aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid Woodhouse <David.Woodhouse@intel.com>2008-10-13 12:13:56 -0400
committerDavid Woodhouse <David.Woodhouse@intel.com>2008-10-13 12:13:56 -0400
commite758936e02700ff88a0b08b722a3847b95283ef2 (patch)
tree50c919bef1b459a778b85159d5929de95b6c4a01 /net
parent239cfbde1f5843c4a24199f117d5f67f637d72d5 (diff)
parent4480f15b3306f43bbb0310d461142b4e897ca45b (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: include/asm-x86/statfs.h
Diffstat (limited to 'net')
-rw-r--r--net/8021q/vlan.c1
-rw-r--r--net/8021q/vlan_dev.c3
-rw-r--r--net/9p/client.c10
-rw-r--r--net/9p/conv.c6
-rw-r--r--net/9p/mod.c92
-rw-r--r--net/9p/trans_fd.c104
-rw-r--r--net/9p/trans_virtio.c2
-rw-r--r--net/Kconfig10
-rw-r--r--net/Makefile2
-rw-r--r--net/atm/br2684.c8
-rw-r--r--net/atm/lec.c1
-rw-r--r--net/ax25/af_ax25.c3
-rw-r--r--net/ax25/ax25_std_timer.c8
-rw-r--r--net/bluetooth/af_bluetooth.c2
-rw-r--r--net/bluetooth/hci_conn.c21
-rw-r--r--net/bluetooth/hci_core.c3
-rw-r--r--net/bluetooth/hci_event.c11
-rw-r--r--net/bluetooth/l2cap.c34
-rw-r--r--net/bluetooth/sco.c2
-rw-r--r--net/bridge/br.c22
-rw-r--r--net/bridge/br_device.c3
-rw-r--r--net/bridge/br_if.c15
-rw-r--r--net/bridge/br_ioctl.c28
-rw-r--r--net/bridge/br_netfilter.c4
-rw-r--r--net/bridge/br_netlink.c15
-rw-r--r--net/bridge/br_notify.c3
-rw-r--r--net/bridge/br_private.h6
-rw-r--r--net/bridge/br_stp_bpdu.c3
-rw-r--r--net/bridge/br_sysfs_br.c26
-rw-r--r--net/bridge/netfilter/Kconfig30
-rw-r--r--net/bridge/netfilter/ebt_802_3.c47
-rw-r--r--net/bridge/netfilter/ebt_among.c85
-rw-r--r--net/bridge/netfilter/ebt_arp.c73
-rw-r--r--net/bridge/netfilter/ebt_arpreply.c49
-rw-r--r--net/bridge/netfilter/ebt_dnat.c57
-rw-r--r--net/bridge/netfilter/ebt_ip.c72
-rw-r--r--net/bridge/netfilter/ebt_ip6.c76
-rw-r--r--net/bridge/netfilter/ebt_limit.c45
-rw-r--r--net/bridge/netfilter/ebt_log.c57
-rw-r--r--net/bridge/netfilter/ebt_mark.c41
-rw-r--r--net/bridge/netfilter/ebt_mark_m.c45
-rw-r--r--net/bridge/netfilter/ebt_nflog.c44
-rw-r--r--net/bridge/netfilter/ebt_pkttype.c41
-rw-r--r--net/bridge/netfilter/ebt_redirect.c63
-rw-r--r--net/bridge/netfilter/ebt_snat.c52
-rw-r--r--net/bridge/netfilter/ebt_stp.c78
-rw-r--r--net/bridge/netfilter/ebt_ulog.c58
-rw-r--r--net/bridge/netfilter/ebt_vlan.c61
-rw-r--r--net/bridge/netfilter/ebtables.c313
-rw-r--r--net/core/Makefile1
-rw-r--r--net/core/dev.c152
-rw-r--r--net/core/dst.c1
-rw-r--r--net/core/neighbour.c21
-rw-r--r--net/core/net-sysfs.c36
-rw-r--r--net/core/net_namespace.c1
-rw-r--r--net/core/rtnetlink.c15
-rw-r--r--net/core/skb_dma_map.c66
-rw-r--r--net/core/skbuff.c63
-rw-r--r--net/core/sock.c13
-rw-r--r--net/dccp/ccids/ccid2.c2
-rw-r--r--net/dccp/ccids/ccid3.c2
-rw-r--r--net/dccp/ccids/lib/loss_interval.c6
-rw-r--r--net/dccp/ccids/lib/tfrc.c2
-rw-r--r--net/dccp/input.c4
-rw-r--r--net/dccp/ipv4.c5
-rw-r--r--net/dccp/ipv6.c12
-rw-r--r--net/dccp/options.c13
-rw-r--r--net/dccp/proto.c4
-rw-r--r--net/dsa/Kconfig60
-rw-r--r--net/dsa/Makefile13
-rw-r--r--net/dsa/dsa.c392
-rw-r--r--net/dsa/dsa_priv.h116
-rw-r--r--net/dsa/mv88e6060.c287
-rw-r--r--net/dsa/mv88e6123_61_65.c421
-rw-r--r--net/dsa/mv88e6131.c380
-rw-r--r--net/dsa/mv88e6xxx.c522
-rw-r--r--net/dsa/mv88e6xxx.h93
-rw-r--r--net/dsa/slave.c298
-rw-r--r--net/dsa/tag_dsa.c194
-rw-r--r--net/dsa/tag_edsa.c213
-rw-r--r--net/dsa/tag_trailer.c130
-rw-r--r--net/ethernet/eth.c14
-rw-r--r--net/ieee80211/ieee80211_module.c8
-rw-r--r--net/ipv4/Kconfig2
-rw-r--r--net/ipv4/Makefile1
-rw-r--r--net/ipv4/af_inet.c2
-rw-r--r--net/ipv4/devinet.c15
-rw-r--r--net/ipv4/igmp.c7
-rw-r--r--net/ipv4/inet_connection_sock.c19
-rw-r--r--net/ipv4/inet_diag.c6
-rw-r--r--net/ipv4/inet_timewait_sock.c36
-rw-r--r--net/ipv4/ip_gre.c487
-rw-r--r--net/ipv4/ip_output.c4
-rw-r--r--net/ipv4/ip_sockglue.c15
-rw-r--r--net/ipv4/ipvs/ip_vs_proto_ah.c178
-rw-r--r--net/ipv4/ipvs/ip_vs_proto_esp.c176
-rw-r--r--net/ipv4/netfilter.c10
-rw-r--r--net/ipv4/netfilter/Kconfig128
-rw-r--r--net/ipv4/netfilter/Makefile4
-rw-r--r--net/ipv4/netfilter/arp_tables.c116
-rw-r--r--net/ipv4/netfilter/arpt_mangle.c15
-rw-r--r--net/ipv4/netfilter/arptable_filter.c8
-rw-r--r--net/ipv4/netfilter/ip_tables.c177
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c29
-rw-r--r--net/ipv4/netfilter/ipt_ECN.c17
-rw-r--r--net/ipv4/netfilter/ipt_LOG.c21
-rw-r--r--net/ipv4/netfilter/ipt_MASQUERADE.c30
-rw-r--r--net/ipv4/netfilter/ipt_NETMAP.c26
-rw-r--r--net/ipv4/netfilter/ipt_REDIRECT.c21
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c19
-rw-r--r--net/ipv4/netfilter/ipt_TTL.c15
-rw-r--r--net/ipv4/netfilter/ipt_ULOG.c23
-rw-r--r--net/ipv4/netfilter/ipt_addrtype.c35
-rw-r--r--net/ipv4/netfilter/ipt_ah.c24
-rw-r--r--net/ipv4/netfilter/ipt_ecn.c20
-rw-r--r--net/ipv4/netfilter/ipt_ttl.c9
-rw-r--r--net/ipv4/netfilter/iptable_filter.c6
-rw-r--r--net/ipv4/netfilter/iptable_mangle.c10
-rw-r--r--net/ipv4/netfilter/iptable_raw.c4
-rw-r--r--net/ipv4/netfilter/iptable_security.c6
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c68
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c73
-rw-r--r--net/ipv4/netfilter/nf_conntrack_proto_icmp.c22
-rw-r--r--net/ipv4/netfilter/nf_defrag_ipv4.c96
-rw-r--r--net/ipv4/netfilter/nf_nat_core.c72
-rw-r--r--net/ipv4/netfilter/nf_nat_helper.c3
-rw-r--r--net/ipv4/netfilter/nf_nat_pptp.c3
-rw-r--r--net/ipv4/netfilter/nf_nat_rule.c92
-rw-r--r--net/ipv4/route.c34
-rw-r--r--net/ipv4/syncookies.c3
-rw-r--r--net/ipv4/sysctl_net_ipv4.c23
-rw-r--r--net/ipv4/tcp.c18
-rw-r--r--net/ipv4/tcp_hybla.c6
-rw-r--r--net/ipv4/tcp_input.c332
-rw-r--r--net/ipv4/tcp_ipv4.c54
-rw-r--r--net/ipv4/tcp_minisocks.c1
-rw-r--r--net/ipv4/tcp_output.c222
-rw-r--r--net/ipv4/tcp_timer.c2
-rw-r--r--net/ipv4/udp.c185
-rw-r--r--net/ipv6/af_inet6.c69
-rw-r--r--net/ipv6/exthdrs.c42
-rw-r--r--net/ipv6/icmp.c8
-rw-r--r--net/ipv6/ip6_input.c27
-rw-r--r--net/ipv6/ip6_output.c144
-rw-r--r--net/ipv6/ip6_tunnel.c4
-rw-r--r--net/ipv6/ip6mr.c3
-rw-r--r--net/ipv6/mcast.c22
-rw-r--r--net/ipv6/ndisc.c12
-rw-r--r--net/ipv6/netfilter.c5
-rw-r--r--net/ipv6/netfilter/Kconfig77
-rw-r--r--net/ipv6/netfilter/ip6_tables.c173
-rw-r--r--net/ipv6/netfilter/ip6t_HL.c15
-rw-r--r--net/ipv6/netfilter/ip6t_LOG.c22
-rw-r--r--net/ipv6/netfilter/ip6t_REJECT.c39
-rw-r--r--net/ipv6/netfilter/ip6t_ah.c21
-rw-r--r--net/ipv6/netfilter/ip6t_eui64.c11
-rw-r--r--net/ipv6/netfilter/ip6t_frag.c21
-rw-r--r--net/ipv6/netfilter/ip6t_hbh.c33
-rw-r--r--net/ipv6/netfilter/ip6t_hl.c9
-rw-r--r--net/ipv6/netfilter/ip6t_ipv6header.c16
-rw-r--r--net/ipv6/netfilter/ip6t_mh.c25
-rw-r--r--net/ipv6/netfilter/ip6t_rt.c21
-rw-r--r--net/ipv6/netfilter/ip6table_filter.c6
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c31
-rw-r--r--net/ipv6/netfilter/ip6table_raw.c20
-rw-r--r--net/ipv6/netfilter/ip6table_security.c6
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c24
-rw-r--r--net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c19
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c32
-rw-r--r--net/ipv6/proc.c121
-rw-r--r--net/ipv6/raw.c10
-rw-r--r--net/ipv6/reassembly.c65
-rw-r--r--net/ipv6/route.c57
-rw-r--r--net/ipv6/tcp_ipv6.c167
-rw-r--r--net/ipv6/udp.c18
-rw-r--r--net/ipv6/udplite.c2
-rw-r--r--net/iucv/iucv.c3
-rw-r--r--net/key/af_key.c155
-rw-r--r--net/mac80211/Kconfig26
-rw-r--r--net/mac80211/Makefile7
-rw-r--r--net/mac80211/cfg.c201
-rw-r--r--net/mac80211/debugfs.c4
-rw-r--r--net/mac80211/debugfs_key.c9
-rw-r--r--net/mac80211/debugfs_netdev.c72
-rw-r--r--net/mac80211/debugfs_sta.c11
-rw-r--r--net/mac80211/event.c5
-rw-r--r--net/mac80211/ht.c992
-rw-r--r--net/mac80211/ieee80211_i.h397
-rw-r--r--net/mac80211/iface.c620
-rw-r--r--net/mac80211/key.c22
-rw-r--r--net/mac80211/main.c1003
-rw-r--r--net/mac80211/mesh.c368
-rw-r--r--net/mac80211/mesh.h80
-rw-r--r--net/mac80211/mesh_hwmp.c230
-rw-r--r--net/mac80211/mesh_pathtbl.c211
-rw-r--r--net/mac80211/mesh_plink.c98
-rw-r--r--net/mac80211/mlme.c3892
-rw-r--r--net/mac80211/rate.c71
-rw-r--r--net/mac80211/rate.h116
-rw-r--r--net/mac80211/rc80211_minstrel.c583
-rw-r--r--net/mac80211/rc80211_minstrel.h85
-rw-r--r--net/mac80211/rc80211_minstrel_debugfs.c164
-rw-r--r--net/mac80211/rc80211_pid.h4
-rw-r--r--net/mac80211/rc80211_pid_algo.c191
-rw-r--r--net/mac80211/rx.c367
-rw-r--r--net/mac80211/scan.c937
-rw-r--r--net/mac80211/spectmgmt.c86
-rw-r--r--net/mac80211/sta_info.c100
-rw-r--r--net/mac80211/sta_info.h42
-rw-r--r--net/mac80211/tkip.c2
-rw-r--r--net/mac80211/tx.c334
-rw-r--r--net/mac80211/util.c365
-rw-r--r--net/mac80211/wep.c17
-rw-r--r--net/mac80211/wext.c165
-rw-r--r--net/mac80211/wme.c14
-rw-r--r--net/mac80211/wme.h3
-rw-r--r--net/mac80211/wpa.c10
-rw-r--r--net/netfilter/Kconfig236
-rw-r--r--net/netfilter/Makefile9
-rw-r--r--net/netfilter/core.c18
-rw-r--r--net/netfilter/ipvs/Kconfig (renamed from net/ipv4/ipvs/Kconfig)21
-rw-r--r--net/netfilter/ipvs/Makefile (renamed from net/ipv4/ipvs/Makefile)3
-rw-r--r--net/netfilter/ipvs/ip_vs_app.c (renamed from net/ipv4/ipvs/ip_vs_app.c)0
-rw-r--r--net/netfilter/ipvs/ip_vs_conn.c (renamed from net/ipv4/ipvs/ip_vs_conn.c)249
-rw-r--r--net/netfilter/ipvs/ip_vs_core.c (renamed from net/ipv4/ipvs/ip_vs_core.c)817
-rw-r--r--net/netfilter/ipvs/ip_vs_ctl.c (renamed from net/ipv4/ipvs/ip_vs_ctl.c)1372
-rw-r--r--net/netfilter/ipvs/ip_vs_dh.c (renamed from net/ipv4/ipvs/ip_vs_dh.c)5
-rw-r--r--net/netfilter/ipvs/ip_vs_est.c (renamed from net/ipv4/ipvs/ip_vs_est.c)58
-rw-r--r--net/netfilter/ipvs/ip_vs_ftp.c (renamed from net/ipv4/ipvs/ip_vs_ftp.c)61
-rw-r--r--net/netfilter/ipvs/ip_vs_lblc.c (renamed from net/ipv4/ipvs/ip_vs_lblc.c)220
-rw-r--r--net/netfilter/ipvs/ip_vs_lblcr.c (renamed from net/ipv4/ipvs/ip_vs_lblcr.c)249
-rw-r--r--net/netfilter/ipvs/ip_vs_lc.c (renamed from net/ipv4/ipvs/ip_vs_lc.c)32
-rw-r--r--net/netfilter/ipvs/ip_vs_nq.c (renamed from net/ipv4/ipvs/ip_vs_nq.c)39
-rw-r--r--net/netfilter/ipvs/ip_vs_proto.c (renamed from net/ipv4/ipvs/ip_vs_proto.c)65
-rw-r--r--net/netfilter/ipvs/ip_vs_proto_ah_esp.c235
-rw-r--r--net/netfilter/ipvs/ip_vs_proto_tcp.c (renamed from net/ipv4/ipvs/ip_vs_proto_tcp.c)254
-rw-r--r--net/netfilter/ipvs/ip_vs_proto_udp.c (renamed from net/ipv4/ipvs/ip_vs_proto_udp.c)227
-rw-r--r--net/netfilter/ipvs/ip_vs_rr.c (renamed from net/ipv4/ipvs/ip_vs_rr.c)20
-rw-r--r--net/netfilter/ipvs/ip_vs_sched.c (renamed from net/ipv4/ipvs/ip_vs_sched.c)0
-rw-r--r--net/netfilter/ipvs/ip_vs_sed.c (renamed from net/ipv4/ipvs/ip_vs_sed.c)39
-rw-r--r--net/netfilter/ipvs/ip_vs_sh.c (renamed from net/ipv4/ipvs/ip_vs_sh.c)5
-rw-r--r--net/netfilter/ipvs/ip_vs_sync.c (renamed from net/ipv4/ipvs/ip_vs_sync.c)46
-rw-r--r--net/netfilter/ipvs/ip_vs_wlc.c (renamed from net/ipv4/ipvs/ip_vs_wlc.c)39
-rw-r--r--net/netfilter/ipvs/ip_vs_wrr.c (renamed from net/ipv4/ipvs/ip_vs_wrr.c)15
-rw-r--r--net/netfilter/ipvs/ip_vs_xmit.c (renamed from net/ipv4/ipvs/ip_vs_xmit.c)471
-rw-r--r--net/netfilter/nf_conntrack_acct.c100
-rw-r--r--net/netfilter/nf_conntrack_core.c344
-rw-r--r--net/netfilter/nf_conntrack_ecache.c26
-rw-r--r--net/netfilter/nf_conntrack_expect.c104
-rw-r--r--net/netfilter/nf_conntrack_ftp.c9
-rw-r--r--net/netfilter/nf_conntrack_h323_main.c6
-rw-r--r--net/netfilter/nf_conntrack_helper.c40
-rw-r--r--net/netfilter/nf_conntrack_irc.c10
-rw-r--r--net/netfilter/nf_conntrack_netlink.c31
-rw-r--r--net/netfilter/nf_conntrack_pptp.c36
-rw-r--r--net/netfilter/nf_conntrack_proto.c10
-rw-r--r--net/netfilter/nf_conntrack_proto_dccp.c20
-rw-r--r--net/netfilter/nf_conntrack_proto_generic.c2
-rw-r--r--net/netfilter/nf_conntrack_proto_gre.c107
-rw-r--r--net/netfilter/nf_conntrack_proto_sctp.c6
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c35
-rw-r--r--net/netfilter/nf_conntrack_proto_udp.c16
-rw-r--r--net/netfilter/nf_conntrack_proto_udplite.c20
-rw-r--r--net/netfilter/nf_conntrack_sip.c9
-rw-r--r--net/netfilter/nf_conntrack_standalone.c146
-rw-r--r--net/netfilter/nf_internals.h4
-rw-r--r--net/netfilter/nf_log.c18
-rw-r--r--net/netfilter/nf_queue.c22
-rw-r--r--net/netfilter/nf_sockopt.c18
-rw-r--r--net/netfilter/nf_tproxy_core.c96
-rw-r--r--net/netfilter/nfnetlink_log.c4
-rw-r--r--net/netfilter/x_tables.c145
-rw-r--r--net/netfilter/xt_CLASSIFY.c44
-rw-r--r--net/netfilter/xt_CONNMARK.c78
-rw-r--r--net/netfilter/xt_CONNSECMARK.c63
-rw-r--r--net/netfilter/xt_DSCP.c59
-rw-r--r--net/netfilter/xt_MARK.c76
-rw-r--r--net/netfilter/xt_NFLOG.c46
-rw-r--r--net/netfilter/xt_NFQUEUE.c10
-rw-r--r--net/netfilter/xt_NOTRACK.c30
-rw-r--r--net/netfilter/xt_RATEEST.c56
-rw-r--r--net/netfilter/xt_SECMARK.c52
-rw-r--r--net/netfilter/xt_TCPMSS.c38
-rw-r--r--net/netfilter/xt_TCPOPTSTRIP.c16
-rw-r--r--net/netfilter/xt_TPROXY.c102
-rw-r--r--net/netfilter/xt_TRACE.c30
-rw-r--r--net/netfilter/xt_comment.c31
-rw-r--r--net/netfilter/xt_connbytes.c56
-rw-r--r--net/netfilter/xt_connlimit.c80
-rw-r--r--net/netfilter/xt_connmark.c68
-rw-r--r--net/netfilter/xt_conntrack.c62
-rw-r--r--net/netfilter/xt_dccp.c27
-rw-r--r--net/netfilter/xt_dscp.c51
-rw-r--r--net/netfilter/xt_esp.c25
-rw-r--r--net/netfilter/xt_hashlimit.c104
-rw-r--r--net/netfilter/xt_helper.c54
-rw-r--r--net/netfilter/xt_iprange.c27
-rw-r--r--net/netfilter/xt_length.c18
-rw-r--r--net/netfilter/xt_limit.c54
-rw-r--r--net/netfilter/xt_mac.c41
-rw-r--r--net/netfilter/xt_mark.c46
-rw-r--r--net/netfilter/xt_multiport.c71
-rw-r--r--net/netfilter/xt_owner.c51
-rw-r--r--net/netfilter/xt_physdev.c49
-rw-r--r--net/netfilter/xt_pkttype.c37
-rw-r--r--net/netfilter/xt_policy.c34
-rw-r--r--net/netfilter/xt_quota.c43
-rw-r--r--net/netfilter/xt_rateest.c58
-rw-r--r--net/netfilter/xt_realm.c9
-rw-r--r--net/netfilter/xt_recent.c (renamed from net/ipv4/netfilter/ipt_recent.c)348
-rw-r--r--net/netfilter/xt_sctp.c27
-rw-r--r--net/netfilter/xt_socket.c185
-rw-r--r--net/netfilter/xt_state.c24
-rw-r--r--net/netfilter/xt_statistic.c45
-rw-r--r--net/netfilter/xt_string.c53
-rw-r--r--net/netfilter/xt_tcpmss.c17
-rw-r--r--net/netfilter/xt_tcpudp.c64
-rw-r--r--net/netfilter/xt_time.c47
-rw-r--r--net/netfilter/xt_u32.c33
-rw-r--r--net/netrom/af_netrom.c2
-rw-r--r--net/phonet/Kconfig16
-rw-r--r--net/phonet/Makefile11
-rw-r--r--net/phonet/af_phonet.c477
-rw-r--r--net/phonet/datagram.c197
-rw-r--r--net/phonet/pep-gprs.c347
-rw-r--r--net/phonet/pep.c1076
-rw-r--r--net/phonet/pn_dev.c208
-rw-r--r--net/phonet/pn_netlink.c165
-rw-r--r--net/phonet/socket.c411
-rw-r--r--net/phonet/sysctl.c113
-rw-r--r--net/rfkill/rfkill-input.h1
-rw-r--r--net/rfkill/rfkill.c259
-rw-r--r--net/sched/Kconfig20
-rw-r--r--net/sched/Makefile2
-rw-r--r--net/sched/act_ipt.c46
-rw-r--r--net/sched/act_skbedit.c203
-rw-r--r--net/sched/cls_api.c2
-rw-r--r--net/sched/cls_flow.c28
-rw-r--r--net/sched/cls_route.c2
-rw-r--r--net/sched/em_cmp.c9
-rw-r--r--net/sched/sch_api.c8
-rw-r--r--net/sched/sch_cbq.c2
-rw-r--r--net/sched/sch_dsmark.c8
-rw-r--r--net/sched/sch_generic.c32
-rw-r--r--net/sched/sch_htb.c4
-rw-r--r--net/sched/sch_multiq.c477
-rw-r--r--net/sched/sch_netem.c20
-rw-r--r--net/sched/sch_prio.c6
-rw-r--r--net/sched/sch_sfq.c4
-rw-r--r--net/sched/sch_teql.c2
-rw-r--r--net/sctp/associola.c18
-rw-r--r--net/sctp/bind_addr.c16
-rw-r--r--net/sctp/ipv6.c7
-rw-r--r--net/sctp/output.c5
-rw-r--r--net/sctp/outqueue.c65
-rw-r--r--net/sctp/sm_make_chunk.c67
-rw-r--r--net/sctp/sm_sideeffect.c81
-rw-r--r--net/sctp/sm_statefuns.c92
-rw-r--r--net/sctp/sm_statetable.c2
-rw-r--r--net/sctp/socket.c10
-rw-r--r--net/sctp/tsnmap.c346
-rw-r--r--net/sctp/ulpevent.c10
-rw-r--r--net/sctp/ulpqueue.c5
-rw-r--r--net/socket.c2
-rw-r--r--net/sunrpc/xprtrdma/rpc_rdma.c4
-rw-r--r--net/tipc/bcast.c22
-rw-r--r--net/tipc/bcast.h22
-rw-r--r--net/tipc/bearer.c2
-rw-r--r--net/tipc/bearer.h2
-rw-r--r--net/tipc/cluster.c16
-rw-r--r--net/tipc/cluster.h10
-rw-r--r--net/tipc/discover.c2
-rw-r--r--net/tipc/link.c26
-rw-r--r--net/tipc/link.h2
-rw-r--r--net/tipc/name_table.h2
-rw-r--r--net/tipc/net.c2
-rw-r--r--net/tipc/net.h2
-rw-r--r--net/tipc/node.c60
-rw-r--r--net/tipc/node.h42
-rw-r--r--net/tipc/node_subscr.c4
-rw-r--r--net/tipc/node_subscr.h10
-rw-r--r--net/tipc/port.h2
-rw-r--r--net/tipc/zone.c4
-rw-r--r--net/tipc/zone.h2
-rw-r--r--net/wireless/Kconfig35
-rw-r--r--net/wireless/core.c45
-rw-r--r--net/wireless/core.h2
-rw-r--r--net/wireless/nl80211.c280
-rw-r--r--net/wireless/reg.c910
-rw-r--r--net/wireless/reg.h13
-rw-r--r--net/xfrm/xfrm_output.c12
-rw-r--r--net/xfrm/xfrm_policy.c123
-rw-r--r--net/xfrm/xfrm_state.c114
-rw-r--r--net/xfrm/xfrm_user.c61
394 files changed, 25068 insertions, 12361 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index b661f47bf10a..f0e335aa20df 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -394,6 +394,7 @@ static void vlan_transfer_features(struct net_device *dev,
394 394
395 vlandev->features &= ~dev->vlan_features; 395 vlandev->features &= ~dev->vlan_features;
396 vlandev->features |= dev->features & dev->vlan_features; 396 vlandev->features |= dev->features & dev->vlan_features;
397 vlandev->gso_max_size = dev->gso_max_size;
397 398
398 if (old_features != vlandev->features) 399 if (old_features != vlandev->features)
399 netdev_features_change(vlandev); 400 netdev_features_change(vlandev);
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 4bf014e51f8c..8883e9c8a223 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -48,7 +48,7 @@ static int vlan_dev_rebuild_header(struct sk_buff *skb)
48 48
49 switch (veth->h_vlan_encapsulated_proto) { 49 switch (veth->h_vlan_encapsulated_proto) {
50#ifdef CONFIG_INET 50#ifdef CONFIG_INET
51 case __constant_htons(ETH_P_IP): 51 case htons(ETH_P_IP):
52 52
53 /* TODO: Confirm this will work with VLAN headers... */ 53 /* TODO: Confirm this will work with VLAN headers... */
54 return arp_find(veth->h_dest, skb); 54 return arp_find(veth->h_dest, skb);
@@ -607,6 +607,7 @@ static int vlan_dev_init(struct net_device *dev)
607 (1<<__LINK_STATE_PRESENT); 607 (1<<__LINK_STATE_PRESENT);
608 608
609 dev->features |= real_dev->features & real_dev->vlan_features; 609 dev->features |= real_dev->features & real_dev->vlan_features;
610 dev->gso_max_size = real_dev->gso_max_size;
610 611
611 /* ipv6 shared card related stuff */ 612 /* ipv6 shared card related stuff */
612 dev->dev_id = real_dev->dev_id; 613 dev->dev_id = real_dev->dev_id;
diff --git a/net/9p/client.c b/net/9p/client.c
index 2ffe40cf2f01..10e320307ec0 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -75,7 +75,6 @@ static int parse_opts(char *opts, struct p9_client *clnt)
75 int option; 75 int option;
76 int ret = 0; 76 int ret = 0;
77 77
78 clnt->trans_mod = v9fs_default_trans();
79 clnt->dotu = 1; 78 clnt->dotu = 1;
80 clnt->msize = 8192; 79 clnt->msize = 8192;
81 80
@@ -108,7 +107,7 @@ static int parse_opts(char *opts, struct p9_client *clnt)
108 clnt->msize = option; 107 clnt->msize = option;
109 break; 108 break;
110 case Opt_trans: 109 case Opt_trans:
111 clnt->trans_mod = v9fs_match_trans(&args[0]); 110 clnt->trans_mod = v9fs_get_trans_by_name(&args[0]);
112 break; 111 break;
113 case Opt_legacy: 112 case Opt_legacy:
114 clnt->dotu = 0; 113 clnt->dotu = 0;
@@ -117,6 +116,10 @@ static int parse_opts(char *opts, struct p9_client *clnt)
117 continue; 116 continue;
118 } 117 }
119 } 118 }
119
120 if (!clnt->trans_mod)
121 clnt->trans_mod = v9fs_get_default_trans();
122
120 kfree(options); 123 kfree(options);
121 return ret; 124 return ret;
122} 125}
@@ -150,6 +153,7 @@ struct p9_client *p9_client_create(const char *dev_name, char *options)
150 if (!clnt) 153 if (!clnt)
151 return ERR_PTR(-ENOMEM); 154 return ERR_PTR(-ENOMEM);
152 155
156 clnt->trans_mod = NULL;
153 clnt->trans = NULL; 157 clnt->trans = NULL;
154 spin_lock_init(&clnt->lock); 158 spin_lock_init(&clnt->lock);
155 INIT_LIST_HEAD(&clnt->fidlist); 159 INIT_LIST_HEAD(&clnt->fidlist);
@@ -235,6 +239,8 @@ void p9_client_destroy(struct p9_client *clnt)
235 clnt->trans = NULL; 239 clnt->trans = NULL;
236 } 240 }
237 241
242 v9fs_put_trans(clnt->trans_mod);
243
238 list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist) 244 list_for_each_entry_safe(fid, fidptr, &clnt->fidlist, flist)
239 p9_fid_destroy(fid); 245 p9_fid_destroy(fid);
240 246
diff --git a/net/9p/conv.c b/net/9p/conv.c
index 44547201f5bc..5ad3a3bd73b2 100644
--- a/net/9p/conv.c
+++ b/net/9p/conv.c
@@ -451,8 +451,10 @@ p9_put_data(struct cbuf *bufp, const char *data, int count,
451 unsigned char **pdata) 451 unsigned char **pdata)
452{ 452{
453 *pdata = buf_alloc(bufp, count); 453 *pdata = buf_alloc(bufp, count);
454 if (*pdata == NULL)
455 return -ENOMEM;
454 memmove(*pdata, data, count); 456 memmove(*pdata, data, count);
455 return count; 457 return 0;
456} 458}
457 459
458static int 460static int
@@ -460,6 +462,8 @@ p9_put_user_data(struct cbuf *bufp, const char __user *data, int count,
460 unsigned char **pdata) 462 unsigned char **pdata)
461{ 463{
462 *pdata = buf_alloc(bufp, count); 464 *pdata = buf_alloc(bufp, count);
465 if (*pdata == NULL)
466 return -ENOMEM;
463 return copy_from_user(*pdata, data, count); 467 return copy_from_user(*pdata, data, count);
464} 468}
465 469
diff --git a/net/9p/mod.c b/net/9p/mod.c
index bdee1fb7cc62..1084feb24cb0 100644
--- a/net/9p/mod.c
+++ b/net/9p/mod.c
@@ -31,6 +31,7 @@
31#include <linux/parser.h> 31#include <linux/parser.h>
32#include <net/9p/transport.h> 32#include <net/9p/transport.h>
33#include <linux/list.h> 33#include <linux/list.h>
34#include <linux/spinlock.h>
34 35
35#ifdef CONFIG_NET_9P_DEBUG 36#ifdef CONFIG_NET_9P_DEBUG
36unsigned int p9_debug_level = 0; /* feature-rific global debug level */ 37unsigned int p9_debug_level = 0; /* feature-rific global debug level */
@@ -44,8 +45,8 @@ MODULE_PARM_DESC(debug, "9P debugging level");
44 * 45 *
45 */ 46 */
46 47
48static DEFINE_SPINLOCK(v9fs_trans_lock);
47static LIST_HEAD(v9fs_trans_list); 49static LIST_HEAD(v9fs_trans_list);
48static struct p9_trans_module *v9fs_default_transport;
49 50
50/** 51/**
51 * v9fs_register_trans - register a new transport with 9p 52 * v9fs_register_trans - register a new transport with 9p
@@ -54,48 +55,87 @@ static struct p9_trans_module *v9fs_default_transport;
54 */ 55 */
55void v9fs_register_trans(struct p9_trans_module *m) 56void v9fs_register_trans(struct p9_trans_module *m)
56{ 57{
58 spin_lock(&v9fs_trans_lock);
57 list_add_tail(&m->list, &v9fs_trans_list); 59 list_add_tail(&m->list, &v9fs_trans_list);
58 if (m->def) 60 spin_unlock(&v9fs_trans_lock);
59 v9fs_default_transport = m;
60} 61}
61EXPORT_SYMBOL(v9fs_register_trans); 62EXPORT_SYMBOL(v9fs_register_trans);
62 63
63/** 64/**
64 * v9fs_match_trans - match transport versus registered transports 65 * v9fs_unregister_trans - unregister a 9p transport
66 * @m: the transport to remove
67 *
68 */
69void v9fs_unregister_trans(struct p9_trans_module *m)
70{
71 spin_lock(&v9fs_trans_lock);
72 list_del_init(&m->list);
73 spin_unlock(&v9fs_trans_lock);
74}
75EXPORT_SYMBOL(v9fs_unregister_trans);
76
77/**
78 * v9fs_get_trans_by_name - get transport with the matching name
65 * @name: string identifying transport 79 * @name: string identifying transport
66 * 80 *
67 */ 81 */
68struct p9_trans_module *v9fs_match_trans(const substring_t *name) 82struct p9_trans_module *v9fs_get_trans_by_name(const substring_t *name)
69{ 83{
70 struct list_head *p; 84 struct p9_trans_module *t, *found = NULL;
71 struct p9_trans_module *t = NULL; 85
72 86 spin_lock(&v9fs_trans_lock);
73 list_for_each(p, &v9fs_trans_list) { 87
74 t = list_entry(p, struct p9_trans_module, list); 88 list_for_each_entry(t, &v9fs_trans_list, list)
75 if (strncmp(t->name, name->from, name->to-name->from) == 0) 89 if (strncmp(t->name, name->from, name->to-name->from) == 0 &&
76 return t; 90 try_module_get(t->owner)) {
77 } 91 found = t;
78 return NULL; 92 break;
93 }
94
95 spin_unlock(&v9fs_trans_lock);
96 return found;
79} 97}
80EXPORT_SYMBOL(v9fs_match_trans); 98EXPORT_SYMBOL(v9fs_get_trans_by_name);
81 99
82/** 100/**
83 * v9fs_default_trans - returns pointer to default transport 101 * v9fs_get_default_trans - get the default transport
84 * 102 *
85 */ 103 */
86 104
87struct p9_trans_module *v9fs_default_trans(void) 105struct p9_trans_module *v9fs_get_default_trans(void)
88{ 106{
89 if (v9fs_default_transport) 107 struct p9_trans_module *t, *found = NULL;
90 return v9fs_default_transport; 108
91 else if (!list_empty(&v9fs_trans_list)) 109 spin_lock(&v9fs_trans_lock);
92 return list_first_entry(&v9fs_trans_list, 110
93 struct p9_trans_module, list); 111 list_for_each_entry(t, &v9fs_trans_list, list)
94 else 112 if (t->def && try_module_get(t->owner)) {
95 return NULL; 113 found = t;
114 break;
115 }
116
117 if (!found)
118 list_for_each_entry(t, &v9fs_trans_list, list)
119 if (try_module_get(t->owner)) {
120 found = t;
121 break;
122 }
123
124 spin_unlock(&v9fs_trans_lock);
125 return found;
96} 126}
97EXPORT_SYMBOL(v9fs_default_trans); 127EXPORT_SYMBOL(v9fs_get_default_trans);
98 128
129/**
130 * v9fs_put_trans - put trans
131 * @m: transport to put
132 *
133 */
134void v9fs_put_trans(struct p9_trans_module *m)
135{
136 if (m)
137 module_put(m->owner);
138}
99 139
100/** 140/**
101 * v9fs_init - Initialize module 141 * v9fs_init - Initialize module
@@ -120,6 +160,8 @@ static int __init init_p9(void)
120static void __exit exit_p9(void) 160static void __exit exit_p9(void)
121{ 161{
122 printk(KERN_INFO "Unloading 9P2000 support\n"); 162 printk(KERN_INFO "Unloading 9P2000 support\n");
163
164 p9_trans_fd_exit();
123} 165}
124 166
125module_init(init_p9) 167module_init(init_p9)
diff --git a/net/9p/trans_fd.c b/net/9p/trans_fd.c
index cdf137af7adc..d652baf5ff91 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -151,7 +151,6 @@ struct p9_mux_poll_task {
151 * @trans: reference to transport instance for this connection 151 * @trans: reference to transport instance for this connection
152 * @tagpool: id accounting for transactions 152 * @tagpool: id accounting for transactions
153 * @err: error state 153 * @err: error state
154 * @equeue: event wait_q (?)
155 * @req_list: accounting for requests which have been sent 154 * @req_list: accounting for requests which have been sent
156 * @unsent_req_list: accounting for requests that haven't been sent 155 * @unsent_req_list: accounting for requests that haven't been sent
157 * @rcall: current response &p9_fcall structure 156 * @rcall: current response &p9_fcall structure
@@ -178,7 +177,6 @@ struct p9_conn {
178 struct p9_trans *trans; 177 struct p9_trans *trans;
179 struct p9_idpool *tagpool; 178 struct p9_idpool *tagpool;
180 int err; 179 int err;
181 wait_queue_head_t equeue;
182 struct list_head req_list; 180 struct list_head req_list;
183 struct list_head unsent_req_list; 181 struct list_head unsent_req_list;
184 struct p9_fcall *rcall; 182 struct p9_fcall *rcall;
@@ -240,22 +238,6 @@ static int p9_conn_rpcnb(struct p9_conn *m, struct p9_fcall *tc,
240 238
241static void p9_conn_cancel(struct p9_conn *m, int err); 239static void p9_conn_cancel(struct p9_conn *m, int err);
242 240
243static int p9_mux_global_init(void)
244{
245 int i;
246
247 for (i = 0; i < ARRAY_SIZE(p9_mux_poll_tasks); i++)
248 p9_mux_poll_tasks[i].task = NULL;
249
250 p9_mux_wq = create_workqueue("v9fs");
251 if (!p9_mux_wq) {
252 printk(KERN_WARNING "v9fs: mux: creating workqueue failed\n");
253 return -ENOMEM;
254 }
255
256 return 0;
257}
258
259static u16 p9_mux_get_tag(struct p9_conn *m) 241static u16 p9_mux_get_tag(struct p9_conn *m)
260{ 242{
261 int tag; 243 int tag;
@@ -409,11 +391,11 @@ static void p9_mux_poll_stop(struct p9_conn *m)
409static struct p9_conn *p9_conn_create(struct p9_trans *trans) 391static struct p9_conn *p9_conn_create(struct p9_trans *trans)
410{ 392{
411 int i, n; 393 int i, n;
412 struct p9_conn *m, *mtmp; 394 struct p9_conn *m;
413 395
414 P9_DPRINTK(P9_DEBUG_MUX, "transport %p msize %d\n", trans, 396 P9_DPRINTK(P9_DEBUG_MUX, "transport %p msize %d\n", trans,
415 trans->msize); 397 trans->msize);
416 m = kmalloc(sizeof(struct p9_conn), GFP_KERNEL); 398 m = kzalloc(sizeof(struct p9_conn), GFP_KERNEL);
417 if (!m) 399 if (!m)
418 return ERR_PTR(-ENOMEM); 400 return ERR_PTR(-ENOMEM);
419 401
@@ -424,25 +406,14 @@ static struct p9_conn *p9_conn_create(struct p9_trans *trans)
424 m->trans = trans; 406 m->trans = trans;
425 m->tagpool = p9_idpool_create(); 407 m->tagpool = p9_idpool_create();
426 if (IS_ERR(m->tagpool)) { 408 if (IS_ERR(m->tagpool)) {
427 mtmp = ERR_PTR(-ENOMEM);
428 kfree(m); 409 kfree(m);
429 return mtmp; 410 return ERR_PTR(-ENOMEM);
430 } 411 }
431 412
432 m->err = 0;
433 init_waitqueue_head(&m->equeue);
434 INIT_LIST_HEAD(&m->req_list); 413 INIT_LIST_HEAD(&m->req_list);
435 INIT_LIST_HEAD(&m->unsent_req_list); 414 INIT_LIST_HEAD(&m->unsent_req_list);
436 m->rcall = NULL;
437 m->rpos = 0;
438 m->rbuf = NULL;
439 m->wpos = m->wsize = 0;
440 m->wbuf = NULL;
441 INIT_WORK(&m->rq, p9_read_work); 415 INIT_WORK(&m->rq, p9_read_work);
442 INIT_WORK(&m->wq, p9_write_work); 416 INIT_WORK(&m->wq, p9_write_work);
443 m->wsched = 0;
444 memset(&m->poll_waddr, 0, sizeof(m->poll_waddr));
445 m->poll_task = NULL;
446 n = p9_mux_poll_start(m); 417 n = p9_mux_poll_start(m);
447 if (n) { 418 if (n) {
448 kfree(m); 419 kfree(m);
@@ -463,10 +434,8 @@ static struct p9_conn *p9_conn_create(struct p9_trans *trans)
463 for (i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) { 434 for (i = 0; i < ARRAY_SIZE(m->poll_waddr); i++) {
464 if (IS_ERR(m->poll_waddr[i])) { 435 if (IS_ERR(m->poll_waddr[i])) {
465 p9_mux_poll_stop(m); 436 p9_mux_poll_stop(m);
466 mtmp = (void *)m->poll_waddr; /* the error code */
467 kfree(m); 437 kfree(m);
468 m = mtmp; 438 return (void *)m->poll_waddr; /* the error code */
469 break;
470 } 439 }
471 } 440 }
472 441
@@ -483,18 +452,13 @@ static void p9_conn_destroy(struct p9_conn *m)
483{ 452{
484 P9_DPRINTK(P9_DEBUG_MUX, "mux %p prev %p next %p\n", m, 453 P9_DPRINTK(P9_DEBUG_MUX, "mux %p prev %p next %p\n", m,
485 m->mux_list.prev, m->mux_list.next); 454 m->mux_list.prev, m->mux_list.next);
486 p9_conn_cancel(m, -ECONNRESET);
487
488 if (!list_empty(&m->req_list)) {
489 /* wait until all processes waiting on this session exit */
490 P9_DPRINTK(P9_DEBUG_MUX,
491 "mux %p waiting for empty request queue\n", m);
492 wait_event_timeout(m->equeue, (list_empty(&m->req_list)), 5000);
493 P9_DPRINTK(P9_DEBUG_MUX, "mux %p request queue empty: %d\n", m,
494 list_empty(&m->req_list));
495 }
496 455
497 p9_mux_poll_stop(m); 456 p9_mux_poll_stop(m);
457 cancel_work_sync(&m->rq);
458 cancel_work_sync(&m->wq);
459
460 p9_conn_cancel(m, -ECONNRESET);
461
498 m->trans = NULL; 462 m->trans = NULL;
499 p9_idpool_destroy(m->tagpool); 463 p9_idpool_destroy(m->tagpool);
500 kfree(m); 464 kfree(m);
@@ -840,8 +804,6 @@ static void p9_read_work(struct work_struct *work)
840 (*req->cb) (req, req->cba); 804 (*req->cb) (req, req->cba);
841 else 805 else
842 kfree(req->rcall); 806 kfree(req->rcall);
843
844 wake_up(&m->equeue);
845 } 807 }
846 } else { 808 } else {
847 if (err >= 0 && rcall->id != P9_RFLUSH) 809 if (err >= 0 && rcall->id != P9_RFLUSH)
@@ -908,8 +870,10 @@ static struct p9_req *p9_send_request(struct p9_conn *m,
908 else 870 else
909 n = p9_mux_get_tag(m); 871 n = p9_mux_get_tag(m);
910 872
911 if (n < 0) 873 if (n < 0) {
874 kfree(req);
912 return ERR_PTR(-ENOMEM); 875 return ERR_PTR(-ENOMEM);
876 }
913 877
914 p9_set_tag(tc, n); 878 p9_set_tag(tc, n);
915 879
@@ -984,8 +948,6 @@ static void p9_mux_flush_cb(struct p9_req *freq, void *a)
984 (*req->cb) (req, req->cba); 948 (*req->cb) (req, req->cba);
985 else 949 else
986 kfree(req->rcall); 950 kfree(req->rcall);
987
988 wake_up(&m->equeue);
989 } 951 }
990 952
991 kfree(freq->tcall); 953 kfree(freq->tcall);
@@ -1191,8 +1153,6 @@ void p9_conn_cancel(struct p9_conn *m, int err)
1191 else 1153 else
1192 kfree(req->rcall); 1154 kfree(req->rcall);
1193 } 1155 }
1194
1195 wake_up(&m->equeue);
1196} 1156}
1197 1157
1198/** 1158/**
@@ -1370,7 +1330,6 @@ p9_fd_poll(struct p9_trans *trans, struct poll_table_struct *pt)
1370{ 1330{
1371 int ret, n; 1331 int ret, n;
1372 struct p9_trans_fd *ts = NULL; 1332 struct p9_trans_fd *ts = NULL;
1373 mm_segment_t oldfs;
1374 1333
1375 if (trans && trans->status == Connected) 1334 if (trans && trans->status == Connected)
1376 ts = trans->priv; 1335 ts = trans->priv;
@@ -1384,24 +1343,17 @@ p9_fd_poll(struct p9_trans *trans, struct poll_table_struct *pt)
1384 if (!ts->wr->f_op || !ts->wr->f_op->poll) 1343 if (!ts->wr->f_op || !ts->wr->f_op->poll)
1385 return -EIO; 1344 return -EIO;
1386 1345
1387 oldfs = get_fs();
1388 set_fs(get_ds());
1389
1390 ret = ts->rd->f_op->poll(ts->rd, pt); 1346 ret = ts->rd->f_op->poll(ts->rd, pt);
1391 if (ret < 0) 1347 if (ret < 0)
1392 goto end; 1348 return ret;
1393 1349
1394 if (ts->rd != ts->wr) { 1350 if (ts->rd != ts->wr) {
1395 n = ts->wr->f_op->poll(ts->wr, pt); 1351 n = ts->wr->f_op->poll(ts->wr, pt);
1396 if (n < 0) { 1352 if (n < 0)
1397 ret = n; 1353 return n;
1398 goto end;
1399 }
1400 ret = (ret & ~POLLOUT) | (n & ~POLLIN); 1354 ret = (ret & ~POLLOUT) | (n & ~POLLIN);
1401 } 1355 }
1402 1356
1403end:
1404 set_fs(oldfs);
1405 return ret; 1357 return ret;
1406} 1358}
1407 1359
@@ -1629,6 +1581,7 @@ static struct p9_trans_module p9_tcp_trans = {
1629 .maxsize = MAX_SOCK_BUF, 1581 .maxsize = MAX_SOCK_BUF,
1630 .def = 1, 1582 .def = 1,
1631 .create = p9_trans_create_tcp, 1583 .create = p9_trans_create_tcp,
1584 .owner = THIS_MODULE,
1632}; 1585};
1633 1586
1634static struct p9_trans_module p9_unix_trans = { 1587static struct p9_trans_module p9_unix_trans = {
@@ -1636,6 +1589,7 @@ static struct p9_trans_module p9_unix_trans = {
1636 .maxsize = MAX_SOCK_BUF, 1589 .maxsize = MAX_SOCK_BUF,
1637 .def = 0, 1590 .def = 0,
1638 .create = p9_trans_create_unix, 1591 .create = p9_trans_create_unix,
1592 .owner = THIS_MODULE,
1639}; 1593};
1640 1594
1641static struct p9_trans_module p9_fd_trans = { 1595static struct p9_trans_module p9_fd_trans = {
@@ -1643,14 +1597,20 @@ static struct p9_trans_module p9_fd_trans = {
1643 .maxsize = MAX_SOCK_BUF, 1597 .maxsize = MAX_SOCK_BUF,
1644 .def = 0, 1598 .def = 0,
1645 .create = p9_trans_create_fd, 1599 .create = p9_trans_create_fd,
1600 .owner = THIS_MODULE,
1646}; 1601};
1647 1602
1648int p9_trans_fd_init(void) 1603int p9_trans_fd_init(void)
1649{ 1604{
1650 int ret = p9_mux_global_init(); 1605 int i;
1651 if (ret) { 1606
1652 printk(KERN_WARNING "9p: starting mux failed\n"); 1607 for (i = 0; i < ARRAY_SIZE(p9_mux_poll_tasks); i++)
1653 return ret; 1608 p9_mux_poll_tasks[i].task = NULL;
1609
1610 p9_mux_wq = create_workqueue("v9fs");
1611 if (!p9_mux_wq) {
1612 printk(KERN_WARNING "v9fs: mux: creating workqueue failed\n");
1613 return -ENOMEM;
1654 } 1614 }
1655 1615
1656 v9fs_register_trans(&p9_tcp_trans); 1616 v9fs_register_trans(&p9_tcp_trans);
@@ -1659,4 +1619,12 @@ int p9_trans_fd_init(void)
1659 1619
1660 return 0; 1620 return 0;
1661} 1621}
1662EXPORT_SYMBOL(p9_trans_fd_init); 1622
1623void p9_trans_fd_exit(void)
1624{
1625 v9fs_unregister_trans(&p9_tcp_trans);
1626 v9fs_unregister_trans(&p9_unix_trans);
1627 v9fs_unregister_trans(&p9_fd_trans);
1628
1629 destroy_workqueue(p9_mux_wq);
1630}
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c
index 42adc052b149..94912e077a55 100644
--- a/net/9p/trans_virtio.c
+++ b/net/9p/trans_virtio.c
@@ -528,6 +528,7 @@ static struct p9_trans_module p9_virtio_trans = {
528 .create = p9_virtio_create, 528 .create = p9_virtio_create,
529 .maxsize = PAGE_SIZE*16, 529 .maxsize = PAGE_SIZE*16,
530 .def = 0, 530 .def = 0,
531 .owner = THIS_MODULE,
531}; 532};
532 533
533/* The standard init function */ 534/* The standard init function */
@@ -545,6 +546,7 @@ static int __init p9_virtio_init(void)
545static void __exit p9_virtio_cleanup(void) 546static void __exit p9_virtio_cleanup(void)
546{ 547{
547 unregister_virtio_driver(&p9_virtio_drv); 548 unregister_virtio_driver(&p9_virtio_drv);
549 v9fs_unregister_trans(&p9_virtio_trans);
548} 550}
549 551
550module_init(p9_virtio_init); 552module_init(p9_virtio_init);
diff --git a/net/Kconfig b/net/Kconfig
index 7612cc8c337c..d789d79551ae 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -180,6 +180,7 @@ source "net/tipc/Kconfig"
180source "net/atm/Kconfig" 180source "net/atm/Kconfig"
181source "net/802/Kconfig" 181source "net/802/Kconfig"
182source "net/bridge/Kconfig" 182source "net/bridge/Kconfig"
183source "net/dsa/Kconfig"
183source "net/8021q/Kconfig" 184source "net/8021q/Kconfig"
184source "net/decnet/Kconfig" 185source "net/decnet/Kconfig"
185source "net/llc/Kconfig" 186source "net/llc/Kconfig"
@@ -232,18 +233,23 @@ source "net/can/Kconfig"
232source "net/irda/Kconfig" 233source "net/irda/Kconfig"
233source "net/bluetooth/Kconfig" 234source "net/bluetooth/Kconfig"
234source "net/rxrpc/Kconfig" 235source "net/rxrpc/Kconfig"
236source "net/phonet/Kconfig"
235 237
236config FIB_RULES 238config FIB_RULES
237 bool 239 bool
238 240
239menu "Wireless" 241menuconfig WIRELESS
242 bool "Wireless"
240 depends on !S390 243 depends on !S390
244 default y
245
246if WIRELESS
241 247
242source "net/wireless/Kconfig" 248source "net/wireless/Kconfig"
243source "net/mac80211/Kconfig" 249source "net/mac80211/Kconfig"
244source "net/ieee80211/Kconfig" 250source "net/ieee80211/Kconfig"
245 251
246endmenu 252endif # WIRELESS
247 253
248source "net/rfkill/Kconfig" 254source "net/rfkill/Kconfig"
249source "net/9p/Kconfig" 255source "net/9p/Kconfig"
diff --git a/net/Makefile b/net/Makefile
index 4f43e7f874f3..27d1f10dc0e0 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_PACKET) += packet/
26obj-$(CONFIG_NET_KEY) += key/ 26obj-$(CONFIG_NET_KEY) += key/
27obj-$(CONFIG_NET_SCHED) += sched/ 27obj-$(CONFIG_NET_SCHED) += sched/
28obj-$(CONFIG_BRIDGE) += bridge/ 28obj-$(CONFIG_BRIDGE) += bridge/
29obj-$(CONFIG_NET_DSA) += dsa/
29obj-$(CONFIG_IPX) += ipx/ 30obj-$(CONFIG_IPX) += ipx/
30obj-$(CONFIG_ATALK) += appletalk/ 31obj-$(CONFIG_ATALK) += appletalk/
31obj-$(CONFIG_WAN_ROUTER) += wanrouter/ 32obj-$(CONFIG_WAN_ROUTER) += wanrouter/
@@ -42,6 +43,7 @@ obj-$(CONFIG_AF_RXRPC) += rxrpc/
42obj-$(CONFIG_ATM) += atm/ 43obj-$(CONFIG_ATM) += atm/
43obj-$(CONFIG_DECNET) += decnet/ 44obj-$(CONFIG_DECNET) += decnet/
44obj-$(CONFIG_ECONET) += econet/ 45obj-$(CONFIG_ECONET) += econet/
46obj-$(CONFIG_PHONET) += phonet/
45ifneq ($(CONFIG_VLAN_8021Q),) 47ifneq ($(CONFIG_VLAN_8021Q),)
46obj-y += 8021q/ 48obj-y += 8021q/
47endif 49endif
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index 8d9a6f158880..280de481edc7 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -375,11 +375,11 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
375 if (memcmp 375 if (memcmp
376 (skb->data + 6, ethertype_ipv6, 376 (skb->data + 6, ethertype_ipv6,
377 sizeof(ethertype_ipv6)) == 0) 377 sizeof(ethertype_ipv6)) == 0)
378 skb->protocol = __constant_htons(ETH_P_IPV6); 378 skb->protocol = htons(ETH_P_IPV6);
379 else if (memcmp 379 else if (memcmp
380 (skb->data + 6, ethertype_ipv4, 380 (skb->data + 6, ethertype_ipv4,
381 sizeof(ethertype_ipv4)) == 0) 381 sizeof(ethertype_ipv4)) == 0)
382 skb->protocol = __constant_htons(ETH_P_IP); 382 skb->protocol = htons(ETH_P_IP);
383 else 383 else
384 goto error; 384 goto error;
385 skb_pull(skb, sizeof(llc_oui_ipv4)); 385 skb_pull(skb, sizeof(llc_oui_ipv4));
@@ -404,9 +404,9 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
404 skb_reset_network_header(skb); 404 skb_reset_network_header(skb);
405 iph = ip_hdr(skb); 405 iph = ip_hdr(skb);
406 if (iph->version == 4) 406 if (iph->version == 4)
407 skb->protocol = __constant_htons(ETH_P_IP); 407 skb->protocol = htons(ETH_P_IP);
408 else if (iph->version == 6) 408 else if (iph->version == 6)
409 skb->protocol = __constant_htons(ETH_P_IPV6); 409 skb->protocol = htons(ETH_P_IPV6);
410 else 410 else
411 goto error; 411 goto error;
412 skb->pkt_type = PACKET_HOST; 412 skb->pkt_type = PACKET_HOST;
diff --git a/net/atm/lec.c b/net/atm/lec.c
index 5799fb52365a..8f701cde5945 100644
--- a/net/atm/lec.c
+++ b/net/atm/lec.c
@@ -1931,7 +1931,6 @@ static struct atm_vcc *lec_arp_resolve(struct lec_priv *priv,
1931 switch (priv->lane_version) { 1931 switch (priv->lane_version) {
1932 case 1: 1932 case 1:
1933 return priv->mcast_vcc; 1933 return priv->mcast_vcc;
1934 break;
1935 case 2: /* LANE2 wants arp for multicast addresses */ 1934 case 2: /* LANE2 wants arp for multicast addresses */
1936 if (!compare_ether_addr(mac_to_find, bus_mac)) 1935 if (!compare_ether_addr(mac_to_find, bus_mac))
1937 return priv->mcast_vcc; 1936 return priv->mcast_vcc;
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 01c83e2a4c19..28c71574a781 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -317,6 +317,9 @@ void ax25_destroy_socket(ax25_cb *ax25)
317 /* Queue the unaccepted socket for death */ 317 /* Queue the unaccepted socket for death */
318 sock_orphan(skb->sk); 318 sock_orphan(skb->sk);
319 319
320 /* 9A4GL: hack to release unaccepted sockets */
321 skb->sk->sk_state = TCP_LISTEN;
322
320 ax25_start_heartbeat(sax25); 323 ax25_start_heartbeat(sax25);
321 sax25->state = AX25_STATE_0; 324 sax25->state = AX25_STATE_0;
322 } 325 }
diff --git a/net/ax25/ax25_std_timer.c b/net/ax25/ax25_std_timer.c
index cdc7e751ef36..96e4b9273250 100644
--- a/net/ax25/ax25_std_timer.c
+++ b/net/ax25/ax25_std_timer.c
@@ -39,9 +39,11 @@ void ax25_std_heartbeat_expiry(ax25_cb *ax25)
39 39
40 switch (ax25->state) { 40 switch (ax25->state) {
41 case AX25_STATE_0: 41 case AX25_STATE_0:
42 if (!sk || 42 /* Magic here: If we listen() and a new link dies before it
43 sock_flag(sk, SOCK_DESTROY) || 43 is accepted() it isn't 'dead' so doesn't get removed. */
44 sock_flag(sk, SOCK_DEAD)) { 44 if (!sk || sock_flag(sk, SOCK_DESTROY) ||
45 (sk->sk_state == TCP_LISTEN &&
46 sock_flag(sk, SOCK_DEAD))) {
45 if (sk) { 47 if (sk) {
46 sock_hold(sk); 48 sock_hold(sk);
47 ax25_destroy_socket(ax25); 49 ax25_destroy_socket(ax25);
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 1edfdf4c095b..f6348e078aa4 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -49,7 +49,7 @@
49#define BT_DBG(D...) 49#define BT_DBG(D...)
50#endif 50#endif
51 51
52#define VERSION "2.12" 52#define VERSION "2.13"
53 53
54/* Bluetooth sockets */ 54/* Bluetooth sockets */
55#define BT_MAX_PROTO 8 55#define BT_MAX_PROTO 8
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index ca8d05245ca0..b7002429f152 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -330,7 +330,7 @@ EXPORT_SYMBOL(hci_get_route);
330 330
331/* Create SCO or ACL connection. 331/* Create SCO or ACL connection.
332 * Device _must_ be locked */ 332 * Device _must_ be locked */
333struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst) 333struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 auth_type)
334{ 334{
335 struct hci_conn *acl; 335 struct hci_conn *acl;
336 struct hci_conn *sco; 336 struct hci_conn *sco;
@@ -344,8 +344,10 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
344 344
345 hci_conn_hold(acl); 345 hci_conn_hold(acl);
346 346
347 if (acl->state == BT_OPEN || acl->state == BT_CLOSED) 347 if (acl->state == BT_OPEN || acl->state == BT_CLOSED) {
348 acl->auth_type = auth_type;
348 hci_acl_connect(acl); 349 hci_acl_connect(acl);
350 }
349 351
350 if (type == ACL_LINK) 352 if (type == ACL_LINK)
351 return acl; 353 return acl;
@@ -374,6 +376,19 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
374} 376}
375EXPORT_SYMBOL(hci_connect); 377EXPORT_SYMBOL(hci_connect);
376 378
379/* Check link security requirement */
380int hci_conn_check_link_mode(struct hci_conn *conn)
381{
382 BT_DBG("conn %p", conn);
383
384 if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0 &&
385 !(conn->link_mode & HCI_LM_ENCRYPT))
386 return 0;
387
388 return 1;
389}
390EXPORT_SYMBOL(hci_conn_check_link_mode);
391
377/* Authenticate remote device */ 392/* Authenticate remote device */
378int hci_conn_auth(struct hci_conn *conn) 393int hci_conn_auth(struct hci_conn *conn)
379{ 394{
@@ -381,7 +396,7 @@ int hci_conn_auth(struct hci_conn *conn)
381 396
382 if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0) { 397 if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0) {
383 if (!(conn->auth_type & 0x01)) { 398 if (!(conn->auth_type & 0x01)) {
384 conn->auth_type = HCI_AT_GENERAL_BONDING_MITM; 399 conn->auth_type |= 0x01;
385 conn->link_mode &= ~HCI_LM_AUTH; 400 conn->link_mode &= ~HCI_LM_AUTH;
386 } 401 }
387 } 402 }
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index f5b21cb93699..278a3ace14f6 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -164,6 +164,9 @@ static inline int hci_request(struct hci_dev *hdev, void (*req)(struct hci_dev *
164{ 164{
165 int ret; 165 int ret;
166 166
167 if (!test_bit(HCI_UP, &hdev->flags))
168 return -ENETDOWN;
169
167 /* Serialize all requests */ 170 /* Serialize all requests */
168 hci_req_lock(hdev); 171 hci_req_lock(hdev);
169 ret = __hci_request(hdev, req, opt, timeout); 172 ret = __hci_request(hdev, req, opt, timeout);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 0e3db289f4be..ad7a553d7713 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1605,14 +1605,11 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b
1605 1605
1606 if (conn->state == BT_CONFIG) { 1606 if (conn->state == BT_CONFIG) {
1607 if (!ev->status && hdev->ssp_mode > 0 && 1607 if (!ev->status && hdev->ssp_mode > 0 &&
1608 conn->ssp_mode > 0) { 1608 conn->ssp_mode > 0 && conn->out) {
1609 if (conn->out) { 1609 struct hci_cp_auth_requested cp;
1610 struct hci_cp_auth_requested cp; 1610 cp.handle = ev->handle;
1611 cp.handle = ev->handle; 1611 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
1612 hci_send_cmd(hdev,
1613 HCI_OP_AUTH_REQUESTED,
1614 sizeof(cp), &cp); 1612 sizeof(cp), &cp);
1615 }
1616 } else { 1613 } else {
1617 conn->state = BT_CONNECTED; 1614 conn->state = BT_CONNECTED;
1618 hci_proto_connect_cfm(conn, ev->status); 1615 hci_proto_connect_cfm(conn, ev->status);
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 3396d5bdef1c..9610a9c85b98 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -55,7 +55,7 @@
55#define BT_DBG(D...) 55#define BT_DBG(D...)
56#endif 56#endif
57 57
58#define VERSION "2.10" 58#define VERSION "2.11"
59 59
60static u32 l2cap_feat_mask = 0x0000; 60static u32 l2cap_feat_mask = 0x0000;
61 61
@@ -778,6 +778,7 @@ static int l2cap_do_connect(struct sock *sk)
778 struct l2cap_conn *conn; 778 struct l2cap_conn *conn;
779 struct hci_conn *hcon; 779 struct hci_conn *hcon;
780 struct hci_dev *hdev; 780 struct hci_dev *hdev;
781 __u8 auth_type;
781 int err = 0; 782 int err = 0;
782 783
783 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm); 784 BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm);
@@ -789,7 +790,21 @@ static int l2cap_do_connect(struct sock *sk)
789 790
790 err = -ENOMEM; 791 err = -ENOMEM;
791 792
792 hcon = hci_connect(hdev, ACL_LINK, dst); 793 if (l2cap_pi(sk)->link_mode & L2CAP_LM_AUTH ||
794 l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT ||
795 l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE) {
796 if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001))
797 auth_type = HCI_AT_NO_BONDING_MITM;
798 else
799 auth_type = HCI_AT_GENERAL_BONDING_MITM;
800 } else {
801 if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001))
802 auth_type = HCI_AT_NO_BONDING;
803 else
804 auth_type = HCI_AT_GENERAL_BONDING;
805 }
806
807 hcon = hci_connect(hdev, ACL_LINK, dst, auth_type);
793 if (!hcon) 808 if (!hcon)
794 goto done; 809 goto done;
795 810
@@ -1553,10 +1568,10 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
1553 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; 1568 struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
1554 struct l2cap_conn_rsp rsp; 1569 struct l2cap_conn_rsp rsp;
1555 struct sock *sk, *parent; 1570 struct sock *sk, *parent;
1556 int result, status = 0; 1571 int result, status = L2CAP_CS_NO_INFO;
1557 1572
1558 u16 dcid = 0, scid = __le16_to_cpu(req->scid); 1573 u16 dcid = 0, scid = __le16_to_cpu(req->scid);
1559 __le16 psm = req->psm; 1574 __le16 psm = req->psm;
1560 1575
1561 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid); 1576 BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
1562 1577
@@ -1567,6 +1582,13 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
1567 goto sendresp; 1582 goto sendresp;
1568 } 1583 }
1569 1584
1585 /* Check if the ACL is secure enough (if not SDP) */
1586 if (psm != cpu_to_le16(0x0001) &&
1587 !hci_conn_check_link_mode(conn->hcon)) {
1588 result = L2CAP_CR_SEC_BLOCK;
1589 goto response;
1590 }
1591
1570 result = L2CAP_CR_NO_MEM; 1592 result = L2CAP_CR_NO_MEM;
1571 1593
1572 /* Check for backlog size */ 1594 /* Check for backlog size */
@@ -2224,7 +2246,7 @@ static int l2cap_auth_cfm(struct hci_conn *hcon, u8 status)
2224 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); 2246 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
2225 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); 2247 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
2226 rsp.result = cpu_to_le16(result); 2248 rsp.result = cpu_to_le16(result);
2227 rsp.status = cpu_to_le16(0); 2249 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
2228 l2cap_send_cmd(conn, l2cap_pi(sk)->ident, 2250 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
2229 L2CAP_CONN_RSP, sizeof(rsp), &rsp); 2251 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
2230 } 2252 }
@@ -2296,7 +2318,7 @@ static int l2cap_encrypt_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
2296 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); 2318 rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
2297 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); 2319 rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
2298 rsp.result = cpu_to_le16(result); 2320 rsp.result = cpu_to_le16(result);
2299 rsp.status = cpu_to_le16(0); 2321 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
2300 l2cap_send_cmd(conn, l2cap_pi(sk)->ident, 2322 l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
2301 L2CAP_CONN_RSP, sizeof(rsp), &rsp); 2323 L2CAP_CONN_RSP, sizeof(rsp), &rsp);
2302 } 2324 }
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index a16011fedc1d..0cc91e6da76d 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -200,7 +200,7 @@ static int sco_connect(struct sock *sk)
200 else 200 else
201 type = SCO_LINK; 201 type = SCO_LINK;
202 202
203 hcon = hci_connect(hdev, type, dst); 203 hcon = hci_connect(hdev, type, dst, HCI_AT_NO_BONDING);
204 if (!hcon) 204 if (!hcon)
205 goto done; 205 goto done;
206 206
diff --git a/net/bridge/br.c b/net/bridge/br.c
index 573acdf6f9ff..4d2c1f1cb524 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -28,6 +28,10 @@ static const struct stp_proto br_stp_proto = {
28 .rcv = br_stp_rcv, 28 .rcv = br_stp_rcv,
29}; 29};
30 30
31static struct pernet_operations br_net_ops = {
32 .exit = br_net_exit,
33};
34
31static int __init br_init(void) 35static int __init br_init(void)
32{ 36{
33 int err; 37 int err;
@@ -42,18 +46,22 @@ static int __init br_init(void)
42 if (err) 46 if (err)
43 goto err_out; 47 goto err_out;
44 48
45 err = br_netfilter_init(); 49 err = register_pernet_subsys(&br_net_ops);
46 if (err) 50 if (err)
47 goto err_out1; 51 goto err_out1;
48 52
49 err = register_netdevice_notifier(&br_device_notifier); 53 err = br_netfilter_init();
50 if (err) 54 if (err)
51 goto err_out2; 55 goto err_out2;
52 56
53 err = br_netlink_init(); 57 err = register_netdevice_notifier(&br_device_notifier);
54 if (err) 58 if (err)
55 goto err_out3; 59 goto err_out3;
56 60
61 err = br_netlink_init();
62 if (err)
63 goto err_out4;
64
57 brioctl_set(br_ioctl_deviceless_stub); 65 brioctl_set(br_ioctl_deviceless_stub);
58 br_handle_frame_hook = br_handle_frame; 66 br_handle_frame_hook = br_handle_frame;
59 67
@@ -61,10 +69,12 @@ static int __init br_init(void)
61 br_fdb_put_hook = br_fdb_put; 69 br_fdb_put_hook = br_fdb_put;
62 70
63 return 0; 71 return 0;
64err_out3: 72err_out4:
65 unregister_netdevice_notifier(&br_device_notifier); 73 unregister_netdevice_notifier(&br_device_notifier);
66err_out2: 74err_out3:
67 br_netfilter_fini(); 75 br_netfilter_fini();
76err_out2:
77 unregister_pernet_subsys(&br_net_ops);
68err_out1: 78err_out1:
69 br_fdb_fini(); 79 br_fdb_fini();
70err_out: 80err_out:
@@ -80,7 +90,7 @@ static void __exit br_deinit(void)
80 unregister_netdevice_notifier(&br_device_notifier); 90 unregister_netdevice_notifier(&br_device_notifier);
81 brioctl_set(NULL); 91 brioctl_set(NULL);
82 92
83 br_cleanup_bridges(); 93 unregister_pernet_subsys(&br_net_ops);
84 94
85 synchronize_net(); 95 synchronize_net();
86 96
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index 4f52c3d50ebe..22ba8632196f 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -178,5 +178,6 @@ void br_dev_setup(struct net_device *dev)
178 dev->priv_flags = IFF_EBRIDGE; 178 dev->priv_flags = IFF_EBRIDGE;
179 179
180 dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | 180 dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
181 NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_LLTX; 181 NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_LLTX |
182 NETIF_F_NETNS_LOCAL;
182} 183}
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 63c18aacde8c..573e20f7dba4 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -168,7 +168,7 @@ static void del_br(struct net_bridge *br)
168 unregister_netdevice(br->dev); 168 unregister_netdevice(br->dev);
169} 169}
170 170
171static struct net_device *new_bridge_dev(const char *name) 171static struct net_device *new_bridge_dev(struct net *net, const char *name)
172{ 172{
173 struct net_bridge *br; 173 struct net_bridge *br;
174 struct net_device *dev; 174 struct net_device *dev;
@@ -178,6 +178,7 @@ static struct net_device *new_bridge_dev(const char *name)
178 178
179 if (!dev) 179 if (!dev)
180 return NULL; 180 return NULL;
181 dev_net_set(dev, net);
181 182
182 br = netdev_priv(dev); 183 br = netdev_priv(dev);
183 br->dev = dev; 184 br->dev = dev;
@@ -262,12 +263,12 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br,
262 return p; 263 return p;
263} 264}
264 265
265int br_add_bridge(const char *name) 266int br_add_bridge(struct net *net, const char *name)
266{ 267{
267 struct net_device *dev; 268 struct net_device *dev;
268 int ret; 269 int ret;
269 270
270 dev = new_bridge_dev(name); 271 dev = new_bridge_dev(net, name);
271 if (!dev) 272 if (!dev)
272 return -ENOMEM; 273 return -ENOMEM;
273 274
@@ -294,13 +295,13 @@ out_free:
294 goto out; 295 goto out;
295} 296}
296 297
297int br_del_bridge(const char *name) 298int br_del_bridge(struct net *net, const char *name)
298{ 299{
299 struct net_device *dev; 300 struct net_device *dev;
300 int ret = 0; 301 int ret = 0;
301 302
302 rtnl_lock(); 303 rtnl_lock();
303 dev = __dev_get_by_name(&init_net, name); 304 dev = __dev_get_by_name(net, name);
304 if (dev == NULL) 305 if (dev == NULL)
305 ret = -ENXIO; /* Could not find device */ 306 ret = -ENXIO; /* Could not find device */
306 307
@@ -445,13 +446,13 @@ int br_del_if(struct net_bridge *br, struct net_device *dev)
445 return 0; 446 return 0;
446} 447}
447 448
448void __exit br_cleanup_bridges(void) 449void br_net_exit(struct net *net)
449{ 450{
450 struct net_device *dev; 451 struct net_device *dev;
451 452
452 rtnl_lock(); 453 rtnl_lock();
453restart: 454restart:
454 for_each_netdev(&init_net, dev) { 455 for_each_netdev(net, dev) {
455 if (dev->priv_flags & IFF_EBRIDGE) { 456 if (dev->priv_flags & IFF_EBRIDGE) {
456 del_br(dev->priv); 457 del_br(dev->priv);
457 goto restart; 458 goto restart;
diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c
index eeee218eed80..6a6433daaf27 100644
--- a/net/bridge/br_ioctl.c
+++ b/net/bridge/br_ioctl.c
@@ -21,12 +21,12 @@
21#include "br_private.h" 21#include "br_private.h"
22 22
23/* called with RTNL */ 23/* called with RTNL */
24static int get_bridge_ifindices(int *indices, int num) 24static int get_bridge_ifindices(struct net *net, int *indices, int num)
25{ 25{
26 struct net_device *dev; 26 struct net_device *dev;
27 int i = 0; 27 int i = 0;
28 28
29 for_each_netdev(&init_net, dev) { 29 for_each_netdev(net, dev) {
30 if (i >= num) 30 if (i >= num)
31 break; 31 break;
32 if (dev->priv_flags & IFF_EBRIDGE) 32 if (dev->priv_flags & IFF_EBRIDGE)
@@ -89,7 +89,7 @@ static int add_del_if(struct net_bridge *br, int ifindex, int isadd)
89 if (!capable(CAP_NET_ADMIN)) 89 if (!capable(CAP_NET_ADMIN))
90 return -EPERM; 90 return -EPERM;
91 91
92 dev = dev_get_by_index(&init_net, ifindex); 92 dev = dev_get_by_index(dev_net(br->dev), ifindex);
93 if (dev == NULL) 93 if (dev == NULL)
94 return -EINVAL; 94 return -EINVAL;
95 95
@@ -188,15 +188,21 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
188 return 0; 188 return 0;
189 189
190 case BRCTL_SET_BRIDGE_HELLO_TIME: 190 case BRCTL_SET_BRIDGE_HELLO_TIME:
191 {
192 unsigned long t = clock_t_to_jiffies(args[1]);
191 if (!capable(CAP_NET_ADMIN)) 193 if (!capable(CAP_NET_ADMIN))
192 return -EPERM; 194 return -EPERM;
193 195
196 if (t < HZ)
197 return -EINVAL;
198
194 spin_lock_bh(&br->lock); 199 spin_lock_bh(&br->lock);
195 br->bridge_hello_time = clock_t_to_jiffies(args[1]); 200 br->bridge_hello_time = t;
196 if (br_is_root_bridge(br)) 201 if (br_is_root_bridge(br))
197 br->hello_time = br->bridge_hello_time; 202 br->hello_time = br->bridge_hello_time;
198 spin_unlock_bh(&br->lock); 203 spin_unlock_bh(&br->lock);
199 return 0; 204 return 0;
205 }
200 206
201 case BRCTL_SET_BRIDGE_MAX_AGE: 207 case BRCTL_SET_BRIDGE_MAX_AGE:
202 if (!capable(CAP_NET_ADMIN)) 208 if (!capable(CAP_NET_ADMIN))
@@ -309,7 +315,7 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
309 return -EOPNOTSUPP; 315 return -EOPNOTSUPP;
310} 316}
311 317
312static int old_deviceless(void __user *uarg) 318static int old_deviceless(struct net *net, void __user *uarg)
313{ 319{
314 unsigned long args[3]; 320 unsigned long args[3];
315 321
@@ -331,7 +337,7 @@ static int old_deviceless(void __user *uarg)
331 if (indices == NULL) 337 if (indices == NULL)
332 return -ENOMEM; 338 return -ENOMEM;
333 339
334 args[2] = get_bridge_ifindices(indices, args[2]); 340 args[2] = get_bridge_ifindices(net, indices, args[2]);
335 341
336 ret = copy_to_user((void __user *)args[1], indices, args[2]*sizeof(int)) 342 ret = copy_to_user((void __user *)args[1], indices, args[2]*sizeof(int))
337 ? -EFAULT : args[2]; 343 ? -EFAULT : args[2];
@@ -354,9 +360,9 @@ static int old_deviceless(void __user *uarg)
354 buf[IFNAMSIZ-1] = 0; 360 buf[IFNAMSIZ-1] = 0;
355 361
356 if (args[0] == BRCTL_ADD_BRIDGE) 362 if (args[0] == BRCTL_ADD_BRIDGE)
357 return br_add_bridge(buf); 363 return br_add_bridge(net, buf);
358 364
359 return br_del_bridge(buf); 365 return br_del_bridge(net, buf);
360 } 366 }
361 } 367 }
362 368
@@ -368,7 +374,7 @@ int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __user *uar
368 switch (cmd) { 374 switch (cmd) {
369 case SIOCGIFBR: 375 case SIOCGIFBR:
370 case SIOCSIFBR: 376 case SIOCSIFBR:
371 return old_deviceless(uarg); 377 return old_deviceless(net, uarg);
372 378
373 case SIOCBRADDBR: 379 case SIOCBRADDBR:
374 case SIOCBRDELBR: 380 case SIOCBRDELBR:
@@ -383,9 +389,9 @@ int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __user *uar
383 389
384 buf[IFNAMSIZ-1] = 0; 390 buf[IFNAMSIZ-1] = 0;
385 if (cmd == SIOCBRADDBR) 391 if (cmd == SIOCBRADDBR)
386 return br_add_bridge(buf); 392 return br_add_bridge(net, buf);
387 393
388 return br_del_bridge(buf); 394 return br_del_bridge(net, buf);
389 } 395 }
390 } 396 }
391 return -EOPNOTSUPP; 397 return -EOPNOTSUPP;
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 6a9a6cd74b1e..a4abed5b4c44 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -657,7 +657,7 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb,
657{ 657{
658 struct nf_bridge_info *nf_bridge; 658 struct nf_bridge_info *nf_bridge;
659 struct net_device *parent; 659 struct net_device *parent;
660 int pf; 660 u_int8_t pf;
661 661
662 if (!skb->nf_bridge) 662 if (!skb->nf_bridge)
663 return NF_ACCEPT; 663 return NF_ACCEPT;
@@ -791,7 +791,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff *skb,
791{ 791{
792 struct nf_bridge_info *nf_bridge = skb->nf_bridge; 792 struct nf_bridge_info *nf_bridge = skb->nf_bridge;
793 struct net_device *realoutdev = bridge_parent(skb->dev); 793 struct net_device *realoutdev = bridge_parent(skb->dev);
794 int pf; 794 u_int8_t pf;
795 795
796#ifdef CONFIG_NETFILTER_DEBUG 796#ifdef CONFIG_NETFILTER_DEBUG
797 /* Be very paranoid. This probably won't happen anymore, but let's 797 /* Be very paranoid. This probably won't happen anymore, but let's
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index f155e6ce8a21..ba7be195803c 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -82,6 +82,7 @@ nla_put_failure:
82 */ 82 */
83void br_ifinfo_notify(int event, struct net_bridge_port *port) 83void br_ifinfo_notify(int event, struct net_bridge_port *port)
84{ 84{
85 struct net *net = dev_net(port->dev);
85 struct sk_buff *skb; 86 struct sk_buff *skb;
86 int err = -ENOBUFS; 87 int err = -ENOBUFS;
87 88
@@ -97,10 +98,10 @@ void br_ifinfo_notify(int event, struct net_bridge_port *port)
97 kfree_skb(skb); 98 kfree_skb(skb);
98 goto errout; 99 goto errout;
99 } 100 }
100 err = rtnl_notify(skb, &init_net,0, RTNLGRP_LINK, NULL, GFP_ATOMIC); 101 err = rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
101errout: 102errout:
102 if (err < 0) 103 if (err < 0)
103 rtnl_set_sk_err(&init_net, RTNLGRP_LINK, err); 104 rtnl_set_sk_err(net, RTNLGRP_LINK, err);
104} 105}
105 106
106/* 107/*
@@ -112,11 +113,8 @@ static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
112 struct net_device *dev; 113 struct net_device *dev;
113 int idx; 114 int idx;
114 115
115 if (net != &init_net)
116 return 0;
117
118 idx = 0; 116 idx = 0;
119 for_each_netdev(&init_net, dev) { 117 for_each_netdev(net, dev) {
120 /* not a bridge port */ 118 /* not a bridge port */
121 if (dev->br_port == NULL || idx < cb->args[0]) 119 if (dev->br_port == NULL || idx < cb->args[0])
122 goto skip; 120 goto skip;
@@ -147,9 +145,6 @@ static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
147 struct net_bridge_port *p; 145 struct net_bridge_port *p;
148 u8 new_state; 146 u8 new_state;
149 147
150 if (net != &init_net)
151 return -EINVAL;
152
153 if (nlmsg_len(nlh) < sizeof(*ifm)) 148 if (nlmsg_len(nlh) < sizeof(*ifm))
154 return -EINVAL; 149 return -EINVAL;
155 150
@@ -165,7 +160,7 @@ static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
165 if (new_state > BR_STATE_BLOCKING) 160 if (new_state > BR_STATE_BLOCKING)
166 return -EINVAL; 161 return -EINVAL;
167 162
168 dev = __dev_get_by_index(&init_net, ifm->ifi_index); 163 dev = __dev_get_by_index(net, ifm->ifi_index);
169 if (!dev) 164 if (!dev)
170 return -ENODEV; 165 return -ENODEV;
171 166
diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c
index 76340bdd052e..763a3ec292e5 100644
--- a/net/bridge/br_notify.c
+++ b/net/bridge/br_notify.c
@@ -35,9 +35,6 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
35 struct net_bridge_port *p = dev->br_port; 35 struct net_bridge_port *p = dev->br_port;
36 struct net_bridge *br; 36 struct net_bridge *br;
37 37
38 if (!net_eq(dev_net(dev), &init_net))
39 return NOTIFY_DONE;
40
41 /* not a port of a bridge */ 38 /* not a port of a bridge */
42 if (p == NULL) 39 if (p == NULL)
43 return NOTIFY_DONE; 40 return NOTIFY_DONE;
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index c3dc18ddc043..b6c3b71974dc 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -178,9 +178,9 @@ extern void br_flood_forward(struct net_bridge *br, struct sk_buff *skb);
178 178
179/* br_if.c */ 179/* br_if.c */
180extern void br_port_carrier_check(struct net_bridge_port *p); 180extern void br_port_carrier_check(struct net_bridge_port *p);
181extern int br_add_bridge(const char *name); 181extern int br_add_bridge(struct net *net, const char *name);
182extern int br_del_bridge(const char *name); 182extern int br_del_bridge(struct net *net, const char *name);
183extern void br_cleanup_bridges(void); 183extern void br_net_exit(struct net *net);
184extern int br_add_if(struct net_bridge *br, 184extern int br_add_if(struct net_bridge *br,
185 struct net_device *dev); 185 struct net_device *dev);
186extern int br_del_if(struct net_bridge *br, 186extern int br_del_if(struct net_bridge *br,
diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c
index 8b200f96f722..81ae40b3f655 100644
--- a/net/bridge/br_stp_bpdu.c
+++ b/net/bridge/br_stp_bpdu.c
@@ -140,9 +140,6 @@ void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb,
140 struct net_bridge *br; 140 struct net_bridge *br;
141 const unsigned char *buf; 141 const unsigned char *buf;
142 142
143 if (!net_eq(dev_net(dev), &init_net))
144 goto err;
145
146 if (!p) 143 if (!p)
147 goto err; 144 goto err;
148 145
diff --git a/net/bridge/br_sysfs_br.c b/net/bridge/br_sysfs_br.c
index 27d6a511c8c1..158dee8b4965 100644
--- a/net/bridge/br_sysfs_br.c
+++ b/net/bridge/br_sysfs_br.c
@@ -29,11 +29,12 @@
29 */ 29 */
30static ssize_t store_bridge_parm(struct device *d, 30static ssize_t store_bridge_parm(struct device *d,
31 const char *buf, size_t len, 31 const char *buf, size_t len,
32 void (*set)(struct net_bridge *, unsigned long)) 32 int (*set)(struct net_bridge *, unsigned long))
33{ 33{
34 struct net_bridge *br = to_bridge(d); 34 struct net_bridge *br = to_bridge(d);
35 char *endp; 35 char *endp;
36 unsigned long val; 36 unsigned long val;
37 int err;
37 38
38 if (!capable(CAP_NET_ADMIN)) 39 if (!capable(CAP_NET_ADMIN))
39 return -EPERM; 40 return -EPERM;
@@ -43,9 +44,9 @@ static ssize_t store_bridge_parm(struct device *d,
43 return -EINVAL; 44 return -EINVAL;
44 45
45 spin_lock_bh(&br->lock); 46 spin_lock_bh(&br->lock);
46 (*set)(br, val); 47 err = (*set)(br, val);
47 spin_unlock_bh(&br->lock); 48 spin_unlock_bh(&br->lock);
48 return len; 49 return err ? err : len;
49} 50}
50 51
51 52
@@ -56,12 +57,13 @@ static ssize_t show_forward_delay(struct device *d,
56 return sprintf(buf, "%lu\n", jiffies_to_clock_t(br->forward_delay)); 57 return sprintf(buf, "%lu\n", jiffies_to_clock_t(br->forward_delay));
57} 58}
58 59
59static void set_forward_delay(struct net_bridge *br, unsigned long val) 60static int set_forward_delay(struct net_bridge *br, unsigned long val)
60{ 61{
61 unsigned long delay = clock_t_to_jiffies(val); 62 unsigned long delay = clock_t_to_jiffies(val);
62 br->forward_delay = delay; 63 br->forward_delay = delay;
63 if (br_is_root_bridge(br)) 64 if (br_is_root_bridge(br))
64 br->bridge_forward_delay = delay; 65 br->bridge_forward_delay = delay;
66 return 0;
65} 67}
66 68
67static ssize_t store_forward_delay(struct device *d, 69static ssize_t store_forward_delay(struct device *d,
@@ -80,12 +82,17 @@ static ssize_t show_hello_time(struct device *d, struct device_attribute *attr,
80 jiffies_to_clock_t(to_bridge(d)->hello_time)); 82 jiffies_to_clock_t(to_bridge(d)->hello_time));
81} 83}
82 84
83static void set_hello_time(struct net_bridge *br, unsigned long val) 85static int set_hello_time(struct net_bridge *br, unsigned long val)
84{ 86{
85 unsigned long t = clock_t_to_jiffies(val); 87 unsigned long t = clock_t_to_jiffies(val);
88
89 if (t < HZ)
90 return -EINVAL;
91
86 br->hello_time = t; 92 br->hello_time = t;
87 if (br_is_root_bridge(br)) 93 if (br_is_root_bridge(br))
88 br->bridge_hello_time = t; 94 br->bridge_hello_time = t;
95 return 0;
89} 96}
90 97
91static ssize_t store_hello_time(struct device *d, 98static ssize_t store_hello_time(struct device *d,
@@ -104,12 +111,13 @@ static ssize_t show_max_age(struct device *d, struct device_attribute *attr,
104 jiffies_to_clock_t(to_bridge(d)->max_age)); 111 jiffies_to_clock_t(to_bridge(d)->max_age));
105} 112}
106 113
107static void set_max_age(struct net_bridge *br, unsigned long val) 114static int set_max_age(struct net_bridge *br, unsigned long val)
108{ 115{
109 unsigned long t = clock_t_to_jiffies(val); 116 unsigned long t = clock_t_to_jiffies(val);
110 br->max_age = t; 117 br->max_age = t;
111 if (br_is_root_bridge(br)) 118 if (br_is_root_bridge(br))
112 br->bridge_max_age = t; 119 br->bridge_max_age = t;
120 return 0;
113} 121}
114 122
115static ssize_t store_max_age(struct device *d, struct device_attribute *attr, 123static ssize_t store_max_age(struct device *d, struct device_attribute *attr,
@@ -126,9 +134,10 @@ static ssize_t show_ageing_time(struct device *d,
126 return sprintf(buf, "%lu\n", jiffies_to_clock_t(br->ageing_time)); 134 return sprintf(buf, "%lu\n", jiffies_to_clock_t(br->ageing_time));
127} 135}
128 136
129static void set_ageing_time(struct net_bridge *br, unsigned long val) 137static int set_ageing_time(struct net_bridge *br, unsigned long val)
130{ 138{
131 br->ageing_time = clock_t_to_jiffies(val); 139 br->ageing_time = clock_t_to_jiffies(val);
140 return 0;
132} 141}
133 142
134static ssize_t store_ageing_time(struct device *d, 143static ssize_t store_ageing_time(struct device *d,
@@ -180,9 +189,10 @@ static ssize_t show_priority(struct device *d, struct device_attribute *attr,
180 (br->bridge_id.prio[0] << 8) | br->bridge_id.prio[1]); 189 (br->bridge_id.prio[0] << 8) | br->bridge_id.prio[1]);
181} 190}
182 191
183static void set_priority(struct net_bridge *br, unsigned long val) 192static int set_priority(struct net_bridge *br, unsigned long val)
184{ 193{
185 br_stp_set_bridge_priority(br, (u16) val); 194 br_stp_set_bridge_priority(br, (u16) val);
195 return 0;
186} 196}
187 197
188static ssize_t store_priority(struct device *d, struct device_attribute *attr, 198static ssize_t store_priority(struct device *d, struct device_attribute *attr,
diff --git a/net/bridge/netfilter/Kconfig b/net/bridge/netfilter/Kconfig
index 909479794999..366d3e9d51f8 100644
--- a/net/bridge/netfilter/Kconfig
+++ b/net/bridge/netfilter/Kconfig
@@ -2,21 +2,21 @@
2# Bridge netfilter configuration 2# Bridge netfilter configuration
3# 3#
4 4
5menu "Bridge: Netfilter Configuration" 5menuconfig BRIDGE_NF_EBTABLES
6 depends on BRIDGE && BRIDGE_NETFILTER
7
8config BRIDGE_NF_EBTABLES
9 tristate "Ethernet Bridge tables (ebtables) support" 6 tristate "Ethernet Bridge tables (ebtables) support"
7 select NETFILTER_XTABLES
10 help 8 help
11 ebtables is a general, extensible frame/packet identification 9 ebtables is a general, extensible frame/packet identification
12 framework. Say 'Y' or 'M' here if you want to do Ethernet 10 framework. Say 'Y' or 'M' here if you want to do Ethernet
13 filtering/NAT/brouting on the Ethernet bridge. 11 filtering/NAT/brouting on the Ethernet bridge.
12
13if BRIDGE_NF_EBTABLES
14
14# 15#
15# tables 16# tables
16# 17#
17config BRIDGE_EBT_BROUTE 18config BRIDGE_EBT_BROUTE
18 tristate "ebt: broute table support" 19 tristate "ebt: broute table support"
19 depends on BRIDGE_NF_EBTABLES
20 help 20 help
21 The ebtables broute table is used to define rules that decide between 21 The ebtables broute table is used to define rules that decide between
22 bridging and routing frames, giving Linux the functionality of a 22 bridging and routing frames, giving Linux the functionality of a
@@ -27,7 +27,6 @@ config BRIDGE_EBT_BROUTE
27 27
28config BRIDGE_EBT_T_FILTER 28config BRIDGE_EBT_T_FILTER
29 tristate "ebt: filter table support" 29 tristate "ebt: filter table support"
30 depends on BRIDGE_NF_EBTABLES
31 help 30 help
32 The ebtables filter table is used to define frame filtering rules at 31 The ebtables filter table is used to define frame filtering rules at
33 local input, forwarding and local output. See the man page for 32 local input, forwarding and local output. See the man page for
@@ -37,7 +36,6 @@ config BRIDGE_EBT_T_FILTER
37 36
38config BRIDGE_EBT_T_NAT 37config BRIDGE_EBT_T_NAT
39 tristate "ebt: nat table support" 38 tristate "ebt: nat table support"
40 depends on BRIDGE_NF_EBTABLES
41 help 39 help
42 The ebtables nat table is used to define rules that alter the MAC 40 The ebtables nat table is used to define rules that alter the MAC
43 source address (MAC SNAT) or the MAC destination address (MAC DNAT). 41 source address (MAC SNAT) or the MAC destination address (MAC DNAT).
@@ -49,7 +47,6 @@ config BRIDGE_EBT_T_NAT
49# 47#
50config BRIDGE_EBT_802_3 48config BRIDGE_EBT_802_3
51 tristate "ebt: 802.3 filter support" 49 tristate "ebt: 802.3 filter support"
52 depends on BRIDGE_NF_EBTABLES
53 help 50 help
54 This option adds matching support for 802.3 Ethernet frames. 51 This option adds matching support for 802.3 Ethernet frames.
55 52
@@ -57,7 +54,6 @@ config BRIDGE_EBT_802_3
57 54
58config BRIDGE_EBT_AMONG 55config BRIDGE_EBT_AMONG
59 tristate "ebt: among filter support" 56 tristate "ebt: among filter support"
60 depends on BRIDGE_NF_EBTABLES
61 help 57 help
62 This option adds the among match, which allows matching the MAC source 58 This option adds the among match, which allows matching the MAC source
63 and/or destination address on a list of addresses. Optionally, 59 and/or destination address on a list of addresses. Optionally,
@@ -67,7 +63,6 @@ config BRIDGE_EBT_AMONG
67 63
68config BRIDGE_EBT_ARP 64config BRIDGE_EBT_ARP
69 tristate "ebt: ARP filter support" 65 tristate "ebt: ARP filter support"
70 depends on BRIDGE_NF_EBTABLES
71 help 66 help
72 This option adds the ARP match, which allows ARP and RARP header field 67 This option adds the ARP match, which allows ARP and RARP header field
73 filtering. 68 filtering.
@@ -76,7 +71,6 @@ config BRIDGE_EBT_ARP
76 71
77config BRIDGE_EBT_IP 72config BRIDGE_EBT_IP
78 tristate "ebt: IP filter support" 73 tristate "ebt: IP filter support"
79 depends on BRIDGE_NF_EBTABLES
80 help 74 help
81 This option adds the IP match, which allows basic IP header field 75 This option adds the IP match, which allows basic IP header field
82 filtering. 76 filtering.
@@ -94,7 +88,6 @@ config BRIDGE_EBT_IP6
94 88
95config BRIDGE_EBT_LIMIT 89config BRIDGE_EBT_LIMIT
96 tristate "ebt: limit match support" 90 tristate "ebt: limit match support"
97 depends on BRIDGE_NF_EBTABLES
98 help 91 help
99 This option adds the limit match, which allows you to control 92 This option adds the limit match, which allows you to control
100 the rate at which a rule can be matched. This match is the 93 the rate at which a rule can be matched. This match is the
@@ -105,7 +98,6 @@ config BRIDGE_EBT_LIMIT
105 98
106config BRIDGE_EBT_MARK 99config BRIDGE_EBT_MARK
107 tristate "ebt: mark filter support" 100 tristate "ebt: mark filter support"
108 depends on BRIDGE_NF_EBTABLES
109 help 101 help
110 This option adds the mark match, which allows matching frames based on 102 This option adds the mark match, which allows matching frames based on
111 the 'nfmark' value in the frame. This can be set by the mark target. 103 the 'nfmark' value in the frame. This can be set by the mark target.
@@ -116,7 +108,6 @@ config BRIDGE_EBT_MARK
116 108
117config BRIDGE_EBT_PKTTYPE 109config BRIDGE_EBT_PKTTYPE
118 tristate "ebt: packet type filter support" 110 tristate "ebt: packet type filter support"
119 depends on BRIDGE_NF_EBTABLES
120 help 111 help
121 This option adds the packet type match, which allows matching on the 112 This option adds the packet type match, which allows matching on the
122 type of packet based on its Ethernet "class" (as determined by 113 type of packet based on its Ethernet "class" (as determined by
@@ -127,7 +118,6 @@ config BRIDGE_EBT_PKTTYPE
127 118
128config BRIDGE_EBT_STP 119config BRIDGE_EBT_STP
129 tristate "ebt: STP filter support" 120 tristate "ebt: STP filter support"
130 depends on BRIDGE_NF_EBTABLES
131 help 121 help
132 This option adds the Spanning Tree Protocol match, which 122 This option adds the Spanning Tree Protocol match, which
133 allows STP header field filtering. 123 allows STP header field filtering.
@@ -136,7 +126,6 @@ config BRIDGE_EBT_STP
136 126
137config BRIDGE_EBT_VLAN 127config BRIDGE_EBT_VLAN
138 tristate "ebt: 802.1Q VLAN filter support" 128 tristate "ebt: 802.1Q VLAN filter support"
139 depends on BRIDGE_NF_EBTABLES
140 help 129 help
141 This option adds the 802.1Q vlan match, which allows the filtering of 130 This option adds the 802.1Q vlan match, which allows the filtering of
142 802.1Q vlan fields. 131 802.1Q vlan fields.
@@ -156,7 +145,6 @@ config BRIDGE_EBT_ARPREPLY
156 145
157config BRIDGE_EBT_DNAT 146config BRIDGE_EBT_DNAT
158 tristate "ebt: dnat target support" 147 tristate "ebt: dnat target support"
159 depends on BRIDGE_NF_EBTABLES
160 help 148 help
161 This option adds the MAC DNAT target, which allows altering the MAC 149 This option adds the MAC DNAT target, which allows altering the MAC
162 destination address of frames. 150 destination address of frames.
@@ -165,7 +153,6 @@ config BRIDGE_EBT_DNAT
165 153
166config BRIDGE_EBT_MARK_T 154config BRIDGE_EBT_MARK_T
167 tristate "ebt: mark target support" 155 tristate "ebt: mark target support"
168 depends on BRIDGE_NF_EBTABLES
169 help 156 help
170 This option adds the mark target, which allows marking frames by 157 This option adds the mark target, which allows marking frames by
171 setting the 'nfmark' value in the frame. 158 setting the 'nfmark' value in the frame.
@@ -176,7 +163,6 @@ config BRIDGE_EBT_MARK_T
176 163
177config BRIDGE_EBT_REDIRECT 164config BRIDGE_EBT_REDIRECT
178 tristate "ebt: redirect target support" 165 tristate "ebt: redirect target support"
179 depends on BRIDGE_NF_EBTABLES
180 help 166 help
181 This option adds the MAC redirect target, which allows altering the MAC 167 This option adds the MAC redirect target, which allows altering the MAC
182 destination address of a frame to that of the device it arrived on. 168 destination address of a frame to that of the device it arrived on.
@@ -185,7 +171,6 @@ config BRIDGE_EBT_REDIRECT
185 171
186config BRIDGE_EBT_SNAT 172config BRIDGE_EBT_SNAT
187 tristate "ebt: snat target support" 173 tristate "ebt: snat target support"
188 depends on BRIDGE_NF_EBTABLES
189 help 174 help
190 This option adds the MAC SNAT target, which allows altering the MAC 175 This option adds the MAC SNAT target, which allows altering the MAC
191 source address of frames. 176 source address of frames.
@@ -196,7 +181,6 @@ config BRIDGE_EBT_SNAT
196# 181#
197config BRIDGE_EBT_LOG 182config BRIDGE_EBT_LOG
198 tristate "ebt: log support" 183 tristate "ebt: log support"
199 depends on BRIDGE_NF_EBTABLES
200 help 184 help
201 This option adds the log watcher, that you can use in any rule 185 This option adds the log watcher, that you can use in any rule
202 in any ebtables table. It records info about the frame header 186 in any ebtables table. It records info about the frame header
@@ -206,7 +190,6 @@ config BRIDGE_EBT_LOG
206 190
207config BRIDGE_EBT_ULOG 191config BRIDGE_EBT_ULOG
208 tristate "ebt: ulog support (OBSOLETE)" 192 tristate "ebt: ulog support (OBSOLETE)"
209 depends on BRIDGE_NF_EBTABLES
210 help 193 help
211 This option enables the old bridge-specific "ebt_ulog" implementation 194 This option enables the old bridge-specific "ebt_ulog" implementation
212 which has been obsoleted by the new "nfnetlink_log" code (see 195 which has been obsoleted by the new "nfnetlink_log" code (see
@@ -223,7 +206,6 @@ config BRIDGE_EBT_ULOG
223 206
224config BRIDGE_EBT_NFLOG 207config BRIDGE_EBT_NFLOG
225 tristate "ebt: nflog support" 208 tristate "ebt: nflog support"
226 depends on BRIDGE_NF_EBTABLES
227 help 209 help
228 This option enables the nflog watcher, which allows to LOG 210 This option enables the nflog watcher, which allows to LOG
229 messages through the netfilter logging API, which can use 211 messages through the netfilter logging API, which can use
@@ -235,4 +217,4 @@ config BRIDGE_EBT_NFLOG
235 217
236 To compile it as a module, choose M here. If unsure, say N. 218 To compile it as a module, choose M here. If unsure, say N.
237 219
238endmenu 220endif # BRIDGE_NF_EBTABLES
diff --git a/net/bridge/netfilter/ebt_802_3.c b/net/bridge/netfilter/ebt_802_3.c
index 98534025360f..bd91dc58d49b 100644
--- a/net/bridge/netfilter/ebt_802_3.c
+++ b/net/bridge/netfilter/ebt_802_3.c
@@ -7,64 +7,63 @@
7 * May 2003 7 * May 2003
8 * 8 *
9 */ 9 */
10 10#include <linux/module.h>
11#include <linux/netfilter/x_tables.h>
11#include <linux/netfilter_bridge/ebtables.h> 12#include <linux/netfilter_bridge/ebtables.h>
12#include <linux/netfilter_bridge/ebt_802_3.h> 13#include <linux/netfilter_bridge/ebt_802_3.h>
13#include <linux/module.h>
14 14
15static int ebt_filter_802_3(const struct sk_buff *skb, const struct net_device *in, 15static bool
16 const struct net_device *out, const void *data, unsigned int datalen) 16ebt_802_3_mt(const struct sk_buff *skb, const struct xt_match_param *par)
17{ 17{
18 const struct ebt_802_3_info *info = data; 18 const struct ebt_802_3_info *info = par->matchinfo;
19 const struct ebt_802_3_hdr *hdr = ebt_802_3_hdr(skb); 19 const struct ebt_802_3_hdr *hdr = ebt_802_3_hdr(skb);
20 __be16 type = hdr->llc.ui.ctrl & IS_UI ? hdr->llc.ui.type : hdr->llc.ni.type; 20 __be16 type = hdr->llc.ui.ctrl & IS_UI ? hdr->llc.ui.type : hdr->llc.ni.type;
21 21
22 if (info->bitmask & EBT_802_3_SAP) { 22 if (info->bitmask & EBT_802_3_SAP) {
23 if (FWINV(info->sap != hdr->llc.ui.ssap, EBT_802_3_SAP)) 23 if (FWINV(info->sap != hdr->llc.ui.ssap, EBT_802_3_SAP))
24 return EBT_NOMATCH; 24 return false;
25 if (FWINV(info->sap != hdr->llc.ui.dsap, EBT_802_3_SAP)) 25 if (FWINV(info->sap != hdr->llc.ui.dsap, EBT_802_3_SAP))
26 return EBT_NOMATCH; 26 return false;
27 } 27 }
28 28
29 if (info->bitmask & EBT_802_3_TYPE) { 29 if (info->bitmask & EBT_802_3_TYPE) {
30 if (!(hdr->llc.ui.dsap == CHECK_TYPE && hdr->llc.ui.ssap == CHECK_TYPE)) 30 if (!(hdr->llc.ui.dsap == CHECK_TYPE && hdr->llc.ui.ssap == CHECK_TYPE))
31 return EBT_NOMATCH; 31 return false;
32 if (FWINV(info->type != type, EBT_802_3_TYPE)) 32 if (FWINV(info->type != type, EBT_802_3_TYPE))
33 return EBT_NOMATCH; 33 return false;
34 } 34 }
35 35
36 return EBT_MATCH; 36 return true;
37} 37}
38 38
39static struct ebt_match filter_802_3; 39static bool ebt_802_3_mt_check(const struct xt_mtchk_param *par)
40static int ebt_802_3_check(const char *tablename, unsigned int hookmask,
41 const struct ebt_entry *e, void *data, unsigned int datalen)
42{ 40{
43 const struct ebt_802_3_info *info = data; 41 const struct ebt_802_3_info *info = par->matchinfo;
44 42
45 if (datalen < sizeof(struct ebt_802_3_info))
46 return -EINVAL;
47 if (info->bitmask & ~EBT_802_3_MASK || info->invflags & ~EBT_802_3_MASK) 43 if (info->bitmask & ~EBT_802_3_MASK || info->invflags & ~EBT_802_3_MASK)
48 return -EINVAL; 44 return false;
49 45
50 return 0; 46 return true;
51} 47}
52 48
53static struct ebt_match filter_802_3 __read_mostly = { 49static struct xt_match ebt_802_3_mt_reg __read_mostly = {
54 .name = EBT_802_3_MATCH, 50 .name = "802_3",
55 .match = ebt_filter_802_3, 51 .revision = 0,
56 .check = ebt_802_3_check, 52 .family = NFPROTO_BRIDGE,
53 .match = ebt_802_3_mt,
54 .checkentry = ebt_802_3_mt_check,
55 .matchsize = XT_ALIGN(sizeof(struct ebt_802_3_info)),
57 .me = THIS_MODULE, 56 .me = THIS_MODULE,
58}; 57};
59 58
60static int __init ebt_802_3_init(void) 59static int __init ebt_802_3_init(void)
61{ 60{
62 return ebt_register_match(&filter_802_3); 61 return xt_register_match(&ebt_802_3_mt_reg);
63} 62}
64 63
65static void __exit ebt_802_3_fini(void) 64static void __exit ebt_802_3_fini(void)
66{ 65{
67 ebt_unregister_match(&filter_802_3); 66 xt_unregister_match(&ebt_802_3_mt_reg);
68} 67}
69 68
70module_init(ebt_802_3_init); 69module_init(ebt_802_3_init);
diff --git a/net/bridge/netfilter/ebt_among.c b/net/bridge/netfilter/ebt_among.c
index 70b6dca5ea75..b595f091f35b 100644
--- a/net/bridge/netfilter/ebt_among.c
+++ b/net/bridge/netfilter/ebt_among.c
@@ -7,15 +7,15 @@
7 * August, 2003 7 * August, 2003
8 * 8 *
9 */ 9 */
10
11#include <linux/netfilter_bridge/ebtables.h>
12#include <linux/netfilter_bridge/ebt_among.h>
13#include <linux/ip.h> 10#include <linux/ip.h>
14#include <linux/if_arp.h> 11#include <linux/if_arp.h>
15#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/netfilter/x_tables.h>
14#include <linux/netfilter_bridge/ebtables.h>
15#include <linux/netfilter_bridge/ebt_among.h>
16 16
17static int ebt_mac_wormhash_contains(const struct ebt_mac_wormhash *wh, 17static bool ebt_mac_wormhash_contains(const struct ebt_mac_wormhash *wh,
18 const char *mac, __be32 ip) 18 const char *mac, __be32 ip)
19{ 19{
20 /* You may be puzzled as to how this code works. 20 /* You may be puzzled as to how this code works.
21 * Some tricks were used, refer to 21 * Some tricks were used, refer to
@@ -33,23 +33,19 @@ static int ebt_mac_wormhash_contains(const struct ebt_mac_wormhash *wh,
33 if (ip) { 33 if (ip) {
34 for (i = start; i < limit; i++) { 34 for (i = start; i < limit; i++) {
35 p = &wh->pool[i]; 35 p = &wh->pool[i];
36 if (cmp[1] == p->cmp[1] && cmp[0] == p->cmp[0]) { 36 if (cmp[1] == p->cmp[1] && cmp[0] == p->cmp[0])
37 if (p->ip == 0 || p->ip == ip) { 37 if (p->ip == 0 || p->ip == ip)
38 return 1; 38 return true;
39 }
40 }
41 } 39 }
42 } else { 40 } else {
43 for (i = start; i < limit; i++) { 41 for (i = start; i < limit; i++) {
44 p = &wh->pool[i]; 42 p = &wh->pool[i];
45 if (cmp[1] == p->cmp[1] && cmp[0] == p->cmp[0]) { 43 if (cmp[1] == p->cmp[1] && cmp[0] == p->cmp[0])
46 if (p->ip == 0) { 44 if (p->ip == 0)
47 return 1; 45 return true;
48 }
49 }
50 } 46 }
51 } 47 }
52 return 0; 48 return false;
53} 49}
54 50
55static int ebt_mac_wormhash_check_integrity(const struct ebt_mac_wormhash 51static int ebt_mac_wormhash_check_integrity(const struct ebt_mac_wormhash
@@ -131,12 +127,10 @@ static int get_ip_src(const struct sk_buff *skb, __be32 *addr)
131 return 0; 127 return 0;
132} 128}
133 129
134static int ebt_filter_among(const struct sk_buff *skb, 130static bool
135 const struct net_device *in, 131ebt_among_mt(const struct sk_buff *skb, const struct xt_match_param *par)
136 const struct net_device *out, const void *data,
137 unsigned int datalen)
138{ 132{
139 const struct ebt_among_info *info = data; 133 const struct ebt_among_info *info = par->matchinfo;
140 const char *dmac, *smac; 134 const char *dmac, *smac;
141 const struct ebt_mac_wormhash *wh_dst, *wh_src; 135 const struct ebt_mac_wormhash *wh_dst, *wh_src;
142 __be32 dip = 0, sip = 0; 136 __be32 dip = 0, sip = 0;
@@ -147,41 +141,41 @@ static int ebt_filter_among(const struct sk_buff *skb,
147 if (wh_src) { 141 if (wh_src) {
148 smac = eth_hdr(skb)->h_source; 142 smac = eth_hdr(skb)->h_source;
149 if (get_ip_src(skb, &sip)) 143 if (get_ip_src(skb, &sip))
150 return EBT_NOMATCH; 144 return false;
151 if (!(info->bitmask & EBT_AMONG_SRC_NEG)) { 145 if (!(info->bitmask & EBT_AMONG_SRC_NEG)) {
152 /* we match only if it contains */ 146 /* we match only if it contains */
153 if (!ebt_mac_wormhash_contains(wh_src, smac, sip)) 147 if (!ebt_mac_wormhash_contains(wh_src, smac, sip))
154 return EBT_NOMATCH; 148 return false;
155 } else { 149 } else {
156 /* we match only if it DOES NOT contain */ 150 /* we match only if it DOES NOT contain */
157 if (ebt_mac_wormhash_contains(wh_src, smac, sip)) 151 if (ebt_mac_wormhash_contains(wh_src, smac, sip))
158 return EBT_NOMATCH; 152 return false;
159 } 153 }
160 } 154 }
161 155
162 if (wh_dst) { 156 if (wh_dst) {
163 dmac = eth_hdr(skb)->h_dest; 157 dmac = eth_hdr(skb)->h_dest;
164 if (get_ip_dst(skb, &dip)) 158 if (get_ip_dst(skb, &dip))
165 return EBT_NOMATCH; 159 return false;
166 if (!(info->bitmask & EBT_AMONG_DST_NEG)) { 160 if (!(info->bitmask & EBT_AMONG_DST_NEG)) {
167 /* we match only if it contains */ 161 /* we match only if it contains */
168 if (!ebt_mac_wormhash_contains(wh_dst, dmac, dip)) 162 if (!ebt_mac_wormhash_contains(wh_dst, dmac, dip))
169 return EBT_NOMATCH; 163 return false;
170 } else { 164 } else {
171 /* we match only if it DOES NOT contain */ 165 /* we match only if it DOES NOT contain */
172 if (ebt_mac_wormhash_contains(wh_dst, dmac, dip)) 166 if (ebt_mac_wormhash_contains(wh_dst, dmac, dip))
173 return EBT_NOMATCH; 167 return false;
174 } 168 }
175 } 169 }
176 170
177 return EBT_MATCH; 171 return true;
178} 172}
179 173
180static int ebt_among_check(const char *tablename, unsigned int hookmask, 174static bool ebt_among_mt_check(const struct xt_mtchk_param *par)
181 const struct ebt_entry *e, void *data,
182 unsigned int datalen)
183{ 175{
184 const struct ebt_among_info *info = data; 176 const struct ebt_among_info *info = par->matchinfo;
177 const struct ebt_entry_match *em =
178 container_of(par->matchinfo, const struct ebt_entry_match, data);
185 int expected_length = sizeof(struct ebt_among_info); 179 int expected_length = sizeof(struct ebt_among_info);
186 const struct ebt_mac_wormhash *wh_dst, *wh_src; 180 const struct ebt_mac_wormhash *wh_dst, *wh_src;
187 int err; 181 int err;
@@ -191,42 +185,45 @@ static int ebt_among_check(const char *tablename, unsigned int hookmask,
191 expected_length += ebt_mac_wormhash_size(wh_dst); 185 expected_length += ebt_mac_wormhash_size(wh_dst);
192 expected_length += ebt_mac_wormhash_size(wh_src); 186 expected_length += ebt_mac_wormhash_size(wh_src);
193 187
194 if (datalen != EBT_ALIGN(expected_length)) { 188 if (em->match_size != EBT_ALIGN(expected_length)) {
195 printk(KERN_WARNING 189 printk(KERN_WARNING
196 "ebtables: among: wrong size: %d " 190 "ebtables: among: wrong size: %d "
197 "against expected %d, rounded to %Zd\n", 191 "against expected %d, rounded to %Zd\n",
198 datalen, expected_length, 192 em->match_size, expected_length,
199 EBT_ALIGN(expected_length)); 193 EBT_ALIGN(expected_length));
200 return -EINVAL; 194 return false;
201 } 195 }
202 if (wh_dst && (err = ebt_mac_wormhash_check_integrity(wh_dst))) { 196 if (wh_dst && (err = ebt_mac_wormhash_check_integrity(wh_dst))) {
203 printk(KERN_WARNING 197 printk(KERN_WARNING
204 "ebtables: among: dst integrity fail: %x\n", -err); 198 "ebtables: among: dst integrity fail: %x\n", -err);
205 return -EINVAL; 199 return false;
206 } 200 }
207 if (wh_src && (err = ebt_mac_wormhash_check_integrity(wh_src))) { 201 if (wh_src && (err = ebt_mac_wormhash_check_integrity(wh_src))) {
208 printk(KERN_WARNING 202 printk(KERN_WARNING
209 "ebtables: among: src integrity fail: %x\n", -err); 203 "ebtables: among: src integrity fail: %x\n", -err);
210 return -EINVAL; 204 return false;
211 } 205 }
212 return 0; 206 return true;
213} 207}
214 208
215static struct ebt_match filter_among __read_mostly = { 209static struct xt_match ebt_among_mt_reg __read_mostly = {
216 .name = EBT_AMONG_MATCH, 210 .name = "among",
217 .match = ebt_filter_among, 211 .revision = 0,
218 .check = ebt_among_check, 212 .family = NFPROTO_BRIDGE,
213 .match = ebt_among_mt,
214 .checkentry = ebt_among_mt_check,
215 .matchsize = -1, /* special case */
219 .me = THIS_MODULE, 216 .me = THIS_MODULE,
220}; 217};
221 218
222static int __init ebt_among_init(void) 219static int __init ebt_among_init(void)
223{ 220{
224 return ebt_register_match(&filter_among); 221 return xt_register_match(&ebt_among_mt_reg);
225} 222}
226 223
227static void __exit ebt_among_fini(void) 224static void __exit ebt_among_fini(void)
228{ 225{
229 ebt_unregister_match(&filter_among); 226 xt_unregister_match(&ebt_among_mt_reg);
230} 227}
231 228
232module_init(ebt_among_init); 229module_init(ebt_among_init);
diff --git a/net/bridge/netfilter/ebt_arp.c b/net/bridge/netfilter/ebt_arp.c
index 7c535be75665..b7ad60419f9a 100644
--- a/net/bridge/netfilter/ebt_arp.c
+++ b/net/bridge/netfilter/ebt_arp.c
@@ -8,58 +8,58 @@
8 * April, 2002 8 * April, 2002
9 * 9 *
10 */ 10 */
11
12#include <linux/netfilter_bridge/ebtables.h>
13#include <linux/netfilter_bridge/ebt_arp.h>
14#include <linux/if_arp.h> 11#include <linux/if_arp.h>
15#include <linux/if_ether.h> 12#include <linux/if_ether.h>
16#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/netfilter/x_tables.h>
15#include <linux/netfilter_bridge/ebtables.h>
16#include <linux/netfilter_bridge/ebt_arp.h>
17 17
18static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in, 18static bool
19 const struct net_device *out, const void *data, unsigned int datalen) 19ebt_arp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
20{ 20{
21 const struct ebt_arp_info *info = data; 21 const struct ebt_arp_info *info = par->matchinfo;
22 const struct arphdr *ah; 22 const struct arphdr *ah;
23 struct arphdr _arph; 23 struct arphdr _arph;
24 24
25 ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph); 25 ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph);
26 if (ah == NULL) 26 if (ah == NULL)
27 return EBT_NOMATCH; 27 return false;
28 if (info->bitmask & EBT_ARP_OPCODE && FWINV(info->opcode != 28 if (info->bitmask & EBT_ARP_OPCODE && FWINV(info->opcode !=
29 ah->ar_op, EBT_ARP_OPCODE)) 29 ah->ar_op, EBT_ARP_OPCODE))
30 return EBT_NOMATCH; 30 return false;
31 if (info->bitmask & EBT_ARP_HTYPE && FWINV(info->htype != 31 if (info->bitmask & EBT_ARP_HTYPE && FWINV(info->htype !=
32 ah->ar_hrd, EBT_ARP_HTYPE)) 32 ah->ar_hrd, EBT_ARP_HTYPE))
33 return EBT_NOMATCH; 33 return false;
34 if (info->bitmask & EBT_ARP_PTYPE && FWINV(info->ptype != 34 if (info->bitmask & EBT_ARP_PTYPE && FWINV(info->ptype !=
35 ah->ar_pro, EBT_ARP_PTYPE)) 35 ah->ar_pro, EBT_ARP_PTYPE))
36 return EBT_NOMATCH; 36 return false;
37 37
38 if (info->bitmask & (EBT_ARP_SRC_IP | EBT_ARP_DST_IP | EBT_ARP_GRAT)) { 38 if (info->bitmask & (EBT_ARP_SRC_IP | EBT_ARP_DST_IP | EBT_ARP_GRAT)) {
39 const __be32 *sap, *dap; 39 const __be32 *sap, *dap;
40 __be32 saddr, daddr; 40 __be32 saddr, daddr;
41 41
42 if (ah->ar_pln != sizeof(__be32) || ah->ar_pro != htons(ETH_P_IP)) 42 if (ah->ar_pln != sizeof(__be32) || ah->ar_pro != htons(ETH_P_IP))
43 return EBT_NOMATCH; 43 return false;
44 sap = skb_header_pointer(skb, sizeof(struct arphdr) + 44 sap = skb_header_pointer(skb, sizeof(struct arphdr) +
45 ah->ar_hln, sizeof(saddr), 45 ah->ar_hln, sizeof(saddr),
46 &saddr); 46 &saddr);
47 if (sap == NULL) 47 if (sap == NULL)
48 return EBT_NOMATCH; 48 return false;
49 dap = skb_header_pointer(skb, sizeof(struct arphdr) + 49 dap = skb_header_pointer(skb, sizeof(struct arphdr) +
50 2*ah->ar_hln+sizeof(saddr), 50 2*ah->ar_hln+sizeof(saddr),
51 sizeof(daddr), &daddr); 51 sizeof(daddr), &daddr);
52 if (dap == NULL) 52 if (dap == NULL)
53 return EBT_NOMATCH; 53 return false;
54 if (info->bitmask & EBT_ARP_SRC_IP && 54 if (info->bitmask & EBT_ARP_SRC_IP &&
55 FWINV(info->saddr != (*sap & info->smsk), EBT_ARP_SRC_IP)) 55 FWINV(info->saddr != (*sap & info->smsk), EBT_ARP_SRC_IP))
56 return EBT_NOMATCH; 56 return false;
57 if (info->bitmask & EBT_ARP_DST_IP && 57 if (info->bitmask & EBT_ARP_DST_IP &&
58 FWINV(info->daddr != (*dap & info->dmsk), EBT_ARP_DST_IP)) 58 FWINV(info->daddr != (*dap & info->dmsk), EBT_ARP_DST_IP))
59 return EBT_NOMATCH; 59 return false;
60 if (info->bitmask & EBT_ARP_GRAT && 60 if (info->bitmask & EBT_ARP_GRAT &&
61 FWINV(*dap != *sap, EBT_ARP_GRAT)) 61 FWINV(*dap != *sap, EBT_ARP_GRAT))
62 return EBT_NOMATCH; 62 return false;
63 } 63 }
64 64
65 if (info->bitmask & (EBT_ARP_SRC_MAC | EBT_ARP_DST_MAC)) { 65 if (info->bitmask & (EBT_ARP_SRC_MAC | EBT_ARP_DST_MAC)) {
@@ -68,18 +68,18 @@ static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in
68 uint8_t verdict, i; 68 uint8_t verdict, i;
69 69
70 if (ah->ar_hln != ETH_ALEN || ah->ar_hrd != htons(ARPHRD_ETHER)) 70 if (ah->ar_hln != ETH_ALEN || ah->ar_hrd != htons(ARPHRD_ETHER))
71 return EBT_NOMATCH; 71 return false;
72 if (info->bitmask & EBT_ARP_SRC_MAC) { 72 if (info->bitmask & EBT_ARP_SRC_MAC) {
73 mp = skb_header_pointer(skb, sizeof(struct arphdr), 73 mp = skb_header_pointer(skb, sizeof(struct arphdr),
74 sizeof(_mac), &_mac); 74 sizeof(_mac), &_mac);
75 if (mp == NULL) 75 if (mp == NULL)
76 return EBT_NOMATCH; 76 return false;
77 verdict = 0; 77 verdict = 0;
78 for (i = 0; i < 6; i++) 78 for (i = 0; i < 6; i++)
79 verdict |= (mp[i] ^ info->smaddr[i]) & 79 verdict |= (mp[i] ^ info->smaddr[i]) &
80 info->smmsk[i]; 80 info->smmsk[i];
81 if (FWINV(verdict != 0, EBT_ARP_SRC_MAC)) 81 if (FWINV(verdict != 0, EBT_ARP_SRC_MAC))
82 return EBT_NOMATCH; 82 return false;
83 } 83 }
84 84
85 if (info->bitmask & EBT_ARP_DST_MAC) { 85 if (info->bitmask & EBT_ARP_DST_MAC) {
@@ -87,50 +87,51 @@ static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in
87 ah->ar_hln + ah->ar_pln, 87 ah->ar_hln + ah->ar_pln,
88 sizeof(_mac), &_mac); 88 sizeof(_mac), &_mac);
89 if (mp == NULL) 89 if (mp == NULL)
90 return EBT_NOMATCH; 90 return false;
91 verdict = 0; 91 verdict = 0;
92 for (i = 0; i < 6; i++) 92 for (i = 0; i < 6; i++)
93 verdict |= (mp[i] ^ info->dmaddr[i]) & 93 verdict |= (mp[i] ^ info->dmaddr[i]) &
94 info->dmmsk[i]; 94 info->dmmsk[i];
95 if (FWINV(verdict != 0, EBT_ARP_DST_MAC)) 95 if (FWINV(verdict != 0, EBT_ARP_DST_MAC))
96 return EBT_NOMATCH; 96 return false;
97 } 97 }
98 } 98 }
99 99
100 return EBT_MATCH; 100 return true;
101} 101}
102 102
103static int ebt_arp_check(const char *tablename, unsigned int hookmask, 103static bool ebt_arp_mt_check(const struct xt_mtchk_param *par)
104 const struct ebt_entry *e, void *data, unsigned int datalen)
105{ 104{
106 const struct ebt_arp_info *info = data; 105 const struct ebt_arp_info *info = par->matchinfo;
106 const struct ebt_entry *e = par->entryinfo;
107 107
108 if (datalen != EBT_ALIGN(sizeof(struct ebt_arp_info)))
109 return -EINVAL;
110 if ((e->ethproto != htons(ETH_P_ARP) && 108 if ((e->ethproto != htons(ETH_P_ARP) &&
111 e->ethproto != htons(ETH_P_RARP)) || 109 e->ethproto != htons(ETH_P_RARP)) ||
112 e->invflags & EBT_IPROTO) 110 e->invflags & EBT_IPROTO)
113 return -EINVAL; 111 return false;
114 if (info->bitmask & ~EBT_ARP_MASK || info->invflags & ~EBT_ARP_MASK) 112 if (info->bitmask & ~EBT_ARP_MASK || info->invflags & ~EBT_ARP_MASK)
115 return -EINVAL; 113 return false;
116 return 0; 114 return true;
117} 115}
118 116
119static struct ebt_match filter_arp __read_mostly = { 117static struct xt_match ebt_arp_mt_reg __read_mostly = {
120 .name = EBT_ARP_MATCH, 118 .name = "arp",
121 .match = ebt_filter_arp, 119 .revision = 0,
122 .check = ebt_arp_check, 120 .family = NFPROTO_BRIDGE,
121 .match = ebt_arp_mt,
122 .checkentry = ebt_arp_mt_check,
123 .matchsize = XT_ALIGN(sizeof(struct ebt_arp_info)),
123 .me = THIS_MODULE, 124 .me = THIS_MODULE,
124}; 125};
125 126
126static int __init ebt_arp_init(void) 127static int __init ebt_arp_init(void)
127{ 128{
128 return ebt_register_match(&filter_arp); 129 return xt_register_match(&ebt_arp_mt_reg);
129} 130}
130 131
131static void __exit ebt_arp_fini(void) 132static void __exit ebt_arp_fini(void)
132{ 133{
133 ebt_unregister_match(&filter_arp); 134 xt_unregister_match(&ebt_arp_mt_reg);
134} 135}
135 136
136module_init(ebt_arp_init); 137module_init(ebt_arp_init);
diff --git a/net/bridge/netfilter/ebt_arpreply.c b/net/bridge/netfilter/ebt_arpreply.c
index 0c4279590fc7..76584cd72e57 100644
--- a/net/bridge/netfilter/ebt_arpreply.c
+++ b/net/bridge/netfilter/ebt_arpreply.c
@@ -8,18 +8,17 @@
8 * August, 2003 8 * August, 2003
9 * 9 *
10 */ 10 */
11
12#include <linux/netfilter_bridge/ebtables.h>
13#include <linux/netfilter_bridge/ebt_arpreply.h>
14#include <linux/if_arp.h> 11#include <linux/if_arp.h>
15#include <net/arp.h> 12#include <net/arp.h>
16#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/netfilter/x_tables.h>
15#include <linux/netfilter_bridge/ebtables.h>
16#include <linux/netfilter_bridge/ebt_arpreply.h>
17 17
18static int ebt_target_reply(struct sk_buff *skb, unsigned int hooknr, 18static unsigned int
19 const struct net_device *in, const struct net_device *out, 19ebt_arpreply_tg(struct sk_buff *skb, const struct xt_target_param *par)
20 const void *data, unsigned int datalen)
21{ 20{
22 struct ebt_arpreply_info *info = (void *)data; 21 const struct ebt_arpreply_info *info = par->targinfo;
23 const __be32 *siptr, *diptr; 22 const __be32 *siptr, *diptr;
24 __be32 _sip, _dip; 23 __be32 _sip, _dip;
25 const struct arphdr *ap; 24 const struct arphdr *ap;
@@ -52,45 +51,45 @@ static int ebt_target_reply(struct sk_buff *skb, unsigned int hooknr,
52 if (diptr == NULL) 51 if (diptr == NULL)
53 return EBT_DROP; 52 return EBT_DROP;
54 53
55 arp_send(ARPOP_REPLY, ETH_P_ARP, *siptr, (struct net_device *)in, 54 arp_send(ARPOP_REPLY, ETH_P_ARP, *siptr, (struct net_device *)par->in,
56 *diptr, shp, info->mac, shp); 55 *diptr, shp, info->mac, shp);
57 56
58 return info->target; 57 return info->target;
59} 58}
60 59
61static int ebt_target_reply_check(const char *tablename, unsigned int hookmask, 60static bool ebt_arpreply_tg_check(const struct xt_tgchk_param *par)
62 const struct ebt_entry *e, void *data, unsigned int datalen)
63{ 61{
64 const struct ebt_arpreply_info *info = data; 62 const struct ebt_arpreply_info *info = par->targinfo;
63 const struct ebt_entry *e = par->entryinfo;
65 64
66 if (datalen != EBT_ALIGN(sizeof(struct ebt_arpreply_info)))
67 return -EINVAL;
68 if (BASE_CHAIN && info->target == EBT_RETURN) 65 if (BASE_CHAIN && info->target == EBT_RETURN)
69 return -EINVAL; 66 return false;
70 if (e->ethproto != htons(ETH_P_ARP) || 67 if (e->ethproto != htons(ETH_P_ARP) ||
71 e->invflags & EBT_IPROTO) 68 e->invflags & EBT_IPROTO)
72 return -EINVAL; 69 return false;
73 CLEAR_BASE_CHAIN_BIT; 70 return true;
74 if (strcmp(tablename, "nat") || hookmask & ~(1 << NF_BR_PRE_ROUTING))
75 return -EINVAL;
76 return 0;
77} 71}
78 72
79static struct ebt_target reply_target __read_mostly = { 73static struct xt_target ebt_arpreply_tg_reg __read_mostly = {
80 .name = EBT_ARPREPLY_TARGET, 74 .name = "arpreply",
81 .target = ebt_target_reply, 75 .revision = 0,
82 .check = ebt_target_reply_check, 76 .family = NFPROTO_BRIDGE,
77 .table = "nat",
78 .hooks = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_PRE_ROUTING),
79 .target = ebt_arpreply_tg,
80 .checkentry = ebt_arpreply_tg_check,
81 .targetsize = XT_ALIGN(sizeof(struct ebt_arpreply_info)),
83 .me = THIS_MODULE, 82 .me = THIS_MODULE,
84}; 83};
85 84
86static int __init ebt_arpreply_init(void) 85static int __init ebt_arpreply_init(void)
87{ 86{
88 return ebt_register_target(&reply_target); 87 return xt_register_target(&ebt_arpreply_tg_reg);
89} 88}
90 89
91static void __exit ebt_arpreply_fini(void) 90static void __exit ebt_arpreply_fini(void)
92{ 91{
93 ebt_unregister_target(&reply_target); 92 xt_unregister_target(&ebt_arpreply_tg_reg);
94} 93}
95 94
96module_init(ebt_arpreply_init); 95module_init(ebt_arpreply_init);
diff --git a/net/bridge/netfilter/ebt_dnat.c b/net/bridge/netfilter/ebt_dnat.c
index ca64c1cc1b47..6b49ea9e31fb 100644
--- a/net/bridge/netfilter/ebt_dnat.c
+++ b/net/bridge/netfilter/ebt_dnat.c
@@ -7,18 +7,17 @@
7 * June, 2002 7 * June, 2002
8 * 8 *
9 */ 9 */
10 10#include <linux/module.h>
11#include <net/sock.h>
11#include <linux/netfilter.h> 12#include <linux/netfilter.h>
13#include <linux/netfilter/x_tables.h>
12#include <linux/netfilter_bridge/ebtables.h> 14#include <linux/netfilter_bridge/ebtables.h>
13#include <linux/netfilter_bridge/ebt_nat.h> 15#include <linux/netfilter_bridge/ebt_nat.h>
14#include <linux/module.h>
15#include <net/sock.h>
16 16
17static int ebt_target_dnat(struct sk_buff *skb, unsigned int hooknr, 17static unsigned int
18 const struct net_device *in, const struct net_device *out, 18ebt_dnat_tg(struct sk_buff *skb, const struct xt_target_param *par)
19 const void *data, unsigned int datalen)
20{ 19{
21 const struct ebt_nat_info *info = data; 20 const struct ebt_nat_info *info = par->targinfo;
22 21
23 if (!skb_make_writable(skb, 0)) 22 if (!skb_make_writable(skb, 0))
24 return EBT_DROP; 23 return EBT_DROP;
@@ -27,40 +26,46 @@ static int ebt_target_dnat(struct sk_buff *skb, unsigned int hooknr,
27 return info->target; 26 return info->target;
28} 27}
29 28
30static int ebt_target_dnat_check(const char *tablename, unsigned int hookmask, 29static bool ebt_dnat_tg_check(const struct xt_tgchk_param *par)
31 const struct ebt_entry *e, void *data, unsigned int datalen)
32{ 30{
33 const struct ebt_nat_info *info = data; 31 const struct ebt_nat_info *info = par->targinfo;
32 unsigned int hook_mask;
34 33
35 if (BASE_CHAIN && info->target == EBT_RETURN) 34 if (BASE_CHAIN && info->target == EBT_RETURN)
36 return -EINVAL; 35 return false;
37 CLEAR_BASE_CHAIN_BIT; 36
38 if ( (strcmp(tablename, "nat") || 37 hook_mask = par->hook_mask & ~(1 << NF_BR_NUMHOOKS);
39 (hookmask & ~((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT)))) && 38 if ((strcmp(par->table, "nat") != 0 ||
40 (strcmp(tablename, "broute") || hookmask & ~(1 << NF_BR_BROUTING)) ) 39 (hook_mask & ~((1 << NF_BR_PRE_ROUTING) |
41 return -EINVAL; 40 (1 << NF_BR_LOCAL_OUT)))) &&
42 if (datalen != EBT_ALIGN(sizeof(struct ebt_nat_info))) 41 (strcmp(par->table, "broute") != 0 ||
43 return -EINVAL; 42 hook_mask & ~(1 << NF_BR_BROUTING)))
43 return false;
44 if (INVALID_TARGET) 44 if (INVALID_TARGET)
45 return -EINVAL; 45 return false;
46 return 0; 46 return true;
47} 47}
48 48
49static struct ebt_target dnat __read_mostly = { 49static struct xt_target ebt_dnat_tg_reg __read_mostly = {
50 .name = EBT_DNAT_TARGET, 50 .name = "dnat",
51 .target = ebt_target_dnat, 51 .revision = 0,
52 .check = ebt_target_dnat_check, 52 .family = NFPROTO_BRIDGE,
53 .hooks = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_PRE_ROUTING) |
54 (1 << NF_BR_LOCAL_OUT) | (1 << NF_BR_BROUTING),
55 .target = ebt_dnat_tg,
56 .checkentry = ebt_dnat_tg_check,
57 .targetsize = XT_ALIGN(sizeof(struct ebt_nat_info)),
53 .me = THIS_MODULE, 58 .me = THIS_MODULE,
54}; 59};
55 60
56static int __init ebt_dnat_init(void) 61static int __init ebt_dnat_init(void)
57{ 62{
58 return ebt_register_target(&dnat); 63 return xt_register_target(&ebt_dnat_tg_reg);
59} 64}
60 65
61static void __exit ebt_dnat_fini(void) 66static void __exit ebt_dnat_fini(void)
62{ 67{
63 ebt_unregister_target(&dnat); 68 xt_unregister_target(&ebt_dnat_tg_reg);
64} 69}
65 70
66module_init(ebt_dnat_init); 71module_init(ebt_dnat_init);
diff --git a/net/bridge/netfilter/ebt_ip.c b/net/bridge/netfilter/ebt_ip.c
index 65caa00dcf2a..d771bbfbcbe6 100644
--- a/net/bridge/netfilter/ebt_ip.c
+++ b/net/bridge/netfilter/ebt_ip.c
@@ -11,24 +11,23 @@
11 * Innominate Security Technologies AG <mhopf@innominate.com> 11 * Innominate Security Technologies AG <mhopf@innominate.com>
12 * September, 2002 12 * September, 2002
13 */ 13 */
14
15#include <linux/netfilter_bridge/ebtables.h>
16#include <linux/netfilter_bridge/ebt_ip.h>
17#include <linux/ip.h> 14#include <linux/ip.h>
18#include <net/ip.h> 15#include <net/ip.h>
19#include <linux/in.h> 16#include <linux/in.h>
20#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/netfilter/x_tables.h>
19#include <linux/netfilter_bridge/ebtables.h>
20#include <linux/netfilter_bridge/ebt_ip.h>
21 21
22struct tcpudphdr { 22struct tcpudphdr {
23 __be16 src; 23 __be16 src;
24 __be16 dst; 24 __be16 dst;
25}; 25};
26 26
27static int ebt_filter_ip(const struct sk_buff *skb, const struct net_device *in, 27static bool
28 const struct net_device *out, const void *data, 28ebt_ip_mt(const struct sk_buff *skb, const struct xt_match_param *par)
29 unsigned int datalen)
30{ 29{
31 const struct ebt_ip_info *info = data; 30 const struct ebt_ip_info *info = par->matchinfo;
32 const struct iphdr *ih; 31 const struct iphdr *ih;
33 struct iphdr _iph; 32 struct iphdr _iph;
34 const struct tcpudphdr *pptr; 33 const struct tcpudphdr *pptr;
@@ -36,92 +35,93 @@ static int ebt_filter_ip(const struct sk_buff *skb, const struct net_device *in,
36 35
37 ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph); 36 ih = skb_header_pointer(skb, 0, sizeof(_iph), &_iph);
38 if (ih == NULL) 37 if (ih == NULL)
39 return EBT_NOMATCH; 38 return false;
40 if (info->bitmask & EBT_IP_TOS && 39 if (info->bitmask & EBT_IP_TOS &&
41 FWINV(info->tos != ih->tos, EBT_IP_TOS)) 40 FWINV(info->tos != ih->tos, EBT_IP_TOS))
42 return EBT_NOMATCH; 41 return false;
43 if (info->bitmask & EBT_IP_SOURCE && 42 if (info->bitmask & EBT_IP_SOURCE &&
44 FWINV((ih->saddr & info->smsk) != 43 FWINV((ih->saddr & info->smsk) !=
45 info->saddr, EBT_IP_SOURCE)) 44 info->saddr, EBT_IP_SOURCE))
46 return EBT_NOMATCH; 45 return false;
47 if ((info->bitmask & EBT_IP_DEST) && 46 if ((info->bitmask & EBT_IP_DEST) &&
48 FWINV((ih->daddr & info->dmsk) != 47 FWINV((ih->daddr & info->dmsk) !=
49 info->daddr, EBT_IP_DEST)) 48 info->daddr, EBT_IP_DEST))
50 return EBT_NOMATCH; 49 return false;
51 if (info->bitmask & EBT_IP_PROTO) { 50 if (info->bitmask & EBT_IP_PROTO) {
52 if (FWINV(info->protocol != ih->protocol, EBT_IP_PROTO)) 51 if (FWINV(info->protocol != ih->protocol, EBT_IP_PROTO))
53 return EBT_NOMATCH; 52 return false;
54 if (!(info->bitmask & EBT_IP_DPORT) && 53 if (!(info->bitmask & EBT_IP_DPORT) &&
55 !(info->bitmask & EBT_IP_SPORT)) 54 !(info->bitmask & EBT_IP_SPORT))
56 return EBT_MATCH; 55 return true;
57 if (ntohs(ih->frag_off) & IP_OFFSET) 56 if (ntohs(ih->frag_off) & IP_OFFSET)
58 return EBT_NOMATCH; 57 return false;
59 pptr = skb_header_pointer(skb, ih->ihl*4, 58 pptr = skb_header_pointer(skb, ih->ihl*4,
60 sizeof(_ports), &_ports); 59 sizeof(_ports), &_ports);
61 if (pptr == NULL) 60 if (pptr == NULL)
62 return EBT_NOMATCH; 61 return false;
63 if (info->bitmask & EBT_IP_DPORT) { 62 if (info->bitmask & EBT_IP_DPORT) {
64 u32 dst = ntohs(pptr->dst); 63 u32 dst = ntohs(pptr->dst);
65 if (FWINV(dst < info->dport[0] || 64 if (FWINV(dst < info->dport[0] ||
66 dst > info->dport[1], 65 dst > info->dport[1],
67 EBT_IP_DPORT)) 66 EBT_IP_DPORT))
68 return EBT_NOMATCH; 67 return false;
69 } 68 }
70 if (info->bitmask & EBT_IP_SPORT) { 69 if (info->bitmask & EBT_IP_SPORT) {
71 u32 src = ntohs(pptr->src); 70 u32 src = ntohs(pptr->src);
72 if (FWINV(src < info->sport[0] || 71 if (FWINV(src < info->sport[0] ||
73 src > info->sport[1], 72 src > info->sport[1],
74 EBT_IP_SPORT)) 73 EBT_IP_SPORT))
75 return EBT_NOMATCH; 74 return false;
76 } 75 }
77 } 76 }
78 return EBT_MATCH; 77 return true;
79} 78}
80 79
81static int ebt_ip_check(const char *tablename, unsigned int hookmask, 80static bool ebt_ip_mt_check(const struct xt_mtchk_param *par)
82 const struct ebt_entry *e, void *data, unsigned int datalen)
83{ 81{
84 const struct ebt_ip_info *info = data; 82 const struct ebt_ip_info *info = par->matchinfo;
83 const struct ebt_entry *e = par->entryinfo;
85 84
86 if (datalen != EBT_ALIGN(sizeof(struct ebt_ip_info)))
87 return -EINVAL;
88 if (e->ethproto != htons(ETH_P_IP) || 85 if (e->ethproto != htons(ETH_P_IP) ||
89 e->invflags & EBT_IPROTO) 86 e->invflags & EBT_IPROTO)
90 return -EINVAL; 87 return false;
91 if (info->bitmask & ~EBT_IP_MASK || info->invflags & ~EBT_IP_MASK) 88 if (info->bitmask & ~EBT_IP_MASK || info->invflags & ~EBT_IP_MASK)
92 return -EINVAL; 89 return false;
93 if (info->bitmask & (EBT_IP_DPORT | EBT_IP_SPORT)) { 90 if (info->bitmask & (EBT_IP_DPORT | EBT_IP_SPORT)) {
94 if (info->invflags & EBT_IP_PROTO) 91 if (info->invflags & EBT_IP_PROTO)
95 return -EINVAL; 92 return false;
96 if (info->protocol != IPPROTO_TCP && 93 if (info->protocol != IPPROTO_TCP &&
97 info->protocol != IPPROTO_UDP && 94 info->protocol != IPPROTO_UDP &&
98 info->protocol != IPPROTO_UDPLITE && 95 info->protocol != IPPROTO_UDPLITE &&
99 info->protocol != IPPROTO_SCTP && 96 info->protocol != IPPROTO_SCTP &&
100 info->protocol != IPPROTO_DCCP) 97 info->protocol != IPPROTO_DCCP)
101 return -EINVAL; 98 return false;
102 } 99 }
103 if (info->bitmask & EBT_IP_DPORT && info->dport[0] > info->dport[1]) 100 if (info->bitmask & EBT_IP_DPORT && info->dport[0] > info->dport[1])
104 return -EINVAL; 101 return false;
105 if (info->bitmask & EBT_IP_SPORT && info->sport[0] > info->sport[1]) 102 if (info->bitmask & EBT_IP_SPORT && info->sport[0] > info->sport[1])
106 return -EINVAL; 103 return false;
107 return 0; 104 return true;
108} 105}
109 106
110static struct ebt_match filter_ip __read_mostly = { 107static struct xt_match ebt_ip_mt_reg __read_mostly = {
111 .name = EBT_IP_MATCH, 108 .name = "ip",
112 .match = ebt_filter_ip, 109 .revision = 0,
113 .check = ebt_ip_check, 110 .family = NFPROTO_BRIDGE,
111 .match = ebt_ip_mt,
112 .checkentry = ebt_ip_mt_check,
113 .matchsize = XT_ALIGN(sizeof(struct ebt_ip_info)),
114 .me = THIS_MODULE, 114 .me = THIS_MODULE,
115}; 115};
116 116
117static int __init ebt_ip_init(void) 117static int __init ebt_ip_init(void)
118{ 118{
119 return ebt_register_match(&filter_ip); 119 return xt_register_match(&ebt_ip_mt_reg);
120} 120}
121 121
122static void __exit ebt_ip_fini(void) 122static void __exit ebt_ip_fini(void)
123{ 123{
124 ebt_unregister_match(&filter_ip); 124 xt_unregister_match(&ebt_ip_mt_reg);
125} 125}
126 126
127module_init(ebt_ip_init); 127module_init(ebt_ip_init);
diff --git a/net/bridge/netfilter/ebt_ip6.c b/net/bridge/netfilter/ebt_ip6.c
index 36efb3a75249..784a6573876c 100644
--- a/net/bridge/netfilter/ebt_ip6.c
+++ b/net/bridge/netfilter/ebt_ip6.c
@@ -13,26 +13,24 @@
13 * 13 *
14 * Jan, 2008 14 * Jan, 2008
15 */ 15 */
16
17#include <linux/netfilter_bridge/ebtables.h>
18#include <linux/netfilter_bridge/ebt_ip6.h>
19#include <linux/ipv6.h> 16#include <linux/ipv6.h>
20#include <net/ipv6.h> 17#include <net/ipv6.h>
21#include <linux/in.h> 18#include <linux/in.h>
22#include <linux/module.h> 19#include <linux/module.h>
23#include <net/dsfield.h> 20#include <net/dsfield.h>
21#include <linux/netfilter/x_tables.h>
22#include <linux/netfilter_bridge/ebtables.h>
23#include <linux/netfilter_bridge/ebt_ip6.h>
24 24
25struct tcpudphdr { 25struct tcpudphdr {
26 __be16 src; 26 __be16 src;
27 __be16 dst; 27 __be16 dst;
28}; 28};
29 29
30static int ebt_filter_ip6(const struct sk_buff *skb, 30static bool
31 const struct net_device *in, 31ebt_ip6_mt(const struct sk_buff *skb, const struct xt_match_param *par)
32 const struct net_device *out, const void *data,
33 unsigned int datalen)
34{ 32{
35 const struct ebt_ip6_info *info = (struct ebt_ip6_info *)data; 33 const struct ebt_ip6_info *info = par->matchinfo;
36 const struct ipv6hdr *ih6; 34 const struct ipv6hdr *ih6;
37 struct ipv6hdr _ip6h; 35 struct ipv6hdr _ip6h;
38 const struct tcpudphdr *pptr; 36 const struct tcpudphdr *pptr;
@@ -42,100 +40,100 @@ static int ebt_filter_ip6(const struct sk_buff *skb,
42 40
43 ih6 = skb_header_pointer(skb, 0, sizeof(_ip6h), &_ip6h); 41 ih6 = skb_header_pointer(skb, 0, sizeof(_ip6h), &_ip6h);
44 if (ih6 == NULL) 42 if (ih6 == NULL)
45 return EBT_NOMATCH; 43 return false;
46 if (info->bitmask & EBT_IP6_TCLASS && 44 if (info->bitmask & EBT_IP6_TCLASS &&
47 FWINV(info->tclass != ipv6_get_dsfield(ih6), EBT_IP6_TCLASS)) 45 FWINV(info->tclass != ipv6_get_dsfield(ih6), EBT_IP6_TCLASS))
48 return EBT_NOMATCH; 46 return false;
49 for (i = 0; i < 4; i++) 47 for (i = 0; i < 4; i++)
50 tmp_addr.in6_u.u6_addr32[i] = ih6->saddr.in6_u.u6_addr32[i] & 48 tmp_addr.in6_u.u6_addr32[i] = ih6->saddr.in6_u.u6_addr32[i] &
51 info->smsk.in6_u.u6_addr32[i]; 49 info->smsk.in6_u.u6_addr32[i];
52 if (info->bitmask & EBT_IP6_SOURCE && 50 if (info->bitmask & EBT_IP6_SOURCE &&
53 FWINV((ipv6_addr_cmp(&tmp_addr, &info->saddr) != 0), 51 FWINV((ipv6_addr_cmp(&tmp_addr, &info->saddr) != 0),
54 EBT_IP6_SOURCE)) 52 EBT_IP6_SOURCE))
55 return EBT_NOMATCH; 53 return false;
56 for (i = 0; i < 4; i++) 54 for (i = 0; i < 4; i++)
57 tmp_addr.in6_u.u6_addr32[i] = ih6->daddr.in6_u.u6_addr32[i] & 55 tmp_addr.in6_u.u6_addr32[i] = ih6->daddr.in6_u.u6_addr32[i] &
58 info->dmsk.in6_u.u6_addr32[i]; 56 info->dmsk.in6_u.u6_addr32[i];
59 if (info->bitmask & EBT_IP6_DEST && 57 if (info->bitmask & EBT_IP6_DEST &&
60 FWINV((ipv6_addr_cmp(&tmp_addr, &info->daddr) != 0), EBT_IP6_DEST)) 58 FWINV((ipv6_addr_cmp(&tmp_addr, &info->daddr) != 0), EBT_IP6_DEST))
61 return EBT_NOMATCH; 59 return false;
62 if (info->bitmask & EBT_IP6_PROTO) { 60 if (info->bitmask & EBT_IP6_PROTO) {
63 uint8_t nexthdr = ih6->nexthdr; 61 uint8_t nexthdr = ih6->nexthdr;
64 int offset_ph; 62 int offset_ph;
65 63
66 offset_ph = ipv6_skip_exthdr(skb, sizeof(_ip6h), &nexthdr); 64 offset_ph = ipv6_skip_exthdr(skb, sizeof(_ip6h), &nexthdr);
67 if (offset_ph == -1) 65 if (offset_ph == -1)
68 return EBT_NOMATCH; 66 return false;
69 if (FWINV(info->protocol != nexthdr, EBT_IP6_PROTO)) 67 if (FWINV(info->protocol != nexthdr, EBT_IP6_PROTO))
70 return EBT_NOMATCH; 68 return false;
71 if (!(info->bitmask & EBT_IP6_DPORT) && 69 if (!(info->bitmask & EBT_IP6_DPORT) &&
72 !(info->bitmask & EBT_IP6_SPORT)) 70 !(info->bitmask & EBT_IP6_SPORT))
73 return EBT_MATCH; 71 return true;
74 pptr = skb_header_pointer(skb, offset_ph, sizeof(_ports), 72 pptr = skb_header_pointer(skb, offset_ph, sizeof(_ports),
75 &_ports); 73 &_ports);
76 if (pptr == NULL) 74 if (pptr == NULL)
77 return EBT_NOMATCH; 75 return false;
78 if (info->bitmask & EBT_IP6_DPORT) { 76 if (info->bitmask & EBT_IP6_DPORT) {
79 u32 dst = ntohs(pptr->dst); 77 u32 dst = ntohs(pptr->dst);
80 if (FWINV(dst < info->dport[0] || 78 if (FWINV(dst < info->dport[0] ||
81 dst > info->dport[1], EBT_IP6_DPORT)) 79 dst > info->dport[1], EBT_IP6_DPORT))
82 return EBT_NOMATCH; 80 return false;
83 } 81 }
84 if (info->bitmask & EBT_IP6_SPORT) { 82 if (info->bitmask & EBT_IP6_SPORT) {
85 u32 src = ntohs(pptr->src); 83 u32 src = ntohs(pptr->src);
86 if (FWINV(src < info->sport[0] || 84 if (FWINV(src < info->sport[0] ||
87 src > info->sport[1], EBT_IP6_SPORT)) 85 src > info->sport[1], EBT_IP6_SPORT))
88 return EBT_NOMATCH; 86 return false;
89 } 87 }
90 return EBT_MATCH; 88 return true;
91 } 89 }
92 return EBT_MATCH; 90 return true;
93} 91}
94 92
95static int ebt_ip6_check(const char *tablename, unsigned int hookmask, 93static bool ebt_ip6_mt_check(const struct xt_mtchk_param *par)
96 const struct ebt_entry *e, void *data, unsigned int datalen)
97{ 94{
98 struct ebt_ip6_info *info = (struct ebt_ip6_info *)data; 95 const struct ebt_entry *e = par->entryinfo;
96 struct ebt_ip6_info *info = par->matchinfo;
99 97
100 if (datalen != EBT_ALIGN(sizeof(struct ebt_ip6_info)))
101 return -EINVAL;
102 if (e->ethproto != htons(ETH_P_IPV6) || e->invflags & EBT_IPROTO) 98 if (e->ethproto != htons(ETH_P_IPV6) || e->invflags & EBT_IPROTO)
103 return -EINVAL; 99 return false;
104 if (info->bitmask & ~EBT_IP6_MASK || info->invflags & ~EBT_IP6_MASK) 100 if (info->bitmask & ~EBT_IP6_MASK || info->invflags & ~EBT_IP6_MASK)
105 return -EINVAL; 101 return false;
106 if (info->bitmask & (EBT_IP6_DPORT | EBT_IP6_SPORT)) { 102 if (info->bitmask & (EBT_IP6_DPORT | EBT_IP6_SPORT)) {
107 if (info->invflags & EBT_IP6_PROTO) 103 if (info->invflags & EBT_IP6_PROTO)
108 return -EINVAL; 104 return false;
109 if (info->protocol != IPPROTO_TCP && 105 if (info->protocol != IPPROTO_TCP &&
110 info->protocol != IPPROTO_UDP && 106 info->protocol != IPPROTO_UDP &&
111 info->protocol != IPPROTO_UDPLITE && 107 info->protocol != IPPROTO_UDPLITE &&
112 info->protocol != IPPROTO_SCTP && 108 info->protocol != IPPROTO_SCTP &&
113 info->protocol != IPPROTO_DCCP) 109 info->protocol != IPPROTO_DCCP)
114 return -EINVAL; 110 return false;
115 } 111 }
116 if (info->bitmask & EBT_IP6_DPORT && info->dport[0] > info->dport[1]) 112 if (info->bitmask & EBT_IP6_DPORT && info->dport[0] > info->dport[1])
117 return -EINVAL; 113 return false;
118 if (info->bitmask & EBT_IP6_SPORT && info->sport[0] > info->sport[1]) 114 if (info->bitmask & EBT_IP6_SPORT && info->sport[0] > info->sport[1])
119 return -EINVAL; 115 return false;
120 return 0; 116 return true;
121} 117}
122 118
123static struct ebt_match filter_ip6 = 119static struct xt_match ebt_ip6_mt_reg __read_mostly = {
124{ 120 .name = "ip6",
125 .name = EBT_IP6_MATCH, 121 .revision = 0,
126 .match = ebt_filter_ip6, 122 .family = NFPROTO_BRIDGE,
127 .check = ebt_ip6_check, 123 .match = ebt_ip6_mt,
124 .checkentry = ebt_ip6_mt_check,
125 .matchsize = XT_ALIGN(sizeof(struct ebt_ip6_info)),
128 .me = THIS_MODULE, 126 .me = THIS_MODULE,
129}; 127};
130 128
131static int __init ebt_ip6_init(void) 129static int __init ebt_ip6_init(void)
132{ 130{
133 return ebt_register_match(&filter_ip6); 131 return xt_register_match(&ebt_ip6_mt_reg);
134} 132}
135 133
136static void __exit ebt_ip6_fini(void) 134static void __exit ebt_ip6_fini(void)
137{ 135{
138 ebt_unregister_match(&filter_ip6); 136 xt_unregister_match(&ebt_ip6_mt_reg);
139} 137}
140 138
141module_init(ebt_ip6_init); 139module_init(ebt_ip6_init);
diff --git a/net/bridge/netfilter/ebt_limit.c b/net/bridge/netfilter/ebt_limit.c
index 8cbdc01c253e..f7bd9192ff0c 100644
--- a/net/bridge/netfilter/ebt_limit.c
+++ b/net/bridge/netfilter/ebt_limit.c
@@ -10,13 +10,12 @@
10 * September, 2003 10 * September, 2003
11 * 11 *
12 */ 12 */
13
14#include <linux/netfilter_bridge/ebtables.h>
15#include <linux/netfilter_bridge/ebt_limit.h>
16#include <linux/module.h> 13#include <linux/module.h>
17
18#include <linux/netdevice.h> 14#include <linux/netdevice.h>
19#include <linux/spinlock.h> 15#include <linux/spinlock.h>
16#include <linux/netfilter/x_tables.h>
17#include <linux/netfilter_bridge/ebtables.h>
18#include <linux/netfilter_bridge/ebt_limit.h>
20 19
21static DEFINE_SPINLOCK(limit_lock); 20static DEFINE_SPINLOCK(limit_lock);
22 21
@@ -31,11 +30,10 @@ static DEFINE_SPINLOCK(limit_lock);
31 30
32#define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ) 31#define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ)
33 32
34static int ebt_limit_match(const struct sk_buff *skb, 33static bool
35 const struct net_device *in, const struct net_device *out, 34ebt_limit_mt(const struct sk_buff *skb, const struct xt_match_param *par)
36 const void *data, unsigned int datalen)
37{ 35{
38 struct ebt_limit_info *info = (struct ebt_limit_info *)data; 36 struct ebt_limit_info *info = (void *)par->matchinfo;
39 unsigned long now = jiffies; 37 unsigned long now = jiffies;
40 38
41 spin_lock_bh(&limit_lock); 39 spin_lock_bh(&limit_lock);
@@ -47,11 +45,11 @@ static int ebt_limit_match(const struct sk_buff *skb,
47 /* We're not limited. */ 45 /* We're not limited. */
48 info->credit -= info->cost; 46 info->credit -= info->cost;
49 spin_unlock_bh(&limit_lock); 47 spin_unlock_bh(&limit_lock);
50 return EBT_MATCH; 48 return true;
51 } 49 }
52 50
53 spin_unlock_bh(&limit_lock); 51 spin_unlock_bh(&limit_lock);
54 return EBT_NOMATCH; 52 return false;
55} 53}
56 54
57/* Precision saver. */ 55/* Precision saver. */
@@ -66,20 +64,16 @@ user2credits(u_int32_t user)
66 return (user * HZ * CREDITS_PER_JIFFY) / EBT_LIMIT_SCALE; 64 return (user * HZ * CREDITS_PER_JIFFY) / EBT_LIMIT_SCALE;
67} 65}
68 66
69static int ebt_limit_check(const char *tablename, unsigned int hookmask, 67static bool ebt_limit_mt_check(const struct xt_mtchk_param *par)
70 const struct ebt_entry *e, void *data, unsigned int datalen)
71{ 68{
72 struct ebt_limit_info *info = data; 69 struct ebt_limit_info *info = par->matchinfo;
73
74 if (datalen != EBT_ALIGN(sizeof(struct ebt_limit_info)))
75 return -EINVAL;
76 70
77 /* Check for overflow. */ 71 /* Check for overflow. */
78 if (info->burst == 0 || 72 if (info->burst == 0 ||
79 user2credits(info->avg * info->burst) < user2credits(info->avg)) { 73 user2credits(info->avg * info->burst) < user2credits(info->avg)) {
80 printk("Overflow in ebt_limit, try lower: %u/%u\n", 74 printk("Overflow in ebt_limit, try lower: %u/%u\n",
81 info->avg, info->burst); 75 info->avg, info->burst);
82 return -EINVAL; 76 return false;
83 } 77 }
84 78
85 /* User avg in seconds * EBT_LIMIT_SCALE: convert to jiffies * 128. */ 79 /* User avg in seconds * EBT_LIMIT_SCALE: convert to jiffies * 128. */
@@ -87,24 +81,27 @@ static int ebt_limit_check(const char *tablename, unsigned int hookmask,
87 info->credit = user2credits(info->avg * info->burst); 81 info->credit = user2credits(info->avg * info->burst);
88 info->credit_cap = user2credits(info->avg * info->burst); 82 info->credit_cap = user2credits(info->avg * info->burst);
89 info->cost = user2credits(info->avg); 83 info->cost = user2credits(info->avg);
90 return 0; 84 return true;
91} 85}
92 86
93static struct ebt_match ebt_limit_reg __read_mostly = { 87static struct xt_match ebt_limit_mt_reg __read_mostly = {
94 .name = EBT_LIMIT_MATCH, 88 .name = "limit",
95 .match = ebt_limit_match, 89 .revision = 0,
96 .check = ebt_limit_check, 90 .family = NFPROTO_BRIDGE,
91 .match = ebt_limit_mt,
92 .checkentry = ebt_limit_mt_check,
93 .matchsize = XT_ALIGN(sizeof(struct ebt_limit_info)),
97 .me = THIS_MODULE, 94 .me = THIS_MODULE,
98}; 95};
99 96
100static int __init ebt_limit_init(void) 97static int __init ebt_limit_init(void)
101{ 98{
102 return ebt_register_match(&ebt_limit_reg); 99 return xt_register_match(&ebt_limit_mt_reg);
103} 100}
104 101
105static void __exit ebt_limit_fini(void) 102static void __exit ebt_limit_fini(void)
106{ 103{
107 ebt_unregister_match(&ebt_limit_reg); 104 xt_unregister_match(&ebt_limit_mt_reg);
108} 105}
109 106
110module_init(ebt_limit_init); 107module_init(ebt_limit_init);
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c
index 2f430d4ae911..3d33c608906a 100644
--- a/net/bridge/netfilter/ebt_log.c
+++ b/net/bridge/netfilter/ebt_log.c
@@ -8,10 +8,6 @@
8 * April, 2002 8 * April, 2002
9 * 9 *
10 */ 10 */
11
12#include <linux/netfilter_bridge/ebtables.h>
13#include <linux/netfilter_bridge/ebt_log.h>
14#include <linux/netfilter.h>
15#include <linux/module.h> 11#include <linux/module.h>
16#include <linux/ip.h> 12#include <linux/ip.h>
17#include <linux/in.h> 13#include <linux/in.h>
@@ -21,22 +17,23 @@
21#include <linux/ipv6.h> 17#include <linux/ipv6.h>
22#include <net/ipv6.h> 18#include <net/ipv6.h>
23#include <linux/in6.h> 19#include <linux/in6.h>
20#include <linux/netfilter/x_tables.h>
21#include <linux/netfilter_bridge/ebtables.h>
22#include <linux/netfilter_bridge/ebt_log.h>
23#include <linux/netfilter.h>
24 24
25static DEFINE_SPINLOCK(ebt_log_lock); 25static DEFINE_SPINLOCK(ebt_log_lock);
26 26
27static int ebt_log_check(const char *tablename, unsigned int hookmask, 27static bool ebt_log_tg_check(const struct xt_tgchk_param *par)
28 const struct ebt_entry *e, void *data, unsigned int datalen)
29{ 28{
30 struct ebt_log_info *info = data; 29 struct ebt_log_info *info = par->targinfo;
31 30
32 if (datalen != EBT_ALIGN(sizeof(struct ebt_log_info)))
33 return -EINVAL;
34 if (info->bitmask & ~EBT_LOG_MASK) 31 if (info->bitmask & ~EBT_LOG_MASK)
35 return -EINVAL; 32 return false;
36 if (info->loglevel >= 8) 33 if (info->loglevel >= 8)
37 return -EINVAL; 34 return false;
38 info->prefix[EBT_LOG_PREFIX_SIZE - 1] = '\0'; 35 info->prefix[EBT_LOG_PREFIX_SIZE - 1] = '\0';
39 return 0; 36 return true;
40} 37}
41 38
42struct tcpudphdr 39struct tcpudphdr
@@ -84,7 +81,7 @@ print_ports(const struct sk_buff *skb, uint8_t protocol, int offset)
84 81
85#define myNIPQUAD(a) a[0], a[1], a[2], a[3] 82#define myNIPQUAD(a) a[0], a[1], a[2], a[3]
86static void 83static void
87ebt_log_packet(unsigned int pf, unsigned int hooknum, 84ebt_log_packet(u_int8_t pf, unsigned int hooknum,
88 const struct sk_buff *skb, const struct net_device *in, 85 const struct sk_buff *skb, const struct net_device *in,
89 const struct net_device *out, const struct nf_loginfo *loginfo, 86 const struct net_device *out, const struct nf_loginfo *loginfo,
90 const char *prefix) 87 const char *prefix)
@@ -194,11 +191,10 @@ out:
194 191
195} 192}
196 193
197static void ebt_log(const struct sk_buff *skb, unsigned int hooknr, 194static unsigned int
198 const struct net_device *in, const struct net_device *out, 195ebt_log_tg(struct sk_buff *skb, const struct xt_target_param *par)
199 const void *data, unsigned int datalen)
200{ 196{
201 const struct ebt_log_info *info = data; 197 const struct ebt_log_info *info = par->targinfo;
202 struct nf_loginfo li; 198 struct nf_loginfo li;
203 199
204 li.type = NF_LOG_TYPE_LOG; 200 li.type = NF_LOG_TYPE_LOG;
@@ -206,18 +202,21 @@ static void ebt_log(const struct sk_buff *skb, unsigned int hooknr,
206 li.u.log.logflags = info->bitmask; 202 li.u.log.logflags = info->bitmask;
207 203
208 if (info->bitmask & EBT_LOG_NFLOG) 204 if (info->bitmask & EBT_LOG_NFLOG)
209 nf_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li, 205 nf_log_packet(NFPROTO_BRIDGE, par->hooknum, skb, par->in,
210 "%s", info->prefix); 206 par->out, &li, "%s", info->prefix);
211 else 207 else
212 ebt_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li, 208 ebt_log_packet(NFPROTO_BRIDGE, par->hooknum, skb, par->in,
213 info->prefix); 209 par->out, &li, info->prefix);
210 return EBT_CONTINUE;
214} 211}
215 212
216static struct ebt_watcher log = 213static struct xt_target ebt_log_tg_reg __read_mostly = {
217{ 214 .name = "log",
218 .name = EBT_LOG_WATCHER, 215 .revision = 0,
219 .watcher = ebt_log, 216 .family = NFPROTO_BRIDGE,
220 .check = ebt_log_check, 217 .target = ebt_log_tg,
218 .checkentry = ebt_log_tg_check,
219 .targetsize = XT_ALIGN(sizeof(struct ebt_log_info)),
221 .me = THIS_MODULE, 220 .me = THIS_MODULE,
222}; 221};
223 222
@@ -231,17 +230,17 @@ static int __init ebt_log_init(void)
231{ 230{
232 int ret; 231 int ret;
233 232
234 ret = ebt_register_watcher(&log); 233 ret = xt_register_target(&ebt_log_tg_reg);
235 if (ret < 0) 234 if (ret < 0)
236 return ret; 235 return ret;
237 nf_log_register(PF_BRIDGE, &ebt_log_logger); 236 nf_log_register(NFPROTO_BRIDGE, &ebt_log_logger);
238 return 0; 237 return 0;
239} 238}
240 239
241static void __exit ebt_log_fini(void) 240static void __exit ebt_log_fini(void)
242{ 241{
243 nf_log_unregister(&ebt_log_logger); 242 nf_log_unregister(&ebt_log_logger);
244 ebt_unregister_watcher(&log); 243 xt_unregister_target(&ebt_log_tg_reg);
245} 244}
246 245
247module_init(ebt_log_init); 246module_init(ebt_log_init);
diff --git a/net/bridge/netfilter/ebt_mark.c b/net/bridge/netfilter/ebt_mark.c
index 36723f47db0a..2fee7e8e2e93 100644
--- a/net/bridge/netfilter/ebt_mark.c
+++ b/net/bridge/netfilter/ebt_mark.c
@@ -13,15 +13,15 @@
13 * Marking a frame doesn't really change anything in the frame anyway. 13 * Marking a frame doesn't really change anything in the frame anyway.
14 */ 14 */
15 15
16#include <linux/module.h>
17#include <linux/netfilter/x_tables.h>
16#include <linux/netfilter_bridge/ebtables.h> 18#include <linux/netfilter_bridge/ebtables.h>
17#include <linux/netfilter_bridge/ebt_mark_t.h> 19#include <linux/netfilter_bridge/ebt_mark_t.h>
18#include <linux/module.h>
19 20
20static int ebt_target_mark(struct sk_buff *skb, unsigned int hooknr, 21static unsigned int
21 const struct net_device *in, const struct net_device *out, 22ebt_mark_tg(struct sk_buff *skb, const struct xt_target_param *par)
22 const void *data, unsigned int datalen)
23{ 23{
24 const struct ebt_mark_t_info *info = data; 24 const struct ebt_mark_t_info *info = par->targinfo;
25 int action = info->target & -16; 25 int action = info->target & -16;
26 26
27 if (action == MARK_SET_VALUE) 27 if (action == MARK_SET_VALUE)
@@ -36,42 +36,41 @@ static int ebt_target_mark(struct sk_buff *skb, unsigned int hooknr,
36 return info->target | ~EBT_VERDICT_BITS; 36 return info->target | ~EBT_VERDICT_BITS;
37} 37}
38 38
39static int ebt_target_mark_check(const char *tablename, unsigned int hookmask, 39static bool ebt_mark_tg_check(const struct xt_tgchk_param *par)
40 const struct ebt_entry *e, void *data, unsigned int datalen)
41{ 40{
42 const struct ebt_mark_t_info *info = data; 41 const struct ebt_mark_t_info *info = par->targinfo;
43 int tmp; 42 int tmp;
44 43
45 if (datalen != EBT_ALIGN(sizeof(struct ebt_mark_t_info)))
46 return -EINVAL;
47 tmp = info->target | ~EBT_VERDICT_BITS; 44 tmp = info->target | ~EBT_VERDICT_BITS;
48 if (BASE_CHAIN && tmp == EBT_RETURN) 45 if (BASE_CHAIN && tmp == EBT_RETURN)
49 return -EINVAL; 46 return false;
50 CLEAR_BASE_CHAIN_BIT;
51 if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0) 47 if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0)
52 return -EINVAL; 48 return false;
53 tmp = info->target & ~EBT_VERDICT_BITS; 49 tmp = info->target & ~EBT_VERDICT_BITS;
54 if (tmp != MARK_SET_VALUE && tmp != MARK_OR_VALUE && 50 if (tmp != MARK_SET_VALUE && tmp != MARK_OR_VALUE &&
55 tmp != MARK_AND_VALUE && tmp != MARK_XOR_VALUE) 51 tmp != MARK_AND_VALUE && tmp != MARK_XOR_VALUE)
56 return -EINVAL; 52 return false;
57 return 0; 53 return true;
58} 54}
59 55
60static struct ebt_target mark_target __read_mostly = { 56static struct xt_target ebt_mark_tg_reg __read_mostly = {
61 .name = EBT_MARK_TARGET, 57 .name = "mark",
62 .target = ebt_target_mark, 58 .revision = 0,
63 .check = ebt_target_mark_check, 59 .family = NFPROTO_BRIDGE,
60 .target = ebt_mark_tg,
61 .checkentry = ebt_mark_tg_check,
62 .targetsize = XT_ALIGN(sizeof(struct ebt_mark_t_info)),
64 .me = THIS_MODULE, 63 .me = THIS_MODULE,
65}; 64};
66 65
67static int __init ebt_mark_init(void) 66static int __init ebt_mark_init(void)
68{ 67{
69 return ebt_register_target(&mark_target); 68 return xt_register_target(&ebt_mark_tg_reg);
70} 69}
71 70
72static void __exit ebt_mark_fini(void) 71static void __exit ebt_mark_fini(void)
73{ 72{
74 ebt_unregister_target(&mark_target); 73 xt_unregister_target(&ebt_mark_tg_reg);
75} 74}
76 75
77module_init(ebt_mark_init); 76module_init(ebt_mark_init);
diff --git a/net/bridge/netfilter/ebt_mark_m.c b/net/bridge/netfilter/ebt_mark_m.c
index 9b0a4543861f..ea570f214b1d 100644
--- a/net/bridge/netfilter/ebt_mark_m.c
+++ b/net/bridge/netfilter/ebt_mark_m.c
@@ -7,53 +7,52 @@
7 * July, 2002 7 * July, 2002
8 * 8 *
9 */ 9 */
10 10#include <linux/module.h>
11#include <linux/netfilter/x_tables.h>
11#include <linux/netfilter_bridge/ebtables.h> 12#include <linux/netfilter_bridge/ebtables.h>
12#include <linux/netfilter_bridge/ebt_mark_m.h> 13#include <linux/netfilter_bridge/ebt_mark_m.h>
13#include <linux/module.h>
14 14
15static int ebt_filter_mark(const struct sk_buff *skb, 15static bool
16 const struct net_device *in, const struct net_device *out, const void *data, 16ebt_mark_mt(const struct sk_buff *skb, const struct xt_match_param *par)
17 unsigned int datalen)
18{ 17{
19 const struct ebt_mark_m_info *info = data; 18 const struct ebt_mark_m_info *info = par->matchinfo;
20 19
21 if (info->bitmask & EBT_MARK_OR) 20 if (info->bitmask & EBT_MARK_OR)
22 return !(!!(skb->mark & info->mask) ^ info->invert); 21 return !!(skb->mark & info->mask) ^ info->invert;
23 return !(((skb->mark & info->mask) == info->mark) ^ info->invert); 22 return ((skb->mark & info->mask) == info->mark) ^ info->invert;
24} 23}
25 24
26static int ebt_mark_check(const char *tablename, unsigned int hookmask, 25static bool ebt_mark_mt_check(const struct xt_mtchk_param *par)
27 const struct ebt_entry *e, void *data, unsigned int datalen)
28{ 26{
29 const struct ebt_mark_m_info *info = data; 27 const struct ebt_mark_m_info *info = par->matchinfo;
30 28
31 if (datalen != EBT_ALIGN(sizeof(struct ebt_mark_m_info)))
32 return -EINVAL;
33 if (info->bitmask & ~EBT_MARK_MASK) 29 if (info->bitmask & ~EBT_MARK_MASK)
34 return -EINVAL; 30 return false;
35 if ((info->bitmask & EBT_MARK_OR) && (info->bitmask & EBT_MARK_AND)) 31 if ((info->bitmask & EBT_MARK_OR) && (info->bitmask & EBT_MARK_AND))
36 return -EINVAL; 32 return false;
37 if (!info->bitmask) 33 if (!info->bitmask)
38 return -EINVAL; 34 return false;
39 return 0; 35 return true;
40} 36}
41 37
42static struct ebt_match filter_mark __read_mostly = { 38static struct xt_match ebt_mark_mt_reg __read_mostly = {
43 .name = EBT_MARK_MATCH, 39 .name = "mark_m",
44 .match = ebt_filter_mark, 40 .revision = 0,
45 .check = ebt_mark_check, 41 .family = NFPROTO_BRIDGE,
42 .match = ebt_mark_mt,
43 .checkentry = ebt_mark_mt_check,
44 .matchsize = XT_ALIGN(sizeof(struct ebt_mark_m_info)),
46 .me = THIS_MODULE, 45 .me = THIS_MODULE,
47}; 46};
48 47
49static int __init ebt_mark_m_init(void) 48static int __init ebt_mark_m_init(void)
50{ 49{
51 return ebt_register_match(&filter_mark); 50 return xt_register_match(&ebt_mark_mt_reg);
52} 51}
53 52
54static void __exit ebt_mark_m_fini(void) 53static void __exit ebt_mark_m_fini(void)
55{ 54{
56 ebt_unregister_match(&filter_mark); 55 xt_unregister_match(&ebt_mark_mt_reg);
57} 56}
58 57
59module_init(ebt_mark_m_init); 58module_init(ebt_mark_m_init);
diff --git a/net/bridge/netfilter/ebt_nflog.c b/net/bridge/netfilter/ebt_nflog.c
index 8e799aa9e560..2a63d996dd4e 100644
--- a/net/bridge/netfilter/ebt_nflog.c
+++ b/net/bridge/netfilter/ebt_nflog.c
@@ -14,17 +14,15 @@
14 14
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/spinlock.h> 16#include <linux/spinlock.h>
17#include <linux/netfilter/x_tables.h>
17#include <linux/netfilter_bridge/ebtables.h> 18#include <linux/netfilter_bridge/ebtables.h>
18#include <linux/netfilter_bridge/ebt_nflog.h> 19#include <linux/netfilter_bridge/ebt_nflog.h>
19#include <net/netfilter/nf_log.h> 20#include <net/netfilter/nf_log.h>
20 21
21static void ebt_nflog(const struct sk_buff *skb, 22static unsigned int
22 unsigned int hooknr, 23ebt_nflog_tg(struct sk_buff *skb, const struct xt_target_param *par)
23 const struct net_device *in,
24 const struct net_device *out,
25 const void *data, unsigned int datalen)
26{ 24{
27 struct ebt_nflog_info *info = (struct ebt_nflog_info *)data; 25 const struct ebt_nflog_info *info = par->targinfo;
28 struct nf_loginfo li; 26 struct nf_loginfo li;
29 27
30 li.type = NF_LOG_TYPE_ULOG; 28 li.type = NF_LOG_TYPE_ULOG;
@@ -32,39 +30,39 @@ static void ebt_nflog(const struct sk_buff *skb,
32 li.u.ulog.group = info->group; 30 li.u.ulog.group = info->group;
33 li.u.ulog.qthreshold = info->threshold; 31 li.u.ulog.qthreshold = info->threshold;
34 32
35 nf_log_packet(PF_BRIDGE, hooknr, skb, in, out, &li, "%s", info->prefix); 33 nf_log_packet(PF_BRIDGE, par->hooknum, skb, par->in, par->out,
34 &li, "%s", info->prefix);
35 return EBT_CONTINUE;
36} 36}
37 37
38static int ebt_nflog_check(const char *tablename, 38static bool ebt_nflog_tg_check(const struct xt_tgchk_param *par)
39 unsigned int hookmask,
40 const struct ebt_entry *e,
41 void *data, unsigned int datalen)
42{ 39{
43 struct ebt_nflog_info *info = (struct ebt_nflog_info *)data; 40 struct ebt_nflog_info *info = par->targinfo;
44 41
45 if (datalen != EBT_ALIGN(sizeof(struct ebt_nflog_info)))
46 return -EINVAL;
47 if (info->flags & ~EBT_NFLOG_MASK) 42 if (info->flags & ~EBT_NFLOG_MASK)
48 return -EINVAL; 43 return false;
49 info->prefix[EBT_NFLOG_PREFIX_SIZE - 1] = '\0'; 44 info->prefix[EBT_NFLOG_PREFIX_SIZE - 1] = '\0';
50 return 0; 45 return true;
51} 46}
52 47
53static struct ebt_watcher nflog __read_mostly = { 48static struct xt_target ebt_nflog_tg_reg __read_mostly = {
54 .name = EBT_NFLOG_WATCHER, 49 .name = "nflog",
55 .watcher = ebt_nflog, 50 .revision = 0,
56 .check = ebt_nflog_check, 51 .family = NFPROTO_BRIDGE,
57 .me = THIS_MODULE, 52 .target = ebt_nflog_tg,
53 .checkentry = ebt_nflog_tg_check,
54 .targetsize = XT_ALIGN(sizeof(struct ebt_nflog_info)),
55 .me = THIS_MODULE,
58}; 56};
59 57
60static int __init ebt_nflog_init(void) 58static int __init ebt_nflog_init(void)
61{ 59{
62 return ebt_register_watcher(&nflog); 60 return xt_register_target(&ebt_nflog_tg_reg);
63} 61}
64 62
65static void __exit ebt_nflog_fini(void) 63static void __exit ebt_nflog_fini(void)
66{ 64{
67 ebt_unregister_watcher(&nflog); 65 xt_unregister_target(&ebt_nflog_tg_reg);
68} 66}
69 67
70module_init(ebt_nflog_init); 68module_init(ebt_nflog_init);
diff --git a/net/bridge/netfilter/ebt_pkttype.c b/net/bridge/netfilter/ebt_pkttype.c
index 676db32df3d1..883e96e2a542 100644
--- a/net/bridge/netfilter/ebt_pkttype.c
+++ b/net/bridge/netfilter/ebt_pkttype.c
@@ -7,50 +7,47 @@
7 * April, 2003 7 * April, 2003
8 * 8 *
9 */ 9 */
10 10#include <linux/module.h>
11#include <linux/netfilter/x_tables.h>
11#include <linux/netfilter_bridge/ebtables.h> 12#include <linux/netfilter_bridge/ebtables.h>
12#include <linux/netfilter_bridge/ebt_pkttype.h> 13#include <linux/netfilter_bridge/ebt_pkttype.h>
13#include <linux/module.h>
14 14
15static int ebt_filter_pkttype(const struct sk_buff *skb, 15static bool
16 const struct net_device *in, 16ebt_pkttype_mt(const struct sk_buff *skb, const struct xt_match_param *par)
17 const struct net_device *out,
18 const void *data,
19 unsigned int datalen)
20{ 17{
21 const struct ebt_pkttype_info *info = data; 18 const struct ebt_pkttype_info *info = par->matchinfo;
22 19
23 return (skb->pkt_type != info->pkt_type) ^ info->invert; 20 return (skb->pkt_type == info->pkt_type) ^ info->invert;
24} 21}
25 22
26static int ebt_pkttype_check(const char *tablename, unsigned int hookmask, 23static bool ebt_pkttype_mt_check(const struct xt_mtchk_param *par)
27 const struct ebt_entry *e, void *data, unsigned int datalen)
28{ 24{
29 const struct ebt_pkttype_info *info = data; 25 const struct ebt_pkttype_info *info = par->matchinfo;
30 26
31 if (datalen != EBT_ALIGN(sizeof(struct ebt_pkttype_info)))
32 return -EINVAL;
33 if (info->invert != 0 && info->invert != 1) 27 if (info->invert != 0 && info->invert != 1)
34 return -EINVAL; 28 return false;
35 /* Allow any pkt_type value */ 29 /* Allow any pkt_type value */
36 return 0; 30 return true;
37} 31}
38 32
39static struct ebt_match filter_pkttype __read_mostly = { 33static struct xt_match ebt_pkttype_mt_reg __read_mostly = {
40 .name = EBT_PKTTYPE_MATCH, 34 .name = "pkttype",
41 .match = ebt_filter_pkttype, 35 .revision = 0,
42 .check = ebt_pkttype_check, 36 .family = NFPROTO_BRIDGE,
37 .match = ebt_pkttype_mt,
38 .checkentry = ebt_pkttype_mt_check,
39 .matchsize = XT_ALIGN(sizeof(struct ebt_pkttype_info)),
43 .me = THIS_MODULE, 40 .me = THIS_MODULE,
44}; 41};
45 42
46static int __init ebt_pkttype_init(void) 43static int __init ebt_pkttype_init(void)
47{ 44{
48 return ebt_register_match(&filter_pkttype); 45 return xt_register_match(&ebt_pkttype_mt_reg);
49} 46}
50 47
51static void __exit ebt_pkttype_fini(void) 48static void __exit ebt_pkttype_fini(void)
52{ 49{
53 ebt_unregister_match(&filter_pkttype); 50 xt_unregister_match(&ebt_pkttype_mt_reg);
54} 51}
55 52
56module_init(ebt_pkttype_init); 53module_init(ebt_pkttype_init);
diff --git a/net/bridge/netfilter/ebt_redirect.c b/net/bridge/netfilter/ebt_redirect.c
index b8afe850cf1e..c8a49f7a57ba 100644
--- a/net/bridge/netfilter/ebt_redirect.c
+++ b/net/bridge/netfilter/ebt_redirect.c
@@ -7,65 +7,70 @@
7 * April, 2002 7 * April, 2002
8 * 8 *
9 */ 9 */
10
11#include <linux/netfilter.h>
12#include <linux/netfilter_bridge/ebtables.h>
13#include <linux/netfilter_bridge/ebt_redirect.h>
14#include <linux/module.h> 10#include <linux/module.h>
15#include <net/sock.h> 11#include <net/sock.h>
16#include "../br_private.h" 12#include "../br_private.h"
13#include <linux/netfilter.h>
14#include <linux/netfilter/x_tables.h>
15#include <linux/netfilter_bridge/ebtables.h>
16#include <linux/netfilter_bridge/ebt_redirect.h>
17 17
18static int ebt_target_redirect(struct sk_buff *skb, unsigned int hooknr, 18static unsigned int
19 const struct net_device *in, const struct net_device *out, 19ebt_redirect_tg(struct sk_buff *skb, const struct xt_target_param *par)
20 const void *data, unsigned int datalen)
21{ 20{
22 const struct ebt_redirect_info *info = data; 21 const struct ebt_redirect_info *info = par->targinfo;
23 22
24 if (!skb_make_writable(skb, 0)) 23 if (!skb_make_writable(skb, 0))
25 return EBT_DROP; 24 return EBT_DROP;
26 25
27 if (hooknr != NF_BR_BROUTING) 26 if (par->hooknum != NF_BR_BROUTING)
28 memcpy(eth_hdr(skb)->h_dest, 27 memcpy(eth_hdr(skb)->h_dest,
29 in->br_port->br->dev->dev_addr, ETH_ALEN); 28 par->in->br_port->br->dev->dev_addr, ETH_ALEN);
30 else 29 else
31 memcpy(eth_hdr(skb)->h_dest, in->dev_addr, ETH_ALEN); 30 memcpy(eth_hdr(skb)->h_dest, par->in->dev_addr, ETH_ALEN);
32 skb->pkt_type = PACKET_HOST; 31 skb->pkt_type = PACKET_HOST;
33 return info->target; 32 return info->target;
34} 33}
35 34
36static int ebt_target_redirect_check(const char *tablename, unsigned int hookmask, 35static bool ebt_redirect_tg_check(const struct xt_tgchk_param *par)
37 const struct ebt_entry *e, void *data, unsigned int datalen)
38{ 36{
39 const struct ebt_redirect_info *info = data; 37 const struct ebt_redirect_info *info = par->targinfo;
38 unsigned int hook_mask;
40 39
41 if (datalen != EBT_ALIGN(sizeof(struct ebt_redirect_info)))
42 return -EINVAL;
43 if (BASE_CHAIN && info->target == EBT_RETURN) 40 if (BASE_CHAIN && info->target == EBT_RETURN)
44 return -EINVAL; 41 return false;
45 CLEAR_BASE_CHAIN_BIT; 42
46 if ( (strcmp(tablename, "nat") || hookmask & ~(1 << NF_BR_PRE_ROUTING)) && 43 hook_mask = par->hook_mask & ~(1 << NF_BR_NUMHOOKS);
47 (strcmp(tablename, "broute") || hookmask & ~(1 << NF_BR_BROUTING)) ) 44 if ((strcmp(par->table, "nat") != 0 ||
48 return -EINVAL; 45 hook_mask & ~(1 << NF_BR_PRE_ROUTING)) &&
46 (strcmp(par->table, "broute") != 0 ||
47 hook_mask & ~(1 << NF_BR_BROUTING)))
48 return false;
49 if (INVALID_TARGET) 49 if (INVALID_TARGET)
50 return -EINVAL; 50 return false;
51 return 0; 51 return true;
52} 52}
53 53
54static struct ebt_target redirect_target __read_mostly = { 54static struct xt_target ebt_redirect_tg_reg __read_mostly = {
55 .name = EBT_REDIRECT_TARGET, 55 .name = "redirect",
56 .target = ebt_target_redirect, 56 .revision = 0,
57 .check = ebt_target_redirect_check, 57 .family = NFPROTO_BRIDGE,
58 .hooks = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_PRE_ROUTING) |
59 (1 << NF_BR_BROUTING),
60 .target = ebt_redirect_tg,
61 .checkentry = ebt_redirect_tg_check,
62 .targetsize = XT_ALIGN(sizeof(struct ebt_redirect_info)),
58 .me = THIS_MODULE, 63 .me = THIS_MODULE,
59}; 64};
60 65
61static int __init ebt_redirect_init(void) 66static int __init ebt_redirect_init(void)
62{ 67{
63 return ebt_register_target(&redirect_target); 68 return xt_register_target(&ebt_redirect_tg_reg);
64} 69}
65 70
66static void __exit ebt_redirect_fini(void) 71static void __exit ebt_redirect_fini(void)
67{ 72{
68 ebt_unregister_target(&redirect_target); 73 xt_unregister_target(&ebt_redirect_tg_reg);
69} 74}
70 75
71module_init(ebt_redirect_init); 76module_init(ebt_redirect_init);
diff --git a/net/bridge/netfilter/ebt_snat.c b/net/bridge/netfilter/ebt_snat.c
index 5425333dda03..8d04d4c302bd 100644
--- a/net/bridge/netfilter/ebt_snat.c
+++ b/net/bridge/netfilter/ebt_snat.c
@@ -7,20 +7,19 @@
7 * June, 2002 7 * June, 2002
8 * 8 *
9 */ 9 */
10
11#include <linux/netfilter.h>
12#include <linux/netfilter_bridge/ebtables.h>
13#include <linux/netfilter_bridge/ebt_nat.h>
14#include <linux/module.h> 10#include <linux/module.h>
15#include <net/sock.h> 11#include <net/sock.h>
16#include <linux/if_arp.h> 12#include <linux/if_arp.h>
17#include <net/arp.h> 13#include <net/arp.h>
14#include <linux/netfilter.h>
15#include <linux/netfilter/x_tables.h>
16#include <linux/netfilter_bridge/ebtables.h>
17#include <linux/netfilter_bridge/ebt_nat.h>
18 18
19static int ebt_target_snat(struct sk_buff *skb, unsigned int hooknr, 19static unsigned int
20 const struct net_device *in, const struct net_device *out, 20ebt_snat_tg(struct sk_buff *skb, const struct xt_target_param *par)
21 const void *data, unsigned int datalen)
22{ 21{
23 const struct ebt_nat_info *info = data; 22 const struct ebt_nat_info *info = par->targinfo;
24 23
25 if (!skb_make_writable(skb, 0)) 24 if (!skb_make_writable(skb, 0))
26 return EBT_DROP; 25 return EBT_DROP;
@@ -43,46 +42,43 @@ out:
43 return info->target | ~EBT_VERDICT_BITS; 42 return info->target | ~EBT_VERDICT_BITS;
44} 43}
45 44
46static int ebt_target_snat_check(const char *tablename, unsigned int hookmask, 45static bool ebt_snat_tg_check(const struct xt_tgchk_param *par)
47 const struct ebt_entry *e, void *data, unsigned int datalen)
48{ 46{
49 const struct ebt_nat_info *info = data; 47 const struct ebt_nat_info *info = par->targinfo;
50 int tmp; 48 int tmp;
51 49
52 if (datalen != EBT_ALIGN(sizeof(struct ebt_nat_info)))
53 return -EINVAL;
54 tmp = info->target | ~EBT_VERDICT_BITS; 50 tmp = info->target | ~EBT_VERDICT_BITS;
55 if (BASE_CHAIN && tmp == EBT_RETURN) 51 if (BASE_CHAIN && tmp == EBT_RETURN)
56 return -EINVAL; 52 return false;
57 CLEAR_BASE_CHAIN_BIT;
58 if (strcmp(tablename, "nat"))
59 return -EINVAL;
60 if (hookmask & ~(1 << NF_BR_POST_ROUTING))
61 return -EINVAL;
62 53
63 if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0) 54 if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0)
64 return -EINVAL; 55 return false;
65 tmp = info->target | EBT_VERDICT_BITS; 56 tmp = info->target | EBT_VERDICT_BITS;
66 if ((tmp & ~NAT_ARP_BIT) != ~NAT_ARP_BIT) 57 if ((tmp & ~NAT_ARP_BIT) != ~NAT_ARP_BIT)
67 return -EINVAL; 58 return false;
68 return 0; 59 return true;
69} 60}
70 61
71static struct ebt_target snat __read_mostly = { 62static struct xt_target ebt_snat_tg_reg __read_mostly = {
72 .name = EBT_SNAT_TARGET, 63 .name = "snat",
73 .target = ebt_target_snat, 64 .revision = 0,
74 .check = ebt_target_snat_check, 65 .family = NFPROTO_BRIDGE,
66 .table = "nat",
67 .hooks = (1 << NF_BR_NUMHOOKS) | (1 << NF_BR_POST_ROUTING),
68 .target = ebt_snat_tg,
69 .checkentry = ebt_snat_tg_check,
70 .targetsize = XT_ALIGN(sizeof(struct ebt_nat_info)),
75 .me = THIS_MODULE, 71 .me = THIS_MODULE,
76}; 72};
77 73
78static int __init ebt_snat_init(void) 74static int __init ebt_snat_init(void)
79{ 75{
80 return ebt_register_target(&snat); 76 return xt_register_target(&ebt_snat_tg_reg);
81} 77}
82 78
83static void __exit ebt_snat_fini(void) 79static void __exit ebt_snat_fini(void)
84{ 80{
85 ebt_unregister_target(&snat); 81 xt_unregister_target(&ebt_snat_tg_reg);
86} 82}
87 83
88module_init(ebt_snat_init); 84module_init(ebt_snat_init);
diff --git a/net/bridge/netfilter/ebt_stp.c b/net/bridge/netfilter/ebt_stp.c
index 40f36d37607d..48527e621626 100644
--- a/net/bridge/netfilter/ebt_stp.c
+++ b/net/bridge/netfilter/ebt_stp.c
@@ -7,11 +7,11 @@
7 * 7 *
8 * July, 2003 8 * July, 2003
9 */ 9 */
10
11#include <linux/netfilter_bridge/ebtables.h>
12#include <linux/netfilter_bridge/ebt_stp.h>
13#include <linux/etherdevice.h> 10#include <linux/etherdevice.h>
14#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/netfilter/x_tables.h>
13#include <linux/netfilter_bridge/ebtables.h>
14#include <linux/netfilter_bridge/ebt_stp.h>
15 15
16#define BPDU_TYPE_CONFIG 0 16#define BPDU_TYPE_CONFIG 0
17#define BPDU_TYPE_TCN 0x80 17#define BPDU_TYPE_TCN 0x80
@@ -40,7 +40,7 @@ struct stp_config_pdu {
40#define NR16(p) (p[0] << 8 | p[1]) 40#define NR16(p) (p[0] << 8 | p[1])
41#define NR32(p) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]) 41#define NR32(p) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3])
42 42
43static int ebt_filter_config(const struct ebt_stp_info *info, 43static bool ebt_filter_config(const struct ebt_stp_info *info,
44 const struct stp_config_pdu *stpc) 44 const struct stp_config_pdu *stpc)
45{ 45{
46 const struct ebt_stp_config_info *c; 46 const struct ebt_stp_config_info *c;
@@ -51,12 +51,12 @@ static int ebt_filter_config(const struct ebt_stp_info *info,
51 c = &info->config; 51 c = &info->config;
52 if ((info->bitmask & EBT_STP_FLAGS) && 52 if ((info->bitmask & EBT_STP_FLAGS) &&
53 FWINV(c->flags != stpc->flags, EBT_STP_FLAGS)) 53 FWINV(c->flags != stpc->flags, EBT_STP_FLAGS))
54 return EBT_NOMATCH; 54 return false;
55 if (info->bitmask & EBT_STP_ROOTPRIO) { 55 if (info->bitmask & EBT_STP_ROOTPRIO) {
56 v16 = NR16(stpc->root); 56 v16 = NR16(stpc->root);
57 if (FWINV(v16 < c->root_priol || 57 if (FWINV(v16 < c->root_priol ||
58 v16 > c->root_priou, EBT_STP_ROOTPRIO)) 58 v16 > c->root_priou, EBT_STP_ROOTPRIO))
59 return EBT_NOMATCH; 59 return false;
60 } 60 }
61 if (info->bitmask & EBT_STP_ROOTADDR) { 61 if (info->bitmask & EBT_STP_ROOTADDR) {
62 verdict = 0; 62 verdict = 0;
@@ -64,19 +64,19 @@ static int ebt_filter_config(const struct ebt_stp_info *info,
64 verdict |= (stpc->root[2+i] ^ c->root_addr[i]) & 64 verdict |= (stpc->root[2+i] ^ c->root_addr[i]) &
65 c->root_addrmsk[i]; 65 c->root_addrmsk[i];
66 if (FWINV(verdict != 0, EBT_STP_ROOTADDR)) 66 if (FWINV(verdict != 0, EBT_STP_ROOTADDR))
67 return EBT_NOMATCH; 67 return false;
68 } 68 }
69 if (info->bitmask & EBT_STP_ROOTCOST) { 69 if (info->bitmask & EBT_STP_ROOTCOST) {
70 v32 = NR32(stpc->root_cost); 70 v32 = NR32(stpc->root_cost);
71 if (FWINV(v32 < c->root_costl || 71 if (FWINV(v32 < c->root_costl ||
72 v32 > c->root_costu, EBT_STP_ROOTCOST)) 72 v32 > c->root_costu, EBT_STP_ROOTCOST))
73 return EBT_NOMATCH; 73 return false;
74 } 74 }
75 if (info->bitmask & EBT_STP_SENDERPRIO) { 75 if (info->bitmask & EBT_STP_SENDERPRIO) {
76 v16 = NR16(stpc->sender); 76 v16 = NR16(stpc->sender);
77 if (FWINV(v16 < c->sender_priol || 77 if (FWINV(v16 < c->sender_priol ||
78 v16 > c->sender_priou, EBT_STP_SENDERPRIO)) 78 v16 > c->sender_priou, EBT_STP_SENDERPRIO))
79 return EBT_NOMATCH; 79 return false;
80 } 80 }
81 if (info->bitmask & EBT_STP_SENDERADDR) { 81 if (info->bitmask & EBT_STP_SENDERADDR) {
82 verdict = 0; 82 verdict = 0;
@@ -84,60 +84,60 @@ static int ebt_filter_config(const struct ebt_stp_info *info,
84 verdict |= (stpc->sender[2+i] ^ c->sender_addr[i]) & 84 verdict |= (stpc->sender[2+i] ^ c->sender_addr[i]) &
85 c->sender_addrmsk[i]; 85 c->sender_addrmsk[i];
86 if (FWINV(verdict != 0, EBT_STP_SENDERADDR)) 86 if (FWINV(verdict != 0, EBT_STP_SENDERADDR))
87 return EBT_NOMATCH; 87 return false;
88 } 88 }
89 if (info->bitmask & EBT_STP_PORT) { 89 if (info->bitmask & EBT_STP_PORT) {
90 v16 = NR16(stpc->port); 90 v16 = NR16(stpc->port);
91 if (FWINV(v16 < c->portl || 91 if (FWINV(v16 < c->portl ||
92 v16 > c->portu, EBT_STP_PORT)) 92 v16 > c->portu, EBT_STP_PORT))
93 return EBT_NOMATCH; 93 return false;
94 } 94 }
95 if (info->bitmask & EBT_STP_MSGAGE) { 95 if (info->bitmask & EBT_STP_MSGAGE) {
96 v16 = NR16(stpc->msg_age); 96 v16 = NR16(stpc->msg_age);
97 if (FWINV(v16 < c->msg_agel || 97 if (FWINV(v16 < c->msg_agel ||
98 v16 > c->msg_ageu, EBT_STP_MSGAGE)) 98 v16 > c->msg_ageu, EBT_STP_MSGAGE))
99 return EBT_NOMATCH; 99 return false;
100 } 100 }
101 if (info->bitmask & EBT_STP_MAXAGE) { 101 if (info->bitmask & EBT_STP_MAXAGE) {
102 v16 = NR16(stpc->max_age); 102 v16 = NR16(stpc->max_age);
103 if (FWINV(v16 < c->max_agel || 103 if (FWINV(v16 < c->max_agel ||
104 v16 > c->max_ageu, EBT_STP_MAXAGE)) 104 v16 > c->max_ageu, EBT_STP_MAXAGE))
105 return EBT_NOMATCH; 105 return false;
106 } 106 }
107 if (info->bitmask & EBT_STP_HELLOTIME) { 107 if (info->bitmask & EBT_STP_HELLOTIME) {
108 v16 = NR16(stpc->hello_time); 108 v16 = NR16(stpc->hello_time);
109 if (FWINV(v16 < c->hello_timel || 109 if (FWINV(v16 < c->hello_timel ||
110 v16 > c->hello_timeu, EBT_STP_HELLOTIME)) 110 v16 > c->hello_timeu, EBT_STP_HELLOTIME))
111 return EBT_NOMATCH; 111 return false;
112 } 112 }
113 if (info->bitmask & EBT_STP_FWDD) { 113 if (info->bitmask & EBT_STP_FWDD) {
114 v16 = NR16(stpc->forward_delay); 114 v16 = NR16(stpc->forward_delay);
115 if (FWINV(v16 < c->forward_delayl || 115 if (FWINV(v16 < c->forward_delayl ||
116 v16 > c->forward_delayu, EBT_STP_FWDD)) 116 v16 > c->forward_delayu, EBT_STP_FWDD))
117 return EBT_NOMATCH; 117 return false;
118 } 118 }
119 return EBT_MATCH; 119 return true;
120} 120}
121 121
122static int ebt_filter_stp(const struct sk_buff *skb, const struct net_device *in, 122static bool
123 const struct net_device *out, const void *data, unsigned int datalen) 123ebt_stp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
124{ 124{
125 const struct ebt_stp_info *info = data; 125 const struct ebt_stp_info *info = par->matchinfo;
126 const struct stp_header *sp; 126 const struct stp_header *sp;
127 struct stp_header _stph; 127 struct stp_header _stph;
128 const uint8_t header[6] = {0x42, 0x42, 0x03, 0x00, 0x00, 0x00}; 128 const uint8_t header[6] = {0x42, 0x42, 0x03, 0x00, 0x00, 0x00};
129 129
130 sp = skb_header_pointer(skb, 0, sizeof(_stph), &_stph); 130 sp = skb_header_pointer(skb, 0, sizeof(_stph), &_stph);
131 if (sp == NULL) 131 if (sp == NULL)
132 return EBT_NOMATCH; 132 return false;
133 133
134 /* The stp code only considers these */ 134 /* The stp code only considers these */
135 if (memcmp(sp, header, sizeof(header))) 135 if (memcmp(sp, header, sizeof(header)))
136 return EBT_NOMATCH; 136 return false;
137 137
138 if (info->bitmask & EBT_STP_TYPE 138 if (info->bitmask & EBT_STP_TYPE
139 && FWINV(info->type != sp->type, EBT_STP_TYPE)) 139 && FWINV(info->type != sp->type, EBT_STP_TYPE))
140 return EBT_NOMATCH; 140 return false;
141 141
142 if (sp->type == BPDU_TYPE_CONFIG && 142 if (sp->type == BPDU_TYPE_CONFIG &&
143 info->bitmask & EBT_STP_CONFIG_MASK) { 143 info->bitmask & EBT_STP_CONFIG_MASK) {
@@ -147,48 +147,48 @@ static int ebt_filter_stp(const struct sk_buff *skb, const struct net_device *in
147 st = skb_header_pointer(skb, sizeof(_stph), 147 st = skb_header_pointer(skb, sizeof(_stph),
148 sizeof(_stpc), &_stpc); 148 sizeof(_stpc), &_stpc);
149 if (st == NULL) 149 if (st == NULL)
150 return EBT_NOMATCH; 150 return false;
151 return ebt_filter_config(info, st); 151 return ebt_filter_config(info, st);
152 } 152 }
153 return EBT_MATCH; 153 return true;
154} 154}
155 155
156static int ebt_stp_check(const char *tablename, unsigned int hookmask, 156static bool ebt_stp_mt_check(const struct xt_mtchk_param *par)
157 const struct ebt_entry *e, void *data, unsigned int datalen)
158{ 157{
159 const struct ebt_stp_info *info = data; 158 const struct ebt_stp_info *info = par->matchinfo;
160 const unsigned int len = EBT_ALIGN(sizeof(struct ebt_stp_info));
161 const uint8_t bridge_ula[6] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x00}; 159 const uint8_t bridge_ula[6] = {0x01, 0x80, 0xc2, 0x00, 0x00, 0x00};
162 const uint8_t msk[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 160 const uint8_t msk[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
161 const struct ebt_entry *e = par->entryinfo;
163 162
164 if (info->bitmask & ~EBT_STP_MASK || info->invflags & ~EBT_STP_MASK || 163 if (info->bitmask & ~EBT_STP_MASK || info->invflags & ~EBT_STP_MASK ||
165 !(info->bitmask & EBT_STP_MASK)) 164 !(info->bitmask & EBT_STP_MASK))
166 return -EINVAL; 165 return false;
167 if (datalen != len)
168 return -EINVAL;
169 /* Make sure the match only receives stp frames */ 166 /* Make sure the match only receives stp frames */
170 if (compare_ether_addr(e->destmac, bridge_ula) || 167 if (compare_ether_addr(e->destmac, bridge_ula) ||
171 compare_ether_addr(e->destmsk, msk) || !(e->bitmask & EBT_DESTMAC)) 168 compare_ether_addr(e->destmsk, msk) || !(e->bitmask & EBT_DESTMAC))
172 return -EINVAL; 169 return false;
173 170
174 return 0; 171 return true;
175} 172}
176 173
177static struct ebt_match filter_stp __read_mostly = { 174static struct xt_match ebt_stp_mt_reg __read_mostly = {
178 .name = EBT_STP_MATCH, 175 .name = "stp",
179 .match = ebt_filter_stp, 176 .revision = 0,
180 .check = ebt_stp_check, 177 .family = NFPROTO_BRIDGE,
178 .match = ebt_stp_mt,
179 .checkentry = ebt_stp_mt_check,
180 .matchsize = XT_ALIGN(sizeof(struct ebt_stp_info)),
181 .me = THIS_MODULE, 181 .me = THIS_MODULE,
182}; 182};
183 183
184static int __init ebt_stp_init(void) 184static int __init ebt_stp_init(void)
185{ 185{
186 return ebt_register_match(&filter_stp); 186 return xt_register_match(&ebt_stp_mt_reg);
187} 187}
188 188
189static void __exit ebt_stp_fini(void) 189static void __exit ebt_stp_fini(void)
190{ 190{
191 ebt_unregister_match(&filter_stp); 191 xt_unregister_match(&ebt_stp_mt_reg);
192} 192}
193 193
194module_init(ebt_stp_init); 194module_init(ebt_stp_init);
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c
index 2d4c9ef909fc..2c6d6823e703 100644
--- a/net/bridge/netfilter/ebt_ulog.c
+++ b/net/bridge/netfilter/ebt_ulog.c
@@ -36,6 +36,7 @@
36#include <linux/timer.h> 36#include <linux/timer.h>
37#include <linux/netlink.h> 37#include <linux/netlink.h>
38#include <linux/netdevice.h> 38#include <linux/netdevice.h>
39#include <linux/netfilter/x_tables.h>
39#include <linux/netfilter_bridge/ebtables.h> 40#include <linux/netfilter_bridge/ebtables.h>
40#include <linux/netfilter_bridge/ebt_ulog.h> 41#include <linux/netfilter_bridge/ebt_ulog.h>
41#include <net/netfilter/nf_log.h> 42#include <net/netfilter/nf_log.h>
@@ -223,7 +224,7 @@ alloc_failure:
223} 224}
224 225
225/* this function is registered with the netfilter core */ 226/* this function is registered with the netfilter core */
226static void ebt_log_packet(unsigned int pf, unsigned int hooknum, 227static void ebt_log_packet(u_int8_t pf, unsigned int hooknum,
227 const struct sk_buff *skb, const struct net_device *in, 228 const struct sk_buff *skb, const struct net_device *in,
228 const struct net_device *out, const struct nf_loginfo *li, 229 const struct net_device *out, const struct nf_loginfo *li,
229 const char *prefix) 230 const char *prefix)
@@ -245,24 +246,20 @@ static void ebt_log_packet(unsigned int pf, unsigned int hooknum,
245 ebt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); 246 ebt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
246} 247}
247 248
248static void ebt_ulog(const struct sk_buff *skb, unsigned int hooknr, 249static unsigned int
249 const struct net_device *in, const struct net_device *out, 250ebt_ulog_tg(struct sk_buff *skb, const struct xt_target_param *par)
250 const void *data, unsigned int datalen)
251{ 251{
252 const struct ebt_ulog_info *uloginfo = data; 252 ebt_ulog_packet(par->hooknum, skb, par->in, par->out,
253 253 par->targinfo, NULL);
254 ebt_ulog_packet(hooknr, skb, in, out, uloginfo, NULL); 254 return EBT_CONTINUE;
255} 255}
256 256
257 257static bool ebt_ulog_tg_check(const struct xt_tgchk_param *par)
258static int ebt_ulog_check(const char *tablename, unsigned int hookmask,
259 const struct ebt_entry *e, void *data, unsigned int datalen)
260{ 258{
261 struct ebt_ulog_info *uloginfo = data; 259 struct ebt_ulog_info *uloginfo = par->targinfo;
262 260
263 if (datalen != EBT_ALIGN(sizeof(struct ebt_ulog_info)) || 261 if (uloginfo->nlgroup > 31)
264 uloginfo->nlgroup > 31) 262 return false;
265 return -EINVAL;
266 263
267 uloginfo->prefix[EBT_ULOG_PREFIX_LEN - 1] = '\0'; 264 uloginfo->prefix[EBT_ULOG_PREFIX_LEN - 1] = '\0';
268 265
@@ -272,27 +269,31 @@ static int ebt_ulog_check(const char *tablename, unsigned int hookmask,
272 return 0; 269 return 0;
273} 270}
274 271
275static struct ebt_watcher ulog __read_mostly = { 272static struct xt_target ebt_ulog_tg_reg __read_mostly = {
276 .name = EBT_ULOG_WATCHER, 273 .name = "ulog",
277 .watcher = ebt_ulog, 274 .revision = 0,
278 .check = ebt_ulog_check, 275 .family = NFPROTO_BRIDGE,
276 .target = ebt_ulog_tg,
277 .checkentry = ebt_ulog_tg_check,
278 .targetsize = XT_ALIGN(sizeof(struct ebt_ulog_info)),
279 .me = THIS_MODULE, 279 .me = THIS_MODULE,
280}; 280};
281 281
282static const struct nf_logger ebt_ulog_logger = { 282static const struct nf_logger ebt_ulog_logger = {
283 .name = EBT_ULOG_WATCHER, 283 .name = "ulog",
284 .logfn = &ebt_log_packet, 284 .logfn = &ebt_log_packet,
285 .me = THIS_MODULE, 285 .me = THIS_MODULE,
286}; 286};
287 287
288static int __init ebt_ulog_init(void) 288static int __init ebt_ulog_init(void)
289{ 289{
290 int i, ret = 0; 290 bool ret = true;
291 int i;
291 292
292 if (nlbufsiz >= 128*1024) { 293 if (nlbufsiz >= 128*1024) {
293 printk(KERN_NOTICE "ebt_ulog: Netlink buffer has to be <= 128kB," 294 printk(KERN_NOTICE "ebt_ulog: Netlink buffer has to be <= 128kB,"
294 " please try a smaller nlbufsiz parameter.\n"); 295 " please try a smaller nlbufsiz parameter.\n");
295 return -EINVAL; 296 return false;
296 } 297 }
297 298
298 /* initialize ulog_buffers */ 299 /* initialize ulog_buffers */
@@ -304,13 +305,16 @@ static int __init ebt_ulog_init(void)
304 ebtulognl = netlink_kernel_create(&init_net, NETLINK_NFLOG, 305 ebtulognl = netlink_kernel_create(&init_net, NETLINK_NFLOG,
305 EBT_ULOG_MAXNLGROUPS, NULL, NULL, 306 EBT_ULOG_MAXNLGROUPS, NULL, NULL,
306 THIS_MODULE); 307 THIS_MODULE);
307 if (!ebtulognl) 308 if (!ebtulognl) {
308 ret = -ENOMEM; 309 printk(KERN_WARNING KBUILD_MODNAME ": out of memory trying to "
309 else if ((ret = ebt_register_watcher(&ulog))) 310 "call netlink_kernel_create\n");
311 ret = false;
312 } else if (xt_register_target(&ebt_ulog_tg_reg) != 0) {
310 netlink_kernel_release(ebtulognl); 313 netlink_kernel_release(ebtulognl);
314 }
311 315
312 if (ret == 0) 316 if (ret)
313 nf_log_register(PF_BRIDGE, &ebt_ulog_logger); 317 nf_log_register(NFPROTO_BRIDGE, &ebt_ulog_logger);
314 318
315 return ret; 319 return ret;
316} 320}
@@ -321,7 +325,7 @@ static void __exit ebt_ulog_fini(void)
321 int i; 325 int i;
322 326
323 nf_log_unregister(&ebt_ulog_logger); 327 nf_log_unregister(&ebt_ulog_logger);
324 ebt_unregister_watcher(&ulog); 328 xt_unregister_target(&ebt_ulog_tg_reg);
325 for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) { 329 for (i = 0; i < EBT_ULOG_MAXNLGROUPS; i++) {
326 ub = &ulog_buffers[i]; 330 ub = &ulog_buffers[i];
327 if (timer_pending(&ub->timer)) 331 if (timer_pending(&ub->timer))
diff --git a/net/bridge/netfilter/ebt_vlan.c b/net/bridge/netfilter/ebt_vlan.c
index ab60b0dade80..3dddd489328e 100644
--- a/net/bridge/netfilter/ebt_vlan.c
+++ b/net/bridge/netfilter/ebt_vlan.c
@@ -22,6 +22,7 @@
22#include <linux/if_vlan.h> 22#include <linux/if_vlan.h>
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/moduleparam.h> 24#include <linux/moduleparam.h>
25#include <linux/netfilter/x_tables.h>
25#include <linux/netfilter_bridge/ebtables.h> 26#include <linux/netfilter_bridge/ebtables.h>
26#include <linux/netfilter_bridge/ebt_vlan.h> 27#include <linux/netfilter_bridge/ebt_vlan.h>
27 28
@@ -37,15 +38,12 @@ MODULE_LICENSE("GPL");
37 38
38#define DEBUG_MSG(args...) if (debug) printk (KERN_DEBUG "ebt_vlan: " args) 39#define DEBUG_MSG(args...) if (debug) printk (KERN_DEBUG "ebt_vlan: " args)
39#define GET_BITMASK(_BIT_MASK_) info->bitmask & _BIT_MASK_ 40#define GET_BITMASK(_BIT_MASK_) info->bitmask & _BIT_MASK_
40#define EXIT_ON_MISMATCH(_MATCH_,_MASK_) {if (!((info->_MATCH_ == _MATCH_)^!!(info->invflags & _MASK_))) return EBT_NOMATCH;} 41#define EXIT_ON_MISMATCH(_MATCH_,_MASK_) {if (!((info->_MATCH_ == _MATCH_)^!!(info->invflags & _MASK_))) return false; }
41 42
42static int 43static bool
43ebt_filter_vlan(const struct sk_buff *skb, 44ebt_vlan_mt(const struct sk_buff *skb, const struct xt_match_param *par)
44 const struct net_device *in,
45 const struct net_device *out,
46 const void *data, unsigned int datalen)
47{ 45{
48 const struct ebt_vlan_info *info = data; 46 const struct ebt_vlan_info *info = par->matchinfo;
49 const struct vlan_hdr *fp; 47 const struct vlan_hdr *fp;
50 struct vlan_hdr _frame; 48 struct vlan_hdr _frame;
51 49
@@ -57,7 +55,7 @@ ebt_filter_vlan(const struct sk_buff *skb,
57 55
58 fp = skb_header_pointer(skb, 0, sizeof(_frame), &_frame); 56 fp = skb_header_pointer(skb, 0, sizeof(_frame), &_frame);
59 if (fp == NULL) 57 if (fp == NULL)
60 return EBT_NOMATCH; 58 return false;
61 59
62 /* Tag Control Information (TCI) consists of the following elements: 60 /* Tag Control Information (TCI) consists of the following elements:
63 * - User_priority. The user_priority field is three bits in length, 61 * - User_priority. The user_priority field is three bits in length,
@@ -83,30 +81,20 @@ ebt_filter_vlan(const struct sk_buff *skb,
83 if (GET_BITMASK(EBT_VLAN_ENCAP)) 81 if (GET_BITMASK(EBT_VLAN_ENCAP))
84 EXIT_ON_MISMATCH(encap, EBT_VLAN_ENCAP); 82 EXIT_ON_MISMATCH(encap, EBT_VLAN_ENCAP);
85 83
86 return EBT_MATCH; 84 return true;
87} 85}
88 86
89static int 87static bool ebt_vlan_mt_check(const struct xt_mtchk_param *par)
90ebt_check_vlan(const char *tablename,
91 unsigned int hooknr,
92 const struct ebt_entry *e, void *data, unsigned int datalen)
93{ 88{
94 struct ebt_vlan_info *info = data; 89 struct ebt_vlan_info *info = par->matchinfo;
95 90 const struct ebt_entry *e = par->entryinfo;
96 /* Parameters buffer overflow check */
97 if (datalen != EBT_ALIGN(sizeof(struct ebt_vlan_info))) {
98 DEBUG_MSG
99 ("passed size %d is not eq to ebt_vlan_info (%Zd)\n",
100 datalen, sizeof(struct ebt_vlan_info));
101 return -EINVAL;
102 }
103 91
104 /* Is it 802.1Q frame checked? */ 92 /* Is it 802.1Q frame checked? */
105 if (e->ethproto != htons(ETH_P_8021Q)) { 93 if (e->ethproto != htons(ETH_P_8021Q)) {
106 DEBUG_MSG 94 DEBUG_MSG
107 ("passed entry proto %2.4X is not 802.1Q (8100)\n", 95 ("passed entry proto %2.4X is not 802.1Q (8100)\n",
108 (unsigned short) ntohs(e->ethproto)); 96 (unsigned short) ntohs(e->ethproto));
109 return -EINVAL; 97 return false;
110 } 98 }
111 99
112 /* Check for bitmask range 100 /* Check for bitmask range
@@ -114,14 +102,14 @@ ebt_check_vlan(const char *tablename,
114 if (info->bitmask & ~EBT_VLAN_MASK) { 102 if (info->bitmask & ~EBT_VLAN_MASK) {
115 DEBUG_MSG("bitmask %2X is out of mask (%2X)\n", 103 DEBUG_MSG("bitmask %2X is out of mask (%2X)\n",
116 info->bitmask, EBT_VLAN_MASK); 104 info->bitmask, EBT_VLAN_MASK);
117 return -EINVAL; 105 return false;
118 } 106 }
119 107
120 /* Check for inversion flags range */ 108 /* Check for inversion flags range */
121 if (info->invflags & ~EBT_VLAN_MASK) { 109 if (info->invflags & ~EBT_VLAN_MASK) {
122 DEBUG_MSG("inversion flags %2X is out of mask (%2X)\n", 110 DEBUG_MSG("inversion flags %2X is out of mask (%2X)\n",
123 info->invflags, EBT_VLAN_MASK); 111 info->invflags, EBT_VLAN_MASK);
124 return -EINVAL; 112 return false;
125 } 113 }
126 114
127 /* Reserved VLAN ID (VID) values 115 /* Reserved VLAN ID (VID) values
@@ -136,7 +124,7 @@ ebt_check_vlan(const char *tablename,
136 DEBUG_MSG 124 DEBUG_MSG
137 ("id %d is out of range (1-4096)\n", 125 ("id %d is out of range (1-4096)\n",
138 info->id); 126 info->id);
139 return -EINVAL; 127 return false;
140 } 128 }
141 /* Note: This is valid VLAN-tagged frame point. 129 /* Note: This is valid VLAN-tagged frame point.
142 * Any value of user_priority are acceptable, 130 * Any value of user_priority are acceptable,
@@ -151,7 +139,7 @@ ebt_check_vlan(const char *tablename,
151 if ((unsigned char) info->prio > 7) { 139 if ((unsigned char) info->prio > 7) {
152 DEBUG_MSG("prio %d is out of range (0-7)\n", 140 DEBUG_MSG("prio %d is out of range (0-7)\n",
153 info->prio); 141 info->prio);
154 return -EINVAL; 142 return false;
155 } 143 }
156 } 144 }
157 /* Check for encapsulated proto range - it is possible to be 145 /* Check for encapsulated proto range - it is possible to be
@@ -162,17 +150,20 @@ ebt_check_vlan(const char *tablename,
162 DEBUG_MSG 150 DEBUG_MSG
163 ("encap frame length %d is less than minimal\n", 151 ("encap frame length %d is less than minimal\n",
164 ntohs(info->encap)); 152 ntohs(info->encap));
165 return -EINVAL; 153 return false;
166 } 154 }
167 } 155 }
168 156
169 return 0; 157 return true;
170} 158}
171 159
172static struct ebt_match filter_vlan __read_mostly = { 160static struct xt_match ebt_vlan_mt_reg __read_mostly = {
173 .name = EBT_VLAN_MATCH, 161 .name = "vlan",
174 .match = ebt_filter_vlan, 162 .revision = 0,
175 .check = ebt_check_vlan, 163 .family = NFPROTO_BRIDGE,
164 .match = ebt_vlan_mt,
165 .checkentry = ebt_vlan_mt_check,
166 .matchsize = XT_ALIGN(sizeof(struct ebt_vlan_info)),
176 .me = THIS_MODULE, 167 .me = THIS_MODULE,
177}; 168};
178 169
@@ -181,12 +172,12 @@ static int __init ebt_vlan_init(void)
181 DEBUG_MSG("ebtables 802.1Q extension module v" 172 DEBUG_MSG("ebtables 802.1Q extension module v"
182 MODULE_VERS "\n"); 173 MODULE_VERS "\n");
183 DEBUG_MSG("module debug=%d\n", !!debug); 174 DEBUG_MSG("module debug=%d\n", !!debug);
184 return ebt_register_match(&filter_vlan); 175 return xt_register_match(&ebt_vlan_mt_reg);
185} 176}
186 177
187static void __exit ebt_vlan_fini(void) 178static void __exit ebt_vlan_fini(void)
188{ 179{
189 ebt_unregister_match(&filter_vlan); 180 xt_unregister_match(&ebt_vlan_mt_reg);
190} 181}
191 182
192module_init(ebt_vlan_init); 183module_init(ebt_vlan_init);
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index 32afff859e4a..5bb88eb0aad4 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -19,6 +19,7 @@
19#include <linux/kmod.h> 19#include <linux/kmod.h>
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/vmalloc.h> 21#include <linux/vmalloc.h>
22#include <linux/netfilter/x_tables.h>
22#include <linux/netfilter_bridge/ebtables.h> 23#include <linux/netfilter_bridge/ebtables.h>
23#include <linux/spinlock.h> 24#include <linux/spinlock.h>
24#include <linux/mutex.h> 25#include <linux/mutex.h>
@@ -55,29 +56,31 @@
55 56
56static DEFINE_MUTEX(ebt_mutex); 57static DEFINE_MUTEX(ebt_mutex);
57static LIST_HEAD(ebt_tables); 58static LIST_HEAD(ebt_tables);
58static LIST_HEAD(ebt_targets);
59static LIST_HEAD(ebt_matches);
60static LIST_HEAD(ebt_watchers);
61 59
62static struct ebt_target ebt_standard_target = 60static struct xt_target ebt_standard_target = {
63{ {NULL, NULL}, EBT_STANDARD_TARGET, NULL, NULL, NULL, NULL}; 61 .name = "standard",
62 .revision = 0,
63 .family = NFPROTO_BRIDGE,
64 .targetsize = sizeof(int),
65};
64 66
65static inline int ebt_do_watcher (struct ebt_entry_watcher *w, 67static inline int
66 const struct sk_buff *skb, unsigned int hooknr, const struct net_device *in, 68ebt_do_watcher(const struct ebt_entry_watcher *w, struct sk_buff *skb,
67 const struct net_device *out) 69 struct xt_target_param *par)
68{ 70{
69 w->u.watcher->watcher(skb, hooknr, in, out, w->data, 71 par->target = w->u.watcher;
70 w->watcher_size); 72 par->targinfo = w->data;
73 w->u.watcher->target(skb, par);
71 /* watchers don't give a verdict */ 74 /* watchers don't give a verdict */
72 return 0; 75 return 0;
73} 76}
74 77
75static inline int ebt_do_match (struct ebt_entry_match *m, 78static inline int ebt_do_match (struct ebt_entry_match *m,
76 const struct sk_buff *skb, const struct net_device *in, 79 const struct sk_buff *skb, struct xt_match_param *par)
77 const struct net_device *out)
78{ 80{
79 return m->u.match->match(skb, in, out, m->data, 81 par->match = m->u.match;
80 m->match_size); 82 par->matchinfo = m->data;
83 return m->u.match->match(skb, par);
81} 84}
82 85
83static inline int ebt_dev_check(char *entry, const struct net_device *device) 86static inline int ebt_dev_check(char *entry, const struct net_device *device)
@@ -153,6 +156,15 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
153 struct ebt_entries *chaininfo; 156 struct ebt_entries *chaininfo;
154 char *base; 157 char *base;
155 struct ebt_table_info *private; 158 struct ebt_table_info *private;
159 bool hotdrop = false;
160 struct xt_match_param mtpar;
161 struct xt_target_param tgpar;
162
163 mtpar.family = tgpar.family = NFPROTO_BRIDGE;
164 mtpar.in = tgpar.in = in;
165 mtpar.out = tgpar.out = out;
166 mtpar.hotdrop = &hotdrop;
167 tgpar.hooknum = hook;
156 168
157 read_lock_bh(&table->lock); 169 read_lock_bh(&table->lock);
158 private = table->private; 170 private = table->private;
@@ -173,8 +185,12 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
173 if (ebt_basic_match(point, eth_hdr(skb), in, out)) 185 if (ebt_basic_match(point, eth_hdr(skb), in, out))
174 goto letscontinue; 186 goto letscontinue;
175 187
176 if (EBT_MATCH_ITERATE(point, ebt_do_match, skb, in, out) != 0) 188 if (EBT_MATCH_ITERATE(point, ebt_do_match, skb, &mtpar) != 0)
177 goto letscontinue; 189 goto letscontinue;
190 if (hotdrop) {
191 read_unlock_bh(&table->lock);
192 return NF_DROP;
193 }
178 194
179 /* increase counter */ 195 /* increase counter */
180 (*(counter_base + i)).pcnt++; 196 (*(counter_base + i)).pcnt++;
@@ -182,17 +198,18 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
182 198
183 /* these should only watch: not modify, nor tell us 199 /* these should only watch: not modify, nor tell us
184 what to do with the packet */ 200 what to do with the packet */
185 EBT_WATCHER_ITERATE(point, ebt_do_watcher, skb, hook, in, 201 EBT_WATCHER_ITERATE(point, ebt_do_watcher, skb, &tgpar);
186 out);
187 202
188 t = (struct ebt_entry_target *) 203 t = (struct ebt_entry_target *)
189 (((char *)point) + point->target_offset); 204 (((char *)point) + point->target_offset);
190 /* standard target */ 205 /* standard target */
191 if (!t->u.target->target) 206 if (!t->u.target->target)
192 verdict = ((struct ebt_standard_target *)t)->verdict; 207 verdict = ((struct ebt_standard_target *)t)->verdict;
193 else 208 else {
194 verdict = t->u.target->target(skb, hook, 209 tgpar.target = t->u.target;
195 in, out, t->data, t->target_size); 210 tgpar.targinfo = t->data;
211 verdict = t->u.target->target(skb, &tgpar);
212 }
196 if (verdict == EBT_ACCEPT) { 213 if (verdict == EBT_ACCEPT) {
197 read_unlock_bh(&table->lock); 214 read_unlock_bh(&table->lock);
198 return NF_ACCEPT; 215 return NF_ACCEPT;
@@ -312,80 +329,71 @@ find_table_lock(const char *name, int *error, struct mutex *mutex)
312 return find_inlist_lock(&ebt_tables, name, "ebtable_", error, mutex); 329 return find_inlist_lock(&ebt_tables, name, "ebtable_", error, mutex);
313} 330}
314 331
315static inline struct ebt_match *
316find_match_lock(const char *name, int *error, struct mutex *mutex)
317{
318 return find_inlist_lock(&ebt_matches, name, "ebt_", error, mutex);
319}
320
321static inline struct ebt_watcher *
322find_watcher_lock(const char *name, int *error, struct mutex *mutex)
323{
324 return find_inlist_lock(&ebt_watchers, name, "ebt_", error, mutex);
325}
326
327static inline struct ebt_target *
328find_target_lock(const char *name, int *error, struct mutex *mutex)
329{
330 return find_inlist_lock(&ebt_targets, name, "ebt_", error, mutex);
331}
332
333static inline int 332static inline int
334ebt_check_match(struct ebt_entry_match *m, struct ebt_entry *e, 333ebt_check_match(struct ebt_entry_match *m, struct xt_mtchk_param *par,
335 const char *name, unsigned int hookmask, unsigned int *cnt) 334 unsigned int *cnt)
336{ 335{
337 struct ebt_match *match; 336 const struct ebt_entry *e = par->entryinfo;
337 struct xt_match *match;
338 size_t left = ((char *)e + e->watchers_offset) - (char *)m; 338 size_t left = ((char *)e + e->watchers_offset) - (char *)m;
339 int ret; 339 int ret;
340 340
341 if (left < sizeof(struct ebt_entry_match) || 341 if (left < sizeof(struct ebt_entry_match) ||
342 left - sizeof(struct ebt_entry_match) < m->match_size) 342 left - sizeof(struct ebt_entry_match) < m->match_size)
343 return -EINVAL; 343 return -EINVAL;
344 match = find_match_lock(m->u.name, &ret, &ebt_mutex); 344
345 if (!match) 345 match = try_then_request_module(xt_find_match(NFPROTO_BRIDGE,
346 return ret; 346 m->u.name, 0), "ebt_%s", m->u.name);
347 m->u.match = match; 347 if (IS_ERR(match))
348 if (!try_module_get(match->me)) { 348 return PTR_ERR(match);
349 mutex_unlock(&ebt_mutex); 349 if (match == NULL)
350 return -ENOENT; 350 return -ENOENT;
351 } 351 m->u.match = match;
352 mutex_unlock(&ebt_mutex); 352
353 if (match->check && 353 par->match = match;
354 match->check(name, hookmask, e, m->data, m->match_size) != 0) { 354 par->matchinfo = m->data;
355 BUGPRINT("match->check failed\n"); 355 ret = xt_check_match(par, m->match_size,
356 e->ethproto, e->invflags & EBT_IPROTO);
357 if (ret < 0) {
356 module_put(match->me); 358 module_put(match->me);
357 return -EINVAL; 359 return ret;
358 } 360 }
361
359 (*cnt)++; 362 (*cnt)++;
360 return 0; 363 return 0;
361} 364}
362 365
363static inline int 366static inline int
364ebt_check_watcher(struct ebt_entry_watcher *w, struct ebt_entry *e, 367ebt_check_watcher(struct ebt_entry_watcher *w, struct xt_tgchk_param *par,
365 const char *name, unsigned int hookmask, unsigned int *cnt) 368 unsigned int *cnt)
366{ 369{
367 struct ebt_watcher *watcher; 370 const struct ebt_entry *e = par->entryinfo;
371 struct xt_target *watcher;
368 size_t left = ((char *)e + e->target_offset) - (char *)w; 372 size_t left = ((char *)e + e->target_offset) - (char *)w;
369 int ret; 373 int ret;
370 374
371 if (left < sizeof(struct ebt_entry_watcher) || 375 if (left < sizeof(struct ebt_entry_watcher) ||
372 left - sizeof(struct ebt_entry_watcher) < w->watcher_size) 376 left - sizeof(struct ebt_entry_watcher) < w->watcher_size)
373 return -EINVAL; 377 return -EINVAL;
374 watcher = find_watcher_lock(w->u.name, &ret, &ebt_mutex); 378
375 if (!watcher) 379 watcher = try_then_request_module(
376 return ret; 380 xt_find_target(NFPROTO_BRIDGE, w->u.name, 0),
377 w->u.watcher = watcher; 381 "ebt_%s", w->u.name);
378 if (!try_module_get(watcher->me)) { 382 if (IS_ERR(watcher))
379 mutex_unlock(&ebt_mutex); 383 return PTR_ERR(watcher);
384 if (watcher == NULL)
380 return -ENOENT; 385 return -ENOENT;
381 } 386 w->u.watcher = watcher;
382 mutex_unlock(&ebt_mutex); 387
383 if (watcher->check && 388 par->target = watcher;
384 watcher->check(name, hookmask, e, w->data, w->watcher_size) != 0) { 389 par->targinfo = w->data;
385 BUGPRINT("watcher->check failed\n"); 390 ret = xt_check_target(par, w->watcher_size,
391 e->ethproto, e->invflags & EBT_IPROTO);
392 if (ret < 0) {
386 module_put(watcher->me); 393 module_put(watcher->me);
387 return -EINVAL; 394 return ret;
388 } 395 }
396
389 (*cnt)++; 397 (*cnt)++;
390 return 0; 398 return 0;
391} 399}
@@ -558,30 +566,41 @@ ebt_get_udc_positions(struct ebt_entry *e, struct ebt_table_info *newinfo,
558static inline int 566static inline int
559ebt_cleanup_match(struct ebt_entry_match *m, unsigned int *i) 567ebt_cleanup_match(struct ebt_entry_match *m, unsigned int *i)
560{ 568{
569 struct xt_mtdtor_param par;
570
561 if (i && (*i)-- == 0) 571 if (i && (*i)-- == 0)
562 return 1; 572 return 1;
563 if (m->u.match->destroy)
564 m->u.match->destroy(m->data, m->match_size);
565 module_put(m->u.match->me);
566 573
574 par.match = m->u.match;
575 par.matchinfo = m->data;
576 par.family = NFPROTO_BRIDGE;
577 if (par.match->destroy != NULL)
578 par.match->destroy(&par);
579 module_put(par.match->me);
567 return 0; 580 return 0;
568} 581}
569 582
570static inline int 583static inline int
571ebt_cleanup_watcher(struct ebt_entry_watcher *w, unsigned int *i) 584ebt_cleanup_watcher(struct ebt_entry_watcher *w, unsigned int *i)
572{ 585{
586 struct xt_tgdtor_param par;
587
573 if (i && (*i)-- == 0) 588 if (i && (*i)-- == 0)
574 return 1; 589 return 1;
575 if (w->u.watcher->destroy)
576 w->u.watcher->destroy(w->data, w->watcher_size);
577 module_put(w->u.watcher->me);
578 590
591 par.target = w->u.watcher;
592 par.targinfo = w->data;
593 par.family = NFPROTO_BRIDGE;
594 if (par.target->destroy != NULL)
595 par.target->destroy(&par);
596 module_put(par.target->me);
579 return 0; 597 return 0;
580} 598}
581 599
582static inline int 600static inline int
583ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt) 601ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt)
584{ 602{
603 struct xt_tgdtor_param par;
585 struct ebt_entry_target *t; 604 struct ebt_entry_target *t;
586 605
587 if (e->bitmask == 0) 606 if (e->bitmask == 0)
@@ -592,10 +611,13 @@ ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt)
592 EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, NULL); 611 EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, NULL);
593 EBT_MATCH_ITERATE(e, ebt_cleanup_match, NULL); 612 EBT_MATCH_ITERATE(e, ebt_cleanup_match, NULL);
594 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset); 613 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
595 if (t->u.target->destroy)
596 t->u.target->destroy(t->data, t->target_size);
597 module_put(t->u.target->me);
598 614
615 par.target = t->u.target;
616 par.targinfo = t->data;
617 par.family = NFPROTO_BRIDGE;
618 if (par.target->destroy != NULL)
619 par.target->destroy(&par);
620 module_put(par.target->me);
599 return 0; 621 return 0;
600} 622}
601 623
@@ -605,10 +627,12 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
605 struct ebt_cl_stack *cl_s, unsigned int udc_cnt) 627 struct ebt_cl_stack *cl_s, unsigned int udc_cnt)
606{ 628{
607 struct ebt_entry_target *t; 629 struct ebt_entry_target *t;
608 struct ebt_target *target; 630 struct xt_target *target;
609 unsigned int i, j, hook = 0, hookmask = 0; 631 unsigned int i, j, hook = 0, hookmask = 0;
610 size_t gap; 632 size_t gap;
611 int ret; 633 int ret;
634 struct xt_mtchk_param mtpar;
635 struct xt_tgchk_param tgpar;
612 636
613 /* don't mess with the struct ebt_entries */ 637 /* don't mess with the struct ebt_entries */
614 if (e->bitmask == 0) 638 if (e->bitmask == 0)
@@ -649,24 +673,31 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
649 hookmask = cl_s[i - 1].hookmask; 673 hookmask = cl_s[i - 1].hookmask;
650 } 674 }
651 i = 0; 675 i = 0;
652 ret = EBT_MATCH_ITERATE(e, ebt_check_match, e, name, hookmask, &i); 676
677 mtpar.table = tgpar.table = name;
678 mtpar.entryinfo = tgpar.entryinfo = e;
679 mtpar.hook_mask = tgpar.hook_mask = hookmask;
680 mtpar.family = tgpar.family = NFPROTO_BRIDGE;
681 ret = EBT_MATCH_ITERATE(e, ebt_check_match, &mtpar, &i);
653 if (ret != 0) 682 if (ret != 0)
654 goto cleanup_matches; 683 goto cleanup_matches;
655 j = 0; 684 j = 0;
656 ret = EBT_WATCHER_ITERATE(e, ebt_check_watcher, e, name, hookmask, &j); 685 ret = EBT_WATCHER_ITERATE(e, ebt_check_watcher, &tgpar, &j);
657 if (ret != 0) 686 if (ret != 0)
658 goto cleanup_watchers; 687 goto cleanup_watchers;
659 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset); 688 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
660 gap = e->next_offset - e->target_offset; 689 gap = e->next_offset - e->target_offset;
661 target = find_target_lock(t->u.name, &ret, &ebt_mutex); 690
662 if (!target) 691 target = try_then_request_module(
692 xt_find_target(NFPROTO_BRIDGE, t->u.name, 0),
693 "ebt_%s", t->u.name);
694 if (IS_ERR(target)) {
695 ret = PTR_ERR(target);
663 goto cleanup_watchers; 696 goto cleanup_watchers;
664 if (!try_module_get(target->me)) { 697 } else if (target == NULL) {
665 mutex_unlock(&ebt_mutex);
666 ret = -ENOENT; 698 ret = -ENOENT;
667 goto cleanup_watchers; 699 goto cleanup_watchers;
668 } 700 }
669 mutex_unlock(&ebt_mutex);
670 701
671 t->u.target = target; 702 t->u.target = target;
672 if (t->u.target == &ebt_standard_target) { 703 if (t->u.target == &ebt_standard_target) {
@@ -681,13 +712,20 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
681 ret = -EFAULT; 712 ret = -EFAULT;
682 goto cleanup_watchers; 713 goto cleanup_watchers;
683 } 714 }
684 } else if (t->target_size > gap - sizeof(struct ebt_entry_target) || 715 } else if (t->target_size > gap - sizeof(struct ebt_entry_target)) {
685 (t->u.target->check &&
686 t->u.target->check(name, hookmask, e, t->data, t->target_size) != 0)){
687 module_put(t->u.target->me); 716 module_put(t->u.target->me);
688 ret = -EFAULT; 717 ret = -EFAULT;
689 goto cleanup_watchers; 718 goto cleanup_watchers;
690 } 719 }
720
721 tgpar.target = target;
722 tgpar.targinfo = t->data;
723 ret = xt_check_target(&tgpar, t->target_size,
724 e->ethproto, e->invflags & EBT_IPROTO);
725 if (ret < 0) {
726 module_put(target->me);
727 goto cleanup_watchers;
728 }
691 (*cnt)++; 729 (*cnt)++;
692 return 0; 730 return 0;
693cleanup_watchers: 731cleanup_watchers:
@@ -1068,87 +1106,6 @@ free_newinfo:
1068 return ret; 1106 return ret;
1069} 1107}
1070 1108
1071int ebt_register_target(struct ebt_target *target)
1072{
1073 struct ebt_target *t;
1074 int ret;
1075
1076 ret = mutex_lock_interruptible(&ebt_mutex);
1077 if (ret != 0)
1078 return ret;
1079 list_for_each_entry(t, &ebt_targets, list) {
1080 if (strcmp(t->name, target->name) == 0) {
1081 mutex_unlock(&ebt_mutex);
1082 return -EEXIST;
1083 }
1084 }
1085 list_add(&target->list, &ebt_targets);
1086 mutex_unlock(&ebt_mutex);
1087
1088 return 0;
1089}
1090
1091void ebt_unregister_target(struct ebt_target *target)
1092{
1093 mutex_lock(&ebt_mutex);
1094 list_del(&target->list);
1095 mutex_unlock(&ebt_mutex);
1096}
1097
1098int ebt_register_match(struct ebt_match *match)
1099{
1100 struct ebt_match *m;
1101 int ret;
1102
1103 ret = mutex_lock_interruptible(&ebt_mutex);
1104 if (ret != 0)
1105 return ret;
1106 list_for_each_entry(m, &ebt_matches, list) {
1107 if (strcmp(m->name, match->name) == 0) {
1108 mutex_unlock(&ebt_mutex);
1109 return -EEXIST;
1110 }
1111 }
1112 list_add(&match->list, &ebt_matches);
1113 mutex_unlock(&ebt_mutex);
1114
1115 return 0;
1116}
1117
1118void ebt_unregister_match(struct ebt_match *match)
1119{
1120 mutex_lock(&ebt_mutex);
1121 list_del(&match->list);
1122 mutex_unlock(&ebt_mutex);
1123}
1124
1125int ebt_register_watcher(struct ebt_watcher *watcher)
1126{
1127 struct ebt_watcher *w;
1128 int ret;
1129
1130 ret = mutex_lock_interruptible(&ebt_mutex);
1131 if (ret != 0)
1132 return ret;
1133 list_for_each_entry(w, &ebt_watchers, list) {
1134 if (strcmp(w->name, watcher->name) == 0) {
1135 mutex_unlock(&ebt_mutex);
1136 return -EEXIST;
1137 }
1138 }
1139 list_add(&watcher->list, &ebt_watchers);
1140 mutex_unlock(&ebt_mutex);
1141
1142 return 0;
1143}
1144
1145void ebt_unregister_watcher(struct ebt_watcher *watcher)
1146{
1147 mutex_lock(&ebt_mutex);
1148 list_del(&watcher->list);
1149 mutex_unlock(&ebt_mutex);
1150}
1151
1152int ebt_register_table(struct ebt_table *table) 1109int ebt_register_table(struct ebt_table *table)
1153{ 1110{
1154 struct ebt_table_info *newinfo; 1111 struct ebt_table_info *newinfo;
@@ -1518,11 +1475,14 @@ static int __init ebtables_init(void)
1518{ 1475{
1519 int ret; 1476 int ret;
1520 1477
1521 mutex_lock(&ebt_mutex); 1478 ret = xt_register_target(&ebt_standard_target);
1522 list_add(&ebt_standard_target.list, &ebt_targets); 1479 if (ret < 0)
1523 mutex_unlock(&ebt_mutex); 1480 return ret;
1524 if ((ret = nf_register_sockopt(&ebt_sockopts)) < 0) 1481 ret = nf_register_sockopt(&ebt_sockopts);
1482 if (ret < 0) {
1483 xt_unregister_target(&ebt_standard_target);
1525 return ret; 1484 return ret;
1485 }
1526 1486
1527 printk(KERN_INFO "Ebtables v2.0 registered\n"); 1487 printk(KERN_INFO "Ebtables v2.0 registered\n");
1528 return 0; 1488 return 0;
@@ -1531,17 +1491,12 @@ static int __init ebtables_init(void)
1531static void __exit ebtables_fini(void) 1491static void __exit ebtables_fini(void)
1532{ 1492{
1533 nf_unregister_sockopt(&ebt_sockopts); 1493 nf_unregister_sockopt(&ebt_sockopts);
1494 xt_unregister_target(&ebt_standard_target);
1534 printk(KERN_INFO "Ebtables v2.0 unregistered\n"); 1495 printk(KERN_INFO "Ebtables v2.0 unregistered\n");
1535} 1496}
1536 1497
1537EXPORT_SYMBOL(ebt_register_table); 1498EXPORT_SYMBOL(ebt_register_table);
1538EXPORT_SYMBOL(ebt_unregister_table); 1499EXPORT_SYMBOL(ebt_unregister_table);
1539EXPORT_SYMBOL(ebt_register_match);
1540EXPORT_SYMBOL(ebt_unregister_match);
1541EXPORT_SYMBOL(ebt_register_watcher);
1542EXPORT_SYMBOL(ebt_unregister_watcher);
1543EXPORT_SYMBOL(ebt_register_target);
1544EXPORT_SYMBOL(ebt_unregister_target);
1545EXPORT_SYMBOL(ebt_do_table); 1500EXPORT_SYMBOL(ebt_do_table);
1546module_init(ebtables_init); 1501module_init(ebtables_init);
1547module_exit(ebtables_fini); 1502module_exit(ebtables_fini);
diff --git a/net/core/Makefile b/net/core/Makefile
index b1332f6d0042..26a37cb31923 100644
--- a/net/core/Makefile
+++ b/net/core/Makefile
@@ -6,6 +6,7 @@ obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \
6 gen_stats.o gen_estimator.o net_namespace.o 6 gen_stats.o gen_estimator.o net_namespace.o
7 7
8obj-$(CONFIG_SYSCTL) += sysctl_net_core.o 8obj-$(CONFIG_SYSCTL) += sysctl_net_core.o
9obj-$(CONFIG_HAS_DMA) += skb_dma_map.o
9 10
10obj-y += dev.o ethtool.o dev_mcast.o dst.o netevent.o \ 11obj-y += dev.o ethtool.o dev_mcast.o dst.o netevent.o \
11 neighbour.o rtnetlink.o utils.o link_watch.o filter.o 12 neighbour.o rtnetlink.o utils.o link_watch.o filter.o
diff --git a/net/core/dev.c b/net/core/dev.c
index 60c51f765887..1408a083fe4e 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -122,6 +122,7 @@
122#include <linux/if_arp.h> 122#include <linux/if_arp.h>
123#include <linux/if_vlan.h> 123#include <linux/if_vlan.h>
124#include <linux/ip.h> 124#include <linux/ip.h>
125#include <net/ip.h>
125#include <linux/ipv6.h> 126#include <linux/ipv6.h>
126#include <linux/in.h> 127#include <linux/in.h>
127#include <linux/jhash.h> 128#include <linux/jhash.h>
@@ -890,7 +891,7 @@ int dev_alloc_name(struct net_device *dev, const char *name)
890 * Change name of a device, can pass format strings "eth%d". 891 * Change name of a device, can pass format strings "eth%d".
891 * for wildcarding. 892 * for wildcarding.
892 */ 893 */
893int dev_change_name(struct net_device *dev, char *newname) 894int dev_change_name(struct net_device *dev, const char *newname)
894{ 895{
895 char oldname[IFNAMSIZ]; 896 char oldname[IFNAMSIZ];
896 int err = 0; 897 int err = 0;
@@ -916,7 +917,6 @@ int dev_change_name(struct net_device *dev, char *newname)
916 err = dev_alloc_name(dev, newname); 917 err = dev_alloc_name(dev, newname);
917 if (err < 0) 918 if (err < 0)
918 return err; 919 return err;
919 strcpy(newname, dev->name);
920 } 920 }
921 else if (__dev_get_by_name(net, newname)) 921 else if (__dev_get_by_name(net, newname))
922 return -EEXIST; 922 return -EEXIST;
@@ -954,6 +954,38 @@ rollback:
954} 954}
955 955
956/** 956/**
957 * dev_set_alias - change ifalias of a device
958 * @dev: device
959 * @alias: name up to IFALIASZ
960 * @len: limit of bytes to copy from info
961 *
962 * Set ifalias for a device,
963 */
964int dev_set_alias(struct net_device *dev, const char *alias, size_t len)
965{
966 ASSERT_RTNL();
967
968 if (len >= IFALIASZ)
969 return -EINVAL;
970
971 if (!len) {
972 if (dev->ifalias) {
973 kfree(dev->ifalias);
974 dev->ifalias = NULL;
975 }
976 return 0;
977 }
978
979 dev->ifalias = krealloc(dev->ifalias, len+1, GFP_KERNEL);
980 if (!dev->ifalias)
981 return -ENOMEM;
982
983 strlcpy(dev->ifalias, alias, len+1);
984 return len;
985}
986
987
988/**
957 * netdev_features_change - device changes features 989 * netdev_features_change - device changes features
958 * @dev: device to cause notification 990 * @dev: device to cause notification
959 * 991 *
@@ -1667,7 +1699,7 @@ static u16 simple_tx_hash(struct net_device *dev, struct sk_buff *skb)
1667{ 1699{
1668 u32 addr1, addr2, ports; 1700 u32 addr1, addr2, ports;
1669 u32 hash, ihl; 1701 u32 hash, ihl;
1670 u8 ip_proto; 1702 u8 ip_proto = 0;
1671 1703
1672 if (unlikely(!simple_tx_hashrnd_initialized)) { 1704 if (unlikely(!simple_tx_hashrnd_initialized)) {
1673 get_random_bytes(&simple_tx_hashrnd, 4); 1705 get_random_bytes(&simple_tx_hashrnd, 4);
@@ -1675,13 +1707,14 @@ static u16 simple_tx_hash(struct net_device *dev, struct sk_buff *skb)
1675 } 1707 }
1676 1708
1677 switch (skb->protocol) { 1709 switch (skb->protocol) {
1678 case __constant_htons(ETH_P_IP): 1710 case htons(ETH_P_IP):
1679 ip_proto = ip_hdr(skb)->protocol; 1711 if (!(ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)))
1712 ip_proto = ip_hdr(skb)->protocol;
1680 addr1 = ip_hdr(skb)->saddr; 1713 addr1 = ip_hdr(skb)->saddr;
1681 addr2 = ip_hdr(skb)->daddr; 1714 addr2 = ip_hdr(skb)->daddr;
1682 ihl = ip_hdr(skb)->ihl; 1715 ihl = ip_hdr(skb)->ihl;
1683 break; 1716 break;
1684 case __constant_htons(ETH_P_IPV6): 1717 case htons(ETH_P_IPV6):
1685 ip_proto = ipv6_hdr(skb)->nexthdr; 1718 ip_proto = ipv6_hdr(skb)->nexthdr;
1686 addr1 = ipv6_hdr(skb)->saddr.s6_addr32[3]; 1719 addr1 = ipv6_hdr(skb)->saddr.s6_addr32[3];
1687 addr2 = ipv6_hdr(skb)->daddr.s6_addr32[3]; 1720 addr2 = ipv6_hdr(skb)->daddr.s6_addr32[3];
@@ -1991,8 +2024,13 @@ static void net_tx_action(struct softirq_action *h)
1991 spin_unlock(root_lock); 2024 spin_unlock(root_lock);
1992 } else { 2025 } else {
1993 if (!test_bit(__QDISC_STATE_DEACTIVATED, 2026 if (!test_bit(__QDISC_STATE_DEACTIVATED,
1994 &q->state)) 2027 &q->state)) {
1995 __netif_reschedule(q); 2028 __netif_reschedule(q);
2029 } else {
2030 smp_mb__before_clear_bit();
2031 clear_bit(__QDISC_STATE_SCHED,
2032 &q->state);
2033 }
1996 } 2034 }
1997 } 2035 }
1998 } 2036 }
@@ -2911,6 +2949,12 @@ int netdev_set_master(struct net_device *slave, struct net_device *master)
2911 return 0; 2949 return 0;
2912} 2950}
2913 2951
2952static void dev_change_rx_flags(struct net_device *dev, int flags)
2953{
2954 if (dev->flags & IFF_UP && dev->change_rx_flags)
2955 dev->change_rx_flags(dev, flags);
2956}
2957
2914static int __dev_set_promiscuity(struct net_device *dev, int inc) 2958static int __dev_set_promiscuity(struct net_device *dev, int inc)
2915{ 2959{
2916 unsigned short old_flags = dev->flags; 2960 unsigned short old_flags = dev->flags;
@@ -2948,8 +2992,7 @@ static int __dev_set_promiscuity(struct net_device *dev, int inc)
2948 current->uid, current->gid, 2992 current->uid, current->gid,
2949 audit_get_sessionid(current)); 2993 audit_get_sessionid(current));
2950 2994
2951 if (dev->change_rx_flags) 2995 dev_change_rx_flags(dev, IFF_PROMISC);
2952 dev->change_rx_flags(dev, IFF_PROMISC);
2953 } 2996 }
2954 return 0; 2997 return 0;
2955} 2998}
@@ -3015,8 +3058,7 @@ int dev_set_allmulti(struct net_device *dev, int inc)
3015 } 3058 }
3016 } 3059 }
3017 if (dev->flags ^ old_flags) { 3060 if (dev->flags ^ old_flags) {
3018 if (dev->change_rx_flags) 3061 dev_change_rx_flags(dev, IFF_ALLMULTI);
3019 dev->change_rx_flags(dev, IFF_ALLMULTI);
3020 dev_set_rx_mode(dev); 3062 dev_set_rx_mode(dev);
3021 } 3063 }
3022 return 0; 3064 return 0;
@@ -3295,6 +3337,12 @@ static void dev_addr_discard(struct net_device *dev)
3295 netif_addr_unlock_bh(dev); 3337 netif_addr_unlock_bh(dev);
3296} 3338}
3297 3339
3340/**
3341 * dev_get_flags - get flags reported to userspace
3342 * @dev: device
3343 *
3344 * Get the combination of flag bits exported through APIs to userspace.
3345 */
3298unsigned dev_get_flags(const struct net_device *dev) 3346unsigned dev_get_flags(const struct net_device *dev)
3299{ 3347{
3300 unsigned flags; 3348 unsigned flags;
@@ -3319,6 +3367,14 @@ unsigned dev_get_flags(const struct net_device *dev)
3319 return flags; 3367 return flags;
3320} 3368}
3321 3369
3370/**
3371 * dev_change_flags - change device settings
3372 * @dev: device
3373 * @flags: device state flags
3374 *
3375 * Change settings on device based state flags. The flags are
3376 * in the userspace exported format.
3377 */
3322int dev_change_flags(struct net_device *dev, unsigned flags) 3378int dev_change_flags(struct net_device *dev, unsigned flags)
3323{ 3379{
3324 int ret, changes; 3380 int ret, changes;
@@ -3340,8 +3396,8 @@ int dev_change_flags(struct net_device *dev, unsigned flags)
3340 * Load in the correct multicast list now the flags have changed. 3396 * Load in the correct multicast list now the flags have changed.
3341 */ 3397 */
3342 3398
3343 if (dev->change_rx_flags && (old_flags ^ flags) & IFF_MULTICAST) 3399 if ((old_flags ^ flags) & IFF_MULTICAST)
3344 dev->change_rx_flags(dev, IFF_MULTICAST); 3400 dev_change_rx_flags(dev, IFF_MULTICAST);
3345 3401
3346 dev_set_rx_mode(dev); 3402 dev_set_rx_mode(dev);
3347 3403
@@ -3388,6 +3444,13 @@ int dev_change_flags(struct net_device *dev, unsigned flags)
3388 return ret; 3444 return ret;
3389} 3445}
3390 3446
3447/**
3448 * dev_set_mtu - Change maximum transfer unit
3449 * @dev: device
3450 * @new_mtu: new transfer unit
3451 *
3452 * Change the maximum transfer size of the network device.
3453 */
3391int dev_set_mtu(struct net_device *dev, int new_mtu) 3454int dev_set_mtu(struct net_device *dev, int new_mtu)
3392{ 3455{
3393 int err; 3456 int err;
@@ -3412,6 +3475,13 @@ int dev_set_mtu(struct net_device *dev, int new_mtu)
3412 return err; 3475 return err;
3413} 3476}
3414 3477
3478/**
3479 * dev_set_mac_address - Change Media Access Control Address
3480 * @dev: device
3481 * @sa: new address
3482 *
3483 * Change the hardware (MAC) address of the device
3484 */
3415int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa) 3485int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa)
3416{ 3486{
3417 int err; 3487 int err;
@@ -3801,14 +3871,11 @@ static int dev_new_index(struct net *net)
3801} 3871}
3802 3872
3803/* Delayed registration/unregisteration */ 3873/* Delayed registration/unregisteration */
3804static DEFINE_SPINLOCK(net_todo_list_lock);
3805static LIST_HEAD(net_todo_list); 3874static LIST_HEAD(net_todo_list);
3806 3875
3807static void net_set_todo(struct net_device *dev) 3876static void net_set_todo(struct net_device *dev)
3808{ 3877{
3809 spin_lock(&net_todo_list_lock);
3810 list_add_tail(&dev->todo_list, &net_todo_list); 3878 list_add_tail(&dev->todo_list, &net_todo_list);
3811 spin_unlock(&net_todo_list_lock);
3812} 3879}
3813 3880
3814static void rollback_registered(struct net_device *dev) 3881static void rollback_registered(struct net_device *dev)
@@ -4135,33 +4202,24 @@ static void netdev_wait_allrefs(struct net_device *dev)
4135 * free_netdev(y1); 4202 * free_netdev(y1);
4136 * free_netdev(y2); 4203 * free_netdev(y2);
4137 * 4204 *
4138 * We are invoked by rtnl_unlock() after it drops the semaphore. 4205 * We are invoked by rtnl_unlock().
4139 * This allows us to deal with problems: 4206 * This allows us to deal with problems:
4140 * 1) We can delete sysfs objects which invoke hotplug 4207 * 1) We can delete sysfs objects which invoke hotplug
4141 * without deadlocking with linkwatch via keventd. 4208 * without deadlocking with linkwatch via keventd.
4142 * 2) Since we run with the RTNL semaphore not held, we can sleep 4209 * 2) Since we run with the RTNL semaphore not held, we can sleep
4143 * safely in order to wait for the netdev refcnt to drop to zero. 4210 * safely in order to wait for the netdev refcnt to drop to zero.
4211 *
4212 * We must not return until all unregister events added during
4213 * the interval the lock was held have been completed.
4144 */ 4214 */
4145static DEFINE_MUTEX(net_todo_run_mutex);
4146void netdev_run_todo(void) 4215void netdev_run_todo(void)
4147{ 4216{
4148 struct list_head list; 4217 struct list_head list;
4149 4218
4150 /* Need to guard against multiple cpu's getting out of order. */
4151 mutex_lock(&net_todo_run_mutex);
4152
4153 /* Not safe to do outside the semaphore. We must not return
4154 * until all unregister events invoked by the local processor
4155 * have been completed (either by this todo run, or one on
4156 * another cpu).
4157 */
4158 if (list_empty(&net_todo_list))
4159 goto out;
4160
4161 /* Snapshot list, allow later requests */ 4219 /* Snapshot list, allow later requests */
4162 spin_lock(&net_todo_list_lock);
4163 list_replace_init(&net_todo_list, &list); 4220 list_replace_init(&net_todo_list, &list);
4164 spin_unlock(&net_todo_list_lock); 4221
4222 __rtnl_unlock();
4165 4223
4166 while (!list_empty(&list)) { 4224 while (!list_empty(&list)) {
4167 struct net_device *dev 4225 struct net_device *dev
@@ -4193,9 +4251,6 @@ void netdev_run_todo(void)
4193 /* Free network device */ 4251 /* Free network device */
4194 kobject_put(&dev->dev.kobj); 4252 kobject_put(&dev->dev.kobj);
4195 } 4253 }
4196
4197out:
4198 mutex_unlock(&net_todo_run_mutex);
4199} 4254}
4200 4255
4201static struct net_device_stats *internal_stats(struct net_device *dev) 4256static struct net_device_stats *internal_stats(struct net_device *dev)
@@ -4315,7 +4370,12 @@ void free_netdev(struct net_device *dev)
4315 put_device(&dev->dev); 4370 put_device(&dev->dev);
4316} 4371}
4317 4372
4318/* Synchronize with packet receive processing. */ 4373/**
4374 * synchronize_net - Synchronize with packet receive processing
4375 *
4376 * Wait for packets currently being received to be done.
4377 * Does not block later packets from starting.
4378 */
4319void synchronize_net(void) 4379void synchronize_net(void)
4320{ 4380{
4321 might_sleep(); 4381 might_sleep();
@@ -4617,7 +4677,7 @@ netdev_dma_event(struct dma_client *client, struct dma_chan *chan,
4617} 4677}
4618 4678
4619/** 4679/**
4620 * netdev_dma_regiser - register the networking subsystem as a DMA client 4680 * netdev_dma_register - register the networking subsystem as a DMA client
4621 */ 4681 */
4622static int __init netdev_dma_register(void) 4682static int __init netdev_dma_register(void)
4623{ 4683{
@@ -4663,6 +4723,12 @@ int netdev_compute_features(unsigned long all, unsigned long one)
4663 one |= NETIF_F_GSO_SOFTWARE; 4723 one |= NETIF_F_GSO_SOFTWARE;
4664 one |= NETIF_F_GSO; 4724 one |= NETIF_F_GSO;
4665 4725
4726 /*
4727 * If even one device supports a GSO protocol with software fallback,
4728 * enable it for all.
4729 */
4730 all |= one & NETIF_F_GSO_SOFTWARE;
4731
4666 /* If even one device supports robust GSO, enable it for all. */ 4732 /* If even one device supports robust GSO, enable it for all. */
4667 if (one & NETIF_F_GSO_ROBUST) 4733 if (one & NETIF_F_GSO_ROBUST)
4668 all |= NETIF_F_GSO_ROBUST; 4734 all |= NETIF_F_GSO_ROBUST;
@@ -4712,10 +4778,18 @@ err_name:
4712 return -ENOMEM; 4778 return -ENOMEM;
4713} 4779}
4714 4780
4715char *netdev_drivername(struct net_device *dev, char *buffer, int len) 4781/**
4782 * netdev_drivername - network driver for the device
4783 * @dev: network device
4784 * @buffer: buffer for resulting name
4785 * @len: size of buffer
4786 *
4787 * Determine network driver for device.
4788 */
4789char *netdev_drivername(const struct net_device *dev, char *buffer, int len)
4716{ 4790{
4717 struct device_driver *driver; 4791 const struct device_driver *driver;
4718 struct device *parent; 4792 const struct device *parent;
4719 4793
4720 if (len <= 0 || !buffer) 4794 if (len <= 0 || !buffer)
4721 return buffer; 4795 return buffer;
diff --git a/net/core/dst.c b/net/core/dst.c
index fe03266130b6..09c1530f4681 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -203,6 +203,7 @@ void __dst_free(struct dst_entry * dst)
203 if (dst_garbage.timer_inc > DST_GC_INC) { 203 if (dst_garbage.timer_inc > DST_GC_INC) {
204 dst_garbage.timer_inc = DST_GC_INC; 204 dst_garbage.timer_inc = DST_GC_INC;
205 dst_garbage.timer_expires = DST_GC_MIN; 205 dst_garbage.timer_expires = DST_GC_MIN;
206 cancel_delayed_work(&dst_gc_work);
206 schedule_delayed_work(&dst_gc_work, dst_garbage.timer_expires); 207 schedule_delayed_work(&dst_gc_work, dst_garbage.timer_expires);
207 } 208 }
208 spin_unlock_bh(&dst_garbage.lock); 209 spin_unlock_bh(&dst_garbage.lock);
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 9d92e41826e7..1dc728b38589 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -927,8 +927,7 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
927 if (skb_queue_len(&neigh->arp_queue) >= 927 if (skb_queue_len(&neigh->arp_queue) >=
928 neigh->parms->queue_len) { 928 neigh->parms->queue_len) {
929 struct sk_buff *buff; 929 struct sk_buff *buff;
930 buff = neigh->arp_queue.next; 930 buff = __skb_dequeue(&neigh->arp_queue);
931 __skb_unlink(buff, &neigh->arp_queue);
932 kfree_skb(buff); 931 kfree_skb(buff);
933 NEIGH_CACHE_STAT_INC(neigh->tbl, unres_discards); 932 NEIGH_CACHE_STAT_INC(neigh->tbl, unres_discards);
934 } 933 }
@@ -1259,24 +1258,20 @@ static void neigh_proxy_process(unsigned long arg)
1259 struct neigh_table *tbl = (struct neigh_table *)arg; 1258 struct neigh_table *tbl = (struct neigh_table *)arg;
1260 long sched_next = 0; 1259 long sched_next = 0;
1261 unsigned long now = jiffies; 1260 unsigned long now = jiffies;
1262 struct sk_buff *skb; 1261 struct sk_buff *skb, *n;
1263 1262
1264 spin_lock(&tbl->proxy_queue.lock); 1263 spin_lock(&tbl->proxy_queue.lock);
1265 1264
1266 skb = tbl->proxy_queue.next; 1265 skb_queue_walk_safe(&tbl->proxy_queue, skb, n) {
1267 1266 long tdif = NEIGH_CB(skb)->sched_next - now;
1268 while (skb != (struct sk_buff *)&tbl->proxy_queue) {
1269 struct sk_buff *back = skb;
1270 long tdif = NEIGH_CB(back)->sched_next - now;
1271 1267
1272 skb = skb->next;
1273 if (tdif <= 0) { 1268 if (tdif <= 0) {
1274 struct net_device *dev = back->dev; 1269 struct net_device *dev = skb->dev;
1275 __skb_unlink(back, &tbl->proxy_queue); 1270 __skb_unlink(skb, &tbl->proxy_queue);
1276 if (tbl->proxy_redo && netif_running(dev)) 1271 if (tbl->proxy_redo && netif_running(dev))
1277 tbl->proxy_redo(back); 1272 tbl->proxy_redo(skb);
1278 else 1273 else
1279 kfree_skb(back); 1274 kfree_skb(skb);
1280 1275
1281 dev_put(dev); 1276 dev_put(dev);
1282 } else if (!sched_next || tdif < sched_next) 1277 } else if (!sched_next || tdif < sched_next)
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index c1f4e0d428c0..92d6b9467314 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -209,9 +209,44 @@ static ssize_t store_tx_queue_len(struct device *dev,
209 return netdev_store(dev, attr, buf, len, change_tx_queue_len); 209 return netdev_store(dev, attr, buf, len, change_tx_queue_len);
210} 210}
211 211
212static ssize_t store_ifalias(struct device *dev, struct device_attribute *attr,
213 const char *buf, size_t len)
214{
215 struct net_device *netdev = to_net_dev(dev);
216 size_t count = len;
217 ssize_t ret;
218
219 if (!capable(CAP_NET_ADMIN))
220 return -EPERM;
221
222 /* ignore trailing newline */
223 if (len > 0 && buf[len - 1] == '\n')
224 --count;
225
226 rtnl_lock();
227 ret = dev_set_alias(netdev, buf, count);
228 rtnl_unlock();
229
230 return ret < 0 ? ret : len;
231}
232
233static ssize_t show_ifalias(struct device *dev,
234 struct device_attribute *attr, char *buf)
235{
236 const struct net_device *netdev = to_net_dev(dev);
237 ssize_t ret = 0;
238
239 rtnl_lock();
240 if (netdev->ifalias)
241 ret = sprintf(buf, "%s\n", netdev->ifalias);
242 rtnl_unlock();
243 return ret;
244}
245
212static struct device_attribute net_class_attributes[] = { 246static struct device_attribute net_class_attributes[] = {
213 __ATTR(addr_len, S_IRUGO, show_addr_len, NULL), 247 __ATTR(addr_len, S_IRUGO, show_addr_len, NULL),
214 __ATTR(dev_id, S_IRUGO, show_dev_id, NULL), 248 __ATTR(dev_id, S_IRUGO, show_dev_id, NULL),
249 __ATTR(ifalias, S_IRUGO | S_IWUSR, show_ifalias, store_ifalias),
215 __ATTR(iflink, S_IRUGO, show_iflink, NULL), 250 __ATTR(iflink, S_IRUGO, show_iflink, NULL),
216 __ATTR(ifindex, S_IRUGO, show_ifindex, NULL), 251 __ATTR(ifindex, S_IRUGO, show_ifindex, NULL),
217 __ATTR(features, S_IRUGO, show_features, NULL), 252 __ATTR(features, S_IRUGO, show_features, NULL),
@@ -418,6 +453,7 @@ static void netdev_release(struct device *d)
418 453
419 BUG_ON(dev->reg_state != NETREG_RELEASED); 454 BUG_ON(dev->reg_state != NETREG_RELEASED);
420 455
456 kfree(dev->ifalias);
421 kfree((char *)dev - dev->padded); 457 kfree((char *)dev - dev->padded);
422} 458}
423 459
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 7c52fe277b62..b0dc818a91d7 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -18,6 +18,7 @@ static struct list_head *first_device = &pernet_list;
18static DEFINE_MUTEX(net_mutex); 18static DEFINE_MUTEX(net_mutex);
19 19
20LIST_HEAD(net_namespace_list); 20LIST_HEAD(net_namespace_list);
21EXPORT_SYMBOL_GPL(net_namespace_list);
21 22
22struct net init_net; 23struct net init_net;
23EXPORT_SYMBOL(init_net); 24EXPORT_SYMBOL(init_net);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 71edb8b36341..3630131fa1fa 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -73,7 +73,7 @@ void __rtnl_unlock(void)
73 73
74void rtnl_unlock(void) 74void rtnl_unlock(void)
75{ 75{
76 mutex_unlock(&rtnl_mutex); 76 /* This fellow will unlock it for us. */
77 netdev_run_todo(); 77 netdev_run_todo();
78} 78}
79 79
@@ -586,6 +586,7 @@ static inline size_t if_nlmsg_size(const struct net_device *dev)
586{ 586{
587 return NLMSG_ALIGN(sizeof(struct ifinfomsg)) 587 return NLMSG_ALIGN(sizeof(struct ifinfomsg))
588 + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */ 588 + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
589 + nla_total_size(IFALIASZ) /* IFLA_IFALIAS */
589 + nla_total_size(IFNAMSIZ) /* IFLA_QDISC */ 590 + nla_total_size(IFNAMSIZ) /* IFLA_QDISC */
590 + nla_total_size(sizeof(struct rtnl_link_ifmap)) 591 + nla_total_size(sizeof(struct rtnl_link_ifmap))
591 + nla_total_size(sizeof(struct rtnl_link_stats)) 592 + nla_total_size(sizeof(struct rtnl_link_stats))
@@ -640,6 +641,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
640 if (txq->qdisc_sleeping) 641 if (txq->qdisc_sleeping)
641 NLA_PUT_STRING(skb, IFLA_QDISC, txq->qdisc_sleeping->ops->id); 642 NLA_PUT_STRING(skb, IFLA_QDISC, txq->qdisc_sleeping->ops->id);
642 643
644 if (dev->ifalias)
645 NLA_PUT_STRING(skb, IFLA_IFALIAS, dev->ifalias);
646
643 if (1) { 647 if (1) {
644 struct rtnl_link_ifmap map = { 648 struct rtnl_link_ifmap map = {
645 .mem_start = dev->mem_start, 649 .mem_start = dev->mem_start,
@@ -713,6 +717,7 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = {
713 [IFLA_LINKMODE] = { .type = NLA_U8 }, 717 [IFLA_LINKMODE] = { .type = NLA_U8 },
714 [IFLA_LINKINFO] = { .type = NLA_NESTED }, 718 [IFLA_LINKINFO] = { .type = NLA_NESTED },
715 [IFLA_NET_NS_PID] = { .type = NLA_U32 }, 719 [IFLA_NET_NS_PID] = { .type = NLA_U32 },
720 [IFLA_IFALIAS] = { .type = NLA_STRING, .len = IFALIASZ-1 },
716}; 721};
717 722
718static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = { 723static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
@@ -853,6 +858,14 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
853 modified = 1; 858 modified = 1;
854 } 859 }
855 860
861 if (tb[IFLA_IFALIAS]) {
862 err = dev_set_alias(dev, nla_data(tb[IFLA_IFALIAS]),
863 nla_len(tb[IFLA_IFALIAS]));
864 if (err < 0)
865 goto errout;
866 modified = 1;
867 }
868
856 if (tb[IFLA_BROADCAST]) { 869 if (tb[IFLA_BROADCAST]) {
857 nla_memcpy(dev->broadcast, tb[IFLA_BROADCAST], dev->addr_len); 870 nla_memcpy(dev->broadcast, tb[IFLA_BROADCAST], dev->addr_len);
858 send_addr_notify = 1; 871 send_addr_notify = 1;
diff --git a/net/core/skb_dma_map.c b/net/core/skb_dma_map.c
new file mode 100644
index 000000000000..1f49afcd8e86
--- /dev/null
+++ b/net/core/skb_dma_map.c
@@ -0,0 +1,66 @@
1/* skb_dma_map.c: DMA mapping helpers for socket buffers.
2 *
3 * Copyright (C) David S. Miller <davem@davemloft.net>
4 */
5
6#include <linux/kernel.h>
7#include <linux/module.h>
8#include <linux/dma-mapping.h>
9#include <linux/skbuff.h>
10
11int skb_dma_map(struct device *dev, struct sk_buff *skb,
12 enum dma_data_direction dir)
13{
14 struct skb_shared_info *sp = skb_shinfo(skb);
15 dma_addr_t map;
16 int i;
17
18 map = dma_map_single(dev, skb->data,
19 skb_headlen(skb), dir);
20 if (dma_mapping_error(dev, map))
21 goto out_err;
22
23 sp->dma_maps[0] = map;
24 for (i = 0; i < sp->nr_frags; i++) {
25 skb_frag_t *fp = &sp->frags[i];
26
27 map = dma_map_page(dev, fp->page, fp->page_offset,
28 fp->size, dir);
29 if (dma_mapping_error(dev, map))
30 goto unwind;
31 sp->dma_maps[i + 1] = map;
32 }
33 sp->num_dma_maps = i + 1;
34
35 return 0;
36
37unwind:
38 while (i-- >= 0) {
39 skb_frag_t *fp = &sp->frags[i];
40
41 dma_unmap_page(dev, sp->dma_maps[i + 1],
42 fp->size, dir);
43 }
44 dma_unmap_single(dev, sp->dma_maps[0],
45 skb_headlen(skb), dir);
46out_err:
47 return -ENOMEM;
48}
49EXPORT_SYMBOL(skb_dma_map);
50
51void skb_dma_unmap(struct device *dev, struct sk_buff *skb,
52 enum dma_data_direction dir)
53{
54 struct skb_shared_info *sp = skb_shinfo(skb);
55 int i;
56
57 dma_unmap_single(dev, sp->dma_maps[0],
58 skb_headlen(skb), dir);
59 for (i = 0; i < sp->nr_frags; i++) {
60 skb_frag_t *fp = &sp->frags[i];
61
62 dma_unmap_page(dev, sp->dma_maps[i + 1],
63 fp->size, dir);
64 }
65}
66EXPORT_SYMBOL(skb_dma_unmap);
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index ca1ccdf1ef76..7f7bb1a636d9 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -263,6 +263,26 @@ struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
263 return skb; 263 return skb;
264} 264}
265 265
266struct page *__netdev_alloc_page(struct net_device *dev, gfp_t gfp_mask)
267{
268 int node = dev->dev.parent ? dev_to_node(dev->dev.parent) : -1;
269 struct page *page;
270
271 page = alloc_pages_node(node, gfp_mask, 0);
272 return page;
273}
274EXPORT_SYMBOL(__netdev_alloc_page);
275
276void skb_add_rx_frag(struct sk_buff *skb, int i, struct page *page, int off,
277 int size)
278{
279 skb_fill_page_desc(skb, i, page, off, size);
280 skb->len += size;
281 skb->data_len += size;
282 skb->truesize += size;
283}
284EXPORT_SYMBOL(skb_add_rx_frag);
285
266/** 286/**
267 * dev_alloc_skb - allocate an skbuff for receiving 287 * dev_alloc_skb - allocate an skbuff for receiving
268 * @length: length to allocate 288 * @length: length to allocate
@@ -363,8 +383,7 @@ static void kfree_skbmem(struct sk_buff *skb)
363 } 383 }
364} 384}
365 385
366/* Free everything but the sk_buff shell. */ 386static void skb_release_head_state(struct sk_buff *skb)
367static void skb_release_all(struct sk_buff *skb)
368{ 387{
369 dst_release(skb->dst); 388 dst_release(skb->dst);
370#ifdef CONFIG_XFRM 389#ifdef CONFIG_XFRM
@@ -388,6 +407,12 @@ static void skb_release_all(struct sk_buff *skb)
388 skb->tc_verd = 0; 407 skb->tc_verd = 0;
389#endif 408#endif
390#endif 409#endif
410}
411
412/* Free everything but the sk_buff shell. */
413static void skb_release_all(struct sk_buff *skb)
414{
415 skb_release_head_state(skb);
391 skb_release_data(skb); 416 skb_release_data(skb);
392} 417}
393 418
@@ -424,6 +449,38 @@ void kfree_skb(struct sk_buff *skb)
424 __kfree_skb(skb); 449 __kfree_skb(skb);
425} 450}
426 451
452int skb_recycle_check(struct sk_buff *skb, int skb_size)
453{
454 struct skb_shared_info *shinfo;
455
456 if (skb_is_nonlinear(skb) || skb->fclone != SKB_FCLONE_UNAVAILABLE)
457 return 0;
458
459 skb_size = SKB_DATA_ALIGN(skb_size + NET_SKB_PAD);
460 if (skb_end_pointer(skb) - skb->head < skb_size)
461 return 0;
462
463 if (skb_shared(skb) || skb_cloned(skb))
464 return 0;
465
466 skb_release_head_state(skb);
467 shinfo = skb_shinfo(skb);
468 atomic_set(&shinfo->dataref, 1);
469 shinfo->nr_frags = 0;
470 shinfo->gso_size = 0;
471 shinfo->gso_segs = 0;
472 shinfo->gso_type = 0;
473 shinfo->ip6_frag_id = 0;
474 shinfo->frag_list = NULL;
475
476 memset(skb, 0, offsetof(struct sk_buff, tail));
477 skb_reset_tail_pointer(skb);
478 skb->data = skb->head + NET_SKB_PAD;
479
480 return 1;
481}
482EXPORT_SYMBOL(skb_recycle_check);
483
427static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old) 484static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
428{ 485{
429 new->tstamp = old->tstamp; 486 new->tstamp = old->tstamp;
@@ -701,6 +758,8 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
701#endif 758#endif
702 long off; 759 long off;
703 760
761 BUG_ON(nhead < 0);
762
704 if (skb_shared(skb)) 763 if (skb_shared(skb))
705 BUG(); 764 BUG();
706 765
diff --git a/net/core/sock.c b/net/core/sock.c
index 91f8bbc93526..5e2a3132a8c9 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -154,7 +154,8 @@ static const char *af_family_key_strings[AF_MAX+1] = {
154 "sk_lock-AF_PPPOX" , "sk_lock-AF_WANPIPE" , "sk_lock-AF_LLC" , 154 "sk_lock-AF_PPPOX" , "sk_lock-AF_WANPIPE" , "sk_lock-AF_LLC" ,
155 "sk_lock-27" , "sk_lock-28" , "sk_lock-AF_CAN" , 155 "sk_lock-27" , "sk_lock-28" , "sk_lock-AF_CAN" ,
156 "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" , 156 "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" ,
157 "sk_lock-AF_RXRPC" , "sk_lock-AF_MAX" 157 "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" ,
158 "sk_lock-AF_MAX"
158}; 159};
159static const char *af_family_slock_key_strings[AF_MAX+1] = { 160static const char *af_family_slock_key_strings[AF_MAX+1] = {
160 "slock-AF_UNSPEC", "slock-AF_UNIX" , "slock-AF_INET" , 161 "slock-AF_UNSPEC", "slock-AF_UNIX" , "slock-AF_INET" ,
@@ -168,7 +169,8 @@ static const char *af_family_slock_key_strings[AF_MAX+1] = {
168 "slock-AF_PPPOX" , "slock-AF_WANPIPE" , "slock-AF_LLC" , 169 "slock-AF_PPPOX" , "slock-AF_WANPIPE" , "slock-AF_LLC" ,
169 "slock-27" , "slock-28" , "slock-AF_CAN" , 170 "slock-27" , "slock-28" , "slock-AF_CAN" ,
170 "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" , 171 "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" ,
171 "slock-AF_RXRPC" , "slock-AF_MAX" 172 "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" ,
173 "slock-AF_MAX"
172}; 174};
173static const char *af_family_clock_key_strings[AF_MAX+1] = { 175static const char *af_family_clock_key_strings[AF_MAX+1] = {
174 "clock-AF_UNSPEC", "clock-AF_UNIX" , "clock-AF_INET" , 176 "clock-AF_UNSPEC", "clock-AF_UNIX" , "clock-AF_INET" ,
@@ -182,7 +184,8 @@ static const char *af_family_clock_key_strings[AF_MAX+1] = {
182 "clock-AF_PPPOX" , "clock-AF_WANPIPE" , "clock-AF_LLC" , 184 "clock-AF_PPPOX" , "clock-AF_WANPIPE" , "clock-AF_LLC" ,
183 "clock-27" , "clock-28" , "clock-AF_CAN" , 185 "clock-27" , "clock-28" , "clock-AF_CAN" ,
184 "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , 186 "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" ,
185 "clock-AF_RXRPC" , "clock-AF_MAX" 187 "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" ,
188 "clock-AF_MAX"
186}; 189};
187#endif 190#endif
188 191
@@ -324,7 +327,7 @@ int sk_receive_skb(struct sock *sk, struct sk_buff *skb, const int nested)
324 */ 327 */
325 mutex_acquire(&sk->sk_lock.dep_map, 0, 1, _RET_IP_); 328 mutex_acquire(&sk->sk_lock.dep_map, 0, 1, _RET_IP_);
326 329
327 rc = sk->sk_backlog_rcv(sk, skb); 330 rc = sk_backlog_rcv(sk, skb);
328 331
329 mutex_release(&sk->sk_lock.dep_map, 1, _RET_IP_); 332 mutex_release(&sk->sk_lock.dep_map, 1, _RET_IP_);
330 } else 333 } else
@@ -1371,7 +1374,7 @@ static void __release_sock(struct sock *sk)
1371 struct sk_buff *next = skb->next; 1374 struct sk_buff *next = skb->next;
1372 1375
1373 skb->next = NULL; 1376 skb->next = NULL;
1374 sk->sk_backlog_rcv(sk, skb); 1377 sk_backlog_rcv(sk, skb);
1375 1378
1376 /* 1379 /*
1377 * We are in process context here with softirqs 1380 * We are in process context here with softirqs
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c
index 8e9580874216..9a430734530c 100644
--- a/net/dccp/ccids/ccid2.c
+++ b/net/dccp/ccids/ccid2.c
@@ -783,7 +783,7 @@ static struct ccid_operations ccid2 = {
783}; 783};
784 784
785#ifdef CONFIG_IP_DCCP_CCID2_DEBUG 785#ifdef CONFIG_IP_DCCP_CCID2_DEBUG
786module_param(ccid2_debug, bool, 0444); 786module_param(ccid2_debug, bool, 0644);
787MODULE_PARM_DESC(ccid2_debug, "Enable debug messages"); 787MODULE_PARM_DESC(ccid2_debug, "Enable debug messages");
788#endif 788#endif
789 789
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index f6756e0c9e69..3b8bd7ca6761 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -963,7 +963,7 @@ static struct ccid_operations ccid3 = {
963}; 963};
964 964
965#ifdef CONFIG_IP_DCCP_CCID3_DEBUG 965#ifdef CONFIG_IP_DCCP_CCID3_DEBUG
966module_param(ccid3_debug, bool, 0444); 966module_param(ccid3_debug, bool, 0644);
967MODULE_PARM_DESC(ccid3_debug, "Enable debug messages"); 967MODULE_PARM_DESC(ccid3_debug, "Enable debug messages");
968#endif 968#endif
969 969
diff --git a/net/dccp/ccids/lib/loss_interval.c b/net/dccp/ccids/lib/loss_interval.c
index bcd6ac415bb9..5b3ce0688c5c 100644
--- a/net/dccp/ccids/lib/loss_interval.c
+++ b/net/dccp/ccids/lib/loss_interval.c
@@ -67,7 +67,10 @@ static void tfrc_lh_calc_i_mean(struct tfrc_loss_hist *lh)
67 u32 i_i, i_tot0 = 0, i_tot1 = 0, w_tot = 0; 67 u32 i_i, i_tot0 = 0, i_tot1 = 0, w_tot = 0;
68 int i, k = tfrc_lh_length(lh) - 1; /* k is as in rfc3448bis, 5.4 */ 68 int i, k = tfrc_lh_length(lh) - 1; /* k is as in rfc3448bis, 5.4 */
69 69
70 for (i=0; i <= k; i++) { 70 if (k <= 0)
71 return;
72
73 for (i = 0; i <= k; i++) {
71 i_i = tfrc_lh_get_interval(lh, i); 74 i_i = tfrc_lh_get_interval(lh, i);
72 75
73 if (i < k) { 76 if (i < k) {
@@ -78,7 +81,6 @@ static void tfrc_lh_calc_i_mean(struct tfrc_loss_hist *lh)
78 i_tot1 += i_i * tfrc_lh_weights[i-1]; 81 i_tot1 += i_i * tfrc_lh_weights[i-1];
79 } 82 }
80 83
81 BUG_ON(w_tot == 0);
82 lh->i_mean = max(i_tot0, i_tot1) / w_tot; 84 lh->i_mean = max(i_tot0, i_tot1) / w_tot;
83} 85}
84 86
diff --git a/net/dccp/ccids/lib/tfrc.c b/net/dccp/ccids/lib/tfrc.c
index 97ecec0a8e76..185916218e07 100644
--- a/net/dccp/ccids/lib/tfrc.c
+++ b/net/dccp/ccids/lib/tfrc.c
@@ -10,7 +10,7 @@
10 10
11#ifdef CONFIG_IP_DCCP_TFRC_DEBUG 11#ifdef CONFIG_IP_DCCP_TFRC_DEBUG
12int tfrc_debug; 12int tfrc_debug;
13module_param(tfrc_debug, bool, 0444); 13module_param(tfrc_debug, bool, 0644);
14MODULE_PARM_DESC(tfrc_debug, "Enable debug messages"); 14MODULE_PARM_DESC(tfrc_debug, "Enable debug messages");
15#endif 15#endif
16 16
diff --git a/net/dccp/input.c b/net/dccp/input.c
index 803933ab396d..779d0ed9ae94 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -370,7 +370,7 @@ int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
370 goto discard; 370 goto discard;
371 371
372 if (dccp_parse_options(sk, NULL, skb)) 372 if (dccp_parse_options(sk, NULL, skb))
373 goto discard; 373 return 1;
374 374
375 if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) 375 if (DCCP_SKB_CB(skb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
376 dccp_event_ack_recv(sk, skb); 376 dccp_event_ack_recv(sk, skb);
@@ -610,7 +610,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
610 * Step 8: Process options and mark acknowledgeable 610 * Step 8: Process options and mark acknowledgeable
611 */ 611 */
612 if (dccp_parse_options(sk, NULL, skb)) 612 if (dccp_parse_options(sk, NULL, skb))
613 goto discard; 613 return 1;
614 614
615 if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) 615 if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
616 dccp_event_ack_recv(sk, skb); 616 dccp_event_ack_recv(sk, skb);
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index 882c5c4de69e..e3dfddab21cc 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -811,9 +811,8 @@ static int dccp_v4_rcv(struct sk_buff *skb)
811 811
812 /* Step 2: 812 /* Step 2:
813 * Look up flow ID in table and get corresponding socket */ 813 * Look up flow ID in table and get corresponding socket */
814 sk = __inet_lookup(dev_net(skb->dst->dev), &dccp_hashinfo, 814 sk = __inet_lookup_skb(&dccp_hashinfo, skb,
815 iph->saddr, dh->dccph_sport, 815 dh->dccph_sport, dh->dccph_dport);
816 iph->daddr, dh->dccph_dport, inet_iif(skb));
817 /* 816 /*
818 * Step 2: 817 * Step 2:
819 * If no socket ... 818 * If no socket ...
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 5e1ee0da2c40..11062780bb02 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -98,7 +98,8 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
98 98
99 if (skb->len < offset + sizeof(*dh) || 99 if (skb->len < offset + sizeof(*dh) ||
100 skb->len < offset + __dccp_basic_hdr_len(dh)) { 100 skb->len < offset + __dccp_basic_hdr_len(dh)) {
101 ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS); 101 ICMP6_INC_STATS_BH(net, __in6_dev_get(skb->dev),
102 ICMP6_MIB_INERRORS);
102 return; 103 return;
103 } 104 }
104 105
@@ -107,7 +108,8 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
107 &hdr->saddr, dh->dccph_sport, inet6_iif(skb)); 108 &hdr->saddr, dh->dccph_sport, inet6_iif(skb));
108 109
109 if (sk == NULL) { 110 if (sk == NULL) {
110 ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS); 111 ICMP6_INC_STATS_BH(net, __in6_dev_get(skb->dev),
112 ICMP6_MIB_INERRORS);
111 return; 113 return;
112 } 114 }
113 115
@@ -805,10 +807,8 @@ static int dccp_v6_rcv(struct sk_buff *skb)
805 807
806 /* Step 2: 808 /* Step 2:
807 * Look up flow ID in table and get corresponding socket */ 809 * Look up flow ID in table and get corresponding socket */
808 sk = __inet6_lookup(dev_net(skb->dst->dev), &dccp_hashinfo, 810 sk = __inet6_lookup_skb(&dccp_hashinfo, skb,
809 &ipv6_hdr(skb)->saddr, dh->dccph_sport, 811 dh->dccph_sport, dh->dccph_dport);
810 &ipv6_hdr(skb)->daddr, ntohs(dh->dccph_dport),
811 inet6_iif(skb));
812 /* 812 /*
813 * Step 2: 813 * Step 2:
814 * If no socket ... 814 * If no socket ...
diff --git a/net/dccp/options.c b/net/dccp/options.c
index dc7c158a2f4b..0809b63cb055 100644
--- a/net/dccp/options.c
+++ b/net/dccp/options.c
@@ -81,11 +81,11 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
81 /* Check if this isn't a single byte option */ 81 /* Check if this isn't a single byte option */
82 if (opt > DCCPO_MAX_RESERVED) { 82 if (opt > DCCPO_MAX_RESERVED) {
83 if (opt_ptr == opt_end) 83 if (opt_ptr == opt_end)
84 goto out_invalid_option; 84 goto out_nonsensical_length;
85 85
86 len = *opt_ptr++; 86 len = *opt_ptr++;
87 if (len < 3) 87 if (len < 2)
88 goto out_invalid_option; 88 goto out_nonsensical_length;
89 /* 89 /*
90 * Remove the type and len fields, leaving 90 * Remove the type and len fields, leaving
91 * just the value size 91 * just the value size
@@ -95,7 +95,7 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
95 opt_ptr += len; 95 opt_ptr += len;
96 96
97 if (opt_ptr > opt_end) 97 if (opt_ptr > opt_end)
98 goto out_invalid_option; 98 goto out_nonsensical_length;
99 } 99 }
100 100
101 /* 101 /*
@@ -283,12 +283,17 @@ ignore_option:
283 if (mandatory) 283 if (mandatory)
284 goto out_invalid_option; 284 goto out_invalid_option;
285 285
286out_nonsensical_length:
287 /* RFC 4340, 5.8: ignore option and all remaining option space */
286 return 0; 288 return 0;
287 289
288out_invalid_option: 290out_invalid_option:
289 DCCP_INC_STATS_BH(DCCP_MIB_INVALIDOPT); 291 DCCP_INC_STATS_BH(DCCP_MIB_INVALIDOPT);
290 DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_OPTION_ERROR; 292 DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_OPTION_ERROR;
291 DCCP_WARN("DCCP(%p): invalid option %d, len=%d", sk, opt, len); 293 DCCP_WARN("DCCP(%p): invalid option %d, len=%d", sk, opt, len);
294 DCCP_SKB_CB(skb)->dccpd_reset_data[0] = opt;
295 DCCP_SKB_CB(skb)->dccpd_reset_data[1] = len > 0 ? value[0] : 0;
296 DCCP_SKB_CB(skb)->dccpd_reset_data[2] = len > 1 ? value[1] : 0;
292 return -1; 297 return -1;
293} 298}
294 299
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index 1ca3b26eed0f..d0bd34819761 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -309,7 +309,9 @@ int dccp_disconnect(struct sock *sk, int flags)
309 sk->sk_err = ECONNRESET; 309 sk->sk_err = ECONNRESET;
310 310
311 dccp_clear_xmit_timers(sk); 311 dccp_clear_xmit_timers(sk);
312
312 __skb_queue_purge(&sk->sk_receive_queue); 313 __skb_queue_purge(&sk->sk_receive_queue);
314 __skb_queue_purge(&sk->sk_write_queue);
313 if (sk->sk_send_head != NULL) { 315 if (sk->sk_send_head != NULL) {
314 __kfree_skb(sk->sk_send_head); 316 __kfree_skb(sk->sk_send_head);
315 sk->sk_send_head = NULL; 317 sk->sk_send_head = NULL;
@@ -1028,7 +1030,7 @@ MODULE_PARM_DESC(thash_entries, "Number of ehash buckets");
1028 1030
1029#ifdef CONFIG_IP_DCCP_DEBUG 1031#ifdef CONFIG_IP_DCCP_DEBUG
1030int dccp_debug; 1032int dccp_debug;
1031module_param(dccp_debug, bool, 0444); 1033module_param(dccp_debug, bool, 0644);
1032MODULE_PARM_DESC(dccp_debug, "Enable debug messages"); 1034MODULE_PARM_DESC(dccp_debug, "Enable debug messages");
1033 1035
1034EXPORT_SYMBOL_GPL(dccp_debug); 1036EXPORT_SYMBOL_GPL(dccp_debug);
diff --git a/net/dsa/Kconfig b/net/dsa/Kconfig
new file mode 100644
index 000000000000..cdce4c6c672a
--- /dev/null
+++ b/net/dsa/Kconfig
@@ -0,0 +1,60 @@
1menuconfig NET_DSA
2 bool "Distributed Switch Architecture support"
3 default n
4 depends on EXPERIMENTAL
5 select PHYLIB
6 ---help---
7 This allows you to use hardware switch chips that use
8 the Distributed Switch Architecture.
9
10
11if NET_DSA
12
13# tagging formats
14config NET_DSA_TAG_DSA
15 bool
16 default n
17
18config NET_DSA_TAG_EDSA
19 bool
20 default n
21
22config NET_DSA_TAG_TRAILER
23 bool
24 default n
25
26
27# switch drivers
28config NET_DSA_MV88E6XXX
29 bool
30 default n
31
32config NET_DSA_MV88E6060
33 bool "Marvell 88E6060 ethernet switch chip support"
34 select NET_DSA_TAG_TRAILER
35 ---help---
36 This enables support for the Marvell 88E6060 ethernet switch
37 chip.
38
39config NET_DSA_MV88E6XXX_NEED_PPU
40 bool
41 default n
42
43config NET_DSA_MV88E6131
44 bool "Marvell 88E6131 ethernet switch chip support"
45 select NET_DSA_MV88E6XXX
46 select NET_DSA_MV88E6XXX_NEED_PPU
47 select NET_DSA_TAG_DSA
48 ---help---
49 This enables support for the Marvell 88E6131 ethernet switch
50 chip.
51
52config NET_DSA_MV88E6123_61_65
53 bool "Marvell 88E6123/6161/6165 ethernet switch chip support"
54 select NET_DSA_MV88E6XXX
55 select NET_DSA_TAG_EDSA
56 ---help---
57 This enables support for the Marvell 88E6123/6161/6165
58 ethernet switch chips.
59
60endif
diff --git a/net/dsa/Makefile b/net/dsa/Makefile
new file mode 100644
index 000000000000..2374faff4dea
--- /dev/null
+++ b/net/dsa/Makefile
@@ -0,0 +1,13 @@
1# tagging formats
2obj-$(CONFIG_NET_DSA_TAG_DSA) += tag_dsa.o
3obj-$(CONFIG_NET_DSA_TAG_EDSA) += tag_edsa.o
4obj-$(CONFIG_NET_DSA_TAG_TRAILER) += tag_trailer.o
5
6# switch drivers
7obj-$(CONFIG_NET_DSA_MV88E6XXX) += mv88e6xxx.o
8obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
9obj-$(CONFIG_NET_DSA_MV88E6123_61_65) += mv88e6123_61_65.o
10obj-$(CONFIG_NET_DSA_MV88E6131) += mv88e6131.o
11
12# the core
13obj-$(CONFIG_NET_DSA) += dsa.o slave.o
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c
new file mode 100644
index 000000000000..33e99462023a
--- /dev/null
+++ b/net/dsa/dsa.c
@@ -0,0 +1,392 @@
1/*
2 * net/dsa/dsa.c - Hardware switch handling
3 * Copyright (c) 2008 Marvell Semiconductor
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 */
10
11#include <linux/list.h>
12#include <linux/netdevice.h>
13#include <linux/platform_device.h>
14#include <net/dsa.h>
15#include "dsa_priv.h"
16
17char dsa_driver_version[] = "0.1";
18
19
20/* switch driver registration ***********************************************/
21static DEFINE_MUTEX(dsa_switch_drivers_mutex);
22static LIST_HEAD(dsa_switch_drivers);
23
24void register_switch_driver(struct dsa_switch_driver *drv)
25{
26 mutex_lock(&dsa_switch_drivers_mutex);
27 list_add_tail(&drv->list, &dsa_switch_drivers);
28 mutex_unlock(&dsa_switch_drivers_mutex);
29}
30
31void unregister_switch_driver(struct dsa_switch_driver *drv)
32{
33 mutex_lock(&dsa_switch_drivers_mutex);
34 list_del_init(&drv->list);
35 mutex_unlock(&dsa_switch_drivers_mutex);
36}
37
38static struct dsa_switch_driver *
39dsa_switch_probe(struct mii_bus *bus, int sw_addr, char **_name)
40{
41 struct dsa_switch_driver *ret;
42 struct list_head *list;
43 char *name;
44
45 ret = NULL;
46 name = NULL;
47
48 mutex_lock(&dsa_switch_drivers_mutex);
49 list_for_each(list, &dsa_switch_drivers) {
50 struct dsa_switch_driver *drv;
51
52 drv = list_entry(list, struct dsa_switch_driver, list);
53
54 name = drv->probe(bus, sw_addr);
55 if (name != NULL) {
56 ret = drv;
57 break;
58 }
59 }
60 mutex_unlock(&dsa_switch_drivers_mutex);
61
62 *_name = name;
63
64 return ret;
65}
66
67
68/* basic switch operations **************************************************/
69static struct dsa_switch *
70dsa_switch_setup(struct device *parent, struct dsa_platform_data *pd,
71 struct mii_bus *bus, struct net_device *dev)
72{
73 struct dsa_switch *ds;
74 int ret;
75 struct dsa_switch_driver *drv;
76 char *name;
77 int i;
78
79 /*
80 * Probe for switch model.
81 */
82 drv = dsa_switch_probe(bus, pd->sw_addr, &name);
83 if (drv == NULL) {
84 printk(KERN_ERR "%s: could not detect attached switch\n",
85 dev->name);
86 return ERR_PTR(-EINVAL);
87 }
88 printk(KERN_INFO "%s: detected a %s switch\n", dev->name, name);
89
90
91 /*
92 * Allocate and initialise switch state.
93 */
94 ds = kzalloc(sizeof(*ds) + drv->priv_size, GFP_KERNEL);
95 if (ds == NULL)
96 return ERR_PTR(-ENOMEM);
97
98 ds->pd = pd;
99 ds->master_netdev = dev;
100 ds->master_mii_bus = bus;
101
102 ds->drv = drv;
103 ds->tag_protocol = drv->tag_protocol;
104
105
106 /*
107 * Validate supplied switch configuration.
108 */
109 ds->cpu_port = -1;
110 for (i = 0; i < DSA_MAX_PORTS; i++) {
111 char *name;
112
113 name = pd->port_names[i];
114 if (name == NULL)
115 continue;
116
117 if (!strcmp(name, "cpu")) {
118 if (ds->cpu_port != -1) {
119 printk(KERN_ERR "multiple cpu ports?!\n");
120 ret = -EINVAL;
121 goto out;
122 }
123 ds->cpu_port = i;
124 } else {
125 ds->valid_port_mask |= 1 << i;
126 }
127 }
128
129 if (ds->cpu_port == -1) {
130 printk(KERN_ERR "no cpu port?!\n");
131 ret = -EINVAL;
132 goto out;
133 }
134
135
136 /*
137 * If we use a tagging format that doesn't have an ethertype
138 * field, make sure that all packets from this point on get
139 * sent to the tag format's receive function. (Which will
140 * discard received packets until we set ds->ports[] below.)
141 */
142 wmb();
143 dev->dsa_ptr = (void *)ds;
144
145
146 /*
147 * Do basic register setup.
148 */
149 ret = drv->setup(ds);
150 if (ret < 0)
151 goto out;
152
153 ret = drv->set_addr(ds, dev->dev_addr);
154 if (ret < 0)
155 goto out;
156
157 ds->slave_mii_bus = mdiobus_alloc();
158 if (ds->slave_mii_bus == NULL) {
159 ret = -ENOMEM;
160 goto out;
161 }
162 dsa_slave_mii_bus_init(ds);
163
164 ret = mdiobus_register(ds->slave_mii_bus);
165 if (ret < 0)
166 goto out_free;
167
168
169 /*
170 * Create network devices for physical switch ports.
171 */
172 wmb();
173 for (i = 0; i < DSA_MAX_PORTS; i++) {
174 struct net_device *slave_dev;
175
176 if (!(ds->valid_port_mask & (1 << i)))
177 continue;
178
179 slave_dev = dsa_slave_create(ds, parent, i, pd->port_names[i]);
180 if (slave_dev == NULL) {
181 printk(KERN_ERR "%s: can't create dsa slave "
182 "device for port %d(%s)\n",
183 dev->name, i, pd->port_names[i]);
184 continue;
185 }
186
187 ds->ports[i] = slave_dev;
188 }
189
190 return ds;
191
192out_free:
193 mdiobus_free(ds->slave_mii_bus);
194out:
195 dev->dsa_ptr = NULL;
196 kfree(ds);
197 return ERR_PTR(ret);
198}
199
200static void dsa_switch_destroy(struct dsa_switch *ds)
201{
202}
203
204
205/* hooks for ethertype-less tagging formats *********************************/
206/*
207 * The original DSA tag format and some other tag formats have no
208 * ethertype, which means that we need to add a little hack to the
209 * networking receive path to make sure that received frames get
210 * the right ->protocol assigned to them when one of those tag
211 * formats is in use.
212 */
213bool dsa_uses_dsa_tags(void *dsa_ptr)
214{
215 struct dsa_switch *ds = dsa_ptr;
216
217 return !!(ds->tag_protocol == htons(ETH_P_DSA));
218}
219
220bool dsa_uses_trailer_tags(void *dsa_ptr)
221{
222 struct dsa_switch *ds = dsa_ptr;
223
224 return !!(ds->tag_protocol == htons(ETH_P_TRAILER));
225}
226
227
228/* link polling *************************************************************/
229static void dsa_link_poll_work(struct work_struct *ugly)
230{
231 struct dsa_switch *ds;
232
233 ds = container_of(ugly, struct dsa_switch, link_poll_work);
234
235 ds->drv->poll_link(ds);
236 mod_timer(&ds->link_poll_timer, round_jiffies(jiffies + HZ));
237}
238
239static void dsa_link_poll_timer(unsigned long _ds)
240{
241 struct dsa_switch *ds = (void *)_ds;
242
243 schedule_work(&ds->link_poll_work);
244}
245
246
247/* platform driver init and cleanup *****************************************/
248static int dev_is_class(struct device *dev, void *class)
249{
250 if (dev->class != NULL && !strcmp(dev->class->name, class))
251 return 1;
252
253 return 0;
254}
255
256static struct device *dev_find_class(struct device *parent, char *class)
257{
258 if (dev_is_class(parent, class)) {
259 get_device(parent);
260 return parent;
261 }
262
263 return device_find_child(parent, class, dev_is_class);
264}
265
266static struct mii_bus *dev_to_mii_bus(struct device *dev)
267{
268 struct device *d;
269
270 d = dev_find_class(dev, "mdio_bus");
271 if (d != NULL) {
272 struct mii_bus *bus;
273
274 bus = to_mii_bus(d);
275 put_device(d);
276
277 return bus;
278 }
279
280 return NULL;
281}
282
283static struct net_device *dev_to_net_device(struct device *dev)
284{
285 struct device *d;
286
287 d = dev_find_class(dev, "net");
288 if (d != NULL) {
289 struct net_device *nd;
290
291 nd = to_net_dev(d);
292 dev_hold(nd);
293 put_device(d);
294
295 return nd;
296 }
297
298 return NULL;
299}
300
301static int dsa_probe(struct platform_device *pdev)
302{
303 static int dsa_version_printed;
304 struct dsa_platform_data *pd = pdev->dev.platform_data;
305 struct net_device *dev;
306 struct mii_bus *bus;
307 struct dsa_switch *ds;
308
309 if (!dsa_version_printed++)
310 printk(KERN_NOTICE "Distributed Switch Architecture "
311 "driver version %s\n", dsa_driver_version);
312
313 if (pd == NULL || pd->mii_bus == NULL || pd->netdev == NULL)
314 return -EINVAL;
315
316 bus = dev_to_mii_bus(pd->mii_bus);
317 if (bus == NULL)
318 return -EINVAL;
319
320 dev = dev_to_net_device(pd->netdev);
321 if (dev == NULL)
322 return -EINVAL;
323
324 if (dev->dsa_ptr != NULL) {
325 dev_put(dev);
326 return -EEXIST;
327 }
328
329 ds = dsa_switch_setup(&pdev->dev, pd, bus, dev);
330 if (IS_ERR(ds)) {
331 dev_put(dev);
332 return PTR_ERR(ds);
333 }
334
335 if (ds->drv->poll_link != NULL) {
336 INIT_WORK(&ds->link_poll_work, dsa_link_poll_work);
337 init_timer(&ds->link_poll_timer);
338 ds->link_poll_timer.data = (unsigned long)ds;
339 ds->link_poll_timer.function = dsa_link_poll_timer;
340 ds->link_poll_timer.expires = round_jiffies(jiffies + HZ);
341 add_timer(&ds->link_poll_timer);
342 }
343
344 platform_set_drvdata(pdev, ds);
345
346 return 0;
347}
348
349static int dsa_remove(struct platform_device *pdev)
350{
351 struct dsa_switch *ds = platform_get_drvdata(pdev);
352
353 if (ds->drv->poll_link != NULL)
354 del_timer_sync(&ds->link_poll_timer);
355
356 flush_scheduled_work();
357
358 dsa_switch_destroy(ds);
359
360 return 0;
361}
362
363static void dsa_shutdown(struct platform_device *pdev)
364{
365}
366
367static struct platform_driver dsa_driver = {
368 .probe = dsa_probe,
369 .remove = dsa_remove,
370 .shutdown = dsa_shutdown,
371 .driver = {
372 .name = "dsa",
373 .owner = THIS_MODULE,
374 },
375};
376
377static int __init dsa_init_module(void)
378{
379 return platform_driver_register(&dsa_driver);
380}
381module_init(dsa_init_module);
382
383static void __exit dsa_cleanup_module(void)
384{
385 platform_driver_unregister(&dsa_driver);
386}
387module_exit(dsa_cleanup_module);
388
389MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>")
390MODULE_DESCRIPTION("Driver for Distributed Switch Architecture switch chips");
391MODULE_LICENSE("GPL");
392MODULE_ALIAS("platform:dsa");
diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h
new file mode 100644
index 000000000000..7063378a1ebf
--- /dev/null
+++ b/net/dsa/dsa_priv.h
@@ -0,0 +1,116 @@
1/*
2 * net/dsa/dsa_priv.h - Hardware switch handling
3 * Copyright (c) 2008 Marvell Semiconductor
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 */
10
11#ifndef __DSA_PRIV_H
12#define __DSA_PRIV_H
13
14#include <linux/list.h>
15#include <linux/phy.h>
16#include <linux/timer.h>
17#include <linux/workqueue.h>
18#include <net/dsa.h>
19
20struct dsa_switch {
21 /*
22 * Configuration data for the platform device that owns
23 * this dsa switch instance.
24 */
25 struct dsa_platform_data *pd;
26
27 /*
28 * References to network device and mii bus to use.
29 */
30 struct net_device *master_netdev;
31 struct mii_bus *master_mii_bus;
32
33 /*
34 * The used switch driver and frame tagging type.
35 */
36 struct dsa_switch_driver *drv;
37 __be16 tag_protocol;
38
39 /*
40 * Slave mii_bus and devices for the individual ports.
41 */
42 int cpu_port;
43 u32 valid_port_mask;
44 struct mii_bus *slave_mii_bus;
45 struct net_device *ports[DSA_MAX_PORTS];
46
47 /*
48 * Link state polling.
49 */
50 struct work_struct link_poll_work;
51 struct timer_list link_poll_timer;
52};
53
54struct dsa_slave_priv {
55 struct net_device *dev;
56 struct dsa_switch *parent;
57 int port;
58 struct phy_device *phy;
59};
60
61struct dsa_switch_driver {
62 struct list_head list;
63
64 __be16 tag_protocol;
65 int priv_size;
66
67 /*
68 * Probing and setup.
69 */
70 char *(*probe)(struct mii_bus *bus, int sw_addr);
71 int (*setup)(struct dsa_switch *ds);
72 int (*set_addr)(struct dsa_switch *ds, u8 *addr);
73
74 /*
75 * Access to the switch's PHY registers.
76 */
77 int (*phy_read)(struct dsa_switch *ds, int port, int regnum);
78 int (*phy_write)(struct dsa_switch *ds, int port,
79 int regnum, u16 val);
80
81 /*
82 * Link state polling and IRQ handling.
83 */
84 void (*poll_link)(struct dsa_switch *ds);
85
86 /*
87 * ethtool hardware statistics.
88 */
89 void (*get_strings)(struct dsa_switch *ds, int port, uint8_t *data);
90 void (*get_ethtool_stats)(struct dsa_switch *ds,
91 int port, uint64_t *data);
92 int (*get_sset_count)(struct dsa_switch *ds);
93};
94
95/* dsa.c */
96extern char dsa_driver_version[];
97void register_switch_driver(struct dsa_switch_driver *type);
98void unregister_switch_driver(struct dsa_switch_driver *type);
99
100/* slave.c */
101void dsa_slave_mii_bus_init(struct dsa_switch *ds);
102struct net_device *dsa_slave_create(struct dsa_switch *ds,
103 struct device *parent,
104 int port, char *name);
105
106/* tag_dsa.c */
107int dsa_xmit(struct sk_buff *skb, struct net_device *dev);
108
109/* tag_edsa.c */
110int edsa_xmit(struct sk_buff *skb, struct net_device *dev);
111
112/* tag_trailer.c */
113int trailer_xmit(struct sk_buff *skb, struct net_device *dev);
114
115
116#endif
diff --git a/net/dsa/mv88e6060.c b/net/dsa/mv88e6060.c
new file mode 100644
index 000000000000..54068ef251e8
--- /dev/null
+++ b/net/dsa/mv88e6060.c
@@ -0,0 +1,287 @@
1/*
2 * net/dsa/mv88e6060.c - Driver for Marvell 88e6060 switch chips
3 * Copyright (c) 2008 Marvell Semiconductor
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 */
10
11#include <linux/list.h>
12#include <linux/netdevice.h>
13#include <linux/phy.h>
14#include "dsa_priv.h"
15
16#define REG_PORT(p) (8 + (p))
17#define REG_GLOBAL 0x0f
18
19static int reg_read(struct dsa_switch *ds, int addr, int reg)
20{
21 return mdiobus_read(ds->master_mii_bus, addr, reg);
22}
23
24#define REG_READ(addr, reg) \
25 ({ \
26 int __ret; \
27 \
28 __ret = reg_read(ds, addr, reg); \
29 if (__ret < 0) \
30 return __ret; \
31 __ret; \
32 })
33
34
35static int reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
36{
37 return mdiobus_write(ds->master_mii_bus, addr, reg, val);
38}
39
40#define REG_WRITE(addr, reg, val) \
41 ({ \
42 int __ret; \
43 \
44 __ret = reg_write(ds, addr, reg, val); \
45 if (__ret < 0) \
46 return __ret; \
47 })
48
49static char *mv88e6060_probe(struct mii_bus *bus, int sw_addr)
50{
51 int ret;
52
53 ret = mdiobus_read(bus, REG_PORT(0), 0x03);
54 if (ret >= 0) {
55 ret &= 0xfff0;
56 if (ret == 0x0600)
57 return "Marvell 88E6060";
58 }
59
60 return NULL;
61}
62
63static int mv88e6060_switch_reset(struct dsa_switch *ds)
64{
65 int i;
66 int ret;
67
68 /*
69 * Set all ports to the disabled state.
70 */
71 for (i = 0; i < 6; i++) {
72 ret = REG_READ(REG_PORT(i), 0x04);
73 REG_WRITE(REG_PORT(i), 0x04, ret & 0xfffc);
74 }
75
76 /*
77 * Wait for transmit queues to drain.
78 */
79 msleep(2);
80
81 /*
82 * Reset the switch.
83 */
84 REG_WRITE(REG_GLOBAL, 0x0A, 0xa130);
85
86 /*
87 * Wait up to one second for reset to complete.
88 */
89 for (i = 0; i < 1000; i++) {
90 ret = REG_READ(REG_GLOBAL, 0x00);
91 if ((ret & 0x8000) == 0x0000)
92 break;
93
94 msleep(1);
95 }
96 if (i == 1000)
97 return -ETIMEDOUT;
98
99 return 0;
100}
101
102static int mv88e6060_setup_global(struct dsa_switch *ds)
103{
104 /*
105 * Disable discarding of frames with excessive collisions,
106 * set the maximum frame size to 1536 bytes, and mask all
107 * interrupt sources.
108 */
109 REG_WRITE(REG_GLOBAL, 0x04, 0x0800);
110
111 /*
112 * Enable automatic address learning, set the address
113 * database size to 1024 entries, and set the default aging
114 * time to 5 minutes.
115 */
116 REG_WRITE(REG_GLOBAL, 0x0a, 0x2130);
117
118 return 0;
119}
120
121static int mv88e6060_setup_port(struct dsa_switch *ds, int p)
122{
123 int addr = REG_PORT(p);
124
125 /*
126 * Do not force flow control, disable Ingress and Egress
127 * Header tagging, disable VLAN tunneling, and set the port
128 * state to Forwarding. Additionally, if this is the CPU
129 * port, enable Ingress and Egress Trailer tagging mode.
130 */
131 REG_WRITE(addr, 0x04, (p == ds->cpu_port) ? 0x4103 : 0x0003);
132
133 /*
134 * Port based VLAN map: give each port its own address
135 * database, allow the CPU port to talk to each of the 'real'
136 * ports, and allow each of the 'real' ports to only talk to
137 * the CPU port.
138 */
139 REG_WRITE(addr, 0x06,
140 ((p & 0xf) << 12) |
141 ((p == ds->cpu_port) ?
142 ds->valid_port_mask :
143 (1 << ds->cpu_port)));
144
145 /*
146 * Port Association Vector: when learning source addresses
147 * of packets, add the address to the address database using
148 * a port bitmap that has only the bit for this port set and
149 * the other bits clear.
150 */
151 REG_WRITE(addr, 0x0b, 1 << p);
152
153 return 0;
154}
155
156static int mv88e6060_setup(struct dsa_switch *ds)
157{
158 int i;
159 int ret;
160
161 ret = mv88e6060_switch_reset(ds);
162 if (ret < 0)
163 return ret;
164
165 /* @@@ initialise atu */
166
167 ret = mv88e6060_setup_global(ds);
168 if (ret < 0)
169 return ret;
170
171 for (i = 0; i < 6; i++) {
172 ret = mv88e6060_setup_port(ds, i);
173 if (ret < 0)
174 return ret;
175 }
176
177 return 0;
178}
179
180static int mv88e6060_set_addr(struct dsa_switch *ds, u8 *addr)
181{
182 REG_WRITE(REG_GLOBAL, 0x01, (addr[0] << 8) | addr[1]);
183 REG_WRITE(REG_GLOBAL, 0x02, (addr[2] << 8) | addr[3]);
184 REG_WRITE(REG_GLOBAL, 0x03, (addr[4] << 8) | addr[5]);
185
186 return 0;
187}
188
189static int mv88e6060_port_to_phy_addr(int port)
190{
191 if (port >= 0 && port <= 5)
192 return port;
193 return -1;
194}
195
196static int mv88e6060_phy_read(struct dsa_switch *ds, int port, int regnum)
197{
198 int addr;
199
200 addr = mv88e6060_port_to_phy_addr(port);
201 if (addr == -1)
202 return 0xffff;
203
204 return reg_read(ds, addr, regnum);
205}
206
207static int
208mv88e6060_phy_write(struct dsa_switch *ds, int port, int regnum, u16 val)
209{
210 int addr;
211
212 addr = mv88e6060_port_to_phy_addr(port);
213 if (addr == -1)
214 return 0xffff;
215
216 return reg_write(ds, addr, regnum, val);
217}
218
219static void mv88e6060_poll_link(struct dsa_switch *ds)
220{
221 int i;
222
223 for (i = 0; i < DSA_MAX_PORTS; i++) {
224 struct net_device *dev;
225 int port_status;
226 int link;
227 int speed;
228 int duplex;
229 int fc;
230
231 dev = ds->ports[i];
232 if (dev == NULL)
233 continue;
234
235 link = 0;
236 if (dev->flags & IFF_UP) {
237 port_status = reg_read(ds, REG_PORT(i), 0x00);
238 if (port_status < 0)
239 continue;
240
241 link = !!(port_status & 0x1000);
242 }
243
244 if (!link) {
245 if (netif_carrier_ok(dev)) {
246 printk(KERN_INFO "%s: link down\n", dev->name);
247 netif_carrier_off(dev);
248 }
249 continue;
250 }
251
252 speed = (port_status & 0x0100) ? 100 : 10;
253 duplex = (port_status & 0x0200) ? 1 : 0;
254 fc = ((port_status & 0xc000) == 0xc000) ? 1 : 0;
255
256 if (!netif_carrier_ok(dev)) {
257 printk(KERN_INFO "%s: link up, %d Mb/s, %s duplex, "
258 "flow control %sabled\n", dev->name,
259 speed, duplex ? "full" : "half",
260 fc ? "en" : "dis");
261 netif_carrier_on(dev);
262 }
263 }
264}
265
266static struct dsa_switch_driver mv88e6060_switch_driver = {
267 .tag_protocol = htons(ETH_P_TRAILER),
268 .probe = mv88e6060_probe,
269 .setup = mv88e6060_setup,
270 .set_addr = mv88e6060_set_addr,
271 .phy_read = mv88e6060_phy_read,
272 .phy_write = mv88e6060_phy_write,
273 .poll_link = mv88e6060_poll_link,
274};
275
276int __init mv88e6060_init(void)
277{
278 register_switch_driver(&mv88e6060_switch_driver);
279 return 0;
280}
281module_init(mv88e6060_init);
282
283void __exit mv88e6060_cleanup(void)
284{
285 unregister_switch_driver(&mv88e6060_switch_driver);
286}
287module_exit(mv88e6060_cleanup);
diff --git a/net/dsa/mv88e6123_61_65.c b/net/dsa/mv88e6123_61_65.c
new file mode 100644
index 000000000000..555b164082fc
--- /dev/null
+++ b/net/dsa/mv88e6123_61_65.c
@@ -0,0 +1,421 @@
1/*
2 * net/dsa/mv88e6123_61_65.c - Marvell 88e6123/6161/6165 switch chip support
3 * Copyright (c) 2008 Marvell Semiconductor
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 */
10
11#include <linux/list.h>
12#include <linux/netdevice.h>
13#include <linux/phy.h>
14#include "dsa_priv.h"
15#include "mv88e6xxx.h"
16
17static char *mv88e6123_61_65_probe(struct mii_bus *bus, int sw_addr)
18{
19 int ret;
20
21 ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), 0x03);
22 if (ret >= 0) {
23 ret &= 0xfff0;
24 if (ret == 0x1210)
25 return "Marvell 88E6123";
26 if (ret == 0x1610)
27 return "Marvell 88E6161";
28 if (ret == 0x1650)
29 return "Marvell 88E6165";
30 }
31
32 return NULL;
33}
34
35static int mv88e6123_61_65_switch_reset(struct dsa_switch *ds)
36{
37 int i;
38 int ret;
39
40 /*
41 * Set all ports to the disabled state.
42 */
43 for (i = 0; i < 8; i++) {
44 ret = REG_READ(REG_PORT(i), 0x04);
45 REG_WRITE(REG_PORT(i), 0x04, ret & 0xfffc);
46 }
47
48 /*
49 * Wait for transmit queues to drain.
50 */
51 msleep(2);
52
53 /*
54 * Reset the switch.
55 */
56 REG_WRITE(REG_GLOBAL, 0x04, 0xc400);
57
58 /*
59 * Wait up to one second for reset to complete.
60 */
61 for (i = 0; i < 1000; i++) {
62 ret = REG_READ(REG_GLOBAL, 0x00);
63 if ((ret & 0xc800) == 0xc800)
64 break;
65
66 msleep(1);
67 }
68 if (i == 1000)
69 return -ETIMEDOUT;
70
71 return 0;
72}
73
74static int mv88e6123_61_65_setup_global(struct dsa_switch *ds)
75{
76 int ret;
77 int i;
78
79 /*
80 * Disable the PHY polling unit (since there won't be any
81 * external PHYs to poll), don't discard packets with
82 * excessive collisions, and mask all interrupt sources.
83 */
84 REG_WRITE(REG_GLOBAL, 0x04, 0x0000);
85
86 /*
87 * Set the default address aging time to 5 minutes, and
88 * enable address learn messages to be sent to all message
89 * ports.
90 */
91 REG_WRITE(REG_GLOBAL, 0x0a, 0x0148);
92
93 /*
94 * Configure the priority mapping registers.
95 */
96 ret = mv88e6xxx_config_prio(ds);
97 if (ret < 0)
98 return ret;
99
100 /*
101 * Configure the cpu port, and configure the cpu port as the
102 * port to which ingress and egress monitor frames are to be
103 * sent.
104 */
105 REG_WRITE(REG_GLOBAL, 0x1a, (ds->cpu_port * 0x1110));
106
107 /*
108 * Disable remote management for now, and set the switch's
109 * DSA device number to zero.
110 */
111 REG_WRITE(REG_GLOBAL, 0x1c, 0x0000);
112
113 /*
114 * Send all frames with destination addresses matching
115 * 01:80:c2:00:00:2x to the CPU port.
116 */
117 REG_WRITE(REG_GLOBAL2, 0x02, 0xffff);
118
119 /*
120 * Send all frames with destination addresses matching
121 * 01:80:c2:00:00:0x to the CPU port.
122 */
123 REG_WRITE(REG_GLOBAL2, 0x03, 0xffff);
124
125 /*
126 * Disable the loopback filter, disable flow control
127 * messages, disable flood broadcast override, disable
128 * removing of provider tags, disable ATU age violation
129 * interrupts, disable tag flow control, force flow
130 * control priority to the highest, and send all special
131 * multicast frames to the CPU at the highest priority.
132 */
133 REG_WRITE(REG_GLOBAL2, 0x05, 0x00ff);
134
135 /*
136 * Map all DSA device IDs to the CPU port.
137 */
138 for (i = 0; i < 32; i++)
139 REG_WRITE(REG_GLOBAL2, 0x06, 0x8000 | (i << 8) | ds->cpu_port);
140
141 /*
142 * Clear all trunk masks.
143 */
144 for (i = 0; i < 8; i++)
145 REG_WRITE(REG_GLOBAL2, 0x07, 0x8000 | (i << 12) | 0xff);
146
147 /*
148 * Clear all trunk mappings.
149 */
150 for (i = 0; i < 16; i++)
151 REG_WRITE(REG_GLOBAL2, 0x08, 0x8000 | (i << 11));
152
153 /*
154 * Disable ingress rate limiting by resetting all ingress
155 * rate limit registers to their initial state.
156 */
157 for (i = 0; i < 6; i++)
158 REG_WRITE(REG_GLOBAL2, 0x09, 0x9000 | (i << 8));
159
160 /*
161 * Initialise cross-chip port VLAN table to reset defaults.
162 */
163 REG_WRITE(REG_GLOBAL2, 0x0b, 0x9000);
164
165 /*
166 * Clear the priority override table.
167 */
168 for (i = 0; i < 16; i++)
169 REG_WRITE(REG_GLOBAL2, 0x0f, 0x8000 | (i << 8));
170
171 /* @@@ initialise AVB (22/23) watchdog (27) sdet (29) registers */
172
173 return 0;
174}
175
176static int mv88e6123_61_65_setup_port(struct dsa_switch *ds, int p)
177{
178 int addr = REG_PORT(p);
179
180 /*
181 * MAC Forcing register: don't force link, speed, duplex
182 * or flow control state to any particular values.
183 */
184 REG_WRITE(addr, 0x01, 0x0003);
185
186 /*
187 * Do not limit the period of time that this port can be
188 * paused for by the remote end or the period of time that
189 * this port can pause the remote end.
190 */
191 REG_WRITE(addr, 0x02, 0x0000);
192
193 /*
194 * Port Control: disable Drop-on-Unlock, disable Drop-on-Lock,
195 * configure the requested (DSA/EDSA) tagging mode if this is
196 * the CPU port, disable Header mode, enable IGMP/MLD snooping,
197 * disable VLAN tunneling, determine priority by looking at
198 * 802.1p and IP priority fields (IP prio has precedence), and
199 * set STP state to Forwarding. Finally, if this is the CPU
200 * port, additionally enable forwarding of unknown unicast and
201 * multicast addresses.
202 */
203 REG_WRITE(addr, 0x04,
204 (p == ds->cpu_port) ?
205 (ds->tag_protocol == htons(ETH_P_DSA)) ?
206 0x053f : 0x373f :
207 0x0433);
208
209 /*
210 * Port Control 1: disable trunking. Also, if this is the
211 * CPU port, enable learn messages to be sent to this port.
212 */
213 REG_WRITE(addr, 0x05, (p == ds->cpu_port) ? 0x8000 : 0x0000);
214
215 /*
216 * Port based VLAN map: give each port its own address
217 * database, allow the CPU port to talk to each of the 'real'
218 * ports, and allow each of the 'real' ports to only talk to
219 * the CPU port.
220 */
221 REG_WRITE(addr, 0x06,
222 ((p & 0xf) << 12) |
223 ((p == ds->cpu_port) ?
224 ds->valid_port_mask :
225 (1 << ds->cpu_port)));
226
227 /*
228 * Default VLAN ID and priority: don't set a default VLAN
229 * ID, and set the default packet priority to zero.
230 */
231 REG_WRITE(addr, 0x07, 0x0000);
232
233 /*
234 * Port Control 2: don't force a good FCS, set the maximum
235 * frame size to 10240 bytes, don't let the switch add or
236 * strip 802.1q tags, don't discard tagged or untagged frames
237 * on this port, do a destination address lookup on all
238 * received packets as usual, disable ARP mirroring and don't
239 * send a copy of all transmitted/received frames on this port
240 * to the CPU.
241 */
242 REG_WRITE(addr, 0x08, 0x2080);
243
244 /*
245 * Egress rate control: disable egress rate control.
246 */
247 REG_WRITE(addr, 0x09, 0x0001);
248
249 /*
250 * Egress rate control 2: disable egress rate control.
251 */
252 REG_WRITE(addr, 0x0a, 0x0000);
253
254 /*
255 * Port Association Vector: when learning source addresses
256 * of packets, add the address to the address database using
257 * a port bitmap that has only the bit for this port set and
258 * the other bits clear.
259 */
260 REG_WRITE(addr, 0x0b, 1 << p);
261
262 /*
263 * Port ATU control: disable limiting the number of address
264 * database entries that this port is allowed to use.
265 */
266 REG_WRITE(addr, 0x0c, 0x0000);
267
268 /*
269 * Priorit Override: disable DA, SA and VTU priority override.
270 */
271 REG_WRITE(addr, 0x0d, 0x0000);
272
273 /*
274 * Port Ethertype: use the Ethertype DSA Ethertype value.
275 */
276 REG_WRITE(addr, 0x0f, ETH_P_EDSA);
277
278 /*
279 * Tag Remap: use an identity 802.1p prio -> switch prio
280 * mapping.
281 */
282 REG_WRITE(addr, 0x18, 0x3210);
283
284 /*
285 * Tag Remap 2: use an identity 802.1p prio -> switch prio
286 * mapping.
287 */
288 REG_WRITE(addr, 0x19, 0x7654);
289
290 return 0;
291}
292
293static int mv88e6123_61_65_setup(struct dsa_switch *ds)
294{
295 struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
296 int i;
297 int ret;
298
299 mutex_init(&ps->smi_mutex);
300 mutex_init(&ps->stats_mutex);
301
302 ret = mv88e6123_61_65_switch_reset(ds);
303 if (ret < 0)
304 return ret;
305
306 /* @@@ initialise vtu and atu */
307
308 ret = mv88e6123_61_65_setup_global(ds);
309 if (ret < 0)
310 return ret;
311
312 for (i = 0; i < 6; i++) {
313 ret = mv88e6123_61_65_setup_port(ds, i);
314 if (ret < 0)
315 return ret;
316 }
317
318 return 0;
319}
320
321static int mv88e6123_61_65_port_to_phy_addr(int port)
322{
323 if (port >= 0 && port <= 4)
324 return port;
325 return -1;
326}
327
328static int
329mv88e6123_61_65_phy_read(struct dsa_switch *ds, int port, int regnum)
330{
331 int addr = mv88e6123_61_65_port_to_phy_addr(port);
332 return mv88e6xxx_phy_read(ds, addr, regnum);
333}
334
335static int
336mv88e6123_61_65_phy_write(struct dsa_switch *ds,
337 int port, int regnum, u16 val)
338{
339 int addr = mv88e6123_61_65_port_to_phy_addr(port);
340 return mv88e6xxx_phy_write(ds, addr, regnum, val);
341}
342
343static struct mv88e6xxx_hw_stat mv88e6123_61_65_hw_stats[] = {
344 { "in_good_octets", 8, 0x00, },
345 { "in_bad_octets", 4, 0x02, },
346 { "in_unicast", 4, 0x04, },
347 { "in_broadcasts", 4, 0x06, },
348 { "in_multicasts", 4, 0x07, },
349 { "in_pause", 4, 0x16, },
350 { "in_undersize", 4, 0x18, },
351 { "in_fragments", 4, 0x19, },
352 { "in_oversize", 4, 0x1a, },
353 { "in_jabber", 4, 0x1b, },
354 { "in_rx_error", 4, 0x1c, },
355 { "in_fcs_error", 4, 0x1d, },
356 { "out_octets", 8, 0x0e, },
357 { "out_unicast", 4, 0x10, },
358 { "out_broadcasts", 4, 0x13, },
359 { "out_multicasts", 4, 0x12, },
360 { "out_pause", 4, 0x15, },
361 { "excessive", 4, 0x11, },
362 { "collisions", 4, 0x1e, },
363 { "deferred", 4, 0x05, },
364 { "single", 4, 0x14, },
365 { "multiple", 4, 0x17, },
366 { "out_fcs_error", 4, 0x03, },
367 { "late", 4, 0x1f, },
368 { "hist_64bytes", 4, 0x08, },
369 { "hist_65_127bytes", 4, 0x09, },
370 { "hist_128_255bytes", 4, 0x0a, },
371 { "hist_256_511bytes", 4, 0x0b, },
372 { "hist_512_1023bytes", 4, 0x0c, },
373 { "hist_1024_max_bytes", 4, 0x0d, },
374};
375
376static void
377mv88e6123_61_65_get_strings(struct dsa_switch *ds, int port, uint8_t *data)
378{
379 mv88e6xxx_get_strings(ds, ARRAY_SIZE(mv88e6123_61_65_hw_stats),
380 mv88e6123_61_65_hw_stats, port, data);
381}
382
383static void
384mv88e6123_61_65_get_ethtool_stats(struct dsa_switch *ds,
385 int port, uint64_t *data)
386{
387 mv88e6xxx_get_ethtool_stats(ds, ARRAY_SIZE(mv88e6123_61_65_hw_stats),
388 mv88e6123_61_65_hw_stats, port, data);
389}
390
391static int mv88e6123_61_65_get_sset_count(struct dsa_switch *ds)
392{
393 return ARRAY_SIZE(mv88e6123_61_65_hw_stats);
394}
395
396static struct dsa_switch_driver mv88e6123_61_65_switch_driver = {
397 .tag_protocol = __constant_htons(ETH_P_EDSA),
398 .priv_size = sizeof(struct mv88e6xxx_priv_state),
399 .probe = mv88e6123_61_65_probe,
400 .setup = mv88e6123_61_65_setup,
401 .set_addr = mv88e6xxx_set_addr_indirect,
402 .phy_read = mv88e6123_61_65_phy_read,
403 .phy_write = mv88e6123_61_65_phy_write,
404 .poll_link = mv88e6xxx_poll_link,
405 .get_strings = mv88e6123_61_65_get_strings,
406 .get_ethtool_stats = mv88e6123_61_65_get_ethtool_stats,
407 .get_sset_count = mv88e6123_61_65_get_sset_count,
408};
409
410int __init mv88e6123_61_65_init(void)
411{
412 register_switch_driver(&mv88e6123_61_65_switch_driver);
413 return 0;
414}
415module_init(mv88e6123_61_65_init);
416
417void __exit mv88e6123_61_65_cleanup(void)
418{
419 unregister_switch_driver(&mv88e6123_61_65_switch_driver);
420}
421module_exit(mv88e6123_61_65_cleanup);
diff --git a/net/dsa/mv88e6131.c b/net/dsa/mv88e6131.c
new file mode 100644
index 000000000000..36e01eb863a0
--- /dev/null
+++ b/net/dsa/mv88e6131.c
@@ -0,0 +1,380 @@
1/*
2 * net/dsa/mv88e6131.c - Marvell 88e6131 switch chip support
3 * Copyright (c) 2008 Marvell Semiconductor
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 */
10
11#include <linux/list.h>
12#include <linux/netdevice.h>
13#include <linux/phy.h>
14#include "dsa_priv.h"
15#include "mv88e6xxx.h"
16
17static char *mv88e6131_probe(struct mii_bus *bus, int sw_addr)
18{
19 int ret;
20
21 ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), 0x03);
22 if (ret >= 0) {
23 ret &= 0xfff0;
24 if (ret == 0x1060)
25 return "Marvell 88E6131";
26 }
27
28 return NULL;
29}
30
31static int mv88e6131_switch_reset(struct dsa_switch *ds)
32{
33 int i;
34 int ret;
35
36 /*
37 * Set all ports to the disabled state.
38 */
39 for (i = 0; i < 8; i++) {
40 ret = REG_READ(REG_PORT(i), 0x04);
41 REG_WRITE(REG_PORT(i), 0x04, ret & 0xfffc);
42 }
43
44 /*
45 * Wait for transmit queues to drain.
46 */
47 msleep(2);
48
49 /*
50 * Reset the switch.
51 */
52 REG_WRITE(REG_GLOBAL, 0x04, 0xc400);
53
54 /*
55 * Wait up to one second for reset to complete.
56 */
57 for (i = 0; i < 1000; i++) {
58 ret = REG_READ(REG_GLOBAL, 0x00);
59 if ((ret & 0xc800) == 0xc800)
60 break;
61
62 msleep(1);
63 }
64 if (i == 1000)
65 return -ETIMEDOUT;
66
67 return 0;
68}
69
70static int mv88e6131_setup_global(struct dsa_switch *ds)
71{
72 int ret;
73 int i;
74
75 /*
76 * Enable the PHY polling unit, don't discard packets with
77 * excessive collisions, use a weighted fair queueing scheme
78 * to arbitrate between packet queues, set the maximum frame
79 * size to 1632, and mask all interrupt sources.
80 */
81 REG_WRITE(REG_GLOBAL, 0x04, 0x4400);
82
83 /*
84 * Set the default address aging time to 5 minutes, and
85 * enable address learn messages to be sent to all message
86 * ports.
87 */
88 REG_WRITE(REG_GLOBAL, 0x0a, 0x0148);
89
90 /*
91 * Configure the priority mapping registers.
92 */
93 ret = mv88e6xxx_config_prio(ds);
94 if (ret < 0)
95 return ret;
96
97 /*
98 * Set the VLAN ethertype to 0x8100.
99 */
100 REG_WRITE(REG_GLOBAL, 0x19, 0x8100);
101
102 /*
103 * Disable ARP mirroring, and configure the cpu port as the
104 * port to which ingress and egress monitor frames are to be
105 * sent.
106 */
107 REG_WRITE(REG_GLOBAL, 0x1a, (ds->cpu_port * 0x1100) | 0x00f0);
108
109 /*
110 * Disable cascade port functionality, and set the switch's
111 * DSA device number to zero.
112 */
113 REG_WRITE(REG_GLOBAL, 0x1c, 0xe000);
114
115 /*
116 * Send all frames with destination addresses matching
117 * 01:80:c2:00:00:0x to the CPU port.
118 */
119 REG_WRITE(REG_GLOBAL2, 0x03, 0xffff);
120
121 /*
122 * Ignore removed tag data on doubly tagged packets, disable
123 * flow control messages, force flow control priority to the
124 * highest, and send all special multicast frames to the CPU
125 * port at the higest priority.
126 */
127 REG_WRITE(REG_GLOBAL2, 0x05, 0x00ff);
128
129 /*
130 * Map all DSA device IDs to the CPU port.
131 */
132 for (i = 0; i < 32; i++)
133 REG_WRITE(REG_GLOBAL2, 0x06, 0x8000 | (i << 8) | ds->cpu_port);
134
135 /*
136 * Clear all trunk masks.
137 */
138 for (i = 0; i < 8; i++)
139 REG_WRITE(REG_GLOBAL2, 0x07, 0x8000 | (i << 12) | 0xff);
140
141 /*
142 * Clear all trunk mappings.
143 */
144 for (i = 0; i < 16; i++)
145 REG_WRITE(REG_GLOBAL2, 0x08, 0x8000 | (i << 11));
146
147 /*
148 * Force the priority of IGMP/MLD snoop frames and ARP frames
149 * to the highest setting.
150 */
151 REG_WRITE(REG_GLOBAL2, 0x0f, 0x00ff);
152
153 return 0;
154}
155
156static int mv88e6131_setup_port(struct dsa_switch *ds, int p)
157{
158 int addr = REG_PORT(p);
159
160 /*
161 * MAC Forcing register: don't force link, speed, duplex
162 * or flow control state to any particular values.
163 */
164 REG_WRITE(addr, 0x01, 0x0003);
165
166 /*
167 * Port Control: disable Core Tag, disable Drop-on-Lock,
168 * transmit frames unmodified, disable Header mode,
169 * enable IGMP/MLD snoop, disable DoubleTag, disable VLAN
170 * tunneling, determine priority by looking at 802.1p and
171 * IP priority fields (IP prio has precedence), and set STP
172 * state to Forwarding. Finally, if this is the CPU port,
173 * additionally enable DSA tagging and forwarding of unknown
174 * unicast addresses.
175 */
176 REG_WRITE(addr, 0x04, (p == ds->cpu_port) ? 0x0537 : 0x0433);
177
178 /*
179 * Port Control 1: disable trunking. Also, if this is the
180 * CPU port, enable learn messages to be sent to this port.
181 */
182 REG_WRITE(addr, 0x05, (p == ds->cpu_port) ? 0x8000 : 0x0000);
183
184 /*
185 * Port based VLAN map: give each port its own address
186 * database, allow the CPU port to talk to each of the 'real'
187 * ports, and allow each of the 'real' ports to only talk to
188 * the CPU port.
189 */
190 REG_WRITE(addr, 0x06,
191 ((p & 0xf) << 12) |
192 ((p == ds->cpu_port) ?
193 ds->valid_port_mask :
194 (1 << ds->cpu_port)));
195
196 /*
197 * Default VLAN ID and priority: don't set a default VLAN
198 * ID, and set the default packet priority to zero.
199 */
200 REG_WRITE(addr, 0x07, 0x0000);
201
202 /*
203 * Port Control 2: don't force a good FCS, don't use
204 * VLAN-based, source address-based or destination
205 * address-based priority overrides, don't let the switch
206 * add or strip 802.1q tags, don't discard tagged or
207 * untagged frames on this port, do a destination address
208 * lookup on received packets as usual, don't send a copy
209 * of all transmitted/received frames on this port to the
210 * CPU, and configure the CPU port number. Also, if this
211 * is the CPU port, enable forwarding of unknown multicast
212 * addresses.
213 */
214 REG_WRITE(addr, 0x08,
215 ((p == ds->cpu_port) ? 0x00c0 : 0x0080) |
216 ds->cpu_port);
217
218 /*
219 * Rate Control: disable ingress rate limiting.
220 */
221 REG_WRITE(addr, 0x09, 0x0000);
222
223 /*
224 * Rate Control 2: disable egress rate limiting.
225 */
226 REG_WRITE(addr, 0x0a, 0x0000);
227
228 /*
229 * Port Association Vector: when learning source addresses
230 * of packets, add the address to the address database using
231 * a port bitmap that has only the bit for this port set and
232 * the other bits clear.
233 */
234 REG_WRITE(addr, 0x0b, 1 << p);
235
236 /*
237 * Tag Remap: use an identity 802.1p prio -> switch prio
238 * mapping.
239 */
240 REG_WRITE(addr, 0x18, 0x3210);
241
242 /*
243 * Tag Remap 2: use an identity 802.1p prio -> switch prio
244 * mapping.
245 */
246 REG_WRITE(addr, 0x19, 0x7654);
247
248 return 0;
249}
250
251static int mv88e6131_setup(struct dsa_switch *ds)
252{
253 struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
254 int i;
255 int ret;
256
257 mutex_init(&ps->smi_mutex);
258 mv88e6xxx_ppu_state_init(ds);
259 mutex_init(&ps->stats_mutex);
260
261 ret = mv88e6131_switch_reset(ds);
262 if (ret < 0)
263 return ret;
264
265 /* @@@ initialise vtu and atu */
266
267 ret = mv88e6131_setup_global(ds);
268 if (ret < 0)
269 return ret;
270
271 for (i = 0; i < 6; i++) {
272 ret = mv88e6131_setup_port(ds, i);
273 if (ret < 0)
274 return ret;
275 }
276
277 return 0;
278}
279
280static int mv88e6131_port_to_phy_addr(int port)
281{
282 if (port >= 0 && port != 3 && port <= 7)
283 return port;
284 return -1;
285}
286
287static int
288mv88e6131_phy_read(struct dsa_switch *ds, int port, int regnum)
289{
290 int addr = mv88e6131_port_to_phy_addr(port);
291 return mv88e6xxx_phy_read_ppu(ds, addr, regnum);
292}
293
294static int
295mv88e6131_phy_write(struct dsa_switch *ds,
296 int port, int regnum, u16 val)
297{
298 int addr = mv88e6131_port_to_phy_addr(port);
299 return mv88e6xxx_phy_write_ppu(ds, addr, regnum, val);
300}
301
302static struct mv88e6xxx_hw_stat mv88e6131_hw_stats[] = {
303 { "in_good_octets", 8, 0x00, },
304 { "in_bad_octets", 4, 0x02, },
305 { "in_unicast", 4, 0x04, },
306 { "in_broadcasts", 4, 0x06, },
307 { "in_multicasts", 4, 0x07, },
308 { "in_pause", 4, 0x16, },
309 { "in_undersize", 4, 0x18, },
310 { "in_fragments", 4, 0x19, },
311 { "in_oversize", 4, 0x1a, },
312 { "in_jabber", 4, 0x1b, },
313 { "in_rx_error", 4, 0x1c, },
314 { "in_fcs_error", 4, 0x1d, },
315 { "out_octets", 8, 0x0e, },
316 { "out_unicast", 4, 0x10, },
317 { "out_broadcasts", 4, 0x13, },
318 { "out_multicasts", 4, 0x12, },
319 { "out_pause", 4, 0x15, },
320 { "excessive", 4, 0x11, },
321 { "collisions", 4, 0x1e, },
322 { "deferred", 4, 0x05, },
323 { "single", 4, 0x14, },
324 { "multiple", 4, 0x17, },
325 { "out_fcs_error", 4, 0x03, },
326 { "late", 4, 0x1f, },
327 { "hist_64bytes", 4, 0x08, },
328 { "hist_65_127bytes", 4, 0x09, },
329 { "hist_128_255bytes", 4, 0x0a, },
330 { "hist_256_511bytes", 4, 0x0b, },
331 { "hist_512_1023bytes", 4, 0x0c, },
332 { "hist_1024_max_bytes", 4, 0x0d, },
333};
334
335static void
336mv88e6131_get_strings(struct dsa_switch *ds, int port, uint8_t *data)
337{
338 mv88e6xxx_get_strings(ds, ARRAY_SIZE(mv88e6131_hw_stats),
339 mv88e6131_hw_stats, port, data);
340}
341
342static void
343mv88e6131_get_ethtool_stats(struct dsa_switch *ds,
344 int port, uint64_t *data)
345{
346 mv88e6xxx_get_ethtool_stats(ds, ARRAY_SIZE(mv88e6131_hw_stats),
347 mv88e6131_hw_stats, port, data);
348}
349
350static int mv88e6131_get_sset_count(struct dsa_switch *ds)
351{
352 return ARRAY_SIZE(mv88e6131_hw_stats);
353}
354
355static struct dsa_switch_driver mv88e6131_switch_driver = {
356 .tag_protocol = __constant_htons(ETH_P_DSA),
357 .priv_size = sizeof(struct mv88e6xxx_priv_state),
358 .probe = mv88e6131_probe,
359 .setup = mv88e6131_setup,
360 .set_addr = mv88e6xxx_set_addr_direct,
361 .phy_read = mv88e6131_phy_read,
362 .phy_write = mv88e6131_phy_write,
363 .poll_link = mv88e6xxx_poll_link,
364 .get_strings = mv88e6131_get_strings,
365 .get_ethtool_stats = mv88e6131_get_ethtool_stats,
366 .get_sset_count = mv88e6131_get_sset_count,
367};
368
369int __init mv88e6131_init(void)
370{
371 register_switch_driver(&mv88e6131_switch_driver);
372 return 0;
373}
374module_init(mv88e6131_init);
375
376void __exit mv88e6131_cleanup(void)
377{
378 unregister_switch_driver(&mv88e6131_switch_driver);
379}
380module_exit(mv88e6131_cleanup);
diff --git a/net/dsa/mv88e6xxx.c b/net/dsa/mv88e6xxx.c
new file mode 100644
index 000000000000..aa6c609c59f2
--- /dev/null
+++ b/net/dsa/mv88e6xxx.c
@@ -0,0 +1,522 @@
1/*
2 * net/dsa/mv88e6xxx.c - Marvell 88e6xxx switch chip support
3 * Copyright (c) 2008 Marvell Semiconductor
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 */
10
11#include <linux/list.h>
12#include <linux/netdevice.h>
13#include <linux/phy.h>
14#include "dsa_priv.h"
15#include "mv88e6xxx.h"
16
17/*
18 * If the switch's ADDR[4:0] strap pins are strapped to zero, it will
19 * use all 32 SMI bus addresses on its SMI bus, and all switch registers
20 * will be directly accessible on some {device address,register address}
21 * pair. If the ADDR[4:0] pins are not strapped to zero, the switch
22 * will only respond to SMI transactions to that specific address, and
23 * an indirect addressing mechanism needs to be used to access its
24 * registers.
25 */
26static int mv88e6xxx_reg_wait_ready(struct mii_bus *bus, int sw_addr)
27{
28 int ret;
29 int i;
30
31 for (i = 0; i < 16; i++) {
32 ret = mdiobus_read(bus, sw_addr, 0);
33 if (ret < 0)
34 return ret;
35
36 if ((ret & 0x8000) == 0)
37 return 0;
38 }
39
40 return -ETIMEDOUT;
41}
42
43int __mv88e6xxx_reg_read(struct mii_bus *bus, int sw_addr, int addr, int reg)
44{
45 int ret;
46
47 if (sw_addr == 0)
48 return mdiobus_read(bus, addr, reg);
49
50 /*
51 * Wait for the bus to become free.
52 */
53 ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
54 if (ret < 0)
55 return ret;
56
57 /*
58 * Transmit the read command.
59 */
60 ret = mdiobus_write(bus, sw_addr, 0, 0x9800 | (addr << 5) | reg);
61 if (ret < 0)
62 return ret;
63
64 /*
65 * Wait for the read command to complete.
66 */
67 ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
68 if (ret < 0)
69 return ret;
70
71 /*
72 * Read the data.
73 */
74 ret = mdiobus_read(bus, sw_addr, 1);
75 if (ret < 0)
76 return ret;
77
78 return ret & 0xffff;
79}
80
81int mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg)
82{
83 struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
84 int ret;
85
86 mutex_lock(&ps->smi_mutex);
87 ret = __mv88e6xxx_reg_read(ds->master_mii_bus,
88 ds->pd->sw_addr, addr, reg);
89 mutex_unlock(&ps->smi_mutex);
90
91 return ret;
92}
93
94int __mv88e6xxx_reg_write(struct mii_bus *bus, int sw_addr, int addr,
95 int reg, u16 val)
96{
97 int ret;
98
99 if (sw_addr == 0)
100 return mdiobus_write(bus, addr, reg, val);
101
102 /*
103 * Wait for the bus to become free.
104 */
105 ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
106 if (ret < 0)
107 return ret;
108
109 /*
110 * Transmit the data to write.
111 */
112 ret = mdiobus_write(bus, sw_addr, 1, val);
113 if (ret < 0)
114 return ret;
115
116 /*
117 * Transmit the write command.
118 */
119 ret = mdiobus_write(bus, sw_addr, 0, 0x9400 | (addr << 5) | reg);
120 if (ret < 0)
121 return ret;
122
123 /*
124 * Wait for the write command to complete.
125 */
126 ret = mv88e6xxx_reg_wait_ready(bus, sw_addr);
127 if (ret < 0)
128 return ret;
129
130 return 0;
131}
132
133int mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
134{
135 struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
136 int ret;
137
138 mutex_lock(&ps->smi_mutex);
139 ret = __mv88e6xxx_reg_write(ds->master_mii_bus,
140 ds->pd->sw_addr, addr, reg, val);
141 mutex_unlock(&ps->smi_mutex);
142
143 return ret;
144}
145
146int mv88e6xxx_config_prio(struct dsa_switch *ds)
147{
148 /*
149 * Configure the IP ToS mapping registers.
150 */
151 REG_WRITE(REG_GLOBAL, 0x10, 0x0000);
152 REG_WRITE(REG_GLOBAL, 0x11, 0x0000);
153 REG_WRITE(REG_GLOBAL, 0x12, 0x5555);
154 REG_WRITE(REG_GLOBAL, 0x13, 0x5555);
155 REG_WRITE(REG_GLOBAL, 0x14, 0xaaaa);
156 REG_WRITE(REG_GLOBAL, 0x15, 0xaaaa);
157 REG_WRITE(REG_GLOBAL, 0x16, 0xffff);
158 REG_WRITE(REG_GLOBAL, 0x17, 0xffff);
159
160 /*
161 * Configure the IEEE 802.1p priority mapping register.
162 */
163 REG_WRITE(REG_GLOBAL, 0x18, 0xfa41);
164
165 return 0;
166}
167
168int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr)
169{
170 REG_WRITE(REG_GLOBAL, 0x01, (addr[0] << 8) | addr[1]);
171 REG_WRITE(REG_GLOBAL, 0x02, (addr[2] << 8) | addr[3]);
172 REG_WRITE(REG_GLOBAL, 0x03, (addr[4] << 8) | addr[5]);
173
174 return 0;
175}
176
177int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr)
178{
179 int i;
180 int ret;
181
182 for (i = 0; i < 6; i++) {
183 int j;
184
185 /*
186 * Write the MAC address byte.
187 */
188 REG_WRITE(REG_GLOBAL2, 0x0d, 0x8000 | (i << 8) | addr[i]);
189
190 /*
191 * Wait for the write to complete.
192 */
193 for (j = 0; j < 16; j++) {
194 ret = REG_READ(REG_GLOBAL2, 0x0d);
195 if ((ret & 0x8000) == 0)
196 break;
197 }
198 if (j == 16)
199 return -ETIMEDOUT;
200 }
201
202 return 0;
203}
204
205int mv88e6xxx_phy_read(struct dsa_switch *ds, int addr, int regnum)
206{
207 if (addr >= 0)
208 return mv88e6xxx_reg_read(ds, addr, regnum);
209 return 0xffff;
210}
211
212int mv88e6xxx_phy_write(struct dsa_switch *ds, int addr, int regnum, u16 val)
213{
214 if (addr >= 0)
215 return mv88e6xxx_reg_write(ds, addr, regnum, val);
216 return 0;
217}
218
219#ifdef CONFIG_NET_DSA_MV88E6XXX_NEED_PPU
220static int mv88e6xxx_ppu_disable(struct dsa_switch *ds)
221{
222 int ret;
223 int i;
224
225 ret = REG_READ(REG_GLOBAL, 0x04);
226 REG_WRITE(REG_GLOBAL, 0x04, ret & ~0x4000);
227
228 for (i = 0; i < 1000; i++) {
229 ret = REG_READ(REG_GLOBAL, 0x00);
230 msleep(1);
231 if ((ret & 0xc000) != 0xc000)
232 return 0;
233 }
234
235 return -ETIMEDOUT;
236}
237
238static int mv88e6xxx_ppu_enable(struct dsa_switch *ds)
239{
240 int ret;
241 int i;
242
243 ret = REG_READ(REG_GLOBAL, 0x04);
244 REG_WRITE(REG_GLOBAL, 0x04, ret | 0x4000);
245
246 for (i = 0; i < 1000; i++) {
247 ret = REG_READ(REG_GLOBAL, 0x00);
248 msleep(1);
249 if ((ret & 0xc000) == 0xc000)
250 return 0;
251 }
252
253 return -ETIMEDOUT;
254}
255
256static void mv88e6xxx_ppu_reenable_work(struct work_struct *ugly)
257{
258 struct mv88e6xxx_priv_state *ps;
259
260 ps = container_of(ugly, struct mv88e6xxx_priv_state, ppu_work);
261 if (mutex_trylock(&ps->ppu_mutex)) {
262 struct dsa_switch *ds = ((struct dsa_switch *)ps) - 1;
263
264 if (mv88e6xxx_ppu_enable(ds) == 0)
265 ps->ppu_disabled = 0;
266 mutex_unlock(&ps->ppu_mutex);
267 }
268}
269
270static void mv88e6xxx_ppu_reenable_timer(unsigned long _ps)
271{
272 struct mv88e6xxx_priv_state *ps = (void *)_ps;
273
274 schedule_work(&ps->ppu_work);
275}
276
277static int mv88e6xxx_ppu_access_get(struct dsa_switch *ds)
278{
279 struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
280 int ret;
281
282 mutex_lock(&ps->ppu_mutex);
283
284 /*
285 * If the PHY polling unit is enabled, disable it so that
286 * we can access the PHY registers. If it was already
287 * disabled, cancel the timer that is going to re-enable
288 * it.
289 */
290 if (!ps->ppu_disabled) {
291 ret = mv88e6xxx_ppu_disable(ds);
292 if (ret < 0) {
293 mutex_unlock(&ps->ppu_mutex);
294 return ret;
295 }
296 ps->ppu_disabled = 1;
297 } else {
298 del_timer(&ps->ppu_timer);
299 ret = 0;
300 }
301
302 return ret;
303}
304
305static void mv88e6xxx_ppu_access_put(struct dsa_switch *ds)
306{
307 struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
308
309 /*
310 * Schedule a timer to re-enable the PHY polling unit.
311 */
312 mod_timer(&ps->ppu_timer, jiffies + msecs_to_jiffies(10));
313 mutex_unlock(&ps->ppu_mutex);
314}
315
316void mv88e6xxx_ppu_state_init(struct dsa_switch *ds)
317{
318 struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
319
320 mutex_init(&ps->ppu_mutex);
321 INIT_WORK(&ps->ppu_work, mv88e6xxx_ppu_reenable_work);
322 init_timer(&ps->ppu_timer);
323 ps->ppu_timer.data = (unsigned long)ps;
324 ps->ppu_timer.function = mv88e6xxx_ppu_reenable_timer;
325}
326
327int mv88e6xxx_phy_read_ppu(struct dsa_switch *ds, int addr, int regnum)
328{
329 int ret;
330
331 ret = mv88e6xxx_ppu_access_get(ds);
332 if (ret >= 0) {
333 ret = mv88e6xxx_reg_read(ds, addr, regnum);
334 mv88e6xxx_ppu_access_put(ds);
335 }
336
337 return ret;
338}
339
340int mv88e6xxx_phy_write_ppu(struct dsa_switch *ds, int addr,
341 int regnum, u16 val)
342{
343 int ret;
344
345 ret = mv88e6xxx_ppu_access_get(ds);
346 if (ret >= 0) {
347 ret = mv88e6xxx_reg_write(ds, addr, regnum, val);
348 mv88e6xxx_ppu_access_put(ds);
349 }
350
351 return ret;
352}
353#endif
354
355void mv88e6xxx_poll_link(struct dsa_switch *ds)
356{
357 int i;
358
359 for (i = 0; i < DSA_MAX_PORTS; i++) {
360 struct net_device *dev;
361 int port_status;
362 int link;
363 int speed;
364 int duplex;
365 int fc;
366
367 dev = ds->ports[i];
368 if (dev == NULL)
369 continue;
370
371 link = 0;
372 if (dev->flags & IFF_UP) {
373 port_status = mv88e6xxx_reg_read(ds, REG_PORT(i), 0x00);
374 if (port_status < 0)
375 continue;
376
377 link = !!(port_status & 0x0800);
378 }
379
380 if (!link) {
381 if (netif_carrier_ok(dev)) {
382 printk(KERN_INFO "%s: link down\n", dev->name);
383 netif_carrier_off(dev);
384 }
385 continue;
386 }
387
388 switch (port_status & 0x0300) {
389 case 0x0000:
390 speed = 10;
391 break;
392 case 0x0100:
393 speed = 100;
394 break;
395 case 0x0200:
396 speed = 1000;
397 break;
398 default:
399 speed = -1;
400 break;
401 }
402 duplex = (port_status & 0x0400) ? 1 : 0;
403 fc = (port_status & 0x8000) ? 1 : 0;
404
405 if (!netif_carrier_ok(dev)) {
406 printk(KERN_INFO "%s: link up, %d Mb/s, %s duplex, "
407 "flow control %sabled\n", dev->name,
408 speed, duplex ? "full" : "half",
409 fc ? "en" : "dis");
410 netif_carrier_on(dev);
411 }
412 }
413}
414
415static int mv88e6xxx_stats_wait(struct dsa_switch *ds)
416{
417 int ret;
418 int i;
419
420 for (i = 0; i < 10; i++) {
421 ret = REG_READ(REG_GLOBAL2, 0x1d);
422 if ((ret & 0x8000) == 0)
423 return 0;
424 }
425
426 return -ETIMEDOUT;
427}
428
429static int mv88e6xxx_stats_snapshot(struct dsa_switch *ds, int port)
430{
431 int ret;
432
433 /*
434 * Snapshot the hardware statistics counters for this port.
435 */
436 REG_WRITE(REG_GLOBAL, 0x1d, 0xdc00 | port);
437
438 /*
439 * Wait for the snapshotting to complete.
440 */
441 ret = mv88e6xxx_stats_wait(ds);
442 if (ret < 0)
443 return ret;
444
445 return 0;
446}
447
448static void mv88e6xxx_stats_read(struct dsa_switch *ds, int stat, u32 *val)
449{
450 u32 _val;
451 int ret;
452
453 *val = 0;
454
455 ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, 0x1d, 0xcc00 | stat);
456 if (ret < 0)
457 return;
458
459 ret = mv88e6xxx_stats_wait(ds);
460 if (ret < 0)
461 return;
462
463 ret = mv88e6xxx_reg_read(ds, REG_GLOBAL, 0x1e);
464 if (ret < 0)
465 return;
466
467 _val = ret << 16;
468
469 ret = mv88e6xxx_reg_read(ds, REG_GLOBAL, 0x1f);
470 if (ret < 0)
471 return;
472
473 *val = _val | ret;
474}
475
476void mv88e6xxx_get_strings(struct dsa_switch *ds,
477 int nr_stats, struct mv88e6xxx_hw_stat *stats,
478 int port, uint8_t *data)
479{
480 int i;
481
482 for (i = 0; i < nr_stats; i++) {
483 memcpy(data + i * ETH_GSTRING_LEN,
484 stats[i].string, ETH_GSTRING_LEN);
485 }
486}
487
488void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds,
489 int nr_stats, struct mv88e6xxx_hw_stat *stats,
490 int port, uint64_t *data)
491{
492 struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
493 int ret;
494 int i;
495
496 mutex_lock(&ps->stats_mutex);
497
498 ret = mv88e6xxx_stats_snapshot(ds, port);
499 if (ret < 0) {
500 mutex_unlock(&ps->stats_mutex);
501 return;
502 }
503
504 /*
505 * Read each of the counters.
506 */
507 for (i = 0; i < nr_stats; i++) {
508 struct mv88e6xxx_hw_stat *s = stats + i;
509 u32 low;
510 u32 high;
511
512 mv88e6xxx_stats_read(ds, s->reg, &low);
513 if (s->sizeof_stat == 8)
514 mv88e6xxx_stats_read(ds, s->reg + 1, &high);
515 else
516 high = 0;
517
518 data[i] = (((u64)high) << 32) | low;
519 }
520
521 mutex_unlock(&ps->stats_mutex);
522}
diff --git a/net/dsa/mv88e6xxx.h b/net/dsa/mv88e6xxx.h
new file mode 100644
index 000000000000..eb0e0aaa9f1b
--- /dev/null
+++ b/net/dsa/mv88e6xxx.h
@@ -0,0 +1,93 @@
1/*
2 * net/dsa/mv88e6xxx.h - Marvell 88e6xxx switch chip support
3 * Copyright (c) 2008 Marvell Semiconductor
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 */
10
11#ifndef __MV88E6XXX_H
12#define __MV88E6XXX_H
13
14#define REG_PORT(p) (0x10 + (p))
15#define REG_GLOBAL 0x1b
16#define REG_GLOBAL2 0x1c
17
18struct mv88e6xxx_priv_state {
19 /*
20 * When using multi-chip addressing, this mutex protects
21 * access to the indirect access registers. (In single-chip
22 * mode, this mutex is effectively useless.)
23 */
24 struct mutex smi_mutex;
25
26#ifdef CONFIG_NET_DSA_MV88E6XXX_NEED_PPU
27 /*
28 * Handles automatic disabling and re-enabling of the PHY
29 * polling unit.
30 */
31 struct mutex ppu_mutex;
32 int ppu_disabled;
33 struct work_struct ppu_work;
34 struct timer_list ppu_timer;
35#endif
36
37 /*
38 * This mutex serialises access to the statistics unit.
39 * Hold this mutex over snapshot + dump sequences.
40 */
41 struct mutex stats_mutex;
42};
43
44struct mv88e6xxx_hw_stat {
45 char string[ETH_GSTRING_LEN];
46 int sizeof_stat;
47 int reg;
48};
49
50int __mv88e6xxx_reg_read(struct mii_bus *bus, int sw_addr, int addr, int reg);
51int mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg);
52int __mv88e6xxx_reg_write(struct mii_bus *bus, int sw_addr, int addr,
53 int reg, u16 val);
54int mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, u16 val);
55int mv88e6xxx_config_prio(struct dsa_switch *ds);
56int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr);
57int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr);
58int mv88e6xxx_phy_read(struct dsa_switch *ds, int addr, int regnum);
59int mv88e6xxx_phy_write(struct dsa_switch *ds, int addr, int regnum, u16 val);
60void mv88e6xxx_ppu_state_init(struct dsa_switch *ds);
61int mv88e6xxx_phy_read_ppu(struct dsa_switch *ds, int addr, int regnum);
62int mv88e6xxx_phy_write_ppu(struct dsa_switch *ds, int addr,
63 int regnum, u16 val);
64void mv88e6xxx_poll_link(struct dsa_switch *ds);
65void mv88e6xxx_get_strings(struct dsa_switch *ds,
66 int nr_stats, struct mv88e6xxx_hw_stat *stats,
67 int port, uint8_t *data);
68void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds,
69 int nr_stats, struct mv88e6xxx_hw_stat *stats,
70 int port, uint64_t *data);
71
72#define REG_READ(addr, reg) \
73 ({ \
74 int __ret; \
75 \
76 __ret = mv88e6xxx_reg_read(ds, addr, reg); \
77 if (__ret < 0) \
78 return __ret; \
79 __ret; \
80 })
81
82#define REG_WRITE(addr, reg, val) \
83 ({ \
84 int __ret; \
85 \
86 __ret = mv88e6xxx_reg_write(ds, addr, reg, val); \
87 if (__ret < 0) \
88 return __ret; \
89 })
90
91
92
93#endif
diff --git a/net/dsa/slave.c b/net/dsa/slave.c
new file mode 100644
index 000000000000..37616884b8a9
--- /dev/null
+++ b/net/dsa/slave.c
@@ -0,0 +1,298 @@
1/*
2 * net/dsa/slave.c - Slave device handling
3 * Copyright (c) 2008 Marvell Semiconductor
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 */
10
11#include <linux/list.h>
12#include <linux/netdevice.h>
13#include <linux/phy.h>
14#include "dsa_priv.h"
15
16/* slave mii_bus handling ***************************************************/
17static int dsa_slave_phy_read(struct mii_bus *bus, int addr, int reg)
18{
19 struct dsa_switch *ds = bus->priv;
20
21 if (ds->valid_port_mask & (1 << addr))
22 return ds->drv->phy_read(ds, addr, reg);
23
24 return 0xffff;
25}
26
27static int dsa_slave_phy_write(struct mii_bus *bus, int addr, int reg, u16 val)
28{
29 struct dsa_switch *ds = bus->priv;
30
31 if (ds->valid_port_mask & (1 << addr))
32 return ds->drv->phy_write(ds, addr, reg, val);
33
34 return 0;
35}
36
37void dsa_slave_mii_bus_init(struct dsa_switch *ds)
38{
39 ds->slave_mii_bus->priv = (void *)ds;
40 ds->slave_mii_bus->name = "dsa slave smi";
41 ds->slave_mii_bus->read = dsa_slave_phy_read;
42 ds->slave_mii_bus->write = dsa_slave_phy_write;
43 snprintf(ds->slave_mii_bus->id, MII_BUS_ID_SIZE, "%s:%.2x",
44 ds->master_mii_bus->id, ds->pd->sw_addr);
45 ds->slave_mii_bus->parent = &(ds->master_mii_bus->dev);
46}
47
48
49/* slave device handling ****************************************************/
50static int dsa_slave_open(struct net_device *dev)
51{
52 return 0;
53}
54
55static int dsa_slave_close(struct net_device *dev)
56{
57 return 0;
58}
59
60static void dsa_slave_change_rx_flags(struct net_device *dev, int change)
61{
62 struct dsa_slave_priv *p = netdev_priv(dev);
63 struct net_device *master = p->parent->master_netdev;
64
65 if (change & IFF_ALLMULTI)
66 dev_set_allmulti(master, dev->flags & IFF_ALLMULTI ? 1 : -1);
67 if (change & IFF_PROMISC)
68 dev_set_promiscuity(master, dev->flags & IFF_PROMISC ? 1 : -1);
69}
70
71static void dsa_slave_set_rx_mode(struct net_device *dev)
72{
73 struct dsa_slave_priv *p = netdev_priv(dev);
74 struct net_device *master = p->parent->master_netdev;
75
76 dev_mc_sync(master, dev);
77 dev_unicast_sync(master, dev);
78}
79
80static int dsa_slave_set_mac_address(struct net_device *dev, void *addr)
81{
82 memcpy(dev->dev_addr, addr + 2, 6);
83
84 return 0;
85}
86
87static int dsa_slave_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
88{
89 struct dsa_slave_priv *p = netdev_priv(dev);
90 struct mii_ioctl_data *mii_data = if_mii(ifr);
91
92 if (p->phy != NULL)
93 return phy_mii_ioctl(p->phy, mii_data, cmd);
94
95 return -EOPNOTSUPP;
96}
97
98
99/* ethtool operations *******************************************************/
100static int
101dsa_slave_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
102{
103 struct dsa_slave_priv *p = netdev_priv(dev);
104 int err;
105
106 err = -EOPNOTSUPP;
107 if (p->phy != NULL) {
108 err = phy_read_status(p->phy);
109 if (err == 0)
110 err = phy_ethtool_gset(p->phy, cmd);
111 }
112
113 return err;
114}
115
116static int
117dsa_slave_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
118{
119 struct dsa_slave_priv *p = netdev_priv(dev);
120
121 if (p->phy != NULL)
122 return phy_ethtool_sset(p->phy, cmd);
123
124 return -EOPNOTSUPP;
125}
126
127static void dsa_slave_get_drvinfo(struct net_device *dev,
128 struct ethtool_drvinfo *drvinfo)
129{
130 strncpy(drvinfo->driver, "dsa", 32);
131 strncpy(drvinfo->version, dsa_driver_version, 32);
132 strncpy(drvinfo->fw_version, "N/A", 32);
133 strncpy(drvinfo->bus_info, "platform", 32);
134}
135
136static int dsa_slave_nway_reset(struct net_device *dev)
137{
138 struct dsa_slave_priv *p = netdev_priv(dev);
139
140 if (p->phy != NULL)
141 return genphy_restart_aneg(p->phy);
142
143 return -EOPNOTSUPP;
144}
145
146static u32 dsa_slave_get_link(struct net_device *dev)
147{
148 struct dsa_slave_priv *p = netdev_priv(dev);
149
150 if (p->phy != NULL) {
151 genphy_update_link(p->phy);
152 return p->phy->link;
153 }
154
155 return -EOPNOTSUPP;
156}
157
158static void dsa_slave_get_strings(struct net_device *dev,
159 uint32_t stringset, uint8_t *data)
160{
161 struct dsa_slave_priv *p = netdev_priv(dev);
162 struct dsa_switch *ds = p->parent;
163
164 if (stringset == ETH_SS_STATS) {
165 int len = ETH_GSTRING_LEN;
166
167 strncpy(data, "tx_packets", len);
168 strncpy(data + len, "tx_bytes", len);
169 strncpy(data + 2 * len, "rx_packets", len);
170 strncpy(data + 3 * len, "rx_bytes", len);
171 if (ds->drv->get_strings != NULL)
172 ds->drv->get_strings(ds, p->port, data + 4 * len);
173 }
174}
175
176static void dsa_slave_get_ethtool_stats(struct net_device *dev,
177 struct ethtool_stats *stats,
178 uint64_t *data)
179{
180 struct dsa_slave_priv *p = netdev_priv(dev);
181 struct dsa_switch *ds = p->parent;
182
183 data[0] = p->dev->stats.tx_packets;
184 data[1] = p->dev->stats.tx_bytes;
185 data[2] = p->dev->stats.rx_packets;
186 data[3] = p->dev->stats.rx_bytes;
187 if (ds->drv->get_ethtool_stats != NULL)
188 ds->drv->get_ethtool_stats(ds, p->port, data + 4);
189}
190
191static int dsa_slave_get_sset_count(struct net_device *dev, int sset)
192{
193 struct dsa_slave_priv *p = netdev_priv(dev);
194 struct dsa_switch *ds = p->parent;
195
196 if (sset == ETH_SS_STATS) {
197 int count;
198
199 count = 4;
200 if (ds->drv->get_sset_count != NULL)
201 count += ds->drv->get_sset_count(ds);
202
203 return count;
204 }
205
206 return -EOPNOTSUPP;
207}
208
209static const struct ethtool_ops dsa_slave_ethtool_ops = {
210 .get_settings = dsa_slave_get_settings,
211 .set_settings = dsa_slave_set_settings,
212 .get_drvinfo = dsa_slave_get_drvinfo,
213 .nway_reset = dsa_slave_nway_reset,
214 .get_link = dsa_slave_get_link,
215 .set_sg = ethtool_op_set_sg,
216 .get_strings = dsa_slave_get_strings,
217 .get_ethtool_stats = dsa_slave_get_ethtool_stats,
218 .get_sset_count = dsa_slave_get_sset_count,
219};
220
221
222/* slave device setup *******************************************************/
223struct net_device *
224dsa_slave_create(struct dsa_switch *ds, struct device *parent,
225 int port, char *name)
226{
227 struct net_device *master = ds->master_netdev;
228 struct net_device *slave_dev;
229 struct dsa_slave_priv *p;
230 int ret;
231
232 slave_dev = alloc_netdev(sizeof(struct dsa_slave_priv),
233 name, ether_setup);
234 if (slave_dev == NULL)
235 return slave_dev;
236
237 slave_dev->features = master->vlan_features;
238 SET_ETHTOOL_OPS(slave_dev, &dsa_slave_ethtool_ops);
239 memcpy(slave_dev->dev_addr, master->dev_addr, ETH_ALEN);
240 slave_dev->tx_queue_len = 0;
241 switch (ds->tag_protocol) {
242#ifdef CONFIG_NET_DSA_TAG_DSA
243 case htons(ETH_P_DSA):
244 slave_dev->hard_start_xmit = dsa_xmit;
245 break;
246#endif
247#ifdef CONFIG_NET_DSA_TAG_EDSA
248 case htons(ETH_P_EDSA):
249 slave_dev->hard_start_xmit = edsa_xmit;
250 break;
251#endif
252#ifdef CONFIG_NET_DSA_TAG_TRAILER
253 case htons(ETH_P_TRAILER):
254 slave_dev->hard_start_xmit = trailer_xmit;
255 break;
256#endif
257 default:
258 BUG();
259 }
260 slave_dev->open = dsa_slave_open;
261 slave_dev->stop = dsa_slave_close;
262 slave_dev->change_rx_flags = dsa_slave_change_rx_flags;
263 slave_dev->set_rx_mode = dsa_slave_set_rx_mode;
264 slave_dev->set_multicast_list = dsa_slave_set_rx_mode;
265 slave_dev->set_mac_address = dsa_slave_set_mac_address;
266 slave_dev->do_ioctl = dsa_slave_ioctl;
267 SET_NETDEV_DEV(slave_dev, parent);
268 slave_dev->vlan_features = master->vlan_features;
269
270 p = netdev_priv(slave_dev);
271 p->dev = slave_dev;
272 p->parent = ds;
273 p->port = port;
274 p->phy = ds->slave_mii_bus->phy_map[port];
275
276 ret = register_netdev(slave_dev);
277 if (ret) {
278 printk(KERN_ERR "%s: error %d registering interface %s\n",
279 master->name, ret, slave_dev->name);
280 free_netdev(slave_dev);
281 return NULL;
282 }
283
284 netif_carrier_off(slave_dev);
285
286 if (p->phy != NULL) {
287 phy_attach(slave_dev, p->phy->dev.bus_id,
288 0, PHY_INTERFACE_MODE_GMII);
289
290 p->phy->autoneg = AUTONEG_ENABLE;
291 p->phy->speed = 0;
292 p->phy->duplex = 0;
293 p->phy->advertising = p->phy->supported | ADVERTISED_Autoneg;
294 phy_start_aneg(p->phy);
295 }
296
297 return slave_dev;
298}
diff --git a/net/dsa/tag_dsa.c b/net/dsa/tag_dsa.c
new file mode 100644
index 000000000000..bdc0510b53b7
--- /dev/null
+++ b/net/dsa/tag_dsa.c
@@ -0,0 +1,194 @@
1/*
2 * net/dsa/tag_dsa.c - (Non-ethertype) DSA tagging
3 * Copyright (c) 2008 Marvell Semiconductor
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 */
10
11#include <linux/etherdevice.h>
12#include <linux/list.h>
13#include <linux/netdevice.h>
14#include "dsa_priv.h"
15
16#define DSA_HLEN 4
17
18int dsa_xmit(struct sk_buff *skb, struct net_device *dev)
19{
20 struct dsa_slave_priv *p = netdev_priv(dev);
21 u8 *dsa_header;
22
23 dev->stats.tx_packets++;
24 dev->stats.tx_bytes += skb->len;
25
26 /*
27 * Convert the outermost 802.1q tag to a DSA tag for tagged
28 * packets, or insert a DSA tag between the addresses and
29 * the ethertype field for untagged packets.
30 */
31 if (skb->protocol == htons(ETH_P_8021Q)) {
32 if (skb_cow_head(skb, 0) < 0)
33 goto out_free;
34
35 /*
36 * Construct tagged FROM_CPU DSA tag from 802.1q tag.
37 */
38 dsa_header = skb->data + 2 * ETH_ALEN;
39 dsa_header[0] = 0x60;
40 dsa_header[1] = p->port << 3;
41
42 /*
43 * Move CFI field from byte 2 to byte 1.
44 */
45 if (dsa_header[2] & 0x10) {
46 dsa_header[1] |= 0x01;
47 dsa_header[2] &= ~0x10;
48 }
49 } else {
50 if (skb_cow_head(skb, DSA_HLEN) < 0)
51 goto out_free;
52 skb_push(skb, DSA_HLEN);
53
54 memmove(skb->data, skb->data + DSA_HLEN, 2 * ETH_ALEN);
55
56 /*
57 * Construct untagged FROM_CPU DSA tag.
58 */
59 dsa_header = skb->data + 2 * ETH_ALEN;
60 dsa_header[0] = 0x40;
61 dsa_header[1] = p->port << 3;
62 dsa_header[2] = 0x00;
63 dsa_header[3] = 0x00;
64 }
65
66 skb->protocol = htons(ETH_P_DSA);
67
68 skb->dev = p->parent->master_netdev;
69 dev_queue_xmit(skb);
70
71 return NETDEV_TX_OK;
72
73out_free:
74 kfree_skb(skb);
75 return NETDEV_TX_OK;
76}
77
78static int dsa_rcv(struct sk_buff *skb, struct net_device *dev,
79 struct packet_type *pt, struct net_device *orig_dev)
80{
81 struct dsa_switch *ds = dev->dsa_ptr;
82 u8 *dsa_header;
83 int source_port;
84
85 if (unlikely(ds == NULL))
86 goto out_drop;
87
88 skb = skb_unshare(skb, GFP_ATOMIC);
89 if (skb == NULL)
90 goto out;
91
92 if (unlikely(!pskb_may_pull(skb, DSA_HLEN)))
93 goto out_drop;
94
95 /*
96 * The ethertype field is part of the DSA header.
97 */
98 dsa_header = skb->data - 2;
99
100 /*
101 * Check that frame type is either TO_CPU or FORWARD, and
102 * that the source device is zero.
103 */
104 if ((dsa_header[0] & 0xdf) != 0x00 && (dsa_header[0] & 0xdf) != 0xc0)
105 goto out_drop;
106
107 /*
108 * Check that the source port is a registered DSA port.
109 */
110 source_port = (dsa_header[1] >> 3) & 0x1f;
111 if (source_port >= DSA_MAX_PORTS || ds->ports[source_port] == NULL)
112 goto out_drop;
113
114 /*
115 * Convert the DSA header to an 802.1q header if the 'tagged'
116 * bit in the DSA header is set. If the 'tagged' bit is clear,
117 * delete the DSA header entirely.
118 */
119 if (dsa_header[0] & 0x20) {
120 u8 new_header[4];
121
122 /*
123 * Insert 802.1q ethertype and copy the VLAN-related
124 * fields, but clear the bit that will hold CFI (since
125 * DSA uses that bit location for another purpose).
126 */
127 new_header[0] = (ETH_P_8021Q >> 8) & 0xff;
128 new_header[1] = ETH_P_8021Q & 0xff;
129 new_header[2] = dsa_header[2] & ~0x10;
130 new_header[3] = dsa_header[3];
131
132 /*
133 * Move CFI bit from its place in the DSA header to
134 * its 802.1q-designated place.
135 */
136 if (dsa_header[1] & 0x01)
137 new_header[2] |= 0x10;
138
139 /*
140 * Update packet checksum if skb is CHECKSUM_COMPLETE.
141 */
142 if (skb->ip_summed == CHECKSUM_COMPLETE) {
143 __wsum c = skb->csum;
144 c = csum_add(c, csum_partial(new_header + 2, 2, 0));
145 c = csum_sub(c, csum_partial(dsa_header + 2, 2, 0));
146 skb->csum = c;
147 }
148
149 memcpy(dsa_header, new_header, DSA_HLEN);
150 } else {
151 /*
152 * Remove DSA tag and update checksum.
153 */
154 skb_pull_rcsum(skb, DSA_HLEN);
155 memmove(skb->data - ETH_HLEN,
156 skb->data - ETH_HLEN - DSA_HLEN,
157 2 * ETH_ALEN);
158 }
159
160 skb->dev = ds->ports[source_port];
161 skb_push(skb, ETH_HLEN);
162 skb->protocol = eth_type_trans(skb, skb->dev);
163
164 skb->dev->last_rx = jiffies;
165 skb->dev->stats.rx_packets++;
166 skb->dev->stats.rx_bytes += skb->len;
167
168 netif_receive_skb(skb);
169
170 return 0;
171
172out_drop:
173 kfree_skb(skb);
174out:
175 return 0;
176}
177
178static struct packet_type dsa_packet_type = {
179 .type = __constant_htons(ETH_P_DSA),
180 .func = dsa_rcv,
181};
182
183static int __init dsa_init_module(void)
184{
185 dev_add_pack(&dsa_packet_type);
186 return 0;
187}
188module_init(dsa_init_module);
189
190static void __exit dsa_cleanup_module(void)
191{
192 dev_remove_pack(&dsa_packet_type);
193}
194module_exit(dsa_cleanup_module);
diff --git a/net/dsa/tag_edsa.c b/net/dsa/tag_edsa.c
new file mode 100644
index 000000000000..f985ea993843
--- /dev/null
+++ b/net/dsa/tag_edsa.c
@@ -0,0 +1,213 @@
1/*
2 * net/dsa/tag_edsa.c - Ethertype DSA tagging
3 * Copyright (c) 2008 Marvell Semiconductor
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 */
10
11#include <linux/etherdevice.h>
12#include <linux/list.h>
13#include <linux/netdevice.h>
14#include "dsa_priv.h"
15
16#define DSA_HLEN 4
17#define EDSA_HLEN 8
18
19int edsa_xmit(struct sk_buff *skb, struct net_device *dev)
20{
21 struct dsa_slave_priv *p = netdev_priv(dev);
22 u8 *edsa_header;
23
24 dev->stats.tx_packets++;
25 dev->stats.tx_bytes += skb->len;
26
27 /*
28 * Convert the outermost 802.1q tag to a DSA tag and prepend
29 * a DSA ethertype field is the packet is tagged, or insert
30 * a DSA ethertype plus DSA tag between the addresses and the
31 * current ethertype field if the packet is untagged.
32 */
33 if (skb->protocol == htons(ETH_P_8021Q)) {
34 if (skb_cow_head(skb, DSA_HLEN) < 0)
35 goto out_free;
36 skb_push(skb, DSA_HLEN);
37
38 memmove(skb->data, skb->data + DSA_HLEN, 2 * ETH_ALEN);
39
40 /*
41 * Construct tagged FROM_CPU DSA tag from 802.1q tag.
42 */
43 edsa_header = skb->data + 2 * ETH_ALEN;
44 edsa_header[0] = (ETH_P_EDSA >> 8) & 0xff;
45 edsa_header[1] = ETH_P_EDSA & 0xff;
46 edsa_header[2] = 0x00;
47 edsa_header[3] = 0x00;
48 edsa_header[4] = 0x60;
49 edsa_header[5] = p->port << 3;
50
51 /*
52 * Move CFI field from byte 6 to byte 5.
53 */
54 if (edsa_header[6] & 0x10) {
55 edsa_header[5] |= 0x01;
56 edsa_header[6] &= ~0x10;
57 }
58 } else {
59 if (skb_cow_head(skb, EDSA_HLEN) < 0)
60 goto out_free;
61 skb_push(skb, EDSA_HLEN);
62
63 memmove(skb->data, skb->data + EDSA_HLEN, 2 * ETH_ALEN);
64
65 /*
66 * Construct untagged FROM_CPU DSA tag.
67 */
68 edsa_header = skb->data + 2 * ETH_ALEN;
69 edsa_header[0] = (ETH_P_EDSA >> 8) & 0xff;
70 edsa_header[1] = ETH_P_EDSA & 0xff;
71 edsa_header[2] = 0x00;
72 edsa_header[3] = 0x00;
73 edsa_header[4] = 0x40;
74 edsa_header[5] = p->port << 3;
75 edsa_header[6] = 0x00;
76 edsa_header[7] = 0x00;
77 }
78
79 skb->protocol = htons(ETH_P_EDSA);
80
81 skb->dev = p->parent->master_netdev;
82 dev_queue_xmit(skb);
83
84 return NETDEV_TX_OK;
85
86out_free:
87 kfree_skb(skb);
88 return NETDEV_TX_OK;
89}
90
91static int edsa_rcv(struct sk_buff *skb, struct net_device *dev,
92 struct packet_type *pt, struct net_device *orig_dev)
93{
94 struct dsa_switch *ds = dev->dsa_ptr;
95 u8 *edsa_header;
96 int source_port;
97
98 if (unlikely(ds == NULL))
99 goto out_drop;
100
101 skb = skb_unshare(skb, GFP_ATOMIC);
102 if (skb == NULL)
103 goto out;
104
105 if (unlikely(!pskb_may_pull(skb, EDSA_HLEN)))
106 goto out_drop;
107
108 /*
109 * Skip the two null bytes after the ethertype.
110 */
111 edsa_header = skb->data + 2;
112
113 /*
114 * Check that frame type is either TO_CPU or FORWARD, and
115 * that the source device is zero.
116 */
117 if ((edsa_header[0] & 0xdf) != 0x00 && (edsa_header[0] & 0xdf) != 0xc0)
118 goto out_drop;
119
120 /*
121 * Check that the source port is a registered DSA port.
122 */
123 source_port = (edsa_header[1] >> 3) & 0x1f;
124 if (source_port >= DSA_MAX_PORTS || ds->ports[source_port] == NULL)
125 goto out_drop;
126
127 /*
128 * If the 'tagged' bit is set, convert the DSA tag to a 802.1q
129 * tag and delete the ethertype part. If the 'tagged' bit is
130 * clear, delete the ethertype and the DSA tag parts.
131 */
132 if (edsa_header[0] & 0x20) {
133 u8 new_header[4];
134
135 /*
136 * Insert 802.1q ethertype and copy the VLAN-related
137 * fields, but clear the bit that will hold CFI (since
138 * DSA uses that bit location for another purpose).
139 */
140 new_header[0] = (ETH_P_8021Q >> 8) & 0xff;
141 new_header[1] = ETH_P_8021Q & 0xff;
142 new_header[2] = edsa_header[2] & ~0x10;
143 new_header[3] = edsa_header[3];
144
145 /*
146 * Move CFI bit from its place in the DSA header to
147 * its 802.1q-designated place.
148 */
149 if (edsa_header[1] & 0x01)
150 new_header[2] |= 0x10;
151
152 skb_pull_rcsum(skb, DSA_HLEN);
153
154 /*
155 * Update packet checksum if skb is CHECKSUM_COMPLETE.
156 */
157 if (skb->ip_summed == CHECKSUM_COMPLETE) {
158 __wsum c = skb->csum;
159 c = csum_add(c, csum_partial(new_header + 2, 2, 0));
160 c = csum_sub(c, csum_partial(edsa_header + 2, 2, 0));
161 skb->csum = c;
162 }
163
164 memcpy(edsa_header, new_header, DSA_HLEN);
165
166 memmove(skb->data - ETH_HLEN,
167 skb->data - ETH_HLEN - DSA_HLEN,
168 2 * ETH_ALEN);
169 } else {
170 /*
171 * Remove DSA tag and update checksum.
172 */
173 skb_pull_rcsum(skb, EDSA_HLEN);
174 memmove(skb->data - ETH_HLEN,
175 skb->data - ETH_HLEN - EDSA_HLEN,
176 2 * ETH_ALEN);
177 }
178
179 skb->dev = ds->ports[source_port];
180 skb_push(skb, ETH_HLEN);
181 skb->protocol = eth_type_trans(skb, skb->dev);
182
183 skb->dev->last_rx = jiffies;
184 skb->dev->stats.rx_packets++;
185 skb->dev->stats.rx_bytes += skb->len;
186
187 netif_receive_skb(skb);
188
189 return 0;
190
191out_drop:
192 kfree_skb(skb);
193out:
194 return 0;
195}
196
197static struct packet_type edsa_packet_type = {
198 .type = __constant_htons(ETH_P_EDSA),
199 .func = edsa_rcv,
200};
201
202static int __init edsa_init_module(void)
203{
204 dev_add_pack(&edsa_packet_type);
205 return 0;
206}
207module_init(edsa_init_module);
208
209static void __exit edsa_cleanup_module(void)
210{
211 dev_remove_pack(&edsa_packet_type);
212}
213module_exit(edsa_cleanup_module);
diff --git a/net/dsa/tag_trailer.c b/net/dsa/tag_trailer.c
new file mode 100644
index 000000000000..d3117764b2c2
--- /dev/null
+++ b/net/dsa/tag_trailer.c
@@ -0,0 +1,130 @@
1/*
2 * net/dsa/tag_trailer.c - Trailer tag format handling
3 * Copyright (c) 2008 Marvell Semiconductor
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 */
10
11#include <linux/etherdevice.h>
12#include <linux/list.h>
13#include <linux/netdevice.h>
14#include "dsa_priv.h"
15
16int trailer_xmit(struct sk_buff *skb, struct net_device *dev)
17{
18 struct dsa_slave_priv *p = netdev_priv(dev);
19 struct sk_buff *nskb;
20 int padlen;
21 u8 *trailer;
22
23 dev->stats.tx_packets++;
24 dev->stats.tx_bytes += skb->len;
25
26 /*
27 * We have to make sure that the trailer ends up as the very
28 * last 4 bytes of the packet. This means that we have to pad
29 * the packet to the minimum ethernet frame size, if necessary,
30 * before adding the trailer.
31 */
32 padlen = 0;
33 if (skb->len < 60)
34 padlen = 60 - skb->len;
35
36 nskb = alloc_skb(NET_IP_ALIGN + skb->len + padlen + 4, GFP_ATOMIC);
37 if (nskb == NULL) {
38 kfree_skb(skb);
39 return NETDEV_TX_OK;
40 }
41 skb_reserve(nskb, NET_IP_ALIGN);
42
43 skb_reset_mac_header(nskb);
44 skb_set_network_header(nskb, skb_network_header(skb) - skb->head);
45 skb_set_transport_header(nskb, skb_transport_header(skb) - skb->head);
46 skb_copy_and_csum_dev(skb, skb_put(nskb, skb->len));
47 kfree_skb(skb);
48
49 if (padlen) {
50 u8 *pad = skb_put(nskb, padlen);
51 memset(pad, 0, padlen);
52 }
53
54 trailer = skb_put(nskb, 4);
55 trailer[0] = 0x80;
56 trailer[1] = 1 << p->port;
57 trailer[2] = 0x10;
58 trailer[3] = 0x00;
59
60 nskb->protocol = htons(ETH_P_TRAILER);
61
62 nskb->dev = p->parent->master_netdev;
63 dev_queue_xmit(nskb);
64
65 return NETDEV_TX_OK;
66}
67
68static int trailer_rcv(struct sk_buff *skb, struct net_device *dev,
69 struct packet_type *pt, struct net_device *orig_dev)
70{
71 struct dsa_switch *ds = dev->dsa_ptr;
72 u8 *trailer;
73 int source_port;
74
75 if (unlikely(ds == NULL))
76 goto out_drop;
77
78 skb = skb_unshare(skb, GFP_ATOMIC);
79 if (skb == NULL)
80 goto out;
81
82 if (skb_linearize(skb))
83 goto out_drop;
84
85 trailer = skb_tail_pointer(skb) - 4;
86 if (trailer[0] != 0x80 || (trailer[1] & 0xf8) != 0x00 ||
87 (trailer[3] & 0xef) != 0x00 || trailer[3] != 0x00)
88 goto out_drop;
89
90 source_port = trailer[1] & 7;
91 if (source_port >= DSA_MAX_PORTS || ds->ports[source_port] == NULL)
92 goto out_drop;
93
94 pskb_trim_rcsum(skb, skb->len - 4);
95
96 skb->dev = ds->ports[source_port];
97 skb_push(skb, ETH_HLEN);
98 skb->protocol = eth_type_trans(skb, skb->dev);
99
100 skb->dev->last_rx = jiffies;
101 skb->dev->stats.rx_packets++;
102 skb->dev->stats.rx_bytes += skb->len;
103
104 netif_receive_skb(skb);
105
106 return 0;
107
108out_drop:
109 kfree_skb(skb);
110out:
111 return 0;
112}
113
114static struct packet_type trailer_packet_type = {
115 .type = __constant_htons(ETH_P_TRAILER),
116 .func = trailer_rcv,
117};
118
119static int __init trailer_init_module(void)
120{
121 dev_add_pack(&trailer_packet_type);
122 return 0;
123}
124module_init(trailer_init_module);
125
126static void __exit trailer_cleanup_module(void)
127{
128 dev_remove_pack(&trailer_packet_type);
129}
130module_exit(trailer_cleanup_module);
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index a80839b02e3f..b9d85af2dd31 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -57,6 +57,7 @@
57#include <net/sock.h> 57#include <net/sock.h>
58#include <net/ipv6.h> 58#include <net/ipv6.h>
59#include <net/ip.h> 59#include <net/ip.h>
60#include <net/dsa.h>
60#include <asm/uaccess.h> 61#include <asm/uaccess.h>
61#include <asm/system.h> 62#include <asm/system.h>
62 63
@@ -129,7 +130,7 @@ int eth_rebuild_header(struct sk_buff *skb)
129 130
130 switch (eth->h_proto) { 131 switch (eth->h_proto) {
131#ifdef CONFIG_INET 132#ifdef CONFIG_INET
132 case __constant_htons(ETH_P_IP): 133 case htons(ETH_P_IP):
133 return arp_find(eth->h_dest, skb); 134 return arp_find(eth->h_dest, skb);
134#endif 135#endif
135 default: 136 default:
@@ -184,6 +185,17 @@ __be16 eth_type_trans(struct sk_buff *skb, struct net_device *dev)
184 skb->pkt_type = PACKET_OTHERHOST; 185 skb->pkt_type = PACKET_OTHERHOST;
185 } 186 }
186 187
188 /*
189 * Some variants of DSA tagging don't have an ethertype field
190 * at all, so we check here whether one of those tagging
191 * variants has been configured on the receiving interface,
192 * and if so, set skb->protocol without looking at the packet.
193 */
194 if (netdev_uses_dsa_tags(dev))
195 return htons(ETH_P_DSA);
196 if (netdev_uses_trailer_tags(dev))
197 return htons(ETH_P_TRAILER);
198
187 if (ntohs(eth->h_proto) >= 1536) 199 if (ntohs(eth->h_proto) >= 1536)
188 return eth->h_proto; 200 return eth->h_proto;
189 201
diff --git a/net/ieee80211/ieee80211_module.c b/net/ieee80211/ieee80211_module.c
index 3bca97f55d47..949772a5a7dc 100644
--- a/net/ieee80211/ieee80211_module.c
+++ b/net/ieee80211/ieee80211_module.c
@@ -157,7 +157,7 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
157 err = ieee80211_networks_allocate(ieee); 157 err = ieee80211_networks_allocate(ieee);
158 if (err) { 158 if (err) {
159 IEEE80211_ERROR("Unable to allocate beacon storage: %d\n", err); 159 IEEE80211_ERROR("Unable to allocate beacon storage: %d\n", err);
160 goto failed; 160 goto failed_free_netdev;
161 } 161 }
162 ieee80211_networks_initialize(ieee); 162 ieee80211_networks_initialize(ieee);
163 163
@@ -193,9 +193,9 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
193 193
194 return dev; 194 return dev;
195 195
196 failed: 196failed_free_netdev:
197 if (dev) 197 free_netdev(dev);
198 free_netdev(dev); 198failed:
199 return NULL; 199 return NULL;
200} 200}
201 201
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index 591ea23639ca..691268f3a359 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -630,5 +630,3 @@ config TCP_MD5SIG
630 630
631 If unsure, say N. 631 If unsure, say N.
632 632
633source "net/ipv4/ipvs/Kconfig"
634
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index ad40ef3f9ebc..80ff87ce43aa 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -33,7 +33,6 @@ obj-$(CONFIG_INET_XFRM_MODE_TRANSPORT) += xfrm4_mode_transport.o
33obj-$(CONFIG_INET_XFRM_MODE_TUNNEL) += xfrm4_mode_tunnel.o 33obj-$(CONFIG_INET_XFRM_MODE_TUNNEL) += xfrm4_mode_tunnel.o
34obj-$(CONFIG_IP_PNP) += ipconfig.o 34obj-$(CONFIG_IP_PNP) += ipconfig.o
35obj-$(CONFIG_NETFILTER) += netfilter.o netfilter/ 35obj-$(CONFIG_NETFILTER) += netfilter.o netfilter/
36obj-$(CONFIG_IP_VS) += ipvs/
37obj-$(CONFIG_INET_DIAG) += inet_diag.o 36obj-$(CONFIG_INET_DIAG) += inet_diag.o
38obj-$(CONFIG_INET_TCP_DIAG) += tcp_diag.o 37obj-$(CONFIG_INET_TCP_DIAG) += tcp_diag.o
39obj-$(CONFIG_NET_TCPPROBE) += tcp_probe.o 38obj-$(CONFIG_NET_TCPPROBE) += tcp_probe.o
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 8a3ac1fa71a9..1fbff5fa4241 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -469,7 +469,7 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
469 */ 469 */
470 err = -EADDRNOTAVAIL; 470 err = -EADDRNOTAVAIL;
471 if (!sysctl_ip_nonlocal_bind && 471 if (!sysctl_ip_nonlocal_bind &&
472 !inet->freebind && 472 !(inet->freebind || inet->transparent) &&
473 addr->sin_addr.s_addr != htonl(INADDR_ANY) && 473 addr->sin_addr.s_addr != htonl(INADDR_ANY) &&
474 chk_addr_ret != RTN_LOCAL && 474 chk_addr_ret != RTN_LOCAL &&
475 chk_addr_ret != RTN_MULTICAST && 475 chk_addr_ret != RTN_MULTICAST &&
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 91d3d96805d0..b12dae2b0b2d 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1029,6 +1029,11 @@ skip:
1029 } 1029 }
1030} 1030}
1031 1031
1032static inline bool inetdev_valid_mtu(unsigned mtu)
1033{
1034 return mtu >= 68;
1035}
1036
1032/* Called only under RTNL semaphore */ 1037/* Called only under RTNL semaphore */
1033 1038
1034static int inetdev_event(struct notifier_block *this, unsigned long event, 1039static int inetdev_event(struct notifier_block *this, unsigned long event,
@@ -1048,6 +1053,10 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
1048 IN_DEV_CONF_SET(in_dev, NOXFRM, 1); 1053 IN_DEV_CONF_SET(in_dev, NOXFRM, 1);
1049 IN_DEV_CONF_SET(in_dev, NOPOLICY, 1); 1054 IN_DEV_CONF_SET(in_dev, NOPOLICY, 1);
1050 } 1055 }
1056 } else if (event == NETDEV_CHANGEMTU) {
1057 /* Re-enabling IP */
1058 if (inetdev_valid_mtu(dev->mtu))
1059 in_dev = inetdev_init(dev);
1051 } 1060 }
1052 goto out; 1061 goto out;
1053 } 1062 }
@@ -1058,7 +1067,7 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
1058 dev->ip_ptr = NULL; 1067 dev->ip_ptr = NULL;
1059 break; 1068 break;
1060 case NETDEV_UP: 1069 case NETDEV_UP:
1061 if (dev->mtu < 68) 1070 if (!inetdev_valid_mtu(dev->mtu))
1062 break; 1071 break;
1063 if (dev->flags & IFF_LOOPBACK) { 1072 if (dev->flags & IFF_LOOPBACK) {
1064 struct in_ifaddr *ifa; 1073 struct in_ifaddr *ifa;
@@ -1080,9 +1089,9 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
1080 ip_mc_down(in_dev); 1089 ip_mc_down(in_dev);
1081 break; 1090 break;
1082 case NETDEV_CHANGEMTU: 1091 case NETDEV_CHANGEMTU:
1083 if (dev->mtu >= 68) 1092 if (inetdev_valid_mtu(dev->mtu))
1084 break; 1093 break;
1085 /* MTU falled under 68, disable IP */ 1094 /* disable IP when MTU is not enough */
1086 case NETDEV_UNREGISTER: 1095 case NETDEV_UNREGISTER:
1087 inetdev_destroy(in_dev); 1096 inetdev_destroy(in_dev);
1088 break; 1097 break;
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index f70fac612596..7f9e337e3908 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -1234,6 +1234,7 @@ void ip_mc_inc_group(struct in_device *in_dev, __be32 addr)
1234 write_lock_bh(&in_dev->mc_list_lock); 1234 write_lock_bh(&in_dev->mc_list_lock);
1235 im->next=in_dev->mc_list; 1235 im->next=in_dev->mc_list;
1236 in_dev->mc_list=im; 1236 in_dev->mc_list=im;
1237 in_dev->mc_count++;
1237 write_unlock_bh(&in_dev->mc_list_lock); 1238 write_unlock_bh(&in_dev->mc_list_lock);
1238#ifdef CONFIG_IP_MULTICAST 1239#ifdef CONFIG_IP_MULTICAST
1239 igmpv3_del_delrec(in_dev, im->multiaddr); 1240 igmpv3_del_delrec(in_dev, im->multiaddr);
@@ -1282,6 +1283,7 @@ void ip_mc_dec_group(struct in_device *in_dev, __be32 addr)
1282 if (--i->users == 0) { 1283 if (--i->users == 0) {
1283 write_lock_bh(&in_dev->mc_list_lock); 1284 write_lock_bh(&in_dev->mc_list_lock);
1284 *ip = i->next; 1285 *ip = i->next;
1286 in_dev->mc_count--;
1285 write_unlock_bh(&in_dev->mc_list_lock); 1287 write_unlock_bh(&in_dev->mc_list_lock);
1286 igmp_group_dropped(i); 1288 igmp_group_dropped(i);
1287 1289
@@ -1330,6 +1332,7 @@ void ip_mc_init_dev(struct in_device *in_dev)
1330 setup_timer(&in_dev->mr_gq_timer, igmp_gq_timer_expire, 1332 setup_timer(&in_dev->mr_gq_timer, igmp_gq_timer_expire,
1331 (unsigned long)in_dev); 1333 (unsigned long)in_dev);
1332 in_dev->mr_ifc_count = 0; 1334 in_dev->mr_ifc_count = 0;
1335 in_dev->mc_count = 0;
1333 setup_timer(&in_dev->mr_ifc_timer, igmp_ifc_timer_expire, 1336 setup_timer(&in_dev->mr_ifc_timer, igmp_ifc_timer_expire,
1334 (unsigned long)in_dev); 1337 (unsigned long)in_dev);
1335 in_dev->mr_qrv = IGMP_Unsolicited_Report_Count; 1338 in_dev->mr_qrv = IGMP_Unsolicited_Report_Count;
@@ -1369,8 +1372,8 @@ void ip_mc_destroy_dev(struct in_device *in_dev)
1369 write_lock_bh(&in_dev->mc_list_lock); 1372 write_lock_bh(&in_dev->mc_list_lock);
1370 while ((i = in_dev->mc_list) != NULL) { 1373 while ((i = in_dev->mc_list) != NULL) {
1371 in_dev->mc_list = i->next; 1374 in_dev->mc_list = i->next;
1375 in_dev->mc_count--;
1372 write_unlock_bh(&in_dev->mc_list_lock); 1376 write_unlock_bh(&in_dev->mc_list_lock);
1373
1374 igmp_group_dropped(i); 1377 igmp_group_dropped(i);
1375 ip_ma_put(i); 1378 ip_ma_put(i);
1376 1379
@@ -2383,7 +2386,7 @@ static int igmp_mc_seq_show(struct seq_file *seq, void *v)
2383 2386
2384 if (state->in_dev->mc_list == im) { 2387 if (state->in_dev->mc_list == im) {
2385 seq_printf(seq, "%d\t%-10s: %5d %7s\n", 2388 seq_printf(seq, "%d\t%-10s: %5d %7s\n",
2386 state->dev->ifindex, state->dev->name, state->dev->mc_count, querier); 2389 state->dev->ifindex, state->dev->name, state->in_dev->mc_count, querier);
2387 } 2390 }
2388 2391
2389 seq_printf(seq, 2392 seq_printf(seq,
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 0c1ae68ee84b..bd1278a2d828 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -30,20 +30,22 @@ EXPORT_SYMBOL(inet_csk_timer_bug_msg);
30#endif 30#endif
31 31
32/* 32/*
33 * This array holds the first and last local port number. 33 * This struct holds the first and last local port number.
34 */ 34 */
35int sysctl_local_port_range[2] = { 32768, 61000 }; 35struct local_ports sysctl_local_ports __read_mostly = {
36DEFINE_SEQLOCK(sysctl_port_range_lock); 36 .lock = SEQLOCK_UNLOCKED,
37 .range = { 32768, 61000 },
38};
37 39
38void inet_get_local_port_range(int *low, int *high) 40void inet_get_local_port_range(int *low, int *high)
39{ 41{
40 unsigned seq; 42 unsigned seq;
41 do { 43 do {
42 seq = read_seqbegin(&sysctl_port_range_lock); 44 seq = read_seqbegin(&sysctl_local_ports.lock);
43 45
44 *low = sysctl_local_port_range[0]; 46 *low = sysctl_local_ports.range[0];
45 *high = sysctl_local_port_range[1]; 47 *high = sysctl_local_ports.range[1];
46 } while (read_seqretry(&sysctl_port_range_lock, seq)); 48 } while (read_seqretry(&sysctl_local_ports.lock, seq));
47} 49}
48EXPORT_SYMBOL(inet_get_local_port_range); 50EXPORT_SYMBOL(inet_get_local_port_range);
49 51
@@ -335,6 +337,7 @@ struct dst_entry* inet_csk_route_req(struct sock *sk,
335 .saddr = ireq->loc_addr, 337 .saddr = ireq->loc_addr,
336 .tos = RT_CONN_FLAGS(sk) } }, 338 .tos = RT_CONN_FLAGS(sk) } },
337 .proto = sk->sk_protocol, 339 .proto = sk->sk_protocol,
340 .flags = inet_sk_flowi_flags(sk),
338 .uli_u = { .ports = 341 .uli_u = { .ports =
339 { .sport = inet_sk(sk)->sport, 342 { .sport = inet_sk(sk)->sport,
340 .dport = ireq->rmt_port } } }; 343 .dport = ireq->rmt_port } } };
@@ -515,6 +518,8 @@ struct sock *inet_csk_clone(struct sock *sk, const struct request_sock *req,
515 newicsk->icsk_bind_hash = NULL; 518 newicsk->icsk_bind_hash = NULL;
516 519
517 inet_sk(newsk)->dport = inet_rsk(req)->rmt_port; 520 inet_sk(newsk)->dport = inet_rsk(req)->rmt_port;
521 inet_sk(newsk)->num = ntohs(inet_rsk(req)->loc_port);
522 inet_sk(newsk)->sport = inet_rsk(req)->loc_port;
518 newsk->sk_write_space = sk_stream_write_space; 523 newsk->sk_write_space = sk_stream_write_space;
519 524
520 newicsk->icsk_retransmits = 0; 525 newicsk->icsk_retransmits = 0;
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index c10036e7a463..89cb047ab314 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -782,11 +782,15 @@ skip_listen_ht:
782 struct sock *sk; 782 struct sock *sk;
783 struct hlist_node *node; 783 struct hlist_node *node;
784 784
785 num = 0;
786
787 if (hlist_empty(&head->chain) && hlist_empty(&head->twchain))
788 continue;
789
785 if (i > s_i) 790 if (i > s_i)
786 s_num = 0; 791 s_num = 0;
787 792
788 read_lock_bh(lock); 793 read_lock_bh(lock);
789 num = 0;
790 sk_for_each(sk, node, &head->chain) { 794 sk_for_each(sk, node, &head->chain) {
791 struct inet_sock *inet = inet_sk(sk); 795 struct inet_sock *inet = inet_sk(sk);
792 796
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c
index d985bd613d25..1c5fd38f8824 100644
--- a/net/ipv4/inet_timewait_sock.c
+++ b/net/ipv4/inet_timewait_sock.c
@@ -126,6 +126,7 @@ struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, const int stat
126 tw->tw_reuse = sk->sk_reuse; 126 tw->tw_reuse = sk->sk_reuse;
127 tw->tw_hash = sk->sk_hash; 127 tw->tw_hash = sk->sk_hash;
128 tw->tw_ipv6only = 0; 128 tw->tw_ipv6only = 0;
129 tw->tw_transparent = inet->transparent;
129 tw->tw_prot = sk->sk_prot_creator; 130 tw->tw_prot = sk->sk_prot_creator;
130 twsk_net_set(tw, hold_net(sock_net(sk))); 131 twsk_net_set(tw, hold_net(sock_net(sk)));
131 atomic_set(&tw->tw_refcnt, 1); 132 atomic_set(&tw->tw_refcnt, 1);
@@ -409,3 +410,38 @@ out:
409} 410}
410 411
411EXPORT_SYMBOL_GPL(inet_twdr_twcal_tick); 412EXPORT_SYMBOL_GPL(inet_twdr_twcal_tick);
413
414void inet_twsk_purge(struct net *net, struct inet_hashinfo *hashinfo,
415 struct inet_timewait_death_row *twdr, int family)
416{
417 struct inet_timewait_sock *tw;
418 struct sock *sk;
419 struct hlist_node *node;
420 int h;
421
422 local_bh_disable();
423 for (h = 0; h < (hashinfo->ehash_size); h++) {
424 struct inet_ehash_bucket *head =
425 inet_ehash_bucket(hashinfo, h);
426 rwlock_t *lock = inet_ehash_lockp(hashinfo, h);
427restart:
428 write_lock(lock);
429 sk_for_each(sk, node, &head->twchain) {
430
431 tw = inet_twsk(sk);
432 if (!net_eq(twsk_net(tw), net) ||
433 tw->tw_family != family)
434 continue;
435
436 atomic_inc(&tw->tw_refcnt);
437 write_unlock(lock);
438 inet_twsk_deschedule(tw, twdr);
439 inet_twsk_put(tw);
440
441 goto restart;
442 }
443 write_unlock(lock);
444 }
445 local_bh_enable();
446}
447EXPORT_SYMBOL_GPL(inet_twsk_purge);
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 2a61158ea722..85c487b8572b 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -27,6 +27,7 @@
27#include <linux/inetdevice.h> 27#include <linux/inetdevice.h>
28#include <linux/igmp.h> 28#include <linux/igmp.h>
29#include <linux/netfilter_ipv4.h> 29#include <linux/netfilter_ipv4.h>
30#include <linux/etherdevice.h>
30#include <linux/if_ether.h> 31#include <linux/if_ether.h>
31 32
32#include <net/sock.h> 33#include <net/sock.h>
@@ -41,6 +42,7 @@
41#include <net/xfrm.h> 42#include <net/xfrm.h>
42#include <net/net_namespace.h> 43#include <net/net_namespace.h>
43#include <net/netns/generic.h> 44#include <net/netns/generic.h>
45#include <net/rtnetlink.h>
44 46
45#ifdef CONFIG_IPV6 47#ifdef CONFIG_IPV6
46#include <net/ipv6.h> 48#include <net/ipv6.h>
@@ -117,8 +119,10 @@
117 Alexey Kuznetsov. 119 Alexey Kuznetsov.
118 */ 120 */
119 121
122static struct rtnl_link_ops ipgre_link_ops __read_mostly;
120static int ipgre_tunnel_init(struct net_device *dev); 123static int ipgre_tunnel_init(struct net_device *dev);
121static void ipgre_tunnel_setup(struct net_device *dev); 124static void ipgre_tunnel_setup(struct net_device *dev);
125static int ipgre_tunnel_bind_dev(struct net_device *dev);
122 126
123/* Fallback tunnel: no source, no destination, no key, no options */ 127/* Fallback tunnel: no source, no destination, no key, no options */
124 128
@@ -163,38 +167,64 @@ static DEFINE_RWLOCK(ipgre_lock);
163/* Given src, dst and key, find appropriate for input tunnel. */ 167/* Given src, dst and key, find appropriate for input tunnel. */
164 168
165static struct ip_tunnel * ipgre_tunnel_lookup(struct net *net, 169static struct ip_tunnel * ipgre_tunnel_lookup(struct net *net,
166 __be32 remote, __be32 local, __be32 key) 170 __be32 remote, __be32 local,
171 __be32 key, __be16 gre_proto)
167{ 172{
168 unsigned h0 = HASH(remote); 173 unsigned h0 = HASH(remote);
169 unsigned h1 = HASH(key); 174 unsigned h1 = HASH(key);
170 struct ip_tunnel *t; 175 struct ip_tunnel *t;
176 struct ip_tunnel *t2 = NULL;
171 struct ipgre_net *ign = net_generic(net, ipgre_net_id); 177 struct ipgre_net *ign = net_generic(net, ipgre_net_id);
178 int dev_type = (gre_proto == htons(ETH_P_TEB)) ?
179 ARPHRD_ETHER : ARPHRD_IPGRE;
172 180
173 for (t = ign->tunnels_r_l[h0^h1]; t; t = t->next) { 181 for (t = ign->tunnels_r_l[h0^h1]; t; t = t->next) {
174 if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) { 182 if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) {
175 if (t->parms.i_key == key && (t->dev->flags&IFF_UP)) 183 if (t->parms.i_key == key && t->dev->flags & IFF_UP) {
176 return t; 184 if (t->dev->type == dev_type)
185 return t;
186 if (t->dev->type == ARPHRD_IPGRE && !t2)
187 t2 = t;
188 }
177 } 189 }
178 } 190 }
191
179 for (t = ign->tunnels_r[h0^h1]; t; t = t->next) { 192 for (t = ign->tunnels_r[h0^h1]; t; t = t->next) {
180 if (remote == t->parms.iph.daddr) { 193 if (remote == t->parms.iph.daddr) {
181 if (t->parms.i_key == key && (t->dev->flags&IFF_UP)) 194 if (t->parms.i_key == key && t->dev->flags & IFF_UP) {
182 return t; 195 if (t->dev->type == dev_type)
196 return t;
197 if (t->dev->type == ARPHRD_IPGRE && !t2)
198 t2 = t;
199 }
183 } 200 }
184 } 201 }
202
185 for (t = ign->tunnels_l[h1]; t; t = t->next) { 203 for (t = ign->tunnels_l[h1]; t; t = t->next) {
186 if (local == t->parms.iph.saddr || 204 if (local == t->parms.iph.saddr ||
187 (local == t->parms.iph.daddr && 205 (local == t->parms.iph.daddr &&
188 ipv4_is_multicast(local))) { 206 ipv4_is_multicast(local))) {
189 if (t->parms.i_key == key && (t->dev->flags&IFF_UP)) 207 if (t->parms.i_key == key && t->dev->flags & IFF_UP) {
190 return t; 208 if (t->dev->type == dev_type)
209 return t;
210 if (t->dev->type == ARPHRD_IPGRE && !t2)
211 t2 = t;
212 }
191 } 213 }
192 } 214 }
215
193 for (t = ign->tunnels_wc[h1]; t; t = t->next) { 216 for (t = ign->tunnels_wc[h1]; t; t = t->next) {
194 if (t->parms.i_key == key && (t->dev->flags&IFF_UP)) 217 if (t->parms.i_key == key && t->dev->flags & IFF_UP) {
195 return t; 218 if (t->dev->type == dev_type)
219 return t;
220 if (t->dev->type == ARPHRD_IPGRE && !t2)
221 t2 = t;
222 }
196 } 223 }
197 224
225 if (t2)
226 return t2;
227
198 if (ign->fb_tunnel_dev->flags&IFF_UP) 228 if (ign->fb_tunnel_dev->flags&IFF_UP)
199 return netdev_priv(ign->fb_tunnel_dev); 229 return netdev_priv(ign->fb_tunnel_dev);
200 return NULL; 230 return NULL;
@@ -249,25 +279,37 @@ static void ipgre_tunnel_unlink(struct ipgre_net *ign, struct ip_tunnel *t)
249 } 279 }
250} 280}
251 281
252static struct ip_tunnel * ipgre_tunnel_locate(struct net *net, 282static struct ip_tunnel *ipgre_tunnel_find(struct net *net,
253 struct ip_tunnel_parm *parms, int create) 283 struct ip_tunnel_parm *parms,
284 int type)
254{ 285{
255 __be32 remote = parms->iph.daddr; 286 __be32 remote = parms->iph.daddr;
256 __be32 local = parms->iph.saddr; 287 __be32 local = parms->iph.saddr;
257 __be32 key = parms->i_key; 288 __be32 key = parms->i_key;
258 struct ip_tunnel *t, **tp, *nt; 289 struct ip_tunnel *t, **tp;
290 struct ipgre_net *ign = net_generic(net, ipgre_net_id);
291
292 for (tp = __ipgre_bucket(ign, parms); (t = *tp) != NULL; tp = &t->next)
293 if (local == t->parms.iph.saddr &&
294 remote == t->parms.iph.daddr &&
295 key == t->parms.i_key &&
296 type == t->dev->type)
297 break;
298
299 return t;
300}
301
302static struct ip_tunnel * ipgre_tunnel_locate(struct net *net,
303 struct ip_tunnel_parm *parms, int create)
304{
305 struct ip_tunnel *t, *nt;
259 struct net_device *dev; 306 struct net_device *dev;
260 char name[IFNAMSIZ]; 307 char name[IFNAMSIZ];
261 struct ipgre_net *ign = net_generic(net, ipgre_net_id); 308 struct ipgre_net *ign = net_generic(net, ipgre_net_id);
262 309
263 for (tp = __ipgre_bucket(ign, parms); (t = *tp) != NULL; tp = &t->next) { 310 t = ipgre_tunnel_find(net, parms, ARPHRD_IPGRE);
264 if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) { 311 if (t || !create)
265 if (key == t->parms.i_key) 312 return t;
266 return t;
267 }
268 }
269 if (!create)
270 return NULL;
271 313
272 if (parms->name[0]) 314 if (parms->name[0])
273 strlcpy(name, parms->name, IFNAMSIZ); 315 strlcpy(name, parms->name, IFNAMSIZ);
@@ -285,9 +327,11 @@ static struct ip_tunnel * ipgre_tunnel_locate(struct net *net,
285 goto failed_free; 327 goto failed_free;
286 } 328 }
287 329
288 dev->init = ipgre_tunnel_init;
289 nt = netdev_priv(dev); 330 nt = netdev_priv(dev);
290 nt->parms = *parms; 331 nt->parms = *parms;
332 dev->rtnl_link_ops = &ipgre_link_ops;
333
334 dev->mtu = ipgre_tunnel_bind_dev(dev);
291 335
292 if (register_netdevice(dev) < 0) 336 if (register_netdevice(dev) < 0)
293 goto failed_free; 337 goto failed_free;
@@ -380,8 +424,9 @@ static void ipgre_err(struct sk_buff *skb, u32 info)
380 424
381 read_lock(&ipgre_lock); 425 read_lock(&ipgre_lock);
382 t = ipgre_tunnel_lookup(dev_net(skb->dev), iph->daddr, iph->saddr, 426 t = ipgre_tunnel_lookup(dev_net(skb->dev), iph->daddr, iph->saddr,
383 (flags&GRE_KEY) ? 427 flags & GRE_KEY ?
384 *(((__be32*)p) + (grehlen>>2) - 1) : 0); 428 *(((__be32 *)p) + (grehlen / 4) - 1) : 0,
429 p[1]);
385 if (t == NULL || t->parms.iph.daddr == 0 || 430 if (t == NULL || t->parms.iph.daddr == 0 ||
386 ipv4_is_multicast(t->parms.iph.daddr)) 431 ipv4_is_multicast(t->parms.iph.daddr))
387 goto out; 432 goto out;
@@ -431,6 +476,8 @@ static int ipgre_rcv(struct sk_buff *skb)
431 u32 seqno = 0; 476 u32 seqno = 0;
432 struct ip_tunnel *tunnel; 477 struct ip_tunnel *tunnel;
433 int offset = 4; 478 int offset = 4;
479 __be16 gre_proto;
480 unsigned int len;
434 481
435 if (!pskb_may_pull(skb, 16)) 482 if (!pskb_may_pull(skb, 16))
436 goto drop_nolock; 483 goto drop_nolock;
@@ -470,20 +517,22 @@ static int ipgre_rcv(struct sk_buff *skb)
470 } 517 }
471 } 518 }
472 519
520 gre_proto = *(__be16 *)(h + 2);
521
473 read_lock(&ipgre_lock); 522 read_lock(&ipgre_lock);
474 if ((tunnel = ipgre_tunnel_lookup(dev_net(skb->dev), 523 if ((tunnel = ipgre_tunnel_lookup(dev_net(skb->dev),
475 iph->saddr, iph->daddr, key)) != NULL) { 524 iph->saddr, iph->daddr, key,
525 gre_proto))) {
476 struct net_device_stats *stats = &tunnel->dev->stats; 526 struct net_device_stats *stats = &tunnel->dev->stats;
477 527
478 secpath_reset(skb); 528 secpath_reset(skb);
479 529
480 skb->protocol = *(__be16*)(h + 2); 530 skb->protocol = gre_proto;
481 /* WCCP version 1 and 2 protocol decoding. 531 /* WCCP version 1 and 2 protocol decoding.
482 * - Change protocol to IP 532 * - Change protocol to IP
483 * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header 533 * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header
484 */ 534 */
485 if (flags == 0 && 535 if (flags == 0 && gre_proto == htons(ETH_P_WCCP)) {
486 skb->protocol == htons(ETH_P_WCCP)) {
487 skb->protocol = htons(ETH_P_IP); 536 skb->protocol = htons(ETH_P_IP);
488 if ((*(h + offset) & 0xF0) != 0x40) 537 if ((*(h + offset) & 0xF0) != 0x40)
489 offset += 4; 538 offset += 4;
@@ -491,7 +540,6 @@ static int ipgre_rcv(struct sk_buff *skb)
491 540
492 skb->mac_header = skb->network_header; 541 skb->mac_header = skb->network_header;
493 __pskb_pull(skb, offset); 542 __pskb_pull(skb, offset);
494 skb_reset_network_header(skb);
495 skb_postpull_rcsum(skb, skb_transport_header(skb), offset); 543 skb_postpull_rcsum(skb, skb_transport_header(skb), offset);
496 skb->pkt_type = PACKET_HOST; 544 skb->pkt_type = PACKET_HOST;
497#ifdef CONFIG_NET_IPGRE_BROADCAST 545#ifdef CONFIG_NET_IPGRE_BROADCAST
@@ -519,13 +567,32 @@ static int ipgre_rcv(struct sk_buff *skb)
519 } 567 }
520 tunnel->i_seqno = seqno + 1; 568 tunnel->i_seqno = seqno + 1;
521 } 569 }
570
571 len = skb->len;
572
573 /* Warning: All skb pointers will be invalidated! */
574 if (tunnel->dev->type == ARPHRD_ETHER) {
575 if (!pskb_may_pull(skb, ETH_HLEN)) {
576 stats->rx_length_errors++;
577 stats->rx_errors++;
578 goto drop;
579 }
580
581 iph = ip_hdr(skb);
582 skb->protocol = eth_type_trans(skb, tunnel->dev);
583 skb_postpull_rcsum(skb, eth_hdr(skb), ETH_HLEN);
584 }
585
522 stats->rx_packets++; 586 stats->rx_packets++;
523 stats->rx_bytes += skb->len; 587 stats->rx_bytes += len;
524 skb->dev = tunnel->dev; 588 skb->dev = tunnel->dev;
525 dst_release(skb->dst); 589 dst_release(skb->dst);
526 skb->dst = NULL; 590 skb->dst = NULL;
527 nf_reset(skb); 591 nf_reset(skb);
592
593 skb_reset_network_header(skb);
528 ipgre_ecn_decapsulate(iph, skb); 594 ipgre_ecn_decapsulate(iph, skb);
595
529 netif_rx(skb); 596 netif_rx(skb);
530 read_unlock(&ipgre_lock); 597 read_unlock(&ipgre_lock);
531 return(0); 598 return(0);
@@ -560,7 +627,10 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
560 goto tx_error; 627 goto tx_error;
561 } 628 }
562 629
563 if (dev->header_ops) { 630 if (dev->type == ARPHRD_ETHER)
631 IPCB(skb)->flags = 0;
632
633 if (dev->header_ops && dev->type == ARPHRD_IPGRE) {
564 gre_hlen = 0; 634 gre_hlen = 0;
565 tiph = (struct iphdr*)skb->data; 635 tiph = (struct iphdr*)skb->data;
566 } else { 636 } else {
@@ -637,7 +707,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
637 707
638 df = tiph->frag_off; 708 df = tiph->frag_off;
639 if (df) 709 if (df)
640 mtu = dst_mtu(&rt->u.dst) - tunnel->hlen; 710 mtu = dst_mtu(&rt->u.dst) - dev->hard_header_len - tunnel->hlen;
641 else 711 else
642 mtu = skb->dst ? dst_mtu(skb->dst) : dev->mtu; 712 mtu = skb->dst ? dst_mtu(skb->dst) : dev->mtu;
643 713
@@ -703,7 +773,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
703 old_iph = ip_hdr(skb); 773 old_iph = ip_hdr(skb);
704 } 774 }
705 775
706 skb->transport_header = skb->network_header; 776 skb_reset_transport_header(skb);
707 skb_push(skb, gre_hlen); 777 skb_push(skb, gre_hlen);
708 skb_reset_network_header(skb); 778 skb_reset_network_header(skb);
709 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); 779 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
@@ -736,8 +806,9 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
736 iph->ttl = dst_metric(&rt->u.dst, RTAX_HOPLIMIT); 806 iph->ttl = dst_metric(&rt->u.dst, RTAX_HOPLIMIT);
737 } 807 }
738 808
739 ((__be16*)(iph+1))[0] = tunnel->parms.o_flags; 809 ((__be16 *)(iph + 1))[0] = tunnel->parms.o_flags;
740 ((__be16*)(iph+1))[1] = skb->protocol; 810 ((__be16 *)(iph + 1))[1] = (dev->type == ARPHRD_ETHER) ?
811 htons(ETH_P_TEB) : skb->protocol;
741 812
742 if (tunnel->parms.o_flags&(GRE_KEY|GRE_CSUM|GRE_SEQ)) { 813 if (tunnel->parms.o_flags&(GRE_KEY|GRE_CSUM|GRE_SEQ)) {
743 __be32 *ptr = (__be32*)(((u8*)iph) + tunnel->hlen - 4); 814 __be32 *ptr = (__be32*)(((u8*)iph) + tunnel->hlen - 4);
@@ -773,7 +844,7 @@ tx_error:
773 return 0; 844 return 0;
774} 845}
775 846
776static void ipgre_tunnel_bind_dev(struct net_device *dev) 847static int ipgre_tunnel_bind_dev(struct net_device *dev)
777{ 848{
778 struct net_device *tdev = NULL; 849 struct net_device *tdev = NULL;
779 struct ip_tunnel *tunnel; 850 struct ip_tunnel *tunnel;
@@ -785,7 +856,7 @@ static void ipgre_tunnel_bind_dev(struct net_device *dev)
785 tunnel = netdev_priv(dev); 856 tunnel = netdev_priv(dev);
786 iph = &tunnel->parms.iph; 857 iph = &tunnel->parms.iph;
787 858
788 /* Guess output device to choose reasonable mtu and hard_header_len */ 859 /* Guess output device to choose reasonable mtu and needed_headroom */
789 860
790 if (iph->daddr) { 861 if (iph->daddr) {
791 struct flowi fl = { .oif = tunnel->parms.link, 862 struct flowi fl = { .oif = tunnel->parms.link,
@@ -799,14 +870,16 @@ static void ipgre_tunnel_bind_dev(struct net_device *dev)
799 tdev = rt->u.dst.dev; 870 tdev = rt->u.dst.dev;
800 ip_rt_put(rt); 871 ip_rt_put(rt);
801 } 872 }
802 dev->flags |= IFF_POINTOPOINT; 873
874 if (dev->type != ARPHRD_ETHER)
875 dev->flags |= IFF_POINTOPOINT;
803 } 876 }
804 877
805 if (!tdev && tunnel->parms.link) 878 if (!tdev && tunnel->parms.link)
806 tdev = __dev_get_by_index(dev_net(dev), tunnel->parms.link); 879 tdev = __dev_get_by_index(dev_net(dev), tunnel->parms.link);
807 880
808 if (tdev) { 881 if (tdev) {
809 hlen = tdev->hard_header_len; 882 hlen = tdev->hard_header_len + tdev->needed_headroom;
810 mtu = tdev->mtu; 883 mtu = tdev->mtu;
811 } 884 }
812 dev->iflink = tunnel->parms.link; 885 dev->iflink = tunnel->parms.link;
@@ -820,10 +893,15 @@ static void ipgre_tunnel_bind_dev(struct net_device *dev)
820 if (tunnel->parms.o_flags&GRE_SEQ) 893 if (tunnel->parms.o_flags&GRE_SEQ)
821 addend += 4; 894 addend += 4;
822 } 895 }
823 dev->hard_header_len = hlen + addend; 896 dev->needed_headroom = addend + hlen;
824 dev->mtu = mtu - addend; 897 mtu -= dev->hard_header_len - addend;
898
899 if (mtu < 68)
900 mtu = 68;
901
825 tunnel->hlen = addend; 902 tunnel->hlen = addend;
826 903
904 return mtu;
827} 905}
828 906
829static int 907static int
@@ -917,7 +995,7 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
917 t->parms.iph.frag_off = p.iph.frag_off; 995 t->parms.iph.frag_off = p.iph.frag_off;
918 if (t->parms.link != p.link) { 996 if (t->parms.link != p.link) {
919 t->parms.link = p.link; 997 t->parms.link = p.link;
920 ipgre_tunnel_bind_dev(dev); 998 dev->mtu = ipgre_tunnel_bind_dev(dev);
921 netdev_state_change(dev); 999 netdev_state_change(dev);
922 } 1000 }
923 } 1001 }
@@ -959,7 +1037,8 @@ done:
959static int ipgre_tunnel_change_mtu(struct net_device *dev, int new_mtu) 1037static int ipgre_tunnel_change_mtu(struct net_device *dev, int new_mtu)
960{ 1038{
961 struct ip_tunnel *tunnel = netdev_priv(dev); 1039 struct ip_tunnel *tunnel = netdev_priv(dev);
962 if (new_mtu < 68 || new_mtu > 0xFFF8 - tunnel->hlen) 1040 if (new_mtu < 68 ||
1041 new_mtu > 0xFFF8 - dev->hard_header_len - tunnel->hlen)
963 return -EINVAL; 1042 return -EINVAL;
964 dev->mtu = new_mtu; 1043 dev->mtu = new_mtu;
965 return 0; 1044 return 0;
@@ -1078,6 +1157,7 @@ static int ipgre_close(struct net_device *dev)
1078 1157
1079static void ipgre_tunnel_setup(struct net_device *dev) 1158static void ipgre_tunnel_setup(struct net_device *dev)
1080{ 1159{
1160 dev->init = ipgre_tunnel_init;
1081 dev->uninit = ipgre_tunnel_uninit; 1161 dev->uninit = ipgre_tunnel_uninit;
1082 dev->destructor = free_netdev; 1162 dev->destructor = free_netdev;
1083 dev->hard_start_xmit = ipgre_tunnel_xmit; 1163 dev->hard_start_xmit = ipgre_tunnel_xmit;
@@ -1085,7 +1165,7 @@ static void ipgre_tunnel_setup(struct net_device *dev)
1085 dev->change_mtu = ipgre_tunnel_change_mtu; 1165 dev->change_mtu = ipgre_tunnel_change_mtu;
1086 1166
1087 dev->type = ARPHRD_IPGRE; 1167 dev->type = ARPHRD_IPGRE;
1088 dev->hard_header_len = LL_MAX_HEADER + sizeof(struct iphdr) + 4; 1168 dev->needed_headroom = LL_MAX_HEADER + sizeof(struct iphdr) + 4;
1089 dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr) - 4; 1169 dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr) - 4;
1090 dev->flags = IFF_NOARP; 1170 dev->flags = IFF_NOARP;
1091 dev->iflink = 0; 1171 dev->iflink = 0;
@@ -1107,8 +1187,6 @@ static int ipgre_tunnel_init(struct net_device *dev)
1107 memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4); 1187 memcpy(dev->dev_addr, &tunnel->parms.iph.saddr, 4);
1108 memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4); 1188 memcpy(dev->broadcast, &tunnel->parms.iph.daddr, 4);
1109 1189
1110 ipgre_tunnel_bind_dev(dev);
1111
1112 if (iph->daddr) { 1190 if (iph->daddr) {
1113#ifdef CONFIG_NET_IPGRE_BROADCAST 1191#ifdef CONFIG_NET_IPGRE_BROADCAST
1114 if (ipv4_is_multicast(iph->daddr)) { 1192 if (ipv4_is_multicast(iph->daddr)) {
@@ -1189,6 +1267,7 @@ static int ipgre_init_net(struct net *net)
1189 1267
1190 ign->fb_tunnel_dev->init = ipgre_fb_tunnel_init; 1268 ign->fb_tunnel_dev->init = ipgre_fb_tunnel_init;
1191 dev_net_set(ign->fb_tunnel_dev, net); 1269 dev_net_set(ign->fb_tunnel_dev, net);
1270 ign->fb_tunnel_dev->rtnl_link_ops = &ipgre_link_ops;
1192 1271
1193 if ((err = register_netdev(ign->fb_tunnel_dev))) 1272 if ((err = register_netdev(ign->fb_tunnel_dev)))
1194 goto err_reg_dev; 1273 goto err_reg_dev;
@@ -1221,6 +1300,298 @@ static struct pernet_operations ipgre_net_ops = {
1221 .exit = ipgre_exit_net, 1300 .exit = ipgre_exit_net,
1222}; 1301};
1223 1302
1303static int ipgre_tunnel_validate(struct nlattr *tb[], struct nlattr *data[])
1304{
1305 __be16 flags;
1306
1307 if (!data)
1308 return 0;
1309
1310 flags = 0;
1311 if (data[IFLA_GRE_IFLAGS])
1312 flags |= nla_get_be16(data[IFLA_GRE_IFLAGS]);
1313 if (data[IFLA_GRE_OFLAGS])
1314 flags |= nla_get_be16(data[IFLA_GRE_OFLAGS]);
1315 if (flags & (GRE_VERSION|GRE_ROUTING))
1316 return -EINVAL;
1317
1318 return 0;
1319}
1320
1321static int ipgre_tap_validate(struct nlattr *tb[], struct nlattr *data[])
1322{
1323 __be32 daddr;
1324
1325 if (tb[IFLA_ADDRESS]) {
1326 if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
1327 return -EINVAL;
1328 if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
1329 return -EADDRNOTAVAIL;
1330 }
1331
1332 if (!data)
1333 goto out;
1334
1335 if (data[IFLA_GRE_REMOTE]) {
1336 memcpy(&daddr, nla_data(data[IFLA_GRE_REMOTE]), 4);
1337 if (!daddr)
1338 return -EINVAL;
1339 }
1340
1341out:
1342 return ipgre_tunnel_validate(tb, data);
1343}
1344
1345static void ipgre_netlink_parms(struct nlattr *data[],
1346 struct ip_tunnel_parm *parms)
1347{
1348 memset(parms, 0, sizeof(*parms));
1349
1350 parms->iph.protocol = IPPROTO_GRE;
1351
1352 if (!data)
1353 return;
1354
1355 if (data[IFLA_GRE_LINK])
1356 parms->link = nla_get_u32(data[IFLA_GRE_LINK]);
1357
1358 if (data[IFLA_GRE_IFLAGS])
1359 parms->i_flags = nla_get_be16(data[IFLA_GRE_IFLAGS]);
1360
1361 if (data[IFLA_GRE_OFLAGS])
1362 parms->o_flags = nla_get_be16(data[IFLA_GRE_OFLAGS]);
1363
1364 if (data[IFLA_GRE_IKEY])
1365 parms->i_key = nla_get_be32(data[IFLA_GRE_IKEY]);
1366
1367 if (data[IFLA_GRE_OKEY])
1368 parms->o_key = nla_get_be32(data[IFLA_GRE_OKEY]);
1369
1370 if (data[IFLA_GRE_LOCAL])
1371 parms->iph.saddr = nla_get_be32(data[IFLA_GRE_LOCAL]);
1372
1373 if (data[IFLA_GRE_REMOTE])
1374 parms->iph.daddr = nla_get_be32(data[IFLA_GRE_REMOTE]);
1375
1376 if (data[IFLA_GRE_TTL])
1377 parms->iph.ttl = nla_get_u8(data[IFLA_GRE_TTL]);
1378
1379 if (data[IFLA_GRE_TOS])
1380 parms->iph.tos = nla_get_u8(data[IFLA_GRE_TOS]);
1381
1382 if (!data[IFLA_GRE_PMTUDISC] || nla_get_u8(data[IFLA_GRE_PMTUDISC]))
1383 parms->iph.frag_off = htons(IP_DF);
1384}
1385
1386static int ipgre_tap_init(struct net_device *dev)
1387{
1388 struct ip_tunnel *tunnel;
1389
1390 tunnel = netdev_priv(dev);
1391
1392 tunnel->dev = dev;
1393 strcpy(tunnel->parms.name, dev->name);
1394
1395 ipgre_tunnel_bind_dev(dev);
1396
1397 return 0;
1398}
1399
1400static void ipgre_tap_setup(struct net_device *dev)
1401{
1402
1403 ether_setup(dev);
1404
1405 dev->init = ipgre_tap_init;
1406 dev->uninit = ipgre_tunnel_uninit;
1407 dev->destructor = free_netdev;
1408 dev->hard_start_xmit = ipgre_tunnel_xmit;
1409 dev->change_mtu = ipgre_tunnel_change_mtu;
1410
1411 dev->iflink = 0;
1412 dev->features |= NETIF_F_NETNS_LOCAL;
1413}
1414
1415static int ipgre_newlink(struct net_device *dev, struct nlattr *tb[],
1416 struct nlattr *data[])
1417{
1418 struct ip_tunnel *nt;
1419 struct net *net = dev_net(dev);
1420 struct ipgre_net *ign = net_generic(net, ipgre_net_id);
1421 int mtu;
1422 int err;
1423
1424 nt = netdev_priv(dev);
1425 ipgre_netlink_parms(data, &nt->parms);
1426
1427 if (ipgre_tunnel_find(net, &nt->parms, dev->type))
1428 return -EEXIST;
1429
1430 if (dev->type == ARPHRD_ETHER && !tb[IFLA_ADDRESS])
1431 random_ether_addr(dev->dev_addr);
1432
1433 mtu = ipgre_tunnel_bind_dev(dev);
1434 if (!tb[IFLA_MTU])
1435 dev->mtu = mtu;
1436
1437 err = register_netdevice(dev);
1438 if (err)
1439 goto out;
1440
1441 dev_hold(dev);
1442 ipgre_tunnel_link(ign, nt);
1443
1444out:
1445 return err;
1446}
1447
1448static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[],
1449 struct nlattr *data[])
1450{
1451 struct ip_tunnel *t, *nt;
1452 struct net *net = dev_net(dev);
1453 struct ipgre_net *ign = net_generic(net, ipgre_net_id);
1454 struct ip_tunnel_parm p;
1455 int mtu;
1456
1457 if (dev == ign->fb_tunnel_dev)
1458 return -EINVAL;
1459
1460 nt = netdev_priv(dev);
1461 ipgre_netlink_parms(data, &p);
1462
1463 t = ipgre_tunnel_locate(net, &p, 0);
1464
1465 if (t) {
1466 if (t->dev != dev)
1467 return -EEXIST;
1468 } else {
1469 unsigned nflags = 0;
1470
1471 t = nt;
1472
1473 if (ipv4_is_multicast(p.iph.daddr))
1474 nflags = IFF_BROADCAST;
1475 else if (p.iph.daddr)
1476 nflags = IFF_POINTOPOINT;
1477
1478 if ((dev->flags ^ nflags) &
1479 (IFF_POINTOPOINT | IFF_BROADCAST))
1480 return -EINVAL;
1481
1482 ipgre_tunnel_unlink(ign, t);
1483 t->parms.iph.saddr = p.iph.saddr;
1484 t->parms.iph.daddr = p.iph.daddr;
1485 t->parms.i_key = p.i_key;
1486 memcpy(dev->dev_addr, &p.iph.saddr, 4);
1487 memcpy(dev->broadcast, &p.iph.daddr, 4);
1488 ipgre_tunnel_link(ign, t);
1489 netdev_state_change(dev);
1490 }
1491
1492 t->parms.o_key = p.o_key;
1493 t->parms.iph.ttl = p.iph.ttl;
1494 t->parms.iph.tos = p.iph.tos;
1495 t->parms.iph.frag_off = p.iph.frag_off;
1496
1497 if (t->parms.link != p.link) {
1498 t->parms.link = p.link;
1499 mtu = ipgre_tunnel_bind_dev(dev);
1500 if (!tb[IFLA_MTU])
1501 dev->mtu = mtu;
1502 netdev_state_change(dev);
1503 }
1504
1505 return 0;
1506}
1507
1508static size_t ipgre_get_size(const struct net_device *dev)
1509{
1510 return
1511 /* IFLA_GRE_LINK */
1512 nla_total_size(4) +
1513 /* IFLA_GRE_IFLAGS */
1514 nla_total_size(2) +
1515 /* IFLA_GRE_OFLAGS */
1516 nla_total_size(2) +
1517 /* IFLA_GRE_IKEY */
1518 nla_total_size(4) +
1519 /* IFLA_GRE_OKEY */
1520 nla_total_size(4) +
1521 /* IFLA_GRE_LOCAL */
1522 nla_total_size(4) +
1523 /* IFLA_GRE_REMOTE */
1524 nla_total_size(4) +
1525 /* IFLA_GRE_TTL */
1526 nla_total_size(1) +
1527 /* IFLA_GRE_TOS */
1528 nla_total_size(1) +
1529 /* IFLA_GRE_PMTUDISC */
1530 nla_total_size(1) +
1531 0;
1532}
1533
1534static int ipgre_fill_info(struct sk_buff *skb, const struct net_device *dev)
1535{
1536 struct ip_tunnel *t = netdev_priv(dev);
1537 struct ip_tunnel_parm *p = &t->parms;
1538
1539 NLA_PUT_U32(skb, IFLA_GRE_LINK, p->link);
1540 NLA_PUT_BE16(skb, IFLA_GRE_IFLAGS, p->i_flags);
1541 NLA_PUT_BE16(skb, IFLA_GRE_OFLAGS, p->o_flags);
1542 NLA_PUT_BE32(skb, IFLA_GRE_IKEY, p->i_key);
1543 NLA_PUT_BE32(skb, IFLA_GRE_OKEY, p->o_key);
1544 NLA_PUT_BE32(skb, IFLA_GRE_LOCAL, p->iph.saddr);
1545 NLA_PUT_BE32(skb, IFLA_GRE_REMOTE, p->iph.daddr);
1546 NLA_PUT_U8(skb, IFLA_GRE_TTL, p->iph.ttl);
1547 NLA_PUT_U8(skb, IFLA_GRE_TOS, p->iph.tos);
1548 NLA_PUT_U8(skb, IFLA_GRE_PMTUDISC, !!(p->iph.frag_off & htons(IP_DF)));
1549
1550 return 0;
1551
1552nla_put_failure:
1553 return -EMSGSIZE;
1554}
1555
1556static const struct nla_policy ipgre_policy[IFLA_GRE_MAX + 1] = {
1557 [IFLA_GRE_LINK] = { .type = NLA_U32 },
1558 [IFLA_GRE_IFLAGS] = { .type = NLA_U16 },
1559 [IFLA_GRE_OFLAGS] = { .type = NLA_U16 },
1560 [IFLA_GRE_IKEY] = { .type = NLA_U32 },
1561 [IFLA_GRE_OKEY] = { .type = NLA_U32 },
1562 [IFLA_GRE_LOCAL] = { .len = FIELD_SIZEOF(struct iphdr, saddr) },
1563 [IFLA_GRE_REMOTE] = { .len = FIELD_SIZEOF(struct iphdr, daddr) },
1564 [IFLA_GRE_TTL] = { .type = NLA_U8 },
1565 [IFLA_GRE_TOS] = { .type = NLA_U8 },
1566 [IFLA_GRE_PMTUDISC] = { .type = NLA_U8 },
1567};
1568
1569static struct rtnl_link_ops ipgre_link_ops __read_mostly = {
1570 .kind = "gre",
1571 .maxtype = IFLA_GRE_MAX,
1572 .policy = ipgre_policy,
1573 .priv_size = sizeof(struct ip_tunnel),
1574 .setup = ipgre_tunnel_setup,
1575 .validate = ipgre_tunnel_validate,
1576 .newlink = ipgre_newlink,
1577 .changelink = ipgre_changelink,
1578 .get_size = ipgre_get_size,
1579 .fill_info = ipgre_fill_info,
1580};
1581
1582static struct rtnl_link_ops ipgre_tap_ops __read_mostly = {
1583 .kind = "gretap",
1584 .maxtype = IFLA_GRE_MAX,
1585 .policy = ipgre_policy,
1586 .priv_size = sizeof(struct ip_tunnel),
1587 .setup = ipgre_tap_setup,
1588 .validate = ipgre_tap_validate,
1589 .newlink = ipgre_newlink,
1590 .changelink = ipgre_changelink,
1591 .get_size = ipgre_get_size,
1592 .fill_info = ipgre_fill_info,
1593};
1594
1224/* 1595/*
1225 * And now the modules code and kernel interface. 1596 * And now the modules code and kernel interface.
1226 */ 1597 */
@@ -1238,19 +1609,39 @@ static int __init ipgre_init(void)
1238 1609
1239 err = register_pernet_gen_device(&ipgre_net_id, &ipgre_net_ops); 1610 err = register_pernet_gen_device(&ipgre_net_id, &ipgre_net_ops);
1240 if (err < 0) 1611 if (err < 0)
1241 inet_del_protocol(&ipgre_protocol, IPPROTO_GRE); 1612 goto gen_device_failed;
1242 1613
1614 err = rtnl_link_register(&ipgre_link_ops);
1615 if (err < 0)
1616 goto rtnl_link_failed;
1617
1618 err = rtnl_link_register(&ipgre_tap_ops);
1619 if (err < 0)
1620 goto tap_ops_failed;
1621
1622out:
1243 return err; 1623 return err;
1624
1625tap_ops_failed:
1626 rtnl_link_unregister(&ipgre_link_ops);
1627rtnl_link_failed:
1628 unregister_pernet_gen_device(ipgre_net_id, &ipgre_net_ops);
1629gen_device_failed:
1630 inet_del_protocol(&ipgre_protocol, IPPROTO_GRE);
1631 goto out;
1244} 1632}
1245 1633
1246static void __exit ipgre_fini(void) 1634static void __exit ipgre_fini(void)
1247{ 1635{
1636 rtnl_link_unregister(&ipgre_tap_ops);
1637 rtnl_link_unregister(&ipgre_link_ops);
1638 unregister_pernet_gen_device(ipgre_net_id, &ipgre_net_ops);
1248 if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0) 1639 if (inet_del_protocol(&ipgre_protocol, IPPROTO_GRE) < 0)
1249 printk(KERN_INFO "ipgre close: can't remove protocol\n"); 1640 printk(KERN_INFO "ipgre close: can't remove protocol\n");
1250
1251 unregister_pernet_gen_device(ipgre_net_id, &ipgre_net_ops);
1252} 1641}
1253 1642
1254module_init(ipgre_init); 1643module_init(ipgre_init);
1255module_exit(ipgre_fini); 1644module_exit(ipgre_fini);
1256MODULE_LICENSE("GPL"); 1645MODULE_LICENSE("GPL");
1646MODULE_ALIAS_RTNL_LINK("gre");
1647MODULE_ALIAS_RTNL_LINK("gretap");
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index d533a89e08de..d2a8f8bb78a6 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -340,6 +340,7 @@ int ip_queue_xmit(struct sk_buff *skb, int ipfragok)
340 .saddr = inet->saddr, 340 .saddr = inet->saddr,
341 .tos = RT_CONN_FLAGS(sk) } }, 341 .tos = RT_CONN_FLAGS(sk) } },
342 .proto = sk->sk_protocol, 342 .proto = sk->sk_protocol,
343 .flags = inet_sk_flowi_flags(sk),
343 .uli_u = { .ports = 344 .uli_u = { .ports =
344 { .sport = inet->sport, 345 { .sport = inet->sport,
345 .dport = inet->dport } } }; 346 .dport = inet->dport } } };
@@ -1371,7 +1372,8 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
1371 .uli_u = { .ports = 1372 .uli_u = { .ports =
1372 { .sport = tcp_hdr(skb)->dest, 1373 { .sport = tcp_hdr(skb)->dest,
1373 .dport = tcp_hdr(skb)->source } }, 1374 .dport = tcp_hdr(skb)->source } },
1374 .proto = sk->sk_protocol }; 1375 .proto = sk->sk_protocol,
1376 .flags = ip_reply_arg_flowi_flags(arg) };
1375 security_skb_classify_flow(skb, &fl); 1377 security_skb_classify_flow(skb, &fl);
1376 if (ip_route_output_key(sock_net(sk), &rt, &fl)) 1378 if (ip_route_output_key(sock_net(sk), &rt, &fl))
1377 return; 1379 return;
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 105d92a039b9..465abf0a9869 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -419,7 +419,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
419 (1<<IP_TTL) | (1<<IP_HDRINCL) | 419 (1<<IP_TTL) | (1<<IP_HDRINCL) |
420 (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) | 420 (1<<IP_MTU_DISCOVER) | (1<<IP_RECVERR) |
421 (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) | 421 (1<<IP_ROUTER_ALERT) | (1<<IP_FREEBIND) |
422 (1<<IP_PASSSEC))) || 422 (1<<IP_PASSSEC) | (1<<IP_TRANSPARENT))) ||
423 optname == IP_MULTICAST_TTL || 423 optname == IP_MULTICAST_TTL ||
424 optname == IP_MULTICAST_LOOP) { 424 optname == IP_MULTICAST_LOOP) {
425 if (optlen >= sizeof(int)) { 425 if (optlen >= sizeof(int)) {
@@ -878,6 +878,16 @@ static int do_ip_setsockopt(struct sock *sk, int level,
878 err = xfrm_user_policy(sk, optname, optval, optlen); 878 err = xfrm_user_policy(sk, optname, optval, optlen);
879 break; 879 break;
880 880
881 case IP_TRANSPARENT:
882 if (!capable(CAP_NET_ADMIN)) {
883 err = -EPERM;
884 break;
885 }
886 if (optlen < 1)
887 goto e_inval;
888 inet->transparent = !!val;
889 break;
890
881 default: 891 default:
882 err = -ENOPROTOOPT; 892 err = -ENOPROTOOPT;
883 break; 893 break;
@@ -1130,6 +1140,9 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
1130 case IP_FREEBIND: 1140 case IP_FREEBIND:
1131 val = inet->freebind; 1141 val = inet->freebind;
1132 break; 1142 break;
1143 case IP_TRANSPARENT:
1144 val = inet->transparent;
1145 break;
1133 default: 1146 default:
1134 release_sock(sk); 1147 release_sock(sk);
1135 return -ENOPROTOOPT; 1148 return -ENOPROTOOPT;
diff --git a/net/ipv4/ipvs/ip_vs_proto_ah.c b/net/ipv4/ipvs/ip_vs_proto_ah.c
deleted file mode 100644
index 73e0ea87c1f5..000000000000
--- a/net/ipv4/ipvs/ip_vs_proto_ah.c
+++ /dev/null
@@ -1,178 +0,0 @@
1/*
2 * ip_vs_proto_ah.c: AH IPSec load balancing support for IPVS
3 *
4 * Authors: Julian Anastasov <ja@ssi.bg>, February 2002
5 * Wensong Zhang <wensong@linuxvirtualserver.org>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation;
10 *
11 */
12
13#include <linux/in.h>
14#include <linux/ip.h>
15#include <linux/module.h>
16#include <linux/kernel.h>
17#include <linux/netfilter.h>
18#include <linux/netfilter_ipv4.h>
19
20#include <net/ip_vs.h>
21
22
23/* TODO:
24
25struct isakmp_hdr {
26 __u8 icookie[8];
27 __u8 rcookie[8];
28 __u8 np;
29 __u8 version;
30 __u8 xchgtype;
31 __u8 flags;
32 __u32 msgid;
33 __u32 length;
34};
35
36*/
37
38#define PORT_ISAKMP 500
39
40
41static struct ip_vs_conn *
42ah_conn_in_get(const struct sk_buff *skb,
43 struct ip_vs_protocol *pp,
44 const struct iphdr *iph,
45 unsigned int proto_off,
46 int inverse)
47{
48 struct ip_vs_conn *cp;
49
50 if (likely(!inverse)) {
51 cp = ip_vs_conn_in_get(IPPROTO_UDP,
52 iph->saddr,
53 htons(PORT_ISAKMP),
54 iph->daddr,
55 htons(PORT_ISAKMP));
56 } else {
57 cp = ip_vs_conn_in_get(IPPROTO_UDP,
58 iph->daddr,
59 htons(PORT_ISAKMP),
60 iph->saddr,
61 htons(PORT_ISAKMP));
62 }
63
64 if (!cp) {
65 /*
66 * We are not sure if the packet is from our
67 * service, so our conn_schedule hook should return NF_ACCEPT
68 */
69 IP_VS_DBG(12, "Unknown ISAKMP entry for outin packet "
70 "%s%s %u.%u.%u.%u->%u.%u.%u.%u\n",
71 inverse ? "ICMP+" : "",
72 pp->name,
73 NIPQUAD(iph->saddr),
74 NIPQUAD(iph->daddr));
75 }
76
77 return cp;
78}
79
80
81static struct ip_vs_conn *
82ah_conn_out_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
83 const struct iphdr *iph, unsigned int proto_off, int inverse)
84{
85 struct ip_vs_conn *cp;
86
87 if (likely(!inverse)) {
88 cp = ip_vs_conn_out_get(IPPROTO_UDP,
89 iph->saddr,
90 htons(PORT_ISAKMP),
91 iph->daddr,
92 htons(PORT_ISAKMP));
93 } else {
94 cp = ip_vs_conn_out_get(IPPROTO_UDP,
95 iph->daddr,
96 htons(PORT_ISAKMP),
97 iph->saddr,
98 htons(PORT_ISAKMP));
99 }
100
101 if (!cp) {
102 IP_VS_DBG(12, "Unknown ISAKMP entry for inout packet "
103 "%s%s %u.%u.%u.%u->%u.%u.%u.%u\n",
104 inverse ? "ICMP+" : "",
105 pp->name,
106 NIPQUAD(iph->saddr),
107 NIPQUAD(iph->daddr));
108 }
109
110 return cp;
111}
112
113
114static int
115ah_conn_schedule(struct sk_buff *skb,
116 struct ip_vs_protocol *pp,
117 int *verdict, struct ip_vs_conn **cpp)
118{
119 /*
120 * AH is only related traffic. Pass the packet to IP stack.
121 */
122 *verdict = NF_ACCEPT;
123 return 0;
124}
125
126
127static void
128ah_debug_packet(struct ip_vs_protocol *pp, const struct sk_buff *skb,
129 int offset, const char *msg)
130{
131 char buf[256];
132 struct iphdr _iph, *ih;
133
134 ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
135 if (ih == NULL)
136 sprintf(buf, "%s TRUNCATED", pp->name);
137 else
138 sprintf(buf, "%s %u.%u.%u.%u->%u.%u.%u.%u",
139 pp->name, NIPQUAD(ih->saddr),
140 NIPQUAD(ih->daddr));
141
142 printk(KERN_DEBUG "IPVS: %s: %s\n", msg, buf);
143}
144
145
146static void ah_init(struct ip_vs_protocol *pp)
147{
148 /* nothing to do now */
149}
150
151
152static void ah_exit(struct ip_vs_protocol *pp)
153{
154 /* nothing to do now */
155}
156
157
158struct ip_vs_protocol ip_vs_protocol_ah = {
159 .name = "AH",
160 .protocol = IPPROTO_AH,
161 .num_states = 1,
162 .dont_defrag = 1,
163 .init = ah_init,
164 .exit = ah_exit,
165 .conn_schedule = ah_conn_schedule,
166 .conn_in_get = ah_conn_in_get,
167 .conn_out_get = ah_conn_out_get,
168 .snat_handler = NULL,
169 .dnat_handler = NULL,
170 .csum_check = NULL,
171 .state_transition = NULL,
172 .register_app = NULL,
173 .unregister_app = NULL,
174 .app_conn_bind = NULL,
175 .debug_packet = ah_debug_packet,
176 .timeout_change = NULL, /* ISAKMP */
177 .set_state_timeout = NULL,
178};
diff --git a/net/ipv4/ipvs/ip_vs_proto_esp.c b/net/ipv4/ipvs/ip_vs_proto_esp.c
deleted file mode 100644
index 21d70c8ffa54..000000000000
--- a/net/ipv4/ipvs/ip_vs_proto_esp.c
+++ /dev/null
@@ -1,176 +0,0 @@
1/*
2 * ip_vs_proto_esp.c: ESP IPSec load balancing support for IPVS
3 *
4 * Authors: Julian Anastasov <ja@ssi.bg>, February 2002
5 * Wensong Zhang <wensong@linuxvirtualserver.org>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation;
10 *
11 */
12
13#include <linux/in.h>
14#include <linux/ip.h>
15#include <linux/module.h>
16#include <linux/kernel.h>
17#include <linux/netfilter.h>
18#include <linux/netfilter_ipv4.h>
19
20#include <net/ip_vs.h>
21
22
23/* TODO:
24
25struct isakmp_hdr {
26 __u8 icookie[8];
27 __u8 rcookie[8];
28 __u8 np;
29 __u8 version;
30 __u8 xchgtype;
31 __u8 flags;
32 __u32 msgid;
33 __u32 length;
34};
35
36*/
37
38#define PORT_ISAKMP 500
39
40
41static struct ip_vs_conn *
42esp_conn_in_get(const struct sk_buff *skb,
43 struct ip_vs_protocol *pp,
44 const struct iphdr *iph,
45 unsigned int proto_off,
46 int inverse)
47{
48 struct ip_vs_conn *cp;
49
50 if (likely(!inverse)) {
51 cp = ip_vs_conn_in_get(IPPROTO_UDP,
52 iph->saddr,
53 htons(PORT_ISAKMP),
54 iph->daddr,
55 htons(PORT_ISAKMP));
56 } else {
57 cp = ip_vs_conn_in_get(IPPROTO_UDP,
58 iph->daddr,
59 htons(PORT_ISAKMP),
60 iph->saddr,
61 htons(PORT_ISAKMP));
62 }
63
64 if (!cp) {
65 /*
66 * We are not sure if the packet is from our
67 * service, so our conn_schedule hook should return NF_ACCEPT
68 */
69 IP_VS_DBG(12, "Unknown ISAKMP entry for outin packet "
70 "%s%s %u.%u.%u.%u->%u.%u.%u.%u\n",
71 inverse ? "ICMP+" : "",
72 pp->name,
73 NIPQUAD(iph->saddr),
74 NIPQUAD(iph->daddr));
75 }
76
77 return cp;
78}
79
80
81static struct ip_vs_conn *
82esp_conn_out_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
83 const struct iphdr *iph, unsigned int proto_off, int inverse)
84{
85 struct ip_vs_conn *cp;
86
87 if (likely(!inverse)) {
88 cp = ip_vs_conn_out_get(IPPROTO_UDP,
89 iph->saddr,
90 htons(PORT_ISAKMP),
91 iph->daddr,
92 htons(PORT_ISAKMP));
93 } else {
94 cp = ip_vs_conn_out_get(IPPROTO_UDP,
95 iph->daddr,
96 htons(PORT_ISAKMP),
97 iph->saddr,
98 htons(PORT_ISAKMP));
99 }
100
101 if (!cp) {
102 IP_VS_DBG(12, "Unknown ISAKMP entry for inout packet "
103 "%s%s %u.%u.%u.%u->%u.%u.%u.%u\n",
104 inverse ? "ICMP+" : "",
105 pp->name,
106 NIPQUAD(iph->saddr),
107 NIPQUAD(iph->daddr));
108 }
109
110 return cp;
111}
112
113
114static int
115esp_conn_schedule(struct sk_buff *skb, struct ip_vs_protocol *pp,
116 int *verdict, struct ip_vs_conn **cpp)
117{
118 /*
119 * ESP is only related traffic. Pass the packet to IP stack.
120 */
121 *verdict = NF_ACCEPT;
122 return 0;
123}
124
125
126static void
127esp_debug_packet(struct ip_vs_protocol *pp, const struct sk_buff *skb,
128 int offset, const char *msg)
129{
130 char buf[256];
131 struct iphdr _iph, *ih;
132
133 ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
134 if (ih == NULL)
135 sprintf(buf, "%s TRUNCATED", pp->name);
136 else
137 sprintf(buf, "%s %u.%u.%u.%u->%u.%u.%u.%u",
138 pp->name, NIPQUAD(ih->saddr),
139 NIPQUAD(ih->daddr));
140
141 printk(KERN_DEBUG "IPVS: %s: %s\n", msg, buf);
142}
143
144
145static void esp_init(struct ip_vs_protocol *pp)
146{
147 /* nothing to do now */
148}
149
150
151static void esp_exit(struct ip_vs_protocol *pp)
152{
153 /* nothing to do now */
154}
155
156
157struct ip_vs_protocol ip_vs_protocol_esp = {
158 .name = "ESP",
159 .protocol = IPPROTO_ESP,
160 .num_states = 1,
161 .dont_defrag = 1,
162 .init = esp_init,
163 .exit = esp_exit,
164 .conn_schedule = esp_conn_schedule,
165 .conn_in_get = esp_conn_in_get,
166 .conn_out_get = esp_conn_out_get,
167 .snat_handler = NULL,
168 .dnat_handler = NULL,
169 .csum_check = NULL,
170 .state_transition = NULL,
171 .register_app = NULL,
172 .unregister_app = NULL,
173 .app_conn_bind = NULL,
174 .debug_packet = esp_debug_packet,
175 .timeout_change = NULL, /* ISAKMP */
176};
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index f8edacdf991d..6efdb70b3eb2 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -12,6 +12,7 @@
12/* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */ 12/* route_me_harder function, used by iptable_nat, iptable_mangle + ip_queue */
13int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) 13int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
14{ 14{
15 struct net *net = dev_net(skb->dst->dev);
15 const struct iphdr *iph = ip_hdr(skb); 16 const struct iphdr *iph = ip_hdr(skb);
16 struct rtable *rt; 17 struct rtable *rt;
17 struct flowi fl = {}; 18 struct flowi fl = {};
@@ -19,7 +20,9 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
19 unsigned int hh_len; 20 unsigned int hh_len;
20 unsigned int type; 21 unsigned int type;
21 22
22 type = inet_addr_type(&init_net, iph->saddr); 23 type = inet_addr_type(net, iph->saddr);
24 if (skb->sk && inet_sk(skb->sk)->transparent)
25 type = RTN_LOCAL;
23 if (addr_type == RTN_UNSPEC) 26 if (addr_type == RTN_UNSPEC)
24 addr_type = type; 27 addr_type = type;
25 28
@@ -33,7 +36,8 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
33 fl.nl_u.ip4_u.tos = RT_TOS(iph->tos); 36 fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
34 fl.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; 37 fl.oif = skb->sk ? skb->sk->sk_bound_dev_if : 0;
35 fl.mark = skb->mark; 38 fl.mark = skb->mark;
36 if (ip_route_output_key(&init_net, &rt, &fl) != 0) 39 fl.flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0;
40 if (ip_route_output_key(net, &rt, &fl) != 0)
37 return -1; 41 return -1;
38 42
39 /* Drop old route. */ 43 /* Drop old route. */
@@ -43,7 +47,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
43 /* non-local src, find valid iif to satisfy 47 /* non-local src, find valid iif to satisfy
44 * rp-filter when calling ip_route_input. */ 48 * rp-filter when calling ip_route_input. */
45 fl.nl_u.ip4_u.daddr = iph->saddr; 49 fl.nl_u.ip4_u.daddr = iph->saddr;
46 if (ip_route_output_key(&init_net, &rt, &fl) != 0) 50 if (ip_route_output_key(net, &rt, &fl) != 0)
47 return -1; 51 return -1;
48 52
49 odst = skb->dst; 53 odst = skb->dst;
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index 90eb7cb47e77..3816e1dc9295 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -5,10 +5,15 @@
5menu "IP: Netfilter Configuration" 5menu "IP: Netfilter Configuration"
6 depends on INET && NETFILTER 6 depends on INET && NETFILTER
7 7
8config NF_DEFRAG_IPV4
9 tristate
10 default n
11
8config NF_CONNTRACK_IPV4 12config NF_CONNTRACK_IPV4
9 tristate "IPv4 connection tracking support (required for NAT)" 13 tristate "IPv4 connection tracking support (required for NAT)"
10 depends on NF_CONNTRACK 14 depends on NF_CONNTRACK
11 default m if NETFILTER_ADVANCED=n 15 default m if NETFILTER_ADVANCED=n
16 select NF_DEFRAG_IPV4
12 ---help--- 17 ---help---
13 Connection tracking keeps a record of what packets have passed 18 Connection tracking keeps a record of what packets have passed
14 through your machine, in order to figure out how they are related 19 through your machine, in order to figure out how they are related
@@ -56,23 +61,30 @@ config IP_NF_IPTABLES
56 61
57 To compile it as a module, choose M here. If unsure, say N. 62 To compile it as a module, choose M here. If unsure, say N.
58 63
64if IP_NF_IPTABLES
65
59# The matches. 66# The matches.
60config IP_NF_MATCH_RECENT 67config IP_NF_MATCH_ADDRTYPE
61 tristate '"recent" match support' 68 tristate '"addrtype" address type match support'
62 depends on IP_NF_IPTABLES
63 depends on NETFILTER_ADVANCED 69 depends on NETFILTER_ADVANCED
64 help 70 help
65 This match is used for creating one or many lists of recently 71 This option allows you to match what routing thinks of an address,
66 used addresses and then matching against that/those list(s). 72 eg. UNICAST, LOCAL, BROADCAST, ...
67 73
68 Short options are available by using 'iptables -m recent -h' 74 If you want to compile it as a module, say M here and read
69 Official Website: <http://snowman.net/projects/ipt_recent/> 75 <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
76
77config IP_NF_MATCH_AH
78 tristate '"ah" match support'
79 depends on NETFILTER_ADVANCED
80 help
81 This match extension allows you to match a range of SPIs
82 inside AH header of IPSec packets.
70 83
71 To compile it as a module, choose M here. If unsure, say N. 84 To compile it as a module, choose M here. If unsure, say N.
72 85
73config IP_NF_MATCH_ECN 86config IP_NF_MATCH_ECN
74 tristate '"ecn" match support' 87 tristate '"ecn" match support'
75 depends on IP_NF_IPTABLES
76 depends on NETFILTER_ADVANCED 88 depends on NETFILTER_ADVANCED
77 help 89 help
78 This option adds a `ECN' match, which allows you to match against 90 This option adds a `ECN' match, which allows you to match against
@@ -80,19 +92,8 @@ config IP_NF_MATCH_ECN
80 92
81 To compile it as a module, choose M here. If unsure, say N. 93 To compile it as a module, choose M here. If unsure, say N.
82 94
83config IP_NF_MATCH_AH
84 tristate '"ah" match support'
85 depends on IP_NF_IPTABLES
86 depends on NETFILTER_ADVANCED
87 help
88 This match extension allows you to match a range of SPIs
89 inside AH header of IPSec packets.
90
91 To compile it as a module, choose M here. If unsure, say N.
92
93config IP_NF_MATCH_TTL 95config IP_NF_MATCH_TTL
94 tristate '"ttl" match support' 96 tristate '"ttl" match support'
95 depends on IP_NF_IPTABLES
96 depends on NETFILTER_ADVANCED 97 depends on NETFILTER_ADVANCED
97 help 98 help
98 This adds CONFIG_IP_NF_MATCH_TTL option, which enabled the user 99 This adds CONFIG_IP_NF_MATCH_TTL option, which enabled the user
@@ -100,21 +101,9 @@ config IP_NF_MATCH_TTL
100 101
101 To compile it as a module, choose M here. If unsure, say N. 102 To compile it as a module, choose M here. If unsure, say N.
102 103
103config IP_NF_MATCH_ADDRTYPE
104 tristate '"addrtype" address type match support'
105 depends on IP_NF_IPTABLES
106 depends on NETFILTER_ADVANCED
107 help
108 This option allows you to match what routing thinks of an address,
109 eg. UNICAST, LOCAL, BROADCAST, ...
110
111 If you want to compile it as a module, say M here and read
112 <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
113
114# `filter', generic and specific targets 104# `filter', generic and specific targets
115config IP_NF_FILTER 105config IP_NF_FILTER
116 tristate "Packet filtering" 106 tristate "Packet filtering"
117 depends on IP_NF_IPTABLES
118 default m if NETFILTER_ADVANCED=n 107 default m if NETFILTER_ADVANCED=n
119 help 108 help
120 Packet filtering defines a table `filter', which has a series of 109 Packet filtering defines a table `filter', which has a series of
@@ -136,7 +125,6 @@ config IP_NF_TARGET_REJECT
136 125
137config IP_NF_TARGET_LOG 126config IP_NF_TARGET_LOG
138 tristate "LOG target support" 127 tristate "LOG target support"
139 depends on IP_NF_IPTABLES
140 default m if NETFILTER_ADVANCED=n 128 default m if NETFILTER_ADVANCED=n
141 help 129 help
142 This option adds a `LOG' target, which allows you to create rules in 130 This option adds a `LOG' target, which allows you to create rules in
@@ -146,7 +134,6 @@ config IP_NF_TARGET_LOG
146 134
147config IP_NF_TARGET_ULOG 135config IP_NF_TARGET_ULOG
148 tristate "ULOG target support" 136 tristate "ULOG target support"
149 depends on IP_NF_IPTABLES
150 default m if NETFILTER_ADVANCED=n 137 default m if NETFILTER_ADVANCED=n
151 ---help--- 138 ---help---
152 139
@@ -167,7 +154,7 @@ config IP_NF_TARGET_ULOG
167# NAT + specific targets: nf_conntrack 154# NAT + specific targets: nf_conntrack
168config NF_NAT 155config NF_NAT
169 tristate "Full NAT" 156 tristate "Full NAT"
170 depends on IP_NF_IPTABLES && NF_CONNTRACK_IPV4 157 depends on NF_CONNTRACK_IPV4
171 default m if NETFILTER_ADVANCED=n 158 default m if NETFILTER_ADVANCED=n
172 help 159 help
173 The Full NAT option allows masquerading, port forwarding and other 160 The Full NAT option allows masquerading, port forwarding and other
@@ -194,26 +181,26 @@ config IP_NF_TARGET_MASQUERADE
194 181
195 To compile it as a module, choose M here. If unsure, say N. 182 To compile it as a module, choose M here. If unsure, say N.
196 183
197config IP_NF_TARGET_REDIRECT 184config IP_NF_TARGET_NETMAP
198 tristate "REDIRECT target support" 185 tristate "NETMAP target support"
199 depends on NF_NAT 186 depends on NF_NAT
200 depends on NETFILTER_ADVANCED 187 depends on NETFILTER_ADVANCED
201 help 188 help
202 REDIRECT is a special case of NAT: all incoming connections are 189 NETMAP is an implementation of static 1:1 NAT mapping of network
203 mapped onto the incoming interface's address, causing the packets to 190 addresses. It maps the network address part, while keeping the host
204 come to the local machine instead of passing through. This is 191 address part intact.
205 useful for transparent proxies.
206 192
207 To compile it as a module, choose M here. If unsure, say N. 193 To compile it as a module, choose M here. If unsure, say N.
208 194
209config IP_NF_TARGET_NETMAP 195config IP_NF_TARGET_REDIRECT
210 tristate "NETMAP target support" 196 tristate "REDIRECT target support"
211 depends on NF_NAT 197 depends on NF_NAT
212 depends on NETFILTER_ADVANCED 198 depends on NETFILTER_ADVANCED
213 help 199 help
214 NETMAP is an implementation of static 1:1 NAT mapping of network 200 REDIRECT is a special case of NAT: all incoming connections are
215 addresses. It maps the network address part, while keeping the host 201 mapped onto the incoming interface's address, causing the packets to
216 address part intact. 202 come to the local machine instead of passing through. This is
203 useful for transparent proxies.
217 204
218 To compile it as a module, choose M here. If unsure, say N. 205 To compile it as a module, choose M here. If unsure, say N.
219 206
@@ -262,44 +249,43 @@ config NF_NAT_PROTO_SCTP
262 249
263config NF_NAT_FTP 250config NF_NAT_FTP
264 tristate 251 tristate
265 depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT 252 depends on NF_CONNTRACK && NF_NAT
266 default NF_NAT && NF_CONNTRACK_FTP 253 default NF_NAT && NF_CONNTRACK_FTP
267 254
268config NF_NAT_IRC 255config NF_NAT_IRC
269 tristate 256 tristate
270 depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT 257 depends on NF_CONNTRACK && NF_NAT
271 default NF_NAT && NF_CONNTRACK_IRC 258 default NF_NAT && NF_CONNTRACK_IRC
272 259
273config NF_NAT_TFTP 260config NF_NAT_TFTP
274 tristate 261 tristate
275 depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT 262 depends on NF_CONNTRACK && NF_NAT
276 default NF_NAT && NF_CONNTRACK_TFTP 263 default NF_NAT && NF_CONNTRACK_TFTP
277 264
278config NF_NAT_AMANDA 265config NF_NAT_AMANDA
279 tristate 266 tristate
280 depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT 267 depends on NF_CONNTRACK && NF_NAT
281 default NF_NAT && NF_CONNTRACK_AMANDA 268 default NF_NAT && NF_CONNTRACK_AMANDA
282 269
283config NF_NAT_PPTP 270config NF_NAT_PPTP
284 tristate 271 tristate
285 depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT 272 depends on NF_CONNTRACK && NF_NAT
286 default NF_NAT && NF_CONNTRACK_PPTP 273 default NF_NAT && NF_CONNTRACK_PPTP
287 select NF_NAT_PROTO_GRE 274 select NF_NAT_PROTO_GRE
288 275
289config NF_NAT_H323 276config NF_NAT_H323
290 tristate 277 tristate
291 depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT 278 depends on NF_CONNTRACK && NF_NAT
292 default NF_NAT && NF_CONNTRACK_H323 279 default NF_NAT && NF_CONNTRACK_H323
293 280
294config NF_NAT_SIP 281config NF_NAT_SIP
295 tristate 282 tristate
296 depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT 283 depends on NF_CONNTRACK && NF_NAT
297 default NF_NAT && NF_CONNTRACK_SIP 284 default NF_NAT && NF_CONNTRACK_SIP
298 285
299# mangle + specific targets 286# mangle + specific targets
300config IP_NF_MANGLE 287config IP_NF_MANGLE
301 tristate "Packet mangling" 288 tristate "Packet mangling"
302 depends on IP_NF_IPTABLES
303 default m if NETFILTER_ADVANCED=n 289 default m if NETFILTER_ADVANCED=n
304 help 290 help
305 This option adds a `mangle' table to iptables: see the man page for 291 This option adds a `mangle' table to iptables: see the man page for
@@ -308,6 +294,19 @@ config IP_NF_MANGLE
308 294
309 To compile it as a module, choose M here. If unsure, say N. 295 To compile it as a module, choose M here. If unsure, say N.
310 296
297config IP_NF_TARGET_CLUSTERIP
298 tristate "CLUSTERIP target support (EXPERIMENTAL)"
299 depends on IP_NF_MANGLE && EXPERIMENTAL
300 depends on NF_CONNTRACK_IPV4
301 depends on NETFILTER_ADVANCED
302 select NF_CONNTRACK_MARK
303 help
304 The CLUSTERIP target allows you to build load-balancing clusters of
305 network servers without having a dedicated load-balancing
306 router/server/switch.
307
308 To compile it as a module, choose M here. If unsure, say N.
309
311config IP_NF_TARGET_ECN 310config IP_NF_TARGET_ECN
312 tristate "ECN target support" 311 tristate "ECN target support"
313 depends on IP_NF_MANGLE 312 depends on IP_NF_MANGLE
@@ -338,23 +337,9 @@ config IP_NF_TARGET_TTL
338 337
339 To compile it as a module, choose M here. If unsure, say N. 338 To compile it as a module, choose M here. If unsure, say N.
340 339
341config IP_NF_TARGET_CLUSTERIP
342 tristate "CLUSTERIP target support (EXPERIMENTAL)"
343 depends on IP_NF_MANGLE && EXPERIMENTAL
344 depends on NF_CONNTRACK_IPV4
345 depends on NETFILTER_ADVANCED
346 select NF_CONNTRACK_MARK
347 help
348 The CLUSTERIP target allows you to build load-balancing clusters of
349 network servers without having a dedicated load-balancing
350 router/server/switch.
351
352 To compile it as a module, choose M here. If unsure, say N.
353
354# raw + specific targets 340# raw + specific targets
355config IP_NF_RAW 341config IP_NF_RAW
356 tristate 'raw table support (required for NOTRACK/TRACE)' 342 tristate 'raw table support (required for NOTRACK/TRACE)'
357 depends on IP_NF_IPTABLES
358 depends on NETFILTER_ADVANCED 343 depends on NETFILTER_ADVANCED
359 help 344 help
360 This option adds a `raw' table to iptables. This table is the very 345 This option adds a `raw' table to iptables. This table is the very
@@ -367,7 +352,6 @@ config IP_NF_RAW
367# security table for MAC policy 352# security table for MAC policy
368config IP_NF_SECURITY 353config IP_NF_SECURITY
369 tristate "Security table" 354 tristate "Security table"
370 depends on IP_NF_IPTABLES
371 depends on SECURITY 355 depends on SECURITY
372 depends on NETFILTER_ADVANCED 356 depends on NETFILTER_ADVANCED
373 help 357 help
@@ -376,6 +360,8 @@ config IP_NF_SECURITY
376 360
377 If unsure, say N. 361 If unsure, say N.
378 362
363endif # IP_NF_IPTABLES
364
379# ARP tables 365# ARP tables
380config IP_NF_ARPTABLES 366config IP_NF_ARPTABLES
381 tristate "ARP tables support" 367 tristate "ARP tables support"
@@ -388,9 +374,10 @@ config IP_NF_ARPTABLES
388 374
389 To compile it as a module, choose M here. If unsure, say N. 375 To compile it as a module, choose M here. If unsure, say N.
390 376
377if IP_NF_ARPTABLES
378
391config IP_NF_ARPFILTER 379config IP_NF_ARPFILTER
392 tristate "ARP packet filtering" 380 tristate "ARP packet filtering"
393 depends on IP_NF_ARPTABLES
394 help 381 help
395 ARP packet filtering defines a table `filter', which has a series of 382 ARP packet filtering defines a table `filter', which has a series of
396 rules for simple ARP packet filtering at local input and 383 rules for simple ARP packet filtering at local input and
@@ -401,10 +388,11 @@ config IP_NF_ARPFILTER
401 388
402config IP_NF_ARP_MANGLE 389config IP_NF_ARP_MANGLE
403 tristate "ARP payload mangling" 390 tristate "ARP payload mangling"
404 depends on IP_NF_ARPTABLES
405 help 391 help
406 Allows altering the ARP packet payload: source and destination 392 Allows altering the ARP packet payload: source and destination
407 hardware and network addresses. 393 hardware and network addresses.
408 394
395endif # IP_NF_ARPTABLES
396
409endmenu 397endmenu
410 398
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index 3f31291f37ce..5f9b650d90fc 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -18,6 +18,9 @@ obj-$(CONFIG_NF_CONNTRACK_IPV4) += nf_conntrack_ipv4.o
18 18
19obj-$(CONFIG_NF_NAT) += nf_nat.o 19obj-$(CONFIG_NF_NAT) += nf_nat.o
20 20
21# defrag
22obj-$(CONFIG_NF_DEFRAG_IPV4) += nf_defrag_ipv4.o
23
21# NAT helpers (nf_conntrack) 24# NAT helpers (nf_conntrack)
22obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o 25obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o
23obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o 26obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o
@@ -48,7 +51,6 @@ obj-$(CONFIG_IP_NF_SECURITY) += iptable_security.o
48obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o 51obj-$(CONFIG_IP_NF_MATCH_ADDRTYPE) += ipt_addrtype.o
49obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o 52obj-$(CONFIG_IP_NF_MATCH_AH) += ipt_ah.o
50obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o 53obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o
51obj-$(CONFIG_IP_NF_MATCH_RECENT) += ipt_recent.o
52obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o 54obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
53 55
54# targets 56# targets
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 03e83a65aec5..8d70d29f1ccf 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -200,15 +200,12 @@ static inline int arp_checkentry(const struct arpt_arp *arp)
200 return 1; 200 return 1;
201} 201}
202 202
203static unsigned int arpt_error(struct sk_buff *skb, 203static unsigned int
204 const struct net_device *in, 204arpt_error(struct sk_buff *skb, const struct xt_target_param *par)
205 const struct net_device *out,
206 unsigned int hooknum,
207 const struct xt_target *target,
208 const void *targinfo)
209{ 205{
210 if (net_ratelimit()) 206 if (net_ratelimit())
211 printk("arp_tables: error: '%s'\n", (char *)targinfo); 207 printk("arp_tables: error: '%s'\n",
208 (const char *)par->targinfo);
212 209
213 return NF_DROP; 210 return NF_DROP;
214} 211}
@@ -232,6 +229,7 @@ unsigned int arpt_do_table(struct sk_buff *skb,
232 const char *indev, *outdev; 229 const char *indev, *outdev;
233 void *table_base; 230 void *table_base;
234 const struct xt_table_info *private; 231 const struct xt_table_info *private;
232 struct xt_target_param tgpar;
235 233
236 if (!pskb_may_pull(skb, arp_hdr_len(skb->dev))) 234 if (!pskb_may_pull(skb, arp_hdr_len(skb->dev)))
237 return NF_DROP; 235 return NF_DROP;
@@ -245,6 +243,11 @@ unsigned int arpt_do_table(struct sk_buff *skb,
245 e = get_entry(table_base, private->hook_entry[hook]); 243 e = get_entry(table_base, private->hook_entry[hook]);
246 back = get_entry(table_base, private->underflow[hook]); 244 back = get_entry(table_base, private->underflow[hook]);
247 245
246 tgpar.in = in;
247 tgpar.out = out;
248 tgpar.hooknum = hook;
249 tgpar.family = NFPROTO_ARP;
250
248 arp = arp_hdr(skb); 251 arp = arp_hdr(skb);
249 do { 252 do {
250 if (arp_packet_match(arp, skb->dev, indev, outdev, &e->arp)) { 253 if (arp_packet_match(arp, skb->dev, indev, outdev, &e->arp)) {
@@ -290,11 +293,10 @@ unsigned int arpt_do_table(struct sk_buff *skb,
290 /* Targets which reenter must return 293 /* Targets which reenter must return
291 * abs. verdicts 294 * abs. verdicts
292 */ 295 */
296 tgpar.target = t->u.kernel.target;
297 tgpar.targinfo = t->data;
293 verdict = t->u.kernel.target->target(skb, 298 verdict = t->u.kernel.target->target(skb,
294 in, out, 299 &tgpar);
295 hook,
296 t->u.kernel.target,
297 t->data);
298 300
299 /* Target might have changed stuff. */ 301 /* Target might have changed stuff. */
300 arp = arp_hdr(skb); 302 arp = arp_hdr(skb);
@@ -456,23 +458,24 @@ static inline int check_entry(struct arpt_entry *e, const char *name)
456 458
457static inline int check_target(struct arpt_entry *e, const char *name) 459static inline int check_target(struct arpt_entry *e, const char *name)
458{ 460{
459 struct arpt_entry_target *t; 461 struct arpt_entry_target *t = arpt_get_target(e);
460 struct xt_target *target;
461 int ret; 462 int ret;
462 463 struct xt_tgchk_param par = {
463 t = arpt_get_target(e); 464 .table = name,
464 target = t->u.kernel.target; 465 .entryinfo = e,
465 466 .target = t->u.kernel.target,
466 ret = xt_check_target(target, NF_ARP, t->u.target_size - sizeof(*t), 467 .targinfo = t->data,
467 name, e->comefrom, 0, 0); 468 .hook_mask = e->comefrom,
468 if (!ret && t->u.kernel.target->checkentry 469 .family = NFPROTO_ARP,
469 && !t->u.kernel.target->checkentry(name, e, target, t->data, 470 };
470 e->comefrom)) { 471
472 ret = xt_check_target(&par, t->u.target_size - sizeof(*t), 0, false);
473 if (ret < 0) {
471 duprintf("arp_tables: check failed for `%s'.\n", 474 duprintf("arp_tables: check failed for `%s'.\n",
472 t->u.kernel.target->name); 475 t->u.kernel.target->name);
473 ret = -EINVAL; 476 return ret;
474 } 477 }
475 return ret; 478 return 0;
476} 479}
477 480
478static inline int 481static inline int
@@ -488,7 +491,8 @@ find_check_entry(struct arpt_entry *e, const char *name, unsigned int size,
488 return ret; 491 return ret;
489 492
490 t = arpt_get_target(e); 493 t = arpt_get_target(e);
491 target = try_then_request_module(xt_find_target(NF_ARP, t->u.user.name, 494 target = try_then_request_module(xt_find_target(NFPROTO_ARP,
495 t->u.user.name,
492 t->u.user.revision), 496 t->u.user.revision),
493 "arpt_%s", t->u.user.name); 497 "arpt_%s", t->u.user.name);
494 if (IS_ERR(target) || !target) { 498 if (IS_ERR(target) || !target) {
@@ -554,15 +558,19 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e,
554 558
555static inline int cleanup_entry(struct arpt_entry *e, unsigned int *i) 559static inline int cleanup_entry(struct arpt_entry *e, unsigned int *i)
556{ 560{
561 struct xt_tgdtor_param par;
557 struct arpt_entry_target *t; 562 struct arpt_entry_target *t;
558 563
559 if (i && (*i)-- == 0) 564 if (i && (*i)-- == 0)
560 return 1; 565 return 1;
561 566
562 t = arpt_get_target(e); 567 t = arpt_get_target(e);
563 if (t->u.kernel.target->destroy) 568 par.target = t->u.kernel.target;
564 t->u.kernel.target->destroy(t->u.kernel.target, t->data); 569 par.targinfo = t->data;
565 module_put(t->u.kernel.target->me); 570 par.family = NFPROTO_ARP;
571 if (par.target->destroy != NULL)
572 par.target->destroy(&par);
573 module_put(par.target->me);
566 return 0; 574 return 0;
567} 575}
568 576
@@ -788,7 +796,7 @@ static void compat_standard_from_user(void *dst, void *src)
788 int v = *(compat_int_t *)src; 796 int v = *(compat_int_t *)src;
789 797
790 if (v > 0) 798 if (v > 0)
791 v += xt_compat_calc_jump(NF_ARP, v); 799 v += xt_compat_calc_jump(NFPROTO_ARP, v);
792 memcpy(dst, &v, sizeof(v)); 800 memcpy(dst, &v, sizeof(v));
793} 801}
794 802
@@ -797,7 +805,7 @@ static int compat_standard_to_user(void __user *dst, void *src)
797 compat_int_t cv = *(int *)src; 805 compat_int_t cv = *(int *)src;
798 806
799 if (cv > 0) 807 if (cv > 0)
800 cv -= xt_compat_calc_jump(NF_ARP, cv); 808 cv -= xt_compat_calc_jump(NFPROTO_ARP, cv);
801 return copy_to_user(dst, &cv, sizeof(cv)) ? -EFAULT : 0; 809 return copy_to_user(dst, &cv, sizeof(cv)) ? -EFAULT : 0;
802} 810}
803 811
@@ -815,7 +823,7 @@ static int compat_calc_entry(struct arpt_entry *e,
815 t = arpt_get_target(e); 823 t = arpt_get_target(e);
816 off += xt_compat_target_offset(t->u.kernel.target); 824 off += xt_compat_target_offset(t->u.kernel.target);
817 newinfo->size -= off; 825 newinfo->size -= off;
818 ret = xt_compat_add_offset(NF_ARP, entry_offset, off); 826 ret = xt_compat_add_offset(NFPROTO_ARP, entry_offset, off);
819 if (ret) 827 if (ret)
820 return ret; 828 return ret;
821 829
@@ -866,9 +874,9 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
866 name[ARPT_TABLE_MAXNAMELEN-1] = '\0'; 874 name[ARPT_TABLE_MAXNAMELEN-1] = '\0';
867#ifdef CONFIG_COMPAT 875#ifdef CONFIG_COMPAT
868 if (compat) 876 if (compat)
869 xt_compat_lock(NF_ARP); 877 xt_compat_lock(NFPROTO_ARP);
870#endif 878#endif
871 t = try_then_request_module(xt_find_table_lock(net, NF_ARP, name), 879 t = try_then_request_module(xt_find_table_lock(net, NFPROTO_ARP, name),
872 "arptable_%s", name); 880 "arptable_%s", name);
873 if (t && !IS_ERR(t)) { 881 if (t && !IS_ERR(t)) {
874 struct arpt_getinfo info; 882 struct arpt_getinfo info;
@@ -878,7 +886,7 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
878 if (compat) { 886 if (compat) {
879 struct xt_table_info tmp; 887 struct xt_table_info tmp;
880 ret = compat_table_info(private, &tmp); 888 ret = compat_table_info(private, &tmp);
881 xt_compat_flush_offsets(NF_ARP); 889 xt_compat_flush_offsets(NFPROTO_ARP);
882 private = &tmp; 890 private = &tmp;
883 } 891 }
884#endif 892#endif
@@ -901,7 +909,7 @@ static int get_info(struct net *net, void __user *user, int *len, int compat)
901 ret = t ? PTR_ERR(t) : -ENOENT; 909 ret = t ? PTR_ERR(t) : -ENOENT;
902#ifdef CONFIG_COMPAT 910#ifdef CONFIG_COMPAT
903 if (compat) 911 if (compat)
904 xt_compat_unlock(NF_ARP); 912 xt_compat_unlock(NFPROTO_ARP);
905#endif 913#endif
906 return ret; 914 return ret;
907} 915}
@@ -925,7 +933,7 @@ static int get_entries(struct net *net, struct arpt_get_entries __user *uptr,
925 return -EINVAL; 933 return -EINVAL;
926 } 934 }
927 935
928 t = xt_find_table_lock(net, NF_ARP, get.name); 936 t = xt_find_table_lock(net, NFPROTO_ARP, get.name);
929 if (t && !IS_ERR(t)) { 937 if (t && !IS_ERR(t)) {
930 const struct xt_table_info *private = t->private; 938 const struct xt_table_info *private = t->private;
931 939
@@ -967,7 +975,7 @@ static int __do_replace(struct net *net, const char *name,
967 goto out; 975 goto out;
968 } 976 }
969 977
970 t = try_then_request_module(xt_find_table_lock(net, NF_ARP, name), 978 t = try_then_request_module(xt_find_table_lock(net, NFPROTO_ARP, name),
971 "arptable_%s", name); 979 "arptable_%s", name);
972 if (!t || IS_ERR(t)) { 980 if (!t || IS_ERR(t)) {
973 ret = t ? PTR_ERR(t) : -ENOENT; 981 ret = t ? PTR_ERR(t) : -ENOENT;
@@ -1134,7 +1142,7 @@ static int do_add_counters(struct net *net, void __user *user, unsigned int len,
1134 goto free; 1142 goto free;
1135 } 1143 }
1136 1144
1137 t = xt_find_table_lock(net, NF_ARP, name); 1145 t = xt_find_table_lock(net, NFPROTO_ARP, name);
1138 if (!t || IS_ERR(t)) { 1146 if (!t || IS_ERR(t)) {
1139 ret = t ? PTR_ERR(t) : -ENOENT; 1147 ret = t ? PTR_ERR(t) : -ENOENT;
1140 goto free; 1148 goto free;
@@ -1218,7 +1226,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
1218 entry_offset = (void *)e - (void *)base; 1226 entry_offset = (void *)e - (void *)base;
1219 1227
1220 t = compat_arpt_get_target(e); 1228 t = compat_arpt_get_target(e);
1221 target = try_then_request_module(xt_find_target(NF_ARP, 1229 target = try_then_request_module(xt_find_target(NFPROTO_ARP,
1222 t->u.user.name, 1230 t->u.user.name,
1223 t->u.user.revision), 1231 t->u.user.revision),
1224 "arpt_%s", t->u.user.name); 1232 "arpt_%s", t->u.user.name);
@@ -1232,7 +1240,7 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
1232 1240
1233 off += xt_compat_target_offset(target); 1241 off += xt_compat_target_offset(target);
1234 *size += off; 1242 *size += off;
1235 ret = xt_compat_add_offset(NF_ARP, entry_offset, off); 1243 ret = xt_compat_add_offset(NFPROTO_ARP, entry_offset, off);
1236 if (ret) 1244 if (ret)
1237 goto release_target; 1245 goto release_target;
1238 1246
@@ -1333,7 +1341,7 @@ static int translate_compat_table(const char *name,
1333 1341
1334 duprintf("translate_compat_table: size %u\n", info->size); 1342 duprintf("translate_compat_table: size %u\n", info->size);
1335 j = 0; 1343 j = 0;
1336 xt_compat_lock(NF_ARP); 1344 xt_compat_lock(NFPROTO_ARP);
1337 /* Walk through entries, checking offsets. */ 1345 /* Walk through entries, checking offsets. */
1338 ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, 1346 ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size,
1339 check_compat_entry_size_and_hooks, 1347 check_compat_entry_size_and_hooks,
@@ -1383,8 +1391,8 @@ static int translate_compat_table(const char *name,
1383 ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, 1391 ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size,
1384 compat_copy_entry_from_user, 1392 compat_copy_entry_from_user,
1385 &pos, &size, name, newinfo, entry1); 1393 &pos, &size, name, newinfo, entry1);
1386 xt_compat_flush_offsets(NF_ARP); 1394 xt_compat_flush_offsets(NFPROTO_ARP);
1387 xt_compat_unlock(NF_ARP); 1395 xt_compat_unlock(NFPROTO_ARP);
1388 if (ret) 1396 if (ret)
1389 goto free_newinfo; 1397 goto free_newinfo;
1390 1398
@@ -1420,8 +1428,8 @@ out:
1420 COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j); 1428 COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j);
1421 return ret; 1429 return ret;
1422out_unlock: 1430out_unlock:
1423 xt_compat_flush_offsets(NF_ARP); 1431 xt_compat_flush_offsets(NFPROTO_ARP);
1424 xt_compat_unlock(NF_ARP); 1432 xt_compat_unlock(NFPROTO_ARP);
1425 goto out; 1433 goto out;
1426} 1434}
1427 1435
@@ -1607,8 +1615,8 @@ static int compat_get_entries(struct net *net,
1607 return -EINVAL; 1615 return -EINVAL;
1608 } 1616 }
1609 1617
1610 xt_compat_lock(NF_ARP); 1618 xt_compat_lock(NFPROTO_ARP);
1611 t = xt_find_table_lock(net, NF_ARP, get.name); 1619 t = xt_find_table_lock(net, NFPROTO_ARP, get.name);
1612 if (t && !IS_ERR(t)) { 1620 if (t && !IS_ERR(t)) {
1613 const struct xt_table_info *private = t->private; 1621 const struct xt_table_info *private = t->private;
1614 struct xt_table_info info; 1622 struct xt_table_info info;
@@ -1623,13 +1631,13 @@ static int compat_get_entries(struct net *net,
1623 private->size, get.size); 1631 private->size, get.size);
1624 ret = -EAGAIN; 1632 ret = -EAGAIN;
1625 } 1633 }
1626 xt_compat_flush_offsets(NF_ARP); 1634 xt_compat_flush_offsets(NFPROTO_ARP);
1627 module_put(t->me); 1635 module_put(t->me);
1628 xt_table_unlock(t); 1636 xt_table_unlock(t);
1629 } else 1637 } else
1630 ret = t ? PTR_ERR(t) : -ENOENT; 1638 ret = t ? PTR_ERR(t) : -ENOENT;
1631 1639
1632 xt_compat_unlock(NF_ARP); 1640 xt_compat_unlock(NFPROTO_ARP);
1633 return ret; 1641 return ret;
1634} 1642}
1635 1643
@@ -1709,7 +1717,7 @@ static int do_arpt_get_ctl(struct sock *sk, int cmd, void __user *user, int *len
1709 break; 1717 break;
1710 } 1718 }
1711 1719
1712 try_then_request_module(xt_find_revision(NF_ARP, rev.name, 1720 try_then_request_module(xt_find_revision(NFPROTO_ARP, rev.name,
1713 rev.revision, 1, &ret), 1721 rev.revision, 1, &ret),
1714 "arpt_%s", rev.name); 1722 "arpt_%s", rev.name);
1715 break; 1723 break;
@@ -1787,7 +1795,7 @@ void arpt_unregister_table(struct xt_table *table)
1787static struct xt_target arpt_standard_target __read_mostly = { 1795static struct xt_target arpt_standard_target __read_mostly = {
1788 .name = ARPT_STANDARD_TARGET, 1796 .name = ARPT_STANDARD_TARGET,
1789 .targetsize = sizeof(int), 1797 .targetsize = sizeof(int),
1790 .family = NF_ARP, 1798 .family = NFPROTO_ARP,
1791#ifdef CONFIG_COMPAT 1799#ifdef CONFIG_COMPAT
1792 .compatsize = sizeof(compat_int_t), 1800 .compatsize = sizeof(compat_int_t),
1793 .compat_from_user = compat_standard_from_user, 1801 .compat_from_user = compat_standard_from_user,
@@ -1799,7 +1807,7 @@ static struct xt_target arpt_error_target __read_mostly = {
1799 .name = ARPT_ERROR_TARGET, 1807 .name = ARPT_ERROR_TARGET,
1800 .target = arpt_error, 1808 .target = arpt_error,
1801 .targetsize = ARPT_FUNCTION_MAXNAMELEN, 1809 .targetsize = ARPT_FUNCTION_MAXNAMELEN,
1802 .family = NF_ARP, 1810 .family = NFPROTO_ARP,
1803}; 1811};
1804 1812
1805static struct nf_sockopt_ops arpt_sockopts = { 1813static struct nf_sockopt_ops arpt_sockopts = {
@@ -1821,12 +1829,12 @@ static struct nf_sockopt_ops arpt_sockopts = {
1821 1829
1822static int __net_init arp_tables_net_init(struct net *net) 1830static int __net_init arp_tables_net_init(struct net *net)
1823{ 1831{
1824 return xt_proto_init(net, NF_ARP); 1832 return xt_proto_init(net, NFPROTO_ARP);
1825} 1833}
1826 1834
1827static void __net_exit arp_tables_net_exit(struct net *net) 1835static void __net_exit arp_tables_net_exit(struct net *net)
1828{ 1836{
1829 xt_proto_fini(net, NF_ARP); 1837 xt_proto_fini(net, NFPROTO_ARP);
1830} 1838}
1831 1839
1832static struct pernet_operations arp_tables_net_ops = { 1840static struct pernet_operations arp_tables_net_ops = {
diff --git a/net/ipv4/netfilter/arpt_mangle.c b/net/ipv4/netfilter/arpt_mangle.c
index a385959d2655..b0d5b1d0a769 100644
--- a/net/ipv4/netfilter/arpt_mangle.c
+++ b/net/ipv4/netfilter/arpt_mangle.c
@@ -9,12 +9,9 @@ MODULE_AUTHOR("Bart De Schuymer <bdschuym@pandora.be>");
9MODULE_DESCRIPTION("arptables arp payload mangle target"); 9MODULE_DESCRIPTION("arptables arp payload mangle target");
10 10
11static unsigned int 11static unsigned int
12target(struct sk_buff *skb, 12target(struct sk_buff *skb, const struct xt_target_param *par)
13 const struct net_device *in, const struct net_device *out,
14 unsigned int hooknum, const struct xt_target *target,
15 const void *targinfo)
16{ 13{
17 const struct arpt_mangle *mangle = targinfo; 14 const struct arpt_mangle *mangle = par->targinfo;
18 const struct arphdr *arp; 15 const struct arphdr *arp;
19 unsigned char *arpptr; 16 unsigned char *arpptr;
20 int pln, hln; 17 int pln, hln;
@@ -57,11 +54,9 @@ target(struct sk_buff *skb,
57 return mangle->target; 54 return mangle->target;
58} 55}
59 56
60static bool 57static bool checkentry(const struct xt_tgchk_param *par)
61checkentry(const char *tablename, const void *e, const struct xt_target *target,
62 void *targinfo, unsigned int hook_mask)
63{ 58{
64 const struct arpt_mangle *mangle = targinfo; 59 const struct arpt_mangle *mangle = par->targinfo;
65 60
66 if (mangle->flags & ~ARPT_MANGLE_MASK || 61 if (mangle->flags & ~ARPT_MANGLE_MASK ||
67 !(mangle->flags & ARPT_MANGLE_MASK)) 62 !(mangle->flags & ARPT_MANGLE_MASK))
@@ -75,7 +70,7 @@ checkentry(const char *tablename, const void *e, const struct xt_target *target,
75 70
76static struct xt_target arpt_mangle_reg __read_mostly = { 71static struct xt_target arpt_mangle_reg __read_mostly = {
77 .name = "mangle", 72 .name = "mangle",
78 .family = NF_ARP, 73 .family = NFPROTO_ARP,
79 .target = target, 74 .target = target,
80 .targetsize = sizeof(struct arpt_mangle), 75 .targetsize = sizeof(struct arpt_mangle),
81 .checkentry = checkentry, 76 .checkentry = checkentry,
diff --git a/net/ipv4/netfilter/arptable_filter.c b/net/ipv4/netfilter/arptable_filter.c
index 082f5dd3156c..bee3d117661a 100644
--- a/net/ipv4/netfilter/arptable_filter.c
+++ b/net/ipv4/netfilter/arptable_filter.c
@@ -51,7 +51,7 @@ static struct xt_table packet_filter = {
51 .lock = __RW_LOCK_UNLOCKED(packet_filter.lock), 51 .lock = __RW_LOCK_UNLOCKED(packet_filter.lock),
52 .private = NULL, 52 .private = NULL,
53 .me = THIS_MODULE, 53 .me = THIS_MODULE,
54 .af = NF_ARP, 54 .af = NFPROTO_ARP,
55}; 55};
56 56
57/* The work comes in here from netfilter.c */ 57/* The work comes in here from netfilter.c */
@@ -89,21 +89,21 @@ static struct nf_hook_ops arpt_ops[] __read_mostly = {
89 { 89 {
90 .hook = arpt_in_hook, 90 .hook = arpt_in_hook,
91 .owner = THIS_MODULE, 91 .owner = THIS_MODULE,
92 .pf = NF_ARP, 92 .pf = NFPROTO_ARP,
93 .hooknum = NF_ARP_IN, 93 .hooknum = NF_ARP_IN,
94 .priority = NF_IP_PRI_FILTER, 94 .priority = NF_IP_PRI_FILTER,
95 }, 95 },
96 { 96 {
97 .hook = arpt_out_hook, 97 .hook = arpt_out_hook,
98 .owner = THIS_MODULE, 98 .owner = THIS_MODULE,
99 .pf = NF_ARP, 99 .pf = NFPROTO_ARP,
100 .hooknum = NF_ARP_OUT, 100 .hooknum = NF_ARP_OUT,
101 .priority = NF_IP_PRI_FILTER, 101 .priority = NF_IP_PRI_FILTER,
102 }, 102 },
103 { 103 {
104 .hook = arpt_forward_hook, 104 .hook = arpt_forward_hook,
105 .owner = THIS_MODULE, 105 .owner = THIS_MODULE,
106 .pf = NF_ARP, 106 .pf = NFPROTO_ARP,
107 .hooknum = NF_ARP_FORWARD, 107 .hooknum = NF_ARP_FORWARD,
108 .priority = NF_IP_PRI_FILTER, 108 .priority = NF_IP_PRI_FILTER,
109 }, 109 },
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 4e7c719445c2..213fb27debc1 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -171,31 +171,25 @@ ip_checkentry(const struct ipt_ip *ip)
171} 171}
172 172
173static unsigned int 173static unsigned int
174ipt_error(struct sk_buff *skb, 174ipt_error(struct sk_buff *skb, const struct xt_target_param *par)
175 const struct net_device *in,
176 const struct net_device *out,
177 unsigned int hooknum,
178 const struct xt_target *target,
179 const void *targinfo)
180{ 175{
181 if (net_ratelimit()) 176 if (net_ratelimit())
182 printk("ip_tables: error: `%s'\n", (char *)targinfo); 177 printk("ip_tables: error: `%s'\n",
178 (const char *)par->targinfo);
183 179
184 return NF_DROP; 180 return NF_DROP;
185} 181}
186 182
187/* Performance critical - called for every packet */ 183/* Performance critical - called for every packet */
188static inline bool 184static inline bool
189do_match(struct ipt_entry_match *m, 185do_match(struct ipt_entry_match *m, const struct sk_buff *skb,
190 const struct sk_buff *skb, 186 struct xt_match_param *par)
191 const struct net_device *in,
192 const struct net_device *out,
193 int offset,
194 bool *hotdrop)
195{ 187{
188 par->match = m->u.kernel.match;
189 par->matchinfo = m->data;
190
196 /* Stop iteration if it doesn't match */ 191 /* Stop iteration if it doesn't match */
197 if (!m->u.kernel.match->match(skb, in, out, m->u.kernel.match, m->data, 192 if (!m->u.kernel.match->match(skb, par))
198 offset, ip_hdrlen(skb), hotdrop))
199 return true; 193 return true;
200 else 194 else
201 return false; 195 return false;
@@ -326,7 +320,6 @@ ipt_do_table(struct sk_buff *skb,
326 struct xt_table *table) 320 struct xt_table *table)
327{ 321{
328 static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); 322 static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
329 u_int16_t offset;
330 const struct iphdr *ip; 323 const struct iphdr *ip;
331 u_int16_t datalen; 324 u_int16_t datalen;
332 bool hotdrop = false; 325 bool hotdrop = false;
@@ -336,6 +329,8 @@ ipt_do_table(struct sk_buff *skb,
336 void *table_base; 329 void *table_base;
337 struct ipt_entry *e, *back; 330 struct ipt_entry *e, *back;
338 struct xt_table_info *private; 331 struct xt_table_info *private;
332 struct xt_match_param mtpar;
333 struct xt_target_param tgpar;
339 334
340 /* Initialization */ 335 /* Initialization */
341 ip = ip_hdr(skb); 336 ip = ip_hdr(skb);
@@ -348,7 +343,13 @@ ipt_do_table(struct sk_buff *skb,
348 * things we don't know, ie. tcp syn flag or ports). If the 343 * things we don't know, ie. tcp syn flag or ports). If the
349 * rule is also a fragment-specific rule, non-fragments won't 344 * rule is also a fragment-specific rule, non-fragments won't
350 * match it. */ 345 * match it. */
351 offset = ntohs(ip->frag_off) & IP_OFFSET; 346 mtpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
347 mtpar.thoff = ip_hdrlen(skb);
348 mtpar.hotdrop = &hotdrop;
349 mtpar.in = tgpar.in = in;
350 mtpar.out = tgpar.out = out;
351 mtpar.family = tgpar.family = NFPROTO_IPV4;
352 tgpar.hooknum = hook;
352 353
353 read_lock_bh(&table->lock); 354 read_lock_bh(&table->lock);
354 IP_NF_ASSERT(table->valid_hooks & (1 << hook)); 355 IP_NF_ASSERT(table->valid_hooks & (1 << hook));
@@ -362,12 +363,11 @@ ipt_do_table(struct sk_buff *skb,
362 do { 363 do {
363 IP_NF_ASSERT(e); 364 IP_NF_ASSERT(e);
364 IP_NF_ASSERT(back); 365 IP_NF_ASSERT(back);
365 if (ip_packet_match(ip, indev, outdev, &e->ip, offset)) { 366 if (ip_packet_match(ip, indev, outdev,
367 &e->ip, mtpar.fragoff)) {
366 struct ipt_entry_target *t; 368 struct ipt_entry_target *t;
367 369
368 if (IPT_MATCH_ITERATE(e, do_match, 370 if (IPT_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0)
369 skb, in, out,
370 offset, &hotdrop) != 0)
371 goto no_match; 371 goto no_match;
372 372
373 ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1); 373 ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1);
@@ -413,16 +413,14 @@ ipt_do_table(struct sk_buff *skb,
413 } else { 413 } else {
414 /* Targets which reenter must return 414 /* Targets which reenter must return
415 abs. verdicts */ 415 abs. verdicts */
416 tgpar.target = t->u.kernel.target;
417 tgpar.targinfo = t->data;
416#ifdef CONFIG_NETFILTER_DEBUG 418#ifdef CONFIG_NETFILTER_DEBUG
417 ((struct ipt_entry *)table_base)->comefrom 419 ((struct ipt_entry *)table_base)->comefrom
418 = 0xeeeeeeec; 420 = 0xeeeeeeec;
419#endif 421#endif
420 verdict = t->u.kernel.target->target(skb, 422 verdict = t->u.kernel.target->target(skb,
421 in, out, 423 &tgpar);
422 hook,
423 t->u.kernel.target,
424 t->data);
425
426#ifdef CONFIG_NETFILTER_DEBUG 424#ifdef CONFIG_NETFILTER_DEBUG
427 if (((struct ipt_entry *)table_base)->comefrom 425 if (((struct ipt_entry *)table_base)->comefrom
428 != 0xeeeeeeec 426 != 0xeeeeeeec
@@ -575,12 +573,17 @@ mark_source_chains(struct xt_table_info *newinfo,
575static int 573static int
576cleanup_match(struct ipt_entry_match *m, unsigned int *i) 574cleanup_match(struct ipt_entry_match *m, unsigned int *i)
577{ 575{
576 struct xt_mtdtor_param par;
577
578 if (i && (*i)-- == 0) 578 if (i && (*i)-- == 0)
579 return 1; 579 return 1;
580 580
581 if (m->u.kernel.match->destroy) 581 par.match = m->u.kernel.match;
582 m->u.kernel.match->destroy(m->u.kernel.match, m->data); 582 par.matchinfo = m->data;
583 module_put(m->u.kernel.match->me); 583 par.family = NFPROTO_IPV4;
584 if (par.match->destroy != NULL)
585 par.match->destroy(&par);
586 module_put(par.match->me);
584 return 0; 587 return 0;
585} 588}
586 589
@@ -606,34 +609,28 @@ check_entry(struct ipt_entry *e, const char *name)
606} 609}
607 610
608static int 611static int
609check_match(struct ipt_entry_match *m, const char *name, 612check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par,
610 const struct ipt_ip *ip, 613 unsigned int *i)
611 unsigned int hookmask, unsigned int *i)
612{ 614{
613 struct xt_match *match; 615 const struct ipt_ip *ip = par->entryinfo;
614 int ret; 616 int ret;
615 617
616 match = m->u.kernel.match; 618 par->match = m->u.kernel.match;
617 ret = xt_check_match(match, AF_INET, m->u.match_size - sizeof(*m), 619 par->matchinfo = m->data;
618 name, hookmask, ip->proto, 620
619 ip->invflags & IPT_INV_PROTO); 621 ret = xt_check_match(par, m->u.match_size - sizeof(*m),
620 if (!ret && m->u.kernel.match->checkentry 622 ip->proto, ip->invflags & IPT_INV_PROTO);
621 && !m->u.kernel.match->checkentry(name, ip, match, m->data, 623 if (ret < 0) {
622 hookmask)) {
623 duprintf("ip_tables: check failed for `%s'.\n", 624 duprintf("ip_tables: check failed for `%s'.\n",
624 m->u.kernel.match->name); 625 par.match->name);
625 ret = -EINVAL; 626 return ret;
626 } 627 }
627 if (!ret) 628 ++*i;
628 (*i)++; 629 return 0;
629 return ret;
630} 630}
631 631
632static int 632static int
633find_check_match(struct ipt_entry_match *m, 633find_check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par,
634 const char *name,
635 const struct ipt_ip *ip,
636 unsigned int hookmask,
637 unsigned int *i) 634 unsigned int *i)
638{ 635{
639 struct xt_match *match; 636 struct xt_match *match;
@@ -648,7 +645,7 @@ find_check_match(struct ipt_entry_match *m,
648 } 645 }
649 m->u.kernel.match = match; 646 m->u.kernel.match = match;
650 647
651 ret = check_match(m, name, ip, hookmask, i); 648 ret = check_match(m, par, i);
652 if (ret) 649 if (ret)
653 goto err; 650 goto err;
654 651
@@ -660,23 +657,25 @@ err:
660 657
661static int check_target(struct ipt_entry *e, const char *name) 658static int check_target(struct ipt_entry *e, const char *name)
662{ 659{
663 struct ipt_entry_target *t; 660 struct ipt_entry_target *t = ipt_get_target(e);
664 struct xt_target *target; 661 struct xt_tgchk_param par = {
662 .table = name,
663 .entryinfo = e,
664 .target = t->u.kernel.target,
665 .targinfo = t->data,
666 .hook_mask = e->comefrom,
667 .family = NFPROTO_IPV4,
668 };
665 int ret; 669 int ret;
666 670
667 t = ipt_get_target(e); 671 ret = xt_check_target(&par, t->u.target_size - sizeof(*t),
668 target = t->u.kernel.target; 672 e->ip.proto, e->ip.invflags & IPT_INV_PROTO);
669 ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t), 673 if (ret < 0) {
670 name, e->comefrom, e->ip.proto,
671 e->ip.invflags & IPT_INV_PROTO);
672 if (!ret && t->u.kernel.target->checkentry
673 && !t->u.kernel.target->checkentry(name, e, target, t->data,
674 e->comefrom)) {
675 duprintf("ip_tables: check failed for `%s'.\n", 674 duprintf("ip_tables: check failed for `%s'.\n",
676 t->u.kernel.target->name); 675 t->u.kernel.target->name);
677 ret = -EINVAL; 676 return ret;
678 } 677 }
679 return ret; 678 return 0;
680} 679}
681 680
682static int 681static int
@@ -687,14 +686,18 @@ find_check_entry(struct ipt_entry *e, const char *name, unsigned int size,
687 struct xt_target *target; 686 struct xt_target *target;
688 int ret; 687 int ret;
689 unsigned int j; 688 unsigned int j;
689 struct xt_mtchk_param mtpar;
690 690
691 ret = check_entry(e, name); 691 ret = check_entry(e, name);
692 if (ret) 692 if (ret)
693 return ret; 693 return ret;
694 694
695 j = 0; 695 j = 0;
696 ret = IPT_MATCH_ITERATE(e, find_check_match, name, &e->ip, 696 mtpar.table = name;
697 e->comefrom, &j); 697 mtpar.entryinfo = &e->ip;
698 mtpar.hook_mask = e->comefrom;
699 mtpar.family = NFPROTO_IPV4;
700 ret = IPT_MATCH_ITERATE(e, find_check_match, &mtpar, &j);
698 if (ret != 0) 701 if (ret != 0)
699 goto cleanup_matches; 702 goto cleanup_matches;
700 703
@@ -769,6 +772,7 @@ check_entry_size_and_hooks(struct ipt_entry *e,
769static int 772static int
770cleanup_entry(struct ipt_entry *e, unsigned int *i) 773cleanup_entry(struct ipt_entry *e, unsigned int *i)
771{ 774{
775 struct xt_tgdtor_param par;
772 struct ipt_entry_target *t; 776 struct ipt_entry_target *t;
773 777
774 if (i && (*i)-- == 0) 778 if (i && (*i)-- == 0)
@@ -777,9 +781,13 @@ cleanup_entry(struct ipt_entry *e, unsigned int *i)
777 /* Cleanup all matches */ 781 /* Cleanup all matches */
778 IPT_MATCH_ITERATE(e, cleanup_match, NULL); 782 IPT_MATCH_ITERATE(e, cleanup_match, NULL);
779 t = ipt_get_target(e); 783 t = ipt_get_target(e);
780 if (t->u.kernel.target->destroy) 784
781 t->u.kernel.target->destroy(t->u.kernel.target, t->data); 785 par.target = t->u.kernel.target;
782 module_put(t->u.kernel.target->me); 786 par.targinfo = t->data;
787 par.family = NFPROTO_IPV4;
788 if (par.target->destroy != NULL)
789 par.target->destroy(&par);
790 module_put(par.target->me);
783 return 0; 791 return 0;
784} 792}
785 793
@@ -1648,12 +1656,16 @@ static int
1648compat_check_entry(struct ipt_entry *e, const char *name, 1656compat_check_entry(struct ipt_entry *e, const char *name,
1649 unsigned int *i) 1657 unsigned int *i)
1650{ 1658{
1659 struct xt_mtchk_param mtpar;
1651 unsigned int j; 1660 unsigned int j;
1652 int ret; 1661 int ret;
1653 1662
1654 j = 0; 1663 j = 0;
1655 ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, 1664 mtpar.table = name;
1656 e->comefrom, &j); 1665 mtpar.entryinfo = &e->ip;
1666 mtpar.hook_mask = e->comefrom;
1667 mtpar.family = NFPROTO_IPV4;
1668 ret = IPT_MATCH_ITERATE(e, check_match, &mtpar, &j);
1657 if (ret) 1669 if (ret)
1658 goto cleanup_matches; 1670 goto cleanup_matches;
1659 1671
@@ -2121,30 +2133,23 @@ icmp_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code,
2121} 2133}
2122 2134
2123static bool 2135static bool
2124icmp_match(const struct sk_buff *skb, 2136icmp_match(const struct sk_buff *skb, const struct xt_match_param *par)
2125 const struct net_device *in,
2126 const struct net_device *out,
2127 const struct xt_match *match,
2128 const void *matchinfo,
2129 int offset,
2130 unsigned int protoff,
2131 bool *hotdrop)
2132{ 2137{
2133 const struct icmphdr *ic; 2138 const struct icmphdr *ic;
2134 struct icmphdr _icmph; 2139 struct icmphdr _icmph;
2135 const struct ipt_icmp *icmpinfo = matchinfo; 2140 const struct ipt_icmp *icmpinfo = par->matchinfo;
2136 2141
2137 /* Must not be a fragment. */ 2142 /* Must not be a fragment. */
2138 if (offset) 2143 if (par->fragoff != 0)
2139 return false; 2144 return false;
2140 2145
2141 ic = skb_header_pointer(skb, protoff, sizeof(_icmph), &_icmph); 2146 ic = skb_header_pointer(skb, par->thoff, sizeof(_icmph), &_icmph);
2142 if (ic == NULL) { 2147 if (ic == NULL) {
2143 /* We've been asked to examine this packet, and we 2148 /* We've been asked to examine this packet, and we
2144 * can't. Hence, no choice but to drop. 2149 * can't. Hence, no choice but to drop.
2145 */ 2150 */
2146 duprintf("Dropping evil ICMP tinygram.\n"); 2151 duprintf("Dropping evil ICMP tinygram.\n");
2147 *hotdrop = true; 2152 *par->hotdrop = true;
2148 return false; 2153 return false;
2149 } 2154 }
2150 2155
@@ -2155,15 +2160,9 @@ icmp_match(const struct sk_buff *skb,
2155 !!(icmpinfo->invflags&IPT_ICMP_INV)); 2160 !!(icmpinfo->invflags&IPT_ICMP_INV));
2156} 2161}
2157 2162
2158/* Called when user tries to insert an entry of this type. */ 2163static bool icmp_checkentry(const struct xt_mtchk_param *par)
2159static bool
2160icmp_checkentry(const char *tablename,
2161 const void *entry,
2162 const struct xt_match *match,
2163 void *matchinfo,
2164 unsigned int hook_mask)
2165{ 2164{
2166 const struct ipt_icmp *icmpinfo = matchinfo; 2165 const struct ipt_icmp *icmpinfo = par->matchinfo;
2167 2166
2168 /* Must specify no unknown invflags */ 2167 /* Must specify no unknown invflags */
2169 return !(icmpinfo->invflags & ~IPT_ICMP_INV); 2168 return !(icmpinfo->invflags & ~IPT_ICMP_INV);
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index fafe8ebb4c55..7ac1677419a9 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -281,11 +281,9 @@ clusterip_responsible(const struct clusterip_config *config, u_int32_t hash)
281 ***********************************************************************/ 281 ***********************************************************************/
282 282
283static unsigned int 283static unsigned int
284clusterip_tg(struct sk_buff *skb, const struct net_device *in, 284clusterip_tg(struct sk_buff *skb, const struct xt_target_param *par)
285 const struct net_device *out, unsigned int hooknum,
286 const struct xt_target *target, const void *targinfo)
287{ 285{
288 const struct ipt_clusterip_tgt_info *cipinfo = targinfo; 286 const struct ipt_clusterip_tgt_info *cipinfo = par->targinfo;
289 struct nf_conn *ct; 287 struct nf_conn *ct;
290 enum ip_conntrack_info ctinfo; 288 enum ip_conntrack_info ctinfo;
291 u_int32_t hash; 289 u_int32_t hash;
@@ -349,13 +347,10 @@ clusterip_tg(struct sk_buff *skb, const struct net_device *in,
349 return XT_CONTINUE; 347 return XT_CONTINUE;
350} 348}
351 349
352static bool 350static bool clusterip_tg_check(const struct xt_tgchk_param *par)
353clusterip_tg_check(const char *tablename, const void *e_void,
354 const struct xt_target *target, void *targinfo,
355 unsigned int hook_mask)
356{ 351{
357 struct ipt_clusterip_tgt_info *cipinfo = targinfo; 352 struct ipt_clusterip_tgt_info *cipinfo = par->targinfo;
358 const struct ipt_entry *e = e_void; 353 const struct ipt_entry *e = par->entryinfo;
359 354
360 struct clusterip_config *config; 355 struct clusterip_config *config;
361 356
@@ -406,9 +401,9 @@ clusterip_tg_check(const char *tablename, const void *e_void,
406 } 401 }
407 cipinfo->config = config; 402 cipinfo->config = config;
408 403
409 if (nf_ct_l3proto_try_module_get(target->family) < 0) { 404 if (nf_ct_l3proto_try_module_get(par->target->family) < 0) {
410 printk(KERN_WARNING "can't load conntrack support for " 405 printk(KERN_WARNING "can't load conntrack support for "
411 "proto=%u\n", target->family); 406 "proto=%u\n", par->target->family);
412 return false; 407 return false;
413 } 408 }
414 409
@@ -416,9 +411,9 @@ clusterip_tg_check(const char *tablename, const void *e_void,
416} 411}
417 412
418/* drop reference count of cluster config when rule is deleted */ 413/* drop reference count of cluster config when rule is deleted */
419static void clusterip_tg_destroy(const struct xt_target *target, void *targinfo) 414static void clusterip_tg_destroy(const struct xt_tgdtor_param *par)
420{ 415{
421 const struct ipt_clusterip_tgt_info *cipinfo = targinfo; 416 const struct ipt_clusterip_tgt_info *cipinfo = par->targinfo;
422 417
423 /* if no more entries are referencing the config, remove it 418 /* if no more entries are referencing the config, remove it
424 * from the list and destroy the proc entry */ 419 * from the list and destroy the proc entry */
@@ -426,7 +421,7 @@ static void clusterip_tg_destroy(const struct xt_target *target, void *targinfo)
426 421
427 clusterip_config_put(cipinfo->config); 422 clusterip_config_put(cipinfo->config);
428 423
429 nf_ct_l3proto_module_put(target->family); 424 nf_ct_l3proto_module_put(par->target->family);
430} 425}
431 426
432#ifdef CONFIG_COMPAT 427#ifdef CONFIG_COMPAT
@@ -445,7 +440,7 @@ struct compat_ipt_clusterip_tgt_info
445 440
446static struct xt_target clusterip_tg_reg __read_mostly = { 441static struct xt_target clusterip_tg_reg __read_mostly = {
447 .name = "CLUSTERIP", 442 .name = "CLUSTERIP",
448 .family = AF_INET, 443 .family = NFPROTO_IPV4,
449 .target = clusterip_tg, 444 .target = clusterip_tg,
450 .checkentry = clusterip_tg_check, 445 .checkentry = clusterip_tg_check,
451 .destroy = clusterip_tg_destroy, 446 .destroy = clusterip_tg_destroy,
@@ -546,7 +541,7 @@ arp_mangle(unsigned int hook,
546 541
547static struct nf_hook_ops cip_arp_ops __read_mostly = { 542static struct nf_hook_ops cip_arp_ops __read_mostly = {
548 .hook = arp_mangle, 543 .hook = arp_mangle,
549 .pf = NF_ARP, 544 .pf = NFPROTO_ARP,
550 .hooknum = NF_ARP_OUT, 545 .hooknum = NF_ARP_OUT,
551 .priority = -1 546 .priority = -1
552}; 547};
diff --git a/net/ipv4/netfilter/ipt_ECN.c b/net/ipv4/netfilter/ipt_ECN.c
index d60139c134ca..f7e2fa0974dc 100644
--- a/net/ipv4/netfilter/ipt_ECN.c
+++ b/net/ipv4/netfilter/ipt_ECN.c
@@ -77,11 +77,9 @@ set_ect_tcp(struct sk_buff *skb, const struct ipt_ECN_info *einfo)
77} 77}
78 78
79static unsigned int 79static unsigned int
80ecn_tg(struct sk_buff *skb, const struct net_device *in, 80ecn_tg(struct sk_buff *skb, const struct xt_target_param *par)
81 const struct net_device *out, unsigned int hooknum,
82 const struct xt_target *target, const void *targinfo)
83{ 81{
84 const struct ipt_ECN_info *einfo = targinfo; 82 const struct ipt_ECN_info *einfo = par->targinfo;
85 83
86 if (einfo->operation & IPT_ECN_OP_SET_IP) 84 if (einfo->operation & IPT_ECN_OP_SET_IP)
87 if (!set_ect_ip(skb, einfo)) 85 if (!set_ect_ip(skb, einfo))
@@ -95,13 +93,10 @@ ecn_tg(struct sk_buff *skb, const struct net_device *in,
95 return XT_CONTINUE; 93 return XT_CONTINUE;
96} 94}
97 95
98static bool 96static bool ecn_tg_check(const struct xt_tgchk_param *par)
99ecn_tg_check(const char *tablename, const void *e_void,
100 const struct xt_target *target, void *targinfo,
101 unsigned int hook_mask)
102{ 97{
103 const struct ipt_ECN_info *einfo = targinfo; 98 const struct ipt_ECN_info *einfo = par->targinfo;
104 const struct ipt_entry *e = e_void; 99 const struct ipt_entry *e = par->entryinfo;
105 100
106 if (einfo->operation & IPT_ECN_OP_MASK) { 101 if (einfo->operation & IPT_ECN_OP_MASK) {
107 printk(KERN_WARNING "ECN: unsupported ECN operation %x\n", 102 printk(KERN_WARNING "ECN: unsupported ECN operation %x\n",
@@ -124,7 +119,7 @@ ecn_tg_check(const char *tablename, const void *e_void,
124 119
125static struct xt_target ecn_tg_reg __read_mostly = { 120static struct xt_target ecn_tg_reg __read_mostly = {
126 .name = "ECN", 121 .name = "ECN",
127 .family = AF_INET, 122 .family = NFPROTO_IPV4,
128 .target = ecn_tg, 123 .target = ecn_tg,
129 .targetsize = sizeof(struct ipt_ECN_info), 124 .targetsize = sizeof(struct ipt_ECN_info),
130 .table = "mangle", 125 .table = "mangle",
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c
index 0af14137137b..fc6ce04a3e35 100644
--- a/net/ipv4/netfilter/ipt_LOG.c
+++ b/net/ipv4/netfilter/ipt_LOG.c
@@ -375,7 +375,7 @@ static struct nf_loginfo default_loginfo = {
375}; 375};
376 376
377static void 377static void
378ipt_log_packet(unsigned int pf, 378ipt_log_packet(u_int8_t pf,
379 unsigned int hooknum, 379 unsigned int hooknum,
380 const struct sk_buff *skb, 380 const struct sk_buff *skb,
381 const struct net_device *in, 381 const struct net_device *in,
@@ -426,28 +426,23 @@ ipt_log_packet(unsigned int pf,
426} 426}
427 427
428static unsigned int 428static unsigned int
429log_tg(struct sk_buff *skb, const struct net_device *in, 429log_tg(struct sk_buff *skb, const struct xt_target_param *par)
430 const struct net_device *out, unsigned int hooknum,
431 const struct xt_target *target, const void *targinfo)
432{ 430{
433 const struct ipt_log_info *loginfo = targinfo; 431 const struct ipt_log_info *loginfo = par->targinfo;
434 struct nf_loginfo li; 432 struct nf_loginfo li;
435 433
436 li.type = NF_LOG_TYPE_LOG; 434 li.type = NF_LOG_TYPE_LOG;
437 li.u.log.level = loginfo->level; 435 li.u.log.level = loginfo->level;
438 li.u.log.logflags = loginfo->logflags; 436 li.u.log.logflags = loginfo->logflags;
439 437
440 ipt_log_packet(PF_INET, hooknum, skb, in, out, &li, 438 ipt_log_packet(NFPROTO_IPV4, par->hooknum, skb, par->in, par->out, &li,
441 loginfo->prefix); 439 loginfo->prefix);
442 return XT_CONTINUE; 440 return XT_CONTINUE;
443} 441}
444 442
445static bool 443static bool log_tg_check(const struct xt_tgchk_param *par)
446log_tg_check(const char *tablename, const void *e,
447 const struct xt_target *target, void *targinfo,
448 unsigned int hook_mask)
449{ 444{
450 const struct ipt_log_info *loginfo = targinfo; 445 const struct ipt_log_info *loginfo = par->targinfo;
451 446
452 if (loginfo->level >= 8) { 447 if (loginfo->level >= 8) {
453 pr_debug("LOG: level %u >= 8\n", loginfo->level); 448 pr_debug("LOG: level %u >= 8\n", loginfo->level);
@@ -463,7 +458,7 @@ log_tg_check(const char *tablename, const void *e,
463 458
464static struct xt_target log_tg_reg __read_mostly = { 459static struct xt_target log_tg_reg __read_mostly = {
465 .name = "LOG", 460 .name = "LOG",
466 .family = AF_INET, 461 .family = NFPROTO_IPV4,
467 .target = log_tg, 462 .target = log_tg,
468 .targetsize = sizeof(struct ipt_log_info), 463 .targetsize = sizeof(struct ipt_log_info),
469 .checkentry = log_tg_check, 464 .checkentry = log_tg_check,
@@ -483,7 +478,7 @@ static int __init log_tg_init(void)
483 ret = xt_register_target(&log_tg_reg); 478 ret = xt_register_target(&log_tg_reg);
484 if (ret < 0) 479 if (ret < 0)
485 return ret; 480 return ret;
486 nf_log_register(PF_INET, &ipt_log_logger); 481 nf_log_register(NFPROTO_IPV4, &ipt_log_logger);
487 return 0; 482 return 0;
488} 483}
489 484
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
index 0841aefaa503..f389f60cb105 100644
--- a/net/ipv4/netfilter/ipt_MASQUERADE.c
+++ b/net/ipv4/netfilter/ipt_MASQUERADE.c
@@ -31,12 +31,9 @@ MODULE_DESCRIPTION("Xtables: automatic-address SNAT");
31static DEFINE_RWLOCK(masq_lock); 31static DEFINE_RWLOCK(masq_lock);
32 32
33/* FIXME: Multiple targets. --RR */ 33/* FIXME: Multiple targets. --RR */
34static bool 34static bool masquerade_tg_check(const struct xt_tgchk_param *par)
35masquerade_tg_check(const char *tablename, const void *e,
36 const struct xt_target *target, void *targinfo,
37 unsigned int hook_mask)
38{ 35{
39 const struct nf_nat_multi_range_compat *mr = targinfo; 36 const struct nf_nat_multi_range_compat *mr = par->targinfo;
40 37
41 if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) { 38 if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) {
42 pr_debug("masquerade_check: bad MAP_IPS.\n"); 39 pr_debug("masquerade_check: bad MAP_IPS.\n");
@@ -50,9 +47,7 @@ masquerade_tg_check(const char *tablename, const void *e,
50} 47}
51 48
52static unsigned int 49static unsigned int
53masquerade_tg(struct sk_buff *skb, const struct net_device *in, 50masquerade_tg(struct sk_buff *skb, const struct xt_target_param *par)
54 const struct net_device *out, unsigned int hooknum,
55 const struct xt_target *target, const void *targinfo)
56{ 51{
57 struct nf_conn *ct; 52 struct nf_conn *ct;
58 struct nf_conn_nat *nat; 53 struct nf_conn_nat *nat;
@@ -62,7 +57,7 @@ masquerade_tg(struct sk_buff *skb, const struct net_device *in,
62 const struct rtable *rt; 57 const struct rtable *rt;
63 __be32 newsrc; 58 __be32 newsrc;
64 59
65 NF_CT_ASSERT(hooknum == NF_INET_POST_ROUTING); 60 NF_CT_ASSERT(par->hooknum == NF_INET_POST_ROUTING);
66 61
67 ct = nf_ct_get(skb, &ctinfo); 62 ct = nf_ct_get(skb, &ctinfo);
68 nat = nfct_nat(ct); 63 nat = nfct_nat(ct);
@@ -76,16 +71,16 @@ masquerade_tg(struct sk_buff *skb, const struct net_device *in,
76 if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip == 0) 71 if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip == 0)
77 return NF_ACCEPT; 72 return NF_ACCEPT;
78 73
79 mr = targinfo; 74 mr = par->targinfo;
80 rt = skb->rtable; 75 rt = skb->rtable;
81 newsrc = inet_select_addr(out, rt->rt_gateway, RT_SCOPE_UNIVERSE); 76 newsrc = inet_select_addr(par->out, rt->rt_gateway, RT_SCOPE_UNIVERSE);
82 if (!newsrc) { 77 if (!newsrc) {
83 printk("MASQUERADE: %s ate my IP address\n", out->name); 78 printk("MASQUERADE: %s ate my IP address\n", par->out->name);
84 return NF_DROP; 79 return NF_DROP;
85 } 80 }
86 81
87 write_lock_bh(&masq_lock); 82 write_lock_bh(&masq_lock);
88 nat->masq_index = out->ifindex; 83 nat->masq_index = par->out->ifindex;
89 write_unlock_bh(&masq_lock); 84 write_unlock_bh(&masq_lock);
90 85
91 /* Transfer from original range. */ 86 /* Transfer from original range. */
@@ -119,9 +114,7 @@ static int masq_device_event(struct notifier_block *this,
119 void *ptr) 114 void *ptr)
120{ 115{
121 const struct net_device *dev = ptr; 116 const struct net_device *dev = ptr;
122 117 struct net *net = dev_net(dev);
123 if (!net_eq(dev_net(dev), &init_net))
124 return NOTIFY_DONE;
125 118
126 if (event == NETDEV_DOWN) { 119 if (event == NETDEV_DOWN) {
127 /* Device was downed. Search entire table for 120 /* Device was downed. Search entire table for
@@ -129,7 +122,8 @@ static int masq_device_event(struct notifier_block *this,
129 and forget them. */ 122 and forget them. */
130 NF_CT_ASSERT(dev->ifindex != 0); 123 NF_CT_ASSERT(dev->ifindex != 0);
131 124
132 nf_ct_iterate_cleanup(device_cmp, (void *)(long)dev->ifindex); 125 nf_ct_iterate_cleanup(net, device_cmp,
126 (void *)(long)dev->ifindex);
133 } 127 }
134 128
135 return NOTIFY_DONE; 129 return NOTIFY_DONE;
@@ -153,7 +147,7 @@ static struct notifier_block masq_inet_notifier = {
153 147
154static struct xt_target masquerade_tg_reg __read_mostly = { 148static struct xt_target masquerade_tg_reg __read_mostly = {
155 .name = "MASQUERADE", 149 .name = "MASQUERADE",
156 .family = AF_INET, 150 .family = NFPROTO_IPV4,
157 .target = masquerade_tg, 151 .target = masquerade_tg,
158 .targetsize = sizeof(struct nf_nat_multi_range_compat), 152 .targetsize = sizeof(struct nf_nat_multi_range_compat),
159 .table = "nat", 153 .table = "nat",
diff --git a/net/ipv4/netfilter/ipt_NETMAP.c b/net/ipv4/netfilter/ipt_NETMAP.c
index 6739abfd1521..7c29582d4ec8 100644
--- a/net/ipv4/netfilter/ipt_NETMAP.c
+++ b/net/ipv4/netfilter/ipt_NETMAP.c
@@ -22,12 +22,9 @@ MODULE_LICENSE("GPL");
22MODULE_AUTHOR("Svenning Soerensen <svenning@post5.tele.dk>"); 22MODULE_AUTHOR("Svenning Soerensen <svenning@post5.tele.dk>");
23MODULE_DESCRIPTION("Xtables: 1:1 NAT mapping of IPv4 subnets"); 23MODULE_DESCRIPTION("Xtables: 1:1 NAT mapping of IPv4 subnets");
24 24
25static bool 25static bool netmap_tg_check(const struct xt_tgchk_param *par)
26netmap_tg_check(const char *tablename, const void *e,
27 const struct xt_target *target, void *targinfo,
28 unsigned int hook_mask)
29{ 26{
30 const struct nf_nat_multi_range_compat *mr = targinfo; 27 const struct nf_nat_multi_range_compat *mr = par->targinfo;
31 28
32 if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) { 29 if (!(mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)) {
33 pr_debug("NETMAP:check: bad MAP_IPS.\n"); 30 pr_debug("NETMAP:check: bad MAP_IPS.\n");
@@ -41,24 +38,23 @@ netmap_tg_check(const char *tablename, const void *e,
41} 38}
42 39
43static unsigned int 40static unsigned int
44netmap_tg(struct sk_buff *skb, const struct net_device *in, 41netmap_tg(struct sk_buff *skb, const struct xt_target_param *par)
45 const struct net_device *out, unsigned int hooknum,
46 const struct xt_target *target, const void *targinfo)
47{ 42{
48 struct nf_conn *ct; 43 struct nf_conn *ct;
49 enum ip_conntrack_info ctinfo; 44 enum ip_conntrack_info ctinfo;
50 __be32 new_ip, netmask; 45 __be32 new_ip, netmask;
51 const struct nf_nat_multi_range_compat *mr = targinfo; 46 const struct nf_nat_multi_range_compat *mr = par->targinfo;
52 struct nf_nat_range newrange; 47 struct nf_nat_range newrange;
53 48
54 NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING 49 NF_CT_ASSERT(par->hooknum == NF_INET_PRE_ROUTING ||
55 || hooknum == NF_INET_POST_ROUTING 50 par->hooknum == NF_INET_POST_ROUTING ||
56 || hooknum == NF_INET_LOCAL_OUT); 51 par->hooknum == NF_INET_LOCAL_OUT);
57 ct = nf_ct_get(skb, &ctinfo); 52 ct = nf_ct_get(skb, &ctinfo);
58 53
59 netmask = ~(mr->range[0].min_ip ^ mr->range[0].max_ip); 54 netmask = ~(mr->range[0].min_ip ^ mr->range[0].max_ip);
60 55
61 if (hooknum == NF_INET_PRE_ROUTING || hooknum == NF_INET_LOCAL_OUT) 56 if (par->hooknum == NF_INET_PRE_ROUTING ||
57 par->hooknum == NF_INET_LOCAL_OUT)
62 new_ip = ip_hdr(skb)->daddr & ~netmask; 58 new_ip = ip_hdr(skb)->daddr & ~netmask;
63 else 59 else
64 new_ip = ip_hdr(skb)->saddr & ~netmask; 60 new_ip = ip_hdr(skb)->saddr & ~netmask;
@@ -70,12 +66,12 @@ netmap_tg(struct sk_buff *skb, const struct net_device *in,
70 mr->range[0].min, mr->range[0].max }); 66 mr->range[0].min, mr->range[0].max });
71 67
72 /* Hand modified range to generic setup. */ 68 /* Hand modified range to generic setup. */
73 return nf_nat_setup_info(ct, &newrange, HOOK2MANIP(hooknum)); 69 return nf_nat_setup_info(ct, &newrange, HOOK2MANIP(par->hooknum));
74} 70}
75 71
76static struct xt_target netmap_tg_reg __read_mostly = { 72static struct xt_target netmap_tg_reg __read_mostly = {
77 .name = "NETMAP", 73 .name = "NETMAP",
78 .family = AF_INET, 74 .family = NFPROTO_IPV4,
79 .target = netmap_tg, 75 .target = netmap_tg,
80 .targetsize = sizeof(struct nf_nat_multi_range_compat), 76 .targetsize = sizeof(struct nf_nat_multi_range_compat),
81 .table = "nat", 77 .table = "nat",
diff --git a/net/ipv4/netfilter/ipt_REDIRECT.c b/net/ipv4/netfilter/ipt_REDIRECT.c
index 5c6292449d13..698e5e78685b 100644
--- a/net/ipv4/netfilter/ipt_REDIRECT.c
+++ b/net/ipv4/netfilter/ipt_REDIRECT.c
@@ -26,12 +26,9 @@ MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
26MODULE_DESCRIPTION("Xtables: Connection redirection to localhost"); 26MODULE_DESCRIPTION("Xtables: Connection redirection to localhost");
27 27
28/* FIXME: Take multiple ranges --RR */ 28/* FIXME: Take multiple ranges --RR */
29static bool 29static bool redirect_tg_check(const struct xt_tgchk_param *par)
30redirect_tg_check(const char *tablename, const void *e,
31 const struct xt_target *target, void *targinfo,
32 unsigned int hook_mask)
33{ 30{
34 const struct nf_nat_multi_range_compat *mr = targinfo; 31 const struct nf_nat_multi_range_compat *mr = par->targinfo;
35 32
36 if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) { 33 if (mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) {
37 pr_debug("redirect_check: bad MAP_IPS.\n"); 34 pr_debug("redirect_check: bad MAP_IPS.\n");
@@ -45,24 +42,22 @@ redirect_tg_check(const char *tablename, const void *e,
45} 42}
46 43
47static unsigned int 44static unsigned int
48redirect_tg(struct sk_buff *skb, const struct net_device *in, 45redirect_tg(struct sk_buff *skb, const struct xt_target_param *par)
49 const struct net_device *out, unsigned int hooknum,
50 const struct xt_target *target, const void *targinfo)
51{ 46{
52 struct nf_conn *ct; 47 struct nf_conn *ct;
53 enum ip_conntrack_info ctinfo; 48 enum ip_conntrack_info ctinfo;
54 __be32 newdst; 49 __be32 newdst;
55 const struct nf_nat_multi_range_compat *mr = targinfo; 50 const struct nf_nat_multi_range_compat *mr = par->targinfo;
56 struct nf_nat_range newrange; 51 struct nf_nat_range newrange;
57 52
58 NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING 53 NF_CT_ASSERT(par->hooknum == NF_INET_PRE_ROUTING ||
59 || hooknum == NF_INET_LOCAL_OUT); 54 par->hooknum == NF_INET_LOCAL_OUT);
60 55
61 ct = nf_ct_get(skb, &ctinfo); 56 ct = nf_ct_get(skb, &ctinfo);
62 NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED)); 57 NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
63 58
64 /* Local packets: make them go to loopback */ 59 /* Local packets: make them go to loopback */
65 if (hooknum == NF_INET_LOCAL_OUT) 60 if (par->hooknum == NF_INET_LOCAL_OUT)
66 newdst = htonl(0x7F000001); 61 newdst = htonl(0x7F000001);
67 else { 62 else {
68 struct in_device *indev; 63 struct in_device *indev;
@@ -92,7 +87,7 @@ redirect_tg(struct sk_buff *skb, const struct net_device *in,
92 87
93static struct xt_target redirect_tg_reg __read_mostly = { 88static struct xt_target redirect_tg_reg __read_mostly = {
94 .name = "REDIRECT", 89 .name = "REDIRECT",
95 .family = AF_INET, 90 .family = NFPROTO_IPV4,
96 .target = redirect_tg, 91 .target = redirect_tg,
97 .targetsize = sizeof(struct nf_nat_multi_range_compat), 92 .targetsize = sizeof(struct nf_nat_multi_range_compat),
98 .table = "nat", 93 .table = "nat",
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index 2639872849da..0b4b6e0ff2b9 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -136,11 +136,9 @@ static inline void send_unreach(struct sk_buff *skb_in, int code)
136} 136}
137 137
138static unsigned int 138static unsigned int
139reject_tg(struct sk_buff *skb, const struct net_device *in, 139reject_tg(struct sk_buff *skb, const struct xt_target_param *par)
140 const struct net_device *out, unsigned int hooknum,
141 const struct xt_target *target, const void *targinfo)
142{ 140{
143 const struct ipt_reject_info *reject = targinfo; 141 const struct ipt_reject_info *reject = par->targinfo;
144 142
145 /* WARNING: This code causes reentry within iptables. 143 /* WARNING: This code causes reentry within iptables.
146 This means that the iptables jump stack is now crap. We 144 This means that the iptables jump stack is now crap. We
@@ -168,7 +166,7 @@ reject_tg(struct sk_buff *skb, const struct net_device *in,
168 send_unreach(skb, ICMP_PKT_FILTERED); 166 send_unreach(skb, ICMP_PKT_FILTERED);
169 break; 167 break;
170 case IPT_TCP_RESET: 168 case IPT_TCP_RESET:
171 send_reset(skb, hooknum); 169 send_reset(skb, par->hooknum);
172 case IPT_ICMP_ECHOREPLY: 170 case IPT_ICMP_ECHOREPLY:
173 /* Doesn't happen. */ 171 /* Doesn't happen. */
174 break; 172 break;
@@ -177,13 +175,10 @@ reject_tg(struct sk_buff *skb, const struct net_device *in,
177 return NF_DROP; 175 return NF_DROP;
178} 176}
179 177
180static bool 178static bool reject_tg_check(const struct xt_tgchk_param *par)
181reject_tg_check(const char *tablename, const void *e_void,
182 const struct xt_target *target, void *targinfo,
183 unsigned int hook_mask)
184{ 179{
185 const struct ipt_reject_info *rejinfo = targinfo; 180 const struct ipt_reject_info *rejinfo = par->targinfo;
186 const struct ipt_entry *e = e_void; 181 const struct ipt_entry *e = par->entryinfo;
187 182
188 if (rejinfo->with == IPT_ICMP_ECHOREPLY) { 183 if (rejinfo->with == IPT_ICMP_ECHOREPLY) {
189 printk("ipt_REJECT: ECHOREPLY no longer supported.\n"); 184 printk("ipt_REJECT: ECHOREPLY no longer supported.\n");
@@ -201,7 +196,7 @@ reject_tg_check(const char *tablename, const void *e_void,
201 196
202static struct xt_target reject_tg_reg __read_mostly = { 197static struct xt_target reject_tg_reg __read_mostly = {
203 .name = "REJECT", 198 .name = "REJECT",
204 .family = AF_INET, 199 .family = NFPROTO_IPV4,
205 .target = reject_tg, 200 .target = reject_tg,
206 .targetsize = sizeof(struct ipt_reject_info), 201 .targetsize = sizeof(struct ipt_reject_info),
207 .table = "filter", 202 .table = "filter",
diff --git a/net/ipv4/netfilter/ipt_TTL.c b/net/ipv4/netfilter/ipt_TTL.c
index 30eed65e7338..6d76aae90cc0 100644
--- a/net/ipv4/netfilter/ipt_TTL.c
+++ b/net/ipv4/netfilter/ipt_TTL.c
@@ -20,12 +20,10 @@ MODULE_DESCRIPTION("Xtables: IPv4 TTL field modification target");
20MODULE_LICENSE("GPL"); 20MODULE_LICENSE("GPL");
21 21
22static unsigned int 22static unsigned int
23ttl_tg(struct sk_buff *skb, const struct net_device *in, 23ttl_tg(struct sk_buff *skb, const struct xt_target_param *par)
24 const struct net_device *out, unsigned int hooknum,
25 const struct xt_target *target, const void *targinfo)
26{ 24{
27 struct iphdr *iph; 25 struct iphdr *iph;
28 const struct ipt_TTL_info *info = targinfo; 26 const struct ipt_TTL_info *info = par->targinfo;
29 int new_ttl; 27 int new_ttl;
30 28
31 if (!skb_make_writable(skb, skb->len)) 29 if (!skb_make_writable(skb, skb->len))
@@ -61,12 +59,9 @@ ttl_tg(struct sk_buff *skb, const struct net_device *in,
61 return XT_CONTINUE; 59 return XT_CONTINUE;
62} 60}
63 61
64static bool 62static bool ttl_tg_check(const struct xt_tgchk_param *par)
65ttl_tg_check(const char *tablename, const void *e,
66 const struct xt_target *target, void *targinfo,
67 unsigned int hook_mask)
68{ 63{
69 const struct ipt_TTL_info *info = targinfo; 64 const struct ipt_TTL_info *info = par->targinfo;
70 65
71 if (info->mode > IPT_TTL_MAXMODE) { 66 if (info->mode > IPT_TTL_MAXMODE) {
72 printk(KERN_WARNING "ipt_TTL: invalid or unknown Mode %u\n", 67 printk(KERN_WARNING "ipt_TTL: invalid or unknown Mode %u\n",
@@ -80,7 +75,7 @@ ttl_tg_check(const char *tablename, const void *e,
80 75
81static struct xt_target ttl_tg_reg __read_mostly = { 76static struct xt_target ttl_tg_reg __read_mostly = {
82 .name = "TTL", 77 .name = "TTL",
83 .family = AF_INET, 78 .family = NFPROTO_IPV4,
84 .target = ttl_tg, 79 .target = ttl_tg,
85 .targetsize = sizeof(struct ipt_TTL_info), 80 .targetsize = sizeof(struct ipt_TTL_info),
86 .table = "mangle", 81 .table = "mangle",
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
index b192756c6d0d..18a2826b57c6 100644
--- a/net/ipv4/netfilter/ipt_ULOG.c
+++ b/net/ipv4/netfilter/ipt_ULOG.c
@@ -281,18 +281,14 @@ alloc_failure:
281} 281}
282 282
283static unsigned int 283static unsigned int
284ulog_tg(struct sk_buff *skb, const struct net_device *in, 284ulog_tg(struct sk_buff *skb, const struct xt_target_param *par)
285 const struct net_device *out, unsigned int hooknum,
286 const struct xt_target *target, const void *targinfo)
287{ 285{
288 struct ipt_ulog_info *loginfo = (struct ipt_ulog_info *) targinfo; 286 ipt_ulog_packet(par->hooknum, skb, par->in, par->out,
289 287 par->targinfo, NULL);
290 ipt_ulog_packet(hooknum, skb, in, out, loginfo, NULL);
291
292 return XT_CONTINUE; 288 return XT_CONTINUE;
293} 289}
294 290
295static void ipt_logfn(unsigned int pf, 291static void ipt_logfn(u_int8_t pf,
296 unsigned int hooknum, 292 unsigned int hooknum,
297 const struct sk_buff *skb, 293 const struct sk_buff *skb,
298 const struct net_device *in, 294 const struct net_device *in,
@@ -317,12 +313,9 @@ static void ipt_logfn(unsigned int pf,
317 ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); 313 ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix);
318} 314}
319 315
320static bool 316static bool ulog_tg_check(const struct xt_tgchk_param *par)
321ulog_tg_check(const char *tablename, const void *e,
322 const struct xt_target *target, void *targinfo,
323 unsigned int hookmask)
324{ 317{
325 const struct ipt_ulog_info *loginfo = targinfo; 318 const struct ipt_ulog_info *loginfo = par->targinfo;
326 319
327 if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') { 320 if (loginfo->prefix[sizeof(loginfo->prefix) - 1] != '\0') {
328 pr_debug("ipt_ULOG: prefix term %i\n", 321 pr_debug("ipt_ULOG: prefix term %i\n",
@@ -374,7 +367,7 @@ static int ulog_tg_compat_to_user(void __user *dst, void *src)
374 367
375static struct xt_target ulog_tg_reg __read_mostly = { 368static struct xt_target ulog_tg_reg __read_mostly = {
376 .name = "ULOG", 369 .name = "ULOG",
377 .family = AF_INET, 370 .family = NFPROTO_IPV4,
378 .target = ulog_tg, 371 .target = ulog_tg,
379 .targetsize = sizeof(struct ipt_ulog_info), 372 .targetsize = sizeof(struct ipt_ulog_info),
380 .checkentry = ulog_tg_check, 373 .checkentry = ulog_tg_check,
@@ -419,7 +412,7 @@ static int __init ulog_tg_init(void)
419 return ret; 412 return ret;
420 } 413 }
421 if (nflog) 414 if (nflog)
422 nf_log_register(PF_INET, &ipt_ulog_logger); 415 nf_log_register(NFPROTO_IPV4, &ipt_ulog_logger);
423 416
424 return 0; 417 return 0;
425} 418}
diff --git a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c
index 462a22c97877..88762f02779d 100644
--- a/net/ipv4/netfilter/ipt_addrtype.c
+++ b/net/ipv4/netfilter/ipt_addrtype.c
@@ -30,12 +30,9 @@ static inline bool match_type(const struct net_device *dev, __be32 addr,
30} 30}
31 31
32static bool 32static bool
33addrtype_mt_v0(const struct sk_buff *skb, const struct net_device *in, 33addrtype_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
34 const struct net_device *out, const struct xt_match *match,
35 const void *matchinfo, int offset, unsigned int protoff,
36 bool *hotdrop)
37{ 34{
38 const struct ipt_addrtype_info *info = matchinfo; 35 const struct ipt_addrtype_info *info = par->matchinfo;
39 const struct iphdr *iph = ip_hdr(skb); 36 const struct iphdr *iph = ip_hdr(skb);
40 bool ret = true; 37 bool ret = true;
41 38
@@ -50,20 +47,17 @@ addrtype_mt_v0(const struct sk_buff *skb, const struct net_device *in,
50} 47}
51 48
52static bool 49static bool
53addrtype_mt_v1(const struct sk_buff *skb, const struct net_device *in, 50addrtype_mt_v1(const struct sk_buff *skb, const struct xt_match_param *par)
54 const struct net_device *out, const struct xt_match *match,
55 const void *matchinfo, int offset, unsigned int protoff,
56 bool *hotdrop)
57{ 51{
58 const struct ipt_addrtype_info_v1 *info = matchinfo; 52 const struct ipt_addrtype_info_v1 *info = par->matchinfo;
59 const struct iphdr *iph = ip_hdr(skb); 53 const struct iphdr *iph = ip_hdr(skb);
60 const struct net_device *dev = NULL; 54 const struct net_device *dev = NULL;
61 bool ret = true; 55 bool ret = true;
62 56
63 if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) 57 if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN)
64 dev = in; 58 dev = par->in;
65 else if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) 59 else if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT)
66 dev = out; 60 dev = par->out;
67 61
68 if (info->source) 62 if (info->source)
69 ret &= match_type(dev, iph->saddr, info->source) ^ 63 ret &= match_type(dev, iph->saddr, info->source) ^
@@ -74,12 +68,9 @@ addrtype_mt_v1(const struct sk_buff *skb, const struct net_device *in,
74 return ret; 68 return ret;
75} 69}
76 70
77static bool 71static bool addrtype_mt_checkentry_v1(const struct xt_mtchk_param *par)
78addrtype_mt_checkentry_v1(const char *tablename, const void *ip_void,
79 const struct xt_match *match, void *matchinfo,
80 unsigned int hook_mask)
81{ 72{
82 struct ipt_addrtype_info_v1 *info = matchinfo; 73 struct ipt_addrtype_info_v1 *info = par->matchinfo;
83 74
84 if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN && 75 if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN &&
85 info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { 76 info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
@@ -88,14 +79,16 @@ addrtype_mt_checkentry_v1(const char *tablename, const void *ip_void,
88 return false; 79 return false;
89 } 80 }
90 81
91 if (hook_mask & (1 << NF_INET_PRE_ROUTING | 1 << NF_INET_LOCAL_IN) && 82 if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) |
83 (1 << NF_INET_LOCAL_IN)) &&
92 info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) { 84 info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
93 printk(KERN_ERR "ipt_addrtype: output interface limitation " 85 printk(KERN_ERR "ipt_addrtype: output interface limitation "
94 "not valid in PRE_ROUTING and INPUT\n"); 86 "not valid in PRE_ROUTING and INPUT\n");
95 return false; 87 return false;
96 } 88 }
97 89
98 if (hook_mask & (1 << NF_INET_POST_ROUTING | 1 << NF_INET_LOCAL_OUT) && 90 if (par->hook_mask & ((1 << NF_INET_POST_ROUTING) |
91 (1 << NF_INET_LOCAL_OUT)) &&
99 info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) { 92 info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) {
100 printk(KERN_ERR "ipt_addrtype: input interface limitation " 93 printk(KERN_ERR "ipt_addrtype: input interface limitation "
101 "not valid in POST_ROUTING and OUTPUT\n"); 94 "not valid in POST_ROUTING and OUTPUT\n");
@@ -108,14 +101,14 @@ addrtype_mt_checkentry_v1(const char *tablename, const void *ip_void,
108static struct xt_match addrtype_mt_reg[] __read_mostly = { 101static struct xt_match addrtype_mt_reg[] __read_mostly = {
109 { 102 {
110 .name = "addrtype", 103 .name = "addrtype",
111 .family = AF_INET, 104 .family = NFPROTO_IPV4,
112 .match = addrtype_mt_v0, 105 .match = addrtype_mt_v0,
113 .matchsize = sizeof(struct ipt_addrtype_info), 106 .matchsize = sizeof(struct ipt_addrtype_info),
114 .me = THIS_MODULE 107 .me = THIS_MODULE
115 }, 108 },
116 { 109 {
117 .name = "addrtype", 110 .name = "addrtype",
118 .family = AF_INET, 111 .family = NFPROTO_IPV4,
119 .revision = 1, 112 .revision = 1,
120 .match = addrtype_mt_v1, 113 .match = addrtype_mt_v1,
121 .checkentry = addrtype_mt_checkentry_v1, 114 .checkentry = addrtype_mt_checkentry_v1,
diff --git a/net/ipv4/netfilter/ipt_ah.c b/net/ipv4/netfilter/ipt_ah.c
index e977989629c7..0104c0b399de 100644
--- a/net/ipv4/netfilter/ipt_ah.c
+++ b/net/ipv4/netfilter/ipt_ah.c
@@ -36,27 +36,23 @@ spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
36 return r; 36 return r;
37} 37}
38 38
39static bool 39static bool ah_mt(const struct sk_buff *skb, const struct xt_match_param *par)
40ah_mt(const struct sk_buff *skb, const struct net_device *in,
41 const struct net_device *out, const struct xt_match *match,
42 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
43{ 40{
44 struct ip_auth_hdr _ahdr; 41 struct ip_auth_hdr _ahdr;
45 const struct ip_auth_hdr *ah; 42 const struct ip_auth_hdr *ah;
46 const struct ipt_ah *ahinfo = matchinfo; 43 const struct ipt_ah *ahinfo = par->matchinfo;
47 44
48 /* Must not be a fragment. */ 45 /* Must not be a fragment. */
49 if (offset) 46 if (par->fragoff != 0)
50 return false; 47 return false;
51 48
52 ah = skb_header_pointer(skb, protoff, 49 ah = skb_header_pointer(skb, par->thoff, sizeof(_ahdr), &_ahdr);
53 sizeof(_ahdr), &_ahdr);
54 if (ah == NULL) { 50 if (ah == NULL) {
55 /* We've been asked to examine this packet, and we 51 /* We've been asked to examine this packet, and we
56 * can't. Hence, no choice but to drop. 52 * can't. Hence, no choice but to drop.
57 */ 53 */
58 duprintf("Dropping evil AH tinygram.\n"); 54 duprintf("Dropping evil AH tinygram.\n");
59 *hotdrop = true; 55 *par->hotdrop = true;
60 return 0; 56 return 0;
61 } 57 }
62 58
@@ -65,13 +61,9 @@ ah_mt(const struct sk_buff *skb, const struct net_device *in,
65 !!(ahinfo->invflags & IPT_AH_INV_SPI)); 61 !!(ahinfo->invflags & IPT_AH_INV_SPI));
66} 62}
67 63
68/* Called when user tries to insert an entry of this type. */ 64static bool ah_mt_check(const struct xt_mtchk_param *par)
69static bool
70ah_mt_check(const char *tablename, const void *ip_void,
71 const struct xt_match *match, void *matchinfo,
72 unsigned int hook_mask)
73{ 65{
74 const struct ipt_ah *ahinfo = matchinfo; 66 const struct ipt_ah *ahinfo = par->matchinfo;
75 67
76 /* Must specify no unknown invflags */ 68 /* Must specify no unknown invflags */
77 if (ahinfo->invflags & ~IPT_AH_INV_MASK) { 69 if (ahinfo->invflags & ~IPT_AH_INV_MASK) {
@@ -83,7 +75,7 @@ ah_mt_check(const char *tablename, const void *ip_void,
83 75
84static struct xt_match ah_mt_reg __read_mostly = { 76static struct xt_match ah_mt_reg __read_mostly = {
85 .name = "ah", 77 .name = "ah",
86 .family = AF_INET, 78 .family = NFPROTO_IPV4,
87 .match = ah_mt, 79 .match = ah_mt,
88 .matchsize = sizeof(struct ipt_ah), 80 .matchsize = sizeof(struct ipt_ah),
89 .proto = IPPROTO_AH, 81 .proto = IPPROTO_AH,
diff --git a/net/ipv4/netfilter/ipt_ecn.c b/net/ipv4/netfilter/ipt_ecn.c
index 749de8284ce5..6289b64144c6 100644
--- a/net/ipv4/netfilter/ipt_ecn.c
+++ b/net/ipv4/netfilter/ipt_ecn.c
@@ -67,12 +67,9 @@ static inline bool match_tcp(const struct sk_buff *skb,
67 return true; 67 return true;
68} 68}
69 69
70static bool 70static bool ecn_mt(const struct sk_buff *skb, const struct xt_match_param *par)
71ecn_mt(const struct sk_buff *skb, const struct net_device *in,
72 const struct net_device *out, const struct xt_match *match,
73 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
74{ 71{
75 const struct ipt_ecn_info *info = matchinfo; 72 const struct ipt_ecn_info *info = par->matchinfo;
76 73
77 if (info->operation & IPT_ECN_OP_MATCH_IP) 74 if (info->operation & IPT_ECN_OP_MATCH_IP)
78 if (!match_ip(skb, info)) 75 if (!match_ip(skb, info))
@@ -81,20 +78,17 @@ ecn_mt(const struct sk_buff *skb, const struct net_device *in,
81 if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) { 78 if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) {
82 if (ip_hdr(skb)->protocol != IPPROTO_TCP) 79 if (ip_hdr(skb)->protocol != IPPROTO_TCP)
83 return false; 80 return false;
84 if (!match_tcp(skb, info, hotdrop)) 81 if (!match_tcp(skb, info, par->hotdrop))
85 return false; 82 return false;
86 } 83 }
87 84
88 return true; 85 return true;
89} 86}
90 87
91static bool 88static bool ecn_mt_check(const struct xt_mtchk_param *par)
92ecn_mt_check(const char *tablename, const void *ip_void,
93 const struct xt_match *match, void *matchinfo,
94 unsigned int hook_mask)
95{ 89{
96 const struct ipt_ecn_info *info = matchinfo; 90 const struct ipt_ecn_info *info = par->matchinfo;
97 const struct ipt_ip *ip = ip_void; 91 const struct ipt_ip *ip = par->entryinfo;
98 92
99 if (info->operation & IPT_ECN_OP_MATCH_MASK) 93 if (info->operation & IPT_ECN_OP_MATCH_MASK)
100 return false; 94 return false;
@@ -114,7 +108,7 @@ ecn_mt_check(const char *tablename, const void *ip_void,
114 108
115static struct xt_match ecn_mt_reg __read_mostly = { 109static struct xt_match ecn_mt_reg __read_mostly = {
116 .name = "ecn", 110 .name = "ecn",
117 .family = AF_INET, 111 .family = NFPROTO_IPV4,
118 .match = ecn_mt, 112 .match = ecn_mt,
119 .matchsize = sizeof(struct ipt_ecn_info), 113 .matchsize = sizeof(struct ipt_ecn_info),
120 .checkentry = ecn_mt_check, 114 .checkentry = ecn_mt_check,
diff --git a/net/ipv4/netfilter/ipt_ttl.c b/net/ipv4/netfilter/ipt_ttl.c
index e0b8caeb710c..297f1cbf4ff5 100644
--- a/net/ipv4/netfilter/ipt_ttl.c
+++ b/net/ipv4/netfilter/ipt_ttl.c
@@ -18,12 +18,9 @@ MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
18MODULE_DESCRIPTION("Xtables: IPv4 TTL field match"); 18MODULE_DESCRIPTION("Xtables: IPv4 TTL field match");
19MODULE_LICENSE("GPL"); 19MODULE_LICENSE("GPL");
20 20
21static bool 21static bool ttl_mt(const struct sk_buff *skb, const struct xt_match_param *par)
22ttl_mt(const struct sk_buff *skb, const struct net_device *in,
23 const struct net_device *out, const struct xt_match *match,
24 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
25{ 22{
26 const struct ipt_ttl_info *info = matchinfo; 23 const struct ipt_ttl_info *info = par->matchinfo;
27 const u8 ttl = ip_hdr(skb)->ttl; 24 const u8 ttl = ip_hdr(skb)->ttl;
28 25
29 switch (info->mode) { 26 switch (info->mode) {
@@ -46,7 +43,7 @@ ttl_mt(const struct sk_buff *skb, const struct net_device *in,
46 43
47static struct xt_match ttl_mt_reg __read_mostly = { 44static struct xt_match ttl_mt_reg __read_mostly = {
48 .name = "ttl", 45 .name = "ttl",
49 .family = AF_INET, 46 .family = NFPROTO_IPV4,
50 .match = ttl_mt, 47 .match = ttl_mt,
51 .matchsize = sizeof(struct ipt_ttl_info), 48 .matchsize = sizeof(struct ipt_ttl_info),
52 .me = THIS_MODULE, 49 .me = THIS_MODULE,
diff --git a/net/ipv4/netfilter/iptable_filter.c b/net/ipv4/netfilter/iptable_filter.c
index 1ea677dcf845..c9224310ebae 100644
--- a/net/ipv4/netfilter/iptable_filter.c
+++ b/net/ipv4/netfilter/iptable_filter.c
@@ -70,7 +70,7 @@ ipt_local_in_hook(unsigned int hook,
70 int (*okfn)(struct sk_buff *)) 70 int (*okfn)(struct sk_buff *))
71{ 71{
72 return ipt_do_table(skb, hook, in, out, 72 return ipt_do_table(skb, hook, in, out,
73 nf_local_in_net(in, out)->ipv4.iptable_filter); 73 dev_net(in)->ipv4.iptable_filter);
74} 74}
75 75
76static unsigned int 76static unsigned int
@@ -81,7 +81,7 @@ ipt_hook(unsigned int hook,
81 int (*okfn)(struct sk_buff *)) 81 int (*okfn)(struct sk_buff *))
82{ 82{
83 return ipt_do_table(skb, hook, in, out, 83 return ipt_do_table(skb, hook, in, out,
84 nf_forward_net(in, out)->ipv4.iptable_filter); 84 dev_net(in)->ipv4.iptable_filter);
85} 85}
86 86
87static unsigned int 87static unsigned int
@@ -101,7 +101,7 @@ ipt_local_out_hook(unsigned int hook,
101 } 101 }
102 102
103 return ipt_do_table(skb, hook, in, out, 103 return ipt_do_table(skb, hook, in, out,
104 nf_local_out_net(in, out)->ipv4.iptable_filter); 104 dev_net(out)->ipv4.iptable_filter);
105} 105}
106 106
107static struct nf_hook_ops ipt_ops[] __read_mostly = { 107static struct nf_hook_ops ipt_ops[] __read_mostly = {
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
index da59182f2226..69f2c4287146 100644
--- a/net/ipv4/netfilter/iptable_mangle.c
+++ b/net/ipv4/netfilter/iptable_mangle.c
@@ -81,7 +81,7 @@ ipt_pre_routing_hook(unsigned int hook,
81 int (*okfn)(struct sk_buff *)) 81 int (*okfn)(struct sk_buff *))
82{ 82{
83 return ipt_do_table(skb, hook, in, out, 83 return ipt_do_table(skb, hook, in, out,
84 nf_pre_routing_net(in, out)->ipv4.iptable_mangle); 84 dev_net(in)->ipv4.iptable_mangle);
85} 85}
86 86
87static unsigned int 87static unsigned int
@@ -92,7 +92,7 @@ ipt_post_routing_hook(unsigned int hook,
92 int (*okfn)(struct sk_buff *)) 92 int (*okfn)(struct sk_buff *))
93{ 93{
94 return ipt_do_table(skb, hook, in, out, 94 return ipt_do_table(skb, hook, in, out,
95 nf_post_routing_net(in, out)->ipv4.iptable_mangle); 95 dev_net(out)->ipv4.iptable_mangle);
96} 96}
97 97
98static unsigned int 98static unsigned int
@@ -103,7 +103,7 @@ ipt_local_in_hook(unsigned int hook,
103 int (*okfn)(struct sk_buff *)) 103 int (*okfn)(struct sk_buff *))
104{ 104{
105 return ipt_do_table(skb, hook, in, out, 105 return ipt_do_table(skb, hook, in, out,
106 nf_local_in_net(in, out)->ipv4.iptable_mangle); 106 dev_net(in)->ipv4.iptable_mangle);
107} 107}
108 108
109static unsigned int 109static unsigned int
@@ -114,7 +114,7 @@ ipt_forward_hook(unsigned int hook,
114 int (*okfn)(struct sk_buff *)) 114 int (*okfn)(struct sk_buff *))
115{ 115{
116 return ipt_do_table(skb, hook, in, out, 116 return ipt_do_table(skb, hook, in, out,
117 nf_forward_net(in, out)->ipv4.iptable_mangle); 117 dev_net(in)->ipv4.iptable_mangle);
118} 118}
119 119
120static unsigned int 120static unsigned int
@@ -147,7 +147,7 @@ ipt_local_hook(unsigned int hook,
147 tos = iph->tos; 147 tos = iph->tos;
148 148
149 ret = ipt_do_table(skb, hook, in, out, 149 ret = ipt_do_table(skb, hook, in, out,
150 nf_local_out_net(in, out)->ipv4.iptable_mangle); 150 dev_net(out)->ipv4.iptable_mangle);
151 /* Reroute for ANY change. */ 151 /* Reroute for ANY change. */
152 if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE) { 152 if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE) {
153 iph = ip_hdr(skb); 153 iph = ip_hdr(skb);
diff --git a/net/ipv4/netfilter/iptable_raw.c b/net/ipv4/netfilter/iptable_raw.c
index fddce7754b72..8faebfe638f1 100644
--- a/net/ipv4/netfilter/iptable_raw.c
+++ b/net/ipv4/netfilter/iptable_raw.c
@@ -53,7 +53,7 @@ ipt_hook(unsigned int hook,
53 int (*okfn)(struct sk_buff *)) 53 int (*okfn)(struct sk_buff *))
54{ 54{
55 return ipt_do_table(skb, hook, in, out, 55 return ipt_do_table(skb, hook, in, out,
56 nf_pre_routing_net(in, out)->ipv4.iptable_raw); 56 dev_net(in)->ipv4.iptable_raw);
57} 57}
58 58
59static unsigned int 59static unsigned int
@@ -72,7 +72,7 @@ ipt_local_hook(unsigned int hook,
72 return NF_ACCEPT; 72 return NF_ACCEPT;
73 } 73 }
74 return ipt_do_table(skb, hook, in, out, 74 return ipt_do_table(skb, hook, in, out,
75 nf_local_out_net(in, out)->ipv4.iptable_raw); 75 dev_net(out)->ipv4.iptable_raw);
76} 76}
77 77
78/* 'raw' is the very first table. */ 78/* 'raw' is the very first table. */
diff --git a/net/ipv4/netfilter/iptable_security.c b/net/ipv4/netfilter/iptable_security.c
index db6d312128e1..36f3be3cc428 100644
--- a/net/ipv4/netfilter/iptable_security.c
+++ b/net/ipv4/netfilter/iptable_security.c
@@ -73,7 +73,7 @@ ipt_local_in_hook(unsigned int hook,
73 int (*okfn)(struct sk_buff *)) 73 int (*okfn)(struct sk_buff *))
74{ 74{
75 return ipt_do_table(skb, hook, in, out, 75 return ipt_do_table(skb, hook, in, out,
76 nf_local_in_net(in, out)->ipv4.iptable_security); 76 dev_net(in)->ipv4.iptable_security);
77} 77}
78 78
79static unsigned int 79static unsigned int
@@ -84,7 +84,7 @@ ipt_forward_hook(unsigned int hook,
84 int (*okfn)(struct sk_buff *)) 84 int (*okfn)(struct sk_buff *))
85{ 85{
86 return ipt_do_table(skb, hook, in, out, 86 return ipt_do_table(skb, hook, in, out,
87 nf_forward_net(in, out)->ipv4.iptable_security); 87 dev_net(in)->ipv4.iptable_security);
88} 88}
89 89
90static unsigned int 90static unsigned int
@@ -103,7 +103,7 @@ ipt_local_out_hook(unsigned int hook,
103 return NF_ACCEPT; 103 return NF_ACCEPT;
104 } 104 }
105 return ipt_do_table(skb, hook, in, out, 105 return ipt_do_table(skb, hook, in, out,
106 nf_local_out_net(in, out)->ipv4.iptable_security); 106 dev_net(out)->ipv4.iptable_security);
107} 107}
108 108
109static struct nf_hook_ops ipt_ops[] __read_mostly = { 109static struct nf_hook_ops ipt_ops[] __read_mostly = {
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 5a955c440364..4a7c35275396 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -1,3 +1,4 @@
1
1/* (C) 1999-2001 Paul `Rusty' Russell 2/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> 3 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
3 * 4 *
@@ -24,6 +25,7 @@
24#include <net/netfilter/nf_conntrack_core.h> 25#include <net/netfilter/nf_conntrack_core.h>
25#include <net/netfilter/ipv4/nf_conntrack_ipv4.h> 26#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
26#include <net/netfilter/nf_nat_helper.h> 27#include <net/netfilter/nf_nat_helper.h>
28#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
27 29
28int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb, 30int (*nf_nat_seq_adjust_hook)(struct sk_buff *skb,
29 struct nf_conn *ct, 31 struct nf_conn *ct,
@@ -63,23 +65,6 @@ static int ipv4_print_tuple(struct seq_file *s,
63 NIPQUAD(tuple->dst.u3.ip)); 65 NIPQUAD(tuple->dst.u3.ip));
64} 66}
65 67
66/* Returns new sk_buff, or NULL */
67static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
68{
69 int err;
70
71 skb_orphan(skb);
72
73 local_bh_disable();
74 err = ip_defrag(skb, user);
75 local_bh_enable();
76
77 if (!err)
78 ip_send_check(ip_hdr(skb));
79
80 return err;
81}
82
83static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff, 68static int ipv4_get_l4proto(const struct sk_buff *skb, unsigned int nhoff,
84 unsigned int *dataoff, u_int8_t *protonum) 69 unsigned int *dataoff, u_int8_t *protonum)
85{ 70{
@@ -144,35 +129,13 @@ out:
144 return nf_conntrack_confirm(skb); 129 return nf_conntrack_confirm(skb);
145} 130}
146 131
147static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
148 struct sk_buff *skb,
149 const struct net_device *in,
150 const struct net_device *out,
151 int (*okfn)(struct sk_buff *))
152{
153 /* Previously seen (loopback)? Ignore. Do this before
154 fragment check. */
155 if (skb->nfct)
156 return NF_ACCEPT;
157
158 /* Gather fragments. */
159 if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
160 if (nf_ct_ipv4_gather_frags(skb,
161 hooknum == NF_INET_PRE_ROUTING ?
162 IP_DEFRAG_CONNTRACK_IN :
163 IP_DEFRAG_CONNTRACK_OUT))
164 return NF_STOLEN;
165 }
166 return NF_ACCEPT;
167}
168
169static unsigned int ipv4_conntrack_in(unsigned int hooknum, 132static unsigned int ipv4_conntrack_in(unsigned int hooknum,
170 struct sk_buff *skb, 133 struct sk_buff *skb,
171 const struct net_device *in, 134 const struct net_device *in,
172 const struct net_device *out, 135 const struct net_device *out,
173 int (*okfn)(struct sk_buff *)) 136 int (*okfn)(struct sk_buff *))
174{ 137{
175 return nf_conntrack_in(PF_INET, hooknum, skb); 138 return nf_conntrack_in(dev_net(in), PF_INET, hooknum, skb);
176} 139}
177 140
178static unsigned int ipv4_conntrack_local(unsigned int hooknum, 141static unsigned int ipv4_conntrack_local(unsigned int hooknum,
@@ -188,20 +151,13 @@ static unsigned int ipv4_conntrack_local(unsigned int hooknum,
188 printk("ipt_hook: happy cracking.\n"); 151 printk("ipt_hook: happy cracking.\n");
189 return NF_ACCEPT; 152 return NF_ACCEPT;
190 } 153 }
191 return nf_conntrack_in(PF_INET, hooknum, skb); 154 return nf_conntrack_in(dev_net(out), PF_INET, hooknum, skb);
192} 155}
193 156
194/* Connection tracking may drop packets, but never alters them, so 157/* Connection tracking may drop packets, but never alters them, so
195 make it the first hook. */ 158 make it the first hook. */
196static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = { 159static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = {
197 { 160 {
198 .hook = ipv4_conntrack_defrag,
199 .owner = THIS_MODULE,
200 .pf = PF_INET,
201 .hooknum = NF_INET_PRE_ROUTING,
202 .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
203 },
204 {
205 .hook = ipv4_conntrack_in, 161 .hook = ipv4_conntrack_in,
206 .owner = THIS_MODULE, 162 .owner = THIS_MODULE,
207 .pf = PF_INET, 163 .pf = PF_INET,
@@ -209,13 +165,6 @@ static struct nf_hook_ops ipv4_conntrack_ops[] __read_mostly = {
209 .priority = NF_IP_PRI_CONNTRACK, 165 .priority = NF_IP_PRI_CONNTRACK,
210 }, 166 },
211 { 167 {
212 .hook = ipv4_conntrack_defrag,
213 .owner = THIS_MODULE,
214 .pf = PF_INET,
215 .hooknum = NF_INET_LOCAL_OUT,
216 .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
217 },
218 {
219 .hook = ipv4_conntrack_local, 168 .hook = ipv4_conntrack_local,
220 .owner = THIS_MODULE, 169 .owner = THIS_MODULE,
221 .pf = PF_INET, 170 .pf = PF_INET,
@@ -254,7 +203,7 @@ static ctl_table ip_ct_sysctl_table[] = {
254 { 203 {
255 .ctl_name = NET_IPV4_NF_CONNTRACK_COUNT, 204 .ctl_name = NET_IPV4_NF_CONNTRACK_COUNT,
256 .procname = "ip_conntrack_count", 205 .procname = "ip_conntrack_count",
257 .data = &nf_conntrack_count, 206 .data = &init_net.ct.count,
258 .maxlen = sizeof(int), 207 .maxlen = sizeof(int),
259 .mode = 0444, 208 .mode = 0444,
260 .proc_handler = &proc_dointvec, 209 .proc_handler = &proc_dointvec,
@@ -270,7 +219,7 @@ static ctl_table ip_ct_sysctl_table[] = {
270 { 219 {
271 .ctl_name = NET_IPV4_NF_CONNTRACK_CHECKSUM, 220 .ctl_name = NET_IPV4_NF_CONNTRACK_CHECKSUM,
272 .procname = "ip_conntrack_checksum", 221 .procname = "ip_conntrack_checksum",
273 .data = &nf_conntrack_checksum, 222 .data = &init_net.ct.sysctl_checksum,
274 .maxlen = sizeof(int), 223 .maxlen = sizeof(int),
275 .mode = 0644, 224 .mode = 0644,
276 .proc_handler = &proc_dointvec, 225 .proc_handler = &proc_dointvec,
@@ -278,7 +227,7 @@ static ctl_table ip_ct_sysctl_table[] = {
278 { 227 {
279 .ctl_name = NET_IPV4_NF_CONNTRACK_LOG_INVALID, 228 .ctl_name = NET_IPV4_NF_CONNTRACK_LOG_INVALID,
280 .procname = "ip_conntrack_log_invalid", 229 .procname = "ip_conntrack_log_invalid",
281 .data = &nf_ct_log_invalid, 230 .data = &init_net.ct.sysctl_log_invalid,
282 .maxlen = sizeof(unsigned int), 231 .maxlen = sizeof(unsigned int),
283 .mode = 0644, 232 .mode = 0644,
284 .proc_handler = &proc_dointvec_minmax, 233 .proc_handler = &proc_dointvec_minmax,
@@ -323,7 +272,7 @@ getorigdst(struct sock *sk, int optval, void __user *user, int *len)
323 return -EINVAL; 272 return -EINVAL;
324 } 273 }
325 274
326 h = nf_conntrack_find_get(&tuple); 275 h = nf_conntrack_find_get(sock_net(sk), &tuple);
327 if (h) { 276 if (h) {
328 struct sockaddr_in sin; 277 struct sockaddr_in sin;
329 struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h); 278 struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
@@ -422,6 +371,7 @@ static int __init nf_conntrack_l3proto_ipv4_init(void)
422 int ret = 0; 371 int ret = 0;
423 372
424 need_conntrack(); 373 need_conntrack();
374 nf_defrag_ipv4_enable();
425 375
426 ret = nf_register_sockopt(&so_getorigdst); 376 ret = nf_register_sockopt(&so_getorigdst);
427 if (ret < 0) { 377 if (ret < 0) {
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
index 3a020720e40b..313ebf00ee36 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
@@ -21,18 +21,20 @@
21#include <net/netfilter/nf_conntrack_acct.h> 21#include <net/netfilter/nf_conntrack_acct.h>
22 22
23struct ct_iter_state { 23struct ct_iter_state {
24 struct seq_net_private p;
24 unsigned int bucket; 25 unsigned int bucket;
25}; 26};
26 27
27static struct hlist_node *ct_get_first(struct seq_file *seq) 28static struct hlist_node *ct_get_first(struct seq_file *seq)
28{ 29{
30 struct net *net = seq_file_net(seq);
29 struct ct_iter_state *st = seq->private; 31 struct ct_iter_state *st = seq->private;
30 struct hlist_node *n; 32 struct hlist_node *n;
31 33
32 for (st->bucket = 0; 34 for (st->bucket = 0;
33 st->bucket < nf_conntrack_htable_size; 35 st->bucket < nf_conntrack_htable_size;
34 st->bucket++) { 36 st->bucket++) {
35 n = rcu_dereference(nf_conntrack_hash[st->bucket].first); 37 n = rcu_dereference(net->ct.hash[st->bucket].first);
36 if (n) 38 if (n)
37 return n; 39 return n;
38 } 40 }
@@ -42,13 +44,14 @@ static struct hlist_node *ct_get_first(struct seq_file *seq)
42static struct hlist_node *ct_get_next(struct seq_file *seq, 44static struct hlist_node *ct_get_next(struct seq_file *seq,
43 struct hlist_node *head) 45 struct hlist_node *head)
44{ 46{
47 struct net *net = seq_file_net(seq);
45 struct ct_iter_state *st = seq->private; 48 struct ct_iter_state *st = seq->private;
46 49
47 head = rcu_dereference(head->next); 50 head = rcu_dereference(head->next);
48 while (head == NULL) { 51 while (head == NULL) {
49 if (++st->bucket >= nf_conntrack_htable_size) 52 if (++st->bucket >= nf_conntrack_htable_size)
50 return NULL; 53 return NULL;
51 head = rcu_dereference(nf_conntrack_hash[st->bucket].first); 54 head = rcu_dereference(net->ct.hash[st->bucket].first);
52 } 55 }
53 return head; 56 return head;
54} 57}
@@ -158,8 +161,8 @@ static const struct seq_operations ct_seq_ops = {
158 161
159static int ct_open(struct inode *inode, struct file *file) 162static int ct_open(struct inode *inode, struct file *file)
160{ 163{
161 return seq_open_private(file, &ct_seq_ops, 164 return seq_open_net(inode, file, &ct_seq_ops,
162 sizeof(struct ct_iter_state)); 165 sizeof(struct ct_iter_state));
163} 166}
164 167
165static const struct file_operations ct_file_ops = { 168static const struct file_operations ct_file_ops = {
@@ -167,21 +170,23 @@ static const struct file_operations ct_file_ops = {
167 .open = ct_open, 170 .open = ct_open,
168 .read = seq_read, 171 .read = seq_read,
169 .llseek = seq_lseek, 172 .llseek = seq_lseek,
170 .release = seq_release_private, 173 .release = seq_release_net,
171}; 174};
172 175
173/* expects */ 176/* expects */
174struct ct_expect_iter_state { 177struct ct_expect_iter_state {
178 struct seq_net_private p;
175 unsigned int bucket; 179 unsigned int bucket;
176}; 180};
177 181
178static struct hlist_node *ct_expect_get_first(struct seq_file *seq) 182static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
179{ 183{
184 struct net *net = seq_file_net(seq);
180 struct ct_expect_iter_state *st = seq->private; 185 struct ct_expect_iter_state *st = seq->private;
181 struct hlist_node *n; 186 struct hlist_node *n;
182 187
183 for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) { 188 for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) {
184 n = rcu_dereference(nf_ct_expect_hash[st->bucket].first); 189 n = rcu_dereference(net->ct.expect_hash[st->bucket].first);
185 if (n) 190 if (n)
186 return n; 191 return n;
187 } 192 }
@@ -191,13 +196,14 @@ static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
191static struct hlist_node *ct_expect_get_next(struct seq_file *seq, 196static struct hlist_node *ct_expect_get_next(struct seq_file *seq,
192 struct hlist_node *head) 197 struct hlist_node *head)
193{ 198{
199 struct net *net = seq_file_net(seq);
194 struct ct_expect_iter_state *st = seq->private; 200 struct ct_expect_iter_state *st = seq->private;
195 201
196 head = rcu_dereference(head->next); 202 head = rcu_dereference(head->next);
197 while (head == NULL) { 203 while (head == NULL) {
198 if (++st->bucket >= nf_ct_expect_hsize) 204 if (++st->bucket >= nf_ct_expect_hsize)
199 return NULL; 205 return NULL;
200 head = rcu_dereference(nf_ct_expect_hash[st->bucket].first); 206 head = rcu_dereference(net->ct.expect_hash[st->bucket].first);
201 } 207 }
202 return head; 208 return head;
203} 209}
@@ -265,8 +271,8 @@ static const struct seq_operations exp_seq_ops = {
265 271
266static int exp_open(struct inode *inode, struct file *file) 272static int exp_open(struct inode *inode, struct file *file)
267{ 273{
268 return seq_open_private(file, &exp_seq_ops, 274 return seq_open_net(inode, file, &exp_seq_ops,
269 sizeof(struct ct_expect_iter_state)); 275 sizeof(struct ct_expect_iter_state));
270} 276}
271 277
272static const struct file_operations ip_exp_file_ops = { 278static const struct file_operations ip_exp_file_ops = {
@@ -274,11 +280,12 @@ static const struct file_operations ip_exp_file_ops = {
274 .open = exp_open, 280 .open = exp_open,
275 .read = seq_read, 281 .read = seq_read,
276 .llseek = seq_lseek, 282 .llseek = seq_lseek,
277 .release = seq_release_private, 283 .release = seq_release_net,
278}; 284};
279 285
280static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos) 286static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
281{ 287{
288 struct net *net = seq_file_net(seq);
282 int cpu; 289 int cpu;
283 290
284 if (*pos == 0) 291 if (*pos == 0)
@@ -288,7 +295,7 @@ static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
288 if (!cpu_possible(cpu)) 295 if (!cpu_possible(cpu))
289 continue; 296 continue;
290 *pos = cpu+1; 297 *pos = cpu+1;
291 return &per_cpu(nf_conntrack_stat, cpu); 298 return per_cpu_ptr(net->ct.stat, cpu);
292 } 299 }
293 300
294 return NULL; 301 return NULL;
@@ -296,13 +303,14 @@ static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
296 303
297static void *ct_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos) 304static void *ct_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos)
298{ 305{
306 struct net *net = seq_file_net(seq);
299 int cpu; 307 int cpu;
300 308
301 for (cpu = *pos; cpu < NR_CPUS; ++cpu) { 309 for (cpu = *pos; cpu < NR_CPUS; ++cpu) {
302 if (!cpu_possible(cpu)) 310 if (!cpu_possible(cpu))
303 continue; 311 continue;
304 *pos = cpu+1; 312 *pos = cpu+1;
305 return &per_cpu(nf_conntrack_stat, cpu); 313 return per_cpu_ptr(net->ct.stat, cpu);
306 } 314 }
307 315
308 return NULL; 316 return NULL;
@@ -314,7 +322,8 @@ static void ct_cpu_seq_stop(struct seq_file *seq, void *v)
314 322
315static int ct_cpu_seq_show(struct seq_file *seq, void *v) 323static int ct_cpu_seq_show(struct seq_file *seq, void *v)
316{ 324{
317 unsigned int nr_conntracks = atomic_read(&nf_conntrack_count); 325 struct net *net = seq_file_net(seq);
326 unsigned int nr_conntracks = atomic_read(&net->ct.count);
318 const struct ip_conntrack_stat *st = v; 327 const struct ip_conntrack_stat *st = v;
319 328
320 if (v == SEQ_START_TOKEN) { 329 if (v == SEQ_START_TOKEN) {
@@ -354,7 +363,8 @@ static const struct seq_operations ct_cpu_seq_ops = {
354 363
355static int ct_cpu_seq_open(struct inode *inode, struct file *file) 364static int ct_cpu_seq_open(struct inode *inode, struct file *file)
356{ 365{
357 return seq_open(file, &ct_cpu_seq_ops); 366 return seq_open_net(inode, file, &ct_cpu_seq_ops,
367 sizeof(struct seq_net_private));
358} 368}
359 369
360static const struct file_operations ct_cpu_seq_fops = { 370static const struct file_operations ct_cpu_seq_fops = {
@@ -362,39 +372,54 @@ static const struct file_operations ct_cpu_seq_fops = {
362 .open = ct_cpu_seq_open, 372 .open = ct_cpu_seq_open,
363 .read = seq_read, 373 .read = seq_read,
364 .llseek = seq_lseek, 374 .llseek = seq_lseek,
365 .release = seq_release, 375 .release = seq_release_net,
366}; 376};
367 377
368int __init nf_conntrack_ipv4_compat_init(void) 378static int __net_init ip_conntrack_net_init(struct net *net)
369{ 379{
370 struct proc_dir_entry *proc, *proc_exp, *proc_stat; 380 struct proc_dir_entry *proc, *proc_exp, *proc_stat;
371 381
372 proc = proc_net_fops_create(&init_net, "ip_conntrack", 0440, &ct_file_ops); 382 proc = proc_net_fops_create(net, "ip_conntrack", 0440, &ct_file_ops);
373 if (!proc) 383 if (!proc)
374 goto err1; 384 goto err1;
375 385
376 proc_exp = proc_net_fops_create(&init_net, "ip_conntrack_expect", 0440, 386 proc_exp = proc_net_fops_create(net, "ip_conntrack_expect", 0440,
377 &ip_exp_file_ops); 387 &ip_exp_file_ops);
378 if (!proc_exp) 388 if (!proc_exp)
379 goto err2; 389 goto err2;
380 390
381 proc_stat = proc_create("ip_conntrack", S_IRUGO, 391 proc_stat = proc_create("ip_conntrack", S_IRUGO,
382 init_net.proc_net_stat, &ct_cpu_seq_fops); 392 net->proc_net_stat, &ct_cpu_seq_fops);
383 if (!proc_stat) 393 if (!proc_stat)
384 goto err3; 394 goto err3;
385 return 0; 395 return 0;
386 396
387err3: 397err3:
388 proc_net_remove(&init_net, "ip_conntrack_expect"); 398 proc_net_remove(net, "ip_conntrack_expect");
389err2: 399err2:
390 proc_net_remove(&init_net, "ip_conntrack"); 400 proc_net_remove(net, "ip_conntrack");
391err1: 401err1:
392 return -ENOMEM; 402 return -ENOMEM;
393} 403}
394 404
405static void __net_exit ip_conntrack_net_exit(struct net *net)
406{
407 remove_proc_entry("ip_conntrack", net->proc_net_stat);
408 proc_net_remove(net, "ip_conntrack_expect");
409 proc_net_remove(net, "ip_conntrack");
410}
411
412static struct pernet_operations ip_conntrack_net_ops = {
413 .init = ip_conntrack_net_init,
414 .exit = ip_conntrack_net_exit,
415};
416
417int __init nf_conntrack_ipv4_compat_init(void)
418{
419 return register_pernet_subsys(&ip_conntrack_net_ops);
420}
421
395void __exit nf_conntrack_ipv4_compat_fini(void) 422void __exit nf_conntrack_ipv4_compat_fini(void)
396{ 423{
397 remove_proc_entry("ip_conntrack", init_net.proc_net_stat); 424 unregister_pernet_subsys(&ip_conntrack_net_ops);
398 proc_net_remove(&init_net, "ip_conntrack_expect");
399 proc_net_remove(&init_net, "ip_conntrack");
400} 425}
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
index 97791048fa9b..4e8879220222 100644
--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -79,7 +79,7 @@ static int icmp_packet(struct nf_conn *ct,
79 const struct sk_buff *skb, 79 const struct sk_buff *skb,
80 unsigned int dataoff, 80 unsigned int dataoff,
81 enum ip_conntrack_info ctinfo, 81 enum ip_conntrack_info ctinfo,
82 int pf, 82 u_int8_t pf,
83 unsigned int hooknum) 83 unsigned int hooknum)
84{ 84{
85 /* Try to delete connection immediately after all replies: 85 /* Try to delete connection immediately after all replies:
@@ -91,7 +91,7 @@ static int icmp_packet(struct nf_conn *ct,
91 nf_ct_kill_acct(ct, ctinfo, skb); 91 nf_ct_kill_acct(ct, ctinfo, skb);
92 } else { 92 } else {
93 atomic_inc(&ct->proto.icmp.count); 93 atomic_inc(&ct->proto.icmp.count);
94 nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb); 94 nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, ct);
95 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmp_timeout); 95 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmp_timeout);
96 } 96 }
97 97
@@ -123,7 +123,7 @@ static bool icmp_new(struct nf_conn *ct, const struct sk_buff *skb,
123 123
124/* Returns conntrack if it dealt with ICMP, and filled in skb fields */ 124/* Returns conntrack if it dealt with ICMP, and filled in skb fields */
125static int 125static int
126icmp_error_message(struct sk_buff *skb, 126icmp_error_message(struct net *net, struct sk_buff *skb,
127 enum ip_conntrack_info *ctinfo, 127 enum ip_conntrack_info *ctinfo,
128 unsigned int hooknum) 128 unsigned int hooknum)
129{ 129{
@@ -155,7 +155,7 @@ icmp_error_message(struct sk_buff *skb,
155 155
156 *ctinfo = IP_CT_RELATED; 156 *ctinfo = IP_CT_RELATED;
157 157
158 h = nf_conntrack_find_get(&innertuple); 158 h = nf_conntrack_find_get(net, &innertuple);
159 if (!h) { 159 if (!h) {
160 pr_debug("icmp_error_message: no match\n"); 160 pr_debug("icmp_error_message: no match\n");
161 return -NF_ACCEPT; 161 return -NF_ACCEPT;
@@ -172,8 +172,8 @@ icmp_error_message(struct sk_buff *skb,
172 172
173/* Small and modified version of icmp_rcv */ 173/* Small and modified version of icmp_rcv */
174static int 174static int
175icmp_error(struct sk_buff *skb, unsigned int dataoff, 175icmp_error(struct net *net, struct sk_buff *skb, unsigned int dataoff,
176 enum ip_conntrack_info *ctinfo, int pf, unsigned int hooknum) 176 enum ip_conntrack_info *ctinfo, u_int8_t pf, unsigned int hooknum)
177{ 177{
178 const struct icmphdr *icmph; 178 const struct icmphdr *icmph;
179 struct icmphdr _ih; 179 struct icmphdr _ih;
@@ -181,16 +181,16 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff,
181 /* Not enough header? */ 181 /* Not enough header? */
182 icmph = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_ih), &_ih); 182 icmph = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_ih), &_ih);
183 if (icmph == NULL) { 183 if (icmph == NULL) {
184 if (LOG_INVALID(IPPROTO_ICMP)) 184 if (LOG_INVALID(net, IPPROTO_ICMP))
185 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, 185 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
186 "nf_ct_icmp: short packet "); 186 "nf_ct_icmp: short packet ");
187 return -NF_ACCEPT; 187 return -NF_ACCEPT;
188 } 188 }
189 189
190 /* See ip_conntrack_proto_tcp.c */ 190 /* See ip_conntrack_proto_tcp.c */
191 if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING && 191 if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
192 nf_ip_checksum(skb, hooknum, dataoff, 0)) { 192 nf_ip_checksum(skb, hooknum, dataoff, 0)) {
193 if (LOG_INVALID(IPPROTO_ICMP)) 193 if (LOG_INVALID(net, IPPROTO_ICMP))
194 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, 194 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
195 "nf_ct_icmp: bad HW ICMP checksum "); 195 "nf_ct_icmp: bad HW ICMP checksum ");
196 return -NF_ACCEPT; 196 return -NF_ACCEPT;
@@ -203,7 +203,7 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff,
203 * discarded. 203 * discarded.
204 */ 204 */
205 if (icmph->type > NR_ICMP_TYPES) { 205 if (icmph->type > NR_ICMP_TYPES) {
206 if (LOG_INVALID(IPPROTO_ICMP)) 206 if (LOG_INVALID(net, IPPROTO_ICMP))
207 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL, 207 nf_log_packet(PF_INET, 0, skb, NULL, NULL, NULL,
208 "nf_ct_icmp: invalid ICMP type "); 208 "nf_ct_icmp: invalid ICMP type ");
209 return -NF_ACCEPT; 209 return -NF_ACCEPT;
@@ -217,7 +217,7 @@ icmp_error(struct sk_buff *skb, unsigned int dataoff,
217 && icmph->type != ICMP_REDIRECT) 217 && icmph->type != ICMP_REDIRECT)
218 return NF_ACCEPT; 218 return NF_ACCEPT;
219 219
220 return icmp_error_message(skb, ctinfo, hooknum); 220 return icmp_error_message(net, skb, ctinfo, hooknum);
221} 221}
222 222
223#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 223#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c
new file mode 100644
index 000000000000..aa2c50a180f7
--- /dev/null
+++ b/net/ipv4/netfilter/nf_defrag_ipv4.c
@@ -0,0 +1,96 @@
1/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/types.h>
10#include <linux/ip.h>
11#include <linux/netfilter.h>
12#include <linux/module.h>
13#include <linux/skbuff.h>
14#include <net/route.h>
15#include <net/ip.h>
16
17#include <linux/netfilter_ipv4.h>
18#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
19
20/* Returns new sk_buff, or NULL */
21static int nf_ct_ipv4_gather_frags(struct sk_buff *skb, u_int32_t user)
22{
23 int err;
24
25 skb_orphan(skb);
26
27 local_bh_disable();
28 err = ip_defrag(skb, user);
29 local_bh_enable();
30
31 if (!err)
32 ip_send_check(ip_hdr(skb));
33
34 return err;
35}
36
37static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
38 struct sk_buff *skb,
39 const struct net_device *in,
40 const struct net_device *out,
41 int (*okfn)(struct sk_buff *))
42{
43#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
44 /* Previously seen (loopback)? Ignore. Do this before
45 fragment check. */
46 if (skb->nfct)
47 return NF_ACCEPT;
48#endif
49
50 /* Gather fragments. */
51 if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
52 if (nf_ct_ipv4_gather_frags(skb,
53 hooknum == NF_INET_PRE_ROUTING ?
54 IP_DEFRAG_CONNTRACK_IN :
55 IP_DEFRAG_CONNTRACK_OUT))
56 return NF_STOLEN;
57 }
58 return NF_ACCEPT;
59}
60
61static struct nf_hook_ops ipv4_defrag_ops[] = {
62 {
63 .hook = ipv4_conntrack_defrag,
64 .owner = THIS_MODULE,
65 .pf = PF_INET,
66 .hooknum = NF_INET_PRE_ROUTING,
67 .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
68 },
69 {
70 .hook = ipv4_conntrack_defrag,
71 .owner = THIS_MODULE,
72 .pf = PF_INET,
73 .hooknum = NF_INET_LOCAL_OUT,
74 .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
75 },
76};
77
78static int __init nf_defrag_init(void)
79{
80 return nf_register_hooks(ipv4_defrag_ops, ARRAY_SIZE(ipv4_defrag_ops));
81}
82
83static void __exit nf_defrag_fini(void)
84{
85 nf_unregister_hooks(ipv4_defrag_ops, ARRAY_SIZE(ipv4_defrag_ops));
86}
87
88void nf_defrag_ipv4_enable(void)
89{
90}
91EXPORT_SYMBOL_GPL(nf_defrag_ipv4_enable);
92
93module_init(nf_defrag_init);
94module_exit(nf_defrag_fini);
95
96MODULE_LICENSE("GPL");
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
index 6c6a3cba8d50..2ac9eaf1a8c9 100644
--- a/net/ipv4/netfilter/nf_nat_core.c
+++ b/net/ipv4/netfilter/nf_nat_core.c
@@ -37,9 +37,6 @@ static struct nf_conntrack_l3proto *l3proto __read_mostly;
37 37
38/* Calculated at init based on memory size */ 38/* Calculated at init based on memory size */
39static unsigned int nf_nat_htable_size __read_mostly; 39static unsigned int nf_nat_htable_size __read_mostly;
40static int nf_nat_vmalloced;
41
42static struct hlist_head *bysource __read_mostly;
43 40
44#define MAX_IP_NAT_PROTO 256 41#define MAX_IP_NAT_PROTO 256
45static const struct nf_nat_protocol *nf_nat_protos[MAX_IP_NAT_PROTO] 42static const struct nf_nat_protocol *nf_nat_protos[MAX_IP_NAT_PROTO]
@@ -145,7 +142,8 @@ same_src(const struct nf_conn *ct,
145 142
146/* Only called for SRC manip */ 143/* Only called for SRC manip */
147static int 144static int
148find_appropriate_src(const struct nf_conntrack_tuple *tuple, 145find_appropriate_src(struct net *net,
146 const struct nf_conntrack_tuple *tuple,
149 struct nf_conntrack_tuple *result, 147 struct nf_conntrack_tuple *result,
150 const struct nf_nat_range *range) 148 const struct nf_nat_range *range)
151{ 149{
@@ -155,7 +153,7 @@ find_appropriate_src(const struct nf_conntrack_tuple *tuple,
155 const struct hlist_node *n; 153 const struct hlist_node *n;
156 154
157 rcu_read_lock(); 155 rcu_read_lock();
158 hlist_for_each_entry_rcu(nat, n, &bysource[h], bysource) { 156 hlist_for_each_entry_rcu(nat, n, &net->ipv4.nat_bysource[h], bysource) {
159 ct = nat->ct; 157 ct = nat->ct;
160 if (same_src(ct, tuple)) { 158 if (same_src(ct, tuple)) {
161 /* Copy source part from reply tuple. */ 159 /* Copy source part from reply tuple. */
@@ -231,6 +229,7 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple,
231 struct nf_conn *ct, 229 struct nf_conn *ct,
232 enum nf_nat_manip_type maniptype) 230 enum nf_nat_manip_type maniptype)
233{ 231{
232 struct net *net = nf_ct_net(ct);
234 const struct nf_nat_protocol *proto; 233 const struct nf_nat_protocol *proto;
235 234
236 /* 1) If this srcip/proto/src-proto-part is currently mapped, 235 /* 1) If this srcip/proto/src-proto-part is currently mapped,
@@ -242,7 +241,7 @@ get_unique_tuple(struct nf_conntrack_tuple *tuple,
242 manips not an issue. */ 241 manips not an issue. */
243 if (maniptype == IP_NAT_MANIP_SRC && 242 if (maniptype == IP_NAT_MANIP_SRC &&
244 !(range->flags & IP_NAT_RANGE_PROTO_RANDOM)) { 243 !(range->flags & IP_NAT_RANGE_PROTO_RANDOM)) {
245 if (find_appropriate_src(orig_tuple, tuple, range)) { 244 if (find_appropriate_src(net, orig_tuple, tuple, range)) {
246 pr_debug("get_unique_tuple: Found current src map\n"); 245 pr_debug("get_unique_tuple: Found current src map\n");
247 if (!nf_nat_used_tuple(tuple, ct)) 246 if (!nf_nat_used_tuple(tuple, ct))
248 return; 247 return;
@@ -283,6 +282,7 @@ nf_nat_setup_info(struct nf_conn *ct,
283 const struct nf_nat_range *range, 282 const struct nf_nat_range *range,
284 enum nf_nat_manip_type maniptype) 283 enum nf_nat_manip_type maniptype)
285{ 284{
285 struct net *net = nf_ct_net(ct);
286 struct nf_conntrack_tuple curr_tuple, new_tuple; 286 struct nf_conntrack_tuple curr_tuple, new_tuple;
287 struct nf_conn_nat *nat; 287 struct nf_conn_nat *nat;
288 int have_to_hash = !(ct->status & IPS_NAT_DONE_MASK); 288 int have_to_hash = !(ct->status & IPS_NAT_DONE_MASK);
@@ -334,7 +334,8 @@ nf_nat_setup_info(struct nf_conn *ct,
334 /* nf_conntrack_alter_reply might re-allocate exntension aera */ 334 /* nf_conntrack_alter_reply might re-allocate exntension aera */
335 nat = nfct_nat(ct); 335 nat = nfct_nat(ct);
336 nat->ct = ct; 336 nat->ct = ct;
337 hlist_add_head_rcu(&nat->bysource, &bysource[srchash]); 337 hlist_add_head_rcu(&nat->bysource,
338 &net->ipv4.nat_bysource[srchash]);
338 spin_unlock_bh(&nf_nat_lock); 339 spin_unlock_bh(&nf_nat_lock);
339 } 340 }
340 341
@@ -583,6 +584,40 @@ static struct nf_ct_ext_type nat_extend __read_mostly = {
583 .flags = NF_CT_EXT_F_PREALLOC, 584 .flags = NF_CT_EXT_F_PREALLOC,
584}; 585};
585 586
587static int __net_init nf_nat_net_init(struct net *net)
588{
589 net->ipv4.nat_bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size,
590 &net->ipv4.nat_vmalloced);
591 if (!net->ipv4.nat_bysource)
592 return -ENOMEM;
593 return 0;
594}
595
596/* Clear NAT section of all conntracks, in case we're loaded again. */
597static int clean_nat(struct nf_conn *i, void *data)
598{
599 struct nf_conn_nat *nat = nfct_nat(i);
600
601 if (!nat)
602 return 0;
603 memset(nat, 0, sizeof(*nat));
604 i->status &= ~(IPS_NAT_MASK | IPS_NAT_DONE_MASK | IPS_SEQ_ADJUST);
605 return 0;
606}
607
608static void __net_exit nf_nat_net_exit(struct net *net)
609{
610 nf_ct_iterate_cleanup(net, &clean_nat, NULL);
611 synchronize_rcu();
612 nf_ct_free_hashtable(net->ipv4.nat_bysource, net->ipv4.nat_vmalloced,
613 nf_nat_htable_size);
614}
615
616static struct pernet_operations nf_nat_net_ops = {
617 .init = nf_nat_net_init,
618 .exit = nf_nat_net_exit,
619};
620
586static int __init nf_nat_init(void) 621static int __init nf_nat_init(void)
587{ 622{
588 size_t i; 623 size_t i;
@@ -599,12 +634,9 @@ static int __init nf_nat_init(void)
599 /* Leave them the same for the moment. */ 634 /* Leave them the same for the moment. */
600 nf_nat_htable_size = nf_conntrack_htable_size; 635 nf_nat_htable_size = nf_conntrack_htable_size;
601 636
602 bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size, 637 ret = register_pernet_subsys(&nf_nat_net_ops);
603 &nf_nat_vmalloced); 638 if (ret < 0)
604 if (!bysource) {
605 ret = -ENOMEM;
606 goto cleanup_extend; 639 goto cleanup_extend;
607 }
608 640
609 /* Sew in builtin protocols. */ 641 /* Sew in builtin protocols. */
610 spin_lock_bh(&nf_nat_lock); 642 spin_lock_bh(&nf_nat_lock);
@@ -629,23 +661,9 @@ static int __init nf_nat_init(void)
629 return ret; 661 return ret;
630} 662}
631 663
632/* Clear NAT section of all conntracks, in case we're loaded again. */
633static int clean_nat(struct nf_conn *i, void *data)
634{
635 struct nf_conn_nat *nat = nfct_nat(i);
636
637 if (!nat)
638 return 0;
639 memset(nat, 0, sizeof(*nat));
640 i->status &= ~(IPS_NAT_MASK | IPS_NAT_DONE_MASK | IPS_SEQ_ADJUST);
641 return 0;
642}
643
644static void __exit nf_nat_cleanup(void) 664static void __exit nf_nat_cleanup(void)
645{ 665{
646 nf_ct_iterate_cleanup(&clean_nat, NULL); 666 unregister_pernet_subsys(&nf_nat_net_ops);
647 synchronize_rcu();
648 nf_ct_free_hashtable(bysource, nf_nat_vmalloced, nf_nat_htable_size);
649 nf_ct_l3proto_put(l3proto); 667 nf_ct_l3proto_put(l3proto);
650 nf_ct_extend_unregister(&nat_extend); 668 nf_ct_extend_unregister(&nat_extend);
651 rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL); 669 rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL);
diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c
index 11976ea29884..cf7a42bf9820 100644
--- a/net/ipv4/netfilter/nf_nat_helper.c
+++ b/net/ipv4/netfilter/nf_nat_helper.c
@@ -16,6 +16,7 @@
16#include <linux/udp.h> 16#include <linux/udp.h>
17#include <net/checksum.h> 17#include <net/checksum.h>
18#include <net/tcp.h> 18#include <net/tcp.h>
19#include <net/route.h>
19 20
20#include <linux/netfilter_ipv4.h> 21#include <linux/netfilter_ipv4.h>
21#include <net/netfilter/nf_conntrack.h> 22#include <net/netfilter/nf_conntrack.h>
@@ -192,7 +193,7 @@ nf_nat_mangle_tcp_packet(struct sk_buff *skb,
192 nf_conntrack_tcp_update(skb, ip_hdrlen(skb), 193 nf_conntrack_tcp_update(skb, ip_hdrlen(skb),
193 ct, CTINFO2DIR(ctinfo)); 194 ct, CTINFO2DIR(ctinfo));
194 195
195 nf_conntrack_event_cache(IPCT_NATSEQADJ, skb); 196 nf_conntrack_event_cache(IPCT_NATSEQADJ, ct);
196 } 197 }
197 return 1; 198 return 1;
198} 199}
diff --git a/net/ipv4/netfilter/nf_nat_pptp.c b/net/ipv4/netfilter/nf_nat_pptp.c
index da3d91a5ef5c..9eb171056c63 100644
--- a/net/ipv4/netfilter/nf_nat_pptp.c
+++ b/net/ipv4/netfilter/nf_nat_pptp.c
@@ -40,6 +40,7 @@ MODULE_ALIAS("ip_nat_pptp");
40static void pptp_nat_expected(struct nf_conn *ct, 40static void pptp_nat_expected(struct nf_conn *ct,
41 struct nf_conntrack_expect *exp) 41 struct nf_conntrack_expect *exp)
42{ 42{
43 struct net *net = nf_ct_net(ct);
43 const struct nf_conn *master = ct->master; 44 const struct nf_conn *master = ct->master;
44 struct nf_conntrack_expect *other_exp; 45 struct nf_conntrack_expect *other_exp;
45 struct nf_conntrack_tuple t; 46 struct nf_conntrack_tuple t;
@@ -73,7 +74,7 @@ static void pptp_nat_expected(struct nf_conn *ct,
73 74
74 pr_debug("trying to unexpect other dir: "); 75 pr_debug("trying to unexpect other dir: ");
75 nf_ct_dump_tuple_ip(&t); 76 nf_ct_dump_tuple_ip(&t);
76 other_exp = nf_ct_expect_find_get(&t); 77 other_exp = nf_ct_expect_find_get(net, &t);
77 if (other_exp) { 78 if (other_exp) {
78 nf_ct_unexpect_related(other_exp); 79 nf_ct_unexpect_related(other_exp);
79 nf_ct_expect_put(other_exp); 80 nf_ct_expect_put(other_exp);
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c
index e8b4d0d4439e..bea54a685109 100644
--- a/net/ipv4/netfilter/nf_nat_rule.c
+++ b/net/ipv4/netfilter/nf_nat_rule.c
@@ -33,7 +33,7 @@ static struct
33 struct ipt_replace repl; 33 struct ipt_replace repl;
34 struct ipt_standard entries[3]; 34 struct ipt_standard entries[3];
35 struct ipt_error term; 35 struct ipt_error term;
36} nat_initial_table __initdata = { 36} nat_initial_table __net_initdata = {
37 .repl = { 37 .repl = {
38 .name = "nat", 38 .name = "nat",
39 .valid_hooks = NAT_VALID_HOOKS, 39 .valid_hooks = NAT_VALID_HOOKS,
@@ -58,47 +58,42 @@ static struct
58 .term = IPT_ERROR_INIT, /* ERROR */ 58 .term = IPT_ERROR_INIT, /* ERROR */
59}; 59};
60 60
61static struct xt_table __nat_table = { 61static struct xt_table nat_table = {
62 .name = "nat", 62 .name = "nat",
63 .valid_hooks = NAT_VALID_HOOKS, 63 .valid_hooks = NAT_VALID_HOOKS,
64 .lock = __RW_LOCK_UNLOCKED(__nat_table.lock), 64 .lock = __RW_LOCK_UNLOCKED(__nat_table.lock),
65 .me = THIS_MODULE, 65 .me = THIS_MODULE,
66 .af = AF_INET, 66 .af = AF_INET,
67}; 67};
68static struct xt_table *nat_table;
69 68
70/* Source NAT */ 69/* Source NAT */
71static unsigned int ipt_snat_target(struct sk_buff *skb, 70static unsigned int
72 const struct net_device *in, 71ipt_snat_target(struct sk_buff *skb, const struct xt_target_param *par)
73 const struct net_device *out,
74 unsigned int hooknum,
75 const struct xt_target *target,
76 const void *targinfo)
77{ 72{
78 struct nf_conn *ct; 73 struct nf_conn *ct;
79 enum ip_conntrack_info ctinfo; 74 enum ip_conntrack_info ctinfo;
80 const struct nf_nat_multi_range_compat *mr = targinfo; 75 const struct nf_nat_multi_range_compat *mr = par->targinfo;
81 76
82 NF_CT_ASSERT(hooknum == NF_INET_POST_ROUTING); 77 NF_CT_ASSERT(par->hooknum == NF_INET_POST_ROUTING);
83 78
84 ct = nf_ct_get(skb, &ctinfo); 79 ct = nf_ct_get(skb, &ctinfo);
85 80
86 /* Connection must be valid and new. */ 81 /* Connection must be valid and new. */
87 NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED || 82 NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
88 ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)); 83 ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY));
89 NF_CT_ASSERT(out); 84 NF_CT_ASSERT(par->out != NULL);
90 85
91 return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_SRC); 86 return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_SRC);
92} 87}
93 88
94/* Before 2.6.11 we did implicit source NAT if required. Warn about change. */ 89/* Before 2.6.11 we did implicit source NAT if required. Warn about change. */
95static void warn_if_extra_mangle(__be32 dstip, __be32 srcip) 90static void warn_if_extra_mangle(struct net *net, __be32 dstip, __be32 srcip)
96{ 91{
97 static int warned = 0; 92 static int warned = 0;
98 struct flowi fl = { .nl_u = { .ip4_u = { .daddr = dstip } } }; 93 struct flowi fl = { .nl_u = { .ip4_u = { .daddr = dstip } } };
99 struct rtable *rt; 94 struct rtable *rt;
100 95
101 if (ip_route_output_key(&init_net, &rt, &fl) != 0) 96 if (ip_route_output_key(net, &rt, &fl) != 0)
102 return; 97 return;
103 98
104 if (rt->rt_src != srcip && !warned) { 99 if (rt->rt_src != srcip && !warned) {
@@ -110,40 +105,32 @@ static void warn_if_extra_mangle(__be32 dstip, __be32 srcip)
110 ip_rt_put(rt); 105 ip_rt_put(rt);
111} 106}
112 107
113static unsigned int ipt_dnat_target(struct sk_buff *skb, 108static unsigned int
114 const struct net_device *in, 109ipt_dnat_target(struct sk_buff *skb, const struct xt_target_param *par)
115 const struct net_device *out,
116 unsigned int hooknum,
117 const struct xt_target *target,
118 const void *targinfo)
119{ 110{
120 struct nf_conn *ct; 111 struct nf_conn *ct;
121 enum ip_conntrack_info ctinfo; 112 enum ip_conntrack_info ctinfo;
122 const struct nf_nat_multi_range_compat *mr = targinfo; 113 const struct nf_nat_multi_range_compat *mr = par->targinfo;
123 114
124 NF_CT_ASSERT(hooknum == NF_INET_PRE_ROUTING || 115 NF_CT_ASSERT(par->hooknum == NF_INET_PRE_ROUTING ||
125 hooknum == NF_INET_LOCAL_OUT); 116 par->hooknum == NF_INET_LOCAL_OUT);
126 117
127 ct = nf_ct_get(skb, &ctinfo); 118 ct = nf_ct_get(skb, &ctinfo);
128 119
129 /* Connection must be valid and new. */ 120 /* Connection must be valid and new. */
130 NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED)); 121 NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
131 122
132 if (hooknum == NF_INET_LOCAL_OUT && 123 if (par->hooknum == NF_INET_LOCAL_OUT &&
133 mr->range[0].flags & IP_NAT_RANGE_MAP_IPS) 124 mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)
134 warn_if_extra_mangle(ip_hdr(skb)->daddr, 125 warn_if_extra_mangle(dev_net(par->out), ip_hdr(skb)->daddr,
135 mr->range[0].min_ip); 126 mr->range[0].min_ip);
136 127
137 return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_DST); 128 return nf_nat_setup_info(ct, &mr->range[0], IP_NAT_MANIP_DST);
138} 129}
139 130
140static bool ipt_snat_checkentry(const char *tablename, 131static bool ipt_snat_checkentry(const struct xt_tgchk_param *par)
141 const void *entry,
142 const struct xt_target *target,
143 void *targinfo,
144 unsigned int hook_mask)
145{ 132{
146 const struct nf_nat_multi_range_compat *mr = targinfo; 133 const struct nf_nat_multi_range_compat *mr = par->targinfo;
147 134
148 /* Must be a valid range */ 135 /* Must be a valid range */
149 if (mr->rangesize != 1) { 136 if (mr->rangesize != 1) {
@@ -153,13 +140,9 @@ static bool ipt_snat_checkentry(const char *tablename,
153 return true; 140 return true;
154} 141}
155 142
156static bool ipt_dnat_checkentry(const char *tablename, 143static bool ipt_dnat_checkentry(const struct xt_tgchk_param *par)
157 const void *entry,
158 const struct xt_target *target,
159 void *targinfo,
160 unsigned int hook_mask)
161{ 144{
162 const struct nf_nat_multi_range_compat *mr = targinfo; 145 const struct nf_nat_multi_range_compat *mr = par->targinfo;
163 146
164 /* Must be a valid range */ 147 /* Must be a valid range */
165 if (mr->rangesize != 1) { 148 if (mr->rangesize != 1) {
@@ -194,9 +177,10 @@ int nf_nat_rule_find(struct sk_buff *skb,
194 const struct net_device *out, 177 const struct net_device *out,
195 struct nf_conn *ct) 178 struct nf_conn *ct)
196{ 179{
180 struct net *net = nf_ct_net(ct);
197 int ret; 181 int ret;
198 182
199 ret = ipt_do_table(skb, hooknum, in, out, nat_table); 183 ret = ipt_do_table(skb, hooknum, in, out, net->ipv4.nat_table);
200 184
201 if (ret == NF_ACCEPT) { 185 if (ret == NF_ACCEPT) {
202 if (!nf_nat_initialized(ct, HOOK2MANIP(hooknum))) 186 if (!nf_nat_initialized(ct, HOOK2MANIP(hooknum)))
@@ -226,14 +210,32 @@ static struct xt_target ipt_dnat_reg __read_mostly = {
226 .family = AF_INET, 210 .family = AF_INET,
227}; 211};
228 212
213static int __net_init nf_nat_rule_net_init(struct net *net)
214{
215 net->ipv4.nat_table = ipt_register_table(net, &nat_table,
216 &nat_initial_table.repl);
217 if (IS_ERR(net->ipv4.nat_table))
218 return PTR_ERR(net->ipv4.nat_table);
219 return 0;
220}
221
222static void __net_exit nf_nat_rule_net_exit(struct net *net)
223{
224 ipt_unregister_table(net->ipv4.nat_table);
225}
226
227static struct pernet_operations nf_nat_rule_net_ops = {
228 .init = nf_nat_rule_net_init,
229 .exit = nf_nat_rule_net_exit,
230};
231
229int __init nf_nat_rule_init(void) 232int __init nf_nat_rule_init(void)
230{ 233{
231 int ret; 234 int ret;
232 235
233 nat_table = ipt_register_table(&init_net, &__nat_table, 236 ret = register_pernet_subsys(&nf_nat_rule_net_ops);
234 &nat_initial_table.repl); 237 if (ret != 0)
235 if (IS_ERR(nat_table)) 238 goto out;
236 return PTR_ERR(nat_table);
237 ret = xt_register_target(&ipt_snat_reg); 239 ret = xt_register_target(&ipt_snat_reg);
238 if (ret != 0) 240 if (ret != 0)
239 goto unregister_table; 241 goto unregister_table;
@@ -247,8 +249,8 @@ int __init nf_nat_rule_init(void)
247 unregister_snat: 249 unregister_snat:
248 xt_unregister_target(&ipt_snat_reg); 250 xt_unregister_target(&ipt_snat_reg);
249 unregister_table: 251 unregister_table:
250 ipt_unregister_table(nat_table); 252 unregister_pernet_subsys(&nf_nat_rule_net_ops);
251 253 out:
252 return ret; 254 return ret;
253} 255}
254 256
@@ -256,5 +258,5 @@ void nf_nat_rule_cleanup(void)
256{ 258{
257 xt_unregister_target(&ipt_dnat_reg); 259 xt_unregister_target(&ipt_dnat_reg);
258 xt_unregister_target(&ipt_snat_reg); 260 xt_unregister_target(&ipt_snat_reg);
259 ipt_unregister_table(nat_table); 261 unregister_pernet_subsys(&nf_nat_rule_net_ops);
260} 262}
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 6ee5354c9aa1..a6d7c584f53b 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -282,6 +282,8 @@ static struct rtable *rt_cache_get_first(struct seq_file *seq)
282 struct rtable *r = NULL; 282 struct rtable *r = NULL;
283 283
284 for (st->bucket = rt_hash_mask; st->bucket >= 0; --st->bucket) { 284 for (st->bucket = rt_hash_mask; st->bucket >= 0; --st->bucket) {
285 if (!rt_hash_table[st->bucket].chain)
286 continue;
285 rcu_read_lock_bh(); 287 rcu_read_lock_bh();
286 r = rcu_dereference(rt_hash_table[st->bucket].chain); 288 r = rcu_dereference(rt_hash_table[st->bucket].chain);
287 while (r) { 289 while (r) {
@@ -299,11 +301,14 @@ static struct rtable *__rt_cache_get_next(struct seq_file *seq,
299 struct rtable *r) 301 struct rtable *r)
300{ 302{
301 struct rt_cache_iter_state *st = seq->private; 303 struct rt_cache_iter_state *st = seq->private;
304
302 r = r->u.dst.rt_next; 305 r = r->u.dst.rt_next;
303 while (!r) { 306 while (!r) {
304 rcu_read_unlock_bh(); 307 rcu_read_unlock_bh();
305 if (--st->bucket < 0) 308 do {
306 break; 309 if (--st->bucket < 0)
310 return NULL;
311 } while (!rt_hash_table[st->bucket].chain);
307 rcu_read_lock_bh(); 312 rcu_read_lock_bh();
308 r = rt_hash_table[st->bucket].chain; 313 r = rt_hash_table[st->bucket].chain;
309 } 314 }
@@ -2356,11 +2361,6 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
2356 ipv4_is_zeronet(oldflp->fl4_src)) 2361 ipv4_is_zeronet(oldflp->fl4_src))
2357 goto out; 2362 goto out;
2358 2363
2359 /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
2360 dev_out = ip_dev_find(net, oldflp->fl4_src);
2361 if (dev_out == NULL)
2362 goto out;
2363
2364 /* I removed check for oif == dev_out->oif here. 2364 /* I removed check for oif == dev_out->oif here.
2365 It was wrong for two reasons: 2365 It was wrong for two reasons:
2366 1. ip_dev_find(net, saddr) can return wrong iface, if saddr 2366 1. ip_dev_find(net, saddr) can return wrong iface, if saddr
@@ -2372,6 +2372,11 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
2372 if (oldflp->oif == 0 2372 if (oldflp->oif == 0
2373 && (ipv4_is_multicast(oldflp->fl4_dst) || 2373 && (ipv4_is_multicast(oldflp->fl4_dst) ||
2374 oldflp->fl4_dst == htonl(0xFFFFFFFF))) { 2374 oldflp->fl4_dst == htonl(0xFFFFFFFF))) {
2375 /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
2376 dev_out = ip_dev_find(net, oldflp->fl4_src);
2377 if (dev_out == NULL)
2378 goto out;
2379
2375 /* Special hack: user can direct multicasts 2380 /* Special hack: user can direct multicasts
2376 and limited broadcast via necessary interface 2381 and limited broadcast via necessary interface
2377 without fiddling with IP_MULTICAST_IF or IP_PKTINFO. 2382 without fiddling with IP_MULTICAST_IF or IP_PKTINFO.
@@ -2390,9 +2395,15 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp,
2390 fl.oif = dev_out->ifindex; 2395 fl.oif = dev_out->ifindex;
2391 goto make_route; 2396 goto make_route;
2392 } 2397 }
2393 if (dev_out) 2398
2399 if (!(oldflp->flags & FLOWI_FLAG_ANYSRC)) {
2400 /* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
2401 dev_out = ip_dev_find(net, oldflp->fl4_src);
2402 if (dev_out == NULL)
2403 goto out;
2394 dev_put(dev_out); 2404 dev_put(dev_out);
2395 dev_out = NULL; 2405 dev_out = NULL;
2406 }
2396 } 2407 }
2397 2408
2398 2409
@@ -2840,7 +2851,9 @@ int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb)
2840 if (s_h < 0) 2851 if (s_h < 0)
2841 s_h = 0; 2852 s_h = 0;
2842 s_idx = idx = cb->args[1]; 2853 s_idx = idx = cb->args[1];
2843 for (h = s_h; h <= rt_hash_mask; h++) { 2854 for (h = s_h; h <= rt_hash_mask; h++, s_idx = 0) {
2855 if (!rt_hash_table[h].chain)
2856 continue;
2844 rcu_read_lock_bh(); 2857 rcu_read_lock_bh();
2845 for (rt = rcu_dereference(rt_hash_table[h].chain), idx = 0; rt; 2858 for (rt = rcu_dereference(rt_hash_table[h].chain), idx = 0; rt;
2846 rt = rcu_dereference(rt->u.dst.rt_next), idx++) { 2859 rt = rcu_dereference(rt->u.dst.rt_next), idx++) {
@@ -2859,7 +2872,6 @@ int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb)
2859 dst_release(xchg(&skb->dst, NULL)); 2872 dst_release(xchg(&skb->dst, NULL));
2860 } 2873 }
2861 rcu_read_unlock_bh(); 2874 rcu_read_unlock_bh();
2862 s_idx = 0;
2863 } 2875 }
2864 2876
2865done: 2877done:
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index 9d38005abbac..d346c22aa6ae 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -16,6 +16,7 @@
16#include <linux/cryptohash.h> 16#include <linux/cryptohash.h>
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <net/tcp.h> 18#include <net/tcp.h>
19#include <net/route.h>
19 20
20/* Timestamps: lowest 9 bits store TCP options */ 21/* Timestamps: lowest 9 bits store TCP options */
21#define TSBITS 9 22#define TSBITS 9
@@ -296,6 +297,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
296 treq->rcv_isn = ntohl(th->seq) - 1; 297 treq->rcv_isn = ntohl(th->seq) - 1;
297 treq->snt_isn = cookie; 298 treq->snt_isn = cookie;
298 req->mss = mss; 299 req->mss = mss;
300 ireq->loc_port = th->dest;
299 ireq->rmt_port = th->source; 301 ireq->rmt_port = th->source;
300 ireq->loc_addr = ip_hdr(skb)->daddr; 302 ireq->loc_addr = ip_hdr(skb)->daddr;
301 ireq->rmt_addr = ip_hdr(skb)->saddr; 303 ireq->rmt_addr = ip_hdr(skb)->saddr;
@@ -337,6 +339,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
337 .saddr = ireq->loc_addr, 339 .saddr = ireq->loc_addr,
338 .tos = RT_CONN_FLAGS(sk) } }, 340 .tos = RT_CONN_FLAGS(sk) } },
339 .proto = IPPROTO_TCP, 341 .proto = IPPROTO_TCP,
342 .flags = inet_sk_flowi_flags(sk),
340 .uli_u = { .ports = 343 .uli_u = { .ports =
341 { .sport = th->dest, 344 { .sport = th->dest,
342 .dport = th->source } } }; 345 .dport = th->source } } };
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index e0689fd7b798..276d047fb85a 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -26,16 +26,13 @@ static int tcp_retr1_max = 255;
26static int ip_local_port_range_min[] = { 1, 1 }; 26static int ip_local_port_range_min[] = { 1, 1 };
27static int ip_local_port_range_max[] = { 65535, 65535 }; 27static int ip_local_port_range_max[] = { 65535, 65535 };
28 28
29extern seqlock_t sysctl_port_range_lock;
30extern int sysctl_local_port_range[2];
31
32/* Update system visible IP port range */ 29/* Update system visible IP port range */
33static void set_local_port_range(int range[2]) 30static void set_local_port_range(int range[2])
34{ 31{
35 write_seqlock(&sysctl_port_range_lock); 32 write_seqlock(&sysctl_local_ports.lock);
36 sysctl_local_port_range[0] = range[0]; 33 sysctl_local_ports.range[0] = range[0];
37 sysctl_local_port_range[1] = range[1]; 34 sysctl_local_ports.range[1] = range[1];
38 write_sequnlock(&sysctl_port_range_lock); 35 write_sequnlock(&sysctl_local_ports.lock);
39} 36}
40 37
41/* Validate changes from /proc interface. */ 38/* Validate changes from /proc interface. */
@@ -44,8 +41,7 @@ static int ipv4_local_port_range(ctl_table *table, int write, struct file *filp,
44 size_t *lenp, loff_t *ppos) 41 size_t *lenp, loff_t *ppos)
45{ 42{
46 int ret; 43 int ret;
47 int range[2] = { sysctl_local_port_range[0], 44 int range[2];
48 sysctl_local_port_range[1] };
49 ctl_table tmp = { 45 ctl_table tmp = {
50 .data = &range, 46 .data = &range,
51 .maxlen = sizeof(range), 47 .maxlen = sizeof(range),
@@ -54,6 +50,7 @@ static int ipv4_local_port_range(ctl_table *table, int write, struct file *filp,
54 .extra2 = &ip_local_port_range_max, 50 .extra2 = &ip_local_port_range_max,
55 }; 51 };
56 52
53 inet_get_local_port_range(range, range + 1);
57 ret = proc_dointvec_minmax(&tmp, write, filp, buffer, lenp, ppos); 54 ret = proc_dointvec_minmax(&tmp, write, filp, buffer, lenp, ppos);
58 55
59 if (write && ret == 0) { 56 if (write && ret == 0) {
@@ -73,8 +70,7 @@ static int ipv4_sysctl_local_port_range(ctl_table *table, int __user *name,
73 void __user *newval, size_t newlen) 70 void __user *newval, size_t newlen)
74{ 71{
75 int ret; 72 int ret;
76 int range[2] = { sysctl_local_port_range[0], 73 int range[2];
77 sysctl_local_port_range[1] };
78 ctl_table tmp = { 74 ctl_table tmp = {
79 .data = &range, 75 .data = &range,
80 .maxlen = sizeof(range), 76 .maxlen = sizeof(range),
@@ -83,6 +79,7 @@ static int ipv4_sysctl_local_port_range(ctl_table *table, int __user *name,
83 .extra2 = &ip_local_port_range_max, 79 .extra2 = &ip_local_port_range_max,
84 }; 80 };
85 81
82 inet_get_local_port_range(range, range + 1);
86 ret = sysctl_intvec(&tmp, name, nlen, oldval, oldlenp, newval, newlen); 83 ret = sysctl_intvec(&tmp, name, nlen, oldval, oldlenp, newval, newlen);
87 if (ret == 0 && newval && newlen) { 84 if (ret == 0 && newval && newlen) {
88 if (range[1] < range[0]) 85 if (range[1] < range[0])
@@ -396,8 +393,8 @@ static struct ctl_table ipv4_table[] = {
396 { 393 {
397 .ctl_name = NET_IPV4_LOCAL_PORT_RANGE, 394 .ctl_name = NET_IPV4_LOCAL_PORT_RANGE,
398 .procname = "ip_local_port_range", 395 .procname = "ip_local_port_range",
399 .data = &sysctl_local_port_range, 396 .data = &sysctl_local_ports.range,
400 .maxlen = sizeof(sysctl_local_port_range), 397 .maxlen = sizeof(sysctl_local_ports.range),
401 .mode = 0644, 398 .mode = 0644,
402 .proc_handler = &ipv4_local_port_range, 399 .proc_handler = &ipv4_local_port_range,
403 .strategy = &ipv4_sysctl_local_port_range, 400 .strategy = &ipv4_sysctl_local_port_range,
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 1ab341e5d3e0..eccb7165a80c 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -384,13 +384,17 @@ unsigned int tcp_poll(struct file *file, struct socket *sock, poll_table *wait)
384 384
385 /* Connected? */ 385 /* Connected? */
386 if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV)) { 386 if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV)) {
387 int target = sock_rcvlowat(sk, 0, INT_MAX);
388
389 if (tp->urg_seq == tp->copied_seq &&
390 !sock_flag(sk, SOCK_URGINLINE) &&
391 tp->urg_data)
392 target--;
393
387 /* Potential race condition. If read of tp below will 394 /* Potential race condition. If read of tp below will
388 * escape above sk->sk_state, we can be illegally awaken 395 * escape above sk->sk_state, we can be illegally awaken
389 * in SYN_* states. */ 396 * in SYN_* states. */
390 if ((tp->rcv_nxt != tp->copied_seq) && 397 if (tp->rcv_nxt - tp->copied_seq >= target)
391 (tp->urg_seq != tp->copied_seq ||
392 tp->rcv_nxt != tp->copied_seq + 1 ||
393 sock_flag(sk, SOCK_URGINLINE) || !tp->urg_data))
394 mask |= POLLIN | POLLRDNORM; 398 mask |= POLLIN | POLLRDNORM;
395 399
396 if (!(sk->sk_shutdown & SEND_SHUTDOWN)) { 400 if (!(sk->sk_shutdown & SEND_SHUTDOWN)) {
@@ -493,10 +497,8 @@ static inline void skb_entail(struct sock *sk, struct sk_buff *skb)
493static inline void tcp_mark_urg(struct tcp_sock *tp, int flags, 497static inline void tcp_mark_urg(struct tcp_sock *tp, int flags,
494 struct sk_buff *skb) 498 struct sk_buff *skb)
495{ 499{
496 if (flags & MSG_OOB) { 500 if (flags & MSG_OOB)
497 tp->urg_mode = 1;
498 tp->snd_up = tp->write_seq; 501 tp->snd_up = tp->write_seq;
499 }
500} 502}
501 503
502static inline void tcp_push(struct sock *sk, int flags, int mss_now, 504static inline void tcp_push(struct sock *sk, int flags, int mss_now,
@@ -1157,7 +1159,7 @@ static void tcp_prequeue_process(struct sock *sk)
1157 * necessary */ 1159 * necessary */
1158 local_bh_disable(); 1160 local_bh_disable();
1159 while ((skb = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) 1161 while ((skb = __skb_dequeue(&tp->ucopy.prequeue)) != NULL)
1160 sk->sk_backlog_rcv(sk, skb); 1162 sk_backlog_rcv(sk, skb);
1161 local_bh_enable(); 1163 local_bh_enable();
1162 1164
1163 /* Clear memory counter. */ 1165 /* Clear memory counter. */
diff --git a/net/ipv4/tcp_hybla.c b/net/ipv4/tcp_hybla.c
index bfcbd148a89d..c209e054a634 100644
--- a/net/ipv4/tcp_hybla.c
+++ b/net/ipv4/tcp_hybla.c
@@ -150,7 +150,11 @@ static void hybla_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
150 ca->snd_cwnd_cents -= 128; 150 ca->snd_cwnd_cents -= 128;
151 tp->snd_cwnd_cnt = 0; 151 tp->snd_cwnd_cnt = 0;
152 } 152 }
153 153 /* check when cwnd has not been incremented for a while */
154 if (increment == 0 && odd == 0 && tp->snd_cwnd_cnt >= tp->snd_cwnd) {
155 tp->snd_cwnd++;
156 tp->snd_cwnd_cnt = 0;
157 }
154 /* clamp down slowstart cwnd to ssthresh value. */ 158 /* clamp down slowstart cwnd to ssthresh value. */
155 if (is_slowstart) 159 if (is_slowstart)
156 tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh); 160 tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh);
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 67ccce2a96bd..d77c0d29e239 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -979,6 +979,39 @@ static void tcp_update_reordering(struct sock *sk, const int metric,
979 } 979 }
980} 980}
981 981
982/* This must be called before lost_out is incremented */
983static void tcp_verify_retransmit_hint(struct tcp_sock *tp, struct sk_buff *skb)
984{
985 if ((tp->retransmit_skb_hint == NULL) ||
986 before(TCP_SKB_CB(skb)->seq,
987 TCP_SKB_CB(tp->retransmit_skb_hint)->seq))
988 tp->retransmit_skb_hint = skb;
989
990 if (!tp->lost_out ||
991 after(TCP_SKB_CB(skb)->end_seq, tp->retransmit_high))
992 tp->retransmit_high = TCP_SKB_CB(skb)->end_seq;
993}
994
995static void tcp_skb_mark_lost(struct tcp_sock *tp, struct sk_buff *skb)
996{
997 if (!(TCP_SKB_CB(skb)->sacked & (TCPCB_LOST|TCPCB_SACKED_ACKED))) {
998 tcp_verify_retransmit_hint(tp, skb);
999
1000 tp->lost_out += tcp_skb_pcount(skb);
1001 TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
1002 }
1003}
1004
1005void tcp_skb_mark_lost_uncond_verify(struct tcp_sock *tp, struct sk_buff *skb)
1006{
1007 tcp_verify_retransmit_hint(tp, skb);
1008
1009 if (!(TCP_SKB_CB(skb)->sacked & (TCPCB_LOST|TCPCB_SACKED_ACKED))) {
1010 tp->lost_out += tcp_skb_pcount(skb);
1011 TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
1012 }
1013}
1014
982/* This procedure tags the retransmission queue when SACKs arrive. 1015/* This procedure tags the retransmission queue when SACKs arrive.
983 * 1016 *
984 * We have three tag bits: SACKED(S), RETRANS(R) and LOST(L). 1017 * We have three tag bits: SACKED(S), RETRANS(R) and LOST(L).
@@ -1155,13 +1188,7 @@ static void tcp_mark_lost_retrans(struct sock *sk)
1155 TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS; 1188 TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS;
1156 tp->retrans_out -= tcp_skb_pcount(skb); 1189 tp->retrans_out -= tcp_skb_pcount(skb);
1157 1190
1158 /* clear lost hint */ 1191 tcp_skb_mark_lost_uncond_verify(tp, skb);
1159 tp->retransmit_skb_hint = NULL;
1160
1161 if (!(TCP_SKB_CB(skb)->sacked & (TCPCB_LOST|TCPCB_SACKED_ACKED))) {
1162 tp->lost_out += tcp_skb_pcount(skb);
1163 TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
1164 }
1165 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPLOSTRETRANSMIT); 1192 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPLOSTRETRANSMIT);
1166 } else { 1193 } else {
1167 if (before(ack_seq, new_low_seq)) 1194 if (before(ack_seq, new_low_seq))
@@ -1271,9 +1298,6 @@ static int tcp_sacktag_one(struct sk_buff *skb, struct sock *sk,
1271 ~(TCPCB_LOST|TCPCB_SACKED_RETRANS); 1298 ~(TCPCB_LOST|TCPCB_SACKED_RETRANS);
1272 tp->lost_out -= tcp_skb_pcount(skb); 1299 tp->lost_out -= tcp_skb_pcount(skb);
1273 tp->retrans_out -= tcp_skb_pcount(skb); 1300 tp->retrans_out -= tcp_skb_pcount(skb);
1274
1275 /* clear lost hint */
1276 tp->retransmit_skb_hint = NULL;
1277 } 1301 }
1278 } else { 1302 } else {
1279 if (!(sacked & TCPCB_RETRANS)) { 1303 if (!(sacked & TCPCB_RETRANS)) {
@@ -1292,9 +1316,6 @@ static int tcp_sacktag_one(struct sk_buff *skb, struct sock *sk,
1292 if (sacked & TCPCB_LOST) { 1316 if (sacked & TCPCB_LOST) {
1293 TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST; 1317 TCP_SKB_CB(skb)->sacked &= ~TCPCB_LOST;
1294 tp->lost_out -= tcp_skb_pcount(skb); 1318 tp->lost_out -= tcp_skb_pcount(skb);
1295
1296 /* clear lost hint */
1297 tp->retransmit_skb_hint = NULL;
1298 } 1319 }
1299 } 1320 }
1300 1321
@@ -1324,7 +1345,6 @@ static int tcp_sacktag_one(struct sk_buff *skb, struct sock *sk,
1324 if (dup_sack && (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS)) { 1345 if (dup_sack && (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS)) {
1325 TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS; 1346 TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS;
1326 tp->retrans_out -= tcp_skb_pcount(skb); 1347 tp->retrans_out -= tcp_skb_pcount(skb);
1327 tp->retransmit_skb_hint = NULL;
1328 } 1348 }
1329 1349
1330 return flag; 1350 return flag;
@@ -1726,6 +1746,8 @@ int tcp_use_frto(struct sock *sk)
1726 return 0; 1746 return 0;
1727 1747
1728 skb = tcp_write_queue_head(sk); 1748 skb = tcp_write_queue_head(sk);
1749 if (tcp_skb_is_last(sk, skb))
1750 return 1;
1729 skb = tcp_write_queue_next(sk, skb); /* Skips head */ 1751 skb = tcp_write_queue_next(sk, skb); /* Skips head */
1730 tcp_for_write_queue_from(skb, sk) { 1752 tcp_for_write_queue_from(skb, sk) {
1731 if (skb == tcp_send_head(sk)) 1753 if (skb == tcp_send_head(sk))
@@ -1867,6 +1889,7 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag)
1867 if (!(TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED)) { 1889 if (!(TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED)) {
1868 TCP_SKB_CB(skb)->sacked |= TCPCB_LOST; 1890 TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
1869 tp->lost_out += tcp_skb_pcount(skb); 1891 tp->lost_out += tcp_skb_pcount(skb);
1892 tp->retransmit_high = TCP_SKB_CB(skb)->end_seq;
1870 } 1893 }
1871 } 1894 }
1872 tcp_verify_left_out(tp); 1895 tcp_verify_left_out(tp);
@@ -1883,7 +1906,7 @@ static void tcp_enter_frto_loss(struct sock *sk, int allowed_segments, int flag)
1883 tp->high_seq = tp->snd_nxt; 1906 tp->high_seq = tp->snd_nxt;
1884 TCP_ECN_queue_cwr(tp); 1907 TCP_ECN_queue_cwr(tp);
1885 1908
1886 tcp_clear_retrans_hints_partial(tp); 1909 tcp_clear_all_retrans_hints(tp);
1887} 1910}
1888 1911
1889static void tcp_clear_retrans_partial(struct tcp_sock *tp) 1912static void tcp_clear_retrans_partial(struct tcp_sock *tp)
@@ -1934,12 +1957,11 @@ void tcp_enter_loss(struct sock *sk, int how)
1934 /* Push undo marker, if it was plain RTO and nothing 1957 /* Push undo marker, if it was plain RTO and nothing
1935 * was retransmitted. */ 1958 * was retransmitted. */
1936 tp->undo_marker = tp->snd_una; 1959 tp->undo_marker = tp->snd_una;
1937 tcp_clear_retrans_hints_partial(tp);
1938 } else { 1960 } else {
1939 tp->sacked_out = 0; 1961 tp->sacked_out = 0;
1940 tp->fackets_out = 0; 1962 tp->fackets_out = 0;
1941 tcp_clear_all_retrans_hints(tp);
1942 } 1963 }
1964 tcp_clear_all_retrans_hints(tp);
1943 1965
1944 tcp_for_write_queue(skb, sk) { 1966 tcp_for_write_queue(skb, sk) {
1945 if (skb == tcp_send_head(sk)) 1967 if (skb == tcp_send_head(sk))
@@ -1952,6 +1974,7 @@ void tcp_enter_loss(struct sock *sk, int how)
1952 TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_ACKED; 1974 TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_ACKED;
1953 TCP_SKB_CB(skb)->sacked |= TCPCB_LOST; 1975 TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
1954 tp->lost_out += tcp_skb_pcount(skb); 1976 tp->lost_out += tcp_skb_pcount(skb);
1977 tp->retransmit_high = TCP_SKB_CB(skb)->end_seq;
1955 } 1978 }
1956 } 1979 }
1957 tcp_verify_left_out(tp); 1980 tcp_verify_left_out(tp);
@@ -2157,19 +2180,6 @@ static int tcp_time_to_recover(struct sock *sk)
2157 return 0; 2180 return 0;
2158} 2181}
2159 2182
2160/* RFC: This is from the original, I doubt that this is necessary at all:
2161 * clear xmit_retrans hint if seq of this skb is beyond hint. How could we
2162 * retransmitted past LOST markings in the first place? I'm not fully sure
2163 * about undo and end of connection cases, which can cause R without L?
2164 */
2165static void tcp_verify_retransmit_hint(struct tcp_sock *tp, struct sk_buff *skb)
2166{
2167 if ((tp->retransmit_skb_hint != NULL) &&
2168 before(TCP_SKB_CB(skb)->seq,
2169 TCP_SKB_CB(tp->retransmit_skb_hint)->seq))
2170 tp->retransmit_skb_hint = NULL;
2171}
2172
2173/* Mark head of queue up as lost. With RFC3517 SACK, the packets is 2183/* Mark head of queue up as lost. With RFC3517 SACK, the packets is
2174 * is against sacked "cnt", otherwise it's against facked "cnt" 2184 * is against sacked "cnt", otherwise it's against facked "cnt"
2175 */ 2185 */
@@ -2217,11 +2227,7 @@ static void tcp_mark_head_lost(struct sock *sk, int packets)
2217 cnt = packets; 2227 cnt = packets;
2218 } 2228 }
2219 2229
2220 if (!(TCP_SKB_CB(skb)->sacked & (TCPCB_SACKED_ACKED|TCPCB_LOST))) { 2230 tcp_skb_mark_lost(tp, skb);
2221 TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
2222 tp->lost_out += tcp_skb_pcount(skb);
2223 tcp_verify_retransmit_hint(tp, skb);
2224 }
2225 } 2231 }
2226 tcp_verify_left_out(tp); 2232 tcp_verify_left_out(tp);
2227} 2233}
@@ -2263,11 +2269,7 @@ static void tcp_update_scoreboard(struct sock *sk, int fast_rexmit)
2263 if (!tcp_skb_timedout(sk, skb)) 2269 if (!tcp_skb_timedout(sk, skb))
2264 break; 2270 break;
2265 2271
2266 if (!(TCP_SKB_CB(skb)->sacked & (TCPCB_SACKED_ACKED|TCPCB_LOST))) { 2272 tcp_skb_mark_lost(tp, skb);
2267 TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
2268 tp->lost_out += tcp_skb_pcount(skb);
2269 tcp_verify_retransmit_hint(tp, skb);
2270 }
2271 } 2273 }
2272 2274
2273 tp->scoreboard_skb_hint = skb; 2275 tp->scoreboard_skb_hint = skb;
@@ -2378,10 +2380,6 @@ static void tcp_undo_cwr(struct sock *sk, const int undo)
2378 } 2380 }
2379 tcp_moderate_cwnd(tp); 2381 tcp_moderate_cwnd(tp);
2380 tp->snd_cwnd_stamp = tcp_time_stamp; 2382 tp->snd_cwnd_stamp = tcp_time_stamp;
2381
2382 /* There is something screwy going on with the retrans hints after
2383 an undo */
2384 tcp_clear_all_retrans_hints(tp);
2385} 2383}
2386 2384
2387static inline int tcp_may_undo(struct tcp_sock *tp) 2385static inline int tcp_may_undo(struct tcp_sock *tp)
@@ -2838,7 +2836,8 @@ static u32 tcp_tso_acked(struct sock *sk, struct sk_buff *skb)
2838 * is before the ack sequence we can discard it as it's confirmed to have 2836 * is before the ack sequence we can discard it as it's confirmed to have
2839 * arrived at the other end. 2837 * arrived at the other end.
2840 */ 2838 */
2841static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets) 2839static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets,
2840 u32 prior_snd_una)
2842{ 2841{
2843 struct tcp_sock *tp = tcp_sk(sk); 2842 struct tcp_sock *tp = tcp_sk(sk);
2844 const struct inet_connection_sock *icsk = inet_csk(sk); 2843 const struct inet_connection_sock *icsk = inet_csk(sk);
@@ -2848,6 +2847,7 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets)
2848 int flag = 0; 2847 int flag = 0;
2849 u32 pkts_acked = 0; 2848 u32 pkts_acked = 0;
2850 u32 reord = tp->packets_out; 2849 u32 reord = tp->packets_out;
2850 u32 prior_sacked = tp->sacked_out;
2851 s32 seq_rtt = -1; 2851 s32 seq_rtt = -1;
2852 s32 ca_seq_rtt = -1; 2852 s32 ca_seq_rtt = -1;
2853 ktime_t last_ackt = net_invalid_timestamp(); 2853 ktime_t last_ackt = net_invalid_timestamp();
@@ -2904,9 +2904,6 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets)
2904 if (sacked & TCPCB_LOST) 2904 if (sacked & TCPCB_LOST)
2905 tp->lost_out -= acked_pcount; 2905 tp->lost_out -= acked_pcount;
2906 2906
2907 if (unlikely(tp->urg_mode && !before(end_seq, tp->snd_up)))
2908 tp->urg_mode = 0;
2909
2910 tp->packets_out -= acked_pcount; 2907 tp->packets_out -= acked_pcount;
2911 pkts_acked += acked_pcount; 2908 pkts_acked += acked_pcount;
2912 2909
@@ -2929,9 +2926,16 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets)
2929 2926
2930 tcp_unlink_write_queue(skb, sk); 2927 tcp_unlink_write_queue(skb, sk);
2931 sk_wmem_free_skb(sk, skb); 2928 sk_wmem_free_skb(sk, skb);
2932 tcp_clear_all_retrans_hints(tp); 2929 tp->scoreboard_skb_hint = NULL;
2930 if (skb == tp->retransmit_skb_hint)
2931 tp->retransmit_skb_hint = NULL;
2932 if (skb == tp->lost_skb_hint)
2933 tp->lost_skb_hint = NULL;
2933 } 2934 }
2934 2935
2936 if (likely(between(tp->snd_up, prior_snd_una, tp->snd_una)))
2937 tp->snd_up = tp->snd_una;
2938
2935 if (skb && (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED)) 2939 if (skb && (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED))
2936 flag |= FLAG_SACK_RENEGING; 2940 flag |= FLAG_SACK_RENEGING;
2937 2941
@@ -2948,6 +2952,15 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets)
2948 /* Non-retransmitted hole got filled? That's reordering */ 2952 /* Non-retransmitted hole got filled? That's reordering */
2949 if (reord < prior_fackets) 2953 if (reord < prior_fackets)
2950 tcp_update_reordering(sk, tp->fackets_out - reord, 0); 2954 tcp_update_reordering(sk, tp->fackets_out - reord, 0);
2955
2956 /* No need to care for underflows here because
2957 * the lost_skb_hint gets NULLed if we're past it
2958 * (or something non-trivial happened)
2959 */
2960 if (tcp_is_fack(tp))
2961 tp->lost_cnt_hint -= pkts_acked;
2962 else
2963 tp->lost_cnt_hint -= prior_sacked - tp->sacked_out;
2951 } 2964 }
2952 2965
2953 tp->fackets_out -= min(pkts_acked, tp->fackets_out); 2966 tp->fackets_out -= min(pkts_acked, tp->fackets_out);
@@ -3299,7 +3312,7 @@ static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
3299 goto no_queue; 3312 goto no_queue;
3300 3313
3301 /* See if we can take anything off of the retransmit queue. */ 3314 /* See if we can take anything off of the retransmit queue. */
3302 flag |= tcp_clean_rtx_queue(sk, prior_fackets); 3315 flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una);
3303 3316
3304 if (tp->frto_counter) 3317 if (tp->frto_counter)
3305 frto_cwnd = tcp_process_frto(sk, flag); 3318 frto_cwnd = tcp_process_frto(sk, flag);
@@ -3442,6 +3455,22 @@ void tcp_parse_options(struct sk_buff *skb, struct tcp_options_received *opt_rx,
3442 } 3455 }
3443} 3456}
3444 3457
3458static int tcp_parse_aligned_timestamp(struct tcp_sock *tp, struct tcphdr *th)
3459{
3460 __be32 *ptr = (__be32 *)(th + 1);
3461
3462 if (*ptr == htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16)
3463 | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) {
3464 tp->rx_opt.saw_tstamp = 1;
3465 ++ptr;
3466 tp->rx_opt.rcv_tsval = ntohl(*ptr);
3467 ++ptr;
3468 tp->rx_opt.rcv_tsecr = ntohl(*ptr);
3469 return 1;
3470 }
3471 return 0;
3472}
3473
3445/* Fast parse options. This hopes to only see timestamps. 3474/* Fast parse options. This hopes to only see timestamps.
3446 * If it is wrong it falls back on tcp_parse_options(). 3475 * If it is wrong it falls back on tcp_parse_options().
3447 */ 3476 */
@@ -3453,16 +3482,8 @@ static int tcp_fast_parse_options(struct sk_buff *skb, struct tcphdr *th,
3453 return 0; 3482 return 0;
3454 } else if (tp->rx_opt.tstamp_ok && 3483 } else if (tp->rx_opt.tstamp_ok &&
3455 th->doff == (sizeof(struct tcphdr)>>2)+(TCPOLEN_TSTAMP_ALIGNED>>2)) { 3484 th->doff == (sizeof(struct tcphdr)>>2)+(TCPOLEN_TSTAMP_ALIGNED>>2)) {
3456 __be32 *ptr = (__be32 *)(th + 1); 3485 if (tcp_parse_aligned_timestamp(tp, th))
3457 if (*ptr == htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16)
3458 | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) {
3459 tp->rx_opt.saw_tstamp = 1;
3460 ++ptr;
3461 tp->rx_opt.rcv_tsval = ntohl(*ptr);
3462 ++ptr;
3463 tp->rx_opt.rcv_tsecr = ntohl(*ptr);
3464 return 1; 3486 return 1;
3465 }
3466 } 3487 }
3467 tcp_parse_options(skb, &tp->rx_opt, 1); 3488 tcp_parse_options(skb, &tp->rx_opt, 1);
3468 return 1; 3489 return 1;
@@ -4138,7 +4159,7 @@ drop:
4138 skb1 = skb1->prev; 4159 skb1 = skb1->prev;
4139 } 4160 }
4140 } 4161 }
4141 __skb_insert(skb, skb1, skb1->next, &tp->out_of_order_queue); 4162 __skb_queue_after(&tp->out_of_order_queue, skb1, skb);
4142 4163
4143 /* And clean segments covered by new one as whole. */ 4164 /* And clean segments covered by new one as whole. */
4144 while ((skb1 = skb->next) != 4165 while ((skb1 = skb->next) !=
@@ -4161,6 +4182,18 @@ add_sack:
4161 } 4182 }
4162} 4183}
4163 4184
4185static struct sk_buff *tcp_collapse_one(struct sock *sk, struct sk_buff *skb,
4186 struct sk_buff_head *list)
4187{
4188 struct sk_buff *next = skb->next;
4189
4190 __skb_unlink(skb, list);
4191 __kfree_skb(skb);
4192 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPRCVCOLLAPSED);
4193
4194 return next;
4195}
4196
4164/* Collapse contiguous sequence of skbs head..tail with 4197/* Collapse contiguous sequence of skbs head..tail with
4165 * sequence numbers start..end. 4198 * sequence numbers start..end.
4166 * Segments with FIN/SYN are not collapsed (only because this 4199 * Segments with FIN/SYN are not collapsed (only because this
@@ -4178,11 +4211,7 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list,
4178 for (skb = head; skb != tail;) { 4211 for (skb = head; skb != tail;) {
4179 /* No new bits? It is possible on ofo queue. */ 4212 /* No new bits? It is possible on ofo queue. */
4180 if (!before(start, TCP_SKB_CB(skb)->end_seq)) { 4213 if (!before(start, TCP_SKB_CB(skb)->end_seq)) {
4181 struct sk_buff *next = skb->next; 4214 skb = tcp_collapse_one(sk, skb, list);
4182 __skb_unlink(skb, list);
4183 __kfree_skb(skb);
4184 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPRCVCOLLAPSED);
4185 skb = next;
4186 continue; 4215 continue;
4187 } 4216 }
4188 4217
@@ -4228,7 +4257,7 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list,
4228 memcpy(nskb->head, skb->head, header); 4257 memcpy(nskb->head, skb->head, header);
4229 memcpy(nskb->cb, skb->cb, sizeof(skb->cb)); 4258 memcpy(nskb->cb, skb->cb, sizeof(skb->cb));
4230 TCP_SKB_CB(nskb)->seq = TCP_SKB_CB(nskb)->end_seq = start; 4259 TCP_SKB_CB(nskb)->seq = TCP_SKB_CB(nskb)->end_seq = start;
4231 __skb_insert(nskb, skb->prev, skb, list); 4260 __skb_queue_before(list, skb, nskb);
4232 skb_set_owner_r(nskb, sk); 4261 skb_set_owner_r(nskb, sk);
4233 4262
4234 /* Copy data, releasing collapsed skbs. */ 4263 /* Copy data, releasing collapsed skbs. */
@@ -4246,11 +4275,7 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list,
4246 start += size; 4275 start += size;
4247 } 4276 }
4248 if (!before(start, TCP_SKB_CB(skb)->end_seq)) { 4277 if (!before(start, TCP_SKB_CB(skb)->end_seq)) {
4249 struct sk_buff *next = skb->next; 4278 skb = tcp_collapse_one(sk, skb, list);
4250 __skb_unlink(skb, list);
4251 __kfree_skb(skb);
4252 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPRCVCOLLAPSED);
4253 skb = next;
4254 if (skb == tail || 4279 if (skb == tail ||
4255 tcp_hdr(skb)->syn || 4280 tcp_hdr(skb)->syn ||
4256 tcp_hdr(skb)->fin) 4281 tcp_hdr(skb)->fin)
@@ -4436,8 +4461,8 @@ static void tcp_new_space(struct sock *sk)
4436 4461
4437 if (tcp_should_expand_sndbuf(sk)) { 4462 if (tcp_should_expand_sndbuf(sk)) {
4438 int sndmem = max_t(u32, tp->rx_opt.mss_clamp, tp->mss_cache) + 4463 int sndmem = max_t(u32, tp->rx_opt.mss_clamp, tp->mss_cache) +
4439 MAX_TCP_HEADER + 16 + sizeof(struct sk_buff), 4464 MAX_TCP_HEADER + 16 + sizeof(struct sk_buff);
4440 demanded = max_t(unsigned int, tp->snd_cwnd, 4465 int demanded = max_t(unsigned int, tp->snd_cwnd,
4441 tp->reordering + 1); 4466 tp->reordering + 1);
4442 sndmem *= 2 * demanded; 4467 sndmem *= 2 * demanded;
4443 if (sndmem > sk->sk_sndbuf) 4468 if (sndmem > sk->sk_sndbuf)
@@ -4691,6 +4716,67 @@ out:
4691} 4716}
4692#endif /* CONFIG_NET_DMA */ 4717#endif /* CONFIG_NET_DMA */
4693 4718
4719/* Does PAWS and seqno based validation of an incoming segment, flags will
4720 * play significant role here.
4721 */
4722static int tcp_validate_incoming(struct sock *sk, struct sk_buff *skb,
4723 struct tcphdr *th, int syn_inerr)
4724{
4725 struct tcp_sock *tp = tcp_sk(sk);
4726
4727 /* RFC1323: H1. Apply PAWS check first. */
4728 if (tcp_fast_parse_options(skb, th, tp) && tp->rx_opt.saw_tstamp &&
4729 tcp_paws_discard(sk, skb)) {
4730 if (!th->rst) {
4731 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSESTABREJECTED);
4732 tcp_send_dupack(sk, skb);
4733 goto discard;
4734 }
4735 /* Reset is accepted even if it did not pass PAWS. */
4736 }
4737
4738 /* Step 1: check sequence number */
4739 if (!tcp_sequence(tp, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq)) {
4740 /* RFC793, page 37: "In all states except SYN-SENT, all reset
4741 * (RST) segments are validated by checking their SEQ-fields."
4742 * And page 69: "If an incoming segment is not acceptable,
4743 * an acknowledgment should be sent in reply (unless the RST
4744 * bit is set, if so drop the segment and return)".
4745 */
4746 if (!th->rst)
4747 tcp_send_dupack(sk, skb);
4748 goto discard;
4749 }
4750
4751 /* Step 2: check RST bit */
4752 if (th->rst) {
4753 tcp_reset(sk);
4754 goto discard;
4755 }
4756
4757 /* ts_recent update must be made after we are sure that the packet
4758 * is in window.
4759 */
4760 tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq);
4761
4762 /* step 3: check security and precedence [ignored] */
4763
4764 /* step 4: Check for a SYN in window. */
4765 if (th->syn && !before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) {
4766 if (syn_inerr)
4767 TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_INERRS);
4768 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPABORTONSYN);
4769 tcp_reset(sk);
4770 return -1;
4771 }
4772
4773 return 1;
4774
4775discard:
4776 __kfree_skb(skb);
4777 return 0;
4778}
4779
4694/* 4780/*
4695 * TCP receive function for the ESTABLISHED state. 4781 * TCP receive function for the ESTABLISHED state.
4696 * 4782 *
@@ -4718,6 +4804,7 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
4718 struct tcphdr *th, unsigned len) 4804 struct tcphdr *th, unsigned len)
4719{ 4805{
4720 struct tcp_sock *tp = tcp_sk(sk); 4806 struct tcp_sock *tp = tcp_sk(sk);
4807 int res;
4721 4808
4722 /* 4809 /*
4723 * Header prediction. 4810 * Header prediction.
@@ -4756,19 +4843,10 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
4756 4843
4757 /* Check timestamp */ 4844 /* Check timestamp */
4758 if (tcp_header_len == sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED) { 4845 if (tcp_header_len == sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED) {
4759 __be32 *ptr = (__be32 *)(th + 1);
4760
4761 /* No? Slow path! */ 4846 /* No? Slow path! */
4762 if (*ptr != htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) 4847 if (!tcp_parse_aligned_timestamp(tp, th))
4763 | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP))
4764 goto slow_path; 4848 goto slow_path;
4765 4849
4766 tp->rx_opt.saw_tstamp = 1;
4767 ++ptr;
4768 tp->rx_opt.rcv_tsval = ntohl(*ptr);
4769 ++ptr;
4770 tp->rx_opt.rcv_tsecr = ntohl(*ptr);
4771
4772 /* If PAWS failed, check it more carefully in slow path */ 4850 /* If PAWS failed, check it more carefully in slow path */
4773 if ((s32)(tp->rx_opt.rcv_tsval - tp->rx_opt.ts_recent) < 0) 4851 if ((s32)(tp->rx_opt.rcv_tsval - tp->rx_opt.ts_recent) < 0)
4774 goto slow_path; 4852 goto slow_path;
@@ -4879,7 +4957,8 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
4879 goto no_ack; 4957 goto no_ack;
4880 } 4958 }
4881 4959
4882 __tcp_ack_snd_check(sk, 0); 4960 if (!copied_early || tp->rcv_nxt != tp->rcv_wup)
4961 __tcp_ack_snd_check(sk, 0);
4883no_ack: 4962no_ack:
4884#ifdef CONFIG_NET_DMA 4963#ifdef CONFIG_NET_DMA
4885 if (copied_early) 4964 if (copied_early)
@@ -4899,51 +4978,12 @@ slow_path:
4899 goto csum_error; 4978 goto csum_error;
4900 4979
4901 /* 4980 /*
4902 * RFC1323: H1. Apply PAWS check first.
4903 */
4904 if (tcp_fast_parse_options(skb, th, tp) && tp->rx_opt.saw_tstamp &&
4905 tcp_paws_discard(sk, skb)) {
4906 if (!th->rst) {
4907 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSESTABREJECTED);
4908 tcp_send_dupack(sk, skb);
4909 goto discard;
4910 }
4911 /* Resets are accepted even if PAWS failed.
4912
4913 ts_recent update must be made after we are sure
4914 that the packet is in window.
4915 */
4916 }
4917
4918 /*
4919 * Standard slow path. 4981 * Standard slow path.
4920 */ 4982 */
4921 4983
4922 if (!tcp_sequence(tp, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq)) { 4984 res = tcp_validate_incoming(sk, skb, th, 1);
4923 /* RFC793, page 37: "In all states except SYN-SENT, all reset 4985 if (res <= 0)
4924 * (RST) segments are validated by checking their SEQ-fields." 4986 return -res;
4925 * And page 69: "If an incoming segment is not acceptable,
4926 * an acknowledgment should be sent in reply (unless the RST bit
4927 * is set, if so drop the segment and return)".
4928 */
4929 if (!th->rst)
4930 tcp_send_dupack(sk, skb);
4931 goto discard;
4932 }
4933
4934 if (th->rst) {
4935 tcp_reset(sk);
4936 goto discard;
4937 }
4938
4939 tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq);
4940
4941 if (th->syn && !before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) {
4942 TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_INERRS);
4943 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPABORTONSYN);
4944 tcp_reset(sk);
4945 return 1;
4946 }
4947 4987
4948step5: 4988step5:
4949 if (th->ack) 4989 if (th->ack)
@@ -5225,6 +5265,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
5225 struct tcp_sock *tp = tcp_sk(sk); 5265 struct tcp_sock *tp = tcp_sk(sk);
5226 struct inet_connection_sock *icsk = inet_csk(sk); 5266 struct inet_connection_sock *icsk = inet_csk(sk);
5227 int queued = 0; 5267 int queued = 0;
5268 int res;
5228 5269
5229 tp->rx_opt.saw_tstamp = 0; 5270 tp->rx_opt.saw_tstamp = 0;
5230 5271
@@ -5277,42 +5318,9 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
5277 return 0; 5318 return 0;
5278 } 5319 }
5279 5320
5280 if (tcp_fast_parse_options(skb, th, tp) && tp->rx_opt.saw_tstamp && 5321 res = tcp_validate_incoming(sk, skb, th, 0);
5281 tcp_paws_discard(sk, skb)) { 5322 if (res <= 0)
5282 if (!th->rst) { 5323 return -res;
5283 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSESTABREJECTED);
5284 tcp_send_dupack(sk, skb);
5285 goto discard;
5286 }
5287 /* Reset is accepted even if it did not pass PAWS. */
5288 }
5289
5290 /* step 1: check sequence number */
5291 if (!tcp_sequence(tp, TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq)) {
5292 if (!th->rst)
5293 tcp_send_dupack(sk, skb);
5294 goto discard;
5295 }
5296
5297 /* step 2: check RST bit */
5298 if (th->rst) {
5299 tcp_reset(sk);
5300 goto discard;
5301 }
5302
5303 tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq);
5304
5305 /* step 3: check security and precedence [ignored] */
5306
5307 /* step 4:
5308 *
5309 * Check for a SYN in window.
5310 */
5311 if (th->syn && !before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) {
5312 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPABORTONSYN);
5313 tcp_reset(sk);
5314 return 1;
5315 }
5316 5324
5317 /* step 5: check the ACK field */ 5325 /* step 5: check the ACK field */
5318 if (th->ack) { 5326 if (th->ack) {
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 44c1e934824b..5c8fa7f1e327 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -583,14 +583,15 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
583 rep.th.doff = arg.iov[0].iov_len / 4; 583 rep.th.doff = arg.iov[0].iov_len / 4;
584 584
585 tcp_v4_md5_hash_hdr((__u8 *) &rep.opt[1], 585 tcp_v4_md5_hash_hdr((__u8 *) &rep.opt[1],
586 key, ip_hdr(skb)->daddr, 586 key, ip_hdr(skb)->saddr,
587 ip_hdr(skb)->saddr, &rep.th); 587 ip_hdr(skb)->daddr, &rep.th);
588 } 588 }
589#endif 589#endif
590 arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr, 590 arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr,
591 ip_hdr(skb)->saddr, /* XXX */ 591 ip_hdr(skb)->saddr, /* XXX */
592 sizeof(struct tcphdr), IPPROTO_TCP, 0); 592 arg.iov[0].iov_len, IPPROTO_TCP, 0);
593 arg.csumoffset = offsetof(struct tcphdr, check) / 2; 593 arg.csumoffset = offsetof(struct tcphdr, check) / 2;
594 arg.flags = (sk && inet_sk(sk)->transparent) ? IP_REPLY_ARG_NOSRCCHECK : 0;
594 595
595 net = dev_net(skb->dst->dev); 596 net = dev_net(skb->dst->dev);
596 ip_send_reply(net->ipv4.tcp_sock, skb, 597 ip_send_reply(net->ipv4.tcp_sock, skb,
@@ -606,7 +607,8 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
606 607
607static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack, 608static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
608 u32 win, u32 ts, int oif, 609 u32 win, u32 ts, int oif,
609 struct tcp_md5sig_key *key) 610 struct tcp_md5sig_key *key,
611 int reply_flags)
610{ 612{
611 struct tcphdr *th = tcp_hdr(skb); 613 struct tcphdr *th = tcp_hdr(skb);
612 struct { 614 struct {
@@ -618,7 +620,7 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
618 ]; 620 ];
619 } rep; 621 } rep;
620 struct ip_reply_arg arg; 622 struct ip_reply_arg arg;
621 struct net *net = dev_net(skb->dev); 623 struct net *net = dev_net(skb->dst->dev);
622 624
623 memset(&rep.th, 0, sizeof(struct tcphdr)); 625 memset(&rep.th, 0, sizeof(struct tcphdr));
624 memset(&arg, 0, sizeof(arg)); 626 memset(&arg, 0, sizeof(arg));
@@ -659,6 +661,7 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
659 ip_hdr(skb)->daddr, &rep.th); 661 ip_hdr(skb)->daddr, &rep.th);
660 } 662 }
661#endif 663#endif
664 arg.flags = reply_flags;
662 arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr, 665 arg.csum = csum_tcpudp_nofold(ip_hdr(skb)->daddr,
663 ip_hdr(skb)->saddr, /* XXX */ 666 ip_hdr(skb)->saddr, /* XXX */
664 arg.iov[0].iov_len, IPPROTO_TCP, 0); 667 arg.iov[0].iov_len, IPPROTO_TCP, 0);
@@ -681,7 +684,8 @@ static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb)
681 tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, 684 tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
682 tcptw->tw_ts_recent, 685 tcptw->tw_ts_recent,
683 tw->tw_bound_dev_if, 686 tw->tw_bound_dev_if,
684 tcp_twsk_md5_key(tcptw) 687 tcp_twsk_md5_key(tcptw),
688 tw->tw_transparent ? IP_REPLY_ARG_NOSRCCHECK : 0
685 ); 689 );
686 690
687 inet_twsk_put(tw); 691 inet_twsk_put(tw);
@@ -694,7 +698,8 @@ static void tcp_v4_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
694 tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, 698 tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd,
695 req->ts_recent, 699 req->ts_recent,
696 0, 700 0,
697 tcp_v4_md5_do_lookup(sk, ip_hdr(skb)->daddr)); 701 tcp_v4_md5_do_lookup(sk, ip_hdr(skb)->daddr),
702 inet_rsk(req)->no_srccheck ? IP_REPLY_ARG_NOSRCCHECK : 0);
698} 703}
699 704
700/* 705/*
@@ -1244,6 +1249,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
1244 ireq = inet_rsk(req); 1249 ireq = inet_rsk(req);
1245 ireq->loc_addr = daddr; 1250 ireq->loc_addr = daddr;
1246 ireq->rmt_addr = saddr; 1251 ireq->rmt_addr = saddr;
1252 ireq->no_srccheck = inet_sk(sk)->transparent;
1247 ireq->opt = tcp_v4_save_options(sk, skb); 1253 ireq->opt = tcp_v4_save_options(sk, skb);
1248 if (!want_cookie) 1254 if (!want_cookie)
1249 TCP_ECN_create_request(req, tcp_hdr(skb)); 1255 TCP_ECN_create_request(req, tcp_hdr(skb));
@@ -1364,6 +1370,10 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1364 tcp_mtup_init(newsk); 1370 tcp_mtup_init(newsk);
1365 tcp_sync_mss(newsk, dst_mtu(dst)); 1371 tcp_sync_mss(newsk, dst_mtu(dst));
1366 newtp->advmss = dst_metric(dst, RTAX_ADVMSS); 1372 newtp->advmss = dst_metric(dst, RTAX_ADVMSS);
1373 if (tcp_sk(sk)->rx_opt.user_mss &&
1374 tcp_sk(sk)->rx_opt.user_mss < newtp->advmss)
1375 newtp->advmss = tcp_sk(sk)->rx_opt.user_mss;
1376
1367 tcp_initialize_rcv_mss(newsk); 1377 tcp_initialize_rcv_mss(newsk);
1368 1378
1369#ifdef CONFIG_TCP_MD5SIG 1379#ifdef CONFIG_TCP_MD5SIG
@@ -1567,8 +1577,7 @@ int tcp_v4_rcv(struct sk_buff *skb)
1567 TCP_SKB_CB(skb)->flags = iph->tos; 1577 TCP_SKB_CB(skb)->flags = iph->tos;
1568 TCP_SKB_CB(skb)->sacked = 0; 1578 TCP_SKB_CB(skb)->sacked = 0;
1569 1579
1570 sk = __inet_lookup(net, &tcp_hashinfo, iph->saddr, 1580 sk = __inet_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest);
1571 th->source, iph->daddr, th->dest, inet_iif(skb));
1572 if (!sk) 1581 if (!sk)
1573 goto no_tcp_socket; 1582 goto no_tcp_socket;
1574 1583
@@ -1946,6 +1955,12 @@ static void *listening_get_idx(struct seq_file *seq, loff_t *pos)
1946 return rc; 1955 return rc;
1947} 1956}
1948 1957
1958static inline int empty_bucket(struct tcp_iter_state *st)
1959{
1960 return hlist_empty(&tcp_hashinfo.ehash[st->bucket].chain) &&
1961 hlist_empty(&tcp_hashinfo.ehash[st->bucket].twchain);
1962}
1963
1949static void *established_get_first(struct seq_file *seq) 1964static void *established_get_first(struct seq_file *seq)
1950{ 1965{
1951 struct tcp_iter_state* st = seq->private; 1966 struct tcp_iter_state* st = seq->private;
@@ -1958,6 +1973,10 @@ static void *established_get_first(struct seq_file *seq)
1958 struct inet_timewait_sock *tw; 1973 struct inet_timewait_sock *tw;
1959 rwlock_t *lock = inet_ehash_lockp(&tcp_hashinfo, st->bucket); 1974 rwlock_t *lock = inet_ehash_lockp(&tcp_hashinfo, st->bucket);
1960 1975
1976 /* Lockless fast path for the common case of empty buckets */
1977 if (empty_bucket(st))
1978 continue;
1979
1961 read_lock_bh(lock); 1980 read_lock_bh(lock);
1962 sk_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) { 1981 sk_for_each(sk, node, &tcp_hashinfo.ehash[st->bucket].chain) {
1963 if (sk->sk_family != st->family || 1982 if (sk->sk_family != st->family ||
@@ -2008,13 +2027,15 @@ get_tw:
2008 read_unlock_bh(inet_ehash_lockp(&tcp_hashinfo, st->bucket)); 2027 read_unlock_bh(inet_ehash_lockp(&tcp_hashinfo, st->bucket));
2009 st->state = TCP_SEQ_STATE_ESTABLISHED; 2028 st->state = TCP_SEQ_STATE_ESTABLISHED;
2010 2029
2011 if (++st->bucket < tcp_hashinfo.ehash_size) { 2030 /* Look for next non empty bucket */
2012 read_lock_bh(inet_ehash_lockp(&tcp_hashinfo, st->bucket)); 2031 while (++st->bucket < tcp_hashinfo.ehash_size &&
2013 sk = sk_head(&tcp_hashinfo.ehash[st->bucket].chain); 2032 empty_bucket(st))
2014 } else { 2033 ;
2015 cur = NULL; 2034 if (st->bucket >= tcp_hashinfo.ehash_size)
2016 goto out; 2035 return NULL;
2017 } 2036
2037 read_lock_bh(inet_ehash_lockp(&tcp_hashinfo, st->bucket));
2038 sk = sk_head(&tcp_hashinfo.ehash[st->bucket].chain);
2018 } else 2039 } else
2019 sk = sk_next(sk); 2040 sk = sk_next(sk);
2020 2041
@@ -2376,6 +2397,7 @@ static int __net_init tcp_sk_init(struct net *net)
2376static void __net_exit tcp_sk_exit(struct net *net) 2397static void __net_exit tcp_sk_exit(struct net *net)
2377{ 2398{
2378 inet_ctl_sock_destroy(net->ipv4.tcp_sock); 2399 inet_ctl_sock_destroy(net->ipv4.tcp_sock);
2400 inet_twsk_purge(net, &tcp_hashinfo, &tcp_death_row, AF_INET);
2379} 2401}
2380 2402
2381static struct pernet_operations __net_initdata tcp_sk_ops = { 2403static struct pernet_operations __net_initdata tcp_sk_ops = {
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index f976fc57892c..779f2e9d0689 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -395,6 +395,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req,
395 newtp->pred_flags = 0; 395 newtp->pred_flags = 0;
396 newtp->rcv_wup = newtp->copied_seq = newtp->rcv_nxt = treq->rcv_isn + 1; 396 newtp->rcv_wup = newtp->copied_seq = newtp->rcv_nxt = treq->rcv_isn + 1;
397 newtp->snd_sml = newtp->snd_una = newtp->snd_nxt = treq->snt_isn + 1; 397 newtp->snd_sml = newtp->snd_una = newtp->snd_nxt = treq->snt_isn + 1;
398 newtp->snd_up = treq->snt_isn + 1;
398 399
399 tcp_prequeue_init(newtp); 400 tcp_prequeue_init(newtp);
400 401
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 8165f5aa8c71..990a58493235 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -345,6 +345,11 @@ static void tcp_init_nondata_skb(struct sk_buff *skb, u32 seq, u8 flags)
345 TCP_SKB_CB(skb)->end_seq = seq; 345 TCP_SKB_CB(skb)->end_seq = seq;
346} 346}
347 347
348static inline int tcp_urg_mode(const struct tcp_sock *tp)
349{
350 return tp->snd_una != tp->snd_up;
351}
352
348#define OPTION_SACK_ADVERTISE (1 << 0) 353#define OPTION_SACK_ADVERTISE (1 << 0)
349#define OPTION_TS (1 << 1) 354#define OPTION_TS (1 << 1)
350#define OPTION_MD5 (1 << 2) 355#define OPTION_MD5 (1 << 2)
@@ -646,7 +651,8 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
646 th->check = 0; 651 th->check = 0;
647 th->urg_ptr = 0; 652 th->urg_ptr = 0;
648 653
649 if (unlikely(tp->urg_mode && 654 /* The urg_mode check is necessary during a below snd_una win probe */
655 if (unlikely(tcp_urg_mode(tp) &&
650 between(tp->snd_up, tcb->seq + 1, tcb->seq + 0xFFFF))) { 656 between(tp->snd_up, tcb->seq + 1, tcb->seq + 0xFFFF))) {
651 th->urg_ptr = htons(tp->snd_up - tcb->seq); 657 th->urg_ptr = htons(tp->snd_up - tcb->seq);
652 th->urg = 1; 658 th->urg = 1;
@@ -1012,7 +1018,7 @@ unsigned int tcp_sync_mss(struct sock *sk, u32 pmtu)
1012/* Compute the current effective MSS, taking SACKs and IP options, 1018/* Compute the current effective MSS, taking SACKs and IP options,
1013 * and even PMTU discovery events into account. 1019 * and even PMTU discovery events into account.
1014 * 1020 *
1015 * LARGESEND note: !urg_mode is overkill, only frames up to snd_up 1021 * LARGESEND note: !tcp_urg_mode is overkill, only frames up to snd_up
1016 * cannot be large. However, taking into account rare use of URG, this 1022 * cannot be large. However, taking into account rare use of URG, this
1017 * is not a big flaw. 1023 * is not a big flaw.
1018 */ 1024 */
@@ -1029,7 +1035,7 @@ unsigned int tcp_current_mss(struct sock *sk, int large_allowed)
1029 1035
1030 mss_now = tp->mss_cache; 1036 mss_now = tp->mss_cache;
1031 1037
1032 if (large_allowed && sk_can_gso(sk) && !tp->urg_mode) 1038 if (large_allowed && sk_can_gso(sk) && !tcp_urg_mode(tp))
1033 doing_tso = 1; 1039 doing_tso = 1;
1034 1040
1035 if (dst) { 1041 if (dst) {
@@ -1193,7 +1199,7 @@ static inline int tcp_nagle_test(struct tcp_sock *tp, struct sk_buff *skb,
1193 /* Don't use the nagle rule for urgent data (or for the final FIN). 1199 /* Don't use the nagle rule for urgent data (or for the final FIN).
1194 * Nagle can be ignored during F-RTO too (see RFC4138). 1200 * Nagle can be ignored during F-RTO too (see RFC4138).
1195 */ 1201 */
1196 if (tp->urg_mode || (tp->frto_counter == 2) || 1202 if (tcp_urg_mode(tp) || (tp->frto_counter == 2) ||
1197 (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN)) 1203 (TCP_SKB_CB(skb)->flags & TCPCB_FLAG_FIN))
1198 return 1; 1204 return 1;
1199 1205
@@ -1824,6 +1830,8 @@ static void tcp_retrans_try_collapse(struct sock *sk, struct sk_buff *skb,
1824 1830
1825 /* changed transmit queue under us so clear hints */ 1831 /* changed transmit queue under us so clear hints */
1826 tcp_clear_retrans_hints_partial(tp); 1832 tcp_clear_retrans_hints_partial(tp);
1833 if (next_skb == tp->retransmit_skb_hint)
1834 tp->retransmit_skb_hint = skb;
1827 1835
1828 sk_wmem_free_skb(sk, next_skb); 1836 sk_wmem_free_skb(sk, next_skb);
1829} 1837}
@@ -1838,7 +1846,7 @@ void tcp_simple_retransmit(struct sock *sk)
1838 struct tcp_sock *tp = tcp_sk(sk); 1846 struct tcp_sock *tp = tcp_sk(sk);
1839 struct sk_buff *skb; 1847 struct sk_buff *skb;
1840 unsigned int mss = tcp_current_mss(sk, 0); 1848 unsigned int mss = tcp_current_mss(sk, 0);
1841 int lost = 0; 1849 u32 prior_lost = tp->lost_out;
1842 1850
1843 tcp_for_write_queue(skb, sk) { 1851 tcp_for_write_queue(skb, sk) {
1844 if (skb == tcp_send_head(sk)) 1852 if (skb == tcp_send_head(sk))
@@ -1849,17 +1857,13 @@ void tcp_simple_retransmit(struct sock *sk)
1849 TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS; 1857 TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_RETRANS;
1850 tp->retrans_out -= tcp_skb_pcount(skb); 1858 tp->retrans_out -= tcp_skb_pcount(skb);
1851 } 1859 }
1852 if (!(TCP_SKB_CB(skb)->sacked & TCPCB_LOST)) { 1860 tcp_skb_mark_lost_uncond_verify(tp, skb);
1853 TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
1854 tp->lost_out += tcp_skb_pcount(skb);
1855 lost = 1;
1856 }
1857 } 1861 }
1858 } 1862 }
1859 1863
1860 tcp_clear_all_retrans_hints(tp); 1864 tcp_clear_retrans_hints_partial(tp);
1861 1865
1862 if (!lost) 1866 if (prior_lost == tp->lost_out)
1863 return; 1867 return;
1864 1868
1865 if (tcp_is_reno(tp)) 1869 if (tcp_is_reno(tp))
@@ -1934,8 +1938,8 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
1934 /* Collapse two adjacent packets if worthwhile and we can. */ 1938 /* Collapse two adjacent packets if worthwhile and we can. */
1935 if (!(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_SYN) && 1939 if (!(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_SYN) &&
1936 (skb->len < (cur_mss >> 1)) && 1940 (skb->len < (cur_mss >> 1)) &&
1937 (tcp_write_queue_next(sk, skb) != tcp_send_head(sk)) &&
1938 (!tcp_skb_is_last(sk, skb)) && 1941 (!tcp_skb_is_last(sk, skb)) &&
1942 (tcp_write_queue_next(sk, skb) != tcp_send_head(sk)) &&
1939 (skb_shinfo(skb)->nr_frags == 0 && 1943 (skb_shinfo(skb)->nr_frags == 0 &&
1940 skb_shinfo(tcp_write_queue_next(sk, skb))->nr_frags == 0) && 1944 skb_shinfo(tcp_write_queue_next(sk, skb))->nr_frags == 0) &&
1941 (tcp_skb_pcount(skb) == 1 && 1945 (tcp_skb_pcount(skb) == 1 &&
@@ -1996,86 +2000,18 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
1996 return err; 2000 return err;
1997} 2001}
1998 2002
1999/* This gets called after a retransmit timeout, and the initially 2003static int tcp_can_forward_retransmit(struct sock *sk)
2000 * retransmitted data is acknowledged. It tries to continue
2001 * resending the rest of the retransmit queue, until either
2002 * we've sent it all or the congestion window limit is reached.
2003 * If doing SACK, the first ACK which comes back for a timeout
2004 * based retransmit packet might feed us FACK information again.
2005 * If so, we use it to avoid unnecessarily retransmissions.
2006 */
2007void tcp_xmit_retransmit_queue(struct sock *sk)
2008{ 2004{
2009 const struct inet_connection_sock *icsk = inet_csk(sk); 2005 const struct inet_connection_sock *icsk = inet_csk(sk);
2010 struct tcp_sock *tp = tcp_sk(sk); 2006 struct tcp_sock *tp = tcp_sk(sk);
2011 struct sk_buff *skb;
2012 int packet_cnt;
2013
2014 if (tp->retransmit_skb_hint) {
2015 skb = tp->retransmit_skb_hint;
2016 packet_cnt = tp->retransmit_cnt_hint;
2017 } else {
2018 skb = tcp_write_queue_head(sk);
2019 packet_cnt = 0;
2020 }
2021
2022 /* First pass: retransmit lost packets. */
2023 if (tp->lost_out) {
2024 tcp_for_write_queue_from(skb, sk) {
2025 __u8 sacked = TCP_SKB_CB(skb)->sacked;
2026
2027 if (skb == tcp_send_head(sk))
2028 break;
2029 /* we could do better than to assign each time */
2030 tp->retransmit_skb_hint = skb;
2031 tp->retransmit_cnt_hint = packet_cnt;
2032
2033 /* Assume this retransmit will generate
2034 * only one packet for congestion window
2035 * calculation purposes. This works because
2036 * tcp_retransmit_skb() will chop up the
2037 * packet to be MSS sized and all the
2038 * packet counting works out.
2039 */
2040 if (tcp_packets_in_flight(tp) >= tp->snd_cwnd)
2041 return;
2042
2043 if (sacked & TCPCB_LOST) {
2044 if (!(sacked & (TCPCB_SACKED_ACKED|TCPCB_SACKED_RETRANS))) {
2045 int mib_idx;
2046
2047 if (tcp_retransmit_skb(sk, skb)) {
2048 tp->retransmit_skb_hint = NULL;
2049 return;
2050 }
2051 if (icsk->icsk_ca_state != TCP_CA_Loss)
2052 mib_idx = LINUX_MIB_TCPFASTRETRANS;
2053 else
2054 mib_idx = LINUX_MIB_TCPSLOWSTARTRETRANS;
2055 NET_INC_STATS_BH(sock_net(sk), mib_idx);
2056
2057 if (skb == tcp_write_queue_head(sk))
2058 inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
2059 inet_csk(sk)->icsk_rto,
2060 TCP_RTO_MAX);
2061 }
2062
2063 packet_cnt += tcp_skb_pcount(skb);
2064 if (packet_cnt >= tp->lost_out)
2065 break;
2066 }
2067 }
2068 }
2069
2070 /* OK, demanded retransmission is finished. */
2071 2007
2072 /* Forward retransmissions are possible only during Recovery. */ 2008 /* Forward retransmissions are possible only during Recovery. */
2073 if (icsk->icsk_ca_state != TCP_CA_Recovery) 2009 if (icsk->icsk_ca_state != TCP_CA_Recovery)
2074 return; 2010 return 0;
2075 2011
2076 /* No forward retransmissions in Reno are possible. */ 2012 /* No forward retransmissions in Reno are possible. */
2077 if (tcp_is_reno(tp)) 2013 if (tcp_is_reno(tp))
2078 return; 2014 return 0;
2079 2015
2080 /* Yeah, we have to make difficult choice between forward transmission 2016 /* Yeah, we have to make difficult choice between forward transmission
2081 * and retransmission... Both ways have their merits... 2017 * and retransmission... Both ways have their merits...
@@ -2086,43 +2022,104 @@ void tcp_xmit_retransmit_queue(struct sock *sk)
2086 */ 2022 */
2087 2023
2088 if (tcp_may_send_now(sk)) 2024 if (tcp_may_send_now(sk))
2089 return; 2025 return 0;
2090 2026
2091 /* If nothing is SACKed, highest_sack in the loop won't be valid */ 2027 return 1;
2092 if (!tp->sacked_out) 2028}
2093 return;
2094 2029
2095 if (tp->forward_skb_hint) 2030/* This gets called after a retransmit timeout, and the initially
2096 skb = tp->forward_skb_hint; 2031 * retransmitted data is acknowledged. It tries to continue
2097 else 2032 * resending the rest of the retransmit queue, until either
2033 * we've sent it all or the congestion window limit is reached.
2034 * If doing SACK, the first ACK which comes back for a timeout
2035 * based retransmit packet might feed us FACK information again.
2036 * If so, we use it to avoid unnecessarily retransmissions.
2037 */
2038void tcp_xmit_retransmit_queue(struct sock *sk)
2039{
2040 const struct inet_connection_sock *icsk = inet_csk(sk);
2041 struct tcp_sock *tp = tcp_sk(sk);
2042 struct sk_buff *skb;
2043 struct sk_buff *hole = NULL;
2044 u32 last_lost;
2045 int mib_idx;
2046 int fwd_rexmitting = 0;
2047
2048 if (!tp->lost_out)
2049 tp->retransmit_high = tp->snd_una;
2050
2051 if (tp->retransmit_skb_hint) {
2052 skb = tp->retransmit_skb_hint;
2053 last_lost = TCP_SKB_CB(skb)->end_seq;
2054 if (after(last_lost, tp->retransmit_high))
2055 last_lost = tp->retransmit_high;
2056 } else {
2098 skb = tcp_write_queue_head(sk); 2057 skb = tcp_write_queue_head(sk);
2058 last_lost = tp->snd_una;
2059 }
2099 2060
2061 /* First pass: retransmit lost packets. */
2100 tcp_for_write_queue_from(skb, sk) { 2062 tcp_for_write_queue_from(skb, sk) {
2101 if (skb == tcp_send_head(sk)) 2063 __u8 sacked = TCP_SKB_CB(skb)->sacked;
2102 break;
2103 tp->forward_skb_hint = skb;
2104 2064
2105 if (!before(TCP_SKB_CB(skb)->seq, tcp_highest_sack_seq(tp))) 2065 if (skb == tcp_send_head(sk))
2106 break; 2066 break;
2067 /* we could do better than to assign each time */
2068 if (hole == NULL)
2069 tp->retransmit_skb_hint = skb;
2107 2070
2071 /* Assume this retransmit will generate
2072 * only one packet for congestion window
2073 * calculation purposes. This works because
2074 * tcp_retransmit_skb() will chop up the
2075 * packet to be MSS sized and all the
2076 * packet counting works out.
2077 */
2108 if (tcp_packets_in_flight(tp) >= tp->snd_cwnd) 2078 if (tcp_packets_in_flight(tp) >= tp->snd_cwnd)
2109 break; 2079 return;
2080
2081 if (fwd_rexmitting) {
2082begin_fwd:
2083 if (!before(TCP_SKB_CB(skb)->seq, tcp_highest_sack_seq(tp)))
2084 break;
2085 mib_idx = LINUX_MIB_TCPFORWARDRETRANS;
2086
2087 } else if (!before(TCP_SKB_CB(skb)->seq, tp->retransmit_high)) {
2088 tp->retransmit_high = last_lost;
2089 if (!tcp_can_forward_retransmit(sk))
2090 break;
2091 /* Backtrack if necessary to non-L'ed skb */
2092 if (hole != NULL) {
2093 skb = hole;
2094 hole = NULL;
2095 }
2096 fwd_rexmitting = 1;
2097 goto begin_fwd;
2110 2098
2111 if (TCP_SKB_CB(skb)->sacked & TCPCB_TAGBITS) 2099 } else if (!(sacked & TCPCB_LOST)) {
2100 if (hole == NULL && !(sacked & TCPCB_SACKED_RETRANS))
2101 hole = skb;
2112 continue; 2102 continue;
2113 2103
2114 /* Ok, retransmit it. */ 2104 } else {
2115 if (tcp_retransmit_skb(sk, skb)) { 2105 last_lost = TCP_SKB_CB(skb)->end_seq;
2116 tp->forward_skb_hint = NULL; 2106 if (icsk->icsk_ca_state != TCP_CA_Loss)
2117 break; 2107 mib_idx = LINUX_MIB_TCPFASTRETRANS;
2108 else
2109 mib_idx = LINUX_MIB_TCPSLOWSTARTRETRANS;
2118 } 2110 }
2119 2111
2112 if (sacked & (TCPCB_SACKED_ACKED|TCPCB_SACKED_RETRANS))
2113 continue;
2114
2115 if (tcp_retransmit_skb(sk, skb))
2116 return;
2117 NET_INC_STATS_BH(sock_net(sk), mib_idx);
2118
2120 if (skb == tcp_write_queue_head(sk)) 2119 if (skb == tcp_write_queue_head(sk))
2121 inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, 2120 inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS,
2122 inet_csk(sk)->icsk_rto, 2121 inet_csk(sk)->icsk_rto,
2123 TCP_RTO_MAX); 2122 TCP_RTO_MAX);
2124
2125 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPFORWARDRETRANS);
2126 } 2123 }
2127} 2124}
2128 2125
@@ -2241,6 +2238,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
2241 struct sk_buff *skb; 2238 struct sk_buff *skb;
2242 struct tcp_md5sig_key *md5; 2239 struct tcp_md5sig_key *md5;
2243 __u8 *md5_hash_location; 2240 __u8 *md5_hash_location;
2241 int mss;
2244 2242
2245 skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15, 1, GFP_ATOMIC); 2243 skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15, 1, GFP_ATOMIC);
2246 if (skb == NULL) 2244 if (skb == NULL)
@@ -2251,13 +2249,17 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
2251 2249
2252 skb->dst = dst_clone(dst); 2250 skb->dst = dst_clone(dst);
2253 2251
2252 mss = dst_metric(dst, RTAX_ADVMSS);
2253 if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < mss)
2254 mss = tp->rx_opt.user_mss;
2255
2254 if (req->rcv_wnd == 0) { /* ignored for retransmitted syns */ 2256 if (req->rcv_wnd == 0) { /* ignored for retransmitted syns */
2255 __u8 rcv_wscale; 2257 __u8 rcv_wscale;
2256 /* Set this up on the first call only */ 2258 /* Set this up on the first call only */
2257 req->window_clamp = tp->window_clamp ? : dst_metric(dst, RTAX_WINDOW); 2259 req->window_clamp = tp->window_clamp ? : dst_metric(dst, RTAX_WINDOW);
2258 /* tcp_full_space because it is guaranteed to be the first packet */ 2260 /* tcp_full_space because it is guaranteed to be the first packet */
2259 tcp_select_initial_window(tcp_full_space(sk), 2261 tcp_select_initial_window(tcp_full_space(sk),
2260 dst_metric(dst, RTAX_ADVMSS) - (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0), 2262 mss - (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0),
2261 &req->rcv_wnd, 2263 &req->rcv_wnd,
2262 &req->window_clamp, 2264 &req->window_clamp,
2263 ireq->wscale_ok, 2265 ireq->wscale_ok,
@@ -2267,8 +2269,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
2267 2269
2268 memset(&opts, 0, sizeof(opts)); 2270 memset(&opts, 0, sizeof(opts));
2269 TCP_SKB_CB(skb)->when = tcp_time_stamp; 2271 TCP_SKB_CB(skb)->when = tcp_time_stamp;
2270 tcp_header_size = tcp_synack_options(sk, req, 2272 tcp_header_size = tcp_synack_options(sk, req, mss,
2271 dst_metric(dst, RTAX_ADVMSS),
2272 skb, &opts, &md5) + 2273 skb, &opts, &md5) +
2273 sizeof(struct tcphdr); 2274 sizeof(struct tcphdr);
2274 2275
@@ -2280,7 +2281,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst,
2280 th->syn = 1; 2281 th->syn = 1;
2281 th->ack = 1; 2282 th->ack = 1;
2282 TCP_ECN_make_synack(req, th); 2283 TCP_ECN_make_synack(req, th);
2283 th->source = inet_sk(sk)->sport; 2284 th->source = ireq->loc_port;
2284 th->dest = ireq->rmt_port; 2285 th->dest = ireq->rmt_port;
2285 /* Setting of flags are superfluous here for callers (and ECE is 2286 /* Setting of flags are superfluous here for callers (and ECE is
2286 * not even correctly set) 2287 * not even correctly set)
@@ -2342,6 +2343,9 @@ static void tcp_connect_init(struct sock *sk)
2342 if (!tp->window_clamp) 2343 if (!tp->window_clamp)
2343 tp->window_clamp = dst_metric(dst, RTAX_WINDOW); 2344 tp->window_clamp = dst_metric(dst, RTAX_WINDOW);
2344 tp->advmss = dst_metric(dst, RTAX_ADVMSS); 2345 tp->advmss = dst_metric(dst, RTAX_ADVMSS);
2346 if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < tp->advmss)
2347 tp->advmss = tp->rx_opt.user_mss;
2348
2345 tcp_initialize_rcv_mss(sk); 2349 tcp_initialize_rcv_mss(sk);
2346 2350
2347 tcp_select_initial_window(tcp_full_space(sk), 2351 tcp_select_initial_window(tcp_full_space(sk),
@@ -2360,6 +2364,7 @@ static void tcp_connect_init(struct sock *sk)
2360 tcp_init_wl(tp, tp->write_seq, 0); 2364 tcp_init_wl(tp, tp->write_seq, 0);
2361 tp->snd_una = tp->write_seq; 2365 tp->snd_una = tp->write_seq;
2362 tp->snd_sml = tp->write_seq; 2366 tp->snd_sml = tp->write_seq;
2367 tp->snd_up = tp->write_seq;
2363 tp->rcv_nxt = 0; 2368 tp->rcv_nxt = 0;
2364 tp->rcv_wup = 0; 2369 tp->rcv_wup = 0;
2365 tp->copied_seq = 0; 2370 tp->copied_seq = 0;
@@ -2569,8 +2574,7 @@ int tcp_write_wakeup(struct sock *sk)
2569 tcp_event_new_data_sent(sk, skb); 2574 tcp_event_new_data_sent(sk, skb);
2570 return err; 2575 return err;
2571 } else { 2576 } else {
2572 if (tp->urg_mode && 2577 if (between(tp->snd_up, tp->snd_una + 1, tp->snd_una + 0xFFFF))
2573 between(tp->snd_up, tp->snd_una + 1, tp->snd_una + 0xFFFF))
2574 tcp_xmit_probe_skb(sk, 1); 2578 tcp_xmit_probe_skb(sk, 1);
2575 return tcp_xmit_probe_skb(sk, 0); 2579 return tcp_xmit_probe_skb(sk, 0);
2576 } 2580 }
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index 5ab6ba19c3ce..6b6dff1164b9 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -201,7 +201,7 @@ static void tcp_delack_timer(unsigned long data)
201 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPSCHEDULERFAILED); 201 NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPSCHEDULERFAILED);
202 202
203 while ((skb = __skb_dequeue(&tp->ucopy.prequeue)) != NULL) 203 while ((skb = __skb_dequeue(&tp->ucopy.prequeue)) != NULL)
204 sk->sk_backlog_rcv(sk, skb); 204 sk_backlog_rcv(sk, skb);
205 205
206 tp->ucopy.memory = 0; 206 tp->ucopy.memory = 0;
207 } 207 }
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 8e42fbbd5761..eacf4cfef146 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -108,9 +108,6 @@
108 * Snmp MIB for the UDP layer 108 * Snmp MIB for the UDP layer
109 */ 109 */
110 110
111DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly;
112EXPORT_SYMBOL(udp_stats_in6);
113
114struct hlist_head udp_hash[UDP_HTABLE_SIZE]; 111struct hlist_head udp_hash[UDP_HTABLE_SIZE];
115DEFINE_RWLOCK(udp_hash_lock); 112DEFINE_RWLOCK(udp_hash_lock);
116 113
@@ -125,14 +122,23 @@ EXPORT_SYMBOL(sysctl_udp_wmem_min);
125atomic_t udp_memory_allocated; 122atomic_t udp_memory_allocated;
126EXPORT_SYMBOL(udp_memory_allocated); 123EXPORT_SYMBOL(udp_memory_allocated);
127 124
128static inline int __udp_lib_lport_inuse(struct net *net, __u16 num, 125static int udp_lib_lport_inuse(struct net *net, __u16 num,
129 const struct hlist_head udptable[]) 126 const struct hlist_head udptable[],
127 struct sock *sk,
128 int (*saddr_comp)(const struct sock *sk1,
129 const struct sock *sk2))
130{ 130{
131 struct sock *sk; 131 struct sock *sk2;
132 struct hlist_node *node; 132 struct hlist_node *node;
133 133
134 sk_for_each(sk, node, &udptable[udp_hashfn(net, num)]) 134 sk_for_each(sk2, node, &udptable[udp_hashfn(net, num)])
135 if (net_eq(sock_net(sk), net) && sk->sk_hash == num) 135 if (net_eq(sock_net(sk2), net) &&
136 sk2 != sk &&
137 sk2->sk_hash == num &&
138 (!sk2->sk_reuse || !sk->sk_reuse) &&
139 (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if
140 || sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
141 (*saddr_comp)(sk, sk2))
136 return 1; 142 return 1;
137 return 0; 143 return 0;
138} 144}
@@ -149,83 +155,37 @@ int udp_lib_get_port(struct sock *sk, unsigned short snum,
149 const struct sock *sk2 ) ) 155 const struct sock *sk2 ) )
150{ 156{
151 struct hlist_head *udptable = sk->sk_prot->h.udp_hash; 157 struct hlist_head *udptable = sk->sk_prot->h.udp_hash;
152 struct hlist_node *node;
153 struct hlist_head *head;
154 struct sock *sk2;
155 int error = 1; 158 int error = 1;
156 struct net *net = sock_net(sk); 159 struct net *net = sock_net(sk);
157 160
158 write_lock_bh(&udp_hash_lock); 161 write_lock_bh(&udp_hash_lock);
159 162
160 if (!snum) { 163 if (!snum) {
161 int i, low, high, remaining; 164 int low, high, remaining;
162 unsigned rover, best, best_size_so_far; 165 unsigned rand;
166 unsigned short first;
163 167
164 inet_get_local_port_range(&low, &high); 168 inet_get_local_port_range(&low, &high);
165 remaining = (high - low) + 1; 169 remaining = (high - low) + 1;
166 170
167 best_size_so_far = UINT_MAX; 171 rand = net_random();
168 best = rover = net_random() % remaining + low; 172 snum = first = rand % remaining + low;
169 173 rand |= 1;
170 /* 1st pass: look for empty (or shortest) hash chain */ 174 while (udp_lib_lport_inuse(net, snum, udptable, sk,
171 for (i = 0; i < UDP_HTABLE_SIZE; i++) { 175 saddr_comp)) {
172 int size = 0; 176 do {
173 177 snum = snum + rand;
174 head = &udptable[udp_hashfn(net, rover)]; 178 } while (snum < low || snum > high);
175 if (hlist_empty(head)) 179 if (snum == first)
176 goto gotit; 180 goto fail;
177
178 sk_for_each(sk2, node, head) {
179 if (++size >= best_size_so_far)
180 goto next;
181 }
182 best_size_so_far = size;
183 best = rover;
184 next:
185 /* fold back if end of range */
186 if (++rover > high)
187 rover = low + ((rover - low)
188 & (UDP_HTABLE_SIZE - 1));
189
190
191 }
192
193 /* 2nd pass: find hole in shortest hash chain */
194 rover = best;
195 for (i = 0; i < (1 << 16) / UDP_HTABLE_SIZE; i++) {
196 if (! __udp_lib_lport_inuse(net, rover, udptable))
197 goto gotit;
198 rover += UDP_HTABLE_SIZE;
199 if (rover > high)
200 rover = low + ((rover - low)
201 & (UDP_HTABLE_SIZE - 1));
202 } 181 }
203 182 } else if (udp_lib_lport_inuse(net, snum, udptable, sk, saddr_comp))
204
205 /* All ports in use! */
206 goto fail; 183 goto fail;
207 184
208gotit:
209 snum = rover;
210 } else {
211 head = &udptable[udp_hashfn(net, snum)];
212
213 sk_for_each(sk2, node, head)
214 if (sk2->sk_hash == snum &&
215 sk2 != sk &&
216 net_eq(sock_net(sk2), net) &&
217 (!sk2->sk_reuse || !sk->sk_reuse) &&
218 (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if
219 || sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
220 (*saddr_comp)(sk, sk2) )
221 goto fail;
222 }
223
224 inet_sk(sk)->num = snum; 185 inet_sk(sk)->num = snum;
225 sk->sk_hash = snum; 186 sk->sk_hash = snum;
226 if (sk_unhashed(sk)) { 187 if (sk_unhashed(sk)) {
227 head = &udptable[udp_hashfn(net, snum)]; 188 sk_add_node(sk, &udptable[udp_hashfn(net, snum)]);
228 sk_add_node(sk, head);
229 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1); 189 sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
230 } 190 }
231 error = 0; 191 error = 0;
@@ -302,6 +262,28 @@ static struct sock *__udp4_lib_lookup(struct net *net, __be32 saddr,
302 return result; 262 return result;
303} 263}
304 264
265static inline struct sock *__udp4_lib_lookup_skb(struct sk_buff *skb,
266 __be16 sport, __be16 dport,
267 struct hlist_head udptable[])
268{
269 struct sock *sk;
270 const struct iphdr *iph = ip_hdr(skb);
271
272 if (unlikely(sk = skb_steal_sock(skb)))
273 return sk;
274 else
275 return __udp4_lib_lookup(dev_net(skb->dst->dev), iph->saddr, sport,
276 iph->daddr, dport, inet_iif(skb),
277 udptable);
278}
279
280struct sock *udp4_lib_lookup(struct net *net, __be32 saddr, __be16 sport,
281 __be32 daddr, __be16 dport, int dif)
282{
283 return __udp4_lib_lookup(net, saddr, sport, daddr, dport, dif, udp_hash);
284}
285EXPORT_SYMBOL_GPL(udp4_lib_lookup);
286
305static inline struct sock *udp_v4_mcast_next(struct sock *sk, 287static inline struct sock *udp_v4_mcast_next(struct sock *sk,
306 __be16 loc_port, __be32 loc_addr, 288 __be16 loc_port, __be32 loc_addr,
307 __be16 rmt_port, __be32 rmt_addr, 289 __be16 rmt_port, __be32 rmt_addr,
@@ -951,6 +933,27 @@ int udp_disconnect(struct sock *sk, int flags)
951 return 0; 933 return 0;
952} 934}
953 935
936static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
937{
938 int is_udplite = IS_UDPLITE(sk);
939 int rc;
940
941 if ((rc = sock_queue_rcv_skb(sk, skb)) < 0) {
942 /* Note that an ENOMEM error is charged twice */
943 if (rc == -ENOMEM)
944 UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_RCVBUFERRORS,
945 is_udplite);
946 goto drop;
947 }
948
949 return 0;
950
951drop:
952 UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
953 kfree_skb(skb);
954 return -1;
955}
956
954/* returns: 957/* returns:
955 * -1: error 958 * -1: error
956 * 0: success 959 * 0: success
@@ -989,9 +992,7 @@ int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
989 up->encap_rcv != NULL) { 992 up->encap_rcv != NULL) {
990 int ret; 993 int ret;
991 994
992 bh_unlock_sock(sk);
993 ret = (*up->encap_rcv)(sk, skb); 995 ret = (*up->encap_rcv)(sk, skb);
994 bh_lock_sock(sk);
995 if (ret <= 0) { 996 if (ret <= 0) {
996 UDP_INC_STATS_BH(sock_net(sk), 997 UDP_INC_STATS_BH(sock_net(sk),
997 UDP_MIB_INDATAGRAMS, 998 UDP_MIB_INDATAGRAMS,
@@ -1044,17 +1045,16 @@ int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
1044 goto drop; 1045 goto drop;
1045 } 1046 }
1046 1047
1047 if ((rc = sock_queue_rcv_skb(sk,skb)) < 0) { 1048 rc = 0;
1048 /* Note that an ENOMEM error is charged twice */
1049 if (rc == -ENOMEM) {
1050 UDP_INC_STATS_BH(sock_net(sk),
1051 UDP_MIB_RCVBUFERRORS, is_udplite);
1052 atomic_inc(&sk->sk_drops);
1053 }
1054 goto drop;
1055 }
1056 1049
1057 return 0; 1050 bh_lock_sock(sk);
1051 if (!sock_owned_by_user(sk))
1052 rc = __udp_queue_rcv_skb(sk, skb);
1053 else
1054 sk_add_backlog(sk, skb);
1055 bh_unlock_sock(sk);
1056
1057 return rc;
1058 1058
1059drop: 1059drop:
1060 UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, is_udplite); 1060 UDP_INC_STATS_BH(sock_net(sk), UDP_MIB_INERRORS, is_udplite);
@@ -1092,15 +1092,7 @@ static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
1092 skb1 = skb_clone(skb, GFP_ATOMIC); 1092 skb1 = skb_clone(skb, GFP_ATOMIC);
1093 1093
1094 if (skb1) { 1094 if (skb1) {
1095 int ret = 0; 1095 int ret = udp_queue_rcv_skb(sk, skb1);
1096
1097 bh_lock_sock(sk);
1098 if (!sock_owned_by_user(sk))
1099 ret = udp_queue_rcv_skb(sk, skb1);
1100 else
1101 sk_add_backlog(sk, skb1);
1102 bh_unlock_sock(sk);
1103
1104 if (ret > 0) 1096 if (ret > 0)
1105 /* we should probably re-process instead 1097 /* we should probably re-process instead
1106 * of dropping packets here. */ 1098 * of dropping packets here. */
@@ -1191,17 +1183,10 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
1191 return __udp4_lib_mcast_deliver(net, skb, uh, 1183 return __udp4_lib_mcast_deliver(net, skb, uh,
1192 saddr, daddr, udptable); 1184 saddr, daddr, udptable);
1193 1185
1194 sk = __udp4_lib_lookup(net, saddr, uh->source, daddr, 1186 sk = __udp4_lib_lookup_skb(skb, uh->source, uh->dest, udptable);
1195 uh->dest, inet_iif(skb), udptable);
1196 1187
1197 if (sk != NULL) { 1188 if (sk != NULL) {
1198 int ret = 0; 1189 int ret = udp_queue_rcv_skb(sk, skb);
1199 bh_lock_sock(sk);
1200 if (!sock_owned_by_user(sk))
1201 ret = udp_queue_rcv_skb(sk, skb);
1202 else
1203 sk_add_backlog(sk, skb);
1204 bh_unlock_sock(sk);
1205 sock_put(sk); 1190 sock_put(sk);
1206 1191
1207 /* a return value > 0 means to resubmit the input, but 1192 /* a return value > 0 means to resubmit the input, but
@@ -1494,7 +1479,7 @@ struct proto udp_prot = {
1494 .sendmsg = udp_sendmsg, 1479 .sendmsg = udp_sendmsg,
1495 .recvmsg = udp_recvmsg, 1480 .recvmsg = udp_recvmsg,
1496 .sendpage = udp_sendpage, 1481 .sendpage = udp_sendpage,
1497 .backlog_rcv = udp_queue_rcv_skb, 1482 .backlog_rcv = __udp_queue_rcv_skb,
1498 .hash = udp_lib_hash, 1483 .hash = udp_lib_hash,
1499 .unhash = udp_lib_unhash, 1484 .unhash = udp_lib_unhash,
1500 .get_port = udp_v4_get_port, 1485 .get_port = udp_v4_get_port,
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 95055f8c3f35..050e14b7f701 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -50,6 +50,7 @@
50#include <net/ipip.h> 50#include <net/ipip.h>
51#include <net/protocol.h> 51#include <net/protocol.h>
52#include <net/inet_common.h> 52#include <net/inet_common.h>
53#include <net/route.h>
53#include <net/transp_v6.h> 54#include <net/transp_v6.h>
54#include <net/ip6_route.h> 55#include <net/ip6_route.h>
55#include <net/addrconf.h> 56#include <net/addrconf.h>
@@ -794,44 +795,43 @@ static void ipv6_packet_cleanup(void)
794 dev_remove_pack(&ipv6_packet_type); 795 dev_remove_pack(&ipv6_packet_type);
795} 796}
796 797
797static int __init init_ipv6_mibs(void) 798static int __net_init ipv6_init_mibs(struct net *net)
798{ 799{
799 if (snmp_mib_init((void **)ipv6_statistics, 800 if (snmp_mib_init((void **)net->mib.udp_stats_in6,
801 sizeof (struct udp_mib)) < 0)
802 return -ENOMEM;
803 if (snmp_mib_init((void **)net->mib.udplite_stats_in6,
804 sizeof (struct udp_mib)) < 0)
805 goto err_udplite_mib;
806 if (snmp_mib_init((void **)net->mib.ipv6_statistics,
800 sizeof(struct ipstats_mib)) < 0) 807 sizeof(struct ipstats_mib)) < 0)
801 goto err_ip_mib; 808 goto err_ip_mib;
802 if (snmp_mib_init((void **)icmpv6_statistics, 809 if (snmp_mib_init((void **)net->mib.icmpv6_statistics,
803 sizeof(struct icmpv6_mib)) < 0) 810 sizeof(struct icmpv6_mib)) < 0)
804 goto err_icmp_mib; 811 goto err_icmp_mib;
805 if (snmp_mib_init((void **)icmpv6msg_statistics, 812 if (snmp_mib_init((void **)net->mib.icmpv6msg_statistics,
806 sizeof(struct icmpv6msg_mib)) < 0) 813 sizeof(struct icmpv6msg_mib)) < 0)
807 goto err_icmpmsg_mib; 814 goto err_icmpmsg_mib;
808 if (snmp_mib_init((void **)udp_stats_in6, sizeof (struct udp_mib)) < 0)
809 goto err_udp_mib;
810 if (snmp_mib_init((void **)udplite_stats_in6,
811 sizeof (struct udp_mib)) < 0)
812 goto err_udplite_mib;
813 return 0; 815 return 0;
814 816
815err_udplite_mib:
816 snmp_mib_free((void **)udp_stats_in6);
817err_udp_mib:
818 snmp_mib_free((void **)icmpv6msg_statistics);
819err_icmpmsg_mib: 817err_icmpmsg_mib:
820 snmp_mib_free((void **)icmpv6_statistics); 818 snmp_mib_free((void **)net->mib.icmpv6_statistics);
821err_icmp_mib: 819err_icmp_mib:
822 snmp_mib_free((void **)ipv6_statistics); 820 snmp_mib_free((void **)net->mib.ipv6_statistics);
823err_ip_mib: 821err_ip_mib:
822 snmp_mib_free((void **)net->mib.udplite_stats_in6);
823err_udplite_mib:
824 snmp_mib_free((void **)net->mib.udp_stats_in6);
824 return -ENOMEM; 825 return -ENOMEM;
825
826} 826}
827 827
828static void cleanup_ipv6_mibs(void) 828static void __net_exit ipv6_cleanup_mibs(struct net *net)
829{ 829{
830 snmp_mib_free((void **)ipv6_statistics); 830 snmp_mib_free((void **)net->mib.udp_stats_in6);
831 snmp_mib_free((void **)icmpv6_statistics); 831 snmp_mib_free((void **)net->mib.udplite_stats_in6);
832 snmp_mib_free((void **)icmpv6msg_statistics); 832 snmp_mib_free((void **)net->mib.ipv6_statistics);
833 snmp_mib_free((void **)udp_stats_in6); 833 snmp_mib_free((void **)net->mib.icmpv6_statistics);
834 snmp_mib_free((void **)udplite_stats_in6); 834 snmp_mib_free((void **)net->mib.icmpv6msg_statistics);
835} 835}
836 836
837static int inet6_net_init(struct net *net) 837static int inet6_net_init(struct net *net)
@@ -839,16 +839,11 @@ static int inet6_net_init(struct net *net)
839 int err = 0; 839 int err = 0;
840 840
841 net->ipv6.sysctl.bindv6only = 0; 841 net->ipv6.sysctl.bindv6only = 0;
842 net->ipv6.sysctl.flush_delay = 0;
843 net->ipv6.sysctl.ip6_rt_max_size = 4096;
844 net->ipv6.sysctl.ip6_rt_gc_min_interval = HZ / 2;
845 net->ipv6.sysctl.ip6_rt_gc_timeout = 60*HZ;
846 net->ipv6.sysctl.ip6_rt_gc_interval = 30*HZ;
847 net->ipv6.sysctl.ip6_rt_gc_elasticity = 9;
848 net->ipv6.sysctl.ip6_rt_mtu_expires = 10*60*HZ;
849 net->ipv6.sysctl.ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40;
850 net->ipv6.sysctl.icmpv6_time = 1*HZ; 842 net->ipv6.sysctl.icmpv6_time = 1*HZ;
851 843
844 err = ipv6_init_mibs(net);
845 if (err)
846 return err;
852#ifdef CONFIG_PROC_FS 847#ifdef CONFIG_PROC_FS
853 err = udp6_proc_init(net); 848 err = udp6_proc_init(net);
854 if (err) 849 if (err)
@@ -859,7 +854,6 @@ static int inet6_net_init(struct net *net)
859 err = ac6_proc_init(net); 854 err = ac6_proc_init(net);
860 if (err) 855 if (err)
861 goto proc_ac6_fail; 856 goto proc_ac6_fail;
862out:
863#endif 857#endif
864 return err; 858 return err;
865 859
@@ -868,7 +862,9 @@ proc_ac6_fail:
868 tcp6_proc_exit(net); 862 tcp6_proc_exit(net);
869proc_tcp6_fail: 863proc_tcp6_fail:
870 udp6_proc_exit(net); 864 udp6_proc_exit(net);
871 goto out; 865out:
866 ipv6_cleanup_mibs(net);
867 return err;
872#endif 868#endif
873} 869}
874 870
@@ -879,6 +875,7 @@ static void inet6_net_exit(struct net *net)
879 tcp6_proc_exit(net); 875 tcp6_proc_exit(net);
880 ac6_proc_exit(net); 876 ac6_proc_exit(net);
881#endif 877#endif
878 ipv6_cleanup_mibs(net);
882} 879}
883 880
884static struct pernet_operations inet6_net_ops = { 881static struct pernet_operations inet6_net_ops = {
@@ -929,11 +926,6 @@ static int __init inet6_init(void)
929 if (err) 926 if (err)
930 goto out_sock_register_fail; 927 goto out_sock_register_fail;
931 928
932 /* Initialise ipv6 mibs */
933 err = init_ipv6_mibs();
934 if (err)
935 goto out_unregister_sock;
936
937#ifdef CONFIG_SYSCTL 929#ifdef CONFIG_SYSCTL
938 err = ipv6_static_sysctl_register(); 930 err = ipv6_static_sysctl_register();
939 if (err) 931 if (err)
@@ -1067,8 +1059,6 @@ register_pernet_fail:
1067 ipv6_static_sysctl_unregister(); 1059 ipv6_static_sysctl_unregister();
1068static_sysctl_fail: 1060static_sysctl_fail:
1069#endif 1061#endif
1070 cleanup_ipv6_mibs();
1071out_unregister_sock:
1072 sock_unregister(PF_INET6); 1062 sock_unregister(PF_INET6);
1073 rtnl_unregister_all(PF_INET6); 1063 rtnl_unregister_all(PF_INET6);
1074out_sock_register_fail: 1064out_sock_register_fail:
@@ -1125,7 +1115,6 @@ static void __exit inet6_exit(void)
1125#ifdef CONFIG_SYSCTL 1115#ifdef CONFIG_SYSCTL
1126 ipv6_static_sysctl_unregister(); 1116 ipv6_static_sysctl_unregister();
1127#endif 1117#endif
1128 cleanup_ipv6_mibs();
1129 proto_unregister(&rawv6_prot); 1118 proto_unregister(&rawv6_prot);
1130 proto_unregister(&udplitev6_prot); 1119 proto_unregister(&udplitev6_prot);
1131 proto_unregister(&udpv6_prot); 1120 proto_unregister(&udpv6_prot);
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 837c830d6d8e..6bfffec2371c 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -277,7 +277,7 @@ static int ipv6_destopt_rcv(struct sk_buff *skb)
277 if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) || 277 if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) ||
278 !pskb_may_pull(skb, (skb_transport_offset(skb) + 278 !pskb_may_pull(skb, (skb_transport_offset(skb) +
279 ((skb_transport_header(skb)[1] + 1) << 3)))) { 279 ((skb_transport_header(skb)[1] + 1) << 3)))) {
280 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 280 IP6_INC_STATS_BH(dev_net(skb->dst->dev), ip6_dst_idev(skb->dst),
281 IPSTATS_MIB_INHDRERRORS); 281 IPSTATS_MIB_INHDRERRORS);
282 kfree_skb(skb); 282 kfree_skb(skb);
283 return -1; 283 return -1;
@@ -301,7 +301,8 @@ static int ipv6_destopt_rcv(struct sk_buff *skb)
301 return 1; 301 return 1;
302 } 302 }
303 303
304 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS); 304 IP6_INC_STATS_BH(dev_net(dst->dev),
305 ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS);
305 dst_release(dst); 306 dst_release(dst);
306 return -1; 307 return -1;
307} 308}
@@ -319,7 +320,8 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb)
319 int n, i; 320 int n, i;
320 struct ipv6_rt_hdr *hdr; 321 struct ipv6_rt_hdr *hdr;
321 struct rt0_hdr *rthdr; 322 struct rt0_hdr *rthdr;
322 int accept_source_route = dev_net(skb->dev)->ipv6.devconf_all->accept_source_route; 323 struct net *net = dev_net(skb->dev);
324 int accept_source_route = net->ipv6.devconf_all->accept_source_route;
323 325
324 idev = in6_dev_get(skb->dev); 326 idev = in6_dev_get(skb->dev);
325 if (idev) { 327 if (idev) {
@@ -331,7 +333,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb)
331 if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) || 333 if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) ||
332 !pskb_may_pull(skb, (skb_transport_offset(skb) + 334 !pskb_may_pull(skb, (skb_transport_offset(skb) +
333 ((skb_transport_header(skb)[1] + 1) << 3)))) { 335 ((skb_transport_header(skb)[1] + 1) << 3)))) {
334 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 336 IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst),
335 IPSTATS_MIB_INHDRERRORS); 337 IPSTATS_MIB_INHDRERRORS);
336 kfree_skb(skb); 338 kfree_skb(skb);
337 return -1; 339 return -1;
@@ -341,7 +343,7 @@ static int ipv6_rthdr_rcv(struct sk_buff *skb)
341 343
342 if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) || 344 if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr) ||
343 skb->pkt_type != PACKET_HOST) { 345 skb->pkt_type != PACKET_HOST) {
344 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 346 IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst),
345 IPSTATS_MIB_INADDRERRORS); 347 IPSTATS_MIB_INADDRERRORS);
346 kfree_skb(skb); 348 kfree_skb(skb);
347 return -1; 349 return -1;
@@ -356,7 +358,7 @@ looped_back:
356 * processed by own 358 * processed by own
357 */ 359 */
358 if (!addr) { 360 if (!addr) {
359 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 361 IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst),
360 IPSTATS_MIB_INADDRERRORS); 362 IPSTATS_MIB_INADDRERRORS);
361 kfree_skb(skb); 363 kfree_skb(skb);
362 return -1; 364 return -1;
@@ -382,7 +384,7 @@ looped_back:
382 goto unknown_rh; 384 goto unknown_rh;
383 /* Silently discard invalid RTH type 2 */ 385 /* Silently discard invalid RTH type 2 */
384 if (hdr->hdrlen != 2 || hdr->segments_left != 1) { 386 if (hdr->hdrlen != 2 || hdr->segments_left != 1) {
385 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 387 IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst),
386 IPSTATS_MIB_INHDRERRORS); 388 IPSTATS_MIB_INHDRERRORS);
387 kfree_skb(skb); 389 kfree_skb(skb);
388 return -1; 390 return -1;
@@ -401,7 +403,7 @@ looped_back:
401 n = hdr->hdrlen >> 1; 403 n = hdr->hdrlen >> 1;
402 404
403 if (hdr->segments_left > n) { 405 if (hdr->segments_left > n) {
404 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 406 IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst),
405 IPSTATS_MIB_INHDRERRORS); 407 IPSTATS_MIB_INHDRERRORS);
406 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, 408 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
407 ((&hdr->segments_left) - 409 ((&hdr->segments_left) -
@@ -415,7 +417,7 @@ looped_back:
415 if (skb_cloned(skb)) { 417 if (skb_cloned(skb)) {
416 /* the copy is a forwarded packet */ 418 /* the copy is a forwarded packet */
417 if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) { 419 if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
418 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 420 IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst),
419 IPSTATS_MIB_OUTDISCARDS); 421 IPSTATS_MIB_OUTDISCARDS);
420 kfree_skb(skb); 422 kfree_skb(skb);
421 return -1; 423 return -1;
@@ -438,13 +440,13 @@ looped_back:
438 if (xfrm6_input_addr(skb, (xfrm_address_t *)addr, 440 if (xfrm6_input_addr(skb, (xfrm_address_t *)addr,
439 (xfrm_address_t *)&ipv6_hdr(skb)->saddr, 441 (xfrm_address_t *)&ipv6_hdr(skb)->saddr,
440 IPPROTO_ROUTING) < 0) { 442 IPPROTO_ROUTING) < 0) {
441 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 443 IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst),
442 IPSTATS_MIB_INADDRERRORS); 444 IPSTATS_MIB_INADDRERRORS);
443 kfree_skb(skb); 445 kfree_skb(skb);
444 return -1; 446 return -1;
445 } 447 }
446 if (!ipv6_chk_home_addr(dev_net(skb->dst->dev), addr)) { 448 if (!ipv6_chk_home_addr(dev_net(skb->dst->dev), addr)) {
447 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 449 IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst),
448 IPSTATS_MIB_INADDRERRORS); 450 IPSTATS_MIB_INADDRERRORS);
449 kfree_skb(skb); 451 kfree_skb(skb);
450 return -1; 452 return -1;
@@ -456,7 +458,7 @@ looped_back:
456 } 458 }
457 459
458 if (ipv6_addr_is_multicast(addr)) { 460 if (ipv6_addr_is_multicast(addr)) {
459 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 461 IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst),
460 IPSTATS_MIB_INADDRERRORS); 462 IPSTATS_MIB_INADDRERRORS);
461 kfree_skb(skb); 463 kfree_skb(skb);
462 return -1; 464 return -1;
@@ -476,7 +478,7 @@ looped_back:
476 478
477 if (skb->dst->dev->flags&IFF_LOOPBACK) { 479 if (skb->dst->dev->flags&IFF_LOOPBACK) {
478 if (ipv6_hdr(skb)->hop_limit <= 1) { 480 if (ipv6_hdr(skb)->hop_limit <= 1) {
479 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 481 IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst),
480 IPSTATS_MIB_INHDRERRORS); 482 IPSTATS_MIB_INHDRERRORS);
481 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 483 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
482 0, skb->dev); 484 0, skb->dev);
@@ -492,7 +494,7 @@ looped_back:
492 return -1; 494 return -1;
493 495
494unknown_rh: 496unknown_rh:
495 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); 497 IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
496 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, 498 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
497 (&hdr->type) - skb_network_header(skb)); 499 (&hdr->type) - skb_network_header(skb));
498 return -1; 500 return -1;
@@ -579,29 +581,33 @@ static int ipv6_hop_jumbo(struct sk_buff *skb, int optoff)
579{ 581{
580 const unsigned char *nh = skb_network_header(skb); 582 const unsigned char *nh = skb_network_header(skb);
581 u32 pkt_len; 583 u32 pkt_len;
584 struct net *net = dev_net(skb->dst->dev);
582 585
583 if (nh[optoff + 1] != 4 || (optoff & 3) != 2) { 586 if (nh[optoff + 1] != 4 || (optoff & 3) != 2) {
584 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", 587 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n",
585 nh[optoff+1]); 588 nh[optoff+1]);
586 IP6_INC_STATS_BH(ipv6_skb_idev(skb), 589 IP6_INC_STATS_BH(net, ipv6_skb_idev(skb),
587 IPSTATS_MIB_INHDRERRORS); 590 IPSTATS_MIB_INHDRERRORS);
588 goto drop; 591 goto drop;
589 } 592 }
590 593
591 pkt_len = ntohl(*(__be32 *)(nh + optoff + 2)); 594 pkt_len = ntohl(*(__be32 *)(nh + optoff + 2));
592 if (pkt_len <= IPV6_MAXPLEN) { 595 if (pkt_len <= IPV6_MAXPLEN) {
593 IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INHDRERRORS); 596 IP6_INC_STATS_BH(net, ipv6_skb_idev(skb),
597 IPSTATS_MIB_INHDRERRORS);
594 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2); 598 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
595 return 0; 599 return 0;
596 } 600 }
597 if (ipv6_hdr(skb)->payload_len) { 601 if (ipv6_hdr(skb)->payload_len) {
598 IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INHDRERRORS); 602 IP6_INC_STATS_BH(net, ipv6_skb_idev(skb),
603 IPSTATS_MIB_INHDRERRORS);
599 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff); 604 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff);
600 return 0; 605 return 0;
601 } 606 }
602 607
603 if (pkt_len > skb->len - sizeof(struct ipv6hdr)) { 608 if (pkt_len > skb->len - sizeof(struct ipv6hdr)) {
604 IP6_INC_STATS_BH(ipv6_skb_idev(skb), IPSTATS_MIB_INTRUNCATEDPKTS); 609 IP6_INC_STATS_BH(net, ipv6_skb_idev(skb),
610 IPSTATS_MIB_INTRUNCATEDPKTS);
605 goto drop; 611 goto drop;
606 } 612 }
607 613
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index b3157a0cc15d..9b7d19ae5ced 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -183,7 +183,7 @@ static inline int icmpv6_xrlim_allow(struct sock *sk, int type,
183 */ 183 */
184 dst = ip6_route_output(net, sk, fl); 184 dst = ip6_route_output(net, sk, fl);
185 if (dst->error) { 185 if (dst->error) {
186 IP6_INC_STATS(ip6_dst_idev(dst), 186 IP6_INC_STATS(net, ip6_dst_idev(dst),
187 IPSTATS_MIB_OUTNOROUTES); 187 IPSTATS_MIB_OUTNOROUTES);
188 } else if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) { 188 } else if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) {
189 res = 1; 189 res = 1;
@@ -664,7 +664,7 @@ static int icmpv6_rcv(struct sk_buff *skb)
664 skb_set_network_header(skb, nh); 664 skb_set_network_header(skb, nh);
665 } 665 }
666 666
667 ICMP6_INC_STATS_BH(idev, ICMP6_MIB_INMSGS); 667 ICMP6_INC_STATS_BH(dev_net(dev), idev, ICMP6_MIB_INMSGS);
668 668
669 saddr = &ipv6_hdr(skb)->saddr; 669 saddr = &ipv6_hdr(skb)->saddr;
670 daddr = &ipv6_hdr(skb)->daddr; 670 daddr = &ipv6_hdr(skb)->daddr;
@@ -693,7 +693,7 @@ static int icmpv6_rcv(struct sk_buff *skb)
693 693
694 type = hdr->icmp6_type; 694 type = hdr->icmp6_type;
695 695
696 ICMP6MSGIN_INC_STATS_BH(idev, type); 696 ICMP6MSGIN_INC_STATS_BH(dev_net(dev), idev, type);
697 697
698 switch (type) { 698 switch (type) {
699 case ICMPV6_ECHO_REQUEST: 699 case ICMPV6_ECHO_REQUEST:
@@ -772,7 +772,7 @@ static int icmpv6_rcv(struct sk_buff *skb)
772 return 0; 772 return 0;
773 773
774discard_it: 774discard_it:
775 ICMP6_INC_STATS_BH(idev, ICMP6_MIB_INERRORS); 775 ICMP6_INC_STATS_BH(dev_net(dev), idev, ICMP6_MIB_INERRORS);
776drop_no_count: 776drop_no_count:
777 kfree_skb(skb); 777 kfree_skb(skb);
778 return 0; 778 return 0;
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 7e14cccd0561..936f48946e20 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -59,6 +59,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
59 struct ipv6hdr *hdr; 59 struct ipv6hdr *hdr;
60 u32 pkt_len; 60 u32 pkt_len;
61 struct inet6_dev *idev; 61 struct inet6_dev *idev;
62 struct net *net = dev_net(skb->dev);
62 63
63 if (skb->pkt_type == PACKET_OTHERHOST) { 64 if (skb->pkt_type == PACKET_OTHERHOST) {
64 kfree_skb(skb); 65 kfree_skb(skb);
@@ -69,11 +70,11 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
69 70
70 idev = __in6_dev_get(skb->dev); 71 idev = __in6_dev_get(skb->dev);
71 72
72 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INRECEIVES); 73 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INRECEIVES);
73 74
74 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL || 75 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL ||
75 !idev || unlikely(idev->cnf.disable_ipv6)) { 76 !idev || unlikely(idev->cnf.disable_ipv6)) {
76 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDISCARDS); 77 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INDISCARDS);
77 rcu_read_unlock(); 78 rcu_read_unlock();
78 goto out; 79 goto out;
79 } 80 }
@@ -118,11 +119,12 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
118 /* pkt_len may be zero if Jumbo payload option is present */ 119 /* pkt_len may be zero if Jumbo payload option is present */
119 if (pkt_len || hdr->nexthdr != NEXTHDR_HOP) { 120 if (pkt_len || hdr->nexthdr != NEXTHDR_HOP) {
120 if (pkt_len + sizeof(struct ipv6hdr) > skb->len) { 121 if (pkt_len + sizeof(struct ipv6hdr) > skb->len) {
121 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INTRUNCATEDPKTS); 122 IP6_INC_STATS_BH(net,
123 idev, IPSTATS_MIB_INTRUNCATEDPKTS);
122 goto drop; 124 goto drop;
123 } 125 }
124 if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr))) { 126 if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr))) {
125 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INHDRERRORS); 127 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INHDRERRORS);
126 goto drop; 128 goto drop;
127 } 129 }
128 hdr = ipv6_hdr(skb); 130 hdr = ipv6_hdr(skb);
@@ -130,7 +132,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
130 132
131 if (hdr->nexthdr == NEXTHDR_HOP) { 133 if (hdr->nexthdr == NEXTHDR_HOP) {
132 if (ipv6_parse_hopopts(skb) < 0) { 134 if (ipv6_parse_hopopts(skb) < 0) {
133 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INHDRERRORS); 135 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INHDRERRORS);
134 rcu_read_unlock(); 136 rcu_read_unlock();
135 return 0; 137 return 0;
136 } 138 }
@@ -141,7 +143,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
141 return NF_HOOK(PF_INET6, NF_INET_PRE_ROUTING, skb, dev, NULL, 143 return NF_HOOK(PF_INET6, NF_INET_PRE_ROUTING, skb, dev, NULL,
142 ip6_rcv_finish); 144 ip6_rcv_finish);
143err: 145err:
144 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INHDRERRORS); 146 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INHDRERRORS);
145drop: 147drop:
146 rcu_read_unlock(); 148 rcu_read_unlock();
147 kfree_skb(skb); 149 kfree_skb(skb);
@@ -161,6 +163,7 @@ static int ip6_input_finish(struct sk_buff *skb)
161 int nexthdr, raw; 163 int nexthdr, raw;
162 u8 hash; 164 u8 hash;
163 struct inet6_dev *idev; 165 struct inet6_dev *idev;
166 struct net *net = dev_net(skb->dst->dev);
164 167
165 /* 168 /*
166 * Parse extension headers 169 * Parse extension headers
@@ -205,24 +208,25 @@ resubmit:
205 if (ret > 0) 208 if (ret > 0)
206 goto resubmit; 209 goto resubmit;
207 else if (ret == 0) 210 else if (ret == 0)
208 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDELIVERS); 211 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INDELIVERS);
209 } else { 212 } else {
210 if (!raw) { 213 if (!raw) {
211 if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { 214 if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
212 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INUNKNOWNPROTOS); 215 IP6_INC_STATS_BH(net, idev,
216 IPSTATS_MIB_INUNKNOWNPROTOS);
213 icmpv6_send(skb, ICMPV6_PARAMPROB, 217 icmpv6_send(skb, ICMPV6_PARAMPROB,
214 ICMPV6_UNK_NEXTHDR, nhoff, 218 ICMPV6_UNK_NEXTHDR, nhoff,
215 skb->dev); 219 skb->dev);
216 } 220 }
217 } else 221 } else
218 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDELIVERS); 222 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INDELIVERS);
219 kfree_skb(skb); 223 kfree_skb(skb);
220 } 224 }
221 rcu_read_unlock(); 225 rcu_read_unlock();
222 return 0; 226 return 0;
223 227
224discard: 228discard:
225 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDISCARDS); 229 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_INDISCARDS);
226 rcu_read_unlock(); 230 rcu_read_unlock();
227 kfree_skb(skb); 231 kfree_skb(skb);
228 return 0; 232 return 0;
@@ -240,7 +244,8 @@ int ip6_mc_input(struct sk_buff *skb)
240 struct ipv6hdr *hdr; 244 struct ipv6hdr *hdr;
241 int deliver; 245 int deliver;
242 246
243 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCASTPKTS); 247 IP6_INC_STATS_BH(dev_net(skb->dst->dev),
248 ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCASTPKTS);
244 249
245 hdr = ipv6_hdr(skb); 250 hdr = ipv6_hdr(skb);
246 deliver = ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL); 251 deliver = ipv6_chk_mcast_addr(skb->dev, &hdr->daddr, NULL);
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 0e844c2736a7..c77db0b95e26 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -103,7 +103,8 @@ static int ip6_output_finish(struct sk_buff *skb)
103 else if (dst->neighbour) 103 else if (dst->neighbour)
104 return dst->neighbour->output(skb); 104 return dst->neighbour->output(skb);
105 105
106 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); 106 IP6_INC_STATS_BH(dev_net(dst->dev),
107 ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
107 kfree_skb(skb); 108 kfree_skb(skb);
108 return -EINVAL; 109 return -EINVAL;
109 110
@@ -150,13 +151,14 @@ static int ip6_output2(struct sk_buff *skb)
150 ip6_dev_loopback_xmit); 151 ip6_dev_loopback_xmit);
151 152
152 if (ipv6_hdr(skb)->hop_limit == 0) { 153 if (ipv6_hdr(skb)->hop_limit == 0) {
153 IP6_INC_STATS(idev, IPSTATS_MIB_OUTDISCARDS); 154 IP6_INC_STATS(dev_net(dev), idev,
155 IPSTATS_MIB_OUTDISCARDS);
154 kfree_skb(skb); 156 kfree_skb(skb);
155 return 0; 157 return 0;
156 } 158 }
157 } 159 }
158 160
159 IP6_INC_STATS(idev, IPSTATS_MIB_OUTMCASTPKTS); 161 IP6_INC_STATS(dev_net(dev), idev, IPSTATS_MIB_OUTMCASTPKTS);
160 } 162 }
161 163
162 return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb->dev, 164 return NF_HOOK(PF_INET6, NF_INET_POST_ROUTING, skb, NULL, skb->dev,
@@ -175,7 +177,8 @@ int ip6_output(struct sk_buff *skb)
175{ 177{
176 struct inet6_dev *idev = ip6_dst_idev(skb->dst); 178 struct inet6_dev *idev = ip6_dst_idev(skb->dst);
177 if (unlikely(idev->cnf.disable_ipv6)) { 179 if (unlikely(idev->cnf.disable_ipv6)) {
178 IP6_INC_STATS(idev, IPSTATS_MIB_OUTDISCARDS); 180 IP6_INC_STATS(dev_net(skb->dst->dev), idev,
181 IPSTATS_MIB_OUTDISCARDS);
179 kfree_skb(skb); 182 kfree_skb(skb);
180 return 0; 183 return 0;
181 } 184 }
@@ -194,6 +197,7 @@ int ip6_output(struct sk_buff *skb)
194int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, 197int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
195 struct ipv6_txoptions *opt, int ipfragok) 198 struct ipv6_txoptions *opt, int ipfragok)
196{ 199{
200 struct net *net = sock_net(sk);
197 struct ipv6_pinfo *np = inet6_sk(sk); 201 struct ipv6_pinfo *np = inet6_sk(sk);
198 struct in6_addr *first_hop = &fl->fl6_dst; 202 struct in6_addr *first_hop = &fl->fl6_dst;
199 struct dst_entry *dst = skb->dst; 203 struct dst_entry *dst = skb->dst;
@@ -216,7 +220,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
216 if (skb_headroom(skb) < head_room) { 220 if (skb_headroom(skb) < head_room) {
217 struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room); 221 struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room);
218 if (skb2 == NULL) { 222 if (skb2 == NULL) {
219 IP6_INC_STATS(ip6_dst_idev(skb->dst), 223 IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
220 IPSTATS_MIB_OUTDISCARDS); 224 IPSTATS_MIB_OUTDISCARDS);
221 kfree_skb(skb); 225 kfree_skb(skb);
222 return -ENOBUFS; 226 return -ENOBUFS;
@@ -270,7 +274,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
270 274
271 mtu = dst_mtu(dst); 275 mtu = dst_mtu(dst);
272 if ((skb->len <= mtu) || skb->local_df || skb_is_gso(skb)) { 276 if ((skb->len <= mtu) || skb->local_df || skb_is_gso(skb)) {
273 IP6_INC_STATS(ip6_dst_idev(skb->dst), 277 IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
274 IPSTATS_MIB_OUTREQUESTS); 278 IPSTATS_MIB_OUTREQUESTS);
275 return NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev, 279 return NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev,
276 dst_output); 280 dst_output);
@@ -280,7 +284,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
280 printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n"); 284 printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n");
281 skb->dev = dst->dev; 285 skb->dev = dst->dev;
282 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); 286 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
283 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); 287 IP6_INC_STATS(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS);
284 kfree_skb(skb); 288 kfree_skb(skb);
285 return -EMSGSIZE; 289 return -EMSGSIZE;
286} 290}
@@ -422,7 +426,7 @@ int ip6_forward(struct sk_buff *skb)
422 goto drop; 426 goto drop;
423 427
424 if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) { 428 if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) {
425 IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS); 429 IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS);
426 goto drop; 430 goto drop;
427 } 431 }
428 432
@@ -455,7 +459,8 @@ int ip6_forward(struct sk_buff *skb)
455 skb->dev = dst->dev; 459 skb->dev = dst->dev;
456 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 460 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
457 0, skb->dev); 461 0, skb->dev);
458 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS); 462 IP6_INC_STATS_BH(net,
463 ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS);
459 464
460 kfree_skb(skb); 465 kfree_skb(skb);
461 return -ETIMEDOUT; 466 return -ETIMEDOUT;
@@ -468,13 +473,14 @@ int ip6_forward(struct sk_buff *skb)
468 if (proxied > 0) 473 if (proxied > 0)
469 return ip6_input(skb); 474 return ip6_input(skb);
470 else if (proxied < 0) { 475 else if (proxied < 0) {
471 IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS); 476 IP6_INC_STATS(net, ip6_dst_idev(dst),
477 IPSTATS_MIB_INDISCARDS);
472 goto drop; 478 goto drop;
473 } 479 }
474 } 480 }
475 481
476 if (!xfrm6_route_forward(skb)) { 482 if (!xfrm6_route_forward(skb)) {
477 IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS); 483 IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS);
478 goto drop; 484 goto drop;
479 } 485 }
480 dst = skb->dst; 486 dst = skb->dst;
@@ -523,14 +529,16 @@ int ip6_forward(struct sk_buff *skb)
523 /* Again, force OUTPUT device used as source address */ 529 /* Again, force OUTPUT device used as source address */
524 skb->dev = dst->dev; 530 skb->dev = dst->dev;
525 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst_mtu(dst), skb->dev); 531 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst_mtu(dst), skb->dev);
526 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INTOOBIGERRORS); 532 IP6_INC_STATS_BH(net,
527 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_FRAGFAILS); 533 ip6_dst_idev(dst), IPSTATS_MIB_INTOOBIGERRORS);
534 IP6_INC_STATS_BH(net,
535 ip6_dst_idev(dst), IPSTATS_MIB_FRAGFAILS);
528 kfree_skb(skb); 536 kfree_skb(skb);
529 return -EMSGSIZE; 537 return -EMSGSIZE;
530 } 538 }
531 539
532 if (skb_cow(skb, dst->dev->hard_header_len)) { 540 if (skb_cow(skb, dst->dev->hard_header_len)) {
533 IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_OUTDISCARDS); 541 IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTDISCARDS);
534 goto drop; 542 goto drop;
535 } 543 }
536 544
@@ -540,12 +548,12 @@ int ip6_forward(struct sk_buff *skb)
540 548
541 hdr->hop_limit--; 549 hdr->hop_limit--;
542 550
543 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_OUTFORWDATAGRAMS); 551 IP6_INC_STATS_BH(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTFORWDATAGRAMS);
544 return NF_HOOK(PF_INET6, NF_INET_FORWARD, skb, skb->dev, dst->dev, 552 return NF_HOOK(PF_INET6, NF_INET_FORWARD, skb, skb->dev, dst->dev,
545 ip6_forward_finish); 553 ip6_forward_finish);
546 554
547error: 555error:
548 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INADDRERRORS); 556 IP6_INC_STATS_BH(net, ip6_dst_idev(dst), IPSTATS_MIB_INADDRERRORS);
549drop: 557drop:
550 kfree_skb(skb); 558 kfree_skb(skb);
551 return -EINVAL; 559 return -EINVAL;
@@ -613,7 +621,6 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
613 621
614static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) 622static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
615{ 623{
616 struct net_device *dev;
617 struct sk_buff *frag; 624 struct sk_buff *frag;
618 struct rt6_info *rt = (struct rt6_info*)skb->dst; 625 struct rt6_info *rt = (struct rt6_info*)skb->dst;
619 struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL; 626 struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL;
@@ -623,8 +630,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
623 __be32 frag_id = 0; 630 __be32 frag_id = 0;
624 int ptr, offset = 0, err=0; 631 int ptr, offset = 0, err=0;
625 u8 *prevhdr, nexthdr = 0; 632 u8 *prevhdr, nexthdr = 0;
633 struct net *net = dev_net(skb->dst->dev);
626 634
627 dev = rt->u.dst.dev;
628 hlen = ip6_find_1stfragopt(skb, &prevhdr); 635 hlen = ip6_find_1stfragopt(skb, &prevhdr);
629 nexthdr = *prevhdr; 636 nexthdr = *prevhdr;
630 637
@@ -637,7 +644,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
637 if (!skb->local_df) { 644 if (!skb->local_df) {
638 skb->dev = skb->dst->dev; 645 skb->dev = skb->dst->dev;
639 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); 646 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
640 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); 647 IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
648 IPSTATS_MIB_FRAGFAILS);
641 kfree_skb(skb); 649 kfree_skb(skb);
642 return -EMSGSIZE; 650 return -EMSGSIZE;
643 } 651 }
@@ -686,7 +694,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
686 *prevhdr = NEXTHDR_FRAGMENT; 694 *prevhdr = NEXTHDR_FRAGMENT;
687 tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC); 695 tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC);
688 if (!tmp_hdr) { 696 if (!tmp_hdr) {
689 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); 697 IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
698 IPSTATS_MIB_FRAGFAILS);
690 return -ENOMEM; 699 return -ENOMEM;
691 } 700 }
692 701
@@ -737,7 +746,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
737 746
738 err = output(skb); 747 err = output(skb);
739 if(!err) 748 if(!err)
740 IP6_INC_STATS(ip6_dst_idev(&rt->u.dst), IPSTATS_MIB_FRAGCREATES); 749 IP6_INC_STATS(net, ip6_dst_idev(&rt->u.dst),
750 IPSTATS_MIB_FRAGCREATES);
741 751
742 if (err || !frag) 752 if (err || !frag)
743 break; 753 break;
@@ -750,7 +760,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
750 kfree(tmp_hdr); 760 kfree(tmp_hdr);
751 761
752 if (err == 0) { 762 if (err == 0) {
753 IP6_INC_STATS(ip6_dst_idev(&rt->u.dst), IPSTATS_MIB_FRAGOKS); 763 IP6_INC_STATS(net, ip6_dst_idev(&rt->u.dst),
764 IPSTATS_MIB_FRAGOKS);
754 dst_release(&rt->u.dst); 765 dst_release(&rt->u.dst);
755 return 0; 766 return 0;
756 } 767 }
@@ -761,7 +772,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
761 frag = skb; 772 frag = skb;
762 } 773 }
763 774
764 IP6_INC_STATS(ip6_dst_idev(&rt->u.dst), IPSTATS_MIB_FRAGFAILS); 775 IP6_INC_STATS(net, ip6_dst_idev(&rt->u.dst),
776 IPSTATS_MIB_FRAGFAILS);
765 dst_release(&rt->u.dst); 777 dst_release(&rt->u.dst);
766 return err; 778 return err;
767 } 779 }
@@ -795,7 +807,7 @@ slow_path:
795 807
796 if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_ALLOCATED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) { 808 if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_ALLOCATED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) {
797 NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n"); 809 NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n");
798 IP6_INC_STATS(ip6_dst_idev(skb->dst), 810 IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
799 IPSTATS_MIB_FRAGFAILS); 811 IPSTATS_MIB_FRAGFAILS);
800 err = -ENOMEM; 812 err = -ENOMEM;
801 goto fail; 813 goto fail;
@@ -859,15 +871,16 @@ slow_path:
859 if (err) 871 if (err)
860 goto fail; 872 goto fail;
861 873
862 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGCREATES); 874 IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
875 IPSTATS_MIB_FRAGCREATES);
863 } 876 }
864 IP6_INC_STATS(ip6_dst_idev(skb->dst), 877 IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
865 IPSTATS_MIB_FRAGOKS); 878 IPSTATS_MIB_FRAGOKS);
866 kfree_skb(skb); 879 kfree_skb(skb);
867 return err; 880 return err;
868 881
869fail: 882fail:
870 IP6_INC_STATS(ip6_dst_idev(skb->dst), 883 IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
871 IPSTATS_MIB_FRAGFAILS); 884 IPSTATS_MIB_FRAGFAILS);
872 kfree_skb(skb); 885 kfree_skb(skb);
873 return err; 886 return err;
@@ -943,46 +956,46 @@ static int ip6_dst_lookup_tail(struct sock *sk,
943 } 956 }
944 957
945#ifdef CONFIG_IPV6_OPTIMISTIC_DAD 958#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
946 /* 959 /*
947 * Here if the dst entry we've looked up 960 * Here if the dst entry we've looked up
948 * has a neighbour entry that is in the INCOMPLETE 961 * has a neighbour entry that is in the INCOMPLETE
949 * state and the src address from the flow is 962 * state and the src address from the flow is
950 * marked as OPTIMISTIC, we release the found 963 * marked as OPTIMISTIC, we release the found
951 * dst entry and replace it instead with the 964 * dst entry and replace it instead with the
952 * dst entry of the nexthop router 965 * dst entry of the nexthop router
953 */ 966 */
954 if (!((*dst)->neighbour->nud_state & NUD_VALID)) { 967 if ((*dst)->neighbour && !((*dst)->neighbour->nud_state & NUD_VALID)) {
955 struct inet6_ifaddr *ifp; 968 struct inet6_ifaddr *ifp;
956 struct flowi fl_gw; 969 struct flowi fl_gw;
957 int redirect; 970 int redirect;
958 971
959 ifp = ipv6_get_ifaddr(net, &fl->fl6_src, 972 ifp = ipv6_get_ifaddr(net, &fl->fl6_src,
960 (*dst)->dev, 1); 973 (*dst)->dev, 1);
961 974
962 redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC); 975 redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC);
963 if (ifp) 976 if (ifp)
964 in6_ifa_put(ifp); 977 in6_ifa_put(ifp);
965 978
966 if (redirect) { 979 if (redirect) {
967 /* 980 /*
968 * We need to get the dst entry for the 981 * We need to get the dst entry for the
969 * default router instead 982 * default router instead
970 */ 983 */
971 dst_release(*dst); 984 dst_release(*dst);
972 memcpy(&fl_gw, fl, sizeof(struct flowi)); 985 memcpy(&fl_gw, fl, sizeof(struct flowi));
973 memset(&fl_gw.fl6_dst, 0, sizeof(struct in6_addr)); 986 memset(&fl_gw.fl6_dst, 0, sizeof(struct in6_addr));
974 *dst = ip6_route_output(net, sk, &fl_gw); 987 *dst = ip6_route_output(net, sk, &fl_gw);
975 if ((err = (*dst)->error)) 988 if ((err = (*dst)->error))
976 goto out_err_release; 989 goto out_err_release;
977 }
978 } 990 }
991 }
979#endif 992#endif
980 993
981 return 0; 994 return 0;
982 995
983out_err_release: 996out_err_release:
984 if (err == -ENETUNREACH) 997 if (err == -ENETUNREACH)
985 IP6_INC_STATS_BH(NULL, IPSTATS_MIB_OUTNOROUTES); 998 IP6_INC_STATS_BH(net, NULL, IPSTATS_MIB_OUTNOROUTES);
986 dst_release(*dst); 999 dst_release(*dst);
987 *dst = NULL; 1000 *dst = NULL;
988 return err; 1001 return err;
@@ -1387,7 +1400,7 @@ alloc_new_skb:
1387 return 0; 1400 return 0;
1388error: 1401error:
1389 inet->cork.length -= length; 1402 inet->cork.length -= length;
1390 IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS); 1403 IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS);
1391 return err; 1404 return err;
1392} 1405}
1393 1406
@@ -1411,6 +1424,7 @@ int ip6_push_pending_frames(struct sock *sk)
1411 struct in6_addr final_dst_buf, *final_dst = &final_dst_buf; 1424 struct in6_addr final_dst_buf, *final_dst = &final_dst_buf;
1412 struct inet_sock *inet = inet_sk(sk); 1425 struct inet_sock *inet = inet_sk(sk);
1413 struct ipv6_pinfo *np = inet6_sk(sk); 1426 struct ipv6_pinfo *np = inet6_sk(sk);
1427 struct net *net = sock_net(sk);
1414 struct ipv6hdr *hdr; 1428 struct ipv6hdr *hdr;
1415 struct ipv6_txoptions *opt = np->cork.opt; 1429 struct ipv6_txoptions *opt = np->cork.opt;
1416 struct rt6_info *rt = (struct rt6_info *)inet->cork.dst; 1430 struct rt6_info *rt = (struct rt6_info *)inet->cork.dst;
@@ -1464,12 +1478,12 @@ int ip6_push_pending_frames(struct sock *sk)
1464 skb->mark = sk->sk_mark; 1478 skb->mark = sk->sk_mark;
1465 1479
1466 skb->dst = dst_clone(&rt->u.dst); 1480 skb->dst = dst_clone(&rt->u.dst);
1467 IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS); 1481 IP6_INC_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS);
1468 if (proto == IPPROTO_ICMPV6) { 1482 if (proto == IPPROTO_ICMPV6) {
1469 struct inet6_dev *idev = ip6_dst_idev(skb->dst); 1483 struct inet6_dev *idev = ip6_dst_idev(skb->dst);
1470 1484
1471 ICMP6MSGOUT_INC_STATS_BH(idev, icmp6_hdr(skb)->icmp6_type); 1485 ICMP6MSGOUT_INC_STATS_BH(net, idev, icmp6_hdr(skb)->icmp6_type);
1472 ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS); 1486 ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS);
1473 } 1487 }
1474 1488
1475 err = ip6_local_out(skb); 1489 err = ip6_local_out(skb);
@@ -1493,7 +1507,7 @@ void ip6_flush_pending_frames(struct sock *sk)
1493 1507
1494 while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) { 1508 while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) {
1495 if (skb->dst) 1509 if (skb->dst)
1496 IP6_INC_STATS(ip6_dst_idev(skb->dst), 1510 IP6_INC_STATS(sock_net(sk), ip6_dst_idev(skb->dst),
1497 IPSTATS_MIB_OUTDISCARDS); 1511 IPSTATS_MIB_OUTDISCARDS);
1498 kfree_skb(skb); 1512 kfree_skb(skb);
1499 } 1513 }
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 17c7b098cdb0..64ce3d33d9c6 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1050,10 +1050,10 @@ ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
1050 } 1050 }
1051 1051
1052 switch (skb->protocol) { 1052 switch (skb->protocol) {
1053 case __constant_htons(ETH_P_IP): 1053 case htons(ETH_P_IP):
1054 ret = ip4ip6_tnl_xmit(skb, dev); 1054 ret = ip4ip6_tnl_xmit(skb, dev);
1055 break; 1055 break;
1056 case __constant_htons(ETH_P_IPV6): 1056 case htons(ETH_P_IPV6):
1057 ret = ip6ip6_tnl_xmit(skb, dev); 1057 ret = ip6ip6_tnl_xmit(skb, dev);
1058 break; 1058 break;
1059 default: 1059 default:
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 095bc453ff4c..182f8a177e7f 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -1383,7 +1383,8 @@ int ip6mr_ioctl(struct sock *sk, int cmd, void __user *arg)
1383 1383
1384static inline int ip6mr_forward2_finish(struct sk_buff *skb) 1384static inline int ip6mr_forward2_finish(struct sk_buff *skb)
1385{ 1385{
1386 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_OUTFORWDATAGRAMS); 1386 IP6_INC_STATS_BH(dev_net(skb->dst->dev), ip6_dst_idev(skb->dst),
1387 IPSTATS_MIB_OUTFORWDATAGRAMS);
1387 return dst_output(skb); 1388 return dst_output(skb);
1388} 1389}
1389 1390
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index e7c03bcc2788..d7b3c6d398ae 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1446,7 +1446,7 @@ static void mld_sendpack(struct sk_buff *skb)
1446 int err; 1446 int err;
1447 struct flowi fl; 1447 struct flowi fl;
1448 1448
1449 IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS); 1449 IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS);
1450 payload_len = (skb->tail - skb->network_header) - sizeof(*pip6); 1450 payload_len = (skb->tail - skb->network_header) - sizeof(*pip6);
1451 mldlen = skb->tail - skb->transport_header; 1451 mldlen = skb->tail - skb->transport_header;
1452 pip6->payload_len = htons(payload_len); 1452 pip6->payload_len = htons(payload_len);
@@ -1474,11 +1474,11 @@ static void mld_sendpack(struct sk_buff *skb)
1474 dst_output); 1474 dst_output);
1475out: 1475out:
1476 if (!err) { 1476 if (!err) {
1477 ICMP6MSGOUT_INC_STATS_BH(idev, ICMPV6_MLD2_REPORT); 1477 ICMP6MSGOUT_INC_STATS_BH(net, idev, ICMPV6_MLD2_REPORT);
1478 ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS); 1478 ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS);
1479 IP6_INC_STATS_BH(idev, IPSTATS_MIB_OUTMCASTPKTS); 1479 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_OUTMCASTPKTS);
1480 } else 1480 } else
1481 IP6_INC_STATS_BH(idev, IPSTATS_MIB_OUTDISCARDS); 1481 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_OUTDISCARDS);
1482 1482
1483 if (likely(idev != NULL)) 1483 if (likely(idev != NULL))
1484 in6_dev_put(idev); 1484 in6_dev_put(idev);
@@ -1771,7 +1771,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1771 struct flowi fl; 1771 struct flowi fl;
1772 1772
1773 rcu_read_lock(); 1773 rcu_read_lock();
1774 IP6_INC_STATS(__in6_dev_get(dev), 1774 IP6_INC_STATS(net, __in6_dev_get(dev),
1775 IPSTATS_MIB_OUTREQUESTS); 1775 IPSTATS_MIB_OUTREQUESTS);
1776 rcu_read_unlock(); 1776 rcu_read_unlock();
1777 if (type == ICMPV6_MGM_REDUCTION) 1777 if (type == ICMPV6_MGM_REDUCTION)
@@ -1787,7 +1787,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1787 1787
1788 if (skb == NULL) { 1788 if (skb == NULL) {
1789 rcu_read_lock(); 1789 rcu_read_lock();
1790 IP6_INC_STATS(__in6_dev_get(dev), 1790 IP6_INC_STATS(net, __in6_dev_get(dev),
1791 IPSTATS_MIB_OUTDISCARDS); 1791 IPSTATS_MIB_OUTDISCARDS);
1792 rcu_read_unlock(); 1792 rcu_read_unlock();
1793 return; 1793 return;
@@ -1839,11 +1839,11 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1839 dst_output); 1839 dst_output);
1840out: 1840out:
1841 if (!err) { 1841 if (!err) {
1842 ICMP6MSGOUT_INC_STATS(idev, type); 1842 ICMP6MSGOUT_INC_STATS(net, idev, type);
1843 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS); 1843 ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
1844 IP6_INC_STATS(idev, IPSTATS_MIB_OUTMCASTPKTS); 1844 IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTMCASTPKTS);
1845 } else 1845 } else
1846 IP6_INC_STATS(idev, IPSTATS_MIB_OUTDISCARDS); 1846 IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
1847 1847
1848 if (likely(idev != NULL)) 1848 if (likely(idev != NULL))
1849 in6_dev_put(idev); 1849 in6_dev_put(idev);
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index f1c62ba0f56b..840b15780a36 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -516,13 +516,13 @@ static void __ndisc_send(struct net_device *dev,
516 skb->dst = dst; 516 skb->dst = dst;
517 517
518 idev = in6_dev_get(dst->dev); 518 idev = in6_dev_get(dst->dev);
519 IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS); 519 IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS);
520 520
521 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev, 521 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, dst->dev,
522 dst_output); 522 dst_output);
523 if (!err) { 523 if (!err) {
524 ICMP6MSGOUT_INC_STATS(idev, type); 524 ICMP6MSGOUT_INC_STATS(net, idev, type);
525 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS); 525 ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
526 } 526 }
527 527
528 if (likely(idev != NULL)) 528 if (likely(idev != NULL))
@@ -1581,12 +1581,12 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1581 1581
1582 buff->dst = dst; 1582 buff->dst = dst;
1583 idev = in6_dev_get(dst->dev); 1583 idev = in6_dev_get(dst->dev);
1584 IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS); 1584 IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS);
1585 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, buff, NULL, dst->dev, 1585 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, buff, NULL, dst->dev,
1586 dst_output); 1586 dst_output);
1587 if (!err) { 1587 if (!err) {
1588 ICMP6MSGOUT_INC_STATS(idev, NDISC_REDIRECT); 1588 ICMP6MSGOUT_INC_STATS(net, idev, NDISC_REDIRECT);
1589 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS); 1589 ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
1590 } 1590 }
1591 1591
1592 if (likely(idev != NULL)) 1592 if (likely(idev != NULL))
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index 8c6c5e71f210..6b29b03925f1 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -23,7 +23,7 @@ int ip6_route_me_harder(struct sk_buff *skb)
23 .saddr = iph->saddr, } }, 23 .saddr = iph->saddr, } },
24 }; 24 };
25 25
26 dst = ip6_route_output(&init_net, skb->sk, &fl); 26 dst = ip6_route_output(dev_net(skb->dst->dev), skb->sk, &fl);
27 27
28#ifdef CONFIG_XFRM 28#ifdef CONFIG_XFRM
29 if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) && 29 if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
@@ -33,7 +33,8 @@ int ip6_route_me_harder(struct sk_buff *skb)
33#endif 33#endif
34 34
35 if (dst->error) { 35 if (dst->error) {
36 IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); 36 IP6_INC_STATS(&init_net, ip6_dst_idev(dst),
37 IPSTATS_MIB_OUTNOROUTES);
37 LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n"); 38 LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n");
38 dst_release(dst); 39 dst_release(dst);
39 return -EINVAL; 40 return -EINVAL;
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index 0cfcce7b18d8..53ea512c4608 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -55,30 +55,29 @@ config IP6_NF_IPTABLES
55 55
56 To compile it as a module, choose M here. If unsure, say N. 56 To compile it as a module, choose M here. If unsure, say N.
57 57
58if IP6_NF_IPTABLES
59
58# The simple matches. 60# The simple matches.
59config IP6_NF_MATCH_RT 61config IP6_NF_MATCH_AH
60 tristate '"rt" Routing header match support' 62 tristate '"ah" match support'
61 depends on IP6_NF_IPTABLES
62 depends on NETFILTER_ADVANCED 63 depends on NETFILTER_ADVANCED
63 help 64 help
64 rt matching allows you to match packets based on the routing 65 This module allows one to match AH packets.
65 header of the packet.
66 66
67 To compile it as a module, choose M here. If unsure, say N. 67 To compile it as a module, choose M here. If unsure, say N.
68 68
69config IP6_NF_MATCH_OPTS 69config IP6_NF_MATCH_EUI64
70 tristate '"hopbyhop" and "dst" opts header match support' 70 tristate '"eui64" address check'
71 depends on IP6_NF_IPTABLES
72 depends on NETFILTER_ADVANCED 71 depends on NETFILTER_ADVANCED
73 help 72 help
74 This allows one to match packets based on the hop-by-hop 73 This module performs checking on the IPv6 source address
75 and destination options headers of a packet. 74 Compares the last 64 bits with the EUI64 (delivered
75 from the MAC address) address
76 76
77 To compile it as a module, choose M here. If unsure, say N. 77 To compile it as a module, choose M here. If unsure, say N.
78 78
79config IP6_NF_MATCH_FRAG 79config IP6_NF_MATCH_FRAG
80 tristate '"frag" Fragmentation header match support' 80 tristate '"frag" Fragmentation header match support'
81 depends on IP6_NF_IPTABLES
82 depends on NETFILTER_ADVANCED 81 depends on NETFILTER_ADVANCED
83 help 82 help
84 frag matching allows you to match packets based on the fragmentation 83 frag matching allows you to match packets based on the fragmentation
@@ -86,9 +85,17 @@ config IP6_NF_MATCH_FRAG
86 85
87 To compile it as a module, choose M here. If unsure, say N. 86 To compile it as a module, choose M here. If unsure, say N.
88 87
88config IP6_NF_MATCH_OPTS
89 tristate '"hbh" hop-by-hop and "dst" opts header match support'
90 depends on NETFILTER_ADVANCED
91 help
92 This allows one to match packets based on the hop-by-hop
93 and destination options headers of a packet.
94
95 To compile it as a module, choose M here. If unsure, say N.
96
89config IP6_NF_MATCH_HL 97config IP6_NF_MATCH_HL
90 tristate '"hl" match support' 98 tristate '"hl" match support'
91 depends on IP6_NF_IPTABLES
92 depends on NETFILTER_ADVANCED 99 depends on NETFILTER_ADVANCED
93 help 100 help
94 HL matching allows you to match packets based on the hop 101 HL matching allows you to match packets based on the hop
@@ -98,7 +105,6 @@ config IP6_NF_MATCH_HL
98 105
99config IP6_NF_MATCH_IPV6HEADER 106config IP6_NF_MATCH_IPV6HEADER
100 tristate '"ipv6header" IPv6 Extension Headers Match' 107 tristate '"ipv6header" IPv6 Extension Headers Match'
101 depends on IP6_NF_IPTABLES
102 default m if NETFILTER_ADVANCED=n 108 default m if NETFILTER_ADVANCED=n
103 help 109 help
104 This module allows one to match packets based upon 110 This module allows one to match packets based upon
@@ -106,54 +112,40 @@ config IP6_NF_MATCH_IPV6HEADER
106 112
107 To compile it as a module, choose M here. If unsure, say N. 113 To compile it as a module, choose M here. If unsure, say N.
108 114
109config IP6_NF_MATCH_AH
110 tristate '"ah" match support'
111 depends on IP6_NF_IPTABLES
112 depends on NETFILTER_ADVANCED
113 help
114 This module allows one to match AH packets.
115
116 To compile it as a module, choose M here. If unsure, say N.
117
118config IP6_NF_MATCH_MH 115config IP6_NF_MATCH_MH
119 tristate '"mh" match support' 116 tristate '"mh" match support'
120 depends on IP6_NF_IPTABLES
121 depends on NETFILTER_ADVANCED 117 depends on NETFILTER_ADVANCED
122 help 118 help
123 This module allows one to match MH packets. 119 This module allows one to match MH packets.
124 120
125 To compile it as a module, choose M here. If unsure, say N. 121 To compile it as a module, choose M here. If unsure, say N.
126 122
127config IP6_NF_MATCH_EUI64 123config IP6_NF_MATCH_RT
128 tristate '"eui64" address check' 124 tristate '"rt" Routing header match support'
129 depends on IP6_NF_IPTABLES
130 depends on NETFILTER_ADVANCED 125 depends on NETFILTER_ADVANCED
131 help 126 help
132 This module performs checking on the IPv6 source address 127 rt matching allows you to match packets based on the routing
133 Compares the last 64 bits with the EUI64 (delivered 128 header of the packet.
134 from the MAC address) address
135 129
136 To compile it as a module, choose M here. If unsure, say N. 130 To compile it as a module, choose M here. If unsure, say N.
137 131
138# The targets 132# The targets
139config IP6_NF_FILTER 133config IP6_NF_TARGET_LOG
140 tristate "Packet filtering" 134 tristate "LOG target support"
141 depends on IP6_NF_IPTABLES
142 default m if NETFILTER_ADVANCED=n 135 default m if NETFILTER_ADVANCED=n
143 help 136 help
144 Packet filtering defines a table `filter', which has a series of 137 This option adds a `LOG' target, which allows you to create rules in
145 rules for simple packet filtering at local input, forwarding and 138 any iptables table which records the packet header to the syslog.
146 local output. See the man page for iptables(8).
147 139
148 To compile it as a module, choose M here. If unsure, say N. 140 To compile it as a module, choose M here. If unsure, say N.
149 141
150config IP6_NF_TARGET_LOG 142config IP6_NF_FILTER
151 tristate "LOG target support" 143 tristate "Packet filtering"
152 depends on IP6_NF_FILTER
153 default m if NETFILTER_ADVANCED=n 144 default m if NETFILTER_ADVANCED=n
154 help 145 help
155 This option adds a `LOG' target, which allows you to create rules in 146 Packet filtering defines a table `filter', which has a series of
156 any iptables table which records the packet header to the syslog. 147 rules for simple packet filtering at local input, forwarding and
148 local output. See the man page for iptables(8).
157 149
158 To compile it as a module, choose M here. If unsure, say N. 150 To compile it as a module, choose M here. If unsure, say N.
159 151
@@ -170,7 +162,6 @@ config IP6_NF_TARGET_REJECT
170 162
171config IP6_NF_MANGLE 163config IP6_NF_MANGLE
172 tristate "Packet mangling" 164 tristate "Packet mangling"
173 depends on IP6_NF_IPTABLES
174 default m if NETFILTER_ADVANCED=n 165 default m if NETFILTER_ADVANCED=n
175 help 166 help
176 This option adds a `mangle' table to iptables: see the man page for 167 This option adds a `mangle' table to iptables: see the man page for
@@ -198,7 +189,6 @@ config IP6_NF_TARGET_HL
198 189
199config IP6_NF_RAW 190config IP6_NF_RAW
200 tristate 'raw table support (required for TRACE)' 191 tristate 'raw table support (required for TRACE)'
201 depends on IP6_NF_IPTABLES
202 depends on NETFILTER_ADVANCED 192 depends on NETFILTER_ADVANCED
203 help 193 help
204 This option adds a `raw' table to ip6tables. This table is the very 194 This option adds a `raw' table to ip6tables. This table is the very
@@ -211,7 +201,6 @@ config IP6_NF_RAW
211# security table for MAC policy 201# security table for MAC policy
212config IP6_NF_SECURITY 202config IP6_NF_SECURITY
213 tristate "Security table" 203 tristate "Security table"
214 depends on IP6_NF_IPTABLES
215 depends on SECURITY 204 depends on SECURITY
216 depends on NETFILTER_ADVANCED 205 depends on NETFILTER_ADVANCED
217 help 206 help
@@ -220,5 +209,7 @@ config IP6_NF_SECURITY
220 209
221 If unsure, say N. 210 If unsure, say N.
222 211
212endif # IP6_NF_IPTABLES
213
223endmenu 214endmenu
224 215
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 0b4557e03431..a33485dc81cb 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -200,32 +200,25 @@ ip6_checkentry(const struct ip6t_ip6 *ipv6)
200} 200}
201 201
202static unsigned int 202static unsigned int
203ip6t_error(struct sk_buff *skb, 203ip6t_error(struct sk_buff *skb, const struct xt_target_param *par)
204 const struct net_device *in,
205 const struct net_device *out,
206 unsigned int hooknum,
207 const struct xt_target *target,
208 const void *targinfo)
209{ 204{
210 if (net_ratelimit()) 205 if (net_ratelimit())
211 printk("ip6_tables: error: `%s'\n", (char *)targinfo); 206 printk("ip6_tables: error: `%s'\n",
207 (const char *)par->targinfo);
212 208
213 return NF_DROP; 209 return NF_DROP;
214} 210}
215 211
216/* Performance critical - called for every packet */ 212/* Performance critical - called for every packet */
217static inline bool 213static inline bool
218do_match(struct ip6t_entry_match *m, 214do_match(struct ip6t_entry_match *m, const struct sk_buff *skb,
219 const struct sk_buff *skb, 215 struct xt_match_param *par)
220 const struct net_device *in,
221 const struct net_device *out,
222 int offset,
223 unsigned int protoff,
224 bool *hotdrop)
225{ 216{
217 par->match = m->u.kernel.match;
218 par->matchinfo = m->data;
219
226 /* Stop iteration if it doesn't match */ 220 /* Stop iteration if it doesn't match */
227 if (!m->u.kernel.match->match(skb, in, out, m->u.kernel.match, m->data, 221 if (!m->u.kernel.match->match(skb, par))
228 offset, protoff, hotdrop))
229 return true; 222 return true;
230 else 223 else
231 return false; 224 return false;
@@ -355,8 +348,6 @@ ip6t_do_table(struct sk_buff *skb,
355 struct xt_table *table) 348 struct xt_table *table)
356{ 349{
357 static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); 350 static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long))));
358 int offset = 0;
359 unsigned int protoff = 0;
360 bool hotdrop = false; 351 bool hotdrop = false;
361 /* Initializing verdict to NF_DROP keeps gcc happy. */ 352 /* Initializing verdict to NF_DROP keeps gcc happy. */
362 unsigned int verdict = NF_DROP; 353 unsigned int verdict = NF_DROP;
@@ -364,6 +355,8 @@ ip6t_do_table(struct sk_buff *skb,
364 void *table_base; 355 void *table_base;
365 struct ip6t_entry *e, *back; 356 struct ip6t_entry *e, *back;
366 struct xt_table_info *private; 357 struct xt_table_info *private;
358 struct xt_match_param mtpar;
359 struct xt_target_param tgpar;
367 360
368 /* Initialization */ 361 /* Initialization */
369 indev = in ? in->name : nulldevname; 362 indev = in ? in->name : nulldevname;
@@ -374,6 +367,11 @@ ip6t_do_table(struct sk_buff *skb,
374 * things we don't know, ie. tcp syn flag or ports). If the 367 * things we don't know, ie. tcp syn flag or ports). If the
375 * rule is also a fragment-specific rule, non-fragments won't 368 * rule is also a fragment-specific rule, non-fragments won't
376 * match it. */ 369 * match it. */
370 mtpar.hotdrop = &hotdrop;
371 mtpar.in = tgpar.in = in;
372 mtpar.out = tgpar.out = out;
373 mtpar.family = tgpar.family = NFPROTO_IPV6;
374 tgpar.hooknum = hook;
377 375
378 read_lock_bh(&table->lock); 376 read_lock_bh(&table->lock);
379 IP_NF_ASSERT(table->valid_hooks & (1 << hook)); 377 IP_NF_ASSERT(table->valid_hooks & (1 << hook));
@@ -388,12 +386,10 @@ ip6t_do_table(struct sk_buff *skb,
388 IP_NF_ASSERT(e); 386 IP_NF_ASSERT(e);
389 IP_NF_ASSERT(back); 387 IP_NF_ASSERT(back);
390 if (ip6_packet_match(skb, indev, outdev, &e->ipv6, 388 if (ip6_packet_match(skb, indev, outdev, &e->ipv6,
391 &protoff, &offset, &hotdrop)) { 389 &mtpar.thoff, &mtpar.fragoff, &hotdrop)) {
392 struct ip6t_entry_target *t; 390 struct ip6t_entry_target *t;
393 391
394 if (IP6T_MATCH_ITERATE(e, do_match, 392 if (IP6T_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0)
395 skb, in, out,
396 offset, protoff, &hotdrop) != 0)
397 goto no_match; 393 goto no_match;
398 394
399 ADD_COUNTER(e->counters, 395 ADD_COUNTER(e->counters,
@@ -441,15 +437,15 @@ ip6t_do_table(struct sk_buff *skb,
441 } else { 437 } else {
442 /* Targets which reenter must return 438 /* Targets which reenter must return
443 abs. verdicts */ 439 abs. verdicts */
440 tgpar.target = t->u.kernel.target;
441 tgpar.targinfo = t->data;
442
444#ifdef CONFIG_NETFILTER_DEBUG 443#ifdef CONFIG_NETFILTER_DEBUG
445 ((struct ip6t_entry *)table_base)->comefrom 444 ((struct ip6t_entry *)table_base)->comefrom
446 = 0xeeeeeeec; 445 = 0xeeeeeeec;
447#endif 446#endif
448 verdict = t->u.kernel.target->target(skb, 447 verdict = t->u.kernel.target->target(skb,
449 in, out, 448 &tgpar);
450 hook,
451 t->u.kernel.target,
452 t->data);
453 449
454#ifdef CONFIG_NETFILTER_DEBUG 450#ifdef CONFIG_NETFILTER_DEBUG
455 if (((struct ip6t_entry *)table_base)->comefrom 451 if (((struct ip6t_entry *)table_base)->comefrom
@@ -602,12 +598,17 @@ mark_source_chains(struct xt_table_info *newinfo,
602static int 598static int
603cleanup_match(struct ip6t_entry_match *m, unsigned int *i) 599cleanup_match(struct ip6t_entry_match *m, unsigned int *i)
604{ 600{
601 struct xt_mtdtor_param par;
602
605 if (i && (*i)-- == 0) 603 if (i && (*i)-- == 0)
606 return 1; 604 return 1;
607 605
608 if (m->u.kernel.match->destroy) 606 par.match = m->u.kernel.match;
609 m->u.kernel.match->destroy(m->u.kernel.match, m->data); 607 par.matchinfo = m->data;
610 module_put(m->u.kernel.match->me); 608 par.family = NFPROTO_IPV6;
609 if (par.match->destroy != NULL)
610 par.match->destroy(&par);
611 module_put(par.match->me);
611 return 0; 612 return 0;
612} 613}
613 614
@@ -632,34 +633,28 @@ check_entry(struct ip6t_entry *e, const char *name)
632 return 0; 633 return 0;
633} 634}
634 635
635static int check_match(struct ip6t_entry_match *m, const char *name, 636static int check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par,
636 const struct ip6t_ip6 *ipv6, 637 unsigned int *i)
637 unsigned int hookmask, unsigned int *i)
638{ 638{
639 struct xt_match *match; 639 const struct ip6t_ip6 *ipv6 = par->entryinfo;
640 int ret; 640 int ret;
641 641
642 match = m->u.kernel.match; 642 par->match = m->u.kernel.match;
643 ret = xt_check_match(match, AF_INET6, m->u.match_size - sizeof(*m), 643 par->matchinfo = m->data;
644 name, hookmask, ipv6->proto, 644
645 ipv6->invflags & IP6T_INV_PROTO); 645 ret = xt_check_match(par, m->u.match_size - sizeof(*m),
646 if (!ret && m->u.kernel.match->checkentry 646 ipv6->proto, ipv6->invflags & IP6T_INV_PROTO);
647 && !m->u.kernel.match->checkentry(name, ipv6, match, m->data, 647 if (ret < 0) {
648 hookmask)) {
649 duprintf("ip_tables: check failed for `%s'.\n", 648 duprintf("ip_tables: check failed for `%s'.\n",
650 m->u.kernel.match->name); 649 par.match->name);
651 ret = -EINVAL; 650 return ret;
652 } 651 }
653 if (!ret) 652 ++*i;
654 (*i)++; 653 return 0;
655 return ret;
656} 654}
657 655
658static int 656static int
659find_check_match(struct ip6t_entry_match *m, 657find_check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par,
660 const char *name,
661 const struct ip6t_ip6 *ipv6,
662 unsigned int hookmask,
663 unsigned int *i) 658 unsigned int *i)
664{ 659{
665 struct xt_match *match; 660 struct xt_match *match;
@@ -674,7 +669,7 @@ find_check_match(struct ip6t_entry_match *m,
674 } 669 }
675 m->u.kernel.match = match; 670 m->u.kernel.match = match;
676 671
677 ret = check_match(m, name, ipv6, hookmask, i); 672 ret = check_match(m, par, i);
678 if (ret) 673 if (ret)
679 goto err; 674 goto err;
680 675
@@ -686,23 +681,26 @@ err:
686 681
687static int check_target(struct ip6t_entry *e, const char *name) 682static int check_target(struct ip6t_entry *e, const char *name)
688{ 683{
689 struct ip6t_entry_target *t; 684 struct ip6t_entry_target *t = ip6t_get_target(e);
690 struct xt_target *target; 685 struct xt_tgchk_param par = {
686 .table = name,
687 .entryinfo = e,
688 .target = t->u.kernel.target,
689 .targinfo = t->data,
690 .hook_mask = e->comefrom,
691 .family = NFPROTO_IPV6,
692 };
691 int ret; 693 int ret;
692 694
693 t = ip6t_get_target(e); 695 t = ip6t_get_target(e);
694 target = t->u.kernel.target; 696 ret = xt_check_target(&par, t->u.target_size - sizeof(*t),
695 ret = xt_check_target(target, AF_INET6, t->u.target_size - sizeof(*t), 697 e->ipv6.proto, e->ipv6.invflags & IP6T_INV_PROTO);
696 name, e->comefrom, e->ipv6.proto, 698 if (ret < 0) {
697 e->ipv6.invflags & IP6T_INV_PROTO);
698 if (!ret && t->u.kernel.target->checkentry
699 && !t->u.kernel.target->checkentry(name, e, target, t->data,
700 e->comefrom)) {
701 duprintf("ip_tables: check failed for `%s'.\n", 699 duprintf("ip_tables: check failed for `%s'.\n",
702 t->u.kernel.target->name); 700 t->u.kernel.target->name);
703 ret = -EINVAL; 701 return ret;
704 } 702 }
705 return ret; 703 return 0;
706} 704}
707 705
708static int 706static int
@@ -713,14 +711,18 @@ find_check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
713 struct xt_target *target; 711 struct xt_target *target;
714 int ret; 712 int ret;
715 unsigned int j; 713 unsigned int j;
714 struct xt_mtchk_param mtpar;
716 715
717 ret = check_entry(e, name); 716 ret = check_entry(e, name);
718 if (ret) 717 if (ret)
719 return ret; 718 return ret;
720 719
721 j = 0; 720 j = 0;
722 ret = IP6T_MATCH_ITERATE(e, find_check_match, name, &e->ipv6, 721 mtpar.table = name;
723 e->comefrom, &j); 722 mtpar.entryinfo = &e->ipv6;
723 mtpar.hook_mask = e->comefrom;
724 mtpar.family = NFPROTO_IPV6;
725 ret = IP6T_MATCH_ITERATE(e, find_check_match, &mtpar, &j);
724 if (ret != 0) 726 if (ret != 0)
725 goto cleanup_matches; 727 goto cleanup_matches;
726 728
@@ -795,6 +797,7 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
795static int 797static int
796cleanup_entry(struct ip6t_entry *e, unsigned int *i) 798cleanup_entry(struct ip6t_entry *e, unsigned int *i)
797{ 799{
800 struct xt_tgdtor_param par;
798 struct ip6t_entry_target *t; 801 struct ip6t_entry_target *t;
799 802
800 if (i && (*i)-- == 0) 803 if (i && (*i)-- == 0)
@@ -803,9 +806,13 @@ cleanup_entry(struct ip6t_entry *e, unsigned int *i)
803 /* Cleanup all matches */ 806 /* Cleanup all matches */
804 IP6T_MATCH_ITERATE(e, cleanup_match, NULL); 807 IP6T_MATCH_ITERATE(e, cleanup_match, NULL);
805 t = ip6t_get_target(e); 808 t = ip6t_get_target(e);
806 if (t->u.kernel.target->destroy) 809
807 t->u.kernel.target->destroy(t->u.kernel.target, t->data); 810 par.target = t->u.kernel.target;
808 module_put(t->u.kernel.target->me); 811 par.targinfo = t->data;
812 par.family = NFPROTO_IPV6;
813 if (par.target->destroy != NULL)
814 par.target->destroy(&par);
815 module_put(par.target->me);
809 return 0; 816 return 0;
810} 817}
811 818
@@ -1677,10 +1684,14 @@ static int compat_check_entry(struct ip6t_entry *e, const char *name,
1677{ 1684{
1678 unsigned int j; 1685 unsigned int j;
1679 int ret; 1686 int ret;
1687 struct xt_mtchk_param mtpar;
1680 1688
1681 j = 0; 1689 j = 0;
1682 ret = IP6T_MATCH_ITERATE(e, check_match, name, &e->ipv6, 1690 mtpar.table = name;
1683 e->comefrom, &j); 1691 mtpar.entryinfo = &e->ipv6;
1692 mtpar.hook_mask = e->comefrom;
1693 mtpar.family = NFPROTO_IPV6;
1694 ret = IP6T_MATCH_ITERATE(e, check_match, &mtpar, &j);
1684 if (ret) 1695 if (ret)
1685 goto cleanup_matches; 1696 goto cleanup_matches;
1686 1697
@@ -2146,30 +2157,23 @@ icmp6_type_code_match(u_int8_t test_type, u_int8_t min_code, u_int8_t max_code,
2146} 2157}
2147 2158
2148static bool 2159static bool
2149icmp6_match(const struct sk_buff *skb, 2160icmp6_match(const struct sk_buff *skb, const struct xt_match_param *par)
2150 const struct net_device *in,
2151 const struct net_device *out,
2152 const struct xt_match *match,
2153 const void *matchinfo,
2154 int offset,
2155 unsigned int protoff,
2156 bool *hotdrop)
2157{ 2161{
2158 const struct icmp6hdr *ic; 2162 const struct icmp6hdr *ic;
2159 struct icmp6hdr _icmph; 2163 struct icmp6hdr _icmph;
2160 const struct ip6t_icmp *icmpinfo = matchinfo; 2164 const struct ip6t_icmp *icmpinfo = par->matchinfo;
2161 2165
2162 /* Must not be a fragment. */ 2166 /* Must not be a fragment. */
2163 if (offset) 2167 if (par->fragoff != 0)
2164 return false; 2168 return false;
2165 2169
2166 ic = skb_header_pointer(skb, protoff, sizeof(_icmph), &_icmph); 2170 ic = skb_header_pointer(skb, par->thoff, sizeof(_icmph), &_icmph);
2167 if (ic == NULL) { 2171 if (ic == NULL) {
2168 /* We've been asked to examine this packet, and we 2172 /* We've been asked to examine this packet, and we
2169 * can't. Hence, no choice but to drop. 2173 * can't. Hence, no choice but to drop.
2170 */ 2174 */
2171 duprintf("Dropping evil ICMP tinygram.\n"); 2175 duprintf("Dropping evil ICMP tinygram.\n");
2172 *hotdrop = true; 2176 *par->hotdrop = true;
2173 return false; 2177 return false;
2174 } 2178 }
2175 2179
@@ -2181,14 +2185,9 @@ icmp6_match(const struct sk_buff *skb,
2181} 2185}
2182 2186
2183/* Called when user tries to insert an entry of this type. */ 2187/* Called when user tries to insert an entry of this type. */
2184static bool 2188static bool icmp6_checkentry(const struct xt_mtchk_param *par)
2185icmp6_checkentry(const char *tablename,
2186 const void *entry,
2187 const struct xt_match *match,
2188 void *matchinfo,
2189 unsigned int hook_mask)
2190{ 2189{
2191 const struct ip6t_icmp *icmpinfo = matchinfo; 2190 const struct ip6t_icmp *icmpinfo = par->matchinfo;
2192 2191
2193 /* Must specify no unknown invflags */ 2192 /* Must specify no unknown invflags */
2194 return !(icmpinfo->invflags & ~IP6T_ICMP_INV); 2193 return !(icmpinfo->invflags & ~IP6T_ICMP_INV);
diff --git a/net/ipv6/netfilter/ip6t_HL.c b/net/ipv6/netfilter/ip6t_HL.c
index d5f8fd5f29d3..27b5adf670a2 100644
--- a/net/ipv6/netfilter/ip6t_HL.c
+++ b/net/ipv6/netfilter/ip6t_HL.c
@@ -19,12 +19,10 @@ MODULE_DESCRIPTION("Xtables: IPv6 Hop Limit field modification target");
19MODULE_LICENSE("GPL"); 19MODULE_LICENSE("GPL");
20 20
21static unsigned int 21static unsigned int
22hl_tg6(struct sk_buff *skb, const struct net_device *in, 22hl_tg6(struct sk_buff *skb, const struct xt_target_param *par)
23 const struct net_device *out, unsigned int hooknum,
24 const struct xt_target *target, const void *targinfo)
25{ 23{
26 struct ipv6hdr *ip6h; 24 struct ipv6hdr *ip6h;
27 const struct ip6t_HL_info *info = targinfo; 25 const struct ip6t_HL_info *info = par->targinfo;
28 int new_hl; 26 int new_hl;
29 27
30 if (!skb_make_writable(skb, skb->len)) 28 if (!skb_make_writable(skb, skb->len))
@@ -56,12 +54,9 @@ hl_tg6(struct sk_buff *skb, const struct net_device *in,
56 return XT_CONTINUE; 54 return XT_CONTINUE;
57} 55}
58 56
59static bool 57static bool hl_tg6_check(const struct xt_tgchk_param *par)
60hl_tg6_check(const char *tablename, const void *entry,
61 const struct xt_target *target, void *targinfo,
62 unsigned int hook_mask)
63{ 58{
64 const struct ip6t_HL_info *info = targinfo; 59 const struct ip6t_HL_info *info = par->targinfo;
65 60
66 if (info->mode > IP6T_HL_MAXMODE) { 61 if (info->mode > IP6T_HL_MAXMODE) {
67 printk(KERN_WARNING "ip6t_HL: invalid or unknown Mode %u\n", 62 printk(KERN_WARNING "ip6t_HL: invalid or unknown Mode %u\n",
@@ -78,7 +73,7 @@ hl_tg6_check(const char *tablename, const void *entry,
78 73
79static struct xt_target hl_tg6_reg __read_mostly = { 74static struct xt_target hl_tg6_reg __read_mostly = {
80 .name = "HL", 75 .name = "HL",
81 .family = AF_INET6, 76 .family = NFPROTO_IPV6,
82 .target = hl_tg6, 77 .target = hl_tg6,
83 .targetsize = sizeof(struct ip6t_HL_info), 78 .targetsize = sizeof(struct ip6t_HL_info),
84 .table = "mangle", 79 .table = "mangle",
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
index 3a2316974f83..caa441d09567 100644
--- a/net/ipv6/netfilter/ip6t_LOG.c
+++ b/net/ipv6/netfilter/ip6t_LOG.c
@@ -385,7 +385,7 @@ static struct nf_loginfo default_loginfo = {
385}; 385};
386 386
387static void 387static void
388ip6t_log_packet(unsigned int pf, 388ip6t_log_packet(u_int8_t pf,
389 unsigned int hooknum, 389 unsigned int hooknum,
390 const struct sk_buff *skb, 390 const struct sk_buff *skb,
391 const struct net_device *in, 391 const struct net_device *in,
@@ -438,28 +438,24 @@ ip6t_log_packet(unsigned int pf,
438} 438}
439 439
440static unsigned int 440static unsigned int
441log_tg6(struct sk_buff *skb, const struct net_device *in, 441log_tg6(struct sk_buff *skb, const struct xt_target_param *par)
442 const struct net_device *out, unsigned int hooknum,
443 const struct xt_target *target, const void *targinfo)
444{ 442{
445 const struct ip6t_log_info *loginfo = targinfo; 443 const struct ip6t_log_info *loginfo = par->targinfo;
446 struct nf_loginfo li; 444 struct nf_loginfo li;
447 445
448 li.type = NF_LOG_TYPE_LOG; 446 li.type = NF_LOG_TYPE_LOG;
449 li.u.log.level = loginfo->level; 447 li.u.log.level = loginfo->level;
450 li.u.log.logflags = loginfo->logflags; 448 li.u.log.logflags = loginfo->logflags;
451 449
452 ip6t_log_packet(PF_INET6, hooknum, skb, in, out, &li, loginfo->prefix); 450 ip6t_log_packet(NFPROTO_IPV6, par->hooknum, skb, par->in, par->out,
451 &li, loginfo->prefix);
453 return XT_CONTINUE; 452 return XT_CONTINUE;
454} 453}
455 454
456 455
457static bool 456static bool log_tg6_check(const struct xt_tgchk_param *par)
458log_tg6_check(const char *tablename, const void *entry,
459 const struct xt_target *target, void *targinfo,
460 unsigned int hook_mask)
461{ 457{
462 const struct ip6t_log_info *loginfo = targinfo; 458 const struct ip6t_log_info *loginfo = par->targinfo;
463 459
464 if (loginfo->level >= 8) { 460 if (loginfo->level >= 8) {
465 pr_debug("LOG: level %u >= 8\n", loginfo->level); 461 pr_debug("LOG: level %u >= 8\n", loginfo->level);
@@ -475,7 +471,7 @@ log_tg6_check(const char *tablename, const void *entry,
475 471
476static struct xt_target log_tg6_reg __read_mostly = { 472static struct xt_target log_tg6_reg __read_mostly = {
477 .name = "LOG", 473 .name = "LOG",
478 .family = AF_INET6, 474 .family = NFPROTO_IPV6,
479 .target = log_tg6, 475 .target = log_tg6,
480 .targetsize = sizeof(struct ip6t_log_info), 476 .targetsize = sizeof(struct ip6t_log_info),
481 .checkentry = log_tg6_check, 477 .checkentry = log_tg6_check,
@@ -495,7 +491,7 @@ static int __init log_tg6_init(void)
495 ret = xt_register_target(&log_tg6_reg); 491 ret = xt_register_target(&log_tg6_reg);
496 if (ret < 0) 492 if (ret < 0)
497 return ret; 493 return ret;
498 nf_log_register(PF_INET6, &ip6t_logger); 494 nf_log_register(NFPROTO_IPV6, &ip6t_logger);
499 return 0; 495 return 0;
500} 496}
501 497
diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c
index 44c8d65a2431..0981b4ccb8b1 100644
--- a/net/ipv6/netfilter/ip6t_REJECT.c
+++ b/net/ipv6/netfilter/ip6t_REJECT.c
@@ -35,7 +35,7 @@ MODULE_DESCRIPTION("Xtables: packet \"rejection\" target for IPv6");
35MODULE_LICENSE("GPL"); 35MODULE_LICENSE("GPL");
36 36
37/* Send RST reply */ 37/* Send RST reply */
38static void send_reset(struct sk_buff *oldskb) 38static void send_reset(struct net *net, struct sk_buff *oldskb)
39{ 39{
40 struct sk_buff *nskb; 40 struct sk_buff *nskb;
41 struct tcphdr otcph, *tcph; 41 struct tcphdr otcph, *tcph;
@@ -94,7 +94,7 @@ static void send_reset(struct sk_buff *oldskb)
94 fl.fl_ip_sport = otcph.dest; 94 fl.fl_ip_sport = otcph.dest;
95 fl.fl_ip_dport = otcph.source; 95 fl.fl_ip_dport = otcph.source;
96 security_skb_classify_flow(oldskb, &fl); 96 security_skb_classify_flow(oldskb, &fl);
97 dst = ip6_route_output(&init_net, NULL, &fl); 97 dst = ip6_route_output(net, NULL, &fl);
98 if (dst == NULL) 98 if (dst == NULL)
99 return; 99 return;
100 if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0)) 100 if (dst->error || xfrm_lookup(&dst, &fl, NULL, 0))
@@ -163,20 +163,20 @@ static void send_reset(struct sk_buff *oldskb)
163} 163}
164 164
165static inline void 165static inline void
166send_unreach(struct sk_buff *skb_in, unsigned char code, unsigned int hooknum) 166send_unreach(struct net *net, struct sk_buff *skb_in, unsigned char code,
167 unsigned int hooknum)
167{ 168{
168 if (hooknum == NF_INET_LOCAL_OUT && skb_in->dev == NULL) 169 if (hooknum == NF_INET_LOCAL_OUT && skb_in->dev == NULL)
169 skb_in->dev = init_net.loopback_dev; 170 skb_in->dev = net->loopback_dev;
170 171
171 icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0, NULL); 172 icmpv6_send(skb_in, ICMPV6_DEST_UNREACH, code, 0, NULL);
172} 173}
173 174
174static unsigned int 175static unsigned int
175reject_tg6(struct sk_buff *skb, const struct net_device *in, 176reject_tg6(struct sk_buff *skb, const struct xt_target_param *par)
176 const struct net_device *out, unsigned int hooknum,
177 const struct xt_target *target, const void *targinfo)
178{ 177{
179 const struct ip6t_reject_info *reject = targinfo; 178 const struct ip6t_reject_info *reject = par->targinfo;
179 struct net *net = dev_net((par->in != NULL) ? par->in : par->out);
180 180
181 pr_debug("%s: medium point\n", __func__); 181 pr_debug("%s: medium point\n", __func__);
182 /* WARNING: This code causes reentry within ip6tables. 182 /* WARNING: This code causes reentry within ip6tables.
@@ -184,25 +184,25 @@ reject_tg6(struct sk_buff *skb, const struct net_device *in,
184 must return an absolute verdict. --RR */ 184 must return an absolute verdict. --RR */
185 switch (reject->with) { 185 switch (reject->with) {
186 case IP6T_ICMP6_NO_ROUTE: 186 case IP6T_ICMP6_NO_ROUTE:
187 send_unreach(skb, ICMPV6_NOROUTE, hooknum); 187 send_unreach(net, skb, ICMPV6_NOROUTE, par->hooknum);
188 break; 188 break;
189 case IP6T_ICMP6_ADM_PROHIBITED: 189 case IP6T_ICMP6_ADM_PROHIBITED:
190 send_unreach(skb, ICMPV6_ADM_PROHIBITED, hooknum); 190 send_unreach(net, skb, ICMPV6_ADM_PROHIBITED, par->hooknum);
191 break; 191 break;
192 case IP6T_ICMP6_NOT_NEIGHBOUR: 192 case IP6T_ICMP6_NOT_NEIGHBOUR:
193 send_unreach(skb, ICMPV6_NOT_NEIGHBOUR, hooknum); 193 send_unreach(net, skb, ICMPV6_NOT_NEIGHBOUR, par->hooknum);
194 break; 194 break;
195 case IP6T_ICMP6_ADDR_UNREACH: 195 case IP6T_ICMP6_ADDR_UNREACH:
196 send_unreach(skb, ICMPV6_ADDR_UNREACH, hooknum); 196 send_unreach(net, skb, ICMPV6_ADDR_UNREACH, par->hooknum);
197 break; 197 break;
198 case IP6T_ICMP6_PORT_UNREACH: 198 case IP6T_ICMP6_PORT_UNREACH:
199 send_unreach(skb, ICMPV6_PORT_UNREACH, hooknum); 199 send_unreach(net, skb, ICMPV6_PORT_UNREACH, par->hooknum);
200 break; 200 break;
201 case IP6T_ICMP6_ECHOREPLY: 201 case IP6T_ICMP6_ECHOREPLY:
202 /* Do nothing */ 202 /* Do nothing */
203 break; 203 break;
204 case IP6T_TCP_RESET: 204 case IP6T_TCP_RESET:
205 send_reset(skb); 205 send_reset(net, skb);
206 break; 206 break;
207 default: 207 default:
208 if (net_ratelimit()) 208 if (net_ratelimit())
@@ -213,13 +213,10 @@ reject_tg6(struct sk_buff *skb, const struct net_device *in,
213 return NF_DROP; 213 return NF_DROP;
214} 214}
215 215
216static bool 216static bool reject_tg6_check(const struct xt_tgchk_param *par)
217reject_tg6_check(const char *tablename, const void *entry,
218 const struct xt_target *target, void *targinfo,
219 unsigned int hook_mask)
220{ 217{
221 const struct ip6t_reject_info *rejinfo = targinfo; 218 const struct ip6t_reject_info *rejinfo = par->targinfo;
222 const struct ip6t_entry *e = entry; 219 const struct ip6t_entry *e = par->entryinfo;
223 220
224 if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) { 221 if (rejinfo->with == IP6T_ICMP6_ECHOREPLY) {
225 printk("ip6t_REJECT: ECHOREPLY is not supported.\n"); 222 printk("ip6t_REJECT: ECHOREPLY is not supported.\n");
@@ -237,7 +234,7 @@ reject_tg6_check(const char *tablename, const void *entry,
237 234
238static struct xt_target reject_tg6_reg __read_mostly = { 235static struct xt_target reject_tg6_reg __read_mostly = {
239 .name = "REJECT", 236 .name = "REJECT",
240 .family = AF_INET6, 237 .family = NFPROTO_IPV6,
241 .target = reject_tg6, 238 .target = reject_tg6,
242 .targetsize = sizeof(struct ip6t_reject_info), 239 .targetsize = sizeof(struct ip6t_reject_info),
243 .table = "filter", 240 .table = "filter",
diff --git a/net/ipv6/netfilter/ip6t_ah.c b/net/ipv6/netfilter/ip6t_ah.c
index 429629fd63b6..3a82f24746b9 100644
--- a/net/ipv6/netfilter/ip6t_ah.c
+++ b/net/ipv6/netfilter/ip6t_ah.c
@@ -36,14 +36,11 @@ spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
36 return r; 36 return r;
37} 37}
38 38
39static bool 39static bool ah_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
40ah_mt6(const struct sk_buff *skb, const struct net_device *in,
41 const struct net_device *out, const struct xt_match *match,
42 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
43{ 40{
44 struct ip_auth_hdr _ah; 41 struct ip_auth_hdr _ah;
45 const struct ip_auth_hdr *ah; 42 const struct ip_auth_hdr *ah;
46 const struct ip6t_ah *ahinfo = matchinfo; 43 const struct ip6t_ah *ahinfo = par->matchinfo;
47 unsigned int ptr; 44 unsigned int ptr;
48 unsigned int hdrlen = 0; 45 unsigned int hdrlen = 0;
49 int err; 46 int err;
@@ -51,13 +48,13 @@ ah_mt6(const struct sk_buff *skb, const struct net_device *in,
51 err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL); 48 err = ipv6_find_hdr(skb, &ptr, NEXTHDR_AUTH, NULL);
52 if (err < 0) { 49 if (err < 0) {
53 if (err != -ENOENT) 50 if (err != -ENOENT)
54 *hotdrop = true; 51 *par->hotdrop = true;
55 return false; 52 return false;
56 } 53 }
57 54
58 ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah); 55 ah = skb_header_pointer(skb, ptr, sizeof(_ah), &_ah);
59 if (ah == NULL) { 56 if (ah == NULL) {
60 *hotdrop = true; 57 *par->hotdrop = true;
61 return false; 58 return false;
62 } 59 }
63 60
@@ -93,13 +90,9 @@ ah_mt6(const struct sk_buff *skb, const struct net_device *in,
93 !(ahinfo->hdrres && ah->reserved); 90 !(ahinfo->hdrres && ah->reserved);
94} 91}
95 92
96/* Called when user tries to insert an entry of this type. */ 93static bool ah_mt6_check(const struct xt_mtchk_param *par)
97static bool
98ah_mt6_check(const char *tablename, const void *entry,
99 const struct xt_match *match, void *matchinfo,
100 unsigned int hook_mask)
101{ 94{
102 const struct ip6t_ah *ahinfo = matchinfo; 95 const struct ip6t_ah *ahinfo = par->matchinfo;
103 96
104 if (ahinfo->invflags & ~IP6T_AH_INV_MASK) { 97 if (ahinfo->invflags & ~IP6T_AH_INV_MASK) {
105 pr_debug("ip6t_ah: unknown flags %X\n", ahinfo->invflags); 98 pr_debug("ip6t_ah: unknown flags %X\n", ahinfo->invflags);
@@ -110,7 +103,7 @@ ah_mt6_check(const char *tablename, const void *entry,
110 103
111static struct xt_match ah_mt6_reg __read_mostly = { 104static struct xt_match ah_mt6_reg __read_mostly = {
112 .name = "ah", 105 .name = "ah",
113 .family = AF_INET6, 106 .family = NFPROTO_IPV6,
114 .match = ah_mt6, 107 .match = ah_mt6,
115 .matchsize = sizeof(struct ip6t_ah), 108 .matchsize = sizeof(struct ip6t_ah),
116 .checkentry = ah_mt6_check, 109 .checkentry = ah_mt6_check,
diff --git a/net/ipv6/netfilter/ip6t_eui64.c b/net/ipv6/netfilter/ip6t_eui64.c
index 8f331f12b2ec..db610bacbcce 100644
--- a/net/ipv6/netfilter/ip6t_eui64.c
+++ b/net/ipv6/netfilter/ip6t_eui64.c
@@ -20,18 +20,15 @@ MODULE_LICENSE("GPL");
20MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>"); 20MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
21 21
22static bool 22static bool
23eui64_mt6(const struct sk_buff *skb, const struct net_device *in, 23eui64_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
24 const struct net_device *out, const struct xt_match *match,
25 const void *matchinfo, int offset, unsigned int protoff,
26 bool *hotdrop)
27{ 24{
28 unsigned char eui64[8]; 25 unsigned char eui64[8];
29 int i = 0; 26 int i = 0;
30 27
31 if (!(skb_mac_header(skb) >= skb->head && 28 if (!(skb_mac_header(skb) >= skb->head &&
32 skb_mac_header(skb) + ETH_HLEN <= skb->data) && 29 skb_mac_header(skb) + ETH_HLEN <= skb->data) &&
33 offset != 0) { 30 par->fragoff != 0) {
34 *hotdrop = true; 31 *par->hotdrop = true;
35 return false; 32 return false;
36 } 33 }
37 34
@@ -60,7 +57,7 @@ eui64_mt6(const struct sk_buff *skb, const struct net_device *in,
60 57
61static struct xt_match eui64_mt6_reg __read_mostly = { 58static struct xt_match eui64_mt6_reg __read_mostly = {
62 .name = "eui64", 59 .name = "eui64",
63 .family = AF_INET6, 60 .family = NFPROTO_IPV6,
64 .match = eui64_mt6, 61 .match = eui64_mt6,
65 .matchsize = sizeof(int), 62 .matchsize = sizeof(int),
66 .hooks = (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_IN) | 63 .hooks = (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_IN) |
diff --git a/net/ipv6/netfilter/ip6t_frag.c b/net/ipv6/netfilter/ip6t_frag.c
index e2bbc63dba5b..673aa0a5084e 100644
--- a/net/ipv6/netfilter/ip6t_frag.c
+++ b/net/ipv6/netfilter/ip6t_frag.c
@@ -35,27 +35,24 @@ id_match(u_int32_t min, u_int32_t max, u_int32_t id, bool invert)
35} 35}
36 36
37static bool 37static bool
38frag_mt6(const struct sk_buff *skb, const struct net_device *in, 38frag_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
39 const struct net_device *out, const struct xt_match *match,
40 const void *matchinfo, int offset, unsigned int protoff,
41 bool *hotdrop)
42{ 39{
43 struct frag_hdr _frag; 40 struct frag_hdr _frag;
44 const struct frag_hdr *fh; 41 const struct frag_hdr *fh;
45 const struct ip6t_frag *fraginfo = matchinfo; 42 const struct ip6t_frag *fraginfo = par->matchinfo;
46 unsigned int ptr; 43 unsigned int ptr;
47 int err; 44 int err;
48 45
49 err = ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL); 46 err = ipv6_find_hdr(skb, &ptr, NEXTHDR_FRAGMENT, NULL);
50 if (err < 0) { 47 if (err < 0) {
51 if (err != -ENOENT) 48 if (err != -ENOENT)
52 *hotdrop = true; 49 *par->hotdrop = true;
53 return false; 50 return false;
54 } 51 }
55 52
56 fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag); 53 fh = skb_header_pointer(skb, ptr, sizeof(_frag), &_frag);
57 if (fh == NULL) { 54 if (fh == NULL) {
58 *hotdrop = true; 55 *par->hotdrop = true;
59 return false; 56 return false;
60 } 57 }
61 58
@@ -110,13 +107,9 @@ frag_mt6(const struct sk_buff *skb, const struct net_device *in,
110 && (ntohs(fh->frag_off) & IP6_MF)); 107 && (ntohs(fh->frag_off) & IP6_MF));
111} 108}
112 109
113/* Called when user tries to insert an entry of this type. */ 110static bool frag_mt6_check(const struct xt_mtchk_param *par)
114static bool
115frag_mt6_check(const char *tablename, const void *ip,
116 const struct xt_match *match, void *matchinfo,
117 unsigned int hook_mask)
118{ 111{
119 const struct ip6t_frag *fraginfo = matchinfo; 112 const struct ip6t_frag *fraginfo = par->matchinfo;
120 113
121 if (fraginfo->invflags & ~IP6T_FRAG_INV_MASK) { 114 if (fraginfo->invflags & ~IP6T_FRAG_INV_MASK) {
122 pr_debug("ip6t_frag: unknown flags %X\n", fraginfo->invflags); 115 pr_debug("ip6t_frag: unknown flags %X\n", fraginfo->invflags);
@@ -127,7 +120,7 @@ frag_mt6_check(const char *tablename, const void *ip,
127 120
128static struct xt_match frag_mt6_reg __read_mostly = { 121static struct xt_match frag_mt6_reg __read_mostly = {
129 .name = "frag", 122 .name = "frag",
130 .family = AF_INET6, 123 .family = NFPROTO_IPV6,
131 .match = frag_mt6, 124 .match = frag_mt6,
132 .matchsize = sizeof(struct ip6t_frag), 125 .matchsize = sizeof(struct ip6t_frag),
133 .checkentry = frag_mt6_check, 126 .checkentry = frag_mt6_check,
diff --git a/net/ipv6/netfilter/ip6t_hbh.c b/net/ipv6/netfilter/ip6t_hbh.c
index 62e39ace0588..cbe8dec9744b 100644
--- a/net/ipv6/netfilter/ip6t_hbh.c
+++ b/net/ipv6/netfilter/ip6t_hbh.c
@@ -42,14 +42,11 @@ MODULE_ALIAS("ip6t_dst");
42 */ 42 */
43 43
44static bool 44static bool
45hbh_mt6(const struct sk_buff *skb, const struct net_device *in, 45hbh_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
46 const struct net_device *out, const struct xt_match *match,
47 const void *matchinfo, int offset, unsigned int protoff,
48 bool *hotdrop)
49{ 46{
50 struct ipv6_opt_hdr _optsh; 47 struct ipv6_opt_hdr _optsh;
51 const struct ipv6_opt_hdr *oh; 48 const struct ipv6_opt_hdr *oh;
52 const struct ip6t_opts *optinfo = matchinfo; 49 const struct ip6t_opts *optinfo = par->matchinfo;
53 unsigned int temp; 50 unsigned int temp;
54 unsigned int ptr; 51 unsigned int ptr;
55 unsigned int hdrlen = 0; 52 unsigned int hdrlen = 0;
@@ -61,16 +58,16 @@ hbh_mt6(const struct sk_buff *skb, const struct net_device *in,
61 unsigned int optlen; 58 unsigned int optlen;
62 int err; 59 int err;
63 60
64 err = ipv6_find_hdr(skb, &ptr, match->data, NULL); 61 err = ipv6_find_hdr(skb, &ptr, par->match->data, NULL);
65 if (err < 0) { 62 if (err < 0) {
66 if (err != -ENOENT) 63 if (err != -ENOENT)
67 *hotdrop = true; 64 *par->hotdrop = true;
68 return false; 65 return false;
69 } 66 }
70 67
71 oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh); 68 oh = skb_header_pointer(skb, ptr, sizeof(_optsh), &_optsh);
72 if (oh == NULL) { 69 if (oh == NULL) {
73 *hotdrop = true; 70 *par->hotdrop = true;
74 return false; 71 return false;
75 } 72 }
76 73
@@ -97,8 +94,6 @@ hbh_mt6(const struct sk_buff *skb, const struct net_device *in,
97 hdrlen -= 2; 94 hdrlen -= 2;
98 if (!(optinfo->flags & IP6T_OPTS_OPTS)) { 95 if (!(optinfo->flags & IP6T_OPTS_OPTS)) {
99 return ret; 96 return ret;
100 } else if (optinfo->flags & IP6T_OPTS_NSTRICT) {
101 pr_debug("Not strict - not implemented");
102 } else { 97 } else {
103 pr_debug("Strict "); 98 pr_debug("Strict ");
104 pr_debug("#%d ", optinfo->optsnr); 99 pr_debug("#%d ", optinfo->optsnr);
@@ -165,25 +160,27 @@ hbh_mt6(const struct sk_buff *skb, const struct net_device *in,
165 return false; 160 return false;
166} 161}
167 162
168/* Called when user tries to insert an entry of this type. */ 163static bool hbh_mt6_check(const struct xt_mtchk_param *par)
169static bool
170hbh_mt6_check(const char *tablename, const void *entry,
171 const struct xt_match *match, void *matchinfo,
172 unsigned int hook_mask)
173{ 164{
174 const struct ip6t_opts *optsinfo = matchinfo; 165 const struct ip6t_opts *optsinfo = par->matchinfo;
175 166
176 if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) { 167 if (optsinfo->invflags & ~IP6T_OPTS_INV_MASK) {
177 pr_debug("ip6t_opts: unknown flags %X\n", optsinfo->invflags); 168 pr_debug("ip6t_opts: unknown flags %X\n", optsinfo->invflags);
178 return false; 169 return false;
179 } 170 }
171
172 if (optsinfo->flags & IP6T_OPTS_NSTRICT) {
173 pr_debug("ip6t_opts: Not strict - not implemented");
174 return false;
175 }
176
180 return true; 177 return true;
181} 178}
182 179
183static struct xt_match hbh_mt6_reg[] __read_mostly = { 180static struct xt_match hbh_mt6_reg[] __read_mostly = {
184 { 181 {
185 .name = "hbh", 182 .name = "hbh",
186 .family = AF_INET6, 183 .family = NFPROTO_IPV6,
187 .match = hbh_mt6, 184 .match = hbh_mt6,
188 .matchsize = sizeof(struct ip6t_opts), 185 .matchsize = sizeof(struct ip6t_opts),
189 .checkentry = hbh_mt6_check, 186 .checkentry = hbh_mt6_check,
@@ -192,7 +189,7 @@ static struct xt_match hbh_mt6_reg[] __read_mostly = {
192 }, 189 },
193 { 190 {
194 .name = "dst", 191 .name = "dst",
195 .family = AF_INET6, 192 .family = NFPROTO_IPV6,
196 .match = hbh_mt6, 193 .match = hbh_mt6,
197 .matchsize = sizeof(struct ip6t_opts), 194 .matchsize = sizeof(struct ip6t_opts),
198 .checkentry = hbh_mt6_check, 195 .checkentry = hbh_mt6_check,
diff --git a/net/ipv6/netfilter/ip6t_hl.c b/net/ipv6/netfilter/ip6t_hl.c
index 345671673845..c964dca1132d 100644
--- a/net/ipv6/netfilter/ip6t_hl.c
+++ b/net/ipv6/netfilter/ip6t_hl.c
@@ -19,12 +19,9 @@ MODULE_AUTHOR("Maciej Soltysiak <solt@dns.toxicfilms.tv>");
19MODULE_DESCRIPTION("Xtables: IPv6 Hop Limit field match"); 19MODULE_DESCRIPTION("Xtables: IPv6 Hop Limit field match");
20MODULE_LICENSE("GPL"); 20MODULE_LICENSE("GPL");
21 21
22static bool 22static bool hl_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
23hl_mt6(const struct sk_buff *skb, const struct net_device *in,
24 const struct net_device *out, const struct xt_match *match,
25 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
26{ 23{
27 const struct ip6t_hl_info *info = matchinfo; 24 const struct ip6t_hl_info *info = par->matchinfo;
28 const struct ipv6hdr *ip6h = ipv6_hdr(skb); 25 const struct ipv6hdr *ip6h = ipv6_hdr(skb);
29 26
30 switch (info->mode) { 27 switch (info->mode) {
@@ -51,7 +48,7 @@ hl_mt6(const struct sk_buff *skb, const struct net_device *in,
51 48
52static struct xt_match hl_mt6_reg __read_mostly = { 49static struct xt_match hl_mt6_reg __read_mostly = {
53 .name = "hl", 50 .name = "hl",
54 .family = AF_INET6, 51 .family = NFPROTO_IPV6,
55 .match = hl_mt6, 52 .match = hl_mt6,
56 .matchsize = sizeof(struct ip6t_hl_info), 53 .matchsize = sizeof(struct ip6t_hl_info),
57 .me = THIS_MODULE, 54 .me = THIS_MODULE,
diff --git a/net/ipv6/netfilter/ip6t_ipv6header.c b/net/ipv6/netfilter/ip6t_ipv6header.c
index 317a8960a757..14e6724d5672 100644
--- a/net/ipv6/netfilter/ip6t_ipv6header.c
+++ b/net/ipv6/netfilter/ip6t_ipv6header.c
@@ -27,12 +27,9 @@ MODULE_DESCRIPTION("Xtables: IPv6 header types match");
27MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>"); 27MODULE_AUTHOR("Andras Kis-Szabo <kisza@sch.bme.hu>");
28 28
29static bool 29static bool
30ipv6header_mt6(const struct sk_buff *skb, const struct net_device *in, 30ipv6header_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
31 const struct net_device *out, const struct xt_match *match,
32 const void *matchinfo, int offset, unsigned int protoff,
33 bool *hotdrop)
34{ 31{
35 const struct ip6t_ipv6header_info *info = matchinfo; 32 const struct ip6t_ipv6header_info *info = par->matchinfo;
36 unsigned int temp; 33 unsigned int temp;
37 int len; 34 int len;
38 u8 nexthdr; 35 u8 nexthdr;
@@ -121,12 +118,9 @@ ipv6header_mt6(const struct sk_buff *skb, const struct net_device *in,
121 } 118 }
122} 119}
123 120
124static bool 121static bool ipv6header_mt6_check(const struct xt_mtchk_param *par)
125ipv6header_mt6_check(const char *tablename, const void *ip,
126 const struct xt_match *match, void *matchinfo,
127 unsigned int hook_mask)
128{ 122{
129 const struct ip6t_ipv6header_info *info = matchinfo; 123 const struct ip6t_ipv6header_info *info = par->matchinfo;
130 124
131 /* invflags is 0 or 0xff in hard mode */ 125 /* invflags is 0 or 0xff in hard mode */
132 if ((!info->modeflag) && info->invflags != 0x00 && 126 if ((!info->modeflag) && info->invflags != 0x00 &&
@@ -138,7 +132,7 @@ ipv6header_mt6_check(const char *tablename, const void *ip,
138 132
139static struct xt_match ipv6header_mt6_reg __read_mostly = { 133static struct xt_match ipv6header_mt6_reg __read_mostly = {
140 .name = "ipv6header", 134 .name = "ipv6header",
141 .family = AF_INET6, 135 .family = NFPROTO_IPV6,
142 .match = ipv6header_mt6, 136 .match = ipv6header_mt6,
143 .matchsize = sizeof(struct ip6t_ipv6header_info), 137 .matchsize = sizeof(struct ip6t_ipv6header_info),
144 .checkentry = ipv6header_mt6_check, 138 .checkentry = ipv6header_mt6_check,
diff --git a/net/ipv6/netfilter/ip6t_mh.c b/net/ipv6/netfilter/ip6t_mh.c
index e06678d07ec8..aafe4e66577b 100644
--- a/net/ipv6/netfilter/ip6t_mh.c
+++ b/net/ipv6/netfilter/ip6t_mh.c
@@ -37,32 +37,29 @@ type_match(u_int8_t min, u_int8_t max, u_int8_t type, bool invert)
37 return (type >= min && type <= max) ^ invert; 37 return (type >= min && type <= max) ^ invert;
38} 38}
39 39
40static bool 40static bool mh_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
41mh_mt6(const struct sk_buff *skb, const struct net_device *in,
42 const struct net_device *out, const struct xt_match *match,
43 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
44{ 41{
45 struct ip6_mh _mh; 42 struct ip6_mh _mh;
46 const struct ip6_mh *mh; 43 const struct ip6_mh *mh;
47 const struct ip6t_mh *mhinfo = matchinfo; 44 const struct ip6t_mh *mhinfo = par->matchinfo;
48 45
49 /* Must not be a fragment. */ 46 /* Must not be a fragment. */
50 if (offset) 47 if (par->fragoff != 0)
51 return false; 48 return false;
52 49
53 mh = skb_header_pointer(skb, protoff, sizeof(_mh), &_mh); 50 mh = skb_header_pointer(skb, par->thoff, sizeof(_mh), &_mh);
54 if (mh == NULL) { 51 if (mh == NULL) {
55 /* We've been asked to examine this packet, and we 52 /* We've been asked to examine this packet, and we
56 can't. Hence, no choice but to drop. */ 53 can't. Hence, no choice but to drop. */
57 duprintf("Dropping evil MH tinygram.\n"); 54 duprintf("Dropping evil MH tinygram.\n");
58 *hotdrop = true; 55 *par->hotdrop = true;
59 return false; 56 return false;
60 } 57 }
61 58
62 if (mh->ip6mh_proto != IPPROTO_NONE) { 59 if (mh->ip6mh_proto != IPPROTO_NONE) {
63 duprintf("Dropping invalid MH Payload Proto: %u\n", 60 duprintf("Dropping invalid MH Payload Proto: %u\n",
64 mh->ip6mh_proto); 61 mh->ip6mh_proto);
65 *hotdrop = true; 62 *par->hotdrop = true;
66 return false; 63 return false;
67 } 64 }
68 65
@@ -70,13 +67,9 @@ mh_mt6(const struct sk_buff *skb, const struct net_device *in,
70 !!(mhinfo->invflags & IP6T_MH_INV_TYPE)); 67 !!(mhinfo->invflags & IP6T_MH_INV_TYPE));
71} 68}
72 69
73/* Called when user tries to insert an entry of this type. */ 70static bool mh_mt6_check(const struct xt_mtchk_param *par)
74static bool
75mh_mt6_check(const char *tablename, const void *entry,
76 const struct xt_match *match, void *matchinfo,
77 unsigned int hook_mask)
78{ 71{
79 const struct ip6t_mh *mhinfo = matchinfo; 72 const struct ip6t_mh *mhinfo = par->matchinfo;
80 73
81 /* Must specify no unknown invflags */ 74 /* Must specify no unknown invflags */
82 return !(mhinfo->invflags & ~IP6T_MH_INV_MASK); 75 return !(mhinfo->invflags & ~IP6T_MH_INV_MASK);
@@ -84,7 +77,7 @@ mh_mt6_check(const char *tablename, const void *entry,
84 77
85static struct xt_match mh_mt6_reg __read_mostly = { 78static struct xt_match mh_mt6_reg __read_mostly = {
86 .name = "mh", 79 .name = "mh",
87 .family = AF_INET6, 80 .family = NFPROTO_IPV6,
88 .checkentry = mh_mt6_check, 81 .checkentry = mh_mt6_check,
89 .match = mh_mt6, 82 .match = mh_mt6,
90 .matchsize = sizeof(struct ip6t_mh), 83 .matchsize = sizeof(struct ip6t_mh),
diff --git a/net/ipv6/netfilter/ip6t_rt.c b/net/ipv6/netfilter/ip6t_rt.c
index 81aaf7aaaabf..356b8d6f6baa 100644
--- a/net/ipv6/netfilter/ip6t_rt.c
+++ b/net/ipv6/netfilter/ip6t_rt.c
@@ -36,14 +36,11 @@ segsleft_match(u_int32_t min, u_int32_t max, u_int32_t id, bool invert)
36 return r; 36 return r;
37} 37}
38 38
39static bool 39static bool rt_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
40rt_mt6(const struct sk_buff *skb, const struct net_device *in,
41 const struct net_device *out, const struct xt_match *match,
42 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
43{ 40{
44 struct ipv6_rt_hdr _route; 41 struct ipv6_rt_hdr _route;
45 const struct ipv6_rt_hdr *rh; 42 const struct ipv6_rt_hdr *rh;
46 const struct ip6t_rt *rtinfo = matchinfo; 43 const struct ip6t_rt *rtinfo = par->matchinfo;
47 unsigned int temp; 44 unsigned int temp;
48 unsigned int ptr; 45 unsigned int ptr;
49 unsigned int hdrlen = 0; 46 unsigned int hdrlen = 0;
@@ -55,13 +52,13 @@ rt_mt6(const struct sk_buff *skb, const struct net_device *in,
55 err = ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL); 52 err = ipv6_find_hdr(skb, &ptr, NEXTHDR_ROUTING, NULL);
56 if (err < 0) { 53 if (err < 0) {
57 if (err != -ENOENT) 54 if (err != -ENOENT)
58 *hotdrop = true; 55 *par->hotdrop = true;
59 return false; 56 return false;
60 } 57 }
61 58
62 rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route); 59 rh = skb_header_pointer(skb, ptr, sizeof(_route), &_route);
63 if (rh == NULL) { 60 if (rh == NULL) {
64 *hotdrop = true; 61 *par->hotdrop = true;
65 return false; 62 return false;
66 } 63 }
67 64
@@ -189,13 +186,9 @@ rt_mt6(const struct sk_buff *skb, const struct net_device *in,
189 return false; 186 return false;
190} 187}
191 188
192/* Called when user tries to insert an entry of this type. */ 189static bool rt_mt6_check(const struct xt_mtchk_param *par)
193static bool
194rt_mt6_check(const char *tablename, const void *entry,
195 const struct xt_match *match, void *matchinfo,
196 unsigned int hook_mask)
197{ 190{
198 const struct ip6t_rt *rtinfo = matchinfo; 191 const struct ip6t_rt *rtinfo = par->matchinfo;
199 192
200 if (rtinfo->invflags & ~IP6T_RT_INV_MASK) { 193 if (rtinfo->invflags & ~IP6T_RT_INV_MASK) {
201 pr_debug("ip6t_rt: unknown flags %X\n", rtinfo->invflags); 194 pr_debug("ip6t_rt: unknown flags %X\n", rtinfo->invflags);
@@ -214,7 +207,7 @@ rt_mt6_check(const char *tablename, const void *entry,
214 207
215static struct xt_match rt_mt6_reg __read_mostly = { 208static struct xt_match rt_mt6_reg __read_mostly = {
216 .name = "rt", 209 .name = "rt",
217 .family = AF_INET6, 210 .family = NFPROTO_IPV6,
218 .match = rt_mt6, 211 .match = rt_mt6,
219 .matchsize = sizeof(struct ip6t_rt), 212 .matchsize = sizeof(struct ip6t_rt),
220 .checkentry = rt_mt6_check, 213 .checkentry = rt_mt6_check,
diff --git a/net/ipv6/netfilter/ip6table_filter.c b/net/ipv6/netfilter/ip6table_filter.c
index 55a2c290bad4..b110a8a85a14 100644
--- a/net/ipv6/netfilter/ip6table_filter.c
+++ b/net/ipv6/netfilter/ip6table_filter.c
@@ -68,7 +68,7 @@ ip6t_local_in_hook(unsigned int hook,
68 int (*okfn)(struct sk_buff *)) 68 int (*okfn)(struct sk_buff *))
69{ 69{
70 return ip6t_do_table(skb, hook, in, out, 70 return ip6t_do_table(skb, hook, in, out,
71 nf_local_in_net(in, out)->ipv6.ip6table_filter); 71 dev_net(in)->ipv6.ip6table_filter);
72} 72}
73 73
74static unsigned int 74static unsigned int
@@ -79,7 +79,7 @@ ip6t_forward_hook(unsigned int hook,
79 int (*okfn)(struct sk_buff *)) 79 int (*okfn)(struct sk_buff *))
80{ 80{
81 return ip6t_do_table(skb, hook, in, out, 81 return ip6t_do_table(skb, hook, in, out,
82 nf_forward_net(in, out)->ipv6.ip6table_filter); 82 dev_net(in)->ipv6.ip6table_filter);
83} 83}
84 84
85static unsigned int 85static unsigned int
@@ -100,7 +100,7 @@ ip6t_local_out_hook(unsigned int hook,
100#endif 100#endif
101 101
102 return ip6t_do_table(skb, hook, in, out, 102 return ip6t_do_table(skb, hook, in, out,
103 nf_local_out_net(in, out)->ipv6.ip6table_filter); 103 dev_net(out)->ipv6.ip6table_filter);
104} 104}
105 105
106static struct nf_hook_ops ip6t_ops[] __read_mostly = { 106static struct nf_hook_ops ip6t_ops[] __read_mostly = {
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index f405cea21a8b..d0b31b259d4d 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -67,17 +67,29 @@ static struct xt_table packet_mangler = {
67 67
68/* The work comes in here from netfilter.c. */ 68/* The work comes in here from netfilter.c. */
69static unsigned int 69static unsigned int
70ip6t_route_hook(unsigned int hook, 70ip6t_in_hook(unsigned int hook,
71 struct sk_buff *skb, 71 struct sk_buff *skb,
72 const struct net_device *in, 72 const struct net_device *in,
73 const struct net_device *out, 73 const struct net_device *out,
74 int (*okfn)(struct sk_buff *)) 74 int (*okfn)(struct sk_buff *))
75{ 75{
76 return ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_mangle); 76 return ip6t_do_table(skb, hook, in, out,
77 dev_net(in)->ipv6.ip6table_mangle);
77} 78}
78 79
79static unsigned int 80static unsigned int
80ip6t_local_hook(unsigned int hook, 81ip6t_post_routing_hook(unsigned int hook,
82 struct sk_buff *skb,
83 const struct net_device *in,
84 const struct net_device *out,
85 int (*okfn)(struct sk_buff *))
86{
87 return ip6t_do_table(skb, hook, in, out,
88 dev_net(out)->ipv6.ip6table_mangle);
89}
90
91static unsigned int
92ip6t_local_out_hook(unsigned int hook,
81 struct sk_buff *skb, 93 struct sk_buff *skb,
82 const struct net_device *in, 94 const struct net_device *in,
83 const struct net_device *out, 95 const struct net_device *out,
@@ -108,7 +120,8 @@ ip6t_local_hook(unsigned int hook,
108 /* flowlabel and prio (includes version, which shouldn't change either */ 120 /* flowlabel and prio (includes version, which shouldn't change either */
109 flowlabel = *((u_int32_t *)ipv6_hdr(skb)); 121 flowlabel = *((u_int32_t *)ipv6_hdr(skb));
110 122
111 ret = ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_mangle); 123 ret = ip6t_do_table(skb, hook, in, out,
124 dev_net(out)->ipv6.ip6table_mangle);
112 125
113 if (ret != NF_DROP && ret != NF_STOLEN 126 if (ret != NF_DROP && ret != NF_STOLEN
114 && (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr)) 127 && (memcmp(&ipv6_hdr(skb)->saddr, &saddr, sizeof(saddr))
@@ -122,35 +135,35 @@ ip6t_local_hook(unsigned int hook,
122 135
123static struct nf_hook_ops ip6t_ops[] __read_mostly = { 136static struct nf_hook_ops ip6t_ops[] __read_mostly = {
124 { 137 {
125 .hook = ip6t_route_hook, 138 .hook = ip6t_in_hook,
126 .owner = THIS_MODULE, 139 .owner = THIS_MODULE,
127 .pf = PF_INET6, 140 .pf = PF_INET6,
128 .hooknum = NF_INET_PRE_ROUTING, 141 .hooknum = NF_INET_PRE_ROUTING,
129 .priority = NF_IP6_PRI_MANGLE, 142 .priority = NF_IP6_PRI_MANGLE,
130 }, 143 },
131 { 144 {
132 .hook = ip6t_route_hook, 145 .hook = ip6t_in_hook,
133 .owner = THIS_MODULE, 146 .owner = THIS_MODULE,
134 .pf = PF_INET6, 147 .pf = PF_INET6,
135 .hooknum = NF_INET_LOCAL_IN, 148 .hooknum = NF_INET_LOCAL_IN,
136 .priority = NF_IP6_PRI_MANGLE, 149 .priority = NF_IP6_PRI_MANGLE,
137 }, 150 },
138 { 151 {
139 .hook = ip6t_route_hook, 152 .hook = ip6t_in_hook,
140 .owner = THIS_MODULE, 153 .owner = THIS_MODULE,
141 .pf = PF_INET6, 154 .pf = PF_INET6,
142 .hooknum = NF_INET_FORWARD, 155 .hooknum = NF_INET_FORWARD,
143 .priority = NF_IP6_PRI_MANGLE, 156 .priority = NF_IP6_PRI_MANGLE,
144 }, 157 },
145 { 158 {
146 .hook = ip6t_local_hook, 159 .hook = ip6t_local_out_hook,
147 .owner = THIS_MODULE, 160 .owner = THIS_MODULE,
148 .pf = PF_INET6, 161 .pf = PF_INET6,
149 .hooknum = NF_INET_LOCAL_OUT, 162 .hooknum = NF_INET_LOCAL_OUT,
150 .priority = NF_IP6_PRI_MANGLE, 163 .priority = NF_IP6_PRI_MANGLE,
151 }, 164 },
152 { 165 {
153 .hook = ip6t_route_hook, 166 .hook = ip6t_post_routing_hook,
154 .owner = THIS_MODULE, 167 .owner = THIS_MODULE,
155 .pf = PF_INET6, 168 .pf = PF_INET6,
156 .hooknum = NF_INET_POST_ROUTING, 169 .hooknum = NF_INET_POST_ROUTING,
diff --git a/net/ipv6/netfilter/ip6table_raw.c b/net/ipv6/netfilter/ip6table_raw.c
index 92b91077ac29..109fab6f831a 100644
--- a/net/ipv6/netfilter/ip6table_raw.c
+++ b/net/ipv6/netfilter/ip6table_raw.c
@@ -45,25 +45,37 @@ static struct xt_table packet_raw = {
45 45
46/* The work comes in here from netfilter.c. */ 46/* The work comes in here from netfilter.c. */
47static unsigned int 47static unsigned int
48ip6t_hook(unsigned int hook, 48ip6t_pre_routing_hook(unsigned int hook,
49 struct sk_buff *skb, 49 struct sk_buff *skb,
50 const struct net_device *in, 50 const struct net_device *in,
51 const struct net_device *out, 51 const struct net_device *out,
52 int (*okfn)(struct sk_buff *)) 52 int (*okfn)(struct sk_buff *))
53{ 53{
54 return ip6t_do_table(skb, hook, in, out, init_net.ipv6.ip6table_raw); 54 return ip6t_do_table(skb, hook, in, out,
55 dev_net(in)->ipv6.ip6table_raw);
56}
57
58static unsigned int
59ip6t_local_out_hook(unsigned int hook,
60 struct sk_buff *skb,
61 const struct net_device *in,
62 const struct net_device *out,
63 int (*okfn)(struct sk_buff *))
64{
65 return ip6t_do_table(skb, hook, in, out,
66 dev_net(out)->ipv6.ip6table_raw);
55} 67}
56 68
57static struct nf_hook_ops ip6t_ops[] __read_mostly = { 69static struct nf_hook_ops ip6t_ops[] __read_mostly = {
58 { 70 {
59 .hook = ip6t_hook, 71 .hook = ip6t_pre_routing_hook,
60 .pf = PF_INET6, 72 .pf = PF_INET6,
61 .hooknum = NF_INET_PRE_ROUTING, 73 .hooknum = NF_INET_PRE_ROUTING,
62 .priority = NF_IP6_PRI_FIRST, 74 .priority = NF_IP6_PRI_FIRST,
63 .owner = THIS_MODULE, 75 .owner = THIS_MODULE,
64 }, 76 },
65 { 77 {
66 .hook = ip6t_hook, 78 .hook = ip6t_local_out_hook,
67 .pf = PF_INET6, 79 .pf = PF_INET6,
68 .hooknum = NF_INET_LOCAL_OUT, 80 .hooknum = NF_INET_LOCAL_OUT,
69 .priority = NF_IP6_PRI_FIRST, 81 .priority = NF_IP6_PRI_FIRST,
diff --git a/net/ipv6/netfilter/ip6table_security.c b/net/ipv6/netfilter/ip6table_security.c
index 6e7131036bc6..20bc52f13e43 100644
--- a/net/ipv6/netfilter/ip6table_security.c
+++ b/net/ipv6/netfilter/ip6table_security.c
@@ -72,7 +72,7 @@ ip6t_local_in_hook(unsigned int hook,
72 int (*okfn)(struct sk_buff *)) 72 int (*okfn)(struct sk_buff *))
73{ 73{
74 return ip6t_do_table(skb, hook, in, out, 74 return ip6t_do_table(skb, hook, in, out,
75 nf_local_in_net(in, out)->ipv6.ip6table_security); 75 dev_net(in)->ipv6.ip6table_security);
76} 76}
77 77
78static unsigned int 78static unsigned int
@@ -83,7 +83,7 @@ ip6t_forward_hook(unsigned int hook,
83 int (*okfn)(struct sk_buff *)) 83 int (*okfn)(struct sk_buff *))
84{ 84{
85 return ip6t_do_table(skb, hook, in, out, 85 return ip6t_do_table(skb, hook, in, out,
86 nf_forward_net(in, out)->ipv6.ip6table_security); 86 dev_net(in)->ipv6.ip6table_security);
87} 87}
88 88
89static unsigned int 89static unsigned int
@@ -95,7 +95,7 @@ ip6t_local_out_hook(unsigned int hook,
95{ 95{
96 /* TBD: handle short packets via raw socket */ 96 /* TBD: handle short packets via raw socket */
97 return ip6t_do_table(skb, hook, in, out, 97 return ip6t_do_table(skb, hook, in, out,
98 nf_local_out_net(in, out)->ipv6.ip6table_security); 98 dev_net(out)->ipv6.ip6table_security);
99} 99}
100 100
101static struct nf_hook_ops ip6t_ops[] __read_mostly = { 101static struct nf_hook_ops ip6t_ops[] __read_mostly = {
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index 85050c072abd..e91db16611d9 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -211,11 +211,10 @@ static unsigned int ipv6_defrag(unsigned int hooknum,
211 return NF_STOLEN; 211 return NF_STOLEN;
212} 212}
213 213
214static unsigned int ipv6_conntrack_in(unsigned int hooknum, 214static unsigned int __ipv6_conntrack_in(struct net *net,
215 struct sk_buff *skb, 215 unsigned int hooknum,
216 const struct net_device *in, 216 struct sk_buff *skb,
217 const struct net_device *out, 217 int (*okfn)(struct sk_buff *))
218 int (*okfn)(struct sk_buff *))
219{ 218{
220 struct sk_buff *reasm = skb->nfct_reasm; 219 struct sk_buff *reasm = skb->nfct_reasm;
221 220
@@ -225,7 +224,7 @@ static unsigned int ipv6_conntrack_in(unsigned int hooknum,
225 if (!reasm->nfct) { 224 if (!reasm->nfct) {
226 unsigned int ret; 225 unsigned int ret;
227 226
228 ret = nf_conntrack_in(PF_INET6, hooknum, reasm); 227 ret = nf_conntrack_in(net, PF_INET6, hooknum, reasm);
229 if (ret != NF_ACCEPT) 228 if (ret != NF_ACCEPT)
230 return ret; 229 return ret;
231 } 230 }
@@ -235,7 +234,16 @@ static unsigned int ipv6_conntrack_in(unsigned int hooknum,
235 return NF_ACCEPT; 234 return NF_ACCEPT;
236 } 235 }
237 236
238 return nf_conntrack_in(PF_INET6, hooknum, skb); 237 return nf_conntrack_in(net, PF_INET6, hooknum, skb);
238}
239
240static unsigned int ipv6_conntrack_in(unsigned int hooknum,
241 struct sk_buff *skb,
242 const struct net_device *in,
243 const struct net_device *out,
244 int (*okfn)(struct sk_buff *))
245{
246 return __ipv6_conntrack_in(dev_net(in), hooknum, skb, okfn);
239} 247}
240 248
241static unsigned int ipv6_conntrack_local(unsigned int hooknum, 249static unsigned int ipv6_conntrack_local(unsigned int hooknum,
@@ -250,7 +258,7 @@ static unsigned int ipv6_conntrack_local(unsigned int hooknum,
250 printk("ipv6_conntrack_local: packet too short\n"); 258 printk("ipv6_conntrack_local: packet too short\n");
251 return NF_ACCEPT; 259 return NF_ACCEPT;
252 } 260 }
253 return ipv6_conntrack_in(hooknum, skb, in, out, okfn); 261 return __ipv6_conntrack_in(dev_net(out), hooknum, skb, okfn);
254} 262}
255 263
256static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = { 264static struct nf_hook_ops ipv6_conntrack_ops[] __read_mostly = {
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index 14d47d833545..05726177903f 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -81,7 +81,7 @@ static int icmpv6_packet(struct nf_conn *ct,
81 const struct sk_buff *skb, 81 const struct sk_buff *skb,
82 unsigned int dataoff, 82 unsigned int dataoff,
83 enum ip_conntrack_info ctinfo, 83 enum ip_conntrack_info ctinfo,
84 int pf, 84 u_int8_t pf,
85 unsigned int hooknum) 85 unsigned int hooknum)
86{ 86{
87 /* Try to delete connection immediately after all replies: 87 /* Try to delete connection immediately after all replies:
@@ -93,7 +93,7 @@ static int icmpv6_packet(struct nf_conn *ct,
93 nf_ct_kill_acct(ct, ctinfo, skb); 93 nf_ct_kill_acct(ct, ctinfo, skb);
94 } else { 94 } else {
95 atomic_inc(&ct->proto.icmp.count); 95 atomic_inc(&ct->proto.icmp.count);
96 nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb); 96 nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, ct);
97 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmpv6_timeout); 97 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_icmpv6_timeout);
98 } 98 }
99 99
@@ -122,7 +122,8 @@ static bool icmpv6_new(struct nf_conn *ct, const struct sk_buff *skb,
122} 122}
123 123
124static int 124static int
125icmpv6_error_message(struct sk_buff *skb, 125icmpv6_error_message(struct net *net,
126 struct sk_buff *skb,
126 unsigned int icmp6off, 127 unsigned int icmp6off,
127 enum ip_conntrack_info *ctinfo, 128 enum ip_conntrack_info *ctinfo,
128 unsigned int hooknum) 129 unsigned int hooknum)
@@ -156,7 +157,7 @@ icmpv6_error_message(struct sk_buff *skb,
156 157
157 *ctinfo = IP_CT_RELATED; 158 *ctinfo = IP_CT_RELATED;
158 159
159 h = nf_conntrack_find_get(&intuple); 160 h = nf_conntrack_find_get(net, &intuple);
160 if (!h) { 161 if (!h) {
161 pr_debug("icmpv6_error: no match\n"); 162 pr_debug("icmpv6_error: no match\n");
162 return -NF_ACCEPT; 163 return -NF_ACCEPT;
@@ -172,21 +173,21 @@ icmpv6_error_message(struct sk_buff *skb,
172} 173}
173 174
174static int 175static int
175icmpv6_error(struct sk_buff *skb, unsigned int dataoff, 176icmpv6_error(struct net *net, struct sk_buff *skb, unsigned int dataoff,
176 enum ip_conntrack_info *ctinfo, int pf, unsigned int hooknum) 177 enum ip_conntrack_info *ctinfo, u_int8_t pf, unsigned int hooknum)
177{ 178{
178 const struct icmp6hdr *icmp6h; 179 const struct icmp6hdr *icmp6h;
179 struct icmp6hdr _ih; 180 struct icmp6hdr _ih;
180 181
181 icmp6h = skb_header_pointer(skb, dataoff, sizeof(_ih), &_ih); 182 icmp6h = skb_header_pointer(skb, dataoff, sizeof(_ih), &_ih);
182 if (icmp6h == NULL) { 183 if (icmp6h == NULL) {
183 if (LOG_INVALID(IPPROTO_ICMPV6)) 184 if (LOG_INVALID(net, IPPROTO_ICMPV6))
184 nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL, 185 nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL,
185 "nf_ct_icmpv6: short packet "); 186 "nf_ct_icmpv6: short packet ");
186 return -NF_ACCEPT; 187 return -NF_ACCEPT;
187 } 188 }
188 189
189 if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING && 190 if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
190 nf_ip6_checksum(skb, hooknum, dataoff, IPPROTO_ICMPV6)) { 191 nf_ip6_checksum(skb, hooknum, dataoff, IPPROTO_ICMPV6)) {
191 nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL, 192 nf_log_packet(PF_INET6, 0, skb, NULL, NULL, NULL,
192 "nf_ct_icmpv6: ICMPv6 checksum failed\n"); 193 "nf_ct_icmpv6: ICMPv6 checksum failed\n");
@@ -197,7 +198,7 @@ icmpv6_error(struct sk_buff *skb, unsigned int dataoff,
197 if (icmp6h->icmp6_type >= 128) 198 if (icmp6h->icmp6_type >= 128)
198 return NF_ACCEPT; 199 return NF_ACCEPT;
199 200
200 return icmpv6_error_message(skb, dataoff, ctinfo, hooknum); 201 return icmpv6_error_message(net, skb, dataoff, ctinfo, hooknum);
201} 202}
202 203
203#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE) 204#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index 52d06dd4b817..9967ac7a01a8 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -27,7 +27,6 @@
27#include <linux/ipv6.h> 27#include <linux/ipv6.h>
28#include <linux/icmpv6.h> 28#include <linux/icmpv6.h>
29#include <linux/random.h> 29#include <linux/random.h>
30#include <linux/jhash.h>
31 30
32#include <net/sock.h> 31#include <net/sock.h>
33#include <net/snmp.h> 32#include <net/snmp.h>
@@ -103,39 +102,12 @@ struct ctl_table nf_ct_ipv6_sysctl_table[] = {
103}; 102};
104#endif 103#endif
105 104
106static unsigned int ip6qhashfn(__be32 id, const struct in6_addr *saddr,
107 const struct in6_addr *daddr)
108{
109 u32 a, b, c;
110
111 a = (__force u32)saddr->s6_addr32[0];
112 b = (__force u32)saddr->s6_addr32[1];
113 c = (__force u32)saddr->s6_addr32[2];
114
115 a += JHASH_GOLDEN_RATIO;
116 b += JHASH_GOLDEN_RATIO;
117 c += nf_frags.rnd;
118 __jhash_mix(a, b, c);
119
120 a += (__force u32)saddr->s6_addr32[3];
121 b += (__force u32)daddr->s6_addr32[0];
122 c += (__force u32)daddr->s6_addr32[1];
123 __jhash_mix(a, b, c);
124
125 a += (__force u32)daddr->s6_addr32[2];
126 b += (__force u32)daddr->s6_addr32[3];
127 c += (__force u32)id;
128 __jhash_mix(a, b, c);
129
130 return c & (INETFRAGS_HASHSZ - 1);
131}
132
133static unsigned int nf_hashfn(struct inet_frag_queue *q) 105static unsigned int nf_hashfn(struct inet_frag_queue *q)
134{ 106{
135 const struct nf_ct_frag6_queue *nq; 107 const struct nf_ct_frag6_queue *nq;
136 108
137 nq = container_of(q, struct nf_ct_frag6_queue, q); 109 nq = container_of(q, struct nf_ct_frag6_queue, q);
138 return ip6qhashfn(nq->id, &nq->saddr, &nq->daddr); 110 return inet6_hash_frag(nq->id, &nq->saddr, &nq->daddr, nf_frags.rnd);
139} 111}
140 112
141static void nf_skb_free(struct sk_buff *skb) 113static void nf_skb_free(struct sk_buff *skb)
@@ -209,7 +181,7 @@ fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst)
209 arg.dst = dst; 181 arg.dst = dst;
210 182
211 read_lock_bh(&nf_frags.lock); 183 read_lock_bh(&nf_frags.lock);
212 hash = ip6qhashfn(id, src, dst); 184 hash = inet6_hash_frag(id, src, dst, nf_frags.rnd);
213 185
214 q = inet_frag_find(&nf_init_frags, &nf_frags, &arg, hash); 186 q = inet_frag_find(&nf_init_frags, &nf_frags, &arg, hash);
215 local_bh_enable(); 187 local_bh_enable();
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index 0179b66864f1..07f0b76e7427 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -29,8 +29,6 @@
29#include <net/transp_v6.h> 29#include <net/transp_v6.h>
30#include <net/ipv6.h> 30#include <net/ipv6.h>
31 31
32static struct proc_dir_entry *proc_net_devsnmp6;
33
34static int sockstat6_seq_show(struct seq_file *seq, void *v) 32static int sockstat6_seq_show(struct seq_file *seq, void *v)
35{ 33{
36 struct net *net = seq->private; 34 struct net *net = seq->private;
@@ -48,6 +46,19 @@ static int sockstat6_seq_show(struct seq_file *seq, void *v)
48 return 0; 46 return 0;
49} 47}
50 48
49static int sockstat6_seq_open(struct inode *inode, struct file *file)
50{
51 return single_open_net(inode, file, sockstat6_seq_show);
52}
53
54static const struct file_operations sockstat6_seq_fops = {
55 .owner = THIS_MODULE,
56 .open = sockstat6_seq_open,
57 .read = seq_read,
58 .llseek = seq_lseek,
59 .release = single_release_net,
60};
61
51static struct snmp_mib snmp6_ipstats_list[] = { 62static struct snmp_mib snmp6_ipstats_list[] = {
52/* ipv6 mib according to RFC 2465 */ 63/* ipv6 mib according to RFC 2465 */
53 SNMP_MIB_ITEM("Ip6InReceives", IPSTATS_MIB_INRECEIVES), 64 SNMP_MIB_ITEM("Ip6InReceives", IPSTATS_MIB_INRECEIVES),
@@ -164,44 +175,52 @@ snmp6_seq_show_item(struct seq_file *seq, void **mib, struct snmp_mib *itemlist)
164 175
165static int snmp6_seq_show(struct seq_file *seq, void *v) 176static int snmp6_seq_show(struct seq_file *seq, void *v)
166{ 177{
167 struct inet6_dev *idev = (struct inet6_dev *)seq->private; 178 struct net *net = (struct net *)seq->private;
168 179
169 if (idev) { 180 snmp6_seq_show_item(seq, (void **)net->mib.ipv6_statistics,
170 seq_printf(seq, "%-32s\t%u\n", "ifIndex", idev->dev->ifindex); 181 snmp6_ipstats_list);
171 snmp6_seq_show_item(seq, (void **)idev->stats.ipv6, snmp6_ipstats_list); 182 snmp6_seq_show_item(seq, (void **)net->mib.icmpv6_statistics,
172 snmp6_seq_show_item(seq, (void **)idev->stats.icmpv6, snmp6_icmp6_list); 183 snmp6_icmp6_list);
173 snmp6_seq_show_icmpv6msg(seq, (void **)idev->stats.icmpv6msg); 184 snmp6_seq_show_icmpv6msg(seq, (void **)net->mib.icmpv6msg_statistics);
174 } else { 185 snmp6_seq_show_item(seq, (void **)net->mib.udp_stats_in6,
175 snmp6_seq_show_item(seq, (void **)ipv6_statistics, snmp6_ipstats_list); 186 snmp6_udp6_list);
176 snmp6_seq_show_item(seq, (void **)icmpv6_statistics, snmp6_icmp6_list); 187 snmp6_seq_show_item(seq, (void **)net->mib.udplite_stats_in6,
177 snmp6_seq_show_icmpv6msg(seq, (void **)icmpv6msg_statistics); 188 snmp6_udplite6_list);
178 snmp6_seq_show_item(seq, (void **)udp_stats_in6, snmp6_udp6_list);
179 snmp6_seq_show_item(seq, (void **)udplite_stats_in6, snmp6_udplite6_list);
180 }
181 return 0; 189 return 0;
182} 190}
183 191
184static int sockstat6_seq_open(struct inode *inode, struct file *file) 192static int snmp6_seq_open(struct inode *inode, struct file *file)
185{ 193{
186 return single_open_net(inode, file, sockstat6_seq_show); 194 return single_open_net(inode, file, snmp6_seq_show);
187} 195}
188 196
189static const struct file_operations sockstat6_seq_fops = { 197static const struct file_operations snmp6_seq_fops = {
190 .owner = THIS_MODULE, 198 .owner = THIS_MODULE,
191 .open = sockstat6_seq_open, 199 .open = snmp6_seq_open,
192 .read = seq_read, 200 .read = seq_read,
193 .llseek = seq_lseek, 201 .llseek = seq_lseek,
194 .release = single_release_net, 202 .release = single_release_net,
195}; 203};
196 204
197static int snmp6_seq_open(struct inode *inode, struct file *file) 205static int snmp6_dev_seq_show(struct seq_file *seq, void *v)
198{ 206{
199 return single_open(file, snmp6_seq_show, PDE(inode)->data); 207 struct inet6_dev *idev = (struct inet6_dev *)seq->private;
208
209 seq_printf(seq, "%-32s\t%u\n", "ifIndex", idev->dev->ifindex);
210 snmp6_seq_show_item(seq, (void **)idev->stats.ipv6, snmp6_ipstats_list);
211 snmp6_seq_show_item(seq, (void **)idev->stats.icmpv6, snmp6_icmp6_list);
212 snmp6_seq_show_icmpv6msg(seq, (void **)idev->stats.icmpv6msg);
213 return 0;
200} 214}
201 215
202static const struct file_operations snmp6_seq_fops = { 216static int snmp6_dev_seq_open(struct inode *inode, struct file *file)
217{
218 return single_open(file, snmp6_dev_seq_show, PDE(inode)->data);
219}
220
221static const struct file_operations snmp6_dev_seq_fops = {
203 .owner = THIS_MODULE, 222 .owner = THIS_MODULE,
204 .open = snmp6_seq_open, 223 .open = snmp6_dev_seq_open,
205 .read = seq_read, 224 .read = seq_read,
206 .llseek = seq_lseek, 225 .llseek = seq_lseek,
207 .release = single_release, 226 .release = single_release,
@@ -210,18 +229,18 @@ static const struct file_operations snmp6_seq_fops = {
210int snmp6_register_dev(struct inet6_dev *idev) 229int snmp6_register_dev(struct inet6_dev *idev)
211{ 230{
212 struct proc_dir_entry *p; 231 struct proc_dir_entry *p;
232 struct net *net;
213 233
214 if (!idev || !idev->dev) 234 if (!idev || !idev->dev)
215 return -EINVAL; 235 return -EINVAL;
216 236
217 if (!net_eq(dev_net(idev->dev), &init_net)) 237 net = dev_net(idev->dev);
218 return 0; 238 if (!net->mib.proc_net_devsnmp6)
219
220 if (!proc_net_devsnmp6)
221 return -ENOENT; 239 return -ENOENT;
222 240
223 p = proc_create_data(idev->dev->name, S_IRUGO, 241 p = proc_create_data(idev->dev->name, S_IRUGO,
224 proc_net_devsnmp6, &snmp6_seq_fops, idev); 242 net->mib.proc_net_devsnmp6,
243 &snmp6_dev_seq_fops, idev);
225 if (!p) 244 if (!p)
226 return -ENOMEM; 245 return -ENOMEM;
227 246
@@ -231,12 +250,13 @@ int snmp6_register_dev(struct inet6_dev *idev)
231 250
232int snmp6_unregister_dev(struct inet6_dev *idev) 251int snmp6_unregister_dev(struct inet6_dev *idev)
233{ 252{
234 if (!proc_net_devsnmp6) 253 struct net *net = dev_net(idev->dev);
254 if (!net->mib.proc_net_devsnmp6)
235 return -ENOENT; 255 return -ENOENT;
236 if (!idev || !idev->stats.proc_dir_entry) 256 if (!idev || !idev->stats.proc_dir_entry)
237 return -EINVAL; 257 return -EINVAL;
238 remove_proc_entry(idev->stats.proc_dir_entry->name, 258 remove_proc_entry(idev->stats.proc_dir_entry->name,
239 proc_net_devsnmp6); 259 net->mib.proc_net_devsnmp6);
240 idev->stats.proc_dir_entry = NULL; 260 idev->stats.proc_dir_entry = NULL;
241 return 0; 261 return 0;
242} 262}
@@ -246,12 +266,27 @@ static int ipv6_proc_init_net(struct net *net)
246 if (!proc_net_fops_create(net, "sockstat6", S_IRUGO, 266 if (!proc_net_fops_create(net, "sockstat6", S_IRUGO,
247 &sockstat6_seq_fops)) 267 &sockstat6_seq_fops))
248 return -ENOMEM; 268 return -ENOMEM;
269
270 if (!proc_net_fops_create(net, "snmp6", S_IRUGO, &snmp6_seq_fops))
271 goto proc_snmp6_fail;
272
273 net->mib.proc_net_devsnmp6 = proc_mkdir("dev_snmp6", net->proc_net);
274 if (!net->mib.proc_net_devsnmp6)
275 goto proc_dev_snmp6_fail;
249 return 0; 276 return 0;
277
278proc_snmp6_fail:
279 proc_net_remove(net, "sockstat6");
280proc_dev_snmp6_fail:
281 proc_net_remove(net, "dev_snmp6");
282 return -ENOMEM;
250} 283}
251 284
252static void ipv6_proc_exit_net(struct net *net) 285static void ipv6_proc_exit_net(struct net *net)
253{ 286{
254 proc_net_remove(net, "sockstat6"); 287 proc_net_remove(net, "sockstat6");
288 proc_net_remove(net, "dev_snmp6");
289 proc_net_remove(net, "snmp6");
255} 290}
256 291
257static struct pernet_operations ipv6_proc_ops = { 292static struct pernet_operations ipv6_proc_ops = {
@@ -261,33 +296,11 @@ static struct pernet_operations ipv6_proc_ops = {
261 296
262int __init ipv6_misc_proc_init(void) 297int __init ipv6_misc_proc_init(void)
263{ 298{
264 int rc = 0; 299 return register_pernet_subsys(&ipv6_proc_ops);
265
266 if (register_pernet_subsys(&ipv6_proc_ops))
267 goto proc_net_fail;
268
269 if (!proc_net_fops_create(&init_net, "snmp6", S_IRUGO, &snmp6_seq_fops))
270 goto proc_snmp6_fail;
271
272 proc_net_devsnmp6 = proc_mkdir("dev_snmp6", init_net.proc_net);
273 if (!proc_net_devsnmp6)
274 goto proc_dev_snmp6_fail;
275out:
276 return rc;
277
278proc_dev_snmp6_fail:
279 proc_net_remove(&init_net, "snmp6");
280proc_snmp6_fail:
281 unregister_pernet_subsys(&ipv6_proc_ops);
282proc_net_fail:
283 rc = -ENOMEM;
284 goto out;
285} 300}
286 301
287void ipv6_misc_proc_exit(void) 302void ipv6_misc_proc_exit(void)
288{ 303{
289 proc_net_remove(&init_net, "dev_snmp6");
290 proc_net_remove(&init_net, "snmp6");
291 unregister_pernet_subsys(&ipv6_proc_ops); 304 unregister_pernet_subsys(&ipv6_proc_ops);
292} 305}
293 306
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 01d47674f7e5..2ba04d41dc25 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -377,14 +377,14 @@ static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb)
377 skb_checksum_complete(skb)) { 377 skb_checksum_complete(skb)) {
378 atomic_inc(&sk->sk_drops); 378 atomic_inc(&sk->sk_drops);
379 kfree_skb(skb); 379 kfree_skb(skb);
380 return 0; 380 return NET_RX_DROP;
381 } 381 }
382 382
383 /* Charge it to the socket. */ 383 /* Charge it to the socket. */
384 if (sock_queue_rcv_skb(sk,skb)<0) { 384 if (sock_queue_rcv_skb(sk,skb)<0) {
385 atomic_inc(&sk->sk_drops); 385 atomic_inc(&sk->sk_drops);
386 kfree_skb(skb); 386 kfree_skb(skb);
387 return 0; 387 return NET_RX_DROP;
388 } 388 }
389 389
390 return 0; 390 return 0;
@@ -429,7 +429,7 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb)
429 if (skb_checksum_complete(skb)) { 429 if (skb_checksum_complete(skb)) {
430 atomic_inc(&sk->sk_drops); 430 atomic_inc(&sk->sk_drops);
431 kfree_skb(skb); 431 kfree_skb(skb);
432 return 0; 432 return NET_RX_DROP;
433 } 433 }
434 } 434 }
435 435
@@ -638,7 +638,7 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
638 if (err) 638 if (err)
639 goto error_fault; 639 goto error_fault;
640 640
641 IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS); 641 IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS);
642 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev, 642 err = NF_HOOK(PF_INET6, NF_INET_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
643 dst_output); 643 dst_output);
644 if (err > 0) 644 if (err > 0)
@@ -652,7 +652,7 @@ error_fault:
652 err = -EFAULT; 652 err = -EFAULT;
653 kfree_skb(skb); 653 kfree_skb(skb);
654error: 654error:
655 IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS); 655 IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS);
656 return err; 656 return err;
657} 657}
658 658
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 89184b576e23..af12de071f4c 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -99,8 +99,8 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
99 * callers should be careful not to use the hash value outside the ipfrag_lock 99 * callers should be careful not to use the hash value outside the ipfrag_lock
100 * as doing so could race with ipfrag_hash_rnd being recalculated. 100 * as doing so could race with ipfrag_hash_rnd being recalculated.
101 */ 101 */
102static unsigned int ip6qhashfn(__be32 id, struct in6_addr *saddr, 102unsigned int inet6_hash_frag(__be32 id, const struct in6_addr *saddr,
103 struct in6_addr *daddr) 103 const struct in6_addr *daddr, u32 rnd)
104{ 104{
105 u32 a, b, c; 105 u32 a, b, c;
106 106
@@ -110,7 +110,7 @@ static unsigned int ip6qhashfn(__be32 id, struct in6_addr *saddr,
110 110
111 a += JHASH_GOLDEN_RATIO; 111 a += JHASH_GOLDEN_RATIO;
112 b += JHASH_GOLDEN_RATIO; 112 b += JHASH_GOLDEN_RATIO;
113 c += ip6_frags.rnd; 113 c += rnd;
114 __jhash_mix(a, b, c); 114 __jhash_mix(a, b, c);
115 115
116 a += (__force u32)saddr->s6_addr32[3]; 116 a += (__force u32)saddr->s6_addr32[3];
@@ -125,13 +125,14 @@ static unsigned int ip6qhashfn(__be32 id, struct in6_addr *saddr,
125 125
126 return c & (INETFRAGS_HASHSZ - 1); 126 return c & (INETFRAGS_HASHSZ - 1);
127} 127}
128EXPORT_SYMBOL_GPL(inet6_hash_frag);
128 129
129static unsigned int ip6_hashfn(struct inet_frag_queue *q) 130static unsigned int ip6_hashfn(struct inet_frag_queue *q)
130{ 131{
131 struct frag_queue *fq; 132 struct frag_queue *fq;
132 133
133 fq = container_of(q, struct frag_queue, q); 134 fq = container_of(q, struct frag_queue, q);
134 return ip6qhashfn(fq->id, &fq->saddr, &fq->daddr); 135 return inet6_hash_frag(fq->id, &fq->saddr, &fq->daddr, ip6_frags.rnd);
135} 136}
136 137
137int ip6_frag_match(struct inet_frag_queue *q, void *a) 138int ip6_frag_match(struct inet_frag_queue *q, void *a)
@@ -188,7 +189,7 @@ static void ip6_evictor(struct net *net, struct inet6_dev *idev)
188 189
189 evicted = inet_frag_evictor(&net->ipv6.frags, &ip6_frags); 190 evicted = inet_frag_evictor(&net->ipv6.frags, &ip6_frags);
190 if (evicted) 191 if (evicted)
191 IP6_ADD_STATS_BH(idev, IPSTATS_MIB_REASMFAILS, evicted); 192 IP6_ADD_STATS_BH(net, idev, IPSTATS_MIB_REASMFAILS, evicted);
192} 193}
193 194
194static void ip6_frag_expire(unsigned long data) 195static void ip6_frag_expire(unsigned long data)
@@ -212,8 +213,8 @@ static void ip6_frag_expire(unsigned long data)
212 goto out; 213 goto out;
213 214
214 rcu_read_lock(); 215 rcu_read_lock();
215 IP6_INC_STATS_BH(__in6_dev_get(dev), IPSTATS_MIB_REASMTIMEOUT); 216 IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMTIMEOUT);
216 IP6_INC_STATS_BH(__in6_dev_get(dev), IPSTATS_MIB_REASMFAILS); 217 IP6_INC_STATS_BH(net, __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS);
217 rcu_read_unlock(); 218 rcu_read_unlock();
218 219
219 /* Don't send error if the first segment did not arrive. */ 220 /* Don't send error if the first segment did not arrive. */
@@ -247,7 +248,7 @@ fq_find(struct net *net, __be32 id, struct in6_addr *src, struct in6_addr *dst,
247 arg.dst = dst; 248 arg.dst = dst;
248 249
249 read_lock(&ip6_frags.lock); 250 read_lock(&ip6_frags.lock);
250 hash = ip6qhashfn(id, src, dst); 251 hash = inet6_hash_frag(id, src, dst, ip6_frags.rnd);
251 252
252 q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash); 253 q = inet_frag_find(&net->ipv6.frags, &ip6_frags, &arg, hash);
253 if (q == NULL) 254 if (q == NULL)
@@ -256,7 +257,7 @@ fq_find(struct net *net, __be32 id, struct in6_addr *src, struct in6_addr *dst,
256 return container_of(q, struct frag_queue, q); 257 return container_of(q, struct frag_queue, q);
257 258
258oom: 259oom:
259 IP6_INC_STATS_BH(idev, IPSTATS_MIB_REASMFAILS); 260 IP6_INC_STATS_BH(net, idev, IPSTATS_MIB_REASMFAILS);
260 return NULL; 261 return NULL;
261} 262}
262 263
@@ -266,6 +267,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
266 struct sk_buff *prev, *next; 267 struct sk_buff *prev, *next;
267 struct net_device *dev; 268 struct net_device *dev;
268 int offset, end; 269 int offset, end;
270 struct net *net = dev_net(skb->dst->dev);
269 271
270 if (fq->q.last_in & INET_FRAG_COMPLETE) 272 if (fq->q.last_in & INET_FRAG_COMPLETE)
271 goto err; 273 goto err;
@@ -275,7 +277,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
275 ((u8 *)(fhdr + 1) - (u8 *)(ipv6_hdr(skb) + 1))); 277 ((u8 *)(fhdr + 1) - (u8 *)(ipv6_hdr(skb) + 1)));
276 278
277 if ((unsigned int)end > IPV6_MAXPLEN) { 279 if ((unsigned int)end > IPV6_MAXPLEN) {
278 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 280 IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst),
279 IPSTATS_MIB_INHDRERRORS); 281 IPSTATS_MIB_INHDRERRORS);
280 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, 282 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
281 ((u8 *)&fhdr->frag_off - 283 ((u8 *)&fhdr->frag_off -
@@ -308,7 +310,7 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
308 /* RFC2460 says always send parameter problem in 310 /* RFC2460 says always send parameter problem in
309 * this case. -DaveM 311 * this case. -DaveM
310 */ 312 */
311 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 313 IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst),
312 IPSTATS_MIB_INHDRERRORS); 314 IPSTATS_MIB_INHDRERRORS);
313 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, 315 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
314 offsetof(struct ipv6hdr, payload_len)); 316 offsetof(struct ipv6hdr, payload_len));
@@ -432,7 +434,8 @@ static int ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
432 return -1; 434 return -1;
433 435
434err: 436err:
435 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMFAILS); 437 IP6_INC_STATS(net, ip6_dst_idev(skb->dst),
438 IPSTATS_MIB_REASMFAILS);
436 kfree_skb(skb); 439 kfree_skb(skb);
437 return -1; 440 return -1;
438} 441}
@@ -548,7 +551,8 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
548 head->csum); 551 head->csum);
549 552
550 rcu_read_lock(); 553 rcu_read_lock();
551 IP6_INC_STATS_BH(__in6_dev_get(dev), IPSTATS_MIB_REASMOKS); 554 IP6_INC_STATS_BH(dev_net(dev),
555 __in6_dev_get(dev), IPSTATS_MIB_REASMOKS);
552 rcu_read_unlock(); 556 rcu_read_unlock();
553 fq->q.fragments = NULL; 557 fq->q.fragments = NULL;
554 return 1; 558 return 1;
@@ -562,7 +566,8 @@ out_oom:
562 printk(KERN_DEBUG "ip6_frag_reasm: no memory for reassembly\n"); 566 printk(KERN_DEBUG "ip6_frag_reasm: no memory for reassembly\n");
563out_fail: 567out_fail:
564 rcu_read_lock(); 568 rcu_read_lock();
565 IP6_INC_STATS_BH(__in6_dev_get(dev), IPSTATS_MIB_REASMFAILS); 569 IP6_INC_STATS_BH(dev_net(dev),
570 __in6_dev_get(dev), IPSTATS_MIB_REASMFAILS);
566 rcu_read_unlock(); 571 rcu_read_unlock();
567 return -1; 572 return -1;
568} 573}
@@ -572,24 +577,17 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
572 struct frag_hdr *fhdr; 577 struct frag_hdr *fhdr;
573 struct frag_queue *fq; 578 struct frag_queue *fq;
574 struct ipv6hdr *hdr = ipv6_hdr(skb); 579 struct ipv6hdr *hdr = ipv6_hdr(skb);
575 struct net *net; 580 struct net *net = dev_net(skb->dst->dev);
576 581
577 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMREQDS); 582 IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMREQDS);
578 583
579 /* Jumbo payload inhibits frag. header */ 584 /* Jumbo payload inhibits frag. header */
580 if (hdr->payload_len==0) { 585 if (hdr->payload_len==0)
581 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); 586 goto fail_hdr;
582 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, 587
583 skb_network_header_len(skb));
584 return -1;
585 }
586 if (!pskb_may_pull(skb, (skb_transport_offset(skb) + 588 if (!pskb_may_pull(skb, (skb_transport_offset(skb) +
587 sizeof(struct frag_hdr)))) { 589 sizeof(struct frag_hdr))))
588 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS); 590 goto fail_hdr;
589 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
590 skb_network_header_len(skb));
591 return -1;
592 }
593 591
594 hdr = ipv6_hdr(skb); 592 hdr = ipv6_hdr(skb);
595 fhdr = (struct frag_hdr *)skb_transport_header(skb); 593 fhdr = (struct frag_hdr *)skb_transport_header(skb);
@@ -597,13 +595,13 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
597 if (!(fhdr->frag_off & htons(0xFFF9))) { 595 if (!(fhdr->frag_off & htons(0xFFF9))) {
598 /* It is not a fragmented frame */ 596 /* It is not a fragmented frame */
599 skb->transport_header += sizeof(struct frag_hdr); 597 skb->transport_header += sizeof(struct frag_hdr);
600 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMOKS); 598 IP6_INC_STATS_BH(net,
599 ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMOKS);
601 600
602 IP6CB(skb)->nhoff = (u8 *)fhdr - skb_network_header(skb); 601 IP6CB(skb)->nhoff = (u8 *)fhdr - skb_network_header(skb);
603 return 1; 602 return 1;
604 } 603 }
605 604
606 net = dev_net(skb->dev);
607 if (atomic_read(&net->ipv6.frags.mem) > net->ipv6.frags.high_thresh) 605 if (atomic_read(&net->ipv6.frags.mem) > net->ipv6.frags.high_thresh)
608 ip6_evictor(net, ip6_dst_idev(skb->dst)); 606 ip6_evictor(net, ip6_dst_idev(skb->dst));
609 607
@@ -620,9 +618,14 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
620 return ret; 618 return ret;
621 } 619 }
622 620
623 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMFAILS); 621 IP6_INC_STATS_BH(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMFAILS);
624 kfree_skb(skb); 622 kfree_skb(skb);
625 return -1; 623 return -1;
624
625fail_hdr:
626 IP6_INC_STATS(net, ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
627 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb_network_header_len(skb));
628 return -1;
626} 629}
627 630
628static struct inet6_protocol frag_protocol = 631static struct inet6_protocol frag_protocol =
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 9af6115f0f50..89dc69924340 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1003,6 +1003,25 @@ int icmp6_dst_gc(void)
1003 return more; 1003 return more;
1004} 1004}
1005 1005
1006static void icmp6_clean_all(int (*func)(struct rt6_info *rt, void *arg),
1007 void *arg)
1008{
1009 struct dst_entry *dst, **pprev;
1010
1011 spin_lock_bh(&icmp6_dst_lock);
1012 pprev = &icmp6_dst_gc_list;
1013 while ((dst = *pprev) != NULL) {
1014 struct rt6_info *rt = (struct rt6_info *) dst;
1015 if (func(rt, arg)) {
1016 *pprev = dst->next;
1017 dst_free(dst);
1018 } else {
1019 pprev = &dst->next;
1020 }
1021 }
1022 spin_unlock_bh(&icmp6_dst_lock);
1023}
1024
1006static int ip6_dst_gc(struct dst_ops *ops) 1025static int ip6_dst_gc(struct dst_ops *ops)
1007{ 1026{
1008 unsigned long now = jiffies; 1027 unsigned long now = jiffies;
@@ -1814,16 +1833,19 @@ int ipv6_route_ioctl(struct net *net, unsigned int cmd, void __user *arg)
1814static int ip6_pkt_drop(struct sk_buff *skb, int code, int ipstats_mib_noroutes) 1833static int ip6_pkt_drop(struct sk_buff *skb, int code, int ipstats_mib_noroutes)
1815{ 1834{
1816 int type; 1835 int type;
1836 struct dst_entry *dst = skb->dst;
1817 switch (ipstats_mib_noroutes) { 1837 switch (ipstats_mib_noroutes) {
1818 case IPSTATS_MIB_INNOROUTES: 1838 case IPSTATS_MIB_INNOROUTES:
1819 type = ipv6_addr_type(&ipv6_hdr(skb)->daddr); 1839 type = ipv6_addr_type(&ipv6_hdr(skb)->daddr);
1820 if (type == IPV6_ADDR_ANY || type == IPV6_ADDR_RESERVED) { 1840 if (type == IPV6_ADDR_ANY || type == IPV6_ADDR_RESERVED) {
1821 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_INADDRERRORS); 1841 IP6_INC_STATS(dev_net(dst->dev), ip6_dst_idev(dst),
1842 IPSTATS_MIB_INADDRERRORS);
1822 break; 1843 break;
1823 } 1844 }
1824 /* FALLTHROUGH */ 1845 /* FALLTHROUGH */
1825 case IPSTATS_MIB_OUTNOROUTES: 1846 case IPSTATS_MIB_OUTNOROUTES:
1826 IP6_INC_STATS(ip6_dst_idev(skb->dst), ipstats_mib_noroutes); 1847 IP6_INC_STATS(dev_net(dst->dev), ip6_dst_idev(dst),
1848 ipstats_mib_noroutes);
1827 break; 1849 break;
1828 } 1850 }
1829 icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0, skb->dev); 1851 icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0, skb->dev);
@@ -1930,6 +1952,7 @@ void rt6_ifdown(struct net *net, struct net_device *dev)
1930 }; 1952 };
1931 1953
1932 fib6_clean_all(net, fib6_ifdown, 0, &adn); 1954 fib6_clean_all(net, fib6_ifdown, 0, &adn);
1955 icmp6_clean_all(fib6_ifdown, &adn);
1933} 1956}
1934 1957
1935struct rt6_mtu_change_arg 1958struct rt6_mtu_change_arg
@@ -2611,10 +2634,8 @@ static int ip6_route_net_init(struct net *net)
2611 net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template, 2634 net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template,
2612 sizeof(*net->ipv6.ip6_prohibit_entry), 2635 sizeof(*net->ipv6.ip6_prohibit_entry),
2613 GFP_KERNEL); 2636 GFP_KERNEL);
2614 if (!net->ipv6.ip6_prohibit_entry) { 2637 if (!net->ipv6.ip6_prohibit_entry)
2615 kfree(net->ipv6.ip6_null_entry); 2638 goto out_ip6_null_entry;
2616 goto out;
2617 }
2618 net->ipv6.ip6_prohibit_entry->u.dst.path = 2639 net->ipv6.ip6_prohibit_entry->u.dst.path =
2619 (struct dst_entry *)net->ipv6.ip6_prohibit_entry; 2640 (struct dst_entry *)net->ipv6.ip6_prohibit_entry;
2620 net->ipv6.ip6_prohibit_entry->u.dst.ops = net->ipv6.ip6_dst_ops; 2641 net->ipv6.ip6_prohibit_entry->u.dst.ops = net->ipv6.ip6_dst_ops;
@@ -2622,16 +2643,22 @@ static int ip6_route_net_init(struct net *net)
2622 net->ipv6.ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template, 2643 net->ipv6.ip6_blk_hole_entry = kmemdup(&ip6_blk_hole_entry_template,
2623 sizeof(*net->ipv6.ip6_blk_hole_entry), 2644 sizeof(*net->ipv6.ip6_blk_hole_entry),
2624 GFP_KERNEL); 2645 GFP_KERNEL);
2625 if (!net->ipv6.ip6_blk_hole_entry) { 2646 if (!net->ipv6.ip6_blk_hole_entry)
2626 kfree(net->ipv6.ip6_null_entry); 2647 goto out_ip6_prohibit_entry;
2627 kfree(net->ipv6.ip6_prohibit_entry);
2628 goto out;
2629 }
2630 net->ipv6.ip6_blk_hole_entry->u.dst.path = 2648 net->ipv6.ip6_blk_hole_entry->u.dst.path =
2631 (struct dst_entry *)net->ipv6.ip6_blk_hole_entry; 2649 (struct dst_entry *)net->ipv6.ip6_blk_hole_entry;
2632 net->ipv6.ip6_blk_hole_entry->u.dst.ops = net->ipv6.ip6_dst_ops; 2650 net->ipv6.ip6_blk_hole_entry->u.dst.ops = net->ipv6.ip6_dst_ops;
2633#endif 2651#endif
2634 2652
2653 net->ipv6.sysctl.flush_delay = 0;
2654 net->ipv6.sysctl.ip6_rt_max_size = 4096;
2655 net->ipv6.sysctl.ip6_rt_gc_min_interval = HZ / 2;
2656 net->ipv6.sysctl.ip6_rt_gc_timeout = 60*HZ;
2657 net->ipv6.sysctl.ip6_rt_gc_interval = 30*HZ;
2658 net->ipv6.sysctl.ip6_rt_gc_elasticity = 9;
2659 net->ipv6.sysctl.ip6_rt_mtu_expires = 10*60*HZ;
2660 net->ipv6.sysctl.ip6_rt_min_advmss = IPV6_MIN_MTU - 20 - 40;
2661
2635#ifdef CONFIG_PROC_FS 2662#ifdef CONFIG_PROC_FS
2636 proc_net_fops_create(net, "ipv6_route", 0, &ipv6_route_proc_fops); 2663 proc_net_fops_create(net, "ipv6_route", 0, &ipv6_route_proc_fops);
2637 proc_net_fops_create(net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops); 2664 proc_net_fops_create(net, "rt6_stats", S_IRUGO, &rt6_stats_seq_fops);
@@ -2642,6 +2669,12 @@ static int ip6_route_net_init(struct net *net)
2642out: 2669out:
2643 return ret; 2670 return ret;
2644 2671
2672#ifdef CONFIG_IPV6_MULTIPLE_TABLES
2673out_ip6_prohibit_entry:
2674 kfree(net->ipv6.ip6_prohibit_entry);
2675out_ip6_null_entry:
2676 kfree(net->ipv6.ip6_null_entry);
2677#endif
2645out_ip6_dst_ops: 2678out_ip6_dst_ops:
2646 release_net(net->ipv6.ip6_dst_ops->dst_net); 2679 release_net(net->ipv6.ip6_dst_ops->dst_net);
2647 kfree(net->ipv6.ip6_dst_ops); 2680 kfree(net->ipv6.ip6_dst_ops);
@@ -2688,6 +2721,8 @@ int __init ip6_route_init(void)
2688 if (ret) 2721 if (ret)
2689 goto out_kmem_cache; 2722 goto out_kmem_cache;
2690 2723
2724 ip6_dst_blackhole_ops.kmem_cachep = ip6_dst_ops_template.kmem_cachep;
2725
2691 /* Registering of the loopback is done before this portion of code, 2726 /* Registering of the loopback is done before this portion of code,
2692 * the loopback reference in rt6_info will not be taken, do it 2727 * the loopback reference in rt6_info will not be taken, do it
2693 * manually for init_net */ 2728 * manually for init_net */
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 5b90b369ccb2..e5310c9b84dc 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -330,7 +330,8 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
330 th->dest, &hdr->saddr, th->source, skb->dev->ifindex); 330 th->dest, &hdr->saddr, th->source, skb->dev->ifindex);
331 331
332 if (sk == NULL) { 332 if (sk == NULL) {
333 ICMP6_INC_STATS_BH(__in6_dev_get(skb->dev), ICMP6_MIB_INERRORS); 333 ICMP6_INC_STATS_BH(net, __in6_dev_get(skb->dev),
334 ICMP6_MIB_INERRORS);
334 return; 335 return;
335 } 336 }
336 337
@@ -941,117 +942,14 @@ static int tcp_v6_gso_send_check(struct sk_buff *skb)
941 return 0; 942 return 0;
942} 943}
943 944
944static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb) 945static void tcp_v6_send_response(struct sk_buff *skb, u32 seq, u32 ack, u32 win,
946 u32 ts, struct tcp_md5sig_key *key, int rst)
945{ 947{
946 struct tcphdr *th = tcp_hdr(skb), *t1; 948 struct tcphdr *th = tcp_hdr(skb), *t1;
947 struct sk_buff *buff; 949 struct sk_buff *buff;
948 struct flowi fl; 950 struct flowi fl;
949 struct net *net = dev_net(skb->dst->dev); 951 struct net *net = dev_net(skb->dst->dev);
950 struct sock *ctl_sk = net->ipv6.tcp_sk; 952 struct sock *ctl_sk = net->ipv6.tcp_sk;
951 unsigned int tot_len = sizeof(*th);
952#ifdef CONFIG_TCP_MD5SIG
953 struct tcp_md5sig_key *key;
954#endif
955
956 if (th->rst)
957 return;
958
959 if (!ipv6_unicast_destination(skb))
960 return;
961
962#ifdef CONFIG_TCP_MD5SIG
963 if (sk)
964 key = tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr);
965 else
966 key = NULL;
967
968 if (key)
969 tot_len += TCPOLEN_MD5SIG_ALIGNED;
970#endif
971
972 /*
973 * We need to grab some memory, and put together an RST,
974 * and then put it into the queue to be sent.
975 */
976
977 buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + tot_len,
978 GFP_ATOMIC);
979 if (buff == NULL)
980 return;
981
982 skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len);
983
984 t1 = (struct tcphdr *) skb_push(buff, tot_len);
985
986 /* Swap the send and the receive. */
987 memset(t1, 0, sizeof(*t1));
988 t1->dest = th->source;
989 t1->source = th->dest;
990 t1->doff = tot_len / 4;
991 t1->rst = 1;
992
993 if(th->ack) {
994 t1->seq = th->ack_seq;
995 } else {
996 t1->ack = 1;
997 t1->ack_seq = htonl(ntohl(th->seq) + th->syn + th->fin
998 + skb->len - (th->doff<<2));
999 }
1000
1001#ifdef CONFIG_TCP_MD5SIG
1002 if (key) {
1003 __be32 *opt = (__be32*)(t1 + 1);
1004 opt[0] = htonl((TCPOPT_NOP << 24) |
1005 (TCPOPT_NOP << 16) |
1006 (TCPOPT_MD5SIG << 8) |
1007 TCPOLEN_MD5SIG);
1008 tcp_v6_md5_hash_hdr((__u8 *)&opt[1], key,
1009 &ipv6_hdr(skb)->daddr,
1010 &ipv6_hdr(skb)->saddr, t1);
1011 }
1012#endif
1013
1014 buff->csum = csum_partial((char *)t1, sizeof(*t1), 0);
1015
1016 memset(&fl, 0, sizeof(fl));
1017 ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr);
1018 ipv6_addr_copy(&fl.fl6_src, &ipv6_hdr(skb)->daddr);
1019
1020 t1->check = csum_ipv6_magic(&fl.fl6_src, &fl.fl6_dst,
1021 sizeof(*t1), IPPROTO_TCP,
1022 buff->csum);
1023
1024 fl.proto = IPPROTO_TCP;
1025 fl.oif = inet6_iif(skb);
1026 fl.fl_ip_dport = t1->dest;
1027 fl.fl_ip_sport = t1->source;
1028 security_skb_classify_flow(skb, &fl);
1029
1030 /* Pass a socket to ip6_dst_lookup either it is for RST
1031 * Underlying function will use this to retrieve the network
1032 * namespace
1033 */
1034 if (!ip6_dst_lookup(ctl_sk, &buff->dst, &fl)) {
1035
1036 if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) {
1037 ip6_xmit(ctl_sk, buff, &fl, NULL, 0);
1038 TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS);
1039 TCP_INC_STATS_BH(net, TCP_MIB_OUTRSTS);
1040 return;
1041 }
1042 }
1043
1044 kfree_skb(buff);
1045}
1046
1047static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts,
1048 struct tcp_md5sig_key *key)
1049{
1050 struct tcphdr *th = tcp_hdr(skb), *t1;
1051 struct sk_buff *buff;
1052 struct flowi fl;
1053 struct net *net = dev_net(skb->dev);
1054 struct sock *ctl_sk = net->ipv6.tcp_sk;
1055 unsigned int tot_len = sizeof(struct tcphdr); 953 unsigned int tot_len = sizeof(struct tcphdr);
1056 __be32 *topt; 954 __be32 *topt;
1057 955
@@ -1069,16 +967,17 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
1069 967
1070 skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len); 968 skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len);
1071 969
1072 t1 = (struct tcphdr *) skb_push(buff,tot_len); 970 t1 = (struct tcphdr *) skb_push(buff, tot_len);
1073 971
1074 /* Swap the send and the receive. */ 972 /* Swap the send and the receive. */
1075 memset(t1, 0, sizeof(*t1)); 973 memset(t1, 0, sizeof(*t1));
1076 t1->dest = th->source; 974 t1->dest = th->source;
1077 t1->source = th->dest; 975 t1->source = th->dest;
1078 t1->doff = tot_len/4; 976 t1->doff = tot_len / 4;
1079 t1->seq = htonl(seq); 977 t1->seq = htonl(seq);
1080 t1->ack_seq = htonl(ack); 978 t1->ack_seq = htonl(ack);
1081 t1->ack = 1; 979 t1->ack = !rst || !th->ack;
980 t1->rst = rst;
1082 t1->window = htons(win); 981 t1->window = htons(win);
1083 982
1084 topt = (__be32 *)(t1 + 1); 983 topt = (__be32 *)(t1 + 1);
@@ -1087,7 +986,7 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
1087 *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | 986 *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
1088 (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); 987 (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
1089 *topt++ = htonl(tcp_time_stamp); 988 *topt++ = htonl(tcp_time_stamp);
1090 *topt = htonl(ts); 989 *topt++ = htonl(ts);
1091 } 990 }
1092 991
1093#ifdef CONFIG_TCP_MD5SIG 992#ifdef CONFIG_TCP_MD5SIG
@@ -1116,10 +1015,16 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
1116 fl.fl_ip_sport = t1->source; 1015 fl.fl_ip_sport = t1->source;
1117 security_skb_classify_flow(skb, &fl); 1016 security_skb_classify_flow(skb, &fl);
1118 1017
1018 /* Pass a socket to ip6_dst_lookup either it is for RST
1019 * Underlying function will use this to retrieve the network
1020 * namespace
1021 */
1119 if (!ip6_dst_lookup(ctl_sk, &buff->dst, &fl)) { 1022 if (!ip6_dst_lookup(ctl_sk, &buff->dst, &fl)) {
1120 if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) { 1023 if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) {
1121 ip6_xmit(ctl_sk, buff, &fl, NULL, 0); 1024 ip6_xmit(ctl_sk, buff, &fl, NULL, 0);
1122 TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS); 1025 TCP_INC_STATS_BH(net, TCP_MIB_OUTSEGS);
1026 if (rst)
1027 TCP_INC_STATS_BH(net, TCP_MIB_OUTRSTS);
1123 return; 1028 return;
1124 } 1029 }
1125 } 1030 }
@@ -1127,6 +1032,38 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
1127 kfree_skb(buff); 1032 kfree_skb(buff);
1128} 1033}
1129 1034
1035static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
1036{
1037 struct tcphdr *th = tcp_hdr(skb);
1038 u32 seq = 0, ack_seq = 0;
1039 struct tcp_md5sig_key *key = NULL;
1040
1041 if (th->rst)
1042 return;
1043
1044 if (!ipv6_unicast_destination(skb))
1045 return;
1046
1047#ifdef CONFIG_TCP_MD5SIG
1048 if (sk)
1049 key = tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr);
1050#endif
1051
1052 if (th->ack)
1053 seq = ntohl(th->ack_seq);
1054 else
1055 ack_seq = ntohl(th->seq) + th->syn + th->fin + skb->len -
1056 (th->doff << 2);
1057
1058 tcp_v6_send_response(skb, seq, ack_seq, 0, 0, key, 1);
1059}
1060
1061static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts,
1062 struct tcp_md5sig_key *key)
1063{
1064 tcp_v6_send_response(skb, seq, ack, win, ts, key, 0);
1065}
1066
1130static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) 1067static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
1131{ 1068{
1132 struct inet_timewait_sock *tw = inet_twsk(sk); 1069 struct inet_timewait_sock *tw = inet_twsk(sk);
@@ -1286,7 +1223,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1286 struct request_sock *req, 1223 struct request_sock *req,
1287 struct dst_entry *dst) 1224 struct dst_entry *dst)
1288{ 1225{
1289 struct inet6_request_sock *treq = inet6_rsk(req); 1226 struct inet6_request_sock *treq;
1290 struct ipv6_pinfo *newnp, *np = inet6_sk(sk); 1227 struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
1291 struct tcp6_sock *newtcp6sk; 1228 struct tcp6_sock *newtcp6sk;
1292 struct inet_sock *newinet; 1229 struct inet_sock *newinet;
@@ -1350,6 +1287,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1350 return newsk; 1287 return newsk;
1351 } 1288 }
1352 1289
1290 treq = inet6_rsk(req);
1353 opt = np->opt; 1291 opt = np->opt;
1354 1292
1355 if (sk_acceptq_is_full(sk)) 1293 if (sk_acceptq_is_full(sk))
@@ -1680,11 +1618,7 @@ static int tcp_v6_rcv(struct sk_buff *skb)
1680 TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(ipv6_hdr(skb)); 1618 TCP_SKB_CB(skb)->flags = ipv6_get_dsfield(ipv6_hdr(skb));
1681 TCP_SKB_CB(skb)->sacked = 0; 1619 TCP_SKB_CB(skb)->sacked = 0;
1682 1620
1683 sk = __inet6_lookup(net, &tcp_hashinfo, 1621 sk = __inet6_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest);
1684 &ipv6_hdr(skb)->saddr, th->source,
1685 &ipv6_hdr(skb)->daddr, ntohs(th->dest),
1686 inet6_iif(skb));
1687
1688 if (!sk) 1622 if (!sk)
1689 goto no_tcp_socket; 1623 goto no_tcp_socket;
1690 1624
@@ -2148,6 +2082,7 @@ static int tcpv6_net_init(struct net *net)
2148static void tcpv6_net_exit(struct net *net) 2082static void tcpv6_net_exit(struct net *net)
2149{ 2083{
2150 inet_ctl_sock_destroy(net->ipv6.tcp_sk); 2084 inet_ctl_sock_destroy(net->ipv6.tcp_sk);
2085 inet_twsk_purge(net, &tcp_hashinfo, &tcp_death_row, AF_INET6);
2151} 2086}
2152 2087
2153static struct pernet_operations tcpv6_net_ops = { 2088static struct pernet_operations tcpv6_net_ops = {
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index a6aecf76a71b..e51da8c092fa 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -107,6 +107,21 @@ static struct sock *__udp6_lib_lookup(struct net *net,
107 return result; 107 return result;
108} 108}
109 109
110static struct sock *__udp6_lib_lookup_skb(struct sk_buff *skb,
111 __be16 sport, __be16 dport,
112 struct hlist_head udptable[])
113{
114 struct sock *sk;
115 struct ipv6hdr *iph = ipv6_hdr(skb);
116
117 if (unlikely(sk = skb_steal_sock(skb)))
118 return sk;
119 else
120 return __udp6_lib_lookup(dev_net(skb->dst->dev), &iph->saddr, sport,
121 &iph->daddr, dport, inet6_iif(skb),
122 udptable);
123}
124
110/* 125/*
111 * This should be easy, if there is something there we 126 * This should be easy, if there is something there we
112 * return it, otherwise we block. 127 * return it, otherwise we block.
@@ -488,8 +503,7 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
488 * check socket cache ... must talk to Alan about his plans 503 * check socket cache ... must talk to Alan about his plans
489 * for sock caches... i'll skip this for now. 504 * for sock caches... i'll skip this for now.
490 */ 505 */
491 sk = __udp6_lib_lookup(net, saddr, uh->source, 506 sk = __udp6_lib_lookup_skb(skb, uh->source, uh->dest, udptable);
492 daddr, uh->dest, inet6_iif(skb), udptable);
493 507
494 if (sk == NULL) { 508 if (sk == NULL) {
495 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) 509 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c
index f6cdcb348e05..3cd1a1ac3d6c 100644
--- a/net/ipv6/udplite.c
+++ b/net/ipv6/udplite.c
@@ -13,8 +13,6 @@
13 */ 13 */
14#include "udp_impl.h" 14#include "udp_impl.h"
15 15
16DEFINE_SNMP_STAT(struct udp_mib, udplite_stats_in6) __read_mostly;
17
18static int udplitev6_rcv(struct sk_buff *skb) 16static int udplitev6_rcv(struct sk_buff *skb)
19{ 17{
20 return __udp6_lib_rcv(skb, udplite_hash, IPPROTO_UDPLITE); 18 return __udp6_lib_rcv(skb, udplite_hash, IPPROTO_UDPLITE);
diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c
index 705959b31e24..d7b54b5bfa69 100644
--- a/net/iucv/iucv.c
+++ b/net/iucv/iucv.c
@@ -524,7 +524,6 @@ static int iucv_enable(void)
524 get_online_cpus(); 524 get_online_cpus();
525 for_each_online_cpu(cpu) 525 for_each_online_cpu(cpu)
526 smp_call_function_single(cpu, iucv_declare_cpu, NULL, 1); 526 smp_call_function_single(cpu, iucv_declare_cpu, NULL, 1);
527 preempt_enable();
528 if (cpus_empty(iucv_buffer_cpumask)) 527 if (cpus_empty(iucv_buffer_cpumask))
529 /* No cpu could declare an iucv buffer. */ 528 /* No cpu could declare an iucv buffer. */
530 goto out_path; 529 goto out_path;
@@ -547,7 +546,9 @@ out:
547 */ 546 */
548static void iucv_disable(void) 547static void iucv_disable(void)
549{ 548{
549 get_online_cpus();
550 on_each_cpu(iucv_retrieve_cpu, NULL, 1); 550 on_each_cpu(iucv_retrieve_cpu, NULL, 1);
551 put_online_cpus();
551 kfree(iucv_path_table); 552 kfree(iucv_path_table);
552} 553}
553 554
diff --git a/net/key/af_key.c b/net/key/af_key.c
index d628df97e02e..e55e0441e4d9 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -58,6 +58,7 @@ struct pfkey_sock {
58 struct xfrm_policy_walk policy; 58 struct xfrm_policy_walk policy;
59 struct xfrm_state_walk state; 59 struct xfrm_state_walk state;
60 } u; 60 } u;
61 struct sk_buff *skb;
61 } dump; 62 } dump;
62}; 63};
63 64
@@ -73,22 +74,22 @@ static int pfkey_can_dump(struct sock *sk)
73 return 0; 74 return 0;
74} 75}
75 76
76static int pfkey_do_dump(struct pfkey_sock *pfk) 77static void pfkey_terminate_dump(struct pfkey_sock *pfk)
77{ 78{
78 int rc; 79 if (pfk->dump.dump) {
79 80 if (pfk->dump.skb) {
80 rc = pfk->dump.dump(pfk); 81 kfree_skb(pfk->dump.skb);
81 if (rc == -ENOBUFS) 82 pfk->dump.skb = NULL;
82 return 0; 83 }
83 84 pfk->dump.done(pfk);
84 pfk->dump.done(pfk); 85 pfk->dump.dump = NULL;
85 pfk->dump.dump = NULL; 86 pfk->dump.done = NULL;
86 pfk->dump.done = NULL; 87 }
87 return rc;
88} 88}
89 89
90static void pfkey_sock_destruct(struct sock *sk) 90static void pfkey_sock_destruct(struct sock *sk)
91{ 91{
92 pfkey_terminate_dump(pfkey_sk(sk));
92 skb_queue_purge(&sk->sk_receive_queue); 93 skb_queue_purge(&sk->sk_receive_queue);
93 94
94 if (!sock_flag(sk, SOCK_DEAD)) { 95 if (!sock_flag(sk, SOCK_DEAD)) {
@@ -310,6 +311,31 @@ static int pfkey_broadcast(struct sk_buff *skb, gfp_t allocation,
310 return err; 311 return err;
311} 312}
312 313
314static int pfkey_do_dump(struct pfkey_sock *pfk)
315{
316 struct sadb_msg *hdr;
317 int rc;
318
319 rc = pfk->dump.dump(pfk);
320 if (rc == -ENOBUFS)
321 return 0;
322
323 if (pfk->dump.skb) {
324 if (!pfkey_can_dump(&pfk->sk))
325 return 0;
326
327 hdr = (struct sadb_msg *) pfk->dump.skb->data;
328 hdr->sadb_msg_seq = 0;
329 hdr->sadb_msg_errno = rc;
330 pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE,
331 &pfk->sk);
332 pfk->dump.skb = NULL;
333 }
334
335 pfkey_terminate_dump(pfk);
336 return rc;
337}
338
313static inline void pfkey_hdr_dup(struct sadb_msg *new, struct sadb_msg *orig) 339static inline void pfkey_hdr_dup(struct sadb_msg *new, struct sadb_msg *orig)
314{ 340{
315 *new = *orig; 341 *new = *orig;
@@ -372,6 +398,7 @@ static u8 sadb_ext_min_len[] = {
372 [SADB_X_EXT_NAT_T_DPORT] = (u8) sizeof(struct sadb_x_nat_t_port), 398 [SADB_X_EXT_NAT_T_DPORT] = (u8) sizeof(struct sadb_x_nat_t_port),
373 [SADB_X_EXT_NAT_T_OA] = (u8) sizeof(struct sadb_address), 399 [SADB_X_EXT_NAT_T_OA] = (u8) sizeof(struct sadb_address),
374 [SADB_X_EXT_SEC_CTX] = (u8) sizeof(struct sadb_x_sec_ctx), 400 [SADB_X_EXT_SEC_CTX] = (u8) sizeof(struct sadb_x_sec_ctx),
401 [SADB_X_EXT_KMADDRESS] = (u8) sizeof(struct sadb_x_kmaddress),
375}; 402};
376 403
377/* Verify sadb_address_{len,prefixlen} against sa_family. */ 404/* Verify sadb_address_{len,prefixlen} against sa_family. */
@@ -1736,9 +1763,14 @@ static int dump_sa(struct xfrm_state *x, int count, void *ptr)
1736 out_hdr->sadb_msg_satype = pfkey_proto2satype(x->id.proto); 1763 out_hdr->sadb_msg_satype = pfkey_proto2satype(x->id.proto);
1737 out_hdr->sadb_msg_errno = 0; 1764 out_hdr->sadb_msg_errno = 0;
1738 out_hdr->sadb_msg_reserved = 0; 1765 out_hdr->sadb_msg_reserved = 0;
1739 out_hdr->sadb_msg_seq = count; 1766 out_hdr->sadb_msg_seq = count + 1;
1740 out_hdr->sadb_msg_pid = pfk->dump.msg_pid; 1767 out_hdr->sadb_msg_pid = pfk->dump.msg_pid;
1741 pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, &pfk->sk); 1768
1769 if (pfk->dump.skb)
1770 pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE,
1771 &pfk->sk);
1772 pfk->dump.skb = out_skb;
1773
1742 return 0; 1774 return 0;
1743} 1775}
1744 1776
@@ -2237,7 +2269,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
2237 return 0; 2269 return 0;
2238 2270
2239out: 2271out:
2240 xp->dead = 1; 2272 xp->walk.dead = 1;
2241 xfrm_policy_destroy(xp); 2273 xfrm_policy_destroy(xp);
2242 return err; 2274 return err;
2243} 2275}
@@ -2309,6 +2341,7 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg
2309 2341
2310 c.seq = hdr->sadb_msg_seq; 2342 c.seq = hdr->sadb_msg_seq;
2311 c.pid = hdr->sadb_msg_pid; 2343 c.pid = hdr->sadb_msg_pid;
2344 c.data.byid = 0;
2312 c.event = XFRM_MSG_DELPOLICY; 2345 c.event = XFRM_MSG_DELPOLICY;
2313 km_policy_notify(xp, pol->sadb_x_policy_dir-1, &c); 2346 km_policy_notify(xp, pol->sadb_x_policy_dir-1, &c);
2314 2347
@@ -2353,24 +2386,21 @@ static int pfkey_sockaddr_pair_size(sa_family_t family)
2353 return PFKEY_ALIGN8(pfkey_sockaddr_len(family) * 2); 2386 return PFKEY_ALIGN8(pfkey_sockaddr_len(family) * 2);
2354} 2387}
2355 2388
2356static int parse_sockaddr_pair(struct sadb_x_ipsecrequest *rq, 2389static int parse_sockaddr_pair(struct sockaddr *sa, int ext_len,
2357 xfrm_address_t *saddr, xfrm_address_t *daddr, 2390 xfrm_address_t *saddr, xfrm_address_t *daddr,
2358 u16 *family) 2391 u16 *family)
2359{ 2392{
2360 u8 *sa = (u8 *) (rq + 1);
2361 int af, socklen; 2393 int af, socklen;
2362 2394
2363 if (rq->sadb_x_ipsecrequest_len < 2395 if (ext_len < pfkey_sockaddr_pair_size(sa->sa_family))
2364 pfkey_sockaddr_pair_size(((struct sockaddr *)sa)->sa_family))
2365 return -EINVAL; 2396 return -EINVAL;
2366 2397
2367 af = pfkey_sockaddr_extract((struct sockaddr *) sa, 2398 af = pfkey_sockaddr_extract(sa, saddr);
2368 saddr);
2369 if (!af) 2399 if (!af)
2370 return -EINVAL; 2400 return -EINVAL;
2371 2401
2372 socklen = pfkey_sockaddr_len(af); 2402 socklen = pfkey_sockaddr_len(af);
2373 if (pfkey_sockaddr_extract((struct sockaddr *) (sa + socklen), 2403 if (pfkey_sockaddr_extract((struct sockaddr *) (((u8 *)sa) + socklen),
2374 daddr) != af) 2404 daddr) != af)
2375 return -EINVAL; 2405 return -EINVAL;
2376 2406
@@ -2390,7 +2420,9 @@ static int ipsecrequests_to_migrate(struct sadb_x_ipsecrequest *rq1, int len,
2390 return -EINVAL; 2420 return -EINVAL;
2391 2421
2392 /* old endoints */ 2422 /* old endoints */
2393 err = parse_sockaddr_pair(rq1, &m->old_saddr, &m->old_daddr, 2423 err = parse_sockaddr_pair((struct sockaddr *)(rq1 + 1),
2424 rq1->sadb_x_ipsecrequest_len,
2425 &m->old_saddr, &m->old_daddr,
2394 &m->old_family); 2426 &m->old_family);
2395 if (err) 2427 if (err)
2396 return err; 2428 return err;
@@ -2403,7 +2435,9 @@ static int ipsecrequests_to_migrate(struct sadb_x_ipsecrequest *rq1, int len,
2403 return -EINVAL; 2435 return -EINVAL;
2404 2436
2405 /* new endpoints */ 2437 /* new endpoints */
2406 err = parse_sockaddr_pair(rq2, &m->new_saddr, &m->new_daddr, 2438 err = parse_sockaddr_pair((struct sockaddr *)(rq2 + 1),
2439 rq2->sadb_x_ipsecrequest_len,
2440 &m->new_saddr, &m->new_daddr,
2407 &m->new_family); 2441 &m->new_family);
2408 if (err) 2442 if (err)
2409 return err; 2443 return err;
@@ -2429,29 +2463,40 @@ static int pfkey_migrate(struct sock *sk, struct sk_buff *skb,
2429 int i, len, ret, err = -EINVAL; 2463 int i, len, ret, err = -EINVAL;
2430 u8 dir; 2464 u8 dir;
2431 struct sadb_address *sa; 2465 struct sadb_address *sa;
2466 struct sadb_x_kmaddress *kma;
2432 struct sadb_x_policy *pol; 2467 struct sadb_x_policy *pol;
2433 struct sadb_x_ipsecrequest *rq; 2468 struct sadb_x_ipsecrequest *rq;
2434 struct xfrm_selector sel; 2469 struct xfrm_selector sel;
2435 struct xfrm_migrate m[XFRM_MAX_DEPTH]; 2470 struct xfrm_migrate m[XFRM_MAX_DEPTH];
2471 struct xfrm_kmaddress k;
2436 2472
2437 if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC - 1], 2473 if (!present_and_same_family(ext_hdrs[SADB_EXT_ADDRESS_SRC - 1],
2438 ext_hdrs[SADB_EXT_ADDRESS_DST - 1]) || 2474 ext_hdrs[SADB_EXT_ADDRESS_DST - 1]) ||
2439 !ext_hdrs[SADB_X_EXT_POLICY - 1]) { 2475 !ext_hdrs[SADB_X_EXT_POLICY - 1]) {
2440 err = -EINVAL; 2476 err = -EINVAL;
2441 goto out; 2477 goto out;
2442 } 2478 }
2443 2479
2480 kma = ext_hdrs[SADB_X_EXT_KMADDRESS - 1];
2444 pol = ext_hdrs[SADB_X_EXT_POLICY - 1]; 2481 pol = ext_hdrs[SADB_X_EXT_POLICY - 1];
2445 if (!pol) {
2446 err = -EINVAL;
2447 goto out;
2448 }
2449 2482
2450 if (pol->sadb_x_policy_dir >= IPSEC_DIR_MAX) { 2483 if (pol->sadb_x_policy_dir >= IPSEC_DIR_MAX) {
2451 err = -EINVAL; 2484 err = -EINVAL;
2452 goto out; 2485 goto out;
2453 } 2486 }
2454 2487
2488 if (kma) {
2489 /* convert sadb_x_kmaddress to xfrm_kmaddress */
2490 k.reserved = kma->sadb_x_kmaddress_reserved;
2491 ret = parse_sockaddr_pair((struct sockaddr *)(kma + 1),
2492 8*(kma->sadb_x_kmaddress_len) - sizeof(*kma),
2493 &k.local, &k.remote, &k.family);
2494 if (ret < 0) {
2495 err = ret;
2496 goto out;
2497 }
2498 }
2499
2455 dir = pol->sadb_x_policy_dir - 1; 2500 dir = pol->sadb_x_policy_dir - 1;
2456 memset(&sel, 0, sizeof(sel)); 2501 memset(&sel, 0, sizeof(sel));
2457 2502
@@ -2496,7 +2541,8 @@ static int pfkey_migrate(struct sock *sk, struct sk_buff *skb,
2496 goto out; 2541 goto out;
2497 } 2542 }
2498 2543
2499 return xfrm_migrate(&sel, dir, XFRM_POLICY_TYPE_MAIN, m, i); 2544 return xfrm_migrate(&sel, dir, XFRM_POLICY_TYPE_MAIN, m, i,
2545 kma ? &k : NULL);
2500 2546
2501 out: 2547 out:
2502 return err; 2548 return err;
@@ -2575,9 +2621,14 @@ static int dump_sp(struct xfrm_policy *xp, int dir, int count, void *ptr)
2575 out_hdr->sadb_msg_type = SADB_X_SPDDUMP; 2621 out_hdr->sadb_msg_type = SADB_X_SPDDUMP;
2576 out_hdr->sadb_msg_satype = SADB_SATYPE_UNSPEC; 2622 out_hdr->sadb_msg_satype = SADB_SATYPE_UNSPEC;
2577 out_hdr->sadb_msg_errno = 0; 2623 out_hdr->sadb_msg_errno = 0;
2578 out_hdr->sadb_msg_seq = count; 2624 out_hdr->sadb_msg_seq = count + 1;
2579 out_hdr->sadb_msg_pid = pfk->dump.msg_pid; 2625 out_hdr->sadb_msg_pid = pfk->dump.msg_pid;
2580 pfkey_broadcast(out_skb, GFP_ATOMIC, BROADCAST_ONE, &pfk->sk); 2626
2627 if (pfk->dump.skb)
2628 pfkey_broadcast(pfk->dump.skb, GFP_ATOMIC, BROADCAST_ONE,
2629 &pfk->sk);
2630 pfk->dump.skb = out_skb;
2631
2581 return 0; 2632 return 0;
2582} 2633}
2583 2634
@@ -3283,6 +3334,32 @@ static int set_sadb_address(struct sk_buff *skb, int sasize, int type,
3283 return 0; 3334 return 0;
3284} 3335}
3285 3336
3337
3338static int set_sadb_kmaddress(struct sk_buff *skb, struct xfrm_kmaddress *k)
3339{
3340 struct sadb_x_kmaddress *kma;
3341 u8 *sa;
3342 int family = k->family;
3343 int socklen = pfkey_sockaddr_len(family);
3344 int size_req;
3345
3346 size_req = (sizeof(struct sadb_x_kmaddress) +
3347 pfkey_sockaddr_pair_size(family));
3348
3349 kma = (struct sadb_x_kmaddress *)skb_put(skb, size_req);
3350 memset(kma, 0, size_req);
3351 kma->sadb_x_kmaddress_len = size_req / 8;
3352 kma->sadb_x_kmaddress_exttype = SADB_X_EXT_KMADDRESS;
3353 kma->sadb_x_kmaddress_reserved = k->reserved;
3354
3355 sa = (u8 *)(kma + 1);
3356 if (!pfkey_sockaddr_fill(&k->local, 0, (struct sockaddr *)sa, family) ||
3357 !pfkey_sockaddr_fill(&k->remote, 0, (struct sockaddr *)(sa+socklen), family))
3358 return -EINVAL;
3359
3360 return 0;
3361}
3362
3286static int set_ipsecrequest(struct sk_buff *skb, 3363static int set_ipsecrequest(struct sk_buff *skb,
3287 uint8_t proto, uint8_t mode, int level, 3364 uint8_t proto, uint8_t mode, int level,
3288 uint32_t reqid, uint8_t family, 3365 uint32_t reqid, uint8_t family,
@@ -3315,7 +3392,8 @@ static int set_ipsecrequest(struct sk_buff *skb,
3315 3392
3316#ifdef CONFIG_NET_KEY_MIGRATE 3393#ifdef CONFIG_NET_KEY_MIGRATE
3317static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type, 3394static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
3318 struct xfrm_migrate *m, int num_bundles) 3395 struct xfrm_migrate *m, int num_bundles,
3396 struct xfrm_kmaddress *k)
3319{ 3397{
3320 int i; 3398 int i;
3321 int sasize_sel; 3399 int sasize_sel;
@@ -3332,6 +3410,12 @@ static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
3332 if (num_bundles <= 0 || num_bundles > XFRM_MAX_DEPTH) 3410 if (num_bundles <= 0 || num_bundles > XFRM_MAX_DEPTH)
3333 return -EINVAL; 3411 return -EINVAL;
3334 3412
3413 if (k != NULL) {
3414 /* addresses for KM */
3415 size += PFKEY_ALIGN8(sizeof(struct sadb_x_kmaddress) +
3416 pfkey_sockaddr_pair_size(k->family));
3417 }
3418
3335 /* selector */ 3419 /* selector */
3336 sasize_sel = pfkey_sockaddr_size(sel->family); 3420 sasize_sel = pfkey_sockaddr_size(sel->family);
3337 if (!sasize_sel) 3421 if (!sasize_sel)
@@ -3368,6 +3452,10 @@ static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
3368 hdr->sadb_msg_seq = 0; 3452 hdr->sadb_msg_seq = 0;
3369 hdr->sadb_msg_pid = 0; 3453 hdr->sadb_msg_pid = 0;
3370 3454
3455 /* Addresses to be used by KM for negotiation, if ext is available */
3456 if (k != NULL && (set_sadb_kmaddress(skb, k) < 0))
3457 return -EINVAL;
3458
3371 /* selector src */ 3459 /* selector src */
3372 set_sadb_address(skb, sasize_sel, SADB_EXT_ADDRESS_SRC, sel); 3460 set_sadb_address(skb, sasize_sel, SADB_EXT_ADDRESS_SRC, sel);
3373 3461
@@ -3413,7 +3501,8 @@ err:
3413} 3501}
3414#else 3502#else
3415static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type, 3503static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
3416 struct xfrm_migrate *m, int num_bundles) 3504 struct xfrm_migrate *m, int num_bundles,
3505 struct xfrm_kmaddress *k)
3417{ 3506{
3418 return -ENOPROTOOPT; 3507 return -ENOPROTOOPT;
3419} 3508}
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index 80d693392b0f..7f710a27e91c 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -22,6 +22,11 @@ config MAC80211_RC_PID
22 mac80211 that uses a PID controller to select the TX 22 mac80211 that uses a PID controller to select the TX
23 rate. 23 rate.
24 24
25config MAC80211_RC_MINSTREL
26 bool "Minstrel"
27 ---help---
28 This option enables the 'minstrel' TX rate control algorithm
29
25choice 30choice
26 prompt "Default rate control algorithm" 31 prompt "Default rate control algorithm"
27 default MAC80211_RC_DEFAULT_PID 32 default MAC80211_RC_DEFAULT_PID
@@ -39,11 +44,19 @@ config MAC80211_RC_DEFAULT_PID
39 default rate control algorithm. You should choose 44 default rate control algorithm. You should choose
40 this unless you know what you are doing. 45 this unless you know what you are doing.
41 46
47config MAC80211_RC_DEFAULT_MINSTREL
48 bool "Minstrel"
49 depends on MAC80211_RC_MINSTREL
50 ---help---
51 Select Minstrel as the default rate control algorithm.
52
53
42endchoice 54endchoice
43 55
44config MAC80211_RC_DEFAULT 56config MAC80211_RC_DEFAULT
45 string 57 string
46 default "pid" if MAC80211_RC_DEFAULT_PID 58 default "pid" if MAC80211_RC_DEFAULT_PID
59 default "minstrel" if MAC80211_RC_DEFAULT_MINSTREL
47 default "" 60 default ""
48 61
49endmenu 62endmenu
@@ -179,19 +192,6 @@ config MAC80211_VERBOSE_MPL_DEBUG
179 192
180 Do not select this option. 193 Do not select this option.
181 194
182config MAC80211_LOWTX_FRAME_DUMP
183 bool "Debug frame dumping"
184 depends on MAC80211_DEBUG_MENU
185 ---help---
186 Selecting this option will cause the stack to
187 print a message for each frame that is handed
188 to the lowlevel driver for transmission. This
189 message includes all MAC addresses and the
190 frame control field.
191
192 If unsure, say N and insert the debugging code
193 you require into the driver you are debugging.
194
195config MAC80211_DEBUG_COUNTERS 195config MAC80211_DEBUG_COUNTERS
196 bool "Extra statistics for TX/RX debugging" 196 bool "Extra statistics for TX/RX debugging"
197 depends on MAC80211_DEBUG_MENU 197 depends on MAC80211_DEBUG_MENU
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index a169b0201d61..31cfd1f89a72 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -7,6 +7,8 @@ mac80211-y := \
7 sta_info.o \ 7 sta_info.o \
8 wep.o \ 8 wep.o \
9 wpa.o \ 9 wpa.o \
10 scan.o \
11 ht.o \
10 mlme.o \ 12 mlme.o \
11 iface.o \ 13 iface.o \
12 rate.o \ 14 rate.o \
@@ -15,6 +17,7 @@ mac80211-y := \
15 aes_ccm.o \ 17 aes_ccm.o \
16 cfg.o \ 18 cfg.o \
17 rx.o \ 19 rx.o \
20 spectmgmt.o \
18 tx.o \ 21 tx.o \
19 key.o \ 22 key.o \
20 util.o \ 23 util.o \
@@ -38,4 +41,8 @@ mac80211-$(CONFIG_MAC80211_MESH) += \
38rc80211_pid-y := rc80211_pid_algo.o 41rc80211_pid-y := rc80211_pid_algo.o
39rc80211_pid-$(CONFIG_MAC80211_DEBUGFS) += rc80211_pid_debugfs.o 42rc80211_pid-$(CONFIG_MAC80211_DEBUGFS) += rc80211_pid_debugfs.o
40 43
44rc80211_minstrel-y := rc80211_minstrel.o
45rc80211_minstrel-$(CONFIG_MAC80211_DEBUGFS) += rc80211_minstrel_debugfs.o
46
41mac80211-$(CONFIG_MAC80211_RC_PID) += $(rc80211_pid-y) 47mac80211-$(CONFIG_MAC80211_RC_PID) += $(rc80211_pid-y)
48mac80211-$(CONFIG_MAC80211_RC_MINSTREL) += $(rc80211_minstrel-y)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 297c257864c7..855126a3039d 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -17,26 +17,26 @@
17#include "rate.h" 17#include "rate.h"
18#include "mesh.h" 18#include "mesh.h"
19 19
20static enum ieee80211_if_types 20struct ieee80211_hw *wiphy_to_hw(struct wiphy *wiphy)
21nl80211_type_to_mac80211_type(enum nl80211_iftype type) 21{
22 struct ieee80211_local *local = wiphy_priv(wiphy);
23 return &local->hw;
24}
25EXPORT_SYMBOL(wiphy_to_hw);
26
27static bool nl80211_type_check(enum nl80211_iftype type)
22{ 28{
23 switch (type) { 29 switch (type) {
24 case NL80211_IFTYPE_UNSPECIFIED:
25 return IEEE80211_IF_TYPE_STA;
26 case NL80211_IFTYPE_ADHOC: 30 case NL80211_IFTYPE_ADHOC:
27 return IEEE80211_IF_TYPE_IBSS;
28 case NL80211_IFTYPE_STATION: 31 case NL80211_IFTYPE_STATION:
29 return IEEE80211_IF_TYPE_STA;
30 case NL80211_IFTYPE_MONITOR: 32 case NL80211_IFTYPE_MONITOR:
31 return IEEE80211_IF_TYPE_MNTR;
32#ifdef CONFIG_MAC80211_MESH 33#ifdef CONFIG_MAC80211_MESH
33 case NL80211_IFTYPE_MESH_POINT: 34 case NL80211_IFTYPE_MESH_POINT:
34 return IEEE80211_IF_TYPE_MESH_POINT;
35#endif 35#endif
36 case NL80211_IFTYPE_WDS: 36 case NL80211_IFTYPE_WDS:
37 return IEEE80211_IF_TYPE_WDS; 37 return true;
38 default: 38 default:
39 return IEEE80211_IF_TYPE_INVALID; 39 return false;
40 } 40 }
41} 41}
42 42
@@ -45,17 +45,15 @@ static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
45 struct vif_params *params) 45 struct vif_params *params)
46{ 46{
47 struct ieee80211_local *local = wiphy_priv(wiphy); 47 struct ieee80211_local *local = wiphy_priv(wiphy);
48 enum ieee80211_if_types itype;
49 struct net_device *dev; 48 struct net_device *dev;
50 struct ieee80211_sub_if_data *sdata; 49 struct ieee80211_sub_if_data *sdata;
51 int err; 50 int err;
52 51
53 itype = nl80211_type_to_mac80211_type(type); 52 if (!nl80211_type_check(type))
54 if (itype == IEEE80211_IF_TYPE_INVALID)
55 return -EINVAL; 53 return -EINVAL;
56 54
57 err = ieee80211_if_add(local, name, &dev, itype, params); 55 err = ieee80211_if_add(local, name, &dev, type, params);
58 if (err || itype != IEEE80211_IF_TYPE_MNTR || !flags) 56 if (err || type != NL80211_IFTYPE_MONITOR || !flags)
59 return err; 57 return err;
60 58
61 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 59 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -66,13 +64,16 @@ static int ieee80211_add_iface(struct wiphy *wiphy, char *name,
66static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex) 64static int ieee80211_del_iface(struct wiphy *wiphy, int ifindex)
67{ 65{
68 struct net_device *dev; 66 struct net_device *dev;
67 struct ieee80211_sub_if_data *sdata;
69 68
70 /* we're under RTNL */ 69 /* we're under RTNL */
71 dev = __dev_get_by_index(&init_net, ifindex); 70 dev = __dev_get_by_index(&init_net, ifindex);
72 if (!dev) 71 if (!dev)
73 return -ENODEV; 72 return -ENODEV;
74 73
75 ieee80211_if_remove(dev); 74 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
75
76 ieee80211_if_remove(sdata);
76 77
77 return 0; 78 return 0;
78} 79}
@@ -81,9 +82,7 @@ static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
81 enum nl80211_iftype type, u32 *flags, 82 enum nl80211_iftype type, u32 *flags,
82 struct vif_params *params) 83 struct vif_params *params)
83{ 84{
84 struct ieee80211_local *local = wiphy_priv(wiphy);
85 struct net_device *dev; 85 struct net_device *dev;
86 enum ieee80211_if_types itype;
87 struct ieee80211_sub_if_data *sdata; 86 struct ieee80211_sub_if_data *sdata;
88 int ret; 87 int ret;
89 88
@@ -92,25 +91,24 @@ static int ieee80211_change_iface(struct wiphy *wiphy, int ifindex,
92 if (!dev) 91 if (!dev)
93 return -ENODEV; 92 return -ENODEV;
94 93
95 itype = nl80211_type_to_mac80211_type(type); 94 if (!nl80211_type_check(type))
96 if (itype == IEEE80211_IF_TYPE_INVALID)
97 return -EINVAL; 95 return -EINVAL;
98 96
99 if (dev == local->mdev)
100 return -EOPNOTSUPP;
101
102 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 97 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
103 98
104 ret = ieee80211_if_change_type(sdata, itype); 99 ret = ieee80211_if_change_type(sdata, type);
105 if (ret) 100 if (ret)
106 return ret; 101 return ret;
107 102
103 if (netif_running(sdata->dev))
104 return -EBUSY;
105
108 if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len) 106 if (ieee80211_vif_is_mesh(&sdata->vif) && params->mesh_id_len)
109 ieee80211_if_sta_set_mesh_id(&sdata->u.sta, 107 ieee80211_sdata_set_mesh_id(sdata,
110 params->mesh_id_len, 108 params->mesh_id_len,
111 params->mesh_id); 109 params->mesh_id);
112 110
113 if (sdata->vif.type != IEEE80211_IF_TYPE_MNTR || !flags) 111 if (sdata->vif.type != NL80211_IFTYPE_MONITOR || !flags)
114 return 0; 112 return 0;
115 113
116 sdata->u.mntr_flags = *flags; 114 sdata->u.mntr_flags = *flags;
@@ -121,16 +119,12 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
121 u8 key_idx, u8 *mac_addr, 119 u8 key_idx, u8 *mac_addr,
122 struct key_params *params) 120 struct key_params *params)
123{ 121{
124 struct ieee80211_local *local = wiphy_priv(wiphy);
125 struct ieee80211_sub_if_data *sdata; 122 struct ieee80211_sub_if_data *sdata;
126 struct sta_info *sta = NULL; 123 struct sta_info *sta = NULL;
127 enum ieee80211_key_alg alg; 124 enum ieee80211_key_alg alg;
128 struct ieee80211_key *key; 125 struct ieee80211_key *key;
129 int err; 126 int err;
130 127
131 if (dev == local->mdev)
132 return -EOPNOTSUPP;
133
134 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 128 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
135 129
136 switch (params->cipher) { 130 switch (params->cipher) {
@@ -175,14 +169,10 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
175static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, 169static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
176 u8 key_idx, u8 *mac_addr) 170 u8 key_idx, u8 *mac_addr)
177{ 171{
178 struct ieee80211_local *local = wiphy_priv(wiphy);
179 struct ieee80211_sub_if_data *sdata; 172 struct ieee80211_sub_if_data *sdata;
180 struct sta_info *sta; 173 struct sta_info *sta;
181 int ret; 174 int ret;
182 175
183 if (dev == local->mdev)
184 return -EOPNOTSUPP;
185
186 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 176 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
187 177
188 rcu_read_lock(); 178 rcu_read_lock();
@@ -223,7 +213,6 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
223 void (*callback)(void *cookie, 213 void (*callback)(void *cookie,
224 struct key_params *params)) 214 struct key_params *params))
225{ 215{
226 struct ieee80211_local *local = wiphy_priv(wiphy);
227 struct ieee80211_sub_if_data *sdata; 216 struct ieee80211_sub_if_data *sdata;
228 struct sta_info *sta = NULL; 217 struct sta_info *sta = NULL;
229 u8 seq[6] = {0}; 218 u8 seq[6] = {0};
@@ -233,9 +222,6 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
233 u16 iv16; 222 u16 iv16;
234 int err = -ENOENT; 223 int err = -ENOENT;
235 224
236 if (dev == local->mdev)
237 return -EOPNOTSUPP;
238
239 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 225 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
240 226
241 rcu_read_lock(); 227 rcu_read_lock();
@@ -311,12 +297,8 @@ static int ieee80211_config_default_key(struct wiphy *wiphy,
311 struct net_device *dev, 297 struct net_device *dev,
312 u8 key_idx) 298 u8 key_idx)
313{ 299{
314 struct ieee80211_local *local = wiphy_priv(wiphy);
315 struct ieee80211_sub_if_data *sdata; 300 struct ieee80211_sub_if_data *sdata;
316 301
317 if (dev == local->mdev)
318 return -EOPNOTSUPP;
319
320 rcu_read_lock(); 302 rcu_read_lock();
321 303
322 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 304 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -365,7 +347,7 @@ static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
365 sta = sta_info_get_by_idx(local, idx, dev); 347 sta = sta_info_get_by_idx(local, idx, dev);
366 if (sta) { 348 if (sta) {
367 ret = 0; 349 ret = 0;
368 memcpy(mac, sta->addr, ETH_ALEN); 350 memcpy(mac, sta->sta.addr, ETH_ALEN);
369 sta_set_sinfo(sta, sinfo); 351 sta_set_sinfo(sta, sinfo);
370 } 352 }
371 353
@@ -497,16 +479,12 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
497static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev, 479static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
498 struct beacon_parameters *params) 480 struct beacon_parameters *params)
499{ 481{
500 struct ieee80211_local *local = wiphy_priv(wiphy);
501 struct ieee80211_sub_if_data *sdata; 482 struct ieee80211_sub_if_data *sdata;
502 struct beacon_data *old; 483 struct beacon_data *old;
503 484
504 if (dev == local->mdev)
505 return -EOPNOTSUPP;
506
507 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 485 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
508 486
509 if (sdata->vif.type != IEEE80211_IF_TYPE_AP) 487 if (sdata->vif.type != NL80211_IFTYPE_AP)
510 return -EINVAL; 488 return -EINVAL;
511 489
512 old = sdata->u.ap.beacon; 490 old = sdata->u.ap.beacon;
@@ -520,16 +498,12 @@ static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
520static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev, 498static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
521 struct beacon_parameters *params) 499 struct beacon_parameters *params)
522{ 500{
523 struct ieee80211_local *local = wiphy_priv(wiphy);
524 struct ieee80211_sub_if_data *sdata; 501 struct ieee80211_sub_if_data *sdata;
525 struct beacon_data *old; 502 struct beacon_data *old;
526 503
527 if (dev == local->mdev)
528 return -EOPNOTSUPP;
529
530 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 504 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
531 505
532 if (sdata->vif.type != IEEE80211_IF_TYPE_AP) 506 if (sdata->vif.type != NL80211_IFTYPE_AP)
533 return -EINVAL; 507 return -EINVAL;
534 508
535 old = sdata->u.ap.beacon; 509 old = sdata->u.ap.beacon;
@@ -542,16 +516,12 @@ static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
542 516
543static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev) 517static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
544{ 518{
545 struct ieee80211_local *local = wiphy_priv(wiphy);
546 struct ieee80211_sub_if_data *sdata; 519 struct ieee80211_sub_if_data *sdata;
547 struct beacon_data *old; 520 struct beacon_data *old;
548 521
549 if (dev == local->mdev)
550 return -EOPNOTSUPP;
551
552 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 522 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
553 523
554 if (sdata->vif.type != IEEE80211_IF_TYPE_AP) 524 if (sdata->vif.type != NL80211_IFTYPE_AP)
555 return -EINVAL; 525 return -EINVAL;
556 526
557 old = sdata->u.ap.beacon; 527 old = sdata->u.ap.beacon;
@@ -594,7 +564,7 @@ static void ieee80211_send_layer2_update(struct sta_info *sta)
594 * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */ 564 * Update response frame; IEEE Std 802.2-1998, 5.4.1.2.1 */
595 565
596 memset(msg->da, 0xff, ETH_ALEN); 566 memset(msg->da, 0xff, ETH_ALEN);
597 memcpy(msg->sa, sta->addr, ETH_ALEN); 567 memcpy(msg->sa, sta->sta.addr, ETH_ALEN);
598 msg->len = htons(6); 568 msg->len = htons(6);
599 msg->dsap = 0; 569 msg->dsap = 0;
600 msg->ssap = 0x01; /* NULL LSAP, CR Bit: Response */ 570 msg->ssap = 0x01; /* NULL LSAP, CR Bit: Response */
@@ -649,9 +619,9 @@ static void sta_apply_parameters(struct ieee80211_local *local,
649 */ 619 */
650 620
651 if (params->aid) { 621 if (params->aid) {
652 sta->aid = params->aid; 622 sta->sta.aid = params->aid;
653 if (sta->aid > IEEE80211_MAX_AID) 623 if (sta->sta.aid > IEEE80211_MAX_AID)
654 sta->aid = 0; /* XXX: should this be an error? */ 624 sta->sta.aid = 0; /* XXX: should this be an error? */
655 } 625 }
656 626
657 if (params->listen_interval >= 0) 627 if (params->listen_interval >= 0)
@@ -668,7 +638,12 @@ static void sta_apply_parameters(struct ieee80211_local *local,
668 rates |= BIT(j); 638 rates |= BIT(j);
669 } 639 }
670 } 640 }
671 sta->supp_rates[local->oper_channel->band] = rates; 641 sta->sta.supp_rates[local->oper_channel->band] = rates;
642 }
643
644 if (params->ht_capa) {
645 ieee80211_ht_cap_ie_to_ht_info(params->ht_capa,
646 &sta->sta.ht_info);
672 } 647 }
673 648
674 if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) { 649 if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) {
@@ -691,9 +666,6 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
691 struct ieee80211_sub_if_data *sdata; 666 struct ieee80211_sub_if_data *sdata;
692 int err; 667 int err;
693 668
694 if (dev == local->mdev || params->vlan == local->mdev)
695 return -EOPNOTSUPP;
696
697 /* Prevent a race with changing the rate control algorithm */ 669 /* Prevent a race with changing the rate control algorithm */
698 if (!netif_running(dev)) 670 if (!netif_running(dev))
699 return -ENETDOWN; 671 return -ENETDOWN;
@@ -701,8 +673,8 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
701 if (params->vlan) { 673 if (params->vlan) {
702 sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); 674 sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
703 675
704 if (sdata->vif.type != IEEE80211_IF_TYPE_VLAN && 676 if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
705 sdata->vif.type != IEEE80211_IF_TYPE_AP) 677 sdata->vif.type != NL80211_IFTYPE_AP)
706 return -EINVAL; 678 return -EINVAL;
707 } else 679 } else
708 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 680 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -721,7 +693,7 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
721 693
722 sta_apply_parameters(local, sta, params); 694 sta_apply_parameters(local, sta, params);
723 695
724 rate_control_rate_init(sta, local); 696 rate_control_rate_init(sta);
725 697
726 rcu_read_lock(); 698 rcu_read_lock();
727 699
@@ -732,8 +704,8 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
732 return err; 704 return err;
733 } 705 }
734 706
735 if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN || 707 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
736 sdata->vif.type == IEEE80211_IF_TYPE_AP) 708 sdata->vif.type == NL80211_IFTYPE_AP)
737 ieee80211_send_layer2_update(sta); 709 ieee80211_send_layer2_update(sta);
738 710
739 rcu_read_unlock(); 711 rcu_read_unlock();
@@ -748,9 +720,6 @@ static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
748 struct ieee80211_sub_if_data *sdata; 720 struct ieee80211_sub_if_data *sdata;
749 struct sta_info *sta; 721 struct sta_info *sta;
750 722
751 if (dev == local->mdev)
752 return -EOPNOTSUPP;
753
754 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 723 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
755 724
756 if (mac) { 725 if (mac) {
@@ -782,9 +751,6 @@ static int ieee80211_change_station(struct wiphy *wiphy,
782 struct sta_info *sta; 751 struct sta_info *sta;
783 struct ieee80211_sub_if_data *vlansdata; 752 struct ieee80211_sub_if_data *vlansdata;
784 753
785 if (dev == local->mdev || params->vlan == local->mdev)
786 return -EOPNOTSUPP;
787
788 rcu_read_lock(); 754 rcu_read_lock();
789 755
790 /* XXX: get sta belonging to dev */ 756 /* XXX: get sta belonging to dev */
@@ -797,8 +763,8 @@ static int ieee80211_change_station(struct wiphy *wiphy,
797 if (params->vlan && params->vlan != sta->sdata->dev) { 763 if (params->vlan && params->vlan != sta->sdata->dev) {
798 vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); 764 vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
799 765
800 if (vlansdata->vif.type != IEEE80211_IF_TYPE_VLAN && 766 if (vlansdata->vif.type != NL80211_IFTYPE_AP_VLAN &&
801 vlansdata->vif.type != IEEE80211_IF_TYPE_AP) { 767 vlansdata->vif.type != NL80211_IFTYPE_AP) {
802 rcu_read_unlock(); 768 rcu_read_unlock();
803 return -EINVAL; 769 return -EINVAL;
804 } 770 }
@@ -824,15 +790,12 @@ static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
824 struct sta_info *sta; 790 struct sta_info *sta;
825 int err; 791 int err;
826 792
827 if (dev == local->mdev)
828 return -EOPNOTSUPP;
829
830 if (!netif_running(dev)) 793 if (!netif_running(dev))
831 return -ENETDOWN; 794 return -ENETDOWN;
832 795
833 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 796 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
834 797
835 if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT) 798 if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
836 return -ENOTSUPP; 799 return -ENOTSUPP;
837 800
838 rcu_read_lock(); 801 rcu_read_lock();
@@ -842,13 +805,13 @@ static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
842 return -ENOENT; 805 return -ENOENT;
843 } 806 }
844 807
845 err = mesh_path_add(dst, dev); 808 err = mesh_path_add(dst, sdata);
846 if (err) { 809 if (err) {
847 rcu_read_unlock(); 810 rcu_read_unlock();
848 return err; 811 return err;
849 } 812 }
850 813
851 mpath = mesh_path_lookup(dst, dev); 814 mpath = mesh_path_lookup(dst, sdata);
852 if (!mpath) { 815 if (!mpath) {
853 rcu_read_unlock(); 816 rcu_read_unlock();
854 return -ENXIO; 817 return -ENXIO;
@@ -862,10 +825,12 @@ static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
862static int ieee80211_del_mpath(struct wiphy *wiphy, struct net_device *dev, 825static int ieee80211_del_mpath(struct wiphy *wiphy, struct net_device *dev,
863 u8 *dst) 826 u8 *dst)
864{ 827{
828 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
829
865 if (dst) 830 if (dst)
866 return mesh_path_del(dst, dev); 831 return mesh_path_del(dst, sdata);
867 832
868 mesh_path_flush(dev); 833 mesh_path_flush(sdata);
869 return 0; 834 return 0;
870} 835}
871 836
@@ -878,15 +843,12 @@ static int ieee80211_change_mpath(struct wiphy *wiphy,
878 struct mesh_path *mpath; 843 struct mesh_path *mpath;
879 struct sta_info *sta; 844 struct sta_info *sta;
880 845
881 if (dev == local->mdev)
882 return -EOPNOTSUPP;
883
884 if (!netif_running(dev)) 846 if (!netif_running(dev))
885 return -ENETDOWN; 847 return -ENETDOWN;
886 848
887 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 849 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
888 850
889 if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT) 851 if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
890 return -ENOTSUPP; 852 return -ENOTSUPP;
891 853
892 rcu_read_lock(); 854 rcu_read_lock();
@@ -897,7 +859,7 @@ static int ieee80211_change_mpath(struct wiphy *wiphy,
897 return -ENOENT; 859 return -ENOENT;
898 } 860 }
899 861
900 mpath = mesh_path_lookup(dst, dev); 862 mpath = mesh_path_lookup(dst, sdata);
901 if (!mpath) { 863 if (!mpath) {
902 rcu_read_unlock(); 864 rcu_read_unlock();
903 return -ENOENT; 865 return -ENOENT;
@@ -913,7 +875,7 @@ static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
913 struct mpath_info *pinfo) 875 struct mpath_info *pinfo)
914{ 876{
915 if (mpath->next_hop) 877 if (mpath->next_hop)
916 memcpy(next_hop, mpath->next_hop->addr, ETH_ALEN); 878 memcpy(next_hop, mpath->next_hop->sta.addr, ETH_ALEN);
917 else 879 else
918 memset(next_hop, 0, ETH_ALEN); 880 memset(next_hop, 0, ETH_ALEN);
919 881
@@ -952,20 +914,16 @@ static int ieee80211_get_mpath(struct wiphy *wiphy, struct net_device *dev,
952 u8 *dst, u8 *next_hop, struct mpath_info *pinfo) 914 u8 *dst, u8 *next_hop, struct mpath_info *pinfo)
953 915
954{ 916{
955 struct ieee80211_local *local = wiphy_priv(wiphy);
956 struct ieee80211_sub_if_data *sdata; 917 struct ieee80211_sub_if_data *sdata;
957 struct mesh_path *mpath; 918 struct mesh_path *mpath;
958 919
959 if (dev == local->mdev)
960 return -EOPNOTSUPP;
961
962 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 920 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
963 921
964 if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT) 922 if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
965 return -ENOTSUPP; 923 return -ENOTSUPP;
966 924
967 rcu_read_lock(); 925 rcu_read_lock();
968 mpath = mesh_path_lookup(dst, dev); 926 mpath = mesh_path_lookup(dst, sdata);
969 if (!mpath) { 927 if (!mpath) {
970 rcu_read_unlock(); 928 rcu_read_unlock();
971 return -ENOENT; 929 return -ENOENT;
@@ -980,20 +938,16 @@ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
980 int idx, u8 *dst, u8 *next_hop, 938 int idx, u8 *dst, u8 *next_hop,
981 struct mpath_info *pinfo) 939 struct mpath_info *pinfo)
982{ 940{
983 struct ieee80211_local *local = wiphy_priv(wiphy);
984 struct ieee80211_sub_if_data *sdata; 941 struct ieee80211_sub_if_data *sdata;
985 struct mesh_path *mpath; 942 struct mesh_path *mpath;
986 943
987 if (dev == local->mdev)
988 return -EOPNOTSUPP;
989
990 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 944 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
991 945
992 if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT) 946 if (sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
993 return -ENOTSUPP; 947 return -ENOTSUPP;
994 948
995 rcu_read_lock(); 949 rcu_read_lock();
996 mpath = mesh_path_lookup_by_idx(idx, dev); 950 mpath = mesh_path_lookup_by_idx(idx, sdata);
997 if (!mpath) { 951 if (!mpath) {
998 rcu_read_unlock(); 952 rcu_read_unlock();
999 return -ENOENT; 953 return -ENOENT;
@@ -1005,6 +959,38 @@ static int ieee80211_dump_mpath(struct wiphy *wiphy, struct net_device *dev,
1005} 959}
1006#endif 960#endif
1007 961
962static int ieee80211_change_bss(struct wiphy *wiphy,
963 struct net_device *dev,
964 struct bss_parameters *params)
965{
966 struct ieee80211_sub_if_data *sdata;
967 u32 changed = 0;
968
969 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
970
971 if (sdata->vif.type != NL80211_IFTYPE_AP)
972 return -EINVAL;
973
974 if (params->use_cts_prot >= 0) {
975 sdata->bss_conf.use_cts_prot = params->use_cts_prot;
976 changed |= BSS_CHANGED_ERP_CTS_PROT;
977 }
978 if (params->use_short_preamble >= 0) {
979 sdata->bss_conf.use_short_preamble =
980 params->use_short_preamble;
981 changed |= BSS_CHANGED_ERP_PREAMBLE;
982 }
983 if (params->use_short_slot_time >= 0) {
984 sdata->bss_conf.use_short_slot =
985 params->use_short_slot_time;
986 changed |= BSS_CHANGED_ERP_SLOT;
987 }
988
989 ieee80211_bss_info_change_notify(sdata, changed);
990
991 return 0;
992}
993
1008struct cfg80211_ops mac80211_config_ops = { 994struct cfg80211_ops mac80211_config_ops = {
1009 .add_virtual_intf = ieee80211_add_iface, 995 .add_virtual_intf = ieee80211_add_iface,
1010 .del_virtual_intf = ieee80211_del_iface, 996 .del_virtual_intf = ieee80211_del_iface,
@@ -1028,4 +1014,5 @@ struct cfg80211_ops mac80211_config_ops = {
1028 .get_mpath = ieee80211_get_mpath, 1014 .get_mpath = ieee80211_get_mpath,
1029 .dump_mpath = ieee80211_dump_mpath, 1015 .dump_mpath = ieee80211_dump_mpath,
1030#endif 1016#endif
1017 .change_bss = ieee80211_change_bss,
1031}; 1018};
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index ee509f1109e2..24ce54463310 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -51,8 +51,6 @@ DEBUGFS_READONLY_FILE(antenna_sel_tx, 20, "%d",
51 local->hw.conf.antenna_sel_tx); 51 local->hw.conf.antenna_sel_tx);
52DEBUGFS_READONLY_FILE(antenna_sel_rx, 20, "%d", 52DEBUGFS_READONLY_FILE(antenna_sel_rx, 20, "%d",
53 local->hw.conf.antenna_sel_rx); 53 local->hw.conf.antenna_sel_rx);
54DEBUGFS_READONLY_FILE(bridge_packets, 20, "%d",
55 local->bridge_packets);
56DEBUGFS_READONLY_FILE(rts_threshold, 20, "%d", 54DEBUGFS_READONLY_FILE(rts_threshold, 20, "%d",
57 local->rts_threshold); 55 local->rts_threshold);
58DEBUGFS_READONLY_FILE(fragmentation_threshold, 20, "%d", 56DEBUGFS_READONLY_FILE(fragmentation_threshold, 20, "%d",
@@ -206,7 +204,6 @@ void debugfs_hw_add(struct ieee80211_local *local)
206 DEBUGFS_ADD(frequency); 204 DEBUGFS_ADD(frequency);
207 DEBUGFS_ADD(antenna_sel_tx); 205 DEBUGFS_ADD(antenna_sel_tx);
208 DEBUGFS_ADD(antenna_sel_rx); 206 DEBUGFS_ADD(antenna_sel_rx);
209 DEBUGFS_ADD(bridge_packets);
210 DEBUGFS_ADD(rts_threshold); 207 DEBUGFS_ADD(rts_threshold);
211 DEBUGFS_ADD(fragmentation_threshold); 208 DEBUGFS_ADD(fragmentation_threshold);
212 DEBUGFS_ADD(short_retry_limit); 209 DEBUGFS_ADD(short_retry_limit);
@@ -263,7 +260,6 @@ void debugfs_hw_del(struct ieee80211_local *local)
263 DEBUGFS_DEL(frequency); 260 DEBUGFS_DEL(frequency);
264 DEBUGFS_DEL(antenna_sel_tx); 261 DEBUGFS_DEL(antenna_sel_tx);
265 DEBUGFS_DEL(antenna_sel_rx); 262 DEBUGFS_DEL(antenna_sel_rx);
266 DEBUGFS_DEL(bridge_packets);
267 DEBUGFS_DEL(rts_threshold); 263 DEBUGFS_DEL(rts_threshold);
268 DEBUGFS_DEL(fragmentation_threshold); 264 DEBUGFS_DEL(fragmentation_threshold);
269 DEBUGFS_DEL(short_retry_limit); 265 DEBUGFS_DEL(short_retry_limit);
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c
index 7439b63df5d0..a3294d109322 100644
--- a/net/mac80211/debugfs_key.c
+++ b/net/mac80211/debugfs_key.c
@@ -206,7 +206,8 @@ void ieee80211_debugfs_key_add(struct ieee80211_key *key)
206 rcu_read_lock(); 206 rcu_read_lock();
207 sta = rcu_dereference(key->sta); 207 sta = rcu_dereference(key->sta);
208 if (sta) 208 if (sta)
209 sprintf(buf, "../../stations/%s", print_mac(mac, sta->addr)); 209 sprintf(buf, "../../stations/%s",
210 print_mac(mac, sta->sta.addr));
210 rcu_read_unlock(); 211 rcu_read_unlock();
211 212
212 /* using sta as a boolean is fine outside RCU lock */ 213 /* using sta as a boolean is fine outside RCU lock */
@@ -265,7 +266,7 @@ void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata)
265 key = sdata->default_key; 266 key = sdata->default_key;
266 if (key) { 267 if (key) {
267 sprintf(buf, "../keys/%d", key->debugfs.cnt); 268 sprintf(buf, "../keys/%d", key->debugfs.cnt);
268 sdata->debugfs.default_key = 269 sdata->common_debugfs.default_key =
269 debugfs_create_symlink("default_key", 270 debugfs_create_symlink("default_key",
270 sdata->debugfsdir, buf); 271 sdata->debugfsdir, buf);
271 } else 272 } else
@@ -277,8 +278,8 @@ void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata)
277 if (!sdata) 278 if (!sdata)
278 return; 279 return;
279 280
280 debugfs_remove(sdata->debugfs.default_key); 281 debugfs_remove(sdata->common_debugfs.default_key);
281 sdata->debugfs.default_key = NULL; 282 sdata->common_debugfs.default_key = NULL;
282} 283}
283 284
284void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key, 285void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key,
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 8165df578c92..2a4515623776 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -173,7 +173,6 @@ IEEE80211_IF_FILE(assoc_tries, u.sta.assoc_tries, DEC);
173IEEE80211_IF_FILE(auth_algs, u.sta.auth_algs, HEX); 173IEEE80211_IF_FILE(auth_algs, u.sta.auth_algs, HEX);
174IEEE80211_IF_FILE(auth_alg, u.sta.auth_alg, DEC); 174IEEE80211_IF_FILE(auth_alg, u.sta.auth_alg, DEC);
175IEEE80211_IF_FILE(auth_transaction, u.sta.auth_transaction, DEC); 175IEEE80211_IF_FILE(auth_transaction, u.sta.auth_transaction, DEC);
176IEEE80211_IF_FILE(num_beacons_sta, u.sta.num_beacons, DEC);
177 176
178static ssize_t ieee80211_if_fmt_flags( 177static ssize_t ieee80211_if_fmt_flags(
179 const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) 178 const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
@@ -192,7 +191,6 @@ __IEEE80211_IF_FILE(flags);
192/* AP attributes */ 191/* AP attributes */
193IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC); 192IEEE80211_IF_FILE(num_sta_ps, u.ap.num_sta_ps, ATOMIC);
194IEEE80211_IF_FILE(dtim_count, u.ap.dtim_count, DEC); 193IEEE80211_IF_FILE(dtim_count, u.ap.dtim_count, DEC);
195IEEE80211_IF_FILE(num_beacons, u.ap.num_beacons, DEC);
196 194
197static ssize_t ieee80211_if_fmt_num_buffered_multicast( 195static ssize_t ieee80211_if_fmt_num_buffered_multicast(
198 const struct ieee80211_sub_if_data *sdata, char *buf, int buflen) 196 const struct ieee80211_sub_if_data *sdata, char *buf, int buflen)
@@ -207,37 +205,37 @@ IEEE80211_IF_FILE(peer, u.wds.remote_addr, MAC);
207 205
208#ifdef CONFIG_MAC80211_MESH 206#ifdef CONFIG_MAC80211_MESH
209/* Mesh stats attributes */ 207/* Mesh stats attributes */
210IEEE80211_IF_FILE(fwded_frames, u.sta.mshstats.fwded_frames, DEC); 208IEEE80211_IF_FILE(fwded_frames, u.mesh.mshstats.fwded_frames, DEC);
211IEEE80211_IF_FILE(dropped_frames_ttl, u.sta.mshstats.dropped_frames_ttl, DEC); 209IEEE80211_IF_FILE(dropped_frames_ttl, u.mesh.mshstats.dropped_frames_ttl, DEC);
212IEEE80211_IF_FILE(dropped_frames_no_route, 210IEEE80211_IF_FILE(dropped_frames_no_route,
213 u.sta.mshstats.dropped_frames_no_route, DEC); 211 u.mesh.mshstats.dropped_frames_no_route, DEC);
214IEEE80211_IF_FILE(estab_plinks, u.sta.mshstats.estab_plinks, ATOMIC); 212IEEE80211_IF_FILE(estab_plinks, u.mesh.mshstats.estab_plinks, ATOMIC);
215 213
216/* Mesh parameters */ 214/* Mesh parameters */
217IEEE80211_IF_WFILE(dot11MeshMaxRetries, 215IEEE80211_IF_WFILE(dot11MeshMaxRetries,
218 u.sta.mshcfg.dot11MeshMaxRetries, DEC, u8); 216 u.mesh.mshcfg.dot11MeshMaxRetries, DEC, u8);
219IEEE80211_IF_WFILE(dot11MeshRetryTimeout, 217IEEE80211_IF_WFILE(dot11MeshRetryTimeout,
220 u.sta.mshcfg.dot11MeshRetryTimeout, DEC, u16); 218 u.mesh.mshcfg.dot11MeshRetryTimeout, DEC, u16);
221IEEE80211_IF_WFILE(dot11MeshConfirmTimeout, 219IEEE80211_IF_WFILE(dot11MeshConfirmTimeout,
222 u.sta.mshcfg.dot11MeshConfirmTimeout, DEC, u16); 220 u.mesh.mshcfg.dot11MeshConfirmTimeout, DEC, u16);
223IEEE80211_IF_WFILE(dot11MeshHoldingTimeout, 221IEEE80211_IF_WFILE(dot11MeshHoldingTimeout,
224 u.sta.mshcfg.dot11MeshHoldingTimeout, DEC, u16); 222 u.mesh.mshcfg.dot11MeshHoldingTimeout, DEC, u16);
225IEEE80211_IF_WFILE(dot11MeshTTL, u.sta.mshcfg.dot11MeshTTL, DEC, u8); 223IEEE80211_IF_WFILE(dot11MeshTTL, u.mesh.mshcfg.dot11MeshTTL, DEC, u8);
226IEEE80211_IF_WFILE(auto_open_plinks, u.sta.mshcfg.auto_open_plinks, DEC, u8); 224IEEE80211_IF_WFILE(auto_open_plinks, u.mesh.mshcfg.auto_open_plinks, DEC, u8);
227IEEE80211_IF_WFILE(dot11MeshMaxPeerLinks, 225IEEE80211_IF_WFILE(dot11MeshMaxPeerLinks,
228 u.sta.mshcfg.dot11MeshMaxPeerLinks, DEC, u16); 226 u.mesh.mshcfg.dot11MeshMaxPeerLinks, DEC, u16);
229IEEE80211_IF_WFILE(dot11MeshHWMPactivePathTimeout, 227IEEE80211_IF_WFILE(dot11MeshHWMPactivePathTimeout,
230 u.sta.mshcfg.dot11MeshHWMPactivePathTimeout, DEC, u32); 228 u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout, DEC, u32);
231IEEE80211_IF_WFILE(dot11MeshHWMPpreqMinInterval, 229IEEE80211_IF_WFILE(dot11MeshHWMPpreqMinInterval,
232 u.sta.mshcfg.dot11MeshHWMPpreqMinInterval, DEC, u16); 230 u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval, DEC, u16);
233IEEE80211_IF_WFILE(dot11MeshHWMPnetDiameterTraversalTime, 231IEEE80211_IF_WFILE(dot11MeshHWMPnetDiameterTraversalTime,
234 u.sta.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC, u16); 232 u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC, u16);
235IEEE80211_IF_WFILE(dot11MeshHWMPmaxPREQretries, 233IEEE80211_IF_WFILE(dot11MeshHWMPmaxPREQretries,
236 u.sta.mshcfg.dot11MeshHWMPmaxPREQretries, DEC, u8); 234 u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries, DEC, u8);
237IEEE80211_IF_WFILE(path_refresh_time, 235IEEE80211_IF_WFILE(path_refresh_time,
238 u.sta.mshcfg.path_refresh_time, DEC, u32); 236 u.mesh.mshcfg.path_refresh_time, DEC, u32);
239IEEE80211_IF_WFILE(min_discovery_timeout, 237IEEE80211_IF_WFILE(min_discovery_timeout,
240 u.sta.mshcfg.min_discovery_timeout, DEC, u16); 238 u.mesh.mshcfg.min_discovery_timeout, DEC, u16);
241#endif 239#endif
242 240
243 241
@@ -265,7 +263,6 @@ static void add_sta_files(struct ieee80211_sub_if_data *sdata)
265 DEBUGFS_ADD(auth_alg, sta); 263 DEBUGFS_ADD(auth_alg, sta);
266 DEBUGFS_ADD(auth_transaction, sta); 264 DEBUGFS_ADD(auth_transaction, sta);
267 DEBUGFS_ADD(flags, sta); 265 DEBUGFS_ADD(flags, sta);
268 DEBUGFS_ADD(num_beacons_sta, sta);
269} 266}
270 267
271static void add_ap_files(struct ieee80211_sub_if_data *sdata) 268static void add_ap_files(struct ieee80211_sub_if_data *sdata)
@@ -276,7 +273,6 @@ static void add_ap_files(struct ieee80211_sub_if_data *sdata)
276 273
277 DEBUGFS_ADD(num_sta_ps, ap); 274 DEBUGFS_ADD(num_sta_ps, ap);
278 DEBUGFS_ADD(dtim_count, ap); 275 DEBUGFS_ADD(dtim_count, ap);
279 DEBUGFS_ADD(num_beacons, ap);
280 DEBUGFS_ADD(num_buffered_multicast, ap); 276 DEBUGFS_ADD(num_buffered_multicast, ap);
281} 277}
282 278
@@ -345,26 +341,26 @@ static void add_files(struct ieee80211_sub_if_data *sdata)
345 return; 341 return;
346 342
347 switch (sdata->vif.type) { 343 switch (sdata->vif.type) {
348 case IEEE80211_IF_TYPE_MESH_POINT: 344 case NL80211_IFTYPE_MESH_POINT:
349#ifdef CONFIG_MAC80211_MESH 345#ifdef CONFIG_MAC80211_MESH
350 add_mesh_stats(sdata); 346 add_mesh_stats(sdata);
351 add_mesh_config(sdata); 347 add_mesh_config(sdata);
352#endif 348#endif
353 /* fall through */ 349 break;
354 case IEEE80211_IF_TYPE_STA: 350 case NL80211_IFTYPE_STATION:
355 case IEEE80211_IF_TYPE_IBSS: 351 case NL80211_IFTYPE_ADHOC:
356 add_sta_files(sdata); 352 add_sta_files(sdata);
357 break; 353 break;
358 case IEEE80211_IF_TYPE_AP: 354 case NL80211_IFTYPE_AP:
359 add_ap_files(sdata); 355 add_ap_files(sdata);
360 break; 356 break;
361 case IEEE80211_IF_TYPE_WDS: 357 case NL80211_IFTYPE_WDS:
362 add_wds_files(sdata); 358 add_wds_files(sdata);
363 break; 359 break;
364 case IEEE80211_IF_TYPE_MNTR: 360 case NL80211_IFTYPE_MONITOR:
365 add_monitor_files(sdata); 361 add_monitor_files(sdata);
366 break; 362 break;
367 case IEEE80211_IF_TYPE_VLAN: 363 case NL80211_IFTYPE_AP_VLAN:
368 add_vlan_files(sdata); 364 add_vlan_files(sdata);
369 break; 365 break;
370 default: 366 default:
@@ -398,7 +394,6 @@ static void del_sta_files(struct ieee80211_sub_if_data *sdata)
398 DEBUGFS_DEL(auth_alg, sta); 394 DEBUGFS_DEL(auth_alg, sta);
399 DEBUGFS_DEL(auth_transaction, sta); 395 DEBUGFS_DEL(auth_transaction, sta);
400 DEBUGFS_DEL(flags, sta); 396 DEBUGFS_DEL(flags, sta);
401 DEBUGFS_DEL(num_beacons_sta, sta);
402} 397}
403 398
404static void del_ap_files(struct ieee80211_sub_if_data *sdata) 399static void del_ap_files(struct ieee80211_sub_if_data *sdata)
@@ -409,7 +404,6 @@ static void del_ap_files(struct ieee80211_sub_if_data *sdata)
409 404
410 DEBUGFS_DEL(num_sta_ps, ap); 405 DEBUGFS_DEL(num_sta_ps, ap);
411 DEBUGFS_DEL(dtim_count, ap); 406 DEBUGFS_DEL(dtim_count, ap);
412 DEBUGFS_DEL(num_beacons, ap);
413 DEBUGFS_DEL(num_buffered_multicast, ap); 407 DEBUGFS_DEL(num_buffered_multicast, ap);
414} 408}
415 409
@@ -482,26 +476,26 @@ static void del_files(struct ieee80211_sub_if_data *sdata)
482 return; 476 return;
483 477
484 switch (sdata->vif.type) { 478 switch (sdata->vif.type) {
485 case IEEE80211_IF_TYPE_MESH_POINT: 479 case NL80211_IFTYPE_MESH_POINT:
486#ifdef CONFIG_MAC80211_MESH 480#ifdef CONFIG_MAC80211_MESH
487 del_mesh_stats(sdata); 481 del_mesh_stats(sdata);
488 del_mesh_config(sdata); 482 del_mesh_config(sdata);
489#endif 483#endif
490 /* fall through */ 484 break;
491 case IEEE80211_IF_TYPE_STA: 485 case NL80211_IFTYPE_STATION:
492 case IEEE80211_IF_TYPE_IBSS: 486 case NL80211_IFTYPE_ADHOC:
493 del_sta_files(sdata); 487 del_sta_files(sdata);
494 break; 488 break;
495 case IEEE80211_IF_TYPE_AP: 489 case NL80211_IFTYPE_AP:
496 del_ap_files(sdata); 490 del_ap_files(sdata);
497 break; 491 break;
498 case IEEE80211_IF_TYPE_WDS: 492 case NL80211_IFTYPE_WDS:
499 del_wds_files(sdata); 493 del_wds_files(sdata);
500 break; 494 break;
501 case IEEE80211_IF_TYPE_MNTR: 495 case NL80211_IFTYPE_MONITOR:
502 del_monitor_files(sdata); 496 del_monitor_files(sdata);
503 break; 497 break;
504 case IEEE80211_IF_TYPE_VLAN: 498 case NL80211_IFTYPE_AP_VLAN:
505 del_vlan_files(sdata); 499 del_vlan_files(sdata);
506 break; 500 break;
507 default: 501 default:
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 79a062782d52..b9902e425f09 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -50,7 +50,7 @@ static const struct file_operations sta_ ##name## _ops = { \
50 STA_READ_##format(name, field) \ 50 STA_READ_##format(name, field) \
51 STA_OPS(name) 51 STA_OPS(name)
52 52
53STA_FILE(aid, aid, D); 53STA_FILE(aid, sta.aid, D);
54STA_FILE(dev, sdata->dev->name, S); 54STA_FILE(dev, sdata->dev->name, S);
55STA_FILE(rx_packets, rx_packets, LU); 55STA_FILE(rx_packets, rx_packets, LU);
56STA_FILE(tx_packets, tx_packets, LU); 56STA_FILE(tx_packets, tx_packets, LU);
@@ -173,10 +173,9 @@ static ssize_t sta_agg_status_write(struct file *file,
173 const char __user *user_buf, size_t count, loff_t *ppos) 173 const char __user *user_buf, size_t count, loff_t *ppos)
174{ 174{
175 struct sta_info *sta = file->private_data; 175 struct sta_info *sta = file->private_data;
176 struct net_device *dev = sta->sdata->dev; 176 struct ieee80211_local *local = sta->sdata->local;
177 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
178 struct ieee80211_hw *hw = &local->hw; 177 struct ieee80211_hw *hw = &local->hw;
179 u8 *da = sta->addr; 178 u8 *da = sta->sta.addr;
180 static int tid_static_tx[16] = {0, 0, 0, 0, 0, 0, 0, 0, 179 static int tid_static_tx[16] = {0, 0, 0, 0, 0, 0, 0, 0,
181 0, 0, 0, 0, 0, 0, 0, 0}; 180 0, 0, 0, 0, 0, 0, 0, 0};
182 static int tid_static_rx[16] = {1, 1, 1, 1, 1, 1, 1, 1, 181 static int tid_static_rx[16] = {1, 1, 1, 1, 1, 1, 1, 1,
@@ -201,7 +200,7 @@ static ssize_t sta_agg_status_write(struct file *file,
201 tid_num = tid_num - 100; 200 tid_num = tid_num - 100;
202 if (tid_static_rx[tid_num] == 1) { 201 if (tid_static_rx[tid_num] == 1) {
203 strcpy(state, "off "); 202 strcpy(state, "off ");
204 ieee80211_sta_stop_rx_ba_session(dev, da, tid_num, 0, 203 ieee80211_sta_stop_rx_ba_session(sta->sdata, da, tid_num, 0,
205 WLAN_REASON_QSTA_REQUIRE_SETUP); 204 WLAN_REASON_QSTA_REQUIRE_SETUP);
206 sta->ampdu_mlme.tid_state_rx[tid_num] |= 205 sta->ampdu_mlme.tid_state_rx[tid_num] |=
207 HT_AGG_STATE_DEBUGFS_CTL; 206 HT_AGG_STATE_DEBUGFS_CTL;
@@ -253,7 +252,7 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
253 if (!stations_dir) 252 if (!stations_dir)
254 return; 253 return;
255 254
256 mac = print_mac(mbuf, sta->addr); 255 mac = print_mac(mbuf, sta->sta.addr);
257 256
258 sta->debugfs.dir = debugfs_create_dir(mac, stations_dir); 257 sta->debugfs.dir = debugfs_create_dir(mac, stations_dir);
259 if (!sta->debugfs.dir) 258 if (!sta->debugfs.dir)
diff --git a/net/mac80211/event.c b/net/mac80211/event.c
index 2280f40b4560..8de60de70bc9 100644
--- a/net/mac80211/event.c
+++ b/net/mac80211/event.c
@@ -8,7 +8,6 @@
8 * mac80211 - events 8 * mac80211 - events
9 */ 9 */
10 10
11#include <linux/netdevice.h>
12#include <net/iw_handler.h> 11#include <net/iw_handler.h>
13#include "ieee80211_i.h" 12#include "ieee80211_i.h"
14 13
@@ -17,7 +16,7 @@
17 * (in the variable hdr) must be long enough to extract the TKIP 16 * (in the variable hdr) must be long enough to extract the TKIP
18 * fields like TSC 17 * fields like TSC
19 */ 18 */
20void mac80211_ev_michael_mic_failure(struct net_device *dev, int keyidx, 19void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx,
21 struct ieee80211_hdr *hdr) 20 struct ieee80211_hdr *hdr)
22{ 21{
23 union iwreq_data wrqu; 22 union iwreq_data wrqu;
@@ -32,7 +31,7 @@ void mac80211_ev_michael_mic_failure(struct net_device *dev, int keyidx,
32 print_mac(mac, hdr->addr2)); 31 print_mac(mac, hdr->addr2));
33 memset(&wrqu, 0, sizeof(wrqu)); 32 memset(&wrqu, 0, sizeof(wrqu));
34 wrqu.data.length = strlen(buf); 33 wrqu.data.length = strlen(buf);
35 wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf); 34 wireless_send_event(sdata->dev, IWEVCUSTOM, &wrqu, buf);
36 kfree(buf); 35 kfree(buf);
37 } 36 }
38 37
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c
new file mode 100644
index 000000000000..dc7d9a3d70d5
--- /dev/null
+++ b/net/mac80211/ht.c
@@ -0,0 +1,992 @@
1/*
2 * HT handling
3 *
4 * Copyright 2003, Jouni Malinen <jkmaline@cc.hut.fi>
5 * Copyright 2002-2005, Instant802 Networks, Inc.
6 * Copyright 2005-2006, Devicescape Software, Inc.
7 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
8 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
9 * Copyright 2007-2008, Intel Corporation
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/ieee80211.h>
17#include <net/wireless.h>
18#include <net/mac80211.h>
19#include "ieee80211_i.h"
20#include "sta_info.h"
21#include "wme.h"
22
23int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie,
24 struct ieee80211_ht_info *ht_info)
25{
26
27 if (ht_info == NULL)
28 return -EINVAL;
29
30 memset(ht_info, 0, sizeof(*ht_info));
31
32 if (ht_cap_ie) {
33 u8 ampdu_info = ht_cap_ie->ampdu_params_info;
34
35 ht_info->ht_supported = 1;
36 ht_info->cap = le16_to_cpu(ht_cap_ie->cap_info);
37 ht_info->ampdu_factor =
38 ampdu_info & IEEE80211_HT_CAP_AMPDU_FACTOR;
39 ht_info->ampdu_density =
40 (ampdu_info & IEEE80211_HT_CAP_AMPDU_DENSITY) >> 2;
41 memcpy(ht_info->supp_mcs_set, ht_cap_ie->supp_mcs_set, 16);
42 } else
43 ht_info->ht_supported = 0;
44
45 return 0;
46}
47
48int ieee80211_ht_addt_info_ie_to_ht_bss_info(
49 struct ieee80211_ht_addt_info *ht_add_info_ie,
50 struct ieee80211_ht_bss_info *bss_info)
51{
52 if (bss_info == NULL)
53 return -EINVAL;
54
55 memset(bss_info, 0, sizeof(*bss_info));
56
57 if (ht_add_info_ie) {
58 u16 op_mode;
59 op_mode = le16_to_cpu(ht_add_info_ie->operation_mode);
60
61 bss_info->primary_channel = ht_add_info_ie->control_chan;
62 bss_info->bss_cap = ht_add_info_ie->ht_param;
63 bss_info->bss_op_mode = (u8)(op_mode & 0xff);
64 }
65
66 return 0;
67}
68
69static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
70 const u8 *da, u16 tid,
71 u8 dialog_token, u16 start_seq_num,
72 u16 agg_size, u16 timeout)
73{
74 struct ieee80211_local *local = sdata->local;
75 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
76 struct sk_buff *skb;
77 struct ieee80211_mgmt *mgmt;
78 u16 capab;
79
80 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
81
82 if (!skb) {
83 printk(KERN_ERR "%s: failed to allocate buffer "
84 "for addba request frame\n", sdata->dev->name);
85 return;
86 }
87 skb_reserve(skb, local->hw.extra_tx_headroom);
88 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
89 memset(mgmt, 0, 24);
90 memcpy(mgmt->da, da, ETH_ALEN);
91 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
92 if (sdata->vif.type == NL80211_IFTYPE_AP)
93 memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
94 else
95 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
96
97 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
98 IEEE80211_STYPE_ACTION);
99
100 skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_req));
101
102 mgmt->u.action.category = WLAN_CATEGORY_BACK;
103 mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ;
104
105 mgmt->u.action.u.addba_req.dialog_token = dialog_token;
106 capab = (u16)(1 << 1); /* bit 1 aggregation policy */
107 capab |= (u16)(tid << 2); /* bit 5:2 TID number */
108 capab |= (u16)(agg_size << 6); /* bit 15:6 max size of aggergation */
109
110 mgmt->u.action.u.addba_req.capab = cpu_to_le16(capab);
111
112 mgmt->u.action.u.addba_req.timeout = cpu_to_le16(timeout);
113 mgmt->u.action.u.addba_req.start_seq_num =
114 cpu_to_le16(start_seq_num << 4);
115
116 ieee80211_tx_skb(sdata, skb, 0);
117}
118
119static void ieee80211_send_addba_resp(struct ieee80211_sub_if_data *sdata, u8 *da, u16 tid,
120 u8 dialog_token, u16 status, u16 policy,
121 u16 buf_size, u16 timeout)
122{
123 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
124 struct ieee80211_local *local = sdata->local;
125 struct sk_buff *skb;
126 struct ieee80211_mgmt *mgmt;
127 u16 capab;
128
129 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
130
131 if (!skb) {
132 printk(KERN_DEBUG "%s: failed to allocate buffer "
133 "for addba resp frame\n", sdata->dev->name);
134 return;
135 }
136
137 skb_reserve(skb, local->hw.extra_tx_headroom);
138 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
139 memset(mgmt, 0, 24);
140 memcpy(mgmt->da, da, ETH_ALEN);
141 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
142 if (sdata->vif.type == NL80211_IFTYPE_AP)
143 memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
144 else
145 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
146 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
147 IEEE80211_STYPE_ACTION);
148
149 skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_resp));
150 mgmt->u.action.category = WLAN_CATEGORY_BACK;
151 mgmt->u.action.u.addba_resp.action_code = WLAN_ACTION_ADDBA_RESP;
152 mgmt->u.action.u.addba_resp.dialog_token = dialog_token;
153
154 capab = (u16)(policy << 1); /* bit 1 aggregation policy */
155 capab |= (u16)(tid << 2); /* bit 5:2 TID number */
156 capab |= (u16)(buf_size << 6); /* bit 15:6 max size of aggregation */
157
158 mgmt->u.action.u.addba_resp.capab = cpu_to_le16(capab);
159 mgmt->u.action.u.addba_resp.timeout = cpu_to_le16(timeout);
160 mgmt->u.action.u.addba_resp.status = cpu_to_le16(status);
161
162 ieee80211_tx_skb(sdata, skb, 0);
163}
164
165static void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
166 const u8 *da, u16 tid,
167 u16 initiator, u16 reason_code)
168{
169 struct ieee80211_local *local = sdata->local;
170 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
171 struct sk_buff *skb;
172 struct ieee80211_mgmt *mgmt;
173 u16 params;
174
175 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
176
177 if (!skb) {
178 printk(KERN_ERR "%s: failed to allocate buffer "
179 "for delba frame\n", sdata->dev->name);
180 return;
181 }
182
183 skb_reserve(skb, local->hw.extra_tx_headroom);
184 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
185 memset(mgmt, 0, 24);
186 memcpy(mgmt->da, da, ETH_ALEN);
187 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
188 if (sdata->vif.type == NL80211_IFTYPE_AP)
189 memcpy(mgmt->bssid, sdata->dev->dev_addr, ETH_ALEN);
190 else
191 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
192 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
193 IEEE80211_STYPE_ACTION);
194
195 skb_put(skb, 1 + sizeof(mgmt->u.action.u.delba));
196
197 mgmt->u.action.category = WLAN_CATEGORY_BACK;
198 mgmt->u.action.u.delba.action_code = WLAN_ACTION_DELBA;
199 params = (u16)(initiator << 11); /* bit 11 initiator */
200 params |= (u16)(tid << 12); /* bit 15:12 TID number */
201
202 mgmt->u.action.u.delba.params = cpu_to_le16(params);
203 mgmt->u.action.u.delba.reason_code = cpu_to_le16(reason_code);
204
205 ieee80211_tx_skb(sdata, skb, 0);
206}
207
208void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn)
209{
210 struct ieee80211_local *local = sdata->local;
211 struct sk_buff *skb;
212 struct ieee80211_bar *bar;
213 u16 bar_control = 0;
214
215 skb = dev_alloc_skb(sizeof(*bar) + local->hw.extra_tx_headroom);
216 if (!skb) {
217 printk(KERN_ERR "%s: failed to allocate buffer for "
218 "bar frame\n", sdata->dev->name);
219 return;
220 }
221 skb_reserve(skb, local->hw.extra_tx_headroom);
222 bar = (struct ieee80211_bar *)skb_put(skb, sizeof(*bar));
223 memset(bar, 0, sizeof(*bar));
224 bar->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
225 IEEE80211_STYPE_BACK_REQ);
226 memcpy(bar->ra, ra, ETH_ALEN);
227 memcpy(bar->ta, sdata->dev->dev_addr, ETH_ALEN);
228 bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL;
229 bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA;
230 bar_control |= (u16)(tid << 12);
231 bar->control = cpu_to_le16(bar_control);
232 bar->start_seq_num = cpu_to_le16(ssn);
233
234 ieee80211_tx_skb(sdata, skb, 0);
235}
236
237void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid,
238 u16 initiator, u16 reason)
239{
240 struct ieee80211_local *local = sdata->local;
241 struct ieee80211_hw *hw = &local->hw;
242 struct sta_info *sta;
243 int ret, i;
244 DECLARE_MAC_BUF(mac);
245
246 rcu_read_lock();
247
248 sta = sta_info_get(local, ra);
249 if (!sta) {
250 rcu_read_unlock();
251 return;
252 }
253
254 /* check if TID is in operational state */
255 spin_lock_bh(&sta->lock);
256 if (sta->ampdu_mlme.tid_state_rx[tid]
257 != HT_AGG_STATE_OPERATIONAL) {
258 spin_unlock_bh(&sta->lock);
259 rcu_read_unlock();
260 return;
261 }
262 sta->ampdu_mlme.tid_state_rx[tid] =
263 HT_AGG_STATE_REQ_STOP_BA_MSK |
264 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
265 spin_unlock_bh(&sta->lock);
266
267 /* stop HW Rx aggregation. ampdu_action existence
268 * already verified in session init so we add the BUG_ON */
269 BUG_ON(!local->ops->ampdu_action);
270
271#ifdef CONFIG_MAC80211_HT_DEBUG
272 printk(KERN_DEBUG "Rx BA session stop requested for %s tid %u\n",
273 print_mac(mac, ra), tid);
274#endif /* CONFIG_MAC80211_HT_DEBUG */
275
276 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_STOP,
277 &sta->sta, tid, NULL);
278 if (ret)
279 printk(KERN_DEBUG "HW problem - can not stop rx "
280 "aggregation for tid %d\n", tid);
281
282 /* shutdown timer has not expired */
283 if (initiator != WLAN_BACK_TIMER)
284 del_timer_sync(&sta->ampdu_mlme.tid_rx[tid]->session_timer);
285
286 /* check if this is a self generated aggregation halt */
287 if (initiator == WLAN_BACK_RECIPIENT || initiator == WLAN_BACK_TIMER)
288 ieee80211_send_delba(sdata, ra, tid, 0, reason);
289
290 /* free the reordering buffer */
291 for (i = 0; i < sta->ampdu_mlme.tid_rx[tid]->buf_size; i++) {
292 if (sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]) {
293 /* release the reordered frames */
294 dev_kfree_skb(sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]);
295 sta->ampdu_mlme.tid_rx[tid]->stored_mpdu_num--;
296 sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i] = NULL;
297 }
298 }
299 /* free resources */
300 kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_buf);
301 kfree(sta->ampdu_mlme.tid_rx[tid]);
302 sta->ampdu_mlme.tid_rx[tid] = NULL;
303 sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_IDLE;
304
305 rcu_read_unlock();
306}
307
308
309/*
310 * After sending add Block Ack request we activated a timer until
311 * add Block Ack response will arrive from the recipient.
312 * If this timer expires sta_addba_resp_timer_expired will be executed.
313 */
314static void sta_addba_resp_timer_expired(unsigned long data)
315{
316 /* not an elegant detour, but there is no choice as the timer passes
317 * only one argument, and both sta_info and TID are needed, so init
318 * flow in sta_info_create gives the TID as data, while the timer_to_id
319 * array gives the sta through container_of */
320 u16 tid = *(u8 *)data;
321 struct sta_info *temp_sta = container_of((void *)data,
322 struct sta_info, timer_to_tid[tid]);
323
324 struct ieee80211_local *local = temp_sta->local;
325 struct ieee80211_hw *hw = &local->hw;
326 struct sta_info *sta;
327 u8 *state;
328
329 rcu_read_lock();
330
331 sta = sta_info_get(local, temp_sta->sta.addr);
332 if (!sta) {
333 rcu_read_unlock();
334 return;
335 }
336
337 state = &sta->ampdu_mlme.tid_state_tx[tid];
338 /* check if the TID waits for addBA response */
339 spin_lock_bh(&sta->lock);
340 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
341 spin_unlock_bh(&sta->lock);
342 *state = HT_AGG_STATE_IDLE;
343#ifdef CONFIG_MAC80211_HT_DEBUG
344 printk(KERN_DEBUG "timer expired on tid %d but we are not "
345 "expecting addBA response there", tid);
346#endif
347 goto timer_expired_exit;
348 }
349
350#ifdef CONFIG_MAC80211_HT_DEBUG
351 printk(KERN_DEBUG "addBA response timer expired on tid %d\n", tid);
352#endif
353
354 /* go through the state check in stop_BA_session */
355 *state = HT_AGG_STATE_OPERATIONAL;
356 spin_unlock_bh(&sta->lock);
357 ieee80211_stop_tx_ba_session(hw, temp_sta->sta.addr, tid,
358 WLAN_BACK_INITIATOR);
359
360timer_expired_exit:
361 rcu_read_unlock();
362}
363
364void ieee80211_sta_tear_down_BA_sessions(struct ieee80211_sub_if_data *sdata, u8 *addr)
365{
366 struct ieee80211_local *local = sdata->local;
367 int i;
368
369 for (i = 0; i < STA_TID_NUM; i++) {
370 ieee80211_stop_tx_ba_session(&local->hw, addr, i,
371 WLAN_BACK_INITIATOR);
372 ieee80211_sta_stop_rx_ba_session(sdata, addr, i,
373 WLAN_BACK_RECIPIENT,
374 WLAN_REASON_QSTA_LEAVE_QBSS);
375 }
376}
377
378int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
379{
380 struct ieee80211_local *local = hw_to_local(hw);
381 struct sta_info *sta;
382 struct ieee80211_sub_if_data *sdata;
383 u16 start_seq_num;
384 u8 *state;
385 int ret;
386 DECLARE_MAC_BUF(mac);
387
388 if (tid >= STA_TID_NUM)
389 return -EINVAL;
390
391#ifdef CONFIG_MAC80211_HT_DEBUG
392 printk(KERN_DEBUG "Open BA session requested for %s tid %u\n",
393 print_mac(mac, ra), tid);
394#endif /* CONFIG_MAC80211_HT_DEBUG */
395
396 rcu_read_lock();
397
398 sta = sta_info_get(local, ra);
399 if (!sta) {
400#ifdef CONFIG_MAC80211_HT_DEBUG
401 printk(KERN_DEBUG "Could not find the station\n");
402#endif
403 ret = -ENOENT;
404 goto exit;
405 }
406
407 spin_lock_bh(&sta->lock);
408
409 /* we have tried too many times, receiver does not want A-MPDU */
410 if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) {
411 ret = -EBUSY;
412 goto err_unlock_sta;
413 }
414
415 state = &sta->ampdu_mlme.tid_state_tx[tid];
416 /* check if the TID is not in aggregation flow already */
417 if (*state != HT_AGG_STATE_IDLE) {
418#ifdef CONFIG_MAC80211_HT_DEBUG
419 printk(KERN_DEBUG "BA request denied - session is not "
420 "idle on tid %u\n", tid);
421#endif /* CONFIG_MAC80211_HT_DEBUG */
422 ret = -EAGAIN;
423 goto err_unlock_sta;
424 }
425
426 /* prepare A-MPDU MLME for Tx aggregation */
427 sta->ampdu_mlme.tid_tx[tid] =
428 kmalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC);
429 if (!sta->ampdu_mlme.tid_tx[tid]) {
430#ifdef CONFIG_MAC80211_HT_DEBUG
431 if (net_ratelimit())
432 printk(KERN_ERR "allocate tx mlme to tid %d failed\n",
433 tid);
434#endif
435 ret = -ENOMEM;
436 goto err_unlock_sta;
437 }
438 /* Tx timer */
439 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function =
440 sta_addba_resp_timer_expired;
441 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.data =
442 (unsigned long)&sta->timer_to_tid[tid];
443 init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
444
445 /* create a new queue for this aggregation */
446 ret = ieee80211_ht_agg_queue_add(local, sta, tid);
447
448 /* case no queue is available to aggregation
449 * don't switch to aggregation */
450 if (ret) {
451#ifdef CONFIG_MAC80211_HT_DEBUG
452 printk(KERN_DEBUG "BA request denied - queue unavailable for"
453 " tid %d\n", tid);
454#endif /* CONFIG_MAC80211_HT_DEBUG */
455 goto err_unlock_queue;
456 }
457 sdata = sta->sdata;
458
459 /* Ok, the Addba frame hasn't been sent yet, but if the driver calls the
460 * call back right away, it must see that the flow has begun */
461 *state |= HT_ADDBA_REQUESTED_MSK;
462
463 /* This is slightly racy because the queue isn't stopped */
464 start_seq_num = sta->tid_seq[tid];
465
466 if (local->ops->ampdu_action)
467 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_START,
468 &sta->sta, tid, &start_seq_num);
469
470 if (ret) {
471 /* No need to requeue the packets in the agg queue, since we
472 * held the tx lock: no packet could be enqueued to the newly
473 * allocated queue */
474 ieee80211_ht_agg_queue_remove(local, sta, tid, 0);
475#ifdef CONFIG_MAC80211_HT_DEBUG
476 printk(KERN_DEBUG "BA request denied - HW unavailable for"
477 " tid %d\n", tid);
478#endif /* CONFIG_MAC80211_HT_DEBUG */
479 *state = HT_AGG_STATE_IDLE;
480 goto err_unlock_queue;
481 }
482
483 /* Will put all the packets in the new SW queue */
484 ieee80211_requeue(local, ieee802_1d_to_ac[tid]);
485 spin_unlock_bh(&sta->lock);
486
487 /* send an addBA request */
488 sta->ampdu_mlme.dialog_token_allocator++;
489 sta->ampdu_mlme.tid_tx[tid]->dialog_token =
490 sta->ampdu_mlme.dialog_token_allocator;
491 sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num;
492
493
494 ieee80211_send_addba_request(sta->sdata, ra, tid,
495 sta->ampdu_mlme.tid_tx[tid]->dialog_token,
496 sta->ampdu_mlme.tid_tx[tid]->ssn,
497 0x40, 5000);
498 /* activate the timer for the recipient's addBA response */
499 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires =
500 jiffies + ADDBA_RESP_INTERVAL;
501 add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
502#ifdef CONFIG_MAC80211_HT_DEBUG
503 printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid);
504#endif
505 goto exit;
506
507err_unlock_queue:
508 kfree(sta->ampdu_mlme.tid_tx[tid]);
509 sta->ampdu_mlme.tid_tx[tid] = NULL;
510 ret = -EBUSY;
511err_unlock_sta:
512 spin_unlock_bh(&sta->lock);
513exit:
514 rcu_read_unlock();
515 return ret;
516}
517EXPORT_SYMBOL(ieee80211_start_tx_ba_session);
518
519int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
520 u8 *ra, u16 tid,
521 enum ieee80211_back_parties initiator)
522{
523 struct ieee80211_local *local = hw_to_local(hw);
524 struct sta_info *sta;
525 u8 *state;
526 int ret = 0;
527 DECLARE_MAC_BUF(mac);
528
529 if (tid >= STA_TID_NUM)
530 return -EINVAL;
531
532 rcu_read_lock();
533 sta = sta_info_get(local, ra);
534 if (!sta) {
535 rcu_read_unlock();
536 return -ENOENT;
537 }
538
539 /* check if the TID is in aggregation */
540 state = &sta->ampdu_mlme.tid_state_tx[tid];
541 spin_lock_bh(&sta->lock);
542
543 if (*state != HT_AGG_STATE_OPERATIONAL) {
544 ret = -ENOENT;
545 goto stop_BA_exit;
546 }
547
548#ifdef CONFIG_MAC80211_HT_DEBUG
549 printk(KERN_DEBUG "Tx BA session stop requested for %s tid %u\n",
550 print_mac(mac, ra), tid);
551#endif /* CONFIG_MAC80211_HT_DEBUG */
552
553 ieee80211_stop_queue(hw, sta->tid_to_tx_q[tid]);
554
555 *state = HT_AGG_STATE_REQ_STOP_BA_MSK |
556 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
557
558 if (local->ops->ampdu_action)
559 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_STOP,
560 &sta->sta, tid, NULL);
561
562 /* case HW denied going back to legacy */
563 if (ret) {
564 WARN_ON(ret != -EBUSY);
565 *state = HT_AGG_STATE_OPERATIONAL;
566 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
567 goto stop_BA_exit;
568 }
569
570stop_BA_exit:
571 spin_unlock_bh(&sta->lock);
572 rcu_read_unlock();
573 return ret;
574}
575EXPORT_SYMBOL(ieee80211_stop_tx_ba_session);
576
577void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
578{
579 struct ieee80211_local *local = hw_to_local(hw);
580 struct sta_info *sta;
581 u8 *state;
582 DECLARE_MAC_BUF(mac);
583
584 if (tid >= STA_TID_NUM) {
585#ifdef CONFIG_MAC80211_HT_DEBUG
586 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
587 tid, STA_TID_NUM);
588#endif
589 return;
590 }
591
592 rcu_read_lock();
593 sta = sta_info_get(local, ra);
594 if (!sta) {
595 rcu_read_unlock();
596#ifdef CONFIG_MAC80211_HT_DEBUG
597 printk(KERN_DEBUG "Could not find station: %s\n",
598 print_mac(mac, ra));
599#endif
600 return;
601 }
602
603 state = &sta->ampdu_mlme.tid_state_tx[tid];
604 spin_lock_bh(&sta->lock);
605
606 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
607#ifdef CONFIG_MAC80211_HT_DEBUG
608 printk(KERN_DEBUG "addBA was not requested yet, state is %d\n",
609 *state);
610#endif
611 spin_unlock_bh(&sta->lock);
612 rcu_read_unlock();
613 return;
614 }
615
616 WARN_ON_ONCE(*state & HT_ADDBA_DRV_READY_MSK);
617
618 *state |= HT_ADDBA_DRV_READY_MSK;
619
620 if (*state == HT_AGG_STATE_OPERATIONAL) {
621#ifdef CONFIG_MAC80211_HT_DEBUG
622 printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid);
623#endif
624 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
625 }
626 spin_unlock_bh(&sta->lock);
627 rcu_read_unlock();
628}
629EXPORT_SYMBOL(ieee80211_start_tx_ba_cb);
630
631void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
632{
633 struct ieee80211_local *local = hw_to_local(hw);
634 struct sta_info *sta;
635 u8 *state;
636 int agg_queue;
637 DECLARE_MAC_BUF(mac);
638
639 if (tid >= STA_TID_NUM) {
640#ifdef CONFIG_MAC80211_HT_DEBUG
641 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
642 tid, STA_TID_NUM);
643#endif
644 return;
645 }
646
647#ifdef CONFIG_MAC80211_HT_DEBUG
648 printk(KERN_DEBUG "Stopping Tx BA session for %s tid %d\n",
649 print_mac(mac, ra), tid);
650#endif /* CONFIG_MAC80211_HT_DEBUG */
651
652 rcu_read_lock();
653 sta = sta_info_get(local, ra);
654 if (!sta) {
655#ifdef CONFIG_MAC80211_HT_DEBUG
656 printk(KERN_DEBUG "Could not find station: %s\n",
657 print_mac(mac, ra));
658#endif
659 rcu_read_unlock();
660 return;
661 }
662 state = &sta->ampdu_mlme.tid_state_tx[tid];
663
664 /* NOTE: no need to use sta->lock in this state check, as
665 * ieee80211_stop_tx_ba_session will let only one stop call to
666 * pass through per sta/tid
667 */
668 if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) {
669#ifdef CONFIG_MAC80211_HT_DEBUG
670 printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n");
671#endif
672 rcu_read_unlock();
673 return;
674 }
675
676 if (*state & HT_AGG_STATE_INITIATOR_MSK)
677 ieee80211_send_delba(sta->sdata, ra, tid,
678 WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
679
680 agg_queue = sta->tid_to_tx_q[tid];
681
682 ieee80211_ht_agg_queue_remove(local, sta, tid, 1);
683
684 /* We just requeued the all the frames that were in the
685 * removed queue, and since we might miss a softirq we do
686 * netif_schedule_queue. ieee80211_wake_queue is not used
687 * here as this queue is not necessarily stopped
688 */
689 netif_schedule_queue(netdev_get_tx_queue(local->mdev, agg_queue));
690 spin_lock_bh(&sta->lock);
691 *state = HT_AGG_STATE_IDLE;
692 sta->ampdu_mlme.addba_req_num[tid] = 0;
693 kfree(sta->ampdu_mlme.tid_tx[tid]);
694 sta->ampdu_mlme.tid_tx[tid] = NULL;
695 spin_unlock_bh(&sta->lock);
696
697 rcu_read_unlock();
698}
699EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb);
700
701void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
702 const u8 *ra, u16 tid)
703{
704 struct ieee80211_local *local = hw_to_local(hw);
705 struct ieee80211_ra_tid *ra_tid;
706 struct sk_buff *skb = dev_alloc_skb(0);
707
708 if (unlikely(!skb)) {
709#ifdef CONFIG_MAC80211_HT_DEBUG
710 if (net_ratelimit())
711 printk(KERN_WARNING "%s: Not enough memory, "
712 "dropping start BA session", skb->dev->name);
713#endif
714 return;
715 }
716 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
717 memcpy(&ra_tid->ra, ra, ETH_ALEN);
718 ra_tid->tid = tid;
719
720 skb->pkt_type = IEEE80211_ADDBA_MSG;
721 skb_queue_tail(&local->skb_queue, skb);
722 tasklet_schedule(&local->tasklet);
723}
724EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe);
725
726void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
727 const u8 *ra, u16 tid)
728{
729 struct ieee80211_local *local = hw_to_local(hw);
730 struct ieee80211_ra_tid *ra_tid;
731 struct sk_buff *skb = dev_alloc_skb(0);
732
733 if (unlikely(!skb)) {
734#ifdef CONFIG_MAC80211_HT_DEBUG
735 if (net_ratelimit())
736 printk(KERN_WARNING "%s: Not enough memory, "
737 "dropping stop BA session", skb->dev->name);
738#endif
739 return;
740 }
741 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
742 memcpy(&ra_tid->ra, ra, ETH_ALEN);
743 ra_tid->tid = tid;
744
745 skb->pkt_type = IEEE80211_DELBA_MSG;
746 skb_queue_tail(&local->skb_queue, skb);
747 tasklet_schedule(&local->tasklet);
748}
749EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb_irqsafe);
750
751/*
752 * After accepting the AddBA Request we activated a timer,
753 * resetting it after each frame that arrives from the originator.
754 * if this timer expires ieee80211_sta_stop_rx_ba_session will be executed.
755 */
756static void sta_rx_agg_session_timer_expired(unsigned long data)
757{
758 /* not an elegant detour, but there is no choice as the timer passes
759 * only one argument, and various sta_info are needed here, so init
760 * flow in sta_info_create gives the TID as data, while the timer_to_id
761 * array gives the sta through container_of */
762 u8 *ptid = (u8 *)data;
763 u8 *timer_to_id = ptid - *ptid;
764 struct sta_info *sta = container_of(timer_to_id, struct sta_info,
765 timer_to_tid[0]);
766
767#ifdef CONFIG_MAC80211_HT_DEBUG
768 printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid);
769#endif
770 ieee80211_sta_stop_rx_ba_session(sta->sdata, sta->sta.addr,
771 (u16)*ptid, WLAN_BACK_TIMER,
772 WLAN_REASON_QSTA_TIMEOUT);
773}
774
775void ieee80211_process_addba_request(struct ieee80211_local *local,
776 struct sta_info *sta,
777 struct ieee80211_mgmt *mgmt,
778 size_t len)
779{
780 struct ieee80211_hw *hw = &local->hw;
781 struct ieee80211_conf *conf = &hw->conf;
782 struct tid_ampdu_rx *tid_agg_rx;
783 u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status;
784 u8 dialog_token;
785 int ret = -EOPNOTSUPP;
786 DECLARE_MAC_BUF(mac);
787
788 /* extract session parameters from addba request frame */
789 dialog_token = mgmt->u.action.u.addba_req.dialog_token;
790 timeout = le16_to_cpu(mgmt->u.action.u.addba_req.timeout);
791 start_seq_num =
792 le16_to_cpu(mgmt->u.action.u.addba_req.start_seq_num) >> 4;
793
794 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
795 ba_policy = (capab & IEEE80211_ADDBA_PARAM_POLICY_MASK) >> 1;
796 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
797 buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6;
798
799 status = WLAN_STATUS_REQUEST_DECLINED;
800
801 /* sanity check for incoming parameters:
802 * check if configuration can support the BA policy
803 * and if buffer size does not exceeds max value */
804 if (((ba_policy != 1)
805 && (!(conf->ht_conf.cap & IEEE80211_HT_CAP_DELAY_BA)))
806 || (buf_size > IEEE80211_MAX_AMPDU_BUF)) {
807 status = WLAN_STATUS_INVALID_QOS_PARAM;
808#ifdef CONFIG_MAC80211_HT_DEBUG
809 if (net_ratelimit())
810 printk(KERN_DEBUG "AddBA Req with bad params from "
811 "%s on tid %u. policy %d, buffer size %d\n",
812 print_mac(mac, mgmt->sa), tid, ba_policy,
813 buf_size);
814#endif /* CONFIG_MAC80211_HT_DEBUG */
815 goto end_no_lock;
816 }
817 /* determine default buffer size */
818 if (buf_size == 0) {
819 struct ieee80211_supported_band *sband;
820
821 sband = local->hw.wiphy->bands[conf->channel->band];
822 buf_size = IEEE80211_MIN_AMPDU_BUF;
823 buf_size = buf_size << sband->ht_info.ampdu_factor;
824 }
825
826
827 /* examine state machine */
828 spin_lock_bh(&sta->lock);
829
830 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) {
831#ifdef CONFIG_MAC80211_HT_DEBUG
832 if (net_ratelimit())
833 printk(KERN_DEBUG "unexpected AddBA Req from "
834 "%s on tid %u\n",
835 print_mac(mac, mgmt->sa), tid);
836#endif /* CONFIG_MAC80211_HT_DEBUG */
837 goto end;
838 }
839
840 /* prepare A-MPDU MLME for Rx aggregation */
841 sta->ampdu_mlme.tid_rx[tid] =
842 kmalloc(sizeof(struct tid_ampdu_rx), GFP_ATOMIC);
843 if (!sta->ampdu_mlme.tid_rx[tid]) {
844#ifdef CONFIG_MAC80211_HT_DEBUG
845 if (net_ratelimit())
846 printk(KERN_ERR "allocate rx mlme to tid %d failed\n",
847 tid);
848#endif
849 goto end;
850 }
851 /* rx timer */
852 sta->ampdu_mlme.tid_rx[tid]->session_timer.function =
853 sta_rx_agg_session_timer_expired;
854 sta->ampdu_mlme.tid_rx[tid]->session_timer.data =
855 (unsigned long)&sta->timer_to_tid[tid];
856 init_timer(&sta->ampdu_mlme.tid_rx[tid]->session_timer);
857
858 tid_agg_rx = sta->ampdu_mlme.tid_rx[tid];
859
860 /* prepare reordering buffer */
861 tid_agg_rx->reorder_buf =
862 kmalloc(buf_size * sizeof(struct sk_buff *), GFP_ATOMIC);
863 if (!tid_agg_rx->reorder_buf) {
864#ifdef CONFIG_MAC80211_HT_DEBUG
865 if (net_ratelimit())
866 printk(KERN_ERR "can not allocate reordering buffer "
867 "to tid %d\n", tid);
868#endif
869 kfree(sta->ampdu_mlme.tid_rx[tid]);
870 goto end;
871 }
872 memset(tid_agg_rx->reorder_buf, 0,
873 buf_size * sizeof(struct sk_buff *));
874
875 if (local->ops->ampdu_action)
876 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_START,
877 &sta->sta, tid, &start_seq_num);
878#ifdef CONFIG_MAC80211_HT_DEBUG
879 printk(KERN_DEBUG "Rx A-MPDU request on tid %d result %d\n", tid, ret);
880#endif /* CONFIG_MAC80211_HT_DEBUG */
881
882 if (ret) {
883 kfree(tid_agg_rx->reorder_buf);
884 kfree(tid_agg_rx);
885 sta->ampdu_mlme.tid_rx[tid] = NULL;
886 goto end;
887 }
888
889 /* change state and send addba resp */
890 sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_OPERATIONAL;
891 tid_agg_rx->dialog_token = dialog_token;
892 tid_agg_rx->ssn = start_seq_num;
893 tid_agg_rx->head_seq_num = start_seq_num;
894 tid_agg_rx->buf_size = buf_size;
895 tid_agg_rx->timeout = timeout;
896 tid_agg_rx->stored_mpdu_num = 0;
897 status = WLAN_STATUS_SUCCESS;
898end:
899 spin_unlock_bh(&sta->lock);
900
901end_no_lock:
902 ieee80211_send_addba_resp(sta->sdata, sta->sta.addr, tid,
903 dialog_token, status, 1, buf_size, timeout);
904}
905
906void ieee80211_process_addba_resp(struct ieee80211_local *local,
907 struct sta_info *sta,
908 struct ieee80211_mgmt *mgmt,
909 size_t len)
910{
911 struct ieee80211_hw *hw = &local->hw;
912 u16 capab;
913 u16 tid;
914 u8 *state;
915
916 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
917 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
918
919 state = &sta->ampdu_mlme.tid_state_tx[tid];
920
921 spin_lock_bh(&sta->lock);
922
923 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
924 spin_unlock_bh(&sta->lock);
925 return;
926 }
927
928 if (mgmt->u.action.u.addba_resp.dialog_token !=
929 sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
930 spin_unlock_bh(&sta->lock);
931#ifdef CONFIG_MAC80211_HT_DEBUG
932 printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
933#endif /* CONFIG_MAC80211_HT_DEBUG */
934 return;
935 }
936
937 del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
938#ifdef CONFIG_MAC80211_HT_DEBUG
939 printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid);
940#endif /* CONFIG_MAC80211_HT_DEBUG */
941 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
942 == WLAN_STATUS_SUCCESS) {
943 *state |= HT_ADDBA_RECEIVED_MSK;
944 sta->ampdu_mlme.addba_req_num[tid] = 0;
945
946 if (*state == HT_AGG_STATE_OPERATIONAL)
947 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
948
949 spin_unlock_bh(&sta->lock);
950 } else {
951 sta->ampdu_mlme.addba_req_num[tid]++;
952 /* this will allow the state check in stop_BA_session */
953 *state = HT_AGG_STATE_OPERATIONAL;
954 spin_unlock_bh(&sta->lock);
955 ieee80211_stop_tx_ba_session(hw, sta->sta.addr, tid,
956 WLAN_BACK_INITIATOR);
957 }
958}
959
960void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
961 struct sta_info *sta,
962 struct ieee80211_mgmt *mgmt, size_t len)
963{
964 struct ieee80211_local *local = sdata->local;
965 u16 tid, params;
966 u16 initiator;
967 DECLARE_MAC_BUF(mac);
968
969 params = le16_to_cpu(mgmt->u.action.u.delba.params);
970 tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12;
971 initiator = (params & IEEE80211_DELBA_PARAM_INITIATOR_MASK) >> 11;
972
973#ifdef CONFIG_MAC80211_HT_DEBUG
974 if (net_ratelimit())
975 printk(KERN_DEBUG "delba from %s (%s) tid %d reason code %d\n",
976 print_mac(mac, mgmt->sa),
977 initiator ? "initiator" : "recipient", tid,
978 mgmt->u.action.u.delba.reason_code);
979#endif /* CONFIG_MAC80211_HT_DEBUG */
980
981 if (initiator == WLAN_BACK_INITIATOR)
982 ieee80211_sta_stop_rx_ba_session(sdata, sta->sta.addr, tid,
983 WLAN_BACK_INITIATOR, 0);
984 else { /* WLAN_BACK_RECIPIENT */
985 spin_lock_bh(&sta->lock);
986 sta->ampdu_mlme.tid_state_tx[tid] =
987 HT_AGG_STATE_OPERATIONAL;
988 spin_unlock_bh(&sta->lock);
989 ieee80211_stop_tx_ba_session(&local->hw, sta->sta.addr, tid,
990 WLAN_BACK_RECIPIENT);
991 }
992}
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 586a9b49b0fc..8025b294588b 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -29,17 +29,6 @@
29#include "key.h" 29#include "key.h"
30#include "sta_info.h" 30#include "sta_info.h"
31 31
32/* ieee80211.o internal definitions, etc. These are not included into
33 * low-level drivers. */
34
35#ifndef ETH_P_PAE
36#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
37#endif /* ETH_P_PAE */
38
39#define WLAN_FC_DATA_PRESENT(fc) (((fc) & 0x4c) == 0x08)
40
41#define IEEE80211_FC(type, subtype) cpu_to_le16(type | subtype)
42
43struct ieee80211_local; 32struct ieee80211_local;
44 33
45/* Maximum number of broadcast/multicast frames to buffer when some of the 34/* Maximum number of broadcast/multicast frames to buffer when some of the
@@ -61,6 +50,12 @@ struct ieee80211_local;
61 * increased memory use (about 2 kB of RAM per entry). */ 50 * increased memory use (about 2 kB of RAM per entry). */
62#define IEEE80211_FRAGMENT_MAX 4 51#define IEEE80211_FRAGMENT_MAX 4
63 52
53/*
54 * Time after which we ignore scan results and no longer report/use
55 * them in any way.
56 */
57#define IEEE80211_SCAN_RESULT_EXPIRE (10 * HZ)
58
64struct ieee80211_fragment_entry { 59struct ieee80211_fragment_entry {
65 unsigned long first_frag_time; 60 unsigned long first_frag_time;
66 unsigned int seq; 61 unsigned int seq;
@@ -73,9 +68,9 @@ struct ieee80211_fragment_entry {
73}; 68};
74 69
75 70
76struct ieee80211_sta_bss { 71struct ieee80211_bss {
77 struct list_head list; 72 struct list_head list;
78 struct ieee80211_sta_bss *hnext; 73 struct ieee80211_bss *hnext;
79 size_t ssid_len; 74 size_t ssid_len;
80 75
81 atomic_t users; 76 atomic_t users;
@@ -87,16 +82,11 @@ struct ieee80211_sta_bss {
87 enum ieee80211_band band; 82 enum ieee80211_band band;
88 int freq; 83 int freq;
89 int signal, noise, qual; 84 int signal, noise, qual;
90 u8 *wpa_ie; 85 u8 *ies; /* all information elements from the last Beacon or Probe
91 size_t wpa_ie_len; 86 * Response frames; note Beacon frame is not allowed to
92 u8 *rsn_ie; 87 * override values from Probe Response */
93 size_t rsn_ie_len; 88 size_t ies_len;
94 u8 *wmm_ie; 89 bool wmm_used;
95 size_t wmm_ie_len;
96 u8 *ht_ie;
97 size_t ht_ie_len;
98 u8 *ht_add_ie;
99 size_t ht_add_ie_len;
100#ifdef CONFIG_MAC80211_MESH 90#ifdef CONFIG_MAC80211_MESH
101 u8 *mesh_id; 91 u8 *mesh_id;
102 size_t mesh_id_len; 92 size_t mesh_id_len;
@@ -108,7 +98,7 @@ struct ieee80211_sta_bss {
108 u64 timestamp; 98 u64 timestamp;
109 int beacon_int; 99 int beacon_int;
110 100
111 bool probe_resp; 101 unsigned long last_probe_resp;
112 unsigned long last_update; 102 unsigned long last_update;
113 103
114 /* during assocation, we save an ERP value from a probe response so 104 /* during assocation, we save an ERP value from a probe response so
@@ -119,7 +109,7 @@ struct ieee80211_sta_bss {
119 u8 erp_value; 109 u8 erp_value;
120}; 110};
121 111
122static inline u8 *bss_mesh_cfg(struct ieee80211_sta_bss *bss) 112static inline u8 *bss_mesh_cfg(struct ieee80211_bss *bss)
123{ 113{
124#ifdef CONFIG_MAC80211_MESH 114#ifdef CONFIG_MAC80211_MESH
125 return bss->mesh_cfg; 115 return bss->mesh_cfg;
@@ -127,7 +117,7 @@ static inline u8 *bss_mesh_cfg(struct ieee80211_sta_bss *bss)
127 return NULL; 117 return NULL;
128} 118}
129 119
130static inline u8 *bss_mesh_id(struct ieee80211_sta_bss *bss) 120static inline u8 *bss_mesh_id(struct ieee80211_bss *bss)
131{ 121{
132#ifdef CONFIG_MAC80211_MESH 122#ifdef CONFIG_MAC80211_MESH
133 return bss->mesh_id; 123 return bss->mesh_id;
@@ -135,7 +125,7 @@ static inline u8 *bss_mesh_id(struct ieee80211_sta_bss *bss)
135 return NULL; 125 return NULL;
136} 126}
137 127
138static inline u8 bss_mesh_id_len(struct ieee80211_sta_bss *bss) 128static inline u8 bss_mesh_id_len(struct ieee80211_bss *bss)
139{ 129{
140#ifdef CONFIG_MAC80211_MESH 130#ifdef CONFIG_MAC80211_MESH
141 return bss->mesh_id_len; 131 return bss->mesh_id_len;
@@ -174,7 +164,7 @@ struct ieee80211_tx_data {
174 struct sk_buff **extra_frag; 164 struct sk_buff **extra_frag;
175 int num_extra_frag; 165 int num_extra_frag;
176 166
177 u16 fc, ethertype; 167 u16 ethertype;
178 unsigned int flags; 168 unsigned int flags;
179}; 169};
180 170
@@ -202,7 +192,7 @@ struct ieee80211_rx_data {
202 struct ieee80211_rx_status *status; 192 struct ieee80211_rx_status *status;
203 struct ieee80211_rate *rate; 193 struct ieee80211_rate *rate;
204 194
205 u16 fc, ethertype; 195 u16 ethertype;
206 unsigned int flags; 196 unsigned int flags;
207 int sent_ps_buffered; 197 int sent_ps_buffered;
208 int queue; 198 int queue;
@@ -239,7 +229,6 @@ struct ieee80211_if_ap {
239 struct sk_buff_head ps_bc_buf; 229 struct sk_buff_head ps_bc_buf;
240 atomic_t num_sta_ps; /* number of stations in PS mode */ 230 atomic_t num_sta_ps; /* number of stations in PS mode */
241 int dtim_count; 231 int dtim_count;
242 int num_beacons; /* number of TXed beacon frames for this BSS */
243}; 232};
244 233
245struct ieee80211_if_wds { 234struct ieee80211_if_wds {
@@ -300,48 +289,37 @@ struct mesh_config {
300#define IEEE80211_STA_AUTO_BSSID_SEL BIT(11) 289#define IEEE80211_STA_AUTO_BSSID_SEL BIT(11)
301#define IEEE80211_STA_AUTO_CHANNEL_SEL BIT(12) 290#define IEEE80211_STA_AUTO_CHANNEL_SEL BIT(12)
302#define IEEE80211_STA_PRIVACY_INVOKED BIT(13) 291#define IEEE80211_STA_PRIVACY_INVOKED BIT(13)
292/* flags for MLME request */
293#define IEEE80211_STA_REQ_SCAN 0
294#define IEEE80211_STA_REQ_DIRECT_PROBE 1
295#define IEEE80211_STA_REQ_AUTH 2
296#define IEEE80211_STA_REQ_RUN 3
297
298/* STA/IBSS MLME states */
299enum ieee80211_sta_mlme_state {
300 IEEE80211_STA_MLME_DISABLED,
301 IEEE80211_STA_MLME_DIRECT_PROBE,
302 IEEE80211_STA_MLME_AUTHENTICATE,
303 IEEE80211_STA_MLME_ASSOCIATE,
304 IEEE80211_STA_MLME_ASSOCIATED,
305 IEEE80211_STA_MLME_IBSS_SEARCH,
306 IEEE80211_STA_MLME_IBSS_JOINED,
307};
308
309/* bitfield of allowed auth algs */
310#define IEEE80211_AUTH_ALG_OPEN BIT(0)
311#define IEEE80211_AUTH_ALG_SHARED_KEY BIT(1)
312#define IEEE80211_AUTH_ALG_LEAP BIT(2)
313
303struct ieee80211_if_sta { 314struct ieee80211_if_sta {
304 struct timer_list timer; 315 struct timer_list timer;
305 struct work_struct work; 316 struct work_struct work;
306 u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN]; 317 u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN];
307 u8 ssid[IEEE80211_MAX_SSID_LEN]; 318 u8 ssid[IEEE80211_MAX_SSID_LEN];
308 enum { 319 enum ieee80211_sta_mlme_state state;
309 IEEE80211_DISABLED, IEEE80211_AUTHENTICATE,
310 IEEE80211_ASSOCIATE, IEEE80211_ASSOCIATED,
311 IEEE80211_IBSS_SEARCH, IEEE80211_IBSS_JOINED,
312 IEEE80211_MESH_UP
313 } state;
314 size_t ssid_len; 320 size_t ssid_len;
315 u8 scan_ssid[IEEE80211_MAX_SSID_LEN]; 321 u8 scan_ssid[IEEE80211_MAX_SSID_LEN];
316 size_t scan_ssid_len; 322 size_t scan_ssid_len;
317#ifdef CONFIG_MAC80211_MESH
318 struct timer_list mesh_path_timer;
319 u8 mesh_id[IEEE80211_MAX_MESH_ID_LEN];
320 size_t mesh_id_len;
321 /* Active Path Selection Protocol Identifier */
322 u8 mesh_pp_id[4];
323 /* Active Path Selection Metric Identifier */
324 u8 mesh_pm_id[4];
325 /* Congestion Control Mode Identifier */
326 u8 mesh_cc_id[4];
327 /* Local mesh Destination Sequence Number */
328 u32 dsn;
329 /* Last used PREQ ID */
330 u32 preq_id;
331 atomic_t mpaths;
332 /* Timestamp of last DSN update */
333 unsigned long last_dsn_update;
334 /* Timestamp of last DSN sent */
335 unsigned long last_preq;
336 struct mesh_rmc *rmc;
337 spinlock_t mesh_preq_queue_lock;
338 struct mesh_preq_queue preq_queue;
339 int preq_queue_len;
340 struct mesh_stats mshstats;
341 struct mesh_config mshcfg;
342 u32 mesh_seqnum;
343 bool accepting_plinks;
344#endif
345 u16 aid; 323 u16 aid;
346 u16 ap_capab, capab; 324 u16 ap_capab, capab;
347 u8 *extra_ie; /* to be added to the end of AssocReq */ 325 u8 *extra_ie; /* to be added to the end of AssocReq */
@@ -353,20 +331,17 @@ struct ieee80211_if_sta {
353 331
354 struct sk_buff_head skb_queue; 332 struct sk_buff_head skb_queue;
355 333
356 int auth_tries, assoc_tries; 334 int assoc_scan_tries; /* number of scans done pre-association */
335 int direct_probe_tries; /* retries for direct probes */
336 int auth_tries; /* retries for auth req */
337 int assoc_tries; /* retries for assoc req */
357 338
358 unsigned long request; 339 unsigned long request;
359 340
360 unsigned long last_probe; 341 unsigned long last_probe;
361 342
362 unsigned int flags; 343 unsigned int flags;
363#define IEEE80211_STA_REQ_SCAN 0
364#define IEEE80211_STA_REQ_AUTH 1
365#define IEEE80211_STA_REQ_RUN 2
366 344
367#define IEEE80211_AUTH_ALG_OPEN BIT(0)
368#define IEEE80211_AUTH_ALG_SHARED_KEY BIT(1)
369#define IEEE80211_AUTH_ALG_LEAP BIT(2)
370 unsigned int auth_algs; /* bitfield of allowed auth algs */ 345 unsigned int auth_algs; /* bitfield of allowed auth algs */
371 int auth_alg; /* currently used IEEE 802.11 authentication algorithm */ 346 int auth_alg; /* currently used IEEE 802.11 authentication algorithm */
372 int auth_transaction; 347 int auth_transaction;
@@ -376,31 +351,70 @@ struct ieee80211_if_sta {
376 u32 supp_rates_bits[IEEE80211_NUM_BANDS]; 351 u32 supp_rates_bits[IEEE80211_NUM_BANDS];
377 352
378 int wmm_last_param_set; 353 int wmm_last_param_set;
379 int num_beacons; /* number of TXed beacon frames by this STA */
380}; 354};
381 355
382static inline void ieee80211_if_sta_set_mesh_id(struct ieee80211_if_sta *ifsta, 356struct ieee80211_if_mesh {
383 u8 mesh_id_len, u8 *mesh_id) 357 struct work_struct work;
384{ 358 struct timer_list housekeeping_timer;
385#ifdef CONFIG_MAC80211_MESH 359 struct timer_list mesh_path_timer;
386 ifsta->mesh_id_len = mesh_id_len; 360 struct sk_buff_head skb_queue;
387 memcpy(ifsta->mesh_id, mesh_id, mesh_id_len); 361
388#endif 362 bool housekeeping;
389} 363
364 u8 mesh_id[IEEE80211_MAX_MESH_ID_LEN];
365 size_t mesh_id_len;
366 /* Active Path Selection Protocol Identifier */
367 u8 mesh_pp_id[4];
368 /* Active Path Selection Metric Identifier */
369 u8 mesh_pm_id[4];
370 /* Congestion Control Mode Identifier */
371 u8 mesh_cc_id[4];
372 /* Local mesh Destination Sequence Number */
373 u32 dsn;
374 /* Last used PREQ ID */
375 u32 preq_id;
376 atomic_t mpaths;
377 /* Timestamp of last DSN update */
378 unsigned long last_dsn_update;
379 /* Timestamp of last DSN sent */
380 unsigned long last_preq;
381 struct mesh_rmc *rmc;
382 spinlock_t mesh_preq_queue_lock;
383 struct mesh_preq_queue preq_queue;
384 int preq_queue_len;
385 struct mesh_stats mshstats;
386 struct mesh_config mshcfg;
387 u32 mesh_seqnum;
388 bool accepting_plinks;
389};
390 390
391#ifdef CONFIG_MAC80211_MESH 391#ifdef CONFIG_MAC80211_MESH
392#define IEEE80211_IFSTA_MESH_CTR_INC(sta, name) \ 392#define IEEE80211_IFSTA_MESH_CTR_INC(msh, name) \
393 do { (sta)->mshstats.name++; } while (0) 393 do { (msh)->mshstats.name++; } while (0)
394#else 394#else
395#define IEEE80211_IFSTA_MESH_CTR_INC(sta, name) \ 395#define IEEE80211_IFSTA_MESH_CTR_INC(msh, name) \
396 do { } while (0) 396 do { } while (0)
397#endif 397#endif
398 398
399/* flags used in struct ieee80211_sub_if_data.flags */ 399/**
400#define IEEE80211_SDATA_ALLMULTI BIT(0) 400 * enum ieee80211_sub_if_data_flags - virtual interface flags
401#define IEEE80211_SDATA_PROMISC BIT(1) 401 *
402#define IEEE80211_SDATA_USERSPACE_MLME BIT(2) 402 * @IEEE80211_SDATA_ALLMULTI: interface wants all multicast packets
403#define IEEE80211_SDATA_OPERATING_GMODE BIT(3) 403 * @IEEE80211_SDATA_PROMISC: interface is promisc
404 * @IEEE80211_SDATA_USERSPACE_MLME: userspace MLME is active
405 * @IEEE80211_SDATA_OPERATING_GMODE: operating in G-only mode
406 * @IEEE80211_SDATA_DONT_BRIDGE_PACKETS: bridge packets between
407 * associated stations and deliver multicast frames both
408 * back to wireless media and to the local net stack.
409 */
410enum ieee80211_sub_if_data_flags {
411 IEEE80211_SDATA_ALLMULTI = BIT(0),
412 IEEE80211_SDATA_PROMISC = BIT(1),
413 IEEE80211_SDATA_USERSPACE_MLME = BIT(2),
414 IEEE80211_SDATA_OPERATING_GMODE = BIT(3),
415 IEEE80211_SDATA_DONT_BRIDGE_PACKETS = BIT(4),
416};
417
404struct ieee80211_sub_if_data { 418struct ieee80211_sub_if_data {
405 struct list_head list; 419 struct list_head list;
406 420
@@ -416,11 +430,6 @@ struct ieee80211_sub_if_data {
416 430
417 int drop_unencrypted; 431 int drop_unencrypted;
418 432
419 /*
420 * basic rates of this AP or the AP we're associated to
421 */
422 u64 basic_rates;
423
424 /* Fragment table for host-based reassembly */ 433 /* Fragment table for host-based reassembly */
425 struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX]; 434 struct ieee80211_fragment_entry fragments[IEEE80211_FRAGMENT_MAX];
426 unsigned int fragment_next; 435 unsigned int fragment_next;
@@ -447,6 +456,9 @@ struct ieee80211_sub_if_data {
447 struct ieee80211_if_wds wds; 456 struct ieee80211_if_wds wds;
448 struct ieee80211_if_vlan vlan; 457 struct ieee80211_if_vlan vlan;
449 struct ieee80211_if_sta sta; 458 struct ieee80211_if_sta sta;
459#ifdef CONFIG_MAC80211_MESH
460 struct ieee80211_if_mesh mesh;
461#endif
450 u32 mntr_flags; 462 u32 mntr_flags;
451 } u; 463 } u;
452 464
@@ -469,7 +481,6 @@ struct ieee80211_sub_if_data {
469 struct dentry *auth_alg; 481 struct dentry *auth_alg;
470 struct dentry *auth_transaction; 482 struct dentry *auth_transaction;
471 struct dentry *flags; 483 struct dentry *flags;
472 struct dentry *num_beacons_sta;
473 struct dentry *force_unicast_rateidx; 484 struct dentry *force_unicast_rateidx;
474 struct dentry *max_ratectrl_rateidx; 485 struct dentry *max_ratectrl_rateidx;
475 } sta; 486 } sta;
@@ -477,7 +488,6 @@ struct ieee80211_sub_if_data {
477 struct dentry *drop_unencrypted; 488 struct dentry *drop_unencrypted;
478 struct dentry *num_sta_ps; 489 struct dentry *num_sta_ps;
479 struct dentry *dtim_count; 490 struct dentry *dtim_count;
480 struct dentry *num_beacons;
481 struct dentry *force_unicast_rateidx; 491 struct dentry *force_unicast_rateidx;
482 struct dentry *max_ratectrl_rateidx; 492 struct dentry *max_ratectrl_rateidx;
483 struct dentry *num_buffered_multicast; 493 struct dentry *num_buffered_multicast;
@@ -496,8 +506,10 @@ struct ieee80211_sub_if_data {
496 struct { 506 struct {
497 struct dentry *mode; 507 struct dentry *mode;
498 } monitor; 508 } monitor;
499 struct dentry *default_key;
500 } debugfs; 509 } debugfs;
510 struct {
511 struct dentry *default_key;
512 } common_debugfs;
501 513
502#ifdef CONFIG_MAC80211_MESH 514#ifdef CONFIG_MAC80211_MESH
503 struct dentry *mesh_stats_dir; 515 struct dentry *mesh_stats_dir;
@@ -538,6 +550,19 @@ struct ieee80211_sub_if_data *vif_to_sdata(struct ieee80211_vif *p)
538 return container_of(p, struct ieee80211_sub_if_data, vif); 550 return container_of(p, struct ieee80211_sub_if_data, vif);
539} 551}
540 552
553static inline void
554ieee80211_sdata_set_mesh_id(struct ieee80211_sub_if_data *sdata,
555 u8 mesh_id_len, u8 *mesh_id)
556{
557#ifdef CONFIG_MAC80211_MESH
558 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
559 ifmsh->mesh_id_len = mesh_id_len;
560 memcpy(ifmsh->mesh_id, mesh_id, mesh_id_len);
561#else
562 WARN_ON(1);
563#endif
564}
565
541enum { 566enum {
542 IEEE80211_RX_MSG = 1, 567 IEEE80211_RX_MSG = 1,
543 IEEE80211_TX_STATUS_MSG = 2, 568 IEEE80211_TX_STATUS_MSG = 2,
@@ -548,6 +573,10 @@ enum {
548/* maximum number of hardware queues we support. */ 573/* maximum number of hardware queues we support. */
549#define QD_MAX_QUEUES (IEEE80211_MAX_AMPDU_QUEUES + IEEE80211_MAX_QUEUES) 574#define QD_MAX_QUEUES (IEEE80211_MAX_AMPDU_QUEUES + IEEE80211_MAX_QUEUES)
550 575
576struct ieee80211_master_priv {
577 struct ieee80211_local *local;
578};
579
551struct ieee80211_local { 580struct ieee80211_local {
552 /* embed the driver visible part. 581 /* embed the driver visible part.
553 * don't cast (use the static inlines below), but we keep 582 * don't cast (use the static inlines below), but we keep
@@ -611,10 +640,6 @@ struct ieee80211_local {
611 struct crypto_blkcipher *wep_rx_tfm; 640 struct crypto_blkcipher *wep_rx_tfm;
612 u32 wep_iv; 641 u32 wep_iv;
613 642
614 int bridge_packets; /* bridge packets between associated stations and
615 * deliver multicast frames both back to wireless
616 * media and to the local net stack */
617
618 struct list_head interfaces; 643 struct list_head interfaces;
619 644
620 /* 645 /*
@@ -624,21 +649,21 @@ struct ieee80211_local {
624 spinlock_t key_lock; 649 spinlock_t key_lock;
625 650
626 651
627 bool sta_sw_scanning; 652 /* Scanning and BSS list */
628 bool sta_hw_scanning; 653 bool sw_scanning, hw_scanning;
629 int scan_channel_idx; 654 int scan_channel_idx;
630 enum ieee80211_band scan_band; 655 enum ieee80211_band scan_band;
631 656
632 enum { SCAN_SET_CHANNEL, SCAN_SEND_PROBE } scan_state; 657 enum { SCAN_SET_CHANNEL, SCAN_SEND_PROBE } scan_state;
633 unsigned long last_scan_completed; 658 unsigned long last_scan_completed;
634 struct delayed_work scan_work; 659 struct delayed_work scan_work;
635 struct net_device *scan_dev; 660 struct ieee80211_sub_if_data *scan_sdata;
636 struct ieee80211_channel *oper_channel, *scan_channel; 661 struct ieee80211_channel *oper_channel, *scan_channel;
637 u8 scan_ssid[IEEE80211_MAX_SSID_LEN]; 662 u8 scan_ssid[IEEE80211_MAX_SSID_LEN];
638 size_t scan_ssid_len; 663 size_t scan_ssid_len;
639 struct list_head sta_bss_list; 664 struct list_head bss_list;
640 struct ieee80211_sta_bss *sta_bss_hash[STA_HASH_SIZE]; 665 struct ieee80211_bss *bss_hash[STA_HASH_SIZE];
641 spinlock_t sta_bss_lock; 666 spinlock_t bss_lock;
642 667
643 /* SNMP counters */ 668 /* SNMP counters */
644 /* dot11CountersTable */ 669 /* dot11CountersTable */
@@ -699,10 +724,11 @@ struct ieee80211_local {
699 724
700#ifdef CONFIG_MAC80211_DEBUGFS 725#ifdef CONFIG_MAC80211_DEBUGFS
701 struct local_debugfsdentries { 726 struct local_debugfsdentries {
727 struct dentry *rcdir;
728 struct dentry *rcname;
702 struct dentry *frequency; 729 struct dentry *frequency;
703 struct dentry *antenna_sel_tx; 730 struct dentry *antenna_sel_tx;
704 struct dentry *antenna_sel_rx; 731 struct dentry *antenna_sel_rx;
705 struct dentry *bridge_packets;
706 struct dentry *rts_threshold; 732 struct dentry *rts_threshold;
707 struct dentry *fragmentation_threshold; 733 struct dentry *fragmentation_threshold;
708 struct dentry *short_retry_limit; 734 struct dentry *short_retry_limit;
@@ -772,6 +798,9 @@ struct ieee80211_ra_tid {
772 798
773/* Parsed Information Elements */ 799/* Parsed Information Elements */
774struct ieee802_11_elems { 800struct ieee802_11_elems {
801 u8 *ie_start;
802 size_t total_len;
803
775 /* pointers to IEs */ 804 /* pointers to IEs */
776 u8 *ssid; 805 u8 *ssid;
777 u8 *supp_rates; 806 u8 *supp_rates;
@@ -855,86 +884,82 @@ static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr)
855} 884}
856 885
857 886
858/* ieee80211.c */
859int ieee80211_hw_config(struct ieee80211_local *local); 887int ieee80211_hw_config(struct ieee80211_local *local);
860int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed); 888int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed);
861void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx); 889void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx);
862u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht, 890u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht,
863 struct ieee80211_ht_info *req_ht_cap, 891 struct ieee80211_ht_info *req_ht_cap,
864 struct ieee80211_ht_bss_info *req_bss_cap); 892 struct ieee80211_ht_bss_info *req_bss_cap);
893void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
894 u32 changed);
895void ieee80211_configure_filter(struct ieee80211_local *local);
865 896
866/* ieee80211_ioctl.c */ 897/* wireless extensions */
867extern const struct iw_handler_def ieee80211_iw_handler_def; 898extern const struct iw_handler_def ieee80211_iw_handler_def;
868int ieee80211_set_freq(struct net_device *dev, int freq);
869 899
870/* ieee80211_sta.c */ 900/* STA/IBSS code */
871void ieee80211_sta_timer(unsigned long data); 901void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata);
872void ieee80211_sta_work(struct work_struct *work); 902void ieee80211_scan_work(struct work_struct *work);
873void ieee80211_sta_scan_work(struct work_struct *work); 903void ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
874void ieee80211_sta_rx_mgmt(struct net_device *dev, struct sk_buff *skb,
875 struct ieee80211_rx_status *rx_status); 904 struct ieee80211_rx_status *rx_status);
876int ieee80211_sta_set_ssid(struct net_device *dev, char *ssid, size_t len); 905int ieee80211_sta_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len);
877int ieee80211_sta_get_ssid(struct net_device *dev, char *ssid, size_t *len); 906int ieee80211_sta_get_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t *len);
878int ieee80211_sta_set_bssid(struct net_device *dev, u8 *bssid); 907int ieee80211_sta_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid);
879int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len); 908void ieee80211_sta_req_auth(struct ieee80211_sub_if_data *sdata,
880void ieee80211_sta_req_auth(struct net_device *dev,
881 struct ieee80211_if_sta *ifsta); 909 struct ieee80211_if_sta *ifsta);
882int ieee80211_sta_scan_results(struct net_device *dev, 910struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
883 struct iw_request_info *info,
884 char *buf, size_t len);
885ieee80211_rx_result ieee80211_sta_rx_scan(
886 struct net_device *dev, struct sk_buff *skb,
887 struct ieee80211_rx_status *rx_status);
888void ieee80211_rx_bss_list_init(struct ieee80211_local *local);
889void ieee80211_rx_bss_list_deinit(struct ieee80211_local *local);
890int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len);
891struct sta_info *ieee80211_ibss_add_sta(struct net_device *dev,
892 struct sk_buff *skb, u8 *bssid, 911 struct sk_buff *skb, u8 *bssid,
893 u8 *addr, u64 supp_rates); 912 u8 *addr, u64 supp_rates);
894int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason); 913int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason);
895int ieee80211_sta_disassociate(struct net_device *dev, u16 reason); 914int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason);
896void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, 915u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata);
897 u32 changed);
898u32 ieee80211_reset_erp_info(struct net_device *dev);
899int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie,
900 struct ieee80211_ht_info *ht_info);
901int ieee80211_ht_addt_info_ie_to_ht_bss_info(
902 struct ieee80211_ht_addt_info *ht_add_info_ie,
903 struct ieee80211_ht_bss_info *bss_info);
904void ieee80211_send_addba_request(struct net_device *dev, const u8 *da,
905 u16 tid, u8 dialog_token, u16 start_seq_num,
906 u16 agg_size, u16 timeout);
907void ieee80211_send_delba(struct net_device *dev, const u8 *da, u16 tid,
908 u16 initiator, u16 reason_code);
909void ieee80211_send_bar(struct net_device *dev, u8 *ra, u16 tid, u16 ssn);
910
911void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *da,
912 u16 tid, u16 initiator, u16 reason);
913void sta_addba_resp_timer_expired(unsigned long data);
914void ieee80211_sta_tear_down_BA_sessions(struct net_device *dev, u8 *addr);
915u64 ieee80211_sta_get_rates(struct ieee80211_local *local, 916u64 ieee80211_sta_get_rates(struct ieee80211_local *local,
916 struct ieee802_11_elems *elems, 917 struct ieee802_11_elems *elems,
917 enum ieee80211_band band); 918 enum ieee80211_band band);
918void ieee80211_sta_tx(struct net_device *dev, struct sk_buff *skb, 919void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
919 int encrypt); 920 u8 *ssid, size_t ssid_len);
920void ieee802_11_parse_elems(u8 *start, size_t len, 921
921 struct ieee802_11_elems *elems); 922/* scan/BSS handling */
922 923int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
923#ifdef CONFIG_MAC80211_MESH 924 u8 *ssid, size_t ssid_len);
924void ieee80211_start_mesh(struct net_device *dev); 925int ieee80211_scan_results(struct ieee80211_local *local,
925#else 926 struct iw_request_info *info,
926static inline void ieee80211_start_mesh(struct net_device *dev) 927 char *buf, size_t len);
927{} 928ieee80211_rx_result
928#endif 929ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata,
930 struct sk_buff *skb,
931 struct ieee80211_rx_status *rx_status);
932void ieee80211_rx_bss_list_init(struct ieee80211_local *local);
933void ieee80211_rx_bss_list_deinit(struct ieee80211_local *local);
934int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata,
935 char *ie, size_t len);
936
937void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local);
938int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata,
939 u8 *ssid, size_t ssid_len);
940struct ieee80211_bss *
941ieee80211_bss_info_update(struct ieee80211_local *local,
942 struct ieee80211_rx_status *rx_status,
943 struct ieee80211_mgmt *mgmt,
944 size_t len,
945 struct ieee802_11_elems *elems,
946 int freq, bool beacon);
947struct ieee80211_bss *
948ieee80211_rx_bss_add(struct ieee80211_local *local, u8 *bssid, int freq,
949 u8 *ssid, u8 ssid_len);
950struct ieee80211_bss *
951ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
952 u8 *ssid, u8 ssid_len);
953void ieee80211_rx_bss_put(struct ieee80211_local *local,
954 struct ieee80211_bss *bss);
929 955
930/* interface handling */ 956/* interface handling */
931void ieee80211_if_setup(struct net_device *dev);
932int ieee80211_if_add(struct ieee80211_local *local, const char *name, 957int ieee80211_if_add(struct ieee80211_local *local, const char *name,
933 struct net_device **new_dev, enum ieee80211_if_types type, 958 struct net_device **new_dev, enum nl80211_iftype type,
934 struct vif_params *params); 959 struct vif_params *params);
935int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, 960int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
936 enum ieee80211_if_types type); 961 enum nl80211_iftype type);
937void ieee80211_if_remove(struct net_device *dev); 962void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata);
938void ieee80211_remove_interfaces(struct ieee80211_local *local); 963void ieee80211_remove_interfaces(struct ieee80211_local *local);
939 964
940/* tx handling */ 965/* tx handling */
@@ -944,16 +969,52 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev);
944int ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev); 969int ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev);
945int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); 970int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev);
946 971
972/* HT */
973int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie,
974 struct ieee80211_ht_info *ht_info);
975int ieee80211_ht_addt_info_ie_to_ht_bss_info(
976 struct ieee80211_ht_addt_info *ht_add_info_ie,
977 struct ieee80211_ht_bss_info *bss_info);
978void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn);
979
980void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *da,
981 u16 tid, u16 initiator, u16 reason);
982void ieee80211_sta_tear_down_BA_sessions(struct ieee80211_sub_if_data *sdata, u8 *addr);
983void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
984 struct sta_info *sta,
985 struct ieee80211_mgmt *mgmt, size_t len);
986void ieee80211_process_addba_resp(struct ieee80211_local *local,
987 struct sta_info *sta,
988 struct ieee80211_mgmt *mgmt,
989 size_t len);
990void ieee80211_process_addba_request(struct ieee80211_local *local,
991 struct sta_info *sta,
992 struct ieee80211_mgmt *mgmt,
993 size_t len);
994
995/* Spectrum management */
996void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
997 struct ieee80211_mgmt *mgmt,
998 size_t len);
999
947/* utility functions/constants */ 1000/* utility functions/constants */
948extern void *mac80211_wiphy_privid; /* for wiphy privid */ 1001extern void *mac80211_wiphy_privid; /* for wiphy privid */
949extern const unsigned char rfc1042_header[6]; 1002extern const unsigned char rfc1042_header[6];
950extern const unsigned char bridge_tunnel_header[6]; 1003extern const unsigned char bridge_tunnel_header[6];
951u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, 1004u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,
952 enum ieee80211_if_types type); 1005 enum nl80211_iftype type);
953int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, 1006int ieee80211_frame_duration(struct ieee80211_local *local, size_t len,
954 int rate, int erp, int short_preamble); 1007 int rate, int erp, int short_preamble);
955void mac80211_ev_michael_mic_failure(struct net_device *dev, int keyidx, 1008void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx,
956 struct ieee80211_hdr *hdr); 1009 struct ieee80211_hdr *hdr);
1010void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata);
1011void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
1012 int encrypt);
1013void ieee802_11_parse_elems(u8 *start, size_t len,
1014 struct ieee802_11_elems *elems);
1015int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freq);
1016u64 ieee80211_mandatory_rates(struct ieee80211_local *local,
1017 enum ieee80211_band band);
957 1018
958#ifdef CONFIG_MAC80211_NOINLINE 1019#ifdef CONFIG_MAC80211_NOINLINE
959#define debug_noinline noinline 1020#define debug_noinline noinline
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 610ed1d9893a..8336fee68d3e 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1,4 +1,6 @@
1/* 1/*
2 * Interface handling (except master interface)
3 *
2 * Copyright 2002-2005, Instant802 Networks, Inc. 4 * Copyright 2002-2005, Instant802 Networks, Inc.
3 * Copyright 2005-2006, Devicescape Software, Inc. 5 * Copyright 2005-2006, Devicescape Software, Inc.
4 * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz> 6 * Copyright (c) 2006 Jiri Benc <jbenc@suse.cz>
@@ -17,7 +19,539 @@
17#include "sta_info.h" 19#include "sta_info.h"
18#include "debugfs_netdev.h" 20#include "debugfs_netdev.h"
19#include "mesh.h" 21#include "mesh.h"
22#include "led.h"
23
24static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
25{
26 int meshhdrlen;
27 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
28
29 meshhdrlen = (sdata->vif.type == NL80211_IFTYPE_MESH_POINT) ? 5 : 0;
30
31 /* FIX: what would be proper limits for MTU?
32 * This interface uses 802.3 frames. */
33 if (new_mtu < 256 ||
34 new_mtu > IEEE80211_MAX_DATA_LEN - 24 - 6 - meshhdrlen) {
35 return -EINVAL;
36 }
37
38#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
39 printk(KERN_DEBUG "%s: setting MTU %d\n", dev->name, new_mtu);
40#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
41 dev->mtu = new_mtu;
42 return 0;
43}
44
45static inline int identical_mac_addr_allowed(int type1, int type2)
46{
47 return type1 == NL80211_IFTYPE_MONITOR ||
48 type2 == NL80211_IFTYPE_MONITOR ||
49 (type1 == NL80211_IFTYPE_AP && type2 == NL80211_IFTYPE_WDS) ||
50 (type1 == NL80211_IFTYPE_WDS &&
51 (type2 == NL80211_IFTYPE_WDS ||
52 type2 == NL80211_IFTYPE_AP)) ||
53 (type1 == NL80211_IFTYPE_AP && type2 == NL80211_IFTYPE_AP_VLAN) ||
54 (type1 == NL80211_IFTYPE_AP_VLAN &&
55 (type2 == NL80211_IFTYPE_AP ||
56 type2 == NL80211_IFTYPE_AP_VLAN));
57}
58
59static int ieee80211_open(struct net_device *dev)
60{
61 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
62 struct ieee80211_sub_if_data *nsdata;
63 struct ieee80211_local *local = sdata->local;
64 struct sta_info *sta;
65 struct ieee80211_if_init_conf conf;
66 u32 changed = 0;
67 int res;
68 bool need_hw_reconfig = 0;
69 u8 null_addr[ETH_ALEN] = {0};
70
71 /* fail early if user set an invalid address */
72 if (compare_ether_addr(dev->dev_addr, null_addr) &&
73 !is_valid_ether_addr(dev->dev_addr))
74 return -EADDRNOTAVAIL;
75
76 /* we hold the RTNL here so can safely walk the list */
77 list_for_each_entry(nsdata, &local->interfaces, list) {
78 struct net_device *ndev = nsdata->dev;
79
80 if (ndev != dev && netif_running(ndev)) {
81 /*
82 * Allow only a single IBSS interface to be up at any
83 * time. This is restricted because beacon distribution
84 * cannot work properly if both are in the same IBSS.
85 *
86 * To remove this restriction we'd have to disallow them
87 * from setting the same SSID on different IBSS interfaces
88 * belonging to the same hardware. Then, however, we're
89 * faced with having to adopt two different TSF timers...
90 */
91 if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
92 nsdata->vif.type == NL80211_IFTYPE_ADHOC)
93 return -EBUSY;
94
95 /*
96 * The remaining checks are only performed for interfaces
97 * with the same MAC address.
98 */
99 if (compare_ether_addr(dev->dev_addr, ndev->dev_addr))
100 continue;
101
102 /*
103 * check whether it may have the same address
104 */
105 if (!identical_mac_addr_allowed(sdata->vif.type,
106 nsdata->vif.type))
107 return -ENOTUNIQ;
108
109 /*
110 * can only add VLANs to enabled APs
111 */
112 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
113 nsdata->vif.type == NL80211_IFTYPE_AP)
114 sdata->bss = &nsdata->u.ap;
115 }
116 }
117
118 switch (sdata->vif.type) {
119 case NL80211_IFTYPE_WDS:
120 if (!is_valid_ether_addr(sdata->u.wds.remote_addr))
121 return -ENOLINK;
122 break;
123 case NL80211_IFTYPE_AP_VLAN:
124 if (!sdata->bss)
125 return -ENOLINK;
126 list_add(&sdata->u.vlan.list, &sdata->bss->vlans);
127 break;
128 case NL80211_IFTYPE_AP:
129 sdata->bss = &sdata->u.ap;
130 break;
131 case NL80211_IFTYPE_MESH_POINT:
132 if (!ieee80211_vif_is_mesh(&sdata->vif))
133 break;
134 /* mesh ifaces must set allmulti to forward mcast traffic */
135 atomic_inc(&local->iff_allmultis);
136 break;
137 case NL80211_IFTYPE_STATION:
138 case NL80211_IFTYPE_MONITOR:
139 case NL80211_IFTYPE_ADHOC:
140 /* no special treatment */
141 break;
142 case NL80211_IFTYPE_UNSPECIFIED:
143 case __NL80211_IFTYPE_AFTER_LAST:
144 /* cannot happen */
145 WARN_ON(1);
146 break;
147 }
148
149 if (local->open_count == 0) {
150 res = 0;
151 if (local->ops->start)
152 res = local->ops->start(local_to_hw(local));
153 if (res)
154 goto err_del_bss;
155 need_hw_reconfig = 1;
156 ieee80211_led_radio(local, local->hw.conf.radio_enabled);
157 }
158
159 /*
160 * Check all interfaces and copy the hopefully now-present
161 * MAC address to those that have the special null one.
162 */
163 list_for_each_entry(nsdata, &local->interfaces, list) {
164 struct net_device *ndev = nsdata->dev;
165
166 /*
167 * No need to check netif_running since we do not allow
168 * it to start up with this invalid address.
169 */
170 if (compare_ether_addr(null_addr, ndev->dev_addr) == 0)
171 memcpy(ndev->dev_addr,
172 local->hw.wiphy->perm_addr,
173 ETH_ALEN);
174 }
175
176 if (compare_ether_addr(null_addr, local->mdev->dev_addr) == 0)
177 memcpy(local->mdev->dev_addr, local->hw.wiphy->perm_addr,
178 ETH_ALEN);
179
180 /*
181 * Validate the MAC address for this device.
182 */
183 if (!is_valid_ether_addr(dev->dev_addr)) {
184 if (!local->open_count && local->ops->stop)
185 local->ops->stop(local_to_hw(local));
186 return -EADDRNOTAVAIL;
187 }
188
189 switch (sdata->vif.type) {
190 case NL80211_IFTYPE_AP_VLAN:
191 /* no need to tell driver */
192 break;
193 case NL80211_IFTYPE_MONITOR:
194 if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) {
195 local->cooked_mntrs++;
196 break;
197 }
198
199 /* must be before the call to ieee80211_configure_filter */
200 local->monitors++;
201 if (local->monitors == 1)
202 local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP;
203
204 if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL)
205 local->fif_fcsfail++;
206 if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL)
207 local->fif_plcpfail++;
208 if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL)
209 local->fif_control++;
210 if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
211 local->fif_other_bss++;
212
213 netif_addr_lock_bh(local->mdev);
214 ieee80211_configure_filter(local);
215 netif_addr_unlock_bh(local->mdev);
216 break;
217 case NL80211_IFTYPE_STATION:
218 case NL80211_IFTYPE_ADHOC:
219 sdata->u.sta.flags &= ~IEEE80211_STA_PREV_BSSID_SET;
220 /* fall through */
221 default:
222 conf.vif = &sdata->vif;
223 conf.type = sdata->vif.type;
224 conf.mac_addr = dev->dev_addr;
225 res = local->ops->add_interface(local_to_hw(local), &conf);
226 if (res)
227 goto err_stop;
228
229 if (ieee80211_vif_is_mesh(&sdata->vif))
230 ieee80211_start_mesh(sdata);
231 changed |= ieee80211_reset_erp_info(sdata);
232 ieee80211_bss_info_change_notify(sdata, changed);
233 ieee80211_enable_keys(sdata);
234
235 if (sdata->vif.type == NL80211_IFTYPE_STATION &&
236 !(sdata->flags & IEEE80211_SDATA_USERSPACE_MLME))
237 netif_carrier_off(dev);
238 else
239 netif_carrier_on(dev);
240 }
241
242 if (sdata->vif.type == NL80211_IFTYPE_WDS) {
243 /* Create STA entry for the WDS peer */
244 sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
245 GFP_KERNEL);
246 if (!sta) {
247 res = -ENOMEM;
248 goto err_del_interface;
249 }
250
251 /* no locking required since STA is not live yet */
252 sta->flags |= WLAN_STA_AUTHORIZED;
253
254 res = sta_info_insert(sta);
255 if (res) {
256 /* STA has been freed */
257 goto err_del_interface;
258 }
259 }
260
261 if (local->open_count == 0) {
262 res = dev_open(local->mdev);
263 WARN_ON(res);
264 if (res)
265 goto err_del_interface;
266 tasklet_enable(&local->tx_pending_tasklet);
267 tasklet_enable(&local->tasklet);
268 }
269
270 /*
271 * set_multicast_list will be invoked by the networking core
272 * which will check whether any increments here were done in
273 * error and sync them down to the hardware as filter flags.
274 */
275 if (sdata->flags & IEEE80211_SDATA_ALLMULTI)
276 atomic_inc(&local->iff_allmultis);
277
278 if (sdata->flags & IEEE80211_SDATA_PROMISC)
279 atomic_inc(&local->iff_promiscs);
280
281 local->open_count++;
282 if (need_hw_reconfig) {
283 ieee80211_hw_config(local);
284 /*
285 * set default queue parameters so drivers don't
286 * need to initialise the hardware if the hardware
287 * doesn't start up with sane defaults
288 */
289 ieee80211_set_wmm_default(sdata);
290 }
291
292 /*
293 * ieee80211_sta_work is disabled while network interface
294 * is down. Therefore, some configuration changes may not
295 * yet be effective. Trigger execution of ieee80211_sta_work
296 * to fix this.
297 */
298 if (sdata->vif.type == NL80211_IFTYPE_STATION ||
299 sdata->vif.type == NL80211_IFTYPE_ADHOC) {
300 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
301 queue_work(local->hw.workqueue, &ifsta->work);
302 }
303
304 netif_tx_start_all_queues(dev);
305
306 return 0;
307 err_del_interface:
308 local->ops->remove_interface(local_to_hw(local), &conf);
309 err_stop:
310 if (!local->open_count && local->ops->stop)
311 local->ops->stop(local_to_hw(local));
312 err_del_bss:
313 sdata->bss = NULL;
314 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
315 list_del(&sdata->u.vlan.list);
316 return res;
317}
318
319static int ieee80211_stop(struct net_device *dev)
320{
321 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
322 struct ieee80211_local *local = sdata->local;
323 struct ieee80211_if_init_conf conf;
324 struct sta_info *sta;
325
326 /*
327 * Stop TX on this interface first.
328 */
329 netif_tx_stop_all_queues(dev);
330
331 /*
332 * Now delete all active aggregation sessions.
333 */
334 rcu_read_lock();
335
336 list_for_each_entry_rcu(sta, &local->sta_list, list) {
337 if (sta->sdata == sdata)
338 ieee80211_sta_tear_down_BA_sessions(sdata,
339 sta->sta.addr);
340 }
341
342 rcu_read_unlock();
343
344 /*
345 * Remove all stations associated with this interface.
346 *
347 * This must be done before calling ops->remove_interface()
348 * because otherwise we can later invoke ops->sta_notify()
349 * whenever the STAs are removed, and that invalidates driver
350 * assumptions about always getting a vif pointer that is valid
351 * (because if we remove a STA after ops->remove_interface()
352 * the driver will have removed the vif info already!)
353 *
354 * We could relax this and only unlink the stations from the
355 * hash table and list but keep them on a per-sdata list that
356 * will be inserted back again when the interface is brought
357 * up again, but I don't currently see a use case for that,
358 * except with WDS which gets a STA entry created when it is
359 * brought up.
360 */
361 sta_info_flush(local, sdata);
362
363 /*
364 * Don't count this interface for promisc/allmulti while it
365 * is down. dev_mc_unsync() will invoke set_multicast_list
366 * on the master interface which will sync these down to the
367 * hardware as filter flags.
368 */
369 if (sdata->flags & IEEE80211_SDATA_ALLMULTI)
370 atomic_dec(&local->iff_allmultis);
371
372 if (sdata->flags & IEEE80211_SDATA_PROMISC)
373 atomic_dec(&local->iff_promiscs);
374
375 dev_mc_unsync(local->mdev, dev);
376
377 /* APs need special treatment */
378 if (sdata->vif.type == NL80211_IFTYPE_AP) {
379 struct ieee80211_sub_if_data *vlan, *tmp;
380 struct beacon_data *old_beacon = sdata->u.ap.beacon;
381
382 /* remove beacon */
383 rcu_assign_pointer(sdata->u.ap.beacon, NULL);
384 synchronize_rcu();
385 kfree(old_beacon);
386
387 /* down all dependent devices, that is VLANs */
388 list_for_each_entry_safe(vlan, tmp, &sdata->u.ap.vlans,
389 u.vlan.list)
390 dev_close(vlan->dev);
391 WARN_ON(!list_empty(&sdata->u.ap.vlans));
392 }
393
394 local->open_count--;
395
396 switch (sdata->vif.type) {
397 case NL80211_IFTYPE_AP_VLAN:
398 list_del(&sdata->u.vlan.list);
399 /* no need to tell driver */
400 break;
401 case NL80211_IFTYPE_MONITOR:
402 if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) {
403 local->cooked_mntrs--;
404 break;
405 }
406
407 local->monitors--;
408 if (local->monitors == 0)
409 local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP;
410
411 if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL)
412 local->fif_fcsfail--;
413 if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL)
414 local->fif_plcpfail--;
415 if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL)
416 local->fif_control--;
417 if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
418 local->fif_other_bss--;
419
420 netif_addr_lock_bh(local->mdev);
421 ieee80211_configure_filter(local);
422 netif_addr_unlock_bh(local->mdev);
423 break;
424 case NL80211_IFTYPE_STATION:
425 case NL80211_IFTYPE_ADHOC:
426 sdata->u.sta.state = IEEE80211_STA_MLME_DISABLED;
427 memset(sdata->u.sta.bssid, 0, ETH_ALEN);
428 del_timer_sync(&sdata->u.sta.timer);
429 /*
430 * If the timer fired while we waited for it, it will have
431 * requeued the work. Now the work will be running again
432 * but will not rearm the timer again because it checks
433 * whether the interface is running, which, at this point,
434 * it no longer is.
435 */
436 cancel_work_sync(&sdata->u.sta.work);
437 /*
438 * When we get here, the interface is marked down.
439 * Call synchronize_rcu() to wait for the RX path
440 * should it be using the interface and enqueuing
441 * frames at this very time on another CPU.
442 */
443 synchronize_rcu();
444 skb_queue_purge(&sdata->u.sta.skb_queue);
445
446 sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED;
447 kfree(sdata->u.sta.extra_ie);
448 sdata->u.sta.extra_ie = NULL;
449 sdata->u.sta.extra_ie_len = 0;
450 /* fall through */
451 case NL80211_IFTYPE_MESH_POINT:
452 if (ieee80211_vif_is_mesh(&sdata->vif)) {
453 /* allmulti is always set on mesh ifaces */
454 atomic_dec(&local->iff_allmultis);
455 ieee80211_stop_mesh(sdata);
456 }
457 /* fall through */
458 default:
459 if (local->scan_sdata == sdata) {
460 if (!local->ops->hw_scan)
461 cancel_delayed_work_sync(&local->scan_work);
462 /*
463 * The software scan can no longer run now, so we can
464 * clear out the scan_sdata reference. However, the
465 * hardware scan may still be running. The complete
466 * function must be prepared to handle a NULL value.
467 */
468 local->scan_sdata = NULL;
469 /*
470 * The memory barrier guarantees that another CPU
471 * that is hardware-scanning will now see the fact
472 * that this interface is gone.
473 */
474 smp_mb();
475 /*
476 * If software scanning, complete the scan but since
477 * the scan_sdata is NULL already don't send out a
478 * scan event to userspace -- the scan is incomplete.
479 */
480 if (local->sw_scanning)
481 ieee80211_scan_completed(&local->hw);
482 }
483
484 conf.vif = &sdata->vif;
485 conf.type = sdata->vif.type;
486 conf.mac_addr = dev->dev_addr;
487 /* disable all keys for as long as this netdev is down */
488 ieee80211_disable_keys(sdata);
489 local->ops->remove_interface(local_to_hw(local), &conf);
490 }
491
492 sdata->bss = NULL;
493
494 if (local->open_count == 0) {
495 if (netif_running(local->mdev))
496 dev_close(local->mdev);
497
498 if (local->ops->stop)
499 local->ops->stop(local_to_hw(local));
500
501 ieee80211_led_radio(local, 0);
502
503 flush_workqueue(local->hw.workqueue);
504
505 tasklet_disable(&local->tx_pending_tasklet);
506 tasklet_disable(&local->tasklet);
507 }
508
509 return 0;
510}
511
512static void ieee80211_set_multicast_list(struct net_device *dev)
513{
514 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
515 struct ieee80211_local *local = sdata->local;
516 int allmulti, promisc, sdata_allmulti, sdata_promisc;
517
518 allmulti = !!(dev->flags & IFF_ALLMULTI);
519 promisc = !!(dev->flags & IFF_PROMISC);
520 sdata_allmulti = !!(sdata->flags & IEEE80211_SDATA_ALLMULTI);
521 sdata_promisc = !!(sdata->flags & IEEE80211_SDATA_PROMISC);
522
523 if (allmulti != sdata_allmulti) {
524 if (dev->flags & IFF_ALLMULTI)
525 atomic_inc(&local->iff_allmultis);
526 else
527 atomic_dec(&local->iff_allmultis);
528 sdata->flags ^= IEEE80211_SDATA_ALLMULTI;
529 }
530
531 if (promisc != sdata_promisc) {
532 if (dev->flags & IFF_PROMISC)
533 atomic_inc(&local->iff_promiscs);
534 else
535 atomic_dec(&local->iff_promiscs);
536 sdata->flags ^= IEEE80211_SDATA_PROMISC;
537 }
538
539 dev_mc_sync(local->mdev, dev);
540}
20 541
542static void ieee80211_if_setup(struct net_device *dev)
543{
544 ether_setup(dev);
545 dev->hard_start_xmit = ieee80211_subif_start_xmit;
546 dev->wireless_handlers = &ieee80211_iw_handler_def;
547 dev->set_multicast_list = ieee80211_set_multicast_list;
548 dev->change_mtu = ieee80211_change_mtu;
549 dev->open = ieee80211_open;
550 dev->stop = ieee80211_stop;
551 dev->destructor = free_netdev;
552 /* we will validate the address ourselves in ->open */
553 dev->validate_addr = NULL;
554}
21/* 555/*
22 * Called when the netdev is removed or, by the code below, before 556 * Called when the netdev is removed or, by the code below, before
23 * the interface type changes. 557 * the interface type changes.
@@ -31,17 +565,17 @@ static void ieee80211_teardown_sdata(struct net_device *dev)
31 int flushed; 565 int flushed;
32 int i; 566 int i;
33 567
34 ieee80211_debugfs_remove_netdev(sdata);
35
36 /* free extra data */ 568 /* free extra data */
37 ieee80211_free_keys(sdata); 569 ieee80211_free_keys(sdata);
38 570
571 ieee80211_debugfs_remove_netdev(sdata);
572
39 for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) 573 for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++)
40 __skb_queue_purge(&sdata->fragments[i].skb_list); 574 __skb_queue_purge(&sdata->fragments[i].skb_list);
41 sdata->fragment_next = 0; 575 sdata->fragment_next = 0;
42 576
43 switch (sdata->vif.type) { 577 switch (sdata->vif.type) {
44 case IEEE80211_IF_TYPE_AP: 578 case NL80211_IFTYPE_AP:
45 beacon = sdata->u.ap.beacon; 579 beacon = sdata->u.ap.beacon;
46 rcu_assign_pointer(sdata->u.ap.beacon, NULL); 580 rcu_assign_pointer(sdata->u.ap.beacon, NULL);
47 synchronize_rcu(); 581 synchronize_rcu();
@@ -53,23 +587,23 @@ static void ieee80211_teardown_sdata(struct net_device *dev)
53 } 587 }
54 588
55 break; 589 break;
56 case IEEE80211_IF_TYPE_MESH_POINT: 590 case NL80211_IFTYPE_MESH_POINT:
57 /* Allow compiler to elide mesh_rmc_free call. */
58 if (ieee80211_vif_is_mesh(&sdata->vif)) 591 if (ieee80211_vif_is_mesh(&sdata->vif))
59 mesh_rmc_free(dev); 592 mesh_rmc_free(sdata);
60 /* fall through */ 593 break;
61 case IEEE80211_IF_TYPE_STA: 594 case NL80211_IFTYPE_STATION:
62 case IEEE80211_IF_TYPE_IBSS: 595 case NL80211_IFTYPE_ADHOC:
63 kfree(sdata->u.sta.extra_ie); 596 kfree(sdata->u.sta.extra_ie);
64 kfree(sdata->u.sta.assocreq_ies); 597 kfree(sdata->u.sta.assocreq_ies);
65 kfree(sdata->u.sta.assocresp_ies); 598 kfree(sdata->u.sta.assocresp_ies);
66 kfree_skb(sdata->u.sta.probe_resp); 599 kfree_skb(sdata->u.sta.probe_resp);
67 break; 600 break;
68 case IEEE80211_IF_TYPE_WDS: 601 case NL80211_IFTYPE_WDS:
69 case IEEE80211_IF_TYPE_VLAN: 602 case NL80211_IFTYPE_AP_VLAN:
70 case IEEE80211_IF_TYPE_MNTR: 603 case NL80211_IFTYPE_MONITOR:
71 break; 604 break;
72 case IEEE80211_IF_TYPE_INVALID: 605 case NL80211_IFTYPE_UNSPECIFIED:
606 case __NL80211_IFTYPE_AFTER_LAST:
73 BUG(); 607 BUG();
74 break; 608 break;
75 } 609 }
@@ -82,55 +616,43 @@ static void ieee80211_teardown_sdata(struct net_device *dev)
82 * Helper function to initialise an interface to a specific type. 616 * Helper function to initialise an interface to a specific type.
83 */ 617 */
84static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, 618static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
85 enum ieee80211_if_types type) 619 enum nl80211_iftype type)
86{ 620{
87 struct ieee80211_if_sta *ifsta;
88
89 /* clear type-dependent union */ 621 /* clear type-dependent union */
90 memset(&sdata->u, 0, sizeof(sdata->u)); 622 memset(&sdata->u, 0, sizeof(sdata->u));
91 623
92 /* and set some type-dependent values */ 624 /* and set some type-dependent values */
93 sdata->vif.type = type; 625 sdata->vif.type = type;
626 sdata->dev->hard_start_xmit = ieee80211_subif_start_xmit;
627 sdata->wdev.iftype = type;
94 628
95 /* only monitor differs */ 629 /* only monitor differs */
96 sdata->dev->type = ARPHRD_ETHER; 630 sdata->dev->type = ARPHRD_ETHER;
97 631
98 switch (type) { 632 switch (type) {
99 case IEEE80211_IF_TYPE_AP: 633 case NL80211_IFTYPE_AP:
100 skb_queue_head_init(&sdata->u.ap.ps_bc_buf); 634 skb_queue_head_init(&sdata->u.ap.ps_bc_buf);
101 INIT_LIST_HEAD(&sdata->u.ap.vlans); 635 INIT_LIST_HEAD(&sdata->u.ap.vlans);
102 break; 636 break;
103 case IEEE80211_IF_TYPE_MESH_POINT: 637 case NL80211_IFTYPE_STATION:
104 case IEEE80211_IF_TYPE_STA: 638 case NL80211_IFTYPE_ADHOC:
105 case IEEE80211_IF_TYPE_IBSS: 639 ieee80211_sta_setup_sdata(sdata);
106 ifsta = &sdata->u.sta; 640 break;
107 INIT_WORK(&ifsta->work, ieee80211_sta_work); 641 case NL80211_IFTYPE_MESH_POINT:
108 setup_timer(&ifsta->timer, ieee80211_sta_timer,
109 (unsigned long) sdata);
110 skb_queue_head_init(&ifsta->skb_queue);
111
112 ifsta->capab = WLAN_CAPABILITY_ESS;
113 ifsta->auth_algs = IEEE80211_AUTH_ALG_OPEN |
114 IEEE80211_AUTH_ALG_SHARED_KEY;
115 ifsta->flags |= IEEE80211_STA_CREATE_IBSS |
116 IEEE80211_STA_AUTO_BSSID_SEL |
117 IEEE80211_STA_AUTO_CHANNEL_SEL;
118 if (ieee80211_num_regular_queues(&sdata->local->hw) >= 4)
119 ifsta->flags |= IEEE80211_STA_WMM_ENABLED;
120
121 if (ieee80211_vif_is_mesh(&sdata->vif)) 642 if (ieee80211_vif_is_mesh(&sdata->vif))
122 ieee80211_mesh_init_sdata(sdata); 643 ieee80211_mesh_init_sdata(sdata);
123 break; 644 break;
124 case IEEE80211_IF_TYPE_MNTR: 645 case NL80211_IFTYPE_MONITOR:
125 sdata->dev->type = ARPHRD_IEEE80211_RADIOTAP; 646 sdata->dev->type = ARPHRD_IEEE80211_RADIOTAP;
126 sdata->dev->hard_start_xmit = ieee80211_monitor_start_xmit; 647 sdata->dev->hard_start_xmit = ieee80211_monitor_start_xmit;
127 sdata->u.mntr_flags = MONITOR_FLAG_CONTROL | 648 sdata->u.mntr_flags = MONITOR_FLAG_CONTROL |
128 MONITOR_FLAG_OTHER_BSS; 649 MONITOR_FLAG_OTHER_BSS;
129 break; 650 break;
130 case IEEE80211_IF_TYPE_WDS: 651 case NL80211_IFTYPE_WDS:
131 case IEEE80211_IF_TYPE_VLAN: 652 case NL80211_IFTYPE_AP_VLAN:
132 break; 653 break;
133 case IEEE80211_IF_TYPE_INVALID: 654 case NL80211_IFTYPE_UNSPECIFIED:
655 case __NL80211_IFTYPE_AFTER_LAST:
134 BUG(); 656 BUG();
135 break; 657 break;
136 } 658 }
@@ -139,7 +661,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
139} 661}
140 662
141int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, 663int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
142 enum ieee80211_if_types type) 664 enum nl80211_iftype type)
143{ 665{
144 ASSERT_RTNL(); 666 ASSERT_RTNL();
145 667
@@ -160,14 +682,16 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
160 ieee80211_setup_sdata(sdata, type); 682 ieee80211_setup_sdata(sdata, type);
161 683
162 /* reset some values that shouldn't be kept across type changes */ 684 /* reset some values that shouldn't be kept across type changes */
163 sdata->basic_rates = 0; 685 sdata->bss_conf.basic_rates =
686 ieee80211_mandatory_rates(sdata->local,
687 sdata->local->hw.conf.channel->band);
164 sdata->drop_unencrypted = 0; 688 sdata->drop_unencrypted = 0;
165 689
166 return 0; 690 return 0;
167} 691}
168 692
169int ieee80211_if_add(struct ieee80211_local *local, const char *name, 693int ieee80211_if_add(struct ieee80211_local *local, const char *name,
170 struct net_device **new_dev, enum ieee80211_if_types type, 694 struct net_device **new_dev, enum nl80211_iftype type,
171 struct vif_params *params) 695 struct vif_params *params)
172{ 696{
173 struct net_device *ndev; 697 struct net_device *ndev;
@@ -225,9 +749,9 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
225 749
226 if (ieee80211_vif_is_mesh(&sdata->vif) && 750 if (ieee80211_vif_is_mesh(&sdata->vif) &&
227 params && params->mesh_id_len) 751 params && params->mesh_id_len)
228 ieee80211_if_sta_set_mesh_id(&sdata->u.sta, 752 ieee80211_sdata_set_mesh_id(sdata,
229 params->mesh_id_len, 753 params->mesh_id_len,
230 params->mesh_id); 754 params->mesh_id);
231 755
232 list_add_tail_rcu(&sdata->list, &local->interfaces); 756 list_add_tail_rcu(&sdata->list, &local->interfaces);
233 757
@@ -241,15 +765,13 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
241 return ret; 765 return ret;
242} 766}
243 767
244void ieee80211_if_remove(struct net_device *dev) 768void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata)
245{ 769{
246 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
247
248 ASSERT_RTNL(); 770 ASSERT_RTNL();
249 771
250 list_del_rcu(&sdata->list); 772 list_del_rcu(&sdata->list);
251 synchronize_rcu(); 773 synchronize_rcu();
252 unregister_netdevice(dev); 774 unregister_netdevice(sdata->dev);
253} 775}
254 776
255/* 777/*
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index 6597c779e35a..a5b06fe71980 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -118,12 +118,12 @@ static const u8 *get_mac_for_key(struct ieee80211_key *key)
118 * address to indicate a transmit-only key. 118 * address to indicate a transmit-only key.
119 */ 119 */
120 if (key->conf.alg != ALG_WEP && 120 if (key->conf.alg != ALG_WEP &&
121 (key->sdata->vif.type == IEEE80211_IF_TYPE_AP || 121 (key->sdata->vif.type == NL80211_IFTYPE_AP ||
122 key->sdata->vif.type == IEEE80211_IF_TYPE_VLAN)) 122 key->sdata->vif.type == NL80211_IFTYPE_AP_VLAN))
123 addr = zero_addr; 123 addr = zero_addr;
124 124
125 if (key->sta) 125 if (key->sta)
126 addr = key->sta->addr; 126 addr = key->sta->sta.addr;
127 127
128 return addr; 128 return addr;
129} 129}
@@ -281,6 +281,20 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg,
281 key->conf.alg = alg; 281 key->conf.alg = alg;
282 key->conf.keyidx = idx; 282 key->conf.keyidx = idx;
283 key->conf.keylen = key_len; 283 key->conf.keylen = key_len;
284 switch (alg) {
285 case ALG_WEP:
286 key->conf.iv_len = WEP_IV_LEN;
287 key->conf.icv_len = WEP_ICV_LEN;
288 break;
289 case ALG_TKIP:
290 key->conf.iv_len = TKIP_IV_LEN;
291 key->conf.icv_len = TKIP_ICV_LEN;
292 break;
293 case ALG_CCMP:
294 key->conf.iv_len = CCMP_HDR_LEN;
295 key->conf.icv_len = CCMP_MIC_LEN;
296 break;
297 }
284 memcpy(key->conf.key, key_data, key_len); 298 memcpy(key->conf.key, key_data, key_len);
285 INIT_LIST_HEAD(&key->list); 299 INIT_LIST_HEAD(&key->list);
286 INIT_LIST_HEAD(&key->todo); 300 INIT_LIST_HEAD(&key->todo);
@@ -331,7 +345,7 @@ void ieee80211_key_link(struct ieee80211_key *key,
331 */ 345 */
332 key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE; 346 key->conf.flags |= IEEE80211_KEY_FLAG_PAIRWISE;
333 } else { 347 } else {
334 if (sdata->vif.type == IEEE80211_IF_TYPE_STA) { 348 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
335 struct sta_info *ap; 349 struct sta_info *ap;
336 350
337 /* 351 /*
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index aa5a191598c9..ae62ad40ad63 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -45,16 +45,9 @@ struct ieee80211_tx_status_rtap_hdr {
45 u8 data_retries; 45 u8 data_retries;
46} __attribute__ ((packed)); 46} __attribute__ ((packed));
47 47
48/* common interface routines */
49
50static int header_parse_80211(const struct sk_buff *skb, unsigned char *haddr)
51{
52 memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN); /* addr2 */
53 return ETH_ALEN;
54}
55 48
56/* must be called under mdev tx lock */ 49/* must be called under mdev tx lock */
57static void ieee80211_configure_filter(struct ieee80211_local *local) 50void ieee80211_configure_filter(struct ieee80211_local *local)
58{ 51{
59 unsigned int changed_flags; 52 unsigned int changed_flags;
60 unsigned int new_flags = 0; 53 unsigned int new_flags = 0;
@@ -97,9 +90,24 @@ static void ieee80211_configure_filter(struct ieee80211_local *local)
97 90
98/* master interface */ 91/* master interface */
99 92
93static int header_parse_80211(const struct sk_buff *skb, unsigned char *haddr)
94{
95 memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN); /* addr2 */
96 return ETH_ALEN;
97}
98
99static const struct header_ops ieee80211_header_ops = {
100 .create = eth_header,
101 .parse = header_parse_80211,
102 .rebuild = eth_rebuild_header,
103 .cache = eth_header_cache,
104 .cache_update = eth_header_cache_update,
105};
106
100static int ieee80211_master_open(struct net_device *dev) 107static int ieee80211_master_open(struct net_device *dev)
101{ 108{
102 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 109 struct ieee80211_master_priv *mpriv = netdev_priv(dev);
110 struct ieee80211_local *local = mpriv->local;
103 struct ieee80211_sub_if_data *sdata; 111 struct ieee80211_sub_if_data *sdata;
104 int res = -EOPNOTSUPP; 112 int res = -EOPNOTSUPP;
105 113
@@ -121,7 +129,8 @@ static int ieee80211_master_open(struct net_device *dev)
121 129
122static int ieee80211_master_stop(struct net_device *dev) 130static int ieee80211_master_stop(struct net_device *dev)
123{ 131{
124 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 132 struct ieee80211_master_priv *mpriv = netdev_priv(dev);
133 struct ieee80211_local *local = mpriv->local;
125 struct ieee80211_sub_if_data *sdata; 134 struct ieee80211_sub_if_data *sdata;
126 135
127 /* we hold the RTNL here so can safely walk the list */ 136 /* we hold the RTNL here so can safely walk the list */
@@ -134,849 +143,12 @@ static int ieee80211_master_stop(struct net_device *dev)
134 143
135static void ieee80211_master_set_multicast_list(struct net_device *dev) 144static void ieee80211_master_set_multicast_list(struct net_device *dev)
136{ 145{
137 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 146 struct ieee80211_master_priv *mpriv = netdev_priv(dev);
147 struct ieee80211_local *local = mpriv->local;
138 148
139 ieee80211_configure_filter(local); 149 ieee80211_configure_filter(local);
140} 150}
141 151
142/* regular interfaces */
143
144static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
145{
146 int meshhdrlen;
147 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
148
149 meshhdrlen = (sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT) ? 5 : 0;
150
151 /* FIX: what would be proper limits for MTU?
152 * This interface uses 802.3 frames. */
153 if (new_mtu < 256 ||
154 new_mtu > IEEE80211_MAX_DATA_LEN - 24 - 6 - meshhdrlen) {
155 return -EINVAL;
156 }
157
158#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
159 printk(KERN_DEBUG "%s: setting MTU %d\n", dev->name, new_mtu);
160#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
161 dev->mtu = new_mtu;
162 return 0;
163}
164
165static inline int identical_mac_addr_allowed(int type1, int type2)
166{
167 return (type1 == IEEE80211_IF_TYPE_MNTR ||
168 type2 == IEEE80211_IF_TYPE_MNTR ||
169 (type1 == IEEE80211_IF_TYPE_AP &&
170 type2 == IEEE80211_IF_TYPE_WDS) ||
171 (type1 == IEEE80211_IF_TYPE_WDS &&
172 (type2 == IEEE80211_IF_TYPE_WDS ||
173 type2 == IEEE80211_IF_TYPE_AP)) ||
174 (type1 == IEEE80211_IF_TYPE_AP &&
175 type2 == IEEE80211_IF_TYPE_VLAN) ||
176 (type1 == IEEE80211_IF_TYPE_VLAN &&
177 (type2 == IEEE80211_IF_TYPE_AP ||
178 type2 == IEEE80211_IF_TYPE_VLAN)));
179}
180
181static int ieee80211_open(struct net_device *dev)
182{
183 struct ieee80211_sub_if_data *sdata, *nsdata;
184 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
185 struct sta_info *sta;
186 struct ieee80211_if_init_conf conf;
187 u32 changed = 0;
188 int res;
189 bool need_hw_reconfig = 0;
190
191 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
192
193 /* we hold the RTNL here so can safely walk the list */
194 list_for_each_entry(nsdata, &local->interfaces, list) {
195 struct net_device *ndev = nsdata->dev;
196
197 if (ndev != dev && netif_running(ndev)) {
198 /*
199 * Allow only a single IBSS interface to be up at any
200 * time. This is restricted because beacon distribution
201 * cannot work properly if both are in the same IBSS.
202 *
203 * To remove this restriction we'd have to disallow them
204 * from setting the same SSID on different IBSS interfaces
205 * belonging to the same hardware. Then, however, we're
206 * faced with having to adopt two different TSF timers...
207 */
208 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS &&
209 nsdata->vif.type == IEEE80211_IF_TYPE_IBSS)
210 return -EBUSY;
211
212 /*
213 * The remaining checks are only performed for interfaces
214 * with the same MAC address.
215 */
216 if (compare_ether_addr(dev->dev_addr, ndev->dev_addr))
217 continue;
218
219 /*
220 * check whether it may have the same address
221 */
222 if (!identical_mac_addr_allowed(sdata->vif.type,
223 nsdata->vif.type))
224 return -ENOTUNIQ;
225
226 /*
227 * can only add VLANs to enabled APs
228 */
229 if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN &&
230 nsdata->vif.type == IEEE80211_IF_TYPE_AP)
231 sdata->bss = &nsdata->u.ap;
232 }
233 }
234
235 switch (sdata->vif.type) {
236 case IEEE80211_IF_TYPE_WDS:
237 if (!is_valid_ether_addr(sdata->u.wds.remote_addr))
238 return -ENOLINK;
239 break;
240 case IEEE80211_IF_TYPE_VLAN:
241 if (!sdata->bss)
242 return -ENOLINK;
243 list_add(&sdata->u.vlan.list, &sdata->bss->vlans);
244 break;
245 case IEEE80211_IF_TYPE_AP:
246 sdata->bss = &sdata->u.ap;
247 break;
248 case IEEE80211_IF_TYPE_MESH_POINT:
249 /* mesh ifaces must set allmulti to forward mcast traffic */
250 atomic_inc(&local->iff_allmultis);
251 break;
252 case IEEE80211_IF_TYPE_STA:
253 case IEEE80211_IF_TYPE_MNTR:
254 case IEEE80211_IF_TYPE_IBSS:
255 /* no special treatment */
256 break;
257 case IEEE80211_IF_TYPE_INVALID:
258 /* cannot happen */
259 WARN_ON(1);
260 break;
261 }
262
263 if (local->open_count == 0) {
264 res = 0;
265 if (local->ops->start)
266 res = local->ops->start(local_to_hw(local));
267 if (res)
268 goto err_del_bss;
269 need_hw_reconfig = 1;
270 ieee80211_led_radio(local, local->hw.conf.radio_enabled);
271 }
272
273 switch (sdata->vif.type) {
274 case IEEE80211_IF_TYPE_VLAN:
275 /* no need to tell driver */
276 break;
277 case IEEE80211_IF_TYPE_MNTR:
278 if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) {
279 local->cooked_mntrs++;
280 break;
281 }
282
283 /* must be before the call to ieee80211_configure_filter */
284 local->monitors++;
285 if (local->monitors == 1)
286 local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP;
287
288 if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL)
289 local->fif_fcsfail++;
290 if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL)
291 local->fif_plcpfail++;
292 if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL)
293 local->fif_control++;
294 if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
295 local->fif_other_bss++;
296
297 netif_addr_lock_bh(local->mdev);
298 ieee80211_configure_filter(local);
299 netif_addr_unlock_bh(local->mdev);
300 break;
301 case IEEE80211_IF_TYPE_STA:
302 case IEEE80211_IF_TYPE_IBSS:
303 sdata->u.sta.flags &= ~IEEE80211_STA_PREV_BSSID_SET;
304 /* fall through */
305 default:
306 conf.vif = &sdata->vif;
307 conf.type = sdata->vif.type;
308 conf.mac_addr = dev->dev_addr;
309 res = local->ops->add_interface(local_to_hw(local), &conf);
310 if (res)
311 goto err_stop;
312
313 if (ieee80211_vif_is_mesh(&sdata->vif))
314 ieee80211_start_mesh(sdata->dev);
315 changed |= ieee80211_reset_erp_info(dev);
316 ieee80211_bss_info_change_notify(sdata, changed);
317 ieee80211_enable_keys(sdata);
318
319 if (sdata->vif.type == IEEE80211_IF_TYPE_STA &&
320 !(sdata->flags & IEEE80211_SDATA_USERSPACE_MLME))
321 netif_carrier_off(dev);
322 else
323 netif_carrier_on(dev);
324 }
325
326 if (sdata->vif.type == IEEE80211_IF_TYPE_WDS) {
327 /* Create STA entry for the WDS peer */
328 sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
329 GFP_KERNEL);
330 if (!sta) {
331 res = -ENOMEM;
332 goto err_del_interface;
333 }
334
335 /* no locking required since STA is not live yet */
336 sta->flags |= WLAN_STA_AUTHORIZED;
337
338 res = sta_info_insert(sta);
339 if (res) {
340 /* STA has been freed */
341 goto err_del_interface;
342 }
343 }
344
345 if (local->open_count == 0) {
346 res = dev_open(local->mdev);
347 WARN_ON(res);
348 if (res)
349 goto err_del_interface;
350 tasklet_enable(&local->tx_pending_tasklet);
351 tasklet_enable(&local->tasklet);
352 }
353
354 /*
355 * set_multicast_list will be invoked by the networking core
356 * which will check whether any increments here were done in
357 * error and sync them down to the hardware as filter flags.
358 */
359 if (sdata->flags & IEEE80211_SDATA_ALLMULTI)
360 atomic_inc(&local->iff_allmultis);
361
362 if (sdata->flags & IEEE80211_SDATA_PROMISC)
363 atomic_inc(&local->iff_promiscs);
364
365 local->open_count++;
366 if (need_hw_reconfig)
367 ieee80211_hw_config(local);
368
369 /*
370 * ieee80211_sta_work is disabled while network interface
371 * is down. Therefore, some configuration changes may not
372 * yet be effective. Trigger execution of ieee80211_sta_work
373 * to fix this.
374 */
375 if (sdata->vif.type == IEEE80211_IF_TYPE_STA ||
376 sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
377 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
378 queue_work(local->hw.workqueue, &ifsta->work);
379 }
380
381 netif_tx_start_all_queues(dev);
382
383 return 0;
384 err_del_interface:
385 local->ops->remove_interface(local_to_hw(local), &conf);
386 err_stop:
387 if (!local->open_count && local->ops->stop)
388 local->ops->stop(local_to_hw(local));
389 err_del_bss:
390 sdata->bss = NULL;
391 if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN)
392 list_del(&sdata->u.vlan.list);
393 return res;
394}
395
396static int ieee80211_stop(struct net_device *dev)
397{
398 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
399 struct ieee80211_local *local = sdata->local;
400 struct ieee80211_if_init_conf conf;
401 struct sta_info *sta;
402
403 /*
404 * Stop TX on this interface first.
405 */
406 netif_tx_stop_all_queues(dev);
407
408 /*
409 * Now delete all active aggregation sessions.
410 */
411 rcu_read_lock();
412
413 list_for_each_entry_rcu(sta, &local->sta_list, list) {
414 if (sta->sdata == sdata)
415 ieee80211_sta_tear_down_BA_sessions(dev, sta->addr);
416 }
417
418 rcu_read_unlock();
419
420 /*
421 * Remove all stations associated with this interface.
422 *
423 * This must be done before calling ops->remove_interface()
424 * because otherwise we can later invoke ops->sta_notify()
425 * whenever the STAs are removed, and that invalidates driver
426 * assumptions about always getting a vif pointer that is valid
427 * (because if we remove a STA after ops->remove_interface()
428 * the driver will have removed the vif info already!)
429 *
430 * We could relax this and only unlink the stations from the
431 * hash table and list but keep them on a per-sdata list that
432 * will be inserted back again when the interface is brought
433 * up again, but I don't currently see a use case for that,
434 * except with WDS which gets a STA entry created when it is
435 * brought up.
436 */
437 sta_info_flush(local, sdata);
438
439 /*
440 * Don't count this interface for promisc/allmulti while it
441 * is down. dev_mc_unsync() will invoke set_multicast_list
442 * on the master interface which will sync these down to the
443 * hardware as filter flags.
444 */
445 if (sdata->flags & IEEE80211_SDATA_ALLMULTI)
446 atomic_dec(&local->iff_allmultis);
447
448 if (sdata->flags & IEEE80211_SDATA_PROMISC)
449 atomic_dec(&local->iff_promiscs);
450
451 dev_mc_unsync(local->mdev, dev);
452
453 /* APs need special treatment */
454 if (sdata->vif.type == IEEE80211_IF_TYPE_AP) {
455 struct ieee80211_sub_if_data *vlan, *tmp;
456 struct beacon_data *old_beacon = sdata->u.ap.beacon;
457
458 /* remove beacon */
459 rcu_assign_pointer(sdata->u.ap.beacon, NULL);
460 synchronize_rcu();
461 kfree(old_beacon);
462
463 /* down all dependent devices, that is VLANs */
464 list_for_each_entry_safe(vlan, tmp, &sdata->u.ap.vlans,
465 u.vlan.list)
466 dev_close(vlan->dev);
467 WARN_ON(!list_empty(&sdata->u.ap.vlans));
468 }
469
470 local->open_count--;
471
472 switch (sdata->vif.type) {
473 case IEEE80211_IF_TYPE_VLAN:
474 list_del(&sdata->u.vlan.list);
475 /* no need to tell driver */
476 break;
477 case IEEE80211_IF_TYPE_MNTR:
478 if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) {
479 local->cooked_mntrs--;
480 break;
481 }
482
483 local->monitors--;
484 if (local->monitors == 0)
485 local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP;
486
487 if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL)
488 local->fif_fcsfail--;
489 if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL)
490 local->fif_plcpfail--;
491 if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL)
492 local->fif_control--;
493 if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
494 local->fif_other_bss--;
495
496 netif_addr_lock_bh(local->mdev);
497 ieee80211_configure_filter(local);
498 netif_addr_unlock_bh(local->mdev);
499 break;
500 case IEEE80211_IF_TYPE_MESH_POINT:
501 /* allmulti is always set on mesh ifaces */
502 atomic_dec(&local->iff_allmultis);
503 /* fall through */
504 case IEEE80211_IF_TYPE_STA:
505 case IEEE80211_IF_TYPE_IBSS:
506 sdata->u.sta.state = IEEE80211_DISABLED;
507 memset(sdata->u.sta.bssid, 0, ETH_ALEN);
508 del_timer_sync(&sdata->u.sta.timer);
509 /*
510 * When we get here, the interface is marked down.
511 * Call synchronize_rcu() to wait for the RX path
512 * should it be using the interface and enqueuing
513 * frames at this very time on another CPU.
514 */
515 synchronize_rcu();
516 skb_queue_purge(&sdata->u.sta.skb_queue);
517
518 if (local->scan_dev == sdata->dev) {
519 if (!local->ops->hw_scan) {
520 local->sta_sw_scanning = 0;
521 cancel_delayed_work(&local->scan_work);
522 } else
523 local->sta_hw_scanning = 0;
524 }
525
526 sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED;
527 kfree(sdata->u.sta.extra_ie);
528 sdata->u.sta.extra_ie = NULL;
529 sdata->u.sta.extra_ie_len = 0;
530 /* fall through */
531 default:
532 conf.vif = &sdata->vif;
533 conf.type = sdata->vif.type;
534 conf.mac_addr = dev->dev_addr;
535 /* disable all keys for as long as this netdev is down */
536 ieee80211_disable_keys(sdata);
537 local->ops->remove_interface(local_to_hw(local), &conf);
538 }
539
540 sdata->bss = NULL;
541
542 if (local->open_count == 0) {
543 if (netif_running(local->mdev))
544 dev_close(local->mdev);
545
546 if (local->ops->stop)
547 local->ops->stop(local_to_hw(local));
548
549 ieee80211_led_radio(local, 0);
550
551 flush_workqueue(local->hw.workqueue);
552
553 tasklet_disable(&local->tx_pending_tasklet);
554 tasklet_disable(&local->tasklet);
555 }
556
557 return 0;
558}
559
560int ieee80211_start_tx_ba_session(struct ieee80211_hw *hw, u8 *ra, u16 tid)
561{
562 struct ieee80211_local *local = hw_to_local(hw);
563 struct sta_info *sta;
564 struct ieee80211_sub_if_data *sdata;
565 u16 start_seq_num = 0;
566 u8 *state;
567 int ret;
568 DECLARE_MAC_BUF(mac);
569
570 if (tid >= STA_TID_NUM)
571 return -EINVAL;
572
573#ifdef CONFIG_MAC80211_HT_DEBUG
574 printk(KERN_DEBUG "Open BA session requested for %s tid %u\n",
575 print_mac(mac, ra), tid);
576#endif /* CONFIG_MAC80211_HT_DEBUG */
577
578 rcu_read_lock();
579
580 sta = sta_info_get(local, ra);
581 if (!sta) {
582#ifdef CONFIG_MAC80211_HT_DEBUG
583 printk(KERN_DEBUG "Could not find the station\n");
584#endif
585 ret = -ENOENT;
586 goto exit;
587 }
588
589 spin_lock_bh(&sta->lock);
590
591 /* we have tried too many times, receiver does not want A-MPDU */
592 if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) {
593 ret = -EBUSY;
594 goto err_unlock_sta;
595 }
596
597 state = &sta->ampdu_mlme.tid_state_tx[tid];
598 /* check if the TID is not in aggregation flow already */
599 if (*state != HT_AGG_STATE_IDLE) {
600#ifdef CONFIG_MAC80211_HT_DEBUG
601 printk(KERN_DEBUG "BA request denied - session is not "
602 "idle on tid %u\n", tid);
603#endif /* CONFIG_MAC80211_HT_DEBUG */
604 ret = -EAGAIN;
605 goto err_unlock_sta;
606 }
607
608 /* prepare A-MPDU MLME for Tx aggregation */
609 sta->ampdu_mlme.tid_tx[tid] =
610 kmalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC);
611 if (!sta->ampdu_mlme.tid_tx[tid]) {
612#ifdef CONFIG_MAC80211_HT_DEBUG
613 if (net_ratelimit())
614 printk(KERN_ERR "allocate tx mlme to tid %d failed\n",
615 tid);
616#endif
617 ret = -ENOMEM;
618 goto err_unlock_sta;
619 }
620 /* Tx timer */
621 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function =
622 sta_addba_resp_timer_expired;
623 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.data =
624 (unsigned long)&sta->timer_to_tid[tid];
625 init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
626
627 /* create a new queue for this aggregation */
628 ret = ieee80211_ht_agg_queue_add(local, sta, tid);
629
630 /* case no queue is available to aggregation
631 * don't switch to aggregation */
632 if (ret) {
633#ifdef CONFIG_MAC80211_HT_DEBUG
634 printk(KERN_DEBUG "BA request denied - queue unavailable for"
635 " tid %d\n", tid);
636#endif /* CONFIG_MAC80211_HT_DEBUG */
637 goto err_unlock_queue;
638 }
639 sdata = sta->sdata;
640
641 /* Ok, the Addba frame hasn't been sent yet, but if the driver calls the
642 * call back right away, it must see that the flow has begun */
643 *state |= HT_ADDBA_REQUESTED_MSK;
644
645 if (local->ops->ampdu_action)
646 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_START,
647 ra, tid, &start_seq_num);
648
649 if (ret) {
650 /* No need to requeue the packets in the agg queue, since we
651 * held the tx lock: no packet could be enqueued to the newly
652 * allocated queue */
653 ieee80211_ht_agg_queue_remove(local, sta, tid, 0);
654#ifdef CONFIG_MAC80211_HT_DEBUG
655 printk(KERN_DEBUG "BA request denied - HW unavailable for"
656 " tid %d\n", tid);
657#endif /* CONFIG_MAC80211_HT_DEBUG */
658 *state = HT_AGG_STATE_IDLE;
659 goto err_unlock_queue;
660 }
661
662 /* Will put all the packets in the new SW queue */
663 ieee80211_requeue(local, ieee802_1d_to_ac[tid]);
664 spin_unlock_bh(&sta->lock);
665
666 /* send an addBA request */
667 sta->ampdu_mlme.dialog_token_allocator++;
668 sta->ampdu_mlme.tid_tx[tid]->dialog_token =
669 sta->ampdu_mlme.dialog_token_allocator;
670 sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num;
671
672
673 ieee80211_send_addba_request(sta->sdata->dev, ra, tid,
674 sta->ampdu_mlme.tid_tx[tid]->dialog_token,
675 sta->ampdu_mlme.tid_tx[tid]->ssn,
676 0x40, 5000);
677 /* activate the timer for the recipient's addBA response */
678 sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires =
679 jiffies + ADDBA_RESP_INTERVAL;
680 add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
681#ifdef CONFIG_MAC80211_HT_DEBUG
682 printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid);
683#endif
684 goto exit;
685
686err_unlock_queue:
687 kfree(sta->ampdu_mlme.tid_tx[tid]);
688 sta->ampdu_mlme.tid_tx[tid] = NULL;
689 ret = -EBUSY;
690err_unlock_sta:
691 spin_unlock_bh(&sta->lock);
692exit:
693 rcu_read_unlock();
694 return ret;
695}
696EXPORT_SYMBOL(ieee80211_start_tx_ba_session);
697
698int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw,
699 u8 *ra, u16 tid,
700 enum ieee80211_back_parties initiator)
701{
702 struct ieee80211_local *local = hw_to_local(hw);
703 struct sta_info *sta;
704 u8 *state;
705 int ret = 0;
706 DECLARE_MAC_BUF(mac);
707
708 if (tid >= STA_TID_NUM)
709 return -EINVAL;
710
711 rcu_read_lock();
712 sta = sta_info_get(local, ra);
713 if (!sta) {
714 rcu_read_unlock();
715 return -ENOENT;
716 }
717
718 /* check if the TID is in aggregation */
719 state = &sta->ampdu_mlme.tid_state_tx[tid];
720 spin_lock_bh(&sta->lock);
721
722 if (*state != HT_AGG_STATE_OPERATIONAL) {
723 ret = -ENOENT;
724 goto stop_BA_exit;
725 }
726
727#ifdef CONFIG_MAC80211_HT_DEBUG
728 printk(KERN_DEBUG "Tx BA session stop requested for %s tid %u\n",
729 print_mac(mac, ra), tid);
730#endif /* CONFIG_MAC80211_HT_DEBUG */
731
732 ieee80211_stop_queue(hw, sta->tid_to_tx_q[tid]);
733
734 *state = HT_AGG_STATE_REQ_STOP_BA_MSK |
735 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
736
737 if (local->ops->ampdu_action)
738 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_TX_STOP,
739 ra, tid, NULL);
740
741 /* case HW denied going back to legacy */
742 if (ret) {
743 WARN_ON(ret != -EBUSY);
744 *state = HT_AGG_STATE_OPERATIONAL;
745 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
746 goto stop_BA_exit;
747 }
748
749stop_BA_exit:
750 spin_unlock_bh(&sta->lock);
751 rcu_read_unlock();
752 return ret;
753}
754EXPORT_SYMBOL(ieee80211_stop_tx_ba_session);
755
756void ieee80211_start_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u16 tid)
757{
758 struct ieee80211_local *local = hw_to_local(hw);
759 struct sta_info *sta;
760 u8 *state;
761 DECLARE_MAC_BUF(mac);
762
763 if (tid >= STA_TID_NUM) {
764#ifdef CONFIG_MAC80211_HT_DEBUG
765 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
766 tid, STA_TID_NUM);
767#endif
768 return;
769 }
770
771 rcu_read_lock();
772 sta = sta_info_get(local, ra);
773 if (!sta) {
774 rcu_read_unlock();
775#ifdef CONFIG_MAC80211_HT_DEBUG
776 printk(KERN_DEBUG "Could not find station: %s\n",
777 print_mac(mac, ra));
778#endif
779 return;
780 }
781
782 state = &sta->ampdu_mlme.tid_state_tx[tid];
783 spin_lock_bh(&sta->lock);
784
785 if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
786#ifdef CONFIG_MAC80211_HT_DEBUG
787 printk(KERN_DEBUG "addBA was not requested yet, state is %d\n",
788 *state);
789#endif
790 spin_unlock_bh(&sta->lock);
791 rcu_read_unlock();
792 return;
793 }
794
795 WARN_ON_ONCE(*state & HT_ADDBA_DRV_READY_MSK);
796
797 *state |= HT_ADDBA_DRV_READY_MSK;
798
799 if (*state == HT_AGG_STATE_OPERATIONAL) {
800#ifdef CONFIG_MAC80211_HT_DEBUG
801 printk(KERN_DEBUG "Aggregation is on for tid %d \n", tid);
802#endif
803 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]);
804 }
805 spin_unlock_bh(&sta->lock);
806 rcu_read_unlock();
807}
808EXPORT_SYMBOL(ieee80211_start_tx_ba_cb);
809
810void ieee80211_stop_tx_ba_cb(struct ieee80211_hw *hw, u8 *ra, u8 tid)
811{
812 struct ieee80211_local *local = hw_to_local(hw);
813 struct sta_info *sta;
814 u8 *state;
815 int agg_queue;
816 DECLARE_MAC_BUF(mac);
817
818 if (tid >= STA_TID_NUM) {
819#ifdef CONFIG_MAC80211_HT_DEBUG
820 printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n",
821 tid, STA_TID_NUM);
822#endif
823 return;
824 }
825
826#ifdef CONFIG_MAC80211_HT_DEBUG
827 printk(KERN_DEBUG "Stopping Tx BA session for %s tid %d\n",
828 print_mac(mac, ra), tid);
829#endif /* CONFIG_MAC80211_HT_DEBUG */
830
831 rcu_read_lock();
832 sta = sta_info_get(local, ra);
833 if (!sta) {
834#ifdef CONFIG_MAC80211_HT_DEBUG
835 printk(KERN_DEBUG "Could not find station: %s\n",
836 print_mac(mac, ra));
837#endif
838 rcu_read_unlock();
839 return;
840 }
841 state = &sta->ampdu_mlme.tid_state_tx[tid];
842
843 /* NOTE: no need to use sta->lock in this state check, as
844 * ieee80211_stop_tx_ba_session will let only one stop call to
845 * pass through per sta/tid
846 */
847 if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) {
848#ifdef CONFIG_MAC80211_HT_DEBUG
849 printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n");
850#endif
851 rcu_read_unlock();
852 return;
853 }
854
855 if (*state & HT_AGG_STATE_INITIATOR_MSK)
856 ieee80211_send_delba(sta->sdata->dev, ra, tid,
857 WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
858
859 agg_queue = sta->tid_to_tx_q[tid];
860
861 ieee80211_ht_agg_queue_remove(local, sta, tid, 1);
862
863 /* We just requeued the all the frames that were in the
864 * removed queue, and since we might miss a softirq we do
865 * netif_schedule_queue. ieee80211_wake_queue is not used
866 * here as this queue is not necessarily stopped
867 */
868 netif_schedule_queue(netdev_get_tx_queue(local->mdev, agg_queue));
869 spin_lock_bh(&sta->lock);
870 *state = HT_AGG_STATE_IDLE;
871 sta->ampdu_mlme.addba_req_num[tid] = 0;
872 kfree(sta->ampdu_mlme.tid_tx[tid]);
873 sta->ampdu_mlme.tid_tx[tid] = NULL;
874 spin_unlock_bh(&sta->lock);
875
876 rcu_read_unlock();
877}
878EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb);
879
880void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
881 const u8 *ra, u16 tid)
882{
883 struct ieee80211_local *local = hw_to_local(hw);
884 struct ieee80211_ra_tid *ra_tid;
885 struct sk_buff *skb = dev_alloc_skb(0);
886
887 if (unlikely(!skb)) {
888#ifdef CONFIG_MAC80211_HT_DEBUG
889 if (net_ratelimit())
890 printk(KERN_WARNING "%s: Not enough memory, "
891 "dropping start BA session", skb->dev->name);
892#endif
893 return;
894 }
895 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
896 memcpy(&ra_tid->ra, ra, ETH_ALEN);
897 ra_tid->tid = tid;
898
899 skb->pkt_type = IEEE80211_ADDBA_MSG;
900 skb_queue_tail(&local->skb_queue, skb);
901 tasklet_schedule(&local->tasklet);
902}
903EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe);
904
905void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_hw *hw,
906 const u8 *ra, u16 tid)
907{
908 struct ieee80211_local *local = hw_to_local(hw);
909 struct ieee80211_ra_tid *ra_tid;
910 struct sk_buff *skb = dev_alloc_skb(0);
911
912 if (unlikely(!skb)) {
913#ifdef CONFIG_MAC80211_HT_DEBUG
914 if (net_ratelimit())
915 printk(KERN_WARNING "%s: Not enough memory, "
916 "dropping stop BA session", skb->dev->name);
917#endif
918 return;
919 }
920 ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
921 memcpy(&ra_tid->ra, ra, ETH_ALEN);
922 ra_tid->tid = tid;
923
924 skb->pkt_type = IEEE80211_DELBA_MSG;
925 skb_queue_tail(&local->skb_queue, skb);
926 tasklet_schedule(&local->tasklet);
927}
928EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb_irqsafe);
929
930static void ieee80211_set_multicast_list(struct net_device *dev)
931{
932 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
933 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
934 int allmulti, promisc, sdata_allmulti, sdata_promisc;
935
936 allmulti = !!(dev->flags & IFF_ALLMULTI);
937 promisc = !!(dev->flags & IFF_PROMISC);
938 sdata_allmulti = !!(sdata->flags & IEEE80211_SDATA_ALLMULTI);
939 sdata_promisc = !!(sdata->flags & IEEE80211_SDATA_PROMISC);
940
941 if (allmulti != sdata_allmulti) {
942 if (dev->flags & IFF_ALLMULTI)
943 atomic_inc(&local->iff_allmultis);
944 else
945 atomic_dec(&local->iff_allmultis);
946 sdata->flags ^= IEEE80211_SDATA_ALLMULTI;
947 }
948
949 if (promisc != sdata_promisc) {
950 if (dev->flags & IFF_PROMISC)
951 atomic_inc(&local->iff_promiscs);
952 else
953 atomic_dec(&local->iff_promiscs);
954 sdata->flags ^= IEEE80211_SDATA_PROMISC;
955 }
956
957 dev_mc_sync(local->mdev, dev);
958}
959
960static const struct header_ops ieee80211_header_ops = {
961 .create = eth_header,
962 .parse = header_parse_80211,
963 .rebuild = eth_rebuild_header,
964 .cache = eth_header_cache,
965 .cache_update = eth_header_cache_update,
966};
967
968void ieee80211_if_setup(struct net_device *dev)
969{
970 ether_setup(dev);
971 dev->hard_start_xmit = ieee80211_subif_start_xmit;
972 dev->wireless_handlers = &ieee80211_iw_handler_def;
973 dev->set_multicast_list = ieee80211_set_multicast_list;
974 dev->change_mtu = ieee80211_change_mtu;
975 dev->open = ieee80211_open;
976 dev->stop = ieee80211_stop;
977 dev->destructor = free_netdev;
978}
979
980/* everything else */ 152/* everything else */
981 153
982int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed) 154int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed)
@@ -987,18 +159,21 @@ int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed)
987 if (WARN_ON(!netif_running(sdata->dev))) 159 if (WARN_ON(!netif_running(sdata->dev)))
988 return 0; 160 return 0;
989 161
162 if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN))
163 return -EINVAL;
164
990 if (!local->ops->config_interface) 165 if (!local->ops->config_interface)
991 return 0; 166 return 0;
992 167
993 memset(&conf, 0, sizeof(conf)); 168 memset(&conf, 0, sizeof(conf));
994 conf.changed = changed; 169 conf.changed = changed;
995 170
996 if (sdata->vif.type == IEEE80211_IF_TYPE_STA || 171 if (sdata->vif.type == NL80211_IFTYPE_STATION ||
997 sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { 172 sdata->vif.type == NL80211_IFTYPE_ADHOC) {
998 conf.bssid = sdata->u.sta.bssid; 173 conf.bssid = sdata->u.sta.bssid;
999 conf.ssid = sdata->u.sta.ssid; 174 conf.ssid = sdata->u.sta.ssid;
1000 conf.ssid_len = sdata->u.sta.ssid_len; 175 conf.ssid_len = sdata->u.sta.ssid_len;
1001 } else if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { 176 } else if (sdata->vif.type == NL80211_IFTYPE_AP) {
1002 conf.bssid = sdata->dev->dev_addr; 177 conf.bssid = sdata->dev->dev_addr;
1003 conf.ssid = sdata->u.ap.ssid; 178 conf.ssid = sdata->u.ap.ssid;
1004 conf.ssid_len = sdata->u.ap.ssid_len; 179 conf.ssid_len = sdata->u.ap.ssid_len;
@@ -1027,7 +202,7 @@ int ieee80211_hw_config(struct ieee80211_local *local)
1027 struct ieee80211_channel *chan; 202 struct ieee80211_channel *chan;
1028 int ret = 0; 203 int ret = 0;
1029 204
1030 if (local->sta_sw_scanning) 205 if (local->sw_scanning)
1031 chan = local->scan_channel; 206 chan = local->scan_channel;
1032 else 207 else
1033 chan = local->oper_channel; 208 chan = local->oper_channel;
@@ -1099,8 +274,8 @@ u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht,
1099 ht_conf.ht_supported = 1; 274 ht_conf.ht_supported = 1;
1100 275
1101 ht_conf.cap = req_ht_cap->cap & sband->ht_info.cap; 276 ht_conf.cap = req_ht_cap->cap & sband->ht_info.cap;
1102 ht_conf.cap &= ~(IEEE80211_HT_CAP_MIMO_PS); 277 ht_conf.cap &= ~(IEEE80211_HT_CAP_SM_PS);
1103 ht_conf.cap |= sband->ht_info.cap & IEEE80211_HT_CAP_MIMO_PS; 278 ht_conf.cap |= sband->ht_info.cap & IEEE80211_HT_CAP_SM_PS;
1104 ht_bss_conf.primary_channel = req_bss_cap->primary_channel; 279 ht_bss_conf.primary_channel = req_bss_cap->primary_channel;
1105 ht_bss_conf.bss_cap = req_bss_cap->bss_cap; 280 ht_bss_conf.bss_cap = req_bss_cap->bss_cap;
1106 ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode; 281 ht_bss_conf.bss_op_mode = req_bss_cap->bss_op_mode;
@@ -1152,6 +327,9 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
1152{ 327{
1153 struct ieee80211_local *local = sdata->local; 328 struct ieee80211_local *local = sdata->local;
1154 329
330 if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN))
331 return;
332
1155 if (!changed) 333 if (!changed)
1156 return; 334 return;
1157 335
@@ -1162,10 +340,8 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
1162 changed); 340 changed);
1163} 341}
1164 342
1165u32 ieee80211_reset_erp_info(struct net_device *dev) 343u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata)
1166{ 344{
1167 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1168
1169 sdata->bss_conf.use_cts_prot = 0; 345 sdata->bss_conf.use_cts_prot = 0;
1170 sdata->bss_conf.use_short_preamble = 0; 346 sdata->bss_conf.use_short_preamble = 0;
1171 return BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE; 347 return BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE;
@@ -1244,9 +420,10 @@ static void ieee80211_remove_tx_extra(struct ieee80211_local *local,
1244 struct ieee80211_key *key, 420 struct ieee80211_key *key,
1245 struct sk_buff *skb) 421 struct sk_buff *skb)
1246{ 422{
1247 int hdrlen, iv_len, mic_len; 423 unsigned int hdrlen, iv_len, mic_len;
424 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1248 425
1249 hdrlen = ieee80211_get_hdrlen_from_skb(skb); 426 hdrlen = ieee80211_hdrlen(hdr->frame_control);
1250 427
1251 if (!key) 428 if (!key)
1252 goto no_key; 429 goto no_key;
@@ -1268,24 +445,20 @@ static void ieee80211_remove_tx_extra(struct ieee80211_local *local,
1268 goto no_key; 445 goto no_key;
1269 } 446 }
1270 447
1271 if (skb->len >= mic_len && 448 if (skb->len >= hdrlen + mic_len &&
1272 !(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) 449 !(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
1273 skb_trim(skb, skb->len - mic_len); 450 skb_trim(skb, skb->len - mic_len);
1274 if (skb->len >= iv_len && skb->len > hdrlen) { 451 if (skb->len >= hdrlen + iv_len) {
1275 memmove(skb->data + iv_len, skb->data, hdrlen); 452 memmove(skb->data + iv_len, skb->data, hdrlen);
1276 skb_pull(skb, iv_len); 453 hdr = (struct ieee80211_hdr *)skb_pull(skb, iv_len);
1277 } 454 }
1278 455
1279no_key: 456no_key:
1280 { 457 if (ieee80211_is_data_qos(hdr->frame_control)) {
1281 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 458 hdr->frame_control &= ~cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
1282 u16 fc = le16_to_cpu(hdr->frame_control); 459 memmove(skb->data + IEEE80211_QOS_CTL_LEN, skb->data,
1283 if ((fc & 0x8C) == 0x88) /* QoS Control Field */ { 460 hdrlen - IEEE80211_QOS_CTL_LEN);
1284 fc &= ~IEEE80211_STYPE_QOS_DATA; 461 skb_pull(skb, IEEE80211_QOS_CTL_LEN);
1285 hdr->frame_control = cpu_to_le16(fc);
1286 memmove(skb->data + 2, skb->data, hdrlen - 2);
1287 skb_pull(skb, 2);
1288 }
1289 } 462 }
1290} 463}
1291 464
@@ -1369,6 +542,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
1369 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 542 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1370 u16 frag, type; 543 u16 frag, type;
1371 __le16 fc; 544 __le16 fc;
545 struct ieee80211_supported_band *sband;
1372 struct ieee80211_tx_status_rtap_hdr *rthdr; 546 struct ieee80211_tx_status_rtap_hdr *rthdr;
1373 struct ieee80211_sub_if_data *sdata; 547 struct ieee80211_sub_if_data *sdata;
1374 struct net_device *prev_dev = NULL; 548 struct net_device *prev_dev = NULL;
@@ -1376,47 +550,48 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
1376 550
1377 rcu_read_lock(); 551 rcu_read_lock();
1378 552
1379 if (info->status.excessive_retries) { 553 sta = sta_info_get(local, hdr->addr1);
1380 sta = sta_info_get(local, hdr->addr1); 554
1381 if (sta) { 555 if (sta) {
1382 if (test_sta_flags(sta, WLAN_STA_PS)) { 556 if (info->status.excessive_retries &&
1383 /* 557 test_sta_flags(sta, WLAN_STA_PS)) {
1384 * The STA is in power save mode, so assume 558 /*
1385 * that this TX packet failed because of that. 559 * The STA is in power save mode, so assume
1386 */ 560 * that this TX packet failed because of that.
1387 ieee80211_handle_filtered_frame(local, sta, skb); 561 */
1388 rcu_read_unlock(); 562 ieee80211_handle_filtered_frame(local, sta, skb);
1389 return; 563 rcu_read_unlock();
1390 } 564 return;
1391 } 565 }
1392 }
1393 566
1394 fc = hdr->frame_control; 567 fc = hdr->frame_control;
568
569 if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) &&
570 (ieee80211_is_data_qos(fc))) {
571 u16 tid, ssn;
572 u8 *qc;
1395 573
1396 if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) &&
1397 (ieee80211_is_data_qos(fc))) {
1398 u16 tid, ssn;
1399 u8 *qc;
1400 sta = sta_info_get(local, hdr->addr1);
1401 if (sta) {
1402 qc = ieee80211_get_qos_ctl(hdr); 574 qc = ieee80211_get_qos_ctl(hdr);
1403 tid = qc[0] & 0xf; 575 tid = qc[0] & 0xf;
1404 ssn = ((le16_to_cpu(hdr->seq_ctrl) + 0x10) 576 ssn = ((le16_to_cpu(hdr->seq_ctrl) + 0x10)
1405 & IEEE80211_SCTL_SEQ); 577 & IEEE80211_SCTL_SEQ);
1406 ieee80211_send_bar(sta->sdata->dev, hdr->addr1, 578 ieee80211_send_bar(sta->sdata, hdr->addr1,
1407 tid, ssn); 579 tid, ssn);
1408 } 580 }
1409 }
1410 581
1411 if (info->flags & IEEE80211_TX_STAT_TX_FILTERED) { 582 if (info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
1412 sta = sta_info_get(local, hdr->addr1);
1413 if (sta) {
1414 ieee80211_handle_filtered_frame(local, sta, skb); 583 ieee80211_handle_filtered_frame(local, sta, skb);
1415 rcu_read_unlock(); 584 rcu_read_unlock();
1416 return; 585 return;
586 } else {
587 if (info->status.excessive_retries)
588 sta->tx_retry_failed++;
589 sta->tx_retry_count += info->status.retry_count;
1417 } 590 }
1418 } else 591
1419 rate_control_tx_status(local->mdev, skb); 592 sband = local->hw.wiphy->bands[info->band];
593 rate_control_tx_status(local, sband, sta, skb);
594 }
1420 595
1421 rcu_read_unlock(); 596 rcu_read_unlock();
1422 597
@@ -1504,7 +679,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
1504 679
1505 rcu_read_lock(); 680 rcu_read_lock();
1506 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 681 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
1507 if (sdata->vif.type == IEEE80211_IF_TYPE_MNTR) { 682 if (sdata->vif.type == NL80211_IFTYPE_MONITOR) {
1508 if (!netif_running(sdata->dev)) 683 if (!netif_running(sdata->dev))
1509 continue; 684 continue;
1510 685
@@ -1580,8 +755,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
1580 755
1581 local->hw.queues = 1; /* default */ 756 local->hw.queues = 1; /* default */
1582 757
1583 local->bridge_packets = 1;
1584
1585 local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; 758 local->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
1586 local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD; 759 local->fragmentation_threshold = IEEE80211_MAX_FRAG_THRESHOLD;
1587 local->short_retry_limit = 7; 760 local->short_retry_limit = 7;
@@ -1592,7 +765,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
1592 765
1593 spin_lock_init(&local->key_lock); 766 spin_lock_init(&local->key_lock);
1594 767
1595 INIT_DELAYED_WORK(&local->scan_work, ieee80211_sta_scan_work); 768 INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work);
1596 769
1597 sta_info_init(local); 770 sta_info_init(local);
1598 771
@@ -1619,7 +792,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
1619 int result; 792 int result;
1620 enum ieee80211_band band; 793 enum ieee80211_band band;
1621 struct net_device *mdev; 794 struct net_device *mdev;
1622 struct wireless_dev *mwdev; 795 struct ieee80211_master_priv *mpriv;
1623 796
1624 /* 797 /*
1625 * generic code guarantees at least one band, 798 * generic code guarantees at least one band,
@@ -1639,6 +812,13 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
1639 } 812 }
1640 } 813 }
1641 814
815 /* if low-level driver supports AP, we also support VLAN */
816 if (local->hw.wiphy->interface_modes & BIT(NL80211_IFTYPE_AP))
817 local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP_VLAN);
818
819 /* mac80211 always supports monitor */
820 local->hw.wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
821
1642 result = wiphy_register(local->hw.wiphy); 822 result = wiphy_register(local->hw.wiphy);
1643 if (result < 0) 823 if (result < 0)
1644 return result; 824 return result;
@@ -1654,16 +834,14 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
1654 if (hw->queues < 4) 834 if (hw->queues < 4)
1655 hw->ampdu_queues = 0; 835 hw->ampdu_queues = 0;
1656 836
1657 mdev = alloc_netdev_mq(sizeof(struct wireless_dev), 837 mdev = alloc_netdev_mq(sizeof(struct ieee80211_master_priv),
1658 "wmaster%d", ether_setup, 838 "wmaster%d", ether_setup,
1659 ieee80211_num_queues(hw)); 839 ieee80211_num_queues(hw));
1660 if (!mdev) 840 if (!mdev)
1661 goto fail_mdev_alloc; 841 goto fail_mdev_alloc;
1662 842
1663 mwdev = netdev_priv(mdev); 843 mpriv = netdev_priv(mdev);
1664 mdev->ieee80211_ptr = mwdev; 844 mpriv->local = local;
1665 mwdev->wiphy = local->hw.wiphy;
1666
1667 local->mdev = mdev; 845 local->mdev = mdev;
1668 846
1669 ieee80211_rx_bss_list_init(local); 847 ieee80211_rx_bss_list_init(local);
@@ -1745,7 +923,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
1745 923
1746 /* add one default STA interface */ 924 /* add one default STA interface */
1747 result = ieee80211_if_add(local, "wlan%d", NULL, 925 result = ieee80211_if_add(local, "wlan%d", NULL,
1748 IEEE80211_IF_TYPE_STA, NULL); 926 NL80211_IFTYPE_STATION, NULL);
1749 if (result) 927 if (result)
1750 printk(KERN_WARNING "%s: Failed to add default virtual iface\n", 928 printk(KERN_WARNING "%s: Failed to add default virtual iface\n",
1751 wiphy_name(local->hw.wiphy)); 929 wiphy_name(local->hw.wiphy));
@@ -1837,6 +1015,10 @@ static int __init ieee80211_init(void)
1837 BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, driver_data) + 1015 BUILD_BUG_ON(offsetof(struct ieee80211_tx_info, driver_data) +
1838 IEEE80211_TX_INFO_DRIVER_DATA_SIZE > sizeof(skb->cb)); 1016 IEEE80211_TX_INFO_DRIVER_DATA_SIZE > sizeof(skb->cb));
1839 1017
1018 ret = rc80211_minstrel_init();
1019 if (ret)
1020 return ret;
1021
1840 ret = rc80211_pid_init(); 1022 ret = rc80211_pid_init();
1841 if (ret) 1023 if (ret)
1842 return ret; 1024 return ret;
@@ -1849,6 +1031,7 @@ static int __init ieee80211_init(void)
1849static void __exit ieee80211_exit(void) 1031static void __exit ieee80211_exit(void)
1850{ 1032{
1851 rc80211_pid_exit(); 1033 rc80211_pid_exit();
1034 rc80211_minstrel_exit();
1852 1035
1853 /* 1036 /*
1854 * For key todo, it'll be empty by now but the work 1037 * For key todo, it'll be empty by now but the work
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 35f2f95f2fa7..8013277924f2 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -12,6 +12,9 @@
12#include "ieee80211_i.h" 12#include "ieee80211_i.h"
13#include "mesh.h" 13#include "mesh.h"
14 14
15#define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ)
16#define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ)
17
15#define PP_OFFSET 1 /* Path Selection Protocol */ 18#define PP_OFFSET 1 /* Path Selection Protocol */
16#define PM_OFFSET 5 /* Path Selection Metric */ 19#define PM_OFFSET 5 /* Path Selection Metric */
17#define CC_OFFSET 9 /* Congestion Control Mode */ 20#define CC_OFFSET 9 /* Congestion Control Mode */
@@ -35,19 +38,28 @@ void ieee80211s_stop(void)
35 kmem_cache_destroy(rm_cache); 38 kmem_cache_destroy(rm_cache);
36} 39}
37 40
41static void ieee80211_mesh_housekeeping_timer(unsigned long data)
42{
43 struct ieee80211_sub_if_data *sdata = (void *) data;
44 struct ieee80211_local *local = sdata->local;
45 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
46
47 ifmsh->housekeeping = true;
48 queue_work(local->hw.workqueue, &ifmsh->work);
49}
50
38/** 51/**
39 * mesh_matches_local - check if the config of a mesh point matches ours 52 * mesh_matches_local - check if the config of a mesh point matches ours
40 * 53 *
41 * @ie: information elements of a management frame from the mesh peer 54 * @ie: information elements of a management frame from the mesh peer
42 * @dev: local mesh interface 55 * @sdata: local mesh subif
43 * 56 *
44 * This function checks if the mesh configuration of a mesh point matches the 57 * This function checks if the mesh configuration of a mesh point matches the
45 * local mesh configuration, i.e. if both nodes belong to the same mesh network. 58 * local mesh configuration, i.e. if both nodes belong to the same mesh network.
46 */ 59 */
47bool mesh_matches_local(struct ieee802_11_elems *ie, struct net_device *dev) 60bool mesh_matches_local(struct ieee802_11_elems *ie, struct ieee80211_sub_if_data *sdata)
48{ 61{
49 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 62 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
50 struct ieee80211_if_sta *sta = &sdata->u.sta;
51 63
52 /* 64 /*
53 * As support for each feature is added, check for matching 65 * As support for each feature is added, check for matching
@@ -59,11 +71,11 @@ bool mesh_matches_local(struct ieee802_11_elems *ie, struct net_device *dev)
59 * - MDA enabled 71 * - MDA enabled
60 * - Power management control on fc 72 * - Power management control on fc
61 */ 73 */
62 if (sta->mesh_id_len == ie->mesh_id_len && 74 if (ifmsh->mesh_id_len == ie->mesh_id_len &&
63 memcmp(sta->mesh_id, ie->mesh_id, ie->mesh_id_len) == 0 && 75 memcmp(ifmsh->mesh_id, ie->mesh_id, ie->mesh_id_len) == 0 &&
64 memcmp(sta->mesh_pp_id, ie->mesh_config + PP_OFFSET, 4) == 0 && 76 memcmp(ifmsh->mesh_pp_id, ie->mesh_config + PP_OFFSET, 4) == 0 &&
65 memcmp(sta->mesh_pm_id, ie->mesh_config + PM_OFFSET, 4) == 0 && 77 memcmp(ifmsh->mesh_pm_id, ie->mesh_config + PM_OFFSET, 4) == 0 &&
66 memcmp(sta->mesh_cc_id, ie->mesh_config + CC_OFFSET, 4) == 0) 78 memcmp(ifmsh->mesh_cc_id, ie->mesh_config + CC_OFFSET, 4) == 0)
67 return true; 79 return true;
68 80
69 return false; 81 return false;
@@ -73,10 +85,8 @@ bool mesh_matches_local(struct ieee802_11_elems *ie, struct net_device *dev)
73 * mesh_peer_accepts_plinks - check if an mp is willing to establish peer links 85 * mesh_peer_accepts_plinks - check if an mp is willing to establish peer links
74 * 86 *
75 * @ie: information elements of a management frame from the mesh peer 87 * @ie: information elements of a management frame from the mesh peer
76 * @dev: local mesh interface
77 */ 88 */
78bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie, 89bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie)
79 struct net_device *dev)
80{ 90{
81 return (*(ie->mesh_config + CAPAB_OFFSET) & ACCEPT_PLINKS) != 0; 91 return (*(ie->mesh_config + CAPAB_OFFSET) & ACCEPT_PLINKS) != 0;
82} 92}
@@ -98,11 +108,11 @@ void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata)
98 */ 108 */
99 free_plinks = mesh_plink_availables(sdata); 109 free_plinks = mesh_plink_availables(sdata);
100 110
101 if (free_plinks != sdata->u.sta.accepting_plinks) 111 if (free_plinks != sdata->u.mesh.accepting_plinks)
102 ieee80211_sta_timer((unsigned long) sdata); 112 ieee80211_mesh_housekeeping_timer((unsigned long) sdata);
103} 113}
104 114
105void mesh_ids_set_default(struct ieee80211_if_sta *sta) 115void mesh_ids_set_default(struct ieee80211_if_mesh *sta)
106{ 116{
107 u8 def_id[4] = {0x00, 0x0F, 0xAC, 0xff}; 117 u8 def_id[4] = {0x00, 0x0F, 0xAC, 0xff};
108 118
@@ -111,28 +121,26 @@ void mesh_ids_set_default(struct ieee80211_if_sta *sta)
111 memcpy(sta->mesh_cc_id, def_id, 4); 121 memcpy(sta->mesh_cc_id, def_id, 4);
112} 122}
113 123
114int mesh_rmc_init(struct net_device *dev) 124int mesh_rmc_init(struct ieee80211_sub_if_data *sdata)
115{ 125{
116 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
117 int i; 126 int i;
118 127
119 sdata->u.sta.rmc = kmalloc(sizeof(struct mesh_rmc), GFP_KERNEL); 128 sdata->u.mesh.rmc = kmalloc(sizeof(struct mesh_rmc), GFP_KERNEL);
120 if (!sdata->u.sta.rmc) 129 if (!sdata->u.mesh.rmc)
121 return -ENOMEM; 130 return -ENOMEM;
122 sdata->u.sta.rmc->idx_mask = RMC_BUCKETS - 1; 131 sdata->u.mesh.rmc->idx_mask = RMC_BUCKETS - 1;
123 for (i = 0; i < RMC_BUCKETS; i++) 132 for (i = 0; i < RMC_BUCKETS; i++)
124 INIT_LIST_HEAD(&sdata->u.sta.rmc->bucket[i].list); 133 INIT_LIST_HEAD(&sdata->u.mesh.rmc->bucket[i].list);
125 return 0; 134 return 0;
126} 135}
127 136
128void mesh_rmc_free(struct net_device *dev) 137void mesh_rmc_free(struct ieee80211_sub_if_data *sdata)
129{ 138{
130 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 139 struct mesh_rmc *rmc = sdata->u.mesh.rmc;
131 struct mesh_rmc *rmc = sdata->u.sta.rmc;
132 struct rmc_entry *p, *n; 140 struct rmc_entry *p, *n;
133 int i; 141 int i;
134 142
135 if (!sdata->u.sta.rmc) 143 if (!sdata->u.mesh.rmc)
136 return; 144 return;
137 145
138 for (i = 0; i < RMC_BUCKETS; i++) 146 for (i = 0; i < RMC_BUCKETS; i++)
@@ -142,7 +150,7 @@ void mesh_rmc_free(struct net_device *dev)
142 } 150 }
143 151
144 kfree(rmc); 152 kfree(rmc);
145 sdata->u.sta.rmc = NULL; 153 sdata->u.mesh.rmc = NULL;
146} 154}
147 155
148/** 156/**
@@ -158,10 +166,9 @@ void mesh_rmc_free(struct net_device *dev)
158 * it. 166 * it.
159 */ 167 */
160int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr, 168int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr,
161 struct net_device *dev) 169 struct ieee80211_sub_if_data *sdata)
162{ 170{
163 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 171 struct mesh_rmc *rmc = sdata->u.mesh.rmc;
164 struct mesh_rmc *rmc = sdata->u.sta.rmc;
165 u32 seqnum = 0; 172 u32 seqnum = 0;
166 int entries = 0; 173 int entries = 0;
167 u8 idx; 174 u8 idx;
@@ -194,10 +201,9 @@ int mesh_rmc_check(u8 *sa, struct ieee80211s_hdr *mesh_hdr,
194 return 0; 201 return 0;
195} 202}
196 203
197void mesh_mgmt_ies_add(struct sk_buff *skb, struct net_device *dev) 204void mesh_mgmt_ies_add(struct sk_buff *skb, struct ieee80211_sub_if_data *sdata)
198{ 205{
199 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 206 struct ieee80211_local *local = sdata->local;
200 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
201 struct ieee80211_supported_band *sband; 207 struct ieee80211_supported_band *sband;
202 u8 *pos; 208 u8 *pos;
203 int len, i, rate; 209 int len, i, rate;
@@ -224,11 +230,11 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct net_device *dev)
224 } 230 }
225 } 231 }
226 232
227 pos = skb_put(skb, 2 + sdata->u.sta.mesh_id_len); 233 pos = skb_put(skb, 2 + sdata->u.mesh.mesh_id_len);
228 *pos++ = WLAN_EID_MESH_ID; 234 *pos++ = WLAN_EID_MESH_ID;
229 *pos++ = sdata->u.sta.mesh_id_len; 235 *pos++ = sdata->u.mesh.mesh_id_len;
230 if (sdata->u.sta.mesh_id_len) 236 if (sdata->u.mesh.mesh_id_len)
231 memcpy(pos, sdata->u.sta.mesh_id, sdata->u.sta.mesh_id_len); 237 memcpy(pos, sdata->u.mesh.mesh_id, sdata->u.mesh.mesh_id_len);
232 238
233 pos = skb_put(skb, 21); 239 pos = skb_put(skb, 21);
234 *pos++ = WLAN_EID_MESH_CONFIG; 240 *pos++ = WLAN_EID_MESH_CONFIG;
@@ -237,15 +243,15 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct net_device *dev)
237 *pos++ = 1; 243 *pos++ = 1;
238 244
239 /* Active path selection protocol ID */ 245 /* Active path selection protocol ID */
240 memcpy(pos, sdata->u.sta.mesh_pp_id, 4); 246 memcpy(pos, sdata->u.mesh.mesh_pp_id, 4);
241 pos += 4; 247 pos += 4;
242 248
243 /* Active path selection metric ID */ 249 /* Active path selection metric ID */
244 memcpy(pos, sdata->u.sta.mesh_pm_id, 4); 250 memcpy(pos, sdata->u.mesh.mesh_pm_id, 4);
245 pos += 4; 251 pos += 4;
246 252
247 /* Congestion control mode identifier */ 253 /* Congestion control mode identifier */
248 memcpy(pos, sdata->u.sta.mesh_cc_id, 4); 254 memcpy(pos, sdata->u.mesh.mesh_cc_id, 4);
249 pos += 4; 255 pos += 4;
250 256
251 /* Channel precedence: 257 /* Channel precedence:
@@ -255,17 +261,17 @@ void mesh_mgmt_ies_add(struct sk_buff *skb, struct net_device *dev)
255 pos += 4; 261 pos += 4;
256 262
257 /* Mesh capability */ 263 /* Mesh capability */
258 sdata->u.sta.accepting_plinks = mesh_plink_availables(sdata); 264 sdata->u.mesh.accepting_plinks = mesh_plink_availables(sdata);
259 *pos++ = sdata->u.sta.accepting_plinks ? ACCEPT_PLINKS : 0x00; 265 *pos++ = sdata->u.mesh.accepting_plinks ? ACCEPT_PLINKS : 0x00;
260 *pos++ = 0x00; 266 *pos++ = 0x00;
261 267
262 return; 268 return;
263} 269}
264 270
265u32 mesh_table_hash(u8 *addr, struct net_device *dev, struct mesh_table *tbl) 271u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata, struct mesh_table *tbl)
266{ 272{
267 /* Use last four bytes of hw addr and interface index as hash index */ 273 /* Use last four bytes of hw addr and interface index as hash index */
268 return jhash_2words(*(u32 *)(addr+2), dev->ifindex, tbl->hash_rnd) 274 return jhash_2words(*(u32 *)(addr+2), sdata->dev->ifindex, tbl->hash_rnd)
269 & tbl->hash_mask; 275 & tbl->hash_mask;
270} 276}
271 277
@@ -344,10 +350,10 @@ static void ieee80211_mesh_path_timer(unsigned long data)
344{ 350{
345 struct ieee80211_sub_if_data *sdata = 351 struct ieee80211_sub_if_data *sdata =
346 (struct ieee80211_sub_if_data *) data; 352 (struct ieee80211_sub_if_data *) data;
347 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 353 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
348 struct ieee80211_local *local = wdev_priv(&sdata->wdev); 354 struct ieee80211_local *local = sdata->local;
349 355
350 queue_work(local->hw.workqueue, &ifsta->work); 356 queue_work(local->hw.workqueue, &ifmsh->work);
351} 357}
352 358
353struct mesh_table *mesh_table_grow(struct mesh_table *tbl) 359struct mesh_table *mesh_table_grow(struct mesh_table *tbl)
@@ -399,50 +405,264 @@ int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
399 struct ieee80211_sub_if_data *sdata) 405 struct ieee80211_sub_if_data *sdata)
400{ 406{
401 meshhdr->flags = 0; 407 meshhdr->flags = 0;
402 meshhdr->ttl = sdata->u.sta.mshcfg.dot11MeshTTL; 408 meshhdr->ttl = sdata->u.mesh.mshcfg.dot11MeshTTL;
403 put_unaligned(cpu_to_le32(sdata->u.sta.mesh_seqnum), &meshhdr->seqnum); 409 put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &meshhdr->seqnum);
404 sdata->u.sta.mesh_seqnum++; 410 sdata->u.mesh.mesh_seqnum++;
405 411
406 return 6; 412 return 6;
407} 413}
408 414
415static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata,
416 struct ieee80211_if_mesh *ifmsh)
417{
418 bool free_plinks;
419
420#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
421 printk(KERN_DEBUG "%s: running mesh housekeeping\n",
422 sdata->dev->name);
423#endif
424
425 ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT);
426 mesh_path_expire(sdata);
427
428 free_plinks = mesh_plink_availables(sdata);
429 if (free_plinks != sdata->u.mesh.accepting_plinks)
430 ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
431
432 ifmsh->housekeeping = false;
433 mod_timer(&ifmsh->housekeeping_timer,
434 round_jiffies(jiffies + IEEE80211_MESH_HOUSEKEEPING_INTERVAL));
435}
436
437
438void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
439{
440 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
441 struct ieee80211_local *local = sdata->local;
442
443 ifmsh->housekeeping = true;
444 queue_work(local->hw.workqueue, &ifmsh->work);
445 ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
446}
447
448void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
449{
450 del_timer_sync(&sdata->u.mesh.housekeeping_timer);
451 /*
452 * If the timer fired while we waited for it, it will have
453 * requeued the work. Now the work will be running again
454 * but will not rearm the timer again because it checks
455 * whether the interface is running, which, at this point,
456 * it no longer is.
457 */
458 cancel_work_sync(&sdata->u.mesh.work);
459
460 /*
461 * When we get here, the interface is marked down.
462 * Call synchronize_rcu() to wait for the RX path
463 * should it be using the interface and enqueuing
464 * frames at this very time on another CPU.
465 */
466 synchronize_rcu();
467 skb_queue_purge(&sdata->u.mesh.skb_queue);
468}
469
470static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
471 u16 stype,
472 struct ieee80211_mgmt *mgmt,
473 size_t len,
474 struct ieee80211_rx_status *rx_status)
475{
476 struct ieee80211_local *local= sdata->local;
477 struct ieee802_11_elems elems;
478 struct ieee80211_channel *channel;
479 u64 supp_rates = 0;
480 size_t baselen;
481 int freq;
482 enum ieee80211_band band = rx_status->band;
483
484 /* ignore ProbeResp to foreign address */
485 if (stype == IEEE80211_STYPE_PROBE_RESP &&
486 compare_ether_addr(mgmt->da, sdata->dev->dev_addr))
487 return;
488
489 baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
490 if (baselen > len)
491 return;
492
493 ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen,
494 &elems);
495
496 if (elems.ds_params && elems.ds_params_len == 1)
497 freq = ieee80211_channel_to_frequency(elems.ds_params[0]);
498 else
499 freq = rx_status->freq;
500
501 channel = ieee80211_get_channel(local->hw.wiphy, freq);
502
503 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
504 return;
505
506 if (elems.mesh_id && elems.mesh_config &&
507 mesh_matches_local(&elems, sdata)) {
508 supp_rates = ieee80211_sta_get_rates(local, &elems, band);
509
510 mesh_neighbour_update(mgmt->sa, supp_rates, sdata,
511 mesh_peer_accepts_plinks(&elems));
512 }
513}
514
515static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata,
516 struct ieee80211_mgmt *mgmt,
517 size_t len,
518 struct ieee80211_rx_status *rx_status)
519{
520 switch (mgmt->u.action.category) {
521 case PLINK_CATEGORY:
522 mesh_rx_plink_frame(sdata, mgmt, len, rx_status);
523 break;
524 case MESH_PATH_SEL_CATEGORY:
525 mesh_rx_path_sel_frame(sdata, mgmt, len);
526 break;
527 }
528}
529
530static void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
531 struct sk_buff *skb)
532{
533 struct ieee80211_rx_status *rx_status;
534 struct ieee80211_if_mesh *ifmsh;
535 struct ieee80211_mgmt *mgmt;
536 u16 stype;
537
538 ifmsh = &sdata->u.mesh;
539
540 rx_status = (struct ieee80211_rx_status *) skb->cb;
541 mgmt = (struct ieee80211_mgmt *) skb->data;
542 stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE;
543
544 switch (stype) {
545 case IEEE80211_STYPE_PROBE_RESP:
546 case IEEE80211_STYPE_BEACON:
547 ieee80211_mesh_rx_bcn_presp(sdata, stype, mgmt, skb->len,
548 rx_status);
549 break;
550 case IEEE80211_STYPE_ACTION:
551 ieee80211_mesh_rx_mgmt_action(sdata, mgmt, skb->len, rx_status);
552 break;
553 }
554
555 kfree_skb(skb);
556}
557
558static void ieee80211_mesh_work(struct work_struct *work)
559{
560 struct ieee80211_sub_if_data *sdata =
561 container_of(work, struct ieee80211_sub_if_data, u.mesh.work);
562 struct ieee80211_local *local = sdata->local;
563 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
564 struct sk_buff *skb;
565
566 if (!netif_running(sdata->dev))
567 return;
568
569 if (local->sw_scanning || local->hw_scanning)
570 return;
571
572 while ((skb = skb_dequeue(&ifmsh->skb_queue)))
573 ieee80211_mesh_rx_queued_mgmt(sdata, skb);
574
575 if (ifmsh->preq_queue_len &&
576 time_after(jiffies,
577 ifmsh->last_preq + msecs_to_jiffies(ifmsh->mshcfg.dot11MeshHWMPpreqMinInterval)))
578 mesh_path_start_discovery(sdata);
579
580 if (ifmsh->housekeeping)
581 ieee80211_mesh_housekeeping(sdata, ifmsh);
582}
583
584void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local)
585{
586 struct ieee80211_sub_if_data *sdata;
587
588 rcu_read_lock();
589 list_for_each_entry_rcu(sdata, &local->interfaces, list)
590 if (ieee80211_vif_is_mesh(&sdata->vif))
591 queue_work(local->hw.workqueue, &sdata->u.mesh.work);
592 rcu_read_unlock();
593}
594
409void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata) 595void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
410{ 596{
411 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 597 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
412 598
413 ifsta->mshcfg.dot11MeshRetryTimeout = MESH_RET_T; 599 INIT_WORK(&ifmsh->work, ieee80211_mesh_work);
414 ifsta->mshcfg.dot11MeshConfirmTimeout = MESH_CONF_T; 600 setup_timer(&ifmsh->housekeeping_timer,
415 ifsta->mshcfg.dot11MeshHoldingTimeout = MESH_HOLD_T; 601 ieee80211_mesh_housekeeping_timer,
416 ifsta->mshcfg.dot11MeshMaxRetries = MESH_MAX_RETR; 602 (unsigned long) sdata);
417 ifsta->mshcfg.dot11MeshTTL = MESH_TTL; 603 skb_queue_head_init(&sdata->u.mesh.skb_queue);
418 ifsta->mshcfg.auto_open_plinks = true; 604
419 ifsta->mshcfg.dot11MeshMaxPeerLinks = 605 ifmsh->mshcfg.dot11MeshRetryTimeout = MESH_RET_T;
606 ifmsh->mshcfg.dot11MeshConfirmTimeout = MESH_CONF_T;
607 ifmsh->mshcfg.dot11MeshHoldingTimeout = MESH_HOLD_T;
608 ifmsh->mshcfg.dot11MeshMaxRetries = MESH_MAX_RETR;
609 ifmsh->mshcfg.dot11MeshTTL = MESH_TTL;
610 ifmsh->mshcfg.auto_open_plinks = true;
611 ifmsh->mshcfg.dot11MeshMaxPeerLinks =
420 MESH_MAX_ESTAB_PLINKS; 612 MESH_MAX_ESTAB_PLINKS;
421 ifsta->mshcfg.dot11MeshHWMPactivePathTimeout = 613 ifmsh->mshcfg.dot11MeshHWMPactivePathTimeout =
422 MESH_PATH_TIMEOUT; 614 MESH_PATH_TIMEOUT;
423 ifsta->mshcfg.dot11MeshHWMPpreqMinInterval = 615 ifmsh->mshcfg.dot11MeshHWMPpreqMinInterval =
424 MESH_PREQ_MIN_INT; 616 MESH_PREQ_MIN_INT;
425 ifsta->mshcfg.dot11MeshHWMPnetDiameterTraversalTime = 617 ifmsh->mshcfg.dot11MeshHWMPnetDiameterTraversalTime =
426 MESH_DIAM_TRAVERSAL_TIME; 618 MESH_DIAM_TRAVERSAL_TIME;
427 ifsta->mshcfg.dot11MeshHWMPmaxPREQretries = 619 ifmsh->mshcfg.dot11MeshHWMPmaxPREQretries =
428 MESH_MAX_PREQ_RETRIES; 620 MESH_MAX_PREQ_RETRIES;
429 ifsta->mshcfg.path_refresh_time = 621 ifmsh->mshcfg.path_refresh_time =
430 MESH_PATH_REFRESH_TIME; 622 MESH_PATH_REFRESH_TIME;
431 ifsta->mshcfg.min_discovery_timeout = 623 ifmsh->mshcfg.min_discovery_timeout =
432 MESH_MIN_DISCOVERY_TIMEOUT; 624 MESH_MIN_DISCOVERY_TIMEOUT;
433 ifsta->accepting_plinks = true; 625 ifmsh->accepting_plinks = true;
434 ifsta->preq_id = 0; 626 ifmsh->preq_id = 0;
435 ifsta->dsn = 0; 627 ifmsh->dsn = 0;
436 atomic_set(&ifsta->mpaths, 0); 628 atomic_set(&ifmsh->mpaths, 0);
437 mesh_rmc_init(sdata->dev); 629 mesh_rmc_init(sdata);
438 ifsta->last_preq = jiffies; 630 ifmsh->last_preq = jiffies;
439 /* Allocate all mesh structures when creating the first mesh interface. */ 631 /* Allocate all mesh structures when creating the first mesh interface. */
440 if (!mesh_allocated) 632 if (!mesh_allocated)
441 ieee80211s_init(); 633 ieee80211s_init();
442 mesh_ids_set_default(ifsta); 634 mesh_ids_set_default(ifmsh);
443 setup_timer(&ifsta->mesh_path_timer, 635 setup_timer(&ifmsh->mesh_path_timer,
444 ieee80211_mesh_path_timer, 636 ieee80211_mesh_path_timer,
445 (unsigned long) sdata); 637 (unsigned long) sdata);
446 INIT_LIST_HEAD(&ifsta->preq_queue.list); 638 INIT_LIST_HEAD(&ifmsh->preq_queue.list);
447 spin_lock_init(&ifsta->mesh_preq_queue_lock); 639 spin_lock_init(&ifmsh->mesh_preq_queue_lock);
640}
641
642ieee80211_rx_result
643ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
644 struct ieee80211_rx_status *rx_status)
645{
646 struct ieee80211_local *local = sdata->local;
647 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
648 struct ieee80211_mgmt *mgmt;
649 u16 fc;
650
651 if (skb->len < 24)
652 return RX_DROP_MONITOR;
653
654 mgmt = (struct ieee80211_mgmt *) skb->data;
655 fc = le16_to_cpu(mgmt->frame_control);
656
657 switch (fc & IEEE80211_FCTL_STYPE) {
658 case IEEE80211_STYPE_PROBE_RESP:
659 case IEEE80211_STYPE_BEACON:
660 case IEEE80211_STYPE_ACTION:
661 memcpy(skb->cb, rx_status, sizeof(*rx_status));
662 skb_queue_tail(&ifmsh->skb_queue, skb);
663 queue_work(local->hw.workqueue, &ifmsh->work);
664 return RX_QUEUED;
665 }
666
667 return RX_CONTINUE;
448} 668}
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 7495fbb0d211..e10471c6ba42 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -47,7 +47,7 @@ enum mesh_path_flags {
47 * struct mesh_path - mac80211 mesh path structure 47 * struct mesh_path - mac80211 mesh path structure
48 * 48 *
49 * @dst: mesh path destination mac address 49 * @dst: mesh path destination mac address
50 * @dev: mesh path device 50 * @sdata: mesh subif
51 * @next_hop: mesh neighbor to which frames for this destination will be 51 * @next_hop: mesh neighbor to which frames for this destination will be
52 * forwarded 52 * forwarded
53 * @timer: mesh path discovery timer 53 * @timer: mesh path discovery timer
@@ -64,14 +64,15 @@ enum mesh_path_flags {
64 * @state_lock: mesh pat state lock 64 * @state_lock: mesh pat state lock
65 * 65 *
66 * 66 *
67 * The combination of dst and dev is unique in the mesh path table. Since the 67 * The combination of dst and sdata is unique in the mesh path table. Since the
68 * next_hop STA is only protected by RCU as well, deleting the STA must also 68 * next_hop STA is only protected by RCU as well, deleting the STA must also
69 * remove/substitute the mesh_path structure and wait until that is no longer 69 * remove/substitute the mesh_path structure and wait until that is no longer
70 * reachable before destroying the STA completely. 70 * reachable before destroying the STA completely.
71 */ 71 */
72struct mesh_path { 72struct mesh_path {
73 u8 dst[ETH_ALEN]; 73 u8 dst[ETH_ALEN];
74 struct net_device *dev; 74 u8 mpp[ETH_ALEN]; /* used for MPP or MAP */
75 struct ieee80211_sub_if_data *sdata;
75 struct sta_info *next_hop; 76 struct sta_info *next_hop;
76 struct timer_list timer; 77 struct timer_list timer;
77 struct sk_buff_head frame_queue; 78 struct sk_buff_head frame_queue;
@@ -203,67 +204,82 @@ int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr);
203int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr, 204int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
204 struct ieee80211_sub_if_data *sdata); 205 struct ieee80211_sub_if_data *sdata);
205int mesh_rmc_check(u8 *addr, struct ieee80211s_hdr *mesh_hdr, 206int mesh_rmc_check(u8 *addr, struct ieee80211s_hdr *mesh_hdr,
206 struct net_device *dev); 207 struct ieee80211_sub_if_data *sdata);
207bool mesh_matches_local(struct ieee802_11_elems *ie, struct net_device *dev); 208bool mesh_matches_local(struct ieee802_11_elems *ie,
208void mesh_ids_set_default(struct ieee80211_if_sta *sta); 209 struct ieee80211_sub_if_data *sdata);
209void mesh_mgmt_ies_add(struct sk_buff *skb, struct net_device *dev); 210void mesh_ids_set_default(struct ieee80211_if_mesh *mesh);
210void mesh_rmc_free(struct net_device *dev); 211void mesh_mgmt_ies_add(struct sk_buff *skb,
211int mesh_rmc_init(struct net_device *dev); 212 struct ieee80211_sub_if_data *sdata);
213void mesh_rmc_free(struct ieee80211_sub_if_data *sdata);
214int mesh_rmc_init(struct ieee80211_sub_if_data *sdata);
212void ieee80211s_init(void); 215void ieee80211s_init(void);
213void ieee80211s_stop(void); 216void ieee80211s_stop(void);
214void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata); 217void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata);
218ieee80211_rx_result
219ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
220 struct ieee80211_rx_status *rx_status);
221void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata);
222void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata);
215 223
216/* Mesh paths */ 224/* Mesh paths */
217int mesh_nexthop_lookup(struct sk_buff *skb, struct net_device *dev); 225int mesh_nexthop_lookup(struct sk_buff *skb,
218void mesh_path_start_discovery(struct net_device *dev); 226 struct ieee80211_sub_if_data *sdata);
219struct mesh_path *mesh_path_lookup(u8 *dst, struct net_device *dev); 227void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata);
220struct mesh_path *mesh_path_lookup_by_idx(int idx, struct net_device *dev); 228struct mesh_path *mesh_path_lookup(u8 *dst,
229 struct ieee80211_sub_if_data *sdata);
230struct mesh_path *mpp_path_lookup(u8 *dst,
231 struct ieee80211_sub_if_data *sdata);
232int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata);
233struct mesh_path *mesh_path_lookup_by_idx(int idx,
234 struct ieee80211_sub_if_data *sdata);
221void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop); 235void mesh_path_fix_nexthop(struct mesh_path *mpath, struct sta_info *next_hop);
222void mesh_path_expire(struct net_device *dev); 236void mesh_path_expire(struct ieee80211_sub_if_data *sdata);
223void mesh_path_flush(struct net_device *dev); 237void mesh_path_flush(struct ieee80211_sub_if_data *sdata);
224void mesh_rx_path_sel_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, 238void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata,
225 size_t len); 239 struct ieee80211_mgmt *mgmt, size_t len);
226int mesh_path_add(u8 *dst, struct net_device *dev); 240int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata);
227/* Mesh plinks */ 241/* Mesh plinks */
228void mesh_neighbour_update(u8 *hw_addr, u64 rates, struct net_device *dev, 242void mesh_neighbour_update(u8 *hw_addr, u64 rates,
229 bool add); 243 struct ieee80211_sub_if_data *sdata, bool add);
230bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie, 244bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie);
231 struct net_device *dev);
232void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata); 245void mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata);
233void mesh_plink_broken(struct sta_info *sta); 246void mesh_plink_broken(struct sta_info *sta);
234void mesh_plink_deactivate(struct sta_info *sta); 247void mesh_plink_deactivate(struct sta_info *sta);
235int mesh_plink_open(struct sta_info *sta); 248int mesh_plink_open(struct sta_info *sta);
236int mesh_plink_close(struct sta_info *sta); 249int mesh_plink_close(struct sta_info *sta);
237void mesh_plink_block(struct sta_info *sta); 250void mesh_plink_block(struct sta_info *sta);
238void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, 251void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
239 size_t len, struct ieee80211_rx_status *rx_status); 252 struct ieee80211_mgmt *mgmt, size_t len,
253 struct ieee80211_rx_status *rx_status);
240 254
241/* Private interfaces */ 255/* Private interfaces */
242/* Mesh tables */ 256/* Mesh tables */
243struct mesh_table *mesh_table_alloc(int size_order); 257struct mesh_table *mesh_table_alloc(int size_order);
244void mesh_table_free(struct mesh_table *tbl, bool free_leafs); 258void mesh_table_free(struct mesh_table *tbl, bool free_leafs);
245struct mesh_table *mesh_table_grow(struct mesh_table *tbl); 259struct mesh_table *mesh_table_grow(struct mesh_table *tbl);
246u32 mesh_table_hash(u8 *addr, struct net_device *dev, struct mesh_table *tbl); 260u32 mesh_table_hash(u8 *addr, struct ieee80211_sub_if_data *sdata,
261 struct mesh_table *tbl);
247/* Mesh paths */ 262/* Mesh paths */
248int mesh_path_error_tx(u8 *dest, __le32 dest_dsn, u8 *ra, 263int mesh_path_error_tx(u8 *dest, __le32 dest_dsn, u8 *ra,
249 struct net_device *dev); 264 struct ieee80211_sub_if_data *sdata);
250void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta); 265void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta);
251void mesh_path_flush_pending(struct mesh_path *mpath); 266void mesh_path_flush_pending(struct mesh_path *mpath);
252void mesh_path_tx_pending(struct mesh_path *mpath); 267void mesh_path_tx_pending(struct mesh_path *mpath);
253int mesh_pathtbl_init(void); 268int mesh_pathtbl_init(void);
254void mesh_pathtbl_unregister(void); 269void mesh_pathtbl_unregister(void);
255int mesh_path_del(u8 *addr, struct net_device *dev); 270int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata);
256void mesh_path_timer(unsigned long data); 271void mesh_path_timer(unsigned long data);
257void mesh_path_flush_by_nexthop(struct sta_info *sta); 272void mesh_path_flush_by_nexthop(struct sta_info *sta);
258void mesh_path_discard_frame(struct sk_buff *skb, struct net_device *dev); 273void mesh_path_discard_frame(struct sk_buff *skb,
274 struct ieee80211_sub_if_data *sdata);
259 275
260#ifdef CONFIG_MAC80211_MESH 276#ifdef CONFIG_MAC80211_MESH
261extern int mesh_allocated; 277extern int mesh_allocated;
262 278
263static inline int mesh_plink_free_count(struct ieee80211_sub_if_data *sdata) 279static inline int mesh_plink_free_count(struct ieee80211_sub_if_data *sdata)
264{ 280{
265 return sdata->u.sta.mshcfg.dot11MeshMaxPeerLinks - 281 return sdata->u.mesh.mshcfg.dot11MeshMaxPeerLinks -
266 atomic_read(&sdata->u.sta.mshstats.estab_plinks); 282 atomic_read(&sdata->u.mesh.mshstats.estab_plinks);
267} 283}
268 284
269static inline bool mesh_plink_availables(struct ieee80211_sub_if_data *sdata) 285static inline bool mesh_plink_availables(struct ieee80211_sub_if_data *sdata)
@@ -281,8 +297,12 @@ static inline void mesh_path_activate(struct mesh_path *mpath)
281 for (i = 0; i <= x->hash_mask; i++) \ 297 for (i = 0; i <= x->hash_mask; i++) \
282 hlist_for_each_entry_rcu(node, p, &x->hash_buckets[i], list) 298 hlist_for_each_entry_rcu(node, p, &x->hash_buckets[i], list)
283 299
300void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local);
301
284#else 302#else
285#define mesh_allocated 0 303#define mesh_allocated 0
304static inline void
305ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) {}
286#endif 306#endif
287 307
288#endif /* IEEE80211S_H */ 308#endif /* IEEE80211S_H */
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 08aca446ca01..501c7831adb4 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -64,14 +64,14 @@ static inline u32 u32_field_get(u8 *preq_elem, int offset, bool ae)
64#define DSN_LT(x, y) ((long) (x) - (long) (y) < 0) 64#define DSN_LT(x, y) ((long) (x) - (long) (y) < 0)
65 65
66#define net_traversal_jiffies(s) \ 66#define net_traversal_jiffies(s) \
67 msecs_to_jiffies(s->u.sta.mshcfg.dot11MeshHWMPnetDiameterTraversalTime) 67 msecs_to_jiffies(s->u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime)
68#define default_lifetime(s) \ 68#define default_lifetime(s) \
69 MSEC_TO_TU(s->u.sta.mshcfg.dot11MeshHWMPactivePathTimeout) 69 MSEC_TO_TU(s->u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout)
70#define min_preq_int_jiff(s) \ 70#define min_preq_int_jiff(s) \
71 (msecs_to_jiffies(s->u.sta.mshcfg.dot11MeshHWMPpreqMinInterval)) 71 (msecs_to_jiffies(s->u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval))
72#define max_preq_retries(s) (s->u.sta.mshcfg.dot11MeshHWMPmaxPREQretries) 72#define max_preq_retries(s) (s->u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries)
73#define disc_timeout_jiff(s) \ 73#define disc_timeout_jiff(s) \
74 msecs_to_jiffies(sdata->u.sta.mshcfg.min_discovery_timeout) 74 msecs_to_jiffies(sdata->u.mesh.mshcfg.min_discovery_timeout)
75 75
76enum mpath_frame_type { 76enum mpath_frame_type {
77 MPATH_PREQ = 0, 77 MPATH_PREQ = 0,
@@ -82,9 +82,9 @@ enum mpath_frame_type {
82static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, 82static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
83 u8 *orig_addr, __le32 orig_dsn, u8 dst_flags, u8 *dst, 83 u8 *orig_addr, __le32 orig_dsn, u8 dst_flags, u8 *dst,
84 __le32 dst_dsn, u8 *da, u8 hop_count, u8 ttl, __le32 lifetime, 84 __le32 dst_dsn, u8 *da, u8 hop_count, u8 ttl, __le32 lifetime,
85 __le32 metric, __le32 preq_id, struct net_device *dev) 85 __le32 metric, __le32 preq_id, struct ieee80211_sub_if_data *sdata)
86{ 86{
87 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 87 struct ieee80211_local *local = sdata->local;
88 struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); 88 struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
89 struct ieee80211_mgmt *mgmt; 89 struct ieee80211_mgmt *mgmt;
90 u8 *pos; 90 u8 *pos;
@@ -99,11 +99,11 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
99 mgmt = (struct ieee80211_mgmt *) 99 mgmt = (struct ieee80211_mgmt *)
100 skb_put(skb, 25 + sizeof(mgmt->u.action.u.mesh_action)); 100 skb_put(skb, 25 + sizeof(mgmt->u.action.u.mesh_action));
101 memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.mesh_action)); 101 memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.mesh_action));
102 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, 102 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
103 IEEE80211_STYPE_ACTION); 103 IEEE80211_STYPE_ACTION);
104 104
105 memcpy(mgmt->da, da, ETH_ALEN); 105 memcpy(mgmt->da, da, ETH_ALEN);
106 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); 106 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
107 /* BSSID is left zeroed, wildcard value */ 107 /* BSSID is left zeroed, wildcard value */
108 mgmt->u.action.category = MESH_PATH_SEL_CATEGORY; 108 mgmt->u.action.category = MESH_PATH_SEL_CATEGORY;
109 mgmt->u.action.u.mesh_action.action_code = action; 109 mgmt->u.action.u.mesh_action.action_code = action;
@@ -149,7 +149,7 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
149 pos += ETH_ALEN; 149 pos += ETH_ALEN;
150 memcpy(pos, &dst_dsn, 4); 150 memcpy(pos, &dst_dsn, 4);
151 151
152 ieee80211_sta_tx(dev, skb, 0); 152 ieee80211_tx_skb(sdata, skb, 0);
153 return 0; 153 return 0;
154} 154}
155 155
@@ -161,9 +161,9 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags,
161 * @ra: node this frame is addressed to 161 * @ra: node this frame is addressed to
162 */ 162 */
163int mesh_path_error_tx(u8 *dst, __le32 dst_dsn, u8 *ra, 163int mesh_path_error_tx(u8 *dst, __le32 dst_dsn, u8 *ra,
164 struct net_device *dev) 164 struct ieee80211_sub_if_data *sdata)
165{ 165{
166 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 166 struct ieee80211_local *local = sdata->local;
167 struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); 167 struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
168 struct ieee80211_mgmt *mgmt; 168 struct ieee80211_mgmt *mgmt;
169 u8 *pos; 169 u8 *pos;
@@ -178,11 +178,11 @@ int mesh_path_error_tx(u8 *dst, __le32 dst_dsn, u8 *ra,
178 mgmt = (struct ieee80211_mgmt *) 178 mgmt = (struct ieee80211_mgmt *)
179 skb_put(skb, 25 + sizeof(mgmt->u.action.u.mesh_action)); 179 skb_put(skb, 25 + sizeof(mgmt->u.action.u.mesh_action));
180 memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.mesh_action)); 180 memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.mesh_action));
181 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, 181 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
182 IEEE80211_STYPE_ACTION); 182 IEEE80211_STYPE_ACTION);
183 183
184 memcpy(mgmt->da, ra, ETH_ALEN); 184 memcpy(mgmt->da, ra, ETH_ALEN);
185 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); 185 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
186 /* BSSID is left zeroed, wildcard value */ 186 /* BSSID is left zeroed, wildcard value */
187 mgmt->u.action.category = MESH_PATH_SEL_CATEGORY; 187 mgmt->u.action.category = MESH_PATH_SEL_CATEGORY;
188 mgmt->u.action.u.mesh_action.action_code = MPATH_PERR; 188 mgmt->u.action.u.mesh_action.action_code = MPATH_PERR;
@@ -198,7 +198,7 @@ int mesh_path_error_tx(u8 *dst, __le32 dst_dsn, u8 *ra,
198 pos += ETH_ALEN; 198 pos += ETH_ALEN;
199 memcpy(pos, &dst_dsn, 4); 199 memcpy(pos, &dst_dsn, 4);
200 200
201 ieee80211_sta_tx(dev, skb, 0); 201 ieee80211_tx_skb(sdata, skb, 0);
202 return 0; 202 return 0;
203} 203}
204 204
@@ -223,7 +223,7 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
223 /* bitrate is in units of 100 Kbps, while we need rate in units of 223 /* bitrate is in units of 100 Kbps, while we need rate in units of
224 * 1Mbps. This will be corrected on tx_time computation. 224 * 1Mbps. This will be corrected on tx_time computation.
225 */ 225 */
226 rate = sband->bitrates[sta->txrate_idx].bitrate; 226 rate = sband->bitrates[sta->last_txrate_idx].bitrate;
227 tx_time = (device_constant + 10 * test_frame_len / rate); 227 tx_time = (device_constant + 10 * test_frame_len / rate);
228 estimated_retx = ((1 << (2 * ARITH_SHIFT)) / (s_unit - err)); 228 estimated_retx = ((1 << (2 * ARITH_SHIFT)) / (s_unit - err));
229 result = (tx_time * estimated_retx) >> (2 * ARITH_SHIFT) ; 229 result = (tx_time * estimated_retx) >> (2 * ARITH_SHIFT) ;
@@ -233,7 +233,7 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
233/** 233/**
234 * hwmp_route_info_get - Update routing info to originator and transmitter 234 * hwmp_route_info_get - Update routing info to originator and transmitter
235 * 235 *
236 * @dev: local mesh interface 236 * @sdata: local mesh subif
237 * @mgmt: mesh management frame 237 * @mgmt: mesh management frame
238 * @hwmp_ie: hwmp information element (PREP or PREQ) 238 * @hwmp_ie: hwmp information element (PREP or PREQ)
239 * 239 *
@@ -246,11 +246,11 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local,
246 * Notes: this function is the only place (besides user-provided info) where 246 * Notes: this function is the only place (besides user-provided info) where
247 * path routing information is updated. 247 * path routing information is updated.
248 */ 248 */
249static u32 hwmp_route_info_get(struct net_device *dev, 249static u32 hwmp_route_info_get(struct ieee80211_sub_if_data *sdata,
250 struct ieee80211_mgmt *mgmt, 250 struct ieee80211_mgmt *mgmt,
251 u8 *hwmp_ie) 251 u8 *hwmp_ie)
252{ 252{
253 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 253 struct ieee80211_local *local = sdata->local;
254 struct mesh_path *mpath; 254 struct mesh_path *mpath;
255 struct sta_info *sta; 255 struct sta_info *sta;
256 bool fresh_info; 256 bool fresh_info;
@@ -301,14 +301,14 @@ static u32 hwmp_route_info_get(struct net_device *dev,
301 new_metric = MAX_METRIC; 301 new_metric = MAX_METRIC;
302 exp_time = TU_TO_EXP_TIME(orig_lifetime); 302 exp_time = TU_TO_EXP_TIME(orig_lifetime);
303 303
304 if (memcmp(orig_addr, dev->dev_addr, ETH_ALEN) == 0) { 304 if (memcmp(orig_addr, sdata->dev->dev_addr, ETH_ALEN) == 0) {
305 /* This MP is the originator, we are not interested in this 305 /* This MP is the originator, we are not interested in this
306 * frame, except for updating transmitter's path info. 306 * frame, except for updating transmitter's path info.
307 */ 307 */
308 process = false; 308 process = false;
309 fresh_info = false; 309 fresh_info = false;
310 } else { 310 } else {
311 mpath = mesh_path_lookup(orig_addr, dev); 311 mpath = mesh_path_lookup(orig_addr, sdata);
312 if (mpath) { 312 if (mpath) {
313 spin_lock_bh(&mpath->state_lock); 313 spin_lock_bh(&mpath->state_lock);
314 if (mpath->flags & MESH_PATH_FIXED) 314 if (mpath->flags & MESH_PATH_FIXED)
@@ -324,8 +324,8 @@ static u32 hwmp_route_info_get(struct net_device *dev,
324 } 324 }
325 } 325 }
326 } else { 326 } else {
327 mesh_path_add(orig_addr, dev); 327 mesh_path_add(orig_addr, sdata);
328 mpath = mesh_path_lookup(orig_addr, dev); 328 mpath = mesh_path_lookup(orig_addr, sdata);
329 if (!mpath) { 329 if (!mpath) {
330 rcu_read_unlock(); 330 rcu_read_unlock();
331 return 0; 331 return 0;
@@ -357,7 +357,7 @@ static u32 hwmp_route_info_get(struct net_device *dev,
357 else { 357 else {
358 fresh_info = true; 358 fresh_info = true;
359 359
360 mpath = mesh_path_lookup(ta, dev); 360 mpath = mesh_path_lookup(ta, sdata);
361 if (mpath) { 361 if (mpath) {
362 spin_lock_bh(&mpath->state_lock); 362 spin_lock_bh(&mpath->state_lock);
363 if ((mpath->flags & MESH_PATH_FIXED) || 363 if ((mpath->flags & MESH_PATH_FIXED) ||
@@ -365,8 +365,8 @@ static u32 hwmp_route_info_get(struct net_device *dev,
365 (last_hop_metric > mpath->metric))) 365 (last_hop_metric > mpath->metric)))
366 fresh_info = false; 366 fresh_info = false;
367 } else { 367 } else {
368 mesh_path_add(ta, dev); 368 mesh_path_add(ta, sdata);
369 mpath = mesh_path_lookup(ta, dev); 369 mpath = mesh_path_lookup(ta, sdata);
370 if (!mpath) { 370 if (!mpath) {
371 rcu_read_unlock(); 371 rcu_read_unlock();
372 return 0; 372 return 0;
@@ -392,11 +392,10 @@ static u32 hwmp_route_info_get(struct net_device *dev,
392 return process ? new_metric : 0; 392 return process ? new_metric : 0;
393} 393}
394 394
395static void hwmp_preq_frame_process(struct net_device *dev, 395static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata,
396 struct ieee80211_mgmt *mgmt, 396 struct ieee80211_mgmt *mgmt,
397 u8 *preq_elem, u32 metric) { 397 u8 *preq_elem, u32 metric) {
398 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 398 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
399 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
400 struct mesh_path *mpath; 399 struct mesh_path *mpath;
401 u8 *dst_addr, *orig_addr; 400 u8 *dst_addr, *orig_addr;
402 u8 dst_flags, ttl; 401 u8 dst_flags, ttl;
@@ -411,19 +410,19 @@ static void hwmp_preq_frame_process(struct net_device *dev,
411 orig_dsn = PREQ_IE_ORIG_DSN(preq_elem); 410 orig_dsn = PREQ_IE_ORIG_DSN(preq_elem);
412 dst_flags = PREQ_IE_DST_F(preq_elem); 411 dst_flags = PREQ_IE_DST_F(preq_elem);
413 412
414 if (memcmp(dst_addr, dev->dev_addr, ETH_ALEN) == 0) { 413 if (memcmp(dst_addr, sdata->dev->dev_addr, ETH_ALEN) == 0) {
415 forward = false; 414 forward = false;
416 reply = true; 415 reply = true;
417 metric = 0; 416 metric = 0;
418 if (time_after(jiffies, ifsta->last_dsn_update + 417 if (time_after(jiffies, ifmsh->last_dsn_update +
419 net_traversal_jiffies(sdata)) || 418 net_traversal_jiffies(sdata)) ||
420 time_before(jiffies, ifsta->last_dsn_update)) { 419 time_before(jiffies, ifmsh->last_dsn_update)) {
421 dst_dsn = ++ifsta->dsn; 420 dst_dsn = ++ifmsh->dsn;
422 ifsta->last_dsn_update = jiffies; 421 ifmsh->last_dsn_update = jiffies;
423 } 422 }
424 } else { 423 } else {
425 rcu_read_lock(); 424 rcu_read_lock();
426 mpath = mesh_path_lookup(dst_addr, dev); 425 mpath = mesh_path_lookup(dst_addr, sdata);
427 if (mpath) { 426 if (mpath) {
428 if ((!(mpath->flags & MESH_PATH_DSN_VALID)) || 427 if ((!(mpath->flags & MESH_PATH_DSN_VALID)) ||
429 DSN_LT(mpath->dsn, dst_dsn)) { 428 DSN_LT(mpath->dsn, dst_dsn)) {
@@ -445,15 +444,15 @@ static void hwmp_preq_frame_process(struct net_device *dev,
445 444
446 if (reply) { 445 if (reply) {
447 lifetime = PREQ_IE_LIFETIME(preq_elem); 446 lifetime = PREQ_IE_LIFETIME(preq_elem);
448 ttl = ifsta->mshcfg.dot11MeshTTL; 447 ttl = ifmsh->mshcfg.dot11MeshTTL;
449 if (ttl != 0) 448 if (ttl != 0)
450 mesh_path_sel_frame_tx(MPATH_PREP, 0, dst_addr, 449 mesh_path_sel_frame_tx(MPATH_PREP, 0, dst_addr,
451 cpu_to_le32(dst_dsn), 0, orig_addr, 450 cpu_to_le32(dst_dsn), 0, orig_addr,
452 cpu_to_le32(orig_dsn), mgmt->sa, 0, ttl, 451 cpu_to_le32(orig_dsn), mgmt->sa, 0, ttl,
453 cpu_to_le32(lifetime), cpu_to_le32(metric), 452 cpu_to_le32(lifetime), cpu_to_le32(metric),
454 0, dev); 453 0, sdata);
455 else 454 else
456 ifsta->mshstats.dropped_frames_ttl++; 455 ifmsh->mshstats.dropped_frames_ttl++;
457 } 456 }
458 457
459 if (forward) { 458 if (forward) {
@@ -463,7 +462,7 @@ static void hwmp_preq_frame_process(struct net_device *dev,
463 ttl = PREQ_IE_TTL(preq_elem); 462 ttl = PREQ_IE_TTL(preq_elem);
464 lifetime = PREQ_IE_LIFETIME(preq_elem); 463 lifetime = PREQ_IE_LIFETIME(preq_elem);
465 if (ttl <= 1) { 464 if (ttl <= 1) {
466 ifsta->mshstats.dropped_frames_ttl++; 465 ifmsh->mshstats.dropped_frames_ttl++;
467 return; 466 return;
468 } 467 }
469 --ttl; 468 --ttl;
@@ -472,20 +471,19 @@ static void hwmp_preq_frame_process(struct net_device *dev,
472 hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1; 471 hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1;
473 mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr, 472 mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr,
474 cpu_to_le32(orig_dsn), dst_flags, dst_addr, 473 cpu_to_le32(orig_dsn), dst_flags, dst_addr,
475 cpu_to_le32(dst_dsn), dev->broadcast, 474 cpu_to_le32(dst_dsn), sdata->dev->broadcast,
476 hopcount, ttl, cpu_to_le32(lifetime), 475 hopcount, ttl, cpu_to_le32(lifetime),
477 cpu_to_le32(metric), cpu_to_le32(preq_id), 476 cpu_to_le32(metric), cpu_to_le32(preq_id),
478 dev); 477 sdata);
479 ifsta->mshstats.fwded_frames++; 478 ifmsh->mshstats.fwded_frames++;
480 } 479 }
481} 480}
482 481
483 482
484static void hwmp_prep_frame_process(struct net_device *dev, 483static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata,
485 struct ieee80211_mgmt *mgmt, 484 struct ieee80211_mgmt *mgmt,
486 u8 *prep_elem, u32 metric) 485 u8 *prep_elem, u32 metric)
487{ 486{
488 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
489 struct mesh_path *mpath; 487 struct mesh_path *mpath;
490 u8 *dst_addr, *orig_addr; 488 u8 *dst_addr, *orig_addr;
491 u8 ttl, hopcount, flags; 489 u8 ttl, hopcount, flags;
@@ -499,18 +497,18 @@ static void hwmp_prep_frame_process(struct net_device *dev,
499 * replies 497 * replies
500 */ 498 */
501 dst_addr = PREP_IE_DST_ADDR(prep_elem); 499 dst_addr = PREP_IE_DST_ADDR(prep_elem);
502 if (memcmp(dst_addr, dev->dev_addr, ETH_ALEN) == 0) 500 if (memcmp(dst_addr, sdata->dev->dev_addr, ETH_ALEN) == 0)
503 /* destination, no forwarding required */ 501 /* destination, no forwarding required */
504 return; 502 return;
505 503
506 ttl = PREP_IE_TTL(prep_elem); 504 ttl = PREP_IE_TTL(prep_elem);
507 if (ttl <= 1) { 505 if (ttl <= 1) {
508 sdata->u.sta.mshstats.dropped_frames_ttl++; 506 sdata->u.mesh.mshstats.dropped_frames_ttl++;
509 return; 507 return;
510 } 508 }
511 509
512 rcu_read_lock(); 510 rcu_read_lock();
513 mpath = mesh_path_lookup(dst_addr, dev); 511 mpath = mesh_path_lookup(dst_addr, sdata);
514 if (mpath) 512 if (mpath)
515 spin_lock_bh(&mpath->state_lock); 513 spin_lock_bh(&mpath->state_lock);
516 else 514 else
@@ -519,7 +517,7 @@ static void hwmp_prep_frame_process(struct net_device *dev,
519 spin_unlock_bh(&mpath->state_lock); 517 spin_unlock_bh(&mpath->state_lock);
520 goto fail; 518 goto fail;
521 } 519 }
522 memcpy(next_hop, mpath->next_hop->addr, ETH_ALEN); 520 memcpy(next_hop, mpath->next_hop->sta.addr, ETH_ALEN);
523 spin_unlock_bh(&mpath->state_lock); 521 spin_unlock_bh(&mpath->state_lock);
524 --ttl; 522 --ttl;
525 flags = PREP_IE_FLAGS(prep_elem); 523 flags = PREP_IE_FLAGS(prep_elem);
@@ -531,20 +529,20 @@ static void hwmp_prep_frame_process(struct net_device *dev,
531 529
532 mesh_path_sel_frame_tx(MPATH_PREP, flags, orig_addr, 530 mesh_path_sel_frame_tx(MPATH_PREP, flags, orig_addr,
533 cpu_to_le32(orig_dsn), 0, dst_addr, 531 cpu_to_le32(orig_dsn), 0, dst_addr,
534 cpu_to_le32(dst_dsn), mpath->next_hop->addr, hopcount, ttl, 532 cpu_to_le32(dst_dsn), mpath->next_hop->sta.addr, hopcount, ttl,
535 cpu_to_le32(lifetime), cpu_to_le32(metric), 533 cpu_to_le32(lifetime), cpu_to_le32(metric),
536 0, dev); 534 0, sdata);
537 rcu_read_unlock(); 535 rcu_read_unlock();
538 sdata->u.sta.mshstats.fwded_frames++; 536 sdata->u.mesh.mshstats.fwded_frames++;
539 return; 537 return;
540 538
541fail: 539fail:
542 rcu_read_unlock(); 540 rcu_read_unlock();
543 sdata->u.sta.mshstats.dropped_frames_no_route++; 541 sdata->u.mesh.mshstats.dropped_frames_no_route++;
544 return; 542 return;
545} 543}
546 544
547static void hwmp_perr_frame_process(struct net_device *dev, 545static void hwmp_perr_frame_process(struct ieee80211_sub_if_data *sdata,
548 struct ieee80211_mgmt *mgmt, u8 *perr_elem) 546 struct ieee80211_mgmt *mgmt, u8 *perr_elem)
549{ 547{
550 struct mesh_path *mpath; 548 struct mesh_path *mpath;
@@ -555,18 +553,18 @@ static void hwmp_perr_frame_process(struct net_device *dev,
555 dst_addr = PERR_IE_DST_ADDR(perr_elem); 553 dst_addr = PERR_IE_DST_ADDR(perr_elem);
556 dst_dsn = PERR_IE_DST_DSN(perr_elem); 554 dst_dsn = PERR_IE_DST_DSN(perr_elem);
557 rcu_read_lock(); 555 rcu_read_lock();
558 mpath = mesh_path_lookup(dst_addr, dev); 556 mpath = mesh_path_lookup(dst_addr, sdata);
559 if (mpath) { 557 if (mpath) {
560 spin_lock_bh(&mpath->state_lock); 558 spin_lock_bh(&mpath->state_lock);
561 if (mpath->flags & MESH_PATH_ACTIVE && 559 if (mpath->flags & MESH_PATH_ACTIVE &&
562 memcmp(ta, mpath->next_hop->addr, ETH_ALEN) == 0 && 560 memcmp(ta, mpath->next_hop->sta.addr, ETH_ALEN) == 0 &&
563 (!(mpath->flags & MESH_PATH_DSN_VALID) || 561 (!(mpath->flags & MESH_PATH_DSN_VALID) ||
564 DSN_GT(dst_dsn, mpath->dsn))) { 562 DSN_GT(dst_dsn, mpath->dsn))) {
565 mpath->flags &= ~MESH_PATH_ACTIVE; 563 mpath->flags &= ~MESH_PATH_ACTIVE;
566 mpath->dsn = dst_dsn; 564 mpath->dsn = dst_dsn;
567 spin_unlock_bh(&mpath->state_lock); 565 spin_unlock_bh(&mpath->state_lock);
568 mesh_path_error_tx(dst_addr, cpu_to_le32(dst_dsn), 566 mesh_path_error_tx(dst_addr, cpu_to_le32(dst_dsn),
569 dev->broadcast, dev); 567 sdata->dev->broadcast, sdata);
570 } else 568 } else
571 spin_unlock_bh(&mpath->state_lock); 569 spin_unlock_bh(&mpath->state_lock);
572 } 570 }
@@ -575,7 +573,7 @@ static void hwmp_perr_frame_process(struct net_device *dev,
575 573
576 574
577 575
578void mesh_rx_path_sel_frame(struct net_device *dev, 576void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata,
579 struct ieee80211_mgmt *mgmt, 577 struct ieee80211_mgmt *mgmt,
580 size_t len) 578 size_t len)
581{ 579{
@@ -583,6 +581,10 @@ void mesh_rx_path_sel_frame(struct net_device *dev,
583 size_t baselen; 581 size_t baselen;
584 u32 last_hop_metric; 582 u32 last_hop_metric;
585 583
584 /* need action_code */
585 if (len < IEEE80211_MIN_ACTION_SIZE + 1)
586 return;
587
586 baselen = (u8 *) mgmt->u.action.u.mesh_action.variable - (u8 *) mgmt; 588 baselen = (u8 *) mgmt->u.action.u.mesh_action.variable - (u8 *) mgmt;
587 ieee802_11_parse_elems(mgmt->u.action.u.mesh_action.variable, 589 ieee802_11_parse_elems(mgmt->u.action.u.mesh_action.variable,
588 len - baselen, &elems); 590 len - baselen, &elems);
@@ -592,25 +594,25 @@ void mesh_rx_path_sel_frame(struct net_device *dev,
592 if (!elems.preq || elems.preq_len != 37) 594 if (!elems.preq || elems.preq_len != 37)
593 /* Right now we support just 1 destination and no AE */ 595 /* Right now we support just 1 destination and no AE */
594 return; 596 return;
595 last_hop_metric = hwmp_route_info_get(dev, mgmt, elems.preq); 597 last_hop_metric = hwmp_route_info_get(sdata, mgmt, elems.preq);
596 if (!last_hop_metric) 598 if (!last_hop_metric)
597 return; 599 return;
598 hwmp_preq_frame_process(dev, mgmt, elems.preq, last_hop_metric); 600 hwmp_preq_frame_process(sdata, mgmt, elems.preq, last_hop_metric);
599 break; 601 break;
600 case MPATH_PREP: 602 case MPATH_PREP:
601 if (!elems.prep || elems.prep_len != 31) 603 if (!elems.prep || elems.prep_len != 31)
602 /* Right now we support no AE */ 604 /* Right now we support no AE */
603 return; 605 return;
604 last_hop_metric = hwmp_route_info_get(dev, mgmt, elems.prep); 606 last_hop_metric = hwmp_route_info_get(sdata, mgmt, elems.prep);
605 if (!last_hop_metric) 607 if (!last_hop_metric)
606 return; 608 return;
607 hwmp_prep_frame_process(dev, mgmt, elems.prep, last_hop_metric); 609 hwmp_prep_frame_process(sdata, mgmt, elems.prep, last_hop_metric);
608 break; 610 break;
609 case MPATH_PERR: 611 case MPATH_PERR:
610 if (!elems.perr || elems.perr_len != 12) 612 if (!elems.perr || elems.perr_len != 12)
611 /* Right now we support only one destination per PERR */ 613 /* Right now we support only one destination per PERR */
612 return; 614 return;
613 hwmp_perr_frame_process(dev, mgmt, elems.perr); 615 hwmp_perr_frame_process(sdata, mgmt, elems.perr);
614 default: 616 default:
615 return; 617 return;
616 } 618 }
@@ -628,9 +630,8 @@ void mesh_rx_path_sel_frame(struct net_device *dev,
628 */ 630 */
629static void mesh_queue_preq(struct mesh_path *mpath, u8 flags) 631static void mesh_queue_preq(struct mesh_path *mpath, u8 flags)
630{ 632{
631 struct ieee80211_sub_if_data *sdata = 633 struct ieee80211_sub_if_data *sdata = mpath->sdata;
632 IEEE80211_DEV_TO_SUB_IF(mpath->dev); 634 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
633 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
634 struct mesh_preq_queue *preq_node; 635 struct mesh_preq_queue *preq_node;
635 636
636 preq_node = kmalloc(sizeof(struct mesh_preq_queue), GFP_KERNEL); 637 preq_node = kmalloc(sizeof(struct mesh_preq_queue), GFP_KERNEL);
@@ -639,9 +640,9 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags)
639 return; 640 return;
640 } 641 }
641 642
642 spin_lock(&ifsta->mesh_preq_queue_lock); 643 spin_lock(&ifmsh->mesh_preq_queue_lock);
643 if (ifsta->preq_queue_len == MAX_PREQ_QUEUE_LEN) { 644 if (ifmsh->preq_queue_len == MAX_PREQ_QUEUE_LEN) {
644 spin_unlock(&ifsta->mesh_preq_queue_lock); 645 spin_unlock(&ifmsh->mesh_preq_queue_lock);
645 kfree(preq_node); 646 kfree(preq_node);
646 if (printk_ratelimit()) 647 if (printk_ratelimit())
647 printk(KERN_DEBUG "Mesh HWMP: PREQ node queue full\n"); 648 printk(KERN_DEBUG "Mesh HWMP: PREQ node queue full\n");
@@ -651,55 +652,53 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags)
651 memcpy(preq_node->dst, mpath->dst, ETH_ALEN); 652 memcpy(preq_node->dst, mpath->dst, ETH_ALEN);
652 preq_node->flags = flags; 653 preq_node->flags = flags;
653 654
654 list_add_tail(&preq_node->list, &ifsta->preq_queue.list); 655 list_add_tail(&preq_node->list, &ifmsh->preq_queue.list);
655 ++ifsta->preq_queue_len; 656 ++ifmsh->preq_queue_len;
656 spin_unlock(&ifsta->mesh_preq_queue_lock); 657 spin_unlock(&ifmsh->mesh_preq_queue_lock);
657 658
658 if (time_after(jiffies, ifsta->last_preq + min_preq_int_jiff(sdata))) 659 if (time_after(jiffies, ifmsh->last_preq + min_preq_int_jiff(sdata)))
659 queue_work(sdata->local->hw.workqueue, &ifsta->work); 660 queue_work(sdata->local->hw.workqueue, &ifmsh->work);
660 661
661 else if (time_before(jiffies, ifsta->last_preq)) { 662 else if (time_before(jiffies, ifmsh->last_preq)) {
662 /* avoid long wait if did not send preqs for a long time 663 /* avoid long wait if did not send preqs for a long time
663 * and jiffies wrapped around 664 * and jiffies wrapped around
664 */ 665 */
665 ifsta->last_preq = jiffies - min_preq_int_jiff(sdata) - 1; 666 ifmsh->last_preq = jiffies - min_preq_int_jiff(sdata) - 1;
666 queue_work(sdata->local->hw.workqueue, &ifsta->work); 667 queue_work(sdata->local->hw.workqueue, &ifmsh->work);
667 } else 668 } else
668 mod_timer(&ifsta->mesh_path_timer, ifsta->last_preq + 669 mod_timer(&ifmsh->mesh_path_timer, ifmsh->last_preq +
669 min_preq_int_jiff(sdata)); 670 min_preq_int_jiff(sdata));
670} 671}
671 672
672/** 673/**
673 * mesh_path_start_discovery - launch a path discovery from the PREQ queue 674 * mesh_path_start_discovery - launch a path discovery from the PREQ queue
674 * 675 *
675 * @dev: local mesh interface 676 * @sdata: local mesh subif
676 */ 677 */
677void mesh_path_start_discovery(struct net_device *dev) 678void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata)
678{ 679{
679 struct ieee80211_sub_if_data *sdata = 680 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
680 IEEE80211_DEV_TO_SUB_IF(dev);
681 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
682 struct mesh_preq_queue *preq_node; 681 struct mesh_preq_queue *preq_node;
683 struct mesh_path *mpath; 682 struct mesh_path *mpath;
684 u8 ttl, dst_flags; 683 u8 ttl, dst_flags;
685 u32 lifetime; 684 u32 lifetime;
686 685
687 spin_lock(&ifsta->mesh_preq_queue_lock); 686 spin_lock(&ifmsh->mesh_preq_queue_lock);
688 if (!ifsta->preq_queue_len || 687 if (!ifmsh->preq_queue_len ||
689 time_before(jiffies, ifsta->last_preq + 688 time_before(jiffies, ifmsh->last_preq +
690 min_preq_int_jiff(sdata))) { 689 min_preq_int_jiff(sdata))) {
691 spin_unlock(&ifsta->mesh_preq_queue_lock); 690 spin_unlock(&ifmsh->mesh_preq_queue_lock);
692 return; 691 return;
693 } 692 }
694 693
695 preq_node = list_first_entry(&ifsta->preq_queue.list, 694 preq_node = list_first_entry(&ifmsh->preq_queue.list,
696 struct mesh_preq_queue, list); 695 struct mesh_preq_queue, list);
697 list_del(&preq_node->list); 696 list_del(&preq_node->list);
698 --ifsta->preq_queue_len; 697 --ifmsh->preq_queue_len;
699 spin_unlock(&ifsta->mesh_preq_queue_lock); 698 spin_unlock(&ifmsh->mesh_preq_queue_lock);
700 699
701 rcu_read_lock(); 700 rcu_read_lock();
702 mpath = mesh_path_lookup(preq_node->dst, dev); 701 mpath = mesh_path_lookup(preq_node->dst, sdata);
703 if (!mpath) 702 if (!mpath)
704 goto enddiscovery; 703 goto enddiscovery;
705 704
@@ -721,18 +720,18 @@ void mesh_path_start_discovery(struct net_device *dev)
721 goto enddiscovery; 720 goto enddiscovery;
722 } 721 }
723 722
724 ifsta->last_preq = jiffies; 723 ifmsh->last_preq = jiffies;
725 724
726 if (time_after(jiffies, ifsta->last_dsn_update + 725 if (time_after(jiffies, ifmsh->last_dsn_update +
727 net_traversal_jiffies(sdata)) || 726 net_traversal_jiffies(sdata)) ||
728 time_before(jiffies, ifsta->last_dsn_update)) { 727 time_before(jiffies, ifmsh->last_dsn_update)) {
729 ++ifsta->dsn; 728 ++ifmsh->dsn;
730 sdata->u.sta.last_dsn_update = jiffies; 729 sdata->u.mesh.last_dsn_update = jiffies;
731 } 730 }
732 lifetime = default_lifetime(sdata); 731 lifetime = default_lifetime(sdata);
733 ttl = sdata->u.sta.mshcfg.dot11MeshTTL; 732 ttl = sdata->u.mesh.mshcfg.dot11MeshTTL;
734 if (ttl == 0) { 733 if (ttl == 0) {
735 sdata->u.sta.mshstats.dropped_frames_ttl++; 734 sdata->u.mesh.mshstats.dropped_frames_ttl++;
736 spin_unlock_bh(&mpath->state_lock); 735 spin_unlock_bh(&mpath->state_lock);
737 goto enddiscovery; 736 goto enddiscovery;
738 } 737 }
@@ -743,11 +742,11 @@ void mesh_path_start_discovery(struct net_device *dev)
743 dst_flags = MP_F_RF; 742 dst_flags = MP_F_RF;
744 743
745 spin_unlock_bh(&mpath->state_lock); 744 spin_unlock_bh(&mpath->state_lock);
746 mesh_path_sel_frame_tx(MPATH_PREQ, 0, dev->dev_addr, 745 mesh_path_sel_frame_tx(MPATH_PREQ, 0, sdata->dev->dev_addr,
747 cpu_to_le32(ifsta->dsn), dst_flags, mpath->dst, 746 cpu_to_le32(ifmsh->dsn), dst_flags, mpath->dst,
748 cpu_to_le32(mpath->dsn), dev->broadcast, 0, 747 cpu_to_le32(mpath->dsn), sdata->dev->broadcast, 0,
749 ttl, cpu_to_le32(lifetime), 0, 748 ttl, cpu_to_le32(lifetime), 0,
750 cpu_to_le32(ifsta->preq_id++), dev); 749 cpu_to_le32(ifmsh->preq_id++), sdata);
751 mod_timer(&mpath->timer, jiffies + mpath->discovery_timeout); 750 mod_timer(&mpath->timer, jiffies + mpath->discovery_timeout);
752 751
753enddiscovery: 752enddiscovery:
@@ -759,7 +758,7 @@ enddiscovery:
759 * ieee80211s_lookup_nexthop - put the appropriate next hop on a mesh frame 758 * ieee80211s_lookup_nexthop - put the appropriate next hop on a mesh frame
760 * 759 *
761 * @skb: 802.11 frame to be sent 760 * @skb: 802.11 frame to be sent
762 * @dev: network device the frame will be sent through 761 * @sdata: network subif the frame will be sent through
763 * @fwd_frame: true if this frame was originally from a different host 762 * @fwd_frame: true if this frame was originally from a different host
764 * 763 *
765 * Returns: 0 if the next hop was found. Nonzero otherwise. If no next hop is 764 * Returns: 0 if the next hop was found. Nonzero otherwise. If no next hop is
@@ -767,9 +766,9 @@ enddiscovery:
767 * sent when the path is resolved. This means the caller must not free the skb 766 * sent when the path is resolved. This means the caller must not free the skb
768 * in this case. 767 * in this case.
769 */ 768 */
770int mesh_nexthop_lookup(struct sk_buff *skb, struct net_device *dev) 769int mesh_nexthop_lookup(struct sk_buff *skb,
770 struct ieee80211_sub_if_data *sdata)
771{ 771{
772 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
773 struct sk_buff *skb_to_free = NULL; 772 struct sk_buff *skb_to_free = NULL;
774 struct mesh_path *mpath; 773 struct mesh_path *mpath;
775 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 774 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
@@ -777,14 +776,14 @@ int mesh_nexthop_lookup(struct sk_buff *skb, struct net_device *dev)
777 int err = 0; 776 int err = 0;
778 777
779 rcu_read_lock(); 778 rcu_read_lock();
780 mpath = mesh_path_lookup(dst_addr, dev); 779 mpath = mesh_path_lookup(dst_addr, sdata);
781 780
782 if (!mpath) { 781 if (!mpath) {
783 mesh_path_add(dst_addr, dev); 782 mesh_path_add(dst_addr, sdata);
784 mpath = mesh_path_lookup(dst_addr, dev); 783 mpath = mesh_path_lookup(dst_addr, sdata);
785 if (!mpath) { 784 if (!mpath) {
786 dev_kfree_skb(skb); 785 dev_kfree_skb(skb);
787 sdata->u.sta.mshstats.dropped_frames_no_route++; 786 sdata->u.mesh.mshstats.dropped_frames_no_route++;
788 err = -ENOSPC; 787 err = -ENOSPC;
789 goto endlookup; 788 goto endlookup;
790 } 789 }
@@ -792,14 +791,15 @@ int mesh_nexthop_lookup(struct sk_buff *skb, struct net_device *dev)
792 791
793 if (mpath->flags & MESH_PATH_ACTIVE) { 792 if (mpath->flags & MESH_PATH_ACTIVE) {
794 if (time_after(jiffies, mpath->exp_time - 793 if (time_after(jiffies, mpath->exp_time -
795 msecs_to_jiffies(sdata->u.sta.mshcfg.path_refresh_time)) 794 msecs_to_jiffies(sdata->u.mesh.mshcfg.path_refresh_time))
796 && !memcmp(dev->dev_addr, hdr->addr4, ETH_ALEN) 795 && !memcmp(sdata->dev->dev_addr, hdr->addr4,
796 ETH_ALEN)
797 && !(mpath->flags & MESH_PATH_RESOLVING) 797 && !(mpath->flags & MESH_PATH_RESOLVING)
798 && !(mpath->flags & MESH_PATH_FIXED)) { 798 && !(mpath->flags & MESH_PATH_FIXED)) {
799 mesh_queue_preq(mpath, 799 mesh_queue_preq(mpath,
800 PREQ_Q_F_START | PREQ_Q_F_REFRESH); 800 PREQ_Q_F_START | PREQ_Q_F_REFRESH);
801 } 801 }
802 memcpy(hdr->addr1, mpath->next_hop->addr, 802 memcpy(hdr->addr1, mpath->next_hop->sta.addr,
803 ETH_ALEN); 803 ETH_ALEN);
804 } else { 804 } else {
805 if (!(mpath->flags & MESH_PATH_RESOLVING)) { 805 if (!(mpath->flags & MESH_PATH_RESOLVING)) {
@@ -815,7 +815,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb, struct net_device *dev)
815 815
816 skb_queue_tail(&mpath->frame_queue, skb); 816 skb_queue_tail(&mpath->frame_queue, skb);
817 if (skb_to_free) 817 if (skb_to_free)
818 mesh_path_discard_frame(skb_to_free, dev); 818 mesh_path_discard_frame(skb_to_free, sdata);
819 err = -ENOENT; 819 err = -ENOENT;
820 } 820 }
821 821
@@ -835,7 +835,7 @@ void mesh_path_timer(unsigned long data)
835 if (!mpath) 835 if (!mpath)
836 goto endmpathtimer; 836 goto endmpathtimer;
837 spin_lock_bh(&mpath->state_lock); 837 spin_lock_bh(&mpath->state_lock);
838 sdata = IEEE80211_DEV_TO_SUB_IF(mpath->dev); 838 sdata = mpath->sdata;
839 if (mpath->flags & MESH_PATH_RESOLVED || 839 if (mpath->flags & MESH_PATH_RESOLVED ||
840 (!(mpath->flags & MESH_PATH_RESOLVING))) 840 (!(mpath->flags & MESH_PATH_RESOLVING)))
841 mpath->flags &= ~(MESH_PATH_RESOLVING | MESH_PATH_RESOLVED); 841 mpath->flags &= ~(MESH_PATH_RESOLVING | MESH_PATH_RESOLVED);
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 838ee60492ad..3c72557df45a 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -9,7 +9,6 @@
9 9
10#include <linux/etherdevice.h> 10#include <linux/etherdevice.h>
11#include <linux/list.h> 11#include <linux/list.h>
12#include <linux/netdevice.h>
13#include <linux/random.h> 12#include <linux/random.h>
14#include <linux/spinlock.h> 13#include <linux/spinlock.h>
15#include <linux/string.h> 14#include <linux/string.h>
@@ -37,6 +36,7 @@ struct mpath_node {
37}; 36};
38 37
39static struct mesh_table *mesh_paths; 38static struct mesh_table *mesh_paths;
39static struct mesh_table *mpp_paths; /* Store paths for MPP&MAP */
40 40
41/* This lock will have the grow table function as writer and add / delete nodes 41/* This lock will have the grow table function as writer and add / delete nodes
42 * as readers. When reading the table (i.e. doing lookups) we are well protected 42 * as readers. When reading the table (i.e. doing lookups) we are well protected
@@ -62,13 +62,13 @@ void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta)
62/** 62/**
63 * mesh_path_lookup - look up a path in the mesh path table 63 * mesh_path_lookup - look up a path in the mesh path table
64 * @dst: hardware address (ETH_ALEN length) of destination 64 * @dst: hardware address (ETH_ALEN length) of destination
65 * @dev: local interface 65 * @sdata: local subif
66 * 66 *
67 * Returns: pointer to the mesh path structure, or NULL if not found 67 * Returns: pointer to the mesh path structure, or NULL if not found
68 * 68 *
69 * Locking: must be called within a read rcu section. 69 * Locking: must be called within a read rcu section.
70 */ 70 */
71struct mesh_path *mesh_path_lookup(u8 *dst, struct net_device *dev) 71struct mesh_path *mesh_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata)
72{ 72{
73 struct mesh_path *mpath; 73 struct mesh_path *mpath;
74 struct hlist_node *n; 74 struct hlist_node *n;
@@ -78,10 +78,10 @@ struct mesh_path *mesh_path_lookup(u8 *dst, struct net_device *dev)
78 78
79 tbl = rcu_dereference(mesh_paths); 79 tbl = rcu_dereference(mesh_paths);
80 80
81 bucket = &tbl->hash_buckets[mesh_table_hash(dst, dev, tbl)]; 81 bucket = &tbl->hash_buckets[mesh_table_hash(dst, sdata, tbl)];
82 hlist_for_each_entry_rcu(node, n, bucket, list) { 82 hlist_for_each_entry_rcu(node, n, bucket, list) {
83 mpath = node->mpath; 83 mpath = node->mpath;
84 if (mpath->dev == dev && 84 if (mpath->sdata == sdata &&
85 memcmp(dst, mpath->dst, ETH_ALEN) == 0) { 85 memcmp(dst, mpath->dst, ETH_ALEN) == 0) {
86 if (MPATH_EXPIRED(mpath)) { 86 if (MPATH_EXPIRED(mpath)) {
87 spin_lock_bh(&mpath->state_lock); 87 spin_lock_bh(&mpath->state_lock);
@@ -95,16 +95,44 @@ struct mesh_path *mesh_path_lookup(u8 *dst, struct net_device *dev)
95 return NULL; 95 return NULL;
96} 96}
97 97
98struct mesh_path *mpp_path_lookup(u8 *dst, struct ieee80211_sub_if_data *sdata)
99{
100 struct mesh_path *mpath;
101 struct hlist_node *n;
102 struct hlist_head *bucket;
103 struct mesh_table *tbl;
104 struct mpath_node *node;
105
106 tbl = rcu_dereference(mpp_paths);
107
108 bucket = &tbl->hash_buckets[mesh_table_hash(dst, sdata, tbl)];
109 hlist_for_each_entry_rcu(node, n, bucket, list) {
110 mpath = node->mpath;
111 if (mpath->sdata == sdata &&
112 memcmp(dst, mpath->dst, ETH_ALEN) == 0) {
113 if (MPATH_EXPIRED(mpath)) {
114 spin_lock_bh(&mpath->state_lock);
115 if (MPATH_EXPIRED(mpath))
116 mpath->flags &= ~MESH_PATH_ACTIVE;
117 spin_unlock_bh(&mpath->state_lock);
118 }
119 return mpath;
120 }
121 }
122 return NULL;
123}
124
125
98/** 126/**
99 * mesh_path_lookup_by_idx - look up a path in the mesh path table by its index 127 * mesh_path_lookup_by_idx - look up a path in the mesh path table by its index
100 * @idx: index 128 * @idx: index
101 * @dev: local interface, or NULL for all entries 129 * @sdata: local subif, or NULL for all entries
102 * 130 *
103 * Returns: pointer to the mesh path structure, or NULL if not found. 131 * Returns: pointer to the mesh path structure, or NULL if not found.
104 * 132 *
105 * Locking: must be called within a read rcu section. 133 * Locking: must be called within a read rcu section.
106 */ 134 */
107struct mesh_path *mesh_path_lookup_by_idx(int idx, struct net_device *dev) 135struct mesh_path *mesh_path_lookup_by_idx(int idx, struct ieee80211_sub_if_data *sdata)
108{ 136{
109 struct mpath_node *node; 137 struct mpath_node *node;
110 struct hlist_node *p; 138 struct hlist_node *p;
@@ -112,7 +140,7 @@ struct mesh_path *mesh_path_lookup_by_idx(int idx, struct net_device *dev)
112 int j = 0; 140 int j = 0;
113 141
114 for_each_mesh_entry(mesh_paths, p, node, i) { 142 for_each_mesh_entry(mesh_paths, p, node, i) {
115 if (dev && node->mpath->dev != dev) 143 if (sdata && node->mpath->sdata != sdata)
116 continue; 144 continue;
117 if (j++ == idx) { 145 if (j++ == idx) {
118 if (MPATH_EXPIRED(node->mpath)) { 146 if (MPATH_EXPIRED(node->mpath)) {
@@ -131,15 +159,14 @@ struct mesh_path *mesh_path_lookup_by_idx(int idx, struct net_device *dev)
131/** 159/**
132 * mesh_path_add - allocate and add a new path to the mesh path table 160 * mesh_path_add - allocate and add a new path to the mesh path table
133 * @addr: destination address of the path (ETH_ALEN length) 161 * @addr: destination address of the path (ETH_ALEN length)
134 * @dev: local interface 162 * @sdata: local subif
135 * 163 *
136 * Returns: 0 on sucess 164 * Returns: 0 on sucess
137 * 165 *
138 * State: the initial state of the new path is set to 0 166 * State: the initial state of the new path is set to 0
139 */ 167 */
140int mesh_path_add(u8 *dst, struct net_device *dev) 168int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
141{ 169{
142 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
143 struct mesh_path *mpath, *new_mpath; 170 struct mesh_path *mpath, *new_mpath;
144 struct mpath_node *node, *new_node; 171 struct mpath_node *node, *new_node;
145 struct hlist_head *bucket; 172 struct hlist_head *bucket;
@@ -148,14 +175,14 @@ int mesh_path_add(u8 *dst, struct net_device *dev)
148 int err = 0; 175 int err = 0;
149 u32 hash_idx; 176 u32 hash_idx;
150 177
151 if (memcmp(dst, dev->dev_addr, ETH_ALEN) == 0) 178 if (memcmp(dst, sdata->dev->dev_addr, ETH_ALEN) == 0)
152 /* never add ourselves as neighbours */ 179 /* never add ourselves as neighbours */
153 return -ENOTSUPP; 180 return -ENOTSUPP;
154 181
155 if (is_multicast_ether_addr(dst)) 182 if (is_multicast_ether_addr(dst))
156 return -ENOTSUPP; 183 return -ENOTSUPP;
157 184
158 if (atomic_add_unless(&sdata->u.sta.mpaths, 1, MESH_MAX_MPATHS) == 0) 185 if (atomic_add_unless(&sdata->u.mesh.mpaths, 1, MESH_MAX_MPATHS) == 0)
159 return -ENOSPC; 186 return -ENOSPC;
160 187
161 err = -ENOMEM; 188 err = -ENOMEM;
@@ -169,7 +196,7 @@ int mesh_path_add(u8 *dst, struct net_device *dev)
169 196
170 read_lock(&pathtbl_resize_lock); 197 read_lock(&pathtbl_resize_lock);
171 memcpy(new_mpath->dst, dst, ETH_ALEN); 198 memcpy(new_mpath->dst, dst, ETH_ALEN);
172 new_mpath->dev = dev; 199 new_mpath->sdata = sdata;
173 new_mpath->flags = 0; 200 new_mpath->flags = 0;
174 skb_queue_head_init(&new_mpath->frame_queue); 201 skb_queue_head_init(&new_mpath->frame_queue);
175 new_node->mpath = new_mpath; 202 new_node->mpath = new_mpath;
@@ -179,7 +206,7 @@ int mesh_path_add(u8 *dst, struct net_device *dev)
179 spin_lock_init(&new_mpath->state_lock); 206 spin_lock_init(&new_mpath->state_lock);
180 init_timer(&new_mpath->timer); 207 init_timer(&new_mpath->timer);
181 208
182 hash_idx = mesh_table_hash(dst, dev, mesh_paths); 209 hash_idx = mesh_table_hash(dst, sdata, mesh_paths);
183 bucket = &mesh_paths->hash_buckets[hash_idx]; 210 bucket = &mesh_paths->hash_buckets[hash_idx];
184 211
185 spin_lock(&mesh_paths->hashwlock[hash_idx]); 212 spin_lock(&mesh_paths->hashwlock[hash_idx]);
@@ -187,7 +214,7 @@ int mesh_path_add(u8 *dst, struct net_device *dev)
187 err = -EEXIST; 214 err = -EEXIST;
188 hlist_for_each_entry(node, n, bucket, list) { 215 hlist_for_each_entry(node, n, bucket, list) {
189 mpath = node->mpath; 216 mpath = node->mpath;
190 if (mpath->dev == dev && memcmp(dst, mpath->dst, ETH_ALEN) == 0) 217 if (mpath->sdata == sdata && memcmp(dst, mpath->dst, ETH_ALEN) == 0)
191 goto err_exists; 218 goto err_exists;
192 } 219 }
193 220
@@ -223,7 +250,92 @@ err_exists:
223err_node_alloc: 250err_node_alloc:
224 kfree(new_mpath); 251 kfree(new_mpath);
225err_path_alloc: 252err_path_alloc:
226 atomic_dec(&sdata->u.sta.mpaths); 253 atomic_dec(&sdata->u.mesh.mpaths);
254 return err;
255}
256
257
258int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
259{
260 struct mesh_path *mpath, *new_mpath;
261 struct mpath_node *node, *new_node;
262 struct hlist_head *bucket;
263 struct hlist_node *n;
264 int grow = 0;
265 int err = 0;
266 u32 hash_idx;
267
268
269 if (memcmp(dst, sdata->dev->dev_addr, ETH_ALEN) == 0)
270 /* never add ourselves as neighbours */
271 return -ENOTSUPP;
272
273 if (is_multicast_ether_addr(dst))
274 return -ENOTSUPP;
275
276 err = -ENOMEM;
277 new_mpath = kzalloc(sizeof(struct mesh_path), GFP_KERNEL);
278 if (!new_mpath)
279 goto err_path_alloc;
280
281 new_node = kmalloc(sizeof(struct mpath_node), GFP_KERNEL);
282 if (!new_node)
283 goto err_node_alloc;
284
285 read_lock(&pathtbl_resize_lock);
286 memcpy(new_mpath->dst, dst, ETH_ALEN);
287 memcpy(new_mpath->mpp, mpp, ETH_ALEN);
288 new_mpath->sdata = sdata;
289 new_mpath->flags = 0;
290 skb_queue_head_init(&new_mpath->frame_queue);
291 new_node->mpath = new_mpath;
292 new_mpath->exp_time = jiffies;
293 spin_lock_init(&new_mpath->state_lock);
294
295 hash_idx = mesh_table_hash(dst, sdata, mpp_paths);
296 bucket = &mpp_paths->hash_buckets[hash_idx];
297
298 spin_lock(&mpp_paths->hashwlock[hash_idx]);
299
300 err = -EEXIST;
301 hlist_for_each_entry(node, n, bucket, list) {
302 mpath = node->mpath;
303 if (mpath->sdata == sdata && memcmp(dst, mpath->dst, ETH_ALEN) == 0)
304 goto err_exists;
305 }
306
307 hlist_add_head_rcu(&new_node->list, bucket);
308 if (atomic_inc_return(&mpp_paths->entries) >=
309 mpp_paths->mean_chain_len * (mpp_paths->hash_mask + 1))
310 grow = 1;
311
312 spin_unlock(&mpp_paths->hashwlock[hash_idx]);
313 read_unlock(&pathtbl_resize_lock);
314 if (grow) {
315 struct mesh_table *oldtbl, *newtbl;
316
317 write_lock(&pathtbl_resize_lock);
318 oldtbl = mpp_paths;
319 newtbl = mesh_table_grow(mpp_paths);
320 if (!newtbl) {
321 write_unlock(&pathtbl_resize_lock);
322 return 0;
323 }
324 rcu_assign_pointer(mpp_paths, newtbl);
325 write_unlock(&pathtbl_resize_lock);
326
327 synchronize_rcu();
328 mesh_table_free(oldtbl, false);
329 }
330 return 0;
331
332err_exists:
333 spin_unlock(&mpp_paths->hashwlock[hash_idx]);
334 read_unlock(&pathtbl_resize_lock);
335 kfree(new_node);
336err_node_alloc:
337 kfree(new_mpath);
338err_path_alloc:
227 return err; 339 return err;
228} 340}
229 341
@@ -241,7 +353,7 @@ void mesh_plink_broken(struct sta_info *sta)
241 struct mesh_path *mpath; 353 struct mesh_path *mpath;
242 struct mpath_node *node; 354 struct mpath_node *node;
243 struct hlist_node *p; 355 struct hlist_node *p;
244 struct net_device *dev = sta->sdata->dev; 356 struct ieee80211_sub_if_data *sdata = sta->sdata;
245 int i; 357 int i;
246 358
247 rcu_read_lock(); 359 rcu_read_lock();
@@ -256,7 +368,7 @@ void mesh_plink_broken(struct sta_info *sta)
256 spin_unlock_bh(&mpath->state_lock); 368 spin_unlock_bh(&mpath->state_lock);
257 mesh_path_error_tx(mpath->dst, 369 mesh_path_error_tx(mpath->dst,
258 cpu_to_le32(mpath->dsn), 370 cpu_to_le32(mpath->dsn),
259 dev->broadcast, dev); 371 sdata->dev->broadcast, sdata);
260 } else 372 } else
261 spin_unlock_bh(&mpath->state_lock); 373 spin_unlock_bh(&mpath->state_lock);
262 } 374 }
@@ -284,11 +396,11 @@ void mesh_path_flush_by_nexthop(struct sta_info *sta)
284 for_each_mesh_entry(mesh_paths, p, node, i) { 396 for_each_mesh_entry(mesh_paths, p, node, i) {
285 mpath = node->mpath; 397 mpath = node->mpath;
286 if (mpath->next_hop == sta) 398 if (mpath->next_hop == sta)
287 mesh_path_del(mpath->dst, mpath->dev); 399 mesh_path_del(mpath->dst, mpath->sdata);
288 } 400 }
289} 401}
290 402
291void mesh_path_flush(struct net_device *dev) 403void mesh_path_flush(struct ieee80211_sub_if_data *sdata)
292{ 404{
293 struct mesh_path *mpath; 405 struct mesh_path *mpath;
294 struct mpath_node *node; 406 struct mpath_node *node;
@@ -297,19 +409,18 @@ void mesh_path_flush(struct net_device *dev)
297 409
298 for_each_mesh_entry(mesh_paths, p, node, i) { 410 for_each_mesh_entry(mesh_paths, p, node, i) {
299 mpath = node->mpath; 411 mpath = node->mpath;
300 if (mpath->dev == dev) 412 if (mpath->sdata == sdata)
301 mesh_path_del(mpath->dst, mpath->dev); 413 mesh_path_del(mpath->dst, mpath->sdata);
302 } 414 }
303} 415}
304 416
305static void mesh_path_node_reclaim(struct rcu_head *rp) 417static void mesh_path_node_reclaim(struct rcu_head *rp)
306{ 418{
307 struct mpath_node *node = container_of(rp, struct mpath_node, rcu); 419 struct mpath_node *node = container_of(rp, struct mpath_node, rcu);
308 struct ieee80211_sub_if_data *sdata = 420 struct ieee80211_sub_if_data *sdata = node->mpath->sdata;
309 IEEE80211_DEV_TO_SUB_IF(node->mpath->dev);
310 421
311 del_timer_sync(&node->mpath->timer); 422 del_timer_sync(&node->mpath->timer);
312 atomic_dec(&sdata->u.sta.mpaths); 423 atomic_dec(&sdata->u.mesh.mpaths);
313 kfree(node->mpath); 424 kfree(node->mpath);
314 kfree(node); 425 kfree(node);
315} 426}
@@ -318,11 +429,11 @@ static void mesh_path_node_reclaim(struct rcu_head *rp)
318 * mesh_path_del - delete a mesh path from the table 429 * mesh_path_del - delete a mesh path from the table
319 * 430 *
320 * @addr: dst address (ETH_ALEN length) 431 * @addr: dst address (ETH_ALEN length)
321 * @dev: local interface 432 * @sdata: local subif
322 * 433 *
323 * Returns: 0 if succesful 434 * Returns: 0 if succesful
324 */ 435 */
325int mesh_path_del(u8 *addr, struct net_device *dev) 436int mesh_path_del(u8 *addr, struct ieee80211_sub_if_data *sdata)
326{ 437{
327 struct mesh_path *mpath; 438 struct mesh_path *mpath;
328 struct mpath_node *node; 439 struct mpath_node *node;
@@ -332,13 +443,13 @@ int mesh_path_del(u8 *addr, struct net_device *dev)
332 int err = 0; 443 int err = 0;
333 444
334 read_lock(&pathtbl_resize_lock); 445 read_lock(&pathtbl_resize_lock);
335 hash_idx = mesh_table_hash(addr, dev, mesh_paths); 446 hash_idx = mesh_table_hash(addr, sdata, mesh_paths);
336 bucket = &mesh_paths->hash_buckets[hash_idx]; 447 bucket = &mesh_paths->hash_buckets[hash_idx];
337 448
338 spin_lock(&mesh_paths->hashwlock[hash_idx]); 449 spin_lock(&mesh_paths->hashwlock[hash_idx]);
339 hlist_for_each_entry(node, n, bucket, list) { 450 hlist_for_each_entry(node, n, bucket, list) {
340 mpath = node->mpath; 451 mpath = node->mpath;
341 if (mpath->dev == dev && 452 if (mpath->sdata == sdata &&
342 memcmp(addr, mpath->dst, ETH_ALEN) == 0) { 453 memcmp(addr, mpath->dst, ETH_ALEN) == 0) {
343 spin_lock_bh(&mpath->state_lock); 454 spin_lock_bh(&mpath->state_lock);
344 mpath->flags |= MESH_PATH_RESOLVING; 455 mpath->flags |= MESH_PATH_RESOLVING;
@@ -378,33 +489,33 @@ void mesh_path_tx_pending(struct mesh_path *mpath)
378 * mesh_path_discard_frame - discard a frame whose path could not be resolved 489 * mesh_path_discard_frame - discard a frame whose path could not be resolved
379 * 490 *
380 * @skb: frame to discard 491 * @skb: frame to discard
381 * @dev: network device the frame was to be sent through 492 * @sdata: network subif the frame was to be sent through
382 * 493 *
383 * If the frame was beign forwarded from another MP, a PERR frame will be sent 494 * If the frame was beign forwarded from another MP, a PERR frame will be sent
384 * to the precursor. 495 * to the precursor.
385 * 496 *
386 * Locking: the function must me called within a rcu_read_lock region 497 * Locking: the function must me called within a rcu_read_lock region
387 */ 498 */
388void mesh_path_discard_frame(struct sk_buff *skb, struct net_device *dev) 499void mesh_path_discard_frame(struct sk_buff *skb,
500 struct ieee80211_sub_if_data *sdata)
389{ 501{
390 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
391 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 502 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
392 struct mesh_path *mpath; 503 struct mesh_path *mpath;
393 u32 dsn = 0; 504 u32 dsn = 0;
394 505
395 if (memcmp(hdr->addr4, dev->dev_addr, ETH_ALEN) != 0) { 506 if (memcmp(hdr->addr4, sdata->dev->dev_addr, ETH_ALEN) != 0) {
396 u8 *ra, *da; 507 u8 *ra, *da;
397 508
398 da = hdr->addr3; 509 da = hdr->addr3;
399 ra = hdr->addr2; 510 ra = hdr->addr2;
400 mpath = mesh_path_lookup(da, dev); 511 mpath = mesh_path_lookup(da, sdata);
401 if (mpath) 512 if (mpath)
402 dsn = ++mpath->dsn; 513 dsn = ++mpath->dsn;
403 mesh_path_error_tx(skb->data, cpu_to_le32(dsn), ra, dev); 514 mesh_path_error_tx(skb->data, cpu_to_le32(dsn), ra, sdata);
404 } 515 }
405 516
406 kfree_skb(skb); 517 kfree_skb(skb);
407 sdata->u.sta.mshstats.dropped_frames_no_route++; 518 sdata->u.mesh.mshstats.dropped_frames_no_route++;
408} 519}
409 520
410/** 521/**
@@ -416,14 +527,11 @@ void mesh_path_discard_frame(struct sk_buff *skb, struct net_device *dev)
416 */ 527 */
417void mesh_path_flush_pending(struct mesh_path *mpath) 528void mesh_path_flush_pending(struct mesh_path *mpath)
418{ 529{
419 struct ieee80211_sub_if_data *sdata;
420 struct sk_buff *skb; 530 struct sk_buff *skb;
421 531
422 sdata = IEEE80211_DEV_TO_SUB_IF(mpath->dev);
423
424 while ((skb = skb_dequeue(&mpath->frame_queue)) && 532 while ((skb = skb_dequeue(&mpath->frame_queue)) &&
425 (mpath->flags & MESH_PATH_ACTIVE)) 533 (mpath->flags & MESH_PATH_ACTIVE))
426 mesh_path_discard_frame(skb, mpath->dev); 534 mesh_path_discard_frame(skb, mpath->sdata);
427} 535}
428 536
429/** 537/**
@@ -472,7 +580,7 @@ static int mesh_path_node_copy(struct hlist_node *p, struct mesh_table *newtbl)
472 node = hlist_entry(p, struct mpath_node, list); 580 node = hlist_entry(p, struct mpath_node, list);
473 mpath = node->mpath; 581 mpath = node->mpath;
474 new_node->mpath = mpath; 582 new_node->mpath = mpath;
475 hash_idx = mesh_table_hash(mpath->dst, mpath->dev, newtbl); 583 hash_idx = mesh_table_hash(mpath->dst, mpath->sdata, newtbl);
476 hlist_add_head(&new_node->list, 584 hlist_add_head(&new_node->list,
477 &newtbl->hash_buckets[hash_idx]); 585 &newtbl->hash_buckets[hash_idx]);
478 return 0; 586 return 0;
@@ -481,15 +589,25 @@ static int mesh_path_node_copy(struct hlist_node *p, struct mesh_table *newtbl)
481int mesh_pathtbl_init(void) 589int mesh_pathtbl_init(void)
482{ 590{
483 mesh_paths = mesh_table_alloc(INIT_PATHS_SIZE_ORDER); 591 mesh_paths = mesh_table_alloc(INIT_PATHS_SIZE_ORDER);
592 if (!mesh_paths)
593 return -ENOMEM;
484 mesh_paths->free_node = &mesh_path_node_free; 594 mesh_paths->free_node = &mesh_path_node_free;
485 mesh_paths->copy_node = &mesh_path_node_copy; 595 mesh_paths->copy_node = &mesh_path_node_copy;
486 mesh_paths->mean_chain_len = MEAN_CHAIN_LEN; 596 mesh_paths->mean_chain_len = MEAN_CHAIN_LEN;
487 if (!mesh_paths) 597
598 mpp_paths = mesh_table_alloc(INIT_PATHS_SIZE_ORDER);
599 if (!mpp_paths) {
600 mesh_table_free(mesh_paths, true);
488 return -ENOMEM; 601 return -ENOMEM;
602 }
603 mpp_paths->free_node = &mesh_path_node_free;
604 mpp_paths->copy_node = &mesh_path_node_copy;
605 mpp_paths->mean_chain_len = MEAN_CHAIN_LEN;
606
489 return 0; 607 return 0;
490} 608}
491 609
492void mesh_path_expire(struct net_device *dev) 610void mesh_path_expire(struct ieee80211_sub_if_data *sdata)
493{ 611{
494 struct mesh_path *mpath; 612 struct mesh_path *mpath;
495 struct mpath_node *node; 613 struct mpath_node *node;
@@ -498,7 +616,7 @@ void mesh_path_expire(struct net_device *dev)
498 616
499 read_lock(&pathtbl_resize_lock); 617 read_lock(&pathtbl_resize_lock);
500 for_each_mesh_entry(mesh_paths, p, node, i) { 618 for_each_mesh_entry(mesh_paths, p, node, i) {
501 if (node->mpath->dev != dev) 619 if (node->mpath->sdata != sdata)
502 continue; 620 continue;
503 mpath = node->mpath; 621 mpath = node->mpath;
504 spin_lock_bh(&mpath->state_lock); 622 spin_lock_bh(&mpath->state_lock);
@@ -507,7 +625,7 @@ void mesh_path_expire(struct net_device *dev)
507 time_after(jiffies, 625 time_after(jiffies,
508 mpath->exp_time + MESH_PATH_EXPIRE)) { 626 mpath->exp_time + MESH_PATH_EXPIRE)) {
509 spin_unlock_bh(&mpath->state_lock); 627 spin_unlock_bh(&mpath->state_lock);
510 mesh_path_del(mpath->dst, mpath->dev); 628 mesh_path_del(mpath->dst, mpath->sdata);
511 } else 629 } else
512 spin_unlock_bh(&mpath->state_lock); 630 spin_unlock_bh(&mpath->state_lock);
513 } 631 }
@@ -517,4 +635,5 @@ void mesh_path_expire(struct net_device *dev)
517void mesh_pathtbl_unregister(void) 635void mesh_pathtbl_unregister(void)
518{ 636{
519 mesh_table_free(mesh_paths, true); 637 mesh_table_free(mesh_paths, true);
638 mesh_table_free(mpp_paths, true);
520} 639}
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 9efeb1f07025..faac101c0f85 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -36,11 +36,11 @@
36#define MESH_SECURITY_AUTHENTICATION_IMPOSSIBLE 9 36#define MESH_SECURITY_AUTHENTICATION_IMPOSSIBLE 9
37#define MESH_SECURITY_FAILED_VERIFICATION 10 37#define MESH_SECURITY_FAILED_VERIFICATION 10
38 38
39#define dot11MeshMaxRetries(s) (s->u.sta.mshcfg.dot11MeshMaxRetries) 39#define dot11MeshMaxRetries(s) (s->u.mesh.mshcfg.dot11MeshMaxRetries)
40#define dot11MeshRetryTimeout(s) (s->u.sta.mshcfg.dot11MeshRetryTimeout) 40#define dot11MeshRetryTimeout(s) (s->u.mesh.mshcfg.dot11MeshRetryTimeout)
41#define dot11MeshConfirmTimeout(s) (s->u.sta.mshcfg.dot11MeshConfirmTimeout) 41#define dot11MeshConfirmTimeout(s) (s->u.mesh.mshcfg.dot11MeshConfirmTimeout)
42#define dot11MeshHoldingTimeout(s) (s->u.sta.mshcfg.dot11MeshHoldingTimeout) 42#define dot11MeshHoldingTimeout(s) (s->u.mesh.mshcfg.dot11MeshHoldingTimeout)
43#define dot11MeshMaxPeerLinks(s) (s->u.sta.mshcfg.dot11MeshMaxPeerLinks) 43#define dot11MeshMaxPeerLinks(s) (s->u.mesh.mshcfg.dot11MeshMaxPeerLinks)
44 44
45enum plink_frame_type { 45enum plink_frame_type {
46 PLINK_OPEN = 0, 46 PLINK_OPEN = 0,
@@ -63,14 +63,14 @@ enum plink_event {
63static inline 63static inline
64void mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata) 64void mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata)
65{ 65{
66 atomic_inc(&sdata->u.sta.mshstats.estab_plinks); 66 atomic_inc(&sdata->u.mesh.mshstats.estab_plinks);
67 mesh_accept_plinks_update(sdata); 67 mesh_accept_plinks_update(sdata);
68} 68}
69 69
70static inline 70static inline
71void mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata) 71void mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata)
72{ 72{
73 atomic_dec(&sdata->u.sta.mshstats.estab_plinks); 73 atomic_dec(&sdata->u.mesh.mshstats.estab_plinks);
74 mesh_accept_plinks_update(sdata); 74 mesh_accept_plinks_update(sdata);
75} 75}
76 76
@@ -106,7 +106,7 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata,
106 return NULL; 106 return NULL;
107 107
108 sta->flags = WLAN_STA_AUTHORIZED; 108 sta->flags = WLAN_STA_AUTHORIZED;
109 sta->supp_rates[local->hw.conf.channel->band] = rates; 109 sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
110 110
111 return sta; 111 return sta;
112} 112}
@@ -144,10 +144,10 @@ void mesh_plink_deactivate(struct sta_info *sta)
144 spin_unlock_bh(&sta->lock); 144 spin_unlock_bh(&sta->lock);
145} 145}
146 146
147static int mesh_plink_frame_tx(struct net_device *dev, 147static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
148 enum plink_frame_type action, u8 *da, __le16 llid, __le16 plid, 148 enum plink_frame_type action, u8 *da, __le16 llid, __le16 plid,
149 __le16 reason) { 149 __le16 reason) {
150 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 150 struct ieee80211_local *local = sdata->local;
151 struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400); 151 struct sk_buff *skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400);
152 struct ieee80211_mgmt *mgmt; 152 struct ieee80211_mgmt *mgmt;
153 bool include_plid = false; 153 bool include_plid = false;
@@ -163,10 +163,10 @@ static int mesh_plink_frame_tx(struct net_device *dev,
163 mgmt = (struct ieee80211_mgmt *) 163 mgmt = (struct ieee80211_mgmt *)
164 skb_put(skb, 25 + sizeof(mgmt->u.action.u.plink_action)); 164 skb_put(skb, 25 + sizeof(mgmt->u.action.u.plink_action));
165 memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.plink_action)); 165 memset(mgmt, 0, 25 + sizeof(mgmt->u.action.u.plink_action));
166 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, 166 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
167 IEEE80211_STYPE_ACTION); 167 IEEE80211_STYPE_ACTION);
168 memcpy(mgmt->da, da, ETH_ALEN); 168 memcpy(mgmt->da, da, ETH_ALEN);
169 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); 169 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
170 /* BSSID is left zeroed, wildcard value */ 170 /* BSSID is left zeroed, wildcard value */
171 mgmt->u.action.category = PLINK_CATEGORY; 171 mgmt->u.action.category = PLINK_CATEGORY;
172 mgmt->u.action.u.plink_action.action_code = action; 172 mgmt->u.action.u.plink_action.action_code = action;
@@ -180,7 +180,7 @@ static int mesh_plink_frame_tx(struct net_device *dev,
180 /* two-byte status code followed by two-byte AID */ 180 /* two-byte status code followed by two-byte AID */
181 memset(pos, 0, 4); 181 memset(pos, 0, 4);
182 } 182 }
183 mesh_mgmt_ies_add(skb, dev); 183 mesh_mgmt_ies_add(skb, sdata);
184 } 184 }
185 185
186 /* Add Peer Link Management element */ 186 /* Add Peer Link Management element */
@@ -217,15 +217,14 @@ static int mesh_plink_frame_tx(struct net_device *dev,
217 memcpy(pos, &reason, 2); 217 memcpy(pos, &reason, 2);
218 } 218 }
219 219
220 ieee80211_sta_tx(dev, skb, 0); 220 ieee80211_tx_skb(sdata, skb, 0);
221 return 0; 221 return 0;
222} 222}
223 223
224void mesh_neighbour_update(u8 *hw_addr, u64 rates, struct net_device *dev, 224void mesh_neighbour_update(u8 *hw_addr, u64 rates, struct ieee80211_sub_if_data *sdata,
225 bool peer_accepting_plinks) 225 bool peer_accepting_plinks)
226{ 226{
227 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 227 struct ieee80211_local *local = sdata->local;
228 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
229 struct sta_info *sta; 228 struct sta_info *sta;
230 229
231 rcu_read_lock(); 230 rcu_read_lock();
@@ -244,10 +243,10 @@ void mesh_neighbour_update(u8 *hw_addr, u64 rates, struct net_device *dev,
244 } 243 }
245 244
246 sta->last_rx = jiffies; 245 sta->last_rx = jiffies;
247 sta->supp_rates[local->hw.conf.channel->band] = rates; 246 sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
248 if (peer_accepting_plinks && sta->plink_state == PLINK_LISTEN && 247 if (peer_accepting_plinks && sta->plink_state == PLINK_LISTEN &&
249 sdata->u.sta.accepting_plinks && 248 sdata->u.mesh.accepting_plinks &&
250 sdata->u.sta.mshcfg.auto_open_plinks) 249 sdata->u.mesh.mshcfg.auto_open_plinks)
251 mesh_plink_open(sta); 250 mesh_plink_open(sta);
252 251
253 rcu_read_unlock(); 252 rcu_read_unlock();
@@ -257,7 +256,6 @@ static void mesh_plink_timer(unsigned long data)
257{ 256{
258 struct sta_info *sta; 257 struct sta_info *sta;
259 __le16 llid, plid, reason; 258 __le16 llid, plid, reason;
260 struct net_device *dev = NULL;
261 struct ieee80211_sub_if_data *sdata; 259 struct ieee80211_sub_if_data *sdata;
262#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG 260#ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG
263 DECLARE_MAC_BUF(mac); 261 DECLARE_MAC_BUF(mac);
@@ -277,12 +275,11 @@ static void mesh_plink_timer(unsigned long data)
277 return; 275 return;
278 } 276 }
279 mpl_dbg("Mesh plink timer for %s fired on state %d\n", 277 mpl_dbg("Mesh plink timer for %s fired on state %d\n",
280 print_mac(mac, sta->addr), sta->plink_state); 278 print_mac(mac, sta->sta.addr), sta->plink_state);
281 reason = 0; 279 reason = 0;
282 llid = sta->llid; 280 llid = sta->llid;
283 plid = sta->plid; 281 plid = sta->plid;
284 sdata = sta->sdata; 282 sdata = sta->sdata;
285 dev = sdata->dev;
286 283
287 switch (sta->plink_state) { 284 switch (sta->plink_state) {
288 case PLINK_OPN_RCVD: 285 case PLINK_OPN_RCVD:
@@ -291,7 +288,7 @@ static void mesh_plink_timer(unsigned long data)
291 if (sta->plink_retries < dot11MeshMaxRetries(sdata)) { 288 if (sta->plink_retries < dot11MeshMaxRetries(sdata)) {
292 u32 rand; 289 u32 rand;
293 mpl_dbg("Mesh plink for %s (retry, timeout): %d %d\n", 290 mpl_dbg("Mesh plink for %s (retry, timeout): %d %d\n",
294 print_mac(mac, sta->addr), 291 print_mac(mac, sta->sta.addr),
295 sta->plink_retries, sta->plink_timeout); 292 sta->plink_retries, sta->plink_timeout);
296 get_random_bytes(&rand, sizeof(u32)); 293 get_random_bytes(&rand, sizeof(u32));
297 sta->plink_timeout = sta->plink_timeout + 294 sta->plink_timeout = sta->plink_timeout +
@@ -299,7 +296,7 @@ static void mesh_plink_timer(unsigned long data)
299 ++sta->plink_retries; 296 ++sta->plink_retries;
300 mod_plink_timer(sta, sta->plink_timeout); 297 mod_plink_timer(sta, sta->plink_timeout);
301 spin_unlock_bh(&sta->lock); 298 spin_unlock_bh(&sta->lock);
302 mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid, 299 mesh_plink_frame_tx(sdata, PLINK_OPEN, sta->sta.addr, llid,
303 0, 0); 300 0, 0);
304 break; 301 break;
305 } 302 }
@@ -312,7 +309,7 @@ static void mesh_plink_timer(unsigned long data)
312 sta->plink_state = PLINK_HOLDING; 309 sta->plink_state = PLINK_HOLDING;
313 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); 310 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
314 spin_unlock_bh(&sta->lock); 311 spin_unlock_bh(&sta->lock);
315 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, plid, 312 mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid, plid,
316 reason); 313 reason);
317 break; 314 break;
318 case PLINK_HOLDING: 315 case PLINK_HOLDING:
@@ -355,10 +352,10 @@ int mesh_plink_open(struct sta_info *sta)
355 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); 352 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata));
356 spin_unlock_bh(&sta->lock); 353 spin_unlock_bh(&sta->lock);
357 mpl_dbg("Mesh plink: starting establishment with %s\n", 354 mpl_dbg("Mesh plink: starting establishment with %s\n",
358 print_mac(mac, sta->addr)); 355 print_mac(mac, sta->sta.addr));
359 356
360 return mesh_plink_frame_tx(sdata->dev, PLINK_OPEN, 357 return mesh_plink_frame_tx(sdata, PLINK_OPEN,
361 sta->addr, llid, 0, 0); 358 sta->sta.addr, llid, 0, 0);
362} 359}
363 360
364void mesh_plink_block(struct sta_info *sta) 361void mesh_plink_block(struct sta_info *sta)
@@ -382,7 +379,7 @@ int mesh_plink_close(struct sta_info *sta)
382#endif 379#endif
383 380
384 mpl_dbg("Mesh plink: closing link with %s\n", 381 mpl_dbg("Mesh plink: closing link with %s\n",
385 print_mac(mac, sta->addr)); 382 print_mac(mac, sta->sta.addr));
386 spin_lock_bh(&sta->lock); 383 spin_lock_bh(&sta->lock);
387 sta->reason = cpu_to_le16(MESH_LINK_CANCELLED); 384 sta->reason = cpu_to_le16(MESH_LINK_CANCELLED);
388 reason = sta->reason; 385 reason = sta->reason;
@@ -403,15 +400,14 @@ int mesh_plink_close(struct sta_info *sta)
403 llid = sta->llid; 400 llid = sta->llid;
404 plid = sta->plid; 401 plid = sta->plid;
405 spin_unlock_bh(&sta->lock); 402 spin_unlock_bh(&sta->lock);
406 mesh_plink_frame_tx(sta->sdata->dev, PLINK_CLOSE, sta->addr, llid, 403 mesh_plink_frame_tx(sta->sdata, PLINK_CLOSE, sta->sta.addr, llid,
407 plid, reason); 404 plid, reason);
408 return 0; 405 return 0;
409} 406}
410 407
411void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt, 408void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt,
412 size_t len, struct ieee80211_rx_status *rx_status) 409 size_t len, struct ieee80211_rx_status *rx_status)
413{ 410{
414 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
415 struct ieee80211_local *local = sdata->local; 411 struct ieee80211_local *local = sdata->local;
416 struct ieee802_11_elems elems; 412 struct ieee802_11_elems elems;
417 struct sta_info *sta; 413 struct sta_info *sta;
@@ -425,6 +421,10 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
425 DECLARE_MAC_BUF(mac); 421 DECLARE_MAC_BUF(mac);
426#endif 422#endif
427 423
424 /* need action_code, aux */
425 if (len < IEEE80211_MIN_ACTION_SIZE + 3)
426 return;
427
428 if (is_multicast_ether_addr(mgmt->da)) { 428 if (is_multicast_ether_addr(mgmt->da)) {
429 mpl_dbg("Mesh plink: ignore frame from multicast address"); 429 mpl_dbg("Mesh plink: ignore frame from multicast address");
430 return; 430 return;
@@ -478,7 +478,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
478 478
479 /* Now we will figure out the appropriate event... */ 479 /* Now we will figure out the appropriate event... */
480 event = PLINK_UNDEFINED; 480 event = PLINK_UNDEFINED;
481 if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, dev))) { 481 if (ftype != PLINK_CLOSE && (!mesh_matches_local(&elems, sdata))) {
482 switch (ftype) { 482 switch (ftype) {
483 case PLINK_OPEN: 483 case PLINK_OPEN:
484 event = OPN_RJCT; 484 event = OPN_RJCT;
@@ -577,9 +577,9 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
577 sta->llid = llid; 577 sta->llid = llid;
578 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); 578 mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata));
579 spin_unlock_bh(&sta->lock); 579 spin_unlock_bh(&sta->lock);
580 mesh_plink_frame_tx(dev, PLINK_OPEN, sta->addr, llid, 580 mesh_plink_frame_tx(sdata, PLINK_OPEN, sta->sta.addr, llid,
581 0, 0); 581 0, 0);
582 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, 582 mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr,
583 llid, plid, 0); 583 llid, plid, 0);
584 break; 584 break;
585 default: 585 default:
@@ -604,7 +604,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
604 604
605 llid = sta->llid; 605 llid = sta->llid;
606 spin_unlock_bh(&sta->lock); 606 spin_unlock_bh(&sta->lock);
607 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, 607 mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid,
608 plid, reason); 608 plid, reason);
609 break; 609 break;
610 case OPN_ACPT: 610 case OPN_ACPT:
@@ -613,7 +613,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
613 sta->plid = plid; 613 sta->plid = plid;
614 llid = sta->llid; 614 llid = sta->llid;
615 spin_unlock_bh(&sta->lock); 615 spin_unlock_bh(&sta->lock);
616 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, 616 mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, llid,
617 plid, 0); 617 plid, 0);
618 break; 618 break;
619 case CNF_ACPT: 619 case CNF_ACPT:
@@ -646,13 +646,13 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
646 646
647 llid = sta->llid; 647 llid = sta->llid;
648 spin_unlock_bh(&sta->lock); 648 spin_unlock_bh(&sta->lock);
649 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, 649 mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid,
650 plid, reason); 650 plid, reason);
651 break; 651 break;
652 case OPN_ACPT: 652 case OPN_ACPT:
653 llid = sta->llid; 653 llid = sta->llid;
654 spin_unlock_bh(&sta->lock); 654 spin_unlock_bh(&sta->lock);
655 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, 655 mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, llid,
656 plid, 0); 656 plid, 0);
657 break; 657 break;
658 case CNF_ACPT: 658 case CNF_ACPT:
@@ -661,7 +661,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
661 mesh_plink_inc_estab_count(sdata); 661 mesh_plink_inc_estab_count(sdata);
662 spin_unlock_bh(&sta->lock); 662 spin_unlock_bh(&sta->lock);
663 mpl_dbg("Mesh plink with %s ESTABLISHED\n", 663 mpl_dbg("Mesh plink with %s ESTABLISHED\n",
664 print_mac(mac, sta->addr)); 664 print_mac(mac, sta->sta.addr));
665 break; 665 break;
666 default: 666 default:
667 spin_unlock_bh(&sta->lock); 667 spin_unlock_bh(&sta->lock);
@@ -685,7 +685,7 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
685 685
686 llid = sta->llid; 686 llid = sta->llid;
687 spin_unlock_bh(&sta->lock); 687 spin_unlock_bh(&sta->lock);
688 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, 688 mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid,
689 plid, reason); 689 plid, reason);
690 break; 690 break;
691 case OPN_ACPT: 691 case OPN_ACPT:
@@ -694,8 +694,8 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
694 mesh_plink_inc_estab_count(sdata); 694 mesh_plink_inc_estab_count(sdata);
695 spin_unlock_bh(&sta->lock); 695 spin_unlock_bh(&sta->lock);
696 mpl_dbg("Mesh plink with %s ESTABLISHED\n", 696 mpl_dbg("Mesh plink with %s ESTABLISHED\n",
697 print_mac(mac, sta->addr)); 697 print_mac(mac, sta->sta.addr));
698 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, 698 mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, llid,
699 plid, 0); 699 plid, 0);
700 break; 700 break;
701 default: 701 default:
@@ -714,13 +714,13 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
714 llid = sta->llid; 714 llid = sta->llid;
715 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata)); 715 mod_plink_timer(sta, dot11MeshHoldingTimeout(sdata));
716 spin_unlock_bh(&sta->lock); 716 spin_unlock_bh(&sta->lock);
717 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, 717 mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr, llid,
718 plid, reason); 718 plid, reason);
719 break; 719 break;
720 case OPN_ACPT: 720 case OPN_ACPT:
721 llid = sta->llid; 721 llid = sta->llid;
722 spin_unlock_bh(&sta->lock); 722 spin_unlock_bh(&sta->lock);
723 mesh_plink_frame_tx(dev, PLINK_CONFIRM, sta->addr, llid, 723 mesh_plink_frame_tx(sdata, PLINK_CONFIRM, sta->sta.addr, llid,
724 plid, 0); 724 plid, 0);
725 break; 725 break;
726 default: 726 default:
@@ -743,8 +743,8 @@ void mesh_rx_plink_frame(struct net_device *dev, struct ieee80211_mgmt *mgmt,
743 llid = sta->llid; 743 llid = sta->llid;
744 reason = sta->reason; 744 reason = sta->reason;
745 spin_unlock_bh(&sta->lock); 745 spin_unlock_bh(&sta->lock);
746 mesh_plink_frame_tx(dev, PLINK_CLOSE, sta->addr, llid, 746 mesh_plink_frame_tx(sdata, PLINK_CLOSE, sta->sta.addr,
747 plid, reason); 747 llid, plid, reason);
748 break; 748 break;
749 default: 749 default:
750 spin_unlock_bh(&sta->lock); 750 spin_unlock_bh(&sta->lock);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 9bb68c6a8f44..49f86fa56bff 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -11,11 +11,6 @@
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
12 */ 12 */
13 13
14/* TODO:
15 * order BSS list by RSSI(?) ("quality of AP")
16 * scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE,
17 * SSID)
18 */
19#include <linux/delay.h> 14#include <linux/delay.h>
20#include <linux/if_ether.h> 15#include <linux/if_ether.h>
21#include <linux/skbuff.h> 16#include <linux/skbuff.h>
@@ -26,577 +21,184 @@
26#include <linux/etherdevice.h> 21#include <linux/etherdevice.h>
27#include <linux/rtnetlink.h> 22#include <linux/rtnetlink.h>
28#include <net/iw_handler.h> 23#include <net/iw_handler.h>
29#include <asm/types.h>
30
31#include <net/mac80211.h> 24#include <net/mac80211.h>
25#include <asm/unaligned.h>
26
32#include "ieee80211_i.h" 27#include "ieee80211_i.h"
33#include "rate.h" 28#include "rate.h"
34#include "led.h" 29#include "led.h"
35#include "mesh.h"
36 30
31#define IEEE80211_ASSOC_SCANS_MAX_TRIES 2
37#define IEEE80211_AUTH_TIMEOUT (HZ / 5) 32#define IEEE80211_AUTH_TIMEOUT (HZ / 5)
38#define IEEE80211_AUTH_MAX_TRIES 3 33#define IEEE80211_AUTH_MAX_TRIES 3
39#define IEEE80211_ASSOC_TIMEOUT (HZ / 5) 34#define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
40#define IEEE80211_ASSOC_MAX_TRIES 3 35#define IEEE80211_ASSOC_MAX_TRIES 3
41#define IEEE80211_MONITORING_INTERVAL (2 * HZ) 36#define IEEE80211_MONITORING_INTERVAL (2 * HZ)
42#define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ)
43#define IEEE80211_PROBE_INTERVAL (60 * HZ) 37#define IEEE80211_PROBE_INTERVAL (60 * HZ)
44#define IEEE80211_RETRY_AUTH_INTERVAL (1 * HZ) 38#define IEEE80211_RETRY_AUTH_INTERVAL (1 * HZ)
45#define IEEE80211_SCAN_INTERVAL (2 * HZ) 39#define IEEE80211_SCAN_INTERVAL (2 * HZ)
46#define IEEE80211_SCAN_INTERVAL_SLOW (15 * HZ) 40#define IEEE80211_SCAN_INTERVAL_SLOW (15 * HZ)
47#define IEEE80211_IBSS_JOIN_TIMEOUT (7 * HZ) 41#define IEEE80211_IBSS_JOIN_TIMEOUT (7 * HZ)
48 42
49#define IEEE80211_PROBE_DELAY (HZ / 33)
50#define IEEE80211_CHANNEL_TIME (HZ / 33)
51#define IEEE80211_PASSIVE_CHANNEL_TIME (HZ / 5)
52#define IEEE80211_SCAN_RESULT_EXPIRE (10 * HZ)
53#define IEEE80211_IBSS_MERGE_INTERVAL (30 * HZ) 43#define IEEE80211_IBSS_MERGE_INTERVAL (30 * HZ)
54#define IEEE80211_IBSS_INACTIVITY_LIMIT (60 * HZ) 44#define IEEE80211_IBSS_INACTIVITY_LIMIT (60 * HZ)
55#define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ)
56 45
57#define IEEE80211_IBSS_MAX_STA_ENTRIES 128 46#define IEEE80211_IBSS_MAX_STA_ENTRIES 128
58 47
59 48
60#define ERP_INFO_USE_PROTECTION BIT(1) 49/* utils */
61
62/* mgmt header + 1 byte action code */
63#define IEEE80211_MIN_ACTION_SIZE (24 + 1)
64
65#define IEEE80211_ADDBA_PARAM_POLICY_MASK 0x0002
66#define IEEE80211_ADDBA_PARAM_TID_MASK 0x003C
67#define IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK 0xFFA0
68#define IEEE80211_DELBA_PARAM_TID_MASK 0xF000
69#define IEEE80211_DELBA_PARAM_INITIATOR_MASK 0x0800
70
71/* next values represent the buffer size for A-MPDU frame.
72 * According to IEEE802.11n spec size varies from 8K to 64K (in powers of 2) */
73#define IEEE80211_MIN_AMPDU_BUF 0x8
74#define IEEE80211_MAX_AMPDU_BUF 0x40
75
76static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst,
77 u8 *ssid, size_t ssid_len);
78static struct ieee80211_sta_bss *
79ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int freq,
80 u8 *ssid, u8 ssid_len);
81static void ieee80211_rx_bss_put(struct ieee80211_local *local,
82 struct ieee80211_sta_bss *bss);
83static int ieee80211_sta_find_ibss(struct net_device *dev,
84 struct ieee80211_if_sta *ifsta);
85static int ieee80211_sta_wep_configured(struct net_device *dev);
86static int ieee80211_sta_start_scan(struct net_device *dev,
87 u8 *ssid, size_t ssid_len);
88static int ieee80211_sta_config_auth(struct net_device *dev,
89 struct ieee80211_if_sta *ifsta);
90static void sta_rx_agg_session_timer_expired(unsigned long data);
91
92
93void ieee802_11_parse_elems(u8 *start, size_t len,
94 struct ieee802_11_elems *elems)
95{
96 size_t left = len;
97 u8 *pos = start;
98
99 memset(elems, 0, sizeof(*elems));
100
101 while (left >= 2) {
102 u8 id, elen;
103
104 id = *pos++;
105 elen = *pos++;
106 left -= 2;
107
108 if (elen > left)
109 return;
110
111 switch (id) {
112 case WLAN_EID_SSID:
113 elems->ssid = pos;
114 elems->ssid_len = elen;
115 break;
116 case WLAN_EID_SUPP_RATES:
117 elems->supp_rates = pos;
118 elems->supp_rates_len = elen;
119 break;
120 case WLAN_EID_FH_PARAMS:
121 elems->fh_params = pos;
122 elems->fh_params_len = elen;
123 break;
124 case WLAN_EID_DS_PARAMS:
125 elems->ds_params = pos;
126 elems->ds_params_len = elen;
127 break;
128 case WLAN_EID_CF_PARAMS:
129 elems->cf_params = pos;
130 elems->cf_params_len = elen;
131 break;
132 case WLAN_EID_TIM:
133 elems->tim = pos;
134 elems->tim_len = elen;
135 break;
136 case WLAN_EID_IBSS_PARAMS:
137 elems->ibss_params = pos;
138 elems->ibss_params_len = elen;
139 break;
140 case WLAN_EID_CHALLENGE:
141 elems->challenge = pos;
142 elems->challenge_len = elen;
143 break;
144 case WLAN_EID_WPA:
145 if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 &&
146 pos[2] == 0xf2) {
147 /* Microsoft OUI (00:50:F2) */
148 if (pos[3] == 1) {
149 /* OUI Type 1 - WPA IE */
150 elems->wpa = pos;
151 elems->wpa_len = elen;
152 } else if (elen >= 5 && pos[3] == 2) {
153 if (pos[4] == 0) {
154 elems->wmm_info = pos;
155 elems->wmm_info_len = elen;
156 } else if (pos[4] == 1) {
157 elems->wmm_param = pos;
158 elems->wmm_param_len = elen;
159 }
160 }
161 }
162 break;
163 case WLAN_EID_RSN:
164 elems->rsn = pos;
165 elems->rsn_len = elen;
166 break;
167 case WLAN_EID_ERP_INFO:
168 elems->erp_info = pos;
169 elems->erp_info_len = elen;
170 break;
171 case WLAN_EID_EXT_SUPP_RATES:
172 elems->ext_supp_rates = pos;
173 elems->ext_supp_rates_len = elen;
174 break;
175 case WLAN_EID_HT_CAPABILITY:
176 elems->ht_cap_elem = pos;
177 elems->ht_cap_elem_len = elen;
178 break;
179 case WLAN_EID_HT_EXTRA_INFO:
180 elems->ht_info_elem = pos;
181 elems->ht_info_elem_len = elen;
182 break;
183 case WLAN_EID_MESH_ID:
184 elems->mesh_id = pos;
185 elems->mesh_id_len = elen;
186 break;
187 case WLAN_EID_MESH_CONFIG:
188 elems->mesh_config = pos;
189 elems->mesh_config_len = elen;
190 break;
191 case WLAN_EID_PEER_LINK:
192 elems->peer_link = pos;
193 elems->peer_link_len = elen;
194 break;
195 case WLAN_EID_PREQ:
196 elems->preq = pos;
197 elems->preq_len = elen;
198 break;
199 case WLAN_EID_PREP:
200 elems->prep = pos;
201 elems->prep_len = elen;
202 break;
203 case WLAN_EID_PERR:
204 elems->perr = pos;
205 elems->perr_len = elen;
206 break;
207 case WLAN_EID_CHANNEL_SWITCH:
208 elems->ch_switch_elem = pos;
209 elems->ch_switch_elem_len = elen;
210 break;
211 case WLAN_EID_QUIET:
212 if (!elems->quiet_elem) {
213 elems->quiet_elem = pos;
214 elems->quiet_elem_len = elen;
215 }
216 elems->num_of_quiet_elem++;
217 break;
218 case WLAN_EID_COUNTRY:
219 elems->country_elem = pos;
220 elems->country_elem_len = elen;
221 break;
222 case WLAN_EID_PWR_CONSTRAINT:
223 elems->pwr_constr_elem = pos;
224 elems->pwr_constr_elem_len = elen;
225 break;
226 default:
227 break;
228 }
229
230 left -= elen;
231 pos += elen;
232 }
233}
234
235
236static int ecw2cw(int ecw) 50static int ecw2cw(int ecw)
237{ 51{
238 return (1 << ecw) - 1; 52 return (1 << ecw) - 1;
239} 53}
240 54
241 55static u8 *ieee80211_bss_get_ie(struct ieee80211_bss *bss, u8 ie)
242static void ieee80211_sta_def_wmm_params(struct net_device *dev,
243 struct ieee80211_sta_bss *bss,
244 int ibss)
245{
246 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
247 struct ieee80211_local *local = sdata->local;
248 int i, have_higher_than_11mbit = 0;
249
250
251 /* cf. IEEE 802.11 9.2.12 */
252 for (i = 0; i < bss->supp_rates_len; i++)
253 if ((bss->supp_rates[i] & 0x7f) * 5 > 110)
254 have_higher_than_11mbit = 1;
255
256 if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ &&
257 have_higher_than_11mbit)
258 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
259 else
260 sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;
261
262
263 if (local->ops->conf_tx) {
264 struct ieee80211_tx_queue_params qparam;
265
266 memset(&qparam, 0, sizeof(qparam));
267
268 qparam.aifs = 2;
269
270 if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ &&
271 !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE))
272 qparam.cw_min = 31;
273 else
274 qparam.cw_min = 15;
275
276 qparam.cw_max = 1023;
277 qparam.txop = 0;
278
279 for (i = 0; i < local_to_hw(local)->queues; i++)
280 local->ops->conf_tx(local_to_hw(local), i, &qparam);
281 }
282}
283
284static void ieee80211_sta_wmm_params(struct net_device *dev,
285 struct ieee80211_if_sta *ifsta,
286 u8 *wmm_param, size_t wmm_param_len)
287{ 56{
288 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 57 u8 *end, *pos;
289 struct ieee80211_tx_queue_params params;
290 size_t left;
291 int count;
292 u8 *pos;
293 58
294 if (!(ifsta->flags & IEEE80211_STA_WMM_ENABLED)) 59 pos = bss->ies;
295 return; 60 if (pos == NULL)
296 61 return NULL;
297 if (!wmm_param) 62 end = pos + bss->ies_len;
298 return;
299
300 if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1)
301 return;
302 count = wmm_param[6] & 0x0f;
303 if (count == ifsta->wmm_last_param_set)
304 return;
305 ifsta->wmm_last_param_set = count;
306
307 pos = wmm_param + 8;
308 left = wmm_param_len - 8;
309
310 memset(&params, 0, sizeof(params));
311
312 if (!local->ops->conf_tx)
313 return;
314
315 local->wmm_acm = 0;
316 for (; left >= 4; left -= 4, pos += 4) {
317 int aci = (pos[0] >> 5) & 0x03;
318 int acm = (pos[0] >> 4) & 0x01;
319 int queue;
320 63
321 switch (aci) { 64 while (pos + 1 < end) {
322 case 1: 65 if (pos + 2 + pos[1] > end)
323 queue = 3;
324 if (acm)
325 local->wmm_acm |= BIT(0) | BIT(3);
326 break;
327 case 2:
328 queue = 1;
329 if (acm)
330 local->wmm_acm |= BIT(4) | BIT(5);
331 break;
332 case 3:
333 queue = 0;
334 if (acm)
335 local->wmm_acm |= BIT(6) | BIT(7);
336 break; 66 break;
337 case 0: 67 if (pos[0] == ie)
338 default: 68 return pos;
339 queue = 2; 69 pos += 2 + pos[1];
340 if (acm)
341 local->wmm_acm |= BIT(1) | BIT(2);
342 break;
343 }
344
345 params.aifs = pos[0] & 0x0f;
346 params.cw_max = ecw2cw((pos[1] & 0xf0) >> 4);
347 params.cw_min = ecw2cw(pos[1] & 0x0f);
348 params.txop = get_unaligned_le16(pos + 2);
349#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
350 printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d "
351 "cWmin=%d cWmax=%d txop=%d\n",
352 dev->name, queue, aci, acm, params.aifs, params.cw_min,
353 params.cw_max, params.txop);
354#endif
355 /* TODO: handle ACM (block TX, fallback to next lowest allowed
356 * AC for now) */
357 if (local->ops->conf_tx(local_to_hw(local), queue, &params)) {
358 printk(KERN_DEBUG "%s: failed to set TX queue "
359 "parameters for queue %d\n", dev->name, queue);
360 }
361 }
362}
363
364static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata,
365 bool use_protection,
366 bool use_short_preamble)
367{
368 struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf;
369#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
370 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
371 DECLARE_MAC_BUF(mac);
372#endif
373 u32 changed = 0;
374
375 if (use_protection != bss_conf->use_cts_prot) {
376#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
377 if (net_ratelimit()) {
378 printk(KERN_DEBUG "%s: CTS protection %s (BSSID="
379 "%s)\n",
380 sdata->dev->name,
381 use_protection ? "enabled" : "disabled",
382 print_mac(mac, ifsta->bssid));
383 }
384#endif
385 bss_conf->use_cts_prot = use_protection;
386 changed |= BSS_CHANGED_ERP_CTS_PROT;
387 }
388
389 if (use_short_preamble != bss_conf->use_short_preamble) {
390#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
391 if (net_ratelimit()) {
392 printk(KERN_DEBUG "%s: switched to %s barker preamble"
393 " (BSSID=%s)\n",
394 sdata->dev->name,
395 use_short_preamble ? "short" : "long",
396 print_mac(mac, ifsta->bssid));
397 }
398#endif
399 bss_conf->use_short_preamble = use_short_preamble;
400 changed |= BSS_CHANGED_ERP_PREAMBLE;
401 }
402
403 return changed;
404}
405
406static u32 ieee80211_handle_erp_ie(struct ieee80211_sub_if_data *sdata,
407 u8 erp_value)
408{
409 bool use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0;
410 bool use_short_preamble = (erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0;
411
412 return ieee80211_handle_protect_preamb(sdata,
413 use_protection, use_short_preamble);
414}
415
416static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
417 struct ieee80211_sta_bss *bss)
418{
419 u32 changed = 0;
420
421 if (bss->has_erp_value)
422 changed |= ieee80211_handle_erp_ie(sdata, bss->erp_value);
423 else {
424 u16 capab = bss->capability;
425 changed |= ieee80211_handle_protect_preamb(sdata, false,
426 (capab & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0);
427 } 70 }
428 71
429 return changed; 72 return NULL;
430}
431
432int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie,
433 struct ieee80211_ht_info *ht_info)
434{
435
436 if (ht_info == NULL)
437 return -EINVAL;
438
439 memset(ht_info, 0, sizeof(*ht_info));
440
441 if (ht_cap_ie) {
442 u8 ampdu_info = ht_cap_ie->ampdu_params_info;
443
444 ht_info->ht_supported = 1;
445 ht_info->cap = le16_to_cpu(ht_cap_ie->cap_info);
446 ht_info->ampdu_factor =
447 ampdu_info & IEEE80211_HT_CAP_AMPDU_FACTOR;
448 ht_info->ampdu_density =
449 (ampdu_info & IEEE80211_HT_CAP_AMPDU_DENSITY) >> 2;
450 memcpy(ht_info->supp_mcs_set, ht_cap_ie->supp_mcs_set, 16);
451 } else
452 ht_info->ht_supported = 0;
453
454 return 0;
455} 73}
456 74
457int ieee80211_ht_addt_info_ie_to_ht_bss_info( 75static int ieee80211_compatible_rates(struct ieee80211_bss *bss,
458 struct ieee80211_ht_addt_info *ht_add_info_ie, 76 struct ieee80211_supported_band *sband,
459 struct ieee80211_ht_bss_info *bss_info) 77 u64 *rates)
460{ 78{
461 if (bss_info == NULL) 79 int i, j, count;
462 return -EINVAL; 80 *rates = 0;
463 81 count = 0;
464 memset(bss_info, 0, sizeof(*bss_info)); 82 for (i = 0; i < bss->supp_rates_len; i++) {
465 83 int rate = (bss->supp_rates[i] & 0x7F) * 5;
466 if (ht_add_info_ie) {
467 u16 op_mode;
468 op_mode = le16_to_cpu(ht_add_info_ie->operation_mode);
469 84
470 bss_info->primary_channel = ht_add_info_ie->control_chan; 85 for (j = 0; j < sband->n_bitrates; j++)
471 bss_info->bss_cap = ht_add_info_ie->ht_param; 86 if (sband->bitrates[j].bitrate == rate) {
472 bss_info->bss_op_mode = (u8)(op_mode & 0xff); 87 *rates |= BIT(j);
88 count++;
89 break;
90 }
473 } 91 }
474 92
475 return 0; 93 return count;
476} 94}
477 95
478static void ieee80211_sta_send_associnfo(struct net_device *dev, 96/* also used by mesh code */
479 struct ieee80211_if_sta *ifsta) 97u64 ieee80211_sta_get_rates(struct ieee80211_local *local,
98 struct ieee802_11_elems *elems,
99 enum ieee80211_band band)
480{ 100{
481 union iwreq_data wrqu; 101 struct ieee80211_supported_band *sband;
102 struct ieee80211_rate *bitrates;
103 size_t num_rates;
104 u64 supp_rates;
105 int i, j;
106 sband = local->hw.wiphy->bands[band];
482 107
483 if (ifsta->assocreq_ies) { 108 if (!sband) {
484 memset(&wrqu, 0, sizeof(wrqu)); 109 WARN_ON(1);
485 wrqu.data.length = ifsta->assocreq_ies_len; 110 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
486 wireless_send_event(dev, IWEVASSOCREQIE, &wrqu,
487 ifsta->assocreq_ies);
488 } 111 }
489 112
490 if (ifsta->assocresp_ies) { 113 bitrates = sband->bitrates;
491 memset(&wrqu, 0, sizeof(wrqu)); 114 num_rates = sband->n_bitrates;
492 wrqu.data.length = ifsta->assocresp_ies_len; 115 supp_rates = 0;
493 wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, 116 for (i = 0; i < elems->supp_rates_len +
494 ifsta->assocresp_ies); 117 elems->ext_supp_rates_len; i++) {
118 u8 rate = 0;
119 int own_rate;
120 if (i < elems->supp_rates_len)
121 rate = elems->supp_rates[i];
122 else if (elems->ext_supp_rates)
123 rate = elems->ext_supp_rates
124 [i - elems->supp_rates_len];
125 own_rate = 5 * (rate & 0x7f);
126 for (j = 0; j < num_rates; j++)
127 if (bitrates[j].bitrate == own_rate)
128 supp_rates |= BIT(j);
495 } 129 }
130 return supp_rates;
496} 131}
497 132
133/* frame sending functions */
498 134
499static void ieee80211_set_associated(struct net_device *dev, 135/* also used by scanning code */
500 struct ieee80211_if_sta *ifsta, 136void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
501 bool assoc) 137 u8 *ssid, size_t ssid_len)
502{ 138{
503 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
504 struct ieee80211_local *local = sdata->local; 139 struct ieee80211_local *local = sdata->local;
505 struct ieee80211_conf *conf = &local_to_hw(local)->conf; 140 struct ieee80211_supported_band *sband;
506 union iwreq_data wrqu; 141 struct sk_buff *skb;
507 u32 changed = BSS_CHANGED_ASSOC; 142 struct ieee80211_mgmt *mgmt;
508 143 u8 *pos, *supp_rates, *esupp_rates = NULL;
509 if (assoc) { 144 int i;
510 struct ieee80211_sta_bss *bss;
511
512 ifsta->flags |= IEEE80211_STA_ASSOCIATED;
513
514 if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
515 return;
516
517 bss = ieee80211_rx_bss_get(dev, ifsta->bssid,
518 conf->channel->center_freq,
519 ifsta->ssid, ifsta->ssid_len);
520 if (bss) {
521 /* set timing information */
522 sdata->bss_conf.beacon_int = bss->beacon_int;
523 sdata->bss_conf.timestamp = bss->timestamp;
524 sdata->bss_conf.dtim_period = bss->dtim_period;
525
526 changed |= ieee80211_handle_bss_capability(sdata, bss);
527
528 ieee80211_rx_bss_put(local, bss);
529 }
530 145
531 if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { 146 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200);
532 changed |= BSS_CHANGED_HT; 147 if (!skb) {
533 sdata->bss_conf.assoc_ht = 1; 148 printk(KERN_DEBUG "%s: failed to allocate buffer for probe "
534 sdata->bss_conf.ht_conf = &conf->ht_conf; 149 "request\n", sdata->dev->name);
535 sdata->bss_conf.ht_bss_conf = &conf->ht_bss_conf; 150 return;
536 } 151 }
152 skb_reserve(skb, local->hw.extra_tx_headroom);
537 153
538 ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET; 154 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
539 memcpy(ifsta->prev_bssid, sdata->u.sta.bssid, ETH_ALEN); 155 memset(mgmt, 0, 24);
540 memcpy(wrqu.ap_addr.sa_data, sdata->u.sta.bssid, ETH_ALEN); 156 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
541 ieee80211_sta_send_associnfo(dev, ifsta); 157 IEEE80211_STYPE_PROBE_REQ);
158 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
159 if (dst) {
160 memcpy(mgmt->da, dst, ETH_ALEN);
161 memcpy(mgmt->bssid, dst, ETH_ALEN);
542 } else { 162 } else {
543 netif_carrier_off(dev); 163 memset(mgmt->da, 0xff, ETH_ALEN);
544 ieee80211_sta_tear_down_BA_sessions(dev, ifsta->bssid); 164 memset(mgmt->bssid, 0xff, ETH_ALEN);
545 ifsta->flags &= ~IEEE80211_STA_ASSOCIATED;
546 changed |= ieee80211_reset_erp_info(dev);
547
548 sdata->bss_conf.assoc_ht = 0;
549 sdata->bss_conf.ht_conf = NULL;
550 sdata->bss_conf.ht_bss_conf = NULL;
551
552 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
553 } 165 }
554 ifsta->last_probe = jiffies; 166 pos = skb_put(skb, 2 + ssid_len);
555 ieee80211_led_assoc(local, assoc); 167 *pos++ = WLAN_EID_SSID;
556 168 *pos++ = ssid_len;
557 sdata->bss_conf.assoc = assoc; 169 memcpy(pos, ssid, ssid_len);
558 ieee80211_bss_info_change_notify(sdata, changed);
559
560 if (assoc)
561 netif_carrier_on(dev);
562
563 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
564 wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
565}
566
567static void ieee80211_set_disassoc(struct net_device *dev,
568 struct ieee80211_if_sta *ifsta, int deauth)
569{
570 if (deauth)
571 ifsta->auth_tries = 0;
572 ifsta->assoc_tries = 0;
573 ieee80211_set_associated(dev, ifsta, 0);
574}
575
576void ieee80211_sta_tx(struct net_device *dev, struct sk_buff *skb,
577 int encrypt)
578{
579 struct ieee80211_sub_if_data *sdata;
580 170
581 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 171 supp_rates = skb_put(skb, 2);
582 skb->dev = sdata->local->mdev; 172 supp_rates[0] = WLAN_EID_SUPP_RATES;
583 skb_set_mac_header(skb, 0); 173 supp_rates[1] = 0;
584 skb_set_network_header(skb, 0); 174 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
585 skb_set_transport_header(skb, 0);
586 175
587 skb->iif = sdata->dev->ifindex; 176 for (i = 0; i < sband->n_bitrates; i++) {
588 skb->do_not_encrypt = !encrypt; 177 struct ieee80211_rate *rate = &sband->bitrates[i];
178 if (esupp_rates) {
179 pos = skb_put(skb, 1);
180 esupp_rates[1]++;
181 } else if (supp_rates[1] == 8) {
182 esupp_rates = skb_put(skb, 3);
183 esupp_rates[0] = WLAN_EID_EXT_SUPP_RATES;
184 esupp_rates[1] = 1;
185 pos = &esupp_rates[2];
186 } else {
187 pos = skb_put(skb, 1);
188 supp_rates[1]++;
189 }
190 *pos = rate->bitrate / 5;
191 }
589 192
590 dev_queue_xmit(skb); 193 ieee80211_tx_skb(sdata, skb, 0);
591} 194}
592 195
593 196static void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
594static void ieee80211_send_auth(struct net_device *dev,
595 struct ieee80211_if_sta *ifsta, 197 struct ieee80211_if_sta *ifsta,
596 int transaction, u8 *extra, size_t extra_len, 198 int transaction, u8 *extra, size_t extra_len,
597 int encrypt) 199 int encrypt)
598{ 200{
599 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 201 struct ieee80211_local *local = sdata->local;
600 struct sk_buff *skb; 202 struct sk_buff *skb;
601 struct ieee80211_mgmt *mgmt; 203 struct ieee80211_mgmt *mgmt;
602 204
@@ -604,19 +206,19 @@ static void ieee80211_send_auth(struct net_device *dev,
604 sizeof(*mgmt) + 6 + extra_len); 206 sizeof(*mgmt) + 6 + extra_len);
605 if (!skb) { 207 if (!skb) {
606 printk(KERN_DEBUG "%s: failed to allocate buffer for auth " 208 printk(KERN_DEBUG "%s: failed to allocate buffer for auth "
607 "frame\n", dev->name); 209 "frame\n", sdata->dev->name);
608 return; 210 return;
609 } 211 }
610 skb_reserve(skb, local->hw.extra_tx_headroom); 212 skb_reserve(skb, local->hw.extra_tx_headroom);
611 213
612 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24 + 6); 214 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24 + 6);
613 memset(mgmt, 0, 24 + 6); 215 memset(mgmt, 0, 24 + 6);
614 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, 216 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
615 IEEE80211_STYPE_AUTH); 217 IEEE80211_STYPE_AUTH);
616 if (encrypt) 218 if (encrypt)
617 mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); 219 mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
618 memcpy(mgmt->da, ifsta->bssid, ETH_ALEN); 220 memcpy(mgmt->da, ifsta->bssid, ETH_ALEN);
619 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); 221 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
620 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); 222 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
621 mgmt->u.auth.auth_alg = cpu_to_le16(ifsta->auth_alg); 223 mgmt->u.auth.auth_alg = cpu_to_le16(ifsta->auth_alg);
622 mgmt->u.auth.auth_transaction = cpu_to_le16(transaction); 224 mgmt->u.auth.auth_transaction = cpu_to_le16(transaction);
@@ -625,64 +227,19 @@ static void ieee80211_send_auth(struct net_device *dev,
625 if (extra) 227 if (extra)
626 memcpy(skb_put(skb, extra_len), extra, extra_len); 228 memcpy(skb_put(skb, extra_len), extra, extra_len);
627 229
628 ieee80211_sta_tx(dev, skb, encrypt); 230 ieee80211_tx_skb(sdata, skb, encrypt);
629}
630
631
632static void ieee80211_authenticate(struct net_device *dev,
633 struct ieee80211_if_sta *ifsta)
634{
635 DECLARE_MAC_BUF(mac);
636
637 ifsta->auth_tries++;
638 if (ifsta->auth_tries > IEEE80211_AUTH_MAX_TRIES) {
639 printk(KERN_DEBUG "%s: authentication with AP %s"
640 " timed out\n",
641 dev->name, print_mac(mac, ifsta->bssid));
642 ifsta->state = IEEE80211_DISABLED;
643 return;
644 }
645
646 ifsta->state = IEEE80211_AUTHENTICATE;
647 printk(KERN_DEBUG "%s: authenticate with AP %s\n",
648 dev->name, print_mac(mac, ifsta->bssid));
649
650 ieee80211_send_auth(dev, ifsta, 1, NULL, 0, 0);
651
652 mod_timer(&ifsta->timer, jiffies + IEEE80211_AUTH_TIMEOUT);
653} 231}
654 232
655static int ieee80211_compatible_rates(struct ieee80211_sta_bss *bss, 233static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
656 struct ieee80211_supported_band *sband,
657 u64 *rates)
658{
659 int i, j, count;
660 *rates = 0;
661 count = 0;
662 for (i = 0; i < bss->supp_rates_len; i++) {
663 int rate = (bss->supp_rates[i] & 0x7F) * 5;
664
665 for (j = 0; j < sband->n_bitrates; j++)
666 if (sband->bitrates[j].bitrate == rate) {
667 *rates |= BIT(j);
668 count++;
669 break;
670 }
671 }
672
673 return count;
674}
675
676static void ieee80211_send_assoc(struct net_device *dev,
677 struct ieee80211_if_sta *ifsta) 234 struct ieee80211_if_sta *ifsta)
678{ 235{
679 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 236 struct ieee80211_local *local = sdata->local;
680 struct sk_buff *skb; 237 struct sk_buff *skb;
681 struct ieee80211_mgmt *mgmt; 238 struct ieee80211_mgmt *mgmt;
682 u8 *pos, *ies; 239 u8 *pos, *ies, *ht_add_ie;
683 int i, len, count, rates_len, supp_rates_len; 240 int i, len, count, rates_len, supp_rates_len;
684 u16 capab; 241 u16 capab;
685 struct ieee80211_sta_bss *bss; 242 struct ieee80211_bss *bss;
686 int wmm = 0; 243 int wmm = 0;
687 struct ieee80211_supported_band *sband; 244 struct ieee80211_supported_band *sband;
688 u64 rates = 0; 245 u64 rates = 0;
@@ -692,7 +249,7 @@ static void ieee80211_send_assoc(struct net_device *dev,
692 ifsta->ssid_len); 249 ifsta->ssid_len);
693 if (!skb) { 250 if (!skb) {
694 printk(KERN_DEBUG "%s: failed to allocate buffer for assoc " 251 printk(KERN_DEBUG "%s: failed to allocate buffer for assoc "
695 "frame\n", dev->name); 252 "frame\n", sdata->dev->name);
696 return; 253 return;
697 } 254 }
698 skb_reserve(skb, local->hw.extra_tx_headroom); 255 skb_reserve(skb, local->hw.extra_tx_headroom);
@@ -708,13 +265,13 @@ static void ieee80211_send_assoc(struct net_device *dev,
708 capab |= WLAN_CAPABILITY_SHORT_PREAMBLE; 265 capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
709 } 266 }
710 267
711 bss = ieee80211_rx_bss_get(dev, ifsta->bssid, 268 bss = ieee80211_rx_bss_get(local, ifsta->bssid,
712 local->hw.conf.channel->center_freq, 269 local->hw.conf.channel->center_freq,
713 ifsta->ssid, ifsta->ssid_len); 270 ifsta->ssid, ifsta->ssid_len);
714 if (bss) { 271 if (bss) {
715 if (bss->capability & WLAN_CAPABILITY_PRIVACY) 272 if (bss->capability & WLAN_CAPABILITY_PRIVACY)
716 capab |= WLAN_CAPABILITY_PRIVACY; 273 capab |= WLAN_CAPABILITY_PRIVACY;
717 if (bss->wmm_ie) 274 if (bss->wmm_used)
718 wmm = 1; 275 wmm = 1;
719 276
720 /* get all rates supported by the device and the AP as 277 /* get all rates supported by the device and the AP as
@@ -736,13 +293,13 @@ static void ieee80211_send_assoc(struct net_device *dev,
736 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); 293 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
737 memset(mgmt, 0, 24); 294 memset(mgmt, 0, 24);
738 memcpy(mgmt->da, ifsta->bssid, ETH_ALEN); 295 memcpy(mgmt->da, ifsta->bssid, ETH_ALEN);
739 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); 296 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
740 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); 297 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
741 298
742 if (ifsta->flags & IEEE80211_STA_PREV_BSSID_SET) { 299 if (ifsta->flags & IEEE80211_STA_PREV_BSSID_SET) {
743 skb_put(skb, 10); 300 skb_put(skb, 10);
744 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, 301 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
745 IEEE80211_STYPE_REASSOC_REQ); 302 IEEE80211_STYPE_REASSOC_REQ);
746 mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab); 303 mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab);
747 mgmt->u.reassoc_req.listen_interval = 304 mgmt->u.reassoc_req.listen_interval =
748 cpu_to_le16(local->hw.conf.listen_interval); 305 cpu_to_le16(local->hw.conf.listen_interval);
@@ -750,8 +307,8 @@ static void ieee80211_send_assoc(struct net_device *dev,
750 ETH_ALEN); 307 ETH_ALEN);
751 } else { 308 } else {
752 skb_put(skb, 4); 309 skb_put(skb, 4);
753 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, 310 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
754 IEEE80211_STYPE_ASSOC_REQ); 311 IEEE80211_STYPE_ASSOC_REQ);
755 mgmt->u.assoc_req.capab_info = cpu_to_le16(capab); 312 mgmt->u.assoc_req.capab_info = cpu_to_le16(capab);
756 mgmt->u.reassoc_req.listen_interval = 313 mgmt->u.reassoc_req.listen_interval =
757 cpu_to_le16(local->hw.conf.listen_interval); 314 cpu_to_le16(local->hw.conf.listen_interval);
@@ -836,9 +393,10 @@ static void ieee80211_send_assoc(struct net_device *dev,
836 393
837 /* wmm support is a must to HT */ 394 /* wmm support is a must to HT */
838 if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) && 395 if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) &&
839 sband->ht_info.ht_supported && bss->ht_add_ie) { 396 sband->ht_info.ht_supported &&
397 (ht_add_ie = ieee80211_bss_get_ie(bss, WLAN_EID_HT_EXTRA_INFO))) {
840 struct ieee80211_ht_addt_info *ht_add_info = 398 struct ieee80211_ht_addt_info *ht_add_info =
841 (struct ieee80211_ht_addt_info *)bss->ht_add_ie; 399 (struct ieee80211_ht_addt_info *)ht_add_ie;
842 u16 cap = sband->ht_info.cap; 400 u16 cap = sband->ht_info.cap;
843 __le16 tmp; 401 __le16 tmp;
844 u32 flags = local->hw.conf.channel->flags; 402 u32 flags = local->hw.conf.channel->flags;
@@ -877,21 +435,22 @@ static void ieee80211_send_assoc(struct net_device *dev,
877 if (ifsta->assocreq_ies) 435 if (ifsta->assocreq_ies)
878 memcpy(ifsta->assocreq_ies, ies, ifsta->assocreq_ies_len); 436 memcpy(ifsta->assocreq_ies, ies, ifsta->assocreq_ies_len);
879 437
880 ieee80211_sta_tx(dev, skb, 0); 438 ieee80211_tx_skb(sdata, skb, 0);
881} 439}
882 440
883 441
884static void ieee80211_send_deauth(struct net_device *dev, 442static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
885 struct ieee80211_if_sta *ifsta, u16 reason) 443 u16 stype, u16 reason)
886{ 444{
887 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 445 struct ieee80211_local *local = sdata->local;
446 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
888 struct sk_buff *skb; 447 struct sk_buff *skb;
889 struct ieee80211_mgmt *mgmt; 448 struct ieee80211_mgmt *mgmt;
890 449
891 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt)); 450 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt));
892 if (!skb) { 451 if (!skb) {
893 printk(KERN_DEBUG "%s: failed to allocate buffer for deauth " 452 printk(KERN_DEBUG "%s: failed to allocate buffer for "
894 "frame\n", dev->name); 453 "deauth/disassoc frame\n", sdata->dev->name);
895 return; 454 return;
896 } 455 }
897 skb_reserve(skb, local->hw.extra_tx_headroom); 456 skb_reserve(skb, local->hw.extra_tx_headroom);
@@ -899,940 +458,594 @@ static void ieee80211_send_deauth(struct net_device *dev,
899 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); 458 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
900 memset(mgmt, 0, 24); 459 memset(mgmt, 0, 24);
901 memcpy(mgmt->da, ifsta->bssid, ETH_ALEN); 460 memcpy(mgmt->da, ifsta->bssid, ETH_ALEN);
902 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); 461 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
903 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); 462 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
904 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, 463 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | stype);
905 IEEE80211_STYPE_DEAUTH);
906 skb_put(skb, 2); 464 skb_put(skb, 2);
465 /* u.deauth.reason_code == u.disassoc.reason_code */
907 mgmt->u.deauth.reason_code = cpu_to_le16(reason); 466 mgmt->u.deauth.reason_code = cpu_to_le16(reason);
908 467
909 ieee80211_sta_tx(dev, skb, 0); 468 ieee80211_tx_skb(sdata, skb, 0);
910} 469}
911 470
912 471/* MLME */
913static void ieee80211_send_disassoc(struct net_device *dev, 472static void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
914 struct ieee80211_if_sta *ifsta, u16 reason) 473 struct ieee80211_bss *bss)
915{ 474{
916 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 475 struct ieee80211_local *local = sdata->local;
917 struct sk_buff *skb; 476 int i, have_higher_than_11mbit = 0;
918 struct ieee80211_mgmt *mgmt;
919 477
920 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt)); 478 /* cf. IEEE 802.11 9.2.12 */
921 if (!skb) { 479 for (i = 0; i < bss->supp_rates_len; i++)
922 printk(KERN_DEBUG "%s: failed to allocate buffer for disassoc " 480 if ((bss->supp_rates[i] & 0x7f) * 5 > 110)
923 "frame\n", dev->name); 481 have_higher_than_11mbit = 1;
924 return;
925 }
926 skb_reserve(skb, local->hw.extra_tx_headroom);
927 482
928 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); 483 if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ &&
929 memset(mgmt, 0, 24); 484 have_higher_than_11mbit)
930 memcpy(mgmt->da, ifsta->bssid, ETH_ALEN); 485 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
931 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); 486 else
932 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); 487 sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;
933 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
934 IEEE80211_STYPE_DISASSOC);
935 skb_put(skb, 2);
936 mgmt->u.disassoc.reason_code = cpu_to_le16(reason);
937 488
938 ieee80211_sta_tx(dev, skb, 0); 489 ieee80211_set_wmm_default(sdata);
939} 490}
940 491
941 492static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
942static int ieee80211_privacy_mismatch(struct net_device *dev, 493 struct ieee80211_if_sta *ifsta,
943 struct ieee80211_if_sta *ifsta) 494 u8 *wmm_param, size_t wmm_param_len)
944{ 495{
945 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 496 struct ieee80211_tx_queue_params params;
946 struct ieee80211_sta_bss *bss; 497 size_t left;
947 int bss_privacy; 498 int count;
948 int wep_privacy; 499 u8 *pos;
949 int privacy_invoked;
950 500
951 if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL)) 501 if (!(ifsta->flags & IEEE80211_STA_WMM_ENABLED))
952 return 0; 502 return;
953 503
954 bss = ieee80211_rx_bss_get(dev, ifsta->bssid, 504 if (!wmm_param)
955 local->hw.conf.channel->center_freq, 505 return;
956 ifsta->ssid, ifsta->ssid_len);
957 if (!bss)
958 return 0;
959 506
960 bss_privacy = !!(bss->capability & WLAN_CAPABILITY_PRIVACY); 507 if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1)
961 wep_privacy = !!ieee80211_sta_wep_configured(dev); 508 return;
962 privacy_invoked = !!(ifsta->flags & IEEE80211_STA_PRIVACY_INVOKED); 509 count = wmm_param[6] & 0x0f;
510 if (count == ifsta->wmm_last_param_set)
511 return;
512 ifsta->wmm_last_param_set = count;
963 513
964 ieee80211_rx_bss_put(local, bss); 514 pos = wmm_param + 8;
515 left = wmm_param_len - 8;
965 516
966 if ((bss_privacy == wep_privacy) || (bss_privacy == privacy_invoked)) 517 memset(&params, 0, sizeof(params));
967 return 0;
968 518
969 return 1; 519 if (!local->ops->conf_tx)
970} 520 return;
521
522 local->wmm_acm = 0;
523 for (; left >= 4; left -= 4, pos += 4) {
524 int aci = (pos[0] >> 5) & 0x03;
525 int acm = (pos[0] >> 4) & 0x01;
526 int queue;
971 527
528 switch (aci) {
529 case 1:
530 queue = 3;
531 if (acm)
532 local->wmm_acm |= BIT(0) | BIT(3);
533 break;
534 case 2:
535 queue = 1;
536 if (acm)
537 local->wmm_acm |= BIT(4) | BIT(5);
538 break;
539 case 3:
540 queue = 0;
541 if (acm)
542 local->wmm_acm |= BIT(6) | BIT(7);
543 break;
544 case 0:
545 default:
546 queue = 2;
547 if (acm)
548 local->wmm_acm |= BIT(1) | BIT(2);
549 break;
550 }
972 551
973static void ieee80211_associate(struct net_device *dev, 552 params.aifs = pos[0] & 0x0f;
974 struct ieee80211_if_sta *ifsta) 553 params.cw_max = ecw2cw((pos[1] & 0xf0) >> 4);
554 params.cw_min = ecw2cw(pos[1] & 0x0f);
555 params.txop = get_unaligned_le16(pos + 2);
556#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
557 printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d "
558 "cWmin=%d cWmax=%d txop=%d\n",
559 local->mdev->name, queue, aci, acm, params.aifs, params.cw_min,
560 params.cw_max, params.txop);
561#endif
562 /* TODO: handle ACM (block TX, fallback to next lowest allowed
563 * AC for now) */
564 if (local->ops->conf_tx(local_to_hw(local), queue, &params)) {
565 printk(KERN_DEBUG "%s: failed to set TX queue "
566 "parameters for queue %d\n", local->mdev->name, queue);
567 }
568 }
569}
570
571static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata,
572 bool use_protection,
573 bool use_short_preamble)
975{ 574{
575 struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf;
576#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
577 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
976 DECLARE_MAC_BUF(mac); 578 DECLARE_MAC_BUF(mac);
579#endif
580 u32 changed = 0;
977 581
978 ifsta->assoc_tries++; 582 if (use_protection != bss_conf->use_cts_prot) {
979 if (ifsta->assoc_tries > IEEE80211_ASSOC_MAX_TRIES) { 583#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
980 printk(KERN_DEBUG "%s: association with AP %s" 584 if (net_ratelimit()) {
981 " timed out\n", 585 printk(KERN_DEBUG "%s: CTS protection %s (BSSID="
982 dev->name, print_mac(mac, ifsta->bssid)); 586 "%s)\n",
983 ifsta->state = IEEE80211_DISABLED; 587 sdata->dev->name,
984 return; 588 use_protection ? "enabled" : "disabled",
589 print_mac(mac, ifsta->bssid));
590 }
591#endif
592 bss_conf->use_cts_prot = use_protection;
593 changed |= BSS_CHANGED_ERP_CTS_PROT;
985 } 594 }
986 595
987 ifsta->state = IEEE80211_ASSOCIATE; 596 if (use_short_preamble != bss_conf->use_short_preamble) {
988 printk(KERN_DEBUG "%s: associate with AP %s\n", 597#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
989 dev->name, print_mac(mac, ifsta->bssid)); 598 if (net_ratelimit()) {
990 if (ieee80211_privacy_mismatch(dev, ifsta)) { 599 printk(KERN_DEBUG "%s: switched to %s barker preamble"
991 printk(KERN_DEBUG "%s: mismatch in privacy configuration and " 600 " (BSSID=%s)\n",
992 "mixed-cell disabled - abort association\n", dev->name); 601 sdata->dev->name,
993 ifsta->state = IEEE80211_DISABLED; 602 use_short_preamble ? "short" : "long",
994 return; 603 print_mac(mac, ifsta->bssid));
604 }
605#endif
606 bss_conf->use_short_preamble = use_short_preamble;
607 changed |= BSS_CHANGED_ERP_PREAMBLE;
995 } 608 }
996 609
997 ieee80211_send_assoc(dev, ifsta); 610 return changed;
998
999 mod_timer(&ifsta->timer, jiffies + IEEE80211_ASSOC_TIMEOUT);
1000} 611}
1001 612
1002 613static u32 ieee80211_handle_erp_ie(struct ieee80211_sub_if_data *sdata,
1003static void ieee80211_associated(struct net_device *dev, 614 u8 erp_value)
1004 struct ieee80211_if_sta *ifsta)
1005{ 615{
1006 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 616 bool use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0;
1007 struct sta_info *sta; 617 bool use_short_preamble = (erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0;
1008 int disassoc;
1009 DECLARE_MAC_BUF(mac);
1010
1011 /* TODO: start monitoring current AP signal quality and number of
1012 * missed beacons. Scan other channels every now and then and search
1013 * for better APs. */
1014 /* TODO: remove expired BSSes */
1015 618
1016 ifsta->state = IEEE80211_ASSOCIATED; 619 return ieee80211_handle_protect_preamb(sdata,
620 use_protection, use_short_preamble);
621}
1017 622
1018 rcu_read_lock(); 623static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
624 struct ieee80211_bss *bss)
625{
626 u32 changed = 0;
1019 627
1020 sta = sta_info_get(local, ifsta->bssid); 628 if (bss->has_erp_value)
1021 if (!sta) { 629 changed |= ieee80211_handle_erp_ie(sdata, bss->erp_value);
1022 printk(KERN_DEBUG "%s: No STA entry for own AP %s\n", 630 else {
1023 dev->name, print_mac(mac, ifsta->bssid)); 631 u16 capab = bss->capability;
1024 disassoc = 1; 632 changed |= ieee80211_handle_protect_preamb(sdata, false,
1025 } else { 633 (capab & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0);
1026 disassoc = 0;
1027 if (time_after(jiffies,
1028 sta->last_rx + IEEE80211_MONITORING_INTERVAL)) {
1029 if (ifsta->flags & IEEE80211_STA_PROBEREQ_POLL) {
1030 printk(KERN_DEBUG "%s: No ProbeResp from "
1031 "current AP %s - assume out of "
1032 "range\n",
1033 dev->name, print_mac(mac, ifsta->bssid));
1034 disassoc = 1;
1035 sta_info_unlink(&sta);
1036 } else
1037 ieee80211_send_probe_req(dev, ifsta->bssid,
1038 local->scan_ssid,
1039 local->scan_ssid_len);
1040 ifsta->flags ^= IEEE80211_STA_PROBEREQ_POLL;
1041 } else {
1042 ifsta->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
1043 if (time_after(jiffies, ifsta->last_probe +
1044 IEEE80211_PROBE_INTERVAL)) {
1045 ifsta->last_probe = jiffies;
1046 ieee80211_send_probe_req(dev, ifsta->bssid,
1047 ifsta->ssid,
1048 ifsta->ssid_len);
1049 }
1050 }
1051 } 634 }
1052 635
1053 rcu_read_unlock(); 636 return changed;
1054
1055 if (disassoc && sta)
1056 sta_info_destroy(sta);
1057
1058 if (disassoc) {
1059 ifsta->state = IEEE80211_DISABLED;
1060 ieee80211_set_associated(dev, ifsta, 0);
1061 } else {
1062 mod_timer(&ifsta->timer, jiffies +
1063 IEEE80211_MONITORING_INTERVAL);
1064 }
1065} 637}
1066 638
639static void ieee80211_sta_send_apinfo(struct ieee80211_sub_if_data *sdata,
640 struct ieee80211_if_sta *ifsta)
641{
642 union iwreq_data wrqu;
643 memset(&wrqu, 0, sizeof(wrqu));
644 if (ifsta->flags & IEEE80211_STA_ASSOCIATED)
645 memcpy(wrqu.ap_addr.sa_data, sdata->u.sta.bssid, ETH_ALEN);
646 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
647 wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL);
648}
1067 649
1068static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, 650static void ieee80211_sta_send_associnfo(struct ieee80211_sub_if_data *sdata,
1069 u8 *ssid, size_t ssid_len) 651 struct ieee80211_if_sta *ifsta)
1070{ 652{
1071 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 653 char *buf;
1072 struct ieee80211_supported_band *sband; 654 size_t len;
1073 struct sk_buff *skb;
1074 struct ieee80211_mgmt *mgmt;
1075 u8 *pos, *supp_rates, *esupp_rates = NULL;
1076 int i; 655 int i;
656 union iwreq_data wrqu;
1077 657
1078 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200); 658 if (!ifsta->assocreq_ies && !ifsta->assocresp_ies)
1079 if (!skb) {
1080 printk(KERN_DEBUG "%s: failed to allocate buffer for probe "
1081 "request\n", dev->name);
1082 return; 659 return;
1083 }
1084 skb_reserve(skb, local->hw.extra_tx_headroom);
1085
1086 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
1087 memset(mgmt, 0, 24);
1088 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
1089 IEEE80211_STYPE_PROBE_REQ);
1090 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN);
1091 if (dst) {
1092 memcpy(mgmt->da, dst, ETH_ALEN);
1093 memcpy(mgmt->bssid, dst, ETH_ALEN);
1094 } else {
1095 memset(mgmt->da, 0xff, ETH_ALEN);
1096 memset(mgmt->bssid, 0xff, ETH_ALEN);
1097 }
1098 pos = skb_put(skb, 2 + ssid_len);
1099 *pos++ = WLAN_EID_SSID;
1100 *pos++ = ssid_len;
1101 memcpy(pos, ssid, ssid_len);
1102 660
1103 supp_rates = skb_put(skb, 2); 661 buf = kmalloc(50 + 2 * (ifsta->assocreq_ies_len +
1104 supp_rates[0] = WLAN_EID_SUPP_RATES; 662 ifsta->assocresp_ies_len), GFP_KERNEL);
1105 supp_rates[1] = 0; 663 if (!buf)
1106 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 664 return;
1107 665
1108 for (i = 0; i < sband->n_bitrates; i++) { 666 len = sprintf(buf, "ASSOCINFO(");
1109 struct ieee80211_rate *rate = &sband->bitrates[i]; 667 if (ifsta->assocreq_ies) {
1110 if (esupp_rates) { 668 len += sprintf(buf + len, "ReqIEs=");
1111 pos = skb_put(skb, 1); 669 for (i = 0; i < ifsta->assocreq_ies_len; i++) {
1112 esupp_rates[1]++; 670 len += sprintf(buf + len, "%02x",
1113 } else if (supp_rates[1] == 8) { 671 ifsta->assocreq_ies[i]);
1114 esupp_rates = skb_put(skb, 3); 672 }
1115 esupp_rates[0] = WLAN_EID_EXT_SUPP_RATES; 673 }
1116 esupp_rates[1] = 1; 674 if (ifsta->assocresp_ies) {
1117 pos = &esupp_rates[2]; 675 if (ifsta->assocreq_ies)
1118 } else { 676 len += sprintf(buf + len, " ");
1119 pos = skb_put(skb, 1); 677 len += sprintf(buf + len, "RespIEs=");
1120 supp_rates[1]++; 678 for (i = 0; i < ifsta->assocresp_ies_len; i++) {
679 len += sprintf(buf + len, "%02x",
680 ifsta->assocresp_ies[i]);
1121 } 681 }
1122 *pos = rate->bitrate / 5;
1123 } 682 }
683 len += sprintf(buf + len, ")");
1124 684
1125 ieee80211_sta_tx(dev, skb, 0); 685 if (len > IW_CUSTOM_MAX) {
1126} 686 len = sprintf(buf, "ASSOCRESPIE=");
687 for (i = 0; i < ifsta->assocresp_ies_len; i++) {
688 len += sprintf(buf + len, "%02x",
689 ifsta->assocresp_ies[i]);
690 }
691 }
1127 692
693 if (len <= IW_CUSTOM_MAX) {
694 memset(&wrqu, 0, sizeof(wrqu));
695 wrqu.data.length = len;
696 wireless_send_event(sdata->dev, IWEVCUSTOM, &wrqu, buf);
697 }
1128 698
1129static int ieee80211_sta_wep_configured(struct net_device *dev) 699 kfree(buf);
1130{
1131 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1132 if (!sdata || !sdata->default_key ||
1133 sdata->default_key->conf.alg != ALG_WEP)
1134 return 0;
1135 return 1;
1136} 700}
1137 701
1138 702
1139static void ieee80211_auth_completed(struct net_device *dev, 703static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
1140 struct ieee80211_if_sta *ifsta) 704 struct ieee80211_if_sta *ifsta)
1141{ 705{
1142 printk(KERN_DEBUG "%s: authenticated\n", dev->name); 706 struct ieee80211_local *local = sdata->local;
1143 ifsta->flags |= IEEE80211_STA_AUTHENTICATED; 707 struct ieee80211_conf *conf = &local_to_hw(local)->conf;
1144 ieee80211_associate(dev, ifsta); 708 u32 changed = BSS_CHANGED_ASSOC;
1145}
1146 709
710 struct ieee80211_bss *bss;
1147 711
1148static void ieee80211_auth_challenge(struct net_device *dev, 712 ifsta->flags |= IEEE80211_STA_ASSOCIATED;
1149 struct ieee80211_if_sta *ifsta,
1150 struct ieee80211_mgmt *mgmt,
1151 size_t len)
1152{
1153 u8 *pos;
1154 struct ieee802_11_elems elems;
1155 713
1156 pos = mgmt->u.auth.variable; 714 if (sdata->vif.type != NL80211_IFTYPE_STATION)
1157 ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
1158 if (!elems.challenge)
1159 return; 715 return;
1160 ieee80211_send_auth(dev, ifsta, 3, elems.challenge - 2,
1161 elems.challenge_len + 2, 1);
1162}
1163 716
1164static void ieee80211_send_addba_resp(struct net_device *dev, u8 *da, u16 tid, 717 bss = ieee80211_rx_bss_get(local, ifsta->bssid,
1165 u8 dialog_token, u16 status, u16 policy, 718 conf->channel->center_freq,
1166 u16 buf_size, u16 timeout) 719 ifsta->ssid, ifsta->ssid_len);
1167{ 720 if (bss) {
1168 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 721 /* set timing information */
1169 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 722 sdata->bss_conf.beacon_int = bss->beacon_int;
1170 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 723 sdata->bss_conf.timestamp = bss->timestamp;
1171 struct sk_buff *skb; 724 sdata->bss_conf.dtim_period = bss->dtim_period;
1172 struct ieee80211_mgmt *mgmt;
1173 u16 capab;
1174 725
1175 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom); 726 changed |= ieee80211_handle_bss_capability(sdata, bss);
1176 727
1177 if (!skb) { 728 ieee80211_rx_bss_put(local, bss);
1178 printk(KERN_DEBUG "%s: failed to allocate buffer "
1179 "for addba resp frame\n", dev->name);
1180 return;
1181 } 729 }
1182 730
1183 skb_reserve(skb, local->hw.extra_tx_headroom); 731 if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) {
1184 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); 732 changed |= BSS_CHANGED_HT;
1185 memset(mgmt, 0, 24); 733 sdata->bss_conf.assoc_ht = 1;
1186 memcpy(mgmt->da, da, ETH_ALEN); 734 sdata->bss_conf.ht_conf = &conf->ht_conf;
1187 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); 735 sdata->bss_conf.ht_bss_conf = &conf->ht_bss_conf;
1188 if (sdata->vif.type == IEEE80211_IF_TYPE_AP) 736 }
1189 memcpy(mgmt->bssid, dev->dev_addr, ETH_ALEN);
1190 else
1191 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
1192 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
1193 IEEE80211_STYPE_ACTION);
1194 737
1195 skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_resp)); 738 ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET;
1196 mgmt->u.action.category = WLAN_CATEGORY_BACK; 739 memcpy(ifsta->prev_bssid, sdata->u.sta.bssid, ETH_ALEN);
1197 mgmt->u.action.u.addba_resp.action_code = WLAN_ACTION_ADDBA_RESP; 740 ieee80211_sta_send_associnfo(sdata, ifsta);
1198 mgmt->u.action.u.addba_resp.dialog_token = dialog_token;
1199 741
1200 capab = (u16)(policy << 1); /* bit 1 aggregation policy */ 742 ifsta->last_probe = jiffies;
1201 capab |= (u16)(tid << 2); /* bit 5:2 TID number */ 743 ieee80211_led_assoc(local, 1);
1202 capab |= (u16)(buf_size << 6); /* bit 15:6 max size of aggregation */
1203 744
1204 mgmt->u.action.u.addba_resp.capab = cpu_to_le16(capab); 745 sdata->bss_conf.assoc = 1;
1205 mgmt->u.action.u.addba_resp.timeout = cpu_to_le16(timeout); 746 /*
1206 mgmt->u.action.u.addba_resp.status = cpu_to_le16(status); 747 * For now just always ask the driver to update the basic rateset
748 * when we have associated, we aren't checking whether it actually
749 * changed or not.
750 */
751 changed |= BSS_CHANGED_BASIC_RATES;
752 ieee80211_bss_info_change_notify(sdata, changed);
1207 753
1208 ieee80211_sta_tx(dev, skb, 0); 754 netif_tx_start_all_queues(sdata->dev);
755 netif_carrier_on(sdata->dev);
1209 756
1210 return; 757 ieee80211_sta_send_apinfo(sdata, ifsta);
1211} 758}
1212 759
1213void ieee80211_send_addba_request(struct net_device *dev, const u8 *da, 760static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata,
1214 u16 tid, u8 dialog_token, u16 start_seq_num, 761 struct ieee80211_if_sta *ifsta)
1215 u16 agg_size, u16 timeout)
1216{ 762{
1217 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 763 DECLARE_MAC_BUF(mac);
1218 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1219 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
1220 struct sk_buff *skb;
1221 struct ieee80211_mgmt *mgmt;
1222 u16 capab;
1223
1224 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
1225 764
1226 if (!skb) { 765 ifsta->direct_probe_tries++;
1227 printk(KERN_ERR "%s: failed to allocate buffer " 766 if (ifsta->direct_probe_tries > IEEE80211_AUTH_MAX_TRIES) {
1228 "for addba request frame\n", dev->name); 767 printk(KERN_DEBUG "%s: direct probe to AP %s timed out\n",
768 sdata->dev->name, print_mac(mac, ifsta->bssid));
769 ifsta->state = IEEE80211_STA_MLME_DISABLED;
1229 return; 770 return;
1230 } 771 }
1231 skb_reserve(skb, local->hw.extra_tx_headroom);
1232 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
1233 memset(mgmt, 0, 24);
1234 memcpy(mgmt->da, da, ETH_ALEN);
1235 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN);
1236 if (sdata->vif.type == IEEE80211_IF_TYPE_AP)
1237 memcpy(mgmt->bssid, dev->dev_addr, ETH_ALEN);
1238 else
1239 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
1240 772
1241 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, 773 printk(KERN_DEBUG "%s: direct probe to AP %s try %d\n",
1242 IEEE80211_STYPE_ACTION); 774 sdata->dev->name, print_mac(mac, ifsta->bssid),
775 ifsta->direct_probe_tries);
1243 776
1244 skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_req)); 777 ifsta->state = IEEE80211_STA_MLME_DIRECT_PROBE;
1245 778
1246 mgmt->u.action.category = WLAN_CATEGORY_BACK; 779 set_bit(IEEE80211_STA_REQ_DIRECT_PROBE, &ifsta->request);
1247 mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ;
1248 780
1249 mgmt->u.action.u.addba_req.dialog_token = dialog_token; 781 /* Direct probe is sent to broadcast address as some APs
1250 capab = (u16)(1 << 1); /* bit 1 aggregation policy */ 782 * will not answer to direct packet in unassociated state.
1251 capab |= (u16)(tid << 2); /* bit 5:2 TID number */ 783 */
1252 capab |= (u16)(agg_size << 6); /* bit 15:6 max size of aggergation */ 784 ieee80211_send_probe_req(sdata, NULL,
1253 785 ifsta->ssid, ifsta->ssid_len);
1254 mgmt->u.action.u.addba_req.capab = cpu_to_le16(capab);
1255
1256 mgmt->u.action.u.addba_req.timeout = cpu_to_le16(timeout);
1257 mgmt->u.action.u.addba_req.start_seq_num =
1258 cpu_to_le16(start_seq_num << 4);
1259 786
1260 ieee80211_sta_tx(dev, skb, 0); 787 mod_timer(&ifsta->timer, jiffies + IEEE80211_AUTH_TIMEOUT);
1261} 788}
1262 789
1263static void ieee80211_sta_process_addba_request(struct net_device *dev, 790
1264 struct ieee80211_mgmt *mgmt, 791static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata,
1265 size_t len) 792 struct ieee80211_if_sta *ifsta)
1266{ 793{
1267 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1268 struct ieee80211_hw *hw = &local->hw;
1269 struct ieee80211_conf *conf = &hw->conf;
1270 struct sta_info *sta;
1271 struct tid_ampdu_rx *tid_agg_rx;
1272 u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status;
1273 u8 dialog_token;
1274 int ret = -EOPNOTSUPP;
1275 DECLARE_MAC_BUF(mac); 794 DECLARE_MAC_BUF(mac);
1276 795
1277 rcu_read_lock(); 796 ifsta->auth_tries++;
1278 797 if (ifsta->auth_tries > IEEE80211_AUTH_MAX_TRIES) {
1279 sta = sta_info_get(local, mgmt->sa); 798 printk(KERN_DEBUG "%s: authentication with AP %s"
1280 if (!sta) { 799 " timed out\n",
1281 rcu_read_unlock(); 800 sdata->dev->name, print_mac(mac, ifsta->bssid));
801 ifsta->state = IEEE80211_STA_MLME_DISABLED;
1282 return; 802 return;
1283 } 803 }
1284 804
1285 /* extract session parameters from addba request frame */ 805 ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE;
1286 dialog_token = mgmt->u.action.u.addba_req.dialog_token; 806 printk(KERN_DEBUG "%s: authenticate with AP %s\n",
1287 timeout = le16_to_cpu(mgmt->u.action.u.addba_req.timeout); 807 sdata->dev->name, print_mac(mac, ifsta->bssid));
1288 start_seq_num =
1289 le16_to_cpu(mgmt->u.action.u.addba_req.start_seq_num) >> 4;
1290
1291 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
1292 ba_policy = (capab & IEEE80211_ADDBA_PARAM_POLICY_MASK) >> 1;
1293 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
1294 buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6;
1295
1296 status = WLAN_STATUS_REQUEST_DECLINED;
1297
1298 /* sanity check for incoming parameters:
1299 * check if configuration can support the BA policy
1300 * and if buffer size does not exceeds max value */
1301 if (((ba_policy != 1)
1302 && (!(conf->ht_conf.cap & IEEE80211_HT_CAP_DELAY_BA)))
1303 || (buf_size > IEEE80211_MAX_AMPDU_BUF)) {
1304 status = WLAN_STATUS_INVALID_QOS_PARAM;
1305#ifdef CONFIG_MAC80211_HT_DEBUG
1306 if (net_ratelimit())
1307 printk(KERN_DEBUG "AddBA Req with bad params from "
1308 "%s on tid %u. policy %d, buffer size %d\n",
1309 print_mac(mac, mgmt->sa), tid, ba_policy,
1310 buf_size);
1311#endif /* CONFIG_MAC80211_HT_DEBUG */
1312 goto end_no_lock;
1313 }
1314 /* determine default buffer size */
1315 if (buf_size == 0) {
1316 struct ieee80211_supported_band *sband;
1317
1318 sband = local->hw.wiphy->bands[conf->channel->band];
1319 buf_size = IEEE80211_MIN_AMPDU_BUF;
1320 buf_size = buf_size << sband->ht_info.ampdu_factor;
1321 }
1322
1323
1324 /* examine state machine */
1325 spin_lock_bh(&sta->lock);
1326
1327 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) {
1328#ifdef CONFIG_MAC80211_HT_DEBUG
1329 if (net_ratelimit())
1330 printk(KERN_DEBUG "unexpected AddBA Req from "
1331 "%s on tid %u\n",
1332 print_mac(mac, mgmt->sa), tid);
1333#endif /* CONFIG_MAC80211_HT_DEBUG */
1334 goto end;
1335 }
1336 808
1337 /* prepare A-MPDU MLME for Rx aggregation */ 809 ieee80211_send_auth(sdata, ifsta, 1, NULL, 0, 0);
1338 sta->ampdu_mlme.tid_rx[tid] =
1339 kmalloc(sizeof(struct tid_ampdu_rx), GFP_ATOMIC);
1340 if (!sta->ampdu_mlme.tid_rx[tid]) {
1341#ifdef CONFIG_MAC80211_HT_DEBUG
1342 if (net_ratelimit())
1343 printk(KERN_ERR "allocate rx mlme to tid %d failed\n",
1344 tid);
1345#endif
1346 goto end;
1347 }
1348 /* rx timer */
1349 sta->ampdu_mlme.tid_rx[tid]->session_timer.function =
1350 sta_rx_agg_session_timer_expired;
1351 sta->ampdu_mlme.tid_rx[tid]->session_timer.data =
1352 (unsigned long)&sta->timer_to_tid[tid];
1353 init_timer(&sta->ampdu_mlme.tid_rx[tid]->session_timer);
1354
1355 tid_agg_rx = sta->ampdu_mlme.tid_rx[tid];
1356
1357 /* prepare reordering buffer */
1358 tid_agg_rx->reorder_buf =
1359 kmalloc(buf_size * sizeof(struct sk_buff *), GFP_ATOMIC);
1360 if (!tid_agg_rx->reorder_buf) {
1361#ifdef CONFIG_MAC80211_HT_DEBUG
1362 if (net_ratelimit())
1363 printk(KERN_ERR "can not allocate reordering buffer "
1364 "to tid %d\n", tid);
1365#endif
1366 kfree(sta->ampdu_mlme.tid_rx[tid]);
1367 goto end;
1368 }
1369 memset(tid_agg_rx->reorder_buf, 0,
1370 buf_size * sizeof(struct sk_buff *));
1371
1372 if (local->ops->ampdu_action)
1373 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_START,
1374 sta->addr, tid, &start_seq_num);
1375#ifdef CONFIG_MAC80211_HT_DEBUG
1376 printk(KERN_DEBUG "Rx A-MPDU request on tid %d result %d\n", tid, ret);
1377#endif /* CONFIG_MAC80211_HT_DEBUG */
1378
1379 if (ret) {
1380 kfree(tid_agg_rx->reorder_buf);
1381 kfree(tid_agg_rx);
1382 sta->ampdu_mlme.tid_rx[tid] = NULL;
1383 goto end;
1384 }
1385 810
1386 /* change state and send addba resp */ 811 mod_timer(&ifsta->timer, jiffies + IEEE80211_AUTH_TIMEOUT);
1387 sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_OPERATIONAL;
1388 tid_agg_rx->dialog_token = dialog_token;
1389 tid_agg_rx->ssn = start_seq_num;
1390 tid_agg_rx->head_seq_num = start_seq_num;
1391 tid_agg_rx->buf_size = buf_size;
1392 tid_agg_rx->timeout = timeout;
1393 tid_agg_rx->stored_mpdu_num = 0;
1394 status = WLAN_STATUS_SUCCESS;
1395end:
1396 spin_unlock_bh(&sta->lock);
1397
1398end_no_lock:
1399 ieee80211_send_addba_resp(sta->sdata->dev, sta->addr, tid,
1400 dialog_token, status, 1, buf_size, timeout);
1401 rcu_read_unlock();
1402} 812}
1403 813
1404static void ieee80211_sta_process_addba_resp(struct net_device *dev, 814static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1405 struct ieee80211_mgmt *mgmt, 815 struct ieee80211_if_sta *ifsta, bool deauth,
1406 size_t len) 816 bool self_disconnected, u16 reason)
1407{ 817{
1408 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 818 struct ieee80211_local *local = sdata->local;
1409 struct ieee80211_hw *hw = &local->hw;
1410 struct sta_info *sta; 819 struct sta_info *sta;
1411 u16 capab; 820 u32 changed = BSS_CHANGED_ASSOC;
1412 u16 tid;
1413 u8 *state;
1414 821
1415 rcu_read_lock(); 822 rcu_read_lock();
1416 823
1417 sta = sta_info_get(local, mgmt->sa); 824 sta = sta_info_get(local, ifsta->bssid);
1418 if (!sta) { 825 if (!sta) {
1419 rcu_read_unlock(); 826 rcu_read_unlock();
1420 return; 827 return;
1421 } 828 }
1422 829
1423 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab); 830 if (deauth) {
1424 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2; 831 ifsta->direct_probe_tries = 0;
832 ifsta->auth_tries = 0;
833 }
834 ifsta->assoc_scan_tries = 0;
835 ifsta->assoc_tries = 0;
1425 836
1426 state = &sta->ampdu_mlme.tid_state_tx[tid]; 837 netif_tx_stop_all_queues(sdata->dev);
838 netif_carrier_off(sdata->dev);
1427 839
1428 spin_lock_bh(&sta->lock); 840 ieee80211_sta_tear_down_BA_sessions(sdata, sta->sta.addr);
1429 841
1430 if (!(*state & HT_ADDBA_REQUESTED_MSK)) { 842 if (self_disconnected) {
1431 spin_unlock_bh(&sta->lock); 843 if (deauth)
1432 goto addba_resp_exit; 844 ieee80211_send_deauth_disassoc(sdata,
845 IEEE80211_STYPE_DEAUTH, reason);
846 else
847 ieee80211_send_deauth_disassoc(sdata,
848 IEEE80211_STYPE_DISASSOC, reason);
1433 } 849 }
1434 850
1435 if (mgmt->u.action.u.addba_resp.dialog_token != 851 ifsta->flags &= ~IEEE80211_STA_ASSOCIATED;
1436 sta->ampdu_mlme.tid_tx[tid]->dialog_token) { 852 changed |= ieee80211_reset_erp_info(sdata);
1437 spin_unlock_bh(&sta->lock);
1438#ifdef CONFIG_MAC80211_HT_DEBUG
1439 printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
1440#endif /* CONFIG_MAC80211_HT_DEBUG */
1441 goto addba_resp_exit;
1442 }
1443 853
1444 del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); 854 if (sdata->bss_conf.assoc_ht)
1445#ifdef CONFIG_MAC80211_HT_DEBUG 855 changed |= BSS_CHANGED_HT;
1446 printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid);
1447#endif /* CONFIG_MAC80211_HT_DEBUG */
1448 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
1449 == WLAN_STATUS_SUCCESS) {
1450 *state |= HT_ADDBA_RECEIVED_MSK;
1451 sta->ampdu_mlme.addba_req_num[tid] = 0;
1452 856
1453 if (*state == HT_AGG_STATE_OPERATIONAL) 857 sdata->bss_conf.assoc_ht = 0;
1454 ieee80211_wake_queue(hw, sta->tid_to_tx_q[tid]); 858 sdata->bss_conf.ht_conf = NULL;
859 sdata->bss_conf.ht_bss_conf = NULL;
1455 860
1456 spin_unlock_bh(&sta->lock); 861 ieee80211_led_assoc(local, 0);
1457 } else { 862 sdata->bss_conf.assoc = 0;
1458 sta->ampdu_mlme.addba_req_num[tid]++; 863
1459 /* this will allow the state check in stop_BA_session */ 864 ieee80211_sta_send_apinfo(sdata, ifsta);
1460 *state = HT_AGG_STATE_OPERATIONAL; 865
1461 spin_unlock_bh(&sta->lock); 866 if (self_disconnected)
1462 ieee80211_stop_tx_ba_session(hw, sta->addr, tid, 867 ifsta->state = IEEE80211_STA_MLME_DISABLED;
1463 WLAN_BACK_INITIATOR); 868
1464 } 869 sta_info_unlink(&sta);
1465 870
1466addba_resp_exit:
1467 rcu_read_unlock(); 871 rcu_read_unlock();
872
873 sta_info_destroy(sta);
1468} 874}
1469 875
1470void ieee80211_send_delba(struct net_device *dev, const u8 *da, u16 tid, 876static int ieee80211_sta_wep_configured(struct ieee80211_sub_if_data *sdata)
1471 u16 initiator, u16 reason_code)
1472{ 877{
1473 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 878 if (!sdata || !sdata->default_key ||
1474 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 879 sdata->default_key->conf.alg != ALG_WEP)
1475 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 880 return 0;
1476 struct sk_buff *skb; 881 return 1;
1477 struct ieee80211_mgmt *mgmt; 882}
1478 u16 params;
1479
1480 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
1481
1482 if (!skb) {
1483 printk(KERN_ERR "%s: failed to allocate buffer "
1484 "for delba frame\n", dev->name);
1485 return;
1486 }
1487 883
1488 skb_reserve(skb, local->hw.extra_tx_headroom); 884static int ieee80211_privacy_mismatch(struct ieee80211_sub_if_data *sdata,
1489 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); 885 struct ieee80211_if_sta *ifsta)
1490 memset(mgmt, 0, 24); 886{
1491 memcpy(mgmt->da, da, ETH_ALEN); 887 struct ieee80211_local *local = sdata->local;
1492 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); 888 struct ieee80211_bss *bss;
1493 if (sdata->vif.type == IEEE80211_IF_TYPE_AP) 889 int bss_privacy;
1494 memcpy(mgmt->bssid, dev->dev_addr, ETH_ALEN); 890 int wep_privacy;
1495 else 891 int privacy_invoked;
1496 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
1497 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
1498 IEEE80211_STYPE_ACTION);
1499 892
1500 skb_put(skb, 1 + sizeof(mgmt->u.action.u.delba)); 893 if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL))
894 return 0;
1501 895
1502 mgmt->u.action.category = WLAN_CATEGORY_BACK; 896 bss = ieee80211_rx_bss_get(local, ifsta->bssid,
1503 mgmt->u.action.u.delba.action_code = WLAN_ACTION_DELBA; 897 local->hw.conf.channel->center_freq,
1504 params = (u16)(initiator << 11); /* bit 11 initiator */ 898 ifsta->ssid, ifsta->ssid_len);
1505 params |= (u16)(tid << 12); /* bit 15:12 TID number */ 899 if (!bss)
900 return 0;
1506 901
1507 mgmt->u.action.u.delba.params = cpu_to_le16(params); 902 bss_privacy = !!(bss->capability & WLAN_CAPABILITY_PRIVACY);
1508 mgmt->u.action.u.delba.reason_code = cpu_to_le16(reason_code); 903 wep_privacy = !!ieee80211_sta_wep_configured(sdata);
904 privacy_invoked = !!(ifsta->flags & IEEE80211_STA_PRIVACY_INVOKED);
1509 905
1510 ieee80211_sta_tx(dev, skb, 0); 906 ieee80211_rx_bss_put(local, bss);
1511}
1512 907
1513void ieee80211_send_bar(struct net_device *dev, u8 *ra, u16 tid, u16 ssn) 908 if ((bss_privacy == wep_privacy) || (bss_privacy == privacy_invoked))
1514{ 909 return 0;
1515 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1516 struct sk_buff *skb;
1517 struct ieee80211_bar *bar;
1518 u16 bar_control = 0;
1519 910
1520 skb = dev_alloc_skb(sizeof(*bar) + local->hw.extra_tx_headroom); 911 return 1;
1521 if (!skb) {
1522 printk(KERN_ERR "%s: failed to allocate buffer for "
1523 "bar frame\n", dev->name);
1524 return;
1525 }
1526 skb_reserve(skb, local->hw.extra_tx_headroom);
1527 bar = (struct ieee80211_bar *)skb_put(skb, sizeof(*bar));
1528 memset(bar, 0, sizeof(*bar));
1529 bar->frame_control = IEEE80211_FC(IEEE80211_FTYPE_CTL,
1530 IEEE80211_STYPE_BACK_REQ);
1531 memcpy(bar->ra, ra, ETH_ALEN);
1532 memcpy(bar->ta, dev->dev_addr, ETH_ALEN);
1533 bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL;
1534 bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA;
1535 bar_control |= (u16)(tid << 12);
1536 bar->control = cpu_to_le16(bar_control);
1537 bar->start_seq_num = cpu_to_le16(ssn);
1538
1539 ieee80211_sta_tx(dev, skb, 0);
1540} 912}
1541 913
1542void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *ra, u16 tid, 914static void ieee80211_associate(struct ieee80211_sub_if_data *sdata,
1543 u16 initiator, u16 reason) 915 struct ieee80211_if_sta *ifsta)
1544{ 916{
1545 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1546 struct ieee80211_hw *hw = &local->hw;
1547 struct sta_info *sta;
1548 int ret, i;
1549 DECLARE_MAC_BUF(mac); 917 DECLARE_MAC_BUF(mac);
1550 918
1551 rcu_read_lock(); 919 ifsta->assoc_tries++;
1552 920 if (ifsta->assoc_tries > IEEE80211_ASSOC_MAX_TRIES) {
1553 sta = sta_info_get(local, ra); 921 printk(KERN_DEBUG "%s: association with AP %s"
1554 if (!sta) { 922 " timed out\n",
1555 rcu_read_unlock(); 923 sdata->dev->name, print_mac(mac, ifsta->bssid));
924 ifsta->state = IEEE80211_STA_MLME_DISABLED;
1556 return; 925 return;
1557 } 926 }
1558 927
1559 /* check if TID is in operational state */ 928 ifsta->state = IEEE80211_STA_MLME_ASSOCIATE;
1560 spin_lock_bh(&sta->lock); 929 printk(KERN_DEBUG "%s: associate with AP %s\n",
1561 if (sta->ampdu_mlme.tid_state_rx[tid] 930 sdata->dev->name, print_mac(mac, ifsta->bssid));
1562 != HT_AGG_STATE_OPERATIONAL) { 931 if (ieee80211_privacy_mismatch(sdata, ifsta)) {
1563 spin_unlock_bh(&sta->lock); 932 printk(KERN_DEBUG "%s: mismatch in privacy configuration and "
1564 rcu_read_unlock(); 933 "mixed-cell disabled - abort association\n", sdata->dev->name);
934 ifsta->state = IEEE80211_STA_MLME_DISABLED;
1565 return; 935 return;
1566 } 936 }
1567 sta->ampdu_mlme.tid_state_rx[tid] =
1568 HT_AGG_STATE_REQ_STOP_BA_MSK |
1569 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
1570 spin_unlock_bh(&sta->lock);
1571
1572 /* stop HW Rx aggregation. ampdu_action existence
1573 * already verified in session init so we add the BUG_ON */
1574 BUG_ON(!local->ops->ampdu_action);
1575
1576#ifdef CONFIG_MAC80211_HT_DEBUG
1577 printk(KERN_DEBUG "Rx BA session stop requested for %s tid %u\n",
1578 print_mac(mac, ra), tid);
1579#endif /* CONFIG_MAC80211_HT_DEBUG */
1580
1581 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_STOP,
1582 ra, tid, NULL);
1583 if (ret)
1584 printk(KERN_DEBUG "HW problem - can not stop rx "
1585 "aggregation for tid %d\n", tid);
1586
1587 /* shutdown timer has not expired */
1588 if (initiator != WLAN_BACK_TIMER)
1589 del_timer_sync(&sta->ampdu_mlme.tid_rx[tid]->session_timer);
1590
1591 /* check if this is a self generated aggregation halt */
1592 if (initiator == WLAN_BACK_RECIPIENT || initiator == WLAN_BACK_TIMER)
1593 ieee80211_send_delba(dev, ra, tid, 0, reason);
1594
1595 /* free the reordering buffer */
1596 for (i = 0; i < sta->ampdu_mlme.tid_rx[tid]->buf_size; i++) {
1597 if (sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]) {
1598 /* release the reordered frames */
1599 dev_kfree_skb(sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]);
1600 sta->ampdu_mlme.tid_rx[tid]->stored_mpdu_num--;
1601 sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i] = NULL;
1602 }
1603 }
1604 /* free resources */
1605 kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_buf);
1606 kfree(sta->ampdu_mlme.tid_rx[tid]);
1607 sta->ampdu_mlme.tid_rx[tid] = NULL;
1608 sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_IDLE;
1609 937
1610 rcu_read_unlock(); 938 ieee80211_send_assoc(sdata, ifsta);
939
940 mod_timer(&ifsta->timer, jiffies + IEEE80211_ASSOC_TIMEOUT);
1611} 941}
1612 942
1613 943
1614static void ieee80211_sta_process_delba(struct net_device *dev, 944static void ieee80211_associated(struct ieee80211_sub_if_data *sdata,
1615 struct ieee80211_mgmt *mgmt, size_t len) 945 struct ieee80211_if_sta *ifsta)
1616{ 946{
1617 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 947 struct ieee80211_local *local = sdata->local;
1618 struct sta_info *sta; 948 struct sta_info *sta;
1619 u16 tid, params; 949 int disassoc;
1620 u16 initiator;
1621 DECLARE_MAC_BUF(mac); 950 DECLARE_MAC_BUF(mac);
1622 951
1623 rcu_read_lock(); 952 /* TODO: start monitoring current AP signal quality and number of
1624 953 * missed beacons. Scan other channels every now and then and search
1625 sta = sta_info_get(local, mgmt->sa); 954 * for better APs. */
1626 if (!sta) { 955 /* TODO: remove expired BSSes */
1627 rcu_read_unlock();
1628 return;
1629 }
1630 956
1631 params = le16_to_cpu(mgmt->u.action.u.delba.params); 957 ifsta->state = IEEE80211_STA_MLME_ASSOCIATED;
1632 tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12;
1633 initiator = (params & IEEE80211_DELBA_PARAM_INITIATOR_MASK) >> 11;
1634
1635#ifdef CONFIG_MAC80211_HT_DEBUG
1636 if (net_ratelimit())
1637 printk(KERN_DEBUG "delba from %s (%s) tid %d reason code %d\n",
1638 print_mac(mac, mgmt->sa),
1639 initiator ? "initiator" : "recipient", tid,
1640 mgmt->u.action.u.delba.reason_code);
1641#endif /* CONFIG_MAC80211_HT_DEBUG */
1642
1643 if (initiator == WLAN_BACK_INITIATOR)
1644 ieee80211_sta_stop_rx_ba_session(dev, sta->addr, tid,
1645 WLAN_BACK_INITIATOR, 0);
1646 else { /* WLAN_BACK_RECIPIENT */
1647 spin_lock_bh(&sta->lock);
1648 sta->ampdu_mlme.tid_state_tx[tid] =
1649 HT_AGG_STATE_OPERATIONAL;
1650 spin_unlock_bh(&sta->lock);
1651 ieee80211_stop_tx_ba_session(&local->hw, sta->addr, tid,
1652 WLAN_BACK_RECIPIENT);
1653 }
1654 rcu_read_unlock();
1655}
1656
1657/*
1658 * After sending add Block Ack request we activated a timer until
1659 * add Block Ack response will arrive from the recipient.
1660 * If this timer expires sta_addba_resp_timer_expired will be executed.
1661 */
1662void sta_addba_resp_timer_expired(unsigned long data)
1663{
1664 /* not an elegant detour, but there is no choice as the timer passes
1665 * only one argument, and both sta_info and TID are needed, so init
1666 * flow in sta_info_create gives the TID as data, while the timer_to_id
1667 * array gives the sta through container_of */
1668 u16 tid = *(u8 *)data;
1669 struct sta_info *temp_sta = container_of((void *)data,
1670 struct sta_info, timer_to_tid[tid]);
1671
1672 struct ieee80211_local *local = temp_sta->local;
1673 struct ieee80211_hw *hw = &local->hw;
1674 struct sta_info *sta;
1675 u8 *state;
1676 958
1677 rcu_read_lock(); 959 rcu_read_lock();
1678 960
1679 sta = sta_info_get(local, temp_sta->addr); 961 sta = sta_info_get(local, ifsta->bssid);
1680 if (!sta) { 962 if (!sta) {
1681 rcu_read_unlock(); 963 printk(KERN_DEBUG "%s: No STA entry for own AP %s\n",
1682 return; 964 sdata->dev->name, print_mac(mac, ifsta->bssid));
1683 } 965 disassoc = 1;
1684 966 } else {
1685 state = &sta->ampdu_mlme.tid_state_tx[tid]; 967 disassoc = 0;
1686 /* check if the TID waits for addBA response */ 968 if (time_after(jiffies,
1687 spin_lock_bh(&sta->lock); 969 sta->last_rx + IEEE80211_MONITORING_INTERVAL)) {
1688 if (!(*state & HT_ADDBA_REQUESTED_MSK)) { 970 if (ifsta->flags & IEEE80211_STA_PROBEREQ_POLL) {
1689 spin_unlock_bh(&sta->lock); 971 printk(KERN_DEBUG "%s: No ProbeResp from "
1690 *state = HT_AGG_STATE_IDLE; 972 "current AP %s - assume out of "
1691#ifdef CONFIG_MAC80211_HT_DEBUG 973 "range\n",
1692 printk(KERN_DEBUG "timer expired on tid %d but we are not " 974 sdata->dev->name, print_mac(mac, ifsta->bssid));
1693 "expecting addBA response there", tid); 975 disassoc = 1;
1694#endif 976 } else
1695 goto timer_expired_exit; 977 ieee80211_send_probe_req(sdata, ifsta->bssid,
978 ifsta->ssid,
979 ifsta->ssid_len);
980 ifsta->flags ^= IEEE80211_STA_PROBEREQ_POLL;
981 } else {
982 ifsta->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
983 if (time_after(jiffies, ifsta->last_probe +
984 IEEE80211_PROBE_INTERVAL)) {
985 ifsta->last_probe = jiffies;
986 ieee80211_send_probe_req(sdata, ifsta->bssid,
987 ifsta->ssid,
988 ifsta->ssid_len);
989 }
990 }
1696 } 991 }
1697 992
1698#ifdef CONFIG_MAC80211_HT_DEBUG
1699 printk(KERN_DEBUG "addBA response timer expired on tid %d\n", tid);
1700#endif
1701
1702 /* go through the state check in stop_BA_session */
1703 *state = HT_AGG_STATE_OPERATIONAL;
1704 spin_unlock_bh(&sta->lock);
1705 ieee80211_stop_tx_ba_session(hw, temp_sta->addr, tid,
1706 WLAN_BACK_INITIATOR);
1707
1708timer_expired_exit:
1709 rcu_read_unlock(); 993 rcu_read_unlock();
1710}
1711 994
1712/* 995 if (disassoc)
1713 * After accepting the AddBA Request we activated a timer, 996 ieee80211_set_disassoc(sdata, ifsta, true, true,
1714 * resetting it after each frame that arrives from the originator. 997 WLAN_REASON_PREV_AUTH_NOT_VALID);
1715 * if this timer expires ieee80211_sta_stop_rx_ba_session will be executed. 998 else
1716 */ 999 mod_timer(&ifsta->timer, jiffies +
1717static void sta_rx_agg_session_timer_expired(unsigned long data) 1000 IEEE80211_MONITORING_INTERVAL);
1718{
1719 /* not an elegant detour, but there is no choice as the timer passes
1720 * only one argument, and various sta_info are needed here, so init
1721 * flow in sta_info_create gives the TID as data, while the timer_to_id
1722 * array gives the sta through container_of */
1723 u8 *ptid = (u8 *)data;
1724 u8 *timer_to_id = ptid - *ptid;
1725 struct sta_info *sta = container_of(timer_to_id, struct sta_info,
1726 timer_to_tid[0]);
1727
1728#ifdef CONFIG_MAC80211_HT_DEBUG
1729 printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid);
1730#endif
1731 ieee80211_sta_stop_rx_ba_session(sta->sdata->dev, sta->addr,
1732 (u16)*ptid, WLAN_BACK_TIMER,
1733 WLAN_REASON_QSTA_TIMEOUT);
1734} 1001}
1735 1002
1736void ieee80211_sta_tear_down_BA_sessions(struct net_device *dev, u8 *addr)
1737{
1738 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1739 int i;
1740 1003
1741 for (i = 0; i < STA_TID_NUM; i++) { 1004static void ieee80211_auth_completed(struct ieee80211_sub_if_data *sdata,
1742 ieee80211_stop_tx_ba_session(&local->hw, addr, i, 1005 struct ieee80211_if_sta *ifsta)
1743 WLAN_BACK_INITIATOR); 1006{
1744 ieee80211_sta_stop_rx_ba_session(dev, addr, i, 1007 printk(KERN_DEBUG "%s: authenticated\n", sdata->dev->name);
1745 WLAN_BACK_RECIPIENT, 1008 ifsta->flags |= IEEE80211_STA_AUTHENTICATED;
1746 WLAN_REASON_QSTA_LEAVE_QBSS); 1009 ieee80211_associate(sdata, ifsta);
1747 }
1748} 1010}
1749 1011
1750static void ieee80211_send_refuse_measurement_request(struct net_device *dev,
1751 struct ieee80211_msrment_ie *request_ie,
1752 const u8 *da, const u8 *bssid,
1753 u8 dialog_token)
1754{
1755 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1756 struct sk_buff *skb;
1757 struct ieee80211_mgmt *msr_report;
1758 1012
1759 skb = dev_alloc_skb(sizeof(*msr_report) + local->hw.extra_tx_headroom + 1013static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
1760 sizeof(struct ieee80211_msrment_ie)); 1014 struct ieee80211_if_sta *ifsta,
1015 struct ieee80211_mgmt *mgmt,
1016 size_t len)
1017{
1018 u8 *pos;
1019 struct ieee802_11_elems elems;
1761 1020
1762 if (!skb) { 1021 pos = mgmt->u.auth.variable;
1763 printk(KERN_ERR "%s: failed to allocate buffer for " 1022 ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
1764 "measurement report frame\n", dev->name); 1023 if (!elems.challenge)
1765 return; 1024 return;
1766 } 1025 ieee80211_send_auth(sdata, ifsta, 3, elems.challenge - 2,
1767 1026 elems.challenge_len + 2, 1);
1768 skb_reserve(skb, local->hw.extra_tx_headroom);
1769 msr_report = (struct ieee80211_mgmt *)skb_put(skb, 24);
1770 memset(msr_report, 0, 24);
1771 memcpy(msr_report->da, da, ETH_ALEN);
1772 memcpy(msr_report->sa, dev->dev_addr, ETH_ALEN);
1773 memcpy(msr_report->bssid, bssid, ETH_ALEN);
1774 msr_report->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
1775 IEEE80211_STYPE_ACTION);
1776
1777 skb_put(skb, 1 + sizeof(msr_report->u.action.u.measurement));
1778 msr_report->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT;
1779 msr_report->u.action.u.measurement.action_code =
1780 WLAN_ACTION_SPCT_MSR_RPRT;
1781 msr_report->u.action.u.measurement.dialog_token = dialog_token;
1782
1783 msr_report->u.action.u.measurement.element_id = WLAN_EID_MEASURE_REPORT;
1784 msr_report->u.action.u.measurement.length =
1785 sizeof(struct ieee80211_msrment_ie);
1786
1787 memset(&msr_report->u.action.u.measurement.msr_elem, 0,
1788 sizeof(struct ieee80211_msrment_ie));
1789 msr_report->u.action.u.measurement.msr_elem.token = request_ie->token;
1790 msr_report->u.action.u.measurement.msr_elem.mode |=
1791 IEEE80211_SPCT_MSR_RPRT_MODE_REFUSED;
1792 msr_report->u.action.u.measurement.msr_elem.type = request_ie->type;
1793
1794 ieee80211_sta_tx(dev, skb, 0);
1795}
1796
1797static void ieee80211_sta_process_measurement_req(struct net_device *dev,
1798 struct ieee80211_mgmt *mgmt,
1799 size_t len)
1800{
1801 /*
1802 * Ignoring measurement request is spec violation.
1803 * Mandatory measurements must be reported optional
1804 * measurements might be refused or reported incapable
1805 * For now just refuse
1806 * TODO: Answer basic measurement as unmeasured
1807 */
1808 ieee80211_send_refuse_measurement_request(dev,
1809 &mgmt->u.action.u.measurement.msr_elem,
1810 mgmt->sa, mgmt->bssid,
1811 mgmt->u.action.u.measurement.dialog_token);
1812} 1027}
1813 1028
1814 1029static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
1815static void ieee80211_rx_mgmt_auth(struct net_device *dev,
1816 struct ieee80211_if_sta *ifsta, 1030 struct ieee80211_if_sta *ifsta,
1817 struct ieee80211_mgmt *mgmt, 1031 struct ieee80211_mgmt *mgmt,
1818 size_t len) 1032 size_t len)
1819{ 1033{
1820 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1821 u16 auth_alg, auth_transaction, status_code; 1034 u16 auth_alg, auth_transaction, status_code;
1822 DECLARE_MAC_BUF(mac); 1035 DECLARE_MAC_BUF(mac);
1823 1036
1824 if (ifsta->state != IEEE80211_AUTHENTICATE && 1037 if (ifsta->state != IEEE80211_STA_MLME_AUTHENTICATE &&
1825 sdata->vif.type != IEEE80211_IF_TYPE_IBSS) 1038 sdata->vif.type != NL80211_IFTYPE_ADHOC)
1826 return; 1039 return;
1827 1040
1828 if (len < 24 + 6) 1041 if (len < 24 + 6)
1829 return; 1042 return;
1830 1043
1831 if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS && 1044 if (sdata->vif.type != NL80211_IFTYPE_ADHOC &&
1832 memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) 1045 memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0)
1833 return; 1046 return;
1834 1047
1835 if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS && 1048 if (sdata->vif.type != NL80211_IFTYPE_ADHOC &&
1836 memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0) 1049 memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0)
1837 return; 1050 return;
1838 1051
@@ -1840,7 +1053,7 @@ static void ieee80211_rx_mgmt_auth(struct net_device *dev,
1840 auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); 1053 auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
1841 status_code = le16_to_cpu(mgmt->u.auth.status_code); 1054 status_code = le16_to_cpu(mgmt->u.auth.status_code);
1842 1055
1843 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { 1056 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
1844 /* 1057 /*
1845 * IEEE 802.11 standard does not require authentication in IBSS 1058 * IEEE 802.11 standard does not require authentication in IBSS
1846 * networks and most implementations do not seem to use it. 1059 * networks and most implementations do not seem to use it.
@@ -1849,7 +1062,7 @@ static void ieee80211_rx_mgmt_auth(struct net_device *dev,
1849 */ 1062 */
1850 if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) 1063 if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1)
1851 return; 1064 return;
1852 ieee80211_send_auth(dev, ifsta, 2, NULL, 0, 0); 1065 ieee80211_send_auth(sdata, ifsta, 2, NULL, 0, 0);
1853 } 1066 }
1854 1067
1855 if (auth_alg != ifsta->auth_alg || 1068 if (auth_alg != ifsta->auth_alg ||
@@ -1882,7 +1095,7 @@ static void ieee80211_rx_mgmt_auth(struct net_device *dev,
1882 algs[pos] == 0xff) 1095 algs[pos] == 0xff)
1883 continue; 1096 continue;
1884 if (algs[pos] == WLAN_AUTH_SHARED_KEY && 1097 if (algs[pos] == WLAN_AUTH_SHARED_KEY &&
1885 !ieee80211_sta_wep_configured(dev)) 1098 !ieee80211_sta_wep_configured(sdata))
1886 continue; 1099 continue;
1887 ifsta->auth_alg = algs[pos]; 1100 ifsta->auth_alg = algs[pos];
1888 break; 1101 break;
@@ -1894,19 +1107,19 @@ static void ieee80211_rx_mgmt_auth(struct net_device *dev,
1894 switch (ifsta->auth_alg) { 1107 switch (ifsta->auth_alg) {
1895 case WLAN_AUTH_OPEN: 1108 case WLAN_AUTH_OPEN:
1896 case WLAN_AUTH_LEAP: 1109 case WLAN_AUTH_LEAP:
1897 ieee80211_auth_completed(dev, ifsta); 1110 ieee80211_auth_completed(sdata, ifsta);
1898 break; 1111 break;
1899 case WLAN_AUTH_SHARED_KEY: 1112 case WLAN_AUTH_SHARED_KEY:
1900 if (ifsta->auth_transaction == 4) 1113 if (ifsta->auth_transaction == 4)
1901 ieee80211_auth_completed(dev, ifsta); 1114 ieee80211_auth_completed(sdata, ifsta);
1902 else 1115 else
1903 ieee80211_auth_challenge(dev, ifsta, mgmt, len); 1116 ieee80211_auth_challenge(sdata, ifsta, mgmt, len);
1904 break; 1117 break;
1905 } 1118 }
1906} 1119}
1907 1120
1908 1121
1909static void ieee80211_rx_mgmt_deauth(struct net_device *dev, 1122static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1910 struct ieee80211_if_sta *ifsta, 1123 struct ieee80211_if_sta *ifsta,
1911 struct ieee80211_mgmt *mgmt, 1124 struct ieee80211_mgmt *mgmt,
1912 size_t len) 1125 size_t len)
@@ -1923,22 +1136,22 @@ static void ieee80211_rx_mgmt_deauth(struct net_device *dev,
1923 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); 1136 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
1924 1137
1925 if (ifsta->flags & IEEE80211_STA_AUTHENTICATED) 1138 if (ifsta->flags & IEEE80211_STA_AUTHENTICATED)
1926 printk(KERN_DEBUG "%s: deauthenticated\n", dev->name); 1139 printk(KERN_DEBUG "%s: deauthenticated\n", sdata->dev->name);
1927 1140
1928 if (ifsta->state == IEEE80211_AUTHENTICATE || 1141 if (ifsta->state == IEEE80211_STA_MLME_AUTHENTICATE ||
1929 ifsta->state == IEEE80211_ASSOCIATE || 1142 ifsta->state == IEEE80211_STA_MLME_ASSOCIATE ||
1930 ifsta->state == IEEE80211_ASSOCIATED) { 1143 ifsta->state == IEEE80211_STA_MLME_ASSOCIATED) {
1931 ifsta->state = IEEE80211_AUTHENTICATE; 1144 ifsta->state = IEEE80211_STA_MLME_DIRECT_PROBE;
1932 mod_timer(&ifsta->timer, jiffies + 1145 mod_timer(&ifsta->timer, jiffies +
1933 IEEE80211_RETRY_AUTH_INTERVAL); 1146 IEEE80211_RETRY_AUTH_INTERVAL);
1934 } 1147 }
1935 1148
1936 ieee80211_set_disassoc(dev, ifsta, 1); 1149 ieee80211_set_disassoc(sdata, ifsta, true, false, 0);
1937 ifsta->flags &= ~IEEE80211_STA_AUTHENTICATED; 1150 ifsta->flags &= ~IEEE80211_STA_AUTHENTICATED;
1938} 1151}
1939 1152
1940 1153
1941static void ieee80211_rx_mgmt_disassoc(struct net_device *dev, 1154static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
1942 struct ieee80211_if_sta *ifsta, 1155 struct ieee80211_if_sta *ifsta,
1943 struct ieee80211_mgmt *mgmt, 1156 struct ieee80211_mgmt *mgmt,
1944 size_t len) 1157 size_t len)
@@ -1955,15 +1168,15 @@ static void ieee80211_rx_mgmt_disassoc(struct net_device *dev,
1955 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); 1168 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
1956 1169
1957 if (ifsta->flags & IEEE80211_STA_ASSOCIATED) 1170 if (ifsta->flags & IEEE80211_STA_ASSOCIATED)
1958 printk(KERN_DEBUG "%s: disassociated\n", dev->name); 1171 printk(KERN_DEBUG "%s: disassociated\n", sdata->dev->name);
1959 1172
1960 if (ifsta->state == IEEE80211_ASSOCIATED) { 1173 if (ifsta->state == IEEE80211_STA_MLME_ASSOCIATED) {
1961 ifsta->state = IEEE80211_ASSOCIATE; 1174 ifsta->state = IEEE80211_STA_MLME_ASSOCIATE;
1962 mod_timer(&ifsta->timer, jiffies + 1175 mod_timer(&ifsta->timer, jiffies +
1963 IEEE80211_RETRY_AUTH_INTERVAL); 1176 IEEE80211_RETRY_AUTH_INTERVAL);
1964 } 1177 }
1965 1178
1966 ieee80211_set_disassoc(dev, ifsta, 0); 1179 ieee80211_set_disassoc(sdata, ifsta, false, false, 0);
1967} 1180}
1968 1181
1969 1182
@@ -1974,7 +1187,6 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1974 int reassoc) 1187 int reassoc)
1975{ 1188{
1976 struct ieee80211_local *local = sdata->local; 1189 struct ieee80211_local *local = sdata->local;
1977 struct net_device *dev = sdata->dev;
1978 struct ieee80211_supported_band *sband; 1190 struct ieee80211_supported_band *sband;
1979 struct sta_info *sta; 1191 struct sta_info *sta;
1980 u64 rates, basic_rates; 1192 u64 rates, basic_rates;
@@ -1989,7 +1201,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1989 /* AssocResp and ReassocResp have identical structure, so process both 1201 /* AssocResp and ReassocResp have identical structure, so process both
1990 * of them in this function. */ 1202 * of them in this function. */
1991 1203
1992 if (ifsta->state != IEEE80211_ASSOCIATE) 1204 if (ifsta->state != IEEE80211_STA_MLME_ASSOCIATE)
1993 return; 1205 return;
1994 1206
1995 if (len < 24 + 6) 1207 if (len < 24 + 6)
@@ -2004,12 +1216,12 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2004 1216
2005 printk(KERN_DEBUG "%s: RX %sssocResp from %s (capab=0x%x " 1217 printk(KERN_DEBUG "%s: RX %sssocResp from %s (capab=0x%x "
2006 "status=%d aid=%d)\n", 1218 "status=%d aid=%d)\n",
2007 dev->name, reassoc ? "Rea" : "A", print_mac(mac, mgmt->sa), 1219 sdata->dev->name, reassoc ? "Rea" : "A", print_mac(mac, mgmt->sa),
2008 capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14)))); 1220 capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14))));
2009 1221
2010 if (status_code != WLAN_STATUS_SUCCESS) { 1222 if (status_code != WLAN_STATUS_SUCCESS) {
2011 printk(KERN_DEBUG "%s: AP denied association (code=%d)\n", 1223 printk(KERN_DEBUG "%s: AP denied association (code=%d)\n",
2012 dev->name, status_code); 1224 sdata->dev->name, status_code);
2013 /* if this was a reassociation, ensure we try a "full" 1225 /* if this was a reassociation, ensure we try a "full"
2014 * association next time. This works around some broken APs 1226 * association next time. This works around some broken APs
2015 * which do not correctly reject reassociation requests. */ 1227 * which do not correctly reject reassociation requests. */
@@ -2019,7 +1231,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2019 1231
2020 if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) 1232 if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
2021 printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not " 1233 printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not "
2022 "set\n", dev->name, aid); 1234 "set\n", sdata->dev->name, aid);
2023 aid &= ~(BIT(15) | BIT(14)); 1235 aid &= ~(BIT(15) | BIT(14));
2024 1236
2025 pos = mgmt->u.assoc_resp.variable; 1237 pos = mgmt->u.assoc_resp.variable;
@@ -2027,11 +1239,11 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2027 1239
2028 if (!elems.supp_rates) { 1240 if (!elems.supp_rates) {
2029 printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n", 1241 printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n",
2030 dev->name); 1242 sdata->dev->name);
2031 return; 1243 return;
2032 } 1244 }
2033 1245
2034 printk(KERN_DEBUG "%s: associated\n", dev->name); 1246 printk(KERN_DEBUG "%s: associated\n", sdata->dev->name);
2035 ifsta->aid = aid; 1247 ifsta->aid = aid;
2036 ifsta->ap_capab = capab_info; 1248 ifsta->ap_capab = capab_info;
2037 1249
@@ -2046,17 +1258,17 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2046 /* Add STA entry for the AP */ 1258 /* Add STA entry for the AP */
2047 sta = sta_info_get(local, ifsta->bssid); 1259 sta = sta_info_get(local, ifsta->bssid);
2048 if (!sta) { 1260 if (!sta) {
2049 struct ieee80211_sta_bss *bss; 1261 struct ieee80211_bss *bss;
2050 int err; 1262 int err;
2051 1263
2052 sta = sta_info_alloc(sdata, ifsta->bssid, GFP_ATOMIC); 1264 sta = sta_info_alloc(sdata, ifsta->bssid, GFP_ATOMIC);
2053 if (!sta) { 1265 if (!sta) {
2054 printk(KERN_DEBUG "%s: failed to alloc STA entry for" 1266 printk(KERN_DEBUG "%s: failed to alloc STA entry for"
2055 " the AP\n", dev->name); 1267 " the AP\n", sdata->dev->name);
2056 rcu_read_unlock(); 1268 rcu_read_unlock();
2057 return; 1269 return;
2058 } 1270 }
2059 bss = ieee80211_rx_bss_get(dev, ifsta->bssid, 1271 bss = ieee80211_rx_bss_get(local, ifsta->bssid,
2060 local->hw.conf.channel->center_freq, 1272 local->hw.conf.channel->center_freq,
2061 ifsta->ssid, ifsta->ssid_len); 1273 ifsta->ssid, ifsta->ssid_len);
2062 if (bss) { 1274 if (bss) {
@@ -2069,7 +1281,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2069 err = sta_info_insert(sta); 1281 err = sta_info_insert(sta);
2070 if (err) { 1282 if (err) {
2071 printk(KERN_DEBUG "%s: failed to insert STA entry for" 1283 printk(KERN_DEBUG "%s: failed to insert STA entry for"
2072 " the AP (error %d)\n", dev->name, err); 1284 " the AP (error %d)\n", sdata->dev->name, err);
2073 rcu_read_unlock(); 1285 rcu_read_unlock();
2074 return; 1286 return;
2075 } 1287 }
@@ -2122,8 +1334,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2122 } 1334 }
2123 } 1335 }
2124 1336
2125 sta->supp_rates[local->hw.conf.channel->band] = rates; 1337 sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
2126 sdata->basic_rates = basic_rates; 1338 sdata->bss_conf.basic_rates = basic_rates;
2127 1339
2128 /* cf. IEEE 802.11 9.2.12 */ 1340 /* cf. IEEE 802.11 9.2.12 */
2129 if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && 1341 if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ &&
@@ -2137,19 +1349,19 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2137 struct ieee80211_ht_bss_info bss_info; 1349 struct ieee80211_ht_bss_info bss_info;
2138 ieee80211_ht_cap_ie_to_ht_info( 1350 ieee80211_ht_cap_ie_to_ht_info(
2139 (struct ieee80211_ht_cap *) 1351 (struct ieee80211_ht_cap *)
2140 elems.ht_cap_elem, &sta->ht_info); 1352 elems.ht_cap_elem, &sta->sta.ht_info);
2141 ieee80211_ht_addt_info_ie_to_ht_bss_info( 1353 ieee80211_ht_addt_info_ie_to_ht_bss_info(
2142 (struct ieee80211_ht_addt_info *) 1354 (struct ieee80211_ht_addt_info *)
2143 elems.ht_info_elem, &bss_info); 1355 elems.ht_info_elem, &bss_info);
2144 ieee80211_handle_ht(local, 1, &sta->ht_info, &bss_info); 1356 ieee80211_handle_ht(local, 1, &sta->sta.ht_info, &bss_info);
2145 } 1357 }
2146 1358
2147 rate_control_rate_init(sta, local); 1359 rate_control_rate_init(sta);
2148 1360
2149 if (elems.wmm_param) { 1361 if (elems.wmm_param) {
2150 set_sta_flags(sta, WLAN_STA_WME); 1362 set_sta_flags(sta, WLAN_STA_WME);
2151 rcu_read_unlock(); 1363 rcu_read_unlock();
2152 ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, 1364 ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param,
2153 elems.wmm_param_len); 1365 elems.wmm_param_len);
2154 } else 1366 } else
2155 rcu_read_unlock(); 1367 rcu_read_unlock();
@@ -2158,234 +1370,26 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2158 * ieee80211_set_associated() will tell the driver */ 1370 * ieee80211_set_associated() will tell the driver */
2159 bss_conf->aid = aid; 1371 bss_conf->aid = aid;
2160 bss_conf->assoc_capability = capab_info; 1372 bss_conf->assoc_capability = capab_info;
2161 ieee80211_set_associated(dev, ifsta, 1); 1373 ieee80211_set_associated(sdata, ifsta);
2162
2163 ieee80211_associated(dev, ifsta);
2164}
2165
2166 1374
2167/* Caller must hold local->sta_bss_lock */ 1375 ieee80211_associated(sdata, ifsta);
2168static void __ieee80211_rx_bss_hash_add(struct net_device *dev,
2169 struct ieee80211_sta_bss *bss)
2170{
2171 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
2172 u8 hash_idx;
2173
2174 if (bss_mesh_cfg(bss))
2175 hash_idx = mesh_id_hash(bss_mesh_id(bss),
2176 bss_mesh_id_len(bss));
2177 else
2178 hash_idx = STA_HASH(bss->bssid);
2179
2180 bss->hnext = local->sta_bss_hash[hash_idx];
2181 local->sta_bss_hash[hash_idx] = bss;
2182}
2183
2184
2185/* Caller must hold local->sta_bss_lock */
2186static void __ieee80211_rx_bss_hash_del(struct ieee80211_local *local,
2187 struct ieee80211_sta_bss *bss)
2188{
2189 struct ieee80211_sta_bss *b, *prev = NULL;
2190 b = local->sta_bss_hash[STA_HASH(bss->bssid)];
2191 while (b) {
2192 if (b == bss) {
2193 if (!prev)
2194 local->sta_bss_hash[STA_HASH(bss->bssid)] =
2195 bss->hnext;
2196 else
2197 prev->hnext = bss->hnext;
2198 break;
2199 }
2200 prev = b;
2201 b = b->hnext;
2202 }
2203}
2204
2205
2206static struct ieee80211_sta_bss *
2207ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int freq,
2208 u8 *ssid, u8 ssid_len)
2209{
2210 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
2211 struct ieee80211_sta_bss *bss;
2212
2213 bss = kzalloc(sizeof(*bss), GFP_ATOMIC);
2214 if (!bss)
2215 return NULL;
2216 atomic_inc(&bss->users);
2217 atomic_inc(&bss->users);
2218 memcpy(bss->bssid, bssid, ETH_ALEN);
2219 bss->freq = freq;
2220 if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) {
2221 memcpy(bss->ssid, ssid, ssid_len);
2222 bss->ssid_len = ssid_len;
2223 }
2224
2225 spin_lock_bh(&local->sta_bss_lock);
2226 /* TODO: order by RSSI? */
2227 list_add_tail(&bss->list, &local->sta_bss_list);
2228 __ieee80211_rx_bss_hash_add(dev, bss);
2229 spin_unlock_bh(&local->sta_bss_lock);
2230 return bss;
2231}
2232
2233static struct ieee80211_sta_bss *
2234ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int freq,
2235 u8 *ssid, u8 ssid_len)
2236{
2237 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
2238 struct ieee80211_sta_bss *bss;
2239
2240 spin_lock_bh(&local->sta_bss_lock);
2241 bss = local->sta_bss_hash[STA_HASH(bssid)];
2242 while (bss) {
2243 if (!bss_mesh_cfg(bss) &&
2244 !memcmp(bss->bssid, bssid, ETH_ALEN) &&
2245 bss->freq == freq &&
2246 bss->ssid_len == ssid_len &&
2247 (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) {
2248 atomic_inc(&bss->users);
2249 break;
2250 }
2251 bss = bss->hnext;
2252 }
2253 spin_unlock_bh(&local->sta_bss_lock);
2254 return bss;
2255}
2256
2257#ifdef CONFIG_MAC80211_MESH
2258static struct ieee80211_sta_bss *
2259ieee80211_rx_mesh_bss_get(struct net_device *dev, u8 *mesh_id, int mesh_id_len,
2260 u8 *mesh_cfg, int freq)
2261{
2262 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
2263 struct ieee80211_sta_bss *bss;
2264
2265 spin_lock_bh(&local->sta_bss_lock);
2266 bss = local->sta_bss_hash[mesh_id_hash(mesh_id, mesh_id_len)];
2267 while (bss) {
2268 if (bss_mesh_cfg(bss) &&
2269 !memcmp(bss_mesh_cfg(bss), mesh_cfg, MESH_CFG_CMP_LEN) &&
2270 bss->freq == freq &&
2271 mesh_id_len == bss->mesh_id_len &&
2272 (mesh_id_len == 0 || !memcmp(bss->mesh_id, mesh_id,
2273 mesh_id_len))) {
2274 atomic_inc(&bss->users);
2275 break;
2276 }
2277 bss = bss->hnext;
2278 }
2279 spin_unlock_bh(&local->sta_bss_lock);
2280 return bss;
2281}
2282
2283static struct ieee80211_sta_bss *
2284ieee80211_rx_mesh_bss_add(struct net_device *dev, u8 *mesh_id, int mesh_id_len,
2285 u8 *mesh_cfg, int mesh_config_len, int freq)
2286{
2287 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
2288 struct ieee80211_sta_bss *bss;
2289
2290 if (mesh_config_len != MESH_CFG_LEN)
2291 return NULL;
2292
2293 bss = kzalloc(sizeof(*bss), GFP_ATOMIC);
2294 if (!bss)
2295 return NULL;
2296
2297 bss->mesh_cfg = kmalloc(MESH_CFG_CMP_LEN, GFP_ATOMIC);
2298 if (!bss->mesh_cfg) {
2299 kfree(bss);
2300 return NULL;
2301 }
2302
2303 if (mesh_id_len && mesh_id_len <= IEEE80211_MAX_MESH_ID_LEN) {
2304 bss->mesh_id = kmalloc(mesh_id_len, GFP_ATOMIC);
2305 if (!bss->mesh_id) {
2306 kfree(bss->mesh_cfg);
2307 kfree(bss);
2308 return NULL;
2309 }
2310 memcpy(bss->mesh_id, mesh_id, mesh_id_len);
2311 }
2312
2313 atomic_inc(&bss->users);
2314 atomic_inc(&bss->users);
2315 memcpy(bss->mesh_cfg, mesh_cfg, MESH_CFG_CMP_LEN);
2316 bss->mesh_id_len = mesh_id_len;
2317 bss->freq = freq;
2318 spin_lock_bh(&local->sta_bss_lock);
2319 /* TODO: order by RSSI? */
2320 list_add_tail(&bss->list, &local->sta_bss_list);
2321 __ieee80211_rx_bss_hash_add(dev, bss);
2322 spin_unlock_bh(&local->sta_bss_lock);
2323 return bss;
2324}
2325#endif
2326
2327static void ieee80211_rx_bss_free(struct ieee80211_sta_bss *bss)
2328{
2329 kfree(bss->wpa_ie);
2330 kfree(bss->rsn_ie);
2331 kfree(bss->wmm_ie);
2332 kfree(bss->ht_ie);
2333 kfree(bss->ht_add_ie);
2334 kfree(bss_mesh_id(bss));
2335 kfree(bss_mesh_cfg(bss));
2336 kfree(bss);
2337}
2338
2339
2340static void ieee80211_rx_bss_put(struct ieee80211_local *local,
2341 struct ieee80211_sta_bss *bss)
2342{
2343 local_bh_disable();
2344 if (!atomic_dec_and_lock(&bss->users, &local->sta_bss_lock)) {
2345 local_bh_enable();
2346 return;
2347 }
2348
2349 __ieee80211_rx_bss_hash_del(local, bss);
2350 list_del(&bss->list);
2351 spin_unlock_bh(&local->sta_bss_lock);
2352 ieee80211_rx_bss_free(bss);
2353}
2354
2355
2356void ieee80211_rx_bss_list_init(struct ieee80211_local *local)
2357{
2358 spin_lock_init(&local->sta_bss_lock);
2359 INIT_LIST_HEAD(&local->sta_bss_list);
2360}
2361
2362
2363void ieee80211_rx_bss_list_deinit(struct ieee80211_local *local)
2364{
2365 struct ieee80211_sta_bss *bss, *tmp;
2366
2367 list_for_each_entry_safe(bss, tmp, &local->sta_bss_list, list)
2368 ieee80211_rx_bss_put(local, bss);
2369} 1376}
2370 1377
2371 1378
2372static int ieee80211_sta_join_ibss(struct net_device *dev, 1379static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
2373 struct ieee80211_if_sta *ifsta, 1380 struct ieee80211_if_sta *ifsta,
2374 struct ieee80211_sta_bss *bss) 1381 struct ieee80211_bss *bss)
2375{ 1382{
2376 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1383 struct ieee80211_local *local = sdata->local;
2377 int res, rates, i, j; 1384 int res, rates, i, j;
2378 struct sk_buff *skb; 1385 struct sk_buff *skb;
2379 struct ieee80211_mgmt *mgmt; 1386 struct ieee80211_mgmt *mgmt;
2380 u8 *pos; 1387 u8 *pos;
2381 struct ieee80211_sub_if_data *sdata;
2382 struct ieee80211_supported_band *sband; 1388 struct ieee80211_supported_band *sband;
2383 union iwreq_data wrqu; 1389 union iwreq_data wrqu;
2384 1390
2385 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 1391 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
2386 1392
2387 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2388
2389 /* Remove possible STA entries from other IBSS networks. */ 1393 /* Remove possible STA entries from other IBSS networks. */
2390 sta_info_flush_delayed(sdata); 1394 sta_info_flush_delayed(sdata);
2391 1395
@@ -2403,7 +1407,7 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
2403 sdata->drop_unencrypted = bss->capability & 1407 sdata->drop_unencrypted = bss->capability &
2404 WLAN_CAPABILITY_PRIVACY ? 1 : 0; 1408 WLAN_CAPABILITY_PRIVACY ? 1 : 0;
2405 1409
2406 res = ieee80211_set_freq(dev, bss->freq); 1410 res = ieee80211_set_freq(sdata, bss->freq);
2407 1411
2408 if (res) 1412 if (res)
2409 return res; 1413 return res;
@@ -2416,10 +1420,10 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
2416 mgmt = (struct ieee80211_mgmt *) 1420 mgmt = (struct ieee80211_mgmt *)
2417 skb_put(skb, 24 + sizeof(mgmt->u.beacon)); 1421 skb_put(skb, 24 + sizeof(mgmt->u.beacon));
2418 memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); 1422 memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
2419 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, 1423 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2420 IEEE80211_STYPE_PROBE_RESP); 1424 IEEE80211_STYPE_PROBE_RESP);
2421 memset(mgmt->da, 0xff, ETH_ALEN); 1425 memset(mgmt->da, 0xff, ETH_ALEN);
2422 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); 1426 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
2423 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); 1427 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
2424 mgmt->u.beacon.beacon_int = 1428 mgmt->u.beacon.beacon_int =
2425 cpu_to_le16(local->hw.conf.beacon_int); 1429 cpu_to_le16(local->hw.conf.beacon_int);
@@ -2476,108 +1480,38 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
2476 } 1480 }
2477 ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates; 1481 ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates;
2478 1482
2479 ieee80211_sta_def_wmm_params(dev, bss, 1); 1483 ieee80211_sta_def_wmm_params(sdata, bss);
2480 1484
2481 ifsta->state = IEEE80211_IBSS_JOINED; 1485 ifsta->state = IEEE80211_STA_MLME_IBSS_JOINED;
2482 mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); 1486 mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL);
2483 1487
1488 ieee80211_led_assoc(local, true);
1489
2484 memset(&wrqu, 0, sizeof(wrqu)); 1490 memset(&wrqu, 0, sizeof(wrqu));
2485 memcpy(wrqu.ap_addr.sa_data, bss->bssid, ETH_ALEN); 1491 memcpy(wrqu.ap_addr.sa_data, bss->bssid, ETH_ALEN);
2486 wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); 1492 wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL);
2487 1493
2488 return res; 1494 return res;
2489} 1495}
2490 1496
2491u64 ieee80211_sta_get_rates(struct ieee80211_local *local, 1497static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2492 struct ieee802_11_elems *elems,
2493 enum ieee80211_band band)
2494{
2495 struct ieee80211_supported_band *sband;
2496 struct ieee80211_rate *bitrates;
2497 size_t num_rates;
2498 u64 supp_rates;
2499 int i, j;
2500 sband = local->hw.wiphy->bands[band];
2501
2502 if (!sband) {
2503 WARN_ON(1);
2504 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
2505 }
2506
2507 bitrates = sband->bitrates;
2508 num_rates = sband->n_bitrates;
2509 supp_rates = 0;
2510 for (i = 0; i < elems->supp_rates_len +
2511 elems->ext_supp_rates_len; i++) {
2512 u8 rate = 0;
2513 int own_rate;
2514 if (i < elems->supp_rates_len)
2515 rate = elems->supp_rates[i];
2516 else if (elems->ext_supp_rates)
2517 rate = elems->ext_supp_rates
2518 [i - elems->supp_rates_len];
2519 own_rate = 5 * (rate & 0x7f);
2520 for (j = 0; j < num_rates; j++)
2521 if (bitrates[j].bitrate == own_rate)
2522 supp_rates |= BIT(j);
2523 }
2524 return supp_rates;
2525}
2526
2527
2528static void ieee80211_rx_bss_info(struct net_device *dev,
2529 struct ieee80211_mgmt *mgmt, 1498 struct ieee80211_mgmt *mgmt,
2530 size_t len, 1499 size_t len,
2531 struct ieee80211_rx_status *rx_status, 1500 struct ieee80211_rx_status *rx_status,
2532 struct ieee802_11_elems *elems, 1501 struct ieee802_11_elems *elems,
2533 int beacon) 1502 bool beacon)
2534{ 1503{
2535 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1504 struct ieee80211_local *local = sdata->local;
2536 int freq, clen; 1505 int freq;
2537 struct ieee80211_sta_bss *bss; 1506 struct ieee80211_bss *bss;
2538 struct sta_info *sta; 1507 struct sta_info *sta;
2539 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2540 u64 beacon_timestamp, rx_timestamp;
2541 struct ieee80211_channel *channel; 1508 struct ieee80211_channel *channel;
1509 u64 beacon_timestamp, rx_timestamp;
1510 u64 supp_rates = 0;
1511 enum ieee80211_band band = rx_status->band;
2542 DECLARE_MAC_BUF(mac); 1512 DECLARE_MAC_BUF(mac);
2543 DECLARE_MAC_BUF(mac2); 1513 DECLARE_MAC_BUF(mac2);
2544 1514
2545 if (!beacon && memcmp(mgmt->da, dev->dev_addr, ETH_ALEN))
2546 return; /* ignore ProbeResp to foreign address */
2547
2548 beacon_timestamp = le64_to_cpu(mgmt->u.beacon.timestamp);
2549
2550 if (ieee80211_vif_is_mesh(&sdata->vif) && elems->mesh_id &&
2551 elems->mesh_config && mesh_matches_local(elems, dev)) {
2552 u64 rates = ieee80211_sta_get_rates(local, elems,
2553 rx_status->band);
2554
2555 mesh_neighbour_update(mgmt->sa, rates, dev,
2556 mesh_peer_accepts_plinks(elems, dev));
2557 }
2558
2559 rcu_read_lock();
2560
2561 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems->supp_rates &&
2562 memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 &&
2563 (sta = sta_info_get(local, mgmt->sa))) {
2564 u64 prev_rates;
2565 u64 supp_rates = ieee80211_sta_get_rates(local, elems,
2566 rx_status->band);
2567
2568 prev_rates = sta->supp_rates[rx_status->band];
2569 sta->supp_rates[rx_status->band] &= supp_rates;
2570 if (sta->supp_rates[rx_status->band] == 0) {
2571 /* No matching rates - this should not really happen.
2572 * Make sure that at least one rate is marked
2573 * supported to avoid issues with TX rate ctrl. */
2574 sta->supp_rates[rx_status->band] =
2575 sdata->u.sta.supp_rates_bits[rx_status->band];
2576 }
2577 }
2578
2579 rcu_read_unlock();
2580
2581 if (elems->ds_params && elems->ds_params_len == 1) 1515 if (elems->ds_params && elems->ds_params_len == 1)
2582 freq = ieee80211_channel_to_frequency(elems->ds_params[0]); 1516 freq = ieee80211_channel_to_frequency(elems->ds_params[0]);
2583 else 1517 else
@@ -2588,215 +1522,60 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
2588 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED) 1522 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
2589 return; 1523 return;
2590 1524
2591#ifdef CONFIG_MAC80211_MESH 1525 if (sdata->vif.type == NL80211_IFTYPE_ADHOC && elems->supp_rates &&
2592 if (elems->mesh_config) 1526 memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0) {
2593 bss = ieee80211_rx_mesh_bss_get(dev, elems->mesh_id, 1527 supp_rates = ieee80211_sta_get_rates(local, elems, band);
2594 elems->mesh_id_len, elems->mesh_config, freq);
2595 else
2596#endif
2597 bss = ieee80211_rx_bss_get(dev, mgmt->bssid, freq,
2598 elems->ssid, elems->ssid_len);
2599 if (!bss) {
2600#ifdef CONFIG_MAC80211_MESH
2601 if (elems->mesh_config)
2602 bss = ieee80211_rx_mesh_bss_add(dev, elems->mesh_id,
2603 elems->mesh_id_len, elems->mesh_config,
2604 elems->mesh_config_len, freq);
2605 else
2606#endif
2607 bss = ieee80211_rx_bss_add(dev, mgmt->bssid, freq,
2608 elems->ssid, elems->ssid_len);
2609 if (!bss)
2610 return;
2611 } else {
2612#if 0
2613 /* TODO: order by RSSI? */
2614 spin_lock_bh(&local->sta_bss_lock);
2615 list_move_tail(&bss->list, &local->sta_bss_list);
2616 spin_unlock_bh(&local->sta_bss_lock);
2617#endif
2618 }
2619 1528
2620 /* save the ERP value so that it is available at association time */ 1529 rcu_read_lock();
2621 if (elems->erp_info && elems->erp_info_len >= 1) {
2622 bss->erp_value = elems->erp_info[0];
2623 bss->has_erp_value = 1;
2624 }
2625 1530
2626 if (elems->ht_cap_elem && 1531 sta = sta_info_get(local, mgmt->sa);
2627 (!bss->ht_ie || bss->ht_ie_len != elems->ht_cap_elem_len || 1532 if (sta) {
2628 memcmp(bss->ht_ie, elems->ht_cap_elem, elems->ht_cap_elem_len))) { 1533 u64 prev_rates;
2629 kfree(bss->ht_ie);
2630 bss->ht_ie = kmalloc(elems->ht_cap_elem_len + 2, GFP_ATOMIC);
2631 if (bss->ht_ie) {
2632 memcpy(bss->ht_ie, elems->ht_cap_elem - 2,
2633 elems->ht_cap_elem_len + 2);
2634 bss->ht_ie_len = elems->ht_cap_elem_len + 2;
2635 } else
2636 bss->ht_ie_len = 0;
2637 } else if (!elems->ht_cap_elem && bss->ht_ie) {
2638 kfree(bss->ht_ie);
2639 bss->ht_ie = NULL;
2640 bss->ht_ie_len = 0;
2641 }
2642 1534
2643 if (elems->ht_info_elem && 1535 prev_rates = sta->sta.supp_rates[band];
2644 (!bss->ht_add_ie || 1536 /* make sure mandatory rates are always added */
2645 bss->ht_add_ie_len != elems->ht_info_elem_len || 1537 sta->sta.supp_rates[band] = supp_rates |
2646 memcmp(bss->ht_add_ie, elems->ht_info_elem, 1538 ieee80211_mandatory_rates(local, band);
2647 elems->ht_info_elem_len))) {
2648 kfree(bss->ht_add_ie);
2649 bss->ht_add_ie =
2650 kmalloc(elems->ht_info_elem_len + 2, GFP_ATOMIC);
2651 if (bss->ht_add_ie) {
2652 memcpy(bss->ht_add_ie, elems->ht_info_elem - 2,
2653 elems->ht_info_elem_len + 2);
2654 bss->ht_add_ie_len = elems->ht_info_elem_len + 2;
2655 } else
2656 bss->ht_add_ie_len = 0;
2657 } else if (!elems->ht_info_elem && bss->ht_add_ie) {
2658 kfree(bss->ht_add_ie);
2659 bss->ht_add_ie = NULL;
2660 bss->ht_add_ie_len = 0;
2661 }
2662
2663 bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int);
2664 bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info);
2665 1539
2666 if (elems->tim) { 1540#ifdef CONFIG_MAC80211_IBSS_DEBUG
2667 struct ieee80211_tim_ie *tim_ie = 1541 if (sta->sta.supp_rates[band] != prev_rates)
2668 (struct ieee80211_tim_ie *)elems->tim; 1542 printk(KERN_DEBUG "%s: updated supp_rates set "
2669 bss->dtim_period = tim_ie->dtim_period; 1543 "for %s based on beacon info (0x%llx | "
2670 } 1544 "0x%llx -> 0x%llx)\n",
1545 sdata->dev->name,
1546 print_mac(mac, sta->sta.addr),
1547 (unsigned long long) prev_rates,
1548 (unsigned long long) supp_rates,
1549 (unsigned long long) sta->sta.supp_rates[band]);
1550#endif
1551 } else {
1552 ieee80211_ibss_add_sta(sdata, NULL, mgmt->bssid,
1553 mgmt->sa, supp_rates);
1554 }
2671 1555
2672 /* set default value for buggy APs */ 1556 rcu_read_unlock();
2673 if (!elems->tim || bss->dtim_period == 0)
2674 bss->dtim_period = 1;
2675
2676 bss->supp_rates_len = 0;
2677 if (elems->supp_rates) {
2678 clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len;
2679 if (clen > elems->supp_rates_len)
2680 clen = elems->supp_rates_len;
2681 memcpy(&bss->supp_rates[bss->supp_rates_len], elems->supp_rates,
2682 clen);
2683 bss->supp_rates_len += clen;
2684 }
2685 if (elems->ext_supp_rates) {
2686 clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len;
2687 if (clen > elems->ext_supp_rates_len)
2688 clen = elems->ext_supp_rates_len;
2689 memcpy(&bss->supp_rates[bss->supp_rates_len],
2690 elems->ext_supp_rates, clen);
2691 bss->supp_rates_len += clen;
2692 } 1557 }
2693 1558
2694 bss->band = rx_status->band; 1559 bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems,
1560 freq, beacon);
1561 if (!bss)
1562 return;
2695 1563
2696 bss->timestamp = beacon_timestamp; 1564 /* was just updated in ieee80211_bss_info_update */
2697 bss->last_update = jiffies; 1565 beacon_timestamp = bss->timestamp;
2698 bss->signal = rx_status->signal;
2699 bss->noise = rx_status->noise;
2700 bss->qual = rx_status->qual;
2701 if (!beacon && !bss->probe_resp)
2702 bss->probe_resp = true;
2703 1566
2704 /* 1567 /*
2705 * In STA mode, the remaining parameters should not be overridden 1568 * In STA mode, the remaining parameters should not be overridden
2706 * by beacons because they're not necessarily accurate there. 1569 * by beacons because they're not necessarily accurate there.
2707 */ 1570 */
2708 if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS && 1571 if (sdata->vif.type != NL80211_IFTYPE_ADHOC &&
2709 bss->probe_resp && beacon) { 1572 bss->last_probe_resp && beacon) {
2710 ieee80211_rx_bss_put(local, bss); 1573 ieee80211_rx_bss_put(local, bss);
2711 return; 1574 return;
2712 } 1575 }
2713 1576
2714 if (elems->wpa &&
2715 (!bss->wpa_ie || bss->wpa_ie_len != elems->wpa_len ||
2716 memcmp(bss->wpa_ie, elems->wpa, elems->wpa_len))) {
2717 kfree(bss->wpa_ie);
2718 bss->wpa_ie = kmalloc(elems->wpa_len + 2, GFP_ATOMIC);
2719 if (bss->wpa_ie) {
2720 memcpy(bss->wpa_ie, elems->wpa - 2, elems->wpa_len + 2);
2721 bss->wpa_ie_len = elems->wpa_len + 2;
2722 } else
2723 bss->wpa_ie_len = 0;
2724 } else if (!elems->wpa && bss->wpa_ie) {
2725 kfree(bss->wpa_ie);
2726 bss->wpa_ie = NULL;
2727 bss->wpa_ie_len = 0;
2728 }
2729
2730 if (elems->rsn &&
2731 (!bss->rsn_ie || bss->rsn_ie_len != elems->rsn_len ||
2732 memcmp(bss->rsn_ie, elems->rsn, elems->rsn_len))) {
2733 kfree(bss->rsn_ie);
2734 bss->rsn_ie = kmalloc(elems->rsn_len + 2, GFP_ATOMIC);
2735 if (bss->rsn_ie) {
2736 memcpy(bss->rsn_ie, elems->rsn - 2, elems->rsn_len + 2);
2737 bss->rsn_ie_len = elems->rsn_len + 2;
2738 } else
2739 bss->rsn_ie_len = 0;
2740 } else if (!elems->rsn && bss->rsn_ie) {
2741 kfree(bss->rsn_ie);
2742 bss->rsn_ie = NULL;
2743 bss->rsn_ie_len = 0;
2744 }
2745
2746 /*
2747 * Cf.
2748 * http://www.wipo.int/pctdb/en/wo.jsp?wo=2007047181&IA=WO2007047181&DISPLAY=DESC
2749 *
2750 * quoting:
2751 *
2752 * In particular, "Wi-Fi CERTIFIED for WMM - Support for Multimedia
2753 * Applications with Quality of Service in Wi-Fi Networks," Wi- Fi
2754 * Alliance (September 1, 2004) is incorporated by reference herein.
2755 * The inclusion of the WMM Parameters in probe responses and
2756 * association responses is mandatory for WMM enabled networks. The
2757 * inclusion of the WMM Parameters in beacons, however, is optional.
2758 */
2759
2760 if (elems->wmm_param &&
2761 (!bss->wmm_ie || bss->wmm_ie_len != elems->wmm_param_len ||
2762 memcmp(bss->wmm_ie, elems->wmm_param, elems->wmm_param_len))) {
2763 kfree(bss->wmm_ie);
2764 bss->wmm_ie = kmalloc(elems->wmm_param_len + 2, GFP_ATOMIC);
2765 if (bss->wmm_ie) {
2766 memcpy(bss->wmm_ie, elems->wmm_param - 2,
2767 elems->wmm_param_len + 2);
2768 bss->wmm_ie_len = elems->wmm_param_len + 2;
2769 } else
2770 bss->wmm_ie_len = 0;
2771 } else if (elems->wmm_info &&
2772 (!bss->wmm_ie || bss->wmm_ie_len != elems->wmm_info_len ||
2773 memcmp(bss->wmm_ie, elems->wmm_info,
2774 elems->wmm_info_len))) {
2775 /* As for certain AP's Fifth bit is not set in WMM IE in
2776 * beacon frames.So while parsing the beacon frame the
2777 * wmm_info structure is used instead of wmm_param.
2778 * wmm_info structure was never used to set bss->wmm_ie.
2779 * This code fixes this problem by copying the WME
2780 * information from wmm_info to bss->wmm_ie and enabling
2781 * n-band association.
2782 */
2783 kfree(bss->wmm_ie);
2784 bss->wmm_ie = kmalloc(elems->wmm_info_len + 2, GFP_ATOMIC);
2785 if (bss->wmm_ie) {
2786 memcpy(bss->wmm_ie, elems->wmm_info - 2,
2787 elems->wmm_info_len + 2);
2788 bss->wmm_ie_len = elems->wmm_info_len + 2;
2789 } else
2790 bss->wmm_ie_len = 0;
2791 } else if (!elems->wmm_param && !elems->wmm_info && bss->wmm_ie) {
2792 kfree(bss->wmm_ie);
2793 bss->wmm_ie = NULL;
2794 bss->wmm_ie_len = 0;
2795 }
2796
2797 /* check if we need to merge IBSS */ 1577 /* check if we need to merge IBSS */
2798 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && beacon && 1578 if (sdata->vif.type == NL80211_IFTYPE_ADHOC && beacon &&
2799 !local->sta_sw_scanning && !local->sta_hw_scanning &&
2800 bss->capability & WLAN_CAPABILITY_IBSS && 1579 bss->capability & WLAN_CAPABILITY_IBSS &&
2801 bss->freq == local->oper_channel->center_freq && 1580 bss->freq == local->oper_channel->center_freq &&
2802 elems->ssid_len == sdata->u.sta.ssid_len && 1581 elems->ssid_len == sdata->u.sta.ssid_len &&
@@ -2818,7 +1597,7 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
2818 * e.g: at 1 MBit that means mactime is 192 usec earlier 1597 * e.g: at 1 MBit that means mactime is 192 usec earlier
2819 * (=24 bytes * 8 usecs/byte) than the beacon timestamp. 1598 * (=24 bytes * 8 usecs/byte) than the beacon timestamp.
2820 */ 1599 */
2821 int rate = local->hw.wiphy->bands[rx_status->band]-> 1600 int rate = local->hw.wiphy->bands[band]->
2822 bitrates[rx_status->rate_idx].bitrate; 1601 bitrates[rx_status->rate_idx].bitrate;
2823 rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate); 1602 rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate);
2824 } else if (local && local->ops && local->ops->get_tsf) 1603 } else if (local && local->ops && local->ops->get_tsf)
@@ -2841,12 +1620,12 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
2841#ifdef CONFIG_MAC80211_IBSS_DEBUG 1620#ifdef CONFIG_MAC80211_IBSS_DEBUG
2842 printk(KERN_DEBUG "%s: beacon TSF higher than " 1621 printk(KERN_DEBUG "%s: beacon TSF higher than "
2843 "local TSF - IBSS merge with BSSID %s\n", 1622 "local TSF - IBSS merge with BSSID %s\n",
2844 dev->name, print_mac(mac, mgmt->bssid)); 1623 sdata->dev->name, print_mac(mac, mgmt->bssid));
2845#endif 1624#endif
2846 ieee80211_sta_join_ibss(dev, &sdata->u.sta, bss); 1625 ieee80211_sta_join_ibss(sdata, &sdata->u.sta, bss);
2847 ieee80211_ibss_add_sta(dev, NULL, 1626 ieee80211_ibss_add_sta(sdata, NULL,
2848 mgmt->bssid, mgmt->sa, 1627 mgmt->bssid, mgmt->sa,
2849 BIT(rx_status->rate_idx)); 1628 supp_rates);
2850 } 1629 }
2851 } 1630 }
2852 1631
@@ -2854,13 +1633,17 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
2854} 1633}
2855 1634
2856 1635
2857static void ieee80211_rx_mgmt_probe_resp(struct net_device *dev, 1636static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
2858 struct ieee80211_mgmt *mgmt, 1637 struct ieee80211_mgmt *mgmt,
2859 size_t len, 1638 size_t len,
2860 struct ieee80211_rx_status *rx_status) 1639 struct ieee80211_rx_status *rx_status)
2861{ 1640{
2862 size_t baselen; 1641 size_t baselen;
2863 struct ieee802_11_elems elems; 1642 struct ieee802_11_elems elems;
1643 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
1644
1645 if (memcmp(mgmt->da, sdata->dev->dev_addr, ETH_ALEN))
1646 return; /* ignore ProbeResp to foreign address */
2864 1647
2865 baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; 1648 baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
2866 if (baselen > len) 1649 if (baselen > len)
@@ -2869,20 +1652,27 @@ static void ieee80211_rx_mgmt_probe_resp(struct net_device *dev,
2869 ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, 1652 ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen,
2870 &elems); 1653 &elems);
2871 1654
2872 ieee80211_rx_bss_info(dev, mgmt, len, rx_status, &elems, 0); 1655 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false);
1656
1657 /* direct probe may be part of the association flow */
1658 if (test_and_clear_bit(IEEE80211_STA_REQ_DIRECT_PROBE,
1659 &ifsta->request)) {
1660 printk(KERN_DEBUG "%s direct probe responded\n",
1661 sdata->dev->name);
1662 ieee80211_authenticate(sdata, ifsta);
1663 }
2873} 1664}
2874 1665
2875 1666
2876static void ieee80211_rx_mgmt_beacon(struct net_device *dev, 1667static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2877 struct ieee80211_mgmt *mgmt, 1668 struct ieee80211_mgmt *mgmt,
2878 size_t len, 1669 size_t len,
2879 struct ieee80211_rx_status *rx_status) 1670 struct ieee80211_rx_status *rx_status)
2880{ 1671{
2881 struct ieee80211_sub_if_data *sdata;
2882 struct ieee80211_if_sta *ifsta; 1672 struct ieee80211_if_sta *ifsta;
2883 size_t baselen; 1673 size_t baselen;
2884 struct ieee802_11_elems elems; 1674 struct ieee802_11_elems elems;
2885 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1675 struct ieee80211_local *local = sdata->local;
2886 struct ieee80211_conf *conf = &local->hw.conf; 1676 struct ieee80211_conf *conf = &local->hw.conf;
2887 u32 changed = 0; 1677 u32 changed = 0;
2888 1678
@@ -2893,10 +1683,9 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev,
2893 1683
2894 ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); 1684 ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems);
2895 1685
2896 ieee80211_rx_bss_info(dev, mgmt, len, rx_status, &elems, 1); 1686 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, true);
2897 1687
2898 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1688 if (sdata->vif.type != NL80211_IFTYPE_STATION)
2899 if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
2900 return; 1689 return;
2901 ifsta = &sdata->u.sta; 1690 ifsta = &sdata->u.sta;
2902 1691
@@ -2904,15 +1693,9 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev,
2904 memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0) 1693 memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0)
2905 return; 1694 return;
2906 1695
2907 ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, 1696 ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param,
2908 elems.wmm_param_len); 1697 elems.wmm_param_len);
2909 1698
2910 /* Do not send changes to driver if we are scanning. This removes
2911 * requirement that driver's bss_info_changed function needs to be
2912 * atomic. */
2913 if (local->sta_sw_scanning || local->sta_hw_scanning)
2914 return;
2915
2916 if (elems.erp_info && elems.erp_info_len >= 1) 1699 if (elems.erp_info && elems.erp_info_len >= 1)
2917 changed |= ieee80211_handle_erp_ie(sdata, elems.erp_info[0]); 1700 changed |= ieee80211_handle_erp_ie(sdata, elems.erp_info[0]);
2918 else { 1701 else {
@@ -2936,14 +1719,13 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev,
2936} 1719}
2937 1720
2938 1721
2939static void ieee80211_rx_mgmt_probe_req(struct net_device *dev, 1722static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
2940 struct ieee80211_if_sta *ifsta, 1723 struct ieee80211_if_sta *ifsta,
2941 struct ieee80211_mgmt *mgmt, 1724 struct ieee80211_mgmt *mgmt,
2942 size_t len, 1725 size_t len,
2943 struct ieee80211_rx_status *rx_status) 1726 struct ieee80211_rx_status *rx_status)
2944{ 1727{
2945 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1728 struct ieee80211_local *local = sdata->local;
2946 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2947 int tx_last_beacon; 1729 int tx_last_beacon;
2948 struct sk_buff *skb; 1730 struct sk_buff *skb;
2949 struct ieee80211_mgmt *resp; 1731 struct ieee80211_mgmt *resp;
@@ -2954,8 +1736,8 @@ static void ieee80211_rx_mgmt_probe_req(struct net_device *dev,
2954 DECLARE_MAC_BUF(mac3); 1736 DECLARE_MAC_BUF(mac3);
2955#endif 1737#endif
2956 1738
2957 if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS || 1739 if (sdata->vif.type != NL80211_IFTYPE_ADHOC ||
2958 ifsta->state != IEEE80211_IBSS_JOINED || 1740 ifsta->state != IEEE80211_STA_MLME_IBSS_JOINED ||
2959 len < 24 + 2 || !ifsta->probe_resp) 1741 len < 24 + 2 || !ifsta->probe_resp)
2960 return; 1742 return;
2961 1743
@@ -2967,7 +1749,7 @@ static void ieee80211_rx_mgmt_probe_req(struct net_device *dev,
2967#ifdef CONFIG_MAC80211_IBSS_DEBUG 1749#ifdef CONFIG_MAC80211_IBSS_DEBUG
2968 printk(KERN_DEBUG "%s: RX ProbeReq SA=%s DA=%s BSSID=" 1750 printk(KERN_DEBUG "%s: RX ProbeReq SA=%s DA=%s BSSID="
2969 "%s (tx_last_beacon=%d)\n", 1751 "%s (tx_last_beacon=%d)\n",
2970 dev->name, print_mac(mac, mgmt->sa), print_mac(mac2, mgmt->da), 1752 sdata->dev->name, print_mac(mac, mgmt->sa), print_mac(mac2, mgmt->da),
2971 print_mac(mac3, mgmt->bssid), tx_last_beacon); 1753 print_mac(mac3, mgmt->bssid), tx_last_beacon);
2972#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 1754#endif /* CONFIG_MAC80211_IBSS_DEBUG */
2973 1755
@@ -2985,7 +1767,7 @@ static void ieee80211_rx_mgmt_probe_req(struct net_device *dev,
2985#ifdef CONFIG_MAC80211_IBSS_DEBUG 1767#ifdef CONFIG_MAC80211_IBSS_DEBUG
2986 printk(KERN_DEBUG "%s: Invalid SSID IE in ProbeReq " 1768 printk(KERN_DEBUG "%s: Invalid SSID IE in ProbeReq "
2987 "from %s\n", 1769 "from %s\n",
2988 dev->name, print_mac(mac, mgmt->sa)); 1770 sdata->dev->name, print_mac(mac, mgmt->sa));
2989#endif 1771#endif
2990 return; 1772 return;
2991 } 1773 }
@@ -3005,74 +1787,15 @@ static void ieee80211_rx_mgmt_probe_req(struct net_device *dev,
3005 memcpy(resp->da, mgmt->sa, ETH_ALEN); 1787 memcpy(resp->da, mgmt->sa, ETH_ALEN);
3006#ifdef CONFIG_MAC80211_IBSS_DEBUG 1788#ifdef CONFIG_MAC80211_IBSS_DEBUG
3007 printk(KERN_DEBUG "%s: Sending ProbeResp to %s\n", 1789 printk(KERN_DEBUG "%s: Sending ProbeResp to %s\n",
3008 dev->name, print_mac(mac, resp->da)); 1790 sdata->dev->name, print_mac(mac, resp->da));
3009#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 1791#endif /* CONFIG_MAC80211_IBSS_DEBUG */
3010 ieee80211_sta_tx(dev, skb, 0); 1792 ieee80211_tx_skb(sdata, skb, 0);
3011} 1793}
3012 1794
3013static void ieee80211_rx_mgmt_action(struct net_device *dev, 1795void ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
3014 struct ieee80211_if_sta *ifsta,
3015 struct ieee80211_mgmt *mgmt,
3016 size_t len,
3017 struct ieee80211_rx_status *rx_status)
3018{
3019 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3020 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
3021
3022 if (len < IEEE80211_MIN_ACTION_SIZE)
3023 return;
3024
3025 switch (mgmt->u.action.category) {
3026 case WLAN_CATEGORY_SPECTRUM_MGMT:
3027 if (local->hw.conf.channel->band != IEEE80211_BAND_5GHZ)
3028 break;
3029 switch (mgmt->u.action.u.chan_switch.action_code) {
3030 case WLAN_ACTION_SPCT_MSR_REQ:
3031 if (len < (IEEE80211_MIN_ACTION_SIZE +
3032 sizeof(mgmt->u.action.u.measurement)))
3033 break;
3034 ieee80211_sta_process_measurement_req(dev, mgmt, len);
3035 break;
3036 }
3037 break;
3038 case WLAN_CATEGORY_BACK:
3039 switch (mgmt->u.action.u.addba_req.action_code) {
3040 case WLAN_ACTION_ADDBA_REQ:
3041 if (len < (IEEE80211_MIN_ACTION_SIZE +
3042 sizeof(mgmt->u.action.u.addba_req)))
3043 break;
3044 ieee80211_sta_process_addba_request(dev, mgmt, len);
3045 break;
3046 case WLAN_ACTION_ADDBA_RESP:
3047 if (len < (IEEE80211_MIN_ACTION_SIZE +
3048 sizeof(mgmt->u.action.u.addba_resp)))
3049 break;
3050 ieee80211_sta_process_addba_resp(dev, mgmt, len);
3051 break;
3052 case WLAN_ACTION_DELBA:
3053 if (len < (IEEE80211_MIN_ACTION_SIZE +
3054 sizeof(mgmt->u.action.u.delba)))
3055 break;
3056 ieee80211_sta_process_delba(dev, mgmt, len);
3057 break;
3058 }
3059 break;
3060 case PLINK_CATEGORY:
3061 if (ieee80211_vif_is_mesh(&sdata->vif))
3062 mesh_rx_plink_frame(dev, mgmt, len, rx_status);
3063 break;
3064 case MESH_PATH_SEL_CATEGORY:
3065 if (ieee80211_vif_is_mesh(&sdata->vif))
3066 mesh_rx_path_sel_frame(dev, mgmt, len);
3067 break;
3068 }
3069}
3070
3071void ieee80211_sta_rx_mgmt(struct net_device *dev, struct sk_buff *skb,
3072 struct ieee80211_rx_status *rx_status) 1796 struct ieee80211_rx_status *rx_status)
3073{ 1797{
3074 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1798 struct ieee80211_local *local = sdata->local;
3075 struct ieee80211_sub_if_data *sdata;
3076 struct ieee80211_if_sta *ifsta; 1799 struct ieee80211_if_sta *ifsta;
3077 struct ieee80211_mgmt *mgmt; 1800 struct ieee80211_mgmt *mgmt;
3078 u16 fc; 1801 u16 fc;
@@ -3080,7 +1803,6 @@ void ieee80211_sta_rx_mgmt(struct net_device *dev, struct sk_buff *skb,
3080 if (skb->len < 24) 1803 if (skb->len < 24)
3081 goto fail; 1804 goto fail;
3082 1805
3083 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3084 ifsta = &sdata->u.sta; 1806 ifsta = &sdata->u.sta;
3085 1807
3086 mgmt = (struct ieee80211_mgmt *) skb->data; 1808 mgmt = (struct ieee80211_mgmt *) skb->data;
@@ -3090,7 +1812,6 @@ void ieee80211_sta_rx_mgmt(struct net_device *dev, struct sk_buff *skb,
3090 case IEEE80211_STYPE_PROBE_REQ: 1812 case IEEE80211_STYPE_PROBE_REQ:
3091 case IEEE80211_STYPE_PROBE_RESP: 1813 case IEEE80211_STYPE_PROBE_RESP:
3092 case IEEE80211_STYPE_BEACON: 1814 case IEEE80211_STYPE_BEACON:
3093 case IEEE80211_STYPE_ACTION:
3094 memcpy(skb->cb, rx_status, sizeof(*rx_status)); 1815 memcpy(skb->cb, rx_status, sizeof(*rx_status));
3095 case IEEE80211_STYPE_AUTH: 1816 case IEEE80211_STYPE_AUTH:
3096 case IEEE80211_STYPE_ASSOC_RESP: 1817 case IEEE80211_STYPE_ASSOC_RESP:
@@ -3106,17 +1827,14 @@ void ieee80211_sta_rx_mgmt(struct net_device *dev, struct sk_buff *skb,
3106 kfree_skb(skb); 1827 kfree_skb(skb);
3107} 1828}
3108 1829
3109 1830static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
3110static void ieee80211_sta_rx_queued_mgmt(struct net_device *dev,
3111 struct sk_buff *skb) 1831 struct sk_buff *skb)
3112{ 1832{
3113 struct ieee80211_rx_status *rx_status; 1833 struct ieee80211_rx_status *rx_status;
3114 struct ieee80211_sub_if_data *sdata;
3115 struct ieee80211_if_sta *ifsta; 1834 struct ieee80211_if_sta *ifsta;
3116 struct ieee80211_mgmt *mgmt; 1835 struct ieee80211_mgmt *mgmt;
3117 u16 fc; 1836 u16 fc;
3118 1837
3119 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3120 ifsta = &sdata->u.sta; 1838 ifsta = &sdata->u.sta;
3121 1839
3122 rx_status = (struct ieee80211_rx_status *) skb->cb; 1840 rx_status = (struct ieee80211_rx_status *) skb->cb;
@@ -3125,17 +1843,17 @@ static void ieee80211_sta_rx_queued_mgmt(struct net_device *dev,
3125 1843
3126 switch (fc & IEEE80211_FCTL_STYPE) { 1844 switch (fc & IEEE80211_FCTL_STYPE) {
3127 case IEEE80211_STYPE_PROBE_REQ: 1845 case IEEE80211_STYPE_PROBE_REQ:
3128 ieee80211_rx_mgmt_probe_req(dev, ifsta, mgmt, skb->len, 1846 ieee80211_rx_mgmt_probe_req(sdata, ifsta, mgmt, skb->len,
3129 rx_status); 1847 rx_status);
3130 break; 1848 break;
3131 case IEEE80211_STYPE_PROBE_RESP: 1849 case IEEE80211_STYPE_PROBE_RESP:
3132 ieee80211_rx_mgmt_probe_resp(dev, mgmt, skb->len, rx_status); 1850 ieee80211_rx_mgmt_probe_resp(sdata, mgmt, skb->len, rx_status);
3133 break; 1851 break;
3134 case IEEE80211_STYPE_BEACON: 1852 case IEEE80211_STYPE_BEACON:
3135 ieee80211_rx_mgmt_beacon(dev, mgmt, skb->len, rx_status); 1853 ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len, rx_status);
3136 break; 1854 break;
3137 case IEEE80211_STYPE_AUTH: 1855 case IEEE80211_STYPE_AUTH:
3138 ieee80211_rx_mgmt_auth(dev, ifsta, mgmt, skb->len); 1856 ieee80211_rx_mgmt_auth(sdata, ifsta, mgmt, skb->len);
3139 break; 1857 break;
3140 case IEEE80211_STYPE_ASSOC_RESP: 1858 case IEEE80211_STYPE_ASSOC_RESP:
3141 ieee80211_rx_mgmt_assoc_resp(sdata, ifsta, mgmt, skb->len, 0); 1859 ieee80211_rx_mgmt_assoc_resp(sdata, ifsta, mgmt, skb->len, 0);
@@ -3144,13 +1862,10 @@ static void ieee80211_sta_rx_queued_mgmt(struct net_device *dev,
3144 ieee80211_rx_mgmt_assoc_resp(sdata, ifsta, mgmt, skb->len, 1); 1862 ieee80211_rx_mgmt_assoc_resp(sdata, ifsta, mgmt, skb->len, 1);
3145 break; 1863 break;
3146 case IEEE80211_STYPE_DEAUTH: 1864 case IEEE80211_STYPE_DEAUTH:
3147 ieee80211_rx_mgmt_deauth(dev, ifsta, mgmt, skb->len); 1865 ieee80211_rx_mgmt_deauth(sdata, ifsta, mgmt, skb->len);
3148 break; 1866 break;
3149 case IEEE80211_STYPE_DISASSOC: 1867 case IEEE80211_STYPE_DISASSOC:
3150 ieee80211_rx_mgmt_disassoc(dev, ifsta, mgmt, skb->len); 1868 ieee80211_rx_mgmt_disassoc(sdata, ifsta, mgmt, skb->len);
3151 break;
3152 case IEEE80211_STYPE_ACTION:
3153 ieee80211_rx_mgmt_action(dev, ifsta, mgmt, skb->len, rx_status);
3154 break; 1869 break;
3155 } 1870 }
3156 1871
@@ -3158,47 +1873,11 @@ static void ieee80211_sta_rx_queued_mgmt(struct net_device *dev,
3158} 1873}
3159 1874
3160 1875
3161ieee80211_rx_result 1876static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata)
3162ieee80211_sta_rx_scan(struct net_device *dev, struct sk_buff *skb,
3163 struct ieee80211_rx_status *rx_status)
3164{
3165 struct ieee80211_mgmt *mgmt;
3166 __le16 fc;
3167
3168 if (skb->len < 2)
3169 return RX_DROP_UNUSABLE;
3170
3171 mgmt = (struct ieee80211_mgmt *) skb->data;
3172 fc = mgmt->frame_control;
3173
3174 if (ieee80211_is_ctl(fc))
3175 return RX_CONTINUE;
3176
3177 if (skb->len < 24)
3178 return RX_DROP_MONITOR;
3179
3180 if (ieee80211_is_probe_resp(fc)) {
3181 ieee80211_rx_mgmt_probe_resp(dev, mgmt, skb->len, rx_status);
3182 dev_kfree_skb(skb);
3183 return RX_QUEUED;
3184 }
3185
3186 if (ieee80211_is_beacon(fc)) {
3187 ieee80211_rx_mgmt_beacon(dev, mgmt, skb->len, rx_status);
3188 dev_kfree_skb(skb);
3189 return RX_QUEUED;
3190 }
3191
3192 return RX_CONTINUE;
3193}
3194
3195
3196static int ieee80211_sta_active_ibss(struct net_device *dev)
3197{ 1877{
3198 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1878 struct ieee80211_local *local = sdata->local;
3199 int active = 0; 1879 int active = 0;
3200 struct sta_info *sta; 1880 struct sta_info *sta;
3201 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3202 1881
3203 rcu_read_lock(); 1882 rcu_read_lock();
3204 1883
@@ -3217,179 +1896,36 @@ static int ieee80211_sta_active_ibss(struct net_device *dev)
3217} 1896}
3218 1897
3219 1898
3220static void ieee80211_sta_expire(struct net_device *dev, unsigned long exp_time) 1899static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata,
3221{
3222 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
3223 struct sta_info *sta, *tmp;
3224 LIST_HEAD(tmp_list);
3225 DECLARE_MAC_BUF(mac);
3226 unsigned long flags;
3227
3228 spin_lock_irqsave(&local->sta_lock, flags);
3229 list_for_each_entry_safe(sta, tmp, &local->sta_list, list)
3230 if (time_after(jiffies, sta->last_rx + exp_time)) {
3231#ifdef CONFIG_MAC80211_IBSS_DEBUG
3232 printk(KERN_DEBUG "%s: expiring inactive STA %s\n",
3233 dev->name, print_mac(mac, sta->addr));
3234#endif
3235 __sta_info_unlink(&sta);
3236 if (sta)
3237 list_add(&sta->list, &tmp_list);
3238 }
3239 spin_unlock_irqrestore(&local->sta_lock, flags);
3240
3241 list_for_each_entry_safe(sta, tmp, &tmp_list, list)
3242 sta_info_destroy(sta);
3243}
3244
3245
3246static void ieee80211_sta_merge_ibss(struct net_device *dev,
3247 struct ieee80211_if_sta *ifsta) 1900 struct ieee80211_if_sta *ifsta)
3248{ 1901{
3249 mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); 1902 mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL);
3250 1903
3251 ieee80211_sta_expire(dev, IEEE80211_IBSS_INACTIVITY_LIMIT); 1904 ieee80211_sta_expire(sdata, IEEE80211_IBSS_INACTIVITY_LIMIT);
3252 if (ieee80211_sta_active_ibss(dev)) 1905 if (ieee80211_sta_active_ibss(sdata))
3253 return; 1906 return;
3254 1907
3255 printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other " 1908 printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other "
3256 "IBSS networks with same SSID (merge)\n", dev->name); 1909 "IBSS networks with same SSID (merge)\n", sdata->dev->name);
3257 ieee80211_sta_req_scan(dev, ifsta->ssid, ifsta->ssid_len); 1910 ieee80211_request_scan(sdata, ifsta->ssid, ifsta->ssid_len);
3258} 1911}
3259 1912
3260 1913
3261#ifdef CONFIG_MAC80211_MESH 1914static void ieee80211_sta_timer(unsigned long data)
3262static void ieee80211_mesh_housekeeping(struct net_device *dev,
3263 struct ieee80211_if_sta *ifsta)
3264{
3265 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3266 bool free_plinks;
3267
3268 ieee80211_sta_expire(dev, IEEE80211_MESH_PEER_INACTIVITY_LIMIT);
3269 mesh_path_expire(dev);
3270
3271 free_plinks = mesh_plink_availables(sdata);
3272 if (free_plinks != sdata->u.sta.accepting_plinks)
3273 ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
3274
3275 mod_timer(&ifsta->timer, jiffies +
3276 IEEE80211_MESH_HOUSEKEEPING_INTERVAL);
3277}
3278
3279
3280void ieee80211_start_mesh(struct net_device *dev)
3281{
3282 struct ieee80211_if_sta *ifsta;
3283 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3284 ifsta = &sdata->u.sta;
3285 ifsta->state = IEEE80211_MESH_UP;
3286 ieee80211_sta_timer((unsigned long)sdata);
3287 ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
3288}
3289#endif
3290
3291
3292void ieee80211_sta_timer(unsigned long data)
3293{ 1915{
3294 struct ieee80211_sub_if_data *sdata = 1916 struct ieee80211_sub_if_data *sdata =
3295 (struct ieee80211_sub_if_data *) data; 1917 (struct ieee80211_sub_if_data *) data;
3296 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 1918 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
3297 struct ieee80211_local *local = wdev_priv(&sdata->wdev); 1919 struct ieee80211_local *local = sdata->local;
3298 1920
3299 set_bit(IEEE80211_STA_REQ_RUN, &ifsta->request); 1921 set_bit(IEEE80211_STA_REQ_RUN, &ifsta->request);
3300 queue_work(local->hw.workqueue, &ifsta->work); 1922 queue_work(local->hw.workqueue, &ifsta->work);
3301} 1923}
3302 1924
3303void ieee80211_sta_work(struct work_struct *work) 1925static void ieee80211_sta_reset_auth(struct ieee80211_sub_if_data *sdata,
3304{
3305 struct ieee80211_sub_if_data *sdata =
3306 container_of(work, struct ieee80211_sub_if_data, u.sta.work);
3307 struct net_device *dev = sdata->dev;
3308 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
3309 struct ieee80211_if_sta *ifsta;
3310 struct sk_buff *skb;
3311
3312 if (!netif_running(dev))
3313 return;
3314
3315 if (local->sta_sw_scanning || local->sta_hw_scanning)
3316 return;
3317
3318 if (WARN_ON(sdata->vif.type != IEEE80211_IF_TYPE_STA &&
3319 sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
3320 sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT))
3321 return;
3322 ifsta = &sdata->u.sta;
3323
3324 while ((skb = skb_dequeue(&ifsta->skb_queue)))
3325 ieee80211_sta_rx_queued_mgmt(dev, skb);
3326
3327#ifdef CONFIG_MAC80211_MESH
3328 if (ifsta->preq_queue_len &&
3329 time_after(jiffies,
3330 ifsta->last_preq + msecs_to_jiffies(ifsta->mshcfg.dot11MeshHWMPpreqMinInterval)))
3331 mesh_path_start_discovery(dev);
3332#endif
3333
3334 if (ifsta->state != IEEE80211_AUTHENTICATE &&
3335 ifsta->state != IEEE80211_ASSOCIATE &&
3336 test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request)) {
3337 if (ifsta->scan_ssid_len)
3338 ieee80211_sta_start_scan(dev, ifsta->scan_ssid, ifsta->scan_ssid_len);
3339 else
3340 ieee80211_sta_start_scan(dev, NULL, 0);
3341 return;
3342 }
3343
3344 if (test_and_clear_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request)) {
3345 if (ieee80211_sta_config_auth(dev, ifsta))
3346 return;
3347 clear_bit(IEEE80211_STA_REQ_RUN, &ifsta->request);
3348 } else if (!test_and_clear_bit(IEEE80211_STA_REQ_RUN, &ifsta->request))
3349 return;
3350
3351 switch (ifsta->state) {
3352 case IEEE80211_DISABLED:
3353 break;
3354 case IEEE80211_AUTHENTICATE:
3355 ieee80211_authenticate(dev, ifsta);
3356 break;
3357 case IEEE80211_ASSOCIATE:
3358 ieee80211_associate(dev, ifsta);
3359 break;
3360 case IEEE80211_ASSOCIATED:
3361 ieee80211_associated(dev, ifsta);
3362 break;
3363 case IEEE80211_IBSS_SEARCH:
3364 ieee80211_sta_find_ibss(dev, ifsta);
3365 break;
3366 case IEEE80211_IBSS_JOINED:
3367 ieee80211_sta_merge_ibss(dev, ifsta);
3368 break;
3369#ifdef CONFIG_MAC80211_MESH
3370 case IEEE80211_MESH_UP:
3371 ieee80211_mesh_housekeeping(dev, ifsta);
3372 break;
3373#endif
3374 default:
3375 WARN_ON(1);
3376 break;
3377 }
3378
3379 if (ieee80211_privacy_mismatch(dev, ifsta)) {
3380 printk(KERN_DEBUG "%s: privacy configuration mismatch and "
3381 "mixed-cell disabled - disassociate\n", dev->name);
3382
3383 ieee80211_send_disassoc(dev, ifsta, WLAN_REASON_UNSPECIFIED);
3384 ieee80211_set_disassoc(dev, ifsta, 0);
3385 }
3386}
3387
3388
3389static void ieee80211_sta_reset_auth(struct net_device *dev,
3390 struct ieee80211_if_sta *ifsta) 1926 struct ieee80211_if_sta *ifsta)
3391{ 1927{
3392 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1928 struct ieee80211_local *local = sdata->local;
3393 1929
3394 if (local->ops->reset_tsf) { 1930 if (local->ops->reset_tsf) {
3395 /* Reset own TSF to allow time synchronization work. */ 1931 /* Reset own TSF to allow time synchronization work. */
@@ -3409,29 +1945,15 @@ static void ieee80211_sta_reset_auth(struct net_device *dev,
3409 ifsta->auth_alg = WLAN_AUTH_OPEN; 1945 ifsta->auth_alg = WLAN_AUTH_OPEN;
3410 ifsta->auth_transaction = -1; 1946 ifsta->auth_transaction = -1;
3411 ifsta->flags &= ~IEEE80211_STA_ASSOCIATED; 1947 ifsta->flags &= ~IEEE80211_STA_ASSOCIATED;
3412 ifsta->auth_tries = ifsta->assoc_tries = 0; 1948 ifsta->assoc_scan_tries = 0;
3413 netif_carrier_off(dev); 1949 ifsta->direct_probe_tries = 0;
1950 ifsta->auth_tries = 0;
1951 ifsta->assoc_tries = 0;
1952 netif_tx_stop_all_queues(sdata->dev);
1953 netif_carrier_off(sdata->dev);
3414} 1954}
3415 1955
3416 1956
3417void ieee80211_sta_req_auth(struct net_device *dev,
3418 struct ieee80211_if_sta *ifsta)
3419{
3420 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
3421 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3422
3423 if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
3424 return;
3425
3426 if ((ifsta->flags & (IEEE80211_STA_BSSID_SET |
3427 IEEE80211_STA_AUTO_BSSID_SEL)) &&
3428 (ifsta->flags & (IEEE80211_STA_SSID_SET |
3429 IEEE80211_STA_AUTO_SSID_SEL))) {
3430 set_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request);
3431 queue_work(local->hw.workqueue, &ifsta->work);
3432 }
3433}
3434
3435static int ieee80211_sta_match_ssid(struct ieee80211_if_sta *ifsta, 1957static int ieee80211_sta_match_ssid(struct ieee80211_if_sta *ifsta,
3436 const char *ssid, int ssid_len) 1958 const char *ssid, int ssid_len)
3437{ 1959{
@@ -3462,81 +1984,11 @@ static int ieee80211_sta_match_ssid(struct ieee80211_if_sta *ifsta,
3462 return 0; 1984 return 0;
3463} 1985}
3464 1986
3465static int ieee80211_sta_config_auth(struct net_device *dev, 1987static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata,
3466 struct ieee80211_if_sta *ifsta)
3467{
3468 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
3469 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3470 struct ieee80211_sta_bss *bss, *selected = NULL;
3471 int top_rssi = 0, freq;
3472
3473 spin_lock_bh(&local->sta_bss_lock);
3474 freq = local->oper_channel->center_freq;
3475 list_for_each_entry(bss, &local->sta_bss_list, list) {
3476 if (!(bss->capability & WLAN_CAPABILITY_ESS))
3477 continue;
3478
3479 if ((ifsta->flags & (IEEE80211_STA_AUTO_SSID_SEL |
3480 IEEE80211_STA_AUTO_BSSID_SEL |
3481 IEEE80211_STA_AUTO_CHANNEL_SEL)) &&
3482 (!!(bss->capability & WLAN_CAPABILITY_PRIVACY) ^
3483 !!sdata->default_key))
3484 continue;
3485
3486 if (!(ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL) &&
3487 bss->freq != freq)
3488 continue;
3489
3490 if (!(ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL) &&
3491 memcmp(bss->bssid, ifsta->bssid, ETH_ALEN))
3492 continue;
3493
3494 if (!(ifsta->flags & IEEE80211_STA_AUTO_SSID_SEL) &&
3495 !ieee80211_sta_match_ssid(ifsta, bss->ssid, bss->ssid_len))
3496 continue;
3497
3498 if (!selected || top_rssi < bss->signal) {
3499 selected = bss;
3500 top_rssi = bss->signal;
3501 }
3502 }
3503 if (selected)
3504 atomic_inc(&selected->users);
3505 spin_unlock_bh(&local->sta_bss_lock);
3506
3507 if (selected) {
3508 ieee80211_set_freq(dev, selected->freq);
3509 if (!(ifsta->flags & IEEE80211_STA_SSID_SET))
3510 ieee80211_sta_set_ssid(dev, selected->ssid,
3511 selected->ssid_len);
3512 ieee80211_sta_set_bssid(dev, selected->bssid);
3513 ieee80211_sta_def_wmm_params(dev, selected, 0);
3514 ieee80211_rx_bss_put(local, selected);
3515 ifsta->state = IEEE80211_AUTHENTICATE;
3516 ieee80211_sta_reset_auth(dev, ifsta);
3517 return 0;
3518 } else {
3519 if (ifsta->state != IEEE80211_AUTHENTICATE) {
3520 if (ifsta->flags & IEEE80211_STA_AUTO_SSID_SEL)
3521 ieee80211_sta_start_scan(dev, NULL, 0);
3522 else
3523 ieee80211_sta_start_scan(dev, ifsta->ssid,
3524 ifsta->ssid_len);
3525 ifsta->state = IEEE80211_AUTHENTICATE;
3526 set_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request);
3527 } else
3528 ifsta->state = IEEE80211_DISABLED;
3529 }
3530 return -1;
3531}
3532
3533
3534static int ieee80211_sta_create_ibss(struct net_device *dev,
3535 struct ieee80211_if_sta *ifsta) 1988 struct ieee80211_if_sta *ifsta)
3536{ 1989{
3537 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1990 struct ieee80211_local *local = sdata->local;
3538 struct ieee80211_sta_bss *bss; 1991 struct ieee80211_bss *bss;
3539 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3540 struct ieee80211_supported_band *sband; 1992 struct ieee80211_supported_band *sband;
3541 u8 bssid[ETH_ALEN], *pos; 1993 u8 bssid[ETH_ALEN], *pos;
3542 int i; 1994 int i;
@@ -3552,15 +2004,15 @@ static int ieee80211_sta_create_ibss(struct net_device *dev,
3552 * random number generator get different BSSID. */ 2004 * random number generator get different BSSID. */
3553 get_random_bytes(bssid, ETH_ALEN); 2005 get_random_bytes(bssid, ETH_ALEN);
3554 for (i = 0; i < ETH_ALEN; i++) 2006 for (i = 0; i < ETH_ALEN; i++)
3555 bssid[i] ^= dev->dev_addr[i]; 2007 bssid[i] ^= sdata->dev->dev_addr[i];
3556 bssid[0] &= ~0x01; 2008 bssid[0] &= ~0x01;
3557 bssid[0] |= 0x02; 2009 bssid[0] |= 0x02;
3558#endif 2010#endif
3559 2011
3560 printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n", 2012 printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n",
3561 dev->name, print_mac(mac, bssid)); 2013 sdata->dev->name, print_mac(mac, bssid));
3562 2014
3563 bss = ieee80211_rx_bss_add(dev, bssid, 2015 bss = ieee80211_rx_bss_add(local, bssid,
3564 local->hw.conf.channel->center_freq, 2016 local->hw.conf.channel->center_freq,
3565 sdata->u.sta.ssid, sdata->u.sta.ssid_len); 2017 sdata->u.sta.ssid, sdata->u.sta.ssid_len);
3566 if (!bss) 2018 if (!bss)
@@ -3587,17 +2039,17 @@ static int ieee80211_sta_create_ibss(struct net_device *dev,
3587 *pos++ = (u8) (rate / 5); 2039 *pos++ = (u8) (rate / 5);
3588 } 2040 }
3589 2041
3590 ret = ieee80211_sta_join_ibss(dev, ifsta, bss); 2042 ret = ieee80211_sta_join_ibss(sdata, ifsta, bss);
3591 ieee80211_rx_bss_put(local, bss); 2043 ieee80211_rx_bss_put(local, bss);
3592 return ret; 2044 return ret;
3593} 2045}
3594 2046
3595 2047
3596static int ieee80211_sta_find_ibss(struct net_device *dev, 2048static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata,
3597 struct ieee80211_if_sta *ifsta) 2049 struct ieee80211_if_sta *ifsta)
3598{ 2050{
3599 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 2051 struct ieee80211_local *local = sdata->local;
3600 struct ieee80211_sta_bss *bss; 2052 struct ieee80211_bss *bss;
3601 int found = 0; 2053 int found = 0;
3602 u8 bssid[ETH_ALEN]; 2054 u8 bssid[ETH_ALEN];
3603 int active_ibss; 2055 int active_ibss;
@@ -3607,13 +2059,13 @@ static int ieee80211_sta_find_ibss(struct net_device *dev,
3607 if (ifsta->ssid_len == 0) 2059 if (ifsta->ssid_len == 0)
3608 return -EINVAL; 2060 return -EINVAL;
3609 2061
3610 active_ibss = ieee80211_sta_active_ibss(dev); 2062 active_ibss = ieee80211_sta_active_ibss(sdata);
3611#ifdef CONFIG_MAC80211_IBSS_DEBUG 2063#ifdef CONFIG_MAC80211_IBSS_DEBUG
3612 printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n", 2064 printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n",
3613 dev->name, active_ibss); 2065 sdata->dev->name, active_ibss);
3614#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 2066#endif /* CONFIG_MAC80211_IBSS_DEBUG */
3615 spin_lock_bh(&local->sta_bss_lock); 2067 spin_lock_bh(&local->bss_lock);
3616 list_for_each_entry(bss, &local->sta_bss_list, list) { 2068 list_for_each_entry(bss, &local->bss_list, list) {
3617 if (ifsta->ssid_len != bss->ssid_len || 2069 if (ifsta->ssid_len != bss->ssid_len ||
3618 memcmp(ifsta->ssid, bss->ssid, bss->ssid_len) != 0 2070 memcmp(ifsta->ssid, bss->ssid, bss->ssid_len) != 0
3619 || !(bss->capability & WLAN_CAPABILITY_IBSS)) 2071 || !(bss->capability & WLAN_CAPABILITY_IBSS))
@@ -3627,7 +2079,7 @@ static int ieee80211_sta_find_ibss(struct net_device *dev,
3627 if (active_ibss || memcmp(bssid, ifsta->bssid, ETH_ALEN) != 0) 2079 if (active_ibss || memcmp(bssid, ifsta->bssid, ETH_ALEN) != 0)
3628 break; 2080 break;
3629 } 2081 }
3630 spin_unlock_bh(&local->sta_bss_lock); 2082 spin_unlock_bh(&local->bss_lock);
3631 2083
3632#ifdef CONFIG_MAC80211_IBSS_DEBUG 2084#ifdef CONFIG_MAC80211_IBSS_DEBUG
3633 if (found) 2085 if (found)
@@ -3645,15 +2097,15 @@ static int ieee80211_sta_find_ibss(struct net_device *dev,
3645 else 2097 else
3646 search_freq = local->hw.conf.channel->center_freq; 2098 search_freq = local->hw.conf.channel->center_freq;
3647 2099
3648 bss = ieee80211_rx_bss_get(dev, bssid, search_freq, 2100 bss = ieee80211_rx_bss_get(local, bssid, search_freq,
3649 ifsta->ssid, ifsta->ssid_len); 2101 ifsta->ssid, ifsta->ssid_len);
3650 if (!bss) 2102 if (!bss)
3651 goto dont_join; 2103 goto dont_join;
3652 2104
3653 printk(KERN_DEBUG "%s: Selected IBSS BSSID %s" 2105 printk(KERN_DEBUG "%s: Selected IBSS BSSID %s"
3654 " based on configured SSID\n", 2106 " based on configured SSID\n",
3655 dev->name, print_mac(mac, bssid)); 2107 sdata->dev->name, print_mac(mac, bssid));
3656 ret = ieee80211_sta_join_ibss(dev, ifsta, bss); 2108 ret = ieee80211_sta_join_ibss(sdata, ifsta, bss);
3657 ieee80211_rx_bss_put(local, bss); 2109 ieee80211_rx_bss_put(local, bss);
3658 return ret; 2110 return ret;
3659 } 2111 }
@@ -3664,17 +2116,17 @@ dont_join:
3664#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 2116#endif /* CONFIG_MAC80211_IBSS_DEBUG */
3665 2117
3666 /* Selected IBSS not found in current scan results - try to scan */ 2118 /* Selected IBSS not found in current scan results - try to scan */
3667 if (ifsta->state == IEEE80211_IBSS_JOINED && 2119 if (ifsta->state == IEEE80211_STA_MLME_IBSS_JOINED &&
3668 !ieee80211_sta_active_ibss(dev)) { 2120 !ieee80211_sta_active_ibss(sdata)) {
3669 mod_timer(&ifsta->timer, jiffies + 2121 mod_timer(&ifsta->timer, jiffies +
3670 IEEE80211_IBSS_MERGE_INTERVAL); 2122 IEEE80211_IBSS_MERGE_INTERVAL);
3671 } else if (time_after(jiffies, local->last_scan_completed + 2123 } else if (time_after(jiffies, local->last_scan_completed +
3672 IEEE80211_SCAN_INTERVAL)) { 2124 IEEE80211_SCAN_INTERVAL)) {
3673 printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to " 2125 printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to "
3674 "join\n", dev->name); 2126 "join\n", sdata->dev->name);
3675 return ieee80211_sta_req_scan(dev, ifsta->ssid, 2127 return ieee80211_request_scan(sdata, ifsta->ssid,
3676 ifsta->ssid_len); 2128 ifsta->ssid_len);
3677 } else if (ifsta->state != IEEE80211_IBSS_JOINED) { 2129 } else if (ifsta->state != IEEE80211_STA_MLME_IBSS_JOINED) {
3678 int interval = IEEE80211_SCAN_INTERVAL; 2130 int interval = IEEE80211_SCAN_INTERVAL;
3679 2131
3680 if (time_after(jiffies, ifsta->ibss_join_req + 2132 if (time_after(jiffies, ifsta->ibss_join_req +
@@ -3682,10 +2134,10 @@ dont_join:
3682 if ((ifsta->flags & IEEE80211_STA_CREATE_IBSS) && 2134 if ((ifsta->flags & IEEE80211_STA_CREATE_IBSS) &&
3683 (!(local->oper_channel->flags & 2135 (!(local->oper_channel->flags &
3684 IEEE80211_CHAN_NO_IBSS))) 2136 IEEE80211_CHAN_NO_IBSS)))
3685 return ieee80211_sta_create_ibss(dev, ifsta); 2137 return ieee80211_sta_create_ibss(sdata, ifsta);
3686 if (ifsta->flags & IEEE80211_STA_CREATE_IBSS) { 2138 if (ifsta->flags & IEEE80211_STA_CREATE_IBSS) {
3687 printk(KERN_DEBUG "%s: IBSS not allowed on" 2139 printk(KERN_DEBUG "%s: IBSS not allowed on"
3688 " %d MHz\n", dev->name, 2140 " %d MHz\n", sdata->dev->name,
3689 local->hw.conf.channel->center_freq); 2141 local->hw.conf.channel->center_freq);
3690 } 2142 }
3691 2143
@@ -3694,7 +2146,7 @@ dont_join:
3694 interval = IEEE80211_SCAN_INTERVAL_SLOW; 2146 interval = IEEE80211_SCAN_INTERVAL_SLOW;
3695 } 2147 }
3696 2148
3697 ifsta->state = IEEE80211_IBSS_SEARCH; 2149 ifsta->state = IEEE80211_STA_MLME_IBSS_SEARCH;
3698 mod_timer(&ifsta->timer, jiffies + interval); 2150 mod_timer(&ifsta->timer, jiffies + interval);
3699 return 0; 2151 return 0;
3700 } 2152 }
@@ -3703,620 +2155,344 @@ dont_join:
3703} 2155}
3704 2156
3705 2157
3706int ieee80211_sta_set_ssid(struct net_device *dev, char *ssid, size_t len) 2158static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata,
2159 struct ieee80211_if_sta *ifsta)
3707{ 2160{
3708 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 2161 struct ieee80211_local *local = sdata->local;
3709 struct ieee80211_if_sta *ifsta; 2162 struct ieee80211_bss *bss, *selected = NULL;
3710 int res; 2163 int top_rssi = 0, freq;
3711 2164
3712 if (len > IEEE80211_MAX_SSID_LEN) 2165 spin_lock_bh(&local->bss_lock);
3713 return -EINVAL; 2166 freq = local->oper_channel->center_freq;
2167 list_for_each_entry(bss, &local->bss_list, list) {
2168 if (!(bss->capability & WLAN_CAPABILITY_ESS))
2169 continue;
3714 2170
3715 ifsta = &sdata->u.sta; 2171 if ((ifsta->flags & (IEEE80211_STA_AUTO_SSID_SEL |
2172 IEEE80211_STA_AUTO_BSSID_SEL |
2173 IEEE80211_STA_AUTO_CHANNEL_SEL)) &&
2174 (!!(bss->capability & WLAN_CAPABILITY_PRIVACY) ^
2175 !!sdata->default_key))
2176 continue;
3716 2177
3717 if (ifsta->ssid_len != len || memcmp(ifsta->ssid, ssid, len) != 0) { 2178 if (!(ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL) &&
3718 memset(ifsta->ssid, 0, sizeof(ifsta->ssid)); 2179 bss->freq != freq)
3719 memcpy(ifsta->ssid, ssid, len); 2180 continue;
3720 ifsta->ssid_len = len;
3721 ifsta->flags &= ~IEEE80211_STA_PREV_BSSID_SET;
3722 2181
3723 res = 0; 2182 if (!(ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL) &&
3724 /* 2183 memcmp(bss->bssid, ifsta->bssid, ETH_ALEN))
3725 * Hack! MLME code needs to be cleaned up to have different 2184 continue;
3726 * entry points for configuration and internal selection change
3727 */
3728 if (netif_running(sdata->dev))
3729 res = ieee80211_if_config(sdata, IEEE80211_IFCC_SSID);
3730 if (res) {
3731 printk(KERN_DEBUG "%s: Failed to config new SSID to "
3732 "the low-level driver\n", dev->name);
3733 return res;
3734 }
3735 }
3736 2185
3737 if (len) 2186 if (!(ifsta->flags & IEEE80211_STA_AUTO_SSID_SEL) &&
3738 ifsta->flags |= IEEE80211_STA_SSID_SET; 2187 !ieee80211_sta_match_ssid(ifsta, bss->ssid, bss->ssid_len))
3739 else 2188 continue;
3740 ifsta->flags &= ~IEEE80211_STA_SSID_SET;
3741 2189
3742 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && 2190 if (!selected || top_rssi < bss->signal) {
3743 !(ifsta->flags & IEEE80211_STA_BSSID_SET)) { 2191 selected = bss;
3744 ifsta->ibss_join_req = jiffies; 2192 top_rssi = bss->signal;
3745 ifsta->state = IEEE80211_IBSS_SEARCH; 2193 }
3746 return ieee80211_sta_find_ibss(dev, ifsta);
3747 } 2194 }
2195 if (selected)
2196 atomic_inc(&selected->users);
2197 spin_unlock_bh(&local->bss_lock);
3748 2198
3749 return 0; 2199 if (selected) {
3750} 2200 ieee80211_set_freq(sdata, selected->freq);
2201 if (!(ifsta->flags & IEEE80211_STA_SSID_SET))
2202 ieee80211_sta_set_ssid(sdata, selected->ssid,
2203 selected->ssid_len);
2204 ieee80211_sta_set_bssid(sdata, selected->bssid);
2205 ieee80211_sta_def_wmm_params(sdata, selected);
3751 2206
2207 /* Send out direct probe if no probe resp was received or
2208 * the one we have is outdated
2209 */
2210 if (!selected->last_probe_resp ||
2211 time_after(jiffies, selected->last_probe_resp
2212 + IEEE80211_SCAN_RESULT_EXPIRE))
2213 ifsta->state = IEEE80211_STA_MLME_DIRECT_PROBE;
2214 else
2215 ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE;
3752 2216
3753int ieee80211_sta_get_ssid(struct net_device *dev, char *ssid, size_t *len) 2217 ieee80211_rx_bss_put(local, selected);
3754{ 2218 ieee80211_sta_reset_auth(sdata, ifsta);
3755 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 2219 return 0;
3756 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 2220 } else {
3757 memcpy(ssid, ifsta->ssid, ifsta->ssid_len); 2221 if (ifsta->assoc_scan_tries < IEEE80211_ASSOC_SCANS_MAX_TRIES) {
3758 *len = ifsta->ssid_len; 2222 ifsta->assoc_scan_tries++;
3759 return 0; 2223 if (ifsta->flags & IEEE80211_STA_AUTO_SSID_SEL)
2224 ieee80211_start_scan(sdata, NULL, 0);
2225 else
2226 ieee80211_start_scan(sdata, ifsta->ssid,
2227 ifsta->ssid_len);
2228 ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE;
2229 set_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request);
2230 } else
2231 ifsta->state = IEEE80211_STA_MLME_DISABLED;
2232 }
2233 return -1;
3760} 2234}
3761 2235
3762 2236
3763int ieee80211_sta_set_bssid(struct net_device *dev, u8 *bssid) 2237static void ieee80211_sta_work(struct work_struct *work)
3764{ 2238{
3765 struct ieee80211_sub_if_data *sdata; 2239 struct ieee80211_sub_if_data *sdata =
2240 container_of(work, struct ieee80211_sub_if_data, u.sta.work);
2241 struct ieee80211_local *local = sdata->local;
3766 struct ieee80211_if_sta *ifsta; 2242 struct ieee80211_if_sta *ifsta;
3767 int res; 2243 struct sk_buff *skb;
3768
3769 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3770 ifsta = &sdata->u.sta;
3771 2244
3772 if (memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) { 2245 if (!netif_running(sdata->dev))
3773 memcpy(ifsta->bssid, bssid, ETH_ALEN); 2246 return;
3774 res = 0;
3775 /*
3776 * Hack! See also ieee80211_sta_set_ssid.
3777 */
3778 if (netif_running(sdata->dev))
3779 res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
3780 if (res) {
3781 printk(KERN_DEBUG "%s: Failed to config new BSSID to "
3782 "the low-level driver\n", dev->name);
3783 return res;
3784 }
3785 }
3786 2247
3787 if (is_valid_ether_addr(bssid)) 2248 if (local->sw_scanning || local->hw_scanning)
3788 ifsta->flags |= IEEE80211_STA_BSSID_SET; 2249 return;
3789 else
3790 ifsta->flags &= ~IEEE80211_STA_BSSID_SET;
3791 2250
3792 return 0; 2251 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION &&
3793} 2252 sdata->vif.type != NL80211_IFTYPE_ADHOC))
2253 return;
2254 ifsta = &sdata->u.sta;
3794 2255
2256 while ((skb = skb_dequeue(&ifsta->skb_queue)))
2257 ieee80211_sta_rx_queued_mgmt(sdata, skb);
3795 2258
3796static void ieee80211_send_nullfunc(struct ieee80211_local *local, 2259 if (ifsta->state != IEEE80211_STA_MLME_DIRECT_PROBE &&
3797 struct ieee80211_sub_if_data *sdata, 2260 ifsta->state != IEEE80211_STA_MLME_AUTHENTICATE &&
3798 int powersave) 2261 ifsta->state != IEEE80211_STA_MLME_ASSOCIATE &&
3799{ 2262 test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request)) {
3800 struct sk_buff *skb; 2263 ieee80211_start_scan(sdata, ifsta->scan_ssid,
3801 struct ieee80211_hdr *nullfunc; 2264 ifsta->scan_ssid_len);
3802 __le16 fc; 2265 return;
2266 }
3803 2267
3804 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24); 2268 if (test_and_clear_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request)) {
3805 if (!skb) { 2269 if (ieee80211_sta_config_auth(sdata, ifsta))
3806 printk(KERN_DEBUG "%s: failed to allocate buffer for nullfunc " 2270 return;
3807 "frame\n", sdata->dev->name); 2271 clear_bit(IEEE80211_STA_REQ_RUN, &ifsta->request);
2272 } else if (!test_and_clear_bit(IEEE80211_STA_REQ_RUN, &ifsta->request))
3808 return; 2273 return;
2274
2275 switch (ifsta->state) {
2276 case IEEE80211_STA_MLME_DISABLED:
2277 break;
2278 case IEEE80211_STA_MLME_DIRECT_PROBE:
2279 ieee80211_direct_probe(sdata, ifsta);
2280 break;
2281 case IEEE80211_STA_MLME_AUTHENTICATE:
2282 ieee80211_authenticate(sdata, ifsta);
2283 break;
2284 case IEEE80211_STA_MLME_ASSOCIATE:
2285 ieee80211_associate(sdata, ifsta);
2286 break;
2287 case IEEE80211_STA_MLME_ASSOCIATED:
2288 ieee80211_associated(sdata, ifsta);
2289 break;
2290 case IEEE80211_STA_MLME_IBSS_SEARCH:
2291 ieee80211_sta_find_ibss(sdata, ifsta);
2292 break;
2293 case IEEE80211_STA_MLME_IBSS_JOINED:
2294 ieee80211_sta_merge_ibss(sdata, ifsta);
2295 break;
2296 default:
2297 WARN_ON(1);
2298 break;
3809 } 2299 }
3810 skb_reserve(skb, local->hw.extra_tx_headroom);
3811 2300
3812 nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24); 2301 if (ieee80211_privacy_mismatch(sdata, ifsta)) {
3813 memset(nullfunc, 0, 24); 2302 printk(KERN_DEBUG "%s: privacy configuration mismatch and "
3814 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC | 2303 "mixed-cell disabled - disassociate\n", sdata->dev->name);
3815 IEEE80211_FCTL_TODS);
3816 if (powersave)
3817 fc |= cpu_to_le16(IEEE80211_FCTL_PM);
3818 nullfunc->frame_control = fc;
3819 memcpy(nullfunc->addr1, sdata->u.sta.bssid, ETH_ALEN);
3820 memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN);
3821 memcpy(nullfunc->addr3, sdata->u.sta.bssid, ETH_ALEN);
3822
3823 ieee80211_sta_tx(sdata->dev, skb, 0);
3824}
3825 2304
2305 ieee80211_set_disassoc(sdata, ifsta, false, true,
2306 WLAN_REASON_UNSPECIFIED);
2307 }
2308}
3826 2309
3827static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata) 2310static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
3828{ 2311{
3829 if (sdata->vif.type == IEEE80211_IF_TYPE_STA || 2312 if (sdata->vif.type == NL80211_IFTYPE_STATION)
3830 ieee80211_vif_is_mesh(&sdata->vif)) 2313 queue_work(sdata->local->hw.workqueue,
3831 ieee80211_sta_timer((unsigned long)sdata); 2314 &sdata->u.sta.work);
3832} 2315}
3833 2316
3834void ieee80211_scan_completed(struct ieee80211_hw *hw) 2317/* interface setup */
2318void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
3835{ 2319{
3836 struct ieee80211_local *local = hw_to_local(hw); 2320 struct ieee80211_if_sta *ifsta;
3837 struct net_device *dev = local->scan_dev;
3838 struct ieee80211_sub_if_data *sdata;
3839 union iwreq_data wrqu;
3840 2321
3841 local->last_scan_completed = jiffies; 2322 ifsta = &sdata->u.sta;
3842 memset(&wrqu, 0, sizeof(wrqu)); 2323 INIT_WORK(&ifsta->work, ieee80211_sta_work);
3843 wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL); 2324 setup_timer(&ifsta->timer, ieee80211_sta_timer,
3844 2325 (unsigned long) sdata);
3845 if (local->sta_hw_scanning) { 2326 skb_queue_head_init(&ifsta->skb_queue);
3846 local->sta_hw_scanning = 0;
3847 if (ieee80211_hw_config(local))
3848 printk(KERN_DEBUG "%s: failed to restore operational "
3849 "channel after scan\n", dev->name);
3850 /* Restart STA timer for HW scan case */
3851 rcu_read_lock();
3852 list_for_each_entry_rcu(sdata, &local->interfaces, list)
3853 ieee80211_restart_sta_timer(sdata);
3854 rcu_read_unlock();
3855 2327
3856 goto done; 2328 ifsta->capab = WLAN_CAPABILITY_ESS;
2329 ifsta->auth_algs = IEEE80211_AUTH_ALG_OPEN |
2330 IEEE80211_AUTH_ALG_SHARED_KEY;
2331 ifsta->flags |= IEEE80211_STA_CREATE_IBSS |
2332 IEEE80211_STA_AUTO_BSSID_SEL |
2333 IEEE80211_STA_AUTO_CHANNEL_SEL;
2334 if (ieee80211_num_regular_queues(&sdata->local->hw) >= 4)
2335 ifsta->flags |= IEEE80211_STA_WMM_ENABLED;
2336}
2337
2338/*
2339 * Add a new IBSS station, will also be called by the RX code when,
2340 * in IBSS mode, receiving a frame from a yet-unknown station, hence
2341 * must be callable in atomic context.
2342 */
2343struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
2344 struct sk_buff *skb, u8 *bssid,
2345 u8 *addr, u64 supp_rates)
2346{
2347 struct ieee80211_local *local = sdata->local;
2348 struct sta_info *sta;
2349 DECLARE_MAC_BUF(mac);
2350 int band = local->hw.conf.channel->band;
2351
2352 /* TODO: Could consider removing the least recently used entry and
2353 * allow new one to be added. */
2354 if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) {
2355 if (net_ratelimit()) {
2356 printk(KERN_DEBUG "%s: No room for a new IBSS STA "
2357 "entry %s\n", sdata->dev->name, print_mac(mac, addr));
2358 }
2359 return NULL;
3857 } 2360 }
3858 2361
3859 local->sta_sw_scanning = 0; 2362 if (compare_ether_addr(bssid, sdata->u.sta.bssid))
3860 if (ieee80211_hw_config(local)) 2363 return NULL;
3861 printk(KERN_DEBUG "%s: failed to restore operational "
3862 "channel after scan\n", dev->name);
3863 2364
2365#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
2366 printk(KERN_DEBUG "%s: Adding new IBSS station %s (dev=%s)\n",
2367 wiphy_name(local->hw.wiphy), print_mac(mac, addr), sdata->dev->name);
2368#endif
3864 2369
3865 netif_tx_lock_bh(local->mdev); 2370 sta = sta_info_alloc(sdata, addr, GFP_ATOMIC);
3866 netif_addr_lock(local->mdev); 2371 if (!sta)
3867 local->filter_flags &= ~FIF_BCN_PRBRESP_PROMISC; 2372 return NULL;
3868 local->ops->configure_filter(local_to_hw(local),
3869 FIF_BCN_PRBRESP_PROMISC,
3870 &local->filter_flags,
3871 local->mdev->mc_count,
3872 local->mdev->mc_list);
3873 2373
3874 netif_addr_unlock(local->mdev); 2374 set_sta_flags(sta, WLAN_STA_AUTHORIZED);
3875 netif_tx_unlock_bh(local->mdev);
3876 2375
3877 rcu_read_lock(); 2376 /* make sure mandatory rates are always added */
3878 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 2377 sta->sta.supp_rates[band] = supp_rates |
3879 /* Tell AP we're back */ 2378 ieee80211_mandatory_rates(local, band);
3880 if (sdata->vif.type == IEEE80211_IF_TYPE_STA &&
3881 sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED)
3882 ieee80211_send_nullfunc(local, sdata, 0);
3883 2379
3884 ieee80211_restart_sta_timer(sdata); 2380 rate_control_rate_init(sta);
3885 2381
3886 netif_wake_queue(sdata->dev); 2382 if (sta_info_insert(sta))
3887 } 2383 return NULL;
3888 rcu_read_unlock();
3889 2384
3890done: 2385 return sta;
3891 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3892 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
3893 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
3894 if (!(ifsta->flags & IEEE80211_STA_BSSID_SET) ||
3895 (!(ifsta->state == IEEE80211_IBSS_JOINED) &&
3896 !ieee80211_sta_active_ibss(dev)))
3897 ieee80211_sta_find_ibss(dev, ifsta);
3898 }
3899} 2386}
3900EXPORT_SYMBOL(ieee80211_scan_completed);
3901 2387
3902void ieee80211_sta_scan_work(struct work_struct *work) 2388/* configuration hooks */
2389void ieee80211_sta_req_auth(struct ieee80211_sub_if_data *sdata,
2390 struct ieee80211_if_sta *ifsta)
3903{ 2391{
3904 struct ieee80211_local *local = 2392 struct ieee80211_local *local = sdata->local;
3905 container_of(work, struct ieee80211_local, scan_work.work);
3906 struct net_device *dev = local->scan_dev;
3907 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3908 struct ieee80211_supported_band *sband;
3909 struct ieee80211_channel *chan;
3910 int skip;
3911 unsigned long next_delay = 0;
3912 2393
3913 if (!local->sta_sw_scanning) 2394 if (sdata->vif.type != NL80211_IFTYPE_STATION)
3914 return; 2395 return;
3915 2396
3916 switch (local->scan_state) { 2397 if ((ifsta->flags & (IEEE80211_STA_BSSID_SET |
3917 case SCAN_SET_CHANNEL: 2398 IEEE80211_STA_AUTO_BSSID_SEL)) &&
3918 /* 2399 (ifsta->flags & (IEEE80211_STA_SSID_SET |
3919 * Get current scan band. scan_band may be IEEE80211_NUM_BANDS 2400 IEEE80211_STA_AUTO_SSID_SEL))) {
3920 * after we successfully scanned the last channel of the last
3921 * band (and the last band is supported by the hw)
3922 */
3923 if (local->scan_band < IEEE80211_NUM_BANDS)
3924 sband = local->hw.wiphy->bands[local->scan_band];
3925 else
3926 sband = NULL;
3927
3928 /*
3929 * If we are at an unsupported band and have more bands
3930 * left to scan, advance to the next supported one.
3931 */
3932 while (!sband && local->scan_band < IEEE80211_NUM_BANDS - 1) {
3933 local->scan_band++;
3934 sband = local->hw.wiphy->bands[local->scan_band];
3935 local->scan_channel_idx = 0;
3936 }
3937
3938 /* if no more bands/channels left, complete scan */
3939 if (!sband || local->scan_channel_idx >= sband->n_channels) {
3940 ieee80211_scan_completed(local_to_hw(local));
3941 return;
3942 }
3943 skip = 0;
3944 chan = &sband->channels[local->scan_channel_idx];
3945
3946 if (chan->flags & IEEE80211_CHAN_DISABLED ||
3947 (sdata->vif.type == IEEE80211_IF_TYPE_IBSS &&
3948 chan->flags & IEEE80211_CHAN_NO_IBSS))
3949 skip = 1;
3950
3951 if (!skip) {
3952 local->scan_channel = chan;
3953 if (ieee80211_hw_config(local)) {
3954 printk(KERN_DEBUG "%s: failed to set freq to "
3955 "%d MHz for scan\n", dev->name,
3956 chan->center_freq);
3957 skip = 1;
3958 }
3959 }
3960
3961 /* advance state machine to next channel/band */
3962 local->scan_channel_idx++;
3963 if (local->scan_channel_idx >= sband->n_channels) {
3964 /*
3965 * scan_band may end up == IEEE80211_NUM_BANDS, but
3966 * we'll catch that case above and complete the scan
3967 * if that is the case.
3968 */
3969 local->scan_band++;
3970 local->scan_channel_idx = 0;
3971 }
3972
3973 if (skip)
3974 break;
3975 2401
3976 next_delay = IEEE80211_PROBE_DELAY + 2402 if (ifsta->state == IEEE80211_STA_MLME_ASSOCIATED)
3977 usecs_to_jiffies(local->hw.channel_change_time); 2403 ieee80211_set_disassoc(sdata, ifsta, true, true,
3978 local->scan_state = SCAN_SEND_PROBE; 2404 WLAN_REASON_DEAUTH_LEAVING);
3979 break;
3980 case SCAN_SEND_PROBE:
3981 next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
3982 local->scan_state = SCAN_SET_CHANNEL;
3983 2405
3984 if (local->scan_channel->flags & IEEE80211_CHAN_PASSIVE_SCAN) 2406 set_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request);
3985 break; 2407 queue_work(local->hw.workqueue, &ifsta->work);
3986 ieee80211_send_probe_req(dev, NULL, local->scan_ssid,
3987 local->scan_ssid_len);
3988 next_delay = IEEE80211_CHANNEL_TIME;
3989 break;
3990 } 2408 }
3991
3992 if (local->sta_sw_scanning)
3993 queue_delayed_work(local->hw.workqueue, &local->scan_work,
3994 next_delay);
3995} 2409}
3996 2410
3997 2411int ieee80211_sta_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len)
3998static int ieee80211_sta_start_scan(struct net_device *dev,
3999 u8 *ssid, size_t ssid_len)
4000{ 2412{
4001 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 2413 struct ieee80211_if_sta *ifsta;
4002 struct ieee80211_sub_if_data *sdata; 2414 int res;
4003 2415
4004 if (ssid_len > IEEE80211_MAX_SSID_LEN) 2416 if (len > IEEE80211_MAX_SSID_LEN)
4005 return -EINVAL; 2417 return -EINVAL;
4006 2418
4007 /* MLME-SCAN.request (page 118) page 144 (11.1.3.1) 2419 ifsta = &sdata->u.sta;
4008 * BSSType: INFRASTRUCTURE, INDEPENDENT, ANY_BSS
4009 * BSSID: MACAddress
4010 * SSID
4011 * ScanType: ACTIVE, PASSIVE
4012 * ProbeDelay: delay (in microseconds) to be used prior to transmitting
4013 * a Probe frame during active scanning
4014 * ChannelList
4015 * MinChannelTime (>= ProbeDelay), in TU
4016 * MaxChannelTime: (>= MinChannelTime), in TU
4017 */
4018
4019 /* MLME-SCAN.confirm
4020 * BSSDescriptionSet
4021 * ResultCode: SUCCESS, INVALID_PARAMETERS
4022 */
4023 2420
4024 if (local->sta_sw_scanning || local->sta_hw_scanning) { 2421 if (ifsta->ssid_len != len || memcmp(ifsta->ssid, ssid, len) != 0) {
4025 if (local->scan_dev == dev) 2422 memset(ifsta->ssid, 0, sizeof(ifsta->ssid));
4026 return 0; 2423 memcpy(ifsta->ssid, ssid, len);
4027 return -EBUSY; 2424 ifsta->ssid_len = len;
4028 } 2425 ifsta->flags &= ~IEEE80211_STA_PREV_BSSID_SET;
4029 2426
4030 if (local->ops->hw_scan) { 2427 res = 0;
4031 int rc = local->ops->hw_scan(local_to_hw(local), 2428 /*
4032 ssid, ssid_len); 2429 * Hack! MLME code needs to be cleaned up to have different
4033 if (!rc) { 2430 * entry points for configuration and internal selection change
4034 local->sta_hw_scanning = 1; 2431 */
4035 local->scan_dev = dev; 2432 if (netif_running(sdata->dev))
2433 res = ieee80211_if_config(sdata, IEEE80211_IFCC_SSID);
2434 if (res) {
2435 printk(KERN_DEBUG "%s: Failed to config new SSID to "
2436 "the low-level driver\n", sdata->dev->name);
2437 return res;
4036 } 2438 }
4037 return rc;
4038 } 2439 }
4039 2440
4040 local->sta_sw_scanning = 1; 2441 if (len)
2442 ifsta->flags |= IEEE80211_STA_SSID_SET;
2443 else
2444 ifsta->flags &= ~IEEE80211_STA_SSID_SET;
4041 2445
4042 rcu_read_lock(); 2446 if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
4043 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 2447 !(ifsta->flags & IEEE80211_STA_BSSID_SET)) {
4044 netif_stop_queue(sdata->dev); 2448 ifsta->ibss_join_req = jiffies;
4045 if (sdata->vif.type == IEEE80211_IF_TYPE_STA && 2449 ifsta->state = IEEE80211_STA_MLME_IBSS_SEARCH;
4046 (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED)) 2450 return ieee80211_sta_find_ibss(sdata, ifsta);
4047 ieee80211_send_nullfunc(local, sdata, 1);
4048 } 2451 }
4049 rcu_read_unlock();
4050
4051 if (ssid) {
4052 local->scan_ssid_len = ssid_len;
4053 memcpy(local->scan_ssid, ssid, ssid_len);
4054 } else
4055 local->scan_ssid_len = 0;
4056 local->scan_state = SCAN_SET_CHANNEL;
4057 local->scan_channel_idx = 0;
4058 local->scan_band = IEEE80211_BAND_2GHZ;
4059 local->scan_dev = dev;
4060
4061 netif_addr_lock_bh(local->mdev);
4062 local->filter_flags |= FIF_BCN_PRBRESP_PROMISC;
4063 local->ops->configure_filter(local_to_hw(local),
4064 FIF_BCN_PRBRESP_PROMISC,
4065 &local->filter_flags,
4066 local->mdev->mc_count,
4067 local->mdev->mc_list);
4068 netif_addr_unlock_bh(local->mdev);
4069
4070 /* TODO: start scan as soon as all nullfunc frames are ACKed */
4071 queue_delayed_work(local->hw.workqueue, &local->scan_work,
4072 IEEE80211_CHANNEL_TIME);
4073 2452
4074 return 0; 2453 return 0;
4075} 2454}
4076 2455
4077 2456int ieee80211_sta_get_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t *len)
4078int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len)
4079{ 2457{
4080 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
4081 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 2458 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
4082 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 2459 memcpy(ssid, ifsta->ssid, ifsta->ssid_len);
4083 2460 *len = ifsta->ssid_len;
4084 if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
4085 return ieee80211_sta_start_scan(dev, ssid, ssid_len);
4086
4087 if (local->sta_sw_scanning || local->sta_hw_scanning) {
4088 if (local->scan_dev == dev)
4089 return 0;
4090 return -EBUSY;
4091 }
4092
4093 ifsta->scan_ssid_len = ssid_len;
4094 if (ssid_len)
4095 memcpy(ifsta->scan_ssid, ssid, ssid_len);
4096 set_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request);
4097 queue_work(local->hw.workqueue, &ifsta->work);
4098 return 0; 2461 return 0;
4099} 2462}
4100 2463
4101static char * 2464int ieee80211_sta_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid)
4102ieee80211_sta_scan_result(struct net_device *dev,
4103 struct iw_request_info *info,
4104 struct ieee80211_sta_bss *bss,
4105 char *current_ev, char *end_buf)
4106{ 2465{
4107 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 2466 struct ieee80211_if_sta *ifsta;
4108 struct iw_event iwe; 2467 int res;
4109
4110 if (time_after(jiffies,
4111 bss->last_update + IEEE80211_SCAN_RESULT_EXPIRE))
4112 return current_ev;
4113
4114 memset(&iwe, 0, sizeof(iwe));
4115 iwe.cmd = SIOCGIWAP;
4116 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
4117 memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
4118 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
4119 IW_EV_ADDR_LEN);
4120
4121 memset(&iwe, 0, sizeof(iwe));
4122 iwe.cmd = SIOCGIWESSID;
4123 if (bss_mesh_cfg(bss)) {
4124 iwe.u.data.length = bss_mesh_id_len(bss);
4125 iwe.u.data.flags = 1;
4126 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4127 &iwe, bss_mesh_id(bss));
4128 } else {
4129 iwe.u.data.length = bss->ssid_len;
4130 iwe.u.data.flags = 1;
4131 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4132 &iwe, bss->ssid);
4133 }
4134
4135 if (bss->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)
4136 || bss_mesh_cfg(bss)) {
4137 memset(&iwe, 0, sizeof(iwe));
4138 iwe.cmd = SIOCGIWMODE;
4139 if (bss_mesh_cfg(bss))
4140 iwe.u.mode = IW_MODE_MESH;
4141 else if (bss->capability & WLAN_CAPABILITY_ESS)
4142 iwe.u.mode = IW_MODE_MASTER;
4143 else
4144 iwe.u.mode = IW_MODE_ADHOC;
4145 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
4146 &iwe, IW_EV_UINT_LEN);
4147 }
4148
4149 memset(&iwe, 0, sizeof(iwe));
4150 iwe.cmd = SIOCGIWFREQ;
4151 iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq);
4152 iwe.u.freq.e = 0;
4153 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
4154 IW_EV_FREQ_LEN);
4155
4156 memset(&iwe, 0, sizeof(iwe));
4157 iwe.cmd = SIOCGIWFREQ;
4158 iwe.u.freq.m = bss->freq;
4159 iwe.u.freq.e = 6;
4160 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
4161 IW_EV_FREQ_LEN);
4162 memset(&iwe, 0, sizeof(iwe));
4163 iwe.cmd = IWEVQUAL;
4164 iwe.u.qual.qual = bss->qual;
4165 iwe.u.qual.level = bss->signal;
4166 iwe.u.qual.noise = bss->noise;
4167 iwe.u.qual.updated = local->wstats_flags;
4168 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
4169 IW_EV_QUAL_LEN);
4170
4171 memset(&iwe, 0, sizeof(iwe));
4172 iwe.cmd = SIOCGIWENCODE;
4173 if (bss->capability & WLAN_CAPABILITY_PRIVACY)
4174 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
4175 else
4176 iwe.u.data.flags = IW_ENCODE_DISABLED;
4177 iwe.u.data.length = 0;
4178 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4179 &iwe, "");
4180
4181 if (bss && bss->wpa_ie) {
4182 memset(&iwe, 0, sizeof(iwe));
4183 iwe.cmd = IWEVGENIE;
4184 iwe.u.data.length = bss->wpa_ie_len;
4185 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4186 &iwe, bss->wpa_ie);
4187 }
4188
4189 if (bss && bss->rsn_ie) {
4190 memset(&iwe, 0, sizeof(iwe));
4191 iwe.cmd = IWEVGENIE;
4192 iwe.u.data.length = bss->rsn_ie_len;
4193 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4194 &iwe, bss->rsn_ie);
4195 }
4196
4197 if (bss && bss->ht_ie) {
4198 memset(&iwe, 0, sizeof(iwe));
4199 iwe.cmd = IWEVGENIE;
4200 iwe.u.data.length = bss->ht_ie_len;
4201 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4202 &iwe, bss->ht_ie);
4203 }
4204
4205 if (bss && bss->supp_rates_len > 0) {
4206 /* display all supported rates in readable format */
4207 char *p = current_ev + iwe_stream_lcp_len(info);
4208 int i;
4209
4210 memset(&iwe, 0, sizeof(iwe));
4211 iwe.cmd = SIOCGIWRATE;
4212 /* Those two flags are ignored... */
4213 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
4214
4215 for (i = 0; i < bss->supp_rates_len; i++) {
4216 iwe.u.bitrate.value = ((bss->supp_rates[i] &
4217 0x7f) * 500000);
4218 p = iwe_stream_add_value(info, current_ev, p,
4219 end_buf, &iwe, IW_EV_PARAM_LEN);
4220 }
4221 current_ev = p;
4222 }
4223 2468
4224 if (bss) { 2469 ifsta = &sdata->u.sta;
4225 char *buf;
4226 buf = kmalloc(30, GFP_ATOMIC);
4227 if (buf) {
4228 memset(&iwe, 0, sizeof(iwe));
4229 iwe.cmd = IWEVCUSTOM;
4230 sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->timestamp));
4231 iwe.u.data.length = strlen(buf);
4232 current_ev = iwe_stream_add_point(info, current_ev,
4233 end_buf,
4234 &iwe, buf);
4235 memset(&iwe, 0, sizeof(iwe));
4236 iwe.cmd = IWEVCUSTOM;
4237 sprintf(buf, " Last beacon: %dms ago",
4238 jiffies_to_msecs(jiffies - bss->last_update));
4239 iwe.u.data.length = strlen(buf);
4240 current_ev = iwe_stream_add_point(info, current_ev,
4241 end_buf, &iwe, buf);
4242 kfree(buf);
4243 }
4244 }
4245 2470
4246 if (bss_mesh_cfg(bss)) { 2471 if (memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) {
4247 char *buf; 2472 memcpy(ifsta->bssid, bssid, ETH_ALEN);
4248 u8 *cfg = bss_mesh_cfg(bss); 2473 res = 0;
4249 buf = kmalloc(50, GFP_ATOMIC); 2474 /*
4250 if (buf) { 2475 * Hack! See also ieee80211_sta_set_ssid.
4251 memset(&iwe, 0, sizeof(iwe)); 2476 */
4252 iwe.cmd = IWEVCUSTOM; 2477 if (netif_running(sdata->dev))
4253 sprintf(buf, "Mesh network (version %d)", cfg[0]); 2478 res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
4254 iwe.u.data.length = strlen(buf); 2479 if (res) {
4255 current_ev = iwe_stream_add_point(info, current_ev, 2480 printk(KERN_DEBUG "%s: Failed to config new BSSID to "
4256 end_buf, 2481 "the low-level driver\n", sdata->dev->name);
4257 &iwe, buf); 2482 return res;
4258 sprintf(buf, "Path Selection Protocol ID: "
4259 "0x%02X%02X%02X%02X", cfg[1], cfg[2], cfg[3],
4260 cfg[4]);
4261 iwe.u.data.length = strlen(buf);
4262 current_ev = iwe_stream_add_point(info, current_ev,
4263 end_buf,
4264 &iwe, buf);
4265 sprintf(buf, "Path Selection Metric ID: "
4266 "0x%02X%02X%02X%02X", cfg[5], cfg[6], cfg[7],
4267 cfg[8]);
4268 iwe.u.data.length = strlen(buf);
4269 current_ev = iwe_stream_add_point(info, current_ev,
4270 end_buf,
4271 &iwe, buf);
4272 sprintf(buf, "Congestion Control Mode ID: "
4273 "0x%02X%02X%02X%02X", cfg[9], cfg[10],
4274 cfg[11], cfg[12]);
4275 iwe.u.data.length = strlen(buf);
4276 current_ev = iwe_stream_add_point(info, current_ev,
4277 end_buf,
4278 &iwe, buf);
4279 sprintf(buf, "Channel Precedence: "
4280 "0x%02X%02X%02X%02X", cfg[13], cfg[14],
4281 cfg[15], cfg[16]);
4282 iwe.u.data.length = strlen(buf);
4283 current_ev = iwe_stream_add_point(info, current_ev,
4284 end_buf,
4285 &iwe, buf);
4286 kfree(buf);
4287 } 2483 }
4288 } 2484 }
4289 2485
4290 return current_ev; 2486 if (is_valid_ether_addr(bssid))
4291} 2487 ifsta->flags |= IEEE80211_STA_BSSID_SET;
4292 2488 else
2489 ifsta->flags &= ~IEEE80211_STA_BSSID_SET;
4293 2490
4294int ieee80211_sta_scan_results(struct net_device *dev, 2491 return 0;
4295 struct iw_request_info *info,
4296 char *buf, size_t len)
4297{
4298 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
4299 char *current_ev = buf;
4300 char *end_buf = buf + len;
4301 struct ieee80211_sta_bss *bss;
4302
4303 spin_lock_bh(&local->sta_bss_lock);
4304 list_for_each_entry(bss, &local->sta_bss_list, list) {
4305 if (buf + len - current_ev <= IW_EV_ADDR_LEN) {
4306 spin_unlock_bh(&local->sta_bss_lock);
4307 return -E2BIG;
4308 }
4309 current_ev = ieee80211_sta_scan_result(dev, info, bss,
4310 current_ev, end_buf);
4311 }
4312 spin_unlock_bh(&local->sta_bss_lock);
4313 return current_ev - buf;
4314} 2492}
4315 2493
4316 2494int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata, char *ie, size_t len)
4317int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len)
4318{ 2495{
4319 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
4320 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 2496 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
4321 2497
4322 kfree(ifsta->extra_ie); 2498 kfree(ifsta->extra_ie);
@@ -4335,92 +2511,60 @@ int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len)
4335 return 0; 2511 return 0;
4336} 2512}
4337 2513
4338 2514int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason)
4339struct sta_info *ieee80211_ibss_add_sta(struct net_device *dev,
4340 struct sk_buff *skb, u8 *bssid,
4341 u8 *addr, u64 supp_rates)
4342{
4343 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
4344 struct sta_info *sta;
4345 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
4346 DECLARE_MAC_BUF(mac);
4347 int band = local->hw.conf.channel->band;
4348
4349 /* TODO: Could consider removing the least recently used entry and
4350 * allow new one to be added. */
4351 if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) {
4352 if (net_ratelimit()) {
4353 printk(KERN_DEBUG "%s: No room for a new IBSS STA "
4354 "entry %s\n", dev->name, print_mac(mac, addr));
4355 }
4356 return NULL;
4357 }
4358
4359 if (compare_ether_addr(bssid, sdata->u.sta.bssid))
4360 return NULL;
4361
4362#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
4363 printk(KERN_DEBUG "%s: Adding new IBSS station %s (dev=%s)\n",
4364 wiphy_name(local->hw.wiphy), print_mac(mac, addr), dev->name);
4365#endif
4366
4367 sta = sta_info_alloc(sdata, addr, GFP_ATOMIC);
4368 if (!sta)
4369 return NULL;
4370
4371 set_sta_flags(sta, WLAN_STA_AUTHORIZED);
4372
4373 if (supp_rates)
4374 sta->supp_rates[band] = supp_rates;
4375 else
4376 sta->supp_rates[band] = sdata->u.sta.supp_rates_bits[band];
4377
4378 rate_control_rate_init(sta, local);
4379
4380 if (sta_info_insert(sta))
4381 return NULL;
4382
4383 return sta;
4384}
4385
4386
4387int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason)
4388{ 2515{
4389 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
4390 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 2516 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
4391 2517
4392 printk(KERN_DEBUG "%s: deauthenticating by local choice (reason=%d)\n", 2518 printk(KERN_DEBUG "%s: deauthenticating by local choice (reason=%d)\n",
4393 dev->name, reason); 2519 sdata->dev->name, reason);
4394 2520
4395 if (sdata->vif.type != IEEE80211_IF_TYPE_STA && 2521 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
4396 sdata->vif.type != IEEE80211_IF_TYPE_IBSS) 2522 sdata->vif.type != NL80211_IFTYPE_ADHOC)
4397 return -EINVAL; 2523 return -EINVAL;
4398 2524
4399 ieee80211_send_deauth(dev, ifsta, reason); 2525 ieee80211_set_disassoc(sdata, ifsta, true, true, reason);
4400 ieee80211_set_disassoc(dev, ifsta, 1);
4401 return 0; 2526 return 0;
4402} 2527}
4403 2528
4404 2529int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason)
4405int ieee80211_sta_disassociate(struct net_device *dev, u16 reason)
4406{ 2530{
4407 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
4408 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 2531 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
4409 2532
4410 printk(KERN_DEBUG "%s: disassociating by local choice (reason=%d)\n", 2533 printk(KERN_DEBUG "%s: disassociating by local choice (reason=%d)\n",
4411 dev->name, reason); 2534 sdata->dev->name, reason);
4412 2535
4413 if (sdata->vif.type != IEEE80211_IF_TYPE_STA) 2536 if (sdata->vif.type != NL80211_IFTYPE_STATION)
4414 return -EINVAL; 2537 return -EINVAL;
4415 2538
4416 if (!(ifsta->flags & IEEE80211_STA_ASSOCIATED)) 2539 if (!(ifsta->flags & IEEE80211_STA_ASSOCIATED))
4417 return -1; 2540 return -1;
4418 2541
4419 ieee80211_send_disassoc(dev, ifsta, reason); 2542 ieee80211_set_disassoc(sdata, ifsta, false, true, reason);
4420 ieee80211_set_disassoc(dev, ifsta, 0);
4421 return 0; 2543 return 0;
4422} 2544}
4423 2545
2546/* scan finished notification */
2547void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local)
2548{
2549 struct ieee80211_sub_if_data *sdata = local->scan_sdata;
2550 struct ieee80211_if_sta *ifsta;
2551
2552 if (sdata && sdata->vif.type == NL80211_IFTYPE_ADHOC) {
2553 ifsta = &sdata->u.sta;
2554 if (!(ifsta->flags & IEEE80211_STA_BSSID_SET) ||
2555 (!(ifsta->state == IEEE80211_STA_MLME_IBSS_JOINED) &&
2556 !ieee80211_sta_active_ibss(sdata)))
2557 ieee80211_sta_find_ibss(sdata, ifsta);
2558 }
2559
2560 /* Restart STA timers */
2561 rcu_read_lock();
2562 list_for_each_entry_rcu(sdata, &local->interfaces, list)
2563 ieee80211_restart_sta_timer(sdata);
2564 rcu_read_unlock();
2565}
2566
2567/* driver notification call */
4424void ieee80211_notify_mac(struct ieee80211_hw *hw, 2568void ieee80211_notify_mac(struct ieee80211_hw *hw,
4425 enum ieee80211_notification_types notif_type) 2569 enum ieee80211_notification_types notif_type)
4426{ 2570{
@@ -4431,10 +2575,10 @@ void ieee80211_notify_mac(struct ieee80211_hw *hw,
4431 case IEEE80211_NOTIFY_RE_ASSOC: 2575 case IEEE80211_NOTIFY_RE_ASSOC:
4432 rcu_read_lock(); 2576 rcu_read_lock();
4433 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 2577 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
4434 if (sdata->vif.type != IEEE80211_IF_TYPE_STA) 2578 if (sdata->vif.type != NL80211_IFTYPE_STATION)
4435 continue; 2579 continue;
4436 2580
4437 ieee80211_sta_req_auth(sdata->dev, &sdata->u.sta); 2581 ieee80211_sta_req_auth(sdata, &sdata->u.sta);
4438 } 2582 }
4439 rcu_read_unlock(); 2583 rcu_read_unlock();
4440 break; 2584 break;
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 0388c090dfe9..5d786720d935 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -12,6 +12,7 @@
12#include <linux/rtnetlink.h> 12#include <linux/rtnetlink.h>
13#include "rate.h" 13#include "rate.h"
14#include "ieee80211_i.h" 14#include "ieee80211_i.h"
15#include "debugfs.h"
15 16
16struct rate_control_alg { 17struct rate_control_alg {
17 struct list_head list; 18 struct list_head list;
@@ -127,19 +128,46 @@ static void ieee80211_rate_control_ops_put(struct rate_control_ops *ops)
127 module_put(ops->module); 128 module_put(ops->module);
128} 129}
129 130
131#ifdef CONFIG_MAC80211_DEBUGFS
132static ssize_t rcname_read(struct file *file, char __user *userbuf,
133 size_t count, loff_t *ppos)
134{
135 struct rate_control_ref *ref = file->private_data;
136 int len = strlen(ref->ops->name);
137
138 return simple_read_from_buffer(userbuf, count, ppos,
139 ref->ops->name, len);
140}
141
142static const struct file_operations rcname_ops = {
143 .read = rcname_read,
144 .open = mac80211_open_file_generic,
145};
146#endif
147
130struct rate_control_ref *rate_control_alloc(const char *name, 148struct rate_control_ref *rate_control_alloc(const char *name,
131 struct ieee80211_local *local) 149 struct ieee80211_local *local)
132{ 150{
151 struct dentry *debugfsdir = NULL;
133 struct rate_control_ref *ref; 152 struct rate_control_ref *ref;
134 153
135 ref = kmalloc(sizeof(struct rate_control_ref), GFP_KERNEL); 154 ref = kmalloc(sizeof(struct rate_control_ref), GFP_KERNEL);
136 if (!ref) 155 if (!ref)
137 goto fail_ref; 156 goto fail_ref;
138 kref_init(&ref->kref); 157 kref_init(&ref->kref);
158 ref->local = local;
139 ref->ops = ieee80211_rate_control_ops_get(name); 159 ref->ops = ieee80211_rate_control_ops_get(name);
140 if (!ref->ops) 160 if (!ref->ops)
141 goto fail_ops; 161 goto fail_ops;
142 ref->priv = ref->ops->alloc(local); 162
163#ifdef CONFIG_MAC80211_DEBUGFS
164 debugfsdir = debugfs_create_dir("rc", local->hw.wiphy->debugfsdir);
165 local->debugfs.rcdir = debugfsdir;
166 local->debugfs.rcname = debugfs_create_file("name", 0400, debugfsdir,
167 ref, &rcname_ops);
168#endif
169
170 ref->priv = ref->ops->alloc(&local->hw, debugfsdir);
143 if (!ref->priv) 171 if (!ref->priv)
144 goto fail_priv; 172 goto fail_priv;
145 return ref; 173 return ref;
@@ -158,29 +186,46 @@ static void rate_control_release(struct kref *kref)
158 186
159 ctrl_ref = container_of(kref, struct rate_control_ref, kref); 187 ctrl_ref = container_of(kref, struct rate_control_ref, kref);
160 ctrl_ref->ops->free(ctrl_ref->priv); 188 ctrl_ref->ops->free(ctrl_ref->priv);
189
190#ifdef CONFIG_MAC80211_DEBUGFS
191 debugfs_remove(ctrl_ref->local->debugfs.rcname);
192 ctrl_ref->local->debugfs.rcname = NULL;
193 debugfs_remove(ctrl_ref->local->debugfs.rcdir);
194 ctrl_ref->local->debugfs.rcdir = NULL;
195#endif
196
161 ieee80211_rate_control_ops_put(ctrl_ref->ops); 197 ieee80211_rate_control_ops_put(ctrl_ref->ops);
162 kfree(ctrl_ref); 198 kfree(ctrl_ref);
163} 199}
164 200
165void rate_control_get_rate(struct net_device *dev, 201void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
166 struct ieee80211_supported_band *sband, 202 struct ieee80211_supported_band *sband,
167 struct sk_buff *skb, 203 struct sta_info *sta, struct sk_buff *skb,
168 struct rate_selection *sel) 204 struct rate_selection *sel)
169{ 205{
170 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 206 struct rate_control_ref *ref = sdata->local->rate_ctrl;
171 struct rate_control_ref *ref = local->rate_ctrl; 207 void *priv_sta = NULL;
172 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 208 struct ieee80211_sta *ista = NULL;
173 struct sta_info *sta;
174 int i; 209 int i;
175 210
176 rcu_read_lock();
177 sta = sta_info_get(local, hdr->addr1);
178
179 sel->rate_idx = -1; 211 sel->rate_idx = -1;
180 sel->nonerp_idx = -1; 212 sel->nonerp_idx = -1;
181 sel->probe_idx = -1; 213 sel->probe_idx = -1;
214 sel->max_rate_idx = sdata->max_ratectrl_rateidx;
215
216 if (sta) {
217 ista = &sta->sta;
218 priv_sta = sta->rate_ctrl_priv;
219 }
220
221 if (sta && sdata->force_unicast_rateidx > -1)
222 sel->rate_idx = sdata->force_unicast_rateidx;
223 else
224 ref->ops->get_rate(ref->priv, sband, ista, priv_sta, skb, sel);
182 225
183 ref->ops->get_rate(ref->priv, dev, sband, skb, sel); 226 if (sdata->max_ratectrl_rateidx > -1 &&
227 sel->rate_idx > sdata->max_ratectrl_rateidx)
228 sel->rate_idx = sdata->max_ratectrl_rateidx;
184 229
185 BUG_ON(sel->rate_idx < 0); 230 BUG_ON(sel->rate_idx < 0);
186 231
@@ -191,13 +236,11 @@ void rate_control_get_rate(struct net_device *dev,
191 if (sband->bitrates[sel->rate_idx].bitrate < rate->bitrate) 236 if (sband->bitrates[sel->rate_idx].bitrate < rate->bitrate)
192 break; 237 break;
193 238
194 if (rate_supported(sta, sband->band, i) && 239 if (rate_supported(ista, sband->band, i) &&
195 !(rate->flags & IEEE80211_RATE_ERP_G)) 240 !(rate->flags & IEEE80211_RATE_ERP_G))
196 sel->nonerp_idx = i; 241 sel->nonerp_idx = i;
197 } 242 }
198 } 243 }
199
200 rcu_read_unlock();
201} 244}
202 245
203struct rate_control_ref *rate_control_get(struct rate_control_ref *ref) 246struct rate_control_ref *rate_control_get(struct rate_control_ref *ref)
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h
index ede7ab56f65b..d0092f847f82 100644
--- a/net/mac80211/rate.h
+++ b/net/mac80211/rate.h
@@ -19,77 +19,48 @@
19#include "ieee80211_i.h" 19#include "ieee80211_i.h"
20#include "sta_info.h" 20#include "sta_info.h"
21 21
22/**
23 * struct rate_selection - rate selection for rate control algos
24 * @rate: selected transmission rate index
25 * @nonerp: Non-ERP rate to use instead if ERP cannot be used
26 * @probe: rate for probing (or -1)
27 *
28 */
29struct rate_selection {
30 s8 rate_idx, nonerp_idx, probe_idx;
31};
32
33struct rate_control_ops {
34 struct module *module;
35 const char *name;
36 void (*tx_status)(void *priv, struct net_device *dev,
37 struct sk_buff *skb);
38 void (*get_rate)(void *priv, struct net_device *dev,
39 struct ieee80211_supported_band *band,
40 struct sk_buff *skb,
41 struct rate_selection *sel);
42 void (*rate_init)(void *priv, void *priv_sta,
43 struct ieee80211_local *local, struct sta_info *sta);
44 void (*clear)(void *priv);
45
46 void *(*alloc)(struct ieee80211_local *local);
47 void (*free)(void *priv);
48 void *(*alloc_sta)(void *priv, gfp_t gfp);
49 void (*free_sta)(void *priv, void *priv_sta);
50
51 int (*add_attrs)(void *priv, struct kobject *kobj);
52 void (*remove_attrs)(void *priv, struct kobject *kobj);
53 void (*add_sta_debugfs)(void *priv, void *priv_sta,
54 struct dentry *dir);
55 void (*remove_sta_debugfs)(void *priv, void *priv_sta);
56};
57
58struct rate_control_ref { 22struct rate_control_ref {
23 struct ieee80211_local *local;
59 struct rate_control_ops *ops; 24 struct rate_control_ops *ops;
60 void *priv; 25 void *priv;
61 struct kref kref; 26 struct kref kref;
62}; 27};
63 28
64int ieee80211_rate_control_register(struct rate_control_ops *ops);
65void ieee80211_rate_control_unregister(struct rate_control_ops *ops);
66
67/* Get a reference to the rate control algorithm. If `name' is NULL, get the 29/* Get a reference to the rate control algorithm. If `name' is NULL, get the
68 * first available algorithm. */ 30 * first available algorithm. */
69struct rate_control_ref *rate_control_alloc(const char *name, 31struct rate_control_ref *rate_control_alloc(const char *name,
70 struct ieee80211_local *local); 32 struct ieee80211_local *local);
71void rate_control_get_rate(struct net_device *dev, 33void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
72 struct ieee80211_supported_band *sband, 34 struct ieee80211_supported_band *sband,
73 struct sk_buff *skb, 35 struct sta_info *sta, struct sk_buff *skb,
74 struct rate_selection *sel); 36 struct rate_selection *sel);
75struct rate_control_ref *rate_control_get(struct rate_control_ref *ref); 37struct rate_control_ref *rate_control_get(struct rate_control_ref *ref);
76void rate_control_put(struct rate_control_ref *ref); 38void rate_control_put(struct rate_control_ref *ref);
77 39
78static inline void rate_control_tx_status(struct net_device *dev, 40static inline void rate_control_tx_status(struct ieee80211_local *local,
41 struct ieee80211_supported_band *sband,
42 struct sta_info *sta,
79 struct sk_buff *skb) 43 struct sk_buff *skb)
80{ 44{
81 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
82 struct rate_control_ref *ref = local->rate_ctrl; 45 struct rate_control_ref *ref = local->rate_ctrl;
46 struct ieee80211_sta *ista = &sta->sta;
47 void *priv_sta = sta->rate_ctrl_priv;
83 48
84 ref->ops->tx_status(ref->priv, dev, skb); 49 ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb);
85} 50}
86 51
87 52
88static inline void rate_control_rate_init(struct sta_info *sta, 53static inline void rate_control_rate_init(struct sta_info *sta)
89 struct ieee80211_local *local)
90{ 54{
55 struct ieee80211_local *local = sta->sdata->local;
91 struct rate_control_ref *ref = sta->rate_ctrl; 56 struct rate_control_ref *ref = sta->rate_ctrl;
92 ref->ops->rate_init(ref->priv, sta->rate_ctrl_priv, local, sta); 57 struct ieee80211_sta *ista = &sta->sta;
58 void *priv_sta = sta->rate_ctrl_priv;
59 struct ieee80211_supported_band *sband;
60
61 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
62
63 ref->ops->rate_init(ref->priv, sband, ista, priv_sta);
93} 64}
94 65
95 66
@@ -100,15 +71,19 @@ static inline void rate_control_clear(struct ieee80211_local *local)
100} 71}
101 72
102static inline void *rate_control_alloc_sta(struct rate_control_ref *ref, 73static inline void *rate_control_alloc_sta(struct rate_control_ref *ref,
74 struct ieee80211_sta *sta,
103 gfp_t gfp) 75 gfp_t gfp)
104{ 76{
105 return ref->ops->alloc_sta(ref->priv, gfp); 77 return ref->ops->alloc_sta(ref->priv, sta, gfp);
106} 78}
107 79
108static inline void rate_control_free_sta(struct rate_control_ref *ref, 80static inline void rate_control_free_sta(struct sta_info *sta)
109 void *priv)
110{ 81{
111 ref->ops->free_sta(ref->priv, priv); 82 struct rate_control_ref *ref = sta->rate_ctrl;
83 struct ieee80211_sta *ista = &sta->sta;
84 void *priv_sta = sta->rate_ctrl_priv;
85
86 ref->ops->free_sta(ref->priv, ista, priv_sta);
112} 87}
113 88
114static inline void rate_control_add_sta_debugfs(struct sta_info *sta) 89static inline void rate_control_add_sta_debugfs(struct sta_info *sta)
@@ -130,31 +105,6 @@ static inline void rate_control_remove_sta_debugfs(struct sta_info *sta)
130#endif 105#endif
131} 106}
132 107
133static inline int rate_supported(struct sta_info *sta,
134 enum ieee80211_band band,
135 int index)
136{
137 return (sta == NULL || sta->supp_rates[band] & BIT(index));
138}
139
140static inline s8
141rate_lowest_index(struct ieee80211_local *local,
142 struct ieee80211_supported_band *sband,
143 struct sta_info *sta)
144{
145 int i;
146
147 for (i = 0; i < sband->n_bitrates; i++)
148 if (rate_supported(sta, sband->band, i))
149 return i;
150
151 /* warn when we cannot find a rate. */
152 WARN_ON(1);
153
154 return 0;
155}
156
157
158/* functions for rate control related to a device */ 108/* functions for rate control related to a device */
159int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local, 109int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local,
160 const char *name); 110 const char *name);
@@ -175,4 +125,18 @@ static inline void rc80211_pid_exit(void)
175} 125}
176#endif 126#endif
177 127
128#ifdef CONFIG_MAC80211_RC_MINSTREL
129extern int rc80211_minstrel_init(void);
130extern void rc80211_minstrel_exit(void);
131#else
132static inline int rc80211_minstrel_init(void)
133{
134 return 0;
135}
136static inline void rc80211_minstrel_exit(void)
137{
138}
139#endif
140
141
178#endif /* IEEE80211_RATE_H */ 142#endif /* IEEE80211_RATE_H */
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
new file mode 100644
index 000000000000..f6d69dab07a3
--- /dev/null
+++ b/net/mac80211/rc80211_minstrel.c
@@ -0,0 +1,583 @@
1/*
2 * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Based on minstrel.c:
9 * Copyright (C) 2005-2007 Derek Smithies <derek@indranet.co.nz>
10 * Sponsored by Indranet Technologies Ltd
11 *
12 * Based on sample.c:
13 * Copyright (c) 2005 John Bicket
14 * All rights reserved.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer,
21 * without modification.
22 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
23 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
24 * redistribution must be conditioned upon including a substantially
25 * similar Disclaimer requirement for further binary redistribution.
26 * 3. Neither the names of the above-listed copyright holders nor the names
27 * of any contributors may be used to endorse or promote products derived
28 * from this software without specific prior written permission.
29 *
30 * Alternatively, this software may be distributed under the terms of the
31 * GNU General Public License ("GPL") version 2 as published by the Free
32 * Software Foundation.
33 *
34 * NO WARRANTY
35 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
38 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
39 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
40 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
41 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
42 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
43 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
44 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
45 * THE POSSIBILITY OF SUCH DAMAGES.
46 */
47#include <linux/netdevice.h>
48#include <linux/types.h>
49#include <linux/skbuff.h>
50#include <linux/debugfs.h>
51#include <linux/random.h>
52#include <linux/ieee80211.h>
53#include <net/mac80211.h>
54#include "rate.h"
55#include "rc80211_minstrel.h"
56
57#define SAMPLE_COLUMNS 10
58#define SAMPLE_TBL(_mi, _idx, _col) \
59 _mi->sample_table[(_idx * SAMPLE_COLUMNS) + _col]
60
61/* convert mac80211 rate index to local array index */
62static inline int
63rix_to_ndx(struct minstrel_sta_info *mi, int rix)
64{
65 int i = rix;
66 for (i = rix; i >= 0; i--)
67 if (mi->r[i].rix == rix)
68 break;
69 WARN_ON(mi->r[i].rix != rix);
70 return i;
71}
72
73static inline bool
74use_low_rate(struct sk_buff *skb)
75{
76 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
77 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
78 u16 fc;
79
80 fc = le16_to_cpu(hdr->frame_control);
81
82 return ((info->flags & IEEE80211_TX_CTL_NO_ACK) ||
83 (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
84 is_multicast_ether_addr(hdr->addr1));
85}
86
87
88static void
89minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
90{
91 u32 max_tp = 0, index_max_tp = 0, index_max_tp2 = 0;
92 u32 max_prob = 0, index_max_prob = 0;
93 u32 usecs;
94 u32 p;
95 int i;
96
97 mi->stats_update = jiffies;
98 for (i = 0; i < mi->n_rates; i++) {
99 struct minstrel_rate *mr = &mi->r[i];
100
101 usecs = mr->perfect_tx_time;
102 if (!usecs)
103 usecs = 1000000;
104
105 /* To avoid rounding issues, probabilities scale from 0 (0%)
106 * to 18000 (100%) */
107 if (mr->attempts) {
108 p = (mr->success * 18000) / mr->attempts;
109 mr->succ_hist += mr->success;
110 mr->att_hist += mr->attempts;
111 mr->cur_prob = p;
112 p = ((p * (100 - mp->ewma_level)) + (mr->probability *
113 mp->ewma_level)) / 100;
114 mr->probability = p;
115 mr->cur_tp = p * (1000000 / usecs);
116 }
117
118 mr->last_success = mr->success;
119 mr->last_attempts = mr->attempts;
120 mr->success = 0;
121 mr->attempts = 0;
122
123 /* Sample less often below the 10% chance of success.
124 * Sample less often above the 95% chance of success. */
125 if ((mr->probability > 17100) || (mr->probability < 1800)) {
126 mr->adjusted_retry_count = mr->retry_count >> 1;
127 if (mr->adjusted_retry_count > 2)
128 mr->adjusted_retry_count = 2;
129 } else {
130 mr->adjusted_retry_count = mr->retry_count;
131 }
132 if (!mr->adjusted_retry_count)
133 mr->adjusted_retry_count = 2;
134 }
135
136 for (i = 0; i < mi->n_rates; i++) {
137 struct minstrel_rate *mr = &mi->r[i];
138 if (max_tp < mr->cur_tp) {
139 index_max_tp = i;
140 max_tp = mr->cur_tp;
141 }
142 if (max_prob < mr->probability) {
143 index_max_prob = i;
144 max_prob = mr->probability;
145 }
146 }
147
148 max_tp = 0;
149 for (i = 0; i < mi->n_rates; i++) {
150 struct minstrel_rate *mr = &mi->r[i];
151
152 if (i == index_max_tp)
153 continue;
154
155 if (max_tp < mr->cur_tp) {
156 index_max_tp2 = i;
157 max_tp = mr->cur_tp;
158 }
159 }
160 mi->max_tp_rate = index_max_tp;
161 mi->max_tp_rate2 = index_max_tp2;
162 mi->max_prob_rate = index_max_prob;
163}
164
165static void
166minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
167 struct ieee80211_sta *sta, void *priv_sta,
168 struct sk_buff *skb)
169{
170 struct minstrel_sta_info *mi = priv_sta;
171 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
172 struct ieee80211_tx_altrate *ar = info->status.retries;
173 struct minstrel_priv *mp = priv;
174 int i, ndx, tries;
175 int success = 0;
176
177 if (!info->status.excessive_retries)
178 success = 1;
179
180 if (!mp->has_mrr || (ar[0].rate_idx < 0)) {
181 ndx = rix_to_ndx(mi, info->tx_rate_idx);
182 tries = info->status.retry_count + 1;
183 mi->r[ndx].success += success;
184 mi->r[ndx].attempts += tries;
185 return;
186 }
187
188 for (i = 0; i < 4; i++) {
189 if (ar[i].rate_idx < 0)
190 break;
191
192 ndx = rix_to_ndx(mi, ar[i].rate_idx);
193 mi->r[ndx].attempts += ar[i].limit + 1;
194
195 if ((i != 3) && (ar[i + 1].rate_idx < 0))
196 mi->r[ndx].success += success;
197 }
198
199 if ((info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) && (i >= 0))
200 mi->sample_count++;
201
202 if (mi->sample_deferred > 0)
203 mi->sample_deferred--;
204}
205
206
207static inline unsigned int
208minstrel_get_retry_count(struct minstrel_rate *mr,
209 struct ieee80211_tx_info *info)
210{
211 unsigned int retry = mr->adjusted_retry_count;
212
213 if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
214 retry = max(2U, min(mr->retry_count_rtscts, retry));
215 else if (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT)
216 retry = max(2U, min(mr->retry_count_cts, retry));
217 return retry;
218}
219
220
221static int
222minstrel_get_next_sample(struct minstrel_sta_info *mi)
223{
224 unsigned int sample_ndx;
225 sample_ndx = SAMPLE_TBL(mi, mi->sample_idx, mi->sample_column);
226 mi->sample_idx++;
227 if (mi->sample_idx > (mi->n_rates - 2)) {
228 mi->sample_idx = 0;
229 mi->sample_column++;
230 if (mi->sample_column >= SAMPLE_COLUMNS)
231 mi->sample_column = 0;
232 }
233 return sample_ndx;
234}
235
236void
237minstrel_get_rate(void *priv, struct ieee80211_supported_band *sband,
238 struct ieee80211_sta *sta, void *priv_sta,
239 struct sk_buff *skb, struct rate_selection *sel)
240{
241 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
242 struct minstrel_sta_info *mi = priv_sta;
243 struct minstrel_priv *mp = priv;
244 struct ieee80211_tx_altrate *ar = info->control.retries;
245 unsigned int ndx, sample_ndx = 0;
246 bool mrr;
247 bool sample_slower = false;
248 bool sample = false;
249 int i, delta;
250 int mrr_ndx[3];
251 int sample_rate;
252
253 if (!sta || !mi || use_low_rate(skb)) {
254 sel->rate_idx = rate_lowest_index(sband, sta);
255 return;
256 }
257
258 mrr = mp->has_mrr;
259
260 /* mac80211 does not allow mrr for RTS/CTS */
261 if ((info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) ||
262 (info->flags & IEEE80211_TX_CTL_USE_CTS_PROTECT))
263 mrr = false;
264
265 if (time_after(jiffies, mi->stats_update + (mp->update_interval *
266 HZ) / 1000))
267 minstrel_update_stats(mp, mi);
268
269 ndx = mi->max_tp_rate;
270
271 if (mrr)
272 sample_rate = mp->lookaround_rate_mrr;
273 else
274 sample_rate = mp->lookaround_rate;
275
276 mi->packet_count++;
277 delta = (mi->packet_count * sample_rate / 100) -
278 (mi->sample_count + mi->sample_deferred / 2);
279
280 /* delta > 0: sampling required */
281 if (delta > 0) {
282 if (mi->packet_count >= 10000) {
283 mi->sample_deferred = 0;
284 mi->sample_count = 0;
285 mi->packet_count = 0;
286 } else if (delta > mi->n_rates * 2) {
287 /* With multi-rate retry, not every planned sample
288 * attempt actually gets used, due to the way the retry
289 * chain is set up - [max_tp,sample,prob,lowest] for
290 * sample_rate < max_tp.
291 *
292 * If there's too much sampling backlog and the link
293 * starts getting worse, minstrel would start bursting
294 * out lots of sampling frames, which would result
295 * in a large throughput loss. */
296 mi->sample_count += (delta - mi->n_rates * 2);
297 }
298
299 sample_ndx = minstrel_get_next_sample(mi);
300 sample = true;
301 sample_slower = mrr && (mi->r[sample_ndx].perfect_tx_time >
302 mi->r[ndx].perfect_tx_time);
303
304 if (!sample_slower) {
305 ndx = sample_ndx;
306 mi->sample_count++;
307 } else {
308 /* Only use IEEE80211_TX_CTL_RATE_CTRL_PROBE to mark
309 * packets that have the sampling rate deferred to the
310 * second MRR stage. Increase the sample counter only
311 * if the deferred sample rate was actually used.
312 * Use the sample_deferred counter to make sure that
313 * the sampling is not done in large bursts */
314 info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
315 mi->sample_deferred++;
316 }
317 }
318 sel->rate_idx = mi->r[ndx].rix;
319 info->control.retry_limit = minstrel_get_retry_count(&mi->r[ndx], info);
320
321 if (!mrr) {
322 ar[0].rate_idx = mi->lowest_rix;
323 ar[0].limit = mp->max_retry;
324 ar[1].rate_idx = -1;
325 return;
326 }
327
328 /* MRR setup */
329 if (sample) {
330 if (sample_slower)
331 mrr_ndx[0] = sample_ndx;
332 else
333 mrr_ndx[0] = mi->max_tp_rate;
334 } else {
335 mrr_ndx[0] = mi->max_tp_rate2;
336 }
337 mrr_ndx[1] = mi->max_prob_rate;
338 mrr_ndx[2] = 0;
339 for (i = 0; i < 3; i++) {
340 ar[i].rate_idx = mi->r[mrr_ndx[i]].rix;
341 ar[i].limit = mi->r[mrr_ndx[i]].adjusted_retry_count;
342 }
343}
344
345
346static void
347calc_rate_durations(struct minstrel_sta_info *mi, struct ieee80211_local *local,
348 struct minstrel_rate *d, struct ieee80211_rate *rate)
349{
350 int erp = !!(rate->flags & IEEE80211_RATE_ERP_G);
351
352 d->perfect_tx_time = ieee80211_frame_duration(local, 1200,
353 rate->bitrate, erp, 1);
354 d->ack_time = ieee80211_frame_duration(local, 10,
355 rate->bitrate, erp, 1);
356}
357
358static void
359init_sample_table(struct minstrel_sta_info *mi)
360{
361 unsigned int i, col, new_idx;
362 unsigned int n_srates = mi->n_rates - 1;
363 u8 rnd[8];
364
365 mi->sample_column = 0;
366 mi->sample_idx = 0;
367 memset(mi->sample_table, 0, SAMPLE_COLUMNS * mi->n_rates);
368
369 for (col = 0; col < SAMPLE_COLUMNS; col++) {
370 for (i = 0; i < n_srates; i++) {
371 get_random_bytes(rnd, sizeof(rnd));
372 new_idx = (i + rnd[i & 7]) % n_srates;
373
374 while (SAMPLE_TBL(mi, new_idx, col) != 0)
375 new_idx = (new_idx + 1) % n_srates;
376
377 /* Don't sample the slowest rate (i.e. slowest base
378 * rate). We must presume that the slowest rate works
379 * fine, or else other management frames will also be
380 * failing and the link will break */
381 SAMPLE_TBL(mi, new_idx, col) = i + 1;
382 }
383 }
384}
385
386static void
387minstrel_rate_init(void *priv, struct ieee80211_supported_band *sband,
388 struct ieee80211_sta *sta, void *priv_sta)
389{
390 struct minstrel_sta_info *mi = priv_sta;
391 struct minstrel_priv *mp = priv;
392 struct minstrel_rate *mr_ctl;
393 unsigned int i, n = 0;
394 unsigned int t_slot = 9; /* FIXME: get real slot time */
395
396 mi->lowest_rix = rate_lowest_index(sband, sta);
397 mr_ctl = &mi->r[rix_to_ndx(mi, mi->lowest_rix)];
398 mi->sp_ack_dur = mr_ctl->ack_time;
399
400 for (i = 0; i < sband->n_bitrates; i++) {
401 struct minstrel_rate *mr = &mi->r[n];
402 unsigned int tx_time = 0, tx_time_cts = 0, tx_time_rtscts = 0;
403 unsigned int tx_time_single;
404 unsigned int cw = mp->cw_min;
405
406 if (!rate_supported(sta, sband->band, i))
407 continue;
408 n++;
409 memset(mr, 0, sizeof(*mr));
410
411 mr->rix = i;
412 mr->bitrate = sband->bitrates[i].bitrate / 5;
413 calc_rate_durations(mi, hw_to_local(mp->hw), mr,
414 &sband->bitrates[i]);
415
416 /* calculate maximum number of retransmissions before
417 * fallback (based on maximum segment size) */
418 mr->retry_count = 1;
419 mr->retry_count_cts = 1;
420 mr->retry_count_rtscts = 1;
421 tx_time = mr->perfect_tx_time + mi->sp_ack_dur;
422 do {
423 /* add one retransmission */
424 tx_time_single = mr->ack_time + mr->perfect_tx_time;
425
426 /* contention window */
427 tx_time_single += t_slot + min(cw, mp->cw_max);
428 cw = (cw + 1) << 1;
429
430 tx_time += tx_time_single;
431 tx_time_cts += tx_time_single + mi->sp_ack_dur;
432 tx_time_rtscts += tx_time_single + 2 * mi->sp_ack_dur;
433 if ((tx_time_cts < mp->segment_size) &&
434 (mr->retry_count_cts < mp->max_retry))
435 mr->retry_count_cts++;
436 if ((tx_time_rtscts < mp->segment_size) &&
437 (mr->retry_count_rtscts < mp->max_retry))
438 mr->retry_count_rtscts++;
439 } while ((tx_time < mp->segment_size) &&
440 (++mr->retry_count < mp->max_retry));
441 mr->adjusted_retry_count = mr->retry_count;
442 }
443
444 for (i = n; i < sband->n_bitrates; i++) {
445 struct minstrel_rate *mr = &mi->r[i];
446 mr->rix = -1;
447 }
448
449 mi->n_rates = n;
450 mi->stats_update = jiffies;
451
452 init_sample_table(mi);
453}
454
455static void *
456minstrel_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp)
457{
458 struct ieee80211_supported_band *sband;
459 struct minstrel_sta_info *mi;
460 struct minstrel_priv *mp = priv;
461 struct ieee80211_hw *hw = mp->hw;
462 int max_rates = 0;
463 int i;
464
465 mi = kzalloc(sizeof(struct minstrel_sta_info), gfp);
466 if (!mi)
467 return NULL;
468
469 for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
470 sband = hw->wiphy->bands[hw->conf.channel->band];
471 if (sband->n_bitrates > max_rates)
472 max_rates = sband->n_bitrates;
473 }
474
475 mi->r = kzalloc(sizeof(struct minstrel_rate) * max_rates, gfp);
476 if (!mi->r)
477 goto error;
478
479 mi->sample_table = kmalloc(SAMPLE_COLUMNS * max_rates, gfp);
480 if (!mi->sample_table)
481 goto error1;
482
483 mi->stats_update = jiffies;
484 return mi;
485
486error1:
487 kfree(mi->r);
488error:
489 kfree(mi);
490 return NULL;
491}
492
493static void
494minstrel_free_sta(void *priv, struct ieee80211_sta *sta, void *priv_sta)
495{
496 struct minstrel_sta_info *mi = priv_sta;
497
498 kfree(mi->sample_table);
499 kfree(mi->r);
500 kfree(mi);
501}
502
503static void
504minstrel_clear(void *priv)
505{
506}
507
508static void *
509minstrel_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir)
510{
511 struct minstrel_priv *mp;
512
513 mp = kzalloc(sizeof(struct minstrel_priv), GFP_ATOMIC);
514 if (!mp)
515 return NULL;
516
517 /* contention window settings
518 * Just an approximation. Using the per-queue values would complicate
519 * the calculations and is probably unnecessary */
520 mp->cw_min = 15;
521 mp->cw_max = 1023;
522
523 /* number of packets (in %) to use for sampling other rates
524 * sample less often for non-mrr packets, because the overhead
525 * is much higher than with mrr */
526 mp->lookaround_rate = 5;
527 mp->lookaround_rate_mrr = 10;
528
529 /* moving average weight for EWMA */
530 mp->ewma_level = 75;
531
532 /* maximum time that the hw is allowed to stay in one MRR segment */
533 mp->segment_size = 6000;
534
535 if (hw->max_altrate_tries > 0)
536 mp->max_retry = hw->max_altrate_tries;
537 else
538 /* safe default, does not necessarily have to match hw properties */
539 mp->max_retry = 7;
540
541 if (hw->max_altrates >= 3)
542 mp->has_mrr = true;
543
544 mp->hw = hw;
545 mp->update_interval = 100;
546
547 return mp;
548}
549
550static void
551minstrel_free(void *priv)
552{
553 kfree(priv);
554}
555
556static struct rate_control_ops mac80211_minstrel = {
557 .name = "minstrel",
558 .tx_status = minstrel_tx_status,
559 .get_rate = minstrel_get_rate,
560 .rate_init = minstrel_rate_init,
561 .clear = minstrel_clear,
562 .alloc = minstrel_alloc,
563 .free = minstrel_free,
564 .alloc_sta = minstrel_alloc_sta,
565 .free_sta = minstrel_free_sta,
566#ifdef CONFIG_MAC80211_DEBUGFS
567 .add_sta_debugfs = minstrel_add_sta_debugfs,
568 .remove_sta_debugfs = minstrel_remove_sta_debugfs,
569#endif
570};
571
572int __init
573rc80211_minstrel_init(void)
574{
575 return ieee80211_rate_control_register(&mac80211_minstrel);
576}
577
578void
579rc80211_minstrel_exit(void)
580{
581 ieee80211_rate_control_unregister(&mac80211_minstrel);
582}
583
diff --git a/net/mac80211/rc80211_minstrel.h b/net/mac80211/rc80211_minstrel.h
new file mode 100644
index 000000000000..9a90a6aee043
--- /dev/null
+++ b/net/mac80211/rc80211_minstrel.h
@@ -0,0 +1,85 @@
1/*
2 * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef __RC_MINSTREL_H
10#define __RC_MINSTREL_H
11
12struct minstrel_rate {
13 int bitrate;
14 int rix;
15
16 unsigned int perfect_tx_time;
17 unsigned int ack_time;
18
19 unsigned int retry_count;
20 unsigned int retry_count_cts;
21 unsigned int retry_count_rtscts;
22 unsigned int adjusted_retry_count;
23
24 u32 success;
25 u32 attempts;
26 u32 last_attempts;
27 u32 last_success;
28
29 /* parts per thousand */
30 u32 cur_prob;
31 u32 probability;
32
33 /* per-rate throughput */
34 u32 cur_tp;
35 u32 throughput;
36
37 u64 succ_hist;
38 u64 att_hist;
39};
40
41struct minstrel_sta_info {
42 unsigned long stats_update;
43 unsigned int sp_ack_dur;
44 unsigned int rate_avg;
45
46 unsigned int lowest_rix;
47
48 unsigned int max_tp_rate;
49 unsigned int max_tp_rate2;
50 unsigned int max_prob_rate;
51 unsigned int packet_count;
52 unsigned int sample_count;
53 int sample_deferred;
54
55 unsigned int sample_idx;
56 unsigned int sample_column;
57
58 int n_rates;
59 struct minstrel_rate *r;
60
61 /* sampling table */
62 u8 *sample_table;
63
64#ifdef CONFIG_MAC80211_DEBUGFS
65 struct dentry *dbg_stats;
66#endif
67};
68
69struct minstrel_priv {
70 struct ieee80211_hw *hw;
71 bool has_mrr;
72 unsigned int cw_min;
73 unsigned int cw_max;
74 unsigned int max_retry;
75 unsigned int ewma_level;
76 unsigned int segment_size;
77 unsigned int update_interval;
78 unsigned int lookaround_rate;
79 unsigned int lookaround_rate_mrr;
80};
81
82void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir);
83void minstrel_remove_sta_debugfs(void *priv, void *priv_sta);
84
85#endif
diff --git a/net/mac80211/rc80211_minstrel_debugfs.c b/net/mac80211/rc80211_minstrel_debugfs.c
new file mode 100644
index 000000000000..0b024cd6b809
--- /dev/null
+++ b/net/mac80211/rc80211_minstrel_debugfs.c
@@ -0,0 +1,164 @@
1/*
2 * Copyright (C) 2008 Felix Fietkau <nbd@openwrt.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * Based on minstrel.c:
9 * Copyright (C) 2005-2007 Derek Smithies <derek@indranet.co.nz>
10 * Sponsored by Indranet Technologies Ltd
11 *
12 * Based on sample.c:
13 * Copyright (c) 2005 John Bicket
14 * All rights reserved.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer,
21 * without modification.
22 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
23 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
24 * redistribution must be conditioned upon including a substantially
25 * similar Disclaimer requirement for further binary redistribution.
26 * 3. Neither the names of the above-listed copyright holders nor the names
27 * of any contributors may be used to endorse or promote products derived
28 * from this software without specific prior written permission.
29 *
30 * Alternatively, this software may be distributed under the terms of the
31 * GNU General Public License ("GPL") version 2 as published by the Free
32 * Software Foundation.
33 *
34 * NO WARRANTY
35 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
38 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
39 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
40 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
41 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
42 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
43 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
44 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
45 * THE POSSIBILITY OF SUCH DAMAGES.
46 */
47#include <linux/netdevice.h>
48#include <linux/types.h>
49#include <linux/skbuff.h>
50#include <linux/debugfs.h>
51#include <linux/ieee80211.h>
52#include <net/mac80211.h>
53#include "rc80211_minstrel.h"
54
55struct minstrel_stats_info {
56 struct minstrel_sta_info *mi;
57 char buf[4096];
58 size_t len;
59};
60
61static int
62minstrel_stats_open(struct inode *inode, struct file *file)
63{
64 struct minstrel_sta_info *mi = inode->i_private;
65 struct minstrel_stats_info *ms;
66 unsigned int i, tp, prob, eprob;
67 char *p;
68
69 ms = kmalloc(sizeof(*ms), GFP_KERNEL);
70 if (!ms)
71 return -ENOMEM;
72
73 file->private_data = ms;
74 p = ms->buf;
75 p += sprintf(p, "rate throughput ewma prob this prob "
76 "this succ/attempt success attempts\n");
77 for (i = 0; i < mi->n_rates; i++) {
78 struct minstrel_rate *mr = &mi->r[i];
79
80 *(p++) = (i == mi->max_tp_rate) ? 'T' : ' ';
81 *(p++) = (i == mi->max_tp_rate2) ? 't' : ' ';
82 *(p++) = (i == mi->max_prob_rate) ? 'P' : ' ';
83 p += sprintf(p, "%3u%s", mr->bitrate / 2,
84 (mr->bitrate & 1 ? ".5" : " "));
85
86 tp = ((mr->cur_tp * 96) / 18000) >> 10;
87 prob = mr->cur_prob / 18;
88 eprob = mr->probability / 18;
89
90 p += sprintf(p, " %6u.%1u %6u.%1u %6u.%1u "
91 "%3u(%3u) %8llu %8llu\n",
92 tp / 10, tp % 10,
93 eprob / 10, eprob % 10,
94 prob / 10, prob % 10,
95 mr->last_success,
96 mr->last_attempts,
97 mr->succ_hist,
98 mr->att_hist);
99 }
100 p += sprintf(p, "\nTotal packet count:: ideal %d "
101 "lookaround %d\n\n",
102 mi->packet_count - mi->sample_count,
103 mi->sample_count);
104 ms->len = p - ms->buf;
105
106 return 0;
107}
108
109static int
110minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *o)
111{
112 struct minstrel_stats_info *ms;
113 char *src;
114
115 ms = file->private_data;
116 src = ms->buf;
117
118 len = min(len, ms->len);
119 if (len <= *o)
120 return 0;
121
122 src += *o;
123 len -= *o;
124 *o += len;
125
126 if (copy_to_user(buf, src, len))
127 return -EFAULT;
128
129 return len;
130}
131
132static int
133minstrel_stats_release(struct inode *inode, struct file *file)
134{
135 struct minstrel_stats_info *ms = file->private_data;
136
137 kfree(ms);
138
139 return 0;
140}
141
142static struct file_operations minstrel_stat_fops = {
143 .owner = THIS_MODULE,
144 .open = minstrel_stats_open,
145 .read = minstrel_stats_read,
146 .release = minstrel_stats_release,
147};
148
149void
150minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir)
151{
152 struct minstrel_sta_info *mi = priv_sta;
153
154 mi->dbg_stats = debugfs_create_file("rc_stats", S_IRUGO, dir, mi,
155 &minstrel_stat_fops);
156}
157
158void
159minstrel_remove_sta_debugfs(void *priv, void *priv_sta)
160{
161 struct minstrel_sta_info *mi = priv_sta;
162
163 debugfs_remove(mi->dbg_stats);
164}
diff --git a/net/mac80211/rc80211_pid.h b/net/mac80211/rc80211_pid.h
index 0a9135b974b5..01d64d53f3b9 100644
--- a/net/mac80211/rc80211_pid.h
+++ b/net/mac80211/rc80211_pid.h
@@ -124,7 +124,6 @@ struct rc_pid_events_file_info {
124 * struct rc_pid_debugfs_entries - tunable parameters 124 * struct rc_pid_debugfs_entries - tunable parameters
125 * 125 *
126 * Algorithm parameters, tunable via debugfs. 126 * Algorithm parameters, tunable via debugfs.
127 * @dir: the debugfs directory for a specific phy
128 * @target: target percentage for failed frames 127 * @target: target percentage for failed frames
129 * @sampling_period: error sampling interval in milliseconds 128 * @sampling_period: error sampling interval in milliseconds
130 * @coeff_p: absolute value of the proportional coefficient 129 * @coeff_p: absolute value of the proportional coefficient
@@ -143,7 +142,6 @@ struct rc_pid_events_file_info {
143 * ordering of rates) 142 * ordering of rates)
144 */ 143 */
145struct rc_pid_debugfs_entries { 144struct rc_pid_debugfs_entries {
146 struct dentry *dir;
147 struct dentry *target; 145 struct dentry *target;
148 struct dentry *sampling_period; 146 struct dentry *sampling_period;
149 struct dentry *coeff_p; 147 struct dentry *coeff_p;
@@ -180,6 +178,8 @@ struct rc_pid_sta_info {
180 u32 tx_num_failed; 178 u32 tx_num_failed;
181 u32 tx_num_xmit; 179 u32 tx_num_xmit;
182 180
181 int txrate_idx;
182
183 /* Average failed frames percentage error (i.e. actual vs. target 183 /* Average failed frames percentage error (i.e. actual vs. target
184 * percentage), scaled by RC_PID_SMOOTHING. This value is computed 184 * percentage), scaled by RC_PID_SMOOTHING. This value is computed
185 * using using an exponential weighted average technique: 185 * using using an exponential weighted average technique:
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c
index a914ba73ccf5..86eb374e3b87 100644
--- a/net/mac80211/rc80211_pid_algo.c
+++ b/net/mac80211/rc80211_pid_algo.c
@@ -68,17 +68,14 @@
68 * exhibited a worse failed frames behaviour and we'll choose the highest rate 68 * exhibited a worse failed frames behaviour and we'll choose the highest rate
69 * whose failed frames behaviour is not worse than the one of the original rate 69 * whose failed frames behaviour is not worse than the one of the original rate
70 * target. While at it, check that the new rate is valid. */ 70 * target. While at it, check that the new rate is valid. */
71static void rate_control_pid_adjust_rate(struct ieee80211_local *local, 71static void rate_control_pid_adjust_rate(struct ieee80211_supported_band *sband,
72 struct sta_info *sta, int adj, 72 struct ieee80211_sta *sta,
73 struct rc_pid_sta_info *spinfo, int adj,
73 struct rc_pid_rateinfo *rinfo) 74 struct rc_pid_rateinfo *rinfo)
74{ 75{
75 struct ieee80211_sub_if_data *sdata;
76 struct ieee80211_supported_band *sband;
77 int cur_sorted, new_sorted, probe, tmp, n_bitrates, band; 76 int cur_sorted, new_sorted, probe, tmp, n_bitrates, band;
78 int cur = sta->txrate_idx; 77 int cur = spinfo->txrate_idx;
79 78
80 sdata = sta->sdata;
81 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
82 band = sband->band; 79 band = sband->band;
83 n_bitrates = sband->n_bitrates; 80 n_bitrates = sband->n_bitrates;
84 81
@@ -111,7 +108,7 @@ static void rate_control_pid_adjust_rate(struct ieee80211_local *local,
111 /* Fit the rate found to the nearest supported rate. */ 108 /* Fit the rate found to the nearest supported rate. */
112 do { 109 do {
113 if (rate_supported(sta, band, rinfo[tmp].index)) { 110 if (rate_supported(sta, band, rinfo[tmp].index)) {
114 sta->txrate_idx = rinfo[tmp].index; 111 spinfo->txrate_idx = rinfo[tmp].index;
115 break; 112 break;
116 } 113 }
117 if (adj < 0) 114 if (adj < 0)
@@ -121,9 +118,9 @@ static void rate_control_pid_adjust_rate(struct ieee80211_local *local,
121 } while (tmp < n_bitrates && tmp >= 0); 118 } while (tmp < n_bitrates && tmp >= 0);
122 119
123#ifdef CONFIG_MAC80211_DEBUGFS 120#ifdef CONFIG_MAC80211_DEBUGFS
124 rate_control_pid_event_rate_change( 121 rate_control_pid_event_rate_change(&spinfo->events,
125 &((struct rc_pid_sta_info *)sta->rate_ctrl_priv)->events, 122 spinfo->txrate_idx,
126 sta->txrate_idx, sband->bitrates[sta->txrate_idx].bitrate); 123 sband->bitrates[spinfo->txrate_idx].bitrate);
127#endif 124#endif
128} 125}
129 126
@@ -145,15 +142,11 @@ static void rate_control_pid_normalize(struct rc_pid_info *pinfo, int l)
145} 142}
146 143
147static void rate_control_pid_sample(struct rc_pid_info *pinfo, 144static void rate_control_pid_sample(struct rc_pid_info *pinfo,
148 struct ieee80211_local *local, 145 struct ieee80211_supported_band *sband,
149 struct sta_info *sta) 146 struct ieee80211_sta *sta,
147 struct rc_pid_sta_info *spinfo)
150{ 148{
151#ifdef CONFIG_MAC80211_MESH
152 struct ieee80211_sub_if_data *sdata = sta->sdata;
153#endif
154 struct rc_pid_sta_info *spinfo = sta->rate_ctrl_priv;
155 struct rc_pid_rateinfo *rinfo = pinfo->rinfo; 149 struct rc_pid_rateinfo *rinfo = pinfo->rinfo;
156 struct ieee80211_supported_band *sband;
157 u32 pf; 150 u32 pf;
158 s32 err_avg; 151 s32 err_avg;
159 u32 err_prop; 152 u32 err_prop;
@@ -162,9 +155,6 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,
162 int adj, i, j, tmp; 155 int adj, i, j, tmp;
163 unsigned long period; 156 unsigned long period;
164 157
165 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
166 spinfo = sta->rate_ctrl_priv;
167
168 /* In case nothing happened during the previous control interval, turn 158 /* In case nothing happened during the previous control interval, turn
169 * the sharpening factor on. */ 159 * the sharpening factor on. */
170 period = (HZ * pinfo->sampling_period + 500) / 1000; 160 period = (HZ * pinfo->sampling_period + 500) / 1000;
@@ -180,14 +170,15 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,
180 if (unlikely(spinfo->tx_num_xmit == 0)) 170 if (unlikely(spinfo->tx_num_xmit == 0))
181 pf = spinfo->last_pf; 171 pf = spinfo->last_pf;
182 else { 172 else {
173 /* XXX: BAD HACK!!! */
174 struct sta_info *si = container_of(sta, struct sta_info, sta);
175
183 pf = spinfo->tx_num_failed * 100 / spinfo->tx_num_xmit; 176 pf = spinfo->tx_num_failed * 100 / spinfo->tx_num_xmit;
184#ifdef CONFIG_MAC80211_MESH 177
185 if (pf == 100 && 178 if (ieee80211_vif_is_mesh(&si->sdata->vif) && pf == 100)
186 sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT) 179 mesh_plink_broken(si);
187 mesh_plink_broken(sta);
188#endif
189 pf <<= RC_PID_ARITH_SHIFT; 180 pf <<= RC_PID_ARITH_SHIFT;
190 sta->fail_avg = ((pf + (spinfo->last_pf << 3)) / 9) 181 si->fail_avg = ((pf + (spinfo->last_pf << 3)) / 9)
191 >> RC_PID_ARITH_SHIFT; 182 >> RC_PID_ARITH_SHIFT;
192 } 183 }
193 184
@@ -195,16 +186,16 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,
195 spinfo->tx_num_failed = 0; 186 spinfo->tx_num_failed = 0;
196 187
197 /* If we just switched rate, update the rate behaviour info. */ 188 /* If we just switched rate, update the rate behaviour info. */
198 if (pinfo->oldrate != sta->txrate_idx) { 189 if (pinfo->oldrate != spinfo->txrate_idx) {
199 190
200 i = rinfo[pinfo->oldrate].rev_index; 191 i = rinfo[pinfo->oldrate].rev_index;
201 j = rinfo[sta->txrate_idx].rev_index; 192 j = rinfo[spinfo->txrate_idx].rev_index;
202 193
203 tmp = (pf - spinfo->last_pf); 194 tmp = (pf - spinfo->last_pf);
204 tmp = RC_PID_DO_ARITH_RIGHT_SHIFT(tmp, RC_PID_ARITH_SHIFT); 195 tmp = RC_PID_DO_ARITH_RIGHT_SHIFT(tmp, RC_PID_ARITH_SHIFT);
205 196
206 rinfo[j].diff = rinfo[i].diff + tmp; 197 rinfo[j].diff = rinfo[i].diff + tmp;
207 pinfo->oldrate = sta->txrate_idx; 198 pinfo->oldrate = spinfo->txrate_idx;
208 } 199 }
209 rate_control_pid_normalize(pinfo, sband->n_bitrates); 200 rate_control_pid_normalize(pinfo, sband->n_bitrates);
210 201
@@ -233,43 +224,26 @@ static void rate_control_pid_sample(struct rc_pid_info *pinfo,
233 224
234 /* Change rate. */ 225 /* Change rate. */
235 if (adj) 226 if (adj)
236 rate_control_pid_adjust_rate(local, sta, adj, rinfo); 227 rate_control_pid_adjust_rate(sband, sta, spinfo, adj, rinfo);
237} 228}
238 229
239static void rate_control_pid_tx_status(void *priv, struct net_device *dev, 230static void rate_control_pid_tx_status(void *priv, struct ieee80211_supported_band *sband,
231 struct ieee80211_sta *sta, void *priv_sta,
240 struct sk_buff *skb) 232 struct sk_buff *skb)
241{ 233{
242 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
243 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
244 struct ieee80211_sub_if_data *sdata;
245 struct rc_pid_info *pinfo = priv; 234 struct rc_pid_info *pinfo = priv;
246 struct sta_info *sta; 235 struct rc_pid_sta_info *spinfo = priv_sta;
247 struct rc_pid_sta_info *spinfo;
248 unsigned long period; 236 unsigned long period;
249 struct ieee80211_supported_band *sband;
250 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 237 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
251 238
252 rcu_read_lock(); 239 if (!spinfo)
253 240 return;
254 sta = sta_info_get(local, hdr->addr1);
255 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
256
257 if (!sta)
258 goto unlock;
259
260 /* Don't update the state if we're not controlling the rate. */
261 sdata = sta->sdata;
262 if (sdata->force_unicast_rateidx > -1) {
263 sta->txrate_idx = sdata->max_ratectrl_rateidx;
264 goto unlock;
265 }
266 241
267 /* Ignore all frames that were sent with a different rate than the rate 242 /* Ignore all frames that were sent with a different rate than the rate
268 * we currently advise mac80211 to use. */ 243 * we currently advise mac80211 to use. */
269 if (info->tx_rate_idx != sta->txrate_idx) 244 if (info->tx_rate_idx != spinfo->txrate_idx)
270 goto unlock; 245 return;
271 246
272 spinfo = sta->rate_ctrl_priv;
273 spinfo->tx_num_xmit++; 247 spinfo->tx_num_xmit++;
274 248
275#ifdef CONFIG_MAC80211_DEBUGFS 249#ifdef CONFIG_MAC80211_DEBUGFS
@@ -287,93 +261,68 @@ static void rate_control_pid_tx_status(void *priv, struct net_device *dev,
287 spinfo->tx_num_xmit++; 261 spinfo->tx_num_xmit++;
288 } 262 }
289 263
290 if (info->status.excessive_retries) {
291 sta->tx_retry_failed++;
292 sta->tx_num_consecutive_failures++;
293 sta->tx_num_mpdu_fail++;
294 } else {
295 sta->tx_num_consecutive_failures = 0;
296 sta->tx_num_mpdu_ok++;
297 }
298 sta->tx_retry_count += info->status.retry_count;
299 sta->tx_num_mpdu_fail += info->status.retry_count;
300
301 /* Update PID controller state. */ 264 /* Update PID controller state. */
302 period = (HZ * pinfo->sampling_period + 500) / 1000; 265 period = (HZ * pinfo->sampling_period + 500) / 1000;
303 if (!period) 266 if (!period)
304 period = 1; 267 period = 1;
305 if (time_after(jiffies, spinfo->last_sample + period)) 268 if (time_after(jiffies, spinfo->last_sample + period))
306 rate_control_pid_sample(pinfo, local, sta); 269 rate_control_pid_sample(pinfo, sband, sta, spinfo);
307
308 unlock:
309 rcu_read_unlock();
310} 270}
311 271
312static void rate_control_pid_get_rate(void *priv, struct net_device *dev, 272static void
313 struct ieee80211_supported_band *sband, 273rate_control_pid_get_rate(void *priv, struct ieee80211_supported_band *sband,
314 struct sk_buff *skb, 274 struct ieee80211_sta *sta, void *priv_sta,
315 struct rate_selection *sel) 275 struct sk_buff *skb,
276 struct rate_selection *sel)
316{ 277{
317 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
318 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 278 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
319 struct ieee80211_sub_if_data *sdata; 279 struct rc_pid_sta_info *spinfo = priv_sta;
320 struct sta_info *sta;
321 int rateidx; 280 int rateidx;
322 u16 fc; 281 u16 fc;
323 282
324 rcu_read_lock();
325
326 sta = sta_info_get(local, hdr->addr1);
327
328 /* Send management frames and broadcast/multicast data using lowest 283 /* Send management frames and broadcast/multicast data using lowest
329 * rate. */ 284 * rate. */
330 fc = le16_to_cpu(hdr->frame_control); 285 fc = le16_to_cpu(hdr->frame_control);
331 if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA || 286 if (!sta || !spinfo ||
332 is_multicast_ether_addr(hdr->addr1) || !sta) { 287 (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
333 sel->rate_idx = rate_lowest_index(local, sband, sta); 288 is_multicast_ether_addr(hdr->addr1)) {
334 rcu_read_unlock(); 289 sel->rate_idx = rate_lowest_index(sband, sta);
335 return; 290 return;
336 } 291 }
337 292
338 /* If a forced rate is in effect, select it. */ 293 rateidx = spinfo->txrate_idx;
339 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
340 if (sdata->force_unicast_rateidx > -1)
341 sta->txrate_idx = sdata->force_unicast_rateidx;
342
343 rateidx = sta->txrate_idx;
344 294
345 if (rateidx >= sband->n_bitrates) 295 if (rateidx >= sband->n_bitrates)
346 rateidx = sband->n_bitrates - 1; 296 rateidx = sband->n_bitrates - 1;
347 297
348 sta->last_txrate_idx = rateidx;
349
350 rcu_read_unlock();
351
352 sel->rate_idx = rateidx; 298 sel->rate_idx = rateidx;
353 299
354#ifdef CONFIG_MAC80211_DEBUGFS 300#ifdef CONFIG_MAC80211_DEBUGFS
355 rate_control_pid_event_tx_rate( 301 rate_control_pid_event_tx_rate(&spinfo->events,
356 &((struct rc_pid_sta_info *) sta->rate_ctrl_priv)->events,
357 rateidx, sband->bitrates[rateidx].bitrate); 302 rateidx, sband->bitrates[rateidx].bitrate);
358#endif 303#endif
359} 304}
360 305
361static void rate_control_pid_rate_init(void *priv, void *priv_sta, 306static void
362 struct ieee80211_local *local, 307rate_control_pid_rate_init(void *priv, struct ieee80211_supported_band *sband,
363 struct sta_info *sta) 308 struct ieee80211_sta *sta, void *priv_sta)
364{ 309{
310 struct rc_pid_sta_info *spinfo = priv_sta;
311 struct sta_info *si;
312
365 /* TODO: This routine should consider using RSSI from previous packets 313 /* TODO: This routine should consider using RSSI from previous packets
366 * as we need to have IEEE 802.1X auth succeed immediately after assoc.. 314 * as we need to have IEEE 802.1X auth succeed immediately after assoc..
367 * Until that method is implemented, we will use the lowest supported 315 * Until that method is implemented, we will use the lowest supported
368 * rate as a workaround. */ 316 * rate as a workaround. */
369 struct ieee80211_supported_band *sband;
370 317
371 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 318 spinfo->txrate_idx = rate_lowest_index(sband, sta);
372 sta->txrate_idx = rate_lowest_index(local, sband, sta); 319 /* HACK */
373 sta->fail_avg = 0; 320 si = container_of(sta, struct sta_info, sta);
321 si->fail_avg = 0;
374} 322}
375 323
376static void *rate_control_pid_alloc(struct ieee80211_local *local) 324static void *rate_control_pid_alloc(struct ieee80211_hw *hw,
325 struct dentry *debugfsdir)
377{ 326{
378 struct rc_pid_info *pinfo; 327 struct rc_pid_info *pinfo;
379 struct rc_pid_rateinfo *rinfo; 328 struct rc_pid_rateinfo *rinfo;
@@ -384,7 +333,7 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local)
384 struct rc_pid_debugfs_entries *de; 333 struct rc_pid_debugfs_entries *de;
385#endif 334#endif
386 335
387 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 336 sband = hw->wiphy->bands[hw->conf.channel->band];
388 337
389 pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC); 338 pinfo = kmalloc(sizeof(*pinfo), GFP_ATOMIC);
390 if (!pinfo) 339 if (!pinfo)
@@ -439,30 +388,28 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local)
439 388
440#ifdef CONFIG_MAC80211_DEBUGFS 389#ifdef CONFIG_MAC80211_DEBUGFS
441 de = &pinfo->dentries; 390 de = &pinfo->dentries;
442 de->dir = debugfs_create_dir("rc80211_pid",
443 local->hw.wiphy->debugfsdir);
444 de->target = debugfs_create_u32("target_pf", S_IRUSR | S_IWUSR, 391 de->target = debugfs_create_u32("target_pf", S_IRUSR | S_IWUSR,
445 de->dir, &pinfo->target); 392 debugfsdir, &pinfo->target);
446 de->sampling_period = debugfs_create_u32("sampling_period", 393 de->sampling_period = debugfs_create_u32("sampling_period",
447 S_IRUSR | S_IWUSR, de->dir, 394 S_IRUSR | S_IWUSR, debugfsdir,
448 &pinfo->sampling_period); 395 &pinfo->sampling_period);
449 de->coeff_p = debugfs_create_u32("coeff_p", S_IRUSR | S_IWUSR, 396 de->coeff_p = debugfs_create_u32("coeff_p", S_IRUSR | S_IWUSR,
450 de->dir, &pinfo->coeff_p); 397 debugfsdir, &pinfo->coeff_p);
451 de->coeff_i = debugfs_create_u32("coeff_i", S_IRUSR | S_IWUSR, 398 de->coeff_i = debugfs_create_u32("coeff_i", S_IRUSR | S_IWUSR,
452 de->dir, &pinfo->coeff_i); 399 debugfsdir, &pinfo->coeff_i);
453 de->coeff_d = debugfs_create_u32("coeff_d", S_IRUSR | S_IWUSR, 400 de->coeff_d = debugfs_create_u32("coeff_d", S_IRUSR | S_IWUSR,
454 de->dir, &pinfo->coeff_d); 401 debugfsdir, &pinfo->coeff_d);
455 de->smoothing_shift = debugfs_create_u32("smoothing_shift", 402 de->smoothing_shift = debugfs_create_u32("smoothing_shift",
456 S_IRUSR | S_IWUSR, de->dir, 403 S_IRUSR | S_IWUSR, debugfsdir,
457 &pinfo->smoothing_shift); 404 &pinfo->smoothing_shift);
458 de->sharpen_factor = debugfs_create_u32("sharpen_factor", 405 de->sharpen_factor = debugfs_create_u32("sharpen_factor",
459 S_IRUSR | S_IWUSR, de->dir, 406 S_IRUSR | S_IWUSR, debugfsdir,
460 &pinfo->sharpen_factor); 407 &pinfo->sharpen_factor);
461 de->sharpen_duration = debugfs_create_u32("sharpen_duration", 408 de->sharpen_duration = debugfs_create_u32("sharpen_duration",
462 S_IRUSR | S_IWUSR, de->dir, 409 S_IRUSR | S_IWUSR, debugfsdir,
463 &pinfo->sharpen_duration); 410 &pinfo->sharpen_duration);
464 de->norm_offset = debugfs_create_u32("norm_offset", 411 de->norm_offset = debugfs_create_u32("norm_offset",
465 S_IRUSR | S_IWUSR, de->dir, 412 S_IRUSR | S_IWUSR, debugfsdir,
466 &pinfo->norm_offset); 413 &pinfo->norm_offset);
467#endif 414#endif
468 415
@@ -484,7 +431,6 @@ static void rate_control_pid_free(void *priv)
484 debugfs_remove(de->coeff_p); 431 debugfs_remove(de->coeff_p);
485 debugfs_remove(de->sampling_period); 432 debugfs_remove(de->sampling_period);
486 debugfs_remove(de->target); 433 debugfs_remove(de->target);
487 debugfs_remove(de->dir);
488#endif 434#endif
489 435
490 kfree(pinfo->rinfo); 436 kfree(pinfo->rinfo);
@@ -495,7 +441,8 @@ static void rate_control_pid_clear(void *priv)
495{ 441{
496} 442}
497 443
498static void *rate_control_pid_alloc_sta(void *priv, gfp_t gfp) 444static void *rate_control_pid_alloc_sta(void *priv, struct ieee80211_sta *sta,
445 gfp_t gfp)
499{ 446{
500 struct rc_pid_sta_info *spinfo; 447 struct rc_pid_sta_info *spinfo;
501 448
@@ -513,10 +460,10 @@ static void *rate_control_pid_alloc_sta(void *priv, gfp_t gfp)
513 return spinfo; 460 return spinfo;
514} 461}
515 462
516static void rate_control_pid_free_sta(void *priv, void *priv_sta) 463static void rate_control_pid_free_sta(void *priv, struct ieee80211_sta *sta,
464 void *priv_sta)
517{ 465{
518 struct rc_pid_sta_info *spinfo = priv_sta; 466 kfree(priv_sta);
519 kfree(spinfo);
520} 467}
521 468
522static struct rate_control_ops mac80211_rcpid = { 469static struct rate_control_ops mac80211_rcpid = {
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 6db854505193..77e7b014872b 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -143,6 +143,8 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
143 /* IEEE80211_RADIOTAP_FLAGS */ 143 /* IEEE80211_RADIOTAP_FLAGS */
144 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) 144 if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS)
145 *pos |= IEEE80211_RADIOTAP_F_FCS; 145 *pos |= IEEE80211_RADIOTAP_F_FCS;
146 if (status->flag & RX_FLAG_SHORTPRE)
147 *pos |= IEEE80211_RADIOTAP_F_SHORTPRE;
146 pos++; 148 pos++;
147 149
148 /* IEEE80211_RADIOTAP_RATE */ 150 /* IEEE80211_RADIOTAP_RATE */
@@ -155,8 +157,11 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local,
155 if (status->band == IEEE80211_BAND_5GHZ) 157 if (status->band == IEEE80211_BAND_5GHZ)
156 *(__le16 *)pos = cpu_to_le16(IEEE80211_CHAN_OFDM | 158 *(__le16 *)pos = cpu_to_le16(IEEE80211_CHAN_OFDM |
157 IEEE80211_CHAN_5GHZ); 159 IEEE80211_CHAN_5GHZ);
160 else if (rate->flags & IEEE80211_RATE_ERP_G)
161 *(__le16 *)pos = cpu_to_le16(IEEE80211_CHAN_OFDM |
162 IEEE80211_CHAN_2GHZ);
158 else 163 else
159 *(__le16 *)pos = cpu_to_le16(IEEE80211_CHAN_DYN | 164 *(__le16 *)pos = cpu_to_le16(IEEE80211_CHAN_CCK |
160 IEEE80211_CHAN_2GHZ); 165 IEEE80211_CHAN_2GHZ);
161 pos += 2; 166 pos += 2;
162 167
@@ -290,7 +295,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
290 if (!netif_running(sdata->dev)) 295 if (!netif_running(sdata->dev))
291 continue; 296 continue;
292 297
293 if (sdata->vif.type != IEEE80211_IF_TYPE_MNTR) 298 if (sdata->vif.type != NL80211_IFTYPE_MONITOR)
294 continue; 299 continue;
295 300
296 if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES) 301 if (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES)
@@ -398,12 +403,12 @@ ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx)
398 struct ieee80211_local *local = rx->local; 403 struct ieee80211_local *local = rx->local;
399 struct sk_buff *skb = rx->skb; 404 struct sk_buff *skb = rx->skb;
400 405
401 if (unlikely(local->sta_hw_scanning)) 406 if (unlikely(local->hw_scanning))
402 return ieee80211_sta_rx_scan(rx->dev, skb, rx->status); 407 return ieee80211_scan_rx(rx->sdata, skb, rx->status);
403 408
404 if (unlikely(local->sta_sw_scanning)) { 409 if (unlikely(local->sw_scanning)) {
405 /* drop all the other packets during a software scan anyway */ 410 /* drop all the other packets during a software scan anyway */
406 if (ieee80211_sta_rx_scan(rx->dev, skb, rx->status) 411 if (ieee80211_scan_rx(rx->sdata, skb, rx->status)
407 != RX_QUEUED) 412 != RX_QUEUED)
408 dev_kfree_skb(skb); 413 dev_kfree_skb(skb);
409 return RX_QUEUED; 414 return RX_QUEUED;
@@ -461,7 +466,7 @@ ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
461 466
462 if (ieee80211_is_data(hdr->frame_control) && 467 if (ieee80211_is_data(hdr->frame_control) &&
463 is_multicast_ether_addr(hdr->addr1) && 468 is_multicast_ether_addr(hdr->addr1) &&
464 mesh_rmc_check(hdr->addr4, msh_h_get(hdr, hdrlen), rx->dev)) 469 mesh_rmc_check(hdr->addr4, msh_h_get(hdr, hdrlen), rx->sdata))
465 return RX_DROP_MONITOR; 470 return RX_DROP_MONITOR;
466#undef msh_h_get 471#undef msh_h_get
467 472
@@ -496,8 +501,8 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
496 /* Drop disallowed frame classes based on STA auth/assoc state; 501 /* Drop disallowed frame classes based on STA auth/assoc state;
497 * IEEE 802.11, Chap 5.5. 502 * IEEE 802.11, Chap 5.5.
498 * 503 *
499 * 80211.o does filtering only based on association state, i.e., it 504 * mac80211 filters only based on association state, i.e. it drops
500 * drops Class 3 frames from not associated stations. hostapd sends 505 * Class 3 frames from not associated stations. hostapd sends
501 * deauth/disassoc frames when needed. In addition, hostapd is 506 * deauth/disassoc frames when needed. In addition, hostapd is
502 * responsible for filtering on both auth and assoc states. 507 * responsible for filtering on both auth and assoc states.
503 */ 508 */
@@ -507,7 +512,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
507 512
508 if (unlikely((ieee80211_is_data(hdr->frame_control) || 513 if (unlikely((ieee80211_is_data(hdr->frame_control) ||
509 ieee80211_is_pspoll(hdr->frame_control)) && 514 ieee80211_is_pspoll(hdr->frame_control)) &&
510 rx->sdata->vif.type != IEEE80211_IF_TYPE_IBSS && 515 rx->sdata->vif.type != NL80211_IFTYPE_ADHOC &&
511 (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) { 516 (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) {
512 if ((!ieee80211_has_fromds(hdr->frame_control) && 517 if ((!ieee80211_has_fromds(hdr->frame_control) &&
513 !ieee80211_has_tods(hdr->frame_control) && 518 !ieee80211_has_tods(hdr->frame_control) &&
@@ -645,32 +650,28 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
645 return result; 650 return result;
646} 651}
647 652
648static void ap_sta_ps_start(struct net_device *dev, struct sta_info *sta) 653static void ap_sta_ps_start(struct sta_info *sta)
649{ 654{
650 struct ieee80211_sub_if_data *sdata; 655 struct ieee80211_sub_if_data *sdata = sta->sdata;
651 DECLARE_MAC_BUF(mac); 656 DECLARE_MAC_BUF(mac);
652 657
653 sdata = sta->sdata;
654
655 atomic_inc(&sdata->bss->num_sta_ps); 658 atomic_inc(&sdata->bss->num_sta_ps);
656 set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL); 659 set_and_clear_sta_flags(sta, WLAN_STA_PS, WLAN_STA_PSPOLL);
657#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 660#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
658 printk(KERN_DEBUG "%s: STA %s aid %d enters power save mode\n", 661 printk(KERN_DEBUG "%s: STA %s aid %d enters power save mode\n",
659 dev->name, print_mac(mac, sta->addr), sta->aid); 662 sdata->dev->name, print_mac(mac, sta->sta.addr), sta->sta.aid);
660#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 663#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
661} 664}
662 665
663static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta) 666static int ap_sta_ps_end(struct sta_info *sta)
664{ 667{
665 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 668 struct ieee80211_sub_if_data *sdata = sta->sdata;
669 struct ieee80211_local *local = sdata->local;
666 struct sk_buff *skb; 670 struct sk_buff *skb;
667 int sent = 0; 671 int sent = 0;
668 struct ieee80211_sub_if_data *sdata;
669 struct ieee80211_tx_info *info; 672 struct ieee80211_tx_info *info;
670 DECLARE_MAC_BUF(mac); 673 DECLARE_MAC_BUF(mac);
671 674
672 sdata = sta->sdata;
673
674 atomic_dec(&sdata->bss->num_sta_ps); 675 atomic_dec(&sdata->bss->num_sta_ps);
675 676
676 clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL); 677 clear_sta_flags(sta, WLAN_STA_PS | WLAN_STA_PSPOLL);
@@ -680,7 +681,7 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta)
680 681
681#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 682#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
682 printk(KERN_DEBUG "%s: STA %s aid %d exits power save mode\n", 683 printk(KERN_DEBUG "%s: STA %s aid %d exits power save mode\n",
683 dev->name, print_mac(mac, sta->addr), sta->aid); 684 sdata->dev->name, print_mac(mac, sta->sta.addr), sta->sta.aid);
684#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 685#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
685 686
686 /* Send all buffered frames to the station */ 687 /* Send all buffered frames to the station */
@@ -696,8 +697,8 @@ static int ap_sta_ps_end(struct net_device *dev, struct sta_info *sta)
696 sent++; 697 sent++;
697#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 698#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
698 printk(KERN_DEBUG "%s: STA %s aid %d send PS frame " 699 printk(KERN_DEBUG "%s: STA %s aid %d send PS frame "
699 "since STA not sleeping anymore\n", dev->name, 700 "since STA not sleeping anymore\n", sdata->dev->name,
700 print_mac(mac, sta->addr), sta->aid); 701 print_mac(mac, sta->sta.addr), sta->sta.aid);
701#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 702#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
702 info->flags |= IEEE80211_TX_CTL_REQUEUE; 703 info->flags |= IEEE80211_TX_CTL_REQUEUE;
703 dev_queue_xmit(skb); 704 dev_queue_xmit(skb);
@@ -710,7 +711,6 @@ static ieee80211_rx_result debug_noinline
710ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) 711ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
711{ 712{
712 struct sta_info *sta = rx->sta; 713 struct sta_info *sta = rx->sta;
713 struct net_device *dev = rx->dev;
714 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data; 714 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
715 715
716 if (!sta) 716 if (!sta)
@@ -719,14 +719,14 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
719 /* Update last_rx only for IBSS packets which are for the current 719 /* Update last_rx only for IBSS packets which are for the current
720 * BSSID to avoid keeping the current IBSS network alive in cases where 720 * BSSID to avoid keeping the current IBSS network alive in cases where
721 * other STAs are using different BSSID. */ 721 * other STAs are using different BSSID. */
722 if (rx->sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { 722 if (rx->sdata->vif.type == NL80211_IFTYPE_ADHOC) {
723 u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len, 723 u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len,
724 IEEE80211_IF_TYPE_IBSS); 724 NL80211_IFTYPE_ADHOC);
725 if (compare_ether_addr(bssid, rx->sdata->u.sta.bssid) == 0) 725 if (compare_ether_addr(bssid, rx->sdata->u.sta.bssid) == 0)
726 sta->last_rx = jiffies; 726 sta->last_rx = jiffies;
727 } else 727 } else
728 if (!is_multicast_ether_addr(hdr->addr1) || 728 if (!is_multicast_ether_addr(hdr->addr1) ||
729 rx->sdata->vif.type == IEEE80211_IF_TYPE_STA) { 729 rx->sdata->vif.type == NL80211_IFTYPE_STATION) {
730 /* Update last_rx only for unicast frames in order to prevent 730 /* Update last_rx only for unicast frames in order to prevent
731 * the Probe Request frames (the only broadcast frames from a 731 * the Probe Request frames (the only broadcast frames from a
732 * STA in infrastructure mode) from keeping a connection alive. 732 * STA in infrastructure mode) from keeping a connection alive.
@@ -746,16 +746,16 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
746 sta->last_noise = rx->status->noise; 746 sta->last_noise = rx->status->noise;
747 747
748 if (!ieee80211_has_morefrags(hdr->frame_control) && 748 if (!ieee80211_has_morefrags(hdr->frame_control) &&
749 (rx->sdata->vif.type == IEEE80211_IF_TYPE_AP || 749 (rx->sdata->vif.type == NL80211_IFTYPE_AP ||
750 rx->sdata->vif.type == IEEE80211_IF_TYPE_VLAN)) { 750 rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) {
751 /* Change STA power saving mode only in the end of a frame 751 /* Change STA power saving mode only in the end of a frame
752 * exchange sequence */ 752 * exchange sequence */
753 if (test_sta_flags(sta, WLAN_STA_PS) && 753 if (test_sta_flags(sta, WLAN_STA_PS) &&
754 !ieee80211_has_pm(hdr->frame_control)) 754 !ieee80211_has_pm(hdr->frame_control))
755 rx->sent_ps_buffered += ap_sta_ps_end(dev, sta); 755 rx->sent_ps_buffered += ap_sta_ps_end(sta);
756 else if (!test_sta_flags(sta, WLAN_STA_PS) && 756 else if (!test_sta_flags(sta, WLAN_STA_PS) &&
757 ieee80211_has_pm(hdr->frame_control)) 757 ieee80211_has_pm(hdr->frame_control))
758 ap_sta_ps_start(dev, sta); 758 ap_sta_ps_start(sta);
759 } 759 }
760 760
761 /* Drop data::nullfunc frames silently, since they are used only to 761 /* Drop data::nullfunc frames silently, since they are used only to
@@ -816,7 +816,7 @@ ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata,
816 816
817static inline struct ieee80211_fragment_entry * 817static inline struct ieee80211_fragment_entry *
818ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata, 818ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata,
819 u16 fc, unsigned int frag, unsigned int seq, 819 unsigned int frag, unsigned int seq,
820 int rx_queue, struct ieee80211_hdr *hdr) 820 int rx_queue, struct ieee80211_hdr *hdr)
821{ 821{
822 struct ieee80211_fragment_entry *entry; 822 struct ieee80211_fragment_entry *entry;
@@ -825,7 +825,6 @@ ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata,
825 idx = sdata->fragment_next; 825 idx = sdata->fragment_next;
826 for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) { 826 for (i = 0; i < IEEE80211_FRAGMENT_MAX; i++) {
827 struct ieee80211_hdr *f_hdr; 827 struct ieee80211_hdr *f_hdr;
828 u16 f_fc;
829 828
830 idx--; 829 idx--;
831 if (idx < 0) 830 if (idx < 0)
@@ -837,10 +836,13 @@ ieee80211_reassemble_find(struct ieee80211_sub_if_data *sdata,
837 entry->last_frag + 1 != frag) 836 entry->last_frag + 1 != frag)
838 continue; 837 continue;
839 838
840 f_hdr = (struct ieee80211_hdr *) entry->skb_list.next->data; 839 f_hdr = (struct ieee80211_hdr *)entry->skb_list.next->data;
841 f_fc = le16_to_cpu(f_hdr->frame_control);
842 840
843 if ((fc & IEEE80211_FCTL_FTYPE) != (f_fc & IEEE80211_FCTL_FTYPE) || 841 /*
842 * Check ftype and addresses are equal, else check next fragment
843 */
844 if (((hdr->frame_control ^ f_hdr->frame_control) &
845 cpu_to_le16(IEEE80211_FCTL_FTYPE)) ||
844 compare_ether_addr(hdr->addr1, f_hdr->addr1) != 0 || 846 compare_ether_addr(hdr->addr1, f_hdr->addr1) != 0 ||
845 compare_ether_addr(hdr->addr2, f_hdr->addr2) != 0) 847 compare_ether_addr(hdr->addr2, f_hdr->addr2) != 0)
846 continue; 848 continue;
@@ -860,16 +862,18 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
860{ 862{
861 struct ieee80211_hdr *hdr; 863 struct ieee80211_hdr *hdr;
862 u16 sc; 864 u16 sc;
865 __le16 fc;
863 unsigned int frag, seq; 866 unsigned int frag, seq;
864 struct ieee80211_fragment_entry *entry; 867 struct ieee80211_fragment_entry *entry;
865 struct sk_buff *skb; 868 struct sk_buff *skb;
866 DECLARE_MAC_BUF(mac); 869 DECLARE_MAC_BUF(mac);
867 870
868 hdr = (struct ieee80211_hdr *) rx->skb->data; 871 hdr = (struct ieee80211_hdr *)rx->skb->data;
872 fc = hdr->frame_control;
869 sc = le16_to_cpu(hdr->seq_ctrl); 873 sc = le16_to_cpu(hdr->seq_ctrl);
870 frag = sc & IEEE80211_SCTL_FRAG; 874 frag = sc & IEEE80211_SCTL_FRAG;
871 875
872 if (likely((!(rx->fc & IEEE80211_FCTL_MOREFRAGS) && frag == 0) || 876 if (likely((!ieee80211_has_morefrags(fc) && frag == 0) ||
873 (rx->skb)->len < 24 || 877 (rx->skb)->len < 24 ||
874 is_multicast_ether_addr(hdr->addr1))) { 878 is_multicast_ether_addr(hdr->addr1))) {
875 /* not fragmented */ 879 /* not fragmented */
@@ -884,7 +888,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
884 entry = ieee80211_reassemble_add(rx->sdata, frag, seq, 888 entry = ieee80211_reassemble_add(rx->sdata, frag, seq,
885 rx->queue, &(rx->skb)); 889 rx->queue, &(rx->skb));
886 if (rx->key && rx->key->conf.alg == ALG_CCMP && 890 if (rx->key && rx->key->conf.alg == ALG_CCMP &&
887 (rx->fc & IEEE80211_FCTL_PROTECTED)) { 891 ieee80211_has_protected(fc)) {
888 /* Store CCMP PN so that we can verify that the next 892 /* Store CCMP PN so that we can verify that the next
889 * fragment has a sequential PN value. */ 893 * fragment has a sequential PN value. */
890 entry->ccmp = 1; 894 entry->ccmp = 1;
@@ -898,8 +902,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
898 /* This is a fragment for a frame that should already be pending in 902 /* This is a fragment for a frame that should already be pending in
899 * fragment cache. Add this fragment to the end of the pending entry. 903 * fragment cache. Add this fragment to the end of the pending entry.
900 */ 904 */
901 entry = ieee80211_reassemble_find(rx->sdata, rx->fc, frag, seq, 905 entry = ieee80211_reassemble_find(rx->sdata, frag, seq, rx->queue, hdr);
902 rx->queue, hdr);
903 if (!entry) { 906 if (!entry) {
904 I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag); 907 I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag);
905 return RX_DROP_MONITOR; 908 return RX_DROP_MONITOR;
@@ -924,11 +927,11 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
924 memcpy(entry->last_pn, pn, CCMP_PN_LEN); 927 memcpy(entry->last_pn, pn, CCMP_PN_LEN);
925 } 928 }
926 929
927 skb_pull(rx->skb, ieee80211_get_hdrlen(rx->fc)); 930 skb_pull(rx->skb, ieee80211_hdrlen(fc));
928 __skb_queue_tail(&entry->skb_list, rx->skb); 931 __skb_queue_tail(&entry->skb_list, rx->skb);
929 entry->last_frag = frag; 932 entry->last_frag = frag;
930 entry->extra_len += rx->skb->len; 933 entry->extra_len += rx->skb->len;
931 if (rx->fc & IEEE80211_FCTL_MOREFRAGS) { 934 if (ieee80211_has_morefrags(fc)) {
932 rx->skb = NULL; 935 rx->skb = NULL;
933 return RX_QUEUED; 936 return RX_QUEUED;
934 } 937 }
@@ -968,15 +971,14 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx)
968 struct sk_buff *skb; 971 struct sk_buff *skb;
969 int no_pending_pkts; 972 int no_pending_pkts;
970 DECLARE_MAC_BUF(mac); 973 DECLARE_MAC_BUF(mac);
974 __le16 fc = ((struct ieee80211_hdr *)rx->skb->data)->frame_control;
971 975
972 if (likely(!rx->sta || 976 if (likely(!rx->sta || !ieee80211_is_pspoll(fc) ||
973 (rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_CTL ||
974 (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_PSPOLL ||
975 !(rx->flags & IEEE80211_RX_RA_MATCH))) 977 !(rx->flags & IEEE80211_RX_RA_MATCH)))
976 return RX_CONTINUE; 978 return RX_CONTINUE;
977 979
978 if ((sdata->vif.type != IEEE80211_IF_TYPE_AP) && 980 if ((sdata->vif.type != NL80211_IFTYPE_AP) &&
979 (sdata->vif.type != IEEE80211_IF_TYPE_VLAN)) 981 (sdata->vif.type != NL80211_IFTYPE_AP_VLAN))
980 return RX_DROP_UNUSABLE; 982 return RX_DROP_UNUSABLE;
981 983
982 skb = skb_dequeue(&rx->sta->tx_filtered); 984 skb = skb_dequeue(&rx->sta->tx_filtered);
@@ -1000,7 +1002,7 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx)
1000 1002
1001#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 1003#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
1002 printk(KERN_DEBUG "STA %s aid %d: PS Poll (entries after %d)\n", 1004 printk(KERN_DEBUG "STA %s aid %d: PS Poll (entries after %d)\n",
1003 print_mac(mac, rx->sta->addr), rx->sta->aid, 1005 print_mac(mac, rx->sta->sta.addr), rx->sta->sta.aid,
1004 skb_queue_len(&rx->sta->ps_tx_buf)); 1006 skb_queue_len(&rx->sta->ps_tx_buf));
1005#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 1007#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
1006 1008
@@ -1025,7 +1027,7 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx)
1025 */ 1027 */
1026 printk(KERN_DEBUG "%s: STA %s sent PS Poll even " 1028 printk(KERN_DEBUG "%s: STA %s sent PS Poll even "
1027 "though there are no buffered frames for it\n", 1029 "though there are no buffered frames for it\n",
1028 rx->dev->name, print_mac(mac, rx->sta->addr)); 1030 rx->dev->name, print_mac(mac, rx->sta->sta.addr));
1029#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 1031#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
1030 } 1032 }
1031 1033
@@ -1050,7 +1052,6 @@ ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx)
1050 ieee80211_hdrlen(hdr->frame_control) - IEEE80211_QOS_CTL_LEN); 1052 ieee80211_hdrlen(hdr->frame_control) - IEEE80211_QOS_CTL_LEN);
1051 hdr = (struct ieee80211_hdr *)skb_pull(rx->skb, IEEE80211_QOS_CTL_LEN); 1053 hdr = (struct ieee80211_hdr *)skb_pull(rx->skb, IEEE80211_QOS_CTL_LEN);
1052 /* change frame type to non QOS */ 1054 /* change frame type to non QOS */
1053 rx->fc &= ~IEEE80211_STYPE_QOS_DATA;
1054 hdr->frame_control &= ~cpu_to_le16(IEEE80211_STYPE_QOS_DATA); 1055 hdr->frame_control &= ~cpu_to_le16(IEEE80211_STYPE_QOS_DATA);
1055 1056
1056 return RX_CONTINUE; 1057 return RX_CONTINUE;
@@ -1067,7 +1068,7 @@ ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx)
1067} 1068}
1068 1069
1069static int 1070static int
1070ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx) 1071ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc)
1071{ 1072{
1072 /* 1073 /*
1073 * Pass through unencrypted frames if the hardware has 1074 * Pass through unencrypted frames if the hardware has
@@ -1077,9 +1078,8 @@ ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx)
1077 return 0; 1078 return 0;
1078 1079
1079 /* Drop unencrypted frames if key is set. */ 1080 /* Drop unencrypted frames if key is set. */
1080 if (unlikely(!(rx->fc & IEEE80211_FCTL_PROTECTED) && 1081 if (unlikely(!ieee80211_has_protected(fc) &&
1081 (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA && 1082 !ieee80211_is_nullfunc(fc) &&
1082 (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_NULLFUNC &&
1083 (rx->key || rx->sdata->drop_unencrypted))) 1083 (rx->key || rx->sdata->drop_unencrypted)))
1084 return -EACCES; 1084 return -EACCES;
1085 1085
@@ -1091,7 +1091,7 @@ ieee80211_data_to_8023(struct ieee80211_rx_data *rx)
1091{ 1091{
1092 struct net_device *dev = rx->dev; 1092 struct net_device *dev = rx->dev;
1093 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data; 1093 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) rx->skb->data;
1094 u16 fc, hdrlen, ethertype; 1094 u16 hdrlen, ethertype;
1095 u8 *payload; 1095 u8 *payload;
1096 u8 dst[ETH_ALEN]; 1096 u8 dst[ETH_ALEN];
1097 u8 src[ETH_ALEN] __aligned(2); 1097 u8 src[ETH_ALEN] __aligned(2);
@@ -1102,16 +1102,10 @@ ieee80211_data_to_8023(struct ieee80211_rx_data *rx)
1102 DECLARE_MAC_BUF(mac3); 1102 DECLARE_MAC_BUF(mac3);
1103 DECLARE_MAC_BUF(mac4); 1103 DECLARE_MAC_BUF(mac4);
1104 1104
1105 fc = rx->fc; 1105 if (unlikely(!ieee80211_is_data_present(hdr->frame_control)))
1106
1107 if (unlikely(!WLAN_FC_DATA_PRESENT(fc)))
1108 return -1; 1106 return -1;
1109 1107
1110 hdrlen = ieee80211_get_hdrlen(fc); 1108 hdrlen = ieee80211_hdrlen(hdr->frame_control);
1111
1112 if (ieee80211_vif_is_mesh(&sdata->vif))
1113 hdrlen += ieee80211_get_mesh_hdrlen(
1114 (struct ieee80211s_hdr *) (skb->data + hdrlen));
1115 1109
1116 /* convert IEEE 802.11 header + possible LLC headers into Ethernet 1110 /* convert IEEE 802.11 header + possible LLC headers into Ethernet
1117 * header 1111 * header
@@ -1122,42 +1116,38 @@ ieee80211_data_to_8023(struct ieee80211_rx_data *rx)
1122 * 1 0 BSSID SA DA n/a 1116 * 1 0 BSSID SA DA n/a
1123 * 1 1 RA TA DA SA 1117 * 1 1 RA TA DA SA
1124 */ 1118 */
1125 1119 memcpy(dst, ieee80211_get_DA(hdr), ETH_ALEN);
1126 switch (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) { 1120 memcpy(src, ieee80211_get_SA(hdr), ETH_ALEN);
1127 case IEEE80211_FCTL_TODS: 1121
1128 /* BSSID SA DA */ 1122 switch (hdr->frame_control &
1129 memcpy(dst, hdr->addr3, ETH_ALEN); 1123 cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) {
1130 memcpy(src, hdr->addr2, ETH_ALEN); 1124 case __constant_cpu_to_le16(IEEE80211_FCTL_TODS):
1131 1125 if (unlikely(sdata->vif.type != NL80211_IFTYPE_AP &&
1132 if (unlikely(sdata->vif.type != IEEE80211_IF_TYPE_AP && 1126 sdata->vif.type != NL80211_IFTYPE_AP_VLAN))
1133 sdata->vif.type != IEEE80211_IF_TYPE_VLAN))
1134 return -1; 1127 return -1;
1135 break; 1128 break;
1136 case (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS): 1129 case __constant_cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS):
1137 /* RA TA DA SA */ 1130 if (unlikely(sdata->vif.type != NL80211_IFTYPE_WDS &&
1138 memcpy(dst, hdr->addr3, ETH_ALEN); 1131 sdata->vif.type != NL80211_IFTYPE_MESH_POINT))
1139 memcpy(src, hdr->addr4, ETH_ALEN);
1140
1141 if (unlikely(sdata->vif.type != IEEE80211_IF_TYPE_WDS &&
1142 sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT))
1143 return -1; 1132 return -1;
1133 if (ieee80211_vif_is_mesh(&sdata->vif)) {
1134 struct ieee80211s_hdr *meshdr = (struct ieee80211s_hdr *)
1135 (skb->data + hdrlen);
1136 hdrlen += ieee80211_get_mesh_hdrlen(meshdr);
1137 if (meshdr->flags & MESH_FLAGS_AE_A5_A6) {
1138 memcpy(dst, meshdr->eaddr1, ETH_ALEN);
1139 memcpy(src, meshdr->eaddr2, ETH_ALEN);
1140 }
1141 }
1144 break; 1142 break;
1145 case IEEE80211_FCTL_FROMDS: 1143 case __constant_cpu_to_le16(IEEE80211_FCTL_FROMDS):
1146 /* DA BSSID SA */ 1144 if (sdata->vif.type != NL80211_IFTYPE_STATION ||
1147 memcpy(dst, hdr->addr1, ETH_ALEN);
1148 memcpy(src, hdr->addr3, ETH_ALEN);
1149
1150 if (sdata->vif.type != IEEE80211_IF_TYPE_STA ||
1151 (is_multicast_ether_addr(dst) && 1145 (is_multicast_ether_addr(dst) &&
1152 !compare_ether_addr(src, dev->dev_addr))) 1146 !compare_ether_addr(src, dev->dev_addr)))
1153 return -1; 1147 return -1;
1154 break; 1148 break;
1155 case 0: 1149 case __constant_cpu_to_le16(0):
1156 /* DA SA BSSID */ 1150 if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
1157 memcpy(dst, hdr->addr1, ETH_ALEN);
1158 memcpy(src, hdr->addr2, ETH_ALEN);
1159
1160 if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS)
1161 return -1; 1151 return -1;
1162 break; 1152 break;
1163 } 1153 }
@@ -1193,7 +1183,7 @@ ieee80211_data_to_8023(struct ieee80211_rx_data *rx)
1193/* 1183/*
1194 * requires that rx->skb is a frame with ethernet header 1184 * requires that rx->skb is a frame with ethernet header
1195 */ 1185 */
1196static bool ieee80211_frame_allowed(struct ieee80211_rx_data *rx) 1186static bool ieee80211_frame_allowed(struct ieee80211_rx_data *rx, __le16 fc)
1197{ 1187{
1198 static const u8 pae_group_addr[ETH_ALEN] __aligned(2) 1188 static const u8 pae_group_addr[ETH_ALEN] __aligned(2)
1199 = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x03 }; 1189 = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x03 };
@@ -1209,7 +1199,7 @@ static bool ieee80211_frame_allowed(struct ieee80211_rx_data *rx)
1209 return true; 1199 return true;
1210 1200
1211 if (ieee80211_802_1x_port_control(rx) || 1201 if (ieee80211_802_1x_port_control(rx) ||
1212 ieee80211_drop_unencrypted(rx)) 1202 ieee80211_drop_unencrypted(rx, fc))
1213 return false; 1203 return false;
1214 1204
1215 return true; 1205 return true;
@@ -1231,8 +1221,9 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx)
1231 skb = rx->skb; 1221 skb = rx->skb;
1232 xmit_skb = NULL; 1222 xmit_skb = NULL;
1233 1223
1234 if (local->bridge_packets && (sdata->vif.type == IEEE80211_IF_TYPE_AP || 1224 if ((sdata->vif.type == NL80211_IFTYPE_AP ||
1235 sdata->vif.type == IEEE80211_IF_TYPE_VLAN) && 1225 sdata->vif.type == NL80211_IFTYPE_AP_VLAN) &&
1226 !(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) &&
1236 (rx->flags & IEEE80211_RX_RA_MATCH)) { 1227 (rx->flags & IEEE80211_RX_RA_MATCH)) {
1237 if (is_multicast_ether_addr(ehdr->h_dest)) { 1228 if (is_multicast_ether_addr(ehdr->h_dest)) {
1238 /* 1229 /*
@@ -1279,20 +1270,21 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
1279{ 1270{
1280 struct net_device *dev = rx->dev; 1271 struct net_device *dev = rx->dev;
1281 struct ieee80211_local *local = rx->local; 1272 struct ieee80211_local *local = rx->local;
1282 u16 fc, ethertype; 1273 u16 ethertype;
1283 u8 *payload; 1274 u8 *payload;
1284 struct sk_buff *skb = rx->skb, *frame = NULL; 1275 struct sk_buff *skb = rx->skb, *frame = NULL;
1276 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1277 __le16 fc = hdr->frame_control;
1285 const struct ethhdr *eth; 1278 const struct ethhdr *eth;
1286 int remaining, err; 1279 int remaining, err;
1287 u8 dst[ETH_ALEN]; 1280 u8 dst[ETH_ALEN];
1288 u8 src[ETH_ALEN]; 1281 u8 src[ETH_ALEN];
1289 DECLARE_MAC_BUF(mac); 1282 DECLARE_MAC_BUF(mac);
1290 1283
1291 fc = rx->fc; 1284 if (unlikely(!ieee80211_is_data(fc)))
1292 if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA))
1293 return RX_CONTINUE; 1285 return RX_CONTINUE;
1294 1286
1295 if (unlikely(!WLAN_FC_DATA_PRESENT(fc))) 1287 if (unlikely(!ieee80211_is_data_present(fc)))
1296 return RX_DROP_MONITOR; 1288 return RX_DROP_MONITOR;
1297 1289
1298 if (!(rx->flags & IEEE80211_RX_AMSDU)) 1290 if (!(rx->flags & IEEE80211_RX_AMSDU))
@@ -1374,7 +1366,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
1374 memcpy(skb_push(frame, ETH_ALEN), dst, ETH_ALEN); 1366 memcpy(skb_push(frame, ETH_ALEN), dst, ETH_ALEN);
1375 } 1367 }
1376 1368
1377 if (!ieee80211_frame_allowed(rx)) { 1369 if (!ieee80211_frame_allowed(rx, fc)) {
1378 if (skb == frame) /* last frame */ 1370 if (skb == frame) /* last frame */
1379 return RX_DROP_UNUSABLE; 1371 return RX_DROP_UNUSABLE;
1380 dev_kfree_skb(frame); 1372 dev_kfree_skb(frame);
@@ -1387,7 +1379,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
1387 return RX_QUEUED; 1379 return RX_QUEUED;
1388} 1380}
1389 1381
1390static ieee80211_rx_result debug_noinline 1382static ieee80211_rx_result
1391ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) 1383ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
1392{ 1384{
1393 struct ieee80211_hdr *hdr; 1385 struct ieee80211_hdr *hdr;
@@ -1406,6 +1398,25 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
1406 /* illegal frame */ 1398 /* illegal frame */
1407 return RX_DROP_MONITOR; 1399 return RX_DROP_MONITOR;
1408 1400
1401 if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6){
1402 struct ieee80211_sub_if_data *sdata;
1403 struct mesh_path *mppath;
1404
1405 sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
1406 rcu_read_lock();
1407 mppath = mpp_path_lookup(mesh_hdr->eaddr2, sdata);
1408 if (!mppath) {
1409 mpp_path_add(mesh_hdr->eaddr2, hdr->addr4, sdata);
1410 } else {
1411 spin_lock_bh(&mppath->state_lock);
1412 mppath->exp_time = jiffies;
1413 if (compare_ether_addr(mppath->mpp, hdr->addr4) != 0)
1414 memcpy(mppath->mpp, hdr->addr4, ETH_ALEN);
1415 spin_unlock_bh(&mppath->state_lock);
1416 }
1417 rcu_read_unlock();
1418 }
1419
1409 if (compare_ether_addr(rx->dev->dev_addr, hdr->addr3) == 0) 1420 if (compare_ether_addr(rx->dev->dev_addr, hdr->addr3) == 0)
1410 return RX_CONTINUE; 1421 return RX_CONTINUE;
1411 1422
@@ -1413,7 +1424,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
1413 1424
1414 if (rx->flags & IEEE80211_RX_RA_MATCH) { 1425 if (rx->flags & IEEE80211_RX_RA_MATCH) {
1415 if (!mesh_hdr->ttl) 1426 if (!mesh_hdr->ttl)
1416 IEEE80211_IFSTA_MESH_CTR_INC(&rx->sdata->u.sta, 1427 IEEE80211_IFSTA_MESH_CTR_INC(&rx->sdata->u.mesh,
1417 dropped_frames_ttl); 1428 dropped_frames_ttl);
1418 else { 1429 else {
1419 struct ieee80211_hdr *fwd_hdr; 1430 struct ieee80211_hdr *fwd_hdr;
@@ -1448,21 +1459,21 @@ static ieee80211_rx_result debug_noinline
1448ieee80211_rx_h_data(struct ieee80211_rx_data *rx) 1459ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
1449{ 1460{
1450 struct net_device *dev = rx->dev; 1461 struct net_device *dev = rx->dev;
1451 u16 fc; 1462 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
1463 __le16 fc = hdr->frame_control;
1452 int err; 1464 int err;
1453 1465
1454 fc = rx->fc; 1466 if (unlikely(!ieee80211_is_data(hdr->frame_control)))
1455 if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA))
1456 return RX_CONTINUE; 1467 return RX_CONTINUE;
1457 1468
1458 if (unlikely(!WLAN_FC_DATA_PRESENT(fc))) 1469 if (unlikely(!ieee80211_is_data_present(hdr->frame_control)))
1459 return RX_DROP_MONITOR; 1470 return RX_DROP_MONITOR;
1460 1471
1461 err = ieee80211_data_to_8023(rx); 1472 err = ieee80211_data_to_8023(rx);
1462 if (unlikely(err)) 1473 if (unlikely(err))
1463 return RX_DROP_UNUSABLE; 1474 return RX_DROP_UNUSABLE;
1464 1475
1465 if (!ieee80211_frame_allowed(rx)) 1476 if (!ieee80211_frame_allowed(rx, fc))
1466 return RX_DROP_MONITOR; 1477 return RX_DROP_MONITOR;
1467 1478
1468 rx->skb->dev = dev; 1479 rx->skb->dev = dev;
@@ -1520,22 +1531,97 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx)
1520} 1531}
1521 1532
1522static ieee80211_rx_result debug_noinline 1533static ieee80211_rx_result debug_noinline
1534ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
1535{
1536 struct ieee80211_local *local = rx->local;
1537 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
1538 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data;
1539 int len = rx->skb->len;
1540
1541 if (!ieee80211_is_action(mgmt->frame_control))
1542 return RX_CONTINUE;
1543
1544 if (!rx->sta)
1545 return RX_DROP_MONITOR;
1546
1547 if (!(rx->flags & IEEE80211_RX_RA_MATCH))
1548 return RX_DROP_MONITOR;
1549
1550 /* all categories we currently handle have action_code */
1551 if (len < IEEE80211_MIN_ACTION_SIZE + 1)
1552 return RX_DROP_MONITOR;
1553
1554 /*
1555 * FIXME: revisit this, I'm sure we should handle most
1556 * of these frames in other modes as well!
1557 */
1558 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
1559 sdata->vif.type != NL80211_IFTYPE_ADHOC)
1560 return RX_CONTINUE;
1561
1562 switch (mgmt->u.action.category) {
1563 case WLAN_CATEGORY_BACK:
1564 switch (mgmt->u.action.u.addba_req.action_code) {
1565 case WLAN_ACTION_ADDBA_REQ:
1566 if (len < (IEEE80211_MIN_ACTION_SIZE +
1567 sizeof(mgmt->u.action.u.addba_req)))
1568 return RX_DROP_MONITOR;
1569 ieee80211_process_addba_request(local, rx->sta, mgmt, len);
1570 break;
1571 case WLAN_ACTION_ADDBA_RESP:
1572 if (len < (IEEE80211_MIN_ACTION_SIZE +
1573 sizeof(mgmt->u.action.u.addba_resp)))
1574 return RX_DROP_MONITOR;
1575 ieee80211_process_addba_resp(local, rx->sta, mgmt, len);
1576 break;
1577 case WLAN_ACTION_DELBA:
1578 if (len < (IEEE80211_MIN_ACTION_SIZE +
1579 sizeof(mgmt->u.action.u.delba)))
1580 return RX_DROP_MONITOR;
1581 ieee80211_process_delba(sdata, rx->sta, mgmt, len);
1582 break;
1583 }
1584 break;
1585 case WLAN_CATEGORY_SPECTRUM_MGMT:
1586 if (local->hw.conf.channel->band != IEEE80211_BAND_5GHZ)
1587 return RX_DROP_MONITOR;
1588 switch (mgmt->u.action.u.measurement.action_code) {
1589 case WLAN_ACTION_SPCT_MSR_REQ:
1590 if (len < (IEEE80211_MIN_ACTION_SIZE +
1591 sizeof(mgmt->u.action.u.measurement)))
1592 return RX_DROP_MONITOR;
1593 ieee80211_process_measurement_req(sdata, mgmt, len);
1594 break;
1595 }
1596 break;
1597 default:
1598 return RX_CONTINUE;
1599 }
1600
1601 rx->sta->rx_packets++;
1602 dev_kfree_skb(rx->skb);
1603 return RX_QUEUED;
1604}
1605
1606static ieee80211_rx_result debug_noinline
1523ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) 1607ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
1524{ 1608{
1525 struct ieee80211_sub_if_data *sdata; 1609 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
1526 1610
1527 if (!(rx->flags & IEEE80211_RX_RA_MATCH)) 1611 if (!(rx->flags & IEEE80211_RX_RA_MATCH))
1528 return RX_DROP_MONITOR; 1612 return RX_DROP_MONITOR;
1529 1613
1530 sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); 1614 if (ieee80211_vif_is_mesh(&sdata->vif))
1531 if ((sdata->vif.type == IEEE80211_IF_TYPE_STA || 1615 return ieee80211_mesh_rx_mgmt(sdata, rx->skb, rx->status);
1532 sdata->vif.type == IEEE80211_IF_TYPE_IBSS || 1616
1533 sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT) && 1617 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
1534 !(sdata->flags & IEEE80211_SDATA_USERSPACE_MLME)) 1618 sdata->vif.type != NL80211_IFTYPE_ADHOC)
1535 ieee80211_sta_rx_mgmt(rx->dev, rx->skb, rx->status); 1619 return RX_DROP_MONITOR;
1536 else 1620
1621 if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME)
1537 return RX_DROP_MONITOR; 1622 return RX_DROP_MONITOR;
1538 1623
1624 ieee80211_sta_rx_mgmt(sdata, rx->skb, rx->status);
1539 return RX_QUEUED; 1625 return RX_QUEUED;
1540} 1626}
1541 1627
@@ -1565,7 +1651,7 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev,
1565 if (!ieee80211_has_protected(hdr->frame_control)) 1651 if (!ieee80211_has_protected(hdr->frame_control))
1566 goto ignore; 1652 goto ignore;
1567 1653
1568 if (rx->sdata->vif.type == IEEE80211_IF_TYPE_AP && keyidx) { 1654 if (rx->sdata->vif.type == NL80211_IFTYPE_AP && keyidx) {
1569 /* 1655 /*
1570 * APs with pairwise keys should never receive Michael MIC 1656 * APs with pairwise keys should never receive Michael MIC
1571 * errors for non-zero keyidx because these are reserved for 1657 * errors for non-zero keyidx because these are reserved for
@@ -1579,7 +1665,7 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev,
1579 !ieee80211_is_auth(hdr->frame_control)) 1665 !ieee80211_is_auth(hdr->frame_control))
1580 goto ignore; 1666 goto ignore;
1581 1667
1582 mac80211_ev_michael_mic_failure(rx->dev, keyidx, hdr); 1668 mac80211_ev_michael_mic_failure(rx->sdata, keyidx, hdr);
1583 ignore: 1669 ignore:
1584 dev_kfree_skb(rx->skb); 1670 dev_kfree_skb(rx->skb);
1585 rx->skb = NULL; 1671 rx->skb = NULL;
@@ -1635,7 +1721,7 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx)
1635 if (!netif_running(sdata->dev)) 1721 if (!netif_running(sdata->dev))
1636 continue; 1722 continue;
1637 1723
1638 if (sdata->vif.type != IEEE80211_IF_TYPE_MNTR || 1724 if (sdata->vif.type != NL80211_IFTYPE_MONITOR ||
1639 !(sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES)) 1725 !(sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES))
1640 continue; 1726 continue;
1641 1727
@@ -1698,6 +1784,7 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
1698 CALL_RXH(ieee80211_rx_h_mesh_fwding); 1784 CALL_RXH(ieee80211_rx_h_mesh_fwding);
1699 CALL_RXH(ieee80211_rx_h_data) 1785 CALL_RXH(ieee80211_rx_h_data)
1700 CALL_RXH(ieee80211_rx_h_ctrl) 1786 CALL_RXH(ieee80211_rx_h_ctrl)
1787 CALL_RXH(ieee80211_rx_h_action)
1701 CALL_RXH(ieee80211_rx_h_mgmt) 1788 CALL_RXH(ieee80211_rx_h_mgmt)
1702 1789
1703#undef CALL_RXH 1790#undef CALL_RXH
@@ -1733,7 +1820,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
1733 int multicast = is_multicast_ether_addr(hdr->addr1); 1820 int multicast = is_multicast_ether_addr(hdr->addr1);
1734 1821
1735 switch (sdata->vif.type) { 1822 switch (sdata->vif.type) {
1736 case IEEE80211_IF_TYPE_STA: 1823 case NL80211_IFTYPE_STATION:
1737 if (!bssid) 1824 if (!bssid)
1738 return 0; 1825 return 0;
1739 if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) { 1826 if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) {
@@ -1748,14 +1835,10 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
1748 rx->flags &= ~IEEE80211_RX_RA_MATCH; 1835 rx->flags &= ~IEEE80211_RX_RA_MATCH;
1749 } 1836 }
1750 break; 1837 break;
1751 case IEEE80211_IF_TYPE_IBSS: 1838 case NL80211_IFTYPE_ADHOC:
1752 if (!bssid) 1839 if (!bssid)
1753 return 0; 1840 return 0;
1754 if (ieee80211_is_beacon(hdr->frame_control)) { 1841 if (ieee80211_is_beacon(hdr->frame_control)) {
1755 if (!rx->sta)
1756 rx->sta = ieee80211_ibss_add_sta(sdata->dev,
1757 rx->skb, bssid, hdr->addr2,
1758 BIT(rx->status->rate_idx));
1759 return 1; 1842 return 1;
1760 } 1843 }
1761 else if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) { 1844 else if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) {
@@ -1769,11 +1852,11 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
1769 return 0; 1852 return 0;
1770 rx->flags &= ~IEEE80211_RX_RA_MATCH; 1853 rx->flags &= ~IEEE80211_RX_RA_MATCH;
1771 } else if (!rx->sta) 1854 } else if (!rx->sta)
1772 rx->sta = ieee80211_ibss_add_sta(sdata->dev, rx->skb, 1855 rx->sta = ieee80211_ibss_add_sta(sdata, rx->skb,
1773 bssid, hdr->addr2, 1856 bssid, hdr->addr2,
1774 BIT(rx->status->rate_idx)); 1857 BIT(rx->status->rate_idx));
1775 break; 1858 break;
1776 case IEEE80211_IF_TYPE_MESH_POINT: 1859 case NL80211_IFTYPE_MESH_POINT:
1777 if (!multicast && 1860 if (!multicast &&
1778 compare_ether_addr(sdata->dev->dev_addr, 1861 compare_ether_addr(sdata->dev->dev_addr,
1779 hdr->addr1) != 0) { 1862 hdr->addr1) != 0) {
@@ -1783,8 +1866,8 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
1783 rx->flags &= ~IEEE80211_RX_RA_MATCH; 1866 rx->flags &= ~IEEE80211_RX_RA_MATCH;
1784 } 1867 }
1785 break; 1868 break;
1786 case IEEE80211_IF_TYPE_VLAN: 1869 case NL80211_IFTYPE_AP_VLAN:
1787 case IEEE80211_IF_TYPE_AP: 1870 case NL80211_IFTYPE_AP:
1788 if (!bssid) { 1871 if (!bssid) {
1789 if (compare_ether_addr(sdata->dev->dev_addr, 1872 if (compare_ether_addr(sdata->dev->dev_addr,
1790 hdr->addr1)) 1873 hdr->addr1))
@@ -1796,16 +1879,17 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
1796 rx->flags &= ~IEEE80211_RX_RA_MATCH; 1879 rx->flags &= ~IEEE80211_RX_RA_MATCH;
1797 } 1880 }
1798 break; 1881 break;
1799 case IEEE80211_IF_TYPE_WDS: 1882 case NL80211_IFTYPE_WDS:
1800 if (bssid || !ieee80211_is_data(hdr->frame_control)) 1883 if (bssid || !ieee80211_is_data(hdr->frame_control))
1801 return 0; 1884 return 0;
1802 if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2)) 1885 if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2))
1803 return 0; 1886 return 0;
1804 break; 1887 break;
1805 case IEEE80211_IF_TYPE_MNTR: 1888 case NL80211_IFTYPE_MONITOR:
1806 /* take everything */ 1889 /* take everything */
1807 break; 1890 break;
1808 case IEEE80211_IF_TYPE_INVALID: 1891 case NL80211_IFTYPE_UNSPECIFIED:
1892 case __NL80211_IFTYPE_AFTER_LAST:
1809 /* should never get here */ 1893 /* should never get here */
1810 WARN_ON(1); 1894 WARN_ON(1);
1811 break; 1895 break;
@@ -1827,23 +1911,20 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
1827 struct ieee80211_sub_if_data *sdata; 1911 struct ieee80211_sub_if_data *sdata;
1828 struct ieee80211_hdr *hdr; 1912 struct ieee80211_hdr *hdr;
1829 struct ieee80211_rx_data rx; 1913 struct ieee80211_rx_data rx;
1830 u16 type;
1831 int prepares; 1914 int prepares;
1832 struct ieee80211_sub_if_data *prev = NULL; 1915 struct ieee80211_sub_if_data *prev = NULL;
1833 struct sk_buff *skb_new; 1916 struct sk_buff *skb_new;
1834 u8 *bssid; 1917 u8 *bssid;
1835 1918
1836 hdr = (struct ieee80211_hdr *) skb->data; 1919 hdr = (struct ieee80211_hdr *)skb->data;
1837 memset(&rx, 0, sizeof(rx)); 1920 memset(&rx, 0, sizeof(rx));
1838 rx.skb = skb; 1921 rx.skb = skb;
1839 rx.local = local; 1922 rx.local = local;
1840 1923
1841 rx.status = status; 1924 rx.status = status;
1842 rx.rate = rate; 1925 rx.rate = rate;
1843 rx.fc = le16_to_cpu(hdr->frame_control);
1844 type = rx.fc & IEEE80211_FCTL_FTYPE;
1845 1926
1846 if (type == IEEE80211_FTYPE_DATA || type == IEEE80211_FTYPE_MGMT) 1927 if (ieee80211_is_data(hdr->frame_control) || ieee80211_is_mgmt(hdr->frame_control))
1847 local->dot11ReceivedFragmentCount++; 1928 local->dot11ReceivedFragmentCount++;
1848 1929
1849 rx.sta = sta_info_get(local, hdr->addr2); 1930 rx.sta = sta_info_get(local, hdr->addr2);
@@ -1857,7 +1938,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
1857 return; 1938 return;
1858 } 1939 }
1859 1940
1860 if (unlikely(local->sta_sw_scanning || local->sta_hw_scanning)) 1941 if (unlikely(local->sw_scanning || local->hw_scanning))
1861 rx.flags |= IEEE80211_RX_IN_SCAN; 1942 rx.flags |= IEEE80211_RX_IN_SCAN;
1862 1943
1863 ieee80211_parse_qos(&rx); 1944 ieee80211_parse_qos(&rx);
@@ -1869,7 +1950,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
1869 if (!netif_running(sdata->dev)) 1950 if (!netif_running(sdata->dev))
1870 continue; 1951 continue;
1871 1952
1872 if (sdata->vif.type == IEEE80211_IF_TYPE_MNTR) 1953 if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
1873 continue; 1954 continue;
1874 1955
1875 bssid = ieee80211_get_bssid(hdr, skb->len, sdata->vif.type); 1956 bssid = ieee80211_get_bssid(hdr, skb->len, sdata->vif.type);
@@ -1904,14 +1985,12 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
1904 prev->dev->name); 1985 prev->dev->name);
1905 continue; 1986 continue;
1906 } 1987 }
1907 rx.fc = le16_to_cpu(hdr->frame_control);
1908 ieee80211_invoke_rx_handlers(prev, &rx, skb_new); 1988 ieee80211_invoke_rx_handlers(prev, &rx, skb_new);
1909 prev = sdata; 1989 prev = sdata;
1910 } 1990 }
1911 if (prev) { 1991 if (prev)
1912 rx.fc = le16_to_cpu(hdr->frame_control);
1913 ieee80211_invoke_rx_handlers(prev, &rx, skb); 1992 ieee80211_invoke_rx_handlers(prev, &rx, skb);
1914 } else 1993 else
1915 dev_kfree_skb(skb); 1994 dev_kfree_skb(skb);
1916} 1995}
1917 1996
@@ -2080,7 +2159,7 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local,
2080 /* if this mpdu is fragmented - terminate rx aggregation session */ 2159 /* if this mpdu is fragmented - terminate rx aggregation session */
2081 sc = le16_to_cpu(hdr->seq_ctrl); 2160 sc = le16_to_cpu(hdr->seq_ctrl);
2082 if (sc & IEEE80211_SCTL_FRAG) { 2161 if (sc & IEEE80211_SCTL_FRAG) {
2083 ieee80211_sta_stop_rx_ba_session(sta->sdata->dev, sta->addr, 2162 ieee80211_sta_stop_rx_ba_session(sta->sdata, sta->sta.addr,
2084 tid, 0, WLAN_REASON_QSTA_REQUIRE_SETUP); 2163 tid, 0, WLAN_REASON_QSTA_REQUIRE_SETUP);
2085 ret = 1; 2164 ret = 1;
2086 goto end_reorder; 2165 goto end_reorder;
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
new file mode 100644
index 000000000000..8e6685e7ae85
--- /dev/null
+++ b/net/mac80211/scan.c
@@ -0,0 +1,937 @@
1/*
2 * Scanning implementation
3 *
4 * Copyright 2003, Jouni Malinen <jkmaline@cc.hut.fi>
5 * Copyright 2004, Instant802 Networks, Inc.
6 * Copyright 2005, Devicescape Software, Inc.
7 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
8 * Copyright 2007, Michael Wu <flamingice@sourmilk.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/* TODO:
16 * order BSS list by RSSI(?) ("quality of AP")
17 * scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE,
18 * SSID)
19 */
20
21#include <linux/wireless.h>
22#include <linux/if_arp.h>
23#include <net/mac80211.h>
24#include <net/iw_handler.h>
25
26#include "ieee80211_i.h"
27#include "mesh.h"
28
29#define IEEE80211_PROBE_DELAY (HZ / 33)
30#define IEEE80211_CHANNEL_TIME (HZ / 33)
31#define IEEE80211_PASSIVE_CHANNEL_TIME (HZ / 5)
32
33void ieee80211_rx_bss_list_init(struct ieee80211_local *local)
34{
35 spin_lock_init(&local->bss_lock);
36 INIT_LIST_HEAD(&local->bss_list);
37}
38
39void ieee80211_rx_bss_list_deinit(struct ieee80211_local *local)
40{
41 struct ieee80211_bss *bss, *tmp;
42
43 list_for_each_entry_safe(bss, tmp, &local->bss_list, list)
44 ieee80211_rx_bss_put(local, bss);
45}
46
47struct ieee80211_bss *
48ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
49 u8 *ssid, u8 ssid_len)
50{
51 struct ieee80211_bss *bss;
52
53 spin_lock_bh(&local->bss_lock);
54 bss = local->bss_hash[STA_HASH(bssid)];
55 while (bss) {
56 if (!bss_mesh_cfg(bss) &&
57 !memcmp(bss->bssid, bssid, ETH_ALEN) &&
58 bss->freq == freq &&
59 bss->ssid_len == ssid_len &&
60 (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) {
61 atomic_inc(&bss->users);
62 break;
63 }
64 bss = bss->hnext;
65 }
66 spin_unlock_bh(&local->bss_lock);
67 return bss;
68}
69
70/* Caller must hold local->bss_lock */
71static void __ieee80211_rx_bss_hash_add(struct ieee80211_local *local,
72 struct ieee80211_bss *bss)
73{
74 u8 hash_idx;
75
76 if (bss_mesh_cfg(bss))
77 hash_idx = mesh_id_hash(bss_mesh_id(bss),
78 bss_mesh_id_len(bss));
79 else
80 hash_idx = STA_HASH(bss->bssid);
81
82 bss->hnext = local->bss_hash[hash_idx];
83 local->bss_hash[hash_idx] = bss;
84}
85
86/* Caller must hold local->bss_lock */
87static void __ieee80211_rx_bss_hash_del(struct ieee80211_local *local,
88 struct ieee80211_bss *bss)
89{
90 struct ieee80211_bss *b, *prev = NULL;
91 b = local->bss_hash[STA_HASH(bss->bssid)];
92 while (b) {
93 if (b == bss) {
94 if (!prev)
95 local->bss_hash[STA_HASH(bss->bssid)] =
96 bss->hnext;
97 else
98 prev->hnext = bss->hnext;
99 break;
100 }
101 prev = b;
102 b = b->hnext;
103 }
104}
105
106struct ieee80211_bss *
107ieee80211_rx_bss_add(struct ieee80211_local *local, u8 *bssid, int freq,
108 u8 *ssid, u8 ssid_len)
109{
110 struct ieee80211_bss *bss;
111
112 bss = kzalloc(sizeof(*bss), GFP_ATOMIC);
113 if (!bss)
114 return NULL;
115 atomic_set(&bss->users, 2);
116 memcpy(bss->bssid, bssid, ETH_ALEN);
117 bss->freq = freq;
118 if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) {
119 memcpy(bss->ssid, ssid, ssid_len);
120 bss->ssid_len = ssid_len;
121 }
122
123 spin_lock_bh(&local->bss_lock);
124 /* TODO: order by RSSI? */
125 list_add_tail(&bss->list, &local->bss_list);
126 __ieee80211_rx_bss_hash_add(local, bss);
127 spin_unlock_bh(&local->bss_lock);
128 return bss;
129}
130
131#ifdef CONFIG_MAC80211_MESH
132static struct ieee80211_bss *
133ieee80211_rx_mesh_bss_get(struct ieee80211_local *local, u8 *mesh_id, int mesh_id_len,
134 u8 *mesh_cfg, int freq)
135{
136 struct ieee80211_bss *bss;
137
138 spin_lock_bh(&local->bss_lock);
139 bss = local->bss_hash[mesh_id_hash(mesh_id, mesh_id_len)];
140 while (bss) {
141 if (bss_mesh_cfg(bss) &&
142 !memcmp(bss_mesh_cfg(bss), mesh_cfg, MESH_CFG_CMP_LEN) &&
143 bss->freq == freq &&
144 mesh_id_len == bss->mesh_id_len &&
145 (mesh_id_len == 0 || !memcmp(bss->mesh_id, mesh_id,
146 mesh_id_len))) {
147 atomic_inc(&bss->users);
148 break;
149 }
150 bss = bss->hnext;
151 }
152 spin_unlock_bh(&local->bss_lock);
153 return bss;
154}
155
156static struct ieee80211_bss *
157ieee80211_rx_mesh_bss_add(struct ieee80211_local *local, u8 *mesh_id, int mesh_id_len,
158 u8 *mesh_cfg, int mesh_config_len, int freq)
159{
160 struct ieee80211_bss *bss;
161
162 if (mesh_config_len != MESH_CFG_LEN)
163 return NULL;
164
165 bss = kzalloc(sizeof(*bss), GFP_ATOMIC);
166 if (!bss)
167 return NULL;
168
169 bss->mesh_cfg = kmalloc(MESH_CFG_CMP_LEN, GFP_ATOMIC);
170 if (!bss->mesh_cfg) {
171 kfree(bss);
172 return NULL;
173 }
174
175 if (mesh_id_len && mesh_id_len <= IEEE80211_MAX_MESH_ID_LEN) {
176 bss->mesh_id = kmalloc(mesh_id_len, GFP_ATOMIC);
177 if (!bss->mesh_id) {
178 kfree(bss->mesh_cfg);
179 kfree(bss);
180 return NULL;
181 }
182 memcpy(bss->mesh_id, mesh_id, mesh_id_len);
183 }
184
185 atomic_set(&bss->users, 2);
186 memcpy(bss->mesh_cfg, mesh_cfg, MESH_CFG_CMP_LEN);
187 bss->mesh_id_len = mesh_id_len;
188 bss->freq = freq;
189 spin_lock_bh(&local->bss_lock);
190 /* TODO: order by RSSI? */
191 list_add_tail(&bss->list, &local->bss_list);
192 __ieee80211_rx_bss_hash_add(local, bss);
193 spin_unlock_bh(&local->bss_lock);
194 return bss;
195}
196#endif
197
198static void ieee80211_rx_bss_free(struct ieee80211_bss *bss)
199{
200 kfree(bss->ies);
201 kfree(bss_mesh_id(bss));
202 kfree(bss_mesh_cfg(bss));
203 kfree(bss);
204}
205
206void ieee80211_rx_bss_put(struct ieee80211_local *local,
207 struct ieee80211_bss *bss)
208{
209 local_bh_disable();
210 if (!atomic_dec_and_lock(&bss->users, &local->bss_lock)) {
211 local_bh_enable();
212 return;
213 }
214
215 __ieee80211_rx_bss_hash_del(local, bss);
216 list_del(&bss->list);
217 spin_unlock_bh(&local->bss_lock);
218 ieee80211_rx_bss_free(bss);
219}
220
221struct ieee80211_bss *
222ieee80211_bss_info_update(struct ieee80211_local *local,
223 struct ieee80211_rx_status *rx_status,
224 struct ieee80211_mgmt *mgmt,
225 size_t len,
226 struct ieee802_11_elems *elems,
227 int freq, bool beacon)
228{
229 struct ieee80211_bss *bss;
230 int clen;
231
232#ifdef CONFIG_MAC80211_MESH
233 if (elems->mesh_config)
234 bss = ieee80211_rx_mesh_bss_get(local, elems->mesh_id,
235 elems->mesh_id_len, elems->mesh_config, freq);
236 else
237#endif
238 bss = ieee80211_rx_bss_get(local, mgmt->bssid, freq,
239 elems->ssid, elems->ssid_len);
240 if (!bss) {
241#ifdef CONFIG_MAC80211_MESH
242 if (elems->mesh_config)
243 bss = ieee80211_rx_mesh_bss_add(local, elems->mesh_id,
244 elems->mesh_id_len, elems->mesh_config,
245 elems->mesh_config_len, freq);
246 else
247#endif
248 bss = ieee80211_rx_bss_add(local, mgmt->bssid, freq,
249 elems->ssid, elems->ssid_len);
250 if (!bss)
251 return NULL;
252 } else {
253#if 0
254 /* TODO: order by RSSI? */
255 spin_lock_bh(&local->bss_lock);
256 list_move_tail(&bss->list, &local->bss_list);
257 spin_unlock_bh(&local->bss_lock);
258#endif
259 }
260
261 /* save the ERP value so that it is available at association time */
262 if (elems->erp_info && elems->erp_info_len >= 1) {
263 bss->erp_value = elems->erp_info[0];
264 bss->has_erp_value = 1;
265 }
266
267 bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int);
268 bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info);
269
270 if (elems->tim) {
271 struct ieee80211_tim_ie *tim_ie =
272 (struct ieee80211_tim_ie *)elems->tim;
273 bss->dtim_period = tim_ie->dtim_period;
274 }
275
276 /* set default value for buggy APs */
277 if (!elems->tim || bss->dtim_period == 0)
278 bss->dtim_period = 1;
279
280 bss->supp_rates_len = 0;
281 if (elems->supp_rates) {
282 clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len;
283 if (clen > elems->supp_rates_len)
284 clen = elems->supp_rates_len;
285 memcpy(&bss->supp_rates[bss->supp_rates_len], elems->supp_rates,
286 clen);
287 bss->supp_rates_len += clen;
288 }
289 if (elems->ext_supp_rates) {
290 clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len;
291 if (clen > elems->ext_supp_rates_len)
292 clen = elems->ext_supp_rates_len;
293 memcpy(&bss->supp_rates[bss->supp_rates_len],
294 elems->ext_supp_rates, clen);
295 bss->supp_rates_len += clen;
296 }
297
298 bss->band = rx_status->band;
299
300 bss->timestamp = le64_to_cpu(mgmt->u.beacon.timestamp);
301 bss->last_update = jiffies;
302 bss->signal = rx_status->signal;
303 bss->noise = rx_status->noise;
304 bss->qual = rx_status->qual;
305 bss->wmm_used = elems->wmm_param || elems->wmm_info;
306
307 if (!beacon)
308 bss->last_probe_resp = jiffies;
309
310 /*
311 * For probe responses, or if we don't have any information yet,
312 * use the IEs from the beacon.
313 */
314 if (!bss->ies || !beacon) {
315 if (bss->ies == NULL || bss->ies_len < elems->total_len) {
316 kfree(bss->ies);
317 bss->ies = kmalloc(elems->total_len, GFP_ATOMIC);
318 }
319 if (bss->ies) {
320 memcpy(bss->ies, elems->ie_start, elems->total_len);
321 bss->ies_len = elems->total_len;
322 } else
323 bss->ies_len = 0;
324 }
325
326 return bss;
327}
328
329ieee80211_rx_result
330ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
331 struct ieee80211_rx_status *rx_status)
332{
333 struct ieee80211_mgmt *mgmt;
334 struct ieee80211_bss *bss;
335 u8 *elements;
336 struct ieee80211_channel *channel;
337 size_t baselen;
338 int freq;
339 __le16 fc;
340 bool presp, beacon = false;
341 struct ieee802_11_elems elems;
342
343 if (skb->len < 2)
344 return RX_DROP_UNUSABLE;
345
346 mgmt = (struct ieee80211_mgmt *) skb->data;
347 fc = mgmt->frame_control;
348
349 if (ieee80211_is_ctl(fc))
350 return RX_CONTINUE;
351
352 if (skb->len < 24)
353 return RX_DROP_MONITOR;
354
355 presp = ieee80211_is_probe_resp(fc);
356 if (presp) {
357 /* ignore ProbeResp to foreign address */
358 if (memcmp(mgmt->da, sdata->dev->dev_addr, ETH_ALEN))
359 return RX_DROP_MONITOR;
360
361 presp = true;
362 elements = mgmt->u.probe_resp.variable;
363 baselen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable);
364 } else {
365 beacon = ieee80211_is_beacon(fc);
366 baselen = offsetof(struct ieee80211_mgmt, u.beacon.variable);
367 elements = mgmt->u.beacon.variable;
368 }
369
370 if (!presp && !beacon)
371 return RX_CONTINUE;
372
373 if (baselen > skb->len)
374 return RX_DROP_MONITOR;
375
376 ieee802_11_parse_elems(elements, skb->len - baselen, &elems);
377
378 if (elems.ds_params && elems.ds_params_len == 1)
379 freq = ieee80211_channel_to_frequency(elems.ds_params[0]);
380 else
381 freq = rx_status->freq;
382
383 channel = ieee80211_get_channel(sdata->local->hw.wiphy, freq);
384
385 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
386 return RX_DROP_MONITOR;
387
388 bss = ieee80211_bss_info_update(sdata->local, rx_status,
389 mgmt, skb->len, &elems,
390 freq, beacon);
391 ieee80211_rx_bss_put(sdata->local, bss);
392
393 dev_kfree_skb(skb);
394 return RX_QUEUED;
395}
396
397static void ieee80211_send_nullfunc(struct ieee80211_local *local,
398 struct ieee80211_sub_if_data *sdata,
399 int powersave)
400{
401 struct sk_buff *skb;
402 struct ieee80211_hdr *nullfunc;
403 __le16 fc;
404
405 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24);
406 if (!skb) {
407 printk(KERN_DEBUG "%s: failed to allocate buffer for nullfunc "
408 "frame\n", sdata->dev->name);
409 return;
410 }
411 skb_reserve(skb, local->hw.extra_tx_headroom);
412
413 nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24);
414 memset(nullfunc, 0, 24);
415 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
416 IEEE80211_FCTL_TODS);
417 if (powersave)
418 fc |= cpu_to_le16(IEEE80211_FCTL_PM);
419 nullfunc->frame_control = fc;
420 memcpy(nullfunc->addr1, sdata->u.sta.bssid, ETH_ALEN);
421 memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN);
422 memcpy(nullfunc->addr3, sdata->u.sta.bssid, ETH_ALEN);
423
424 ieee80211_tx_skb(sdata, skb, 0);
425}
426
427void ieee80211_scan_completed(struct ieee80211_hw *hw)
428{
429 struct ieee80211_local *local = hw_to_local(hw);
430 struct ieee80211_sub_if_data *sdata;
431 union iwreq_data wrqu;
432
433 if (WARN_ON(!local->hw_scanning && !local->sw_scanning))
434 return;
435
436 local->last_scan_completed = jiffies;
437 memset(&wrqu, 0, sizeof(wrqu));
438
439 /*
440 * local->scan_sdata could have been NULLed by the interface
441 * down code in case we were scanning on an interface that is
442 * being taken down.
443 */
444 sdata = local->scan_sdata;
445 if (sdata)
446 wireless_send_event(sdata->dev, SIOCGIWSCAN, &wrqu, NULL);
447
448 if (local->hw_scanning) {
449 local->hw_scanning = false;
450 if (ieee80211_hw_config(local))
451 printk(KERN_DEBUG "%s: failed to restore operational "
452 "channel after scan\n", wiphy_name(local->hw.wiphy));
453
454 goto done;
455 }
456
457 local->sw_scanning = false;
458 if (ieee80211_hw_config(local))
459 printk(KERN_DEBUG "%s: failed to restore operational "
460 "channel after scan\n", wiphy_name(local->hw.wiphy));
461
462
463 netif_tx_lock_bh(local->mdev);
464 netif_addr_lock(local->mdev);
465 local->filter_flags &= ~FIF_BCN_PRBRESP_PROMISC;
466 local->ops->configure_filter(local_to_hw(local),
467 FIF_BCN_PRBRESP_PROMISC,
468 &local->filter_flags,
469 local->mdev->mc_count,
470 local->mdev->mc_list);
471
472 netif_addr_unlock(local->mdev);
473 netif_tx_unlock_bh(local->mdev);
474
475 rcu_read_lock();
476 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
477 /* Tell AP we're back */
478 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
479 if (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED) {
480 ieee80211_send_nullfunc(local, sdata, 0);
481 netif_tx_wake_all_queues(sdata->dev);
482 }
483 } else
484 netif_tx_wake_all_queues(sdata->dev);
485 }
486 rcu_read_unlock();
487
488 done:
489 ieee80211_mlme_notify_scan_completed(local);
490 ieee80211_mesh_notify_scan_completed(local);
491}
492EXPORT_SYMBOL(ieee80211_scan_completed);
493
494
495void ieee80211_scan_work(struct work_struct *work)
496{
497 struct ieee80211_local *local =
498 container_of(work, struct ieee80211_local, scan_work.work);
499 struct ieee80211_sub_if_data *sdata = local->scan_sdata;
500 struct ieee80211_supported_band *sband;
501 struct ieee80211_channel *chan;
502 int skip;
503 unsigned long next_delay = 0;
504
505 /*
506 * Avoid re-scheduling when the sdata is going away.
507 */
508 if (!netif_running(sdata->dev))
509 return;
510
511 switch (local->scan_state) {
512 case SCAN_SET_CHANNEL:
513 /*
514 * Get current scan band. scan_band may be IEEE80211_NUM_BANDS
515 * after we successfully scanned the last channel of the last
516 * band (and the last band is supported by the hw)
517 */
518 if (local->scan_band < IEEE80211_NUM_BANDS)
519 sband = local->hw.wiphy->bands[local->scan_band];
520 else
521 sband = NULL;
522
523 /*
524 * If we are at an unsupported band and have more bands
525 * left to scan, advance to the next supported one.
526 */
527 while (!sband && local->scan_band < IEEE80211_NUM_BANDS - 1) {
528 local->scan_band++;
529 sband = local->hw.wiphy->bands[local->scan_band];
530 local->scan_channel_idx = 0;
531 }
532
533 /* if no more bands/channels left, complete scan */
534 if (!sband || local->scan_channel_idx >= sband->n_channels) {
535 ieee80211_scan_completed(local_to_hw(local));
536 return;
537 }
538 skip = 0;
539 chan = &sband->channels[local->scan_channel_idx];
540
541 if (chan->flags & IEEE80211_CHAN_DISABLED ||
542 (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
543 chan->flags & IEEE80211_CHAN_NO_IBSS))
544 skip = 1;
545
546 if (!skip) {
547 local->scan_channel = chan;
548 if (ieee80211_hw_config(local)) {
549 printk(KERN_DEBUG "%s: failed to set freq to "
550 "%d MHz for scan\n", wiphy_name(local->hw.wiphy),
551 chan->center_freq);
552 skip = 1;
553 }
554 }
555
556 /* advance state machine to next channel/band */
557 local->scan_channel_idx++;
558 if (local->scan_channel_idx >= sband->n_channels) {
559 /*
560 * scan_band may end up == IEEE80211_NUM_BANDS, but
561 * we'll catch that case above and complete the scan
562 * if that is the case.
563 */
564 local->scan_band++;
565 local->scan_channel_idx = 0;
566 }
567
568 if (skip)
569 break;
570
571 next_delay = IEEE80211_PROBE_DELAY +
572 usecs_to_jiffies(local->hw.channel_change_time);
573 local->scan_state = SCAN_SEND_PROBE;
574 break;
575 case SCAN_SEND_PROBE:
576 next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
577 local->scan_state = SCAN_SET_CHANNEL;
578
579 if (local->scan_channel->flags & IEEE80211_CHAN_PASSIVE_SCAN)
580 break;
581 ieee80211_send_probe_req(sdata, NULL, local->scan_ssid,
582 local->scan_ssid_len);
583 next_delay = IEEE80211_CHANNEL_TIME;
584 break;
585 }
586
587 queue_delayed_work(local->hw.workqueue, &local->scan_work,
588 next_delay);
589}
590
591
592int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata,
593 u8 *ssid, size_t ssid_len)
594{
595 struct ieee80211_local *local = scan_sdata->local;
596 struct ieee80211_sub_if_data *sdata;
597
598 if (ssid_len > IEEE80211_MAX_SSID_LEN)
599 return -EINVAL;
600
601 /* MLME-SCAN.request (page 118) page 144 (11.1.3.1)
602 * BSSType: INFRASTRUCTURE, INDEPENDENT, ANY_BSS
603 * BSSID: MACAddress
604 * SSID
605 * ScanType: ACTIVE, PASSIVE
606 * ProbeDelay: delay (in microseconds) to be used prior to transmitting
607 * a Probe frame during active scanning
608 * ChannelList
609 * MinChannelTime (>= ProbeDelay), in TU
610 * MaxChannelTime: (>= MinChannelTime), in TU
611 */
612
613 /* MLME-SCAN.confirm
614 * BSSDescriptionSet
615 * ResultCode: SUCCESS, INVALID_PARAMETERS
616 */
617
618 if (local->sw_scanning || local->hw_scanning) {
619 if (local->scan_sdata == scan_sdata)
620 return 0;
621 return -EBUSY;
622 }
623
624 if (local->ops->hw_scan) {
625 int rc;
626
627 local->hw_scanning = true;
628 rc = local->ops->hw_scan(local_to_hw(local), ssid, ssid_len);
629 if (rc) {
630 local->hw_scanning = false;
631 return rc;
632 }
633 local->scan_sdata = scan_sdata;
634 return 0;
635 }
636
637 local->sw_scanning = true;
638
639 rcu_read_lock();
640 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
641 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
642 if (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED) {
643 netif_tx_stop_all_queues(sdata->dev);
644 ieee80211_send_nullfunc(local, sdata, 1);
645 }
646 } else
647 netif_tx_stop_all_queues(sdata->dev);
648 }
649 rcu_read_unlock();
650
651 if (ssid) {
652 local->scan_ssid_len = ssid_len;
653 memcpy(local->scan_ssid, ssid, ssid_len);
654 } else
655 local->scan_ssid_len = 0;
656 local->scan_state = SCAN_SET_CHANNEL;
657 local->scan_channel_idx = 0;
658 local->scan_band = IEEE80211_BAND_2GHZ;
659 local->scan_sdata = scan_sdata;
660
661 netif_addr_lock_bh(local->mdev);
662 local->filter_flags |= FIF_BCN_PRBRESP_PROMISC;
663 local->ops->configure_filter(local_to_hw(local),
664 FIF_BCN_PRBRESP_PROMISC,
665 &local->filter_flags,
666 local->mdev->mc_count,
667 local->mdev->mc_list);
668 netif_addr_unlock_bh(local->mdev);
669
670 /* TODO: start scan as soon as all nullfunc frames are ACKed */
671 queue_delayed_work(local->hw.workqueue, &local->scan_work,
672 IEEE80211_CHANNEL_TIME);
673
674 return 0;
675}
676
677
678int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
679 u8 *ssid, size_t ssid_len)
680{
681 struct ieee80211_local *local = sdata->local;
682 struct ieee80211_if_sta *ifsta;
683
684 if (sdata->vif.type != NL80211_IFTYPE_STATION)
685 return ieee80211_start_scan(sdata, ssid, ssid_len);
686
687 /*
688 * STA has a state machine that might need to defer scanning
689 * while it's trying to associate/authenticate, therefore we
690 * queue it up to the state machine in that case.
691 */
692
693 if (local->sw_scanning || local->hw_scanning) {
694 if (local->scan_sdata == sdata)
695 return 0;
696 return -EBUSY;
697 }
698
699 ifsta = &sdata->u.sta;
700
701 ifsta->scan_ssid_len = ssid_len;
702 if (ssid_len)
703 memcpy(ifsta->scan_ssid, ssid, ssid_len);
704 set_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request);
705 queue_work(local->hw.workqueue, &ifsta->work);
706
707 return 0;
708}
709
710
711static void ieee80211_scan_add_ies(struct iw_request_info *info,
712 struct ieee80211_bss *bss,
713 char **current_ev, char *end_buf)
714{
715 u8 *pos, *end, *next;
716 struct iw_event iwe;
717
718 if (bss == NULL || bss->ies == NULL)
719 return;
720
721 /*
722 * If needed, fragment the IEs buffer (at IE boundaries) into short
723 * enough fragments to fit into IW_GENERIC_IE_MAX octet messages.
724 */
725 pos = bss->ies;
726 end = pos + bss->ies_len;
727
728 while (end - pos > IW_GENERIC_IE_MAX) {
729 next = pos + 2 + pos[1];
730 while (next + 2 + next[1] - pos < IW_GENERIC_IE_MAX)
731 next = next + 2 + next[1];
732
733 memset(&iwe, 0, sizeof(iwe));
734 iwe.cmd = IWEVGENIE;
735 iwe.u.data.length = next - pos;
736 *current_ev = iwe_stream_add_point(info, *current_ev,
737 end_buf, &iwe, pos);
738
739 pos = next;
740 }
741
742 if (end > pos) {
743 memset(&iwe, 0, sizeof(iwe));
744 iwe.cmd = IWEVGENIE;
745 iwe.u.data.length = end - pos;
746 *current_ev = iwe_stream_add_point(info, *current_ev,
747 end_buf, &iwe, pos);
748 }
749}
750
751
752static char *
753ieee80211_scan_result(struct ieee80211_local *local,
754 struct iw_request_info *info,
755 struct ieee80211_bss *bss,
756 char *current_ev, char *end_buf)
757{
758 struct iw_event iwe;
759 char *buf;
760
761 if (time_after(jiffies,
762 bss->last_update + IEEE80211_SCAN_RESULT_EXPIRE))
763 return current_ev;
764
765 memset(&iwe, 0, sizeof(iwe));
766 iwe.cmd = SIOCGIWAP;
767 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
768 memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
769 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
770 IW_EV_ADDR_LEN);
771
772 memset(&iwe, 0, sizeof(iwe));
773 iwe.cmd = SIOCGIWESSID;
774 if (bss_mesh_cfg(bss)) {
775 iwe.u.data.length = bss_mesh_id_len(bss);
776 iwe.u.data.flags = 1;
777 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
778 &iwe, bss_mesh_id(bss));
779 } else {
780 iwe.u.data.length = bss->ssid_len;
781 iwe.u.data.flags = 1;
782 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
783 &iwe, bss->ssid);
784 }
785
786 if (bss->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)
787 || bss_mesh_cfg(bss)) {
788 memset(&iwe, 0, sizeof(iwe));
789 iwe.cmd = SIOCGIWMODE;
790 if (bss_mesh_cfg(bss))
791 iwe.u.mode = IW_MODE_MESH;
792 else if (bss->capability & WLAN_CAPABILITY_ESS)
793 iwe.u.mode = IW_MODE_MASTER;
794 else
795 iwe.u.mode = IW_MODE_ADHOC;
796 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
797 &iwe, IW_EV_UINT_LEN);
798 }
799
800 memset(&iwe, 0, sizeof(iwe));
801 iwe.cmd = SIOCGIWFREQ;
802 iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq);
803 iwe.u.freq.e = 0;
804 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
805 IW_EV_FREQ_LEN);
806
807 memset(&iwe, 0, sizeof(iwe));
808 iwe.cmd = SIOCGIWFREQ;
809 iwe.u.freq.m = bss->freq;
810 iwe.u.freq.e = 6;
811 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
812 IW_EV_FREQ_LEN);
813 memset(&iwe, 0, sizeof(iwe));
814 iwe.cmd = IWEVQUAL;
815 iwe.u.qual.qual = bss->qual;
816 iwe.u.qual.level = bss->signal;
817 iwe.u.qual.noise = bss->noise;
818 iwe.u.qual.updated = local->wstats_flags;
819 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
820 IW_EV_QUAL_LEN);
821
822 memset(&iwe, 0, sizeof(iwe));
823 iwe.cmd = SIOCGIWENCODE;
824 if (bss->capability & WLAN_CAPABILITY_PRIVACY)
825 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
826 else
827 iwe.u.data.flags = IW_ENCODE_DISABLED;
828 iwe.u.data.length = 0;
829 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
830 &iwe, "");
831
832 ieee80211_scan_add_ies(info, bss, &current_ev, end_buf);
833
834 if (bss->supp_rates_len > 0) {
835 /* display all supported rates in readable format */
836 char *p = current_ev + iwe_stream_lcp_len(info);
837 int i;
838
839 memset(&iwe, 0, sizeof(iwe));
840 iwe.cmd = SIOCGIWRATE;
841 /* Those two flags are ignored... */
842 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
843
844 for (i = 0; i < bss->supp_rates_len; i++) {
845 iwe.u.bitrate.value = ((bss->supp_rates[i] &
846 0x7f) * 500000);
847 p = iwe_stream_add_value(info, current_ev, p,
848 end_buf, &iwe, IW_EV_PARAM_LEN);
849 }
850 current_ev = p;
851 }
852
853 buf = kmalloc(30, GFP_ATOMIC);
854 if (buf) {
855 memset(&iwe, 0, sizeof(iwe));
856 iwe.cmd = IWEVCUSTOM;
857 sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->timestamp));
858 iwe.u.data.length = strlen(buf);
859 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
860 &iwe, buf);
861 memset(&iwe, 0, sizeof(iwe));
862 iwe.cmd = IWEVCUSTOM;
863 sprintf(buf, " Last beacon: %dms ago",
864 jiffies_to_msecs(jiffies - bss->last_update));
865 iwe.u.data.length = strlen(buf);
866 current_ev = iwe_stream_add_point(info, current_ev,
867 end_buf, &iwe, buf);
868 kfree(buf);
869 }
870
871 if (bss_mesh_cfg(bss)) {
872 u8 *cfg = bss_mesh_cfg(bss);
873 buf = kmalloc(50, GFP_ATOMIC);
874 if (buf) {
875 memset(&iwe, 0, sizeof(iwe));
876 iwe.cmd = IWEVCUSTOM;
877 sprintf(buf, "Mesh network (version %d)", cfg[0]);
878 iwe.u.data.length = strlen(buf);
879 current_ev = iwe_stream_add_point(info, current_ev,
880 end_buf,
881 &iwe, buf);
882 sprintf(buf, "Path Selection Protocol ID: "
883 "0x%02X%02X%02X%02X", cfg[1], cfg[2], cfg[3],
884 cfg[4]);
885 iwe.u.data.length = strlen(buf);
886 current_ev = iwe_stream_add_point(info, current_ev,
887 end_buf,
888 &iwe, buf);
889 sprintf(buf, "Path Selection Metric ID: "
890 "0x%02X%02X%02X%02X", cfg[5], cfg[6], cfg[7],
891 cfg[8]);
892 iwe.u.data.length = strlen(buf);
893 current_ev = iwe_stream_add_point(info, current_ev,
894 end_buf,
895 &iwe, buf);
896 sprintf(buf, "Congestion Control Mode ID: "
897 "0x%02X%02X%02X%02X", cfg[9], cfg[10],
898 cfg[11], cfg[12]);
899 iwe.u.data.length = strlen(buf);
900 current_ev = iwe_stream_add_point(info, current_ev,
901 end_buf,
902 &iwe, buf);
903 sprintf(buf, "Channel Precedence: "
904 "0x%02X%02X%02X%02X", cfg[13], cfg[14],
905 cfg[15], cfg[16]);
906 iwe.u.data.length = strlen(buf);
907 current_ev = iwe_stream_add_point(info, current_ev,
908 end_buf,
909 &iwe, buf);
910 kfree(buf);
911 }
912 }
913
914 return current_ev;
915}
916
917
918int ieee80211_scan_results(struct ieee80211_local *local,
919 struct iw_request_info *info,
920 char *buf, size_t len)
921{
922 char *current_ev = buf;
923 char *end_buf = buf + len;
924 struct ieee80211_bss *bss;
925
926 spin_lock_bh(&local->bss_lock);
927 list_for_each_entry(bss, &local->bss_list, list) {
928 if (buf + len - current_ev <= IW_EV_ADDR_LEN) {
929 spin_unlock_bh(&local->bss_lock);
930 return -E2BIG;
931 }
932 current_ev = ieee80211_scan_result(local, info, bss,
933 current_ev, end_buf);
934 }
935 spin_unlock_bh(&local->bss_lock);
936 return current_ev - buf;
937}
diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c
new file mode 100644
index 000000000000..f72bad636d8e
--- /dev/null
+++ b/net/mac80211/spectmgmt.c
@@ -0,0 +1,86 @@
1/*
2 * spectrum management
3 *
4 * Copyright 2003, Jouni Malinen <jkmaline@cc.hut.fi>
5 * Copyright 2002-2005, Instant802 Networks, Inc.
6 * Copyright 2005-2006, Devicescape Software, Inc.
7 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
8 * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
9 * Copyright 2007-2008, Intel Corporation
10 * Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 */
16
17#include <linux/ieee80211.h>
18#include <net/wireless.h>
19#include <net/mac80211.h>
20#include "ieee80211_i.h"
21#include "sta_info.h"
22#include "wme.h"
23
24static void ieee80211_send_refuse_measurement_request(struct ieee80211_sub_if_data *sdata,
25 struct ieee80211_msrment_ie *request_ie,
26 const u8 *da, const u8 *bssid,
27 u8 dialog_token)
28{
29 struct ieee80211_local *local = sdata->local;
30 struct sk_buff *skb;
31 struct ieee80211_mgmt *msr_report;
32
33 skb = dev_alloc_skb(sizeof(*msr_report) + local->hw.extra_tx_headroom +
34 sizeof(struct ieee80211_msrment_ie));
35
36 if (!skb) {
37 printk(KERN_ERR "%s: failed to allocate buffer for "
38 "measurement report frame\n", sdata->dev->name);
39 return;
40 }
41
42 skb_reserve(skb, local->hw.extra_tx_headroom);
43 msr_report = (struct ieee80211_mgmt *)skb_put(skb, 24);
44 memset(msr_report, 0, 24);
45 memcpy(msr_report->da, da, ETH_ALEN);
46 memcpy(msr_report->sa, sdata->dev->dev_addr, ETH_ALEN);
47 memcpy(msr_report->bssid, bssid, ETH_ALEN);
48 msr_report->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
49 IEEE80211_STYPE_ACTION);
50
51 skb_put(skb, 1 + sizeof(msr_report->u.action.u.measurement));
52 msr_report->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT;
53 msr_report->u.action.u.measurement.action_code =
54 WLAN_ACTION_SPCT_MSR_RPRT;
55 msr_report->u.action.u.measurement.dialog_token = dialog_token;
56
57 msr_report->u.action.u.measurement.element_id = WLAN_EID_MEASURE_REPORT;
58 msr_report->u.action.u.measurement.length =
59 sizeof(struct ieee80211_msrment_ie);
60
61 memset(&msr_report->u.action.u.measurement.msr_elem, 0,
62 sizeof(struct ieee80211_msrment_ie));
63 msr_report->u.action.u.measurement.msr_elem.token = request_ie->token;
64 msr_report->u.action.u.measurement.msr_elem.mode |=
65 IEEE80211_SPCT_MSR_RPRT_MODE_REFUSED;
66 msr_report->u.action.u.measurement.msr_elem.type = request_ie->type;
67
68 ieee80211_tx_skb(sdata, skb, 0);
69}
70
71void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
72 struct ieee80211_mgmt *mgmt,
73 size_t len)
74{
75 /*
76 * Ignoring measurement request is spec violation.
77 * Mandatory measurements must be reported optional
78 * measurements might be refused or reported incapable
79 * For now just refuse
80 * TODO: Answer basic measurement as unmeasured
81 */
82 ieee80211_send_refuse_measurement_request(sdata,
83 &mgmt->u.action.u.measurement.msr_elem,
84 mgmt->sa, mgmt->bssid,
85 mgmt->u.action.u.measurement.dialog_token);
86}
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index f2ba653b9d69..9b72d15bc8dc 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -73,11 +73,11 @@ static int sta_info_hash_del(struct ieee80211_local *local,
73{ 73{
74 struct sta_info *s; 74 struct sta_info *s;
75 75
76 s = local->sta_hash[STA_HASH(sta->addr)]; 76 s = local->sta_hash[STA_HASH(sta->sta.addr)];
77 if (!s) 77 if (!s)
78 return -ENOENT; 78 return -ENOENT;
79 if (s == sta) { 79 if (s == sta) {
80 rcu_assign_pointer(local->sta_hash[STA_HASH(sta->addr)], 80 rcu_assign_pointer(local->sta_hash[STA_HASH(sta->sta.addr)],
81 s->hnext); 81 s->hnext);
82 return 0; 82 return 0;
83 } 83 }
@@ -93,26 +93,19 @@ static int sta_info_hash_del(struct ieee80211_local *local,
93} 93}
94 94
95/* protected by RCU */ 95/* protected by RCU */
96static struct sta_info *__sta_info_find(struct ieee80211_local *local, 96struct sta_info *sta_info_get(struct ieee80211_local *local, const u8 *addr)
97 u8 *addr)
98{ 97{
99 struct sta_info *sta; 98 struct sta_info *sta;
100 99
101 sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]); 100 sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]);
102 while (sta) { 101 while (sta) {
103 if (compare_ether_addr(sta->addr, addr) == 0) 102 if (compare_ether_addr(sta->sta.addr, addr) == 0)
104 break; 103 break;
105 sta = rcu_dereference(sta->hnext); 104 sta = rcu_dereference(sta->hnext);
106 } 105 }
107 return sta; 106 return sta;
108} 107}
109 108
110struct sta_info *sta_info_get(struct ieee80211_local *local, u8 *addr)
111{
112 return __sta_info_find(local, addr);
113}
114EXPORT_SYMBOL(sta_info_get);
115
116struct sta_info *sta_info_get_by_idx(struct ieee80211_local *local, int idx, 109struct sta_info *sta_info_get_by_idx(struct ieee80211_local *local, int idx,
117 struct net_device *dev) 110 struct net_device *dev)
118{ 111{
@@ -146,12 +139,12 @@ static void __sta_info_free(struct ieee80211_local *local,
146{ 139{
147 DECLARE_MAC_BUF(mbuf); 140 DECLARE_MAC_BUF(mbuf);
148 141
149 rate_control_free_sta(sta->rate_ctrl, sta->rate_ctrl_priv); 142 rate_control_free_sta(sta);
150 rate_control_put(sta->rate_ctrl); 143 rate_control_put(sta->rate_ctrl);
151 144
152#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 145#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
153 printk(KERN_DEBUG "%s: Destroyed STA %s\n", 146 printk(KERN_DEBUG "%s: Destroyed STA %s\n",
154 wiphy_name(local->hw.wiphy), print_mac(mbuf, sta->addr)); 147 wiphy_name(local->hw.wiphy), print_mac(mbuf, sta->sta.addr));
155#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 148#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
156 149
157 kfree(sta); 150 kfree(sta);
@@ -219,8 +212,8 @@ void sta_info_destroy(struct sta_info *sta)
219static void sta_info_hash_add(struct ieee80211_local *local, 212static void sta_info_hash_add(struct ieee80211_local *local,
220 struct sta_info *sta) 213 struct sta_info *sta)
221{ 214{
222 sta->hnext = local->sta_hash[STA_HASH(sta->addr)]; 215 sta->hnext = local->sta_hash[STA_HASH(sta->sta.addr)];
223 rcu_assign_pointer(local->sta_hash[STA_HASH(sta->addr)], sta); 216 rcu_assign_pointer(local->sta_hash[STA_HASH(sta->sta.addr)], sta);
224} 217}
225 218
226struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, 219struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
@@ -231,20 +224,20 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
231 int i; 224 int i;
232 DECLARE_MAC_BUF(mbuf); 225 DECLARE_MAC_BUF(mbuf);
233 226
234 sta = kzalloc(sizeof(*sta), gfp); 227 sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp);
235 if (!sta) 228 if (!sta)
236 return NULL; 229 return NULL;
237 230
238 spin_lock_init(&sta->lock); 231 spin_lock_init(&sta->lock);
239 spin_lock_init(&sta->flaglock); 232 spin_lock_init(&sta->flaglock);
240 233
241 memcpy(sta->addr, addr, ETH_ALEN); 234 memcpy(sta->sta.addr, addr, ETH_ALEN);
242 sta->local = local; 235 sta->local = local;
243 sta->sdata = sdata; 236 sta->sdata = sdata;
244 237
245 sta->rate_ctrl = rate_control_get(local->rate_ctrl); 238 sta->rate_ctrl = rate_control_get(local->rate_ctrl);
246 sta->rate_ctrl_priv = rate_control_alloc_sta(sta->rate_ctrl, 239 sta->rate_ctrl_priv = rate_control_alloc_sta(sta->rate_ctrl,
247 gfp); 240 &sta->sta, gfp);
248 if (!sta->rate_ctrl_priv) { 241 if (!sta->rate_ctrl_priv) {
249 rate_control_put(sta->rate_ctrl); 242 rate_control_put(sta->rate_ctrl);
250 kfree(sta); 243 kfree(sta);
@@ -271,7 +264,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
271 264
272#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 265#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
273 printk(KERN_DEBUG "%s: Allocated STA %s\n", 266 printk(KERN_DEBUG "%s: Allocated STA %s\n",
274 wiphy_name(local->hw.wiphy), print_mac(mbuf, sta->addr)); 267 wiphy_name(local->hw.wiphy), print_mac(mbuf, sta->sta.addr));
275#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 268#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
276 269
277#ifdef CONFIG_MAC80211_MESH 270#ifdef CONFIG_MAC80211_MESH
@@ -300,15 +293,15 @@ int sta_info_insert(struct sta_info *sta)
300 goto out_free; 293 goto out_free;
301 } 294 }
302 295
303 if (WARN_ON(compare_ether_addr(sta->addr, sdata->dev->dev_addr) == 0 || 296 if (WARN_ON(compare_ether_addr(sta->sta.addr, sdata->dev->dev_addr) == 0 ||
304 is_multicast_ether_addr(sta->addr))) { 297 is_multicast_ether_addr(sta->sta.addr))) {
305 err = -EINVAL; 298 err = -EINVAL;
306 goto out_free; 299 goto out_free;
307 } 300 }
308 301
309 spin_lock_irqsave(&local->sta_lock, flags); 302 spin_lock_irqsave(&local->sta_lock, flags);
310 /* check if STA exists already */ 303 /* check if STA exists already */
311 if (__sta_info_find(local, sta->addr)) { 304 if (sta_info_get(local, sta->sta.addr)) {
312 spin_unlock_irqrestore(&local->sta_lock, flags); 305 spin_unlock_irqrestore(&local->sta_lock, flags);
313 err = -EEXIST; 306 err = -EEXIST;
314 goto out_free; 307 goto out_free;
@@ -319,18 +312,18 @@ int sta_info_insert(struct sta_info *sta)
319 312
320 /* notify driver */ 313 /* notify driver */
321 if (local->ops->sta_notify) { 314 if (local->ops->sta_notify) {
322 if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) 315 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
323 sdata = container_of(sdata->bss, 316 sdata = container_of(sdata->bss,
324 struct ieee80211_sub_if_data, 317 struct ieee80211_sub_if_data,
325 u.ap); 318 u.ap);
326 319
327 local->ops->sta_notify(local_to_hw(local), &sdata->vif, 320 local->ops->sta_notify(local_to_hw(local), &sdata->vif,
328 STA_NOTIFY_ADD, sta->addr); 321 STA_NOTIFY_ADD, &sta->sta);
329 } 322 }
330 323
331#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 324#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
332 printk(KERN_DEBUG "%s: Inserted STA %s\n", 325 printk(KERN_DEBUG "%s: Inserted STA %s\n",
333 wiphy_name(local->hw.wiphy), print_mac(mac, sta->addr)); 326 wiphy_name(local->hw.wiphy), print_mac(mac, sta->sta.addr));
334#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 327#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
335 328
336 spin_unlock_irqrestore(&local->sta_lock, flags); 329 spin_unlock_irqrestore(&local->sta_lock, flags);
@@ -379,11 +372,12 @@ static void __sta_info_set_tim_bit(struct ieee80211_if_ap *bss,
379{ 372{
380 BUG_ON(!bss); 373 BUG_ON(!bss);
381 374
382 __bss_tim_set(bss, sta->aid); 375 __bss_tim_set(bss, sta->sta.aid);
383 376
384 if (sta->local->ops->set_tim) { 377 if (sta->local->ops->set_tim) {
385 sta->local->tim_in_locked_section = true; 378 sta->local->tim_in_locked_section = true;
386 sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 1); 379 sta->local->ops->set_tim(local_to_hw(sta->local),
380 &sta->sta, true);
387 sta->local->tim_in_locked_section = false; 381 sta->local->tim_in_locked_section = false;
388 } 382 }
389} 383}
@@ -404,11 +398,12 @@ static void __sta_info_clear_tim_bit(struct ieee80211_if_ap *bss,
404{ 398{
405 BUG_ON(!bss); 399 BUG_ON(!bss);
406 400
407 __bss_tim_clear(bss, sta->aid); 401 __bss_tim_clear(bss, sta->sta.aid);
408 402
409 if (sta->local->ops->set_tim) { 403 if (sta->local->ops->set_tim) {
410 sta->local->tim_in_locked_section = true; 404 sta->local->tim_in_locked_section = true;
411 sta->local->ops->set_tim(local_to_hw(sta->local), sta->aid, 0); 405 sta->local->ops->set_tim(local_to_hw(sta->local),
406 &sta->sta, false);
412 sta->local->tim_in_locked_section = false; 407 sta->local->tim_in_locked_section = false;
413 } 408 }
414} 409}
@@ -424,7 +419,7 @@ void sta_info_clear_tim_bit(struct sta_info *sta)
424 spin_unlock_irqrestore(&sta->local->sta_lock, flags); 419 spin_unlock_irqrestore(&sta->local->sta_lock, flags);
425} 420}
426 421
427void __sta_info_unlink(struct sta_info **sta) 422static void __sta_info_unlink(struct sta_info **sta)
428{ 423{
429 struct ieee80211_local *local = (*sta)->local; 424 struct ieee80211_local *local = (*sta)->local;
430 struct ieee80211_sub_if_data *sdata = (*sta)->sdata; 425 struct ieee80211_sub_if_data *sdata = (*sta)->sdata;
@@ -456,13 +451,13 @@ void __sta_info_unlink(struct sta_info **sta)
456 local->num_sta--; 451 local->num_sta--;
457 452
458 if (local->ops->sta_notify) { 453 if (local->ops->sta_notify) {
459 if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) 454 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
460 sdata = container_of(sdata->bss, 455 sdata = container_of(sdata->bss,
461 struct ieee80211_sub_if_data, 456 struct ieee80211_sub_if_data,
462 u.ap); 457 u.ap);
463 458
464 local->ops->sta_notify(local_to_hw(local), &sdata->vif, 459 local->ops->sta_notify(local_to_hw(local), &sdata->vif,
465 STA_NOTIFY_REMOVE, (*sta)->addr); 460 STA_NOTIFY_REMOVE, &(*sta)->sta);
466 } 461 }
467 462
468 if (ieee80211_vif_is_mesh(&sdata->vif)) { 463 if (ieee80211_vif_is_mesh(&sdata->vif)) {
@@ -474,7 +469,7 @@ void __sta_info_unlink(struct sta_info **sta)
474 469
475#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 470#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
476 printk(KERN_DEBUG "%s: Removed STA %s\n", 471 printk(KERN_DEBUG "%s: Removed STA %s\n",
477 wiphy_name(local->hw.wiphy), print_mac(mbuf, (*sta)->addr)); 472 wiphy_name(local->hw.wiphy), print_mac(mbuf, (*sta)->sta.addr));
478#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ 473#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
479 474
480 /* 475 /*
@@ -570,7 +565,7 @@ static void sta_info_cleanup_expire_buffered(struct ieee80211_local *local,
570 local->total_ps_buffered--; 565 local->total_ps_buffered--;
571#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 566#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
572 printk(KERN_DEBUG "Buffered frame expired (STA " 567 printk(KERN_DEBUG "Buffered frame expired (STA "
573 "%s)\n", print_mac(mac, sta->addr)); 568 "%s)\n", print_mac(mac, sta->sta.addr));
574#endif 569#endif
575 dev_kfree_skb(skb); 570 dev_kfree_skb(skb);
576 571
@@ -802,3 +797,40 @@ void sta_info_flush_delayed(struct ieee80211_sub_if_data *sdata)
802 schedule_work(&local->sta_flush_work); 797 schedule_work(&local->sta_flush_work);
803 spin_unlock_irqrestore(&local->sta_lock, flags); 798 spin_unlock_irqrestore(&local->sta_lock, flags);
804} 799}
800
801void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
802 unsigned long exp_time)
803{
804 struct ieee80211_local *local = sdata->local;
805 struct sta_info *sta, *tmp;
806 LIST_HEAD(tmp_list);
807 DECLARE_MAC_BUF(mac);
808 unsigned long flags;
809
810 spin_lock_irqsave(&local->sta_lock, flags);
811 list_for_each_entry_safe(sta, tmp, &local->sta_list, list)
812 if (time_after(jiffies, sta->last_rx + exp_time)) {
813#ifdef CONFIG_MAC80211_IBSS_DEBUG
814 printk(KERN_DEBUG "%s: expiring inactive STA %s\n",
815 sdata->dev->name, print_mac(mac, sta->sta.addr));
816#endif
817 __sta_info_unlink(&sta);
818 if (sta)
819 list_add(&sta->list, &tmp_list);
820 }
821 spin_unlock_irqrestore(&local->sta_lock, flags);
822
823 list_for_each_entry_safe(sta, tmp, &tmp_list, list)
824 sta_info_destroy(sta);
825}
826
827struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_hw *hw,
828 const u8 *addr)
829{
830 struct sta_info *sta = sta_info_get(hw_to_local(hw), addr);
831
832 if (!sta)
833 return NULL;
834 return &sta->sta;
835}
836EXPORT_SYMBOL(ieee80211_find_sta);
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 109db787ccb7..a6b51862a89d 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -167,8 +167,6 @@ struct sta_ampdu_mlme {
167 * @lock: used for locking all fields that require locking, see comments 167 * @lock: used for locking all fields that require locking, see comments
168 * in the header file. 168 * in the header file.
169 * @flaglock: spinlock for flags accesses 169 * @flaglock: spinlock for flags accesses
170 * @ht_info: HT capabilities of this STA
171 * @supp_rates: Bitmap of supported rates (per band)
172 * @addr: MAC address of this STA 170 * @addr: MAC address of this STA
173 * @aid: STA's unique AID (1..2007, 0 = not assigned yet), 171 * @aid: STA's unique AID (1..2007, 0 = not assigned yet),
174 * only used in AP (and IBSS?) mode 172 * only used in AP (and IBSS?) mode
@@ -191,20 +189,15 @@ struct sta_ampdu_mlme {
191 * @last_qual: qual of last received frame from this STA 189 * @last_qual: qual of last received frame from this STA
192 * @last_noise: noise of last received frame from this STA 190 * @last_noise: noise of last received frame from this STA
193 * @last_seq_ctrl: last received seq/frag number from this STA (per RX queue) 191 * @last_seq_ctrl: last received seq/frag number from this STA (per RX queue)
194 * @wme_rx_queue: TBD
195 * @tx_filtered_count: TBD 192 * @tx_filtered_count: TBD
196 * @tx_retry_failed: TBD 193 * @tx_retry_failed: TBD
197 * @tx_retry_count: TBD 194 * @tx_retry_count: TBD
198 * @tx_num_consecutive_failures: TBD
199 * @tx_num_mpdu_ok: TBD
200 * @tx_num_mpdu_fail: TBD
201 * @fail_avg: moving percentage of failed MSDUs 195 * @fail_avg: moving percentage of failed MSDUs
202 * @tx_packets: number of RX/TX MSDUs 196 * @tx_packets: number of RX/TX MSDUs
203 * @tx_bytes: TBD 197 * @tx_bytes: TBD
204 * @tx_fragments: number of transmitted MPDUs 198 * @tx_fragments: number of transmitted MPDUs
205 * @txrate_idx: TBD 199 * @last_txrate_idx: Index of the last used transmit rate
206 * @last_txrate_idx: TBD 200 * @tid_seq: TBD
207 * @wme_tx_queue: TBD
208 * @ampdu_mlme: TBD 201 * @ampdu_mlme: TBD
209 * @timer_to_tid: identity mapping to ID timers 202 * @timer_to_tid: identity mapping to ID timers
210 * @tid_to_tx_q: map tid to tx queue 203 * @tid_to_tx_q: map tid to tx queue
@@ -217,6 +210,7 @@ struct sta_ampdu_mlme {
217 * @plink_timeout: TBD 210 * @plink_timeout: TBD
218 * @plink_timer: TBD 211 * @plink_timer: TBD
219 * @debugfs: debug filesystem info 212 * @debugfs: debug filesystem info
213 * @sta: station information we share with the driver
220 */ 214 */
221struct sta_info { 215struct sta_info {
222 /* General information, mostly static */ 216 /* General information, mostly static */
@@ -229,10 +223,7 @@ struct sta_info {
229 void *rate_ctrl_priv; 223 void *rate_ctrl_priv;
230 spinlock_t lock; 224 spinlock_t lock;
231 spinlock_t flaglock; 225 spinlock_t flaglock;
232 struct ieee80211_ht_info ht_info; 226
233 u64 supp_rates[IEEE80211_NUM_BANDS];
234 u8 addr[ETH_ALEN];
235 u16 aid;
236 u16 listen_interval; 227 u16 listen_interval;
237 228
238 /* 229 /*
@@ -265,17 +256,10 @@ struct sta_info {
265 int last_qual; 256 int last_qual;
266 int last_noise; 257 int last_noise;
267 __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES]; 258 __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES];
268#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
269 unsigned int wme_rx_queue[NUM_RX_DATA_QUEUES];
270#endif
271 259
272 /* Updated from TX status path only, no locking requirements */ 260 /* Updated from TX status path only, no locking requirements */
273 unsigned long tx_filtered_count; 261 unsigned long tx_filtered_count;
274 unsigned long tx_retry_failed, tx_retry_count; 262 unsigned long tx_retry_failed, tx_retry_count;
275 /* TODO: update in generic code not rate control? */
276 u32 tx_num_consecutive_failures;
277 u32 tx_num_mpdu_ok;
278 u32 tx_num_mpdu_fail;
279 /* moving percentage of failed MSDUs */ 263 /* moving percentage of failed MSDUs */
280 unsigned int fail_avg; 264 unsigned int fail_avg;
281 265
@@ -283,12 +267,8 @@ struct sta_info {
283 unsigned long tx_packets; 267 unsigned long tx_packets;
284 unsigned long tx_bytes; 268 unsigned long tx_bytes;
285 unsigned long tx_fragments; 269 unsigned long tx_fragments;
286 int txrate_idx; 270 unsigned int last_txrate_idx;
287 int last_txrate_idx;
288 u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1]; 271 u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1];
289#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
290 unsigned int wme_tx_queue[NUM_RX_DATA_QUEUES];
291#endif
292 272
293 /* 273 /*
294 * Aggregation information, locked with lock. 274 * Aggregation information, locked with lock.
@@ -319,13 +299,12 @@ struct sta_info {
319 struct dentry *num_ps_buf_frames; 299 struct dentry *num_ps_buf_frames;
320 struct dentry *inactive_ms; 300 struct dentry *inactive_ms;
321 struct dentry *last_seq_ctrl; 301 struct dentry *last_seq_ctrl;
322#ifdef CONFIG_MAC80211_DEBUG_COUNTERS
323 struct dentry *wme_rx_queue;
324 struct dentry *wme_tx_queue;
325#endif
326 struct dentry *agg_status; 302 struct dentry *agg_status;
327 } debugfs; 303 } debugfs;
328#endif 304#endif
305
306 /* keep last! */
307 struct ieee80211_sta sta;
329}; 308};
330 309
331static inline enum plink_state sta_plink_state(struct sta_info *sta) 310static inline enum plink_state sta_plink_state(struct sta_info *sta)
@@ -425,7 +404,7 @@ static inline u32 get_sta_flags(struct sta_info *sta)
425/* 404/*
426 * Get a STA info, must have be under RCU read lock. 405 * Get a STA info, must have be under RCU read lock.
427 */ 406 */
428struct sta_info *sta_info_get(struct ieee80211_local *local, u8 *addr); 407struct sta_info *sta_info_get(struct ieee80211_local *local, const u8 *addr);
429/* 408/*
430 * Get STA info by index, BROKEN! 409 * Get STA info by index, BROKEN!
431 */ 410 */
@@ -451,7 +430,6 @@ int sta_info_insert(struct sta_info *sta);
451 * has already unlinked it. 430 * has already unlinked it.
452 */ 431 */
453void sta_info_unlink(struct sta_info **sta); 432void sta_info_unlink(struct sta_info **sta);
454void __sta_info_unlink(struct sta_info **sta);
455 433
456void sta_info_destroy(struct sta_info *sta); 434void sta_info_destroy(struct sta_info *sta);
457void sta_info_set_tim_bit(struct sta_info *sta); 435void sta_info_set_tim_bit(struct sta_info *sta);
@@ -463,5 +441,7 @@ void sta_info_stop(struct ieee80211_local *local);
463int sta_info_flush(struct ieee80211_local *local, 441int sta_info_flush(struct ieee80211_local *local,
464 struct ieee80211_sub_if_data *sdata); 442 struct ieee80211_sub_if_data *sdata);
465void sta_info_flush_delayed(struct ieee80211_sub_if_data *sdata); 443void sta_info_flush_delayed(struct ieee80211_sub_if_data *sdata);
444void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
445 unsigned long exp_time);
466 446
467#endif /* STA_INFO_H */ 447#endif /* STA_INFO_H */
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c
index 995f7af3d25e..34b32bc8f609 100644
--- a/net/mac80211/tkip.c
+++ b/net/mac80211/tkip.c
@@ -304,7 +304,7 @@ int ieee80211_tkip_decrypt_data(struct crypto_blkcipher *tfm,
304 key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { 304 key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
305 u8 bcast[ETH_ALEN] = 305 u8 bcast[ETH_ALEN] =
306 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 306 {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
307 u8 *sta_addr = key->sta->addr; 307 u8 *sta_addr = key->sta->sta.addr;
308 308
309 if (is_multicast_ether_addr(ra)) 309 if (is_multicast_ether_addr(ra))
310 sta_addr = bcast; 310 sta_addr = bcast;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 4788f7b91f49..1460537faf33 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -38,43 +38,6 @@
38 38
39/* misc utils */ 39/* misc utils */
40 40
41#ifdef CONFIG_MAC80211_LOWTX_FRAME_DUMP
42static void ieee80211_dump_frame(const char *ifname, const char *title,
43 const struct sk_buff *skb)
44{
45 const struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
46 unsigned int hdrlen;
47 DECLARE_MAC_BUF(mac);
48
49 printk(KERN_DEBUG "%s: %s (len=%d)", ifname, title, skb->len);
50 if (skb->len < 4) {
51 printk("\n");
52 return;
53 }
54
55 hdrlen = ieee80211_hdrlen(hdr->frame_control);
56 if (hdrlen > skb->len)
57 hdrlen = skb->len;
58 if (hdrlen >= 4)
59 printk(" FC=0x%04x DUR=0x%04x",
60 le16_to_cpu(hdr->frame_control), le16_to_cpu(hdr->duration_id));
61 if (hdrlen >= 10)
62 printk(" A1=%s", print_mac(mac, hdr->addr1));
63 if (hdrlen >= 16)
64 printk(" A2=%s", print_mac(mac, hdr->addr2));
65 if (hdrlen >= 24)
66 printk(" A3=%s", print_mac(mac, hdr->addr3));
67 if (hdrlen >= 30)
68 printk(" A4=%s", print_mac(mac, hdr->addr4));
69 printk("\n");
70}
71#else /* CONFIG_MAC80211_LOWTX_FRAME_DUMP */
72static inline void ieee80211_dump_frame(const char *ifname, const char *title,
73 struct sk_buff *skb)
74{
75}
76#endif /* CONFIG_MAC80211_LOWTX_FRAME_DUMP */
77
78static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr, 41static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr,
79 int next_frag_len) 42 int next_frag_len)
80{ 43{
@@ -82,6 +45,7 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr,
82 struct ieee80211_rate *txrate; 45 struct ieee80211_rate *txrate;
83 struct ieee80211_local *local = tx->local; 46 struct ieee80211_local *local = tx->local;
84 struct ieee80211_supported_band *sband; 47 struct ieee80211_supported_band *sband;
48 struct ieee80211_hdr *hdr;
85 49
86 sband = local->hw.wiphy->bands[tx->channel->band]; 50 sband = local->hw.wiphy->bands[tx->channel->band];
87 txrate = &sband->bitrates[tx->rate_idx]; 51 txrate = &sband->bitrates[tx->rate_idx];
@@ -107,10 +71,10 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr,
107 * at the highest possible rate belonging to the PHY rates in the 71 * at the highest possible rate belonging to the PHY rates in the
108 * BSSBasicRateSet 72 * BSSBasicRateSet
109 */ 73 */
110 74 hdr = (struct ieee80211_hdr *)tx->skb->data;
111 if ((tx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) { 75 if (ieee80211_is_ctl(hdr->frame_control)) {
112 /* TODO: These control frames are not currently sent by 76 /* TODO: These control frames are not currently sent by
113 * 80211.o, but should they be implemented, this function 77 * mac80211, but should they be implemented, this function
114 * needs to be updated to support duration field calculation. 78 * needs to be updated to support duration field calculation.
115 * 79 *
116 * RTS: time needed to transmit pending data/mgmt frame plus 80 * RTS: time needed to transmit pending data/mgmt frame plus
@@ -152,7 +116,7 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr,
152 if (r->bitrate > txrate->bitrate) 116 if (r->bitrate > txrate->bitrate)
153 break; 117 break;
154 118
155 if (tx->sdata->basic_rates & BIT(i)) 119 if (tx->sdata->bss_conf.basic_rates & BIT(i))
156 rate = r->bitrate; 120 rate = r->bitrate;
157 121
158 switch (sband->band) { 122 switch (sband->band) {
@@ -201,11 +165,10 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, int group_addr,
201 return cpu_to_le16(dur); 165 return cpu_to_le16(dur);
202} 166}
203 167
204static int inline is_ieee80211_device(struct net_device *dev, 168static int inline is_ieee80211_device(struct ieee80211_local *local,
205 struct net_device *master) 169 struct net_device *dev)
206{ 170{
207 return (wdev_priv(dev->ieee80211_ptr) == 171 return local == wdev_priv(dev->ieee80211_ptr);
208 wdev_priv(master->ieee80211_ptr));
209} 172}
210 173
211/* tx handlers */ 174/* tx handlers */
@@ -213,21 +176,19 @@ static int inline is_ieee80211_device(struct net_device *dev,
213static ieee80211_tx_result debug_noinline 176static ieee80211_tx_result debug_noinline
214ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) 177ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
215{ 178{
216#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 179
217 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; 180 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
218#endif /* CONFIG_MAC80211_VERBOSE_DEBUG */
219 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); 181 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
220 u32 sta_flags; 182 u32 sta_flags;
221 183
222 if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) 184 if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED))
223 return TX_CONTINUE; 185 return TX_CONTINUE;
224 186
225 if (unlikely(tx->local->sta_sw_scanning) && 187 if (unlikely(tx->local->sw_scanning) &&
226 ((tx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT || 188 !ieee80211_is_probe_req(hdr->frame_control))
227 (tx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_PROBE_REQ))
228 return TX_DROP; 189 return TX_DROP;
229 190
230 if (tx->sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT) 191 if (tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
231 return TX_CONTINUE; 192 return TX_CONTINUE;
232 193
233 if (tx->flags & IEEE80211_TX_PS_BUFFERED) 194 if (tx->flags & IEEE80211_TX_PS_BUFFERED)
@@ -237,8 +198,8 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
237 198
238 if (likely(tx->flags & IEEE80211_TX_UNICAST)) { 199 if (likely(tx->flags & IEEE80211_TX_UNICAST)) {
239 if (unlikely(!(sta_flags & WLAN_STA_ASSOC) && 200 if (unlikely(!(sta_flags & WLAN_STA_ASSOC) &&
240 tx->sdata->vif.type != IEEE80211_IF_TYPE_IBSS && 201 tx->sdata->vif.type != NL80211_IFTYPE_ADHOC &&
241 (tx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA)) { 202 ieee80211_is_data(hdr->frame_control))) {
242#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 203#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
243 DECLARE_MAC_BUF(mac); 204 DECLARE_MAC_BUF(mac);
244 printk(KERN_DEBUG "%s: dropped data frame to not " 205 printk(KERN_DEBUG "%s: dropped data frame to not "
@@ -249,9 +210,9 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
249 return TX_DROP; 210 return TX_DROP;
250 } 211 }
251 } else { 212 } else {
252 if (unlikely((tx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA && 213 if (unlikely(ieee80211_is_data(hdr->frame_control) &&
253 tx->local->num_sta == 0 && 214 tx->local->num_sta == 0 &&
254 tx->sdata->vif.type != IEEE80211_IF_TYPE_IBSS)) { 215 tx->sdata->vif.type != NL80211_IFTYPE_ADHOC)) {
255 /* 216 /*
256 * No associated STAs - no need to send multicast 217 * No associated STAs - no need to send multicast
257 * frames. 218 * frames.
@@ -282,7 +243,7 @@ static void purge_old_ps_buffers(struct ieee80211_local *local)
282 243
283 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 244 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
284 struct ieee80211_if_ap *ap; 245 struct ieee80211_if_ap *ap;
285 if (sdata->vif.type != IEEE80211_IF_TYPE_AP) 246 if (sdata->vif.type != NL80211_IFTYPE_AP)
286 continue; 247 continue;
287 ap = &sdata->u.ap; 248 ap = &sdata->u.ap;
288 skb = skb_dequeue(&ap->ps_bc_buf); 249 skb = skb_dequeue(&ap->ps_bc_buf);
@@ -315,6 +276,7 @@ static ieee80211_tx_result
315ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) 276ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx)
316{ 277{
317 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); 278 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
279 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
318 280
319 /* 281 /*
320 * broadcast/multicast frame 282 * broadcast/multicast frame
@@ -329,7 +291,7 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx)
329 return TX_CONTINUE; 291 return TX_CONTINUE;
330 292
331 /* no buffering for ordered frames */ 293 /* no buffering for ordered frames */
332 if (tx->fc & IEEE80211_FCTL_ORDER) 294 if (ieee80211_has_order(hdr->frame_control))
333 return TX_CONTINUE; 295 return TX_CONTINUE;
334 296
335 /* no stations in PS mode */ 297 /* no stations in PS mode */
@@ -367,12 +329,11 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
367{ 329{
368 struct sta_info *sta = tx->sta; 330 struct sta_info *sta = tx->sta;
369 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); 331 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
332 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
370 u32 staflags; 333 u32 staflags;
371 DECLARE_MAC_BUF(mac); 334 DECLARE_MAC_BUF(mac);
372 335
373 if (unlikely(!sta || 336 if (unlikely(!sta || ieee80211_is_probe_resp(hdr->frame_control)))
374 ((tx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT &&
375 (tx->fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP)))
376 return TX_CONTINUE; 337 return TX_CONTINUE;
377 338
378 staflags = get_sta_flags(sta); 339 staflags = get_sta_flags(sta);
@@ -382,7 +343,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
382#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG 343#ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG
383 printk(KERN_DEBUG "STA %s aid %d: PS buffer (entries " 344 printk(KERN_DEBUG "STA %s aid %d: PS buffer (entries "
384 "before %d)\n", 345 "before %d)\n",
385 print_mac(mac, sta->addr), sta->aid, 346 print_mac(mac, sta->sta.addr), sta->sta.aid,
386 skb_queue_len(&sta->ps_tx_buf)); 347 skb_queue_len(&sta->ps_tx_buf));
387#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 348#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
388 if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) 349 if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER)
@@ -393,7 +354,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
393 if (net_ratelimit()) { 354 if (net_ratelimit()) {
394 printk(KERN_DEBUG "%s: STA %s TX " 355 printk(KERN_DEBUG "%s: STA %s TX "
395 "buffer full - dropping oldest frame\n", 356 "buffer full - dropping oldest frame\n",
396 tx->dev->name, print_mac(mac, sta->addr)); 357 tx->dev->name, print_mac(mac, sta->sta.addr));
397 } 358 }
398#endif 359#endif
399 dev_kfree_skb(old); 360 dev_kfree_skb(old);
@@ -412,7 +373,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
412 else if (unlikely(test_sta_flags(sta, WLAN_STA_PS))) { 373 else if (unlikely(test_sta_flags(sta, WLAN_STA_PS))) {
413 printk(KERN_DEBUG "%s: STA %s in PS mode, but pspoll " 374 printk(KERN_DEBUG "%s: STA %s in PS mode, but pspoll "
414 "set -> send frame\n", tx->dev->name, 375 "set -> send frame\n", tx->dev->name,
415 print_mac(mac, sta->addr)); 376 print_mac(mac, sta->sta.addr));
416 } 377 }
417#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ 378#endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */
418 clear_sta_flags(sta, WLAN_STA_PSPOLL); 379 clear_sta_flags(sta, WLAN_STA_PSPOLL);
@@ -437,7 +398,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
437{ 398{
438 struct ieee80211_key *key; 399 struct ieee80211_key *key;
439 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); 400 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
440 u16 fc = tx->fc; 401 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
441 402
442 if (unlikely(tx->skb->do_not_encrypt)) 403 if (unlikely(tx->skb->do_not_encrypt))
443 tx->key = NULL; 404 tx->key = NULL;
@@ -454,22 +415,16 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
454 tx->key = NULL; 415 tx->key = NULL;
455 416
456 if (tx->key) { 417 if (tx->key) {
457 u16 ftype, stype;
458
459 tx->key->tx_rx_count++; 418 tx->key->tx_rx_count++;
460 /* TODO: add threshold stuff again */ 419 /* TODO: add threshold stuff again */
461 420
462 switch (tx->key->conf.alg) { 421 switch (tx->key->conf.alg) {
463 case ALG_WEP: 422 case ALG_WEP:
464 ftype = fc & IEEE80211_FCTL_FTYPE; 423 if (ieee80211_is_auth(hdr->frame_control))
465 stype = fc & IEEE80211_FCTL_STYPE;
466
467 if (ftype == IEEE80211_FTYPE_MGMT &&
468 stype == IEEE80211_STYPE_AUTH)
469 break; 424 break;
470 case ALG_TKIP: 425 case ALG_TKIP:
471 case ALG_CCMP: 426 case ALG_CCMP:
472 if (!WLAN_FC_DATA_PRESENT(fc)) 427 if (!ieee80211_is_data_present(hdr->frame_control))
473 tx->key = NULL; 428 tx->key = NULL;
474 break; 429 break;
475 } 430 }
@@ -491,20 +446,24 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
491 sband = tx->local->hw.wiphy->bands[tx->channel->band]; 446 sband = tx->local->hw.wiphy->bands[tx->channel->band];
492 447
493 if (likely(tx->rate_idx < 0)) { 448 if (likely(tx->rate_idx < 0)) {
494 rate_control_get_rate(tx->dev, sband, tx->skb, &rsel); 449 rate_control_get_rate(tx->sdata, sband, tx->sta,
450 tx->skb, &rsel);
451 if (tx->sta)
452 tx->sta->last_txrate_idx = rsel.rate_idx;
495 tx->rate_idx = rsel.rate_idx; 453 tx->rate_idx = rsel.rate_idx;
496 if (unlikely(rsel.probe_idx >= 0)) { 454 if (unlikely(rsel.probe_idx >= 0)) {
497 info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; 455 info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
498 tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG; 456 tx->flags |= IEEE80211_TX_PROBE_LAST_FRAG;
499 info->control.alt_retry_rate_idx = tx->rate_idx; 457 info->control.retries[0].rate_idx = tx->rate_idx;
458 info->control.retries[0].limit = tx->local->hw.max_altrate_tries;
500 tx->rate_idx = rsel.probe_idx; 459 tx->rate_idx = rsel.probe_idx;
501 } else 460 } else if (info->control.retries[0].limit == 0)
502 info->control.alt_retry_rate_idx = -1; 461 info->control.retries[0].rate_idx = -1;
503 462
504 if (unlikely(tx->rate_idx < 0)) 463 if (unlikely(tx->rate_idx < 0))
505 return TX_DROP; 464 return TX_DROP;
506 } else 465 } else
507 info->control.alt_retry_rate_idx = -1; 466 info->control.retries[0].rate_idx = -1;
508 467
509 if (tx->sdata->bss_conf.use_cts_prot && 468 if (tx->sdata->bss_conf.use_cts_prot &&
510 (tx->flags & IEEE80211_TX_FRAGMENTED) && (rsel.nonerp_idx >= 0)) { 469 (tx->flags & IEEE80211_TX_FRAGMENTED) && (rsel.nonerp_idx >= 0)) {
@@ -535,7 +494,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
535 sband = tx->local->hw.wiphy->bands[tx->channel->band]; 494 sband = tx->local->hw.wiphy->bands[tx->channel->band];
536 495
537 if (tx->sta) 496 if (tx->sta)
538 info->control.aid = tx->sta->aid; 497 info->control.sta = &tx->sta->sta;
539 498
540 if (!info->control.retry_limit) { 499 if (!info->control.retry_limit) {
541 if (!is_multicast_ether_addr(hdr->addr1)) { 500 if (!is_multicast_ether_addr(hdr->addr1)) {
@@ -563,7 +522,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
563 * frames. 522 * frames.
564 * TODO: The last fragment could still use multiple retry 523 * TODO: The last fragment could still use multiple retry
565 * rates. */ 524 * rates. */
566 info->control.alt_retry_rate_idx = -1; 525 info->control.retries[0].rate_idx = -1;
567 } 526 }
568 527
569 /* Use CTS protection for unicast frames sent using extended rates if 528 /* Use CTS protection for unicast frames sent using extended rates if
@@ -593,7 +552,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
593 int idx; 552 int idx;
594 553
595 /* Do not use multiple retry rates when using RTS/CTS */ 554 /* Do not use multiple retry rates when using RTS/CTS */
596 info->control.alt_retry_rate_idx = -1; 555 info->control.retries[0].rate_idx = -1;
597 556
598 /* Use min(data rate, max base rate) as CTS/RTS rate */ 557 /* Use min(data rate, max base rate) as CTS/RTS rate */
599 rate = &sband->bitrates[tx->rate_idx]; 558 rate = &sband->bitrates[tx->rate_idx];
@@ -601,7 +560,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
601 for (idx = 0; idx < sband->n_bitrates; idx++) { 560 for (idx = 0; idx < sband->n_bitrates; idx++) {
602 if (sband->bitrates[idx].bitrate > rate->bitrate) 561 if (sband->bitrates[idx].bitrate > rate->bitrate)
603 continue; 562 continue;
604 if (tx->sdata->basic_rates & BIT(idx) && 563 if (tx->sdata->bss_conf.basic_rates & BIT(idx) &&
605 (baserate < 0 || 564 (baserate < 0 ||
606 (sband->bitrates[baserate].bitrate 565 (sband->bitrates[baserate].bitrate
607 < sband->bitrates[idx].bitrate))) 566 < sband->bitrates[idx].bitrate)))
@@ -615,7 +574,7 @@ ieee80211_tx_h_misc(struct ieee80211_tx_data *tx)
615 } 574 }
616 575
617 if (tx->sta) 576 if (tx->sta)
618 info->control.aid = tx->sta->aid; 577 info->control.sta = &tx->sta->sta;
619 578
620 return TX_CONTINUE; 579 return TX_CONTINUE;
621} 580}
@@ -629,7 +588,14 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
629 u8 *qc; 588 u8 *qc;
630 int tid; 589 int tid;
631 590
632 /* only for injected frames */ 591 /*
592 * Packet injection may want to control the sequence
593 * number, if we have no matching interface then we
594 * neither assign one ourselves nor ask the driver to.
595 */
596 if (unlikely(!info->control.vif))
597 return TX_CONTINUE;
598
633 if (unlikely(ieee80211_is_ctl(hdr->frame_control))) 599 if (unlikely(ieee80211_is_ctl(hdr->frame_control)))
634 return TX_CONTINUE; 600 return TX_CONTINUE;
635 601
@@ -854,7 +820,6 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
854 sband = tx->local->hw.wiphy->bands[tx->channel->band]; 820 sband = tx->local->hw.wiphy->bands[tx->channel->band];
855 821
856 skb->do_not_encrypt = 1; 822 skb->do_not_encrypt = 1;
857 info->flags |= IEEE80211_TX_CTL_INJECTED;
858 tx->flags &= ~IEEE80211_TX_FRAGMENTED; 823 tx->flags &= ~IEEE80211_TX_FRAGMENTED;
859 824
860 /* 825 /*
@@ -986,7 +951,7 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
986 951
987 /* process and remove the injection radiotap header */ 952 /* process and remove the injection radiotap header */
988 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 953 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
989 if (unlikely(sdata->vif.type == IEEE80211_IF_TYPE_MNTR)) { 954 if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) {
990 if (__ieee80211_parse_tx_radiotap(tx, skb) == TX_DROP) 955 if (__ieee80211_parse_tx_radiotap(tx, skb) == TX_DROP)
991 return TX_DROP; 956 return TX_DROP;
992 957
@@ -1000,7 +965,6 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
1000 hdr = (struct ieee80211_hdr *) skb->data; 965 hdr = (struct ieee80211_hdr *) skb->data;
1001 966
1002 tx->sta = sta_info_get(local, hdr->addr1); 967 tx->sta = sta_info_get(local, hdr->addr1);
1003 tx->fc = le16_to_cpu(hdr->frame_control);
1004 968
1005 if (is_multicast_ether_addr(hdr->addr1)) { 969 if (is_multicast_ether_addr(hdr->addr1)) {
1006 tx->flags &= ~IEEE80211_TX_UNICAST; 970 tx->flags &= ~IEEE80211_TX_UNICAST;
@@ -1025,7 +989,7 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
1025 else if (test_and_clear_sta_flags(tx->sta, WLAN_STA_CLEAR_PS_FILT)) 989 else if (test_and_clear_sta_flags(tx->sta, WLAN_STA_CLEAR_PS_FILT))
1026 info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; 990 info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
1027 991
1028 hdrlen = ieee80211_get_hdrlen(tx->fc); 992 hdrlen = ieee80211_hdrlen(hdr->frame_control);
1029 if (skb->len > hdrlen + sizeof(rfc1042_header) + 2) { 993 if (skb->len > hdrlen + sizeof(rfc1042_header) + 2) {
1030 u8 *pos = &skb->data[hdrlen + sizeof(rfc1042_header)]; 994 u8 *pos = &skb->data[hdrlen + sizeof(rfc1042_header)];
1031 tx->ethertype = (pos[0] << 8) | pos[1]; 995 tx->ethertype = (pos[0] << 8) | pos[1];
@@ -1038,14 +1002,14 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
1038/* 1002/*
1039 * NB: @tx is uninitialised when passed in here 1003 * NB: @tx is uninitialised when passed in here
1040 */ 1004 */
1041static int ieee80211_tx_prepare(struct ieee80211_tx_data *tx, 1005static int ieee80211_tx_prepare(struct ieee80211_local *local,
1042 struct sk_buff *skb, 1006 struct ieee80211_tx_data *tx,
1043 struct net_device *mdev) 1007 struct sk_buff *skb)
1044{ 1008{
1045 struct net_device *dev; 1009 struct net_device *dev;
1046 1010
1047 dev = dev_get_by_index(&init_net, skb->iif); 1011 dev = dev_get_by_index(&init_net, skb->iif);
1048 if (unlikely(dev && !is_ieee80211_device(dev, mdev))) { 1012 if (unlikely(dev && !is_ieee80211_device(local, dev))) {
1049 dev_put(dev); 1013 dev_put(dev);
1050 dev = NULL; 1014 dev = NULL;
1051 } 1015 }
@@ -1068,8 +1032,6 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb,
1068 return IEEE80211_TX_AGAIN; 1032 return IEEE80211_TX_AGAIN;
1069 info = IEEE80211_SKB_CB(skb); 1033 info = IEEE80211_SKB_CB(skb);
1070 1034
1071 ieee80211_dump_frame(wiphy_name(local->hw.wiphy),
1072 "TX to low-level driver", skb);
1073 ret = local->ops->tx(local_to_hw(local), skb); 1035 ret = local->ops->tx(local_to_hw(local), skb);
1074 if (ret) 1036 if (ret)
1075 return IEEE80211_TX_AGAIN; 1037 return IEEE80211_TX_AGAIN;
@@ -1099,9 +1061,6 @@ static int __ieee80211_tx(struct ieee80211_local *local, struct sk_buff *skb,
1099 ~IEEE80211_TX_CTL_RATE_CTRL_PROBE; 1061 ~IEEE80211_TX_CTL_RATE_CTRL_PROBE;
1100 } 1062 }
1101 1063
1102 ieee80211_dump_frame(wiphy_name(local->hw.wiphy),
1103 "TX to low-level driver",
1104 tx->extra_frag[i]);
1105 ret = local->ops->tx(local_to_hw(local), 1064 ret = local->ops->tx(local_to_hw(local),
1106 tx->extra_frag[i]); 1065 tx->extra_frag[i]);
1107 if (ret) 1066 if (ret)
@@ -1297,20 +1256,26 @@ static int ieee80211_skb_resize(struct ieee80211_local *local,
1297 return 0; 1256 return 0;
1298} 1257}
1299 1258
1300int ieee80211_master_start_xmit(struct sk_buff *skb, 1259int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
1301 struct net_device *dev)
1302{ 1260{
1261 struct ieee80211_master_priv *mpriv = netdev_priv(dev);
1262 struct ieee80211_local *local = mpriv->local;
1303 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1263 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1304 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 1264 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1305 struct net_device *odev = NULL; 1265 struct net_device *odev = NULL;
1306 struct ieee80211_sub_if_data *osdata; 1266 struct ieee80211_sub_if_data *osdata;
1307 int headroom; 1267 int headroom;
1308 bool may_encrypt; 1268 bool may_encrypt;
1269 enum {
1270 NOT_MONITOR,
1271 FOUND_SDATA,
1272 UNKNOWN_ADDRESS,
1273 } monitor_iface = NOT_MONITOR;
1309 int ret; 1274 int ret;
1310 1275
1311 if (skb->iif) 1276 if (skb->iif)
1312 odev = dev_get_by_index(&init_net, skb->iif); 1277 odev = dev_get_by_index(&init_net, skb->iif);
1313 if (unlikely(odev && !is_ieee80211_device(odev, dev))) { 1278 if (unlikely(odev && !is_ieee80211_device(local, odev))) {
1314 dev_put(odev); 1279 dev_put(odev);
1315 odev = NULL; 1280 odev = NULL;
1316 } 1281 }
@@ -1331,15 +1296,55 @@ int ieee80211_master_start_xmit(struct sk_buff *skb,
1331 1296
1332 if (ieee80211_vif_is_mesh(&osdata->vif) && 1297 if (ieee80211_vif_is_mesh(&osdata->vif) &&
1333 ieee80211_is_data(hdr->frame_control)) { 1298 ieee80211_is_data(hdr->frame_control)) {
1334 if (ieee80211_is_data(hdr->frame_control)) { 1299 if (is_multicast_ether_addr(hdr->addr3))
1335 if (is_multicast_ether_addr(hdr->addr3)) 1300 memcpy(hdr->addr1, hdr->addr3, ETH_ALEN);
1336 memcpy(hdr->addr1, hdr->addr3, ETH_ALEN); 1301 else
1337 else 1302 if (mesh_nexthop_lookup(skb, osdata))
1338 if (mesh_nexthop_lookup(skb, odev)) 1303 return 0;
1339 return 0; 1304 if (memcmp(odev->dev_addr, hdr->addr4, ETH_ALEN) != 0)
1340 if (memcmp(odev->dev_addr, hdr->addr4, ETH_ALEN) != 0) 1305 IEEE80211_IFSTA_MESH_CTR_INC(&osdata->u.mesh,
1341 IEEE80211_IFSTA_MESH_CTR_INC(&osdata->u.sta, 1306 fwded_frames);
1342 fwded_frames); 1307 } else if (unlikely(osdata->vif.type == NL80211_IFTYPE_MONITOR)) {
1308 struct ieee80211_sub_if_data *sdata;
1309 int hdrlen;
1310 u16 len_rthdr;
1311
1312 info->flags |= IEEE80211_TX_CTL_INJECTED;
1313 monitor_iface = UNKNOWN_ADDRESS;
1314
1315 len_rthdr = ieee80211_get_radiotap_len(skb->data);
1316 hdr = (struct ieee80211_hdr *)skb->data + len_rthdr;
1317 hdrlen = ieee80211_hdrlen(hdr->frame_control);
1318
1319 /* check the header is complete in the frame */
1320 if (likely(skb->len >= len_rthdr + hdrlen)) {
1321 /*
1322 * We process outgoing injected frames that have a
1323 * local address we handle as though they are our
1324 * own frames.
1325 * This code here isn't entirely correct, the local
1326 * MAC address is not necessarily enough to find
1327 * the interface to use; for that proper VLAN/WDS
1328 * support we will need a different mechanism.
1329 */
1330
1331 rcu_read_lock();
1332 list_for_each_entry_rcu(sdata, &local->interfaces,
1333 list) {
1334 if (!netif_running(sdata->dev))
1335 continue;
1336 if (compare_ether_addr(sdata->dev->dev_addr,
1337 hdr->addr2)) {
1338 dev_hold(sdata->dev);
1339 dev_put(odev);
1340 osdata = sdata;
1341 odev = osdata->dev;
1342 skb->iif = sdata->dev->ifindex;
1343 monitor_iface = FOUND_SDATA;
1344 break;
1345 }
1346 }
1347 rcu_read_unlock();
1343 } 1348 }
1344 } 1349 }
1345 1350
@@ -1357,7 +1362,12 @@ int ieee80211_master_start_xmit(struct sk_buff *skb,
1357 return 0; 1362 return 0;
1358 } 1363 }
1359 1364
1360 info->control.vif = &osdata->vif; 1365 if (osdata->vif.type == NL80211_IFTYPE_AP_VLAN)
1366 osdata = container_of(osdata->bss,
1367 struct ieee80211_sub_if_data,
1368 u.ap);
1369 if (likely(monitor_iface != UNKNOWN_ADDRESS))
1370 info->control.vif = &osdata->vif;
1361 ret = ieee80211_tx(odev, skb); 1371 ret = ieee80211_tx(odev, skb);
1362 dev_put(odev); 1372 dev_put(odev);
1363 1373
@@ -1437,8 +1447,8 @@ fail:
1437int ieee80211_subif_start_xmit(struct sk_buff *skb, 1447int ieee80211_subif_start_xmit(struct sk_buff *skb,
1438 struct net_device *dev) 1448 struct net_device *dev)
1439{ 1449{
1440 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1450 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1441 struct ieee80211_sub_if_data *sdata; 1451 struct ieee80211_local *local = sdata->local;
1442 int ret = 1, head_need; 1452 int ret = 1, head_need;
1443 u16 ethertype, hdrlen, meshhdrlen = 0; 1453 u16 ethertype, hdrlen, meshhdrlen = 0;
1444 __le16 fc; 1454 __le16 fc;
@@ -1450,7 +1460,6 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1450 struct sta_info *sta; 1460 struct sta_info *sta;
1451 u32 sta_flags = 0; 1461 u32 sta_flags = 0;
1452 1462
1453 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1454 if (unlikely(skb->len < ETH_HLEN)) { 1463 if (unlikely(skb->len < ETH_HLEN)) {
1455 ret = 0; 1464 ret = 0;
1456 goto fail; 1465 goto fail;
@@ -1465,8 +1474,8 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1465 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA); 1474 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA);
1466 1475
1467 switch (sdata->vif.type) { 1476 switch (sdata->vif.type) {
1468 case IEEE80211_IF_TYPE_AP: 1477 case NL80211_IFTYPE_AP:
1469 case IEEE80211_IF_TYPE_VLAN: 1478 case NL80211_IFTYPE_AP_VLAN:
1470 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS); 1479 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS);
1471 /* DA BSSID SA */ 1480 /* DA BSSID SA */
1472 memcpy(hdr.addr1, skb->data, ETH_ALEN); 1481 memcpy(hdr.addr1, skb->data, ETH_ALEN);
@@ -1474,7 +1483,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1474 memcpy(hdr.addr3, skb->data + ETH_ALEN, ETH_ALEN); 1483 memcpy(hdr.addr3, skb->data + ETH_ALEN, ETH_ALEN);
1475 hdrlen = 24; 1484 hdrlen = 24;
1476 break; 1485 break;
1477 case IEEE80211_IF_TYPE_WDS: 1486 case NL80211_IFTYPE_WDS:
1478 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); 1487 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
1479 /* RA TA DA SA */ 1488 /* RA TA DA SA */
1480 memcpy(hdr.addr1, sdata->u.wds.remote_addr, ETH_ALEN); 1489 memcpy(hdr.addr1, sdata->u.wds.remote_addr, ETH_ALEN);
@@ -1484,24 +1493,56 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1484 hdrlen = 30; 1493 hdrlen = 30;
1485 break; 1494 break;
1486#ifdef CONFIG_MAC80211_MESH 1495#ifdef CONFIG_MAC80211_MESH
1487 case IEEE80211_IF_TYPE_MESH_POINT: 1496 case NL80211_IFTYPE_MESH_POINT:
1488 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS); 1497 fc |= cpu_to_le16(IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
1489 /* RA TA DA SA */ 1498 if (!sdata->u.mesh.mshcfg.dot11MeshTTL) {
1490 memset(hdr.addr1, 0, ETH_ALEN);
1491 memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN);
1492 memcpy(hdr.addr3, skb->data, ETH_ALEN);
1493 memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
1494 if (!sdata->u.sta.mshcfg.dot11MeshTTL) {
1495 /* Do not send frames with mesh_ttl == 0 */ 1499 /* Do not send frames with mesh_ttl == 0 */
1496 sdata->u.sta.mshstats.dropped_frames_ttl++; 1500 sdata->u.mesh.mshstats.dropped_frames_ttl++;
1497 ret = 0; 1501 ret = 0;
1498 goto fail; 1502 goto fail;
1499 } 1503 }
1500 meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, sdata); 1504 memset(&mesh_hdr, 0, sizeof(mesh_hdr));
1505
1506 if (compare_ether_addr(dev->dev_addr,
1507 skb->data + ETH_ALEN) == 0) {
1508 /* RA TA DA SA */
1509 memset(hdr.addr1, 0, ETH_ALEN);
1510 memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN);
1511 memcpy(hdr.addr3, skb->data, ETH_ALEN);
1512 memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
1513 meshhdrlen = ieee80211_new_mesh_header(&mesh_hdr, sdata);
1514 } else {
1515 /* packet from other interface */
1516 struct mesh_path *mppath;
1517
1518 memset(hdr.addr1, 0, ETH_ALEN);
1519 memcpy(hdr.addr2, dev->dev_addr, ETH_ALEN);
1520 memcpy(hdr.addr4, dev->dev_addr, ETH_ALEN);
1521
1522 if (is_multicast_ether_addr(skb->data))
1523 memcpy(hdr.addr3, skb->data, ETH_ALEN);
1524 else {
1525 rcu_read_lock();
1526 mppath = mpp_path_lookup(skb->data, sdata);
1527 if (mppath)
1528 memcpy(hdr.addr3, mppath->mpp, ETH_ALEN);
1529 else
1530 memset(hdr.addr3, 0xff, ETH_ALEN);
1531 rcu_read_unlock();
1532 }
1533
1534 mesh_hdr.flags |= MESH_FLAGS_AE_A5_A6;
1535 mesh_hdr.ttl = sdata->u.mesh.mshcfg.dot11MeshTTL;
1536 put_unaligned(cpu_to_le32(sdata->u.mesh.mesh_seqnum), &mesh_hdr.seqnum);
1537 memcpy(mesh_hdr.eaddr1, skb->data, ETH_ALEN);
1538 memcpy(mesh_hdr.eaddr2, skb->data + ETH_ALEN, ETH_ALEN);
1539 sdata->u.mesh.mesh_seqnum++;
1540 meshhdrlen = 18;
1541 }
1501 hdrlen = 30; 1542 hdrlen = 30;
1502 break; 1543 break;
1503#endif 1544#endif
1504 case IEEE80211_IF_TYPE_STA: 1545 case NL80211_IFTYPE_STATION:
1505 fc |= cpu_to_le16(IEEE80211_FCTL_TODS); 1546 fc |= cpu_to_le16(IEEE80211_FCTL_TODS);
1506 /* BSSID SA DA */ 1547 /* BSSID SA DA */
1507 memcpy(hdr.addr1, sdata->u.sta.bssid, ETH_ALEN); 1548 memcpy(hdr.addr1, sdata->u.sta.bssid, ETH_ALEN);
@@ -1509,7 +1550,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1509 memcpy(hdr.addr3, skb->data, ETH_ALEN); 1550 memcpy(hdr.addr3, skb->data, ETH_ALEN);
1510 hdrlen = 24; 1551 hdrlen = 24;
1511 break; 1552 break;
1512 case IEEE80211_IF_TYPE_IBSS: 1553 case NL80211_IFTYPE_ADHOC:
1513 /* DA SA BSSID */ 1554 /* DA SA BSSID */
1514 memcpy(hdr.addr1, skb->data, ETH_ALEN); 1555 memcpy(hdr.addr1, skb->data, ETH_ALEN);
1515 memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN); 1556 memcpy(hdr.addr2, skb->data + ETH_ALEN, ETH_ALEN);
@@ -1588,19 +1629,6 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1588 nh_pos -= skip_header_bytes; 1629 nh_pos -= skip_header_bytes;
1589 h_pos -= skip_header_bytes; 1630 h_pos -= skip_header_bytes;
1590 1631
1591 /* TODO: implement support for fragments so that there is no need to
1592 * reallocate and copy payload; it might be enough to support one
1593 * extra fragment that would be copied in the beginning of the frame
1594 * data.. anyway, it would be nice to include this into skb structure
1595 * somehow
1596 *
1597 * There are few options for this:
1598 * use skb->cb as an extra space for 802.11 header
1599 * allocate new buffer if not enough headroom
1600 * make sure that there is enough headroom in every skb by increasing
1601 * build in headroom in __dev_alloc_skb() (linux/skbuff.h) and
1602 * alloc_skb() (net/core/skbuff.c)
1603 */
1604 head_need = hdrlen + encaps_len + meshhdrlen - skb_headroom(skb); 1632 head_need = hdrlen + encaps_len + meshhdrlen - skb_headroom(skb);
1605 1633
1606 /* 1634 /*
@@ -1823,10 +1851,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
1823 struct rate_selection rsel; 1851 struct rate_selection rsel;
1824 struct beacon_data *beacon; 1852 struct beacon_data *beacon;
1825 struct ieee80211_supported_band *sband; 1853 struct ieee80211_supported_band *sband;
1826 struct ieee80211_mgmt *mgmt;
1827 int *num_beacons;
1828 enum ieee80211_band band = local->hw.conf.channel->band; 1854 enum ieee80211_band band = local->hw.conf.channel->band;
1829 u8 *pos;
1830 1855
1831 sband = local->hw.wiphy->bands[band]; 1856 sband = local->hw.wiphy->bands[band];
1832 1857
@@ -1835,7 +1860,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
1835 sdata = vif_to_sdata(vif); 1860 sdata = vif_to_sdata(vif);
1836 bdev = sdata->dev; 1861 bdev = sdata->dev;
1837 1862
1838 if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { 1863 if (sdata->vif.type == NL80211_IFTYPE_AP) {
1839 ap = &sdata->u.ap; 1864 ap = &sdata->u.ap;
1840 beacon = rcu_dereference(ap->beacon); 1865 beacon = rcu_dereference(ap->beacon);
1841 if (ap && beacon) { 1866 if (ap && beacon) {
@@ -1873,11 +1898,9 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
1873 if (beacon->tail) 1898 if (beacon->tail)
1874 memcpy(skb_put(skb, beacon->tail_len), 1899 memcpy(skb_put(skb, beacon->tail_len),
1875 beacon->tail, beacon->tail_len); 1900 beacon->tail, beacon->tail_len);
1876
1877 num_beacons = &ap->num_beacons;
1878 } else 1901 } else
1879 goto out; 1902 goto out;
1880 } else if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { 1903 } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
1881 struct ieee80211_hdr *hdr; 1904 struct ieee80211_hdr *hdr;
1882 ifsta = &sdata->u.sta; 1905 ifsta = &sdata->u.sta;
1883 1906
@@ -1889,11 +1912,13 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
1889 goto out; 1912 goto out;
1890 1913
1891 hdr = (struct ieee80211_hdr *) skb->data; 1914 hdr = (struct ieee80211_hdr *) skb->data;
1892 hdr->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, 1915 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
1893 IEEE80211_STYPE_BEACON); 1916 IEEE80211_STYPE_BEACON);
1894 1917
1895 num_beacons = &ifsta->num_beacons;
1896 } else if (ieee80211_vif_is_mesh(&sdata->vif)) { 1918 } else if (ieee80211_vif_is_mesh(&sdata->vif)) {
1919 struct ieee80211_mgmt *mgmt;
1920 u8 *pos;
1921
1897 /* headroom, head length, tail length and maximum TIM length */ 1922 /* headroom, head length, tail length and maximum TIM length */
1898 skb = dev_alloc_skb(local->tx_headroom + 400); 1923 skb = dev_alloc_skb(local->tx_headroom + 400);
1899 if (!skb) 1924 if (!skb)
@@ -1916,9 +1941,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
1916 *pos++ = WLAN_EID_SSID; 1941 *pos++ = WLAN_EID_SSID;
1917 *pos++ = 0x0; 1942 *pos++ = 0x0;
1918 1943
1919 mesh_mgmt_ies_add(skb, sdata->dev); 1944 mesh_mgmt_ies_add(skb, sdata);
1920
1921 num_beacons = &sdata->u.sta.num_beacons;
1922 } else { 1945 } else {
1923 WARN_ON(1); 1946 WARN_ON(1);
1924 goto out; 1947 goto out;
@@ -1929,7 +1952,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
1929 skb->do_not_encrypt = 1; 1952 skb->do_not_encrypt = 1;
1930 1953
1931 info->band = band; 1954 info->band = band;
1932 rate_control_get_rate(local->mdev, sband, skb, &rsel); 1955 rate_control_get_rate(sdata, sband, NULL, skb, &rsel);
1933 1956
1934 if (unlikely(rsel.rate_idx < 0)) { 1957 if (unlikely(rsel.rate_idx < 0)) {
1935 if (net_ratelimit()) { 1958 if (net_ratelimit()) {
@@ -1955,7 +1978,6 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
1955 info->antenna_sel_tx = local->hw.conf.antenna_sel_tx; 1978 info->antenna_sel_tx = local->hw.conf.antenna_sel_tx;
1956 info->control.retry_limit = 1; 1979 info->control.retry_limit = 1;
1957 1980
1958 (*num_beacons)++;
1959out: 1981out:
1960 rcu_read_unlock(); 1982 rcu_read_unlock();
1961 return skb; 1983 return skb;
@@ -2017,7 +2039,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
2017 rcu_read_lock(); 2039 rcu_read_lock();
2018 beacon = rcu_dereference(bss->beacon); 2040 beacon = rcu_dereference(bss->beacon);
2019 2041
2020 if (sdata->vif.type != IEEE80211_IF_TYPE_AP || !beacon || !beacon->head) 2042 if (sdata->vif.type != NL80211_IFTYPE_AP || !beacon || !beacon->head)
2021 goto out; 2043 goto out;
2022 2044
2023 if (bss->dtim_count != 0) 2045 if (bss->dtim_count != 0)
@@ -2039,7 +2061,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
2039 cpu_to_le16(IEEE80211_FCTL_MOREDATA); 2061 cpu_to_le16(IEEE80211_FCTL_MOREDATA);
2040 } 2062 }
2041 2063
2042 if (!ieee80211_tx_prepare(&tx, skb, local->mdev)) 2064 if (!ieee80211_tx_prepare(local, &tx, skb))
2043 break; 2065 break;
2044 dev_kfree_skb_any(skb); 2066 dev_kfree_skb_any(skb);
2045 } 2067 }
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 0d463c80c404..f32561ec224c 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -43,7 +43,7 @@ const unsigned char bridge_tunnel_header[] __aligned(2) =
43 43
44 44
45u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, 45u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,
46 enum ieee80211_if_types type) 46 enum nl80211_iftype type)
47{ 47{
48 __le16 fc = hdr->frame_control; 48 __le16 fc = hdr->frame_control;
49 49
@@ -77,10 +77,10 @@ u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,
77 77
78 if (ieee80211_is_back_req(fc)) { 78 if (ieee80211_is_back_req(fc)) {
79 switch (type) { 79 switch (type) {
80 case IEEE80211_IF_TYPE_STA: 80 case NL80211_IFTYPE_STATION:
81 return hdr->addr2; 81 return hdr->addr2;
82 case IEEE80211_IF_TYPE_AP: 82 case NL80211_IFTYPE_AP:
83 case IEEE80211_IF_TYPE_VLAN: 83 case NL80211_IFTYPE_AP_VLAN:
84 return hdr->addr1; 84 return hdr->addr1;
85 default: 85 default:
86 break; /* fall through to the return */ 86 break; /* fall through to the return */
@@ -91,45 +91,6 @@ u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,
91 return NULL; 91 return NULL;
92} 92}
93 93
94int ieee80211_get_hdrlen(u16 fc)
95{
96 int hdrlen = 24;
97
98 switch (fc & IEEE80211_FCTL_FTYPE) {
99 case IEEE80211_FTYPE_DATA:
100 if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
101 hdrlen = 30; /* Addr4 */
102 /*
103 * The QoS Control field is two bytes and its presence is
104 * indicated by the IEEE80211_STYPE_QOS_DATA bit. Add 2 to
105 * hdrlen if that bit is set.
106 * This works by masking out the bit and shifting it to
107 * bit position 1 so the result has the value 0 or 2.
108 */
109 hdrlen += (fc & IEEE80211_STYPE_QOS_DATA)
110 >> (ilog2(IEEE80211_STYPE_QOS_DATA)-1);
111 break;
112 case IEEE80211_FTYPE_CTL:
113 /*
114 * ACK and CTS are 10 bytes, all others 16. To see how
115 * to get this condition consider
116 * subtype mask: 0b0000000011110000 (0x00F0)
117 * ACK subtype: 0b0000000011010000 (0x00D0)
118 * CTS subtype: 0b0000000011000000 (0x00C0)
119 * bits that matter: ^^^ (0x00E0)
120 * value of those: 0b0000000011000000 (0x00C0)
121 */
122 if ((fc & 0xE0) == 0xC0)
123 hdrlen = 10;
124 else
125 hdrlen = 16;
126 break;
127 }
128
129 return hdrlen;
130}
131EXPORT_SYMBOL(ieee80211_get_hdrlen);
132
133unsigned int ieee80211_hdrlen(__le16 fc) 94unsigned int ieee80211_hdrlen(__le16 fc)
134{ 95{
135 unsigned int hdrlen = 24; 96 unsigned int hdrlen = 24;
@@ -270,16 +231,21 @@ __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,
270 struct ieee80211_rate *rate) 231 struct ieee80211_rate *rate)
271{ 232{
272 struct ieee80211_local *local = hw_to_local(hw); 233 struct ieee80211_local *local = hw_to_local(hw);
273 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 234 struct ieee80211_sub_if_data *sdata;
274 u16 dur; 235 u16 dur;
275 int erp; 236 int erp;
237 bool short_preamble = false;
276 238
277 erp = 0; 239 erp = 0;
278 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) 240 if (vif) {
279 erp = rate->flags & IEEE80211_RATE_ERP_G; 241 sdata = vif_to_sdata(vif);
242 short_preamble = sdata->bss_conf.use_short_preamble;
243 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
244 erp = rate->flags & IEEE80211_RATE_ERP_G;
245 }
280 246
281 dur = ieee80211_frame_duration(local, frame_len, rate->bitrate, erp, 247 dur = ieee80211_frame_duration(local, frame_len, rate->bitrate, erp,
282 sdata->bss_conf.use_short_preamble); 248 short_preamble);
283 249
284 return cpu_to_le16(dur); 250 return cpu_to_le16(dur);
285} 251}
@@ -291,7 +257,7 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
291{ 257{
292 struct ieee80211_local *local = hw_to_local(hw); 258 struct ieee80211_local *local = hw_to_local(hw);
293 struct ieee80211_rate *rate; 259 struct ieee80211_rate *rate;
294 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 260 struct ieee80211_sub_if_data *sdata;
295 bool short_preamble; 261 bool short_preamble;
296 int erp; 262 int erp;
297 u16 dur; 263 u16 dur;
@@ -299,13 +265,17 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
299 265
300 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 266 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
301 267
302 short_preamble = sdata->bss_conf.use_short_preamble; 268 short_preamble = false;
303 269
304 rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx]; 270 rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx];
305 271
306 erp = 0; 272 erp = 0;
307 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) 273 if (vif) {
308 erp = rate->flags & IEEE80211_RATE_ERP_G; 274 sdata = vif_to_sdata(vif);
275 short_preamble = sdata->bss_conf.use_short_preamble;
276 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
277 erp = rate->flags & IEEE80211_RATE_ERP_G;
278 }
309 279
310 /* CTS duration */ 280 /* CTS duration */
311 dur = ieee80211_frame_duration(local, 10, rate->bitrate, 281 dur = ieee80211_frame_duration(local, 10, rate->bitrate,
@@ -328,7 +298,7 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
328{ 298{
329 struct ieee80211_local *local = hw_to_local(hw); 299 struct ieee80211_local *local = hw_to_local(hw);
330 struct ieee80211_rate *rate; 300 struct ieee80211_rate *rate;
331 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 301 struct ieee80211_sub_if_data *sdata;
332 bool short_preamble; 302 bool short_preamble;
333 int erp; 303 int erp;
334 u16 dur; 304 u16 dur;
@@ -336,12 +306,16 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
336 306
337 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 307 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
338 308
339 short_preamble = sdata->bss_conf.use_short_preamble; 309 short_preamble = false;
340 310
341 rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx]; 311 rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx];
342 erp = 0; 312 erp = 0;
343 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) 313 if (vif) {
344 erp = rate->flags & IEEE80211_RATE_ERP_G; 314 sdata = vif_to_sdata(vif);
315 short_preamble = sdata->bss_conf.use_short_preamble;
316 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
317 erp = rate->flags & IEEE80211_RATE_ERP_G;
318 }
345 319
346 /* Data frame duration */ 320 /* Data frame duration */
347 dur = ieee80211_frame_duration(local, frame_len, rate->bitrate, 321 dur = ieee80211_frame_duration(local, frame_len, rate->bitrate,
@@ -386,6 +360,13 @@ void ieee80211_stop_queues(struct ieee80211_hw *hw)
386} 360}
387EXPORT_SYMBOL(ieee80211_stop_queues); 361EXPORT_SYMBOL(ieee80211_stop_queues);
388 362
363int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue)
364{
365 struct ieee80211_local *local = hw_to_local(hw);
366 return __netif_subqueue_stopped(local->mdev, queue);
367}
368EXPORT_SYMBOL(ieee80211_queue_stopped);
369
389void ieee80211_wake_queues(struct ieee80211_hw *hw) 370void ieee80211_wake_queues(struct ieee80211_hw *hw)
390{ 371{
391 int i; 372 int i;
@@ -408,15 +389,16 @@ void ieee80211_iterate_active_interfaces(
408 389
409 list_for_each_entry(sdata, &local->interfaces, list) { 390 list_for_each_entry(sdata, &local->interfaces, list) {
410 switch (sdata->vif.type) { 391 switch (sdata->vif.type) {
411 case IEEE80211_IF_TYPE_INVALID: 392 case __NL80211_IFTYPE_AFTER_LAST:
412 case IEEE80211_IF_TYPE_MNTR: 393 case NL80211_IFTYPE_UNSPECIFIED:
413 case IEEE80211_IF_TYPE_VLAN: 394 case NL80211_IFTYPE_MONITOR:
395 case NL80211_IFTYPE_AP_VLAN:
414 continue; 396 continue;
415 case IEEE80211_IF_TYPE_AP: 397 case NL80211_IFTYPE_AP:
416 case IEEE80211_IF_TYPE_STA: 398 case NL80211_IFTYPE_STATION:
417 case IEEE80211_IF_TYPE_IBSS: 399 case NL80211_IFTYPE_ADHOC:
418 case IEEE80211_IF_TYPE_WDS: 400 case NL80211_IFTYPE_WDS:
419 case IEEE80211_IF_TYPE_MESH_POINT: 401 case NL80211_IFTYPE_MESH_POINT:
420 break; 402 break;
421 } 403 }
422 if (netif_running(sdata->dev)) 404 if (netif_running(sdata->dev))
@@ -441,15 +423,16 @@ void ieee80211_iterate_active_interfaces_atomic(
441 423
442 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 424 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
443 switch (sdata->vif.type) { 425 switch (sdata->vif.type) {
444 case IEEE80211_IF_TYPE_INVALID: 426 case __NL80211_IFTYPE_AFTER_LAST:
445 case IEEE80211_IF_TYPE_MNTR: 427 case NL80211_IFTYPE_UNSPECIFIED:
446 case IEEE80211_IF_TYPE_VLAN: 428 case NL80211_IFTYPE_MONITOR:
429 case NL80211_IFTYPE_AP_VLAN:
447 continue; 430 continue;
448 case IEEE80211_IF_TYPE_AP: 431 case NL80211_IFTYPE_AP:
449 case IEEE80211_IF_TYPE_STA: 432 case NL80211_IFTYPE_STATION:
450 case IEEE80211_IF_TYPE_IBSS: 433 case NL80211_IFTYPE_ADHOC:
451 case IEEE80211_IF_TYPE_WDS: 434 case NL80211_IFTYPE_WDS:
452 case IEEE80211_IF_TYPE_MESH_POINT: 435 case NL80211_IFTYPE_MESH_POINT:
453 break; 436 break;
454 } 437 }
455 if (netif_running(sdata->dev)) 438 if (netif_running(sdata->dev))
@@ -460,3 +443,243 @@ void ieee80211_iterate_active_interfaces_atomic(
460 rcu_read_unlock(); 443 rcu_read_unlock();
461} 444}
462EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); 445EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic);
446
447void ieee802_11_parse_elems(u8 *start, size_t len,
448 struct ieee802_11_elems *elems)
449{
450 size_t left = len;
451 u8 *pos = start;
452
453 memset(elems, 0, sizeof(*elems));
454 elems->ie_start = start;
455 elems->total_len = len;
456
457 while (left >= 2) {
458 u8 id, elen;
459
460 id = *pos++;
461 elen = *pos++;
462 left -= 2;
463
464 if (elen > left)
465 return;
466
467 switch (id) {
468 case WLAN_EID_SSID:
469 elems->ssid = pos;
470 elems->ssid_len = elen;
471 break;
472 case WLAN_EID_SUPP_RATES:
473 elems->supp_rates = pos;
474 elems->supp_rates_len = elen;
475 break;
476 case WLAN_EID_FH_PARAMS:
477 elems->fh_params = pos;
478 elems->fh_params_len = elen;
479 break;
480 case WLAN_EID_DS_PARAMS:
481 elems->ds_params = pos;
482 elems->ds_params_len = elen;
483 break;
484 case WLAN_EID_CF_PARAMS:
485 elems->cf_params = pos;
486 elems->cf_params_len = elen;
487 break;
488 case WLAN_EID_TIM:
489 elems->tim = pos;
490 elems->tim_len = elen;
491 break;
492 case WLAN_EID_IBSS_PARAMS:
493 elems->ibss_params = pos;
494 elems->ibss_params_len = elen;
495 break;
496 case WLAN_EID_CHALLENGE:
497 elems->challenge = pos;
498 elems->challenge_len = elen;
499 break;
500 case WLAN_EID_WPA:
501 if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 &&
502 pos[2] == 0xf2) {
503 /* Microsoft OUI (00:50:F2) */
504 if (pos[3] == 1) {
505 /* OUI Type 1 - WPA IE */
506 elems->wpa = pos;
507 elems->wpa_len = elen;
508 } else if (elen >= 5 && pos[3] == 2) {
509 if (pos[4] == 0) {
510 elems->wmm_info = pos;
511 elems->wmm_info_len = elen;
512 } else if (pos[4] == 1) {
513 elems->wmm_param = pos;
514 elems->wmm_param_len = elen;
515 }
516 }
517 }
518 break;
519 case WLAN_EID_RSN:
520 elems->rsn = pos;
521 elems->rsn_len = elen;
522 break;
523 case WLAN_EID_ERP_INFO:
524 elems->erp_info = pos;
525 elems->erp_info_len = elen;
526 break;
527 case WLAN_EID_EXT_SUPP_RATES:
528 elems->ext_supp_rates = pos;
529 elems->ext_supp_rates_len = elen;
530 break;
531 case WLAN_EID_HT_CAPABILITY:
532 elems->ht_cap_elem = pos;
533 elems->ht_cap_elem_len = elen;
534 break;
535 case WLAN_EID_HT_EXTRA_INFO:
536 elems->ht_info_elem = pos;
537 elems->ht_info_elem_len = elen;
538 break;
539 case WLAN_EID_MESH_ID:
540 elems->mesh_id = pos;
541 elems->mesh_id_len = elen;
542 break;
543 case WLAN_EID_MESH_CONFIG:
544 elems->mesh_config = pos;
545 elems->mesh_config_len = elen;
546 break;
547 case WLAN_EID_PEER_LINK:
548 elems->peer_link = pos;
549 elems->peer_link_len = elen;
550 break;
551 case WLAN_EID_PREQ:
552 elems->preq = pos;
553 elems->preq_len = elen;
554 break;
555 case WLAN_EID_PREP:
556 elems->prep = pos;
557 elems->prep_len = elen;
558 break;
559 case WLAN_EID_PERR:
560 elems->perr = pos;
561 elems->perr_len = elen;
562 break;
563 case WLAN_EID_CHANNEL_SWITCH:
564 elems->ch_switch_elem = pos;
565 elems->ch_switch_elem_len = elen;
566 break;
567 case WLAN_EID_QUIET:
568 if (!elems->quiet_elem) {
569 elems->quiet_elem = pos;
570 elems->quiet_elem_len = elen;
571 }
572 elems->num_of_quiet_elem++;
573 break;
574 case WLAN_EID_COUNTRY:
575 elems->country_elem = pos;
576 elems->country_elem_len = elen;
577 break;
578 case WLAN_EID_PWR_CONSTRAINT:
579 elems->pwr_constr_elem = pos;
580 elems->pwr_constr_elem_len = elen;
581 break;
582 default:
583 break;
584 }
585
586 left -= elen;
587 pos += elen;
588 }
589}
590
591void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
592{
593 struct ieee80211_local *local = sdata->local;
594 struct ieee80211_tx_queue_params qparam;
595 int i;
596
597 if (!local->ops->conf_tx)
598 return;
599
600 memset(&qparam, 0, sizeof(qparam));
601
602 qparam.aifs = 2;
603
604 if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ &&
605 !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE))
606 qparam.cw_min = 31;
607 else
608 qparam.cw_min = 15;
609
610 qparam.cw_max = 1023;
611 qparam.txop = 0;
612
613 for (i = 0; i < local_to_hw(local)->queues; i++)
614 local->ops->conf_tx(local_to_hw(local), i, &qparam);
615}
616
617void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
618 int encrypt)
619{
620 skb->dev = sdata->local->mdev;
621 skb_set_mac_header(skb, 0);
622 skb_set_network_header(skb, 0);
623 skb_set_transport_header(skb, 0);
624
625 skb->iif = sdata->dev->ifindex;
626 skb->do_not_encrypt = !encrypt;
627
628 dev_queue_xmit(skb);
629}
630
631int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freqMHz)
632{
633 int ret = -EINVAL;
634 struct ieee80211_channel *chan;
635 struct ieee80211_local *local = sdata->local;
636
637 chan = ieee80211_get_channel(local->hw.wiphy, freqMHz);
638
639 if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) {
640 if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
641 chan->flags & IEEE80211_CHAN_NO_IBSS) {
642 printk(KERN_DEBUG "%s: IBSS not allowed on frequency "
643 "%d MHz\n", sdata->dev->name, chan->center_freq);
644 return ret;
645 }
646 local->oper_channel = chan;
647
648 if (local->sw_scanning || local->hw_scanning)
649 ret = 0;
650 else
651 ret = ieee80211_hw_config(local);
652
653 rate_control_clear(local);
654 }
655
656 return ret;
657}
658
659u64 ieee80211_mandatory_rates(struct ieee80211_local *local,
660 enum ieee80211_band band)
661{
662 struct ieee80211_supported_band *sband;
663 struct ieee80211_rate *bitrates;
664 u64 mandatory_rates;
665 enum ieee80211_rate_flags mandatory_flag;
666 int i;
667
668 sband = local->hw.wiphy->bands[band];
669 if (!sband) {
670 WARN_ON(1);
671 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
672 }
673
674 if (band == IEEE80211_BAND_2GHZ)
675 mandatory_flag = IEEE80211_RATE_MANDATORY_B;
676 else
677 mandatory_flag = IEEE80211_RATE_MANDATORY_A;
678
679 bitrates = sband->bitrates;
680 mandatory_rates = 0;
681 for (i = 0; i < sband->n_bitrates; i++)
682 if (bitrates[i].flags & mandatory_flag)
683 mandatory_rates |= BIT(i);
684 return mandatory_rates;
685}
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 5c2bf0a3d4db..f0e2d3ecb5c4 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -228,11 +228,10 @@ int ieee80211_wep_decrypt(struct ieee80211_local *local, struct sk_buff *skb,
228 return -1; 228 return -1;
229 229
230 hdrlen = ieee80211_hdrlen(hdr->frame_control); 230 hdrlen = ieee80211_hdrlen(hdr->frame_control);
231 231 if (skb->len < hdrlen + WEP_IV_LEN + WEP_ICV_LEN)
232 if (skb->len < 8 + hdrlen)
233 return -1; 232 return -1;
234 233
235 len = skb->len - hdrlen - 8; 234 len = skb->len - hdrlen - WEP_IV_LEN - WEP_ICV_LEN;
236 235
237 keyidx = skb->data[hdrlen + 3] >> 6; 236 keyidx = skb->data[hdrlen + 3] >> 6;
238 237
@@ -292,9 +291,10 @@ u8 * ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key)
292ieee80211_rx_result 291ieee80211_rx_result
293ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx) 292ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx)
294{ 293{
295 if ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA && 294 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
296 ((rx->fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT || 295
297 (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_AUTH)) 296 if (!ieee80211_is_data(hdr->frame_control) &&
297 !ieee80211_is_auth(hdr->frame_control))
298 return RX_CONTINUE; 298 return RX_CONTINUE;
299 299
300 if (!(rx->status->flag & RX_FLAG_DECRYPTED)) { 300 if (!(rx->status->flag & RX_FLAG_DECRYPTED)) {
@@ -303,7 +303,7 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx)
303 } else if (!(rx->status->flag & RX_FLAG_IV_STRIPPED)) { 303 } else if (!(rx->status->flag & RX_FLAG_IV_STRIPPED)) {
304 ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); 304 ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key);
305 /* remove ICV */ 305 /* remove ICV */
306 skb_trim(rx->skb, rx->skb->len - 4); 306 skb_trim(rx->skb, rx->skb->len - WEP_ICV_LEN);
307 } 307 }
308 308
309 return RX_CONTINUE; 309 return RX_CONTINUE;
@@ -313,9 +313,6 @@ static int wep_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
313{ 313{
314 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 314 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
315 315
316 info->control.iv_len = WEP_IV_LEN;
317 info->control.icv_len = WEP_ICV_LEN;
318
319 if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) { 316 if (!(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) {
320 if (ieee80211_wep_encrypt(tx->local, skb, tx->key)) 317 if (ieee80211_wep_encrypt(tx->local, skb, tx->key))
321 return -1; 318 return -1;
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index 34fa8ed1e784..7e0d53abde24 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -27,22 +27,19 @@
27#include "aes_ccm.h" 27#include "aes_ccm.h"
28 28
29 29
30static int ieee80211_set_encryption(struct net_device *dev, u8 *sta_addr, 30static int ieee80211_set_encryption(struct ieee80211_sub_if_data *sdata, u8 *sta_addr,
31 int idx, int alg, int remove, 31 int idx, int alg, int remove,
32 int set_tx_key, const u8 *_key, 32 int set_tx_key, const u8 *_key,
33 size_t key_len) 33 size_t key_len)
34{ 34{
35 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 35 struct ieee80211_local *local = sdata->local;
36 struct sta_info *sta; 36 struct sta_info *sta;
37 struct ieee80211_key *key; 37 struct ieee80211_key *key;
38 struct ieee80211_sub_if_data *sdata;
39 int err; 38 int err;
40 39
41 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
42
43 if (idx < 0 || idx >= NUM_DEFAULT_KEYS) { 40 if (idx < 0 || idx >= NUM_DEFAULT_KEYS) {
44 printk(KERN_DEBUG "%s: set_encrypt - invalid idx=%d\n", 41 printk(KERN_DEBUG "%s: set_encrypt - invalid idx=%d\n",
45 dev->name, idx); 42 sdata->dev->name, idx);
46 return -EINVAL; 43 return -EINVAL;
47 } 44 }
48 45
@@ -125,13 +122,13 @@ static int ieee80211_ioctl_siwgenie(struct net_device *dev,
125 if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME) 122 if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME)
126 return -EOPNOTSUPP; 123 return -EOPNOTSUPP;
127 124
128 if (sdata->vif.type == IEEE80211_IF_TYPE_STA || 125 if (sdata->vif.type == NL80211_IFTYPE_STATION ||
129 sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { 126 sdata->vif.type == NL80211_IFTYPE_ADHOC) {
130 int ret = ieee80211_sta_set_extra_ie(dev, extra, data->length); 127 int ret = ieee80211_sta_set_extra_ie(sdata, extra, data->length);
131 if (ret) 128 if (ret)
132 return ret; 129 return ret;
133 sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL; 130 sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
134 ieee80211_sta_req_auth(dev, &sdata->u.sta); 131 ieee80211_sta_req_auth(sdata, &sdata->u.sta);
135 return 0; 132 return 0;
136 } 133 }
137 134
@@ -276,21 +273,21 @@ static int ieee80211_ioctl_siwmode(struct net_device *dev,
276 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 273 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
277 int type; 274 int type;
278 275
279 if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN) 276 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
280 return -EOPNOTSUPP; 277 return -EOPNOTSUPP;
281 278
282 switch (*mode) { 279 switch (*mode) {
283 case IW_MODE_INFRA: 280 case IW_MODE_INFRA:
284 type = IEEE80211_IF_TYPE_STA; 281 type = NL80211_IFTYPE_STATION;
285 break; 282 break;
286 case IW_MODE_ADHOC: 283 case IW_MODE_ADHOC:
287 type = IEEE80211_IF_TYPE_IBSS; 284 type = NL80211_IFTYPE_ADHOC;
288 break; 285 break;
289 case IW_MODE_REPEAT: 286 case IW_MODE_REPEAT:
290 type = IEEE80211_IF_TYPE_WDS; 287 type = NL80211_IFTYPE_WDS;
291 break; 288 break;
292 case IW_MODE_MONITOR: 289 case IW_MODE_MONITOR:
293 type = IEEE80211_IF_TYPE_MNTR; 290 type = NL80211_IFTYPE_MONITOR;
294 break; 291 break;
295 default: 292 default:
296 return -EINVAL; 293 return -EINVAL;
@@ -308,22 +305,22 @@ static int ieee80211_ioctl_giwmode(struct net_device *dev,
308 305
309 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 306 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
310 switch (sdata->vif.type) { 307 switch (sdata->vif.type) {
311 case IEEE80211_IF_TYPE_AP: 308 case NL80211_IFTYPE_AP:
312 *mode = IW_MODE_MASTER; 309 *mode = IW_MODE_MASTER;
313 break; 310 break;
314 case IEEE80211_IF_TYPE_STA: 311 case NL80211_IFTYPE_STATION:
315 *mode = IW_MODE_INFRA; 312 *mode = IW_MODE_INFRA;
316 break; 313 break;
317 case IEEE80211_IF_TYPE_IBSS: 314 case NL80211_IFTYPE_ADHOC:
318 *mode = IW_MODE_ADHOC; 315 *mode = IW_MODE_ADHOC;
319 break; 316 break;
320 case IEEE80211_IF_TYPE_MNTR: 317 case NL80211_IFTYPE_MONITOR:
321 *mode = IW_MODE_MONITOR; 318 *mode = IW_MODE_MONITOR;
322 break; 319 break;
323 case IEEE80211_IF_TYPE_WDS: 320 case NL80211_IFTYPE_WDS:
324 *mode = IW_MODE_REPEAT; 321 *mode = IW_MODE_REPEAT;
325 break; 322 break;
326 case IEEE80211_IF_TYPE_VLAN: 323 case NL80211_IFTYPE_AP_VLAN:
327 *mode = IW_MODE_SECOND; /* FIXME */ 324 *mode = IW_MODE_SECOND; /* FIXME */
328 break; 325 break;
329 default: 326 default:
@@ -333,60 +330,31 @@ static int ieee80211_ioctl_giwmode(struct net_device *dev,
333 return 0; 330 return 0;
334} 331}
335 332
336int ieee80211_set_freq(struct net_device *dev, int freqMHz)
337{
338 int ret = -EINVAL;
339 struct ieee80211_channel *chan;
340 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
341 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
342
343 chan = ieee80211_get_channel(local->hw.wiphy, freqMHz);
344
345 if (chan && !(chan->flags & IEEE80211_CHAN_DISABLED)) {
346 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS &&
347 chan->flags & IEEE80211_CHAN_NO_IBSS) {
348 printk(KERN_DEBUG "%s: IBSS not allowed on frequency "
349 "%d MHz\n", dev->name, chan->center_freq);
350 return ret;
351 }
352 local->oper_channel = chan;
353
354 if (local->sta_sw_scanning || local->sta_hw_scanning)
355 ret = 0;
356 else
357 ret = ieee80211_hw_config(local);
358
359 rate_control_clear(local);
360 }
361
362 return ret;
363}
364
365static int ieee80211_ioctl_siwfreq(struct net_device *dev, 333static int ieee80211_ioctl_siwfreq(struct net_device *dev,
366 struct iw_request_info *info, 334 struct iw_request_info *info,
367 struct iw_freq *freq, char *extra) 335 struct iw_freq *freq, char *extra)
368{ 336{
369 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 337 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
370 338
371 if (sdata->vif.type == IEEE80211_IF_TYPE_STA) 339 if (sdata->vif.type == NL80211_IFTYPE_STATION)
372 sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_CHANNEL_SEL; 340 sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_CHANNEL_SEL;
373 341
374 /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */ 342 /* freq->e == 0: freq->m = channel; otherwise freq = m * 10^e */
375 if (freq->e == 0) { 343 if (freq->e == 0) {
376 if (freq->m < 0) { 344 if (freq->m < 0) {
377 if (sdata->vif.type == IEEE80211_IF_TYPE_STA) 345 if (sdata->vif.type == NL80211_IFTYPE_STATION)
378 sdata->u.sta.flags |= 346 sdata->u.sta.flags |=
379 IEEE80211_STA_AUTO_CHANNEL_SEL; 347 IEEE80211_STA_AUTO_CHANNEL_SEL;
380 return 0; 348 return 0;
381 } else 349 } else
382 return ieee80211_set_freq(dev, 350 return ieee80211_set_freq(sdata,
383 ieee80211_channel_to_frequency(freq->m)); 351 ieee80211_channel_to_frequency(freq->m));
384 } else { 352 } else {
385 int i, div = 1000000; 353 int i, div = 1000000;
386 for (i = 0; i < freq->e; i++) 354 for (i = 0; i < freq->e; i++)
387 div /= 10; 355 div /= 10;
388 if (div > 0) 356 if (div > 0)
389 return ieee80211_set_freq(dev, freq->m / div); 357 return ieee80211_set_freq(sdata, freq->m / div);
390 else 358 else
391 return -EINVAL; 359 return -EINVAL;
392 } 360 }
@@ -418,8 +386,8 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev,
418 len--; 386 len--;
419 387
420 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 388 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
421 if (sdata->vif.type == IEEE80211_IF_TYPE_STA || 389 if (sdata->vif.type == NL80211_IFTYPE_STATION ||
422 sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { 390 sdata->vif.type == NL80211_IFTYPE_ADHOC) {
423 int ret; 391 int ret;
424 if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME) { 392 if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME) {
425 if (len > IEEE80211_MAX_SSID_LEN) 393 if (len > IEEE80211_MAX_SSID_LEN)
@@ -432,14 +400,14 @@ static int ieee80211_ioctl_siwessid(struct net_device *dev,
432 sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_SSID_SEL; 400 sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_SSID_SEL;
433 else 401 else
434 sdata->u.sta.flags |= IEEE80211_STA_AUTO_SSID_SEL; 402 sdata->u.sta.flags |= IEEE80211_STA_AUTO_SSID_SEL;
435 ret = ieee80211_sta_set_ssid(dev, ssid, len); 403 ret = ieee80211_sta_set_ssid(sdata, ssid, len);
436 if (ret) 404 if (ret)
437 return ret; 405 return ret;
438 ieee80211_sta_req_auth(dev, &sdata->u.sta); 406 ieee80211_sta_req_auth(sdata, &sdata->u.sta);
439 return 0; 407 return 0;
440 } 408 }
441 409
442 if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { 410 if (sdata->vif.type == NL80211_IFTYPE_AP) {
443 memcpy(sdata->u.ap.ssid, ssid, len); 411 memcpy(sdata->u.ap.ssid, ssid, len);
444 memset(sdata->u.ap.ssid + len, 0, 412 memset(sdata->u.ap.ssid + len, 0,
445 IEEE80211_MAX_SSID_LEN - len); 413 IEEE80211_MAX_SSID_LEN - len);
@@ -458,9 +426,9 @@ static int ieee80211_ioctl_giwessid(struct net_device *dev,
458 426
459 struct ieee80211_sub_if_data *sdata; 427 struct ieee80211_sub_if_data *sdata;
460 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 428 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
461 if (sdata->vif.type == IEEE80211_IF_TYPE_STA || 429 if (sdata->vif.type == NL80211_IFTYPE_STATION ||
462 sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { 430 sdata->vif.type == NL80211_IFTYPE_ADHOC) {
463 int res = ieee80211_sta_get_ssid(dev, ssid, &len); 431 int res = ieee80211_sta_get_ssid(sdata, ssid, &len);
464 if (res == 0) { 432 if (res == 0) {
465 data->length = len; 433 data->length = len;
466 data->flags = 1; 434 data->flags = 1;
@@ -469,7 +437,7 @@ static int ieee80211_ioctl_giwessid(struct net_device *dev,
469 return res; 437 return res;
470 } 438 }
471 439
472 if (sdata->vif.type == IEEE80211_IF_TYPE_AP) { 440 if (sdata->vif.type == NL80211_IFTYPE_AP) {
473 len = sdata->u.ap.ssid_len; 441 len = sdata->u.ap.ssid_len;
474 if (len > IW_ESSID_MAX_SIZE) 442 if (len > IW_ESSID_MAX_SIZE)
475 len = IW_ESSID_MAX_SIZE; 443 len = IW_ESSID_MAX_SIZE;
@@ -489,8 +457,8 @@ static int ieee80211_ioctl_siwap(struct net_device *dev,
489 struct ieee80211_sub_if_data *sdata; 457 struct ieee80211_sub_if_data *sdata;
490 458
491 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 459 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
492 if (sdata->vif.type == IEEE80211_IF_TYPE_STA || 460 if (sdata->vif.type == NL80211_IFTYPE_STATION ||
493 sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { 461 sdata->vif.type == NL80211_IFTYPE_ADHOC) {
494 int ret; 462 int ret;
495 if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME) { 463 if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME) {
496 memcpy(sdata->u.sta.bssid, (u8 *) &ap_addr->sa_data, 464 memcpy(sdata->u.sta.bssid, (u8 *) &ap_addr->sa_data,
@@ -504,12 +472,12 @@ static int ieee80211_ioctl_siwap(struct net_device *dev,
504 sdata->u.sta.flags |= IEEE80211_STA_AUTO_BSSID_SEL; 472 sdata->u.sta.flags |= IEEE80211_STA_AUTO_BSSID_SEL;
505 else 473 else
506 sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL; 474 sdata->u.sta.flags &= ~IEEE80211_STA_AUTO_BSSID_SEL;
507 ret = ieee80211_sta_set_bssid(dev, (u8 *) &ap_addr->sa_data); 475 ret = ieee80211_sta_set_bssid(sdata, (u8 *) &ap_addr->sa_data);
508 if (ret) 476 if (ret)
509 return ret; 477 return ret;
510 ieee80211_sta_req_auth(dev, &sdata->u.sta); 478 ieee80211_sta_req_auth(sdata, &sdata->u.sta);
511 return 0; 479 return 0;
512 } else if (sdata->vif.type == IEEE80211_IF_TYPE_WDS) { 480 } else if (sdata->vif.type == NL80211_IFTYPE_WDS) {
513 /* 481 /*
514 * If it is necessary to update the WDS peer address 482 * If it is necessary to update the WDS peer address
515 * while the interface is running, then we need to do 483 * while the interface is running, then we need to do
@@ -537,10 +505,10 @@ static int ieee80211_ioctl_giwap(struct net_device *dev,
537 struct ieee80211_sub_if_data *sdata; 505 struct ieee80211_sub_if_data *sdata;
538 506
539 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 507 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
540 if (sdata->vif.type == IEEE80211_IF_TYPE_STA || 508 if (sdata->vif.type == NL80211_IFTYPE_STATION ||
541 sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { 509 sdata->vif.type == NL80211_IFTYPE_ADHOC) {
542 if (sdata->u.sta.state == IEEE80211_ASSOCIATED || 510 if (sdata->u.sta.state == IEEE80211_STA_MLME_ASSOCIATED ||
543 sdata->u.sta.state == IEEE80211_IBSS_JOINED) { 511 sdata->u.sta.state == IEEE80211_STA_MLME_IBSS_JOINED) {
544 ap_addr->sa_family = ARPHRD_ETHER; 512 ap_addr->sa_family = ARPHRD_ETHER;
545 memcpy(&ap_addr->sa_data, sdata->u.sta.bssid, ETH_ALEN); 513 memcpy(&ap_addr->sa_data, sdata->u.sta.bssid, ETH_ALEN);
546 return 0; 514 return 0;
@@ -548,7 +516,7 @@ static int ieee80211_ioctl_giwap(struct net_device *dev,
548 memset(&ap_addr->sa_data, 0, ETH_ALEN); 516 memset(&ap_addr->sa_data, 0, ETH_ALEN);
549 return 0; 517 return 0;
550 } 518 }
551 } else if (sdata->vif.type == IEEE80211_IF_TYPE_WDS) { 519 } else if (sdata->vif.type == NL80211_IFTYPE_WDS) {
552 ap_addr->sa_family = ARPHRD_ETHER; 520 ap_addr->sa_family = ARPHRD_ETHER;
553 memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN); 521 memcpy(&ap_addr->sa_data, sdata->u.wds.remote_addr, ETH_ALEN);
554 return 0; 522 return 0;
@@ -570,10 +538,10 @@ static int ieee80211_ioctl_siwscan(struct net_device *dev,
570 if (!netif_running(dev)) 538 if (!netif_running(dev))
571 return -ENETDOWN; 539 return -ENETDOWN;
572 540
573 if (sdata->vif.type != IEEE80211_IF_TYPE_STA && 541 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
574 sdata->vif.type != IEEE80211_IF_TYPE_IBSS && 542 sdata->vif.type != NL80211_IFTYPE_ADHOC &&
575 sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT && 543 sdata->vif.type != NL80211_IFTYPE_MESH_POINT &&
576 sdata->vif.type != IEEE80211_IF_TYPE_AP) 544 sdata->vif.type != NL80211_IFTYPE_AP)
577 return -EOPNOTSUPP; 545 return -EOPNOTSUPP;
578 546
579 /* if SSID was specified explicitly then use that */ 547 /* if SSID was specified explicitly then use that */
@@ -584,7 +552,7 @@ static int ieee80211_ioctl_siwscan(struct net_device *dev,
584 ssid_len = req->essid_len; 552 ssid_len = req->essid_len;
585 } 553 }
586 554
587 return ieee80211_sta_req_scan(dev, ssid, ssid_len); 555 return ieee80211_request_scan(sdata, ssid, ssid_len);
588} 556}
589 557
590 558
@@ -594,11 +562,14 @@ static int ieee80211_ioctl_giwscan(struct net_device *dev,
594{ 562{
595 int res; 563 int res;
596 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 564 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
565 struct ieee80211_sub_if_data *sdata;
566
567 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
597 568
598 if (local->sta_sw_scanning || local->sta_hw_scanning) 569 if (local->sw_scanning || local->hw_scanning)
599 return -EAGAIN; 570 return -EAGAIN;
600 571
601 res = ieee80211_sta_scan_results(dev, info, extra, data->length); 572 res = ieee80211_scan_results(local, info, extra, data->length);
602 if (res >= 0) { 573 if (res >= 0) {
603 data->length = res; 574 data->length = res;
604 return 0; 575 return 0;
@@ -656,7 +627,7 @@ static int ieee80211_ioctl_giwrate(struct net_device *dev,
656 627
657 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 628 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
658 629
659 if (sdata->vif.type != IEEE80211_IF_TYPE_STA) 630 if (sdata->vif.type != NL80211_IFTYPE_STATION)
660 return -EOPNOTSUPP; 631 return -EOPNOTSUPP;
661 632
662 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 633 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
@@ -665,8 +636,8 @@ static int ieee80211_ioctl_giwrate(struct net_device *dev,
665 636
666 sta = sta_info_get(local, sdata->u.sta.bssid); 637 sta = sta_info_get(local, sdata->u.sta.bssid);
667 638
668 if (sta && sta->txrate_idx < sband->n_bitrates) 639 if (sta && sta->last_txrate_idx < sband->n_bitrates)
669 rate->value = sband->bitrates[sta->txrate_idx].bitrate; 640 rate->value = sband->bitrates[sta->last_txrate_idx].bitrate;
670 else 641 else
671 rate->value = 0; 642 rate->value = 0;
672 643
@@ -887,17 +858,17 @@ static int ieee80211_ioctl_siwmlme(struct net_device *dev,
887 struct iw_mlme *mlme = (struct iw_mlme *) extra; 858 struct iw_mlme *mlme = (struct iw_mlme *) extra;
888 859
889 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 860 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
890 if (sdata->vif.type != IEEE80211_IF_TYPE_STA && 861 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
891 sdata->vif.type != IEEE80211_IF_TYPE_IBSS) 862 sdata->vif.type != NL80211_IFTYPE_ADHOC)
892 return -EINVAL; 863 return -EINVAL;
893 864
894 switch (mlme->cmd) { 865 switch (mlme->cmd) {
895 case IW_MLME_DEAUTH: 866 case IW_MLME_DEAUTH:
896 /* TODO: mlme->addr.sa_data */ 867 /* TODO: mlme->addr.sa_data */
897 return ieee80211_sta_deauthenticate(dev, mlme->reason_code); 868 return ieee80211_sta_deauthenticate(sdata, mlme->reason_code);
898 case IW_MLME_DISASSOC: 869 case IW_MLME_DISASSOC:
899 /* TODO: mlme->addr.sa_data */ 870 /* TODO: mlme->addr.sa_data */
900 return ieee80211_sta_disassociate(dev, mlme->reason_code); 871 return ieee80211_sta_disassociate(sdata, mlme->reason_code);
901 default: 872 default:
902 return -EOPNOTSUPP; 873 return -EOPNOTSUPP;
903 } 874 }
@@ -938,7 +909,7 @@ static int ieee80211_ioctl_siwencode(struct net_device *dev,
938 } 909 }
939 910
940 return ieee80211_set_encryption( 911 return ieee80211_set_encryption(
941 dev, bcaddr, 912 sdata, bcaddr,
942 idx, alg, remove, 913 idx, alg, remove,
943 !sdata->default_key, 914 !sdata->default_key,
944 keybuf, erq->length); 915 keybuf, erq->length);
@@ -983,7 +954,7 @@ static int ieee80211_ioctl_giwencode(struct net_device *dev,
983 erq->length = sdata->keys[idx]->conf.keylen; 954 erq->length = sdata->keys[idx]->conf.keylen;
984 erq->flags |= IW_ENCODE_ENABLED; 955 erq->flags |= IW_ENCODE_ENABLED;
985 956
986 if (sdata->vif.type == IEEE80211_IF_TYPE_STA) { 957 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
987 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 958 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
988 switch (ifsta->auth_alg) { 959 switch (ifsta->auth_alg) {
989 case WLAN_AUTH_OPEN: 960 case WLAN_AUTH_OPEN:
@@ -1057,7 +1028,7 @@ static int ieee80211_ioctl_siwauth(struct net_device *dev,
1057 sdata->drop_unencrypted = !!data->value; 1028 sdata->drop_unencrypted = !!data->value;
1058 break; 1029 break;
1059 case IW_AUTH_PRIVACY_INVOKED: 1030 case IW_AUTH_PRIVACY_INVOKED:
1060 if (sdata->vif.type != IEEE80211_IF_TYPE_STA) 1031 if (sdata->vif.type != NL80211_IFTYPE_STATION)
1061 ret = -EINVAL; 1032 ret = -EINVAL;
1062 else { 1033 else {
1063 sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED; 1034 sdata->u.sta.flags &= ~IEEE80211_STA_PRIVACY_INVOKED;
@@ -1072,8 +1043,8 @@ static int ieee80211_ioctl_siwauth(struct net_device *dev,
1072 } 1043 }
1073 break; 1044 break;
1074 case IW_AUTH_80211_AUTH_ALG: 1045 case IW_AUTH_80211_AUTH_ALG:
1075 if (sdata->vif.type == IEEE80211_IF_TYPE_STA || 1046 if (sdata->vif.type == NL80211_IFTYPE_STATION ||
1076 sdata->vif.type == IEEE80211_IF_TYPE_IBSS) 1047 sdata->vif.type == NL80211_IFTYPE_ADHOC)
1077 sdata->u.sta.auth_algs = data->value; 1048 sdata->u.sta.auth_algs = data->value;
1078 else 1049 else
1079 ret = -EOPNOTSUPP; 1050 ret = -EOPNOTSUPP;
@@ -1095,8 +1066,8 @@ static struct iw_statistics *ieee80211_get_wireless_stats(struct net_device *dev
1095 1066
1096 rcu_read_lock(); 1067 rcu_read_lock();
1097 1068
1098 if (sdata->vif.type == IEEE80211_IF_TYPE_STA || 1069 if (sdata->vif.type == NL80211_IFTYPE_STATION ||
1099 sdata->vif.type == IEEE80211_IF_TYPE_IBSS) 1070 sdata->vif.type == NL80211_IFTYPE_ADHOC)
1100 sta = sta_info_get(local, sdata->u.sta.bssid); 1071 sta = sta_info_get(local, sdata->u.sta.bssid);
1101 if (!sta) { 1072 if (!sta) {
1102 wstats->discard.fragment = 0; 1073 wstats->discard.fragment = 0;
@@ -1126,8 +1097,8 @@ static int ieee80211_ioctl_giwauth(struct net_device *dev,
1126 1097
1127 switch (data->flags & IW_AUTH_INDEX) { 1098 switch (data->flags & IW_AUTH_INDEX) {
1128 case IW_AUTH_80211_AUTH_ALG: 1099 case IW_AUTH_80211_AUTH_ALG:
1129 if (sdata->vif.type == IEEE80211_IF_TYPE_STA || 1100 if (sdata->vif.type == NL80211_IFTYPE_STATION ||
1130 sdata->vif.type == IEEE80211_IF_TYPE_IBSS) 1101 sdata->vif.type == NL80211_IFTYPE_ADHOC)
1131 data->value = sdata->u.sta.auth_algs; 1102 data->value = sdata->u.sta.auth_algs;
1132 else 1103 else
1133 ret = -EOPNOTSUPP; 1104 ret = -EOPNOTSUPP;
@@ -1184,7 +1155,7 @@ static int ieee80211_ioctl_siwencodeext(struct net_device *dev,
1184 } else 1155 } else
1185 idx--; 1156 idx--;
1186 1157
1187 return ieee80211_set_encryption(dev, ext->addr.sa_data, idx, alg, 1158 return ieee80211_set_encryption(sdata, ext->addr.sa_data, idx, alg,
1188 remove, 1159 remove,
1189 ext->ext_flags & 1160 ext->ext_flags &
1190 IW_ENCODE_EXT_SET_TX_KEY, 1161 IW_ENCODE_EXT_SET_TX_KEY,
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index 4310e2f65661..139b5f267b34 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -39,7 +39,7 @@ static unsigned int classify_1d(struct sk_buff *skb)
39 return skb->priority - 256; 39 return skb->priority - 256;
40 40
41 switch (skb->protocol) { 41 switch (skb->protocol) {
42 case __constant_htons(ETH_P_IP): 42 case htons(ETH_P_IP):
43 dscp = ip_hdr(skb)->tos & 0xfc; 43 dscp = ip_hdr(skb)->tos & 0xfc;
44 break; 44 break;
45 45
@@ -47,8 +47,6 @@ static unsigned int classify_1d(struct sk_buff *skb)
47 return 0; 47 return 0;
48 } 48 }
49 49
50 if (dscp & 0x1c)
51 return 0;
52 return dscp >> 5; 50 return dscp >> 5;
53} 51}
54 52
@@ -75,9 +73,8 @@ static int wme_downgrade_ac(struct sk_buff *skb)
75 73
76 74
77/* Indicate which queue to use. */ 75/* Indicate which queue to use. */
78static u16 classify80211(struct sk_buff *skb, struct net_device *dev) 76static u16 classify80211(struct ieee80211_local *local, struct sk_buff *skb)
79{ 77{
80 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
81 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 78 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
82 79
83 if (!ieee80211_is_data(hdr->frame_control)) { 80 if (!ieee80211_is_data(hdr->frame_control)) {
@@ -115,14 +112,15 @@ static u16 classify80211(struct sk_buff *skb, struct net_device *dev)
115 112
116u16 ieee80211_select_queue(struct net_device *dev, struct sk_buff *skb) 113u16 ieee80211_select_queue(struct net_device *dev, struct sk_buff *skb)
117{ 114{
115 struct ieee80211_master_priv *mpriv = netdev_priv(dev);
116 struct ieee80211_local *local = mpriv->local;
118 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 117 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
119 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
120 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 118 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
121 struct sta_info *sta; 119 struct sta_info *sta;
122 u16 queue; 120 u16 queue;
123 u8 tid; 121 u8 tid;
124 122
125 queue = classify80211(skb, dev); 123 queue = classify80211(local, skb);
126 if (unlikely(queue >= local->hw.queues)) 124 if (unlikely(queue >= local->hw.queues))
127 queue = local->hw.queues - 1; 125 queue = local->hw.queues - 1;
128 126
@@ -212,7 +210,7 @@ int ieee80211_ht_agg_queue_add(struct ieee80211_local *local,
212 DECLARE_MAC_BUF(mac); 210 DECLARE_MAC_BUF(mac);
213 printk(KERN_DEBUG "allocated aggregation queue" 211 printk(KERN_DEBUG "allocated aggregation queue"
214 " %d tid %d addr %s pool=0x%lX\n", 212 " %d tid %d addr %s pool=0x%lX\n",
215 i, tid, print_mac(mac, sta->addr), 213 i, tid, print_mac(mac, sta->sta.addr),
216 local->queue_pool[0]); 214 local->queue_pool[0]);
217 } 215 }
218#endif /* CONFIG_MAC80211_HT_DEBUG */ 216#endif /* CONFIG_MAC80211_HT_DEBUG */
diff --git a/net/mac80211/wme.h b/net/mac80211/wme.h
index 04de28c071a6..bc62f28a4d3d 100644
--- a/net/mac80211/wme.h
+++ b/net/mac80211/wme.h
@@ -1,5 +1,4 @@
1/* 1/*
2 * IEEE 802.11 driver (80211.o) - QoS datatypes
3 * Copyright 2004, Instant802 Networks, Inc. 2 * Copyright 2004, Instant802 Networks, Inc.
4 * Copyright 2005, Devicescape Software, Inc. 3 * Copyright 2005, Devicescape Software, Inc.
5 * 4 *
@@ -14,8 +13,6 @@
14#include <linux/netdevice.h> 13#include <linux/netdevice.h>
15#include "ieee80211_i.h" 14#include "ieee80211_i.h"
16 15
17#define QOS_CONTROL_LEN 2
18
19#define QOS_CONTROL_ACK_POLICY_NORMAL 0 16#define QOS_CONTROL_ACK_POLICY_NORMAL 0
20#define QOS_CONTROL_ACK_POLICY_NOACK 1 17#define QOS_CONTROL_ACK_POLICY_NOACK 1
21 18
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c
index 2f33df0dcccf..6db649480e8f 100644
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -127,7 +127,7 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx)
127 if (!(rx->flags & IEEE80211_RX_RA_MATCH)) 127 if (!(rx->flags & IEEE80211_RX_RA_MATCH))
128 return RX_DROP_UNUSABLE; 128 return RX_DROP_UNUSABLE;
129 129
130 mac80211_ev_michael_mic_failure(rx->dev, rx->key->conf.keyidx, 130 mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx,
131 (void *) skb->data); 131 (void *) skb->data);
132 return RX_DROP_UNUSABLE; 132 return RX_DROP_UNUSABLE;
133 } 133 }
@@ -152,9 +152,6 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
152 int len, tail; 152 int len, tail;
153 u8 *pos; 153 u8 *pos;
154 154
155 info->control.icv_len = TKIP_ICV_LEN;
156 info->control.iv_len = TKIP_IV_LEN;
157
158 if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && 155 if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
159 !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { 156 !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
160 /* hwaccel - with no need for preallocated room for IV/ICV */ 157 /* hwaccel - with no need for preallocated room for IV/ICV */
@@ -256,7 +253,7 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx)
256 253
257 res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm, 254 res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm,
258 key, skb->data + hdrlen, 255 key, skb->data + hdrlen,
259 skb->len - hdrlen, rx->sta->addr, 256 skb->len - hdrlen, rx->sta->sta.addr,
260 hdr->addr1, hwaccel, rx->queue, 257 hdr->addr1, hwaccel, rx->queue,
261 &rx->tkip_iv32, 258 &rx->tkip_iv32,
262 &rx->tkip_iv16); 259 &rx->tkip_iv16);
@@ -374,9 +371,6 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb)
374 u8 *pos, *pn; 371 u8 *pos, *pn;
375 int i; 372 int i;
376 373
377 info->control.icv_len = CCMP_MIC_LEN;
378 info->control.iv_len = CCMP_HDR_LEN;
379
380 if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) && 374 if ((tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) &&
381 !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) { 375 !(tx->key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) {
382 /* hwaccel - with no need for preallocated room for CCMP " 376 /* hwaccel - with no need for preallocated room for CCMP "
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index ee898e74808d..78892cf2b021 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -38,10 +38,11 @@ config NF_CONNTRACK
38 38
39 To compile it as a module, choose M here. If unsure, say N. 39 To compile it as a module, choose M here. If unsure, say N.
40 40
41if NF_CONNTRACK
42
41config NF_CT_ACCT 43config NF_CT_ACCT
42 bool "Connection tracking flow accounting" 44 bool "Connection tracking flow accounting"
43 depends on NETFILTER_ADVANCED 45 depends on NETFILTER_ADVANCED
44 depends on NF_CONNTRACK
45 help 46 help
46 If this option is enabled, the connection tracking code will 47 If this option is enabled, the connection tracking code will
47 keep per-flow packet and byte counters. 48 keep per-flow packet and byte counters.
@@ -63,7 +64,6 @@ config NF_CT_ACCT
63config NF_CONNTRACK_MARK 64config NF_CONNTRACK_MARK
64 bool 'Connection mark tracking support' 65 bool 'Connection mark tracking support'
65 depends on NETFILTER_ADVANCED 66 depends on NETFILTER_ADVANCED
66 depends on NF_CONNTRACK
67 help 67 help
68 This option enables support for connection marks, used by the 68 This option enables support for connection marks, used by the
69 `CONNMARK' target and `connmark' match. Similar to the mark value 69 `CONNMARK' target and `connmark' match. Similar to the mark value
@@ -72,7 +72,7 @@ config NF_CONNTRACK_MARK
72 72
73config NF_CONNTRACK_SECMARK 73config NF_CONNTRACK_SECMARK
74 bool 'Connection tracking security mark support' 74 bool 'Connection tracking security mark support'
75 depends on NF_CONNTRACK && NETWORK_SECMARK 75 depends on NETWORK_SECMARK
76 default m if NETFILTER_ADVANCED=n 76 default m if NETFILTER_ADVANCED=n
77 help 77 help
78 This option enables security markings to be applied to 78 This option enables security markings to be applied to
@@ -85,7 +85,6 @@ config NF_CONNTRACK_SECMARK
85 85
86config NF_CONNTRACK_EVENTS 86config NF_CONNTRACK_EVENTS
87 bool "Connection tracking events" 87 bool "Connection tracking events"
88 depends on NF_CONNTRACK
89 depends on NETFILTER_ADVANCED 88 depends on NETFILTER_ADVANCED
90 help 89 help
91 If this option is enabled, the connection tracking code will 90 If this option is enabled, the connection tracking code will
@@ -96,7 +95,7 @@ config NF_CONNTRACK_EVENTS
96 95
97config NF_CT_PROTO_DCCP 96config NF_CT_PROTO_DCCP
98 tristate 'DCCP protocol connection tracking support (EXPERIMENTAL)' 97 tristate 'DCCP protocol connection tracking support (EXPERIMENTAL)'
99 depends on EXPERIMENTAL && NF_CONNTRACK 98 depends on EXPERIMENTAL
100 depends on NETFILTER_ADVANCED 99 depends on NETFILTER_ADVANCED
101 default IP_DCCP 100 default IP_DCCP
102 help 101 help
@@ -107,11 +106,10 @@ config NF_CT_PROTO_DCCP
107 106
108config NF_CT_PROTO_GRE 107config NF_CT_PROTO_GRE
109 tristate 108 tristate
110 depends on NF_CONNTRACK
111 109
112config NF_CT_PROTO_SCTP 110config NF_CT_PROTO_SCTP
113 tristate 'SCTP protocol connection tracking support (EXPERIMENTAL)' 111 tristate 'SCTP protocol connection tracking support (EXPERIMENTAL)'
114 depends on EXPERIMENTAL && NF_CONNTRACK 112 depends on EXPERIMENTAL
115 depends on NETFILTER_ADVANCED 113 depends on NETFILTER_ADVANCED
116 default IP_SCTP 114 default IP_SCTP
117 help 115 help
@@ -123,7 +121,6 @@ config NF_CT_PROTO_SCTP
123 121
124config NF_CT_PROTO_UDPLITE 122config NF_CT_PROTO_UDPLITE
125 tristate 'UDP-Lite protocol connection tracking support' 123 tristate 'UDP-Lite protocol connection tracking support'
126 depends on NF_CONNTRACK
127 depends on NETFILTER_ADVANCED 124 depends on NETFILTER_ADVANCED
128 help 125 help
129 With this option enabled, the layer 3 independent connection 126 With this option enabled, the layer 3 independent connection
@@ -134,7 +131,6 @@ config NF_CT_PROTO_UDPLITE
134 131
135config NF_CONNTRACK_AMANDA 132config NF_CONNTRACK_AMANDA
136 tristate "Amanda backup protocol support" 133 tristate "Amanda backup protocol support"
137 depends on NF_CONNTRACK
138 depends on NETFILTER_ADVANCED 134 depends on NETFILTER_ADVANCED
139 select TEXTSEARCH 135 select TEXTSEARCH
140 select TEXTSEARCH_KMP 136 select TEXTSEARCH_KMP
@@ -150,7 +146,6 @@ config NF_CONNTRACK_AMANDA
150 146
151config NF_CONNTRACK_FTP 147config NF_CONNTRACK_FTP
152 tristate "FTP protocol support" 148 tristate "FTP protocol support"
153 depends on NF_CONNTRACK
154 default m if NETFILTER_ADVANCED=n 149 default m if NETFILTER_ADVANCED=n
155 help 150 help
156 Tracking FTP connections is problematic: special helpers are 151 Tracking FTP connections is problematic: special helpers are
@@ -165,7 +160,7 @@ config NF_CONNTRACK_FTP
165 160
166config NF_CONNTRACK_H323 161config NF_CONNTRACK_H323
167 tristate "H.323 protocol support" 162 tristate "H.323 protocol support"
168 depends on NF_CONNTRACK && (IPV6 || IPV6=n) 163 depends on (IPV6 || IPV6=n)
169 depends on NETFILTER_ADVANCED 164 depends on NETFILTER_ADVANCED
170 help 165 help
171 H.323 is a VoIP signalling protocol from ITU-T. As one of the most 166 H.323 is a VoIP signalling protocol from ITU-T. As one of the most
@@ -185,7 +180,6 @@ config NF_CONNTRACK_H323
185 180
186config NF_CONNTRACK_IRC 181config NF_CONNTRACK_IRC
187 tristate "IRC protocol support" 182 tristate "IRC protocol support"
188 depends on NF_CONNTRACK
189 default m if NETFILTER_ADVANCED=n 183 default m if NETFILTER_ADVANCED=n
190 help 184 help
191 There is a commonly-used extension to IRC called 185 There is a commonly-used extension to IRC called
@@ -201,7 +195,6 @@ config NF_CONNTRACK_IRC
201 195
202config NF_CONNTRACK_NETBIOS_NS 196config NF_CONNTRACK_NETBIOS_NS
203 tristate "NetBIOS name service protocol support" 197 tristate "NetBIOS name service protocol support"
204 depends on NF_CONNTRACK
205 depends on NETFILTER_ADVANCED 198 depends on NETFILTER_ADVANCED
206 help 199 help
207 NetBIOS name service requests are sent as broadcast messages from an 200 NetBIOS name service requests are sent as broadcast messages from an
@@ -221,7 +214,6 @@ config NF_CONNTRACK_NETBIOS_NS
221 214
222config NF_CONNTRACK_PPTP 215config NF_CONNTRACK_PPTP
223 tristate "PPtP protocol support" 216 tristate "PPtP protocol support"
224 depends on NF_CONNTRACK
225 depends on NETFILTER_ADVANCED 217 depends on NETFILTER_ADVANCED
226 select NF_CT_PROTO_GRE 218 select NF_CT_PROTO_GRE
227 help 219 help
@@ -241,7 +233,7 @@ config NF_CONNTRACK_PPTP
241 233
242config NF_CONNTRACK_SANE 234config NF_CONNTRACK_SANE
243 tristate "SANE protocol support (EXPERIMENTAL)" 235 tristate "SANE protocol support (EXPERIMENTAL)"
244 depends on EXPERIMENTAL && NF_CONNTRACK 236 depends on EXPERIMENTAL
245 depends on NETFILTER_ADVANCED 237 depends on NETFILTER_ADVANCED
246 help 238 help
247 SANE is a protocol for remote access to scanners as implemented 239 SANE is a protocol for remote access to scanners as implemented
@@ -255,7 +247,6 @@ config NF_CONNTRACK_SANE
255 247
256config NF_CONNTRACK_SIP 248config NF_CONNTRACK_SIP
257 tristate "SIP protocol support" 249 tristate "SIP protocol support"
258 depends on NF_CONNTRACK
259 default m if NETFILTER_ADVANCED=n 250 default m if NETFILTER_ADVANCED=n
260 help 251 help
261 SIP is an application-layer control protocol that can establish, 252 SIP is an application-layer control protocol that can establish,
@@ -268,7 +259,6 @@ config NF_CONNTRACK_SIP
268 259
269config NF_CONNTRACK_TFTP 260config NF_CONNTRACK_TFTP
270 tristate "TFTP protocol support" 261 tristate "TFTP protocol support"
271 depends on NF_CONNTRACK
272 depends on NETFILTER_ADVANCED 262 depends on NETFILTER_ADVANCED
273 help 263 help
274 TFTP connection tracking helper, this is required depending 264 TFTP connection tracking helper, this is required depending
@@ -280,13 +270,29 @@ config NF_CONNTRACK_TFTP
280 270
281config NF_CT_NETLINK 271config NF_CT_NETLINK
282 tristate 'Connection tracking netlink interface' 272 tristate 'Connection tracking netlink interface'
283 depends on NF_CONNTRACK
284 select NETFILTER_NETLINK 273 select NETFILTER_NETLINK
285 depends on NF_NAT=n || NF_NAT 274 depends on NF_NAT=n || NF_NAT
286 default m if NETFILTER_ADVANCED=n 275 default m if NETFILTER_ADVANCED=n
287 help 276 help
288 This option enables support for a netlink-based userspace interface 277 This option enables support for a netlink-based userspace interface
289 278
279# transparent proxy support
280config NETFILTER_TPROXY
281 tristate "Transparent proxying support (EXPERIMENTAL)"
282 depends on EXPERIMENTAL
283 depends on IP_NF_MANGLE
284 depends on NETFILTER_ADVANCED
285 help
286 This option enables transparent proxying support, that is,
287 support for handling non-locally bound IPv4 TCP and UDP sockets.
288 For it to work you will have to configure certain iptables rules
289 and use policy routing. For more information on how to set it up
290 see Documentation/networking/tproxy.txt.
291
292 To compile it as a module, choose M here. If unsure, say N.
293
294endif # NF_CONNTRACK
295
290config NETFILTER_XTABLES 296config NETFILTER_XTABLES
291 tristate "Netfilter Xtables support (required for ip_tables)" 297 tristate "Netfilter Xtables support (required for ip_tables)"
292 default m if NETFILTER_ADVANCED=n 298 default m if NETFILTER_ADVANCED=n
@@ -294,11 +300,12 @@ config NETFILTER_XTABLES
294 This is required if you intend to use any of ip_tables, 300 This is required if you intend to use any of ip_tables,
295 ip6_tables or arp_tables. 301 ip6_tables or arp_tables.
296 302
303if NETFILTER_XTABLES
304
297# alphabetically ordered list of targets 305# alphabetically ordered list of targets
298 306
299config NETFILTER_XT_TARGET_CLASSIFY 307config NETFILTER_XT_TARGET_CLASSIFY
300 tristate '"CLASSIFY" target support' 308 tristate '"CLASSIFY" target support'
301 depends on NETFILTER_XTABLES
302 depends on NETFILTER_ADVANCED 309 depends on NETFILTER_ADVANCED
303 help 310 help
304 This option adds a `CLASSIFY' target, which enables the user to set 311 This option adds a `CLASSIFY' target, which enables the user to set
@@ -311,8 +318,6 @@ config NETFILTER_XT_TARGET_CLASSIFY
311 318
312config NETFILTER_XT_TARGET_CONNMARK 319config NETFILTER_XT_TARGET_CONNMARK
313 tristate '"CONNMARK" target support' 320 tristate '"CONNMARK" target support'
314 depends on NETFILTER_XTABLES
315 depends on IP_NF_MANGLE || IP6_NF_MANGLE
316 depends on NF_CONNTRACK 321 depends on NF_CONNTRACK
317 depends on NETFILTER_ADVANCED 322 depends on NETFILTER_ADVANCED
318 select NF_CONNTRACK_MARK 323 select NF_CONNTRACK_MARK
@@ -325,9 +330,20 @@ config NETFILTER_XT_TARGET_CONNMARK
325 <file:Documentation/kbuild/modules.txt>. The module will be called 330 <file:Documentation/kbuild/modules.txt>. The module will be called
326 ipt_CONNMARK.ko. If unsure, say `N'. 331 ipt_CONNMARK.ko. If unsure, say `N'.
327 332
333config NETFILTER_XT_TARGET_CONNSECMARK
334 tristate '"CONNSECMARK" target support'
335 depends on NF_CONNTRACK && NF_CONNTRACK_SECMARK
336 default m if NETFILTER_ADVANCED=n
337 help
338 The CONNSECMARK target copies security markings from packets
339 to connections, and restores security markings from connections
340 to packets (if the packets are not already marked). This would
341 normally be used in conjunction with the SECMARK target.
342
343 To compile it as a module, choose M here. If unsure, say N.
344
328config NETFILTER_XT_TARGET_DSCP 345config NETFILTER_XT_TARGET_DSCP
329 tristate '"DSCP" and "TOS" target support' 346 tristate '"DSCP" and "TOS" target support'
330 depends on NETFILTER_XTABLES
331 depends on IP_NF_MANGLE || IP6_NF_MANGLE 347 depends on IP_NF_MANGLE || IP6_NF_MANGLE
332 depends on NETFILTER_ADVANCED 348 depends on NETFILTER_ADVANCED
333 help 349 help
@@ -344,7 +360,6 @@ config NETFILTER_XT_TARGET_DSCP
344 360
345config NETFILTER_XT_TARGET_MARK 361config NETFILTER_XT_TARGET_MARK
346 tristate '"MARK" target support' 362 tristate '"MARK" target support'
347 depends on NETFILTER_XTABLES
348 default m if NETFILTER_ADVANCED=n 363 default m if NETFILTER_ADVANCED=n
349 help 364 help
350 This option adds a `MARK' target, which allows you to create rules 365 This option adds a `MARK' target, which allows you to create rules
@@ -356,21 +371,8 @@ config NETFILTER_XT_TARGET_MARK
356 371
357 To compile it as a module, choose M here. If unsure, say N. 372 To compile it as a module, choose M here. If unsure, say N.
358 373
359config NETFILTER_XT_TARGET_NFQUEUE
360 tristate '"NFQUEUE" target Support'
361 depends on NETFILTER_XTABLES
362 depends on NETFILTER_ADVANCED
363 help
364 This target replaced the old obsolete QUEUE target.
365
366 As opposed to QUEUE, it supports 65535 different queues,
367 not just one.
368
369 To compile it as a module, choose M here. If unsure, say N.
370
371config NETFILTER_XT_TARGET_NFLOG 374config NETFILTER_XT_TARGET_NFLOG
372 tristate '"NFLOG" target support' 375 tristate '"NFLOG" target support'
373 depends on NETFILTER_XTABLES
374 default m if NETFILTER_ADVANCED=n 376 default m if NETFILTER_ADVANCED=n
375 help 377 help
376 This option enables the NFLOG target, which allows to LOG 378 This option enables the NFLOG target, which allows to LOG
@@ -380,9 +382,19 @@ config NETFILTER_XT_TARGET_NFLOG
380 382
381 To compile it as a module, choose M here. If unsure, say N. 383 To compile it as a module, choose M here. If unsure, say N.
382 384
385config NETFILTER_XT_TARGET_NFQUEUE
386 tristate '"NFQUEUE" target Support'
387 depends on NETFILTER_ADVANCED
388 help
389 This target replaced the old obsolete QUEUE target.
390
391 As opposed to QUEUE, it supports 65535 different queues,
392 not just one.
393
394 To compile it as a module, choose M here. If unsure, say N.
395
383config NETFILTER_XT_TARGET_NOTRACK 396config NETFILTER_XT_TARGET_NOTRACK
384 tristate '"NOTRACK" target support' 397 tristate '"NOTRACK" target support'
385 depends on NETFILTER_XTABLES
386 depends on IP_NF_RAW || IP6_NF_RAW 398 depends on IP_NF_RAW || IP6_NF_RAW
387 depends on NF_CONNTRACK 399 depends on NF_CONNTRACK
388 depends on NETFILTER_ADVANCED 400 depends on NETFILTER_ADVANCED
@@ -397,7 +409,6 @@ config NETFILTER_XT_TARGET_NOTRACK
397 409
398config NETFILTER_XT_TARGET_RATEEST 410config NETFILTER_XT_TARGET_RATEEST
399 tristate '"RATEEST" target support' 411 tristate '"RATEEST" target support'
400 depends on NETFILTER_XTABLES
401 depends on NETFILTER_ADVANCED 412 depends on NETFILTER_ADVANCED
402 help 413 help
403 This option adds a `RATEEST' target, which allows to measure 414 This option adds a `RATEEST' target, which allows to measure
@@ -406,9 +417,23 @@ config NETFILTER_XT_TARGET_RATEEST
406 417
407 To compile it as a module, choose M here. If unsure, say N. 418 To compile it as a module, choose M here. If unsure, say N.
408 419
420config NETFILTER_XT_TARGET_TPROXY
421 tristate '"TPROXY" target support (EXPERIMENTAL)'
422 depends on EXPERIMENTAL
423 depends on NETFILTER_TPROXY
424 depends on NETFILTER_XTABLES
425 depends on NETFILTER_ADVANCED
426 select NF_DEFRAG_IPV4
427 help
428 This option adds a `TPROXY' target, which is somewhat similar to
429 REDIRECT. It can only be used in the mangle table and is useful
430 to redirect traffic to a transparent proxy. It does _not_ depend
431 on Netfilter connection tracking and NAT, unlike REDIRECT.
432
433 To compile it as a module, choose M here. If unsure, say N.
434
409config NETFILTER_XT_TARGET_TRACE 435config NETFILTER_XT_TARGET_TRACE
410 tristate '"TRACE" target support' 436 tristate '"TRACE" target support'
411 depends on NETFILTER_XTABLES
412 depends on IP_NF_RAW || IP6_NF_RAW 437 depends on IP_NF_RAW || IP6_NF_RAW
413 depends on NETFILTER_ADVANCED 438 depends on NETFILTER_ADVANCED
414 help 439 help
@@ -421,7 +446,7 @@ config NETFILTER_XT_TARGET_TRACE
421 446
422config NETFILTER_XT_TARGET_SECMARK 447config NETFILTER_XT_TARGET_SECMARK
423 tristate '"SECMARK" target support' 448 tristate '"SECMARK" target support'
424 depends on NETFILTER_XTABLES && NETWORK_SECMARK 449 depends on NETWORK_SECMARK
425 default m if NETFILTER_ADVANCED=n 450 default m if NETFILTER_ADVANCED=n
426 help 451 help
427 The SECMARK target allows security marking of network 452 The SECMARK target allows security marking of network
@@ -429,21 +454,9 @@ config NETFILTER_XT_TARGET_SECMARK
429 454
430 To compile it as a module, choose M here. If unsure, say N. 455 To compile it as a module, choose M here. If unsure, say N.
431 456
432config NETFILTER_XT_TARGET_CONNSECMARK
433 tristate '"CONNSECMARK" target support'
434 depends on NETFILTER_XTABLES && NF_CONNTRACK && NF_CONNTRACK_SECMARK
435 default m if NETFILTER_ADVANCED=n
436 help
437 The CONNSECMARK target copies security markings from packets
438 to connections, and restores security markings from connections
439 to packets (if the packets are not already marked). This would
440 normally be used in conjunction with the SECMARK target.
441
442 To compile it as a module, choose M here. If unsure, say N.
443
444config NETFILTER_XT_TARGET_TCPMSS 457config NETFILTER_XT_TARGET_TCPMSS
445 tristate '"TCPMSS" target support' 458 tristate '"TCPMSS" target support'
446 depends on NETFILTER_XTABLES && (IPV6 || IPV6=n) 459 depends on (IPV6 || IPV6=n)
447 default m if NETFILTER_ADVANCED=n 460 default m if NETFILTER_ADVANCED=n
448 ---help--- 461 ---help---
449 This option adds a `TCPMSS' target, which allows you to alter the 462 This option adds a `TCPMSS' target, which allows you to alter the
@@ -470,7 +483,7 @@ config NETFILTER_XT_TARGET_TCPMSS
470 483
471config NETFILTER_XT_TARGET_TCPOPTSTRIP 484config NETFILTER_XT_TARGET_TCPOPTSTRIP
472 tristate '"TCPOPTSTRIP" target support (EXPERIMENTAL)' 485 tristate '"TCPOPTSTRIP" target support (EXPERIMENTAL)'
473 depends on EXPERIMENTAL && NETFILTER_XTABLES 486 depends on EXPERIMENTAL
474 depends on IP_NF_MANGLE || IP6_NF_MANGLE 487 depends on IP_NF_MANGLE || IP6_NF_MANGLE
475 depends on NETFILTER_ADVANCED 488 depends on NETFILTER_ADVANCED
476 help 489 help
@@ -479,7 +492,6 @@ config NETFILTER_XT_TARGET_TCPOPTSTRIP
479 492
480config NETFILTER_XT_MATCH_COMMENT 493config NETFILTER_XT_MATCH_COMMENT
481 tristate '"comment" match support' 494 tristate '"comment" match support'
482 depends on NETFILTER_XTABLES
483 depends on NETFILTER_ADVANCED 495 depends on NETFILTER_ADVANCED
484 help 496 help
485 This option adds a `comment' dummy-match, which allows you to put 497 This option adds a `comment' dummy-match, which allows you to put
@@ -490,7 +502,6 @@ config NETFILTER_XT_MATCH_COMMENT
490 502
491config NETFILTER_XT_MATCH_CONNBYTES 503config NETFILTER_XT_MATCH_CONNBYTES
492 tristate '"connbytes" per-connection counter match support' 504 tristate '"connbytes" per-connection counter match support'
493 depends on NETFILTER_XTABLES
494 depends on NF_CONNTRACK 505 depends on NF_CONNTRACK
495 depends on NETFILTER_ADVANCED 506 depends on NETFILTER_ADVANCED
496 select NF_CT_ACCT 507 select NF_CT_ACCT
@@ -503,7 +514,6 @@ config NETFILTER_XT_MATCH_CONNBYTES
503 514
504config NETFILTER_XT_MATCH_CONNLIMIT 515config NETFILTER_XT_MATCH_CONNLIMIT
505 tristate '"connlimit" match support"' 516 tristate '"connlimit" match support"'
506 depends on NETFILTER_XTABLES
507 depends on NF_CONNTRACK 517 depends on NF_CONNTRACK
508 depends on NETFILTER_ADVANCED 518 depends on NETFILTER_ADVANCED
509 ---help--- 519 ---help---
@@ -512,7 +522,6 @@ config NETFILTER_XT_MATCH_CONNLIMIT
512 522
513config NETFILTER_XT_MATCH_CONNMARK 523config NETFILTER_XT_MATCH_CONNMARK
514 tristate '"connmark" connection mark match support' 524 tristate '"connmark" connection mark match support'
515 depends on NETFILTER_XTABLES
516 depends on NF_CONNTRACK 525 depends on NF_CONNTRACK
517 depends on NETFILTER_ADVANCED 526 depends on NETFILTER_ADVANCED
518 select NF_CONNTRACK_MARK 527 select NF_CONNTRACK_MARK
@@ -526,7 +535,6 @@ config NETFILTER_XT_MATCH_CONNMARK
526 535
527config NETFILTER_XT_MATCH_CONNTRACK 536config NETFILTER_XT_MATCH_CONNTRACK
528 tristate '"conntrack" connection tracking match support' 537 tristate '"conntrack" connection tracking match support'
529 depends on NETFILTER_XTABLES
530 depends on NF_CONNTRACK 538 depends on NF_CONNTRACK
531 default m if NETFILTER_ADVANCED=n 539 default m if NETFILTER_ADVANCED=n
532 help 540 help
@@ -540,7 +548,6 @@ config NETFILTER_XT_MATCH_CONNTRACK
540 548
541config NETFILTER_XT_MATCH_DCCP 549config NETFILTER_XT_MATCH_DCCP
542 tristate '"dccp" protocol match support' 550 tristate '"dccp" protocol match support'
543 depends on NETFILTER_XTABLES
544 depends on NETFILTER_ADVANCED 551 depends on NETFILTER_ADVANCED
545 default IP_DCCP 552 default IP_DCCP
546 help 553 help
@@ -553,7 +560,6 @@ config NETFILTER_XT_MATCH_DCCP
553 560
554config NETFILTER_XT_MATCH_DSCP 561config NETFILTER_XT_MATCH_DSCP
555 tristate '"dscp" and "tos" match support' 562 tristate '"dscp" and "tos" match support'
556 depends on NETFILTER_XTABLES
557 depends on NETFILTER_ADVANCED 563 depends on NETFILTER_ADVANCED
558 help 564 help
559 This option adds a `DSCP' match, which allows you to match against 565 This option adds a `DSCP' match, which allows you to match against
@@ -569,7 +575,6 @@ config NETFILTER_XT_MATCH_DSCP
569 575
570config NETFILTER_XT_MATCH_ESP 576config NETFILTER_XT_MATCH_ESP
571 tristate '"esp" match support' 577 tristate '"esp" match support'
572 depends on NETFILTER_XTABLES
573 depends on NETFILTER_ADVANCED 578 depends on NETFILTER_ADVANCED
574 help 579 help
575 This match extension allows you to match a range of SPIs 580 This match extension allows you to match a range of SPIs
@@ -577,9 +582,23 @@ config NETFILTER_XT_MATCH_ESP
577 582
578 To compile it as a module, choose M here. If unsure, say N. 583 To compile it as a module, choose M here. If unsure, say N.
579 584
585config NETFILTER_XT_MATCH_HASHLIMIT
586 tristate '"hashlimit" match support'
587 depends on (IP6_NF_IPTABLES || IP6_NF_IPTABLES=n)
588 depends on NETFILTER_ADVANCED
589 help
590 This option adds a `hashlimit' match.
591
592 As opposed to `limit', this match dynamically creates a hash table
593 of limit buckets, based on your selection of source/destination
594 addresses and/or ports.
595
596 It enables you to express policies like `10kpps for any given
597 destination address' or `500pps from any given source address'
598 with a single rule.
599
580config NETFILTER_XT_MATCH_HELPER 600config NETFILTER_XT_MATCH_HELPER
581 tristate '"helper" match support' 601 tristate '"helper" match support'
582 depends on NETFILTER_XTABLES
583 depends on NF_CONNTRACK 602 depends on NF_CONNTRACK
584 depends on NETFILTER_ADVANCED 603 depends on NETFILTER_ADVANCED
585 help 604 help
@@ -590,7 +609,6 @@ config NETFILTER_XT_MATCH_HELPER
590 609
591config NETFILTER_XT_MATCH_IPRANGE 610config NETFILTER_XT_MATCH_IPRANGE
592 tristate '"iprange" address range match support' 611 tristate '"iprange" address range match support'
593 depends on NETFILTER_XTABLES
594 depends on NETFILTER_ADVANCED 612 depends on NETFILTER_ADVANCED
595 ---help--- 613 ---help---
596 This option adds a "iprange" match, which allows you to match based on 614 This option adds a "iprange" match, which allows you to match based on
@@ -601,7 +619,6 @@ config NETFILTER_XT_MATCH_IPRANGE
601 619
602config NETFILTER_XT_MATCH_LENGTH 620config NETFILTER_XT_MATCH_LENGTH
603 tristate '"length" match support' 621 tristate '"length" match support'
604 depends on NETFILTER_XTABLES
605 depends on NETFILTER_ADVANCED 622 depends on NETFILTER_ADVANCED
606 help 623 help
607 This option allows you to match the length of a packet against a 624 This option allows you to match the length of a packet against a
@@ -611,7 +628,6 @@ config NETFILTER_XT_MATCH_LENGTH
611 628
612config NETFILTER_XT_MATCH_LIMIT 629config NETFILTER_XT_MATCH_LIMIT
613 tristate '"limit" match support' 630 tristate '"limit" match support'
614 depends on NETFILTER_XTABLES
615 depends on NETFILTER_ADVANCED 631 depends on NETFILTER_ADVANCED
616 help 632 help
617 limit matching allows you to control the rate at which a rule can be 633 limit matching allows you to control the rate at which a rule can be
@@ -622,7 +638,6 @@ config NETFILTER_XT_MATCH_LIMIT
622 638
623config NETFILTER_XT_MATCH_MAC 639config NETFILTER_XT_MATCH_MAC
624 tristate '"mac" address match support' 640 tristate '"mac" address match support'
625 depends on NETFILTER_XTABLES
626 depends on NETFILTER_ADVANCED 641 depends on NETFILTER_ADVANCED
627 help 642 help
628 MAC matching allows you to match packets based on the source 643 MAC matching allows you to match packets based on the source
@@ -632,7 +647,6 @@ config NETFILTER_XT_MATCH_MAC
632 647
633config NETFILTER_XT_MATCH_MARK 648config NETFILTER_XT_MATCH_MARK
634 tristate '"mark" match support' 649 tristate '"mark" match support'
635 depends on NETFILTER_XTABLES
636 default m if NETFILTER_ADVANCED=n 650 default m if NETFILTER_ADVANCED=n
637 help 651 help
638 Netfilter mark matching allows you to match packets based on the 652 Netfilter mark matching allows you to match packets based on the
@@ -641,9 +655,18 @@ config NETFILTER_XT_MATCH_MARK
641 655
642 To compile it as a module, choose M here. If unsure, say N. 656 To compile it as a module, choose M here. If unsure, say N.
643 657
658config NETFILTER_XT_MATCH_MULTIPORT
659 tristate '"multiport" Multiple port match support'
660 depends on NETFILTER_ADVANCED
661 help
662 Multiport matching allows you to match TCP or UDP packets based on
663 a series of source or destination ports: normally a rule can only
664 match a single range of ports.
665
666 To compile it as a module, choose M here. If unsure, say N.
667
644config NETFILTER_XT_MATCH_OWNER 668config NETFILTER_XT_MATCH_OWNER
645 tristate '"owner" match support' 669 tristate '"owner" match support'
646 depends on NETFILTER_XTABLES
647 depends on NETFILTER_ADVANCED 670 depends on NETFILTER_ADVANCED
648 ---help--- 671 ---help---
649 Socket owner matching allows you to match locally-generated packets 672 Socket owner matching allows you to match locally-generated packets
@@ -652,7 +675,7 @@ config NETFILTER_XT_MATCH_OWNER
652 675
653config NETFILTER_XT_MATCH_POLICY 676config NETFILTER_XT_MATCH_POLICY
654 tristate 'IPsec "policy" match support' 677 tristate 'IPsec "policy" match support'
655 depends on NETFILTER_XTABLES && XFRM 678 depends on XFRM
656 default m if NETFILTER_ADVANCED=n 679 default m if NETFILTER_ADVANCED=n
657 help 680 help
658 Policy matching allows you to match packets based on the 681 Policy matching allows you to match packets based on the
@@ -661,20 +684,9 @@ config NETFILTER_XT_MATCH_POLICY
661 684
662 To compile it as a module, choose M here. If unsure, say N. 685 To compile it as a module, choose M here. If unsure, say N.
663 686
664config NETFILTER_XT_MATCH_MULTIPORT
665 tristate '"multiport" Multiple port match support'
666 depends on NETFILTER_XTABLES
667 depends on NETFILTER_ADVANCED
668 help
669 Multiport matching allows you to match TCP or UDP packets based on
670 a series of source or destination ports: normally a rule can only
671 match a single range of ports.
672
673 To compile it as a module, choose M here. If unsure, say N.
674
675config NETFILTER_XT_MATCH_PHYSDEV 687config NETFILTER_XT_MATCH_PHYSDEV
676 tristate '"physdev" match support' 688 tristate '"physdev" match support'
677 depends on NETFILTER_XTABLES && BRIDGE && BRIDGE_NETFILTER 689 depends on BRIDGE && BRIDGE_NETFILTER
678 depends on NETFILTER_ADVANCED 690 depends on NETFILTER_ADVANCED
679 help 691 help
680 Physdev packet matching matches against the physical bridge ports 692 Physdev packet matching matches against the physical bridge ports
@@ -684,7 +696,6 @@ config NETFILTER_XT_MATCH_PHYSDEV
684 696
685config NETFILTER_XT_MATCH_PKTTYPE 697config NETFILTER_XT_MATCH_PKTTYPE
686 tristate '"pkttype" packet type match support' 698 tristate '"pkttype" packet type match support'
687 depends on NETFILTER_XTABLES
688 depends on NETFILTER_ADVANCED 699 depends on NETFILTER_ADVANCED
689 help 700 help
690 Packet type matching allows you to match a packet by 701 Packet type matching allows you to match a packet by
@@ -697,7 +708,6 @@ config NETFILTER_XT_MATCH_PKTTYPE
697 708
698config NETFILTER_XT_MATCH_QUOTA 709config NETFILTER_XT_MATCH_QUOTA
699 tristate '"quota" match support' 710 tristate '"quota" match support'
700 depends on NETFILTER_XTABLES
701 depends on NETFILTER_ADVANCED 711 depends on NETFILTER_ADVANCED
702 help 712 help
703 This option adds a `quota' match, which allows to match on a 713 This option adds a `quota' match, which allows to match on a
@@ -708,7 +718,6 @@ config NETFILTER_XT_MATCH_QUOTA
708 718
709config NETFILTER_XT_MATCH_RATEEST 719config NETFILTER_XT_MATCH_RATEEST
710 tristate '"rateest" match support' 720 tristate '"rateest" match support'
711 depends on NETFILTER_XTABLES
712 depends on NETFILTER_ADVANCED 721 depends on NETFILTER_ADVANCED
713 select NETFILTER_XT_TARGET_RATEEST 722 select NETFILTER_XT_TARGET_RATEEST
714 help 723 help
@@ -719,7 +728,6 @@ config NETFILTER_XT_MATCH_RATEEST
719 728
720config NETFILTER_XT_MATCH_REALM 729config NETFILTER_XT_MATCH_REALM
721 tristate '"realm" match support' 730 tristate '"realm" match support'
722 depends on NETFILTER_XTABLES
723 depends on NETFILTER_ADVANCED 731 depends on NETFILTER_ADVANCED
724 select NET_CLS_ROUTE 732 select NET_CLS_ROUTE
725 help 733 help
@@ -732,9 +740,26 @@ config NETFILTER_XT_MATCH_REALM
732 If you want to compile it as a module, say M here and read 740 If you want to compile it as a module, say M here and read
733 <file:Documentation/kbuild/modules.txt>. If unsure, say `N'. 741 <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
734 742
743config NETFILTER_XT_MATCH_RECENT
744 tristate '"recent" match support'
745 depends on NETFILTER_ADVANCED
746 ---help---
747 This match is used for creating one or many lists of recently
748 used addresses and then matching against that/those list(s).
749
750 Short options are available by using 'iptables -m recent -h'
751 Official Website: <http://snowman.net/projects/ipt_recent/>
752
753config NETFILTER_XT_MATCH_RECENT_PROC_COMPAT
754 bool 'Enable obsolete /proc/net/ipt_recent'
755 depends on NETFILTER_XT_MATCH_RECENT && PROC_FS
756 ---help---
757 This option enables the old /proc/net/ipt_recent interface,
758 which has been obsoleted by /proc/net/xt_recent.
759
735config NETFILTER_XT_MATCH_SCTP 760config NETFILTER_XT_MATCH_SCTP
736 tristate '"sctp" protocol match support (EXPERIMENTAL)' 761 tristate '"sctp" protocol match support (EXPERIMENTAL)'
737 depends on NETFILTER_XTABLES && EXPERIMENTAL 762 depends on EXPERIMENTAL
738 depends on NETFILTER_ADVANCED 763 depends on NETFILTER_ADVANCED
739 default IP_SCTP 764 default IP_SCTP
740 help 765 help
@@ -745,9 +770,23 @@ config NETFILTER_XT_MATCH_SCTP
745 If you want to compile it as a module, say M here and read 770 If you want to compile it as a module, say M here and read
746 <file:Documentation/kbuild/modules.txt>. If unsure, say `N'. 771 <file:Documentation/kbuild/modules.txt>. If unsure, say `N'.
747 772
773config NETFILTER_XT_MATCH_SOCKET
774 tristate '"socket" match support (EXPERIMENTAL)'
775 depends on EXPERIMENTAL
776 depends on NETFILTER_TPROXY
777 depends on NETFILTER_XTABLES
778 depends on NETFILTER_ADVANCED
779 select NF_DEFRAG_IPV4
780 help
781 This option adds a `socket' match, which can be used to match
782 packets for which a TCP or UDP socket lookup finds a valid socket.
783 It can be used in combination with the MARK target and policy
784 routing to implement full featured non-locally bound sockets.
785
786 To compile it as a module, choose M here. If unsure, say N.
787
748config NETFILTER_XT_MATCH_STATE 788config NETFILTER_XT_MATCH_STATE
749 tristate '"state" match support' 789 tristate '"state" match support'
750 depends on NETFILTER_XTABLES
751 depends on NF_CONNTRACK 790 depends on NF_CONNTRACK
752 default m if NETFILTER_ADVANCED=n 791 default m if NETFILTER_ADVANCED=n
753 help 792 help
@@ -759,7 +798,6 @@ config NETFILTER_XT_MATCH_STATE
759 798
760config NETFILTER_XT_MATCH_STATISTIC 799config NETFILTER_XT_MATCH_STATISTIC
761 tristate '"statistic" match support' 800 tristate '"statistic" match support'
762 depends on NETFILTER_XTABLES
763 depends on NETFILTER_ADVANCED 801 depends on NETFILTER_ADVANCED
764 help 802 help
765 This option adds a `statistic' match, which allows you to match 803 This option adds a `statistic' match, which allows you to match
@@ -769,7 +807,6 @@ config NETFILTER_XT_MATCH_STATISTIC
769 807
770config NETFILTER_XT_MATCH_STRING 808config NETFILTER_XT_MATCH_STRING
771 tristate '"string" match support' 809 tristate '"string" match support'
772 depends on NETFILTER_XTABLES
773 depends on NETFILTER_ADVANCED 810 depends on NETFILTER_ADVANCED
774 select TEXTSEARCH 811 select TEXTSEARCH
775 select TEXTSEARCH_KMP 812 select TEXTSEARCH_KMP
@@ -783,7 +820,6 @@ config NETFILTER_XT_MATCH_STRING
783 820
784config NETFILTER_XT_MATCH_TCPMSS 821config NETFILTER_XT_MATCH_TCPMSS
785 tristate '"tcpmss" match support' 822 tristate '"tcpmss" match support'
786 depends on NETFILTER_XTABLES
787 depends on NETFILTER_ADVANCED 823 depends on NETFILTER_ADVANCED
788 help 824 help
789 This option adds a `tcpmss' match, which allows you to examine the 825 This option adds a `tcpmss' match, which allows you to examine the
@@ -794,7 +830,6 @@ config NETFILTER_XT_MATCH_TCPMSS
794 830
795config NETFILTER_XT_MATCH_TIME 831config NETFILTER_XT_MATCH_TIME
796 tristate '"time" match support' 832 tristate '"time" match support'
797 depends on NETFILTER_XTABLES
798 depends on NETFILTER_ADVANCED 833 depends on NETFILTER_ADVANCED
799 ---help--- 834 ---help---
800 This option adds a "time" match, which allows you to match based on 835 This option adds a "time" match, which allows you to match based on
@@ -809,7 +844,6 @@ config NETFILTER_XT_MATCH_TIME
809 844
810config NETFILTER_XT_MATCH_U32 845config NETFILTER_XT_MATCH_U32
811 tristate '"u32" match support' 846 tristate '"u32" match support'
812 depends on NETFILTER_XTABLES
813 depends on NETFILTER_ADVANCED 847 depends on NETFILTER_ADVANCED
814 ---help--- 848 ---help---
815 u32 allows you to extract quantities of up to 4 bytes from a packet, 849 u32 allows you to extract quantities of up to 4 bytes from a packet,
@@ -821,20 +855,8 @@ config NETFILTER_XT_MATCH_U32
821 855
822 Details and examples are in the kernel module source. 856 Details and examples are in the kernel module source.
823 857
824config NETFILTER_XT_MATCH_HASHLIMIT 858endif # NETFILTER_XTABLES
825 tristate '"hashlimit" match support'
826 depends on NETFILTER_XTABLES && (IP6_NF_IPTABLES || IP6_NF_IPTABLES=n)
827 depends on NETFILTER_ADVANCED
828 help
829 This option adds a `hashlimit' match.
830
831 As opposed to `limit', this match dynamically creates a hash table
832 of limit buckets, based on your selection of source/destination
833 addresses and/or ports.
834
835 It enables you to express policies like `10kpps for any given
836 destination address' or `500pps from any given source address'
837 with a single rule.
838 859
839endmenu 860endmenu
840 861
862source "net/netfilter/ipvs/Kconfig"
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 3bd2cc556aea..da3d909e053f 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -34,6 +34,9 @@ obj-$(CONFIG_NF_CONNTRACK_SANE) += nf_conntrack_sane.o
34obj-$(CONFIG_NF_CONNTRACK_SIP) += nf_conntrack_sip.o 34obj-$(CONFIG_NF_CONNTRACK_SIP) += nf_conntrack_sip.o
35obj-$(CONFIG_NF_CONNTRACK_TFTP) += nf_conntrack_tftp.o 35obj-$(CONFIG_NF_CONNTRACK_TFTP) += nf_conntrack_tftp.o
36 36
37# transparent proxy support
38obj-$(CONFIG_NETFILTER_TPROXY) += nf_tproxy_core.o
39
37# generic X tables 40# generic X tables
38obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o 41obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o
39 42
@@ -48,6 +51,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
48obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o 51obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o
49obj-$(CONFIG_NETFILTER_XT_TARGET_RATEEST) += xt_RATEEST.o 52obj-$(CONFIG_NETFILTER_XT_TARGET_RATEEST) += xt_RATEEST.o
50obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o 53obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o
54obj-$(CONFIG_NETFILTER_XT_TARGET_TPROXY) += xt_TPROXY.o
51obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o 55obj-$(CONFIG_NETFILTER_XT_TARGET_TCPMSS) += xt_TCPMSS.o
52obj-$(CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP) += xt_TCPOPTSTRIP.o 56obj-$(CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP) += xt_TCPOPTSTRIP.o
53obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o 57obj-$(CONFIG_NETFILTER_XT_TARGET_TRACE) += xt_TRACE.o
@@ -76,10 +80,15 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o
76obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) += xt_quota.o 80obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) += xt_quota.o
77obj-$(CONFIG_NETFILTER_XT_MATCH_RATEEST) += xt_rateest.o 81obj-$(CONFIG_NETFILTER_XT_MATCH_RATEEST) += xt_rateest.o
78obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o 82obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o
83obj-$(CONFIG_NETFILTER_XT_MATCH_RECENT) += xt_recent.o
79obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o 84obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
85obj-$(CONFIG_NETFILTER_XT_MATCH_SOCKET) += xt_socket.o
80obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o 86obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o
81obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o 87obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o
82obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o 88obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o
83obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o 89obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o
84obj-$(CONFIG_NETFILTER_XT_MATCH_TIME) += xt_time.o 90obj-$(CONFIG_NETFILTER_XT_MATCH_TIME) += xt_time.o
85obj-$(CONFIG_NETFILTER_XT_MATCH_U32) += xt_u32.o 91obj-$(CONFIG_NETFILTER_XT_MATCH_U32) += xt_u32.o
92
93# IPVS
94obj-$(CONFIG_IP_VS) += ipvs/
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index 292fa28146fb..a90ac83c5918 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -26,7 +26,7 @@
26 26
27static DEFINE_MUTEX(afinfo_mutex); 27static DEFINE_MUTEX(afinfo_mutex);
28 28
29const struct nf_afinfo *nf_afinfo[NPROTO] __read_mostly; 29const struct nf_afinfo *nf_afinfo[NFPROTO_NUMPROTO] __read_mostly;
30EXPORT_SYMBOL(nf_afinfo); 30EXPORT_SYMBOL(nf_afinfo);
31 31
32int nf_register_afinfo(const struct nf_afinfo *afinfo) 32int nf_register_afinfo(const struct nf_afinfo *afinfo)
@@ -51,7 +51,7 @@ void nf_unregister_afinfo(const struct nf_afinfo *afinfo)
51} 51}
52EXPORT_SYMBOL_GPL(nf_unregister_afinfo); 52EXPORT_SYMBOL_GPL(nf_unregister_afinfo);
53 53
54struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS] __read_mostly; 54struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS] __read_mostly;
55EXPORT_SYMBOL(nf_hooks); 55EXPORT_SYMBOL(nf_hooks);
56static DEFINE_MUTEX(nf_hook_mutex); 56static DEFINE_MUTEX(nf_hook_mutex);
57 57
@@ -113,7 +113,7 @@ EXPORT_SYMBOL(nf_unregister_hooks);
113 113
114unsigned int nf_iterate(struct list_head *head, 114unsigned int nf_iterate(struct list_head *head,
115 struct sk_buff *skb, 115 struct sk_buff *skb,
116 int hook, 116 unsigned int hook,
117 const struct net_device *indev, 117 const struct net_device *indev,
118 const struct net_device *outdev, 118 const struct net_device *outdev,
119 struct list_head **i, 119 struct list_head **i,
@@ -155,7 +155,7 @@ unsigned int nf_iterate(struct list_head *head,
155 155
156/* Returns 1 if okfn() needs to be executed by the caller, 156/* Returns 1 if okfn() needs to be executed by the caller,
157 * -EPERM for NF_DROP, 0 otherwise. */ 157 * -EPERM for NF_DROP, 0 otherwise. */
158int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb, 158int nf_hook_slow(u_int8_t pf, unsigned int hook, struct sk_buff *skb,
159 struct net_device *indev, 159 struct net_device *indev,
160 struct net_device *outdev, 160 struct net_device *outdev,
161 int (*okfn)(struct sk_buff *), 161 int (*okfn)(struct sk_buff *),
@@ -165,14 +165,6 @@ int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb,
165 unsigned int verdict; 165 unsigned int verdict;
166 int ret = 0; 166 int ret = 0;
167 167
168#ifdef CONFIG_NET_NS
169 struct net *net;
170
171 net = indev == NULL ? dev_net(outdev) : dev_net(indev);
172 if (net != &init_net)
173 return 1;
174#endif
175
176 /* We may already have this, but read-locks nest anyway */ 168 /* We may already have this, but read-locks nest anyway */
177 rcu_read_lock(); 169 rcu_read_lock();
178 170
@@ -264,7 +256,7 @@ EXPORT_SYMBOL(proc_net_netfilter);
264void __init netfilter_init(void) 256void __init netfilter_init(void)
265{ 257{
266 int i, h; 258 int i, h;
267 for (i = 0; i < NPROTO; i++) { 259 for (i = 0; i < ARRAY_SIZE(nf_hooks); i++) {
268 for (h = 0; h < NF_MAX_HOOKS; h++) 260 for (h = 0; h < NF_MAX_HOOKS; h++)
269 INIT_LIST_HEAD(&nf_hooks[i][h]); 261 INIT_LIST_HEAD(&nf_hooks[i][h]);
270 } 262 }
diff --git a/net/ipv4/ipvs/Kconfig b/net/netfilter/ipvs/Kconfig
index 09d0c3f35669..05048e403266 100644
--- a/net/ipv4/ipvs/Kconfig
+++ b/net/netfilter/ipvs/Kconfig
@@ -2,8 +2,8 @@
2# IP Virtual Server configuration 2# IP Virtual Server configuration
3# 3#
4menuconfig IP_VS 4menuconfig IP_VS
5 tristate "IP virtual server support (EXPERIMENTAL)" 5 tristate "IP virtual server support"
6 depends on NETFILTER 6 depends on NET && INET && NETFILTER
7 ---help--- 7 ---help---
8 IP Virtual Server support will let you build a high-performance 8 IP Virtual Server support will let you build a high-performance
9 virtual server based on cluster of two or more real servers. This 9 virtual server based on cluster of two or more real servers. This
@@ -24,6 +24,14 @@ menuconfig IP_VS
24 24
25if IP_VS 25if IP_VS
26 26
27config IP_VS_IPV6
28 bool "IPv6 support for IPVS (DANGEROUS)"
29 depends on EXPERIMENTAL && (IPV6 = y || IP_VS = IPV6)
30 ---help---
31 Add IPv6 support to IPVS. This is incomplete and might be dangerous.
32
33 Say N if unsure.
34
27config IP_VS_DEBUG 35config IP_VS_DEBUG
28 bool "IP virtual server debugging" 36 bool "IP virtual server debugging"
29 ---help--- 37 ---help---
@@ -33,7 +41,8 @@ config IP_VS_DEBUG
33 41
34config IP_VS_TAB_BITS 42config IP_VS_TAB_BITS
35 int "IPVS connection table size (the Nth power of 2)" 43 int "IPVS connection table size (the Nth power of 2)"
36 default "12" 44 range 8 20
45 default 12
37 ---help--- 46 ---help---
38 The IPVS connection hash table uses the chaining scheme to handle 47 The IPVS connection hash table uses the chaining scheme to handle
39 hash collisions. Using a big IPVS connection hash table will greatly 48 hash collisions. Using a big IPVS connection hash table will greatly
@@ -71,14 +80,20 @@ config IP_VS_PROTO_UDP
71 This option enables support for load balancing UDP transport 80 This option enables support for load balancing UDP transport
72 protocol. Say Y if unsure. 81 protocol. Say Y if unsure.
73 82
83config IP_VS_PROTO_AH_ESP
84 bool
85 depends on UNDEFINED
86
74config IP_VS_PROTO_ESP 87config IP_VS_PROTO_ESP
75 bool "ESP load balancing support" 88 bool "ESP load balancing support"
89 select IP_VS_PROTO_AH_ESP
76 ---help--- 90 ---help---
77 This option enables support for load balancing ESP (Encapsulation 91 This option enables support for load balancing ESP (Encapsulation
78 Security Payload) transport protocol. Say Y if unsure. 92 Security Payload) transport protocol. Say Y if unsure.
79 93
80config IP_VS_PROTO_AH 94config IP_VS_PROTO_AH
81 bool "AH load balancing support" 95 bool "AH load balancing support"
96 select IP_VS_PROTO_AH_ESP
82 ---help--- 97 ---help---
83 This option enables support for load balancing AH (Authentication 98 This option enables support for load balancing AH (Authentication
84 Header) transport protocol. Say Y if unsure. 99 Header) transport protocol. Say Y if unsure.
diff --git a/net/ipv4/ipvs/Makefile b/net/netfilter/ipvs/Makefile
index 30e85de9ffff..73a46fe1fe4c 100644
--- a/net/ipv4/ipvs/Makefile
+++ b/net/netfilter/ipvs/Makefile
@@ -6,8 +6,7 @@
6ip_vs_proto-objs-y := 6ip_vs_proto-objs-y :=
7ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_TCP) += ip_vs_proto_tcp.o 7ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_TCP) += ip_vs_proto_tcp.o
8ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_UDP) += ip_vs_proto_udp.o 8ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_UDP) += ip_vs_proto_udp.o
9ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_ESP) += ip_vs_proto_esp.o 9ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_AH_ESP) += ip_vs_proto_ah_esp.o
10ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_AH) += ip_vs_proto_ah.o
11 10
12ip_vs-objs := ip_vs_conn.o ip_vs_core.o ip_vs_ctl.o ip_vs_sched.o \ 11ip_vs-objs := ip_vs_conn.o ip_vs_core.o ip_vs_ctl.o ip_vs_sched.o \
13 ip_vs_xmit.o ip_vs_app.o ip_vs_sync.o \ 12 ip_vs_xmit.o ip_vs_app.o ip_vs_sync.o \
diff --git a/net/ipv4/ipvs/ip_vs_app.c b/net/netfilter/ipvs/ip_vs_app.c
index 201b8ea3020d..201b8ea3020d 100644
--- a/net/ipv4/ipvs/ip_vs_app.c
+++ b/net/netfilter/ipvs/ip_vs_app.c
diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
index 44a6872dc245..9a24332fbed8 100644
--- a/net/ipv4/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@ -114,9 +114,18 @@ static inline void ct_write_unlock_bh(unsigned key)
114/* 114/*
115 * Returns hash value for IPVS connection entry 115 * Returns hash value for IPVS connection entry
116 */ 116 */
117static unsigned int ip_vs_conn_hashkey(unsigned proto, __be32 addr, __be16 port) 117static unsigned int ip_vs_conn_hashkey(int af, unsigned proto,
118 const union nf_inet_addr *addr,
119 __be16 port)
118{ 120{
119 return jhash_3words((__force u32)addr, (__force u32)port, proto, ip_vs_conn_rnd) 121#ifdef CONFIG_IP_VS_IPV6
122 if (af == AF_INET6)
123 return jhash_3words(jhash(addr, 16, ip_vs_conn_rnd),
124 (__force u32)port, proto, ip_vs_conn_rnd)
125 & IP_VS_CONN_TAB_MASK;
126#endif
127 return jhash_3words((__force u32)addr->ip, (__force u32)port, proto,
128 ip_vs_conn_rnd)
120 & IP_VS_CONN_TAB_MASK; 129 & IP_VS_CONN_TAB_MASK;
121} 130}
122 131
@@ -131,7 +140,7 @@ static inline int ip_vs_conn_hash(struct ip_vs_conn *cp)
131 int ret; 140 int ret;
132 141
133 /* Hash by protocol, client address and port */ 142 /* Hash by protocol, client address and port */
134 hash = ip_vs_conn_hashkey(cp->protocol, cp->caddr, cp->cport); 143 hash = ip_vs_conn_hashkey(cp->af, cp->protocol, &cp->caddr, cp->cport);
135 144
136 ct_write_lock(hash); 145 ct_write_lock(hash);
137 146
@@ -162,7 +171,7 @@ static inline int ip_vs_conn_unhash(struct ip_vs_conn *cp)
162 int ret; 171 int ret;
163 172
164 /* unhash it and decrease its reference counter */ 173 /* unhash it and decrease its reference counter */
165 hash = ip_vs_conn_hashkey(cp->protocol, cp->caddr, cp->cport); 174 hash = ip_vs_conn_hashkey(cp->af, cp->protocol, &cp->caddr, cp->cport);
166 175
167 ct_write_lock(hash); 176 ct_write_lock(hash);
168 177
@@ -187,20 +196,23 @@ static inline int ip_vs_conn_unhash(struct ip_vs_conn *cp)
187 * d_addr, d_port: pkt dest address (load balancer) 196 * d_addr, d_port: pkt dest address (load balancer)
188 */ 197 */
189static inline struct ip_vs_conn *__ip_vs_conn_in_get 198static inline struct ip_vs_conn *__ip_vs_conn_in_get
190(int protocol, __be32 s_addr, __be16 s_port, __be32 d_addr, __be16 d_port) 199(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port,
200 const union nf_inet_addr *d_addr, __be16 d_port)
191{ 201{
192 unsigned hash; 202 unsigned hash;
193 struct ip_vs_conn *cp; 203 struct ip_vs_conn *cp;
194 204
195 hash = ip_vs_conn_hashkey(protocol, s_addr, s_port); 205 hash = ip_vs_conn_hashkey(af, protocol, s_addr, s_port);
196 206
197 ct_read_lock(hash); 207 ct_read_lock(hash);
198 208
199 list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) { 209 list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) {
200 if (s_addr==cp->caddr && s_port==cp->cport && 210 if (cp->af == af &&
201 d_port==cp->vport && d_addr==cp->vaddr && 211 ip_vs_addr_equal(af, s_addr, &cp->caddr) &&
212 ip_vs_addr_equal(af, d_addr, &cp->vaddr) &&
213 s_port == cp->cport && d_port == cp->vport &&
202 ((!s_port) ^ (!(cp->flags & IP_VS_CONN_F_NO_CPORT))) && 214 ((!s_port) ^ (!(cp->flags & IP_VS_CONN_F_NO_CPORT))) &&
203 protocol==cp->protocol) { 215 protocol == cp->protocol) {
204 /* HIT */ 216 /* HIT */
205 atomic_inc(&cp->refcnt); 217 atomic_inc(&cp->refcnt);
206 ct_read_unlock(hash); 218 ct_read_unlock(hash);
@@ -214,39 +226,44 @@ static inline struct ip_vs_conn *__ip_vs_conn_in_get
214} 226}
215 227
216struct ip_vs_conn *ip_vs_conn_in_get 228struct ip_vs_conn *ip_vs_conn_in_get
217(int protocol, __be32 s_addr, __be16 s_port, __be32 d_addr, __be16 d_port) 229(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port,
230 const union nf_inet_addr *d_addr, __be16 d_port)
218{ 231{
219 struct ip_vs_conn *cp; 232 struct ip_vs_conn *cp;
220 233
221 cp = __ip_vs_conn_in_get(protocol, s_addr, s_port, d_addr, d_port); 234 cp = __ip_vs_conn_in_get(af, protocol, s_addr, s_port, d_addr, d_port);
222 if (!cp && atomic_read(&ip_vs_conn_no_cport_cnt)) 235 if (!cp && atomic_read(&ip_vs_conn_no_cport_cnt))
223 cp = __ip_vs_conn_in_get(protocol, s_addr, 0, d_addr, d_port); 236 cp = __ip_vs_conn_in_get(af, protocol, s_addr, 0, d_addr,
237 d_port);
224 238
225 IP_VS_DBG(9, "lookup/in %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n", 239 IP_VS_DBG_BUF(9, "lookup/in %s %s:%d->%s:%d %s\n",
226 ip_vs_proto_name(protocol), 240 ip_vs_proto_name(protocol),
227 NIPQUAD(s_addr), ntohs(s_port), 241 IP_VS_DBG_ADDR(af, s_addr), ntohs(s_port),
228 NIPQUAD(d_addr), ntohs(d_port), 242 IP_VS_DBG_ADDR(af, d_addr), ntohs(d_port),
229 cp?"hit":"not hit"); 243 cp ? "hit" : "not hit");
230 244
231 return cp; 245 return cp;
232} 246}
233 247
234/* Get reference to connection template */ 248/* Get reference to connection template */
235struct ip_vs_conn *ip_vs_ct_in_get 249struct ip_vs_conn *ip_vs_ct_in_get
236(int protocol, __be32 s_addr, __be16 s_port, __be32 d_addr, __be16 d_port) 250(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port,
251 const union nf_inet_addr *d_addr, __be16 d_port)
237{ 252{
238 unsigned hash; 253 unsigned hash;
239 struct ip_vs_conn *cp; 254 struct ip_vs_conn *cp;
240 255
241 hash = ip_vs_conn_hashkey(protocol, s_addr, s_port); 256 hash = ip_vs_conn_hashkey(af, protocol, s_addr, s_port);
242 257
243 ct_read_lock(hash); 258 ct_read_lock(hash);
244 259
245 list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) { 260 list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) {
246 if (s_addr==cp->caddr && s_port==cp->cport && 261 if (cp->af == af &&
247 d_port==cp->vport && d_addr==cp->vaddr && 262 ip_vs_addr_equal(af, s_addr, &cp->caddr) &&
263 ip_vs_addr_equal(af, d_addr, &cp->vaddr) &&
264 s_port == cp->cport && d_port == cp->vport &&
248 cp->flags & IP_VS_CONN_F_TEMPLATE && 265 cp->flags & IP_VS_CONN_F_TEMPLATE &&
249 protocol==cp->protocol) { 266 protocol == cp->protocol) {
250 /* HIT */ 267 /* HIT */
251 atomic_inc(&cp->refcnt); 268 atomic_inc(&cp->refcnt);
252 goto out; 269 goto out;
@@ -257,11 +274,11 @@ struct ip_vs_conn *ip_vs_ct_in_get
257 out: 274 out:
258 ct_read_unlock(hash); 275 ct_read_unlock(hash);
259 276
260 IP_VS_DBG(9, "template lookup/in %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n", 277 IP_VS_DBG_BUF(9, "template lookup/in %s %s:%d->%s:%d %s\n",
261 ip_vs_proto_name(protocol), 278 ip_vs_proto_name(protocol),
262 NIPQUAD(s_addr), ntohs(s_port), 279 IP_VS_DBG_ADDR(af, s_addr), ntohs(s_port),
263 NIPQUAD(d_addr), ntohs(d_port), 280 IP_VS_DBG_ADDR(af, d_addr), ntohs(d_port),
264 cp?"hit":"not hit"); 281 cp ? "hit" : "not hit");
265 282
266 return cp; 283 return cp;
267} 284}
@@ -273,7 +290,8 @@ struct ip_vs_conn *ip_vs_ct_in_get
273 * d_addr, d_port: pkt dest address (foreign host) 290 * d_addr, d_port: pkt dest address (foreign host)
274 */ 291 */
275struct ip_vs_conn *ip_vs_conn_out_get 292struct ip_vs_conn *ip_vs_conn_out_get
276(int protocol, __be32 s_addr, __be16 s_port, __be32 d_addr, __be16 d_port) 293(int af, int protocol, const union nf_inet_addr *s_addr, __be16 s_port,
294 const union nf_inet_addr *d_addr, __be16 d_port)
277{ 295{
278 unsigned hash; 296 unsigned hash;
279 struct ip_vs_conn *cp, *ret=NULL; 297 struct ip_vs_conn *cp, *ret=NULL;
@@ -281,13 +299,15 @@ struct ip_vs_conn *ip_vs_conn_out_get
281 /* 299 /*
282 * Check for "full" addressed entries 300 * Check for "full" addressed entries
283 */ 301 */
284 hash = ip_vs_conn_hashkey(protocol, d_addr, d_port); 302 hash = ip_vs_conn_hashkey(af, protocol, d_addr, d_port);
285 303
286 ct_read_lock(hash); 304 ct_read_lock(hash);
287 305
288 list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) { 306 list_for_each_entry(cp, &ip_vs_conn_tab[hash], c_list) {
289 if (d_addr == cp->caddr && d_port == cp->cport && 307 if (cp->af == af &&
290 s_port == cp->dport && s_addr == cp->daddr && 308 ip_vs_addr_equal(af, d_addr, &cp->caddr) &&
309 ip_vs_addr_equal(af, s_addr, &cp->daddr) &&
310 d_port == cp->cport && s_port == cp->dport &&
291 protocol == cp->protocol) { 311 protocol == cp->protocol) {
292 /* HIT */ 312 /* HIT */
293 atomic_inc(&cp->refcnt); 313 atomic_inc(&cp->refcnt);
@@ -298,11 +318,11 @@ struct ip_vs_conn *ip_vs_conn_out_get
298 318
299 ct_read_unlock(hash); 319 ct_read_unlock(hash);
300 320
301 IP_VS_DBG(9, "lookup/out %s %u.%u.%u.%u:%d->%u.%u.%u.%u:%d %s\n", 321 IP_VS_DBG_BUF(9, "lookup/out %s %s:%d->%s:%d %s\n",
302 ip_vs_proto_name(protocol), 322 ip_vs_proto_name(protocol),
303 NIPQUAD(s_addr), ntohs(s_port), 323 IP_VS_DBG_ADDR(af, s_addr), ntohs(s_port),
304 NIPQUAD(d_addr), ntohs(d_port), 324 IP_VS_DBG_ADDR(af, d_addr), ntohs(d_port),
305 ret?"hit":"not hit"); 325 ret ? "hit" : "not hit");
306 326
307 return ret; 327 return ret;
308} 328}
@@ -369,6 +389,33 @@ static inline void ip_vs_bind_xmit(struct ip_vs_conn *cp)
369 } 389 }
370} 390}
371 391
392#ifdef CONFIG_IP_VS_IPV6
393static inline void ip_vs_bind_xmit_v6(struct ip_vs_conn *cp)
394{
395 switch (IP_VS_FWD_METHOD(cp)) {
396 case IP_VS_CONN_F_MASQ:
397 cp->packet_xmit = ip_vs_nat_xmit_v6;
398 break;
399
400 case IP_VS_CONN_F_TUNNEL:
401 cp->packet_xmit = ip_vs_tunnel_xmit_v6;
402 break;
403
404 case IP_VS_CONN_F_DROUTE:
405 cp->packet_xmit = ip_vs_dr_xmit_v6;
406 break;
407
408 case IP_VS_CONN_F_LOCALNODE:
409 cp->packet_xmit = ip_vs_null_xmit;
410 break;
411
412 case IP_VS_CONN_F_BYPASS:
413 cp->packet_xmit = ip_vs_bypass_xmit_v6;
414 break;
415 }
416}
417#endif
418
372 419
373static inline int ip_vs_dest_totalconns(struct ip_vs_dest *dest) 420static inline int ip_vs_dest_totalconns(struct ip_vs_dest *dest)
374{ 421{
@@ -402,16 +449,16 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)
402 cp->flags |= atomic_read(&dest->conn_flags); 449 cp->flags |= atomic_read(&dest->conn_flags);
403 cp->dest = dest; 450 cp->dest = dest;
404 451
405 IP_VS_DBG(7, "Bind-dest %s c:%u.%u.%u.%u:%d v:%u.%u.%u.%u:%d " 452 IP_VS_DBG_BUF(7, "Bind-dest %s c:%s:%d v:%s:%d "
406 "d:%u.%u.%u.%u:%d fwd:%c s:%u conn->flags:%X conn->refcnt:%d " 453 "d:%s:%d fwd:%c s:%u conn->flags:%X conn->refcnt:%d "
407 "dest->refcnt:%d\n", 454 "dest->refcnt:%d\n",
408 ip_vs_proto_name(cp->protocol), 455 ip_vs_proto_name(cp->protocol),
409 NIPQUAD(cp->caddr), ntohs(cp->cport), 456 IP_VS_DBG_ADDR(cp->af, &cp->caddr), ntohs(cp->cport),
410 NIPQUAD(cp->vaddr), ntohs(cp->vport), 457 IP_VS_DBG_ADDR(cp->af, &cp->vaddr), ntohs(cp->vport),
411 NIPQUAD(cp->daddr), ntohs(cp->dport), 458 IP_VS_DBG_ADDR(cp->af, &cp->daddr), ntohs(cp->dport),
412 ip_vs_fwd_tag(cp), cp->state, 459 ip_vs_fwd_tag(cp), cp->state,
413 cp->flags, atomic_read(&cp->refcnt), 460 cp->flags, atomic_read(&cp->refcnt),
414 atomic_read(&dest->refcnt)); 461 atomic_read(&dest->refcnt));
415 462
416 /* Update the connection counters */ 463 /* Update the connection counters */
417 if (!(cp->flags & IP_VS_CONN_F_TEMPLATE)) { 464 if (!(cp->flags & IP_VS_CONN_F_TEMPLATE)) {
@@ -444,8 +491,9 @@ struct ip_vs_dest *ip_vs_try_bind_dest(struct ip_vs_conn *cp)
444 struct ip_vs_dest *dest; 491 struct ip_vs_dest *dest;
445 492
446 if ((cp) && (!cp->dest)) { 493 if ((cp) && (!cp->dest)) {
447 dest = ip_vs_find_dest(cp->daddr, cp->dport, 494 dest = ip_vs_find_dest(cp->af, &cp->daddr, cp->dport,
448 cp->vaddr, cp->vport, cp->protocol); 495 &cp->vaddr, cp->vport,
496 cp->protocol);
449 ip_vs_bind_dest(cp, dest); 497 ip_vs_bind_dest(cp, dest);
450 return dest; 498 return dest;
451 } else 499 } else
@@ -464,16 +512,16 @@ static inline void ip_vs_unbind_dest(struct ip_vs_conn *cp)
464 if (!dest) 512 if (!dest)
465 return; 513 return;
466 514
467 IP_VS_DBG(7, "Unbind-dest %s c:%u.%u.%u.%u:%d v:%u.%u.%u.%u:%d " 515 IP_VS_DBG_BUF(7, "Unbind-dest %s c:%s:%d v:%s:%d "
468 "d:%u.%u.%u.%u:%d fwd:%c s:%u conn->flags:%X conn->refcnt:%d " 516 "d:%s:%d fwd:%c s:%u conn->flags:%X conn->refcnt:%d "
469 "dest->refcnt:%d\n", 517 "dest->refcnt:%d\n",
470 ip_vs_proto_name(cp->protocol), 518 ip_vs_proto_name(cp->protocol),
471 NIPQUAD(cp->caddr), ntohs(cp->cport), 519 IP_VS_DBG_ADDR(cp->af, &cp->caddr), ntohs(cp->cport),
472 NIPQUAD(cp->vaddr), ntohs(cp->vport), 520 IP_VS_DBG_ADDR(cp->af, &cp->vaddr), ntohs(cp->vport),
473 NIPQUAD(cp->daddr), ntohs(cp->dport), 521 IP_VS_DBG_ADDR(cp->af, &cp->daddr), ntohs(cp->dport),
474 ip_vs_fwd_tag(cp), cp->state, 522 ip_vs_fwd_tag(cp), cp->state,
475 cp->flags, atomic_read(&cp->refcnt), 523 cp->flags, atomic_read(&cp->refcnt),
476 atomic_read(&dest->refcnt)); 524 atomic_read(&dest->refcnt));
477 525
478 /* Update the connection counters */ 526 /* Update the connection counters */
479 if (!(cp->flags & IP_VS_CONN_F_TEMPLATE)) { 527 if (!(cp->flags & IP_VS_CONN_F_TEMPLATE)) {
@@ -526,13 +574,16 @@ int ip_vs_check_template(struct ip_vs_conn *ct)
526 !(dest->flags & IP_VS_DEST_F_AVAILABLE) || 574 !(dest->flags & IP_VS_DEST_F_AVAILABLE) ||
527 (sysctl_ip_vs_expire_quiescent_template && 575 (sysctl_ip_vs_expire_quiescent_template &&
528 (atomic_read(&dest->weight) == 0))) { 576 (atomic_read(&dest->weight) == 0))) {
529 IP_VS_DBG(9, "check_template: dest not available for " 577 IP_VS_DBG_BUF(9, "check_template: dest not available for "
530 "protocol %s s:%u.%u.%u.%u:%d v:%u.%u.%u.%u:%d " 578 "protocol %s s:%s:%d v:%s:%d "
531 "-> d:%u.%u.%u.%u:%d\n", 579 "-> d:%s:%d\n",
532 ip_vs_proto_name(ct->protocol), 580 ip_vs_proto_name(ct->protocol),
533 NIPQUAD(ct->caddr), ntohs(ct->cport), 581 IP_VS_DBG_ADDR(ct->af, &ct->caddr),
534 NIPQUAD(ct->vaddr), ntohs(ct->vport), 582 ntohs(ct->cport),
535 NIPQUAD(ct->daddr), ntohs(ct->dport)); 583 IP_VS_DBG_ADDR(ct->af, &ct->vaddr),
584 ntohs(ct->vport),
585 IP_VS_DBG_ADDR(ct->af, &ct->daddr),
586 ntohs(ct->dport));
536 587
537 /* 588 /*
538 * Invalidate the connection template 589 * Invalidate the connection template
@@ -625,8 +676,9 @@ void ip_vs_conn_expire_now(struct ip_vs_conn *cp)
625 * Create a new connection entry and hash it into the ip_vs_conn_tab 676 * Create a new connection entry and hash it into the ip_vs_conn_tab
626 */ 677 */
627struct ip_vs_conn * 678struct ip_vs_conn *
628ip_vs_conn_new(int proto, __be32 caddr, __be16 cport, __be32 vaddr, __be16 vport, 679ip_vs_conn_new(int af, int proto, const union nf_inet_addr *caddr, __be16 cport,
629 __be32 daddr, __be16 dport, unsigned flags, 680 const union nf_inet_addr *vaddr, __be16 vport,
681 const union nf_inet_addr *daddr, __be16 dport, unsigned flags,
630 struct ip_vs_dest *dest) 682 struct ip_vs_dest *dest)
631{ 683{
632 struct ip_vs_conn *cp; 684 struct ip_vs_conn *cp;
@@ -640,12 +692,13 @@ ip_vs_conn_new(int proto, __be32 caddr, __be16 cport, __be32 vaddr, __be16 vport
640 692
641 INIT_LIST_HEAD(&cp->c_list); 693 INIT_LIST_HEAD(&cp->c_list);
642 setup_timer(&cp->timer, ip_vs_conn_expire, (unsigned long)cp); 694 setup_timer(&cp->timer, ip_vs_conn_expire, (unsigned long)cp);
695 cp->af = af;
643 cp->protocol = proto; 696 cp->protocol = proto;
644 cp->caddr = caddr; 697 ip_vs_addr_copy(af, &cp->caddr, caddr);
645 cp->cport = cport; 698 cp->cport = cport;
646 cp->vaddr = vaddr; 699 ip_vs_addr_copy(af, &cp->vaddr, vaddr);
647 cp->vport = vport; 700 cp->vport = vport;
648 cp->daddr = daddr; 701 ip_vs_addr_copy(af, &cp->daddr, daddr);
649 cp->dport = dport; 702 cp->dport = dport;
650 cp->flags = flags; 703 cp->flags = flags;
651 spin_lock_init(&cp->lock); 704 spin_lock_init(&cp->lock);
@@ -672,7 +725,12 @@ ip_vs_conn_new(int proto, __be32 caddr, __be16 cport, __be32 vaddr, __be16 vport
672 cp->timeout = 3*HZ; 725 cp->timeout = 3*HZ;
673 726
674 /* Bind its packet transmitter */ 727 /* Bind its packet transmitter */
675 ip_vs_bind_xmit(cp); 728#ifdef CONFIG_IP_VS_IPV6
729 if (af == AF_INET6)
730 ip_vs_bind_xmit_v6(cp);
731 else
732#endif
733 ip_vs_bind_xmit(cp);
676 734
677 if (unlikely(pp && atomic_read(&pp->appcnt))) 735 if (unlikely(pp && atomic_read(&pp->appcnt)))
678 ip_vs_bind_app(cp, pp); 736 ip_vs_bind_app(cp, pp);
@@ -760,12 +818,26 @@ static int ip_vs_conn_seq_show(struct seq_file *seq, void *v)
760 else { 818 else {
761 const struct ip_vs_conn *cp = v; 819 const struct ip_vs_conn *cp = v;
762 820
763 seq_printf(seq, 821#ifdef CONFIG_IP_VS_IPV6
764 "%-3s %08X %04X %08X %04X %08X %04X %-11s %7lu\n", 822 if (cp->af == AF_INET6)
823 seq_printf(seq,
824 "%-3s " NIP6_FMT " %04X " NIP6_FMT
825 " %04X " NIP6_FMT " %04X %-11s %7lu\n",
826 ip_vs_proto_name(cp->protocol),
827 NIP6(cp->caddr.in6), ntohs(cp->cport),
828 NIP6(cp->vaddr.in6), ntohs(cp->vport),
829 NIP6(cp->daddr.in6), ntohs(cp->dport),
830 ip_vs_state_name(cp->protocol, cp->state),
831 (cp->timer.expires-jiffies)/HZ);
832 else
833#endif
834 seq_printf(seq,
835 "%-3s %08X %04X %08X %04X"
836 " %08X %04X %-11s %7lu\n",
765 ip_vs_proto_name(cp->protocol), 837 ip_vs_proto_name(cp->protocol),
766 ntohl(cp->caddr), ntohs(cp->cport), 838 ntohl(cp->caddr.ip), ntohs(cp->cport),
767 ntohl(cp->vaddr), ntohs(cp->vport), 839 ntohl(cp->vaddr.ip), ntohs(cp->vport),
768 ntohl(cp->daddr), ntohs(cp->dport), 840 ntohl(cp->daddr.ip), ntohs(cp->dport),
769 ip_vs_state_name(cp->protocol, cp->state), 841 ip_vs_state_name(cp->protocol, cp->state),
770 (cp->timer.expires-jiffies)/HZ); 842 (cp->timer.expires-jiffies)/HZ);
771 } 843 }
@@ -809,12 +881,27 @@ static int ip_vs_conn_sync_seq_show(struct seq_file *seq, void *v)
809 else { 881 else {
810 const struct ip_vs_conn *cp = v; 882 const struct ip_vs_conn *cp = v;
811 883
812 seq_printf(seq, 884#ifdef CONFIG_IP_VS_IPV6
813 "%-3s %08X %04X %08X %04X %08X %04X %-11s %-6s %7lu\n", 885 if (cp->af == AF_INET6)
886 seq_printf(seq,
887 "%-3s " NIP6_FMT " %04X " NIP6_FMT
888 " %04X " NIP6_FMT " %04X %-11s %-6s %7lu\n",
889 ip_vs_proto_name(cp->protocol),
890 NIP6(cp->caddr.in6), ntohs(cp->cport),
891 NIP6(cp->vaddr.in6), ntohs(cp->vport),
892 NIP6(cp->daddr.in6), ntohs(cp->dport),
893 ip_vs_state_name(cp->protocol, cp->state),
894 ip_vs_origin_name(cp->flags),
895 (cp->timer.expires-jiffies)/HZ);
896 else
897#endif
898 seq_printf(seq,
899 "%-3s %08X %04X %08X %04X "
900 "%08X %04X %-11s %-6s %7lu\n",
814 ip_vs_proto_name(cp->protocol), 901 ip_vs_proto_name(cp->protocol),
815 ntohl(cp->caddr), ntohs(cp->cport), 902 ntohl(cp->caddr.ip), ntohs(cp->cport),
816 ntohl(cp->vaddr), ntohs(cp->vport), 903 ntohl(cp->vaddr.ip), ntohs(cp->vport),
817 ntohl(cp->daddr), ntohs(cp->dport), 904 ntohl(cp->daddr.ip), ntohs(cp->dport),
818 ip_vs_state_name(cp->protocol, cp->state), 905 ip_vs_state_name(cp->protocol, cp->state),
819 ip_vs_origin_name(cp->flags), 906 ip_vs_origin_name(cp->flags),
820 (cp->timer.expires-jiffies)/HZ); 907 (cp->timer.expires-jiffies)/HZ);
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index a7879eafc3b5..958abf3e5f8c 100644
--- a/net/ipv4/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -39,6 +39,11 @@
39#include <linux/netfilter.h> 39#include <linux/netfilter.h>
40#include <linux/netfilter_ipv4.h> 40#include <linux/netfilter_ipv4.h>
41 41
42#ifdef CONFIG_IP_VS_IPV6
43#include <net/ipv6.h>
44#include <linux/netfilter_ipv6.h>
45#endif
46
42#include <net/ip_vs.h> 47#include <net/ip_vs.h>
43 48
44 49
@@ -60,6 +65,7 @@ EXPORT_SYMBOL(ip_vs_get_debug_level);
60 65
61/* ID used in ICMP lookups */ 66/* ID used in ICMP lookups */
62#define icmp_id(icmph) (((icmph)->un).echo.id) 67#define icmp_id(icmph) (((icmph)->un).echo.id)
68#define icmpv6_id(icmph) (icmph->icmp6_dataun.u_echo.identifier)
63 69
64const char *ip_vs_proto_name(unsigned proto) 70const char *ip_vs_proto_name(unsigned proto)
65{ 71{
@@ -74,6 +80,10 @@ const char *ip_vs_proto_name(unsigned proto)
74 return "TCP"; 80 return "TCP";
75 case IPPROTO_ICMP: 81 case IPPROTO_ICMP:
76 return "ICMP"; 82 return "ICMP";
83#ifdef CONFIG_IP_VS_IPV6
84 case IPPROTO_ICMPV6:
85 return "ICMPv6";
86#endif
77 default: 87 default:
78 sprintf(buf, "IP_%d", proto); 88 sprintf(buf, "IP_%d", proto);
79 return buf; 89 return buf;
@@ -92,18 +102,18 @@ ip_vs_in_stats(struct ip_vs_conn *cp, struct sk_buff *skb)
92 struct ip_vs_dest *dest = cp->dest; 102 struct ip_vs_dest *dest = cp->dest;
93 if (dest && (dest->flags & IP_VS_DEST_F_AVAILABLE)) { 103 if (dest && (dest->flags & IP_VS_DEST_F_AVAILABLE)) {
94 spin_lock(&dest->stats.lock); 104 spin_lock(&dest->stats.lock);
95 dest->stats.inpkts++; 105 dest->stats.ustats.inpkts++;
96 dest->stats.inbytes += skb->len; 106 dest->stats.ustats.inbytes += skb->len;
97 spin_unlock(&dest->stats.lock); 107 spin_unlock(&dest->stats.lock);
98 108
99 spin_lock(&dest->svc->stats.lock); 109 spin_lock(&dest->svc->stats.lock);
100 dest->svc->stats.inpkts++; 110 dest->svc->stats.ustats.inpkts++;
101 dest->svc->stats.inbytes += skb->len; 111 dest->svc->stats.ustats.inbytes += skb->len;
102 spin_unlock(&dest->svc->stats.lock); 112 spin_unlock(&dest->svc->stats.lock);
103 113
104 spin_lock(&ip_vs_stats.lock); 114 spin_lock(&ip_vs_stats.lock);
105 ip_vs_stats.inpkts++; 115 ip_vs_stats.ustats.inpkts++;
106 ip_vs_stats.inbytes += skb->len; 116 ip_vs_stats.ustats.inbytes += skb->len;
107 spin_unlock(&ip_vs_stats.lock); 117 spin_unlock(&ip_vs_stats.lock);
108 } 118 }
109} 119}
@@ -115,18 +125,18 @@ ip_vs_out_stats(struct ip_vs_conn *cp, struct sk_buff *skb)
115 struct ip_vs_dest *dest = cp->dest; 125 struct ip_vs_dest *dest = cp->dest;
116 if (dest && (dest->flags & IP_VS_DEST_F_AVAILABLE)) { 126 if (dest && (dest->flags & IP_VS_DEST_F_AVAILABLE)) {
117 spin_lock(&dest->stats.lock); 127 spin_lock(&dest->stats.lock);
118 dest->stats.outpkts++; 128 dest->stats.ustats.outpkts++;
119 dest->stats.outbytes += skb->len; 129 dest->stats.ustats.outbytes += skb->len;
120 spin_unlock(&dest->stats.lock); 130 spin_unlock(&dest->stats.lock);
121 131
122 spin_lock(&dest->svc->stats.lock); 132 spin_lock(&dest->svc->stats.lock);
123 dest->svc->stats.outpkts++; 133 dest->svc->stats.ustats.outpkts++;
124 dest->svc->stats.outbytes += skb->len; 134 dest->svc->stats.ustats.outbytes += skb->len;
125 spin_unlock(&dest->svc->stats.lock); 135 spin_unlock(&dest->svc->stats.lock);
126 136
127 spin_lock(&ip_vs_stats.lock); 137 spin_lock(&ip_vs_stats.lock);
128 ip_vs_stats.outpkts++; 138 ip_vs_stats.ustats.outpkts++;
129 ip_vs_stats.outbytes += skb->len; 139 ip_vs_stats.ustats.outbytes += skb->len;
130 spin_unlock(&ip_vs_stats.lock); 140 spin_unlock(&ip_vs_stats.lock);
131 } 141 }
132} 142}
@@ -136,15 +146,15 @@ static inline void
136ip_vs_conn_stats(struct ip_vs_conn *cp, struct ip_vs_service *svc) 146ip_vs_conn_stats(struct ip_vs_conn *cp, struct ip_vs_service *svc)
137{ 147{
138 spin_lock(&cp->dest->stats.lock); 148 spin_lock(&cp->dest->stats.lock);
139 cp->dest->stats.conns++; 149 cp->dest->stats.ustats.conns++;
140 spin_unlock(&cp->dest->stats.lock); 150 spin_unlock(&cp->dest->stats.lock);
141 151
142 spin_lock(&svc->stats.lock); 152 spin_lock(&svc->stats.lock);
143 svc->stats.conns++; 153 svc->stats.ustats.conns++;
144 spin_unlock(&svc->stats.lock); 154 spin_unlock(&svc->stats.lock);
145 155
146 spin_lock(&ip_vs_stats.lock); 156 spin_lock(&ip_vs_stats.lock);
147 ip_vs_stats.conns++; 157 ip_vs_stats.ustats.conns++;
148 spin_unlock(&ip_vs_stats.lock); 158 spin_unlock(&ip_vs_stats.lock);
149} 159}
150 160
@@ -173,20 +183,28 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
173 __be16 ports[2]) 183 __be16 ports[2])
174{ 184{
175 struct ip_vs_conn *cp = NULL; 185 struct ip_vs_conn *cp = NULL;
176 struct iphdr *iph = ip_hdr(skb); 186 struct ip_vs_iphdr iph;
177 struct ip_vs_dest *dest; 187 struct ip_vs_dest *dest;
178 struct ip_vs_conn *ct; 188 struct ip_vs_conn *ct;
179 __be16 dport; /* destination port to forward */ 189 __be16 dport; /* destination port to forward */
180 __be32 snet; /* source network of the client, after masking */ 190 union nf_inet_addr snet; /* source network of the client,
191 after masking */
192
193 ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);
181 194
182 /* Mask saddr with the netmask to adjust template granularity */ 195 /* Mask saddr with the netmask to adjust template granularity */
183 snet = iph->saddr & svc->netmask; 196#ifdef CONFIG_IP_VS_IPV6
197 if (svc->af == AF_INET6)
198 ipv6_addr_prefix(&snet.in6, &iph.saddr.in6, svc->netmask);
199 else
200#endif
201 snet.ip = iph.saddr.ip & svc->netmask;
184 202
185 IP_VS_DBG(6, "p-schedule: src %u.%u.%u.%u:%u dest %u.%u.%u.%u:%u " 203 IP_VS_DBG_BUF(6, "p-schedule: src %s:%u dest %s:%u "
186 "mnet %u.%u.%u.%u\n", 204 "mnet %s\n",
187 NIPQUAD(iph->saddr), ntohs(ports[0]), 205 IP_VS_DBG_ADDR(svc->af, &iph.saddr), ntohs(ports[0]),
188 NIPQUAD(iph->daddr), ntohs(ports[1]), 206 IP_VS_DBG_ADDR(svc->af, &iph.daddr), ntohs(ports[1]),
189 NIPQUAD(snet)); 207 IP_VS_DBG_ADDR(svc->af, &snet));
190 208
191 /* 209 /*
192 * As far as we know, FTP is a very complicated network protocol, and 210 * As far as we know, FTP is a very complicated network protocol, and
@@ -204,11 +222,11 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
204 if (ports[1] == svc->port) { 222 if (ports[1] == svc->port) {
205 /* Check if a template already exists */ 223 /* Check if a template already exists */
206 if (svc->port != FTPPORT) 224 if (svc->port != FTPPORT)
207 ct = ip_vs_ct_in_get(iph->protocol, snet, 0, 225 ct = ip_vs_ct_in_get(svc->af, iph.protocol, &snet, 0,
208 iph->daddr, ports[1]); 226 &iph.daddr, ports[1]);
209 else 227 else
210 ct = ip_vs_ct_in_get(iph->protocol, snet, 0, 228 ct = ip_vs_ct_in_get(svc->af, iph.protocol, &snet, 0,
211 iph->daddr, 0); 229 &iph.daddr, 0);
212 230
213 if (!ct || !ip_vs_check_template(ct)) { 231 if (!ct || !ip_vs_check_template(ct)) {
214 /* 232 /*
@@ -228,18 +246,18 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
228 * for ftp service. 246 * for ftp service.
229 */ 247 */
230 if (svc->port != FTPPORT) 248 if (svc->port != FTPPORT)
231 ct = ip_vs_conn_new(iph->protocol, 249 ct = ip_vs_conn_new(svc->af, iph.protocol,
232 snet, 0, 250 &snet, 0,
233 iph->daddr, 251 &iph.daddr,
234 ports[1], 252 ports[1],
235 dest->addr, dest->port, 253 &dest->addr, dest->port,
236 IP_VS_CONN_F_TEMPLATE, 254 IP_VS_CONN_F_TEMPLATE,
237 dest); 255 dest);
238 else 256 else
239 ct = ip_vs_conn_new(iph->protocol, 257 ct = ip_vs_conn_new(svc->af, iph.protocol,
240 snet, 0, 258 &snet, 0,
241 iph->daddr, 0, 259 &iph.daddr, 0,
242 dest->addr, 0, 260 &dest->addr, 0,
243 IP_VS_CONN_F_TEMPLATE, 261 IP_VS_CONN_F_TEMPLATE,
244 dest); 262 dest);
245 if (ct == NULL) 263 if (ct == NULL)
@@ -258,12 +276,16 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
258 * fwmark template: <IPPROTO_IP,caddr,0,fwmark,0,daddr,0> 276 * fwmark template: <IPPROTO_IP,caddr,0,fwmark,0,daddr,0>
259 * port zero template: <protocol,caddr,0,vaddr,0,daddr,0> 277 * port zero template: <protocol,caddr,0,vaddr,0,daddr,0>
260 */ 278 */
261 if (svc->fwmark) 279 if (svc->fwmark) {
262 ct = ip_vs_ct_in_get(IPPROTO_IP, snet, 0, 280 union nf_inet_addr fwmark = {
263 htonl(svc->fwmark), 0); 281 .all = { 0, 0, 0, htonl(svc->fwmark) }
264 else 282 };
265 ct = ip_vs_ct_in_get(iph->protocol, snet, 0, 283
266 iph->daddr, 0); 284 ct = ip_vs_ct_in_get(svc->af, IPPROTO_IP, &snet, 0,
285 &fwmark, 0);
286 } else
287 ct = ip_vs_ct_in_get(svc->af, iph.protocol, &snet, 0,
288 &iph.daddr, 0);
267 289
268 if (!ct || !ip_vs_check_template(ct)) { 290 if (!ct || !ip_vs_check_template(ct)) {
269 /* 291 /*
@@ -282,18 +304,22 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
282 /* 304 /*
283 * Create a template according to the service 305 * Create a template according to the service
284 */ 306 */
285 if (svc->fwmark) 307 if (svc->fwmark) {
286 ct = ip_vs_conn_new(IPPROTO_IP, 308 union nf_inet_addr fwmark = {
287 snet, 0, 309 .all = { 0, 0, 0, htonl(svc->fwmark) }
288 htonl(svc->fwmark), 0, 310 };
289 dest->addr, 0, 311
312 ct = ip_vs_conn_new(svc->af, IPPROTO_IP,
313 &snet, 0,
314 &fwmark, 0,
315 &dest->addr, 0,
290 IP_VS_CONN_F_TEMPLATE, 316 IP_VS_CONN_F_TEMPLATE,
291 dest); 317 dest);
292 else 318 } else
293 ct = ip_vs_conn_new(iph->protocol, 319 ct = ip_vs_conn_new(svc->af, iph.protocol,
294 snet, 0, 320 &snet, 0,
295 iph->daddr, 0, 321 &iph.daddr, 0,
296 dest->addr, 0, 322 &dest->addr, 0,
297 IP_VS_CONN_F_TEMPLATE, 323 IP_VS_CONN_F_TEMPLATE,
298 dest); 324 dest);
299 if (ct == NULL) 325 if (ct == NULL)
@@ -310,10 +336,10 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
310 /* 336 /*
311 * Create a new connection according to the template 337 * Create a new connection according to the template
312 */ 338 */
313 cp = ip_vs_conn_new(iph->protocol, 339 cp = ip_vs_conn_new(svc->af, iph.protocol,
314 iph->saddr, ports[0], 340 &iph.saddr, ports[0],
315 iph->daddr, ports[1], 341 &iph.daddr, ports[1],
316 dest->addr, dport, 342 &dest->addr, dport,
317 0, 343 0,
318 dest); 344 dest);
319 if (cp == NULL) { 345 if (cp == NULL) {
@@ -342,12 +368,12 @@ struct ip_vs_conn *
342ip_vs_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) 368ip_vs_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
343{ 369{
344 struct ip_vs_conn *cp = NULL; 370 struct ip_vs_conn *cp = NULL;
345 struct iphdr *iph = ip_hdr(skb); 371 struct ip_vs_iphdr iph;
346 struct ip_vs_dest *dest; 372 struct ip_vs_dest *dest;
347 __be16 _ports[2], *pptr; 373 __be16 _ports[2], *pptr;
348 374
349 pptr = skb_header_pointer(skb, iph->ihl*4, 375 ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);
350 sizeof(_ports), _ports); 376 pptr = skb_header_pointer(skb, iph.len, sizeof(_ports), _ports);
351 if (pptr == NULL) 377 if (pptr == NULL)
352 return NULL; 378 return NULL;
353 379
@@ -377,22 +403,22 @@ ip_vs_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
377 /* 403 /*
378 * Create a connection entry. 404 * Create a connection entry.
379 */ 405 */
380 cp = ip_vs_conn_new(iph->protocol, 406 cp = ip_vs_conn_new(svc->af, iph.protocol,
381 iph->saddr, pptr[0], 407 &iph.saddr, pptr[0],
382 iph->daddr, pptr[1], 408 &iph.daddr, pptr[1],
383 dest->addr, dest->port?dest->port:pptr[1], 409 &dest->addr, dest->port ? dest->port : pptr[1],
384 0, 410 0,
385 dest); 411 dest);
386 if (cp == NULL) 412 if (cp == NULL)
387 return NULL; 413 return NULL;
388 414
389 IP_VS_DBG(6, "Schedule fwd:%c c:%u.%u.%u.%u:%u v:%u.%u.%u.%u:%u " 415 IP_VS_DBG_BUF(6, "Schedule fwd:%c c:%s:%u v:%s:%u "
390 "d:%u.%u.%u.%u:%u conn->flags:%X conn->refcnt:%d\n", 416 "d:%s:%u conn->flags:%X conn->refcnt:%d\n",
391 ip_vs_fwd_tag(cp), 417 ip_vs_fwd_tag(cp),
392 NIPQUAD(cp->caddr), ntohs(cp->cport), 418 IP_VS_DBG_ADDR(svc->af, &cp->caddr), ntohs(cp->cport),
393 NIPQUAD(cp->vaddr), ntohs(cp->vport), 419 IP_VS_DBG_ADDR(svc->af, &cp->vaddr), ntohs(cp->vport),
394 NIPQUAD(cp->daddr), ntohs(cp->dport), 420 IP_VS_DBG_ADDR(svc->af, &cp->daddr), ntohs(cp->dport),
395 cp->flags, atomic_read(&cp->refcnt)); 421 cp->flags, atomic_read(&cp->refcnt));
396 422
397 ip_vs_conn_stats(cp, svc); 423 ip_vs_conn_stats(cp, svc);
398 return cp; 424 return cp;
@@ -408,31 +434,39 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
408 struct ip_vs_protocol *pp) 434 struct ip_vs_protocol *pp)
409{ 435{
410 __be16 _ports[2], *pptr; 436 __be16 _ports[2], *pptr;
411 struct iphdr *iph = ip_hdr(skb); 437 struct ip_vs_iphdr iph;
438 int unicast;
439 ip_vs_fill_iphdr(svc->af, skb_network_header(skb), &iph);
412 440
413 pptr = skb_header_pointer(skb, iph->ihl*4, 441 pptr = skb_header_pointer(skb, iph.len, sizeof(_ports), _ports);
414 sizeof(_ports), _ports);
415 if (pptr == NULL) { 442 if (pptr == NULL) {
416 ip_vs_service_put(svc); 443 ip_vs_service_put(svc);
417 return NF_DROP; 444 return NF_DROP;
418 } 445 }
419 446
447#ifdef CONFIG_IP_VS_IPV6
448 if (svc->af == AF_INET6)
449 unicast = ipv6_addr_type(&iph.daddr.in6) & IPV6_ADDR_UNICAST;
450 else
451#endif
452 unicast = (inet_addr_type(&init_net, iph.daddr.ip) == RTN_UNICAST);
453
420 /* if it is fwmark-based service, the cache_bypass sysctl is up 454 /* if it is fwmark-based service, the cache_bypass sysctl is up
421 and the destination is RTN_UNICAST (and not local), then create 455 and the destination is a non-local unicast, then create
422 a cache_bypass connection entry */ 456 a cache_bypass connection entry */
423 if (sysctl_ip_vs_cache_bypass && svc->fwmark 457 if (sysctl_ip_vs_cache_bypass && svc->fwmark && unicast) {
424 && (inet_addr_type(&init_net, iph->daddr) == RTN_UNICAST)) {
425 int ret, cs; 458 int ret, cs;
426 struct ip_vs_conn *cp; 459 struct ip_vs_conn *cp;
460 union nf_inet_addr daddr = { .all = { 0, 0, 0, 0 } };
427 461
428 ip_vs_service_put(svc); 462 ip_vs_service_put(svc);
429 463
430 /* create a new connection entry */ 464 /* create a new connection entry */
431 IP_VS_DBG(6, "ip_vs_leave: create a cache_bypass entry\n"); 465 IP_VS_DBG(6, "ip_vs_leave: create a cache_bypass entry\n");
432 cp = ip_vs_conn_new(iph->protocol, 466 cp = ip_vs_conn_new(svc->af, iph.protocol,
433 iph->saddr, pptr[0], 467 &iph.saddr, pptr[0],
434 iph->daddr, pptr[1], 468 &iph.daddr, pptr[1],
435 0, 0, 469 &daddr, 0,
436 IP_VS_CONN_F_BYPASS, 470 IP_VS_CONN_F_BYPASS,
437 NULL); 471 NULL);
438 if (cp == NULL) 472 if (cp == NULL)
@@ -473,7 +507,14 @@ int ip_vs_leave(struct ip_vs_service *svc, struct sk_buff *skb,
473 * created, the TCP RST packet cannot be sent, instead that 507 * created, the TCP RST packet cannot be sent, instead that
474 * ICMP_PORT_UNREACH is sent here no matter it is TCP/UDP. --WZ 508 * ICMP_PORT_UNREACH is sent here no matter it is TCP/UDP. --WZ
475 */ 509 */
476 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); 510#ifdef CONFIG_IP_VS_IPV6
511 if (svc->af == AF_INET6)
512 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0,
513 skb->dev);
514 else
515#endif
516 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
517
477 return NF_DROP; 518 return NF_DROP;
478} 519}
479 520
@@ -512,6 +553,14 @@ static inline int ip_vs_gather_frags(struct sk_buff *skb, u_int32_t user)
512 return err; 553 return err;
513} 554}
514 555
556#ifdef CONFIG_IP_VS_IPV6
557static inline int ip_vs_gather_frags_v6(struct sk_buff *skb, u_int32_t user)
558{
559 /* TODO IPv6: Find out what to do here for IPv6 */
560 return 0;
561}
562#endif
563
515/* 564/*
516 * Packet has been made sufficiently writable in caller 565 * Packet has been made sufficiently writable in caller
517 * - inout: 1=in->out, 0=out->in 566 * - inout: 1=in->out, 0=out->in
@@ -526,14 +575,14 @@ void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp,
526 struct iphdr *ciph = (struct iphdr *)(icmph + 1); 575 struct iphdr *ciph = (struct iphdr *)(icmph + 1);
527 576
528 if (inout) { 577 if (inout) {
529 iph->saddr = cp->vaddr; 578 iph->saddr = cp->vaddr.ip;
530 ip_send_check(iph); 579 ip_send_check(iph);
531 ciph->daddr = cp->vaddr; 580 ciph->daddr = cp->vaddr.ip;
532 ip_send_check(ciph); 581 ip_send_check(ciph);
533 } else { 582 } else {
534 iph->daddr = cp->daddr; 583 iph->daddr = cp->daddr.ip;
535 ip_send_check(iph); 584 ip_send_check(iph);
536 ciph->saddr = cp->daddr; 585 ciph->saddr = cp->daddr.ip;
537 ip_send_check(ciph); 586 ip_send_check(ciph);
538 } 587 }
539 588
@@ -560,21 +609,112 @@ void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp,
560 "Forwarding altered incoming ICMP"); 609 "Forwarding altered incoming ICMP");
561} 610}
562 611
612#ifdef CONFIG_IP_VS_IPV6
613void ip_vs_nat_icmp_v6(struct sk_buff *skb, struct ip_vs_protocol *pp,
614 struct ip_vs_conn *cp, int inout)
615{
616 struct ipv6hdr *iph = ipv6_hdr(skb);
617 unsigned int icmp_offset = sizeof(struct ipv6hdr);
618 struct icmp6hdr *icmph = (struct icmp6hdr *)(skb_network_header(skb) +
619 icmp_offset);
620 struct ipv6hdr *ciph = (struct ipv6hdr *)(icmph + 1);
621
622 if (inout) {
623 iph->saddr = cp->vaddr.in6;
624 ciph->daddr = cp->vaddr.in6;
625 } else {
626 iph->daddr = cp->daddr.in6;
627 ciph->saddr = cp->daddr.in6;
628 }
629
630 /* the TCP/UDP port */
631 if (IPPROTO_TCP == ciph->nexthdr || IPPROTO_UDP == ciph->nexthdr) {
632 __be16 *ports = (void *)ciph + sizeof(struct ipv6hdr);
633
634 if (inout)
635 ports[1] = cp->vport;
636 else
637 ports[0] = cp->dport;
638 }
639
640 /* And finally the ICMP checksum */
641 icmph->icmp6_cksum = 0;
642 /* TODO IPv6: is this correct for ICMPv6? */
643 ip_vs_checksum_complete(skb, icmp_offset);
644 skb->ip_summed = CHECKSUM_UNNECESSARY;
645
646 if (inout)
647 IP_VS_DBG_PKT(11, pp, skb, (void *)ciph - (void *)iph,
648 "Forwarding altered outgoing ICMPv6");
649 else
650 IP_VS_DBG_PKT(11, pp, skb, (void *)ciph - (void *)iph,
651 "Forwarding altered incoming ICMPv6");
652}
653#endif
654
655/* Handle relevant response ICMP messages - forward to the right
656 * destination host. Used for NAT and local client.
657 */
658static int handle_response_icmp(int af, struct sk_buff *skb,
659 union nf_inet_addr *snet,
660 __u8 protocol, struct ip_vs_conn *cp,
661 struct ip_vs_protocol *pp,
662 unsigned int offset, unsigned int ihl)
663{
664 unsigned int verdict = NF_DROP;
665
666 if (IP_VS_FWD_METHOD(cp) != 0) {
667 IP_VS_ERR("shouldn't reach here, because the box is on the "
668 "half connection in the tun/dr module.\n");
669 }
670
671 /* Ensure the checksum is correct */
672 if (!skb_csum_unnecessary(skb) && ip_vs_checksum_complete(skb, ihl)) {
673 /* Failed checksum! */
674 IP_VS_DBG_BUF(1, "Forward ICMP: failed checksum from %s!\n",
675 IP_VS_DBG_ADDR(af, snet));
676 goto out;
677 }
678
679 if (IPPROTO_TCP == protocol || IPPROTO_UDP == protocol)
680 offset += 2 * sizeof(__u16);
681 if (!skb_make_writable(skb, offset))
682 goto out;
683
684#ifdef CONFIG_IP_VS_IPV6
685 if (af == AF_INET6)
686 ip_vs_nat_icmp_v6(skb, pp, cp, 1);
687 else
688#endif
689 ip_vs_nat_icmp(skb, pp, cp, 1);
690
691 /* do the statistics and put it back */
692 ip_vs_out_stats(cp, skb);
693
694 skb->ipvs_property = 1;
695 verdict = NF_ACCEPT;
696
697out:
698 __ip_vs_conn_put(cp);
699
700 return verdict;
701}
702
563/* 703/*
564 * Handle ICMP messages in the inside-to-outside direction (outgoing). 704 * Handle ICMP messages in the inside-to-outside direction (outgoing).
565 * Find any that might be relevant, check against existing connections, 705 * Find any that might be relevant, check against existing connections.
566 * forward to the right destination host if relevant.
567 * Currently handles error types - unreachable, quench, ttl exceeded. 706 * Currently handles error types - unreachable, quench, ttl exceeded.
568 * (Only used in VS/NAT)
569 */ 707 */
570static int ip_vs_out_icmp(struct sk_buff *skb, int *related) 708static int ip_vs_out_icmp(struct sk_buff *skb, int *related)
571{ 709{
572 struct iphdr *iph; 710 struct iphdr *iph;
573 struct icmphdr _icmph, *ic; 711 struct icmphdr _icmph, *ic;
574 struct iphdr _ciph, *cih; /* The ip header contained within the ICMP */ 712 struct iphdr _ciph, *cih; /* The ip header contained within the ICMP */
713 struct ip_vs_iphdr ciph;
575 struct ip_vs_conn *cp; 714 struct ip_vs_conn *cp;
576 struct ip_vs_protocol *pp; 715 struct ip_vs_protocol *pp;
577 unsigned int offset, ihl, verdict; 716 unsigned int offset, ihl;
717 union nf_inet_addr snet;
578 718
579 *related = 1; 719 *related = 1;
580 720
@@ -627,102 +767,231 @@ static int ip_vs_out_icmp(struct sk_buff *skb, int *related)
627 767
628 offset += cih->ihl * 4; 768 offset += cih->ihl * 4;
629 769
770 ip_vs_fill_iphdr(AF_INET, cih, &ciph);
630 /* The embedded headers contain source and dest in reverse order */ 771 /* The embedded headers contain source and dest in reverse order */
631 cp = pp->conn_out_get(skb, pp, cih, offset, 1); 772 cp = pp->conn_out_get(AF_INET, skb, pp, &ciph, offset, 1);
632 if (!cp) 773 if (!cp)
633 return NF_ACCEPT; 774 return NF_ACCEPT;
634 775
635 verdict = NF_DROP; 776 snet.ip = iph->saddr;
777 return handle_response_icmp(AF_INET, skb, &snet, cih->protocol, cp,
778 pp, offset, ihl);
779}
636 780
637 if (IP_VS_FWD_METHOD(cp) != 0) { 781#ifdef CONFIG_IP_VS_IPV6
638 IP_VS_ERR("shouldn't reach here, because the box is on the " 782static int ip_vs_out_icmp_v6(struct sk_buff *skb, int *related)
639 "half connection in the tun/dr module.\n"); 783{
784 struct ipv6hdr *iph;
785 struct icmp6hdr _icmph, *ic;
786 struct ipv6hdr _ciph, *cih; /* The ip header contained
787 within the ICMP */
788 struct ip_vs_iphdr ciph;
789 struct ip_vs_conn *cp;
790 struct ip_vs_protocol *pp;
791 unsigned int offset;
792 union nf_inet_addr snet;
793
794 *related = 1;
795
796 /* reassemble IP fragments */
797 if (ipv6_hdr(skb)->nexthdr == IPPROTO_FRAGMENT) {
798 if (ip_vs_gather_frags_v6(skb, IP_DEFRAG_VS_OUT))
799 return NF_STOLEN;
640 } 800 }
641 801
642 /* Ensure the checksum is correct */ 802 iph = ipv6_hdr(skb);
643 if (!skb_csum_unnecessary(skb) && ip_vs_checksum_complete(skb, ihl)) { 803 offset = sizeof(struct ipv6hdr);
644 /* Failed checksum! */ 804 ic = skb_header_pointer(skb, offset, sizeof(_icmph), &_icmph);
645 IP_VS_DBG(1, "Forward ICMP: failed checksum from %d.%d.%d.%d!\n", 805 if (ic == NULL)
646 NIPQUAD(iph->saddr)); 806 return NF_DROP;
647 goto out; 807
808 IP_VS_DBG(12, "Outgoing ICMPv6 (%d,%d) " NIP6_FMT "->" NIP6_FMT "\n",
809 ic->icmp6_type, ntohs(icmpv6_id(ic)),
810 NIP6(iph->saddr), NIP6(iph->daddr));
811
812 /*
813 * Work through seeing if this is for us.
814 * These checks are supposed to be in an order that means easy
815 * things are checked first to speed up processing.... however
816 * this means that some packets will manage to get a long way
817 * down this stack and then be rejected, but that's life.
818 */
819 if ((ic->icmp6_type != ICMPV6_DEST_UNREACH) &&
820 (ic->icmp6_type != ICMPV6_PKT_TOOBIG) &&
821 (ic->icmp6_type != ICMPV6_TIME_EXCEED)) {
822 *related = 0;
823 return NF_ACCEPT;
648 } 824 }
649 825
650 if (IPPROTO_TCP == cih->protocol || IPPROTO_UDP == cih->protocol) 826 /* Now find the contained IP header */
651 offset += 2 * sizeof(__u16); 827 offset += sizeof(_icmph);
652 if (!skb_make_writable(skb, offset)) 828 cih = skb_header_pointer(skb, offset, sizeof(_ciph), &_ciph);
653 goto out; 829 if (cih == NULL)
830 return NF_ACCEPT; /* The packet looks wrong, ignore */
654 831
655 ip_vs_nat_icmp(skb, pp, cp, 1); 832 pp = ip_vs_proto_get(cih->nexthdr);
833 if (!pp)
834 return NF_ACCEPT;
656 835
657 /* do the statistics and put it back */ 836 /* Is the embedded protocol header present? */
658 ip_vs_out_stats(cp, skb); 837 /* TODO: we don't support fragmentation at the moment anyways */
838 if (unlikely(cih->nexthdr == IPPROTO_FRAGMENT && pp->dont_defrag))
839 return NF_ACCEPT;
659 840
660 skb->ipvs_property = 1; 841 IP_VS_DBG_PKT(11, pp, skb, offset, "Checking outgoing ICMPv6 for");
661 verdict = NF_ACCEPT;
662 842
663 out: 843 offset += sizeof(struct ipv6hdr);
664 __ip_vs_conn_put(cp);
665 844
666 return verdict; 845 ip_vs_fill_iphdr(AF_INET6, cih, &ciph);
846 /* The embedded headers contain source and dest in reverse order */
847 cp = pp->conn_out_get(AF_INET6, skb, pp, &ciph, offset, 1);
848 if (!cp)
849 return NF_ACCEPT;
850
851 ipv6_addr_copy(&snet.in6, &iph->saddr);
852 return handle_response_icmp(AF_INET6, skb, &snet, cih->nexthdr, cp,
853 pp, offset, sizeof(struct ipv6hdr));
667} 854}
855#endif
668 856
669static inline int is_tcp_reset(const struct sk_buff *skb) 857static inline int is_tcp_reset(const struct sk_buff *skb, int nh_len)
670{ 858{
671 struct tcphdr _tcph, *th; 859 struct tcphdr _tcph, *th;
672 860
673 th = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_tcph), &_tcph); 861 th = skb_header_pointer(skb, nh_len, sizeof(_tcph), &_tcph);
674 if (th == NULL) 862 if (th == NULL)
675 return 0; 863 return 0;
676 return th->rst; 864 return th->rst;
677} 865}
678 866
867/* Handle response packets: rewrite addresses and send away...
868 * Used for NAT and local client.
869 */
870static unsigned int
871handle_response(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
872 struct ip_vs_conn *cp, int ihl)
873{
874 IP_VS_DBG_PKT(11, pp, skb, 0, "Outgoing packet");
875
876 if (!skb_make_writable(skb, ihl))
877 goto drop;
878
879 /* mangle the packet */
880 if (pp->snat_handler && !pp->snat_handler(skb, pp, cp))
881 goto drop;
882
883#ifdef CONFIG_IP_VS_IPV6
884 if (af == AF_INET6)
885 ipv6_hdr(skb)->saddr = cp->vaddr.in6;
886 else
887#endif
888 {
889 ip_hdr(skb)->saddr = cp->vaddr.ip;
890 ip_send_check(ip_hdr(skb));
891 }
892
893 /* For policy routing, packets originating from this
894 * machine itself may be routed differently to packets
895 * passing through. We want this packet to be routed as
896 * if it came from this machine itself. So re-compute
897 * the routing information.
898 */
899#ifdef CONFIG_IP_VS_IPV6
900 if (af == AF_INET6) {
901 if (ip6_route_me_harder(skb) != 0)
902 goto drop;
903 } else
904#endif
905 if (ip_route_me_harder(skb, RTN_LOCAL) != 0)
906 goto drop;
907
908 IP_VS_DBG_PKT(10, pp, skb, 0, "After SNAT");
909
910 ip_vs_out_stats(cp, skb);
911 ip_vs_set_state(cp, IP_VS_DIR_OUTPUT, skb, pp);
912 ip_vs_conn_put(cp);
913
914 skb->ipvs_property = 1;
915
916 LeaveFunction(11);
917 return NF_ACCEPT;
918
919drop:
920 ip_vs_conn_put(cp);
921 kfree_skb(skb);
922 return NF_STOLEN;
923}
924
679/* 925/*
680 * It is hooked at the NF_INET_FORWARD chain, used only for VS/NAT. 926 * It is hooked at the NF_INET_FORWARD chain, used only for VS/NAT.
681 * Check if outgoing packet belongs to the established ip_vs_conn, 927 * Check if outgoing packet belongs to the established ip_vs_conn.
682 * rewrite addresses of the packet and send it on its way...
683 */ 928 */
684static unsigned int 929static unsigned int
685ip_vs_out(unsigned int hooknum, struct sk_buff *skb, 930ip_vs_out(unsigned int hooknum, struct sk_buff *skb,
686 const struct net_device *in, const struct net_device *out, 931 const struct net_device *in, const struct net_device *out,
687 int (*okfn)(struct sk_buff *)) 932 int (*okfn)(struct sk_buff *))
688{ 933{
689 struct iphdr *iph; 934 struct ip_vs_iphdr iph;
690 struct ip_vs_protocol *pp; 935 struct ip_vs_protocol *pp;
691 struct ip_vs_conn *cp; 936 struct ip_vs_conn *cp;
692 int ihl; 937 int af;
693 938
694 EnterFunction(11); 939 EnterFunction(11);
695 940
941 af = (skb->protocol == htons(ETH_P_IP)) ? AF_INET : AF_INET6;
942
696 if (skb->ipvs_property) 943 if (skb->ipvs_property)
697 return NF_ACCEPT; 944 return NF_ACCEPT;
698 945
699 iph = ip_hdr(skb); 946 ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
700 if (unlikely(iph->protocol == IPPROTO_ICMP)) { 947#ifdef CONFIG_IP_VS_IPV6
701 int related, verdict = ip_vs_out_icmp(skb, &related); 948 if (af == AF_INET6) {
949 if (unlikely(iph.protocol == IPPROTO_ICMPV6)) {
950 int related, verdict = ip_vs_out_icmp_v6(skb, &related);
702 951
703 if (related) 952 if (related)
704 return verdict; 953 return verdict;
705 iph = ip_hdr(skb); 954 ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
706 } 955 }
956 } else
957#endif
958 if (unlikely(iph.protocol == IPPROTO_ICMP)) {
959 int related, verdict = ip_vs_out_icmp(skb, &related);
707 960
708 pp = ip_vs_proto_get(iph->protocol); 961 if (related)
962 return verdict;
963 ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
964 }
965
966 pp = ip_vs_proto_get(iph.protocol);
709 if (unlikely(!pp)) 967 if (unlikely(!pp))
710 return NF_ACCEPT; 968 return NF_ACCEPT;
711 969
712 /* reassemble IP fragments */ 970 /* reassemble IP fragments */
713 if (unlikely(iph->frag_off & htons(IP_MF|IP_OFFSET) && 971#ifdef CONFIG_IP_VS_IPV6
714 !pp->dont_defrag)) { 972 if (af == AF_INET6) {
715 if (ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT)) 973 if (unlikely(iph.protocol == IPPROTO_ICMPV6)) {
716 return NF_STOLEN; 974 int related, verdict = ip_vs_out_icmp_v6(skb, &related);
717 iph = ip_hdr(skb); 975
718 } 976 if (related)
977 return verdict;
719 978
720 ihl = iph->ihl << 2; 979 ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
980 }
981 } else
982#endif
983 if (unlikely(ip_hdr(skb)->frag_off & htons(IP_MF|IP_OFFSET) &&
984 !pp->dont_defrag)) {
985 if (ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT))
986 return NF_STOLEN;
987
988 ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
989 }
721 990
722 /* 991 /*
723 * Check if the packet belongs to an existing entry 992 * Check if the packet belongs to an existing entry
724 */ 993 */
725 cp = pp->conn_out_get(skb, pp, iph, ihl, 0); 994 cp = pp->conn_out_get(af, skb, pp, &iph, iph.len, 0);
726 995
727 if (unlikely(!cp)) { 996 if (unlikely(!cp)) {
728 if (sysctl_ip_vs_nat_icmp_send && 997 if (sysctl_ip_vs_nat_icmp_send &&
@@ -730,21 +999,31 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb,
730 pp->protocol == IPPROTO_UDP)) { 999 pp->protocol == IPPROTO_UDP)) {
731 __be16 _ports[2], *pptr; 1000 __be16 _ports[2], *pptr;
732 1001
733 pptr = skb_header_pointer(skb, ihl, 1002 pptr = skb_header_pointer(skb, iph.len,
734 sizeof(_ports), _ports); 1003 sizeof(_ports), _ports);
735 if (pptr == NULL) 1004 if (pptr == NULL)
736 return NF_ACCEPT; /* Not for me */ 1005 return NF_ACCEPT; /* Not for me */
737 if (ip_vs_lookup_real_service(iph->protocol, 1006 if (ip_vs_lookup_real_service(af, iph.protocol,
738 iph->saddr, pptr[0])) { 1007 &iph.saddr,
1008 pptr[0])) {
739 /* 1009 /*
740 * Notify the real server: there is no 1010 * Notify the real server: there is no
741 * existing entry if it is not RST 1011 * existing entry if it is not RST
742 * packet or not TCP packet. 1012 * packet or not TCP packet.
743 */ 1013 */
744 if (iph->protocol != IPPROTO_TCP 1014 if (iph.protocol != IPPROTO_TCP
745 || !is_tcp_reset(skb)) { 1015 || !is_tcp_reset(skb, iph.len)) {
746 icmp_send(skb,ICMP_DEST_UNREACH, 1016#ifdef CONFIG_IP_VS_IPV6
747 ICMP_PORT_UNREACH, 0); 1017 if (af == AF_INET6)
1018 icmpv6_send(skb,
1019 ICMPV6_DEST_UNREACH,
1020 ICMPV6_PORT_UNREACH,
1021 0, skb->dev);
1022 else
1023#endif
1024 icmp_send(skb,
1025 ICMP_DEST_UNREACH,
1026 ICMP_PORT_UNREACH, 0);
748 return NF_DROP; 1027 return NF_DROP;
749 } 1028 }
750 } 1029 }
@@ -754,41 +1033,7 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb,
754 return NF_ACCEPT; 1033 return NF_ACCEPT;
755 } 1034 }
756 1035
757 IP_VS_DBG_PKT(11, pp, skb, 0, "Outgoing packet"); 1036 return handle_response(af, skb, pp, cp, iph.len);
758
759 if (!skb_make_writable(skb, ihl))
760 goto drop;
761
762 /* mangle the packet */
763 if (pp->snat_handler && !pp->snat_handler(skb, pp, cp))
764 goto drop;
765 ip_hdr(skb)->saddr = cp->vaddr;
766 ip_send_check(ip_hdr(skb));
767
768 /* For policy routing, packets originating from this
769 * machine itself may be routed differently to packets
770 * passing through. We want this packet to be routed as
771 * if it came from this machine itself. So re-compute
772 * the routing information.
773 */
774 if (ip_route_me_harder(skb, RTN_LOCAL) != 0)
775 goto drop;
776
777 IP_VS_DBG_PKT(10, pp, skb, 0, "After SNAT");
778
779 ip_vs_out_stats(cp, skb);
780 ip_vs_set_state(cp, IP_VS_DIR_OUTPUT, skb, pp);
781 ip_vs_conn_put(cp);
782
783 skb->ipvs_property = 1;
784
785 LeaveFunction(11);
786 return NF_ACCEPT;
787
788 drop:
789 ip_vs_conn_put(cp);
790 kfree_skb(skb);
791 return NF_STOLEN;
792} 1037}
793 1038
794 1039
@@ -804,9 +1049,11 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
804 struct iphdr *iph; 1049 struct iphdr *iph;
805 struct icmphdr _icmph, *ic; 1050 struct icmphdr _icmph, *ic;
806 struct iphdr _ciph, *cih; /* The ip header contained within the ICMP */ 1051 struct iphdr _ciph, *cih; /* The ip header contained within the ICMP */
1052 struct ip_vs_iphdr ciph;
807 struct ip_vs_conn *cp; 1053 struct ip_vs_conn *cp;
808 struct ip_vs_protocol *pp; 1054 struct ip_vs_protocol *pp;
809 unsigned int offset, ihl, verdict; 1055 unsigned int offset, ihl, verdict;
1056 union nf_inet_addr snet;
810 1057
811 *related = 1; 1058 *related = 1;
812 1059
@@ -860,10 +1107,20 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
860 1107
861 offset += cih->ihl * 4; 1108 offset += cih->ihl * 4;
862 1109
1110 ip_vs_fill_iphdr(AF_INET, cih, &ciph);
863 /* The embedded headers contain source and dest in reverse order */ 1111 /* The embedded headers contain source and dest in reverse order */
864 cp = pp->conn_in_get(skb, pp, cih, offset, 1); 1112 cp = pp->conn_in_get(AF_INET, skb, pp, &ciph, offset, 1);
865 if (!cp) 1113 if (!cp) {
1114 /* The packet could also belong to a local client */
1115 cp = pp->conn_out_get(AF_INET, skb, pp, &ciph, offset, 1);
1116 if (cp) {
1117 snet.ip = iph->saddr;
1118 return handle_response_icmp(AF_INET, skb, &snet,
1119 cih->protocol, cp, pp,
1120 offset, ihl);
1121 }
866 return NF_ACCEPT; 1122 return NF_ACCEPT;
1123 }
867 1124
868 verdict = NF_DROP; 1125 verdict = NF_DROP;
869 1126
@@ -888,6 +1145,105 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
888 return verdict; 1145 return verdict;
889} 1146}
890 1147
1148#ifdef CONFIG_IP_VS_IPV6
1149static int
1150ip_vs_in_icmp_v6(struct sk_buff *skb, int *related, unsigned int hooknum)
1151{
1152 struct ipv6hdr *iph;
1153 struct icmp6hdr _icmph, *ic;
1154 struct ipv6hdr _ciph, *cih; /* The ip header contained
1155 within the ICMP */
1156 struct ip_vs_iphdr ciph;
1157 struct ip_vs_conn *cp;
1158 struct ip_vs_protocol *pp;
1159 unsigned int offset, verdict;
1160 union nf_inet_addr snet;
1161
1162 *related = 1;
1163
1164 /* reassemble IP fragments */
1165 if (ipv6_hdr(skb)->nexthdr == IPPROTO_FRAGMENT) {
1166 if (ip_vs_gather_frags_v6(skb, hooknum == NF_INET_LOCAL_IN ?
1167 IP_DEFRAG_VS_IN :
1168 IP_DEFRAG_VS_FWD))
1169 return NF_STOLEN;
1170 }
1171
1172 iph = ipv6_hdr(skb);
1173 offset = sizeof(struct ipv6hdr);
1174 ic = skb_header_pointer(skb, offset, sizeof(_icmph), &_icmph);
1175 if (ic == NULL)
1176 return NF_DROP;
1177
1178 IP_VS_DBG(12, "Incoming ICMPv6 (%d,%d) " NIP6_FMT "->" NIP6_FMT "\n",
1179 ic->icmp6_type, ntohs(icmpv6_id(ic)),
1180 NIP6(iph->saddr), NIP6(iph->daddr));
1181
1182 /*
1183 * Work through seeing if this is for us.
1184 * These checks are supposed to be in an order that means easy
1185 * things are checked first to speed up processing.... however
1186 * this means that some packets will manage to get a long way
1187 * down this stack and then be rejected, but that's life.
1188 */
1189 if ((ic->icmp6_type != ICMPV6_DEST_UNREACH) &&
1190 (ic->icmp6_type != ICMPV6_PKT_TOOBIG) &&
1191 (ic->icmp6_type != ICMPV6_TIME_EXCEED)) {
1192 *related = 0;
1193 return NF_ACCEPT;
1194 }
1195
1196 /* Now find the contained IP header */
1197 offset += sizeof(_icmph);
1198 cih = skb_header_pointer(skb, offset, sizeof(_ciph), &_ciph);
1199 if (cih == NULL)
1200 return NF_ACCEPT; /* The packet looks wrong, ignore */
1201
1202 pp = ip_vs_proto_get(cih->nexthdr);
1203 if (!pp)
1204 return NF_ACCEPT;
1205
1206 /* Is the embedded protocol header present? */
1207 /* TODO: we don't support fragmentation at the moment anyways */
1208 if (unlikely(cih->nexthdr == IPPROTO_FRAGMENT && pp->dont_defrag))
1209 return NF_ACCEPT;
1210
1211 IP_VS_DBG_PKT(11, pp, skb, offset, "Checking incoming ICMPv6 for");
1212
1213 offset += sizeof(struct ipv6hdr);
1214
1215 ip_vs_fill_iphdr(AF_INET6, cih, &ciph);
1216 /* The embedded headers contain source and dest in reverse order */
1217 cp = pp->conn_in_get(AF_INET6, skb, pp, &ciph, offset, 1);
1218 if (!cp) {
1219 /* The packet could also belong to a local client */
1220 cp = pp->conn_out_get(AF_INET6, skb, pp, &ciph, offset, 1);
1221 if (cp) {
1222 ipv6_addr_copy(&snet.in6, &iph->saddr);
1223 return handle_response_icmp(AF_INET6, skb, &snet,
1224 cih->nexthdr,
1225 cp, pp, offset,
1226 sizeof(struct ipv6hdr));
1227 }
1228 return NF_ACCEPT;
1229 }
1230
1231 verdict = NF_DROP;
1232
1233 /* do the statistics and put it back */
1234 ip_vs_in_stats(cp, skb);
1235 if (IPPROTO_TCP == cih->nexthdr || IPPROTO_UDP == cih->nexthdr)
1236 offset += 2 * sizeof(__u16);
1237 verdict = ip_vs_icmp_xmit_v6(skb, cp, pp, offset);
1238 /* do not touch skb anymore */
1239
1240 __ip_vs_conn_put(cp);
1241
1242 return verdict;
1243}
1244#endif
1245
1246
891/* 1247/*
892 * Check if it's for virtual services, look it up, 1248 * Check if it's for virtual services, look it up,
893 * and send it on its way... 1249 * and send it on its way...
@@ -897,50 +1253,54 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
897 const struct net_device *in, const struct net_device *out, 1253 const struct net_device *in, const struct net_device *out,
898 int (*okfn)(struct sk_buff *)) 1254 int (*okfn)(struct sk_buff *))
899{ 1255{
900 struct iphdr *iph; 1256 struct ip_vs_iphdr iph;
901 struct ip_vs_protocol *pp; 1257 struct ip_vs_protocol *pp;
902 struct ip_vs_conn *cp; 1258 struct ip_vs_conn *cp;
903 int ret, restart; 1259 int ret, restart, af;
904 int ihl; 1260
1261 af = (skb->protocol == htons(ETH_P_IP)) ? AF_INET : AF_INET6;
1262
1263 ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
905 1264
906 /* 1265 /*
907 * Big tappo: only PACKET_HOST (neither loopback nor mcasts) 1266 * Big tappo: only PACKET_HOST, including loopback for local client
908 * ... don't know why 1st test DOES NOT include 2nd (?) 1267 * Don't handle local packets on IPv6 for now
909 */ 1268 */
910 if (unlikely(skb->pkt_type != PACKET_HOST 1269 if (unlikely(skb->pkt_type != PACKET_HOST)) {
911 || skb->dev->flags & IFF_LOOPBACK || skb->sk)) { 1270 IP_VS_DBG_BUF(12, "packet type=%d proto=%d daddr=%s ignored\n",
912 IP_VS_DBG(12, "packet type=%d proto=%d daddr=%d.%d.%d.%d ignored\n", 1271 skb->pkt_type,
913 skb->pkt_type, 1272 iph.protocol,
914 ip_hdr(skb)->protocol, 1273 IP_VS_DBG_ADDR(af, &iph.daddr));
915 NIPQUAD(ip_hdr(skb)->daddr));
916 return NF_ACCEPT; 1274 return NF_ACCEPT;
917 } 1275 }
918 1276
919 iph = ip_hdr(skb); 1277 if (unlikely(iph.protocol == IPPROTO_ICMP)) {
920 if (unlikely(iph->protocol == IPPROTO_ICMP)) {
921 int related, verdict = ip_vs_in_icmp(skb, &related, hooknum); 1278 int related, verdict = ip_vs_in_icmp(skb, &related, hooknum);
922 1279
923 if (related) 1280 if (related)
924 return verdict; 1281 return verdict;
925 iph = ip_hdr(skb); 1282 ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
926 } 1283 }
927 1284
928 /* Protocol supported? */ 1285 /* Protocol supported? */
929 pp = ip_vs_proto_get(iph->protocol); 1286 pp = ip_vs_proto_get(iph.protocol);
930 if (unlikely(!pp)) 1287 if (unlikely(!pp))
931 return NF_ACCEPT; 1288 return NF_ACCEPT;
932 1289
933 ihl = iph->ihl << 2;
934
935 /* 1290 /*
936 * Check if the packet belongs to an existing connection entry 1291 * Check if the packet belongs to an existing connection entry
937 */ 1292 */
938 cp = pp->conn_in_get(skb, pp, iph, ihl, 0); 1293 cp = pp->conn_in_get(af, skb, pp, &iph, iph.len, 0);
939 1294
940 if (unlikely(!cp)) { 1295 if (unlikely(!cp)) {
941 int v; 1296 int v;
942 1297
943 if (!pp->conn_schedule(skb, pp, &v, &cp)) 1298 /* For local client packets, it could be a response */
1299 cp = pp->conn_out_get(af, skb, pp, &iph, iph.len, 0);
1300 if (cp)
1301 return handle_response(af, skb, pp, cp, iph.len);
1302
1303 if (!pp->conn_schedule(af, skb, pp, &v, &cp))
944 return v; 1304 return v;
945 } 1305 }
946 1306
@@ -984,7 +1344,8 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
984 * encorage the standby servers to update the connections timeout 1344 * encorage the standby servers to update the connections timeout
985 */ 1345 */
986 atomic_inc(&cp->in_pkts); 1346 atomic_inc(&cp->in_pkts);
987 if ((ip_vs_sync_state & IP_VS_STATE_MASTER) && 1347 if (af == AF_INET &&
1348 (ip_vs_sync_state & IP_VS_STATE_MASTER) &&
988 (((cp->protocol != IPPROTO_TCP || 1349 (((cp->protocol != IPPROTO_TCP ||
989 cp->state == IP_VS_TCP_S_ESTABLISHED) && 1350 cp->state == IP_VS_TCP_S_ESTABLISHED) &&
990 (atomic_read(&cp->in_pkts) % sysctl_ip_vs_sync_threshold[1] 1351 (atomic_read(&cp->in_pkts) % sysctl_ip_vs_sync_threshold[1]
@@ -1023,6 +1384,21 @@ ip_vs_forward_icmp(unsigned int hooknum, struct sk_buff *skb,
1023 return ip_vs_in_icmp(skb, &r, hooknum); 1384 return ip_vs_in_icmp(skb, &r, hooknum);
1024} 1385}
1025 1386
1387#ifdef CONFIG_IP_VS_IPV6
1388static unsigned int
1389ip_vs_forward_icmp_v6(unsigned int hooknum, struct sk_buff *skb,
1390 const struct net_device *in, const struct net_device *out,
1391 int (*okfn)(struct sk_buff *))
1392{
1393 int r;
1394
1395 if (ipv6_hdr(skb)->nexthdr != IPPROTO_ICMPV6)
1396 return NF_ACCEPT;
1397
1398 return ip_vs_in_icmp_v6(skb, &r, hooknum);
1399}
1400#endif
1401
1026 1402
1027static struct nf_hook_ops ip_vs_ops[] __read_mostly = { 1403static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
1028 /* After packet filtering, forward packet through VS/DR, VS/TUN, 1404 /* After packet filtering, forward packet through VS/DR, VS/TUN,
@@ -1060,6 +1436,43 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
1060 .hooknum = NF_INET_POST_ROUTING, 1436 .hooknum = NF_INET_POST_ROUTING,
1061 .priority = NF_IP_PRI_NAT_SRC-1, 1437 .priority = NF_IP_PRI_NAT_SRC-1,
1062 }, 1438 },
1439#ifdef CONFIG_IP_VS_IPV6
1440 /* After packet filtering, forward packet through VS/DR, VS/TUN,
1441 * or VS/NAT(change destination), so that filtering rules can be
1442 * applied to IPVS. */
1443 {
1444 .hook = ip_vs_in,
1445 .owner = THIS_MODULE,
1446 .pf = PF_INET6,
1447 .hooknum = NF_INET_LOCAL_IN,
1448 .priority = 100,
1449 },
1450 /* After packet filtering, change source only for VS/NAT */
1451 {
1452 .hook = ip_vs_out,
1453 .owner = THIS_MODULE,
1454 .pf = PF_INET6,
1455 .hooknum = NF_INET_FORWARD,
1456 .priority = 100,
1457 },
1458 /* After packet filtering (but before ip_vs_out_icmp), catch icmp
1459 * destined for 0.0.0.0/0, which is for incoming IPVS connections */
1460 {
1461 .hook = ip_vs_forward_icmp_v6,
1462 .owner = THIS_MODULE,
1463 .pf = PF_INET6,
1464 .hooknum = NF_INET_FORWARD,
1465 .priority = 99,
1466 },
1467 /* Before the netfilter connection tracking, exit from POST_ROUTING */
1468 {
1469 .hook = ip_vs_post_routing,
1470 .owner = THIS_MODULE,
1471 .pf = PF_INET6,
1472 .hooknum = NF_INET_POST_ROUTING,
1473 .priority = NF_IP6_PRI_NAT_SRC-1,
1474 },
1475#endif
1063}; 1476};
1064 1477
1065 1478
@@ -1070,10 +1483,12 @@ static int __init ip_vs_init(void)
1070{ 1483{
1071 int ret; 1484 int ret;
1072 1485
1486 ip_vs_estimator_init();
1487
1073 ret = ip_vs_control_init(); 1488 ret = ip_vs_control_init();
1074 if (ret < 0) { 1489 if (ret < 0) {
1075 IP_VS_ERR("can't setup control.\n"); 1490 IP_VS_ERR("can't setup control.\n");
1076 goto cleanup_nothing; 1491 goto cleanup_estimator;
1077 } 1492 }
1078 1493
1079 ip_vs_protocol_init(); 1494 ip_vs_protocol_init();
@@ -1106,7 +1521,8 @@ static int __init ip_vs_init(void)
1106 cleanup_protocol: 1521 cleanup_protocol:
1107 ip_vs_protocol_cleanup(); 1522 ip_vs_protocol_cleanup();
1108 ip_vs_control_cleanup(); 1523 ip_vs_control_cleanup();
1109 cleanup_nothing: 1524 cleanup_estimator:
1525 ip_vs_estimator_cleanup();
1110 return ret; 1526 return ret;
1111} 1527}
1112 1528
@@ -1117,6 +1533,7 @@ static void __exit ip_vs_cleanup(void)
1117 ip_vs_app_cleanup(); 1533 ip_vs_app_cleanup();
1118 ip_vs_protocol_cleanup(); 1534 ip_vs_protocol_cleanup();
1119 ip_vs_control_cleanup(); 1535 ip_vs_control_cleanup();
1536 ip_vs_estimator_cleanup();
1120 IP_VS_INFO("ipvs unloaded.\n"); 1537 IP_VS_INFO("ipvs unloaded.\n");
1121} 1538}
1122 1539
diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 6379705a8dcb..0302cf3e5039 100644
--- a/net/ipv4/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -35,8 +35,13 @@
35 35
36#include <net/net_namespace.h> 36#include <net/net_namespace.h>
37#include <net/ip.h> 37#include <net/ip.h>
38#ifdef CONFIG_IP_VS_IPV6
39#include <net/ipv6.h>
40#include <net/ip6_route.h>
41#endif
38#include <net/route.h> 42#include <net/route.h>
39#include <net/sock.h> 43#include <net/sock.h>
44#include <net/genetlink.h>
40 45
41#include <asm/uaccess.h> 46#include <asm/uaccess.h>
42 47
@@ -90,6 +95,26 @@ int ip_vs_get_debug_level(void)
90} 95}
91#endif 96#endif
92 97
98#ifdef CONFIG_IP_VS_IPV6
99/* Taken from rt6_fill_node() in net/ipv6/route.c, is there a better way? */
100static int __ip_vs_addr_is_local_v6(const struct in6_addr *addr)
101{
102 struct rt6_info *rt;
103 struct flowi fl = {
104 .oif = 0,
105 .nl_u = {
106 .ip6_u = {
107 .daddr = *addr,
108 .saddr = { .s6_addr32 = {0, 0, 0, 0} }, } },
109 };
110
111 rt = (struct rt6_info *)ip6_route_output(&init_net, NULL, &fl);
112 if (rt && rt->rt6i_dev && (rt->rt6i_dev->flags & IFF_LOOPBACK))
113 return 1;
114
115 return 0;
116}
117#endif
93/* 118/*
94 * update_defense_level is called from keventd and from sysctl, 119 * update_defense_level is called from keventd and from sysctl,
95 * so it needs to protect itself from softirqs 120 * so it needs to protect itself from softirqs
@@ -281,11 +306,19 @@ static atomic_t ip_vs_nullsvc_counter = ATOMIC_INIT(0);
281 * Returns hash value for virtual service 306 * Returns hash value for virtual service
282 */ 307 */
283static __inline__ unsigned 308static __inline__ unsigned
284ip_vs_svc_hashkey(unsigned proto, __be32 addr, __be16 port) 309ip_vs_svc_hashkey(int af, unsigned proto, const union nf_inet_addr *addr,
310 __be16 port)
285{ 311{
286 register unsigned porth = ntohs(port); 312 register unsigned porth = ntohs(port);
313 __be32 addr_fold = addr->ip;
314
315#ifdef CONFIG_IP_VS_IPV6
316 if (af == AF_INET6)
317 addr_fold = addr->ip6[0]^addr->ip6[1]^
318 addr->ip6[2]^addr->ip6[3];
319#endif
287 320
288 return (proto^ntohl(addr)^(porth>>IP_VS_SVC_TAB_BITS)^porth) 321 return (proto^ntohl(addr_fold)^(porth>>IP_VS_SVC_TAB_BITS)^porth)
289 & IP_VS_SVC_TAB_MASK; 322 & IP_VS_SVC_TAB_MASK;
290} 323}
291 324
@@ -316,7 +349,8 @@ static int ip_vs_svc_hash(struct ip_vs_service *svc)
316 /* 349 /*
317 * Hash it by <protocol,addr,port> in ip_vs_svc_table 350 * Hash it by <protocol,addr,port> in ip_vs_svc_table
318 */ 351 */
319 hash = ip_vs_svc_hashkey(svc->protocol, svc->addr, svc->port); 352 hash = ip_vs_svc_hashkey(svc->af, svc->protocol, &svc->addr,
353 svc->port);
320 list_add(&svc->s_list, &ip_vs_svc_table[hash]); 354 list_add(&svc->s_list, &ip_vs_svc_table[hash]);
321 } else { 355 } else {
322 /* 356 /*
@@ -362,17 +396,19 @@ static int ip_vs_svc_unhash(struct ip_vs_service *svc)
362/* 396/*
363 * Get service by {proto,addr,port} in the service table. 397 * Get service by {proto,addr,port} in the service table.
364 */ 398 */
365static __inline__ struct ip_vs_service * 399static inline struct ip_vs_service *
366__ip_vs_service_get(__u16 protocol, __be32 vaddr, __be16 vport) 400__ip_vs_service_get(int af, __u16 protocol, const union nf_inet_addr *vaddr,
401 __be16 vport)
367{ 402{
368 unsigned hash; 403 unsigned hash;
369 struct ip_vs_service *svc; 404 struct ip_vs_service *svc;
370 405
371 /* Check for "full" addressed entries */ 406 /* Check for "full" addressed entries */
372 hash = ip_vs_svc_hashkey(protocol, vaddr, vport); 407 hash = ip_vs_svc_hashkey(af, protocol, vaddr, vport);
373 408
374 list_for_each_entry(svc, &ip_vs_svc_table[hash], s_list){ 409 list_for_each_entry(svc, &ip_vs_svc_table[hash], s_list){
375 if ((svc->addr == vaddr) 410 if ((svc->af == af)
411 && ip_vs_addr_equal(af, &svc->addr, vaddr)
376 && (svc->port == vport) 412 && (svc->port == vport)
377 && (svc->protocol == protocol)) { 413 && (svc->protocol == protocol)) {
378 /* HIT */ 414 /* HIT */
@@ -388,7 +424,8 @@ __ip_vs_service_get(__u16 protocol, __be32 vaddr, __be16 vport)
388/* 424/*
389 * Get service by {fwmark} in the service table. 425 * Get service by {fwmark} in the service table.
390 */ 426 */
391static __inline__ struct ip_vs_service *__ip_vs_svc_fwm_get(__u32 fwmark) 427static inline struct ip_vs_service *
428__ip_vs_svc_fwm_get(int af, __u32 fwmark)
392{ 429{
393 unsigned hash; 430 unsigned hash;
394 struct ip_vs_service *svc; 431 struct ip_vs_service *svc;
@@ -397,7 +434,7 @@ static __inline__ struct ip_vs_service *__ip_vs_svc_fwm_get(__u32 fwmark)
397 hash = ip_vs_svc_fwm_hashkey(fwmark); 434 hash = ip_vs_svc_fwm_hashkey(fwmark);
398 435
399 list_for_each_entry(svc, &ip_vs_svc_fwm_table[hash], f_list) { 436 list_for_each_entry(svc, &ip_vs_svc_fwm_table[hash], f_list) {
400 if (svc->fwmark == fwmark) { 437 if (svc->fwmark == fwmark && svc->af == af) {
401 /* HIT */ 438 /* HIT */
402 atomic_inc(&svc->usecnt); 439 atomic_inc(&svc->usecnt);
403 return svc; 440 return svc;
@@ -408,7 +445,8 @@ static __inline__ struct ip_vs_service *__ip_vs_svc_fwm_get(__u32 fwmark)
408} 445}
409 446
410struct ip_vs_service * 447struct ip_vs_service *
411ip_vs_service_get(__u32 fwmark, __u16 protocol, __be32 vaddr, __be16 vport) 448ip_vs_service_get(int af, __u32 fwmark, __u16 protocol,
449 const union nf_inet_addr *vaddr, __be16 vport)
412{ 450{
413 struct ip_vs_service *svc; 451 struct ip_vs_service *svc;
414 452
@@ -417,14 +455,14 @@ ip_vs_service_get(__u32 fwmark, __u16 protocol, __be32 vaddr, __be16 vport)
417 /* 455 /*
418 * Check the table hashed by fwmark first 456 * Check the table hashed by fwmark first
419 */ 457 */
420 if (fwmark && (svc = __ip_vs_svc_fwm_get(fwmark))) 458 if (fwmark && (svc = __ip_vs_svc_fwm_get(af, fwmark)))
421 goto out; 459 goto out;
422 460
423 /* 461 /*
424 * Check the table hashed by <protocol,addr,port> 462 * Check the table hashed by <protocol,addr,port>
425 * for "full" addressed entries 463 * for "full" addressed entries
426 */ 464 */
427 svc = __ip_vs_service_get(protocol, vaddr, vport); 465 svc = __ip_vs_service_get(af, protocol, vaddr, vport);
428 466
429 if (svc == NULL 467 if (svc == NULL
430 && protocol == IPPROTO_TCP 468 && protocol == IPPROTO_TCP
@@ -434,7 +472,7 @@ ip_vs_service_get(__u32 fwmark, __u16 protocol, __be32 vaddr, __be16 vport)
434 * Check if ftp service entry exists, the packet 472 * Check if ftp service entry exists, the packet
435 * might belong to FTP data connections. 473 * might belong to FTP data connections.
436 */ 474 */
437 svc = __ip_vs_service_get(protocol, vaddr, FTPPORT); 475 svc = __ip_vs_service_get(af, protocol, vaddr, FTPPORT);
438 } 476 }
439 477
440 if (svc == NULL 478 if (svc == NULL
@@ -442,16 +480,16 @@ ip_vs_service_get(__u32 fwmark, __u16 protocol, __be32 vaddr, __be16 vport)
442 /* 480 /*
443 * Check if the catch-all port (port zero) exists 481 * Check if the catch-all port (port zero) exists
444 */ 482 */
445 svc = __ip_vs_service_get(protocol, vaddr, 0); 483 svc = __ip_vs_service_get(af, protocol, vaddr, 0);
446 } 484 }
447 485
448 out: 486 out:
449 read_unlock(&__ip_vs_svc_lock); 487 read_unlock(&__ip_vs_svc_lock);
450 488
451 IP_VS_DBG(9, "lookup service: fwm %u %s %u.%u.%u.%u:%u %s\n", 489 IP_VS_DBG_BUF(9, "lookup service: fwm %u %s %s:%u %s\n",
452 fwmark, ip_vs_proto_name(protocol), 490 fwmark, ip_vs_proto_name(protocol),
453 NIPQUAD(vaddr), ntohs(vport), 491 IP_VS_DBG_ADDR(af, vaddr), ntohs(vport),
454 svc?"hit":"not hit"); 492 svc ? "hit" : "not hit");
455 493
456 return svc; 494 return svc;
457} 495}
@@ -478,11 +516,20 @@ __ip_vs_unbind_svc(struct ip_vs_dest *dest)
478/* 516/*
479 * Returns hash value for real service 517 * Returns hash value for real service
480 */ 518 */
481static __inline__ unsigned ip_vs_rs_hashkey(__be32 addr, __be16 port) 519static inline unsigned ip_vs_rs_hashkey(int af,
520 const union nf_inet_addr *addr,
521 __be16 port)
482{ 522{
483 register unsigned porth = ntohs(port); 523 register unsigned porth = ntohs(port);
524 __be32 addr_fold = addr->ip;
525
526#ifdef CONFIG_IP_VS_IPV6
527 if (af == AF_INET6)
528 addr_fold = addr->ip6[0]^addr->ip6[1]^
529 addr->ip6[2]^addr->ip6[3];
530#endif
484 531
485 return (ntohl(addr)^(porth>>IP_VS_RTAB_BITS)^porth) 532 return (ntohl(addr_fold)^(porth>>IP_VS_RTAB_BITS)^porth)
486 & IP_VS_RTAB_MASK; 533 & IP_VS_RTAB_MASK;
487} 534}
488 535
@@ -502,7 +549,8 @@ static int ip_vs_rs_hash(struct ip_vs_dest *dest)
502 * Hash by proto,addr,port, 549 * Hash by proto,addr,port,
503 * which are the parameters of the real service. 550 * which are the parameters of the real service.
504 */ 551 */
505 hash = ip_vs_rs_hashkey(dest->addr, dest->port); 552 hash = ip_vs_rs_hashkey(dest->af, &dest->addr, dest->port);
553
506 list_add(&dest->d_list, &ip_vs_rtable[hash]); 554 list_add(&dest->d_list, &ip_vs_rtable[hash]);
507 555
508 return 1; 556 return 1;
@@ -529,7 +577,9 @@ static int ip_vs_rs_unhash(struct ip_vs_dest *dest)
529 * Lookup real service by <proto,addr,port> in the real service table. 577 * Lookup real service by <proto,addr,port> in the real service table.
530 */ 578 */
531struct ip_vs_dest * 579struct ip_vs_dest *
532ip_vs_lookup_real_service(__u16 protocol, __be32 daddr, __be16 dport) 580ip_vs_lookup_real_service(int af, __u16 protocol,
581 const union nf_inet_addr *daddr,
582 __be16 dport)
533{ 583{
534 unsigned hash; 584 unsigned hash;
535 struct ip_vs_dest *dest; 585 struct ip_vs_dest *dest;
@@ -538,11 +588,12 @@ ip_vs_lookup_real_service(__u16 protocol, __be32 daddr, __be16 dport)
538 * Check for "full" addressed entries 588 * Check for "full" addressed entries
539 * Return the first found entry 589 * Return the first found entry
540 */ 590 */
541 hash = ip_vs_rs_hashkey(daddr, dport); 591 hash = ip_vs_rs_hashkey(af, daddr, dport);
542 592
543 read_lock(&__ip_vs_rs_lock); 593 read_lock(&__ip_vs_rs_lock);
544 list_for_each_entry(dest, &ip_vs_rtable[hash], d_list) { 594 list_for_each_entry(dest, &ip_vs_rtable[hash], d_list) {
545 if ((dest->addr == daddr) 595 if ((dest->af == af)
596 && ip_vs_addr_equal(af, &dest->addr, daddr)
546 && (dest->port == dport) 597 && (dest->port == dport)
547 && ((dest->protocol == protocol) || 598 && ((dest->protocol == protocol) ||
548 dest->vfwmark)) { 599 dest->vfwmark)) {
@@ -560,7 +611,8 @@ ip_vs_lookup_real_service(__u16 protocol, __be32 daddr, __be16 dport)
560 * Lookup destination by {addr,port} in the given service 611 * Lookup destination by {addr,port} in the given service
561 */ 612 */
562static struct ip_vs_dest * 613static struct ip_vs_dest *
563ip_vs_lookup_dest(struct ip_vs_service *svc, __be32 daddr, __be16 dport) 614ip_vs_lookup_dest(struct ip_vs_service *svc, const union nf_inet_addr *daddr,
615 __be16 dport)
564{ 616{
565 struct ip_vs_dest *dest; 617 struct ip_vs_dest *dest;
566 618
@@ -568,7 +620,9 @@ ip_vs_lookup_dest(struct ip_vs_service *svc, __be32 daddr, __be16 dport)
568 * Find the destination for the given service 620 * Find the destination for the given service
569 */ 621 */
570 list_for_each_entry(dest, &svc->destinations, n_list) { 622 list_for_each_entry(dest, &svc->destinations, n_list) {
571 if ((dest->addr == daddr) && (dest->port == dport)) { 623 if ((dest->af == svc->af)
624 && ip_vs_addr_equal(svc->af, &dest->addr, daddr)
625 && (dest->port == dport)) {
572 /* HIT */ 626 /* HIT */
573 return dest; 627 return dest;
574 } 628 }
@@ -587,13 +641,15 @@ ip_vs_lookup_dest(struct ip_vs_service *svc, __be32 daddr, __be16 dport)
587 * ip_vs_lookup_real_service() looked promissing, but 641 * ip_vs_lookup_real_service() looked promissing, but
588 * seems not working as expected. 642 * seems not working as expected.
589 */ 643 */
590struct ip_vs_dest *ip_vs_find_dest(__be32 daddr, __be16 dport, 644struct ip_vs_dest *ip_vs_find_dest(int af, const union nf_inet_addr *daddr,
591 __be32 vaddr, __be16 vport, __u16 protocol) 645 __be16 dport,
646 const union nf_inet_addr *vaddr,
647 __be16 vport, __u16 protocol)
592{ 648{
593 struct ip_vs_dest *dest; 649 struct ip_vs_dest *dest;
594 struct ip_vs_service *svc; 650 struct ip_vs_service *svc;
595 651
596 svc = ip_vs_service_get(0, protocol, vaddr, vport); 652 svc = ip_vs_service_get(af, 0, protocol, vaddr, vport);
597 if (!svc) 653 if (!svc)
598 return NULL; 654 return NULL;
599 dest = ip_vs_lookup_dest(svc, daddr, dport); 655 dest = ip_vs_lookup_dest(svc, daddr, dport);
@@ -614,7 +670,8 @@ struct ip_vs_dest *ip_vs_find_dest(__be32 daddr, __be16 dport,
614 * scheduling. 670 * scheduling.
615 */ 671 */
616static struct ip_vs_dest * 672static struct ip_vs_dest *
617ip_vs_trash_get_dest(struct ip_vs_service *svc, __be32 daddr, __be16 dport) 673ip_vs_trash_get_dest(struct ip_vs_service *svc, const union nf_inet_addr *daddr,
674 __be16 dport)
618{ 675{
619 struct ip_vs_dest *dest, *nxt; 676 struct ip_vs_dest *dest, *nxt;
620 677
@@ -622,17 +679,19 @@ ip_vs_trash_get_dest(struct ip_vs_service *svc, __be32 daddr, __be16 dport)
622 * Find the destination in trash 679 * Find the destination in trash
623 */ 680 */
624 list_for_each_entry_safe(dest, nxt, &ip_vs_dest_trash, n_list) { 681 list_for_each_entry_safe(dest, nxt, &ip_vs_dest_trash, n_list) {
625 IP_VS_DBG(3, "Destination %u/%u.%u.%u.%u:%u still in trash, " 682 IP_VS_DBG_BUF(3, "Destination %u/%s:%u still in trash, "
626 "dest->refcnt=%d\n", 683 "dest->refcnt=%d\n",
627 dest->vfwmark, 684 dest->vfwmark,
628 NIPQUAD(dest->addr), ntohs(dest->port), 685 IP_VS_DBG_ADDR(svc->af, &dest->addr),
629 atomic_read(&dest->refcnt)); 686 ntohs(dest->port),
630 if (dest->addr == daddr && 687 atomic_read(&dest->refcnt));
688 if (dest->af == svc->af &&
689 ip_vs_addr_equal(svc->af, &dest->addr, daddr) &&
631 dest->port == dport && 690 dest->port == dport &&
632 dest->vfwmark == svc->fwmark && 691 dest->vfwmark == svc->fwmark &&
633 dest->protocol == svc->protocol && 692 dest->protocol == svc->protocol &&
634 (svc->fwmark || 693 (svc->fwmark ||
635 (dest->vaddr == svc->addr && 694 (ip_vs_addr_equal(svc->af, &dest->vaddr, &svc->addr) &&
636 dest->vport == svc->port))) { 695 dest->vport == svc->port))) {
637 /* HIT */ 696 /* HIT */
638 return dest; 697 return dest;
@@ -642,10 +701,11 @@ ip_vs_trash_get_dest(struct ip_vs_service *svc, __be32 daddr, __be16 dport)
642 * Try to purge the destination from trash if not referenced 701 * Try to purge the destination from trash if not referenced
643 */ 702 */
644 if (atomic_read(&dest->refcnt) == 1) { 703 if (atomic_read(&dest->refcnt) == 1) {
645 IP_VS_DBG(3, "Removing destination %u/%u.%u.%u.%u:%u " 704 IP_VS_DBG_BUF(3, "Removing destination %u/%s:%u "
646 "from trash\n", 705 "from trash\n",
647 dest->vfwmark, 706 dest->vfwmark,
648 NIPQUAD(dest->addr), ntohs(dest->port)); 707 IP_VS_DBG_ADDR(svc->af, &dest->addr),
708 ntohs(dest->port));
649 list_del(&dest->n_list); 709 list_del(&dest->n_list);
650 ip_vs_dst_reset(dest); 710 ip_vs_dst_reset(dest);
651 __ip_vs_unbind_svc(dest); 711 __ip_vs_unbind_svc(dest);
@@ -684,18 +744,7 @@ ip_vs_zero_stats(struct ip_vs_stats *stats)
684{ 744{
685 spin_lock_bh(&stats->lock); 745 spin_lock_bh(&stats->lock);
686 746
687 stats->conns = 0; 747 memset(&stats->ustats, 0, sizeof(stats->ustats));
688 stats->inpkts = 0;
689 stats->outpkts = 0;
690 stats->inbytes = 0;
691 stats->outbytes = 0;
692
693 stats->cps = 0;
694 stats->inpps = 0;
695 stats->outpps = 0;
696 stats->inbps = 0;
697 stats->outbps = 0;
698
699 ip_vs_zero_estimator(stats); 748 ip_vs_zero_estimator(stats);
700 749
701 spin_unlock_bh(&stats->lock); 750 spin_unlock_bh(&stats->lock);
@@ -706,7 +755,7 @@ ip_vs_zero_stats(struct ip_vs_stats *stats)
706 */ 755 */
707static void 756static void
708__ip_vs_update_dest(struct ip_vs_service *svc, 757__ip_vs_update_dest(struct ip_vs_service *svc,
709 struct ip_vs_dest *dest, struct ip_vs_dest_user *udest) 758 struct ip_vs_dest *dest, struct ip_vs_dest_user_kern *udest)
710{ 759{
711 int conn_flags; 760 int conn_flags;
712 761
@@ -715,10 +764,18 @@ __ip_vs_update_dest(struct ip_vs_service *svc,
715 conn_flags = udest->conn_flags | IP_VS_CONN_F_INACTIVE; 764 conn_flags = udest->conn_flags | IP_VS_CONN_F_INACTIVE;
716 765
717 /* check if local node and update the flags */ 766 /* check if local node and update the flags */
718 if (inet_addr_type(&init_net, udest->addr) == RTN_LOCAL) { 767#ifdef CONFIG_IP_VS_IPV6
719 conn_flags = (conn_flags & ~IP_VS_CONN_F_FWD_MASK) 768 if (svc->af == AF_INET6) {
720 | IP_VS_CONN_F_LOCALNODE; 769 if (__ip_vs_addr_is_local_v6(&udest->addr.in6)) {
721 } 770 conn_flags = (conn_flags & ~IP_VS_CONN_F_FWD_MASK)
771 | IP_VS_CONN_F_LOCALNODE;
772 }
773 } else
774#endif
775 if (inet_addr_type(&init_net, udest->addr.ip) == RTN_LOCAL) {
776 conn_flags = (conn_flags & ~IP_VS_CONN_F_FWD_MASK)
777 | IP_VS_CONN_F_LOCALNODE;
778 }
722 779
723 /* set the IP_VS_CONN_F_NOOUTPUT flag if not masquerading/NAT */ 780 /* set the IP_VS_CONN_F_NOOUTPUT flag if not masquerading/NAT */
724 if ((conn_flags & IP_VS_CONN_F_FWD_MASK) != 0) { 781 if ((conn_flags & IP_VS_CONN_F_FWD_MASK) != 0) {
@@ -759,7 +816,7 @@ __ip_vs_update_dest(struct ip_vs_service *svc,
759 * Create a destination for the given service 816 * Create a destination for the given service
760 */ 817 */
761static int 818static int
762ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest, 819ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest,
763 struct ip_vs_dest **dest_p) 820 struct ip_vs_dest **dest_p)
764{ 821{
765 struct ip_vs_dest *dest; 822 struct ip_vs_dest *dest;
@@ -767,9 +824,20 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest,
767 824
768 EnterFunction(2); 825 EnterFunction(2);
769 826
770 atype = inet_addr_type(&init_net, udest->addr); 827#ifdef CONFIG_IP_VS_IPV6
771 if (atype != RTN_LOCAL && atype != RTN_UNICAST) 828 if (svc->af == AF_INET6) {
772 return -EINVAL; 829 atype = ipv6_addr_type(&udest->addr.in6);
830 if ((!(atype & IPV6_ADDR_UNICAST) ||
831 atype & IPV6_ADDR_LINKLOCAL) &&
832 !__ip_vs_addr_is_local_v6(&udest->addr.in6))
833 return -EINVAL;
834 } else
835#endif
836 {
837 atype = inet_addr_type(&init_net, udest->addr.ip);
838 if (atype != RTN_LOCAL && atype != RTN_UNICAST)
839 return -EINVAL;
840 }
773 841
774 dest = kzalloc(sizeof(struct ip_vs_dest), GFP_ATOMIC); 842 dest = kzalloc(sizeof(struct ip_vs_dest), GFP_ATOMIC);
775 if (dest == NULL) { 843 if (dest == NULL) {
@@ -777,11 +845,12 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest,
777 return -ENOMEM; 845 return -ENOMEM;
778 } 846 }
779 847
848 dest->af = svc->af;
780 dest->protocol = svc->protocol; 849 dest->protocol = svc->protocol;
781 dest->vaddr = svc->addr; 850 dest->vaddr = svc->addr;
782 dest->vport = svc->port; 851 dest->vport = svc->port;
783 dest->vfwmark = svc->fwmark; 852 dest->vfwmark = svc->fwmark;
784 dest->addr = udest->addr; 853 ip_vs_addr_copy(svc->af, &dest->addr, &udest->addr);
785 dest->port = udest->port; 854 dest->port = udest->port;
786 855
787 atomic_set(&dest->activeconns, 0); 856 atomic_set(&dest->activeconns, 0);
@@ -806,10 +875,10 @@ ip_vs_new_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest,
806 * Add a destination into an existing service 875 * Add a destination into an existing service
807 */ 876 */
808static int 877static int
809ip_vs_add_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest) 878ip_vs_add_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest)
810{ 879{
811 struct ip_vs_dest *dest; 880 struct ip_vs_dest *dest;
812 __be32 daddr = udest->addr; 881 union nf_inet_addr daddr;
813 __be16 dport = udest->port; 882 __be16 dport = udest->port;
814 int ret; 883 int ret;
815 884
@@ -826,10 +895,13 @@ ip_vs_add_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest)
826 return -ERANGE; 895 return -ERANGE;
827 } 896 }
828 897
898 ip_vs_addr_copy(svc->af, &daddr, &udest->addr);
899
829 /* 900 /*
830 * Check if the dest already exists in the list 901 * Check if the dest already exists in the list
831 */ 902 */
832 dest = ip_vs_lookup_dest(svc, daddr, dport); 903 dest = ip_vs_lookup_dest(svc, &daddr, dport);
904
833 if (dest != NULL) { 905 if (dest != NULL) {
834 IP_VS_DBG(1, "ip_vs_add_dest(): dest already exists\n"); 906 IP_VS_DBG(1, "ip_vs_add_dest(): dest already exists\n");
835 return -EEXIST; 907 return -EEXIST;
@@ -839,15 +911,17 @@ ip_vs_add_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest)
839 * Check if the dest already exists in the trash and 911 * Check if the dest already exists in the trash and
840 * is from the same service 912 * is from the same service
841 */ 913 */
842 dest = ip_vs_trash_get_dest(svc, daddr, dport); 914 dest = ip_vs_trash_get_dest(svc, &daddr, dport);
915
843 if (dest != NULL) { 916 if (dest != NULL) {
844 IP_VS_DBG(3, "Get destination %u.%u.%u.%u:%u from trash, " 917 IP_VS_DBG_BUF(3, "Get destination %s:%u from trash, "
845 "dest->refcnt=%d, service %u/%u.%u.%u.%u:%u\n", 918 "dest->refcnt=%d, service %u/%s:%u\n",
846 NIPQUAD(daddr), ntohs(dport), 919 IP_VS_DBG_ADDR(svc->af, &daddr), ntohs(dport),
847 atomic_read(&dest->refcnt), 920 atomic_read(&dest->refcnt),
848 dest->vfwmark, 921 dest->vfwmark,
849 NIPQUAD(dest->vaddr), 922 IP_VS_DBG_ADDR(svc->af, &dest->vaddr),
850 ntohs(dest->vport)); 923 ntohs(dest->vport));
924
851 __ip_vs_update_dest(svc, dest, udest); 925 __ip_vs_update_dest(svc, dest, udest);
852 926
853 /* 927 /*
@@ -868,7 +942,8 @@ ip_vs_add_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest)
868 svc->num_dests++; 942 svc->num_dests++;
869 943
870 /* call the update_service function of its scheduler */ 944 /* call the update_service function of its scheduler */
871 svc->scheduler->update_service(svc); 945 if (svc->scheduler->update_service)
946 svc->scheduler->update_service(svc);
872 947
873 write_unlock_bh(&__ip_vs_svc_lock); 948 write_unlock_bh(&__ip_vs_svc_lock);
874 return 0; 949 return 0;
@@ -898,7 +973,8 @@ ip_vs_add_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest)
898 svc->num_dests++; 973 svc->num_dests++;
899 974
900 /* call the update_service function of its scheduler */ 975 /* call the update_service function of its scheduler */
901 svc->scheduler->update_service(svc); 976 if (svc->scheduler->update_service)
977 svc->scheduler->update_service(svc);
902 978
903 write_unlock_bh(&__ip_vs_svc_lock); 979 write_unlock_bh(&__ip_vs_svc_lock);
904 980
@@ -912,10 +988,10 @@ ip_vs_add_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest)
912 * Edit a destination in the given service 988 * Edit a destination in the given service
913 */ 989 */
914static int 990static int
915ip_vs_edit_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest) 991ip_vs_edit_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest)
916{ 992{
917 struct ip_vs_dest *dest; 993 struct ip_vs_dest *dest;
918 __be32 daddr = udest->addr; 994 union nf_inet_addr daddr;
919 __be16 dport = udest->port; 995 __be16 dport = udest->port;
920 996
921 EnterFunction(2); 997 EnterFunction(2);
@@ -931,10 +1007,13 @@ ip_vs_edit_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest)
931 return -ERANGE; 1007 return -ERANGE;
932 } 1008 }
933 1009
1010 ip_vs_addr_copy(svc->af, &daddr, &udest->addr);
1011
934 /* 1012 /*
935 * Lookup the destination list 1013 * Lookup the destination list
936 */ 1014 */
937 dest = ip_vs_lookup_dest(svc, daddr, dport); 1015 dest = ip_vs_lookup_dest(svc, &daddr, dport);
1016
938 if (dest == NULL) { 1017 if (dest == NULL) {
939 IP_VS_DBG(1, "ip_vs_edit_dest(): dest doesn't exist\n"); 1018 IP_VS_DBG(1, "ip_vs_edit_dest(): dest doesn't exist\n");
940 return -ENOENT; 1019 return -ENOENT;
@@ -948,7 +1027,8 @@ ip_vs_edit_dest(struct ip_vs_service *svc, struct ip_vs_dest_user *udest)
948 IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 1); 1027 IP_VS_WAIT_WHILE(atomic_read(&svc->usecnt) > 1);
949 1028
950 /* call the update_service, because server weight may be changed */ 1029 /* call the update_service, because server weight may be changed */
951 svc->scheduler->update_service(svc); 1030 if (svc->scheduler->update_service)
1031 svc->scheduler->update_service(svc);
952 1032
953 write_unlock_bh(&__ip_vs_svc_lock); 1033 write_unlock_bh(&__ip_vs_svc_lock);
954 1034
@@ -987,10 +1067,11 @@ static void __ip_vs_del_dest(struct ip_vs_dest *dest)
987 atomic_dec(&dest->svc->refcnt); 1067 atomic_dec(&dest->svc->refcnt);
988 kfree(dest); 1068 kfree(dest);
989 } else { 1069 } else {
990 IP_VS_DBG(3, "Moving dest %u.%u.%u.%u:%u into trash, " 1070 IP_VS_DBG_BUF(3, "Moving dest %s:%u into trash, "
991 "dest->refcnt=%d\n", 1071 "dest->refcnt=%d\n",
992 NIPQUAD(dest->addr), ntohs(dest->port), 1072 IP_VS_DBG_ADDR(dest->af, &dest->addr),
993 atomic_read(&dest->refcnt)); 1073 ntohs(dest->port),
1074 atomic_read(&dest->refcnt));
994 list_add(&dest->n_list, &ip_vs_dest_trash); 1075 list_add(&dest->n_list, &ip_vs_dest_trash);
995 atomic_inc(&dest->refcnt); 1076 atomic_inc(&dest->refcnt);
996 } 1077 }
@@ -1011,12 +1092,12 @@ static void __ip_vs_unlink_dest(struct ip_vs_service *svc,
1011 */ 1092 */
1012 list_del(&dest->n_list); 1093 list_del(&dest->n_list);
1013 svc->num_dests--; 1094 svc->num_dests--;
1014 if (svcupd) { 1095
1015 /* 1096 /*
1016 * Call the update_service function of its scheduler 1097 * Call the update_service function of its scheduler
1017 */ 1098 */
1018 svc->scheduler->update_service(svc); 1099 if (svcupd && svc->scheduler->update_service)
1019 } 1100 svc->scheduler->update_service(svc);
1020} 1101}
1021 1102
1022 1103
@@ -1024,15 +1105,15 @@ static void __ip_vs_unlink_dest(struct ip_vs_service *svc,
1024 * Delete a destination server in the given service 1105 * Delete a destination server in the given service
1025 */ 1106 */
1026static int 1107static int
1027ip_vs_del_dest(struct ip_vs_service *svc,struct ip_vs_dest_user *udest) 1108ip_vs_del_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest)
1028{ 1109{
1029 struct ip_vs_dest *dest; 1110 struct ip_vs_dest *dest;
1030 __be32 daddr = udest->addr;
1031 __be16 dport = udest->port; 1111 __be16 dport = udest->port;
1032 1112
1033 EnterFunction(2); 1113 EnterFunction(2);
1034 1114
1035 dest = ip_vs_lookup_dest(svc, daddr, dport); 1115 dest = ip_vs_lookup_dest(svc, &udest->addr, dport);
1116
1036 if (dest == NULL) { 1117 if (dest == NULL) {
1037 IP_VS_DBG(1, "ip_vs_del_dest(): destination not found!\n"); 1118 IP_VS_DBG(1, "ip_vs_del_dest(): destination not found!\n");
1038 return -ENOENT; 1119 return -ENOENT;
@@ -1067,7 +1148,8 @@ ip_vs_del_dest(struct ip_vs_service *svc,struct ip_vs_dest_user *udest)
1067 * Add a service into the service hash table 1148 * Add a service into the service hash table
1068 */ 1149 */
1069static int 1150static int
1070ip_vs_add_service(struct ip_vs_service_user *u, struct ip_vs_service **svc_p) 1151ip_vs_add_service(struct ip_vs_service_user_kern *u,
1152 struct ip_vs_service **svc_p)
1071{ 1153{
1072 int ret = 0; 1154 int ret = 0;
1073 struct ip_vs_scheduler *sched = NULL; 1155 struct ip_vs_scheduler *sched = NULL;
@@ -1085,6 +1167,19 @@ ip_vs_add_service(struct ip_vs_service_user *u, struct ip_vs_service **svc_p)
1085 goto out_mod_dec; 1167 goto out_mod_dec;
1086 } 1168 }
1087 1169
1170#ifdef CONFIG_IP_VS_IPV6
1171 if (u->af == AF_INET6) {
1172 if (!sched->supports_ipv6) {
1173 ret = -EAFNOSUPPORT;
1174 goto out_err;
1175 }
1176 if ((u->netmask < 1) || (u->netmask > 128)) {
1177 ret = -EINVAL;
1178 goto out_err;
1179 }
1180 }
1181#endif
1182
1088 svc = kzalloc(sizeof(struct ip_vs_service), GFP_ATOMIC); 1183 svc = kzalloc(sizeof(struct ip_vs_service), GFP_ATOMIC);
1089 if (svc == NULL) { 1184 if (svc == NULL) {
1090 IP_VS_DBG(1, "ip_vs_add_service: kmalloc failed.\n"); 1185 IP_VS_DBG(1, "ip_vs_add_service: kmalloc failed.\n");
@@ -1096,8 +1191,9 @@ ip_vs_add_service(struct ip_vs_service_user *u, struct ip_vs_service **svc_p)
1096 atomic_set(&svc->usecnt, 1); 1191 atomic_set(&svc->usecnt, 1);
1097 atomic_set(&svc->refcnt, 0); 1192 atomic_set(&svc->refcnt, 0);
1098 1193
1194 svc->af = u->af;
1099 svc->protocol = u->protocol; 1195 svc->protocol = u->protocol;
1100 svc->addr = u->addr; 1196 ip_vs_addr_copy(svc->af, &svc->addr, &u->addr);
1101 svc->port = u->port; 1197 svc->port = u->port;
1102 svc->fwmark = u->fwmark; 1198 svc->fwmark = u->fwmark;
1103 svc->flags = u->flags; 1199 svc->flags = u->flags;
@@ -1121,7 +1217,10 @@ ip_vs_add_service(struct ip_vs_service_user *u, struct ip_vs_service **svc_p)
1121 atomic_inc(&ip_vs_nullsvc_counter); 1217 atomic_inc(&ip_vs_nullsvc_counter);
1122 1218
1123 ip_vs_new_estimator(&svc->stats); 1219 ip_vs_new_estimator(&svc->stats);
1124 ip_vs_num_services++; 1220
1221 /* Count only IPv4 services for old get/setsockopt interface */
1222 if (svc->af == AF_INET)
1223 ip_vs_num_services++;
1125 1224
1126 /* Hash the service into the service table */ 1225 /* Hash the service into the service table */
1127 write_lock_bh(&__ip_vs_svc_lock); 1226 write_lock_bh(&__ip_vs_svc_lock);
@@ -1156,7 +1255,7 @@ ip_vs_add_service(struct ip_vs_service_user *u, struct ip_vs_service **svc_p)
1156 * Edit a service and bind it with a new scheduler 1255 * Edit a service and bind it with a new scheduler
1157 */ 1256 */
1158static int 1257static int
1159ip_vs_edit_service(struct ip_vs_service *svc, struct ip_vs_service_user *u) 1258ip_vs_edit_service(struct ip_vs_service *svc, struct ip_vs_service_user_kern *u)
1160{ 1259{
1161 struct ip_vs_scheduler *sched, *old_sched; 1260 struct ip_vs_scheduler *sched, *old_sched;
1162 int ret = 0; 1261 int ret = 0;
@@ -1172,6 +1271,19 @@ ip_vs_edit_service(struct ip_vs_service *svc, struct ip_vs_service_user *u)
1172 } 1271 }
1173 old_sched = sched; 1272 old_sched = sched;
1174 1273
1274#ifdef CONFIG_IP_VS_IPV6
1275 if (u->af == AF_INET6) {
1276 if (!sched->supports_ipv6) {
1277 ret = -EAFNOSUPPORT;
1278 goto out;
1279 }
1280 if ((u->netmask < 1) || (u->netmask > 128)) {
1281 ret = -EINVAL;
1282 goto out;
1283 }
1284 }
1285#endif
1286
1175 write_lock_bh(&__ip_vs_svc_lock); 1287 write_lock_bh(&__ip_vs_svc_lock);
1176 1288
1177 /* 1289 /*
@@ -1193,7 +1305,7 @@ ip_vs_edit_service(struct ip_vs_service *svc, struct ip_vs_service_user *u)
1193 */ 1305 */
1194 if ((ret = ip_vs_unbind_scheduler(svc))) { 1306 if ((ret = ip_vs_unbind_scheduler(svc))) {
1195 old_sched = sched; 1307 old_sched = sched;
1196 goto out; 1308 goto out_unlock;
1197 } 1309 }
1198 1310
1199 /* 1311 /*
@@ -1212,12 +1324,15 @@ ip_vs_edit_service(struct ip_vs_service *svc, struct ip_vs_service_user *u)
1212 */ 1324 */
1213 ip_vs_bind_scheduler(svc, old_sched); 1325 ip_vs_bind_scheduler(svc, old_sched);
1214 old_sched = sched; 1326 old_sched = sched;
1215 goto out; 1327 goto out_unlock;
1216 } 1328 }
1217 } 1329 }
1218 1330
1219 out: 1331 out_unlock:
1220 write_unlock_bh(&__ip_vs_svc_lock); 1332 write_unlock_bh(&__ip_vs_svc_lock);
1333#ifdef CONFIG_IP_VS_IPV6
1334 out:
1335#endif
1221 1336
1222 if (old_sched) 1337 if (old_sched)
1223 ip_vs_scheduler_put(old_sched); 1338 ip_vs_scheduler_put(old_sched);
@@ -1236,7 +1351,10 @@ static void __ip_vs_del_service(struct ip_vs_service *svc)
1236 struct ip_vs_dest *dest, *nxt; 1351 struct ip_vs_dest *dest, *nxt;
1237 struct ip_vs_scheduler *old_sched; 1352 struct ip_vs_scheduler *old_sched;
1238 1353
1239 ip_vs_num_services--; 1354 /* Count only IPv4 services for old get/setsockopt interface */
1355 if (svc->af == AF_INET)
1356 ip_vs_num_services--;
1357
1240 ip_vs_kill_estimator(&svc->stats); 1358 ip_vs_kill_estimator(&svc->stats);
1241 1359
1242 /* Unbind scheduler */ 1360 /* Unbind scheduler */
@@ -1671,6 +1789,7 @@ static struct ip_vs_service *ip_vs_info_array(struct seq_file *seq, loff_t pos)
1671} 1789}
1672 1790
1673static void *ip_vs_info_seq_start(struct seq_file *seq, loff_t *pos) 1791static void *ip_vs_info_seq_start(struct seq_file *seq, loff_t *pos)
1792__acquires(__ip_vs_svc_lock)
1674{ 1793{
1675 1794
1676 read_lock_bh(&__ip_vs_svc_lock); 1795 read_lock_bh(&__ip_vs_svc_lock);
@@ -1724,6 +1843,7 @@ static void *ip_vs_info_seq_next(struct seq_file *seq, void *v, loff_t *pos)
1724} 1843}
1725 1844
1726static void ip_vs_info_seq_stop(struct seq_file *seq, void *v) 1845static void ip_vs_info_seq_stop(struct seq_file *seq, void *v)
1846__releases(__ip_vs_svc_lock)
1727{ 1847{
1728 read_unlock_bh(&__ip_vs_svc_lock); 1848 read_unlock_bh(&__ip_vs_svc_lock);
1729} 1849}
@@ -1744,15 +1864,25 @@ static int ip_vs_info_seq_show(struct seq_file *seq, void *v)
1744 const struct ip_vs_iter *iter = seq->private; 1864 const struct ip_vs_iter *iter = seq->private;
1745 const struct ip_vs_dest *dest; 1865 const struct ip_vs_dest *dest;
1746 1866
1747 if (iter->table == ip_vs_svc_table) 1867 if (iter->table == ip_vs_svc_table) {
1748 seq_printf(seq, "%s %08X:%04X %s ", 1868#ifdef CONFIG_IP_VS_IPV6
1749 ip_vs_proto_name(svc->protocol), 1869 if (svc->af == AF_INET6)
1750 ntohl(svc->addr), 1870 seq_printf(seq, "%s [" NIP6_FMT "]:%04X %s ",
1751 ntohs(svc->port), 1871 ip_vs_proto_name(svc->protocol),
1752 svc->scheduler->name); 1872 NIP6(svc->addr.in6),
1753 else 1873 ntohs(svc->port),
1874 svc->scheduler->name);
1875 else
1876#endif
1877 seq_printf(seq, "%s %08X:%04X %s ",
1878 ip_vs_proto_name(svc->protocol),
1879 ntohl(svc->addr.ip),
1880 ntohs(svc->port),
1881 svc->scheduler->name);
1882 } else {
1754 seq_printf(seq, "FWM %08X %s ", 1883 seq_printf(seq, "FWM %08X %s ",
1755 svc->fwmark, svc->scheduler->name); 1884 svc->fwmark, svc->scheduler->name);
1885 }
1756 1886
1757 if (svc->flags & IP_VS_SVC_F_PERSISTENT) 1887 if (svc->flags & IP_VS_SVC_F_PERSISTENT)
1758 seq_printf(seq, "persistent %d %08X\n", 1888 seq_printf(seq, "persistent %d %08X\n",
@@ -1762,13 +1892,29 @@ static int ip_vs_info_seq_show(struct seq_file *seq, void *v)
1762 seq_putc(seq, '\n'); 1892 seq_putc(seq, '\n');
1763 1893
1764 list_for_each_entry(dest, &svc->destinations, n_list) { 1894 list_for_each_entry(dest, &svc->destinations, n_list) {
1765 seq_printf(seq, 1895#ifdef CONFIG_IP_VS_IPV6
1766 " -> %08X:%04X %-7s %-6d %-10d %-10d\n", 1896 if (dest->af == AF_INET6)
1767 ntohl(dest->addr), ntohs(dest->port), 1897 seq_printf(seq,
1768 ip_vs_fwd_name(atomic_read(&dest->conn_flags)), 1898 " -> [" NIP6_FMT "]:%04X"
1769 atomic_read(&dest->weight), 1899 " %-7s %-6d %-10d %-10d\n",
1770 atomic_read(&dest->activeconns), 1900 NIP6(dest->addr.in6),
1771 atomic_read(&dest->inactconns)); 1901 ntohs(dest->port),
1902 ip_vs_fwd_name(atomic_read(&dest->conn_flags)),
1903 atomic_read(&dest->weight),
1904 atomic_read(&dest->activeconns),
1905 atomic_read(&dest->inactconns));
1906 else
1907#endif
1908 seq_printf(seq,
1909 " -> %08X:%04X "
1910 "%-7s %-6d %-10d %-10d\n",
1911 ntohl(dest->addr.ip),
1912 ntohs(dest->port),
1913 ip_vs_fwd_name(atomic_read(&dest->conn_flags)),
1914 atomic_read(&dest->weight),
1915 atomic_read(&dest->activeconns),
1916 atomic_read(&dest->inactconns));
1917
1772 } 1918 }
1773 } 1919 }
1774 return 0; 1920 return 0;
@@ -1812,20 +1958,20 @@ static int ip_vs_stats_show(struct seq_file *seq, void *v)
1812 " Conns Packets Packets Bytes Bytes\n"); 1958 " Conns Packets Packets Bytes Bytes\n");
1813 1959
1814 spin_lock_bh(&ip_vs_stats.lock); 1960 spin_lock_bh(&ip_vs_stats.lock);
1815 seq_printf(seq, "%8X %8X %8X %16LX %16LX\n\n", ip_vs_stats.conns, 1961 seq_printf(seq, "%8X %8X %8X %16LX %16LX\n\n", ip_vs_stats.ustats.conns,
1816 ip_vs_stats.inpkts, ip_vs_stats.outpkts, 1962 ip_vs_stats.ustats.inpkts, ip_vs_stats.ustats.outpkts,
1817 (unsigned long long) ip_vs_stats.inbytes, 1963 (unsigned long long) ip_vs_stats.ustats.inbytes,
1818 (unsigned long long) ip_vs_stats.outbytes); 1964 (unsigned long long) ip_vs_stats.ustats.outbytes);
1819 1965
1820/* 01234567 01234567 01234567 0123456701234567 0123456701234567 */ 1966/* 01234567 01234567 01234567 0123456701234567 0123456701234567 */
1821 seq_puts(seq, 1967 seq_puts(seq,
1822 " Conns/s Pkts/s Pkts/s Bytes/s Bytes/s\n"); 1968 " Conns/s Pkts/s Pkts/s Bytes/s Bytes/s\n");
1823 seq_printf(seq,"%8X %8X %8X %16X %16X\n", 1969 seq_printf(seq,"%8X %8X %8X %16X %16X\n",
1824 ip_vs_stats.cps, 1970 ip_vs_stats.ustats.cps,
1825 ip_vs_stats.inpps, 1971 ip_vs_stats.ustats.inpps,
1826 ip_vs_stats.outpps, 1972 ip_vs_stats.ustats.outpps,
1827 ip_vs_stats.inbps, 1973 ip_vs_stats.ustats.inbps,
1828 ip_vs_stats.outbps); 1974 ip_vs_stats.ustats.outbps);
1829 spin_unlock_bh(&ip_vs_stats.lock); 1975 spin_unlock_bh(&ip_vs_stats.lock);
1830 1976
1831 return 0; 1977 return 0;
@@ -1900,14 +2046,44 @@ static const unsigned char set_arglen[SET_CMDID(IP_VS_SO_SET_MAX)+1] = {
1900 [SET_CMDID(IP_VS_SO_SET_ZERO)] = SERVICE_ARG_LEN, 2046 [SET_CMDID(IP_VS_SO_SET_ZERO)] = SERVICE_ARG_LEN,
1901}; 2047};
1902 2048
2049static void ip_vs_copy_usvc_compat(struct ip_vs_service_user_kern *usvc,
2050 struct ip_vs_service_user *usvc_compat)
2051{
2052 usvc->af = AF_INET;
2053 usvc->protocol = usvc_compat->protocol;
2054 usvc->addr.ip = usvc_compat->addr;
2055 usvc->port = usvc_compat->port;
2056 usvc->fwmark = usvc_compat->fwmark;
2057
2058 /* Deep copy of sched_name is not needed here */
2059 usvc->sched_name = usvc_compat->sched_name;
2060
2061 usvc->flags = usvc_compat->flags;
2062 usvc->timeout = usvc_compat->timeout;
2063 usvc->netmask = usvc_compat->netmask;
2064}
2065
2066static void ip_vs_copy_udest_compat(struct ip_vs_dest_user_kern *udest,
2067 struct ip_vs_dest_user *udest_compat)
2068{
2069 udest->addr.ip = udest_compat->addr;
2070 udest->port = udest_compat->port;
2071 udest->conn_flags = udest_compat->conn_flags;
2072 udest->weight = udest_compat->weight;
2073 udest->u_threshold = udest_compat->u_threshold;
2074 udest->l_threshold = udest_compat->l_threshold;
2075}
2076
1903static int 2077static int
1904do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len) 2078do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
1905{ 2079{
1906 int ret; 2080 int ret;
1907 unsigned char arg[MAX_ARG_LEN]; 2081 unsigned char arg[MAX_ARG_LEN];
1908 struct ip_vs_service_user *usvc; 2082 struct ip_vs_service_user *usvc_compat;
2083 struct ip_vs_service_user_kern usvc;
1909 struct ip_vs_service *svc; 2084 struct ip_vs_service *svc;
1910 struct ip_vs_dest_user *udest; 2085 struct ip_vs_dest_user *udest_compat;
2086 struct ip_vs_dest_user_kern udest;
1911 2087
1912 if (!capable(CAP_NET_ADMIN)) 2088 if (!capable(CAP_NET_ADMIN))
1913 return -EPERM; 2089 return -EPERM;
@@ -1947,35 +2123,40 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
1947 goto out_unlock; 2123 goto out_unlock;
1948 } 2124 }
1949 2125
1950 usvc = (struct ip_vs_service_user *)arg; 2126 usvc_compat = (struct ip_vs_service_user *)arg;
1951 udest = (struct ip_vs_dest_user *)(usvc + 1); 2127 udest_compat = (struct ip_vs_dest_user *)(usvc_compat + 1);
2128
2129 /* We only use the new structs internally, so copy userspace compat
2130 * structs to extended internal versions */
2131 ip_vs_copy_usvc_compat(&usvc, usvc_compat);
2132 ip_vs_copy_udest_compat(&udest, udest_compat);
1952 2133
1953 if (cmd == IP_VS_SO_SET_ZERO) { 2134 if (cmd == IP_VS_SO_SET_ZERO) {
1954 /* if no service address is set, zero counters in all */ 2135 /* if no service address is set, zero counters in all */
1955 if (!usvc->fwmark && !usvc->addr && !usvc->port) { 2136 if (!usvc.fwmark && !usvc.addr.ip && !usvc.port) {
1956 ret = ip_vs_zero_all(); 2137 ret = ip_vs_zero_all();
1957 goto out_unlock; 2138 goto out_unlock;
1958 } 2139 }
1959 } 2140 }
1960 2141
1961 /* Check for valid protocol: TCP or UDP, even for fwmark!=0 */ 2142 /* Check for valid protocol: TCP or UDP, even for fwmark!=0 */
1962 if (usvc->protocol!=IPPROTO_TCP && usvc->protocol!=IPPROTO_UDP) { 2143 if (usvc.protocol != IPPROTO_TCP && usvc.protocol != IPPROTO_UDP) {
1963 IP_VS_ERR("set_ctl: invalid protocol: %d %d.%d.%d.%d:%d %s\n", 2144 IP_VS_ERR("set_ctl: invalid protocol: %d %d.%d.%d.%d:%d %s\n",
1964 usvc->protocol, NIPQUAD(usvc->addr), 2145 usvc.protocol, NIPQUAD(usvc.addr.ip),
1965 ntohs(usvc->port), usvc->sched_name); 2146 ntohs(usvc.port), usvc.sched_name);
1966 ret = -EFAULT; 2147 ret = -EFAULT;
1967 goto out_unlock; 2148 goto out_unlock;
1968 } 2149 }
1969 2150
1970 /* Lookup the exact service by <protocol, addr, port> or fwmark */ 2151 /* Lookup the exact service by <protocol, addr, port> or fwmark */
1971 if (usvc->fwmark == 0) 2152 if (usvc.fwmark == 0)
1972 svc = __ip_vs_service_get(usvc->protocol, 2153 svc = __ip_vs_service_get(usvc.af, usvc.protocol,
1973 usvc->addr, usvc->port); 2154 &usvc.addr, usvc.port);
1974 else 2155 else
1975 svc = __ip_vs_svc_fwm_get(usvc->fwmark); 2156 svc = __ip_vs_svc_fwm_get(usvc.af, usvc.fwmark);
1976 2157
1977 if (cmd != IP_VS_SO_SET_ADD 2158 if (cmd != IP_VS_SO_SET_ADD
1978 && (svc == NULL || svc->protocol != usvc->protocol)) { 2159 && (svc == NULL || svc->protocol != usvc.protocol)) {
1979 ret = -ESRCH; 2160 ret = -ESRCH;
1980 goto out_unlock; 2161 goto out_unlock;
1981 } 2162 }
@@ -1985,10 +2166,10 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
1985 if (svc != NULL) 2166 if (svc != NULL)
1986 ret = -EEXIST; 2167 ret = -EEXIST;
1987 else 2168 else
1988 ret = ip_vs_add_service(usvc, &svc); 2169 ret = ip_vs_add_service(&usvc, &svc);
1989 break; 2170 break;
1990 case IP_VS_SO_SET_EDIT: 2171 case IP_VS_SO_SET_EDIT:
1991 ret = ip_vs_edit_service(svc, usvc); 2172 ret = ip_vs_edit_service(svc, &usvc);
1992 break; 2173 break;
1993 case IP_VS_SO_SET_DEL: 2174 case IP_VS_SO_SET_DEL:
1994 ret = ip_vs_del_service(svc); 2175 ret = ip_vs_del_service(svc);
@@ -1999,13 +2180,13 @@ do_ip_vs_set_ctl(struct sock *sk, int cmd, void __user *user, unsigned int len)
1999 ret = ip_vs_zero_service(svc); 2180 ret = ip_vs_zero_service(svc);
2000 break; 2181 break;
2001 case IP_VS_SO_SET_ADDDEST: 2182 case IP_VS_SO_SET_ADDDEST:
2002 ret = ip_vs_add_dest(svc, udest); 2183 ret = ip_vs_add_dest(svc, &udest);
2003 break; 2184 break;
2004 case IP_VS_SO_SET_EDITDEST: 2185 case IP_VS_SO_SET_EDITDEST:
2005 ret = ip_vs_edit_dest(svc, udest); 2186 ret = ip_vs_edit_dest(svc, &udest);
2006 break; 2187 break;
2007 case IP_VS_SO_SET_DELDEST: 2188 case IP_VS_SO_SET_DELDEST:
2008 ret = ip_vs_del_dest(svc, udest); 2189 ret = ip_vs_del_dest(svc, &udest);
2009 break; 2190 break;
2010 default: 2191 default:
2011 ret = -EINVAL; 2192 ret = -EINVAL;
@@ -2028,7 +2209,7 @@ static void
2028ip_vs_copy_stats(struct ip_vs_stats_user *dst, struct ip_vs_stats *src) 2209ip_vs_copy_stats(struct ip_vs_stats_user *dst, struct ip_vs_stats *src)
2029{ 2210{
2030 spin_lock_bh(&src->lock); 2211 spin_lock_bh(&src->lock);
2031 memcpy(dst, src, (char*)&src->lock - (char*)src); 2212 memcpy(dst, &src->ustats, sizeof(*dst));
2032 spin_unlock_bh(&src->lock); 2213 spin_unlock_bh(&src->lock);
2033} 2214}
2034 2215
@@ -2036,7 +2217,7 @@ static void
2036ip_vs_copy_service(struct ip_vs_service_entry *dst, struct ip_vs_service *src) 2217ip_vs_copy_service(struct ip_vs_service_entry *dst, struct ip_vs_service *src)
2037{ 2218{
2038 dst->protocol = src->protocol; 2219 dst->protocol = src->protocol;
2039 dst->addr = src->addr; 2220 dst->addr = src->addr.ip;
2040 dst->port = src->port; 2221 dst->port = src->port;
2041 dst->fwmark = src->fwmark; 2222 dst->fwmark = src->fwmark;
2042 strlcpy(dst->sched_name, src->scheduler->name, sizeof(dst->sched_name)); 2223 strlcpy(dst->sched_name, src->scheduler->name, sizeof(dst->sched_name));
@@ -2058,6 +2239,10 @@ __ip_vs_get_service_entries(const struct ip_vs_get_services *get,
2058 2239
2059 for (idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) { 2240 for (idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
2060 list_for_each_entry(svc, &ip_vs_svc_table[idx], s_list) { 2241 list_for_each_entry(svc, &ip_vs_svc_table[idx], s_list) {
2242 /* Only expose IPv4 entries to old interface */
2243 if (svc->af != AF_INET)
2244 continue;
2245
2061 if (count >= get->num_services) 2246 if (count >= get->num_services)
2062 goto out; 2247 goto out;
2063 memset(&entry, 0, sizeof(entry)); 2248 memset(&entry, 0, sizeof(entry));
@@ -2073,6 +2258,10 @@ __ip_vs_get_service_entries(const struct ip_vs_get_services *get,
2073 2258
2074 for (idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) { 2259 for (idx = 0; idx < IP_VS_SVC_TAB_SIZE; idx++) {
2075 list_for_each_entry(svc, &ip_vs_svc_fwm_table[idx], f_list) { 2260 list_for_each_entry(svc, &ip_vs_svc_fwm_table[idx], f_list) {
2261 /* Only expose IPv4 entries to old interface */
2262 if (svc->af != AF_INET)
2263 continue;
2264
2076 if (count >= get->num_services) 2265 if (count >= get->num_services)
2077 goto out; 2266 goto out;
2078 memset(&entry, 0, sizeof(entry)); 2267 memset(&entry, 0, sizeof(entry));
@@ -2094,13 +2283,15 @@ __ip_vs_get_dest_entries(const struct ip_vs_get_dests *get,
2094 struct ip_vs_get_dests __user *uptr) 2283 struct ip_vs_get_dests __user *uptr)
2095{ 2284{
2096 struct ip_vs_service *svc; 2285 struct ip_vs_service *svc;
2286 union nf_inet_addr addr = { .ip = get->addr };
2097 int ret = 0; 2287 int ret = 0;
2098 2288
2099 if (get->fwmark) 2289 if (get->fwmark)
2100 svc = __ip_vs_svc_fwm_get(get->fwmark); 2290 svc = __ip_vs_svc_fwm_get(AF_INET, get->fwmark);
2101 else 2291 else
2102 svc = __ip_vs_service_get(get->protocol, 2292 svc = __ip_vs_service_get(AF_INET, get->protocol, &addr,
2103 get->addr, get->port); 2293 get->port);
2294
2104 if (svc) { 2295 if (svc) {
2105 int count = 0; 2296 int count = 0;
2106 struct ip_vs_dest *dest; 2297 struct ip_vs_dest *dest;
@@ -2110,7 +2301,7 @@ __ip_vs_get_dest_entries(const struct ip_vs_get_dests *get,
2110 if (count >= get->num_dests) 2301 if (count >= get->num_dests)
2111 break; 2302 break;
2112 2303
2113 entry.addr = dest->addr; 2304 entry.addr = dest->addr.ip;
2114 entry.port = dest->port; 2305 entry.port = dest->port;
2115 entry.conn_flags = atomic_read(&dest->conn_flags); 2306 entry.conn_flags = atomic_read(&dest->conn_flags);
2116 entry.weight = atomic_read(&dest->weight); 2307 entry.weight = atomic_read(&dest->weight);
@@ -2235,13 +2426,15 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len)
2235 { 2426 {
2236 struct ip_vs_service_entry *entry; 2427 struct ip_vs_service_entry *entry;
2237 struct ip_vs_service *svc; 2428 struct ip_vs_service *svc;
2429 union nf_inet_addr addr;
2238 2430
2239 entry = (struct ip_vs_service_entry *)arg; 2431 entry = (struct ip_vs_service_entry *)arg;
2432 addr.ip = entry->addr;
2240 if (entry->fwmark) 2433 if (entry->fwmark)
2241 svc = __ip_vs_svc_fwm_get(entry->fwmark); 2434 svc = __ip_vs_svc_fwm_get(AF_INET, entry->fwmark);
2242 else 2435 else
2243 svc = __ip_vs_service_get(entry->protocol, 2436 svc = __ip_vs_service_get(AF_INET, entry->protocol,
2244 entry->addr, entry->port); 2437 &addr, entry->port);
2245 if (svc) { 2438 if (svc) {
2246 ip_vs_copy_service(entry, svc); 2439 ip_vs_copy_service(entry, svc);
2247 if (copy_to_user(user, entry, sizeof(*entry)) != 0) 2440 if (copy_to_user(user, entry, sizeof(*entry)) != 0)
@@ -2320,6 +2513,875 @@ static struct nf_sockopt_ops ip_vs_sockopts = {
2320 .owner = THIS_MODULE, 2513 .owner = THIS_MODULE,
2321}; 2514};
2322 2515
2516/*
2517 * Generic Netlink interface
2518 */
2519
2520/* IPVS genetlink family */
2521static struct genl_family ip_vs_genl_family = {
2522 .id = GENL_ID_GENERATE,
2523 .hdrsize = 0,
2524 .name = IPVS_GENL_NAME,
2525 .version = IPVS_GENL_VERSION,
2526 .maxattr = IPVS_CMD_MAX,
2527};
2528
2529/* Policy used for first-level command attributes */
2530static const struct nla_policy ip_vs_cmd_policy[IPVS_CMD_ATTR_MAX + 1] = {
2531 [IPVS_CMD_ATTR_SERVICE] = { .type = NLA_NESTED },
2532 [IPVS_CMD_ATTR_DEST] = { .type = NLA_NESTED },
2533 [IPVS_CMD_ATTR_DAEMON] = { .type = NLA_NESTED },
2534 [IPVS_CMD_ATTR_TIMEOUT_TCP] = { .type = NLA_U32 },
2535 [IPVS_CMD_ATTR_TIMEOUT_TCP_FIN] = { .type = NLA_U32 },
2536 [IPVS_CMD_ATTR_TIMEOUT_UDP] = { .type = NLA_U32 },
2537};
2538
2539/* Policy used for attributes in nested attribute IPVS_CMD_ATTR_DAEMON */
2540static const struct nla_policy ip_vs_daemon_policy[IPVS_DAEMON_ATTR_MAX + 1] = {
2541 [IPVS_DAEMON_ATTR_STATE] = { .type = NLA_U32 },
2542 [IPVS_DAEMON_ATTR_MCAST_IFN] = { .type = NLA_NUL_STRING,
2543 .len = IP_VS_IFNAME_MAXLEN },
2544 [IPVS_DAEMON_ATTR_SYNC_ID] = { .type = NLA_U32 },
2545};
2546
2547/* Policy used for attributes in nested attribute IPVS_CMD_ATTR_SERVICE */
2548static const struct nla_policy ip_vs_svc_policy[IPVS_SVC_ATTR_MAX + 1] = {
2549 [IPVS_SVC_ATTR_AF] = { .type = NLA_U16 },
2550 [IPVS_SVC_ATTR_PROTOCOL] = { .type = NLA_U16 },
2551 [IPVS_SVC_ATTR_ADDR] = { .type = NLA_BINARY,
2552 .len = sizeof(union nf_inet_addr) },
2553 [IPVS_SVC_ATTR_PORT] = { .type = NLA_U16 },
2554 [IPVS_SVC_ATTR_FWMARK] = { .type = NLA_U32 },
2555 [IPVS_SVC_ATTR_SCHED_NAME] = { .type = NLA_NUL_STRING,
2556 .len = IP_VS_SCHEDNAME_MAXLEN },
2557 [IPVS_SVC_ATTR_FLAGS] = { .type = NLA_BINARY,
2558 .len = sizeof(struct ip_vs_flags) },
2559 [IPVS_SVC_ATTR_TIMEOUT] = { .type = NLA_U32 },
2560 [IPVS_SVC_ATTR_NETMASK] = { .type = NLA_U32 },
2561 [IPVS_SVC_ATTR_STATS] = { .type = NLA_NESTED },
2562};
2563
2564/* Policy used for attributes in nested attribute IPVS_CMD_ATTR_DEST */
2565static const struct nla_policy ip_vs_dest_policy[IPVS_DEST_ATTR_MAX + 1] = {
2566 [IPVS_DEST_ATTR_ADDR] = { .type = NLA_BINARY,
2567 .len = sizeof(union nf_inet_addr) },
2568 [IPVS_DEST_ATTR_PORT] = { .type = NLA_U16 },
2569 [IPVS_DEST_ATTR_FWD_METHOD] = { .type = NLA_U32 },
2570 [IPVS_DEST_ATTR_WEIGHT] = { .type = NLA_U32 },
2571 [IPVS_DEST_ATTR_U_THRESH] = { .type = NLA_U32 },
2572 [IPVS_DEST_ATTR_L_THRESH] = { .type = NLA_U32 },
2573 [IPVS_DEST_ATTR_ACTIVE_CONNS] = { .type = NLA_U32 },
2574 [IPVS_DEST_ATTR_INACT_CONNS] = { .type = NLA_U32 },
2575 [IPVS_DEST_ATTR_PERSIST_CONNS] = { .type = NLA_U32 },
2576 [IPVS_DEST_ATTR_STATS] = { .type = NLA_NESTED },
2577};
2578
2579static int ip_vs_genl_fill_stats(struct sk_buff *skb, int container_type,
2580 struct ip_vs_stats *stats)
2581{
2582 struct nlattr *nl_stats = nla_nest_start(skb, container_type);
2583 if (!nl_stats)
2584 return -EMSGSIZE;
2585
2586 spin_lock_bh(&stats->lock);
2587
2588 NLA_PUT_U32(skb, IPVS_STATS_ATTR_CONNS, stats->ustats.conns);
2589 NLA_PUT_U32(skb, IPVS_STATS_ATTR_INPKTS, stats->ustats.inpkts);
2590 NLA_PUT_U32(skb, IPVS_STATS_ATTR_OUTPKTS, stats->ustats.outpkts);
2591 NLA_PUT_U64(skb, IPVS_STATS_ATTR_INBYTES, stats->ustats.inbytes);
2592 NLA_PUT_U64(skb, IPVS_STATS_ATTR_OUTBYTES, stats->ustats.outbytes);
2593 NLA_PUT_U32(skb, IPVS_STATS_ATTR_CPS, stats->ustats.cps);
2594 NLA_PUT_U32(skb, IPVS_STATS_ATTR_INPPS, stats->ustats.inpps);
2595 NLA_PUT_U32(skb, IPVS_STATS_ATTR_OUTPPS, stats->ustats.outpps);
2596 NLA_PUT_U32(skb, IPVS_STATS_ATTR_INBPS, stats->ustats.inbps);
2597 NLA_PUT_U32(skb, IPVS_STATS_ATTR_OUTBPS, stats->ustats.outbps);
2598
2599 spin_unlock_bh(&stats->lock);
2600
2601 nla_nest_end(skb, nl_stats);
2602
2603 return 0;
2604
2605nla_put_failure:
2606 spin_unlock_bh(&stats->lock);
2607 nla_nest_cancel(skb, nl_stats);
2608 return -EMSGSIZE;
2609}
2610
2611static int ip_vs_genl_fill_service(struct sk_buff *skb,
2612 struct ip_vs_service *svc)
2613{
2614 struct nlattr *nl_service;
2615 struct ip_vs_flags flags = { .flags = svc->flags,
2616 .mask = ~0 };
2617
2618 nl_service = nla_nest_start(skb, IPVS_CMD_ATTR_SERVICE);
2619 if (!nl_service)
2620 return -EMSGSIZE;
2621
2622 NLA_PUT_U16(skb, IPVS_SVC_ATTR_AF, svc->af);
2623
2624 if (svc->fwmark) {
2625 NLA_PUT_U32(skb, IPVS_SVC_ATTR_FWMARK, svc->fwmark);
2626 } else {
2627 NLA_PUT_U16(skb, IPVS_SVC_ATTR_PROTOCOL, svc->protocol);
2628 NLA_PUT(skb, IPVS_SVC_ATTR_ADDR, sizeof(svc->addr), &svc->addr);
2629 NLA_PUT_U16(skb, IPVS_SVC_ATTR_PORT, svc->port);
2630 }
2631
2632 NLA_PUT_STRING(skb, IPVS_SVC_ATTR_SCHED_NAME, svc->scheduler->name);
2633 NLA_PUT(skb, IPVS_SVC_ATTR_FLAGS, sizeof(flags), &flags);
2634 NLA_PUT_U32(skb, IPVS_SVC_ATTR_TIMEOUT, svc->timeout / HZ);
2635 NLA_PUT_U32(skb, IPVS_SVC_ATTR_NETMASK, svc->netmask);
2636
2637 if (ip_vs_genl_fill_stats(skb, IPVS_SVC_ATTR_STATS, &svc->stats))
2638 goto nla_put_failure;
2639
2640 nla_nest_end(skb, nl_service);
2641
2642 return 0;
2643
2644nla_put_failure:
2645 nla_nest_cancel(skb, nl_service);
2646 return -EMSGSIZE;
2647}
2648
2649static int ip_vs_genl_dump_service(struct sk_buff *skb,
2650 struct ip_vs_service *svc,
2651 struct netlink_callback *cb)
2652{
2653 void *hdr;
2654
2655 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
2656 &ip_vs_genl_family, NLM_F_MULTI,
2657 IPVS_CMD_NEW_SERVICE);
2658 if (!hdr)
2659 return -EMSGSIZE;
2660
2661 if (ip_vs_genl_fill_service(skb, svc) < 0)
2662 goto nla_put_failure;
2663
2664 return genlmsg_end(skb, hdr);
2665
2666nla_put_failure:
2667 genlmsg_cancel(skb, hdr);
2668 return -EMSGSIZE;
2669}
2670
2671static int ip_vs_genl_dump_services(struct sk_buff *skb,
2672 struct netlink_callback *cb)
2673{
2674 int idx = 0, i;
2675 int start = cb->args[0];
2676 struct ip_vs_service *svc;
2677
2678 mutex_lock(&__ip_vs_mutex);
2679 for (i = 0; i < IP_VS_SVC_TAB_SIZE; i++) {
2680 list_for_each_entry(svc, &ip_vs_svc_table[i], s_list) {
2681 if (++idx <= start)
2682 continue;
2683 if (ip_vs_genl_dump_service(skb, svc, cb) < 0) {
2684 idx--;
2685 goto nla_put_failure;
2686 }
2687 }
2688 }
2689
2690 for (i = 0; i < IP_VS_SVC_TAB_SIZE; i++) {
2691 list_for_each_entry(svc, &ip_vs_svc_fwm_table[i], f_list) {
2692 if (++idx <= start)
2693 continue;
2694 if (ip_vs_genl_dump_service(skb, svc, cb) < 0) {
2695 idx--;
2696 goto nla_put_failure;
2697 }
2698 }
2699 }
2700
2701nla_put_failure:
2702 mutex_unlock(&__ip_vs_mutex);
2703 cb->args[0] = idx;
2704
2705 return skb->len;
2706}
2707
2708static int ip_vs_genl_parse_service(struct ip_vs_service_user_kern *usvc,
2709 struct nlattr *nla, int full_entry)
2710{
2711 struct nlattr *attrs[IPVS_SVC_ATTR_MAX + 1];
2712 struct nlattr *nla_af, *nla_port, *nla_fwmark, *nla_protocol, *nla_addr;
2713
2714 /* Parse mandatory identifying service fields first */
2715 if (nla == NULL ||
2716 nla_parse_nested(attrs, IPVS_SVC_ATTR_MAX, nla, ip_vs_svc_policy))
2717 return -EINVAL;
2718
2719 nla_af = attrs[IPVS_SVC_ATTR_AF];
2720 nla_protocol = attrs[IPVS_SVC_ATTR_PROTOCOL];
2721 nla_addr = attrs[IPVS_SVC_ATTR_ADDR];
2722 nla_port = attrs[IPVS_SVC_ATTR_PORT];
2723 nla_fwmark = attrs[IPVS_SVC_ATTR_FWMARK];
2724
2725 if (!(nla_af && (nla_fwmark || (nla_port && nla_protocol && nla_addr))))
2726 return -EINVAL;
2727
2728 usvc->af = nla_get_u16(nla_af);
2729#ifdef CONFIG_IP_VS_IPV6
2730 if (usvc->af != AF_INET && usvc->af != AF_INET6)
2731#else
2732 if (usvc->af != AF_INET)
2733#endif
2734 return -EAFNOSUPPORT;
2735
2736 if (nla_fwmark) {
2737 usvc->protocol = IPPROTO_TCP;
2738 usvc->fwmark = nla_get_u32(nla_fwmark);
2739 } else {
2740 usvc->protocol = nla_get_u16(nla_protocol);
2741 nla_memcpy(&usvc->addr, nla_addr, sizeof(usvc->addr));
2742 usvc->port = nla_get_u16(nla_port);
2743 usvc->fwmark = 0;
2744 }
2745
2746 /* If a full entry was requested, check for the additional fields */
2747 if (full_entry) {
2748 struct nlattr *nla_sched, *nla_flags, *nla_timeout,
2749 *nla_netmask;
2750 struct ip_vs_flags flags;
2751 struct ip_vs_service *svc;
2752
2753 nla_sched = attrs[IPVS_SVC_ATTR_SCHED_NAME];
2754 nla_flags = attrs[IPVS_SVC_ATTR_FLAGS];
2755 nla_timeout = attrs[IPVS_SVC_ATTR_TIMEOUT];
2756 nla_netmask = attrs[IPVS_SVC_ATTR_NETMASK];
2757
2758 if (!(nla_sched && nla_flags && nla_timeout && nla_netmask))
2759 return -EINVAL;
2760
2761 nla_memcpy(&flags, nla_flags, sizeof(flags));
2762
2763 /* prefill flags from service if it already exists */
2764 if (usvc->fwmark)
2765 svc = __ip_vs_svc_fwm_get(usvc->af, usvc->fwmark);
2766 else
2767 svc = __ip_vs_service_get(usvc->af, usvc->protocol,
2768 &usvc->addr, usvc->port);
2769 if (svc) {
2770 usvc->flags = svc->flags;
2771 ip_vs_service_put(svc);
2772 } else
2773 usvc->flags = 0;
2774
2775 /* set new flags from userland */
2776 usvc->flags = (usvc->flags & ~flags.mask) |
2777 (flags.flags & flags.mask);
2778 usvc->sched_name = nla_data(nla_sched);
2779 usvc->timeout = nla_get_u32(nla_timeout);
2780 usvc->netmask = nla_get_u32(nla_netmask);
2781 }
2782
2783 return 0;
2784}
2785
2786static struct ip_vs_service *ip_vs_genl_find_service(struct nlattr *nla)
2787{
2788 struct ip_vs_service_user_kern usvc;
2789 int ret;
2790
2791 ret = ip_vs_genl_parse_service(&usvc, nla, 0);
2792 if (ret)
2793 return ERR_PTR(ret);
2794
2795 if (usvc.fwmark)
2796 return __ip_vs_svc_fwm_get(usvc.af, usvc.fwmark);
2797 else
2798 return __ip_vs_service_get(usvc.af, usvc.protocol,
2799 &usvc.addr, usvc.port);
2800}
2801
2802static int ip_vs_genl_fill_dest(struct sk_buff *skb, struct ip_vs_dest *dest)
2803{
2804 struct nlattr *nl_dest;
2805
2806 nl_dest = nla_nest_start(skb, IPVS_CMD_ATTR_DEST);
2807 if (!nl_dest)
2808 return -EMSGSIZE;
2809
2810 NLA_PUT(skb, IPVS_DEST_ATTR_ADDR, sizeof(dest->addr), &dest->addr);
2811 NLA_PUT_U16(skb, IPVS_DEST_ATTR_PORT, dest->port);
2812
2813 NLA_PUT_U32(skb, IPVS_DEST_ATTR_FWD_METHOD,
2814 atomic_read(&dest->conn_flags) & IP_VS_CONN_F_FWD_MASK);
2815 NLA_PUT_U32(skb, IPVS_DEST_ATTR_WEIGHT, atomic_read(&dest->weight));
2816 NLA_PUT_U32(skb, IPVS_DEST_ATTR_U_THRESH, dest->u_threshold);
2817 NLA_PUT_U32(skb, IPVS_DEST_ATTR_L_THRESH, dest->l_threshold);
2818 NLA_PUT_U32(skb, IPVS_DEST_ATTR_ACTIVE_CONNS,
2819 atomic_read(&dest->activeconns));
2820 NLA_PUT_U32(skb, IPVS_DEST_ATTR_INACT_CONNS,
2821 atomic_read(&dest->inactconns));
2822 NLA_PUT_U32(skb, IPVS_DEST_ATTR_PERSIST_CONNS,
2823 atomic_read(&dest->persistconns));
2824
2825 if (ip_vs_genl_fill_stats(skb, IPVS_DEST_ATTR_STATS, &dest->stats))
2826 goto nla_put_failure;
2827
2828 nla_nest_end(skb, nl_dest);
2829
2830 return 0;
2831
2832nla_put_failure:
2833 nla_nest_cancel(skb, nl_dest);
2834 return -EMSGSIZE;
2835}
2836
2837static int ip_vs_genl_dump_dest(struct sk_buff *skb, struct ip_vs_dest *dest,
2838 struct netlink_callback *cb)
2839{
2840 void *hdr;
2841
2842 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
2843 &ip_vs_genl_family, NLM_F_MULTI,
2844 IPVS_CMD_NEW_DEST);
2845 if (!hdr)
2846 return -EMSGSIZE;
2847
2848 if (ip_vs_genl_fill_dest(skb, dest) < 0)
2849 goto nla_put_failure;
2850
2851 return genlmsg_end(skb, hdr);
2852
2853nla_put_failure:
2854 genlmsg_cancel(skb, hdr);
2855 return -EMSGSIZE;
2856}
2857
2858static int ip_vs_genl_dump_dests(struct sk_buff *skb,
2859 struct netlink_callback *cb)
2860{
2861 int idx = 0;
2862 int start = cb->args[0];
2863 struct ip_vs_service *svc;
2864 struct ip_vs_dest *dest;
2865 struct nlattr *attrs[IPVS_CMD_ATTR_MAX + 1];
2866
2867 mutex_lock(&__ip_vs_mutex);
2868
2869 /* Try to find the service for which to dump destinations */
2870 if (nlmsg_parse(cb->nlh, GENL_HDRLEN, attrs,
2871 IPVS_CMD_ATTR_MAX, ip_vs_cmd_policy))
2872 goto out_err;
2873
2874 svc = ip_vs_genl_find_service(attrs[IPVS_CMD_ATTR_SERVICE]);
2875 if (IS_ERR(svc) || svc == NULL)
2876 goto out_err;
2877
2878 /* Dump the destinations */
2879 list_for_each_entry(dest, &svc->destinations, n_list) {
2880 if (++idx <= start)
2881 continue;
2882 if (ip_vs_genl_dump_dest(skb, dest, cb) < 0) {
2883 idx--;
2884 goto nla_put_failure;
2885 }
2886 }
2887
2888nla_put_failure:
2889 cb->args[0] = idx;
2890 ip_vs_service_put(svc);
2891
2892out_err:
2893 mutex_unlock(&__ip_vs_mutex);
2894
2895 return skb->len;
2896}
2897
2898static int ip_vs_genl_parse_dest(struct ip_vs_dest_user_kern *udest,
2899 struct nlattr *nla, int full_entry)
2900{
2901 struct nlattr *attrs[IPVS_DEST_ATTR_MAX + 1];
2902 struct nlattr *nla_addr, *nla_port;
2903
2904 /* Parse mandatory identifying destination fields first */
2905 if (nla == NULL ||
2906 nla_parse_nested(attrs, IPVS_DEST_ATTR_MAX, nla, ip_vs_dest_policy))
2907 return -EINVAL;
2908
2909 nla_addr = attrs[IPVS_DEST_ATTR_ADDR];
2910 nla_port = attrs[IPVS_DEST_ATTR_PORT];
2911
2912 if (!(nla_addr && nla_port))
2913 return -EINVAL;
2914
2915 nla_memcpy(&udest->addr, nla_addr, sizeof(udest->addr));
2916 udest->port = nla_get_u16(nla_port);
2917
2918 /* If a full entry was requested, check for the additional fields */
2919 if (full_entry) {
2920 struct nlattr *nla_fwd, *nla_weight, *nla_u_thresh,
2921 *nla_l_thresh;
2922
2923 nla_fwd = attrs[IPVS_DEST_ATTR_FWD_METHOD];
2924 nla_weight = attrs[IPVS_DEST_ATTR_WEIGHT];
2925 nla_u_thresh = attrs[IPVS_DEST_ATTR_U_THRESH];
2926 nla_l_thresh = attrs[IPVS_DEST_ATTR_L_THRESH];
2927
2928 if (!(nla_fwd && nla_weight && nla_u_thresh && nla_l_thresh))
2929 return -EINVAL;
2930
2931 udest->conn_flags = nla_get_u32(nla_fwd)
2932 & IP_VS_CONN_F_FWD_MASK;
2933 udest->weight = nla_get_u32(nla_weight);
2934 udest->u_threshold = nla_get_u32(nla_u_thresh);
2935 udest->l_threshold = nla_get_u32(nla_l_thresh);
2936 }
2937
2938 return 0;
2939}
2940
2941static int ip_vs_genl_fill_daemon(struct sk_buff *skb, __be32 state,
2942 const char *mcast_ifn, __be32 syncid)
2943{
2944 struct nlattr *nl_daemon;
2945
2946 nl_daemon = nla_nest_start(skb, IPVS_CMD_ATTR_DAEMON);
2947 if (!nl_daemon)
2948 return -EMSGSIZE;
2949
2950 NLA_PUT_U32(skb, IPVS_DAEMON_ATTR_STATE, state);
2951 NLA_PUT_STRING(skb, IPVS_DAEMON_ATTR_MCAST_IFN, mcast_ifn);
2952 NLA_PUT_U32(skb, IPVS_DAEMON_ATTR_SYNC_ID, syncid);
2953
2954 nla_nest_end(skb, nl_daemon);
2955
2956 return 0;
2957
2958nla_put_failure:
2959 nla_nest_cancel(skb, nl_daemon);
2960 return -EMSGSIZE;
2961}
2962
2963static int ip_vs_genl_dump_daemon(struct sk_buff *skb, __be32 state,
2964 const char *mcast_ifn, __be32 syncid,
2965 struct netlink_callback *cb)
2966{
2967 void *hdr;
2968 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
2969 &ip_vs_genl_family, NLM_F_MULTI,
2970 IPVS_CMD_NEW_DAEMON);
2971 if (!hdr)
2972 return -EMSGSIZE;
2973
2974 if (ip_vs_genl_fill_daemon(skb, state, mcast_ifn, syncid))
2975 goto nla_put_failure;
2976
2977 return genlmsg_end(skb, hdr);
2978
2979nla_put_failure:
2980 genlmsg_cancel(skb, hdr);
2981 return -EMSGSIZE;
2982}
2983
2984static int ip_vs_genl_dump_daemons(struct sk_buff *skb,
2985 struct netlink_callback *cb)
2986{
2987 mutex_lock(&__ip_vs_mutex);
2988 if ((ip_vs_sync_state & IP_VS_STATE_MASTER) && !cb->args[0]) {
2989 if (ip_vs_genl_dump_daemon(skb, IP_VS_STATE_MASTER,
2990 ip_vs_master_mcast_ifn,
2991 ip_vs_master_syncid, cb) < 0)
2992 goto nla_put_failure;
2993
2994 cb->args[0] = 1;
2995 }
2996
2997 if ((ip_vs_sync_state & IP_VS_STATE_BACKUP) && !cb->args[1]) {
2998 if (ip_vs_genl_dump_daemon(skb, IP_VS_STATE_BACKUP,
2999 ip_vs_backup_mcast_ifn,
3000 ip_vs_backup_syncid, cb) < 0)
3001 goto nla_put_failure;
3002
3003 cb->args[1] = 1;
3004 }
3005
3006nla_put_failure:
3007 mutex_unlock(&__ip_vs_mutex);
3008
3009 return skb->len;
3010}
3011
3012static int ip_vs_genl_new_daemon(struct nlattr **attrs)
3013{
3014 if (!(attrs[IPVS_DAEMON_ATTR_STATE] &&
3015 attrs[IPVS_DAEMON_ATTR_MCAST_IFN] &&
3016 attrs[IPVS_DAEMON_ATTR_SYNC_ID]))
3017 return -EINVAL;
3018
3019 return start_sync_thread(nla_get_u32(attrs[IPVS_DAEMON_ATTR_STATE]),
3020 nla_data(attrs[IPVS_DAEMON_ATTR_MCAST_IFN]),
3021 nla_get_u32(attrs[IPVS_DAEMON_ATTR_SYNC_ID]));
3022}
3023
3024static int ip_vs_genl_del_daemon(struct nlattr **attrs)
3025{
3026 if (!attrs[IPVS_DAEMON_ATTR_STATE])
3027 return -EINVAL;
3028
3029 return stop_sync_thread(nla_get_u32(attrs[IPVS_DAEMON_ATTR_STATE]));
3030}
3031
3032static int ip_vs_genl_set_config(struct nlattr **attrs)
3033{
3034 struct ip_vs_timeout_user t;
3035
3036 __ip_vs_get_timeouts(&t);
3037
3038 if (attrs[IPVS_CMD_ATTR_TIMEOUT_TCP])
3039 t.tcp_timeout = nla_get_u32(attrs[IPVS_CMD_ATTR_TIMEOUT_TCP]);
3040
3041 if (attrs[IPVS_CMD_ATTR_TIMEOUT_TCP_FIN])
3042 t.tcp_fin_timeout =
3043 nla_get_u32(attrs[IPVS_CMD_ATTR_TIMEOUT_TCP_FIN]);
3044
3045 if (attrs[IPVS_CMD_ATTR_TIMEOUT_UDP])
3046 t.udp_timeout = nla_get_u32(attrs[IPVS_CMD_ATTR_TIMEOUT_UDP]);
3047
3048 return ip_vs_set_timeout(&t);
3049}
3050
3051static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info)
3052{
3053 struct ip_vs_service *svc = NULL;
3054 struct ip_vs_service_user_kern usvc;
3055 struct ip_vs_dest_user_kern udest;
3056 int ret = 0, cmd;
3057 int need_full_svc = 0, need_full_dest = 0;
3058
3059 cmd = info->genlhdr->cmd;
3060
3061 mutex_lock(&__ip_vs_mutex);
3062
3063 if (cmd == IPVS_CMD_FLUSH) {
3064 ret = ip_vs_flush();
3065 goto out;
3066 } else if (cmd == IPVS_CMD_SET_CONFIG) {
3067 ret = ip_vs_genl_set_config(info->attrs);
3068 goto out;
3069 } else if (cmd == IPVS_CMD_NEW_DAEMON ||
3070 cmd == IPVS_CMD_DEL_DAEMON) {
3071
3072 struct nlattr *daemon_attrs[IPVS_DAEMON_ATTR_MAX + 1];
3073
3074 if (!info->attrs[IPVS_CMD_ATTR_DAEMON] ||
3075 nla_parse_nested(daemon_attrs, IPVS_DAEMON_ATTR_MAX,
3076 info->attrs[IPVS_CMD_ATTR_DAEMON],
3077 ip_vs_daemon_policy)) {
3078 ret = -EINVAL;
3079 goto out;
3080 }
3081
3082 if (cmd == IPVS_CMD_NEW_DAEMON)
3083 ret = ip_vs_genl_new_daemon(daemon_attrs);
3084 else
3085 ret = ip_vs_genl_del_daemon(daemon_attrs);
3086 goto out;
3087 } else if (cmd == IPVS_CMD_ZERO &&
3088 !info->attrs[IPVS_CMD_ATTR_SERVICE]) {
3089 ret = ip_vs_zero_all();
3090 goto out;
3091 }
3092
3093 /* All following commands require a service argument, so check if we
3094 * received a valid one. We need a full service specification when
3095 * adding / editing a service. Only identifying members otherwise. */
3096 if (cmd == IPVS_CMD_NEW_SERVICE || cmd == IPVS_CMD_SET_SERVICE)
3097 need_full_svc = 1;
3098
3099 ret = ip_vs_genl_parse_service(&usvc,
3100 info->attrs[IPVS_CMD_ATTR_SERVICE],
3101 need_full_svc);
3102 if (ret)
3103 goto out;
3104
3105 /* Lookup the exact service by <protocol, addr, port> or fwmark */
3106 if (usvc.fwmark == 0)
3107 svc = __ip_vs_service_get(usvc.af, usvc.protocol,
3108 &usvc.addr, usvc.port);
3109 else
3110 svc = __ip_vs_svc_fwm_get(usvc.af, usvc.fwmark);
3111
3112 /* Unless we're adding a new service, the service must already exist */
3113 if ((cmd != IPVS_CMD_NEW_SERVICE) && (svc == NULL)) {
3114 ret = -ESRCH;
3115 goto out;
3116 }
3117
3118 /* Destination commands require a valid destination argument. For
3119 * adding / editing a destination, we need a full destination
3120 * specification. */
3121 if (cmd == IPVS_CMD_NEW_DEST || cmd == IPVS_CMD_SET_DEST ||
3122 cmd == IPVS_CMD_DEL_DEST) {
3123 if (cmd != IPVS_CMD_DEL_DEST)
3124 need_full_dest = 1;
3125
3126 ret = ip_vs_genl_parse_dest(&udest,
3127 info->attrs[IPVS_CMD_ATTR_DEST],
3128 need_full_dest);
3129 if (ret)
3130 goto out;
3131 }
3132
3133 switch (cmd) {
3134 case IPVS_CMD_NEW_SERVICE:
3135 if (svc == NULL)
3136 ret = ip_vs_add_service(&usvc, &svc);
3137 else
3138 ret = -EEXIST;
3139 break;
3140 case IPVS_CMD_SET_SERVICE:
3141 ret = ip_vs_edit_service(svc, &usvc);
3142 break;
3143 case IPVS_CMD_DEL_SERVICE:
3144 ret = ip_vs_del_service(svc);
3145 break;
3146 case IPVS_CMD_NEW_DEST:
3147 ret = ip_vs_add_dest(svc, &udest);
3148 break;
3149 case IPVS_CMD_SET_DEST:
3150 ret = ip_vs_edit_dest(svc, &udest);
3151 break;
3152 case IPVS_CMD_DEL_DEST:
3153 ret = ip_vs_del_dest(svc, &udest);
3154 break;
3155 case IPVS_CMD_ZERO:
3156 ret = ip_vs_zero_service(svc);
3157 break;
3158 default:
3159 ret = -EINVAL;
3160 }
3161
3162out:
3163 if (svc)
3164 ip_vs_service_put(svc);
3165 mutex_unlock(&__ip_vs_mutex);
3166
3167 return ret;
3168}
3169
3170static int ip_vs_genl_get_cmd(struct sk_buff *skb, struct genl_info *info)
3171{
3172 struct sk_buff *msg;
3173 void *reply;
3174 int ret, cmd, reply_cmd;
3175
3176 cmd = info->genlhdr->cmd;
3177
3178 if (cmd == IPVS_CMD_GET_SERVICE)
3179 reply_cmd = IPVS_CMD_NEW_SERVICE;
3180 else if (cmd == IPVS_CMD_GET_INFO)
3181 reply_cmd = IPVS_CMD_SET_INFO;
3182 else if (cmd == IPVS_CMD_GET_CONFIG)
3183 reply_cmd = IPVS_CMD_SET_CONFIG;
3184 else {
3185 IP_VS_ERR("unknown Generic Netlink command\n");
3186 return -EINVAL;
3187 }
3188
3189 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3190 if (!msg)
3191 return -ENOMEM;
3192
3193 mutex_lock(&__ip_vs_mutex);
3194
3195 reply = genlmsg_put_reply(msg, info, &ip_vs_genl_family, 0, reply_cmd);
3196 if (reply == NULL)
3197 goto nla_put_failure;
3198
3199 switch (cmd) {
3200 case IPVS_CMD_GET_SERVICE:
3201 {
3202 struct ip_vs_service *svc;
3203
3204 svc = ip_vs_genl_find_service(info->attrs[IPVS_CMD_ATTR_SERVICE]);
3205 if (IS_ERR(svc)) {
3206 ret = PTR_ERR(svc);
3207 goto out_err;
3208 } else if (svc) {
3209 ret = ip_vs_genl_fill_service(msg, svc);
3210 ip_vs_service_put(svc);
3211 if (ret)
3212 goto nla_put_failure;
3213 } else {
3214 ret = -ESRCH;
3215 goto out_err;
3216 }
3217
3218 break;
3219 }
3220
3221 case IPVS_CMD_GET_CONFIG:
3222 {
3223 struct ip_vs_timeout_user t;
3224
3225 __ip_vs_get_timeouts(&t);
3226#ifdef CONFIG_IP_VS_PROTO_TCP
3227 NLA_PUT_U32(msg, IPVS_CMD_ATTR_TIMEOUT_TCP, t.tcp_timeout);
3228 NLA_PUT_U32(msg, IPVS_CMD_ATTR_TIMEOUT_TCP_FIN,
3229 t.tcp_fin_timeout);
3230#endif
3231#ifdef CONFIG_IP_VS_PROTO_UDP
3232 NLA_PUT_U32(msg, IPVS_CMD_ATTR_TIMEOUT_UDP, t.udp_timeout);
3233#endif
3234
3235 break;
3236 }
3237
3238 case IPVS_CMD_GET_INFO:
3239 NLA_PUT_U32(msg, IPVS_INFO_ATTR_VERSION, IP_VS_VERSION_CODE);
3240 NLA_PUT_U32(msg, IPVS_INFO_ATTR_CONN_TAB_SIZE,
3241 IP_VS_CONN_TAB_SIZE);
3242 break;
3243 }
3244
3245 genlmsg_end(msg, reply);
3246 ret = genlmsg_unicast(msg, info->snd_pid);
3247 goto out;
3248
3249nla_put_failure:
3250 IP_VS_ERR("not enough space in Netlink message\n");
3251 ret = -EMSGSIZE;
3252
3253out_err:
3254 nlmsg_free(msg);
3255out:
3256 mutex_unlock(&__ip_vs_mutex);
3257
3258 return ret;
3259}
3260
3261
3262static struct genl_ops ip_vs_genl_ops[] __read_mostly = {
3263 {
3264 .cmd = IPVS_CMD_NEW_SERVICE,
3265 .flags = GENL_ADMIN_PERM,
3266 .policy = ip_vs_cmd_policy,
3267 .doit = ip_vs_genl_set_cmd,
3268 },
3269 {
3270 .cmd = IPVS_CMD_SET_SERVICE,
3271 .flags = GENL_ADMIN_PERM,
3272 .policy = ip_vs_cmd_policy,
3273 .doit = ip_vs_genl_set_cmd,
3274 },
3275 {
3276 .cmd = IPVS_CMD_DEL_SERVICE,
3277 .flags = GENL_ADMIN_PERM,
3278 .policy = ip_vs_cmd_policy,
3279 .doit = ip_vs_genl_set_cmd,
3280 },
3281 {
3282 .cmd = IPVS_CMD_GET_SERVICE,
3283 .flags = GENL_ADMIN_PERM,
3284 .doit = ip_vs_genl_get_cmd,
3285 .dumpit = ip_vs_genl_dump_services,
3286 .policy = ip_vs_cmd_policy,
3287 },
3288 {
3289 .cmd = IPVS_CMD_NEW_DEST,
3290 .flags = GENL_ADMIN_PERM,
3291 .policy = ip_vs_cmd_policy,
3292 .doit = ip_vs_genl_set_cmd,
3293 },
3294 {
3295 .cmd = IPVS_CMD_SET_DEST,
3296 .flags = GENL_ADMIN_PERM,
3297 .policy = ip_vs_cmd_policy,
3298 .doit = ip_vs_genl_set_cmd,
3299 },
3300 {
3301 .cmd = IPVS_CMD_DEL_DEST,
3302 .flags = GENL_ADMIN_PERM,
3303 .policy = ip_vs_cmd_policy,
3304 .doit = ip_vs_genl_set_cmd,
3305 },
3306 {
3307 .cmd = IPVS_CMD_GET_DEST,
3308 .flags = GENL_ADMIN_PERM,
3309 .policy = ip_vs_cmd_policy,
3310 .dumpit = ip_vs_genl_dump_dests,
3311 },
3312 {
3313 .cmd = IPVS_CMD_NEW_DAEMON,
3314 .flags = GENL_ADMIN_PERM,
3315 .policy = ip_vs_cmd_policy,
3316 .doit = ip_vs_genl_set_cmd,
3317 },
3318 {
3319 .cmd = IPVS_CMD_DEL_DAEMON,
3320 .flags = GENL_ADMIN_PERM,
3321 .policy = ip_vs_cmd_policy,
3322 .doit = ip_vs_genl_set_cmd,
3323 },
3324 {
3325 .cmd = IPVS_CMD_GET_DAEMON,
3326 .flags = GENL_ADMIN_PERM,
3327 .dumpit = ip_vs_genl_dump_daemons,
3328 },
3329 {
3330 .cmd = IPVS_CMD_SET_CONFIG,
3331 .flags = GENL_ADMIN_PERM,
3332 .policy = ip_vs_cmd_policy,
3333 .doit = ip_vs_genl_set_cmd,
3334 },
3335 {
3336 .cmd = IPVS_CMD_GET_CONFIG,
3337 .flags = GENL_ADMIN_PERM,
3338 .doit = ip_vs_genl_get_cmd,
3339 },
3340 {
3341 .cmd = IPVS_CMD_GET_INFO,
3342 .flags = GENL_ADMIN_PERM,
3343 .doit = ip_vs_genl_get_cmd,
3344 },
3345 {
3346 .cmd = IPVS_CMD_ZERO,
3347 .flags = GENL_ADMIN_PERM,
3348 .policy = ip_vs_cmd_policy,
3349 .doit = ip_vs_genl_set_cmd,
3350 },
3351 {
3352 .cmd = IPVS_CMD_FLUSH,
3353 .flags = GENL_ADMIN_PERM,
3354 .doit = ip_vs_genl_set_cmd,
3355 },
3356};
3357
3358static int __init ip_vs_genl_register(void)
3359{
3360 int ret, i;
3361
3362 ret = genl_register_family(&ip_vs_genl_family);
3363 if (ret)
3364 return ret;
3365
3366 for (i = 0; i < ARRAY_SIZE(ip_vs_genl_ops); i++) {
3367 ret = genl_register_ops(&ip_vs_genl_family, &ip_vs_genl_ops[i]);
3368 if (ret)
3369 goto err_out;
3370 }
3371 return 0;
3372
3373err_out:
3374 genl_unregister_family(&ip_vs_genl_family);
3375 return ret;
3376}
3377
3378static void ip_vs_genl_unregister(void)
3379{
3380 genl_unregister_family(&ip_vs_genl_family);
3381}
3382
3383/* End of Generic Netlink interface definitions */
3384
2323 3385
2324int __init ip_vs_control_init(void) 3386int __init ip_vs_control_init(void)
2325{ 3387{
@@ -2334,6 +3396,13 @@ int __init ip_vs_control_init(void)
2334 return ret; 3396 return ret;
2335 } 3397 }
2336 3398
3399 ret = ip_vs_genl_register();
3400 if (ret) {
3401 IP_VS_ERR("cannot register Generic Netlink interface.\n");
3402 nf_unregister_sockopt(&ip_vs_sockopts);
3403 return ret;
3404 }
3405
2337 proc_net_fops_create(&init_net, "ip_vs", 0, &ip_vs_info_fops); 3406 proc_net_fops_create(&init_net, "ip_vs", 0, &ip_vs_info_fops);
2338 proc_net_fops_create(&init_net, "ip_vs_stats",0, &ip_vs_stats_fops); 3407 proc_net_fops_create(&init_net, "ip_vs_stats",0, &ip_vs_stats_fops);
2339 3408
@@ -2368,6 +3437,7 @@ void ip_vs_control_cleanup(void)
2368 unregister_sysctl_table(sysctl_header); 3437 unregister_sysctl_table(sysctl_header);
2369 proc_net_remove(&init_net, "ip_vs_stats"); 3438 proc_net_remove(&init_net, "ip_vs_stats");
2370 proc_net_remove(&init_net, "ip_vs"); 3439 proc_net_remove(&init_net, "ip_vs");
3440 ip_vs_genl_unregister();
2371 nf_unregister_sockopt(&ip_vs_sockopts); 3441 nf_unregister_sockopt(&ip_vs_sockopts);
2372 LeaveFunction(2); 3442 LeaveFunction(2);
2373} 3443}
diff --git a/net/ipv4/ipvs/ip_vs_dh.c b/net/netfilter/ipvs/ip_vs_dh.c
index fa66824d264f..a16943fd72f1 100644
--- a/net/ipv4/ipvs/ip_vs_dh.c
+++ b/net/netfilter/ipvs/ip_vs_dh.c
@@ -218,7 +218,7 @@ ip_vs_dh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
218 IP_VS_DBG(6, "DH: destination IP address %u.%u.%u.%u " 218 IP_VS_DBG(6, "DH: destination IP address %u.%u.%u.%u "
219 "--> server %u.%u.%u.%u:%d\n", 219 "--> server %u.%u.%u.%u:%d\n",
220 NIPQUAD(iph->daddr), 220 NIPQUAD(iph->daddr),
221 NIPQUAD(dest->addr), 221 NIPQUAD(dest->addr.ip),
222 ntohs(dest->port)); 222 ntohs(dest->port));
223 223
224 return dest; 224 return dest;
@@ -234,6 +234,9 @@ static struct ip_vs_scheduler ip_vs_dh_scheduler =
234 .refcnt = ATOMIC_INIT(0), 234 .refcnt = ATOMIC_INIT(0),
235 .module = THIS_MODULE, 235 .module = THIS_MODULE,
236 .n_list = LIST_HEAD_INIT(ip_vs_dh_scheduler.n_list), 236 .n_list = LIST_HEAD_INIT(ip_vs_dh_scheduler.n_list),
237#ifdef CONFIG_IP_VS_IPV6
238 .supports_ipv6 = 0,
239#endif
237 .init_service = ip_vs_dh_init_svc, 240 .init_service = ip_vs_dh_init_svc,
238 .done_service = ip_vs_dh_done_svc, 241 .done_service = ip_vs_dh_done_svc,
239 .update_service = ip_vs_dh_update_svc, 242 .update_service = ip_vs_dh_update_svc,
diff --git a/net/ipv4/ipvs/ip_vs_est.c b/net/netfilter/ipvs/ip_vs_est.c
index 5a20f93bd7f9..2eb2860dabb5 100644
--- a/net/ipv4/ipvs/ip_vs_est.c
+++ b/net/netfilter/ipvs/ip_vs_est.c
@@ -65,37 +65,37 @@ static void estimation_timer(unsigned long arg)
65 s = container_of(e, struct ip_vs_stats, est); 65 s = container_of(e, struct ip_vs_stats, est);
66 66
67 spin_lock(&s->lock); 67 spin_lock(&s->lock);
68 n_conns = s->conns; 68 n_conns = s->ustats.conns;
69 n_inpkts = s->inpkts; 69 n_inpkts = s->ustats.inpkts;
70 n_outpkts = s->outpkts; 70 n_outpkts = s->ustats.outpkts;
71 n_inbytes = s->inbytes; 71 n_inbytes = s->ustats.inbytes;
72 n_outbytes = s->outbytes; 72 n_outbytes = s->ustats.outbytes;
73 73
74 /* scaled by 2^10, but divided 2 seconds */ 74 /* scaled by 2^10, but divided 2 seconds */
75 rate = (n_conns - e->last_conns)<<9; 75 rate = (n_conns - e->last_conns)<<9;
76 e->last_conns = n_conns; 76 e->last_conns = n_conns;
77 e->cps += ((long)rate - (long)e->cps)>>2; 77 e->cps += ((long)rate - (long)e->cps)>>2;
78 s->cps = (e->cps+0x1FF)>>10; 78 s->ustats.cps = (e->cps+0x1FF)>>10;
79 79
80 rate = (n_inpkts - e->last_inpkts)<<9; 80 rate = (n_inpkts - e->last_inpkts)<<9;
81 e->last_inpkts = n_inpkts; 81 e->last_inpkts = n_inpkts;
82 e->inpps += ((long)rate - (long)e->inpps)>>2; 82 e->inpps += ((long)rate - (long)e->inpps)>>2;
83 s->inpps = (e->inpps+0x1FF)>>10; 83 s->ustats.inpps = (e->inpps+0x1FF)>>10;
84 84
85 rate = (n_outpkts - e->last_outpkts)<<9; 85 rate = (n_outpkts - e->last_outpkts)<<9;
86 e->last_outpkts = n_outpkts; 86 e->last_outpkts = n_outpkts;
87 e->outpps += ((long)rate - (long)e->outpps)>>2; 87 e->outpps += ((long)rate - (long)e->outpps)>>2;
88 s->outpps = (e->outpps+0x1FF)>>10; 88 s->ustats.outpps = (e->outpps+0x1FF)>>10;
89 89
90 rate = (n_inbytes - e->last_inbytes)<<4; 90 rate = (n_inbytes - e->last_inbytes)<<4;
91 e->last_inbytes = n_inbytes; 91 e->last_inbytes = n_inbytes;
92 e->inbps += ((long)rate - (long)e->inbps)>>2; 92 e->inbps += ((long)rate - (long)e->inbps)>>2;
93 s->inbps = (e->inbps+0xF)>>5; 93 s->ustats.inbps = (e->inbps+0xF)>>5;
94 94
95 rate = (n_outbytes - e->last_outbytes)<<4; 95 rate = (n_outbytes - e->last_outbytes)<<4;
96 e->last_outbytes = n_outbytes; 96 e->last_outbytes = n_outbytes;
97 e->outbps += ((long)rate - (long)e->outbps)>>2; 97 e->outbps += ((long)rate - (long)e->outbps)>>2;
98 s->outbps = (e->outbps+0xF)>>5; 98 s->ustats.outbps = (e->outbps+0xF)>>5;
99 spin_unlock(&s->lock); 99 spin_unlock(&s->lock);
100 } 100 }
101 spin_unlock(&est_lock); 101 spin_unlock(&est_lock);
@@ -108,24 +108,22 @@ void ip_vs_new_estimator(struct ip_vs_stats *stats)
108 108
109 INIT_LIST_HEAD(&est->list); 109 INIT_LIST_HEAD(&est->list);
110 110
111 est->last_conns = stats->conns; 111 est->last_conns = stats->ustats.conns;
112 est->cps = stats->cps<<10; 112 est->cps = stats->ustats.cps<<10;
113 113
114 est->last_inpkts = stats->inpkts; 114 est->last_inpkts = stats->ustats.inpkts;
115 est->inpps = stats->inpps<<10; 115 est->inpps = stats->ustats.inpps<<10;
116 116
117 est->last_outpkts = stats->outpkts; 117 est->last_outpkts = stats->ustats.outpkts;
118 est->outpps = stats->outpps<<10; 118 est->outpps = stats->ustats.outpps<<10;
119 119
120 est->last_inbytes = stats->inbytes; 120 est->last_inbytes = stats->ustats.inbytes;
121 est->inbps = stats->inbps<<5; 121 est->inbps = stats->ustats.inbps<<5;
122 122
123 est->last_outbytes = stats->outbytes; 123 est->last_outbytes = stats->ustats.outbytes;
124 est->outbps = stats->outbps<<5; 124 est->outbps = stats->ustats.outbps<<5;
125 125
126 spin_lock_bh(&est_lock); 126 spin_lock_bh(&est_lock);
127 if (list_empty(&est_list))
128 mod_timer(&est_timer, jiffies + 2 * HZ);
129 list_add(&est->list, &est_list); 127 list_add(&est->list, &est_list);
130 spin_unlock_bh(&est_lock); 128 spin_unlock_bh(&est_lock);
131} 129}
@@ -136,11 +134,6 @@ void ip_vs_kill_estimator(struct ip_vs_stats *stats)
136 134
137 spin_lock_bh(&est_lock); 135 spin_lock_bh(&est_lock);
138 list_del(&est->list); 136 list_del(&est->list);
139 while (list_empty(&est_list) && try_to_del_timer_sync(&est_timer) < 0) {
140 spin_unlock_bh(&est_lock);
141 cpu_relax();
142 spin_lock_bh(&est_lock);
143 }
144 spin_unlock_bh(&est_lock); 137 spin_unlock_bh(&est_lock);
145} 138}
146 139
@@ -160,3 +153,14 @@ void ip_vs_zero_estimator(struct ip_vs_stats *stats)
160 est->inbps = 0; 153 est->inbps = 0;
161 est->outbps = 0; 154 est->outbps = 0;
162} 155}
156
157int __init ip_vs_estimator_init(void)
158{
159 mod_timer(&est_timer, jiffies + 2 * HZ);
160 return 0;
161}
162
163void ip_vs_estimator_cleanup(void)
164{
165 del_timer_sync(&est_timer);
166}
diff --git a/net/ipv4/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c
index c1c758e4f733..2e7dbd8b73a4 100644
--- a/net/ipv4/ipvs/ip_vs_ftp.c
+++ b/net/netfilter/ipvs/ip_vs_ftp.c
@@ -140,13 +140,21 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
140 struct tcphdr *th; 140 struct tcphdr *th;
141 char *data, *data_limit; 141 char *data, *data_limit;
142 char *start, *end; 142 char *start, *end;
143 __be32 from; 143 union nf_inet_addr from;
144 __be16 port; 144 __be16 port;
145 struct ip_vs_conn *n_cp; 145 struct ip_vs_conn *n_cp;
146 char buf[24]; /* xxx.xxx.xxx.xxx,ppp,ppp\000 */ 146 char buf[24]; /* xxx.xxx.xxx.xxx,ppp,ppp\000 */
147 unsigned buf_len; 147 unsigned buf_len;
148 int ret; 148 int ret;
149 149
150#ifdef CONFIG_IP_VS_IPV6
151 /* This application helper doesn't work with IPv6 yet,
152 * so turn this into a no-op for IPv6 packets
153 */
154 if (cp->af == AF_INET6)
155 return 1;
156#endif
157
150 *diff = 0; 158 *diff = 0;
151 159
152 /* Only useful for established sessions */ 160 /* Only useful for established sessions */
@@ -166,24 +174,25 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
166 if (ip_vs_ftp_get_addrport(data, data_limit, 174 if (ip_vs_ftp_get_addrport(data, data_limit,
167 SERVER_STRING, 175 SERVER_STRING,
168 sizeof(SERVER_STRING)-1, ')', 176 sizeof(SERVER_STRING)-1, ')',
169 &from, &port, 177 &from.ip, &port,
170 &start, &end) != 1) 178 &start, &end) != 1)
171 return 1; 179 return 1;
172 180
173 IP_VS_DBG(7, "PASV response (%u.%u.%u.%u:%d) -> " 181 IP_VS_DBG(7, "PASV response (%u.%u.%u.%u:%d) -> "
174 "%u.%u.%u.%u:%d detected\n", 182 "%u.%u.%u.%u:%d detected\n",
175 NIPQUAD(from), ntohs(port), NIPQUAD(cp->caddr), 0); 183 NIPQUAD(from.ip), ntohs(port),
184 NIPQUAD(cp->caddr.ip), 0);
176 185
177 /* 186 /*
178 * Now update or create an connection entry for it 187 * Now update or create an connection entry for it
179 */ 188 */
180 n_cp = ip_vs_conn_out_get(iph->protocol, from, port, 189 n_cp = ip_vs_conn_out_get(AF_INET, iph->protocol, &from, port,
181 cp->caddr, 0); 190 &cp->caddr, 0);
182 if (!n_cp) { 191 if (!n_cp) {
183 n_cp = ip_vs_conn_new(IPPROTO_TCP, 192 n_cp = ip_vs_conn_new(AF_INET, IPPROTO_TCP,
184 cp->caddr, 0, 193 &cp->caddr, 0,
185 cp->vaddr, port, 194 &cp->vaddr, port,
186 from, port, 195 &from, port,
187 IP_VS_CONN_F_NO_CPORT, 196 IP_VS_CONN_F_NO_CPORT,
188 cp->dest); 197 cp->dest);
189 if (!n_cp) 198 if (!n_cp)
@@ -196,9 +205,9 @@ static int ip_vs_ftp_out(struct ip_vs_app *app, struct ip_vs_conn *cp,
196 /* 205 /*
197 * Replace the old passive address with the new one 206 * Replace the old passive address with the new one
198 */ 207 */
199 from = n_cp->vaddr; 208 from.ip = n_cp->vaddr.ip;
200 port = n_cp->vport; 209 port = n_cp->vport;
201 sprintf(buf,"%d,%d,%d,%d,%d,%d", NIPQUAD(from), 210 sprintf(buf, "%d,%d,%d,%d,%d,%d", NIPQUAD(from.ip),
202 (ntohs(port)>>8)&255, ntohs(port)&255); 211 (ntohs(port)>>8)&255, ntohs(port)&255);
203 buf_len = strlen(buf); 212 buf_len = strlen(buf);
204 213
@@ -243,10 +252,18 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp,
243 struct tcphdr *th; 252 struct tcphdr *th;
244 char *data, *data_start, *data_limit; 253 char *data, *data_start, *data_limit;
245 char *start, *end; 254 char *start, *end;
246 __be32 to; 255 union nf_inet_addr to;
247 __be16 port; 256 __be16 port;
248 struct ip_vs_conn *n_cp; 257 struct ip_vs_conn *n_cp;
249 258
259#ifdef CONFIG_IP_VS_IPV6
260 /* This application helper doesn't work with IPv6 yet,
261 * so turn this into a no-op for IPv6 packets
262 */
263 if (cp->af == AF_INET6)
264 return 1;
265#endif
266
250 /* no diff required for incoming packets */ 267 /* no diff required for incoming packets */
251 *diff = 0; 268 *diff = 0;
252 269
@@ -291,12 +308,12 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp,
291 */ 308 */
292 if (ip_vs_ftp_get_addrport(data_start, data_limit, 309 if (ip_vs_ftp_get_addrport(data_start, data_limit,
293 CLIENT_STRING, sizeof(CLIENT_STRING)-1, 310 CLIENT_STRING, sizeof(CLIENT_STRING)-1,
294 '\r', &to, &port, 311 '\r', &to.ip, &port,
295 &start, &end) != 1) 312 &start, &end) != 1)
296 return 1; 313 return 1;
297 314
298 IP_VS_DBG(7, "PORT %u.%u.%u.%u:%d detected\n", 315 IP_VS_DBG(7, "PORT %u.%u.%u.%u:%d detected\n",
299 NIPQUAD(to), ntohs(port)); 316 NIPQUAD(to.ip), ntohs(port));
300 317
301 /* Passive mode off */ 318 /* Passive mode off */
302 cp->app_data = NULL; 319 cp->app_data = NULL;
@@ -306,16 +323,16 @@ static int ip_vs_ftp_in(struct ip_vs_app *app, struct ip_vs_conn *cp,
306 */ 323 */
307 IP_VS_DBG(7, "protocol %s %u.%u.%u.%u:%d %u.%u.%u.%u:%d\n", 324 IP_VS_DBG(7, "protocol %s %u.%u.%u.%u:%d %u.%u.%u.%u:%d\n",
308 ip_vs_proto_name(iph->protocol), 325 ip_vs_proto_name(iph->protocol),
309 NIPQUAD(to), ntohs(port), NIPQUAD(cp->vaddr), 0); 326 NIPQUAD(to.ip), ntohs(port), NIPQUAD(cp->vaddr.ip), 0);
310 327
311 n_cp = ip_vs_conn_in_get(iph->protocol, 328 n_cp = ip_vs_conn_in_get(AF_INET, iph->protocol,
312 to, port, 329 &to, port,
313 cp->vaddr, htons(ntohs(cp->vport)-1)); 330 &cp->vaddr, htons(ntohs(cp->vport)-1));
314 if (!n_cp) { 331 if (!n_cp) {
315 n_cp = ip_vs_conn_new(IPPROTO_TCP, 332 n_cp = ip_vs_conn_new(AF_INET, IPPROTO_TCP,
316 to, port, 333 &to, port,
317 cp->vaddr, htons(ntohs(cp->vport)-1), 334 &cp->vaddr, htons(ntohs(cp->vport)-1),
318 cp->daddr, htons(ntohs(cp->dport)-1), 335 &cp->daddr, htons(ntohs(cp->dport)-1),
319 0, 336 0,
320 cp->dest); 337 cp->dest);
321 if (!n_cp) 338 if (!n_cp)
diff --git a/net/ipv4/ipvs/ip_vs_lblc.c b/net/netfilter/ipvs/ip_vs_lblc.c
index 7a6a319f544a..6ecef3518cac 100644
--- a/net/ipv4/ipvs/ip_vs_lblc.c
+++ b/net/netfilter/ipvs/ip_vs_lblc.c
@@ -96,7 +96,6 @@ struct ip_vs_lblc_entry {
96 * IPVS lblc hash table 96 * IPVS lblc hash table
97 */ 97 */
98struct ip_vs_lblc_table { 98struct ip_vs_lblc_table {
99 rwlock_t lock; /* lock for this table */
100 struct list_head bucket[IP_VS_LBLC_TAB_SIZE]; /* hash bucket */ 99 struct list_head bucket[IP_VS_LBLC_TAB_SIZE]; /* hash bucket */
101 atomic_t entries; /* number of entries */ 100 atomic_t entries; /* number of entries */
102 int max_size; /* maximum size of entries */ 101 int max_size; /* maximum size of entries */
@@ -123,31 +122,6 @@ static ctl_table vs_vars_table[] = {
123 122
124static struct ctl_table_header * sysctl_header; 123static struct ctl_table_header * sysctl_header;
125 124
126/*
127 * new/free a ip_vs_lblc_entry, which is a mapping of a destionation
128 * IP address to a server.
129 */
130static inline struct ip_vs_lblc_entry *
131ip_vs_lblc_new(__be32 daddr, struct ip_vs_dest *dest)
132{
133 struct ip_vs_lblc_entry *en;
134
135 en = kmalloc(sizeof(struct ip_vs_lblc_entry), GFP_ATOMIC);
136 if (en == NULL) {
137 IP_VS_ERR("ip_vs_lblc_new(): no memory\n");
138 return NULL;
139 }
140
141 INIT_LIST_HEAD(&en->list);
142 en->addr = daddr;
143
144 atomic_inc(&dest->refcnt);
145 en->dest = dest;
146
147 return en;
148}
149
150
151static inline void ip_vs_lblc_free(struct ip_vs_lblc_entry *en) 125static inline void ip_vs_lblc_free(struct ip_vs_lblc_entry *en)
152{ 126{
153 list_del(&en->list); 127 list_del(&en->list);
@@ -173,55 +147,66 @@ static inline unsigned ip_vs_lblc_hashkey(__be32 addr)
173 * Hash an entry in the ip_vs_lblc_table. 147 * Hash an entry in the ip_vs_lblc_table.
174 * returns bool success. 148 * returns bool success.
175 */ 149 */
176static int 150static void
177ip_vs_lblc_hash(struct ip_vs_lblc_table *tbl, struct ip_vs_lblc_entry *en) 151ip_vs_lblc_hash(struct ip_vs_lblc_table *tbl, struct ip_vs_lblc_entry *en)
178{ 152{
179 unsigned hash; 153 unsigned hash = ip_vs_lblc_hashkey(en->addr);
180
181 if (!list_empty(&en->list)) {
182 IP_VS_ERR("ip_vs_lblc_hash(): request for already hashed, "
183 "called from %p\n", __builtin_return_address(0));
184 return 0;
185 }
186
187 /*
188 * Hash by destination IP address
189 */
190 hash = ip_vs_lblc_hashkey(en->addr);
191 154
192 write_lock(&tbl->lock);
193 list_add(&en->list, &tbl->bucket[hash]); 155 list_add(&en->list, &tbl->bucket[hash]);
194 atomic_inc(&tbl->entries); 156 atomic_inc(&tbl->entries);
195 write_unlock(&tbl->lock);
196
197 return 1;
198} 157}
199 158
200 159
201/* 160/*
202 * Get ip_vs_lblc_entry associated with supplied parameters. 161 * Get ip_vs_lblc_entry associated with supplied parameters. Called under read
162 * lock
203 */ 163 */
204static inline struct ip_vs_lblc_entry * 164static inline struct ip_vs_lblc_entry *
205ip_vs_lblc_get(struct ip_vs_lblc_table *tbl, __be32 addr) 165ip_vs_lblc_get(struct ip_vs_lblc_table *tbl, __be32 addr)
206{ 166{
207 unsigned hash; 167 unsigned hash = ip_vs_lblc_hashkey(addr);
208 struct ip_vs_lblc_entry *en; 168 struct ip_vs_lblc_entry *en;
209 169
210 hash = ip_vs_lblc_hashkey(addr); 170 list_for_each_entry(en, &tbl->bucket[hash], list)
171 if (en->addr == addr)
172 return en;
211 173
212 read_lock(&tbl->lock); 174 return NULL;
175}
213 176
214 list_for_each_entry(en, &tbl->bucket[hash], list) { 177
215 if (en->addr == addr) { 178/*
216 /* HIT */ 179 * Create or update an ip_vs_lblc_entry, which is a mapping of a destination IP
217 read_unlock(&tbl->lock); 180 * address to a server. Called under write lock.
218 return en; 181 */
182static inline struct ip_vs_lblc_entry *
183ip_vs_lblc_new(struct ip_vs_lblc_table *tbl, __be32 daddr,
184 struct ip_vs_dest *dest)
185{
186 struct ip_vs_lblc_entry *en;
187
188 en = ip_vs_lblc_get(tbl, daddr);
189 if (!en) {
190 en = kmalloc(sizeof(*en), GFP_ATOMIC);
191 if (!en) {
192 IP_VS_ERR("ip_vs_lblc_new(): no memory\n");
193 return NULL;
219 } 194 }
220 }
221 195
222 read_unlock(&tbl->lock); 196 en->addr = daddr;
197 en->lastuse = jiffies;
223 198
224 return NULL; 199 atomic_inc(&dest->refcnt);
200 en->dest = dest;
201
202 ip_vs_lblc_hash(tbl, en);
203 } else if (en->dest != dest) {
204 atomic_dec(&en->dest->refcnt);
205 atomic_inc(&dest->refcnt);
206 en->dest = dest;
207 }
208
209 return en;
225} 210}
226 211
227 212
@@ -230,30 +215,29 @@ ip_vs_lblc_get(struct ip_vs_lblc_table *tbl, __be32 addr)
230 */ 215 */
231static void ip_vs_lblc_flush(struct ip_vs_lblc_table *tbl) 216static void ip_vs_lblc_flush(struct ip_vs_lblc_table *tbl)
232{ 217{
233 int i;
234 struct ip_vs_lblc_entry *en, *nxt; 218 struct ip_vs_lblc_entry *en, *nxt;
219 int i;
235 220
236 for (i=0; i<IP_VS_LBLC_TAB_SIZE; i++) { 221 for (i=0; i<IP_VS_LBLC_TAB_SIZE; i++) {
237 write_lock(&tbl->lock);
238 list_for_each_entry_safe(en, nxt, &tbl->bucket[i], list) { 222 list_for_each_entry_safe(en, nxt, &tbl->bucket[i], list) {
239 ip_vs_lblc_free(en); 223 ip_vs_lblc_free(en);
240 atomic_dec(&tbl->entries); 224 atomic_dec(&tbl->entries);
241 } 225 }
242 write_unlock(&tbl->lock);
243 } 226 }
244} 227}
245 228
246 229
247static inline void ip_vs_lblc_full_check(struct ip_vs_lblc_table *tbl) 230static inline void ip_vs_lblc_full_check(struct ip_vs_service *svc)
248{ 231{
232 struct ip_vs_lblc_table *tbl = svc->sched_data;
233 struct ip_vs_lblc_entry *en, *nxt;
249 unsigned long now = jiffies; 234 unsigned long now = jiffies;
250 int i, j; 235 int i, j;
251 struct ip_vs_lblc_entry *en, *nxt;
252 236
253 for (i=0, j=tbl->rover; i<IP_VS_LBLC_TAB_SIZE; i++) { 237 for (i=0, j=tbl->rover; i<IP_VS_LBLC_TAB_SIZE; i++) {
254 j = (j + 1) & IP_VS_LBLC_TAB_MASK; 238 j = (j + 1) & IP_VS_LBLC_TAB_MASK;
255 239
256 write_lock(&tbl->lock); 240 write_lock(&svc->sched_lock);
257 list_for_each_entry_safe(en, nxt, &tbl->bucket[j], list) { 241 list_for_each_entry_safe(en, nxt, &tbl->bucket[j], list) {
258 if (time_before(now, 242 if (time_before(now,
259 en->lastuse + sysctl_ip_vs_lblc_expiration)) 243 en->lastuse + sysctl_ip_vs_lblc_expiration))
@@ -262,7 +246,7 @@ static inline void ip_vs_lblc_full_check(struct ip_vs_lblc_table *tbl)
262 ip_vs_lblc_free(en); 246 ip_vs_lblc_free(en);
263 atomic_dec(&tbl->entries); 247 atomic_dec(&tbl->entries);
264 } 248 }
265 write_unlock(&tbl->lock); 249 write_unlock(&svc->sched_lock);
266 } 250 }
267 tbl->rover = j; 251 tbl->rover = j;
268} 252}
@@ -281,17 +265,16 @@ static inline void ip_vs_lblc_full_check(struct ip_vs_lblc_table *tbl)
281 */ 265 */
282static void ip_vs_lblc_check_expire(unsigned long data) 266static void ip_vs_lblc_check_expire(unsigned long data)
283{ 267{
284 struct ip_vs_lblc_table *tbl; 268 struct ip_vs_service *svc = (struct ip_vs_service *) data;
269 struct ip_vs_lblc_table *tbl = svc->sched_data;
285 unsigned long now = jiffies; 270 unsigned long now = jiffies;
286 int goal; 271 int goal;
287 int i, j; 272 int i, j;
288 struct ip_vs_lblc_entry *en, *nxt; 273 struct ip_vs_lblc_entry *en, *nxt;
289 274
290 tbl = (struct ip_vs_lblc_table *)data;
291
292 if ((tbl->counter % COUNT_FOR_FULL_EXPIRATION) == 0) { 275 if ((tbl->counter % COUNT_FOR_FULL_EXPIRATION) == 0) {
293 /* do full expiration check */ 276 /* do full expiration check */
294 ip_vs_lblc_full_check(tbl); 277 ip_vs_lblc_full_check(svc);
295 tbl->counter = 1; 278 tbl->counter = 1;
296 goto out; 279 goto out;
297 } 280 }
@@ -308,7 +291,7 @@ static void ip_vs_lblc_check_expire(unsigned long data)
308 for (i=0, j=tbl->rover; i<IP_VS_LBLC_TAB_SIZE; i++) { 291 for (i=0, j=tbl->rover; i<IP_VS_LBLC_TAB_SIZE; i++) {
309 j = (j + 1) & IP_VS_LBLC_TAB_MASK; 292 j = (j + 1) & IP_VS_LBLC_TAB_MASK;
310 293
311 write_lock(&tbl->lock); 294 write_lock(&svc->sched_lock);
312 list_for_each_entry_safe(en, nxt, &tbl->bucket[j], list) { 295 list_for_each_entry_safe(en, nxt, &tbl->bucket[j], list) {
313 if (time_before(now, en->lastuse + ENTRY_TIMEOUT)) 296 if (time_before(now, en->lastuse + ENTRY_TIMEOUT))
314 continue; 297 continue;
@@ -317,7 +300,7 @@ static void ip_vs_lblc_check_expire(unsigned long data)
317 atomic_dec(&tbl->entries); 300 atomic_dec(&tbl->entries);
318 goal--; 301 goal--;
319 } 302 }
320 write_unlock(&tbl->lock); 303 write_unlock(&svc->sched_lock);
321 if (goal <= 0) 304 if (goal <= 0)
322 break; 305 break;
323 } 306 }
@@ -336,15 +319,14 @@ static int ip_vs_lblc_init_svc(struct ip_vs_service *svc)
336 /* 319 /*
337 * Allocate the ip_vs_lblc_table for this service 320 * Allocate the ip_vs_lblc_table for this service
338 */ 321 */
339 tbl = kmalloc(sizeof(struct ip_vs_lblc_table), GFP_ATOMIC); 322 tbl = kmalloc(sizeof(*tbl), GFP_ATOMIC);
340 if (tbl == NULL) { 323 if (tbl == NULL) {
341 IP_VS_ERR("ip_vs_lblc_init_svc(): no memory\n"); 324 IP_VS_ERR("ip_vs_lblc_init_svc(): no memory\n");
342 return -ENOMEM; 325 return -ENOMEM;
343 } 326 }
344 svc->sched_data = tbl; 327 svc->sched_data = tbl;
345 IP_VS_DBG(6, "LBLC hash table (memory=%Zdbytes) allocated for " 328 IP_VS_DBG(6, "LBLC hash table (memory=%Zdbytes) allocated for "
346 "current service\n", 329 "current service\n", sizeof(*tbl));
347 sizeof(struct ip_vs_lblc_table));
348 330
349 /* 331 /*
350 * Initialize the hash buckets 332 * Initialize the hash buckets
@@ -352,7 +334,6 @@ static int ip_vs_lblc_init_svc(struct ip_vs_service *svc)
352 for (i=0; i<IP_VS_LBLC_TAB_SIZE; i++) { 334 for (i=0; i<IP_VS_LBLC_TAB_SIZE; i++) {
353 INIT_LIST_HEAD(&tbl->bucket[i]); 335 INIT_LIST_HEAD(&tbl->bucket[i]);
354 } 336 }
355 rwlock_init(&tbl->lock);
356 tbl->max_size = IP_VS_LBLC_TAB_SIZE*16; 337 tbl->max_size = IP_VS_LBLC_TAB_SIZE*16;
357 tbl->rover = 0; 338 tbl->rover = 0;
358 tbl->counter = 1; 339 tbl->counter = 1;
@@ -361,9 +342,8 @@ static int ip_vs_lblc_init_svc(struct ip_vs_service *svc)
361 * Hook periodic timer for garbage collection 342 * Hook periodic timer for garbage collection
362 */ 343 */
363 setup_timer(&tbl->periodic_timer, ip_vs_lblc_check_expire, 344 setup_timer(&tbl->periodic_timer, ip_vs_lblc_check_expire,
364 (unsigned long)tbl); 345 (unsigned long)svc);
365 tbl->periodic_timer.expires = jiffies+CHECK_EXPIRE_INTERVAL; 346 mod_timer(&tbl->periodic_timer, jiffies + CHECK_EXPIRE_INTERVAL);
366 add_timer(&tbl->periodic_timer);
367 347
368 return 0; 348 return 0;
369} 349}
@@ -380,22 +360,16 @@ static int ip_vs_lblc_done_svc(struct ip_vs_service *svc)
380 ip_vs_lblc_flush(tbl); 360 ip_vs_lblc_flush(tbl);
381 361
382 /* release the table itself */ 362 /* release the table itself */
383 kfree(svc->sched_data); 363 kfree(tbl);
384 IP_VS_DBG(6, "LBLC hash table (memory=%Zdbytes) released\n", 364 IP_VS_DBG(6, "LBLC hash table (memory=%Zdbytes) released\n",
385 sizeof(struct ip_vs_lblc_table)); 365 sizeof(*tbl));
386 366
387 return 0; 367 return 0;
388} 368}
389 369
390 370
391static int ip_vs_lblc_update_svc(struct ip_vs_service *svc)
392{
393 return 0;
394}
395
396
397static inline struct ip_vs_dest * 371static inline struct ip_vs_dest *
398__ip_vs_wlc_schedule(struct ip_vs_service *svc, struct iphdr *iph) 372__ip_vs_lblc_schedule(struct ip_vs_service *svc, struct iphdr *iph)
399{ 373{
400 struct ip_vs_dest *dest, *least; 374 struct ip_vs_dest *dest, *least;
401 int loh, doh; 375 int loh, doh;
@@ -448,7 +422,7 @@ __ip_vs_wlc_schedule(struct ip_vs_service *svc, struct iphdr *iph)
448 422
449 IP_VS_DBG(6, "LBLC: server %d.%d.%d.%d:%d " 423 IP_VS_DBG(6, "LBLC: server %d.%d.%d.%d:%d "
450 "activeconns %d refcnt %d weight %d overhead %d\n", 424 "activeconns %d refcnt %d weight %d overhead %d\n",
451 NIPQUAD(least->addr), ntohs(least->port), 425 NIPQUAD(least->addr.ip), ntohs(least->port),
452 atomic_read(&least->activeconns), 426 atomic_read(&least->activeconns),
453 atomic_read(&least->refcnt), 427 atomic_read(&least->refcnt),
454 atomic_read(&least->weight), loh); 428 atomic_read(&least->weight), loh);
@@ -484,47 +458,55 @@ is_overloaded(struct ip_vs_dest *dest, struct ip_vs_service *svc)
484static struct ip_vs_dest * 458static struct ip_vs_dest *
485ip_vs_lblc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) 459ip_vs_lblc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
486{ 460{
487 struct ip_vs_dest *dest; 461 struct ip_vs_lblc_table *tbl = svc->sched_data;
488 struct ip_vs_lblc_table *tbl;
489 struct ip_vs_lblc_entry *en;
490 struct iphdr *iph = ip_hdr(skb); 462 struct iphdr *iph = ip_hdr(skb);
463 struct ip_vs_dest *dest = NULL;
464 struct ip_vs_lblc_entry *en;
491 465
492 IP_VS_DBG(6, "ip_vs_lblc_schedule(): Scheduling...\n"); 466 IP_VS_DBG(6, "ip_vs_lblc_schedule(): Scheduling...\n");
493 467
494 tbl = (struct ip_vs_lblc_table *)svc->sched_data; 468 /* First look in our cache */
469 read_lock(&svc->sched_lock);
495 en = ip_vs_lblc_get(tbl, iph->daddr); 470 en = ip_vs_lblc_get(tbl, iph->daddr);
496 if (en == NULL) { 471 if (en) {
497 dest = __ip_vs_wlc_schedule(svc, iph); 472 /* We only hold a read lock, but this is atomic */
498 if (dest == NULL) { 473 en->lastuse = jiffies;
499 IP_VS_DBG(1, "no destination available\n"); 474
500 return NULL; 475 /*
501 } 476 * If the destination is not available, i.e. it's in the trash,
502 en = ip_vs_lblc_new(iph->daddr, dest); 477 * we must ignore it, as it may be removed from under our feet,
503 if (en == NULL) { 478 * if someone drops our reference count. Our caller only makes
504 return NULL; 479 * sure that destinations, that are not in the trash, are not
505 } 480 * moved to the trash, while we are scheduling. But anyone can
506 ip_vs_lblc_hash(tbl, en); 481 * free up entries from the trash at any time.
507 } else { 482 */
508 dest = en->dest; 483
509 if (!(dest->flags & IP_VS_DEST_F_AVAILABLE) 484 if (en->dest->flags & IP_VS_DEST_F_AVAILABLE)
510 || atomic_read(&dest->weight) <= 0 485 dest = en->dest;
511 || is_overloaded(dest, svc)) { 486 }
512 dest = __ip_vs_wlc_schedule(svc, iph); 487 read_unlock(&svc->sched_lock);
513 if (dest == NULL) { 488
514 IP_VS_DBG(1, "no destination available\n"); 489 /* If the destination has a weight and is not overloaded, use it */
515 return NULL; 490 if (dest && atomic_read(&dest->weight) > 0 && !is_overloaded(dest, svc))
516 } 491 goto out;
517 atomic_dec(&en->dest->refcnt); 492
518 atomic_inc(&dest->refcnt); 493 /* No cache entry or it is invalid, time to schedule */
519 en->dest = dest; 494 dest = __ip_vs_lblc_schedule(svc, iph);
520 } 495 if (!dest) {
496 IP_VS_DBG(1, "no destination available\n");
497 return NULL;
521 } 498 }
522 en->lastuse = jiffies;
523 499
500 /* If we fail to create a cache entry, we'll just use the valid dest */
501 write_lock(&svc->sched_lock);
502 ip_vs_lblc_new(tbl, iph->daddr, dest);
503 write_unlock(&svc->sched_lock);
504
505out:
524 IP_VS_DBG(6, "LBLC: destination IP address %u.%u.%u.%u " 506 IP_VS_DBG(6, "LBLC: destination IP address %u.%u.%u.%u "
525 "--> server %u.%u.%u.%u:%d\n", 507 "--> server %u.%u.%u.%u:%d\n",
526 NIPQUAD(en->addr), 508 NIPQUAD(iph->daddr),
527 NIPQUAD(dest->addr), 509 NIPQUAD(dest->addr.ip),
528 ntohs(dest->port)); 510 ntohs(dest->port));
529 511
530 return dest; 512 return dest;
@@ -540,9 +522,11 @@ static struct ip_vs_scheduler ip_vs_lblc_scheduler =
540 .refcnt = ATOMIC_INIT(0), 522 .refcnt = ATOMIC_INIT(0),
541 .module = THIS_MODULE, 523 .module = THIS_MODULE,
542 .n_list = LIST_HEAD_INIT(ip_vs_lblc_scheduler.n_list), 524 .n_list = LIST_HEAD_INIT(ip_vs_lblc_scheduler.n_list),
525#ifdef CONFIG_IP_VS_IPV6
526 .supports_ipv6 = 0,
527#endif
543 .init_service = ip_vs_lblc_init_svc, 528 .init_service = ip_vs_lblc_init_svc,
544 .done_service = ip_vs_lblc_done_svc, 529 .done_service = ip_vs_lblc_done_svc,
545 .update_service = ip_vs_lblc_update_svc,
546 .schedule = ip_vs_lblc_schedule, 530 .schedule = ip_vs_lblc_schedule,
547}; 531};
548 532
diff --git a/net/ipv4/ipvs/ip_vs_lblcr.c b/net/netfilter/ipvs/ip_vs_lblcr.c
index c234e73968a6..1f75ea83bcf8 100644
--- a/net/ipv4/ipvs/ip_vs_lblcr.c
+++ b/net/netfilter/ipvs/ip_vs_lblcr.c
@@ -106,7 +106,7 @@ ip_vs_dest_set_insert(struct ip_vs_dest_set *set, struct ip_vs_dest *dest)
106 return NULL; 106 return NULL;
107 } 107 }
108 108
109 e = kmalloc(sizeof(struct ip_vs_dest_list), GFP_ATOMIC); 109 e = kmalloc(sizeof(*e), GFP_ATOMIC);
110 if (e == NULL) { 110 if (e == NULL) {
111 IP_VS_ERR("ip_vs_dest_set_insert(): no memory\n"); 111 IP_VS_ERR("ip_vs_dest_set_insert(): no memory\n");
112 return NULL; 112 return NULL;
@@ -116,11 +116,9 @@ ip_vs_dest_set_insert(struct ip_vs_dest_set *set, struct ip_vs_dest *dest)
116 e->dest = dest; 116 e->dest = dest;
117 117
118 /* link it to the list */ 118 /* link it to the list */
119 write_lock(&set->lock);
120 e->next = set->list; 119 e->next = set->list;
121 set->list = e; 120 set->list = e;
122 atomic_inc(&set->size); 121 atomic_inc(&set->size);
123 write_unlock(&set->lock);
124 122
125 set->lastmod = jiffies; 123 set->lastmod = jiffies;
126 return e; 124 return e;
@@ -131,7 +129,6 @@ ip_vs_dest_set_erase(struct ip_vs_dest_set *set, struct ip_vs_dest *dest)
131{ 129{
132 struct ip_vs_dest_list *e, **ep; 130 struct ip_vs_dest_list *e, **ep;
133 131
134 write_lock(&set->lock);
135 for (ep=&set->list, e=*ep; e!=NULL; e=*ep) { 132 for (ep=&set->list, e=*ep; e!=NULL; e=*ep) {
136 if (e->dest == dest) { 133 if (e->dest == dest) {
137 /* HIT */ 134 /* HIT */
@@ -144,7 +141,6 @@ ip_vs_dest_set_erase(struct ip_vs_dest_set *set, struct ip_vs_dest *dest)
144 } 141 }
145 ep = &e->next; 142 ep = &e->next;
146 } 143 }
147 write_unlock(&set->lock);
148} 144}
149 145
150static void ip_vs_dest_set_eraseall(struct ip_vs_dest_set *set) 146static void ip_vs_dest_set_eraseall(struct ip_vs_dest_set *set)
@@ -174,7 +170,6 @@ static inline struct ip_vs_dest *ip_vs_dest_set_min(struct ip_vs_dest_set *set)
174 if (set == NULL) 170 if (set == NULL)
175 return NULL; 171 return NULL;
176 172
177 read_lock(&set->lock);
178 /* select the first destination server, whose weight > 0 */ 173 /* select the first destination server, whose weight > 0 */
179 for (e=set->list; e!=NULL; e=e->next) { 174 for (e=set->list; e!=NULL; e=e->next) {
180 least = e->dest; 175 least = e->dest;
@@ -188,7 +183,6 @@ static inline struct ip_vs_dest *ip_vs_dest_set_min(struct ip_vs_dest_set *set)
188 goto nextstage; 183 goto nextstage;
189 } 184 }
190 } 185 }
191 read_unlock(&set->lock);
192 return NULL; 186 return NULL;
193 187
194 /* find the destination with the weighted least load */ 188 /* find the destination with the weighted least load */
@@ -207,11 +201,10 @@ static inline struct ip_vs_dest *ip_vs_dest_set_min(struct ip_vs_dest_set *set)
207 loh = doh; 201 loh = doh;
208 } 202 }
209 } 203 }
210 read_unlock(&set->lock);
211 204
212 IP_VS_DBG(6, "ip_vs_dest_set_min: server %d.%d.%d.%d:%d " 205 IP_VS_DBG(6, "ip_vs_dest_set_min: server %d.%d.%d.%d:%d "
213 "activeconns %d refcnt %d weight %d overhead %d\n", 206 "activeconns %d refcnt %d weight %d overhead %d\n",
214 NIPQUAD(least->addr), ntohs(least->port), 207 NIPQUAD(least->addr.ip), ntohs(least->port),
215 atomic_read(&least->activeconns), 208 atomic_read(&least->activeconns),
216 atomic_read(&least->refcnt), 209 atomic_read(&least->refcnt),
217 atomic_read(&least->weight), loh); 210 atomic_read(&least->weight), loh);
@@ -229,7 +222,6 @@ static inline struct ip_vs_dest *ip_vs_dest_set_max(struct ip_vs_dest_set *set)
229 if (set == NULL) 222 if (set == NULL)
230 return NULL; 223 return NULL;
231 224
232 read_lock(&set->lock);
233 /* select the first destination server, whose weight > 0 */ 225 /* select the first destination server, whose weight > 0 */
234 for (e=set->list; e!=NULL; e=e->next) { 226 for (e=set->list; e!=NULL; e=e->next) {
235 most = e->dest; 227 most = e->dest;
@@ -239,7 +231,6 @@ static inline struct ip_vs_dest *ip_vs_dest_set_max(struct ip_vs_dest_set *set)
239 goto nextstage; 231 goto nextstage;
240 } 232 }
241 } 233 }
242 read_unlock(&set->lock);
243 return NULL; 234 return NULL;
244 235
245 /* find the destination with the weighted most load */ 236 /* find the destination with the weighted most load */
@@ -256,11 +247,10 @@ static inline struct ip_vs_dest *ip_vs_dest_set_max(struct ip_vs_dest_set *set)
256 moh = doh; 247 moh = doh;
257 } 248 }
258 } 249 }
259 read_unlock(&set->lock);
260 250
261 IP_VS_DBG(6, "ip_vs_dest_set_max: server %d.%d.%d.%d:%d " 251 IP_VS_DBG(6, "ip_vs_dest_set_max: server %d.%d.%d.%d:%d "
262 "activeconns %d refcnt %d weight %d overhead %d\n", 252 "activeconns %d refcnt %d weight %d overhead %d\n",
263 NIPQUAD(most->addr), ntohs(most->port), 253 NIPQUAD(most->addr.ip), ntohs(most->port),
264 atomic_read(&most->activeconns), 254 atomic_read(&most->activeconns),
265 atomic_read(&most->refcnt), 255 atomic_read(&most->refcnt),
266 atomic_read(&most->weight), moh); 256 atomic_read(&most->weight), moh);
@@ -284,7 +274,6 @@ struct ip_vs_lblcr_entry {
284 * IPVS lblcr hash table 274 * IPVS lblcr hash table
285 */ 275 */
286struct ip_vs_lblcr_table { 276struct ip_vs_lblcr_table {
287 rwlock_t lock; /* lock for this table */
288 struct list_head bucket[IP_VS_LBLCR_TAB_SIZE]; /* hash bucket */ 277 struct list_head bucket[IP_VS_LBLCR_TAB_SIZE]; /* hash bucket */
289 atomic_t entries; /* number of entries */ 278 atomic_t entries; /* number of entries */
290 int max_size; /* maximum size of entries */ 279 int max_size; /* maximum size of entries */
@@ -311,32 +300,6 @@ static ctl_table vs_vars_table[] = {
311 300
312static struct ctl_table_header * sysctl_header; 301static struct ctl_table_header * sysctl_header;
313 302
314/*
315 * new/free a ip_vs_lblcr_entry, which is a mapping of a destination
316 * IP address to a server.
317 */
318static inline struct ip_vs_lblcr_entry *ip_vs_lblcr_new(__be32 daddr)
319{
320 struct ip_vs_lblcr_entry *en;
321
322 en = kmalloc(sizeof(struct ip_vs_lblcr_entry), GFP_ATOMIC);
323 if (en == NULL) {
324 IP_VS_ERR("ip_vs_lblcr_new(): no memory\n");
325 return NULL;
326 }
327
328 INIT_LIST_HEAD(&en->list);
329 en->addr = daddr;
330
331 /* initilize its dest set */
332 atomic_set(&(en->set.size), 0);
333 en->set.list = NULL;
334 rwlock_init(&en->set.lock);
335
336 return en;
337}
338
339
340static inline void ip_vs_lblcr_free(struct ip_vs_lblcr_entry *en) 303static inline void ip_vs_lblcr_free(struct ip_vs_lblcr_entry *en)
341{ 304{
342 list_del(&en->list); 305 list_del(&en->list);
@@ -358,55 +321,68 @@ static inline unsigned ip_vs_lblcr_hashkey(__be32 addr)
358 * Hash an entry in the ip_vs_lblcr_table. 321 * Hash an entry in the ip_vs_lblcr_table.
359 * returns bool success. 322 * returns bool success.
360 */ 323 */
361static int 324static void
362ip_vs_lblcr_hash(struct ip_vs_lblcr_table *tbl, struct ip_vs_lblcr_entry *en) 325ip_vs_lblcr_hash(struct ip_vs_lblcr_table *tbl, struct ip_vs_lblcr_entry *en)
363{ 326{
364 unsigned hash; 327 unsigned hash = ip_vs_lblcr_hashkey(en->addr);
365 328
366 if (!list_empty(&en->list)) {
367 IP_VS_ERR("ip_vs_lblcr_hash(): request for already hashed, "
368 "called from %p\n", __builtin_return_address(0));
369 return 0;
370 }
371
372 /*
373 * Hash by destination IP address
374 */
375 hash = ip_vs_lblcr_hashkey(en->addr);
376
377 write_lock(&tbl->lock);
378 list_add(&en->list, &tbl->bucket[hash]); 329 list_add(&en->list, &tbl->bucket[hash]);
379 atomic_inc(&tbl->entries); 330 atomic_inc(&tbl->entries);
380 write_unlock(&tbl->lock);
381
382 return 1;
383} 331}
384 332
385 333
386/* 334/*
387 * Get ip_vs_lblcr_entry associated with supplied parameters. 335 * Get ip_vs_lblcr_entry associated with supplied parameters. Called under
336 * read lock.
388 */ 337 */
389static inline struct ip_vs_lblcr_entry * 338static inline struct ip_vs_lblcr_entry *
390ip_vs_lblcr_get(struct ip_vs_lblcr_table *tbl, __be32 addr) 339ip_vs_lblcr_get(struct ip_vs_lblcr_table *tbl, __be32 addr)
391{ 340{
392 unsigned hash; 341 unsigned hash = ip_vs_lblcr_hashkey(addr);
393 struct ip_vs_lblcr_entry *en; 342 struct ip_vs_lblcr_entry *en;
394 343
395 hash = ip_vs_lblcr_hashkey(addr); 344 list_for_each_entry(en, &tbl->bucket[hash], list)
345 if (en->addr == addr)
346 return en;
396 347
397 read_lock(&tbl->lock); 348 return NULL;
349}
398 350
399 list_for_each_entry(en, &tbl->bucket[hash], list) { 351
400 if (en->addr == addr) { 352/*
401 /* HIT */ 353 * Create or update an ip_vs_lblcr_entry, which is a mapping of a destination
402 read_unlock(&tbl->lock); 354 * IP address to a server. Called under write lock.
403 return en; 355 */
356static inline struct ip_vs_lblcr_entry *
357ip_vs_lblcr_new(struct ip_vs_lblcr_table *tbl, __be32 daddr,
358 struct ip_vs_dest *dest)
359{
360 struct ip_vs_lblcr_entry *en;
361
362 en = ip_vs_lblcr_get(tbl, daddr);
363 if (!en) {
364 en = kmalloc(sizeof(*en), GFP_ATOMIC);
365 if (!en) {
366 IP_VS_ERR("ip_vs_lblcr_new(): no memory\n");
367 return NULL;
404 } 368 }
369
370 en->addr = daddr;
371 en->lastuse = jiffies;
372
373 /* initilize its dest set */
374 atomic_set(&(en->set.size), 0);
375 en->set.list = NULL;
376 rwlock_init(&en->set.lock);
377
378 ip_vs_lblcr_hash(tbl, en);
405 } 379 }
406 380
407 read_unlock(&tbl->lock); 381 write_lock(&en->set.lock);
382 ip_vs_dest_set_insert(&en->set, dest);
383 write_unlock(&en->set.lock);
408 384
409 return NULL; 385 return en;
410} 386}
411 387
412 388
@@ -418,19 +394,18 @@ static void ip_vs_lblcr_flush(struct ip_vs_lblcr_table *tbl)
418 int i; 394 int i;
419 struct ip_vs_lblcr_entry *en, *nxt; 395 struct ip_vs_lblcr_entry *en, *nxt;
420 396
397 /* No locking required, only called during cleanup. */
421 for (i=0; i<IP_VS_LBLCR_TAB_SIZE; i++) { 398 for (i=0; i<IP_VS_LBLCR_TAB_SIZE; i++) {
422 write_lock(&tbl->lock);
423 list_for_each_entry_safe(en, nxt, &tbl->bucket[i], list) { 399 list_for_each_entry_safe(en, nxt, &tbl->bucket[i], list) {
424 ip_vs_lblcr_free(en); 400 ip_vs_lblcr_free(en);
425 atomic_dec(&tbl->entries);
426 } 401 }
427 write_unlock(&tbl->lock);
428 } 402 }
429} 403}
430 404
431 405
432static inline void ip_vs_lblcr_full_check(struct ip_vs_lblcr_table *tbl) 406static inline void ip_vs_lblcr_full_check(struct ip_vs_service *svc)
433{ 407{
408 struct ip_vs_lblcr_table *tbl = svc->sched_data;
434 unsigned long now = jiffies; 409 unsigned long now = jiffies;
435 int i, j; 410 int i, j;
436 struct ip_vs_lblcr_entry *en, *nxt; 411 struct ip_vs_lblcr_entry *en, *nxt;
@@ -438,7 +413,7 @@ static inline void ip_vs_lblcr_full_check(struct ip_vs_lblcr_table *tbl)
438 for (i=0, j=tbl->rover; i<IP_VS_LBLCR_TAB_SIZE; i++) { 413 for (i=0, j=tbl->rover; i<IP_VS_LBLCR_TAB_SIZE; i++) {
439 j = (j + 1) & IP_VS_LBLCR_TAB_MASK; 414 j = (j + 1) & IP_VS_LBLCR_TAB_MASK;
440 415
441 write_lock(&tbl->lock); 416 write_lock(&svc->sched_lock);
442 list_for_each_entry_safe(en, nxt, &tbl->bucket[j], list) { 417 list_for_each_entry_safe(en, nxt, &tbl->bucket[j], list) {
443 if (time_after(en->lastuse+sysctl_ip_vs_lblcr_expiration, 418 if (time_after(en->lastuse+sysctl_ip_vs_lblcr_expiration,
444 now)) 419 now))
@@ -447,7 +422,7 @@ static inline void ip_vs_lblcr_full_check(struct ip_vs_lblcr_table *tbl)
447 ip_vs_lblcr_free(en); 422 ip_vs_lblcr_free(en);
448 atomic_dec(&tbl->entries); 423 atomic_dec(&tbl->entries);
449 } 424 }
450 write_unlock(&tbl->lock); 425 write_unlock(&svc->sched_lock);
451 } 426 }
452 tbl->rover = j; 427 tbl->rover = j;
453} 428}
@@ -466,17 +441,16 @@ static inline void ip_vs_lblcr_full_check(struct ip_vs_lblcr_table *tbl)
466 */ 441 */
467static void ip_vs_lblcr_check_expire(unsigned long data) 442static void ip_vs_lblcr_check_expire(unsigned long data)
468{ 443{
469 struct ip_vs_lblcr_table *tbl; 444 struct ip_vs_service *svc = (struct ip_vs_service *) data;
445 struct ip_vs_lblcr_table *tbl = svc->sched_data;
470 unsigned long now = jiffies; 446 unsigned long now = jiffies;
471 int goal; 447 int goal;
472 int i, j; 448 int i, j;
473 struct ip_vs_lblcr_entry *en, *nxt; 449 struct ip_vs_lblcr_entry *en, *nxt;
474 450
475 tbl = (struct ip_vs_lblcr_table *)data;
476
477 if ((tbl->counter % COUNT_FOR_FULL_EXPIRATION) == 0) { 451 if ((tbl->counter % COUNT_FOR_FULL_EXPIRATION) == 0) {
478 /* do full expiration check */ 452 /* do full expiration check */
479 ip_vs_lblcr_full_check(tbl); 453 ip_vs_lblcr_full_check(svc);
480 tbl->counter = 1; 454 tbl->counter = 1;
481 goto out; 455 goto out;
482 } 456 }
@@ -493,7 +467,7 @@ static void ip_vs_lblcr_check_expire(unsigned long data)
493 for (i=0, j=tbl->rover; i<IP_VS_LBLCR_TAB_SIZE; i++) { 467 for (i=0, j=tbl->rover; i<IP_VS_LBLCR_TAB_SIZE; i++) {
494 j = (j + 1) & IP_VS_LBLCR_TAB_MASK; 468 j = (j + 1) & IP_VS_LBLCR_TAB_MASK;
495 469
496 write_lock(&tbl->lock); 470 write_lock(&svc->sched_lock);
497 list_for_each_entry_safe(en, nxt, &tbl->bucket[j], list) { 471 list_for_each_entry_safe(en, nxt, &tbl->bucket[j], list) {
498 if (time_before(now, en->lastuse+ENTRY_TIMEOUT)) 472 if (time_before(now, en->lastuse+ENTRY_TIMEOUT))
499 continue; 473 continue;
@@ -502,7 +476,7 @@ static void ip_vs_lblcr_check_expire(unsigned long data)
502 atomic_dec(&tbl->entries); 476 atomic_dec(&tbl->entries);
503 goal--; 477 goal--;
504 } 478 }
505 write_unlock(&tbl->lock); 479 write_unlock(&svc->sched_lock);
506 if (goal <= 0) 480 if (goal <= 0)
507 break; 481 break;
508 } 482 }
@@ -520,15 +494,14 @@ static int ip_vs_lblcr_init_svc(struct ip_vs_service *svc)
520 /* 494 /*
521 * Allocate the ip_vs_lblcr_table for this service 495 * Allocate the ip_vs_lblcr_table for this service
522 */ 496 */
523 tbl = kmalloc(sizeof(struct ip_vs_lblcr_table), GFP_ATOMIC); 497 tbl = kmalloc(sizeof(*tbl), GFP_ATOMIC);
524 if (tbl == NULL) { 498 if (tbl == NULL) {
525 IP_VS_ERR("ip_vs_lblcr_init_svc(): no memory\n"); 499 IP_VS_ERR("ip_vs_lblcr_init_svc(): no memory\n");
526 return -ENOMEM; 500 return -ENOMEM;
527 } 501 }
528 svc->sched_data = tbl; 502 svc->sched_data = tbl;
529 IP_VS_DBG(6, "LBLCR hash table (memory=%Zdbytes) allocated for " 503 IP_VS_DBG(6, "LBLCR hash table (memory=%Zdbytes) allocated for "
530 "current service\n", 504 "current service\n", sizeof(*tbl));
531 sizeof(struct ip_vs_lblcr_table));
532 505
533 /* 506 /*
534 * Initialize the hash buckets 507 * Initialize the hash buckets
@@ -536,7 +509,6 @@ static int ip_vs_lblcr_init_svc(struct ip_vs_service *svc)
536 for (i=0; i<IP_VS_LBLCR_TAB_SIZE; i++) { 509 for (i=0; i<IP_VS_LBLCR_TAB_SIZE; i++) {
537 INIT_LIST_HEAD(&tbl->bucket[i]); 510 INIT_LIST_HEAD(&tbl->bucket[i]);
538 } 511 }
539 rwlock_init(&tbl->lock);
540 tbl->max_size = IP_VS_LBLCR_TAB_SIZE*16; 512 tbl->max_size = IP_VS_LBLCR_TAB_SIZE*16;
541 tbl->rover = 0; 513 tbl->rover = 0;
542 tbl->counter = 1; 514 tbl->counter = 1;
@@ -545,9 +517,8 @@ static int ip_vs_lblcr_init_svc(struct ip_vs_service *svc)
545 * Hook periodic timer for garbage collection 517 * Hook periodic timer for garbage collection
546 */ 518 */
547 setup_timer(&tbl->periodic_timer, ip_vs_lblcr_check_expire, 519 setup_timer(&tbl->periodic_timer, ip_vs_lblcr_check_expire,
548 (unsigned long)tbl); 520 (unsigned long)svc);
549 tbl->periodic_timer.expires = jiffies+CHECK_EXPIRE_INTERVAL; 521 mod_timer(&tbl->periodic_timer, jiffies + CHECK_EXPIRE_INTERVAL);
550 add_timer(&tbl->periodic_timer);
551 522
552 return 0; 523 return 0;
553} 524}
@@ -564,22 +535,16 @@ static int ip_vs_lblcr_done_svc(struct ip_vs_service *svc)
564 ip_vs_lblcr_flush(tbl); 535 ip_vs_lblcr_flush(tbl);
565 536
566 /* release the table itself */ 537 /* release the table itself */
567 kfree(svc->sched_data); 538 kfree(tbl);
568 IP_VS_DBG(6, "LBLCR hash table (memory=%Zdbytes) released\n", 539 IP_VS_DBG(6, "LBLCR hash table (memory=%Zdbytes) released\n",
569 sizeof(struct ip_vs_lblcr_table)); 540 sizeof(*tbl));
570 541
571 return 0; 542 return 0;
572} 543}
573 544
574 545
575static int ip_vs_lblcr_update_svc(struct ip_vs_service *svc)
576{
577 return 0;
578}
579
580
581static inline struct ip_vs_dest * 546static inline struct ip_vs_dest *
582__ip_vs_wlc_schedule(struct ip_vs_service *svc, struct iphdr *iph) 547__ip_vs_lblcr_schedule(struct ip_vs_service *svc, struct iphdr *iph)
583{ 548{
584 struct ip_vs_dest *dest, *least; 549 struct ip_vs_dest *dest, *least;
585 int loh, doh; 550 int loh, doh;
@@ -633,7 +598,7 @@ __ip_vs_wlc_schedule(struct ip_vs_service *svc, struct iphdr *iph)
633 598
634 IP_VS_DBG(6, "LBLCR: server %d.%d.%d.%d:%d " 599 IP_VS_DBG(6, "LBLCR: server %d.%d.%d.%d:%d "
635 "activeconns %d refcnt %d weight %d overhead %d\n", 600 "activeconns %d refcnt %d weight %d overhead %d\n",
636 NIPQUAD(least->addr), ntohs(least->port), 601 NIPQUAD(least->addr.ip), ntohs(least->port),
637 atomic_read(&least->activeconns), 602 atomic_read(&least->activeconns),
638 atomic_read(&least->refcnt), 603 atomic_read(&least->refcnt),
639 atomic_read(&least->weight), loh); 604 atomic_read(&least->weight), loh);
@@ -669,51 +634,79 @@ is_overloaded(struct ip_vs_dest *dest, struct ip_vs_service *svc)
669static struct ip_vs_dest * 634static struct ip_vs_dest *
670ip_vs_lblcr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb) 635ip_vs_lblcr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
671{ 636{
672 struct ip_vs_dest *dest; 637 struct ip_vs_lblcr_table *tbl = svc->sched_data;
673 struct ip_vs_lblcr_table *tbl;
674 struct ip_vs_lblcr_entry *en;
675 struct iphdr *iph = ip_hdr(skb); 638 struct iphdr *iph = ip_hdr(skb);
639 struct ip_vs_dest *dest = NULL;
640 struct ip_vs_lblcr_entry *en;
676 641
677 IP_VS_DBG(6, "ip_vs_lblcr_schedule(): Scheduling...\n"); 642 IP_VS_DBG(6, "ip_vs_lblcr_schedule(): Scheduling...\n");
678 643
679 tbl = (struct ip_vs_lblcr_table *)svc->sched_data; 644 /* First look in our cache */
645 read_lock(&svc->sched_lock);
680 en = ip_vs_lblcr_get(tbl, iph->daddr); 646 en = ip_vs_lblcr_get(tbl, iph->daddr);
681 if (en == NULL) { 647 if (en) {
682 dest = __ip_vs_wlc_schedule(svc, iph); 648 /* We only hold a read lock, but this is atomic */
683 if (dest == NULL) { 649 en->lastuse = jiffies;
684 IP_VS_DBG(1, "no destination available\n"); 650
685 return NULL; 651 /* Get the least loaded destination */
686 } 652 read_lock(&en->set.lock);
687 en = ip_vs_lblcr_new(iph->daddr);
688 if (en == NULL) {
689 return NULL;
690 }
691 ip_vs_dest_set_insert(&en->set, dest);
692 ip_vs_lblcr_hash(tbl, en);
693 } else {
694 dest = ip_vs_dest_set_min(&en->set); 653 dest = ip_vs_dest_set_min(&en->set);
695 if (!dest || is_overloaded(dest, svc)) { 654 read_unlock(&en->set.lock);
696 dest = __ip_vs_wlc_schedule(svc, iph); 655
697 if (dest == NULL) { 656 /* More than one destination + enough time passed by, cleanup */
698 IP_VS_DBG(1, "no destination available\n");
699 return NULL;
700 }
701 ip_vs_dest_set_insert(&en->set, dest);
702 }
703 if (atomic_read(&en->set.size) > 1 && 657 if (atomic_read(&en->set.size) > 1 &&
704 jiffies-en->set.lastmod > sysctl_ip_vs_lblcr_expiration) { 658 time_after(jiffies, en->set.lastmod +
659 sysctl_ip_vs_lblcr_expiration)) {
705 struct ip_vs_dest *m; 660 struct ip_vs_dest *m;
661
662 write_lock(&en->set.lock);
706 m = ip_vs_dest_set_max(&en->set); 663 m = ip_vs_dest_set_max(&en->set);
707 if (m) 664 if (m)
708 ip_vs_dest_set_erase(&en->set, m); 665 ip_vs_dest_set_erase(&en->set, m);
666 write_unlock(&en->set.lock);
709 } 667 }
668
669 /* If the destination is not overloaded, use it */
670 if (dest && !is_overloaded(dest, svc)) {
671 read_unlock(&svc->sched_lock);
672 goto out;
673 }
674
675 /* The cache entry is invalid, time to schedule */
676 dest = __ip_vs_lblcr_schedule(svc, iph);
677 if (!dest) {
678 IP_VS_DBG(1, "no destination available\n");
679 read_unlock(&svc->sched_lock);
680 return NULL;
681 }
682
683 /* Update our cache entry */
684 write_lock(&en->set.lock);
685 ip_vs_dest_set_insert(&en->set, dest);
686 write_unlock(&en->set.lock);
687 }
688 read_unlock(&svc->sched_lock);
689
690 if (dest)
691 goto out;
692
693 /* No cache entry, time to schedule */
694 dest = __ip_vs_lblcr_schedule(svc, iph);
695 if (!dest) {
696 IP_VS_DBG(1, "no destination available\n");
697 return NULL;
710 } 698 }
711 en->lastuse = jiffies;
712 699
700 /* If we fail to create a cache entry, we'll just use the valid dest */
701 write_lock(&svc->sched_lock);
702 ip_vs_lblcr_new(tbl, iph->daddr, dest);
703 write_unlock(&svc->sched_lock);
704
705out:
713 IP_VS_DBG(6, "LBLCR: destination IP address %u.%u.%u.%u " 706 IP_VS_DBG(6, "LBLCR: destination IP address %u.%u.%u.%u "
714 "--> server %u.%u.%u.%u:%d\n", 707 "--> server %u.%u.%u.%u:%d\n",
715 NIPQUAD(en->addr), 708 NIPQUAD(iph->daddr),
716 NIPQUAD(dest->addr), 709 NIPQUAD(dest->addr.ip),
717 ntohs(dest->port)); 710 ntohs(dest->port));
718 711
719 return dest; 712 return dest;
@@ -729,9 +722,11 @@ static struct ip_vs_scheduler ip_vs_lblcr_scheduler =
729 .refcnt = ATOMIC_INIT(0), 722 .refcnt = ATOMIC_INIT(0),
730 .module = THIS_MODULE, 723 .module = THIS_MODULE,
731 .n_list = LIST_HEAD_INIT(ip_vs_lblcr_scheduler.n_list), 724 .n_list = LIST_HEAD_INIT(ip_vs_lblcr_scheduler.n_list),
725#ifdef CONFIG_IP_VS_IPV6
726 .supports_ipv6 = 0,
727#endif
732 .init_service = ip_vs_lblcr_init_svc, 728 .init_service = ip_vs_lblcr_init_svc,
733 .done_service = ip_vs_lblcr_done_svc, 729 .done_service = ip_vs_lblcr_done_svc,
734 .update_service = ip_vs_lblcr_update_svc,
735 .schedule = ip_vs_lblcr_schedule, 730 .schedule = ip_vs_lblcr_schedule,
736}; 731};
737 732
diff --git a/net/ipv4/ipvs/ip_vs_lc.c b/net/netfilter/ipvs/ip_vs_lc.c
index ebcdbf75ac65..b69f808ac461 100644
--- a/net/ipv4/ipvs/ip_vs_lc.c
+++ b/net/netfilter/ipvs/ip_vs_lc.c
@@ -20,24 +20,6 @@
20#include <net/ip_vs.h> 20#include <net/ip_vs.h>
21 21
22 22
23static int ip_vs_lc_init_svc(struct ip_vs_service *svc)
24{
25 return 0;
26}
27
28
29static int ip_vs_lc_done_svc(struct ip_vs_service *svc)
30{
31 return 0;
32}
33
34
35static int ip_vs_lc_update_svc(struct ip_vs_service *svc)
36{
37 return 0;
38}
39
40
41static inline unsigned int 23static inline unsigned int
42ip_vs_lc_dest_overhead(struct ip_vs_dest *dest) 24ip_vs_lc_dest_overhead(struct ip_vs_dest *dest)
43{ 25{
@@ -85,10 +67,10 @@ ip_vs_lc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
85 } 67 }
86 68
87 if (least) 69 if (least)
88 IP_VS_DBG(6, "LC: server %u.%u.%u.%u:%u activeconns %d inactconns %d\n", 70 IP_VS_DBG_BUF(6, "LC: server %s:%u activeconns %d inactconns %d\n",
89 NIPQUAD(least->addr), ntohs(least->port), 71 IP_VS_DBG_ADDR(svc->af, &least->addr), ntohs(least->port),
90 atomic_read(&least->activeconns), 72 atomic_read(&least->activeconns),
91 atomic_read(&least->inactconns)); 73 atomic_read(&least->inactconns));
92 74
93 return least; 75 return least;
94} 76}
@@ -99,9 +81,9 @@ static struct ip_vs_scheduler ip_vs_lc_scheduler = {
99 .refcnt = ATOMIC_INIT(0), 81 .refcnt = ATOMIC_INIT(0),
100 .module = THIS_MODULE, 82 .module = THIS_MODULE,
101 .n_list = LIST_HEAD_INIT(ip_vs_lc_scheduler.n_list), 83 .n_list = LIST_HEAD_INIT(ip_vs_lc_scheduler.n_list),
102 .init_service = ip_vs_lc_init_svc, 84#ifdef CONFIG_IP_VS_IPV6
103 .done_service = ip_vs_lc_done_svc, 85 .supports_ipv6 = 1,
104 .update_service = ip_vs_lc_update_svc, 86#endif
105 .schedule = ip_vs_lc_schedule, 87 .schedule = ip_vs_lc_schedule,
106}; 88};
107 89
diff --git a/net/ipv4/ipvs/ip_vs_nq.c b/net/netfilter/ipvs/ip_vs_nq.c
index 92f3a6770031..9a2d8033f08f 100644
--- a/net/ipv4/ipvs/ip_vs_nq.c
+++ b/net/netfilter/ipvs/ip_vs_nq.c
@@ -37,27 +37,6 @@
37#include <net/ip_vs.h> 37#include <net/ip_vs.h>
38 38
39 39
40static int
41ip_vs_nq_init_svc(struct ip_vs_service *svc)
42{
43 return 0;
44}
45
46
47static int
48ip_vs_nq_done_svc(struct ip_vs_service *svc)
49{
50 return 0;
51}
52
53
54static int
55ip_vs_nq_update_svc(struct ip_vs_service *svc)
56{
57 return 0;
58}
59
60
61static inline unsigned int 40static inline unsigned int
62ip_vs_nq_dest_overhead(struct ip_vs_dest *dest) 41ip_vs_nq_dest_overhead(struct ip_vs_dest *dest)
63{ 42{
@@ -120,12 +99,12 @@ ip_vs_nq_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
120 return NULL; 99 return NULL;
121 100
122 out: 101 out:
123 IP_VS_DBG(6, "NQ: server %u.%u.%u.%u:%u " 102 IP_VS_DBG_BUF(6, "NQ: server %s:%u "
124 "activeconns %d refcnt %d weight %d overhead %d\n", 103 "activeconns %d refcnt %d weight %d overhead %d\n",
125 NIPQUAD(least->addr), ntohs(least->port), 104 IP_VS_DBG_ADDR(svc->af, &least->addr), ntohs(least->port),
126 atomic_read(&least->activeconns), 105 atomic_read(&least->activeconns),
127 atomic_read(&least->refcnt), 106 atomic_read(&least->refcnt),
128 atomic_read(&least->weight), loh); 107 atomic_read(&least->weight), loh);
129 108
130 return least; 109 return least;
131} 110}
@@ -137,9 +116,9 @@ static struct ip_vs_scheduler ip_vs_nq_scheduler =
137 .refcnt = ATOMIC_INIT(0), 116 .refcnt = ATOMIC_INIT(0),
138 .module = THIS_MODULE, 117 .module = THIS_MODULE,
139 .n_list = LIST_HEAD_INIT(ip_vs_nq_scheduler.n_list), 118 .n_list = LIST_HEAD_INIT(ip_vs_nq_scheduler.n_list),
140 .init_service = ip_vs_nq_init_svc, 119#ifdef CONFIG_IP_VS_IPV6
141 .done_service = ip_vs_nq_done_svc, 120 .supports_ipv6 = 1,
142 .update_service = ip_vs_nq_update_svc, 121#endif
143 .schedule = ip_vs_nq_schedule, 122 .schedule = ip_vs_nq_schedule,
144}; 123};
145 124
diff --git a/net/ipv4/ipvs/ip_vs_proto.c b/net/netfilter/ipvs/ip_vs_proto.c
index 6099a88fc200..0791f9e08feb 100644
--- a/net/ipv4/ipvs/ip_vs_proto.c
+++ b/net/netfilter/ipvs/ip_vs_proto.c
@@ -151,11 +151,11 @@ const char * ip_vs_state_name(__u16 proto, int state)
151} 151}
152 152
153 153
154void 154static void
155ip_vs_tcpudp_debug_packet(struct ip_vs_protocol *pp, 155ip_vs_tcpudp_debug_packet_v4(struct ip_vs_protocol *pp,
156 const struct sk_buff *skb, 156 const struct sk_buff *skb,
157 int offset, 157 int offset,
158 const char *msg) 158 const char *msg)
159{ 159{
160 char buf[128]; 160 char buf[128];
161 struct iphdr _iph, *ih; 161 struct iphdr _iph, *ih;
@@ -189,6 +189,61 @@ ip_vs_tcpudp_debug_packet(struct ip_vs_protocol *pp,
189 printk(KERN_DEBUG "IPVS: %s: %s\n", msg, buf); 189 printk(KERN_DEBUG "IPVS: %s: %s\n", msg, buf);
190} 190}
191 191
192#ifdef CONFIG_IP_VS_IPV6
193static void
194ip_vs_tcpudp_debug_packet_v6(struct ip_vs_protocol *pp,
195 const struct sk_buff *skb,
196 int offset,
197 const char *msg)
198{
199 char buf[192];
200 struct ipv6hdr _iph, *ih;
201
202 ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
203 if (ih == NULL)
204 sprintf(buf, "%s TRUNCATED", pp->name);
205 else if (ih->nexthdr == IPPROTO_FRAGMENT)
206 sprintf(buf, "%s " NIP6_FMT "->" NIP6_FMT " frag",
207 pp->name, NIP6(ih->saddr),
208 NIP6(ih->daddr));
209 else {
210 __be16 _ports[2], *pptr;
211
212 pptr = skb_header_pointer(skb, offset + sizeof(struct ipv6hdr),
213 sizeof(_ports), _ports);
214 if (pptr == NULL)
215 sprintf(buf, "%s TRUNCATED " NIP6_FMT "->" NIP6_FMT,
216 pp->name,
217 NIP6(ih->saddr),
218 NIP6(ih->daddr));
219 else
220 sprintf(buf, "%s " NIP6_FMT ":%u->" NIP6_FMT ":%u",
221 pp->name,
222 NIP6(ih->saddr),
223 ntohs(pptr[0]),
224 NIP6(ih->daddr),
225 ntohs(pptr[1]));
226 }
227
228 printk(KERN_DEBUG "IPVS: %s: %s\n", msg, buf);
229}
230#endif
231
232
233void
234ip_vs_tcpudp_debug_packet(struct ip_vs_protocol *pp,
235 const struct sk_buff *skb,
236 int offset,
237 const char *msg)
238{
239#ifdef CONFIG_IP_VS_IPV6
240 if (skb->protocol == htons(ETH_P_IPV6))
241 ip_vs_tcpudp_debug_packet_v6(pp, skb, offset, msg);
242 else
243#endif
244 ip_vs_tcpudp_debug_packet_v4(pp, skb, offset, msg);
245}
246
192 247
193int __init ip_vs_protocol_init(void) 248int __init ip_vs_protocol_init(void)
194{ 249{
diff --git a/net/netfilter/ipvs/ip_vs_proto_ah_esp.c b/net/netfilter/ipvs/ip_vs_proto_ah_esp.c
new file mode 100644
index 000000000000..80ab0c8e5b4a
--- /dev/null
+++ b/net/netfilter/ipvs/ip_vs_proto_ah_esp.c
@@ -0,0 +1,235 @@
1/*
2 * ip_vs_proto_ah_esp.c: AH/ESP IPSec load balancing support for IPVS
3 *
4 * Authors: Julian Anastasov <ja@ssi.bg>, February 2002
5 * Wensong Zhang <wensong@linuxvirtualserver.org>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * version 2 as published by the Free Software Foundation;
10 *
11 */
12
13#include <linux/in.h>
14#include <linux/ip.h>
15#include <linux/module.h>
16#include <linux/kernel.h>
17#include <linux/netfilter.h>
18#include <linux/netfilter_ipv4.h>
19
20#include <net/ip_vs.h>
21
22
23/* TODO:
24
25struct isakmp_hdr {
26 __u8 icookie[8];
27 __u8 rcookie[8];
28 __u8 np;
29 __u8 version;
30 __u8 xchgtype;
31 __u8 flags;
32 __u32 msgid;
33 __u32 length;
34};
35
36*/
37
38#define PORT_ISAKMP 500
39
40
41static struct ip_vs_conn *
42ah_esp_conn_in_get(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp,
43 const struct ip_vs_iphdr *iph, unsigned int proto_off,
44 int inverse)
45{
46 struct ip_vs_conn *cp;
47
48 if (likely(!inverse)) {
49 cp = ip_vs_conn_in_get(af, IPPROTO_UDP,
50 &iph->saddr,
51 htons(PORT_ISAKMP),
52 &iph->daddr,
53 htons(PORT_ISAKMP));
54 } else {
55 cp = ip_vs_conn_in_get(af, IPPROTO_UDP,
56 &iph->daddr,
57 htons(PORT_ISAKMP),
58 &iph->saddr,
59 htons(PORT_ISAKMP));
60 }
61
62 if (!cp) {
63 /*
64 * We are not sure if the packet is from our
65 * service, so our conn_schedule hook should return NF_ACCEPT
66 */
67 IP_VS_DBG_BUF(12, "Unknown ISAKMP entry for outin packet "
68 "%s%s %s->%s\n",
69 inverse ? "ICMP+" : "",
70 pp->name,
71 IP_VS_DBG_ADDR(af, &iph->saddr),
72 IP_VS_DBG_ADDR(af, &iph->daddr));
73 }
74
75 return cp;
76}
77
78
79static struct ip_vs_conn *
80ah_esp_conn_out_get(int af, const struct sk_buff *skb,
81 struct ip_vs_protocol *pp,
82 const struct ip_vs_iphdr *iph,
83 unsigned int proto_off,
84 int inverse)
85{
86 struct ip_vs_conn *cp;
87
88 if (likely(!inverse)) {
89 cp = ip_vs_conn_out_get(af, IPPROTO_UDP,
90 &iph->saddr,
91 htons(PORT_ISAKMP),
92 &iph->daddr,
93 htons(PORT_ISAKMP));
94 } else {
95 cp = ip_vs_conn_out_get(af, IPPROTO_UDP,
96 &iph->daddr,
97 htons(PORT_ISAKMP),
98 &iph->saddr,
99 htons(PORT_ISAKMP));
100 }
101
102 if (!cp) {
103 IP_VS_DBG_BUF(12, "Unknown ISAKMP entry for inout packet "
104 "%s%s %s->%s\n",
105 inverse ? "ICMP+" : "",
106 pp->name,
107 IP_VS_DBG_ADDR(af, &iph->saddr),
108 IP_VS_DBG_ADDR(af, &iph->daddr));
109 }
110
111 return cp;
112}
113
114
115static int
116ah_esp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
117 int *verdict, struct ip_vs_conn **cpp)
118{
119 /*
120 * AH/ESP is only related traffic. Pass the packet to IP stack.
121 */
122 *verdict = NF_ACCEPT;
123 return 0;
124}
125
126
127static void
128ah_esp_debug_packet_v4(struct ip_vs_protocol *pp, const struct sk_buff *skb,
129 int offset, const char *msg)
130{
131 char buf[256];
132 struct iphdr _iph, *ih;
133
134 ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
135 if (ih == NULL)
136 sprintf(buf, "%s TRUNCATED", pp->name);
137 else
138 sprintf(buf, "%s %u.%u.%u.%u->%u.%u.%u.%u",
139 pp->name, NIPQUAD(ih->saddr),
140 NIPQUAD(ih->daddr));
141
142 printk(KERN_DEBUG "IPVS: %s: %s\n", msg, buf);
143}
144
145#ifdef CONFIG_IP_VS_IPV6
146static void
147ah_esp_debug_packet_v6(struct ip_vs_protocol *pp, const struct sk_buff *skb,
148 int offset, const char *msg)
149{
150 char buf[256];
151 struct ipv6hdr _iph, *ih;
152
153 ih = skb_header_pointer(skb, offset, sizeof(_iph), &_iph);
154 if (ih == NULL)
155 sprintf(buf, "%s TRUNCATED", pp->name);
156 else
157 sprintf(buf, "%s " NIP6_FMT "->" NIP6_FMT,
158 pp->name, NIP6(ih->saddr),
159 NIP6(ih->daddr));
160
161 printk(KERN_DEBUG "IPVS: %s: %s\n", msg, buf);
162}
163#endif
164
165static void
166ah_esp_debug_packet(struct ip_vs_protocol *pp, const struct sk_buff *skb,
167 int offset, const char *msg)
168{
169#ifdef CONFIG_IP_VS_IPV6
170 if (skb->protocol == htons(ETH_P_IPV6))
171 ah_esp_debug_packet_v6(pp, skb, offset, msg);
172 else
173#endif
174 ah_esp_debug_packet_v4(pp, skb, offset, msg);
175}
176
177
178static void ah_esp_init(struct ip_vs_protocol *pp)
179{
180 /* nothing to do now */
181}
182
183
184static void ah_esp_exit(struct ip_vs_protocol *pp)
185{
186 /* nothing to do now */
187}
188
189
190#ifdef CONFIG_IP_VS_PROTO_AH
191struct ip_vs_protocol ip_vs_protocol_ah = {
192 .name = "AH",
193 .protocol = IPPROTO_AH,
194 .num_states = 1,
195 .dont_defrag = 1,
196 .init = ah_esp_init,
197 .exit = ah_esp_exit,
198 .conn_schedule = ah_esp_conn_schedule,
199 .conn_in_get = ah_esp_conn_in_get,
200 .conn_out_get = ah_esp_conn_out_get,
201 .snat_handler = NULL,
202 .dnat_handler = NULL,
203 .csum_check = NULL,
204 .state_transition = NULL,
205 .register_app = NULL,
206 .unregister_app = NULL,
207 .app_conn_bind = NULL,
208 .debug_packet = ah_esp_debug_packet,
209 .timeout_change = NULL, /* ISAKMP */
210 .set_state_timeout = NULL,
211};
212#endif
213
214#ifdef CONFIG_IP_VS_PROTO_ESP
215struct ip_vs_protocol ip_vs_protocol_esp = {
216 .name = "ESP",
217 .protocol = IPPROTO_ESP,
218 .num_states = 1,
219 .dont_defrag = 1,
220 .init = ah_esp_init,
221 .exit = ah_esp_exit,
222 .conn_schedule = ah_esp_conn_schedule,
223 .conn_in_get = ah_esp_conn_in_get,
224 .conn_out_get = ah_esp_conn_out_get,
225 .snat_handler = NULL,
226 .dnat_handler = NULL,
227 .csum_check = NULL,
228 .state_transition = NULL,
229 .register_app = NULL,
230 .unregister_app = NULL,
231 .app_conn_bind = NULL,
232 .debug_packet = ah_esp_debug_packet,
233 .timeout_change = NULL, /* ISAKMP */
234};
235#endif
diff --git a/net/ipv4/ipvs/ip_vs_proto_tcp.c b/net/netfilter/ipvs/ip_vs_proto_tcp.c
index d0ea467986a0..dd4566ea2bff 100644
--- a/net/ipv4/ipvs/ip_vs_proto_tcp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_tcp.c
@@ -18,6 +18,7 @@
18#include <linux/tcp.h> /* for tcphdr */ 18#include <linux/tcp.h> /* for tcphdr */
19#include <net/ip.h> 19#include <net/ip.h>
20#include <net/tcp.h> /* for csum_tcpudp_magic */ 20#include <net/tcp.h> /* for csum_tcpudp_magic */
21#include <net/ip6_checksum.h>
21#include <linux/netfilter.h> 22#include <linux/netfilter.h>
22#include <linux/netfilter_ipv4.h> 23#include <linux/netfilter_ipv4.h>
23 24
@@ -25,8 +26,9 @@
25 26
26 27
27static struct ip_vs_conn * 28static struct ip_vs_conn *
28tcp_conn_in_get(const struct sk_buff *skb, struct ip_vs_protocol *pp, 29tcp_conn_in_get(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp,
29 const struct iphdr *iph, unsigned int proto_off, int inverse) 30 const struct ip_vs_iphdr *iph, unsigned int proto_off,
31 int inverse)
30{ 32{
31 __be16 _ports[2], *pptr; 33 __be16 _ports[2], *pptr;
32 34
@@ -35,19 +37,20 @@ tcp_conn_in_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
35 return NULL; 37 return NULL;
36 38
37 if (likely(!inverse)) { 39 if (likely(!inverse)) {
38 return ip_vs_conn_in_get(iph->protocol, 40 return ip_vs_conn_in_get(af, iph->protocol,
39 iph->saddr, pptr[0], 41 &iph->saddr, pptr[0],
40 iph->daddr, pptr[1]); 42 &iph->daddr, pptr[1]);
41 } else { 43 } else {
42 return ip_vs_conn_in_get(iph->protocol, 44 return ip_vs_conn_in_get(af, iph->protocol,
43 iph->daddr, pptr[1], 45 &iph->daddr, pptr[1],
44 iph->saddr, pptr[0]); 46 &iph->saddr, pptr[0]);
45 } 47 }
46} 48}
47 49
48static struct ip_vs_conn * 50static struct ip_vs_conn *
49tcp_conn_out_get(const struct sk_buff *skb, struct ip_vs_protocol *pp, 51tcp_conn_out_get(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp,
50 const struct iphdr *iph, unsigned int proto_off, int inverse) 52 const struct ip_vs_iphdr *iph, unsigned int proto_off,
53 int inverse)
51{ 54{
52 __be16 _ports[2], *pptr; 55 __be16 _ports[2], *pptr;
53 56
@@ -56,34 +59,36 @@ tcp_conn_out_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
56 return NULL; 59 return NULL;
57 60
58 if (likely(!inverse)) { 61 if (likely(!inverse)) {
59 return ip_vs_conn_out_get(iph->protocol, 62 return ip_vs_conn_out_get(af, iph->protocol,
60 iph->saddr, pptr[0], 63 &iph->saddr, pptr[0],
61 iph->daddr, pptr[1]); 64 &iph->daddr, pptr[1]);
62 } else { 65 } else {
63 return ip_vs_conn_out_get(iph->protocol, 66 return ip_vs_conn_out_get(af, iph->protocol,
64 iph->daddr, pptr[1], 67 &iph->daddr, pptr[1],
65 iph->saddr, pptr[0]); 68 &iph->saddr, pptr[0]);
66 } 69 }
67} 70}
68 71
69 72
70static int 73static int
71tcp_conn_schedule(struct sk_buff *skb, 74tcp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
72 struct ip_vs_protocol *pp,
73 int *verdict, struct ip_vs_conn **cpp) 75 int *verdict, struct ip_vs_conn **cpp)
74{ 76{
75 struct ip_vs_service *svc; 77 struct ip_vs_service *svc;
76 struct tcphdr _tcph, *th; 78 struct tcphdr _tcph, *th;
79 struct ip_vs_iphdr iph;
77 80
78 th = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_tcph), &_tcph); 81 ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
82
83 th = skb_header_pointer(skb, iph.len, sizeof(_tcph), &_tcph);
79 if (th == NULL) { 84 if (th == NULL) {
80 *verdict = NF_DROP; 85 *verdict = NF_DROP;
81 return 0; 86 return 0;
82 } 87 }
83 88
84 if (th->syn && 89 if (th->syn &&
85 (svc = ip_vs_service_get(skb->mark, ip_hdr(skb)->protocol, 90 (svc = ip_vs_service_get(af, skb->mark, iph.protocol, &iph.daddr,
86 ip_hdr(skb)->daddr, th->dest))) { 91 th->dest))) {
87 if (ip_vs_todrop()) { 92 if (ip_vs_todrop()) {
88 /* 93 /*
89 * It seems that we are very loaded. 94 * It seems that we are very loaded.
@@ -110,22 +115,62 @@ tcp_conn_schedule(struct sk_buff *skb,
110 115
111 116
112static inline void 117static inline void
113tcp_fast_csum_update(struct tcphdr *tcph, __be32 oldip, __be32 newip, 118tcp_fast_csum_update(int af, struct tcphdr *tcph,
119 const union nf_inet_addr *oldip,
120 const union nf_inet_addr *newip,
114 __be16 oldport, __be16 newport) 121 __be16 oldport, __be16 newport)
115{ 122{
123#ifdef CONFIG_IP_VS_IPV6
124 if (af == AF_INET6)
125 tcph->check =
126 csum_fold(ip_vs_check_diff16(oldip->ip6, newip->ip6,
127 ip_vs_check_diff2(oldport, newport,
128 ~csum_unfold(tcph->check))));
129 else
130#endif
116 tcph->check = 131 tcph->check =
117 csum_fold(ip_vs_check_diff4(oldip, newip, 132 csum_fold(ip_vs_check_diff4(oldip->ip, newip->ip,
118 ip_vs_check_diff2(oldport, newport, 133 ip_vs_check_diff2(oldport, newport,
119 ~csum_unfold(tcph->check)))); 134 ~csum_unfold(tcph->check))));
120} 135}
121 136
122 137
138static inline void
139tcp_partial_csum_update(int af, struct tcphdr *tcph,
140 const union nf_inet_addr *oldip,
141 const union nf_inet_addr *newip,
142 __be16 oldlen, __be16 newlen)
143{
144#ifdef CONFIG_IP_VS_IPV6
145 if (af == AF_INET6)
146 tcph->check =
147 csum_fold(ip_vs_check_diff16(oldip->ip6, newip->ip6,
148 ip_vs_check_diff2(oldlen, newlen,
149 ~csum_unfold(tcph->check))));
150 else
151#endif
152 tcph->check =
153 csum_fold(ip_vs_check_diff4(oldip->ip, newip->ip,
154 ip_vs_check_diff2(oldlen, newlen,
155 ~csum_unfold(tcph->check))));
156}
157
158
123static int 159static int
124tcp_snat_handler(struct sk_buff *skb, 160tcp_snat_handler(struct sk_buff *skb,
125 struct ip_vs_protocol *pp, struct ip_vs_conn *cp) 161 struct ip_vs_protocol *pp, struct ip_vs_conn *cp)
126{ 162{
127 struct tcphdr *tcph; 163 struct tcphdr *tcph;
128 const unsigned int tcphoff = ip_hdrlen(skb); 164 unsigned int tcphoff;
165 int oldlen;
166
167#ifdef CONFIG_IP_VS_IPV6
168 if (cp->af == AF_INET6)
169 tcphoff = sizeof(struct ipv6hdr);
170 else
171#endif
172 tcphoff = ip_hdrlen(skb);
173 oldlen = skb->len - tcphoff;
129 174
130 /* csum_check requires unshared skb */ 175 /* csum_check requires unshared skb */
131 if (!skb_make_writable(skb, tcphoff+sizeof(*tcph))) 176 if (!skb_make_writable(skb, tcphoff+sizeof(*tcph)))
@@ -133,7 +178,7 @@ tcp_snat_handler(struct sk_buff *skb,
133 178
134 if (unlikely(cp->app != NULL)) { 179 if (unlikely(cp->app != NULL)) {
135 /* Some checks before mangling */ 180 /* Some checks before mangling */
136 if (pp->csum_check && !pp->csum_check(skb, pp)) 181 if (pp->csum_check && !pp->csum_check(cp->af, skb, pp))
137 return 0; 182 return 0;
138 183
139 /* Call application helper if needed */ 184 /* Call application helper if needed */
@@ -141,13 +186,17 @@ tcp_snat_handler(struct sk_buff *skb,
141 return 0; 186 return 0;
142 } 187 }
143 188
144 tcph = (void *)ip_hdr(skb) + tcphoff; 189 tcph = (void *)skb_network_header(skb) + tcphoff;
145 tcph->source = cp->vport; 190 tcph->source = cp->vport;
146 191
147 /* Adjust TCP checksums */ 192 /* Adjust TCP checksums */
148 if (!cp->app) { 193 if (skb->ip_summed == CHECKSUM_PARTIAL) {
194 tcp_partial_csum_update(cp->af, tcph, &cp->daddr, &cp->vaddr,
195 htonl(oldlen),
196 htonl(skb->len - tcphoff));
197 } else if (!cp->app) {
149 /* Only port and addr are changed, do fast csum update */ 198 /* Only port and addr are changed, do fast csum update */
150 tcp_fast_csum_update(tcph, cp->daddr, cp->vaddr, 199 tcp_fast_csum_update(cp->af, tcph, &cp->daddr, &cp->vaddr,
151 cp->dport, cp->vport); 200 cp->dport, cp->vport);
152 if (skb->ip_summed == CHECKSUM_COMPLETE) 201 if (skb->ip_summed == CHECKSUM_COMPLETE)
153 skb->ip_summed = CHECKSUM_NONE; 202 skb->ip_summed = CHECKSUM_NONE;
@@ -155,9 +204,20 @@ tcp_snat_handler(struct sk_buff *skb,
155 /* full checksum calculation */ 204 /* full checksum calculation */
156 tcph->check = 0; 205 tcph->check = 0;
157 skb->csum = skb_checksum(skb, tcphoff, skb->len - tcphoff, 0); 206 skb->csum = skb_checksum(skb, tcphoff, skb->len - tcphoff, 0);
158 tcph->check = csum_tcpudp_magic(cp->vaddr, cp->caddr, 207#ifdef CONFIG_IP_VS_IPV6
159 skb->len - tcphoff, 208 if (cp->af == AF_INET6)
160 cp->protocol, skb->csum); 209 tcph->check = csum_ipv6_magic(&cp->vaddr.in6,
210 &cp->caddr.in6,
211 skb->len - tcphoff,
212 cp->protocol, skb->csum);
213 else
214#endif
215 tcph->check = csum_tcpudp_magic(cp->vaddr.ip,
216 cp->caddr.ip,
217 skb->len - tcphoff,
218 cp->protocol,
219 skb->csum);
220
161 IP_VS_DBG(11, "O-pkt: %s O-csum=%d (+%zd)\n", 221 IP_VS_DBG(11, "O-pkt: %s O-csum=%d (+%zd)\n",
162 pp->name, tcph->check, 222 pp->name, tcph->check,
163 (char*)&(tcph->check) - (char*)tcph); 223 (char*)&(tcph->check) - (char*)tcph);
@@ -171,7 +231,16 @@ tcp_dnat_handler(struct sk_buff *skb,
171 struct ip_vs_protocol *pp, struct ip_vs_conn *cp) 231 struct ip_vs_protocol *pp, struct ip_vs_conn *cp)
172{ 232{
173 struct tcphdr *tcph; 233 struct tcphdr *tcph;
174 const unsigned int tcphoff = ip_hdrlen(skb); 234 unsigned int tcphoff;
235 int oldlen;
236
237#ifdef CONFIG_IP_VS_IPV6
238 if (cp->af == AF_INET6)
239 tcphoff = sizeof(struct ipv6hdr);
240 else
241#endif
242 tcphoff = ip_hdrlen(skb);
243 oldlen = skb->len - tcphoff;
175 244
176 /* csum_check requires unshared skb */ 245 /* csum_check requires unshared skb */
177 if (!skb_make_writable(skb, tcphoff+sizeof(*tcph))) 246 if (!skb_make_writable(skb, tcphoff+sizeof(*tcph)))
@@ -179,7 +248,7 @@ tcp_dnat_handler(struct sk_buff *skb,
179 248
180 if (unlikely(cp->app != NULL)) { 249 if (unlikely(cp->app != NULL)) {
181 /* Some checks before mangling */ 250 /* Some checks before mangling */
182 if (pp->csum_check && !pp->csum_check(skb, pp)) 251 if (pp->csum_check && !pp->csum_check(cp->af, skb, pp))
183 return 0; 252 return 0;
184 253
185 /* 254 /*
@@ -190,15 +259,19 @@ tcp_dnat_handler(struct sk_buff *skb,
190 return 0; 259 return 0;
191 } 260 }
192 261
193 tcph = (void *)ip_hdr(skb) + tcphoff; 262 tcph = (void *)skb_network_header(skb) + tcphoff;
194 tcph->dest = cp->dport; 263 tcph->dest = cp->dport;
195 264
196 /* 265 /*
197 * Adjust TCP checksums 266 * Adjust TCP checksums
198 */ 267 */
199 if (!cp->app) { 268 if (skb->ip_summed == CHECKSUM_PARTIAL) {
269 tcp_partial_csum_update(cp->af, tcph, &cp->daddr, &cp->vaddr,
270 htonl(oldlen),
271 htonl(skb->len - tcphoff));
272 } else if (!cp->app) {
200 /* Only port and addr are changed, do fast csum update */ 273 /* Only port and addr are changed, do fast csum update */
201 tcp_fast_csum_update(tcph, cp->vaddr, cp->daddr, 274 tcp_fast_csum_update(cp->af, tcph, &cp->vaddr, &cp->daddr,
202 cp->vport, cp->dport); 275 cp->vport, cp->dport);
203 if (skb->ip_summed == CHECKSUM_COMPLETE) 276 if (skb->ip_summed == CHECKSUM_COMPLETE)
204 skb->ip_summed = CHECKSUM_NONE; 277 skb->ip_summed = CHECKSUM_NONE;
@@ -206,9 +279,19 @@ tcp_dnat_handler(struct sk_buff *skb,
206 /* full checksum calculation */ 279 /* full checksum calculation */
207 tcph->check = 0; 280 tcph->check = 0;
208 skb->csum = skb_checksum(skb, tcphoff, skb->len - tcphoff, 0); 281 skb->csum = skb_checksum(skb, tcphoff, skb->len - tcphoff, 0);
209 tcph->check = csum_tcpudp_magic(cp->caddr, cp->daddr, 282#ifdef CONFIG_IP_VS_IPV6
210 skb->len - tcphoff, 283 if (cp->af == AF_INET6)
211 cp->protocol, skb->csum); 284 tcph->check = csum_ipv6_magic(&cp->caddr.in6,
285 &cp->daddr.in6,
286 skb->len - tcphoff,
287 cp->protocol, skb->csum);
288 else
289#endif
290 tcph->check = csum_tcpudp_magic(cp->caddr.ip,
291 cp->daddr.ip,
292 skb->len - tcphoff,
293 cp->protocol,
294 skb->csum);
212 skb->ip_summed = CHECKSUM_UNNECESSARY; 295 skb->ip_summed = CHECKSUM_UNNECESSARY;
213 } 296 }
214 return 1; 297 return 1;
@@ -216,21 +299,43 @@ tcp_dnat_handler(struct sk_buff *skb,
216 299
217 300
218static int 301static int
219tcp_csum_check(struct sk_buff *skb, struct ip_vs_protocol *pp) 302tcp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
220{ 303{
221 const unsigned int tcphoff = ip_hdrlen(skb); 304 unsigned int tcphoff;
305
306#ifdef CONFIG_IP_VS_IPV6
307 if (af == AF_INET6)
308 tcphoff = sizeof(struct ipv6hdr);
309 else
310#endif
311 tcphoff = ip_hdrlen(skb);
222 312
223 switch (skb->ip_summed) { 313 switch (skb->ip_summed) {
224 case CHECKSUM_NONE: 314 case CHECKSUM_NONE:
225 skb->csum = skb_checksum(skb, tcphoff, skb->len - tcphoff, 0); 315 skb->csum = skb_checksum(skb, tcphoff, skb->len - tcphoff, 0);
226 case CHECKSUM_COMPLETE: 316 case CHECKSUM_COMPLETE:
227 if (csum_tcpudp_magic(ip_hdr(skb)->saddr, ip_hdr(skb)->daddr, 317#ifdef CONFIG_IP_VS_IPV6
228 skb->len - tcphoff, 318 if (af == AF_INET6) {
229 ip_hdr(skb)->protocol, skb->csum)) { 319 if (csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
230 IP_VS_DBG_RL_PKT(0, pp, skb, 0, 320 &ipv6_hdr(skb)->daddr,
231 "Failed checksum for"); 321 skb->len - tcphoff,
232 return 0; 322 ipv6_hdr(skb)->nexthdr,
233 } 323 skb->csum)) {
324 IP_VS_DBG_RL_PKT(0, pp, skb, 0,
325 "Failed checksum for");
326 return 0;
327 }
328 } else
329#endif
330 if (csum_tcpudp_magic(ip_hdr(skb)->saddr,
331 ip_hdr(skb)->daddr,
332 skb->len - tcphoff,
333 ip_hdr(skb)->protocol,
334 skb->csum)) {
335 IP_VS_DBG_RL_PKT(0, pp, skb, 0,
336 "Failed checksum for");
337 return 0;
338 }
234 break; 339 break;
235 default: 340 default:
236 /* No need to checksum. */ 341 /* No need to checksum. */
@@ -419,19 +524,23 @@ set_tcp_state(struct ip_vs_protocol *pp, struct ip_vs_conn *cp,
419 if (new_state != cp->state) { 524 if (new_state != cp->state) {
420 struct ip_vs_dest *dest = cp->dest; 525 struct ip_vs_dest *dest = cp->dest;
421 526
422 IP_VS_DBG(8, "%s %s [%c%c%c%c] %u.%u.%u.%u:%d->" 527 IP_VS_DBG_BUF(8, "%s %s [%c%c%c%c] %s:%d->"
423 "%u.%u.%u.%u:%d state: %s->%s conn->refcnt:%d\n", 528 "%s:%d state: %s->%s conn->refcnt:%d\n",
424 pp->name, 529 pp->name,
425 (state_off==TCP_DIR_OUTPUT)?"output ":"input ", 530 ((state_off == TCP_DIR_OUTPUT) ?
426 th->syn? 'S' : '.', 531 "output " : "input "),
427 th->fin? 'F' : '.', 532 th->syn ? 'S' : '.',
428 th->ack? 'A' : '.', 533 th->fin ? 'F' : '.',
429 th->rst? 'R' : '.', 534 th->ack ? 'A' : '.',
430 NIPQUAD(cp->daddr), ntohs(cp->dport), 535 th->rst ? 'R' : '.',
431 NIPQUAD(cp->caddr), ntohs(cp->cport), 536 IP_VS_DBG_ADDR(cp->af, &cp->daddr),
432 tcp_state_name(cp->state), 537 ntohs(cp->dport),
433 tcp_state_name(new_state), 538 IP_VS_DBG_ADDR(cp->af, &cp->caddr),
434 atomic_read(&cp->refcnt)); 539 ntohs(cp->cport),
540 tcp_state_name(cp->state),
541 tcp_state_name(new_state),
542 atomic_read(&cp->refcnt));
543
435 if (dest) { 544 if (dest) {
436 if (!(cp->flags & IP_VS_CONN_F_INACTIVE) && 545 if (!(cp->flags & IP_VS_CONN_F_INACTIVE) &&
437 (new_state != IP_VS_TCP_S_ESTABLISHED)) { 546 (new_state != IP_VS_TCP_S_ESTABLISHED)) {
@@ -461,7 +570,13 @@ tcp_state_transition(struct ip_vs_conn *cp, int direction,
461{ 570{
462 struct tcphdr _tcph, *th; 571 struct tcphdr _tcph, *th;
463 572
464 th = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_tcph), &_tcph); 573#ifdef CONFIG_IP_VS_IPV6
574 int ihl = cp->af == AF_INET ? ip_hdrlen(skb) : sizeof(struct ipv6hdr);
575#else
576 int ihl = ip_hdrlen(skb);
577#endif
578
579 th = skb_header_pointer(skb, ihl, sizeof(_tcph), &_tcph);
465 if (th == NULL) 580 if (th == NULL)
466 return 0; 581 return 0;
467 582
@@ -546,12 +661,15 @@ tcp_app_conn_bind(struct ip_vs_conn *cp)
546 break; 661 break;
547 spin_unlock(&tcp_app_lock); 662 spin_unlock(&tcp_app_lock);
548 663
549 IP_VS_DBG(9, "%s: Binding conn %u.%u.%u.%u:%u->" 664 IP_VS_DBG_BUF(9, "%s: Binding conn %s:%u->"
550 "%u.%u.%u.%u:%u to app %s on port %u\n", 665 "%s:%u to app %s on port %u\n",
551 __func__, 666 __func__,
552 NIPQUAD(cp->caddr), ntohs(cp->cport), 667 IP_VS_DBG_ADDR(cp->af, &cp->caddr),
553 NIPQUAD(cp->vaddr), ntohs(cp->vport), 668 ntohs(cp->cport),
554 inc->name, ntohs(inc->port)); 669 IP_VS_DBG_ADDR(cp->af, &cp->vaddr),
670 ntohs(cp->vport),
671 inc->name, ntohs(inc->port));
672
555 cp->app = inc; 673 cp->app = inc;
556 if (inc->init_conn) 674 if (inc->init_conn)
557 result = inc->init_conn(inc, cp); 675 result = inc->init_conn(inc, cp);
diff --git a/net/ipv4/ipvs/ip_vs_proto_udp.c b/net/netfilter/ipvs/ip_vs_proto_udp.c
index c6be5d56823f..6eb6039d6343 100644
--- a/net/ipv4/ipvs/ip_vs_proto_udp.c
+++ b/net/netfilter/ipvs/ip_vs_proto_udp.c
@@ -22,10 +22,12 @@
22 22
23#include <net/ip_vs.h> 23#include <net/ip_vs.h>
24#include <net/ip.h> 24#include <net/ip.h>
25#include <net/ip6_checksum.h>
25 26
26static struct ip_vs_conn * 27static struct ip_vs_conn *
27udp_conn_in_get(const struct sk_buff *skb, struct ip_vs_protocol *pp, 28udp_conn_in_get(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp,
28 const struct iphdr *iph, unsigned int proto_off, int inverse) 29 const struct ip_vs_iphdr *iph, unsigned int proto_off,
30 int inverse)
29{ 31{
30 struct ip_vs_conn *cp; 32 struct ip_vs_conn *cp;
31 __be16 _ports[2], *pptr; 33 __be16 _ports[2], *pptr;
@@ -35,13 +37,13 @@ udp_conn_in_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
35 return NULL; 37 return NULL;
36 38
37 if (likely(!inverse)) { 39 if (likely(!inverse)) {
38 cp = ip_vs_conn_in_get(iph->protocol, 40 cp = ip_vs_conn_in_get(af, iph->protocol,
39 iph->saddr, pptr[0], 41 &iph->saddr, pptr[0],
40 iph->daddr, pptr[1]); 42 &iph->daddr, pptr[1]);
41 } else { 43 } else {
42 cp = ip_vs_conn_in_get(iph->protocol, 44 cp = ip_vs_conn_in_get(af, iph->protocol,
43 iph->daddr, pptr[1], 45 &iph->daddr, pptr[1],
44 iph->saddr, pptr[0]); 46 &iph->saddr, pptr[0]);
45 } 47 }
46 48
47 return cp; 49 return cp;
@@ -49,25 +51,25 @@ udp_conn_in_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
49 51
50 52
51static struct ip_vs_conn * 53static struct ip_vs_conn *
52udp_conn_out_get(const struct sk_buff *skb, struct ip_vs_protocol *pp, 54udp_conn_out_get(int af, const struct sk_buff *skb, struct ip_vs_protocol *pp,
53 const struct iphdr *iph, unsigned int proto_off, int inverse) 55 const struct ip_vs_iphdr *iph, unsigned int proto_off,
56 int inverse)
54{ 57{
55 struct ip_vs_conn *cp; 58 struct ip_vs_conn *cp;
56 __be16 _ports[2], *pptr; 59 __be16 _ports[2], *pptr;
57 60
58 pptr = skb_header_pointer(skb, ip_hdrlen(skb), 61 pptr = skb_header_pointer(skb, proto_off, sizeof(_ports), _ports);
59 sizeof(_ports), _ports);
60 if (pptr == NULL) 62 if (pptr == NULL)
61 return NULL; 63 return NULL;
62 64
63 if (likely(!inverse)) { 65 if (likely(!inverse)) {
64 cp = ip_vs_conn_out_get(iph->protocol, 66 cp = ip_vs_conn_out_get(af, iph->protocol,
65 iph->saddr, pptr[0], 67 &iph->saddr, pptr[0],
66 iph->daddr, pptr[1]); 68 &iph->daddr, pptr[1]);
67 } else { 69 } else {
68 cp = ip_vs_conn_out_get(iph->protocol, 70 cp = ip_vs_conn_out_get(af, iph->protocol,
69 iph->daddr, pptr[1], 71 &iph->daddr, pptr[1],
70 iph->saddr, pptr[0]); 72 &iph->saddr, pptr[0]);
71 } 73 }
72 74
73 return cp; 75 return cp;
@@ -75,21 +77,24 @@ udp_conn_out_get(const struct sk_buff *skb, struct ip_vs_protocol *pp,
75 77
76 78
77static int 79static int
78udp_conn_schedule(struct sk_buff *skb, struct ip_vs_protocol *pp, 80udp_conn_schedule(int af, struct sk_buff *skb, struct ip_vs_protocol *pp,
79 int *verdict, struct ip_vs_conn **cpp) 81 int *verdict, struct ip_vs_conn **cpp)
80{ 82{
81 struct ip_vs_service *svc; 83 struct ip_vs_service *svc;
82 struct udphdr _udph, *uh; 84 struct udphdr _udph, *uh;
85 struct ip_vs_iphdr iph;
86
87 ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
83 88
84 uh = skb_header_pointer(skb, ip_hdrlen(skb), 89 uh = skb_header_pointer(skb, iph.len, sizeof(_udph), &_udph);
85 sizeof(_udph), &_udph);
86 if (uh == NULL) { 90 if (uh == NULL) {
87 *verdict = NF_DROP; 91 *verdict = NF_DROP;
88 return 0; 92 return 0;
89 } 93 }
90 94
91 if ((svc = ip_vs_service_get(skb->mark, ip_hdr(skb)->protocol, 95 svc = ip_vs_service_get(af, skb->mark, iph.protocol,
92 ip_hdr(skb)->daddr, uh->dest))) { 96 &iph.daddr, uh->dest);
97 if (svc) {
93 if (ip_vs_todrop()) { 98 if (ip_vs_todrop()) {
94 /* 99 /*
95 * It seems that we are very loaded. 100 * It seems that we are very loaded.
@@ -116,23 +121,63 @@ udp_conn_schedule(struct sk_buff *skb, struct ip_vs_protocol *pp,
116 121
117 122
118static inline void 123static inline void
119udp_fast_csum_update(struct udphdr *uhdr, __be32 oldip, __be32 newip, 124udp_fast_csum_update(int af, struct udphdr *uhdr,
125 const union nf_inet_addr *oldip,
126 const union nf_inet_addr *newip,
120 __be16 oldport, __be16 newport) 127 __be16 oldport, __be16 newport)
121{ 128{
122 uhdr->check = 129#ifdef CONFIG_IP_VS_IPV6
123 csum_fold(ip_vs_check_diff4(oldip, newip, 130 if (af == AF_INET6)
124 ip_vs_check_diff2(oldport, newport, 131 uhdr->check =
125 ~csum_unfold(uhdr->check)))); 132 csum_fold(ip_vs_check_diff16(oldip->ip6, newip->ip6,
133 ip_vs_check_diff2(oldport, newport,
134 ~csum_unfold(uhdr->check))));
135 else
136#endif
137 uhdr->check =
138 csum_fold(ip_vs_check_diff4(oldip->ip, newip->ip,
139 ip_vs_check_diff2(oldport, newport,
140 ~csum_unfold(uhdr->check))));
126 if (!uhdr->check) 141 if (!uhdr->check)
127 uhdr->check = CSUM_MANGLED_0; 142 uhdr->check = CSUM_MANGLED_0;
128} 143}
129 144
145static inline void
146udp_partial_csum_update(int af, struct udphdr *uhdr,
147 const union nf_inet_addr *oldip,
148 const union nf_inet_addr *newip,
149 __be16 oldlen, __be16 newlen)
150{
151#ifdef CONFIG_IP_VS_IPV6
152 if (af == AF_INET6)
153 uhdr->check =
154 csum_fold(ip_vs_check_diff16(oldip->ip6, newip->ip6,
155 ip_vs_check_diff2(oldlen, newlen,
156 ~csum_unfold(uhdr->check))));
157 else
158#endif
159 uhdr->check =
160 csum_fold(ip_vs_check_diff4(oldip->ip, newip->ip,
161 ip_vs_check_diff2(oldlen, newlen,
162 ~csum_unfold(uhdr->check))));
163}
164
165
130static int 166static int
131udp_snat_handler(struct sk_buff *skb, 167udp_snat_handler(struct sk_buff *skb,
132 struct ip_vs_protocol *pp, struct ip_vs_conn *cp) 168 struct ip_vs_protocol *pp, struct ip_vs_conn *cp)
133{ 169{
134 struct udphdr *udph; 170 struct udphdr *udph;
135 const unsigned int udphoff = ip_hdrlen(skb); 171 unsigned int udphoff;
172 int oldlen;
173
174#ifdef CONFIG_IP_VS_IPV6
175 if (cp->af == AF_INET6)
176 udphoff = sizeof(struct ipv6hdr);
177 else
178#endif
179 udphoff = ip_hdrlen(skb);
180 oldlen = skb->len - udphoff;
136 181
137 /* csum_check requires unshared skb */ 182 /* csum_check requires unshared skb */
138 if (!skb_make_writable(skb, udphoff+sizeof(*udph))) 183 if (!skb_make_writable(skb, udphoff+sizeof(*udph)))
@@ -140,7 +185,7 @@ udp_snat_handler(struct sk_buff *skb,
140 185
141 if (unlikely(cp->app != NULL)) { 186 if (unlikely(cp->app != NULL)) {
142 /* Some checks before mangling */ 187 /* Some checks before mangling */
143 if (pp->csum_check && !pp->csum_check(skb, pp)) 188 if (pp->csum_check && !pp->csum_check(cp->af, skb, pp))
144 return 0; 189 return 0;
145 190
146 /* 191 /*
@@ -150,15 +195,19 @@ udp_snat_handler(struct sk_buff *skb,
150 return 0; 195 return 0;
151 } 196 }
152 197
153 udph = (void *)ip_hdr(skb) + udphoff; 198 udph = (void *)skb_network_header(skb) + udphoff;
154 udph->source = cp->vport; 199 udph->source = cp->vport;
155 200
156 /* 201 /*
157 * Adjust UDP checksums 202 * Adjust UDP checksums
158 */ 203 */
159 if (!cp->app && (udph->check != 0)) { 204 if (skb->ip_summed == CHECKSUM_PARTIAL) {
205 udp_partial_csum_update(cp->af, udph, &cp->daddr, &cp->vaddr,
206 htonl(oldlen),
207 htonl(skb->len - udphoff));
208 } else if (!cp->app && (udph->check != 0)) {
160 /* Only port and addr are changed, do fast csum update */ 209 /* Only port and addr are changed, do fast csum update */
161 udp_fast_csum_update(udph, cp->daddr, cp->vaddr, 210 udp_fast_csum_update(cp->af, udph, &cp->daddr, &cp->vaddr,
162 cp->dport, cp->vport); 211 cp->dport, cp->vport);
163 if (skb->ip_summed == CHECKSUM_COMPLETE) 212 if (skb->ip_summed == CHECKSUM_COMPLETE)
164 skb->ip_summed = CHECKSUM_NONE; 213 skb->ip_summed = CHECKSUM_NONE;
@@ -166,9 +215,19 @@ udp_snat_handler(struct sk_buff *skb,
166 /* full checksum calculation */ 215 /* full checksum calculation */
167 udph->check = 0; 216 udph->check = 0;
168 skb->csum = skb_checksum(skb, udphoff, skb->len - udphoff, 0); 217 skb->csum = skb_checksum(skb, udphoff, skb->len - udphoff, 0);
169 udph->check = csum_tcpudp_magic(cp->vaddr, cp->caddr, 218#ifdef CONFIG_IP_VS_IPV6
170 skb->len - udphoff, 219 if (cp->af == AF_INET6)
171 cp->protocol, skb->csum); 220 udph->check = csum_ipv6_magic(&cp->vaddr.in6,
221 &cp->caddr.in6,
222 skb->len - udphoff,
223 cp->protocol, skb->csum);
224 else
225#endif
226 udph->check = csum_tcpudp_magic(cp->vaddr.ip,
227 cp->caddr.ip,
228 skb->len - udphoff,
229 cp->protocol,
230 skb->csum);
172 if (udph->check == 0) 231 if (udph->check == 0)
173 udph->check = CSUM_MANGLED_0; 232 udph->check = CSUM_MANGLED_0;
174 IP_VS_DBG(11, "O-pkt: %s O-csum=%d (+%zd)\n", 233 IP_VS_DBG(11, "O-pkt: %s O-csum=%d (+%zd)\n",
@@ -184,7 +243,16 @@ udp_dnat_handler(struct sk_buff *skb,
184 struct ip_vs_protocol *pp, struct ip_vs_conn *cp) 243 struct ip_vs_protocol *pp, struct ip_vs_conn *cp)
185{ 244{
186 struct udphdr *udph; 245 struct udphdr *udph;
187 unsigned int udphoff = ip_hdrlen(skb); 246 unsigned int udphoff;
247 int oldlen;
248
249#ifdef CONFIG_IP_VS_IPV6
250 if (cp->af == AF_INET6)
251 udphoff = sizeof(struct ipv6hdr);
252 else
253#endif
254 udphoff = ip_hdrlen(skb);
255 oldlen = skb->len - udphoff;
188 256
189 /* csum_check requires unshared skb */ 257 /* csum_check requires unshared skb */
190 if (!skb_make_writable(skb, udphoff+sizeof(*udph))) 258 if (!skb_make_writable(skb, udphoff+sizeof(*udph)))
@@ -192,7 +260,7 @@ udp_dnat_handler(struct sk_buff *skb,
192 260
193 if (unlikely(cp->app != NULL)) { 261 if (unlikely(cp->app != NULL)) {
194 /* Some checks before mangling */ 262 /* Some checks before mangling */
195 if (pp->csum_check && !pp->csum_check(skb, pp)) 263 if (pp->csum_check && !pp->csum_check(cp->af, skb, pp))
196 return 0; 264 return 0;
197 265
198 /* 266 /*
@@ -203,15 +271,19 @@ udp_dnat_handler(struct sk_buff *skb,
203 return 0; 271 return 0;
204 } 272 }
205 273
206 udph = (void *)ip_hdr(skb) + udphoff; 274 udph = (void *)skb_network_header(skb) + udphoff;
207 udph->dest = cp->dport; 275 udph->dest = cp->dport;
208 276
209 /* 277 /*
210 * Adjust UDP checksums 278 * Adjust UDP checksums
211 */ 279 */
212 if (!cp->app && (udph->check != 0)) { 280 if (skb->ip_summed == CHECKSUM_PARTIAL) {
281 udp_partial_csum_update(cp->af, udph, &cp->daddr, &cp->vaddr,
282 htonl(oldlen),
283 htonl(skb->len - udphoff));
284 } else if (!cp->app && (udph->check != 0)) {
213 /* Only port and addr are changed, do fast csum update */ 285 /* Only port and addr are changed, do fast csum update */
214 udp_fast_csum_update(udph, cp->vaddr, cp->daddr, 286 udp_fast_csum_update(cp->af, udph, &cp->vaddr, &cp->daddr,
215 cp->vport, cp->dport); 287 cp->vport, cp->dport);
216 if (skb->ip_summed == CHECKSUM_COMPLETE) 288 if (skb->ip_summed == CHECKSUM_COMPLETE)
217 skb->ip_summed = CHECKSUM_NONE; 289 skb->ip_summed = CHECKSUM_NONE;
@@ -219,9 +291,19 @@ udp_dnat_handler(struct sk_buff *skb,
219 /* full checksum calculation */ 291 /* full checksum calculation */
220 udph->check = 0; 292 udph->check = 0;
221 skb->csum = skb_checksum(skb, udphoff, skb->len - udphoff, 0); 293 skb->csum = skb_checksum(skb, udphoff, skb->len - udphoff, 0);
222 udph->check = csum_tcpudp_magic(cp->caddr, cp->daddr, 294#ifdef CONFIG_IP_VS_IPV6
223 skb->len - udphoff, 295 if (cp->af == AF_INET6)
224 cp->protocol, skb->csum); 296 udph->check = csum_ipv6_magic(&cp->caddr.in6,
297 &cp->daddr.in6,
298 skb->len - udphoff,
299 cp->protocol, skb->csum);
300 else
301#endif
302 udph->check = csum_tcpudp_magic(cp->caddr.ip,
303 cp->daddr.ip,
304 skb->len - udphoff,
305 cp->protocol,
306 skb->csum);
225 if (udph->check == 0) 307 if (udph->check == 0)
226 udph->check = CSUM_MANGLED_0; 308 udph->check = CSUM_MANGLED_0;
227 skb->ip_summed = CHECKSUM_UNNECESSARY; 309 skb->ip_summed = CHECKSUM_UNNECESSARY;
@@ -231,10 +313,17 @@ udp_dnat_handler(struct sk_buff *skb,
231 313
232 314
233static int 315static int
234udp_csum_check(struct sk_buff *skb, struct ip_vs_protocol *pp) 316udp_csum_check(int af, struct sk_buff *skb, struct ip_vs_protocol *pp)
235{ 317{
236 struct udphdr _udph, *uh; 318 struct udphdr _udph, *uh;
237 const unsigned int udphoff = ip_hdrlen(skb); 319 unsigned int udphoff;
320
321#ifdef CONFIG_IP_VS_IPV6
322 if (af == AF_INET6)
323 udphoff = sizeof(struct ipv6hdr);
324 else
325#endif
326 udphoff = ip_hdrlen(skb);
238 327
239 uh = skb_header_pointer(skb, udphoff, sizeof(_udph), &_udph); 328 uh = skb_header_pointer(skb, udphoff, sizeof(_udph), &_udph);
240 if (uh == NULL) 329 if (uh == NULL)
@@ -246,15 +335,28 @@ udp_csum_check(struct sk_buff *skb, struct ip_vs_protocol *pp)
246 skb->csum = skb_checksum(skb, udphoff, 335 skb->csum = skb_checksum(skb, udphoff,
247 skb->len - udphoff, 0); 336 skb->len - udphoff, 0);
248 case CHECKSUM_COMPLETE: 337 case CHECKSUM_COMPLETE:
249 if (csum_tcpudp_magic(ip_hdr(skb)->saddr, 338#ifdef CONFIG_IP_VS_IPV6
250 ip_hdr(skb)->daddr, 339 if (af == AF_INET6) {
251 skb->len - udphoff, 340 if (csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
252 ip_hdr(skb)->protocol, 341 &ipv6_hdr(skb)->daddr,
253 skb->csum)) { 342 skb->len - udphoff,
254 IP_VS_DBG_RL_PKT(0, pp, skb, 0, 343 ipv6_hdr(skb)->nexthdr,
255 "Failed checksum for"); 344 skb->csum)) {
256 return 0; 345 IP_VS_DBG_RL_PKT(0, pp, skb, 0,
257 } 346 "Failed checksum for");
347 return 0;
348 }
349 } else
350#endif
351 if (csum_tcpudp_magic(ip_hdr(skb)->saddr,
352 ip_hdr(skb)->daddr,
353 skb->len - udphoff,
354 ip_hdr(skb)->protocol,
355 skb->csum)) {
356 IP_VS_DBG_RL_PKT(0, pp, skb, 0,
357 "Failed checksum for");
358 return 0;
359 }
258 break; 360 break;
259 default: 361 default:
260 /* No need to checksum. */ 362 /* No need to checksum. */
@@ -340,12 +442,15 @@ static int udp_app_conn_bind(struct ip_vs_conn *cp)
340 break; 442 break;
341 spin_unlock(&udp_app_lock); 443 spin_unlock(&udp_app_lock);
342 444
343 IP_VS_DBG(9, "%s: Binding conn %u.%u.%u.%u:%u->" 445 IP_VS_DBG_BUF(9, "%s: Binding conn %s:%u->"
344 "%u.%u.%u.%u:%u to app %s on port %u\n", 446 "%s:%u to app %s on port %u\n",
345 __func__, 447 __func__,
346 NIPQUAD(cp->caddr), ntohs(cp->cport), 448 IP_VS_DBG_ADDR(cp->af, &cp->caddr),
347 NIPQUAD(cp->vaddr), ntohs(cp->vport), 449 ntohs(cp->cport),
348 inc->name, ntohs(inc->port)); 450 IP_VS_DBG_ADDR(cp->af, &cp->vaddr),
451 ntohs(cp->vport),
452 inc->name, ntohs(inc->port));
453
349 cp->app = inc; 454 cp->app = inc;
350 if (inc->init_conn) 455 if (inc->init_conn)
351 result = inc->init_conn(inc, cp); 456 result = inc->init_conn(inc, cp);
diff --git a/net/ipv4/ipvs/ip_vs_rr.c b/net/netfilter/ipvs/ip_vs_rr.c
index 358110d17e59..a22195f68ac4 100644
--- a/net/ipv4/ipvs/ip_vs_rr.c
+++ b/net/netfilter/ipvs/ip_vs_rr.c
@@ -32,12 +32,6 @@ static int ip_vs_rr_init_svc(struct ip_vs_service *svc)
32} 32}
33 33
34 34
35static int ip_vs_rr_done_svc(struct ip_vs_service *svc)
36{
37 return 0;
38}
39
40
41static int ip_vs_rr_update_svc(struct ip_vs_service *svc) 35static int ip_vs_rr_update_svc(struct ip_vs_service *svc)
42{ 36{
43 svc->sched_data = &svc->destinations; 37 svc->sched_data = &svc->destinations;
@@ -80,11 +74,11 @@ ip_vs_rr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
80 out: 74 out:
81 svc->sched_data = q; 75 svc->sched_data = q;
82 write_unlock(&svc->sched_lock); 76 write_unlock(&svc->sched_lock);
83 IP_VS_DBG(6, "RR: server %u.%u.%u.%u:%u " 77 IP_VS_DBG_BUF(6, "RR: server %s:%u "
84 "activeconns %d refcnt %d weight %d\n", 78 "activeconns %d refcnt %d weight %d\n",
85 NIPQUAD(dest->addr), ntohs(dest->port), 79 IP_VS_DBG_ADDR(svc->af, &dest->addr), ntohs(dest->port),
86 atomic_read(&dest->activeconns), 80 atomic_read(&dest->activeconns),
87 atomic_read(&dest->refcnt), atomic_read(&dest->weight)); 81 atomic_read(&dest->refcnt), atomic_read(&dest->weight));
88 82
89 return dest; 83 return dest;
90} 84}
@@ -95,8 +89,10 @@ static struct ip_vs_scheduler ip_vs_rr_scheduler = {
95 .refcnt = ATOMIC_INIT(0), 89 .refcnt = ATOMIC_INIT(0),
96 .module = THIS_MODULE, 90 .module = THIS_MODULE,
97 .n_list = LIST_HEAD_INIT(ip_vs_rr_scheduler.n_list), 91 .n_list = LIST_HEAD_INIT(ip_vs_rr_scheduler.n_list),
92#ifdef CONFIG_IP_VS_IPV6
93 .supports_ipv6 = 1,
94#endif
98 .init_service = ip_vs_rr_init_svc, 95 .init_service = ip_vs_rr_init_svc,
99 .done_service = ip_vs_rr_done_svc,
100 .update_service = ip_vs_rr_update_svc, 96 .update_service = ip_vs_rr_update_svc,
101 .schedule = ip_vs_rr_schedule, 97 .schedule = ip_vs_rr_schedule,
102}; 98};
diff --git a/net/ipv4/ipvs/ip_vs_sched.c b/net/netfilter/ipvs/ip_vs_sched.c
index a46ad9e35016..a46ad9e35016 100644
--- a/net/ipv4/ipvs/ip_vs_sched.c
+++ b/net/netfilter/ipvs/ip_vs_sched.c
diff --git a/net/ipv4/ipvs/ip_vs_sed.c b/net/netfilter/ipvs/ip_vs_sed.c
index 77663d84cbd1..7d2f22f04b83 100644
--- a/net/ipv4/ipvs/ip_vs_sed.c
+++ b/net/netfilter/ipvs/ip_vs_sed.c
@@ -41,27 +41,6 @@
41#include <net/ip_vs.h> 41#include <net/ip_vs.h>
42 42
43 43
44static int
45ip_vs_sed_init_svc(struct ip_vs_service *svc)
46{
47 return 0;
48}
49
50
51static int
52ip_vs_sed_done_svc(struct ip_vs_service *svc)
53{
54 return 0;
55}
56
57
58static int
59ip_vs_sed_update_svc(struct ip_vs_service *svc)
60{
61 return 0;
62}
63
64
65static inline unsigned int 44static inline unsigned int
66ip_vs_sed_dest_overhead(struct ip_vs_dest *dest) 45ip_vs_sed_dest_overhead(struct ip_vs_dest *dest)
67{ 46{
@@ -122,12 +101,12 @@ ip_vs_sed_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
122 } 101 }
123 } 102 }
124 103
125 IP_VS_DBG(6, "SED: server %u.%u.%u.%u:%u " 104 IP_VS_DBG_BUF(6, "SED: server %s:%u "
126 "activeconns %d refcnt %d weight %d overhead %d\n", 105 "activeconns %d refcnt %d weight %d overhead %d\n",
127 NIPQUAD(least->addr), ntohs(least->port), 106 IP_VS_DBG_ADDR(svc->af, &least->addr), ntohs(least->port),
128 atomic_read(&least->activeconns), 107 atomic_read(&least->activeconns),
129 atomic_read(&least->refcnt), 108 atomic_read(&least->refcnt),
130 atomic_read(&least->weight), loh); 109 atomic_read(&least->weight), loh);
131 110
132 return least; 111 return least;
133} 112}
@@ -139,9 +118,9 @@ static struct ip_vs_scheduler ip_vs_sed_scheduler =
139 .refcnt = ATOMIC_INIT(0), 118 .refcnt = ATOMIC_INIT(0),
140 .module = THIS_MODULE, 119 .module = THIS_MODULE,
141 .n_list = LIST_HEAD_INIT(ip_vs_sed_scheduler.n_list), 120 .n_list = LIST_HEAD_INIT(ip_vs_sed_scheduler.n_list),
142 .init_service = ip_vs_sed_init_svc, 121#ifdef CONFIG_IP_VS_IPV6
143 .done_service = ip_vs_sed_done_svc, 122 .supports_ipv6 = 1,
144 .update_service = ip_vs_sed_update_svc, 123#endif
145 .schedule = ip_vs_sed_schedule, 124 .schedule = ip_vs_sed_schedule,
146}; 125};
147 126
diff --git a/net/ipv4/ipvs/ip_vs_sh.c b/net/netfilter/ipvs/ip_vs_sh.c
index 7b979e228056..1d96de27fefd 100644
--- a/net/ipv4/ipvs/ip_vs_sh.c
+++ b/net/netfilter/ipvs/ip_vs_sh.c
@@ -215,7 +215,7 @@ ip_vs_sh_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
215 IP_VS_DBG(6, "SH: source IP address %u.%u.%u.%u " 215 IP_VS_DBG(6, "SH: source IP address %u.%u.%u.%u "
216 "--> server %u.%u.%u.%u:%d\n", 216 "--> server %u.%u.%u.%u:%d\n",
217 NIPQUAD(iph->saddr), 217 NIPQUAD(iph->saddr),
218 NIPQUAD(dest->addr), 218 NIPQUAD(dest->addr.ip),
219 ntohs(dest->port)); 219 ntohs(dest->port));
220 220
221 return dest; 221 return dest;
@@ -231,6 +231,9 @@ static struct ip_vs_scheduler ip_vs_sh_scheduler =
231 .refcnt = ATOMIC_INIT(0), 231 .refcnt = ATOMIC_INIT(0),
232 .module = THIS_MODULE, 232 .module = THIS_MODULE,
233 .n_list = LIST_HEAD_INIT(ip_vs_sh_scheduler.n_list), 233 .n_list = LIST_HEAD_INIT(ip_vs_sh_scheduler.n_list),
234#ifdef CONFIG_IP_VS_IPV6
235 .supports_ipv6 = 0,
236#endif
234 .init_service = ip_vs_sh_init_svc, 237 .init_service = ip_vs_sh_init_svc,
235 .done_service = ip_vs_sh_done_svc, 238 .done_service = ip_vs_sh_done_svc,
236 .update_service = ip_vs_sh_update_svc, 239 .update_service = ip_vs_sh_update_svc,
diff --git a/net/ipv4/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
index a652da2c3200..de5e7e118eed 100644
--- a/net/ipv4/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -30,6 +30,7 @@
30#include <linux/err.h> 30#include <linux/err.h>
31#include <linux/kthread.h> 31#include <linux/kthread.h>
32#include <linux/wait.h> 32#include <linux/wait.h>
33#include <linux/kernel.h>
33 34
34#include <net/ip.h> 35#include <net/ip.h>
35#include <net/sock.h> 36#include <net/sock.h>
@@ -99,6 +100,7 @@ struct ip_vs_sync_thread_data {
99*/ 100*/
100 101
101#define SYNC_MESG_HEADER_LEN 4 102#define SYNC_MESG_HEADER_LEN 4
103#define MAX_CONNS_PER_SYNCBUFF 255 /* nr_conns in ip_vs_sync_mesg is 8 bit */
102 104
103struct ip_vs_sync_mesg { 105struct ip_vs_sync_mesg {
104 __u8 nr_conns; 106 __u8 nr_conns;
@@ -256,9 +258,9 @@ void ip_vs_sync_conn(struct ip_vs_conn *cp)
256 s->cport = cp->cport; 258 s->cport = cp->cport;
257 s->vport = cp->vport; 259 s->vport = cp->vport;
258 s->dport = cp->dport; 260 s->dport = cp->dport;
259 s->caddr = cp->caddr; 261 s->caddr = cp->caddr.ip;
260 s->vaddr = cp->vaddr; 262 s->vaddr = cp->vaddr.ip;
261 s->daddr = cp->daddr; 263 s->daddr = cp->daddr.ip;
262 s->flags = htons(cp->flags & ~IP_VS_CONN_F_HASHED); 264 s->flags = htons(cp->flags & ~IP_VS_CONN_F_HASHED);
263 s->state = htons(cp->state); 265 s->state = htons(cp->state);
264 if (cp->flags & IP_VS_CONN_F_SEQ_MASK) { 266 if (cp->flags & IP_VS_CONN_F_SEQ_MASK) {
@@ -366,21 +368,28 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
366 } 368 }
367 369
368 if (!(flags & IP_VS_CONN_F_TEMPLATE)) 370 if (!(flags & IP_VS_CONN_F_TEMPLATE))
369 cp = ip_vs_conn_in_get(s->protocol, 371 cp = ip_vs_conn_in_get(AF_INET, s->protocol,
370 s->caddr, s->cport, 372 (union nf_inet_addr *)&s->caddr,
371 s->vaddr, s->vport); 373 s->cport,
374 (union nf_inet_addr *)&s->vaddr,
375 s->vport);
372 else 376 else
373 cp = ip_vs_ct_in_get(s->protocol, 377 cp = ip_vs_ct_in_get(AF_INET, s->protocol,
374 s->caddr, s->cport, 378 (union nf_inet_addr *)&s->caddr,
375 s->vaddr, s->vport); 379 s->cport,
380 (union nf_inet_addr *)&s->vaddr,
381 s->vport);
376 if (!cp) { 382 if (!cp) {
377 /* 383 /*
378 * Find the appropriate destination for the connection. 384 * Find the appropriate destination for the connection.
379 * If it is not found the connection will remain unbound 385 * If it is not found the connection will remain unbound
380 * but still handled. 386 * but still handled.
381 */ 387 */
382 dest = ip_vs_find_dest(s->daddr, s->dport, 388 dest = ip_vs_find_dest(AF_INET,
383 s->vaddr, s->vport, 389 (union nf_inet_addr *)&s->daddr,
390 s->dport,
391 (union nf_inet_addr *)&s->vaddr,
392 s->vport,
384 s->protocol); 393 s->protocol);
385 /* Set the approprite ativity flag */ 394 /* Set the approprite ativity flag */
386 if (s->protocol == IPPROTO_TCP) { 395 if (s->protocol == IPPROTO_TCP) {
@@ -389,10 +398,13 @@ static void ip_vs_process_message(const char *buffer, const size_t buflen)
389 else 398 else
390 flags &= ~IP_VS_CONN_F_INACTIVE; 399 flags &= ~IP_VS_CONN_F_INACTIVE;
391 } 400 }
392 cp = ip_vs_conn_new(s->protocol, 401 cp = ip_vs_conn_new(AF_INET, s->protocol,
393 s->caddr, s->cport, 402 (union nf_inet_addr *)&s->caddr,
394 s->vaddr, s->vport, 403 s->cport,
395 s->daddr, s->dport, 404 (union nf_inet_addr *)&s->vaddr,
405 s->vport,
406 (union nf_inet_addr *)&s->daddr,
407 s->dport,
396 flags, dest); 408 flags, dest);
397 if (dest) 409 if (dest)
398 atomic_dec(&dest->refcnt); 410 atomic_dec(&dest->refcnt);
@@ -506,8 +518,8 @@ static int set_sync_mesg_maxlen(int sync_state)
506 num = (dev->mtu - sizeof(struct iphdr) - 518 num = (dev->mtu - sizeof(struct iphdr) -
507 sizeof(struct udphdr) - 519 sizeof(struct udphdr) -
508 SYNC_MESG_HEADER_LEN - 20) / SIMPLE_CONN_SIZE; 520 SYNC_MESG_HEADER_LEN - 20) / SIMPLE_CONN_SIZE;
509 sync_send_mesg_maxlen = 521 sync_send_mesg_maxlen = SYNC_MESG_HEADER_LEN +
510 SYNC_MESG_HEADER_LEN + SIMPLE_CONN_SIZE * num; 522 SIMPLE_CONN_SIZE * min(num, MAX_CONNS_PER_SYNCBUFF);
511 IP_VS_DBG(7, "setting the maximum length of sync sending " 523 IP_VS_DBG(7, "setting the maximum length of sync sending "
512 "message %d.\n", sync_send_mesg_maxlen); 524 "message %d.\n", sync_send_mesg_maxlen);
513 } else if (sync_state == IP_VS_STATE_BACKUP) { 525 } else if (sync_state == IP_VS_STATE_BACKUP) {
diff --git a/net/ipv4/ipvs/ip_vs_wlc.c b/net/netfilter/ipvs/ip_vs_wlc.c
index 9b0ef86bb1f7..8c596e712599 100644
--- a/net/ipv4/ipvs/ip_vs_wlc.c
+++ b/net/netfilter/ipvs/ip_vs_wlc.c
@@ -25,27 +25,6 @@
25#include <net/ip_vs.h> 25#include <net/ip_vs.h>
26 26
27 27
28static int
29ip_vs_wlc_init_svc(struct ip_vs_service *svc)
30{
31 return 0;
32}
33
34
35static int
36ip_vs_wlc_done_svc(struct ip_vs_service *svc)
37{
38 return 0;
39}
40
41
42static int
43ip_vs_wlc_update_svc(struct ip_vs_service *svc)
44{
45 return 0;
46}
47
48
49static inline unsigned int 28static inline unsigned int
50ip_vs_wlc_dest_overhead(struct ip_vs_dest *dest) 29ip_vs_wlc_dest_overhead(struct ip_vs_dest *dest)
51{ 30{
@@ -110,12 +89,12 @@ ip_vs_wlc_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
110 } 89 }
111 } 90 }
112 91
113 IP_VS_DBG(6, "WLC: server %u.%u.%u.%u:%u " 92 IP_VS_DBG_BUF(6, "WLC: server %s:%u "
114 "activeconns %d refcnt %d weight %d overhead %d\n", 93 "activeconns %d refcnt %d weight %d overhead %d\n",
115 NIPQUAD(least->addr), ntohs(least->port), 94 IP_VS_DBG_ADDR(svc->af, &least->addr), ntohs(least->port),
116 atomic_read(&least->activeconns), 95 atomic_read(&least->activeconns),
117 atomic_read(&least->refcnt), 96 atomic_read(&least->refcnt),
118 atomic_read(&least->weight), loh); 97 atomic_read(&least->weight), loh);
119 98
120 return least; 99 return least;
121} 100}
@@ -127,9 +106,9 @@ static struct ip_vs_scheduler ip_vs_wlc_scheduler =
127 .refcnt = ATOMIC_INIT(0), 106 .refcnt = ATOMIC_INIT(0),
128 .module = THIS_MODULE, 107 .module = THIS_MODULE,
129 .n_list = LIST_HEAD_INIT(ip_vs_wlc_scheduler.n_list), 108 .n_list = LIST_HEAD_INIT(ip_vs_wlc_scheduler.n_list),
130 .init_service = ip_vs_wlc_init_svc, 109#ifdef CONFIG_IP_VS_IPV6
131 .done_service = ip_vs_wlc_done_svc, 110 .supports_ipv6 = 1,
132 .update_service = ip_vs_wlc_update_svc, 111#endif
133 .schedule = ip_vs_wlc_schedule, 112 .schedule = ip_vs_wlc_schedule,
134}; 113};
135 114
diff --git a/net/ipv4/ipvs/ip_vs_wrr.c b/net/netfilter/ipvs/ip_vs_wrr.c
index 0d86a79b87b5..7ea92fed50bf 100644
--- a/net/ipv4/ipvs/ip_vs_wrr.c
+++ b/net/netfilter/ipvs/ip_vs_wrr.c
@@ -195,12 +195,12 @@ ip_vs_wrr_schedule(struct ip_vs_service *svc, const struct sk_buff *skb)
195 } 195 }
196 } 196 }
197 197
198 IP_VS_DBG(6, "WRR: server %u.%u.%u.%u:%u " 198 IP_VS_DBG_BUF(6, "WRR: server %s:%u "
199 "activeconns %d refcnt %d weight %d\n", 199 "activeconns %d refcnt %d weight %d\n",
200 NIPQUAD(dest->addr), ntohs(dest->port), 200 IP_VS_DBG_ADDR(svc->af, &dest->addr), ntohs(dest->port),
201 atomic_read(&dest->activeconns), 201 atomic_read(&dest->activeconns),
202 atomic_read(&dest->refcnt), 202 atomic_read(&dest->refcnt),
203 atomic_read(&dest->weight)); 203 atomic_read(&dest->weight));
204 204
205 out: 205 out:
206 write_unlock(&svc->sched_lock); 206 write_unlock(&svc->sched_lock);
@@ -213,6 +213,9 @@ static struct ip_vs_scheduler ip_vs_wrr_scheduler = {
213 .refcnt = ATOMIC_INIT(0), 213 .refcnt = ATOMIC_INIT(0),
214 .module = THIS_MODULE, 214 .module = THIS_MODULE,
215 .n_list = LIST_HEAD_INIT(ip_vs_wrr_scheduler.n_list), 215 .n_list = LIST_HEAD_INIT(ip_vs_wrr_scheduler.n_list),
216#ifdef CONFIG_IP_VS_IPV6
217 .supports_ipv6 = 1,
218#endif
216 .init_service = ip_vs_wrr_init_svc, 219 .init_service = ip_vs_wrr_init_svc,
217 .done_service = ip_vs_wrr_done_svc, 220 .done_service = ip_vs_wrr_done_svc,
218 .update_service = ip_vs_wrr_update_svc, 221 .update_service = ip_vs_wrr_update_svc,
diff --git a/net/ipv4/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index 9892d4aca42e..02ddc2b3ce2e 100644
--- a/net/ipv4/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -20,6 +20,9 @@
20#include <net/udp.h> 20#include <net/udp.h>
21#include <net/icmp.h> /* for icmp_send */ 21#include <net/icmp.h> /* for icmp_send */
22#include <net/route.h> /* for ip_route_output */ 22#include <net/route.h> /* for ip_route_output */
23#include <net/ipv6.h>
24#include <net/ip6_route.h>
25#include <linux/icmpv6.h>
23#include <linux/netfilter.h> 26#include <linux/netfilter.h>
24#include <linux/netfilter_ipv4.h> 27#include <linux/netfilter_ipv4.h>
25 28
@@ -47,7 +50,8 @@ __ip_vs_dst_check(struct ip_vs_dest *dest, u32 rtos, u32 cookie)
47 50
48 if (!dst) 51 if (!dst)
49 return NULL; 52 return NULL;
50 if ((dst->obsolete || rtos != dest->dst_rtos) && 53 if ((dst->obsolete
54 || (dest->af == AF_INET && rtos != dest->dst_rtos)) &&
51 dst->ops->check(dst, cookie) == NULL) { 55 dst->ops->check(dst, cookie) == NULL) {
52 dest->dst_cache = NULL; 56 dest->dst_cache = NULL;
53 dst_release(dst); 57 dst_release(dst);
@@ -71,7 +75,7 @@ __ip_vs_get_out_rt(struct ip_vs_conn *cp, u32 rtos)
71 .oif = 0, 75 .oif = 0,
72 .nl_u = { 76 .nl_u = {
73 .ip4_u = { 77 .ip4_u = {
74 .daddr = dest->addr, 78 .daddr = dest->addr.ip,
75 .saddr = 0, 79 .saddr = 0,
76 .tos = rtos, } }, 80 .tos = rtos, } },
77 }; 81 };
@@ -80,12 +84,12 @@ __ip_vs_get_out_rt(struct ip_vs_conn *cp, u32 rtos)
80 spin_unlock(&dest->dst_lock); 84 spin_unlock(&dest->dst_lock);
81 IP_VS_DBG_RL("ip_route_output error, " 85 IP_VS_DBG_RL("ip_route_output error, "
82 "dest: %u.%u.%u.%u\n", 86 "dest: %u.%u.%u.%u\n",
83 NIPQUAD(dest->addr)); 87 NIPQUAD(dest->addr.ip));
84 return NULL; 88 return NULL;
85 } 89 }
86 __ip_vs_dst_set(dest, rtos, dst_clone(&rt->u.dst)); 90 __ip_vs_dst_set(dest, rtos, dst_clone(&rt->u.dst));
87 IP_VS_DBG(10, "new dst %u.%u.%u.%u, refcnt=%d, rtos=%X\n", 91 IP_VS_DBG(10, "new dst %u.%u.%u.%u, refcnt=%d, rtos=%X\n",
88 NIPQUAD(dest->addr), 92 NIPQUAD(dest->addr.ip),
89 atomic_read(&rt->u.dst.__refcnt), rtos); 93 atomic_read(&rt->u.dst.__refcnt), rtos);
90 } 94 }
91 spin_unlock(&dest->dst_lock); 95 spin_unlock(&dest->dst_lock);
@@ -94,14 +98,14 @@ __ip_vs_get_out_rt(struct ip_vs_conn *cp, u32 rtos)
94 .oif = 0, 98 .oif = 0,
95 .nl_u = { 99 .nl_u = {
96 .ip4_u = { 100 .ip4_u = {
97 .daddr = cp->daddr, 101 .daddr = cp->daddr.ip,
98 .saddr = 0, 102 .saddr = 0,
99 .tos = rtos, } }, 103 .tos = rtos, } },
100 }; 104 };
101 105
102 if (ip_route_output_key(&init_net, &rt, &fl)) { 106 if (ip_route_output_key(&init_net, &rt, &fl)) {
103 IP_VS_DBG_RL("ip_route_output error, dest: " 107 IP_VS_DBG_RL("ip_route_output error, dest: "
104 "%u.%u.%u.%u\n", NIPQUAD(cp->daddr)); 108 "%u.%u.%u.%u\n", NIPQUAD(cp->daddr.ip));
105 return NULL; 109 return NULL;
106 } 110 }
107 } 111 }
@@ -109,6 +113,70 @@ __ip_vs_get_out_rt(struct ip_vs_conn *cp, u32 rtos)
109 return rt; 113 return rt;
110} 114}
111 115
116#ifdef CONFIG_IP_VS_IPV6
117static struct rt6_info *
118__ip_vs_get_out_rt_v6(struct ip_vs_conn *cp)
119{
120 struct rt6_info *rt; /* Route to the other host */
121 struct ip_vs_dest *dest = cp->dest;
122
123 if (dest) {
124 spin_lock(&dest->dst_lock);
125 rt = (struct rt6_info *)__ip_vs_dst_check(dest, 0, 0);
126 if (!rt) {
127 struct flowi fl = {
128 .oif = 0,
129 .nl_u = {
130 .ip6_u = {
131 .daddr = dest->addr.in6,
132 .saddr = {
133 .s6_addr32 =
134 { 0, 0, 0, 0 },
135 },
136 },
137 },
138 };
139
140 rt = (struct rt6_info *)ip6_route_output(&init_net,
141 NULL, &fl);
142 if (!rt) {
143 spin_unlock(&dest->dst_lock);
144 IP_VS_DBG_RL("ip6_route_output error, "
145 "dest: " NIP6_FMT "\n",
146 NIP6(dest->addr.in6));
147 return NULL;
148 }
149 __ip_vs_dst_set(dest, 0, dst_clone(&rt->u.dst));
150 IP_VS_DBG(10, "new dst " NIP6_FMT ", refcnt=%d\n",
151 NIP6(dest->addr.in6),
152 atomic_read(&rt->u.dst.__refcnt));
153 }
154 spin_unlock(&dest->dst_lock);
155 } else {
156 struct flowi fl = {
157 .oif = 0,
158 .nl_u = {
159 .ip6_u = {
160 .daddr = cp->daddr.in6,
161 .saddr = {
162 .s6_addr32 = { 0, 0, 0, 0 },
163 },
164 },
165 },
166 };
167
168 rt = (struct rt6_info *)ip6_route_output(&init_net, NULL, &fl);
169 if (!rt) {
170 IP_VS_DBG_RL("ip6_route_output error, dest: "
171 NIP6_FMT "\n", NIP6(cp->daddr.in6));
172 return NULL;
173 }
174 }
175
176 return rt;
177}
178#endif
179
112 180
113/* 181/*
114 * Release dest->dst_cache before a dest is removed 182 * Release dest->dst_cache before a dest is removed
@@ -123,11 +191,11 @@ ip_vs_dst_reset(struct ip_vs_dest *dest)
123 dst_release(old_dst); 191 dst_release(old_dst);
124} 192}
125 193
126#define IP_VS_XMIT(skb, rt) \ 194#define IP_VS_XMIT(pf, skb, rt) \
127do { \ 195do { \
128 (skb)->ipvs_property = 1; \ 196 (skb)->ipvs_property = 1; \
129 skb_forward_csum(skb); \ 197 skb_forward_csum(skb); \
130 NF_HOOK(PF_INET, NF_INET_LOCAL_OUT, (skb), NULL, \ 198 NF_HOOK(pf, NF_INET_LOCAL_OUT, (skb), NULL, \
131 (rt)->u.dst.dev, dst_output); \ 199 (rt)->u.dst.dev, dst_output); \
132} while (0) 200} while (0)
133 201
@@ -200,7 +268,7 @@ ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
200 /* Another hack: avoid icmp_send in ip_fragment */ 268 /* Another hack: avoid icmp_send in ip_fragment */
201 skb->local_df = 1; 269 skb->local_df = 1;
202 270
203 IP_VS_XMIT(skb, rt); 271 IP_VS_XMIT(PF_INET, skb, rt);
204 272
205 LeaveFunction(10); 273 LeaveFunction(10);
206 return NF_STOLEN; 274 return NF_STOLEN;
@@ -213,6 +281,70 @@ ip_vs_bypass_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
213 return NF_STOLEN; 281 return NF_STOLEN;
214} 282}
215 283
284#ifdef CONFIG_IP_VS_IPV6
285int
286ip_vs_bypass_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
287 struct ip_vs_protocol *pp)
288{
289 struct rt6_info *rt; /* Route to the other host */
290 struct ipv6hdr *iph = ipv6_hdr(skb);
291 int mtu;
292 struct flowi fl = {
293 .oif = 0,
294 .nl_u = {
295 .ip6_u = {
296 .daddr = iph->daddr,
297 .saddr = { .s6_addr32 = {0, 0, 0, 0} }, } },
298 };
299
300 EnterFunction(10);
301
302 rt = (struct rt6_info *)ip6_route_output(&init_net, NULL, &fl);
303 if (!rt) {
304 IP_VS_DBG_RL("ip_vs_bypass_xmit_v6(): ip6_route_output error, "
305 "dest: " NIP6_FMT "\n", NIP6(iph->daddr));
306 goto tx_error_icmp;
307 }
308
309 /* MTU checking */
310 mtu = dst_mtu(&rt->u.dst);
311 if (skb->len > mtu) {
312 dst_release(&rt->u.dst);
313 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
314 IP_VS_DBG_RL("ip_vs_bypass_xmit_v6(): frag needed\n");
315 goto tx_error;
316 }
317
318 /*
319 * Call ip_send_check because we are not sure it is called
320 * after ip_defrag. Is copy-on-write needed?
321 */
322 skb = skb_share_check(skb, GFP_ATOMIC);
323 if (unlikely(skb == NULL)) {
324 dst_release(&rt->u.dst);
325 return NF_STOLEN;
326 }
327
328 /* drop old route */
329 dst_release(skb->dst);
330 skb->dst = &rt->u.dst;
331
332 /* Another hack: avoid icmp_send in ip_fragment */
333 skb->local_df = 1;
334
335 IP_VS_XMIT(PF_INET6, skb, rt);
336
337 LeaveFunction(10);
338 return NF_STOLEN;
339
340 tx_error_icmp:
341 dst_link_failure(skb);
342 tx_error:
343 kfree_skb(skb);
344 LeaveFunction(10);
345 return NF_STOLEN;
346}
347#endif
216 348
217/* 349/*
218 * NAT transmitter (only for outside-to-inside nat forwarding) 350 * NAT transmitter (only for outside-to-inside nat forwarding)
@@ -264,7 +396,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
264 /* mangle the packet */ 396 /* mangle the packet */
265 if (pp->dnat_handler && !pp->dnat_handler(skb, pp, cp)) 397 if (pp->dnat_handler && !pp->dnat_handler(skb, pp, cp))
266 goto tx_error; 398 goto tx_error;
267 ip_hdr(skb)->daddr = cp->daddr; 399 ip_hdr(skb)->daddr = cp->daddr.ip;
268 ip_send_check(ip_hdr(skb)); 400 ip_send_check(ip_hdr(skb));
269 401
270 IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT"); 402 IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT");
@@ -276,7 +408,7 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
276 /* Another hack: avoid icmp_send in ip_fragment */ 408 /* Another hack: avoid icmp_send in ip_fragment */
277 skb->local_df = 1; 409 skb->local_df = 1;
278 410
279 IP_VS_XMIT(skb, rt); 411 IP_VS_XMIT(PF_INET, skb, rt);
280 412
281 LeaveFunction(10); 413 LeaveFunction(10);
282 return NF_STOLEN; 414 return NF_STOLEN;
@@ -292,6 +424,83 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
292 goto tx_error; 424 goto tx_error;
293} 425}
294 426
427#ifdef CONFIG_IP_VS_IPV6
428int
429ip_vs_nat_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
430 struct ip_vs_protocol *pp)
431{
432 struct rt6_info *rt; /* Route to the other host */
433 int mtu;
434
435 EnterFunction(10);
436
437 /* check if it is a connection of no-client-port */
438 if (unlikely(cp->flags & IP_VS_CONN_F_NO_CPORT)) {
439 __be16 _pt, *p;
440 p = skb_header_pointer(skb, sizeof(struct ipv6hdr),
441 sizeof(_pt), &_pt);
442 if (p == NULL)
443 goto tx_error;
444 ip_vs_conn_fill_cport(cp, *p);
445 IP_VS_DBG(10, "filled cport=%d\n", ntohs(*p));
446 }
447
448 rt = __ip_vs_get_out_rt_v6(cp);
449 if (!rt)
450 goto tx_error_icmp;
451
452 /* MTU checking */
453 mtu = dst_mtu(&rt->u.dst);
454 if (skb->len > mtu) {
455 dst_release(&rt->u.dst);
456 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
457 IP_VS_DBG_RL_PKT(0, pp, skb, 0,
458 "ip_vs_nat_xmit_v6(): frag needed for");
459 goto tx_error;
460 }
461
462 /* copy-on-write the packet before mangling it */
463 if (!skb_make_writable(skb, sizeof(struct ipv6hdr)))
464 goto tx_error_put;
465
466 if (skb_cow(skb, rt->u.dst.dev->hard_header_len))
467 goto tx_error_put;
468
469 /* drop old route */
470 dst_release(skb->dst);
471 skb->dst = &rt->u.dst;
472
473 /* mangle the packet */
474 if (pp->dnat_handler && !pp->dnat_handler(skb, pp, cp))
475 goto tx_error;
476 ipv6_hdr(skb)->daddr = cp->daddr.in6;
477
478 IP_VS_DBG_PKT(10, pp, skb, 0, "After DNAT");
479
480 /* FIXME: when application helper enlarges the packet and the length
481 is larger than the MTU of outgoing device, there will be still
482 MTU problem. */
483
484 /* Another hack: avoid icmp_send in ip_fragment */
485 skb->local_df = 1;
486
487 IP_VS_XMIT(PF_INET6, skb, rt);
488
489 LeaveFunction(10);
490 return NF_STOLEN;
491
492tx_error_icmp:
493 dst_link_failure(skb);
494tx_error:
495 LeaveFunction(10);
496 kfree_skb(skb);
497 return NF_STOLEN;
498tx_error_put:
499 dst_release(&rt->u.dst);
500 goto tx_error;
501}
502#endif
503
295 504
296/* 505/*
297 * IP Tunneling transmitter 506 * IP Tunneling transmitter
@@ -423,6 +632,112 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
423 return NF_STOLEN; 632 return NF_STOLEN;
424} 633}
425 634
635#ifdef CONFIG_IP_VS_IPV6
636int
637ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
638 struct ip_vs_protocol *pp)
639{
640 struct rt6_info *rt; /* Route to the other host */
641 struct net_device *tdev; /* Device to other host */
642 struct ipv6hdr *old_iph = ipv6_hdr(skb);
643 sk_buff_data_t old_transport_header = skb->transport_header;
644 struct ipv6hdr *iph; /* Our new IP header */
645 unsigned int max_headroom; /* The extra header space needed */
646 int mtu;
647
648 EnterFunction(10);
649
650 if (skb->protocol != htons(ETH_P_IPV6)) {
651 IP_VS_DBG_RL("ip_vs_tunnel_xmit_v6(): protocol error, "
652 "ETH_P_IPV6: %d, skb protocol: %d\n",
653 htons(ETH_P_IPV6), skb->protocol);
654 goto tx_error;
655 }
656
657 rt = __ip_vs_get_out_rt_v6(cp);
658 if (!rt)
659 goto tx_error_icmp;
660
661 tdev = rt->u.dst.dev;
662
663 mtu = dst_mtu(&rt->u.dst) - sizeof(struct ipv6hdr);
664 /* TODO IPv6: do we need this check in IPv6? */
665 if (mtu < 1280) {
666 dst_release(&rt->u.dst);
667 IP_VS_DBG_RL("ip_vs_tunnel_xmit_v6(): mtu less than 1280\n");
668 goto tx_error;
669 }
670 if (skb->dst)
671 skb->dst->ops->update_pmtu(skb->dst, mtu);
672
673 if (mtu < ntohs(old_iph->payload_len) + sizeof(struct ipv6hdr)) {
674 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
675 dst_release(&rt->u.dst);
676 IP_VS_DBG_RL("ip_vs_tunnel_xmit_v6(): frag needed\n");
677 goto tx_error;
678 }
679
680 /*
681 * Okay, now see if we can stuff it in the buffer as-is.
682 */
683 max_headroom = LL_RESERVED_SPACE(tdev) + sizeof(struct ipv6hdr);
684
685 if (skb_headroom(skb) < max_headroom
686 || skb_cloned(skb) || skb_shared(skb)) {
687 struct sk_buff *new_skb =
688 skb_realloc_headroom(skb, max_headroom);
689 if (!new_skb) {
690 dst_release(&rt->u.dst);
691 kfree_skb(skb);
692 IP_VS_ERR_RL("ip_vs_tunnel_xmit_v6(): no memory\n");
693 return NF_STOLEN;
694 }
695 kfree_skb(skb);
696 skb = new_skb;
697 old_iph = ipv6_hdr(skb);
698 }
699
700 skb->transport_header = old_transport_header;
701
702 skb_push(skb, sizeof(struct ipv6hdr));
703 skb_reset_network_header(skb);
704 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
705
706 /* drop old route */
707 dst_release(skb->dst);
708 skb->dst = &rt->u.dst;
709
710 /*
711 * Push down and install the IPIP header.
712 */
713 iph = ipv6_hdr(skb);
714 iph->version = 6;
715 iph->nexthdr = IPPROTO_IPV6;
716 iph->payload_len = old_iph->payload_len + sizeof(old_iph);
717 iph->priority = old_iph->priority;
718 memset(&iph->flow_lbl, 0, sizeof(iph->flow_lbl));
719 iph->daddr = rt->rt6i_dst.addr;
720 iph->saddr = cp->vaddr.in6; /* rt->rt6i_src.addr; */
721 iph->hop_limit = old_iph->hop_limit;
722
723 /* Another hack: avoid icmp_send in ip_fragment */
724 skb->local_df = 1;
725
726 ip6_local_out(skb);
727
728 LeaveFunction(10);
729
730 return NF_STOLEN;
731
732tx_error_icmp:
733 dst_link_failure(skb);
734tx_error:
735 kfree_skb(skb);
736 LeaveFunction(10);
737 return NF_STOLEN;
738}
739#endif
740
426 741
427/* 742/*
428 * Direct Routing transmitter 743 * Direct Routing transmitter
@@ -467,7 +782,7 @@ ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
467 /* Another hack: avoid icmp_send in ip_fragment */ 782 /* Another hack: avoid icmp_send in ip_fragment */
468 skb->local_df = 1; 783 skb->local_df = 1;
469 784
470 IP_VS_XMIT(skb, rt); 785 IP_VS_XMIT(PF_INET, skb, rt);
471 786
472 LeaveFunction(10); 787 LeaveFunction(10);
473 return NF_STOLEN; 788 return NF_STOLEN;
@@ -480,6 +795,60 @@ ip_vs_dr_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
480 return NF_STOLEN; 795 return NF_STOLEN;
481} 796}
482 797
798#ifdef CONFIG_IP_VS_IPV6
799int
800ip_vs_dr_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
801 struct ip_vs_protocol *pp)
802{
803 struct rt6_info *rt; /* Route to the other host */
804 int mtu;
805
806 EnterFunction(10);
807
808 rt = __ip_vs_get_out_rt_v6(cp);
809 if (!rt)
810 goto tx_error_icmp;
811
812 /* MTU checking */
813 mtu = dst_mtu(&rt->u.dst);
814 if (skb->len > mtu) {
815 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
816 dst_release(&rt->u.dst);
817 IP_VS_DBG_RL("ip_vs_dr_xmit_v6(): frag needed\n");
818 goto tx_error;
819 }
820
821 /*
822 * Call ip_send_check because we are not sure it is called
823 * after ip_defrag. Is copy-on-write needed?
824 */
825 skb = skb_share_check(skb, GFP_ATOMIC);
826 if (unlikely(skb == NULL)) {
827 dst_release(&rt->u.dst);
828 return NF_STOLEN;
829 }
830
831 /* drop old route */
832 dst_release(skb->dst);
833 skb->dst = &rt->u.dst;
834
835 /* Another hack: avoid icmp_send in ip_fragment */
836 skb->local_df = 1;
837
838 IP_VS_XMIT(PF_INET6, skb, rt);
839
840 LeaveFunction(10);
841 return NF_STOLEN;
842
843tx_error_icmp:
844 dst_link_failure(skb);
845tx_error:
846 kfree_skb(skb);
847 LeaveFunction(10);
848 return NF_STOLEN;
849}
850#endif
851
483 852
484/* 853/*
485 * ICMP packet transmitter 854 * ICMP packet transmitter
@@ -540,7 +909,7 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
540 /* Another hack: avoid icmp_send in ip_fragment */ 909 /* Another hack: avoid icmp_send in ip_fragment */
541 skb->local_df = 1; 910 skb->local_df = 1;
542 911
543 IP_VS_XMIT(skb, rt); 912 IP_VS_XMIT(PF_INET, skb, rt);
544 913
545 rc = NF_STOLEN; 914 rc = NF_STOLEN;
546 goto out; 915 goto out;
@@ -557,3 +926,79 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
557 ip_rt_put(rt); 926 ip_rt_put(rt);
558 goto tx_error; 927 goto tx_error;
559} 928}
929
930#ifdef CONFIG_IP_VS_IPV6
931int
932ip_vs_icmp_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
933 struct ip_vs_protocol *pp, int offset)
934{
935 struct rt6_info *rt; /* Route to the other host */
936 int mtu;
937 int rc;
938
939 EnterFunction(10);
940
941 /* The ICMP packet for VS/TUN, VS/DR and LOCALNODE will be
942 forwarded directly here, because there is no need to
943 translate address/port back */
944 if (IP_VS_FWD_METHOD(cp) != IP_VS_CONN_F_MASQ) {
945 if (cp->packet_xmit)
946 rc = cp->packet_xmit(skb, cp, pp);
947 else
948 rc = NF_ACCEPT;
949 /* do not touch skb anymore */
950 atomic_inc(&cp->in_pkts);
951 goto out;
952 }
953
954 /*
955 * mangle and send the packet here (only for VS/NAT)
956 */
957
958 rt = __ip_vs_get_out_rt_v6(cp);
959 if (!rt)
960 goto tx_error_icmp;
961
962 /* MTU checking */
963 mtu = dst_mtu(&rt->u.dst);
964 if (skb->len > mtu) {
965 dst_release(&rt->u.dst);
966 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
967 IP_VS_DBG_RL("ip_vs_in_icmp(): frag needed\n");
968 goto tx_error;
969 }
970
971 /* copy-on-write the packet before mangling it */
972 if (!skb_make_writable(skb, offset))
973 goto tx_error_put;
974
975 if (skb_cow(skb, rt->u.dst.dev->hard_header_len))
976 goto tx_error_put;
977
978 /* drop the old route when skb is not shared */
979 dst_release(skb->dst);
980 skb->dst = &rt->u.dst;
981
982 ip_vs_nat_icmp_v6(skb, pp, cp, 0);
983
984 /* Another hack: avoid icmp_send in ip_fragment */
985 skb->local_df = 1;
986
987 IP_VS_XMIT(PF_INET6, skb, rt);
988
989 rc = NF_STOLEN;
990 goto out;
991
992tx_error_icmp:
993 dst_link_failure(skb);
994tx_error:
995 dev_kfree_skb(skb);
996 rc = NF_STOLEN;
997out:
998 LeaveFunction(10);
999 return rc;
1000tx_error_put:
1001 dst_release(&rt->u.dst);
1002 goto tx_error;
1003}
1004#endif
diff --git a/net/netfilter/nf_conntrack_acct.c b/net/netfilter/nf_conntrack_acct.c
index 59bd8b903a19..03591d37b9cc 100644
--- a/net/netfilter/nf_conntrack_acct.c
+++ b/net/netfilter/nf_conntrack_acct.c
@@ -22,19 +22,17 @@
22#define NF_CT_ACCT_DEFAULT 0 22#define NF_CT_ACCT_DEFAULT 0
23#endif 23#endif
24 24
25int nf_ct_acct __read_mostly = NF_CT_ACCT_DEFAULT; 25static int nf_ct_acct __read_mostly = NF_CT_ACCT_DEFAULT;
26EXPORT_SYMBOL_GPL(nf_ct_acct);
27 26
28module_param_named(acct, nf_ct_acct, bool, 0644); 27module_param_named(acct, nf_ct_acct, bool, 0644);
29MODULE_PARM_DESC(acct, "Enable connection tracking flow accounting."); 28MODULE_PARM_DESC(acct, "Enable connection tracking flow accounting.");
30 29
31#ifdef CONFIG_SYSCTL 30#ifdef CONFIG_SYSCTL
32static struct ctl_table_header *acct_sysctl_header;
33static struct ctl_table acct_sysctl_table[] = { 31static struct ctl_table acct_sysctl_table[] = {
34 { 32 {
35 .ctl_name = CTL_UNNUMBERED, 33 .ctl_name = CTL_UNNUMBERED,
36 .procname = "nf_conntrack_acct", 34 .procname = "nf_conntrack_acct",
37 .data = &nf_ct_acct, 35 .data = &init_net.ct.sysctl_acct,
38 .maxlen = sizeof(unsigned int), 36 .maxlen = sizeof(unsigned int),
39 .mode = 0644, 37 .mode = 0644,
40 .proc_handler = &proc_dointvec, 38 .proc_handler = &proc_dointvec,
@@ -64,41 +62,87 @@ static struct nf_ct_ext_type acct_extend __read_mostly = {
64 .id = NF_CT_EXT_ACCT, 62 .id = NF_CT_EXT_ACCT,
65}; 63};
66 64
67int nf_conntrack_acct_init(void) 65#ifdef CONFIG_SYSCTL
66static int nf_conntrack_acct_init_sysctl(struct net *net)
68{ 67{
69 int ret; 68 struct ctl_table *table;
70 69
71#ifdef CONFIG_NF_CT_ACCT 70 table = kmemdup(acct_sysctl_table, sizeof(acct_sysctl_table),
72 printk(KERN_WARNING "CONFIG_NF_CT_ACCT is deprecated and will be removed soon. Plase use\n"); 71 GFP_KERNEL);
73 printk(KERN_WARNING "nf_conntrack.acct=1 kernel paramater, acct=1 nf_conntrack module option or\n"); 72 if (!table)
74 printk(KERN_WARNING "sysctl net.netfilter.nf_conntrack_acct=1 to enable it.\n"); 73 goto out;
75#endif 74
75 table[0].data = &net->ct.sysctl_acct;
76 76
77 ret = nf_ct_extend_register(&acct_extend); 77 net->ct.acct_sysctl_header = register_net_sysctl_table(net,
78 if (ret < 0) { 78 nf_net_netfilter_sysctl_path, table);
79 printk(KERN_ERR "nf_conntrack_acct: Unable to register extension\n"); 79 if (!net->ct.acct_sysctl_header) {
80 return ret; 80 printk(KERN_ERR "nf_conntrack_acct: can't register to sysctl.\n");
81 goto out_register;
81 } 82 }
83 return 0;
82 84
83#ifdef CONFIG_SYSCTL 85out_register:
84 acct_sysctl_header = register_sysctl_paths(nf_net_netfilter_sysctl_path, 86 kfree(table);
85 acct_sysctl_table); 87out:
88 return -ENOMEM;
89}
86 90
87 if (!acct_sysctl_header) { 91static void nf_conntrack_acct_fini_sysctl(struct net *net)
88 nf_ct_extend_unregister(&acct_extend); 92{
93 struct ctl_table *table;
89 94
90 printk(KERN_ERR "nf_conntrack_acct: can't register to sysctl.\n"); 95 table = net->ct.acct_sysctl_header->ctl_table_arg;
91 return -ENOMEM; 96 unregister_net_sysctl_table(net->ct.acct_sysctl_header);
92 } 97 kfree(table);
98}
99#else
100static int nf_conntrack_acct_init_sysctl(struct net *net)
101{
102 return 0;
103}
104
105static void nf_conntrack_acct_fini_sysctl(struct net *net)
106{
107}
108#endif
109
110int nf_conntrack_acct_init(struct net *net)
111{
112 int ret;
113
114 net->ct.sysctl_acct = nf_ct_acct;
115
116 if (net_eq(net, &init_net)) {
117#ifdef CONFIG_NF_CT_ACCT
118 printk(KERN_WARNING "CONFIG_NF_CT_ACCT is deprecated and will be removed soon. Plase use\n");
119 printk(KERN_WARNING "nf_conntrack.acct=1 kernel paramater, acct=1 nf_conntrack module option or\n");
120 printk(KERN_WARNING "sysctl net.netfilter.nf_conntrack_acct=1 to enable it.\n");
93#endif 121#endif
94 122
123 ret = nf_ct_extend_register(&acct_extend);
124 if (ret < 0) {
125 printk(KERN_ERR "nf_conntrack_acct: Unable to register extension\n");
126 goto out_extend_register;
127 }
128 }
129
130 ret = nf_conntrack_acct_init_sysctl(net);
131 if (ret < 0)
132 goto out_sysctl;
133
95 return 0; 134 return 0;
135
136out_sysctl:
137 if (net_eq(net, &init_net))
138 nf_ct_extend_unregister(&acct_extend);
139out_extend_register:
140 return ret;
96} 141}
97 142
98void nf_conntrack_acct_fini(void) 143void nf_conntrack_acct_fini(struct net *net)
99{ 144{
100#ifdef CONFIG_SYSCTL 145 nf_conntrack_acct_fini_sysctl(net);
101 unregister_sysctl_table(acct_sysctl_header); 146 if (net_eq(net, &init_net))
102#endif 147 nf_ct_extend_unregister(&acct_extend);
103 nf_ct_extend_unregister(&acct_extend);
104} 148}
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 9d1830da8e84..27de3c7b006e 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -44,30 +44,17 @@
44DEFINE_SPINLOCK(nf_conntrack_lock); 44DEFINE_SPINLOCK(nf_conntrack_lock);
45EXPORT_SYMBOL_GPL(nf_conntrack_lock); 45EXPORT_SYMBOL_GPL(nf_conntrack_lock);
46 46
47/* nf_conntrack_standalone needs this */
48atomic_t nf_conntrack_count = ATOMIC_INIT(0);
49EXPORT_SYMBOL_GPL(nf_conntrack_count);
50
51unsigned int nf_conntrack_htable_size __read_mostly; 47unsigned int nf_conntrack_htable_size __read_mostly;
52EXPORT_SYMBOL_GPL(nf_conntrack_htable_size); 48EXPORT_SYMBOL_GPL(nf_conntrack_htable_size);
53 49
54int nf_conntrack_max __read_mostly; 50int nf_conntrack_max __read_mostly;
55EXPORT_SYMBOL_GPL(nf_conntrack_max); 51EXPORT_SYMBOL_GPL(nf_conntrack_max);
56 52
57struct hlist_head *nf_conntrack_hash __read_mostly;
58EXPORT_SYMBOL_GPL(nf_conntrack_hash);
59
60struct nf_conn nf_conntrack_untracked __read_mostly; 53struct nf_conn nf_conntrack_untracked __read_mostly;
61EXPORT_SYMBOL_GPL(nf_conntrack_untracked); 54EXPORT_SYMBOL_GPL(nf_conntrack_untracked);
62 55
63unsigned int nf_ct_log_invalid __read_mostly;
64HLIST_HEAD(unconfirmed);
65static int nf_conntrack_vmalloc __read_mostly;
66static struct kmem_cache *nf_conntrack_cachep __read_mostly; 56static struct kmem_cache *nf_conntrack_cachep __read_mostly;
67 57
68DEFINE_PER_CPU(struct ip_conntrack_stat, nf_conntrack_stat);
69EXPORT_PER_CPU_SYMBOL(nf_conntrack_stat);
70
71static int nf_conntrack_hash_rnd_initted; 58static int nf_conntrack_hash_rnd_initted;
72static unsigned int nf_conntrack_hash_rnd; 59static unsigned int nf_conntrack_hash_rnd;
73 60
@@ -180,6 +167,7 @@ static void
180destroy_conntrack(struct nf_conntrack *nfct) 167destroy_conntrack(struct nf_conntrack *nfct)
181{ 168{
182 struct nf_conn *ct = (struct nf_conn *)nfct; 169 struct nf_conn *ct = (struct nf_conn *)nfct;
170 struct net *net = nf_ct_net(ct);
183 struct nf_conntrack_l4proto *l4proto; 171 struct nf_conntrack_l4proto *l4proto;
184 172
185 pr_debug("destroy_conntrack(%p)\n", ct); 173 pr_debug("destroy_conntrack(%p)\n", ct);
@@ -212,7 +200,7 @@ destroy_conntrack(struct nf_conntrack *nfct)
212 hlist_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode); 200 hlist_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode);
213 } 201 }
214 202
215 NF_CT_STAT_INC(delete); 203 NF_CT_STAT_INC(net, delete);
216 spin_unlock_bh(&nf_conntrack_lock); 204 spin_unlock_bh(&nf_conntrack_lock);
217 205
218 if (ct->master) 206 if (ct->master)
@@ -225,6 +213,7 @@ destroy_conntrack(struct nf_conntrack *nfct)
225static void death_by_timeout(unsigned long ul_conntrack) 213static void death_by_timeout(unsigned long ul_conntrack)
226{ 214{
227 struct nf_conn *ct = (void *)ul_conntrack; 215 struct nf_conn *ct = (void *)ul_conntrack;
216 struct net *net = nf_ct_net(ct);
228 struct nf_conn_help *help = nfct_help(ct); 217 struct nf_conn_help *help = nfct_help(ct);
229 struct nf_conntrack_helper *helper; 218 struct nf_conntrack_helper *helper;
230 219
@@ -239,14 +228,14 @@ static void death_by_timeout(unsigned long ul_conntrack)
239 spin_lock_bh(&nf_conntrack_lock); 228 spin_lock_bh(&nf_conntrack_lock);
240 /* Inside lock so preempt is disabled on module removal path. 229 /* Inside lock so preempt is disabled on module removal path.
241 * Otherwise we can get spurious warnings. */ 230 * Otherwise we can get spurious warnings. */
242 NF_CT_STAT_INC(delete_list); 231 NF_CT_STAT_INC(net, delete_list);
243 clean_from_lists(ct); 232 clean_from_lists(ct);
244 spin_unlock_bh(&nf_conntrack_lock); 233 spin_unlock_bh(&nf_conntrack_lock);
245 nf_ct_put(ct); 234 nf_ct_put(ct);
246} 235}
247 236
248struct nf_conntrack_tuple_hash * 237struct nf_conntrack_tuple_hash *
249__nf_conntrack_find(const struct nf_conntrack_tuple *tuple) 238__nf_conntrack_find(struct net *net, const struct nf_conntrack_tuple *tuple)
250{ 239{
251 struct nf_conntrack_tuple_hash *h; 240 struct nf_conntrack_tuple_hash *h;
252 struct hlist_node *n; 241 struct hlist_node *n;
@@ -256,13 +245,13 @@ __nf_conntrack_find(const struct nf_conntrack_tuple *tuple)
256 * at least once for the stats anyway. 245 * at least once for the stats anyway.
257 */ 246 */
258 local_bh_disable(); 247 local_bh_disable();
259 hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[hash], hnode) { 248 hlist_for_each_entry_rcu(h, n, &net->ct.hash[hash], hnode) {
260 if (nf_ct_tuple_equal(tuple, &h->tuple)) { 249 if (nf_ct_tuple_equal(tuple, &h->tuple)) {
261 NF_CT_STAT_INC(found); 250 NF_CT_STAT_INC(net, found);
262 local_bh_enable(); 251 local_bh_enable();
263 return h; 252 return h;
264 } 253 }
265 NF_CT_STAT_INC(searched); 254 NF_CT_STAT_INC(net, searched);
266 } 255 }
267 local_bh_enable(); 256 local_bh_enable();
268 257
@@ -272,13 +261,13 @@ EXPORT_SYMBOL_GPL(__nf_conntrack_find);
272 261
273/* Find a connection corresponding to a tuple. */ 262/* Find a connection corresponding to a tuple. */
274struct nf_conntrack_tuple_hash * 263struct nf_conntrack_tuple_hash *
275nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple) 264nf_conntrack_find_get(struct net *net, const struct nf_conntrack_tuple *tuple)
276{ 265{
277 struct nf_conntrack_tuple_hash *h; 266 struct nf_conntrack_tuple_hash *h;
278 struct nf_conn *ct; 267 struct nf_conn *ct;
279 268
280 rcu_read_lock(); 269 rcu_read_lock();
281 h = __nf_conntrack_find(tuple); 270 h = __nf_conntrack_find(net, tuple);
282 if (h) { 271 if (h) {
283 ct = nf_ct_tuplehash_to_ctrack(h); 272 ct = nf_ct_tuplehash_to_ctrack(h);
284 if (unlikely(!atomic_inc_not_zero(&ct->ct_general.use))) 273 if (unlikely(!atomic_inc_not_zero(&ct->ct_general.use)))
@@ -294,10 +283,12 @@ static void __nf_conntrack_hash_insert(struct nf_conn *ct,
294 unsigned int hash, 283 unsigned int hash,
295 unsigned int repl_hash) 284 unsigned int repl_hash)
296{ 285{
286 struct net *net = nf_ct_net(ct);
287
297 hlist_add_head_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode, 288 hlist_add_head_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode,
298 &nf_conntrack_hash[hash]); 289 &net->ct.hash[hash]);
299 hlist_add_head_rcu(&ct->tuplehash[IP_CT_DIR_REPLY].hnode, 290 hlist_add_head_rcu(&ct->tuplehash[IP_CT_DIR_REPLY].hnode,
300 &nf_conntrack_hash[repl_hash]); 291 &net->ct.hash[repl_hash]);
301} 292}
302 293
303void nf_conntrack_hash_insert(struct nf_conn *ct) 294void nf_conntrack_hash_insert(struct nf_conn *ct)
@@ -323,8 +314,10 @@ __nf_conntrack_confirm(struct sk_buff *skb)
323 struct nf_conn_help *help; 314 struct nf_conn_help *help;
324 struct hlist_node *n; 315 struct hlist_node *n;
325 enum ip_conntrack_info ctinfo; 316 enum ip_conntrack_info ctinfo;
317 struct net *net;
326 318
327 ct = nf_ct_get(skb, &ctinfo); 319 ct = nf_ct_get(skb, &ctinfo);
320 net = nf_ct_net(ct);
328 321
329 /* ipt_REJECT uses nf_conntrack_attach to attach related 322 /* ipt_REJECT uses nf_conntrack_attach to attach related
330 ICMP/TCP RST packets in other direction. Actual packet 323 ICMP/TCP RST packets in other direction. Actual packet
@@ -351,11 +344,11 @@ __nf_conntrack_confirm(struct sk_buff *skb)
351 /* See if there's one in the list already, including reverse: 344 /* See if there's one in the list already, including reverse:
352 NAT could have grabbed it without realizing, since we're 345 NAT could have grabbed it without realizing, since we're
353 not in the hash. If there is, we lost race. */ 346 not in the hash. If there is, we lost race. */
354 hlist_for_each_entry(h, n, &nf_conntrack_hash[hash], hnode) 347 hlist_for_each_entry(h, n, &net->ct.hash[hash], hnode)
355 if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, 348 if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
356 &h->tuple)) 349 &h->tuple))
357 goto out; 350 goto out;
358 hlist_for_each_entry(h, n, &nf_conntrack_hash[repl_hash], hnode) 351 hlist_for_each_entry(h, n, &net->ct.hash[repl_hash], hnode)
359 if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_REPLY].tuple, 352 if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_REPLY].tuple,
360 &h->tuple)) 353 &h->tuple))
361 goto out; 354 goto out;
@@ -371,22 +364,22 @@ __nf_conntrack_confirm(struct sk_buff *skb)
371 add_timer(&ct->timeout); 364 add_timer(&ct->timeout);
372 atomic_inc(&ct->ct_general.use); 365 atomic_inc(&ct->ct_general.use);
373 set_bit(IPS_CONFIRMED_BIT, &ct->status); 366 set_bit(IPS_CONFIRMED_BIT, &ct->status);
374 NF_CT_STAT_INC(insert); 367 NF_CT_STAT_INC(net, insert);
375 spin_unlock_bh(&nf_conntrack_lock); 368 spin_unlock_bh(&nf_conntrack_lock);
376 help = nfct_help(ct); 369 help = nfct_help(ct);
377 if (help && help->helper) 370 if (help && help->helper)
378 nf_conntrack_event_cache(IPCT_HELPER, skb); 371 nf_conntrack_event_cache(IPCT_HELPER, ct);
379#ifdef CONFIG_NF_NAT_NEEDED 372#ifdef CONFIG_NF_NAT_NEEDED
380 if (test_bit(IPS_SRC_NAT_DONE_BIT, &ct->status) || 373 if (test_bit(IPS_SRC_NAT_DONE_BIT, &ct->status) ||
381 test_bit(IPS_DST_NAT_DONE_BIT, &ct->status)) 374 test_bit(IPS_DST_NAT_DONE_BIT, &ct->status))
382 nf_conntrack_event_cache(IPCT_NATINFO, skb); 375 nf_conntrack_event_cache(IPCT_NATINFO, ct);
383#endif 376#endif
384 nf_conntrack_event_cache(master_ct(ct) ? 377 nf_conntrack_event_cache(master_ct(ct) ?
385 IPCT_RELATED : IPCT_NEW, skb); 378 IPCT_RELATED : IPCT_NEW, ct);
386 return NF_ACCEPT; 379 return NF_ACCEPT;
387 380
388out: 381out:
389 NF_CT_STAT_INC(insert_failed); 382 NF_CT_STAT_INC(net, insert_failed);
390 spin_unlock_bh(&nf_conntrack_lock); 383 spin_unlock_bh(&nf_conntrack_lock);
391 return NF_DROP; 384 return NF_DROP;
392} 385}
@@ -398,6 +391,7 @@ int
398nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple, 391nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
399 const struct nf_conn *ignored_conntrack) 392 const struct nf_conn *ignored_conntrack)
400{ 393{
394 struct net *net = nf_ct_net(ignored_conntrack);
401 struct nf_conntrack_tuple_hash *h; 395 struct nf_conntrack_tuple_hash *h;
402 struct hlist_node *n; 396 struct hlist_node *n;
403 unsigned int hash = hash_conntrack(tuple); 397 unsigned int hash = hash_conntrack(tuple);
@@ -406,14 +400,14 @@ nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
406 * least once for the stats anyway. 400 * least once for the stats anyway.
407 */ 401 */
408 rcu_read_lock_bh(); 402 rcu_read_lock_bh();
409 hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[hash], hnode) { 403 hlist_for_each_entry_rcu(h, n, &net->ct.hash[hash], hnode) {
410 if (nf_ct_tuplehash_to_ctrack(h) != ignored_conntrack && 404 if (nf_ct_tuplehash_to_ctrack(h) != ignored_conntrack &&
411 nf_ct_tuple_equal(tuple, &h->tuple)) { 405 nf_ct_tuple_equal(tuple, &h->tuple)) {
412 NF_CT_STAT_INC(found); 406 NF_CT_STAT_INC(net, found);
413 rcu_read_unlock_bh(); 407 rcu_read_unlock_bh();
414 return 1; 408 return 1;
415 } 409 }
416 NF_CT_STAT_INC(searched); 410 NF_CT_STAT_INC(net, searched);
417 } 411 }
418 rcu_read_unlock_bh(); 412 rcu_read_unlock_bh();
419 413
@@ -425,7 +419,7 @@ EXPORT_SYMBOL_GPL(nf_conntrack_tuple_taken);
425 419
426/* There's a small race here where we may free a just-assured 420/* There's a small race here where we may free a just-assured
427 connection. Too bad: we're in trouble anyway. */ 421 connection. Too bad: we're in trouble anyway. */
428static noinline int early_drop(unsigned int hash) 422static noinline int early_drop(struct net *net, unsigned int hash)
429{ 423{
430 /* Use oldest entry, which is roughly LRU */ 424 /* Use oldest entry, which is roughly LRU */
431 struct nf_conntrack_tuple_hash *h; 425 struct nf_conntrack_tuple_hash *h;
@@ -436,7 +430,7 @@ static noinline int early_drop(unsigned int hash)
436 430
437 rcu_read_lock(); 431 rcu_read_lock();
438 for (i = 0; i < nf_conntrack_htable_size; i++) { 432 for (i = 0; i < nf_conntrack_htable_size; i++) {
439 hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[hash], 433 hlist_for_each_entry_rcu(h, n, &net->ct.hash[hash],
440 hnode) { 434 hnode) {
441 tmp = nf_ct_tuplehash_to_ctrack(h); 435 tmp = nf_ct_tuplehash_to_ctrack(h);
442 if (!test_bit(IPS_ASSURED_BIT, &tmp->status)) 436 if (!test_bit(IPS_ASSURED_BIT, &tmp->status))
@@ -458,13 +452,14 @@ static noinline int early_drop(unsigned int hash)
458 if (del_timer(&ct->timeout)) { 452 if (del_timer(&ct->timeout)) {
459 death_by_timeout((unsigned long)ct); 453 death_by_timeout((unsigned long)ct);
460 dropped = 1; 454 dropped = 1;
461 NF_CT_STAT_INC_ATOMIC(early_drop); 455 NF_CT_STAT_INC_ATOMIC(net, early_drop);
462 } 456 }
463 nf_ct_put(ct); 457 nf_ct_put(ct);
464 return dropped; 458 return dropped;
465} 459}
466 460
467struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig, 461struct nf_conn *nf_conntrack_alloc(struct net *net,
462 const struct nf_conntrack_tuple *orig,
468 const struct nf_conntrack_tuple *repl, 463 const struct nf_conntrack_tuple *repl,
469 gfp_t gfp) 464 gfp_t gfp)
470{ 465{
@@ -476,13 +471,13 @@ struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
476 } 471 }
477 472
478 /* We don't want any race condition at early drop stage */ 473 /* We don't want any race condition at early drop stage */
479 atomic_inc(&nf_conntrack_count); 474 atomic_inc(&net->ct.count);
480 475
481 if (nf_conntrack_max && 476 if (nf_conntrack_max &&
482 unlikely(atomic_read(&nf_conntrack_count) > nf_conntrack_max)) { 477 unlikely(atomic_read(&net->ct.count) > nf_conntrack_max)) {
483 unsigned int hash = hash_conntrack(orig); 478 unsigned int hash = hash_conntrack(orig);
484 if (!early_drop(hash)) { 479 if (!early_drop(net, hash)) {
485 atomic_dec(&nf_conntrack_count); 480 atomic_dec(&net->ct.count);
486 if (net_ratelimit()) 481 if (net_ratelimit())
487 printk(KERN_WARNING 482 printk(KERN_WARNING
488 "nf_conntrack: table full, dropping" 483 "nf_conntrack: table full, dropping"
@@ -494,7 +489,7 @@ struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
494 ct = kmem_cache_zalloc(nf_conntrack_cachep, gfp); 489 ct = kmem_cache_zalloc(nf_conntrack_cachep, gfp);
495 if (ct == NULL) { 490 if (ct == NULL) {
496 pr_debug("nf_conntrack_alloc: Can't alloc conntrack.\n"); 491 pr_debug("nf_conntrack_alloc: Can't alloc conntrack.\n");
497 atomic_dec(&nf_conntrack_count); 492 atomic_dec(&net->ct.count);
498 return ERR_PTR(-ENOMEM); 493 return ERR_PTR(-ENOMEM);
499 } 494 }
500 495
@@ -503,6 +498,9 @@ struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
503 ct->tuplehash[IP_CT_DIR_REPLY].tuple = *repl; 498 ct->tuplehash[IP_CT_DIR_REPLY].tuple = *repl;
504 /* Don't set timer yet: wait for confirmation */ 499 /* Don't set timer yet: wait for confirmation */
505 setup_timer(&ct->timeout, death_by_timeout, (unsigned long)ct); 500 setup_timer(&ct->timeout, death_by_timeout, (unsigned long)ct);
501#ifdef CONFIG_NET_NS
502 ct->ct_net = net;
503#endif
506 INIT_RCU_HEAD(&ct->rcu); 504 INIT_RCU_HEAD(&ct->rcu);
507 505
508 return ct; 506 return ct;
@@ -512,10 +510,11 @@ EXPORT_SYMBOL_GPL(nf_conntrack_alloc);
512static void nf_conntrack_free_rcu(struct rcu_head *head) 510static void nf_conntrack_free_rcu(struct rcu_head *head)
513{ 511{
514 struct nf_conn *ct = container_of(head, struct nf_conn, rcu); 512 struct nf_conn *ct = container_of(head, struct nf_conn, rcu);
513 struct net *net = nf_ct_net(ct);
515 514
516 nf_ct_ext_free(ct); 515 nf_ct_ext_free(ct);
517 kmem_cache_free(nf_conntrack_cachep, ct); 516 kmem_cache_free(nf_conntrack_cachep, ct);
518 atomic_dec(&nf_conntrack_count); 517 atomic_dec(&net->ct.count);
519} 518}
520 519
521void nf_conntrack_free(struct nf_conn *ct) 520void nf_conntrack_free(struct nf_conn *ct)
@@ -528,7 +527,8 @@ EXPORT_SYMBOL_GPL(nf_conntrack_free);
528/* Allocate a new conntrack: we return -ENOMEM if classification 527/* Allocate a new conntrack: we return -ENOMEM if classification
529 failed due to stress. Otherwise it really is unclassifiable. */ 528 failed due to stress. Otherwise it really is unclassifiable. */
530static struct nf_conntrack_tuple_hash * 529static struct nf_conntrack_tuple_hash *
531init_conntrack(const struct nf_conntrack_tuple *tuple, 530init_conntrack(struct net *net,
531 const struct nf_conntrack_tuple *tuple,
532 struct nf_conntrack_l3proto *l3proto, 532 struct nf_conntrack_l3proto *l3proto,
533 struct nf_conntrack_l4proto *l4proto, 533 struct nf_conntrack_l4proto *l4proto,
534 struct sk_buff *skb, 534 struct sk_buff *skb,
@@ -544,7 +544,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
544 return NULL; 544 return NULL;
545 } 545 }
546 546
547 ct = nf_conntrack_alloc(tuple, &repl_tuple, GFP_ATOMIC); 547 ct = nf_conntrack_alloc(net, tuple, &repl_tuple, GFP_ATOMIC);
548 if (ct == NULL || IS_ERR(ct)) { 548 if (ct == NULL || IS_ERR(ct)) {
549 pr_debug("Can't allocate conntrack.\n"); 549 pr_debug("Can't allocate conntrack.\n");
550 return (struct nf_conntrack_tuple_hash *)ct; 550 return (struct nf_conntrack_tuple_hash *)ct;
@@ -559,7 +559,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
559 nf_ct_acct_ext_add(ct, GFP_ATOMIC); 559 nf_ct_acct_ext_add(ct, GFP_ATOMIC);
560 560
561 spin_lock_bh(&nf_conntrack_lock); 561 spin_lock_bh(&nf_conntrack_lock);
562 exp = nf_ct_find_expectation(tuple); 562 exp = nf_ct_find_expectation(net, tuple);
563 if (exp) { 563 if (exp) {
564 pr_debug("conntrack: expectation arrives ct=%p exp=%p\n", 564 pr_debug("conntrack: expectation arrives ct=%p exp=%p\n",
565 ct, exp); 565 ct, exp);
@@ -579,7 +579,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
579 ct->secmark = exp->master->secmark; 579 ct->secmark = exp->master->secmark;
580#endif 580#endif
581 nf_conntrack_get(&ct->master->ct_general); 581 nf_conntrack_get(&ct->master->ct_general);
582 NF_CT_STAT_INC(expect_new); 582 NF_CT_STAT_INC(net, expect_new);
583 } else { 583 } else {
584 struct nf_conntrack_helper *helper; 584 struct nf_conntrack_helper *helper;
585 585
@@ -589,11 +589,12 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
589 if (help) 589 if (help)
590 rcu_assign_pointer(help->helper, helper); 590 rcu_assign_pointer(help->helper, helper);
591 } 591 }
592 NF_CT_STAT_INC(new); 592 NF_CT_STAT_INC(net, new);
593 } 593 }
594 594
595 /* Overload tuple linked list to put us in unconfirmed list. */ 595 /* Overload tuple linked list to put us in unconfirmed list. */
596 hlist_add_head(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode, &unconfirmed); 596 hlist_add_head(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode,
597 &net->ct.unconfirmed);
597 598
598 spin_unlock_bh(&nf_conntrack_lock); 599 spin_unlock_bh(&nf_conntrack_lock);
599 600
@@ -608,7 +609,8 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
608 609
609/* On success, returns conntrack ptr, sets skb->nfct and ctinfo */ 610/* On success, returns conntrack ptr, sets skb->nfct and ctinfo */
610static inline struct nf_conn * 611static inline struct nf_conn *
611resolve_normal_ct(struct sk_buff *skb, 612resolve_normal_ct(struct net *net,
613 struct sk_buff *skb,
612 unsigned int dataoff, 614 unsigned int dataoff,
613 u_int16_t l3num, 615 u_int16_t l3num,
614 u_int8_t protonum, 616 u_int8_t protonum,
@@ -629,9 +631,9 @@ resolve_normal_ct(struct sk_buff *skb,
629 } 631 }
630 632
631 /* look for tuple match */ 633 /* look for tuple match */
632 h = nf_conntrack_find_get(&tuple); 634 h = nf_conntrack_find_get(net, &tuple);
633 if (!h) { 635 if (!h) {
634 h = init_conntrack(&tuple, l3proto, l4proto, skb, dataoff); 636 h = init_conntrack(net, &tuple, l3proto, l4proto, skb, dataoff);
635 if (!h) 637 if (!h)
636 return NULL; 638 return NULL;
637 if (IS_ERR(h)) 639 if (IS_ERR(h))
@@ -665,7 +667,8 @@ resolve_normal_ct(struct sk_buff *skb,
665} 667}
666 668
667unsigned int 669unsigned int
668nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff *skb) 670nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,
671 struct sk_buff *skb)
669{ 672{
670 struct nf_conn *ct; 673 struct nf_conn *ct;
671 enum ip_conntrack_info ctinfo; 674 enum ip_conntrack_info ctinfo;
@@ -678,44 +681,46 @@ nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff *skb)
678 681
679 /* Previously seen (loopback or untracked)? Ignore. */ 682 /* Previously seen (loopback or untracked)? Ignore. */
680 if (skb->nfct) { 683 if (skb->nfct) {
681 NF_CT_STAT_INC_ATOMIC(ignore); 684 NF_CT_STAT_INC_ATOMIC(net, ignore);
682 return NF_ACCEPT; 685 return NF_ACCEPT;
683 } 686 }
684 687
685 /* rcu_read_lock()ed by nf_hook_slow */ 688 /* rcu_read_lock()ed by nf_hook_slow */
686 l3proto = __nf_ct_l3proto_find((u_int16_t)pf); 689 l3proto = __nf_ct_l3proto_find(pf);
687 ret = l3proto->get_l4proto(skb, skb_network_offset(skb), 690 ret = l3proto->get_l4proto(skb, skb_network_offset(skb),
688 &dataoff, &protonum); 691 &dataoff, &protonum);
689 if (ret <= 0) { 692 if (ret <= 0) {
690 pr_debug("not prepared to track yet or error occured\n"); 693 pr_debug("not prepared to track yet or error occured\n");
691 NF_CT_STAT_INC_ATOMIC(error); 694 NF_CT_STAT_INC_ATOMIC(net, error);
692 NF_CT_STAT_INC_ATOMIC(invalid); 695 NF_CT_STAT_INC_ATOMIC(net, invalid);
693 return -ret; 696 return -ret;
694 } 697 }
695 698
696 l4proto = __nf_ct_l4proto_find((u_int16_t)pf, protonum); 699 l4proto = __nf_ct_l4proto_find(pf, protonum);
697 700
698 /* It may be an special packet, error, unclean... 701 /* It may be an special packet, error, unclean...
699 * inverse of the return code tells to the netfilter 702 * inverse of the return code tells to the netfilter
700 * core what to do with the packet. */ 703 * core what to do with the packet. */
701 if (l4proto->error != NULL && 704 if (l4proto->error != NULL) {
702 (ret = l4proto->error(skb, dataoff, &ctinfo, pf, hooknum)) <= 0) { 705 ret = l4proto->error(net, skb, dataoff, &ctinfo, pf, hooknum);
703 NF_CT_STAT_INC_ATOMIC(error); 706 if (ret <= 0) {
704 NF_CT_STAT_INC_ATOMIC(invalid); 707 NF_CT_STAT_INC_ATOMIC(net, error);
705 return -ret; 708 NF_CT_STAT_INC_ATOMIC(net, invalid);
709 return -ret;
710 }
706 } 711 }
707 712
708 ct = resolve_normal_ct(skb, dataoff, pf, protonum, l3proto, l4proto, 713 ct = resolve_normal_ct(net, skb, dataoff, pf, protonum,
709 &set_reply, &ctinfo); 714 l3proto, l4proto, &set_reply, &ctinfo);
710 if (!ct) { 715 if (!ct) {
711 /* Not valid part of a connection */ 716 /* Not valid part of a connection */
712 NF_CT_STAT_INC_ATOMIC(invalid); 717 NF_CT_STAT_INC_ATOMIC(net, invalid);
713 return NF_ACCEPT; 718 return NF_ACCEPT;
714 } 719 }
715 720
716 if (IS_ERR(ct)) { 721 if (IS_ERR(ct)) {
717 /* Too stressed to deal. */ 722 /* Too stressed to deal. */
718 NF_CT_STAT_INC_ATOMIC(drop); 723 NF_CT_STAT_INC_ATOMIC(net, drop);
719 return NF_DROP; 724 return NF_DROP;
720 } 725 }
721 726
@@ -728,12 +733,12 @@ nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff *skb)
728 pr_debug("nf_conntrack_in: Can't track with proto module\n"); 733 pr_debug("nf_conntrack_in: Can't track with proto module\n");
729 nf_conntrack_put(skb->nfct); 734 nf_conntrack_put(skb->nfct);
730 skb->nfct = NULL; 735 skb->nfct = NULL;
731 NF_CT_STAT_INC_ATOMIC(invalid); 736 NF_CT_STAT_INC_ATOMIC(net, invalid);
732 return -ret; 737 return -ret;
733 } 738 }
734 739
735 if (set_reply && !test_and_set_bit(IPS_SEEN_REPLY_BIT, &ct->status)) 740 if (set_reply && !test_and_set_bit(IPS_SEEN_REPLY_BIT, &ct->status))
736 nf_conntrack_event_cache(IPCT_STATUS, skb); 741 nf_conntrack_event_cache(IPCT_STATUS, ct);
737 742
738 return ret; 743 return ret;
739} 744}
@@ -846,7 +851,7 @@ acct:
846 851
847 /* must be unlocked when calling event cache */ 852 /* must be unlocked when calling event cache */
848 if (event) 853 if (event)
849 nf_conntrack_event_cache(event, skb); 854 nf_conntrack_event_cache(event, ct);
850} 855}
851EXPORT_SYMBOL_GPL(__nf_ct_refresh_acct); 856EXPORT_SYMBOL_GPL(__nf_ct_refresh_acct);
852 857
@@ -938,7 +943,7 @@ static void nf_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb)
938 943
939/* Bring out ya dead! */ 944/* Bring out ya dead! */
940static struct nf_conn * 945static struct nf_conn *
941get_next_corpse(int (*iter)(struct nf_conn *i, void *data), 946get_next_corpse(struct net *net, int (*iter)(struct nf_conn *i, void *data),
942 void *data, unsigned int *bucket) 947 void *data, unsigned int *bucket)
943{ 948{
944 struct nf_conntrack_tuple_hash *h; 949 struct nf_conntrack_tuple_hash *h;
@@ -947,13 +952,13 @@ get_next_corpse(int (*iter)(struct nf_conn *i, void *data),
947 952
948 spin_lock_bh(&nf_conntrack_lock); 953 spin_lock_bh(&nf_conntrack_lock);
949 for (; *bucket < nf_conntrack_htable_size; (*bucket)++) { 954 for (; *bucket < nf_conntrack_htable_size; (*bucket)++) {
950 hlist_for_each_entry(h, n, &nf_conntrack_hash[*bucket], hnode) { 955 hlist_for_each_entry(h, n, &net->ct.hash[*bucket], hnode) {
951 ct = nf_ct_tuplehash_to_ctrack(h); 956 ct = nf_ct_tuplehash_to_ctrack(h);
952 if (iter(ct, data)) 957 if (iter(ct, data))
953 goto found; 958 goto found;
954 } 959 }
955 } 960 }
956 hlist_for_each_entry(h, n, &unconfirmed, hnode) { 961 hlist_for_each_entry(h, n, &net->ct.unconfirmed, hnode) {
957 ct = nf_ct_tuplehash_to_ctrack(h); 962 ct = nf_ct_tuplehash_to_ctrack(h);
958 if (iter(ct, data)) 963 if (iter(ct, data))
959 set_bit(IPS_DYING_BIT, &ct->status); 964 set_bit(IPS_DYING_BIT, &ct->status);
@@ -966,13 +971,14 @@ found:
966 return ct; 971 return ct;
967} 972}
968 973
969void 974void nf_ct_iterate_cleanup(struct net *net,
970nf_ct_iterate_cleanup(int (*iter)(struct nf_conn *i, void *data), void *data) 975 int (*iter)(struct nf_conn *i, void *data),
976 void *data)
971{ 977{
972 struct nf_conn *ct; 978 struct nf_conn *ct;
973 unsigned int bucket = 0; 979 unsigned int bucket = 0;
974 980
975 while ((ct = get_next_corpse(iter, data, &bucket)) != NULL) { 981 while ((ct = get_next_corpse(net, iter, data, &bucket)) != NULL) {
976 /* Time to push up daises... */ 982 /* Time to push up daises... */
977 if (del_timer(&ct->timeout)) 983 if (del_timer(&ct->timeout))
978 death_by_timeout((unsigned long)ct); 984 death_by_timeout((unsigned long)ct);
@@ -998,27 +1004,26 @@ void nf_ct_free_hashtable(struct hlist_head *hash, int vmalloced, unsigned int s
998} 1004}
999EXPORT_SYMBOL_GPL(nf_ct_free_hashtable); 1005EXPORT_SYMBOL_GPL(nf_ct_free_hashtable);
1000 1006
1001void nf_conntrack_flush(void) 1007void nf_conntrack_flush(struct net *net)
1002{ 1008{
1003 nf_ct_iterate_cleanup(kill_all, NULL); 1009 nf_ct_iterate_cleanup(net, kill_all, NULL);
1004} 1010}
1005EXPORT_SYMBOL_GPL(nf_conntrack_flush); 1011EXPORT_SYMBOL_GPL(nf_conntrack_flush);
1006 1012
1007/* Mishearing the voices in his head, our hero wonders how he's 1013static void nf_conntrack_cleanup_init_net(void)
1008 supposed to kill the mall. */
1009void nf_conntrack_cleanup(void)
1010{ 1014{
1011 rcu_assign_pointer(ip_ct_attach, NULL); 1015 nf_conntrack_helper_fini();
1012 1016 nf_conntrack_proto_fini();
1013 /* This makes sure all current packets have passed through 1017 kmem_cache_destroy(nf_conntrack_cachep);
1014 netfilter framework. Roll on, two-stage module 1018}
1015 delete... */
1016 synchronize_net();
1017 1019
1018 nf_ct_event_cache_flush(); 1020static void nf_conntrack_cleanup_net(struct net *net)
1021{
1022 nf_ct_event_cache_flush(net);
1023 nf_conntrack_ecache_fini(net);
1019 i_see_dead_people: 1024 i_see_dead_people:
1020 nf_conntrack_flush(); 1025 nf_conntrack_flush(net);
1021 if (atomic_read(&nf_conntrack_count) != 0) { 1026 if (atomic_read(&net->ct.count) != 0) {
1022 schedule(); 1027 schedule();
1023 goto i_see_dead_people; 1028 goto i_see_dead_people;
1024 } 1029 }
@@ -1026,16 +1031,31 @@ void nf_conntrack_cleanup(void)
1026 while (atomic_read(&nf_conntrack_untracked.ct_general.use) > 1) 1031 while (atomic_read(&nf_conntrack_untracked.ct_general.use) > 1)
1027 schedule(); 1032 schedule();
1028 1033
1029 rcu_assign_pointer(nf_ct_destroy, NULL); 1034 nf_ct_free_hashtable(net->ct.hash, net->ct.hash_vmalloc,
1030
1031 kmem_cache_destroy(nf_conntrack_cachep);
1032 nf_ct_free_hashtable(nf_conntrack_hash, nf_conntrack_vmalloc,
1033 nf_conntrack_htable_size); 1035 nf_conntrack_htable_size);
1036 nf_conntrack_acct_fini(net);
1037 nf_conntrack_expect_fini(net);
1038 free_percpu(net->ct.stat);
1039}
1034 1040
1035 nf_conntrack_acct_fini(); 1041/* Mishearing the voices in his head, our hero wonders how he's
1036 nf_conntrack_expect_fini(); 1042 supposed to kill the mall. */
1037 nf_conntrack_helper_fini(); 1043void nf_conntrack_cleanup(struct net *net)
1038 nf_conntrack_proto_fini(); 1044{
1045 if (net_eq(net, &init_net))
1046 rcu_assign_pointer(ip_ct_attach, NULL);
1047
1048 /* This makes sure all current packets have passed through
1049 netfilter framework. Roll on, two-stage module
1050 delete... */
1051 synchronize_net();
1052
1053 nf_conntrack_cleanup_net(net);
1054
1055 if (net_eq(net, &init_net)) {
1056 rcu_assign_pointer(nf_ct_destroy, NULL);
1057 nf_conntrack_cleanup_init_net();
1058 }
1039} 1059}
1040 1060
1041struct hlist_head *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced) 1061struct hlist_head *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced)
@@ -1094,8 +1114,8 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
1094 */ 1114 */
1095 spin_lock_bh(&nf_conntrack_lock); 1115 spin_lock_bh(&nf_conntrack_lock);
1096 for (i = 0; i < nf_conntrack_htable_size; i++) { 1116 for (i = 0; i < nf_conntrack_htable_size; i++) {
1097 while (!hlist_empty(&nf_conntrack_hash[i])) { 1117 while (!hlist_empty(&init_net.ct.hash[i])) {
1098 h = hlist_entry(nf_conntrack_hash[i].first, 1118 h = hlist_entry(init_net.ct.hash[i].first,
1099 struct nf_conntrack_tuple_hash, hnode); 1119 struct nf_conntrack_tuple_hash, hnode);
1100 hlist_del_rcu(&h->hnode); 1120 hlist_del_rcu(&h->hnode);
1101 bucket = __hash_conntrack(&h->tuple, hashsize, rnd); 1121 bucket = __hash_conntrack(&h->tuple, hashsize, rnd);
@@ -1103,12 +1123,12 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
1103 } 1123 }
1104 } 1124 }
1105 old_size = nf_conntrack_htable_size; 1125 old_size = nf_conntrack_htable_size;
1106 old_vmalloced = nf_conntrack_vmalloc; 1126 old_vmalloced = init_net.ct.hash_vmalloc;
1107 old_hash = nf_conntrack_hash; 1127 old_hash = init_net.ct.hash;
1108 1128
1109 nf_conntrack_htable_size = hashsize; 1129 nf_conntrack_htable_size = hashsize;
1110 nf_conntrack_vmalloc = vmalloced; 1130 init_net.ct.hash_vmalloc = vmalloced;
1111 nf_conntrack_hash = hash; 1131 init_net.ct.hash = hash;
1112 nf_conntrack_hash_rnd = rnd; 1132 nf_conntrack_hash_rnd = rnd;
1113 spin_unlock_bh(&nf_conntrack_lock); 1133 spin_unlock_bh(&nf_conntrack_lock);
1114 1134
@@ -1120,7 +1140,7 @@ EXPORT_SYMBOL_GPL(nf_conntrack_set_hashsize);
1120module_param_call(hashsize, nf_conntrack_set_hashsize, param_get_uint, 1140module_param_call(hashsize, nf_conntrack_set_hashsize, param_get_uint,
1121 &nf_conntrack_htable_size, 0600); 1141 &nf_conntrack_htable_size, 0600);
1122 1142
1123int __init nf_conntrack_init(void) 1143static int nf_conntrack_init_init_net(void)
1124{ 1144{
1125 int max_factor = 8; 1145 int max_factor = 8;
1126 int ret; 1146 int ret;
@@ -1142,13 +1162,6 @@ int __init nf_conntrack_init(void)
1142 * entries. */ 1162 * entries. */
1143 max_factor = 4; 1163 max_factor = 4;
1144 } 1164 }
1145 nf_conntrack_hash = nf_ct_alloc_hashtable(&nf_conntrack_htable_size,
1146 &nf_conntrack_vmalloc);
1147 if (!nf_conntrack_hash) {
1148 printk(KERN_ERR "Unable to create nf_conntrack_hash\n");
1149 goto err_out;
1150 }
1151
1152 nf_conntrack_max = max_factor * nf_conntrack_htable_size; 1165 nf_conntrack_max = max_factor * nf_conntrack_htable_size;
1153 1166
1154 printk("nf_conntrack version %s (%u buckets, %d max)\n", 1167 printk("nf_conntrack version %s (%u buckets, %d max)\n",
@@ -1160,48 +1173,103 @@ int __init nf_conntrack_init(void)
1160 0, 0, NULL); 1173 0, 0, NULL);
1161 if (!nf_conntrack_cachep) { 1174 if (!nf_conntrack_cachep) {
1162 printk(KERN_ERR "Unable to create nf_conn slab cache\n"); 1175 printk(KERN_ERR "Unable to create nf_conn slab cache\n");
1163 goto err_free_hash; 1176 ret = -ENOMEM;
1177 goto err_cache;
1164 } 1178 }
1165 1179
1166 ret = nf_conntrack_proto_init(); 1180 ret = nf_conntrack_proto_init();
1167 if (ret < 0) 1181 if (ret < 0)
1168 goto err_free_conntrack_slab; 1182 goto err_proto;
1169
1170 ret = nf_conntrack_expect_init();
1171 if (ret < 0)
1172 goto out_fini_proto;
1173 1183
1174 ret = nf_conntrack_helper_init(); 1184 ret = nf_conntrack_helper_init();
1175 if (ret < 0) 1185 if (ret < 0)
1176 goto out_fini_expect; 1186 goto err_helper;
1177 1187
1178 ret = nf_conntrack_acct_init(); 1188 return 0;
1179 if (ret < 0)
1180 goto out_fini_helper;
1181 1189
1182 /* For use by REJECT target */ 1190err_helper:
1183 rcu_assign_pointer(ip_ct_attach, nf_conntrack_attach); 1191 nf_conntrack_proto_fini();
1184 rcu_assign_pointer(nf_ct_destroy, destroy_conntrack); 1192err_proto:
1193 kmem_cache_destroy(nf_conntrack_cachep);
1194err_cache:
1195 return ret;
1196}
1197
1198static int nf_conntrack_init_net(struct net *net)
1199{
1200 int ret;
1201
1202 atomic_set(&net->ct.count, 0);
1203 INIT_HLIST_HEAD(&net->ct.unconfirmed);
1204 net->ct.stat = alloc_percpu(struct ip_conntrack_stat);
1205 if (!net->ct.stat) {
1206 ret = -ENOMEM;
1207 goto err_stat;
1208 }
1209 ret = nf_conntrack_ecache_init(net);
1210 if (ret < 0)
1211 goto err_ecache;
1212 net->ct.hash = nf_ct_alloc_hashtable(&nf_conntrack_htable_size,
1213 &net->ct.hash_vmalloc);
1214 if (!net->ct.hash) {
1215 ret = -ENOMEM;
1216 printk(KERN_ERR "Unable to create nf_conntrack_hash\n");
1217 goto err_hash;
1218 }
1219 ret = nf_conntrack_expect_init(net);
1220 if (ret < 0)
1221 goto err_expect;
1222 ret = nf_conntrack_acct_init(net);
1223 if (ret < 0)
1224 goto err_acct;
1185 1225
1186 /* Set up fake conntrack: 1226 /* Set up fake conntrack:
1187 - to never be deleted, not in any hashes */ 1227 - to never be deleted, not in any hashes */
1228#ifdef CONFIG_NET_NS
1229 nf_conntrack_untracked.ct_net = &init_net;
1230#endif
1188 atomic_set(&nf_conntrack_untracked.ct_general.use, 1); 1231 atomic_set(&nf_conntrack_untracked.ct_general.use, 1);
1189 /* - and look it like as a confirmed connection */ 1232 /* - and look it like as a confirmed connection */
1190 set_bit(IPS_CONFIRMED_BIT, &nf_conntrack_untracked.status); 1233 set_bit(IPS_CONFIRMED_BIT, &nf_conntrack_untracked.status);
1191 1234
1192 return ret; 1235 return 0;
1193 1236
1194out_fini_helper: 1237err_acct:
1195 nf_conntrack_helper_fini(); 1238 nf_conntrack_expect_fini(net);
1196out_fini_expect: 1239err_expect:
1197 nf_conntrack_expect_fini(); 1240 nf_ct_free_hashtable(net->ct.hash, net->ct.hash_vmalloc,
1198out_fini_proto:
1199 nf_conntrack_proto_fini();
1200err_free_conntrack_slab:
1201 kmem_cache_destroy(nf_conntrack_cachep);
1202err_free_hash:
1203 nf_ct_free_hashtable(nf_conntrack_hash, nf_conntrack_vmalloc,
1204 nf_conntrack_htable_size); 1241 nf_conntrack_htable_size);
1205err_out: 1242err_hash:
1206 return -ENOMEM; 1243 nf_conntrack_ecache_fini(net);
1244err_ecache:
1245 free_percpu(net->ct.stat);
1246err_stat:
1247 return ret;
1248}
1249
1250int nf_conntrack_init(struct net *net)
1251{
1252 int ret;
1253
1254 if (net_eq(net, &init_net)) {
1255 ret = nf_conntrack_init_init_net();
1256 if (ret < 0)
1257 goto out_init_net;
1258 }
1259 ret = nf_conntrack_init_net(net);
1260 if (ret < 0)
1261 goto out_net;
1262
1263 if (net_eq(net, &init_net)) {
1264 /* For use by REJECT target */
1265 rcu_assign_pointer(ip_ct_attach, nf_conntrack_attach);
1266 rcu_assign_pointer(nf_ct_destroy, destroy_conntrack);
1267 }
1268 return 0;
1269
1270out_net:
1271 if (net_eq(net, &init_net))
1272 nf_conntrack_cleanup_init_net();
1273out_init_net:
1274 return ret;
1207} 1275}
diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c
index 83c41ac3505b..a5f5e2e65d13 100644
--- a/net/netfilter/nf_conntrack_ecache.c
+++ b/net/netfilter/nf_conntrack_ecache.c
@@ -29,9 +29,6 @@ EXPORT_SYMBOL_GPL(nf_conntrack_chain);
29ATOMIC_NOTIFIER_HEAD(nf_ct_expect_chain); 29ATOMIC_NOTIFIER_HEAD(nf_ct_expect_chain);
30EXPORT_SYMBOL_GPL(nf_ct_expect_chain); 30EXPORT_SYMBOL_GPL(nf_ct_expect_chain);
31 31
32DEFINE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache);
33EXPORT_PER_CPU_SYMBOL_GPL(nf_conntrack_ecache);
34
35/* deliver cached events and clear cache entry - must be called with locally 32/* deliver cached events and clear cache entry - must be called with locally
36 * disabled softirqs */ 33 * disabled softirqs */
37static inline void 34static inline void
@@ -51,10 +48,11 @@ __nf_ct_deliver_cached_events(struct nf_conntrack_ecache *ecache)
51 * by code prior to async packet handling for freeing the skb */ 48 * by code prior to async packet handling for freeing the skb */
52void nf_ct_deliver_cached_events(const struct nf_conn *ct) 49void nf_ct_deliver_cached_events(const struct nf_conn *ct)
53{ 50{
51 struct net *net = nf_ct_net(ct);
54 struct nf_conntrack_ecache *ecache; 52 struct nf_conntrack_ecache *ecache;
55 53
56 local_bh_disable(); 54 local_bh_disable();
57 ecache = &__get_cpu_var(nf_conntrack_ecache); 55 ecache = per_cpu_ptr(net->ct.ecache, raw_smp_processor_id());
58 if (ecache->ct == ct) 56 if (ecache->ct == ct)
59 __nf_ct_deliver_cached_events(ecache); 57 __nf_ct_deliver_cached_events(ecache);
60 local_bh_enable(); 58 local_bh_enable();
@@ -64,10 +62,11 @@ EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
64/* Deliver cached events for old pending events, if current conntrack != old */ 62/* Deliver cached events for old pending events, if current conntrack != old */
65void __nf_ct_event_cache_init(struct nf_conn *ct) 63void __nf_ct_event_cache_init(struct nf_conn *ct)
66{ 64{
65 struct net *net = nf_ct_net(ct);
67 struct nf_conntrack_ecache *ecache; 66 struct nf_conntrack_ecache *ecache;
68 67
69 /* take care of delivering potentially old events */ 68 /* take care of delivering potentially old events */
70 ecache = &__get_cpu_var(nf_conntrack_ecache); 69 ecache = per_cpu_ptr(net->ct.ecache, raw_smp_processor_id());
71 BUG_ON(ecache->ct == ct); 70 BUG_ON(ecache->ct == ct);
72 if (ecache->ct) 71 if (ecache->ct)
73 __nf_ct_deliver_cached_events(ecache); 72 __nf_ct_deliver_cached_events(ecache);
@@ -79,18 +78,31 @@ EXPORT_SYMBOL_GPL(__nf_ct_event_cache_init);
79 78
80/* flush the event cache - touches other CPU's data and must not be called 79/* flush the event cache - touches other CPU's data and must not be called
81 * while packets are still passing through the code */ 80 * while packets are still passing through the code */
82void nf_ct_event_cache_flush(void) 81void nf_ct_event_cache_flush(struct net *net)
83{ 82{
84 struct nf_conntrack_ecache *ecache; 83 struct nf_conntrack_ecache *ecache;
85 int cpu; 84 int cpu;
86 85
87 for_each_possible_cpu(cpu) { 86 for_each_possible_cpu(cpu) {
88 ecache = &per_cpu(nf_conntrack_ecache, cpu); 87 ecache = per_cpu_ptr(net->ct.ecache, cpu);
89 if (ecache->ct) 88 if (ecache->ct)
90 nf_ct_put(ecache->ct); 89 nf_ct_put(ecache->ct);
91 } 90 }
92} 91}
93 92
93int nf_conntrack_ecache_init(struct net *net)
94{
95 net->ct.ecache = alloc_percpu(struct nf_conntrack_ecache);
96 if (!net->ct.ecache)
97 return -ENOMEM;
98 return 0;
99}
100
101void nf_conntrack_ecache_fini(struct net *net)
102{
103 free_percpu(net->ct.ecache);
104}
105
94int nf_conntrack_register_notifier(struct notifier_block *nb) 106int nf_conntrack_register_notifier(struct notifier_block *nb)
95{ 107{
96 return atomic_notifier_chain_register(&nf_conntrack_chain, nb); 108 return atomic_notifier_chain_register(&nf_conntrack_chain, nb);
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index e8f0dead267f..37a703bc3b8e 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -28,17 +28,12 @@
28#include <net/netfilter/nf_conntrack_helper.h> 28#include <net/netfilter/nf_conntrack_helper.h>
29#include <net/netfilter/nf_conntrack_tuple.h> 29#include <net/netfilter/nf_conntrack_tuple.h>
30 30
31struct hlist_head *nf_ct_expect_hash __read_mostly;
32EXPORT_SYMBOL_GPL(nf_ct_expect_hash);
33
34unsigned int nf_ct_expect_hsize __read_mostly; 31unsigned int nf_ct_expect_hsize __read_mostly;
35EXPORT_SYMBOL_GPL(nf_ct_expect_hsize); 32EXPORT_SYMBOL_GPL(nf_ct_expect_hsize);
36 33
37static unsigned int nf_ct_expect_hash_rnd __read_mostly; 34static unsigned int nf_ct_expect_hash_rnd __read_mostly;
38static unsigned int nf_ct_expect_count;
39unsigned int nf_ct_expect_max __read_mostly; 35unsigned int nf_ct_expect_max __read_mostly;
40static int nf_ct_expect_hash_rnd_initted __read_mostly; 36static int nf_ct_expect_hash_rnd_initted __read_mostly;
41static int nf_ct_expect_vmalloc;
42 37
43static struct kmem_cache *nf_ct_expect_cachep __read_mostly; 38static struct kmem_cache *nf_ct_expect_cachep __read_mostly;
44 39
@@ -46,18 +41,19 @@ static struct kmem_cache *nf_ct_expect_cachep __read_mostly;
46void nf_ct_unlink_expect(struct nf_conntrack_expect *exp) 41void nf_ct_unlink_expect(struct nf_conntrack_expect *exp)
47{ 42{
48 struct nf_conn_help *master_help = nfct_help(exp->master); 43 struct nf_conn_help *master_help = nfct_help(exp->master);
44 struct net *net = nf_ct_exp_net(exp);
49 45
50 NF_CT_ASSERT(master_help); 46 NF_CT_ASSERT(master_help);
51 NF_CT_ASSERT(!timer_pending(&exp->timeout)); 47 NF_CT_ASSERT(!timer_pending(&exp->timeout));
52 48
53 hlist_del_rcu(&exp->hnode); 49 hlist_del_rcu(&exp->hnode);
54 nf_ct_expect_count--; 50 net->ct.expect_count--;
55 51
56 hlist_del(&exp->lnode); 52 hlist_del(&exp->lnode);
57 master_help->expecting[exp->class]--; 53 master_help->expecting[exp->class]--;
58 nf_ct_expect_put(exp); 54 nf_ct_expect_put(exp);
59 55
60 NF_CT_STAT_INC(expect_delete); 56 NF_CT_STAT_INC(net, expect_delete);
61} 57}
62EXPORT_SYMBOL_GPL(nf_ct_unlink_expect); 58EXPORT_SYMBOL_GPL(nf_ct_unlink_expect);
63 59
@@ -87,17 +83,17 @@ static unsigned int nf_ct_expect_dst_hash(const struct nf_conntrack_tuple *tuple
87} 83}
88 84
89struct nf_conntrack_expect * 85struct nf_conntrack_expect *
90__nf_ct_expect_find(const struct nf_conntrack_tuple *tuple) 86__nf_ct_expect_find(struct net *net, const struct nf_conntrack_tuple *tuple)
91{ 87{
92 struct nf_conntrack_expect *i; 88 struct nf_conntrack_expect *i;
93 struct hlist_node *n; 89 struct hlist_node *n;
94 unsigned int h; 90 unsigned int h;
95 91
96 if (!nf_ct_expect_count) 92 if (!net->ct.expect_count)
97 return NULL; 93 return NULL;
98 94
99 h = nf_ct_expect_dst_hash(tuple); 95 h = nf_ct_expect_dst_hash(tuple);
100 hlist_for_each_entry_rcu(i, n, &nf_ct_expect_hash[h], hnode) { 96 hlist_for_each_entry_rcu(i, n, &net->ct.expect_hash[h], hnode) {
101 if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)) 97 if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask))
102 return i; 98 return i;
103 } 99 }
@@ -107,12 +103,12 @@ EXPORT_SYMBOL_GPL(__nf_ct_expect_find);
107 103
108/* Just find a expectation corresponding to a tuple. */ 104/* Just find a expectation corresponding to a tuple. */
109struct nf_conntrack_expect * 105struct nf_conntrack_expect *
110nf_ct_expect_find_get(const struct nf_conntrack_tuple *tuple) 106nf_ct_expect_find_get(struct net *net, const struct nf_conntrack_tuple *tuple)
111{ 107{
112 struct nf_conntrack_expect *i; 108 struct nf_conntrack_expect *i;
113 109
114 rcu_read_lock(); 110 rcu_read_lock();
115 i = __nf_ct_expect_find(tuple); 111 i = __nf_ct_expect_find(net, tuple);
116 if (i && !atomic_inc_not_zero(&i->use)) 112 if (i && !atomic_inc_not_zero(&i->use))
117 i = NULL; 113 i = NULL;
118 rcu_read_unlock(); 114 rcu_read_unlock();
@@ -124,17 +120,17 @@ EXPORT_SYMBOL_GPL(nf_ct_expect_find_get);
124/* If an expectation for this connection is found, it gets delete from 120/* If an expectation for this connection is found, it gets delete from
125 * global list then returned. */ 121 * global list then returned. */
126struct nf_conntrack_expect * 122struct nf_conntrack_expect *
127nf_ct_find_expectation(const struct nf_conntrack_tuple *tuple) 123nf_ct_find_expectation(struct net *net, const struct nf_conntrack_tuple *tuple)
128{ 124{
129 struct nf_conntrack_expect *i, *exp = NULL; 125 struct nf_conntrack_expect *i, *exp = NULL;
130 struct hlist_node *n; 126 struct hlist_node *n;
131 unsigned int h; 127 unsigned int h;
132 128
133 if (!nf_ct_expect_count) 129 if (!net->ct.expect_count)
134 return NULL; 130 return NULL;
135 131
136 h = nf_ct_expect_dst_hash(tuple); 132 h = nf_ct_expect_dst_hash(tuple);
137 hlist_for_each_entry(i, n, &nf_ct_expect_hash[h], hnode) { 133 hlist_for_each_entry(i, n, &net->ct.expect_hash[h], hnode) {
138 if (!(i->flags & NF_CT_EXPECT_INACTIVE) && 134 if (!(i->flags & NF_CT_EXPECT_INACTIVE) &&
139 nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)) { 135 nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)) {
140 exp = i; 136 exp = i;
@@ -241,7 +237,7 @@ struct nf_conntrack_expect *nf_ct_expect_alloc(struct nf_conn *me)
241EXPORT_SYMBOL_GPL(nf_ct_expect_alloc); 237EXPORT_SYMBOL_GPL(nf_ct_expect_alloc);
242 238
243void nf_ct_expect_init(struct nf_conntrack_expect *exp, unsigned int class, 239void nf_ct_expect_init(struct nf_conntrack_expect *exp, unsigned int class,
244 int family, 240 u_int8_t family,
245 const union nf_inet_addr *saddr, 241 const union nf_inet_addr *saddr,
246 const union nf_inet_addr *daddr, 242 const union nf_inet_addr *daddr,
247 u_int8_t proto, const __be16 *src, const __be16 *dst) 243 u_int8_t proto, const __be16 *src, const __be16 *dst)
@@ -311,6 +307,7 @@ EXPORT_SYMBOL_GPL(nf_ct_expect_put);
311static void nf_ct_expect_insert(struct nf_conntrack_expect *exp) 307static void nf_ct_expect_insert(struct nf_conntrack_expect *exp)
312{ 308{
313 struct nf_conn_help *master_help = nfct_help(exp->master); 309 struct nf_conn_help *master_help = nfct_help(exp->master);
310 struct net *net = nf_ct_exp_net(exp);
314 const struct nf_conntrack_expect_policy *p; 311 const struct nf_conntrack_expect_policy *p;
315 unsigned int h = nf_ct_expect_dst_hash(&exp->tuple); 312 unsigned int h = nf_ct_expect_dst_hash(&exp->tuple);
316 313
@@ -319,8 +316,8 @@ static void nf_ct_expect_insert(struct nf_conntrack_expect *exp)
319 hlist_add_head(&exp->lnode, &master_help->expectations); 316 hlist_add_head(&exp->lnode, &master_help->expectations);
320 master_help->expecting[exp->class]++; 317 master_help->expecting[exp->class]++;
321 318
322 hlist_add_head_rcu(&exp->hnode, &nf_ct_expect_hash[h]); 319 hlist_add_head_rcu(&exp->hnode, &net->ct.expect_hash[h]);
323 nf_ct_expect_count++; 320 net->ct.expect_count++;
324 321
325 setup_timer(&exp->timeout, nf_ct_expectation_timed_out, 322 setup_timer(&exp->timeout, nf_ct_expectation_timed_out,
326 (unsigned long)exp); 323 (unsigned long)exp);
@@ -329,7 +326,7 @@ static void nf_ct_expect_insert(struct nf_conntrack_expect *exp)
329 add_timer(&exp->timeout); 326 add_timer(&exp->timeout);
330 327
331 atomic_inc(&exp->use); 328 atomic_inc(&exp->use);
332 NF_CT_STAT_INC(expect_create); 329 NF_CT_STAT_INC(net, expect_create);
333} 330}
334 331
335/* Race with expectations being used means we could have none to find; OK. */ 332/* Race with expectations being used means we could have none to find; OK. */
@@ -371,6 +368,7 @@ int nf_ct_expect_related(struct nf_conntrack_expect *expect)
371 struct nf_conntrack_expect *i; 368 struct nf_conntrack_expect *i;
372 struct nf_conn *master = expect->master; 369 struct nf_conn *master = expect->master;
373 struct nf_conn_help *master_help = nfct_help(master); 370 struct nf_conn_help *master_help = nfct_help(master);
371 struct net *net = nf_ct_exp_net(expect);
374 struct hlist_node *n; 372 struct hlist_node *n;
375 unsigned int h; 373 unsigned int h;
376 int ret; 374 int ret;
@@ -383,7 +381,7 @@ int nf_ct_expect_related(struct nf_conntrack_expect *expect)
383 goto out; 381 goto out;
384 } 382 }
385 h = nf_ct_expect_dst_hash(&expect->tuple); 383 h = nf_ct_expect_dst_hash(&expect->tuple);
386 hlist_for_each_entry(i, n, &nf_ct_expect_hash[h], hnode) { 384 hlist_for_each_entry(i, n, &net->ct.expect_hash[h], hnode) {
387 if (expect_matches(i, expect)) { 385 if (expect_matches(i, expect)) {
388 /* Refresh timer: if it's dying, ignore.. */ 386 /* Refresh timer: if it's dying, ignore.. */
389 if (refresh_timer(i)) { 387 if (refresh_timer(i)) {
@@ -406,7 +404,7 @@ int nf_ct_expect_related(struct nf_conntrack_expect *expect)
406 } 404 }
407 } 405 }
408 406
409 if (nf_ct_expect_count >= nf_ct_expect_max) { 407 if (net->ct.expect_count >= nf_ct_expect_max) {
410 if (net_ratelimit()) 408 if (net_ratelimit())
411 printk(KERN_WARNING 409 printk(KERN_WARNING
412 "nf_conntrack: expectation table full\n"); 410 "nf_conntrack: expectation table full\n");
@@ -425,16 +423,18 @@ EXPORT_SYMBOL_GPL(nf_ct_expect_related);
425 423
426#ifdef CONFIG_PROC_FS 424#ifdef CONFIG_PROC_FS
427struct ct_expect_iter_state { 425struct ct_expect_iter_state {
426 struct seq_net_private p;
428 unsigned int bucket; 427 unsigned int bucket;
429}; 428};
430 429
431static struct hlist_node *ct_expect_get_first(struct seq_file *seq) 430static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
432{ 431{
432 struct net *net = seq_file_net(seq);
433 struct ct_expect_iter_state *st = seq->private; 433 struct ct_expect_iter_state *st = seq->private;
434 struct hlist_node *n; 434 struct hlist_node *n;
435 435
436 for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) { 436 for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) {
437 n = rcu_dereference(nf_ct_expect_hash[st->bucket].first); 437 n = rcu_dereference(net->ct.expect_hash[st->bucket].first);
438 if (n) 438 if (n)
439 return n; 439 return n;
440 } 440 }
@@ -444,13 +444,14 @@ static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
444static struct hlist_node *ct_expect_get_next(struct seq_file *seq, 444static struct hlist_node *ct_expect_get_next(struct seq_file *seq,
445 struct hlist_node *head) 445 struct hlist_node *head)
446{ 446{
447 struct net *net = seq_file_net(seq);
447 struct ct_expect_iter_state *st = seq->private; 448 struct ct_expect_iter_state *st = seq->private;
448 449
449 head = rcu_dereference(head->next); 450 head = rcu_dereference(head->next);
450 while (head == NULL) { 451 while (head == NULL) {
451 if (++st->bucket >= nf_ct_expect_hsize) 452 if (++st->bucket >= nf_ct_expect_hsize)
452 return NULL; 453 return NULL;
453 head = rcu_dereference(nf_ct_expect_hash[st->bucket].first); 454 head = rcu_dereference(net->ct.expect_hash[st->bucket].first);
454 } 455 }
455 return head; 456 return head;
456} 457}
@@ -524,7 +525,7 @@ static const struct seq_operations exp_seq_ops = {
524 525
525static int exp_open(struct inode *inode, struct file *file) 526static int exp_open(struct inode *inode, struct file *file)
526{ 527{
527 return seq_open_private(file, &exp_seq_ops, 528 return seq_open_net(inode, file, &exp_seq_ops,
528 sizeof(struct ct_expect_iter_state)); 529 sizeof(struct ct_expect_iter_state));
529} 530}
530 531
@@ -533,72 +534,79 @@ static const struct file_operations exp_file_ops = {
533 .open = exp_open, 534 .open = exp_open,
534 .read = seq_read, 535 .read = seq_read,
535 .llseek = seq_lseek, 536 .llseek = seq_lseek,
536 .release = seq_release_private, 537 .release = seq_release_net,
537}; 538};
538#endif /* CONFIG_PROC_FS */ 539#endif /* CONFIG_PROC_FS */
539 540
540static int __init exp_proc_init(void) 541static int exp_proc_init(struct net *net)
541{ 542{
542#ifdef CONFIG_PROC_FS 543#ifdef CONFIG_PROC_FS
543 struct proc_dir_entry *proc; 544 struct proc_dir_entry *proc;
544 545
545 proc = proc_net_fops_create(&init_net, "nf_conntrack_expect", 0440, &exp_file_ops); 546 proc = proc_net_fops_create(net, "nf_conntrack_expect", 0440, &exp_file_ops);
546 if (!proc) 547 if (!proc)
547 return -ENOMEM; 548 return -ENOMEM;
548#endif /* CONFIG_PROC_FS */ 549#endif /* CONFIG_PROC_FS */
549 return 0; 550 return 0;
550} 551}
551 552
552static void exp_proc_remove(void) 553static void exp_proc_remove(struct net *net)
553{ 554{
554#ifdef CONFIG_PROC_FS 555#ifdef CONFIG_PROC_FS
555 proc_net_remove(&init_net, "nf_conntrack_expect"); 556 proc_net_remove(net, "nf_conntrack_expect");
556#endif /* CONFIG_PROC_FS */ 557#endif /* CONFIG_PROC_FS */
557} 558}
558 559
559module_param_named(expect_hashsize, nf_ct_expect_hsize, uint, 0600); 560module_param_named(expect_hashsize, nf_ct_expect_hsize, uint, 0600);
560 561
561int __init nf_conntrack_expect_init(void) 562int nf_conntrack_expect_init(struct net *net)
562{ 563{
563 int err = -ENOMEM; 564 int err = -ENOMEM;
564 565
565 if (!nf_ct_expect_hsize) { 566 if (net_eq(net, &init_net)) {
566 nf_ct_expect_hsize = nf_conntrack_htable_size / 256; 567 if (!nf_ct_expect_hsize) {
567 if (!nf_ct_expect_hsize) 568 nf_ct_expect_hsize = nf_conntrack_htable_size / 256;
568 nf_ct_expect_hsize = 1; 569 if (!nf_ct_expect_hsize)
570 nf_ct_expect_hsize = 1;
571 }
572 nf_ct_expect_max = nf_ct_expect_hsize * 4;
569 } 573 }
570 nf_ct_expect_max = nf_ct_expect_hsize * 4;
571 574
572 nf_ct_expect_hash = nf_ct_alloc_hashtable(&nf_ct_expect_hsize, 575 net->ct.expect_count = 0;
573 &nf_ct_expect_vmalloc); 576 net->ct.expect_hash = nf_ct_alloc_hashtable(&nf_ct_expect_hsize,
574 if (nf_ct_expect_hash == NULL) 577 &net->ct.expect_vmalloc);
578 if (net->ct.expect_hash == NULL)
575 goto err1; 579 goto err1;
576 580
577 nf_ct_expect_cachep = kmem_cache_create("nf_conntrack_expect", 581 if (net_eq(net, &init_net)) {
582 nf_ct_expect_cachep = kmem_cache_create("nf_conntrack_expect",
578 sizeof(struct nf_conntrack_expect), 583 sizeof(struct nf_conntrack_expect),
579 0, 0, NULL); 584 0, 0, NULL);
580 if (!nf_ct_expect_cachep) 585 if (!nf_ct_expect_cachep)
581 goto err2; 586 goto err2;
587 }
582 588
583 err = exp_proc_init(); 589 err = exp_proc_init(net);
584 if (err < 0) 590 if (err < 0)
585 goto err3; 591 goto err3;
586 592
587 return 0; 593 return 0;
588 594
589err3: 595err3:
590 kmem_cache_destroy(nf_ct_expect_cachep); 596 if (net_eq(net, &init_net))
597 kmem_cache_destroy(nf_ct_expect_cachep);
591err2: 598err2:
592 nf_ct_free_hashtable(nf_ct_expect_hash, nf_ct_expect_vmalloc, 599 nf_ct_free_hashtable(net->ct.expect_hash, net->ct.expect_vmalloc,
593 nf_ct_expect_hsize); 600 nf_ct_expect_hsize);
594err1: 601err1:
595 return err; 602 return err;
596} 603}
597 604
598void nf_conntrack_expect_fini(void) 605void nf_conntrack_expect_fini(struct net *net)
599{ 606{
600 exp_proc_remove(); 607 exp_proc_remove(net);
601 kmem_cache_destroy(nf_ct_expect_cachep); 608 if (net_eq(net, &init_net))
602 nf_ct_free_hashtable(nf_ct_expect_hash, nf_ct_expect_vmalloc, 609 kmem_cache_destroy(nf_ct_expect_cachep);
610 nf_ct_free_hashtable(net->ct.expect_hash, net->ct.expect_vmalloc,
603 nf_ct_expect_hsize); 611 nf_ct_expect_hsize);
604} 612}
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index bb20672fe036..4f7107107e99 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -318,7 +318,8 @@ static int find_nl_seq(u32 seq, const struct nf_ct_ftp_master *info, int dir)
318} 318}
319 319
320/* We don't update if it's older than what we have. */ 320/* We don't update if it's older than what we have. */
321static void update_nl_seq(u32 nl_seq, struct nf_ct_ftp_master *info, int dir, 321static void update_nl_seq(struct nf_conn *ct, u32 nl_seq,
322 struct nf_ct_ftp_master *info, int dir,
322 struct sk_buff *skb) 323 struct sk_buff *skb)
323{ 324{
324 unsigned int i, oldest = NUM_SEQ_TO_REMEMBER; 325 unsigned int i, oldest = NUM_SEQ_TO_REMEMBER;
@@ -336,11 +337,11 @@ static void update_nl_seq(u32 nl_seq, struct nf_ct_ftp_master *info, int dir,
336 337
337 if (info->seq_aft_nl_num[dir] < NUM_SEQ_TO_REMEMBER) { 338 if (info->seq_aft_nl_num[dir] < NUM_SEQ_TO_REMEMBER) {
338 info->seq_aft_nl[dir][info->seq_aft_nl_num[dir]++] = nl_seq; 339 info->seq_aft_nl[dir][info->seq_aft_nl_num[dir]++] = nl_seq;
339 nf_conntrack_event_cache(IPCT_HELPINFO_VOLATILE, skb); 340 nf_conntrack_event_cache(IPCT_HELPINFO_VOLATILE, ct);
340 } else if (oldest != NUM_SEQ_TO_REMEMBER && 341 } else if (oldest != NUM_SEQ_TO_REMEMBER &&
341 after(nl_seq, info->seq_aft_nl[dir][oldest])) { 342 after(nl_seq, info->seq_aft_nl[dir][oldest])) {
342 info->seq_aft_nl[dir][oldest] = nl_seq; 343 info->seq_aft_nl[dir][oldest] = nl_seq;
343 nf_conntrack_event_cache(IPCT_HELPINFO_VOLATILE, skb); 344 nf_conntrack_event_cache(IPCT_HELPINFO_VOLATILE, ct);
344 } 345 }
345} 346}
346 347
@@ -509,7 +510,7 @@ out_update_nl:
509 /* Now if this ends in \n, update ftp info. Seq may have been 510 /* Now if this ends in \n, update ftp info. Seq may have been
510 * adjusted by NAT code. */ 511 * adjusted by NAT code. */
511 if (ends_in_nl) 512 if (ends_in_nl)
512 update_nl_seq(seq, ct_ftp_info, dir, skb); 513 update_nl_seq(ct, seq, ct_ftp_info, dir, skb);
513 out: 514 out:
514 spin_unlock_bh(&nf_ftp_lock); 515 spin_unlock_bh(&nf_ftp_lock);
515 return ret; 516 return ret;
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
index 2f83c158934d..c1504f71cdff 100644
--- a/net/netfilter/nf_conntrack_h323_main.c
+++ b/net/netfilter/nf_conntrack_h323_main.c
@@ -709,7 +709,8 @@ static int expect_h245(struct sk_buff *skb, struct nf_conn *ct,
709/* If the calling party is on the same side of the forward-to party, 709/* If the calling party is on the same side of the forward-to party,
710 * we don't need to track the second call */ 710 * we don't need to track the second call */
711static int callforward_do_filter(const union nf_inet_addr *src, 711static int callforward_do_filter(const union nf_inet_addr *src,
712 const union nf_inet_addr *dst, int family) 712 const union nf_inet_addr *dst,
713 u_int8_t family)
713{ 714{
714 const struct nf_afinfo *afinfo; 715 const struct nf_afinfo *afinfo;
715 struct flowi fl1, fl2; 716 struct flowi fl1, fl2;
@@ -1209,6 +1210,7 @@ static struct nf_conntrack_expect *find_expect(struct nf_conn *ct,
1209 union nf_inet_addr *addr, 1210 union nf_inet_addr *addr,
1210 __be16 port) 1211 __be16 port)
1211{ 1212{
1213 struct net *net = nf_ct_net(ct);
1212 struct nf_conntrack_expect *exp; 1214 struct nf_conntrack_expect *exp;
1213 struct nf_conntrack_tuple tuple; 1215 struct nf_conntrack_tuple tuple;
1214 1216
@@ -1218,7 +1220,7 @@ static struct nf_conntrack_expect *find_expect(struct nf_conn *ct,
1218 tuple.dst.u.tcp.port = port; 1220 tuple.dst.u.tcp.port = port;
1219 tuple.dst.protonum = IPPROTO_TCP; 1221 tuple.dst.protonum = IPPROTO_TCP;
1220 1222
1221 exp = __nf_ct_expect_find(&tuple); 1223 exp = __nf_ct_expect_find(net, &tuple);
1222 if (exp && exp->master == ct) 1224 if (exp && exp->master == ct)
1223 return exp; 1225 return exp;
1224 return NULL; 1226 return NULL;
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
index 8e0b4c8f62a8..9c06b9f86ad4 100644
--- a/net/netfilter/nf_conntrack_helper.c
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -123,29 +123,18 @@ int nf_conntrack_helper_register(struct nf_conntrack_helper *me)
123} 123}
124EXPORT_SYMBOL_GPL(nf_conntrack_helper_register); 124EXPORT_SYMBOL_GPL(nf_conntrack_helper_register);
125 125
126void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me) 126static void __nf_conntrack_helper_unregister(struct nf_conntrack_helper *me,
127 struct net *net)
127{ 128{
128 struct nf_conntrack_tuple_hash *h; 129 struct nf_conntrack_tuple_hash *h;
129 struct nf_conntrack_expect *exp; 130 struct nf_conntrack_expect *exp;
130 const struct hlist_node *n, *next; 131 const struct hlist_node *n, *next;
131 unsigned int i; 132 unsigned int i;
132 133
133 mutex_lock(&nf_ct_helper_mutex);
134 hlist_del_rcu(&me->hnode);
135 nf_ct_helper_count--;
136 mutex_unlock(&nf_ct_helper_mutex);
137
138 /* Make sure every nothing is still using the helper unless its a
139 * connection in the hash.
140 */
141 synchronize_rcu();
142
143 spin_lock_bh(&nf_conntrack_lock);
144
145 /* Get rid of expectations */ 134 /* Get rid of expectations */
146 for (i = 0; i < nf_ct_expect_hsize; i++) { 135 for (i = 0; i < nf_ct_expect_hsize; i++) {
147 hlist_for_each_entry_safe(exp, n, next, 136 hlist_for_each_entry_safe(exp, n, next,
148 &nf_ct_expect_hash[i], hnode) { 137 &net->ct.expect_hash[i], hnode) {
149 struct nf_conn_help *help = nfct_help(exp->master); 138 struct nf_conn_help *help = nfct_help(exp->master);
150 if ((help->helper == me || exp->helper == me) && 139 if ((help->helper == me || exp->helper == me) &&
151 del_timer(&exp->timeout)) { 140 del_timer(&exp->timeout)) {
@@ -156,12 +145,31 @@ void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
156 } 145 }
157 146
158 /* Get rid of expecteds, set helpers to NULL. */ 147 /* Get rid of expecteds, set helpers to NULL. */
159 hlist_for_each_entry(h, n, &unconfirmed, hnode) 148 hlist_for_each_entry(h, n, &net->ct.unconfirmed, hnode)
160 unhelp(h, me); 149 unhelp(h, me);
161 for (i = 0; i < nf_conntrack_htable_size; i++) { 150 for (i = 0; i < nf_conntrack_htable_size; i++) {
162 hlist_for_each_entry(h, n, &nf_conntrack_hash[i], hnode) 151 hlist_for_each_entry(h, n, &net->ct.hash[i], hnode)
163 unhelp(h, me); 152 unhelp(h, me);
164 } 153 }
154}
155
156void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
157{
158 struct net *net;
159
160 mutex_lock(&nf_ct_helper_mutex);
161 hlist_del_rcu(&me->hnode);
162 nf_ct_helper_count--;
163 mutex_unlock(&nf_ct_helper_mutex);
164
165 /* Make sure every nothing is still using the helper unless its a
166 * connection in the hash.
167 */
168 synchronize_rcu();
169
170 spin_lock_bh(&nf_conntrack_lock);
171 for_each_net(net)
172 __nf_conntrack_helper_unregister(me, net);
165 spin_unlock_bh(&nf_conntrack_lock); 173 spin_unlock_bh(&nf_conntrack_lock);
166} 174}
167EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister); 175EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister);
diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c
index 1b1226d6653f..20633fdf7e6b 100644
--- a/net/netfilter/nf_conntrack_irc.c
+++ b/net/netfilter/nf_conntrack_irc.c
@@ -68,11 +68,21 @@ static const char *const dccprotos[] = {
68static int parse_dcc(char *data, const char *data_end, u_int32_t *ip, 68static int parse_dcc(char *data, const char *data_end, u_int32_t *ip,
69 u_int16_t *port, char **ad_beg_p, char **ad_end_p) 69 u_int16_t *port, char **ad_beg_p, char **ad_end_p)
70{ 70{
71 char *tmp;
72
71 /* at least 12: "AAAAAAAA P\1\n" */ 73 /* at least 12: "AAAAAAAA P\1\n" */
72 while (*data++ != ' ') 74 while (*data++ != ' ')
73 if (data > data_end - 12) 75 if (data > data_end - 12)
74 return -1; 76 return -1;
75 77
78 /* Make sure we have a newline character within the packet boundaries
79 * because simple_strtoul parses until the first invalid character. */
80 for (tmp = data; tmp <= data_end; tmp++)
81 if (*tmp == '\n')
82 break;
83 if (tmp > data_end || *tmp != '\n')
84 return -1;
85
76 *ad_beg_p = data; 86 *ad_beg_p = data;
77 *ip = simple_strtoul(data, &data, 10); 87 *ip = simple_strtoul(data, &data, 10);
78 88
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index a8752031adcb..cadfd15b44f6 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -549,7 +549,7 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
549 last = (struct nf_conn *)cb->args[1]; 549 last = (struct nf_conn *)cb->args[1];
550 for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) { 550 for (; cb->args[0] < nf_conntrack_htable_size; cb->args[0]++) {
551restart: 551restart:
552 hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[cb->args[0]], 552 hlist_for_each_entry_rcu(h, n, &init_net.ct.hash[cb->args[0]],
553 hnode) { 553 hnode) {
554 if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL) 554 if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL)
555 continue; 555 continue;
@@ -794,14 +794,14 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
794 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, u3); 794 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, u3);
795 else { 795 else {
796 /* Flush the whole table */ 796 /* Flush the whole table */
797 nf_conntrack_flush(); 797 nf_conntrack_flush(&init_net);
798 return 0; 798 return 0;
799 } 799 }
800 800
801 if (err < 0) 801 if (err < 0)
802 return err; 802 return err;
803 803
804 h = nf_conntrack_find_get(&tuple); 804 h = nf_conntrack_find_get(&init_net, &tuple);
805 if (!h) 805 if (!h)
806 return -ENOENT; 806 return -ENOENT;
807 807
@@ -847,7 +847,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
847 if (err < 0) 847 if (err < 0)
848 return err; 848 return err;
849 849
850 h = nf_conntrack_find_get(&tuple); 850 h = nf_conntrack_find_get(&init_net, &tuple);
851 if (!h) 851 if (!h)
852 return -ENOENT; 852 return -ENOENT;
853 853
@@ -1125,7 +1125,7 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
1125 struct nf_conn_help *help; 1125 struct nf_conn_help *help;
1126 struct nf_conntrack_helper *helper; 1126 struct nf_conntrack_helper *helper;
1127 1127
1128 ct = nf_conntrack_alloc(otuple, rtuple, GFP_KERNEL); 1128 ct = nf_conntrack_alloc(&init_net, otuple, rtuple, GFP_KERNEL);
1129 if (ct == NULL || IS_ERR(ct)) 1129 if (ct == NULL || IS_ERR(ct))
1130 return -ENOMEM; 1130 return -ENOMEM;
1131 1131
@@ -1213,9 +1213,9 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
1213 1213
1214 spin_lock_bh(&nf_conntrack_lock); 1214 spin_lock_bh(&nf_conntrack_lock);
1215 if (cda[CTA_TUPLE_ORIG]) 1215 if (cda[CTA_TUPLE_ORIG])
1216 h = __nf_conntrack_find(&otuple); 1216 h = __nf_conntrack_find(&init_net, &otuple);
1217 else if (cda[CTA_TUPLE_REPLY]) 1217 else if (cda[CTA_TUPLE_REPLY])
1218 h = __nf_conntrack_find(&rtuple); 1218 h = __nf_conntrack_find(&init_net, &rtuple);
1219 1219
1220 if (h == NULL) { 1220 if (h == NULL) {
1221 struct nf_conntrack_tuple master; 1221 struct nf_conntrack_tuple master;
@@ -1230,7 +1230,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
1230 if (err < 0) 1230 if (err < 0)
1231 goto out_unlock; 1231 goto out_unlock;
1232 1232
1233 master_h = __nf_conntrack_find(&master); 1233 master_h = __nf_conntrack_find(&init_net, &master);
1234 if (master_h == NULL) { 1234 if (master_h == NULL) {
1235 err = -ENOENT; 1235 err = -ENOENT;
1236 goto out_unlock; 1236 goto out_unlock;
@@ -1458,6 +1458,7 @@ static int ctnetlink_exp_done(struct netlink_callback *cb)
1458static int 1458static int
1459ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb) 1459ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
1460{ 1460{
1461 struct net *net = &init_net;
1461 struct nf_conntrack_expect *exp, *last; 1462 struct nf_conntrack_expect *exp, *last;
1462 struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh); 1463 struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
1463 struct hlist_node *n; 1464 struct hlist_node *n;
@@ -1467,7 +1468,7 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
1467 last = (struct nf_conntrack_expect *)cb->args[1]; 1468 last = (struct nf_conntrack_expect *)cb->args[1];
1468 for (; cb->args[0] < nf_ct_expect_hsize; cb->args[0]++) { 1469 for (; cb->args[0] < nf_ct_expect_hsize; cb->args[0]++) {
1469restart: 1470restart:
1470 hlist_for_each_entry(exp, n, &nf_ct_expect_hash[cb->args[0]], 1471 hlist_for_each_entry(exp, n, &net->ct.expect_hash[cb->args[0]],
1471 hnode) { 1472 hnode) {
1472 if (l3proto && exp->tuple.src.l3num != l3proto) 1473 if (l3proto && exp->tuple.src.l3num != l3proto)
1473 continue; 1474 continue;
@@ -1529,7 +1530,7 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
1529 if (err < 0) 1530 if (err < 0)
1530 return err; 1531 return err;
1531 1532
1532 exp = nf_ct_expect_find_get(&tuple); 1533 exp = nf_ct_expect_find_get(&init_net, &tuple);
1533 if (!exp) 1534 if (!exp)
1534 return -ENOENT; 1535 return -ENOENT;
1535 1536
@@ -1583,7 +1584,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1583 return err; 1584 return err;
1584 1585
1585 /* bump usage count to 2 */ 1586 /* bump usage count to 2 */
1586 exp = nf_ct_expect_find_get(&tuple); 1587 exp = nf_ct_expect_find_get(&init_net, &tuple);
1587 if (!exp) 1588 if (!exp)
1588 return -ENOENT; 1589 return -ENOENT;
1589 1590
@@ -1613,7 +1614,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1613 } 1614 }
1614 for (i = 0; i < nf_ct_expect_hsize; i++) { 1615 for (i = 0; i < nf_ct_expect_hsize; i++) {
1615 hlist_for_each_entry_safe(exp, n, next, 1616 hlist_for_each_entry_safe(exp, n, next,
1616 &nf_ct_expect_hash[i], 1617 &init_net.ct.expect_hash[i],
1617 hnode) { 1618 hnode) {
1618 m_help = nfct_help(exp->master); 1619 m_help = nfct_help(exp->master);
1619 if (m_help->helper == h 1620 if (m_help->helper == h
@@ -1629,7 +1630,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1629 spin_lock_bh(&nf_conntrack_lock); 1630 spin_lock_bh(&nf_conntrack_lock);
1630 for (i = 0; i < nf_ct_expect_hsize; i++) { 1631 for (i = 0; i < nf_ct_expect_hsize; i++) {
1631 hlist_for_each_entry_safe(exp, n, next, 1632 hlist_for_each_entry_safe(exp, n, next,
1632 &nf_ct_expect_hash[i], 1633 &init_net.ct.expect_hash[i],
1633 hnode) { 1634 hnode) {
1634 if (del_timer(&exp->timeout)) { 1635 if (del_timer(&exp->timeout)) {
1635 nf_ct_unlink_expect(exp); 1636 nf_ct_unlink_expect(exp);
@@ -1670,7 +1671,7 @@ ctnetlink_create_expect(struct nlattr *cda[], u_int8_t u3)
1670 return err; 1671 return err;
1671 1672
1672 /* Look for master conntrack of this expectation */ 1673 /* Look for master conntrack of this expectation */
1673 h = nf_conntrack_find_get(&master_tuple); 1674 h = nf_conntrack_find_get(&init_net, &master_tuple);
1674 if (!h) 1675 if (!h)
1675 return -ENOENT; 1676 return -ENOENT;
1676 ct = nf_ct_tuplehash_to_ctrack(h); 1677 ct = nf_ct_tuplehash_to_ctrack(h);
@@ -1724,7 +1725,7 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
1724 return err; 1725 return err;
1725 1726
1726 spin_lock_bh(&nf_conntrack_lock); 1727 spin_lock_bh(&nf_conntrack_lock);
1727 exp = __nf_ct_expect_find(&tuple); 1728 exp = __nf_ct_expect_find(&init_net, &tuple);
1728 1729
1729 if (!exp) { 1730 if (!exp) {
1730 spin_unlock_bh(&nf_conntrack_lock); 1731 spin_unlock_bh(&nf_conntrack_lock);
diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c
index 97e54b0e43a3..373e51e91ce5 100644
--- a/net/netfilter/nf_conntrack_pptp.c
+++ b/net/netfilter/nf_conntrack_pptp.c
@@ -98,6 +98,7 @@ EXPORT_SYMBOL(pptp_msg_name);
98static void pptp_expectfn(struct nf_conn *ct, 98static void pptp_expectfn(struct nf_conn *ct,
99 struct nf_conntrack_expect *exp) 99 struct nf_conntrack_expect *exp)
100{ 100{
101 struct net *net = nf_ct_net(ct);
101 typeof(nf_nat_pptp_hook_expectfn) nf_nat_pptp_expectfn; 102 typeof(nf_nat_pptp_hook_expectfn) nf_nat_pptp_expectfn;
102 pr_debug("increasing timeouts\n"); 103 pr_debug("increasing timeouts\n");
103 104
@@ -121,7 +122,7 @@ static void pptp_expectfn(struct nf_conn *ct,
121 pr_debug("trying to unexpect other dir: "); 122 pr_debug("trying to unexpect other dir: ");
122 nf_ct_dump_tuple(&inv_t); 123 nf_ct_dump_tuple(&inv_t);
123 124
124 exp_other = nf_ct_expect_find_get(&inv_t); 125 exp_other = nf_ct_expect_find_get(net, &inv_t);
125 if (exp_other) { 126 if (exp_other) {
126 /* delete other expectation. */ 127 /* delete other expectation. */
127 pr_debug("found\n"); 128 pr_debug("found\n");
@@ -134,7 +135,8 @@ static void pptp_expectfn(struct nf_conn *ct,
134 rcu_read_unlock(); 135 rcu_read_unlock();
135} 136}
136 137
137static int destroy_sibling_or_exp(const struct nf_conntrack_tuple *t) 138static int destroy_sibling_or_exp(struct net *net,
139 const struct nf_conntrack_tuple *t)
138{ 140{
139 const struct nf_conntrack_tuple_hash *h; 141 const struct nf_conntrack_tuple_hash *h;
140 struct nf_conntrack_expect *exp; 142 struct nf_conntrack_expect *exp;
@@ -143,7 +145,7 @@ static int destroy_sibling_or_exp(const struct nf_conntrack_tuple *t)
143 pr_debug("trying to timeout ct or exp for tuple "); 145 pr_debug("trying to timeout ct or exp for tuple ");
144 nf_ct_dump_tuple(t); 146 nf_ct_dump_tuple(t);
145 147
146 h = nf_conntrack_find_get(t); 148 h = nf_conntrack_find_get(net, t);
147 if (h) { 149 if (h) {
148 sibling = nf_ct_tuplehash_to_ctrack(h); 150 sibling = nf_ct_tuplehash_to_ctrack(h);
149 pr_debug("setting timeout of conntrack %p to 0\n", sibling); 151 pr_debug("setting timeout of conntrack %p to 0\n", sibling);
@@ -154,7 +156,7 @@ static int destroy_sibling_or_exp(const struct nf_conntrack_tuple *t)
154 nf_ct_put(sibling); 156 nf_ct_put(sibling);
155 return 1; 157 return 1;
156 } else { 158 } else {
157 exp = nf_ct_expect_find_get(t); 159 exp = nf_ct_expect_find_get(net, t);
158 if (exp) { 160 if (exp) {
159 pr_debug("unexpect_related of expect %p\n", exp); 161 pr_debug("unexpect_related of expect %p\n", exp);
160 nf_ct_unexpect_related(exp); 162 nf_ct_unexpect_related(exp);
@@ -168,6 +170,7 @@ static int destroy_sibling_or_exp(const struct nf_conntrack_tuple *t)
168/* timeout GRE data connections */ 170/* timeout GRE data connections */
169static void pptp_destroy_siblings(struct nf_conn *ct) 171static void pptp_destroy_siblings(struct nf_conn *ct)
170{ 172{
173 struct net *net = nf_ct_net(ct);
171 const struct nf_conn_help *help = nfct_help(ct); 174 const struct nf_conn_help *help = nfct_help(ct);
172 struct nf_conntrack_tuple t; 175 struct nf_conntrack_tuple t;
173 176
@@ -178,7 +181,7 @@ static void pptp_destroy_siblings(struct nf_conn *ct)
178 t.dst.protonum = IPPROTO_GRE; 181 t.dst.protonum = IPPROTO_GRE;
179 t.src.u.gre.key = help->help.ct_pptp_info.pns_call_id; 182 t.src.u.gre.key = help->help.ct_pptp_info.pns_call_id;
180 t.dst.u.gre.key = help->help.ct_pptp_info.pac_call_id; 183 t.dst.u.gre.key = help->help.ct_pptp_info.pac_call_id;
181 if (!destroy_sibling_or_exp(&t)) 184 if (!destroy_sibling_or_exp(net, &t))
182 pr_debug("failed to timeout original pns->pac ct/exp\n"); 185 pr_debug("failed to timeout original pns->pac ct/exp\n");
183 186
184 /* try reply (pac->pns) tuple */ 187 /* try reply (pac->pns) tuple */
@@ -186,7 +189,7 @@ static void pptp_destroy_siblings(struct nf_conn *ct)
186 t.dst.protonum = IPPROTO_GRE; 189 t.dst.protonum = IPPROTO_GRE;
187 t.src.u.gre.key = help->help.ct_pptp_info.pac_call_id; 190 t.src.u.gre.key = help->help.ct_pptp_info.pac_call_id;
188 t.dst.u.gre.key = help->help.ct_pptp_info.pns_call_id; 191 t.dst.u.gre.key = help->help.ct_pptp_info.pns_call_id;
189 if (!destroy_sibling_or_exp(&t)) 192 if (!destroy_sibling_or_exp(net, &t))
190 pr_debug("failed to timeout reply pac->pns ct/exp\n"); 193 pr_debug("failed to timeout reply pac->pns ct/exp\n");
191} 194}
192 195
@@ -594,15 +597,32 @@ static struct nf_conntrack_helper pptp __read_mostly = {
594 .expect_policy = &pptp_exp_policy, 597 .expect_policy = &pptp_exp_policy,
595}; 598};
596 599
600static void nf_conntrack_pptp_net_exit(struct net *net)
601{
602 nf_ct_gre_keymap_flush(net);
603}
604
605static struct pernet_operations nf_conntrack_pptp_net_ops = {
606 .exit = nf_conntrack_pptp_net_exit,
607};
608
597static int __init nf_conntrack_pptp_init(void) 609static int __init nf_conntrack_pptp_init(void)
598{ 610{
599 return nf_conntrack_helper_register(&pptp); 611 int rv;
612
613 rv = nf_conntrack_helper_register(&pptp);
614 if (rv < 0)
615 return rv;
616 rv = register_pernet_subsys(&nf_conntrack_pptp_net_ops);
617 if (rv < 0)
618 nf_conntrack_helper_unregister(&pptp);
619 return rv;
600} 620}
601 621
602static void __exit nf_conntrack_pptp_fini(void) 622static void __exit nf_conntrack_pptp_fini(void)
603{ 623{
604 nf_conntrack_helper_unregister(&pptp); 624 nf_conntrack_helper_unregister(&pptp);
605 nf_ct_gre_keymap_flush(); 625 unregister_pernet_subsys(&nf_conntrack_pptp_net_ops);
606} 626}
607 627
608module_init(nf_conntrack_pptp_init); 628module_init(nf_conntrack_pptp_init);
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
index a49fc932629b..a59a307e685d 100644
--- a/net/netfilter/nf_conntrack_proto.c
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -207,6 +207,8 @@ EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_register);
207 207
208void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto) 208void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto)
209{ 209{
210 struct net *net;
211
210 BUG_ON(proto->l3proto >= AF_MAX); 212 BUG_ON(proto->l3proto >= AF_MAX);
211 213
212 mutex_lock(&nf_ct_proto_mutex); 214 mutex_lock(&nf_ct_proto_mutex);
@@ -219,7 +221,8 @@ void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto)
219 synchronize_rcu(); 221 synchronize_rcu();
220 222
221 /* Remove all contrack entries for this protocol */ 223 /* Remove all contrack entries for this protocol */
222 nf_ct_iterate_cleanup(kill_l3proto, proto); 224 for_each_net(net)
225 nf_ct_iterate_cleanup(net, kill_l3proto, proto);
223} 226}
224EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_unregister); 227EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_unregister);
225 228
@@ -316,6 +319,8 @@ EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_register);
316 319
317void nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *l4proto) 320void nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *l4proto)
318{ 321{
322 struct net *net;
323
319 BUG_ON(l4proto->l3proto >= PF_MAX); 324 BUG_ON(l4proto->l3proto >= PF_MAX);
320 325
321 mutex_lock(&nf_ct_proto_mutex); 326 mutex_lock(&nf_ct_proto_mutex);
@@ -328,7 +333,8 @@ void nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *l4proto)
328 synchronize_rcu(); 333 synchronize_rcu();
329 334
330 /* Remove all contrack entries for this protocol */ 335 /* Remove all contrack entries for this protocol */
331 nf_ct_iterate_cleanup(kill_l4proto, l4proto); 336 for_each_net(net)
337 nf_ct_iterate_cleanup(net, kill_l4proto, l4proto);
332} 338}
333EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_unregister); 339EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_unregister);
334 340
diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c
index e7866dd3cde6..8fcf1762fabf 100644
--- a/net/netfilter/nf_conntrack_proto_dccp.c
+++ b/net/netfilter/nf_conntrack_proto_dccp.c
@@ -418,6 +418,7 @@ static bool dccp_invert_tuple(struct nf_conntrack_tuple *inv,
418static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb, 418static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb,
419 unsigned int dataoff) 419 unsigned int dataoff)
420{ 420{
421 struct net *net = nf_ct_net(ct);
421 struct dccp_hdr _dh, *dh; 422 struct dccp_hdr _dh, *dh;
422 const char *msg; 423 const char *msg;
423 u_int8_t state; 424 u_int8_t state;
@@ -445,7 +446,7 @@ static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb,
445 return true; 446 return true;
446 447
447out_invalid: 448out_invalid:
448 if (LOG_INVALID(IPPROTO_DCCP)) 449 if (LOG_INVALID(net, IPPROTO_DCCP))
449 nf_log_packet(nf_ct_l3num(ct), 0, skb, NULL, NULL, NULL, msg); 450 nf_log_packet(nf_ct_l3num(ct), 0, skb, NULL, NULL, NULL, msg);
450 return false; 451 return false;
451} 452}
@@ -461,8 +462,9 @@ static u64 dccp_ack_seq(const struct dccp_hdr *dh)
461 462
462static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb, 463static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,
463 unsigned int dataoff, enum ip_conntrack_info ctinfo, 464 unsigned int dataoff, enum ip_conntrack_info ctinfo,
464 int pf, unsigned int hooknum) 465 u_int8_t pf, unsigned int hooknum)
465{ 466{
467 struct net *net = nf_ct_net(ct);
466 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 468 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
467 struct dccp_hdr _dh, *dh; 469 struct dccp_hdr _dh, *dh;
468 u_int8_t type, old_state, new_state; 470 u_int8_t type, old_state, new_state;
@@ -524,13 +526,13 @@ static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,
524 ct->proto.dccp.last_pkt = type; 526 ct->proto.dccp.last_pkt = type;
525 527
526 write_unlock_bh(&dccp_lock); 528 write_unlock_bh(&dccp_lock);
527 if (LOG_INVALID(IPPROTO_DCCP)) 529 if (LOG_INVALID(net, IPPROTO_DCCP))
528 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 530 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
529 "nf_ct_dccp: invalid packet ignored "); 531 "nf_ct_dccp: invalid packet ignored ");
530 return NF_ACCEPT; 532 return NF_ACCEPT;
531 case CT_DCCP_INVALID: 533 case CT_DCCP_INVALID:
532 write_unlock_bh(&dccp_lock); 534 write_unlock_bh(&dccp_lock);
533 if (LOG_INVALID(IPPROTO_DCCP)) 535 if (LOG_INVALID(net, IPPROTO_DCCP))
534 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 536 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
535 "nf_ct_dccp: invalid state transition "); 537 "nf_ct_dccp: invalid state transition ");
536 return -NF_ACCEPT; 538 return -NF_ACCEPT;
@@ -545,9 +547,9 @@ static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,
545 return NF_ACCEPT; 547 return NF_ACCEPT;
546} 548}
547 549
548static int dccp_error(struct sk_buff *skb, unsigned int dataoff, 550static int dccp_error(struct net *net, struct sk_buff *skb,
549 enum ip_conntrack_info *ctinfo, int pf, 551 unsigned int dataoff, enum ip_conntrack_info *ctinfo,
550 unsigned int hooknum) 552 u_int8_t pf, unsigned int hooknum)
551{ 553{
552 struct dccp_hdr _dh, *dh; 554 struct dccp_hdr _dh, *dh;
553 unsigned int dccp_len = skb->len - dataoff; 555 unsigned int dccp_len = skb->len - dataoff;
@@ -575,7 +577,7 @@ static int dccp_error(struct sk_buff *skb, unsigned int dataoff,
575 } 577 }
576 } 578 }
577 579
578 if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING && 580 if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
579 nf_checksum_partial(skb, hooknum, dataoff, cscov, IPPROTO_DCCP, 581 nf_checksum_partial(skb, hooknum, dataoff, cscov, IPPROTO_DCCP,
580 pf)) { 582 pf)) {
581 msg = "nf_ct_dccp: bad checksum "; 583 msg = "nf_ct_dccp: bad checksum ";
@@ -590,7 +592,7 @@ static int dccp_error(struct sk_buff *skb, unsigned int dataoff,
590 return NF_ACCEPT; 592 return NF_ACCEPT;
591 593
592out_invalid: 594out_invalid:
593 if (LOG_INVALID(IPPROTO_DCCP)) 595 if (LOG_INVALID(net, IPPROTO_DCCP))
594 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, msg); 596 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, msg);
595 return -NF_ACCEPT; 597 return -NF_ACCEPT;
596} 598}
diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c
index e31b0e7bd0b1..dbe680af85d2 100644
--- a/net/netfilter/nf_conntrack_proto_generic.c
+++ b/net/netfilter/nf_conntrack_proto_generic.c
@@ -45,7 +45,7 @@ static int packet(struct nf_conn *ct,
45 const struct sk_buff *skb, 45 const struct sk_buff *skb,
46 unsigned int dataoff, 46 unsigned int dataoff,
47 enum ip_conntrack_info ctinfo, 47 enum ip_conntrack_info ctinfo,
48 int pf, 48 u_int8_t pf,
49 unsigned int hooknum) 49 unsigned int hooknum)
50{ 50{
51 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_generic_timeout); 51 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_generic_timeout);
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
index 654a4f7f12c6..a2cdbcbf64c4 100644
--- a/net/netfilter/nf_conntrack_proto_gre.c
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -29,8 +29,11 @@
29#include <linux/list.h> 29#include <linux/list.h>
30#include <linux/seq_file.h> 30#include <linux/seq_file.h>
31#include <linux/in.h> 31#include <linux/in.h>
32#include <linux/netdevice.h>
32#include <linux/skbuff.h> 33#include <linux/skbuff.h>
33 34#include <net/dst.h>
35#include <net/net_namespace.h>
36#include <net/netns/generic.h>
34#include <net/netfilter/nf_conntrack_l4proto.h> 37#include <net/netfilter/nf_conntrack_l4proto.h>
35#include <net/netfilter/nf_conntrack_helper.h> 38#include <net/netfilter/nf_conntrack_helper.h>
36#include <net/netfilter/nf_conntrack_core.h> 39#include <net/netfilter/nf_conntrack_core.h>
@@ -40,19 +43,23 @@
40#define GRE_TIMEOUT (30 * HZ) 43#define GRE_TIMEOUT (30 * HZ)
41#define GRE_STREAM_TIMEOUT (180 * HZ) 44#define GRE_STREAM_TIMEOUT (180 * HZ)
42 45
43static DEFINE_RWLOCK(nf_ct_gre_lock); 46static int proto_gre_net_id;
44static LIST_HEAD(gre_keymap_list); 47struct netns_proto_gre {
48 rwlock_t keymap_lock;
49 struct list_head keymap_list;
50};
45 51
46void nf_ct_gre_keymap_flush(void) 52void nf_ct_gre_keymap_flush(struct net *net)
47{ 53{
48 struct list_head *pos, *n; 54 struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id);
55 struct nf_ct_gre_keymap *km, *tmp;
49 56
50 write_lock_bh(&nf_ct_gre_lock); 57 write_lock_bh(&net_gre->keymap_lock);
51 list_for_each_safe(pos, n, &gre_keymap_list) { 58 list_for_each_entry_safe(km, tmp, &net_gre->keymap_list, list) {
52 list_del(pos); 59 list_del(&km->list);
53 kfree(pos); 60 kfree(km);
54 } 61 }
55 write_unlock_bh(&nf_ct_gre_lock); 62 write_unlock_bh(&net_gre->keymap_lock);
56} 63}
57EXPORT_SYMBOL(nf_ct_gre_keymap_flush); 64EXPORT_SYMBOL(nf_ct_gre_keymap_flush);
58 65
@@ -67,19 +74,20 @@ static inline int gre_key_cmpfn(const struct nf_ct_gre_keymap *km,
67} 74}
68 75
69/* look up the source key for a given tuple */ 76/* look up the source key for a given tuple */
70static __be16 gre_keymap_lookup(struct nf_conntrack_tuple *t) 77static __be16 gre_keymap_lookup(struct net *net, struct nf_conntrack_tuple *t)
71{ 78{
79 struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id);
72 struct nf_ct_gre_keymap *km; 80 struct nf_ct_gre_keymap *km;
73 __be16 key = 0; 81 __be16 key = 0;
74 82
75 read_lock_bh(&nf_ct_gre_lock); 83 read_lock_bh(&net_gre->keymap_lock);
76 list_for_each_entry(km, &gre_keymap_list, list) { 84 list_for_each_entry(km, &net_gre->keymap_list, list) {
77 if (gre_key_cmpfn(km, t)) { 85 if (gre_key_cmpfn(km, t)) {
78 key = km->tuple.src.u.gre.key; 86 key = km->tuple.src.u.gre.key;
79 break; 87 break;
80 } 88 }
81 } 89 }
82 read_unlock_bh(&nf_ct_gre_lock); 90 read_unlock_bh(&net_gre->keymap_lock);
83 91
84 pr_debug("lookup src key 0x%x for ", key); 92 pr_debug("lookup src key 0x%x for ", key);
85 nf_ct_dump_tuple(t); 93 nf_ct_dump_tuple(t);
@@ -91,16 +99,22 @@ static __be16 gre_keymap_lookup(struct nf_conntrack_tuple *t)
91int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir, 99int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
92 struct nf_conntrack_tuple *t) 100 struct nf_conntrack_tuple *t)
93{ 101{
102 struct net *net = nf_ct_net(ct);
103 struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id);
94 struct nf_conn_help *help = nfct_help(ct); 104 struct nf_conn_help *help = nfct_help(ct);
95 struct nf_ct_gre_keymap **kmp, *km; 105 struct nf_ct_gre_keymap **kmp, *km;
96 106
97 kmp = &help->help.ct_pptp_info.keymap[dir]; 107 kmp = &help->help.ct_pptp_info.keymap[dir];
98 if (*kmp) { 108 if (*kmp) {
99 /* check whether it's a retransmission */ 109 /* check whether it's a retransmission */
100 list_for_each_entry(km, &gre_keymap_list, list) { 110 read_lock_bh(&net_gre->keymap_lock);
101 if (gre_key_cmpfn(km, t) && km == *kmp) 111 list_for_each_entry(km, &net_gre->keymap_list, list) {
112 if (gre_key_cmpfn(km, t) && km == *kmp) {
113 read_unlock_bh(&net_gre->keymap_lock);
102 return 0; 114 return 0;
115 }
103 } 116 }
117 read_unlock_bh(&net_gre->keymap_lock);
104 pr_debug("trying to override keymap_%s for ct %p\n", 118 pr_debug("trying to override keymap_%s for ct %p\n",
105 dir == IP_CT_DIR_REPLY ? "reply" : "orig", ct); 119 dir == IP_CT_DIR_REPLY ? "reply" : "orig", ct);
106 return -EEXIST; 120 return -EEXIST;
@@ -115,9 +129,9 @@ int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
115 pr_debug("adding new entry %p: ", km); 129 pr_debug("adding new entry %p: ", km);
116 nf_ct_dump_tuple(&km->tuple); 130 nf_ct_dump_tuple(&km->tuple);
117 131
118 write_lock_bh(&nf_ct_gre_lock); 132 write_lock_bh(&net_gre->keymap_lock);
119 list_add_tail(&km->list, &gre_keymap_list); 133 list_add_tail(&km->list, &net_gre->keymap_list);
120 write_unlock_bh(&nf_ct_gre_lock); 134 write_unlock_bh(&net_gre->keymap_lock);
121 135
122 return 0; 136 return 0;
123} 137}
@@ -126,12 +140,14 @@ EXPORT_SYMBOL_GPL(nf_ct_gre_keymap_add);
126/* destroy the keymap entries associated with specified master ct */ 140/* destroy the keymap entries associated with specified master ct */
127void nf_ct_gre_keymap_destroy(struct nf_conn *ct) 141void nf_ct_gre_keymap_destroy(struct nf_conn *ct)
128{ 142{
143 struct net *net = nf_ct_net(ct);
144 struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id);
129 struct nf_conn_help *help = nfct_help(ct); 145 struct nf_conn_help *help = nfct_help(ct);
130 enum ip_conntrack_dir dir; 146 enum ip_conntrack_dir dir;
131 147
132 pr_debug("entering for ct %p\n", ct); 148 pr_debug("entering for ct %p\n", ct);
133 149
134 write_lock_bh(&nf_ct_gre_lock); 150 write_lock_bh(&net_gre->keymap_lock);
135 for (dir = IP_CT_DIR_ORIGINAL; dir < IP_CT_DIR_MAX; dir++) { 151 for (dir = IP_CT_DIR_ORIGINAL; dir < IP_CT_DIR_MAX; dir++) {
136 if (help->help.ct_pptp_info.keymap[dir]) { 152 if (help->help.ct_pptp_info.keymap[dir]) {
137 pr_debug("removing %p from list\n", 153 pr_debug("removing %p from list\n",
@@ -141,7 +157,7 @@ void nf_ct_gre_keymap_destroy(struct nf_conn *ct)
141 help->help.ct_pptp_info.keymap[dir] = NULL; 157 help->help.ct_pptp_info.keymap[dir] = NULL;
142 } 158 }
143 } 159 }
144 write_unlock_bh(&nf_ct_gre_lock); 160 write_unlock_bh(&net_gre->keymap_lock);
145} 161}
146EXPORT_SYMBOL_GPL(nf_ct_gre_keymap_destroy); 162EXPORT_SYMBOL_GPL(nf_ct_gre_keymap_destroy);
147 163
@@ -160,6 +176,7 @@ static bool gre_invert_tuple(struct nf_conntrack_tuple *tuple,
160static bool gre_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff, 176static bool gre_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
161 struct nf_conntrack_tuple *tuple) 177 struct nf_conntrack_tuple *tuple)
162{ 178{
179 struct net *net = dev_net(skb->dev ? skb->dev : skb->dst->dev);
163 const struct gre_hdr_pptp *pgrehdr; 180 const struct gre_hdr_pptp *pgrehdr;
164 struct gre_hdr_pptp _pgrehdr; 181 struct gre_hdr_pptp _pgrehdr;
165 __be16 srckey; 182 __be16 srckey;
@@ -186,7 +203,7 @@ static bool gre_pkt_to_tuple(const struct sk_buff *skb, unsigned int dataoff,
186 } 203 }
187 204
188 tuple->dst.u.gre.key = pgrehdr->call_id; 205 tuple->dst.u.gre.key = pgrehdr->call_id;
189 srckey = gre_keymap_lookup(tuple); 206 srckey = gre_keymap_lookup(net, tuple);
190 tuple->src.u.gre.key = srckey; 207 tuple->src.u.gre.key = srckey;
191 208
192 return true; 209 return true;
@@ -215,7 +232,7 @@ static int gre_packet(struct nf_conn *ct,
215 const struct sk_buff *skb, 232 const struct sk_buff *skb,
216 unsigned int dataoff, 233 unsigned int dataoff,
217 enum ip_conntrack_info ctinfo, 234 enum ip_conntrack_info ctinfo,
218 int pf, 235 u_int8_t pf,
219 unsigned int hooknum) 236 unsigned int hooknum)
220{ 237{
221 /* If we've seen traffic both ways, this is a GRE connection. 238 /* If we've seen traffic both ways, this is a GRE connection.
@@ -225,7 +242,7 @@ static int gre_packet(struct nf_conn *ct,
225 ct->proto.gre.stream_timeout); 242 ct->proto.gre.stream_timeout);
226 /* Also, more likely to be important, and not a probe. */ 243 /* Also, more likely to be important, and not a probe. */
227 set_bit(IPS_ASSURED_BIT, &ct->status); 244 set_bit(IPS_ASSURED_BIT, &ct->status);
228 nf_conntrack_event_cache(IPCT_STATUS, skb); 245 nf_conntrack_event_cache(IPCT_STATUS, ct);
229 } else 246 } else
230 nf_ct_refresh_acct(ct, ctinfo, skb, 247 nf_ct_refresh_acct(ct, ctinfo, skb,
231 ct->proto.gre.timeout); 248 ct->proto.gre.timeout);
@@ -281,15 +298,53 @@ static struct nf_conntrack_l4proto nf_conntrack_l4proto_gre4 __read_mostly = {
281#endif 298#endif
282}; 299};
283 300
301static int proto_gre_net_init(struct net *net)
302{
303 struct netns_proto_gre *net_gre;
304 int rv;
305
306 net_gre = kmalloc(sizeof(struct netns_proto_gre), GFP_KERNEL);
307 if (!net_gre)
308 return -ENOMEM;
309 rwlock_init(&net_gre->keymap_lock);
310 INIT_LIST_HEAD(&net_gre->keymap_list);
311
312 rv = net_assign_generic(net, proto_gre_net_id, net_gre);
313 if (rv < 0)
314 kfree(net_gre);
315 return rv;
316}
317
318static void proto_gre_net_exit(struct net *net)
319{
320 struct netns_proto_gre *net_gre = net_generic(net, proto_gre_net_id);
321
322 nf_ct_gre_keymap_flush(net);
323 kfree(net_gre);
324}
325
326static struct pernet_operations proto_gre_net_ops = {
327 .init = proto_gre_net_init,
328 .exit = proto_gre_net_exit,
329};
330
284static int __init nf_ct_proto_gre_init(void) 331static int __init nf_ct_proto_gre_init(void)
285{ 332{
286 return nf_conntrack_l4proto_register(&nf_conntrack_l4proto_gre4); 333 int rv;
334
335 rv = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_gre4);
336 if (rv < 0)
337 return rv;
338 rv = register_pernet_gen_device(&proto_gre_net_id, &proto_gre_net_ops);
339 if (rv < 0)
340 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_gre4);
341 return rv;
287} 342}
288 343
289static void nf_ct_proto_gre_fini(void) 344static void nf_ct_proto_gre_fini(void)
290{ 345{
291 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_gre4); 346 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_gre4);
292 nf_ct_gre_keymap_flush(); 347 unregister_pernet_gen_device(proto_gre_net_id, &proto_gre_net_ops);
293} 348}
294 349
295module_init(nf_ct_proto_gre_init); 350module_init(nf_ct_proto_gre_init);
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index 30aa5b94a771..ae8c2609e230 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -287,7 +287,7 @@ static int sctp_packet(struct nf_conn *ct,
287 const struct sk_buff *skb, 287 const struct sk_buff *skb,
288 unsigned int dataoff, 288 unsigned int dataoff,
289 enum ip_conntrack_info ctinfo, 289 enum ip_conntrack_info ctinfo,
290 int pf, 290 u_int8_t pf,
291 unsigned int hooknum) 291 unsigned int hooknum)
292{ 292{
293 enum sctp_conntrack new_state, old_state; 293 enum sctp_conntrack new_state, old_state;
@@ -369,7 +369,7 @@ static int sctp_packet(struct nf_conn *ct,
369 369
370 ct->proto.sctp.state = new_state; 370 ct->proto.sctp.state = new_state;
371 if (old_state != new_state) 371 if (old_state != new_state)
372 nf_conntrack_event_cache(IPCT_PROTOINFO, skb); 372 nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
373 } 373 }
374 write_unlock_bh(&sctp_lock); 374 write_unlock_bh(&sctp_lock);
375 375
@@ -380,7 +380,7 @@ static int sctp_packet(struct nf_conn *ct,
380 new_state == SCTP_CONNTRACK_ESTABLISHED) { 380 new_state == SCTP_CONNTRACK_ESTABLISHED) {
381 pr_debug("Setting assured bit\n"); 381 pr_debug("Setting assured bit\n");
382 set_bit(IPS_ASSURED_BIT, &ct->status); 382 set_bit(IPS_ASSURED_BIT, &ct->status);
383 nf_conntrack_event_cache(IPCT_STATUS, skb); 383 nf_conntrack_event_cache(IPCT_STATUS, ct);
384 } 384 }
385 385
386 return NF_ACCEPT; 386 return NF_ACCEPT;
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 6f61261888ef..f947ec41e391 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -486,8 +486,9 @@ static bool tcp_in_window(const struct nf_conn *ct,
486 const struct sk_buff *skb, 486 const struct sk_buff *skb,
487 unsigned int dataoff, 487 unsigned int dataoff,
488 const struct tcphdr *tcph, 488 const struct tcphdr *tcph,
489 int pf) 489 u_int8_t pf)
490{ 490{
491 struct net *net = nf_ct_net(ct);
491 struct ip_ct_tcp_state *sender = &state->seen[dir]; 492 struct ip_ct_tcp_state *sender = &state->seen[dir];
492 struct ip_ct_tcp_state *receiver = &state->seen[!dir]; 493 struct ip_ct_tcp_state *receiver = &state->seen[!dir];
493 const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple; 494 const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple;
@@ -668,7 +669,7 @@ static bool tcp_in_window(const struct nf_conn *ct,
668 if (sender->flags & IP_CT_TCP_FLAG_BE_LIBERAL || 669 if (sender->flags & IP_CT_TCP_FLAG_BE_LIBERAL ||
669 nf_ct_tcp_be_liberal) 670 nf_ct_tcp_be_liberal)
670 res = true; 671 res = true;
671 if (!res && LOG_INVALID(IPPROTO_TCP)) 672 if (!res && LOG_INVALID(net, IPPROTO_TCP))
672 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 673 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
673 "nf_ct_tcp: %s ", 674 "nf_ct_tcp: %s ",
674 before(seq, sender->td_maxend + 1) ? 675 before(seq, sender->td_maxend + 1) ?
@@ -746,10 +747,11 @@ static const u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG) + 1] =
746}; 747};
747 748
748/* Protect conntrack agaist broken packets. Code taken from ipt_unclean.c. */ 749/* Protect conntrack agaist broken packets. Code taken from ipt_unclean.c. */
749static int tcp_error(struct sk_buff *skb, 750static int tcp_error(struct net *net,
751 struct sk_buff *skb,
750 unsigned int dataoff, 752 unsigned int dataoff,
751 enum ip_conntrack_info *ctinfo, 753 enum ip_conntrack_info *ctinfo,
752 int pf, 754 u_int8_t pf,
753 unsigned int hooknum) 755 unsigned int hooknum)
754{ 756{
755 const struct tcphdr *th; 757 const struct tcphdr *th;
@@ -760,7 +762,7 @@ static int tcp_error(struct sk_buff *skb,
760 /* Smaller that minimal TCP header? */ 762 /* Smaller that minimal TCP header? */
761 th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph); 763 th = skb_header_pointer(skb, dataoff, sizeof(_tcph), &_tcph);
762 if (th == NULL) { 764 if (th == NULL) {
763 if (LOG_INVALID(IPPROTO_TCP)) 765 if (LOG_INVALID(net, IPPROTO_TCP))
764 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 766 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
765 "nf_ct_tcp: short packet "); 767 "nf_ct_tcp: short packet ");
766 return -NF_ACCEPT; 768 return -NF_ACCEPT;
@@ -768,7 +770,7 @@ static int tcp_error(struct sk_buff *skb,
768 770
769 /* Not whole TCP header or malformed packet */ 771 /* Not whole TCP header or malformed packet */
770 if (th->doff*4 < sizeof(struct tcphdr) || tcplen < th->doff*4) { 772 if (th->doff*4 < sizeof(struct tcphdr) || tcplen < th->doff*4) {
771 if (LOG_INVALID(IPPROTO_TCP)) 773 if (LOG_INVALID(net, IPPROTO_TCP))
772 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 774 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
773 "nf_ct_tcp: truncated/malformed packet "); 775 "nf_ct_tcp: truncated/malformed packet ");
774 return -NF_ACCEPT; 776 return -NF_ACCEPT;
@@ -779,9 +781,9 @@ static int tcp_error(struct sk_buff *skb,
779 * because the checksum is assumed to be correct. 781 * because the checksum is assumed to be correct.
780 */ 782 */
781 /* FIXME: Source route IP option packets --RR */ 783 /* FIXME: Source route IP option packets --RR */
782 if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING && 784 if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
783 nf_checksum(skb, hooknum, dataoff, IPPROTO_TCP, pf)) { 785 nf_checksum(skb, hooknum, dataoff, IPPROTO_TCP, pf)) {
784 if (LOG_INVALID(IPPROTO_TCP)) 786 if (LOG_INVALID(net, IPPROTO_TCP))
785 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 787 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
786 "nf_ct_tcp: bad TCP checksum "); 788 "nf_ct_tcp: bad TCP checksum ");
787 return -NF_ACCEPT; 789 return -NF_ACCEPT;
@@ -790,7 +792,7 @@ static int tcp_error(struct sk_buff *skb,
790 /* Check TCP flags. */ 792 /* Check TCP flags. */
791 tcpflags = (((u_int8_t *)th)[13] & ~(TH_ECE|TH_CWR|TH_PUSH)); 793 tcpflags = (((u_int8_t *)th)[13] & ~(TH_ECE|TH_CWR|TH_PUSH));
792 if (!tcp_valid_flags[tcpflags]) { 794 if (!tcp_valid_flags[tcpflags]) {
793 if (LOG_INVALID(IPPROTO_TCP)) 795 if (LOG_INVALID(net, IPPROTO_TCP))
794 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 796 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
795 "nf_ct_tcp: invalid TCP flag combination "); 797 "nf_ct_tcp: invalid TCP flag combination ");
796 return -NF_ACCEPT; 798 return -NF_ACCEPT;
@@ -804,9 +806,10 @@ static int tcp_packet(struct nf_conn *ct,
804 const struct sk_buff *skb, 806 const struct sk_buff *skb,
805 unsigned int dataoff, 807 unsigned int dataoff,
806 enum ip_conntrack_info ctinfo, 808 enum ip_conntrack_info ctinfo,
807 int pf, 809 u_int8_t pf,
808 unsigned int hooknum) 810 unsigned int hooknum)
809{ 811{
812 struct net *net = nf_ct_net(ct);
810 struct nf_conntrack_tuple *tuple; 813 struct nf_conntrack_tuple *tuple;
811 enum tcp_conntrack new_state, old_state; 814 enum tcp_conntrack new_state, old_state;
812 enum ip_conntrack_dir dir; 815 enum ip_conntrack_dir dir;
@@ -885,7 +888,7 @@ static int tcp_packet(struct nf_conn *ct,
885 * thus initiate a clean new session. 888 * thus initiate a clean new session.
886 */ 889 */
887 write_unlock_bh(&tcp_lock); 890 write_unlock_bh(&tcp_lock);
888 if (LOG_INVALID(IPPROTO_TCP)) 891 if (LOG_INVALID(net, IPPROTO_TCP))
889 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 892 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
890 "nf_ct_tcp: killing out of sync session "); 893 "nf_ct_tcp: killing out of sync session ");
891 nf_ct_kill(ct); 894 nf_ct_kill(ct);
@@ -898,7 +901,7 @@ static int tcp_packet(struct nf_conn *ct,
898 segment_seq_plus_len(ntohl(th->seq), skb->len, dataoff, th); 901 segment_seq_plus_len(ntohl(th->seq), skb->len, dataoff, th);
899 902
900 write_unlock_bh(&tcp_lock); 903 write_unlock_bh(&tcp_lock);
901 if (LOG_INVALID(IPPROTO_TCP)) 904 if (LOG_INVALID(net, IPPROTO_TCP))
902 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 905 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
903 "nf_ct_tcp: invalid packet ignored "); 906 "nf_ct_tcp: invalid packet ignored ");
904 return NF_ACCEPT; 907 return NF_ACCEPT;
@@ -907,7 +910,7 @@ static int tcp_packet(struct nf_conn *ct,
907 pr_debug("nf_ct_tcp: Invalid dir=%i index=%u ostate=%u\n", 910 pr_debug("nf_ct_tcp: Invalid dir=%i index=%u ostate=%u\n",
908 dir, get_conntrack_index(th), old_state); 911 dir, get_conntrack_index(th), old_state);
909 write_unlock_bh(&tcp_lock); 912 write_unlock_bh(&tcp_lock);
910 if (LOG_INVALID(IPPROTO_TCP)) 913 if (LOG_INVALID(net, IPPROTO_TCP))
911 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 914 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
912 "nf_ct_tcp: invalid state "); 915 "nf_ct_tcp: invalid state ");
913 return -NF_ACCEPT; 916 return -NF_ACCEPT;
@@ -968,9 +971,9 @@ static int tcp_packet(struct nf_conn *ct,
968 timeout = tcp_timeouts[new_state]; 971 timeout = tcp_timeouts[new_state];
969 write_unlock_bh(&tcp_lock); 972 write_unlock_bh(&tcp_lock);
970 973
971 nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, skb); 974 nf_conntrack_event_cache(IPCT_PROTOINFO_VOLATILE, ct);
972 if (new_state != old_state) 975 if (new_state != old_state)
973 nf_conntrack_event_cache(IPCT_PROTOINFO, skb); 976 nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
974 977
975 if (!test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) { 978 if (!test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) {
976 /* If only reply is a RST, we can consider ourselves not to 979 /* If only reply is a RST, we can consider ourselves not to
@@ -989,7 +992,7 @@ static int tcp_packet(struct nf_conn *ct,
989 after SYN_RECV or a valid answer for a picked up 992 after SYN_RECV or a valid answer for a picked up
990 connection. */ 993 connection. */
991 set_bit(IPS_ASSURED_BIT, &ct->status); 994 set_bit(IPS_ASSURED_BIT, &ct->status);
992 nf_conntrack_event_cache(IPCT_STATUS, skb); 995 nf_conntrack_event_cache(IPCT_STATUS, ct);
993 } 996 }
994 nf_ct_refresh_acct(ct, ctinfo, skb, timeout); 997 nf_ct_refresh_acct(ct, ctinfo, skb, timeout);
995 998
diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c
index 8b21762e65de..7c2ca48698be 100644
--- a/net/netfilter/nf_conntrack_proto_udp.c
+++ b/net/netfilter/nf_conntrack_proto_udp.c
@@ -66,7 +66,7 @@ static int udp_packet(struct nf_conn *ct,
66 const struct sk_buff *skb, 66 const struct sk_buff *skb,
67 unsigned int dataoff, 67 unsigned int dataoff,
68 enum ip_conntrack_info ctinfo, 68 enum ip_conntrack_info ctinfo,
69 int pf, 69 u_int8_t pf,
70 unsigned int hooknum) 70 unsigned int hooknum)
71{ 71{
72 /* If we've seen traffic both ways, this is some kind of UDP 72 /* If we've seen traffic both ways, this is some kind of UDP
@@ -75,7 +75,7 @@ static int udp_packet(struct nf_conn *ct,
75 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_udp_timeout_stream); 75 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_udp_timeout_stream);
76 /* Also, more likely to be important, and not a probe */ 76 /* Also, more likely to be important, and not a probe */
77 if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status)) 77 if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status))
78 nf_conntrack_event_cache(IPCT_STATUS, skb); 78 nf_conntrack_event_cache(IPCT_STATUS, ct);
79 } else 79 } else
80 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_udp_timeout); 80 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_udp_timeout);
81 81
@@ -89,9 +89,9 @@ static bool udp_new(struct nf_conn *ct, const struct sk_buff *skb,
89 return true; 89 return true;
90} 90}
91 91
92static int udp_error(struct sk_buff *skb, unsigned int dataoff, 92static int udp_error(struct net *net, struct sk_buff *skb, unsigned int dataoff,
93 enum ip_conntrack_info *ctinfo, 93 enum ip_conntrack_info *ctinfo,
94 int pf, 94 u_int8_t pf,
95 unsigned int hooknum) 95 unsigned int hooknum)
96{ 96{
97 unsigned int udplen = skb->len - dataoff; 97 unsigned int udplen = skb->len - dataoff;
@@ -101,7 +101,7 @@ static int udp_error(struct sk_buff *skb, unsigned int dataoff,
101 /* Header is too small? */ 101 /* Header is too small? */
102 hdr = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr); 102 hdr = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
103 if (hdr == NULL) { 103 if (hdr == NULL) {
104 if (LOG_INVALID(IPPROTO_UDP)) 104 if (LOG_INVALID(net, IPPROTO_UDP))
105 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 105 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
106 "nf_ct_udp: short packet "); 106 "nf_ct_udp: short packet ");
107 return -NF_ACCEPT; 107 return -NF_ACCEPT;
@@ -109,7 +109,7 @@ static int udp_error(struct sk_buff *skb, unsigned int dataoff,
109 109
110 /* Truncated/malformed packets */ 110 /* Truncated/malformed packets */
111 if (ntohs(hdr->len) > udplen || ntohs(hdr->len) < sizeof(*hdr)) { 111 if (ntohs(hdr->len) > udplen || ntohs(hdr->len) < sizeof(*hdr)) {
112 if (LOG_INVALID(IPPROTO_UDP)) 112 if (LOG_INVALID(net, IPPROTO_UDP))
113 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 113 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
114 "nf_ct_udp: truncated/malformed packet "); 114 "nf_ct_udp: truncated/malformed packet ");
115 return -NF_ACCEPT; 115 return -NF_ACCEPT;
@@ -123,9 +123,9 @@ static int udp_error(struct sk_buff *skb, unsigned int dataoff,
123 * We skip checking packets on the outgoing path 123 * We skip checking packets on the outgoing path
124 * because the checksum is assumed to be correct. 124 * because the checksum is assumed to be correct.
125 * FIXME: Source route IP option packets --RR */ 125 * FIXME: Source route IP option packets --RR */
126 if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING && 126 if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
127 nf_checksum(skb, hooknum, dataoff, IPPROTO_UDP, pf)) { 127 nf_checksum(skb, hooknum, dataoff, IPPROTO_UDP, pf)) {
128 if (LOG_INVALID(IPPROTO_UDP)) 128 if (LOG_INVALID(net, IPPROTO_UDP))
129 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 129 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
130 "nf_ct_udp: bad UDP checksum "); 130 "nf_ct_udp: bad UDP checksum ");
131 return -NF_ACCEPT; 131 return -NF_ACCEPT;
diff --git a/net/netfilter/nf_conntrack_proto_udplite.c b/net/netfilter/nf_conntrack_proto_udplite.c
index 1fa62f3c24f1..d22d839e4f94 100644
--- a/net/netfilter/nf_conntrack_proto_udplite.c
+++ b/net/netfilter/nf_conntrack_proto_udplite.c
@@ -65,7 +65,7 @@ static int udplite_packet(struct nf_conn *ct,
65 const struct sk_buff *skb, 65 const struct sk_buff *skb,
66 unsigned int dataoff, 66 unsigned int dataoff,
67 enum ip_conntrack_info ctinfo, 67 enum ip_conntrack_info ctinfo,
68 int pf, 68 u_int8_t pf,
69 unsigned int hooknum) 69 unsigned int hooknum)
70{ 70{
71 /* If we've seen traffic both ways, this is some kind of UDP 71 /* If we've seen traffic both ways, this is some kind of UDP
@@ -75,7 +75,7 @@ static int udplite_packet(struct nf_conn *ct,
75 nf_ct_udplite_timeout_stream); 75 nf_ct_udplite_timeout_stream);
76 /* Also, more likely to be important, and not a probe */ 76 /* Also, more likely to be important, and not a probe */
77 if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status)) 77 if (!test_and_set_bit(IPS_ASSURED_BIT, &ct->status))
78 nf_conntrack_event_cache(IPCT_STATUS, skb); 78 nf_conntrack_event_cache(IPCT_STATUS, ct);
79 } else 79 } else
80 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_udplite_timeout); 80 nf_ct_refresh_acct(ct, ctinfo, skb, nf_ct_udplite_timeout);
81 81
@@ -89,9 +89,11 @@ static bool udplite_new(struct nf_conn *ct, const struct sk_buff *skb,
89 return true; 89 return true;
90} 90}
91 91
92static int udplite_error(struct sk_buff *skb, unsigned int dataoff, 92static int udplite_error(struct net *net,
93 struct sk_buff *skb,
94 unsigned int dataoff,
93 enum ip_conntrack_info *ctinfo, 95 enum ip_conntrack_info *ctinfo,
94 int pf, 96 u_int8_t pf,
95 unsigned int hooknum) 97 unsigned int hooknum)
96{ 98{
97 unsigned int udplen = skb->len - dataoff; 99 unsigned int udplen = skb->len - dataoff;
@@ -102,7 +104,7 @@ static int udplite_error(struct sk_buff *skb, unsigned int dataoff,
102 /* Header is too small? */ 104 /* Header is too small? */
103 hdr = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr); 105 hdr = skb_header_pointer(skb, dataoff, sizeof(_hdr), &_hdr);
104 if (hdr == NULL) { 106 if (hdr == NULL) {
105 if (LOG_INVALID(IPPROTO_UDPLITE)) 107 if (LOG_INVALID(net, IPPROTO_UDPLITE))
106 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 108 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
107 "nf_ct_udplite: short packet "); 109 "nf_ct_udplite: short packet ");
108 return -NF_ACCEPT; 110 return -NF_ACCEPT;
@@ -112,7 +114,7 @@ static int udplite_error(struct sk_buff *skb, unsigned int dataoff,
112 if (cscov == 0) 114 if (cscov == 0)
113 cscov = udplen; 115 cscov = udplen;
114 else if (cscov < sizeof(*hdr) || cscov > udplen) { 116 else if (cscov < sizeof(*hdr) || cscov > udplen) {
115 if (LOG_INVALID(IPPROTO_UDPLITE)) 117 if (LOG_INVALID(net, IPPROTO_UDPLITE))
116 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 118 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
117 "nf_ct_udplite: invalid checksum coverage "); 119 "nf_ct_udplite: invalid checksum coverage ");
118 return -NF_ACCEPT; 120 return -NF_ACCEPT;
@@ -120,17 +122,17 @@ static int udplite_error(struct sk_buff *skb, unsigned int dataoff,
120 122
121 /* UDPLITE mandates checksums */ 123 /* UDPLITE mandates checksums */
122 if (!hdr->check) { 124 if (!hdr->check) {
123 if (LOG_INVALID(IPPROTO_UDPLITE)) 125 if (LOG_INVALID(net, IPPROTO_UDPLITE))
124 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 126 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
125 "nf_ct_udplite: checksum missing "); 127 "nf_ct_udplite: checksum missing ");
126 return -NF_ACCEPT; 128 return -NF_ACCEPT;
127 } 129 }
128 130
129 /* Checksum invalid? Ignore. */ 131 /* Checksum invalid? Ignore. */
130 if (nf_conntrack_checksum && hooknum == NF_INET_PRE_ROUTING && 132 if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
131 nf_checksum_partial(skb, hooknum, dataoff, cscov, IPPROTO_UDP, 133 nf_checksum_partial(skb, hooknum, dataoff, cscov, IPPROTO_UDP,
132 pf)) { 134 pf)) {
133 if (LOG_INVALID(IPPROTO_UDPLITE)) 135 if (LOG_INVALID(net, IPPROTO_UDPLITE))
134 nf_log_packet(pf, 0, skb, NULL, NULL, NULL, 136 nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
135 "nf_ct_udplite: bad UDPLite checksum "); 137 "nf_ct_udplite: bad UDPLite checksum ");
136 return -NF_ACCEPT; 138 return -NF_ACCEPT;
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index 2f9bbc058b48..6813f1c8863f 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -736,6 +736,7 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb,
736 struct nf_conntrack_expect *exp, *rtp_exp, *rtcp_exp; 736 struct nf_conntrack_expect *exp, *rtp_exp, *rtcp_exp;
737 enum ip_conntrack_info ctinfo; 737 enum ip_conntrack_info ctinfo;
738 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 738 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
739 struct net *net = nf_ct_net(ct);
739 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 740 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
740 union nf_inet_addr *saddr; 741 union nf_inet_addr *saddr;
741 struct nf_conntrack_tuple tuple; 742 struct nf_conntrack_tuple tuple;
@@ -775,7 +776,7 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb,
775 776
776 rcu_read_lock(); 777 rcu_read_lock();
777 do { 778 do {
778 exp = __nf_ct_expect_find(&tuple); 779 exp = __nf_ct_expect_find(net, &tuple);
779 780
780 if (!exp || exp->master == ct || 781 if (!exp || exp->master == ct ||
781 nfct_help(exp->master)->helper != nfct_help(ct)->helper || 782 nfct_help(exp->master)->helper != nfct_help(ct)->helper ||
@@ -1193,7 +1194,6 @@ static const struct sip_handler sip_handlers[] = {
1193static int process_sip_response(struct sk_buff *skb, 1194static int process_sip_response(struct sk_buff *skb,
1194 const char **dptr, unsigned int *datalen) 1195 const char **dptr, unsigned int *datalen)
1195{ 1196{
1196 static const struct sip_handler *handler;
1197 enum ip_conntrack_info ctinfo; 1197 enum ip_conntrack_info ctinfo;
1198 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 1198 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
1199 unsigned int matchoff, matchlen; 1199 unsigned int matchoff, matchlen;
@@ -1214,6 +1214,8 @@ static int process_sip_response(struct sk_buff *skb,
1214 dataoff = matchoff + matchlen + 1; 1214 dataoff = matchoff + matchlen + 1;
1215 1215
1216 for (i = 0; i < ARRAY_SIZE(sip_handlers); i++) { 1216 for (i = 0; i < ARRAY_SIZE(sip_handlers); i++) {
1217 const struct sip_handler *handler;
1218
1217 handler = &sip_handlers[i]; 1219 handler = &sip_handlers[i];
1218 if (handler->response == NULL) 1220 if (handler->response == NULL)
1219 continue; 1221 continue;
@@ -1228,13 +1230,14 @@ static int process_sip_response(struct sk_buff *skb,
1228static int process_sip_request(struct sk_buff *skb, 1230static int process_sip_request(struct sk_buff *skb,
1229 const char **dptr, unsigned int *datalen) 1231 const char **dptr, unsigned int *datalen)
1230{ 1232{
1231 static const struct sip_handler *handler;
1232 enum ip_conntrack_info ctinfo; 1233 enum ip_conntrack_info ctinfo;
1233 struct nf_conn *ct = nf_ct_get(skb, &ctinfo); 1234 struct nf_conn *ct = nf_ct_get(skb, &ctinfo);
1234 unsigned int matchoff, matchlen; 1235 unsigned int matchoff, matchlen;
1235 unsigned int cseq, i; 1236 unsigned int cseq, i;
1236 1237
1237 for (i = 0; i < ARRAY_SIZE(sip_handlers); i++) { 1238 for (i = 0; i < ARRAY_SIZE(sip_handlers); i++) {
1239 const struct sip_handler *handler;
1240
1238 handler = &sip_handlers[i]; 1241 handler = &sip_handlers[i];
1239 if (handler->request == NULL) 1242 if (handler->request == NULL)
1240 continue; 1243 continue;
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 8509db14670b..98106d4e89f0 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -40,18 +40,20 @@ print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple,
40EXPORT_SYMBOL_GPL(print_tuple); 40EXPORT_SYMBOL_GPL(print_tuple);
41 41
42struct ct_iter_state { 42struct ct_iter_state {
43 struct seq_net_private p;
43 unsigned int bucket; 44 unsigned int bucket;
44}; 45};
45 46
46static struct hlist_node *ct_get_first(struct seq_file *seq) 47static struct hlist_node *ct_get_first(struct seq_file *seq)
47{ 48{
49 struct net *net = seq_file_net(seq);
48 struct ct_iter_state *st = seq->private; 50 struct ct_iter_state *st = seq->private;
49 struct hlist_node *n; 51 struct hlist_node *n;
50 52
51 for (st->bucket = 0; 53 for (st->bucket = 0;
52 st->bucket < nf_conntrack_htable_size; 54 st->bucket < nf_conntrack_htable_size;
53 st->bucket++) { 55 st->bucket++) {
54 n = rcu_dereference(nf_conntrack_hash[st->bucket].first); 56 n = rcu_dereference(net->ct.hash[st->bucket].first);
55 if (n) 57 if (n)
56 return n; 58 return n;
57 } 59 }
@@ -61,13 +63,14 @@ static struct hlist_node *ct_get_first(struct seq_file *seq)
61static struct hlist_node *ct_get_next(struct seq_file *seq, 63static struct hlist_node *ct_get_next(struct seq_file *seq,
62 struct hlist_node *head) 64 struct hlist_node *head)
63{ 65{
66 struct net *net = seq_file_net(seq);
64 struct ct_iter_state *st = seq->private; 67 struct ct_iter_state *st = seq->private;
65 68
66 head = rcu_dereference(head->next); 69 head = rcu_dereference(head->next);
67 while (head == NULL) { 70 while (head == NULL) {
68 if (++st->bucket >= nf_conntrack_htable_size) 71 if (++st->bucket >= nf_conntrack_htable_size)
69 return NULL; 72 return NULL;
70 head = rcu_dereference(nf_conntrack_hash[st->bucket].first); 73 head = rcu_dereference(net->ct.hash[st->bucket].first);
71 } 74 }
72 return head; 75 return head;
73} 76}
@@ -177,7 +180,7 @@ static const struct seq_operations ct_seq_ops = {
177 180
178static int ct_open(struct inode *inode, struct file *file) 181static int ct_open(struct inode *inode, struct file *file)
179{ 182{
180 return seq_open_private(file, &ct_seq_ops, 183 return seq_open_net(inode, file, &ct_seq_ops,
181 sizeof(struct ct_iter_state)); 184 sizeof(struct ct_iter_state));
182} 185}
183 186
@@ -186,11 +189,12 @@ static const struct file_operations ct_file_ops = {
186 .open = ct_open, 189 .open = ct_open,
187 .read = seq_read, 190 .read = seq_read,
188 .llseek = seq_lseek, 191 .llseek = seq_lseek,
189 .release = seq_release_private, 192 .release = seq_release_net,
190}; 193};
191 194
192static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos) 195static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
193{ 196{
197 struct net *net = seq_file_net(seq);
194 int cpu; 198 int cpu;
195 199
196 if (*pos == 0) 200 if (*pos == 0)
@@ -200,7 +204,7 @@ static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
200 if (!cpu_possible(cpu)) 204 if (!cpu_possible(cpu))
201 continue; 205 continue;
202 *pos = cpu + 1; 206 *pos = cpu + 1;
203 return &per_cpu(nf_conntrack_stat, cpu); 207 return per_cpu_ptr(net->ct.stat, cpu);
204 } 208 }
205 209
206 return NULL; 210 return NULL;
@@ -208,13 +212,14 @@ static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
208 212
209static void *ct_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos) 213static void *ct_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos)
210{ 214{
215 struct net *net = seq_file_net(seq);
211 int cpu; 216 int cpu;
212 217
213 for (cpu = *pos; cpu < NR_CPUS; ++cpu) { 218 for (cpu = *pos; cpu < NR_CPUS; ++cpu) {
214 if (!cpu_possible(cpu)) 219 if (!cpu_possible(cpu))
215 continue; 220 continue;
216 *pos = cpu + 1; 221 *pos = cpu + 1;
217 return &per_cpu(nf_conntrack_stat, cpu); 222 return per_cpu_ptr(net->ct.stat, cpu);
218 } 223 }
219 224
220 return NULL; 225 return NULL;
@@ -226,7 +231,8 @@ static void ct_cpu_seq_stop(struct seq_file *seq, void *v)
226 231
227static int ct_cpu_seq_show(struct seq_file *seq, void *v) 232static int ct_cpu_seq_show(struct seq_file *seq, void *v)
228{ 233{
229 unsigned int nr_conntracks = atomic_read(&nf_conntrack_count); 234 struct net *net = seq_file_net(seq);
235 unsigned int nr_conntracks = atomic_read(&net->ct.count);
230 const struct ip_conntrack_stat *st = v; 236 const struct ip_conntrack_stat *st = v;
231 237
232 if (v == SEQ_START_TOKEN) { 238 if (v == SEQ_START_TOKEN) {
@@ -266,7 +272,8 @@ static const struct seq_operations ct_cpu_seq_ops = {
266 272
267static int ct_cpu_seq_open(struct inode *inode, struct file *file) 273static int ct_cpu_seq_open(struct inode *inode, struct file *file)
268{ 274{
269 return seq_open(file, &ct_cpu_seq_ops); 275 return seq_open_net(inode, file, &ct_cpu_seq_ops,
276 sizeof(struct seq_net_private));
270} 277}
271 278
272static const struct file_operations ct_cpu_seq_fops = { 279static const struct file_operations ct_cpu_seq_fops = {
@@ -274,56 +281,52 @@ static const struct file_operations ct_cpu_seq_fops = {
274 .open = ct_cpu_seq_open, 281 .open = ct_cpu_seq_open,
275 .read = seq_read, 282 .read = seq_read,
276 .llseek = seq_lseek, 283 .llseek = seq_lseek,
277 .release = seq_release, 284 .release = seq_release_net,
278}; 285};
279 286
280static int nf_conntrack_standalone_init_proc(void) 287static int nf_conntrack_standalone_init_proc(struct net *net)
281{ 288{
282 struct proc_dir_entry *pde; 289 struct proc_dir_entry *pde;
283 290
284 pde = proc_net_fops_create(&init_net, "nf_conntrack", 0440, &ct_file_ops); 291 pde = proc_net_fops_create(net, "nf_conntrack", 0440, &ct_file_ops);
285 if (!pde) 292 if (!pde)
286 goto out_nf_conntrack; 293 goto out_nf_conntrack;
287 294
288 pde = proc_create("nf_conntrack", S_IRUGO, init_net.proc_net_stat, 295 pde = proc_create("nf_conntrack", S_IRUGO, net->proc_net_stat,
289 &ct_cpu_seq_fops); 296 &ct_cpu_seq_fops);
290 if (!pde) 297 if (!pde)
291 goto out_stat_nf_conntrack; 298 goto out_stat_nf_conntrack;
292 return 0; 299 return 0;
293 300
294out_stat_nf_conntrack: 301out_stat_nf_conntrack:
295 proc_net_remove(&init_net, "nf_conntrack"); 302 proc_net_remove(net, "nf_conntrack");
296out_nf_conntrack: 303out_nf_conntrack:
297 return -ENOMEM; 304 return -ENOMEM;
298} 305}
299 306
300static void nf_conntrack_standalone_fini_proc(void) 307static void nf_conntrack_standalone_fini_proc(struct net *net)
301{ 308{
302 remove_proc_entry("nf_conntrack", init_net.proc_net_stat); 309 remove_proc_entry("nf_conntrack", net->proc_net_stat);
303 proc_net_remove(&init_net, "nf_conntrack"); 310 proc_net_remove(net, "nf_conntrack");
304} 311}
305#else 312#else
306static int nf_conntrack_standalone_init_proc(void) 313static int nf_conntrack_standalone_init_proc(struct net *net)
307{ 314{
308 return 0; 315 return 0;
309} 316}
310 317
311static void nf_conntrack_standalone_fini_proc(void) 318static void nf_conntrack_standalone_fini_proc(struct net *net)
312{ 319{
313} 320}
314#endif /* CONFIG_PROC_FS */ 321#endif /* CONFIG_PROC_FS */
315 322
316/* Sysctl support */ 323/* Sysctl support */
317 324
318int nf_conntrack_checksum __read_mostly = 1;
319EXPORT_SYMBOL_GPL(nf_conntrack_checksum);
320
321#ifdef CONFIG_SYSCTL 325#ifdef CONFIG_SYSCTL
322/* Log invalid packets of a given protocol */ 326/* Log invalid packets of a given protocol */
323static int log_invalid_proto_min = 0; 327static int log_invalid_proto_min = 0;
324static int log_invalid_proto_max = 255; 328static int log_invalid_proto_max = 255;
325 329
326static struct ctl_table_header *nf_ct_sysctl_header;
327static struct ctl_table_header *nf_ct_netfilter_header; 330static struct ctl_table_header *nf_ct_netfilter_header;
328 331
329static ctl_table nf_ct_sysctl_table[] = { 332static ctl_table nf_ct_sysctl_table[] = {
@@ -338,7 +341,7 @@ static ctl_table nf_ct_sysctl_table[] = {
338 { 341 {
339 .ctl_name = NET_NF_CONNTRACK_COUNT, 342 .ctl_name = NET_NF_CONNTRACK_COUNT,
340 .procname = "nf_conntrack_count", 343 .procname = "nf_conntrack_count",
341 .data = &nf_conntrack_count, 344 .data = &init_net.ct.count,
342 .maxlen = sizeof(int), 345 .maxlen = sizeof(int),
343 .mode = 0444, 346 .mode = 0444,
344 .proc_handler = &proc_dointvec, 347 .proc_handler = &proc_dointvec,
@@ -354,7 +357,7 @@ static ctl_table nf_ct_sysctl_table[] = {
354 { 357 {
355 .ctl_name = NET_NF_CONNTRACK_CHECKSUM, 358 .ctl_name = NET_NF_CONNTRACK_CHECKSUM,
356 .procname = "nf_conntrack_checksum", 359 .procname = "nf_conntrack_checksum",
357 .data = &nf_conntrack_checksum, 360 .data = &init_net.ct.sysctl_checksum,
358 .maxlen = sizeof(unsigned int), 361 .maxlen = sizeof(unsigned int),
359 .mode = 0644, 362 .mode = 0644,
360 .proc_handler = &proc_dointvec, 363 .proc_handler = &proc_dointvec,
@@ -362,7 +365,7 @@ static ctl_table nf_ct_sysctl_table[] = {
362 { 365 {
363 .ctl_name = NET_NF_CONNTRACK_LOG_INVALID, 366 .ctl_name = NET_NF_CONNTRACK_LOG_INVALID,
364 .procname = "nf_conntrack_log_invalid", 367 .procname = "nf_conntrack_log_invalid",
365 .data = &nf_ct_log_invalid, 368 .data = &init_net.ct.sysctl_log_invalid,
366 .maxlen = sizeof(unsigned int), 369 .maxlen = sizeof(unsigned int),
367 .mode = 0644, 370 .mode = 0644,
368 .proc_handler = &proc_dointvec_minmax, 371 .proc_handler = &proc_dointvec_minmax,
@@ -400,74 +403,109 @@ static struct ctl_path nf_ct_path[] = {
400 { } 403 { }
401}; 404};
402 405
403EXPORT_SYMBOL_GPL(nf_ct_log_invalid); 406static int nf_conntrack_standalone_init_sysctl(struct net *net)
404
405static int nf_conntrack_standalone_init_sysctl(void)
406{ 407{
407 nf_ct_netfilter_header = 408 struct ctl_table *table;
408 register_sysctl_paths(nf_ct_path, nf_ct_netfilter_table); 409
409 if (!nf_ct_netfilter_header) 410 if (net_eq(net, &init_net)) {
410 goto out; 411 nf_ct_netfilter_header =
411 412 register_sysctl_paths(nf_ct_path, nf_ct_netfilter_table);
412 nf_ct_sysctl_header = 413 if (!nf_ct_netfilter_header)
413 register_sysctl_paths(nf_net_netfilter_sysctl_path, 414 goto out;
414 nf_ct_sysctl_table); 415 }
415 if (!nf_ct_sysctl_header) 416
417 table = kmemdup(nf_ct_sysctl_table, sizeof(nf_ct_sysctl_table),
418 GFP_KERNEL);
419 if (!table)
420 goto out_kmemdup;
421
422 table[1].data = &net->ct.count;
423 table[3].data = &net->ct.sysctl_checksum;
424 table[4].data = &net->ct.sysctl_log_invalid;
425
426 net->ct.sysctl_header = register_net_sysctl_table(net,
427 nf_net_netfilter_sysctl_path, table);
428 if (!net->ct.sysctl_header)
416 goto out_unregister_netfilter; 429 goto out_unregister_netfilter;
417 430
418 return 0; 431 return 0;
419 432
420out_unregister_netfilter: 433out_unregister_netfilter:
421 unregister_sysctl_table(nf_ct_netfilter_header); 434 kfree(table);
435out_kmemdup:
436 if (net_eq(net, &init_net))
437 unregister_sysctl_table(nf_ct_netfilter_header);
422out: 438out:
423 printk("nf_conntrack: can't register to sysctl.\n"); 439 printk("nf_conntrack: can't register to sysctl.\n");
424 return -ENOMEM; 440 return -ENOMEM;
425} 441}
426 442
427static void nf_conntrack_standalone_fini_sysctl(void) 443static void nf_conntrack_standalone_fini_sysctl(struct net *net)
428{ 444{
429 unregister_sysctl_table(nf_ct_netfilter_header); 445 struct ctl_table *table;
430 unregister_sysctl_table(nf_ct_sysctl_header); 446
447 if (net_eq(net, &init_net))
448 unregister_sysctl_table(nf_ct_netfilter_header);
449 table = net->ct.sysctl_header->ctl_table_arg;
450 unregister_net_sysctl_table(net->ct.sysctl_header);
451 kfree(table);
431} 452}
432#else 453#else
433static int nf_conntrack_standalone_init_sysctl(void) 454static int nf_conntrack_standalone_init_sysctl(struct net *net)
434{ 455{
435 return 0; 456 return 0;
436} 457}
437 458
438static void nf_conntrack_standalone_fini_sysctl(void) 459static void nf_conntrack_standalone_fini_sysctl(struct net *net)
439{ 460{
440} 461}
441#endif /* CONFIG_SYSCTL */ 462#endif /* CONFIG_SYSCTL */
442 463
443static int __init nf_conntrack_standalone_init(void) 464static int nf_conntrack_net_init(struct net *net)
444{ 465{
445 int ret; 466 int ret;
446 467
447 ret = nf_conntrack_init(); 468 ret = nf_conntrack_init(net);
448 if (ret < 0) 469 if (ret < 0)
449 goto out; 470 goto out_init;
450 ret = nf_conntrack_standalone_init_proc(); 471 ret = nf_conntrack_standalone_init_proc(net);
451 if (ret < 0) 472 if (ret < 0)
452 goto out_proc; 473 goto out_proc;
453 ret = nf_conntrack_standalone_init_sysctl(); 474 net->ct.sysctl_checksum = 1;
475 net->ct.sysctl_log_invalid = 0;
476 ret = nf_conntrack_standalone_init_sysctl(net);
454 if (ret < 0) 477 if (ret < 0)
455 goto out_sysctl; 478 goto out_sysctl;
456 return 0; 479 return 0;
457 480
458out_sysctl: 481out_sysctl:
459 nf_conntrack_standalone_fini_proc(); 482 nf_conntrack_standalone_fini_proc(net);
460out_proc: 483out_proc:
461 nf_conntrack_cleanup(); 484 nf_conntrack_cleanup(net);
462out: 485out_init:
463 return ret; 486 return ret;
464} 487}
465 488
489static void nf_conntrack_net_exit(struct net *net)
490{
491 nf_conntrack_standalone_fini_sysctl(net);
492 nf_conntrack_standalone_fini_proc(net);
493 nf_conntrack_cleanup(net);
494}
495
496static struct pernet_operations nf_conntrack_net_ops = {
497 .init = nf_conntrack_net_init,
498 .exit = nf_conntrack_net_exit,
499};
500
501static int __init nf_conntrack_standalone_init(void)
502{
503 return register_pernet_subsys(&nf_conntrack_net_ops);
504}
505
466static void __exit nf_conntrack_standalone_fini(void) 506static void __exit nf_conntrack_standalone_fini(void)
467{ 507{
468 nf_conntrack_standalone_fini_sysctl(); 508 unregister_pernet_subsys(&nf_conntrack_net_ops);
469 nf_conntrack_standalone_fini_proc();
470 nf_conntrack_cleanup();
471} 509}
472 510
473module_init(nf_conntrack_standalone_init); 511module_init(nf_conntrack_standalone_init);
diff --git a/net/netfilter/nf_internals.h b/net/netfilter/nf_internals.h
index 196269c1e586..bf6609978af7 100644
--- a/net/netfilter/nf_internals.h
+++ b/net/netfilter/nf_internals.h
@@ -15,7 +15,7 @@
15/* core.c */ 15/* core.c */
16extern unsigned int nf_iterate(struct list_head *head, 16extern unsigned int nf_iterate(struct list_head *head,
17 struct sk_buff *skb, 17 struct sk_buff *skb,
18 int hook, 18 unsigned int hook,
19 const struct net_device *indev, 19 const struct net_device *indev,
20 const struct net_device *outdev, 20 const struct net_device *outdev,
21 struct list_head **i, 21 struct list_head **i,
@@ -25,7 +25,7 @@ extern unsigned int nf_iterate(struct list_head *head,
25/* nf_queue.c */ 25/* nf_queue.c */
26extern int nf_queue(struct sk_buff *skb, 26extern int nf_queue(struct sk_buff *skb,
27 struct list_head *elem, 27 struct list_head *elem,
28 int pf, unsigned int hook, 28 u_int8_t pf, unsigned int hook,
29 struct net_device *indev, 29 struct net_device *indev,
30 struct net_device *outdev, 30 struct net_device *outdev,
31 int (*okfn)(struct sk_buff *), 31 int (*okfn)(struct sk_buff *),
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
index 9fda6ee95a31..fa8ae5d2659c 100644
--- a/net/netfilter/nf_log.c
+++ b/net/netfilter/nf_log.c
@@ -15,16 +15,16 @@
15 15
16#define NF_LOG_PREFIXLEN 128 16#define NF_LOG_PREFIXLEN 128
17 17
18static const struct nf_logger *nf_loggers[NPROTO] __read_mostly; 18static const struct nf_logger *nf_loggers[NFPROTO_NUMPROTO] __read_mostly;
19static DEFINE_MUTEX(nf_log_mutex); 19static DEFINE_MUTEX(nf_log_mutex);
20 20
21/* return EBUSY if somebody else is registered, EEXIST if the same logger 21/* return EBUSY if somebody else is registered, EEXIST if the same logger
22 * is registred, 0 on success. */ 22 * is registred, 0 on success. */
23int nf_log_register(int pf, const struct nf_logger *logger) 23int nf_log_register(u_int8_t pf, const struct nf_logger *logger)
24{ 24{
25 int ret; 25 int ret;
26 26
27 if (pf >= NPROTO) 27 if (pf >= ARRAY_SIZE(nf_loggers))
28 return -EINVAL; 28 return -EINVAL;
29 29
30 /* Any setup of logging members must be done before 30 /* Any setup of logging members must be done before
@@ -45,9 +45,9 @@ int nf_log_register(int pf, const struct nf_logger *logger)
45} 45}
46EXPORT_SYMBOL(nf_log_register); 46EXPORT_SYMBOL(nf_log_register);
47 47
48void nf_log_unregister_pf(int pf) 48void nf_log_unregister_pf(u_int8_t pf)
49{ 49{
50 if (pf >= NPROTO) 50 if (pf >= ARRAY_SIZE(nf_loggers))
51 return; 51 return;
52 mutex_lock(&nf_log_mutex); 52 mutex_lock(&nf_log_mutex);
53 rcu_assign_pointer(nf_loggers[pf], NULL); 53 rcu_assign_pointer(nf_loggers[pf], NULL);
@@ -63,7 +63,7 @@ void nf_log_unregister(const struct nf_logger *logger)
63 int i; 63 int i;
64 64
65 mutex_lock(&nf_log_mutex); 65 mutex_lock(&nf_log_mutex);
66 for (i = 0; i < NPROTO; i++) { 66 for (i = 0; i < ARRAY_SIZE(nf_loggers); i++) {
67 if (nf_loggers[i] == logger) 67 if (nf_loggers[i] == logger)
68 rcu_assign_pointer(nf_loggers[i], NULL); 68 rcu_assign_pointer(nf_loggers[i], NULL);
69 } 69 }
@@ -73,7 +73,7 @@ void nf_log_unregister(const struct nf_logger *logger)
73} 73}
74EXPORT_SYMBOL(nf_log_unregister); 74EXPORT_SYMBOL(nf_log_unregister);
75 75
76void nf_log_packet(int pf, 76void nf_log_packet(u_int8_t pf,
77 unsigned int hooknum, 77 unsigned int hooknum,
78 const struct sk_buff *skb, 78 const struct sk_buff *skb,
79 const struct net_device *in, 79 const struct net_device *in,
@@ -103,7 +103,7 @@ static void *seq_start(struct seq_file *seq, loff_t *pos)
103{ 103{
104 rcu_read_lock(); 104 rcu_read_lock();
105 105
106 if (*pos >= NPROTO) 106 if (*pos >= ARRAY_SIZE(nf_loggers))
107 return NULL; 107 return NULL;
108 108
109 return pos; 109 return pos;
@@ -113,7 +113,7 @@ static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
113{ 113{
114 (*pos)++; 114 (*pos)++;
115 115
116 if (*pos >= NPROTO) 116 if (*pos >= ARRAY_SIZE(nf_loggers))
117 return NULL; 117 return NULL;
118 118
119 return pos; 119 return pos;
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
index 582ec3efc8a5..4f2310c93e01 100644
--- a/net/netfilter/nf_queue.c
+++ b/net/netfilter/nf_queue.c
@@ -16,17 +16,17 @@
16 * long term mutex. The handler must provide an an outfn() to accept packets 16 * long term mutex. The handler must provide an an outfn() to accept packets
17 * for queueing and must reinject all packets it receives, no matter what. 17 * for queueing and must reinject all packets it receives, no matter what.
18 */ 18 */
19static const struct nf_queue_handler *queue_handler[NPROTO]; 19static const struct nf_queue_handler *queue_handler[NFPROTO_NUMPROTO] __read_mostly;
20 20
21static DEFINE_MUTEX(queue_handler_mutex); 21static DEFINE_MUTEX(queue_handler_mutex);
22 22
23/* return EBUSY when somebody else is registered, return EEXIST if the 23/* return EBUSY when somebody else is registered, return EEXIST if the
24 * same handler is registered, return 0 in case of success. */ 24 * same handler is registered, return 0 in case of success. */
25int nf_register_queue_handler(int pf, const struct nf_queue_handler *qh) 25int nf_register_queue_handler(u_int8_t pf, const struct nf_queue_handler *qh)
26{ 26{
27 int ret; 27 int ret;
28 28
29 if (pf >= NPROTO) 29 if (pf >= ARRAY_SIZE(queue_handler))
30 return -EINVAL; 30 return -EINVAL;
31 31
32 mutex_lock(&queue_handler_mutex); 32 mutex_lock(&queue_handler_mutex);
@@ -45,9 +45,9 @@ int nf_register_queue_handler(int pf, const struct nf_queue_handler *qh)
45EXPORT_SYMBOL(nf_register_queue_handler); 45EXPORT_SYMBOL(nf_register_queue_handler);
46 46
47/* The caller must flush their queue before this */ 47/* The caller must flush their queue before this */
48int nf_unregister_queue_handler(int pf, const struct nf_queue_handler *qh) 48int nf_unregister_queue_handler(u_int8_t pf, const struct nf_queue_handler *qh)
49{ 49{
50 if (pf >= NPROTO) 50 if (pf >= ARRAY_SIZE(queue_handler))
51 return -EINVAL; 51 return -EINVAL;
52 52
53 mutex_lock(&queue_handler_mutex); 53 mutex_lock(&queue_handler_mutex);
@@ -67,10 +67,10 @@ EXPORT_SYMBOL(nf_unregister_queue_handler);
67 67
68void nf_unregister_queue_handlers(const struct nf_queue_handler *qh) 68void nf_unregister_queue_handlers(const struct nf_queue_handler *qh)
69{ 69{
70 int pf; 70 u_int8_t pf;
71 71
72 mutex_lock(&queue_handler_mutex); 72 mutex_lock(&queue_handler_mutex);
73 for (pf = 0; pf < NPROTO; pf++) { 73 for (pf = 0; pf < ARRAY_SIZE(queue_handler); pf++) {
74 if (queue_handler[pf] == qh) 74 if (queue_handler[pf] == qh)
75 rcu_assign_pointer(queue_handler[pf], NULL); 75 rcu_assign_pointer(queue_handler[pf], NULL);
76 } 76 }
@@ -107,7 +107,7 @@ static void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
107 */ 107 */
108static int __nf_queue(struct sk_buff *skb, 108static int __nf_queue(struct sk_buff *skb,
109 struct list_head *elem, 109 struct list_head *elem,
110 int pf, unsigned int hook, 110 u_int8_t pf, unsigned int hook,
111 struct net_device *indev, 111 struct net_device *indev,
112 struct net_device *outdev, 112 struct net_device *outdev,
113 int (*okfn)(struct sk_buff *), 113 int (*okfn)(struct sk_buff *),
@@ -191,7 +191,7 @@ err:
191 191
192int nf_queue(struct sk_buff *skb, 192int nf_queue(struct sk_buff *skb,
193 struct list_head *elem, 193 struct list_head *elem,
194 int pf, unsigned int hook, 194 u_int8_t pf, unsigned int hook,
195 struct net_device *indev, 195 struct net_device *indev,
196 struct net_device *outdev, 196 struct net_device *outdev,
197 int (*okfn)(struct sk_buff *), 197 int (*okfn)(struct sk_buff *),
@@ -285,7 +285,7 @@ EXPORT_SYMBOL(nf_reinject);
285#ifdef CONFIG_PROC_FS 285#ifdef CONFIG_PROC_FS
286static void *seq_start(struct seq_file *seq, loff_t *pos) 286static void *seq_start(struct seq_file *seq, loff_t *pos)
287{ 287{
288 if (*pos >= NPROTO) 288 if (*pos >= ARRAY_SIZE(queue_handler))
289 return NULL; 289 return NULL;
290 290
291 return pos; 291 return pos;
@@ -295,7 +295,7 @@ static void *seq_next(struct seq_file *s, void *v, loff_t *pos)
295{ 295{
296 (*pos)++; 296 (*pos)++;
297 297
298 if (*pos >= NPROTO) 298 if (*pos >= ARRAY_SIZE(queue_handler))
299 return NULL; 299 return NULL;
300 300
301 return pos; 301 return pos;
diff --git a/net/netfilter/nf_sockopt.c b/net/netfilter/nf_sockopt.c
index 01489681fa96..8ab829f86574 100644
--- a/net/netfilter/nf_sockopt.c
+++ b/net/netfilter/nf_sockopt.c
@@ -60,14 +60,11 @@ void nf_unregister_sockopt(struct nf_sockopt_ops *reg)
60} 60}
61EXPORT_SYMBOL(nf_unregister_sockopt); 61EXPORT_SYMBOL(nf_unregister_sockopt);
62 62
63static struct nf_sockopt_ops *nf_sockopt_find(struct sock *sk, int pf, 63static struct nf_sockopt_ops *nf_sockopt_find(struct sock *sk, u_int8_t pf,
64 int val, int get) 64 int val, int get)
65{ 65{
66 struct nf_sockopt_ops *ops; 66 struct nf_sockopt_ops *ops;
67 67
68 if (!net_eq(sock_net(sk), &init_net))
69 return ERR_PTR(-ENOPROTOOPT);
70
71 if (mutex_lock_interruptible(&nf_sockopt_mutex) != 0) 68 if (mutex_lock_interruptible(&nf_sockopt_mutex) != 0)
72 return ERR_PTR(-EINTR); 69 return ERR_PTR(-EINTR);
73 70
@@ -96,7 +93,7 @@ out:
96} 93}
97 94
98/* Call get/setsockopt() */ 95/* Call get/setsockopt() */
99static int nf_sockopt(struct sock *sk, int pf, int val, 96static int nf_sockopt(struct sock *sk, u_int8_t pf, int val,
100 char __user *opt, int *len, int get) 97 char __user *opt, int *len, int get)
101{ 98{
102 struct nf_sockopt_ops *ops; 99 struct nf_sockopt_ops *ops;
@@ -115,21 +112,22 @@ static int nf_sockopt(struct sock *sk, int pf, int val,
115 return ret; 112 return ret;
116} 113}
117 114
118int nf_setsockopt(struct sock *sk, int pf, int val, char __user *opt, 115int nf_setsockopt(struct sock *sk, u_int8_t pf, int val, char __user *opt,
119 int len) 116 int len)
120{ 117{
121 return nf_sockopt(sk, pf, val, opt, &len, 0); 118 return nf_sockopt(sk, pf, val, opt, &len, 0);
122} 119}
123EXPORT_SYMBOL(nf_setsockopt); 120EXPORT_SYMBOL(nf_setsockopt);
124 121
125int nf_getsockopt(struct sock *sk, int pf, int val, char __user *opt, int *len) 122int nf_getsockopt(struct sock *sk, u_int8_t pf, int val, char __user *opt,
123 int *len)
126{ 124{
127 return nf_sockopt(sk, pf, val, opt, len, 1); 125 return nf_sockopt(sk, pf, val, opt, len, 1);
128} 126}
129EXPORT_SYMBOL(nf_getsockopt); 127EXPORT_SYMBOL(nf_getsockopt);
130 128
131#ifdef CONFIG_COMPAT 129#ifdef CONFIG_COMPAT
132static int compat_nf_sockopt(struct sock *sk, int pf, int val, 130static int compat_nf_sockopt(struct sock *sk, u_int8_t pf, int val,
133 char __user *opt, int *len, int get) 131 char __user *opt, int *len, int get)
134{ 132{
135 struct nf_sockopt_ops *ops; 133 struct nf_sockopt_ops *ops;
@@ -155,14 +153,14 @@ static int compat_nf_sockopt(struct sock *sk, int pf, int val,
155 return ret; 153 return ret;
156} 154}
157 155
158int compat_nf_setsockopt(struct sock *sk, int pf, 156int compat_nf_setsockopt(struct sock *sk, u_int8_t pf,
159 int val, char __user *opt, int len) 157 int val, char __user *opt, int len)
160{ 158{
161 return compat_nf_sockopt(sk, pf, val, opt, &len, 0); 159 return compat_nf_sockopt(sk, pf, val, opt, &len, 0);
162} 160}
163EXPORT_SYMBOL(compat_nf_setsockopt); 161EXPORT_SYMBOL(compat_nf_setsockopt);
164 162
165int compat_nf_getsockopt(struct sock *sk, int pf, 163int compat_nf_getsockopt(struct sock *sk, u_int8_t pf,
166 int val, char __user *opt, int *len) 164 int val, char __user *opt, int *len)
167{ 165{
168 return compat_nf_sockopt(sk, pf, val, opt, len, 1); 166 return compat_nf_sockopt(sk, pf, val, opt, len, 1);
diff --git a/net/netfilter/nf_tproxy_core.c b/net/netfilter/nf_tproxy_core.c
new file mode 100644
index 000000000000..fe34f4bf74cc
--- /dev/null
+++ b/net/netfilter/nf_tproxy_core.c
@@ -0,0 +1,96 @@
1/*
2 * Transparent proxy support for Linux/iptables
3 *
4 * Copyright (c) 2006-2007 BalaBit IT Ltd.
5 * Author: Balazs Scheidler, Krisztian Kovacs
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 */
12
13#include <linux/version.h>
14#include <linux/module.h>
15
16#include <linux/net.h>
17#include <linux/if.h>
18#include <linux/netdevice.h>
19#include <net/udp.h>
20#include <net/netfilter/nf_tproxy_core.h>
21
22struct sock *
23nf_tproxy_get_sock_v4(struct net *net, const u8 protocol,
24 const __be32 saddr, const __be32 daddr,
25 const __be16 sport, const __be16 dport,
26 const struct net_device *in, bool listening_only)
27{
28 struct sock *sk;
29
30 /* look up socket */
31 switch (protocol) {
32 case IPPROTO_TCP:
33 if (listening_only)
34 sk = __inet_lookup_listener(net, &tcp_hashinfo,
35 daddr, ntohs(dport),
36 in->ifindex);
37 else
38 sk = __inet_lookup(net, &tcp_hashinfo,
39 saddr, sport, daddr, dport,
40 in->ifindex);
41 break;
42 case IPPROTO_UDP:
43 sk = udp4_lib_lookup(net, saddr, sport, daddr, dport,
44 in->ifindex);
45 break;
46 default:
47 WARN_ON(1);
48 sk = NULL;
49 }
50
51 pr_debug("tproxy socket lookup: proto %u %08x:%u -> %08x:%u, listener only: %d, sock %p\n",
52 protocol, ntohl(saddr), ntohs(sport), ntohl(daddr), ntohs(dport), listening_only, sk);
53
54 return sk;
55}
56EXPORT_SYMBOL_GPL(nf_tproxy_get_sock_v4);
57
58static void
59nf_tproxy_destructor(struct sk_buff *skb)
60{
61 struct sock *sk = skb->sk;
62
63 skb->sk = NULL;
64 skb->destructor = NULL;
65
66 if (sk)
67 nf_tproxy_put_sock(sk);
68}
69
70/* consumes sk */
71int
72nf_tproxy_assign_sock(struct sk_buff *skb, struct sock *sk)
73{
74 if (inet_sk(sk)->transparent) {
75 skb->sk = sk;
76 skb->destructor = nf_tproxy_destructor;
77 return 1;
78 } else
79 nf_tproxy_put_sock(sk);
80
81 return 0;
82}
83EXPORT_SYMBOL_GPL(nf_tproxy_assign_sock);
84
85static int __init nf_tproxy_init(void)
86{
87 pr_info("NF_TPROXY: Transparent proxy support initialized, version 4.1.0\n");
88 pr_info("NF_TPROXY: Copyright (c) 2006-2007 BalaBit IT Ltd.\n");
89 return 0;
90}
91
92module_init(nf_tproxy_init);
93
94MODULE_LICENSE("GPL");
95MODULE_AUTHOR("Krisztian Kovacs");
96MODULE_DESCRIPTION("Transparent proxy support core routines");
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 9a35b57ab76d..41e0105d3828 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -359,7 +359,7 @@ static inline int
359__build_packet_message(struct nfulnl_instance *inst, 359__build_packet_message(struct nfulnl_instance *inst,
360 const struct sk_buff *skb, 360 const struct sk_buff *skb,
361 unsigned int data_len, 361 unsigned int data_len,
362 unsigned int pf, 362 u_int8_t pf,
363 unsigned int hooknum, 363 unsigned int hooknum,
364 const struct net_device *indev, 364 const struct net_device *indev,
365 const struct net_device *outdev, 365 const struct net_device *outdev,
@@ -534,7 +534,7 @@ static struct nf_loginfo default_loginfo = {
534 534
535/* log handler for internal netfilter logging api */ 535/* log handler for internal netfilter logging api */
536static void 536static void
537nfulnl_log_packet(unsigned int pf, 537nfulnl_log_packet(u_int8_t pf,
538 unsigned int hooknum, 538 unsigned int hooknum,
539 const struct sk_buff *skb, 539 const struct sk_buff *skb,
540 const struct net_device *in, 540 const struct net_device *in,
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 5d75cd86ebb3..89837a4eef76 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -30,7 +30,7 @@
30 30
31MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
32MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 32MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
33MODULE_DESCRIPTION("[ip,ip6,arp]_tables backend module"); 33MODULE_DESCRIPTION("{ip,ip6,arp,eb}_tables backend module");
34 34
35#define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1)) 35#define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1))
36 36
@@ -58,17 +58,20 @@ static struct xt_af *xt;
58#define duprintf(format, args...) 58#define duprintf(format, args...)
59#endif 59#endif
60 60
61static const char *const xt_prefix[NPROTO] = { 61static const char *const xt_prefix[NFPROTO_NUMPROTO] = {
62 [AF_INET] = "ip", 62 [NFPROTO_UNSPEC] = "x",
63 [AF_INET6] = "ip6", 63 [NFPROTO_IPV4] = "ip",
64 [NF_ARP] = "arp", 64 [NFPROTO_ARP] = "arp",
65 [NFPROTO_BRIDGE] = "eb",
66 [NFPROTO_IPV6] = "ip6",
65}; 67};
66 68
67/* Registration hooks for targets. */ 69/* Registration hooks for targets. */
68int 70int
69xt_register_target(struct xt_target *target) 71xt_register_target(struct xt_target *target)
70{ 72{
71 int ret, af = target->family; 73 u_int8_t af = target->family;
74 int ret;
72 75
73 ret = mutex_lock_interruptible(&xt[af].mutex); 76 ret = mutex_lock_interruptible(&xt[af].mutex);
74 if (ret != 0) 77 if (ret != 0)
@@ -82,7 +85,7 @@ EXPORT_SYMBOL(xt_register_target);
82void 85void
83xt_unregister_target(struct xt_target *target) 86xt_unregister_target(struct xt_target *target)
84{ 87{
85 int af = target->family; 88 u_int8_t af = target->family;
86 89
87 mutex_lock(&xt[af].mutex); 90 mutex_lock(&xt[af].mutex);
88 list_del(&target->list); 91 list_del(&target->list);
@@ -123,7 +126,8 @@ EXPORT_SYMBOL(xt_unregister_targets);
123int 126int
124xt_register_match(struct xt_match *match) 127xt_register_match(struct xt_match *match)
125{ 128{
126 int ret, af = match->family; 129 u_int8_t af = match->family;
130 int ret;
127 131
128 ret = mutex_lock_interruptible(&xt[af].mutex); 132 ret = mutex_lock_interruptible(&xt[af].mutex);
129 if (ret != 0) 133 if (ret != 0)
@@ -139,7 +143,7 @@ EXPORT_SYMBOL(xt_register_match);
139void 143void
140xt_unregister_match(struct xt_match *match) 144xt_unregister_match(struct xt_match *match)
141{ 145{
142 int af = match->family; 146 u_int8_t af = match->family;
143 147
144 mutex_lock(&xt[af].mutex); 148 mutex_lock(&xt[af].mutex);
145 list_del(&match->list); 149 list_del(&match->list);
@@ -185,7 +189,7 @@ EXPORT_SYMBOL(xt_unregister_matches);
185 */ 189 */
186 190
187/* Find match, grabs ref. Returns ERR_PTR() on error. */ 191/* Find match, grabs ref. Returns ERR_PTR() on error. */
188struct xt_match *xt_find_match(int af, const char *name, u8 revision) 192struct xt_match *xt_find_match(u8 af, const char *name, u8 revision)
189{ 193{
190 struct xt_match *m; 194 struct xt_match *m;
191 int err = 0; 195 int err = 0;
@@ -205,12 +209,17 @@ struct xt_match *xt_find_match(int af, const char *name, u8 revision)
205 } 209 }
206 } 210 }
207 mutex_unlock(&xt[af].mutex); 211 mutex_unlock(&xt[af].mutex);
212
213 if (af != NFPROTO_UNSPEC)
214 /* Try searching again in the family-independent list */
215 return xt_find_match(NFPROTO_UNSPEC, name, revision);
216
208 return ERR_PTR(err); 217 return ERR_PTR(err);
209} 218}
210EXPORT_SYMBOL(xt_find_match); 219EXPORT_SYMBOL(xt_find_match);
211 220
212/* Find target, grabs ref. Returns ERR_PTR() on error. */ 221/* Find target, grabs ref. Returns ERR_PTR() on error. */
213struct xt_target *xt_find_target(int af, const char *name, u8 revision) 222struct xt_target *xt_find_target(u8 af, const char *name, u8 revision)
214{ 223{
215 struct xt_target *t; 224 struct xt_target *t;
216 int err = 0; 225 int err = 0;
@@ -230,11 +239,16 @@ struct xt_target *xt_find_target(int af, const char *name, u8 revision)
230 } 239 }
231 } 240 }
232 mutex_unlock(&xt[af].mutex); 241 mutex_unlock(&xt[af].mutex);
242
243 if (af != NFPROTO_UNSPEC)
244 /* Try searching again in the family-independent list */
245 return xt_find_target(NFPROTO_UNSPEC, name, revision);
246
233 return ERR_PTR(err); 247 return ERR_PTR(err);
234} 248}
235EXPORT_SYMBOL(xt_find_target); 249EXPORT_SYMBOL(xt_find_target);
236 250
237struct xt_target *xt_request_find_target(int af, const char *name, u8 revision) 251struct xt_target *xt_request_find_target(u8 af, const char *name, u8 revision)
238{ 252{
239 struct xt_target *target; 253 struct xt_target *target;
240 254
@@ -246,7 +260,7 @@ struct xt_target *xt_request_find_target(int af, const char *name, u8 revision)
246} 260}
247EXPORT_SYMBOL_GPL(xt_request_find_target); 261EXPORT_SYMBOL_GPL(xt_request_find_target);
248 262
249static int match_revfn(int af, const char *name, u8 revision, int *bestp) 263static int match_revfn(u8 af, const char *name, u8 revision, int *bestp)
250{ 264{
251 const struct xt_match *m; 265 const struct xt_match *m;
252 int have_rev = 0; 266 int have_rev = 0;
@@ -262,7 +276,7 @@ static int match_revfn(int af, const char *name, u8 revision, int *bestp)
262 return have_rev; 276 return have_rev;
263} 277}
264 278
265static int target_revfn(int af, const char *name, u8 revision, int *bestp) 279static int target_revfn(u8 af, const char *name, u8 revision, int *bestp)
266{ 280{
267 const struct xt_target *t; 281 const struct xt_target *t;
268 int have_rev = 0; 282 int have_rev = 0;
@@ -279,7 +293,7 @@ static int target_revfn(int af, const char *name, u8 revision, int *bestp)
279} 293}
280 294
281/* Returns true or false (if no such extension at all) */ 295/* Returns true or false (if no such extension at all) */
282int xt_find_revision(int af, const char *name, u8 revision, int target, 296int xt_find_revision(u8 af, const char *name, u8 revision, int target,
283 int *err) 297 int *err)
284{ 298{
285 int have_rev, best = -1; 299 int have_rev, best = -1;
@@ -307,37 +321,47 @@ int xt_find_revision(int af, const char *name, u8 revision, int target,
307} 321}
308EXPORT_SYMBOL_GPL(xt_find_revision); 322EXPORT_SYMBOL_GPL(xt_find_revision);
309 323
310int xt_check_match(const struct xt_match *match, unsigned short family, 324int xt_check_match(struct xt_mtchk_param *par,
311 unsigned int size, const char *table, unsigned int hook_mask, 325 unsigned int size, u_int8_t proto, bool inv_proto)
312 unsigned short proto, int inv_proto)
313{ 326{
314 if (XT_ALIGN(match->matchsize) != size) { 327 if (XT_ALIGN(par->match->matchsize) != size &&
328 par->match->matchsize != -1) {
329 /*
330 * ebt_among is exempt from centralized matchsize checking
331 * because it uses a dynamic-size data set.
332 */
315 printk("%s_tables: %s match: invalid size %Zu != %u\n", 333 printk("%s_tables: %s match: invalid size %Zu != %u\n",
316 xt_prefix[family], match->name, 334 xt_prefix[par->family], par->match->name,
317 XT_ALIGN(match->matchsize), size); 335 XT_ALIGN(par->match->matchsize), size);
318 return -EINVAL; 336 return -EINVAL;
319 } 337 }
320 if (match->table && strcmp(match->table, table)) { 338 if (par->match->table != NULL &&
339 strcmp(par->match->table, par->table) != 0) {
321 printk("%s_tables: %s match: only valid in %s table, not %s\n", 340 printk("%s_tables: %s match: only valid in %s table, not %s\n",
322 xt_prefix[family], match->name, match->table, table); 341 xt_prefix[par->family], par->match->name,
342 par->match->table, par->table);
323 return -EINVAL; 343 return -EINVAL;
324 } 344 }
325 if (match->hooks && (hook_mask & ~match->hooks) != 0) { 345 if (par->match->hooks && (par->hook_mask & ~par->match->hooks) != 0) {
326 printk("%s_tables: %s match: bad hook_mask %u/%u\n", 346 printk("%s_tables: %s match: bad hook_mask %#x/%#x\n",
327 xt_prefix[family], match->name, hook_mask, match->hooks); 347 xt_prefix[par->family], par->match->name,
348 par->hook_mask, par->match->hooks);
328 return -EINVAL; 349 return -EINVAL;
329 } 350 }
330 if (match->proto && (match->proto != proto || inv_proto)) { 351 if (par->match->proto && (par->match->proto != proto || inv_proto)) {
331 printk("%s_tables: %s match: only valid for protocol %u\n", 352 printk("%s_tables: %s match: only valid for protocol %u\n",
332 xt_prefix[family], match->name, match->proto); 353 xt_prefix[par->family], par->match->name,
354 par->match->proto);
333 return -EINVAL; 355 return -EINVAL;
334 } 356 }
357 if (par->match->checkentry != NULL && !par->match->checkentry(par))
358 return -EINVAL;
335 return 0; 359 return 0;
336} 360}
337EXPORT_SYMBOL_GPL(xt_check_match); 361EXPORT_SYMBOL_GPL(xt_check_match);
338 362
339#ifdef CONFIG_COMPAT 363#ifdef CONFIG_COMPAT
340int xt_compat_add_offset(int af, unsigned int offset, short delta) 364int xt_compat_add_offset(u_int8_t af, unsigned int offset, short delta)
341{ 365{
342 struct compat_delta *tmp; 366 struct compat_delta *tmp;
343 367
@@ -359,7 +383,7 @@ int xt_compat_add_offset(int af, unsigned int offset, short delta)
359} 383}
360EXPORT_SYMBOL_GPL(xt_compat_add_offset); 384EXPORT_SYMBOL_GPL(xt_compat_add_offset);
361 385
362void xt_compat_flush_offsets(int af) 386void xt_compat_flush_offsets(u_int8_t af)
363{ 387{
364 struct compat_delta *tmp, *next; 388 struct compat_delta *tmp, *next;
365 389
@@ -373,7 +397,7 @@ void xt_compat_flush_offsets(int af)
373} 397}
374EXPORT_SYMBOL_GPL(xt_compat_flush_offsets); 398EXPORT_SYMBOL_GPL(xt_compat_flush_offsets);
375 399
376short xt_compat_calc_jump(int af, unsigned int offset) 400short xt_compat_calc_jump(u_int8_t af, unsigned int offset)
377{ 401{
378 struct compat_delta *tmp; 402 struct compat_delta *tmp;
379 short delta; 403 short delta;
@@ -448,32 +472,36 @@ int xt_compat_match_to_user(struct xt_entry_match *m, void __user **dstptr,
448EXPORT_SYMBOL_GPL(xt_compat_match_to_user); 472EXPORT_SYMBOL_GPL(xt_compat_match_to_user);
449#endif /* CONFIG_COMPAT */ 473#endif /* CONFIG_COMPAT */
450 474
451int xt_check_target(const struct xt_target *target, unsigned short family, 475int xt_check_target(struct xt_tgchk_param *par,
452 unsigned int size, const char *table, unsigned int hook_mask, 476 unsigned int size, u_int8_t proto, bool inv_proto)
453 unsigned short proto, int inv_proto)
454{ 477{
455 if (XT_ALIGN(target->targetsize) != size) { 478 if (XT_ALIGN(par->target->targetsize) != size) {
456 printk("%s_tables: %s target: invalid size %Zu != %u\n", 479 printk("%s_tables: %s target: invalid size %Zu != %u\n",
457 xt_prefix[family], target->name, 480 xt_prefix[par->family], par->target->name,
458 XT_ALIGN(target->targetsize), size); 481 XT_ALIGN(par->target->targetsize), size);
459 return -EINVAL; 482 return -EINVAL;
460 } 483 }
461 if (target->table && strcmp(target->table, table)) { 484 if (par->target->table != NULL &&
485 strcmp(par->target->table, par->table) != 0) {
462 printk("%s_tables: %s target: only valid in %s table, not %s\n", 486 printk("%s_tables: %s target: only valid in %s table, not %s\n",
463 xt_prefix[family], target->name, target->table, table); 487 xt_prefix[par->family], par->target->name,
488 par->target->table, par->table);
464 return -EINVAL; 489 return -EINVAL;
465 } 490 }
466 if (target->hooks && (hook_mask & ~target->hooks) != 0) { 491 if (par->target->hooks && (par->hook_mask & ~par->target->hooks) != 0) {
467 printk("%s_tables: %s target: bad hook_mask %u/%u\n", 492 printk("%s_tables: %s target: bad hook_mask %#x/%#x\n",
468 xt_prefix[family], target->name, hook_mask, 493 xt_prefix[par->family], par->target->name,
469 target->hooks); 494 par->hook_mask, par->target->hooks);
470 return -EINVAL; 495 return -EINVAL;
471 } 496 }
472 if (target->proto && (target->proto != proto || inv_proto)) { 497 if (par->target->proto && (par->target->proto != proto || inv_proto)) {
473 printk("%s_tables: %s target: only valid for protocol %u\n", 498 printk("%s_tables: %s target: only valid for protocol %u\n",
474 xt_prefix[family], target->name, target->proto); 499 xt_prefix[par->family], par->target->name,
500 par->target->proto);
475 return -EINVAL; 501 return -EINVAL;
476 } 502 }
503 if (par->target->checkentry != NULL && !par->target->checkentry(par))
504 return -EINVAL;
477 return 0; 505 return 0;
478} 506}
479EXPORT_SYMBOL_GPL(xt_check_target); 507EXPORT_SYMBOL_GPL(xt_check_target);
@@ -590,7 +618,8 @@ void xt_free_table_info(struct xt_table_info *info)
590EXPORT_SYMBOL(xt_free_table_info); 618EXPORT_SYMBOL(xt_free_table_info);
591 619
592/* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */ 620/* Find table by name, grabs mutex & ref. Returns ERR_PTR() on error. */
593struct xt_table *xt_find_table_lock(struct net *net, int af, const char *name) 621struct xt_table *xt_find_table_lock(struct net *net, u_int8_t af,
622 const char *name)
594{ 623{
595 struct xt_table *t; 624 struct xt_table *t;
596 625
@@ -612,13 +641,13 @@ void xt_table_unlock(struct xt_table *table)
612EXPORT_SYMBOL_GPL(xt_table_unlock); 641EXPORT_SYMBOL_GPL(xt_table_unlock);
613 642
614#ifdef CONFIG_COMPAT 643#ifdef CONFIG_COMPAT
615void xt_compat_lock(int af) 644void xt_compat_lock(u_int8_t af)
616{ 645{
617 mutex_lock(&xt[af].compat_mutex); 646 mutex_lock(&xt[af].compat_mutex);
618} 647}
619EXPORT_SYMBOL_GPL(xt_compat_lock); 648EXPORT_SYMBOL_GPL(xt_compat_lock);
620 649
621void xt_compat_unlock(int af) 650void xt_compat_unlock(u_int8_t af)
622{ 651{
623 mutex_unlock(&xt[af].compat_mutex); 652 mutex_unlock(&xt[af].compat_mutex);
624} 653}
@@ -722,13 +751,13 @@ EXPORT_SYMBOL_GPL(xt_unregister_table);
722#ifdef CONFIG_PROC_FS 751#ifdef CONFIG_PROC_FS
723struct xt_names_priv { 752struct xt_names_priv {
724 struct seq_net_private p; 753 struct seq_net_private p;
725 int af; 754 u_int8_t af;
726}; 755};
727static void *xt_table_seq_start(struct seq_file *seq, loff_t *pos) 756static void *xt_table_seq_start(struct seq_file *seq, loff_t *pos)
728{ 757{
729 struct xt_names_priv *priv = seq->private; 758 struct xt_names_priv *priv = seq->private;
730 struct net *net = seq_file_net(seq); 759 struct net *net = seq_file_net(seq);
731 int af = priv->af; 760 u_int8_t af = priv->af;
732 761
733 mutex_lock(&xt[af].mutex); 762 mutex_lock(&xt[af].mutex);
734 return seq_list_start(&net->xt.tables[af], *pos); 763 return seq_list_start(&net->xt.tables[af], *pos);
@@ -738,7 +767,7 @@ static void *xt_table_seq_next(struct seq_file *seq, void *v, loff_t *pos)
738{ 767{
739 struct xt_names_priv *priv = seq->private; 768 struct xt_names_priv *priv = seq->private;
740 struct net *net = seq_file_net(seq); 769 struct net *net = seq_file_net(seq);
741 int af = priv->af; 770 u_int8_t af = priv->af;
742 771
743 return seq_list_next(v, &net->xt.tables[af], pos); 772 return seq_list_next(v, &net->xt.tables[af], pos);
744} 773}
@@ -746,7 +775,7 @@ static void *xt_table_seq_next(struct seq_file *seq, void *v, loff_t *pos)
746static void xt_table_seq_stop(struct seq_file *seq, void *v) 775static void xt_table_seq_stop(struct seq_file *seq, void *v)
747{ 776{
748 struct xt_names_priv *priv = seq->private; 777 struct xt_names_priv *priv = seq->private;
749 int af = priv->af; 778 u_int8_t af = priv->af;
750 779
751 mutex_unlock(&xt[af].mutex); 780 mutex_unlock(&xt[af].mutex);
752} 781}
@@ -922,14 +951,14 @@ static const struct file_operations xt_target_ops = {
922 951
923#endif /* CONFIG_PROC_FS */ 952#endif /* CONFIG_PROC_FS */
924 953
925int xt_proto_init(struct net *net, int af) 954int xt_proto_init(struct net *net, u_int8_t af)
926{ 955{
927#ifdef CONFIG_PROC_FS 956#ifdef CONFIG_PROC_FS
928 char buf[XT_FUNCTION_MAXNAMELEN]; 957 char buf[XT_FUNCTION_MAXNAMELEN];
929 struct proc_dir_entry *proc; 958 struct proc_dir_entry *proc;
930#endif 959#endif
931 960
932 if (af >= NPROTO) 961 if (af >= ARRAY_SIZE(xt_prefix))
933 return -EINVAL; 962 return -EINVAL;
934 963
935 964
@@ -974,7 +1003,7 @@ out:
974} 1003}
975EXPORT_SYMBOL_GPL(xt_proto_init); 1004EXPORT_SYMBOL_GPL(xt_proto_init);
976 1005
977void xt_proto_fini(struct net *net, int af) 1006void xt_proto_fini(struct net *net, u_int8_t af)
978{ 1007{
979#ifdef CONFIG_PROC_FS 1008#ifdef CONFIG_PROC_FS
980 char buf[XT_FUNCTION_MAXNAMELEN]; 1009 char buf[XT_FUNCTION_MAXNAMELEN];
@@ -998,7 +1027,7 @@ static int __net_init xt_net_init(struct net *net)
998{ 1027{
999 int i; 1028 int i;
1000 1029
1001 for (i = 0; i < NPROTO; i++) 1030 for (i = 0; i < NFPROTO_NUMPROTO; i++)
1002 INIT_LIST_HEAD(&net->xt.tables[i]); 1031 INIT_LIST_HEAD(&net->xt.tables[i]);
1003 return 0; 1032 return 0;
1004} 1033}
@@ -1011,11 +1040,11 @@ static int __init xt_init(void)
1011{ 1040{
1012 int i, rv; 1041 int i, rv;
1013 1042
1014 xt = kmalloc(sizeof(struct xt_af) * NPROTO, GFP_KERNEL); 1043 xt = kmalloc(sizeof(struct xt_af) * NFPROTO_NUMPROTO, GFP_KERNEL);
1015 if (!xt) 1044 if (!xt)
1016 return -ENOMEM; 1045 return -ENOMEM;
1017 1046
1018 for (i = 0; i < NPROTO; i++) { 1047 for (i = 0; i < NFPROTO_NUMPROTO; i++) {
1019 mutex_init(&xt[i].mutex); 1048 mutex_init(&xt[i].mutex);
1020#ifdef CONFIG_COMPAT 1049#ifdef CONFIG_COMPAT
1021 mutex_init(&xt[i].compat_mutex); 1050 mutex_init(&xt[i].compat_mutex);
diff --git a/net/netfilter/xt_CLASSIFY.c b/net/netfilter/xt_CLASSIFY.c
index 77a52bf83225..011bc80dd2a1 100644
--- a/net/netfilter/xt_CLASSIFY.c
+++ b/net/netfilter/xt_CLASSIFY.c
@@ -27,50 +27,34 @@ MODULE_ALIAS("ipt_CLASSIFY");
27MODULE_ALIAS("ip6t_CLASSIFY"); 27MODULE_ALIAS("ip6t_CLASSIFY");
28 28
29static unsigned int 29static unsigned int
30classify_tg(struct sk_buff *skb, const struct net_device *in, 30classify_tg(struct sk_buff *skb, const struct xt_target_param *par)
31 const struct net_device *out, unsigned int hooknum,
32 const struct xt_target *target, const void *targinfo)
33{ 31{
34 const struct xt_classify_target_info *clinfo = targinfo; 32 const struct xt_classify_target_info *clinfo = par->targinfo;
35 33
36 skb->priority = clinfo->priority; 34 skb->priority = clinfo->priority;
37 return XT_CONTINUE; 35 return XT_CONTINUE;
38} 36}
39 37
40static struct xt_target classify_tg_reg[] __read_mostly = { 38static struct xt_target classify_tg_reg __read_mostly = {
41 { 39 .name = "CLASSIFY",
42 .family = AF_INET, 40 .revision = 0,
43 .name = "CLASSIFY", 41 .family = NFPROTO_UNSPEC,
44 .target = classify_tg, 42 .table = "mangle",
45 .targetsize = sizeof(struct xt_classify_target_info), 43 .hooks = (1 << NF_INET_LOCAL_OUT) | (1 << NF_INET_FORWARD) |
46 .table = "mangle", 44 (1 << NF_INET_POST_ROUTING),
47 .hooks = (1 << NF_INET_LOCAL_OUT) | 45 .target = classify_tg,
48 (1 << NF_INET_FORWARD) | 46 .targetsize = sizeof(struct xt_classify_target_info),
49 (1 << NF_INET_POST_ROUTING), 47 .me = THIS_MODULE,
50 .me = THIS_MODULE,
51 },
52 {
53 .name = "CLASSIFY",
54 .family = AF_INET6,
55 .target = classify_tg,
56 .targetsize = sizeof(struct xt_classify_target_info),
57 .table = "mangle",
58 .hooks = (1 << NF_INET_LOCAL_OUT) |
59 (1 << NF_INET_FORWARD) |
60 (1 << NF_INET_POST_ROUTING),
61 .me = THIS_MODULE,
62 },
63}; 48};
64 49
65static int __init classify_tg_init(void) 50static int __init classify_tg_init(void)
66{ 51{
67 return xt_register_targets(classify_tg_reg, 52 return xt_register_target(&classify_tg_reg);
68 ARRAY_SIZE(classify_tg_reg));
69} 53}
70 54
71static void __exit classify_tg_exit(void) 55static void __exit classify_tg_exit(void)
72{ 56{
73 xt_unregister_targets(classify_tg_reg, ARRAY_SIZE(classify_tg_reg)); 57 xt_unregister_target(&classify_tg_reg);
74} 58}
75 59
76module_init(classify_tg_init); 60module_init(classify_tg_init);
diff --git a/net/netfilter/xt_CONNMARK.c b/net/netfilter/xt_CONNMARK.c
index 5fecfb4794b1..d6e5ab463277 100644
--- a/net/netfilter/xt_CONNMARK.c
+++ b/net/netfilter/xt_CONNMARK.c
@@ -36,11 +36,9 @@ MODULE_ALIAS("ip6t_CONNMARK");
36#include <net/netfilter/nf_conntrack_ecache.h> 36#include <net/netfilter/nf_conntrack_ecache.h>
37 37
38static unsigned int 38static unsigned int
39connmark_tg_v0(struct sk_buff *skb, const struct net_device *in, 39connmark_tg_v0(struct sk_buff *skb, const struct xt_target_param *par)
40 const struct net_device *out, unsigned int hooknum,
41 const struct xt_target *target, const void *targinfo)
42{ 40{
43 const struct xt_connmark_target_info *markinfo = targinfo; 41 const struct xt_connmark_target_info *markinfo = par->targinfo;
44 struct nf_conn *ct; 42 struct nf_conn *ct;
45 enum ip_conntrack_info ctinfo; 43 enum ip_conntrack_info ctinfo;
46 u_int32_t diff; 44 u_int32_t diff;
@@ -54,7 +52,7 @@ connmark_tg_v0(struct sk_buff *skb, const struct net_device *in,
54 newmark = (ct->mark & ~markinfo->mask) | markinfo->mark; 52 newmark = (ct->mark & ~markinfo->mask) | markinfo->mark;
55 if (newmark != ct->mark) { 53 if (newmark != ct->mark) {
56 ct->mark = newmark; 54 ct->mark = newmark;
57 nf_conntrack_event_cache(IPCT_MARK, skb); 55 nf_conntrack_event_cache(IPCT_MARK, ct);
58 } 56 }
59 break; 57 break;
60 case XT_CONNMARK_SAVE: 58 case XT_CONNMARK_SAVE:
@@ -62,7 +60,7 @@ connmark_tg_v0(struct sk_buff *skb, const struct net_device *in,
62 (skb->mark & markinfo->mask); 60 (skb->mark & markinfo->mask);
63 if (ct->mark != newmark) { 61 if (ct->mark != newmark) {
64 ct->mark = newmark; 62 ct->mark = newmark;
65 nf_conntrack_event_cache(IPCT_MARK, skb); 63 nf_conntrack_event_cache(IPCT_MARK, ct);
66 } 64 }
67 break; 65 break;
68 case XT_CONNMARK_RESTORE: 66 case XT_CONNMARK_RESTORE:
@@ -77,11 +75,9 @@ connmark_tg_v0(struct sk_buff *skb, const struct net_device *in,
77} 75}
78 76
79static unsigned int 77static unsigned int
80connmark_tg(struct sk_buff *skb, const struct net_device *in, 78connmark_tg(struct sk_buff *skb, const struct xt_target_param *par)
81 const struct net_device *out, unsigned int hooknum,
82 const struct xt_target *target, const void *targinfo)
83{ 79{
84 const struct xt_connmark_tginfo1 *info = targinfo; 80 const struct xt_connmark_tginfo1 *info = par->targinfo;
85 enum ip_conntrack_info ctinfo; 81 enum ip_conntrack_info ctinfo;
86 struct nf_conn *ct; 82 struct nf_conn *ct;
87 u_int32_t newmark; 83 u_int32_t newmark;
@@ -95,7 +91,7 @@ connmark_tg(struct sk_buff *skb, const struct net_device *in,
95 newmark = (ct->mark & ~info->ctmask) ^ info->ctmark; 91 newmark = (ct->mark & ~info->ctmask) ^ info->ctmark;
96 if (ct->mark != newmark) { 92 if (ct->mark != newmark) {
97 ct->mark = newmark; 93 ct->mark = newmark;
98 nf_conntrack_event_cache(IPCT_MARK, skb); 94 nf_conntrack_event_cache(IPCT_MARK, ct);
99 } 95 }
100 break; 96 break;
101 case XT_CONNMARK_SAVE: 97 case XT_CONNMARK_SAVE:
@@ -103,7 +99,7 @@ connmark_tg(struct sk_buff *skb, const struct net_device *in,
103 (skb->mark & info->nfmask); 99 (skb->mark & info->nfmask);
104 if (ct->mark != newmark) { 100 if (ct->mark != newmark) {
105 ct->mark = newmark; 101 ct->mark = newmark;
106 nf_conntrack_event_cache(IPCT_MARK, skb); 102 nf_conntrack_event_cache(IPCT_MARK, ct);
107 } 103 }
108 break; 104 break;
109 case XT_CONNMARK_RESTORE: 105 case XT_CONNMARK_RESTORE:
@@ -116,18 +112,15 @@ connmark_tg(struct sk_buff *skb, const struct net_device *in,
116 return XT_CONTINUE; 112 return XT_CONTINUE;
117} 113}
118 114
119static bool 115static bool connmark_tg_check_v0(const struct xt_tgchk_param *par)
120connmark_tg_check_v0(const char *tablename, const void *entry,
121 const struct xt_target *target, void *targinfo,
122 unsigned int hook_mask)
123{ 116{
124 const struct xt_connmark_target_info *matchinfo = targinfo; 117 const struct xt_connmark_target_info *matchinfo = par->targinfo;
125 118
126 if (matchinfo->mode == XT_CONNMARK_RESTORE) { 119 if (matchinfo->mode == XT_CONNMARK_RESTORE) {
127 if (strcmp(tablename, "mangle") != 0) { 120 if (strcmp(par->table, "mangle") != 0) {
128 printk(KERN_WARNING "CONNMARK: restore can only be " 121 printk(KERN_WARNING "CONNMARK: restore can only be "
129 "called from \"mangle\" table, not \"%s\"\n", 122 "called from \"mangle\" table, not \"%s\"\n",
130 tablename); 123 par->table);
131 return false; 124 return false;
132 } 125 }
133 } 126 }
@@ -135,31 +128,27 @@ connmark_tg_check_v0(const char *tablename, const void *entry,
135 printk(KERN_WARNING "CONNMARK: Only supports 32bit mark\n"); 128 printk(KERN_WARNING "CONNMARK: Only supports 32bit mark\n");
136 return false; 129 return false;
137 } 130 }
138 if (nf_ct_l3proto_try_module_get(target->family) < 0) { 131 if (nf_ct_l3proto_try_module_get(par->family) < 0) {
139 printk(KERN_WARNING "can't load conntrack support for " 132 printk(KERN_WARNING "can't load conntrack support for "
140 "proto=%u\n", target->family); 133 "proto=%u\n", par->family);
141 return false; 134 return false;
142 } 135 }
143 return true; 136 return true;
144} 137}
145 138
146static bool 139static bool connmark_tg_check(const struct xt_tgchk_param *par)
147connmark_tg_check(const char *tablename, const void *entry,
148 const struct xt_target *target, void *targinfo,
149 unsigned int hook_mask)
150{ 140{
151 if (nf_ct_l3proto_try_module_get(target->family) < 0) { 141 if (nf_ct_l3proto_try_module_get(par->family) < 0) {
152 printk(KERN_WARNING "cannot load conntrack support for " 142 printk(KERN_WARNING "cannot load conntrack support for "
153 "proto=%u\n", target->family); 143 "proto=%u\n", par->family);
154 return false; 144 return false;
155 } 145 }
156 return true; 146 return true;
157} 147}
158 148
159static void 149static void connmark_tg_destroy(const struct xt_tgdtor_param *par)
160connmark_tg_destroy(const struct xt_target *target, void *targinfo)
161{ 150{
162 nf_ct_l3proto_module_put(target->family); 151 nf_ct_l3proto_module_put(par->family);
163} 152}
164 153
165#ifdef CONFIG_COMPAT 154#ifdef CONFIG_COMPAT
@@ -197,7 +186,7 @@ static struct xt_target connmark_tg_reg[] __read_mostly = {
197 { 186 {
198 .name = "CONNMARK", 187 .name = "CONNMARK",
199 .revision = 0, 188 .revision = 0,
200 .family = AF_INET, 189 .family = NFPROTO_UNSPEC,
201 .checkentry = connmark_tg_check_v0, 190 .checkentry = connmark_tg_check_v0,
202 .destroy = connmark_tg_destroy, 191 .destroy = connmark_tg_destroy,
203 .target = connmark_tg_v0, 192 .target = connmark_tg_v0,
@@ -210,34 +199,9 @@ static struct xt_target connmark_tg_reg[] __read_mostly = {
210 .me = THIS_MODULE 199 .me = THIS_MODULE
211 }, 200 },
212 { 201 {
213 .name = "CONNMARK",
214 .revision = 0,
215 .family = AF_INET6,
216 .checkentry = connmark_tg_check_v0,
217 .destroy = connmark_tg_destroy,
218 .target = connmark_tg_v0,
219 .targetsize = sizeof(struct xt_connmark_target_info),
220#ifdef CONFIG_COMPAT
221 .compatsize = sizeof(struct compat_xt_connmark_target_info),
222 .compat_from_user = connmark_tg_compat_from_user_v0,
223 .compat_to_user = connmark_tg_compat_to_user_v0,
224#endif
225 .me = THIS_MODULE
226 },
227 {
228 .name = "CONNMARK",
229 .revision = 1,
230 .family = AF_INET,
231 .checkentry = connmark_tg_check,
232 .target = connmark_tg,
233 .targetsize = sizeof(struct xt_connmark_tginfo1),
234 .destroy = connmark_tg_destroy,
235 .me = THIS_MODULE,
236 },
237 {
238 .name = "CONNMARK", 202 .name = "CONNMARK",
239 .revision = 1, 203 .revision = 1,
240 .family = AF_INET6, 204 .family = NFPROTO_UNSPEC,
241 .checkentry = connmark_tg_check, 205 .checkentry = connmark_tg_check,
242 .target = connmark_tg, 206 .target = connmark_tg,
243 .targetsize = sizeof(struct xt_connmark_tginfo1), 207 .targetsize = sizeof(struct xt_connmark_tginfo1),
diff --git a/net/netfilter/xt_CONNSECMARK.c b/net/netfilter/xt_CONNSECMARK.c
index 76ca1f2421eb..b54c3756fdc3 100644
--- a/net/netfilter/xt_CONNSECMARK.c
+++ b/net/netfilter/xt_CONNSECMARK.c
@@ -43,7 +43,7 @@ static void secmark_save(const struct sk_buff *skb)
43 ct = nf_ct_get(skb, &ctinfo); 43 ct = nf_ct_get(skb, &ctinfo);
44 if (ct && !ct->secmark) { 44 if (ct && !ct->secmark) {
45 ct->secmark = skb->secmark; 45 ct->secmark = skb->secmark;
46 nf_conntrack_event_cache(IPCT_SECMARK, skb); 46 nf_conntrack_event_cache(IPCT_SECMARK, ct);
47 } 47 }
48 } 48 }
49} 49}
@@ -65,11 +65,9 @@ static void secmark_restore(struct sk_buff *skb)
65} 65}
66 66
67static unsigned int 67static unsigned int
68connsecmark_tg(struct sk_buff *skb, const struct net_device *in, 68connsecmark_tg(struct sk_buff *skb, const struct xt_target_param *par)
69 const struct net_device *out, unsigned int hooknum,
70 const struct xt_target *target, const void *targinfo)
71{ 69{
72 const struct xt_connsecmark_target_info *info = targinfo; 70 const struct xt_connsecmark_target_info *info = par->targinfo;
73 71
74 switch (info->mode) { 72 switch (info->mode) {
75 case CONNSECMARK_SAVE: 73 case CONNSECMARK_SAVE:
@@ -87,16 +85,14 @@ connsecmark_tg(struct sk_buff *skb, const struct net_device *in,
87 return XT_CONTINUE; 85 return XT_CONTINUE;
88} 86}
89 87
90static bool 88static bool connsecmark_tg_check(const struct xt_tgchk_param *par)
91connsecmark_tg_check(const char *tablename, const void *entry,
92 const struct xt_target *target, void *targinfo,
93 unsigned int hook_mask)
94{ 89{
95 const struct xt_connsecmark_target_info *info = targinfo; 90 const struct xt_connsecmark_target_info *info = par->targinfo;
96 91
97 if (strcmp(tablename, "mangle") && strcmp(tablename, "security")) { 92 if (strcmp(par->table, "mangle") != 0 &&
93 strcmp(par->table, "security") != 0) {
98 printk(KERN_INFO PFX "target only valid in the \'mangle\' " 94 printk(KERN_INFO PFX "target only valid in the \'mangle\' "
99 "or \'security\' tables, not \'%s\'.\n", tablename); 95 "or \'security\' tables, not \'%s\'.\n", par->table);
100 return false; 96 return false;
101 } 97 }
102 98
@@ -110,51 +106,38 @@ connsecmark_tg_check(const char *tablename, const void *entry,
110 return false; 106 return false;
111 } 107 }
112 108
113 if (nf_ct_l3proto_try_module_get(target->family) < 0) { 109 if (nf_ct_l3proto_try_module_get(par->family) < 0) {
114 printk(KERN_WARNING "can't load conntrack support for " 110 printk(KERN_WARNING "can't load conntrack support for "
115 "proto=%u\n", target->family); 111 "proto=%u\n", par->family);
116 return false; 112 return false;
117 } 113 }
118 return true; 114 return true;
119} 115}
120 116
121static void 117static void connsecmark_tg_destroy(const struct xt_tgdtor_param *par)
122connsecmark_tg_destroy(const struct xt_target *target, void *targinfo)
123{ 118{
124 nf_ct_l3proto_module_put(target->family); 119 nf_ct_l3proto_module_put(par->family);
125} 120}
126 121
127static struct xt_target connsecmark_tg_reg[] __read_mostly = { 122static struct xt_target connsecmark_tg_reg __read_mostly = {
128 { 123 .name = "CONNSECMARK",
129 .name = "CONNSECMARK", 124 .revision = 0,
130 .family = AF_INET, 125 .family = NFPROTO_UNSPEC,
131 .checkentry = connsecmark_tg_check, 126 .checkentry = connsecmark_tg_check,
132 .destroy = connsecmark_tg_destroy, 127 .destroy = connsecmark_tg_destroy,
133 .target = connsecmark_tg, 128 .target = connsecmark_tg,
134 .targetsize = sizeof(struct xt_connsecmark_target_info), 129 .targetsize = sizeof(struct xt_connsecmark_target_info),
135 .me = THIS_MODULE, 130 .me = THIS_MODULE,
136 },
137 {
138 .name = "CONNSECMARK",
139 .family = AF_INET6,
140 .checkentry = connsecmark_tg_check,
141 .destroy = connsecmark_tg_destroy,
142 .target = connsecmark_tg,
143 .targetsize = sizeof(struct xt_connsecmark_target_info),
144 .me = THIS_MODULE,
145 },
146}; 131};
147 132
148static int __init connsecmark_tg_init(void) 133static int __init connsecmark_tg_init(void)
149{ 134{
150 return xt_register_targets(connsecmark_tg_reg, 135 return xt_register_target(&connsecmark_tg_reg);
151 ARRAY_SIZE(connsecmark_tg_reg));
152} 136}
153 137
154static void __exit connsecmark_tg_exit(void) 138static void __exit connsecmark_tg_exit(void)
155{ 139{
156 xt_unregister_targets(connsecmark_tg_reg, 140 xt_unregister_target(&connsecmark_tg_reg);
157 ARRAY_SIZE(connsecmark_tg_reg));
158} 141}
159 142
160module_init(connsecmark_tg_init); 143module_init(connsecmark_tg_init);
diff --git a/net/netfilter/xt_DSCP.c b/net/netfilter/xt_DSCP.c
index 97efd74c04fe..6a347e768f86 100644
--- a/net/netfilter/xt_DSCP.c
+++ b/net/netfilter/xt_DSCP.c
@@ -29,11 +29,9 @@ MODULE_ALIAS("ipt_TOS");
29MODULE_ALIAS("ip6t_TOS"); 29MODULE_ALIAS("ip6t_TOS");
30 30
31static unsigned int 31static unsigned int
32dscp_tg(struct sk_buff *skb, const struct net_device *in, 32dscp_tg(struct sk_buff *skb, const struct xt_target_param *par)
33 const struct net_device *out, unsigned int hooknum,
34 const struct xt_target *target, const void *targinfo)
35{ 33{
36 const struct xt_DSCP_info *dinfo = targinfo; 34 const struct xt_DSCP_info *dinfo = par->targinfo;
37 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;
38 36
39 if (dscp != dinfo->dscp) { 37 if (dscp != dinfo->dscp) {
@@ -48,11 +46,9 @@ dscp_tg(struct sk_buff *skb, const struct net_device *in,
48} 46}
49 47
50static unsigned int 48static unsigned int
51dscp_tg6(struct sk_buff *skb, const struct net_device *in, 49dscp_tg6(struct sk_buff *skb, const struct xt_target_param *par)
52 const struct net_device *out, unsigned int hooknum,
53 const struct xt_target *target, const void *targinfo)
54{ 50{
55 const struct xt_DSCP_info *dinfo = targinfo; 51 const struct xt_DSCP_info *dinfo = par->targinfo;
56 u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT; 52 u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT;
57 53
58 if (dscp != dinfo->dscp) { 54 if (dscp != dinfo->dscp) {
@@ -65,26 +61,21 @@ dscp_tg6(struct sk_buff *skb, const struct net_device *in,
65 return XT_CONTINUE; 61 return XT_CONTINUE;
66} 62}
67 63
68static bool 64static bool dscp_tg_check(const struct xt_tgchk_param *par)
69dscp_tg_check(const char *tablename, const void *e_void,
70 const struct xt_target *target, void *targinfo,
71 unsigned int hook_mask)
72{ 65{
73 const u_int8_t dscp = ((struct xt_DSCP_info *)targinfo)->dscp; 66 const struct xt_DSCP_info *info = par->targinfo;
74 67
75 if (dscp > XT_DSCP_MAX) { 68 if (info->dscp > XT_DSCP_MAX) {
76 printk(KERN_WARNING "DSCP: dscp %x out of range\n", dscp); 69 printk(KERN_WARNING "DSCP: dscp %x out of range\n", info->dscp);
77 return false; 70 return false;
78 } 71 }
79 return true; 72 return true;
80} 73}
81 74
82static unsigned int 75static unsigned int
83tos_tg_v0(struct sk_buff *skb, const struct net_device *in, 76tos_tg_v0(struct sk_buff *skb, const struct xt_target_param *par)
84 const struct net_device *out, unsigned int hooknum,
85 const struct xt_target *target, const void *targinfo)
86{ 77{
87 const struct ipt_tos_target_info *info = targinfo; 78 const struct ipt_tos_target_info *info = par->targinfo;
88 struct iphdr *iph = ip_hdr(skb); 79 struct iphdr *iph = ip_hdr(skb);
89 u_int8_t oldtos; 80 u_int8_t oldtos;
90 81
@@ -101,12 +92,10 @@ tos_tg_v0(struct sk_buff *skb, const struct net_device *in,
101 return XT_CONTINUE; 92 return XT_CONTINUE;
102} 93}
103 94
104static bool 95static bool tos_tg_check_v0(const struct xt_tgchk_param *par)
105tos_tg_check_v0(const char *tablename, const void *e_void,
106 const struct xt_target *target, void *targinfo,
107 unsigned int hook_mask)
108{ 96{
109 const u_int8_t tos = ((struct ipt_tos_target_info *)targinfo)->tos; 97 const struct ipt_tos_target_info *info = par->targinfo;
98 const uint8_t tos = info->tos;
110 99
111 if (tos != IPTOS_LOWDELAY && tos != IPTOS_THROUGHPUT && 100 if (tos != IPTOS_LOWDELAY && tos != IPTOS_THROUGHPUT &&
112 tos != IPTOS_RELIABILITY && tos != IPTOS_MINCOST && 101 tos != IPTOS_RELIABILITY && tos != IPTOS_MINCOST &&
@@ -119,11 +108,9 @@ tos_tg_check_v0(const char *tablename, const void *e_void,
119} 108}
120 109
121static unsigned int 110static unsigned int
122tos_tg(struct sk_buff *skb, const struct net_device *in, 111tos_tg(struct sk_buff *skb, const struct xt_target_param *par)
123 const struct net_device *out, unsigned int hooknum,
124 const struct xt_target *target, const void *targinfo)
125{ 112{
126 const struct xt_tos_target_info *info = targinfo; 113 const struct xt_tos_target_info *info = par->targinfo;
127 struct iphdr *iph = ip_hdr(skb); 114 struct iphdr *iph = ip_hdr(skb);
128 u_int8_t orig, nv; 115 u_int8_t orig, nv;
129 116
@@ -141,11 +128,9 @@ tos_tg(struct sk_buff *skb, const struct net_device *in,
141} 128}
142 129
143static unsigned int 130static unsigned int
144tos_tg6(struct sk_buff *skb, const struct net_device *in, 131tos_tg6(struct sk_buff *skb, const struct xt_target_param *par)
145 const struct net_device *out, unsigned int hooknum,
146 const struct xt_target *target, const void *targinfo)
147{ 132{
148 const struct xt_tos_target_info *info = targinfo; 133 const struct xt_tos_target_info *info = par->targinfo;
149 struct ipv6hdr *iph = ipv6_hdr(skb); 134 struct ipv6hdr *iph = ipv6_hdr(skb);
150 u_int8_t orig, nv; 135 u_int8_t orig, nv;
151 136
@@ -165,7 +150,7 @@ tos_tg6(struct sk_buff *skb, const struct net_device *in,
165static struct xt_target dscp_tg_reg[] __read_mostly = { 150static struct xt_target dscp_tg_reg[] __read_mostly = {
166 { 151 {
167 .name = "DSCP", 152 .name = "DSCP",
168 .family = AF_INET, 153 .family = NFPROTO_IPV4,
169 .checkentry = dscp_tg_check, 154 .checkentry = dscp_tg_check,
170 .target = dscp_tg, 155 .target = dscp_tg,
171 .targetsize = sizeof(struct xt_DSCP_info), 156 .targetsize = sizeof(struct xt_DSCP_info),
@@ -174,7 +159,7 @@ static struct xt_target dscp_tg_reg[] __read_mostly = {
174 }, 159 },
175 { 160 {
176 .name = "DSCP", 161 .name = "DSCP",
177 .family = AF_INET6, 162 .family = NFPROTO_IPV6,
178 .checkentry = dscp_tg_check, 163 .checkentry = dscp_tg_check,
179 .target = dscp_tg6, 164 .target = dscp_tg6,
180 .targetsize = sizeof(struct xt_DSCP_info), 165 .targetsize = sizeof(struct xt_DSCP_info),
@@ -184,7 +169,7 @@ static struct xt_target dscp_tg_reg[] __read_mostly = {
184 { 169 {
185 .name = "TOS", 170 .name = "TOS",
186 .revision = 0, 171 .revision = 0,
187 .family = AF_INET, 172 .family = NFPROTO_IPV4,
188 .table = "mangle", 173 .table = "mangle",
189 .target = tos_tg_v0, 174 .target = tos_tg_v0,
190 .targetsize = sizeof(struct ipt_tos_target_info), 175 .targetsize = sizeof(struct ipt_tos_target_info),
@@ -194,7 +179,7 @@ static struct xt_target dscp_tg_reg[] __read_mostly = {
194 { 179 {
195 .name = "TOS", 180 .name = "TOS",
196 .revision = 1, 181 .revision = 1,
197 .family = AF_INET, 182 .family = NFPROTO_IPV4,
198 .table = "mangle", 183 .table = "mangle",
199 .target = tos_tg, 184 .target = tos_tg,
200 .targetsize = sizeof(struct xt_tos_target_info), 185 .targetsize = sizeof(struct xt_tos_target_info),
@@ -203,7 +188,7 @@ static struct xt_target dscp_tg_reg[] __read_mostly = {
203 { 188 {
204 .name = "TOS", 189 .name = "TOS",
205 .revision = 1, 190 .revision = 1,
206 .family = AF_INET6, 191 .family = NFPROTO_IPV6,
207 .table = "mangle", 192 .table = "mangle",
208 .target = tos_tg6, 193 .target = tos_tg6,
209 .targetsize = sizeof(struct xt_tos_target_info), 194 .targetsize = sizeof(struct xt_tos_target_info),
diff --git a/net/netfilter/xt_MARK.c b/net/netfilter/xt_MARK.c
index f9ce20b58981..67574bcfb8ac 100644
--- a/net/netfilter/xt_MARK.c
+++ b/net/netfilter/xt_MARK.c
@@ -25,22 +25,18 @@ MODULE_ALIAS("ipt_MARK");
25MODULE_ALIAS("ip6t_MARK"); 25MODULE_ALIAS("ip6t_MARK");
26 26
27static unsigned int 27static unsigned int
28mark_tg_v0(struct sk_buff *skb, const struct net_device *in, 28mark_tg_v0(struct sk_buff *skb, const struct xt_target_param *par)
29 const struct net_device *out, unsigned int hooknum,
30 const struct xt_target *target, const void *targinfo)
31{ 29{
32 const struct xt_mark_target_info *markinfo = targinfo; 30 const struct xt_mark_target_info *markinfo = par->targinfo;
33 31
34 skb->mark = markinfo->mark; 32 skb->mark = markinfo->mark;
35 return XT_CONTINUE; 33 return XT_CONTINUE;
36} 34}
37 35
38static unsigned int 36static unsigned int
39mark_tg_v1(struct sk_buff *skb, const struct net_device *in, 37mark_tg_v1(struct sk_buff *skb, const struct xt_target_param *par)
40 const struct net_device *out, unsigned int hooknum,
41 const struct xt_target *target, const void *targinfo)
42{ 38{
43 const struct xt_mark_target_info_v1 *markinfo = targinfo; 39 const struct xt_mark_target_info_v1 *markinfo = par->targinfo;
44 int mark = 0; 40 int mark = 0;
45 41
46 switch (markinfo->mode) { 42 switch (markinfo->mode) {
@@ -62,22 +58,17 @@ mark_tg_v1(struct sk_buff *skb, const struct net_device *in,
62} 58}
63 59
64static unsigned int 60static unsigned int
65mark_tg(struct sk_buff *skb, const struct net_device *in, 61mark_tg(struct sk_buff *skb, const struct xt_target_param *par)
66 const struct net_device *out, unsigned int hooknum,
67 const struct xt_target *target, const void *targinfo)
68{ 62{
69 const struct xt_mark_tginfo2 *info = targinfo; 63 const struct xt_mark_tginfo2 *info = par->targinfo;
70 64
71 skb->mark = (skb->mark & ~info->mask) ^ info->mark; 65 skb->mark = (skb->mark & ~info->mask) ^ info->mark;
72 return XT_CONTINUE; 66 return XT_CONTINUE;
73} 67}
74 68
75static bool 69static bool mark_tg_check_v0(const struct xt_tgchk_param *par)
76mark_tg_check_v0(const char *tablename, const void *entry,
77 const struct xt_target *target, void *targinfo,
78 unsigned int hook_mask)
79{ 70{
80 const struct xt_mark_target_info *markinfo = targinfo; 71 const struct xt_mark_target_info *markinfo = par->targinfo;
81 72
82 if (markinfo->mark > 0xffffffff) { 73 if (markinfo->mark > 0xffffffff) {
83 printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n"); 74 printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n");
@@ -86,12 +77,9 @@ mark_tg_check_v0(const char *tablename, const void *entry,
86 return true; 77 return true;
87} 78}
88 79
89static bool 80static bool mark_tg_check_v1(const struct xt_tgchk_param *par)
90mark_tg_check_v1(const char *tablename, const void *entry,
91 const struct xt_target *target, void *targinfo,
92 unsigned int hook_mask)
93{ 81{
94 const struct xt_mark_target_info_v1 *markinfo = targinfo; 82 const struct xt_mark_target_info_v1 *markinfo = par->targinfo;
95 83
96 if (markinfo->mode != XT_MARK_SET 84 if (markinfo->mode != XT_MARK_SET
97 && markinfo->mode != XT_MARK_AND 85 && markinfo->mode != XT_MARK_AND
@@ -161,7 +149,7 @@ static int mark_tg_compat_to_user_v1(void __user *dst, void *src)
161static struct xt_target mark_tg_reg[] __read_mostly = { 149static struct xt_target mark_tg_reg[] __read_mostly = {
162 { 150 {
163 .name = "MARK", 151 .name = "MARK",
164 .family = AF_INET, 152 .family = NFPROTO_UNSPEC,
165 .revision = 0, 153 .revision = 0,
166 .checkentry = mark_tg_check_v0, 154 .checkentry = mark_tg_check_v0,
167 .target = mark_tg_v0, 155 .target = mark_tg_v0,
@@ -176,7 +164,7 @@ static struct xt_target mark_tg_reg[] __read_mostly = {
176 }, 164 },
177 { 165 {
178 .name = "MARK", 166 .name = "MARK",
179 .family = AF_INET, 167 .family = NFPROTO_UNSPEC,
180 .revision = 1, 168 .revision = 1,
181 .checkentry = mark_tg_check_v1, 169 .checkentry = mark_tg_check_v1,
182 .target = mark_tg_v1, 170 .target = mark_tg_v1,
@@ -190,47 +178,9 @@ static struct xt_target mark_tg_reg[] __read_mostly = {
190 .me = THIS_MODULE, 178 .me = THIS_MODULE,
191 }, 179 },
192 { 180 {
193 .name = "MARK",
194 .family = AF_INET6,
195 .revision = 0,
196 .checkentry = mark_tg_check_v0,
197 .target = mark_tg_v0,
198 .targetsize = sizeof(struct xt_mark_target_info),
199#ifdef CONFIG_COMPAT
200 .compatsize = sizeof(struct compat_xt_mark_target_info),
201 .compat_from_user = mark_tg_compat_from_user_v0,
202 .compat_to_user = mark_tg_compat_to_user_v0,
203#endif
204 .table = "mangle",
205 .me = THIS_MODULE,
206 },
207 {
208 .name = "MARK",
209 .family = AF_INET6,
210 .revision = 1,
211 .checkentry = mark_tg_check_v1,
212 .target = mark_tg_v1,
213 .targetsize = sizeof(struct xt_mark_target_info_v1),
214#ifdef CONFIG_COMPAT
215 .compatsize = sizeof(struct compat_xt_mark_target_info_v1),
216 .compat_from_user = mark_tg_compat_from_user_v1,
217 .compat_to_user = mark_tg_compat_to_user_v1,
218#endif
219 .table = "mangle",
220 .me = THIS_MODULE,
221 },
222 {
223 .name = "MARK",
224 .revision = 2,
225 .family = AF_INET,
226 .target = mark_tg,
227 .targetsize = sizeof(struct xt_mark_tginfo2),
228 .me = THIS_MODULE,
229 },
230 {
231 .name = "MARK", 181 .name = "MARK",
232 .revision = 2, 182 .revision = 2,
233 .family = AF_INET6, 183 .family = NFPROTO_UNSPEC,
234 .target = mark_tg, 184 .target = mark_tg,
235 .targetsize = sizeof(struct xt_mark_tginfo2), 185 .targetsize = sizeof(struct xt_mark_tginfo2),
236 .me = THIS_MODULE, 186 .me = THIS_MODULE,
diff --git a/net/netfilter/xt_NFLOG.c b/net/netfilter/xt_NFLOG.c
index 19ae8efae655..50e3a52d3b31 100644
--- a/net/netfilter/xt_NFLOG.c
+++ b/net/netfilter/xt_NFLOG.c
@@ -21,11 +21,9 @@ MODULE_ALIAS("ipt_NFLOG");
21MODULE_ALIAS("ip6t_NFLOG"); 21MODULE_ALIAS("ip6t_NFLOG");
22 22
23static unsigned int 23static unsigned int
24nflog_tg(struct sk_buff *skb, const struct net_device *in, 24nflog_tg(struct sk_buff *skb, const struct xt_target_param *par)
25 const struct net_device *out, unsigned int hooknum,
26 const struct xt_target *target, const void *targinfo)
27{ 25{
28 const struct xt_nflog_info *info = targinfo; 26 const struct xt_nflog_info *info = par->targinfo;
29 struct nf_loginfo li; 27 struct nf_loginfo li;
30 28
31 li.type = NF_LOG_TYPE_ULOG; 29 li.type = NF_LOG_TYPE_ULOG;
@@ -33,17 +31,14 @@ nflog_tg(struct sk_buff *skb, const struct net_device *in,
33 li.u.ulog.group = info->group; 31 li.u.ulog.group = info->group;
34 li.u.ulog.qthreshold = info->threshold; 32 li.u.ulog.qthreshold = info->threshold;
35 33
36 nf_log_packet(target->family, hooknum, skb, in, out, &li, 34 nf_log_packet(par->family, par->hooknum, skb, par->in,
37 "%s", info->prefix); 35 par->out, &li, "%s", info->prefix);
38 return XT_CONTINUE; 36 return XT_CONTINUE;
39} 37}
40 38
41static bool 39static bool nflog_tg_check(const struct xt_tgchk_param *par)
42nflog_tg_check(const char *tablename, const void *entry,
43 const struct xt_target *target, void *targetinfo,
44 unsigned int hookmask)
45{ 40{
46 const struct xt_nflog_info *info = targetinfo; 41 const struct xt_nflog_info *info = par->targinfo;
47 42
48 if (info->flags & ~XT_NFLOG_MASK) 43 if (info->flags & ~XT_NFLOG_MASK)
49 return false; 44 return false;
@@ -52,33 +47,24 @@ nflog_tg_check(const char *tablename, const void *entry,
52 return true; 47 return true;
53} 48}
54 49
55static struct xt_target nflog_tg_reg[] __read_mostly = { 50static struct xt_target nflog_tg_reg __read_mostly = {
56 { 51 .name = "NFLOG",
57 .name = "NFLOG", 52 .revision = 0,
58 .family = AF_INET, 53 .family = NFPROTO_UNSPEC,
59 .checkentry = nflog_tg_check, 54 .checkentry = nflog_tg_check,
60 .target = nflog_tg, 55 .target = nflog_tg,
61 .targetsize = sizeof(struct xt_nflog_info), 56 .targetsize = sizeof(struct xt_nflog_info),
62 .me = THIS_MODULE, 57 .me = THIS_MODULE,
63 },
64 {
65 .name = "NFLOG",
66 .family = AF_INET6,
67 .checkentry = nflog_tg_check,
68 .target = nflog_tg,
69 .targetsize = sizeof(struct xt_nflog_info),
70 .me = THIS_MODULE,
71 },
72}; 58};
73 59
74static int __init nflog_tg_init(void) 60static int __init nflog_tg_init(void)
75{ 61{
76 return xt_register_targets(nflog_tg_reg, ARRAY_SIZE(nflog_tg_reg)); 62 return xt_register_target(&nflog_tg_reg);
77} 63}
78 64
79static void __exit nflog_tg_exit(void) 65static void __exit nflog_tg_exit(void)
80{ 66{
81 xt_unregister_targets(nflog_tg_reg, ARRAY_SIZE(nflog_tg_reg)); 67 xt_unregister_target(&nflog_tg_reg);
82} 68}
83 69
84module_init(nflog_tg_init); 70module_init(nflog_tg_init);
diff --git a/net/netfilter/xt_NFQUEUE.c b/net/netfilter/xt_NFQUEUE.c
index beb24d19a56f..2cc1fff49307 100644
--- a/net/netfilter/xt_NFQUEUE.c
+++ b/net/netfilter/xt_NFQUEUE.c
@@ -24,11 +24,9 @@ MODULE_ALIAS("ip6t_NFQUEUE");
24MODULE_ALIAS("arpt_NFQUEUE"); 24MODULE_ALIAS("arpt_NFQUEUE");
25 25
26static unsigned int 26static unsigned int
27nfqueue_tg(struct sk_buff *skb, const struct net_device *in, 27nfqueue_tg(struct sk_buff *skb, const struct xt_target_param *par)
28 const struct net_device *out, unsigned int hooknum,
29 const struct xt_target *target, const void *targinfo)
30{ 28{
31 const struct xt_NFQ_info *tinfo = targinfo; 29 const struct xt_NFQ_info *tinfo = par->targinfo;
32 30
33 return NF_QUEUE_NR(tinfo->queuenum); 31 return NF_QUEUE_NR(tinfo->queuenum);
34} 32}
@@ -36,14 +34,14 @@ nfqueue_tg(struct sk_buff *skb, const struct net_device *in,
36static struct xt_target nfqueue_tg_reg[] __read_mostly = { 34static struct xt_target nfqueue_tg_reg[] __read_mostly = {
37 { 35 {
38 .name = "NFQUEUE", 36 .name = "NFQUEUE",
39 .family = AF_INET, 37 .family = NFPROTO_IPV4,
40 .target = nfqueue_tg, 38 .target = nfqueue_tg,
41 .targetsize = sizeof(struct xt_NFQ_info), 39 .targetsize = sizeof(struct xt_NFQ_info),
42 .me = THIS_MODULE, 40 .me = THIS_MODULE,
43 }, 41 },
44 { 42 {
45 .name = "NFQUEUE", 43 .name = "NFQUEUE",
46 .family = AF_INET6, 44 .family = NFPROTO_IPV6,
47 .target = nfqueue_tg, 45 .target = nfqueue_tg,
48 .targetsize = sizeof(struct xt_NFQ_info), 46 .targetsize = sizeof(struct xt_NFQ_info),
49 .me = THIS_MODULE, 47 .me = THIS_MODULE,
diff --git a/net/netfilter/xt_NOTRACK.c b/net/netfilter/xt_NOTRACK.c
index 6c9de611eb8d..e7a0a54fd4ea 100644
--- a/net/netfilter/xt_NOTRACK.c
+++ b/net/netfilter/xt_NOTRACK.c
@@ -13,9 +13,7 @@ MODULE_ALIAS("ipt_NOTRACK");
13MODULE_ALIAS("ip6t_NOTRACK"); 13MODULE_ALIAS("ip6t_NOTRACK");
14 14
15static unsigned int 15static unsigned int
16notrack_tg(struct sk_buff *skb, const struct net_device *in, 16notrack_tg(struct sk_buff *skb, const struct xt_target_param *par)
17 const struct net_device *out, unsigned int hooknum,
18 const struct xt_target *target, const void *targinfo)
19{ 17{
20 /* Previously seen (loopback)? Ignore. */ 18 /* Previously seen (loopback)? Ignore. */
21 if (skb->nfct != NULL) 19 if (skb->nfct != NULL)
@@ -32,31 +30,23 @@ notrack_tg(struct sk_buff *skb, const struct net_device *in,
32 return XT_CONTINUE; 30 return XT_CONTINUE;
33} 31}
34 32
35static struct xt_target notrack_tg_reg[] __read_mostly = { 33static struct xt_target notrack_tg_reg __read_mostly = {
36 { 34 .name = "NOTRACK",
37 .name = "NOTRACK", 35 .revision = 0,
38 .family = AF_INET, 36 .family = NFPROTO_UNSPEC,
39 .target = notrack_tg, 37 .target = notrack_tg,
40 .table = "raw", 38 .table = "raw",
41 .me = THIS_MODULE, 39 .me = THIS_MODULE,
42 },
43 {
44 .name = "NOTRACK",
45 .family = AF_INET6,
46 .target = notrack_tg,
47 .table = "raw",
48 .me = THIS_MODULE,
49 },
50}; 40};
51 41
52static int __init notrack_tg_init(void) 42static int __init notrack_tg_init(void)
53{ 43{
54 return xt_register_targets(notrack_tg_reg, ARRAY_SIZE(notrack_tg_reg)); 44 return xt_register_target(&notrack_tg_reg);
55} 45}
56 46
57static void __exit notrack_tg_exit(void) 47static void __exit notrack_tg_exit(void)
58{ 48{
59 xt_unregister_targets(notrack_tg_reg, ARRAY_SIZE(notrack_tg_reg)); 49 xt_unregister_target(&notrack_tg_reg);
60} 50}
61 51
62module_init(notrack_tg_init); 52module_init(notrack_tg_init);
diff --git a/net/netfilter/xt_RATEEST.c b/net/netfilter/xt_RATEEST.c
index 64d6ad380293..43f5676b1af4 100644
--- a/net/netfilter/xt_RATEEST.c
+++ b/net/netfilter/xt_RATEEST.c
@@ -71,14 +71,9 @@ void xt_rateest_put(struct xt_rateest *est)
71EXPORT_SYMBOL_GPL(xt_rateest_put); 71EXPORT_SYMBOL_GPL(xt_rateest_put);
72 72
73static unsigned int 73static unsigned int
74xt_rateest_tg(struct sk_buff *skb, 74xt_rateest_tg(struct sk_buff *skb, const struct xt_target_param *par)
75 const struct net_device *in,
76 const struct net_device *out,
77 unsigned int hooknum,
78 const struct xt_target *target,
79 const void *targinfo)
80{ 75{
81 const struct xt_rateest_target_info *info = targinfo; 76 const struct xt_rateest_target_info *info = par->targinfo;
82 struct gnet_stats_basic *stats = &info->est->bstats; 77 struct gnet_stats_basic *stats = &info->est->bstats;
83 78
84 spin_lock_bh(&info->est->lock); 79 spin_lock_bh(&info->est->lock);
@@ -89,14 +84,9 @@ xt_rateest_tg(struct sk_buff *skb,
89 return XT_CONTINUE; 84 return XT_CONTINUE;
90} 85}
91 86
92static bool 87static bool xt_rateest_tg_checkentry(const struct xt_tgchk_param *par)
93xt_rateest_tg_checkentry(const char *tablename,
94 const void *entry,
95 const struct xt_target *target,
96 void *targinfo,
97 unsigned int hook_mask)
98{ 88{
99 struct xt_rateest_target_info *info = targinfo; 89 struct xt_rateest_target_info *info = par->targinfo;
100 struct xt_rateest *est; 90 struct xt_rateest *est;
101 struct { 91 struct {
102 struct nlattr opt; 92 struct nlattr opt;
@@ -149,33 +139,22 @@ err1:
149 return false; 139 return false;
150} 140}
151 141
152static void xt_rateest_tg_destroy(const struct xt_target *target, 142static void xt_rateest_tg_destroy(const struct xt_tgdtor_param *par)
153 void *targinfo)
154{ 143{
155 struct xt_rateest_target_info *info = targinfo; 144 struct xt_rateest_target_info *info = par->targinfo;
156 145
157 xt_rateest_put(info->est); 146 xt_rateest_put(info->est);
158} 147}
159 148
160static struct xt_target xt_rateest_target[] __read_mostly = { 149static struct xt_target xt_rateest_tg_reg __read_mostly = {
161 { 150 .name = "RATEEST",
162 .family = AF_INET, 151 .revision = 0,
163 .name = "RATEEST", 152 .family = NFPROTO_UNSPEC,
164 .target = xt_rateest_tg, 153 .target = xt_rateest_tg,
165 .checkentry = xt_rateest_tg_checkentry, 154 .checkentry = xt_rateest_tg_checkentry,
166 .destroy = xt_rateest_tg_destroy, 155 .destroy = xt_rateest_tg_destroy,
167 .targetsize = sizeof(struct xt_rateest_target_info), 156 .targetsize = sizeof(struct xt_rateest_target_info),
168 .me = THIS_MODULE, 157 .me = THIS_MODULE,
169 },
170 {
171 .family = AF_INET6,
172 .name = "RATEEST",
173 .target = xt_rateest_tg,
174 .checkentry = xt_rateest_tg_checkentry,
175 .destroy = xt_rateest_tg_destroy,
176 .targetsize = sizeof(struct xt_rateest_target_info),
177 .me = THIS_MODULE,
178 },
179}; 158};
180 159
181static int __init xt_rateest_tg_init(void) 160static int __init xt_rateest_tg_init(void)
@@ -186,13 +165,12 @@ static int __init xt_rateest_tg_init(void)
186 INIT_HLIST_HEAD(&rateest_hash[i]); 165 INIT_HLIST_HEAD(&rateest_hash[i]);
187 166
188 get_random_bytes(&jhash_rnd, sizeof(jhash_rnd)); 167 get_random_bytes(&jhash_rnd, sizeof(jhash_rnd));
189 return xt_register_targets(xt_rateest_target, 168 return xt_register_target(&xt_rateest_tg_reg);
190 ARRAY_SIZE(xt_rateest_target));
191} 169}
192 170
193static void __exit xt_rateest_tg_fini(void) 171static void __exit xt_rateest_tg_fini(void)
194{ 172{
195 xt_unregister_targets(xt_rateest_target, ARRAY_SIZE(xt_rateest_target)); 173 xt_unregister_target(&xt_rateest_tg_reg);
196} 174}
197 175
198 176
diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c
index 94f87ee7552b..7a6f9e6f5dfa 100644
--- a/net/netfilter/xt_SECMARK.c
+++ b/net/netfilter/xt_SECMARK.c
@@ -29,12 +29,10 @@ MODULE_ALIAS("ip6t_SECMARK");
29static u8 mode; 29static u8 mode;
30 30
31static unsigned int 31static unsigned int
32secmark_tg(struct sk_buff *skb, const struct net_device *in, 32secmark_tg(struct sk_buff *skb, const struct xt_target_param *par)
33 const struct net_device *out, unsigned int hooknum,
34 const struct xt_target *target, const void *targinfo)
35{ 33{
36 u32 secmark = 0; 34 u32 secmark = 0;
37 const struct xt_secmark_target_info *info = targinfo; 35 const struct xt_secmark_target_info *info = par->targinfo;
38 36
39 BUG_ON(info->mode != mode); 37 BUG_ON(info->mode != mode);
40 38
@@ -82,16 +80,14 @@ static bool checkentry_selinux(struct xt_secmark_target_info *info)
82 return true; 80 return true;
83} 81}
84 82
85static bool 83static bool secmark_tg_check(const struct xt_tgchk_param *par)
86secmark_tg_check(const char *tablename, const void *entry,
87 const struct xt_target *target, void *targinfo,
88 unsigned int hook_mask)
89{ 84{
90 struct xt_secmark_target_info *info = targinfo; 85 struct xt_secmark_target_info *info = par->targinfo;
91 86
92 if (strcmp(tablename, "mangle") && strcmp(tablename, "security")) { 87 if (strcmp(par->table, "mangle") != 0 &&
88 strcmp(par->table, "security") != 0) {
93 printk(KERN_INFO PFX "target only valid in the \'mangle\' " 89 printk(KERN_INFO PFX "target only valid in the \'mangle\' "
94 "or \'security\' tables, not \'%s\'.\n", tablename); 90 "or \'security\' tables, not \'%s\'.\n", par->table);
95 return false; 91 return false;
96 } 92 }
97 93
@@ -117,7 +113,7 @@ secmark_tg_check(const char *tablename, const void *entry,
117 return true; 113 return true;
118} 114}
119 115
120static void secmark_tg_destroy(const struct xt_target *target, void *targinfo) 116static void secmark_tg_destroy(const struct xt_tgdtor_param *par)
121{ 117{
122 switch (mode) { 118 switch (mode) {
123 case SECMARK_MODE_SEL: 119 case SECMARK_MODE_SEL:
@@ -125,35 +121,25 @@ static void secmark_tg_destroy(const struct xt_target *target, void *targinfo)
125 } 121 }
126} 122}
127 123
128static struct xt_target secmark_tg_reg[] __read_mostly = { 124static struct xt_target secmark_tg_reg __read_mostly = {
129 { 125 .name = "SECMARK",
130 .name = "SECMARK", 126 .revision = 0,
131 .family = AF_INET, 127 .family = NFPROTO_UNSPEC,
132 .checkentry = secmark_tg_check, 128 .checkentry = secmark_tg_check,
133 .destroy = secmark_tg_destroy, 129 .destroy = secmark_tg_destroy,
134 .target = secmark_tg, 130 .target = secmark_tg,
135 .targetsize = sizeof(struct xt_secmark_target_info), 131 .targetsize = sizeof(struct xt_secmark_target_info),
136 .me = THIS_MODULE, 132 .me = THIS_MODULE,
137 },
138 {
139 .name = "SECMARK",
140 .family = AF_INET6,
141 .checkentry = secmark_tg_check,
142 .destroy = secmark_tg_destroy,
143 .target = secmark_tg,
144 .targetsize = sizeof(struct xt_secmark_target_info),
145 .me = THIS_MODULE,
146 },
147}; 133};
148 134
149static int __init secmark_tg_init(void) 135static int __init secmark_tg_init(void)
150{ 136{
151 return xt_register_targets(secmark_tg_reg, ARRAY_SIZE(secmark_tg_reg)); 137 return xt_register_target(&secmark_tg_reg);
152} 138}
153 139
154static void __exit secmark_tg_exit(void) 140static void __exit secmark_tg_exit(void)
155{ 141{
156 xt_unregister_targets(secmark_tg_reg, ARRAY_SIZE(secmark_tg_reg)); 142 xt_unregister_target(&secmark_tg_reg);
157} 143}
158 144
159module_init(secmark_tg_init); 145module_init(secmark_tg_init);
diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c
index beb5094703cb..4f3b1f808795 100644
--- a/net/netfilter/xt_TCPMSS.c
+++ b/net/netfilter/xt_TCPMSS.c
@@ -174,15 +174,13 @@ static u_int32_t tcpmss_reverse_mtu(const struct sk_buff *skb,
174} 174}
175 175
176static unsigned int 176static unsigned int
177tcpmss_tg4(struct sk_buff *skb, const struct net_device *in, 177tcpmss_tg4(struct sk_buff *skb, const struct xt_target_param *par)
178 const struct net_device *out, unsigned int hooknum,
179 const struct xt_target *target, const void *targinfo)
180{ 178{
181 struct iphdr *iph = ip_hdr(skb); 179 struct iphdr *iph = ip_hdr(skb);
182 __be16 newlen; 180 __be16 newlen;
183 int ret; 181 int ret;
184 182
185 ret = tcpmss_mangle_packet(skb, targinfo, 183 ret = tcpmss_mangle_packet(skb, par->targinfo,
186 tcpmss_reverse_mtu(skb, PF_INET), 184 tcpmss_reverse_mtu(skb, PF_INET),
187 iph->ihl * 4, 185 iph->ihl * 4,
188 sizeof(*iph) + sizeof(struct tcphdr)); 186 sizeof(*iph) + sizeof(struct tcphdr));
@@ -199,9 +197,7 @@ tcpmss_tg4(struct sk_buff *skb, const struct net_device *in,
199 197
200#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) 198#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
201static unsigned int 199static unsigned int
202tcpmss_tg6(struct sk_buff *skb, const struct net_device *in, 200tcpmss_tg6(struct sk_buff *skb, const struct xt_target_param *par)
203 const struct net_device *out, unsigned int hooknum,
204 const struct xt_target *target, const void *targinfo)
205{ 201{
206 struct ipv6hdr *ipv6h = ipv6_hdr(skb); 202 struct ipv6hdr *ipv6h = ipv6_hdr(skb);
207 u8 nexthdr; 203 u8 nexthdr;
@@ -212,7 +208,7 @@ tcpmss_tg6(struct sk_buff *skb, const struct net_device *in,
212 tcphoff = ipv6_skip_exthdr(skb, sizeof(*ipv6h), &nexthdr); 208 tcphoff = ipv6_skip_exthdr(skb, sizeof(*ipv6h), &nexthdr);
213 if (tcphoff < 0) 209 if (tcphoff < 0)
214 return NF_DROP; 210 return NF_DROP;
215 ret = tcpmss_mangle_packet(skb, targinfo, 211 ret = tcpmss_mangle_packet(skb, par->targinfo,
216 tcpmss_reverse_mtu(skb, PF_INET6), 212 tcpmss_reverse_mtu(skb, PF_INET6),
217 tcphoff, 213 tcphoff,
218 sizeof(*ipv6h) + sizeof(struct tcphdr)); 214 sizeof(*ipv6h) + sizeof(struct tcphdr));
@@ -241,16 +237,13 @@ static inline bool find_syn_match(const struct xt_entry_match *m)
241 return false; 237 return false;
242} 238}
243 239
244static bool 240static bool tcpmss_tg4_check(const struct xt_tgchk_param *par)
245tcpmss_tg4_check(const char *tablename, const void *entry,
246 const struct xt_target *target, void *targinfo,
247 unsigned int hook_mask)
248{ 241{
249 const struct xt_tcpmss_info *info = targinfo; 242 const struct xt_tcpmss_info *info = par->targinfo;
250 const struct ipt_entry *e = entry; 243 const struct ipt_entry *e = par->entryinfo;
251 244
252 if (info->mss == XT_TCPMSS_CLAMP_PMTU && 245 if (info->mss == XT_TCPMSS_CLAMP_PMTU &&
253 (hook_mask & ~((1 << NF_INET_FORWARD) | 246 (par->hook_mask & ~((1 << NF_INET_FORWARD) |
254 (1 << NF_INET_LOCAL_OUT) | 247 (1 << NF_INET_LOCAL_OUT) |
255 (1 << NF_INET_POST_ROUTING))) != 0) { 248 (1 << NF_INET_POST_ROUTING))) != 0) {
256 printk("xt_TCPMSS: path-MTU clamping only supported in " 249 printk("xt_TCPMSS: path-MTU clamping only supported in "
@@ -264,16 +257,13 @@ tcpmss_tg4_check(const char *tablename, const void *entry,
264} 257}
265 258
266#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) 259#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
267static bool 260static bool tcpmss_tg6_check(const struct xt_tgchk_param *par)
268tcpmss_tg6_check(const char *tablename, const void *entry,
269 const struct xt_target *target, void *targinfo,
270 unsigned int hook_mask)
271{ 261{
272 const struct xt_tcpmss_info *info = targinfo; 262 const struct xt_tcpmss_info *info = par->targinfo;
273 const struct ip6t_entry *e = entry; 263 const struct ip6t_entry *e = par->entryinfo;
274 264
275 if (info->mss == XT_TCPMSS_CLAMP_PMTU && 265 if (info->mss == XT_TCPMSS_CLAMP_PMTU &&
276 (hook_mask & ~((1 << NF_INET_FORWARD) | 266 (par->hook_mask & ~((1 << NF_INET_FORWARD) |
277 (1 << NF_INET_LOCAL_OUT) | 267 (1 << NF_INET_LOCAL_OUT) |
278 (1 << NF_INET_POST_ROUTING))) != 0) { 268 (1 << NF_INET_POST_ROUTING))) != 0) {
279 printk("xt_TCPMSS: path-MTU clamping only supported in " 269 printk("xt_TCPMSS: path-MTU clamping only supported in "
@@ -289,7 +279,7 @@ tcpmss_tg6_check(const char *tablename, const void *entry,
289 279
290static struct xt_target tcpmss_tg_reg[] __read_mostly = { 280static struct xt_target tcpmss_tg_reg[] __read_mostly = {
291 { 281 {
292 .family = AF_INET, 282 .family = NFPROTO_IPV4,
293 .name = "TCPMSS", 283 .name = "TCPMSS",
294 .checkentry = tcpmss_tg4_check, 284 .checkentry = tcpmss_tg4_check,
295 .target = tcpmss_tg4, 285 .target = tcpmss_tg4,
@@ -299,7 +289,7 @@ static struct xt_target tcpmss_tg_reg[] __read_mostly = {
299 }, 289 },
300#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) 290#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
301 { 291 {
302 .family = AF_INET6, 292 .family = NFPROTO_IPV6,
303 .name = "TCPMSS", 293 .name = "TCPMSS",
304 .checkentry = tcpmss_tg6_check, 294 .checkentry = tcpmss_tg6_check,
305 .target = tcpmss_tg6, 295 .target = tcpmss_tg6,
diff --git a/net/netfilter/xt_TCPOPTSTRIP.c b/net/netfilter/xt_TCPOPTSTRIP.c
index 9685b6fcbc81..9dd8c8ef63eb 100644
--- a/net/netfilter/xt_TCPOPTSTRIP.c
+++ b/net/netfilter/xt_TCPOPTSTRIP.c
@@ -75,19 +75,15 @@ tcpoptstrip_mangle_packet(struct sk_buff *skb,
75} 75}
76 76
77static unsigned int 77static unsigned int
78tcpoptstrip_tg4(struct sk_buff *skb, const struct net_device *in, 78tcpoptstrip_tg4(struct sk_buff *skb, const struct xt_target_param *par)
79 const struct net_device *out, unsigned int hooknum,
80 const struct xt_target *target, const void *targinfo)
81{ 79{
82 return tcpoptstrip_mangle_packet(skb, targinfo, ip_hdrlen(skb), 80 return tcpoptstrip_mangle_packet(skb, par->targinfo, ip_hdrlen(skb),
83 sizeof(struct iphdr) + sizeof(struct tcphdr)); 81 sizeof(struct iphdr) + sizeof(struct tcphdr));
84} 82}
85 83
86#if defined(CONFIG_IP6_NF_MANGLE) || defined(CONFIG_IP6_NF_MANGLE_MODULE) 84#if defined(CONFIG_IP6_NF_MANGLE) || defined(CONFIG_IP6_NF_MANGLE_MODULE)
87static unsigned int 85static unsigned int
88tcpoptstrip_tg6(struct sk_buff *skb, const struct net_device *in, 86tcpoptstrip_tg6(struct sk_buff *skb, const struct xt_target_param *par)
89 const struct net_device *out, unsigned int hooknum,
90 const struct xt_target *target, const void *targinfo)
91{ 87{
92 struct ipv6hdr *ipv6h = ipv6_hdr(skb); 88 struct ipv6hdr *ipv6h = ipv6_hdr(skb);
93 int tcphoff; 89 int tcphoff;
@@ -98,7 +94,7 @@ tcpoptstrip_tg6(struct sk_buff *skb, const struct net_device *in,
98 if (tcphoff < 0) 94 if (tcphoff < 0)
99 return NF_DROP; 95 return NF_DROP;
100 96
101 return tcpoptstrip_mangle_packet(skb, targinfo, tcphoff, 97 return tcpoptstrip_mangle_packet(skb, par->targinfo, tcphoff,
102 sizeof(*ipv6h) + sizeof(struct tcphdr)); 98 sizeof(*ipv6h) + sizeof(struct tcphdr));
103} 99}
104#endif 100#endif
@@ -106,7 +102,7 @@ tcpoptstrip_tg6(struct sk_buff *skb, const struct net_device *in,
106static struct xt_target tcpoptstrip_tg_reg[] __read_mostly = { 102static struct xt_target tcpoptstrip_tg_reg[] __read_mostly = {
107 { 103 {
108 .name = "TCPOPTSTRIP", 104 .name = "TCPOPTSTRIP",
109 .family = AF_INET, 105 .family = NFPROTO_IPV4,
110 .table = "mangle", 106 .table = "mangle",
111 .proto = IPPROTO_TCP, 107 .proto = IPPROTO_TCP,
112 .target = tcpoptstrip_tg4, 108 .target = tcpoptstrip_tg4,
@@ -116,7 +112,7 @@ static struct xt_target tcpoptstrip_tg_reg[] __read_mostly = {
116#if defined(CONFIG_IP6_NF_MANGLE) || defined(CONFIG_IP6_NF_MANGLE_MODULE) 112#if defined(CONFIG_IP6_NF_MANGLE) || defined(CONFIG_IP6_NF_MANGLE_MODULE)
117 { 113 {
118 .name = "TCPOPTSTRIP", 114 .name = "TCPOPTSTRIP",
119 .family = AF_INET6, 115 .family = NFPROTO_IPV6,
120 .table = "mangle", 116 .table = "mangle",
121 .proto = IPPROTO_TCP, 117 .proto = IPPROTO_TCP,
122 .target = tcpoptstrip_tg6, 118 .target = tcpoptstrip_tg6,
diff --git a/net/netfilter/xt_TPROXY.c b/net/netfilter/xt_TPROXY.c
new file mode 100644
index 000000000000..1340c2fa3621
--- /dev/null
+++ b/net/netfilter/xt_TPROXY.c
@@ -0,0 +1,102 @@
1/*
2 * Transparent proxy support for Linux/iptables
3 *
4 * Copyright (c) 2006-2007 BalaBit IT Ltd.
5 * Author: Balazs Scheidler, Krisztian Kovacs
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 */
12
13#include <linux/module.h>
14#include <linux/skbuff.h>
15#include <linux/ip.h>
16#include <net/checksum.h>
17#include <net/udp.h>
18#include <net/inet_sock.h>
19
20#include <linux/netfilter/x_tables.h>
21#include <linux/netfilter_ipv4/ip_tables.h>
22#include <linux/netfilter/xt_TPROXY.h>
23
24#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
25#include <net/netfilter/nf_tproxy_core.h>
26
27static unsigned int
28tproxy_tg(struct sk_buff *skb, const struct xt_target_param *par)
29{
30 const struct iphdr *iph = ip_hdr(skb);
31 const struct xt_tproxy_target_info *tgi = par->targinfo;
32 struct udphdr _hdr, *hp;
33 struct sock *sk;
34
35 hp = skb_header_pointer(skb, ip_hdrlen(skb), sizeof(_hdr), &_hdr);
36 if (hp == NULL)
37 return NF_DROP;
38
39 sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), iph->protocol,
40 iph->saddr, tgi->laddr ? tgi->laddr : iph->daddr,
41 hp->source, tgi->lport ? tgi->lport : hp->dest,
42 par->in, true);
43
44 /* NOTE: assign_sock consumes our sk reference */
45 if (sk && nf_tproxy_assign_sock(skb, sk)) {
46 /* This should be in a separate target, but we don't do multiple
47 targets on the same rule yet */
48 skb->mark = (skb->mark & ~tgi->mark_mask) ^ tgi->mark_value;
49
50 pr_debug("redirecting: proto %u %08x:%u -> %08x:%u, mark: %x\n",
51 iph->protocol, ntohl(iph->daddr), ntohs(hp->dest),
52 ntohl(tgi->laddr), ntohs(tgi->lport), skb->mark);
53 return NF_ACCEPT;
54 }
55
56 pr_debug("no socket, dropping: proto %u %08x:%u -> %08x:%u, mark: %x\n",
57 iph->protocol, ntohl(iph->daddr), ntohs(hp->dest),
58 ntohl(tgi->laddr), ntohs(tgi->lport), skb->mark);
59 return NF_DROP;
60}
61
62static bool tproxy_tg_check(const struct xt_tgchk_param *par)
63{
64 const struct ipt_ip *i = par->entryinfo;
65
66 if ((i->proto == IPPROTO_TCP || i->proto == IPPROTO_UDP)
67 && !(i->invflags & IPT_INV_PROTO))
68 return true;
69
70 pr_info("xt_TPROXY: Can be used only in combination with "
71 "either -p tcp or -p udp\n");
72 return false;
73}
74
75static struct xt_target tproxy_tg_reg __read_mostly = {
76 .name = "TPROXY",
77 .family = AF_INET,
78 .table = "mangle",
79 .target = tproxy_tg,
80 .targetsize = sizeof(struct xt_tproxy_target_info),
81 .checkentry = tproxy_tg_check,
82 .hooks = 1 << NF_INET_PRE_ROUTING,
83 .me = THIS_MODULE,
84};
85
86static int __init tproxy_tg_init(void)
87{
88 nf_defrag_ipv4_enable();
89 return xt_register_target(&tproxy_tg_reg);
90}
91
92static void __exit tproxy_tg_exit(void)
93{
94 xt_unregister_target(&tproxy_tg_reg);
95}
96
97module_init(tproxy_tg_init);
98module_exit(tproxy_tg_exit);
99MODULE_LICENSE("GPL");
100MODULE_AUTHOR("Krisztian Kovacs");
101MODULE_DESCRIPTION("Netfilter transparent proxy (TPROXY) target module.");
102MODULE_ALIAS("ipt_TPROXY");
diff --git a/net/netfilter/xt_TRACE.c b/net/netfilter/xt_TRACE.c
index 30dab79a3438..fbb04b86c46b 100644
--- a/net/netfilter/xt_TRACE.c
+++ b/net/netfilter/xt_TRACE.c
@@ -11,39 +11,29 @@ MODULE_ALIAS("ipt_TRACE");
11MODULE_ALIAS("ip6t_TRACE"); 11MODULE_ALIAS("ip6t_TRACE");
12 12
13static unsigned int 13static unsigned int
14trace_tg(struct sk_buff *skb, const struct net_device *in, 14trace_tg(struct sk_buff *skb, const struct xt_target_param *par)
15 const struct net_device *out, unsigned int hooknum,
16 const struct xt_target *target, const void *targinfo)
17{ 15{
18 skb->nf_trace = 1; 16 skb->nf_trace = 1;
19 return XT_CONTINUE; 17 return XT_CONTINUE;
20} 18}
21 19
22static struct xt_target trace_tg_reg[] __read_mostly = { 20static struct xt_target trace_tg_reg __read_mostly = {
23 { 21 .name = "TRACE",
24 .name = "TRACE", 22 .revision = 0,
25 .family = AF_INET, 23 .family = NFPROTO_UNSPEC,
26 .target = trace_tg, 24 .table = "raw",
27 .table = "raw", 25 .target = trace_tg,
28 .me = THIS_MODULE, 26 .me = THIS_MODULE,
29 },
30 {
31 .name = "TRACE",
32 .family = AF_INET6,
33 .target = trace_tg,
34 .table = "raw",
35 .me = THIS_MODULE,
36 },
37}; 27};
38 28
39static int __init trace_tg_init(void) 29static int __init trace_tg_init(void)
40{ 30{
41 return xt_register_targets(trace_tg_reg, ARRAY_SIZE(trace_tg_reg)); 31 return xt_register_target(&trace_tg_reg);
42} 32}
43 33
44static void __exit trace_tg_exit(void) 34static void __exit trace_tg_exit(void)
45{ 35{
46 xt_unregister_targets(trace_tg_reg, ARRAY_SIZE(trace_tg_reg)); 36 xt_unregister_target(&trace_tg_reg);
47} 37}
48 38
49module_init(trace_tg_init); 39module_init(trace_tg_init);
diff --git a/net/netfilter/xt_comment.c b/net/netfilter/xt_comment.c
index 89f47364e848..e82179832acd 100644
--- a/net/netfilter/xt_comment.c
+++ b/net/netfilter/xt_comment.c
@@ -16,40 +16,29 @@ MODULE_ALIAS("ipt_comment");
16MODULE_ALIAS("ip6t_comment"); 16MODULE_ALIAS("ip6t_comment");
17 17
18static bool 18static bool
19comment_mt(const struct sk_buff *skb, const struct net_device *in, 19comment_mt(const struct sk_buff *skb, const struct xt_match_param *par)
20 const struct net_device *out, const struct xt_match *match,
21 const void *matchinfo, int offset, unsigned int protooff,
22 bool *hotdrop)
23{ 20{
24 /* We always match */ 21 /* We always match */
25 return true; 22 return true;
26} 23}
27 24
28static struct xt_match comment_mt_reg[] __read_mostly = { 25static struct xt_match comment_mt_reg __read_mostly = {
29 { 26 .name = "comment",
30 .name = "comment", 27 .revision = 0,
31 .family = AF_INET, 28 .family = NFPROTO_UNSPEC,
32 .match = comment_mt, 29 .match = comment_mt,
33 .matchsize = sizeof(struct xt_comment_info), 30 .matchsize = sizeof(struct xt_comment_info),
34 .me = THIS_MODULE 31 .me = THIS_MODULE,
35 },
36 {
37 .name = "comment",
38 .family = AF_INET6,
39 .match = comment_mt,
40 .matchsize = sizeof(struct xt_comment_info),
41 .me = THIS_MODULE
42 },
43}; 32};
44 33
45static int __init comment_mt_init(void) 34static int __init comment_mt_init(void)
46{ 35{
47 return xt_register_matches(comment_mt_reg, ARRAY_SIZE(comment_mt_reg)); 36 return xt_register_match(&comment_mt_reg);
48} 37}
49 38
50static void __exit comment_mt_exit(void) 39static void __exit comment_mt_exit(void)
51{ 40{
52 xt_unregister_matches(comment_mt_reg, ARRAY_SIZE(comment_mt_reg)); 41 xt_unregister_match(&comment_mt_reg);
53} 42}
54 43
55module_init(comment_mt_init); 44module_init(comment_mt_init);
diff --git a/net/netfilter/xt_connbytes.c b/net/netfilter/xt_connbytes.c
index 3e39c4fe1931..955e6598a7f0 100644
--- a/net/netfilter/xt_connbytes.c
+++ b/net/netfilter/xt_connbytes.c
@@ -17,12 +17,9 @@ MODULE_ALIAS("ipt_connbytes");
17MODULE_ALIAS("ip6t_connbytes"); 17MODULE_ALIAS("ip6t_connbytes");
18 18
19static bool 19static bool
20connbytes_mt(const struct sk_buff *skb, const struct net_device *in, 20connbytes_mt(const struct sk_buff *skb, const struct xt_match_param *par)
21 const struct net_device *out, const struct xt_match *match,
22 const void *matchinfo, int offset, unsigned int protoff,
23 bool *hotdrop)
24{ 21{
25 const struct xt_connbytes_info *sinfo = matchinfo; 22 const struct xt_connbytes_info *sinfo = par->matchinfo;
26 const struct nf_conn *ct; 23 const struct nf_conn *ct;
27 enum ip_conntrack_info ctinfo; 24 enum ip_conntrack_info ctinfo;
28 u_int64_t what = 0; /* initialize to make gcc happy */ 25 u_int64_t what = 0; /* initialize to make gcc happy */
@@ -95,12 +92,9 @@ connbytes_mt(const struct sk_buff *skb, const struct net_device *in,
95 return what >= sinfo->count.from; 92 return what >= sinfo->count.from;
96} 93}
97 94
98static bool 95static bool connbytes_mt_check(const struct xt_mtchk_param *par)
99connbytes_mt_check(const char *tablename, const void *ip,
100 const struct xt_match *match, void *matchinfo,
101 unsigned int hook_mask)
102{ 96{
103 const struct xt_connbytes_info *sinfo = matchinfo; 97 const struct xt_connbytes_info *sinfo = par->matchinfo;
104 98
105 if (sinfo->what != XT_CONNBYTES_PKTS && 99 if (sinfo->what != XT_CONNBYTES_PKTS &&
106 sinfo->what != XT_CONNBYTES_BYTES && 100 sinfo->what != XT_CONNBYTES_BYTES &&
@@ -112,51 +106,39 @@ connbytes_mt_check(const char *tablename, const void *ip,
112 sinfo->direction != XT_CONNBYTES_DIR_BOTH) 106 sinfo->direction != XT_CONNBYTES_DIR_BOTH)
113 return false; 107 return false;
114 108
115 if (nf_ct_l3proto_try_module_get(match->family) < 0) { 109 if (nf_ct_l3proto_try_module_get(par->family) < 0) {
116 printk(KERN_WARNING "can't load conntrack support for " 110 printk(KERN_WARNING "can't load conntrack support for "
117 "proto=%u\n", match->family); 111 "proto=%u\n", par->family);
118 return false; 112 return false;
119 } 113 }
120 114
121 return true; 115 return true;
122} 116}
123 117
124static void 118static void connbytes_mt_destroy(const struct xt_mtdtor_param *par)
125connbytes_mt_destroy(const struct xt_match *match, void *matchinfo)
126{ 119{
127 nf_ct_l3proto_module_put(match->family); 120 nf_ct_l3proto_module_put(par->family);
128} 121}
129 122
130static struct xt_match connbytes_mt_reg[] __read_mostly = { 123static struct xt_match connbytes_mt_reg __read_mostly = {
131 { 124 .name = "connbytes",
132 .name = "connbytes", 125 .revision = 0,
133 .family = AF_INET, 126 .family = NFPROTO_UNSPEC,
134 .checkentry = connbytes_mt_check, 127 .checkentry = connbytes_mt_check,
135 .match = connbytes_mt, 128 .match = connbytes_mt,
136 .destroy = connbytes_mt_destroy, 129 .destroy = connbytes_mt_destroy,
137 .matchsize = sizeof(struct xt_connbytes_info), 130 .matchsize = sizeof(struct xt_connbytes_info),
138 .me = THIS_MODULE 131 .me = THIS_MODULE,
139 },
140 {
141 .name = "connbytes",
142 .family = AF_INET6,
143 .checkentry = connbytes_mt_check,
144 .match = connbytes_mt,
145 .destroy = connbytes_mt_destroy,
146 .matchsize = sizeof(struct xt_connbytes_info),
147 .me = THIS_MODULE
148 },
149}; 132};
150 133
151static int __init connbytes_mt_init(void) 134static int __init connbytes_mt_init(void)
152{ 135{
153 return xt_register_matches(connbytes_mt_reg, 136 return xt_register_match(&connbytes_mt_reg);
154 ARRAY_SIZE(connbytes_mt_reg));
155} 137}
156 138
157static void __exit connbytes_mt_exit(void) 139static void __exit connbytes_mt_exit(void)
158{ 140{
159 xt_unregister_matches(connbytes_mt_reg, ARRAY_SIZE(connbytes_mt_reg)); 141 xt_unregister_match(&connbytes_mt_reg);
160} 142}
161 143
162module_init(connbytes_mt_init); 144module_init(connbytes_mt_init);
diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c
index 70907f6baac3..7f404cc64c83 100644
--- a/net/netfilter/xt_connlimit.c
+++ b/net/netfilter/xt_connlimit.c
@@ -82,9 +82,9 @@ static inline bool already_closed(const struct nf_conn *conn)
82static inline unsigned int 82static inline unsigned int
83same_source_net(const union nf_inet_addr *addr, 83same_source_net(const union nf_inet_addr *addr,
84 const union nf_inet_addr *mask, 84 const union nf_inet_addr *mask,
85 const union nf_inet_addr *u3, unsigned int family) 85 const union nf_inet_addr *u3, u_int8_t family)
86{ 86{
87 if (family == AF_INET) { 87 if (family == NFPROTO_IPV4) {
88 return (addr->ip & mask->ip) == (u3->ip & mask->ip); 88 return (addr->ip & mask->ip) == (u3->ip & mask->ip);
89 } else { 89 } else {
90 union nf_inet_addr lh, rh; 90 union nf_inet_addr lh, rh;
@@ -114,7 +114,7 @@ static int count_them(struct xt_connlimit_data *data,
114 int matches = 0; 114 int matches = 0;
115 115
116 116
117 if (match->family == AF_INET6) 117 if (match->family == NFPROTO_IPV6)
118 hash = &data->iphash[connlimit_iphash6(addr, mask)]; 118 hash = &data->iphash[connlimit_iphash6(addr, mask)];
119 else 119 else
120 hash = &data->iphash[connlimit_iphash(addr->ip & mask->ip)]; 120 hash = &data->iphash[connlimit_iphash(addr->ip & mask->ip)];
@@ -123,7 +123,7 @@ static int count_them(struct xt_connlimit_data *data,
123 123
124 /* check the saved connections */ 124 /* check the saved connections */
125 list_for_each_entry_safe(conn, tmp, hash, list) { 125 list_for_each_entry_safe(conn, tmp, hash, list) {
126 found = __nf_conntrack_find(&conn->tuple); 126 found = __nf_conntrack_find(&init_net, &conn->tuple);
127 found_ct = NULL; 127 found_ct = NULL;
128 128
129 if (found != NULL) 129 if (found != NULL)
@@ -178,12 +178,9 @@ static int count_them(struct xt_connlimit_data *data,
178} 178}
179 179
180static bool 180static bool
181connlimit_mt(const struct sk_buff *skb, const struct net_device *in, 181connlimit_mt(const struct sk_buff *skb, const struct xt_match_param *par)
182 const struct net_device *out, const struct xt_match *match,
183 const void *matchinfo, int offset, unsigned int protoff,
184 bool *hotdrop)
185{ 182{
186 const struct xt_connlimit_info *info = matchinfo; 183 const struct xt_connlimit_info *info = par->matchinfo;
187 union nf_inet_addr addr; 184 union nf_inet_addr addr;
188 struct nf_conntrack_tuple tuple; 185 struct nf_conntrack_tuple tuple;
189 const struct nf_conntrack_tuple *tuple_ptr = &tuple; 186 const struct nf_conntrack_tuple *tuple_ptr = &tuple;
@@ -195,10 +192,10 @@ connlimit_mt(const struct sk_buff *skb, const struct net_device *in,
195 if (ct != NULL) 192 if (ct != NULL)
196 tuple_ptr = &ct->tuplehash[0].tuple; 193 tuple_ptr = &ct->tuplehash[0].tuple;
197 else if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb), 194 else if (!nf_ct_get_tuplepr(skb, skb_network_offset(skb),
198 match->family, &tuple)) 195 par->family, &tuple))
199 goto hotdrop; 196 goto hotdrop;
200 197
201 if (match->family == AF_INET6) { 198 if (par->family == NFPROTO_IPV6) {
202 const struct ipv6hdr *iph = ipv6_hdr(skb); 199 const struct ipv6hdr *iph = ipv6_hdr(skb);
203 memcpy(&addr.ip6, &iph->saddr, sizeof(iph->saddr)); 200 memcpy(&addr.ip6, &iph->saddr, sizeof(iph->saddr));
204 } else { 201 } else {
@@ -208,40 +205,37 @@ connlimit_mt(const struct sk_buff *skb, const struct net_device *in,
208 205
209 spin_lock_bh(&info->data->lock); 206 spin_lock_bh(&info->data->lock);
210 connections = count_them(info->data, tuple_ptr, &addr, 207 connections = count_them(info->data, tuple_ptr, &addr,
211 &info->mask, match); 208 &info->mask, par->match);
212 spin_unlock_bh(&info->data->lock); 209 spin_unlock_bh(&info->data->lock);
213 210
214 if (connections < 0) { 211 if (connections < 0) {
215 /* kmalloc failed, drop it entirely */ 212 /* kmalloc failed, drop it entirely */
216 *hotdrop = true; 213 *par->hotdrop = true;
217 return false; 214 return false;
218 } 215 }
219 216
220 return (connections > info->limit) ^ info->inverse; 217 return (connections > info->limit) ^ info->inverse;
221 218
222 hotdrop: 219 hotdrop:
223 *hotdrop = true; 220 *par->hotdrop = true;
224 return false; 221 return false;
225} 222}
226 223
227static bool 224static bool connlimit_mt_check(const struct xt_mtchk_param *par)
228connlimit_mt_check(const char *tablename, const void *ip,
229 const struct xt_match *match, void *matchinfo,
230 unsigned int hook_mask)
231{ 225{
232 struct xt_connlimit_info *info = matchinfo; 226 struct xt_connlimit_info *info = par->matchinfo;
233 unsigned int i; 227 unsigned int i;
234 228
235 if (nf_ct_l3proto_try_module_get(match->family) < 0) { 229 if (nf_ct_l3proto_try_module_get(par->family) < 0) {
236 printk(KERN_WARNING "cannot load conntrack support for " 230 printk(KERN_WARNING "cannot load conntrack support for "
237 "address family %u\n", match->family); 231 "address family %u\n", par->family);
238 return false; 232 return false;
239 } 233 }
240 234
241 /* init private data */ 235 /* init private data */
242 info->data = kmalloc(sizeof(struct xt_connlimit_data), GFP_KERNEL); 236 info->data = kmalloc(sizeof(struct xt_connlimit_data), GFP_KERNEL);
243 if (info->data == NULL) { 237 if (info->data == NULL) {
244 nf_ct_l3proto_module_put(match->family); 238 nf_ct_l3proto_module_put(par->family);
245 return false; 239 return false;
246 } 240 }
247 241
@@ -252,16 +246,15 @@ connlimit_mt_check(const char *tablename, const void *ip,
252 return true; 246 return true;
253} 247}
254 248
255static void 249static void connlimit_mt_destroy(const struct xt_mtdtor_param *par)
256connlimit_mt_destroy(const struct xt_match *match, void *matchinfo)
257{ 250{
258 const struct xt_connlimit_info *info = matchinfo; 251 const struct xt_connlimit_info *info = par->matchinfo;
259 struct xt_connlimit_conn *conn; 252 struct xt_connlimit_conn *conn;
260 struct xt_connlimit_conn *tmp; 253 struct xt_connlimit_conn *tmp;
261 struct list_head *hash = info->data->iphash; 254 struct list_head *hash = info->data->iphash;
262 unsigned int i; 255 unsigned int i;
263 256
264 nf_ct_l3proto_module_put(match->family); 257 nf_ct_l3proto_module_put(par->family);
265 258
266 for (i = 0; i < ARRAY_SIZE(info->data->iphash); ++i) { 259 for (i = 0; i < ARRAY_SIZE(info->data->iphash); ++i) {
267 list_for_each_entry_safe(conn, tmp, &hash[i], list) { 260 list_for_each_entry_safe(conn, tmp, &hash[i], list) {
@@ -273,41 +266,30 @@ connlimit_mt_destroy(const struct xt_match *match, void *matchinfo)
273 kfree(info->data); 266 kfree(info->data);
274} 267}
275 268
276static struct xt_match connlimit_mt_reg[] __read_mostly = { 269static struct xt_match connlimit_mt_reg __read_mostly = {
277 { 270 .name = "connlimit",
278 .name = "connlimit", 271 .revision = 0,
279 .family = AF_INET, 272 .family = NFPROTO_UNSPEC,
280 .checkentry = connlimit_mt_check, 273 .checkentry = connlimit_mt_check,
281 .match = connlimit_mt, 274 .match = connlimit_mt,
282 .matchsize = sizeof(struct xt_connlimit_info), 275 .matchsize = sizeof(struct xt_connlimit_info),
283 .destroy = connlimit_mt_destroy, 276 .destroy = connlimit_mt_destroy,
284 .me = THIS_MODULE, 277 .me = THIS_MODULE,
285 },
286 {
287 .name = "connlimit",
288 .family = AF_INET6,
289 .checkentry = connlimit_mt_check,
290 .match = connlimit_mt,
291 .matchsize = sizeof(struct xt_connlimit_info),
292 .destroy = connlimit_mt_destroy,
293 .me = THIS_MODULE,
294 },
295}; 278};
296 279
297static int __init connlimit_mt_init(void) 280static int __init connlimit_mt_init(void)
298{ 281{
299 return xt_register_matches(connlimit_mt_reg, 282 return xt_register_match(&connlimit_mt_reg);
300 ARRAY_SIZE(connlimit_mt_reg));
301} 283}
302 284
303static void __exit connlimit_mt_exit(void) 285static void __exit connlimit_mt_exit(void)
304{ 286{
305 xt_unregister_matches(connlimit_mt_reg, ARRAY_SIZE(connlimit_mt_reg)); 287 xt_unregister_match(&connlimit_mt_reg);
306} 288}
307 289
308module_init(connlimit_mt_init); 290module_init(connlimit_mt_init);
309module_exit(connlimit_mt_exit); 291module_exit(connlimit_mt_exit);
310MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>"); 292MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>");
311MODULE_DESCRIPTION("Xtables: Number of connections matching"); 293MODULE_DESCRIPTION("Xtables: Number of connections matching");
312MODULE_LICENSE("GPL"); 294MODULE_LICENSE("GPL");
313MODULE_ALIAS("ipt_connlimit"); 295MODULE_ALIAS("ipt_connlimit");
diff --git a/net/netfilter/xt_connmark.c b/net/netfilter/xt_connmark.c
index aaa1b96691f9..86cacab7a4a3 100644
--- a/net/netfilter/xt_connmark.c
+++ b/net/netfilter/xt_connmark.c
@@ -34,12 +34,9 @@ MODULE_ALIAS("ipt_connmark");
34MODULE_ALIAS("ip6t_connmark"); 34MODULE_ALIAS("ip6t_connmark");
35 35
36static bool 36static bool
37connmark_mt(const struct sk_buff *skb, const struct net_device *in, 37connmark_mt(const struct sk_buff *skb, const struct xt_match_param *par)
38 const struct net_device *out, const struct xt_match *match,
39 const void *matchinfo, int offset, unsigned int protoff,
40 bool *hotdrop)
41{ 38{
42 const struct xt_connmark_mtinfo1 *info = matchinfo; 39 const struct xt_connmark_mtinfo1 *info = par->matchinfo;
43 enum ip_conntrack_info ctinfo; 40 enum ip_conntrack_info ctinfo;
44 const struct nf_conn *ct; 41 const struct nf_conn *ct;
45 42
@@ -51,12 +48,9 @@ connmark_mt(const struct sk_buff *skb, const struct net_device *in,
51} 48}
52 49
53static bool 50static bool
54connmark_mt_v0(const struct sk_buff *skb, const struct net_device *in, 51connmark_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
55 const struct net_device *out, const struct xt_match *match,
56 const void *matchinfo, int offset, unsigned int protoff,
57 bool *hotdrop)
58{ 52{
59 const struct xt_connmark_info *info = matchinfo; 53 const struct xt_connmark_info *info = par->matchinfo;
60 const struct nf_conn *ct; 54 const struct nf_conn *ct;
61 enum ip_conntrack_info ctinfo; 55 enum ip_conntrack_info ctinfo;
62 56
@@ -67,42 +61,35 @@ connmark_mt_v0(const struct sk_buff *skb, const struct net_device *in,
67 return ((ct->mark & info->mask) == info->mark) ^ info->invert; 61 return ((ct->mark & info->mask) == info->mark) ^ info->invert;
68} 62}
69 63
70static bool 64static bool connmark_mt_check_v0(const struct xt_mtchk_param *par)
71connmark_mt_check_v0(const char *tablename, const void *ip,
72 const struct xt_match *match, void *matchinfo,
73 unsigned int hook_mask)
74{ 65{
75 const struct xt_connmark_info *cm = matchinfo; 66 const struct xt_connmark_info *cm = par->matchinfo;
76 67
77 if (cm->mark > 0xffffffff || cm->mask > 0xffffffff) { 68 if (cm->mark > 0xffffffff || cm->mask > 0xffffffff) {
78 printk(KERN_WARNING "connmark: only support 32bit mark\n"); 69 printk(KERN_WARNING "connmark: only support 32bit mark\n");
79 return false; 70 return false;
80 } 71 }
81 if (nf_ct_l3proto_try_module_get(match->family) < 0) { 72 if (nf_ct_l3proto_try_module_get(par->family) < 0) {
82 printk(KERN_WARNING "can't load conntrack support for " 73 printk(KERN_WARNING "can't load conntrack support for "
83 "proto=%u\n", match->family); 74 "proto=%u\n", par->family);
84 return false; 75 return false;
85 } 76 }
86 return true; 77 return true;
87} 78}
88 79
89static bool 80static bool connmark_mt_check(const struct xt_mtchk_param *par)
90connmark_mt_check(const char *tablename, const void *ip,
91 const struct xt_match *match, void *matchinfo,
92 unsigned int hook_mask)
93{ 81{
94 if (nf_ct_l3proto_try_module_get(match->family) < 0) { 82 if (nf_ct_l3proto_try_module_get(par->family) < 0) {
95 printk(KERN_WARNING "cannot load conntrack support for " 83 printk(KERN_WARNING "cannot load conntrack support for "
96 "proto=%u\n", match->family); 84 "proto=%u\n", par->family);
97 return false; 85 return false;
98 } 86 }
99 return true; 87 return true;
100} 88}
101 89
102static void 90static void connmark_mt_destroy(const struct xt_mtdtor_param *par)
103connmark_mt_destroy(const struct xt_match *match, void *matchinfo)
104{ 91{
105 nf_ct_l3proto_module_put(match->family); 92 nf_ct_l3proto_module_put(par->family);
106} 93}
107 94
108#ifdef CONFIG_COMPAT 95#ifdef CONFIG_COMPAT
@@ -140,7 +127,7 @@ static struct xt_match connmark_mt_reg[] __read_mostly = {
140 { 127 {
141 .name = "connmark", 128 .name = "connmark",
142 .revision = 0, 129 .revision = 0,
143 .family = AF_INET, 130 .family = NFPROTO_UNSPEC,
144 .checkentry = connmark_mt_check_v0, 131 .checkentry = connmark_mt_check_v0,
145 .match = connmark_mt_v0, 132 .match = connmark_mt_v0,
146 .destroy = connmark_mt_destroy, 133 .destroy = connmark_mt_destroy,
@@ -153,34 +140,9 @@ static struct xt_match connmark_mt_reg[] __read_mostly = {
153 .me = THIS_MODULE 140 .me = THIS_MODULE
154 }, 141 },
155 { 142 {
156 .name = "connmark",
157 .revision = 0,
158 .family = AF_INET6,
159 .checkentry = connmark_mt_check_v0,
160 .match = connmark_mt_v0,
161 .destroy = connmark_mt_destroy,
162 .matchsize = sizeof(struct xt_connmark_info),
163#ifdef CONFIG_COMPAT
164 .compatsize = sizeof(struct compat_xt_connmark_info),
165 .compat_from_user = connmark_mt_compat_from_user_v0,
166 .compat_to_user = connmark_mt_compat_to_user_v0,
167#endif
168 .me = THIS_MODULE
169 },
170 {
171 .name = "connmark",
172 .revision = 1,
173 .family = AF_INET,
174 .checkentry = connmark_mt_check,
175 .match = connmark_mt,
176 .matchsize = sizeof(struct xt_connmark_mtinfo1),
177 .destroy = connmark_mt_destroy,
178 .me = THIS_MODULE,
179 },
180 {
181 .name = "connmark", 143 .name = "connmark",
182 .revision = 1, 144 .revision = 1,
183 .family = AF_INET6, 145 .family = NFPROTO_UNSPEC,
184 .checkentry = connmark_mt_check, 146 .checkentry = connmark_mt_check,
185 .match = connmark_mt, 147 .match = connmark_mt,
186 .matchsize = sizeof(struct xt_connmark_mtinfo1), 148 .matchsize = sizeof(struct xt_connmark_mtinfo1),
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c
index d61412f58ef7..0b7139f3dd78 100644
--- a/net/netfilter/xt_conntrack.c
+++ b/net/netfilter/xt_conntrack.c
@@ -25,12 +25,9 @@ MODULE_ALIAS("ipt_conntrack");
25MODULE_ALIAS("ip6t_conntrack"); 25MODULE_ALIAS("ip6t_conntrack");
26 26
27static bool 27static bool
28conntrack_mt_v0(const struct sk_buff *skb, const struct net_device *in, 28conntrack_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
29 const struct net_device *out, const struct xt_match *match,
30 const void *matchinfo, int offset, unsigned int protoff,
31 bool *hotdrop)
32{ 29{
33 const struct xt_conntrack_info *sinfo = matchinfo; 30 const struct xt_conntrack_info *sinfo = par->matchinfo;
34 const struct nf_conn *ct; 31 const struct nf_conn *ct;
35 enum ip_conntrack_info ctinfo; 32 enum ip_conntrack_info ctinfo;
36 unsigned int statebit; 33 unsigned int statebit;
@@ -121,9 +118,9 @@ conntrack_addrcmp(const union nf_inet_addr *kaddr,
121 const union nf_inet_addr *uaddr, 118 const union nf_inet_addr *uaddr,
122 const union nf_inet_addr *umask, unsigned int l3proto) 119 const union nf_inet_addr *umask, unsigned int l3proto)
123{ 120{
124 if (l3proto == AF_INET) 121 if (l3proto == NFPROTO_IPV4)
125 return ((kaddr->ip ^ uaddr->ip) & umask->ip) == 0; 122 return ((kaddr->ip ^ uaddr->ip) & umask->ip) == 0;
126 else if (l3proto == AF_INET6) 123 else if (l3proto == NFPROTO_IPV6)
127 return ipv6_masked_addr_cmp(&kaddr->in6, &umask->in6, 124 return ipv6_masked_addr_cmp(&kaddr->in6, &umask->in6,
128 &uaddr->in6) == 0; 125 &uaddr->in6) == 0;
129 else 126 else
@@ -133,7 +130,7 @@ conntrack_addrcmp(const union nf_inet_addr *kaddr,
133static inline bool 130static inline bool
134conntrack_mt_origsrc(const struct nf_conn *ct, 131conntrack_mt_origsrc(const struct nf_conn *ct,
135 const struct xt_conntrack_mtinfo1 *info, 132 const struct xt_conntrack_mtinfo1 *info,
136 unsigned int family) 133 u_int8_t family)
137{ 134{
138 return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3, 135 return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3,
139 &info->origsrc_addr, &info->origsrc_mask, family); 136 &info->origsrc_addr, &info->origsrc_mask, family);
@@ -142,7 +139,7 @@ conntrack_mt_origsrc(const struct nf_conn *ct,
142static inline bool 139static inline bool
143conntrack_mt_origdst(const struct nf_conn *ct, 140conntrack_mt_origdst(const struct nf_conn *ct,
144 const struct xt_conntrack_mtinfo1 *info, 141 const struct xt_conntrack_mtinfo1 *info,
145 unsigned int family) 142 u_int8_t family)
146{ 143{
147 return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3, 144 return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u3,
148 &info->origdst_addr, &info->origdst_mask, family); 145 &info->origdst_addr, &info->origdst_mask, family);
@@ -151,7 +148,7 @@ conntrack_mt_origdst(const struct nf_conn *ct,
151static inline bool 148static inline bool
152conntrack_mt_replsrc(const struct nf_conn *ct, 149conntrack_mt_replsrc(const struct nf_conn *ct,
153 const struct xt_conntrack_mtinfo1 *info, 150 const struct xt_conntrack_mtinfo1 *info,
154 unsigned int family) 151 u_int8_t family)
155{ 152{
156 return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3, 153 return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3,
157 &info->replsrc_addr, &info->replsrc_mask, family); 154 &info->replsrc_addr, &info->replsrc_mask, family);
@@ -160,7 +157,7 @@ conntrack_mt_replsrc(const struct nf_conn *ct,
160static inline bool 157static inline bool
161conntrack_mt_repldst(const struct nf_conn *ct, 158conntrack_mt_repldst(const struct nf_conn *ct,
162 const struct xt_conntrack_mtinfo1 *info, 159 const struct xt_conntrack_mtinfo1 *info,
163 unsigned int family) 160 u_int8_t family)
164{ 161{
165 return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3, 162 return conntrack_addrcmp(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3,
166 &info->repldst_addr, &info->repldst_mask, family); 163 &info->repldst_addr, &info->repldst_mask, family);
@@ -205,12 +202,9 @@ ct_proto_port_check(const struct xt_conntrack_mtinfo1 *info,
205} 202}
206 203
207static bool 204static bool
208conntrack_mt(const struct sk_buff *skb, const struct net_device *in, 205conntrack_mt(const struct sk_buff *skb, const struct xt_match_param *par)
209 const struct net_device *out, const struct xt_match *match,
210 const void *matchinfo, int offset, unsigned int protoff,
211 bool *hotdrop)
212{ 206{
213 const struct xt_conntrack_mtinfo1 *info = matchinfo; 207 const struct xt_conntrack_mtinfo1 *info = par->matchinfo;
214 enum ip_conntrack_info ctinfo; 208 enum ip_conntrack_info ctinfo;
215 const struct nf_conn *ct; 209 const struct nf_conn *ct;
216 unsigned int statebit; 210 unsigned int statebit;
@@ -244,22 +238,22 @@ conntrack_mt(const struct sk_buff *skb, const struct net_device *in,
244 return false; 238 return false;
245 239
246 if (info->match_flags & XT_CONNTRACK_ORIGSRC) 240 if (info->match_flags & XT_CONNTRACK_ORIGSRC)
247 if (conntrack_mt_origsrc(ct, info, match->family) ^ 241 if (conntrack_mt_origsrc(ct, info, par->family) ^
248 !(info->invert_flags & XT_CONNTRACK_ORIGSRC)) 242 !(info->invert_flags & XT_CONNTRACK_ORIGSRC))
249 return false; 243 return false;
250 244
251 if (info->match_flags & XT_CONNTRACK_ORIGDST) 245 if (info->match_flags & XT_CONNTRACK_ORIGDST)
252 if (conntrack_mt_origdst(ct, info, match->family) ^ 246 if (conntrack_mt_origdst(ct, info, par->family) ^
253 !(info->invert_flags & XT_CONNTRACK_ORIGDST)) 247 !(info->invert_flags & XT_CONNTRACK_ORIGDST))
254 return false; 248 return false;
255 249
256 if (info->match_flags & XT_CONNTRACK_REPLSRC) 250 if (info->match_flags & XT_CONNTRACK_REPLSRC)
257 if (conntrack_mt_replsrc(ct, info, match->family) ^ 251 if (conntrack_mt_replsrc(ct, info, par->family) ^
258 !(info->invert_flags & XT_CONNTRACK_REPLSRC)) 252 !(info->invert_flags & XT_CONNTRACK_REPLSRC))
259 return false; 253 return false;
260 254
261 if (info->match_flags & XT_CONNTRACK_REPLDST) 255 if (info->match_flags & XT_CONNTRACK_REPLDST)
262 if (conntrack_mt_repldst(ct, info, match->family) ^ 256 if (conntrack_mt_repldst(ct, info, par->family) ^
263 !(info->invert_flags & XT_CONNTRACK_REPLDST)) 257 !(info->invert_flags & XT_CONNTRACK_REPLDST))
264 return false; 258 return false;
265 259
@@ -284,23 +278,19 @@ conntrack_mt(const struct sk_buff *skb, const struct net_device *in,
284 return true; 278 return true;
285} 279}
286 280
287static bool 281static bool conntrack_mt_check(const struct xt_mtchk_param *par)
288conntrack_mt_check(const char *tablename, const void *ip,
289 const struct xt_match *match, void *matchinfo,
290 unsigned int hook_mask)
291{ 282{
292 if (nf_ct_l3proto_try_module_get(match->family) < 0) { 283 if (nf_ct_l3proto_try_module_get(par->family) < 0) {
293 printk(KERN_WARNING "can't load conntrack support for " 284 printk(KERN_WARNING "can't load conntrack support for "
294 "proto=%u\n", match->family); 285 "proto=%u\n", par->family);
295 return false; 286 return false;
296 } 287 }
297 return true; 288 return true;
298} 289}
299 290
300static void 291static void conntrack_mt_destroy(const struct xt_mtdtor_param *par)
301conntrack_mt_destroy(const struct xt_match *match, void *matchinfo)
302{ 292{
303 nf_ct_l3proto_module_put(match->family); 293 nf_ct_l3proto_module_put(par->family);
304} 294}
305 295
306#ifdef CONFIG_COMPAT 296#ifdef CONFIG_COMPAT
@@ -356,7 +346,7 @@ static struct xt_match conntrack_mt_reg[] __read_mostly = {
356 { 346 {
357 .name = "conntrack", 347 .name = "conntrack",
358 .revision = 0, 348 .revision = 0,
359 .family = AF_INET, 349 .family = NFPROTO_IPV4,
360 .match = conntrack_mt_v0, 350 .match = conntrack_mt_v0,
361 .checkentry = conntrack_mt_check, 351 .checkentry = conntrack_mt_check,
362 .destroy = conntrack_mt_destroy, 352 .destroy = conntrack_mt_destroy,
@@ -371,17 +361,7 @@ static struct xt_match conntrack_mt_reg[] __read_mostly = {
371 { 361 {
372 .name = "conntrack", 362 .name = "conntrack",
373 .revision = 1, 363 .revision = 1,
374 .family = AF_INET, 364 .family = NFPROTO_UNSPEC,
375 .matchsize = sizeof(struct xt_conntrack_mtinfo1),
376 .match = conntrack_mt,
377 .checkentry = conntrack_mt_check,
378 .destroy = conntrack_mt_destroy,
379 .me = THIS_MODULE,
380 },
381 {
382 .name = "conntrack",
383 .revision = 1,
384 .family = AF_INET6,
385 .matchsize = sizeof(struct xt_conntrack_mtinfo1), 365 .matchsize = sizeof(struct xt_conntrack_mtinfo1),
386 .match = conntrack_mt, 366 .match = conntrack_mt,
387 .checkentry = conntrack_mt_check, 367 .checkentry = conntrack_mt_check,
diff --git a/net/netfilter/xt_dccp.c b/net/netfilter/xt_dccp.c
index 8b6522186d9f..e5d3e8673287 100644
--- a/net/netfilter/xt_dccp.c
+++ b/net/netfilter/xt_dccp.c
@@ -93,20 +93,18 @@ match_option(u_int8_t option, const struct sk_buff *skb, unsigned int protoff,
93} 93}
94 94
95static bool 95static bool
96dccp_mt(const struct sk_buff *skb, const struct net_device *in, 96dccp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
97 const struct net_device *out, const struct xt_match *match,
98 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
99{ 97{
100 const struct xt_dccp_info *info = matchinfo; 98 const struct xt_dccp_info *info = par->matchinfo;
101 const struct dccp_hdr *dh; 99 const struct dccp_hdr *dh;
102 struct dccp_hdr _dh; 100 struct dccp_hdr _dh;
103 101
104 if (offset) 102 if (par->fragoff != 0)
105 return false; 103 return false;
106 104
107 dh = skb_header_pointer(skb, protoff, sizeof(_dh), &_dh); 105 dh = skb_header_pointer(skb, par->thoff, sizeof(_dh), &_dh);
108 if (dh == NULL) { 106 if (dh == NULL) {
109 *hotdrop = true; 107 *par->hotdrop = true;
110 return false; 108 return false;
111 } 109 }
112 110
@@ -118,17 +116,14 @@ dccp_mt(const struct sk_buff *skb, const struct net_device *in,
118 XT_DCCP_DEST_PORTS, info->flags, info->invflags) 116 XT_DCCP_DEST_PORTS, info->flags, info->invflags)
119 && DCCHECK(match_types(dh, info->typemask), 117 && DCCHECK(match_types(dh, info->typemask),
120 XT_DCCP_TYPE, info->flags, info->invflags) 118 XT_DCCP_TYPE, info->flags, info->invflags)
121 && DCCHECK(match_option(info->option, skb, protoff, dh, 119 && DCCHECK(match_option(info->option, skb, par->thoff, dh,
122 hotdrop), 120 par->hotdrop),
123 XT_DCCP_OPTION, info->flags, info->invflags); 121 XT_DCCP_OPTION, info->flags, info->invflags);
124} 122}
125 123
126static bool 124static bool dccp_mt_check(const struct xt_mtchk_param *par)
127dccp_mt_check(const char *tablename, const void *inf,
128 const struct xt_match *match, void *matchinfo,
129 unsigned int hook_mask)
130{ 125{
131 const struct xt_dccp_info *info = matchinfo; 126 const struct xt_dccp_info *info = par->matchinfo;
132 127
133 return !(info->flags & ~XT_DCCP_VALID_FLAGS) 128 return !(info->flags & ~XT_DCCP_VALID_FLAGS)
134 && !(info->invflags & ~XT_DCCP_VALID_FLAGS) 129 && !(info->invflags & ~XT_DCCP_VALID_FLAGS)
@@ -138,7 +133,7 @@ dccp_mt_check(const char *tablename, const void *inf,
138static struct xt_match dccp_mt_reg[] __read_mostly = { 133static struct xt_match dccp_mt_reg[] __read_mostly = {
139 { 134 {
140 .name = "dccp", 135 .name = "dccp",
141 .family = AF_INET, 136 .family = NFPROTO_IPV4,
142 .checkentry = dccp_mt_check, 137 .checkentry = dccp_mt_check,
143 .match = dccp_mt, 138 .match = dccp_mt,
144 .matchsize = sizeof(struct xt_dccp_info), 139 .matchsize = sizeof(struct xt_dccp_info),
@@ -147,7 +142,7 @@ static struct xt_match dccp_mt_reg[] __read_mostly = {
147 }, 142 },
148 { 143 {
149 .name = "dccp", 144 .name = "dccp",
150 .family = AF_INET6, 145 .family = NFPROTO_IPV6,
151 .checkentry = dccp_mt_check, 146 .checkentry = dccp_mt_check,
152 .match = dccp_mt, 147 .match = dccp_mt,
153 .matchsize = sizeof(struct xt_dccp_info), 148 .matchsize = sizeof(struct xt_dccp_info),
diff --git a/net/netfilter/xt_dscp.c b/net/netfilter/xt_dscp.c
index 26f4aab9c429..c3f8085460d7 100644
--- a/net/netfilter/xt_dscp.c
+++ b/net/netfilter/xt_dscp.c
@@ -26,61 +26,48 @@ MODULE_ALIAS("ipt_tos");
26MODULE_ALIAS("ip6t_tos"); 26MODULE_ALIAS("ip6t_tos");
27 27
28static bool 28static bool
29dscp_mt(const struct sk_buff *skb, const struct net_device *in, 29dscp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
30 const struct net_device *out, const struct xt_match *match,
31 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
32{ 30{
33 const struct xt_dscp_info *info = matchinfo; 31 const struct xt_dscp_info *info = par->matchinfo;
34 u_int8_t dscp = ipv4_get_dsfield(ip_hdr(skb)) >> XT_DSCP_SHIFT; 32 u_int8_t dscp = ipv4_get_dsfield(ip_hdr(skb)) >> XT_DSCP_SHIFT;
35 33
36 return (dscp == info->dscp) ^ !!info->invert; 34 return (dscp == info->dscp) ^ !!info->invert;
37} 35}
38 36
39static bool 37static bool
40dscp_mt6(const struct sk_buff *skb, const struct net_device *in, 38dscp_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
41 const struct net_device *out, const struct xt_match *match,
42 const void *matchinfo, int offset, unsigned int protoff,
43 bool *hotdrop)
44{ 39{
45 const struct xt_dscp_info *info = matchinfo; 40 const struct xt_dscp_info *info = par->matchinfo;
46 u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT; 41 u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT;
47 42
48 return (dscp == info->dscp) ^ !!info->invert; 43 return (dscp == info->dscp) ^ !!info->invert;
49} 44}
50 45
51static bool 46static bool dscp_mt_check(const struct xt_mtchk_param *par)
52dscp_mt_check(const char *tablename, const void *info,
53 const struct xt_match *match, void *matchinfo,
54 unsigned int hook_mask)
55{ 47{
56 const u_int8_t dscp = ((struct xt_dscp_info *)matchinfo)->dscp; 48 const struct xt_dscp_info *info = par->matchinfo;
57 49
58 if (dscp > XT_DSCP_MAX) { 50 if (info->dscp > XT_DSCP_MAX) {
59 printk(KERN_ERR "xt_dscp: dscp %x out of range\n", dscp); 51 printk(KERN_ERR "xt_dscp: dscp %x out of range\n", info->dscp);
60 return false; 52 return false;
61 } 53 }
62 54
63 return true; 55 return true;
64} 56}
65 57
66static bool tos_mt_v0(const struct sk_buff *skb, const struct net_device *in, 58static bool
67 const struct net_device *out, 59tos_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
68 const struct xt_match *match, const void *matchinfo,
69 int offset, unsigned int protoff, bool *hotdrop)
70{ 60{
71 const struct ipt_tos_info *info = matchinfo; 61 const struct ipt_tos_info *info = par->matchinfo;
72 62
73 return (ip_hdr(skb)->tos == info->tos) ^ info->invert; 63 return (ip_hdr(skb)->tos == info->tos) ^ info->invert;
74} 64}
75 65
76static bool tos_mt(const struct sk_buff *skb, const struct net_device *in, 66static bool tos_mt(const struct sk_buff *skb, const struct xt_match_param *par)
77 const struct net_device *out, const struct xt_match *match,
78 const void *matchinfo, int offset, unsigned int protoff,
79 bool *hotdrop)
80{ 67{
81 const struct xt_tos_match_info *info = matchinfo; 68 const struct xt_tos_match_info *info = par->matchinfo;
82 69
83 if (match->family == AF_INET) 70 if (par->match->family == NFPROTO_IPV4)
84 return ((ip_hdr(skb)->tos & info->tos_mask) == 71 return ((ip_hdr(skb)->tos & info->tos_mask) ==
85 info->tos_value) ^ !!info->invert; 72 info->tos_value) ^ !!info->invert;
86 else 73 else
@@ -91,7 +78,7 @@ static bool tos_mt(const struct sk_buff *skb, const struct net_device *in,
91static struct xt_match dscp_mt_reg[] __read_mostly = { 78static struct xt_match dscp_mt_reg[] __read_mostly = {
92 { 79 {
93 .name = "dscp", 80 .name = "dscp",
94 .family = AF_INET, 81 .family = NFPROTO_IPV4,
95 .checkentry = dscp_mt_check, 82 .checkentry = dscp_mt_check,
96 .match = dscp_mt, 83 .match = dscp_mt,
97 .matchsize = sizeof(struct xt_dscp_info), 84 .matchsize = sizeof(struct xt_dscp_info),
@@ -99,7 +86,7 @@ static struct xt_match dscp_mt_reg[] __read_mostly = {
99 }, 86 },
100 { 87 {
101 .name = "dscp", 88 .name = "dscp",
102 .family = AF_INET6, 89 .family = NFPROTO_IPV6,
103 .checkentry = dscp_mt_check, 90 .checkentry = dscp_mt_check,
104 .match = dscp_mt6, 91 .match = dscp_mt6,
105 .matchsize = sizeof(struct xt_dscp_info), 92 .matchsize = sizeof(struct xt_dscp_info),
@@ -108,7 +95,7 @@ static struct xt_match dscp_mt_reg[] __read_mostly = {
108 { 95 {
109 .name = "tos", 96 .name = "tos",
110 .revision = 0, 97 .revision = 0,
111 .family = AF_INET, 98 .family = NFPROTO_IPV4,
112 .match = tos_mt_v0, 99 .match = tos_mt_v0,
113 .matchsize = sizeof(struct ipt_tos_info), 100 .matchsize = sizeof(struct ipt_tos_info),
114 .me = THIS_MODULE, 101 .me = THIS_MODULE,
@@ -116,7 +103,7 @@ static struct xt_match dscp_mt_reg[] __read_mostly = {
116 { 103 {
117 .name = "tos", 104 .name = "tos",
118 .revision = 1, 105 .revision = 1,
119 .family = AF_INET, 106 .family = NFPROTO_IPV4,
120 .match = tos_mt, 107 .match = tos_mt,
121 .matchsize = sizeof(struct xt_tos_match_info), 108 .matchsize = sizeof(struct xt_tos_match_info),
122 .me = THIS_MODULE, 109 .me = THIS_MODULE,
@@ -124,7 +111,7 @@ static struct xt_match dscp_mt_reg[] __read_mostly = {
124 { 111 {
125 .name = "tos", 112 .name = "tos",
126 .revision = 1, 113 .revision = 1,
127 .family = AF_INET6, 114 .family = NFPROTO_IPV6,
128 .match = tos_mt, 115 .match = tos_mt,
129 .matchsize = sizeof(struct xt_tos_match_info), 116 .matchsize = sizeof(struct xt_tos_match_info),
130 .me = THIS_MODULE, 117 .me = THIS_MODULE,
diff --git a/net/netfilter/xt_esp.c b/net/netfilter/xt_esp.c
index a133eb9b23e1..609439967c2c 100644
--- a/net/netfilter/xt_esp.c
+++ b/net/netfilter/xt_esp.c
@@ -42,26 +42,23 @@ spi_match(u_int32_t min, u_int32_t max, u_int32_t spi, bool invert)
42 return r; 42 return r;
43} 43}
44 44
45static bool 45static bool esp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
46esp_mt(const struct sk_buff *skb, const struct net_device *in,
47 const struct net_device *out, const struct xt_match *match,
48 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
49{ 46{
50 const struct ip_esp_hdr *eh; 47 const struct ip_esp_hdr *eh;
51 struct ip_esp_hdr _esp; 48 struct ip_esp_hdr _esp;
52 const struct xt_esp *espinfo = matchinfo; 49 const struct xt_esp *espinfo = par->matchinfo;
53 50
54 /* Must not be a fragment. */ 51 /* Must not be a fragment. */
55 if (offset) 52 if (par->fragoff != 0)
56 return false; 53 return false;
57 54
58 eh = skb_header_pointer(skb, protoff, sizeof(_esp), &_esp); 55 eh = skb_header_pointer(skb, par->thoff, sizeof(_esp), &_esp);
59 if (eh == NULL) { 56 if (eh == NULL) {
60 /* We've been asked to examine this packet, and we 57 /* We've been asked to examine this packet, and we
61 * can't. Hence, no choice but to drop. 58 * can't. Hence, no choice but to drop.
62 */ 59 */
63 duprintf("Dropping evil ESP tinygram.\n"); 60 duprintf("Dropping evil ESP tinygram.\n");
64 *hotdrop = true; 61 *par->hotdrop = true;
65 return false; 62 return false;
66 } 63 }
67 64
@@ -69,13 +66,9 @@ esp_mt(const struct sk_buff *skb, const struct net_device *in,
69 !!(espinfo->invflags & XT_ESP_INV_SPI)); 66 !!(espinfo->invflags & XT_ESP_INV_SPI));
70} 67}
71 68
72/* Called when user tries to insert an entry of this type. */ 69static bool esp_mt_check(const struct xt_mtchk_param *par)
73static bool
74esp_mt_check(const char *tablename, const void *ip_void,
75 const struct xt_match *match, void *matchinfo,
76 unsigned int hook_mask)
77{ 70{
78 const struct xt_esp *espinfo = matchinfo; 71 const struct xt_esp *espinfo = par->matchinfo;
79 72
80 if (espinfo->invflags & ~XT_ESP_INV_MASK) { 73 if (espinfo->invflags & ~XT_ESP_INV_MASK) {
81 duprintf("xt_esp: unknown flags %X\n", espinfo->invflags); 74 duprintf("xt_esp: unknown flags %X\n", espinfo->invflags);
@@ -88,7 +81,7 @@ esp_mt_check(const char *tablename, const void *ip_void,
88static struct xt_match esp_mt_reg[] __read_mostly = { 81static struct xt_match esp_mt_reg[] __read_mostly = {
89 { 82 {
90 .name = "esp", 83 .name = "esp",
91 .family = AF_INET, 84 .family = NFPROTO_IPV4,
92 .checkentry = esp_mt_check, 85 .checkentry = esp_mt_check,
93 .match = esp_mt, 86 .match = esp_mt,
94 .matchsize = sizeof(struct xt_esp), 87 .matchsize = sizeof(struct xt_esp),
@@ -97,7 +90,7 @@ static struct xt_match esp_mt_reg[] __read_mostly = {
97 }, 90 },
98 { 91 {
99 .name = "esp", 92 .name = "esp",
100 .family = AF_INET6, 93 .family = NFPROTO_IPV6,
101 .checkentry = esp_mt_check, 94 .checkentry = esp_mt_check,
102 .match = esp_mt, 95 .match = esp_mt,
103 .matchsize = sizeof(struct xt_esp), 96 .matchsize = sizeof(struct xt_esp),
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index d9418a267812..6fc4292d46e6 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -80,7 +80,7 @@ struct dsthash_ent {
80struct xt_hashlimit_htable { 80struct xt_hashlimit_htable {
81 struct hlist_node node; /* global list of all htables */ 81 struct hlist_node node; /* global list of all htables */
82 atomic_t use; 82 atomic_t use;
83 int family; 83 u_int8_t family;
84 84
85 struct hashlimit_cfg1 cfg; /* config */ 85 struct hashlimit_cfg1 cfg; /* config */
86 86
@@ -185,7 +185,7 @@ dsthash_free(struct xt_hashlimit_htable *ht, struct dsthash_ent *ent)
185} 185}
186static void htable_gc(unsigned long htlong); 186static void htable_gc(unsigned long htlong);
187 187
188static int htable_create_v0(struct xt_hashlimit_info *minfo, int family) 188static int htable_create_v0(struct xt_hashlimit_info *minfo, u_int8_t family)
189{ 189{
190 struct xt_hashlimit_htable *hinfo; 190 struct xt_hashlimit_htable *hinfo;
191 unsigned int size; 191 unsigned int size;
@@ -218,7 +218,7 @@ static int htable_create_v0(struct xt_hashlimit_info *minfo, int family)
218 hinfo->cfg.gc_interval = minfo->cfg.gc_interval; 218 hinfo->cfg.gc_interval = minfo->cfg.gc_interval;
219 hinfo->cfg.expire = minfo->cfg.expire; 219 hinfo->cfg.expire = minfo->cfg.expire;
220 220
221 if (family == AF_INET) 221 if (family == NFPROTO_IPV4)
222 hinfo->cfg.srcmask = hinfo->cfg.dstmask = 32; 222 hinfo->cfg.srcmask = hinfo->cfg.dstmask = 32;
223 else 223 else
224 hinfo->cfg.srcmask = hinfo->cfg.dstmask = 128; 224 hinfo->cfg.srcmask = hinfo->cfg.dstmask = 128;
@@ -237,11 +237,10 @@ static int htable_create_v0(struct xt_hashlimit_info *minfo, int family)
237 hinfo->family = family; 237 hinfo->family = family;
238 hinfo->rnd_initialized = 0; 238 hinfo->rnd_initialized = 0;
239 spin_lock_init(&hinfo->lock); 239 spin_lock_init(&hinfo->lock);
240 hinfo->pde = 240 hinfo->pde = proc_create_data(minfo->name, 0,
241 proc_create_data(minfo->name, 0, 241 (family == NFPROTO_IPV4) ?
242 family == AF_INET ? hashlimit_procdir4 : 242 hashlimit_procdir4 : hashlimit_procdir6,
243 hashlimit_procdir6, 243 &dl_file_ops, hinfo);
244 &dl_file_ops, hinfo);
245 if (!hinfo->pde) { 244 if (!hinfo->pde) {
246 vfree(hinfo); 245 vfree(hinfo);
247 return -1; 246 return -1;
@@ -258,8 +257,7 @@ static int htable_create_v0(struct xt_hashlimit_info *minfo, int family)
258 return 0; 257 return 0;
259} 258}
260 259
261static int htable_create(struct xt_hashlimit_mtinfo1 *minfo, 260static int htable_create(struct xt_hashlimit_mtinfo1 *minfo, u_int8_t family)
262 unsigned int family)
263{ 261{
264 struct xt_hashlimit_htable *hinfo; 262 struct xt_hashlimit_htable *hinfo;
265 unsigned int size; 263 unsigned int size;
@@ -301,11 +299,10 @@ static int htable_create(struct xt_hashlimit_mtinfo1 *minfo,
301 hinfo->rnd_initialized = 0; 299 hinfo->rnd_initialized = 0;
302 spin_lock_init(&hinfo->lock); 300 spin_lock_init(&hinfo->lock);
303 301
304 hinfo->pde = 302 hinfo->pde = proc_create_data(minfo->name, 0,
305 proc_create_data(minfo->name, 0, 303 (family == NFPROTO_IPV4) ?
306 family == AF_INET ? hashlimit_procdir4 : 304 hashlimit_procdir4 : hashlimit_procdir6,
307 hashlimit_procdir6, 305 &dl_file_ops, hinfo);
308 &dl_file_ops, hinfo);
309 if (hinfo->pde == NULL) { 306 if (hinfo->pde == NULL) {
310 vfree(hinfo); 307 vfree(hinfo);
311 return -1; 308 return -1;
@@ -371,14 +368,14 @@ static void htable_destroy(struct xt_hashlimit_htable *hinfo)
371 368
372 /* remove proc entry */ 369 /* remove proc entry */
373 remove_proc_entry(hinfo->pde->name, 370 remove_proc_entry(hinfo->pde->name,
374 hinfo->family == AF_INET ? hashlimit_procdir4 : 371 hinfo->family == NFPROTO_IPV4 ? hashlimit_procdir4 :
375 hashlimit_procdir6); 372 hashlimit_procdir6);
376 htable_selective_cleanup(hinfo, select_all); 373 htable_selective_cleanup(hinfo, select_all);
377 vfree(hinfo); 374 vfree(hinfo);
378} 375}
379 376
380static struct xt_hashlimit_htable *htable_find_get(const char *name, 377static struct xt_hashlimit_htable *htable_find_get(const char *name,
381 int family) 378 u_int8_t family)
382{ 379{
383 struct xt_hashlimit_htable *hinfo; 380 struct xt_hashlimit_htable *hinfo;
384 struct hlist_node *pos; 381 struct hlist_node *pos;
@@ -502,7 +499,7 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
502 memset(dst, 0, sizeof(*dst)); 499 memset(dst, 0, sizeof(*dst));
503 500
504 switch (hinfo->family) { 501 switch (hinfo->family) {
505 case AF_INET: 502 case NFPROTO_IPV4:
506 if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_DIP) 503 if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_DIP)
507 dst->ip.dst = maskl(ip_hdr(skb)->daddr, 504 dst->ip.dst = maskl(ip_hdr(skb)->daddr,
508 hinfo->cfg.dstmask); 505 hinfo->cfg.dstmask);
@@ -516,7 +513,7 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
516 nexthdr = ip_hdr(skb)->protocol; 513 nexthdr = ip_hdr(skb)->protocol;
517 break; 514 break;
518#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) 515#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
519 case AF_INET6: 516 case NFPROTO_IPV6:
520 if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_DIP) { 517 if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_DIP) {
521 memcpy(&dst->ip6.dst, &ipv6_hdr(skb)->daddr, 518 memcpy(&dst->ip6.dst, &ipv6_hdr(skb)->daddr,
522 sizeof(dst->ip6.dst)); 519 sizeof(dst->ip6.dst));
@@ -566,19 +563,16 @@ hashlimit_init_dst(const struct xt_hashlimit_htable *hinfo,
566} 563}
567 564
568static bool 565static bool
569hashlimit_mt_v0(const struct sk_buff *skb, const struct net_device *in, 566hashlimit_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
570 const struct net_device *out, const struct xt_match *match,
571 const void *matchinfo, int offset, unsigned int protoff,
572 bool *hotdrop)
573{ 567{
574 const struct xt_hashlimit_info *r = 568 const struct xt_hashlimit_info *r =
575 ((const struct xt_hashlimit_info *)matchinfo)->u.master; 569 ((const struct xt_hashlimit_info *)par->matchinfo)->u.master;
576 struct xt_hashlimit_htable *hinfo = r->hinfo; 570 struct xt_hashlimit_htable *hinfo = r->hinfo;
577 unsigned long now = jiffies; 571 unsigned long now = jiffies;
578 struct dsthash_ent *dh; 572 struct dsthash_ent *dh;
579 struct dsthash_dst dst; 573 struct dsthash_dst dst;
580 574
581 if (hashlimit_init_dst(hinfo, &dst, skb, protoff) < 0) 575 if (hashlimit_init_dst(hinfo, &dst, skb, par->thoff) < 0)
582 goto hotdrop; 576 goto hotdrop;
583 577
584 spin_lock_bh(&hinfo->lock); 578 spin_lock_bh(&hinfo->lock);
@@ -616,23 +610,20 @@ hashlimit_mt_v0(const struct sk_buff *skb, const struct net_device *in,
616 return false; 610 return false;
617 611
618hotdrop: 612hotdrop:
619 *hotdrop = true; 613 *par->hotdrop = true;
620 return false; 614 return false;
621} 615}
622 616
623static bool 617static bool
624hashlimit_mt(const struct sk_buff *skb, const struct net_device *in, 618hashlimit_mt(const struct sk_buff *skb, const struct xt_match_param *par)
625 const struct net_device *out, const struct xt_match *match,
626 const void *matchinfo, int offset, unsigned int protoff,
627 bool *hotdrop)
628{ 619{
629 const struct xt_hashlimit_mtinfo1 *info = matchinfo; 620 const struct xt_hashlimit_mtinfo1 *info = par->matchinfo;
630 struct xt_hashlimit_htable *hinfo = info->hinfo; 621 struct xt_hashlimit_htable *hinfo = info->hinfo;
631 unsigned long now = jiffies; 622 unsigned long now = jiffies;
632 struct dsthash_ent *dh; 623 struct dsthash_ent *dh;
633 struct dsthash_dst dst; 624 struct dsthash_dst dst;
634 625
635 if (hashlimit_init_dst(hinfo, &dst, skb, protoff) < 0) 626 if (hashlimit_init_dst(hinfo, &dst, skb, par->thoff) < 0)
636 goto hotdrop; 627 goto hotdrop;
637 628
638 spin_lock_bh(&hinfo->lock); 629 spin_lock_bh(&hinfo->lock);
@@ -669,16 +660,13 @@ hashlimit_mt(const struct sk_buff *skb, const struct net_device *in,
669 return info->cfg.mode & XT_HASHLIMIT_INVERT; 660 return info->cfg.mode & XT_HASHLIMIT_INVERT;
670 661
671 hotdrop: 662 hotdrop:
672 *hotdrop = true; 663 *par->hotdrop = true;
673 return false; 664 return false;
674} 665}
675 666
676static bool 667static bool hashlimit_mt_check_v0(const struct xt_mtchk_param *par)
677hashlimit_mt_check_v0(const char *tablename, const void *inf,
678 const struct xt_match *match, void *matchinfo,
679 unsigned int hook_mask)
680{ 668{
681 struct xt_hashlimit_info *r = matchinfo; 669 struct xt_hashlimit_info *r = par->matchinfo;
682 670
683 /* Check for overflow. */ 671 /* Check for overflow. */
684 if (r->cfg.burst == 0 || 672 if (r->cfg.burst == 0 ||
@@ -707,8 +695,8 @@ hashlimit_mt_check_v0(const char *tablename, const void *inf,
707 * the list of htable's in htable_create(), since then we would 695 * the list of htable's in htable_create(), since then we would
708 * create duplicate proc files. -HW */ 696 * create duplicate proc files. -HW */
709 mutex_lock(&hlimit_mutex); 697 mutex_lock(&hlimit_mutex);
710 r->hinfo = htable_find_get(r->name, match->family); 698 r->hinfo = htable_find_get(r->name, par->match->family);
711 if (!r->hinfo && htable_create_v0(r, match->family) != 0) { 699 if (!r->hinfo && htable_create_v0(r, par->match->family) != 0) {
712 mutex_unlock(&hlimit_mutex); 700 mutex_unlock(&hlimit_mutex);
713 return false; 701 return false;
714 } 702 }
@@ -719,12 +707,9 @@ hashlimit_mt_check_v0(const char *tablename, const void *inf,
719 return true; 707 return true;
720} 708}
721 709
722static bool 710static bool hashlimit_mt_check(const struct xt_mtchk_param *par)
723hashlimit_mt_check(const char *tablename, const void *inf,
724 const struct xt_match *match, void *matchinfo,
725 unsigned int hook_mask)
726{ 711{
727 struct xt_hashlimit_mtinfo1 *info = matchinfo; 712 struct xt_hashlimit_mtinfo1 *info = par->matchinfo;
728 713
729 /* Check for overflow. */ 714 /* Check for overflow. */
730 if (info->cfg.burst == 0 || 715 if (info->cfg.burst == 0 ||
@@ -738,7 +723,7 @@ hashlimit_mt_check(const char *tablename, const void *inf,
738 return false; 723 return false;
739 if (info->name[sizeof(info->name)-1] != '\0') 724 if (info->name[sizeof(info->name)-1] != '\0')
740 return false; 725 return false;
741 if (match->family == AF_INET) { 726 if (par->match->family == NFPROTO_IPV4) {
742 if (info->cfg.srcmask > 32 || info->cfg.dstmask > 32) 727 if (info->cfg.srcmask > 32 || info->cfg.dstmask > 32)
743 return false; 728 return false;
744 } else { 729 } else {
@@ -753,8 +738,8 @@ hashlimit_mt_check(const char *tablename, const void *inf,
753 * the list of htable's in htable_create(), since then we would 738 * the list of htable's in htable_create(), since then we would
754 * create duplicate proc files. -HW */ 739 * create duplicate proc files. -HW */
755 mutex_lock(&hlimit_mutex); 740 mutex_lock(&hlimit_mutex);
756 info->hinfo = htable_find_get(info->name, match->family); 741 info->hinfo = htable_find_get(info->name, par->match->family);
757 if (!info->hinfo && htable_create(info, match->family) != 0) { 742 if (!info->hinfo && htable_create(info, par->match->family) != 0) {
758 mutex_unlock(&hlimit_mutex); 743 mutex_unlock(&hlimit_mutex);
759 return false; 744 return false;
760 } 745 }
@@ -763,17 +748,16 @@ hashlimit_mt_check(const char *tablename, const void *inf,
763} 748}
764 749
765static void 750static void
766hashlimit_mt_destroy_v0(const struct xt_match *match, void *matchinfo) 751hashlimit_mt_destroy_v0(const struct xt_mtdtor_param *par)
767{ 752{
768 const struct xt_hashlimit_info *r = matchinfo; 753 const struct xt_hashlimit_info *r = par->matchinfo;
769 754
770 htable_put(r->hinfo); 755 htable_put(r->hinfo);
771} 756}
772 757
773static void 758static void hashlimit_mt_destroy(const struct xt_mtdtor_param *par)
774hashlimit_mt_destroy(const struct xt_match *match, void *matchinfo)
775{ 759{
776 const struct xt_hashlimit_mtinfo1 *info = matchinfo; 760 const struct xt_hashlimit_mtinfo1 *info = par->matchinfo;
777 761
778 htable_put(info->hinfo); 762 htable_put(info->hinfo);
779} 763}
@@ -806,7 +790,7 @@ static struct xt_match hashlimit_mt_reg[] __read_mostly = {
806 { 790 {
807 .name = "hashlimit", 791 .name = "hashlimit",
808 .revision = 0, 792 .revision = 0,
809 .family = AF_INET, 793 .family = NFPROTO_IPV4,
810 .match = hashlimit_mt_v0, 794 .match = hashlimit_mt_v0,
811 .matchsize = sizeof(struct xt_hashlimit_info), 795 .matchsize = sizeof(struct xt_hashlimit_info),
812#ifdef CONFIG_COMPAT 796#ifdef CONFIG_COMPAT
@@ -821,7 +805,7 @@ static struct xt_match hashlimit_mt_reg[] __read_mostly = {
821 { 805 {
822 .name = "hashlimit", 806 .name = "hashlimit",
823 .revision = 1, 807 .revision = 1,
824 .family = AF_INET, 808 .family = NFPROTO_IPV4,
825 .match = hashlimit_mt, 809 .match = hashlimit_mt,
826 .matchsize = sizeof(struct xt_hashlimit_mtinfo1), 810 .matchsize = sizeof(struct xt_hashlimit_mtinfo1),
827 .checkentry = hashlimit_mt_check, 811 .checkentry = hashlimit_mt_check,
@@ -831,7 +815,7 @@ static struct xt_match hashlimit_mt_reg[] __read_mostly = {
831#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) 815#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
832 { 816 {
833 .name = "hashlimit", 817 .name = "hashlimit",
834 .family = AF_INET6, 818 .family = NFPROTO_IPV6,
835 .match = hashlimit_mt_v0, 819 .match = hashlimit_mt_v0,
836 .matchsize = sizeof(struct xt_hashlimit_info), 820 .matchsize = sizeof(struct xt_hashlimit_info),
837#ifdef CONFIG_COMPAT 821#ifdef CONFIG_COMPAT
@@ -846,7 +830,7 @@ static struct xt_match hashlimit_mt_reg[] __read_mostly = {
846 { 830 {
847 .name = "hashlimit", 831 .name = "hashlimit",
848 .revision = 1, 832 .revision = 1,
849 .family = AF_INET6, 833 .family = NFPROTO_IPV6,
850 .match = hashlimit_mt, 834 .match = hashlimit_mt,
851 .matchsize = sizeof(struct xt_hashlimit_mtinfo1), 835 .matchsize = sizeof(struct xt_hashlimit_mtinfo1),
852 .checkentry = hashlimit_mt_check, 836 .checkentry = hashlimit_mt_check,
@@ -901,14 +885,14 @@ static void dl_seq_stop(struct seq_file *s, void *v)
901 spin_unlock_bh(&htable->lock); 885 spin_unlock_bh(&htable->lock);
902} 886}
903 887
904static int dl_seq_real_show(struct dsthash_ent *ent, int family, 888static int dl_seq_real_show(struct dsthash_ent *ent, u_int8_t family,
905 struct seq_file *s) 889 struct seq_file *s)
906{ 890{
907 /* recalculate to show accurate numbers */ 891 /* recalculate to show accurate numbers */
908 rateinfo_recalc(ent, jiffies); 892 rateinfo_recalc(ent, jiffies);
909 893
910 switch (family) { 894 switch (family) {
911 case AF_INET: 895 case NFPROTO_IPV4:
912 return seq_printf(s, "%ld %u.%u.%u.%u:%u->" 896 return seq_printf(s, "%ld %u.%u.%u.%u:%u->"
913 "%u.%u.%u.%u:%u %u %u %u\n", 897 "%u.%u.%u.%u:%u %u %u %u\n",
914 (long)(ent->expires - jiffies)/HZ, 898 (long)(ent->expires - jiffies)/HZ,
@@ -919,7 +903,7 @@ static int dl_seq_real_show(struct dsthash_ent *ent, int family,
919 ent->rateinfo.credit, ent->rateinfo.credit_cap, 903 ent->rateinfo.credit, ent->rateinfo.credit_cap,
920 ent->rateinfo.cost); 904 ent->rateinfo.cost);
921#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE) 905#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
922 case AF_INET6: 906 case NFPROTO_IPV6:
923 return seq_printf(s, "%ld " NIP6_FMT ":%u->" 907 return seq_printf(s, "%ld " NIP6_FMT ":%u->"
924 NIP6_FMT ":%u %u %u %u\n", 908 NIP6_FMT ":%u %u %u %u\n",
925 (long)(ent->expires - jiffies)/HZ, 909 (long)(ent->expires - jiffies)/HZ,
diff --git a/net/netfilter/xt_helper.c b/net/netfilter/xt_helper.c
index dada2905d66e..64fc7f277221 100644
--- a/net/netfilter/xt_helper.c
+++ b/net/netfilter/xt_helper.c
@@ -24,12 +24,9 @@ MODULE_ALIAS("ip6t_helper");
24 24
25 25
26static bool 26static bool
27helper_mt(const struct sk_buff *skb, const struct net_device *in, 27helper_mt(const struct sk_buff *skb, const struct xt_match_param *par)
28 const struct net_device *out, const struct xt_match *match,
29 const void *matchinfo, int offset, unsigned int protoff,
30 bool *hotdrop)
31{ 28{
32 const struct xt_helper_info *info = matchinfo; 29 const struct xt_helper_info *info = par->matchinfo;
33 const struct nf_conn *ct; 30 const struct nf_conn *ct;
34 const struct nf_conn_help *master_help; 31 const struct nf_conn_help *master_help;
35 const struct nf_conntrack_helper *helper; 32 const struct nf_conntrack_helper *helper;
@@ -57,56 +54,43 @@ helper_mt(const struct sk_buff *skb, const struct net_device *in,
57 return ret; 54 return ret;
58} 55}
59 56
60static bool 57static bool helper_mt_check(const struct xt_mtchk_param *par)
61helper_mt_check(const char *tablename, const void *inf,
62 const struct xt_match *match, void *matchinfo,
63 unsigned int hook_mask)
64{ 58{
65 struct xt_helper_info *info = matchinfo; 59 struct xt_helper_info *info = par->matchinfo;
66 60
67 if (nf_ct_l3proto_try_module_get(match->family) < 0) { 61 if (nf_ct_l3proto_try_module_get(par->family) < 0) {
68 printk(KERN_WARNING "can't load conntrack support for " 62 printk(KERN_WARNING "can't load conntrack support for "
69 "proto=%u\n", match->family); 63 "proto=%u\n", par->family);
70 return false; 64 return false;
71 } 65 }
72 info->name[29] = '\0'; 66 info->name[29] = '\0';
73 return true; 67 return true;
74} 68}
75 69
76static void helper_mt_destroy(const struct xt_match *match, void *matchinfo) 70static void helper_mt_destroy(const struct xt_mtdtor_param *par)
77{ 71{
78 nf_ct_l3proto_module_put(match->family); 72 nf_ct_l3proto_module_put(par->family);
79} 73}
80 74
81static struct xt_match helper_mt_reg[] __read_mostly = { 75static struct xt_match helper_mt_reg __read_mostly = {
82 { 76 .name = "helper",
83 .name = "helper", 77 .revision = 0,
84 .family = AF_INET, 78 .family = NFPROTO_UNSPEC,
85 .checkentry = helper_mt_check, 79 .checkentry = helper_mt_check,
86 .match = helper_mt, 80 .match = helper_mt,
87 .destroy = helper_mt_destroy, 81 .destroy = helper_mt_destroy,
88 .matchsize = sizeof(struct xt_helper_info), 82 .matchsize = sizeof(struct xt_helper_info),
89 .me = THIS_MODULE, 83 .me = THIS_MODULE,
90 },
91 {
92 .name = "helper",
93 .family = AF_INET6,
94 .checkentry = helper_mt_check,
95 .match = helper_mt,
96 .destroy = helper_mt_destroy,
97 .matchsize = sizeof(struct xt_helper_info),
98 .me = THIS_MODULE,
99 },
100}; 84};
101 85
102static int __init helper_mt_init(void) 86static int __init helper_mt_init(void)
103{ 87{
104 return xt_register_matches(helper_mt_reg, ARRAY_SIZE(helper_mt_reg)); 88 return xt_register_match(&helper_mt_reg);
105} 89}
106 90
107static void __exit helper_mt_exit(void) 91static void __exit helper_mt_exit(void)
108{ 92{
109 xt_unregister_matches(helper_mt_reg, ARRAY_SIZE(helper_mt_reg)); 93 xt_unregister_match(&helper_mt_reg);
110} 94}
111 95
112module_init(helper_mt_init); 96module_init(helper_mt_init);
diff --git a/net/netfilter/xt_iprange.c b/net/netfilter/xt_iprange.c
index c63e9333c755..6f62c36948d9 100644
--- a/net/netfilter/xt_iprange.c
+++ b/net/netfilter/xt_iprange.c
@@ -17,12 +17,9 @@
17#include <linux/netfilter_ipv4/ipt_iprange.h> 17#include <linux/netfilter_ipv4/ipt_iprange.h>
18 18
19static bool 19static bool
20iprange_mt_v0(const struct sk_buff *skb, const struct net_device *in, 20iprange_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
21 const struct net_device *out, const struct xt_match *match,
22 const void *matchinfo, int offset, unsigned int protoff,
23 bool *hotdrop)
24{ 21{
25 const struct ipt_iprange_info *info = matchinfo; 22 const struct ipt_iprange_info *info = par->matchinfo;
26 const struct iphdr *iph = ip_hdr(skb); 23 const struct iphdr *iph = ip_hdr(skb);
27 24
28 if (info->flags & IPRANGE_SRC) { 25 if (info->flags & IPRANGE_SRC) {
@@ -55,12 +52,9 @@ iprange_mt_v0(const struct sk_buff *skb, const struct net_device *in,
55} 52}
56 53
57static bool 54static bool
58iprange_mt4(const struct sk_buff *skb, const struct net_device *in, 55iprange_mt4(const struct sk_buff *skb, const struct xt_match_param *par)
59 const struct net_device *out, const struct xt_match *match,
60 const void *matchinfo, int offset, unsigned int protoff,
61 bool *hotdrop)
62{ 56{
63 const struct xt_iprange_mtinfo *info = matchinfo; 57 const struct xt_iprange_mtinfo *info = par->matchinfo;
64 const struct iphdr *iph = ip_hdr(skb); 58 const struct iphdr *iph = ip_hdr(skb);
65 bool m; 59 bool m;
66 60
@@ -111,12 +105,9 @@ iprange_ipv6_sub(const struct in6_addr *a, const struct in6_addr *b)
111} 105}
112 106
113static bool 107static bool
114iprange_mt6(const struct sk_buff *skb, const struct net_device *in, 108iprange_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
115 const struct net_device *out, const struct xt_match *match,
116 const void *matchinfo, int offset, unsigned int protoff,
117 bool *hotdrop)
118{ 109{
119 const struct xt_iprange_mtinfo *info = matchinfo; 110 const struct xt_iprange_mtinfo *info = par->matchinfo;
120 const struct ipv6hdr *iph = ipv6_hdr(skb); 111 const struct ipv6hdr *iph = ipv6_hdr(skb);
121 bool m; 112 bool m;
122 113
@@ -141,7 +132,7 @@ static struct xt_match iprange_mt_reg[] __read_mostly = {
141 { 132 {
142 .name = "iprange", 133 .name = "iprange",
143 .revision = 0, 134 .revision = 0,
144 .family = AF_INET, 135 .family = NFPROTO_IPV4,
145 .match = iprange_mt_v0, 136 .match = iprange_mt_v0,
146 .matchsize = sizeof(struct ipt_iprange_info), 137 .matchsize = sizeof(struct ipt_iprange_info),
147 .me = THIS_MODULE, 138 .me = THIS_MODULE,
@@ -149,7 +140,7 @@ static struct xt_match iprange_mt_reg[] __read_mostly = {
149 { 140 {
150 .name = "iprange", 141 .name = "iprange",
151 .revision = 1, 142 .revision = 1,
152 .family = AF_INET, 143 .family = NFPROTO_IPV4,
153 .match = iprange_mt4, 144 .match = iprange_mt4,
154 .matchsize = sizeof(struct xt_iprange_mtinfo), 145 .matchsize = sizeof(struct xt_iprange_mtinfo),
155 .me = THIS_MODULE, 146 .me = THIS_MODULE,
@@ -157,7 +148,7 @@ static struct xt_match iprange_mt_reg[] __read_mostly = {
157 { 148 {
158 .name = "iprange", 149 .name = "iprange",
159 .revision = 1, 150 .revision = 1,
160 .family = AF_INET6, 151 .family = NFPROTO_IPV6,
161 .match = iprange_mt6, 152 .match = iprange_mt6,
162 .matchsize = sizeof(struct xt_iprange_mtinfo), 153 .matchsize = sizeof(struct xt_iprange_mtinfo),
163 .me = THIS_MODULE, 154 .me = THIS_MODULE,
diff --git a/net/netfilter/xt_length.c b/net/netfilter/xt_length.c
index b8640f972950..c4871ca6c86d 100644
--- a/net/netfilter/xt_length.c
+++ b/net/netfilter/xt_length.c
@@ -21,24 +21,18 @@ MODULE_ALIAS("ipt_length");
21MODULE_ALIAS("ip6t_length"); 21MODULE_ALIAS("ip6t_length");
22 22
23static bool 23static bool
24length_mt(const struct sk_buff *skb, const struct net_device *in, 24length_mt(const struct sk_buff *skb, const struct xt_match_param *par)
25 const struct net_device *out, const struct xt_match *match,
26 const void *matchinfo, int offset, unsigned int protoff,
27 bool *hotdrop)
28{ 25{
29 const struct xt_length_info *info = matchinfo; 26 const struct xt_length_info *info = par->matchinfo;
30 u_int16_t pktlen = ntohs(ip_hdr(skb)->tot_len); 27 u_int16_t pktlen = ntohs(ip_hdr(skb)->tot_len);
31 28
32 return (pktlen >= info->min && pktlen <= info->max) ^ info->invert; 29 return (pktlen >= info->min && pktlen <= info->max) ^ info->invert;
33} 30}
34 31
35static bool 32static bool
36length_mt6(const struct sk_buff *skb, const struct net_device *in, 33length_mt6(const struct sk_buff *skb, const struct xt_match_param *par)
37 const struct net_device *out, const struct xt_match *match,
38 const void *matchinfo, int offset, unsigned int protoff,
39 bool *hotdrop)
40{ 34{
41 const struct xt_length_info *info = matchinfo; 35 const struct xt_length_info *info = par->matchinfo;
42 const u_int16_t pktlen = ntohs(ipv6_hdr(skb)->payload_len) + 36 const u_int16_t pktlen = ntohs(ipv6_hdr(skb)->payload_len) +
43 sizeof(struct ipv6hdr); 37 sizeof(struct ipv6hdr);
44 38
@@ -48,14 +42,14 @@ length_mt6(const struct sk_buff *skb, const struct net_device *in,
48static struct xt_match length_mt_reg[] __read_mostly = { 42static struct xt_match length_mt_reg[] __read_mostly = {
49 { 43 {
50 .name = "length", 44 .name = "length",
51 .family = AF_INET, 45 .family = NFPROTO_IPV4,
52 .match = length_mt, 46 .match = length_mt,
53 .matchsize = sizeof(struct xt_length_info), 47 .matchsize = sizeof(struct xt_length_info),
54 .me = THIS_MODULE, 48 .me = THIS_MODULE,
55 }, 49 },
56 { 50 {
57 .name = "length", 51 .name = "length",
58 .family = AF_INET6, 52 .family = NFPROTO_IPV6,
59 .match = length_mt6, 53 .match = length_mt6,
60 .matchsize = sizeof(struct xt_length_info), 54 .matchsize = sizeof(struct xt_length_info),
61 .me = THIS_MODULE, 55 .me = THIS_MODULE,
diff --git a/net/netfilter/xt_limit.c b/net/netfilter/xt_limit.c
index aad9ab8d2046..c908d69a5595 100644
--- a/net/netfilter/xt_limit.c
+++ b/net/netfilter/xt_limit.c
@@ -58,13 +58,10 @@ static DEFINE_SPINLOCK(limit_lock);
58#define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ) 58#define CREDITS_PER_JIFFY POW2_BELOW32(MAX_CPJ)
59 59
60static bool 60static bool
61limit_mt(const struct sk_buff *skb, const struct net_device *in, 61limit_mt(const struct sk_buff *skb, const struct xt_match_param *par)
62 const struct net_device *out, const struct xt_match *match,
63 const void *matchinfo, int offset, unsigned int protoff,
64 bool *hotdrop)
65{ 62{
66 struct xt_rateinfo *r = 63 struct xt_rateinfo *r =
67 ((const struct xt_rateinfo *)matchinfo)->master; 64 ((const struct xt_rateinfo *)par->matchinfo)->master;
68 unsigned long now = jiffies; 65 unsigned long now = jiffies;
69 66
70 spin_lock_bh(&limit_lock); 67 spin_lock_bh(&limit_lock);
@@ -95,12 +92,9 @@ user2credits(u_int32_t user)
95 return (user * HZ * CREDITS_PER_JIFFY) / XT_LIMIT_SCALE; 92 return (user * HZ * CREDITS_PER_JIFFY) / XT_LIMIT_SCALE;
96} 93}
97 94
98static bool 95static bool limit_mt_check(const struct xt_mtchk_param *par)
99limit_mt_check(const char *tablename, const void *inf,
100 const struct xt_match *match, void *matchinfo,
101 unsigned int hook_mask)
102{ 96{
103 struct xt_rateinfo *r = matchinfo; 97 struct xt_rateinfo *r = par->matchinfo;
104 98
105 /* Check for overflow. */ 99 /* Check for overflow. */
106 if (r->burst == 0 100 if (r->burst == 0
@@ -167,43 +161,29 @@ static int limit_mt_compat_to_user(void __user *dst, void *src)
167} 161}
168#endif /* CONFIG_COMPAT */ 162#endif /* CONFIG_COMPAT */
169 163
170static struct xt_match limit_mt_reg[] __read_mostly = { 164static struct xt_match limit_mt_reg __read_mostly = {
171 { 165 .name = "limit",
172 .name = "limit", 166 .revision = 0,
173 .family = AF_INET, 167 .family = NFPROTO_UNSPEC,
174 .checkentry = limit_mt_check, 168 .match = limit_mt,
175 .match = limit_mt, 169 .checkentry = limit_mt_check,
176 .matchsize = sizeof(struct xt_rateinfo), 170 .matchsize = sizeof(struct xt_rateinfo),
177#ifdef CONFIG_COMPAT
178 .compatsize = sizeof(struct compat_xt_rateinfo),
179 .compat_from_user = limit_mt_compat_from_user,
180 .compat_to_user = limit_mt_compat_to_user,
181#endif
182 .me = THIS_MODULE,
183 },
184 {
185 .name = "limit",
186 .family = AF_INET6,
187 .checkentry = limit_mt_check,
188 .match = limit_mt,
189 .matchsize = sizeof(struct xt_rateinfo),
190#ifdef CONFIG_COMPAT 171#ifdef CONFIG_COMPAT
191 .compatsize = sizeof(struct compat_xt_rateinfo), 172 .compatsize = sizeof(struct compat_xt_rateinfo),
192 .compat_from_user = limit_mt_compat_from_user, 173 .compat_from_user = limit_mt_compat_from_user,
193 .compat_to_user = limit_mt_compat_to_user, 174 .compat_to_user = limit_mt_compat_to_user,
194#endif 175#endif
195 .me = THIS_MODULE, 176 .me = THIS_MODULE,
196 },
197}; 177};
198 178
199static int __init limit_mt_init(void) 179static int __init limit_mt_init(void)
200{ 180{
201 return xt_register_matches(limit_mt_reg, ARRAY_SIZE(limit_mt_reg)); 181 return xt_register_match(&limit_mt_reg);
202} 182}
203 183
204static void __exit limit_mt_exit(void) 184static void __exit limit_mt_exit(void)
205{ 185{
206 xt_unregister_matches(limit_mt_reg, ARRAY_SIZE(limit_mt_reg)); 186 xt_unregister_match(&limit_mt_reg);
207} 187}
208 188
209module_init(limit_mt_init); 189module_init(limit_mt_init);
diff --git a/net/netfilter/xt_mac.c b/net/netfilter/xt_mac.c
index b3e96a0ec176..c2007116ce5b 100644
--- a/net/netfilter/xt_mac.c
+++ b/net/netfilter/xt_mac.c
@@ -24,12 +24,9 @@ MODULE_DESCRIPTION("Xtables: MAC address match");
24MODULE_ALIAS("ipt_mac"); 24MODULE_ALIAS("ipt_mac");
25MODULE_ALIAS("ip6t_mac"); 25MODULE_ALIAS("ip6t_mac");
26 26
27static bool 27static bool mac_mt(const struct sk_buff *skb, const struct xt_match_param *par)
28mac_mt(const struct sk_buff *skb, const struct net_device *in,
29 const struct net_device *out, const struct xt_match *match,
30 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
31{ 28{
32 const struct xt_mac_info *info = matchinfo; 29 const struct xt_mac_info *info = par->matchinfo;
33 30
34 /* Is mac pointer valid? */ 31 /* Is mac pointer valid? */
35 return skb_mac_header(skb) >= skb->head && 32 return skb_mac_header(skb) >= skb->head &&
@@ -39,37 +36,25 @@ mac_mt(const struct sk_buff *skb, const struct net_device *in,
39 ^ info->invert); 36 ^ info->invert);
40} 37}
41 38
42static struct xt_match mac_mt_reg[] __read_mostly = { 39static struct xt_match mac_mt_reg __read_mostly = {
43 { 40 .name = "mac",
44 .name = "mac", 41 .revision = 0,
45 .family = AF_INET, 42 .family = NFPROTO_UNSPEC,
46 .match = mac_mt, 43 .match = mac_mt,
47 .matchsize = sizeof(struct xt_mac_info), 44 .matchsize = sizeof(struct xt_mac_info),
48 .hooks = (1 << NF_INET_PRE_ROUTING) | 45 .hooks = (1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_IN) |
49 (1 << NF_INET_LOCAL_IN) | 46 (1 << NF_INET_FORWARD),
50 (1 << NF_INET_FORWARD), 47 .me = THIS_MODULE,
51 .me = THIS_MODULE,
52 },
53 {
54 .name = "mac",
55 .family = AF_INET6,
56 .match = mac_mt,
57 .matchsize = sizeof(struct xt_mac_info),
58 .hooks = (1 << NF_INET_PRE_ROUTING) |
59 (1 << NF_INET_LOCAL_IN) |
60 (1 << NF_INET_FORWARD),
61 .me = THIS_MODULE,
62 },
63}; 48};
64 49
65static int __init mac_mt_init(void) 50static int __init mac_mt_init(void)
66{ 51{
67 return xt_register_matches(mac_mt_reg, ARRAY_SIZE(mac_mt_reg)); 52 return xt_register_match(&mac_mt_reg);
68} 53}
69 54
70static void __exit mac_mt_exit(void) 55static void __exit mac_mt_exit(void)
71{ 56{
72 xt_unregister_matches(mac_mt_reg, ARRAY_SIZE(mac_mt_reg)); 57 xt_unregister_match(&mac_mt_reg);
73} 58}
74 59
75module_init(mac_mt_init); 60module_init(mac_mt_init);
diff --git a/net/netfilter/xt_mark.c b/net/netfilter/xt_mark.c
index 9f78f6120fbd..10b9e34bbc5b 100644
--- a/net/netfilter/xt_mark.c
+++ b/net/netfilter/xt_mark.c
@@ -23,32 +23,24 @@ MODULE_ALIAS("ipt_mark");
23MODULE_ALIAS("ip6t_mark"); 23MODULE_ALIAS("ip6t_mark");
24 24
25static bool 25static bool
26mark_mt_v0(const struct sk_buff *skb, const struct net_device *in, 26mark_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
27 const struct net_device *out, const struct xt_match *match,
28 const void *matchinfo, int offset, unsigned int protoff,
29 bool *hotdrop)
30{ 27{
31 const struct xt_mark_info *info = matchinfo; 28 const struct xt_mark_info *info = par->matchinfo;
32 29
33 return ((skb->mark & info->mask) == info->mark) ^ info->invert; 30 return ((skb->mark & info->mask) == info->mark) ^ info->invert;
34} 31}
35 32
36static bool 33static bool
37mark_mt(const struct sk_buff *skb, const struct net_device *in, 34mark_mt(const struct sk_buff *skb, const struct xt_match_param *par)
38 const struct net_device *out, const struct xt_match *match,
39 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
40{ 35{
41 const struct xt_mark_mtinfo1 *info = matchinfo; 36 const struct xt_mark_mtinfo1 *info = par->matchinfo;
42 37
43 return ((skb->mark & info->mask) == info->mark) ^ info->invert; 38 return ((skb->mark & info->mask) == info->mark) ^ info->invert;
44} 39}
45 40
46static bool 41static bool mark_mt_check_v0(const struct xt_mtchk_param *par)
47mark_mt_check_v0(const char *tablename, const void *entry,
48 const struct xt_match *match, void *matchinfo,
49 unsigned int hook_mask)
50{ 42{
51 const struct xt_mark_info *minfo = matchinfo; 43 const struct xt_mark_info *minfo = par->matchinfo;
52 44
53 if (minfo->mark > 0xffffffff || minfo->mask > 0xffffffff) { 45 if (minfo->mark > 0xffffffff || minfo->mask > 0xffffffff) {
54 printk(KERN_WARNING "mark: only supports 32bit mark\n"); 46 printk(KERN_WARNING "mark: only supports 32bit mark\n");
@@ -92,7 +84,7 @@ static struct xt_match mark_mt_reg[] __read_mostly = {
92 { 84 {
93 .name = "mark", 85 .name = "mark",
94 .revision = 0, 86 .revision = 0,
95 .family = AF_INET, 87 .family = NFPROTO_UNSPEC,
96 .checkentry = mark_mt_check_v0, 88 .checkentry = mark_mt_check_v0,
97 .match = mark_mt_v0, 89 .match = mark_mt_v0,
98 .matchsize = sizeof(struct xt_mark_info), 90 .matchsize = sizeof(struct xt_mark_info),
@@ -104,31 +96,9 @@ static struct xt_match mark_mt_reg[] __read_mostly = {
104 .me = THIS_MODULE, 96 .me = THIS_MODULE,
105 }, 97 },
106 { 98 {
107 .name = "mark",
108 .revision = 0,
109 .family = AF_INET6,
110 .checkentry = mark_mt_check_v0,
111 .match = mark_mt_v0,
112 .matchsize = sizeof(struct xt_mark_info),
113#ifdef CONFIG_COMPAT
114 .compatsize = sizeof(struct compat_xt_mark_info),
115 .compat_from_user = mark_mt_compat_from_user_v0,
116 .compat_to_user = mark_mt_compat_to_user_v0,
117#endif
118 .me = THIS_MODULE,
119 },
120 {
121 .name = "mark",
122 .revision = 1,
123 .family = AF_INET,
124 .match = mark_mt,
125 .matchsize = sizeof(struct xt_mark_mtinfo1),
126 .me = THIS_MODULE,
127 },
128 {
129 .name = "mark", 99 .name = "mark",
130 .revision = 1, 100 .revision = 1,
131 .family = AF_INET6, 101 .family = NFPROTO_UNSPEC,
132 .match = mark_mt, 102 .match = mark_mt,
133 .matchsize = sizeof(struct xt_mark_mtinfo1), 103 .matchsize = sizeof(struct xt_mark_mtinfo1),
134 .me = THIS_MODULE, 104 .me = THIS_MODULE,
diff --git a/net/netfilter/xt_multiport.c b/net/netfilter/xt_multiport.c
index fd88c489b70e..d06bb2dd3900 100644
--- a/net/netfilter/xt_multiport.c
+++ b/net/netfilter/xt_multiport.c
@@ -95,25 +95,22 @@ ports_match_v1(const struct xt_multiport_v1 *minfo,
95} 95}
96 96
97static bool 97static bool
98multiport_mt_v0(const struct sk_buff *skb, const struct net_device *in, 98multiport_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
99 const struct net_device *out, const struct xt_match *match,
100 const void *matchinfo, int offset, unsigned int protoff,
101 bool *hotdrop)
102{ 99{
103 const __be16 *pptr; 100 const __be16 *pptr;
104 __be16 _ports[2]; 101 __be16 _ports[2];
105 const struct xt_multiport *multiinfo = matchinfo; 102 const struct xt_multiport *multiinfo = par->matchinfo;
106 103
107 if (offset) 104 if (par->fragoff != 0)
108 return false; 105 return false;
109 106
110 pptr = skb_header_pointer(skb, protoff, sizeof(_ports), _ports); 107 pptr = skb_header_pointer(skb, par->thoff, sizeof(_ports), _ports);
111 if (pptr == NULL) { 108 if (pptr == NULL) {
112 /* We've been asked to examine this packet, and we 109 /* We've been asked to examine this packet, and we
113 * can't. Hence, no choice but to drop. 110 * can't. Hence, no choice but to drop.
114 */ 111 */
115 duprintf("xt_multiport: Dropping evil offset=0 tinygram.\n"); 112 duprintf("xt_multiport: Dropping evil offset=0 tinygram.\n");
116 *hotdrop = true; 113 *par->hotdrop = true;
117 return false; 114 return false;
118 } 115 }
119 116
@@ -122,25 +119,22 @@ multiport_mt_v0(const struct sk_buff *skb, const struct net_device *in,
122} 119}
123 120
124static bool 121static bool
125multiport_mt(const struct sk_buff *skb, const struct net_device *in, 122multiport_mt(const struct sk_buff *skb, const struct xt_match_param *par)
126 const struct net_device *out, const struct xt_match *match,
127 const void *matchinfo, int offset, unsigned int protoff,
128 bool *hotdrop)
129{ 123{
130 const __be16 *pptr; 124 const __be16 *pptr;
131 __be16 _ports[2]; 125 __be16 _ports[2];
132 const struct xt_multiport_v1 *multiinfo = matchinfo; 126 const struct xt_multiport_v1 *multiinfo = par->matchinfo;
133 127
134 if (offset) 128 if (par->fragoff != 0)
135 return false; 129 return false;
136 130
137 pptr = skb_header_pointer(skb, protoff, sizeof(_ports), _ports); 131 pptr = skb_header_pointer(skb, par->thoff, sizeof(_ports), _ports);
138 if (pptr == NULL) { 132 if (pptr == NULL) {
139 /* We've been asked to examine this packet, and we 133 /* We've been asked to examine this packet, and we
140 * can't. Hence, no choice but to drop. 134 * can't. Hence, no choice but to drop.
141 */ 135 */
142 duprintf("xt_multiport: Dropping evil offset=0 tinygram.\n"); 136 duprintf("xt_multiport: Dropping evil offset=0 tinygram.\n");
143 *hotdrop = true; 137 *par->hotdrop = true;
144 return false; 138 return false;
145 } 139 }
146 140
@@ -164,50 +158,37 @@ check(u_int16_t proto,
164 && count <= XT_MULTI_PORTS; 158 && count <= XT_MULTI_PORTS;
165} 159}
166 160
167/* Called when user tries to insert an entry of this type. */ 161static bool multiport_mt_check_v0(const struct xt_mtchk_param *par)
168static bool
169multiport_mt_check_v0(const char *tablename, const void *info,
170 const struct xt_match *match, void *matchinfo,
171 unsigned int hook_mask)
172{ 162{
173 const struct ipt_ip *ip = info; 163 const struct ipt_ip *ip = par->entryinfo;
174 const struct xt_multiport *multiinfo = matchinfo; 164 const struct xt_multiport *multiinfo = par->matchinfo;
175 165
176 return check(ip->proto, ip->invflags, multiinfo->flags, 166 return check(ip->proto, ip->invflags, multiinfo->flags,
177 multiinfo->count); 167 multiinfo->count);
178} 168}
179 169
180static bool 170static bool multiport_mt_check(const struct xt_mtchk_param *par)
181multiport_mt_check(const char *tablename, const void *info,
182 const struct xt_match *match, void *matchinfo,
183 unsigned int hook_mask)
184{ 171{
185 const struct ipt_ip *ip = info; 172 const struct ipt_ip *ip = par->entryinfo;
186 const struct xt_multiport_v1 *multiinfo = matchinfo; 173 const struct xt_multiport_v1 *multiinfo = par->matchinfo;
187 174
188 return check(ip->proto, ip->invflags, multiinfo->flags, 175 return check(ip->proto, ip->invflags, multiinfo->flags,
189 multiinfo->count); 176 multiinfo->count);
190} 177}
191 178
192static bool 179static bool multiport_mt6_check_v0(const struct xt_mtchk_param *par)
193multiport_mt6_check_v0(const char *tablename, const void *info,
194 const struct xt_match *match, void *matchinfo,
195 unsigned int hook_mask)
196{ 180{
197 const struct ip6t_ip6 *ip = info; 181 const struct ip6t_ip6 *ip = par->entryinfo;
198 const struct xt_multiport *multiinfo = matchinfo; 182 const struct xt_multiport *multiinfo = par->matchinfo;
199 183
200 return check(ip->proto, ip->invflags, multiinfo->flags, 184 return check(ip->proto, ip->invflags, multiinfo->flags,
201 multiinfo->count); 185 multiinfo->count);
202} 186}
203 187
204static bool 188static bool multiport_mt6_check(const struct xt_mtchk_param *par)
205multiport_mt6_check(const char *tablename, const void *info,
206 const struct xt_match *match, void *matchinfo,
207 unsigned int hook_mask)
208{ 189{
209 const struct ip6t_ip6 *ip = info; 190 const struct ip6t_ip6 *ip = par->entryinfo;
210 const struct xt_multiport_v1 *multiinfo = matchinfo; 191 const struct xt_multiport_v1 *multiinfo = par->matchinfo;
211 192
212 return check(ip->proto, ip->invflags, multiinfo->flags, 193 return check(ip->proto, ip->invflags, multiinfo->flags,
213 multiinfo->count); 194 multiinfo->count);
@@ -216,7 +197,7 @@ multiport_mt6_check(const char *tablename, const void *info,
216static struct xt_match multiport_mt_reg[] __read_mostly = { 197static struct xt_match multiport_mt_reg[] __read_mostly = {
217 { 198 {
218 .name = "multiport", 199 .name = "multiport",
219 .family = AF_INET, 200 .family = NFPROTO_IPV4,
220 .revision = 0, 201 .revision = 0,
221 .checkentry = multiport_mt_check_v0, 202 .checkentry = multiport_mt_check_v0,
222 .match = multiport_mt_v0, 203 .match = multiport_mt_v0,
@@ -225,7 +206,7 @@ static struct xt_match multiport_mt_reg[] __read_mostly = {
225 }, 206 },
226 { 207 {
227 .name = "multiport", 208 .name = "multiport",
228 .family = AF_INET, 209 .family = NFPROTO_IPV4,
229 .revision = 1, 210 .revision = 1,
230 .checkentry = multiport_mt_check, 211 .checkentry = multiport_mt_check,
231 .match = multiport_mt, 212 .match = multiport_mt,
@@ -234,7 +215,7 @@ static struct xt_match multiport_mt_reg[] __read_mostly = {
234 }, 215 },
235 { 216 {
236 .name = "multiport", 217 .name = "multiport",
237 .family = AF_INET6, 218 .family = NFPROTO_IPV6,
238 .revision = 0, 219 .revision = 0,
239 .checkentry = multiport_mt6_check_v0, 220 .checkentry = multiport_mt6_check_v0,
240 .match = multiport_mt_v0, 221 .match = multiport_mt_v0,
@@ -243,7 +224,7 @@ static struct xt_match multiport_mt_reg[] __read_mostly = {
243 }, 224 },
244 { 225 {
245 .name = "multiport", 226 .name = "multiport",
246 .family = AF_INET6, 227 .family = NFPROTO_IPV6,
247 .revision = 1, 228 .revision = 1,
248 .checkentry = multiport_mt6_check, 229 .checkentry = multiport_mt6_check,
249 .match = multiport_mt, 230 .match = multiport_mt,
diff --git a/net/netfilter/xt_owner.c b/net/netfilter/xt_owner.c
index 9059c16144c3..f19ebd9b78f5 100644
--- a/net/netfilter/xt_owner.c
+++ b/net/netfilter/xt_owner.c
@@ -21,12 +21,9 @@
21#include <linux/netfilter_ipv6/ip6t_owner.h> 21#include <linux/netfilter_ipv6/ip6t_owner.h>
22 22
23static bool 23static bool
24owner_mt_v0(const struct sk_buff *skb, const struct net_device *in, 24owner_mt_v0(const struct sk_buff *skb, const struct xt_match_param *par)
25 const struct net_device *out, const struct xt_match *match,
26 const void *matchinfo, int offset, unsigned int protoff,
27 bool *hotdrop)
28{ 25{
29 const struct ipt_owner_info *info = matchinfo; 26 const struct ipt_owner_info *info = par->matchinfo;
30 const struct file *filp; 27 const struct file *filp;
31 28
32 if (skb->sk == NULL || skb->sk->sk_socket == NULL) 29 if (skb->sk == NULL || skb->sk->sk_socket == NULL)
@@ -50,12 +47,9 @@ owner_mt_v0(const struct sk_buff *skb, const struct net_device *in,
50} 47}
51 48
52static bool 49static bool
53owner_mt6_v0(const struct sk_buff *skb, const struct net_device *in, 50owner_mt6_v0(const struct sk_buff *skb, const struct xt_match_param *par)
54 const struct net_device *out, const struct xt_match *match,
55 const void *matchinfo, int offset, unsigned int protoff,
56 bool *hotdrop)
57{ 51{
58 const struct ip6t_owner_info *info = matchinfo; 52 const struct ip6t_owner_info *info = par->matchinfo;
59 const struct file *filp; 53 const struct file *filp;
60 54
61 if (skb->sk == NULL || skb->sk->sk_socket == NULL) 55 if (skb->sk == NULL || skb->sk->sk_socket == NULL)
@@ -79,12 +73,9 @@ owner_mt6_v0(const struct sk_buff *skb, const struct net_device *in,
79} 73}
80 74
81static bool 75static bool
82owner_mt(const struct sk_buff *skb, const struct net_device *in, 76owner_mt(const struct sk_buff *skb, const struct xt_match_param *par)
83 const struct net_device *out, const struct xt_match *match,
84 const void *matchinfo, int offset, unsigned int protoff,
85 bool *hotdrop)
86{ 77{
87 const struct xt_owner_match_info *info = matchinfo; 78 const struct xt_owner_match_info *info = par->matchinfo;
88 const struct file *filp; 79 const struct file *filp;
89 80
90 if (skb->sk == NULL || skb->sk->sk_socket == NULL) 81 if (skb->sk == NULL || skb->sk->sk_socket == NULL)
@@ -116,12 +107,9 @@ owner_mt(const struct sk_buff *skb, const struct net_device *in,
116 return true; 107 return true;
117} 108}
118 109
119static bool 110static bool owner_mt_check_v0(const struct xt_mtchk_param *par)
120owner_mt_check_v0(const char *tablename, const void *ip,
121 const struct xt_match *match, void *matchinfo,
122 unsigned int hook_mask)
123{ 111{
124 const struct ipt_owner_info *info = matchinfo; 112 const struct ipt_owner_info *info = par->matchinfo;
125 113
126 if (info->match & (IPT_OWNER_PID | IPT_OWNER_SID | IPT_OWNER_COMM)) { 114 if (info->match & (IPT_OWNER_PID | IPT_OWNER_SID | IPT_OWNER_COMM)) {
127 printk(KERN_WARNING KBUILD_MODNAME 115 printk(KERN_WARNING KBUILD_MODNAME
@@ -133,12 +121,9 @@ owner_mt_check_v0(const char *tablename, const void *ip,
133 return true; 121 return true;
134} 122}
135 123
136static bool 124static bool owner_mt6_check_v0(const struct xt_mtchk_param *par)
137owner_mt6_check_v0(const char *tablename, const void *ip,
138 const struct xt_match *match, void *matchinfo,
139 unsigned int hook_mask)
140{ 125{
141 const struct ip6t_owner_info *info = matchinfo; 126 const struct ip6t_owner_info *info = par->matchinfo;
142 127
143 if (info->match & (IP6T_OWNER_PID | IP6T_OWNER_SID)) { 128 if (info->match & (IP6T_OWNER_PID | IP6T_OWNER_SID)) {
144 printk(KERN_WARNING KBUILD_MODNAME 129 printk(KERN_WARNING KBUILD_MODNAME
@@ -153,7 +138,7 @@ static struct xt_match owner_mt_reg[] __read_mostly = {
153 { 138 {
154 .name = "owner", 139 .name = "owner",
155 .revision = 0, 140 .revision = 0,
156 .family = AF_INET, 141 .family = NFPROTO_IPV4,
157 .match = owner_mt_v0, 142 .match = owner_mt_v0,
158 .matchsize = sizeof(struct ipt_owner_info), 143 .matchsize = sizeof(struct ipt_owner_info),
159 .checkentry = owner_mt_check_v0, 144 .checkentry = owner_mt_check_v0,
@@ -164,7 +149,7 @@ static struct xt_match owner_mt_reg[] __read_mostly = {
164 { 149 {
165 .name = "owner", 150 .name = "owner",
166 .revision = 0, 151 .revision = 0,
167 .family = AF_INET6, 152 .family = NFPROTO_IPV6,
168 .match = owner_mt6_v0, 153 .match = owner_mt6_v0,
169 .matchsize = sizeof(struct ip6t_owner_info), 154 .matchsize = sizeof(struct ip6t_owner_info),
170 .checkentry = owner_mt6_check_v0, 155 .checkentry = owner_mt6_check_v0,
@@ -175,17 +160,7 @@ static struct xt_match owner_mt_reg[] __read_mostly = {
175 { 160 {
176 .name = "owner", 161 .name = "owner",
177 .revision = 1, 162 .revision = 1,
178 .family = AF_INET, 163 .family = NFPROTO_UNSPEC,
179 .match = owner_mt,
180 .matchsize = sizeof(struct xt_owner_match_info),
181 .hooks = (1 << NF_INET_LOCAL_OUT) |
182 (1 << NF_INET_POST_ROUTING),
183 .me = THIS_MODULE,
184 },
185 {
186 .name = "owner",
187 .revision = 1,
188 .family = AF_INET6,
189 .match = owner_mt, 164 .match = owner_mt,
190 .matchsize = sizeof(struct xt_owner_match_info), 165 .matchsize = sizeof(struct xt_owner_match_info),
191 .hooks = (1 << NF_INET_LOCAL_OUT) | 166 .hooks = (1 << NF_INET_LOCAL_OUT) |
diff --git a/net/netfilter/xt_physdev.c b/net/netfilter/xt_physdev.c
index 4ec1094bda92..1bcdfc12cf59 100644
--- a/net/netfilter/xt_physdev.c
+++ b/net/netfilter/xt_physdev.c
@@ -21,14 +21,11 @@ MODULE_ALIAS("ipt_physdev");
21MODULE_ALIAS("ip6t_physdev"); 21MODULE_ALIAS("ip6t_physdev");
22 22
23static bool 23static bool
24physdev_mt(const struct sk_buff *skb, const struct net_device *in, 24physdev_mt(const struct sk_buff *skb, const struct xt_match_param *par)
25 const struct net_device *out, const struct xt_match *match,
26 const void *matchinfo, int offset, unsigned int protoff,
27 bool *hotdrop)
28{ 25{
29 int i; 26 int i;
30 static const char nulldevname[IFNAMSIZ]; 27 static const char nulldevname[IFNAMSIZ];
31 const struct xt_physdev_info *info = matchinfo; 28 const struct xt_physdev_info *info = par->matchinfo;
32 bool ret; 29 bool ret;
33 const char *indev, *outdev; 30 const char *indev, *outdev;
34 const struct nf_bridge_info *nf_bridge; 31 const struct nf_bridge_info *nf_bridge;
@@ -94,12 +91,9 @@ match_outdev:
94 return ret ^ !(info->invert & XT_PHYSDEV_OP_OUT); 91 return ret ^ !(info->invert & XT_PHYSDEV_OP_OUT);
95} 92}
96 93
97static bool 94static bool physdev_mt_check(const struct xt_mtchk_param *par)
98physdev_mt_check(const char *tablename, const void *ip,
99 const struct xt_match *match, void *matchinfo,
100 unsigned int hook_mask)
101{ 95{
102 const struct xt_physdev_info *info = matchinfo; 96 const struct xt_physdev_info *info = par->matchinfo;
103 97
104 if (!(info->bitmask & XT_PHYSDEV_OP_MASK) || 98 if (!(info->bitmask & XT_PHYSDEV_OP_MASK) ||
105 info->bitmask & ~XT_PHYSDEV_OP_MASK) 99 info->bitmask & ~XT_PHYSDEV_OP_MASK)
@@ -107,44 +101,35 @@ physdev_mt_check(const char *tablename, const void *ip,
107 if (info->bitmask & XT_PHYSDEV_OP_OUT && 101 if (info->bitmask & XT_PHYSDEV_OP_OUT &&
108 (!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) || 102 (!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) ||
109 info->invert & XT_PHYSDEV_OP_BRIDGED) && 103 info->invert & XT_PHYSDEV_OP_BRIDGED) &&
110 hook_mask & ((1 << NF_INET_LOCAL_OUT) | (1 << NF_INET_FORWARD) | 104 par->hook_mask & ((1 << NF_INET_LOCAL_OUT) |
111 (1 << NF_INET_POST_ROUTING))) { 105 (1 << NF_INET_FORWARD) | (1 << NF_INET_POST_ROUTING))) {
112 printk(KERN_WARNING "physdev match: using --physdev-out in the " 106 printk(KERN_WARNING "physdev match: using --physdev-out in the "
113 "OUTPUT, FORWARD and POSTROUTING chains for non-bridged " 107 "OUTPUT, FORWARD and POSTROUTING chains for non-bridged "
114 "traffic is not supported anymore.\n"); 108 "traffic is not supported anymore.\n");
115 if (hook_mask & (1 << NF_INET_LOCAL_OUT)) 109 if (par->hook_mask & (1 << NF_INET_LOCAL_OUT))
116 return false; 110 return false;
117 } 111 }
118 return true; 112 return true;
119} 113}
120 114
121static struct xt_match physdev_mt_reg[] __read_mostly = { 115static struct xt_match physdev_mt_reg __read_mostly = {
122 { 116 .name = "physdev",
123 .name = "physdev", 117 .revision = 0,
124 .family = AF_INET, 118 .family = NFPROTO_UNSPEC,
125 .checkentry = physdev_mt_check, 119 .checkentry = physdev_mt_check,
126 .match = physdev_mt, 120 .match = physdev_mt,
127 .matchsize = sizeof(struct xt_physdev_info), 121 .matchsize = sizeof(struct xt_physdev_info),
128 .me = THIS_MODULE, 122 .me = THIS_MODULE,
129 },
130 {
131 .name = "physdev",
132 .family = AF_INET6,
133 .checkentry = physdev_mt_check,
134 .match = physdev_mt,
135 .matchsize = sizeof(struct xt_physdev_info),
136 .me = THIS_MODULE,
137 },
138}; 123};
139 124
140static int __init physdev_mt_init(void) 125static int __init physdev_mt_init(void)
141{ 126{
142 return xt_register_matches(physdev_mt_reg, ARRAY_SIZE(physdev_mt_reg)); 127 return xt_register_match(&physdev_mt_reg);
143} 128}
144 129
145static void __exit physdev_mt_exit(void) 130static void __exit physdev_mt_exit(void)
146{ 131{
147 xt_unregister_matches(physdev_mt_reg, ARRAY_SIZE(physdev_mt_reg)); 132 xt_unregister_match(&physdev_mt_reg);
148} 133}
149 134
150module_init(physdev_mt_init); 135module_init(physdev_mt_init);
diff --git a/net/netfilter/xt_pkttype.c b/net/netfilter/xt_pkttype.c
index 7936f7e23254..69da1d3a1d85 100644
--- a/net/netfilter/xt_pkttype.c
+++ b/net/netfilter/xt_pkttype.c
@@ -23,20 +23,17 @@ MODULE_ALIAS("ipt_pkttype");
23MODULE_ALIAS("ip6t_pkttype"); 23MODULE_ALIAS("ip6t_pkttype");
24 24
25static bool 25static bool
26pkttype_mt(const struct sk_buff *skb, const struct net_device *in, 26pkttype_mt(const struct sk_buff *skb, const struct xt_match_param *par)
27 const struct net_device *out, const struct xt_match *match,
28 const void *matchinfo, int offset, unsigned int protoff,
29 bool *hotdrop)
30{ 27{
31 const struct xt_pkttype_info *info = matchinfo; 28 const struct xt_pkttype_info *info = par->matchinfo;
32 u_int8_t type; 29 u_int8_t type;
33 30
34 if (skb->pkt_type != PACKET_LOOPBACK) 31 if (skb->pkt_type != PACKET_LOOPBACK)
35 type = skb->pkt_type; 32 type = skb->pkt_type;
36 else if (match->family == AF_INET && 33 else if (par->family == NFPROTO_IPV4 &&
37 ipv4_is_multicast(ip_hdr(skb)->daddr)) 34 ipv4_is_multicast(ip_hdr(skb)->daddr))
38 type = PACKET_MULTICAST; 35 type = PACKET_MULTICAST;
39 else if (match->family == AF_INET6 && 36 else if (par->family == NFPROTO_IPV6 &&
40 ipv6_hdr(skb)->daddr.s6_addr[0] == 0xFF) 37 ipv6_hdr(skb)->daddr.s6_addr[0] == 0xFF)
41 type = PACKET_MULTICAST; 38 type = PACKET_MULTICAST;
42 else 39 else
@@ -45,31 +42,23 @@ pkttype_mt(const struct sk_buff *skb, const struct net_device *in,
45 return (type == info->pkttype) ^ info->invert; 42 return (type == info->pkttype) ^ info->invert;
46} 43}
47 44
48static struct xt_match pkttype_mt_reg[] __read_mostly = { 45static struct xt_match pkttype_mt_reg __read_mostly = {
49 { 46 .name = "pkttype",
50 .name = "pkttype", 47 .revision = 0,
51 .family = AF_INET, 48 .family = NFPROTO_UNSPEC,
52 .match = pkttype_mt, 49 .match = pkttype_mt,
53 .matchsize = sizeof(struct xt_pkttype_info), 50 .matchsize = sizeof(struct xt_pkttype_info),
54 .me = THIS_MODULE, 51 .me = THIS_MODULE,
55 },
56 {
57 .name = "pkttype",
58 .family = AF_INET6,
59 .match = pkttype_mt,
60 .matchsize = sizeof(struct xt_pkttype_info),
61 .me = THIS_MODULE,
62 },
63}; 52};
64 53
65static int __init pkttype_mt_init(void) 54static int __init pkttype_mt_init(void)
66{ 55{
67 return xt_register_matches(pkttype_mt_reg, ARRAY_SIZE(pkttype_mt_reg)); 56 return xt_register_match(&pkttype_mt_reg);
68} 57}
69 58
70static void __exit pkttype_mt_exit(void) 59static void __exit pkttype_mt_exit(void)
71{ 60{
72 xt_unregister_matches(pkttype_mt_reg, ARRAY_SIZE(pkttype_mt_reg)); 61 xt_unregister_match(&pkttype_mt_reg);
73} 62}
74 63
75module_init(pkttype_mt_init); 64module_init(pkttype_mt_init);
diff --git a/net/netfilter/xt_policy.c b/net/netfilter/xt_policy.c
index d351582b2a3d..328bd20ddd25 100644
--- a/net/netfilter/xt_policy.c
+++ b/net/netfilter/xt_policy.c
@@ -26,9 +26,9 @@ xt_addr_cmp(const union nf_inet_addr *a1, const union nf_inet_addr *m,
26 const union nf_inet_addr *a2, unsigned short family) 26 const union nf_inet_addr *a2, unsigned short family)
27{ 27{
28 switch (family) { 28 switch (family) {
29 case AF_INET: 29 case NFPROTO_IPV4:
30 return ((a1->ip ^ a2->ip) & m->ip) == 0; 30 return ((a1->ip ^ a2->ip) & m->ip) == 0;
31 case AF_INET6: 31 case NFPROTO_IPV6:
32 return ipv6_masked_addr_cmp(&a1->in6, &m->in6, &a2->in6) == 0; 32 return ipv6_masked_addr_cmp(&a1->in6, &m->in6, &a2->in6) == 0;
33 } 33 }
34 return false; 34 return false;
@@ -110,18 +110,15 @@ match_policy_out(const struct sk_buff *skb, const struct xt_policy_info *info,
110} 110}
111 111
112static bool 112static bool
113policy_mt(const struct sk_buff *skb, const struct net_device *in, 113policy_mt(const struct sk_buff *skb, const struct xt_match_param *par)
114 const struct net_device *out, const struct xt_match *match,
115 const void *matchinfo, int offset, unsigned int protoff,
116 bool *hotdrop)
117{ 114{
118 const struct xt_policy_info *info = matchinfo; 115 const struct xt_policy_info *info = par->matchinfo;
119 int ret; 116 int ret;
120 117
121 if (info->flags & XT_POLICY_MATCH_IN) 118 if (info->flags & XT_POLICY_MATCH_IN)
122 ret = match_policy_in(skb, info, match->family); 119 ret = match_policy_in(skb, info, par->match->family);
123 else 120 else
124 ret = match_policy_out(skb, info, match->family); 121 ret = match_policy_out(skb, info, par->match->family);
125 122
126 if (ret < 0) 123 if (ret < 0)
127 ret = info->flags & XT_POLICY_MATCH_NONE ? true : false; 124 ret = info->flags & XT_POLICY_MATCH_NONE ? true : false;
@@ -131,26 +128,23 @@ policy_mt(const struct sk_buff *skb, const struct net_device *in,
131 return ret; 128 return ret;
132} 129}
133 130
134static bool 131static bool policy_mt_check(const struct xt_mtchk_param *par)
135policy_mt_check(const char *tablename, const void *ip_void,
136 const struct xt_match *match, void *matchinfo,
137 unsigned int hook_mask)
138{ 132{
139 const struct xt_policy_info *info = matchinfo; 133 const struct xt_policy_info *info = par->matchinfo;
140 134
141 if (!(info->flags & (XT_POLICY_MATCH_IN|XT_POLICY_MATCH_OUT))) { 135 if (!(info->flags & (XT_POLICY_MATCH_IN|XT_POLICY_MATCH_OUT))) {
142 printk(KERN_ERR "xt_policy: neither incoming nor " 136 printk(KERN_ERR "xt_policy: neither incoming nor "
143 "outgoing policy selected\n"); 137 "outgoing policy selected\n");
144 return false; 138 return false;
145 } 139 }
146 if (hook_mask & (1 << NF_INET_PRE_ROUTING | 1 << NF_INET_LOCAL_IN) 140 if (par->hook_mask & ((1 << NF_INET_PRE_ROUTING) |
147 && info->flags & XT_POLICY_MATCH_OUT) { 141 (1 << NF_INET_LOCAL_IN)) && info->flags & XT_POLICY_MATCH_OUT) {
148 printk(KERN_ERR "xt_policy: output policy not valid in " 142 printk(KERN_ERR "xt_policy: output policy not valid in "
149 "PRE_ROUTING and INPUT\n"); 143 "PRE_ROUTING and INPUT\n");
150 return false; 144 return false;
151 } 145 }
152 if (hook_mask & (1 << NF_INET_POST_ROUTING | 1 << NF_INET_LOCAL_OUT) 146 if (par->hook_mask & ((1 << NF_INET_POST_ROUTING) |
153 && info->flags & XT_POLICY_MATCH_IN) { 147 (1 << NF_INET_LOCAL_OUT)) && info->flags & XT_POLICY_MATCH_IN) {
154 printk(KERN_ERR "xt_policy: input policy not valid in " 148 printk(KERN_ERR "xt_policy: input policy not valid in "
155 "POST_ROUTING and OUTPUT\n"); 149 "POST_ROUTING and OUTPUT\n");
156 return false; 150 return false;
@@ -165,7 +159,7 @@ policy_mt_check(const char *tablename, const void *ip_void,
165static struct xt_match policy_mt_reg[] __read_mostly = { 159static struct xt_match policy_mt_reg[] __read_mostly = {
166 { 160 {
167 .name = "policy", 161 .name = "policy",
168 .family = AF_INET, 162 .family = NFPROTO_IPV4,
169 .checkentry = policy_mt_check, 163 .checkentry = policy_mt_check,
170 .match = policy_mt, 164 .match = policy_mt,
171 .matchsize = sizeof(struct xt_policy_info), 165 .matchsize = sizeof(struct xt_policy_info),
@@ -173,7 +167,7 @@ static struct xt_match policy_mt_reg[] __read_mostly = {
173 }, 167 },
174 { 168 {
175 .name = "policy", 169 .name = "policy",
176 .family = AF_INET6, 170 .family = NFPROTO_IPV6,
177 .checkentry = policy_mt_check, 171 .checkentry = policy_mt_check,
178 .match = policy_mt, 172 .match = policy_mt,
179 .matchsize = sizeof(struct xt_policy_info), 173 .matchsize = sizeof(struct xt_policy_info),
diff --git a/net/netfilter/xt_quota.c b/net/netfilter/xt_quota.c
index 3b021d0c522a..c84fce5e0f3e 100644
--- a/net/netfilter/xt_quota.c
+++ b/net/netfilter/xt_quota.c
@@ -18,13 +18,10 @@ MODULE_ALIAS("ip6t_quota");
18static DEFINE_SPINLOCK(quota_lock); 18static DEFINE_SPINLOCK(quota_lock);
19 19
20static bool 20static bool
21quota_mt(const struct sk_buff *skb, const struct net_device *in, 21quota_mt(const struct sk_buff *skb, const struct xt_match_param *par)
22 const struct net_device *out, const struct xt_match *match,
23 const void *matchinfo, int offset, unsigned int protoff,
24 bool *hotdrop)
25{ 22{
26 struct xt_quota_info *q = 23 struct xt_quota_info *q =
27 ((const struct xt_quota_info *)matchinfo)->master; 24 ((const struct xt_quota_info *)par->matchinfo)->master;
28 bool ret = q->flags & XT_QUOTA_INVERT; 25 bool ret = q->flags & XT_QUOTA_INVERT;
29 26
30 spin_lock_bh(&quota_lock); 27 spin_lock_bh(&quota_lock);
@@ -40,12 +37,9 @@ quota_mt(const struct sk_buff *skb, const struct net_device *in,
40 return ret; 37 return ret;
41} 38}
42 39
43static bool 40static bool quota_mt_check(const struct xt_mtchk_param *par)
44quota_mt_check(const char *tablename, const void *entry,
45 const struct xt_match *match, void *matchinfo,
46 unsigned int hook_mask)
47{ 41{
48 struct xt_quota_info *q = matchinfo; 42 struct xt_quota_info *q = par->matchinfo;
49 43
50 if (q->flags & ~XT_QUOTA_MASK) 44 if (q->flags & ~XT_QUOTA_MASK)
51 return false; 45 return false;
@@ -54,33 +48,24 @@ quota_mt_check(const char *tablename, const void *entry,
54 return true; 48 return true;
55} 49}
56 50
57static struct xt_match quota_mt_reg[] __read_mostly = { 51static struct xt_match quota_mt_reg __read_mostly = {
58 { 52 .name = "quota",
59 .name = "quota", 53 .revision = 0,
60 .family = AF_INET, 54 .family = NFPROTO_UNSPEC,
61 .checkentry = quota_mt_check, 55 .match = quota_mt,
62 .match = quota_mt, 56 .checkentry = quota_mt_check,
63 .matchsize = sizeof(struct xt_quota_info), 57 .matchsize = sizeof(struct xt_quota_info),
64 .me = THIS_MODULE 58 .me = THIS_MODULE,
65 },
66 {
67 .name = "quota",
68 .family = AF_INET6,
69 .checkentry = quota_mt_check,
70 .match = quota_mt,
71 .matchsize = sizeof(struct xt_quota_info),
72 .me = THIS_MODULE
73 },
74}; 59};
75 60
76static int __init quota_mt_init(void) 61static int __init quota_mt_init(void)
77{ 62{
78 return xt_register_matches(quota_mt_reg, ARRAY_SIZE(quota_mt_reg)); 63 return xt_register_match(&quota_mt_reg);
79} 64}
80 65
81static void __exit quota_mt_exit(void) 66static void __exit quota_mt_exit(void)
82{ 67{
83 xt_unregister_matches(quota_mt_reg, ARRAY_SIZE(quota_mt_reg)); 68 xt_unregister_match(&quota_mt_reg);
84} 69}
85 70
86module_init(quota_mt_init); 71module_init(quota_mt_init);
diff --git a/net/netfilter/xt_rateest.c b/net/netfilter/xt_rateest.c
index ebd84f1b4f62..220a1d588ee0 100644
--- a/net/netfilter/xt_rateest.c
+++ b/net/netfilter/xt_rateest.c
@@ -14,16 +14,10 @@
14#include <net/netfilter/xt_rateest.h> 14#include <net/netfilter/xt_rateest.h>
15 15
16 16
17static bool xt_rateest_mt(const struct sk_buff *skb, 17static bool
18 const struct net_device *in, 18xt_rateest_mt(const struct sk_buff *skb, const struct xt_match_param *par)
19 const struct net_device *out,
20 const struct xt_match *match,
21 const void *matchinfo,
22 int offset,
23 unsigned int protoff,
24 bool *hotdrop)
25{ 19{
26 const struct xt_rateest_match_info *info = matchinfo; 20 const struct xt_rateest_match_info *info = par->matchinfo;
27 struct gnet_stats_rate_est *r; 21 struct gnet_stats_rate_est *r;
28 u_int32_t bps1, bps2, pps1, pps2; 22 u_int32_t bps1, bps2, pps1, pps2;
29 bool ret = true; 23 bool ret = true;
@@ -80,13 +74,9 @@ static bool xt_rateest_mt(const struct sk_buff *skb,
80 return ret; 74 return ret;
81} 75}
82 76
83static bool xt_rateest_mt_checkentry(const char *tablename, 77static bool xt_rateest_mt_checkentry(const struct xt_mtchk_param *par)
84 const void *ip,
85 const struct xt_match *match,
86 void *matchinfo,
87 unsigned int hook_mask)
88{ 78{
89 struct xt_rateest_match_info *info = matchinfo; 79 struct xt_rateest_match_info *info = par->matchinfo;
90 struct xt_rateest *est1, *est2; 80 struct xt_rateest *est1, *est2;
91 81
92 if (hweight32(info->flags & (XT_RATEEST_MATCH_ABS | 82 if (hweight32(info->flags & (XT_RATEEST_MATCH_ABS |
@@ -127,46 +117,34 @@ err1:
127 return false; 117 return false;
128} 118}
129 119
130static void xt_rateest_mt_destroy(const struct xt_match *match, 120static void xt_rateest_mt_destroy(const struct xt_mtdtor_param *par)
131 void *matchinfo)
132{ 121{
133 struct xt_rateest_match_info *info = matchinfo; 122 struct xt_rateest_match_info *info = par->matchinfo;
134 123
135 xt_rateest_put(info->est1); 124 xt_rateest_put(info->est1);
136 if (info->est2) 125 if (info->est2)
137 xt_rateest_put(info->est2); 126 xt_rateest_put(info->est2);
138} 127}
139 128
140static struct xt_match xt_rateest_match[] __read_mostly = { 129static struct xt_match xt_rateest_mt_reg __read_mostly = {
141 { 130 .name = "rateest",
142 .family = AF_INET, 131 .revision = 0,
143 .name = "rateest", 132 .family = NFPROTO_UNSPEC,
144 .match = xt_rateest_mt, 133 .match = xt_rateest_mt,
145 .checkentry = xt_rateest_mt_checkentry, 134 .checkentry = xt_rateest_mt_checkentry,
146 .destroy = xt_rateest_mt_destroy, 135 .destroy = xt_rateest_mt_destroy,
147 .matchsize = sizeof(struct xt_rateest_match_info), 136 .matchsize = sizeof(struct xt_rateest_match_info),
148 .me = THIS_MODULE, 137 .me = THIS_MODULE,
149 },
150 {
151 .family = AF_INET6,
152 .name = "rateest",
153 .match = xt_rateest_mt,
154 .checkentry = xt_rateest_mt_checkentry,
155 .destroy = xt_rateest_mt_destroy,
156 .matchsize = sizeof(struct xt_rateest_match_info),
157 .me = THIS_MODULE,
158 },
159}; 138};
160 139
161static int __init xt_rateest_mt_init(void) 140static int __init xt_rateest_mt_init(void)
162{ 141{
163 return xt_register_matches(xt_rateest_match, 142 return xt_register_match(&xt_rateest_mt_reg);
164 ARRAY_SIZE(xt_rateest_match));
165} 143}
166 144
167static void __exit xt_rateest_mt_fini(void) 145static void __exit xt_rateest_mt_fini(void)
168{ 146{
169 xt_unregister_matches(xt_rateest_match, ARRAY_SIZE(xt_rateest_match)); 147 xt_unregister_match(&xt_rateest_mt_reg);
170} 148}
171 149
172MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); 150MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
diff --git a/net/netfilter/xt_realm.c b/net/netfilter/xt_realm.c
index 7df1627c536f..67419287bc7e 100644
--- a/net/netfilter/xt_realm.c
+++ b/net/netfilter/xt_realm.c
@@ -22,12 +22,9 @@ MODULE_DESCRIPTION("Xtables: Routing realm match");
22MODULE_ALIAS("ipt_realm"); 22MODULE_ALIAS("ipt_realm");
23 23
24static bool 24static bool
25realm_mt(const struct sk_buff *skb, const struct net_device *in, 25realm_mt(const struct sk_buff *skb, const struct xt_match_param *par)
26 const struct net_device *out, const struct xt_match *match,
27 const void *matchinfo, int offset, unsigned int protoff,
28 bool *hotdrop)
29{ 26{
30 const struct xt_realm_info *info = matchinfo; 27 const struct xt_realm_info *info = par->matchinfo;
31 const struct dst_entry *dst = skb->dst; 28 const struct dst_entry *dst = skb->dst;
32 29
33 return (info->id == (dst->tclassid & info->mask)) ^ info->invert; 30 return (info->id == (dst->tclassid & info->mask)) ^ info->invert;
@@ -39,7 +36,7 @@ static struct xt_match realm_mt_reg __read_mostly = {
39 .matchsize = sizeof(struct xt_realm_info), 36 .matchsize = sizeof(struct xt_realm_info),
40 .hooks = (1 << NF_INET_POST_ROUTING) | (1 << NF_INET_FORWARD) | 37 .hooks = (1 << NF_INET_POST_ROUTING) | (1 << NF_INET_FORWARD) |
41 (1 << NF_INET_LOCAL_OUT) | (1 << NF_INET_LOCAL_IN), 38 (1 << NF_INET_LOCAL_OUT) | (1 << NF_INET_LOCAL_IN),
42 .family = AF_INET, 39 .family = NFPROTO_UNSPEC,
43 .me = THIS_MODULE 40 .me = THIS_MODULE
44}; 41};
45 42
diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/netfilter/xt_recent.c
index 3974d7cae5c0..4ebd4ca9a991 100644
--- a/net/ipv4/netfilter/ipt_recent.c
+++ b/net/netfilter/xt_recent.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright (c) 2006 Patrick McHardy <kaber@trash.net> 2 * Copyright (c) 2006 Patrick McHardy <kaber@trash.net>
3 * Copyright © CC Computer Consultants GmbH, 2007 - 2008
3 * 4 *
4 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as 6 * it under the terms of the GNU General Public License version 2 as
@@ -13,6 +14,8 @@
13 */ 14 */
14#include <linux/init.h> 15#include <linux/init.h>
15#include <linux/ip.h> 16#include <linux/ip.h>
17#include <linux/ipv6.h>
18#include <linux/module.h>
16#include <linux/moduleparam.h> 19#include <linux/moduleparam.h>
17#include <linux/proc_fs.h> 20#include <linux/proc_fs.h>
18#include <linux/seq_file.h> 21#include <linux/seq_file.h>
@@ -27,11 +30,14 @@
27#include <net/net_namespace.h> 30#include <net/net_namespace.h>
28 31
29#include <linux/netfilter/x_tables.h> 32#include <linux/netfilter/x_tables.h>
30#include <linux/netfilter_ipv4/ipt_recent.h> 33#include <linux/netfilter/xt_recent.h>
31 34
32MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>"); 35MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
36MODULE_AUTHOR("Jan Engelhardt <jengelh@computergmbh.de>");
33MODULE_DESCRIPTION("Xtables: \"recently-seen\" host matching for IPv4"); 37MODULE_DESCRIPTION("Xtables: \"recently-seen\" host matching for IPv4");
34MODULE_LICENSE("GPL"); 38MODULE_LICENSE("GPL");
39MODULE_ALIAS("ipt_recent");
40MODULE_ALIAS("ip6t_recent");
35 41
36static unsigned int ip_list_tot = 100; 42static unsigned int ip_list_tot = 100;
37static unsigned int ip_pkt_list_tot = 20; 43static unsigned int ip_pkt_list_tot = 20;
@@ -48,14 +54,15 @@ module_param(ip_list_gid, uint, 0400);
48MODULE_PARM_DESC(ip_list_tot, "number of IPs to remember per list"); 54MODULE_PARM_DESC(ip_list_tot, "number of IPs to remember per list");
49MODULE_PARM_DESC(ip_pkt_list_tot, "number of packets per IP to remember (max. 255)"); 55MODULE_PARM_DESC(ip_pkt_list_tot, "number of packets per IP to remember (max. 255)");
50MODULE_PARM_DESC(ip_list_hash_size, "size of hash table used to look up IPs"); 56MODULE_PARM_DESC(ip_list_hash_size, "size of hash table used to look up IPs");
51MODULE_PARM_DESC(ip_list_perms, "permissions on /proc/net/ipt_recent/* files"); 57MODULE_PARM_DESC(ip_list_perms, "permissions on /proc/net/xt_recent/* files");
52MODULE_PARM_DESC(ip_list_uid,"owner of /proc/net/ipt_recent/* files"); 58MODULE_PARM_DESC(ip_list_uid,"owner of /proc/net/xt_recent/* files");
53MODULE_PARM_DESC(ip_list_gid,"owning group of /proc/net/ipt_recent/* files"); 59MODULE_PARM_DESC(ip_list_gid,"owning group of /proc/net/xt_recent/* files");
54 60
55struct recent_entry { 61struct recent_entry {
56 struct list_head list; 62 struct list_head list;
57 struct list_head lru_list; 63 struct list_head lru_list;
58 __be32 addr; 64 union nf_inet_addr addr;
65 u_int16_t family;
59 u_int8_t ttl; 66 u_int8_t ttl;
60 u_int8_t index; 67 u_int8_t index;
61 u_int16_t nstamps; 68 u_int16_t nstamps;
@@ -64,9 +71,9 @@ struct recent_entry {
64 71
65struct recent_table { 72struct recent_table {
66 struct list_head list; 73 struct list_head list;
67 char name[IPT_RECENT_NAME_LEN]; 74 char name[XT_RECENT_NAME_LEN];
68#ifdef CONFIG_PROC_FS 75#ifdef CONFIG_PROC_FS
69 struct proc_dir_entry *proc; 76 struct proc_dir_entry *proc_old, *proc;
70#endif 77#endif
71 unsigned int refcnt; 78 unsigned int refcnt;
72 unsigned int entries; 79 unsigned int entries;
@@ -79,31 +86,53 @@ static DEFINE_SPINLOCK(recent_lock);
79static DEFINE_MUTEX(recent_mutex); 86static DEFINE_MUTEX(recent_mutex);
80 87
81#ifdef CONFIG_PROC_FS 88#ifdef CONFIG_PROC_FS
82static struct proc_dir_entry *proc_dir; 89#ifdef CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT
83static const struct file_operations recent_fops; 90static struct proc_dir_entry *proc_old_dir;
91#endif
92static struct proc_dir_entry *recent_proc_dir;
93static const struct file_operations recent_old_fops, recent_mt_fops;
84#endif 94#endif
85 95
86static u_int32_t hash_rnd; 96static u_int32_t hash_rnd;
87static int hash_rnd_initted; 97static bool hash_rnd_initted;
98
99static unsigned int recent_entry_hash4(const union nf_inet_addr *addr)
100{
101 if (!hash_rnd_initted) {
102 get_random_bytes(&hash_rnd, sizeof(hash_rnd));
103 hash_rnd_initted = true;
104 }
105 return jhash_1word((__force u32)addr->ip, hash_rnd) &
106 (ip_list_hash_size - 1);
107}
88 108
89static unsigned int recent_entry_hash(__be32 addr) 109static unsigned int recent_entry_hash6(const union nf_inet_addr *addr)
90{ 110{
91 if (!hash_rnd_initted) { 111 if (!hash_rnd_initted) {
92 get_random_bytes(&hash_rnd, 4); 112 get_random_bytes(&hash_rnd, sizeof(hash_rnd));
93 hash_rnd_initted = 1; 113 hash_rnd_initted = true;
94 } 114 }
95 return jhash_1word((__force u32)addr, hash_rnd) & (ip_list_hash_size - 1); 115 return jhash2((u32 *)addr->ip6, ARRAY_SIZE(addr->ip6), hash_rnd) &
116 (ip_list_hash_size - 1);
96} 117}
97 118
98static struct recent_entry * 119static struct recent_entry *
99recent_entry_lookup(const struct recent_table *table, __be32 addr, u_int8_t ttl) 120recent_entry_lookup(const struct recent_table *table,
121 const union nf_inet_addr *addrp, u_int16_t family,
122 u_int8_t ttl)
100{ 123{
101 struct recent_entry *e; 124 struct recent_entry *e;
102 unsigned int h; 125 unsigned int h;
103 126
104 h = recent_entry_hash(addr); 127 if (family == NFPROTO_IPV4)
128 h = recent_entry_hash4(addrp);
129 else
130 h = recent_entry_hash6(addrp);
131
105 list_for_each_entry(e, &table->iphash[h], list) 132 list_for_each_entry(e, &table->iphash[h], list)
106 if (e->addr == addr && (ttl == e->ttl || !ttl || !e->ttl)) 133 if (e->family == family &&
134 memcmp(&e->addr, addrp, sizeof(e->addr)) == 0 &&
135 (ttl == e->ttl || ttl == 0 || e->ttl == 0))
107 return e; 136 return e;
108 return NULL; 137 return NULL;
109} 138}
@@ -117,7 +146,8 @@ static void recent_entry_remove(struct recent_table *t, struct recent_entry *e)
117} 146}
118 147
119static struct recent_entry * 148static struct recent_entry *
120recent_entry_init(struct recent_table *t, __be32 addr, u_int8_t ttl) 149recent_entry_init(struct recent_table *t, const union nf_inet_addr *addr,
150 u_int16_t family, u_int8_t ttl)
121{ 151{
122 struct recent_entry *e; 152 struct recent_entry *e;
123 153
@@ -129,12 +159,16 @@ recent_entry_init(struct recent_table *t, __be32 addr, u_int8_t ttl)
129 GFP_ATOMIC); 159 GFP_ATOMIC);
130 if (e == NULL) 160 if (e == NULL)
131 return NULL; 161 return NULL;
132 e->addr = addr; 162 memcpy(&e->addr, addr, sizeof(e->addr));
133 e->ttl = ttl; 163 e->ttl = ttl;
134 e->stamps[0] = jiffies; 164 e->stamps[0] = jiffies;
135 e->nstamps = 1; 165 e->nstamps = 1;
136 e->index = 1; 166 e->index = 1;
137 list_add_tail(&e->list, &t->iphash[recent_entry_hash(addr)]); 167 e->family = family;
168 if (family == NFPROTO_IPV4)
169 list_add_tail(&e->list, &t->iphash[recent_entry_hash4(addr)]);
170 else
171 list_add_tail(&e->list, &t->iphash[recent_entry_hash6(addr)]);
138 list_add_tail(&e->lru_list, &t->lru_list); 172 list_add_tail(&e->lru_list, &t->lru_list);
139 t->entries++; 173 t->entries++;
140 return e; 174 return e;
@@ -170,48 +204,59 @@ static void recent_table_flush(struct recent_table *t)
170} 204}
171 205
172static bool 206static bool
173recent_mt(const struct sk_buff *skb, const struct net_device *in, 207recent_mt(const struct sk_buff *skb, const struct xt_match_param *par)
174 const struct net_device *out, const struct xt_match *match,
175 const void *matchinfo, int offset, unsigned int protoff,
176 bool *hotdrop)
177{ 208{
178 const struct ipt_recent_info *info = matchinfo; 209 const struct xt_recent_mtinfo *info = par->matchinfo;
179 struct recent_table *t; 210 struct recent_table *t;
180 struct recent_entry *e; 211 struct recent_entry *e;
181 __be32 addr; 212 union nf_inet_addr addr = {};
182 u_int8_t ttl; 213 u_int8_t ttl;
183 bool ret = info->invert; 214 bool ret = info->invert;
184 215
185 if (info->side == IPT_RECENT_DEST) 216 if (par->match->family == NFPROTO_IPV4) {
186 addr = ip_hdr(skb)->daddr; 217 const struct iphdr *iph = ip_hdr(skb);
187 else 218
188 addr = ip_hdr(skb)->saddr; 219 if (info->side == XT_RECENT_DEST)
220 addr.ip = iph->daddr;
221 else
222 addr.ip = iph->saddr;
223
224 ttl = iph->ttl;
225 } else {
226 const struct ipv6hdr *iph = ipv6_hdr(skb);
227
228 if (info->side == XT_RECENT_DEST)
229 memcpy(&addr.in6, &iph->daddr, sizeof(addr.in6));
230 else
231 memcpy(&addr.in6, &iph->saddr, sizeof(addr.in6));
232
233 ttl = iph->hop_limit;
234 }
189 235
190 ttl = ip_hdr(skb)->ttl;
191 /* use TTL as seen before forwarding */ 236 /* use TTL as seen before forwarding */
192 if (out && !skb->sk) 237 if (par->out != NULL && skb->sk == NULL)
193 ttl++; 238 ttl++;
194 239
195 spin_lock_bh(&recent_lock); 240 spin_lock_bh(&recent_lock);
196 t = recent_table_lookup(info->name); 241 t = recent_table_lookup(info->name);
197 e = recent_entry_lookup(t, addr, 242 e = recent_entry_lookup(t, &addr, par->match->family,
198 info->check_set & IPT_RECENT_TTL ? ttl : 0); 243 (info->check_set & XT_RECENT_TTL) ? ttl : 0);
199 if (e == NULL) { 244 if (e == NULL) {
200 if (!(info->check_set & IPT_RECENT_SET)) 245 if (!(info->check_set & XT_RECENT_SET))
201 goto out; 246 goto out;
202 e = recent_entry_init(t, addr, ttl); 247 e = recent_entry_init(t, &addr, par->match->family, ttl);
203 if (e == NULL) 248 if (e == NULL)
204 *hotdrop = true; 249 *par->hotdrop = true;
205 ret = !ret; 250 ret = !ret;
206 goto out; 251 goto out;
207 } 252 }
208 253
209 if (info->check_set & IPT_RECENT_SET) 254 if (info->check_set & XT_RECENT_SET)
210 ret = !ret; 255 ret = !ret;
211 else if (info->check_set & IPT_RECENT_REMOVE) { 256 else if (info->check_set & XT_RECENT_REMOVE) {
212 recent_entry_remove(t, e); 257 recent_entry_remove(t, e);
213 ret = !ret; 258 ret = !ret;
214 } else if (info->check_set & (IPT_RECENT_CHECK | IPT_RECENT_UPDATE)) { 259 } else if (info->check_set & (XT_RECENT_CHECK | XT_RECENT_UPDATE)) {
215 unsigned long time = jiffies - info->seconds * HZ; 260 unsigned long time = jiffies - info->seconds * HZ;
216 unsigned int i, hits = 0; 261 unsigned int i, hits = 0;
217 262
@@ -225,8 +270,8 @@ recent_mt(const struct sk_buff *skb, const struct net_device *in,
225 } 270 }
226 } 271 }
227 272
228 if (info->check_set & IPT_RECENT_SET || 273 if (info->check_set & XT_RECENT_SET ||
229 (info->check_set & IPT_RECENT_UPDATE && ret)) { 274 (info->check_set & XT_RECENT_UPDATE && ret)) {
230 recent_entry_update(t, e); 275 recent_entry_update(t, e);
231 e->ttl = ttl; 276 e->ttl = ttl;
232 } 277 }
@@ -235,27 +280,24 @@ out:
235 return ret; 280 return ret;
236} 281}
237 282
238static bool 283static bool recent_mt_check(const struct xt_mtchk_param *par)
239recent_mt_check(const char *tablename, const void *ip,
240 const struct xt_match *match, void *matchinfo,
241 unsigned int hook_mask)
242{ 284{
243 const struct ipt_recent_info *info = matchinfo; 285 const struct xt_recent_mtinfo *info = par->matchinfo;
244 struct recent_table *t; 286 struct recent_table *t;
245 unsigned i; 287 unsigned i;
246 bool ret = false; 288 bool ret = false;
247 289
248 if (hweight8(info->check_set & 290 if (hweight8(info->check_set &
249 (IPT_RECENT_SET | IPT_RECENT_REMOVE | 291 (XT_RECENT_SET | XT_RECENT_REMOVE |
250 IPT_RECENT_CHECK | IPT_RECENT_UPDATE)) != 1) 292 XT_RECENT_CHECK | XT_RECENT_UPDATE)) != 1)
251 return false; 293 return false;
252 if ((info->check_set & (IPT_RECENT_SET | IPT_RECENT_REMOVE)) && 294 if ((info->check_set & (XT_RECENT_SET | XT_RECENT_REMOVE)) &&
253 (info->seconds || info->hit_count)) 295 (info->seconds || info->hit_count))
254 return false; 296 return false;
255 if (info->hit_count > ip_pkt_list_tot) 297 if (info->hit_count > ip_pkt_list_tot)
256 return false; 298 return false;
257 if (info->name[0] == '\0' || 299 if (info->name[0] == '\0' ||
258 strnlen(info->name, IPT_RECENT_NAME_LEN) == IPT_RECENT_NAME_LEN) 300 strnlen(info->name, XT_RECENT_NAME_LEN) == XT_RECENT_NAME_LEN)
259 return false; 301 return false;
260 302
261 mutex_lock(&recent_mutex); 303 mutex_lock(&recent_mutex);
@@ -276,11 +318,24 @@ recent_mt_check(const char *tablename, const void *ip,
276 for (i = 0; i < ip_list_hash_size; i++) 318 for (i = 0; i < ip_list_hash_size; i++)
277 INIT_LIST_HEAD(&t->iphash[i]); 319 INIT_LIST_HEAD(&t->iphash[i]);
278#ifdef CONFIG_PROC_FS 320#ifdef CONFIG_PROC_FS
279 t->proc = proc_create(t->name, ip_list_perms, proc_dir, &recent_fops); 321 t->proc = proc_create(t->name, ip_list_perms, recent_proc_dir,
322 &recent_mt_fops);
280 if (t->proc == NULL) { 323 if (t->proc == NULL) {
281 kfree(t); 324 kfree(t);
282 goto out; 325 goto out;
283 } 326 }
327#ifdef CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT
328 t->proc_old = proc_create(t->name, ip_list_perms, proc_old_dir,
329 &recent_old_fops);
330 if (t->proc_old == NULL) {
331 remove_proc_entry(t->name, proc_old_dir);
332 kfree(t);
333 goto out;
334 }
335 t->proc_old->uid = ip_list_uid;
336 t->proc_old->gid = ip_list_gid;
337 t->proc_old->data = t;
338#endif
284 t->proc->uid = ip_list_uid; 339 t->proc->uid = ip_list_uid;
285 t->proc->gid = ip_list_gid; 340 t->proc->gid = ip_list_gid;
286 t->proc->data = t; 341 t->proc->data = t;
@@ -294,9 +349,9 @@ out:
294 return ret; 349 return ret;
295} 350}
296 351
297static void recent_mt_destroy(const struct xt_match *match, void *matchinfo) 352static void recent_mt_destroy(const struct xt_mtdtor_param *par)
298{ 353{
299 const struct ipt_recent_info *info = matchinfo; 354 const struct xt_recent_mtinfo *info = par->matchinfo;
300 struct recent_table *t; 355 struct recent_table *t;
301 356
302 mutex_lock(&recent_mutex); 357 mutex_lock(&recent_mutex);
@@ -306,7 +361,10 @@ static void recent_mt_destroy(const struct xt_match *match, void *matchinfo)
306 list_del(&t->list); 361 list_del(&t->list);
307 spin_unlock_bh(&recent_lock); 362 spin_unlock_bh(&recent_lock);
308#ifdef CONFIG_PROC_FS 363#ifdef CONFIG_PROC_FS
309 remove_proc_entry(t->name, proc_dir); 364#ifdef CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT
365 remove_proc_entry(t->name, proc_old_dir);
366#endif
367 remove_proc_entry(t->name, recent_proc_dir);
310#endif 368#endif
311 recent_table_flush(t); 369 recent_table_flush(t);
312 kfree(t); 370 kfree(t);
@@ -316,7 +374,7 @@ static void recent_mt_destroy(const struct xt_match *match, void *matchinfo)
316 374
317#ifdef CONFIG_PROC_FS 375#ifdef CONFIG_PROC_FS
318struct recent_iter_state { 376struct recent_iter_state {
319 struct recent_table *table; 377 const struct recent_table *table;
320 unsigned int bucket; 378 unsigned int bucket;
321}; 379};
322 380
@@ -341,8 +399,8 @@ static void *recent_seq_next(struct seq_file *seq, void *v, loff_t *pos)
341{ 399{
342 struct recent_iter_state *st = seq->private; 400 struct recent_iter_state *st = seq->private;
343 const struct recent_table *t = st->table; 401 const struct recent_table *t = st->table;
344 struct recent_entry *e = v; 402 const struct recent_entry *e = v;
345 struct list_head *head = e->list.next; 403 const struct list_head *head = e->list.next;
346 404
347 while (head == &t->iphash[st->bucket]) { 405 while (head == &t->iphash[st->bucket]) {
348 if (++st->bucket >= ip_list_hash_size) 406 if (++st->bucket >= ip_list_hash_size)
@@ -365,8 +423,14 @@ static int recent_seq_show(struct seq_file *seq, void *v)
365 unsigned int i; 423 unsigned int i;
366 424
367 i = (e->index - 1) % ip_pkt_list_tot; 425 i = (e->index - 1) % ip_pkt_list_tot;
368 seq_printf(seq, "src=%u.%u.%u.%u ttl: %u last_seen: %lu oldest_pkt: %u", 426 if (e->family == NFPROTO_IPV4)
369 NIPQUAD(e->addr), e->ttl, e->stamps[i], e->index); 427 seq_printf(seq, "src=" NIPQUAD_FMT " ttl: %u last_seen: %lu "
428 "oldest_pkt: %u", NIPQUAD(e->addr.ip), e->ttl,
429 e->stamps[i], e->index);
430 else
431 seq_printf(seq, "src=" NIP6_FMT " ttl: %u last_seen: %lu "
432 "oldest_pkt: %u", NIP6(e->addr.in6), e->ttl,
433 e->stamps[i], e->index);
370 for (i = 0; i < e->nstamps; i++) 434 for (i = 0; i < e->nstamps; i++)
371 seq_printf(seq, "%s %lu", i ? "," : "", e->stamps[i]); 435 seq_printf(seq, "%s %lu", i ? "," : "", e->stamps[i]);
372 seq_printf(seq, "\n"); 436 seq_printf(seq, "\n");
@@ -393,8 +457,22 @@ static int recent_seq_open(struct inode *inode, struct file *file)
393 return 0; 457 return 0;
394} 458}
395 459
396static ssize_t recent_proc_write(struct file *file, const char __user *input, 460#ifdef CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT
397 size_t size, loff_t *loff) 461static int recent_old_seq_open(struct inode *inode, struct file *filp)
462{
463 static bool warned_of_old;
464
465 if (unlikely(!warned_of_old)) {
466 printk(KERN_INFO KBUILD_MODNAME ": Use of /proc/net/ipt_recent"
467 " is deprecated; use /proc/net/xt_recent.\n");
468 warned_of_old = true;
469 }
470 return recent_seq_open(inode, filp);
471}
472
473static ssize_t recent_old_proc_write(struct file *file,
474 const char __user *input,
475 size_t size, loff_t *loff)
398{ 476{
399 const struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode); 477 const struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode);
400 struct recent_table *t = pde->data; 478 struct recent_table *t = pde->data;
@@ -407,6 +485,7 @@ static ssize_t recent_proc_write(struct file *file, const char __user *input,
407 size = sizeof(buf); 485 size = sizeof(buf);
408 if (copy_from_user(buf, input, size)) 486 if (copy_from_user(buf, input, size))
409 return -EFAULT; 487 return -EFAULT;
488
410 while (isspace(*c)) 489 while (isspace(*c))
411 c++; 490 c++;
412 491
@@ -434,10 +513,11 @@ static ssize_t recent_proc_write(struct file *file, const char __user *input,
434 addr = in_aton(c); 513 addr = in_aton(c);
435 514
436 spin_lock_bh(&recent_lock); 515 spin_lock_bh(&recent_lock);
437 e = recent_entry_lookup(t, addr, 0); 516 e = recent_entry_lookup(t, (const void *)&addr, NFPROTO_IPV4, 0);
438 if (e == NULL) { 517 if (e == NULL) {
439 if (add) 518 if (add)
440 recent_entry_init(t, addr, 0); 519 recent_entry_init(t, (const void *)&addr,
520 NFPROTO_IPV4, 0);
441 } else { 521 } else {
442 if (add) 522 if (add)
443 recent_entry_update(t, e); 523 recent_entry_update(t, e);
@@ -448,23 +528,118 @@ static ssize_t recent_proc_write(struct file *file, const char __user *input,
448 return size; 528 return size;
449} 529}
450 530
451static const struct file_operations recent_fops = { 531static const struct file_operations recent_old_fops = {
452 .open = recent_seq_open, 532 .open = recent_old_seq_open,
453 .read = seq_read, 533 .read = seq_read,
454 .write = recent_proc_write, 534 .write = recent_old_proc_write,
455 .release = seq_release_private, 535 .release = seq_release_private,
456 .owner = THIS_MODULE, 536 .owner = THIS_MODULE,
457}; 537};
538#endif
539
540static ssize_t
541recent_mt_proc_write(struct file *file, const char __user *input,
542 size_t size, loff_t *loff)
543{
544 const struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode);
545 struct recent_table *t = pde->data;
546 struct recent_entry *e;
547 char buf[sizeof("+b335:1d35:1e55:dead:c0de:1715:5afe:c0de")];
548 const char *c = buf;
549 union nf_inet_addr addr;
550 u_int16_t family;
551 bool add, succ;
552
553 if (size == 0)
554 return 0;
555 if (size > sizeof(buf))
556 size = sizeof(buf);
557 if (copy_from_user(buf, input, size) != 0)
558 return -EFAULT;
559
560 /* Strict protocol! */
561 if (*loff != 0)
562 return -ESPIPE;
563 switch (*c) {
564 case '/': /* flush table */
565 spin_lock_bh(&recent_lock);
566 recent_table_flush(t);
567 spin_unlock_bh(&recent_lock);
568 return size;
569 case '-': /* remove address */
570 add = false;
571 break;
572 case '+': /* add address */
573 add = true;
574 break;
575 default:
576 printk(KERN_INFO KBUILD_MODNAME ": Need +ip, -ip or /\n");
577 return -EINVAL;
578 }
579
580 ++c;
581 --size;
582 if (strnchr(c, size, ':') != NULL) {
583 family = NFPROTO_IPV6;
584 succ = in6_pton(c, size, (void *)&addr, '\n', NULL);
585 } else {
586 family = NFPROTO_IPV4;
587 succ = in4_pton(c, size, (void *)&addr, '\n', NULL);
588 }
589
590 if (!succ) {
591 printk(KERN_INFO KBUILD_MODNAME ": illegal address written "
592 "to procfs\n");
593 return -EINVAL;
594 }
595
596 spin_lock_bh(&recent_lock);
597 e = recent_entry_lookup(t, &addr, family, 0);
598 if (e == NULL) {
599 if (add)
600 recent_entry_init(t, &addr, family, 0);
601 } else {
602 if (add)
603 recent_entry_update(t, e);
604 else
605 recent_entry_remove(t, e);
606 }
607 spin_unlock_bh(&recent_lock);
608 /* Note we removed one above */
609 *loff += size + 1;
610 return size + 1;
611}
612
613static const struct file_operations recent_mt_fops = {
614 .open = recent_seq_open,
615 .read = seq_read,
616 .write = recent_mt_proc_write,
617 .release = seq_release_private,
618 .owner = THIS_MODULE,
619};
458#endif /* CONFIG_PROC_FS */ 620#endif /* CONFIG_PROC_FS */
459 621
460static struct xt_match recent_mt_reg __read_mostly = { 622static struct xt_match recent_mt_reg[] __read_mostly = {
461 .name = "recent", 623 {
462 .family = AF_INET, 624 .name = "recent",
463 .match = recent_mt, 625 .revision = 0,
464 .matchsize = sizeof(struct ipt_recent_info), 626 .family = NFPROTO_IPV4,
465 .checkentry = recent_mt_check, 627 .match = recent_mt,
466 .destroy = recent_mt_destroy, 628 .matchsize = sizeof(struct xt_recent_mtinfo),
467 .me = THIS_MODULE, 629 .checkentry = recent_mt_check,
630 .destroy = recent_mt_destroy,
631 .me = THIS_MODULE,
632 },
633 {
634 .name = "recent",
635 .revision = 0,
636 .family = NFPROTO_IPV6,
637 .match = recent_mt,
638 .matchsize = sizeof(struct xt_recent_mtinfo),
639 .checkentry = recent_mt_check,
640 .destroy = recent_mt_destroy,
641 .me = THIS_MODULE,
642 },
468}; 643};
469 644
470static int __init recent_mt_init(void) 645static int __init recent_mt_init(void)
@@ -475,26 +650,39 @@ static int __init recent_mt_init(void)
475 return -EINVAL; 650 return -EINVAL;
476 ip_list_hash_size = 1 << fls(ip_list_tot); 651 ip_list_hash_size = 1 << fls(ip_list_tot);
477 652
478 err = xt_register_match(&recent_mt_reg); 653 err = xt_register_matches(recent_mt_reg, ARRAY_SIZE(recent_mt_reg));
479#ifdef CONFIG_PROC_FS 654#ifdef CONFIG_PROC_FS
480 if (err) 655 if (err)
481 return err; 656 return err;
482 proc_dir = proc_mkdir("ipt_recent", init_net.proc_net); 657 recent_proc_dir = proc_mkdir("xt_recent", init_net.proc_net);
483 if (proc_dir == NULL) { 658 if (recent_proc_dir == NULL) {
484 xt_unregister_match(&recent_mt_reg); 659 xt_unregister_matches(recent_mt_reg, ARRAY_SIZE(recent_mt_reg));
660 err = -ENOMEM;
661 }
662#ifdef CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT
663 if (err < 0)
664 return err;
665 proc_old_dir = proc_mkdir("ipt_recent", init_net.proc_net);
666 if (proc_old_dir == NULL) {
667 remove_proc_entry("xt_recent", init_net.proc_net);
668 xt_unregister_matches(recent_mt_reg, ARRAY_SIZE(recent_mt_reg));
485 err = -ENOMEM; 669 err = -ENOMEM;
486 } 670 }
487#endif 671#endif
672#endif
488 return err; 673 return err;
489} 674}
490 675
491static void __exit recent_mt_exit(void) 676static void __exit recent_mt_exit(void)
492{ 677{
493 BUG_ON(!list_empty(&tables)); 678 BUG_ON(!list_empty(&tables));
494 xt_unregister_match(&recent_mt_reg); 679 xt_unregister_matches(recent_mt_reg, ARRAY_SIZE(recent_mt_reg));
495#ifdef CONFIG_PROC_FS 680#ifdef CONFIG_PROC_FS
681#ifdef CONFIG_NETFILTER_XT_MATCH_RECENT_PROC_COMPAT
496 remove_proc_entry("ipt_recent", init_net.proc_net); 682 remove_proc_entry("ipt_recent", init_net.proc_net);
497#endif 683#endif
684 remove_proc_entry("xt_recent", init_net.proc_net);
685#endif
498} 686}
499 687
500module_init(recent_mt_init); 688module_init(recent_mt_init);
diff --git a/net/netfilter/xt_sctp.c b/net/netfilter/xt_sctp.c
index e6e4681fa047..e223cb43ae8e 100644
--- a/net/netfilter/xt_sctp.c
+++ b/net/netfilter/xt_sctp.c
@@ -117,23 +117,21 @@ match_packet(const struct sk_buff *skb,
117} 117}
118 118
119static bool 119static bool
120sctp_mt(const struct sk_buff *skb, const struct net_device *in, 120sctp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
121 const struct net_device *out, const struct xt_match *match,
122 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
123{ 121{
124 const struct xt_sctp_info *info = matchinfo; 122 const struct xt_sctp_info *info = par->matchinfo;
125 const sctp_sctphdr_t *sh; 123 const sctp_sctphdr_t *sh;
126 sctp_sctphdr_t _sh; 124 sctp_sctphdr_t _sh;
127 125
128 if (offset) { 126 if (par->fragoff != 0) {
129 duprintf("Dropping non-first fragment.. FIXME\n"); 127 duprintf("Dropping non-first fragment.. FIXME\n");
130 return false; 128 return false;
131 } 129 }
132 130
133 sh = skb_header_pointer(skb, protoff, sizeof(_sh), &_sh); 131 sh = skb_header_pointer(skb, par->thoff, sizeof(_sh), &_sh);
134 if (sh == NULL) { 132 if (sh == NULL) {
135 duprintf("Dropping evil TCP offset=0 tinygram.\n"); 133 duprintf("Dropping evil TCP offset=0 tinygram.\n");
136 *hotdrop = true; 134 *par->hotdrop = true;
137 return false; 135 return false;
138 } 136 }
139 duprintf("spt: %d\tdpt: %d\n", ntohs(sh->source), ntohs(sh->dest)); 137 duprintf("spt: %d\tdpt: %d\n", ntohs(sh->source), ntohs(sh->dest));
@@ -144,17 +142,14 @@ sctp_mt(const struct sk_buff *skb, const struct net_device *in,
144 && SCCHECK(ntohs(sh->dest) >= info->dpts[0] 142 && SCCHECK(ntohs(sh->dest) >= info->dpts[0]
145 && ntohs(sh->dest) <= info->dpts[1], 143 && ntohs(sh->dest) <= info->dpts[1],
146 XT_SCTP_DEST_PORTS, info->flags, info->invflags) 144 XT_SCTP_DEST_PORTS, info->flags, info->invflags)
147 && SCCHECK(match_packet(skb, protoff + sizeof (sctp_sctphdr_t), 145 && SCCHECK(match_packet(skb, par->thoff + sizeof(sctp_sctphdr_t),
148 info, hotdrop), 146 info, par->hotdrop),
149 XT_SCTP_CHUNK_TYPES, info->flags, info->invflags); 147 XT_SCTP_CHUNK_TYPES, info->flags, info->invflags);
150} 148}
151 149
152static bool 150static bool sctp_mt_check(const struct xt_mtchk_param *par)
153sctp_mt_check(const char *tablename, const void *inf,
154 const struct xt_match *match, void *matchinfo,
155 unsigned int hook_mask)
156{ 151{
157 const struct xt_sctp_info *info = matchinfo; 152 const struct xt_sctp_info *info = par->matchinfo;
158 153
159 return !(info->flags & ~XT_SCTP_VALID_FLAGS) 154 return !(info->flags & ~XT_SCTP_VALID_FLAGS)
160 && !(info->invflags & ~XT_SCTP_VALID_FLAGS) 155 && !(info->invflags & ~XT_SCTP_VALID_FLAGS)
@@ -169,7 +164,7 @@ sctp_mt_check(const char *tablename, const void *inf,
169static struct xt_match sctp_mt_reg[] __read_mostly = { 164static struct xt_match sctp_mt_reg[] __read_mostly = {
170 { 165 {
171 .name = "sctp", 166 .name = "sctp",
172 .family = AF_INET, 167 .family = NFPROTO_IPV4,
173 .checkentry = sctp_mt_check, 168 .checkentry = sctp_mt_check,
174 .match = sctp_mt, 169 .match = sctp_mt,
175 .matchsize = sizeof(struct xt_sctp_info), 170 .matchsize = sizeof(struct xt_sctp_info),
@@ -178,7 +173,7 @@ static struct xt_match sctp_mt_reg[] __read_mostly = {
178 }, 173 },
179 { 174 {
180 .name = "sctp", 175 .name = "sctp",
181 .family = AF_INET6, 176 .family = NFPROTO_IPV6,
182 .checkentry = sctp_mt_check, 177 .checkentry = sctp_mt_check,
183 .match = sctp_mt, 178 .match = sctp_mt,
184 .matchsize = sizeof(struct xt_sctp_info), 179 .matchsize = sizeof(struct xt_sctp_info),
diff --git a/net/netfilter/xt_socket.c b/net/netfilter/xt_socket.c
new file mode 100644
index 000000000000..02a8fed21082
--- /dev/null
+++ b/net/netfilter/xt_socket.c
@@ -0,0 +1,185 @@
1/*
2 * Transparent proxy support for Linux/iptables
3 *
4 * Copyright (C) 2007-2008 BalaBit IT Ltd.
5 * Author: Krisztian Kovacs
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 */
12
13#include <linux/module.h>
14#include <linux/skbuff.h>
15#include <linux/netfilter/x_tables.h>
16#include <linux/netfilter_ipv4/ip_tables.h>
17#include <net/tcp.h>
18#include <net/udp.h>
19#include <net/icmp.h>
20#include <net/sock.h>
21#include <net/inet_sock.h>
22#include <net/netfilter/nf_tproxy_core.h>
23#include <net/netfilter/ipv4/nf_defrag_ipv4.h>
24
25#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
26#define XT_SOCKET_HAVE_CONNTRACK 1
27#include <net/netfilter/nf_conntrack.h>
28#endif
29
30static int
31extract_icmp_fields(const struct sk_buff *skb,
32 u8 *protocol,
33 __be32 *raddr,
34 __be32 *laddr,
35 __be16 *rport,
36 __be16 *lport)
37{
38 unsigned int outside_hdrlen = ip_hdrlen(skb);
39 struct iphdr *inside_iph, _inside_iph;
40 struct icmphdr *icmph, _icmph;
41 __be16 *ports, _ports[2];
42
43 icmph = skb_header_pointer(skb, outside_hdrlen,
44 sizeof(_icmph), &_icmph);
45 if (icmph == NULL)
46 return 1;
47
48 switch (icmph->type) {
49 case ICMP_DEST_UNREACH:
50 case ICMP_SOURCE_QUENCH:
51 case ICMP_REDIRECT:
52 case ICMP_TIME_EXCEEDED:
53 case ICMP_PARAMETERPROB:
54 break;
55 default:
56 return 1;
57 }
58
59 inside_iph = skb_header_pointer(skb, outside_hdrlen +
60 sizeof(struct icmphdr),
61 sizeof(_inside_iph), &_inside_iph);
62 if (inside_iph == NULL)
63 return 1;
64
65 if (inside_iph->protocol != IPPROTO_TCP &&
66 inside_iph->protocol != IPPROTO_UDP)
67 return 1;
68
69 ports = skb_header_pointer(skb, outside_hdrlen +
70 sizeof(struct icmphdr) +
71 (inside_iph->ihl << 2),
72 sizeof(_ports), &_ports);
73 if (ports == NULL)
74 return 1;
75
76 /* the inside IP packet is the one quoted from our side, thus
77 * its saddr is the local address */
78 *protocol = inside_iph->protocol;
79 *laddr = inside_iph->saddr;
80 *lport = ports[0];
81 *raddr = inside_iph->daddr;
82 *rport = ports[1];
83
84 return 0;
85}
86
87
88static bool
89socket_mt(const struct sk_buff *skb, const struct xt_match_param *par)
90{
91 const struct iphdr *iph = ip_hdr(skb);
92 struct udphdr _hdr, *hp = NULL;
93 struct sock *sk;
94 __be32 daddr, saddr;
95 __be16 dport, sport;
96 u8 protocol;
97#ifdef XT_SOCKET_HAVE_CONNTRACK
98 struct nf_conn const *ct;
99 enum ip_conntrack_info ctinfo;
100#endif
101
102 if (iph->protocol == IPPROTO_UDP || iph->protocol == IPPROTO_TCP) {
103 hp = skb_header_pointer(skb, ip_hdrlen(skb),
104 sizeof(_hdr), &_hdr);
105 if (hp == NULL)
106 return false;
107
108 protocol = iph->protocol;
109 saddr = iph->saddr;
110 sport = hp->source;
111 daddr = iph->daddr;
112 dport = hp->dest;
113
114 } else if (iph->protocol == IPPROTO_ICMP) {
115 if (extract_icmp_fields(skb, &protocol, &saddr, &daddr,
116 &sport, &dport))
117 return false;
118 } else {
119 return false;
120 }
121
122#ifdef XT_SOCKET_HAVE_CONNTRACK
123 /* Do the lookup with the original socket address in case this is a
124 * reply packet of an established SNAT-ted connection. */
125
126 ct = nf_ct_get(skb, &ctinfo);
127 if (ct && (ct != &nf_conntrack_untracked) &&
128 ((iph->protocol != IPPROTO_ICMP &&
129 ctinfo == IP_CT_IS_REPLY + IP_CT_ESTABLISHED) ||
130 (iph->protocol == IPPROTO_ICMP &&
131 ctinfo == IP_CT_IS_REPLY + IP_CT_RELATED)) &&
132 (ct->status & IPS_SRC_NAT_DONE)) {
133
134 daddr = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip;
135 dport = (iph->protocol == IPPROTO_TCP) ?
136 ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.tcp.port :
137 ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port;
138 }
139#endif
140
141 sk = nf_tproxy_get_sock_v4(dev_net(skb->dev), protocol,
142 saddr, daddr, sport, dport, par->in, false);
143 if (sk != NULL) {
144 bool wildcard = (inet_sk(sk)->rcv_saddr == 0);
145
146 nf_tproxy_put_sock(sk);
147 if (wildcard)
148 sk = NULL;
149 }
150
151 pr_debug("socket match: proto %u %08x:%u -> %08x:%u "
152 "(orig %08x:%u) sock %p\n",
153 protocol, ntohl(saddr), ntohs(sport),
154 ntohl(daddr), ntohs(dport),
155 ntohl(iph->daddr), hp ? ntohs(hp->dest) : 0, sk);
156
157 return (sk != NULL);
158}
159
160static struct xt_match socket_mt_reg __read_mostly = {
161 .name = "socket",
162 .family = AF_INET,
163 .match = socket_mt,
164 .hooks = 1 << NF_INET_PRE_ROUTING,
165 .me = THIS_MODULE,
166};
167
168static int __init socket_mt_init(void)
169{
170 nf_defrag_ipv4_enable();
171 return xt_register_match(&socket_mt_reg);
172}
173
174static void __exit socket_mt_exit(void)
175{
176 xt_unregister_match(&socket_mt_reg);
177}
178
179module_init(socket_mt_init);
180module_exit(socket_mt_exit);
181
182MODULE_LICENSE("GPL");
183MODULE_AUTHOR("Krisztian Kovacs, Balazs Scheidler");
184MODULE_DESCRIPTION("x_tables socket match module");
185MODULE_ALIAS("ipt_socket");
diff --git a/net/netfilter/xt_state.c b/net/netfilter/xt_state.c
index a776dc36a193..4c946cbd731f 100644
--- a/net/netfilter/xt_state.c
+++ b/net/netfilter/xt_state.c
@@ -21,12 +21,9 @@ MODULE_ALIAS("ipt_state");
21MODULE_ALIAS("ip6t_state"); 21MODULE_ALIAS("ip6t_state");
22 22
23static bool 23static bool
24state_mt(const struct sk_buff *skb, const struct net_device *in, 24state_mt(const struct sk_buff *skb, const struct xt_match_param *par)
25 const struct net_device *out, const struct xt_match *match,
26 const void *matchinfo, int offset, unsigned int protoff,
27 bool *hotdrop)
28{ 25{
29 const struct xt_state_info *sinfo = matchinfo; 26 const struct xt_state_info *sinfo = par->matchinfo;
30 enum ip_conntrack_info ctinfo; 27 enum ip_conntrack_info ctinfo;
31 unsigned int statebit; 28 unsigned int statebit;
32 29
@@ -40,28 +37,25 @@ state_mt(const struct sk_buff *skb, const struct net_device *in,
40 return (sinfo->statemask & statebit); 37 return (sinfo->statemask & statebit);
41} 38}
42 39
43static bool 40static bool state_mt_check(const struct xt_mtchk_param *par)
44state_mt_check(const char *tablename, const void *inf,
45 const struct xt_match *match, void *matchinfo,
46 unsigned int hook_mask)
47{ 41{
48 if (nf_ct_l3proto_try_module_get(match->family) < 0) { 42 if (nf_ct_l3proto_try_module_get(par->match->family) < 0) {
49 printk(KERN_WARNING "can't load conntrack support for " 43 printk(KERN_WARNING "can't load conntrack support for "
50 "proto=%u\n", match->family); 44 "proto=%u\n", par->match->family);
51 return false; 45 return false;
52 } 46 }
53 return true; 47 return true;
54} 48}
55 49
56static void state_mt_destroy(const struct xt_match *match, void *matchinfo) 50static void state_mt_destroy(const struct xt_mtdtor_param *par)
57{ 51{
58 nf_ct_l3proto_module_put(match->family); 52 nf_ct_l3proto_module_put(par->match->family);
59} 53}
60 54
61static struct xt_match state_mt_reg[] __read_mostly = { 55static struct xt_match state_mt_reg[] __read_mostly = {
62 { 56 {
63 .name = "state", 57 .name = "state",
64 .family = AF_INET, 58 .family = NFPROTO_IPV4,
65 .checkentry = state_mt_check, 59 .checkentry = state_mt_check,
66 .match = state_mt, 60 .match = state_mt,
67 .destroy = state_mt_destroy, 61 .destroy = state_mt_destroy,
@@ -70,7 +64,7 @@ static struct xt_match state_mt_reg[] __read_mostly = {
70 }, 64 },
71 { 65 {
72 .name = "state", 66 .name = "state",
73 .family = AF_INET6, 67 .family = NFPROTO_IPV6,
74 .checkentry = state_mt_check, 68 .checkentry = state_mt_check,
75 .match = state_mt, 69 .match = state_mt,
76 .destroy = state_mt_destroy, 70 .destroy = state_mt_destroy,
diff --git a/net/netfilter/xt_statistic.c b/net/netfilter/xt_statistic.c
index 43133080da7d..0d75141139d5 100644
--- a/net/netfilter/xt_statistic.c
+++ b/net/netfilter/xt_statistic.c
@@ -25,12 +25,9 @@ MODULE_ALIAS("ip6t_statistic");
25static DEFINE_SPINLOCK(nth_lock); 25static DEFINE_SPINLOCK(nth_lock);
26 26
27static bool 27static bool
28statistic_mt(const struct sk_buff *skb, const struct net_device *in, 28statistic_mt(const struct sk_buff *skb, const struct xt_match_param *par)
29 const struct net_device *out, const struct xt_match *match,
30 const void *matchinfo, int offset, unsigned int protoff,
31 bool *hotdrop)
32{ 29{
33 struct xt_statistic_info *info = (struct xt_statistic_info *)matchinfo; 30 struct xt_statistic_info *info = (void *)par->matchinfo;
34 bool ret = info->flags & XT_STATISTIC_INVERT; 31 bool ret = info->flags & XT_STATISTIC_INVERT;
35 32
36 switch (info->mode) { 33 switch (info->mode) {
@@ -52,12 +49,9 @@ statistic_mt(const struct sk_buff *skb, const struct net_device *in,
52 return ret; 49 return ret;
53} 50}
54 51
55static bool 52static bool statistic_mt_check(const struct xt_mtchk_param *par)
56statistic_mt_check(const char *tablename, const void *entry,
57 const struct xt_match *match, void *matchinfo,
58 unsigned int hook_mask)
59{ 53{
60 struct xt_statistic_info *info = matchinfo; 54 struct xt_statistic_info *info = par->matchinfo;
61 55
62 if (info->mode > XT_STATISTIC_MODE_MAX || 56 if (info->mode > XT_STATISTIC_MODE_MAX ||
63 info->flags & ~XT_STATISTIC_MASK) 57 info->flags & ~XT_STATISTIC_MASK)
@@ -66,35 +60,24 @@ statistic_mt_check(const char *tablename, const void *entry,
66 return true; 60 return true;
67} 61}
68 62
69static struct xt_match statistic_mt_reg[] __read_mostly = { 63static struct xt_match xt_statistic_mt_reg __read_mostly = {
70 { 64 .name = "statistic",
71 .name = "statistic", 65 .revision = 0,
72 .family = AF_INET, 66 .family = NFPROTO_UNSPEC,
73 .checkentry = statistic_mt_check, 67 .match = statistic_mt,
74 .match = statistic_mt, 68 .checkentry = statistic_mt_check,
75 .matchsize = sizeof(struct xt_statistic_info), 69 .matchsize = sizeof(struct xt_statistic_info),
76 .me = THIS_MODULE, 70 .me = THIS_MODULE,
77 },
78 {
79 .name = "statistic",
80 .family = AF_INET6,
81 .checkentry = statistic_mt_check,
82 .match = statistic_mt,
83 .matchsize = sizeof(struct xt_statistic_info),
84 .me = THIS_MODULE,
85 },
86}; 71};
87 72
88static int __init statistic_mt_init(void) 73static int __init statistic_mt_init(void)
89{ 74{
90 return xt_register_matches(statistic_mt_reg, 75 return xt_register_match(&xt_statistic_mt_reg);
91 ARRAY_SIZE(statistic_mt_reg));
92} 76}
93 77
94static void __exit statistic_mt_exit(void) 78static void __exit statistic_mt_exit(void)
95{ 79{
96 xt_unregister_matches(statistic_mt_reg, 80 xt_unregister_match(&xt_statistic_mt_reg);
97 ARRAY_SIZE(statistic_mt_reg));
98} 81}
99 82
100module_init(statistic_mt_init); 83module_init(statistic_mt_init);
diff --git a/net/netfilter/xt_string.c b/net/netfilter/xt_string.c
index 4903182a062b..b4d774111311 100644
--- a/net/netfilter/xt_string.c
+++ b/net/netfilter/xt_string.c
@@ -22,18 +22,15 @@ MODULE_ALIAS("ipt_string");
22MODULE_ALIAS("ip6t_string"); 22MODULE_ALIAS("ip6t_string");
23 23
24static bool 24static bool
25string_mt(const struct sk_buff *skb, const struct net_device *in, 25string_mt(const struct sk_buff *skb, const struct xt_match_param *par)
26 const struct net_device *out, const struct xt_match *match,
27 const void *matchinfo, int offset, unsigned int protoff,
28 bool *hotdrop)
29{ 26{
30 const struct xt_string_info *conf = matchinfo; 27 const struct xt_string_info *conf = par->matchinfo;
31 struct ts_state state; 28 struct ts_state state;
32 int invert; 29 int invert;
33 30
34 memset(&state, 0, sizeof(struct ts_state)); 31 memset(&state, 0, sizeof(struct ts_state));
35 32
36 invert = (match->revision == 0 ? conf->u.v0.invert : 33 invert = (par->match->revision == 0 ? conf->u.v0.invert :
37 conf->u.v1.flags & XT_STRING_FLAG_INVERT); 34 conf->u.v1.flags & XT_STRING_FLAG_INVERT);
38 35
39 return (skb_find_text((struct sk_buff *)skb, conf->from_offset, 36 return (skb_find_text((struct sk_buff *)skb, conf->from_offset,
@@ -43,12 +40,9 @@ string_mt(const struct sk_buff *skb, const struct net_device *in,
43 40
44#define STRING_TEXT_PRIV(m) ((struct xt_string_info *)(m)) 41#define STRING_TEXT_PRIV(m) ((struct xt_string_info *)(m))
45 42
46static bool 43static bool string_mt_check(const struct xt_mtchk_param *par)
47string_mt_check(const char *tablename, const void *ip,
48 const struct xt_match *match, void *matchinfo,
49 unsigned int hook_mask)
50{ 44{
51 struct xt_string_info *conf = matchinfo; 45 struct xt_string_info *conf = par->matchinfo;
52 struct ts_config *ts_conf; 46 struct ts_config *ts_conf;
53 int flags = TS_AUTOLOAD; 47 int flags = TS_AUTOLOAD;
54 48
@@ -59,7 +53,7 @@ string_mt_check(const char *tablename, const void *ip,
59 return false; 53 return false;
60 if (conf->patlen > XT_STRING_MAX_PATTERN_SIZE) 54 if (conf->patlen > XT_STRING_MAX_PATTERN_SIZE)
61 return false; 55 return false;
62 if (match->revision == 1) { 56 if (par->match->revision == 1) {
63 if (conf->u.v1.flags & 57 if (conf->u.v1.flags &
64 ~(XT_STRING_FLAG_IGNORECASE | XT_STRING_FLAG_INVERT)) 58 ~(XT_STRING_FLAG_IGNORECASE | XT_STRING_FLAG_INVERT))
65 return false; 59 return false;
@@ -76,36 +70,16 @@ string_mt_check(const char *tablename, const void *ip,
76 return true; 70 return true;
77} 71}
78 72
79static void string_mt_destroy(const struct xt_match *match, void *matchinfo) 73static void string_mt_destroy(const struct xt_mtdtor_param *par)
80{ 74{
81 textsearch_destroy(STRING_TEXT_PRIV(matchinfo)->config); 75 textsearch_destroy(STRING_TEXT_PRIV(par->matchinfo)->config);
82} 76}
83 77
84static struct xt_match string_mt_reg[] __read_mostly = { 78static struct xt_match xt_string_mt_reg[] __read_mostly = {
85 {
86 .name = "string",
87 .revision = 0,
88 .family = AF_INET,
89 .checkentry = string_mt_check,
90 .match = string_mt,
91 .destroy = string_mt_destroy,
92 .matchsize = sizeof(struct xt_string_info),
93 .me = THIS_MODULE
94 },
95 {
96 .name = "string",
97 .revision = 1,
98 .family = AF_INET,
99 .checkentry = string_mt_check,
100 .match = string_mt,
101 .destroy = string_mt_destroy,
102 .matchsize = sizeof(struct xt_string_info),
103 .me = THIS_MODULE
104 },
105 { 79 {
106 .name = "string", 80 .name = "string",
107 .revision = 0, 81 .revision = 0,
108 .family = AF_INET6, 82 .family = NFPROTO_UNSPEC,
109 .checkentry = string_mt_check, 83 .checkentry = string_mt_check,
110 .match = string_mt, 84 .match = string_mt,
111 .destroy = string_mt_destroy, 85 .destroy = string_mt_destroy,
@@ -115,7 +89,7 @@ static struct xt_match string_mt_reg[] __read_mostly = {
115 { 89 {
116 .name = "string", 90 .name = "string",
117 .revision = 1, 91 .revision = 1,
118 .family = AF_INET6, 92 .family = NFPROTO_UNSPEC,
119 .checkentry = string_mt_check, 93 .checkentry = string_mt_check,
120 .match = string_mt, 94 .match = string_mt,
121 .destroy = string_mt_destroy, 95 .destroy = string_mt_destroy,
@@ -126,12 +100,13 @@ static struct xt_match string_mt_reg[] __read_mostly = {
126 100
127static int __init string_mt_init(void) 101static int __init string_mt_init(void)
128{ 102{
129 return xt_register_matches(string_mt_reg, ARRAY_SIZE(string_mt_reg)); 103 return xt_register_matches(xt_string_mt_reg,
104 ARRAY_SIZE(xt_string_mt_reg));
130} 105}
131 106
132static void __exit string_mt_exit(void) 107static void __exit string_mt_exit(void)
133{ 108{
134 xt_unregister_matches(string_mt_reg, ARRAY_SIZE(string_mt_reg)); 109 xt_unregister_matches(xt_string_mt_reg, ARRAY_SIZE(xt_string_mt_reg));
135} 110}
136 111
137module_init(string_mt_init); 112module_init(string_mt_init);
diff --git a/net/netfilter/xt_tcpmss.c b/net/netfilter/xt_tcpmss.c
index 6771bf01275b..4809b34b10f8 100644
--- a/net/netfilter/xt_tcpmss.c
+++ b/net/netfilter/xt_tcpmss.c
@@ -25,12 +25,9 @@ MODULE_ALIAS("ipt_tcpmss");
25MODULE_ALIAS("ip6t_tcpmss"); 25MODULE_ALIAS("ip6t_tcpmss");
26 26
27static bool 27static bool
28tcpmss_mt(const struct sk_buff *skb, const struct net_device *in, 28tcpmss_mt(const struct sk_buff *skb, const struct xt_match_param *par)
29 const struct net_device *out, const struct xt_match *match,
30 const void *matchinfo, int offset, unsigned int protoff,
31 bool *hotdrop)
32{ 29{
33 const struct xt_tcpmss_match_info *info = matchinfo; 30 const struct xt_tcpmss_match_info *info = par->matchinfo;
34 const struct tcphdr *th; 31 const struct tcphdr *th;
35 struct tcphdr _tcph; 32 struct tcphdr _tcph;
36 /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */ 33 /* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */
@@ -39,7 +36,7 @@ tcpmss_mt(const struct sk_buff *skb, const struct net_device *in,
39 unsigned int i, optlen; 36 unsigned int i, optlen;
40 37
41 /* If we don't have the whole header, drop packet. */ 38 /* If we don't have the whole header, drop packet. */
42 th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph); 39 th = skb_header_pointer(skb, par->thoff, sizeof(_tcph), &_tcph);
43 if (th == NULL) 40 if (th == NULL)
44 goto dropit; 41 goto dropit;
45 42
@@ -52,7 +49,7 @@ tcpmss_mt(const struct sk_buff *skb, const struct net_device *in,
52 goto out; 49 goto out;
53 50
54 /* Truncated options. */ 51 /* Truncated options. */
55 op = skb_header_pointer(skb, protoff + sizeof(*th), optlen, _opt); 52 op = skb_header_pointer(skb, par->thoff + sizeof(*th), optlen, _opt);
56 if (op == NULL) 53 if (op == NULL)
57 goto dropit; 54 goto dropit;
58 55
@@ -76,14 +73,14 @@ out:
76 return info->invert; 73 return info->invert;
77 74
78dropit: 75dropit:
79 *hotdrop = true; 76 *par->hotdrop = true;
80 return false; 77 return false;
81} 78}
82 79
83static struct xt_match tcpmss_mt_reg[] __read_mostly = { 80static struct xt_match tcpmss_mt_reg[] __read_mostly = {
84 { 81 {
85 .name = "tcpmss", 82 .name = "tcpmss",
86 .family = AF_INET, 83 .family = NFPROTO_IPV4,
87 .match = tcpmss_mt, 84 .match = tcpmss_mt,
88 .matchsize = sizeof(struct xt_tcpmss_match_info), 85 .matchsize = sizeof(struct xt_tcpmss_match_info),
89 .proto = IPPROTO_TCP, 86 .proto = IPPROTO_TCP,
@@ -91,7 +88,7 @@ static struct xt_match tcpmss_mt_reg[] __read_mostly = {
91 }, 88 },
92 { 89 {
93 .name = "tcpmss", 90 .name = "tcpmss",
94 .family = AF_INET6, 91 .family = NFPROTO_IPV6,
95 .match = tcpmss_mt, 92 .match = tcpmss_mt,
96 .matchsize = sizeof(struct xt_tcpmss_match_info), 93 .matchsize = sizeof(struct xt_tcpmss_match_info),
97 .proto = IPPROTO_TCP, 94 .proto = IPPROTO_TCP,
diff --git a/net/netfilter/xt_tcpudp.c b/net/netfilter/xt_tcpudp.c
index 951b06b8d701..1ebdc4934eed 100644
--- a/net/netfilter/xt_tcpudp.c
+++ b/net/netfilter/xt_tcpudp.c
@@ -68,25 +68,22 @@ tcp_find_option(u_int8_t option,
68 return invert; 68 return invert;
69} 69}
70 70
71static bool 71static bool tcp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
72tcp_mt(const struct sk_buff *skb, const struct net_device *in,
73 const struct net_device *out, const struct xt_match *match,
74 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
75{ 72{
76 const struct tcphdr *th; 73 const struct tcphdr *th;
77 struct tcphdr _tcph; 74 struct tcphdr _tcph;
78 const struct xt_tcp *tcpinfo = matchinfo; 75 const struct xt_tcp *tcpinfo = par->matchinfo;
79 76
80 if (offset) { 77 if (par->fragoff != 0) {
81 /* To quote Alan: 78 /* To quote Alan:
82 79
83 Don't allow a fragment of TCP 8 bytes in. Nobody normal 80 Don't allow a fragment of TCP 8 bytes in. Nobody normal
84 causes this. Its a cracker trying to break in by doing a 81 causes this. Its a cracker trying to break in by doing a
85 flag overwrite to pass the direction checks. 82 flag overwrite to pass the direction checks.
86 */ 83 */
87 if (offset == 1) { 84 if (par->fragoff == 1) {
88 duprintf("Dropping evil TCP offset=1 frag.\n"); 85 duprintf("Dropping evil TCP offset=1 frag.\n");
89 *hotdrop = true; 86 *par->hotdrop = true;
90 } 87 }
91 /* Must not be a fragment. */ 88 /* Must not be a fragment. */
92 return false; 89 return false;
@@ -94,12 +91,12 @@ tcp_mt(const struct sk_buff *skb, const struct net_device *in,
94 91
95#define FWINVTCP(bool, invflg) ((bool) ^ !!(tcpinfo->invflags & (invflg))) 92#define FWINVTCP(bool, invflg) ((bool) ^ !!(tcpinfo->invflags & (invflg)))
96 93
97 th = skb_header_pointer(skb, protoff, sizeof(_tcph), &_tcph); 94 th = skb_header_pointer(skb, par->thoff, sizeof(_tcph), &_tcph);
98 if (th == NULL) { 95 if (th == NULL) {
99 /* We've been asked to examine this packet, and we 96 /* We've been asked to examine this packet, and we
100 can't. Hence, no choice but to drop. */ 97 can't. Hence, no choice but to drop. */
101 duprintf("Dropping evil TCP offset=0 tinygram.\n"); 98 duprintf("Dropping evil TCP offset=0 tinygram.\n");
102 *hotdrop = true; 99 *par->hotdrop = true;
103 return false; 100 return false;
104 } 101 }
105 102
@@ -117,49 +114,42 @@ tcp_mt(const struct sk_buff *skb, const struct net_device *in,
117 return false; 114 return false;
118 if (tcpinfo->option) { 115 if (tcpinfo->option) {
119 if (th->doff * 4 < sizeof(_tcph)) { 116 if (th->doff * 4 < sizeof(_tcph)) {
120 *hotdrop = true; 117 *par->hotdrop = true;
121 return false; 118 return false;
122 } 119 }
123 if (!tcp_find_option(tcpinfo->option, skb, protoff, 120 if (!tcp_find_option(tcpinfo->option, skb, par->thoff,
124 th->doff*4 - sizeof(_tcph), 121 th->doff*4 - sizeof(_tcph),
125 tcpinfo->invflags & XT_TCP_INV_OPTION, 122 tcpinfo->invflags & XT_TCP_INV_OPTION,
126 hotdrop)) 123 par->hotdrop))
127 return false; 124 return false;
128 } 125 }
129 return true; 126 return true;
130} 127}
131 128
132/* Called when user tries to insert an entry of this type. */ 129static bool tcp_mt_check(const struct xt_mtchk_param *par)
133static bool
134tcp_mt_check(const char *tablename, const void *info,
135 const struct xt_match *match, void *matchinfo,
136 unsigned int hook_mask)
137{ 130{
138 const struct xt_tcp *tcpinfo = matchinfo; 131 const struct xt_tcp *tcpinfo = par->matchinfo;
139 132
140 /* Must specify no unknown invflags */ 133 /* Must specify no unknown invflags */
141 return !(tcpinfo->invflags & ~XT_TCP_INV_MASK); 134 return !(tcpinfo->invflags & ~XT_TCP_INV_MASK);
142} 135}
143 136
144static bool 137static bool udp_mt(const struct sk_buff *skb, const struct xt_match_param *par)
145udp_mt(const struct sk_buff *skb, const struct net_device *in,
146 const struct net_device *out, const struct xt_match *match,
147 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
148{ 138{
149 const struct udphdr *uh; 139 const struct udphdr *uh;
150 struct udphdr _udph; 140 struct udphdr _udph;
151 const struct xt_udp *udpinfo = matchinfo; 141 const struct xt_udp *udpinfo = par->matchinfo;
152 142
153 /* Must not be a fragment. */ 143 /* Must not be a fragment. */
154 if (offset) 144 if (par->fragoff != 0)
155 return false; 145 return false;
156 146
157 uh = skb_header_pointer(skb, protoff, sizeof(_udph), &_udph); 147 uh = skb_header_pointer(skb, par->thoff, sizeof(_udph), &_udph);
158 if (uh == NULL) { 148 if (uh == NULL) {
159 /* We've been asked to examine this packet, and we 149 /* We've been asked to examine this packet, and we
160 can't. Hence, no choice but to drop. */ 150 can't. Hence, no choice but to drop. */
161 duprintf("Dropping evil UDP tinygram.\n"); 151 duprintf("Dropping evil UDP tinygram.\n");
162 *hotdrop = true; 152 *par->hotdrop = true;
163 return false; 153 return false;
164 } 154 }
165 155
@@ -171,13 +161,9 @@ udp_mt(const struct sk_buff *skb, const struct net_device *in,
171 !!(udpinfo->invflags & XT_UDP_INV_DSTPT)); 161 !!(udpinfo->invflags & XT_UDP_INV_DSTPT));
172} 162}
173 163
174/* Called when user tries to insert an entry of this type. */ 164static bool udp_mt_check(const struct xt_mtchk_param *par)
175static bool
176udp_mt_check(const char *tablename, const void *info,
177 const struct xt_match *match, void *matchinfo,
178 unsigned int hook_mask)
179{ 165{
180 const struct xt_udp *udpinfo = matchinfo; 166 const struct xt_udp *udpinfo = par->matchinfo;
181 167
182 /* Must specify no unknown invflags */ 168 /* Must specify no unknown invflags */
183 return !(udpinfo->invflags & ~XT_UDP_INV_MASK); 169 return !(udpinfo->invflags & ~XT_UDP_INV_MASK);
@@ -186,7 +172,7 @@ udp_mt_check(const char *tablename, const void *info,
186static struct xt_match tcpudp_mt_reg[] __read_mostly = { 172static struct xt_match tcpudp_mt_reg[] __read_mostly = {
187 { 173 {
188 .name = "tcp", 174 .name = "tcp",
189 .family = AF_INET, 175 .family = NFPROTO_IPV4,
190 .checkentry = tcp_mt_check, 176 .checkentry = tcp_mt_check,
191 .match = tcp_mt, 177 .match = tcp_mt,
192 .matchsize = sizeof(struct xt_tcp), 178 .matchsize = sizeof(struct xt_tcp),
@@ -195,7 +181,7 @@ static struct xt_match tcpudp_mt_reg[] __read_mostly = {
195 }, 181 },
196 { 182 {
197 .name = "tcp", 183 .name = "tcp",
198 .family = AF_INET6, 184 .family = NFPROTO_IPV6,
199 .checkentry = tcp_mt_check, 185 .checkentry = tcp_mt_check,
200 .match = tcp_mt, 186 .match = tcp_mt,
201 .matchsize = sizeof(struct xt_tcp), 187 .matchsize = sizeof(struct xt_tcp),
@@ -204,7 +190,7 @@ static struct xt_match tcpudp_mt_reg[] __read_mostly = {
204 }, 190 },
205 { 191 {
206 .name = "udp", 192 .name = "udp",
207 .family = AF_INET, 193 .family = NFPROTO_IPV4,
208 .checkentry = udp_mt_check, 194 .checkentry = udp_mt_check,
209 .match = udp_mt, 195 .match = udp_mt,
210 .matchsize = sizeof(struct xt_udp), 196 .matchsize = sizeof(struct xt_udp),
@@ -213,7 +199,7 @@ static struct xt_match tcpudp_mt_reg[] __read_mostly = {
213 }, 199 },
214 { 200 {
215 .name = "udp", 201 .name = "udp",
216 .family = AF_INET6, 202 .family = NFPROTO_IPV6,
217 .checkentry = udp_mt_check, 203 .checkentry = udp_mt_check,
218 .match = udp_mt, 204 .match = udp_mt,
219 .matchsize = sizeof(struct xt_udp), 205 .matchsize = sizeof(struct xt_udp),
@@ -222,7 +208,7 @@ static struct xt_match tcpudp_mt_reg[] __read_mostly = {
222 }, 208 },
223 { 209 {
224 .name = "udplite", 210 .name = "udplite",
225 .family = AF_INET, 211 .family = NFPROTO_IPV4,
226 .checkentry = udp_mt_check, 212 .checkentry = udp_mt_check,
227 .match = udp_mt, 213 .match = udp_mt,
228 .matchsize = sizeof(struct xt_udp), 214 .matchsize = sizeof(struct xt_udp),
@@ -231,7 +217,7 @@ static struct xt_match tcpudp_mt_reg[] __read_mostly = {
231 }, 217 },
232 { 218 {
233 .name = "udplite", 219 .name = "udplite",
234 .family = AF_INET6, 220 .family = NFPROTO_IPV6,
235 .checkentry = udp_mt_check, 221 .checkentry = udp_mt_check,
236 .match = udp_mt, 222 .match = udp_mt,
237 .matchsize = sizeof(struct xt_udp), 223 .matchsize = sizeof(struct xt_udp),
diff --git a/net/netfilter/xt_time.c b/net/netfilter/xt_time.c
index 9f328593287e..29375ba8db73 100644
--- a/net/netfilter/xt_time.c
+++ b/net/netfilter/xt_time.c
@@ -136,26 +136,26 @@ static void localtime_3(struct xtm *r, time_t time)
136 * from w repeatedly while counting.) 136 * from w repeatedly while counting.)
137 */ 137 */
138 if (is_leap(year)) { 138 if (is_leap(year)) {
139 /* use days_since_leapyear[] in a leap year */
139 for (i = ARRAY_SIZE(days_since_leapyear) - 1; 140 for (i = ARRAY_SIZE(days_since_leapyear) - 1;
140 i > 0 && days_since_year[i] > w; --i) 141 i > 0 && days_since_leapyear[i] > w; --i)
141 /* just loop */; 142 /* just loop */;
143 r->monthday = w - days_since_leapyear[i] + 1;
142 } else { 144 } else {
143 for (i = ARRAY_SIZE(days_since_year) - 1; 145 for (i = ARRAY_SIZE(days_since_year) - 1;
144 i > 0 && days_since_year[i] > w; --i) 146 i > 0 && days_since_year[i] > w; --i)
145 /* just loop */; 147 /* just loop */;
148 r->monthday = w - days_since_year[i] + 1;
146 } 149 }
147 150
148 r->month = i + 1; 151 r->month = i + 1;
149 r->monthday = w - days_since_year[i] + 1;
150 return; 152 return;
151} 153}
152 154
153static bool 155static bool
154time_mt(const struct sk_buff *skb, const struct net_device *in, 156time_mt(const struct sk_buff *skb, const struct xt_match_param *par)
155 const struct net_device *out, const struct xt_match *match,
156 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
157{ 157{
158 const struct xt_time_info *info = matchinfo; 158 const struct xt_time_info *info = par->matchinfo;
159 unsigned int packet_time; 159 unsigned int packet_time;
160 struct xtm current_time; 160 struct xtm current_time;
161 s64 stamp; 161 s64 stamp;
@@ -218,12 +218,9 @@ time_mt(const struct sk_buff *skb, const struct net_device *in,
218 return true; 218 return true;
219} 219}
220 220
221static bool 221static bool time_mt_check(const struct xt_mtchk_param *par)
222time_mt_check(const char *tablename, const void *ip,
223 const struct xt_match *match, void *matchinfo,
224 unsigned int hook_mask)
225{ 222{
226 const struct xt_time_info *info = matchinfo; 223 const struct xt_time_info *info = par->matchinfo;
227 224
228 if (info->daytime_start > XT_TIME_MAX_DAYTIME || 225 if (info->daytime_start > XT_TIME_MAX_DAYTIME ||
229 info->daytime_stop > XT_TIME_MAX_DAYTIME) { 226 info->daytime_stop > XT_TIME_MAX_DAYTIME) {
@@ -235,33 +232,23 @@ time_mt_check(const char *tablename, const void *ip,
235 return true; 232 return true;
236} 233}
237 234
238static struct xt_match time_mt_reg[] __read_mostly = { 235static struct xt_match xt_time_mt_reg __read_mostly = {
239 { 236 .name = "time",
240 .name = "time", 237 .family = NFPROTO_UNSPEC,
241 .family = AF_INET, 238 .match = time_mt,
242 .match = time_mt, 239 .checkentry = time_mt_check,
243 .matchsize = sizeof(struct xt_time_info), 240 .matchsize = sizeof(struct xt_time_info),
244 .checkentry = time_mt_check, 241 .me = THIS_MODULE,
245 .me = THIS_MODULE,
246 },
247 {
248 .name = "time",
249 .family = AF_INET6,
250 .match = time_mt,
251 .matchsize = sizeof(struct xt_time_info),
252 .checkentry = time_mt_check,
253 .me = THIS_MODULE,
254 },
255}; 242};
256 243
257static int __init time_mt_init(void) 244static int __init time_mt_init(void)
258{ 245{
259 return xt_register_matches(time_mt_reg, ARRAY_SIZE(time_mt_reg)); 246 return xt_register_match(&xt_time_mt_reg);
260} 247}
261 248
262static void __exit time_mt_exit(void) 249static void __exit time_mt_exit(void)
263{ 250{
264 xt_unregister_matches(time_mt_reg, ARRAY_SIZE(time_mt_reg)); 251 xt_unregister_match(&xt_time_mt_reg);
265} 252}
266 253
267module_init(time_mt_init); 254module_init(time_mt_init);
diff --git a/net/netfilter/xt_u32.c b/net/netfilter/xt_u32.c
index 627e0f336d54..24a527624500 100644
--- a/net/netfilter/xt_u32.c
+++ b/net/netfilter/xt_u32.c
@@ -87,43 +87,32 @@ static bool u32_match_it(const struct xt_u32 *data,
87 return true; 87 return true;
88} 88}
89 89
90static bool 90static bool u32_mt(const struct sk_buff *skb, const struct xt_match_param *par)
91u32_mt(const struct sk_buff *skb, const struct net_device *in,
92 const struct net_device *out, const struct xt_match *match,
93 const void *matchinfo, int offset, unsigned int protoff, bool *hotdrop)
94{ 91{
95 const struct xt_u32 *data = matchinfo; 92 const struct xt_u32 *data = par->matchinfo;
96 bool ret; 93 bool ret;
97 94
98 ret = u32_match_it(data, skb); 95 ret = u32_match_it(data, skb);
99 return ret ^ data->invert; 96 return ret ^ data->invert;
100} 97}
101 98
102static struct xt_match u32_mt_reg[] __read_mostly = { 99static struct xt_match xt_u32_mt_reg __read_mostly = {
103 { 100 .name = "u32",
104 .name = "u32", 101 .revision = 0,
105 .family = AF_INET, 102 .family = NFPROTO_UNSPEC,
106 .match = u32_mt, 103 .match = u32_mt,
107 .matchsize = sizeof(struct xt_u32), 104 .matchsize = sizeof(struct xt_u32),
108 .me = THIS_MODULE, 105 .me = THIS_MODULE,
109 },
110 {
111 .name = "u32",
112 .family = AF_INET6,
113 .match = u32_mt,
114 .matchsize = sizeof(struct xt_u32),
115 .me = THIS_MODULE,
116 },
117}; 106};
118 107
119static int __init u32_mt_init(void) 108static int __init u32_mt_init(void)
120{ 109{
121 return xt_register_matches(u32_mt_reg, ARRAY_SIZE(u32_mt_reg)); 110 return xt_register_match(&xt_u32_mt_reg);
122} 111}
123 112
124static void __exit u32_mt_exit(void) 113static void __exit u32_mt_exit(void)
125{ 114{
126 xt_unregister_matches(u32_mt_reg, ARRAY_SIZE(u32_mt_reg)); 115 xt_unregister_match(&xt_u32_mt_reg);
127} 116}
128 117
129module_init(u32_mt_init); 118module_init(u32_mt_init);
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index 532e4faa29f7..9f1ea4a27b35 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -525,6 +525,7 @@ static int nr_release(struct socket *sock)
525 if (sk == NULL) return 0; 525 if (sk == NULL) return 0;
526 526
527 sock_hold(sk); 527 sock_hold(sk);
528 sock_orphan(sk);
528 lock_sock(sk); 529 lock_sock(sk);
529 nr = nr_sk(sk); 530 nr = nr_sk(sk);
530 531
@@ -548,7 +549,6 @@ static int nr_release(struct socket *sock)
548 sk->sk_state = TCP_CLOSE; 549 sk->sk_state = TCP_CLOSE;
549 sk->sk_shutdown |= SEND_SHUTDOWN; 550 sk->sk_shutdown |= SEND_SHUTDOWN;
550 sk->sk_state_change(sk); 551 sk->sk_state_change(sk);
551 sock_orphan(sk);
552 sock_set_flag(sk, SOCK_DESTROY); 552 sock_set_flag(sk, SOCK_DESTROY);
553 break; 553 break;
554 554
diff --git a/net/phonet/Kconfig b/net/phonet/Kconfig
new file mode 100644
index 000000000000..51a5669573f2
--- /dev/null
+++ b/net/phonet/Kconfig
@@ -0,0 +1,16 @@
1#
2# Phonet protocol
3#
4
5config PHONET
6 tristate "Phonet protocols family"
7 help
8 The Phone Network protocol (PhoNet) is a packet-oriented
9 communication protocol developped by Nokia for use with its modems.
10
11 This is required for Maemo to use cellular data connectivity (if
12 supported). It can also be used to control Nokia phones
13 from a Linux computer, although AT commands may be easier to use.
14
15 To compile this driver as a module, choose M here: the module
16 will be called phonet. If unsure, say N.
diff --git a/net/phonet/Makefile b/net/phonet/Makefile
new file mode 100644
index 000000000000..d62bbba649b3
--- /dev/null
+++ b/net/phonet/Makefile
@@ -0,0 +1,11 @@
1obj-$(CONFIG_PHONET) += phonet.o pn_pep.o
2
3phonet-objs := \
4 pn_dev.o \
5 pn_netlink.o \
6 socket.o \
7 datagram.o \
8 sysctl.o \
9 af_phonet.o
10
11pn_pep-objs := pep.o pep-gprs.o
diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c
new file mode 100644
index 000000000000..9e9c6fce11aa
--- /dev/null
+++ b/net/phonet/af_phonet.c
@@ -0,0 +1,477 @@
1/*
2 * File: af_phonet.c
3 *
4 * Phonet protocols family
5 *
6 * Copyright (C) 2008 Nokia Corporation.
7 *
8 * Contact: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
9 * Original author: Sakari Ailus <sakari.ailus@nokia.com>
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * version 2 as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 */
25
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <asm/unaligned.h>
29#include <net/sock.h>
30
31#include <linux/if_phonet.h>
32#include <linux/phonet.h>
33#include <net/phonet/phonet.h>
34#include <net/phonet/pn_dev.h>
35
36static struct net_proto_family phonet_proto_family;
37static struct phonet_protocol *phonet_proto_get(int protocol);
38static inline void phonet_proto_put(struct phonet_protocol *pp);
39
40/* protocol family functions */
41
42static int pn_socket_create(struct net *net, struct socket *sock, int protocol)
43{
44 struct sock *sk;
45 struct pn_sock *pn;
46 struct phonet_protocol *pnp;
47 int err;
48
49 if (net != &init_net)
50 return -EAFNOSUPPORT;
51
52 if (!capable(CAP_SYS_ADMIN))
53 return -EPERM;
54
55 if (protocol == 0) {
56 /* Default protocol selection */
57 switch (sock->type) {
58 case SOCK_DGRAM:
59 protocol = PN_PROTO_PHONET;
60 break;
61 case SOCK_SEQPACKET:
62 protocol = PN_PROTO_PIPE;
63 break;
64 default:
65 return -EPROTONOSUPPORT;
66 }
67 }
68
69 pnp = phonet_proto_get(protocol);
70#ifdef CONFIG_KMOD
71 if (pnp == NULL &&
72 request_module("net-pf-%d-proto-%d", PF_PHONET, protocol) == 0)
73 pnp = phonet_proto_get(protocol);
74#endif
75 if (pnp == NULL)
76 return -EPROTONOSUPPORT;
77 if (sock->type != pnp->sock_type) {
78 err = -EPROTONOSUPPORT;
79 goto out;
80 }
81
82 sk = sk_alloc(net, PF_PHONET, GFP_KERNEL, pnp->prot);
83 if (sk == NULL) {
84 err = -ENOMEM;
85 goto out;
86 }
87
88 sock_init_data(sock, sk);
89 sock->state = SS_UNCONNECTED;
90 sock->ops = pnp->ops;
91 sk->sk_backlog_rcv = sk->sk_prot->backlog_rcv;
92 sk->sk_protocol = protocol;
93 pn = pn_sk(sk);
94 pn->sobject = 0;
95 pn->resource = 0;
96 sk->sk_prot->init(sk);
97 err = 0;
98
99out:
100 phonet_proto_put(pnp);
101 return err;
102}
103
104static struct net_proto_family phonet_proto_family = {
105 .family = PF_PHONET,
106 .create = pn_socket_create,
107 .owner = THIS_MODULE,
108};
109
110/* Phonet device header operations */
111static int pn_header_create(struct sk_buff *skb, struct net_device *dev,
112 unsigned short type, const void *daddr,
113 const void *saddr, unsigned len)
114{
115 u8 *media = skb_push(skb, 1);
116
117 if (type != ETH_P_PHONET)
118 return -1;
119
120 if (!saddr)
121 saddr = dev->dev_addr;
122 *media = *(const u8 *)saddr;
123 return 1;
124}
125
126static int pn_header_parse(const struct sk_buff *skb, unsigned char *haddr)
127{
128 const u8 *media = skb_mac_header(skb);
129 *haddr = *media;
130 return 1;
131}
132
133struct header_ops phonet_header_ops = {
134 .create = pn_header_create,
135 .parse = pn_header_parse,
136};
137EXPORT_SYMBOL(phonet_header_ops);
138
139/*
140 * Prepends an ISI header and sends a datagram.
141 */
142static int pn_send(struct sk_buff *skb, struct net_device *dev,
143 u16 dst, u16 src, u8 res, u8 irq)
144{
145 struct phonethdr *ph;
146 int err;
147
148 if (skb->len + 2 > 0xffff) {
149 /* Phonet length field would overflow */
150 err = -EMSGSIZE;
151 goto drop;
152 }
153
154 skb_reset_transport_header(skb);
155 WARN_ON(skb_headroom(skb) & 1); /* HW assumes word alignment */
156 skb_push(skb, sizeof(struct phonethdr));
157 skb_reset_network_header(skb);
158 ph = pn_hdr(skb);
159 ph->pn_rdev = pn_dev(dst);
160 ph->pn_sdev = pn_dev(src);
161 ph->pn_res = res;
162 ph->pn_length = __cpu_to_be16(skb->len + 2 - sizeof(*ph));
163 ph->pn_robj = pn_obj(dst);
164 ph->pn_sobj = pn_obj(src);
165
166 skb->protocol = htons(ETH_P_PHONET);
167 skb->priority = 0;
168 skb->dev = dev;
169
170 if (pn_addr(src) == pn_addr(dst)) {
171 skb_reset_mac_header(skb);
172 skb->pkt_type = PACKET_LOOPBACK;
173 skb_orphan(skb);
174 if (irq)
175 netif_rx(skb);
176 else
177 netif_rx_ni(skb);
178 err = 0;
179 } else {
180 err = dev_hard_header(skb, dev, ntohs(skb->protocol),
181 NULL, NULL, skb->len);
182 if (err < 0) {
183 err = -EHOSTUNREACH;
184 goto drop;
185 }
186 err = dev_queue_xmit(skb);
187 }
188
189 return err;
190drop:
191 kfree_skb(skb);
192 return err;
193}
194
195static int pn_raw_send(const void *data, int len, struct net_device *dev,
196 u16 dst, u16 src, u8 res)
197{
198 struct sk_buff *skb = alloc_skb(MAX_PHONET_HEADER + len, GFP_ATOMIC);
199 if (skb == NULL)
200 return -ENOMEM;
201
202 skb_reserve(skb, MAX_PHONET_HEADER);
203 __skb_put(skb, len);
204 skb_copy_to_linear_data(skb, data, len);
205 return pn_send(skb, dev, dst, src, res, 1);
206}
207
208/*
209 * Create a Phonet header for the skb and send it out. Returns
210 * non-zero error code if failed. The skb is freed then.
211 */
212int pn_skb_send(struct sock *sk, struct sk_buff *skb,
213 const struct sockaddr_pn *target)
214{
215 struct net_device *dev;
216 struct pn_sock *pn = pn_sk(sk);
217 int err;
218 u16 src;
219 u8 daddr = pn_sockaddr_get_addr(target), saddr = PN_NO_ADDR;
220
221 err = -EHOSTUNREACH;
222 if (sk->sk_bound_dev_if)
223 dev = dev_get_by_index(sock_net(sk), sk->sk_bound_dev_if);
224 else
225 dev = phonet_device_get(sock_net(sk));
226 if (!dev || !(dev->flags & IFF_UP))
227 goto drop;
228
229 saddr = phonet_address_get(dev, daddr);
230 if (saddr == PN_NO_ADDR)
231 goto drop;
232
233 src = pn->sobject;
234 if (!pn_addr(src))
235 src = pn_object(saddr, pn_obj(src));
236
237 err = pn_send(skb, dev, pn_sockaddr_get_object(target),
238 src, pn_sockaddr_get_resource(target), 0);
239 dev_put(dev);
240 return err;
241
242drop:
243 kfree_skb(skb);
244 if (dev)
245 dev_put(dev);
246 return err;
247}
248EXPORT_SYMBOL(pn_skb_send);
249
250/* Do not send an error message in response to an error message */
251static inline int can_respond(struct sk_buff *skb)
252{
253 const struct phonethdr *ph;
254 const struct phonetmsg *pm;
255 u8 submsg_id;
256
257 if (!pskb_may_pull(skb, 3))
258 return 0;
259
260 ph = pn_hdr(skb);
261 if (phonet_address_get(skb->dev, ph->pn_rdev) != ph->pn_rdev)
262 return 0; /* we are not the destination */
263 if (ph->pn_res == PN_PREFIX && !pskb_may_pull(skb, 5))
264 return 0;
265
266 ph = pn_hdr(skb); /* re-acquires the pointer */
267 pm = pn_msg(skb);
268 if (pm->pn_msg_id != PN_COMMON_MESSAGE)
269 return 1;
270 submsg_id = (ph->pn_res == PN_PREFIX)
271 ? pm->pn_e_submsg_id : pm->pn_submsg_id;
272 if (submsg_id != PN_COMM_ISA_ENTITY_NOT_REACHABLE_RESP &&
273 pm->pn_e_submsg_id != PN_COMM_SERVICE_NOT_IDENTIFIED_RESP)
274 return 1;
275 return 0;
276}
277
278static int send_obj_unreachable(struct sk_buff *rskb)
279{
280 const struct phonethdr *oph = pn_hdr(rskb);
281 const struct phonetmsg *opm = pn_msg(rskb);
282 struct phonetmsg resp;
283
284 memset(&resp, 0, sizeof(resp));
285 resp.pn_trans_id = opm->pn_trans_id;
286 resp.pn_msg_id = PN_COMMON_MESSAGE;
287 if (oph->pn_res == PN_PREFIX) {
288 resp.pn_e_res_id = opm->pn_e_res_id;
289 resp.pn_e_submsg_id = PN_COMM_ISA_ENTITY_NOT_REACHABLE_RESP;
290 resp.pn_e_orig_msg_id = opm->pn_msg_id;
291 resp.pn_e_status = 0;
292 } else {
293 resp.pn_submsg_id = PN_COMM_ISA_ENTITY_NOT_REACHABLE_RESP;
294 resp.pn_orig_msg_id = opm->pn_msg_id;
295 resp.pn_status = 0;
296 }
297 return pn_raw_send(&resp, sizeof(resp), rskb->dev,
298 pn_object(oph->pn_sdev, oph->pn_sobj),
299 pn_object(oph->pn_rdev, oph->pn_robj),
300 oph->pn_res);
301}
302
303static int send_reset_indications(struct sk_buff *rskb)
304{
305 struct phonethdr *oph = pn_hdr(rskb);
306 static const u8 data[4] = {
307 0x00 /* trans ID */, 0x10 /* subscribe msg */,
308 0x00 /* subscription count */, 0x00 /* dummy */
309 };
310
311 return pn_raw_send(data, sizeof(data), rskb->dev,
312 pn_object(oph->pn_sdev, 0x00),
313 pn_object(oph->pn_rdev, oph->pn_robj), 0x10);
314}
315
316
317/* packet type functions */
318
319/*
320 * Stuff received packets to associated sockets.
321 * On error, returns non-zero and releases the skb.
322 */
323static int phonet_rcv(struct sk_buff *skb, struct net_device *dev,
324 struct packet_type *pkttype,
325 struct net_device *orig_dev)
326{
327 struct phonethdr *ph;
328 struct sock *sk;
329 struct sockaddr_pn sa;
330 u16 len;
331
332 if (dev_net(dev) != &init_net)
333 goto out;
334
335 /* check we have at least a full Phonet header */
336 if (!pskb_pull(skb, sizeof(struct phonethdr)))
337 goto out;
338
339 /* check that the advertised length is correct */
340 ph = pn_hdr(skb);
341 len = get_unaligned_be16(&ph->pn_length);
342 if (len < 2)
343 goto out;
344 len -= 2;
345 if ((len > skb->len) || pskb_trim(skb, len))
346 goto out;
347 skb_reset_transport_header(skb);
348
349 pn_skb_get_dst_sockaddr(skb, &sa);
350 if (pn_sockaddr_get_addr(&sa) == 0)
351 goto out; /* currently, we cannot be device 0 */
352
353 sk = pn_find_sock_by_sa(&sa);
354 if (sk == NULL) {
355 if (can_respond(skb)) {
356 send_obj_unreachable(skb);
357 send_reset_indications(skb);
358 }
359 goto out;
360 }
361
362 /* Push data to the socket (or other sockets connected to it). */
363 return sk_receive_skb(sk, skb, 0);
364
365out:
366 kfree_skb(skb);
367 return NET_RX_DROP;
368}
369
370static struct packet_type phonet_packet_type = {
371 .type = __constant_htons(ETH_P_PHONET),
372 .dev = NULL,
373 .func = phonet_rcv,
374};
375
376/* Transport protocol registration */
377static struct phonet_protocol *proto_tab[PHONET_NPROTO] __read_mostly;
378static DEFINE_SPINLOCK(proto_tab_lock);
379
380int __init_or_module phonet_proto_register(int protocol,
381 struct phonet_protocol *pp)
382{
383 int err = 0;
384
385 if (protocol >= PHONET_NPROTO)
386 return -EINVAL;
387
388 err = proto_register(pp->prot, 1);
389 if (err)
390 return err;
391
392 spin_lock(&proto_tab_lock);
393 if (proto_tab[protocol])
394 err = -EBUSY;
395 else
396 proto_tab[protocol] = pp;
397 spin_unlock(&proto_tab_lock);
398
399 return err;
400}
401EXPORT_SYMBOL(phonet_proto_register);
402
403void phonet_proto_unregister(int protocol, struct phonet_protocol *pp)
404{
405 spin_lock(&proto_tab_lock);
406 BUG_ON(proto_tab[protocol] != pp);
407 proto_tab[protocol] = NULL;
408 spin_unlock(&proto_tab_lock);
409 proto_unregister(pp->prot);
410}
411EXPORT_SYMBOL(phonet_proto_unregister);
412
413static struct phonet_protocol *phonet_proto_get(int protocol)
414{
415 struct phonet_protocol *pp;
416
417 if (protocol >= PHONET_NPROTO)
418 return NULL;
419
420 spin_lock(&proto_tab_lock);
421 pp = proto_tab[protocol];
422 if (pp && !try_module_get(pp->prot->owner))
423 pp = NULL;
424 spin_unlock(&proto_tab_lock);
425
426 return pp;
427}
428
429static inline void phonet_proto_put(struct phonet_protocol *pp)
430{
431 module_put(pp->prot->owner);
432}
433
434/* Module registration */
435static int __init phonet_init(void)
436{
437 int err;
438
439 err = sock_register(&phonet_proto_family);
440 if (err) {
441 printk(KERN_ALERT
442 "phonet protocol family initialization failed\n");
443 return err;
444 }
445
446 phonet_device_init();
447 dev_add_pack(&phonet_packet_type);
448 phonet_netlink_register();
449 phonet_sysctl_init();
450
451 err = isi_register();
452 if (err)
453 goto err;
454 return 0;
455
456err:
457 phonet_sysctl_exit();
458 sock_unregister(PF_PHONET);
459 dev_remove_pack(&phonet_packet_type);
460 phonet_device_exit();
461 return err;
462}
463
464static void __exit phonet_exit(void)
465{
466 isi_unregister();
467 phonet_sysctl_exit();
468 sock_unregister(PF_PHONET);
469 dev_remove_pack(&phonet_packet_type);
470 phonet_device_exit();
471}
472
473module_init(phonet_init);
474module_exit(phonet_exit);
475MODULE_DESCRIPTION("Phonet protocol stack for Linux");
476MODULE_LICENSE("GPL");
477MODULE_ALIAS_NETPROTO(PF_PHONET);
diff --git a/net/phonet/datagram.c b/net/phonet/datagram.c
new file mode 100644
index 000000000000..e087862ed7e4
--- /dev/null
+++ b/net/phonet/datagram.c
@@ -0,0 +1,197 @@
1/*
2 * File: datagram.c
3 *
4 * Datagram (ISI) Phonet sockets
5 *
6 * Copyright (C) 2008 Nokia Corporation.
7 *
8 * Contact: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
9 * Original author: Sakari Ailus <sakari.ailus@nokia.com>
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * version 2 as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 */
25
26#include <linux/kernel.h>
27#include <linux/socket.h>
28#include <asm/ioctls.h>
29#include <net/sock.h>
30
31#include <linux/phonet.h>
32#include <net/phonet/phonet.h>
33
34static int pn_backlog_rcv(struct sock *sk, struct sk_buff *skb);
35
36/* associated socket ceases to exist */
37static void pn_sock_close(struct sock *sk, long timeout)
38{
39 sk_common_release(sk);
40}
41
42static int pn_ioctl(struct sock *sk, int cmd, unsigned long arg)
43{
44 struct sk_buff *skb;
45 int answ;
46
47 switch (cmd) {
48 case SIOCINQ:
49 lock_sock(sk);
50 skb = skb_peek(&sk->sk_receive_queue);
51 answ = skb ? skb->len : 0;
52 release_sock(sk);
53 return put_user(answ, (int __user *)arg);
54 }
55
56 return -ENOIOCTLCMD;
57}
58
59/* Destroy socket. All references are gone. */
60static void pn_destruct(struct sock *sk)
61{
62 skb_queue_purge(&sk->sk_receive_queue);
63}
64
65static int pn_init(struct sock *sk)
66{
67 sk->sk_destruct = pn_destruct;
68 return 0;
69}
70
71static int pn_sendmsg(struct kiocb *iocb, struct sock *sk,
72 struct msghdr *msg, size_t len)
73{
74 struct sockaddr_pn *target;
75 struct sk_buff *skb;
76 int err;
77
78 if (msg->msg_flags & MSG_OOB)
79 return -EOPNOTSUPP;
80
81 if (msg->msg_name == NULL)
82 return -EDESTADDRREQ;
83
84 if (msg->msg_namelen < sizeof(struct sockaddr_pn))
85 return -EINVAL;
86
87 target = (struct sockaddr_pn *)msg->msg_name;
88 if (target->spn_family != AF_PHONET)
89 return -EAFNOSUPPORT;
90
91 skb = sock_alloc_send_skb(sk, MAX_PHONET_HEADER + len,
92 msg->msg_flags & MSG_DONTWAIT, &err);
93 if (skb == NULL)
94 return err;
95 skb_reserve(skb, MAX_PHONET_HEADER);
96
97 err = memcpy_fromiovec((void *)skb_put(skb, len), msg->msg_iov, len);
98 if (err < 0) {
99 kfree_skb(skb);
100 return err;
101 }
102
103 /*
104 * Fill in the Phonet header and
105 * finally pass the packet forwards.
106 */
107 err = pn_skb_send(sk, skb, target);
108
109 /* If ok, return len. */
110 return (err >= 0) ? len : err;
111}
112
113static int pn_recvmsg(struct kiocb *iocb, struct sock *sk,
114 struct msghdr *msg, size_t len, int noblock,
115 int flags, int *addr_len)
116{
117 struct sk_buff *skb = NULL;
118 struct sockaddr_pn sa;
119 int rval = -EOPNOTSUPP;
120 int copylen;
121
122 if (flags & MSG_OOB)
123 goto out_nofree;
124
125 if (addr_len)
126 *addr_len = sizeof(sa);
127
128 skb = skb_recv_datagram(sk, flags, noblock, &rval);
129 if (skb == NULL)
130 goto out_nofree;
131
132 pn_skb_get_src_sockaddr(skb, &sa);
133
134 copylen = skb->len;
135 if (len < copylen) {
136 msg->msg_flags |= MSG_TRUNC;
137 copylen = len;
138 }
139
140 rval = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copylen);
141 if (rval) {
142 rval = -EFAULT;
143 goto out;
144 }
145
146 rval = (flags & MSG_TRUNC) ? skb->len : copylen;
147
148 if (msg->msg_name != NULL)
149 memcpy(msg->msg_name, &sa, sizeof(struct sockaddr_pn));
150
151out:
152 skb_free_datagram(sk, skb);
153
154out_nofree:
155 return rval;
156}
157
158/* Queue an skb for a sock. */
159static int pn_backlog_rcv(struct sock *sk, struct sk_buff *skb)
160{
161 int err = sock_queue_rcv_skb(sk, skb);
162 if (err < 0)
163 kfree_skb(skb);
164 return err ? NET_RX_DROP : NET_RX_SUCCESS;
165}
166
167/* Module registration */
168static struct proto pn_proto = {
169 .close = pn_sock_close,
170 .ioctl = pn_ioctl,
171 .init = pn_init,
172 .sendmsg = pn_sendmsg,
173 .recvmsg = pn_recvmsg,
174 .backlog_rcv = pn_backlog_rcv,
175 .hash = pn_sock_hash,
176 .unhash = pn_sock_unhash,
177 .get_port = pn_sock_get_port,
178 .obj_size = sizeof(struct pn_sock),
179 .owner = THIS_MODULE,
180 .name = "PHONET",
181};
182
183static struct phonet_protocol pn_dgram_proto = {
184 .ops = &phonet_dgram_ops,
185 .prot = &pn_proto,
186 .sock_type = SOCK_DGRAM,
187};
188
189int __init isi_register(void)
190{
191 return phonet_proto_register(PN_PROTO_PHONET, &pn_dgram_proto);
192}
193
194void __exit isi_unregister(void)
195{
196 phonet_proto_unregister(PN_PROTO_PHONET, &pn_dgram_proto);
197}
diff --git a/net/phonet/pep-gprs.c b/net/phonet/pep-gprs.c
new file mode 100644
index 000000000000..9978afbd9f2a
--- /dev/null
+++ b/net/phonet/pep-gprs.c
@@ -0,0 +1,347 @@
1/*
2 * File: pep-gprs.c
3 *
4 * GPRS over Phonet pipe end point socket
5 *
6 * Copyright (C) 2008 Nokia Corporation.
7 *
8 * Author: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * version 2 as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 */
24
25#include <linux/kernel.h>
26#include <linux/netdevice.h>
27#include <linux/if_ether.h>
28#include <linux/if_arp.h>
29#include <net/sock.h>
30
31#include <linux/if_phonet.h>
32#include <net/tcp_states.h>
33#include <net/phonet/gprs.h>
34
35#define GPRS_DEFAULT_MTU 1400
36
37struct gprs_dev {
38 struct sock *sk;
39 void (*old_state_change)(struct sock *);
40 void (*old_data_ready)(struct sock *, int);
41 void (*old_write_space)(struct sock *);
42
43 struct net_device *net;
44 struct net_device_stats stats;
45
46 struct sk_buff_head tx_queue;
47 struct work_struct tx_work;
48 spinlock_t tx_lock;
49 unsigned tx_max;
50};
51
52static int gprs_type_trans(struct sk_buff *skb)
53{
54 const u8 *pvfc;
55 u8 buf;
56
57 pvfc = skb_header_pointer(skb, 0, 1, &buf);
58 if (!pvfc)
59 return 0;
60 /* Look at IP version field */
61 switch (*pvfc >> 4) {
62 case 4:
63 return htons(ETH_P_IP);
64 case 6:
65 return htons(ETH_P_IPV6);
66 }
67 return 0;
68}
69
70/*
71 * Socket callbacks
72 */
73
74static void gprs_state_change(struct sock *sk)
75{
76 struct gprs_dev *dev = sk->sk_user_data;
77
78 if (sk->sk_state == TCP_CLOSE_WAIT) {
79 netif_stop_queue(dev->net);
80 netif_carrier_off(dev->net);
81 }
82}
83
84static int gprs_recv(struct gprs_dev *dev, struct sk_buff *skb)
85{
86 int err = 0;
87 u16 protocol = gprs_type_trans(skb);
88
89 if (!protocol) {
90 err = -EINVAL;
91 goto drop;
92 }
93
94 if (likely(skb_headroom(skb) & 3)) {
95 struct sk_buff *rskb, *fs;
96 int flen = 0;
97
98 /* Phonet Pipe data header is misaligned (3 bytes),
99 * so wrap the IP packet as a single fragment of an head-less
100 * socket buffer. The network stack will pull what it needs,
101 * but at least, the whole IP payload is not memcpy'd. */
102 rskb = netdev_alloc_skb(dev->net, 0);
103 if (!rskb) {
104 err = -ENOBUFS;
105 goto drop;
106 }
107 skb_shinfo(rskb)->frag_list = skb;
108 rskb->len += skb->len;
109 rskb->data_len += rskb->len;
110 rskb->truesize += rskb->len;
111
112 /* Avoid nested fragments */
113 for (fs = skb_shinfo(skb)->frag_list; fs; fs = fs->next)
114 flen += fs->len;
115 skb->next = skb_shinfo(skb)->frag_list;
116 skb_shinfo(skb)->frag_list = NULL;
117 skb->len -= flen;
118 skb->data_len -= flen;
119 skb->truesize -= flen;
120
121 skb = rskb;
122 }
123
124 skb->protocol = protocol;
125 skb_reset_mac_header(skb);
126 skb->dev = dev->net;
127
128 if (likely(dev->net->flags & IFF_UP)) {
129 dev->stats.rx_packets++;
130 dev->stats.rx_bytes += skb->len;
131 netif_rx(skb);
132 skb = NULL;
133 } else
134 err = -ENODEV;
135
136drop:
137 if (skb) {
138 dev_kfree_skb(skb);
139 dev->stats.rx_dropped++;
140 }
141 return err;
142}
143
144static void gprs_data_ready(struct sock *sk, int len)
145{
146 struct gprs_dev *dev = sk->sk_user_data;
147 struct sk_buff *skb;
148
149 while ((skb = pep_read(sk)) != NULL) {
150 skb_orphan(skb);
151 gprs_recv(dev, skb);
152 }
153}
154
155static void gprs_write_space(struct sock *sk)
156{
157 struct gprs_dev *dev = sk->sk_user_data;
158 unsigned credits = pep_writeable(sk);
159
160 spin_lock_bh(&dev->tx_lock);
161 dev->tx_max = credits;
162 if (credits > skb_queue_len(&dev->tx_queue))
163 netif_wake_queue(dev->net);
164 spin_unlock_bh(&dev->tx_lock);
165}
166
167/*
168 * Network device callbacks
169 */
170
171static int gprs_xmit(struct sk_buff *skb, struct net_device *net)
172{
173 struct gprs_dev *dev = netdev_priv(net);
174
175 switch (skb->protocol) {
176 case htons(ETH_P_IP):
177 case htons(ETH_P_IPV6):
178 break;
179 default:
180 dev_kfree_skb(skb);
181 return 0;
182 }
183
184 spin_lock(&dev->tx_lock);
185 if (likely(skb_queue_len(&dev->tx_queue) < dev->tx_max)) {
186 skb_queue_tail(&dev->tx_queue, skb);
187 skb = NULL;
188 }
189 if (skb_queue_len(&dev->tx_queue) >= dev->tx_max)
190 netif_stop_queue(net);
191 spin_unlock(&dev->tx_lock);
192
193 schedule_work(&dev->tx_work);
194 if (unlikely(skb))
195 dev_kfree_skb(skb);
196 return 0;
197}
198
199static void gprs_tx(struct work_struct *work)
200{
201 struct gprs_dev *dev = container_of(work, struct gprs_dev, tx_work);
202 struct sock *sk = dev->sk;
203 struct sk_buff *skb;
204
205 while ((skb = skb_dequeue(&dev->tx_queue)) != NULL) {
206 int err;
207
208 dev->stats.tx_bytes += skb->len;
209 dev->stats.tx_packets++;
210
211 skb_orphan(skb);
212 skb_set_owner_w(skb, sk);
213
214 lock_sock(sk);
215 err = pep_write(sk, skb);
216 if (err) {
217 LIMIT_NETDEBUG(KERN_WARNING"%s: TX error (%d)\n",
218 dev->net->name, err);
219 dev->stats.tx_aborted_errors++;
220 dev->stats.tx_errors++;
221 }
222 release_sock(sk);
223 }
224
225 lock_sock(sk);
226 gprs_write_space(sk);
227 release_sock(sk);
228}
229
230static int gprs_set_mtu(struct net_device *net, int new_mtu)
231{
232 if ((new_mtu < 576) || (new_mtu > (PHONET_MAX_MTU - 11)))
233 return -EINVAL;
234
235 net->mtu = new_mtu;
236 return 0;
237}
238
239static struct net_device_stats *gprs_get_stats(struct net_device *net)
240{
241 struct gprs_dev *dev = netdev_priv(net);
242
243 return &dev->stats;
244}
245
246static void gprs_setup(struct net_device *net)
247{
248 net->features = NETIF_F_FRAGLIST;
249 net->type = ARPHRD_NONE;
250 net->flags = IFF_POINTOPOINT | IFF_NOARP;
251 net->mtu = GPRS_DEFAULT_MTU;
252 net->hard_header_len = 0;
253 net->addr_len = 0;
254 net->tx_queue_len = 10;
255
256 net->destructor = free_netdev;
257 net->hard_start_xmit = gprs_xmit; /* mandatory */
258 net->change_mtu = gprs_set_mtu;
259 net->get_stats = gprs_get_stats;
260}
261
262/*
263 * External interface
264 */
265
266/*
267 * Attach a GPRS interface to a datagram socket.
268 * Returns the interface index on success, negative error code on error.
269 */
270int gprs_attach(struct sock *sk)
271{
272 static const char ifname[] = "gprs%d";
273 struct gprs_dev *dev;
274 struct net_device *net;
275 int err;
276
277 if (unlikely(sk->sk_type == SOCK_STREAM))
278 return -EINVAL; /* need packet boundaries */
279
280 /* Create net device */
281 net = alloc_netdev(sizeof(*dev), ifname, gprs_setup);
282 if (!net)
283 return -ENOMEM;
284 dev = netdev_priv(net);
285 dev->net = net;
286 dev->tx_max = 0;
287 spin_lock_init(&dev->tx_lock);
288 skb_queue_head_init(&dev->tx_queue);
289 INIT_WORK(&dev->tx_work, gprs_tx);
290
291 netif_stop_queue(net);
292 err = register_netdev(net);
293 if (err) {
294 free_netdev(net);
295 return err;
296 }
297
298 lock_sock(sk);
299 if (unlikely(sk->sk_user_data)) {
300 err = -EBUSY;
301 goto out_rel;
302 }
303 if (unlikely((1 << sk->sk_state & (TCPF_CLOSE|TCPF_LISTEN)) ||
304 sock_flag(sk, SOCK_DEAD))) {
305 err = -EINVAL;
306 goto out_rel;
307 }
308 sk->sk_user_data = dev;
309 dev->old_state_change = sk->sk_state_change;
310 dev->old_data_ready = sk->sk_data_ready;
311 dev->old_write_space = sk->sk_write_space;
312 sk->sk_state_change = gprs_state_change;
313 sk->sk_data_ready = gprs_data_ready;
314 sk->sk_write_space = gprs_write_space;
315 release_sock(sk);
316
317 sock_hold(sk);
318 dev->sk = sk;
319
320 printk(KERN_DEBUG"%s: attached\n", net->name);
321 gprs_write_space(sk); /* kick off TX */
322 return net->ifindex;
323
324out_rel:
325 release_sock(sk);
326 unregister_netdev(net);
327 return err;
328}
329
330void gprs_detach(struct sock *sk)
331{
332 struct gprs_dev *dev = sk->sk_user_data;
333 struct net_device *net = dev->net;
334
335 lock_sock(sk);
336 sk->sk_user_data = NULL;
337 sk->sk_state_change = dev->old_state_change;
338 sk->sk_data_ready = dev->old_data_ready;
339 sk->sk_write_space = dev->old_write_space;
340 release_sock(sk);
341
342 printk(KERN_DEBUG"%s: detached\n", net->name);
343 unregister_netdev(net);
344 flush_scheduled_work();
345 sock_put(sk);
346 skb_queue_purge(&dev->tx_queue);
347}
diff --git a/net/phonet/pep.c b/net/phonet/pep.c
new file mode 100644
index 000000000000..bc6d50f83249
--- /dev/null
+++ b/net/phonet/pep.c
@@ -0,0 +1,1076 @@
1/*
2 * File: pep.c
3 *
4 * Phonet pipe protocol end point socket
5 *
6 * Copyright (C) 2008 Nokia Corporation.
7 *
8 * Author: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * version 2 as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 */
24
25#include <linux/kernel.h>
26#include <linux/socket.h>
27#include <net/sock.h>
28#include <net/tcp_states.h>
29#include <asm/ioctls.h>
30
31#include <linux/phonet.h>
32#include <net/phonet/phonet.h>
33#include <net/phonet/pep.h>
34#include <net/phonet/gprs.h>
35
36/* sk_state values:
37 * TCP_CLOSE sock not in use yet
38 * TCP_CLOSE_WAIT disconnected pipe
39 * TCP_LISTEN listening pipe endpoint
40 * TCP_SYN_RECV connected pipe in disabled state
41 * TCP_ESTABLISHED connected pipe in enabled state
42 *
43 * pep_sock locking:
44 * - sk_state, ackq, hlist: sock lock needed
45 * - listener: read only
46 * - pipe_handle: read only
47 */
48
49#define CREDITS_MAX 10
50#define CREDITS_THR 7
51
52static const struct sockaddr_pn pipe_srv = {
53 .spn_family = AF_PHONET,
54 .spn_resource = 0xD9, /* pipe service */
55};
56
57#define pep_sb_size(s) (((s) + 5) & ~3) /* 2-bytes head, 32-bits aligned */
58
59/* Get the next TLV sub-block. */
60static unsigned char *pep_get_sb(struct sk_buff *skb, u8 *ptype, u8 *plen,
61 void *buf)
62{
63 void *data = NULL;
64 struct {
65 u8 sb_type;
66 u8 sb_len;
67 } *ph, h;
68 int buflen = *plen;
69
70 ph = skb_header_pointer(skb, 0, 2, &h);
71 if (ph == NULL || ph->sb_len < 2 || !pskb_may_pull(skb, ph->sb_len))
72 return NULL;
73 ph->sb_len -= 2;
74 *ptype = ph->sb_type;
75 *plen = ph->sb_len;
76
77 if (buflen > ph->sb_len)
78 buflen = ph->sb_len;
79 data = skb_header_pointer(skb, 2, buflen, buf);
80 __skb_pull(skb, 2 + ph->sb_len);
81 return data;
82}
83
84static int pep_reply(struct sock *sk, struct sk_buff *oskb,
85 u8 code, const void *data, int len, gfp_t priority)
86{
87 const struct pnpipehdr *oph = pnp_hdr(oskb);
88 struct pnpipehdr *ph;
89 struct sk_buff *skb;
90
91 skb = alloc_skb(MAX_PNPIPE_HEADER + len, priority);
92 if (!skb)
93 return -ENOMEM;
94 skb_set_owner_w(skb, sk);
95
96 skb_reserve(skb, MAX_PNPIPE_HEADER);
97 __skb_put(skb, len);
98 skb_copy_to_linear_data(skb, data, len);
99 __skb_push(skb, sizeof(*ph));
100 skb_reset_transport_header(skb);
101 ph = pnp_hdr(skb);
102 ph->utid = oph->utid;
103 ph->message_id = oph->message_id + 1; /* REQ -> RESP */
104 ph->pipe_handle = oph->pipe_handle;
105 ph->error_code = code;
106
107 return pn_skb_send(sk, skb, &pipe_srv);
108}
109
110#define PAD 0x00
111static int pep_accept_conn(struct sock *sk, struct sk_buff *skb)
112{
113 static const u8 data[20] = {
114 PAD, PAD, PAD, 2 /* sub-blocks */,
115 PN_PIPE_SB_REQUIRED_FC_TX, pep_sb_size(5), 3, PAD,
116 PN_MULTI_CREDIT_FLOW_CONTROL,
117 PN_ONE_CREDIT_FLOW_CONTROL,
118 PN_LEGACY_FLOW_CONTROL,
119 PAD,
120 PN_PIPE_SB_PREFERRED_FC_RX, pep_sb_size(5), 3, PAD,
121 PN_MULTI_CREDIT_FLOW_CONTROL,
122 PN_ONE_CREDIT_FLOW_CONTROL,
123 PN_LEGACY_FLOW_CONTROL,
124 PAD,
125 };
126
127 might_sleep();
128 return pep_reply(sk, skb, PN_PIPE_NO_ERROR, data, sizeof(data),
129 GFP_KERNEL);
130}
131
132static int pep_reject_conn(struct sock *sk, struct sk_buff *skb, u8 code)
133{
134 static const u8 data[4] = { PAD, PAD, PAD, 0 /* sub-blocks */ };
135 WARN_ON(code == PN_PIPE_NO_ERROR);
136 return pep_reply(sk, skb, code, data, sizeof(data), GFP_ATOMIC);
137}
138
139/* Control requests are not sent by the pipe service and have a specific
140 * message format. */
141static int pep_ctrlreq_error(struct sock *sk, struct sk_buff *oskb, u8 code,
142 gfp_t priority)
143{
144 const struct pnpipehdr *oph = pnp_hdr(oskb);
145 struct sk_buff *skb;
146 struct pnpipehdr *ph;
147 struct sockaddr_pn dst;
148
149 skb = alloc_skb(MAX_PNPIPE_HEADER + 4, priority);
150 if (!skb)
151 return -ENOMEM;
152 skb_set_owner_w(skb, sk);
153
154 skb_reserve(skb, MAX_PHONET_HEADER);
155 ph = (struct pnpipehdr *)skb_put(skb, sizeof(*ph) + 4);
156
157 ph->utid = oph->utid;
158 ph->message_id = PNS_PEP_CTRL_RESP;
159 ph->pipe_handle = oph->pipe_handle;
160 ph->data[0] = oph->data[1]; /* CTRL id */
161 ph->data[1] = oph->data[0]; /* PEP type */
162 ph->data[2] = code; /* error code, at an usual offset */
163 ph->data[3] = PAD;
164 ph->data[4] = PAD;
165
166 pn_skb_get_src_sockaddr(oskb, &dst);
167 return pn_skb_send(sk, skb, &dst);
168}
169
170static int pipe_snd_status(struct sock *sk, u8 type, u8 status, gfp_t priority)
171{
172 struct pep_sock *pn = pep_sk(sk);
173 struct pnpipehdr *ph;
174 struct sk_buff *skb;
175
176 skb = alloc_skb(MAX_PNPIPE_HEADER + 4, priority);
177 if (!skb)
178 return -ENOMEM;
179 skb_set_owner_w(skb, sk);
180
181 skb_reserve(skb, MAX_PNPIPE_HEADER + 4);
182 __skb_push(skb, sizeof(*ph) + 4);
183 skb_reset_transport_header(skb);
184 ph = pnp_hdr(skb);
185 ph->utid = 0;
186 ph->message_id = PNS_PEP_STATUS_IND;
187 ph->pipe_handle = pn->pipe_handle;
188 ph->pep_type = PN_PEP_TYPE_COMMON;
189 ph->data[1] = type;
190 ph->data[2] = PAD;
191 ph->data[3] = PAD;
192 ph->data[4] = status;
193
194 return pn_skb_send(sk, skb, &pipe_srv);
195}
196
197/* Send our RX flow control information to the sender.
198 * Socket must be locked. */
199static void pipe_grant_credits(struct sock *sk)
200{
201 struct pep_sock *pn = pep_sk(sk);
202
203 BUG_ON(sk->sk_state != TCP_ESTABLISHED);
204
205 switch (pn->rx_fc) {
206 case PN_LEGACY_FLOW_CONTROL: /* TODO */
207 break;
208 case PN_ONE_CREDIT_FLOW_CONTROL:
209 pipe_snd_status(sk, PN_PEP_IND_FLOW_CONTROL,
210 PEP_IND_READY, GFP_ATOMIC);
211 pn->rx_credits = 1;
212 break;
213 case PN_MULTI_CREDIT_FLOW_CONTROL:
214 if ((pn->rx_credits + CREDITS_THR) > CREDITS_MAX)
215 break;
216 if (pipe_snd_status(sk, PN_PEP_IND_ID_MCFC_GRANT_CREDITS,
217 CREDITS_MAX - pn->rx_credits,
218 GFP_ATOMIC) == 0)
219 pn->rx_credits = CREDITS_MAX;
220 break;
221 }
222}
223
224static int pipe_rcv_status(struct sock *sk, struct sk_buff *skb)
225{
226 struct pep_sock *pn = pep_sk(sk);
227 struct pnpipehdr *hdr = pnp_hdr(skb);
228
229 if (!pskb_may_pull(skb, sizeof(*hdr) + 4))
230 return -EINVAL;
231
232 if (hdr->data[0] != PN_PEP_TYPE_COMMON) {
233 LIMIT_NETDEBUG(KERN_DEBUG"Phonet unknown PEP type: %u\n",
234 (unsigned)hdr->data[0]);
235 return -EOPNOTSUPP;
236 }
237
238 switch (hdr->data[1]) {
239 case PN_PEP_IND_FLOW_CONTROL:
240 switch (pn->tx_fc) {
241 case PN_LEGACY_FLOW_CONTROL:
242 switch (hdr->data[4]) {
243 case PEP_IND_BUSY:
244 pn->tx_credits = 0;
245 break;
246 case PEP_IND_READY:
247 pn->tx_credits = 1;
248 break;
249 }
250 break;
251 case PN_ONE_CREDIT_FLOW_CONTROL:
252 if (hdr->data[4] == PEP_IND_READY)
253 pn->tx_credits = 1;
254 break;
255 }
256 break;
257
258 case PN_PEP_IND_ID_MCFC_GRANT_CREDITS:
259 if (pn->tx_fc != PN_MULTI_CREDIT_FLOW_CONTROL)
260 break;
261 if (pn->tx_credits + hdr->data[4] > 0xff)
262 pn->tx_credits = 0xff;
263 else
264 pn->tx_credits += hdr->data[4];
265 break;
266
267 default:
268 LIMIT_NETDEBUG(KERN_DEBUG"Phonet unknown PEP indication: %u\n",
269 (unsigned)hdr->data[1]);
270 return -EOPNOTSUPP;
271 }
272 if (pn->tx_credits)
273 sk->sk_write_space(sk);
274 return 0;
275}
276
277static int pipe_rcv_created(struct sock *sk, struct sk_buff *skb)
278{
279 struct pep_sock *pn = pep_sk(sk);
280 struct pnpipehdr *hdr = pnp_hdr(skb);
281 u8 n_sb = hdr->data[0];
282
283 pn->rx_fc = pn->tx_fc = PN_LEGACY_FLOW_CONTROL;
284 __skb_pull(skb, sizeof(*hdr));
285 while (n_sb > 0) {
286 u8 type, buf[2], len = sizeof(buf);
287 u8 *data = pep_get_sb(skb, &type, &len, buf);
288
289 if (data == NULL)
290 return -EINVAL;
291 switch (type) {
292 case PN_PIPE_SB_NEGOTIATED_FC:
293 if (len < 2 || (data[0] | data[1]) > 3)
294 break;
295 pn->tx_fc = data[0] & 3;
296 pn->rx_fc = data[1] & 3;
297 break;
298 }
299 n_sb--;
300 }
301 return 0;
302}
303
304/* Queue an skb to a connected sock.
305 * Socket lock must be held. */
306static int pipe_do_rcv(struct sock *sk, struct sk_buff *skb)
307{
308 struct pep_sock *pn = pep_sk(sk);
309 struct pnpipehdr *hdr = pnp_hdr(skb);
310 struct sk_buff_head *queue;
311 int err = 0;
312
313 BUG_ON(sk->sk_state == TCP_CLOSE_WAIT);
314
315 switch (hdr->message_id) {
316 case PNS_PEP_CONNECT_REQ:
317 pep_reject_conn(sk, skb, PN_PIPE_ERR_PEP_IN_USE);
318 break;
319
320 case PNS_PEP_DISCONNECT_REQ:
321 pep_reply(sk, skb, PN_PIPE_NO_ERROR, NULL, 0, GFP_ATOMIC);
322 sk->sk_state = TCP_CLOSE_WAIT;
323 if (!sock_flag(sk, SOCK_DEAD))
324 sk->sk_state_change(sk);
325 break;
326
327 case PNS_PEP_ENABLE_REQ:
328 /* Wait for PNS_PIPE_(ENABLED|REDIRECTED)_IND */
329 pep_reply(sk, skb, PN_PIPE_NO_ERROR, NULL, 0, GFP_ATOMIC);
330 break;
331
332 case PNS_PEP_RESET_REQ:
333 switch (hdr->state_after_reset) {
334 case PN_PIPE_DISABLE:
335 pn->init_enable = 0;
336 break;
337 case PN_PIPE_ENABLE:
338 pn->init_enable = 1;
339 break;
340 default: /* not allowed to send an error here!? */
341 err = -EINVAL;
342 goto out;
343 }
344 /* fall through */
345 case PNS_PEP_DISABLE_REQ:
346 pn->tx_credits = 0;
347 pep_reply(sk, skb, PN_PIPE_NO_ERROR, NULL, 0, GFP_ATOMIC);
348 break;
349
350 case PNS_PEP_CTRL_REQ:
351 if (skb_queue_len(&pn->ctrlreq_queue) >= PNPIPE_CTRLREQ_MAX)
352 break;
353 __skb_pull(skb, 4);
354 queue = &pn->ctrlreq_queue;
355 goto queue;
356
357 case PNS_PIPE_DATA:
358 __skb_pull(skb, 3); /* Pipe data header */
359 if (!pn_flow_safe(pn->rx_fc)) {
360 err = sock_queue_rcv_skb(sk, skb);
361 if (!err)
362 return 0;
363 break;
364 }
365
366 if (pn->rx_credits == 0) {
367 err = -ENOBUFS;
368 break;
369 }
370 pn->rx_credits--;
371 queue = &sk->sk_receive_queue;
372 goto queue;
373
374 case PNS_PEP_STATUS_IND:
375 pipe_rcv_status(sk, skb);
376 break;
377
378 case PNS_PIPE_REDIRECTED_IND:
379 err = pipe_rcv_created(sk, skb);
380 break;
381
382 case PNS_PIPE_CREATED_IND:
383 err = pipe_rcv_created(sk, skb);
384 if (err)
385 break;
386 /* fall through */
387 case PNS_PIPE_RESET_IND:
388 if (!pn->init_enable)
389 break;
390 /* fall through */
391 case PNS_PIPE_ENABLED_IND:
392 if (!pn_flow_safe(pn->tx_fc)) {
393 pn->tx_credits = 1;
394 sk->sk_write_space(sk);
395 }
396 if (sk->sk_state == TCP_ESTABLISHED)
397 break; /* Nothing to do */
398 sk->sk_state = TCP_ESTABLISHED;
399 pipe_grant_credits(sk);
400 break;
401
402 case PNS_PIPE_DISABLED_IND:
403 sk->sk_state = TCP_SYN_RECV;
404 pn->rx_credits = 0;
405 break;
406
407 default:
408 LIMIT_NETDEBUG(KERN_DEBUG"Phonet unknown PEP message: %u\n",
409 hdr->message_id);
410 err = -EINVAL;
411 }
412out:
413 kfree_skb(skb);
414 return err;
415
416queue:
417 skb->dev = NULL;
418 skb_set_owner_r(skb, sk);
419 err = skb->len;
420 skb_queue_tail(queue, skb);
421 if (!sock_flag(sk, SOCK_DEAD))
422 sk->sk_data_ready(sk, err);
423 return 0;
424}
425
426/* Destroy connected sock. */
427static void pipe_destruct(struct sock *sk)
428{
429 struct pep_sock *pn = pep_sk(sk);
430
431 skb_queue_purge(&sk->sk_receive_queue);
432 skb_queue_purge(&pn->ctrlreq_queue);
433}
434
435static int pep_connreq_rcv(struct sock *sk, struct sk_buff *skb)
436{
437 struct sock *newsk;
438 struct pep_sock *newpn, *pn = pep_sk(sk);
439 struct pnpipehdr *hdr;
440 struct sockaddr_pn dst;
441 u16 peer_type;
442 u8 pipe_handle, enabled, n_sb;
443
444 if (!pskb_pull(skb, sizeof(*hdr) + 4))
445 return -EINVAL;
446
447 hdr = pnp_hdr(skb);
448 pipe_handle = hdr->pipe_handle;
449 switch (hdr->state_after_connect) {
450 case PN_PIPE_DISABLE:
451 enabled = 0;
452 break;
453 case PN_PIPE_ENABLE:
454 enabled = 1;
455 break;
456 default:
457 pep_reject_conn(sk, skb, PN_PIPE_ERR_INVALID_PARAM);
458 return -EINVAL;
459 }
460 peer_type = hdr->other_pep_type << 8;
461
462 if (unlikely(sk->sk_state != TCP_LISTEN) || sk_acceptq_is_full(sk)) {
463 pep_reject_conn(sk, skb, PN_PIPE_ERR_PEP_IN_USE);
464 return -ENOBUFS;
465 }
466
467 /* Parse sub-blocks (options) */
468 n_sb = hdr->data[4];
469 while (n_sb > 0) {
470 u8 type, buf[1], len = sizeof(buf);
471 const u8 *data = pep_get_sb(skb, &type, &len, buf);
472
473 if (data == NULL)
474 return -EINVAL;
475 switch (type) {
476 case PN_PIPE_SB_CONNECT_REQ_PEP_SUB_TYPE:
477 if (len < 1)
478 return -EINVAL;
479 peer_type = (peer_type & 0xff00) | data[0];
480 break;
481 }
482 n_sb--;
483 }
484
485 skb = skb_clone(skb, GFP_ATOMIC);
486 if (!skb)
487 return -ENOMEM;
488
489 /* Create a new to-be-accepted sock */
490 newsk = sk_alloc(sock_net(sk), PF_PHONET, GFP_ATOMIC, sk->sk_prot);
491 if (!newsk) {
492 kfree_skb(skb);
493 return -ENOMEM;
494 }
495 sock_init_data(NULL, newsk);
496 newsk->sk_state = TCP_SYN_RECV;
497 newsk->sk_backlog_rcv = pipe_do_rcv;
498 newsk->sk_protocol = sk->sk_protocol;
499 newsk->sk_destruct = pipe_destruct;
500
501 newpn = pep_sk(newsk);
502 pn_skb_get_dst_sockaddr(skb, &dst);
503 newpn->pn_sk.sobject = pn_sockaddr_get_object(&dst);
504 newpn->pn_sk.resource = pn->pn_sk.resource;
505 skb_queue_head_init(&newpn->ctrlreq_queue);
506 newpn->pipe_handle = pipe_handle;
507 newpn->peer_type = peer_type;
508 newpn->rx_credits = newpn->tx_credits = 0;
509 newpn->rx_fc = newpn->tx_fc = PN_LEGACY_FLOW_CONTROL;
510 newpn->init_enable = enabled;
511
512 BUG_ON(!skb_queue_empty(&newsk->sk_receive_queue));
513 skb_queue_head(&newsk->sk_receive_queue, skb);
514 if (!sock_flag(sk, SOCK_DEAD))
515 sk->sk_data_ready(sk, 0);
516
517 sk_acceptq_added(sk);
518 sk_add_node(newsk, &pn->ackq);
519 return 0;
520}
521
522/* Listening sock must be locked */
523static struct sock *pep_find_pipe(const struct hlist_head *hlist,
524 const struct sockaddr_pn *dst,
525 u8 pipe_handle)
526{
527 struct hlist_node *node;
528 struct sock *sknode;
529 u16 dobj = pn_sockaddr_get_object(dst);
530
531 sk_for_each(sknode, node, hlist) {
532 struct pep_sock *pnnode = pep_sk(sknode);
533
534 /* Ports match, but addresses might not: */
535 if (pnnode->pn_sk.sobject != dobj)
536 continue;
537 if (pnnode->pipe_handle != pipe_handle)
538 continue;
539 if (sknode->sk_state == TCP_CLOSE_WAIT)
540 continue;
541
542 sock_hold(sknode);
543 return sknode;
544 }
545 return NULL;
546}
547
548/*
549 * Deliver an skb to a listening sock.
550 * Socket lock must be held.
551 * We then queue the skb to the right connected sock (if any).
552 */
553static int pep_do_rcv(struct sock *sk, struct sk_buff *skb)
554{
555 struct pep_sock *pn = pep_sk(sk);
556 struct sock *sknode;
557 struct pnpipehdr *hdr = pnp_hdr(skb);
558 struct sockaddr_pn dst;
559 int err = NET_RX_SUCCESS;
560 u8 pipe_handle;
561
562 if (!pskb_may_pull(skb, sizeof(*hdr)))
563 goto drop;
564
565 hdr = pnp_hdr(skb);
566 pipe_handle = hdr->pipe_handle;
567 if (pipe_handle == PN_PIPE_INVALID_HANDLE)
568 goto drop;
569
570 pn_skb_get_dst_sockaddr(skb, &dst);
571
572 /* Look for an existing pipe handle */
573 sknode = pep_find_pipe(&pn->hlist, &dst, pipe_handle);
574 if (sknode)
575 return sk_receive_skb(sknode, skb, 1);
576
577 /* Look for a pipe handle pending accept */
578 sknode = pep_find_pipe(&pn->ackq, &dst, pipe_handle);
579 if (sknode) {
580 sock_put(sknode);
581 if (net_ratelimit())
582 printk(KERN_WARNING"Phonet unconnected PEP ignored");
583 err = NET_RX_DROP;
584 goto drop;
585 }
586
587 switch (hdr->message_id) {
588 case PNS_PEP_CONNECT_REQ:
589 err = pep_connreq_rcv(sk, skb);
590 break;
591
592 case PNS_PEP_DISCONNECT_REQ:
593 pep_reply(sk, skb, PN_PIPE_NO_ERROR, NULL, 0, GFP_ATOMIC);
594 break;
595
596 case PNS_PEP_CTRL_REQ:
597 pep_ctrlreq_error(sk, skb, PN_PIPE_INVALID_HANDLE, GFP_ATOMIC);
598 break;
599
600 case PNS_PEP_RESET_REQ:
601 case PNS_PEP_ENABLE_REQ:
602 case PNS_PEP_DISABLE_REQ:
603 /* invalid handle is not even allowed here! */
604 default:
605 err = NET_RX_DROP;
606 }
607drop:
608 kfree_skb(skb);
609 return err;
610}
611
612/* associated socket ceases to exist */
613static void pep_sock_close(struct sock *sk, long timeout)
614{
615 struct pep_sock *pn = pep_sk(sk);
616 int ifindex = 0;
617
618 sk_common_release(sk);
619
620 lock_sock(sk);
621 if (sk->sk_state == TCP_LISTEN) {
622 /* Destroy the listen queue */
623 struct sock *sknode;
624 struct hlist_node *p, *n;
625
626 sk_for_each_safe(sknode, p, n, &pn->ackq)
627 sk_del_node_init(sknode);
628 sk->sk_state = TCP_CLOSE;
629 }
630 ifindex = pn->ifindex;
631 pn->ifindex = 0;
632 release_sock(sk);
633
634 if (ifindex)
635 gprs_detach(sk);
636}
637
638static int pep_wait_connreq(struct sock *sk, int noblock)
639{
640 struct task_struct *tsk = current;
641 struct pep_sock *pn = pep_sk(sk);
642 long timeo = sock_rcvtimeo(sk, noblock);
643
644 for (;;) {
645 DEFINE_WAIT(wait);
646
647 if (sk->sk_state != TCP_LISTEN)
648 return -EINVAL;
649 if (!hlist_empty(&pn->ackq))
650 break;
651 if (!timeo)
652 return -EWOULDBLOCK;
653 if (signal_pending(tsk))
654 return sock_intr_errno(timeo);
655
656 prepare_to_wait_exclusive(&sk->sk_socket->wait, &wait,
657 TASK_INTERRUPTIBLE);
658 release_sock(sk);
659 timeo = schedule_timeout(timeo);
660 lock_sock(sk);
661 finish_wait(&sk->sk_socket->wait, &wait);
662 }
663
664 return 0;
665}
666
667static struct sock *pep_sock_accept(struct sock *sk, int flags, int *errp)
668{
669 struct pep_sock *pn = pep_sk(sk);
670 struct sock *newsk = NULL;
671 struct sk_buff *oskb;
672 int err;
673
674 lock_sock(sk);
675 err = pep_wait_connreq(sk, flags & O_NONBLOCK);
676 if (err)
677 goto out;
678
679 newsk = __sk_head(&pn->ackq);
680
681 oskb = skb_dequeue(&newsk->sk_receive_queue);
682 err = pep_accept_conn(newsk, oskb);
683 if (err) {
684 skb_queue_head(&newsk->sk_receive_queue, oskb);
685 newsk = NULL;
686 goto out;
687 }
688
689 sock_hold(sk);
690 pep_sk(newsk)->listener = sk;
691
692 sock_hold(newsk);
693 sk_del_node_init(newsk);
694 sk_acceptq_removed(sk);
695 sk_add_node(newsk, &pn->hlist);
696 __sock_put(newsk);
697
698out:
699 release_sock(sk);
700 *errp = err;
701 return newsk;
702}
703
704static int pep_ioctl(struct sock *sk, int cmd, unsigned long arg)
705{
706 struct pep_sock *pn = pep_sk(sk);
707 int answ;
708
709 switch (cmd) {
710 case SIOCINQ:
711 if (sk->sk_state == TCP_LISTEN)
712 return -EINVAL;
713
714 lock_sock(sk);
715 if (sock_flag(sk, SOCK_URGINLINE)
716 && !skb_queue_empty(&pn->ctrlreq_queue))
717 answ = skb_peek(&pn->ctrlreq_queue)->len;
718 else if (!skb_queue_empty(&sk->sk_receive_queue))
719 answ = skb_peek(&sk->sk_receive_queue)->len;
720 else
721 answ = 0;
722 release_sock(sk);
723 return put_user(answ, (int __user *)arg);
724 }
725
726 return -ENOIOCTLCMD;
727}
728
729static int pep_init(struct sock *sk)
730{
731 struct pep_sock *pn = pep_sk(sk);
732
733 INIT_HLIST_HEAD(&pn->ackq);
734 INIT_HLIST_HEAD(&pn->hlist);
735 skb_queue_head_init(&pn->ctrlreq_queue);
736 pn->pipe_handle = PN_PIPE_INVALID_HANDLE;
737 return 0;
738}
739
740static int pep_setsockopt(struct sock *sk, int level, int optname,
741 char __user *optval, int optlen)
742{
743 struct pep_sock *pn = pep_sk(sk);
744 int val = 0, err = 0;
745
746 if (level != SOL_PNPIPE)
747 return -ENOPROTOOPT;
748 if (optlen >= sizeof(int)) {
749 if (get_user(val, (int __user *) optval))
750 return -EFAULT;
751 }
752
753 lock_sock(sk);
754 switch (optname) {
755 case PNPIPE_ENCAP:
756 if (val && val != PNPIPE_ENCAP_IP) {
757 err = -EINVAL;
758 break;
759 }
760 if (!pn->ifindex == !val)
761 break; /* Nothing to do! */
762 if (!capable(CAP_NET_ADMIN)) {
763 err = -EPERM;
764 break;
765 }
766 if (val) {
767 release_sock(sk);
768 err = gprs_attach(sk);
769 if (err > 0) {
770 pn->ifindex = err;
771 err = 0;
772 }
773 } else {
774 pn->ifindex = 0;
775 release_sock(sk);
776 gprs_detach(sk);
777 err = 0;
778 }
779 goto out_norel;
780 default:
781 err = -ENOPROTOOPT;
782 }
783 release_sock(sk);
784
785out_norel:
786 return err;
787}
788
789static int pep_getsockopt(struct sock *sk, int level, int optname,
790 char __user *optval, int __user *optlen)
791{
792 struct pep_sock *pn = pep_sk(sk);
793 int len, val;
794
795 if (level != SOL_PNPIPE)
796 return -ENOPROTOOPT;
797 if (get_user(len, optlen))
798 return -EFAULT;
799
800 switch (optname) {
801 case PNPIPE_ENCAP:
802 val = pn->ifindex ? PNPIPE_ENCAP_IP : PNPIPE_ENCAP_NONE;
803 break;
804 case PNPIPE_IFINDEX:
805 val = pn->ifindex;
806 break;
807 default:
808 return -ENOPROTOOPT;
809 }
810
811 len = min_t(unsigned int, sizeof(int), len);
812 if (put_user(len, optlen))
813 return -EFAULT;
814 if (put_user(val, (int __user *) optval))
815 return -EFAULT;
816 return 0;
817}
818
819static int pipe_skb_send(struct sock *sk, struct sk_buff *skb)
820{
821 struct pep_sock *pn = pep_sk(sk);
822 struct pnpipehdr *ph;
823
824 skb_push(skb, 3);
825 skb_reset_transport_header(skb);
826 ph = pnp_hdr(skb);
827 ph->utid = 0;
828 ph->message_id = PNS_PIPE_DATA;
829 ph->pipe_handle = pn->pipe_handle;
830 if (pn_flow_safe(pn->tx_fc) && pn->tx_credits)
831 pn->tx_credits--;
832
833 return pn_skb_send(sk, skb, &pipe_srv);
834}
835
836static int pep_sendmsg(struct kiocb *iocb, struct sock *sk,
837 struct msghdr *msg, size_t len)
838{
839 struct pep_sock *pn = pep_sk(sk);
840 struct sk_buff *skb = NULL;
841 long timeo;
842 int flags = msg->msg_flags;
843 int err, done;
844
845 if (msg->msg_flags & MSG_OOB || !(msg->msg_flags & MSG_EOR))
846 return -EOPNOTSUPP;
847
848 lock_sock(sk);
849 timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT);
850 if ((1 << sk->sk_state) & (TCPF_LISTEN|TCPF_CLOSE)) {
851 err = -ENOTCONN;
852 goto out;
853 }
854 if (sk->sk_state != TCP_ESTABLISHED) {
855 /* Wait until the pipe gets to enabled state */
856disabled:
857 err = sk_stream_wait_connect(sk, &timeo);
858 if (err)
859 goto out;
860
861 if (sk->sk_state == TCP_CLOSE_WAIT) {
862 err = -ECONNRESET;
863 goto out;
864 }
865 }
866 BUG_ON(sk->sk_state != TCP_ESTABLISHED);
867
868 /* Wait until flow control allows TX */
869 done = pn->tx_credits > 0;
870 while (!done) {
871 DEFINE_WAIT(wait);
872
873 if (!timeo) {
874 err = -EAGAIN;
875 goto out;
876 }
877 if (signal_pending(current)) {
878 err = sock_intr_errno(timeo);
879 goto out;
880 }
881
882 prepare_to_wait(&sk->sk_socket->wait, &wait,
883 TASK_INTERRUPTIBLE);
884 done = sk_wait_event(sk, &timeo, pn->tx_credits > 0);
885 finish_wait(&sk->sk_socket->wait, &wait);
886
887 if (sk->sk_state != TCP_ESTABLISHED)
888 goto disabled;
889 }
890
891 if (!skb) {
892 skb = sock_alloc_send_skb(sk, MAX_PNPIPE_HEADER + len,
893 flags & MSG_DONTWAIT, &err);
894 if (skb == NULL)
895 goto out;
896 skb_reserve(skb, MAX_PHONET_HEADER + 3);
897
898 if (sk->sk_state != TCP_ESTABLISHED || !pn->tx_credits)
899 goto disabled; /* sock_alloc_send_skb might sleep */
900 }
901
902 err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
903 if (err < 0)
904 goto out;
905
906 err = pipe_skb_send(sk, skb);
907 if (err >= 0)
908 err = len; /* success! */
909 skb = NULL;
910out:
911 release_sock(sk);
912 kfree_skb(skb);
913 return err;
914}
915
916int pep_writeable(struct sock *sk)
917{
918 struct pep_sock *pn = pep_sk(sk);
919
920 return (sk->sk_state == TCP_ESTABLISHED) ? pn->tx_credits : 0;
921}
922
923int pep_write(struct sock *sk, struct sk_buff *skb)
924{
925 struct sk_buff *rskb, *fs;
926 int flen = 0;
927
928 rskb = alloc_skb(MAX_PNPIPE_HEADER, GFP_ATOMIC);
929 if (!rskb) {
930 kfree_skb(skb);
931 return -ENOMEM;
932 }
933 skb_shinfo(rskb)->frag_list = skb;
934 rskb->len += skb->len;
935 rskb->data_len += rskb->len;
936 rskb->truesize += rskb->len;
937
938 /* Avoid nested fragments */
939 for (fs = skb_shinfo(skb)->frag_list; fs; fs = fs->next)
940 flen += fs->len;
941 skb->next = skb_shinfo(skb)->frag_list;
942 skb_shinfo(skb)->frag_list = NULL;
943 skb->len -= flen;
944 skb->data_len -= flen;
945 skb->truesize -= flen;
946
947 skb_reserve(rskb, MAX_PHONET_HEADER + 3);
948 return pipe_skb_send(sk, rskb);
949}
950
951struct sk_buff *pep_read(struct sock *sk)
952{
953 struct sk_buff *skb = skb_dequeue(&sk->sk_receive_queue);
954
955 if (sk->sk_state == TCP_ESTABLISHED)
956 pipe_grant_credits(sk);
957 return skb;
958}
959
960static int pep_recvmsg(struct kiocb *iocb, struct sock *sk,
961 struct msghdr *msg, size_t len, int noblock,
962 int flags, int *addr_len)
963{
964 struct sk_buff *skb;
965 int err;
966
967 if (unlikely(1 << sk->sk_state & (TCPF_LISTEN | TCPF_CLOSE)))
968 return -ENOTCONN;
969
970 if ((flags & MSG_OOB) || sock_flag(sk, SOCK_URGINLINE)) {
971 /* Dequeue and acknowledge control request */
972 struct pep_sock *pn = pep_sk(sk);
973
974 skb = skb_dequeue(&pn->ctrlreq_queue);
975 if (skb) {
976 pep_ctrlreq_error(sk, skb, PN_PIPE_NO_ERROR,
977 GFP_KERNEL);
978 msg->msg_flags |= MSG_OOB;
979 goto copy;
980 }
981 if (flags & MSG_OOB)
982 return -EINVAL;
983 }
984
985 skb = skb_recv_datagram(sk, flags, noblock, &err);
986 lock_sock(sk);
987 if (skb == NULL) {
988 if (err == -ENOTCONN && sk->sk_state == TCP_CLOSE_WAIT)
989 err = -ECONNRESET;
990 release_sock(sk);
991 return err;
992 }
993
994 if (sk->sk_state == TCP_ESTABLISHED)
995 pipe_grant_credits(sk);
996 release_sock(sk);
997copy:
998 msg->msg_flags |= MSG_EOR;
999 if (skb->len > len)
1000 msg->msg_flags |= MSG_TRUNC;
1001 else
1002 len = skb->len;
1003
1004 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, len);
1005 if (!err)
1006 err = (flags & MSG_TRUNC) ? skb->len : len;
1007
1008 skb_free_datagram(sk, skb);
1009 return err;
1010}
1011
1012static void pep_sock_unhash(struct sock *sk)
1013{
1014 struct pep_sock *pn = pep_sk(sk);
1015 struct sock *skparent = NULL;
1016
1017 lock_sock(sk);
1018 if ((1 << sk->sk_state) & ~(TCPF_CLOSE|TCPF_LISTEN)) {
1019 skparent = pn->listener;
1020 sk_del_node_init(sk);
1021 release_sock(sk);
1022
1023 sk = skparent;
1024 pn = pep_sk(skparent);
1025 lock_sock(sk);
1026 }
1027 /* Unhash a listening sock only when it is closed
1028 * and all of its active connected pipes are closed. */
1029 if (hlist_empty(&pn->hlist))
1030 pn_sock_unhash(&pn->pn_sk.sk);
1031 release_sock(sk);
1032
1033 if (skparent)
1034 sock_put(skparent);
1035}
1036
1037static struct proto pep_proto = {
1038 .close = pep_sock_close,
1039 .accept = pep_sock_accept,
1040 .ioctl = pep_ioctl,
1041 .init = pep_init,
1042 .setsockopt = pep_setsockopt,
1043 .getsockopt = pep_getsockopt,
1044 .sendmsg = pep_sendmsg,
1045 .recvmsg = pep_recvmsg,
1046 .backlog_rcv = pep_do_rcv,
1047 .hash = pn_sock_hash,
1048 .unhash = pep_sock_unhash,
1049 .get_port = pn_sock_get_port,
1050 .obj_size = sizeof(struct pep_sock),
1051 .owner = THIS_MODULE,
1052 .name = "PNPIPE",
1053};
1054
1055static struct phonet_protocol pep_pn_proto = {
1056 .ops = &phonet_stream_ops,
1057 .prot = &pep_proto,
1058 .sock_type = SOCK_SEQPACKET,
1059};
1060
1061static int __init pep_register(void)
1062{
1063 return phonet_proto_register(PN_PROTO_PIPE, &pep_pn_proto);
1064}
1065
1066static void __exit pep_unregister(void)
1067{
1068 phonet_proto_unregister(PN_PROTO_PIPE, &pep_pn_proto);
1069}
1070
1071module_init(pep_register);
1072module_exit(pep_unregister);
1073MODULE_AUTHOR("Remi Denis-Courmont, Nokia");
1074MODULE_DESCRIPTION("Phonet pipe protocol");
1075MODULE_LICENSE("GPL");
1076MODULE_ALIAS_NET_PF_PROTO(PF_PHONET, PN_PROTO_PIPE);
diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c
new file mode 100644
index 000000000000..53be9fc82aaa
--- /dev/null
+++ b/net/phonet/pn_dev.c
@@ -0,0 +1,208 @@
1/*
2 * File: pn_dev.c
3 *
4 * Phonet network device
5 *
6 * Copyright (C) 2008 Nokia Corporation.
7 *
8 * Contact: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
9 * Original author: Sakari Ailus <sakari.ailus@nokia.com>
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * version 2 as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 */
25
26#include <linux/kernel.h>
27#include <linux/net.h>
28#include <linux/netdevice.h>
29#include <linux/phonet.h>
30#include <net/sock.h>
31#include <net/phonet/pn_dev.h>
32
33/* when accessing, remember to lock with spin_lock(&pndevs.lock); */
34struct phonet_device_list pndevs = {
35 .list = LIST_HEAD_INIT(pndevs.list),
36 .lock = __SPIN_LOCK_UNLOCKED(pndevs.lock),
37};
38
39/* Allocate new Phonet device. */
40static struct phonet_device *__phonet_device_alloc(struct net_device *dev)
41{
42 struct phonet_device *pnd = kmalloc(sizeof(*pnd), GFP_ATOMIC);
43 if (pnd == NULL)
44 return NULL;
45 pnd->netdev = dev;
46 bitmap_zero(pnd->addrs, 64);
47
48 list_add(&pnd->list, &pndevs.list);
49 return pnd;
50}
51
52static struct phonet_device *__phonet_get(struct net_device *dev)
53{
54 struct phonet_device *pnd;
55
56 list_for_each_entry(pnd, &pndevs.list, list) {
57 if (pnd->netdev == dev)
58 return pnd;
59 }
60 return NULL;
61}
62
63static void __phonet_device_free(struct phonet_device *pnd)
64{
65 list_del(&pnd->list);
66 kfree(pnd);
67}
68
69struct net_device *phonet_device_get(struct net *net)
70{
71 struct phonet_device *pnd;
72 struct net_device *dev;
73
74 spin_lock_bh(&pndevs.lock);
75 list_for_each_entry(pnd, &pndevs.list, list) {
76 dev = pnd->netdev;
77 BUG_ON(!dev);
78
79 if (dev_net(dev) == net &&
80 (dev->reg_state == NETREG_REGISTERED) &&
81 ((pnd->netdev->flags & IFF_UP)) == IFF_UP)
82 break;
83 dev = NULL;
84 }
85 if (dev)
86 dev_hold(dev);
87 spin_unlock_bh(&pndevs.lock);
88 return dev;
89}
90
91int phonet_address_add(struct net_device *dev, u8 addr)
92{
93 struct phonet_device *pnd;
94 int err = 0;
95
96 spin_lock_bh(&pndevs.lock);
97 /* Find or create Phonet-specific device data */
98 pnd = __phonet_get(dev);
99 if (pnd == NULL)
100 pnd = __phonet_device_alloc(dev);
101 if (unlikely(pnd == NULL))
102 err = -ENOMEM;
103 else if (test_and_set_bit(addr >> 2, pnd->addrs))
104 err = -EEXIST;
105 spin_unlock_bh(&pndevs.lock);
106 return err;
107}
108
109int phonet_address_del(struct net_device *dev, u8 addr)
110{
111 struct phonet_device *pnd;
112 int err = 0;
113
114 spin_lock_bh(&pndevs.lock);
115 pnd = __phonet_get(dev);
116 if (!pnd || !test_and_clear_bit(addr >> 2, pnd->addrs))
117 err = -EADDRNOTAVAIL;
118 if (bitmap_empty(pnd->addrs, 64))
119 __phonet_device_free(pnd);
120 spin_unlock_bh(&pndevs.lock);
121 return err;
122}
123
124/* Gets a source address toward a destination, through a interface. */
125u8 phonet_address_get(struct net_device *dev, u8 addr)
126{
127 struct phonet_device *pnd;
128
129 spin_lock_bh(&pndevs.lock);
130 pnd = __phonet_get(dev);
131 if (pnd) {
132 BUG_ON(bitmap_empty(pnd->addrs, 64));
133
134 /* Use same source address as destination, if possible */
135 if (!test_bit(addr >> 2, pnd->addrs))
136 addr = find_first_bit(pnd->addrs, 64) << 2;
137 } else
138 addr = PN_NO_ADDR;
139 spin_unlock_bh(&pndevs.lock);
140 return addr;
141}
142
143int phonet_address_lookup(u8 addr)
144{
145 struct phonet_device *pnd;
146
147 spin_lock_bh(&pndevs.lock);
148 list_for_each_entry(pnd, &pndevs.list, list) {
149 /* Don't allow unregistering devices! */
150 if ((pnd->netdev->reg_state != NETREG_REGISTERED) ||
151 ((pnd->netdev->flags & IFF_UP)) != IFF_UP)
152 continue;
153
154 if (test_bit(addr >> 2, pnd->addrs)) {
155 spin_unlock_bh(&pndevs.lock);
156 return 0;
157 }
158 }
159 spin_unlock_bh(&pndevs.lock);
160 return -EADDRNOTAVAIL;
161}
162
163/* notify Phonet of device events */
164static int phonet_device_notify(struct notifier_block *me, unsigned long what,
165 void *arg)
166{
167 struct net_device *dev = arg;
168
169 if (what == NETDEV_UNREGISTER) {
170 struct phonet_device *pnd;
171
172 /* Destroy phonet-specific device data */
173 spin_lock_bh(&pndevs.lock);
174 pnd = __phonet_get(dev);
175 if (pnd)
176 __phonet_device_free(pnd);
177 spin_unlock_bh(&pndevs.lock);
178 }
179 return 0;
180
181}
182
183static struct notifier_block phonet_device_notifier = {
184 .notifier_call = phonet_device_notify,
185 .priority = 0,
186};
187
188/* Initialize Phonet devices list */
189void phonet_device_init(void)
190{
191 register_netdevice_notifier(&phonet_device_notifier);
192}
193
194void phonet_device_exit(void)
195{
196 struct phonet_device *pnd, *n;
197
198 rtnl_unregister_all(PF_PHONET);
199 rtnl_lock();
200 spin_lock_bh(&pndevs.lock);
201
202 list_for_each_entry_safe(pnd, n, &pndevs.list, list)
203 __phonet_device_free(pnd);
204
205 spin_unlock_bh(&pndevs.lock);
206 rtnl_unlock();
207 unregister_netdevice_notifier(&phonet_device_notifier);
208}
diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c
new file mode 100644
index 000000000000..b1770d66bc8d
--- /dev/null
+++ b/net/phonet/pn_netlink.c
@@ -0,0 +1,165 @@
1/*
2 * File: pn_netlink.c
3 *
4 * Phonet netlink interface
5 *
6 * Copyright (C) 2008 Nokia Corporation.
7 *
8 * Contact: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
9 * Original author: Sakari Ailus <sakari.ailus@nokia.com>
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * version 2 as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 */
25
26#include <linux/kernel.h>
27#include <linux/netlink.h>
28#include <linux/phonet.h>
29#include <net/sock.h>
30#include <net/phonet/pn_dev.h>
31
32static int fill_addr(struct sk_buff *skb, struct net_device *dev, u8 addr,
33 u32 pid, u32 seq, int event);
34
35static void rtmsg_notify(int event, struct net_device *dev, u8 addr)
36{
37 struct sk_buff *skb;
38 int err = -ENOBUFS;
39
40 skb = nlmsg_new(NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
41 nla_total_size(1), GFP_KERNEL);
42 if (skb == NULL)
43 goto errout;
44 err = fill_addr(skb, dev, addr, 0, 0, event);
45 if (err < 0) {
46 WARN_ON(err == -EMSGSIZE);
47 kfree_skb(skb);
48 goto errout;
49 }
50 err = rtnl_notify(skb, dev_net(dev), 0,
51 RTNLGRP_PHONET_IFADDR, NULL, GFP_KERNEL);
52errout:
53 if (err < 0)
54 rtnl_set_sk_err(dev_net(dev), RTNLGRP_PHONET_IFADDR, err);
55}
56
57static const struct nla_policy ifa_phonet_policy[IFA_MAX+1] = {
58 [IFA_LOCAL] = { .type = NLA_U8 },
59};
60
61static int addr_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *attr)
62{
63 struct net *net = sock_net(skb->sk);
64 struct nlattr *tb[IFA_MAX+1];
65 struct net_device *dev;
66 struct ifaddrmsg *ifm;
67 int err;
68 u8 pnaddr;
69
70 if (!capable(CAP_SYS_ADMIN))
71 return -EPERM;
72
73 ASSERT_RTNL();
74
75 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_phonet_policy);
76 if (err < 0)
77 return err;
78
79 ifm = nlmsg_data(nlh);
80 if (tb[IFA_LOCAL] == NULL)
81 return -EINVAL;
82 pnaddr = nla_get_u8(tb[IFA_LOCAL]);
83 if (pnaddr & 3)
84 /* Phonet addresses only have 6 high-order bits */
85 return -EINVAL;
86
87 dev = __dev_get_by_index(net, ifm->ifa_index);
88 if (dev == NULL)
89 return -ENODEV;
90
91 if (nlh->nlmsg_type == RTM_NEWADDR)
92 err = phonet_address_add(dev, pnaddr);
93 else
94 err = phonet_address_del(dev, pnaddr);
95 if (!err)
96 rtmsg_notify(nlh->nlmsg_type, dev, pnaddr);
97 return err;
98}
99
100static int fill_addr(struct sk_buff *skb, struct net_device *dev, u8 addr,
101 u32 pid, u32 seq, int event)
102{
103 struct ifaddrmsg *ifm;
104 struct nlmsghdr *nlh;
105
106 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*ifm), 0);
107 if (nlh == NULL)
108 return -EMSGSIZE;
109
110 ifm = nlmsg_data(nlh);
111 ifm->ifa_family = AF_PHONET;
112 ifm->ifa_prefixlen = 0;
113 ifm->ifa_flags = IFA_F_PERMANENT;
114 ifm->ifa_scope = RT_SCOPE_LINK;
115 ifm->ifa_index = dev->ifindex;
116 NLA_PUT_U8(skb, IFA_LOCAL, addr);
117 return nlmsg_end(skb, nlh);
118
119nla_put_failure:
120 nlmsg_cancel(skb, nlh);
121 return -EMSGSIZE;
122}
123
124static int getaddr_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
125{
126 struct phonet_device *pnd;
127 int dev_idx = 0, dev_start_idx = cb->args[0];
128 int addr_idx = 0, addr_start_idx = cb->args[1];
129
130 spin_lock_bh(&pndevs.lock);
131 list_for_each_entry(pnd, &pndevs.list, list) {
132 u8 addr;
133
134 if (dev_idx > dev_start_idx)
135 addr_start_idx = 0;
136 if (dev_idx++ < dev_start_idx)
137 continue;
138
139 addr_idx = 0;
140 for (addr = find_first_bit(pnd->addrs, 64); addr < 64;
141 addr = find_next_bit(pnd->addrs, 64, 1+addr)) {
142 if (addr_idx++ < addr_start_idx)
143 continue;
144
145 if (fill_addr(skb, pnd->netdev, addr << 2,
146 NETLINK_CB(cb->skb).pid,
147 cb->nlh->nlmsg_seq, RTM_NEWADDR))
148 goto out;
149 }
150 }
151
152out:
153 spin_unlock_bh(&pndevs.lock);
154 cb->args[0] = dev_idx;
155 cb->args[1] = addr_idx;
156
157 return skb->len;
158}
159
160void __init phonet_netlink_register(void)
161{
162 rtnl_register(PF_PHONET, RTM_NEWADDR, addr_doit, NULL);
163 rtnl_register(PF_PHONET, RTM_DELADDR, addr_doit, NULL);
164 rtnl_register(PF_PHONET, RTM_GETADDR, NULL, getaddr_dumpit);
165}
diff --git a/net/phonet/socket.c b/net/phonet/socket.c
new file mode 100644
index 000000000000..d81740187fb4
--- /dev/null
+++ b/net/phonet/socket.c
@@ -0,0 +1,411 @@
1/*
2 * File: socket.c
3 *
4 * Phonet sockets
5 *
6 * Copyright (C) 2008 Nokia Corporation.
7 *
8 * Contact: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
9 * Original author: Sakari Ailus <sakari.ailus@nokia.com>
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * version 2 as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 */
25
26#include <linux/kernel.h>
27#include <linux/net.h>
28#include <linux/poll.h>
29#include <net/sock.h>
30#include <net/tcp_states.h>
31
32#include <linux/phonet.h>
33#include <net/phonet/phonet.h>
34#include <net/phonet/pep.h>
35#include <net/phonet/pn_dev.h>
36
37static int pn_socket_release(struct socket *sock)
38{
39 struct sock *sk = sock->sk;
40
41 if (sk) {
42 sock->sk = NULL;
43 sk->sk_prot->close(sk, 0);
44 }
45 return 0;
46}
47
48static struct {
49 struct hlist_head hlist;
50 spinlock_t lock;
51} pnsocks = {
52 .hlist = HLIST_HEAD_INIT,
53 .lock = __SPIN_LOCK_UNLOCKED(pnsocks.lock),
54};
55
56/*
57 * Find address based on socket address, match only certain fields.
58 * Also grab sock if it was found. Remember to sock_put it later.
59 */
60struct sock *pn_find_sock_by_sa(const struct sockaddr_pn *spn)
61{
62 struct hlist_node *node;
63 struct sock *sknode;
64 struct sock *rval = NULL;
65 u16 obj = pn_sockaddr_get_object(spn);
66 u8 res = spn->spn_resource;
67
68 spin_lock_bh(&pnsocks.lock);
69
70 sk_for_each(sknode, node, &pnsocks.hlist) {
71 struct pn_sock *pn = pn_sk(sknode);
72 BUG_ON(!pn->sobject); /* unbound socket */
73
74 if (pn_port(obj)) {
75 /* Look up socket by port */
76 if (pn_port(pn->sobject) != pn_port(obj))
77 continue;
78 } else {
79 /* If port is zero, look up by resource */
80 if (pn->resource != res)
81 continue;
82 }
83 if (pn_addr(pn->sobject)
84 && pn_addr(pn->sobject) != pn_addr(obj))
85 continue;
86
87 rval = sknode;
88 sock_hold(sknode);
89 break;
90 }
91
92 spin_unlock_bh(&pnsocks.lock);
93
94 return rval;
95
96}
97
98void pn_sock_hash(struct sock *sk)
99{
100 spin_lock_bh(&pnsocks.lock);
101 sk_add_node(sk, &pnsocks.hlist);
102 spin_unlock_bh(&pnsocks.lock);
103}
104EXPORT_SYMBOL(pn_sock_hash);
105
106void pn_sock_unhash(struct sock *sk)
107{
108 spin_lock_bh(&pnsocks.lock);
109 sk_del_node_init(sk);
110 spin_unlock_bh(&pnsocks.lock);
111}
112EXPORT_SYMBOL(pn_sock_unhash);
113
114static int pn_socket_bind(struct socket *sock, struct sockaddr *addr, int len)
115{
116 struct sock *sk = sock->sk;
117 struct pn_sock *pn = pn_sk(sk);
118 struct sockaddr_pn *spn = (struct sockaddr_pn *)addr;
119 int err;
120 u16 handle;
121 u8 saddr;
122
123 if (sk->sk_prot->bind)
124 return sk->sk_prot->bind(sk, addr, len);
125
126 if (len < sizeof(struct sockaddr_pn))
127 return -EINVAL;
128 if (spn->spn_family != AF_PHONET)
129 return -EAFNOSUPPORT;
130
131 handle = pn_sockaddr_get_object((struct sockaddr_pn *)addr);
132 saddr = pn_addr(handle);
133 if (saddr && phonet_address_lookup(saddr))
134 return -EADDRNOTAVAIL;
135
136 lock_sock(sk);
137 if (sk->sk_state != TCP_CLOSE || pn_port(pn->sobject)) {
138 err = -EINVAL; /* attempt to rebind */
139 goto out;
140 }
141 err = sk->sk_prot->get_port(sk, pn_port(handle));
142 if (err)
143 goto out;
144
145 /* get_port() sets the port, bind() sets the address if applicable */
146 pn->sobject = pn_object(saddr, pn_port(pn->sobject));
147 pn->resource = spn->spn_resource;
148
149 /* Enable RX on the socket */
150 sk->sk_prot->hash(sk);
151out:
152 release_sock(sk);
153 return err;
154}
155
156static int pn_socket_autobind(struct socket *sock)
157{
158 struct sockaddr_pn sa;
159 int err;
160
161 memset(&sa, 0, sizeof(sa));
162 sa.spn_family = AF_PHONET;
163 err = pn_socket_bind(sock, (struct sockaddr *)&sa,
164 sizeof(struct sockaddr_pn));
165 if (err != -EINVAL)
166 return err;
167 BUG_ON(!pn_port(pn_sk(sock->sk)->sobject));
168 return 0; /* socket was already bound */
169}
170
171static int pn_socket_accept(struct socket *sock, struct socket *newsock,
172 int flags)
173{
174 struct sock *sk = sock->sk;
175 struct sock *newsk;
176 int err;
177
178 newsk = sk->sk_prot->accept(sk, flags, &err);
179 if (!newsk)
180 return err;
181
182 lock_sock(newsk);
183 sock_graft(newsk, newsock);
184 newsock->state = SS_CONNECTED;
185 release_sock(newsk);
186 return 0;
187}
188
189static int pn_socket_getname(struct socket *sock, struct sockaddr *addr,
190 int *sockaddr_len, int peer)
191{
192 struct sock *sk = sock->sk;
193 struct pn_sock *pn = pn_sk(sk);
194
195 memset(addr, 0, sizeof(struct sockaddr_pn));
196 addr->sa_family = AF_PHONET;
197 if (!peer) /* Race with bind() here is userland's problem. */
198 pn_sockaddr_set_object((struct sockaddr_pn *)addr,
199 pn->sobject);
200
201 *sockaddr_len = sizeof(struct sockaddr_pn);
202 return 0;
203}
204
205static unsigned int pn_socket_poll(struct file *file, struct socket *sock,
206 poll_table *wait)
207{
208 struct sock *sk = sock->sk;
209 struct pep_sock *pn = pep_sk(sk);
210 unsigned int mask = 0;
211
212 poll_wait(file, &sock->wait, wait);
213
214 switch (sk->sk_state) {
215 case TCP_LISTEN:
216 return hlist_empty(&pn->ackq) ? 0 : POLLIN;
217 case TCP_CLOSE:
218 return POLLERR;
219 }
220
221 if (!skb_queue_empty(&sk->sk_receive_queue))
222 mask |= POLLIN | POLLRDNORM;
223 if (!skb_queue_empty(&pn->ctrlreq_queue))
224 mask |= POLLPRI;
225 if (!mask && sk->sk_state == TCP_CLOSE_WAIT)
226 return POLLHUP;
227
228 if (sk->sk_state == TCP_ESTABLISHED && pn->tx_credits)
229 mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
230
231 return mask;
232}
233
234static int pn_socket_ioctl(struct socket *sock, unsigned int cmd,
235 unsigned long arg)
236{
237 struct sock *sk = sock->sk;
238 struct pn_sock *pn = pn_sk(sk);
239
240 if (cmd == SIOCPNGETOBJECT) {
241 struct net_device *dev;
242 u16 handle;
243 u8 saddr;
244
245 if (get_user(handle, (__u16 __user *)arg))
246 return -EFAULT;
247
248 lock_sock(sk);
249 if (sk->sk_bound_dev_if)
250 dev = dev_get_by_index(sock_net(sk),
251 sk->sk_bound_dev_if);
252 else
253 dev = phonet_device_get(sock_net(sk));
254 if (dev && (dev->flags & IFF_UP))
255 saddr = phonet_address_get(dev, pn_addr(handle));
256 else
257 saddr = PN_NO_ADDR;
258 release_sock(sk);
259
260 if (dev)
261 dev_put(dev);
262 if (saddr == PN_NO_ADDR)
263 return -EHOSTUNREACH;
264
265 handle = pn_object(saddr, pn_port(pn->sobject));
266 return put_user(handle, (__u16 __user *)arg);
267 }
268
269 return sk->sk_prot->ioctl(sk, cmd, arg);
270}
271
272static int pn_socket_listen(struct socket *sock, int backlog)
273{
274 struct sock *sk = sock->sk;
275 int err = 0;
276
277 if (sock->state != SS_UNCONNECTED)
278 return -EINVAL;
279 if (pn_socket_autobind(sock))
280 return -ENOBUFS;
281
282 lock_sock(sk);
283 if (sk->sk_state != TCP_CLOSE) {
284 err = -EINVAL;
285 goto out;
286 }
287
288 sk->sk_state = TCP_LISTEN;
289 sk->sk_ack_backlog = 0;
290 sk->sk_max_ack_backlog = backlog;
291out:
292 release_sock(sk);
293 return err;
294}
295
296static int pn_socket_sendmsg(struct kiocb *iocb, struct socket *sock,
297 struct msghdr *m, size_t total_len)
298{
299 struct sock *sk = sock->sk;
300
301 if (pn_socket_autobind(sock))
302 return -EAGAIN;
303
304 return sk->sk_prot->sendmsg(iocb, sk, m, total_len);
305}
306
307const struct proto_ops phonet_dgram_ops = {
308 .family = AF_PHONET,
309 .owner = THIS_MODULE,
310 .release = pn_socket_release,
311 .bind = pn_socket_bind,
312 .connect = sock_no_connect,
313 .socketpair = sock_no_socketpair,
314 .accept = sock_no_accept,
315 .getname = pn_socket_getname,
316 .poll = datagram_poll,
317 .ioctl = pn_socket_ioctl,
318 .listen = sock_no_listen,
319 .shutdown = sock_no_shutdown,
320 .setsockopt = sock_no_setsockopt,
321 .getsockopt = sock_no_getsockopt,
322#ifdef CONFIG_COMPAT
323 .compat_setsockopt = sock_no_setsockopt,
324 .compat_getsockopt = sock_no_getsockopt,
325#endif
326 .sendmsg = pn_socket_sendmsg,
327 .recvmsg = sock_common_recvmsg,
328 .mmap = sock_no_mmap,
329 .sendpage = sock_no_sendpage,
330};
331
332const struct proto_ops phonet_stream_ops = {
333 .family = AF_PHONET,
334 .owner = THIS_MODULE,
335 .release = pn_socket_release,
336 .bind = pn_socket_bind,
337 .connect = sock_no_connect,
338 .socketpair = sock_no_socketpair,
339 .accept = pn_socket_accept,
340 .getname = pn_socket_getname,
341 .poll = pn_socket_poll,
342 .ioctl = pn_socket_ioctl,
343 .listen = pn_socket_listen,
344 .shutdown = sock_no_shutdown,
345 .setsockopt = sock_common_setsockopt,
346 .getsockopt = sock_common_getsockopt,
347#ifdef CONFIG_COMPAT
348 .compat_setsockopt = compat_sock_common_setsockopt,
349 .compat_getsockopt = compat_sock_common_getsockopt,
350#endif
351 .sendmsg = pn_socket_sendmsg,
352 .recvmsg = sock_common_recvmsg,
353 .mmap = sock_no_mmap,
354 .sendpage = sock_no_sendpage,
355};
356EXPORT_SYMBOL(phonet_stream_ops);
357
358static DEFINE_MUTEX(port_mutex);
359
360/* allocate port for a socket */
361int pn_sock_get_port(struct sock *sk, unsigned short sport)
362{
363 static int port_cur;
364 struct pn_sock *pn = pn_sk(sk);
365 struct sockaddr_pn try_sa;
366 struct sock *tmpsk;
367
368 memset(&try_sa, 0, sizeof(struct sockaddr_pn));
369 try_sa.spn_family = AF_PHONET;
370
371 mutex_lock(&port_mutex);
372
373 if (!sport) {
374 /* search free port */
375 int port, pmin, pmax;
376
377 phonet_get_local_port_range(&pmin, &pmax);
378 for (port = pmin; port <= pmax; port++) {
379 port_cur++;
380 if (port_cur < pmin || port_cur > pmax)
381 port_cur = pmin;
382
383 pn_sockaddr_set_port(&try_sa, port_cur);
384 tmpsk = pn_find_sock_by_sa(&try_sa);
385 if (tmpsk == NULL) {
386 sport = port_cur;
387 goto found;
388 } else
389 sock_put(tmpsk);
390 }
391 } else {
392 /* try to find specific port */
393 pn_sockaddr_set_port(&try_sa, sport);
394 tmpsk = pn_find_sock_by_sa(&try_sa);
395 if (tmpsk == NULL)
396 /* No sock there! We can use that port... */
397 goto found;
398 else
399 sock_put(tmpsk);
400 }
401 mutex_unlock(&port_mutex);
402
403 /* the port must be in use already */
404 return -EADDRINUSE;
405
406found:
407 mutex_unlock(&port_mutex);
408 pn->sobject = pn_object(pn_addr(pn->sobject), sport);
409 return 0;
410}
411EXPORT_SYMBOL(pn_sock_get_port);
diff --git a/net/phonet/sysctl.c b/net/phonet/sysctl.c
new file mode 100644
index 000000000000..600a4309b8c8
--- /dev/null
+++ b/net/phonet/sysctl.c
@@ -0,0 +1,113 @@
1/*
2 * File: sysctl.c
3 *
4 * Phonet /proc/sys/net/phonet interface implementation
5 *
6 * Copyright (C) 2008 Nokia Corporation.
7 *
8 * Contact: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * version 2 as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA
23 */
24
25#include <linux/seqlock.h>
26#include <linux/sysctl.h>
27#include <linux/errno.h>
28#include <linux/init.h>
29
30#define DYNAMIC_PORT_MIN 0x40
31#define DYNAMIC_PORT_MAX 0x7f
32
33static DEFINE_SEQLOCK(local_port_range_lock);
34static int local_port_range_min[2] = {0, 0};
35static int local_port_range_max[2] = {1023, 1023};
36static int local_port_range[2] = {DYNAMIC_PORT_MIN, DYNAMIC_PORT_MAX};
37static struct ctl_table_header *phonet_table_hrd;
38
39static void set_local_port_range(int range[2])
40{
41 write_seqlock(&local_port_range_lock);
42 local_port_range[0] = range[0];
43 local_port_range[1] = range[1];
44 write_sequnlock(&local_port_range_lock);
45}
46
47void phonet_get_local_port_range(int *min, int *max)
48{
49 unsigned seq;
50 do {
51 seq = read_seqbegin(&local_port_range_lock);
52 if (min)
53 *min = local_port_range[0];
54 if (max)
55 *max = local_port_range[1];
56 } while (read_seqretry(&local_port_range_lock, seq));
57}
58
59static int proc_local_port_range(ctl_table *table, int write, struct file *filp,
60 void __user *buffer,
61 size_t *lenp, loff_t *ppos)
62{
63 int ret;
64 int range[2] = {local_port_range[0], local_port_range[1]};
65 ctl_table tmp = {
66 .data = &range,
67 .maxlen = sizeof(range),
68 .mode = table->mode,
69 .extra1 = &local_port_range_min,
70 .extra2 = &local_port_range_max,
71 };
72
73 ret = proc_dointvec_minmax(&tmp, write, filp, buffer, lenp, ppos);
74
75 if (write && ret == 0) {
76 if (range[1] < range[0])
77 ret = -EINVAL;
78 else
79 set_local_port_range(range);
80 }
81
82 return ret;
83}
84
85static struct ctl_table phonet_table[] = {
86 {
87 .ctl_name = CTL_UNNUMBERED,
88 .procname = "local_port_range",
89 .data = &local_port_range,
90 .maxlen = sizeof(local_port_range),
91 .mode = 0644,
92 .proc_handler = &proc_local_port_range,
93 .strategy = NULL,
94 },
95 { .ctl_name = 0 }
96};
97
98struct ctl_path phonet_ctl_path[] = {
99 { .procname = "net", .ctl_name = CTL_NET, },
100 { .procname = "phonet", .ctl_name = CTL_UNNUMBERED, },
101 { },
102};
103
104int __init phonet_sysctl_init(void)
105{
106 phonet_table_hrd = register_sysctl_paths(phonet_ctl_path, phonet_table);
107 return phonet_table_hrd == NULL ? -ENOMEM : 0;
108}
109
110void phonet_sysctl_exit(void)
111{
112 unregister_sysctl_table(phonet_table_hrd);
113}
diff --git a/net/rfkill/rfkill-input.h b/net/rfkill/rfkill-input.h
index f63d05045685..bbfa646157c6 100644
--- a/net/rfkill/rfkill-input.h
+++ b/net/rfkill/rfkill-input.h
@@ -13,5 +13,6 @@
13 13
14void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state); 14void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state);
15void rfkill_epo(void); 15void rfkill_epo(void);
16void rfkill_restore_states(void);
16 17
17#endif /* __RFKILL_INPUT_H */ 18#endif /* __RFKILL_INPUT_H */
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c
index 74aecc098bad..f949a482b007 100644
--- a/net/rfkill/rfkill.c
+++ b/net/rfkill/rfkill.c
@@ -37,14 +37,20 @@ MODULE_DESCRIPTION("RF switch support");
37MODULE_LICENSE("GPL"); 37MODULE_LICENSE("GPL");
38 38
39static LIST_HEAD(rfkill_list); /* list of registered rf switches */ 39static LIST_HEAD(rfkill_list); /* list of registered rf switches */
40static DEFINE_MUTEX(rfkill_mutex); 40static DEFINE_MUTEX(rfkill_global_mutex);
41 41
42static unsigned int rfkill_default_state = RFKILL_STATE_UNBLOCKED; 42static unsigned int rfkill_default_state = RFKILL_STATE_UNBLOCKED;
43module_param_named(default_state, rfkill_default_state, uint, 0444); 43module_param_named(default_state, rfkill_default_state, uint, 0444);
44MODULE_PARM_DESC(default_state, 44MODULE_PARM_DESC(default_state,
45 "Default initial state for all radio types, 0 = radio off"); 45 "Default initial state for all radio types, 0 = radio off");
46 46
47static enum rfkill_state rfkill_states[RFKILL_TYPE_MAX]; 47struct rfkill_gsw_state {
48 enum rfkill_state current_state;
49 enum rfkill_state default_state;
50};
51
52static struct rfkill_gsw_state rfkill_global_states[RFKILL_TYPE_MAX];
53static unsigned long rfkill_states_lockdflt[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
48 54
49static BLOCKING_NOTIFIER_HEAD(rfkill_notifier_list); 55static BLOCKING_NOTIFIER_HEAD(rfkill_notifier_list);
50 56
@@ -70,6 +76,7 @@ static BLOCKING_NOTIFIER_HEAD(rfkill_notifier_list);
70 */ 76 */
71int register_rfkill_notifier(struct notifier_block *nb) 77int register_rfkill_notifier(struct notifier_block *nb)
72{ 78{
79 BUG_ON(!nb);
73 return blocking_notifier_chain_register(&rfkill_notifier_list, nb); 80 return blocking_notifier_chain_register(&rfkill_notifier_list, nb);
74} 81}
75EXPORT_SYMBOL_GPL(register_rfkill_notifier); 82EXPORT_SYMBOL_GPL(register_rfkill_notifier);
@@ -85,6 +92,7 @@ EXPORT_SYMBOL_GPL(register_rfkill_notifier);
85 */ 92 */
86int unregister_rfkill_notifier(struct notifier_block *nb) 93int unregister_rfkill_notifier(struct notifier_block *nb)
87{ 94{
95 BUG_ON(!nb);
88 return blocking_notifier_chain_unregister(&rfkill_notifier_list, nb); 96 return blocking_notifier_chain_unregister(&rfkill_notifier_list, nb);
89} 97}
90EXPORT_SYMBOL_GPL(unregister_rfkill_notifier); 98EXPORT_SYMBOL_GPL(unregister_rfkill_notifier);
@@ -117,6 +125,7 @@ static void rfkill_led_trigger_activate(struct led_classdev *led)
117 125
118static void notify_rfkill_state_change(struct rfkill *rfkill) 126static void notify_rfkill_state_change(struct rfkill *rfkill)
119{ 127{
128 rfkill_led_trigger(rfkill, rfkill->state);
120 blocking_notifier_call_chain(&rfkill_notifier_list, 129 blocking_notifier_call_chain(&rfkill_notifier_list,
121 RFKILL_STATE_CHANGED, 130 RFKILL_STATE_CHANGED,
122 rfkill); 131 rfkill);
@@ -195,6 +204,11 @@ static int rfkill_toggle_radio(struct rfkill *rfkill,
195 * BLOCK even a transmitter that is already in state 204 * BLOCK even a transmitter that is already in state
196 * RFKILL_STATE_HARD_BLOCKED */ 205 * RFKILL_STATE_HARD_BLOCKED */
197 break; 206 break;
207 default:
208 WARN(1, KERN_WARNING
209 "rfkill: illegal state %d passed as parameter "
210 "to rfkill_toggle_radio\n", state);
211 return -EINVAL;
198 } 212 }
199 213
200 if (force || state != rfkill->state) { 214 if (force || state != rfkill->state) {
@@ -204,31 +218,36 @@ static int rfkill_toggle_radio(struct rfkill *rfkill,
204 rfkill->state = state; 218 rfkill->state = state;
205 } 219 }
206 220
207 if (force || rfkill->state != oldstate) { 221 if (force || rfkill->state != oldstate)
208 rfkill_led_trigger(rfkill, rfkill->state);
209 notify_rfkill_state_change(rfkill); 222 notify_rfkill_state_change(rfkill);
210 }
211 223
212 return retval; 224 return retval;
213} 225}
214 226
215/** 227/**
216 * rfkill_switch_all - Toggle state of all switches of given type 228 * __rfkill_switch_all - Toggle state of all switches of given type
217 * @type: type of interfaces to be affected 229 * @type: type of interfaces to be affected
218 * @state: the new state 230 * @state: the new state
219 * 231 *
220 * This function toggles the state of all switches of given type, 232 * This function toggles the state of all switches of given type,
221 * unless a specific switch is claimed by userspace (in which case, 233 * unless a specific switch is claimed by userspace (in which case,
222 * that switch is left alone) or suspended. 234 * that switch is left alone) or suspended.
235 *
236 * Caller must have acquired rfkill_global_mutex.
223 */ 237 */
224void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state) 238static void __rfkill_switch_all(const enum rfkill_type type,
239 const enum rfkill_state state)
225{ 240{
226 struct rfkill *rfkill; 241 struct rfkill *rfkill;
227 242
228 mutex_lock(&rfkill_mutex); 243 if (WARN((state >= RFKILL_STATE_MAX || type >= RFKILL_TYPE_MAX),
229 244 KERN_WARNING
230 rfkill_states[type] = state; 245 "rfkill: illegal state %d or type %d "
246 "passed as parameter to __rfkill_switch_all\n",
247 state, type))
248 return;
231 249
250 rfkill_global_states[type].current_state = state;
232 list_for_each_entry(rfkill, &rfkill_list, node) { 251 list_for_each_entry(rfkill, &rfkill_list, node) {
233 if ((!rfkill->user_claim) && (rfkill->type == type)) { 252 if ((!rfkill->user_claim) && (rfkill->type == type)) {
234 mutex_lock(&rfkill->mutex); 253 mutex_lock(&rfkill->mutex);
@@ -236,8 +255,21 @@ void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state)
236 mutex_unlock(&rfkill->mutex); 255 mutex_unlock(&rfkill->mutex);
237 } 256 }
238 } 257 }
258}
239 259
240 mutex_unlock(&rfkill_mutex); 260/**
261 * rfkill_switch_all - Toggle state of all switches of given type
262 * @type: type of interfaces to be affected
263 * @state: the new state
264 *
265 * Acquires rfkill_global_mutex and calls __rfkill_switch_all(@type, @state).
266 * Please refer to __rfkill_switch_all() for details.
267 */
268void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state)
269{
270 mutex_lock(&rfkill_global_mutex);
271 __rfkill_switch_all(type, state);
272 mutex_unlock(&rfkill_global_mutex);
241} 273}
242EXPORT_SYMBOL(rfkill_switch_all); 274EXPORT_SYMBOL(rfkill_switch_all);
243 275
@@ -245,23 +277,53 @@ EXPORT_SYMBOL(rfkill_switch_all);
245 * rfkill_epo - emergency power off all transmitters 277 * rfkill_epo - emergency power off all transmitters
246 * 278 *
247 * This kicks all non-suspended rfkill devices to RFKILL_STATE_SOFT_BLOCKED, 279 * This kicks all non-suspended rfkill devices to RFKILL_STATE_SOFT_BLOCKED,
248 * ignoring everything in its path but rfkill_mutex and rfkill->mutex. 280 * ignoring everything in its path but rfkill_global_mutex and rfkill->mutex.
281 *
282 * The global state before the EPO is saved and can be restored later
283 * using rfkill_restore_states().
249 */ 284 */
250void rfkill_epo(void) 285void rfkill_epo(void)
251{ 286{
252 struct rfkill *rfkill; 287 struct rfkill *rfkill;
288 int i;
289
290 mutex_lock(&rfkill_global_mutex);
253 291
254 mutex_lock(&rfkill_mutex);
255 list_for_each_entry(rfkill, &rfkill_list, node) { 292 list_for_each_entry(rfkill, &rfkill_list, node) {
256 mutex_lock(&rfkill->mutex); 293 mutex_lock(&rfkill->mutex);
257 rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1); 294 rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1);
258 mutex_unlock(&rfkill->mutex); 295 mutex_unlock(&rfkill->mutex);
259 } 296 }
260 mutex_unlock(&rfkill_mutex); 297 for (i = 0; i < RFKILL_TYPE_MAX; i++) {
298 rfkill_global_states[i].default_state =
299 rfkill_global_states[i].current_state;
300 rfkill_global_states[i].current_state =
301 RFKILL_STATE_SOFT_BLOCKED;
302 }
303 mutex_unlock(&rfkill_global_mutex);
261} 304}
262EXPORT_SYMBOL_GPL(rfkill_epo); 305EXPORT_SYMBOL_GPL(rfkill_epo);
263 306
264/** 307/**
308 * rfkill_restore_states - restore global states
309 *
310 * Restore (and sync switches to) the global state from the
311 * states in rfkill_default_states. This can undo the effects of
312 * a call to rfkill_epo().
313 */
314void rfkill_restore_states(void)
315{
316 int i;
317
318 mutex_lock(&rfkill_global_mutex);
319
320 for (i = 0; i < RFKILL_TYPE_MAX; i++)
321 __rfkill_switch_all(i, rfkill_global_states[i].default_state);
322 mutex_unlock(&rfkill_global_mutex);
323}
324EXPORT_SYMBOL_GPL(rfkill_restore_states);
325
326/**
265 * rfkill_force_state - Force the internal rfkill radio state 327 * rfkill_force_state - Force the internal rfkill radio state
266 * @rfkill: pointer to the rfkill class to modify. 328 * @rfkill: pointer to the rfkill class to modify.
267 * @state: the current radio state the class should be forced to. 329 * @state: the current radio state the class should be forced to.
@@ -282,9 +344,11 @@ int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state)
282{ 344{
283 enum rfkill_state oldstate; 345 enum rfkill_state oldstate;
284 346
285 if (state != RFKILL_STATE_SOFT_BLOCKED && 347 BUG_ON(!rfkill);
286 state != RFKILL_STATE_UNBLOCKED && 348 if (WARN((state >= RFKILL_STATE_MAX),
287 state != RFKILL_STATE_HARD_BLOCKED) 349 KERN_WARNING
350 "rfkill: illegal state %d passed as parameter "
351 "to rfkill_force_state\n", state))
288 return -EINVAL; 352 return -EINVAL;
289 353
290 mutex_lock(&rfkill->mutex); 354 mutex_lock(&rfkill->mutex);
@@ -352,12 +416,16 @@ static ssize_t rfkill_state_store(struct device *dev,
352 const char *buf, size_t count) 416 const char *buf, size_t count)
353{ 417{
354 struct rfkill *rfkill = to_rfkill(dev); 418 struct rfkill *rfkill = to_rfkill(dev);
355 unsigned int state = simple_strtoul(buf, NULL, 0); 419 unsigned long state;
356 int error; 420 int error;
357 421
358 if (!capable(CAP_NET_ADMIN)) 422 if (!capable(CAP_NET_ADMIN))
359 return -EPERM; 423 return -EPERM;
360 424
425 error = strict_strtoul(buf, 0, &state);
426 if (error)
427 return error;
428
361 /* RFKILL_STATE_HARD_BLOCKED is illegal here... */ 429 /* RFKILL_STATE_HARD_BLOCKED is illegal here... */
362 if (state != RFKILL_STATE_UNBLOCKED && 430 if (state != RFKILL_STATE_UNBLOCKED &&
363 state != RFKILL_STATE_SOFT_BLOCKED) 431 state != RFKILL_STATE_SOFT_BLOCKED)
@@ -385,7 +453,8 @@ static ssize_t rfkill_claim_store(struct device *dev,
385 const char *buf, size_t count) 453 const char *buf, size_t count)
386{ 454{
387 struct rfkill *rfkill = to_rfkill(dev); 455 struct rfkill *rfkill = to_rfkill(dev);
388 bool claim = !!simple_strtoul(buf, NULL, 0); 456 unsigned long claim_tmp;
457 bool claim;
389 int error; 458 int error;
390 459
391 if (!capable(CAP_NET_ADMIN)) 460 if (!capable(CAP_NET_ADMIN))
@@ -394,11 +463,16 @@ static ssize_t rfkill_claim_store(struct device *dev,
394 if (rfkill->user_claim_unsupported) 463 if (rfkill->user_claim_unsupported)
395 return -EOPNOTSUPP; 464 return -EOPNOTSUPP;
396 465
466 error = strict_strtoul(buf, 0, &claim_tmp);
467 if (error)
468 return error;
469 claim = !!claim_tmp;
470
397 /* 471 /*
398 * Take the global lock to make sure the kernel is not in 472 * Take the global lock to make sure the kernel is not in
399 * the middle of rfkill_switch_all 473 * the middle of rfkill_switch_all
400 */ 474 */
401 error = mutex_lock_interruptible(&rfkill_mutex); 475 error = mutex_lock_interruptible(&rfkill_global_mutex);
402 if (error) 476 if (error)
403 return error; 477 return error;
404 478
@@ -406,14 +480,14 @@ static ssize_t rfkill_claim_store(struct device *dev,
406 if (!claim) { 480 if (!claim) {
407 mutex_lock(&rfkill->mutex); 481 mutex_lock(&rfkill->mutex);
408 rfkill_toggle_radio(rfkill, 482 rfkill_toggle_radio(rfkill,
409 rfkill_states[rfkill->type], 483 rfkill_global_states[rfkill->type].current_state,
410 0); 484 0);
411 mutex_unlock(&rfkill->mutex); 485 mutex_unlock(&rfkill->mutex);
412 } 486 }
413 rfkill->user_claim = claim; 487 rfkill->user_claim = claim;
414 } 488 }
415 489
416 mutex_unlock(&rfkill_mutex); 490 mutex_unlock(&rfkill_global_mutex);
417 491
418 return error ? error : count; 492 return error ? error : count;
419} 493}
@@ -437,21 +511,9 @@ static void rfkill_release(struct device *dev)
437#ifdef CONFIG_PM 511#ifdef CONFIG_PM
438static int rfkill_suspend(struct device *dev, pm_message_t state) 512static int rfkill_suspend(struct device *dev, pm_message_t state)
439{ 513{
440 struct rfkill *rfkill = to_rfkill(dev); 514 /* mark class device as suspended */
441 515 if (dev->power.power_state.event != state.event)
442 if (dev->power.power_state.event != state.event) {
443 if (state.event & PM_EVENT_SLEEP) {
444 /* Stop transmitter, keep state, no notifies */
445 update_rfkill_state(rfkill);
446
447 mutex_lock(&rfkill->mutex);
448 rfkill->toggle_radio(rfkill->data,
449 RFKILL_STATE_SOFT_BLOCKED);
450 mutex_unlock(&rfkill->mutex);
451 }
452
453 dev->power.power_state = state; 516 dev->power.power_state = state;
454 }
455 517
456 return 0; 518 return 0;
457} 519}
@@ -525,24 +587,60 @@ static struct class rfkill_class = {
525 .dev_uevent = rfkill_dev_uevent, 587 .dev_uevent = rfkill_dev_uevent,
526}; 588};
527 589
590static int rfkill_check_duplicity(const struct rfkill *rfkill)
591{
592 struct rfkill *p;
593 unsigned long seen[BITS_TO_LONGS(RFKILL_TYPE_MAX)];
594
595 memset(seen, 0, sizeof(seen));
596
597 list_for_each_entry(p, &rfkill_list, node) {
598 if (WARN((p == rfkill), KERN_WARNING
599 "rfkill: illegal attempt to register "
600 "an already registered rfkill struct\n"))
601 return -EEXIST;
602 set_bit(p->type, seen);
603 }
604
605 /* 0: first switch of its kind */
606 return test_bit(rfkill->type, seen);
607}
608
528static int rfkill_add_switch(struct rfkill *rfkill) 609static int rfkill_add_switch(struct rfkill *rfkill)
529{ 610{
530 mutex_lock(&rfkill_mutex); 611 int error;
612
613 mutex_lock(&rfkill_global_mutex);
531 614
532 rfkill_toggle_radio(rfkill, rfkill_states[rfkill->type], 0); 615 error = rfkill_check_duplicity(rfkill);
616 if (error < 0)
617 goto unlock_out;
618
619 if (!error) {
620 /* lock default after first use */
621 set_bit(rfkill->type, rfkill_states_lockdflt);
622 rfkill_global_states[rfkill->type].current_state =
623 rfkill_global_states[rfkill->type].default_state;
624 }
625
626 rfkill_toggle_radio(rfkill,
627 rfkill_global_states[rfkill->type].current_state,
628 0);
533 629
534 list_add_tail(&rfkill->node, &rfkill_list); 630 list_add_tail(&rfkill->node, &rfkill_list);
535 631
536 mutex_unlock(&rfkill_mutex); 632 error = 0;
633unlock_out:
634 mutex_unlock(&rfkill_global_mutex);
537 635
538 return 0; 636 return error;
539} 637}
540 638
541static void rfkill_remove_switch(struct rfkill *rfkill) 639static void rfkill_remove_switch(struct rfkill *rfkill)
542{ 640{
543 mutex_lock(&rfkill_mutex); 641 mutex_lock(&rfkill_global_mutex);
544 list_del_init(&rfkill->node); 642 list_del_init(&rfkill->node);
545 mutex_unlock(&rfkill_mutex); 643 mutex_unlock(&rfkill_global_mutex);
546 644
547 mutex_lock(&rfkill->mutex); 645 mutex_lock(&rfkill->mutex);
548 rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1); 646 rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1);
@@ -562,11 +660,18 @@ static void rfkill_remove_switch(struct rfkill *rfkill)
562 * NOTE: If registration fails the structure shoudl be freed by calling 660 * NOTE: If registration fails the structure shoudl be freed by calling
563 * rfkill_free() otherwise rfkill_unregister() should be used. 661 * rfkill_free() otherwise rfkill_unregister() should be used.
564 */ 662 */
565struct rfkill *rfkill_allocate(struct device *parent, enum rfkill_type type) 663struct rfkill * __must_check rfkill_allocate(struct device *parent,
664 enum rfkill_type type)
566{ 665{
567 struct rfkill *rfkill; 666 struct rfkill *rfkill;
568 struct device *dev; 667 struct device *dev;
569 668
669 if (WARN((type >= RFKILL_TYPE_MAX),
670 KERN_WARNING
671 "rfkill: illegal type %d passed as parameter "
672 "to rfkill_allocate\n", type))
673 return NULL;
674
570 rfkill = kzalloc(sizeof(struct rfkill), GFP_KERNEL); 675 rfkill = kzalloc(sizeof(struct rfkill), GFP_KERNEL);
571 if (!rfkill) 676 if (!rfkill)
572 return NULL; 677 return NULL;
@@ -633,15 +738,18 @@ static void rfkill_led_trigger_unregister(struct rfkill *rfkill)
633 * structure needs to be registered. Immediately from registration the 738 * structure needs to be registered. Immediately from registration the
634 * switch driver should be able to service calls to toggle_radio. 739 * switch driver should be able to service calls to toggle_radio.
635 */ 740 */
636int rfkill_register(struct rfkill *rfkill) 741int __must_check rfkill_register(struct rfkill *rfkill)
637{ 742{
638 static atomic_t rfkill_no = ATOMIC_INIT(0); 743 static atomic_t rfkill_no = ATOMIC_INIT(0);
639 struct device *dev = &rfkill->dev; 744 struct device *dev = &rfkill->dev;
640 int error; 745 int error;
641 746
642 if (!rfkill->toggle_radio) 747 if (WARN((!rfkill || !rfkill->toggle_radio ||
643 return -EINVAL; 748 rfkill->type >= RFKILL_TYPE_MAX ||
644 if (rfkill->type >= RFKILL_TYPE_MAX) 749 rfkill->state >= RFKILL_STATE_MAX),
750 KERN_WARNING
751 "rfkill: attempt to register a "
752 "badly initialized rfkill struct\n"))
645 return -EINVAL; 753 return -EINVAL;
646 754
647 snprintf(dev->bus_id, sizeof(dev->bus_id), 755 snprintf(dev->bus_id, sizeof(dev->bus_id),
@@ -676,6 +784,7 @@ EXPORT_SYMBOL(rfkill_register);
676 */ 784 */
677void rfkill_unregister(struct rfkill *rfkill) 785void rfkill_unregister(struct rfkill *rfkill)
678{ 786{
787 BUG_ON(!rfkill);
679 device_del(&rfkill->dev); 788 device_del(&rfkill->dev);
680 rfkill_remove_switch(rfkill); 789 rfkill_remove_switch(rfkill);
681 rfkill_led_trigger_unregister(rfkill); 790 rfkill_led_trigger_unregister(rfkill);
@@ -683,6 +792,56 @@ void rfkill_unregister(struct rfkill *rfkill)
683} 792}
684EXPORT_SYMBOL(rfkill_unregister); 793EXPORT_SYMBOL(rfkill_unregister);
685 794
795/**
796 * rfkill_set_default - set initial value for a switch type
797 * @type - the type of switch to set the default state of
798 * @state - the new default state for that group of switches
799 *
800 * Sets the initial state rfkill should use for a given type.
801 * The following initial states are allowed: RFKILL_STATE_SOFT_BLOCKED
802 * and RFKILL_STATE_UNBLOCKED.
803 *
804 * This function is meant to be used by platform drivers for platforms
805 * that can save switch state across power down/reboot.
806 *
807 * The default state for each switch type can be changed exactly once.
808 * After a switch of that type is registered, the default state cannot
809 * be changed anymore. This guards against multiple drivers it the
810 * same platform trying to set the initial switch default state, which
811 * is not allowed.
812 *
813 * Returns -EPERM if the state has already been set once or is in use,
814 * so drivers likely want to either ignore or at most printk(KERN_NOTICE)
815 * if this function returns -EPERM.
816 *
817 * Returns 0 if the new default state was set, or an error if it
818 * could not be set.
819 */
820int rfkill_set_default(enum rfkill_type type, enum rfkill_state state)
821{
822 int error;
823
824 if (WARN((type >= RFKILL_TYPE_MAX ||
825 (state != RFKILL_STATE_SOFT_BLOCKED &&
826 state != RFKILL_STATE_UNBLOCKED)),
827 KERN_WARNING
828 "rfkill: illegal state %d or type %d passed as "
829 "parameter to rfkill_set_default\n", state, type))
830 return -EINVAL;
831
832 mutex_lock(&rfkill_global_mutex);
833
834 if (!test_and_set_bit(type, rfkill_states_lockdflt)) {
835 rfkill_global_states[type].default_state = state;
836 error = 0;
837 } else
838 error = -EPERM;
839
840 mutex_unlock(&rfkill_global_mutex);
841 return error;
842}
843EXPORT_SYMBOL_GPL(rfkill_set_default);
844
686/* 845/*
687 * Rfkill module initialization/deinitialization. 846 * Rfkill module initialization/deinitialization.
688 */ 847 */
@@ -696,8 +855,8 @@ static int __init rfkill_init(void)
696 rfkill_default_state != RFKILL_STATE_UNBLOCKED) 855 rfkill_default_state != RFKILL_STATE_UNBLOCKED)
697 return -EINVAL; 856 return -EINVAL;
698 857
699 for (i = 0; i < ARRAY_SIZE(rfkill_states); i++) 858 for (i = 0; i < RFKILL_TYPE_MAX; i++)
700 rfkill_states[i] = rfkill_default_state; 859 rfkill_global_states[i].default_state = rfkill_default_state;
701 860
702 error = class_register(&rfkill_class); 861 error = class_register(&rfkill_class);
703 if (error) { 862 if (error) {
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index 9437b27ff84d..6767e54155db 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -106,6 +106,15 @@ config NET_SCH_PRIO
106 To compile this code as a module, choose M here: the 106 To compile this code as a module, choose M here: the
107 module will be called sch_prio. 107 module will be called sch_prio.
108 108
109config NET_SCH_MULTIQ
110 tristate "Hardware Multiqueue-aware Multi Band Queuing (MULTIQ)"
111 ---help---
112 Say Y here if you want to use an n-band queue packet scheduler
113 to support devices that have multiple hardware transmit queues.
114
115 To compile this code as a module, choose M here: the
116 module will be called sch_multiq.
117
109config NET_SCH_RED 118config NET_SCH_RED
110 tristate "Random Early Detection (RED)" 119 tristate "Random Early Detection (RED)"
111 ---help--- 120 ---help---
@@ -476,6 +485,17 @@ config NET_ACT_SIMP
476 To compile this code as a module, choose M here: the 485 To compile this code as a module, choose M here: the
477 module will be called simple. 486 module will be called simple.
478 487
488config NET_ACT_SKBEDIT
489 tristate "SKB Editing"
490 depends on NET_CLS_ACT
491 ---help---
492 Say Y here to change skb priority or queue_mapping settings.
493
494 If unsure, say N.
495
496 To compile this code as a module, choose M here: the
497 module will be called skbedit.
498
479config NET_CLS_IND 499config NET_CLS_IND
480 bool "Incoming device classification" 500 bool "Incoming device classification"
481 depends on NET_CLS_U32 || NET_CLS_FW 501 depends on NET_CLS_U32 || NET_CLS_FW
diff --git a/net/sched/Makefile b/net/sched/Makefile
index 1d2b0f7df848..e60c9925b269 100644
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_NET_ACT_IPT) += act_ipt.o
14obj-$(CONFIG_NET_ACT_NAT) += act_nat.o 14obj-$(CONFIG_NET_ACT_NAT) += act_nat.o
15obj-$(CONFIG_NET_ACT_PEDIT) += act_pedit.o 15obj-$(CONFIG_NET_ACT_PEDIT) += act_pedit.o
16obj-$(CONFIG_NET_ACT_SIMP) += act_simple.o 16obj-$(CONFIG_NET_ACT_SIMP) += act_simple.o
17obj-$(CONFIG_NET_ACT_SKBEDIT) += act_skbedit.o
17obj-$(CONFIG_NET_SCH_FIFO) += sch_fifo.o 18obj-$(CONFIG_NET_SCH_FIFO) += sch_fifo.o
18obj-$(CONFIG_NET_SCH_CBQ) += sch_cbq.o 19obj-$(CONFIG_NET_SCH_CBQ) += sch_cbq.o
19obj-$(CONFIG_NET_SCH_HTB) += sch_htb.o 20obj-$(CONFIG_NET_SCH_HTB) += sch_htb.o
@@ -26,6 +27,7 @@ obj-$(CONFIG_NET_SCH_SFQ) += sch_sfq.o
26obj-$(CONFIG_NET_SCH_TBF) += sch_tbf.o 27obj-$(CONFIG_NET_SCH_TBF) += sch_tbf.o
27obj-$(CONFIG_NET_SCH_TEQL) += sch_teql.o 28obj-$(CONFIG_NET_SCH_TEQL) += sch_teql.o
28obj-$(CONFIG_NET_SCH_PRIO) += sch_prio.o 29obj-$(CONFIG_NET_SCH_PRIO) += sch_prio.o
30obj-$(CONFIG_NET_SCH_MULTIQ) += sch_multiq.o
29obj-$(CONFIG_NET_SCH_ATM) += sch_atm.o 31obj-$(CONFIG_NET_SCH_ATM) += sch_atm.o
30obj-$(CONFIG_NET_SCH_NETEM) += sch_netem.o 32obj-$(CONFIG_NET_SCH_NETEM) += sch_netem.o
31obj-$(CONFIG_NET_CLS_U32) += cls_u32.o 33obj-$(CONFIG_NET_CLS_U32) += cls_u32.o
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
index d1263b3c96c3..0453d79ebf57 100644
--- a/net/sched/act_ipt.c
+++ b/net/sched/act_ipt.c
@@ -40,6 +40,7 @@ static struct tcf_hashinfo ipt_hash_info = {
40 40
41static int ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int hook) 41static int ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int hook)
42{ 42{
43 struct xt_tgchk_param par;
43 struct xt_target *target; 44 struct xt_target *target;
44 int ret = 0; 45 int ret = 0;
45 46
@@ -49,29 +50,30 @@ static int ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int
49 return -ENOENT; 50 return -ENOENT;
50 51
51 t->u.kernel.target = target; 52 t->u.kernel.target = target;
52 53 par.table = table;
53 ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t), 54 par.entryinfo = NULL;
54 table, hook, 0, 0); 55 par.target = target;
55 if (ret) { 56 par.targinfo = t->data;
57 par.hook_mask = hook;
58 par.family = NFPROTO_IPV4;
59
60 ret = xt_check_target(&par, t->u.target_size - sizeof(*t), 0, false);
61 if (ret < 0) {
56 module_put(t->u.kernel.target->me); 62 module_put(t->u.kernel.target->me);
57 return ret; 63 return ret;
58 } 64 }
59 if (t->u.kernel.target->checkentry 65 return 0;
60 && !t->u.kernel.target->checkentry(table, NULL,
61 t->u.kernel.target, t->data,
62 hook)) {
63 module_put(t->u.kernel.target->me);
64 ret = -EINVAL;
65 }
66
67 return ret;
68} 66}
69 67
70static void ipt_destroy_target(struct ipt_entry_target *t) 68static void ipt_destroy_target(struct ipt_entry_target *t)
71{ 69{
72 if (t->u.kernel.target->destroy) 70 struct xt_tgdtor_param par = {
73 t->u.kernel.target->destroy(t->u.kernel.target, t->data); 71 .target = t->u.kernel.target,
74 module_put(t->u.kernel.target->me); 72 .targinfo = t->data,
73 };
74 if (par.target->destroy != NULL)
75 par.target->destroy(&par);
76 module_put(par.target->me);
75} 77}
76 78
77static int tcf_ipt_release(struct tcf_ipt *ipt, int bind) 79static int tcf_ipt_release(struct tcf_ipt *ipt, int bind)
@@ -196,6 +198,7 @@ static int tcf_ipt(struct sk_buff *skb, struct tc_action *a,
196{ 198{
197 int ret = 0, result = 0; 199 int ret = 0, result = 0;
198 struct tcf_ipt *ipt = a->priv; 200 struct tcf_ipt *ipt = a->priv;
201 struct xt_target_param par;
199 202
200 if (skb_cloned(skb)) { 203 if (skb_cloned(skb)) {
201 if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) 204 if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
@@ -211,10 +214,13 @@ static int tcf_ipt(struct sk_buff *skb, struct tc_action *a,
211 /* yes, we have to worry about both in and out dev 214 /* yes, we have to worry about both in and out dev
212 worry later - danger - this API seems to have changed 215 worry later - danger - this API seems to have changed
213 from earlier kernels */ 216 from earlier kernels */
214 ret = ipt->tcfi_t->u.kernel.target->target(skb, skb->dev, NULL, 217 par.in = skb->dev;
215 ipt->tcfi_hook, 218 par.out = NULL;
216 ipt->tcfi_t->u.kernel.target, 219 par.hooknum = ipt->tcfi_hook;
217 ipt->tcfi_t->data); 220 par.target = ipt->tcfi_t->u.kernel.target;
221 par.targinfo = ipt->tcfi_t->data;
222 ret = par.target->target(skb, &par);
223
218 switch (ret) { 224 switch (ret) {
219 case NF_ACCEPT: 225 case NF_ACCEPT:
220 result = TC_ACT_OK; 226 result = TC_ACT_OK;
diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c
new file mode 100644
index 000000000000..fe9777e77f35
--- /dev/null
+++ b/net/sched/act_skbedit.c
@@ -0,0 +1,203 @@
1/*
2 * Copyright (c) 2008, Intel Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15 * Place - Suite 330, Boston, MA 02111-1307 USA.
16 *
17 * Author: Alexander Duyck <alexander.h.duyck@intel.com>
18 */
19
20#include <linux/module.h>
21#include <linux/init.h>
22#include <linux/kernel.h>
23#include <linux/skbuff.h>
24#include <linux/rtnetlink.h>
25#include <net/netlink.h>
26#include <net/pkt_sched.h>
27
28#include <linux/tc_act/tc_skbedit.h>
29#include <net/tc_act/tc_skbedit.h>
30
31#define SKBEDIT_TAB_MASK 15
32static struct tcf_common *tcf_skbedit_ht[SKBEDIT_TAB_MASK + 1];
33static u32 skbedit_idx_gen;
34static DEFINE_RWLOCK(skbedit_lock);
35
36static struct tcf_hashinfo skbedit_hash_info = {
37 .htab = tcf_skbedit_ht,
38 .hmask = SKBEDIT_TAB_MASK,
39 .lock = &skbedit_lock,
40};
41
42static int tcf_skbedit(struct sk_buff *skb, struct tc_action *a,
43 struct tcf_result *res)
44{
45 struct tcf_skbedit *d = a->priv;
46
47 spin_lock(&d->tcf_lock);
48 d->tcf_tm.lastuse = jiffies;
49 d->tcf_bstats.bytes += qdisc_pkt_len(skb);
50 d->tcf_bstats.packets++;
51
52 if (d->flags & SKBEDIT_F_PRIORITY)
53 skb->priority = d->priority;
54 if (d->flags & SKBEDIT_F_QUEUE_MAPPING &&
55 skb->dev->real_num_tx_queues > d->queue_mapping)
56 skb_set_queue_mapping(skb, d->queue_mapping);
57
58 spin_unlock(&d->tcf_lock);
59 return d->tcf_action;
60}
61
62static const struct nla_policy skbedit_policy[TCA_SKBEDIT_MAX + 1] = {
63 [TCA_SKBEDIT_PARMS] = { .len = sizeof(struct tc_skbedit) },
64 [TCA_SKBEDIT_PRIORITY] = { .len = sizeof(u32) },
65 [TCA_SKBEDIT_QUEUE_MAPPING] = { .len = sizeof(u16) },
66};
67
68static int tcf_skbedit_init(struct nlattr *nla, struct nlattr *est,
69 struct tc_action *a, int ovr, int bind)
70{
71 struct nlattr *tb[TCA_SKBEDIT_MAX + 1];
72 struct tc_skbedit *parm;
73 struct tcf_skbedit *d;
74 struct tcf_common *pc;
75 u32 flags = 0, *priority = NULL;
76 u16 *queue_mapping = NULL;
77 int ret = 0, err;
78
79 if (nla == NULL)
80 return -EINVAL;
81
82 err = nla_parse_nested(tb, TCA_SKBEDIT_MAX, nla, skbedit_policy);
83 if (err < 0)
84 return err;
85
86 if (tb[TCA_SKBEDIT_PARMS] == NULL)
87 return -EINVAL;
88
89 if (tb[TCA_SKBEDIT_PRIORITY] != NULL) {
90 flags |= SKBEDIT_F_PRIORITY;
91 priority = nla_data(tb[TCA_SKBEDIT_PRIORITY]);
92 }
93
94 if (tb[TCA_SKBEDIT_QUEUE_MAPPING] != NULL) {
95 flags |= SKBEDIT_F_QUEUE_MAPPING;
96 queue_mapping = nla_data(tb[TCA_SKBEDIT_QUEUE_MAPPING]);
97 }
98 if (!flags)
99 return -EINVAL;
100
101 parm = nla_data(tb[TCA_SKBEDIT_PARMS]);
102
103 pc = tcf_hash_check(parm->index, a, bind, &skbedit_hash_info);
104 if (!pc) {
105 pc = tcf_hash_create(parm->index, est, a, sizeof(*d), bind,
106 &skbedit_idx_gen, &skbedit_hash_info);
107 if (unlikely(!pc))
108 return -ENOMEM;
109
110 d = to_skbedit(pc);
111 ret = ACT_P_CREATED;
112 } else {
113 d = to_skbedit(pc);
114 if (!ovr) {
115 tcf_hash_release(pc, bind, &skbedit_hash_info);
116 return -EEXIST;
117 }
118 }
119
120 spin_lock_bh(&d->tcf_lock);
121
122 d->flags = flags;
123 if (flags & SKBEDIT_F_PRIORITY)
124 d->priority = *priority;
125 if (flags & SKBEDIT_F_QUEUE_MAPPING)
126 d->queue_mapping = *queue_mapping;
127 d->tcf_action = parm->action;
128
129 spin_unlock_bh(&d->tcf_lock);
130
131 if (ret == ACT_P_CREATED)
132 tcf_hash_insert(pc, &skbedit_hash_info);
133 return ret;
134}
135
136static inline int tcf_skbedit_cleanup(struct tc_action *a, int bind)
137{
138 struct tcf_skbedit *d = a->priv;
139
140 if (d)
141 return tcf_hash_release(&d->common, bind, &skbedit_hash_info);
142 return 0;
143}
144
145static inline int tcf_skbedit_dump(struct sk_buff *skb, struct tc_action *a,
146 int bind, int ref)
147{
148 unsigned char *b = skb_tail_pointer(skb);
149 struct tcf_skbedit *d = a->priv;
150 struct tc_skbedit opt;
151 struct tcf_t t;
152
153 opt.index = d->tcf_index;
154 opt.refcnt = d->tcf_refcnt - ref;
155 opt.bindcnt = d->tcf_bindcnt - bind;
156 opt.action = d->tcf_action;
157 NLA_PUT(skb, TCA_SKBEDIT_PARMS, sizeof(opt), &opt);
158 if (d->flags & SKBEDIT_F_PRIORITY)
159 NLA_PUT(skb, TCA_SKBEDIT_PRIORITY, sizeof(d->priority),
160 &d->priority);
161 if (d->flags & SKBEDIT_F_QUEUE_MAPPING)
162 NLA_PUT(skb, TCA_SKBEDIT_QUEUE_MAPPING,
163 sizeof(d->queue_mapping), &d->queue_mapping);
164 t.install = jiffies_to_clock_t(jiffies - d->tcf_tm.install);
165 t.lastuse = jiffies_to_clock_t(jiffies - d->tcf_tm.lastuse);
166 t.expires = jiffies_to_clock_t(d->tcf_tm.expires);
167 NLA_PUT(skb, TCA_SKBEDIT_TM, sizeof(t), &t);
168 return skb->len;
169
170nla_put_failure:
171 nlmsg_trim(skb, b);
172 return -1;
173}
174
175static struct tc_action_ops act_skbedit_ops = {
176 .kind = "skbedit",
177 .hinfo = &skbedit_hash_info,
178 .type = TCA_ACT_SKBEDIT,
179 .capab = TCA_CAP_NONE,
180 .owner = THIS_MODULE,
181 .act = tcf_skbedit,
182 .dump = tcf_skbedit_dump,
183 .cleanup = tcf_skbedit_cleanup,
184 .init = tcf_skbedit_init,
185 .walk = tcf_generic_walker,
186};
187
188MODULE_AUTHOR("Alexander Duyck, <alexander.h.duyck@intel.com>");
189MODULE_DESCRIPTION("SKB Editing");
190MODULE_LICENSE("GPL");
191
192static int __init skbedit_init_module(void)
193{
194 return tcf_register_action(&act_skbedit_ops);
195}
196
197static void __exit skbedit_cleanup_module(void)
198{
199 tcf_unregister_action(&act_skbedit_ops);
200}
201
202module_init(skbedit_init_module);
203module_exit(skbedit_cleanup_module);
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 5cafdd4c8018..8eb79e92e94c 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -205,7 +205,7 @@ replay:
205 } 205 }
206 } 206 }
207 207
208 root_lock = qdisc_root_lock(q); 208 root_lock = qdisc_root_sleeping_lock(q);
209 209
210 if (tp == NULL) { 210 if (tp == NULL) {
211 /* Proto-tcf does not exist, create new one */ 211 /* Proto-tcf does not exist, create new one */
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
index 8f63a1a94014..0ebaff637e31 100644
--- a/net/sched/cls_flow.c
+++ b/net/sched/cls_flow.c
@@ -67,9 +67,9 @@ static inline u32 addr_fold(void *addr)
67static u32 flow_get_src(const struct sk_buff *skb) 67static u32 flow_get_src(const struct sk_buff *skb)
68{ 68{
69 switch (skb->protocol) { 69 switch (skb->protocol) {
70 case __constant_htons(ETH_P_IP): 70 case htons(ETH_P_IP):
71 return ntohl(ip_hdr(skb)->saddr); 71 return ntohl(ip_hdr(skb)->saddr);
72 case __constant_htons(ETH_P_IPV6): 72 case htons(ETH_P_IPV6):
73 return ntohl(ipv6_hdr(skb)->saddr.s6_addr32[3]); 73 return ntohl(ipv6_hdr(skb)->saddr.s6_addr32[3]);
74 default: 74 default:
75 return addr_fold(skb->sk); 75 return addr_fold(skb->sk);
@@ -79,9 +79,9 @@ static u32 flow_get_src(const struct sk_buff *skb)
79static u32 flow_get_dst(const struct sk_buff *skb) 79static u32 flow_get_dst(const struct sk_buff *skb)
80{ 80{
81 switch (skb->protocol) { 81 switch (skb->protocol) {
82 case __constant_htons(ETH_P_IP): 82 case htons(ETH_P_IP):
83 return ntohl(ip_hdr(skb)->daddr); 83 return ntohl(ip_hdr(skb)->daddr);
84 case __constant_htons(ETH_P_IPV6): 84 case htons(ETH_P_IPV6):
85 return ntohl(ipv6_hdr(skb)->daddr.s6_addr32[3]); 85 return ntohl(ipv6_hdr(skb)->daddr.s6_addr32[3]);
86 default: 86 default:
87 return addr_fold(skb->dst) ^ (__force u16)skb->protocol; 87 return addr_fold(skb->dst) ^ (__force u16)skb->protocol;
@@ -91,9 +91,9 @@ static u32 flow_get_dst(const struct sk_buff *skb)
91static u32 flow_get_proto(const struct sk_buff *skb) 91static u32 flow_get_proto(const struct sk_buff *skb)
92{ 92{
93 switch (skb->protocol) { 93 switch (skb->protocol) {
94 case __constant_htons(ETH_P_IP): 94 case htons(ETH_P_IP):
95 return ip_hdr(skb)->protocol; 95 return ip_hdr(skb)->protocol;
96 case __constant_htons(ETH_P_IPV6): 96 case htons(ETH_P_IPV6):
97 return ipv6_hdr(skb)->nexthdr; 97 return ipv6_hdr(skb)->nexthdr;
98 default: 98 default:
99 return 0; 99 return 0;
@@ -120,7 +120,7 @@ static u32 flow_get_proto_src(const struct sk_buff *skb)
120 u32 res = 0; 120 u32 res = 0;
121 121
122 switch (skb->protocol) { 122 switch (skb->protocol) {
123 case __constant_htons(ETH_P_IP): { 123 case htons(ETH_P_IP): {
124 struct iphdr *iph = ip_hdr(skb); 124 struct iphdr *iph = ip_hdr(skb);
125 125
126 if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && 126 if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
@@ -128,7 +128,7 @@ static u32 flow_get_proto_src(const struct sk_buff *skb)
128 res = ntohs(*(__be16 *)((void *)iph + iph->ihl * 4)); 128 res = ntohs(*(__be16 *)((void *)iph + iph->ihl * 4));
129 break; 129 break;
130 } 130 }
131 case __constant_htons(ETH_P_IPV6): { 131 case htons(ETH_P_IPV6): {
132 struct ipv6hdr *iph = ipv6_hdr(skb); 132 struct ipv6hdr *iph = ipv6_hdr(skb);
133 133
134 if (has_ports(iph->nexthdr)) 134 if (has_ports(iph->nexthdr))
@@ -147,7 +147,7 @@ static u32 flow_get_proto_dst(const struct sk_buff *skb)
147 u32 res = 0; 147 u32 res = 0;
148 148
149 switch (skb->protocol) { 149 switch (skb->protocol) {
150 case __constant_htons(ETH_P_IP): { 150 case htons(ETH_P_IP): {
151 struct iphdr *iph = ip_hdr(skb); 151 struct iphdr *iph = ip_hdr(skb);
152 152
153 if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && 153 if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
@@ -155,7 +155,7 @@ static u32 flow_get_proto_dst(const struct sk_buff *skb)
155 res = ntohs(*(__be16 *)((void *)iph + iph->ihl * 4 + 2)); 155 res = ntohs(*(__be16 *)((void *)iph + iph->ihl * 4 + 2));
156 break; 156 break;
157 } 157 }
158 case __constant_htons(ETH_P_IPV6): { 158 case htons(ETH_P_IPV6): {
159 struct ipv6hdr *iph = ipv6_hdr(skb); 159 struct ipv6hdr *iph = ipv6_hdr(skb);
160 160
161 if (has_ports(iph->nexthdr)) 161 if (has_ports(iph->nexthdr))
@@ -213,9 +213,9 @@ static u32 flow_get_nfct(const struct sk_buff *skb)
213static u32 flow_get_nfct_src(const struct sk_buff *skb) 213static u32 flow_get_nfct_src(const struct sk_buff *skb)
214{ 214{
215 switch (skb->protocol) { 215 switch (skb->protocol) {
216 case __constant_htons(ETH_P_IP): 216 case htons(ETH_P_IP):
217 return ntohl(CTTUPLE(skb, src.u3.ip)); 217 return ntohl(CTTUPLE(skb, src.u3.ip));
218 case __constant_htons(ETH_P_IPV6): 218 case htons(ETH_P_IPV6):
219 return ntohl(CTTUPLE(skb, src.u3.ip6[3])); 219 return ntohl(CTTUPLE(skb, src.u3.ip6[3]));
220 } 220 }
221fallback: 221fallback:
@@ -225,9 +225,9 @@ fallback:
225static u32 flow_get_nfct_dst(const struct sk_buff *skb) 225static u32 flow_get_nfct_dst(const struct sk_buff *skb)
226{ 226{
227 switch (skb->protocol) { 227 switch (skb->protocol) {
228 case __constant_htons(ETH_P_IP): 228 case htons(ETH_P_IP):
229 return ntohl(CTTUPLE(skb, dst.u3.ip)); 229 return ntohl(CTTUPLE(skb, dst.u3.ip));
230 case __constant_htons(ETH_P_IPV6): 230 case htons(ETH_P_IPV6):
231 return ntohl(CTTUPLE(skb, dst.u3.ip6[3])); 231 return ntohl(CTTUPLE(skb, dst.u3.ip6[3]));
232 } 232 }
233fallback: 233fallback:
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index 481260a4f10f..e3d8455eebc2 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -75,7 +75,7 @@ static __inline__ int route4_fastmap_hash(u32 id, int iif)
75static inline 75static inline
76void route4_reset_fastmap(struct Qdisc *q, struct route4_head *head, u32 id) 76void route4_reset_fastmap(struct Qdisc *q, struct route4_head *head, u32 id)
77{ 77{
78 spinlock_t *root_lock = qdisc_root_lock(q); 78 spinlock_t *root_lock = qdisc_root_sleeping_lock(q);
79 79
80 spin_lock_bh(root_lock); 80 spin_lock_bh(root_lock);
81 memset(head->fastmap, 0, sizeof(head->fastmap)); 81 memset(head->fastmap, 0, sizeof(head->fastmap));
diff --git a/net/sched/em_cmp.c b/net/sched/em_cmp.c
index cc49c932641d..bc450397487a 100644
--- a/net/sched/em_cmp.c
+++ b/net/sched/em_cmp.c
@@ -14,6 +14,7 @@
14#include <linux/kernel.h> 14#include <linux/kernel.h>
15#include <linux/skbuff.h> 15#include <linux/skbuff.h>
16#include <linux/tc_ematch/tc_em_cmp.h> 16#include <linux/tc_ematch/tc_em_cmp.h>
17#include <asm/unaligned.h>
17#include <net/pkt_cls.h> 18#include <net/pkt_cls.h>
18 19
19static inline int cmp_needs_transformation(struct tcf_em_cmp *cmp) 20static inline int cmp_needs_transformation(struct tcf_em_cmp *cmp)
@@ -37,8 +38,7 @@ static int em_cmp_match(struct sk_buff *skb, struct tcf_ematch *em,
37 break; 38 break;
38 39
39 case TCF_EM_ALIGN_U16: 40 case TCF_EM_ALIGN_U16:
40 val = *ptr << 8; 41 val = get_unaligned_be16(ptr);
41 val |= *(ptr+1);
42 42
43 if (cmp_needs_transformation(cmp)) 43 if (cmp_needs_transformation(cmp))
44 val = be16_to_cpu(val); 44 val = be16_to_cpu(val);
@@ -47,10 +47,7 @@ static int em_cmp_match(struct sk_buff *skb, struct tcf_ematch *em,
47 case TCF_EM_ALIGN_U32: 47 case TCF_EM_ALIGN_U32:
48 /* Worth checking boundries? The branching seems 48 /* Worth checking boundries? The branching seems
49 * to get worse. Visit again. */ 49 * to get worse. Visit again. */
50 val = *ptr << 24; 50 val = get_unaligned_be32(ptr);
51 val |= *(ptr+1) << 16;
52 val |= *(ptr+2) << 8;
53 val |= *(ptr+3);
54 51
55 if (cmp_needs_transformation(cmp)) 52 if (cmp_needs_transformation(cmp))
56 val = be32_to_cpu(val); 53 val = be32_to_cpu(val);
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 506b709510b6..1122c952aa99 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1169,8 +1169,8 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
1169 if (q->stab && qdisc_dump_stab(skb, q->stab) < 0) 1169 if (q->stab && qdisc_dump_stab(skb, q->stab) < 0)
1170 goto nla_put_failure; 1170 goto nla_put_failure;
1171 1171
1172 if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS, 1172 if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS, TCA_XSTATS,
1173 TCA_XSTATS, qdisc_root_lock(q), &d) < 0) 1173 qdisc_root_sleeping_lock(q), &d) < 0)
1174 goto nla_put_failure; 1174 goto nla_put_failure;
1175 1175
1176 if (q->ops->dump_stats && q->ops->dump_stats(q, &d) < 0) 1176 if (q->ops->dump_stats && q->ops->dump_stats(q, &d) < 0)
@@ -1461,8 +1461,8 @@ static int tc_fill_tclass(struct sk_buff *skb, struct Qdisc *q,
1461 if (cl_ops->dump && cl_ops->dump(q, cl, skb, tcm) < 0) 1461 if (cl_ops->dump && cl_ops->dump(q, cl, skb, tcm) < 0)
1462 goto nla_put_failure; 1462 goto nla_put_failure;
1463 1463
1464 if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS, 1464 if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS, TCA_XSTATS,
1465 TCA_XSTATS, qdisc_root_lock(q), &d) < 0) 1465 qdisc_root_sleeping_lock(q), &d) < 0)
1466 goto nla_put_failure; 1466 goto nla_put_failure;
1467 1467
1468 if (cl_ops->dump_stats && cl_ops->dump_stats(q, cl, &d) < 0) 1468 if (cl_ops->dump_stats && cl_ops->dump_stats(q, cl, &d) < 0)
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index 9b720adedead..8b06fa900482 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -1754,7 +1754,7 @@ static void cbq_put(struct Qdisc *sch, unsigned long arg)
1754 1754
1755 if (--cl->refcnt == 0) { 1755 if (--cl->refcnt == 0) {
1756#ifdef CONFIG_NET_CLS_ACT 1756#ifdef CONFIG_NET_CLS_ACT
1757 spinlock_t *root_lock = qdisc_root_lock(sch); 1757 spinlock_t *root_lock = qdisc_root_sleeping_lock(sch);
1758 struct cbq_sched_data *q = qdisc_priv(sch); 1758 struct cbq_sched_data *q = qdisc_priv(sch);
1759 1759
1760 spin_lock_bh(root_lock); 1760 spin_lock_bh(root_lock);
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
index edd1298f85f6..ba43aab3a851 100644
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -202,7 +202,7 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch)
202 202
203 if (p->set_tc_index) { 203 if (p->set_tc_index) {
204 switch (skb->protocol) { 204 switch (skb->protocol) {
205 case __constant_htons(ETH_P_IP): 205 case htons(ETH_P_IP):
206 if (skb_cow_head(skb, sizeof(struct iphdr))) 206 if (skb_cow_head(skb, sizeof(struct iphdr)))
207 goto drop; 207 goto drop;
208 208
@@ -210,7 +210,7 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch)
210 & ~INET_ECN_MASK; 210 & ~INET_ECN_MASK;
211 break; 211 break;
212 212
213 case __constant_htons(ETH_P_IPV6): 213 case htons(ETH_P_IPV6):
214 if (skb_cow_head(skb, sizeof(struct ipv6hdr))) 214 if (skb_cow_head(skb, sizeof(struct ipv6hdr)))
215 goto drop; 215 goto drop;
216 216
@@ -289,11 +289,11 @@ static struct sk_buff *dsmark_dequeue(struct Qdisc *sch)
289 pr_debug("index %d->%d\n", skb->tc_index, index); 289 pr_debug("index %d->%d\n", skb->tc_index, index);
290 290
291 switch (skb->protocol) { 291 switch (skb->protocol) {
292 case __constant_htons(ETH_P_IP): 292 case htons(ETH_P_IP):
293 ipv4_change_dsfield(ip_hdr(skb), p->mask[index], 293 ipv4_change_dsfield(ip_hdr(skb), p->mask[index],
294 p->value[index]); 294 p->value[index]);
295 break; 295 break;
296 case __constant_htons(ETH_P_IPV6): 296 case htons(ETH_P_IPV6):
297 ipv6_change_dsfield(ipv6_hdr(skb), p->mask[index], 297 ipv6_change_dsfield(ipv6_hdr(skb), p->mask[index],
298 p->value[index]); 298 p->value[index]);
299 break; 299 break;
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 9634091ee2f0..7b5572d6beb5 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -44,23 +44,30 @@ static inline int qdisc_qlen(struct Qdisc *q)
44 44
45static inline int dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q) 45static inline int dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q)
46{ 46{
47 if (unlikely(skb->next)) 47 q->gso_skb = skb;
48 q->gso_skb = skb; 48 q->qstats.requeues++;
49 else
50 q->ops->requeue(skb, q);
51
52 __netif_schedule(q); 49 __netif_schedule(q);
50
53 return 0; 51 return 0;
54} 52}
55 53
56static inline struct sk_buff *dequeue_skb(struct Qdisc *q) 54static inline struct sk_buff *dequeue_skb(struct Qdisc *q)
57{ 55{
58 struct sk_buff *skb; 56 struct sk_buff *skb = q->gso_skb;
59 57
60 if ((skb = q->gso_skb)) 58 if (unlikely(skb)) {
61 q->gso_skb = NULL; 59 struct net_device *dev = qdisc_dev(q);
62 else 60 struct netdev_queue *txq;
61
62 /* check the reason of requeuing without tx lock first */
63 txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
64 if (!netif_tx_queue_stopped(txq) && !netif_tx_queue_frozen(txq))
65 q->gso_skb = NULL;
66 else
67 skb = NULL;
68 } else {
63 skb = q->dequeue(q); 69 skb = q->dequeue(q);
70 }
64 71
65 return skb; 72 return skb;
66} 73}
@@ -215,10 +222,9 @@ static void dev_watchdog(unsigned long arg)
215 time_after(jiffies, (dev->trans_start + 222 time_after(jiffies, (dev->trans_start +
216 dev->watchdog_timeo))) { 223 dev->watchdog_timeo))) {
217 char drivername[64]; 224 char drivername[64];
218 printk(KERN_INFO "NETDEV WATCHDOG: %s (%s): transmit timed out\n", 225 WARN_ONCE(1, KERN_INFO "NETDEV WATCHDOG: %s (%s): transmit timed out\n",
219 dev->name, netdev_drivername(dev, drivername, 64)); 226 dev->name, netdev_drivername(dev, drivername, 64));
220 dev->tx_timeout(dev); 227 dev->tx_timeout(dev);
221 WARN_ON_ONCE(1);
222 } 228 }
223 if (!mod_timer(&dev->watchdog_timer, 229 if (!mod_timer(&dev->watchdog_timer,
224 round_jiffies(jiffies + 230 round_jiffies(jiffies +
@@ -328,6 +334,7 @@ struct Qdisc noop_qdisc = {
328 .flags = TCQ_F_BUILTIN, 334 .flags = TCQ_F_BUILTIN,
329 .ops = &noop_qdisc_ops, 335 .ops = &noop_qdisc_ops,
330 .list = LIST_HEAD_INIT(noop_qdisc.list), 336 .list = LIST_HEAD_INIT(noop_qdisc.list),
337 .requeue.lock = __SPIN_LOCK_UNLOCKED(noop_qdisc.q.lock),
331 .q.lock = __SPIN_LOCK_UNLOCKED(noop_qdisc.q.lock), 338 .q.lock = __SPIN_LOCK_UNLOCKED(noop_qdisc.q.lock),
332 .dev_queue = &noop_netdev_queue, 339 .dev_queue = &noop_netdev_queue,
333}; 340};
@@ -353,6 +360,7 @@ static struct Qdisc noqueue_qdisc = {
353 .flags = TCQ_F_BUILTIN, 360 .flags = TCQ_F_BUILTIN,
354 .ops = &noqueue_qdisc_ops, 361 .ops = &noqueue_qdisc_ops,
355 .list = LIST_HEAD_INIT(noqueue_qdisc.list), 362 .list = LIST_HEAD_INIT(noqueue_qdisc.list),
363 .requeue.lock = __SPIN_LOCK_UNLOCKED(noqueue_qdisc.q.lock),
356 .q.lock = __SPIN_LOCK_UNLOCKED(noqueue_qdisc.q.lock), 364 .q.lock = __SPIN_LOCK_UNLOCKED(noqueue_qdisc.q.lock),
357 .dev_queue = &noqueue_netdev_queue, 365 .dev_queue = &noqueue_netdev_queue,
358}; 366};
@@ -473,6 +481,7 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
473 sch->padded = (char *) sch - (char *) p; 481 sch->padded = (char *) sch - (char *) p;
474 482
475 INIT_LIST_HEAD(&sch->list); 483 INIT_LIST_HEAD(&sch->list);
484 skb_queue_head_init(&sch->requeue);
476 skb_queue_head_init(&sch->q); 485 skb_queue_head_init(&sch->q);
477 sch->ops = ops; 486 sch->ops = ops;
478 sch->enqueue = ops->enqueue; 487 sch->enqueue = ops->enqueue;
@@ -541,6 +550,7 @@ void qdisc_destroy(struct Qdisc *qdisc)
541 dev_put(qdisc_dev(qdisc)); 550 dev_put(qdisc_dev(qdisc));
542 551
543 kfree_skb(qdisc->gso_skb); 552 kfree_skb(qdisc->gso_skb);
553 __skb_queue_purge(&qdisc->requeue);
544 554
545 kfree((char *) qdisc - qdisc->padded); 555 kfree((char *) qdisc - qdisc->padded);
546} 556}
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 97d4761cc31e..d14f02056ae6 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -1043,7 +1043,7 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt)
1043 1043
1044static int htb_dump(struct Qdisc *sch, struct sk_buff *skb) 1044static int htb_dump(struct Qdisc *sch, struct sk_buff *skb)
1045{ 1045{
1046 spinlock_t *root_lock = qdisc_root_lock(sch); 1046 spinlock_t *root_lock = qdisc_root_sleeping_lock(sch);
1047 struct htb_sched *q = qdisc_priv(sch); 1047 struct htb_sched *q = qdisc_priv(sch);
1048 struct nlattr *nest; 1048 struct nlattr *nest;
1049 struct tc_htb_glob gopt; 1049 struct tc_htb_glob gopt;
@@ -1075,7 +1075,7 @@ static int htb_dump_class(struct Qdisc *sch, unsigned long arg,
1075 struct sk_buff *skb, struct tcmsg *tcm) 1075 struct sk_buff *skb, struct tcmsg *tcm)
1076{ 1076{
1077 struct htb_class *cl = (struct htb_class *)arg; 1077 struct htb_class *cl = (struct htb_class *)arg;
1078 spinlock_t *root_lock = qdisc_root_lock(sch); 1078 spinlock_t *root_lock = qdisc_root_sleeping_lock(sch);
1079 struct nlattr *nest; 1079 struct nlattr *nest;
1080 struct tc_htb_opt opt; 1080 struct tc_htb_opt opt;
1081 1081
diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c
new file mode 100644
index 000000000000..915f3149dde2
--- /dev/null
+++ b/net/sched/sch_multiq.c
@@ -0,0 +1,477 @@
1/*
2 * Copyright (c) 2008, Intel Corporation.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms and conditions of the GNU General Public License,
6 * version 2, as published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should have received a copy of the GNU General Public License along with
14 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15 * Place - Suite 330, Boston, MA 02111-1307 USA.
16 *
17 * Author: Alexander Duyck <alexander.h.duyck@intel.com>
18 */
19
20#include <linux/module.h>
21#include <linux/types.h>
22#include <linux/kernel.h>
23#include <linux/string.h>
24#include <linux/errno.h>
25#include <linux/skbuff.h>
26#include <net/netlink.h>
27#include <net/pkt_sched.h>
28
29
30struct multiq_sched_data {
31 u16 bands;
32 u16 max_bands;
33 u16 curband;
34 struct tcf_proto *filter_list;
35 struct Qdisc **queues;
36};
37
38
39static struct Qdisc *
40multiq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
41{
42 struct multiq_sched_data *q = qdisc_priv(sch);
43 u32 band;
44 struct tcf_result res;
45 int err;
46
47 *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
48 err = tc_classify(skb, q->filter_list, &res);
49#ifdef CONFIG_NET_CLS_ACT
50 switch (err) {
51 case TC_ACT_STOLEN:
52 case TC_ACT_QUEUED:
53 *qerr = NET_XMIT_SUCCESS | __NET_XMIT_STOLEN;
54 case TC_ACT_SHOT:
55 return NULL;
56 }
57#endif
58 band = skb_get_queue_mapping(skb);
59
60 if (band >= q->bands)
61 return q->queues[0];
62
63 return q->queues[band];
64}
65
66static int
67multiq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
68{
69 struct Qdisc *qdisc;
70 int ret;
71
72 qdisc = multiq_classify(skb, sch, &ret);
73#ifdef CONFIG_NET_CLS_ACT
74 if (qdisc == NULL) {
75
76 if (ret & __NET_XMIT_BYPASS)
77 sch->qstats.drops++;
78 kfree_skb(skb);
79 return ret;
80 }
81#endif
82
83 ret = qdisc_enqueue(skb, qdisc);
84 if (ret == NET_XMIT_SUCCESS) {
85 sch->bstats.bytes += qdisc_pkt_len(skb);
86 sch->bstats.packets++;
87 sch->q.qlen++;
88 return NET_XMIT_SUCCESS;
89 }
90 if (net_xmit_drop_count(ret))
91 sch->qstats.drops++;
92 return ret;
93}
94
95
96static int
97multiq_requeue(struct sk_buff *skb, struct Qdisc *sch)
98{
99 struct Qdisc *qdisc;
100 struct multiq_sched_data *q = qdisc_priv(sch);
101 int ret;
102
103 qdisc = multiq_classify(skb, sch, &ret);
104#ifdef CONFIG_NET_CLS_ACT
105 if (qdisc == NULL) {
106 if (ret & __NET_XMIT_BYPASS)
107 sch->qstats.drops++;
108 kfree_skb(skb);
109 return ret;
110 }
111#endif
112
113 ret = qdisc->ops->requeue(skb, qdisc);
114 if (ret == NET_XMIT_SUCCESS) {
115 sch->q.qlen++;
116 sch->qstats.requeues++;
117 if (q->curband)
118 q->curband--;
119 else
120 q->curband = q->bands - 1;
121 return NET_XMIT_SUCCESS;
122 }
123 if (net_xmit_drop_count(ret))
124 sch->qstats.drops++;
125 return ret;
126}
127
128
129static struct sk_buff *multiq_dequeue(struct Qdisc *sch)
130{
131 struct multiq_sched_data *q = qdisc_priv(sch);
132 struct Qdisc *qdisc;
133 struct sk_buff *skb;
134 int band;
135
136 for (band = 0; band < q->bands; band++) {
137 /* cycle through bands to ensure fairness */
138 q->curband++;
139 if (q->curband >= q->bands)
140 q->curband = 0;
141
142 /* Check that target subqueue is available before
143 * pulling an skb to avoid excessive requeues
144 */
145 if (!__netif_subqueue_stopped(qdisc_dev(sch), q->curband)) {
146 qdisc = q->queues[q->curband];
147 skb = qdisc->dequeue(qdisc);
148 if (skb) {
149 sch->q.qlen--;
150 return skb;
151 }
152 }
153 }
154 return NULL;
155
156}
157
158static unsigned int multiq_drop(struct Qdisc *sch)
159{
160 struct multiq_sched_data *q = qdisc_priv(sch);
161 int band;
162 unsigned int len;
163 struct Qdisc *qdisc;
164
165 for (band = q->bands-1; band >= 0; band--) {
166 qdisc = q->queues[band];
167 if (qdisc->ops->drop) {
168 len = qdisc->ops->drop(qdisc);
169 if (len != 0) {
170 sch->q.qlen--;
171 return len;
172 }
173 }
174 }
175 return 0;
176}
177
178
179static void
180multiq_reset(struct Qdisc *sch)
181{
182 u16 band;
183 struct multiq_sched_data *q = qdisc_priv(sch);
184
185 for (band = 0; band < q->bands; band++)
186 qdisc_reset(q->queues[band]);
187 sch->q.qlen = 0;
188 q->curband = 0;
189}
190
191static void
192multiq_destroy(struct Qdisc *sch)
193{
194 int band;
195 struct multiq_sched_data *q = qdisc_priv(sch);
196
197 tcf_destroy_chain(&q->filter_list);
198 for (band = 0; band < q->bands; band++)
199 qdisc_destroy(q->queues[band]);
200
201 kfree(q->queues);
202}
203
204static int multiq_tune(struct Qdisc *sch, struct nlattr *opt)
205{
206 struct multiq_sched_data *q = qdisc_priv(sch);
207 struct tc_multiq_qopt *qopt;
208 int i;
209
210 if (!netif_is_multiqueue(qdisc_dev(sch)))
211 return -EINVAL;
212 if (nla_len(opt) < sizeof(*qopt))
213 return -EINVAL;
214
215 qopt = nla_data(opt);
216
217 qopt->bands = qdisc_dev(sch)->real_num_tx_queues;
218
219 sch_tree_lock(sch);
220 q->bands = qopt->bands;
221 for (i = q->bands; i < q->max_bands; i++) {
222 if (q->queues[i] != &noop_qdisc) {
223 struct Qdisc *child = xchg(&q->queues[i], &noop_qdisc);
224 qdisc_tree_decrease_qlen(child, child->q.qlen);
225 qdisc_destroy(child);
226 }
227 }
228
229 sch_tree_unlock(sch);
230
231 for (i = 0; i < q->bands; i++) {
232 if (q->queues[i] == &noop_qdisc) {
233 struct Qdisc *child;
234 child = qdisc_create_dflt(qdisc_dev(sch),
235 sch->dev_queue,
236 &pfifo_qdisc_ops,
237 TC_H_MAKE(sch->handle,
238 i + 1));
239 if (child) {
240 sch_tree_lock(sch);
241 child = xchg(&q->queues[i], child);
242
243 if (child != &noop_qdisc) {
244 qdisc_tree_decrease_qlen(child,
245 child->q.qlen);
246 qdisc_destroy(child);
247 }
248 sch_tree_unlock(sch);
249 }
250 }
251 }
252 return 0;
253}
254
255static int multiq_init(struct Qdisc *sch, struct nlattr *opt)
256{
257 struct multiq_sched_data *q = qdisc_priv(sch);
258 int i, err;
259
260 q->queues = NULL;
261
262 if (opt == NULL)
263 return -EINVAL;
264
265 q->max_bands = qdisc_dev(sch)->num_tx_queues;
266
267 q->queues = kcalloc(q->max_bands, sizeof(struct Qdisc *), GFP_KERNEL);
268 if (!q->queues)
269 return -ENOBUFS;
270 for (i = 0; i < q->max_bands; i++)
271 q->queues[i] = &noop_qdisc;
272
273 err = multiq_tune(sch,opt);
274
275 if (err)
276 kfree(q->queues);
277
278 return err;
279}
280
281static int multiq_dump(struct Qdisc *sch, struct sk_buff *skb)
282{
283 struct multiq_sched_data *q = qdisc_priv(sch);
284 unsigned char *b = skb_tail_pointer(skb);
285 struct tc_multiq_qopt opt;
286
287 opt.bands = q->bands;
288 opt.max_bands = q->max_bands;
289
290 NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
291
292 return skb->len;
293
294nla_put_failure:
295 nlmsg_trim(skb, b);
296 return -1;
297}
298
299static int multiq_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
300 struct Qdisc **old)
301{
302 struct multiq_sched_data *q = qdisc_priv(sch);
303 unsigned long band = arg - 1;
304
305 if (band >= q->bands)
306 return -EINVAL;
307
308 if (new == NULL)
309 new = &noop_qdisc;
310
311 sch_tree_lock(sch);
312 *old = q->queues[band];
313 q->queues[band] = new;
314 qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
315 qdisc_reset(*old);
316 sch_tree_unlock(sch);
317
318 return 0;
319}
320
321static struct Qdisc *
322multiq_leaf(struct Qdisc *sch, unsigned long arg)
323{
324 struct multiq_sched_data *q = qdisc_priv(sch);
325 unsigned long band = arg - 1;
326
327 if (band >= q->bands)
328 return NULL;
329
330 return q->queues[band];
331}
332
333static unsigned long multiq_get(struct Qdisc *sch, u32 classid)
334{
335 struct multiq_sched_data *q = qdisc_priv(sch);
336 unsigned long band = TC_H_MIN(classid);
337
338 if (band - 1 >= q->bands)
339 return 0;
340 return band;
341}
342
343static unsigned long multiq_bind(struct Qdisc *sch, unsigned long parent,
344 u32 classid)
345{
346 return multiq_get(sch, classid);
347}
348
349
350static void multiq_put(struct Qdisc *q, unsigned long cl)
351{
352 return;
353}
354
355static int multiq_change(struct Qdisc *sch, u32 handle, u32 parent,
356 struct nlattr **tca, unsigned long *arg)
357{
358 unsigned long cl = *arg;
359 struct multiq_sched_data *q = qdisc_priv(sch);
360
361 if (cl - 1 > q->bands)
362 return -ENOENT;
363 return 0;
364}
365
366static int multiq_delete(struct Qdisc *sch, unsigned long cl)
367{
368 struct multiq_sched_data *q = qdisc_priv(sch);
369 if (cl - 1 > q->bands)
370 return -ENOENT;
371 return 0;
372}
373
374
375static int multiq_dump_class(struct Qdisc *sch, unsigned long cl,
376 struct sk_buff *skb, struct tcmsg *tcm)
377{
378 struct multiq_sched_data *q = qdisc_priv(sch);
379
380 if (cl - 1 > q->bands)
381 return -ENOENT;
382 tcm->tcm_handle |= TC_H_MIN(cl);
383 if (q->queues[cl-1])
384 tcm->tcm_info = q->queues[cl-1]->handle;
385 return 0;
386}
387
388static int multiq_dump_class_stats(struct Qdisc *sch, unsigned long cl,
389 struct gnet_dump *d)
390{
391 struct multiq_sched_data *q = qdisc_priv(sch);
392 struct Qdisc *cl_q;
393
394 cl_q = q->queues[cl - 1];
395 if (gnet_stats_copy_basic(d, &cl_q->bstats) < 0 ||
396 gnet_stats_copy_queue(d, &cl_q->qstats) < 0)
397 return -1;
398
399 return 0;
400}
401
402static void multiq_walk(struct Qdisc *sch, struct qdisc_walker *arg)
403{
404 struct multiq_sched_data *q = qdisc_priv(sch);
405 int band;
406
407 if (arg->stop)
408 return;
409
410 for (band = 0; band < q->bands; band++) {
411 if (arg->count < arg->skip) {
412 arg->count++;
413 continue;
414 }
415 if (arg->fn(sch, band+1, arg) < 0) {
416 arg->stop = 1;
417 break;
418 }
419 arg->count++;
420 }
421}
422
423static struct tcf_proto **multiq_find_tcf(struct Qdisc *sch, unsigned long cl)
424{
425 struct multiq_sched_data *q = qdisc_priv(sch);
426
427 if (cl)
428 return NULL;
429 return &q->filter_list;
430}
431
432static const struct Qdisc_class_ops multiq_class_ops = {
433 .graft = multiq_graft,
434 .leaf = multiq_leaf,
435 .get = multiq_get,
436 .put = multiq_put,
437 .change = multiq_change,
438 .delete = multiq_delete,
439 .walk = multiq_walk,
440 .tcf_chain = multiq_find_tcf,
441 .bind_tcf = multiq_bind,
442 .unbind_tcf = multiq_put,
443 .dump = multiq_dump_class,
444 .dump_stats = multiq_dump_class_stats,
445};
446
447static struct Qdisc_ops multiq_qdisc_ops __read_mostly = {
448 .next = NULL,
449 .cl_ops = &multiq_class_ops,
450 .id = "multiq",
451 .priv_size = sizeof(struct multiq_sched_data),
452 .enqueue = multiq_enqueue,
453 .dequeue = multiq_dequeue,
454 .requeue = multiq_requeue,
455 .drop = multiq_drop,
456 .init = multiq_init,
457 .reset = multiq_reset,
458 .destroy = multiq_destroy,
459 .change = multiq_tune,
460 .dump = multiq_dump,
461 .owner = THIS_MODULE,
462};
463
464static int __init multiq_module_init(void)
465{
466 return register_qdisc(&multiq_qdisc_ops);
467}
468
469static void __exit multiq_module_exit(void)
470{
471 unregister_qdisc(&multiq_qdisc_ops);
472}
473
474module_init(multiq_module_init)
475module_exit(multiq_module_exit)
476
477MODULE_LICENSE("GPL");
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index fb0294d0b55e..a11959908d9a 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -341,7 +341,7 @@ static int get_dist_table(struct Qdisc *sch, const struct nlattr *attr)
341 for (i = 0; i < n; i++) 341 for (i = 0; i < n; i++)
342 d->table[i] = data[i]; 342 d->table[i] = data[i];
343 343
344 root_lock = qdisc_root_lock(sch); 344 root_lock = qdisc_root_sleeping_lock(sch);
345 345
346 spin_lock_bh(root_lock); 346 spin_lock_bh(root_lock);
347 d = xchg(&q->delay_dist, d); 347 d = xchg(&q->delay_dist, d);
@@ -388,6 +388,20 @@ static const struct nla_policy netem_policy[TCA_NETEM_MAX + 1] = {
388 [TCA_NETEM_CORRUPT] = { .len = sizeof(struct tc_netem_corrupt) }, 388 [TCA_NETEM_CORRUPT] = { .len = sizeof(struct tc_netem_corrupt) },
389}; 389};
390 390
391static int parse_attr(struct nlattr *tb[], int maxtype, struct nlattr *nla,
392 const struct nla_policy *policy, int len)
393{
394 int nested_len = nla_len(nla) - NLA_ALIGN(len);
395
396 if (nested_len < 0)
397 return -EINVAL;
398 if (nested_len >= nla_attr_size(0))
399 return nla_parse(tb, maxtype, nla_data(nla) + NLA_ALIGN(len),
400 nested_len, policy);
401 memset(tb, 0, sizeof(struct nlattr *) * (maxtype + 1));
402 return 0;
403}
404
391/* Parse netlink message to set options */ 405/* Parse netlink message to set options */
392static int netem_change(struct Qdisc *sch, struct nlattr *opt) 406static int netem_change(struct Qdisc *sch, struct nlattr *opt)
393{ 407{
@@ -399,8 +413,8 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt)
399 if (opt == NULL) 413 if (opt == NULL)
400 return -EINVAL; 414 return -EINVAL;
401 415
402 ret = nla_parse_nested_compat(tb, TCA_NETEM_MAX, opt, netem_policy, 416 qopt = nla_data(opt);
403 qopt, sizeof(*qopt)); 417 ret = parse_attr(tb, TCA_NETEM_MAX, opt, netem_policy, sizeof(*qopt));
404 if (ret < 0) 418 if (ret < 0)
405 return ret; 419 return ret;
406 420
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index a6697c686c7f..504a78cdb718 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -254,16 +254,12 @@ static int prio_dump(struct Qdisc *sch, struct sk_buff *skb)
254{ 254{
255 struct prio_sched_data *q = qdisc_priv(sch); 255 struct prio_sched_data *q = qdisc_priv(sch);
256 unsigned char *b = skb_tail_pointer(skb); 256 unsigned char *b = skb_tail_pointer(skb);
257 struct nlattr *nest;
258 struct tc_prio_qopt opt; 257 struct tc_prio_qopt opt;
259 258
260 opt.bands = q->bands; 259 opt.bands = q->bands;
261 memcpy(&opt.priomap, q->prio2band, TC_PRIO_MAX+1); 260 memcpy(&opt.priomap, q->prio2band, TC_PRIO_MAX+1);
262 261
263 nest = nla_nest_compat_start(skb, TCA_OPTIONS, sizeof(opt), &opt); 262 NLA_PUT(skb, TCA_OPTIONS, sizeof(opt), &opt);
264 if (nest == NULL)
265 goto nla_put_failure;
266 nla_nest_compat_end(skb, nest);
267 263
268 return skb->len; 264 return skb->len;
269 265
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index 6e041d10dbdb..fe1508ef0d3d 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -119,7 +119,7 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
119 u32 h, h2; 119 u32 h, h2;
120 120
121 switch (skb->protocol) { 121 switch (skb->protocol) {
122 case __constant_htons(ETH_P_IP): 122 case htons(ETH_P_IP):
123 { 123 {
124 const struct iphdr *iph = ip_hdr(skb); 124 const struct iphdr *iph = ip_hdr(skb);
125 h = iph->daddr; 125 h = iph->daddr;
@@ -134,7 +134,7 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
134 h2 ^= *(((u32*)iph) + iph->ihl); 134 h2 ^= *(((u32*)iph) + iph->ihl);
135 break; 135 break;
136 } 136 }
137 case __constant_htons(ETH_P_IPV6): 137 case htons(ETH_P_IPV6):
138 { 138 {
139 struct ipv6hdr *iph = ipv6_hdr(skb); 139 struct ipv6hdr *iph = ipv6_hdr(skb);
140 h = iph->daddr.s6_addr32[3]; 140 h = iph->daddr.s6_addr32[3];
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index 2c35c678563b..d35ef059abb1 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -161,7 +161,7 @@ teql_destroy(struct Qdisc* sch)
161 txq = netdev_get_tx_queue(master->dev, 0); 161 txq = netdev_get_tx_queue(master->dev, 0);
162 master->slaves = NULL; 162 master->slaves = NULL;
163 163
164 root_lock = qdisc_root_lock(txq->qdisc); 164 root_lock = qdisc_root_sleeping_lock(txq->qdisc);
165 spin_lock_bh(root_lock); 165 spin_lock_bh(root_lock);
166 qdisc_reset(txq->qdisc); 166 qdisc_reset(txq->qdisc);
167 spin_unlock_bh(root_lock); 167 spin_unlock_bh(root_lock);
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index 8472b8b349c4..f4b23043b610 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -283,8 +283,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
283 if (!sctp_ulpq_init(&asoc->ulpq, asoc)) 283 if (!sctp_ulpq_init(&asoc->ulpq, asoc))
284 goto fail_init; 284 goto fail_init;
285 285
286 /* Set up the tsn tracking. */ 286 memset(&asoc->peer.tsn_map, 0, sizeof(struct sctp_tsnmap));
287 sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_SIZE, 0);
288 287
289 asoc->need_ecne = 0; 288 asoc->need_ecne = 0;
290 289
@@ -402,6 +401,8 @@ void sctp_association_free(struct sctp_association *asoc)
402 /* Dispose of any pending chunks on the inqueue. */ 401 /* Dispose of any pending chunks on the inqueue. */
403 sctp_inq_free(&asoc->base.inqueue); 402 sctp_inq_free(&asoc->base.inqueue);
404 403
404 sctp_tsnmap_free(&asoc->peer.tsn_map);
405
405 /* Free ssnmap storage. */ 406 /* Free ssnmap storage. */
406 sctp_ssnmap_free(asoc->ssnmap); 407 sctp_ssnmap_free(asoc->ssnmap);
407 408
@@ -599,11 +600,12 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
599 /* Check to see if this is a duplicate. */ 600 /* Check to see if this is a duplicate. */
600 peer = sctp_assoc_lookup_paddr(asoc, addr); 601 peer = sctp_assoc_lookup_paddr(asoc, addr);
601 if (peer) { 602 if (peer) {
603 /* An UNKNOWN state is only set on transports added by
604 * user in sctp_connectx() call. Such transports should be
605 * considered CONFIRMED per RFC 4960, Section 5.4.
606 */
602 if (peer->state == SCTP_UNKNOWN) { 607 if (peer->state == SCTP_UNKNOWN) {
603 if (peer_state == SCTP_ACTIVE) 608 peer->state = SCTP_ACTIVE;
604 peer->state = SCTP_ACTIVE;
605 if (peer_state == SCTP_UNCONFIRMED)
606 peer->state = SCTP_UNCONFIRMED;
607 } 609 }
608 return peer; 610 return peer;
609 } 611 }
@@ -1121,8 +1123,8 @@ void sctp_assoc_update(struct sctp_association *asoc,
1121 asoc->peer.rwnd = new->peer.rwnd; 1123 asoc->peer.rwnd = new->peer.rwnd;
1122 asoc->peer.sack_needed = new->peer.sack_needed; 1124 asoc->peer.sack_needed = new->peer.sack_needed;
1123 asoc->peer.i = new->peer.i; 1125 asoc->peer.i = new->peer.i;
1124 sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_SIZE, 1126 sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_INITIAL,
1125 asoc->peer.i.initial_tsn); 1127 asoc->peer.i.initial_tsn, GFP_ATOMIC);
1126 1128
1127 /* Remove any peer addresses not present in the new association. */ 1129 /* Remove any peer addresses not present in the new association. */
1128 list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { 1130 list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c
index f62bc2468935..6d5944a745d4 100644
--- a/net/sctp/bind_addr.c
+++ b/net/sctp/bind_addr.c
@@ -457,7 +457,7 @@ static int sctp_copy_one_addr(struct sctp_bind_addr *dest,
457{ 457{
458 int error = 0; 458 int error = 0;
459 459
460 if (sctp_is_any(addr)) { 460 if (sctp_is_any(NULL, addr)) {
461 error = sctp_copy_local_addr_list(dest, scope, gfp, flags); 461 error = sctp_copy_local_addr_list(dest, scope, gfp, flags);
462 } else if (sctp_in_scope(addr, scope)) { 462 } else if (sctp_in_scope(addr, scope)) {
463 /* Now that the address is in scope, check to see if 463 /* Now that the address is in scope, check to see if
@@ -477,11 +477,21 @@ static int sctp_copy_one_addr(struct sctp_bind_addr *dest,
477} 477}
478 478
479/* Is this a wildcard address? */ 479/* Is this a wildcard address? */
480int sctp_is_any(const union sctp_addr *addr) 480int sctp_is_any(struct sock *sk, const union sctp_addr *addr)
481{ 481{
482 struct sctp_af *af = sctp_get_af_specific(addr->sa.sa_family); 482 unsigned short fam = 0;
483 struct sctp_af *af;
484
485 /* Try to get the right address family */
486 if (addr->sa.sa_family != AF_UNSPEC)
487 fam = addr->sa.sa_family;
488 else if (sk)
489 fam = sk->sk_family;
490
491 af = sctp_get_af_specific(fam);
483 if (!af) 492 if (!af)
484 return 0; 493 return 0;
494
485 return af->is_any(addr); 495 return af->is_any(addr);
486} 496}
487 497
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 47f91afa0211..4124bbb99947 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -156,7 +156,7 @@ SCTP_STATIC void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
156 skb->network_header = saveip; 156 skb->network_header = saveip;
157 skb->transport_header = savesctp; 157 skb->transport_header = savesctp;
158 if (!sk) { 158 if (!sk) {
159 ICMP6_INC_STATS_BH(idev, ICMP6_MIB_INERRORS); 159 ICMP6_INC_STATS_BH(dev_net(skb->dev), idev, ICMP6_MIB_INERRORS);
160 goto out; 160 goto out;
161 } 161 }
162 162
@@ -837,6 +837,7 @@ static int sctp_inet6_cmp_addr(const union sctp_addr *addr1,
837 struct sctp_sock *opt) 837 struct sctp_sock *opt)
838{ 838{
839 struct sctp_af *af1, *af2; 839 struct sctp_af *af1, *af2;
840 struct sock *sk = sctp_opt2sk(opt);
840 841
841 af1 = sctp_get_af_specific(addr1->sa.sa_family); 842 af1 = sctp_get_af_specific(addr1->sa.sa_family);
842 af2 = sctp_get_af_specific(addr2->sa.sa_family); 843 af2 = sctp_get_af_specific(addr2->sa.sa_family);
@@ -845,11 +846,11 @@ static int sctp_inet6_cmp_addr(const union sctp_addr *addr1,
845 return 0; 846 return 0;
846 847
847 /* If the socket is IPv6 only, v4 addrs will not match */ 848 /* If the socket is IPv6 only, v4 addrs will not match */
848 if (__ipv6_only_sock(sctp_opt2sk(opt)) && af1 != af2) 849 if (__ipv6_only_sock(sk) && af1 != af2)
849 return 0; 850 return 0;
850 851
851 /* Today, wildcard AF_INET/AF_INET6. */ 852 /* Today, wildcard AF_INET/AF_INET6. */
852 if (sctp_is_any(addr1) || sctp_is_any(addr2)) 853 if (sctp_is_any(sk, addr1) || sctp_is_any(sk, addr2))
853 return 1; 854 return 1;
854 855
855 if (addr1->sa.sa_family != addr2->sa.sa_family) 856 if (addr1->sa.sa_family != addr2->sa.sa_family)
diff --git a/net/sctp/output.c b/net/sctp/output.c
index 0dc4a7dfb234..c3f417f7ec6e 100644
--- a/net/sctp/output.c
+++ b/net/sctp/output.c
@@ -533,7 +533,8 @@ int sctp_packet_transmit(struct sctp_packet *packet)
533 if (!(dst->dev->features & NETIF_F_NO_CSUM)) { 533 if (!(dst->dev->features & NETIF_F_NO_CSUM)) {
534 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len); 534 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len);
535 crc32 = sctp_end_cksum(crc32); 535 crc32 = sctp_end_cksum(crc32);
536 } 536 } else
537 nskb->ip_summed = CHECKSUM_UNNECESSARY;
537 538
538 /* 3) Put the resultant value into the checksum field in the 539 /* 3) Put the resultant value into the checksum field in the
539 * common header, and leave the rest of the bits unchanged. 540 * common header, and leave the rest of the bits unchanged.
@@ -698,7 +699,7 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet,
698 * When a Fast Retransmit is being performed the sender SHOULD 699 * When a Fast Retransmit is being performed the sender SHOULD
699 * ignore the value of cwnd and SHOULD NOT delay retransmission. 700 * ignore the value of cwnd and SHOULD NOT delay retransmission.
700 */ 701 */
701 if (chunk->fast_retransmit <= 0) 702 if (chunk->fast_retransmit != SCTP_NEED_FRTX)
702 if (transport->flight_size >= transport->cwnd) { 703 if (transport->flight_size >= transport->cwnd) {
703 retval = SCTP_XMIT_RWND_FULL; 704 retval = SCTP_XMIT_RWND_FULL;
704 goto finish; 705 goto finish;
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index 4328ad5439c9..247ebc95c1e5 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -420,7 +420,7 @@ void sctp_retransmit_mark(struct sctp_outq *q,
420 * be added to the retransmit queue. 420 * be added to the retransmit queue.
421 */ 421 */
422 if ((reason == SCTP_RTXR_FAST_RTX && 422 if ((reason == SCTP_RTXR_FAST_RTX &&
423 (chunk->fast_retransmit > 0)) || 423 (chunk->fast_retransmit == SCTP_NEED_FRTX)) ||
424 (reason != SCTP_RTXR_FAST_RTX && !chunk->tsn_gap_acked)) { 424 (reason != SCTP_RTXR_FAST_RTX && !chunk->tsn_gap_acked)) {
425 /* If this chunk was sent less then 1 rto ago, do not 425 /* If this chunk was sent less then 1 rto ago, do not
426 * retransmit this chunk, but give the peer time 426 * retransmit this chunk, but give the peer time
@@ -650,8 +650,8 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt,
650 /* Mark the chunk as ineligible for fast retransmit 650 /* Mark the chunk as ineligible for fast retransmit
651 * after it is retransmitted. 651 * after it is retransmitted.
652 */ 652 */
653 if (chunk->fast_retransmit > 0) 653 if (chunk->fast_retransmit == SCTP_NEED_FRTX)
654 chunk->fast_retransmit = -1; 654 chunk->fast_retransmit = SCTP_DONT_FRTX;
655 655
656 /* Force start T3-rtx timer when fast retransmitting 656 /* Force start T3-rtx timer when fast retransmitting
657 * the earliest outstanding TSN 657 * the earliest outstanding TSN
@@ -680,8 +680,8 @@ static int sctp_outq_flush_rtx(struct sctp_outq *q, struct sctp_packet *pkt,
680 */ 680 */
681 if (rtx_timeout || fast_rtx) { 681 if (rtx_timeout || fast_rtx) {
682 list_for_each_entry(chunk1, lqueue, transmitted_list) { 682 list_for_each_entry(chunk1, lqueue, transmitted_list) {
683 if (chunk1->fast_retransmit > 0) 683 if (chunk1->fast_retransmit == SCTP_NEED_FRTX)
684 chunk1->fast_retransmit = -1; 684 chunk1->fast_retransmit = SCTP_DONT_FRTX;
685 } 685 }
686 } 686 }
687 687
@@ -1129,12 +1129,13 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
1129 unsigned outstanding; 1129 unsigned outstanding;
1130 struct sctp_transport *primary = asoc->peer.primary_path; 1130 struct sctp_transport *primary = asoc->peer.primary_path;
1131 int count_of_newacks = 0; 1131 int count_of_newacks = 0;
1132 int gap_ack_blocks;
1132 1133
1133 /* Grab the association's destination address list. */ 1134 /* Grab the association's destination address list. */
1134 transport_list = &asoc->peer.transport_addr_list; 1135 transport_list = &asoc->peer.transport_addr_list;
1135 1136
1136 sack_ctsn = ntohl(sack->cum_tsn_ack); 1137 sack_ctsn = ntohl(sack->cum_tsn_ack);
1137 1138 gap_ack_blocks = ntohs(sack->num_gap_ack_blocks);
1138 /* 1139 /*
1139 * SFR-CACC algorithm: 1140 * SFR-CACC algorithm:
1140 * On receipt of a SACK the sender SHOULD execute the 1141 * On receipt of a SACK the sender SHOULD execute the
@@ -1144,35 +1145,38 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
1144 * on the current primary, the CHANGEOVER_ACTIVE flag SHOULD be 1145 * on the current primary, the CHANGEOVER_ACTIVE flag SHOULD be
1145 * cleared. The CYCLING_CHANGEOVER flag SHOULD also be cleared for 1146 * cleared. The CYCLING_CHANGEOVER flag SHOULD also be cleared for
1146 * all destinations. 1147 * all destinations.
1147 */
1148 if (TSN_lte(primary->cacc.next_tsn_at_change, sack_ctsn)) {
1149 primary->cacc.changeover_active = 0;
1150 list_for_each_entry(transport, transport_list,
1151 transports) {
1152 transport->cacc.cycling_changeover = 0;
1153 }
1154 }
1155
1156 /*
1157 * SFR-CACC algorithm:
1158 * 2) If the SACK contains gap acks and the flag CHANGEOVER_ACTIVE 1148 * 2) If the SACK contains gap acks and the flag CHANGEOVER_ACTIVE
1159 * is set the receiver of the SACK MUST take the following actions: 1149 * is set the receiver of the SACK MUST take the following actions:
1160 * 1150 *
1161 * A) Initialize the cacc_saw_newack to 0 for all destination 1151 * A) Initialize the cacc_saw_newack to 0 for all destination
1162 * addresses. 1152 * addresses.
1153 *
1154 * Only bother if changeover_active is set. Otherwise, this is
1155 * totally suboptimal to do on every SACK.
1163 */ 1156 */
1164 if (sack->num_gap_ack_blocks && 1157 if (primary->cacc.changeover_active) {
1165 primary->cacc.changeover_active) { 1158 u8 clear_cycling = 0;
1166 list_for_each_entry(transport, transport_list, transports) { 1159
1167 transport->cacc.cacc_saw_newack = 0; 1160 if (TSN_lte(primary->cacc.next_tsn_at_change, sack_ctsn)) {
1161 primary->cacc.changeover_active = 0;
1162 clear_cycling = 1;
1163 }
1164
1165 if (clear_cycling || gap_ack_blocks) {
1166 list_for_each_entry(transport, transport_list,
1167 transports) {
1168 if (clear_cycling)
1169 transport->cacc.cycling_changeover = 0;
1170 if (gap_ack_blocks)
1171 transport->cacc.cacc_saw_newack = 0;
1172 }
1168 } 1173 }
1169 } 1174 }
1170 1175
1171 /* Get the highest TSN in the sack. */ 1176 /* Get the highest TSN in the sack. */
1172 highest_tsn = sack_ctsn; 1177 highest_tsn = sack_ctsn;
1173 if (sack->num_gap_ack_blocks) 1178 if (gap_ack_blocks)
1174 highest_tsn += 1179 highest_tsn += ntohs(frags[gap_ack_blocks - 1].gab.end);
1175 ntohs(frags[ntohs(sack->num_gap_ack_blocks) - 1].gab.end);
1176 1180
1177 if (TSN_lt(asoc->highest_sacked, highest_tsn)) { 1181 if (TSN_lt(asoc->highest_sacked, highest_tsn)) {
1178 highest_new_tsn = highest_tsn; 1182 highest_new_tsn = highest_tsn;
@@ -1181,11 +1185,11 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
1181 highest_new_tsn = sctp_highest_new_tsn(sack, asoc); 1185 highest_new_tsn = sctp_highest_new_tsn(sack, asoc);
1182 } 1186 }
1183 1187
1188
1184 /* Run through the retransmit queue. Credit bytes received 1189 /* Run through the retransmit queue. Credit bytes received
1185 * and free those chunks that we can. 1190 * and free those chunks that we can.
1186 */ 1191 */
1187 sctp_check_transmitted(q, &q->retransmit, NULL, sack, highest_new_tsn); 1192 sctp_check_transmitted(q, &q->retransmit, NULL, sack, highest_new_tsn);
1188 sctp_mark_missing(q, &q->retransmit, NULL, highest_new_tsn, 0);
1189 1193
1190 /* Run through the transmitted queue. 1194 /* Run through the transmitted queue.
1191 * Credit bytes received and free those chunks which we can. 1195 * Credit bytes received and free those chunks which we can.
@@ -1204,9 +1208,10 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
1204 count_of_newacks ++; 1208 count_of_newacks ++;
1205 } 1209 }
1206 1210
1207 list_for_each_entry(transport, transport_list, transports) { 1211 if (gap_ack_blocks) {
1208 sctp_mark_missing(q, &transport->transmitted, transport, 1212 list_for_each_entry(transport, transport_list, transports)
1209 highest_new_tsn, count_of_newacks); 1213 sctp_mark_missing(q, &transport->transmitted, transport,
1214 highest_new_tsn, count_of_newacks);
1210 } 1215 }
1211 1216
1212 /* Move the Cumulative TSN Ack Point if appropriate. */ 1217 /* Move the Cumulative TSN Ack Point if appropriate. */
@@ -1651,7 +1656,7 @@ static void sctp_mark_missing(struct sctp_outq *q,
1651 * chunk if it has NOT been fast retransmitted or marked for 1656 * chunk if it has NOT been fast retransmitted or marked for
1652 * fast retransmit already. 1657 * fast retransmit already.
1653 */ 1658 */
1654 if (!chunk->fast_retransmit && 1659 if (chunk->fast_retransmit == SCTP_CAN_FRTX &&
1655 !chunk->tsn_gap_acked && 1660 !chunk->tsn_gap_acked &&
1656 TSN_lt(tsn, highest_new_tsn_in_sack)) { 1661 TSN_lt(tsn, highest_new_tsn_in_sack)) {
1657 1662
@@ -1676,7 +1681,7 @@ static void sctp_mark_missing(struct sctp_outq *q,
1676 */ 1681 */
1677 1682
1678 if (chunk->tsn_missing_report >= 3) { 1683 if (chunk->tsn_missing_report >= 3) {
1679 chunk->fast_retransmit = 1; 1684 chunk->fast_retransmit = SCTP_NEED_FRTX;
1680 do_fast_retransmit = 1; 1685 do_fast_retransmit = 1;
1681 } 1686 }
1682 } 1687 }
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index e8ca4e54981f..fd8acb48c3f2 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -702,12 +702,14 @@ struct sctp_chunk *sctp_make_sack(const struct sctp_association *asoc)
702 __u32 ctsn; 702 __u32 ctsn;
703 __u16 num_gabs, num_dup_tsns; 703 __u16 num_gabs, num_dup_tsns;
704 struct sctp_tsnmap *map = (struct sctp_tsnmap *)&asoc->peer.tsn_map; 704 struct sctp_tsnmap *map = (struct sctp_tsnmap *)&asoc->peer.tsn_map;
705 struct sctp_gap_ack_block gabs[SCTP_MAX_GABS];
705 706
707 memset(gabs, 0, sizeof(gabs));
706 ctsn = sctp_tsnmap_get_ctsn(map); 708 ctsn = sctp_tsnmap_get_ctsn(map);
707 SCTP_DEBUG_PRINTK("sackCTSNAck sent: 0x%x.\n", ctsn); 709 SCTP_DEBUG_PRINTK("sackCTSNAck sent: 0x%x.\n", ctsn);
708 710
709 /* How much room is needed in the chunk? */ 711 /* How much room is needed in the chunk? */
710 num_gabs = sctp_tsnmap_num_gabs(map); 712 num_gabs = sctp_tsnmap_num_gabs(map, gabs);
711 num_dup_tsns = sctp_tsnmap_num_dups(map); 713 num_dup_tsns = sctp_tsnmap_num_dups(map);
712 714
713 /* Initialize the SACK header. */ 715 /* Initialize the SACK header. */
@@ -763,7 +765,7 @@ struct sctp_chunk *sctp_make_sack(const struct sctp_association *asoc)
763 /* Add the gap ack block information. */ 765 /* Add the gap ack block information. */
764 if (num_gabs) 766 if (num_gabs)
765 sctp_addto_chunk(retval, sizeof(__u32) * num_gabs, 767 sctp_addto_chunk(retval, sizeof(__u32) * num_gabs,
766 sctp_tsnmap_get_gabs(map)); 768 gabs);
767 769
768 /* Add the duplicate TSN information. */ 770 /* Add the duplicate TSN information. */
769 if (num_dup_tsns) 771 if (num_dup_tsns)
@@ -1012,6 +1014,29 @@ end:
1012 return retval; 1014 return retval;
1013} 1015}
1014 1016
1017struct sctp_chunk *sctp_make_violation_paramlen(
1018 const struct sctp_association *asoc,
1019 const struct sctp_chunk *chunk,
1020 struct sctp_paramhdr *param)
1021{
1022 struct sctp_chunk *retval;
1023 static const char error[] = "The following parameter had invalid length:";
1024 size_t payload_len = sizeof(error) + sizeof(sctp_errhdr_t) +
1025 sizeof(sctp_paramhdr_t);
1026
1027 retval = sctp_make_abort(asoc, chunk, payload_len);
1028 if (!retval)
1029 goto nodata;
1030
1031 sctp_init_cause(retval, SCTP_ERROR_PROTO_VIOLATION,
1032 sizeof(error) + sizeof(sctp_paramhdr_t));
1033 sctp_addto_chunk(retval, sizeof(error), error);
1034 sctp_addto_param(retval, sizeof(sctp_paramhdr_t), param);
1035
1036nodata:
1037 return retval;
1038}
1039
1015/* Make a HEARTBEAT chunk. */ 1040/* Make a HEARTBEAT chunk. */
1016struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc, 1041struct sctp_chunk *sctp_make_heartbeat(const struct sctp_association *asoc,
1017 const struct sctp_transport *transport, 1042 const struct sctp_transport *transport,
@@ -1188,7 +1213,7 @@ struct sctp_chunk *sctp_chunkify(struct sk_buff *skb,
1188 */ 1213 */
1189 retval->tsn_missing_report = 0; 1214 retval->tsn_missing_report = 0;
1190 retval->tsn_gap_acked = 0; 1215 retval->tsn_gap_acked = 0;
1191 retval->fast_retransmit = 0; 1216 retval->fast_retransmit = SCTP_CAN_FRTX;
1192 1217
1193 /* If this is a fragmented message, track all fragments 1218 /* If this is a fragmented message, track all fragments
1194 * of the message (for SEND_FAILED). 1219 * of the message (for SEND_FAILED).
@@ -1782,11 +1807,6 @@ static int sctp_process_inv_paramlength(const struct sctp_association *asoc,
1782 const struct sctp_chunk *chunk, 1807 const struct sctp_chunk *chunk,
1783 struct sctp_chunk **errp) 1808 struct sctp_chunk **errp)
1784{ 1809{
1785 static const char error[] = "The following parameter had invalid length:";
1786 size_t payload_len = WORD_ROUND(sizeof(error)) +
1787 sizeof(sctp_paramhdr_t);
1788
1789
1790 /* This is a fatal error. Any accumulated non-fatal errors are 1810 /* This is a fatal error. Any accumulated non-fatal errors are
1791 * not reported. 1811 * not reported.
1792 */ 1812 */
@@ -1794,14 +1814,7 @@ static int sctp_process_inv_paramlength(const struct sctp_association *asoc,
1794 sctp_chunk_free(*errp); 1814 sctp_chunk_free(*errp);
1795 1815
1796 /* Create an error chunk and fill it in with our payload. */ 1816 /* Create an error chunk and fill it in with our payload. */
1797 *errp = sctp_make_op_error_space(asoc, chunk, payload_len); 1817 *errp = sctp_make_violation_paramlen(asoc, chunk, param);
1798
1799 if (*errp) {
1800 sctp_init_cause(*errp, SCTP_ERROR_PROTO_VIOLATION,
1801 sizeof(error) + sizeof(sctp_paramhdr_t));
1802 sctp_addto_chunk(*errp, sizeof(error), error);
1803 sctp_addto_param(*errp, sizeof(sctp_paramhdr_t), param);
1804 }
1805 1818
1806 return 0; 1819 return 0;
1807} 1820}
@@ -1886,11 +1899,13 @@ static void sctp_process_ext_param(struct sctp_association *asoc,
1886 /* if the peer reports AUTH, assume that he 1899 /* if the peer reports AUTH, assume that he
1887 * supports AUTH. 1900 * supports AUTH.
1888 */ 1901 */
1889 asoc->peer.auth_capable = 1; 1902 if (sctp_auth_enable)
1903 asoc->peer.auth_capable = 1;
1890 break; 1904 break;
1891 case SCTP_CID_ASCONF: 1905 case SCTP_CID_ASCONF:
1892 case SCTP_CID_ASCONF_ACK: 1906 case SCTP_CID_ASCONF_ACK:
1893 asoc->peer.asconf_capable = 1; 1907 if (sctp_addip_enable)
1908 asoc->peer.asconf_capable = 1;
1894 break; 1909 break;
1895 default: 1910 default:
1896 break; 1911 break;
@@ -2275,8 +2290,9 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
2275 } 2290 }
2276 2291
2277 /* Set up the TSN tracking pieces. */ 2292 /* Set up the TSN tracking pieces. */
2278 sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_SIZE, 2293 if (!sctp_tsnmap_init(&asoc->peer.tsn_map, SCTP_TSN_MAP_INITIAL,
2279 asoc->peer.i.initial_tsn); 2294 asoc->peer.i.initial_tsn, gfp))
2295 goto clean_up;
2280 2296
2281 /* RFC 2960 6.5 Stream Identifier and Stream Sequence Number 2297 /* RFC 2960 6.5 Stream Identifier and Stream Sequence Number
2282 * 2298 *
@@ -2319,12 +2335,10 @@ clean_up:
2319 /* Release the transport structures. */ 2335 /* Release the transport structures. */
2320 list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) { 2336 list_for_each_safe(pos, temp, &asoc->peer.transport_addr_list) {
2321 transport = list_entry(pos, struct sctp_transport, transports); 2337 transport = list_entry(pos, struct sctp_transport, transports);
2322 list_del_init(pos); 2338 if (transport->state != SCTP_ACTIVE)
2323 sctp_transport_free(transport); 2339 sctp_assoc_rm_peer(asoc, transport);
2324 } 2340 }
2325 2341
2326 asoc->peer.transport_count = 0;
2327
2328nomem: 2342nomem:
2329 return 0; 2343 return 0;
2330} 2344}
@@ -2456,10 +2470,13 @@ do_addr_param:
2456 break; 2470 break;
2457 2471
2458 case SCTP_PARAM_ADAPTATION_LAYER_IND: 2472 case SCTP_PARAM_ADAPTATION_LAYER_IND:
2459 asoc->peer.adaptation_ind = param.aind->adaptation_ind; 2473 asoc->peer.adaptation_ind = ntohl(param.aind->adaptation_ind);
2460 break; 2474 break;
2461 2475
2462 case SCTP_PARAM_SET_PRIMARY: 2476 case SCTP_PARAM_SET_PRIMARY:
2477 if (!sctp_addip_enable)
2478 goto fall_through;
2479
2463 addr_param = param.v + sizeof(sctp_addip_param_t); 2480 addr_param = param.v + sizeof(sctp_addip_param_t);
2464 2481
2465 af = sctp_get_af_specific(param_type2af(param.p->type)); 2482 af = sctp_get_af_specific(param_type2af(param.p->type));
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 9732c797e8ed..e1d6076b4f59 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -889,6 +889,35 @@ static void sctp_cmd_adaptation_ind(sctp_cmd_seq_t *commands,
889 sctp_ulpq_tail_event(&asoc->ulpq, ev); 889 sctp_ulpq_tail_event(&asoc->ulpq, ev);
890} 890}
891 891
892
893static void sctp_cmd_t1_timer_update(struct sctp_association *asoc,
894 sctp_event_timeout_t timer,
895 char *name)
896{
897 struct sctp_transport *t;
898
899 t = asoc->init_last_sent_to;
900 asoc->init_err_counter++;
901
902 if (t->init_sent_count > (asoc->init_cycle + 1)) {
903 asoc->timeouts[timer] *= 2;
904 if (asoc->timeouts[timer] > asoc->max_init_timeo) {
905 asoc->timeouts[timer] = asoc->max_init_timeo;
906 }
907 asoc->init_cycle++;
908 SCTP_DEBUG_PRINTK(
909 "T1 %s Timeout adjustment"
910 " init_err_counter: %d"
911 " cycle: %d"
912 " timeout: %ld\n",
913 name,
914 asoc->init_err_counter,
915 asoc->init_cycle,
916 asoc->timeouts[timer]);
917 }
918
919}
920
892/* These three macros allow us to pull the debugging code out of the 921/* These three macros allow us to pull the debugging code out of the
893 * main flow of sctp_do_sm() to keep attention focused on the real 922 * main flow of sctp_do_sm() to keep attention focused on the real
894 * functionality there. 923 * functionality there.
@@ -1123,7 +1152,8 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1123 1152
1124 case SCTP_CMD_REPORT_TSN: 1153 case SCTP_CMD_REPORT_TSN:
1125 /* Record the arrival of a TSN. */ 1154 /* Record the arrival of a TSN. */
1126 sctp_tsnmap_mark(&asoc->peer.tsn_map, cmd->obj.u32); 1155 error = sctp_tsnmap_mark(&asoc->peer.tsn_map,
1156 cmd->obj.u32);
1127 break; 1157 break;
1128 1158
1129 case SCTP_CMD_REPORT_FWDTSN: 1159 case SCTP_CMD_REPORT_FWDTSN:
@@ -1196,6 +1226,11 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1196 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, 1226 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
1197 SCTP_CHUNK(cmd->obj.ptr)); 1227 SCTP_CHUNK(cmd->obj.ptr));
1198 1228
1229 if (new_obj->transport) {
1230 new_obj->transport->init_sent_count++;
1231 asoc->init_last_sent_to = new_obj->transport;
1232 }
1233
1199 /* FIXME - Eventually come up with a cleaner way to 1234 /* FIXME - Eventually come up with a cleaner way to
1200 * enabling COOKIE-ECHO + DATA bundling during 1235 * enabling COOKIE-ECHO + DATA bundling during
1201 * multihoming stale cookie scenarios, the following 1236 * multihoming stale cookie scenarios, the following
@@ -1345,26 +1380,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1345 * all transports have been tried at the current 1380 * all transports have been tried at the current
1346 * timeout. 1381 * timeout.
1347 */ 1382 */
1348 t = asoc->init_last_sent_to; 1383 sctp_cmd_t1_timer_update(asoc,
1349 asoc->init_err_counter++; 1384 SCTP_EVENT_TIMEOUT_T1_INIT,
1350 1385 "INIT");
1351 if (t->init_sent_count > (asoc->init_cycle + 1)) {
1352 asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] *= 2;
1353 if (asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] >
1354 asoc->max_init_timeo) {
1355 asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT] =
1356 asoc->max_init_timeo;
1357 }
1358 asoc->init_cycle++;
1359 SCTP_DEBUG_PRINTK(
1360 "T1 INIT Timeout adjustment"
1361 " init_err_counter: %d"
1362 " cycle: %d"
1363 " timeout: %ld\n",
1364 asoc->init_err_counter,
1365 asoc->init_cycle,
1366 asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_INIT]);
1367 }
1368 1386
1369 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, 1387 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART,
1370 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT)); 1388 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT));
@@ -1377,20 +1395,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1377 * all transports have been tried at the current 1395 * all transports have been tried at the current
1378 * timeout. 1396 * timeout.
1379 */ 1397 */
1380 asoc->init_err_counter++; 1398 sctp_cmd_t1_timer_update(asoc,
1381 1399 SCTP_EVENT_TIMEOUT_T1_COOKIE,
1382 asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] *= 2; 1400 "COOKIE");
1383 if (asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] >
1384 asoc->max_init_timeo) {
1385 asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE] =
1386 asoc->max_init_timeo;
1387 }
1388 SCTP_DEBUG_PRINTK(
1389 "T1 COOKIE Timeout adjustment"
1390 " init_err_counter: %d"
1391 " timeout: %ld\n",
1392 asoc->init_err_counter,
1393 asoc->timeouts[SCTP_EVENT_TIMEOUT_T1_COOKIE]);
1394 1401
1395 /* If we've sent any data bundled with 1402 /* If we've sent any data bundled with
1396 * COOKIE-ECHO we need to resend. 1403 * COOKIE-ECHO we need to resend.
@@ -1422,6 +1429,10 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1422 case SCTP_CMD_INIT_COUNTER_RESET: 1429 case SCTP_CMD_INIT_COUNTER_RESET:
1423 asoc->init_err_counter = 0; 1430 asoc->init_err_counter = 0;
1424 asoc->init_cycle = 0; 1431 asoc->init_cycle = 0;
1432 list_for_each_entry(t, &asoc->peer.transport_addr_list,
1433 transports) {
1434 t->init_sent_count = 0;
1435 }
1425 break; 1436 break;
1426 1437
1427 case SCTP_CMD_REPORT_DUP: 1438 case SCTP_CMD_REPORT_DUP:
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 8848d329aa2c..d4c3fbc4671e 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -119,7 +119,7 @@ static sctp_disposition_t sctp_sf_violation_paramlen(
119 const struct sctp_endpoint *ep, 119 const struct sctp_endpoint *ep,
120 const struct sctp_association *asoc, 120 const struct sctp_association *asoc,
121 const sctp_subtype_t type, 121 const sctp_subtype_t type,
122 void *arg, 122 void *arg, void *ext,
123 sctp_cmd_seq_t *commands); 123 sctp_cmd_seq_t *commands);
124 124
125static sctp_disposition_t sctp_sf_violation_ctsn( 125static sctp_disposition_t sctp_sf_violation_ctsn(
@@ -315,8 +315,10 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const struct sctp_endpoint *ep,
315 /* If the packet is an OOTB packet which is temporarily on the 315 /* If the packet is an OOTB packet which is temporarily on the
316 * control endpoint, respond with an ABORT. 316 * control endpoint, respond with an ABORT.
317 */ 317 */
318 if (ep == sctp_sk((sctp_get_ctl_sock()))->ep) 318 if (ep == sctp_sk((sctp_get_ctl_sock()))->ep) {
319 SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES);
319 return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands); 320 return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
321 }
320 322
321 /* 3.1 A packet containing an INIT chunk MUST have a zero Verification 323 /* 3.1 A packet containing an INIT chunk MUST have a zero Verification
322 * Tag. 324 * Tag.
@@ -635,8 +637,10 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
635 /* If the packet is an OOTB packet which is temporarily on the 637 /* If the packet is an OOTB packet which is temporarily on the
636 * control endpoint, respond with an ABORT. 638 * control endpoint, respond with an ABORT.
637 */ 639 */
638 if (ep == sctp_sk((sctp_get_ctl_sock()))->ep) 640 if (ep == sctp_sk((sctp_get_ctl_sock()))->ep) {
641 SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES);
639 return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands); 642 return sctp_sf_tabort_8_4_8(ep, asoc, type, arg, commands);
643 }
640 644
641 /* Make sure that the COOKIE_ECHO chunk has a valid length. 645 /* Make sure that the COOKIE_ECHO chunk has a valid length.
642 * In this case, we check that we have enough for at least a 646 * In this case, we check that we have enough for at least a
@@ -2076,10 +2080,6 @@ sctp_disposition_t sctp_sf_shutdown_pending_abort(
2076 sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest)) 2080 sctp_bind_addr_state(&asoc->base.bind_addr, &chunk->dest))
2077 return sctp_sf_discard_chunk(ep, asoc, type, arg, commands); 2081 return sctp_sf_discard_chunk(ep, asoc, type, arg, commands);
2078 2082
2079 /* Stop the T5-shutdown guard timer. */
2080 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
2081 SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
2082
2083 return __sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands); 2083 return __sctp_sf_do_9_1_abort(ep, asoc, type, arg, commands);
2084} 2084}
2085 2085
@@ -3382,6 +3382,8 @@ sctp_disposition_t sctp_sf_do_8_5_1_E_sa(const struct sctp_endpoint *ep,
3382 * packet and the state function that handles OOTB SHUTDOWN_ACK is 3382 * packet and the state function that handles OOTB SHUTDOWN_ACK is
3383 * called with a NULL association. 3383 * called with a NULL association.
3384 */ 3384 */
3385 SCTP_INC_STATS(SCTP_MIB_OUTOFBLUES);
3386
3385 return sctp_sf_shut_8_4_5(ep, NULL, type, arg, commands); 3387 return sctp_sf_shut_8_4_5(ep, NULL, type, arg, commands);
3386} 3388}
3387 3389
@@ -3425,7 +3427,7 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep,
3425 addr_param = (union sctp_addr_param *)hdr->params; 3427 addr_param = (union sctp_addr_param *)hdr->params;
3426 length = ntohs(addr_param->p.length); 3428 length = ntohs(addr_param->p.length);
3427 if (length < sizeof(sctp_paramhdr_t)) 3429 if (length < sizeof(sctp_paramhdr_t))
3428 return sctp_sf_violation_paramlen(ep, asoc, type, 3430 return sctp_sf_violation_paramlen(ep, asoc, type, arg,
3429 (void *)addr_param, commands); 3431 (void *)addr_param, commands);
3430 3432
3431 /* Verify the ASCONF chunk before processing it. */ 3433 /* Verify the ASCONF chunk before processing it. */
@@ -3433,8 +3435,8 @@ sctp_disposition_t sctp_sf_do_asconf(const struct sctp_endpoint *ep,
3433 (sctp_paramhdr_t *)((void *)addr_param + length), 3435 (sctp_paramhdr_t *)((void *)addr_param + length),
3434 (void *)chunk->chunk_end, 3436 (void *)chunk->chunk_end,
3435 &err_param)) 3437 &err_param))
3436 return sctp_sf_violation_paramlen(ep, asoc, type, 3438 return sctp_sf_violation_paramlen(ep, asoc, type, arg,
3437 (void *)&err_param, commands); 3439 (void *)err_param, commands);
3438 3440
3439 /* ADDIP 5.2 E1) Compare the value of the serial number to the value 3441 /* ADDIP 5.2 E1) Compare the value of the serial number to the value
3440 * the endpoint stored in a new association variable 3442 * the endpoint stored in a new association variable
@@ -3542,8 +3544,8 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
3542 (sctp_paramhdr_t *)addip_hdr->params, 3544 (sctp_paramhdr_t *)addip_hdr->params,
3543 (void *)asconf_ack->chunk_end, 3545 (void *)asconf_ack->chunk_end,
3544 &err_param)) 3546 &err_param))
3545 return sctp_sf_violation_paramlen(ep, asoc, type, 3547 return sctp_sf_violation_paramlen(ep, asoc, type, arg,
3546 (void *)&err_param, commands); 3548 (void *)err_param, commands);
3547 3549
3548 if (last_asconf) { 3550 if (last_asconf) {
3549 addip_hdr = (sctp_addiphdr_t *)last_asconf->subh.addip_hdr; 3551 addip_hdr = (sctp_addiphdr_t *)last_asconf->subh.addip_hdr;
@@ -4186,11 +4188,10 @@ static sctp_disposition_t sctp_sf_abort_violation(
4186 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS); 4188 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
4187 } 4189 }
4188 4190
4189discard:
4190 sctp_sf_pdiscard(ep, asoc, SCTP_ST_CHUNK(0), arg, commands);
4191
4192 SCTP_INC_STATS(SCTP_MIB_ABORTEDS); 4191 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
4193 4192
4193discard:
4194 sctp_sf_pdiscard(ep, asoc, SCTP_ST_CHUNK(0), arg, commands);
4194 return SCTP_DISPOSITION_ABORT; 4195 return SCTP_DISPOSITION_ABORT;
4195 4196
4196nomem_pkt: 4197nomem_pkt:
@@ -4240,12 +4241,36 @@ static sctp_disposition_t sctp_sf_violation_paramlen(
4240 const struct sctp_endpoint *ep, 4241 const struct sctp_endpoint *ep,
4241 const struct sctp_association *asoc, 4242 const struct sctp_association *asoc,
4242 const sctp_subtype_t type, 4243 const sctp_subtype_t type,
4243 void *arg, 4244 void *arg, void *ext,
4244 sctp_cmd_seq_t *commands) { 4245 sctp_cmd_seq_t *commands)
4245 static const char err_str[] = "The following parameter had invalid length:"; 4246{
4247 struct sctp_chunk *chunk = arg;
4248 struct sctp_paramhdr *param = ext;
4249 struct sctp_chunk *abort = NULL;
4246 4250
4247 return sctp_sf_abort_violation(ep, asoc, arg, commands, err_str, 4251 if (sctp_auth_recv_cid(SCTP_CID_ABORT, asoc))
4248 sizeof(err_str)); 4252 goto discard;
4253
4254 /* Make the abort chunk. */
4255 abort = sctp_make_violation_paramlen(asoc, chunk, param);
4256 if (!abort)
4257 goto nomem;
4258
4259 sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
4260 SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
4261
4262 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
4263 SCTP_ERROR(ECONNABORTED));
4264 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
4265 SCTP_PERR(SCTP_ERROR_PROTO_VIOLATION));
4266 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
4267 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
4268
4269discard:
4270 sctp_sf_pdiscard(ep, asoc, SCTP_ST_CHUNK(0), arg, commands);
4271 return SCTP_DISPOSITION_ABORT;
4272nomem:
4273 return SCTP_DISPOSITION_NOMEM;
4249} 4274}
4250 4275
4251/* Handle a protocol violation when the peer trying to advance the 4276/* Handle a protocol violation when the peer trying to advance the
@@ -4517,13 +4542,6 @@ sctp_disposition_t sctp_sf_do_9_2_prm_shutdown(
4517 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, 4542 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
4518 SCTP_STATE(SCTP_STATE_SHUTDOWN_PENDING)); 4543 SCTP_STATE(SCTP_STATE_SHUTDOWN_PENDING));
4519 4544
4520 /* sctpimpguide-05 Section 2.12.2
4521 * The sender of the SHUTDOWN MAY also start an overall guard timer
4522 * 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
4523 */
4524 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
4525 SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
4526
4527 disposition = SCTP_DISPOSITION_CONSUME; 4545 disposition = SCTP_DISPOSITION_CONSUME;
4528 if (sctp_outq_is_empty(&asoc->outqueue)) { 4546 if (sctp_outq_is_empty(&asoc->outqueue)) {
4529 disposition = sctp_sf_do_9_2_start_shutdown(ep, asoc, type, 4547 disposition = sctp_sf_do_9_2_start_shutdown(ep, asoc, type,
@@ -4968,6 +4986,13 @@ sctp_disposition_t sctp_sf_do_9_2_start_shutdown(
4968 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, 4986 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
4969 SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN)); 4987 SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN));
4970 4988
4989 /* RFC 4960 Section 9.2
4990 * The sender of the SHUTDOWN MAY also start an overall guard timer
4991 * 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
4992 */
4993 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
4994 SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
4995
4971 if (asoc->autoclose) 4996 if (asoc->autoclose)
4972 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, 4997 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP,
4973 SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE)); 4998 SCTP_TO(SCTP_EVENT_TIMEOUT_AUTOCLOSE));
@@ -5279,6 +5304,8 @@ sctp_disposition_t sctp_sf_t1_cookie_timer_expire(const struct sctp_endpoint *ep
5279 if (!repl) 5304 if (!repl)
5280 return SCTP_DISPOSITION_NOMEM; 5305 return SCTP_DISPOSITION_NOMEM;
5281 5306
5307 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_CHOOSE_TRANSPORT,
5308 SCTP_CHUNK(repl));
5282 /* Issue a sideeffect to do the needed accounting. */ 5309 /* Issue a sideeffect to do the needed accounting. */
5283 sctp_add_cmd_sf(commands, SCTP_CMD_COOKIEECHO_RESTART, 5310 sctp_add_cmd_sf(commands, SCTP_CMD_COOKIEECHO_RESTART,
5284 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE)); 5311 SCTP_TO(SCTP_EVENT_TIMEOUT_T1_COOKIE));
@@ -5406,7 +5433,7 @@ sctp_disposition_t sctp_sf_t4_timer_expire(
5406 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, 5433 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
5407 SCTP_PERR(SCTP_ERROR_NO_ERROR)); 5434 SCTP_PERR(SCTP_ERROR_NO_ERROR));
5408 SCTP_INC_STATS(SCTP_MIB_ABORTEDS); 5435 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
5409 SCTP_INC_STATS(SCTP_MIB_CURRESTAB); 5436 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
5410 return SCTP_DISPOSITION_ABORT; 5437 return SCTP_DISPOSITION_ABORT;
5411 } 5438 }
5412 5439
@@ -5462,6 +5489,9 @@ sctp_disposition_t sctp_sf_t5_timer_expire(const struct sctp_endpoint *ep,
5462 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, 5489 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
5463 SCTP_PERR(SCTP_ERROR_NO_ERROR)); 5490 SCTP_PERR(SCTP_ERROR_NO_ERROR));
5464 5491
5492 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
5493 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
5494
5465 return SCTP_DISPOSITION_DELETE_TCB; 5495 return SCTP_DISPOSITION_DELETE_TCB;
5466nomem: 5496nomem:
5467 return SCTP_DISPOSITION_NOMEM; 5497 return SCTP_DISPOSITION_NOMEM;
@@ -5494,12 +5524,6 @@ sctp_disposition_t sctp_sf_autoclose_timer_expire(
5494 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, 5524 sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
5495 SCTP_STATE(SCTP_STATE_SHUTDOWN_PENDING)); 5525 SCTP_STATE(SCTP_STATE_SHUTDOWN_PENDING));
5496 5526
5497 /* sctpimpguide-05 Section 2.12.2
5498 * The sender of the SHUTDOWN MAY also start an overall guard timer
5499 * 'T5-shutdown-guard' to bound the overall time for shutdown sequence.
5500 */
5501 sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START,
5502 SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD));
5503 disposition = SCTP_DISPOSITION_CONSUME; 5527 disposition = SCTP_DISPOSITION_CONSUME;
5504 if (sctp_outq_is_empty(&asoc->outqueue)) { 5528 if (sctp_outq_is_empty(&asoc->outqueue)) {
5505 disposition = sctp_sf_do_9_2_start_shutdown(ep, asoc, type, 5529 disposition = sctp_sf_do_9_2_start_shutdown(ep, asoc, type,
diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c
index d991237fb400..dd4ddc40c0ad 100644
--- a/net/sctp/sm_statetable.c
+++ b/net/sctp/sm_statetable.c
@@ -897,7 +897,7 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_
897 /* SCTP_STATE_ESTABLISHED */ \ 897 /* SCTP_STATE_ESTABLISHED */ \
898 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ 898 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
899 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 899 /* SCTP_STATE_SHUTDOWN_PENDING */ \
900 TYPE_SCTP_FUNC(sctp_sf_t5_timer_expire), \ 900 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
901 /* SCTP_STATE_SHUTDOWN_SENT */ \ 901 /* SCTP_STATE_SHUTDOWN_SENT */ \
902 TYPE_SCTP_FUNC(sctp_sf_t5_timer_expire), \ 902 TYPE_SCTP_FUNC(sctp_sf_t5_timer_expire), \
903 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 903 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 5ffb9dec1c3f..a1b904529d5e 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2309,7 +2309,7 @@ static int sctp_setsockopt_peer_addr_params(struct sock *sk,
2309 /* If an address other than INADDR_ANY is specified, and 2309 /* If an address other than INADDR_ANY is specified, and
2310 * no transport is found, then the request is invalid. 2310 * no transport is found, then the request is invalid.
2311 */ 2311 */
2312 if (!sctp_is_any(( union sctp_addr *)&params.spp_address)) { 2312 if (!sctp_is_any(sk, ( union sctp_addr *)&params.spp_address)) {
2313 trans = sctp_addr_id2transport(sk, &params.spp_address, 2313 trans = sctp_addr_id2transport(sk, &params.spp_address,
2314 params.spp_assoc_id); 2314 params.spp_assoc_id);
2315 if (!trans) 2315 if (!trans)
@@ -4062,7 +4062,7 @@ static int sctp_getsockopt_peer_addr_params(struct sock *sk, int len,
4062 /* If an address other than INADDR_ANY is specified, and 4062 /* If an address other than INADDR_ANY is specified, and
4063 * no transport is found, then the request is invalid. 4063 * no transport is found, then the request is invalid.
4064 */ 4064 */
4065 if (!sctp_is_any(( union sctp_addr *)&params.spp_address)) { 4065 if (!sctp_is_any(sk, ( union sctp_addr *)&params.spp_address)) {
4066 trans = sctp_addr_id2transport(sk, &params.spp_address, 4066 trans = sctp_addr_id2transport(sk, &params.spp_address,
4067 params.spp_assoc_id); 4067 params.spp_assoc_id);
4068 if (!trans) { 4068 if (!trans) {
@@ -4414,7 +4414,7 @@ static int sctp_getsockopt_local_addrs_num_old(struct sock *sk, int len,
4414 if (sctp_list_single_entry(&bp->address_list)) { 4414 if (sctp_list_single_entry(&bp->address_list)) {
4415 addr = list_entry(bp->address_list.next, 4415 addr = list_entry(bp->address_list.next,
4416 struct sctp_sockaddr_entry, list); 4416 struct sctp_sockaddr_entry, list);
4417 if (sctp_is_any(&addr->a)) { 4417 if (sctp_is_any(sk, &addr->a)) {
4418 rcu_read_lock(); 4418 rcu_read_lock();
4419 list_for_each_entry_rcu(addr, 4419 list_for_each_entry_rcu(addr,
4420 &sctp_local_addr_list, list) { 4420 &sctp_local_addr_list, list) {
@@ -4602,7 +4602,7 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len,
4602 if (sctp_list_single_entry(&bp->address_list)) { 4602 if (sctp_list_single_entry(&bp->address_list)) {
4603 addr = list_entry(bp->address_list.next, 4603 addr = list_entry(bp->address_list.next,
4604 struct sctp_sockaddr_entry, list); 4604 struct sctp_sockaddr_entry, list);
4605 if (sctp_is_any(&addr->a)) { 4605 if (sctp_is_any(sk, &addr->a)) {
4606 cnt = sctp_copy_laddrs_old(sk, bp->port, 4606 cnt = sctp_copy_laddrs_old(sk, bp->port,
4607 getaddrs.addr_num, 4607 getaddrs.addr_num,
4608 addrs, &bytes_copied); 4608 addrs, &bytes_copied);
@@ -4695,7 +4695,7 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
4695 if (sctp_list_single_entry(&bp->address_list)) { 4695 if (sctp_list_single_entry(&bp->address_list)) {
4696 addr = list_entry(bp->address_list.next, 4696 addr = list_entry(bp->address_list.next,
4697 struct sctp_sockaddr_entry, list); 4697 struct sctp_sockaddr_entry, list);
4698 if (sctp_is_any(&addr->a)) { 4698 if (sctp_is_any(sk, &addr->a)) {
4699 cnt = sctp_copy_laddrs(sk, bp->port, addrs, 4699 cnt = sctp_copy_laddrs(sk, bp->port, addrs,
4700 space_left, &bytes_copied); 4700 space_left, &bytes_copied);
4701 if (cnt < 0) { 4701 if (cnt < 0) {
diff --git a/net/sctp/tsnmap.c b/net/sctp/tsnmap.c
index f3e58b275905..35c73e82553a 100644
--- a/net/sctp/tsnmap.c
+++ b/net/sctp/tsnmap.c
@@ -43,37 +43,44 @@
43 */ 43 */
44 44
45#include <linux/types.h> 45#include <linux/types.h>
46#include <linux/bitmap.h>
46#include <net/sctp/sctp.h> 47#include <net/sctp/sctp.h>
47#include <net/sctp/sm.h> 48#include <net/sctp/sm.h>
48 49
49static void sctp_tsnmap_update(struct sctp_tsnmap *map); 50static void sctp_tsnmap_update(struct sctp_tsnmap *map);
50static void sctp_tsnmap_find_gap_ack(__u8 *map, __u16 off, 51static void sctp_tsnmap_find_gap_ack(unsigned long *map, __u16 off,
51 __u16 len, __u16 base, 52 __u16 len, __u16 *start, __u16 *end);
52 int *started, __u16 *start, 53static int sctp_tsnmap_grow(struct sctp_tsnmap *map, u16 gap);
53 int *ended, __u16 *end);
54 54
55/* Initialize a block of memory as a tsnmap. */ 55/* Initialize a block of memory as a tsnmap. */
56struct sctp_tsnmap *sctp_tsnmap_init(struct sctp_tsnmap *map, __u16 len, 56struct sctp_tsnmap *sctp_tsnmap_init(struct sctp_tsnmap *map, __u16 len,
57 __u32 initial_tsn) 57 __u32 initial_tsn, gfp_t gfp)
58{ 58{
59 map->tsn_map = map->raw_map; 59 if (!map->tsn_map) {
60 map->overflow_map = map->tsn_map + len; 60 map->tsn_map = kzalloc(len>>3, gfp);
61 map->len = len; 61 if (map->tsn_map == NULL)
62 62 return NULL;
63 /* Clear out a TSN ack status. */ 63
64 memset(map->tsn_map, 0x00, map->len + map->len); 64 map->len = len;
65 } else {
66 bitmap_zero(map->tsn_map, map->len);
67 }
65 68
66 /* Keep track of TSNs represented by tsn_map. */ 69 /* Keep track of TSNs represented by tsn_map. */
67 map->base_tsn = initial_tsn; 70 map->base_tsn = initial_tsn;
68 map->overflow_tsn = initial_tsn + map->len;
69 map->cumulative_tsn_ack_point = initial_tsn - 1; 71 map->cumulative_tsn_ack_point = initial_tsn - 1;
70 map->max_tsn_seen = map->cumulative_tsn_ack_point; 72 map->max_tsn_seen = map->cumulative_tsn_ack_point;
71 map->malloced = 0;
72 map->num_dup_tsns = 0; 73 map->num_dup_tsns = 0;
73 74
74 return map; 75 return map;
75} 76}
76 77
78void sctp_tsnmap_free(struct sctp_tsnmap *map)
79{
80 map->len = 0;
81 kfree(map->tsn_map);
82}
83
77/* Test the tracking state of this TSN. 84/* Test the tracking state of this TSN.
78 * Returns: 85 * Returns:
79 * 0 if the TSN has not yet been seen 86 * 0 if the TSN has not yet been seen
@@ -82,66 +89,69 @@ struct sctp_tsnmap *sctp_tsnmap_init(struct sctp_tsnmap *map, __u16 len,
82 */ 89 */
83int sctp_tsnmap_check(const struct sctp_tsnmap *map, __u32 tsn) 90int sctp_tsnmap_check(const struct sctp_tsnmap *map, __u32 tsn)
84{ 91{
85 __s32 gap; 92 u32 gap;
86 int dup; 93
94 /* Check to see if this is an old TSN */
95 if (TSN_lte(tsn, map->cumulative_tsn_ack_point))
96 return 1;
97
98 /* Verify that we can hold this TSN and that it will not
99 * overlfow our map
100 */
101 if (!TSN_lt(tsn, map->base_tsn + SCTP_TSN_MAP_SIZE))
102 return -1;
87 103
88 /* Calculate the index into the mapping arrays. */ 104 /* Calculate the index into the mapping arrays. */
89 gap = tsn - map->base_tsn; 105 gap = tsn - map->base_tsn;
90 106
91 /* Verify that we can hold this TSN. */ 107 /* Check to see if TSN has already been recorded. */
92 if (gap >= (/* base */ map->len + /* overflow */ map->len)) { 108 if (gap < map->len && test_bit(gap, map->tsn_map))
93 dup = -1; 109 return 1;
94 goto out;
95 }
96
97 /* Honk if we've already seen this TSN.
98 * We have three cases:
99 * 1. The TSN is ancient or belongs to a previous tsn_map.
100 * 2. The TSN is already marked in the tsn_map.
101 * 3. The TSN is already marked in the tsn_map_overflow.
102 */
103 if (gap < 0 ||
104 (gap < map->len && map->tsn_map[gap]) ||
105 (gap >= map->len && map->overflow_map[gap - map->len]))
106 dup = 1;
107 else 110 else
108 dup = 0; 111 return 0;
109
110out:
111 return dup;
112} 112}
113 113
114 114
115/* Mark this TSN as seen. */ 115/* Mark this TSN as seen. */
116void sctp_tsnmap_mark(struct sctp_tsnmap *map, __u32 tsn) 116int sctp_tsnmap_mark(struct sctp_tsnmap *map, __u32 tsn)
117{ 117{
118 __s32 gap; 118 u16 gap;
119 119
120 /* Vacuously mark any TSN which precedes the map base or
121 * exceeds the end of the map.
122 */
123 if (TSN_lt(tsn, map->base_tsn)) 120 if (TSN_lt(tsn, map->base_tsn))
124 return; 121 return 0;
125 if (!TSN_lt(tsn, map->base_tsn + map->len + map->len))
126 return;
127
128 /* Bump the max. */
129 if (TSN_lt(map->max_tsn_seen, tsn))
130 map->max_tsn_seen = tsn;
131 122
132 /* Assert: TSN is in range. */
133 gap = tsn - map->base_tsn; 123 gap = tsn - map->base_tsn;
134 124
135 /* Mark the TSN as received. */ 125 if (gap >= map->len && !sctp_tsnmap_grow(map, gap))
136 if (gap < map->len) 126 return -ENOMEM;
137 map->tsn_map[gap]++;
138 else
139 map->overflow_map[gap - map->len]++;
140 127
141 /* Go fixup any internal TSN mapping variables including 128 if (!sctp_tsnmap_has_gap(map) && gap == 0) {
142 * cumulative_tsn_ack_point. 129 /* In this case the map has no gaps and the tsn we are
143 */ 130 * recording is the next expected tsn. We don't touch
144 sctp_tsnmap_update(map); 131 * the map but simply bump the values.
132 */
133 map->max_tsn_seen++;
134 map->cumulative_tsn_ack_point++;
135 map->base_tsn++;
136 } else {
137 /* Either we already have a gap, or about to record a gap, so
138 * have work to do.
139 *
140 * Bump the max.
141 */
142 if (TSN_lt(map->max_tsn_seen, tsn))
143 map->max_tsn_seen = tsn;
144
145 /* Mark the TSN as received. */
146 set_bit(gap, map->tsn_map);
147
148 /* Go fixup any internal TSN mapping variables including
149 * cumulative_tsn_ack_point.
150 */
151 sctp_tsnmap_update(map);
152 }
153
154 return 0;
145} 155}
146 156
147 157
@@ -160,66 +170,34 @@ SCTP_STATIC int sctp_tsnmap_next_gap_ack(const struct sctp_tsnmap *map,
160 struct sctp_tsnmap_iter *iter, 170 struct sctp_tsnmap_iter *iter,
161 __u16 *start, __u16 *end) 171 __u16 *start, __u16 *end)
162{ 172{
163 int started, ended; 173 int ended = 0;
164 __u16 start_, end_, offset; 174 __u16 start_ = 0, end_ = 0, offset;
165
166 /* We haven't found a gap yet. */
167 started = ended = 0;
168 175
169 /* If there are no more gap acks possible, get out fast. */ 176 /* If there are no more gap acks possible, get out fast. */
170 if (TSN_lte(map->max_tsn_seen, iter->start)) 177 if (TSN_lte(map->max_tsn_seen, iter->start))
171 return 0; 178 return 0;
172 179
173 /* Search the first mapping array. */ 180 offset = iter->start - map->base_tsn;
174 if (iter->start - map->base_tsn < map->len) { 181 sctp_tsnmap_find_gap_ack(map->tsn_map, offset, map->len,
175 182 &start_, &end_);
176 offset = iter->start - map->base_tsn;
177 sctp_tsnmap_find_gap_ack(map->tsn_map, offset, map->len, 0,
178 &started, &start_, &ended, &end_);
179 }
180
181 /* Do we need to check the overflow map? */
182 if (!ended) {
183 /* Fix up where we'd like to start searching in the
184 * overflow map.
185 */
186 if (iter->start - map->base_tsn < map->len)
187 offset = 0;
188 else
189 offset = iter->start - map->base_tsn - map->len;
190
191 /* Search the overflow map. */
192 sctp_tsnmap_find_gap_ack(map->overflow_map,
193 offset,
194 map->len,
195 map->len,
196 &started, &start_,
197 &ended, &end_);
198 }
199 183
200 /* The Gap Ack Block happens to end at the end of the 184 /* The Gap Ack Block happens to end at the end of the map. */
201 * overflow map. 185 if (start_ && !end_)
202 */ 186 end_ = map->len - 1;
203 if (started && !ended) {
204 ended++;
205 end_ = map->len + map->len - 1;
206 }
207 187
208 /* If we found a Gap Ack Block, return the start and end and 188 /* If we found a Gap Ack Block, return the start and end and
209 * bump the iterator forward. 189 * bump the iterator forward.
210 */ 190 */
211 if (ended) { 191 if (end_) {
212 /* Fix up the start and end based on the 192 /* Fix up the start and end based on the
213 * Cumulative TSN Ack offset into the map. 193 * Cumulative TSN Ack which is always 1 behind base.
214 */ 194 */
215 int gap = map->cumulative_tsn_ack_point - 195 *start = start_ + 1;
216 map->base_tsn; 196 *end = end_ + 1;
217
218 *start = start_ - gap;
219 *end = end_ - gap;
220 197
221 /* Move the iterator forward. */ 198 /* Move the iterator forward. */
222 iter->start = map->cumulative_tsn_ack_point + *end + 1; 199 iter->start = map->cumulative_tsn_ack_point + *end + 1;
200 ended = 1;
223 } 201 }
224 202
225 return ended; 203 return ended;
@@ -228,35 +206,33 @@ SCTP_STATIC int sctp_tsnmap_next_gap_ack(const struct sctp_tsnmap *map,
228/* Mark this and any lower TSN as seen. */ 206/* Mark this and any lower TSN as seen. */
229void sctp_tsnmap_skip(struct sctp_tsnmap *map, __u32 tsn) 207void sctp_tsnmap_skip(struct sctp_tsnmap *map, __u32 tsn)
230{ 208{
231 __s32 gap; 209 u32 gap;
232 210
233 /* Vacuously mark any TSN which precedes the map base or
234 * exceeds the end of the map.
235 */
236 if (TSN_lt(tsn, map->base_tsn)) 211 if (TSN_lt(tsn, map->base_tsn))
237 return; 212 return;
238 if (!TSN_lt(tsn, map->base_tsn + map->len + map->len)) 213 if (!TSN_lt(tsn, map->base_tsn + SCTP_TSN_MAP_SIZE))
239 return; 214 return;
240 215
241 /* Bump the max. */ 216 /* Bump the max. */
242 if (TSN_lt(map->max_tsn_seen, tsn)) 217 if (TSN_lt(map->max_tsn_seen, tsn))
243 map->max_tsn_seen = tsn; 218 map->max_tsn_seen = tsn;
244 219
245 /* Assert: TSN is in range. */
246 gap = tsn - map->base_tsn + 1; 220 gap = tsn - map->base_tsn + 1;
247 221
248 /* Mark the TSNs as received. */ 222 map->base_tsn += gap;
249 if (gap <= map->len) 223 map->cumulative_tsn_ack_point += gap;
250 memset(map->tsn_map, 0x01, gap); 224 if (gap >= map->len) {
251 else { 225 /* If our gap is larger then the map size, just
252 memset(map->tsn_map, 0x01, map->len); 226 * zero out the map.
253 memset(map->overflow_map, 0x01, (gap - map->len)); 227 */
228 bitmap_zero(map->tsn_map, map->len);
229 } else {
230 /* If the gap is smaller then the map size,
231 * shift the map by 'gap' bits and update further.
232 */
233 bitmap_shift_right(map->tsn_map, map->tsn_map, gap, map->len);
234 sctp_tsnmap_update(map);
254 } 235 }
255
256 /* Go fixup any internal TSN mapping variables including
257 * cumulative_tsn_ack_point.
258 */
259 sctp_tsnmap_update(map);
260} 236}
261 237
262/******************************************************************** 238/********************************************************************
@@ -268,27 +244,19 @@ void sctp_tsnmap_skip(struct sctp_tsnmap *map, __u32 tsn)
268 */ 244 */
269static void sctp_tsnmap_update(struct sctp_tsnmap *map) 245static void sctp_tsnmap_update(struct sctp_tsnmap *map)
270{ 246{
271 __u32 ctsn; 247 u16 len;
272 248 unsigned long zero_bit;
273 ctsn = map->cumulative_tsn_ack_point; 249
274 do { 250
275 ctsn++; 251 len = map->max_tsn_seen - map->cumulative_tsn_ack_point;
276 if (ctsn == map->overflow_tsn) { 252 zero_bit = find_first_zero_bit(map->tsn_map, len);
277 /* Now tsn_map must have been all '1's, 253 if (!zero_bit)
278 * so we swap the map and check the overflow table 254 return; /* The first 0-bit is bit 0. nothing to do */
279 */ 255
280 __u8 *tmp = map->tsn_map; 256 map->base_tsn += zero_bit;
281 memset(tmp, 0, map->len); 257 map->cumulative_tsn_ack_point += zero_bit;
282 map->tsn_map = map->overflow_map;
283 map->overflow_map = tmp;
284
285 /* Update the tsn_map boundaries. */
286 map->base_tsn += map->len;
287 map->overflow_tsn += map->len;
288 }
289 } while (map->tsn_map[ctsn - map->base_tsn]);
290 258
291 map->cumulative_tsn_ack_point = ctsn - 1; /* Back up one. */ 259 bitmap_shift_right(map->tsn_map, map->tsn_map, zero_bit, map->len);
292} 260}
293 261
294/* How many data chunks are we missing from our peer? 262/* How many data chunks are we missing from our peer?
@@ -299,31 +267,19 @@ __u16 sctp_tsnmap_pending(struct sctp_tsnmap *map)
299 __u32 max_tsn = map->max_tsn_seen; 267 __u32 max_tsn = map->max_tsn_seen;
300 __u32 base_tsn = map->base_tsn; 268 __u32 base_tsn = map->base_tsn;
301 __u16 pending_data; 269 __u16 pending_data;
302 __s32 gap, start, end, i; 270 u32 gap, i;
303 271
304 pending_data = max_tsn - cum_tsn; 272 pending_data = max_tsn - cum_tsn;
305 gap = max_tsn - base_tsn; 273 gap = max_tsn - base_tsn;
306 274
307 if (gap <= 0 || gap >= (map->len + map->len)) 275 if (gap == 0 || gap >= map->len)
308 goto out; 276 goto out;
309 277
310 start = ((cum_tsn >= base_tsn) ? (cum_tsn - base_tsn + 1) : 0); 278 for (i = 0; i < gap+1; i++) {
311 end = ((gap > map->len ) ? map->len : gap + 1); 279 if (test_bit(i, map->tsn_map))
312
313 for (i = start; i < end; i++) {
314 if (map->tsn_map[i])
315 pending_data--; 280 pending_data--;
316 } 281 }
317 282
318 if (gap >= map->len) {
319 start = 0;
320 end = gap - map->len + 1;
321 for (i = start; i < end; i++) {
322 if (map->overflow_map[i])
323 pending_data--;
324 }
325 }
326
327out: 283out:
328 return pending_data; 284 return pending_data;
329} 285}
@@ -334,10 +290,8 @@ out:
334 * The flags "started" and "ended" tell is if we found the beginning 290 * The flags "started" and "ended" tell is if we found the beginning
335 * or (respectively) the end of a Gap Ack Block. 291 * or (respectively) the end of a Gap Ack Block.
336 */ 292 */
337static void sctp_tsnmap_find_gap_ack(__u8 *map, __u16 off, 293static void sctp_tsnmap_find_gap_ack(unsigned long *map, __u16 off,
338 __u16 len, __u16 base, 294 __u16 len, __u16 *start, __u16 *end)
339 int *started, __u16 *start,
340 int *ended, __u16 *end)
341{ 295{
342 int i = off; 296 int i = off;
343 297
@@ -348,56 +302,44 @@ static void sctp_tsnmap_find_gap_ack(__u8 *map, __u16 off,
348 /* Also, stop looking past the maximum TSN seen. */ 302 /* Also, stop looking past the maximum TSN seen. */
349 303
350 /* Look for the start. */ 304 /* Look for the start. */
351 if (!(*started)) { 305 i = find_next_bit(map, len, off);
352 for (; i < len; i++) { 306 if (i < len)
353 if (map[i]) { 307 *start = i;
354 (*started)++;
355 *start = base + i;
356 break;
357 }
358 }
359 }
360 308
361 /* Look for the end. */ 309 /* Look for the end. */
362 if (*started) { 310 if (*start) {
363 /* We have found the start, let's find the 311 /* We have found the start, let's find the
364 * end. If we find the end, break out. 312 * end. If we find the end, break out.
365 */ 313 */
366 for (; i < len; i++) { 314 i = find_next_zero_bit(map, len, i);
367 if (!map[i]) { 315 if (i < len)
368 (*ended)++; 316 *end = i - 1;
369 *end = base + i - 1;
370 break;
371 }
372 }
373 } 317 }
374} 318}
375 319
376/* Renege that we have seen a TSN. */ 320/* Renege that we have seen a TSN. */
377void sctp_tsnmap_renege(struct sctp_tsnmap *map, __u32 tsn) 321void sctp_tsnmap_renege(struct sctp_tsnmap *map, __u32 tsn)
378{ 322{
379 __s32 gap; 323 u32 gap;
380 324
381 if (TSN_lt(tsn, map->base_tsn)) 325 if (TSN_lt(tsn, map->base_tsn))
382 return; 326 return;
383 if (!TSN_lt(tsn, map->base_tsn + map->len + map->len)) 327 /* Assert: TSN is in range. */
328 if (!TSN_lt(tsn, map->base_tsn + map->len))
384 return; 329 return;
385 330
386 /* Assert: TSN is in range. */
387 gap = tsn - map->base_tsn; 331 gap = tsn - map->base_tsn;
388 332
389 /* Pretend we never saw the TSN. */ 333 /* Pretend we never saw the TSN. */
390 if (gap < map->len) 334 clear_bit(gap, map->tsn_map);
391 map->tsn_map[gap] = 0;
392 else
393 map->overflow_map[gap - map->len] = 0;
394} 335}
395 336
396/* How many gap ack blocks do we have recorded? */ 337/* How many gap ack blocks do we have recorded? */
397__u16 sctp_tsnmap_num_gabs(struct sctp_tsnmap *map) 338__u16 sctp_tsnmap_num_gabs(struct sctp_tsnmap *map,
339 struct sctp_gap_ack_block *gabs)
398{ 340{
399 struct sctp_tsnmap_iter iter; 341 struct sctp_tsnmap_iter iter;
400 int gabs = 0; 342 int ngaps = 0;
401 343
402 /* Refresh the gap ack information. */ 344 /* Refresh the gap ack information. */
403 if (sctp_tsnmap_has_gap(map)) { 345 if (sctp_tsnmap_has_gap(map)) {
@@ -407,12 +349,36 @@ __u16 sctp_tsnmap_num_gabs(struct sctp_tsnmap *map)
407 &start, 349 &start,
408 &end)) { 350 &end)) {
409 351
410 map->gabs[gabs].start = htons(start); 352 gabs[ngaps].start = htons(start);
411 map->gabs[gabs].end = htons(end); 353 gabs[ngaps].end = htons(end);
412 gabs++; 354 ngaps++;
413 if (gabs >= SCTP_MAX_GABS) 355 if (ngaps >= SCTP_MAX_GABS)
414 break; 356 break;
415 } 357 }
416 } 358 }
417 return gabs; 359 return ngaps;
360}
361
362static int sctp_tsnmap_grow(struct sctp_tsnmap *map, u16 gap)
363{
364 unsigned long *new;
365 unsigned long inc;
366 u16 len;
367
368 if (gap >= SCTP_TSN_MAP_SIZE)
369 return 0;
370
371 inc = ALIGN((gap - map->len),BITS_PER_LONG) + SCTP_TSN_MAP_INCREMENT;
372 len = min_t(u16, map->len + inc, SCTP_TSN_MAP_SIZE);
373
374 new = kzalloc(len>>3, GFP_ATOMIC);
375 if (!new)
376 return 0;
377
378 bitmap_copy(new, map->tsn_map, map->max_tsn_seen - map->base_tsn);
379 kfree(map->tsn_map);
380 map->tsn_map = new;
381 map->len = len;
382
383 return 1;
418} 384}
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
index a1f654aea268..5f186ca550d7 100644
--- a/net/sctp/ulpevent.c
+++ b/net/sctp/ulpevent.c
@@ -713,7 +713,9 @@ struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc,
713 /* Now that all memory allocations for this chunk succeeded, we 713 /* Now that all memory allocations for this chunk succeeded, we
714 * can mark it as received so the tsn_map is updated correctly. 714 * can mark it as received so the tsn_map is updated correctly.
715 */ 715 */
716 sctp_tsnmap_mark(&asoc->peer.tsn_map, ntohl(chunk->subh.data_hdr->tsn)); 716 if (sctp_tsnmap_mark(&asoc->peer.tsn_map,
717 ntohl(chunk->subh.data_hdr->tsn)))
718 goto fail_mark;
717 719
718 /* First calculate the padding, so we don't inadvertently 720 /* First calculate the padding, so we don't inadvertently
719 * pass up the wrong length to the user. 721 * pass up the wrong length to the user.
@@ -755,8 +757,12 @@ struct sctp_ulpevent *sctp_ulpevent_make_rcvmsg(struct sctp_association *asoc,
755 event->msg_flags |= chunk->chunk_hdr->flags; 757 event->msg_flags |= chunk->chunk_hdr->flags;
756 event->iif = sctp_chunk_iif(chunk); 758 event->iif = sctp_chunk_iif(chunk);
757 759
758fail:
759 return event; 760 return event;
761
762fail_mark:
763 kfree_skb(skb);
764fail:
765 return NULL;
760} 766}
761 767
762/* Create a partial delivery related event. 768/* Create a partial delivery related event.
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
index 5061a26c5028..7b23803343cc 100644
--- a/net/sctp/ulpqueue.c
+++ b/net/sctp/ulpqueue.c
@@ -317,7 +317,7 @@ static void sctp_ulpq_store_reasm(struct sctp_ulpq *ulpq,
317 } 317 }
318 318
319 /* Insert before pos. */ 319 /* Insert before pos. */
320 __skb_insert(sctp_event2skb(event), pos->prev, pos, &ulpq->reasm); 320 __skb_queue_before(&ulpq->reasm, pos, sctp_event2skb(event));
321 321
322} 322}
323 323
@@ -825,8 +825,7 @@ static void sctp_ulpq_store_ordered(struct sctp_ulpq *ulpq,
825 825
826 826
827 /* Insert before pos. */ 827 /* Insert before pos. */
828 __skb_insert(sctp_event2skb(event), pos->prev, pos, &ulpq->lobby); 828 __skb_queue_before(&ulpq->lobby, pos, sctp_event2skb(event));
829
830} 829}
831 830
832static struct sctp_ulpevent *sctp_ulpq_order(struct sctp_ulpq *ulpq, 831static struct sctp_ulpevent *sctp_ulpq_order(struct sctp_ulpq *ulpq,
diff --git a/net/socket.c b/net/socket.c
index 8ef8ba81b9e2..3e8d4e35c08f 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1511,6 +1511,7 @@ out_fd:
1511 goto out_put; 1511 goto out_put;
1512} 1512}
1513 1513
1514#if 0
1514#ifdef HAVE_SET_RESTORE_SIGMASK 1515#ifdef HAVE_SET_RESTORE_SIGMASK
1515asmlinkage long sys_paccept(int fd, struct sockaddr __user *upeer_sockaddr, 1516asmlinkage long sys_paccept(int fd, struct sockaddr __user *upeer_sockaddr,
1516 int __user *upeer_addrlen, 1517 int __user *upeer_addrlen,
@@ -1564,6 +1565,7 @@ asmlinkage long sys_paccept(int fd, struct sockaddr __user *upeer_sockaddr,
1564 return do_accept(fd, upeer_sockaddr, upeer_addrlen, flags); 1565 return do_accept(fd, upeer_sockaddr, upeer_addrlen, flags);
1565} 1566}
1566#endif 1567#endif
1568#endif
1567 1569
1568asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr, 1570asmlinkage long sys_accept(int fd, struct sockaddr __user *upeer_sockaddr,
1569 int __user *upeer_addrlen) 1571 int __user *upeer_addrlen)
diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c
index e55427f73dfe..5c1954d28d09 100644
--- a/net/sunrpc/xprtrdma/rpc_rdma.c
+++ b/net/sunrpc/xprtrdma/rpc_rdma.c
@@ -769,7 +769,7 @@ repost:
769 /* check for expected message types */ 769 /* check for expected message types */
770 /* The order of some of these tests is important. */ 770 /* The order of some of these tests is important. */
771 switch (headerp->rm_type) { 771 switch (headerp->rm_type) {
772 case __constant_htonl(RDMA_MSG): 772 case htonl(RDMA_MSG):
773 /* never expect read chunks */ 773 /* never expect read chunks */
774 /* never expect reply chunks (two ways to check) */ 774 /* never expect reply chunks (two ways to check) */
775 /* never expect write chunks without having offered RDMA */ 775 /* never expect write chunks without having offered RDMA */
@@ -802,7 +802,7 @@ repost:
802 rpcrdma_inline_fixup(rqst, (char *)iptr, rep->rr_len); 802 rpcrdma_inline_fixup(rqst, (char *)iptr, rep->rr_len);
803 break; 803 break;
804 804
805 case __constant_htonl(RDMA_NOMSG): 805 case htonl(RDMA_NOMSG):
806 /* never expect read or write chunks, always reply chunks */ 806 /* never expect read or write chunks, always reply chunks */
807 if (headerp->rm_body.rm_chunks[0] != xdr_zero || 807 if (headerp->rm_body.rm_chunks[0] != xdr_zero ||
808 headerp->rm_body.rm_chunks[1] != xdr_zero || 808 headerp->rm_body.rm_chunks[1] != xdr_zero ||
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index b1ff16aa4bdb..3ddaff42d1bb 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -96,8 +96,8 @@ struct bcbearer {
96 struct media media; 96 struct media media;
97 struct bcbearer_pair bpairs[MAX_BEARERS]; 97 struct bcbearer_pair bpairs[MAX_BEARERS];
98 struct bcbearer_pair bpairs_temp[TIPC_MAX_LINK_PRI + 1]; 98 struct bcbearer_pair bpairs_temp[TIPC_MAX_LINK_PRI + 1];
99 struct node_map remains; 99 struct tipc_node_map remains;
100 struct node_map remains_new; 100 struct tipc_node_map remains_new;
101}; 101};
102 102
103/** 103/**
@@ -110,7 +110,7 @@ struct bcbearer {
110 110
111struct bclink { 111struct bclink {
112 struct link link; 112 struct link link;
113 struct node node; 113 struct tipc_node node;
114}; 114};
115 115
116 116
@@ -149,7 +149,7 @@ static void bcbuf_decr_acks(struct sk_buff *buf)
149 * Called with 'node' locked, bc_lock unlocked 149 * Called with 'node' locked, bc_lock unlocked
150 */ 150 */
151 151
152static void bclink_set_gap(struct node *n_ptr) 152static void bclink_set_gap(struct tipc_node *n_ptr)
153{ 153{
154 struct sk_buff *buf = n_ptr->bclink.deferred_head; 154 struct sk_buff *buf = n_ptr->bclink.deferred_head;
155 155
@@ -202,7 +202,7 @@ static void bclink_retransmit_pkt(u32 after, u32 to)
202 * Node is locked, bc_lock unlocked. 202 * Node is locked, bc_lock unlocked.
203 */ 203 */
204 204
205void tipc_bclink_acknowledge(struct node *n_ptr, u32 acked) 205void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked)
206{ 206{
207 struct sk_buff *crs; 207 struct sk_buff *crs;
208 struct sk_buff *next; 208 struct sk_buff *next;
@@ -250,7 +250,7 @@ void tipc_bclink_acknowledge(struct node *n_ptr, u32 acked)
250 * tipc_net_lock and node lock set 250 * tipc_net_lock and node lock set
251 */ 251 */
252 252
253static void bclink_send_ack(struct node *n_ptr) 253static void bclink_send_ack(struct tipc_node *n_ptr)
254{ 254{
255 struct link *l_ptr = n_ptr->active_links[n_ptr->addr & 1]; 255 struct link *l_ptr = n_ptr->active_links[n_ptr->addr & 1];
256 256
@@ -264,7 +264,7 @@ static void bclink_send_ack(struct node *n_ptr)
264 * tipc_net_lock and node lock set 264 * tipc_net_lock and node lock set
265 */ 265 */
266 266
267static void bclink_send_nack(struct node *n_ptr) 267static void bclink_send_nack(struct tipc_node *n_ptr)
268{ 268{
269 struct sk_buff *buf; 269 struct sk_buff *buf;
270 struct tipc_msg *msg; 270 struct tipc_msg *msg;
@@ -308,7 +308,7 @@ static void bclink_send_nack(struct node *n_ptr)
308 * tipc_net_lock and node lock set 308 * tipc_net_lock and node lock set
309 */ 309 */
310 310
311void tipc_bclink_check_gap(struct node *n_ptr, u32 last_sent) 311void tipc_bclink_check_gap(struct tipc_node *n_ptr, u32 last_sent)
312{ 312{
313 if (!n_ptr->bclink.supported || 313 if (!n_ptr->bclink.supported ||
314 less_eq(last_sent, mod(n_ptr->bclink.last_in))) 314 less_eq(last_sent, mod(n_ptr->bclink.last_in)))
@@ -328,7 +328,7 @@ void tipc_bclink_check_gap(struct node *n_ptr, u32 last_sent)
328 328
329static void tipc_bclink_peek_nack(u32 dest, u32 sender_tag, u32 gap_after, u32 gap_to) 329static void tipc_bclink_peek_nack(u32 dest, u32 sender_tag, u32 gap_after, u32 gap_to)
330{ 330{
331 struct node *n_ptr = tipc_node_find(dest); 331 struct tipc_node *n_ptr = tipc_node_find(dest);
332 u32 my_after, my_to; 332 u32 my_after, my_to;
333 333
334 if (unlikely(!n_ptr || !tipc_node_is_up(n_ptr))) 334 if (unlikely(!n_ptr || !tipc_node_is_up(n_ptr)))
@@ -418,7 +418,7 @@ void tipc_bclink_recv_pkt(struct sk_buff *buf)
418 static int rx_count = 0; 418 static int rx_count = 0;
419#endif 419#endif
420 struct tipc_msg *msg = buf_msg(buf); 420 struct tipc_msg *msg = buf_msg(buf);
421 struct node* node = tipc_node_find(msg_prevnode(msg)); 421 struct tipc_node* node = tipc_node_find(msg_prevnode(msg));
422 u32 next_in; 422 u32 next_in;
423 u32 seqno; 423 u32 seqno;
424 struct sk_buff *deferred; 424 struct sk_buff *deferred;
@@ -538,7 +538,7 @@ u32 tipc_bclink_get_last_sent(void)
538 return last_sent; 538 return last_sent;
539} 539}
540 540
541u32 tipc_bclink_acks_missing(struct node *n_ptr) 541u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr)
542{ 542{
543 return (n_ptr->bclink.supported && 543 return (n_ptr->bclink.supported &&
544 (tipc_bclink_get_last_sent() != n_ptr->bclink.acked)); 544 (tipc_bclink_get_last_sent() != n_ptr->bclink.acked));
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h
index a2416fa6b906..5aa024b99c55 100644
--- a/net/tipc/bcast.h
+++ b/net/tipc/bcast.h
@@ -41,12 +41,12 @@
41#define WSIZE 32 41#define WSIZE 32
42 42
43/** 43/**
44 * struct node_map - set of node identifiers 44 * struct tipc_node_map - set of node identifiers
45 * @count: # of nodes in set 45 * @count: # of nodes in set
46 * @map: bitmap of node identifiers that are in the set 46 * @map: bitmap of node identifiers that are in the set
47 */ 47 */
48 48
49struct node_map { 49struct tipc_node_map {
50 u32 count; 50 u32 count;
51 u32 map[MAX_NODES / WSIZE]; 51 u32 map[MAX_NODES / WSIZE];
52}; 52};
@@ -68,7 +68,7 @@ struct port_list {
68}; 68};
69 69
70 70
71struct node; 71struct tipc_node;
72 72
73extern char tipc_bclink_name[]; 73extern char tipc_bclink_name[];
74 74
@@ -77,7 +77,7 @@ extern char tipc_bclink_name[];
77 * nmap_add - add a node to a node map 77 * nmap_add - add a node to a node map
78 */ 78 */
79 79
80static inline void tipc_nmap_add(struct node_map *nm_ptr, u32 node) 80static inline void tipc_nmap_add(struct tipc_node_map *nm_ptr, u32 node)
81{ 81{
82 int n = tipc_node(node); 82 int n = tipc_node(node);
83 int w = n / WSIZE; 83 int w = n / WSIZE;
@@ -93,7 +93,7 @@ static inline void tipc_nmap_add(struct node_map *nm_ptr, u32 node)
93 * nmap_remove - remove a node from a node map 93 * nmap_remove - remove a node from a node map
94 */ 94 */
95 95
96static inline void tipc_nmap_remove(struct node_map *nm_ptr, u32 node) 96static inline void tipc_nmap_remove(struct tipc_node_map *nm_ptr, u32 node)
97{ 97{
98 int n = tipc_node(node); 98 int n = tipc_node(node);
99 int w = n / WSIZE; 99 int w = n / WSIZE;
@@ -109,7 +109,7 @@ static inline void tipc_nmap_remove(struct node_map *nm_ptr, u32 node)
109 * nmap_equal - test for equality of node maps 109 * nmap_equal - test for equality of node maps
110 */ 110 */
111 111
112static inline int tipc_nmap_equal(struct node_map *nm_a, struct node_map *nm_b) 112static inline int tipc_nmap_equal(struct tipc_node_map *nm_a, struct tipc_node_map *nm_b)
113{ 113{
114 return !memcmp(nm_a, nm_b, sizeof(*nm_a)); 114 return !memcmp(nm_a, nm_b, sizeof(*nm_a));
115} 115}
@@ -121,8 +121,8 @@ static inline int tipc_nmap_equal(struct node_map *nm_a, struct node_map *nm_b)
121 * @nm_diff: output node map A-B (i.e. nodes of A that are not in B) 121 * @nm_diff: output node map A-B (i.e. nodes of A that are not in B)
122 */ 122 */
123 123
124static inline void tipc_nmap_diff(struct node_map *nm_a, struct node_map *nm_b, 124static inline void tipc_nmap_diff(struct tipc_node_map *nm_a, struct tipc_node_map *nm_b,
125 struct node_map *nm_diff) 125 struct tipc_node_map *nm_diff)
126{ 126{
127 int stop = sizeof(nm_a->map) / sizeof(u32); 127 int stop = sizeof(nm_a->map) / sizeof(u32);
128 int w; 128 int w;
@@ -195,12 +195,12 @@ static inline void tipc_port_list_free(struct port_list *pl_ptr)
195 195
196int tipc_bclink_init(void); 196int tipc_bclink_init(void);
197void tipc_bclink_stop(void); 197void tipc_bclink_stop(void);
198void tipc_bclink_acknowledge(struct node *n_ptr, u32 acked); 198void tipc_bclink_acknowledge(struct tipc_node *n_ptr, u32 acked);
199int tipc_bclink_send_msg(struct sk_buff *buf); 199int tipc_bclink_send_msg(struct sk_buff *buf);
200void tipc_bclink_recv_pkt(struct sk_buff *buf); 200void tipc_bclink_recv_pkt(struct sk_buff *buf);
201u32 tipc_bclink_get_last_sent(void); 201u32 tipc_bclink_get_last_sent(void);
202u32 tipc_bclink_acks_missing(struct node *n_ptr); 202u32 tipc_bclink_acks_missing(struct tipc_node *n_ptr);
203void tipc_bclink_check_gap(struct node *n_ptr, u32 seqno); 203void tipc_bclink_check_gap(struct tipc_node *n_ptr, u32 seqno);
204int tipc_bclink_stats(char *stats_buf, const u32 buf_size); 204int tipc_bclink_stats(char *stats_buf, const u32 buf_size);
205int tipc_bclink_reset_stats(void); 205int tipc_bclink_reset_stats(void);
206int tipc_bclink_set_queue_limits(u32 limit); 206int tipc_bclink_set_queue_limits(u32 limit);
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 6a9aba3edd08..a7a36779b9b3 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -599,7 +599,7 @@ int tipc_block_bearer(const char *name)
599 spin_lock_bh(&b_ptr->publ.lock); 599 spin_lock_bh(&b_ptr->publ.lock);
600 b_ptr->publ.blocked = 1; 600 b_ptr->publ.blocked = 1;
601 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) { 601 list_for_each_entry_safe(l_ptr, temp_l_ptr, &b_ptr->links, link_list) {
602 struct node *n_ptr = l_ptr->owner; 602 struct tipc_node *n_ptr = l_ptr->owner;
603 603
604 spin_lock_bh(&n_ptr->lock); 604 spin_lock_bh(&n_ptr->lock);
605 tipc_link_reset(l_ptr); 605 tipc_link_reset(l_ptr);
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index 6a36b6600e6c..ca5734892713 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -104,7 +104,7 @@ struct bearer {
104 u32 continue_count; 104 u32 continue_count;
105 int active; 105 int active;
106 char net_plane; 106 char net_plane;
107 struct node_map nodes; 107 struct tipc_node_map nodes;
108}; 108};
109 109
110struct bearer_name { 110struct bearer_name {
diff --git a/net/tipc/cluster.c b/net/tipc/cluster.c
index 46ee6c58532d..689fdefe9d04 100644
--- a/net/tipc/cluster.c
+++ b/net/tipc/cluster.c
@@ -48,8 +48,8 @@ static void tipc_cltr_multicast(struct cluster *c_ptr, struct sk_buff *buf,
48 u32 lower, u32 upper); 48 u32 lower, u32 upper);
49static struct sk_buff *tipc_cltr_prepare_routing_msg(u32 data_size, u32 dest); 49static struct sk_buff *tipc_cltr_prepare_routing_msg(u32 data_size, u32 dest);
50 50
51struct node **tipc_local_nodes = NULL; 51struct tipc_node **tipc_local_nodes = NULL;
52struct node_map tipc_cltr_bcast_nodes = {0,{0,}}; 52struct tipc_node_map tipc_cltr_bcast_nodes = {0,{0,}};
53u32 tipc_highest_allowed_slave = 0; 53u32 tipc_highest_allowed_slave = 0;
54 54
55struct cluster *tipc_cltr_create(u32 addr) 55struct cluster *tipc_cltr_create(u32 addr)
@@ -115,7 +115,7 @@ void tipc_cltr_delete(struct cluster *c_ptr)
115 115
116u32 tipc_cltr_next_node(struct cluster *c_ptr, u32 addr) 116u32 tipc_cltr_next_node(struct cluster *c_ptr, u32 addr)
117{ 117{
118 struct node *n_ptr; 118 struct tipc_node *n_ptr;
119 u32 n_num = tipc_node(addr) + 1; 119 u32 n_num = tipc_node(addr) + 1;
120 120
121 if (!c_ptr) 121 if (!c_ptr)
@@ -133,7 +133,7 @@ u32 tipc_cltr_next_node(struct cluster *c_ptr, u32 addr)
133 return 0; 133 return 0;
134} 134}
135 135
136void tipc_cltr_attach_node(struct cluster *c_ptr, struct node *n_ptr) 136void tipc_cltr_attach_node(struct cluster *c_ptr, struct tipc_node *n_ptr)
137{ 137{
138 u32 n_num = tipc_node(n_ptr->addr); 138 u32 n_num = tipc_node(n_ptr->addr);
139 u32 max_n_num = tipc_max_nodes; 139 u32 max_n_num = tipc_max_nodes;
@@ -196,7 +196,7 @@ u32 tipc_cltr_select_router(struct cluster *c_ptr, u32 ref)
196 * Uses deterministic and fair algorithm. 196 * Uses deterministic and fair algorithm.
197 */ 197 */
198 198
199struct node *tipc_cltr_select_node(struct cluster *c_ptr, u32 selector) 199struct tipc_node *tipc_cltr_select_node(struct cluster *c_ptr, u32 selector)
200{ 200{
201 u32 n_num; 201 u32 n_num;
202 u32 mask = tipc_max_nodes; 202 u32 mask = tipc_max_nodes;
@@ -379,7 +379,7 @@ void tipc_cltr_recv_routing_table(struct sk_buff *buf)
379{ 379{
380 struct tipc_msg *msg = buf_msg(buf); 380 struct tipc_msg *msg = buf_msg(buf);
381 struct cluster *c_ptr; 381 struct cluster *c_ptr;
382 struct node *n_ptr; 382 struct tipc_node *n_ptr;
383 unchar *node_table; 383 unchar *node_table;
384 u32 table_size; 384 u32 table_size;
385 u32 router; 385 u32 router;
@@ -499,7 +499,7 @@ static void tipc_cltr_multicast(struct cluster *c_ptr, struct sk_buff *buf,
499 u32 lower, u32 upper) 499 u32 lower, u32 upper)
500{ 500{
501 struct sk_buff *buf_copy; 501 struct sk_buff *buf_copy;
502 struct node *n_ptr; 502 struct tipc_node *n_ptr;
503 u32 n_num; 503 u32 n_num;
504 u32 tstop; 504 u32 tstop;
505 505
@@ -534,7 +534,7 @@ void tipc_cltr_broadcast(struct sk_buff *buf)
534{ 534{
535 struct sk_buff *buf_copy; 535 struct sk_buff *buf_copy;
536 struct cluster *c_ptr; 536 struct cluster *c_ptr;
537 struct node *n_ptr; 537 struct tipc_node *n_ptr;
538 u32 n_num; 538 u32 n_num;
539 u32 tstart; 539 u32 tstart;
540 u32 tstop; 540 u32 tstop;
diff --git a/net/tipc/cluster.h b/net/tipc/cluster.h
index 62df074afaec..333efb0b9c44 100644
--- a/net/tipc/cluster.h
+++ b/net/tipc/cluster.h
@@ -54,24 +54,24 @@
54struct cluster { 54struct cluster {
55 u32 addr; 55 u32 addr;
56 struct _zone *owner; 56 struct _zone *owner;
57 struct node **nodes; 57 struct tipc_node **nodes;
58 u32 highest_node; 58 u32 highest_node;
59 u32 highest_slave; 59 u32 highest_slave;
60}; 60};
61 61
62 62
63extern struct node **tipc_local_nodes; 63extern struct tipc_node **tipc_local_nodes;
64extern u32 tipc_highest_allowed_slave; 64extern u32 tipc_highest_allowed_slave;
65extern struct node_map tipc_cltr_bcast_nodes; 65extern struct tipc_node_map tipc_cltr_bcast_nodes;
66 66
67void tipc_cltr_remove_as_router(struct cluster *c_ptr, u32 router); 67void tipc_cltr_remove_as_router(struct cluster *c_ptr, u32 router);
68void tipc_cltr_send_ext_routes(struct cluster *c_ptr, u32 dest); 68void tipc_cltr_send_ext_routes(struct cluster *c_ptr, u32 dest);
69struct node *tipc_cltr_select_node(struct cluster *c_ptr, u32 selector); 69struct tipc_node *tipc_cltr_select_node(struct cluster *c_ptr, u32 selector);
70u32 tipc_cltr_select_router(struct cluster *c_ptr, u32 ref); 70u32 tipc_cltr_select_router(struct cluster *c_ptr, u32 ref);
71void tipc_cltr_recv_routing_table(struct sk_buff *buf); 71void tipc_cltr_recv_routing_table(struct sk_buff *buf);
72struct cluster *tipc_cltr_create(u32 addr); 72struct cluster *tipc_cltr_create(u32 addr);
73void tipc_cltr_delete(struct cluster *c_ptr); 73void tipc_cltr_delete(struct cluster *c_ptr);
74void tipc_cltr_attach_node(struct cluster *c_ptr, struct node *n_ptr); 74void tipc_cltr_attach_node(struct cluster *c_ptr, struct tipc_node *n_ptr);
75void tipc_cltr_send_slave_routes(struct cluster *c_ptr, u32 dest); 75void tipc_cltr_send_slave_routes(struct cluster *c_ptr, u32 dest);
76void tipc_cltr_broadcast(struct sk_buff *buf); 76void tipc_cltr_broadcast(struct sk_buff *buf);
77int tipc_cltr_init(void); 77int tipc_cltr_init(void);
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index 1657f0e795ff..74b7d1e28aec 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -193,7 +193,7 @@ void tipc_disc_recv_msg(struct sk_buff *buf, struct bearer *b_ptr)
193 /* Always accept link here */ 193 /* Always accept link here */
194 struct sk_buff *rbuf; 194 struct sk_buff *rbuf;
195 struct tipc_media_addr *addr; 195 struct tipc_media_addr *addr;
196 struct node *n_ptr = tipc_node_find(orig); 196 struct tipc_node *n_ptr = tipc_node_find(orig);
197 int link_fully_up; 197 int link_fully_up;
198 198
199 dbg(" in own cluster\n"); 199 dbg(" in own cluster\n");
diff --git a/net/tipc/link.c b/net/tipc/link.c
index d60113ba4b1b..dd4c18b9a35b 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1155,7 +1155,7 @@ int tipc_link_send_buf(struct link *l_ptr, struct sk_buff *buf)
1155int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector) 1155int tipc_link_send(struct sk_buff *buf, u32 dest, u32 selector)
1156{ 1156{
1157 struct link *l_ptr; 1157 struct link *l_ptr;
1158 struct node *n_ptr; 1158 struct tipc_node *n_ptr;
1159 int res = -ELINKCONG; 1159 int res = -ELINKCONG;
1160 1160
1161 read_lock_bh(&tipc_net_lock); 1161 read_lock_bh(&tipc_net_lock);
@@ -1226,7 +1226,7 @@ static int link_send_buf_fast(struct link *l_ptr, struct sk_buff *buf,
1226int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode) 1226int tipc_send_buf_fast(struct sk_buff *buf, u32 destnode)
1227{ 1227{
1228 struct link *l_ptr; 1228 struct link *l_ptr;
1229 struct node *n_ptr; 1229 struct tipc_node *n_ptr;
1230 int res; 1230 int res;
1231 u32 selector = msg_origport(buf_msg(buf)) & 1; 1231 u32 selector = msg_origport(buf_msg(buf)) & 1;
1232 u32 dummy; 1232 u32 dummy;
@@ -1270,7 +1270,7 @@ int tipc_link_send_sections_fast(struct port *sender,
1270 struct tipc_msg *hdr = &sender->publ.phdr; 1270 struct tipc_msg *hdr = &sender->publ.phdr;
1271 struct link *l_ptr; 1271 struct link *l_ptr;
1272 struct sk_buff *buf; 1272 struct sk_buff *buf;
1273 struct node *node; 1273 struct tipc_node *node;
1274 int res; 1274 int res;
1275 u32 selector = msg_origport(hdr) & 1; 1275 u32 selector = msg_origport(hdr) & 1;
1276 1276
@@ -1364,7 +1364,7 @@ static int link_send_sections_long(struct port *sender,
1364 u32 destaddr) 1364 u32 destaddr)
1365{ 1365{
1366 struct link *l_ptr; 1366 struct link *l_ptr;
1367 struct node *node; 1367 struct tipc_node *node;
1368 struct tipc_msg *hdr = &sender->publ.phdr; 1368 struct tipc_msg *hdr = &sender->publ.phdr;
1369 u32 dsz = msg_data_sz(hdr); 1369 u32 dsz = msg_data_sz(hdr);
1370 u32 max_pkt,fragm_sz,rest; 1370 u32 max_pkt,fragm_sz,rest;
@@ -1636,7 +1636,7 @@ void tipc_link_push_queue(struct link *l_ptr)
1636 1636
1637static void link_reset_all(unsigned long addr) 1637static void link_reset_all(unsigned long addr)
1638{ 1638{
1639 struct node *n_ptr; 1639 struct tipc_node *n_ptr;
1640 char addr_string[16]; 1640 char addr_string[16];
1641 u32 i; 1641 u32 i;
1642 1642
@@ -1682,7 +1682,7 @@ static void link_retransmit_failure(struct link *l_ptr, struct sk_buff *buf)
1682 1682
1683 /* Handle failure on broadcast link */ 1683 /* Handle failure on broadcast link */
1684 1684
1685 struct node *n_ptr; 1685 struct tipc_node *n_ptr;
1686 char addr_string[16]; 1686 char addr_string[16];
1687 1687
1688 tipc_printf(TIPC_OUTPUT, "Msg seq number: %u, ", msg_seqno(msg)); 1688 tipc_printf(TIPC_OUTPUT, "Msg seq number: %u, ", msg_seqno(msg));
@@ -1843,7 +1843,7 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr)
1843 read_lock_bh(&tipc_net_lock); 1843 read_lock_bh(&tipc_net_lock);
1844 while (head) { 1844 while (head) {
1845 struct bearer *b_ptr = (struct bearer *)tb_ptr; 1845 struct bearer *b_ptr = (struct bearer *)tb_ptr;
1846 struct node *n_ptr; 1846 struct tipc_node *n_ptr;
1847 struct link *l_ptr; 1847 struct link *l_ptr;
1848 struct sk_buff *crs; 1848 struct sk_buff *crs;
1849 struct sk_buff *buf = head; 1849 struct sk_buff *buf = head;
@@ -2935,7 +2935,7 @@ void tipc_link_set_queue_limits(struct link *l_ptr, u32 window)
2935 * Returns pointer to link (or 0 if invalid link name). 2935 * Returns pointer to link (or 0 if invalid link name).
2936 */ 2936 */
2937 2937
2938static struct link *link_find_link(const char *name, struct node **node) 2938static struct link *link_find_link(const char *name, struct tipc_node **node)
2939{ 2939{
2940 struct link_name link_name_parts; 2940 struct link_name link_name_parts;
2941 struct bearer *b_ptr; 2941 struct bearer *b_ptr;
@@ -2965,7 +2965,7 @@ struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area, int req_tlv_space
2965 struct tipc_link_config *args; 2965 struct tipc_link_config *args;
2966 u32 new_value; 2966 u32 new_value;
2967 struct link *l_ptr; 2967 struct link *l_ptr;
2968 struct node *node; 2968 struct tipc_node *node;
2969 int res; 2969 int res;
2970 2970
2971 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_CONFIG)) 2971 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_CONFIG))
@@ -3043,7 +3043,7 @@ struct sk_buff *tipc_link_cmd_reset_stats(const void *req_tlv_area, int req_tlv_
3043{ 3043{
3044 char *link_name; 3044 char *link_name;
3045 struct link *l_ptr; 3045 struct link *l_ptr;
3046 struct node *node; 3046 struct tipc_node *node;
3047 3047
3048 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_NAME)) 3048 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_LINK_NAME))
3049 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 3049 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
@@ -3091,7 +3091,7 @@ static int tipc_link_stats(const char *name, char *buf, const u32 buf_size)
3091{ 3091{
3092 struct print_buf pb; 3092 struct print_buf pb;
3093 struct link *l_ptr; 3093 struct link *l_ptr;
3094 struct node *node; 3094 struct tipc_node *node;
3095 char *status; 3095 char *status;
3096 u32 profile_total = 0; 3096 u32 profile_total = 0;
3097 3097
@@ -3207,7 +3207,7 @@ int link_control(const char *name, u32 op, u32 val)
3207 int res = -EINVAL; 3207 int res = -EINVAL;
3208 struct link *l_ptr; 3208 struct link *l_ptr;
3209 u32 bearer_id; 3209 u32 bearer_id;
3210 struct node * node; 3210 struct tipc_node * node;
3211 u32 a; 3211 u32 a;
3212 3212
3213 a = link_name2addr(name, &bearer_id); 3213 a = link_name2addr(name, &bearer_id);
@@ -3249,7 +3249,7 @@ int link_control(const char *name, u32 op, u32 val)
3249 3249
3250u32 tipc_link_get_max_pkt(u32 dest, u32 selector) 3250u32 tipc_link_get_max_pkt(u32 dest, u32 selector)
3251{ 3251{
3252 struct node *n_ptr; 3252 struct tipc_node *n_ptr;
3253 struct link *l_ptr; 3253 struct link *l_ptr;
3254 u32 res = MAX_PKT_DEFAULT; 3254 u32 res = MAX_PKT_DEFAULT;
3255 3255
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 52f3e7c1871f..6a51e38ad25c 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -116,7 +116,7 @@ struct link {
116 char name[TIPC_MAX_LINK_NAME]; 116 char name[TIPC_MAX_LINK_NAME];
117 struct tipc_media_addr media_addr; 117 struct tipc_media_addr media_addr;
118 struct timer_list timer; 118 struct timer_list timer;
119 struct node *owner; 119 struct tipc_node *owner;
120 struct list_head link_list; 120 struct list_head link_list;
121 121
122 /* Management and link supervision data */ 122 /* Management and link supervision data */
diff --git a/net/tipc/name_table.h b/net/tipc/name_table.h
index b9e7cd336d76..139882d4ed00 100644
--- a/net/tipc/name_table.h
+++ b/net/tipc/name_table.h
@@ -76,7 +76,7 @@ struct publication {
76 u32 node; 76 u32 node;
77 u32 ref; 77 u32 ref;
78 u32 key; 78 u32 key;
79 struct node_subscr subscr; 79 struct tipc_node_subscr subscr;
80 struct list_head local_list; 80 struct list_head local_list;
81 struct list_head pport_list; 81 struct list_head pport_list;
82 struct publication *node_list_next; 82 struct publication *node_list_next;
diff --git a/net/tipc/net.c b/net/tipc/net.c
index ec7b04fbdc43..7906608bf510 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -118,7 +118,7 @@
118DEFINE_RWLOCK(tipc_net_lock); 118DEFINE_RWLOCK(tipc_net_lock);
119struct network tipc_net = { NULL }; 119struct network tipc_net = { NULL };
120 120
121struct node *tipc_net_select_remote_node(u32 addr, u32 ref) 121struct tipc_node *tipc_net_select_remote_node(u32 addr, u32 ref)
122{ 122{
123 return tipc_zone_select_remote_node(tipc_net.zones[tipc_zone(addr)], addr, ref); 123 return tipc_zone_select_remote_node(tipc_net.zones[tipc_zone(addr)], addr, ref);
124} 124}
diff --git a/net/tipc/net.h b/net/tipc/net.h
index d154ac2bda9a..de2b9ad8f646 100644
--- a/net/tipc/net.h
+++ b/net/tipc/net.h
@@ -55,7 +55,7 @@ extern rwlock_t tipc_net_lock;
55void tipc_net_remove_as_router(u32 router); 55void tipc_net_remove_as_router(u32 router);
56void tipc_net_send_external_routes(u32 dest); 56void tipc_net_send_external_routes(u32 dest);
57void tipc_net_route_msg(struct sk_buff *buf); 57void tipc_net_route_msg(struct sk_buff *buf);
58struct node *tipc_net_select_remote_node(u32 addr, u32 ref); 58struct tipc_node *tipc_net_select_remote_node(u32 addr, u32 ref);
59u32 tipc_net_select_router(u32 addr, u32 ref); 59u32 tipc_net_select_router(u32 addr, u32 ref);
60 60
61int tipc_net_start(u32 addr); 61int tipc_net_start(u32 addr);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index ee952ad60218..20d98c56e152 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -46,11 +46,11 @@
46#include "bearer.h" 46#include "bearer.h"
47#include "name_distr.h" 47#include "name_distr.h"
48 48
49void node_print(struct print_buf *buf, struct node *n_ptr, char *str); 49void node_print(struct print_buf *buf, struct tipc_node *n_ptr, char *str);
50static void node_lost_contact(struct node *n_ptr); 50static void node_lost_contact(struct tipc_node *n_ptr);
51static void node_established_contact(struct node *n_ptr); 51static void node_established_contact(struct tipc_node *n_ptr);
52 52
53struct node *tipc_nodes = NULL; /* sorted list of nodes within cluster */ 53struct tipc_node *tipc_nodes = NULL; /* sorted list of nodes within cluster */
54 54
55static DEFINE_SPINLOCK(node_create_lock); 55static DEFINE_SPINLOCK(node_create_lock);
56 56
@@ -66,11 +66,11 @@ u32 tipc_own_tag = 0;
66 * but this is a non-trivial change.) 66 * but this is a non-trivial change.)
67 */ 67 */
68 68
69struct node *tipc_node_create(u32 addr) 69struct tipc_node *tipc_node_create(u32 addr)
70{ 70{
71 struct cluster *c_ptr; 71 struct cluster *c_ptr;
72 struct node *n_ptr; 72 struct tipc_node *n_ptr;
73 struct node **curr_node; 73 struct tipc_node **curr_node;
74 74
75 spin_lock_bh(&node_create_lock); 75 spin_lock_bh(&node_create_lock);
76 76
@@ -120,7 +120,7 @@ struct node *tipc_node_create(u32 addr)
120 return n_ptr; 120 return n_ptr;
121} 121}
122 122
123void tipc_node_delete(struct node *n_ptr) 123void tipc_node_delete(struct tipc_node *n_ptr)
124{ 124{
125 if (!n_ptr) 125 if (!n_ptr)
126 return; 126 return;
@@ -146,7 +146,7 @@ void tipc_node_delete(struct node *n_ptr)
146 * Link becomes active (alone or shared) or standby, depending on its priority. 146 * Link becomes active (alone or shared) or standby, depending on its priority.
147 */ 147 */
148 148
149void tipc_node_link_up(struct node *n_ptr, struct link *l_ptr) 149void tipc_node_link_up(struct tipc_node *n_ptr, struct link *l_ptr)
150{ 150{
151 struct link **active = &n_ptr->active_links[0]; 151 struct link **active = &n_ptr->active_links[0];
152 152
@@ -180,7 +180,7 @@ void tipc_node_link_up(struct node *n_ptr, struct link *l_ptr)
180 * node_select_active_links - select active link 180 * node_select_active_links - select active link
181 */ 181 */
182 182
183static void node_select_active_links(struct node *n_ptr) 183static void node_select_active_links(struct tipc_node *n_ptr)
184{ 184{
185 struct link **active = &n_ptr->active_links[0]; 185 struct link **active = &n_ptr->active_links[0];
186 u32 i; 186 u32 i;
@@ -208,7 +208,7 @@ static void node_select_active_links(struct node *n_ptr)
208 * tipc_node_link_down - handle loss of link 208 * tipc_node_link_down - handle loss of link
209 */ 209 */
210 210
211void tipc_node_link_down(struct node *n_ptr, struct link *l_ptr) 211void tipc_node_link_down(struct tipc_node *n_ptr, struct link *l_ptr)
212{ 212{
213 struct link **active; 213 struct link **active;
214 214
@@ -235,30 +235,30 @@ void tipc_node_link_down(struct node *n_ptr, struct link *l_ptr)
235 node_lost_contact(n_ptr); 235 node_lost_contact(n_ptr);
236} 236}
237 237
238int tipc_node_has_active_links(struct node *n_ptr) 238int tipc_node_has_active_links(struct tipc_node *n_ptr)
239{ 239{
240 return (n_ptr && 240 return (n_ptr &&
241 ((n_ptr->active_links[0]) || (n_ptr->active_links[1]))); 241 ((n_ptr->active_links[0]) || (n_ptr->active_links[1])));
242} 242}
243 243
244int tipc_node_has_redundant_links(struct node *n_ptr) 244int tipc_node_has_redundant_links(struct tipc_node *n_ptr)
245{ 245{
246 return (n_ptr->working_links > 1); 246 return (n_ptr->working_links > 1);
247} 247}
248 248
249static int tipc_node_has_active_routes(struct node *n_ptr) 249static int tipc_node_has_active_routes(struct tipc_node *n_ptr)
250{ 250{
251 return (n_ptr && (n_ptr->last_router >= 0)); 251 return (n_ptr && (n_ptr->last_router >= 0));
252} 252}
253 253
254int tipc_node_is_up(struct node *n_ptr) 254int tipc_node_is_up(struct tipc_node *n_ptr)
255{ 255{
256 return (tipc_node_has_active_links(n_ptr) || tipc_node_has_active_routes(n_ptr)); 256 return (tipc_node_has_active_links(n_ptr) || tipc_node_has_active_routes(n_ptr));
257} 257}
258 258
259struct node *tipc_node_attach_link(struct link *l_ptr) 259struct tipc_node *tipc_node_attach_link(struct link *l_ptr)
260{ 260{
261 struct node *n_ptr = tipc_node_find(l_ptr->addr); 261 struct tipc_node *n_ptr = tipc_node_find(l_ptr->addr);
262 262
263 if (!n_ptr) 263 if (!n_ptr)
264 n_ptr = tipc_node_create(l_ptr->addr); 264 n_ptr = tipc_node_create(l_ptr->addr);
@@ -285,7 +285,7 @@ struct node *tipc_node_attach_link(struct link *l_ptr)
285 return NULL; 285 return NULL;
286} 286}
287 287
288void tipc_node_detach_link(struct node *n_ptr, struct link *l_ptr) 288void tipc_node_detach_link(struct tipc_node *n_ptr, struct link *l_ptr)
289{ 289{
290 n_ptr->links[l_ptr->b_ptr->identity] = NULL; 290 n_ptr->links[l_ptr->b_ptr->identity] = NULL;
291 tipc_net.zones[tipc_zone(l_ptr->addr)]->links--; 291 tipc_net.zones[tipc_zone(l_ptr->addr)]->links--;
@@ -338,7 +338,7 @@ void tipc_node_detach_link(struct node *n_ptr, struct link *l_ptr)
338 * 338 *
339 */ 339 */
340 340
341static void node_established_contact(struct node *n_ptr) 341static void node_established_contact(struct tipc_node *n_ptr)
342{ 342{
343 struct cluster *c_ptr; 343 struct cluster *c_ptr;
344 344
@@ -384,10 +384,10 @@ static void node_established_contact(struct node *n_ptr)
384 tipc_highest_allowed_slave); 384 tipc_highest_allowed_slave);
385} 385}
386 386
387static void node_lost_contact(struct node *n_ptr) 387static void node_lost_contact(struct tipc_node *n_ptr)
388{ 388{
389 struct cluster *c_ptr; 389 struct cluster *c_ptr;
390 struct node_subscr *ns, *tns; 390 struct tipc_node_subscr *ns, *tns;
391 char addr_string[16]; 391 char addr_string[16];
392 u32 i; 392 u32 i;
393 393
@@ -466,9 +466,9 @@ static void node_lost_contact(struct node *n_ptr)
466 * Called by when cluster local lookup has failed. 466 * Called by when cluster local lookup has failed.
467 */ 467 */
468 468
469struct node *tipc_node_select_next_hop(u32 addr, u32 selector) 469struct tipc_node *tipc_node_select_next_hop(u32 addr, u32 selector)
470{ 470{
471 struct node *n_ptr; 471 struct tipc_node *n_ptr;
472 u32 router_addr; 472 u32 router_addr;
473 473
474 if (!tipc_addr_domain_valid(addr)) 474 if (!tipc_addr_domain_valid(addr))
@@ -513,7 +513,7 @@ struct node *tipc_node_select_next_hop(u32 addr, u32 selector)
513 * Uses a deterministic and fair algorithm for selecting router node. 513 * Uses a deterministic and fair algorithm for selecting router node.
514 */ 514 */
515 515
516u32 tipc_node_select_router(struct node *n_ptr, u32 ref) 516u32 tipc_node_select_router(struct tipc_node *n_ptr, u32 ref)
517{ 517{
518 u32 ulim; 518 u32 ulim;
519 u32 mask; 519 u32 mask;
@@ -551,7 +551,7 @@ u32 tipc_node_select_router(struct node *n_ptr, u32 ref)
551 return tipc_addr(own_zone(), own_cluster(), r); 551 return tipc_addr(own_zone(), own_cluster(), r);
552} 552}
553 553
554void tipc_node_add_router(struct node *n_ptr, u32 router) 554void tipc_node_add_router(struct tipc_node *n_ptr, u32 router)
555{ 555{
556 u32 r_num = tipc_node(router); 556 u32 r_num = tipc_node(router);
557 557
@@ -562,7 +562,7 @@ void tipc_node_add_router(struct node *n_ptr, u32 router)
562 !n_ptr->routers[n_ptr->last_router]); 562 !n_ptr->routers[n_ptr->last_router]);
563} 563}
564 564
565void tipc_node_remove_router(struct node *n_ptr, u32 router) 565void tipc_node_remove_router(struct tipc_node *n_ptr, u32 router)
566{ 566{
567 u32 r_num = tipc_node(router); 567 u32 r_num = tipc_node(router);
568 568
@@ -580,7 +580,7 @@ void tipc_node_remove_router(struct node *n_ptr, u32 router)
580} 580}
581 581
582#if 0 582#if 0
583void node_print(struct print_buf *buf, struct node *n_ptr, char *str) 583void node_print(struct print_buf *buf, struct tipc_node *n_ptr, char *str)
584{ 584{
585 u32 i; 585 u32 i;
586 586
@@ -597,7 +597,7 @@ void node_print(struct print_buf *buf, struct node *n_ptr, char *str)
597 597
598u32 tipc_available_nodes(const u32 domain) 598u32 tipc_available_nodes(const u32 domain)
599{ 599{
600 struct node *n_ptr; 600 struct tipc_node *n_ptr;
601 u32 cnt = 0; 601 u32 cnt = 0;
602 602
603 read_lock_bh(&tipc_net_lock); 603 read_lock_bh(&tipc_net_lock);
@@ -615,7 +615,7 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
615{ 615{
616 u32 domain; 616 u32 domain;
617 struct sk_buff *buf; 617 struct sk_buff *buf;
618 struct node *n_ptr; 618 struct tipc_node *n_ptr;
619 struct tipc_node_info node_info; 619 struct tipc_node_info node_info;
620 u32 payload_size; 620 u32 payload_size;
621 621
@@ -667,7 +667,7 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
667{ 667{
668 u32 domain; 668 u32 domain;
669 struct sk_buff *buf; 669 struct sk_buff *buf;
670 struct node *n_ptr; 670 struct tipc_node *n_ptr;
671 struct tipc_link_info link_info; 671 struct tipc_link_info link_info;
672 u32 payload_size; 672 u32 payload_size;
673 673
diff --git a/net/tipc/node.h b/net/tipc/node.h
index cd1882654bbb..6f990da5d143 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -43,7 +43,7 @@
43#include "bearer.h" 43#include "bearer.h"
44 44
45/** 45/**
46 * struct node - TIPC node structure 46 * struct tipc_node - TIPC node structure
47 * @addr: network address of node 47 * @addr: network address of node
48 * @lock: spinlock governing access to structure 48 * @lock: spinlock governing access to structure
49 * @owner: pointer to cluster that node belongs to 49 * @owner: pointer to cluster that node belongs to
@@ -68,11 +68,11 @@
68 * @defragm: list of partially reassembled b'cast message fragments from node 68 * @defragm: list of partially reassembled b'cast message fragments from node
69 */ 69 */
70 70
71struct node { 71struct tipc_node {
72 u32 addr; 72 u32 addr;
73 spinlock_t lock; 73 spinlock_t lock;
74 struct cluster *owner; 74 struct cluster *owner;
75 struct node *next; 75 struct tipc_node *next;
76 struct list_head nsub; 76 struct list_head nsub;
77 struct link *active_links[2]; 77 struct link *active_links[2];
78 struct link *links[MAX_BEARERS]; 78 struct link *links[MAX_BEARERS];
@@ -94,26 +94,26 @@ struct node {
94 } bclink; 94 } bclink;
95}; 95};
96 96
97extern struct node *tipc_nodes; 97extern struct tipc_node *tipc_nodes;
98extern u32 tipc_own_tag; 98extern u32 tipc_own_tag;
99 99
100struct node *tipc_node_create(u32 addr); 100struct tipc_node *tipc_node_create(u32 addr);
101void tipc_node_delete(struct node *n_ptr); 101void tipc_node_delete(struct tipc_node *n_ptr);
102struct node *tipc_node_attach_link(struct link *l_ptr); 102struct tipc_node *tipc_node_attach_link(struct link *l_ptr);
103void tipc_node_detach_link(struct node *n_ptr, struct link *l_ptr); 103void tipc_node_detach_link(struct tipc_node *n_ptr, struct link *l_ptr);
104void tipc_node_link_down(struct node *n_ptr, struct link *l_ptr); 104void tipc_node_link_down(struct tipc_node *n_ptr, struct link *l_ptr);
105void tipc_node_link_up(struct node *n_ptr, struct link *l_ptr); 105void tipc_node_link_up(struct tipc_node *n_ptr, struct link *l_ptr);
106int tipc_node_has_active_links(struct node *n_ptr); 106int tipc_node_has_active_links(struct tipc_node *n_ptr);
107int tipc_node_has_redundant_links(struct node *n_ptr); 107int tipc_node_has_redundant_links(struct tipc_node *n_ptr);
108u32 tipc_node_select_router(struct node *n_ptr, u32 ref); 108u32 tipc_node_select_router(struct tipc_node *n_ptr, u32 ref);
109struct node *tipc_node_select_next_hop(u32 addr, u32 selector); 109struct tipc_node *tipc_node_select_next_hop(u32 addr, u32 selector);
110int tipc_node_is_up(struct node *n_ptr); 110int tipc_node_is_up(struct tipc_node *n_ptr);
111void tipc_node_add_router(struct node *n_ptr, u32 router); 111void tipc_node_add_router(struct tipc_node *n_ptr, u32 router);
112void tipc_node_remove_router(struct node *n_ptr, u32 router); 112void tipc_node_remove_router(struct tipc_node *n_ptr, u32 router);
113struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space); 113struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space);
114struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space); 114struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space);
115 115
116static inline struct node *tipc_node_find(u32 addr) 116static inline struct tipc_node *tipc_node_find(u32 addr)
117{ 117{
118 if (likely(in_own_cluster(addr))) 118 if (likely(in_own_cluster(addr)))
119 return tipc_local_nodes[tipc_node(addr)]; 119 return tipc_local_nodes[tipc_node(addr)];
@@ -126,19 +126,19 @@ static inline struct node *tipc_node_find(u32 addr)
126 return NULL; 126 return NULL;
127} 127}
128 128
129static inline struct node *tipc_node_select(u32 addr, u32 selector) 129static inline struct tipc_node *tipc_node_select(u32 addr, u32 selector)
130{ 130{
131 if (likely(in_own_cluster(addr))) 131 if (likely(in_own_cluster(addr)))
132 return tipc_local_nodes[tipc_node(addr)]; 132 return tipc_local_nodes[tipc_node(addr)];
133 return tipc_node_select_next_hop(addr, selector); 133 return tipc_node_select_next_hop(addr, selector);
134} 134}
135 135
136static inline void tipc_node_lock(struct node *n_ptr) 136static inline void tipc_node_lock(struct tipc_node *n_ptr)
137{ 137{
138 spin_lock_bh(&n_ptr->lock); 138 spin_lock_bh(&n_ptr->lock);
139} 139}
140 140
141static inline void tipc_node_unlock(struct node *n_ptr) 141static inline void tipc_node_unlock(struct tipc_node *n_ptr)
142{ 142{
143 spin_unlock_bh(&n_ptr->lock); 143 spin_unlock_bh(&n_ptr->lock);
144} 144}
diff --git a/net/tipc/node_subscr.c b/net/tipc/node_subscr.c
index 8ecbd0fb6103..19194d476a9e 100644
--- a/net/tipc/node_subscr.c
+++ b/net/tipc/node_subscr.c
@@ -44,7 +44,7 @@
44 * tipc_nodesub_subscribe - create "node down" subscription for specified node 44 * tipc_nodesub_subscribe - create "node down" subscription for specified node
45 */ 45 */
46 46
47void tipc_nodesub_subscribe(struct node_subscr *node_sub, u32 addr, 47void tipc_nodesub_subscribe(struct tipc_node_subscr *node_sub, u32 addr,
48 void *usr_handle, net_ev_handler handle_down) 48 void *usr_handle, net_ev_handler handle_down)
49{ 49{
50 if (addr == tipc_own_addr) { 50 if (addr == tipc_own_addr) {
@@ -69,7 +69,7 @@ void tipc_nodesub_subscribe(struct node_subscr *node_sub, u32 addr,
69 * tipc_nodesub_unsubscribe - cancel "node down" subscription (if any) 69 * tipc_nodesub_unsubscribe - cancel "node down" subscription (if any)
70 */ 70 */
71 71
72void tipc_nodesub_unsubscribe(struct node_subscr *node_sub) 72void tipc_nodesub_unsubscribe(struct tipc_node_subscr *node_sub)
73{ 73{
74 if (!node_sub->node) 74 if (!node_sub->node)
75 return; 75 return;
diff --git a/net/tipc/node_subscr.h b/net/tipc/node_subscr.h
index 5f3f5859b84c..006ed739f515 100644
--- a/net/tipc/node_subscr.h
+++ b/net/tipc/node_subscr.h
@@ -42,22 +42,22 @@
42typedef void (*net_ev_handler) (void *usr_handle); 42typedef void (*net_ev_handler) (void *usr_handle);
43 43
44/** 44/**
45 * struct node_subscr - "node down" subscription entry 45 * struct tipc_node_subscr - "node down" subscription entry
46 * @node: ptr to node structure of interest (or NULL, if none) 46 * @node: ptr to node structure of interest (or NULL, if none)
47 * @handle_node_down: routine to invoke when node fails 47 * @handle_node_down: routine to invoke when node fails
48 * @usr_handle: argument to pass to routine when node fails 48 * @usr_handle: argument to pass to routine when node fails
49 * @nodesub_list: adjacent entries in list of subscriptions for the node 49 * @nodesub_list: adjacent entries in list of subscriptions for the node
50 */ 50 */
51 51
52struct node_subscr { 52struct tipc_node_subscr {
53 struct node *node; 53 struct tipc_node *node;
54 net_ev_handler handle_node_down; 54 net_ev_handler handle_node_down;
55 void *usr_handle; 55 void *usr_handle;
56 struct list_head nodesub_list; 56 struct list_head nodesub_list;
57}; 57};
58 58
59void tipc_nodesub_subscribe(struct node_subscr *node_sub, u32 addr, 59void tipc_nodesub_subscribe(struct tipc_node_subscr *node_sub, u32 addr,
60 void *usr_handle, net_ev_handler handle_down); 60 void *usr_handle, net_ev_handler handle_down);
61void tipc_nodesub_unsubscribe(struct node_subscr *node_sub); 61void tipc_nodesub_unsubscribe(struct tipc_node_subscr *node_sub);
62 62
63#endif 63#endif
diff --git a/net/tipc/port.h b/net/tipc/port.h
index e5f8c16429bd..ff31ee4a1dc3 100644
--- a/net/tipc/port.h
+++ b/net/tipc/port.h
@@ -105,7 +105,7 @@ struct port {
105 u32 probing_interval; 105 u32 probing_interval;
106 u32 last_in_seqno; 106 u32 last_in_seqno;
107 struct timer_list timer; 107 struct timer_list timer;
108 struct node_subscr subscription; 108 struct tipc_node_subscr subscription;
109}; 109};
110 110
111extern spinlock_t tipc_port_list_lock; 111extern spinlock_t tipc_port_list_lock;
diff --git a/net/tipc/zone.c b/net/tipc/zone.c
index 3506f8563441..2c01ba2d86bf 100644
--- a/net/tipc/zone.c
+++ b/net/tipc/zone.c
@@ -111,10 +111,10 @@ void tipc_zone_send_external_routes(struct _zone *z_ptr, u32 dest)
111 } 111 }
112} 112}
113 113
114struct node *tipc_zone_select_remote_node(struct _zone *z_ptr, u32 addr, u32 ref) 114struct tipc_node *tipc_zone_select_remote_node(struct _zone *z_ptr, u32 addr, u32 ref)
115{ 115{
116 struct cluster *c_ptr; 116 struct cluster *c_ptr;
117 struct node *n_ptr; 117 struct tipc_node *n_ptr;
118 u32 c_num; 118 u32 c_num;
119 119
120 if (!z_ptr) 120 if (!z_ptr)
diff --git a/net/tipc/zone.h b/net/tipc/zone.h
index 6e7a08df8af5..7bdc3406ba9b 100644
--- a/net/tipc/zone.h
+++ b/net/tipc/zone.h
@@ -54,7 +54,7 @@ struct _zone {
54 u32 links; 54 u32 links;
55}; 55};
56 56
57struct node *tipc_zone_select_remote_node(struct _zone *z_ptr, u32 addr, u32 ref); 57struct tipc_node *tipc_zone_select_remote_node(struct _zone *z_ptr, u32 addr, u32 ref);
58u32 tipc_zone_select_router(struct _zone *z_ptr, u32 addr, u32 ref); 58u32 tipc_zone_select_router(struct _zone *z_ptr, u32 addr, u32 ref);
59void tipc_zone_remove_as_router(struct _zone *z_ptr, u32 router); 59void tipc_zone_remove_as_router(struct _zone *z_ptr, u32 router);
60void tipc_zone_send_external_routes(struct _zone *z_ptr, u32 dest); 60void tipc_zone_send_external_routes(struct _zone *z_ptr, u32 dest);
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig
index ab015c62d561..7d82be07fa1d 100644
--- a/net/wireless/Kconfig
+++ b/net/wireless/Kconfig
@@ -14,6 +14,38 @@ config NL80211
14 14
15 If unsure, say Y. 15 If unsure, say Y.
16 16
17config WIRELESS_OLD_REGULATORY
18 bool "Old wireless static regulatory definitions"
19 default n
20 ---help---
21 This option enables the old static regulatory information
22 and uses it within the new framework. This is available
23 temporarily as an option to help prevent immediate issues
24 due to the switch to the new regulatory framework which
25 does require a new userspace application which has the
26 database of regulatory information (CRDA) and another for
27 setting regulatory domains (iw).
28
29 For more information see:
30
31 http://wireless.kernel.org/en/developers/Regulatory/CRDA
32 http://wireless.kernel.org/en/users/Documentation/iw
33
34 It is important to note though that if you *do* have CRDA present
35 and if this option is enabled CRDA *will* be called to update the
36 regulatory domain (for US and JP only). Support for letting the user
37 set the regulatory domain through iw is also supported. This option
38 mainly exists to leave around for a kernel release some old static
39 regulatory domains that were defined and to keep around the old
40 ieee80211_regdom module parameter. This is being phased out and you
41 should stop using them ASAP.
42
43 Say N unless you cannot install a new userspace application
44 or have one currently depending on the ieee80211_regdom module
45 parameter and cannot port it to use the new userspace interfaces.
46
47 This is scheduled for removal for 2.6.29.
48
17config WIRELESS_EXT 49config WIRELESS_EXT
18 bool "Wireless extensions" 50 bool "Wireless extensions"
19 default n 51 default n
@@ -39,4 +71,5 @@ config WIRELESS_EXT_SYSFS
39 files in /sys/class/net/*/wireless/. The same information 71 files in /sys/class/net/*/wireless/. The same information
40 is available via the ioctls as well. 72 is available via the ioctls as well.
41 73
42 Say Y if you have programs using it (we don't know of any). 74 Say Y if you have programs using it, like old versions of
75 hal.
diff --git a/net/wireless/core.c b/net/wireless/core.c
index f1da0b93bc56..5cadbeb76a14 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * This is the linux wireless configuration interface. 2 * This is the linux wireless configuration interface.
3 * 3 *
4 * Copyright 2006, 2007 Johannes Berg <johannes@sipsolutions.net> 4 * Copyright 2006-2008 Johannes Berg <johannes@sipsolutions.net>
5 */ 5 */
6 6
7#include <linux/if.h> 7#include <linux/if.h>
@@ -13,12 +13,14 @@
13#include <linux/debugfs.h> 13#include <linux/debugfs.h>
14#include <linux/notifier.h> 14#include <linux/notifier.h>
15#include <linux/device.h> 15#include <linux/device.h>
16#include <linux/list.h>
16#include <net/genetlink.h> 17#include <net/genetlink.h>
17#include <net/cfg80211.h> 18#include <net/cfg80211.h>
18#include <net/wireless.h> 19#include <net/wireless.h>
19#include "nl80211.h" 20#include "nl80211.h"
20#include "core.h" 21#include "core.h"
21#include "sysfs.h" 22#include "sysfs.h"
23#include "reg.h"
22 24
23/* name for sysfs, %d is appended */ 25/* name for sysfs, %d is appended */
24#define PHY_NAME "phy" 26#define PHY_NAME "phy"
@@ -32,7 +34,6 @@ MODULE_DESCRIPTION("wireless configuration support");
32 * often because we need to do it for each command */ 34 * often because we need to do it for each command */
33LIST_HEAD(cfg80211_drv_list); 35LIST_HEAD(cfg80211_drv_list);
34DEFINE_MUTEX(cfg80211_drv_mutex); 36DEFINE_MUTEX(cfg80211_drv_mutex);
35static int wiphy_counter;
36 37
37/* for debugfs */ 38/* for debugfs */
38static struct dentry *ieee80211_debugfs_dir; 39static struct dentry *ieee80211_debugfs_dir;
@@ -204,6 +205,8 @@ out_unlock:
204 205
205struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv) 206struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv)
206{ 207{
208 static int wiphy_counter;
209
207 struct cfg80211_registered_device *drv; 210 struct cfg80211_registered_device *drv;
208 int alloc_size; 211 int alloc_size;
209 212
@@ -220,21 +223,18 @@ struct wiphy *wiphy_new(struct cfg80211_ops *ops, int sizeof_priv)
220 223
221 mutex_lock(&cfg80211_drv_mutex); 224 mutex_lock(&cfg80211_drv_mutex);
222 225
223 drv->idx = wiphy_counter; 226 drv->idx = wiphy_counter++;
224
225 /* now increase counter for the next device unless
226 * it has wrapped previously */
227 if (wiphy_counter >= 0)
228 wiphy_counter++;
229
230 mutex_unlock(&cfg80211_drv_mutex);
231 227
232 if (unlikely(drv->idx < 0)) { 228 if (unlikely(drv->idx < 0)) {
229 wiphy_counter--;
230 mutex_unlock(&cfg80211_drv_mutex);
233 /* ugh, wrapped! */ 231 /* ugh, wrapped! */
234 kfree(drv); 232 kfree(drv);
235 return NULL; 233 return NULL;
236 } 234 }
237 235
236 mutex_unlock(&cfg80211_drv_mutex);
237
238 /* give it a proper name */ 238 /* give it a proper name */
239 snprintf(drv->wiphy.dev.bus_id, BUS_ID_SIZE, 239 snprintf(drv->wiphy.dev.bus_id, BUS_ID_SIZE,
240 PHY_NAME "%d", drv->idx); 240 PHY_NAME "%d", drv->idx);
@@ -259,6 +259,13 @@ int wiphy_register(struct wiphy *wiphy)
259 struct ieee80211_supported_band *sband; 259 struct ieee80211_supported_band *sband;
260 bool have_band = false; 260 bool have_band = false;
261 int i; 261 int i;
262 u16 ifmodes = wiphy->interface_modes;
263
264 /* sanity check ifmodes */
265 WARN_ON(!ifmodes);
266 ifmodes &= ((1 << __NL80211_IFTYPE_AFTER_LAST) - 1) & ~1;
267 if (WARN_ON(ifmodes != wiphy->interface_modes))
268 wiphy->interface_modes = ifmodes;
262 269
263 /* sanity check supported bands/channels */ 270 /* sanity check supported bands/channels */
264 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 271 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
@@ -295,7 +302,9 @@ int wiphy_register(struct wiphy *wiphy)
295 ieee80211_set_bitrate_flags(wiphy); 302 ieee80211_set_bitrate_flags(wiphy);
296 303
297 /* set up regulatory info */ 304 /* set up regulatory info */
298 wiphy_update_regulatory(wiphy); 305 mutex_lock(&cfg80211_reg_mutex);
306 wiphy_update_regulatory(wiphy, REGDOM_SET_BY_CORE);
307 mutex_unlock(&cfg80211_reg_mutex);
299 308
300 mutex_lock(&cfg80211_drv_mutex); 309 mutex_lock(&cfg80211_drv_mutex);
301 310
@@ -373,6 +382,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
373 382
374 rdev = wiphy_to_dev(dev->ieee80211_ptr->wiphy); 383 rdev = wiphy_to_dev(dev->ieee80211_ptr->wiphy);
375 384
385 WARN_ON(dev->ieee80211_ptr->iftype == NL80211_IFTYPE_UNSPECIFIED);
386
376 switch (state) { 387 switch (state) {
377 case NETDEV_REGISTER: 388 case NETDEV_REGISTER:
378 mutex_lock(&rdev->devlist_mtx); 389 mutex_lock(&rdev->devlist_mtx);
@@ -404,7 +415,9 @@ static struct notifier_block cfg80211_netdev_notifier = {
404 415
405static int cfg80211_init(void) 416static int cfg80211_init(void)
406{ 417{
407 int err = wiphy_sysfs_init(); 418 int err;
419
420 err = wiphy_sysfs_init();
408 if (err) 421 if (err)
409 goto out_fail_sysfs; 422 goto out_fail_sysfs;
410 423
@@ -418,8 +431,14 @@ static int cfg80211_init(void)
418 431
419 ieee80211_debugfs_dir = debugfs_create_dir("ieee80211", NULL); 432 ieee80211_debugfs_dir = debugfs_create_dir("ieee80211", NULL);
420 433
434 err = regulatory_init();
435 if (err)
436 goto out_fail_reg;
437
421 return 0; 438 return 0;
422 439
440out_fail_reg:
441 debugfs_remove(ieee80211_debugfs_dir);
423out_fail_nl80211: 442out_fail_nl80211:
424 unregister_netdevice_notifier(&cfg80211_netdev_notifier); 443 unregister_netdevice_notifier(&cfg80211_netdev_notifier);
425out_fail_notifier: 444out_fail_notifier:
@@ -427,6 +446,7 @@ out_fail_notifier:
427out_fail_sysfs: 446out_fail_sysfs:
428 return err; 447 return err;
429} 448}
449
430subsys_initcall(cfg80211_init); 450subsys_initcall(cfg80211_init);
431 451
432static void cfg80211_exit(void) 452static void cfg80211_exit(void)
@@ -435,5 +455,6 @@ static void cfg80211_exit(void)
435 nl80211_exit(); 455 nl80211_exit();
436 unregister_netdevice_notifier(&cfg80211_netdev_notifier); 456 unregister_netdevice_notifier(&cfg80211_netdev_notifier);
437 wiphy_sysfs_exit(); 457 wiphy_sysfs_exit();
458 regulatory_exit();
438} 459}
439module_exit(cfg80211_exit); 460module_exit(cfg80211_exit);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 7a02c356d63d..771cc5cc7658 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -79,6 +79,6 @@ extern int cfg80211_dev_rename(struct cfg80211_registered_device *drv,
79 char *newname); 79 char *newname);
80 80
81void ieee80211_set_bitrate_flags(struct wiphy *wiphy); 81void ieee80211_set_bitrate_flags(struct wiphy *wiphy);
82void wiphy_update_regulatory(struct wiphy *wiphy); 82void wiphy_update_regulatory(struct wiphy *wiphy, enum reg_set_by setby);
83 83
84#endif /* __NET_WIRELESS_CORE_H */ 84#endif /* __NET_WIRELESS_CORE_H */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 59eb2cf42e5f..572793c8c7ab 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -18,6 +18,7 @@
18#include <net/cfg80211.h> 18#include <net/cfg80211.h>
19#include "core.h" 19#include "core.h"
20#include "nl80211.h" 20#include "nl80211.h"
21#include "reg.h"
21 22
22/* the netlink family */ 23/* the netlink family */
23static struct genl_family nl80211_fam = { 24static struct genl_family nl80211_fam = {
@@ -87,6 +88,16 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
87 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY, 88 [NL80211_ATTR_MESH_ID] = { .type = NLA_BINARY,
88 .len = IEEE80211_MAX_MESH_ID_LEN }, 89 .len = IEEE80211_MAX_MESH_ID_LEN },
89 [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 }, 90 [NL80211_ATTR_MPATH_NEXT_HOP] = { .type = NLA_U32 },
91
92 [NL80211_ATTR_REG_ALPHA2] = { .type = NLA_STRING, .len = 2 },
93 [NL80211_ATTR_REG_RULES] = { .type = NLA_NESTED },
94
95 [NL80211_ATTR_BSS_CTS_PROT] = { .type = NLA_U8 },
96 [NL80211_ATTR_BSS_SHORT_PREAMBLE] = { .type = NLA_U8 },
97 [NL80211_ATTR_BSS_SHORT_SLOT_TIME] = { .type = NLA_U8 },
98
99 [NL80211_ATTR_HT_CAPABILITY] = { .type = NLA_BINARY,
100 .len = NL80211_HT_CAPABILITY_LEN },
90}; 101};
91 102
92/* message building helper */ 103/* message building helper */
@@ -106,10 +117,12 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
106 struct nlattr *nl_bands, *nl_band; 117 struct nlattr *nl_bands, *nl_band;
107 struct nlattr *nl_freqs, *nl_freq; 118 struct nlattr *nl_freqs, *nl_freq;
108 struct nlattr *nl_rates, *nl_rate; 119 struct nlattr *nl_rates, *nl_rate;
120 struct nlattr *nl_modes;
109 enum ieee80211_band band; 121 enum ieee80211_band band;
110 struct ieee80211_channel *chan; 122 struct ieee80211_channel *chan;
111 struct ieee80211_rate *rate; 123 struct ieee80211_rate *rate;
112 int i; 124 int i;
125 u16 ifmodes = dev->wiphy.interface_modes;
113 126
114 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY); 127 hdr = nl80211hdr_put(msg, pid, seq, flags, NL80211_CMD_NEW_WIPHY);
115 if (!hdr) 128 if (!hdr)
@@ -118,6 +131,20 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
118 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->idx); 131 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, dev->idx);
119 NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy)); 132 NLA_PUT_STRING(msg, NL80211_ATTR_WIPHY_NAME, wiphy_name(&dev->wiphy));
120 133
134 nl_modes = nla_nest_start(msg, NL80211_ATTR_SUPPORTED_IFTYPES);
135 if (!nl_modes)
136 goto nla_put_failure;
137
138 i = 0;
139 while (ifmodes) {
140 if (ifmodes & 1)
141 NLA_PUT_FLAG(msg, i);
142 ifmodes >>= 1;
143 i++;
144 }
145
146 nla_nest_end(msg, nl_modes);
147
121 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS); 148 nl_bands = nla_nest_start(msg, NL80211_ATTR_WIPHY_BANDS);
122 if (!nl_bands) 149 if (!nl_bands)
123 goto nla_put_failure; 150 goto nla_put_failure;
@@ -272,7 +299,7 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 pid, u32 seq, int flags,
272 299
273 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); 300 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
274 NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, dev->name); 301 NLA_PUT_STRING(msg, NL80211_ATTR_IFNAME, dev->name);
275 /* TODO: interface type */ 302 NLA_PUT_U32(msg, NL80211_ATTR_IFTYPE, dev->ieee80211_ptr->iftype);
276 return genlmsg_end(msg, hdr); 303 return genlmsg_end(msg, hdr);
277 304
278 nla_put_failure: 305 nla_put_failure:
@@ -391,40 +418,56 @@ static int nl80211_set_interface(struct sk_buff *skb, struct genl_info *info)
391 int err, ifindex; 418 int err, ifindex;
392 enum nl80211_iftype type; 419 enum nl80211_iftype type;
393 struct net_device *dev; 420 struct net_device *dev;
394 u32 flags; 421 u32 _flags, *flags = NULL;
395 422
396 memset(&params, 0, sizeof(params)); 423 memset(&params, 0, sizeof(params));
397 424
398 if (info->attrs[NL80211_ATTR_IFTYPE]) {
399 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
400 if (type > NL80211_IFTYPE_MAX)
401 return -EINVAL;
402 } else
403 return -EINVAL;
404
405 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev); 425 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
406 if (err) 426 if (err)
407 return err; 427 return err;
408 ifindex = dev->ifindex; 428 ifindex = dev->ifindex;
429 type = dev->ieee80211_ptr->iftype;
409 dev_put(dev); 430 dev_put(dev);
410 431
411 if (!drv->ops->change_virtual_intf) { 432 err = -EINVAL;
433 if (info->attrs[NL80211_ATTR_IFTYPE]) {
434 type = nla_get_u32(info->attrs[NL80211_ATTR_IFTYPE]);
435 if (type > NL80211_IFTYPE_MAX)
436 goto unlock;
437 }
438
439 if (!drv->ops->change_virtual_intf ||
440 !(drv->wiphy.interface_modes & (1 << type))) {
412 err = -EOPNOTSUPP; 441 err = -EOPNOTSUPP;
413 goto unlock; 442 goto unlock;
414 } 443 }
415 444
416 if (type == NL80211_IFTYPE_MESH_POINT && 445 if (info->attrs[NL80211_ATTR_MESH_ID]) {
417 info->attrs[NL80211_ATTR_MESH_ID]) { 446 if (type != NL80211_IFTYPE_MESH_POINT) {
447 err = -EINVAL;
448 goto unlock;
449 }
418 params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]); 450 params.mesh_id = nla_data(info->attrs[NL80211_ATTR_MESH_ID]);
419 params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]); 451 params.mesh_id_len = nla_len(info->attrs[NL80211_ATTR_MESH_ID]);
420 } 452 }
421 453
454 if (info->attrs[NL80211_ATTR_MNTR_FLAGS]) {
455 if (type != NL80211_IFTYPE_MONITOR) {
456 err = -EINVAL;
457 goto unlock;
458 }
459 err = parse_monitor_flags(info->attrs[NL80211_ATTR_MNTR_FLAGS],
460 &_flags);
461 if (!err)
462 flags = &_flags;
463 }
422 rtnl_lock(); 464 rtnl_lock();
423 err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ?
424 info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL,
425 &flags);
426 err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex, 465 err = drv->ops->change_virtual_intf(&drv->wiphy, ifindex,
427 type, err ? NULL : &flags, &params); 466 type, flags, &params);
467
468 dev = __dev_get_by_index(&init_net, ifindex);
469 WARN_ON(!dev || (!err && dev->ieee80211_ptr->iftype != type));
470
428 rtnl_unlock(); 471 rtnl_unlock();
429 472
430 unlock: 473 unlock:
@@ -455,7 +498,8 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
455 if (IS_ERR(drv)) 498 if (IS_ERR(drv))
456 return PTR_ERR(drv); 499 return PTR_ERR(drv);
457 500
458 if (!drv->ops->add_virtual_intf) { 501 if (!drv->ops->add_virtual_intf ||
502 !(drv->wiphy.interface_modes & (1 << type))) {
459 err = -EOPNOTSUPP; 503 err = -EOPNOTSUPP;
460 goto unlock; 504 goto unlock;
461 } 505 }
@@ -1125,6 +1169,10 @@ static int nl80211_set_station(struct sk_buff *skb, struct genl_info *info)
1125 params.listen_interval = 1169 params.listen_interval =
1126 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]); 1170 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
1127 1171
1172 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
1173 params.ht_capa =
1174 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
1175
1128 if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS], 1176 if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
1129 &params.station_flags)) 1177 &params.station_flags))
1130 return -EINVAL; 1178 return -EINVAL;
@@ -1188,6 +1236,9 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
1188 params.listen_interval = 1236 params.listen_interval =
1189 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]); 1237 nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
1190 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]); 1238 params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
1239 if (info->attrs[NL80211_ATTR_HT_CAPABILITY])
1240 params.ht_capa =
1241 nla_data(info->attrs[NL80211_ATTR_HT_CAPABILITY]);
1191 1242
1192 if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS], 1243 if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
1193 &params.station_flags)) 1244 &params.station_flags))
@@ -1525,6 +1576,183 @@ static int nl80211_del_mpath(struct sk_buff *skb, struct genl_info *info)
1525 return err; 1576 return err;
1526} 1577}
1527 1578
1579static int nl80211_set_bss(struct sk_buff *skb, struct genl_info *info)
1580{
1581 struct cfg80211_registered_device *drv;
1582 int err;
1583 struct net_device *dev;
1584 struct bss_parameters params;
1585
1586 memset(&params, 0, sizeof(params));
1587 /* default to not changing parameters */
1588 params.use_cts_prot = -1;
1589 params.use_short_preamble = -1;
1590 params.use_short_slot_time = -1;
1591
1592 if (info->attrs[NL80211_ATTR_BSS_CTS_PROT])
1593 params.use_cts_prot =
1594 nla_get_u8(info->attrs[NL80211_ATTR_BSS_CTS_PROT]);
1595 if (info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE])
1596 params.use_short_preamble =
1597 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_PREAMBLE]);
1598 if (info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME])
1599 params.use_short_slot_time =
1600 nla_get_u8(info->attrs[NL80211_ATTR_BSS_SHORT_SLOT_TIME]);
1601
1602 err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);
1603 if (err)
1604 return err;
1605
1606 if (!drv->ops->change_bss) {
1607 err = -EOPNOTSUPP;
1608 goto out;
1609 }
1610
1611 rtnl_lock();
1612 err = drv->ops->change_bss(&drv->wiphy, dev, &params);
1613 rtnl_unlock();
1614
1615 out:
1616 cfg80211_put_dev(drv);
1617 dev_put(dev);
1618 return err;
1619}
1620
1621static const struct nla_policy
1622 reg_rule_policy[NL80211_REG_RULE_ATTR_MAX + 1] = {
1623 [NL80211_ATTR_REG_RULE_FLAGS] = { .type = NLA_U32 },
1624 [NL80211_ATTR_FREQ_RANGE_START] = { .type = NLA_U32 },
1625 [NL80211_ATTR_FREQ_RANGE_END] = { .type = NLA_U32 },
1626 [NL80211_ATTR_FREQ_RANGE_MAX_BW] = { .type = NLA_U32 },
1627 [NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN] = { .type = NLA_U32 },
1628 [NL80211_ATTR_POWER_RULE_MAX_EIRP] = { .type = NLA_U32 },
1629};
1630
1631static int parse_reg_rule(struct nlattr *tb[],
1632 struct ieee80211_reg_rule *reg_rule)
1633{
1634 struct ieee80211_freq_range *freq_range = &reg_rule->freq_range;
1635 struct ieee80211_power_rule *power_rule = &reg_rule->power_rule;
1636
1637 if (!tb[NL80211_ATTR_REG_RULE_FLAGS])
1638 return -EINVAL;
1639 if (!tb[NL80211_ATTR_FREQ_RANGE_START])
1640 return -EINVAL;
1641 if (!tb[NL80211_ATTR_FREQ_RANGE_END])
1642 return -EINVAL;
1643 if (!tb[NL80211_ATTR_FREQ_RANGE_MAX_BW])
1644 return -EINVAL;
1645 if (!tb[NL80211_ATTR_POWER_RULE_MAX_EIRP])
1646 return -EINVAL;
1647
1648 reg_rule->flags = nla_get_u32(tb[NL80211_ATTR_REG_RULE_FLAGS]);
1649
1650 freq_range->start_freq_khz =
1651 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_START]);
1652 freq_range->end_freq_khz =
1653 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_END]);
1654 freq_range->max_bandwidth_khz =
1655 nla_get_u32(tb[NL80211_ATTR_FREQ_RANGE_MAX_BW]);
1656
1657 power_rule->max_eirp =
1658 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_EIRP]);
1659
1660 if (tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN])
1661 power_rule->max_antenna_gain =
1662 nla_get_u32(tb[NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN]);
1663
1664 return 0;
1665}
1666
1667static int nl80211_req_set_reg(struct sk_buff *skb, struct genl_info *info)
1668{
1669 int r;
1670 char *data = NULL;
1671
1672 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
1673 return -EINVAL;
1674
1675 data = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
1676
1677#ifdef CONFIG_WIRELESS_OLD_REGULATORY
1678 /* We ignore world regdom requests with the old regdom setup */
1679 if (is_world_regdom(data))
1680 return -EINVAL;
1681#endif
1682 mutex_lock(&cfg80211_drv_mutex);
1683 r = __regulatory_hint(NULL, REGDOM_SET_BY_USER, data, NULL);
1684 mutex_unlock(&cfg80211_drv_mutex);
1685 return r;
1686}
1687
1688static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
1689{
1690 struct nlattr *tb[NL80211_REG_RULE_ATTR_MAX + 1];
1691 struct nlattr *nl_reg_rule;
1692 char *alpha2 = NULL;
1693 int rem_reg_rules = 0, r = 0;
1694 u32 num_rules = 0, rule_idx = 0, size_of_regd;
1695 struct ieee80211_regdomain *rd = NULL;
1696
1697 if (!info->attrs[NL80211_ATTR_REG_ALPHA2])
1698 return -EINVAL;
1699
1700 if (!info->attrs[NL80211_ATTR_REG_RULES])
1701 return -EINVAL;
1702
1703 alpha2 = nla_data(info->attrs[NL80211_ATTR_REG_ALPHA2]);
1704
1705 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
1706 rem_reg_rules) {
1707 num_rules++;
1708 if (num_rules > NL80211_MAX_SUPP_REG_RULES)
1709 goto bad_reg;
1710 }
1711
1712 if (!reg_is_valid_request(alpha2))
1713 return -EINVAL;
1714
1715 size_of_regd = sizeof(struct ieee80211_regdomain) +
1716 (num_rules * sizeof(struct ieee80211_reg_rule));
1717
1718 rd = kzalloc(size_of_regd, GFP_KERNEL);
1719 if (!rd)
1720 return -ENOMEM;
1721
1722 rd->n_reg_rules = num_rules;
1723 rd->alpha2[0] = alpha2[0];
1724 rd->alpha2[1] = alpha2[1];
1725
1726 nla_for_each_nested(nl_reg_rule, info->attrs[NL80211_ATTR_REG_RULES],
1727 rem_reg_rules) {
1728 nla_parse(tb, NL80211_REG_RULE_ATTR_MAX,
1729 nla_data(nl_reg_rule), nla_len(nl_reg_rule),
1730 reg_rule_policy);
1731 r = parse_reg_rule(tb, &rd->reg_rules[rule_idx]);
1732 if (r)
1733 goto bad_reg;
1734
1735 rule_idx++;
1736
1737 if (rule_idx > NL80211_MAX_SUPP_REG_RULES)
1738 goto bad_reg;
1739 }
1740
1741 BUG_ON(rule_idx != num_rules);
1742
1743 mutex_lock(&cfg80211_drv_mutex);
1744 r = set_regdom(rd);
1745 mutex_unlock(&cfg80211_drv_mutex);
1746 if (r)
1747 goto bad_reg;
1748
1749 return r;
1750
1751bad_reg:
1752 kfree(rd);
1753 return -EINVAL;
1754}
1755
1528static struct genl_ops nl80211_ops[] = { 1756static struct genl_ops nl80211_ops[] = {
1529 { 1757 {
1530 .cmd = NL80211_CMD_GET_WIPHY, 1758 .cmd = NL80211_CMD_GET_WIPHY,
@@ -1656,6 +1884,24 @@ static struct genl_ops nl80211_ops[] = {
1656 .policy = nl80211_policy, 1884 .policy = nl80211_policy,
1657 .flags = GENL_ADMIN_PERM, 1885 .flags = GENL_ADMIN_PERM,
1658 }, 1886 },
1887 {
1888 .cmd = NL80211_CMD_SET_BSS,
1889 .doit = nl80211_set_bss,
1890 .policy = nl80211_policy,
1891 .flags = GENL_ADMIN_PERM,
1892 },
1893 {
1894 .cmd = NL80211_CMD_SET_REG,
1895 .doit = nl80211_set_reg,
1896 .policy = nl80211_policy,
1897 .flags = GENL_ADMIN_PERM,
1898 },
1899 {
1900 .cmd = NL80211_CMD_REQ_SET_REG,
1901 .doit = nl80211_req_set_reg,
1902 .policy = nl80211_policy,
1903 .flags = GENL_ADMIN_PERM,
1904 },
1659}; 1905};
1660 1906
1661/* multicast groups */ 1907/* multicast groups */
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 855bff4b3250..626dbb688499 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -2,179 +2,871 @@
2 * Copyright 2002-2005, Instant802 Networks, Inc. 2 * Copyright 2002-2005, Instant802 Networks, Inc.
3 * Copyright 2005-2006, Devicescape Software, Inc. 3 * Copyright 2005-2006, Devicescape Software, Inc.
4 * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> 4 * Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
5 * Copyright 2008 Luis R. Rodriguez <lrodriguz@atheros.com>
5 * 6 *
6 * 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
7 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
9 */ 10 */
10 11
11/* 12/**
12 * This regulatory domain control implementation is highly incomplete, it 13 * DOC: Wireless regulatory infrastructure
13 * only exists for the purpose of not regressing mac80211.
14 *
15 * For now, drivers can restrict the set of allowed channels by either
16 * not registering those channels or setting the IEEE80211_CHAN_DISABLED
17 * flag; that flag will only be *set* by this code, never *cleared.
18 * 14 *
19 * The usual implementation is for a driver to read a device EEPROM to 15 * The usual implementation is for a driver to read a device EEPROM to
20 * determine which regulatory domain it should be operating under, then 16 * determine which regulatory domain it should be operating under, then
21 * looking up the allowable channels in a driver-local table and finally 17 * looking up the allowable channels in a driver-local table and finally
22 * registering those channels in the wiphy structure. 18 * registering those channels in the wiphy structure.
23 * 19 *
24 * Alternatively, drivers that trust the regulatory domain control here 20 * Another set of compliance enforcement is for drivers to use their
25 * will register a complete set of capabilities and the control code 21 * own compliance limits which can be stored on the EEPROM. The host
26 * will restrict the set by setting the IEEE80211_CHAN_* flags. 22 * driver or firmware may ensure these are used.
23 *
24 * In addition to all this we provide an extra layer of regulatory
25 * conformance. For drivers which do not have any regulatory
26 * information CRDA provides the complete regulatory solution.
27 * For others it provides a community effort on further restrictions
28 * to enhance compliance.
29 *
30 * Note: When number of rules --> infinity we will not be able to
31 * index on alpha2 any more, instead we'll probably have to
32 * rely on some SHA1 checksum of the regdomain for example.
33 *
27 */ 34 */
28#include <linux/kernel.h> 35#include <linux/kernel.h>
36#include <linux/list.h>
37#include <linux/random.h>
38#include <linux/nl80211.h>
39#include <linux/platform_device.h>
29#include <net/wireless.h> 40#include <net/wireless.h>
41#include <net/cfg80211.h>
30#include "core.h" 42#include "core.h"
43#include "reg.h"
31 44
32static char *ieee80211_regdom = "US"; 45/* wiphy is set if this request's initiator is REGDOM_SET_BY_DRIVER */
33module_param(ieee80211_regdom, charp, 0444); 46struct regulatory_request {
34MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code"); 47 struct list_head list;
35 48 struct wiphy *wiphy;
36struct ieee80211_channel_range { 49 int granted;
37 short start_freq; 50 enum reg_set_by initiator;
38 short end_freq; 51 char alpha2[2];
39 int max_power;
40 int max_antenna_gain;
41 u32 flags;
42}; 52};
43 53
44struct ieee80211_regdomain { 54static LIST_HEAD(regulatory_requests);
45 const char *code; 55DEFINE_MUTEX(cfg80211_reg_mutex);
46 const struct ieee80211_channel_range *ranges; 56
47 int n_ranges; 57/* To trigger userspace events */
58static struct platform_device *reg_pdev;
59
60/* Keep the ordering from large to small */
61static u32 supported_bandwidths[] = {
62 MHZ_TO_KHZ(40),
63 MHZ_TO_KHZ(20),
48}; 64};
49 65
50#define RANGE_PWR(_start, _end, _pwr, _ag, _flags) \ 66static struct list_head regulatory_requests;
51 { _start, _end, _pwr, _ag, _flags }
52 67
68/* Central wireless core regulatory domains, we only need two,
69 * the current one and a world regulatory domain in case we have no
70 * information to give us an alpha2 */
71static const struct ieee80211_regdomain *cfg80211_regdomain;
53 72
54/* 73/* We keep a static world regulatory domain in case of the absence of CRDA */
55 * Ideally, in the future, these definitions will be loaded from a 74static const struct ieee80211_regdomain world_regdom = {
56 * userspace table via some daemon. 75 .n_reg_rules = 1,
57 */ 76 .alpha2 = "00",
58static const struct ieee80211_channel_range ieee80211_US_channels[] = { 77 .reg_rules = {
59 /* IEEE 802.11b/g, channels 1..11 */ 78 REG_RULE(2412-10, 2462+10, 40, 6, 20,
60 RANGE_PWR(2412, 2462, 27, 6, 0), 79 NL80211_RRF_PASSIVE_SCAN |
61 /* IEEE 802.11a, channel 36*/ 80 NL80211_RRF_NO_IBSS),
62 RANGE_PWR(5180, 5180, 23, 6, 0), 81 }
63 /* IEEE 802.11a, channel 40*/
64 RANGE_PWR(5200, 5200, 23, 6, 0),
65 /* IEEE 802.11a, channel 44*/
66 RANGE_PWR(5220, 5220, 23, 6, 0),
67 /* IEEE 802.11a, channels 48..64 */
68 RANGE_PWR(5240, 5320, 23, 6, 0),
69 /* IEEE 802.11a, channels 149..165, outdoor */
70 RANGE_PWR(5745, 5825, 30, 6, 0),
71}; 82};
72 83
73static const struct ieee80211_channel_range ieee80211_JP_channels[] = { 84static const struct ieee80211_regdomain *cfg80211_world_regdom =
74 /* IEEE 802.11b/g, channels 1..14 */ 85 &world_regdom;
75 RANGE_PWR(2412, 2484, 20, 6, 0), 86
76 /* IEEE 802.11a, channels 34..48 */ 87#ifdef CONFIG_WIRELESS_OLD_REGULATORY
77 RANGE_PWR(5170, 5240, 20, 6, IEEE80211_CHAN_PASSIVE_SCAN), 88static char *ieee80211_regdom = "US";
78 /* IEEE 802.11a, channels 52..64 */ 89module_param(ieee80211_regdom, charp, 0444);
79 RANGE_PWR(5260, 5320, 20, 6, IEEE80211_CHAN_NO_IBSS | 90MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code");
80 IEEE80211_CHAN_RADAR), 91
81}; 92/* We assume 40 MHz bandwidth for the old regulatory work.
93 * We make emphasis we are using the exact same frequencies
94 * as before */
82 95
83static const struct ieee80211_channel_range ieee80211_EU_channels[] = { 96static const struct ieee80211_regdomain us_regdom = {
84 /* IEEE 802.11b/g, channels 1..13 */ 97 .n_reg_rules = 6,
85 RANGE_PWR(2412, 2472, 20, 6, 0), 98 .alpha2 = "US",
86 /* IEEE 802.11a, channel 36*/ 99 .reg_rules = {
87 RANGE_PWR(5180, 5180, 23, 6, IEEE80211_CHAN_PASSIVE_SCAN), 100 /* IEEE 802.11b/g, channels 1..11 */
88 /* IEEE 802.11a, channel 40*/ 101 REG_RULE(2412-10, 2462+10, 40, 6, 27, 0),
89 RANGE_PWR(5200, 5200, 23, 6, IEEE80211_CHAN_PASSIVE_SCAN), 102 /* IEEE 802.11a, channel 36 */
90 /* IEEE 802.11a, channel 44*/ 103 REG_RULE(5180-10, 5180+10, 40, 6, 23, 0),
91 RANGE_PWR(5220, 5220, 23, 6, IEEE80211_CHAN_PASSIVE_SCAN), 104 /* IEEE 802.11a, channel 40 */
92 /* IEEE 802.11a, channels 48..64 */ 105 REG_RULE(5200-10, 5200+10, 40, 6, 23, 0),
93 RANGE_PWR(5240, 5320, 23, 6, IEEE80211_CHAN_NO_IBSS | 106 /* IEEE 802.11a, channel 44 */
94 IEEE80211_CHAN_RADAR), 107 REG_RULE(5220-10, 5220+10, 40, 6, 23, 0),
95 /* IEEE 802.11a, channels 100..140 */ 108 /* IEEE 802.11a, channels 48..64 */
96 RANGE_PWR(5500, 5700, 30, 6, IEEE80211_CHAN_NO_IBSS | 109 REG_RULE(5240-10, 5320+10, 40, 6, 23, 0),
97 IEEE80211_CHAN_RADAR), 110 /* IEEE 802.11a, channels 149..165, outdoor */
111 REG_RULE(5745-10, 5825+10, 40, 6, 30, 0),
112 }
98}; 113};
99 114
100#define REGDOM(_code) \ 115static const struct ieee80211_regdomain jp_regdom = {
101 { \ 116 .n_reg_rules = 3,
102 .code = __stringify(_code), \ 117 .alpha2 = "JP",
103 .ranges = ieee80211_ ##_code## _channels, \ 118 .reg_rules = {
104 .n_ranges = ARRAY_SIZE(ieee80211_ ##_code## _channels), \ 119 /* IEEE 802.11b/g, channels 1..14 */
120 REG_RULE(2412-10, 2484+10, 40, 6, 20, 0),
121 /* IEEE 802.11a, channels 34..48 */
122 REG_RULE(5170-10, 5240+10, 40, 6, 20,
123 NL80211_RRF_PASSIVE_SCAN),
124 /* IEEE 802.11a, channels 52..64 */
125 REG_RULE(5260-10, 5320+10, 40, 6, 20,
126 NL80211_RRF_NO_IBSS |
127 NL80211_RRF_DFS),
105 } 128 }
129};
106 130
107static const struct ieee80211_regdomain ieee80211_regdoms[] = { 131static const struct ieee80211_regdomain eu_regdom = {
108 REGDOM(US), 132 .n_reg_rules = 6,
109 REGDOM(JP), 133 /* This alpha2 is bogus, we leave it here just for stupid
110 REGDOM(EU), 134 * backward compatibility */
135 .alpha2 = "EU",
136 .reg_rules = {
137 /* IEEE 802.11b/g, channels 1..13 */
138 REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
139 /* IEEE 802.11a, channel 36 */
140 REG_RULE(5180-10, 5180+10, 40, 6, 23,
141 NL80211_RRF_PASSIVE_SCAN),
142 /* IEEE 802.11a, channel 40 */
143 REG_RULE(5200-10, 5200+10, 40, 6, 23,
144 NL80211_RRF_PASSIVE_SCAN),
145 /* IEEE 802.11a, channel 44 */
146 REG_RULE(5220-10, 5220+10, 40, 6, 23,
147 NL80211_RRF_PASSIVE_SCAN),
148 /* IEEE 802.11a, channels 48..64 */
149 REG_RULE(5240-10, 5320+10, 40, 6, 20,
150 NL80211_RRF_NO_IBSS |
151 NL80211_RRF_DFS),
152 /* IEEE 802.11a, channels 100..140 */
153 REG_RULE(5500-10, 5700+10, 40, 6, 30,
154 NL80211_RRF_NO_IBSS |
155 NL80211_RRF_DFS),
156 }
111}; 157};
112 158
159static const struct ieee80211_regdomain *static_regdom(char *alpha2)
160{
161 if (alpha2[0] == 'U' && alpha2[1] == 'S')
162 return &us_regdom;
163 if (alpha2[0] == 'J' && alpha2[1] == 'P')
164 return &jp_regdom;
165 if (alpha2[0] == 'E' && alpha2[1] == 'U')
166 return &eu_regdom;
167 /* Default, as per the old rules */
168 return &us_regdom;
169}
170
171static bool is_old_static_regdom(const struct ieee80211_regdomain *rd)
172{
173 if (rd == &us_regdom || rd == &jp_regdom || rd == &eu_regdom)
174 return true;
175 return false;
176}
177#else
178static inline bool is_old_static_regdom(const struct ieee80211_regdomain *rd)
179{
180 return false;
181}
182#endif
113 183
114static const struct ieee80211_regdomain *get_regdom(void) 184static void reset_regdomains(void)
115{ 185{
116 static const struct ieee80211_channel_range 186 /* avoid freeing static information or freeing something twice */
117 ieee80211_world_channels[] = { 187 if (cfg80211_regdomain == cfg80211_world_regdom)
118 /* IEEE 802.11b/g, channels 1..11 */ 188 cfg80211_regdomain = NULL;
119 RANGE_PWR(2412, 2462, 27, 6, 0), 189 if (cfg80211_world_regdom == &world_regdom)
190 cfg80211_world_regdom = NULL;
191 if (cfg80211_regdomain == &world_regdom)
192 cfg80211_regdomain = NULL;
193 if (is_old_static_regdom(cfg80211_regdomain))
194 cfg80211_regdomain = NULL;
195
196 kfree(cfg80211_regdomain);
197 kfree(cfg80211_world_regdom);
198
199 cfg80211_world_regdom = &world_regdom;
200 cfg80211_regdomain = NULL;
201}
202
203/* Dynamic world regulatory domain requested by the wireless
204 * core upon initialization */
205static void update_world_regdomain(const struct ieee80211_regdomain *rd)
206{
207 BUG_ON(list_empty(&regulatory_requests));
208
209 reset_regdomains();
210
211 cfg80211_world_regdom = rd;
212 cfg80211_regdomain = rd;
213}
214
215bool is_world_regdom(const char *alpha2)
216{
217 if (!alpha2)
218 return false;
219 if (alpha2[0] == '0' && alpha2[1] == '0')
220 return true;
221 return false;
222}
223
224static bool is_alpha2_set(const char *alpha2)
225{
226 if (!alpha2)
227 return false;
228 if (alpha2[0] != 0 && alpha2[1] != 0)
229 return true;
230 return false;
231}
232
233static bool is_alpha_upper(char letter)
234{
235 /* ASCII A - Z */
236 if (letter >= 65 && letter <= 90)
237 return true;
238 return false;
239}
240
241static bool is_unknown_alpha2(const char *alpha2)
242{
243 if (!alpha2)
244 return false;
245 /* Special case where regulatory domain was built by driver
246 * but a specific alpha2 cannot be determined */
247 if (alpha2[0] == '9' && alpha2[1] == '9')
248 return true;
249 return false;
250}
251
252static bool is_an_alpha2(const char *alpha2)
253{
254 if (!alpha2)
255 return false;
256 if (is_alpha_upper(alpha2[0]) && is_alpha_upper(alpha2[1]))
257 return true;
258 return false;
259}
260
261static bool alpha2_equal(const char *alpha2_x, const char *alpha2_y)
262{
263 if (!alpha2_x || !alpha2_y)
264 return false;
265 if (alpha2_x[0] == alpha2_y[0] &&
266 alpha2_x[1] == alpha2_y[1])
267 return true;
268 return false;
269}
270
271static bool regdom_changed(const char *alpha2)
272{
273 if (!cfg80211_regdomain)
274 return true;
275 if (alpha2_equal(cfg80211_regdomain->alpha2, alpha2))
276 return false;
277 return true;
278}
279
280/* This lets us keep regulatory code which is updated on a regulatory
281 * basis in userspace. */
282static int call_crda(const char *alpha2)
283{
284 char country_env[9 + 2] = "COUNTRY=";
285 char *envp[] = {
286 country_env,
287 NULL
120 }; 288 };
121 static const struct ieee80211_regdomain regdom_world = REGDOM(world);
122 int i;
123 289
124 for (i = 0; i < ARRAY_SIZE(ieee80211_regdoms); i++) 290 if (!is_world_regdom((char *) alpha2))
125 if (strcmp(ieee80211_regdom, ieee80211_regdoms[i].code) == 0) 291 printk(KERN_INFO "cfg80211: Calling CRDA for country: %c%c\n",
126 return &ieee80211_regdoms[i]; 292 alpha2[0], alpha2[1]);
293 else
294 printk(KERN_INFO "cfg80211: Calling CRDA to update world "
295 "regulatory domain\n");
296
297 country_env[8] = alpha2[0];
298 country_env[9] = alpha2[1];
127 299
128 return &regdom_world; 300 return kobject_uevent_env(&reg_pdev->dev.kobj, KOBJ_CHANGE, envp);
129} 301}
130 302
303/* This has the logic which determines when a new request
304 * should be ignored. */
305static int ignore_request(struct wiphy *wiphy, enum reg_set_by set_by,
306 char *alpha2, struct ieee80211_regdomain *rd)
307{
308 struct regulatory_request *last_request = NULL;
309
310 /* All initial requests are respected */
311 if (list_empty(&regulatory_requests))
312 return 0;
313
314 last_request = list_first_entry(&regulatory_requests,
315 struct regulatory_request, list);
131 316
132static void handle_channel(struct ieee80211_channel *chan, 317 switch (set_by) {
133 const struct ieee80211_regdomain *rd) 318 case REGDOM_SET_BY_INIT:
319 return -EINVAL;
320 case REGDOM_SET_BY_CORE:
321 /* Always respect new wireless core hints, should only
322 * come in for updating the world regulatory domain at init
323 * anyway */
324 return 0;
325 case REGDOM_SET_BY_COUNTRY_IE:
326 if (last_request->initiator == set_by) {
327 if (last_request->wiphy != wiphy) {
328 /* Two cards with two APs claiming different
329 * different Country IE alpha2s!
330 * You're special!! */
331 if (!alpha2_equal(last_request->alpha2,
332 cfg80211_regdomain->alpha2)) {
333 /* XXX: Deal with conflict, consider
334 * building a new one out of the
335 * intersection */
336 WARN_ON(1);
337 return -EOPNOTSUPP;
338 }
339 return -EALREADY;
340 }
341 /* Two consecutive Country IE hints on the same wiphy */
342 if (!alpha2_equal(cfg80211_regdomain->alpha2, alpha2))
343 return 0;
344 return -EALREADY;
345 }
346 if (WARN_ON(!is_alpha2_set(alpha2) || !is_an_alpha2(alpha2)),
347 "Invalid Country IE regulatory hint passed "
348 "to the wireless core\n")
349 return -EINVAL;
350 /* We ignore Country IE hints for now, as we haven't yet
351 * added the dot11MultiDomainCapabilityEnabled flag
352 * for wiphys */
353 return 1;
354 case REGDOM_SET_BY_DRIVER:
355 BUG_ON(!wiphy);
356 if (last_request->initiator == set_by) {
357 /* Two separate drivers hinting different things,
358 * this is possible if you have two devices present
359 * on a system with different EEPROM regulatory
360 * readings. XXX: Do intersection, we support only
361 * the first regulatory hint for now */
362 if (last_request->wiphy != wiphy)
363 return -EALREADY;
364 if (rd)
365 return -EALREADY;
366 /* Driver should not be trying to hint different
367 * regulatory domains! */
368 BUG_ON(!alpha2_equal(alpha2,
369 cfg80211_regdomain->alpha2));
370 return -EALREADY;
371 }
372 if (last_request->initiator == REGDOM_SET_BY_CORE)
373 return 0;
374 /* XXX: Handle intersection, and add the
375 * dot11MultiDomainCapabilityEnabled flag to wiphy. For now
376 * we assume the driver has this set to false, following the
377 * 802.11d dot11MultiDomainCapabilityEnabled documentation */
378 if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE)
379 return 0;
380 return 0;
381 case REGDOM_SET_BY_USER:
382 if (last_request->initiator == set_by ||
383 last_request->initiator == REGDOM_SET_BY_CORE)
384 return 0;
385 /* Drivers can use their wiphy's reg_notifier()
386 * to override any information */
387 if (last_request->initiator == REGDOM_SET_BY_DRIVER)
388 return 0;
389 /* XXX: Handle intersection */
390 if (last_request->initiator == REGDOM_SET_BY_COUNTRY_IE)
391 return -EOPNOTSUPP;
392 return 0;
393 default:
394 return -EINVAL;
395 }
396}
397
398static bool __reg_is_valid_request(const char *alpha2,
399 struct regulatory_request **request)
400{
401 struct regulatory_request *req;
402 if (list_empty(&regulatory_requests))
403 return false;
404 list_for_each_entry(req, &regulatory_requests, list) {
405 if (alpha2_equal(req->alpha2, alpha2)) {
406 *request = req;
407 return true;
408 }
409 }
410 return false;
411}
412
413/* Used by nl80211 before kmalloc'ing our regulatory domain */
414bool reg_is_valid_request(const char *alpha2)
415{
416 struct regulatory_request *request = NULL;
417 return __reg_is_valid_request(alpha2, &request);
418}
419
420/* Sanity check on a regulatory rule */
421static bool is_valid_reg_rule(const struct ieee80211_reg_rule *rule)
422{
423 const struct ieee80211_freq_range *freq_range = &rule->freq_range;
424 u32 freq_diff;
425
426 if (freq_range->start_freq_khz == 0 || freq_range->end_freq_khz == 0)
427 return false;
428
429 if (freq_range->start_freq_khz > freq_range->end_freq_khz)
430 return false;
431
432 freq_diff = freq_range->end_freq_khz - freq_range->start_freq_khz;
433
434 if (freq_range->max_bandwidth_khz > freq_diff)
435 return false;
436
437 return true;
438}
439
440static bool is_valid_rd(const struct ieee80211_regdomain *rd)
441{
442 const struct ieee80211_reg_rule *reg_rule = NULL;
443 unsigned int i;
444
445 if (!rd->n_reg_rules)
446 return false;
447
448 for (i = 0; i < rd->n_reg_rules; i++) {
449 reg_rule = &rd->reg_rules[i];
450 if (!is_valid_reg_rule(reg_rule))
451 return false;
452 }
453
454 return true;
455}
456
457/* Returns value in KHz */
458static u32 freq_max_bandwidth(const struct ieee80211_freq_range *freq_range,
459 u32 freq)
460{
461 unsigned int i;
462 for (i = 0; i < ARRAY_SIZE(supported_bandwidths); i++) {
463 u32 start_freq_khz = freq - supported_bandwidths[i]/2;
464 u32 end_freq_khz = freq + supported_bandwidths[i]/2;
465 if (start_freq_khz >= freq_range->start_freq_khz &&
466 end_freq_khz <= freq_range->end_freq_khz)
467 return supported_bandwidths[i];
468 }
469 return 0;
470}
471
472/* XXX: add support for the rest of enum nl80211_reg_rule_flags, we may
473 * want to just have the channel structure use these */
474static u32 map_regdom_flags(u32 rd_flags)
475{
476 u32 channel_flags = 0;
477 if (rd_flags & NL80211_RRF_PASSIVE_SCAN)
478 channel_flags |= IEEE80211_CHAN_PASSIVE_SCAN;
479 if (rd_flags & NL80211_RRF_NO_IBSS)
480 channel_flags |= IEEE80211_CHAN_NO_IBSS;
481 if (rd_flags & NL80211_RRF_DFS)
482 channel_flags |= IEEE80211_CHAN_RADAR;
483 return channel_flags;
484}
485
486/**
487 * freq_reg_info - get regulatory information for the given frequency
488 * @center_freq: Frequency in KHz for which we want regulatory information for
489 * @bandwidth: the bandwidth requirement you have in KHz, if you do not have one
490 * you can set this to 0. If this frequency is allowed we then set
491 * this value to the maximum allowed bandwidth.
492 * @reg_rule: the regulatory rule which we have for this frequency
493 *
494 * Use this function to get the regulatory rule for a specific frequency.
495 */
496static int freq_reg_info(u32 center_freq, u32 *bandwidth,
497 const struct ieee80211_reg_rule **reg_rule)
134{ 498{
135 int i; 499 int i;
136 u32 flags = chan->orig_flags; 500 u32 max_bandwidth = 0;
137 const struct ieee80211_channel_range *rg = NULL;
138 501
139 for (i = 0; i < rd->n_ranges; i++) { 502 if (!cfg80211_regdomain)
140 if (rd->ranges[i].start_freq <= chan->center_freq && 503 return -EINVAL;
141 chan->center_freq <= rd->ranges[i].end_freq) { 504
142 rg = &rd->ranges[i]; 505 for (i = 0; i < cfg80211_regdomain->n_reg_rules; i++) {
506 const struct ieee80211_reg_rule *rr;
507 const struct ieee80211_freq_range *fr = NULL;
508 const struct ieee80211_power_rule *pr = NULL;
509
510 rr = &cfg80211_regdomain->reg_rules[i];
511 fr = &rr->freq_range;
512 pr = &rr->power_rule;
513 max_bandwidth = freq_max_bandwidth(fr, center_freq);
514 if (max_bandwidth && *bandwidth <= max_bandwidth) {
515 *reg_rule = rr;
516 *bandwidth = max_bandwidth;
143 break; 517 break;
144 } 518 }
145 } 519 }
146 520
147 if (!rg) { 521 return !max_bandwidth;
148 /* not found */ 522}
523
524static void handle_channel(struct ieee80211_channel *chan)
525{
526 int r;
527 u32 flags = chan->orig_flags;
528 u32 max_bandwidth = 0;
529 const struct ieee80211_reg_rule *reg_rule = NULL;
530 const struct ieee80211_power_rule *power_rule = NULL;
531
532 r = freq_reg_info(MHZ_TO_KHZ(chan->center_freq),
533 &max_bandwidth, &reg_rule);
534
535 if (r) {
149 flags |= IEEE80211_CHAN_DISABLED; 536 flags |= IEEE80211_CHAN_DISABLED;
150 chan->flags = flags; 537 chan->flags = flags;
151 return; 538 return;
152 } 539 }
153 540
154 chan->flags = flags; 541 power_rule = &reg_rule->power_rule;
542
543 chan->flags = flags | map_regdom_flags(reg_rule->flags);
155 chan->max_antenna_gain = min(chan->orig_mag, 544 chan->max_antenna_gain = min(chan->orig_mag,
156 rg->max_antenna_gain); 545 (int) MBI_TO_DBI(power_rule->max_antenna_gain));
546 chan->max_bandwidth = KHZ_TO_MHZ(max_bandwidth);
157 if (chan->orig_mpwr) 547 if (chan->orig_mpwr)
158 chan->max_power = min(chan->orig_mpwr, rg->max_power); 548 chan->max_power = min(chan->orig_mpwr,
549 (int) MBM_TO_DBM(power_rule->max_eirp));
159 else 550 else
160 chan->max_power = rg->max_power; 551 chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp);
161} 552}
162 553
163static void handle_band(struct ieee80211_supported_band *sband, 554static void handle_band(struct ieee80211_supported_band *sband)
164 const struct ieee80211_regdomain *rd)
165{ 555{
166 int i; 556 int i;
167 557
168 for (i = 0; i < sband->n_channels; i++) 558 for (i = 0; i < sband->n_channels; i++)
169 handle_channel(&sband->channels[i], rd); 559 handle_channel(&sband->channels[i]);
170} 560}
171 561
172void wiphy_update_regulatory(struct wiphy *wiphy) 562static void update_all_wiphy_regulatory(enum reg_set_by setby)
173{ 563{
174 enum ieee80211_band band; 564 struct cfg80211_registered_device *drv;
175 const struct ieee80211_regdomain *rd = get_regdom(); 565
566 list_for_each_entry(drv, &cfg80211_drv_list, list)
567 wiphy_update_regulatory(&drv->wiphy, setby);
568}
176 569
177 for (band = 0; band < IEEE80211_NUM_BANDS; band++) 570void wiphy_update_regulatory(struct wiphy *wiphy, enum reg_set_by setby)
571{
572 enum ieee80211_band band;
573 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
178 if (wiphy->bands[band]) 574 if (wiphy->bands[band])
179 handle_band(wiphy->bands[band], rd); 575 handle_band(wiphy->bands[band]);
576 if (wiphy->reg_notifier)
577 wiphy->reg_notifier(wiphy, setby);
578 }
579}
580
581/* Caller must hold &cfg80211_drv_mutex */
582int __regulatory_hint(struct wiphy *wiphy, enum reg_set_by set_by,
583 const char *alpha2, struct ieee80211_regdomain *rd)
584{
585 struct regulatory_request *request;
586 char *rd_alpha2;
587 int r = 0;
588
589 r = ignore_request(wiphy, set_by, (char *) alpha2, rd);
590 if (r)
591 return r;
592
593 if (rd)
594 rd_alpha2 = rd->alpha2;
595 else
596 rd_alpha2 = (char *) alpha2;
597
598 switch (set_by) {
599 case REGDOM_SET_BY_CORE:
600 case REGDOM_SET_BY_COUNTRY_IE:
601 case REGDOM_SET_BY_DRIVER:
602 case REGDOM_SET_BY_USER:
603 request = kzalloc(sizeof(struct regulatory_request),
604 GFP_KERNEL);
605 if (!request)
606 return -ENOMEM;
607
608 request->alpha2[0] = rd_alpha2[0];
609 request->alpha2[1] = rd_alpha2[1];
610 request->initiator = set_by;
611 request->wiphy = wiphy;
612
613 list_add_tail(&request->list, &regulatory_requests);
614 if (rd)
615 break;
616 r = call_crda(alpha2);
617#ifndef CONFIG_WIRELESS_OLD_REGULATORY
618 if (r)
619 printk(KERN_ERR "cfg80211: Failed calling CRDA\n");
620#endif
621 break;
622 default:
623 r = -ENOTSUPP;
624 break;
625 }
626
627 return r;
628}
629
630/* If rd is not NULL and if this call fails the caller must free it */
631int regulatory_hint(struct wiphy *wiphy, const char *alpha2,
632 struct ieee80211_regdomain *rd)
633{
634 int r;
635 BUG_ON(!rd && !alpha2);
636
637 mutex_lock(&cfg80211_drv_mutex);
638
639 r = __regulatory_hint(wiphy, REGDOM_SET_BY_DRIVER, alpha2, rd);
640 if (r || !rd)
641 goto unlock_and_exit;
642
643 /* If the driver passed a regulatory domain we skipped asking
644 * userspace for one so we can now go ahead and set it */
645 r = set_regdom(rd);
646
647unlock_and_exit:
648 mutex_unlock(&cfg80211_drv_mutex);
649 return r;
650}
651EXPORT_SYMBOL(regulatory_hint);
652
653
654static void print_rd_rules(const struct ieee80211_regdomain *rd)
655{
656 unsigned int i;
657 const struct ieee80211_reg_rule *reg_rule = NULL;
658 const struct ieee80211_freq_range *freq_range = NULL;
659 const struct ieee80211_power_rule *power_rule = NULL;
660
661 printk(KERN_INFO "\t(start_freq - end_freq @ bandwidth), "
662 "(max_antenna_gain, max_eirp)\n");
663
664 for (i = 0; i < rd->n_reg_rules; i++) {
665 reg_rule = &rd->reg_rules[i];
666 freq_range = &reg_rule->freq_range;
667 power_rule = &reg_rule->power_rule;
668
669 /* There may not be documentation for max antenna gain
670 * in certain regions */
671 if (power_rule->max_antenna_gain)
672 printk(KERN_INFO "\t(%d KHz - %d KHz @ %d KHz), "
673 "(%d mBi, %d mBm)\n",
674 freq_range->start_freq_khz,
675 freq_range->end_freq_khz,
676 freq_range->max_bandwidth_khz,
677 power_rule->max_antenna_gain,
678 power_rule->max_eirp);
679 else
680 printk(KERN_INFO "\t(%d KHz - %d KHz @ %d KHz), "
681 "(N/A, %d mBm)\n",
682 freq_range->start_freq_khz,
683 freq_range->end_freq_khz,
684 freq_range->max_bandwidth_khz,
685 power_rule->max_eirp);
686 }
687}
688
689static void print_regdomain(const struct ieee80211_regdomain *rd)
690{
691
692 if (is_world_regdom(rd->alpha2))
693 printk(KERN_INFO "cfg80211: World regulatory "
694 "domain updated:\n");
695 else {
696 if (is_unknown_alpha2(rd->alpha2))
697 printk(KERN_INFO "cfg80211: Regulatory domain "
698 "changed to driver built-in settings "
699 "(unknown country)\n");
700 else
701 printk(KERN_INFO "cfg80211: Regulatory domain "
702 "changed to country: %c%c\n",
703 rd->alpha2[0], rd->alpha2[1]);
704 }
705 print_rd_rules(rd);
706}
707
708void print_regdomain_info(const struct ieee80211_regdomain *rd)
709{
710 printk(KERN_INFO "cfg80211: Regulatory domain: %c%c\n",
711 rd->alpha2[0], rd->alpha2[1]);
712 print_rd_rules(rd);
713}
714
715static int __set_regdom(const struct ieee80211_regdomain *rd)
716{
717 struct regulatory_request *request = NULL;
718
719 /* Some basic sanity checks first */
720
721 if (is_world_regdom(rd->alpha2)) {
722 if (WARN_ON(!__reg_is_valid_request(rd->alpha2, &request)))
723 return -EINVAL;
724 update_world_regdomain(rd);
725 return 0;
726 }
727
728 if (!is_alpha2_set(rd->alpha2) && !is_an_alpha2(rd->alpha2) &&
729 !is_unknown_alpha2(rd->alpha2))
730 return -EINVAL;
731
732 if (list_empty(&regulatory_requests))
733 return -EINVAL;
734
735 /* allow overriding the static definitions if CRDA is present */
736 if (!is_old_static_regdom(cfg80211_regdomain) &&
737 !regdom_changed(rd->alpha2))
738 return -EINVAL;
739
740 /* Now lets set the regulatory domain, update all driver channels
741 * and finally inform them of what we have done, in case they want
742 * to review or adjust their own settings based on their own
743 * internal EEPROM data */
744
745 if (WARN_ON(!__reg_is_valid_request(rd->alpha2, &request)))
746 return -EINVAL;
747
748 reset_regdomains();
749
750 /* Country IE parsing coming soon */
751 switch (request->initiator) {
752 case REGDOM_SET_BY_CORE:
753 case REGDOM_SET_BY_DRIVER:
754 case REGDOM_SET_BY_USER:
755 if (!is_valid_rd(rd)) {
756 printk(KERN_ERR "cfg80211: Invalid "
757 "regulatory domain detected:\n");
758 print_regdomain_info(rd);
759 return -EINVAL;
760 }
761 break;
762 case REGDOM_SET_BY_COUNTRY_IE: /* Not yet */
763 WARN_ON(1);
764 default:
765 return -EOPNOTSUPP;
766 }
767
768 /* Tada! */
769 cfg80211_regdomain = rd;
770 request->granted = 1;
771
772 return 0;
773}
774
775
776/* Use this call to set the current regulatory domain. Conflicts with
777 * multiple drivers can be ironed out later. Caller must've already
778 * kmalloc'd the rd structure. If this calls fails you should kfree()
779 * the passed rd. Caller must hold cfg80211_drv_mutex */
780int set_regdom(const struct ieee80211_regdomain *rd)
781{
782 struct regulatory_request *this_request = NULL, *prev_request = NULL;
783 int r;
784
785 if (!list_empty(&regulatory_requests))
786 prev_request = list_first_entry(&regulatory_requests,
787 struct regulatory_request, list);
788
789 /* Note that this doesn't update the wiphys, this is done below */
790 r = __set_regdom(rd);
791 if (r)
792 return r;
793
794 BUG_ON((!__reg_is_valid_request(rd->alpha2, &this_request)));
795
796 /* The initial standard core update of the world regulatory domain, no
797 * need to keep that request info around if it didn't fail. */
798 if (is_world_regdom(rd->alpha2) &&
799 this_request->initiator == REGDOM_SET_BY_CORE &&
800 this_request->granted) {
801 list_del(&this_request->list);
802 kfree(this_request);
803 this_request = NULL;
804 }
805
806 /* Remove old requests, we only leave behind the last one */
807 if (prev_request) {
808 list_del(&prev_request->list);
809 kfree(prev_request);
810 prev_request = NULL;
811 }
812
813 /* This would make this whole thing pointless */
814 BUG_ON(rd != cfg80211_regdomain);
815
816 /* update all wiphys now with the new established regulatory domain */
817 update_all_wiphy_regulatory(this_request->initiator);
818
819 print_regdomain(rd);
820
821 return r;
822}
823
824int regulatory_init(void)
825{
826 int err;
827
828 reg_pdev = platform_device_register_simple("regulatory", 0, NULL, 0);
829 if (IS_ERR(reg_pdev))
830 return PTR_ERR(reg_pdev);
831
832#ifdef CONFIG_WIRELESS_OLD_REGULATORY
833 cfg80211_regdomain = static_regdom(ieee80211_regdom);
834
835 printk(KERN_INFO "cfg80211: Using static regulatory domain info\n");
836 print_regdomain_info(cfg80211_regdomain);
837 /* The old code still requests for a new regdomain and if
838 * you have CRDA you get it updated, otherwise you get
839 * stuck with the static values. We ignore "EU" code as
840 * that is not a valid ISO / IEC 3166 alpha2 */
841 if (ieee80211_regdom[0] != 'E' && ieee80211_regdom[1] != 'U')
842 err = __regulatory_hint(NULL, REGDOM_SET_BY_CORE,
843 ieee80211_regdom, NULL);
844#else
845 cfg80211_regdomain = cfg80211_world_regdom;
846
847 err = __regulatory_hint(NULL, REGDOM_SET_BY_CORE, "00", NULL);
848 if (err)
849 printk(KERN_ERR "cfg80211: calling CRDA failed - "
850 "unable to update world regulatory domain, "
851 "using static definition\n");
852#endif
853
854 return 0;
855}
856
857void regulatory_exit(void)
858{
859 struct regulatory_request *req, *req_tmp;
860
861 mutex_lock(&cfg80211_drv_mutex);
862
863 reset_regdomains();
864
865 list_for_each_entry_safe(req, req_tmp, &regulatory_requests, list) {
866 list_del(&req->list);
867 kfree(req);
868 }
869 platform_device_unregister(reg_pdev);
870
871 mutex_unlock(&cfg80211_drv_mutex);
180} 872}
diff --git a/net/wireless/reg.h b/net/wireless/reg.h
new file mode 100644
index 000000000000..a33362872f3c
--- /dev/null
+++ b/net/wireless/reg.h
@@ -0,0 +1,13 @@
1#ifndef __NET_WIRELESS_REG_H
2#define __NET_WIRELESS_REG_H
3
4extern struct mutex cfg80211_reg_mutex;
5bool is_world_regdom(const char *alpha2);
6bool reg_is_valid_request(const char *alpha2);
7
8int regulatory_init(void);
9void regulatory_exit(void);
10
11int set_regdom(const struct ieee80211_regdomain *rd);
12
13#endif /* __NET_WIRELESS_REG_H */
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index ac25b4c0e982..dc50f1e71f76 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -27,10 +27,14 @@ static int xfrm_state_check_space(struct xfrm_state *x, struct sk_buff *skb)
27 - skb_headroom(skb); 27 - skb_headroom(skb);
28 int ntail = dst->dev->needed_tailroom - skb_tailroom(skb); 28 int ntail = dst->dev->needed_tailroom - skb_tailroom(skb);
29 29
30 if (nhead > 0 || ntail > 0) 30 if (nhead <= 0) {
31 return pskb_expand_head(skb, nhead, ntail, GFP_ATOMIC); 31 if (ntail <= 0)
32 32 return 0;
33 return 0; 33 nhead = 0;
34 } else if (ntail < 0)
35 ntail = 0;
36
37 return pskb_expand_head(skb, nhead, ntail, GFP_ATOMIC);
34} 38}
35 39
36static int xfrm_output_one(struct sk_buff *skb, int err) 40static int xfrm_output_one(struct sk_buff *skb, int err)
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 841b32a2e680..832b47c1de80 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -34,7 +34,7 @@
34 34
35#include "xfrm_hash.h" 35#include "xfrm_hash.h"
36 36
37int sysctl_xfrm_larval_drop __read_mostly; 37int sysctl_xfrm_larval_drop __read_mostly = 1;
38 38
39#ifdef CONFIG_XFRM_STATISTICS 39#ifdef CONFIG_XFRM_STATISTICS
40DEFINE_SNMP_STAT(struct linux_xfrm_mib, xfrm_statistics) __read_mostly; 40DEFINE_SNMP_STAT(struct linux_xfrm_mib, xfrm_statistics) __read_mostly;
@@ -46,7 +46,7 @@ EXPORT_SYMBOL(xfrm_cfg_mutex);
46 46
47static DEFINE_RWLOCK(xfrm_policy_lock); 47static DEFINE_RWLOCK(xfrm_policy_lock);
48 48
49static struct list_head xfrm_policy_bytype[XFRM_POLICY_TYPE_MAX]; 49static struct list_head xfrm_policy_all;
50unsigned int xfrm_policy_count[XFRM_POLICY_MAX*2]; 50unsigned int xfrm_policy_count[XFRM_POLICY_MAX*2];
51EXPORT_SYMBOL(xfrm_policy_count); 51EXPORT_SYMBOL(xfrm_policy_count);
52 52
@@ -164,7 +164,7 @@ static void xfrm_policy_timer(unsigned long data)
164 164
165 read_lock(&xp->lock); 165 read_lock(&xp->lock);
166 166
167 if (xp->dead) 167 if (xp->walk.dead)
168 goto out; 168 goto out;
169 169
170 dir = xfrm_policy_id2dir(xp->index); 170 dir = xfrm_policy_id2dir(xp->index);
@@ -236,7 +236,7 @@ struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp)
236 policy = kzalloc(sizeof(struct xfrm_policy), gfp); 236 policy = kzalloc(sizeof(struct xfrm_policy), gfp);
237 237
238 if (policy) { 238 if (policy) {
239 INIT_LIST_HEAD(&policy->bytype); 239 INIT_LIST_HEAD(&policy->walk.all);
240 INIT_HLIST_NODE(&policy->bydst); 240 INIT_HLIST_NODE(&policy->bydst);
241 INIT_HLIST_NODE(&policy->byidx); 241 INIT_HLIST_NODE(&policy->byidx);
242 rwlock_init(&policy->lock); 242 rwlock_init(&policy->lock);
@@ -252,17 +252,13 @@ EXPORT_SYMBOL(xfrm_policy_alloc);
252 252
253void xfrm_policy_destroy(struct xfrm_policy *policy) 253void xfrm_policy_destroy(struct xfrm_policy *policy)
254{ 254{
255 BUG_ON(!policy->dead); 255 BUG_ON(!policy->walk.dead);
256 256
257 BUG_ON(policy->bundles); 257 BUG_ON(policy->bundles);
258 258
259 if (del_timer(&policy->timer)) 259 if (del_timer(&policy->timer))
260 BUG(); 260 BUG();
261 261
262 write_lock_bh(&xfrm_policy_lock);
263 list_del(&policy->bytype);
264 write_unlock_bh(&xfrm_policy_lock);
265
266 security_xfrm_policy_free(policy->security); 262 security_xfrm_policy_free(policy->security);
267 kfree(policy); 263 kfree(policy);
268} 264}
@@ -310,8 +306,8 @@ static void xfrm_policy_kill(struct xfrm_policy *policy)
310 int dead; 306 int dead;
311 307
312 write_lock_bh(&policy->lock); 308 write_lock_bh(&policy->lock);
313 dead = policy->dead; 309 dead = policy->walk.dead;
314 policy->dead = 1; 310 policy->walk.dead = 1;
315 write_unlock_bh(&policy->lock); 311 write_unlock_bh(&policy->lock);
316 312
317 if (unlikely(dead)) { 313 if (unlikely(dead)) {
@@ -609,6 +605,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
609 if (delpol) { 605 if (delpol) {
610 hlist_del(&delpol->bydst); 606 hlist_del(&delpol->bydst);
611 hlist_del(&delpol->byidx); 607 hlist_del(&delpol->byidx);
608 list_del(&delpol->walk.all);
612 xfrm_policy_count[dir]--; 609 xfrm_policy_count[dir]--;
613 } 610 }
614 policy->index = delpol ? delpol->index : xfrm_gen_index(policy->type, dir); 611 policy->index = delpol ? delpol->index : xfrm_gen_index(policy->type, dir);
@@ -617,7 +614,7 @@ int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl)
617 policy->curlft.use_time = 0; 614 policy->curlft.use_time = 0;
618 if (!mod_timer(&policy->timer, jiffies + HZ)) 615 if (!mod_timer(&policy->timer, jiffies + HZ))
619 xfrm_pol_hold(policy); 616 xfrm_pol_hold(policy);
620 list_add_tail(&policy->bytype, &xfrm_policy_bytype[policy->type]); 617 list_add(&policy->walk.all, &xfrm_policy_all);
621 write_unlock_bh(&xfrm_policy_lock); 618 write_unlock_bh(&xfrm_policy_lock);
622 619
623 if (delpol) 620 if (delpol)
@@ -684,6 +681,7 @@ struct xfrm_policy *xfrm_policy_bysel_ctx(u8 type, int dir,
684 } 681 }
685 hlist_del(&pol->bydst); 682 hlist_del(&pol->bydst);
686 hlist_del(&pol->byidx); 683 hlist_del(&pol->byidx);
684 list_del(&pol->walk.all);
687 xfrm_policy_count[dir]--; 685 xfrm_policy_count[dir]--;
688 } 686 }
689 ret = pol; 687 ret = pol;
@@ -727,6 +725,7 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete,
727 } 725 }
728 hlist_del(&pol->bydst); 726 hlist_del(&pol->bydst);
729 hlist_del(&pol->byidx); 727 hlist_del(&pol->byidx);
728 list_del(&pol->walk.all);
730 xfrm_policy_count[dir]--; 729 xfrm_policy_count[dir]--;
731 } 730 }
732 ret = pol; 731 ret = pol;
@@ -840,6 +839,7 @@ int xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info)
840 continue; 839 continue;
841 hlist_del(&pol->bydst); 840 hlist_del(&pol->bydst);
842 hlist_del(&pol->byidx); 841 hlist_del(&pol->byidx);
842 list_del(&pol->walk.all);
843 write_unlock_bh(&xfrm_policy_lock); 843 write_unlock_bh(&xfrm_policy_lock);
844 844
845 xfrm_audit_policy_delete(pol, 1, 845 xfrm_audit_policy_delete(pol, 1,
@@ -867,60 +867,68 @@ int xfrm_policy_walk(struct xfrm_policy_walk *walk,
867 int (*func)(struct xfrm_policy *, int, int, void*), 867 int (*func)(struct xfrm_policy *, int, int, void*),
868 void *data) 868 void *data)
869{ 869{
870 struct xfrm_policy *old, *pol, *last = NULL; 870 struct xfrm_policy *pol;
871 struct xfrm_policy_walk_entry *x;
871 int error = 0; 872 int error = 0;
872 873
873 if (walk->type >= XFRM_POLICY_TYPE_MAX && 874 if (walk->type >= XFRM_POLICY_TYPE_MAX &&
874 walk->type != XFRM_POLICY_TYPE_ANY) 875 walk->type != XFRM_POLICY_TYPE_ANY)
875 return -EINVAL; 876 return -EINVAL;
876 877
877 if (walk->policy == NULL && walk->count != 0) 878 if (list_empty(&walk->walk.all) && walk->seq != 0)
878 return 0; 879 return 0;
879 880
880 old = pol = walk->policy; 881 write_lock_bh(&xfrm_policy_lock);
881 walk->policy = NULL; 882 if (list_empty(&walk->walk.all))
882 read_lock_bh(&xfrm_policy_lock); 883 x = list_first_entry(&xfrm_policy_all, struct xfrm_policy_walk_entry, all);
883 884 else
884 for (; walk->cur_type < XFRM_POLICY_TYPE_MAX; walk->cur_type++) { 885 x = list_entry(&walk->walk.all, struct xfrm_policy_walk_entry, all);
885 if (walk->type != walk->cur_type && 886 list_for_each_entry_from(x, &xfrm_policy_all, all) {
886 walk->type != XFRM_POLICY_TYPE_ANY) 887 if (x->dead)
887 continue; 888 continue;
888 889 pol = container_of(x, struct xfrm_policy, walk);
889 if (pol == NULL) { 890 if (walk->type != XFRM_POLICY_TYPE_ANY &&
890 pol = list_first_entry(&xfrm_policy_bytype[walk->cur_type], 891 walk->type != pol->type)
891 struct xfrm_policy, bytype); 892 continue;
892 } 893 error = func(pol, xfrm_policy_id2dir(pol->index),
893 list_for_each_entry_from(pol, &xfrm_policy_bytype[walk->cur_type], bytype) { 894 walk->seq, data);
894 if (pol->dead) 895 if (error) {
895 continue; 896 list_move_tail(&walk->walk.all, &x->all);
896 if (last) { 897 goto out;
897 error = func(last, xfrm_policy_id2dir(last->index),
898 walk->count, data);
899 if (error) {
900 xfrm_pol_hold(last);
901 walk->policy = last;
902 goto out;
903 }
904 }
905 last = pol;
906 walk->count++;
907 } 898 }
908 pol = NULL; 899 walk->seq++;
909 } 900 }
910 if (walk->count == 0) { 901 if (walk->seq == 0) {
911 error = -ENOENT; 902 error = -ENOENT;
912 goto out; 903 goto out;
913 } 904 }
914 if (last) 905 list_del_init(&walk->walk.all);
915 error = func(last, xfrm_policy_id2dir(last->index), 0, data);
916out: 906out:
917 read_unlock_bh(&xfrm_policy_lock); 907 write_unlock_bh(&xfrm_policy_lock);
918 if (old != NULL)
919 xfrm_pol_put(old);
920 return error; 908 return error;
921} 909}
922EXPORT_SYMBOL(xfrm_policy_walk); 910EXPORT_SYMBOL(xfrm_policy_walk);
923 911
912void xfrm_policy_walk_init(struct xfrm_policy_walk *walk, u8 type)
913{
914 INIT_LIST_HEAD(&walk->walk.all);
915 walk->walk.dead = 1;
916 walk->type = type;
917 walk->seq = 0;
918}
919EXPORT_SYMBOL(xfrm_policy_walk_init);
920
921void xfrm_policy_walk_done(struct xfrm_policy_walk *walk)
922{
923 if (list_empty(&walk->walk.all))
924 return;
925
926 write_lock_bh(&xfrm_policy_lock);
927 list_del(&walk->walk.all);
928 write_unlock_bh(&xfrm_policy_lock);
929}
930EXPORT_SYMBOL(xfrm_policy_walk_done);
931
924/* 932/*
925 * Find policy to apply to this flow. 933 * Find policy to apply to this flow.
926 * 934 *
@@ -1077,6 +1085,7 @@ static void __xfrm_policy_link(struct xfrm_policy *pol, int dir)
1077 struct hlist_head *chain = policy_hash_bysel(&pol->selector, 1085 struct hlist_head *chain = policy_hash_bysel(&pol->selector,
1078 pol->family, dir); 1086 pol->family, dir);
1079 1087
1088 list_add(&pol->walk.all, &xfrm_policy_all);
1080 hlist_add_head(&pol->bydst, chain); 1089 hlist_add_head(&pol->bydst, chain);
1081 hlist_add_head(&pol->byidx, xfrm_policy_byidx+idx_hash(pol->index)); 1090 hlist_add_head(&pol->byidx, xfrm_policy_byidx+idx_hash(pol->index));
1082 xfrm_policy_count[dir]++; 1091 xfrm_policy_count[dir]++;
@@ -1094,6 +1103,7 @@ static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol,
1094 1103
1095 hlist_del(&pol->bydst); 1104 hlist_del(&pol->bydst);
1096 hlist_del(&pol->byidx); 1105 hlist_del(&pol->byidx);
1106 list_del(&pol->walk.all);
1097 xfrm_policy_count[dir]--; 1107 xfrm_policy_count[dir]--;
1098 1108
1099 return pol; 1109 return pol;
@@ -1719,7 +1729,7 @@ restart:
1719 1729
1720 for (pi = 0; pi < npols; pi++) { 1730 for (pi = 0; pi < npols; pi++) {
1721 read_lock_bh(&pols[pi]->lock); 1731 read_lock_bh(&pols[pi]->lock);
1722 pol_dead |= pols[pi]->dead; 1732 pol_dead |= pols[pi]->walk.dead;
1723 read_unlock_bh(&pols[pi]->lock); 1733 read_unlock_bh(&pols[pi]->lock);
1724 } 1734 }
1725 1735
@@ -1731,8 +1741,7 @@ restart:
1731 * We can't enlist stable bundles either. 1741 * We can't enlist stable bundles either.
1732 */ 1742 */
1733 write_unlock_bh(&policy->lock); 1743 write_unlock_bh(&policy->lock);
1734 if (dst) 1744 dst_free(dst);
1735 dst_free(dst);
1736 1745
1737 if (pol_dead) 1746 if (pol_dead)
1738 XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLDEAD); 1747 XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLDEAD);
@@ -1748,8 +1757,7 @@ restart:
1748 err = xfrm_dst_update_origin(dst, fl); 1757 err = xfrm_dst_update_origin(dst, fl);
1749 if (unlikely(err)) { 1758 if (unlikely(err)) {
1750 write_unlock_bh(&policy->lock); 1759 write_unlock_bh(&policy->lock);
1751 if (dst) 1760 dst_free(dst);
1752 dst_free(dst);
1753 XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLECHECKERROR); 1761 XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLECHECKERROR);
1754 goto error; 1762 goto error;
1755 } 1763 }
@@ -2416,9 +2424,7 @@ static void __init xfrm_policy_init(void)
2416 panic("XFRM: failed to allocate bydst hash\n"); 2424 panic("XFRM: failed to allocate bydst hash\n");
2417 } 2425 }
2418 2426
2419 for (dir = 0; dir < XFRM_POLICY_TYPE_MAX; dir++) 2427 INIT_LIST_HEAD(&xfrm_policy_all);
2420 INIT_LIST_HEAD(&xfrm_policy_bytype[dir]);
2421
2422 INIT_WORK(&xfrm_policy_gc_work, xfrm_policy_gc_task); 2428 INIT_WORK(&xfrm_policy_gc_work, xfrm_policy_gc_task);
2423 register_netdevice_notifier(&xfrm_dev_notifier); 2429 register_netdevice_notifier(&xfrm_dev_notifier);
2424} 2430}
@@ -2602,7 +2608,7 @@ static int xfrm_policy_migrate(struct xfrm_policy *pol,
2602 int i, j, n = 0; 2608 int i, j, n = 0;
2603 2609
2604 write_lock_bh(&pol->lock); 2610 write_lock_bh(&pol->lock);
2605 if (unlikely(pol->dead)) { 2611 if (unlikely(pol->walk.dead)) {
2606 /* target policy has been deleted */ 2612 /* target policy has been deleted */
2607 write_unlock_bh(&pol->lock); 2613 write_unlock_bh(&pol->lock);
2608 return -ENOENT; 2614 return -ENOENT;
@@ -2673,7 +2679,8 @@ static int xfrm_migrate_check(struct xfrm_migrate *m, int num_migrate)
2673} 2679}
2674 2680
2675int xfrm_migrate(struct xfrm_selector *sel, u8 dir, u8 type, 2681int xfrm_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
2676 struct xfrm_migrate *m, int num_migrate) 2682 struct xfrm_migrate *m, int num_migrate,
2683 struct xfrm_kmaddress *k)
2677{ 2684{
2678 int i, err, nx_cur = 0, nx_new = 0; 2685 int i, err, nx_cur = 0, nx_new = 0;
2679 struct xfrm_policy *pol = NULL; 2686 struct xfrm_policy *pol = NULL;
@@ -2717,7 +2724,7 @@ int xfrm_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
2717 } 2724 }
2718 2725
2719 /* Stage 5 - announce */ 2726 /* Stage 5 - announce */
2720 km_migrate(sel, dir, type, m, num_migrate); 2727 km_migrate(sel, dir, type, m, num_migrate, k);
2721 2728
2722 xfrm_pol_put(pol); 2729 xfrm_pol_put(pol);
2723 2730
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 4c6914ef7d92..508337f97249 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -408,11 +408,10 @@ static void xfrm_state_gc_task(struct work_struct *data)
408 struct hlist_head gc_list; 408 struct hlist_head gc_list;
409 409
410 spin_lock_bh(&xfrm_state_gc_lock); 410 spin_lock_bh(&xfrm_state_gc_lock);
411 gc_list.first = xfrm_state_gc_list.first; 411 hlist_move_list(&xfrm_state_gc_list, &gc_list);
412 INIT_HLIST_HEAD(&xfrm_state_gc_list);
413 spin_unlock_bh(&xfrm_state_gc_lock); 412 spin_unlock_bh(&xfrm_state_gc_lock);
414 413
415 hlist_for_each_entry_safe(x, entry, tmp, &gc_list, bydst) 414 hlist_for_each_entry_safe(x, entry, tmp, &gc_list, gclist)
416 xfrm_state_gc_destroy(x); 415 xfrm_state_gc_destroy(x);
417 416
418 wake_up(&km_waitq); 417 wake_up(&km_waitq);
@@ -514,7 +513,7 @@ struct xfrm_state *xfrm_state_alloc(void)
514 if (x) { 513 if (x) {
515 atomic_set(&x->refcnt, 1); 514 atomic_set(&x->refcnt, 1);
516 atomic_set(&x->tunnel_users, 0); 515 atomic_set(&x->tunnel_users, 0);
517 INIT_LIST_HEAD(&x->all); 516 INIT_LIST_HEAD(&x->km.all);
518 INIT_HLIST_NODE(&x->bydst); 517 INIT_HLIST_NODE(&x->bydst);
519 INIT_HLIST_NODE(&x->bysrc); 518 INIT_HLIST_NODE(&x->bysrc);
520 INIT_HLIST_NODE(&x->byspi); 519 INIT_HLIST_NODE(&x->byspi);
@@ -540,12 +539,8 @@ void __xfrm_state_destroy(struct xfrm_state *x)
540{ 539{
541 WARN_ON(x->km.state != XFRM_STATE_DEAD); 540 WARN_ON(x->km.state != XFRM_STATE_DEAD);
542 541
543 spin_lock_bh(&xfrm_state_lock);
544 list_del(&x->all);
545 spin_unlock_bh(&xfrm_state_lock);
546
547 spin_lock_bh(&xfrm_state_gc_lock); 542 spin_lock_bh(&xfrm_state_gc_lock);
548 hlist_add_head(&x->bydst, &xfrm_state_gc_list); 543 hlist_add_head(&x->gclist, &xfrm_state_gc_list);
549 spin_unlock_bh(&xfrm_state_gc_lock); 544 spin_unlock_bh(&xfrm_state_gc_lock);
550 schedule_work(&xfrm_state_gc_work); 545 schedule_work(&xfrm_state_gc_work);
551} 546}
@@ -558,6 +553,7 @@ int __xfrm_state_delete(struct xfrm_state *x)
558 if (x->km.state != XFRM_STATE_DEAD) { 553 if (x->km.state != XFRM_STATE_DEAD) {
559 x->km.state = XFRM_STATE_DEAD; 554 x->km.state = XFRM_STATE_DEAD;
560 spin_lock(&xfrm_state_lock); 555 spin_lock(&xfrm_state_lock);
556 list_del(&x->km.all);
561 hlist_del(&x->bydst); 557 hlist_del(&x->bydst);
562 hlist_del(&x->bysrc); 558 hlist_del(&x->bysrc);
563 if (x->id.spi) 559 if (x->id.spi)
@@ -780,11 +776,13 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
780{ 776{
781 unsigned int h; 777 unsigned int h;
782 struct hlist_node *entry; 778 struct hlist_node *entry;
783 struct xfrm_state *x, *x0; 779 struct xfrm_state *x, *x0, *to_put;
784 int acquire_in_progress = 0; 780 int acquire_in_progress = 0;
785 int error = 0; 781 int error = 0;
786 struct xfrm_state *best = NULL; 782 struct xfrm_state *best = NULL;
787 783
784 to_put = NULL;
785
788 spin_lock_bh(&xfrm_state_lock); 786 spin_lock_bh(&xfrm_state_lock);
789 h = xfrm_dst_hash(daddr, saddr, tmpl->reqid, family); 787 h = xfrm_dst_hash(daddr, saddr, tmpl->reqid, family);
790 hlist_for_each_entry(x, entry, xfrm_state_bydst+h, bydst) { 788 hlist_for_each_entry(x, entry, xfrm_state_bydst+h, bydst) {
@@ -833,7 +831,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
833 if (tmpl->id.spi && 831 if (tmpl->id.spi &&
834 (x0 = __xfrm_state_lookup(daddr, tmpl->id.spi, 832 (x0 = __xfrm_state_lookup(daddr, tmpl->id.spi,
835 tmpl->id.proto, family)) != NULL) { 833 tmpl->id.proto, family)) != NULL) {
836 xfrm_state_put(x0); 834 to_put = x0;
837 error = -EEXIST; 835 error = -EEXIST;
838 goto out; 836 goto out;
839 } 837 }
@@ -849,13 +847,14 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
849 error = security_xfrm_state_alloc_acquire(x, pol->security, fl->secid); 847 error = security_xfrm_state_alloc_acquire(x, pol->security, fl->secid);
850 if (error) { 848 if (error) {
851 x->km.state = XFRM_STATE_DEAD; 849 x->km.state = XFRM_STATE_DEAD;
852 xfrm_state_put(x); 850 to_put = x;
853 x = NULL; 851 x = NULL;
854 goto out; 852 goto out;
855 } 853 }
856 854
857 if (km_query(x, tmpl, pol) == 0) { 855 if (km_query(x, tmpl, pol) == 0) {
858 x->km.state = XFRM_STATE_ACQ; 856 x->km.state = XFRM_STATE_ACQ;
857 list_add(&x->km.all, &xfrm_state_all);
859 hlist_add_head(&x->bydst, xfrm_state_bydst+h); 858 hlist_add_head(&x->bydst, xfrm_state_bydst+h);
860 h = xfrm_src_hash(daddr, saddr, family); 859 h = xfrm_src_hash(daddr, saddr, family);
861 hlist_add_head(&x->bysrc, xfrm_state_bysrc+h); 860 hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);
@@ -870,7 +869,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
870 xfrm_hash_grow_check(x->bydst.next != NULL); 869 xfrm_hash_grow_check(x->bydst.next != NULL);
871 } else { 870 } else {
872 x->km.state = XFRM_STATE_DEAD; 871 x->km.state = XFRM_STATE_DEAD;
873 xfrm_state_put(x); 872 to_put = x;
874 x = NULL; 873 x = NULL;
875 error = -ESRCH; 874 error = -ESRCH;
876 } 875 }
@@ -881,6 +880,8 @@ out:
881 else 880 else
882 *err = acquire_in_progress ? -EAGAIN : error; 881 *err = acquire_in_progress ? -EAGAIN : error;
883 spin_unlock_bh(&xfrm_state_lock); 882 spin_unlock_bh(&xfrm_state_lock);
883 if (to_put)
884 xfrm_state_put(to_put);
884 return x; 885 return x;
885} 886}
886 887
@@ -922,7 +923,7 @@ static void __xfrm_state_insert(struct xfrm_state *x)
922 923
923 x->genid = ++xfrm_state_genid; 924 x->genid = ++xfrm_state_genid;
924 925
925 list_add_tail(&x->all, &xfrm_state_all); 926 list_add(&x->km.all, &xfrm_state_all);
926 927
927 h = xfrm_dst_hash(&x->id.daddr, &x->props.saddr, 928 h = xfrm_dst_hash(&x->id.daddr, &x->props.saddr,
928 x->props.reqid, x->props.family); 929 x->props.reqid, x->props.family);
@@ -1051,6 +1052,7 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re
1051 xfrm_state_hold(x); 1052 xfrm_state_hold(x);
1052 x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ; 1053 x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ;
1053 add_timer(&x->timer); 1054 add_timer(&x->timer);
1055 list_add(&x->km.all, &xfrm_state_all);
1054 hlist_add_head(&x->bydst, xfrm_state_bydst+h); 1056 hlist_add_head(&x->bydst, xfrm_state_bydst+h);
1055 h = xfrm_src_hash(daddr, saddr, family); 1057 h = xfrm_src_hash(daddr, saddr, family);
1056 hlist_add_head(&x->bysrc, xfrm_state_bysrc+h); 1058 hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);
@@ -1067,18 +1069,20 @@ static struct xfrm_state *__xfrm_find_acq_byseq(u32 seq);
1067 1069
1068int xfrm_state_add(struct xfrm_state *x) 1070int xfrm_state_add(struct xfrm_state *x)
1069{ 1071{
1070 struct xfrm_state *x1; 1072 struct xfrm_state *x1, *to_put;
1071 int family; 1073 int family;
1072 int err; 1074 int err;
1073 int use_spi = xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY); 1075 int use_spi = xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY);
1074 1076
1075 family = x->props.family; 1077 family = x->props.family;
1076 1078
1079 to_put = NULL;
1080
1077 spin_lock_bh(&xfrm_state_lock); 1081 spin_lock_bh(&xfrm_state_lock);
1078 1082
1079 x1 = __xfrm_state_locate(x, use_spi, family); 1083 x1 = __xfrm_state_locate(x, use_spi, family);
1080 if (x1) { 1084 if (x1) {
1081 xfrm_state_put(x1); 1085 to_put = x1;
1082 x1 = NULL; 1086 x1 = NULL;
1083 err = -EEXIST; 1087 err = -EEXIST;
1084 goto out; 1088 goto out;
@@ -1088,7 +1092,7 @@ int xfrm_state_add(struct xfrm_state *x)
1088 x1 = __xfrm_find_acq_byseq(x->km.seq); 1092 x1 = __xfrm_find_acq_byseq(x->km.seq);
1089 if (x1 && ((x1->id.proto != x->id.proto) || 1093 if (x1 && ((x1->id.proto != x->id.proto) ||
1090 xfrm_addr_cmp(&x1->id.daddr, &x->id.daddr, family))) { 1094 xfrm_addr_cmp(&x1->id.daddr, &x->id.daddr, family))) {
1091 xfrm_state_put(x1); 1095 to_put = x1;
1092 x1 = NULL; 1096 x1 = NULL;
1093 } 1097 }
1094 } 1098 }
@@ -1110,6 +1114,9 @@ out:
1110 xfrm_state_put(x1); 1114 xfrm_state_put(x1);
1111 } 1115 }
1112 1116
1117 if (to_put)
1118 xfrm_state_put(to_put);
1119
1113 return err; 1120 return err;
1114} 1121}
1115EXPORT_SYMBOL(xfrm_state_add); 1122EXPORT_SYMBOL(xfrm_state_add);
@@ -1269,10 +1276,12 @@ EXPORT_SYMBOL(xfrm_state_migrate);
1269 1276
1270int xfrm_state_update(struct xfrm_state *x) 1277int xfrm_state_update(struct xfrm_state *x)
1271{ 1278{
1272 struct xfrm_state *x1; 1279 struct xfrm_state *x1, *to_put;
1273 int err; 1280 int err;
1274 int use_spi = xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY); 1281 int use_spi = xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY);
1275 1282
1283 to_put = NULL;
1284
1276 spin_lock_bh(&xfrm_state_lock); 1285 spin_lock_bh(&xfrm_state_lock);
1277 x1 = __xfrm_state_locate(x, use_spi, x->props.family); 1286 x1 = __xfrm_state_locate(x, use_spi, x->props.family);
1278 1287
@@ -1281,7 +1290,7 @@ int xfrm_state_update(struct xfrm_state *x)
1281 goto out; 1290 goto out;
1282 1291
1283 if (xfrm_state_kern(x1)) { 1292 if (xfrm_state_kern(x1)) {
1284 xfrm_state_put(x1); 1293 to_put = x1;
1285 err = -EEXIST; 1294 err = -EEXIST;
1286 goto out; 1295 goto out;
1287 } 1296 }
@@ -1295,6 +1304,9 @@ int xfrm_state_update(struct xfrm_state *x)
1295out: 1304out:
1296 spin_unlock_bh(&xfrm_state_lock); 1305 spin_unlock_bh(&xfrm_state_lock);
1297 1306
1307 if (to_put)
1308 xfrm_state_put(to_put);
1309
1298 if (err) 1310 if (err)
1299 return err; 1311 return err;
1300 1312
@@ -1537,47 +1549,62 @@ int xfrm_state_walk(struct xfrm_state_walk *walk,
1537 int (*func)(struct xfrm_state *, int, void*), 1549 int (*func)(struct xfrm_state *, int, void*),
1538 void *data) 1550 void *data)
1539{ 1551{
1540 struct xfrm_state *old, *x, *last = NULL; 1552 struct xfrm_state *state;
1553 struct xfrm_state_walk *x;
1541 int err = 0; 1554 int err = 0;
1542 1555
1543 if (walk->state == NULL && walk->count != 0) 1556 if (walk->seq != 0 && list_empty(&walk->all))
1544 return 0; 1557 return 0;
1545 1558
1546 old = x = walk->state;
1547 walk->state = NULL;
1548 spin_lock_bh(&xfrm_state_lock); 1559 spin_lock_bh(&xfrm_state_lock);
1549 if (x == NULL) 1560 if (list_empty(&walk->all))
1550 x = list_first_entry(&xfrm_state_all, struct xfrm_state, all); 1561 x = list_first_entry(&xfrm_state_all, struct xfrm_state_walk, all);
1562 else
1563 x = list_entry(&walk->all, struct xfrm_state_walk, all);
1551 list_for_each_entry_from(x, &xfrm_state_all, all) { 1564 list_for_each_entry_from(x, &xfrm_state_all, all) {
1552 if (x->km.state == XFRM_STATE_DEAD) 1565 if (x->state == XFRM_STATE_DEAD)
1553 continue; 1566 continue;
1554 if (!xfrm_id_proto_match(x->id.proto, walk->proto)) 1567 state = container_of(x, struct xfrm_state, km);
1568 if (!xfrm_id_proto_match(state->id.proto, walk->proto))
1555 continue; 1569 continue;
1556 if (last) { 1570 err = func(state, walk->seq, data);
1557 err = func(last, walk->count, data); 1571 if (err) {
1558 if (err) { 1572 list_move_tail(&walk->all, &x->all);
1559 xfrm_state_hold(last); 1573 goto out;
1560 walk->state = last;
1561 goto out;
1562 }
1563 } 1574 }
1564 last = x; 1575 walk->seq++;
1565 walk->count++;
1566 } 1576 }
1567 if (walk->count == 0) { 1577 if (walk->seq == 0) {
1568 err = -ENOENT; 1578 err = -ENOENT;
1569 goto out; 1579 goto out;
1570 } 1580 }
1571 if (last) 1581 list_del_init(&walk->all);
1572 err = func(last, 0, data);
1573out: 1582out:
1574 spin_unlock_bh(&xfrm_state_lock); 1583 spin_unlock_bh(&xfrm_state_lock);
1575 if (old != NULL)
1576 xfrm_state_put(old);
1577 return err; 1584 return err;
1578} 1585}
1579EXPORT_SYMBOL(xfrm_state_walk); 1586EXPORT_SYMBOL(xfrm_state_walk);
1580 1587
1588void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto)
1589{
1590 INIT_LIST_HEAD(&walk->all);
1591 walk->proto = proto;
1592 walk->state = XFRM_STATE_DEAD;
1593 walk->seq = 0;
1594}
1595EXPORT_SYMBOL(xfrm_state_walk_init);
1596
1597void xfrm_state_walk_done(struct xfrm_state_walk *walk)
1598{
1599 if (list_empty(&walk->all))
1600 return;
1601
1602 spin_lock_bh(&xfrm_state_lock);
1603 list_del(&walk->all);
1604 spin_lock_bh(&xfrm_state_lock);
1605}
1606EXPORT_SYMBOL(xfrm_state_walk_done);
1607
1581 1608
1582void xfrm_replay_notify(struct xfrm_state *x, int event) 1609void xfrm_replay_notify(struct xfrm_state *x, int event)
1583{ 1610{
@@ -1787,7 +1814,8 @@ EXPORT_SYMBOL(km_policy_expired);
1787 1814
1788#ifdef CONFIG_XFRM_MIGRATE 1815#ifdef CONFIG_XFRM_MIGRATE
1789int km_migrate(struct xfrm_selector *sel, u8 dir, u8 type, 1816int km_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
1790 struct xfrm_migrate *m, int num_migrate) 1817 struct xfrm_migrate *m, int num_migrate,
1818 struct xfrm_kmaddress *k)
1791{ 1819{
1792 int err = -EINVAL; 1820 int err = -EINVAL;
1793 int ret; 1821 int ret;
@@ -1796,7 +1824,7 @@ int km_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
1796 read_lock(&xfrm_km_lock); 1824 read_lock(&xfrm_km_lock);
1797 list_for_each_entry(km, &xfrm_km_list, list) { 1825 list_for_each_entry(km, &xfrm_km_list, list) {
1798 if (km->migrate) { 1826 if (km->migrate) {
1799 ret = km->migrate(sel, dir, type, m, num_migrate); 1827 ret = km->migrate(sel, dir, type, m, num_migrate, k);
1800 if (!ret) 1828 if (!ret)
1801 err = ret; 1829 err = ret;
1802 } 1830 }
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 04c41504f84c..4a8a1abb59ee 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1102,7 +1102,7 @@ static struct xfrm_policy *xfrm_policy_construct(struct xfrm_userpolicy_info *p,
1102 return xp; 1102 return xp;
1103 error: 1103 error:
1104 *errp = err; 1104 *errp = err;
1105 xp->dead = 1; 1105 xp->walk.dead = 1;
1106 xfrm_policy_destroy(xp); 1106 xfrm_policy_destroy(xp);
1107 return NULL; 1107 return NULL;
1108} 1108}
@@ -1595,7 +1595,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
1595 return -ENOENT; 1595 return -ENOENT;
1596 1596
1597 read_lock(&xp->lock); 1597 read_lock(&xp->lock);
1598 if (xp->dead) { 1598 if (xp->walk.dead) {
1599 read_unlock(&xp->lock); 1599 read_unlock(&xp->lock);
1600 goto out; 1600 goto out;
1601 } 1601 }
@@ -1710,12 +1710,23 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,
1710 1710
1711#ifdef CONFIG_XFRM_MIGRATE 1711#ifdef CONFIG_XFRM_MIGRATE
1712static int copy_from_user_migrate(struct xfrm_migrate *ma, 1712static int copy_from_user_migrate(struct xfrm_migrate *ma,
1713 struct xfrm_kmaddress *k,
1713 struct nlattr **attrs, int *num) 1714 struct nlattr **attrs, int *num)
1714{ 1715{
1715 struct nlattr *rt = attrs[XFRMA_MIGRATE]; 1716 struct nlattr *rt = attrs[XFRMA_MIGRATE];
1716 struct xfrm_user_migrate *um; 1717 struct xfrm_user_migrate *um;
1717 int i, num_migrate; 1718 int i, num_migrate;
1718 1719
1720 if (k != NULL) {
1721 struct xfrm_user_kmaddress *uk;
1722
1723 uk = nla_data(attrs[XFRMA_KMADDRESS]);
1724 memcpy(&k->local, &uk->local, sizeof(k->local));
1725 memcpy(&k->remote, &uk->remote, sizeof(k->remote));
1726 k->family = uk->family;
1727 k->reserved = uk->reserved;
1728 }
1729
1719 um = nla_data(rt); 1730 um = nla_data(rt);
1720 num_migrate = nla_len(rt) / sizeof(*um); 1731 num_migrate = nla_len(rt) / sizeof(*um);
1721 1732
@@ -1745,6 +1756,7 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
1745{ 1756{
1746 struct xfrm_userpolicy_id *pi = nlmsg_data(nlh); 1757 struct xfrm_userpolicy_id *pi = nlmsg_data(nlh);
1747 struct xfrm_migrate m[XFRM_MAX_DEPTH]; 1758 struct xfrm_migrate m[XFRM_MAX_DEPTH];
1759 struct xfrm_kmaddress km, *kmp;
1748 u8 type; 1760 u8 type;
1749 int err; 1761 int err;
1750 int n = 0; 1762 int n = 0;
@@ -1752,19 +1764,20 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
1752 if (attrs[XFRMA_MIGRATE] == NULL) 1764 if (attrs[XFRMA_MIGRATE] == NULL)
1753 return -EINVAL; 1765 return -EINVAL;
1754 1766
1767 kmp = attrs[XFRMA_KMADDRESS] ? &km : NULL;
1768
1755 err = copy_from_user_policy_type(&type, attrs); 1769 err = copy_from_user_policy_type(&type, attrs);
1756 if (err) 1770 if (err)
1757 return err; 1771 return err;
1758 1772
1759 err = copy_from_user_migrate((struct xfrm_migrate *)m, 1773 err = copy_from_user_migrate((struct xfrm_migrate *)m, kmp, attrs, &n);
1760 attrs, &n);
1761 if (err) 1774 if (err)
1762 return err; 1775 return err;
1763 1776
1764 if (!n) 1777 if (!n)
1765 return 0; 1778 return 0;
1766 1779
1767 xfrm_migrate(&pi->sel, pi->dir, type, m, n); 1780 xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp);
1768 1781
1769 return 0; 1782 return 0;
1770} 1783}
@@ -1795,16 +1808,30 @@ static int copy_to_user_migrate(struct xfrm_migrate *m, struct sk_buff *skb)
1795 return nla_put(skb, XFRMA_MIGRATE, sizeof(um), &um); 1808 return nla_put(skb, XFRMA_MIGRATE, sizeof(um), &um);
1796} 1809}
1797 1810
1798static inline size_t xfrm_migrate_msgsize(int num_migrate) 1811static int copy_to_user_kmaddress(struct xfrm_kmaddress *k, struct sk_buff *skb)
1812{
1813 struct xfrm_user_kmaddress uk;
1814
1815 memset(&uk, 0, sizeof(uk));
1816 uk.family = k->family;
1817 uk.reserved = k->reserved;
1818 memcpy(&uk.local, &k->local, sizeof(uk.local));
1819 memcpy(&uk.remote, &k->local, sizeof(uk.remote));
1820
1821 return nla_put(skb, XFRMA_KMADDRESS, sizeof(uk), &uk);
1822}
1823
1824static inline size_t xfrm_migrate_msgsize(int num_migrate, int with_kma)
1799{ 1825{
1800 return NLMSG_ALIGN(sizeof(struct xfrm_userpolicy_id)) 1826 return NLMSG_ALIGN(sizeof(struct xfrm_userpolicy_id))
1801 + nla_total_size(sizeof(struct xfrm_user_migrate) * num_migrate) 1827 + (with_kma ? nla_total_size(sizeof(struct xfrm_kmaddress)) : 0)
1802 + userpolicy_type_attrsize(); 1828 + nla_total_size(sizeof(struct xfrm_user_migrate) * num_migrate)
1829 + userpolicy_type_attrsize();
1803} 1830}
1804 1831
1805static int build_migrate(struct sk_buff *skb, struct xfrm_migrate *m, 1832static int build_migrate(struct sk_buff *skb, struct xfrm_migrate *m,
1806 int num_migrate, struct xfrm_selector *sel, 1833 int num_migrate, struct xfrm_kmaddress *k,
1807 u8 dir, u8 type) 1834 struct xfrm_selector *sel, u8 dir, u8 type)
1808{ 1835{
1809 struct xfrm_migrate *mp; 1836 struct xfrm_migrate *mp;
1810 struct xfrm_userpolicy_id *pol_id; 1837 struct xfrm_userpolicy_id *pol_id;
@@ -1821,6 +1848,9 @@ static int build_migrate(struct sk_buff *skb, struct xfrm_migrate *m,
1821 memcpy(&pol_id->sel, sel, sizeof(pol_id->sel)); 1848 memcpy(&pol_id->sel, sel, sizeof(pol_id->sel));
1822 pol_id->dir = dir; 1849 pol_id->dir = dir;
1823 1850
1851 if (k != NULL && (copy_to_user_kmaddress(k, skb) < 0))
1852 goto nlmsg_failure;
1853
1824 if (copy_to_user_policy_type(type, skb) < 0) 1854 if (copy_to_user_policy_type(type, skb) < 0)
1825 goto nlmsg_failure; 1855 goto nlmsg_failure;
1826 1856
@@ -1836,23 +1866,25 @@ nlmsg_failure:
1836} 1866}
1837 1867
1838static int xfrm_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type, 1868static int xfrm_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
1839 struct xfrm_migrate *m, int num_migrate) 1869 struct xfrm_migrate *m, int num_migrate,
1870 struct xfrm_kmaddress *k)
1840{ 1871{
1841 struct sk_buff *skb; 1872 struct sk_buff *skb;
1842 1873
1843 skb = nlmsg_new(xfrm_migrate_msgsize(num_migrate), GFP_ATOMIC); 1874 skb = nlmsg_new(xfrm_migrate_msgsize(num_migrate, !!k), GFP_ATOMIC);
1844 if (skb == NULL) 1875 if (skb == NULL)
1845 return -ENOMEM; 1876 return -ENOMEM;
1846 1877
1847 /* build migrate */ 1878 /* build migrate */
1848 if (build_migrate(skb, m, num_migrate, sel, dir, type) < 0) 1879 if (build_migrate(skb, m, num_migrate, k, sel, dir, type) < 0)
1849 BUG(); 1880 BUG();
1850 1881
1851 return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_MIGRATE, GFP_ATOMIC); 1882 return nlmsg_multicast(xfrm_nl, skb, 0, XFRMNLGRP_MIGRATE, GFP_ATOMIC);
1852} 1883}
1853#else 1884#else
1854static int xfrm_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type, 1885static int xfrm_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
1855 struct xfrm_migrate *m, int num_migrate) 1886 struct xfrm_migrate *m, int num_migrate,
1887 struct xfrm_kmaddress *k)
1856{ 1888{
1857 return -ENOPROTOOPT; 1889 return -ENOPROTOOPT;
1858} 1890}
@@ -1901,6 +1933,7 @@ static const struct nla_policy xfrma_policy[XFRMA_MAX+1] = {
1901 [XFRMA_COADDR] = { .len = sizeof(xfrm_address_t) }, 1933 [XFRMA_COADDR] = { .len = sizeof(xfrm_address_t) },
1902 [XFRMA_POLICY_TYPE] = { .len = sizeof(struct xfrm_userpolicy_type)}, 1934 [XFRMA_POLICY_TYPE] = { .len = sizeof(struct xfrm_userpolicy_type)},
1903 [XFRMA_MIGRATE] = { .len = sizeof(struct xfrm_user_migrate) }, 1935 [XFRMA_MIGRATE] = { .len = sizeof(struct xfrm_user_migrate) },
1936 [XFRMA_KMADDRESS] = { .len = sizeof(struct xfrm_user_kmaddress) },
1904}; 1937};
1905 1938
1906static struct xfrm_link { 1939static struct xfrm_link {