aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorArjan van de Ven <arjan@linux.intel.com>2008-10-17 12:20:26 -0400
committerArjan van de Ven <arjan@linux.intel.com>2008-10-17 12:20:26 -0400
commit651dab4264e4ba0e563f5ff56f748127246e9065 (patch)
tree016630974bdcb00fe529b673f96d389e0fd6dc94 /net
parent40b8606253552109815786e5d4b0de98782d31f5 (diff)
parent2e532d68a2b3e2aa6b19731501222069735c741c (diff)
Merge commit 'linus/master' into merge-linus
Conflicts: arch/x86/kvm/i8254.c
Diffstat (limited to 'net')
-rw-r--r--net/802/fc.c2
-rw-r--r--net/802/psnap.c2
-rw-r--r--net/8021q/vlan.c1
-rw-r--r--net/8021q/vlan_dev.c3
-rw-r--r--net/9p/client.c12
-rw-r--r--net/9p/conv.c6
-rw-r--r--net/9p/mod.c92
-rw-r--r--net/9p/trans_fd.c106
-rw-r--r--net/9p/trans_virtio.c2
-rw-r--r--net/Kconfig10
-rw-r--r--net/Makefile2
-rw-r--r--net/appletalk/ddp.c4
-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/hidp/core.c214
-rw-r--r--net/bluetooth/hidp/hidp.h2
-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/Kconfig31
-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/datagram.c2
-rw-r--r--net/core/dev.c152
-rw-r--r--net/core/dev_mcast.c2
-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.c3
-rw-r--r--net/core/pktgen.c8
-rw-r--r--net/core/rtnetlink.c15
-rw-r--r--net/core/skb_dma_map.c66
-rw-r--r--net/core/skbuff.c65
-rw-r--r--net/core/sock.c13
-rw-r--r--net/core/stream.c2
-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/decnet/dn_dev.c6
-rw-r--r--net/decnet/sysctl_net_decnet.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/cipso_ipv4.c656
-rw-r--r--net/ipv4/devinet.c7
-rw-r--r--net/ipv4/icmp.c2
-rw-r--r--net/ipv4/igmp.c9
-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_fragment.c2
-rw-r--r--net/ipv4/ip_gre.c487
-rw-r--r--net/ipv4/ip_input.c2
-rw-r--r--net/ipv4/ip_options.c2
-rw-r--r--net/ipv4/ip_output.c4
-rw-r--r--net/ipv4/ip_sockglue.c15
-rw-r--r--net/ipv4/ipip.c2
-rw-r--r--net/ipv4/ipmr.c2
-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.c97
-rw-r--r--net/ipv4/netfilter/nf_nat_core.c169
-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.c41
-rw-r--r--net/ipv4/syncookies.c3
-rw-r--r--net/ipv4/sysctl_net_ipv4.c41
-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.c187
-rw-r--r--net/ipv6/addrconf.c1
-rw-r--r--net/ipv6/af_inet6.c71
-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.c25
-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.c4
-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.c3
-rw-r--r--net/mac80211/debugfs_netdev.c78
-rw-r--r--net/mac80211/debugfs_sta.c24
-rw-r--r--net/mac80211/event.c5
-rw-r--r--net/mac80211/ht.c992
-rw-r--r--net/mac80211/ieee80211_i.h399
-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.c3923
-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.c372
-rw-r--r--net/mac80211/scan.c938
-rw-r--r--net/mac80211/spectmgmt.c86
-rw-r--r--net/mac80211/sta_info.c107
-rw-r--r--net/mac80211/sta_info.h43
-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.c167
-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.c351
-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.c182
-rw-r--r--net/netfilter/nf_conntrack_pptp.c38
-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.c95
-rw-r--r--net/netfilter/nfnetlink.c12
-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/netlabel/Makefile3
-rw-r--r--net/netlabel/netlabel_addrlist.c388
-rw-r--r--net/netlabel/netlabel_addrlist.h189
-rw-r--r--net/netlabel/netlabel_cipso_v4.c136
-rw-r--r--net/netlabel/netlabel_cipso_v4.h10
-rw-r--r--net/netlabel/netlabel_domainhash.c393
-rw-r--r--net/netlabel/netlabel_domainhash.h40
-rw-r--r--net/netlabel/netlabel_kapi.c272
-rw-r--r--net/netlabel/netlabel_mgmt.c410
-rw-r--r--net/netlabel/netlabel_mgmt.h59
-rw-r--r--net/netlabel/netlabel_unlabeled.c456
-rw-r--r--net/netlink/af_netlink.c2
-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.c1
-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_flow.c28
-rw-r--r--net/sched/em_cmp.c9
-rw-r--r--net/sched/sch_dsmark.c8
-rw-r--r--net/sched/sch_generic.c32
-rw-r--r--net/sched/sch_multiq.c477
-rw-r--r--net/sched/sch_netem.c18
-rw-r--r--net/sched/sch_prio.c6
-rw-r--r--net/sched/sch_sfq.c4
-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/clnt.c6
-rw-r--r--net/sunrpc/rpcb_clnt.c121
-rw-r--r--net/sunrpc/svc.c251
-rw-r--r--net/sunrpc/svc_xprt.c39
-rw-r--r--net/sunrpc/svcsock.c17
-rw-r--r--net/sunrpc/xprt.c12
-rw-r--r--net/sunrpc/xprtrdma/rpc_rdma.c33
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_recvfrom.c187
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_sendto.c255
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_transport.c364
-rw-r--r--net/sunrpc/xprtrdma/transport.c41
-rw-r--r--net/sunrpc/xprtrdma/verbs.c741
-rw-r--r--net/sunrpc/xprtrdma/xprt_rdma.h17
-rw-r--r--net/sunrpc/xprtsock.c4
-rw-r--r--net/unix/af_unix.c2
-rw-r--r--net/wireless/Kconfig32
-rw-r--r--net/wireless/core.c49
-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.c117
-rw-r--r--net/xfrm/xfrm_state.c82
-rw-r--r--net/xfrm/xfrm_user.c61
416 files changed, 29078 insertions, 13790 deletions
diff --git a/net/802/fc.c b/net/802/fc.c
index cb3475ea6fd..34cf1ee014b 100644
--- a/net/802/fc.c
+++ b/net/802/fc.c
@@ -82,13 +82,13 @@ static int fc_header(struct sk_buff *skb, struct net_device *dev,
82 82
83static int fc_rebuild_header(struct sk_buff *skb) 83static int fc_rebuild_header(struct sk_buff *skb)
84{ 84{
85#ifdef CONFIG_INET
85 struct fch_hdr *fch=(struct fch_hdr *)skb->data; 86 struct fch_hdr *fch=(struct fch_hdr *)skb->data;
86 struct fcllc *fcllc=(struct fcllc *)(skb->data+sizeof(struct fch_hdr)); 87 struct fcllc *fcllc=(struct fcllc *)(skb->data+sizeof(struct fch_hdr));
87 if(fcllc->ethertype != htons(ETH_P_IP)) { 88 if(fcllc->ethertype != htons(ETH_P_IP)) {
88 printk("fc_rebuild_header: Don't know how to resolve type %04X addresses ?\n", ntohs(fcllc->ethertype)); 89 printk("fc_rebuild_header: Don't know how to resolve type %04X addresses ?\n", ntohs(fcllc->ethertype));
89 return 0; 90 return 0;
90 } 91 }
91#ifdef CONFIG_INET
92 return arp_find(fch->daddr, skb); 92 return arp_find(fch->daddr, skb);
93#else 93#else
94 return 0; 94 return 0;
diff --git a/net/802/psnap.c b/net/802/psnap.c
index b3cfe5a14fc..70980baeb68 100644
--- a/net/802/psnap.c
+++ b/net/802/psnap.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * SNAP data link layer. Derived from 802.2 2 * SNAP data link layer. Derived from 802.2
3 * 3 *
4 * Alan Cox <Alan.Cox@linux.org>, 4 * Alan Cox <alan@lxorguk.ukuu.org.uk>,
5 * from the 802.2 layer by Greg Page. 5 * from the 802.2 layer by Greg Page.
6 * Merged in additions from Greg Page's psnap.c. 6 * Merged in additions from Greg Page's psnap.c.
7 * 7 *
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index b661f47bf10..f0e335aa20d 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 4bf014e51f8..8883e9c8a22 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 2ffe40cf2f0..e053e06028a 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -52,7 +52,7 @@ enum {
52 Opt_err, 52 Opt_err,
53}; 53};
54 54
55static match_table_t tokens = { 55static const match_table_t tokens = {
56 {Opt_msize, "msize=%u"}, 56 {Opt_msize, "msize=%u"},
57 {Opt_legacy, "noextend"}, 57 {Opt_legacy, "noextend"},
58 {Opt_trans, "trans=%s"}, 58 {Opt_trans, "trans=%s"},
@@ -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 44547201f5b..5ad3a3bd73b 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 bdee1fb7cc6..1084feb24cb 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 cdf137af7ad..6dabbdb6665 100644
--- a/net/9p/trans_fd.c
+++ b/net/9p/trans_fd.c
@@ -86,7 +86,7 @@ enum {
86 Opt_port, Opt_rfdno, Opt_wfdno, Opt_err, 86 Opt_port, Opt_rfdno, Opt_wfdno, Opt_err,
87}; 87};
88 88
89static match_table_t tokens = { 89static const match_table_t tokens = {
90 {Opt_port, "port=%u"}, 90 {Opt_port, "port=%u"},
91 {Opt_rfdno, "rfdno=%u"}, 91 {Opt_rfdno, "rfdno=%u"},
92 {Opt_wfdno, "wfdno=%u"}, 92 {Opt_wfdno, "wfdno=%u"},
@@ -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 42adc052b14..94912e077a5 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 7612cc8c337..d789d79551a 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 4f43e7f874f..27d1f10dc0e 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/appletalk/ddp.c b/net/appletalk/ddp.c
index 0c850427a85..d3134e7e6ee 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -2,7 +2,7 @@
2 * DDP: An implementation of the AppleTalk DDP protocol for 2 * DDP: An implementation of the AppleTalk DDP protocol for
3 * Ethernet 'ELAP'. 3 * Ethernet 'ELAP'.
4 * 4 *
5 * Alan Cox <Alan.Cox@linux.org> 5 * Alan Cox <alan@lxorguk.ukuu.org.uk>
6 * 6 *
7 * With more than a little assistance from 7 * With more than a little assistance from
8 * 8 *
@@ -1934,6 +1934,6 @@ static void __exit atalk_exit(void)
1934module_exit(atalk_exit); 1934module_exit(atalk_exit);
1935 1935
1936MODULE_LICENSE("GPL"); 1936MODULE_LICENSE("GPL");
1937MODULE_AUTHOR("Alan Cox <Alan.Cox@linux.org>"); 1937MODULE_AUTHOR("Alan Cox <alan@lxorguk.ukuu.org.uk>");
1938MODULE_DESCRIPTION("AppleTalk 0.20\n"); 1938MODULE_DESCRIPTION("AppleTalk 0.20\n");
1939MODULE_ALIAS_NETPROTO(PF_APPLETALK); 1939MODULE_ALIAS_NETPROTO(PF_APPLETALK);
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index 8d9a6f15888..280de481edc 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 5799fb52365..8f701cde594 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 01c83e2a4c1..28c71574a78 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 cdc7e751ef3..96e4b927325 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 1edfdf4c095..f6348e078aa 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 ca8d05245ca..b7002429f15 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 f5b21cb9369..278a3ace14f 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 0e3db289f4b..ad7a553d771 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/hidp/core.c b/net/bluetooth/hidp/core.c
index 96434d774c8..acdeab3d980 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -578,7 +578,7 @@ static int hidp_session(void *arg)
578 if (session->hid) { 578 if (session->hid) {
579 if (session->hid->claimed & HID_CLAIMED_INPUT) 579 if (session->hid->claimed & HID_CLAIMED_INPUT)
580 hidinput_disconnect(session->hid); 580 hidinput_disconnect(session->hid);
581 hid_free_device(session->hid); 581 hid_destroy_device(session->hid);
582 } 582 }
583 583
584 /* Wakeup user-space polling for socket errors */ 584 /* Wakeup user-space polling for socket errors */
@@ -623,9 +623,15 @@ static struct device *hidp_get_device(struct hidp_session *session)
623static int hidp_setup_input(struct hidp_session *session, 623static int hidp_setup_input(struct hidp_session *session,
624 struct hidp_connadd_req *req) 624 struct hidp_connadd_req *req)
625{ 625{
626 struct input_dev *input = session->input; 626 struct input_dev *input;
627 int i; 627 int i;
628 628
629 input = input_allocate_device();
630 if (!input)
631 return -ENOMEM;
632
633 session->input = input;
634
629 input_set_drvdata(input, session); 635 input_set_drvdata(input, session);
630 636
631 input->name = "Bluetooth HID Boot Protocol Device"; 637 input->name = "Bluetooth HID Boot Protocol Device";
@@ -677,67 +683,114 @@ static void hidp_close(struct hid_device *hid)
677{ 683{
678} 684}
679 685
680static const struct { 686static int hidp_parse(struct hid_device *hid)
681 __u16 idVendor; 687{
682 __u16 idProduct; 688 struct hidp_session *session = hid->driver_data;
683 unsigned quirks; 689 struct hidp_connadd_req *req = session->req;
684} hidp_blacklist[] = { 690 unsigned char *buf;
685 /* Apple wireless Mighty Mouse */ 691 int ret;
686 { 0x05ac, 0x030c, HID_QUIRK_MIGHTYMOUSE | HID_QUIRK_INVERT_HWHEEL },
687 692
688 { } /* Terminating entry */ 693 buf = kmalloc(req->rd_size, GFP_KERNEL);
689}; 694 if (!buf)
695 return -ENOMEM;
696
697 if (copy_from_user(buf, req->rd_data, req->rd_size)) {
698 kfree(buf);
699 return -EFAULT;
700 }
701
702 ret = hid_parse_report(session->hid, buf, req->rd_size);
703
704 kfree(buf);
705
706 if (ret)
707 return ret;
708
709 session->req = NULL;
710
711 return 0;
712}
713
714static int hidp_start(struct hid_device *hid)
715{
716 struct hidp_session *session = hid->driver_data;
717 struct hid_report *report;
690 718
691static void hidp_setup_quirks(struct hid_device *hid) 719 list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].
720 report_list, list)
721 hidp_send_report(session, report);
722
723 list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].
724 report_list, list)
725 hidp_send_report(session, report);
726
727 return 0;
728}
729
730static void hidp_stop(struct hid_device *hid)
692{ 731{
693 unsigned int n; 732 struct hidp_session *session = hid->driver_data;
733
734 skb_queue_purge(&session->ctrl_transmit);
735 skb_queue_purge(&session->intr_transmit);
694 736
695 for (n = 0; hidp_blacklist[n].idVendor; n++) 737 if (hid->claimed & HID_CLAIMED_INPUT)
696 if (hidp_blacklist[n].idVendor == le16_to_cpu(hid->vendor) && 738 hidinput_disconnect(hid);
697 hidp_blacklist[n].idProduct == le16_to_cpu(hid->product)) 739 hid->claimed = 0;
698 hid->quirks = hidp_blacklist[n].quirks;
699} 740}
700 741
701static void hidp_setup_hid(struct hidp_session *session, 742static struct hid_ll_driver hidp_hid_driver = {
743 .parse = hidp_parse,
744 .start = hidp_start,
745 .stop = hidp_stop,
746 .open = hidp_open,
747 .close = hidp_close,
748 .hidinput_input_event = hidp_hidinput_event,
749};
750
751static int hidp_setup_hid(struct hidp_session *session,
702 struct hidp_connadd_req *req) 752 struct hidp_connadd_req *req)
703{ 753{
704 struct hid_device *hid = session->hid; 754 struct hid_device *hid;
705 struct hid_report *report;
706 bdaddr_t src, dst; 755 bdaddr_t src, dst;
756 int ret;
707 757
708 baswap(&src, &bt_sk(session->ctrl_sock->sk)->src); 758 hid = hid_allocate_device();
709 baswap(&dst, &bt_sk(session->ctrl_sock->sk)->dst); 759 if (IS_ERR(hid)) {
760 ret = PTR_ERR(session->hid);
761 goto err;
762 }
710 763
764 session->hid = hid;
765 session->req = req;
711 hid->driver_data = session; 766 hid->driver_data = session;
712 767
713 hid->country = req->country; 768 baswap(&src, &bt_sk(session->ctrl_sock->sk)->src);
769 baswap(&dst, &bt_sk(session->ctrl_sock->sk)->dst);
714 770
715 hid->bus = BUS_BLUETOOTH; 771 hid->bus = BUS_BLUETOOTH;
716 hid->vendor = req->vendor; 772 hid->vendor = req->vendor;
717 hid->product = req->product; 773 hid->product = req->product;
718 hid->version = req->version; 774 hid->version = req->version;
775 hid->country = req->country;
719 776
720 strncpy(hid->name, req->name, 128); 777 strncpy(hid->name, req->name, 128);
721 strncpy(hid->phys, batostr(&src), 64); 778 strncpy(hid->phys, batostr(&src), 64);
722 strncpy(hid->uniq, batostr(&dst), 64); 779 strncpy(hid->uniq, batostr(&dst), 64);
723 780
724 hid->dev = hidp_get_device(session); 781 hid->dev.parent = hidp_get_device(session);
725 782 hid->ll_driver = &hidp_hid_driver;
726 hid->hid_open = hidp_open;
727 hid->hid_close = hidp_close;
728
729 hid->hidinput_input_event = hidp_hidinput_event;
730 783
731 hidp_setup_quirks(hid); 784 ret = hid_add_device(hid);
785 if (ret)
786 goto err_hid;
732 787
733 list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].report_list, list) 788 return 0;
734 hidp_send_report(session, report); 789err_hid:
735 790 hid_destroy_device(hid);
736 list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list) 791 session->hid = NULL;
737 hidp_send_report(session, report); 792err:
738 793 return ret;
739 if (hidinput_connect(hid) == 0)
740 hid->claimed |= HID_CLAIMED_INPUT;
741} 794}
742 795
743int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock) 796int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock)
@@ -757,38 +810,6 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
757 810
758 BT_DBG("rd_data %p rd_size %d", req->rd_data, req->rd_size); 811 BT_DBG("rd_data %p rd_size %d", req->rd_data, req->rd_size);
759 812
760 if (req->rd_size > 0) {
761 unsigned char *buf = kmalloc(req->rd_size, GFP_KERNEL);
762
763 if (!buf) {
764 kfree(session);
765 return -ENOMEM;
766 }
767
768 if (copy_from_user(buf, req->rd_data, req->rd_size)) {
769 kfree(buf);
770 kfree(session);
771 return -EFAULT;
772 }
773
774 session->hid = hid_parse_report(buf, req->rd_size);
775
776 kfree(buf);
777
778 if (!session->hid) {
779 kfree(session);
780 return -EINVAL;
781 }
782 }
783
784 if (!session->hid) {
785 session->input = input_allocate_device();
786 if (!session->input) {
787 kfree(session);
788 return -ENOMEM;
789 }
790 }
791
792 down_write(&hidp_session_sem); 813 down_write(&hidp_session_sem);
793 814
794 s = __hidp_get_session(&bt_sk(ctrl_sock->sk)->dst); 815 s = __hidp_get_session(&bt_sk(ctrl_sock->sk)->dst);
@@ -816,15 +837,18 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock,
816 session->flags = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID); 837 session->flags = req->flags & (1 << HIDP_BLUETOOTH_VENDOR_ID);
817 session->idle_to = req->idle_to; 838 session->idle_to = req->idle_to;
818 839
819 if (session->input) { 840 if (req->rd_size > 0) {
841 err = hidp_setup_hid(session, req);
842 if (err && err != -ENODEV)
843 goto err_skb;
844 }
845
846 if (!session->hid) {
820 err = hidp_setup_input(session, req); 847 err = hidp_setup_input(session, req);
821 if (err < 0) 848 if (err < 0)
822 goto failed; 849 goto err_skb;
823 } 850 }
824 851
825 if (session->hid)
826 hidp_setup_hid(session, req);
827
828 __hidp_link_session(session); 852 __hidp_link_session(session);
829 853
830 hidp_set_timer(session); 854 hidp_set_timer(session);
@@ -850,17 +874,16 @@ unlink:
850 874
851 __hidp_unlink_session(session); 875 __hidp_unlink_session(session);
852 876
853 if (session->input) { 877 if (session->input)
854 input_unregister_device(session->input); 878 input_unregister_device(session->input);
855 session->input = NULL; /* don't try to free it here */ 879 if (session->hid)
856 } 880 hid_destroy_device(session->hid);
857 881err_skb:
882 skb_queue_purge(&session->ctrl_transmit);
883 skb_queue_purge(&session->intr_transmit);
858failed: 884failed:
859 up_write(&hidp_session_sem); 885 up_write(&hidp_session_sem);
860 886
861 if (session->hid)
862 hid_free_device(session->hid);
863
864 input_free_device(session->input); 887 input_free_device(session->input);
865 kfree(session); 888 kfree(session);
866 return err; 889 return err;
@@ -950,18 +973,43 @@ int hidp_get_conninfo(struct hidp_conninfo *ci)
950 return err; 973 return err;
951} 974}
952 975
976static const struct hid_device_id hidp_table[] = {
977 { HID_BLUETOOTH_DEVICE(HID_ANY_ID, HID_ANY_ID) },
978 { }
979};
980
981static struct hid_driver hidp_driver = {
982 .name = "generic-bluetooth",
983 .id_table = hidp_table,
984};
985
953static int __init hidp_init(void) 986static int __init hidp_init(void)
954{ 987{
988 int ret;
989
955 l2cap_load(); 990 l2cap_load();
956 991
957 BT_INFO("HIDP (Human Interface Emulation) ver %s", VERSION); 992 BT_INFO("HIDP (Human Interface Emulation) ver %s", VERSION);
958 993
959 return hidp_init_sockets(); 994 ret = hid_register_driver(&hidp_driver);
995 if (ret)
996 goto err;
997
998 ret = hidp_init_sockets();
999 if (ret)
1000 goto err_drv;
1001
1002 return 0;
1003err_drv:
1004 hid_unregister_driver(&hidp_driver);
1005err:
1006 return ret;
960} 1007}
961 1008
962static void __exit hidp_exit(void) 1009static void __exit hidp_exit(void)
963{ 1010{
964 hidp_cleanup_sockets(); 1011 hidp_cleanup_sockets();
1012 hid_unregister_driver(&hidp_driver);
965} 1013}
966 1014
967module_init(hidp_init); 1015module_init(hidp_init);
diff --git a/net/bluetooth/hidp/hidp.h b/net/bluetooth/hidp/hidp.h
index 343fb0566b3..e503c89057a 100644
--- a/net/bluetooth/hidp/hidp.h
+++ b/net/bluetooth/hidp/hidp.h
@@ -151,6 +151,8 @@ struct hidp_session {
151 151
152 struct sk_buff_head ctrl_transmit; 152 struct sk_buff_head ctrl_transmit;
153 struct sk_buff_head intr_transmit; 153 struct sk_buff_head intr_transmit;
154
155 struct hidp_connadd_req *req;
154}; 156};
155 157
156static inline void hidp_schedule(struct hidp_session *session) 158static inline void hidp_schedule(struct hidp_session *session)
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index 3396d5bdef1..9610a9c85b9 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 a16011fedc1..0cc91e6da76 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 573acdf6f9f..4d2c1f1cb52 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 4f52c3d50eb..22ba8632196 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 63c18aacde8..573e20f7dba 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 eeee218eed8..6a6433daaf2 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 6a9a6cd74b1..a4abed5b4c4 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 f155e6ce8a2..ba7be195803 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 76340bdd052..763a3ec292e 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 c3dc18ddc04..b6c3b71974d 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 8b200f96f72..81ae40b3f65 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 27d6a511c8c..158dee8b496 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 90947979499..ba6f73eb06c 100644
--- a/net/bridge/netfilter/Kconfig
+++ b/net/bridge/netfilter/Kconfig
@@ -2,21 +2,22 @@
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 depends on BRIDGE && BRIDGE_NETFILTER
8 select NETFILTER_XTABLES
10 help 9 help
11 ebtables is a general, extensible frame/packet identification 10 ebtables is a general, extensible frame/packet identification
12 framework. Say 'Y' or 'M' here if you want to do Ethernet 11 framework. Say 'Y' or 'M' here if you want to do Ethernet
13 filtering/NAT/brouting on the Ethernet bridge. 12 filtering/NAT/brouting on the Ethernet bridge.
13
14if BRIDGE_NF_EBTABLES
15
14# 16#
15# tables 17# tables
16# 18#
17config BRIDGE_EBT_BROUTE 19config BRIDGE_EBT_BROUTE
18 tristate "ebt: broute table support" 20 tristate "ebt: broute table support"
19 depends on BRIDGE_NF_EBTABLES
20 help 21 help
21 The ebtables broute table is used to define rules that decide between 22 The ebtables broute table is used to define rules that decide between
22 bridging and routing frames, giving Linux the functionality of a 23 bridging and routing frames, giving Linux the functionality of a
@@ -27,7 +28,6 @@ config BRIDGE_EBT_BROUTE
27 28
28config BRIDGE_EBT_T_FILTER 29config BRIDGE_EBT_T_FILTER
29 tristate "ebt: filter table support" 30 tristate "ebt: filter table support"
30 depends on BRIDGE_NF_EBTABLES
31 help 31 help
32 The ebtables filter table is used to define frame filtering rules at 32 The ebtables filter table is used to define frame filtering rules at
33 local input, forwarding and local output. See the man page for 33 local input, forwarding and local output. See the man page for
@@ -37,7 +37,6 @@ config BRIDGE_EBT_T_FILTER
37 37
38config BRIDGE_EBT_T_NAT 38config BRIDGE_EBT_T_NAT
39 tristate "ebt: nat table support" 39 tristate "ebt: nat table support"
40 depends on BRIDGE_NF_EBTABLES
41 help 40 help
42 The ebtables nat table is used to define rules that alter the MAC 41 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). 42 source address (MAC SNAT) or the MAC destination address (MAC DNAT).
@@ -49,7 +48,6 @@ config BRIDGE_EBT_T_NAT
49# 48#
50config BRIDGE_EBT_802_3 49config BRIDGE_EBT_802_3
51 tristate "ebt: 802.3 filter support" 50 tristate "ebt: 802.3 filter support"
52 depends on BRIDGE_NF_EBTABLES
53 help 51 help
54 This option adds matching support for 802.3 Ethernet frames. 52 This option adds matching support for 802.3 Ethernet frames.
55 53
@@ -57,7 +55,6 @@ config BRIDGE_EBT_802_3
57 55
58config BRIDGE_EBT_AMONG 56config BRIDGE_EBT_AMONG
59 tristate "ebt: among filter support" 57 tristate "ebt: among filter support"
60 depends on BRIDGE_NF_EBTABLES
61 help 58 help
62 This option adds the among match, which allows matching the MAC source 59 This option adds the among match, which allows matching the MAC source
63 and/or destination address on a list of addresses. Optionally, 60 and/or destination address on a list of addresses. Optionally,
@@ -67,7 +64,6 @@ config BRIDGE_EBT_AMONG
67 64
68config BRIDGE_EBT_ARP 65config BRIDGE_EBT_ARP
69 tristate "ebt: ARP filter support" 66 tristate "ebt: ARP filter support"
70 depends on BRIDGE_NF_EBTABLES
71 help 67 help
72 This option adds the ARP match, which allows ARP and RARP header field 68 This option adds the ARP match, which allows ARP and RARP header field
73 filtering. 69 filtering.
@@ -76,7 +72,6 @@ config BRIDGE_EBT_ARP
76 72
77config BRIDGE_EBT_IP 73config BRIDGE_EBT_IP
78 tristate "ebt: IP filter support" 74 tristate "ebt: IP filter support"
79 depends on BRIDGE_NF_EBTABLES
80 help 75 help
81 This option adds the IP match, which allows basic IP header field 76 This option adds the IP match, which allows basic IP header field
82 filtering. 77 filtering.
@@ -94,7 +89,6 @@ config BRIDGE_EBT_IP6
94 89
95config BRIDGE_EBT_LIMIT 90config BRIDGE_EBT_LIMIT
96 tristate "ebt: limit match support" 91 tristate "ebt: limit match support"
97 depends on BRIDGE_NF_EBTABLES
98 help 92 help
99 This option adds the limit match, which allows you to control 93 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 94 the rate at which a rule can be matched. This match is the
@@ -105,7 +99,6 @@ config BRIDGE_EBT_LIMIT
105 99
106config BRIDGE_EBT_MARK 100config BRIDGE_EBT_MARK
107 tristate "ebt: mark filter support" 101 tristate "ebt: mark filter support"
108 depends on BRIDGE_NF_EBTABLES
109 help 102 help
110 This option adds the mark match, which allows matching frames based on 103 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. 104 the 'nfmark' value in the frame. This can be set by the mark target.
@@ -116,7 +109,6 @@ config BRIDGE_EBT_MARK
116 109
117config BRIDGE_EBT_PKTTYPE 110config BRIDGE_EBT_PKTTYPE
118 tristate "ebt: packet type filter support" 111 tristate "ebt: packet type filter support"
119 depends on BRIDGE_NF_EBTABLES
120 help 112 help
121 This option adds the packet type match, which allows matching on the 113 This option adds the packet type match, which allows matching on the
122 type of packet based on its Ethernet "class" (as determined by 114 type of packet based on its Ethernet "class" (as determined by
@@ -127,7 +119,6 @@ config BRIDGE_EBT_PKTTYPE
127 119
128config BRIDGE_EBT_STP 120config BRIDGE_EBT_STP
129 tristate "ebt: STP filter support" 121 tristate "ebt: STP filter support"
130 depends on BRIDGE_NF_EBTABLES
131 help 122 help
132 This option adds the Spanning Tree Protocol match, which 123 This option adds the Spanning Tree Protocol match, which
133 allows STP header field filtering. 124 allows STP header field filtering.
@@ -136,7 +127,6 @@ config BRIDGE_EBT_STP
136 127
137config BRIDGE_EBT_VLAN 128config BRIDGE_EBT_VLAN
138 tristate "ebt: 802.1Q VLAN filter support" 129 tristate "ebt: 802.1Q VLAN filter support"
139 depends on BRIDGE_NF_EBTABLES
140 help 130 help
141 This option adds the 802.1Q vlan match, which allows the filtering of 131 This option adds the 802.1Q vlan match, which allows the filtering of
142 802.1Q vlan fields. 132 802.1Q vlan fields.
@@ -156,7 +146,6 @@ config BRIDGE_EBT_ARPREPLY
156 146
157config BRIDGE_EBT_DNAT 147config BRIDGE_EBT_DNAT
158 tristate "ebt: dnat target support" 148 tristate "ebt: dnat target support"
159 depends on BRIDGE_NF_EBTABLES
160 help 149 help
161 This option adds the MAC DNAT target, which allows altering the MAC 150 This option adds the MAC DNAT target, which allows altering the MAC
162 destination address of frames. 151 destination address of frames.
@@ -165,7 +154,6 @@ config BRIDGE_EBT_DNAT
165 154
166config BRIDGE_EBT_MARK_T 155config BRIDGE_EBT_MARK_T
167 tristate "ebt: mark target support" 156 tristate "ebt: mark target support"
168 depends on BRIDGE_NF_EBTABLES
169 help 157 help
170 This option adds the mark target, which allows marking frames by 158 This option adds the mark target, which allows marking frames by
171 setting the 'nfmark' value in the frame. 159 setting the 'nfmark' value in the frame.
@@ -176,7 +164,6 @@ config BRIDGE_EBT_MARK_T
176 164
177config BRIDGE_EBT_REDIRECT 165config BRIDGE_EBT_REDIRECT
178 tristate "ebt: redirect target support" 166 tristate "ebt: redirect target support"
179 depends on BRIDGE_NF_EBTABLES
180 help 167 help
181 This option adds the MAC redirect target, which allows altering the MAC 168 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. 169 destination address of a frame to that of the device it arrived on.
@@ -185,7 +172,6 @@ config BRIDGE_EBT_REDIRECT
185 172
186config BRIDGE_EBT_SNAT 173config BRIDGE_EBT_SNAT
187 tristate "ebt: snat target support" 174 tristate "ebt: snat target support"
188 depends on BRIDGE_NF_EBTABLES
189 help 175 help
190 This option adds the MAC SNAT target, which allows altering the MAC 176 This option adds the MAC SNAT target, which allows altering the MAC
191 source address of frames. 177 source address of frames.
@@ -196,7 +182,6 @@ config BRIDGE_EBT_SNAT
196# 182#
197config BRIDGE_EBT_LOG 183config BRIDGE_EBT_LOG
198 tristate "ebt: log support" 184 tristate "ebt: log support"
199 depends on BRIDGE_NF_EBTABLES
200 help 185 help
201 This option adds the log watcher, that you can use in any rule 186 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 187 in any ebtables table. It records info about the frame header
@@ -206,7 +191,6 @@ config BRIDGE_EBT_LOG
206 191
207config BRIDGE_EBT_ULOG 192config BRIDGE_EBT_ULOG
208 tristate "ebt: ulog support (OBSOLETE)" 193 tristate "ebt: ulog support (OBSOLETE)"
209 depends on BRIDGE_NF_EBTABLES
210 help 194 help
211 This option enables the old bridge-specific "ebt_ulog" implementation 195 This option enables the old bridge-specific "ebt_ulog" implementation
212 which has been obsoleted by the new "nfnetlink_log" code (see 196 which has been obsoleted by the new "nfnetlink_log" code (see
@@ -223,7 +207,6 @@ config BRIDGE_EBT_ULOG
223 207
224config BRIDGE_EBT_NFLOG 208config BRIDGE_EBT_NFLOG
225 tristate "ebt: nflog support" 209 tristate "ebt: nflog support"
226 depends on BRIDGE_NF_EBTABLES
227 help 210 help
228 This option enables the nflog watcher, which allows to LOG 211 This option enables the nflog watcher, which allows to LOG
229 messages through the netfilter logging API, which can use 212 messages through the netfilter logging API, which can use
@@ -235,4 +218,4 @@ config BRIDGE_EBT_NFLOG
235 218
236 To compile it as a module, choose M here. If unsure, say N. 219 To compile it as a module, choose M here. If unsure, say N.
237 220
238endmenu 221endif # BRIDGE_NF_EBTABLES
diff --git a/net/bridge/netfilter/ebt_802_3.c b/net/bridge/netfilter/ebt_802_3.c
index 98534025360..bd91dc58d49 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 70b6dca5ea7..b595f091f35 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 7c535be7566..b7ad60419f9 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 0c4279590fc..76584cd72e5 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 ca64c1cc1b4..6b49ea9e31f 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 65caa00dcf2..d771bbfbcbe 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 36efb3a7524..784a6573876 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 8cbdc01c253..f7bd9192ff0 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 2f430d4ae91..3d33c608906 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 36723f47db0..2fee7e8e2e9 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 9b0a4543861..ea570f214b1 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 8e799aa9e56..2a63d996dd4 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 676db32df3d..883e96e2a54 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 b8afe850cf1..c8a49f7a57b 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 5425333dda0..8d04d4c302b 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 40f36d37607..48527e62162 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 2d4c9ef909f..2c6d6823e70 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 ab60b0dade8..3dddd489328 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 32afff859e4..5bb88eb0aad 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 b1332f6d004..26a37cb3192 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/datagram.c b/net/core/datagram.c
index 52f577a0f54..ee631843c2f 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -9,7 +9,7 @@
9 * identical recvmsg() code. So we share it here. The poll was 9 * identical recvmsg() code. So we share it here. The poll was
10 * shared before but buried in udp.c so I moved it. 10 * shared before but buried in udp.c so I moved it.
11 * 11 *
12 * Authors: Alan Cox <alan@redhat.com>. (datagram_poll() from old 12 * Authors: Alan Cox <alan@lxorguk.ukuu.org.uk>. (datagram_poll() from old
13 * udp.c code) 13 * udp.c code)
14 * 14 *
15 * Fixes: 15 * Fixes:
diff --git a/net/core/dev.c b/net/core/dev.c
index 60c51f76588..1408a083fe4 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/dev_mcast.c b/net/core/dev_mcast.c
index 5402b3b38e0..9e2fa39f22a 100644
--- a/net/core/dev_mcast.c
+++ b/net/core/dev_mcast.c
@@ -6,7 +6,7 @@
6 * Richard Underwood <richard@wuzz.demon.co.uk> 6 * Richard Underwood <richard@wuzz.demon.co.uk>
7 * 7 *
8 * Stir fried together from the IP multicast and CAP patches above 8 * Stir fried together from the IP multicast and CAP patches above
9 * Alan Cox <Alan.Cox@linux.org> 9 * Alan Cox <alan@lxorguk.ukuu.org.uk>
10 * 10 *
11 * Fixes: 11 * Fixes:
12 * Alan Cox : Update the device on a real delete 12 * Alan Cox : Update the device on a real delete
diff --git a/net/core/dst.c b/net/core/dst.c
index fe03266130b..09c1530f468 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 9d92e41826e..1dc728b3858 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 c1f4e0d428c..92d6b946731 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 7c52fe277b6..f1d07b5c1e1 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);
@@ -95,7 +96,7 @@ static void net_free(struct net *net)
95 return; 96 return;
96 } 97 }
97#endif 98#endif
98 99 kfree(net->gen);
99 kmem_cache_free(net_cachep, net); 100 kmem_cache_free(net_cachep, net);
100} 101}
101 102
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index a756847e381..99f656d35b4 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -2474,7 +2474,7 @@ static inline int process_ipsec(struct pktgen_dev *pkt_dev,
2474 if (ret < 0) { 2474 if (ret < 0) {
2475 printk(KERN_ERR "Error expanding " 2475 printk(KERN_ERR "Error expanding "
2476 "ipsec packet %d\n",ret); 2476 "ipsec packet %d\n",ret);
2477 return 0; 2477 goto err;
2478 } 2478 }
2479 } 2479 }
2480 2480
@@ -2484,8 +2484,7 @@ static inline int process_ipsec(struct pktgen_dev *pkt_dev,
2484 if (ret) { 2484 if (ret) {
2485 printk(KERN_ERR "Error creating ipsec " 2485 printk(KERN_ERR "Error creating ipsec "
2486 "packet %d\n",ret); 2486 "packet %d\n",ret);
2487 kfree_skb(skb); 2487 goto err;
2488 return 0;
2489 } 2488 }
2490 /* restore ll */ 2489 /* restore ll */
2491 eth = (__u8 *) skb_push(skb, ETH_HLEN); 2490 eth = (__u8 *) skb_push(skb, ETH_HLEN);
@@ -2494,6 +2493,9 @@ static inline int process_ipsec(struct pktgen_dev *pkt_dev,
2494 } 2493 }
2495 } 2494 }
2496 return 1; 2495 return 1;
2496err:
2497 kfree_skb(skb);
2498 return 0;
2497} 2499}
2498#endif 2500#endif
2499 2501
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 71edb8b3634..3630131fa1f 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 00000000000..86234923a3b
--- /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 ca1ccdf1ef7..4e22e3a3535 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Routines having to do with the 'struct sk_buff' memory handlers. 2 * Routines having to do with the 'struct sk_buff' memory handlers.
3 * 3 *
4 * Authors: Alan Cox <iiitac@pyr.swan.ac.uk> 4 * Authors: Alan Cox <alan@lxorguk.ukuu.org.uk>
5 * Florian La Roche <rzsfl@rz.uni-sb.de> 5 * Florian La Roche <rzsfl@rz.uni-sb.de>
6 * 6 *
7 * Fixes: 7 * Fixes:
@@ -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 91f8bbc9352..5e2a3132a8c 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/core/stream.c b/net/core/stream.c
index a6b3437ff08..8727cead64a 100644
--- a/net/core/stream.c
+++ b/net/core/stream.c
@@ -9,7 +9,7 @@
9 * 9 *
10 * Authors: Arnaldo Carvalho de Melo <acme@conectiva.com.br> 10 * Authors: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
11 * (from old tcp.c code) 11 * (from old tcp.c code)
12 * Alan Cox <alan@redhat.com> (Borrowed comments 8-)) 12 * Alan Cox <alan@lxorguk.ukuu.org.uk> (Borrowed comments 8-))
13 */ 13 */
14 14
15#include <linux/module.h> 15#include <linux/module.h>
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c
index 8e958087421..9a430734530 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 f6756e0c9e6..3b8bd7ca676 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 bcd6ac415bb..5b3ce0688c5 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 97ecec0a8e7..185916218e0 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 803933ab396..779d0ed9ae9 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 882c5c4de69..e3dfddab21c 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 5e1ee0da2c4..11062780bb0 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 dc7c158a2f4..0809b63cb05 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 1ca3b26eed0..d0bd3481976 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/decnet/dn_dev.c b/net/decnet/dn_dev.c
index 2f0ac3c3eb7..8008c861302 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -152,7 +152,7 @@ static struct dn_dev_parms dn_dev_list[] = {
152 152
153#define DN_DEV_LIST_SIZE ARRAY_SIZE(dn_dev_list) 153#define DN_DEV_LIST_SIZE ARRAY_SIZE(dn_dev_list)
154 154
155#define DN_DEV_PARMS_OFFSET(x) ((int) ((char *) &((struct dn_dev_parms *)0)->x)) 155#define DN_DEV_PARMS_OFFSET(x) offsetof(struct dn_dev_parms, x)
156 156
157#ifdef CONFIG_SYSCTL 157#ifdef CONFIG_SYSCTL
158 158
@@ -166,7 +166,7 @@ static int max_priority[] = { 127 }; /* From DECnet spec */
166 166
167static int dn_forwarding_proc(ctl_table *, int, struct file *, 167static int dn_forwarding_proc(ctl_table *, int, struct file *,
168 void __user *, size_t *, loff_t *); 168 void __user *, size_t *, loff_t *);
169static int dn_forwarding_sysctl(ctl_table *table, int __user *name, int nlen, 169static int dn_forwarding_sysctl(ctl_table *table,
170 void __user *oldval, size_t __user *oldlenp, 170 void __user *oldval, size_t __user *oldlenp,
171 void __user *newval, size_t newlen); 171 void __user *newval, size_t newlen);
172 172
@@ -318,7 +318,7 @@ static int dn_forwarding_proc(ctl_table *table, int write,
318#endif 318#endif
319} 319}
320 320
321static int dn_forwarding_sysctl(ctl_table *table, int __user *name, int nlen, 321static int dn_forwarding_sysctl(ctl_table *table,
322 void __user *oldval, size_t __user *oldlenp, 322 void __user *oldval, size_t __user *oldlenp,
323 void __user *newval, size_t newlen) 323 void __user *newval, size_t newlen)
324{ 324{
diff --git a/net/decnet/sysctl_net_decnet.c b/net/decnet/sysctl_net_decnet.c
index 228067c571b..36400b26689 100644
--- a/net/decnet/sysctl_net_decnet.c
+++ b/net/decnet/sysctl_net_decnet.c
@@ -132,7 +132,7 @@ static int parse_addr(__le16 *addr, char *str)
132} 132}
133 133
134 134
135static int dn_node_address_strategy(ctl_table *table, int __user *name, int nlen, 135static int dn_node_address_strategy(ctl_table *table,
136 void __user *oldval, size_t __user *oldlenp, 136 void __user *oldval, size_t __user *oldlenp,
137 void __user *newval, size_t newlen) 137 void __user *newval, size_t newlen)
138{ 138{
@@ -217,7 +217,7 @@ static int dn_node_address_handler(ctl_table *table, int write,
217} 217}
218 218
219 219
220static int dn_def_dev_strategy(ctl_table *table, int __user *name, int nlen, 220static int dn_def_dev_strategy(ctl_table *table,
221 void __user *oldval, size_t __user *oldlenp, 221 void __user *oldval, size_t __user *oldlenp,
222 void __user *newval, size_t newlen) 222 void __user *newval, size_t newlen)
223{ 223{
diff --git a/net/dsa/Kconfig b/net/dsa/Kconfig
new file mode 100644
index 00000000000..49211b35725
--- /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 && !S390
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 00000000000..2374faff4de
--- /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 00000000000..33e99462023
--- /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 00000000000..7063378a1eb
--- /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 00000000000..54068ef251e
--- /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 00000000000..555b164082f
--- /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 00000000000..36e01eb863a
--- /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 00000000000..aa6c609c59f
--- /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 00000000000..eb0e0aaa9f1
--- /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 00000000000..37616884b8a
--- /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 00000000000..bdc0510b53b
--- /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 00000000000..f985ea99384
--- /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 00000000000..d3117764b2c
--- /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 a80839b02e3..b9d85af2dd3 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 3bca97f55d4..949772a5a7d 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 591ea23639c..691268f3a35 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 ad40ef3f9eb..80ff87ce43a 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 8a3ac1fa71a..1fbff5fa424 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/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index 2c0e4572cc9..490e035c6d9 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -13,7 +13,7 @@
13 */ 13 */
14 14
15/* 15/*
16 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 16 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006, 2008
17 * 17 *
18 * This program is free software; you can redistribute it and/or modify 18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by 19 * it under the terms of the GNU General Public License as published by
@@ -47,17 +47,7 @@
47#include <asm/bug.h> 47#include <asm/bug.h>
48#include <asm/unaligned.h> 48#include <asm/unaligned.h>
49 49
50struct cipso_v4_domhsh_entry {
51 char *domain;
52 u32 valid;
53 struct list_head list;
54 struct rcu_head rcu;
55};
56
57/* List of available DOI definitions */ 50/* List of available DOI definitions */
58/* XXX - Updates should be minimal so having a single lock for the
59 * cipso_v4_doi_list and the cipso_v4_doi_list->dom_list should be
60 * okay. */
61/* XXX - This currently assumes a minimal number of different DOIs in use, 51/* XXX - This currently assumes a minimal number of different DOIs in use,
62 * if in practice there are a lot of different DOIs this list should 52 * if in practice there are a lot of different DOIs this list should
63 * probably be turned into a hash table or something similar so we 53 * probably be turned into a hash table or something similar so we
@@ -119,6 +109,19 @@ int cipso_v4_rbm_strictvalid = 1;
119 * be omitted. */ 109 * be omitted. */
120#define CIPSO_V4_TAG_RNG_CAT_MAX 8 110#define CIPSO_V4_TAG_RNG_CAT_MAX 8
121 111
112/* Base length of the local tag (non-standard tag).
113 * Tag definition (may change between kernel versions)
114 *
115 * 0 8 16 24 32
116 * +----------+----------+----------+----------+
117 * | 10000000 | 00000110 | 32-bit secid value |
118 * +----------+----------+----------+----------+
119 * | in (host byte order)|
120 * +----------+----------+
121 *
122 */
123#define CIPSO_V4_TAG_LOC_BLEN 6
124
122/* 125/*
123 * Helper Functions 126 * Helper Functions
124 */ 127 */
@@ -194,25 +197,6 @@ static void cipso_v4_bitmap_setbit(unsigned char *bitmap,
194} 197}
195 198
196/** 199/**
197 * cipso_v4_doi_domhsh_free - Frees a domain list entry
198 * @entry: the entry's RCU field
199 *
200 * Description:
201 * This function is designed to be used as a callback to the call_rcu()
202 * function so that the memory allocated to a domain list entry can be released
203 * safely.
204 *
205 */
206static void cipso_v4_doi_domhsh_free(struct rcu_head *entry)
207{
208 struct cipso_v4_domhsh_entry *ptr;
209
210 ptr = container_of(entry, struct cipso_v4_domhsh_entry, rcu);
211 kfree(ptr->domain);
212 kfree(ptr);
213}
214
215/**
216 * cipso_v4_cache_entry_free - Frees a cache entry 200 * cipso_v4_cache_entry_free - Frees a cache entry
217 * @entry: the entry to free 201 * @entry: the entry to free
218 * 202 *
@@ -457,7 +441,7 @@ static struct cipso_v4_doi *cipso_v4_doi_search(u32 doi)
457 struct cipso_v4_doi *iter; 441 struct cipso_v4_doi *iter;
458 442
459 list_for_each_entry_rcu(iter, &cipso_v4_doi_list, list) 443 list_for_each_entry_rcu(iter, &cipso_v4_doi_list, list)
460 if (iter->doi == doi && iter->valid) 444 if (iter->doi == doi && atomic_read(&iter->refcount))
461 return iter; 445 return iter;
462 return NULL; 446 return NULL;
463} 447}
@@ -496,14 +480,17 @@ int cipso_v4_doi_add(struct cipso_v4_doi *doi_def)
496 if (doi_def->type != CIPSO_V4_MAP_PASS) 480 if (doi_def->type != CIPSO_V4_MAP_PASS)
497 return -EINVAL; 481 return -EINVAL;
498 break; 482 break;
483 case CIPSO_V4_TAG_LOCAL:
484 if (doi_def->type != CIPSO_V4_MAP_LOCAL)
485 return -EINVAL;
486 break;
499 default: 487 default:
500 return -EINVAL; 488 return -EINVAL;
501 } 489 }
502 } 490 }
503 491
504 doi_def->valid = 1; 492 atomic_set(&doi_def->refcount, 1);
505 INIT_RCU_HEAD(&doi_def->rcu); 493 INIT_RCU_HEAD(&doi_def->rcu);
506 INIT_LIST_HEAD(&doi_def->dom_list);
507 494
508 spin_lock(&cipso_v4_doi_list_lock); 495 spin_lock(&cipso_v4_doi_list_lock);
509 if (cipso_v4_doi_search(doi_def->doi) != NULL) 496 if (cipso_v4_doi_search(doi_def->doi) != NULL)
@@ -519,59 +506,129 @@ doi_add_failure:
519} 506}
520 507
521/** 508/**
509 * cipso_v4_doi_free - Frees a DOI definition
510 * @entry: the entry's RCU field
511 *
512 * Description:
513 * This function frees all of the memory associated with a DOI definition.
514 *
515 */
516void cipso_v4_doi_free(struct cipso_v4_doi *doi_def)
517{
518 if (doi_def == NULL)
519 return;
520
521 switch (doi_def->type) {
522 case CIPSO_V4_MAP_TRANS:
523 kfree(doi_def->map.std->lvl.cipso);
524 kfree(doi_def->map.std->lvl.local);
525 kfree(doi_def->map.std->cat.cipso);
526 kfree(doi_def->map.std->cat.local);
527 break;
528 }
529 kfree(doi_def);
530}
531
532/**
533 * cipso_v4_doi_free_rcu - Frees a DOI definition via the RCU pointer
534 * @entry: the entry's RCU field
535 *
536 * Description:
537 * This function is designed to be used as a callback to the call_rcu()
538 * function so that the memory allocated to the DOI definition can be released
539 * safely.
540 *
541 */
542static void cipso_v4_doi_free_rcu(struct rcu_head *entry)
543{
544 struct cipso_v4_doi *doi_def;
545
546 doi_def = container_of(entry, struct cipso_v4_doi, rcu);
547 cipso_v4_doi_free(doi_def);
548}
549
550/**
522 * cipso_v4_doi_remove - Remove an existing DOI from the CIPSO protocol engine 551 * cipso_v4_doi_remove - Remove an existing DOI from the CIPSO protocol engine
523 * @doi: the DOI value 552 * @doi: the DOI value
524 * @audit_secid: the LSM secid to use in the audit message 553 * @audit_secid: the LSM secid to use in the audit message
525 * @callback: the DOI cleanup/free callback
526 * 554 *
527 * Description: 555 * Description:
528 * Removes a DOI definition from the CIPSO engine, @callback is called to 556 * Removes a DOI definition from the CIPSO engine. The NetLabel routines will
529 * free any memory. The NetLabel routines will be called to release their own 557 * be called to release their own LSM domain mappings as well as our own
530 * LSM domain mappings as well as our own domain list. Returns zero on 558 * domain list. Returns zero on success and negative values on failure.
531 * success and negative values on failure.
532 * 559 *
533 */ 560 */
534int cipso_v4_doi_remove(u32 doi, 561int cipso_v4_doi_remove(u32 doi, struct netlbl_audit *audit_info)
535 struct netlbl_audit *audit_info,
536 void (*callback) (struct rcu_head * head))
537{ 562{
538 struct cipso_v4_doi *doi_def; 563 struct cipso_v4_doi *doi_def;
539 struct cipso_v4_domhsh_entry *dom_iter;
540 564
541 spin_lock(&cipso_v4_doi_list_lock); 565 spin_lock(&cipso_v4_doi_list_lock);
542 doi_def = cipso_v4_doi_search(doi); 566 doi_def = cipso_v4_doi_search(doi);
543 if (doi_def != NULL) { 567 if (doi_def == NULL) {
544 doi_def->valid = 0;
545 list_del_rcu(&doi_def->list);
546 spin_unlock(&cipso_v4_doi_list_lock); 568 spin_unlock(&cipso_v4_doi_list_lock);
547 rcu_read_lock(); 569 return -ENOENT;
548 list_for_each_entry_rcu(dom_iter, &doi_def->dom_list, list) 570 }
549 if (dom_iter->valid) 571 if (!atomic_dec_and_test(&doi_def->refcount)) {
550 netlbl_cfg_map_del(dom_iter->domain, 572 spin_unlock(&cipso_v4_doi_list_lock);
551 audit_info); 573 return -EBUSY;
552 rcu_read_unlock();
553 cipso_v4_cache_invalidate();
554 call_rcu(&doi_def->rcu, callback);
555 return 0;
556 } 574 }
575 list_del_rcu(&doi_def->list);
557 spin_unlock(&cipso_v4_doi_list_lock); 576 spin_unlock(&cipso_v4_doi_list_lock);
558 577
559 return -ENOENT; 578 cipso_v4_cache_invalidate();
579 call_rcu(&doi_def->rcu, cipso_v4_doi_free_rcu);
580
581 return 0;
560} 582}
561 583
562/** 584/**
563 * cipso_v4_doi_getdef - Returns a pointer to a valid DOI definition 585 * cipso_v4_doi_getdef - Returns a reference to a valid DOI definition
564 * @doi: the DOI value 586 * @doi: the DOI value
565 * 587 *
566 * Description: 588 * Description:
567 * Searches for a valid DOI definition and if one is found it is returned to 589 * Searches for a valid DOI definition and if one is found it is returned to
568 * the caller. Otherwise NULL is returned. The caller must ensure that 590 * the caller. Otherwise NULL is returned. The caller must ensure that
569 * rcu_read_lock() is held while accessing the returned definition. 591 * rcu_read_lock() is held while accessing the returned definition and the DOI
592 * definition reference count is decremented when the caller is done.
570 * 593 *
571 */ 594 */
572struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi) 595struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi)
573{ 596{
574 return cipso_v4_doi_search(doi); 597 struct cipso_v4_doi *doi_def;
598
599 rcu_read_lock();
600 doi_def = cipso_v4_doi_search(doi);
601 if (doi_def == NULL)
602 goto doi_getdef_return;
603 if (!atomic_inc_not_zero(&doi_def->refcount))
604 doi_def = NULL;
605
606doi_getdef_return:
607 rcu_read_unlock();
608 return doi_def;
609}
610
611/**
612 * cipso_v4_doi_putdef - Releases a reference for the given DOI definition
613 * @doi_def: the DOI definition
614 *
615 * Description:
616 * Releases a DOI definition reference obtained from cipso_v4_doi_getdef().
617 *
618 */
619void cipso_v4_doi_putdef(struct cipso_v4_doi *doi_def)
620{
621 if (doi_def == NULL)
622 return;
623
624 if (!atomic_dec_and_test(&doi_def->refcount))
625 return;
626 spin_lock(&cipso_v4_doi_list_lock);
627 list_del_rcu(&doi_def->list);
628 spin_unlock(&cipso_v4_doi_list_lock);
629
630 cipso_v4_cache_invalidate();
631 call_rcu(&doi_def->rcu, cipso_v4_doi_free_rcu);
575} 632}
576 633
577/** 634/**
@@ -597,7 +654,7 @@ int cipso_v4_doi_walk(u32 *skip_cnt,
597 654
598 rcu_read_lock(); 655 rcu_read_lock();
599 list_for_each_entry_rcu(iter_doi, &cipso_v4_doi_list, list) 656 list_for_each_entry_rcu(iter_doi, &cipso_v4_doi_list, list)
600 if (iter_doi->valid) { 657 if (atomic_read(&iter_doi->refcount) > 0) {
601 if (doi_cnt++ < *skip_cnt) 658 if (doi_cnt++ < *skip_cnt)
602 continue; 659 continue;
603 ret_val = callback(iter_doi, cb_arg); 660 ret_val = callback(iter_doi, cb_arg);
@@ -613,85 +670,6 @@ doi_walk_return:
613 return ret_val; 670 return ret_val;
614} 671}
615 672
616/**
617 * cipso_v4_doi_domhsh_add - Adds a domain entry to a DOI definition
618 * @doi_def: the DOI definition
619 * @domain: the domain to add
620 *
621 * Description:
622 * Adds the @domain to the DOI specified by @doi_def, this function
623 * should only be called by external functions (i.e. NetLabel). This function
624 * does allocate memory. Returns zero on success, negative values on failure.
625 *
626 */
627int cipso_v4_doi_domhsh_add(struct cipso_v4_doi *doi_def, const char *domain)
628{
629 struct cipso_v4_domhsh_entry *iter;
630 struct cipso_v4_domhsh_entry *new_dom;
631
632 new_dom = kzalloc(sizeof(*new_dom), GFP_KERNEL);
633 if (new_dom == NULL)
634 return -ENOMEM;
635 if (domain) {
636 new_dom->domain = kstrdup(domain, GFP_KERNEL);
637 if (new_dom->domain == NULL) {
638 kfree(new_dom);
639 return -ENOMEM;
640 }
641 }
642 new_dom->valid = 1;
643 INIT_RCU_HEAD(&new_dom->rcu);
644
645 spin_lock(&cipso_v4_doi_list_lock);
646 list_for_each_entry(iter, &doi_def->dom_list, list)
647 if (iter->valid &&
648 ((domain != NULL && iter->domain != NULL &&
649 strcmp(iter->domain, domain) == 0) ||
650 (domain == NULL && iter->domain == NULL))) {
651 spin_unlock(&cipso_v4_doi_list_lock);
652 kfree(new_dom->domain);
653 kfree(new_dom);
654 return -EEXIST;
655 }
656 list_add_tail_rcu(&new_dom->list, &doi_def->dom_list);
657 spin_unlock(&cipso_v4_doi_list_lock);
658
659 return 0;
660}
661
662/**
663 * cipso_v4_doi_domhsh_remove - Removes a domain entry from a DOI definition
664 * @doi_def: the DOI definition
665 * @domain: the domain to remove
666 *
667 * Description:
668 * Removes the @domain from the DOI specified by @doi_def, this function
669 * should only be called by external functions (i.e. NetLabel). Returns zero
670 * on success and negative values on error.
671 *
672 */
673int cipso_v4_doi_domhsh_remove(struct cipso_v4_doi *doi_def,
674 const char *domain)
675{
676 struct cipso_v4_domhsh_entry *iter;
677
678 spin_lock(&cipso_v4_doi_list_lock);
679 list_for_each_entry(iter, &doi_def->dom_list, list)
680 if (iter->valid &&
681 ((domain != NULL && iter->domain != NULL &&
682 strcmp(iter->domain, domain) == 0) ||
683 (domain == NULL && iter->domain == NULL))) {
684 iter->valid = 0;
685 list_del_rcu(&iter->list);
686 spin_unlock(&cipso_v4_doi_list_lock);
687 call_rcu(&iter->rcu, cipso_v4_doi_domhsh_free);
688 return 0;
689 }
690 spin_unlock(&cipso_v4_doi_list_lock);
691
692 return -ENOENT;
693}
694
695/* 673/*
696 * Label Mapping Functions 674 * Label Mapping Functions
697 */ 675 */
@@ -712,7 +690,7 @@ static int cipso_v4_map_lvl_valid(const struct cipso_v4_doi *doi_def, u8 level)
712 switch (doi_def->type) { 690 switch (doi_def->type) {
713 case CIPSO_V4_MAP_PASS: 691 case CIPSO_V4_MAP_PASS:
714 return 0; 692 return 0;
715 case CIPSO_V4_MAP_STD: 693 case CIPSO_V4_MAP_TRANS:
716 if (doi_def->map.std->lvl.cipso[level] < CIPSO_V4_INV_LVL) 694 if (doi_def->map.std->lvl.cipso[level] < CIPSO_V4_INV_LVL)
717 return 0; 695 return 0;
718 break; 696 break;
@@ -741,7 +719,7 @@ static int cipso_v4_map_lvl_hton(const struct cipso_v4_doi *doi_def,
741 case CIPSO_V4_MAP_PASS: 719 case CIPSO_V4_MAP_PASS:
742 *net_lvl = host_lvl; 720 *net_lvl = host_lvl;
743 return 0; 721 return 0;
744 case CIPSO_V4_MAP_STD: 722 case CIPSO_V4_MAP_TRANS:
745 if (host_lvl < doi_def->map.std->lvl.local_size && 723 if (host_lvl < doi_def->map.std->lvl.local_size &&
746 doi_def->map.std->lvl.local[host_lvl] < CIPSO_V4_INV_LVL) { 724 doi_def->map.std->lvl.local[host_lvl] < CIPSO_V4_INV_LVL) {
747 *net_lvl = doi_def->map.std->lvl.local[host_lvl]; 725 *net_lvl = doi_def->map.std->lvl.local[host_lvl];
@@ -775,7 +753,7 @@ static int cipso_v4_map_lvl_ntoh(const struct cipso_v4_doi *doi_def,
775 case CIPSO_V4_MAP_PASS: 753 case CIPSO_V4_MAP_PASS:
776 *host_lvl = net_lvl; 754 *host_lvl = net_lvl;
777 return 0; 755 return 0;
778 case CIPSO_V4_MAP_STD: 756 case CIPSO_V4_MAP_TRANS:
779 map_tbl = doi_def->map.std; 757 map_tbl = doi_def->map.std;
780 if (net_lvl < map_tbl->lvl.cipso_size && 758 if (net_lvl < map_tbl->lvl.cipso_size &&
781 map_tbl->lvl.cipso[net_lvl] < CIPSO_V4_INV_LVL) { 759 map_tbl->lvl.cipso[net_lvl] < CIPSO_V4_INV_LVL) {
@@ -812,7 +790,7 @@ static int cipso_v4_map_cat_rbm_valid(const struct cipso_v4_doi *doi_def,
812 switch (doi_def->type) { 790 switch (doi_def->type) {
813 case CIPSO_V4_MAP_PASS: 791 case CIPSO_V4_MAP_PASS:
814 return 0; 792 return 0;
815 case CIPSO_V4_MAP_STD: 793 case CIPSO_V4_MAP_TRANS:
816 cipso_cat_size = doi_def->map.std->cat.cipso_size; 794 cipso_cat_size = doi_def->map.std->cat.cipso_size;
817 cipso_array = doi_def->map.std->cat.cipso; 795 cipso_array = doi_def->map.std->cat.cipso;
818 for (;;) { 796 for (;;) {
@@ -860,7 +838,7 @@ static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def,
860 u32 host_cat_size = 0; 838 u32 host_cat_size = 0;
861 u32 *host_cat_array = NULL; 839 u32 *host_cat_array = NULL;
862 840
863 if (doi_def->type == CIPSO_V4_MAP_STD) { 841 if (doi_def->type == CIPSO_V4_MAP_TRANS) {
864 host_cat_size = doi_def->map.std->cat.local_size; 842 host_cat_size = doi_def->map.std->cat.local_size;
865 host_cat_array = doi_def->map.std->cat.local; 843 host_cat_array = doi_def->map.std->cat.local;
866 } 844 }
@@ -875,7 +853,7 @@ static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def,
875 case CIPSO_V4_MAP_PASS: 853 case CIPSO_V4_MAP_PASS:
876 net_spot = host_spot; 854 net_spot = host_spot;
877 break; 855 break;
878 case CIPSO_V4_MAP_STD: 856 case CIPSO_V4_MAP_TRANS:
879 if (host_spot >= host_cat_size) 857 if (host_spot >= host_cat_size)
880 return -EPERM; 858 return -EPERM;
881 net_spot = host_cat_array[host_spot]; 859 net_spot = host_cat_array[host_spot];
@@ -921,7 +899,7 @@ static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def,
921 u32 net_cat_size = 0; 899 u32 net_cat_size = 0;
922 u32 *net_cat_array = NULL; 900 u32 *net_cat_array = NULL;
923 901
924 if (doi_def->type == CIPSO_V4_MAP_STD) { 902 if (doi_def->type == CIPSO_V4_MAP_TRANS) {
925 net_cat_size = doi_def->map.std->cat.cipso_size; 903 net_cat_size = doi_def->map.std->cat.cipso_size;
926 net_cat_array = doi_def->map.std->cat.cipso; 904 net_cat_array = doi_def->map.std->cat.cipso;
927 } 905 }
@@ -941,7 +919,7 @@ static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def,
941 case CIPSO_V4_MAP_PASS: 919 case CIPSO_V4_MAP_PASS:
942 host_spot = net_spot; 920 host_spot = net_spot;
943 break; 921 break;
944 case CIPSO_V4_MAP_STD: 922 case CIPSO_V4_MAP_TRANS:
945 if (net_spot >= net_cat_size) 923 if (net_spot >= net_cat_size)
946 return -EPERM; 924 return -EPERM;
947 host_spot = net_cat_array[net_spot]; 925 host_spot = net_cat_array[net_spot];
@@ -1277,7 +1255,7 @@ static int cipso_v4_gentag_rbm(const struct cipso_v4_doi *doi_def,
1277 } else 1255 } else
1278 tag_len = 4; 1256 tag_len = 4;
1279 1257
1280 buffer[0] = 0x01; 1258 buffer[0] = CIPSO_V4_TAG_RBITMAP;
1281 buffer[1] = tag_len; 1259 buffer[1] = tag_len;
1282 buffer[3] = level; 1260 buffer[3] = level;
1283 1261
@@ -1373,7 +1351,7 @@ static int cipso_v4_gentag_enum(const struct cipso_v4_doi *doi_def,
1373 } else 1351 } else
1374 tag_len = 4; 1352 tag_len = 4;
1375 1353
1376 buffer[0] = 0x02; 1354 buffer[0] = CIPSO_V4_TAG_ENUM;
1377 buffer[1] = tag_len; 1355 buffer[1] = tag_len;
1378 buffer[3] = level; 1356 buffer[3] = level;
1379 1357
@@ -1469,7 +1447,7 @@ static int cipso_v4_gentag_rng(const struct cipso_v4_doi *doi_def,
1469 } else 1447 } else
1470 tag_len = 4; 1448 tag_len = 4;
1471 1449
1472 buffer[0] = 0x05; 1450 buffer[0] = CIPSO_V4_TAG_RANGE;
1473 buffer[1] = tag_len; 1451 buffer[1] = tag_len;
1474 buffer[3] = level; 1452 buffer[3] = level;
1475 1453
@@ -1523,6 +1501,54 @@ static int cipso_v4_parsetag_rng(const struct cipso_v4_doi *doi_def,
1523} 1501}
1524 1502
1525/** 1503/**
1504 * cipso_v4_gentag_loc - Generate a CIPSO local tag (non-standard)
1505 * @doi_def: the DOI definition
1506 * @secattr: the security attributes
1507 * @buffer: the option buffer
1508 * @buffer_len: length of buffer in bytes
1509 *
1510 * Description:
1511 * Generate a CIPSO option using the local tag. Returns the size of the tag
1512 * on success, negative values on failure.
1513 *
1514 */
1515static int cipso_v4_gentag_loc(const struct cipso_v4_doi *doi_def,
1516 const struct netlbl_lsm_secattr *secattr,
1517 unsigned char *buffer,
1518 u32 buffer_len)
1519{
1520 if (!(secattr->flags & NETLBL_SECATTR_SECID))
1521 return -EPERM;
1522
1523 buffer[0] = CIPSO_V4_TAG_LOCAL;
1524 buffer[1] = CIPSO_V4_TAG_LOC_BLEN;
1525 *(u32 *)&buffer[2] = secattr->attr.secid;
1526
1527 return CIPSO_V4_TAG_LOC_BLEN;
1528}
1529
1530/**
1531 * cipso_v4_parsetag_loc - Parse a CIPSO local tag
1532 * @doi_def: the DOI definition
1533 * @tag: the CIPSO tag
1534 * @secattr: the security attributes
1535 *
1536 * Description:
1537 * Parse a CIPSO local tag and return the security attributes in @secattr.
1538 * Return zero on success, negatives values on failure.
1539 *
1540 */
1541static int cipso_v4_parsetag_loc(const struct cipso_v4_doi *doi_def,
1542 const unsigned char *tag,
1543 struct netlbl_lsm_secattr *secattr)
1544{
1545 secattr->attr.secid = *(u32 *)&tag[2];
1546 secattr->flags |= NETLBL_SECATTR_SECID;
1547
1548 return 0;
1549}
1550
1551/**
1526 * cipso_v4_validate - Validate a CIPSO option 1552 * cipso_v4_validate - Validate a CIPSO option
1527 * @option: the start of the option, on error it is set to point to the error 1553 * @option: the start of the option, on error it is set to point to the error
1528 * 1554 *
@@ -1541,7 +1567,7 @@ static int cipso_v4_parsetag_rng(const struct cipso_v4_doi *doi_def,
1541 * that is unrecognized." 1567 * that is unrecognized."
1542 * 1568 *
1543 */ 1569 */
1544int cipso_v4_validate(unsigned char **option) 1570int cipso_v4_validate(const struct sk_buff *skb, unsigned char **option)
1545{ 1571{
1546 unsigned char *opt = *option; 1572 unsigned char *opt = *option;
1547 unsigned char *tag; 1573 unsigned char *tag;
@@ -1566,7 +1592,7 @@ int cipso_v4_validate(unsigned char **option)
1566 goto validate_return_locked; 1592 goto validate_return_locked;
1567 } 1593 }
1568 1594
1569 opt_iter = 6; 1595 opt_iter = CIPSO_V4_HDR_LEN;
1570 tag = opt + opt_iter; 1596 tag = opt + opt_iter;
1571 while (opt_iter < opt_len) { 1597 while (opt_iter < opt_len) {
1572 for (tag_iter = 0; doi_def->tags[tag_iter] != tag[0];) 1598 for (tag_iter = 0; doi_def->tags[tag_iter] != tag[0];)
@@ -1584,7 +1610,7 @@ int cipso_v4_validate(unsigned char **option)
1584 1610
1585 switch (tag[0]) { 1611 switch (tag[0]) {
1586 case CIPSO_V4_TAG_RBITMAP: 1612 case CIPSO_V4_TAG_RBITMAP:
1587 if (tag_len < 4) { 1613 if (tag_len < CIPSO_V4_TAG_RBM_BLEN) {
1588 err_offset = opt_iter + 1; 1614 err_offset = opt_iter + 1;
1589 goto validate_return_locked; 1615 goto validate_return_locked;
1590 } 1616 }
@@ -1602,7 +1628,7 @@ int cipso_v4_validate(unsigned char **option)
1602 err_offset = opt_iter + 3; 1628 err_offset = opt_iter + 3;
1603 goto validate_return_locked; 1629 goto validate_return_locked;
1604 } 1630 }
1605 if (tag_len > 4 && 1631 if (tag_len > CIPSO_V4_TAG_RBM_BLEN &&
1606 cipso_v4_map_cat_rbm_valid(doi_def, 1632 cipso_v4_map_cat_rbm_valid(doi_def,
1607 &tag[4], 1633 &tag[4],
1608 tag_len - 4) < 0) { 1634 tag_len - 4) < 0) {
@@ -1612,7 +1638,7 @@ int cipso_v4_validate(unsigned char **option)
1612 } 1638 }
1613 break; 1639 break;
1614 case CIPSO_V4_TAG_ENUM: 1640 case CIPSO_V4_TAG_ENUM:
1615 if (tag_len < 4) { 1641 if (tag_len < CIPSO_V4_TAG_ENUM_BLEN) {
1616 err_offset = opt_iter + 1; 1642 err_offset = opt_iter + 1;
1617 goto validate_return_locked; 1643 goto validate_return_locked;
1618 } 1644 }
@@ -1622,7 +1648,7 @@ int cipso_v4_validate(unsigned char **option)
1622 err_offset = opt_iter + 3; 1648 err_offset = opt_iter + 3;
1623 goto validate_return_locked; 1649 goto validate_return_locked;
1624 } 1650 }
1625 if (tag_len > 4 && 1651 if (tag_len > CIPSO_V4_TAG_ENUM_BLEN &&
1626 cipso_v4_map_cat_enum_valid(doi_def, 1652 cipso_v4_map_cat_enum_valid(doi_def,
1627 &tag[4], 1653 &tag[4],
1628 tag_len - 4) < 0) { 1654 tag_len - 4) < 0) {
@@ -1631,7 +1657,7 @@ int cipso_v4_validate(unsigned char **option)
1631 } 1657 }
1632 break; 1658 break;
1633 case CIPSO_V4_TAG_RANGE: 1659 case CIPSO_V4_TAG_RANGE:
1634 if (tag_len < 4) { 1660 if (tag_len < CIPSO_V4_TAG_RNG_BLEN) {
1635 err_offset = opt_iter + 1; 1661 err_offset = opt_iter + 1;
1636 goto validate_return_locked; 1662 goto validate_return_locked;
1637 } 1663 }
@@ -1641,7 +1667,7 @@ int cipso_v4_validate(unsigned char **option)
1641 err_offset = opt_iter + 3; 1667 err_offset = opt_iter + 3;
1642 goto validate_return_locked; 1668 goto validate_return_locked;
1643 } 1669 }
1644 if (tag_len > 4 && 1670 if (tag_len > CIPSO_V4_TAG_RNG_BLEN &&
1645 cipso_v4_map_cat_rng_valid(doi_def, 1671 cipso_v4_map_cat_rng_valid(doi_def,
1646 &tag[4], 1672 &tag[4],
1647 tag_len - 4) < 0) { 1673 tag_len - 4) < 0) {
@@ -1649,6 +1675,19 @@ int cipso_v4_validate(unsigned char **option)
1649 goto validate_return_locked; 1675 goto validate_return_locked;
1650 } 1676 }
1651 break; 1677 break;
1678 case CIPSO_V4_TAG_LOCAL:
1679 /* This is a non-standard tag that we only allow for
1680 * local connections, so if the incoming interface is
1681 * not the loopback device drop the packet. */
1682 if (!(skb->dev->flags & IFF_LOOPBACK)) {
1683 err_offset = opt_iter;
1684 goto validate_return_locked;
1685 }
1686 if (tag_len != CIPSO_V4_TAG_LOC_BLEN) {
1687 err_offset = opt_iter + 1;
1688 goto validate_return_locked;
1689 }
1690 break;
1652 default: 1691 default:
1653 err_offset = opt_iter; 1692 err_offset = opt_iter;
1654 goto validate_return_locked; 1693 goto validate_return_locked;
@@ -1704,48 +1743,27 @@ void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway)
1704} 1743}
1705 1744
1706/** 1745/**
1707 * cipso_v4_sock_setattr - Add a CIPSO option to a socket 1746 * cipso_v4_genopt - Generate a CIPSO option
1708 * @sk: the socket 1747 * @buf: the option buffer
1748 * @buf_len: the size of opt_buf
1709 * @doi_def: the CIPSO DOI to use 1749 * @doi_def: the CIPSO DOI to use
1710 * @secattr: the specific security attributes of the socket 1750 * @secattr: the security attributes
1711 * 1751 *
1712 * Description: 1752 * Description:
1713 * Set the CIPSO option on the given socket using the DOI definition and 1753 * Generate a CIPSO option using the DOI definition and security attributes
1714 * security attributes passed to the function. This function requires 1754 * passed to the function. Returns the length of the option on success and
1715 * exclusive access to @sk, which means it either needs to be in the 1755 * negative values on failure.
1716 * process of being created or locked. Returns zero on success and negative
1717 * values on failure.
1718 * 1756 *
1719 */ 1757 */
1720int cipso_v4_sock_setattr(struct sock *sk, 1758static int cipso_v4_genopt(unsigned char *buf, u32 buf_len,
1721 const struct cipso_v4_doi *doi_def, 1759 const struct cipso_v4_doi *doi_def,
1722 const struct netlbl_lsm_secattr *secattr) 1760 const struct netlbl_lsm_secattr *secattr)
1723{ 1761{
1724 int ret_val = -EPERM; 1762 int ret_val;
1725 u32 iter; 1763 u32 iter;
1726 unsigned char *buf;
1727 u32 buf_len = 0;
1728 u32 opt_len;
1729 struct ip_options *opt = NULL;
1730 struct inet_sock *sk_inet;
1731 struct inet_connection_sock *sk_conn;
1732 1764
1733 /* In the case of sock_create_lite(), the sock->sk field is not 1765 if (buf_len <= CIPSO_V4_HDR_LEN)
1734 * defined yet but it is not a problem as the only users of these 1766 return -ENOSPC;
1735 * "lite" PF_INET sockets are functions which do an accept() call
1736 * afterwards so we will label the socket as part of the accept(). */
1737 if (sk == NULL)
1738 return 0;
1739
1740 /* We allocate the maximum CIPSO option size here so we are probably
1741 * being a little wasteful, but it makes our life _much_ easier later
1742 * on and after all we are only talking about 40 bytes. */
1743 buf_len = CIPSO_V4_OPT_LEN_MAX;
1744 buf = kmalloc(buf_len, GFP_ATOMIC);
1745 if (buf == NULL) {
1746 ret_val = -ENOMEM;
1747 goto socket_setattr_failure;
1748 }
1749 1767
1750 /* XXX - This code assumes only one tag per CIPSO option which isn't 1768 /* XXX - This code assumes only one tag per CIPSO option which isn't
1751 * really a good assumption to make but since we only support the MAC 1769 * really a good assumption to make but since we only support the MAC
@@ -1772,9 +1790,14 @@ int cipso_v4_sock_setattr(struct sock *sk,
1772 &buf[CIPSO_V4_HDR_LEN], 1790 &buf[CIPSO_V4_HDR_LEN],
1773 buf_len - CIPSO_V4_HDR_LEN); 1791 buf_len - CIPSO_V4_HDR_LEN);
1774 break; 1792 break;
1793 case CIPSO_V4_TAG_LOCAL:
1794 ret_val = cipso_v4_gentag_loc(doi_def,
1795 secattr,
1796 &buf[CIPSO_V4_HDR_LEN],
1797 buf_len - CIPSO_V4_HDR_LEN);
1798 break;
1775 default: 1799 default:
1776 ret_val = -EPERM; 1800 return -EPERM;
1777 goto socket_setattr_failure;
1778 } 1801 }
1779 1802
1780 iter++; 1803 iter++;
@@ -1782,9 +1805,58 @@ int cipso_v4_sock_setattr(struct sock *sk,
1782 iter < CIPSO_V4_TAG_MAXCNT && 1805 iter < CIPSO_V4_TAG_MAXCNT &&
1783 doi_def->tags[iter] != CIPSO_V4_TAG_INVALID); 1806 doi_def->tags[iter] != CIPSO_V4_TAG_INVALID);
1784 if (ret_val < 0) 1807 if (ret_val < 0)
1785 goto socket_setattr_failure; 1808 return ret_val;
1786 cipso_v4_gentag_hdr(doi_def, buf, ret_val); 1809 cipso_v4_gentag_hdr(doi_def, buf, ret_val);
1787 buf_len = CIPSO_V4_HDR_LEN + ret_val; 1810 return CIPSO_V4_HDR_LEN + ret_val;
1811}
1812
1813/**
1814 * cipso_v4_sock_setattr - Add a CIPSO option to a socket
1815 * @sk: the socket
1816 * @doi_def: the CIPSO DOI to use
1817 * @secattr: the specific security attributes of the socket
1818 *
1819 * Description:
1820 * Set the CIPSO option on the given socket using the DOI definition and
1821 * security attributes passed to the function. This function requires
1822 * exclusive access to @sk, which means it either needs to be in the
1823 * process of being created or locked. Returns zero on success and negative
1824 * values on failure.
1825 *
1826 */
1827int cipso_v4_sock_setattr(struct sock *sk,
1828 const struct cipso_v4_doi *doi_def,
1829 const struct netlbl_lsm_secattr *secattr)
1830{
1831 int ret_val = -EPERM;
1832 unsigned char *buf = NULL;
1833 u32 buf_len;
1834 u32 opt_len;
1835 struct ip_options *opt = NULL;
1836 struct inet_sock *sk_inet;
1837 struct inet_connection_sock *sk_conn;
1838
1839 /* In the case of sock_create_lite(), the sock->sk field is not
1840 * defined yet but it is not a problem as the only users of these
1841 * "lite" PF_INET sockets are functions which do an accept() call
1842 * afterwards so we will label the socket as part of the accept(). */
1843 if (sk == NULL)
1844 return 0;
1845
1846 /* We allocate the maximum CIPSO option size here so we are probably
1847 * being a little wasteful, but it makes our life _much_ easier later
1848 * on and after all we are only talking about 40 bytes. */
1849 buf_len = CIPSO_V4_OPT_LEN_MAX;
1850 buf = kmalloc(buf_len, GFP_ATOMIC);
1851 if (buf == NULL) {
1852 ret_val = -ENOMEM;
1853 goto socket_setattr_failure;
1854 }
1855
1856 ret_val = cipso_v4_genopt(buf, buf_len, doi_def, secattr);
1857 if (ret_val < 0)
1858 goto socket_setattr_failure;
1859 buf_len = ret_val;
1788 1860
1789 /* We can't use ip_options_get() directly because it makes a call to 1861 /* We can't use ip_options_get() directly because it makes a call to
1790 * ip_options_get_alloc() which allocates memory with GFP_KERNEL and 1862 * ip_options_get_alloc() which allocates memory with GFP_KERNEL and
@@ -1822,6 +1894,80 @@ socket_setattr_failure:
1822} 1894}
1823 1895
1824/** 1896/**
1897 * cipso_v4_sock_delattr - Delete the CIPSO option from a socket
1898 * @sk: the socket
1899 *
1900 * Description:
1901 * Removes the CIPSO option from a socket, if present.
1902 *
1903 */
1904void cipso_v4_sock_delattr(struct sock *sk)
1905{
1906 u8 hdr_delta;
1907 struct ip_options *opt;
1908 struct inet_sock *sk_inet;
1909
1910 sk_inet = inet_sk(sk);
1911 opt = sk_inet->opt;
1912 if (opt == NULL || opt->cipso == 0)
1913 return;
1914
1915 if (opt->srr || opt->rr || opt->ts || opt->router_alert) {
1916 u8 cipso_len;
1917 u8 cipso_off;
1918 unsigned char *cipso_ptr;
1919 int iter;
1920 int optlen_new;
1921
1922 cipso_off = opt->cipso - sizeof(struct iphdr);
1923 cipso_ptr = &opt->__data[cipso_off];
1924 cipso_len = cipso_ptr[1];
1925
1926 if (opt->srr > opt->cipso)
1927 opt->srr -= cipso_len;
1928 if (opt->rr > opt->cipso)
1929 opt->rr -= cipso_len;
1930 if (opt->ts > opt->cipso)
1931 opt->ts -= cipso_len;
1932 if (opt->router_alert > opt->cipso)
1933 opt->router_alert -= cipso_len;
1934 opt->cipso = 0;
1935
1936 memmove(cipso_ptr, cipso_ptr + cipso_len,
1937 opt->optlen - cipso_off - cipso_len);
1938
1939 /* determining the new total option length is tricky because of
1940 * the padding necessary, the only thing i can think to do at
1941 * this point is walk the options one-by-one, skipping the
1942 * padding at the end to determine the actual option size and
1943 * from there we can determine the new total option length */
1944 iter = 0;
1945 optlen_new = 0;
1946 while (iter < opt->optlen)
1947 if (opt->__data[iter] != IPOPT_NOP) {
1948 iter += opt->__data[iter + 1];
1949 optlen_new = iter;
1950 } else
1951 iter++;
1952 hdr_delta = opt->optlen;
1953 opt->optlen = (optlen_new + 3) & ~3;
1954 hdr_delta -= opt->optlen;
1955 } else {
1956 /* only the cipso option was present on the socket so we can
1957 * remove the entire option struct */
1958 sk_inet->opt = NULL;
1959 hdr_delta = opt->optlen;
1960 kfree(opt);
1961 }
1962
1963 if (sk_inet->is_icsk && hdr_delta > 0) {
1964 struct inet_connection_sock *sk_conn = inet_csk(sk);
1965 sk_conn->icsk_ext_hdr_len -= hdr_delta;
1966 sk_conn->icsk_sync_mss(sk, sk_conn->icsk_pmtu_cookie);
1967 }
1968}
1969
1970/**
1825 * cipso_v4_getattr - Helper function for the cipso_v4_*_getattr functions 1971 * cipso_v4_getattr - Helper function for the cipso_v4_*_getattr functions
1826 * @cipso: the CIPSO v4 option 1972 * @cipso: the CIPSO v4 option
1827 * @secattr: the security attributes 1973 * @secattr: the security attributes
@@ -1859,6 +2005,9 @@ static int cipso_v4_getattr(const unsigned char *cipso,
1859 case CIPSO_V4_TAG_RANGE: 2005 case CIPSO_V4_TAG_RANGE:
1860 ret_val = cipso_v4_parsetag_rng(doi_def, &cipso[6], secattr); 2006 ret_val = cipso_v4_parsetag_rng(doi_def, &cipso[6], secattr);
1861 break; 2007 break;
2008 case CIPSO_V4_TAG_LOCAL:
2009 ret_val = cipso_v4_parsetag_loc(doi_def, &cipso[6], secattr);
2010 break;
1862 } 2011 }
1863 if (ret_val == 0) 2012 if (ret_val == 0)
1864 secattr->type = NETLBL_NLTYPE_CIPSOV4; 2013 secattr->type = NETLBL_NLTYPE_CIPSOV4;
@@ -1893,6 +2042,123 @@ int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
1893} 2042}
1894 2043
1895/** 2044/**
2045 * cipso_v4_skbuff_setattr - Set the CIPSO option on a packet
2046 * @skb: the packet
2047 * @secattr: the security attributes
2048 *
2049 * Description:
2050 * Set the CIPSO option on the given packet based on the security attributes.
2051 * Returns a pointer to the IP header on success and NULL on failure.
2052 *
2053 */
2054int cipso_v4_skbuff_setattr(struct sk_buff *skb,
2055 const struct cipso_v4_doi *doi_def,
2056 const struct netlbl_lsm_secattr *secattr)
2057{
2058 int ret_val;
2059 struct iphdr *iph;
2060 struct ip_options *opt = &IPCB(skb)->opt;
2061 unsigned char buf[CIPSO_V4_OPT_LEN_MAX];
2062 u32 buf_len = CIPSO_V4_OPT_LEN_MAX;
2063 u32 opt_len;
2064 int len_delta;
2065
2066 buf_len = cipso_v4_genopt(buf, buf_len, doi_def, secattr);
2067 if (buf_len < 0)
2068 return buf_len;
2069 opt_len = (buf_len + 3) & ~3;
2070
2071 /* we overwrite any existing options to ensure that we have enough
2072 * room for the CIPSO option, the reason is that we _need_ to guarantee
2073 * that the security label is applied to the packet - we do the same
2074 * thing when using the socket options and it hasn't caused a problem,
2075 * if we need to we can always revisit this choice later */
2076
2077 len_delta = opt_len - opt->optlen;
2078 /* if we don't ensure enough headroom we could panic on the skb_push()
2079 * call below so make sure we have enough, we are also "mangling" the
2080 * packet so we should probably do a copy-on-write call anyway */
2081 ret_val = skb_cow(skb, skb_headroom(skb) + len_delta);
2082 if (ret_val < 0)
2083 return ret_val;
2084
2085 if (len_delta > 0) {
2086 /* we assume that the header + opt->optlen have already been
2087 * "pushed" in ip_options_build() or similar */
2088 iph = ip_hdr(skb);
2089 skb_push(skb, len_delta);
2090 memmove((char *)iph - len_delta, iph, iph->ihl << 2);
2091 skb_reset_network_header(skb);
2092 iph = ip_hdr(skb);
2093 } else if (len_delta < 0) {
2094 iph = ip_hdr(skb);
2095 memset(iph + 1, IPOPT_NOP, opt->optlen);
2096 } else
2097 iph = ip_hdr(skb);
2098
2099 if (opt->optlen > 0)
2100 memset(opt, 0, sizeof(*opt));
2101 opt->optlen = opt_len;
2102 opt->cipso = sizeof(struct iphdr);
2103 opt->is_changed = 1;
2104
2105 /* we have to do the following because we are being called from a
2106 * netfilter hook which means the packet already has had the header
2107 * fields populated and the checksum calculated - yes this means we
2108 * are doing more work than needed but we do it to keep the core
2109 * stack clean and tidy */
2110 memcpy(iph + 1, buf, buf_len);
2111 if (opt_len > buf_len)
2112 memset((char *)(iph + 1) + buf_len, 0, opt_len - buf_len);
2113 if (len_delta != 0) {
2114 iph->ihl = 5 + (opt_len >> 2);
2115 iph->tot_len = htons(skb->len);
2116 }
2117 ip_send_check(iph);
2118
2119 return 0;
2120}
2121
2122/**
2123 * cipso_v4_skbuff_delattr - Delete any CIPSO options from a packet
2124 * @skb: the packet
2125 *
2126 * Description:
2127 * Removes any and all CIPSO options from the given packet. Returns zero on
2128 * success, negative values on failure.
2129 *
2130 */
2131int cipso_v4_skbuff_delattr(struct sk_buff *skb)
2132{
2133 int ret_val;
2134 struct iphdr *iph;
2135 struct ip_options *opt = &IPCB(skb)->opt;
2136 unsigned char *cipso_ptr;
2137
2138 if (opt->cipso == 0)
2139 return 0;
2140
2141 /* since we are changing the packet we should make a copy */
2142 ret_val = skb_cow(skb, skb_headroom(skb));
2143 if (ret_val < 0)
2144 return ret_val;
2145
2146 /* the easiest thing to do is just replace the cipso option with noop
2147 * options since we don't change the size of the packet, although we
2148 * still need to recalculate the checksum */
2149
2150 iph = ip_hdr(skb);
2151 cipso_ptr = (unsigned char *)iph + opt->cipso;
2152 memset(cipso_ptr, IPOPT_NOOP, cipso_ptr[1]);
2153 opt->cipso = 0;
2154 opt->is_changed = 1;
2155
2156 ip_send_check(iph);
2157
2158 return 0;
2159}
2160
2161/**
1896 * cipso_v4_skbuff_getattr - Get the security attributes from the CIPSO option 2162 * cipso_v4_skbuff_getattr - Get the security attributes from the CIPSO option
1897 * @skb: the packet 2163 * @skb: the packet
1898 * @secattr: the security attributes 2164 * @secattr: the security attributes
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index b12dae2b0b2..5154e729cf1 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1283,7 +1283,7 @@ static int devinet_conf_proc(ctl_table *ctl, int write,
1283 return ret; 1283 return ret;
1284} 1284}
1285 1285
1286static int devinet_conf_sysctl(ctl_table *table, int __user *name, int nlen, 1286static int devinet_conf_sysctl(ctl_table *table,
1287 void __user *oldval, size_t __user *oldlenp, 1287 void __user *oldval, size_t __user *oldlenp,
1288 void __user *newval, size_t newlen) 1288 void __user *newval, size_t newlen)
1289{ 1289{
@@ -1379,12 +1379,11 @@ int ipv4_doint_and_flush(ctl_table *ctl, int write,
1379 return ret; 1379 return ret;
1380} 1380}
1381 1381
1382int ipv4_doint_and_flush_strategy(ctl_table *table, int __user *name, int nlen, 1382int ipv4_doint_and_flush_strategy(ctl_table *table,
1383 void __user *oldval, size_t __user *oldlenp, 1383 void __user *oldval, size_t __user *oldlenp,
1384 void __user *newval, size_t newlen) 1384 void __user *newval, size_t newlen)
1385{ 1385{
1386 int ret = devinet_conf_sysctl(table, name, nlen, oldval, oldlenp, 1386 int ret = devinet_conf_sysctl(table, oldval, oldlenp, newval, newlen);
1387 newval, newlen);
1388 struct net *net = table->extra2; 1387 struct net *net = table->extra2;
1389 1388
1390 if (ret == 1) 1389 if (ret == 1)
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 55c355e6323..72b2de76f1c 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * NET3: Implementation of the ICMP protocol layer. 2 * NET3: Implementation of the ICMP protocol layer.
3 * 3 *
4 * Alan Cox, <alan@redhat.com> 4 * Alan Cox, <alan@lxorguk.ukuu.org.uk>
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License 7 * modify it under the terms of the GNU General Public License
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index f70fac61259..a0d86455c53 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -9,7 +9,7 @@
9 * seems to fall out with gcc 2.6.2. 9 * seems to fall out with gcc 2.6.2.
10 * 10 *
11 * Authors: 11 * Authors:
12 * Alan Cox <Alan.Cox@linux.org> 12 * Alan Cox <alan@lxorguk.ukuu.org.uk>
13 * 13 *
14 * This program is free software; you can redistribute it and/or 14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License 15 * modify it under the terms of the GNU General Public License
@@ -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 0c1ae68ee84..bd1278a2d82 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 c10036e7a46..89cb047ab31 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 d985bd613d2..1c5fd38f882 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_fragment.c b/net/ipv4/ip_fragment.c
index 2152d222b95..e4f81f54bef 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -6,7 +6,7 @@
6 * The IP fragmentation functionality. 6 * The IP fragmentation functionality.
7 * 7 *
8 * Authors: Fred N. van Kempen <waltje@uWalt.NL.Mugnet.ORG> 8 * Authors: Fred N. van Kempen <waltje@uWalt.NL.Mugnet.ORG>
9 * Alan Cox <Alan.Cox@linux.org> 9 * Alan Cox <alan@lxorguk.ukuu.org.uk>
10 * 10 *
11 * Fixes: 11 * Fixes:
12 * Alan Cox : Split from ip.c , see ip_input.c for history. 12 * Alan Cox : Split from ip.c , see ip_input.c for history.
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 2a61158ea72..85c487b8572 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_input.c b/net/ipv4/ip_input.c
index e0bed56c51f..861978a4f1a 100644
--- a/net/ipv4/ip_input.c
+++ b/net/ipv4/ip_input.c
@@ -8,7 +8,7 @@
8 * Authors: Ross Biro 8 * Authors: Ross Biro
9 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 9 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
10 * Donald Becker, <becker@super.org> 10 * Donald Becker, <becker@super.org>
11 * Alan Cox, <Alan.Cox@linux.org> 11 * Alan Cox, <alan@lxorguk.ukuu.org.uk>
12 * Richard Underwood 12 * Richard Underwood
13 * Stefan Becker, <stefanb@yello.ping.de> 13 * Stefan Becker, <stefanb@yello.ping.de>
14 * Jorge Cwik, <jorge@laser.satlink.net> 14 * Jorge Cwik, <jorge@laser.satlink.net>
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index be3f18a7a40..2c88da6e786 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -438,7 +438,7 @@ int ip_options_compile(struct net *net,
438 goto error; 438 goto error;
439 } 439 }
440 opt->cipso = optptr - iph; 440 opt->cipso = optptr - iph;
441 if (cipso_v4_validate(&optptr)) { 441 if (cipso_v4_validate(skb, &optptr)) {
442 pp_ptr = optptr; 442 pp_ptr = optptr;
443 goto error; 443 goto error;
444 } 444 }
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index d533a89e08d..d2a8f8bb78a 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 105d92a039b..465abf0a986 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/ipip.c b/net/ipv4/ipip.c
index 4c6d2caf920..29609d29df7 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -41,7 +41,7 @@
41 Made the tunnels use dev->name not tunnel: when error reporting. 41 Made the tunnels use dev->name not tunnel: when error reporting.
42 Added tx_dropped stat 42 Added tx_dropped stat
43 43
44 -Alan Cox (Alan.Cox@linux.org) 21 March 95 44 -Alan Cox (alan@lxorguk.ukuu.org.uk) 21 March 95
45 45
46 Reworked: 46 Reworked:
47 Changed to tunnel to destination gateway in addition to the 47 Changed to tunnel to destination gateway in addition to the
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index c519b8d30ee..b42e082cc17 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * IP multicast routing support for mrouted 3.6/3.8 2 * IP multicast routing support for mrouted 3.6/3.8
3 * 3 *
4 * (c) 1995 Alan Cox, <alan@redhat.com> 4 * (c) 1995 Alan Cox, <alan@lxorguk.ukuu.org.uk>
5 * Linux Consultancy and Custom Driver Development 5 * Linux Consultancy and Custom Driver Development
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
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 73e0ea87c1f..00000000000
--- 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 21d70c8ffa5..00000000000
--- 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 f8edacdf991..6efdb70b3eb 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 90eb7cb47e7..3816e1dc929 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 3f31291f37c..5f9b650d90f 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 03e83a65aec..8d70d29f1cc 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 a385959d265..b0d5b1d0a76 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 082f5dd3156..bee3d117661 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 4e7c719445c..213fb27debc 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 fafe8ebb4c5..7ac1677419a 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 d60139c134c..f7e2fa0974d 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 0af14137137..fc6ce04a3e3 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 0841aefaa50..f389f60cb10 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 6739abfd152..7c29582d4ec 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 5c6292449d1..698e5e78685 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 2639872849d..0b4b6e0ff2b 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 30eed65e733..6d76aae90cc 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 b192756c6d0..18a2826b57c 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 462a22c9787..88762f02779 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 e977989629c..0104c0b399d 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 749de8284ce..6289b64144c 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 e0b8caeb710..297f1cbf4ff 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 1ea677dcf84..c9224310eba 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 da59182f222..69f2c428714 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 fddce7754b7..8faebfe638f 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 db6d312128e..36f3be3cc42 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 5a955c44036..4a7c3527539 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 3a020720e40..313ebf00ee3 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 97791048fa9..4e887922022 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 00000000000..fa2d6b6fc3e
--- /dev/null
+++ b/net/ipv4/netfilter/nf_defrag_ipv4.c
@@ -0,0 +1,97 @@
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#if !defined(CONFIG_NF_NAT) && !defined(CONFIG_NF_NAT_MODULE)
45 /* Previously seen (loopback)? Ignore. Do this before
46 fragment check. */
47 if (skb->nfct)
48 return NF_ACCEPT;
49#endif
50#endif
51 /* Gather fragments. */
52 if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) {
53 if (nf_ct_ipv4_gather_frags(skb,
54 hooknum == NF_INET_PRE_ROUTING ?
55 IP_DEFRAG_CONNTRACK_IN :
56 IP_DEFRAG_CONNTRACK_OUT))
57 return NF_STOLEN;
58 }
59 return NF_ACCEPT;
60}
61
62static struct nf_hook_ops ipv4_defrag_ops[] = {
63 {
64 .hook = ipv4_conntrack_defrag,
65 .owner = THIS_MODULE,
66 .pf = PF_INET,
67 .hooknum = NF_INET_PRE_ROUTING,
68 .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
69 },
70 {
71 .hook = ipv4_conntrack_defrag,
72 .owner = THIS_MODULE,
73 .pf = PF_INET,
74 .hooknum = NF_INET_LOCAL_OUT,
75 .priority = NF_IP_PRI_CONNTRACK_DEFRAG,
76 },
77};
78
79static int __init nf_defrag_init(void)
80{
81 return nf_register_hooks(ipv4_defrag_ops, ARRAY_SIZE(ipv4_defrag_ops));
82}
83
84static void __exit nf_defrag_fini(void)
85{
86 nf_unregister_hooks(ipv4_defrag_ops, ARRAY_SIZE(ipv4_defrag_ops));
87}
88
89void nf_defrag_ipv4_enable(void)
90{
91}
92EXPORT_SYMBOL_GPL(nf_defrag_ipv4_enable);
93
94module_init(nf_defrag_init);
95module_exit(nf_defrag_fini);
96
97MODULE_LICENSE("GPL");
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
index 6c6a3cba8d5..a65cf692359 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,132 @@ 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
587#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
588
589#include <linux/netfilter/nfnetlink.h>
590#include <linux/netfilter/nfnetlink_conntrack.h>
591
592static const struct nla_policy protonat_nla_policy[CTA_PROTONAT_MAX+1] = {
593 [CTA_PROTONAT_PORT_MIN] = { .type = NLA_U16 },
594 [CTA_PROTONAT_PORT_MAX] = { .type = NLA_U16 },
595};
596
597static int nfnetlink_parse_nat_proto(struct nlattr *attr,
598 const struct nf_conn *ct,
599 struct nf_nat_range *range)
600{
601 struct nlattr *tb[CTA_PROTONAT_MAX+1];
602 const struct nf_nat_protocol *npt;
603 int err;
604
605 err = nla_parse_nested(tb, CTA_PROTONAT_MAX, attr, protonat_nla_policy);
606 if (err < 0)
607 return err;
608
609 npt = nf_nat_proto_find_get(nf_ct_protonum(ct));
610 if (npt->nlattr_to_range)
611 err = npt->nlattr_to_range(tb, range);
612 nf_nat_proto_put(npt);
613 return err;
614}
615
616static const struct nla_policy nat_nla_policy[CTA_NAT_MAX+1] = {
617 [CTA_NAT_MINIP] = { .type = NLA_U32 },
618 [CTA_NAT_MAXIP] = { .type = NLA_U32 },
619};
620
621static int
622nfnetlink_parse_nat(struct nlattr *nat,
623 const struct nf_conn *ct, struct nf_nat_range *range)
624{
625 struct nlattr *tb[CTA_NAT_MAX+1];
626 int err;
627
628 memset(range, 0, sizeof(*range));
629
630 err = nla_parse_nested(tb, CTA_NAT_MAX, nat, nat_nla_policy);
631 if (err < 0)
632 return err;
633
634 if (tb[CTA_NAT_MINIP])
635 range->min_ip = nla_get_be32(tb[CTA_NAT_MINIP]);
636
637 if (!tb[CTA_NAT_MAXIP])
638 range->max_ip = range->min_ip;
639 else
640 range->max_ip = nla_get_be32(tb[CTA_NAT_MAXIP]);
641
642 if (range->min_ip)
643 range->flags |= IP_NAT_RANGE_MAP_IPS;
644
645 if (!tb[CTA_NAT_PROTO])
646 return 0;
647
648 err = nfnetlink_parse_nat_proto(tb[CTA_NAT_PROTO], ct, range);
649 if (err < 0)
650 return err;
651
652 return 0;
653}
654
655static int
656nfnetlink_parse_nat_setup(struct nf_conn *ct,
657 enum nf_nat_manip_type manip,
658 struct nlattr *attr)
659{
660 struct nf_nat_range range;
661
662 if (nfnetlink_parse_nat(attr, ct, &range) < 0)
663 return -EINVAL;
664 if (nf_nat_initialized(ct, manip))
665 return -EEXIST;
666
667 return nf_nat_setup_info(ct, &range, manip);
668}
669#else
670static int
671nfnetlink_parse_nat_setup(struct nf_conn *ct,
672 enum nf_nat_manip_type manip,
673 struct nlattr *attr)
674{
675 return -EOPNOTSUPP;
676}
677#endif
678
679static int __net_init nf_nat_net_init(struct net *net)
680{
681 net->ipv4.nat_bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size,
682 &net->ipv4.nat_vmalloced);
683 if (!net->ipv4.nat_bysource)
684 return -ENOMEM;
685 return 0;
686}
687
688/* Clear NAT section of all conntracks, in case we're loaded again. */
689static int clean_nat(struct nf_conn *i, void *data)
690{
691 struct nf_conn_nat *nat = nfct_nat(i);
692
693 if (!nat)
694 return 0;
695 memset(nat, 0, sizeof(*nat));
696 i->status &= ~(IPS_NAT_MASK | IPS_NAT_DONE_MASK | IPS_SEQ_ADJUST);
697 return 0;
698}
699
700static void __net_exit nf_nat_net_exit(struct net *net)
701{
702 nf_ct_iterate_cleanup(net, &clean_nat, NULL);
703 synchronize_rcu();
704 nf_ct_free_hashtable(net->ipv4.nat_bysource, net->ipv4.nat_vmalloced,
705 nf_nat_htable_size);
706}
707
708static struct pernet_operations nf_nat_net_ops = {
709 .init = nf_nat_net_init,
710 .exit = nf_nat_net_exit,
711};
712
586static int __init nf_nat_init(void) 713static int __init nf_nat_init(void)
587{ 714{
588 size_t i; 715 size_t i;
@@ -599,12 +726,9 @@ static int __init nf_nat_init(void)
599 /* Leave them the same for the moment. */ 726 /* Leave them the same for the moment. */
600 nf_nat_htable_size = nf_conntrack_htable_size; 727 nf_nat_htable_size = nf_conntrack_htable_size;
601 728
602 bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size, 729 ret = register_pernet_subsys(&nf_nat_net_ops);
603 &nf_nat_vmalloced); 730 if (ret < 0)
604 if (!bysource) {
605 ret = -ENOMEM;
606 goto cleanup_extend; 731 goto cleanup_extend;
607 }
608 732
609 /* Sew in builtin protocols. */ 733 /* Sew in builtin protocols. */
610 spin_lock_bh(&nf_nat_lock); 734 spin_lock_bh(&nf_nat_lock);
@@ -622,6 +746,9 @@ static int __init nf_nat_init(void)
622 746
623 BUG_ON(nf_nat_seq_adjust_hook != NULL); 747 BUG_ON(nf_nat_seq_adjust_hook != NULL);
624 rcu_assign_pointer(nf_nat_seq_adjust_hook, nf_nat_seq_adjust); 748 rcu_assign_pointer(nf_nat_seq_adjust_hook, nf_nat_seq_adjust);
749 BUG_ON(nfnetlink_parse_nat_setup_hook != NULL);
750 rcu_assign_pointer(nfnetlink_parse_nat_setup_hook,
751 nfnetlink_parse_nat_setup);
625 return 0; 752 return 0;
626 753
627 cleanup_extend: 754 cleanup_extend:
@@ -629,30 +756,18 @@ static int __init nf_nat_init(void)
629 return ret; 756 return ret;
630} 757}
631 758
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) 759static void __exit nf_nat_cleanup(void)
645{ 760{
646 nf_ct_iterate_cleanup(&clean_nat, NULL); 761 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); 762 nf_ct_l3proto_put(l3proto);
650 nf_ct_extend_unregister(&nat_extend); 763 nf_ct_extend_unregister(&nat_extend);
651 rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL); 764 rcu_assign_pointer(nf_nat_seq_adjust_hook, NULL);
765 rcu_assign_pointer(nfnetlink_parse_nat_setup_hook, NULL);
652 synchronize_net(); 766 synchronize_net();
653} 767}
654 768
655MODULE_LICENSE("GPL"); 769MODULE_LICENSE("GPL");
770MODULE_ALIAS("nf-nat-ipv4");
656 771
657module_init(nf_nat_init); 772module_init(nf_nat_init);
658module_exit(nf_nat_cleanup); 773module_exit(nf_nat_cleanup);
diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c
index 11976ea2988..cf7a42bf982 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 da3d91a5ef5..9eb171056c6 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 e8b4d0d4439..bea54a68510 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 6ee5354c9aa..942be04e795 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:
@@ -2896,8 +2908,6 @@ static int ipv4_sysctl_rtcache_flush(ctl_table *__ctl, int write,
2896} 2908}
2897 2909
2898static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table, 2910static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table,
2899 int __user *name,
2900 int nlen,
2901 void __user *oldval, 2911 void __user *oldval,
2902 size_t __user *oldlenp, 2912 size_t __user *oldlenp,
2903 void __user *newval, 2913 void __user *newval,
@@ -2960,16 +2970,13 @@ static int ipv4_sysctl_rt_secret_interval(ctl_table *ctl, int write,
2960} 2970}
2961 2971
2962static int ipv4_sysctl_rt_secret_interval_strategy(ctl_table *table, 2972static int ipv4_sysctl_rt_secret_interval_strategy(ctl_table *table,
2963 int __user *name,
2964 int nlen,
2965 void __user *oldval, 2973 void __user *oldval,
2966 size_t __user *oldlenp, 2974 size_t __user *oldlenp,
2967 void __user *newval, 2975 void __user *newval,
2968 size_t newlen) 2976 size_t newlen)
2969{ 2977{
2970 int old = ip_rt_secret_interval; 2978 int old = ip_rt_secret_interval;
2971 int ret = sysctl_jiffies(table, name, nlen, oldval, oldlenp, newval, 2979 int ret = sysctl_jiffies(table, oldval, oldlenp, newval, newlen);
2972 newlen);
2973 2980
2974 rt_secret_reschedule(old); 2981 rt_secret_reschedule(old);
2975 2982
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index 9d38005abba..d346c22aa6a 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 e0689fd7b79..1bb10df8ce7 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) {
@@ -67,14 +64,13 @@ static int ipv4_local_port_range(ctl_table *table, int write, struct file *filp,
67} 64}
68 65
69/* Validate changes from sysctl interface. */ 66/* Validate changes from sysctl interface. */
70static int ipv4_sysctl_local_port_range(ctl_table *table, int __user *name, 67static int ipv4_sysctl_local_port_range(ctl_table *table,
71 int nlen, void __user *oldval, 68 void __user *oldval,
72 size_t __user *oldlenp, 69 size_t __user *oldlenp,
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,7 +79,8 @@ 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
86 ret = sysctl_intvec(&tmp, name, nlen, oldval, oldlenp, newval, newlen); 82 inet_get_local_port_range(range, range + 1);
83 ret = sysctl_intvec(&tmp, 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])
89 ret = -EINVAL; 86 ret = -EINVAL;
@@ -112,8 +109,8 @@ static int proc_tcp_congestion_control(ctl_table *ctl, int write, struct file *
112 return ret; 109 return ret;
113} 110}
114 111
115static int sysctl_tcp_congestion_control(ctl_table *table, int __user *name, 112static int sysctl_tcp_congestion_control(ctl_table *table,
116 int nlen, void __user *oldval, 113 void __user *oldval,
117 size_t __user *oldlenp, 114 size_t __user *oldlenp,
118 void __user *newval, size_t newlen) 115 void __user *newval, size_t newlen)
119{ 116{
@@ -125,7 +122,7 @@ static int sysctl_tcp_congestion_control(ctl_table *table, int __user *name,
125 int ret; 122 int ret;
126 123
127 tcp_get_default_congestion_control(val); 124 tcp_get_default_congestion_control(val);
128 ret = sysctl_string(&tbl, name, nlen, oldval, oldlenp, newval, newlen); 125 ret = sysctl_string(&tbl, oldval, oldlenp, newval, newlen);
129 if (ret == 1 && newval && newlen) 126 if (ret == 1 && newval && newlen)
130 ret = tcp_set_default_congestion_control(val); 127 ret = tcp_set_default_congestion_control(val);
131 return ret; 128 return ret;
@@ -168,8 +165,8 @@ static int proc_allowed_congestion_control(ctl_table *ctl,
168 return ret; 165 return ret;
169} 166}
170 167
171static int strategy_allowed_congestion_control(ctl_table *table, int __user *name, 168static int strategy_allowed_congestion_control(ctl_table *table,
172 int nlen, void __user *oldval, 169 void __user *oldval,
173 size_t __user *oldlenp, 170 size_t __user *oldlenp,
174 void __user *newval, 171 void __user *newval,
175 size_t newlen) 172 size_t newlen)
@@ -182,7 +179,7 @@ static int strategy_allowed_congestion_control(ctl_table *table, int __user *nam
182 return -ENOMEM; 179 return -ENOMEM;
183 180
184 tcp_get_available_congestion_control(tbl.data, tbl.maxlen); 181 tcp_get_available_congestion_control(tbl.data, tbl.maxlen);
185 ret = sysctl_string(&tbl, name, nlen, oldval, oldlenp, newval, newlen); 182 ret = sysctl_string(&tbl, oldval, oldlenp, newval, newlen);
186 if (ret == 1 && newval && newlen) 183 if (ret == 1 && newval && newlen)
187 ret = tcp_set_allowed_congestion_control(tbl.data); 184 ret = tcp_set_allowed_congestion_control(tbl.data);
188 kfree(tbl.data); 185 kfree(tbl.data);
@@ -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 1ab341e5d3e..eccb7165a80 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 bfcbd148a89..c209e054a63 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 67ccce2a96b..d77c0d29e23 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 44c1e934824..5c8fa7f1e32 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 f976fc57892..779f2e9d068 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 8165f5aa8c7..990a5849323 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 5ab6ba19c3c..6b6dff1164b 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 8e42fbbd576..2095abc3cab 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -8,7 +8,7 @@
8 * Authors: Ross Biro 8 * Authors: Ross Biro
9 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 9 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
10 * Arnt Gulbrandsen, <agulbra@nvg.unit.no> 10 * Arnt Gulbrandsen, <agulbra@nvg.unit.no>
11 * Alan Cox, <Alan.Cox@linux.org> 11 * Alan Cox, <alan@lxorguk.ukuu.org.uk>
12 * Hirokazu Takahashi, <taka@valinux.co.jp> 12 * Hirokazu Takahashi, <taka@valinux.co.jp>
13 * 13 *
14 * Fixes: 14 * Fixes:
@@ -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/addrconf.c b/net/ipv6/addrconf.c
index 7b6a584b62d..eea9542728c 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3982,7 +3982,6 @@ int addrconf_sysctl_forward(ctl_table *ctl, int write, struct file * filp,
3982} 3982}
3983 3983
3984static int addrconf_sysctl_forward_strategy(ctl_table *table, 3984static int addrconf_sysctl_forward_strategy(ctl_table *table,
3985 int __user *name, int nlen,
3986 void __user *oldval, 3985 void __user *oldval,
3987 size_t __user *oldlenp, 3986 size_t __user *oldlenp,
3988 void __user *newval, size_t newlen) 3987 void __user *newval, size_t newlen)
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 95055f8c3f3..01edac88851 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,61 +795,55 @@ 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 __net_init inet6_net_init(struct net *net)
838{ 838{
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 837c830d6d8..6bfffec2371 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 b3157a0cc15..9b7d19ae5ce 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 7e14cccd056..936f48946e2 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 0e844c2736a..c77db0b95e2 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 17c7b098cdb..64ce3d33d9c 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 095bc453ff4..182f8a177e7 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 e7c03bcc278..d7b3c6d398a 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 f1c62ba0f56..172438320ee 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))
@@ -1199,7 +1199,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
1199 } 1199 }
1200 neigh->flags |= NTF_ROUTER; 1200 neigh->flags |= NTF_ROUTER;
1201 } else if (rt) { 1201 } else if (rt) {
1202 rt->rt6i_flags |= (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref); 1202 rt->rt6i_flags = (rt->rt6i_flags & ~RTF_PREF_MASK) | RTF_PREF(pref);
1203 } 1203 }
1204 1204
1205 if (rt) 1205 if (rt)
@@ -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))
@@ -1730,9 +1730,8 @@ int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, struct file * f
1730 return ret; 1730 return ret;
1731} 1731}
1732 1732
1733int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl, int __user *name, 1733int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl,
1734 int nlen, void __user *oldval, 1734 void __user *oldval, size_t __user *oldlenp,
1735 size_t __user *oldlenp,
1736 void __user *newval, size_t newlen) 1735 void __user *newval, size_t newlen)
1737{ 1736{
1738 struct net_device *dev = ctl->extra1; 1737 struct net_device *dev = ctl->extra1;
@@ -1745,13 +1744,11 @@ int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl, int __user *name,
1745 1744
1746 switch (ctl->ctl_name) { 1745 switch (ctl->ctl_name) {
1747 case NET_NEIGH_REACHABLE_TIME: 1746 case NET_NEIGH_REACHABLE_TIME:
1748 ret = sysctl_jiffies(ctl, name, nlen, 1747 ret = sysctl_jiffies(ctl, oldval, oldlenp, newval, newlen);
1749 oldval, oldlenp, newval, newlen);
1750 break; 1748 break;
1751 case NET_NEIGH_RETRANS_TIME_MS: 1749 case NET_NEIGH_RETRANS_TIME_MS:
1752 case NET_NEIGH_REACHABLE_TIME_MS: 1750 case NET_NEIGH_REACHABLE_TIME_MS:
1753 ret = sysctl_ms_jiffies(ctl, name, nlen, 1751 ret = sysctl_ms_jiffies(ctl, oldval, oldlenp, newval, newlen);
1754 oldval, oldlenp, newval, newlen);
1755 break; 1752 break;
1756 default: 1753 default:
1757 ret = 0; 1754 ret = 0;
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index 8c6c5e71f21..fd5b3a4e332 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -12,6 +12,7 @@
12 12
13int ip6_route_me_harder(struct sk_buff *skb) 13int ip6_route_me_harder(struct sk_buff *skb)
14{ 14{
15 struct net *net = dev_net(skb->dst->dev);
15 struct ipv6hdr *iph = ipv6_hdr(skb); 16 struct ipv6hdr *iph = ipv6_hdr(skb);
16 struct dst_entry *dst; 17 struct dst_entry *dst;
17 struct flowi fl = { 18 struct flowi fl = {
@@ -23,7 +24,7 @@ int ip6_route_me_harder(struct sk_buff *skb)
23 .saddr = iph->saddr, } }, 24 .saddr = iph->saddr, } },
24 }; 25 };
25 26
26 dst = ip6_route_output(&init_net, skb->sk, &fl); 27 dst = ip6_route_output(net, skb->sk, &fl);
27 28
28#ifdef CONFIG_XFRM 29#ifdef CONFIG_XFRM
29 if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) && 30 if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
@@ -33,7 +34,7 @@ int ip6_route_me_harder(struct sk_buff *skb)
33#endif 34#endif
34 35
35 if (dst->error) { 36 if (dst->error) {
36 IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); 37 IP6_INC_STATS(net, ip6_dst_idev(dst), 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 0cfcce7b18d..53ea512c460 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 0b4557e0343..a33485dc81c 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 d5f8fd5f29d..27b5adf670a 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 3a2316974f8..caa441d0956 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 44c8d65a243..0981b4ccb8b 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 429629fd63b..3a82f24746b 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 8f331f12b2e..db610bacbcc 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 e2bbc63dba5..673aa0a5084 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 62e39ace058..cbe8dec9744 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 34567167384..c964dca1132 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 317a8960a75..14e6724d567 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 e06678d07ec..aafe4e66577 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 81aaf7aaaab..356b8d6f6ba 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 55a2c290bad..b110a8a85a1 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 f405cea21a8..d0b31b259d4 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 92b91077ac2..109fab6f831 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 6e7131036bc..20bc52f13e4 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 85050c072ab..e91db16611d 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 14d47d83354..05726177903 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 52d06dd4b81..9967ac7a01a 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 0179b66864f..07f0b76e742 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 e53e493606c..2ba04d41dc2 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -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 89184b576e2..af12de071f4 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 9af6115f0f5..89dc6992434 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 5b90b369ccb..e5310c9b84d 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 a6aecf76a71..e51da8c092f 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 f6cdcb348e0..3cd1a1ac3d6 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 705959b31e2..d7b54b5bfa6 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 d628df97e02..e55e0441e4d 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 80d693392b0..7f710a27e91 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 a169b0201d6..31cfd1f89a7 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 297c257864c..855126a3039 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 ee509f1109e..24ce5446331 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 cf82acec913..a3294d10932 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 */
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 8165df578c9..2ad504fc341 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:
@@ -551,8 +545,12 @@ static int netdev_notify(struct notifier_block *nb,
551 545
552 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 546 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
553 547
554 sprintf(buf, "netdev:%s", dev->name);
555 dir = sdata->debugfsdir; 548 dir = sdata->debugfsdir;
549
550 if (!dir)
551 return 0;
552
553 sprintf(buf, "netdev:%s", dev->name);
556 if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf)) 554 if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf))
557 printk(KERN_ERR "mac80211: debugfs: failed to rename debugfs " 555 printk(KERN_ERR "mac80211: debugfs: failed to rename debugfs "
558 "dir to %s\n", buf); 556 "dir to %s\n", buf);
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 79a062782d5..189d0bafa91 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;
@@ -250,11 +249,22 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta)
250 DECLARE_MAC_BUF(mbuf); 249 DECLARE_MAC_BUF(mbuf);
251 u8 *mac; 250 u8 *mac;
252 251
252 sta->debugfs.add_has_run = true;
253
253 if (!stations_dir) 254 if (!stations_dir)
254 return; 255 return;
255 256
256 mac = print_mac(mbuf, sta->addr); 257 mac = print_mac(mbuf, sta->sta.addr);
257 258
259 /*
260 * This might fail due to a race condition:
261 * When mac80211 unlinks a station, the debugfs entries
262 * remain, but it is already possible to link a new
263 * station with the same address which triggers adding
264 * it to debugfs; therefore, if the old station isn't
265 * destroyed quickly enough the old station's debugfs
266 * dir might still be around.
267 */
258 sta->debugfs.dir = debugfs_create_dir(mac, stations_dir); 268 sta->debugfs.dir = debugfs_create_dir(mac, stations_dir);
259 if (!sta->debugfs.dir) 269 if (!sta->debugfs.dir)
260 return; 270 return;
diff --git a/net/mac80211/event.c b/net/mac80211/event.c
index 2280f40b456..8de60de70bc 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 00000000000..dc7d9a3d70d
--- /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 4498d871365..156e42a003a 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;
@@ -540,6 +550,19 @@ struct ieee80211_sub_if_data *vif_to_sdata(struct ieee80211_vif *p)
540 return container_of(p, struct ieee80211_sub_if_data, vif); 550 return container_of(p, struct ieee80211_sub_if_data, vif);
541} 551}
542 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
543enum { 566enum {
544 IEEE80211_RX_MSG = 1, 567 IEEE80211_RX_MSG = 1,
545 IEEE80211_TX_STATUS_MSG = 2, 568 IEEE80211_TX_STATUS_MSG = 2,
@@ -550,6 +573,10 @@ enum {
550/* maximum number of hardware queues we support. */ 573/* maximum number of hardware queues we support. */
551#define QD_MAX_QUEUES (IEEE80211_MAX_AMPDU_QUEUES + IEEE80211_MAX_QUEUES) 574#define QD_MAX_QUEUES (IEEE80211_MAX_AMPDU_QUEUES + IEEE80211_MAX_QUEUES)
552 575
576struct ieee80211_master_priv {
577 struct ieee80211_local *local;
578};
579
553struct ieee80211_local { 580struct ieee80211_local {
554 /* embed the driver visible part. 581 /* embed the driver visible part.
555 * don't cast (use the static inlines below), but we keep 582 * don't cast (use the static inlines below), but we keep
@@ -613,10 +640,6 @@ struct ieee80211_local {
613 struct crypto_blkcipher *wep_rx_tfm; 640 struct crypto_blkcipher *wep_rx_tfm;
614 u32 wep_iv; 641 u32 wep_iv;
615 642
616 int bridge_packets; /* bridge packets between associated stations and
617 * deliver multicast frames both back to wireless
618 * media and to the local net stack */
619
620 struct list_head interfaces; 643 struct list_head interfaces;
621 644
622 /* 645 /*
@@ -626,21 +649,21 @@ struct ieee80211_local {
626 spinlock_t key_lock; 649 spinlock_t key_lock;
627 650
628 651
629 bool sta_sw_scanning; 652 /* Scanning and BSS list */
630 bool sta_hw_scanning; 653 bool sw_scanning, hw_scanning;
631 int scan_channel_idx; 654 int scan_channel_idx;
632 enum ieee80211_band scan_band; 655 enum ieee80211_band scan_band;
633 656
634 enum { SCAN_SET_CHANNEL, SCAN_SEND_PROBE } scan_state; 657 enum { SCAN_SET_CHANNEL, SCAN_SEND_PROBE } scan_state;
635 unsigned long last_scan_completed; 658 unsigned long last_scan_completed;
636 struct delayed_work scan_work; 659 struct delayed_work scan_work;
637 struct net_device *scan_dev; 660 struct ieee80211_sub_if_data *scan_sdata;
638 struct ieee80211_channel *oper_channel, *scan_channel; 661 struct ieee80211_channel *oper_channel, *scan_channel;
639 u8 scan_ssid[IEEE80211_MAX_SSID_LEN]; 662 u8 scan_ssid[IEEE80211_MAX_SSID_LEN];
640 size_t scan_ssid_len; 663 size_t scan_ssid_len;
641 struct list_head sta_bss_list; 664 struct list_head bss_list;
642 struct ieee80211_sta_bss *sta_bss_hash[STA_HASH_SIZE]; 665 struct ieee80211_bss *bss_hash[STA_HASH_SIZE];
643 spinlock_t sta_bss_lock; 666 spinlock_t bss_lock;
644 667
645 /* SNMP counters */ 668 /* SNMP counters */
646 /* dot11CountersTable */ 669 /* dot11CountersTable */
@@ -701,10 +724,11 @@ struct ieee80211_local {
701 724
702#ifdef CONFIG_MAC80211_DEBUGFS 725#ifdef CONFIG_MAC80211_DEBUGFS
703 struct local_debugfsdentries { 726 struct local_debugfsdentries {
727 struct dentry *rcdir;
728 struct dentry *rcname;
704 struct dentry *frequency; 729 struct dentry *frequency;
705 struct dentry *antenna_sel_tx; 730 struct dentry *antenna_sel_tx;
706 struct dentry *antenna_sel_rx; 731 struct dentry *antenna_sel_rx;
707 struct dentry *bridge_packets;
708 struct dentry *rts_threshold; 732 struct dentry *rts_threshold;
709 struct dentry *fragmentation_threshold; 733 struct dentry *fragmentation_threshold;
710 struct dentry *short_retry_limit; 734 struct dentry *short_retry_limit;
@@ -774,6 +798,9 @@ struct ieee80211_ra_tid {
774 798
775/* Parsed Information Elements */ 799/* Parsed Information Elements */
776struct ieee802_11_elems { 800struct ieee802_11_elems {
801 u8 *ie_start;
802 size_t total_len;
803
777 /* pointers to IEs */ 804 /* pointers to IEs */
778 u8 *ssid; 805 u8 *ssid;
779 u8 *supp_rates; 806 u8 *supp_rates;
@@ -789,8 +816,8 @@ struct ieee802_11_elems {
789 u8 *ext_supp_rates; 816 u8 *ext_supp_rates;
790 u8 *wmm_info; 817 u8 *wmm_info;
791 u8 *wmm_param; 818 u8 *wmm_param;
792 u8 *ht_cap_elem; 819 struct ieee80211_ht_cap *ht_cap_elem;
793 u8 *ht_info_elem; 820 struct ieee80211_ht_addt_info *ht_info_elem;
794 u8 *mesh_config; 821 u8 *mesh_config;
795 u8 *mesh_id; 822 u8 *mesh_id;
796 u8 *peer_link; 823 u8 *peer_link;
@@ -817,8 +844,6 @@ struct ieee802_11_elems {
817 u8 ext_supp_rates_len; 844 u8 ext_supp_rates_len;
818 u8 wmm_info_len; 845 u8 wmm_info_len;
819 u8 wmm_param_len; 846 u8 wmm_param_len;
820 u8 ht_cap_elem_len;
821 u8 ht_info_elem_len;
822 u8 mesh_config_len; 847 u8 mesh_config_len;
823 u8 mesh_id_len; 848 u8 mesh_id_len;
824 u8 peer_link_len; 849 u8 peer_link_len;
@@ -857,86 +882,82 @@ static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr)
857} 882}
858 883
859 884
860/* ieee80211.c */
861int ieee80211_hw_config(struct ieee80211_local *local); 885int ieee80211_hw_config(struct ieee80211_local *local);
862int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed); 886int ieee80211_if_config(struct ieee80211_sub_if_data *sdata, u32 changed);
863void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx); 887void ieee80211_tx_set_protected(struct ieee80211_tx_data *tx);
864u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht, 888u32 ieee80211_handle_ht(struct ieee80211_local *local, int enable_ht,
865 struct ieee80211_ht_info *req_ht_cap, 889 struct ieee80211_ht_info *req_ht_cap,
866 struct ieee80211_ht_bss_info *req_bss_cap); 890 struct ieee80211_ht_bss_info *req_bss_cap);
891void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
892 u32 changed);
893void ieee80211_configure_filter(struct ieee80211_local *local);
867 894
868/* ieee80211_ioctl.c */ 895/* wireless extensions */
869extern const struct iw_handler_def ieee80211_iw_handler_def; 896extern const struct iw_handler_def ieee80211_iw_handler_def;
870int ieee80211_set_freq(struct net_device *dev, int freq);
871 897
872/* ieee80211_sta.c */ 898/* STA/IBSS code */
873void ieee80211_sta_timer(unsigned long data); 899void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata);
874void ieee80211_sta_work(struct work_struct *work); 900void ieee80211_scan_work(struct work_struct *work);
875void ieee80211_sta_scan_work(struct work_struct *work); 901void ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
876void ieee80211_sta_rx_mgmt(struct net_device *dev, struct sk_buff *skb,
877 struct ieee80211_rx_status *rx_status); 902 struct ieee80211_rx_status *rx_status);
878int ieee80211_sta_set_ssid(struct net_device *dev, char *ssid, size_t len); 903int ieee80211_sta_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len);
879int ieee80211_sta_get_ssid(struct net_device *dev, char *ssid, size_t *len); 904int ieee80211_sta_get_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t *len);
880int ieee80211_sta_set_bssid(struct net_device *dev, u8 *bssid); 905int ieee80211_sta_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid);
881int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len); 906void ieee80211_sta_req_auth(struct ieee80211_sub_if_data *sdata,
882void ieee80211_sta_req_auth(struct net_device *dev,
883 struct ieee80211_if_sta *ifsta); 907 struct ieee80211_if_sta *ifsta);
884int ieee80211_sta_scan_results(struct net_device *dev, 908struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
885 struct iw_request_info *info,
886 char *buf, size_t len);
887ieee80211_rx_result ieee80211_sta_rx_scan(
888 struct net_device *dev, struct sk_buff *skb,
889 struct ieee80211_rx_status *rx_status);
890void ieee80211_rx_bss_list_init(struct ieee80211_local *local);
891void ieee80211_rx_bss_list_deinit(struct ieee80211_local *local);
892int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len);
893struct sta_info *ieee80211_ibss_add_sta(struct net_device *dev,
894 struct sk_buff *skb, u8 *bssid, 909 struct sk_buff *skb, u8 *bssid,
895 u8 *addr, u64 supp_rates); 910 u8 *addr, u64 supp_rates);
896int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason); 911int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason);
897int ieee80211_sta_disassociate(struct net_device *dev, u16 reason); 912int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason);
898void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, 913u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata);
899 u32 changed);
900u32 ieee80211_reset_erp_info(struct net_device *dev);
901int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie,
902 struct ieee80211_ht_info *ht_info);
903int ieee80211_ht_addt_info_ie_to_ht_bss_info(
904 struct ieee80211_ht_addt_info *ht_add_info_ie,
905 struct ieee80211_ht_bss_info *bss_info);
906void ieee80211_send_addba_request(struct net_device *dev, const u8 *da,
907 u16 tid, u8 dialog_token, u16 start_seq_num,
908 u16 agg_size, u16 timeout);
909void ieee80211_send_delba(struct net_device *dev, const u8 *da, u16 tid,
910 u16 initiator, u16 reason_code);
911void ieee80211_send_bar(struct net_device *dev, u8 *ra, u16 tid, u16 ssn);
912
913void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *da,
914 u16 tid, u16 initiator, u16 reason);
915void sta_addba_resp_timer_expired(unsigned long data);
916void ieee80211_sta_tear_down_BA_sessions(struct net_device *dev, u8 *addr);
917u64 ieee80211_sta_get_rates(struct ieee80211_local *local, 914u64 ieee80211_sta_get_rates(struct ieee80211_local *local,
918 struct ieee802_11_elems *elems, 915 struct ieee802_11_elems *elems,
919 enum ieee80211_band band); 916 enum ieee80211_band band);
920void ieee80211_sta_tx(struct net_device *dev, struct sk_buff *skb, 917void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
921 int encrypt); 918 u8 *ssid, size_t ssid_len);
922void ieee802_11_parse_elems(u8 *start, size_t len, 919
923 struct ieee802_11_elems *elems); 920/* scan/BSS handling */
924 921int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
925#ifdef CONFIG_MAC80211_MESH 922 u8 *ssid, size_t ssid_len);
926void ieee80211_start_mesh(struct net_device *dev); 923int ieee80211_scan_results(struct ieee80211_local *local,
927#else 924 struct iw_request_info *info,
928static inline void ieee80211_start_mesh(struct net_device *dev) 925 char *buf, size_t len);
929{} 926ieee80211_rx_result
930#endif 927ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata,
928 struct sk_buff *skb,
929 struct ieee80211_rx_status *rx_status);
930void ieee80211_rx_bss_list_init(struct ieee80211_local *local);
931void ieee80211_rx_bss_list_deinit(struct ieee80211_local *local);
932int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata,
933 char *ie, size_t len);
934
935void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local);
936int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata,
937 u8 *ssid, size_t ssid_len);
938struct ieee80211_bss *
939ieee80211_bss_info_update(struct ieee80211_local *local,
940 struct ieee80211_rx_status *rx_status,
941 struct ieee80211_mgmt *mgmt,
942 size_t len,
943 struct ieee802_11_elems *elems,
944 int freq, bool beacon);
945struct ieee80211_bss *
946ieee80211_rx_bss_add(struct ieee80211_local *local, u8 *bssid, int freq,
947 u8 *ssid, u8 ssid_len);
948struct ieee80211_bss *
949ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
950 u8 *ssid, u8 ssid_len);
951void ieee80211_rx_bss_put(struct ieee80211_local *local,
952 struct ieee80211_bss *bss);
931 953
932/* interface handling */ 954/* interface handling */
933void ieee80211_if_setup(struct net_device *dev);
934int ieee80211_if_add(struct ieee80211_local *local, const char *name, 955int ieee80211_if_add(struct ieee80211_local *local, const char *name,
935 struct net_device **new_dev, enum ieee80211_if_types type, 956 struct net_device **new_dev, enum nl80211_iftype type,
936 struct vif_params *params); 957 struct vif_params *params);
937int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, 958int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
938 enum ieee80211_if_types type); 959 enum nl80211_iftype type);
939void ieee80211_if_remove(struct net_device *dev); 960void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata);
940void ieee80211_remove_interfaces(struct ieee80211_local *local); 961void ieee80211_remove_interfaces(struct ieee80211_local *local);
941 962
942/* tx handling */ 963/* tx handling */
@@ -946,16 +967,52 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev);
946int ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev); 967int ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev);
947int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); 968int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev);
948 969
970/* HT */
971int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie,
972 struct ieee80211_ht_info *ht_info);
973int ieee80211_ht_addt_info_ie_to_ht_bss_info(
974 struct ieee80211_ht_addt_info *ht_add_info_ie,
975 struct ieee80211_ht_bss_info *bss_info);
976void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn);
977
978void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *da,
979 u16 tid, u16 initiator, u16 reason);
980void ieee80211_sta_tear_down_BA_sessions(struct ieee80211_sub_if_data *sdata, u8 *addr);
981void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata,
982 struct sta_info *sta,
983 struct ieee80211_mgmt *mgmt, size_t len);
984void ieee80211_process_addba_resp(struct ieee80211_local *local,
985 struct sta_info *sta,
986 struct ieee80211_mgmt *mgmt,
987 size_t len);
988void ieee80211_process_addba_request(struct ieee80211_local *local,
989 struct sta_info *sta,
990 struct ieee80211_mgmt *mgmt,
991 size_t len);
992
993/* Spectrum management */
994void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
995 struct ieee80211_mgmt *mgmt,
996 size_t len);
997
949/* utility functions/constants */ 998/* utility functions/constants */
950extern void *mac80211_wiphy_privid; /* for wiphy privid */ 999extern void *mac80211_wiphy_privid; /* for wiphy privid */
951extern const unsigned char rfc1042_header[6]; 1000extern const unsigned char rfc1042_header[6];
952extern const unsigned char bridge_tunnel_header[6]; 1001extern const unsigned char bridge_tunnel_header[6];
953u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len, 1002u8 *ieee80211_get_bssid(struct ieee80211_hdr *hdr, size_t len,
954 enum ieee80211_if_types type); 1003 enum nl80211_iftype type);
955int ieee80211_frame_duration(struct ieee80211_local *local, size_t len, 1004int ieee80211_frame_duration(struct ieee80211_local *local, size_t len,
956 int rate, int erp, int short_preamble); 1005 int rate, int erp, int short_preamble);
957void mac80211_ev_michael_mic_failure(struct net_device *dev, int keyidx, 1006void mac80211_ev_michael_mic_failure(struct ieee80211_sub_if_data *sdata, int keyidx,
958 struct ieee80211_hdr *hdr); 1007 struct ieee80211_hdr *hdr);
1008void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata);
1009void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
1010 int encrypt);
1011void ieee802_11_parse_elems(u8 *start, size_t len,
1012 struct ieee802_11_elems *elems);
1013int ieee80211_set_freq(struct ieee80211_sub_if_data *sdata, int freq);
1014u64 ieee80211_mandatory_rates(struct ieee80211_local *local,
1015 enum ieee80211_band band);
959 1016
960#ifdef CONFIG_MAC80211_NOINLINE 1017#ifdef CONFIG_MAC80211_NOINLINE
961#define debug_noinline noinline 1018#define debug_noinline noinline
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 610ed1d9893..8336fee68d3 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 6597c779e35..a5b06fe7198 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 aa5a191598c..ae62ad40ad6 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 35f2f95f2fa..8013277924f 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 7495fbb0d21..e10471c6ba4 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 08aca446ca0..501c7831adb 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 838ee60492a..3c72557df45 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 9efeb1f0702..faac101c0f8 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 902cac1bd24..87665d7bb4f 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,607 +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
294 if (!(ifsta->flags & IEEE80211_STA_WMM_ENABLED))
295 return;
296 58
297 if (!wmm_param) 59 pos = bss->ies;
298 return; 60 if (pos == NULL)
299 61 return NULL;
300 if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1) 62 end = pos + bss->ies_len;
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; 66 break;
332 case 3: 67 if (pos[0] == ie)
333 queue = 0; 68 return pos;
334 if (acm) 69 pos += 2 + pos[1];
335 local->wmm_acm |= BIT(6) | BIT(7);
336 break;
337 case 0:
338 default:
339 queue = 2;
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 } 70 }
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 71
375 if (use_protection != bss_conf->use_cts_prot) { 72 return NULL;
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} 73}
415 74
416static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata, 75static int ieee80211_compatible_rates(struct ieee80211_bss *bss,
417 struct ieee80211_sta_bss *bss) 76 struct ieee80211_supported_band *sband,
77 u64 *rates)
418{ 78{
419 u32 changed = 0; 79 int i, j, count;
80 *rates = 0;
81 count = 0;
82 for (i = 0; i < bss->supp_rates_len; i++) {
83 int rate = (bss->supp_rates[i] & 0x7F) * 5;
420 84
421 if (bss->has_erp_value) 85 for (j = 0; j < sband->n_bitrates; j++)
422 changed |= ieee80211_handle_erp_ie(sdata, bss->erp_value); 86 if (sband->bitrates[j].bitrate == rate) {
423 else { 87 *rates |= BIT(j);
424 u16 capab = bss->capability; 88 count++;
425 changed |= ieee80211_handle_protect_preamb(sdata, false, 89 break;
426 (capab & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0); 90 }
427 } 91 }
428 92
429 return changed; 93 return count;
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} 94}
456 95
457int ieee80211_ht_addt_info_ie_to_ht_bss_info( 96/* also used by mesh code */
458 struct ieee80211_ht_addt_info *ht_add_info_ie, 97u64 ieee80211_sta_get_rates(struct ieee80211_local *local,
459 struct ieee80211_ht_bss_info *bss_info) 98 struct ieee802_11_elems *elems,
99 enum ieee80211_band band)
460{ 100{
461 if (bss_info == NULL) 101 struct ieee80211_supported_band *sband;
462 return -EINVAL; 102 struct ieee80211_rate *bitrates;
463 103 size_t num_rates;
464 memset(bss_info, 0, sizeof(*bss_info)); 104 u64 supp_rates;
465 105 int i, j;
466 if (ht_add_info_ie) { 106 sband = local->hw.wiphy->bands[band];
467 u16 op_mode;
468 op_mode = le16_to_cpu(ht_add_info_ie->operation_mode);
469 107
470 bss_info->primary_channel = ht_add_info_ie->control_chan; 108 if (!sband) {
471 bss_info->bss_cap = ht_add_info_ie->ht_param; 109 WARN_ON(1);
472 bss_info->bss_op_mode = (u8)(op_mode & 0xff); 110 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
473 } 111 }
474 112
475 return 0; 113 bitrates = sband->bitrates;
114 num_rates = sband->n_bitrates;
115 supp_rates = 0;
116 for (i = 0; i < elems->supp_rates_len +
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);
129 }
130 return supp_rates;
476} 131}
477 132
478static void ieee80211_sta_send_associnfo(struct net_device *dev, 133/* frame sending functions */
479 struct ieee80211_if_sta *ifsta) 134
135/* also used by scanning code */
136void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
137 u8 *ssid, size_t ssid_len)
480{ 138{
481 char *buf; 139 struct ieee80211_local *local = sdata->local;
482 size_t len; 140 struct ieee80211_supported_band *sband;
141 struct sk_buff *skb;
142 struct ieee80211_mgmt *mgmt;
143 u8 *pos, *supp_rates, *esupp_rates = NULL;
483 int i; 144 int i;
484 union iwreq_data wrqu;
485
486 if (!ifsta->assocreq_ies && !ifsta->assocresp_ies)
487 return;
488 145
489 buf = kmalloc(50 + 2 * (ifsta->assocreq_ies_len + 146 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200);
490 ifsta->assocresp_ies_len), GFP_KERNEL); 147 if (!skb) {
491 if (!buf) 148 printk(KERN_DEBUG "%s: failed to allocate buffer for probe "
149 "request\n", sdata->dev->name);
492 return; 150 return;
493
494 len = sprintf(buf, "ASSOCINFO(");
495 if (ifsta->assocreq_ies) {
496 len += sprintf(buf + len, "ReqIEs=");
497 for (i = 0; i < ifsta->assocreq_ies_len; i++) {
498 len += sprintf(buf + len, "%02x",
499 ifsta->assocreq_ies[i]);
500 }
501 } 151 }
502 if (ifsta->assocresp_ies) { 152 skb_reserve(skb, local->hw.extra_tx_headroom);
503 if (ifsta->assocreq_ies)
504 len += sprintf(buf + len, " ");
505 len += sprintf(buf + len, "RespIEs=");
506 for (i = 0; i < ifsta->assocresp_ies_len; i++) {
507 len += sprintf(buf + len, "%02x",
508 ifsta->assocresp_ies[i]);
509 }
510 }
511 len += sprintf(buf + len, ")");
512 153
513 if (len > IW_CUSTOM_MAX) { 154 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
514 len = sprintf(buf, "ASSOCRESPIE="); 155 memset(mgmt, 0, 24);
515 for (i = 0; i < ifsta->assocresp_ies_len; i++) { 156 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
516 len += sprintf(buf + len, "%02x", 157 IEEE80211_STYPE_PROBE_REQ);
517 ifsta->assocresp_ies[i]); 158 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
518 } 159 if (dst) {
160 memcpy(mgmt->da, dst, ETH_ALEN);
161 memcpy(mgmt->bssid, dst, ETH_ALEN);
162 } else {
163 memset(mgmt->da, 0xff, ETH_ALEN);
164 memset(mgmt->bssid, 0xff, ETH_ALEN);
519 } 165 }
166 pos = skb_put(skb, 2 + ssid_len);
167 *pos++ = WLAN_EID_SSID;
168 *pos++ = ssid_len;
169 memcpy(pos, ssid, ssid_len);
520 170
521 memset(&wrqu, 0, sizeof(wrqu)); 171 supp_rates = skb_put(skb, 2);
522 wrqu.data.length = len; 172 supp_rates[0] = WLAN_EID_SUPP_RATES;
523 wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf); 173 supp_rates[1] = 0;
524 174 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
525 kfree(buf);
526}
527
528
529static void ieee80211_set_associated(struct net_device *dev,
530 struct ieee80211_if_sta *ifsta,
531 bool assoc)
532{
533 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
534 struct ieee80211_local *local = sdata->local;
535 struct ieee80211_conf *conf = &local_to_hw(local)->conf;
536 union iwreq_data wrqu;
537 u32 changed = BSS_CHANGED_ASSOC;
538
539 if (assoc) {
540 struct ieee80211_sta_bss *bss;
541
542 ifsta->flags |= IEEE80211_STA_ASSOCIATED;
543
544 if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
545 return;
546
547 bss = ieee80211_rx_bss_get(dev, ifsta->bssid,
548 conf->channel->center_freq,
549 ifsta->ssid, ifsta->ssid_len);
550 if (bss) {
551 /* set timing information */
552 sdata->bss_conf.beacon_int = bss->beacon_int;
553 sdata->bss_conf.timestamp = bss->timestamp;
554 sdata->bss_conf.dtim_period = bss->dtim_period;
555
556 changed |= ieee80211_handle_bss_capability(sdata, bss);
557
558 ieee80211_rx_bss_put(local, bss);
559 }
560 175
561 if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { 176 for (i = 0; i < sband->n_bitrates; i++) {
562 changed |= BSS_CHANGED_HT; 177 struct ieee80211_rate *rate = &sband->bitrates[i];
563 sdata->bss_conf.assoc_ht = 1; 178 if (esupp_rates) {
564 sdata->bss_conf.ht_conf = &conf->ht_conf; 179 pos = skb_put(skb, 1);
565 sdata->bss_conf.ht_bss_conf = &conf->ht_bss_conf; 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]++;
566 } 189 }
567 190 *pos = rate->bitrate / 5;
568 ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET;
569 memcpy(ifsta->prev_bssid, sdata->u.sta.bssid, ETH_ALEN);
570 memcpy(wrqu.ap_addr.sa_data, sdata->u.sta.bssid, ETH_ALEN);
571 ieee80211_sta_send_associnfo(dev, ifsta);
572 } else {
573 netif_carrier_off(dev);
574 ieee80211_sta_tear_down_BA_sessions(dev, ifsta->bssid);
575 ifsta->flags &= ~IEEE80211_STA_ASSOCIATED;
576 changed |= ieee80211_reset_erp_info(dev);
577
578 sdata->bss_conf.assoc_ht = 0;
579 sdata->bss_conf.ht_conf = NULL;
580 sdata->bss_conf.ht_bss_conf = NULL;
581
582 memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
583 } 191 }
584 ifsta->last_probe = jiffies;
585 ieee80211_led_assoc(local, assoc);
586 192
587 sdata->bss_conf.assoc = assoc; 193 ieee80211_tx_skb(sdata, skb, 0);
588 ieee80211_bss_info_change_notify(sdata, changed);
589
590 if (assoc)
591 netif_carrier_on(dev);
592
593 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
594 wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
595} 194}
596 195
597static void ieee80211_set_disassoc(struct net_device *dev, 196static void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
598 struct ieee80211_if_sta *ifsta, int deauth)
599{
600 if (deauth)
601 ifsta->auth_tries = 0;
602 ifsta->assoc_tries = 0;
603 ieee80211_set_associated(dev, ifsta, 0);
604}
605
606void ieee80211_sta_tx(struct net_device *dev, struct sk_buff *skb,
607 int encrypt)
608{
609 struct ieee80211_sub_if_data *sdata;
610
611 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
612 skb->dev = sdata->local->mdev;
613 skb_set_mac_header(skb, 0);
614 skb_set_network_header(skb, 0);
615 skb_set_transport_header(skb, 0);
616
617 skb->iif = sdata->dev->ifindex;
618 skb->do_not_encrypt = !encrypt;
619
620 dev_queue_xmit(skb);
621}
622
623
624static void ieee80211_send_auth(struct net_device *dev,
625 struct ieee80211_if_sta *ifsta, 197 struct ieee80211_if_sta *ifsta,
626 int transaction, u8 *extra, size_t extra_len, 198 int transaction, u8 *extra, size_t extra_len,
627 int encrypt) 199 int encrypt)
628{ 200{
629 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 201 struct ieee80211_local *local = sdata->local;
630 struct sk_buff *skb; 202 struct sk_buff *skb;
631 struct ieee80211_mgmt *mgmt; 203 struct ieee80211_mgmt *mgmt;
632 204
@@ -634,19 +206,19 @@ static void ieee80211_send_auth(struct net_device *dev,
634 sizeof(*mgmt) + 6 + extra_len); 206 sizeof(*mgmt) + 6 + extra_len);
635 if (!skb) { 207 if (!skb) {
636 printk(KERN_DEBUG "%s: failed to allocate buffer for auth " 208 printk(KERN_DEBUG "%s: failed to allocate buffer for auth "
637 "frame\n", dev->name); 209 "frame\n", sdata->dev->name);
638 return; 210 return;
639 } 211 }
640 skb_reserve(skb, local->hw.extra_tx_headroom); 212 skb_reserve(skb, local->hw.extra_tx_headroom);
641 213
642 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24 + 6); 214 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24 + 6);
643 memset(mgmt, 0, 24 + 6); 215 memset(mgmt, 0, 24 + 6);
644 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, 216 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
645 IEEE80211_STYPE_AUTH); 217 IEEE80211_STYPE_AUTH);
646 if (encrypt) 218 if (encrypt)
647 mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); 219 mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
648 memcpy(mgmt->da, ifsta->bssid, ETH_ALEN); 220 memcpy(mgmt->da, ifsta->bssid, ETH_ALEN);
649 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); 221 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
650 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); 222 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
651 mgmt->u.auth.auth_alg = cpu_to_le16(ifsta->auth_alg); 223 mgmt->u.auth.auth_alg = cpu_to_le16(ifsta->auth_alg);
652 mgmt->u.auth.auth_transaction = cpu_to_le16(transaction); 224 mgmt->u.auth.auth_transaction = cpu_to_le16(transaction);
@@ -655,64 +227,19 @@ static void ieee80211_send_auth(struct net_device *dev,
655 if (extra) 227 if (extra)
656 memcpy(skb_put(skb, extra_len), extra, extra_len); 228 memcpy(skb_put(skb, extra_len), extra, extra_len);
657 229
658 ieee80211_sta_tx(dev, skb, encrypt); 230 ieee80211_tx_skb(sdata, skb, encrypt);
659}
660
661
662static void ieee80211_authenticate(struct net_device *dev,
663 struct ieee80211_if_sta *ifsta)
664{
665 DECLARE_MAC_BUF(mac);
666
667 ifsta->auth_tries++;
668 if (ifsta->auth_tries > IEEE80211_AUTH_MAX_TRIES) {
669 printk(KERN_DEBUG "%s: authentication with AP %s"
670 " timed out\n",
671 dev->name, print_mac(mac, ifsta->bssid));
672 ifsta->state = IEEE80211_DISABLED;
673 return;
674 }
675
676 ifsta->state = IEEE80211_AUTHENTICATE;
677 printk(KERN_DEBUG "%s: authenticate with AP %s\n",
678 dev->name, print_mac(mac, ifsta->bssid));
679
680 ieee80211_send_auth(dev, ifsta, 1, NULL, 0, 0);
681
682 mod_timer(&ifsta->timer, jiffies + IEEE80211_AUTH_TIMEOUT);
683}
684
685static int ieee80211_compatible_rates(struct ieee80211_sta_bss *bss,
686 struct ieee80211_supported_band *sband,
687 u64 *rates)
688{
689 int i, j, count;
690 *rates = 0;
691 count = 0;
692 for (i = 0; i < bss->supp_rates_len; i++) {
693 int rate = (bss->supp_rates[i] & 0x7F) * 5;
694
695 for (j = 0; j < sband->n_bitrates; j++)
696 if (sband->bitrates[j].bitrate == rate) {
697 *rates |= BIT(j);
698 count++;
699 break;
700 }
701 }
702
703 return count;
704} 231}
705 232
706static void ieee80211_send_assoc(struct net_device *dev, 233static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
707 struct ieee80211_if_sta *ifsta) 234 struct ieee80211_if_sta *ifsta)
708{ 235{
709 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 236 struct ieee80211_local *local = sdata->local;
710 struct sk_buff *skb; 237 struct sk_buff *skb;
711 struct ieee80211_mgmt *mgmt; 238 struct ieee80211_mgmt *mgmt;
712 u8 *pos, *ies; 239 u8 *pos, *ies, *ht_add_ie;
713 int i, len, count, rates_len, supp_rates_len; 240 int i, len, count, rates_len, supp_rates_len;
714 u16 capab; 241 u16 capab;
715 struct ieee80211_sta_bss *bss; 242 struct ieee80211_bss *bss;
716 int wmm = 0; 243 int wmm = 0;
717 struct ieee80211_supported_band *sband; 244 struct ieee80211_supported_band *sband;
718 u64 rates = 0; 245 u64 rates = 0;
@@ -722,7 +249,7 @@ static void ieee80211_send_assoc(struct net_device *dev,
722 ifsta->ssid_len); 249 ifsta->ssid_len);
723 if (!skb) { 250 if (!skb) {
724 printk(KERN_DEBUG "%s: failed to allocate buffer for assoc " 251 printk(KERN_DEBUG "%s: failed to allocate buffer for assoc "
725 "frame\n", dev->name); 252 "frame\n", sdata->dev->name);
726 return; 253 return;
727 } 254 }
728 skb_reserve(skb, local->hw.extra_tx_headroom); 255 skb_reserve(skb, local->hw.extra_tx_headroom);
@@ -738,13 +265,13 @@ static void ieee80211_send_assoc(struct net_device *dev,
738 capab |= WLAN_CAPABILITY_SHORT_PREAMBLE; 265 capab |= WLAN_CAPABILITY_SHORT_PREAMBLE;
739 } 266 }
740 267
741 bss = ieee80211_rx_bss_get(dev, ifsta->bssid, 268 bss = ieee80211_rx_bss_get(local, ifsta->bssid,
742 local->hw.conf.channel->center_freq, 269 local->hw.conf.channel->center_freq,
743 ifsta->ssid, ifsta->ssid_len); 270 ifsta->ssid, ifsta->ssid_len);
744 if (bss) { 271 if (bss) {
745 if (bss->capability & WLAN_CAPABILITY_PRIVACY) 272 if (bss->capability & WLAN_CAPABILITY_PRIVACY)
746 capab |= WLAN_CAPABILITY_PRIVACY; 273 capab |= WLAN_CAPABILITY_PRIVACY;
747 if (bss->wmm_ie) 274 if (bss->wmm_used)
748 wmm = 1; 275 wmm = 1;
749 276
750 /* get all rates supported by the device and the AP as 277 /* get all rates supported by the device and the AP as
@@ -766,13 +293,13 @@ static void ieee80211_send_assoc(struct net_device *dev,
766 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); 293 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
767 memset(mgmt, 0, 24); 294 memset(mgmt, 0, 24);
768 memcpy(mgmt->da, ifsta->bssid, ETH_ALEN); 295 memcpy(mgmt->da, ifsta->bssid, ETH_ALEN);
769 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); 296 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
770 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); 297 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
771 298
772 if (ifsta->flags & IEEE80211_STA_PREV_BSSID_SET) { 299 if (ifsta->flags & IEEE80211_STA_PREV_BSSID_SET) {
773 skb_put(skb, 10); 300 skb_put(skb, 10);
774 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, 301 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
775 IEEE80211_STYPE_REASSOC_REQ); 302 IEEE80211_STYPE_REASSOC_REQ);
776 mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab); 303 mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab);
777 mgmt->u.reassoc_req.listen_interval = 304 mgmt->u.reassoc_req.listen_interval =
778 cpu_to_le16(local->hw.conf.listen_interval); 305 cpu_to_le16(local->hw.conf.listen_interval);
@@ -780,8 +307,8 @@ static void ieee80211_send_assoc(struct net_device *dev,
780 ETH_ALEN); 307 ETH_ALEN);
781 } else { 308 } else {
782 skb_put(skb, 4); 309 skb_put(skb, 4);
783 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, 310 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
784 IEEE80211_STYPE_ASSOC_REQ); 311 IEEE80211_STYPE_ASSOC_REQ);
785 mgmt->u.assoc_req.capab_info = cpu_to_le16(capab); 312 mgmt->u.assoc_req.capab_info = cpu_to_le16(capab);
786 mgmt->u.reassoc_req.listen_interval = 313 mgmt->u.reassoc_req.listen_interval =
787 cpu_to_le16(local->hw.conf.listen_interval); 314 cpu_to_le16(local->hw.conf.listen_interval);
@@ -866,9 +393,10 @@ static void ieee80211_send_assoc(struct net_device *dev,
866 393
867 /* wmm support is a must to HT */ 394 /* wmm support is a must to HT */
868 if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) && 395 if (wmm && (ifsta->flags & IEEE80211_STA_WMM_ENABLED) &&
869 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))) {
870 struct ieee80211_ht_addt_info *ht_add_info = 398 struct ieee80211_ht_addt_info *ht_add_info =
871 (struct ieee80211_ht_addt_info *)bss->ht_add_ie; 399 (struct ieee80211_ht_addt_info *)ht_add_ie;
872 u16 cap = sband->ht_info.cap; 400 u16 cap = sband->ht_info.cap;
873 __le16 tmp; 401 __le16 tmp;
874 u32 flags = local->hw.conf.channel->flags; 402 u32 flags = local->hw.conf.channel->flags;
@@ -907,21 +435,22 @@ static void ieee80211_send_assoc(struct net_device *dev,
907 if (ifsta->assocreq_ies) 435 if (ifsta->assocreq_ies)
908 memcpy(ifsta->assocreq_ies, ies, ifsta->assocreq_ies_len); 436 memcpy(ifsta->assocreq_ies, ies, ifsta->assocreq_ies_len);
909 437
910 ieee80211_sta_tx(dev, skb, 0); 438 ieee80211_tx_skb(sdata, skb, 0);
911} 439}
912 440
913 441
914static void ieee80211_send_deauth(struct net_device *dev, 442static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
915 struct ieee80211_if_sta *ifsta, u16 reason) 443 u16 stype, u16 reason)
916{ 444{
917 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;
918 struct sk_buff *skb; 447 struct sk_buff *skb;
919 struct ieee80211_mgmt *mgmt; 448 struct ieee80211_mgmt *mgmt;
920 449
921 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt)); 450 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt));
922 if (!skb) { 451 if (!skb) {
923 printk(KERN_DEBUG "%s: failed to allocate buffer for deauth " 452 printk(KERN_DEBUG "%s: failed to allocate buffer for "
924 "frame\n", dev->name); 453 "deauth/disassoc frame\n", sdata->dev->name);
925 return; 454 return;
926 } 455 }
927 skb_reserve(skb, local->hw.extra_tx_headroom); 456 skb_reserve(skb, local->hw.extra_tx_headroom);
@@ -929,940 +458,594 @@ static void ieee80211_send_deauth(struct net_device *dev,
929 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); 458 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
930 memset(mgmt, 0, 24); 459 memset(mgmt, 0, 24);
931 memcpy(mgmt->da, ifsta->bssid, ETH_ALEN); 460 memcpy(mgmt->da, ifsta->bssid, ETH_ALEN);
932 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); 461 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
933 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); 462 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
934 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, 463 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | stype);
935 IEEE80211_STYPE_DEAUTH);
936 skb_put(skb, 2); 464 skb_put(skb, 2);
465 /* u.deauth.reason_code == u.disassoc.reason_code */
937 mgmt->u.deauth.reason_code = cpu_to_le16(reason); 466 mgmt->u.deauth.reason_code = cpu_to_le16(reason);
938 467
939 ieee80211_sta_tx(dev, skb, 0); 468 ieee80211_tx_skb(sdata, skb, 0);
940} 469}
941 470
942 471/* MLME */
943static void ieee80211_send_disassoc(struct net_device *dev, 472static void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
944 struct ieee80211_if_sta *ifsta, u16 reason) 473 struct ieee80211_bss *bss)
945{ 474{
946 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 475 struct ieee80211_local *local = sdata->local;
947 struct sk_buff *skb; 476 int i, have_higher_than_11mbit = 0;
948 struct ieee80211_mgmt *mgmt;
949 477
950 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt)); 478 /* cf. IEEE 802.11 9.2.12 */
951 if (!skb) { 479 for (i = 0; i < bss->supp_rates_len; i++)
952 printk(KERN_DEBUG "%s: failed to allocate buffer for disassoc " 480 if ((bss->supp_rates[i] & 0x7f) * 5 > 110)
953 "frame\n", dev->name); 481 have_higher_than_11mbit = 1;
954 return;
955 }
956 skb_reserve(skb, local->hw.extra_tx_headroom);
957 482
958 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); 483 if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ &&
959 memset(mgmt, 0, 24); 484 have_higher_than_11mbit)
960 memcpy(mgmt->da, ifsta->bssid, ETH_ALEN); 485 sdata->flags |= IEEE80211_SDATA_OPERATING_GMODE;
961 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); 486 else
962 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); 487 sdata->flags &= ~IEEE80211_SDATA_OPERATING_GMODE;
963 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
964 IEEE80211_STYPE_DISASSOC);
965 skb_put(skb, 2);
966 mgmt->u.disassoc.reason_code = cpu_to_le16(reason);
967 488
968 ieee80211_sta_tx(dev, skb, 0); 489 ieee80211_set_wmm_default(sdata);
969} 490}
970 491
971 492static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
972static int ieee80211_privacy_mismatch(struct net_device *dev, 493 struct ieee80211_if_sta *ifsta,
973 struct ieee80211_if_sta *ifsta) 494 u8 *wmm_param, size_t wmm_param_len)
974{ 495{
975 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 496 struct ieee80211_tx_queue_params params;
976 struct ieee80211_sta_bss *bss; 497 size_t left;
977 int bss_privacy; 498 int count;
978 int wep_privacy; 499 u8 *pos;
979 int privacy_invoked;
980 500
981 if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL)) 501 if (!(ifsta->flags & IEEE80211_STA_WMM_ENABLED))
982 return 0; 502 return;
983 503
984 bss = ieee80211_rx_bss_get(dev, ifsta->bssid, 504 if (!wmm_param)
985 local->hw.conf.channel->center_freq, 505 return;
986 ifsta->ssid, ifsta->ssid_len);
987 if (!bss)
988 return 0;
989 506
990 bss_privacy = !!(bss->capability & WLAN_CAPABILITY_PRIVACY); 507 if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1)
991 wep_privacy = !!ieee80211_sta_wep_configured(dev); 508 return;
992 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;
993 513
994 ieee80211_rx_bss_put(local, bss); 514 pos = wmm_param + 8;
515 left = wmm_param_len - 8;
995 516
996 if ((bss_privacy == wep_privacy) || (bss_privacy == privacy_invoked)) 517 memset(&params, 0, sizeof(params));
997 return 0;
998 518
999 return 1; 519 if (!local->ops->conf_tx)
1000} 520 return;
1001 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;
1002 527
1003static void ieee80211_associate(struct net_device *dev, 528 switch (aci) {
1004 struct ieee80211_if_sta *ifsta) 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 }
551
552 params.aifs = pos[0] & 0x0f;
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)
1005{ 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;
1006 DECLARE_MAC_BUF(mac); 578 DECLARE_MAC_BUF(mac);
579#endif
580 u32 changed = 0;
1007 581
1008 ifsta->assoc_tries++; 582 if (use_protection != bss_conf->use_cts_prot) {
1009 if (ifsta->assoc_tries > IEEE80211_ASSOC_MAX_TRIES) { 583#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
1010 printk(KERN_DEBUG "%s: association with AP %s" 584 if (net_ratelimit()) {
1011 " timed out\n", 585 printk(KERN_DEBUG "%s: CTS protection %s (BSSID="
1012 dev->name, print_mac(mac, ifsta->bssid)); 586 "%s)\n",
1013 ifsta->state = IEEE80211_DISABLED; 587 sdata->dev->name,
1014 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;
1015 } 594 }
1016 595
1017 ifsta->state = IEEE80211_ASSOCIATE; 596 if (use_short_preamble != bss_conf->use_short_preamble) {
1018 printk(KERN_DEBUG "%s: associate with AP %s\n", 597#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
1019 dev->name, print_mac(mac, ifsta->bssid)); 598 if (net_ratelimit()) {
1020 if (ieee80211_privacy_mismatch(dev, ifsta)) { 599 printk(KERN_DEBUG "%s: switched to %s barker preamble"
1021 printk(KERN_DEBUG "%s: mismatch in privacy configuration and " 600 " (BSSID=%s)\n",
1022 "mixed-cell disabled - abort association\n", dev->name); 601 sdata->dev->name,
1023 ifsta->state = IEEE80211_DISABLED; 602 use_short_preamble ? "short" : "long",
1024 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;
1025 } 608 }
1026 609
1027 ieee80211_send_assoc(dev, ifsta); 610 return changed;
1028
1029 mod_timer(&ifsta->timer, jiffies + IEEE80211_ASSOC_TIMEOUT);
1030} 611}
1031 612
1032 613static u32 ieee80211_handle_erp_ie(struct ieee80211_sub_if_data *sdata,
1033static void ieee80211_associated(struct net_device *dev, 614 u8 erp_value)
1034 struct ieee80211_if_sta *ifsta)
1035{ 615{
1036 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 616 bool use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0;
1037 struct sta_info *sta; 617 bool use_short_preamble = (erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0;
1038 int disassoc;
1039 DECLARE_MAC_BUF(mac);
1040
1041 /* TODO: start monitoring current AP signal quality and number of
1042 * missed beacons. Scan other channels every now and then and search
1043 * for better APs. */
1044 /* TODO: remove expired BSSes */
1045 618
1046 ifsta->state = IEEE80211_ASSOCIATED; 619 return ieee80211_handle_protect_preamb(sdata,
620 use_protection, use_short_preamble);
621}
1047 622
1048 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;
1049 627
1050 sta = sta_info_get(local, ifsta->bssid); 628 if (bss->has_erp_value)
1051 if (!sta) { 629 changed |= ieee80211_handle_erp_ie(sdata, bss->erp_value);
1052 printk(KERN_DEBUG "%s: No STA entry for own AP %s\n", 630 else {
1053 dev->name, print_mac(mac, ifsta->bssid)); 631 u16 capab = bss->capability;
1054 disassoc = 1; 632 changed |= ieee80211_handle_protect_preamb(sdata, false,
1055 } else { 633 (capab & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0);
1056 disassoc = 0;
1057 if (time_after(jiffies,
1058 sta->last_rx + IEEE80211_MONITORING_INTERVAL)) {
1059 if (ifsta->flags & IEEE80211_STA_PROBEREQ_POLL) {
1060 printk(KERN_DEBUG "%s: No ProbeResp from "
1061 "current AP %s - assume out of "
1062 "range\n",
1063 dev->name, print_mac(mac, ifsta->bssid));
1064 disassoc = 1;
1065 sta_info_unlink(&sta);
1066 } else
1067 ieee80211_send_probe_req(dev, ifsta->bssid,
1068 local->scan_ssid,
1069 local->scan_ssid_len);
1070 ifsta->flags ^= IEEE80211_STA_PROBEREQ_POLL;
1071 } else {
1072 ifsta->flags &= ~IEEE80211_STA_PROBEREQ_POLL;
1073 if (time_after(jiffies, ifsta->last_probe +
1074 IEEE80211_PROBE_INTERVAL)) {
1075 ifsta->last_probe = jiffies;
1076 ieee80211_send_probe_req(dev, ifsta->bssid,
1077 ifsta->ssid,
1078 ifsta->ssid_len);
1079 }
1080 }
1081 } 634 }
1082 635
1083 rcu_read_unlock(); 636 return changed;
1084
1085 if (disassoc && sta)
1086 sta_info_destroy(sta);
1087
1088 if (disassoc) {
1089 ifsta->state = IEEE80211_DISABLED;
1090 ieee80211_set_associated(dev, ifsta, 0);
1091 } else {
1092 mod_timer(&ifsta->timer, jiffies +
1093 IEEE80211_MONITORING_INTERVAL);
1094 }
1095} 637}
1096 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}
1097 649
1098static void ieee80211_send_probe_req(struct net_device *dev, u8 *dst, 650static void ieee80211_sta_send_associnfo(struct ieee80211_sub_if_data *sdata,
1099 u8 *ssid, size_t ssid_len) 651 struct ieee80211_if_sta *ifsta)
1100{ 652{
1101 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 653 char *buf;
1102 struct ieee80211_supported_band *sband; 654 size_t len;
1103 struct sk_buff *skb;
1104 struct ieee80211_mgmt *mgmt;
1105 u8 *pos, *supp_rates, *esupp_rates = NULL;
1106 int i; 655 int i;
656 union iwreq_data wrqu;
1107 657
1108 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200); 658 if (!ifsta->assocreq_ies && !ifsta->assocresp_ies)
1109 if (!skb) {
1110 printk(KERN_DEBUG "%s: failed to allocate buffer for probe "
1111 "request\n", dev->name);
1112 return; 659 return;
1113 }
1114 skb_reserve(skb, local->hw.extra_tx_headroom);
1115 660
1116 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); 661 buf = kmalloc(50 + 2 * (ifsta->assocreq_ies_len +
1117 memset(mgmt, 0, 24); 662 ifsta->assocresp_ies_len), GFP_KERNEL);
1118 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, 663 if (!buf)
1119 IEEE80211_STYPE_PROBE_REQ); 664 return;
1120 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN);
1121 if (dst) {
1122 memcpy(mgmt->da, dst, ETH_ALEN);
1123 memcpy(mgmt->bssid, dst, ETH_ALEN);
1124 } else {
1125 memset(mgmt->da, 0xff, ETH_ALEN);
1126 memset(mgmt->bssid, 0xff, ETH_ALEN);
1127 }
1128 pos = skb_put(skb, 2 + ssid_len);
1129 *pos++ = WLAN_EID_SSID;
1130 *pos++ = ssid_len;
1131 memcpy(pos, ssid, ssid_len);
1132
1133 supp_rates = skb_put(skb, 2);
1134 supp_rates[0] = WLAN_EID_SUPP_RATES;
1135 supp_rates[1] = 0;
1136 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
1137 665
1138 for (i = 0; i < sband->n_bitrates; i++) { 666 len = sprintf(buf, "ASSOCINFO(");
1139 struct ieee80211_rate *rate = &sband->bitrates[i]; 667 if (ifsta->assocreq_ies) {
1140 if (esupp_rates) { 668 len += sprintf(buf + len, "ReqIEs=");
1141 pos = skb_put(skb, 1); 669 for (i = 0; i < ifsta->assocreq_ies_len; i++) {
1142 esupp_rates[1]++; 670 len += sprintf(buf + len, "%02x",
1143 } else if (supp_rates[1] == 8) { 671 ifsta->assocreq_ies[i]);
1144 esupp_rates = skb_put(skb, 3);
1145 esupp_rates[0] = WLAN_EID_EXT_SUPP_RATES;
1146 esupp_rates[1] = 1;
1147 pos = &esupp_rates[2];
1148 } else {
1149 pos = skb_put(skb, 1);
1150 supp_rates[1]++;
1151 } 672 }
1152 *pos = rate->bitrate / 5;
1153 } 673 }
674 if (ifsta->assocresp_ies) {
675 if (ifsta->assocreq_ies)
676 len += sprintf(buf + len, " ");
677 len += sprintf(buf + len, "RespIEs=");
678 for (i = 0; i < ifsta->assocresp_ies_len; i++) {
679 len += sprintf(buf + len, "%02x",
680 ifsta->assocresp_ies[i]);
681 }
682 }
683 len += sprintf(buf + len, ")");
1154 684
1155 ieee80211_sta_tx(dev, skb, 0); 685 if (len > IW_CUSTOM_MAX) {
1156} 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 }
1157 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 }
1158 698
1159static int ieee80211_sta_wep_configured(struct net_device *dev) 699 kfree(buf);
1160{
1161 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1162 if (!sdata || !sdata->default_key ||
1163 sdata->default_key->conf.alg != ALG_WEP)
1164 return 0;
1165 return 1;
1166} 700}
1167 701
1168 702
1169static void ieee80211_auth_completed(struct net_device *dev, 703static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
1170 struct ieee80211_if_sta *ifsta) 704 struct ieee80211_if_sta *ifsta)
1171{ 705{
1172 printk(KERN_DEBUG "%s: authenticated\n", dev->name); 706 struct ieee80211_local *local = sdata->local;
1173 ifsta->flags |= IEEE80211_STA_AUTHENTICATED; 707 struct ieee80211_conf *conf = &local_to_hw(local)->conf;
1174 ieee80211_associate(dev, ifsta); 708 u32 changed = BSS_CHANGED_ASSOC;
1175}
1176 709
710 struct ieee80211_bss *bss;
1177 711
1178static void ieee80211_auth_challenge(struct net_device *dev, 712 ifsta->flags |= IEEE80211_STA_ASSOCIATED;
1179 struct ieee80211_if_sta *ifsta,
1180 struct ieee80211_mgmt *mgmt,
1181 size_t len)
1182{
1183 u8 *pos;
1184 struct ieee802_11_elems elems;
1185 713
1186 pos = mgmt->u.auth.variable; 714 if (sdata->vif.type != NL80211_IFTYPE_STATION)
1187 ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
1188 if (!elems.challenge)
1189 return; 715 return;
1190 ieee80211_send_auth(dev, ifsta, 3, elems.challenge - 2,
1191 elems.challenge_len + 2, 1);
1192}
1193 716
1194static void ieee80211_send_addba_resp(struct net_device *dev, u8 *da, u16 tid, 717 bss = ieee80211_rx_bss_get(local, ifsta->bssid,
1195 u8 dialog_token, u16 status, u16 policy, 718 conf->channel->center_freq,
1196 u16 buf_size, u16 timeout) 719 ifsta->ssid, ifsta->ssid_len);
1197{ 720 if (bss) {
1198 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 721 /* set timing information */
1199 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 722 sdata->bss_conf.beacon_int = bss->beacon_int;
1200 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 723 sdata->bss_conf.timestamp = bss->timestamp;
1201 struct sk_buff *skb; 724 sdata->bss_conf.dtim_period = bss->dtim_period;
1202 struct ieee80211_mgmt *mgmt;
1203 u16 capab;
1204 725
1205 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom); 726 changed |= ieee80211_handle_bss_capability(sdata, bss);
1206 727
1207 if (!skb) { 728 ieee80211_rx_bss_put(local, bss);
1208 printk(KERN_DEBUG "%s: failed to allocate buffer "
1209 "for addba resp frame\n", dev->name);
1210 return;
1211 } 729 }
1212 730
1213 skb_reserve(skb, local->hw.extra_tx_headroom); 731 if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) {
1214 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); 732 changed |= BSS_CHANGED_HT;
1215 memset(mgmt, 0, 24); 733 sdata->bss_conf.assoc_ht = 1;
1216 memcpy(mgmt->da, da, ETH_ALEN); 734 sdata->bss_conf.ht_conf = &conf->ht_conf;
1217 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); 735 sdata->bss_conf.ht_bss_conf = &conf->ht_bss_conf;
1218 if (sdata->vif.type == IEEE80211_IF_TYPE_AP) 736 }
1219 memcpy(mgmt->bssid, dev->dev_addr, ETH_ALEN);
1220 else
1221 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
1222 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
1223 IEEE80211_STYPE_ACTION);
1224 737
1225 skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_resp)); 738 ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET;
1226 mgmt->u.action.category = WLAN_CATEGORY_BACK; 739 memcpy(ifsta->prev_bssid, sdata->u.sta.bssid, ETH_ALEN);
1227 mgmt->u.action.u.addba_resp.action_code = WLAN_ACTION_ADDBA_RESP; 740 ieee80211_sta_send_associnfo(sdata, ifsta);
1228 mgmt->u.action.u.addba_resp.dialog_token = dialog_token;
1229 741
1230 capab = (u16)(policy << 1); /* bit 1 aggregation policy */ 742 ifsta->last_probe = jiffies;
1231 capab |= (u16)(tid << 2); /* bit 5:2 TID number */ 743 ieee80211_led_assoc(local, 1);
1232 capab |= (u16)(buf_size << 6); /* bit 15:6 max size of aggregation */
1233 744
1234 mgmt->u.action.u.addba_resp.capab = cpu_to_le16(capab); 745 sdata->bss_conf.assoc = 1;
1235 mgmt->u.action.u.addba_resp.timeout = cpu_to_le16(timeout); 746 /*
1236 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);
1237 753
1238 ieee80211_sta_tx(dev, skb, 0); 754 netif_tx_start_all_queues(sdata->dev);
755 netif_carrier_on(sdata->dev);
1239 756
1240 return; 757 ieee80211_sta_send_apinfo(sdata, ifsta);
1241} 758}
1242 759
1243void ieee80211_send_addba_request(struct net_device *dev, const u8 *da, 760static void ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata,
1244 u16 tid, u8 dialog_token, u16 start_seq_num, 761 struct ieee80211_if_sta *ifsta)
1245 u16 agg_size, u16 timeout)
1246{ 762{
1247 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 763 DECLARE_MAC_BUF(mac);
1248 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1249 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
1250 struct sk_buff *skb;
1251 struct ieee80211_mgmt *mgmt;
1252 u16 capab;
1253
1254 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
1255 764
1256 if (!skb) { 765 ifsta->direct_probe_tries++;
1257 printk(KERN_ERR "%s: failed to allocate buffer " 766 if (ifsta->direct_probe_tries > IEEE80211_AUTH_MAX_TRIES) {
1258 "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;
1259 return; 770 return;
1260 } 771 }
1261 skb_reserve(skb, local->hw.extra_tx_headroom);
1262 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24);
1263 memset(mgmt, 0, 24);
1264 memcpy(mgmt->da, da, ETH_ALEN);
1265 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN);
1266 if (sdata->vif.type == IEEE80211_IF_TYPE_AP)
1267 memcpy(mgmt->bssid, dev->dev_addr, ETH_ALEN);
1268 else
1269 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
1270
1271 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
1272 IEEE80211_STYPE_ACTION);
1273
1274 skb_put(skb, 1 + sizeof(mgmt->u.action.u.addba_req));
1275 772
1276 mgmt->u.action.category = WLAN_CATEGORY_BACK; 773 printk(KERN_DEBUG "%s: direct probe to AP %s try %d\n",
1277 mgmt->u.action.u.addba_req.action_code = WLAN_ACTION_ADDBA_REQ; 774 sdata->dev->name, print_mac(mac, ifsta->bssid),
775 ifsta->direct_probe_tries);
1278 776
1279 mgmt->u.action.u.addba_req.dialog_token = dialog_token; 777 ifsta->state = IEEE80211_STA_MLME_DIRECT_PROBE;
1280 capab = (u16)(1 << 1); /* bit 1 aggregation policy */
1281 capab |= (u16)(tid << 2); /* bit 5:2 TID number */
1282 capab |= (u16)(agg_size << 6); /* bit 15:6 max size of aggergation */
1283 778
1284 mgmt->u.action.u.addba_req.capab = cpu_to_le16(capab); 779 set_bit(IEEE80211_STA_REQ_DIRECT_PROBE, &ifsta->request);
1285 780
1286 mgmt->u.action.u.addba_req.timeout = cpu_to_le16(timeout); 781 /* Direct probe is sent to broadcast address as some APs
1287 mgmt->u.action.u.addba_req.start_seq_num = 782 * will not answer to direct packet in unassociated state.
1288 cpu_to_le16(start_seq_num << 4); 783 */
784 ieee80211_send_probe_req(sdata, NULL,
785 ifsta->ssid, ifsta->ssid_len);
1289 786
1290 ieee80211_sta_tx(dev, skb, 0); 787 mod_timer(&ifsta->timer, jiffies + IEEE80211_AUTH_TIMEOUT);
1291} 788}
1292 789
1293static void ieee80211_sta_process_addba_request(struct net_device *dev, 790
1294 struct ieee80211_mgmt *mgmt, 791static void ieee80211_authenticate(struct ieee80211_sub_if_data *sdata,
1295 size_t len) 792 struct ieee80211_if_sta *ifsta)
1296{ 793{
1297 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1298 struct ieee80211_hw *hw = &local->hw;
1299 struct ieee80211_conf *conf = &hw->conf;
1300 struct sta_info *sta;
1301 struct tid_ampdu_rx *tid_agg_rx;
1302 u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num, status;
1303 u8 dialog_token;
1304 int ret = -EOPNOTSUPP;
1305 DECLARE_MAC_BUF(mac); 794 DECLARE_MAC_BUF(mac);
1306 795
1307 rcu_read_lock(); 796 ifsta->auth_tries++;
1308 797 if (ifsta->auth_tries > IEEE80211_AUTH_MAX_TRIES) {
1309 sta = sta_info_get(local, mgmt->sa); 798 printk(KERN_DEBUG "%s: authentication with AP %s"
1310 if (!sta) { 799 " timed out\n",
1311 rcu_read_unlock(); 800 sdata->dev->name, print_mac(mac, ifsta->bssid));
801 ifsta->state = IEEE80211_STA_MLME_DISABLED;
1312 return; 802 return;
1313 } 803 }
1314 804
1315 /* extract session parameters from addba request frame */ 805 ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE;
1316 dialog_token = mgmt->u.action.u.addba_req.dialog_token; 806 printk(KERN_DEBUG "%s: authenticate with AP %s\n",
1317 timeout = le16_to_cpu(mgmt->u.action.u.addba_req.timeout); 807 sdata->dev->name, print_mac(mac, ifsta->bssid));
1318 start_seq_num =
1319 le16_to_cpu(mgmt->u.action.u.addba_req.start_seq_num) >> 4;
1320
1321 capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
1322 ba_policy = (capab & IEEE80211_ADDBA_PARAM_POLICY_MASK) >> 1;
1323 tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
1324 buf_size = (capab & IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK) >> 6;
1325
1326 status = WLAN_STATUS_REQUEST_DECLINED;
1327
1328 /* sanity check for incoming parameters:
1329 * check if configuration can support the BA policy
1330 * and if buffer size does not exceeds max value */
1331 if (((ba_policy != 1)
1332 && (!(conf->ht_conf.cap & IEEE80211_HT_CAP_DELAY_BA)))
1333 || (buf_size > IEEE80211_MAX_AMPDU_BUF)) {
1334 status = WLAN_STATUS_INVALID_QOS_PARAM;
1335#ifdef CONFIG_MAC80211_HT_DEBUG
1336 if (net_ratelimit())
1337 printk(KERN_DEBUG "AddBA Req with bad params from "
1338 "%s on tid %u. policy %d, buffer size %d\n",
1339 print_mac(mac, mgmt->sa), tid, ba_policy,
1340 buf_size);
1341#endif /* CONFIG_MAC80211_HT_DEBUG */
1342 goto end_no_lock;
1343 }
1344 /* determine default buffer size */
1345 if (buf_size == 0) {
1346 struct ieee80211_supported_band *sband;
1347
1348 sband = local->hw.wiphy->bands[conf->channel->band];
1349 buf_size = IEEE80211_MIN_AMPDU_BUF;
1350 buf_size = buf_size << sband->ht_info.ampdu_factor;
1351 }
1352
1353
1354 /* examine state machine */
1355 spin_lock_bh(&sta->lock);
1356 808
1357 if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) { 809 ieee80211_send_auth(sdata, ifsta, 1, NULL, 0, 0);
1358#ifdef CONFIG_MAC80211_HT_DEBUG
1359 if (net_ratelimit())
1360 printk(KERN_DEBUG "unexpected AddBA Req from "
1361 "%s on tid %u\n",
1362 print_mac(mac, mgmt->sa), tid);
1363#endif /* CONFIG_MAC80211_HT_DEBUG */
1364 goto end;
1365 }
1366 810
1367 /* prepare A-MPDU MLME for Rx aggregation */ 811 mod_timer(&ifsta->timer, jiffies + IEEE80211_AUTH_TIMEOUT);
1368 sta->ampdu_mlme.tid_rx[tid] =
1369 kmalloc(sizeof(struct tid_ampdu_rx), GFP_ATOMIC);
1370 if (!sta->ampdu_mlme.tid_rx[tid]) {
1371#ifdef CONFIG_MAC80211_HT_DEBUG
1372 if (net_ratelimit())
1373 printk(KERN_ERR "allocate rx mlme to tid %d failed\n",
1374 tid);
1375#endif
1376 goto end;
1377 }
1378 /* rx timer */
1379 sta->ampdu_mlme.tid_rx[tid]->session_timer.function =
1380 sta_rx_agg_session_timer_expired;
1381 sta->ampdu_mlme.tid_rx[tid]->session_timer.data =
1382 (unsigned long)&sta->timer_to_tid[tid];
1383 init_timer(&sta->ampdu_mlme.tid_rx[tid]->session_timer);
1384
1385 tid_agg_rx = sta->ampdu_mlme.tid_rx[tid];
1386
1387 /* prepare reordering buffer */
1388 tid_agg_rx->reorder_buf =
1389 kmalloc(buf_size * sizeof(struct sk_buff *), GFP_ATOMIC);
1390 if (!tid_agg_rx->reorder_buf) {
1391#ifdef CONFIG_MAC80211_HT_DEBUG
1392 if (net_ratelimit())
1393 printk(KERN_ERR "can not allocate reordering buffer "
1394 "to tid %d\n", tid);
1395#endif
1396 kfree(sta->ampdu_mlme.tid_rx[tid]);
1397 goto end;
1398 }
1399 memset(tid_agg_rx->reorder_buf, 0,
1400 buf_size * sizeof(struct sk_buff *));
1401
1402 if (local->ops->ampdu_action)
1403 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_START,
1404 sta->addr, tid, &start_seq_num);
1405#ifdef CONFIG_MAC80211_HT_DEBUG
1406 printk(KERN_DEBUG "Rx A-MPDU request on tid %d result %d\n", tid, ret);
1407#endif /* CONFIG_MAC80211_HT_DEBUG */
1408
1409 if (ret) {
1410 kfree(tid_agg_rx->reorder_buf);
1411 kfree(tid_agg_rx);
1412 sta->ampdu_mlme.tid_rx[tid] = NULL;
1413 goto end;
1414 }
1415
1416 /* change state and send addba resp */
1417 sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_OPERATIONAL;
1418 tid_agg_rx->dialog_token = dialog_token;
1419 tid_agg_rx->ssn = start_seq_num;
1420 tid_agg_rx->head_seq_num = start_seq_num;
1421 tid_agg_rx->buf_size = buf_size;
1422 tid_agg_rx->timeout = timeout;
1423 tid_agg_rx->stored_mpdu_num = 0;
1424 status = WLAN_STATUS_SUCCESS;
1425end:
1426 spin_unlock_bh(&sta->lock);
1427
1428end_no_lock:
1429 ieee80211_send_addba_resp(sta->sdata->dev, sta->addr, tid,
1430 dialog_token, status, 1, buf_size, timeout);
1431 rcu_read_unlock();
1432} 812}
1433 813
1434static void ieee80211_sta_process_addba_resp(struct net_device *dev, 814static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1435 struct ieee80211_mgmt *mgmt, 815 struct ieee80211_if_sta *ifsta, bool deauth,
1436 size_t len) 816 bool self_disconnected, u16 reason)
1437{ 817{
1438 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 818 struct ieee80211_local *local = sdata->local;
1439 struct ieee80211_hw *hw = &local->hw;
1440 struct sta_info *sta; 819 struct sta_info *sta;
1441 u16 capab; 820 u32 changed = BSS_CHANGED_ASSOC;
1442 u16 tid;
1443 u8 *state;
1444 821
1445 rcu_read_lock(); 822 rcu_read_lock();
1446 823
1447 sta = sta_info_get(local, mgmt->sa); 824 sta = sta_info_get(local, ifsta->bssid);
1448 if (!sta) { 825 if (!sta) {
1449 rcu_read_unlock(); 826 rcu_read_unlock();
1450 return; 827 return;
1451 } 828 }
1452 829
1453 capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab); 830 if (deauth) {
1454 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;
1455 836
1456 state = &sta->ampdu_mlme.tid_state_tx[tid]; 837 netif_tx_stop_all_queues(sdata->dev);
838 netif_carrier_off(sdata->dev);
1457 839
1458 spin_lock_bh(&sta->lock); 840 ieee80211_sta_tear_down_BA_sessions(sdata, sta->sta.addr);
1459 841
1460 if (!(*state & HT_ADDBA_REQUESTED_MSK)) { 842 if (self_disconnected) {
1461 spin_unlock_bh(&sta->lock); 843 if (deauth)
1462 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);
1463 } 849 }
1464 850
1465 if (mgmt->u.action.u.addba_resp.dialog_token != 851 ifsta->flags &= ~IEEE80211_STA_ASSOCIATED;
1466 sta->ampdu_mlme.tid_tx[tid]->dialog_token) { 852 changed |= ieee80211_reset_erp_info(sdata);
1467 spin_unlock_bh(&sta->lock);
1468#ifdef CONFIG_MAC80211_HT_DEBUG
1469 printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
1470#endif /* CONFIG_MAC80211_HT_DEBUG */
1471 goto addba_resp_exit;
1472 }
1473 853
1474 del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); 854 if (sdata->bss_conf.assoc_ht)
1475#ifdef CONFIG_MAC80211_HT_DEBUG 855 changed |= BSS_CHANGED_HT;
1476 printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid);
1477#endif /* CONFIG_MAC80211_HT_DEBUG */
1478 if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
1479 == WLAN_STATUS_SUCCESS) {
1480 *state |= HT_ADDBA_RECEIVED_MSK;
1481 sta->ampdu_mlme.addba_req_num[tid] = 0;
1482 856
1483 if (*state == HT_AGG_STATE_OPERATIONAL) 857 sdata->bss_conf.assoc_ht = 0;
1484 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;
1485 860
1486 spin_unlock_bh(&sta->lock); 861 ieee80211_led_assoc(local, 0);
1487 } else { 862 sdata->bss_conf.assoc = 0;
1488 sta->ampdu_mlme.addba_req_num[tid]++; 863
1489 /* this will allow the state check in stop_BA_session */ 864 ieee80211_sta_send_apinfo(sdata, ifsta);
1490 *state = HT_AGG_STATE_OPERATIONAL; 865
1491 spin_unlock_bh(&sta->lock); 866 if (self_disconnected)
1492 ieee80211_stop_tx_ba_session(hw, sta->addr, tid, 867 ifsta->state = IEEE80211_STA_MLME_DISABLED;
1493 WLAN_BACK_INITIATOR); 868
1494 } 869 sta_info_unlink(&sta);
1495 870
1496addba_resp_exit:
1497 rcu_read_unlock(); 871 rcu_read_unlock();
872
873 sta_info_destroy(sta);
1498} 874}
1499 875
1500void ieee80211_send_delba(struct net_device *dev, const u8 *da, u16 tid, 876static int ieee80211_sta_wep_configured(struct ieee80211_sub_if_data *sdata)
1501 u16 initiator, u16 reason_code)
1502{ 877{
1503 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 878 if (!sdata || !sdata->default_key ||
1504 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 879 sdata->default_key->conf.alg != ALG_WEP)
1505 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 880 return 0;
1506 struct sk_buff *skb; 881 return 1;
1507 struct ieee80211_mgmt *mgmt; 882}
1508 u16 params;
1509
1510 skb = dev_alloc_skb(sizeof(*mgmt) + local->hw.extra_tx_headroom);
1511
1512 if (!skb) {
1513 printk(KERN_ERR "%s: failed to allocate buffer "
1514 "for delba frame\n", dev->name);
1515 return;
1516 }
1517 883
1518 skb_reserve(skb, local->hw.extra_tx_headroom); 884static int ieee80211_privacy_mismatch(struct ieee80211_sub_if_data *sdata,
1519 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); 885 struct ieee80211_if_sta *ifsta)
1520 memset(mgmt, 0, 24); 886{
1521 memcpy(mgmt->da, da, ETH_ALEN); 887 struct ieee80211_local *local = sdata->local;
1522 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); 888 struct ieee80211_bss *bss;
1523 if (sdata->vif.type == IEEE80211_IF_TYPE_AP) 889 int bss_privacy;
1524 memcpy(mgmt->bssid, dev->dev_addr, ETH_ALEN); 890 int wep_privacy;
1525 else 891 int privacy_invoked;
1526 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
1527 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
1528 IEEE80211_STYPE_ACTION);
1529 892
1530 skb_put(skb, 1 + sizeof(mgmt->u.action.u.delba)); 893 if (!ifsta || (ifsta->flags & IEEE80211_STA_MIXED_CELL))
894 return 0;
1531 895
1532 mgmt->u.action.category = WLAN_CATEGORY_BACK; 896 bss = ieee80211_rx_bss_get(local, ifsta->bssid,
1533 mgmt->u.action.u.delba.action_code = WLAN_ACTION_DELBA; 897 local->hw.conf.channel->center_freq,
1534 params = (u16)(initiator << 11); /* bit 11 initiator */ 898 ifsta->ssid, ifsta->ssid_len);
1535 params |= (u16)(tid << 12); /* bit 15:12 TID number */ 899 if (!bss)
900 return 0;
1536 901
1537 mgmt->u.action.u.delba.params = cpu_to_le16(params); 902 bss_privacy = !!(bss->capability & WLAN_CAPABILITY_PRIVACY);
1538 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);
1539 905
1540 ieee80211_sta_tx(dev, skb, 0); 906 ieee80211_rx_bss_put(local, bss);
1541}
1542 907
1543void ieee80211_send_bar(struct net_device *dev, u8 *ra, u16 tid, u16 ssn) 908 if ((bss_privacy == wep_privacy) || (bss_privacy == privacy_invoked))
1544{ 909 return 0;
1545 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1546 struct sk_buff *skb;
1547 struct ieee80211_bar *bar;
1548 u16 bar_control = 0;
1549 910
1550 skb = dev_alloc_skb(sizeof(*bar) + local->hw.extra_tx_headroom); 911 return 1;
1551 if (!skb) {
1552 printk(KERN_ERR "%s: failed to allocate buffer for "
1553 "bar frame\n", dev->name);
1554 return;
1555 }
1556 skb_reserve(skb, local->hw.extra_tx_headroom);
1557 bar = (struct ieee80211_bar *)skb_put(skb, sizeof(*bar));
1558 memset(bar, 0, sizeof(*bar));
1559 bar->frame_control = IEEE80211_FC(IEEE80211_FTYPE_CTL,
1560 IEEE80211_STYPE_BACK_REQ);
1561 memcpy(bar->ra, ra, ETH_ALEN);
1562 memcpy(bar->ta, dev->dev_addr, ETH_ALEN);
1563 bar_control |= (u16)IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL;
1564 bar_control |= (u16)IEEE80211_BAR_CTRL_CBMTID_COMPRESSED_BA;
1565 bar_control |= (u16)(tid << 12);
1566 bar->control = cpu_to_le16(bar_control);
1567 bar->start_seq_num = cpu_to_le16(ssn);
1568
1569 ieee80211_sta_tx(dev, skb, 0);
1570} 912}
1571 913
1572void ieee80211_sta_stop_rx_ba_session(struct net_device *dev, u8 *ra, u16 tid, 914static void ieee80211_associate(struct ieee80211_sub_if_data *sdata,
1573 u16 initiator, u16 reason) 915 struct ieee80211_if_sta *ifsta)
1574{ 916{
1575 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1576 struct ieee80211_hw *hw = &local->hw;
1577 struct sta_info *sta;
1578 int ret, i;
1579 DECLARE_MAC_BUF(mac); 917 DECLARE_MAC_BUF(mac);
1580 918
1581 rcu_read_lock(); 919 ifsta->assoc_tries++;
1582 920 if (ifsta->assoc_tries > IEEE80211_ASSOC_MAX_TRIES) {
1583 sta = sta_info_get(local, ra); 921 printk(KERN_DEBUG "%s: association with AP %s"
1584 if (!sta) { 922 " timed out\n",
1585 rcu_read_unlock(); 923 sdata->dev->name, print_mac(mac, ifsta->bssid));
924 ifsta->state = IEEE80211_STA_MLME_DISABLED;
1586 return; 925 return;
1587 } 926 }
1588 927
1589 /* check if TID is in operational state */ 928 ifsta->state = IEEE80211_STA_MLME_ASSOCIATE;
1590 spin_lock_bh(&sta->lock); 929 printk(KERN_DEBUG "%s: associate with AP %s\n",
1591 if (sta->ampdu_mlme.tid_state_rx[tid] 930 sdata->dev->name, print_mac(mac, ifsta->bssid));
1592 != HT_AGG_STATE_OPERATIONAL) { 931 if (ieee80211_privacy_mismatch(sdata, ifsta)) {
1593 spin_unlock_bh(&sta->lock); 932 printk(KERN_DEBUG "%s: mismatch in privacy configuration and "
1594 rcu_read_unlock(); 933 "mixed-cell disabled - abort association\n", sdata->dev->name);
934 ifsta->state = IEEE80211_STA_MLME_DISABLED;
1595 return; 935 return;
1596 } 936 }
1597 sta->ampdu_mlme.tid_state_rx[tid] =
1598 HT_AGG_STATE_REQ_STOP_BA_MSK |
1599 (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
1600 spin_unlock_bh(&sta->lock);
1601
1602 /* stop HW Rx aggregation. ampdu_action existence
1603 * already verified in session init so we add the BUG_ON */
1604 BUG_ON(!local->ops->ampdu_action);
1605
1606#ifdef CONFIG_MAC80211_HT_DEBUG
1607 printk(KERN_DEBUG "Rx BA session stop requested for %s tid %u\n",
1608 print_mac(mac, ra), tid);
1609#endif /* CONFIG_MAC80211_HT_DEBUG */
1610
1611 ret = local->ops->ampdu_action(hw, IEEE80211_AMPDU_RX_STOP,
1612 ra, tid, NULL);
1613 if (ret)
1614 printk(KERN_DEBUG "HW problem - can not stop rx "
1615 "aggregation for tid %d\n", tid);
1616
1617 /* shutdown timer has not expired */
1618 if (initiator != WLAN_BACK_TIMER)
1619 del_timer_sync(&sta->ampdu_mlme.tid_rx[tid]->session_timer);
1620
1621 /* check if this is a self generated aggregation halt */
1622 if (initiator == WLAN_BACK_RECIPIENT || initiator == WLAN_BACK_TIMER)
1623 ieee80211_send_delba(dev, ra, tid, 0, reason);
1624
1625 /* free the reordering buffer */
1626 for (i = 0; i < sta->ampdu_mlme.tid_rx[tid]->buf_size; i++) {
1627 if (sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]) {
1628 /* release the reordered frames */
1629 dev_kfree_skb(sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]);
1630 sta->ampdu_mlme.tid_rx[tid]->stored_mpdu_num--;
1631 sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i] = NULL;
1632 }
1633 }
1634 /* free resources */
1635 kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_buf);
1636 kfree(sta->ampdu_mlme.tid_rx[tid]);
1637 sta->ampdu_mlme.tid_rx[tid] = NULL;
1638 sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_IDLE;
1639 937
1640 rcu_read_unlock(); 938 ieee80211_send_assoc(sdata, ifsta);
939
940 mod_timer(&ifsta->timer, jiffies + IEEE80211_ASSOC_TIMEOUT);
1641} 941}
1642 942
1643 943
1644static void ieee80211_sta_process_delba(struct net_device *dev, 944static void ieee80211_associated(struct ieee80211_sub_if_data *sdata,
1645 struct ieee80211_mgmt *mgmt, size_t len) 945 struct ieee80211_if_sta *ifsta)
1646{ 946{
1647 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 947 struct ieee80211_local *local = sdata->local;
1648 struct sta_info *sta; 948 struct sta_info *sta;
1649 u16 tid, params; 949 int disassoc;
1650 u16 initiator;
1651 DECLARE_MAC_BUF(mac); 950 DECLARE_MAC_BUF(mac);
1652 951
1653 rcu_read_lock(); 952 /* TODO: start monitoring current AP signal quality and number of
1654 953 * missed beacons. Scan other channels every now and then and search
1655 sta = sta_info_get(local, mgmt->sa); 954 * for better APs. */
1656 if (!sta) { 955 /* TODO: remove expired BSSes */
1657 rcu_read_unlock();
1658 return;
1659 }
1660
1661 params = le16_to_cpu(mgmt->u.action.u.delba.params);
1662 tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12;
1663 initiator = (params & IEEE80211_DELBA_PARAM_INITIATOR_MASK) >> 11;
1664
1665#ifdef CONFIG_MAC80211_HT_DEBUG
1666 if (net_ratelimit())
1667 printk(KERN_DEBUG "delba from %s (%s) tid %d reason code %d\n",
1668 print_mac(mac, mgmt->sa),
1669 initiator ? "initiator" : "recipient", tid,
1670 mgmt->u.action.u.delba.reason_code);
1671#endif /* CONFIG_MAC80211_HT_DEBUG */
1672
1673 if (initiator == WLAN_BACK_INITIATOR)
1674 ieee80211_sta_stop_rx_ba_session(dev, sta->addr, tid,
1675 WLAN_BACK_INITIATOR, 0);
1676 else { /* WLAN_BACK_RECIPIENT */
1677 spin_lock_bh(&sta->lock);
1678 sta->ampdu_mlme.tid_state_tx[tid] =
1679 HT_AGG_STATE_OPERATIONAL;
1680 spin_unlock_bh(&sta->lock);
1681 ieee80211_stop_tx_ba_session(&local->hw, sta->addr, tid,
1682 WLAN_BACK_RECIPIENT);
1683 }
1684 rcu_read_unlock();
1685}
1686 956
1687/* 957 ifsta->state = IEEE80211_STA_MLME_ASSOCIATED;
1688 * After sending add Block Ack request we activated a timer until
1689 * add Block Ack response will arrive from the recipient.
1690 * If this timer expires sta_addba_resp_timer_expired will be executed.
1691 */
1692void sta_addba_resp_timer_expired(unsigned long data)
1693{
1694 /* not an elegant detour, but there is no choice as the timer passes
1695 * only one argument, and both sta_info and TID are needed, so init
1696 * flow in sta_info_create gives the TID as data, while the timer_to_id
1697 * array gives the sta through container_of */
1698 u16 tid = *(u8 *)data;
1699 struct sta_info *temp_sta = container_of((void *)data,
1700 struct sta_info, timer_to_tid[tid]);
1701
1702 struct ieee80211_local *local = temp_sta->local;
1703 struct ieee80211_hw *hw = &local->hw;
1704 struct sta_info *sta;
1705 u8 *state;
1706 958
1707 rcu_read_lock(); 959 rcu_read_lock();
1708 960
1709 sta = sta_info_get(local, temp_sta->addr); 961 sta = sta_info_get(local, ifsta->bssid);
1710 if (!sta) { 962 if (!sta) {
1711 rcu_read_unlock(); 963 printk(KERN_DEBUG "%s: No STA entry for own AP %s\n",
1712 return; 964 sdata->dev->name, print_mac(mac, ifsta->bssid));
1713 } 965 disassoc = 1;
1714 966 } else {
1715 state = &sta->ampdu_mlme.tid_state_tx[tid]; 967 disassoc = 0;
1716 /* check if the TID waits for addBA response */ 968 if (time_after(jiffies,
1717 spin_lock_bh(&sta->lock); 969 sta->last_rx + IEEE80211_MONITORING_INTERVAL)) {
1718 if (!(*state & HT_ADDBA_REQUESTED_MSK)) { 970 if (ifsta->flags & IEEE80211_STA_PROBEREQ_POLL) {
1719 spin_unlock_bh(&sta->lock); 971 printk(KERN_DEBUG "%s: No ProbeResp from "
1720 *state = HT_AGG_STATE_IDLE; 972 "current AP %s - assume out of "
1721#ifdef CONFIG_MAC80211_HT_DEBUG 973 "range\n",
1722 printk(KERN_DEBUG "timer expired on tid %d but we are not " 974 sdata->dev->name, print_mac(mac, ifsta->bssid));
1723 "expecting addBA response there", tid); 975 disassoc = 1;
1724#endif 976 } else
1725 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 }
1726 } 991 }
1727 992
1728#ifdef CONFIG_MAC80211_HT_DEBUG
1729 printk(KERN_DEBUG "addBA response timer expired on tid %d\n", tid);
1730#endif
1731
1732 /* go through the state check in stop_BA_session */
1733 *state = HT_AGG_STATE_OPERATIONAL;
1734 spin_unlock_bh(&sta->lock);
1735 ieee80211_stop_tx_ba_session(hw, temp_sta->addr, tid,
1736 WLAN_BACK_INITIATOR);
1737
1738timer_expired_exit:
1739 rcu_read_unlock(); 993 rcu_read_unlock();
1740}
1741 994
1742/* 995 if (disassoc)
1743 * After accepting the AddBA Request we activated a timer, 996 ieee80211_set_disassoc(sdata, ifsta, true, true,
1744 * resetting it after each frame that arrives from the originator. 997 WLAN_REASON_PREV_AUTH_NOT_VALID);
1745 * if this timer expires ieee80211_sta_stop_rx_ba_session will be executed. 998 else
1746 */ 999 mod_timer(&ifsta->timer, jiffies +
1747static void sta_rx_agg_session_timer_expired(unsigned long data) 1000 IEEE80211_MONITORING_INTERVAL);
1748{
1749 /* not an elegant detour, but there is no choice as the timer passes
1750 * only one argument, and various sta_info are needed here, so init
1751 * flow in sta_info_create gives the TID as data, while the timer_to_id
1752 * array gives the sta through container_of */
1753 u8 *ptid = (u8 *)data;
1754 u8 *timer_to_id = ptid - *ptid;
1755 struct sta_info *sta = container_of(timer_to_id, struct sta_info,
1756 timer_to_tid[0]);
1757
1758#ifdef CONFIG_MAC80211_HT_DEBUG
1759 printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid);
1760#endif
1761 ieee80211_sta_stop_rx_ba_session(sta->sdata->dev, sta->addr,
1762 (u16)*ptid, WLAN_BACK_TIMER,
1763 WLAN_REASON_QSTA_TIMEOUT);
1764} 1001}
1765 1002
1766void ieee80211_sta_tear_down_BA_sessions(struct net_device *dev, u8 *addr)
1767{
1768 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1769 int i;
1770 1003
1771 for (i = 0; i < STA_TID_NUM; i++) { 1004static void ieee80211_auth_completed(struct ieee80211_sub_if_data *sdata,
1772 ieee80211_stop_tx_ba_session(&local->hw, addr, i, 1005 struct ieee80211_if_sta *ifsta)
1773 WLAN_BACK_INITIATOR); 1006{
1774 ieee80211_sta_stop_rx_ba_session(dev, addr, i, 1007 printk(KERN_DEBUG "%s: authenticated\n", sdata->dev->name);
1775 WLAN_BACK_RECIPIENT, 1008 ifsta->flags |= IEEE80211_STA_AUTHENTICATED;
1776 WLAN_REASON_QSTA_LEAVE_QBSS); 1009 ieee80211_associate(sdata, ifsta);
1777 }
1778} 1010}
1779 1011
1780static void ieee80211_send_refuse_measurement_request(struct net_device *dev,
1781 struct ieee80211_msrment_ie *request_ie,
1782 const u8 *da, const u8 *bssid,
1783 u8 dialog_token)
1784{
1785 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1786 struct sk_buff *skb;
1787 struct ieee80211_mgmt *msr_report;
1788 1012
1789 skb = dev_alloc_skb(sizeof(*msr_report) + local->hw.extra_tx_headroom + 1013static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
1790 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;
1791 1020
1792 if (!skb) { 1021 pos = mgmt->u.auth.variable;
1793 printk(KERN_ERR "%s: failed to allocate buffer for " 1022 ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
1794 "measurement report frame\n", dev->name); 1023 if (!elems.challenge)
1795 return; 1024 return;
1796 } 1025 ieee80211_send_auth(sdata, ifsta, 3, elems.challenge - 2,
1797 1026 elems.challenge_len + 2, 1);
1798 skb_reserve(skb, local->hw.extra_tx_headroom);
1799 msr_report = (struct ieee80211_mgmt *)skb_put(skb, 24);
1800 memset(msr_report, 0, 24);
1801 memcpy(msr_report->da, da, ETH_ALEN);
1802 memcpy(msr_report->sa, dev->dev_addr, ETH_ALEN);
1803 memcpy(msr_report->bssid, bssid, ETH_ALEN);
1804 msr_report->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT,
1805 IEEE80211_STYPE_ACTION);
1806
1807 skb_put(skb, 1 + sizeof(msr_report->u.action.u.measurement));
1808 msr_report->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT;
1809 msr_report->u.action.u.measurement.action_code =
1810 WLAN_ACTION_SPCT_MSR_RPRT;
1811 msr_report->u.action.u.measurement.dialog_token = dialog_token;
1812
1813 msr_report->u.action.u.measurement.element_id = WLAN_EID_MEASURE_REPORT;
1814 msr_report->u.action.u.measurement.length =
1815 sizeof(struct ieee80211_msrment_ie);
1816
1817 memset(&msr_report->u.action.u.measurement.msr_elem, 0,
1818 sizeof(struct ieee80211_msrment_ie));
1819 msr_report->u.action.u.measurement.msr_elem.token = request_ie->token;
1820 msr_report->u.action.u.measurement.msr_elem.mode |=
1821 IEEE80211_SPCT_MSR_RPRT_MODE_REFUSED;
1822 msr_report->u.action.u.measurement.msr_elem.type = request_ie->type;
1823
1824 ieee80211_sta_tx(dev, skb, 0);
1825}
1826
1827static void ieee80211_sta_process_measurement_req(struct net_device *dev,
1828 struct ieee80211_mgmt *mgmt,
1829 size_t len)
1830{
1831 /*
1832 * Ignoring measurement request is spec violation.
1833 * Mandatory measurements must be reported optional
1834 * measurements might be refused or reported incapable
1835 * For now just refuse
1836 * TODO: Answer basic measurement as unmeasured
1837 */
1838 ieee80211_send_refuse_measurement_request(dev,
1839 &mgmt->u.action.u.measurement.msr_elem,
1840 mgmt->sa, mgmt->bssid,
1841 mgmt->u.action.u.measurement.dialog_token);
1842} 1027}
1843 1028
1844 1029static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata,
1845static void ieee80211_rx_mgmt_auth(struct net_device *dev,
1846 struct ieee80211_if_sta *ifsta, 1030 struct ieee80211_if_sta *ifsta,
1847 struct ieee80211_mgmt *mgmt, 1031 struct ieee80211_mgmt *mgmt,
1848 size_t len) 1032 size_t len)
1849{ 1033{
1850 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1851 u16 auth_alg, auth_transaction, status_code; 1034 u16 auth_alg, auth_transaction, status_code;
1852 DECLARE_MAC_BUF(mac); 1035 DECLARE_MAC_BUF(mac);
1853 1036
1854 if (ifsta->state != IEEE80211_AUTHENTICATE && 1037 if (ifsta->state != IEEE80211_STA_MLME_AUTHENTICATE &&
1855 sdata->vif.type != IEEE80211_IF_TYPE_IBSS) 1038 sdata->vif.type != NL80211_IFTYPE_ADHOC)
1856 return; 1039 return;
1857 1040
1858 if (len < 24 + 6) 1041 if (len < 24 + 6)
1859 return; 1042 return;
1860 1043
1861 if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS && 1044 if (sdata->vif.type != NL80211_IFTYPE_ADHOC &&
1862 memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0) 1045 memcmp(ifsta->bssid, mgmt->sa, ETH_ALEN) != 0)
1863 return; 1046 return;
1864 1047
1865 if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS && 1048 if (sdata->vif.type != NL80211_IFTYPE_ADHOC &&
1866 memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0) 1049 memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0)
1867 return; 1050 return;
1868 1051
@@ -1870,7 +1053,7 @@ static void ieee80211_rx_mgmt_auth(struct net_device *dev,
1870 auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); 1053 auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
1871 status_code = le16_to_cpu(mgmt->u.auth.status_code); 1054 status_code = le16_to_cpu(mgmt->u.auth.status_code);
1872 1055
1873 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { 1056 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
1874 /* 1057 /*
1875 * IEEE 802.11 standard does not require authentication in IBSS 1058 * IEEE 802.11 standard does not require authentication in IBSS
1876 * networks and most implementations do not seem to use it. 1059 * networks and most implementations do not seem to use it.
@@ -1879,7 +1062,7 @@ static void ieee80211_rx_mgmt_auth(struct net_device *dev,
1879 */ 1062 */
1880 if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) 1063 if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1)
1881 return; 1064 return;
1882 ieee80211_send_auth(dev, ifsta, 2, NULL, 0, 0); 1065 ieee80211_send_auth(sdata, ifsta, 2, NULL, 0, 0);
1883 } 1066 }
1884 1067
1885 if (auth_alg != ifsta->auth_alg || 1068 if (auth_alg != ifsta->auth_alg ||
@@ -1912,7 +1095,7 @@ static void ieee80211_rx_mgmt_auth(struct net_device *dev,
1912 algs[pos] == 0xff) 1095 algs[pos] == 0xff)
1913 continue; 1096 continue;
1914 if (algs[pos] == WLAN_AUTH_SHARED_KEY && 1097 if (algs[pos] == WLAN_AUTH_SHARED_KEY &&
1915 !ieee80211_sta_wep_configured(dev)) 1098 !ieee80211_sta_wep_configured(sdata))
1916 continue; 1099 continue;
1917 ifsta->auth_alg = algs[pos]; 1100 ifsta->auth_alg = algs[pos];
1918 break; 1101 break;
@@ -1924,19 +1107,19 @@ static void ieee80211_rx_mgmt_auth(struct net_device *dev,
1924 switch (ifsta->auth_alg) { 1107 switch (ifsta->auth_alg) {
1925 case WLAN_AUTH_OPEN: 1108 case WLAN_AUTH_OPEN:
1926 case WLAN_AUTH_LEAP: 1109 case WLAN_AUTH_LEAP:
1927 ieee80211_auth_completed(dev, ifsta); 1110 ieee80211_auth_completed(sdata, ifsta);
1928 break; 1111 break;
1929 case WLAN_AUTH_SHARED_KEY: 1112 case WLAN_AUTH_SHARED_KEY:
1930 if (ifsta->auth_transaction == 4) 1113 if (ifsta->auth_transaction == 4)
1931 ieee80211_auth_completed(dev, ifsta); 1114 ieee80211_auth_completed(sdata, ifsta);
1932 else 1115 else
1933 ieee80211_auth_challenge(dev, ifsta, mgmt, len); 1116 ieee80211_auth_challenge(sdata, ifsta, mgmt, len);
1934 break; 1117 break;
1935 } 1118 }
1936} 1119}
1937 1120
1938 1121
1939static void ieee80211_rx_mgmt_deauth(struct net_device *dev, 1122static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1940 struct ieee80211_if_sta *ifsta, 1123 struct ieee80211_if_sta *ifsta,
1941 struct ieee80211_mgmt *mgmt, 1124 struct ieee80211_mgmt *mgmt,
1942 size_t len) 1125 size_t len)
@@ -1953,22 +1136,22 @@ static void ieee80211_rx_mgmt_deauth(struct net_device *dev,
1953 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); 1136 reason_code = le16_to_cpu(mgmt->u.deauth.reason_code);
1954 1137
1955 if (ifsta->flags & IEEE80211_STA_AUTHENTICATED) 1138 if (ifsta->flags & IEEE80211_STA_AUTHENTICATED)
1956 printk(KERN_DEBUG "%s: deauthenticated\n", dev->name); 1139 printk(KERN_DEBUG "%s: deauthenticated\n", sdata->dev->name);
1957 1140
1958 if (ifsta->state == IEEE80211_AUTHENTICATE || 1141 if (ifsta->state == IEEE80211_STA_MLME_AUTHENTICATE ||
1959 ifsta->state == IEEE80211_ASSOCIATE || 1142 ifsta->state == IEEE80211_STA_MLME_ASSOCIATE ||
1960 ifsta->state == IEEE80211_ASSOCIATED) { 1143 ifsta->state == IEEE80211_STA_MLME_ASSOCIATED) {
1961 ifsta->state = IEEE80211_AUTHENTICATE; 1144 ifsta->state = IEEE80211_STA_MLME_DIRECT_PROBE;
1962 mod_timer(&ifsta->timer, jiffies + 1145 mod_timer(&ifsta->timer, jiffies +
1963 IEEE80211_RETRY_AUTH_INTERVAL); 1146 IEEE80211_RETRY_AUTH_INTERVAL);
1964 } 1147 }
1965 1148
1966 ieee80211_set_disassoc(dev, ifsta, 1); 1149 ieee80211_set_disassoc(sdata, ifsta, true, false, 0);
1967 ifsta->flags &= ~IEEE80211_STA_AUTHENTICATED; 1150 ifsta->flags &= ~IEEE80211_STA_AUTHENTICATED;
1968} 1151}
1969 1152
1970 1153
1971static void ieee80211_rx_mgmt_disassoc(struct net_device *dev, 1154static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
1972 struct ieee80211_if_sta *ifsta, 1155 struct ieee80211_if_sta *ifsta,
1973 struct ieee80211_mgmt *mgmt, 1156 struct ieee80211_mgmt *mgmt,
1974 size_t len) 1157 size_t len)
@@ -1985,15 +1168,15 @@ static void ieee80211_rx_mgmt_disassoc(struct net_device *dev,
1985 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); 1168 reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code);
1986 1169
1987 if (ifsta->flags & IEEE80211_STA_ASSOCIATED) 1170 if (ifsta->flags & IEEE80211_STA_ASSOCIATED)
1988 printk(KERN_DEBUG "%s: disassociated\n", dev->name); 1171 printk(KERN_DEBUG "%s: disassociated\n", sdata->dev->name);
1989 1172
1990 if (ifsta->state == IEEE80211_ASSOCIATED) { 1173 if (ifsta->state == IEEE80211_STA_MLME_ASSOCIATED) {
1991 ifsta->state = IEEE80211_ASSOCIATE; 1174 ifsta->state = IEEE80211_STA_MLME_ASSOCIATE;
1992 mod_timer(&ifsta->timer, jiffies + 1175 mod_timer(&ifsta->timer, jiffies +
1993 IEEE80211_RETRY_AUTH_INTERVAL); 1176 IEEE80211_RETRY_AUTH_INTERVAL);
1994 } 1177 }
1995 1178
1996 ieee80211_set_disassoc(dev, ifsta, 0); 1179 ieee80211_set_disassoc(sdata, ifsta, false, false, 0);
1997} 1180}
1998 1181
1999 1182
@@ -2004,7 +1187,6 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2004 int reassoc) 1187 int reassoc)
2005{ 1188{
2006 struct ieee80211_local *local = sdata->local; 1189 struct ieee80211_local *local = sdata->local;
2007 struct net_device *dev = sdata->dev;
2008 struct ieee80211_supported_band *sband; 1190 struct ieee80211_supported_band *sband;
2009 struct sta_info *sta; 1191 struct sta_info *sta;
2010 u64 rates, basic_rates; 1192 u64 rates, basic_rates;
@@ -2019,7 +1201,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2019 /* AssocResp and ReassocResp have identical structure, so process both 1201 /* AssocResp and ReassocResp have identical structure, so process both
2020 * of them in this function. */ 1202 * of them in this function. */
2021 1203
2022 if (ifsta->state != IEEE80211_ASSOCIATE) 1204 if (ifsta->state != IEEE80211_STA_MLME_ASSOCIATE)
2023 return; 1205 return;
2024 1206
2025 if (len < 24 + 6) 1207 if (len < 24 + 6)
@@ -2034,12 +1216,12 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2034 1216
2035 printk(KERN_DEBUG "%s: RX %sssocResp from %s (capab=0x%x " 1217 printk(KERN_DEBUG "%s: RX %sssocResp from %s (capab=0x%x "
2036 "status=%d aid=%d)\n", 1218 "status=%d aid=%d)\n",
2037 dev->name, reassoc ? "Rea" : "A", print_mac(mac, mgmt->sa), 1219 sdata->dev->name, reassoc ? "Rea" : "A", print_mac(mac, mgmt->sa),
2038 capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14)))); 1220 capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14))));
2039 1221
2040 if (status_code != WLAN_STATUS_SUCCESS) { 1222 if (status_code != WLAN_STATUS_SUCCESS) {
2041 printk(KERN_DEBUG "%s: AP denied association (code=%d)\n", 1223 printk(KERN_DEBUG "%s: AP denied association (code=%d)\n",
2042 dev->name, status_code); 1224 sdata->dev->name, status_code);
2043 /* if this was a reassociation, ensure we try a "full" 1225 /* if this was a reassociation, ensure we try a "full"
2044 * association next time. This works around some broken APs 1226 * association next time. This works around some broken APs
2045 * which do not correctly reject reassociation requests. */ 1227 * which do not correctly reject reassociation requests. */
@@ -2049,7 +1231,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2049 1231
2050 if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) 1232 if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
2051 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 "
2052 "set\n", dev->name, aid); 1234 "set\n", sdata->dev->name, aid);
2053 aid &= ~(BIT(15) | BIT(14)); 1235 aid &= ~(BIT(15) | BIT(14));
2054 1236
2055 pos = mgmt->u.assoc_resp.variable; 1237 pos = mgmt->u.assoc_resp.variable;
@@ -2057,11 +1239,11 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2057 1239
2058 if (!elems.supp_rates) { 1240 if (!elems.supp_rates) {
2059 printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n", 1241 printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n",
2060 dev->name); 1242 sdata->dev->name);
2061 return; 1243 return;
2062 } 1244 }
2063 1245
2064 printk(KERN_DEBUG "%s: associated\n", dev->name); 1246 printk(KERN_DEBUG "%s: associated\n", sdata->dev->name);
2065 ifsta->aid = aid; 1247 ifsta->aid = aid;
2066 ifsta->ap_capab = capab_info; 1248 ifsta->ap_capab = capab_info;
2067 1249
@@ -2076,17 +1258,17 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2076 /* Add STA entry for the AP */ 1258 /* Add STA entry for the AP */
2077 sta = sta_info_get(local, ifsta->bssid); 1259 sta = sta_info_get(local, ifsta->bssid);
2078 if (!sta) { 1260 if (!sta) {
2079 struct ieee80211_sta_bss *bss; 1261 struct ieee80211_bss *bss;
2080 int err; 1262 int err;
2081 1263
2082 sta = sta_info_alloc(sdata, ifsta->bssid, GFP_ATOMIC); 1264 sta = sta_info_alloc(sdata, ifsta->bssid, GFP_ATOMIC);
2083 if (!sta) { 1265 if (!sta) {
2084 printk(KERN_DEBUG "%s: failed to alloc STA entry for" 1266 printk(KERN_DEBUG "%s: failed to alloc STA entry for"
2085 " the AP\n", dev->name); 1267 " the AP\n", sdata->dev->name);
2086 rcu_read_unlock(); 1268 rcu_read_unlock();
2087 return; 1269 return;
2088 } 1270 }
2089 bss = ieee80211_rx_bss_get(dev, ifsta->bssid, 1271 bss = ieee80211_rx_bss_get(local, ifsta->bssid,
2090 local->hw.conf.channel->center_freq, 1272 local->hw.conf.channel->center_freq,
2091 ifsta->ssid, ifsta->ssid_len); 1273 ifsta->ssid, ifsta->ssid_len);
2092 if (bss) { 1274 if (bss) {
@@ -2099,7 +1281,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2099 err = sta_info_insert(sta); 1281 err = sta_info_insert(sta);
2100 if (err) { 1282 if (err) {
2101 printk(KERN_DEBUG "%s: failed to insert STA entry for" 1283 printk(KERN_DEBUG "%s: failed to insert STA entry for"
2102 " the AP (error %d)\n", dev->name, err); 1284 " the AP (error %d)\n", sdata->dev->name, err);
2103 rcu_read_unlock(); 1285 rcu_read_unlock();
2104 return; 1286 return;
2105 } 1287 }
@@ -2152,8 +1334,8 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2152 } 1334 }
2153 } 1335 }
2154 1336
2155 sta->supp_rates[local->hw.conf.channel->band] = rates; 1337 sta->sta.supp_rates[local->hw.conf.channel->band] = rates;
2156 sdata->basic_rates = basic_rates; 1338 sdata->bss_conf.basic_rates = basic_rates;
2157 1339
2158 /* cf. IEEE 802.11 9.2.12 */ 1340 /* cf. IEEE 802.11 9.2.12 */
2159 if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ && 1341 if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ &&
@@ -2166,20 +1348,18 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2166 (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) { 1348 (ifsta->flags & IEEE80211_STA_WMM_ENABLED)) {
2167 struct ieee80211_ht_bss_info bss_info; 1349 struct ieee80211_ht_bss_info bss_info;
2168 ieee80211_ht_cap_ie_to_ht_info( 1350 ieee80211_ht_cap_ie_to_ht_info(
2169 (struct ieee80211_ht_cap *) 1351 elems.ht_cap_elem, &sta->sta.ht_info);
2170 elems.ht_cap_elem, &sta->ht_info);
2171 ieee80211_ht_addt_info_ie_to_ht_bss_info( 1352 ieee80211_ht_addt_info_ie_to_ht_bss_info(
2172 (struct ieee80211_ht_addt_info *)
2173 elems.ht_info_elem, &bss_info); 1353 elems.ht_info_elem, &bss_info);
2174 ieee80211_handle_ht(local, 1, &sta->ht_info, &bss_info); 1354 ieee80211_handle_ht(local, 1, &sta->sta.ht_info, &bss_info);
2175 } 1355 }
2176 1356
2177 rate_control_rate_init(sta, local); 1357 rate_control_rate_init(sta);
2178 1358
2179 if (elems.wmm_param) { 1359 if (elems.wmm_param) {
2180 set_sta_flags(sta, WLAN_STA_WME); 1360 set_sta_flags(sta, WLAN_STA_WME);
2181 rcu_read_unlock(); 1361 rcu_read_unlock();
2182 ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, 1362 ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param,
2183 elems.wmm_param_len); 1363 elems.wmm_param_len);
2184 } else 1364 } else
2185 rcu_read_unlock(); 1365 rcu_read_unlock();
@@ -2188,234 +1368,26 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2188 * ieee80211_set_associated() will tell the driver */ 1368 * ieee80211_set_associated() will tell the driver */
2189 bss_conf->aid = aid; 1369 bss_conf->aid = aid;
2190 bss_conf->assoc_capability = capab_info; 1370 bss_conf->assoc_capability = capab_info;
2191 ieee80211_set_associated(dev, ifsta, 1); 1371 ieee80211_set_associated(sdata, ifsta);
2192 1372
2193 ieee80211_associated(dev, ifsta); 1373 ieee80211_associated(sdata, ifsta);
2194} 1374}
2195 1375
2196 1376
2197/* Caller must hold local->sta_bss_lock */ 1377static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
2198static void __ieee80211_rx_bss_hash_add(struct net_device *dev,
2199 struct ieee80211_sta_bss *bss)
2200{
2201 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
2202 u8 hash_idx;
2203
2204 if (bss_mesh_cfg(bss))
2205 hash_idx = mesh_id_hash(bss_mesh_id(bss),
2206 bss_mesh_id_len(bss));
2207 else
2208 hash_idx = STA_HASH(bss->bssid);
2209
2210 bss->hnext = local->sta_bss_hash[hash_idx];
2211 local->sta_bss_hash[hash_idx] = bss;
2212}
2213
2214
2215/* Caller must hold local->sta_bss_lock */
2216static void __ieee80211_rx_bss_hash_del(struct ieee80211_local *local,
2217 struct ieee80211_sta_bss *bss)
2218{
2219 struct ieee80211_sta_bss *b, *prev = NULL;
2220 b = local->sta_bss_hash[STA_HASH(bss->bssid)];
2221 while (b) {
2222 if (b == bss) {
2223 if (!prev)
2224 local->sta_bss_hash[STA_HASH(bss->bssid)] =
2225 bss->hnext;
2226 else
2227 prev->hnext = bss->hnext;
2228 break;
2229 }
2230 prev = b;
2231 b = b->hnext;
2232 }
2233}
2234
2235
2236static struct ieee80211_sta_bss *
2237ieee80211_rx_bss_add(struct net_device *dev, u8 *bssid, int freq,
2238 u8 *ssid, u8 ssid_len)
2239{
2240 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
2241 struct ieee80211_sta_bss *bss;
2242
2243 bss = kzalloc(sizeof(*bss), GFP_ATOMIC);
2244 if (!bss)
2245 return NULL;
2246 atomic_inc(&bss->users);
2247 atomic_inc(&bss->users);
2248 memcpy(bss->bssid, bssid, ETH_ALEN);
2249 bss->freq = freq;
2250 if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) {
2251 memcpy(bss->ssid, ssid, ssid_len);
2252 bss->ssid_len = ssid_len;
2253 }
2254
2255 spin_lock_bh(&local->sta_bss_lock);
2256 /* TODO: order by RSSI? */
2257 list_add_tail(&bss->list, &local->sta_bss_list);
2258 __ieee80211_rx_bss_hash_add(dev, bss);
2259 spin_unlock_bh(&local->sta_bss_lock);
2260 return bss;
2261}
2262
2263static struct ieee80211_sta_bss *
2264ieee80211_rx_bss_get(struct net_device *dev, u8 *bssid, int freq,
2265 u8 *ssid, u8 ssid_len)
2266{
2267 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
2268 struct ieee80211_sta_bss *bss;
2269
2270 spin_lock_bh(&local->sta_bss_lock);
2271 bss = local->sta_bss_hash[STA_HASH(bssid)];
2272 while (bss) {
2273 if (!bss_mesh_cfg(bss) &&
2274 !memcmp(bss->bssid, bssid, ETH_ALEN) &&
2275 bss->freq == freq &&
2276 bss->ssid_len == ssid_len &&
2277 (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) {
2278 atomic_inc(&bss->users);
2279 break;
2280 }
2281 bss = bss->hnext;
2282 }
2283 spin_unlock_bh(&local->sta_bss_lock);
2284 return bss;
2285}
2286
2287#ifdef CONFIG_MAC80211_MESH
2288static struct ieee80211_sta_bss *
2289ieee80211_rx_mesh_bss_get(struct net_device *dev, u8 *mesh_id, int mesh_id_len,
2290 u8 *mesh_cfg, int freq)
2291{
2292 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
2293 struct ieee80211_sta_bss *bss;
2294
2295 spin_lock_bh(&local->sta_bss_lock);
2296 bss = local->sta_bss_hash[mesh_id_hash(mesh_id, mesh_id_len)];
2297 while (bss) {
2298 if (bss_mesh_cfg(bss) &&
2299 !memcmp(bss_mesh_cfg(bss), mesh_cfg, MESH_CFG_CMP_LEN) &&
2300 bss->freq == freq &&
2301 mesh_id_len == bss->mesh_id_len &&
2302 (mesh_id_len == 0 || !memcmp(bss->mesh_id, mesh_id,
2303 mesh_id_len))) {
2304 atomic_inc(&bss->users);
2305 break;
2306 }
2307 bss = bss->hnext;
2308 }
2309 spin_unlock_bh(&local->sta_bss_lock);
2310 return bss;
2311}
2312
2313static struct ieee80211_sta_bss *
2314ieee80211_rx_mesh_bss_add(struct net_device *dev, u8 *mesh_id, int mesh_id_len,
2315 u8 *mesh_cfg, int mesh_config_len, int freq)
2316{
2317 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
2318 struct ieee80211_sta_bss *bss;
2319
2320 if (mesh_config_len != MESH_CFG_LEN)
2321 return NULL;
2322
2323 bss = kzalloc(sizeof(*bss), GFP_ATOMIC);
2324 if (!bss)
2325 return NULL;
2326
2327 bss->mesh_cfg = kmalloc(MESH_CFG_CMP_LEN, GFP_ATOMIC);
2328 if (!bss->mesh_cfg) {
2329 kfree(bss);
2330 return NULL;
2331 }
2332
2333 if (mesh_id_len && mesh_id_len <= IEEE80211_MAX_MESH_ID_LEN) {
2334 bss->mesh_id = kmalloc(mesh_id_len, GFP_ATOMIC);
2335 if (!bss->mesh_id) {
2336 kfree(bss->mesh_cfg);
2337 kfree(bss);
2338 return NULL;
2339 }
2340 memcpy(bss->mesh_id, mesh_id, mesh_id_len);
2341 }
2342
2343 atomic_inc(&bss->users);
2344 atomic_inc(&bss->users);
2345 memcpy(bss->mesh_cfg, mesh_cfg, MESH_CFG_CMP_LEN);
2346 bss->mesh_id_len = mesh_id_len;
2347 bss->freq = freq;
2348 spin_lock_bh(&local->sta_bss_lock);
2349 /* TODO: order by RSSI? */
2350 list_add_tail(&bss->list, &local->sta_bss_list);
2351 __ieee80211_rx_bss_hash_add(dev, bss);
2352 spin_unlock_bh(&local->sta_bss_lock);
2353 return bss;
2354}
2355#endif
2356
2357static void ieee80211_rx_bss_free(struct ieee80211_sta_bss *bss)
2358{
2359 kfree(bss->wpa_ie);
2360 kfree(bss->rsn_ie);
2361 kfree(bss->wmm_ie);
2362 kfree(bss->ht_ie);
2363 kfree(bss->ht_add_ie);
2364 kfree(bss_mesh_id(bss));
2365 kfree(bss_mesh_cfg(bss));
2366 kfree(bss);
2367}
2368
2369
2370static void ieee80211_rx_bss_put(struct ieee80211_local *local,
2371 struct ieee80211_sta_bss *bss)
2372{
2373 local_bh_disable();
2374 if (!atomic_dec_and_lock(&bss->users, &local->sta_bss_lock)) {
2375 local_bh_enable();
2376 return;
2377 }
2378
2379 __ieee80211_rx_bss_hash_del(local, bss);
2380 list_del(&bss->list);
2381 spin_unlock_bh(&local->sta_bss_lock);
2382 ieee80211_rx_bss_free(bss);
2383}
2384
2385
2386void ieee80211_rx_bss_list_init(struct ieee80211_local *local)
2387{
2388 spin_lock_init(&local->sta_bss_lock);
2389 INIT_LIST_HEAD(&local->sta_bss_list);
2390}
2391
2392
2393void ieee80211_rx_bss_list_deinit(struct ieee80211_local *local)
2394{
2395 struct ieee80211_sta_bss *bss, *tmp;
2396
2397 list_for_each_entry_safe(bss, tmp, &local->sta_bss_list, list)
2398 ieee80211_rx_bss_put(local, bss);
2399}
2400
2401
2402static int ieee80211_sta_join_ibss(struct net_device *dev,
2403 struct ieee80211_if_sta *ifsta, 1378 struct ieee80211_if_sta *ifsta,
2404 struct ieee80211_sta_bss *bss) 1379 struct ieee80211_bss *bss)
2405{ 1380{
2406 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1381 struct ieee80211_local *local = sdata->local;
2407 int res, rates, i, j; 1382 int res, rates, i, j;
2408 struct sk_buff *skb; 1383 struct sk_buff *skb;
2409 struct ieee80211_mgmt *mgmt; 1384 struct ieee80211_mgmt *mgmt;
2410 u8 *pos; 1385 u8 *pos;
2411 struct ieee80211_sub_if_data *sdata;
2412 struct ieee80211_supported_band *sband; 1386 struct ieee80211_supported_band *sband;
2413 union iwreq_data wrqu; 1387 union iwreq_data wrqu;
2414 1388
2415 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 1389 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
2416 1390
2417 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2418
2419 /* Remove possible STA entries from other IBSS networks. */ 1391 /* Remove possible STA entries from other IBSS networks. */
2420 sta_info_flush_delayed(sdata); 1392 sta_info_flush_delayed(sdata);
2421 1393
@@ -2433,7 +1405,7 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
2433 sdata->drop_unencrypted = bss->capability & 1405 sdata->drop_unencrypted = bss->capability &
2434 WLAN_CAPABILITY_PRIVACY ? 1 : 0; 1406 WLAN_CAPABILITY_PRIVACY ? 1 : 0;
2435 1407
2436 res = ieee80211_set_freq(dev, bss->freq); 1408 res = ieee80211_set_freq(sdata, bss->freq);
2437 1409
2438 if (res) 1410 if (res)
2439 return res; 1411 return res;
@@ -2446,10 +1418,10 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
2446 mgmt = (struct ieee80211_mgmt *) 1418 mgmt = (struct ieee80211_mgmt *)
2447 skb_put(skb, 24 + sizeof(mgmt->u.beacon)); 1419 skb_put(skb, 24 + sizeof(mgmt->u.beacon));
2448 memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon)); 1420 memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
2449 mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, 1421 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2450 IEEE80211_STYPE_PROBE_RESP); 1422 IEEE80211_STYPE_PROBE_RESP);
2451 memset(mgmt->da, 0xff, ETH_ALEN); 1423 memset(mgmt->da, 0xff, ETH_ALEN);
2452 memcpy(mgmt->sa, dev->dev_addr, ETH_ALEN); 1424 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
2453 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN); 1425 memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
2454 mgmt->u.beacon.beacon_int = 1426 mgmt->u.beacon.beacon_int =
2455 cpu_to_le16(local->hw.conf.beacon_int); 1427 cpu_to_le16(local->hw.conf.beacon_int);
@@ -2506,108 +1478,38 @@ static int ieee80211_sta_join_ibss(struct net_device *dev,
2506 } 1478 }
2507 ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates; 1479 ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates;
2508 1480
2509 ieee80211_sta_def_wmm_params(dev, bss, 1); 1481 ieee80211_sta_def_wmm_params(sdata, bss);
2510 1482
2511 ifsta->state = IEEE80211_IBSS_JOINED; 1483 ifsta->state = IEEE80211_STA_MLME_IBSS_JOINED;
2512 mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); 1484 mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL);
2513 1485
1486 ieee80211_led_assoc(local, true);
1487
2514 memset(&wrqu, 0, sizeof(wrqu)); 1488 memset(&wrqu, 0, sizeof(wrqu));
2515 memcpy(wrqu.ap_addr.sa_data, bss->bssid, ETH_ALEN); 1489 memcpy(wrqu.ap_addr.sa_data, bss->bssid, ETH_ALEN);
2516 wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); 1490 wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL);
2517 1491
2518 return res; 1492 return res;
2519} 1493}
2520 1494
2521u64 ieee80211_sta_get_rates(struct ieee80211_local *local, 1495static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2522 struct ieee802_11_elems *elems,
2523 enum ieee80211_band band)
2524{
2525 struct ieee80211_supported_band *sband;
2526 struct ieee80211_rate *bitrates;
2527 size_t num_rates;
2528 u64 supp_rates;
2529 int i, j;
2530 sband = local->hw.wiphy->bands[band];
2531
2532 if (!sband) {
2533 WARN_ON(1);
2534 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
2535 }
2536
2537 bitrates = sband->bitrates;
2538 num_rates = sband->n_bitrates;
2539 supp_rates = 0;
2540 for (i = 0; i < elems->supp_rates_len +
2541 elems->ext_supp_rates_len; i++) {
2542 u8 rate = 0;
2543 int own_rate;
2544 if (i < elems->supp_rates_len)
2545 rate = elems->supp_rates[i];
2546 else if (elems->ext_supp_rates)
2547 rate = elems->ext_supp_rates
2548 [i - elems->supp_rates_len];
2549 own_rate = 5 * (rate & 0x7f);
2550 for (j = 0; j < num_rates; j++)
2551 if (bitrates[j].bitrate == own_rate)
2552 supp_rates |= BIT(j);
2553 }
2554 return supp_rates;
2555}
2556
2557
2558static void ieee80211_rx_bss_info(struct net_device *dev,
2559 struct ieee80211_mgmt *mgmt, 1496 struct ieee80211_mgmt *mgmt,
2560 size_t len, 1497 size_t len,
2561 struct ieee80211_rx_status *rx_status, 1498 struct ieee80211_rx_status *rx_status,
2562 struct ieee802_11_elems *elems, 1499 struct ieee802_11_elems *elems,
2563 int beacon) 1500 bool beacon)
2564{ 1501{
2565 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1502 struct ieee80211_local *local = sdata->local;
2566 int freq, clen; 1503 int freq;
2567 struct ieee80211_sta_bss *bss; 1504 struct ieee80211_bss *bss;
2568 struct sta_info *sta; 1505 struct sta_info *sta;
2569 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2570 u64 beacon_timestamp, rx_timestamp;
2571 struct ieee80211_channel *channel; 1506 struct ieee80211_channel *channel;
1507 u64 beacon_timestamp, rx_timestamp;
1508 u64 supp_rates = 0;
1509 enum ieee80211_band band = rx_status->band;
2572 DECLARE_MAC_BUF(mac); 1510 DECLARE_MAC_BUF(mac);
2573 DECLARE_MAC_BUF(mac2); 1511 DECLARE_MAC_BUF(mac2);
2574 1512
2575 if (!beacon && memcmp(mgmt->da, dev->dev_addr, ETH_ALEN))
2576 return; /* ignore ProbeResp to foreign address */
2577
2578 beacon_timestamp = le64_to_cpu(mgmt->u.beacon.timestamp);
2579
2580 if (ieee80211_vif_is_mesh(&sdata->vif) && elems->mesh_id &&
2581 elems->mesh_config && mesh_matches_local(elems, dev)) {
2582 u64 rates = ieee80211_sta_get_rates(local, elems,
2583 rx_status->band);
2584
2585 mesh_neighbour_update(mgmt->sa, rates, dev,
2586 mesh_peer_accepts_plinks(elems, dev));
2587 }
2588
2589 rcu_read_lock();
2590
2591 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && elems->supp_rates &&
2592 memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 &&
2593 (sta = sta_info_get(local, mgmt->sa))) {
2594 u64 prev_rates;
2595 u64 supp_rates = ieee80211_sta_get_rates(local, elems,
2596 rx_status->band);
2597
2598 prev_rates = sta->supp_rates[rx_status->band];
2599 sta->supp_rates[rx_status->band] &= supp_rates;
2600 if (sta->supp_rates[rx_status->band] == 0) {
2601 /* No matching rates - this should not really happen.
2602 * Make sure that at least one rate is marked
2603 * supported to avoid issues with TX rate ctrl. */
2604 sta->supp_rates[rx_status->band] =
2605 sdata->u.sta.supp_rates_bits[rx_status->band];
2606 }
2607 }
2608
2609 rcu_read_unlock();
2610
2611 if (elems->ds_params && elems->ds_params_len == 1) 1513 if (elems->ds_params && elems->ds_params_len == 1)
2612 freq = ieee80211_channel_to_frequency(elems->ds_params[0]); 1514 freq = ieee80211_channel_to_frequency(elems->ds_params[0]);
2613 else 1515 else
@@ -2618,215 +1520,60 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
2618 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED) 1520 if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
2619 return; 1521 return;
2620 1522
2621#ifdef CONFIG_MAC80211_MESH 1523 if (sdata->vif.type == NL80211_IFTYPE_ADHOC && elems->supp_rates &&
2622 if (elems->mesh_config) 1524 memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0) {
2623 bss = ieee80211_rx_mesh_bss_get(dev, elems->mesh_id, 1525 supp_rates = ieee80211_sta_get_rates(local, elems, band);
2624 elems->mesh_id_len, elems->mesh_config, freq);
2625 else
2626#endif
2627 bss = ieee80211_rx_bss_get(dev, mgmt->bssid, freq,
2628 elems->ssid, elems->ssid_len);
2629 if (!bss) {
2630#ifdef CONFIG_MAC80211_MESH
2631 if (elems->mesh_config)
2632 bss = ieee80211_rx_mesh_bss_add(dev, elems->mesh_id,
2633 elems->mesh_id_len, elems->mesh_config,
2634 elems->mesh_config_len, freq);
2635 else
2636#endif
2637 bss = ieee80211_rx_bss_add(dev, mgmt->bssid, freq,
2638 elems->ssid, elems->ssid_len);
2639 if (!bss)
2640 return;
2641 } else {
2642#if 0
2643 /* TODO: order by RSSI? */
2644 spin_lock_bh(&local->sta_bss_lock);
2645 list_move_tail(&bss->list, &local->sta_bss_list);
2646 spin_unlock_bh(&local->sta_bss_lock);
2647#endif
2648 }
2649
2650 /* save the ERP value so that it is available at association time */
2651 if (elems->erp_info && elems->erp_info_len >= 1) {
2652 bss->erp_value = elems->erp_info[0];
2653 bss->has_erp_value = 1;
2654 }
2655 1526
2656 if (elems->ht_cap_elem && 1527 rcu_read_lock();
2657 (!bss->ht_ie || bss->ht_ie_len != elems->ht_cap_elem_len ||
2658 memcmp(bss->ht_ie, elems->ht_cap_elem, elems->ht_cap_elem_len))) {
2659 kfree(bss->ht_ie);
2660 bss->ht_ie = kmalloc(elems->ht_cap_elem_len + 2, GFP_ATOMIC);
2661 if (bss->ht_ie) {
2662 memcpy(bss->ht_ie, elems->ht_cap_elem - 2,
2663 elems->ht_cap_elem_len + 2);
2664 bss->ht_ie_len = elems->ht_cap_elem_len + 2;
2665 } else
2666 bss->ht_ie_len = 0;
2667 } else if (!elems->ht_cap_elem && bss->ht_ie) {
2668 kfree(bss->ht_ie);
2669 bss->ht_ie = NULL;
2670 bss->ht_ie_len = 0;
2671 }
2672 1528
2673 if (elems->ht_info_elem && 1529 sta = sta_info_get(local, mgmt->sa);
2674 (!bss->ht_add_ie || 1530 if (sta) {
2675 bss->ht_add_ie_len != elems->ht_info_elem_len || 1531 u64 prev_rates;
2676 memcmp(bss->ht_add_ie, elems->ht_info_elem,
2677 elems->ht_info_elem_len))) {
2678 kfree(bss->ht_add_ie);
2679 bss->ht_add_ie =
2680 kmalloc(elems->ht_info_elem_len + 2, GFP_ATOMIC);
2681 if (bss->ht_add_ie) {
2682 memcpy(bss->ht_add_ie, elems->ht_info_elem - 2,
2683 elems->ht_info_elem_len + 2);
2684 bss->ht_add_ie_len = elems->ht_info_elem_len + 2;
2685 } else
2686 bss->ht_add_ie_len = 0;
2687 } else if (!elems->ht_info_elem && bss->ht_add_ie) {
2688 kfree(bss->ht_add_ie);
2689 bss->ht_add_ie = NULL;
2690 bss->ht_add_ie_len = 0;
2691 }
2692 1532
2693 bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int); 1533 prev_rates = sta->sta.supp_rates[band];
2694 bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); 1534 /* make sure mandatory rates are always added */
1535 sta->sta.supp_rates[band] = supp_rates |
1536 ieee80211_mandatory_rates(local, band);
2695 1537
2696 if (elems->tim) { 1538#ifdef CONFIG_MAC80211_IBSS_DEBUG
2697 struct ieee80211_tim_ie *tim_ie = 1539 if (sta->sta.supp_rates[band] != prev_rates)
2698 (struct ieee80211_tim_ie *)elems->tim; 1540 printk(KERN_DEBUG "%s: updated supp_rates set "
2699 bss->dtim_period = tim_ie->dtim_period; 1541 "for %s based on beacon info (0x%llx | "
2700 } 1542 "0x%llx -> 0x%llx)\n",
1543 sdata->dev->name,
1544 print_mac(mac, sta->sta.addr),
1545 (unsigned long long) prev_rates,
1546 (unsigned long long) supp_rates,
1547 (unsigned long long) sta->sta.supp_rates[band]);
1548#endif
1549 } else {
1550 ieee80211_ibss_add_sta(sdata, NULL, mgmt->bssid,
1551 mgmt->sa, supp_rates);
1552 }
2701 1553
2702 /* set default value for buggy APs */ 1554 rcu_read_unlock();
2703 if (!elems->tim || bss->dtim_period == 0)
2704 bss->dtim_period = 1;
2705
2706 bss->supp_rates_len = 0;
2707 if (elems->supp_rates) {
2708 clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len;
2709 if (clen > elems->supp_rates_len)
2710 clen = elems->supp_rates_len;
2711 memcpy(&bss->supp_rates[bss->supp_rates_len], elems->supp_rates,
2712 clen);
2713 bss->supp_rates_len += clen;
2714 }
2715 if (elems->ext_supp_rates) {
2716 clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len;
2717 if (clen > elems->ext_supp_rates_len)
2718 clen = elems->ext_supp_rates_len;
2719 memcpy(&bss->supp_rates[bss->supp_rates_len],
2720 elems->ext_supp_rates, clen);
2721 bss->supp_rates_len += clen;
2722 } 1555 }
2723 1556
2724 bss->band = rx_status->band; 1557 bss = ieee80211_bss_info_update(local, rx_status, mgmt, len, elems,
1558 freq, beacon);
1559 if (!bss)
1560 return;
2725 1561
2726 bss->timestamp = beacon_timestamp; 1562 /* was just updated in ieee80211_bss_info_update */
2727 bss->last_update = jiffies; 1563 beacon_timestamp = bss->timestamp;
2728 bss->signal = rx_status->signal;
2729 bss->noise = rx_status->noise;
2730 bss->qual = rx_status->qual;
2731 if (!beacon && !bss->probe_resp)
2732 bss->probe_resp = true;
2733 1564
2734 /* 1565 /*
2735 * In STA mode, the remaining parameters should not be overridden 1566 * In STA mode, the remaining parameters should not be overridden
2736 * by beacons because they're not necessarily accurate there. 1567 * by beacons because they're not necessarily accurate there.
2737 */ 1568 */
2738 if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS && 1569 if (sdata->vif.type != NL80211_IFTYPE_ADHOC &&
2739 bss->probe_resp && beacon) { 1570 bss->last_probe_resp && beacon) {
2740 ieee80211_rx_bss_put(local, bss); 1571 ieee80211_rx_bss_put(local, bss);
2741 return; 1572 return;
2742 } 1573 }
2743 1574
2744 if (elems->wpa &&
2745 (!bss->wpa_ie || bss->wpa_ie_len != elems->wpa_len ||
2746 memcmp(bss->wpa_ie, elems->wpa, elems->wpa_len))) {
2747 kfree(bss->wpa_ie);
2748 bss->wpa_ie = kmalloc(elems->wpa_len + 2, GFP_ATOMIC);
2749 if (bss->wpa_ie) {
2750 memcpy(bss->wpa_ie, elems->wpa - 2, elems->wpa_len + 2);
2751 bss->wpa_ie_len = elems->wpa_len + 2;
2752 } else
2753 bss->wpa_ie_len = 0;
2754 } else if (!elems->wpa && bss->wpa_ie) {
2755 kfree(bss->wpa_ie);
2756 bss->wpa_ie = NULL;
2757 bss->wpa_ie_len = 0;
2758 }
2759
2760 if (elems->rsn &&
2761 (!bss->rsn_ie || bss->rsn_ie_len != elems->rsn_len ||
2762 memcmp(bss->rsn_ie, elems->rsn, elems->rsn_len))) {
2763 kfree(bss->rsn_ie);
2764 bss->rsn_ie = kmalloc(elems->rsn_len + 2, GFP_ATOMIC);
2765 if (bss->rsn_ie) {
2766 memcpy(bss->rsn_ie, elems->rsn - 2, elems->rsn_len + 2);
2767 bss->rsn_ie_len = elems->rsn_len + 2;
2768 } else
2769 bss->rsn_ie_len = 0;
2770 } else if (!elems->rsn && bss->rsn_ie) {
2771 kfree(bss->rsn_ie);
2772 bss->rsn_ie = NULL;
2773 bss->rsn_ie_len = 0;
2774 }
2775
2776 /*
2777 * Cf.
2778 * http://www.wipo.int/pctdb/en/wo.jsp?wo=2007047181&IA=WO2007047181&DISPLAY=DESC
2779 *
2780 * quoting:
2781 *
2782 * In particular, "Wi-Fi CERTIFIED for WMM - Support for Multimedia
2783 * Applications with Quality of Service in Wi-Fi Networks," Wi- Fi
2784 * Alliance (September 1, 2004) is incorporated by reference herein.
2785 * The inclusion of the WMM Parameters in probe responses and
2786 * association responses is mandatory for WMM enabled networks. The
2787 * inclusion of the WMM Parameters in beacons, however, is optional.
2788 */
2789
2790 if (elems->wmm_param &&
2791 (!bss->wmm_ie || bss->wmm_ie_len != elems->wmm_param_len ||
2792 memcmp(bss->wmm_ie, elems->wmm_param, elems->wmm_param_len))) {
2793 kfree(bss->wmm_ie);
2794 bss->wmm_ie = kmalloc(elems->wmm_param_len + 2, GFP_ATOMIC);
2795 if (bss->wmm_ie) {
2796 memcpy(bss->wmm_ie, elems->wmm_param - 2,
2797 elems->wmm_param_len + 2);
2798 bss->wmm_ie_len = elems->wmm_param_len + 2;
2799 } else
2800 bss->wmm_ie_len = 0;
2801 } else if (elems->wmm_info &&
2802 (!bss->wmm_ie || bss->wmm_ie_len != elems->wmm_info_len ||
2803 memcmp(bss->wmm_ie, elems->wmm_info,
2804 elems->wmm_info_len))) {
2805 /* As for certain AP's Fifth bit is not set in WMM IE in
2806 * beacon frames.So while parsing the beacon frame the
2807 * wmm_info structure is used instead of wmm_param.
2808 * wmm_info structure was never used to set bss->wmm_ie.
2809 * This code fixes this problem by copying the WME
2810 * information from wmm_info to bss->wmm_ie and enabling
2811 * n-band association.
2812 */
2813 kfree(bss->wmm_ie);
2814 bss->wmm_ie = kmalloc(elems->wmm_info_len + 2, GFP_ATOMIC);
2815 if (bss->wmm_ie) {
2816 memcpy(bss->wmm_ie, elems->wmm_info - 2,
2817 elems->wmm_info_len + 2);
2818 bss->wmm_ie_len = elems->wmm_info_len + 2;
2819 } else
2820 bss->wmm_ie_len = 0;
2821 } else if (!elems->wmm_param && !elems->wmm_info && bss->wmm_ie) {
2822 kfree(bss->wmm_ie);
2823 bss->wmm_ie = NULL;
2824 bss->wmm_ie_len = 0;
2825 }
2826
2827 /* check if we need to merge IBSS */ 1575 /* check if we need to merge IBSS */
2828 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && beacon && 1576 if (sdata->vif.type == NL80211_IFTYPE_ADHOC && beacon &&
2829 !local->sta_sw_scanning && !local->sta_hw_scanning &&
2830 bss->capability & WLAN_CAPABILITY_IBSS && 1577 bss->capability & WLAN_CAPABILITY_IBSS &&
2831 bss->freq == local->oper_channel->center_freq && 1578 bss->freq == local->oper_channel->center_freq &&
2832 elems->ssid_len == sdata->u.sta.ssid_len && 1579 elems->ssid_len == sdata->u.sta.ssid_len &&
@@ -2848,7 +1595,7 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
2848 * e.g: at 1 MBit that means mactime is 192 usec earlier 1595 * e.g: at 1 MBit that means mactime is 192 usec earlier
2849 * (=24 bytes * 8 usecs/byte) than the beacon timestamp. 1596 * (=24 bytes * 8 usecs/byte) than the beacon timestamp.
2850 */ 1597 */
2851 int rate = local->hw.wiphy->bands[rx_status->band]-> 1598 int rate = local->hw.wiphy->bands[band]->
2852 bitrates[rx_status->rate_idx].bitrate; 1599 bitrates[rx_status->rate_idx].bitrate;
2853 rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate); 1600 rx_timestamp = rx_status->mactime + (24 * 8 * 10 / rate);
2854 } else if (local && local->ops && local->ops->get_tsf) 1601 } else if (local && local->ops && local->ops->get_tsf)
@@ -2871,12 +1618,12 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
2871#ifdef CONFIG_MAC80211_IBSS_DEBUG 1618#ifdef CONFIG_MAC80211_IBSS_DEBUG
2872 printk(KERN_DEBUG "%s: beacon TSF higher than " 1619 printk(KERN_DEBUG "%s: beacon TSF higher than "
2873 "local TSF - IBSS merge with BSSID %s\n", 1620 "local TSF - IBSS merge with BSSID %s\n",
2874 dev->name, print_mac(mac, mgmt->bssid)); 1621 sdata->dev->name, print_mac(mac, mgmt->bssid));
2875#endif 1622#endif
2876 ieee80211_sta_join_ibss(dev, &sdata->u.sta, bss); 1623 ieee80211_sta_join_ibss(sdata, &sdata->u.sta, bss);
2877 ieee80211_ibss_add_sta(dev, NULL, 1624 ieee80211_ibss_add_sta(sdata, NULL,
2878 mgmt->bssid, mgmt->sa, 1625 mgmt->bssid, mgmt->sa,
2879 BIT(rx_status->rate_idx)); 1626 supp_rates);
2880 } 1627 }
2881 } 1628 }
2882 1629
@@ -2884,13 +1631,17 @@ static void ieee80211_rx_bss_info(struct net_device *dev,
2884} 1631}
2885 1632
2886 1633
2887static void ieee80211_rx_mgmt_probe_resp(struct net_device *dev, 1634static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
2888 struct ieee80211_mgmt *mgmt, 1635 struct ieee80211_mgmt *mgmt,
2889 size_t len, 1636 size_t len,
2890 struct ieee80211_rx_status *rx_status) 1637 struct ieee80211_rx_status *rx_status)
2891{ 1638{
2892 size_t baselen; 1639 size_t baselen;
2893 struct ieee802_11_elems elems; 1640 struct ieee802_11_elems elems;
1641 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
1642
1643 if (memcmp(mgmt->da, sdata->dev->dev_addr, ETH_ALEN))
1644 return; /* ignore ProbeResp to foreign address */
2894 1645
2895 baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt; 1646 baselen = (u8 *) mgmt->u.probe_resp.variable - (u8 *) mgmt;
2896 if (baselen > len) 1647 if (baselen > len)
@@ -2899,20 +1650,27 @@ static void ieee80211_rx_mgmt_probe_resp(struct net_device *dev,
2899 ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen, 1650 ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen,
2900 &elems); 1651 &elems);
2901 1652
2902 ieee80211_rx_bss_info(dev, mgmt, len, rx_status, &elems, 0); 1653 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false);
1654
1655 /* direct probe may be part of the association flow */
1656 if (test_and_clear_bit(IEEE80211_STA_REQ_DIRECT_PROBE,
1657 &ifsta->request)) {
1658 printk(KERN_DEBUG "%s direct probe responded\n",
1659 sdata->dev->name);
1660 ieee80211_authenticate(sdata, ifsta);
1661 }
2903} 1662}
2904 1663
2905 1664
2906static void ieee80211_rx_mgmt_beacon(struct net_device *dev, 1665static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2907 struct ieee80211_mgmt *mgmt, 1666 struct ieee80211_mgmt *mgmt,
2908 size_t len, 1667 size_t len,
2909 struct ieee80211_rx_status *rx_status) 1668 struct ieee80211_rx_status *rx_status)
2910{ 1669{
2911 struct ieee80211_sub_if_data *sdata;
2912 struct ieee80211_if_sta *ifsta; 1670 struct ieee80211_if_sta *ifsta;
2913 size_t baselen; 1671 size_t baselen;
2914 struct ieee802_11_elems elems; 1672 struct ieee802_11_elems elems;
2915 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1673 struct ieee80211_local *local = sdata->local;
2916 struct ieee80211_conf *conf = &local->hw.conf; 1674 struct ieee80211_conf *conf = &local->hw.conf;
2917 u32 changed = 0; 1675 u32 changed = 0;
2918 1676
@@ -2923,10 +1681,9 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev,
2923 1681
2924 ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); 1682 ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems);
2925 1683
2926 ieee80211_rx_bss_info(dev, mgmt, len, rx_status, &elems, 1); 1684 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, true);
2927 1685
2928 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1686 if (sdata->vif.type != NL80211_IFTYPE_STATION)
2929 if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
2930 return; 1687 return;
2931 ifsta = &sdata->u.sta; 1688 ifsta = &sdata->u.sta;
2932 1689
@@ -2934,15 +1691,9 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev,
2934 memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0) 1691 memcmp(ifsta->bssid, mgmt->bssid, ETH_ALEN) != 0)
2935 return; 1692 return;
2936 1693
2937 ieee80211_sta_wmm_params(dev, ifsta, elems.wmm_param, 1694 ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param,
2938 elems.wmm_param_len); 1695 elems.wmm_param_len);
2939 1696
2940 /* Do not send changes to driver if we are scanning. This removes
2941 * requirement that driver's bss_info_changed function needs to be
2942 * atomic. */
2943 if (local->sta_sw_scanning || local->sta_hw_scanning)
2944 return;
2945
2946 if (elems.erp_info && elems.erp_info_len >= 1) 1697 if (elems.erp_info && elems.erp_info_len >= 1)
2947 changed |= ieee80211_handle_erp_ie(sdata, elems.erp_info[0]); 1698 changed |= ieee80211_handle_erp_ie(sdata, elems.erp_info[0]);
2948 else { 1699 else {
@@ -2956,7 +1707,6 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev,
2956 struct ieee80211_ht_bss_info bss_info; 1707 struct ieee80211_ht_bss_info bss_info;
2957 1708
2958 ieee80211_ht_addt_info_ie_to_ht_bss_info( 1709 ieee80211_ht_addt_info_ie_to_ht_bss_info(
2959 (struct ieee80211_ht_addt_info *)
2960 elems.ht_info_elem, &bss_info); 1710 elems.ht_info_elem, &bss_info);
2961 changed |= ieee80211_handle_ht(local, 1, &conf->ht_conf, 1711 changed |= ieee80211_handle_ht(local, 1, &conf->ht_conf,
2962 &bss_info); 1712 &bss_info);
@@ -2966,14 +1716,13 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev,
2966} 1716}
2967 1717
2968 1718
2969static void ieee80211_rx_mgmt_probe_req(struct net_device *dev, 1719static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata,
2970 struct ieee80211_if_sta *ifsta, 1720 struct ieee80211_if_sta *ifsta,
2971 struct ieee80211_mgmt *mgmt, 1721 struct ieee80211_mgmt *mgmt,
2972 size_t len, 1722 size_t len,
2973 struct ieee80211_rx_status *rx_status) 1723 struct ieee80211_rx_status *rx_status)
2974{ 1724{
2975 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1725 struct ieee80211_local *local = sdata->local;
2976 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
2977 int tx_last_beacon; 1726 int tx_last_beacon;
2978 struct sk_buff *skb; 1727 struct sk_buff *skb;
2979 struct ieee80211_mgmt *resp; 1728 struct ieee80211_mgmt *resp;
@@ -2984,8 +1733,8 @@ static void ieee80211_rx_mgmt_probe_req(struct net_device *dev,
2984 DECLARE_MAC_BUF(mac3); 1733 DECLARE_MAC_BUF(mac3);
2985#endif 1734#endif
2986 1735
2987 if (sdata->vif.type != IEEE80211_IF_TYPE_IBSS || 1736 if (sdata->vif.type != NL80211_IFTYPE_ADHOC ||
2988 ifsta->state != IEEE80211_IBSS_JOINED || 1737 ifsta->state != IEEE80211_STA_MLME_IBSS_JOINED ||
2989 len < 24 + 2 || !ifsta->probe_resp) 1738 len < 24 + 2 || !ifsta->probe_resp)
2990 return; 1739 return;
2991 1740
@@ -2997,7 +1746,7 @@ static void ieee80211_rx_mgmt_probe_req(struct net_device *dev,
2997#ifdef CONFIG_MAC80211_IBSS_DEBUG 1746#ifdef CONFIG_MAC80211_IBSS_DEBUG
2998 printk(KERN_DEBUG "%s: RX ProbeReq SA=%s DA=%s BSSID=" 1747 printk(KERN_DEBUG "%s: RX ProbeReq SA=%s DA=%s BSSID="
2999 "%s (tx_last_beacon=%d)\n", 1748 "%s (tx_last_beacon=%d)\n",
3000 dev->name, print_mac(mac, mgmt->sa), print_mac(mac2, mgmt->da), 1749 sdata->dev->name, print_mac(mac, mgmt->sa), print_mac(mac2, mgmt->da),
3001 print_mac(mac3, mgmt->bssid), tx_last_beacon); 1750 print_mac(mac3, mgmt->bssid), tx_last_beacon);
3002#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 1751#endif /* CONFIG_MAC80211_IBSS_DEBUG */
3003 1752
@@ -3015,7 +1764,7 @@ static void ieee80211_rx_mgmt_probe_req(struct net_device *dev,
3015#ifdef CONFIG_MAC80211_IBSS_DEBUG 1764#ifdef CONFIG_MAC80211_IBSS_DEBUG
3016 printk(KERN_DEBUG "%s: Invalid SSID IE in ProbeReq " 1765 printk(KERN_DEBUG "%s: Invalid SSID IE in ProbeReq "
3017 "from %s\n", 1766 "from %s\n",
3018 dev->name, print_mac(mac, mgmt->sa)); 1767 sdata->dev->name, print_mac(mac, mgmt->sa));
3019#endif 1768#endif
3020 return; 1769 return;
3021 } 1770 }
@@ -3035,74 +1784,15 @@ static void ieee80211_rx_mgmt_probe_req(struct net_device *dev,
3035 memcpy(resp->da, mgmt->sa, ETH_ALEN); 1784 memcpy(resp->da, mgmt->sa, ETH_ALEN);
3036#ifdef CONFIG_MAC80211_IBSS_DEBUG 1785#ifdef CONFIG_MAC80211_IBSS_DEBUG
3037 printk(KERN_DEBUG "%s: Sending ProbeResp to %s\n", 1786 printk(KERN_DEBUG "%s: Sending ProbeResp to %s\n",
3038 dev->name, print_mac(mac, resp->da)); 1787 sdata->dev->name, print_mac(mac, resp->da));
3039#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 1788#endif /* CONFIG_MAC80211_IBSS_DEBUG */
3040 ieee80211_sta_tx(dev, skb, 0); 1789 ieee80211_tx_skb(sdata, skb, 0);
3041} 1790}
3042 1791
3043static void ieee80211_rx_mgmt_action(struct net_device *dev, 1792void ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
3044 struct ieee80211_if_sta *ifsta,
3045 struct ieee80211_mgmt *mgmt,
3046 size_t len,
3047 struct ieee80211_rx_status *rx_status)
3048{
3049 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3050 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
3051
3052 if (len < IEEE80211_MIN_ACTION_SIZE)
3053 return;
3054
3055 switch (mgmt->u.action.category) {
3056 case WLAN_CATEGORY_SPECTRUM_MGMT:
3057 if (local->hw.conf.channel->band != IEEE80211_BAND_5GHZ)
3058 break;
3059 switch (mgmt->u.action.u.chan_switch.action_code) {
3060 case WLAN_ACTION_SPCT_MSR_REQ:
3061 if (len < (IEEE80211_MIN_ACTION_SIZE +
3062 sizeof(mgmt->u.action.u.measurement)))
3063 break;
3064 ieee80211_sta_process_measurement_req(dev, mgmt, len);
3065 break;
3066 }
3067 break;
3068 case WLAN_CATEGORY_BACK:
3069 switch (mgmt->u.action.u.addba_req.action_code) {
3070 case WLAN_ACTION_ADDBA_REQ:
3071 if (len < (IEEE80211_MIN_ACTION_SIZE +
3072 sizeof(mgmt->u.action.u.addba_req)))
3073 break;
3074 ieee80211_sta_process_addba_request(dev, mgmt, len);
3075 break;
3076 case WLAN_ACTION_ADDBA_RESP:
3077 if (len < (IEEE80211_MIN_ACTION_SIZE +
3078 sizeof(mgmt->u.action.u.addba_resp)))
3079 break;
3080 ieee80211_sta_process_addba_resp(dev, mgmt, len);
3081 break;
3082 case WLAN_ACTION_DELBA:
3083 if (len < (IEEE80211_MIN_ACTION_SIZE +
3084 sizeof(mgmt->u.action.u.delba)))
3085 break;
3086 ieee80211_sta_process_delba(dev, mgmt, len);
3087 break;
3088 }
3089 break;
3090 case PLINK_CATEGORY:
3091 if (ieee80211_vif_is_mesh(&sdata->vif))
3092 mesh_rx_plink_frame(dev, mgmt, len, rx_status);
3093 break;
3094 case MESH_PATH_SEL_CATEGORY:
3095 if (ieee80211_vif_is_mesh(&sdata->vif))
3096 mesh_rx_path_sel_frame(dev, mgmt, len);
3097 break;
3098 }
3099}
3100
3101void ieee80211_sta_rx_mgmt(struct net_device *dev, struct sk_buff *skb,
3102 struct ieee80211_rx_status *rx_status) 1793 struct ieee80211_rx_status *rx_status)
3103{ 1794{
3104 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1795 struct ieee80211_local *local = sdata->local;
3105 struct ieee80211_sub_if_data *sdata;
3106 struct ieee80211_if_sta *ifsta; 1796 struct ieee80211_if_sta *ifsta;
3107 struct ieee80211_mgmt *mgmt; 1797 struct ieee80211_mgmt *mgmt;
3108 u16 fc; 1798 u16 fc;
@@ -3110,7 +1800,6 @@ void ieee80211_sta_rx_mgmt(struct net_device *dev, struct sk_buff *skb,
3110 if (skb->len < 24) 1800 if (skb->len < 24)
3111 goto fail; 1801 goto fail;
3112 1802
3113 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3114 ifsta = &sdata->u.sta; 1803 ifsta = &sdata->u.sta;
3115 1804
3116 mgmt = (struct ieee80211_mgmt *) skb->data; 1805 mgmt = (struct ieee80211_mgmt *) skb->data;
@@ -3120,7 +1809,6 @@ void ieee80211_sta_rx_mgmt(struct net_device *dev, struct sk_buff *skb,
3120 case IEEE80211_STYPE_PROBE_REQ: 1809 case IEEE80211_STYPE_PROBE_REQ:
3121 case IEEE80211_STYPE_PROBE_RESP: 1810 case IEEE80211_STYPE_PROBE_RESP:
3122 case IEEE80211_STYPE_BEACON: 1811 case IEEE80211_STYPE_BEACON:
3123 case IEEE80211_STYPE_ACTION:
3124 memcpy(skb->cb, rx_status, sizeof(*rx_status)); 1812 memcpy(skb->cb, rx_status, sizeof(*rx_status));
3125 case IEEE80211_STYPE_AUTH: 1813 case IEEE80211_STYPE_AUTH:
3126 case IEEE80211_STYPE_ASSOC_RESP: 1814 case IEEE80211_STYPE_ASSOC_RESP:
@@ -3136,17 +1824,14 @@ void ieee80211_sta_rx_mgmt(struct net_device *dev, struct sk_buff *skb,
3136 kfree_skb(skb); 1824 kfree_skb(skb);
3137} 1825}
3138 1826
3139 1827static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
3140static void ieee80211_sta_rx_queued_mgmt(struct net_device *dev,
3141 struct sk_buff *skb) 1828 struct sk_buff *skb)
3142{ 1829{
3143 struct ieee80211_rx_status *rx_status; 1830 struct ieee80211_rx_status *rx_status;
3144 struct ieee80211_sub_if_data *sdata;
3145 struct ieee80211_if_sta *ifsta; 1831 struct ieee80211_if_sta *ifsta;
3146 struct ieee80211_mgmt *mgmt; 1832 struct ieee80211_mgmt *mgmt;
3147 u16 fc; 1833 u16 fc;
3148 1834
3149 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3150 ifsta = &sdata->u.sta; 1835 ifsta = &sdata->u.sta;
3151 1836
3152 rx_status = (struct ieee80211_rx_status *) skb->cb; 1837 rx_status = (struct ieee80211_rx_status *) skb->cb;
@@ -3155,17 +1840,17 @@ static void ieee80211_sta_rx_queued_mgmt(struct net_device *dev,
3155 1840
3156 switch (fc & IEEE80211_FCTL_STYPE) { 1841 switch (fc & IEEE80211_FCTL_STYPE) {
3157 case IEEE80211_STYPE_PROBE_REQ: 1842 case IEEE80211_STYPE_PROBE_REQ:
3158 ieee80211_rx_mgmt_probe_req(dev, ifsta, mgmt, skb->len, 1843 ieee80211_rx_mgmt_probe_req(sdata, ifsta, mgmt, skb->len,
3159 rx_status); 1844 rx_status);
3160 break; 1845 break;
3161 case IEEE80211_STYPE_PROBE_RESP: 1846 case IEEE80211_STYPE_PROBE_RESP:
3162 ieee80211_rx_mgmt_probe_resp(dev, mgmt, skb->len, rx_status); 1847 ieee80211_rx_mgmt_probe_resp(sdata, mgmt, skb->len, rx_status);
3163 break; 1848 break;
3164 case IEEE80211_STYPE_BEACON: 1849 case IEEE80211_STYPE_BEACON:
3165 ieee80211_rx_mgmt_beacon(dev, mgmt, skb->len, rx_status); 1850 ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len, rx_status);
3166 break; 1851 break;
3167 case IEEE80211_STYPE_AUTH: 1852 case IEEE80211_STYPE_AUTH:
3168 ieee80211_rx_mgmt_auth(dev, ifsta, mgmt, skb->len); 1853 ieee80211_rx_mgmt_auth(sdata, ifsta, mgmt, skb->len);
3169 break; 1854 break;
3170 case IEEE80211_STYPE_ASSOC_RESP: 1855 case IEEE80211_STYPE_ASSOC_RESP:
3171 ieee80211_rx_mgmt_assoc_resp(sdata, ifsta, mgmt, skb->len, 0); 1856 ieee80211_rx_mgmt_assoc_resp(sdata, ifsta, mgmt, skb->len, 0);
@@ -3174,13 +1859,10 @@ static void ieee80211_sta_rx_queued_mgmt(struct net_device *dev,
3174 ieee80211_rx_mgmt_assoc_resp(sdata, ifsta, mgmt, skb->len, 1); 1859 ieee80211_rx_mgmt_assoc_resp(sdata, ifsta, mgmt, skb->len, 1);
3175 break; 1860 break;
3176 case IEEE80211_STYPE_DEAUTH: 1861 case IEEE80211_STYPE_DEAUTH:
3177 ieee80211_rx_mgmt_deauth(dev, ifsta, mgmt, skb->len); 1862 ieee80211_rx_mgmt_deauth(sdata, ifsta, mgmt, skb->len);
3178 break; 1863 break;
3179 case IEEE80211_STYPE_DISASSOC: 1864 case IEEE80211_STYPE_DISASSOC:
3180 ieee80211_rx_mgmt_disassoc(dev, ifsta, mgmt, skb->len); 1865 ieee80211_rx_mgmt_disassoc(sdata, ifsta, mgmt, skb->len);
3181 break;
3182 case IEEE80211_STYPE_ACTION:
3183 ieee80211_rx_mgmt_action(dev, ifsta, mgmt, skb->len, rx_status);
3184 break; 1866 break;
3185 } 1867 }
3186 1868
@@ -3188,47 +1870,11 @@ static void ieee80211_sta_rx_queued_mgmt(struct net_device *dev,
3188} 1870}
3189 1871
3190 1872
3191ieee80211_rx_result 1873static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata)
3192ieee80211_sta_rx_scan(struct net_device *dev, struct sk_buff *skb,
3193 struct ieee80211_rx_status *rx_status)
3194{ 1874{
3195 struct ieee80211_mgmt *mgmt; 1875 struct ieee80211_local *local = sdata->local;
3196 __le16 fc;
3197
3198 if (skb->len < 2)
3199 return RX_DROP_UNUSABLE;
3200
3201 mgmt = (struct ieee80211_mgmt *) skb->data;
3202 fc = mgmt->frame_control;
3203
3204 if (ieee80211_is_ctl(fc))
3205 return RX_CONTINUE;
3206
3207 if (skb->len < 24)
3208 return RX_DROP_MONITOR;
3209
3210 if (ieee80211_is_probe_resp(fc)) {
3211 ieee80211_rx_mgmt_probe_resp(dev, mgmt, skb->len, rx_status);
3212 dev_kfree_skb(skb);
3213 return RX_QUEUED;
3214 }
3215
3216 if (ieee80211_is_beacon(fc)) {
3217 ieee80211_rx_mgmt_beacon(dev, mgmt, skb->len, rx_status);
3218 dev_kfree_skb(skb);
3219 return RX_QUEUED;
3220 }
3221
3222 return RX_CONTINUE;
3223}
3224
3225
3226static int ieee80211_sta_active_ibss(struct net_device *dev)
3227{
3228 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
3229 int active = 0; 1876 int active = 0;
3230 struct sta_info *sta; 1877 struct sta_info *sta;
3231 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3232 1878
3233 rcu_read_lock(); 1879 rcu_read_lock();
3234 1880
@@ -3247,179 +1893,36 @@ static int ieee80211_sta_active_ibss(struct net_device *dev)
3247} 1893}
3248 1894
3249 1895
3250static void ieee80211_sta_expire(struct net_device *dev, unsigned long exp_time) 1896static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata,
3251{
3252 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
3253 struct sta_info *sta, *tmp;
3254 LIST_HEAD(tmp_list);
3255 DECLARE_MAC_BUF(mac);
3256 unsigned long flags;
3257
3258 spin_lock_irqsave(&local->sta_lock, flags);
3259 list_for_each_entry_safe(sta, tmp, &local->sta_list, list)
3260 if (time_after(jiffies, sta->last_rx + exp_time)) {
3261#ifdef CONFIG_MAC80211_IBSS_DEBUG
3262 printk(KERN_DEBUG "%s: expiring inactive STA %s\n",
3263 dev->name, print_mac(mac, sta->addr));
3264#endif
3265 __sta_info_unlink(&sta);
3266 if (sta)
3267 list_add(&sta->list, &tmp_list);
3268 }
3269 spin_unlock_irqrestore(&local->sta_lock, flags);
3270
3271 list_for_each_entry_safe(sta, tmp, &tmp_list, list)
3272 sta_info_destroy(sta);
3273}
3274
3275
3276static void ieee80211_sta_merge_ibss(struct net_device *dev,
3277 struct ieee80211_if_sta *ifsta) 1897 struct ieee80211_if_sta *ifsta)
3278{ 1898{
3279 mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL); 1899 mod_timer(&ifsta->timer, jiffies + IEEE80211_IBSS_MERGE_INTERVAL);
3280 1900
3281 ieee80211_sta_expire(dev, IEEE80211_IBSS_INACTIVITY_LIMIT); 1901 ieee80211_sta_expire(sdata, IEEE80211_IBSS_INACTIVITY_LIMIT);
3282 if (ieee80211_sta_active_ibss(dev)) 1902 if (ieee80211_sta_active_ibss(sdata))
3283 return; 1903 return;
3284 1904
3285 printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other " 1905 printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other "
3286 "IBSS networks with same SSID (merge)\n", dev->name); 1906 "IBSS networks with same SSID (merge)\n", sdata->dev->name);
3287 ieee80211_sta_req_scan(dev, ifsta->ssid, ifsta->ssid_len); 1907 ieee80211_request_scan(sdata, ifsta->ssid, ifsta->ssid_len);
3288} 1908}
3289 1909
3290 1910
3291#ifdef CONFIG_MAC80211_MESH 1911static void ieee80211_sta_timer(unsigned long data)
3292static void ieee80211_mesh_housekeeping(struct net_device *dev,
3293 struct ieee80211_if_sta *ifsta)
3294{
3295 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3296 bool free_plinks;
3297
3298 ieee80211_sta_expire(dev, IEEE80211_MESH_PEER_INACTIVITY_LIMIT);
3299 mesh_path_expire(dev);
3300
3301 free_plinks = mesh_plink_availables(sdata);
3302 if (free_plinks != sdata->u.sta.accepting_plinks)
3303 ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
3304
3305 mod_timer(&ifsta->timer, jiffies +
3306 IEEE80211_MESH_HOUSEKEEPING_INTERVAL);
3307}
3308
3309
3310void ieee80211_start_mesh(struct net_device *dev)
3311{
3312 struct ieee80211_if_sta *ifsta;
3313 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3314 ifsta = &sdata->u.sta;
3315 ifsta->state = IEEE80211_MESH_UP;
3316 ieee80211_sta_timer((unsigned long)sdata);
3317 ieee80211_if_config(sdata, IEEE80211_IFCC_BEACON);
3318}
3319#endif
3320
3321
3322void ieee80211_sta_timer(unsigned long data)
3323{ 1912{
3324 struct ieee80211_sub_if_data *sdata = 1913 struct ieee80211_sub_if_data *sdata =
3325 (struct ieee80211_sub_if_data *) data; 1914 (struct ieee80211_sub_if_data *) data;
3326 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 1915 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
3327 struct ieee80211_local *local = wdev_priv(&sdata->wdev); 1916 struct ieee80211_local *local = sdata->local;
3328 1917
3329 set_bit(IEEE80211_STA_REQ_RUN, &ifsta->request); 1918 set_bit(IEEE80211_STA_REQ_RUN, &ifsta->request);
3330 queue_work(local->hw.workqueue, &ifsta->work); 1919 queue_work(local->hw.workqueue, &ifsta->work);
3331} 1920}
3332 1921
3333void ieee80211_sta_work(struct work_struct *work) 1922static void ieee80211_sta_reset_auth(struct ieee80211_sub_if_data *sdata,
3334{
3335 struct ieee80211_sub_if_data *sdata =
3336 container_of(work, struct ieee80211_sub_if_data, u.sta.work);
3337 struct net_device *dev = sdata->dev;
3338 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
3339 struct ieee80211_if_sta *ifsta;
3340 struct sk_buff *skb;
3341
3342 if (!netif_running(dev))
3343 return;
3344
3345 if (local->sta_sw_scanning || local->sta_hw_scanning)
3346 return;
3347
3348 if (WARN_ON(sdata->vif.type != IEEE80211_IF_TYPE_STA &&
3349 sdata->vif.type != IEEE80211_IF_TYPE_IBSS &&
3350 sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT))
3351 return;
3352 ifsta = &sdata->u.sta;
3353
3354 while ((skb = skb_dequeue(&ifsta->skb_queue)))
3355 ieee80211_sta_rx_queued_mgmt(dev, skb);
3356
3357#ifdef CONFIG_MAC80211_MESH
3358 if (ifsta->preq_queue_len &&
3359 time_after(jiffies,
3360 ifsta->last_preq + msecs_to_jiffies(ifsta->mshcfg.dot11MeshHWMPpreqMinInterval)))
3361 mesh_path_start_discovery(dev);
3362#endif
3363
3364 if (ifsta->state != IEEE80211_AUTHENTICATE &&
3365 ifsta->state != IEEE80211_ASSOCIATE &&
3366 test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request)) {
3367 if (ifsta->scan_ssid_len)
3368 ieee80211_sta_start_scan(dev, ifsta->scan_ssid, ifsta->scan_ssid_len);
3369 else
3370 ieee80211_sta_start_scan(dev, NULL, 0);
3371 return;
3372 }
3373
3374 if (test_and_clear_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request)) {
3375 if (ieee80211_sta_config_auth(dev, ifsta))
3376 return;
3377 clear_bit(IEEE80211_STA_REQ_RUN, &ifsta->request);
3378 } else if (!test_and_clear_bit(IEEE80211_STA_REQ_RUN, &ifsta->request))
3379 return;
3380
3381 switch (ifsta->state) {
3382 case IEEE80211_DISABLED:
3383 break;
3384 case IEEE80211_AUTHENTICATE:
3385 ieee80211_authenticate(dev, ifsta);
3386 break;
3387 case IEEE80211_ASSOCIATE:
3388 ieee80211_associate(dev, ifsta);
3389 break;
3390 case IEEE80211_ASSOCIATED:
3391 ieee80211_associated(dev, ifsta);
3392 break;
3393 case IEEE80211_IBSS_SEARCH:
3394 ieee80211_sta_find_ibss(dev, ifsta);
3395 break;
3396 case IEEE80211_IBSS_JOINED:
3397 ieee80211_sta_merge_ibss(dev, ifsta);
3398 break;
3399#ifdef CONFIG_MAC80211_MESH
3400 case IEEE80211_MESH_UP:
3401 ieee80211_mesh_housekeeping(dev, ifsta);
3402 break;
3403#endif
3404 default:
3405 WARN_ON(1);
3406 break;
3407 }
3408
3409 if (ieee80211_privacy_mismatch(dev, ifsta)) {
3410 printk(KERN_DEBUG "%s: privacy configuration mismatch and "
3411 "mixed-cell disabled - disassociate\n", dev->name);
3412
3413 ieee80211_send_disassoc(dev, ifsta, WLAN_REASON_UNSPECIFIED);
3414 ieee80211_set_disassoc(dev, ifsta, 0);
3415 }
3416}
3417
3418
3419static void ieee80211_sta_reset_auth(struct net_device *dev,
3420 struct ieee80211_if_sta *ifsta) 1923 struct ieee80211_if_sta *ifsta)
3421{ 1924{
3422 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1925 struct ieee80211_local *local = sdata->local;
3423 1926
3424 if (local->ops->reset_tsf) { 1927 if (local->ops->reset_tsf) {
3425 /* Reset own TSF to allow time synchronization work. */ 1928 /* Reset own TSF to allow time synchronization work. */
@@ -3439,29 +1942,15 @@ static void ieee80211_sta_reset_auth(struct net_device *dev,
3439 ifsta->auth_alg = WLAN_AUTH_OPEN; 1942 ifsta->auth_alg = WLAN_AUTH_OPEN;
3440 ifsta->auth_transaction = -1; 1943 ifsta->auth_transaction = -1;
3441 ifsta->flags &= ~IEEE80211_STA_ASSOCIATED; 1944 ifsta->flags &= ~IEEE80211_STA_ASSOCIATED;
3442 ifsta->auth_tries = ifsta->assoc_tries = 0; 1945 ifsta->assoc_scan_tries = 0;
3443 netif_carrier_off(dev); 1946 ifsta->direct_probe_tries = 0;
1947 ifsta->auth_tries = 0;
1948 ifsta->assoc_tries = 0;
1949 netif_tx_stop_all_queues(sdata->dev);
1950 netif_carrier_off(sdata->dev);
3444} 1951}
3445 1952
3446 1953
3447void ieee80211_sta_req_auth(struct net_device *dev,
3448 struct ieee80211_if_sta *ifsta)
3449{
3450 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
3451 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3452
3453 if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
3454 return;
3455
3456 if ((ifsta->flags & (IEEE80211_STA_BSSID_SET |
3457 IEEE80211_STA_AUTO_BSSID_SEL)) &&
3458 (ifsta->flags & (IEEE80211_STA_SSID_SET |
3459 IEEE80211_STA_AUTO_SSID_SEL))) {
3460 set_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request);
3461 queue_work(local->hw.workqueue, &ifsta->work);
3462 }
3463}
3464
3465static int ieee80211_sta_match_ssid(struct ieee80211_if_sta *ifsta, 1954static int ieee80211_sta_match_ssid(struct ieee80211_if_sta *ifsta,
3466 const char *ssid, int ssid_len) 1955 const char *ssid, int ssid_len)
3467{ 1956{
@@ -3492,81 +1981,11 @@ static int ieee80211_sta_match_ssid(struct ieee80211_if_sta *ifsta,
3492 return 0; 1981 return 0;
3493} 1982}
3494 1983
3495static int ieee80211_sta_config_auth(struct net_device *dev, 1984static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata,
3496 struct ieee80211_if_sta *ifsta)
3497{
3498 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
3499 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3500 struct ieee80211_sta_bss *bss, *selected = NULL;
3501 int top_rssi = 0, freq;
3502
3503 spin_lock_bh(&local->sta_bss_lock);
3504 freq = local->oper_channel->center_freq;
3505 list_for_each_entry(bss, &local->sta_bss_list, list) {
3506 if (!(bss->capability & WLAN_CAPABILITY_ESS))
3507 continue;
3508
3509 if ((ifsta->flags & (IEEE80211_STA_AUTO_SSID_SEL |
3510 IEEE80211_STA_AUTO_BSSID_SEL |
3511 IEEE80211_STA_AUTO_CHANNEL_SEL)) &&
3512 (!!(bss->capability & WLAN_CAPABILITY_PRIVACY) ^
3513 !!sdata->default_key))
3514 continue;
3515
3516 if (!(ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL) &&
3517 bss->freq != freq)
3518 continue;
3519
3520 if (!(ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL) &&
3521 memcmp(bss->bssid, ifsta->bssid, ETH_ALEN))
3522 continue;
3523
3524 if (!(ifsta->flags & IEEE80211_STA_AUTO_SSID_SEL) &&
3525 !ieee80211_sta_match_ssid(ifsta, bss->ssid, bss->ssid_len))
3526 continue;
3527
3528 if (!selected || top_rssi < bss->signal) {
3529 selected = bss;
3530 top_rssi = bss->signal;
3531 }
3532 }
3533 if (selected)
3534 atomic_inc(&selected->users);
3535 spin_unlock_bh(&local->sta_bss_lock);
3536
3537 if (selected) {
3538 ieee80211_set_freq(dev, selected->freq);
3539 if (!(ifsta->flags & IEEE80211_STA_SSID_SET))
3540 ieee80211_sta_set_ssid(dev, selected->ssid,
3541 selected->ssid_len);
3542 ieee80211_sta_set_bssid(dev, selected->bssid);
3543 ieee80211_sta_def_wmm_params(dev, selected, 0);
3544 ieee80211_rx_bss_put(local, selected);
3545 ifsta->state = IEEE80211_AUTHENTICATE;
3546 ieee80211_sta_reset_auth(dev, ifsta);
3547 return 0;
3548 } else {
3549 if (ifsta->state != IEEE80211_AUTHENTICATE) {
3550 if (ifsta->flags & IEEE80211_STA_AUTO_SSID_SEL)
3551 ieee80211_sta_start_scan(dev, NULL, 0);
3552 else
3553 ieee80211_sta_start_scan(dev, ifsta->ssid,
3554 ifsta->ssid_len);
3555 ifsta->state = IEEE80211_AUTHENTICATE;
3556 set_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request);
3557 } else
3558 ifsta->state = IEEE80211_DISABLED;
3559 }
3560 return -1;
3561}
3562
3563
3564static int ieee80211_sta_create_ibss(struct net_device *dev,
3565 struct ieee80211_if_sta *ifsta) 1985 struct ieee80211_if_sta *ifsta)
3566{ 1986{
3567 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1987 struct ieee80211_local *local = sdata->local;
3568 struct ieee80211_sta_bss *bss; 1988 struct ieee80211_bss *bss;
3569 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3570 struct ieee80211_supported_band *sband; 1989 struct ieee80211_supported_band *sband;
3571 u8 bssid[ETH_ALEN], *pos; 1990 u8 bssid[ETH_ALEN], *pos;
3572 int i; 1991 int i;
@@ -3582,15 +2001,15 @@ static int ieee80211_sta_create_ibss(struct net_device *dev,
3582 * random number generator get different BSSID. */ 2001 * random number generator get different BSSID. */
3583 get_random_bytes(bssid, ETH_ALEN); 2002 get_random_bytes(bssid, ETH_ALEN);
3584 for (i = 0; i < ETH_ALEN; i++) 2003 for (i = 0; i < ETH_ALEN; i++)
3585 bssid[i] ^= dev->dev_addr[i]; 2004 bssid[i] ^= sdata->dev->dev_addr[i];
3586 bssid[0] &= ~0x01; 2005 bssid[0] &= ~0x01;
3587 bssid[0] |= 0x02; 2006 bssid[0] |= 0x02;
3588#endif 2007#endif
3589 2008
3590 printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n", 2009 printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %s\n",
3591 dev->name, print_mac(mac, bssid)); 2010 sdata->dev->name, print_mac(mac, bssid));
3592 2011
3593 bss = ieee80211_rx_bss_add(dev, bssid, 2012 bss = ieee80211_rx_bss_add(local, bssid,
3594 local->hw.conf.channel->center_freq, 2013 local->hw.conf.channel->center_freq,
3595 sdata->u.sta.ssid, sdata->u.sta.ssid_len); 2014 sdata->u.sta.ssid, sdata->u.sta.ssid_len);
3596 if (!bss) 2015 if (!bss)
@@ -3617,17 +2036,17 @@ static int ieee80211_sta_create_ibss(struct net_device *dev,
3617 *pos++ = (u8) (rate / 5); 2036 *pos++ = (u8) (rate / 5);
3618 } 2037 }
3619 2038
3620 ret = ieee80211_sta_join_ibss(dev, ifsta, bss); 2039 ret = ieee80211_sta_join_ibss(sdata, ifsta, bss);
3621 ieee80211_rx_bss_put(local, bss); 2040 ieee80211_rx_bss_put(local, bss);
3622 return ret; 2041 return ret;
3623} 2042}
3624 2043
3625 2044
3626static int ieee80211_sta_find_ibss(struct net_device *dev, 2045static int ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata,
3627 struct ieee80211_if_sta *ifsta) 2046 struct ieee80211_if_sta *ifsta)
3628{ 2047{
3629 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 2048 struct ieee80211_local *local = sdata->local;
3630 struct ieee80211_sta_bss *bss; 2049 struct ieee80211_bss *bss;
3631 int found = 0; 2050 int found = 0;
3632 u8 bssid[ETH_ALEN]; 2051 u8 bssid[ETH_ALEN];
3633 int active_ibss; 2052 int active_ibss;
@@ -3637,13 +2056,13 @@ static int ieee80211_sta_find_ibss(struct net_device *dev,
3637 if (ifsta->ssid_len == 0) 2056 if (ifsta->ssid_len == 0)
3638 return -EINVAL; 2057 return -EINVAL;
3639 2058
3640 active_ibss = ieee80211_sta_active_ibss(dev); 2059 active_ibss = ieee80211_sta_active_ibss(sdata);
3641#ifdef CONFIG_MAC80211_IBSS_DEBUG 2060#ifdef CONFIG_MAC80211_IBSS_DEBUG
3642 printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n", 2061 printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n",
3643 dev->name, active_ibss); 2062 sdata->dev->name, active_ibss);
3644#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 2063#endif /* CONFIG_MAC80211_IBSS_DEBUG */
3645 spin_lock_bh(&local->sta_bss_lock); 2064 spin_lock_bh(&local->bss_lock);
3646 list_for_each_entry(bss, &local->sta_bss_list, list) { 2065 list_for_each_entry(bss, &local->bss_list, list) {
3647 if (ifsta->ssid_len != bss->ssid_len || 2066 if (ifsta->ssid_len != bss->ssid_len ||
3648 memcmp(ifsta->ssid, bss->ssid, bss->ssid_len) != 0 2067 memcmp(ifsta->ssid, bss->ssid, bss->ssid_len) != 0
3649 || !(bss->capability & WLAN_CAPABILITY_IBSS)) 2068 || !(bss->capability & WLAN_CAPABILITY_IBSS))
@@ -3657,7 +2076,7 @@ static int ieee80211_sta_find_ibss(struct net_device *dev,
3657 if (active_ibss || memcmp(bssid, ifsta->bssid, ETH_ALEN) != 0) 2076 if (active_ibss || memcmp(bssid, ifsta->bssid, ETH_ALEN) != 0)
3658 break; 2077 break;
3659 } 2078 }
3660 spin_unlock_bh(&local->sta_bss_lock); 2079 spin_unlock_bh(&local->bss_lock);
3661 2080
3662#ifdef CONFIG_MAC80211_IBSS_DEBUG 2081#ifdef CONFIG_MAC80211_IBSS_DEBUG
3663 if (found) 2082 if (found)
@@ -3675,15 +2094,15 @@ static int ieee80211_sta_find_ibss(struct net_device *dev,
3675 else 2094 else
3676 search_freq = local->hw.conf.channel->center_freq; 2095 search_freq = local->hw.conf.channel->center_freq;
3677 2096
3678 bss = ieee80211_rx_bss_get(dev, bssid, search_freq, 2097 bss = ieee80211_rx_bss_get(local, bssid, search_freq,
3679 ifsta->ssid, ifsta->ssid_len); 2098 ifsta->ssid, ifsta->ssid_len);
3680 if (!bss) 2099 if (!bss)
3681 goto dont_join; 2100 goto dont_join;
3682 2101
3683 printk(KERN_DEBUG "%s: Selected IBSS BSSID %s" 2102 printk(KERN_DEBUG "%s: Selected IBSS BSSID %s"
3684 " based on configured SSID\n", 2103 " based on configured SSID\n",
3685 dev->name, print_mac(mac, bssid)); 2104 sdata->dev->name, print_mac(mac, bssid));
3686 ret = ieee80211_sta_join_ibss(dev, ifsta, bss); 2105 ret = ieee80211_sta_join_ibss(sdata, ifsta, bss);
3687 ieee80211_rx_bss_put(local, bss); 2106 ieee80211_rx_bss_put(local, bss);
3688 return ret; 2107 return ret;
3689 } 2108 }
@@ -3694,17 +2113,17 @@ dont_join:
3694#endif /* CONFIG_MAC80211_IBSS_DEBUG */ 2113#endif /* CONFIG_MAC80211_IBSS_DEBUG */
3695 2114
3696 /* Selected IBSS not found in current scan results - try to scan */ 2115 /* Selected IBSS not found in current scan results - try to scan */
3697 if (ifsta->state == IEEE80211_IBSS_JOINED && 2116 if (ifsta->state == IEEE80211_STA_MLME_IBSS_JOINED &&
3698 !ieee80211_sta_active_ibss(dev)) { 2117 !ieee80211_sta_active_ibss(sdata)) {
3699 mod_timer(&ifsta->timer, jiffies + 2118 mod_timer(&ifsta->timer, jiffies +
3700 IEEE80211_IBSS_MERGE_INTERVAL); 2119 IEEE80211_IBSS_MERGE_INTERVAL);
3701 } else if (time_after(jiffies, local->last_scan_completed + 2120 } else if (time_after(jiffies, local->last_scan_completed +
3702 IEEE80211_SCAN_INTERVAL)) { 2121 IEEE80211_SCAN_INTERVAL)) {
3703 printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to " 2122 printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to "
3704 "join\n", dev->name); 2123 "join\n", sdata->dev->name);
3705 return ieee80211_sta_req_scan(dev, ifsta->ssid, 2124 return ieee80211_request_scan(sdata, ifsta->ssid,
3706 ifsta->ssid_len); 2125 ifsta->ssid_len);
3707 } else if (ifsta->state != IEEE80211_IBSS_JOINED) { 2126 } else if (ifsta->state != IEEE80211_STA_MLME_IBSS_JOINED) {
3708 int interval = IEEE80211_SCAN_INTERVAL; 2127 int interval = IEEE80211_SCAN_INTERVAL;
3709 2128
3710 if (time_after(jiffies, ifsta->ibss_join_req + 2129 if (time_after(jiffies, ifsta->ibss_join_req +
@@ -3712,10 +2131,10 @@ dont_join:
3712 if ((ifsta->flags & IEEE80211_STA_CREATE_IBSS) && 2131 if ((ifsta->flags & IEEE80211_STA_CREATE_IBSS) &&
3713 (!(local->oper_channel->flags & 2132 (!(local->oper_channel->flags &
3714 IEEE80211_CHAN_NO_IBSS))) 2133 IEEE80211_CHAN_NO_IBSS)))
3715 return ieee80211_sta_create_ibss(dev, ifsta); 2134 return ieee80211_sta_create_ibss(sdata, ifsta);
3716 if (ifsta->flags & IEEE80211_STA_CREATE_IBSS) { 2135 if (ifsta->flags & IEEE80211_STA_CREATE_IBSS) {
3717 printk(KERN_DEBUG "%s: IBSS not allowed on" 2136 printk(KERN_DEBUG "%s: IBSS not allowed on"
3718 " %d MHz\n", dev->name, 2137 " %d MHz\n", sdata->dev->name,
3719 local->hw.conf.channel->center_freq); 2138 local->hw.conf.channel->center_freq);
3720 } 2139 }
3721 2140
@@ -3724,7 +2143,7 @@ dont_join:
3724 interval = IEEE80211_SCAN_INTERVAL_SLOW; 2143 interval = IEEE80211_SCAN_INTERVAL_SLOW;
3725 } 2144 }
3726 2145
3727 ifsta->state = IEEE80211_IBSS_SEARCH; 2146 ifsta->state = IEEE80211_STA_MLME_IBSS_SEARCH;
3728 mod_timer(&ifsta->timer, jiffies + interval); 2147 mod_timer(&ifsta->timer, jiffies + interval);
3729 return 0; 2148 return 0;
3730 } 2149 }
@@ -3733,620 +2152,344 @@ dont_join:
3733} 2152}
3734 2153
3735 2154
3736int ieee80211_sta_set_ssid(struct net_device *dev, char *ssid, size_t len) 2155static int ieee80211_sta_config_auth(struct ieee80211_sub_if_data *sdata,
2156 struct ieee80211_if_sta *ifsta)
3737{ 2157{
3738 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 2158 struct ieee80211_local *local = sdata->local;
3739 struct ieee80211_if_sta *ifsta; 2159 struct ieee80211_bss *bss, *selected = NULL;
3740 int res; 2160 int top_rssi = 0, freq;
3741 2161
3742 if (len > IEEE80211_MAX_SSID_LEN) 2162 spin_lock_bh(&local->bss_lock);
3743 return -EINVAL; 2163 freq = local->oper_channel->center_freq;
2164 list_for_each_entry(bss, &local->bss_list, list) {
2165 if (!(bss->capability & WLAN_CAPABILITY_ESS))
2166 continue;
3744 2167
3745 ifsta = &sdata->u.sta; 2168 if ((ifsta->flags & (IEEE80211_STA_AUTO_SSID_SEL |
2169 IEEE80211_STA_AUTO_BSSID_SEL |
2170 IEEE80211_STA_AUTO_CHANNEL_SEL)) &&
2171 (!!(bss->capability & WLAN_CAPABILITY_PRIVACY) ^
2172 !!sdata->default_key))
2173 continue;
3746 2174
3747 if (ifsta->ssid_len != len || memcmp(ifsta->ssid, ssid, len) != 0) { 2175 if (!(ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL) &&
3748 memset(ifsta->ssid, 0, sizeof(ifsta->ssid)); 2176 bss->freq != freq)
3749 memcpy(ifsta->ssid, ssid, len); 2177 continue;
3750 ifsta->ssid_len = len;
3751 ifsta->flags &= ~IEEE80211_STA_PREV_BSSID_SET;
3752 2178
3753 res = 0; 2179 if (!(ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL) &&
3754 /* 2180 memcmp(bss->bssid, ifsta->bssid, ETH_ALEN))
3755 * Hack! MLME code needs to be cleaned up to have different 2181 continue;
3756 * entry points for configuration and internal selection change
3757 */
3758 if (netif_running(sdata->dev))
3759 res = ieee80211_if_config(sdata, IEEE80211_IFCC_SSID);
3760 if (res) {
3761 printk(KERN_DEBUG "%s: Failed to config new SSID to "
3762 "the low-level driver\n", dev->name);
3763 return res;
3764 }
3765 }
3766 2182
3767 if (len) 2183 if (!(ifsta->flags & IEEE80211_STA_AUTO_SSID_SEL) &&
3768 ifsta->flags |= IEEE80211_STA_SSID_SET; 2184 !ieee80211_sta_match_ssid(ifsta, bss->ssid, bss->ssid_len))
3769 else 2185 continue;
3770 ifsta->flags &= ~IEEE80211_STA_SSID_SET;
3771 2186
3772 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS && 2187 if (!selected || top_rssi < bss->signal) {
3773 !(ifsta->flags & IEEE80211_STA_BSSID_SET)) { 2188 selected = bss;
3774 ifsta->ibss_join_req = jiffies; 2189 top_rssi = bss->signal;
3775 ifsta->state = IEEE80211_IBSS_SEARCH; 2190 }
3776 return ieee80211_sta_find_ibss(dev, ifsta);
3777 } 2191 }
2192 if (selected)
2193 atomic_inc(&selected->users);
2194 spin_unlock_bh(&local->bss_lock);
3778 2195
3779 return 0; 2196 if (selected) {
3780} 2197 ieee80211_set_freq(sdata, selected->freq);
2198 if (!(ifsta->flags & IEEE80211_STA_SSID_SET))
2199 ieee80211_sta_set_ssid(sdata, selected->ssid,
2200 selected->ssid_len);
2201 ieee80211_sta_set_bssid(sdata, selected->bssid);
2202 ieee80211_sta_def_wmm_params(sdata, selected);
3781 2203
2204 /* Send out direct probe if no probe resp was received or
2205 * the one we have is outdated
2206 */
2207 if (!selected->last_probe_resp ||
2208 time_after(jiffies, selected->last_probe_resp
2209 + IEEE80211_SCAN_RESULT_EXPIRE))
2210 ifsta->state = IEEE80211_STA_MLME_DIRECT_PROBE;
2211 else
2212 ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE;
3782 2213
3783int ieee80211_sta_get_ssid(struct net_device *dev, char *ssid, size_t *len) 2214 ieee80211_rx_bss_put(local, selected);
3784{ 2215 ieee80211_sta_reset_auth(sdata, ifsta);
3785 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 2216 return 0;
3786 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 2217 } else {
3787 memcpy(ssid, ifsta->ssid, ifsta->ssid_len); 2218 if (ifsta->assoc_scan_tries < IEEE80211_ASSOC_SCANS_MAX_TRIES) {
3788 *len = ifsta->ssid_len; 2219 ifsta->assoc_scan_tries++;
3789 return 0; 2220 if (ifsta->flags & IEEE80211_STA_AUTO_SSID_SEL)
2221 ieee80211_start_scan(sdata, NULL, 0);
2222 else
2223 ieee80211_start_scan(sdata, ifsta->ssid,
2224 ifsta->ssid_len);
2225 ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE;
2226 set_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request);
2227 } else
2228 ifsta->state = IEEE80211_STA_MLME_DISABLED;
2229 }
2230 return -1;
3790} 2231}
3791 2232
3792 2233
3793int ieee80211_sta_set_bssid(struct net_device *dev, u8 *bssid) 2234static void ieee80211_sta_work(struct work_struct *work)
3794{ 2235{
3795 struct ieee80211_sub_if_data *sdata; 2236 struct ieee80211_sub_if_data *sdata =
2237 container_of(work, struct ieee80211_sub_if_data, u.sta.work);
2238 struct ieee80211_local *local = sdata->local;
3796 struct ieee80211_if_sta *ifsta; 2239 struct ieee80211_if_sta *ifsta;
3797 int res; 2240 struct sk_buff *skb;
3798
3799 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3800 ifsta = &sdata->u.sta;
3801 2241
3802 if (memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) { 2242 if (!netif_running(sdata->dev))
3803 memcpy(ifsta->bssid, bssid, ETH_ALEN); 2243 return;
3804 res = 0;
3805 /*
3806 * Hack! See also ieee80211_sta_set_ssid.
3807 */
3808 if (netif_running(sdata->dev))
3809 res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
3810 if (res) {
3811 printk(KERN_DEBUG "%s: Failed to config new BSSID to "
3812 "the low-level driver\n", dev->name);
3813 return res;
3814 }
3815 }
3816 2244
3817 if (is_valid_ether_addr(bssid)) 2245 if (local->sw_scanning || local->hw_scanning)
3818 ifsta->flags |= IEEE80211_STA_BSSID_SET; 2246 return;
3819 else
3820 ifsta->flags &= ~IEEE80211_STA_BSSID_SET;
3821 2247
3822 return 0; 2248 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION &&
3823} 2249 sdata->vif.type != NL80211_IFTYPE_ADHOC))
2250 return;
2251 ifsta = &sdata->u.sta;
3824 2252
2253 while ((skb = skb_dequeue(&ifsta->skb_queue)))
2254 ieee80211_sta_rx_queued_mgmt(sdata, skb);
3825 2255
3826static void ieee80211_send_nullfunc(struct ieee80211_local *local, 2256 if (ifsta->state != IEEE80211_STA_MLME_DIRECT_PROBE &&
3827 struct ieee80211_sub_if_data *sdata, 2257 ifsta->state != IEEE80211_STA_MLME_AUTHENTICATE &&
3828 int powersave) 2258 ifsta->state != IEEE80211_STA_MLME_ASSOCIATE &&
3829{ 2259 test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request)) {
3830 struct sk_buff *skb; 2260 ieee80211_start_scan(sdata, ifsta->scan_ssid,
3831 struct ieee80211_hdr *nullfunc; 2261 ifsta->scan_ssid_len);
3832 __le16 fc; 2262 return;
2263 }
3833 2264
3834 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24); 2265 if (test_and_clear_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request)) {
3835 if (!skb) { 2266 if (ieee80211_sta_config_auth(sdata, ifsta))
3836 printk(KERN_DEBUG "%s: failed to allocate buffer for nullfunc " 2267 return;
3837 "frame\n", sdata->dev->name); 2268 clear_bit(IEEE80211_STA_REQ_RUN, &ifsta->request);
2269 } else if (!test_and_clear_bit(IEEE80211_STA_REQ_RUN, &ifsta->request))
3838 return; 2270 return;
2271
2272 switch (ifsta->state) {
2273 case IEEE80211_STA_MLME_DISABLED:
2274 break;
2275 case IEEE80211_STA_MLME_DIRECT_PROBE:
2276 ieee80211_direct_probe(sdata, ifsta);
2277 break;
2278 case IEEE80211_STA_MLME_AUTHENTICATE:
2279 ieee80211_authenticate(sdata, ifsta);
2280 break;
2281 case IEEE80211_STA_MLME_ASSOCIATE:
2282 ieee80211_associate(sdata, ifsta);
2283 break;
2284 case IEEE80211_STA_MLME_ASSOCIATED:
2285 ieee80211_associated(sdata, ifsta);
2286 break;
2287 case IEEE80211_STA_MLME_IBSS_SEARCH:
2288 ieee80211_sta_find_ibss(sdata, ifsta);
2289 break;
2290 case IEEE80211_STA_MLME_IBSS_JOINED:
2291 ieee80211_sta_merge_ibss(sdata, ifsta);
2292 break;
2293 default:
2294 WARN_ON(1);
2295 break;
3839 } 2296 }
3840 skb_reserve(skb, local->hw.extra_tx_headroom);
3841 2297
3842 nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24); 2298 if (ieee80211_privacy_mismatch(sdata, ifsta)) {
3843 memset(nullfunc, 0, 24); 2299 printk(KERN_DEBUG "%s: privacy configuration mismatch and "
3844 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC | 2300 "mixed-cell disabled - disassociate\n", sdata->dev->name);
3845 IEEE80211_FCTL_TODS);
3846 if (powersave)
3847 fc |= cpu_to_le16(IEEE80211_FCTL_PM);
3848 nullfunc->frame_control = fc;
3849 memcpy(nullfunc->addr1, sdata->u.sta.bssid, ETH_ALEN);
3850 memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN);
3851 memcpy(nullfunc->addr3, sdata->u.sta.bssid, ETH_ALEN);
3852
3853 ieee80211_sta_tx(sdata->dev, skb, 0);
3854}
3855 2301
2302 ieee80211_set_disassoc(sdata, ifsta, false, true,
2303 WLAN_REASON_UNSPECIFIED);
2304 }
2305}
3856 2306
3857static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata) 2307static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
3858{ 2308{
3859 if (sdata->vif.type == IEEE80211_IF_TYPE_STA || 2309 if (sdata->vif.type == NL80211_IFTYPE_STATION)
3860 ieee80211_vif_is_mesh(&sdata->vif)) 2310 queue_work(sdata->local->hw.workqueue,
3861 ieee80211_sta_timer((unsigned long)sdata); 2311 &sdata->u.sta.work);
3862} 2312}
3863 2313
3864void ieee80211_scan_completed(struct ieee80211_hw *hw) 2314/* interface setup */
2315void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
3865{ 2316{
3866 struct ieee80211_local *local = hw_to_local(hw); 2317 struct ieee80211_if_sta *ifsta;
3867 struct net_device *dev = local->scan_dev;
3868 struct ieee80211_sub_if_data *sdata;
3869 union iwreq_data wrqu;
3870 2318
3871 local->last_scan_completed = jiffies; 2319 ifsta = &sdata->u.sta;
3872 memset(&wrqu, 0, sizeof(wrqu)); 2320 INIT_WORK(&ifsta->work, ieee80211_sta_work);
3873 wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL); 2321 setup_timer(&ifsta->timer, ieee80211_sta_timer,
3874 2322 (unsigned long) sdata);
3875 if (local->sta_hw_scanning) { 2323 skb_queue_head_init(&ifsta->skb_queue);
3876 local->sta_hw_scanning = 0;
3877 if (ieee80211_hw_config(local))
3878 printk(KERN_DEBUG "%s: failed to restore operational "
3879 "channel after scan\n", dev->name);
3880 /* Restart STA timer for HW scan case */
3881 rcu_read_lock();
3882 list_for_each_entry_rcu(sdata, &local->interfaces, list)
3883 ieee80211_restart_sta_timer(sdata);
3884 rcu_read_unlock();
3885 2324
3886 goto done; 2325 ifsta->capab = WLAN_CAPABILITY_ESS;
2326 ifsta->auth_algs = IEEE80211_AUTH_ALG_OPEN |
2327 IEEE80211_AUTH_ALG_SHARED_KEY;
2328 ifsta->flags |= IEEE80211_STA_CREATE_IBSS |
2329 IEEE80211_STA_AUTO_BSSID_SEL |
2330 IEEE80211_STA_AUTO_CHANNEL_SEL;
2331 if (ieee80211_num_regular_queues(&sdata->local->hw) >= 4)
2332 ifsta->flags |= IEEE80211_STA_WMM_ENABLED;
2333}
2334
2335/*
2336 * Add a new IBSS station, will also be called by the RX code when,
2337 * in IBSS mode, receiving a frame from a yet-unknown station, hence
2338 * must be callable in atomic context.
2339 */
2340struct sta_info *ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
2341 struct sk_buff *skb, u8 *bssid,
2342 u8 *addr, u64 supp_rates)
2343{
2344 struct ieee80211_local *local = sdata->local;
2345 struct sta_info *sta;
2346 DECLARE_MAC_BUF(mac);
2347 int band = local->hw.conf.channel->band;
2348
2349 /* TODO: Could consider removing the least recently used entry and
2350 * allow new one to be added. */
2351 if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) {
2352 if (net_ratelimit()) {
2353 printk(KERN_DEBUG "%s: No room for a new IBSS STA "
2354 "entry %s\n", sdata->dev->name, print_mac(mac, addr));
2355 }
2356 return NULL;
3887 } 2357 }
3888 2358
3889 local->sta_sw_scanning = 0; 2359 if (compare_ether_addr(bssid, sdata->u.sta.bssid))
3890 if (ieee80211_hw_config(local)) 2360 return NULL;
3891 printk(KERN_DEBUG "%s: failed to restore operational "
3892 "channel after scan\n", dev->name);
3893 2361
2362#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
2363 printk(KERN_DEBUG "%s: Adding new IBSS station %s (dev=%s)\n",
2364 wiphy_name(local->hw.wiphy), print_mac(mac, addr), sdata->dev->name);
2365#endif
3894 2366
3895 netif_tx_lock_bh(local->mdev); 2367 sta = sta_info_alloc(sdata, addr, GFP_ATOMIC);
3896 netif_addr_lock(local->mdev); 2368 if (!sta)
3897 local->filter_flags &= ~FIF_BCN_PRBRESP_PROMISC; 2369 return NULL;
3898 local->ops->configure_filter(local_to_hw(local),
3899 FIF_BCN_PRBRESP_PROMISC,
3900 &local->filter_flags,
3901 local->mdev->mc_count,
3902 local->mdev->mc_list);
3903 2370
3904 netif_addr_unlock(local->mdev); 2371 set_sta_flags(sta, WLAN_STA_AUTHORIZED);
3905 netif_tx_unlock_bh(local->mdev);
3906 2372
3907 rcu_read_lock(); 2373 /* make sure mandatory rates are always added */
3908 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 2374 sta->sta.supp_rates[band] = supp_rates |
3909 /* Tell AP we're back */ 2375 ieee80211_mandatory_rates(local, band);
3910 if (sdata->vif.type == IEEE80211_IF_TYPE_STA &&
3911 sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED)
3912 ieee80211_send_nullfunc(local, sdata, 0);
3913 2376
3914 ieee80211_restart_sta_timer(sdata); 2377 rate_control_rate_init(sta);
3915 2378
3916 netif_wake_queue(sdata->dev); 2379 if (sta_info_insert(sta))
3917 } 2380 return NULL;
3918 rcu_read_unlock();
3919 2381
3920done: 2382 return sta;
3921 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3922 if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) {
3923 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
3924 if (!(ifsta->flags & IEEE80211_STA_BSSID_SET) ||
3925 (!(ifsta->state == IEEE80211_IBSS_JOINED) &&
3926 !ieee80211_sta_active_ibss(dev)))
3927 ieee80211_sta_find_ibss(dev, ifsta);
3928 }
3929} 2383}
3930EXPORT_SYMBOL(ieee80211_scan_completed);
3931 2384
3932void ieee80211_sta_scan_work(struct work_struct *work) 2385/* configuration hooks */
2386void ieee80211_sta_req_auth(struct ieee80211_sub_if_data *sdata,
2387 struct ieee80211_if_sta *ifsta)
3933{ 2388{
3934 struct ieee80211_local *local = 2389 struct ieee80211_local *local = sdata->local;
3935 container_of(work, struct ieee80211_local, scan_work.work);
3936 struct net_device *dev = local->scan_dev;
3937 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
3938 struct ieee80211_supported_band *sband;
3939 struct ieee80211_channel *chan;
3940 int skip;
3941 unsigned long next_delay = 0;
3942 2390
3943 if (!local->sta_sw_scanning) 2391 if (sdata->vif.type != NL80211_IFTYPE_STATION)
3944 return; 2392 return;
3945 2393
3946 switch (local->scan_state) { 2394 if ((ifsta->flags & (IEEE80211_STA_BSSID_SET |
3947 case SCAN_SET_CHANNEL: 2395 IEEE80211_STA_AUTO_BSSID_SEL)) &&
3948 /* 2396 (ifsta->flags & (IEEE80211_STA_SSID_SET |
3949 * Get current scan band. scan_band may be IEEE80211_NUM_BANDS 2397 IEEE80211_STA_AUTO_SSID_SEL))) {
3950 * after we successfully scanned the last channel of the last
3951 * band (and the last band is supported by the hw)
3952 */
3953 if (local->scan_band < IEEE80211_NUM_BANDS)
3954 sband = local->hw.wiphy->bands[local->scan_band];
3955 else
3956 sband = NULL;
3957
3958 /*
3959 * If we are at an unsupported band and have more bands
3960 * left to scan, advance to the next supported one.
3961 */
3962 while (!sband && local->scan_band < IEEE80211_NUM_BANDS - 1) {
3963 local->scan_band++;
3964 sband = local->hw.wiphy->bands[local->scan_band];
3965 local->scan_channel_idx = 0;
3966 }
3967
3968 /* if no more bands/channels left, complete scan */
3969 if (!sband || local->scan_channel_idx >= sband->n_channels) {
3970 ieee80211_scan_completed(local_to_hw(local));
3971 return;
3972 }
3973 skip = 0;
3974 chan = &sband->channels[local->scan_channel_idx];
3975
3976 if (chan->flags & IEEE80211_CHAN_DISABLED ||
3977 (sdata->vif.type == IEEE80211_IF_TYPE_IBSS &&
3978 chan->flags & IEEE80211_CHAN_NO_IBSS))
3979 skip = 1;
3980
3981 if (!skip) {
3982 local->scan_channel = chan;
3983 if (ieee80211_hw_config(local)) {
3984 printk(KERN_DEBUG "%s: failed to set freq to "
3985 "%d MHz for scan\n", dev->name,
3986 chan->center_freq);
3987 skip = 1;
3988 }
3989 }
3990
3991 /* advance state machine to next channel/band */
3992 local->scan_channel_idx++;
3993 if (local->scan_channel_idx >= sband->n_channels) {
3994 /*
3995 * scan_band may end up == IEEE80211_NUM_BANDS, but
3996 * we'll catch that case above and complete the scan
3997 * if that is the case.
3998 */
3999 local->scan_band++;
4000 local->scan_channel_idx = 0;
4001 }
4002
4003 if (skip)
4004 break;
4005 2398
4006 next_delay = IEEE80211_PROBE_DELAY + 2399 if (ifsta->state == IEEE80211_STA_MLME_ASSOCIATED)
4007 usecs_to_jiffies(local->hw.channel_change_time); 2400 ieee80211_set_disassoc(sdata, ifsta, true, true,
4008 local->scan_state = SCAN_SEND_PROBE; 2401 WLAN_REASON_DEAUTH_LEAVING);
4009 break;
4010 case SCAN_SEND_PROBE:
4011 next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
4012 local->scan_state = SCAN_SET_CHANNEL;
4013 2402
4014 if (local->scan_channel->flags & IEEE80211_CHAN_PASSIVE_SCAN) 2403 set_bit(IEEE80211_STA_REQ_AUTH, &ifsta->request);
4015 break; 2404 queue_work(local->hw.workqueue, &ifsta->work);
4016 ieee80211_send_probe_req(dev, NULL, local->scan_ssid,
4017 local->scan_ssid_len);
4018 next_delay = IEEE80211_CHANNEL_TIME;
4019 break;
4020 } 2405 }
4021
4022 if (local->sta_sw_scanning)
4023 queue_delayed_work(local->hw.workqueue, &local->scan_work,
4024 next_delay);
4025} 2406}
4026 2407
4027 2408int ieee80211_sta_set_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t len)
4028static int ieee80211_sta_start_scan(struct net_device *dev,
4029 u8 *ssid, size_t ssid_len)
4030{ 2409{
4031 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 2410 struct ieee80211_if_sta *ifsta;
4032 struct ieee80211_sub_if_data *sdata; 2411 int res;
4033 2412
4034 if (ssid_len > IEEE80211_MAX_SSID_LEN) 2413 if (len > IEEE80211_MAX_SSID_LEN)
4035 return -EINVAL; 2414 return -EINVAL;
4036 2415
4037 /* MLME-SCAN.request (page 118) page 144 (11.1.3.1) 2416 ifsta = &sdata->u.sta;
4038 * BSSType: INFRASTRUCTURE, INDEPENDENT, ANY_BSS
4039 * BSSID: MACAddress
4040 * SSID
4041 * ScanType: ACTIVE, PASSIVE
4042 * ProbeDelay: delay (in microseconds) to be used prior to transmitting
4043 * a Probe frame during active scanning
4044 * ChannelList
4045 * MinChannelTime (>= ProbeDelay), in TU
4046 * MaxChannelTime: (>= MinChannelTime), in TU
4047 */
4048
4049 /* MLME-SCAN.confirm
4050 * BSSDescriptionSet
4051 * ResultCode: SUCCESS, INVALID_PARAMETERS
4052 */
4053 2417
4054 if (local->sta_sw_scanning || local->sta_hw_scanning) { 2418 if (ifsta->ssid_len != len || memcmp(ifsta->ssid, ssid, len) != 0) {
4055 if (local->scan_dev == dev) 2419 memset(ifsta->ssid, 0, sizeof(ifsta->ssid));
4056 return 0; 2420 memcpy(ifsta->ssid, ssid, len);
4057 return -EBUSY; 2421 ifsta->ssid_len = len;
4058 } 2422 ifsta->flags &= ~IEEE80211_STA_PREV_BSSID_SET;
4059 2423
4060 if (local->ops->hw_scan) { 2424 res = 0;
4061 int rc = local->ops->hw_scan(local_to_hw(local), 2425 /*
4062 ssid, ssid_len); 2426 * Hack! MLME code needs to be cleaned up to have different
4063 if (!rc) { 2427 * entry points for configuration and internal selection change
4064 local->sta_hw_scanning = 1; 2428 */
4065 local->scan_dev = dev; 2429 if (netif_running(sdata->dev))
2430 res = ieee80211_if_config(sdata, IEEE80211_IFCC_SSID);
2431 if (res) {
2432 printk(KERN_DEBUG "%s: Failed to config new SSID to "
2433 "the low-level driver\n", sdata->dev->name);
2434 return res;
4066 } 2435 }
4067 return rc;
4068 } 2436 }
4069 2437
4070 local->sta_sw_scanning = 1; 2438 if (len)
2439 ifsta->flags |= IEEE80211_STA_SSID_SET;
2440 else
2441 ifsta->flags &= ~IEEE80211_STA_SSID_SET;
4071 2442
4072 rcu_read_lock(); 2443 if (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
4073 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 2444 !(ifsta->flags & IEEE80211_STA_BSSID_SET)) {
4074 netif_stop_queue(sdata->dev); 2445 ifsta->ibss_join_req = jiffies;
4075 if (sdata->vif.type == IEEE80211_IF_TYPE_STA && 2446 ifsta->state = IEEE80211_STA_MLME_IBSS_SEARCH;
4076 (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED)) 2447 return ieee80211_sta_find_ibss(sdata, ifsta);
4077 ieee80211_send_nullfunc(local, sdata, 1);
4078 } 2448 }
4079 rcu_read_unlock();
4080
4081 if (ssid) {
4082 local->scan_ssid_len = ssid_len;
4083 memcpy(local->scan_ssid, ssid, ssid_len);
4084 } else
4085 local->scan_ssid_len = 0;
4086 local->scan_state = SCAN_SET_CHANNEL;
4087 local->scan_channel_idx = 0;
4088 local->scan_band = IEEE80211_BAND_2GHZ;
4089 local->scan_dev = dev;
4090
4091 netif_addr_lock_bh(local->mdev);
4092 local->filter_flags |= FIF_BCN_PRBRESP_PROMISC;
4093 local->ops->configure_filter(local_to_hw(local),
4094 FIF_BCN_PRBRESP_PROMISC,
4095 &local->filter_flags,
4096 local->mdev->mc_count,
4097 local->mdev->mc_list);
4098 netif_addr_unlock_bh(local->mdev);
4099
4100 /* TODO: start scan as soon as all nullfunc frames are ACKed */
4101 queue_delayed_work(local->hw.workqueue, &local->scan_work,
4102 IEEE80211_CHANNEL_TIME);
4103 2449
4104 return 0; 2450 return 0;
4105} 2451}
4106 2452
4107 2453int ieee80211_sta_get_ssid(struct ieee80211_sub_if_data *sdata, char *ssid, size_t *len)
4108int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len)
4109{ 2454{
4110 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
4111 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 2455 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
4112 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 2456 memcpy(ssid, ifsta->ssid, ifsta->ssid_len);
4113 2457 *len = ifsta->ssid_len;
4114 if (sdata->vif.type != IEEE80211_IF_TYPE_STA)
4115 return ieee80211_sta_start_scan(dev, ssid, ssid_len);
4116
4117 if (local->sta_sw_scanning || local->sta_hw_scanning) {
4118 if (local->scan_dev == dev)
4119 return 0;
4120 return -EBUSY;
4121 }
4122
4123 ifsta->scan_ssid_len = ssid_len;
4124 if (ssid_len)
4125 memcpy(ifsta->scan_ssid, ssid, ssid_len);
4126 set_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request);
4127 queue_work(local->hw.workqueue, &ifsta->work);
4128 return 0; 2458 return 0;
4129} 2459}
4130 2460
4131static char * 2461int ieee80211_sta_set_bssid(struct ieee80211_sub_if_data *sdata, u8 *bssid)
4132ieee80211_sta_scan_result(struct net_device *dev,
4133 struct iw_request_info *info,
4134 struct ieee80211_sta_bss *bss,
4135 char *current_ev, char *end_buf)
4136{ 2462{
4137 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 2463 struct ieee80211_if_sta *ifsta;
4138 struct iw_event iwe; 2464 int res;
4139
4140 if (time_after(jiffies,
4141 bss->last_update + IEEE80211_SCAN_RESULT_EXPIRE))
4142 return current_ev;
4143
4144 memset(&iwe, 0, sizeof(iwe));
4145 iwe.cmd = SIOCGIWAP;
4146 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
4147 memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
4148 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
4149 IW_EV_ADDR_LEN);
4150
4151 memset(&iwe, 0, sizeof(iwe));
4152 iwe.cmd = SIOCGIWESSID;
4153 if (bss_mesh_cfg(bss)) {
4154 iwe.u.data.length = bss_mesh_id_len(bss);
4155 iwe.u.data.flags = 1;
4156 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4157 &iwe, bss_mesh_id(bss));
4158 } else {
4159 iwe.u.data.length = bss->ssid_len;
4160 iwe.u.data.flags = 1;
4161 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4162 &iwe, bss->ssid);
4163 }
4164
4165 if (bss->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)
4166 || bss_mesh_cfg(bss)) {
4167 memset(&iwe, 0, sizeof(iwe));
4168 iwe.cmd = SIOCGIWMODE;
4169 if (bss_mesh_cfg(bss))
4170 iwe.u.mode = IW_MODE_MESH;
4171 else if (bss->capability & WLAN_CAPABILITY_ESS)
4172 iwe.u.mode = IW_MODE_MASTER;
4173 else
4174 iwe.u.mode = IW_MODE_ADHOC;
4175 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
4176 &iwe, IW_EV_UINT_LEN);
4177 }
4178
4179 memset(&iwe, 0, sizeof(iwe));
4180 iwe.cmd = SIOCGIWFREQ;
4181 iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq);
4182 iwe.u.freq.e = 0;
4183 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
4184 IW_EV_FREQ_LEN);
4185
4186 memset(&iwe, 0, sizeof(iwe));
4187 iwe.cmd = SIOCGIWFREQ;
4188 iwe.u.freq.m = bss->freq;
4189 iwe.u.freq.e = 6;
4190 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
4191 IW_EV_FREQ_LEN);
4192 memset(&iwe, 0, sizeof(iwe));
4193 iwe.cmd = IWEVQUAL;
4194 iwe.u.qual.qual = bss->qual;
4195 iwe.u.qual.level = bss->signal;
4196 iwe.u.qual.noise = bss->noise;
4197 iwe.u.qual.updated = local->wstats_flags;
4198 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
4199 IW_EV_QUAL_LEN);
4200
4201 memset(&iwe, 0, sizeof(iwe));
4202 iwe.cmd = SIOCGIWENCODE;
4203 if (bss->capability & WLAN_CAPABILITY_PRIVACY)
4204 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
4205 else
4206 iwe.u.data.flags = IW_ENCODE_DISABLED;
4207 iwe.u.data.length = 0;
4208 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4209 &iwe, "");
4210
4211 if (bss && bss->wpa_ie) {
4212 memset(&iwe, 0, sizeof(iwe));
4213 iwe.cmd = IWEVGENIE;
4214 iwe.u.data.length = bss->wpa_ie_len;
4215 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4216 &iwe, bss->wpa_ie);
4217 }
4218
4219 if (bss && bss->rsn_ie) {
4220 memset(&iwe, 0, sizeof(iwe));
4221 iwe.cmd = IWEVGENIE;
4222 iwe.u.data.length = bss->rsn_ie_len;
4223 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4224 &iwe, bss->rsn_ie);
4225 }
4226
4227 if (bss && bss->ht_ie) {
4228 memset(&iwe, 0, sizeof(iwe));
4229 iwe.cmd = IWEVGENIE;
4230 iwe.u.data.length = bss->ht_ie_len;
4231 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4232 &iwe, bss->ht_ie);
4233 }
4234
4235 if (bss && bss->supp_rates_len > 0) {
4236 /* display all supported rates in readable format */
4237 char *p = current_ev + iwe_stream_lcp_len(info);
4238 int i;
4239
4240 memset(&iwe, 0, sizeof(iwe));
4241 iwe.cmd = SIOCGIWRATE;
4242 /* Those two flags are ignored... */
4243 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
4244
4245 for (i = 0; i < bss->supp_rates_len; i++) {
4246 iwe.u.bitrate.value = ((bss->supp_rates[i] &
4247 0x7f) * 500000);
4248 p = iwe_stream_add_value(info, current_ev, p,
4249 end_buf, &iwe, IW_EV_PARAM_LEN);
4250 }
4251 current_ev = p;
4252 }
4253 2465
4254 if (bss) { 2466 ifsta = &sdata->u.sta;
4255 char *buf;
4256 buf = kmalloc(30, GFP_ATOMIC);
4257 if (buf) {
4258 memset(&iwe, 0, sizeof(iwe));
4259 iwe.cmd = IWEVCUSTOM;
4260 sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->timestamp));
4261 iwe.u.data.length = strlen(buf);
4262 current_ev = iwe_stream_add_point(info, current_ev,
4263 end_buf,
4264 &iwe, buf);
4265 memset(&iwe, 0, sizeof(iwe));
4266 iwe.cmd = IWEVCUSTOM;
4267 sprintf(buf, " Last beacon: %dms ago",
4268 jiffies_to_msecs(jiffies - bss->last_update));
4269 iwe.u.data.length = strlen(buf);
4270 current_ev = iwe_stream_add_point(info, current_ev,
4271 end_buf, &iwe, buf);
4272 kfree(buf);
4273 }
4274 }
4275 2467
4276 if (bss_mesh_cfg(bss)) { 2468 if (memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) {
4277 char *buf; 2469 memcpy(ifsta->bssid, bssid, ETH_ALEN);
4278 u8 *cfg = bss_mesh_cfg(bss); 2470 res = 0;
4279 buf = kmalloc(50, GFP_ATOMIC); 2471 /*
4280 if (buf) { 2472 * Hack! See also ieee80211_sta_set_ssid.
4281 memset(&iwe, 0, sizeof(iwe)); 2473 */
4282 iwe.cmd = IWEVCUSTOM; 2474 if (netif_running(sdata->dev))
4283 sprintf(buf, "Mesh network (version %d)", cfg[0]); 2475 res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
4284 iwe.u.data.length = strlen(buf); 2476 if (res) {
4285 current_ev = iwe_stream_add_point(info, current_ev, 2477 printk(KERN_DEBUG "%s: Failed to config new BSSID to "
4286 end_buf, 2478 "the low-level driver\n", sdata->dev->name);
4287 &iwe, buf); 2479 return res;
4288 sprintf(buf, "Path Selection Protocol ID: "
4289 "0x%02X%02X%02X%02X", cfg[1], cfg[2], cfg[3],
4290 cfg[4]);
4291 iwe.u.data.length = strlen(buf);
4292 current_ev = iwe_stream_add_point(info, current_ev,
4293 end_buf,
4294 &iwe, buf);
4295 sprintf(buf, "Path Selection Metric ID: "
4296 "0x%02X%02X%02X%02X", cfg[5], cfg[6], cfg[7],
4297 cfg[8]);
4298 iwe.u.data.length = strlen(buf);
4299 current_ev = iwe_stream_add_point(info, current_ev,
4300 end_buf,
4301 &iwe, buf);
4302 sprintf(buf, "Congestion Control Mode ID: "
4303 "0x%02X%02X%02X%02X", cfg[9], cfg[10],
4304 cfg[11], cfg[12]);
4305 iwe.u.data.length = strlen(buf);
4306 current_ev = iwe_stream_add_point(info, current_ev,
4307 end_buf,
4308 &iwe, buf);
4309 sprintf(buf, "Channel Precedence: "
4310 "0x%02X%02X%02X%02X", cfg[13], cfg[14],
4311 cfg[15], cfg[16]);
4312 iwe.u.data.length = strlen(buf);
4313 current_ev = iwe_stream_add_point(info, current_ev,
4314 end_buf,
4315 &iwe, buf);
4316 kfree(buf);
4317 } 2480 }
4318 } 2481 }
4319 2482
4320 return current_ev; 2483 if (is_valid_ether_addr(bssid))
4321} 2484 ifsta->flags |= IEEE80211_STA_BSSID_SET;
4322 2485 else
2486 ifsta->flags &= ~IEEE80211_STA_BSSID_SET;
4323 2487
4324int ieee80211_sta_scan_results(struct net_device *dev, 2488 return 0;
4325 struct iw_request_info *info,
4326 char *buf, size_t len)
4327{
4328 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
4329 char *current_ev = buf;
4330 char *end_buf = buf + len;
4331 struct ieee80211_sta_bss *bss;
4332
4333 spin_lock_bh(&local->sta_bss_lock);
4334 list_for_each_entry(bss, &local->sta_bss_list, list) {
4335 if (buf + len - current_ev <= IW_EV_ADDR_LEN) {
4336 spin_unlock_bh(&local->sta_bss_lock);
4337 return -E2BIG;
4338 }
4339 current_ev = ieee80211_sta_scan_result(dev, info, bss,
4340 current_ev, end_buf);
4341 }
4342 spin_unlock_bh(&local->sta_bss_lock);
4343 return current_ev - buf;
4344} 2489}
4345 2490
4346 2491int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata, char *ie, size_t len)
4347int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len)
4348{ 2492{
4349 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
4350 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 2493 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
4351 2494
4352 kfree(ifsta->extra_ie); 2495 kfree(ifsta->extra_ie);
@@ -4365,92 +2508,60 @@ int ieee80211_sta_set_extra_ie(struct net_device *dev, char *ie, size_t len)
4365 return 0; 2508 return 0;
4366} 2509}
4367 2510
4368 2511int ieee80211_sta_deauthenticate(struct ieee80211_sub_if_data *sdata, u16 reason)
4369struct sta_info *ieee80211_ibss_add_sta(struct net_device *dev,
4370 struct sk_buff *skb, u8 *bssid,
4371 u8 *addr, u64 supp_rates)
4372{
4373 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
4374 struct sta_info *sta;
4375 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
4376 DECLARE_MAC_BUF(mac);
4377 int band = local->hw.conf.channel->band;
4378
4379 /* TODO: Could consider removing the least recently used entry and
4380 * allow new one to be added. */
4381 if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) {
4382 if (net_ratelimit()) {
4383 printk(KERN_DEBUG "%s: No room for a new IBSS STA "
4384 "entry %s\n", dev->name, print_mac(mac, addr));
4385 }
4386 return NULL;
4387 }
4388
4389 if (compare_ether_addr(bssid, sdata->u.sta.bssid))
4390 return NULL;
4391
4392#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
4393 printk(KERN_DEBUG "%s: Adding new IBSS station %s (dev=%s)\n",
4394 wiphy_name(local->hw.wiphy), print_mac(mac, addr), dev->name);
4395#endif
4396
4397 sta = sta_info_alloc(sdata, addr, GFP_ATOMIC);
4398 if (!sta)
4399 return NULL;
4400
4401 set_sta_flags(sta, WLAN_STA_AUTHORIZED);
4402
4403 if (supp_rates)
4404 sta->supp_rates[band] = supp_rates;
4405 else
4406 sta->supp_rates[band] = sdata->u.sta.supp_rates_bits[band];
4407
4408 rate_control_rate_init(sta, local);
4409
4410 if (sta_info_insert(sta))
4411 return NULL;
4412
4413 return sta;
4414}
4415
4416
4417int ieee80211_sta_deauthenticate(struct net_device *dev, u16 reason)
4418{ 2512{
4419 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
4420 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 2513 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
4421 2514
4422 printk(KERN_DEBUG "%s: deauthenticating by local choice (reason=%d)\n", 2515 printk(KERN_DEBUG "%s: deauthenticating by local choice (reason=%d)\n",
4423 dev->name, reason); 2516 sdata->dev->name, reason);
4424 2517
4425 if (sdata->vif.type != IEEE80211_IF_TYPE_STA && 2518 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
4426 sdata->vif.type != IEEE80211_IF_TYPE_IBSS) 2519 sdata->vif.type != NL80211_IFTYPE_ADHOC)
4427 return -EINVAL; 2520 return -EINVAL;
4428 2521
4429 ieee80211_send_deauth(dev, ifsta, reason); 2522 ieee80211_set_disassoc(sdata, ifsta, true, true, reason);
4430 ieee80211_set_disassoc(dev, ifsta, 1);
4431 return 0; 2523 return 0;
4432} 2524}
4433 2525
4434 2526int ieee80211_sta_disassociate(struct ieee80211_sub_if_data *sdata, u16 reason)
4435int ieee80211_sta_disassociate(struct net_device *dev, u16 reason)
4436{ 2527{
4437 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
4438 struct ieee80211_if_sta *ifsta = &sdata->u.sta; 2528 struct ieee80211_if_sta *ifsta = &sdata->u.sta;
4439 2529
4440 printk(KERN_DEBUG "%s: disassociating by local choice (reason=%d)\n", 2530 printk(KERN_DEBUG "%s: disassociating by local choice (reason=%d)\n",
4441 dev->name, reason); 2531 sdata->dev->name, reason);
4442 2532
4443 if (sdata->vif.type != IEEE80211_IF_TYPE_STA) 2533 if (sdata->vif.type != NL80211_IFTYPE_STATION)
4444 return -EINVAL; 2534 return -EINVAL;
4445 2535
4446 if (!(ifsta->flags & IEEE80211_STA_ASSOCIATED)) 2536 if (!(ifsta->flags & IEEE80211_STA_ASSOCIATED))
4447 return -1; 2537 return -1;
4448 2538
4449 ieee80211_send_disassoc(dev, ifsta, reason); 2539 ieee80211_set_disassoc(sdata, ifsta, false, true, reason);
4450 ieee80211_set_disassoc(dev, ifsta, 0);
4451 return 0; 2540 return 0;
4452} 2541}
4453 2542
2543/* scan finished notification */
2544void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local)
2545{
2546 struct ieee80211_sub_if_data *sdata = local->scan_sdata;
2547 struct ieee80211_if_sta *ifsta;
2548
2549 if (sdata && sdata->vif.type == NL80211_IFTYPE_ADHOC) {
2550 ifsta = &sdata->u.sta;
2551 if (!(ifsta->flags & IEEE80211_STA_BSSID_SET) ||
2552 (!(ifsta->state == IEEE80211_STA_MLME_IBSS_JOINED) &&
2553 !ieee80211_sta_active_ibss(sdata)))
2554 ieee80211_sta_find_ibss(sdata, ifsta);
2555 }
2556
2557 /* Restart STA timers */
2558 rcu_read_lock();
2559 list_for_each_entry_rcu(sdata, &local->interfaces, list)
2560 ieee80211_restart_sta_timer(sdata);
2561 rcu_read_unlock();
2562}
2563
2564/* driver notification call */
4454void ieee80211_notify_mac(struct ieee80211_hw *hw, 2565void ieee80211_notify_mac(struct ieee80211_hw *hw,
4455 enum ieee80211_notification_types notif_type) 2566 enum ieee80211_notification_types notif_type)
4456{ 2567{
@@ -4461,10 +2572,10 @@ void ieee80211_notify_mac(struct ieee80211_hw *hw,
4461 case IEEE80211_NOTIFY_RE_ASSOC: 2572 case IEEE80211_NOTIFY_RE_ASSOC:
4462 rcu_read_lock(); 2573 rcu_read_lock();
4463 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 2574 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
4464 if (sdata->vif.type != IEEE80211_IF_TYPE_STA) 2575 if (sdata->vif.type != NL80211_IFTYPE_STATION)
4465 continue; 2576 continue;
4466 2577
4467 ieee80211_sta_req_auth(sdata->dev, &sdata->u.sta); 2578 ieee80211_sta_req_auth(sdata, &sdata->u.sta);
4468 } 2579 }
4469 rcu_read_unlock(); 2580 rcu_read_unlock();
4470 break; 2581 break;
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 0388c090dfe..5d786720d93 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 ede7ab56f65..d0092f847f8 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 00000000000..f6d69dab07a
--- /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 00000000000..9a90a6aee04
--- /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 00000000000..0b024cd6b80
--- /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 0a9135b974b..01d64d53f3b 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 a914ba73ccf..86eb374e3b8 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 6db85450519..cf6b121e1bb 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,8 @@ 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 1382#ifdef CONFIG_MAC80211_MESH
1383static ieee80211_rx_result
1391ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) 1384ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
1392{ 1385{
1393 struct ieee80211_hdr *hdr; 1386 struct ieee80211_hdr *hdr;
@@ -1406,6 +1399,25 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
1406 /* illegal frame */ 1399 /* illegal frame */
1407 return RX_DROP_MONITOR; 1400 return RX_DROP_MONITOR;
1408 1401
1402 if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6){
1403 struct ieee80211_sub_if_data *sdata;
1404 struct mesh_path *mppath;
1405
1406 sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
1407 rcu_read_lock();
1408 mppath = mpp_path_lookup(mesh_hdr->eaddr2, sdata);
1409 if (!mppath) {
1410 mpp_path_add(mesh_hdr->eaddr2, hdr->addr4, sdata);
1411 } else {
1412 spin_lock_bh(&mppath->state_lock);
1413 mppath->exp_time = jiffies;
1414 if (compare_ether_addr(mppath->mpp, hdr->addr4) != 0)
1415 memcpy(mppath->mpp, hdr->addr4, ETH_ALEN);
1416 spin_unlock_bh(&mppath->state_lock);
1417 }
1418 rcu_read_unlock();
1419 }
1420
1409 if (compare_ether_addr(rx->dev->dev_addr, hdr->addr3) == 0) 1421 if (compare_ether_addr(rx->dev->dev_addr, hdr->addr3) == 0)
1410 return RX_CONTINUE; 1422 return RX_CONTINUE;
1411 1423
@@ -1413,7 +1425,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
1413 1425
1414 if (rx->flags & IEEE80211_RX_RA_MATCH) { 1426 if (rx->flags & IEEE80211_RX_RA_MATCH) {
1415 if (!mesh_hdr->ttl) 1427 if (!mesh_hdr->ttl)
1416 IEEE80211_IFSTA_MESH_CTR_INC(&rx->sdata->u.sta, 1428 IEEE80211_IFSTA_MESH_CTR_INC(&rx->sdata->u.mesh,
1417 dropped_frames_ttl); 1429 dropped_frames_ttl);
1418 else { 1430 else {
1419 struct ieee80211_hdr *fwd_hdr; 1431 struct ieee80211_hdr *fwd_hdr;
@@ -1442,27 +1454,27 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
1442 else 1454 else
1443 return RX_DROP_MONITOR; 1455 return RX_DROP_MONITOR;
1444} 1456}
1445 1457#endif
1446 1458
1447static ieee80211_rx_result debug_noinline 1459static ieee80211_rx_result debug_noinline
1448ieee80211_rx_h_data(struct ieee80211_rx_data *rx) 1460ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
1449{ 1461{
1450 struct net_device *dev = rx->dev; 1462 struct net_device *dev = rx->dev;
1451 u16 fc; 1463 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;
1464 __le16 fc = hdr->frame_control;
1452 int err; 1465 int err;
1453 1466
1454 fc = rx->fc; 1467 if (unlikely(!ieee80211_is_data(hdr->frame_control)))
1455 if (unlikely((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA))
1456 return RX_CONTINUE; 1468 return RX_CONTINUE;
1457 1469
1458 if (unlikely(!WLAN_FC_DATA_PRESENT(fc))) 1470 if (unlikely(!ieee80211_is_data_present(hdr->frame_control)))
1459 return RX_DROP_MONITOR; 1471 return RX_DROP_MONITOR;
1460 1472
1461 err = ieee80211_data_to_8023(rx); 1473 err = ieee80211_data_to_8023(rx);
1462 if (unlikely(err)) 1474 if (unlikely(err))
1463 return RX_DROP_UNUSABLE; 1475 return RX_DROP_UNUSABLE;
1464 1476
1465 if (!ieee80211_frame_allowed(rx)) 1477 if (!ieee80211_frame_allowed(rx, fc))
1466 return RX_DROP_MONITOR; 1478 return RX_DROP_MONITOR;
1467 1479
1468 rx->skb->dev = dev; 1480 rx->skb->dev = dev;
@@ -1520,22 +1532,97 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx)
1520} 1532}
1521 1533
1522static ieee80211_rx_result debug_noinline 1534static ieee80211_rx_result debug_noinline
1535ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
1536{
1537 struct ieee80211_local *local = rx->local;
1538 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
1539 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data;
1540 int len = rx->skb->len;
1541
1542 if (!ieee80211_is_action(mgmt->frame_control))
1543 return RX_CONTINUE;
1544
1545 if (!rx->sta)
1546 return RX_DROP_MONITOR;
1547
1548 if (!(rx->flags & IEEE80211_RX_RA_MATCH))
1549 return RX_DROP_MONITOR;
1550
1551 /* all categories we currently handle have action_code */
1552 if (len < IEEE80211_MIN_ACTION_SIZE + 1)
1553 return RX_DROP_MONITOR;
1554
1555 /*
1556 * FIXME: revisit this, I'm sure we should handle most
1557 * of these frames in other modes as well!
1558 */
1559 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
1560 sdata->vif.type != NL80211_IFTYPE_ADHOC)
1561 return RX_CONTINUE;
1562
1563 switch (mgmt->u.action.category) {
1564 case WLAN_CATEGORY_BACK:
1565 switch (mgmt->u.action.u.addba_req.action_code) {
1566 case WLAN_ACTION_ADDBA_REQ:
1567 if (len < (IEEE80211_MIN_ACTION_SIZE +
1568 sizeof(mgmt->u.action.u.addba_req)))
1569 return RX_DROP_MONITOR;
1570 ieee80211_process_addba_request(local, rx->sta, mgmt, len);
1571 break;
1572 case WLAN_ACTION_ADDBA_RESP:
1573 if (len < (IEEE80211_MIN_ACTION_SIZE +
1574 sizeof(mgmt->u.action.u.addba_resp)))
1575 return RX_DROP_MONITOR;
1576 ieee80211_process_addba_resp(local, rx->sta, mgmt, len);
1577 break;
1578 case WLAN_ACTION_DELBA:
1579 if (len < (IEEE80211_MIN_ACTION_SIZE +
1580 sizeof(mgmt->u.action.u.delba)))
1581 return RX_DROP_MONITOR;
1582 ieee80211_process_delba(sdata, rx->sta, mgmt, len);
1583 break;
1584 }
1585 break;
1586 case WLAN_CATEGORY_SPECTRUM_MGMT:
1587 if (local->hw.conf.channel->band != IEEE80211_BAND_5GHZ)
1588 return RX_DROP_MONITOR;
1589 switch (mgmt->u.action.u.measurement.action_code) {
1590 case WLAN_ACTION_SPCT_MSR_REQ:
1591 if (len < (IEEE80211_MIN_ACTION_SIZE +
1592 sizeof(mgmt->u.action.u.measurement)))
1593 return RX_DROP_MONITOR;
1594 ieee80211_process_measurement_req(sdata, mgmt, len);
1595 break;
1596 }
1597 break;
1598 default:
1599 return RX_CONTINUE;
1600 }
1601
1602 rx->sta->rx_packets++;
1603 dev_kfree_skb(rx->skb);
1604 return RX_QUEUED;
1605}
1606
1607static ieee80211_rx_result debug_noinline
1523ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) 1608ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
1524{ 1609{
1525 struct ieee80211_sub_if_data *sdata; 1610 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
1526 1611
1527 if (!(rx->flags & IEEE80211_RX_RA_MATCH)) 1612 if (!(rx->flags & IEEE80211_RX_RA_MATCH))
1528 return RX_DROP_MONITOR; 1613 return RX_DROP_MONITOR;
1529 1614
1530 sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); 1615 if (ieee80211_vif_is_mesh(&sdata->vif))
1531 if ((sdata->vif.type == IEEE80211_IF_TYPE_STA || 1616 return ieee80211_mesh_rx_mgmt(sdata, rx->skb, rx->status);
1532 sdata->vif.type == IEEE80211_IF_TYPE_IBSS || 1617
1533 sdata->vif.type == IEEE80211_IF_TYPE_MESH_POINT) && 1618 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
1534 !(sdata->flags & IEEE80211_SDATA_USERSPACE_MLME)) 1619 sdata->vif.type != NL80211_IFTYPE_ADHOC)
1535 ieee80211_sta_rx_mgmt(rx->dev, rx->skb, rx->status);
1536 else
1537 return RX_DROP_MONITOR; 1620 return RX_DROP_MONITOR;
1538 1621
1622 if (sdata->flags & IEEE80211_SDATA_USERSPACE_MLME)
1623 return RX_DROP_MONITOR;
1624
1625 ieee80211_sta_rx_mgmt(sdata, rx->skb, rx->status);
1539 return RX_QUEUED; 1626 return RX_QUEUED;
1540} 1627}
1541 1628
@@ -1565,7 +1652,7 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev,
1565 if (!ieee80211_has_protected(hdr->frame_control)) 1652 if (!ieee80211_has_protected(hdr->frame_control))
1566 goto ignore; 1653 goto ignore;
1567 1654
1568 if (rx->sdata->vif.type == IEEE80211_IF_TYPE_AP && keyidx) { 1655 if (rx->sdata->vif.type == NL80211_IFTYPE_AP && keyidx) {
1569 /* 1656 /*
1570 * APs with pairwise keys should never receive Michael MIC 1657 * APs with pairwise keys should never receive Michael MIC
1571 * errors for non-zero keyidx because these are reserved for 1658 * errors for non-zero keyidx because these are reserved for
@@ -1579,7 +1666,7 @@ static void ieee80211_rx_michael_mic_report(struct net_device *dev,
1579 !ieee80211_is_auth(hdr->frame_control)) 1666 !ieee80211_is_auth(hdr->frame_control))
1580 goto ignore; 1667 goto ignore;
1581 1668
1582 mac80211_ev_michael_mic_failure(rx->dev, keyidx, hdr); 1669 mac80211_ev_michael_mic_failure(rx->sdata, keyidx, hdr);
1583 ignore: 1670 ignore:
1584 dev_kfree_skb(rx->skb); 1671 dev_kfree_skb(rx->skb);
1585 rx->skb = NULL; 1672 rx->skb = NULL;
@@ -1635,7 +1722,7 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx)
1635 if (!netif_running(sdata->dev)) 1722 if (!netif_running(sdata->dev))
1636 continue; 1723 continue;
1637 1724
1638 if (sdata->vif.type != IEEE80211_IF_TYPE_MNTR || 1725 if (sdata->vif.type != NL80211_IFTYPE_MONITOR ||
1639 !(sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES)) 1726 !(sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES))
1640 continue; 1727 continue;
1641 1728
@@ -1694,10 +1781,13 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_sub_if_data *sdata,
1694 /* must be after MMIC verify so header is counted in MPDU mic */ 1781 /* must be after MMIC verify so header is counted in MPDU mic */
1695 CALL_RXH(ieee80211_rx_h_remove_qos_control) 1782 CALL_RXH(ieee80211_rx_h_remove_qos_control)
1696 CALL_RXH(ieee80211_rx_h_amsdu) 1783 CALL_RXH(ieee80211_rx_h_amsdu)
1784#ifdef CONFIG_MAC80211_MESH
1697 if (ieee80211_vif_is_mesh(&sdata->vif)) 1785 if (ieee80211_vif_is_mesh(&sdata->vif))
1698 CALL_RXH(ieee80211_rx_h_mesh_fwding); 1786 CALL_RXH(ieee80211_rx_h_mesh_fwding);
1787#endif
1699 CALL_RXH(ieee80211_rx_h_data) 1788 CALL_RXH(ieee80211_rx_h_data)
1700 CALL_RXH(ieee80211_rx_h_ctrl) 1789 CALL_RXH(ieee80211_rx_h_ctrl)
1790 CALL_RXH(ieee80211_rx_h_action)
1701 CALL_RXH(ieee80211_rx_h_mgmt) 1791 CALL_RXH(ieee80211_rx_h_mgmt)
1702 1792
1703#undef CALL_RXH 1793#undef CALL_RXH
@@ -1733,7 +1823,7 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
1733 int multicast = is_multicast_ether_addr(hdr->addr1); 1823 int multicast = is_multicast_ether_addr(hdr->addr1);
1734 1824
1735 switch (sdata->vif.type) { 1825 switch (sdata->vif.type) {
1736 case IEEE80211_IF_TYPE_STA: 1826 case NL80211_IFTYPE_STATION:
1737 if (!bssid) 1827 if (!bssid)
1738 return 0; 1828 return 0;
1739 if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) { 1829 if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) {
@@ -1748,14 +1838,10 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
1748 rx->flags &= ~IEEE80211_RX_RA_MATCH; 1838 rx->flags &= ~IEEE80211_RX_RA_MATCH;
1749 } 1839 }
1750 break; 1840 break;
1751 case IEEE80211_IF_TYPE_IBSS: 1841 case NL80211_IFTYPE_ADHOC:
1752 if (!bssid) 1842 if (!bssid)
1753 return 0; 1843 return 0;
1754 if (ieee80211_is_beacon(hdr->frame_control)) { 1844 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; 1845 return 1;
1760 } 1846 }
1761 else if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) { 1847 else if (!ieee80211_bssid_match(bssid, sdata->u.sta.bssid)) {
@@ -1769,11 +1855,11 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
1769 return 0; 1855 return 0;
1770 rx->flags &= ~IEEE80211_RX_RA_MATCH; 1856 rx->flags &= ~IEEE80211_RX_RA_MATCH;
1771 } else if (!rx->sta) 1857 } else if (!rx->sta)
1772 rx->sta = ieee80211_ibss_add_sta(sdata->dev, rx->skb, 1858 rx->sta = ieee80211_ibss_add_sta(sdata, rx->skb,
1773 bssid, hdr->addr2, 1859 bssid, hdr->addr2,
1774 BIT(rx->status->rate_idx)); 1860 BIT(rx->status->rate_idx));
1775 break; 1861 break;
1776 case IEEE80211_IF_TYPE_MESH_POINT: 1862 case NL80211_IFTYPE_MESH_POINT:
1777 if (!multicast && 1863 if (!multicast &&
1778 compare_ether_addr(sdata->dev->dev_addr, 1864 compare_ether_addr(sdata->dev->dev_addr,
1779 hdr->addr1) != 0) { 1865 hdr->addr1) != 0) {
@@ -1783,8 +1869,8 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
1783 rx->flags &= ~IEEE80211_RX_RA_MATCH; 1869 rx->flags &= ~IEEE80211_RX_RA_MATCH;
1784 } 1870 }
1785 break; 1871 break;
1786 case IEEE80211_IF_TYPE_VLAN: 1872 case NL80211_IFTYPE_AP_VLAN:
1787 case IEEE80211_IF_TYPE_AP: 1873 case NL80211_IFTYPE_AP:
1788 if (!bssid) { 1874 if (!bssid) {
1789 if (compare_ether_addr(sdata->dev->dev_addr, 1875 if (compare_ether_addr(sdata->dev->dev_addr,
1790 hdr->addr1)) 1876 hdr->addr1))
@@ -1796,16 +1882,17 @@ static int prepare_for_handlers(struct ieee80211_sub_if_data *sdata,
1796 rx->flags &= ~IEEE80211_RX_RA_MATCH; 1882 rx->flags &= ~IEEE80211_RX_RA_MATCH;
1797 } 1883 }
1798 break; 1884 break;
1799 case IEEE80211_IF_TYPE_WDS: 1885 case NL80211_IFTYPE_WDS:
1800 if (bssid || !ieee80211_is_data(hdr->frame_control)) 1886 if (bssid || !ieee80211_is_data(hdr->frame_control))
1801 return 0; 1887 return 0;
1802 if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2)) 1888 if (compare_ether_addr(sdata->u.wds.remote_addr, hdr->addr2))
1803 return 0; 1889 return 0;
1804 break; 1890 break;
1805 case IEEE80211_IF_TYPE_MNTR: 1891 case NL80211_IFTYPE_MONITOR:
1806 /* take everything */ 1892 /* take everything */
1807 break; 1893 break;
1808 case IEEE80211_IF_TYPE_INVALID: 1894 case NL80211_IFTYPE_UNSPECIFIED:
1895 case __NL80211_IFTYPE_AFTER_LAST:
1809 /* should never get here */ 1896 /* should never get here */
1810 WARN_ON(1); 1897 WARN_ON(1);
1811 break; 1898 break;
@@ -1827,23 +1914,20 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
1827 struct ieee80211_sub_if_data *sdata; 1914 struct ieee80211_sub_if_data *sdata;
1828 struct ieee80211_hdr *hdr; 1915 struct ieee80211_hdr *hdr;
1829 struct ieee80211_rx_data rx; 1916 struct ieee80211_rx_data rx;
1830 u16 type;
1831 int prepares; 1917 int prepares;
1832 struct ieee80211_sub_if_data *prev = NULL; 1918 struct ieee80211_sub_if_data *prev = NULL;
1833 struct sk_buff *skb_new; 1919 struct sk_buff *skb_new;
1834 u8 *bssid; 1920 u8 *bssid;
1835 1921
1836 hdr = (struct ieee80211_hdr *) skb->data; 1922 hdr = (struct ieee80211_hdr *)skb->data;
1837 memset(&rx, 0, sizeof(rx)); 1923 memset(&rx, 0, sizeof(rx));
1838 rx.skb = skb; 1924 rx.skb = skb;
1839 rx.local = local; 1925 rx.local = local;
1840 1926
1841 rx.status = status; 1927 rx.status = status;
1842 rx.rate = rate; 1928 rx.rate = rate;
1843 rx.fc = le16_to_cpu(hdr->frame_control);
1844 type = rx.fc & IEEE80211_FCTL_FTYPE;
1845 1929
1846 if (type == IEEE80211_FTYPE_DATA || type == IEEE80211_FTYPE_MGMT) 1930 if (ieee80211_is_data(hdr->frame_control) || ieee80211_is_mgmt(hdr->frame_control))
1847 local->dot11ReceivedFragmentCount++; 1931 local->dot11ReceivedFragmentCount++;
1848 1932
1849 rx.sta = sta_info_get(local, hdr->addr2); 1933 rx.sta = sta_info_get(local, hdr->addr2);
@@ -1857,7 +1941,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
1857 return; 1941 return;
1858 } 1942 }
1859 1943
1860 if (unlikely(local->sta_sw_scanning || local->sta_hw_scanning)) 1944 if (unlikely(local->sw_scanning || local->hw_scanning))
1861 rx.flags |= IEEE80211_RX_IN_SCAN; 1945 rx.flags |= IEEE80211_RX_IN_SCAN;
1862 1946
1863 ieee80211_parse_qos(&rx); 1947 ieee80211_parse_qos(&rx);
@@ -1869,7 +1953,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
1869 if (!netif_running(sdata->dev)) 1953 if (!netif_running(sdata->dev))
1870 continue; 1954 continue;
1871 1955
1872 if (sdata->vif.type == IEEE80211_IF_TYPE_MNTR) 1956 if (sdata->vif.type == NL80211_IFTYPE_MONITOR)
1873 continue; 1957 continue;
1874 1958
1875 bssid = ieee80211_get_bssid(hdr, skb->len, sdata->vif.type); 1959 bssid = ieee80211_get_bssid(hdr, skb->len, sdata->vif.type);
@@ -1904,14 +1988,12 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
1904 prev->dev->name); 1988 prev->dev->name);
1905 continue; 1989 continue;
1906 } 1990 }
1907 rx.fc = le16_to_cpu(hdr->frame_control);
1908 ieee80211_invoke_rx_handlers(prev, &rx, skb_new); 1991 ieee80211_invoke_rx_handlers(prev, &rx, skb_new);
1909 prev = sdata; 1992 prev = sdata;
1910 } 1993 }
1911 if (prev) { 1994 if (prev)
1912 rx.fc = le16_to_cpu(hdr->frame_control);
1913 ieee80211_invoke_rx_handlers(prev, &rx, skb); 1995 ieee80211_invoke_rx_handlers(prev, &rx, skb);
1914 } else 1996 else
1915 dev_kfree_skb(skb); 1997 dev_kfree_skb(skb);
1916} 1998}
1917 1999
@@ -2080,7 +2162,7 @@ static u8 ieee80211_rx_reorder_ampdu(struct ieee80211_local *local,
2080 /* if this mpdu is fragmented - terminate rx aggregation session */ 2162 /* if this mpdu is fragmented - terminate rx aggregation session */
2081 sc = le16_to_cpu(hdr->seq_ctrl); 2163 sc = le16_to_cpu(hdr->seq_ctrl);
2082 if (sc & IEEE80211_SCTL_FRAG) { 2164 if (sc & IEEE80211_SCTL_FRAG) {
2083 ieee80211_sta_stop_rx_ba_session(sta->sdata->dev, sta->addr, 2165 ieee80211_sta_stop_rx_ba_session(sta->sdata, sta->sta.addr,
2084 tid, 0, WLAN_REASON_QSTA_REQUIRE_SETUP); 2166 tid, 0, WLAN_REASON_QSTA_REQUIRE_SETUP);
2085 ret = 1; 2167 ret = 1;
2086 goto end_reorder; 2168 goto end_reorder;
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
new file mode 100644
index 00000000000..416bb41099f
--- /dev/null
+++ b/net/mac80211/scan.c
@@ -0,0 +1,938 @@
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 if (bss)
392 ieee80211_rx_bss_put(sdata->local, bss);
393
394 dev_kfree_skb(skb);
395 return RX_QUEUED;
396}
397
398static void ieee80211_send_nullfunc(struct ieee80211_local *local,
399 struct ieee80211_sub_if_data *sdata,
400 int powersave)
401{
402 struct sk_buff *skb;
403 struct ieee80211_hdr *nullfunc;
404 __le16 fc;
405
406 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24);
407 if (!skb) {
408 printk(KERN_DEBUG "%s: failed to allocate buffer for nullfunc "
409 "frame\n", sdata->dev->name);
410 return;
411 }
412 skb_reserve(skb, local->hw.extra_tx_headroom);
413
414 nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24);
415 memset(nullfunc, 0, 24);
416 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
417 IEEE80211_FCTL_TODS);
418 if (powersave)
419 fc |= cpu_to_le16(IEEE80211_FCTL_PM);
420 nullfunc->frame_control = fc;
421 memcpy(nullfunc->addr1, sdata->u.sta.bssid, ETH_ALEN);
422 memcpy(nullfunc->addr2, sdata->dev->dev_addr, ETH_ALEN);
423 memcpy(nullfunc->addr3, sdata->u.sta.bssid, ETH_ALEN);
424
425 ieee80211_tx_skb(sdata, skb, 0);
426}
427
428void ieee80211_scan_completed(struct ieee80211_hw *hw)
429{
430 struct ieee80211_local *local = hw_to_local(hw);
431 struct ieee80211_sub_if_data *sdata;
432 union iwreq_data wrqu;
433
434 if (WARN_ON(!local->hw_scanning && !local->sw_scanning))
435 return;
436
437 local->last_scan_completed = jiffies;
438 memset(&wrqu, 0, sizeof(wrqu));
439
440 /*
441 * local->scan_sdata could have been NULLed by the interface
442 * down code in case we were scanning on an interface that is
443 * being taken down.
444 */
445 sdata = local->scan_sdata;
446 if (sdata)
447 wireless_send_event(sdata->dev, SIOCGIWSCAN, &wrqu, NULL);
448
449 if (local->hw_scanning) {
450 local->hw_scanning = false;
451 if (ieee80211_hw_config(local))
452 printk(KERN_DEBUG "%s: failed to restore operational "
453 "channel after scan\n", wiphy_name(local->hw.wiphy));
454
455 goto done;
456 }
457
458 local->sw_scanning = false;
459 if (ieee80211_hw_config(local))
460 printk(KERN_DEBUG "%s: failed to restore operational "
461 "channel after scan\n", wiphy_name(local->hw.wiphy));
462
463
464 netif_tx_lock_bh(local->mdev);
465 netif_addr_lock(local->mdev);
466 local->filter_flags &= ~FIF_BCN_PRBRESP_PROMISC;
467 local->ops->configure_filter(local_to_hw(local),
468 FIF_BCN_PRBRESP_PROMISC,
469 &local->filter_flags,
470 local->mdev->mc_count,
471 local->mdev->mc_list);
472
473 netif_addr_unlock(local->mdev);
474 netif_tx_unlock_bh(local->mdev);
475
476 rcu_read_lock();
477 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
478 /* Tell AP we're back */
479 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
480 if (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED) {
481 ieee80211_send_nullfunc(local, sdata, 0);
482 netif_tx_wake_all_queues(sdata->dev);
483 }
484 } else
485 netif_tx_wake_all_queues(sdata->dev);
486 }
487 rcu_read_unlock();
488
489 done:
490 ieee80211_mlme_notify_scan_completed(local);
491 ieee80211_mesh_notify_scan_completed(local);
492}
493EXPORT_SYMBOL(ieee80211_scan_completed);
494
495
496void ieee80211_scan_work(struct work_struct *work)
497{
498 struct ieee80211_local *local =
499 container_of(work, struct ieee80211_local, scan_work.work);
500 struct ieee80211_sub_if_data *sdata = local->scan_sdata;
501 struct ieee80211_supported_band *sband;
502 struct ieee80211_channel *chan;
503 int skip;
504 unsigned long next_delay = 0;
505
506 /*
507 * Avoid re-scheduling when the sdata is going away.
508 */
509 if (!netif_running(sdata->dev))
510 return;
511
512 switch (local->scan_state) {
513 case SCAN_SET_CHANNEL:
514 /*
515 * Get current scan band. scan_band may be IEEE80211_NUM_BANDS
516 * after we successfully scanned the last channel of the last
517 * band (and the last band is supported by the hw)
518 */
519 if (local->scan_band < IEEE80211_NUM_BANDS)
520 sband = local->hw.wiphy->bands[local->scan_band];
521 else
522 sband = NULL;
523
524 /*
525 * If we are at an unsupported band and have more bands
526 * left to scan, advance to the next supported one.
527 */
528 while (!sband && local->scan_band < IEEE80211_NUM_BANDS - 1) {
529 local->scan_band++;
530 sband = local->hw.wiphy->bands[local->scan_band];
531 local->scan_channel_idx = 0;
532 }
533
534 /* if no more bands/channels left, complete scan */
535 if (!sband || local->scan_channel_idx >= sband->n_channels) {
536 ieee80211_scan_completed(local_to_hw(local));
537 return;
538 }
539 skip = 0;
540 chan = &sband->channels[local->scan_channel_idx];
541
542 if (chan->flags & IEEE80211_CHAN_DISABLED ||
543 (sdata->vif.type == NL80211_IFTYPE_ADHOC &&
544 chan->flags & IEEE80211_CHAN_NO_IBSS))
545 skip = 1;
546
547 if (!skip) {
548 local->scan_channel = chan;
549 if (ieee80211_hw_config(local)) {
550 printk(KERN_DEBUG "%s: failed to set freq to "
551 "%d MHz for scan\n", wiphy_name(local->hw.wiphy),
552 chan->center_freq);
553 skip = 1;
554 }
555 }
556
557 /* advance state machine to next channel/band */
558 local->scan_channel_idx++;
559 if (local->scan_channel_idx >= sband->n_channels) {
560 /*
561 * scan_band may end up == IEEE80211_NUM_BANDS, but
562 * we'll catch that case above and complete the scan
563 * if that is the case.
564 */
565 local->scan_band++;
566 local->scan_channel_idx = 0;
567 }
568
569 if (skip)
570 break;
571
572 next_delay = IEEE80211_PROBE_DELAY +
573 usecs_to_jiffies(local->hw.channel_change_time);
574 local->scan_state = SCAN_SEND_PROBE;
575 break;
576 case SCAN_SEND_PROBE:
577 next_delay = IEEE80211_PASSIVE_CHANNEL_TIME;
578 local->scan_state = SCAN_SET_CHANNEL;
579
580 if (local->scan_channel->flags & IEEE80211_CHAN_PASSIVE_SCAN)
581 break;
582 ieee80211_send_probe_req(sdata, NULL, local->scan_ssid,
583 local->scan_ssid_len);
584 next_delay = IEEE80211_CHANNEL_TIME;
585 break;
586 }
587
588 queue_delayed_work(local->hw.workqueue, &local->scan_work,
589 next_delay);
590}
591
592
593int ieee80211_start_scan(struct ieee80211_sub_if_data *scan_sdata,
594 u8 *ssid, size_t ssid_len)
595{
596 struct ieee80211_local *local = scan_sdata->local;
597 struct ieee80211_sub_if_data *sdata;
598
599 if (ssid_len > IEEE80211_MAX_SSID_LEN)
600 return -EINVAL;
601
602 /* MLME-SCAN.request (page 118) page 144 (11.1.3.1)
603 * BSSType: INFRASTRUCTURE, INDEPENDENT, ANY_BSS
604 * BSSID: MACAddress
605 * SSID
606 * ScanType: ACTIVE, PASSIVE
607 * ProbeDelay: delay (in microseconds) to be used prior to transmitting
608 * a Probe frame during active scanning
609 * ChannelList
610 * MinChannelTime (>= ProbeDelay), in TU
611 * MaxChannelTime: (>= MinChannelTime), in TU
612 */
613
614 /* MLME-SCAN.confirm
615 * BSSDescriptionSet
616 * ResultCode: SUCCESS, INVALID_PARAMETERS
617 */
618
619 if (local->sw_scanning || local->hw_scanning) {
620 if (local->scan_sdata == scan_sdata)
621 return 0;
622 return -EBUSY;
623 }
624
625 if (local->ops->hw_scan) {
626 int rc;
627
628 local->hw_scanning = true;
629 rc = local->ops->hw_scan(local_to_hw(local), ssid, ssid_len);
630 if (rc) {
631 local->hw_scanning = false;
632 return rc;
633 }
634 local->scan_sdata = scan_sdata;
635 return 0;
636 }
637
638 local->sw_scanning = true;
639
640 rcu_read_lock();
641 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
642 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
643 if (sdata->u.sta.flags & IEEE80211_STA_ASSOCIATED) {
644 netif_tx_stop_all_queues(sdata->dev);
645 ieee80211_send_nullfunc(local, sdata, 1);
646 }
647 } else
648 netif_tx_stop_all_queues(sdata->dev);
649 }
650 rcu_read_unlock();
651
652 if (ssid) {
653 local->scan_ssid_len = ssid_len;
654 memcpy(local->scan_ssid, ssid, ssid_len);
655 } else
656 local->scan_ssid_len = 0;
657 local->scan_state = SCAN_SET_CHANNEL;
658 local->scan_channel_idx = 0;
659 local->scan_band = IEEE80211_BAND_2GHZ;
660 local->scan_sdata = scan_sdata;
661
662 netif_addr_lock_bh(local->mdev);
663 local->filter_flags |= FIF_BCN_PRBRESP_PROMISC;
664 local->ops->configure_filter(local_to_hw(local),
665 FIF_BCN_PRBRESP_PROMISC,
666 &local->filter_flags,
667 local->mdev->mc_count,
668 local->mdev->mc_list);
669 netif_addr_unlock_bh(local->mdev);
670
671 /* TODO: start scan as soon as all nullfunc frames are ACKed */
672 queue_delayed_work(local->hw.workqueue, &local->scan_work,
673 IEEE80211_CHANNEL_TIME);
674
675 return 0;
676}
677
678
679int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
680 u8 *ssid, size_t ssid_len)
681{
682 struct ieee80211_local *local = sdata->local;
683 struct ieee80211_if_sta *ifsta;
684
685 if (sdata->vif.type != NL80211_IFTYPE_STATION)
686 return ieee80211_start_scan(sdata, ssid, ssid_len);
687
688 /*
689 * STA has a state machine that might need to defer scanning
690 * while it's trying to associate/authenticate, therefore we
691 * queue it up to the state machine in that case.
692 */
693
694 if (local->sw_scanning || local->hw_scanning) {
695 if (local->scan_sdata == sdata)
696 return 0;
697 return -EBUSY;
698 }
699
700 ifsta = &sdata->u.sta;
701
702 ifsta->scan_ssid_len = ssid_len;
703 if (ssid_len)
704 memcpy(ifsta->scan_ssid, ssid, ssid_len);
705 set_bit(IEEE80211_STA_REQ_SCAN, &ifsta->request);
706 queue_work(local->hw.workqueue, &ifsta->work);
707
708 return 0;
709}
710
711
712static void ieee80211_scan_add_ies(struct iw_request_info *info,
713 struct ieee80211_bss *bss,
714 char **current_ev, char *end_buf)
715{
716 u8 *pos, *end, *next;
717 struct iw_event iwe;
718
719 if (bss == NULL || bss->ies == NULL)
720 return;
721
722 /*
723 * If needed, fragment the IEs buffer (at IE boundaries) into short
724 * enough fragments to fit into IW_GENERIC_IE_MAX octet messages.
725 */
726 pos = bss->ies;
727 end = pos + bss->ies_len;
728
729 while (end - pos > IW_GENERIC_IE_MAX) {
730 next = pos + 2 + pos[1];
731 while (next + 2 + next[1] - pos < IW_GENERIC_IE_MAX)
732 next = next + 2 + next[1];
733
734 memset(&iwe, 0, sizeof(iwe));
735 iwe.cmd = IWEVGENIE;
736 iwe.u.data.length = next - pos;
737 *current_ev = iwe_stream_add_point(info, *current_ev,
738 end_buf, &iwe, pos);
739
740 pos = next;
741 }
742
743 if (end > pos) {
744 memset(&iwe, 0, sizeof(iwe));
745 iwe.cmd = IWEVGENIE;
746 iwe.u.data.length = end - pos;
747 *current_ev = iwe_stream_add_point(info, *current_ev,
748 end_buf, &iwe, pos);
749 }
750}
751
752
753static char *
754ieee80211_scan_result(struct ieee80211_local *local,
755 struct iw_request_info *info,
756 struct ieee80211_bss *bss,
757 char *current_ev, char *end_buf)
758{
759 struct iw_event iwe;
760 char *buf;
761
762 if (time_after(jiffies,
763 bss->last_update + IEEE80211_SCAN_RESULT_EXPIRE))
764 return current_ev;
765
766 memset(&iwe, 0, sizeof(iwe));
767 iwe.cmd = SIOCGIWAP;
768 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
769 memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
770 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
771 IW_EV_ADDR_LEN);
772
773 memset(&iwe, 0, sizeof(iwe));
774 iwe.cmd = SIOCGIWESSID;
775 if (bss_mesh_cfg(bss)) {
776 iwe.u.data.length = bss_mesh_id_len(bss);
777 iwe.u.data.flags = 1;
778 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
779 &iwe, bss_mesh_id(bss));
780 } else {
781 iwe.u.data.length = bss->ssid_len;
782 iwe.u.data.flags = 1;
783 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
784 &iwe, bss->ssid);
785 }
786
787 if (bss->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)
788 || bss_mesh_cfg(bss)) {
789 memset(&iwe, 0, sizeof(iwe));
790 iwe.cmd = SIOCGIWMODE;
791 if (bss_mesh_cfg(bss))
792 iwe.u.mode = IW_MODE_MESH;
793 else if (bss->capability & WLAN_CAPABILITY_ESS)
794 iwe.u.mode = IW_MODE_MASTER;
795 else
796 iwe.u.mode = IW_MODE_ADHOC;
797 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
798 &iwe, IW_EV_UINT_LEN);
799 }
800
801 memset(&iwe, 0, sizeof(iwe));
802 iwe.cmd = SIOCGIWFREQ;
803 iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq);
804 iwe.u.freq.e = 0;
805 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
806 IW_EV_FREQ_LEN);
807
808 memset(&iwe, 0, sizeof(iwe));
809 iwe.cmd = SIOCGIWFREQ;
810 iwe.u.freq.m = bss->freq;
811 iwe.u.freq.e = 6;
812 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
813 IW_EV_FREQ_LEN);
814 memset(&iwe, 0, sizeof(iwe));
815 iwe.cmd = IWEVQUAL;
816 iwe.u.qual.qual = bss->qual;
817 iwe.u.qual.level = bss->signal;
818 iwe.u.qual.noise = bss->noise;
819 iwe.u.qual.updated = local->wstats_flags;
820 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
821 IW_EV_QUAL_LEN);
822
823 memset(&iwe, 0, sizeof(iwe));
824 iwe.cmd = SIOCGIWENCODE;
825 if (bss->capability & WLAN_CAPABILITY_PRIVACY)
826 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
827 else
828 iwe.u.data.flags = IW_ENCODE_DISABLED;
829 iwe.u.data.length = 0;
830 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
831 &iwe, "");
832
833 ieee80211_scan_add_ies(info, bss, &current_ev, end_buf);
834
835 if (bss->supp_rates_len > 0) {
836 /* display all supported rates in readable format */
837 char *p = current_ev + iwe_stream_lcp_len(info);
838 int i;
839
840 memset(&iwe, 0, sizeof(iwe));
841 iwe.cmd = SIOCGIWRATE;
842 /* Those two flags are ignored... */
843 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
844
845 for (i = 0; i < bss->supp_rates_len; i++) {
846 iwe.u.bitrate.value = ((bss->supp_rates[i] &
847 0x7f) * 500000);
848 p = iwe_stream_add_value(info, current_ev, p,
849 end_buf, &iwe, IW_EV_PARAM_LEN);
850 }
851 current_ev = p;
852 }
853
854 buf = kmalloc(30, GFP_ATOMIC);
855 if (buf) {
856 memset(&iwe, 0, sizeof(iwe));
857 iwe.cmd = IWEVCUSTOM;
858 sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->timestamp));
859 iwe.u.data.length = strlen(buf);
860 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
861 &iwe, buf);
862 memset(&iwe, 0, sizeof(iwe));
863 iwe.cmd = IWEVCUSTOM;
864 sprintf(buf, " Last beacon: %dms ago",
865 jiffies_to_msecs(jiffies - bss->last_update));
866 iwe.u.data.length = strlen(buf);
867 current_ev = iwe_stream_add_point(info, current_ev,
868 end_buf, &iwe, buf);
869 kfree(buf);
870 }
871
872 if (bss_mesh_cfg(bss)) {
873 u8 *cfg = bss_mesh_cfg(bss);
874 buf = kmalloc(50, GFP_ATOMIC);
875 if (buf) {
876 memset(&iwe, 0, sizeof(iwe));
877 iwe.cmd = IWEVCUSTOM;
878 sprintf(buf, "Mesh network (version %d)", cfg[0]);
879 iwe.u.data.length = strlen(buf);
880 current_ev = iwe_stream_add_point(info, current_ev,
881 end_buf,
882 &iwe, buf);
883 sprintf(buf, "Path Selection Protocol ID: "
884 "0x%02X%02X%02X%02X", cfg[1], cfg[2], cfg[3],
885 cfg[4]);
886 iwe.u.data.length = strlen(buf);
887 current_ev = iwe_stream_add_point(info, current_ev,
888 end_buf,
889 &iwe, buf);
890 sprintf(buf, "Path Selection Metric ID: "
891 "0x%02X%02X%02X%02X", cfg[5], cfg[6], cfg[7],
892 cfg[8]);
893 iwe.u.data.length = strlen(buf);
894 current_ev = iwe_stream_add_point(info, current_ev,
895 end_buf,
896 &iwe, buf);
897 sprintf(buf, "Congestion Control Mode ID: "
898 "0x%02X%02X%02X%02X", cfg[9], cfg[10],
899 cfg[11], cfg[12]);
900 iwe.u.data.length = strlen(buf);
901 current_ev = iwe_stream_add_point(info, current_ev,
902 end_buf,
903 &iwe, buf);
904 sprintf(buf, "Channel Precedence: "
905 "0x%02X%02X%02X%02X", cfg[13], cfg[14],
906 cfg[15], cfg[16]);
907 iwe.u.data.length = strlen(buf);
908 current_ev = iwe_stream_add_point(info, current_ev,
909 end_buf,
910 &iwe, buf);
911 kfree(buf);
912 }
913 }
914
915 return current_ev;
916}
917
918
919int ieee80211_scan_results(struct ieee80211_local *local,
920 struct iw_request_info *info,
921 char *buf, size_t len)
922{
923 char *current_ev = buf;
924 char *end_buf = buf + len;
925 struct ieee80211_bss *bss;
926
927 spin_lock_bh(&local->bss_lock);
928 list_for_each_entry(bss, &local->bss_list, list) {
929 if (buf + len - current_ev <= IW_EV_ADDR_LEN) {
930 spin_unlock_bh(&local->bss_lock);
931 return -E2BIG;
932 }
933 current_ev = ieee80211_scan_result(local, info, bss,
934 current_ev, end_buf);
935 }
936 spin_unlock_bh(&local->bss_lock);
937 return current_ev - buf;
938}
diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c
new file mode 100644
index 00000000000..f72bad636d8
--- /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 f2ba653b9d6..7fef8ea1f5e 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
@@ -640,7 +635,12 @@ static void sta_info_debugfs_add_work(struct work_struct *work)
640 635
641 spin_lock_irqsave(&local->sta_lock, flags); 636 spin_lock_irqsave(&local->sta_lock, flags);
642 list_for_each_entry(tmp, &local->sta_list, list) { 637 list_for_each_entry(tmp, &local->sta_list, list) {
643 if (!tmp->debugfs.dir) { 638 /*
639 * debugfs.add_has_run will be set by
640 * ieee80211_sta_debugfs_add regardless
641 * of what else it does.
642 */
643 if (!tmp->debugfs.add_has_run) {
644 sta = tmp; 644 sta = tmp;
645 __sta_info_pin(sta); 645 __sta_info_pin(sta);
646 break; 646 break;
@@ -802,3 +802,40 @@ void sta_info_flush_delayed(struct ieee80211_sub_if_data *sdata)
802 schedule_work(&local->sta_flush_work); 802 schedule_work(&local->sta_flush_work);
803 spin_unlock_irqrestore(&local->sta_lock, flags); 803 spin_unlock_irqrestore(&local->sta_lock, flags);
804} 804}
805
806void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
807 unsigned long exp_time)
808{
809 struct ieee80211_local *local = sdata->local;
810 struct sta_info *sta, *tmp;
811 LIST_HEAD(tmp_list);
812 DECLARE_MAC_BUF(mac);
813 unsigned long flags;
814
815 spin_lock_irqsave(&local->sta_lock, flags);
816 list_for_each_entry_safe(sta, tmp, &local->sta_list, list)
817 if (time_after(jiffies, sta->last_rx + exp_time)) {
818#ifdef CONFIG_MAC80211_IBSS_DEBUG
819 printk(KERN_DEBUG "%s: expiring inactive STA %s\n",
820 sdata->dev->name, print_mac(mac, sta->sta.addr));
821#endif
822 __sta_info_unlink(&sta);
823 if (sta)
824 list_add(&sta->list, &tmp_list);
825 }
826 spin_unlock_irqrestore(&local->sta_lock, flags);
827
828 list_for_each_entry_safe(sta, tmp, &tmp_list, list)
829 sta_info_destroy(sta);
830}
831
832struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_hw *hw,
833 const u8 *addr)
834{
835 struct sta_info *sta = sta_info_get(hw_to_local(hw), addr);
836
837 if (!sta)
838 return NULL;
839 return &sta->sta;
840}
841EXPORT_SYMBOL(ieee80211_find_sta);
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 109db787ccb..168a39a298b 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,13 @@ 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;
303 bool add_has_run;
327 } debugfs; 304 } debugfs;
328#endif 305#endif
306
307 /* keep last! */
308 struct ieee80211_sta sta;
329}; 309};
330 310
331static inline enum plink_state sta_plink_state(struct sta_info *sta) 311static inline enum plink_state sta_plink_state(struct sta_info *sta)
@@ -425,7 +405,7 @@ static inline u32 get_sta_flags(struct sta_info *sta)
425/* 405/*
426 * Get a STA info, must have be under RCU read lock. 406 * Get a STA info, must have be under RCU read lock.
427 */ 407 */
428struct sta_info *sta_info_get(struct ieee80211_local *local, u8 *addr); 408struct sta_info *sta_info_get(struct ieee80211_local *local, const u8 *addr);
429/* 409/*
430 * Get STA info by index, BROKEN! 410 * Get STA info by index, BROKEN!
431 */ 411 */
@@ -451,7 +431,6 @@ int sta_info_insert(struct sta_info *sta);
451 * has already unlinked it. 431 * has already unlinked it.
452 */ 432 */
453void sta_info_unlink(struct sta_info **sta); 433void sta_info_unlink(struct sta_info **sta);
454void __sta_info_unlink(struct sta_info **sta);
455 434
456void sta_info_destroy(struct sta_info *sta); 435void sta_info_destroy(struct sta_info *sta);
457void sta_info_set_tim_bit(struct sta_info *sta); 436void sta_info_set_tim_bit(struct sta_info *sta);
@@ -463,5 +442,7 @@ void sta_info_stop(struct ieee80211_local *local);
463int sta_info_flush(struct ieee80211_local *local, 442int sta_info_flush(struct ieee80211_local *local,
464 struct ieee80211_sub_if_data *sdata); 443 struct ieee80211_sub_if_data *sdata);
465void sta_info_flush_delayed(struct ieee80211_sub_if_data *sdata); 444void sta_info_flush_delayed(struct ieee80211_sub_if_data *sdata);
445void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata,
446 unsigned long exp_time);
466 447
467#endif /* STA_INFO_H */ 448#endif /* STA_INFO_H */
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c
index 995f7af3d25..34b32bc8f60 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 4788f7b91f4..1460537faf3 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 0d463c80c40..cee4884b9d0 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 if (elen >= sizeof(struct ieee80211_ht_cap))
533 elems->ht_cap_elem = (void *)pos;
534 break;
535 case WLAN_EID_HT_EXTRA_INFO:
536 if (elen >= sizeof(struct ieee80211_ht_addt_info))
537 elems->ht_info_elem = (void *)pos;
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 5c2bf0a3d4d..f0e2d3ecb5c 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 34fa8ed1e78..742f811ca41 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
@@ -804,7 +775,7 @@ static int ieee80211_ioctl_siwfrag(struct net_device *dev,
804 * configure it here */ 775 * configure it here */
805 776
806 if (local->ops->set_frag_threshold) 777 if (local->ops->set_frag_threshold)
807 local->ops->set_frag_threshold( 778 return local->ops->set_frag_threshold(
808 local_to_hw(local), 779 local_to_hw(local),
809 local->fragmentation_threshold); 780 local->fragmentation_threshold);
810 781
@@ -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 4310e2f6566..139b5f267b3 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 04de28c071a..bc62f28a4d3 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 2f33df0dccc..6db649480e8 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 ee898e74808..78892cf2b02 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 3bd2cc556ae..da3d909e053 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 292fa28146f..a90ac83c591 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 09d0c3f3566..05048e40326 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 30e85de9fff..73a46fe1fe4 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 201b8ea3020..201b8ea3020 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 44a6872dc24..9a24332fbed 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 a7879eafc3b..958abf3e5f8 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 6379705a8dc..0302cf3e503 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 fa66824d264..a16943fd72f 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 5a20f93bd7f..2eb2860dabb 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 c1c758e4f73..2e7dbd8b73a 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 7a6a319f544..6ecef3518ca 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 c234e73968a..1f75ea83bcf 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 ebcdbf75ac6..b69f808ac46 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 92f3a677003..9a2d8033f08 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 6099a88fc20..0791f9e08fe 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 00000000000..80ab0c8e5b4
--- /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 d0ea467986a..dd4566ea2bf 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 c6be5d56823..6eb6039d634 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 358110d17e5..a22195f68ac 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 a46ad9e3501..a46ad9e3501 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 77663d84cbd..7d2f22f04b8 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 7b979e22805..1d96de27fef 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 a652da2c320..de5e7e118ee 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 9b0ef86bb1f..8c596e71259 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 0d86a79b87b..7ea92fed50b 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 9892d4aca42..02ddc2b3ce2 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 59bd8b903a1..b92df5c1dfc 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. Please 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 9d1830da8e8..622d7c671cb 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -38,36 +38,30 @@
38#include <net/netfilter/nf_conntrack_core.h> 38#include <net/netfilter/nf_conntrack_core.h>
39#include <net/netfilter/nf_conntrack_extend.h> 39#include <net/netfilter/nf_conntrack_extend.h>
40#include <net/netfilter/nf_conntrack_acct.h> 40#include <net/netfilter/nf_conntrack_acct.h>
41#include <net/netfilter/nf_nat.h>
41 42
42#define NF_CONNTRACK_VERSION "0.5.0" 43#define NF_CONNTRACK_VERSION "0.5.0"
43 44
45unsigned int
46(*nfnetlink_parse_nat_setup_hook)(struct nf_conn *ct,
47 enum nf_nat_manip_type manip,
48 struct nlattr *attr) __read_mostly;
49EXPORT_SYMBOL_GPL(nfnetlink_parse_nat_setup_hook);
50
44DEFINE_SPINLOCK(nf_conntrack_lock); 51DEFINE_SPINLOCK(nf_conntrack_lock);
45EXPORT_SYMBOL_GPL(nf_conntrack_lock); 52EXPORT_SYMBOL_GPL(nf_conntrack_lock);
46 53
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; 54unsigned int nf_conntrack_htable_size __read_mostly;
52EXPORT_SYMBOL_GPL(nf_conntrack_htable_size); 55EXPORT_SYMBOL_GPL(nf_conntrack_htable_size);
53 56
54int nf_conntrack_max __read_mostly; 57int nf_conntrack_max __read_mostly;
55EXPORT_SYMBOL_GPL(nf_conntrack_max); 58EXPORT_SYMBOL_GPL(nf_conntrack_max);
56 59
57struct hlist_head *nf_conntrack_hash __read_mostly;
58EXPORT_SYMBOL_GPL(nf_conntrack_hash);
59
60struct nf_conn nf_conntrack_untracked __read_mostly; 60struct nf_conn nf_conntrack_untracked __read_mostly;
61EXPORT_SYMBOL_GPL(nf_conntrack_untracked); 61EXPORT_SYMBOL_GPL(nf_conntrack_untracked);
62 62
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; 63static struct kmem_cache *nf_conntrack_cachep __read_mostly;
67 64
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; 65static int nf_conntrack_hash_rnd_initted;
72static unsigned int nf_conntrack_hash_rnd; 66static unsigned int nf_conntrack_hash_rnd;
73 67
@@ -180,6 +174,7 @@ static void
180destroy_conntrack(struct nf_conntrack *nfct) 174destroy_conntrack(struct nf_conntrack *nfct)
181{ 175{
182 struct nf_conn *ct = (struct nf_conn *)nfct; 176 struct nf_conn *ct = (struct nf_conn *)nfct;
177 struct net *net = nf_ct_net(ct);
183 struct nf_conntrack_l4proto *l4proto; 178 struct nf_conntrack_l4proto *l4proto;
184 179
185 pr_debug("destroy_conntrack(%p)\n", ct); 180 pr_debug("destroy_conntrack(%p)\n", ct);
@@ -212,7 +207,7 @@ destroy_conntrack(struct nf_conntrack *nfct)
212 hlist_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode); 207 hlist_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode);
213 } 208 }
214 209
215 NF_CT_STAT_INC(delete); 210 NF_CT_STAT_INC(net, delete);
216 spin_unlock_bh(&nf_conntrack_lock); 211 spin_unlock_bh(&nf_conntrack_lock);
217 212
218 if (ct->master) 213 if (ct->master)
@@ -225,6 +220,7 @@ destroy_conntrack(struct nf_conntrack *nfct)
225static void death_by_timeout(unsigned long ul_conntrack) 220static void death_by_timeout(unsigned long ul_conntrack)
226{ 221{
227 struct nf_conn *ct = (void *)ul_conntrack; 222 struct nf_conn *ct = (void *)ul_conntrack;
223 struct net *net = nf_ct_net(ct);
228 struct nf_conn_help *help = nfct_help(ct); 224 struct nf_conn_help *help = nfct_help(ct);
229 struct nf_conntrack_helper *helper; 225 struct nf_conntrack_helper *helper;
230 226
@@ -239,14 +235,14 @@ static void death_by_timeout(unsigned long ul_conntrack)
239 spin_lock_bh(&nf_conntrack_lock); 235 spin_lock_bh(&nf_conntrack_lock);
240 /* Inside lock so preempt is disabled on module removal path. 236 /* Inside lock so preempt is disabled on module removal path.
241 * Otherwise we can get spurious warnings. */ 237 * Otherwise we can get spurious warnings. */
242 NF_CT_STAT_INC(delete_list); 238 NF_CT_STAT_INC(net, delete_list);
243 clean_from_lists(ct); 239 clean_from_lists(ct);
244 spin_unlock_bh(&nf_conntrack_lock); 240 spin_unlock_bh(&nf_conntrack_lock);
245 nf_ct_put(ct); 241 nf_ct_put(ct);
246} 242}
247 243
248struct nf_conntrack_tuple_hash * 244struct nf_conntrack_tuple_hash *
249__nf_conntrack_find(const struct nf_conntrack_tuple *tuple) 245__nf_conntrack_find(struct net *net, const struct nf_conntrack_tuple *tuple)
250{ 246{
251 struct nf_conntrack_tuple_hash *h; 247 struct nf_conntrack_tuple_hash *h;
252 struct hlist_node *n; 248 struct hlist_node *n;
@@ -256,13 +252,13 @@ __nf_conntrack_find(const struct nf_conntrack_tuple *tuple)
256 * at least once for the stats anyway. 252 * at least once for the stats anyway.
257 */ 253 */
258 local_bh_disable(); 254 local_bh_disable();
259 hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[hash], hnode) { 255 hlist_for_each_entry_rcu(h, n, &net->ct.hash[hash], hnode) {
260 if (nf_ct_tuple_equal(tuple, &h->tuple)) { 256 if (nf_ct_tuple_equal(tuple, &h->tuple)) {
261 NF_CT_STAT_INC(found); 257 NF_CT_STAT_INC(net, found);
262 local_bh_enable(); 258 local_bh_enable();
263 return h; 259 return h;
264 } 260 }
265 NF_CT_STAT_INC(searched); 261 NF_CT_STAT_INC(net, searched);
266 } 262 }
267 local_bh_enable(); 263 local_bh_enable();
268 264
@@ -272,13 +268,13 @@ EXPORT_SYMBOL_GPL(__nf_conntrack_find);
272 268
273/* Find a connection corresponding to a tuple. */ 269/* Find a connection corresponding to a tuple. */
274struct nf_conntrack_tuple_hash * 270struct nf_conntrack_tuple_hash *
275nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple) 271nf_conntrack_find_get(struct net *net, const struct nf_conntrack_tuple *tuple)
276{ 272{
277 struct nf_conntrack_tuple_hash *h; 273 struct nf_conntrack_tuple_hash *h;
278 struct nf_conn *ct; 274 struct nf_conn *ct;
279 275
280 rcu_read_lock(); 276 rcu_read_lock();
281 h = __nf_conntrack_find(tuple); 277 h = __nf_conntrack_find(net, tuple);
282 if (h) { 278 if (h) {
283 ct = nf_ct_tuplehash_to_ctrack(h); 279 ct = nf_ct_tuplehash_to_ctrack(h);
284 if (unlikely(!atomic_inc_not_zero(&ct->ct_general.use))) 280 if (unlikely(!atomic_inc_not_zero(&ct->ct_general.use)))
@@ -294,10 +290,12 @@ static void __nf_conntrack_hash_insert(struct nf_conn *ct,
294 unsigned int hash, 290 unsigned int hash,
295 unsigned int repl_hash) 291 unsigned int repl_hash)
296{ 292{
293 struct net *net = nf_ct_net(ct);
294
297 hlist_add_head_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode, 295 hlist_add_head_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode,
298 &nf_conntrack_hash[hash]); 296 &net->ct.hash[hash]);
299 hlist_add_head_rcu(&ct->tuplehash[IP_CT_DIR_REPLY].hnode, 297 hlist_add_head_rcu(&ct->tuplehash[IP_CT_DIR_REPLY].hnode,
300 &nf_conntrack_hash[repl_hash]); 298 &net->ct.hash[repl_hash]);
301} 299}
302 300
303void nf_conntrack_hash_insert(struct nf_conn *ct) 301void nf_conntrack_hash_insert(struct nf_conn *ct)
@@ -323,8 +321,10 @@ __nf_conntrack_confirm(struct sk_buff *skb)
323 struct nf_conn_help *help; 321 struct nf_conn_help *help;
324 struct hlist_node *n; 322 struct hlist_node *n;
325 enum ip_conntrack_info ctinfo; 323 enum ip_conntrack_info ctinfo;
324 struct net *net;
326 325
327 ct = nf_ct_get(skb, &ctinfo); 326 ct = nf_ct_get(skb, &ctinfo);
327 net = nf_ct_net(ct);
328 328
329 /* ipt_REJECT uses nf_conntrack_attach to attach related 329 /* ipt_REJECT uses nf_conntrack_attach to attach related
330 ICMP/TCP RST packets in other direction. Actual packet 330 ICMP/TCP RST packets in other direction. Actual packet
@@ -351,11 +351,11 @@ __nf_conntrack_confirm(struct sk_buff *skb)
351 /* See if there's one in the list already, including reverse: 351 /* See if there's one in the list already, including reverse:
352 NAT could have grabbed it without realizing, since we're 352 NAT could have grabbed it without realizing, since we're
353 not in the hash. If there is, we lost race. */ 353 not in the hash. If there is, we lost race. */
354 hlist_for_each_entry(h, n, &nf_conntrack_hash[hash], hnode) 354 hlist_for_each_entry(h, n, &net->ct.hash[hash], hnode)
355 if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, 355 if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
356 &h->tuple)) 356 &h->tuple))
357 goto out; 357 goto out;
358 hlist_for_each_entry(h, n, &nf_conntrack_hash[repl_hash], hnode) 358 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, 359 if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_REPLY].tuple,
360 &h->tuple)) 360 &h->tuple))
361 goto out; 361 goto out;
@@ -371,22 +371,22 @@ __nf_conntrack_confirm(struct sk_buff *skb)
371 add_timer(&ct->timeout); 371 add_timer(&ct->timeout);
372 atomic_inc(&ct->ct_general.use); 372 atomic_inc(&ct->ct_general.use);
373 set_bit(IPS_CONFIRMED_BIT, &ct->status); 373 set_bit(IPS_CONFIRMED_BIT, &ct->status);
374 NF_CT_STAT_INC(insert); 374 NF_CT_STAT_INC(net, insert);
375 spin_unlock_bh(&nf_conntrack_lock); 375 spin_unlock_bh(&nf_conntrack_lock);
376 help = nfct_help(ct); 376 help = nfct_help(ct);
377 if (help && help->helper) 377 if (help && help->helper)
378 nf_conntrack_event_cache(IPCT_HELPER, skb); 378 nf_conntrack_event_cache(IPCT_HELPER, ct);
379#ifdef CONFIG_NF_NAT_NEEDED 379#ifdef CONFIG_NF_NAT_NEEDED
380 if (test_bit(IPS_SRC_NAT_DONE_BIT, &ct->status) || 380 if (test_bit(IPS_SRC_NAT_DONE_BIT, &ct->status) ||
381 test_bit(IPS_DST_NAT_DONE_BIT, &ct->status)) 381 test_bit(IPS_DST_NAT_DONE_BIT, &ct->status))
382 nf_conntrack_event_cache(IPCT_NATINFO, skb); 382 nf_conntrack_event_cache(IPCT_NATINFO, ct);
383#endif 383#endif
384 nf_conntrack_event_cache(master_ct(ct) ? 384 nf_conntrack_event_cache(master_ct(ct) ?
385 IPCT_RELATED : IPCT_NEW, skb); 385 IPCT_RELATED : IPCT_NEW, ct);
386 return NF_ACCEPT; 386 return NF_ACCEPT;
387 387
388out: 388out:
389 NF_CT_STAT_INC(insert_failed); 389 NF_CT_STAT_INC(net, insert_failed);
390 spin_unlock_bh(&nf_conntrack_lock); 390 spin_unlock_bh(&nf_conntrack_lock);
391 return NF_DROP; 391 return NF_DROP;
392} 392}
@@ -398,6 +398,7 @@ int
398nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple, 398nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
399 const struct nf_conn *ignored_conntrack) 399 const struct nf_conn *ignored_conntrack)
400{ 400{
401 struct net *net = nf_ct_net(ignored_conntrack);
401 struct nf_conntrack_tuple_hash *h; 402 struct nf_conntrack_tuple_hash *h;
402 struct hlist_node *n; 403 struct hlist_node *n;
403 unsigned int hash = hash_conntrack(tuple); 404 unsigned int hash = hash_conntrack(tuple);
@@ -406,14 +407,14 @@ nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
406 * least once for the stats anyway. 407 * least once for the stats anyway.
407 */ 408 */
408 rcu_read_lock_bh(); 409 rcu_read_lock_bh();
409 hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[hash], hnode) { 410 hlist_for_each_entry_rcu(h, n, &net->ct.hash[hash], hnode) {
410 if (nf_ct_tuplehash_to_ctrack(h) != ignored_conntrack && 411 if (nf_ct_tuplehash_to_ctrack(h) != ignored_conntrack &&
411 nf_ct_tuple_equal(tuple, &h->tuple)) { 412 nf_ct_tuple_equal(tuple, &h->tuple)) {
412 NF_CT_STAT_INC(found); 413 NF_CT_STAT_INC(net, found);
413 rcu_read_unlock_bh(); 414 rcu_read_unlock_bh();
414 return 1; 415 return 1;
415 } 416 }
416 NF_CT_STAT_INC(searched); 417 NF_CT_STAT_INC(net, searched);
417 } 418 }
418 rcu_read_unlock_bh(); 419 rcu_read_unlock_bh();
419 420
@@ -425,7 +426,7 @@ EXPORT_SYMBOL_GPL(nf_conntrack_tuple_taken);
425 426
426/* There's a small race here where we may free a just-assured 427/* There's a small race here where we may free a just-assured
427 connection. Too bad: we're in trouble anyway. */ 428 connection. Too bad: we're in trouble anyway. */
428static noinline int early_drop(unsigned int hash) 429static noinline int early_drop(struct net *net, unsigned int hash)
429{ 430{
430 /* Use oldest entry, which is roughly LRU */ 431 /* Use oldest entry, which is roughly LRU */
431 struct nf_conntrack_tuple_hash *h; 432 struct nf_conntrack_tuple_hash *h;
@@ -436,7 +437,7 @@ static noinline int early_drop(unsigned int hash)
436 437
437 rcu_read_lock(); 438 rcu_read_lock();
438 for (i = 0; i < nf_conntrack_htable_size; i++) { 439 for (i = 0; i < nf_conntrack_htable_size; i++) {
439 hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[hash], 440 hlist_for_each_entry_rcu(h, n, &net->ct.hash[hash],
440 hnode) { 441 hnode) {
441 tmp = nf_ct_tuplehash_to_ctrack(h); 442 tmp = nf_ct_tuplehash_to_ctrack(h);
442 if (!test_bit(IPS_ASSURED_BIT, &tmp->status)) 443 if (!test_bit(IPS_ASSURED_BIT, &tmp->status))
@@ -458,13 +459,14 @@ static noinline int early_drop(unsigned int hash)
458 if (del_timer(&ct->timeout)) { 459 if (del_timer(&ct->timeout)) {
459 death_by_timeout((unsigned long)ct); 460 death_by_timeout((unsigned long)ct);
460 dropped = 1; 461 dropped = 1;
461 NF_CT_STAT_INC_ATOMIC(early_drop); 462 NF_CT_STAT_INC_ATOMIC(net, early_drop);
462 } 463 }
463 nf_ct_put(ct); 464 nf_ct_put(ct);
464 return dropped; 465 return dropped;
465} 466}
466 467
467struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig, 468struct nf_conn *nf_conntrack_alloc(struct net *net,
469 const struct nf_conntrack_tuple *orig,
468 const struct nf_conntrack_tuple *repl, 470 const struct nf_conntrack_tuple *repl,
469 gfp_t gfp) 471 gfp_t gfp)
470{ 472{
@@ -476,13 +478,13 @@ struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
476 } 478 }
477 479
478 /* We don't want any race condition at early drop stage */ 480 /* We don't want any race condition at early drop stage */
479 atomic_inc(&nf_conntrack_count); 481 atomic_inc(&net->ct.count);
480 482
481 if (nf_conntrack_max && 483 if (nf_conntrack_max &&
482 unlikely(atomic_read(&nf_conntrack_count) > nf_conntrack_max)) { 484 unlikely(atomic_read(&net->ct.count) > nf_conntrack_max)) {
483 unsigned int hash = hash_conntrack(orig); 485 unsigned int hash = hash_conntrack(orig);
484 if (!early_drop(hash)) { 486 if (!early_drop(net, hash)) {
485 atomic_dec(&nf_conntrack_count); 487 atomic_dec(&net->ct.count);
486 if (net_ratelimit()) 488 if (net_ratelimit())
487 printk(KERN_WARNING 489 printk(KERN_WARNING
488 "nf_conntrack: table full, dropping" 490 "nf_conntrack: table full, dropping"
@@ -494,7 +496,7 @@ struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
494 ct = kmem_cache_zalloc(nf_conntrack_cachep, gfp); 496 ct = kmem_cache_zalloc(nf_conntrack_cachep, gfp);
495 if (ct == NULL) { 497 if (ct == NULL) {
496 pr_debug("nf_conntrack_alloc: Can't alloc conntrack.\n"); 498 pr_debug("nf_conntrack_alloc: Can't alloc conntrack.\n");
497 atomic_dec(&nf_conntrack_count); 499 atomic_dec(&net->ct.count);
498 return ERR_PTR(-ENOMEM); 500 return ERR_PTR(-ENOMEM);
499 } 501 }
500 502
@@ -503,6 +505,9 @@ struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
503 ct->tuplehash[IP_CT_DIR_REPLY].tuple = *repl; 505 ct->tuplehash[IP_CT_DIR_REPLY].tuple = *repl;
504 /* Don't set timer yet: wait for confirmation */ 506 /* Don't set timer yet: wait for confirmation */
505 setup_timer(&ct->timeout, death_by_timeout, (unsigned long)ct); 507 setup_timer(&ct->timeout, death_by_timeout, (unsigned long)ct);
508#ifdef CONFIG_NET_NS
509 ct->ct_net = net;
510#endif
506 INIT_RCU_HEAD(&ct->rcu); 511 INIT_RCU_HEAD(&ct->rcu);
507 512
508 return ct; 513 return ct;
@@ -512,10 +517,11 @@ EXPORT_SYMBOL_GPL(nf_conntrack_alloc);
512static void nf_conntrack_free_rcu(struct rcu_head *head) 517static void nf_conntrack_free_rcu(struct rcu_head *head)
513{ 518{
514 struct nf_conn *ct = container_of(head, struct nf_conn, rcu); 519 struct nf_conn *ct = container_of(head, struct nf_conn, rcu);
520 struct net *net = nf_ct_net(ct);
515 521
516 nf_ct_ext_free(ct); 522 nf_ct_ext_free(ct);
517 kmem_cache_free(nf_conntrack_cachep, ct); 523 kmem_cache_free(nf_conntrack_cachep, ct);
518 atomic_dec(&nf_conntrack_count); 524 atomic_dec(&net->ct.count);
519} 525}
520 526
521void nf_conntrack_free(struct nf_conn *ct) 527void nf_conntrack_free(struct nf_conn *ct)
@@ -528,7 +534,8 @@ EXPORT_SYMBOL_GPL(nf_conntrack_free);
528/* Allocate a new conntrack: we return -ENOMEM if classification 534/* Allocate a new conntrack: we return -ENOMEM if classification
529 failed due to stress. Otherwise it really is unclassifiable. */ 535 failed due to stress. Otherwise it really is unclassifiable. */
530static struct nf_conntrack_tuple_hash * 536static struct nf_conntrack_tuple_hash *
531init_conntrack(const struct nf_conntrack_tuple *tuple, 537init_conntrack(struct net *net,
538 const struct nf_conntrack_tuple *tuple,
532 struct nf_conntrack_l3proto *l3proto, 539 struct nf_conntrack_l3proto *l3proto,
533 struct nf_conntrack_l4proto *l4proto, 540 struct nf_conntrack_l4proto *l4proto,
534 struct sk_buff *skb, 541 struct sk_buff *skb,
@@ -544,7 +551,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
544 return NULL; 551 return NULL;
545 } 552 }
546 553
547 ct = nf_conntrack_alloc(tuple, &repl_tuple, GFP_ATOMIC); 554 ct = nf_conntrack_alloc(net, tuple, &repl_tuple, GFP_ATOMIC);
548 if (ct == NULL || IS_ERR(ct)) { 555 if (ct == NULL || IS_ERR(ct)) {
549 pr_debug("Can't allocate conntrack.\n"); 556 pr_debug("Can't allocate conntrack.\n");
550 return (struct nf_conntrack_tuple_hash *)ct; 557 return (struct nf_conntrack_tuple_hash *)ct;
@@ -559,7 +566,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
559 nf_ct_acct_ext_add(ct, GFP_ATOMIC); 566 nf_ct_acct_ext_add(ct, GFP_ATOMIC);
560 567
561 spin_lock_bh(&nf_conntrack_lock); 568 spin_lock_bh(&nf_conntrack_lock);
562 exp = nf_ct_find_expectation(tuple); 569 exp = nf_ct_find_expectation(net, tuple);
563 if (exp) { 570 if (exp) {
564 pr_debug("conntrack: expectation arrives ct=%p exp=%p\n", 571 pr_debug("conntrack: expectation arrives ct=%p exp=%p\n",
565 ct, exp); 572 ct, exp);
@@ -579,7 +586,7 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
579 ct->secmark = exp->master->secmark; 586 ct->secmark = exp->master->secmark;
580#endif 587#endif
581 nf_conntrack_get(&ct->master->ct_general); 588 nf_conntrack_get(&ct->master->ct_general);
582 NF_CT_STAT_INC(expect_new); 589 NF_CT_STAT_INC(net, expect_new);
583 } else { 590 } else {
584 struct nf_conntrack_helper *helper; 591 struct nf_conntrack_helper *helper;
585 592
@@ -589,11 +596,12 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
589 if (help) 596 if (help)
590 rcu_assign_pointer(help->helper, helper); 597 rcu_assign_pointer(help->helper, helper);
591 } 598 }
592 NF_CT_STAT_INC(new); 599 NF_CT_STAT_INC(net, new);
593 } 600 }
594 601
595 /* Overload tuple linked list to put us in unconfirmed list. */ 602 /* Overload tuple linked list to put us in unconfirmed list. */
596 hlist_add_head(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode, &unconfirmed); 603 hlist_add_head(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnode,
604 &net->ct.unconfirmed);
597 605
598 spin_unlock_bh(&nf_conntrack_lock); 606 spin_unlock_bh(&nf_conntrack_lock);
599 607
@@ -608,7 +616,8 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
608 616
609/* On success, returns conntrack ptr, sets skb->nfct and ctinfo */ 617/* On success, returns conntrack ptr, sets skb->nfct and ctinfo */
610static inline struct nf_conn * 618static inline struct nf_conn *
611resolve_normal_ct(struct sk_buff *skb, 619resolve_normal_ct(struct net *net,
620 struct sk_buff *skb,
612 unsigned int dataoff, 621 unsigned int dataoff,
613 u_int16_t l3num, 622 u_int16_t l3num,
614 u_int8_t protonum, 623 u_int8_t protonum,
@@ -629,9 +638,9 @@ resolve_normal_ct(struct sk_buff *skb,
629 } 638 }
630 639
631 /* look for tuple match */ 640 /* look for tuple match */
632 h = nf_conntrack_find_get(&tuple); 641 h = nf_conntrack_find_get(net, &tuple);
633 if (!h) { 642 if (!h) {
634 h = init_conntrack(&tuple, l3proto, l4proto, skb, dataoff); 643 h = init_conntrack(net, &tuple, l3proto, l4proto, skb, dataoff);
635 if (!h) 644 if (!h)
636 return NULL; 645 return NULL;
637 if (IS_ERR(h)) 646 if (IS_ERR(h))
@@ -665,7 +674,8 @@ resolve_normal_ct(struct sk_buff *skb,
665} 674}
666 675
667unsigned int 676unsigned int
668nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff *skb) 677nf_conntrack_in(struct net *net, u_int8_t pf, unsigned int hooknum,
678 struct sk_buff *skb)
669{ 679{
670 struct nf_conn *ct; 680 struct nf_conn *ct;
671 enum ip_conntrack_info ctinfo; 681 enum ip_conntrack_info ctinfo;
@@ -678,44 +688,46 @@ nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff *skb)
678 688
679 /* Previously seen (loopback or untracked)? Ignore. */ 689 /* Previously seen (loopback or untracked)? Ignore. */
680 if (skb->nfct) { 690 if (skb->nfct) {
681 NF_CT_STAT_INC_ATOMIC(ignore); 691 NF_CT_STAT_INC_ATOMIC(net, ignore);
682 return NF_ACCEPT; 692 return NF_ACCEPT;
683 } 693 }
684 694
685 /* rcu_read_lock()ed by nf_hook_slow */ 695 /* rcu_read_lock()ed by nf_hook_slow */
686 l3proto = __nf_ct_l3proto_find((u_int16_t)pf); 696 l3proto = __nf_ct_l3proto_find(pf);
687 ret = l3proto->get_l4proto(skb, skb_network_offset(skb), 697 ret = l3proto->get_l4proto(skb, skb_network_offset(skb),
688 &dataoff, &protonum); 698 &dataoff, &protonum);
689 if (ret <= 0) { 699 if (ret <= 0) {
690 pr_debug("not prepared to track yet or error occured\n"); 700 pr_debug("not prepared to track yet or error occured\n");
691 NF_CT_STAT_INC_ATOMIC(error); 701 NF_CT_STAT_INC_ATOMIC(net, error);
692 NF_CT_STAT_INC_ATOMIC(invalid); 702 NF_CT_STAT_INC_ATOMIC(net, invalid);
693 return -ret; 703 return -ret;
694 } 704 }
695 705
696 l4proto = __nf_ct_l4proto_find((u_int16_t)pf, protonum); 706 l4proto = __nf_ct_l4proto_find(pf, protonum);
697 707
698 /* It may be an special packet, error, unclean... 708 /* It may be an special packet, error, unclean...
699 * inverse of the return code tells to the netfilter 709 * inverse of the return code tells to the netfilter
700 * core what to do with the packet. */ 710 * core what to do with the packet. */
701 if (l4proto->error != NULL && 711 if (l4proto->error != NULL) {
702 (ret = l4proto->error(skb, dataoff, &ctinfo, pf, hooknum)) <= 0) { 712 ret = l4proto->error(net, skb, dataoff, &ctinfo, pf, hooknum);
703 NF_CT_STAT_INC_ATOMIC(error); 713 if (ret <= 0) {
704 NF_CT_STAT_INC_ATOMIC(invalid); 714 NF_CT_STAT_INC_ATOMIC(net, error);
705 return -ret; 715 NF_CT_STAT_INC_ATOMIC(net, invalid);
716 return -ret;
717 }
706 } 718 }
707 719
708 ct = resolve_normal_ct(skb, dataoff, pf, protonum, l3proto, l4proto, 720 ct = resolve_normal_ct(net, skb, dataoff, pf, protonum,
709 &set_reply, &ctinfo); 721 l3proto, l4proto, &set_reply, &ctinfo);
710 if (!ct) { 722 if (!ct) {
711 /* Not valid part of a connection */ 723 /* Not valid part of a connection */
712 NF_CT_STAT_INC_ATOMIC(invalid); 724 NF_CT_STAT_INC_ATOMIC(net, invalid);
713 return NF_ACCEPT; 725 return NF_ACCEPT;
714 } 726 }
715 727
716 if (IS_ERR(ct)) { 728 if (IS_ERR(ct)) {
717 /* Too stressed to deal. */ 729 /* Too stressed to deal. */
718 NF_CT_STAT_INC_ATOMIC(drop); 730 NF_CT_STAT_INC_ATOMIC(net, drop);
719 return NF_DROP; 731 return NF_DROP;
720 } 732 }
721 733
@@ -728,12 +740,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"); 740 pr_debug("nf_conntrack_in: Can't track with proto module\n");
729 nf_conntrack_put(skb->nfct); 741 nf_conntrack_put(skb->nfct);
730 skb->nfct = NULL; 742 skb->nfct = NULL;
731 NF_CT_STAT_INC_ATOMIC(invalid); 743 NF_CT_STAT_INC_ATOMIC(net, invalid);
732 return -ret; 744 return -ret;
733 } 745 }
734 746
735 if (set_reply && !test_and_set_bit(IPS_SEEN_REPLY_BIT, &ct->status)) 747 if (set_reply && !test_and_set_bit(IPS_SEEN_REPLY_BIT, &ct->status))
736 nf_conntrack_event_cache(IPCT_STATUS, skb); 748 nf_conntrack_event_cache(IPCT_STATUS, ct);
737 749
738 return ret; 750 return ret;
739} 751}
@@ -846,7 +858,7 @@ acct:
846 858
847 /* must be unlocked when calling event cache */ 859 /* must be unlocked when calling event cache */
848 if (event) 860 if (event)
849 nf_conntrack_event_cache(event, skb); 861 nf_conntrack_event_cache(event, ct);
850} 862}
851EXPORT_SYMBOL_GPL(__nf_ct_refresh_acct); 863EXPORT_SYMBOL_GPL(__nf_ct_refresh_acct);
852 864
@@ -938,7 +950,7 @@ static void nf_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb)
938 950
939/* Bring out ya dead! */ 951/* Bring out ya dead! */
940static struct nf_conn * 952static struct nf_conn *
941get_next_corpse(int (*iter)(struct nf_conn *i, void *data), 953get_next_corpse(struct net *net, int (*iter)(struct nf_conn *i, void *data),
942 void *data, unsigned int *bucket) 954 void *data, unsigned int *bucket)
943{ 955{
944 struct nf_conntrack_tuple_hash *h; 956 struct nf_conntrack_tuple_hash *h;
@@ -947,13 +959,13 @@ get_next_corpse(int (*iter)(struct nf_conn *i, void *data),
947 959
948 spin_lock_bh(&nf_conntrack_lock); 960 spin_lock_bh(&nf_conntrack_lock);
949 for (; *bucket < nf_conntrack_htable_size; (*bucket)++) { 961 for (; *bucket < nf_conntrack_htable_size; (*bucket)++) {
950 hlist_for_each_entry(h, n, &nf_conntrack_hash[*bucket], hnode) { 962 hlist_for_each_entry(h, n, &net->ct.hash[*bucket], hnode) {
951 ct = nf_ct_tuplehash_to_ctrack(h); 963 ct = nf_ct_tuplehash_to_ctrack(h);
952 if (iter(ct, data)) 964 if (iter(ct, data))
953 goto found; 965 goto found;
954 } 966 }
955 } 967 }
956 hlist_for_each_entry(h, n, &unconfirmed, hnode) { 968 hlist_for_each_entry(h, n, &net->ct.unconfirmed, hnode) {
957 ct = nf_ct_tuplehash_to_ctrack(h); 969 ct = nf_ct_tuplehash_to_ctrack(h);
958 if (iter(ct, data)) 970 if (iter(ct, data))
959 set_bit(IPS_DYING_BIT, &ct->status); 971 set_bit(IPS_DYING_BIT, &ct->status);
@@ -966,13 +978,14 @@ found:
966 return ct; 978 return ct;
967} 979}
968 980
969void 981void nf_ct_iterate_cleanup(struct net *net,
970nf_ct_iterate_cleanup(int (*iter)(struct nf_conn *i, void *data), void *data) 982 int (*iter)(struct nf_conn *i, void *data),
983 void *data)
971{ 984{
972 struct nf_conn *ct; 985 struct nf_conn *ct;
973 unsigned int bucket = 0; 986 unsigned int bucket = 0;
974 987
975 while ((ct = get_next_corpse(iter, data, &bucket)) != NULL) { 988 while ((ct = get_next_corpse(net, iter, data, &bucket)) != NULL) {
976 /* Time to push up daises... */ 989 /* Time to push up daises... */
977 if (del_timer(&ct->timeout)) 990 if (del_timer(&ct->timeout))
978 death_by_timeout((unsigned long)ct); 991 death_by_timeout((unsigned long)ct);
@@ -998,27 +1011,26 @@ void nf_ct_free_hashtable(struct hlist_head *hash, int vmalloced, unsigned int s
998} 1011}
999EXPORT_SYMBOL_GPL(nf_ct_free_hashtable); 1012EXPORT_SYMBOL_GPL(nf_ct_free_hashtable);
1000 1013
1001void nf_conntrack_flush(void) 1014void nf_conntrack_flush(struct net *net)
1002{ 1015{
1003 nf_ct_iterate_cleanup(kill_all, NULL); 1016 nf_ct_iterate_cleanup(net, kill_all, NULL);
1004} 1017}
1005EXPORT_SYMBOL_GPL(nf_conntrack_flush); 1018EXPORT_SYMBOL_GPL(nf_conntrack_flush);
1006 1019
1007/* Mishearing the voices in his head, our hero wonders how he's 1020static void nf_conntrack_cleanup_init_net(void)
1008 supposed to kill the mall. */
1009void nf_conntrack_cleanup(void)
1010{ 1021{
1011 rcu_assign_pointer(ip_ct_attach, NULL); 1022 nf_conntrack_helper_fini();
1012 1023 nf_conntrack_proto_fini();
1013 /* This makes sure all current packets have passed through 1024 kmem_cache_destroy(nf_conntrack_cachep);
1014 netfilter framework. Roll on, two-stage module 1025}
1015 delete... */
1016 synchronize_net();
1017 1026
1018 nf_ct_event_cache_flush(); 1027static void nf_conntrack_cleanup_net(struct net *net)
1028{
1029 nf_ct_event_cache_flush(net);
1030 nf_conntrack_ecache_fini(net);
1019 i_see_dead_people: 1031 i_see_dead_people:
1020 nf_conntrack_flush(); 1032 nf_conntrack_flush(net);
1021 if (atomic_read(&nf_conntrack_count) != 0) { 1033 if (atomic_read(&net->ct.count) != 0) {
1022 schedule(); 1034 schedule();
1023 goto i_see_dead_people; 1035 goto i_see_dead_people;
1024 } 1036 }
@@ -1026,16 +1038,31 @@ void nf_conntrack_cleanup(void)
1026 while (atomic_read(&nf_conntrack_untracked.ct_general.use) > 1) 1038 while (atomic_read(&nf_conntrack_untracked.ct_general.use) > 1)
1027 schedule(); 1039 schedule();
1028 1040
1029 rcu_assign_pointer(nf_ct_destroy, NULL); 1041 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); 1042 nf_conntrack_htable_size);
1043 nf_conntrack_acct_fini(net);
1044 nf_conntrack_expect_fini(net);
1045 free_percpu(net->ct.stat);
1046}
1034 1047
1035 nf_conntrack_acct_fini(); 1048/* Mishearing the voices in his head, our hero wonders how he's
1036 nf_conntrack_expect_fini(); 1049 supposed to kill the mall. */
1037 nf_conntrack_helper_fini(); 1050void nf_conntrack_cleanup(struct net *net)
1038 nf_conntrack_proto_fini(); 1051{
1052 if (net_eq(net, &init_net))
1053 rcu_assign_pointer(ip_ct_attach, NULL);
1054
1055 /* This makes sure all current packets have passed through
1056 netfilter framework. Roll on, two-stage module
1057 delete... */
1058 synchronize_net();
1059
1060 nf_conntrack_cleanup_net(net);
1061
1062 if (net_eq(net, &init_net)) {
1063 rcu_assign_pointer(nf_ct_destroy, NULL);
1064 nf_conntrack_cleanup_init_net();
1065 }
1039} 1066}
1040 1067
1041struct hlist_head *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced) 1068struct hlist_head *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced)
@@ -1094,8 +1121,8 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
1094 */ 1121 */
1095 spin_lock_bh(&nf_conntrack_lock); 1122 spin_lock_bh(&nf_conntrack_lock);
1096 for (i = 0; i < nf_conntrack_htable_size; i++) { 1123 for (i = 0; i < nf_conntrack_htable_size; i++) {
1097 while (!hlist_empty(&nf_conntrack_hash[i])) { 1124 while (!hlist_empty(&init_net.ct.hash[i])) {
1098 h = hlist_entry(nf_conntrack_hash[i].first, 1125 h = hlist_entry(init_net.ct.hash[i].first,
1099 struct nf_conntrack_tuple_hash, hnode); 1126 struct nf_conntrack_tuple_hash, hnode);
1100 hlist_del_rcu(&h->hnode); 1127 hlist_del_rcu(&h->hnode);
1101 bucket = __hash_conntrack(&h->tuple, hashsize, rnd); 1128 bucket = __hash_conntrack(&h->tuple, hashsize, rnd);
@@ -1103,12 +1130,12 @@ int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp)
1103 } 1130 }
1104 } 1131 }
1105 old_size = nf_conntrack_htable_size; 1132 old_size = nf_conntrack_htable_size;
1106 old_vmalloced = nf_conntrack_vmalloc; 1133 old_vmalloced = init_net.ct.hash_vmalloc;
1107 old_hash = nf_conntrack_hash; 1134 old_hash = init_net.ct.hash;
1108 1135
1109 nf_conntrack_htable_size = hashsize; 1136 nf_conntrack_htable_size = hashsize;
1110 nf_conntrack_vmalloc = vmalloced; 1137 init_net.ct.hash_vmalloc = vmalloced;
1111 nf_conntrack_hash = hash; 1138 init_net.ct.hash = hash;
1112 nf_conntrack_hash_rnd = rnd; 1139 nf_conntrack_hash_rnd = rnd;
1113 spin_unlock_bh(&nf_conntrack_lock); 1140 spin_unlock_bh(&nf_conntrack_lock);
1114 1141
@@ -1120,7 +1147,7 @@ EXPORT_SYMBOL_GPL(nf_conntrack_set_hashsize);
1120module_param_call(hashsize, nf_conntrack_set_hashsize, param_get_uint, 1147module_param_call(hashsize, nf_conntrack_set_hashsize, param_get_uint,
1121 &nf_conntrack_htable_size, 0600); 1148 &nf_conntrack_htable_size, 0600);
1122 1149
1123int __init nf_conntrack_init(void) 1150static int nf_conntrack_init_init_net(void)
1124{ 1151{
1125 int max_factor = 8; 1152 int max_factor = 8;
1126 int ret; 1153 int ret;
@@ -1142,13 +1169,6 @@ int __init nf_conntrack_init(void)
1142 * entries. */ 1169 * entries. */
1143 max_factor = 4; 1170 max_factor = 4;
1144 } 1171 }
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; 1172 nf_conntrack_max = max_factor * nf_conntrack_htable_size;
1153 1173
1154 printk("nf_conntrack version %s (%u buckets, %d max)\n", 1174 printk("nf_conntrack version %s (%u buckets, %d max)\n",
@@ -1160,48 +1180,103 @@ int __init nf_conntrack_init(void)
1160 0, 0, NULL); 1180 0, 0, NULL);
1161 if (!nf_conntrack_cachep) { 1181 if (!nf_conntrack_cachep) {
1162 printk(KERN_ERR "Unable to create nf_conn slab cache\n"); 1182 printk(KERN_ERR "Unable to create nf_conn slab cache\n");
1163 goto err_free_hash; 1183 ret = -ENOMEM;
1184 goto err_cache;
1164 } 1185 }
1165 1186
1166 ret = nf_conntrack_proto_init(); 1187 ret = nf_conntrack_proto_init();
1167 if (ret < 0) 1188 if (ret < 0)
1168 goto err_free_conntrack_slab; 1189 goto err_proto;
1169
1170 ret = nf_conntrack_expect_init();
1171 if (ret < 0)
1172 goto out_fini_proto;
1173 1190
1174 ret = nf_conntrack_helper_init(); 1191 ret = nf_conntrack_helper_init();
1175 if (ret < 0) 1192 if (ret < 0)
1176 goto out_fini_expect; 1193 goto err_helper;
1177 1194
1178 ret = nf_conntrack_acct_init(); 1195 return 0;
1179 if (ret < 0) 1196
1180 goto out_fini_helper; 1197err_helper:
1198 nf_conntrack_proto_fini();
1199err_proto:
1200 kmem_cache_destroy(nf_conntrack_cachep);
1201err_cache:
1202 return ret;
1203}
1181 1204
1182 /* For use by REJECT target */ 1205static int nf_conntrack_init_net(struct net *net)
1183 rcu_assign_pointer(ip_ct_attach, nf_conntrack_attach); 1206{
1184 rcu_assign_pointer(nf_ct_destroy, destroy_conntrack); 1207 int ret;
1208
1209 atomic_set(&net->ct.count, 0);
1210 INIT_HLIST_HEAD(&net->ct.unconfirmed);
1211 net->ct.stat = alloc_percpu(struct ip_conntrack_stat);
1212 if (!net->ct.stat) {
1213 ret = -ENOMEM;
1214 goto err_stat;
1215 }
1216 ret = nf_conntrack_ecache_init(net);
1217 if (ret < 0)
1218 goto err_ecache;
1219 net->ct.hash = nf_ct_alloc_hashtable(&nf_conntrack_htable_size,
1220 &net->ct.hash_vmalloc);
1221 if (!net->ct.hash) {
1222 ret = -ENOMEM;
1223 printk(KERN_ERR "Unable to create nf_conntrack_hash\n");
1224 goto err_hash;
1225 }
1226 ret = nf_conntrack_expect_init(net);
1227 if (ret < 0)
1228 goto err_expect;
1229 ret = nf_conntrack_acct_init(net);
1230 if (ret < 0)
1231 goto err_acct;
1185 1232
1186 /* Set up fake conntrack: 1233 /* Set up fake conntrack:
1187 - to never be deleted, not in any hashes */ 1234 - to never be deleted, not in any hashes */
1235#ifdef CONFIG_NET_NS
1236 nf_conntrack_untracked.ct_net = &init_net;
1237#endif
1188 atomic_set(&nf_conntrack_untracked.ct_general.use, 1); 1238 atomic_set(&nf_conntrack_untracked.ct_general.use, 1);
1189 /* - and look it like as a confirmed connection */ 1239 /* - and look it like as a confirmed connection */
1190 set_bit(IPS_CONFIRMED_BIT, &nf_conntrack_untracked.status); 1240 set_bit(IPS_CONFIRMED_BIT, &nf_conntrack_untracked.status);
1191 1241
1192 return ret; 1242 return 0;
1193 1243
1194out_fini_helper: 1244err_acct:
1195 nf_conntrack_helper_fini(); 1245 nf_conntrack_expect_fini(net);
1196out_fini_expect: 1246err_expect:
1197 nf_conntrack_expect_fini(); 1247 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); 1248 nf_conntrack_htable_size);
1205err_out: 1249err_hash:
1206 return -ENOMEM; 1250 nf_conntrack_ecache_fini(net);
1251err_ecache:
1252 free_percpu(net->ct.stat);
1253err_stat:
1254 return ret;
1255}
1256
1257int nf_conntrack_init(struct net *net)
1258{
1259 int ret;
1260
1261 if (net_eq(net, &init_net)) {
1262 ret = nf_conntrack_init_init_net();
1263 if (ret < 0)
1264 goto out_init_net;
1265 }
1266 ret = nf_conntrack_init_net(net);
1267 if (ret < 0)
1268 goto out_net;
1269
1270 if (net_eq(net, &init_net)) {
1271 /* For use by REJECT target */
1272 rcu_assign_pointer(ip_ct_attach, nf_conntrack_attach);
1273 rcu_assign_pointer(nf_ct_destroy, destroy_conntrack);
1274 }
1275 return 0;
1276
1277out_net:
1278 if (net_eq(net, &init_net))
1279 nf_conntrack_cleanup_init_net();
1280out_init_net:
1281 return ret;
1207} 1282}
diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c
index 83c41ac3505..a5f5e2e65d1 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 e8f0dead267..37a703bc3b8 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 bb20672fe03..4f7107107e9 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 2f83c158934..c1504f71cdf 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 8e0b4c8f62a..9c06b9f86ad 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 1b1226d6653..20633fdf7e6 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 a8752031adc..08e82d64eb6 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;
@@ -689,71 +689,6 @@ ctnetlink_parse_tuple(struct nlattr *cda[], struct nf_conntrack_tuple *tuple,
689 return 0; 689 return 0;
690} 690}
691 691
692#ifdef CONFIG_NF_NAT_NEEDED
693static const struct nla_policy protonat_nla_policy[CTA_PROTONAT_MAX+1] = {
694 [CTA_PROTONAT_PORT_MIN] = { .type = NLA_U16 },
695 [CTA_PROTONAT_PORT_MAX] = { .type = NLA_U16 },
696};
697
698static int nfnetlink_parse_nat_proto(struct nlattr *attr,
699 const struct nf_conn *ct,
700 struct nf_nat_range *range)
701{
702 struct nlattr *tb[CTA_PROTONAT_MAX+1];
703 const struct nf_nat_protocol *npt;
704 int err;
705
706 err = nla_parse_nested(tb, CTA_PROTONAT_MAX, attr, protonat_nla_policy);
707 if (err < 0)
708 return err;
709
710 npt = nf_nat_proto_find_get(nf_ct_protonum(ct));
711 if (npt->nlattr_to_range)
712 err = npt->nlattr_to_range(tb, range);
713 nf_nat_proto_put(npt);
714 return err;
715}
716
717static const struct nla_policy nat_nla_policy[CTA_NAT_MAX+1] = {
718 [CTA_NAT_MINIP] = { .type = NLA_U32 },
719 [CTA_NAT_MAXIP] = { .type = NLA_U32 },
720};
721
722static inline int
723nfnetlink_parse_nat(struct nlattr *nat,
724 const struct nf_conn *ct, struct nf_nat_range *range)
725{
726 struct nlattr *tb[CTA_NAT_MAX+1];
727 int err;
728
729 memset(range, 0, sizeof(*range));
730
731 err = nla_parse_nested(tb, CTA_NAT_MAX, nat, nat_nla_policy);
732 if (err < 0)
733 return err;
734
735 if (tb[CTA_NAT_MINIP])
736 range->min_ip = nla_get_be32(tb[CTA_NAT_MINIP]);
737
738 if (!tb[CTA_NAT_MAXIP])
739 range->max_ip = range->min_ip;
740 else
741 range->max_ip = nla_get_be32(tb[CTA_NAT_MAXIP]);
742
743 if (range->min_ip)
744 range->flags |= IP_NAT_RANGE_MAP_IPS;
745
746 if (!tb[CTA_NAT_PROTO])
747 return 0;
748
749 err = nfnetlink_parse_nat_proto(tb[CTA_NAT_PROTO], ct, range);
750 if (err < 0)
751 return err;
752
753 return 0;
754}
755#endif
756
757static inline int 692static inline int
758ctnetlink_parse_help(struct nlattr *attr, char **helper_name) 693ctnetlink_parse_help(struct nlattr *attr, char **helper_name)
759{ 694{
@@ -794,14 +729,14 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
794 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, u3); 729 err = ctnetlink_parse_tuple(cda, &tuple, CTA_TUPLE_REPLY, u3);
795 else { 730 else {
796 /* Flush the whole table */ 731 /* Flush the whole table */
797 nf_conntrack_flush(); 732 nf_conntrack_flush(&init_net);
798 return 0; 733 return 0;
799 } 734 }
800 735
801 if (err < 0) 736 if (err < 0)
802 return err; 737 return err;
803 738
804 h = nf_conntrack_find_get(&tuple); 739 h = nf_conntrack_find_get(&init_net, &tuple);
805 if (!h) 740 if (!h)
806 return -ENOENT; 741 return -ENOENT;
807 742
@@ -847,7 +782,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
847 if (err < 0) 782 if (err < 0)
848 return err; 783 return err;
849 784
850 h = nf_conntrack_find_get(&tuple); 785 h = nf_conntrack_find_get(&init_net, &tuple);
851 if (!h) 786 if (!h)
852 return -ENOENT; 787 return -ENOENT;
853 788
@@ -879,6 +814,34 @@ out:
879} 814}
880 815
881static int 816static int
817ctnetlink_parse_nat_setup(struct nf_conn *ct,
818 enum nf_nat_manip_type manip,
819 struct nlattr *attr)
820{
821 typeof(nfnetlink_parse_nat_setup_hook) parse_nat_setup;
822
823 parse_nat_setup = rcu_dereference(nfnetlink_parse_nat_setup_hook);
824 if (!parse_nat_setup) {
825#ifdef CONFIG_KMOD
826 rcu_read_unlock();
827 nfnl_unlock();
828 if (request_module("nf-nat-ipv4") < 0) {
829 nfnl_lock();
830 rcu_read_lock();
831 return -EOPNOTSUPP;
832 }
833 nfnl_lock();
834 rcu_read_lock();
835 if (nfnetlink_parse_nat_setup_hook)
836 return -EAGAIN;
837#endif
838 return -EOPNOTSUPP;
839 }
840
841 return parse_nat_setup(ct, manip, attr);
842}
843
844static int
882ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[]) 845ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[])
883{ 846{
884 unsigned long d; 847 unsigned long d;
@@ -897,31 +860,6 @@ ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[])
897 /* ASSURED bit can only be set */ 860 /* ASSURED bit can only be set */
898 return -EBUSY; 861 return -EBUSY;
899 862
900 if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) {
901#ifndef CONFIG_NF_NAT_NEEDED
902 return -EOPNOTSUPP;
903#else
904 struct nf_nat_range range;
905
906 if (cda[CTA_NAT_DST]) {
907 if (nfnetlink_parse_nat(cda[CTA_NAT_DST], ct,
908 &range) < 0)
909 return -EINVAL;
910 if (nf_nat_initialized(ct, IP_NAT_MANIP_DST))
911 return -EEXIST;
912 nf_nat_setup_info(ct, &range, IP_NAT_MANIP_DST);
913 }
914 if (cda[CTA_NAT_SRC]) {
915 if (nfnetlink_parse_nat(cda[CTA_NAT_SRC], ct,
916 &range) < 0)
917 return -EINVAL;
918 if (nf_nat_initialized(ct, IP_NAT_MANIP_SRC))
919 return -EEXIST;
920 nf_nat_setup_info(ct, &range, IP_NAT_MANIP_SRC);
921 }
922#endif
923 }
924
925 /* Be careful here, modifying NAT bits can screw up things, 863 /* Be careful here, modifying NAT bits can screw up things,
926 * so don't let users modify them directly if they don't pass 864 * so don't let users modify them directly if they don't pass
927 * nf_nat_range. */ 865 * nf_nat_range. */
@@ -929,6 +867,31 @@ ctnetlink_change_status(struct nf_conn *ct, struct nlattr *cda[])
929 return 0; 867 return 0;
930} 868}
931 869
870static int
871ctnetlink_change_nat(struct nf_conn *ct, struct nlattr *cda[])
872{
873#ifdef CONFIG_NF_NAT_NEEDED
874 int ret;
875
876 if (cda[CTA_NAT_DST]) {
877 ret = ctnetlink_parse_nat_setup(ct,
878 IP_NAT_MANIP_DST,
879 cda[CTA_NAT_DST]);
880 if (ret < 0)
881 return ret;
882 }
883 if (cda[CTA_NAT_SRC]) {
884 ret = ctnetlink_parse_nat_setup(ct,
885 IP_NAT_MANIP_SRC,
886 cda[CTA_NAT_SRC]);
887 if (ret < 0)
888 return ret;
889 }
890 return 0;
891#else
892 return -EOPNOTSUPP;
893#endif
894}
932 895
933static inline int 896static inline int
934ctnetlink_change_helper(struct nf_conn *ct, struct nlattr *cda[]) 897ctnetlink_change_helper(struct nf_conn *ct, struct nlattr *cda[])
@@ -1125,7 +1088,7 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
1125 struct nf_conn_help *help; 1088 struct nf_conn_help *help;
1126 struct nf_conntrack_helper *helper; 1089 struct nf_conntrack_helper *helper;
1127 1090
1128 ct = nf_conntrack_alloc(otuple, rtuple, GFP_KERNEL); 1091 ct = nf_conntrack_alloc(&init_net, otuple, rtuple, GFP_KERNEL);
1129 if (ct == NULL || IS_ERR(ct)) 1092 if (ct == NULL || IS_ERR(ct))
1130 return -ENOMEM; 1093 return -ENOMEM;
1131 1094
@@ -1157,6 +1120,14 @@ ctnetlink_create_conntrack(struct nlattr *cda[],
1157 } 1120 }
1158 } 1121 }
1159 1122
1123 if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) {
1124 err = ctnetlink_change_nat(ct, cda);
1125 if (err < 0) {
1126 rcu_read_unlock();
1127 goto err;
1128 }
1129 }
1130
1160 if (cda[CTA_PROTOINFO]) { 1131 if (cda[CTA_PROTOINFO]) {
1161 err = ctnetlink_change_protoinfo(ct, cda); 1132 err = ctnetlink_change_protoinfo(ct, cda);
1162 if (err < 0) { 1133 if (err < 0) {
@@ -1213,9 +1184,9 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
1213 1184
1214 spin_lock_bh(&nf_conntrack_lock); 1185 spin_lock_bh(&nf_conntrack_lock);
1215 if (cda[CTA_TUPLE_ORIG]) 1186 if (cda[CTA_TUPLE_ORIG])
1216 h = __nf_conntrack_find(&otuple); 1187 h = __nf_conntrack_find(&init_net, &otuple);
1217 else if (cda[CTA_TUPLE_REPLY]) 1188 else if (cda[CTA_TUPLE_REPLY])
1218 h = __nf_conntrack_find(&rtuple); 1189 h = __nf_conntrack_find(&init_net, &rtuple);
1219 1190
1220 if (h == NULL) { 1191 if (h == NULL) {
1221 struct nf_conntrack_tuple master; 1192 struct nf_conntrack_tuple master;
@@ -1230,7 +1201,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
1230 if (err < 0) 1201 if (err < 0)
1231 goto out_unlock; 1202 goto out_unlock;
1232 1203
1233 master_h = __nf_conntrack_find(&master); 1204 master_h = __nf_conntrack_find(&init_net, &master);
1234 if (master_h == NULL) { 1205 if (master_h == NULL) {
1235 err = -ENOENT; 1206 err = -ENOENT;
1236 goto out_unlock; 1207 goto out_unlock;
@@ -1458,6 +1429,7 @@ static int ctnetlink_exp_done(struct netlink_callback *cb)
1458static int 1429static int
1459ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb) 1430ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
1460{ 1431{
1432 struct net *net = &init_net;
1461 struct nf_conntrack_expect *exp, *last; 1433 struct nf_conntrack_expect *exp, *last;
1462 struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh); 1434 struct nfgenmsg *nfmsg = NLMSG_DATA(cb->nlh);
1463 struct hlist_node *n; 1435 struct hlist_node *n;
@@ -1467,7 +1439,7 @@ ctnetlink_exp_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
1467 last = (struct nf_conntrack_expect *)cb->args[1]; 1439 last = (struct nf_conntrack_expect *)cb->args[1];
1468 for (; cb->args[0] < nf_ct_expect_hsize; cb->args[0]++) { 1440 for (; cb->args[0] < nf_ct_expect_hsize; cb->args[0]++) {
1469restart: 1441restart:
1470 hlist_for_each_entry(exp, n, &nf_ct_expect_hash[cb->args[0]], 1442 hlist_for_each_entry(exp, n, &net->ct.expect_hash[cb->args[0]],
1471 hnode) { 1443 hnode) {
1472 if (l3proto && exp->tuple.src.l3num != l3proto) 1444 if (l3proto && exp->tuple.src.l3num != l3proto)
1473 continue; 1445 continue;
@@ -1529,7 +1501,7 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
1529 if (err < 0) 1501 if (err < 0)
1530 return err; 1502 return err;
1531 1503
1532 exp = nf_ct_expect_find_get(&tuple); 1504 exp = nf_ct_expect_find_get(&init_net, &tuple);
1533 if (!exp) 1505 if (!exp)
1534 return -ENOENT; 1506 return -ENOENT;
1535 1507
@@ -1583,7 +1555,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1583 return err; 1555 return err;
1584 1556
1585 /* bump usage count to 2 */ 1557 /* bump usage count to 2 */
1586 exp = nf_ct_expect_find_get(&tuple); 1558 exp = nf_ct_expect_find_get(&init_net, &tuple);
1587 if (!exp) 1559 if (!exp)
1588 return -ENOENT; 1560 return -ENOENT;
1589 1561
@@ -1613,7 +1585,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1613 } 1585 }
1614 for (i = 0; i < nf_ct_expect_hsize; i++) { 1586 for (i = 0; i < nf_ct_expect_hsize; i++) {
1615 hlist_for_each_entry_safe(exp, n, next, 1587 hlist_for_each_entry_safe(exp, n, next,
1616 &nf_ct_expect_hash[i], 1588 &init_net.ct.expect_hash[i],
1617 hnode) { 1589 hnode) {
1618 m_help = nfct_help(exp->master); 1590 m_help = nfct_help(exp->master);
1619 if (m_help->helper == h 1591 if (m_help->helper == h
@@ -1629,7 +1601,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1629 spin_lock_bh(&nf_conntrack_lock); 1601 spin_lock_bh(&nf_conntrack_lock);
1630 for (i = 0; i < nf_ct_expect_hsize; i++) { 1602 for (i = 0; i < nf_ct_expect_hsize; i++) {
1631 hlist_for_each_entry_safe(exp, n, next, 1603 hlist_for_each_entry_safe(exp, n, next,
1632 &nf_ct_expect_hash[i], 1604 &init_net.ct.expect_hash[i],
1633 hnode) { 1605 hnode) {
1634 if (del_timer(&exp->timeout)) { 1606 if (del_timer(&exp->timeout)) {
1635 nf_ct_unlink_expect(exp); 1607 nf_ct_unlink_expect(exp);
@@ -1670,7 +1642,7 @@ ctnetlink_create_expect(struct nlattr *cda[], u_int8_t u3)
1670 return err; 1642 return err;
1671 1643
1672 /* Look for master conntrack of this expectation */ 1644 /* Look for master conntrack of this expectation */
1673 h = nf_conntrack_find_get(&master_tuple); 1645 h = nf_conntrack_find_get(&init_net, &master_tuple);
1674 if (!h) 1646 if (!h)
1675 return -ENOENT; 1647 return -ENOENT;
1676 ct = nf_ct_tuplehash_to_ctrack(h); 1648 ct = nf_ct_tuplehash_to_ctrack(h);
@@ -1724,7 +1696,7 @@ ctnetlink_new_expect(struct sock *ctnl, struct sk_buff *skb,
1724 return err; 1696 return err;
1725 1697
1726 spin_lock_bh(&nf_conntrack_lock); 1698 spin_lock_bh(&nf_conntrack_lock);
1727 exp = __nf_ct_expect_find(&tuple); 1699 exp = __nf_ct_expect_find(&init_net, &tuple);
1728 1700
1729 if (!exp) { 1701 if (!exp) {
1730 spin_unlock_bh(&nf_conntrack_lock); 1702 spin_unlock_bh(&nf_conntrack_lock);
diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c
index 97e54b0e43a..1bc3001d182 100644
--- a/net/netfilter/nf_conntrack_pptp.c
+++ b/net/netfilter/nf_conntrack_pptp.c
@@ -65,7 +65,7 @@ void
65 struct nf_conntrack_expect *exp) __read_mostly; 65 struct nf_conntrack_expect *exp) __read_mostly;
66EXPORT_SYMBOL_GPL(nf_nat_pptp_hook_expectfn); 66EXPORT_SYMBOL_GPL(nf_nat_pptp_hook_expectfn);
67 67
68#ifdef DEBUG 68#if defined(DEBUG) || defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
69/* PptpControlMessageType names */ 69/* PptpControlMessageType names */
70const char *const pptp_msg_name[] = { 70const char *const pptp_msg_name[] = {
71 "UNKNOWN_MESSAGE", 71 "UNKNOWN_MESSAGE",
@@ -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 a49fc932629..a59a307e685 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 e7866dd3cde..8fcf1762fab 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 e31b0e7bd0b..dbe680af85d 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 654a4f7f12c..a2cdbcbf64c 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 30aa5b94a77..ae8c2609e23 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 6f61261888e..f947ec41e39 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 8b21762e65d..7c2ca48698b 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 1fa62f3c24f..d22d839e4f9 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 2f9bbc058b4..6813f1c8863 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 8509db14670..98106d4e89f 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 196269c1e58..bf6609978af 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 9fda6ee95a3..fa8ae5d2659 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 582ec3efc8a..4f2310c93e0 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 01489681fa9..8ab829f8657 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 00000000000..cdc97f3105a
--- /dev/null
+++ b/net/netfilter/nf_tproxy_core.c
@@ -0,0 +1,95 @@
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
15#include <linux/net.h>
16#include <linux/if.h>
17#include <linux/netdevice.h>
18#include <net/udp.h>
19#include <net/netfilter/nf_tproxy_core.h>
20
21struct sock *
22nf_tproxy_get_sock_v4(struct net *net, const u8 protocol,
23 const __be32 saddr, const __be32 daddr,
24 const __be16 sport, const __be16 dport,
25 const struct net_device *in, bool listening_only)
26{
27 struct sock *sk;
28
29 /* look up socket */
30 switch (protocol) {
31 case IPPROTO_TCP:
32 if (listening_only)
33 sk = __inet_lookup_listener(net, &tcp_hashinfo,
34 daddr, ntohs(dport),
35 in->ifindex);
36 else
37 sk = __inet_lookup(net, &tcp_hashinfo,
38 saddr, sport, daddr, dport,
39 in->ifindex);
40 break;
41 case IPPROTO_UDP:
42 sk = udp4_lib_lookup(net, saddr, sport, daddr, dport,
43 in->ifindex);
44 break;
45 default:
46 WARN_ON(1);
47 sk = NULL;
48 }
49
50 pr_debug("tproxy socket lookup: proto %u %08x:%u -> %08x:%u, listener only: %d, sock %p\n",
51 protocol, ntohl(saddr), ntohs(sport), ntohl(daddr), ntohs(dport), listening_only, sk);
52
53 return sk;
54}
55EXPORT_SYMBOL_GPL(nf_tproxy_get_sock_v4);
56
57static void
58nf_tproxy_destructor(struct sk_buff *skb)
59{
60 struct sock *sk = skb->sk;
61
62 skb->sk = NULL;
63 skb->destructor = NULL;
64
65 if (sk)
66 nf_tproxy_put_sock(sk);
67}
68
69/* consumes sk */
70int
71nf_tproxy_assign_sock(struct sk_buff *skb, struct sock *sk)
72{
73 if (inet_sk(sk)->transparent) {
74 skb->sk = sk;
75 skb->destructor = nf_tproxy_destructor;
76 return 1;
77 } else
78 nf_tproxy_put_sock(sk);
79
80 return 0;
81}
82EXPORT_SYMBOL_GPL(nf_tproxy_assign_sock);
83
84static int __init nf_tproxy_init(void)
85{
86 pr_info("NF_TPROXY: Transparent proxy support initialized, version 4.1.0\n");
87 pr_info("NF_TPROXY: Copyright (c) 2006-2007 BalaBit IT Ltd.\n");
88 return 0;
89}
90
91module_init(nf_tproxy_init);
92
93MODULE_LICENSE("GPL");
94MODULE_AUTHOR("Krisztian Kovacs");
95MODULE_DESCRIPTION("Transparent proxy support core routines");
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index b75c9c4a995..4739f9f961d 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -44,15 +44,17 @@ static struct sock *nfnl = NULL;
44static const struct nfnetlink_subsystem *subsys_table[NFNL_SUBSYS_COUNT]; 44static const struct nfnetlink_subsystem *subsys_table[NFNL_SUBSYS_COUNT];
45static DEFINE_MUTEX(nfnl_mutex); 45static DEFINE_MUTEX(nfnl_mutex);
46 46
47static inline void nfnl_lock(void) 47void nfnl_lock(void)
48{ 48{
49 mutex_lock(&nfnl_mutex); 49 mutex_lock(&nfnl_mutex);
50} 50}
51EXPORT_SYMBOL_GPL(nfnl_lock);
51 52
52static inline void nfnl_unlock(void) 53void nfnl_unlock(void)
53{ 54{
54 mutex_unlock(&nfnl_mutex); 55 mutex_unlock(&nfnl_mutex);
55} 56}
57EXPORT_SYMBOL_GPL(nfnl_unlock);
56 58
57int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n) 59int nfnetlink_subsys_register(const struct nfnetlink_subsystem *n)
58{ 60{
@@ -132,6 +134,7 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
132 return 0; 134 return 0;
133 135
134 type = nlh->nlmsg_type; 136 type = nlh->nlmsg_type;
137replay:
135 ss = nfnetlink_get_subsys(type); 138 ss = nfnetlink_get_subsys(type);
136 if (!ss) { 139 if (!ss) {
137#ifdef CONFIG_KMOD 140#ifdef CONFIG_KMOD
@@ -165,7 +168,10 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
165 } else 168 } else
166 return -EINVAL; 169 return -EINVAL;
167 170
168 return nc->call(nfnl, skb, nlh, cda); 171 err = nc->call(nfnl, skb, nlh, cda);
172 if (err == -EAGAIN)
173 goto replay;
174 return err;
169 } 175 }
170} 176}
171 177
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 9a35b57ab76..41e0105d382 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 5d75cd86ebb..89837a4eef7 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 77a52bf8322..011bc80dd2a 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 5fecfb4794b..d6e5ab46327 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 76ca1f2421e..b54c3756fdc 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 97efd74c04f..6a347e768f8 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 f9ce20b5898..67574bcfb8a 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 19ae8efae65..50e3a52d3b3 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 beb24d19a56..2cc1fff4930 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 6c9de611eb8..e7a0a54fd4e 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 64d6ad38029..43f5676b1af 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 94f87ee7552..7a6f9e6f5df 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 beb5094703c..4f3b1f80879 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 9685b6fcbc8..9dd8c8ef63e 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 00000000000..1340c2fa362
--- /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 30dab79a343..fbb04b86c46 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 89f47364e84..e82179832ac 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 3e39c4fe193..955e6598a7f 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 70907f6baac..7f404cc64c8 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 aaa1b96691f..86cacab7a4a 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 d61412f58ef..0b7139f3dd7 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 8b6522186d9..e5d3e867328 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 26f4aab9c42..c3f8085460d 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 a133eb9b23e..609439967c2 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 d9418a26781..6fc4292d46e 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 dada2905d66..64fc7f27722 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 c63e9333c75..6f62c36948d 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 b8640f97295..c4871ca6c86 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 aad9ab8d204..c908d69a559 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 b3e96a0ec17..c2007116ce5 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 9f78f6120fb..10b9e34bbc5 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 fd88c489b70..d06bb2dd390 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 9059c16144c..f19ebd9b78f 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 4ec1094bda9..1bcdfc12cf5 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 7936f7e2325..69da1d3a1d8 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 d351582b2a3..328bd20ddd2 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 3b021d0c522..c84fce5e0f3 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 ebd84f1b4f6..220a1d588ee 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 7df1627c536..67419287bc7 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 3974d7cae5c..4ebd4ca9a99 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 e6e4681fa04..e223cb43ae8 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 00000000000..02a8fed2108
--- /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 a776dc36a19..4c946cbd731 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 43133080da7..0d75141139d 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 4903182a062..b4d77411131 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 6771bf01275..4809b34b10f 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 951b06b8d70..1ebdc4934ee 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 9f328593287..29375ba8db7 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 627e0f336d5..24a52762450 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/netlabel/Makefile b/net/netlabel/Makefile
index 8af18c0a47d..ea750e9df65 100644
--- a/net/netlabel/Makefile
+++ b/net/netlabel/Makefile
@@ -5,7 +5,8 @@
5# 5#
6 6
7# base objects 7# base objects
8obj-y := netlabel_user.o netlabel_kapi.o netlabel_domainhash.o 8obj-y := netlabel_user.o netlabel_kapi.o
9obj-y += netlabel_domainhash.o netlabel_addrlist.o
9 10
10# management objects 11# management objects
11obj-y += netlabel_mgmt.o 12obj-y += netlabel_mgmt.o
diff --git a/net/netlabel/netlabel_addrlist.c b/net/netlabel/netlabel_addrlist.c
new file mode 100644
index 00000000000..b0925a30335
--- /dev/null
+++ b/net/netlabel/netlabel_addrlist.c
@@ -0,0 +1,388 @@
1/*
2 * NetLabel Network Address Lists
3 *
4 * This file contains network address list functions used to manage ordered
5 * lists of network addresses for use by the NetLabel subsystem. The NetLabel
6 * system manages static and dynamic label mappings for network protocols such
7 * as CIPSO and RIPSO.
8 *
9 * Author: Paul Moore <paul.moore@hp.com>
10 *
11 */
12
13/*
14 * (c) Copyright Hewlett-Packard Development Company, L.P., 2008
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
24 * the GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 *
30 */
31
32#include <linux/types.h>
33#include <linux/rcupdate.h>
34#include <linux/list.h>
35#include <linux/spinlock.h>
36#include <linux/in.h>
37#include <linux/in6.h>
38#include <linux/ip.h>
39#include <linux/ipv6.h>
40#include <net/ip.h>
41#include <net/ipv6.h>
42#include <linux/audit.h>
43
44#include "netlabel_addrlist.h"
45
46/*
47 * Address List Functions
48 */
49
50/**
51 * netlbl_af4list_search - Search for a matching IPv4 address entry
52 * @addr: IPv4 address
53 * @head: the list head
54 *
55 * Description:
56 * Searches the IPv4 address list given by @head. If a matching address entry
57 * is found it is returned, otherwise NULL is returned. The caller is
58 * responsible for calling the rcu_read_[un]lock() functions.
59 *
60 */
61struct netlbl_af4list *netlbl_af4list_search(__be32 addr,
62 struct list_head *head)
63{
64 struct netlbl_af4list *iter;
65
66 list_for_each_entry_rcu(iter, head, list)
67 if (iter->valid && (addr & iter->mask) == iter->addr)
68 return iter;
69
70 return NULL;
71}
72
73/**
74 * netlbl_af4list_search_exact - Search for an exact IPv4 address entry
75 * @addr: IPv4 address
76 * @mask: IPv4 address mask
77 * @head: the list head
78 *
79 * Description:
80 * Searches the IPv4 address list given by @head. If an exact match if found
81 * it is returned, otherwise NULL is returned. The caller is responsible for
82 * calling the rcu_read_[un]lock() functions.
83 *
84 */
85struct netlbl_af4list *netlbl_af4list_search_exact(__be32 addr,
86 __be32 mask,
87 struct list_head *head)
88{
89 struct netlbl_af4list *iter;
90
91 list_for_each_entry_rcu(iter, head, list)
92 if (iter->valid && iter->addr == addr && iter->mask == mask)
93 return iter;
94
95 return NULL;
96}
97
98
99#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
100/**
101 * netlbl_af6list_search - Search for a matching IPv6 address entry
102 * @addr: IPv6 address
103 * @head: the list head
104 *
105 * Description:
106 * Searches the IPv6 address list given by @head. If a matching address entry
107 * is found it is returned, otherwise NULL is returned. The caller is
108 * responsible for calling the rcu_read_[un]lock() functions.
109 *
110 */
111struct netlbl_af6list *netlbl_af6list_search(const struct in6_addr *addr,
112 struct list_head *head)
113{
114 struct netlbl_af6list *iter;
115
116 list_for_each_entry_rcu(iter, head, list)
117 if (iter->valid &&
118 ipv6_masked_addr_cmp(&iter->addr, &iter->mask, addr) == 0)
119 return iter;
120
121 return NULL;
122}
123
124/**
125 * netlbl_af6list_search_exact - Search for an exact IPv6 address entry
126 * @addr: IPv6 address
127 * @mask: IPv6 address mask
128 * @head: the list head
129 *
130 * Description:
131 * Searches the IPv6 address list given by @head. If an exact match if found
132 * it is returned, otherwise NULL is returned. The caller is responsible for
133 * calling the rcu_read_[un]lock() functions.
134 *
135 */
136struct netlbl_af6list *netlbl_af6list_search_exact(const struct in6_addr *addr,
137 const struct in6_addr *mask,
138 struct list_head *head)
139{
140 struct netlbl_af6list *iter;
141
142 list_for_each_entry_rcu(iter, head, list)
143 if (iter->valid &&
144 ipv6_addr_equal(&iter->addr, addr) &&
145 ipv6_addr_equal(&iter->mask, mask))
146 return iter;
147
148 return NULL;
149}
150#endif /* IPv6 */
151
152/**
153 * netlbl_af4list_add - Add a new IPv4 address entry to a list
154 * @entry: address entry
155 * @head: the list head
156 *
157 * Description:
158 * Add a new address entry to the list pointed to by @head. On success zero is
159 * returned, otherwise a negative value is returned. The caller is responsible
160 * for calling the necessary locking functions.
161 *
162 */
163int netlbl_af4list_add(struct netlbl_af4list *entry, struct list_head *head)
164{
165 struct netlbl_af4list *iter;
166
167 iter = netlbl_af4list_search(entry->addr, head);
168 if (iter != NULL &&
169 iter->addr == entry->addr && iter->mask == entry->mask)
170 return -EEXIST;
171
172 /* in order to speed up address searches through the list (the common
173 * case) we need to keep the list in order based on the size of the
174 * address mask such that the entry with the widest mask (smallest
175 * numerical value) appears first in the list */
176 list_for_each_entry_rcu(iter, head, list)
177 if (iter->valid &&
178 ntohl(entry->mask) > ntohl(iter->mask)) {
179 __list_add_rcu(&entry->list,
180 iter->list.prev,
181 &iter->list);
182 return 0;
183 }
184 list_add_tail_rcu(&entry->list, head);
185 return 0;
186}
187
188#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
189/**
190 * netlbl_af6list_add - Add a new IPv6 address entry to a list
191 * @entry: address entry
192 * @head: the list head
193 *
194 * Description:
195 * Add a new address entry to the list pointed to by @head. On success zero is
196 * returned, otherwise a negative value is returned. The caller is responsible
197 * for calling the necessary locking functions.
198 *
199 */
200int netlbl_af6list_add(struct netlbl_af6list *entry, struct list_head *head)
201{
202 struct netlbl_af6list *iter;
203
204 iter = netlbl_af6list_search(&entry->addr, head);
205 if (iter != NULL &&
206 ipv6_addr_equal(&iter->addr, &entry->addr) &&
207 ipv6_addr_equal(&iter->mask, &entry->mask))
208 return -EEXIST;
209
210 /* in order to speed up address searches through the list (the common
211 * case) we need to keep the list in order based on the size of the
212 * address mask such that the entry with the widest mask (smallest
213 * numerical value) appears first in the list */
214 list_for_each_entry_rcu(iter, head, list)
215 if (iter->valid &&
216 ipv6_addr_cmp(&entry->mask, &iter->mask) > 0) {
217 __list_add_rcu(&entry->list,
218 iter->list.prev,
219 &iter->list);
220 return 0;
221 }
222 list_add_tail_rcu(&entry->list, head);
223 return 0;
224}
225#endif /* IPv6 */
226
227/**
228 * netlbl_af4list_remove_entry - Remove an IPv4 address entry
229 * @entry: address entry
230 *
231 * Description:
232 * Remove the specified IP address entry. The caller is responsible for
233 * calling the necessary locking functions.
234 *
235 */
236void netlbl_af4list_remove_entry(struct netlbl_af4list *entry)
237{
238 entry->valid = 0;
239 list_del_rcu(&entry->list);
240}
241
242/**
243 * netlbl_af4list_remove - Remove an IPv4 address entry
244 * @addr: IP address
245 * @mask: IP address mask
246 * @head: the list head
247 *
248 * Description:
249 * Remove an IP address entry from the list pointed to by @head. Returns the
250 * entry on success, NULL on failure. The caller is responsible for calling
251 * the necessary locking functions.
252 *
253 */
254struct netlbl_af4list *netlbl_af4list_remove(__be32 addr, __be32 mask,
255 struct list_head *head)
256{
257 struct netlbl_af4list *entry;
258
259 entry = netlbl_af4list_search(addr, head);
260 if (entry != NULL && entry->addr == addr && entry->mask == mask) {
261 netlbl_af4list_remove_entry(entry);
262 return entry;
263 }
264
265 return NULL;
266}
267
268#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
269/**
270 * netlbl_af6list_remove_entry - Remove an IPv6 address entry
271 * @entry: address entry
272 *
273 * Description:
274 * Remove the specified IP address entry. The caller is responsible for
275 * calling the necessary locking functions.
276 *
277 */
278void netlbl_af6list_remove_entry(struct netlbl_af6list *entry)
279{
280 entry->valid = 0;
281 list_del_rcu(&entry->list);
282}
283
284/**
285 * netlbl_af6list_remove - Remove an IPv6 address entry
286 * @addr: IP address
287 * @mask: IP address mask
288 * @head: the list head
289 *
290 * Description:
291 * Remove an IP address entry from the list pointed to by @head. Returns the
292 * entry on success, NULL on failure. The caller is responsible for calling
293 * the necessary locking functions.
294 *
295 */
296struct netlbl_af6list *netlbl_af6list_remove(const struct in6_addr *addr,
297 const struct in6_addr *mask,
298 struct list_head *head)
299{
300 struct netlbl_af6list *entry;
301
302 entry = netlbl_af6list_search(addr, head);
303 if (entry != NULL &&
304 ipv6_addr_equal(&entry->addr, addr) &&
305 ipv6_addr_equal(&entry->mask, mask)) {
306 netlbl_af6list_remove_entry(entry);
307 return entry;
308 }
309
310 return NULL;
311}
312#endif /* IPv6 */
313
314/*
315 * Audit Helper Functions
316 */
317
318/**
319 * netlbl_af4list_audit_addr - Audit an IPv4 address
320 * @audit_buf: audit buffer
321 * @src: true if source address, false if destination
322 * @dev: network interface
323 * @addr: IP address
324 * @mask: IP address mask
325 *
326 * Description:
327 * Write the IPv4 address and address mask, if necessary, to @audit_buf.
328 *
329 */
330void netlbl_af4list_audit_addr(struct audit_buffer *audit_buf,
331 int src, const char *dev,
332 __be32 addr, __be32 mask)
333{
334 u32 mask_val = ntohl(mask);
335 char *dir = (src ? "src" : "dst");
336
337 if (dev != NULL)
338 audit_log_format(audit_buf, " netif=%s", dev);
339 audit_log_format(audit_buf, " %s=" NIPQUAD_FMT, dir, NIPQUAD(addr));
340 if (mask_val != 0xffffffff) {
341 u32 mask_len = 0;
342 while (mask_val > 0) {
343 mask_val <<= 1;
344 mask_len++;
345 }
346 audit_log_format(audit_buf, " %s_prefixlen=%d", dir, mask_len);
347 }
348}
349
350#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
351/**
352 * netlbl_af6list_audit_addr - Audit an IPv6 address
353 * @audit_buf: audit buffer
354 * @src: true if source address, false if destination
355 * @dev: network interface
356 * @addr: IP address
357 * @mask: IP address mask
358 *
359 * Description:
360 * Write the IPv6 address and address mask, if necessary, to @audit_buf.
361 *
362 */
363void netlbl_af6list_audit_addr(struct audit_buffer *audit_buf,
364 int src,
365 const char *dev,
366 const struct in6_addr *addr,
367 const struct in6_addr *mask)
368{
369 char *dir = (src ? "src" : "dst");
370
371 if (dev != NULL)
372 audit_log_format(audit_buf, " netif=%s", dev);
373 audit_log_format(audit_buf, " %s=" NIP6_FMT, dir, NIP6(*addr));
374 if (ntohl(mask->s6_addr32[3]) != 0xffffffff) {
375 u32 mask_len = 0;
376 u32 mask_val;
377 int iter = -1;
378 while (ntohl(mask->s6_addr32[++iter]) == 0xffffffff)
379 mask_len += 32;
380 mask_val = ntohl(mask->s6_addr32[iter]);
381 while (mask_val > 0) {
382 mask_val <<= 1;
383 mask_len++;
384 }
385 audit_log_format(audit_buf, " %s_prefixlen=%d", dir, mask_len);
386 }
387}
388#endif /* IPv6 */
diff --git a/net/netlabel/netlabel_addrlist.h b/net/netlabel/netlabel_addrlist.h
new file mode 100644
index 00000000000..0242bead405
--- /dev/null
+++ b/net/netlabel/netlabel_addrlist.h
@@ -0,0 +1,189 @@
1/*
2 * NetLabel Network Address Lists
3 *
4 * This file contains network address list functions used to manage ordered
5 * lists of network addresses for use by the NetLabel subsystem. The NetLabel
6 * system manages static and dynamic label mappings for network protocols such
7 * as CIPSO and RIPSO.
8 *
9 * Author: Paul Moore <paul.moore@hp.com>
10 *
11 */
12
13/*
14 * (c) Copyright Hewlett-Packard Development Company, L.P., 2008
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
24 * the GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 *
30 */
31
32#ifndef _NETLABEL_ADDRLIST_H
33#define _NETLABEL_ADDRLIST_H
34
35#include <linux/types.h>
36#include <linux/rcupdate.h>
37#include <linux/list.h>
38#include <linux/in6.h>
39#include <linux/audit.h>
40
41/**
42 * struct netlbl_af4list - NetLabel IPv4 address list
43 * @addr: IPv4 address
44 * @mask: IPv4 address mask
45 * @valid: valid flag
46 * @list: list structure, used internally
47 */
48struct netlbl_af4list {
49 __be32 addr;
50 __be32 mask;
51
52 u32 valid;
53 struct list_head list;
54};
55
56/**
57 * struct netlbl_af6list - NetLabel IPv6 address list
58 * @addr: IPv6 address
59 * @mask: IPv6 address mask
60 * @valid: valid flag
61 * @list: list structure, used internally
62 */
63struct netlbl_af6list {
64 struct in6_addr addr;
65 struct in6_addr mask;
66
67 u32 valid;
68 struct list_head list;
69};
70
71#define __af4list_entry(ptr) container_of(ptr, struct netlbl_af4list, list)
72
73static inline struct netlbl_af4list *__af4list_valid(struct list_head *s,
74 struct list_head *h)
75{
76 struct list_head *i = s;
77 struct netlbl_af4list *n = __af4list_entry(s);
78 while (i != h && !n->valid) {
79 i = i->next;
80 n = __af4list_entry(i);
81 }
82 return n;
83}
84
85static inline struct netlbl_af4list *__af4list_valid_rcu(struct list_head *s,
86 struct list_head *h)
87{
88 struct list_head *i = s;
89 struct netlbl_af4list *n = __af4list_entry(s);
90 while (i != h && !n->valid) {
91 i = rcu_dereference(i->next);
92 n = __af4list_entry(i);
93 }
94 return n;
95}
96
97#define netlbl_af4list_foreach(iter, head) \
98 for (iter = __af4list_valid((head)->next, head); \
99 prefetch(iter->list.next), &iter->list != (head); \
100 iter = __af4list_valid(iter->list.next, head))
101
102#define netlbl_af4list_foreach_rcu(iter, head) \
103 for (iter = __af4list_valid_rcu((head)->next, head); \
104 prefetch(iter->list.next), &iter->list != (head); \
105 iter = __af4list_valid_rcu(iter->list.next, head))
106
107#define netlbl_af4list_foreach_safe(iter, tmp, head) \
108 for (iter = __af4list_valid((head)->next, head), \
109 tmp = __af4list_valid(iter->list.next, head); \
110 &iter->list != (head); \
111 iter = tmp, tmp = __af4list_valid(iter->list.next, head))
112
113int netlbl_af4list_add(struct netlbl_af4list *entry,
114 struct list_head *head);
115struct netlbl_af4list *netlbl_af4list_remove(__be32 addr, __be32 mask,
116 struct list_head *head);
117void netlbl_af4list_remove_entry(struct netlbl_af4list *entry);
118struct netlbl_af4list *netlbl_af4list_search(__be32 addr,
119 struct list_head *head);
120struct netlbl_af4list *netlbl_af4list_search_exact(__be32 addr,
121 __be32 mask,
122 struct list_head *head);
123void netlbl_af4list_audit_addr(struct audit_buffer *audit_buf,
124 int src, const char *dev,
125 __be32 addr, __be32 mask);
126
127#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
128
129#define __af6list_entry(ptr) container_of(ptr, struct netlbl_af6list, list)
130
131static inline struct netlbl_af6list *__af6list_valid(struct list_head *s,
132 struct list_head *h)
133{
134 struct list_head *i = s;
135 struct netlbl_af6list *n = __af6list_entry(s);
136 while (i != h && !n->valid) {
137 i = i->next;
138 n = __af6list_entry(i);
139 }
140 return n;
141}
142
143static inline struct netlbl_af6list *__af6list_valid_rcu(struct list_head *s,
144 struct list_head *h)
145{
146 struct list_head *i = s;
147 struct netlbl_af6list *n = __af6list_entry(s);
148 while (i != h && !n->valid) {
149 i = rcu_dereference(i->next);
150 n = __af6list_entry(i);
151 }
152 return n;
153}
154
155#define netlbl_af6list_foreach(iter, head) \
156 for (iter = __af6list_valid((head)->next, head); \
157 prefetch(iter->list.next), &iter->list != (head); \
158 iter = __af6list_valid(iter->list.next, head))
159
160#define netlbl_af6list_foreach_rcu(iter, head) \
161 for (iter = __af6list_valid_rcu((head)->next, head); \
162 prefetch(iter->list.next), &iter->list != (head); \
163 iter = __af6list_valid_rcu(iter->list.next, head))
164
165#define netlbl_af6list_foreach_safe(iter, tmp, head) \
166 for (iter = __af6list_valid((head)->next, head), \
167 tmp = __af6list_valid(iter->list.next, head); \
168 &iter->list != (head); \
169 iter = tmp, tmp = __af6list_valid(iter->list.next, head))
170
171int netlbl_af6list_add(struct netlbl_af6list *entry,
172 struct list_head *head);
173struct netlbl_af6list *netlbl_af6list_remove(const struct in6_addr *addr,
174 const struct in6_addr *mask,
175 struct list_head *head);
176void netlbl_af6list_remove_entry(struct netlbl_af6list *entry);
177struct netlbl_af6list *netlbl_af6list_search(const struct in6_addr *addr,
178 struct list_head *head);
179struct netlbl_af6list *netlbl_af6list_search_exact(const struct in6_addr *addr,
180 const struct in6_addr *mask,
181 struct list_head *head);
182void netlbl_af6list_audit_addr(struct audit_buffer *audit_buf,
183 int src,
184 const char *dev,
185 const struct in6_addr *addr,
186 const struct in6_addr *mask);
187#endif /* IPV6 */
188
189#endif
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c
index 0aec318bf0e..fff32b70efa 100644
--- a/net/netlabel/netlabel_cipso_v4.c
+++ b/net/netlabel/netlabel_cipso_v4.c
@@ -43,6 +43,7 @@
43#include "netlabel_user.h" 43#include "netlabel_user.h"
44#include "netlabel_cipso_v4.h" 44#include "netlabel_cipso_v4.h"
45#include "netlabel_mgmt.h" 45#include "netlabel_mgmt.h"
46#include "netlabel_domainhash.h"
46 47
47/* Argument struct for cipso_v4_doi_walk() */ 48/* Argument struct for cipso_v4_doi_walk() */
48struct netlbl_cipsov4_doiwalk_arg { 49struct netlbl_cipsov4_doiwalk_arg {
@@ -51,6 +52,12 @@ struct netlbl_cipsov4_doiwalk_arg {
51 u32 seq; 52 u32 seq;
52}; 53};
53 54
55/* Argument struct for netlbl_domhsh_walk() */
56struct netlbl_domhsh_walk_arg {
57 struct netlbl_audit *audit_info;
58 u32 doi;
59};
60
54/* NetLabel Generic NETLINK CIPSOv4 family */ 61/* NetLabel Generic NETLINK CIPSOv4 family */
55static struct genl_family netlbl_cipsov4_gnl_family = { 62static struct genl_family netlbl_cipsov4_gnl_family = {
56 .id = GENL_ID_GENERATE, 63 .id = GENL_ID_GENERATE,
@@ -81,32 +88,6 @@ static const struct nla_policy netlbl_cipsov4_genl_policy[NLBL_CIPSOV4_A_MAX + 1
81 */ 88 */
82 89
83/** 90/**
84 * netlbl_cipsov4_doi_free - Frees a CIPSO V4 DOI definition
85 * @entry: the entry's RCU field
86 *
87 * Description:
88 * This function is designed to be used as a callback to the call_rcu()
89 * function so that the memory allocated to the DOI definition can be released
90 * safely.
91 *
92 */
93void netlbl_cipsov4_doi_free(struct rcu_head *entry)
94{
95 struct cipso_v4_doi *ptr;
96
97 ptr = container_of(entry, struct cipso_v4_doi, rcu);
98 switch (ptr->type) {
99 case CIPSO_V4_MAP_STD:
100 kfree(ptr->map.std->lvl.cipso);
101 kfree(ptr->map.std->lvl.local);
102 kfree(ptr->map.std->cat.cipso);
103 kfree(ptr->map.std->cat.local);
104 break;
105 }
106 kfree(ptr);
107}
108
109/**
110 * netlbl_cipsov4_add_common - Parse the common sections of a ADD message 91 * netlbl_cipsov4_add_common - Parse the common sections of a ADD message
111 * @info: the Generic NETLINK info block 92 * @info: the Generic NETLINK info block
112 * @doi_def: the CIPSO V4 DOI definition 93 * @doi_def: the CIPSO V4 DOI definition
@@ -151,9 +132,9 @@ static int netlbl_cipsov4_add_common(struct genl_info *info,
151 * @info: the Generic NETLINK info block 132 * @info: the Generic NETLINK info block
152 * 133 *
153 * Description: 134 * Description:
154 * Create a new CIPSO_V4_MAP_STD DOI definition based on the given ADD message 135 * Create a new CIPSO_V4_MAP_TRANS DOI definition based on the given ADD
155 * and add it to the CIPSO V4 engine. Return zero on success and non-zero on 136 * message and add it to the CIPSO V4 engine. Return zero on success and
156 * error. 137 * non-zero on error.
157 * 138 *
158 */ 139 */
159static int netlbl_cipsov4_add_std(struct genl_info *info) 140static int netlbl_cipsov4_add_std(struct genl_info *info)
@@ -183,7 +164,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
183 ret_val = -ENOMEM; 164 ret_val = -ENOMEM;
184 goto add_std_failure; 165 goto add_std_failure;
185 } 166 }
186 doi_def->type = CIPSO_V4_MAP_STD; 167 doi_def->type = CIPSO_V4_MAP_TRANS;
187 168
188 ret_val = netlbl_cipsov4_add_common(info, doi_def); 169 ret_val = netlbl_cipsov4_add_common(info, doi_def);
189 if (ret_val != 0) 170 if (ret_val != 0)
@@ -342,7 +323,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
342 323
343add_std_failure: 324add_std_failure:
344 if (doi_def) 325 if (doi_def)
345 netlbl_cipsov4_doi_free(&doi_def->rcu); 326 cipso_v4_doi_free(doi_def);
346 return ret_val; 327 return ret_val;
347} 328}
348 329
@@ -379,7 +360,44 @@ static int netlbl_cipsov4_add_pass(struct genl_info *info)
379 return 0; 360 return 0;
380 361
381add_pass_failure: 362add_pass_failure:
382 netlbl_cipsov4_doi_free(&doi_def->rcu); 363 cipso_v4_doi_free(doi_def);
364 return ret_val;
365}
366
367/**
368 * netlbl_cipsov4_add_local - Adds a CIPSO V4 DOI definition
369 * @info: the Generic NETLINK info block
370 *
371 * Description:
372 * Create a new CIPSO_V4_MAP_LOCAL DOI definition based on the given ADD
373 * message and add it to the CIPSO V4 engine. Return zero on success and
374 * non-zero on error.
375 *
376 */
377static int netlbl_cipsov4_add_local(struct genl_info *info)
378{
379 int ret_val;
380 struct cipso_v4_doi *doi_def = NULL;
381
382 if (!info->attrs[NLBL_CIPSOV4_A_TAGLST])
383 return -EINVAL;
384
385 doi_def = kmalloc(sizeof(*doi_def), GFP_KERNEL);
386 if (doi_def == NULL)
387 return -ENOMEM;
388 doi_def->type = CIPSO_V4_MAP_LOCAL;
389
390 ret_val = netlbl_cipsov4_add_common(info, doi_def);
391 if (ret_val != 0)
392 goto add_local_failure;
393
394 ret_val = cipso_v4_doi_add(doi_def);
395 if (ret_val != 0)
396 goto add_local_failure;
397 return 0;
398
399add_local_failure:
400 cipso_v4_doi_free(doi_def);
383 return ret_val; 401 return ret_val;
384} 402}
385 403
@@ -412,14 +430,18 @@ static int netlbl_cipsov4_add(struct sk_buff *skb, struct genl_info *info)
412 430
413 type = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_MTYPE]); 431 type = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_MTYPE]);
414 switch (type) { 432 switch (type) {
415 case CIPSO_V4_MAP_STD: 433 case CIPSO_V4_MAP_TRANS:
416 type_str = "std"; 434 type_str = "trans";
417 ret_val = netlbl_cipsov4_add_std(info); 435 ret_val = netlbl_cipsov4_add_std(info);
418 break; 436 break;
419 case CIPSO_V4_MAP_PASS: 437 case CIPSO_V4_MAP_PASS:
420 type_str = "pass"; 438 type_str = "pass";
421 ret_val = netlbl_cipsov4_add_pass(info); 439 ret_val = netlbl_cipsov4_add_pass(info);
422 break; 440 break;
441 case CIPSO_V4_MAP_LOCAL:
442 type_str = "local";
443 ret_val = netlbl_cipsov4_add_local(info);
444 break;
423 } 445 }
424 if (ret_val == 0) 446 if (ret_val == 0)
425 atomic_inc(&netlabel_mgmt_protocount); 447 atomic_inc(&netlabel_mgmt_protocount);
@@ -491,7 +513,7 @@ list_start:
491 doi_def = cipso_v4_doi_getdef(doi); 513 doi_def = cipso_v4_doi_getdef(doi);
492 if (doi_def == NULL) { 514 if (doi_def == NULL) {
493 ret_val = -EINVAL; 515 ret_val = -EINVAL;
494 goto list_failure; 516 goto list_failure_lock;
495 } 517 }
496 518
497 ret_val = nla_put_u32(ans_skb, NLBL_CIPSOV4_A_MTYPE, doi_def->type); 519 ret_val = nla_put_u32(ans_skb, NLBL_CIPSOV4_A_MTYPE, doi_def->type);
@@ -516,7 +538,7 @@ list_start:
516 nla_nest_end(ans_skb, nla_a); 538 nla_nest_end(ans_skb, nla_a);
517 539
518 switch (doi_def->type) { 540 switch (doi_def->type) {
519 case CIPSO_V4_MAP_STD: 541 case CIPSO_V4_MAP_TRANS:
520 nla_a = nla_nest_start(ans_skb, NLBL_CIPSOV4_A_MLSLVLLST); 542 nla_a = nla_nest_start(ans_skb, NLBL_CIPSOV4_A_MLSLVLLST);
521 if (nla_a == NULL) { 543 if (nla_a == NULL) {
522 ret_val = -ENOMEM; 544 ret_val = -ENOMEM;
@@ -655,7 +677,7 @@ static int netlbl_cipsov4_listall(struct sk_buff *skb,
655 struct netlink_callback *cb) 677 struct netlink_callback *cb)
656{ 678{
657 struct netlbl_cipsov4_doiwalk_arg cb_arg; 679 struct netlbl_cipsov4_doiwalk_arg cb_arg;
658 int doi_skip = cb->args[0]; 680 u32 doi_skip = cb->args[0];
659 681
660 cb_arg.nl_cb = cb; 682 cb_arg.nl_cb = cb;
661 cb_arg.skb = skb; 683 cb_arg.skb = skb;
@@ -668,6 +690,29 @@ static int netlbl_cipsov4_listall(struct sk_buff *skb,
668} 690}
669 691
670/** 692/**
693 * netlbl_cipsov4_remove_cb - netlbl_cipsov4_remove() callback for REMOVE
694 * @entry: LSM domain mapping entry
695 * @arg: the netlbl_domhsh_walk_arg structure
696 *
697 * Description:
698 * This function is intended for use by netlbl_cipsov4_remove() as the callback
699 * for the netlbl_domhsh_walk() function; it removes LSM domain map entries
700 * which are associated with the CIPSO DOI specified in @arg. Returns zero on
701 * success, negative values on failure.
702 *
703 */
704static int netlbl_cipsov4_remove_cb(struct netlbl_dom_map *entry, void *arg)
705{
706 struct netlbl_domhsh_walk_arg *cb_arg = arg;
707
708 if (entry->type == NETLBL_NLTYPE_CIPSOV4 &&
709 entry->type_def.cipsov4->doi == cb_arg->doi)
710 return netlbl_domhsh_remove_entry(entry, cb_arg->audit_info);
711
712 return 0;
713}
714
715/**
671 * netlbl_cipsov4_remove - Handle a REMOVE message 716 * netlbl_cipsov4_remove - Handle a REMOVE message
672 * @skb: the NETLINK buffer 717 * @skb: the NETLINK buffer
673 * @info: the Generic NETLINK info block 718 * @info: the Generic NETLINK info block
@@ -681,8 +726,11 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info)
681{ 726{
682 int ret_val = -EINVAL; 727 int ret_val = -EINVAL;
683 u32 doi = 0; 728 u32 doi = 0;
729 struct netlbl_domhsh_walk_arg cb_arg;
684 struct audit_buffer *audit_buf; 730 struct audit_buffer *audit_buf;
685 struct netlbl_audit audit_info; 731 struct netlbl_audit audit_info;
732 u32 skip_bkt = 0;
733 u32 skip_chain = 0;
686 734
687 if (!info->attrs[NLBL_CIPSOV4_A_DOI]) 735 if (!info->attrs[NLBL_CIPSOV4_A_DOI])
688 return -EINVAL; 736 return -EINVAL;
@@ -690,11 +738,15 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info)
690 doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]); 738 doi = nla_get_u32(info->attrs[NLBL_CIPSOV4_A_DOI]);
691 netlbl_netlink_auditinfo(skb, &audit_info); 739 netlbl_netlink_auditinfo(skb, &audit_info);
692 740
693 ret_val = cipso_v4_doi_remove(doi, 741 cb_arg.doi = doi;
694 &audit_info, 742 cb_arg.audit_info = &audit_info;
695 netlbl_cipsov4_doi_free); 743 ret_val = netlbl_domhsh_walk(&skip_bkt, &skip_chain,
696 if (ret_val == 0) 744 netlbl_cipsov4_remove_cb, &cb_arg);
697 atomic_dec(&netlabel_mgmt_protocount); 745 if (ret_val == 0 || ret_val == -ENOENT) {
746 ret_val = cipso_v4_doi_remove(doi, &audit_info);
747 if (ret_val == 0)
748 atomic_dec(&netlabel_mgmt_protocount);
749 }
698 750
699 audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_DEL, 751 audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_DEL,
700 &audit_info); 752 &audit_info);
diff --git a/net/netlabel/netlabel_cipso_v4.h b/net/netlabel/netlabel_cipso_v4.h
index 220cb9d06b4..c8a4079261f 100644
--- a/net/netlabel/netlabel_cipso_v4.h
+++ b/net/netlabel/netlabel_cipso_v4.h
@@ -45,12 +45,13 @@
45 * NLBL_CIPSOV4_A_MTYPE 45 * NLBL_CIPSOV4_A_MTYPE
46 * NLBL_CIPSOV4_A_TAGLST 46 * NLBL_CIPSOV4_A_TAGLST
47 * 47 *
48 * If using CIPSO_V4_MAP_STD the following attributes are required: 48 * If using CIPSO_V4_MAP_TRANS the following attributes are required:
49 * 49 *
50 * NLBL_CIPSOV4_A_MLSLVLLST 50 * NLBL_CIPSOV4_A_MLSLVLLST
51 * NLBL_CIPSOV4_A_MLSCATLST 51 * NLBL_CIPSOV4_A_MLSCATLST
52 * 52 *
53 * If using CIPSO_V4_MAP_PASS no additional attributes are required. 53 * If using CIPSO_V4_MAP_PASS or CIPSO_V4_MAP_LOCAL no additional attributes
54 * are required.
54 * 55 *
55 * o REMOVE: 56 * o REMOVE:
56 * Sent by an application to remove a specific DOI mapping table from the 57 * Sent by an application to remove a specific DOI mapping table from the
@@ -76,12 +77,13 @@
76 * NLBL_CIPSOV4_A_MTYPE 77 * NLBL_CIPSOV4_A_MTYPE
77 * NLBL_CIPSOV4_A_TAGLST 78 * NLBL_CIPSOV4_A_TAGLST
78 * 79 *
79 * If using CIPSO_V4_MAP_STD the following attributes are required: 80 * If using CIPSO_V4_MAP_TRANS the following attributes are required:
80 * 81 *
81 * NLBL_CIPSOV4_A_MLSLVLLST 82 * NLBL_CIPSOV4_A_MLSLVLLST
82 * NLBL_CIPSOV4_A_MLSCATLST 83 * NLBL_CIPSOV4_A_MLSCATLST
83 * 84 *
84 * If using CIPSO_V4_MAP_PASS no additional attributes are required. 85 * If using CIPSO_V4_MAP_PASS or CIPSO_V4_MAP_LOCAL no additional attributes
86 * are required.
85 * 87 *
86 * o LISTALL: 88 * o LISTALL:
87 * This message is sent by an application to list the valid DOIs on the 89 * This message is sent by an application to list the valid DOIs on the
diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c
index 643c032a3a5..5fadf10e5dd 100644
--- a/net/netlabel/netlabel_domainhash.c
+++ b/net/netlabel/netlabel_domainhash.c
@@ -11,7 +11,7 @@
11 */ 11 */
12 12
13/* 13/*
14 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 14 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006, 2008
15 * 15 *
16 * This program is free software; you can redistribute it and/or modify 16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by 17 * it under the terms of the GNU General Public License as published by
@@ -40,6 +40,7 @@
40#include <asm/bug.h> 40#include <asm/bug.h>
41 41
42#include "netlabel_mgmt.h" 42#include "netlabel_mgmt.h"
43#include "netlabel_addrlist.h"
43#include "netlabel_domainhash.h" 44#include "netlabel_domainhash.h"
44#include "netlabel_user.h" 45#include "netlabel_user.h"
45 46
@@ -72,8 +73,28 @@ static struct netlbl_dom_map *netlbl_domhsh_def = NULL;
72static void netlbl_domhsh_free_entry(struct rcu_head *entry) 73static void netlbl_domhsh_free_entry(struct rcu_head *entry)
73{ 74{
74 struct netlbl_dom_map *ptr; 75 struct netlbl_dom_map *ptr;
76 struct netlbl_af4list *iter4;
77 struct netlbl_af4list *tmp4;
78#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
79 struct netlbl_af6list *iter6;
80 struct netlbl_af6list *tmp6;
81#endif /* IPv6 */
75 82
76 ptr = container_of(entry, struct netlbl_dom_map, rcu); 83 ptr = container_of(entry, struct netlbl_dom_map, rcu);
84 if (ptr->type == NETLBL_NLTYPE_ADDRSELECT) {
85 netlbl_af4list_foreach_safe(iter4, tmp4,
86 &ptr->type_def.addrsel->list4) {
87 netlbl_af4list_remove_entry(iter4);
88 kfree(netlbl_domhsh_addr4_entry(iter4));
89 }
90#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
91 netlbl_af6list_foreach_safe(iter6, tmp6,
92 &ptr->type_def.addrsel->list6) {
93 netlbl_af6list_remove_entry(iter6);
94 kfree(netlbl_domhsh_addr6_entry(iter6));
95 }
96#endif /* IPv6 */
97 }
77 kfree(ptr->domain); 98 kfree(ptr->domain);
78 kfree(ptr); 99 kfree(ptr);
79} 100}
@@ -115,13 +136,13 @@ static u32 netlbl_domhsh_hash(const char *key)
115static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain) 136static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain)
116{ 137{
117 u32 bkt; 138 u32 bkt;
139 struct list_head *bkt_list;
118 struct netlbl_dom_map *iter; 140 struct netlbl_dom_map *iter;
119 141
120 if (domain != NULL) { 142 if (domain != NULL) {
121 bkt = netlbl_domhsh_hash(domain); 143 bkt = netlbl_domhsh_hash(domain);
122 list_for_each_entry_rcu(iter, 144 bkt_list = &rcu_dereference(netlbl_domhsh)->tbl[bkt];
123 &rcu_dereference(netlbl_domhsh)->tbl[bkt], 145 list_for_each_entry_rcu(iter, bkt_list, list)
124 list)
125 if (iter->valid && strcmp(iter->domain, domain) == 0) 146 if (iter->valid && strcmp(iter->domain, domain) == 0)
126 return iter; 147 return iter;
127 } 148 }
@@ -156,6 +177,69 @@ static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain)
156 return entry; 177 return entry;
157} 178}
158 179
180/**
181 * netlbl_domhsh_audit_add - Generate an audit entry for an add event
182 * @entry: the entry being added
183 * @addr4: the IPv4 address information
184 * @addr6: the IPv6 address information
185 * @result: the result code
186 * @audit_info: NetLabel audit information
187 *
188 * Description:
189 * Generate an audit record for adding a new NetLabel/LSM mapping entry with
190 * the given information. Caller is responsibile for holding the necessary
191 * locks.
192 *
193 */
194static void netlbl_domhsh_audit_add(struct netlbl_dom_map *entry,
195 struct netlbl_af4list *addr4,
196 struct netlbl_af6list *addr6,
197 int result,
198 struct netlbl_audit *audit_info)
199{
200 struct audit_buffer *audit_buf;
201 struct cipso_v4_doi *cipsov4 = NULL;
202 u32 type;
203
204 audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_ADD, audit_info);
205 if (audit_buf != NULL) {
206 audit_log_format(audit_buf, " nlbl_domain=%s",
207 entry->domain ? entry->domain : "(default)");
208 if (addr4 != NULL) {
209 struct netlbl_domaddr4_map *map4;
210 map4 = netlbl_domhsh_addr4_entry(addr4);
211 type = map4->type;
212 cipsov4 = map4->type_def.cipsov4;
213 netlbl_af4list_audit_addr(audit_buf, 0, NULL,
214 addr4->addr, addr4->mask);
215#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
216 } else if (addr6 != NULL) {
217 struct netlbl_domaddr6_map *map6;
218 map6 = netlbl_domhsh_addr6_entry(addr6);
219 type = map6->type;
220 netlbl_af6list_audit_addr(audit_buf, 0, NULL,
221 &addr6->addr, &addr6->mask);
222#endif /* IPv6 */
223 } else {
224 type = entry->type;
225 cipsov4 = entry->type_def.cipsov4;
226 }
227 switch (type) {
228 case NETLBL_NLTYPE_UNLABELED:
229 audit_log_format(audit_buf, " nlbl_protocol=unlbl");
230 break;
231 case NETLBL_NLTYPE_CIPSOV4:
232 BUG_ON(cipsov4 == NULL);
233 audit_log_format(audit_buf,
234 " nlbl_protocol=cipsov4 cipso_doi=%u",
235 cipsov4->doi);
236 break;
237 }
238 audit_log_format(audit_buf, " res=%u", result == 0 ? 1 : 0);
239 audit_log_end(audit_buf);
240 }
241}
242
159/* 243/*
160 * Domain Hash Table Functions 244 * Domain Hash Table Functions
161 */ 245 */
@@ -213,74 +297,106 @@ int __init netlbl_domhsh_init(u32 size)
213int netlbl_domhsh_add(struct netlbl_dom_map *entry, 297int netlbl_domhsh_add(struct netlbl_dom_map *entry,
214 struct netlbl_audit *audit_info) 298 struct netlbl_audit *audit_info)
215{ 299{
216 int ret_val; 300 int ret_val = 0;
217 u32 bkt; 301 struct netlbl_dom_map *entry_old;
218 struct audit_buffer *audit_buf; 302 struct netlbl_af4list *iter4;
219 303 struct netlbl_af4list *tmp4;
220 switch (entry->type) { 304#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
221 case NETLBL_NLTYPE_UNLABELED: 305 struct netlbl_af6list *iter6;
222 ret_val = 0; 306 struct netlbl_af6list *tmp6;
223 break; 307#endif /* IPv6 */
224 case NETLBL_NLTYPE_CIPSOV4:
225 ret_val = cipso_v4_doi_domhsh_add(entry->type_def.cipsov4,
226 entry->domain);
227 break;
228 default:
229 return -EINVAL;
230 }
231 if (ret_val != 0)
232 return ret_val;
233
234 entry->valid = 1;
235 INIT_RCU_HEAD(&entry->rcu);
236 308
237 rcu_read_lock(); 309 rcu_read_lock();
310
238 spin_lock(&netlbl_domhsh_lock); 311 spin_lock(&netlbl_domhsh_lock);
239 if (entry->domain != NULL) { 312 if (entry->domain != NULL)
240 bkt = netlbl_domhsh_hash(entry->domain); 313 entry_old = netlbl_domhsh_search(entry->domain);
241 if (netlbl_domhsh_search(entry->domain) == NULL) 314 else
315 entry_old = netlbl_domhsh_search_def(entry->domain);
316 if (entry_old == NULL) {
317 entry->valid = 1;
318 INIT_RCU_HEAD(&entry->rcu);
319
320 if (entry->domain != NULL) {
321 u32 bkt = netlbl_domhsh_hash(entry->domain);
242 list_add_tail_rcu(&entry->list, 322 list_add_tail_rcu(&entry->list,
243 &rcu_dereference(netlbl_domhsh)->tbl[bkt]); 323 &rcu_dereference(netlbl_domhsh)->tbl[bkt]);
244 else 324 } else {
245 ret_val = -EEXIST; 325 INIT_LIST_HEAD(&entry->list);
246 } else {
247 INIT_LIST_HEAD(&entry->list);
248 if (rcu_dereference(netlbl_domhsh_def) == NULL)
249 rcu_assign_pointer(netlbl_domhsh_def, entry); 326 rcu_assign_pointer(netlbl_domhsh_def, entry);
250 else
251 ret_val = -EEXIST;
252 }
253 spin_unlock(&netlbl_domhsh_lock);
254 audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_ADD, audit_info);
255 if (audit_buf != NULL) {
256 audit_log_format(audit_buf,
257 " nlbl_domain=%s",
258 entry->domain ? entry->domain : "(default)");
259 switch (entry->type) {
260 case NETLBL_NLTYPE_UNLABELED:
261 audit_log_format(audit_buf, " nlbl_protocol=unlbl");
262 break;
263 case NETLBL_NLTYPE_CIPSOV4:
264 audit_log_format(audit_buf,
265 " nlbl_protocol=cipsov4 cipso_doi=%u",
266 entry->type_def.cipsov4->doi);
267 break;
268 } 327 }
269 audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0);
270 audit_log_end(audit_buf);
271 }
272 rcu_read_unlock();
273 328
274 if (ret_val != 0) { 329 if (entry->type == NETLBL_NLTYPE_ADDRSELECT) {
275 switch (entry->type) { 330 netlbl_af4list_foreach_rcu(iter4,
276 case NETLBL_NLTYPE_CIPSOV4: 331 &entry->type_def.addrsel->list4)
277 if (cipso_v4_doi_domhsh_remove(entry->type_def.cipsov4, 332 netlbl_domhsh_audit_add(entry, iter4, NULL,
278 entry->domain) != 0) 333 ret_val, audit_info);
279 BUG(); 334#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
280 break; 335 netlbl_af6list_foreach_rcu(iter6,
336 &entry->type_def.addrsel->list6)
337 netlbl_domhsh_audit_add(entry, NULL, iter6,
338 ret_val, audit_info);
339#endif /* IPv6 */
340 } else
341 netlbl_domhsh_audit_add(entry, NULL, NULL,
342 ret_val, audit_info);
343 } else if (entry_old->type == NETLBL_NLTYPE_ADDRSELECT &&
344 entry->type == NETLBL_NLTYPE_ADDRSELECT) {
345 struct list_head *old_list4;
346 struct list_head *old_list6;
347
348 old_list4 = &entry_old->type_def.addrsel->list4;
349 old_list6 = &entry_old->type_def.addrsel->list6;
350
351 /* we only allow the addition of address selectors if all of
352 * the selectors do not exist in the existing domain map */
353 netlbl_af4list_foreach_rcu(iter4,
354 &entry->type_def.addrsel->list4)
355 if (netlbl_af4list_search_exact(iter4->addr,
356 iter4->mask,
357 old_list4)) {
358 ret_val = -EEXIST;
359 goto add_return;
360 }
361#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
362 netlbl_af6list_foreach_rcu(iter6,
363 &entry->type_def.addrsel->list6)
364 if (netlbl_af6list_search_exact(&iter6->addr,
365 &iter6->mask,
366 old_list6)) {
367 ret_val = -EEXIST;
368 goto add_return;
369 }
370#endif /* IPv6 */
371
372 netlbl_af4list_foreach_safe(iter4, tmp4,
373 &entry->type_def.addrsel->list4) {
374 netlbl_af4list_remove_entry(iter4);
375 iter4->valid = 1;
376 ret_val = netlbl_af4list_add(iter4, old_list4);
377 netlbl_domhsh_audit_add(entry_old, iter4, NULL,
378 ret_val, audit_info);
379 if (ret_val != 0)
380 goto add_return;
281 } 381 }
282 } 382#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
383 netlbl_af6list_foreach_safe(iter6, tmp6,
384 &entry->type_def.addrsel->list6) {
385 netlbl_af6list_remove_entry(iter6);
386 iter6->valid = 1;
387 ret_val = netlbl_af6list_add(iter6, old_list6);
388 netlbl_domhsh_audit_add(entry_old, NULL, iter6,
389 ret_val, audit_info);
390 if (ret_val != 0)
391 goto add_return;
392 }
393#endif /* IPv6 */
394 } else
395 ret_val = -EINVAL;
283 396
397add_return:
398 spin_unlock(&netlbl_domhsh_lock);
399 rcu_read_unlock();
284 return ret_val; 400 return ret_val;
285} 401}
286 402
@@ -302,35 +418,26 @@ int netlbl_domhsh_add_default(struct netlbl_dom_map *entry,
302} 418}
303 419
304/** 420/**
305 * netlbl_domhsh_remove - Removes an entry from the domain hash table 421 * netlbl_domhsh_remove_entry - Removes a given entry from the domain table
306 * @domain: the domain to remove 422 * @entry: the entry to remove
307 * @audit_info: NetLabel audit information 423 * @audit_info: NetLabel audit information
308 * 424 *
309 * Description: 425 * Description:
310 * Removes an entry from the domain hash table and handles any updates to the 426 * Removes an entry from the domain hash table and handles any updates to the
311 * lower level protocol handler (i.e. CIPSO). Returns zero on success, 427 * lower level protocol handler (i.e. CIPSO). Caller is responsible for
312 * negative on failure. 428 * ensuring that the RCU read lock is held. Returns zero on success, negative
429 * on failure.
313 * 430 *
314 */ 431 */
315int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info) 432int netlbl_domhsh_remove_entry(struct netlbl_dom_map *entry,
433 struct netlbl_audit *audit_info)
316{ 434{
317 int ret_val = -ENOENT; 435 int ret_val = 0;
318 struct netlbl_dom_map *entry;
319 struct audit_buffer *audit_buf; 436 struct audit_buffer *audit_buf;
320 437
321 rcu_read_lock();
322 if (domain)
323 entry = netlbl_domhsh_search(domain);
324 else
325 entry = netlbl_domhsh_search_def(domain);
326 if (entry == NULL) 438 if (entry == NULL)
327 goto remove_return; 439 return -ENOENT;
328 switch (entry->type) { 440
329 case NETLBL_NLTYPE_CIPSOV4:
330 cipso_v4_doi_domhsh_remove(entry->type_def.cipsov4,
331 entry->domain);
332 break;
333 }
334 spin_lock(&netlbl_domhsh_lock); 441 spin_lock(&netlbl_domhsh_lock);
335 if (entry->valid) { 442 if (entry->valid) {
336 entry->valid = 0; 443 entry->valid = 0;
@@ -338,8 +445,8 @@ int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info)
338 list_del_rcu(&entry->list); 445 list_del_rcu(&entry->list);
339 else 446 else
340 rcu_assign_pointer(netlbl_domhsh_def, NULL); 447 rcu_assign_pointer(netlbl_domhsh_def, NULL);
341 ret_val = 0; 448 } else
342 } 449 ret_val = -ENOENT;
343 spin_unlock(&netlbl_domhsh_lock); 450 spin_unlock(&netlbl_domhsh_lock);
344 451
345 audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_DEL, audit_info); 452 audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_DEL, audit_info);
@@ -351,10 +458,54 @@ int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info)
351 audit_log_end(audit_buf); 458 audit_log_end(audit_buf);
352 } 459 }
353 460
354remove_return: 461 if (ret_val == 0) {
355 rcu_read_unlock(); 462 struct netlbl_af4list *iter4;
356 if (ret_val == 0) 463 struct netlbl_domaddr4_map *map4;
464
465 switch (entry->type) {
466 case NETLBL_NLTYPE_ADDRSELECT:
467 netlbl_af4list_foreach_rcu(iter4,
468 &entry->type_def.addrsel->list4) {
469 map4 = netlbl_domhsh_addr4_entry(iter4);
470 cipso_v4_doi_putdef(map4->type_def.cipsov4);
471 }
472 /* no need to check the IPv6 list since we currently
473 * support only unlabeled protocols for IPv6 */
474 break;
475 case NETLBL_NLTYPE_CIPSOV4:
476 cipso_v4_doi_putdef(entry->type_def.cipsov4);
477 break;
478 }
357 call_rcu(&entry->rcu, netlbl_domhsh_free_entry); 479 call_rcu(&entry->rcu, netlbl_domhsh_free_entry);
480 }
481
482 return ret_val;
483}
484
485/**
486 * netlbl_domhsh_remove - Removes an entry from the domain hash table
487 * @domain: the domain to remove
488 * @audit_info: NetLabel audit information
489 *
490 * Description:
491 * Removes an entry from the domain hash table and handles any updates to the
492 * lower level protocol handler (i.e. CIPSO). Returns zero on success,
493 * negative on failure.
494 *
495 */
496int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info)
497{
498 int ret_val;
499 struct netlbl_dom_map *entry;
500
501 rcu_read_lock();
502 if (domain)
503 entry = netlbl_domhsh_search(domain);
504 else
505 entry = netlbl_domhsh_search_def(domain);
506 ret_val = netlbl_domhsh_remove_entry(entry, audit_info);
507 rcu_read_unlock();
508
358 return ret_val; 509 return ret_val;
359} 510}
360 511
@@ -389,6 +540,70 @@ struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain)
389} 540}
390 541
391/** 542/**
543 * netlbl_domhsh_getentry_af4 - Get an entry from the domain hash table
544 * @domain: the domain name to search for
545 * @addr: the IP address to search for
546 *
547 * Description:
548 * Look through the domain hash table searching for an entry to match @domain
549 * and @addr, return a pointer to a copy of the entry or NULL. The caller is
550 * responsible for ensuring that rcu_read_[un]lock() is called.
551 *
552 */
553struct netlbl_domaddr4_map *netlbl_domhsh_getentry_af4(const char *domain,
554 __be32 addr)
555{
556 struct netlbl_dom_map *dom_iter;
557 struct netlbl_af4list *addr_iter;
558
559 dom_iter = netlbl_domhsh_search_def(domain);
560 if (dom_iter == NULL)
561 return NULL;
562 if (dom_iter->type != NETLBL_NLTYPE_ADDRSELECT)
563 return NULL;
564
565 addr_iter = netlbl_af4list_search(addr,
566 &dom_iter->type_def.addrsel->list4);
567 if (addr_iter == NULL)
568 return NULL;
569
570 return netlbl_domhsh_addr4_entry(addr_iter);
571}
572
573#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
574/**
575 * netlbl_domhsh_getentry_af6 - Get an entry from the domain hash table
576 * @domain: the domain name to search for
577 * @addr: the IP address to search for
578 *
579 * Description:
580 * Look through the domain hash table searching for an entry to match @domain
581 * and @addr, return a pointer to a copy of the entry or NULL. The caller is
582 * responsible for ensuring that rcu_read_[un]lock() is called.
583 *
584 */
585struct netlbl_domaddr6_map *netlbl_domhsh_getentry_af6(const char *domain,
586 const struct in6_addr *addr)
587{
588 struct netlbl_dom_map *dom_iter;
589 struct netlbl_af6list *addr_iter;
590
591 dom_iter = netlbl_domhsh_search_def(domain);
592 if (dom_iter == NULL)
593 return NULL;
594 if (dom_iter->type != NETLBL_NLTYPE_ADDRSELECT)
595 return NULL;
596
597 addr_iter = netlbl_af6list_search(addr,
598 &dom_iter->type_def.addrsel->list6);
599 if (addr_iter == NULL)
600 return NULL;
601
602 return netlbl_domhsh_addr6_entry(addr_iter);
603}
604#endif /* IPv6 */
605
606/**
392 * netlbl_domhsh_walk - Iterate through the domain mapping hash table 607 * netlbl_domhsh_walk - Iterate through the domain mapping hash table
393 * @skip_bkt: the number of buckets to skip at the start 608 * @skip_bkt: the number of buckets to skip at the start
394 * @skip_chain: the number of entries to skip in the first iterated bucket 609 * @skip_chain: the number of entries to skip in the first iterated bucket
@@ -410,6 +625,7 @@ int netlbl_domhsh_walk(u32 *skip_bkt,
410{ 625{
411 int ret_val = -ENOENT; 626 int ret_val = -ENOENT;
412 u32 iter_bkt; 627 u32 iter_bkt;
628 struct list_head *iter_list;
413 struct netlbl_dom_map *iter_entry; 629 struct netlbl_dom_map *iter_entry;
414 u32 chain_cnt = 0; 630 u32 chain_cnt = 0;
415 631
@@ -417,9 +633,8 @@ int netlbl_domhsh_walk(u32 *skip_bkt,
417 for (iter_bkt = *skip_bkt; 633 for (iter_bkt = *skip_bkt;
418 iter_bkt < rcu_dereference(netlbl_domhsh)->size; 634 iter_bkt < rcu_dereference(netlbl_domhsh)->size;
419 iter_bkt++, chain_cnt = 0) { 635 iter_bkt++, chain_cnt = 0) {
420 list_for_each_entry_rcu(iter_entry, 636 iter_list = &rcu_dereference(netlbl_domhsh)->tbl[iter_bkt];
421 &rcu_dereference(netlbl_domhsh)->tbl[iter_bkt], 637 list_for_each_entry_rcu(iter_entry, iter_list, list)
422 list)
423 if (iter_entry->valid) { 638 if (iter_entry->valid) {
424 if (chain_cnt++ < *skip_chain) 639 if (chain_cnt++ < *skip_chain)
425 continue; 640 continue;
diff --git a/net/netlabel/netlabel_domainhash.h b/net/netlabel/netlabel_domainhash.h
index 8220990ceb9..bfcb6763a1a 100644
--- a/net/netlabel/netlabel_domainhash.h
+++ b/net/netlabel/netlabel_domainhash.h
@@ -11,7 +11,7 @@
11 */ 11 */
12 12
13/* 13/*
14 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 14 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006, 2008
15 * 15 *
16 * This program is free software; you can redistribute it and/or modify 16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by 17 * it under the terms of the GNU General Public License as published by
@@ -36,16 +36,43 @@
36#include <linux/rcupdate.h> 36#include <linux/rcupdate.h>
37#include <linux/list.h> 37#include <linux/list.h>
38 38
39#include "netlabel_addrlist.h"
40
39/* Domain hash table size */ 41/* Domain hash table size */
40/* XXX - currently this number is an uneducated guess */ 42/* XXX - currently this number is an uneducated guess */
41#define NETLBL_DOMHSH_BITSIZE 7 43#define NETLBL_DOMHSH_BITSIZE 7
42 44
43/* Domain mapping definition struct */ 45/* Domain mapping definition structures */
46#define netlbl_domhsh_addr4_entry(iter) \
47 container_of(iter, struct netlbl_domaddr4_map, list)
48struct netlbl_domaddr4_map {
49 u32 type;
50 union {
51 struct cipso_v4_doi *cipsov4;
52 } type_def;
53
54 struct netlbl_af4list list;
55};
56#define netlbl_domhsh_addr6_entry(iter) \
57 container_of(iter, struct netlbl_domaddr6_map, list)
58struct netlbl_domaddr6_map {
59 u32 type;
60
61 /* NOTE: no 'type_def' union needed at present since we don't currently
62 * support any IPv6 labeling protocols */
63
64 struct netlbl_af6list list;
65};
66struct netlbl_domaddr_map {
67 struct list_head list4;
68 struct list_head list6;
69};
44struct netlbl_dom_map { 70struct netlbl_dom_map {
45 char *domain; 71 char *domain;
46 u32 type; 72 u32 type;
47 union { 73 union {
48 struct cipso_v4_doi *cipsov4; 74 struct cipso_v4_doi *cipsov4;
75 struct netlbl_domaddr_map *addrsel;
49 } type_def; 76 } type_def;
50 77
51 u32 valid; 78 u32 valid;
@@ -61,12 +88,21 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
61 struct netlbl_audit *audit_info); 88 struct netlbl_audit *audit_info);
62int netlbl_domhsh_add_default(struct netlbl_dom_map *entry, 89int netlbl_domhsh_add_default(struct netlbl_dom_map *entry,
63 struct netlbl_audit *audit_info); 90 struct netlbl_audit *audit_info);
91int netlbl_domhsh_remove_entry(struct netlbl_dom_map *entry,
92 struct netlbl_audit *audit_info);
64int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info); 93int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info);
65int netlbl_domhsh_remove_default(struct netlbl_audit *audit_info); 94int netlbl_domhsh_remove_default(struct netlbl_audit *audit_info);
66struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain); 95struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain);
96struct netlbl_domaddr4_map *netlbl_domhsh_getentry_af4(const char *domain,
97 __be32 addr);
67int netlbl_domhsh_walk(u32 *skip_bkt, 98int netlbl_domhsh_walk(u32 *skip_bkt,
68 u32 *skip_chain, 99 u32 *skip_chain,
69 int (*callback) (struct netlbl_dom_map *entry, void *arg), 100 int (*callback) (struct netlbl_dom_map *entry, void *arg),
70 void *cb_arg); 101 void *cb_arg);
71 102
103#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
104struct netlbl_domaddr6_map *netlbl_domhsh_getentry_af6(const char *domain,
105 const struct in6_addr *addr);
106#endif /* IPv6 */
107
72#endif 108#endif
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index 39793a1a93a..b32eceb3ab0 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -10,7 +10,7 @@
10 */ 10 */
11 11
12/* 12/*
13 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 13 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006, 2008
14 * 14 *
15 * This program is free software; you can redistribute it and/or modify 15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by 16 * it under the terms of the GNU General Public License as published by
@@ -82,7 +82,7 @@ int netlbl_cfg_unlbl_add_map(const char *domain,
82 82
83 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 83 entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
84 if (entry == NULL) 84 if (entry == NULL)
85 goto cfg_unlbl_add_map_failure; 85 return -ENOMEM;
86 if (domain != NULL) { 86 if (domain != NULL) {
87 entry->domain = kstrdup(domain, GFP_ATOMIC); 87 entry->domain = kstrdup(domain, GFP_ATOMIC);
88 if (entry->domain == NULL) 88 if (entry->domain == NULL)
@@ -104,49 +104,6 @@ cfg_unlbl_add_map_failure:
104} 104}
105 105
106/** 106/**
107 * netlbl_cfg_cipsov4_add - Add a new CIPSOv4 DOI definition
108 * @doi_def: the DOI definition
109 * @audit_info: NetLabel audit information
110 *
111 * Description:
112 * Add a new CIPSOv4 DOI definition to the NetLabel subsystem. Returns zero on
113 * success, negative values on failure.
114 *
115 */
116int netlbl_cfg_cipsov4_add(struct cipso_v4_doi *doi_def,
117 struct netlbl_audit *audit_info)
118{
119 int ret_val;
120 const char *type_str;
121 struct audit_buffer *audit_buf;
122
123 ret_val = cipso_v4_doi_add(doi_def);
124
125 audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD,
126 audit_info);
127 if (audit_buf != NULL) {
128 switch (doi_def->type) {
129 case CIPSO_V4_MAP_STD:
130 type_str = "std";
131 break;
132 case CIPSO_V4_MAP_PASS:
133 type_str = "pass";
134 break;
135 default:
136 type_str = "(unknown)";
137 }
138 audit_log_format(audit_buf,
139 " cipso_doi=%u cipso_type=%s res=%u",
140 doi_def->doi,
141 type_str,
142 ret_val == 0 ? 1 : 0);
143 audit_log_end(audit_buf);
144 }
145
146 return ret_val;
147}
148
149/**
150 * netlbl_cfg_cipsov4_add_map - Add a new CIPSOv4 DOI definition and mapping 107 * netlbl_cfg_cipsov4_add_map - Add a new CIPSOv4 DOI definition and mapping
151 * @doi_def: the DOI definition 108 * @doi_def: the DOI definition
152 * @domain: the domain mapping to add 109 * @domain: the domain mapping to add
@@ -164,58 +121,71 @@ int netlbl_cfg_cipsov4_add_map(struct cipso_v4_doi *doi_def,
164 struct netlbl_audit *audit_info) 121 struct netlbl_audit *audit_info)
165{ 122{
166 int ret_val = -ENOMEM; 123 int ret_val = -ENOMEM;
124 u32 doi;
125 u32 doi_type;
167 struct netlbl_dom_map *entry; 126 struct netlbl_dom_map *entry;
127 const char *type_str;
128 struct audit_buffer *audit_buf;
129
130 doi = doi_def->doi;
131 doi_type = doi_def->type;
168 132
169 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 133 entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
170 if (entry == NULL) 134 if (entry == NULL)
171 goto cfg_cipsov4_add_map_failure; 135 return -ENOMEM;
172 if (domain != NULL) { 136 if (domain != NULL) {
173 entry->domain = kstrdup(domain, GFP_ATOMIC); 137 entry->domain = kstrdup(domain, GFP_ATOMIC);
174 if (entry->domain == NULL) 138 if (entry->domain == NULL)
175 goto cfg_cipsov4_add_map_failure; 139 goto cfg_cipsov4_add_map_failure;
176 } 140 }
177 entry->type = NETLBL_NLTYPE_CIPSOV4;
178 entry->type_def.cipsov4 = doi_def;
179
180 /* Grab a RCU read lock here so nothing happens to the doi_def variable
181 * between adding it to the CIPSOv4 protocol engine and adding a
182 * domain mapping for it. */
183 141
184 rcu_read_lock(); 142 ret_val = cipso_v4_doi_add(doi_def);
185 ret_val = netlbl_cfg_cipsov4_add(doi_def, audit_info);
186 if (ret_val != 0) 143 if (ret_val != 0)
187 goto cfg_cipsov4_add_map_failure_unlock; 144 goto cfg_cipsov4_add_map_failure_remove_doi;
145 entry->type = NETLBL_NLTYPE_CIPSOV4;
146 entry->type_def.cipsov4 = cipso_v4_doi_getdef(doi);
147 if (entry->type_def.cipsov4 == NULL) {
148 ret_val = -ENOENT;
149 goto cfg_cipsov4_add_map_failure_remove_doi;
150 }
188 ret_val = netlbl_domhsh_add(entry, audit_info); 151 ret_val = netlbl_domhsh_add(entry, audit_info);
189 if (ret_val != 0) 152 if (ret_val != 0)
190 goto cfg_cipsov4_add_map_failure_remove_doi; 153 goto cfg_cipsov4_add_map_failure_release_doi;
191 rcu_read_unlock();
192 154
193 return 0; 155cfg_cipsov4_add_map_return:
156 audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD,
157 audit_info);
158 if (audit_buf != NULL) {
159 switch (doi_type) {
160 case CIPSO_V4_MAP_TRANS:
161 type_str = "trans";
162 break;
163 case CIPSO_V4_MAP_PASS:
164 type_str = "pass";
165 break;
166 case CIPSO_V4_MAP_LOCAL:
167 type_str = "local";
168 break;
169 default:
170 type_str = "(unknown)";
171 }
172 audit_log_format(audit_buf,
173 " cipso_doi=%u cipso_type=%s res=%u",
174 doi, type_str, ret_val == 0 ? 1 : 0);
175 audit_log_end(audit_buf);
176 }
194 177
178 return ret_val;
179
180cfg_cipsov4_add_map_failure_release_doi:
181 cipso_v4_doi_putdef(doi_def);
195cfg_cipsov4_add_map_failure_remove_doi: 182cfg_cipsov4_add_map_failure_remove_doi:
196 cipso_v4_doi_remove(doi_def->doi, audit_info, netlbl_cipsov4_doi_free); 183 cipso_v4_doi_remove(doi, audit_info);
197cfg_cipsov4_add_map_failure_unlock:
198 rcu_read_unlock();
199cfg_cipsov4_add_map_failure: 184cfg_cipsov4_add_map_failure:
200 if (entry != NULL) 185 if (entry != NULL)
201 kfree(entry->domain); 186 kfree(entry->domain);
202 kfree(entry); 187 kfree(entry);
203 return ret_val; 188 goto cfg_cipsov4_add_map_return;
204}
205
206/**
207 * netlbl_cfg_cipsov4_del - Removean existing CIPSOv4 DOI definition
208 * @doi: the CIPSO DOI value
209 * @audit_info: NetLabel audit information
210 *
211 * Description:
212 * Removes an existing CIPSOv4 DOI definition from the NetLabel subsystem.
213 * Returns zero on success, negative values on failure.
214 *
215 */
216int netlbl_cfg_cipsov4_del(u32 doi, struct netlbl_audit *audit_info)
217{
218 return cipso_v4_doi_remove(doi, audit_info, netlbl_cipsov4_doi_free);
219} 189}
220 190
221/* 191/*
@@ -452,7 +422,9 @@ int netlbl_enabled(void)
452 * Attach the correct label to the given socket using the security attributes 422 * Attach the correct label to the given socket using the security attributes
453 * specified in @secattr. This function requires exclusive access to @sk, 423 * specified in @secattr. This function requires exclusive access to @sk,
454 * which means it either needs to be in the process of being created or locked. 424 * which means it either needs to be in the process of being created or locked.
455 * Returns zero on success, negative values on failure. 425 * Returns zero on success, -EDESTADDRREQ if the domain is configured to use
426 * network address selectors (can't blindly label the socket), and negative
427 * values on all other failures.
456 * 428 *
457 */ 429 */
458int netlbl_sock_setattr(struct sock *sk, 430int netlbl_sock_setattr(struct sock *sk,
@@ -466,6 +438,9 @@ int netlbl_sock_setattr(struct sock *sk,
466 if (dom_entry == NULL) 438 if (dom_entry == NULL)
467 goto socket_setattr_return; 439 goto socket_setattr_return;
468 switch (dom_entry->type) { 440 switch (dom_entry->type) {
441 case NETLBL_NLTYPE_ADDRSELECT:
442 ret_val = -EDESTADDRREQ;
443 break;
469 case NETLBL_NLTYPE_CIPSOV4: 444 case NETLBL_NLTYPE_CIPSOV4:
470 ret_val = cipso_v4_sock_setattr(sk, 445 ret_val = cipso_v4_sock_setattr(sk,
471 dom_entry->type_def.cipsov4, 446 dom_entry->type_def.cipsov4,
@@ -484,6 +459,20 @@ socket_setattr_return:
484} 459}
485 460
486/** 461/**
462 * netlbl_sock_delattr - Delete all the NetLabel labels on a socket
463 * @sk: the socket
464 *
465 * Description:
466 * Remove all the NetLabel labeling from @sk. The caller is responsible for
467 * ensuring that @sk is locked.
468 *
469 */
470void netlbl_sock_delattr(struct sock *sk)
471{
472 cipso_v4_sock_delattr(sk);
473}
474
475/**
487 * netlbl_sock_getattr - Determine the security attributes of a sock 476 * netlbl_sock_getattr - Determine the security attributes of a sock
488 * @sk: the sock 477 * @sk: the sock
489 * @secattr: the security attributes 478 * @secattr: the security attributes
@@ -501,6 +490,128 @@ int netlbl_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
501} 490}
502 491
503/** 492/**
493 * netlbl_conn_setattr - Label a connected socket using the correct protocol
494 * @sk: the socket to label
495 * @addr: the destination address
496 * @secattr: the security attributes
497 *
498 * Description:
499 * Attach the correct label to the given connected socket using the security
500 * attributes specified in @secattr. The caller is responsible for ensuring
501 * that @sk is locked. Returns zero on success, negative values on failure.
502 *
503 */
504int netlbl_conn_setattr(struct sock *sk,
505 struct sockaddr *addr,
506 const struct netlbl_lsm_secattr *secattr)
507{
508 int ret_val;
509 struct sockaddr_in *addr4;
510 struct netlbl_domaddr4_map *af4_entry;
511
512 rcu_read_lock();
513 switch (addr->sa_family) {
514 case AF_INET:
515 addr4 = (struct sockaddr_in *)addr;
516 af4_entry = netlbl_domhsh_getentry_af4(secattr->domain,
517 addr4->sin_addr.s_addr);
518 if (af4_entry == NULL) {
519 ret_val = -ENOENT;
520 goto conn_setattr_return;
521 }
522 switch (af4_entry->type) {
523 case NETLBL_NLTYPE_CIPSOV4:
524 ret_val = cipso_v4_sock_setattr(sk,
525 af4_entry->type_def.cipsov4,
526 secattr);
527 break;
528 case NETLBL_NLTYPE_UNLABELED:
529 /* just delete the protocols we support for right now
530 * but we could remove other protocols if needed */
531 cipso_v4_sock_delattr(sk);
532 ret_val = 0;
533 break;
534 default:
535 ret_val = -ENOENT;
536 }
537 break;
538#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
539 case AF_INET6:
540 /* since we don't support any IPv6 labeling protocols right
541 * now we can optimize everything away until we do */
542 ret_val = 0;
543 break;
544#endif /* IPv6 */
545 default:
546 ret_val = 0;
547 }
548
549conn_setattr_return:
550 rcu_read_unlock();
551 return ret_val;
552}
553
554/**
555 * netlbl_skbuff_setattr - Label a packet using the correct protocol
556 * @skb: the packet
557 * @family: protocol family
558 * @secattr: the security attributes
559 *
560 * Description:
561 * Attach the correct label to the given packet using the security attributes
562 * specified in @secattr. Returns zero on success, negative values on failure.
563 *
564 */
565int netlbl_skbuff_setattr(struct sk_buff *skb,
566 u16 family,
567 const struct netlbl_lsm_secattr *secattr)
568{
569 int ret_val;
570 struct iphdr *hdr4;
571 struct netlbl_domaddr4_map *af4_entry;
572
573 rcu_read_lock();
574 switch (family) {
575 case AF_INET:
576 hdr4 = ip_hdr(skb);
577 af4_entry = netlbl_domhsh_getentry_af4(secattr->domain,
578 hdr4->daddr);
579 if (af4_entry == NULL) {
580 ret_val = -ENOENT;
581 goto skbuff_setattr_return;
582 }
583 switch (af4_entry->type) {
584 case NETLBL_NLTYPE_CIPSOV4:
585 ret_val = cipso_v4_skbuff_setattr(skb,
586 af4_entry->type_def.cipsov4,
587 secattr);
588 break;
589 case NETLBL_NLTYPE_UNLABELED:
590 /* just delete the protocols we support for right now
591 * but we could remove other protocols if needed */
592 ret_val = cipso_v4_skbuff_delattr(skb);
593 break;
594 default:
595 ret_val = -ENOENT;
596 }
597 break;
598#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
599 case AF_INET6:
600 /* since we don't support any IPv6 labeling protocols right
601 * now we can optimize everything away until we do */
602 ret_val = 0;
603 break;
604#endif /* IPv6 */
605 default:
606 ret_val = 0;
607 }
608
609skbuff_setattr_return:
610 rcu_read_unlock();
611 return ret_val;
612}
613
614/**
504 * netlbl_skbuff_getattr - Determine the security attributes of a packet 615 * netlbl_skbuff_getattr - Determine the security attributes of a packet
505 * @skb: the packet 616 * @skb: the packet
506 * @family: protocol family 617 * @family: protocol family
@@ -528,6 +639,7 @@ int netlbl_skbuff_getattr(const struct sk_buff *skb,
528 * netlbl_skbuff_err - Handle a LSM error on a sk_buff 639 * netlbl_skbuff_err - Handle a LSM error on a sk_buff
529 * @skb: the packet 640 * @skb: the packet
530 * @error: the error code 641 * @error: the error code
642 * @gateway: true if host is acting as a gateway, false otherwise
531 * 643 *
532 * Description: 644 * Description:
533 * Deal with a LSM problem when handling the packet in @skb, typically this is 645 * Deal with a LSM problem when handling the packet in @skb, typically this is
@@ -535,10 +647,10 @@ int netlbl_skbuff_getattr(const struct sk_buff *skb,
535 * according to the packet's labeling protocol. 647 * according to the packet's labeling protocol.
536 * 648 *
537 */ 649 */
538void netlbl_skbuff_err(struct sk_buff *skb, int error) 650void netlbl_skbuff_err(struct sk_buff *skb, int error, int gateway)
539{ 651{
540 if (CIPSO_V4_OPTEXIST(skb)) 652 if (CIPSO_V4_OPTEXIST(skb))
541 cipso_v4_error(skb, error, 0); 653 cipso_v4_error(skb, error, gateway);
542} 654}
543 655
544/** 656/**
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
index 44be5d5261f..ee769ecaa13 100644
--- a/net/netlabel/netlabel_mgmt.c
+++ b/net/netlabel/netlabel_mgmt.c
@@ -10,7 +10,7 @@
10 */ 10 */
11 11
12/* 12/*
13 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 13 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006, 2008
14 * 14 *
15 * This program is free software; you can redistribute it and/or modify 15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by 16 * it under the terms of the GNU General Public License as published by
@@ -32,9 +32,13 @@
32#include <linux/socket.h> 32#include <linux/socket.h>
33#include <linux/string.h> 33#include <linux/string.h>
34#include <linux/skbuff.h> 34#include <linux/skbuff.h>
35#include <linux/in.h>
36#include <linux/in6.h>
35#include <net/sock.h> 37#include <net/sock.h>
36#include <net/netlink.h> 38#include <net/netlink.h>
37#include <net/genetlink.h> 39#include <net/genetlink.h>
40#include <net/ip.h>
41#include <net/ipv6.h>
38#include <net/netlabel.h> 42#include <net/netlabel.h>
39#include <net/cipso_ipv4.h> 43#include <net/cipso_ipv4.h>
40#include <asm/atomic.h> 44#include <asm/atomic.h>
@@ -71,86 +75,337 @@ static const struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = {
71}; 75};
72 76
73/* 77/*
74 * NetLabel Command Handlers 78 * Helper Functions
75 */ 79 */
76 80
77/** 81/**
78 * netlbl_mgmt_add - Handle an ADD message 82 * netlbl_mgmt_add - Handle an ADD message
79 * @skb: the NETLINK buffer
80 * @info: the Generic NETLINK info block 83 * @info: the Generic NETLINK info block
84 * @audit_info: NetLabel audit information
81 * 85 *
82 * Description: 86 * Description:
83 * Process a user generated ADD message and add the domains from the message 87 * Helper function for the ADD and ADDDEF messages to add the domain mappings
84 * to the hash table. See netlabel.h for a description of the message format. 88 * from the message to the hash table. See netlabel.h for a description of the
85 * Returns zero on success, negative values on failure. 89 * message format. Returns zero on success, negative values on failure.
86 * 90 *
87 */ 91 */
88static int netlbl_mgmt_add(struct sk_buff *skb, struct genl_info *info) 92static int netlbl_mgmt_add_common(struct genl_info *info,
93 struct netlbl_audit *audit_info)
89{ 94{
90 int ret_val = -EINVAL; 95 int ret_val = -EINVAL;
91 struct netlbl_dom_map *entry = NULL; 96 struct netlbl_dom_map *entry = NULL;
92 size_t tmp_size; 97 struct netlbl_domaddr_map *addrmap = NULL;
98 struct cipso_v4_doi *cipsov4 = NULL;
93 u32 tmp_val; 99 u32 tmp_val;
94 struct netlbl_audit audit_info;
95
96 if (!info->attrs[NLBL_MGMT_A_DOMAIN] ||
97 !info->attrs[NLBL_MGMT_A_PROTOCOL])
98 goto add_failure;
99
100 netlbl_netlink_auditinfo(skb, &audit_info);
101 100
102 entry = kzalloc(sizeof(*entry), GFP_KERNEL); 101 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
103 if (entry == NULL) { 102 if (entry == NULL) {
104 ret_val = -ENOMEM; 103 ret_val = -ENOMEM;
105 goto add_failure; 104 goto add_failure;
106 } 105 }
107 tmp_size = nla_len(info->attrs[NLBL_MGMT_A_DOMAIN]);
108 entry->domain = kmalloc(tmp_size, GFP_KERNEL);
109 if (entry->domain == NULL) {
110 ret_val = -ENOMEM;
111 goto add_failure;
112 }
113 entry->type = nla_get_u32(info->attrs[NLBL_MGMT_A_PROTOCOL]); 106 entry->type = nla_get_u32(info->attrs[NLBL_MGMT_A_PROTOCOL]);
114 nla_strlcpy(entry->domain, info->attrs[NLBL_MGMT_A_DOMAIN], tmp_size); 107 if (info->attrs[NLBL_MGMT_A_DOMAIN]) {
108 size_t tmp_size = nla_len(info->attrs[NLBL_MGMT_A_DOMAIN]);
109 entry->domain = kmalloc(tmp_size, GFP_KERNEL);
110 if (entry->domain == NULL) {
111 ret_val = -ENOMEM;
112 goto add_failure;
113 }
114 nla_strlcpy(entry->domain,
115 info->attrs[NLBL_MGMT_A_DOMAIN], tmp_size);
116 }
117
118 /* NOTE: internally we allow/use a entry->type value of
119 * NETLBL_NLTYPE_ADDRSELECT but we don't currently allow users
120 * to pass that as a protocol value because we need to know the
121 * "real" protocol */
115 122
116 switch (entry->type) { 123 switch (entry->type) {
117 case NETLBL_NLTYPE_UNLABELED: 124 case NETLBL_NLTYPE_UNLABELED:
118 ret_val = netlbl_domhsh_add(entry, &audit_info);
119 break; 125 break;
120 case NETLBL_NLTYPE_CIPSOV4: 126 case NETLBL_NLTYPE_CIPSOV4:
121 if (!info->attrs[NLBL_MGMT_A_CV4DOI]) 127 if (!info->attrs[NLBL_MGMT_A_CV4DOI])
122 goto add_failure; 128 goto add_failure;
123 129
124 tmp_val = nla_get_u32(info->attrs[NLBL_MGMT_A_CV4DOI]); 130 tmp_val = nla_get_u32(info->attrs[NLBL_MGMT_A_CV4DOI]);
125 /* We should be holding a rcu_read_lock() here while we hold 131 cipsov4 = cipso_v4_doi_getdef(tmp_val);
126 * the result but since the entry will always be deleted when 132 if (cipsov4 == NULL)
127 * the CIPSO DOI is deleted we aren't going to keep the
128 * lock. */
129 rcu_read_lock();
130 entry->type_def.cipsov4 = cipso_v4_doi_getdef(tmp_val);
131 if (entry->type_def.cipsov4 == NULL) {
132 rcu_read_unlock();
133 goto add_failure; 133 goto add_failure;
134 } 134 entry->type_def.cipsov4 = cipsov4;
135 ret_val = netlbl_domhsh_add(entry, &audit_info);
136 rcu_read_unlock();
137 break; 135 break;
138 default: 136 default:
139 goto add_failure; 137 goto add_failure;
140 } 138 }
139
140 if (info->attrs[NLBL_MGMT_A_IPV4ADDR]) {
141 struct in_addr *addr;
142 struct in_addr *mask;
143 struct netlbl_domaddr4_map *map;
144
145 addrmap = kzalloc(sizeof(*addrmap), GFP_KERNEL);
146 if (addrmap == NULL) {
147 ret_val = -ENOMEM;
148 goto add_failure;
149 }
150 INIT_LIST_HEAD(&addrmap->list4);
151 INIT_LIST_HEAD(&addrmap->list6);
152
153 if (nla_len(info->attrs[NLBL_MGMT_A_IPV4ADDR]) !=
154 sizeof(struct in_addr)) {
155 ret_val = -EINVAL;
156 goto add_failure;
157 }
158 if (nla_len(info->attrs[NLBL_MGMT_A_IPV4MASK]) !=
159 sizeof(struct in_addr)) {
160 ret_val = -EINVAL;
161 goto add_failure;
162 }
163 addr = nla_data(info->attrs[NLBL_MGMT_A_IPV4ADDR]);
164 mask = nla_data(info->attrs[NLBL_MGMT_A_IPV4MASK]);
165
166 map = kzalloc(sizeof(*map), GFP_KERNEL);
167 if (map == NULL) {
168 ret_val = -ENOMEM;
169 goto add_failure;
170 }
171 map->list.addr = addr->s_addr & mask->s_addr;
172 map->list.mask = mask->s_addr;
173 map->list.valid = 1;
174 map->type = entry->type;
175 if (cipsov4)
176 map->type_def.cipsov4 = cipsov4;
177
178 ret_val = netlbl_af4list_add(&map->list, &addrmap->list4);
179 if (ret_val != 0) {
180 kfree(map);
181 goto add_failure;
182 }
183
184 entry->type = NETLBL_NLTYPE_ADDRSELECT;
185 entry->type_def.addrsel = addrmap;
186#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
187 } else if (info->attrs[NLBL_MGMT_A_IPV6ADDR]) {
188 struct in6_addr *addr;
189 struct in6_addr *mask;
190 struct netlbl_domaddr6_map *map;
191
192 addrmap = kzalloc(sizeof(*addrmap), GFP_KERNEL);
193 if (addrmap == NULL) {
194 ret_val = -ENOMEM;
195 goto add_failure;
196 }
197 INIT_LIST_HEAD(&addrmap->list4);
198 INIT_LIST_HEAD(&addrmap->list6);
199
200 if (nla_len(info->attrs[NLBL_MGMT_A_IPV6ADDR]) !=
201 sizeof(struct in6_addr)) {
202 ret_val = -EINVAL;
203 goto add_failure;
204 }
205 if (nla_len(info->attrs[NLBL_MGMT_A_IPV6MASK]) !=
206 sizeof(struct in6_addr)) {
207 ret_val = -EINVAL;
208 goto add_failure;
209 }
210 addr = nla_data(info->attrs[NLBL_MGMT_A_IPV6ADDR]);
211 mask = nla_data(info->attrs[NLBL_MGMT_A_IPV6MASK]);
212
213 map = kzalloc(sizeof(*map), GFP_KERNEL);
214 if (map == NULL) {
215 ret_val = -ENOMEM;
216 goto add_failure;
217 }
218 ipv6_addr_copy(&map->list.addr, addr);
219 map->list.addr.s6_addr32[0] &= mask->s6_addr32[0];
220 map->list.addr.s6_addr32[1] &= mask->s6_addr32[1];
221 map->list.addr.s6_addr32[2] &= mask->s6_addr32[2];
222 map->list.addr.s6_addr32[3] &= mask->s6_addr32[3];
223 ipv6_addr_copy(&map->list.mask, mask);
224 map->list.valid = 1;
225 map->type = entry->type;
226
227 ret_val = netlbl_af6list_add(&map->list, &addrmap->list6);
228 if (ret_val != 0) {
229 kfree(map);
230 goto add_failure;
231 }
232
233 entry->type = NETLBL_NLTYPE_ADDRSELECT;
234 entry->type_def.addrsel = addrmap;
235#endif /* IPv6 */
236 }
237
238 ret_val = netlbl_domhsh_add(entry, audit_info);
141 if (ret_val != 0) 239 if (ret_val != 0)
142 goto add_failure; 240 goto add_failure;
143 241
144 return 0; 242 return 0;
145 243
146add_failure: 244add_failure:
245 if (cipsov4)
246 cipso_v4_doi_putdef(cipsov4);
147 if (entry) 247 if (entry)
148 kfree(entry->domain); 248 kfree(entry->domain);
249 kfree(addrmap);
149 kfree(entry); 250 kfree(entry);
150 return ret_val; 251 return ret_val;
151} 252}
152 253
153/** 254/**
255 * netlbl_mgmt_listentry - List a NetLabel/LSM domain map entry
256 * @skb: the NETLINK buffer
257 * @entry: the map entry
258 *
259 * Description:
260 * This function is a helper function used by the LISTALL and LISTDEF command
261 * handlers. The caller is responsibile for ensuring that the RCU read lock
262 * is held. Returns zero on success, negative values on failure.
263 *
264 */
265static int netlbl_mgmt_listentry(struct sk_buff *skb,
266 struct netlbl_dom_map *entry)
267{
268 int ret_val;
269 struct nlattr *nla_a;
270 struct nlattr *nla_b;
271 struct netlbl_af4list *iter4;
272#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
273 struct netlbl_af6list *iter6;
274#endif
275
276 if (entry->domain != NULL) {
277 ret_val = nla_put_string(skb,
278 NLBL_MGMT_A_DOMAIN, entry->domain);
279 if (ret_val != 0)
280 return ret_val;
281 }
282
283 switch (entry->type) {
284 case NETLBL_NLTYPE_ADDRSELECT:
285 nla_a = nla_nest_start(skb, NLBL_MGMT_A_SELECTORLIST);
286 if (nla_a == NULL)
287 return -ENOMEM;
288
289 netlbl_af4list_foreach_rcu(iter4,
290 &entry->type_def.addrsel->list4) {
291 struct netlbl_domaddr4_map *map4;
292 struct in_addr addr_struct;
293
294 nla_b = nla_nest_start(skb, NLBL_MGMT_A_ADDRSELECTOR);
295 if (nla_b == NULL)
296 return -ENOMEM;
297
298 addr_struct.s_addr = iter4->addr;
299 ret_val = nla_put(skb, NLBL_MGMT_A_IPV4ADDR,
300 sizeof(struct in_addr),
301 &addr_struct);
302 if (ret_val != 0)
303 return ret_val;
304 addr_struct.s_addr = iter4->mask;
305 ret_val = nla_put(skb, NLBL_MGMT_A_IPV4MASK,
306 sizeof(struct in_addr),
307 &addr_struct);
308 if (ret_val != 0)
309 return ret_val;
310 map4 = netlbl_domhsh_addr4_entry(iter4);
311 ret_val = nla_put_u32(skb, NLBL_MGMT_A_PROTOCOL,
312 map4->type);
313 if (ret_val != 0)
314 return ret_val;
315 switch (map4->type) {
316 case NETLBL_NLTYPE_CIPSOV4:
317 ret_val = nla_put_u32(skb, NLBL_MGMT_A_CV4DOI,
318 map4->type_def.cipsov4->doi);
319 if (ret_val != 0)
320 return ret_val;
321 break;
322 }
323
324 nla_nest_end(skb, nla_b);
325 }
326#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
327 netlbl_af6list_foreach_rcu(iter6,
328 &entry->type_def.addrsel->list6) {
329 struct netlbl_domaddr6_map *map6;
330
331 nla_b = nla_nest_start(skb, NLBL_MGMT_A_ADDRSELECTOR);
332 if (nla_b == NULL)
333 return -ENOMEM;
334
335 ret_val = nla_put(skb, NLBL_MGMT_A_IPV6ADDR,
336 sizeof(struct in6_addr),
337 &iter6->addr);
338 if (ret_val != 0)
339 return ret_val;
340 ret_val = nla_put(skb, NLBL_MGMT_A_IPV6MASK,
341 sizeof(struct in6_addr),
342 &iter6->mask);
343 if (ret_val != 0)
344 return ret_val;
345 map6 = netlbl_domhsh_addr6_entry(iter6);
346 ret_val = nla_put_u32(skb, NLBL_MGMT_A_PROTOCOL,
347 map6->type);
348 if (ret_val != 0)
349 return ret_val;
350
351 nla_nest_end(skb, nla_b);
352 }
353#endif /* IPv6 */
354
355 nla_nest_end(skb, nla_a);
356 break;
357 case NETLBL_NLTYPE_UNLABELED:
358 ret_val = nla_put_u32(skb, NLBL_MGMT_A_PROTOCOL, entry->type);
359 break;
360 case NETLBL_NLTYPE_CIPSOV4:
361 ret_val = nla_put_u32(skb, NLBL_MGMT_A_PROTOCOL, entry->type);
362 if (ret_val != 0)
363 return ret_val;
364 ret_val = nla_put_u32(skb, NLBL_MGMT_A_CV4DOI,
365 entry->type_def.cipsov4->doi);
366 break;
367 }
368
369 return ret_val;
370}
371
372/*
373 * NetLabel Command Handlers
374 */
375
376/**
377 * netlbl_mgmt_add - Handle an ADD message
378 * @skb: the NETLINK buffer
379 * @info: the Generic NETLINK info block
380 *
381 * Description:
382 * Process a user generated ADD message and add the domains from the message
383 * to the hash table. See netlabel.h for a description of the message format.
384 * Returns zero on success, negative values on failure.
385 *
386 */
387static int netlbl_mgmt_add(struct sk_buff *skb, struct genl_info *info)
388{
389 struct netlbl_audit audit_info;
390
391 if ((!info->attrs[NLBL_MGMT_A_DOMAIN]) ||
392 (!info->attrs[NLBL_MGMT_A_PROTOCOL]) ||
393 (info->attrs[NLBL_MGMT_A_IPV4ADDR] &&
394 info->attrs[NLBL_MGMT_A_IPV6ADDR]) ||
395 (info->attrs[NLBL_MGMT_A_IPV4MASK] &&
396 info->attrs[NLBL_MGMT_A_IPV6MASK]) ||
397 ((info->attrs[NLBL_MGMT_A_IPV4ADDR] != NULL) ^
398 (info->attrs[NLBL_MGMT_A_IPV4MASK] != NULL)) ||
399 ((info->attrs[NLBL_MGMT_A_IPV6ADDR] != NULL) ^
400 (info->attrs[NLBL_MGMT_A_IPV6MASK] != NULL)))
401 return -EINVAL;
402
403 netlbl_netlink_auditinfo(skb, &audit_info);
404
405 return netlbl_mgmt_add_common(info, &audit_info);
406}
407
408/**
154 * netlbl_mgmt_remove - Handle a REMOVE message 409 * netlbl_mgmt_remove - Handle a REMOVE message
155 * @skb: the NETLINK buffer 410 * @skb: the NETLINK buffer
156 * @info: the Generic NETLINK info block 411 * @info: the Generic NETLINK info block
@@ -198,23 +453,9 @@ static int netlbl_mgmt_listall_cb(struct netlbl_dom_map *entry, void *arg)
198 if (data == NULL) 453 if (data == NULL)
199 goto listall_cb_failure; 454 goto listall_cb_failure;
200 455
201 ret_val = nla_put_string(cb_arg->skb, 456 ret_val = netlbl_mgmt_listentry(cb_arg->skb, entry);
202 NLBL_MGMT_A_DOMAIN,
203 entry->domain);
204 if (ret_val != 0) 457 if (ret_val != 0)
205 goto listall_cb_failure; 458 goto listall_cb_failure;
206 ret_val = nla_put_u32(cb_arg->skb, NLBL_MGMT_A_PROTOCOL, entry->type);
207 if (ret_val != 0)
208 goto listall_cb_failure;
209 switch (entry->type) {
210 case NETLBL_NLTYPE_CIPSOV4:
211 ret_val = nla_put_u32(cb_arg->skb,
212 NLBL_MGMT_A_CV4DOI,
213 entry->type_def.cipsov4->doi);
214 if (ret_val != 0)
215 goto listall_cb_failure;
216 break;
217 }
218 459
219 cb_arg->seq++; 460 cb_arg->seq++;
220 return genlmsg_end(cb_arg->skb, data); 461 return genlmsg_end(cb_arg->skb, data);
@@ -268,56 +509,22 @@ static int netlbl_mgmt_listall(struct sk_buff *skb,
268 */ 509 */
269static int netlbl_mgmt_adddef(struct sk_buff *skb, struct genl_info *info) 510static int netlbl_mgmt_adddef(struct sk_buff *skb, struct genl_info *info)
270{ 511{
271 int ret_val = -EINVAL;
272 struct netlbl_dom_map *entry = NULL;
273 u32 tmp_val;
274 struct netlbl_audit audit_info; 512 struct netlbl_audit audit_info;
275 513
276 if (!info->attrs[NLBL_MGMT_A_PROTOCOL]) 514 if ((!info->attrs[NLBL_MGMT_A_PROTOCOL]) ||
277 goto adddef_failure; 515 (info->attrs[NLBL_MGMT_A_IPV4ADDR] &&
516 info->attrs[NLBL_MGMT_A_IPV6ADDR]) ||
517 (info->attrs[NLBL_MGMT_A_IPV4MASK] &&
518 info->attrs[NLBL_MGMT_A_IPV6MASK]) ||
519 ((info->attrs[NLBL_MGMT_A_IPV4ADDR] != NULL) ^
520 (info->attrs[NLBL_MGMT_A_IPV4MASK] != NULL)) ||
521 ((info->attrs[NLBL_MGMT_A_IPV6ADDR] != NULL) ^
522 (info->attrs[NLBL_MGMT_A_IPV6MASK] != NULL)))
523 return -EINVAL;
278 524
279 netlbl_netlink_auditinfo(skb, &audit_info); 525 netlbl_netlink_auditinfo(skb, &audit_info);
280 526
281 entry = kzalloc(sizeof(*entry), GFP_KERNEL); 527 return netlbl_mgmt_add_common(info, &audit_info);
282 if (entry == NULL) {
283 ret_val = -ENOMEM;
284 goto adddef_failure;
285 }
286 entry->type = nla_get_u32(info->attrs[NLBL_MGMT_A_PROTOCOL]);
287
288 switch (entry->type) {
289 case NETLBL_NLTYPE_UNLABELED:
290 ret_val = netlbl_domhsh_add_default(entry, &audit_info);
291 break;
292 case NETLBL_NLTYPE_CIPSOV4:
293 if (!info->attrs[NLBL_MGMT_A_CV4DOI])
294 goto adddef_failure;
295
296 tmp_val = nla_get_u32(info->attrs[NLBL_MGMT_A_CV4DOI]);
297 /* We should be holding a rcu_read_lock() here while we hold
298 * the result but since the entry will always be deleted when
299 * the CIPSO DOI is deleted we aren't going to keep the
300 * lock. */
301 rcu_read_lock();
302 entry->type_def.cipsov4 = cipso_v4_doi_getdef(tmp_val);
303 if (entry->type_def.cipsov4 == NULL) {
304 rcu_read_unlock();
305 goto adddef_failure;
306 }
307 ret_val = netlbl_domhsh_add_default(entry, &audit_info);
308 rcu_read_unlock();
309 break;
310 default:
311 goto adddef_failure;
312 }
313 if (ret_val != 0)
314 goto adddef_failure;
315
316 return 0;
317
318adddef_failure:
319 kfree(entry);
320 return ret_val;
321} 528}
322 529
323/** 530/**
@@ -371,19 +578,10 @@ static int netlbl_mgmt_listdef(struct sk_buff *skb, struct genl_info *info)
371 ret_val = -ENOENT; 578 ret_val = -ENOENT;
372 goto listdef_failure_lock; 579 goto listdef_failure_lock;
373 } 580 }
374 ret_val = nla_put_u32(ans_skb, NLBL_MGMT_A_PROTOCOL, entry->type); 581 ret_val = netlbl_mgmt_listentry(ans_skb, entry);
375 if (ret_val != 0)
376 goto listdef_failure_lock;
377 switch (entry->type) {
378 case NETLBL_NLTYPE_CIPSOV4:
379 ret_val = nla_put_u32(ans_skb,
380 NLBL_MGMT_A_CV4DOI,
381 entry->type_def.cipsov4->doi);
382 if (ret_val != 0)
383 goto listdef_failure_lock;
384 break;
385 }
386 rcu_read_unlock(); 582 rcu_read_unlock();
583 if (ret_val != 0)
584 goto listdef_failure;
387 585
388 genlmsg_end(ans_skb, data); 586 genlmsg_end(ans_skb, data);
389 return genlmsg_reply(ans_skb, info); 587 return genlmsg_reply(ans_skb, info);
diff --git a/net/netlabel/netlabel_mgmt.h b/net/netlabel/netlabel_mgmt.h
index a43bff169d6..05d96431f81 100644
--- a/net/netlabel/netlabel_mgmt.h
+++ b/net/netlabel/netlabel_mgmt.h
@@ -45,6 +45,16 @@
45 * NLBL_MGMT_A_DOMAIN 45 * NLBL_MGMT_A_DOMAIN
46 * NLBL_MGMT_A_PROTOCOL 46 * NLBL_MGMT_A_PROTOCOL
47 * 47 *
48 * If IPv4 is specified the following attributes are required:
49 *
50 * NLBL_MGMT_A_IPV4ADDR
51 * NLBL_MGMT_A_IPV4MASK
52 *
53 * If IPv6 is specified the following attributes are required:
54 *
55 * NLBL_MGMT_A_IPV6ADDR
56 * NLBL_MGMT_A_IPV6MASK
57 *
48 * If using NETLBL_NLTYPE_CIPSOV4 the following attributes are required: 58 * If using NETLBL_NLTYPE_CIPSOV4 the following attributes are required:
49 * 59 *
50 * NLBL_MGMT_A_CV4DOI 60 * NLBL_MGMT_A_CV4DOI
@@ -68,13 +78,24 @@
68 * Required attributes: 78 * Required attributes:
69 * 79 *
70 * NLBL_MGMT_A_DOMAIN 80 * NLBL_MGMT_A_DOMAIN
81 *
82 * If the IP address selectors are not used the following attribute is
83 * required:
84 *
71 * NLBL_MGMT_A_PROTOCOL 85 * NLBL_MGMT_A_PROTOCOL
72 * 86 *
73 * If using NETLBL_NLTYPE_CIPSOV4 the following attributes are required: 87 * If the IP address selectors are used then the following attritbute is
88 * required:
89 *
90 * NLBL_MGMT_A_SELECTORLIST
91 *
92 * If the mapping is using the NETLBL_NLTYPE_CIPSOV4 type then the following
93 * attributes are required:
74 * 94 *
75 * NLBL_MGMT_A_CV4DOI 95 * NLBL_MGMT_A_CV4DOI
76 * 96 *
77 * If using NETLBL_NLTYPE_UNLABELED no other attributes are required. 97 * If the mapping is using the NETLBL_NLTYPE_UNLABELED type no other
98 * attributes are required.
78 * 99 *
79 * o ADDDEF: 100 * o ADDDEF:
80 * Sent by an application to set the default domain mapping for the NetLabel 101 * Sent by an application to set the default domain mapping for the NetLabel
@@ -100,15 +121,23 @@
100 * application there is no payload. On success the kernel should send a 121 * application there is no payload. On success the kernel should send a
101 * response using the following format. 122 * response using the following format.
102 * 123 *
103 * Required attributes: 124 * If the IP address selectors are not used the following attribute is
125 * required:
104 * 126 *
105 * NLBL_MGMT_A_PROTOCOL 127 * NLBL_MGMT_A_PROTOCOL
106 * 128 *
107 * If using NETLBL_NLTYPE_CIPSOV4 the following attributes are required: 129 * If the IP address selectors are used then the following attritbute is
130 * required:
131 *
132 * NLBL_MGMT_A_SELECTORLIST
133 *
134 * If the mapping is using the NETLBL_NLTYPE_CIPSOV4 type then the following
135 * attributes are required:
108 * 136 *
109 * NLBL_MGMT_A_CV4DOI 137 * NLBL_MGMT_A_CV4DOI
110 * 138 *
111 * If using NETLBL_NLTYPE_UNLABELED no other attributes are required. 139 * If the mapping is using the NETLBL_NLTYPE_UNLABELED type no other
140 * attributes are required.
112 * 141 *
113 * o PROTOCOLS: 142 * o PROTOCOLS:
114 * Sent by an application to request a list of configured NetLabel protocols 143 * Sent by an application to request a list of configured NetLabel protocols
@@ -162,6 +191,26 @@ enum {
162 NLBL_MGMT_A_CV4DOI, 191 NLBL_MGMT_A_CV4DOI,
163 /* (NLA_U32) 192 /* (NLA_U32)
164 * the CIPSOv4 DOI value */ 193 * the CIPSOv4 DOI value */
194 NLBL_MGMT_A_IPV6ADDR,
195 /* (NLA_BINARY, struct in6_addr)
196 * an IPv6 address */
197 NLBL_MGMT_A_IPV6MASK,
198 /* (NLA_BINARY, struct in6_addr)
199 * an IPv6 address mask */
200 NLBL_MGMT_A_IPV4ADDR,
201 /* (NLA_BINARY, struct in_addr)
202 * an IPv4 address */
203 NLBL_MGMT_A_IPV4MASK,
204 /* (NLA_BINARY, struct in_addr)
205 * and IPv4 address mask */
206 NLBL_MGMT_A_ADDRSELECTOR,
207 /* (NLA_NESTED)
208 * an IP address selector, must contain an address, mask, and protocol
209 * attribute plus any protocol specific attributes */
210 NLBL_MGMT_A_SELECTORLIST,
211 /* (NLA_NESTED)
212 * the selector list, there must be at least one
213 * NLBL_MGMT_A_ADDRSELECTOR attribute */
165 __NLBL_MGMT_A_MAX, 214 __NLBL_MGMT_A_MAX,
166}; 215};
167#define NLBL_MGMT_A_MAX (__NLBL_MGMT_A_MAX - 1) 216#define NLBL_MGMT_A_MAX (__NLBL_MGMT_A_MAX - 1)
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index 921c118ead8..e8a5c32b0f1 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -10,7 +10,7 @@
10 */ 10 */
11 11
12/* 12/*
13 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 - 2007 13 * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 - 2008
14 * 14 *
15 * This program is free software; you can redistribute it and/or modify 15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by 16 * it under the terms of the GNU General Public License as published by
@@ -54,6 +54,7 @@
54#include <asm/atomic.h> 54#include <asm/atomic.h>
55 55
56#include "netlabel_user.h" 56#include "netlabel_user.h"
57#include "netlabel_addrlist.h"
57#include "netlabel_domainhash.h" 58#include "netlabel_domainhash.h"
58#include "netlabel_unlabeled.h" 59#include "netlabel_unlabeled.h"
59#include "netlabel_mgmt.h" 60#include "netlabel_mgmt.h"
@@ -76,22 +77,20 @@ struct netlbl_unlhsh_tbl {
76 struct list_head *tbl; 77 struct list_head *tbl;
77 u32 size; 78 u32 size;
78}; 79};
80#define netlbl_unlhsh_addr4_entry(iter) \
81 container_of(iter, struct netlbl_unlhsh_addr4, list)
79struct netlbl_unlhsh_addr4 { 82struct netlbl_unlhsh_addr4 {
80 __be32 addr;
81 __be32 mask;
82 u32 secid; 83 u32 secid;
83 84
84 u32 valid; 85 struct netlbl_af4list list;
85 struct list_head list;
86 struct rcu_head rcu; 86 struct rcu_head rcu;
87}; 87};
88#define netlbl_unlhsh_addr6_entry(iter) \
89 container_of(iter, struct netlbl_unlhsh_addr6, list)
88struct netlbl_unlhsh_addr6 { 90struct netlbl_unlhsh_addr6 {
89 struct in6_addr addr;
90 struct in6_addr mask;
91 u32 secid; 91 u32 secid;
92 92
93 u32 valid; 93 struct netlbl_af6list list;
94 struct list_head list;
95 struct rcu_head rcu; 94 struct rcu_head rcu;
96}; 95};
97struct netlbl_unlhsh_iface { 96struct netlbl_unlhsh_iface {
@@ -147,76 +146,6 @@ static const struct nla_policy netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1
147}; 146};
148 147
149/* 148/*
150 * Audit Helper Functions
151 */
152
153/**
154 * netlbl_unlabel_audit_addr4 - Audit an IPv4 address
155 * @audit_buf: audit buffer
156 * @dev: network interface
157 * @addr: IP address
158 * @mask: IP address mask
159 *
160 * Description:
161 * Write the IPv4 address and address mask, if necessary, to @audit_buf.
162 *
163 */
164static void netlbl_unlabel_audit_addr4(struct audit_buffer *audit_buf,
165 const char *dev,
166 __be32 addr, __be32 mask)
167{
168 u32 mask_val = ntohl(mask);
169
170 if (dev != NULL)
171 audit_log_format(audit_buf, " netif=%s", dev);
172 audit_log_format(audit_buf, " src=" NIPQUAD_FMT, NIPQUAD(addr));
173 if (mask_val != 0xffffffff) {
174 u32 mask_len = 0;
175 while (mask_val > 0) {
176 mask_val <<= 1;
177 mask_len++;
178 }
179 audit_log_format(audit_buf, " src_prefixlen=%d", mask_len);
180 }
181}
182
183#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
184/**
185 * netlbl_unlabel_audit_addr6 - Audit an IPv6 address
186 * @audit_buf: audit buffer
187 * @dev: network interface
188 * @addr: IP address
189 * @mask: IP address mask
190 *
191 * Description:
192 * Write the IPv6 address and address mask, if necessary, to @audit_buf.
193 *
194 */
195static void netlbl_unlabel_audit_addr6(struct audit_buffer *audit_buf,
196 const char *dev,
197 const struct in6_addr *addr,
198 const struct in6_addr *mask)
199{
200 if (dev != NULL)
201 audit_log_format(audit_buf, " netif=%s", dev);
202 audit_log_format(audit_buf, " src=" NIP6_FMT, NIP6(*addr));
203 if (ntohl(mask->s6_addr32[3]) != 0xffffffff) {
204 u32 mask_len = 0;
205 u32 mask_val;
206 int iter = -1;
207 while (ntohl(mask->s6_addr32[++iter]) == 0xffffffff)
208 mask_len += 32;
209 mask_val = ntohl(mask->s6_addr32[iter]);
210 while (mask_val > 0) {
211 mask_val <<= 1;
212 mask_len++;
213 }
214 audit_log_format(audit_buf, " src_prefixlen=%d", mask_len);
215 }
216}
217#endif /* IPv6 */
218
219/*
220 * Unlabeled Connection Hash Table Functions 149 * Unlabeled Connection Hash Table Functions
221 */ 150 */
222 151
@@ -274,26 +203,28 @@ static void netlbl_unlhsh_free_addr6(struct rcu_head *entry)
274static void netlbl_unlhsh_free_iface(struct rcu_head *entry) 203static void netlbl_unlhsh_free_iface(struct rcu_head *entry)
275{ 204{
276 struct netlbl_unlhsh_iface *iface; 205 struct netlbl_unlhsh_iface *iface;
277 struct netlbl_unlhsh_addr4 *iter4; 206 struct netlbl_af4list *iter4;
278 struct netlbl_unlhsh_addr4 *tmp4; 207 struct netlbl_af4list *tmp4;
279 struct netlbl_unlhsh_addr6 *iter6; 208#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
280 struct netlbl_unlhsh_addr6 *tmp6; 209 struct netlbl_af6list *iter6;
210 struct netlbl_af6list *tmp6;
211#endif /* IPv6 */
281 212
282 iface = container_of(entry, struct netlbl_unlhsh_iface, rcu); 213 iface = container_of(entry, struct netlbl_unlhsh_iface, rcu);
283 214
284 /* no need for locks here since we are the only one with access to this 215 /* no need for locks here since we are the only one with access to this
285 * structure */ 216 * structure */
286 217
287 list_for_each_entry_safe(iter4, tmp4, &iface->addr4_list, list) 218 netlbl_af4list_foreach_safe(iter4, tmp4, &iface->addr4_list) {
288 if (iter4->valid) { 219 netlbl_af4list_remove_entry(iter4);
289 list_del_rcu(&iter4->list); 220 kfree(netlbl_unlhsh_addr4_entry(iter4));
290 kfree(iter4); 221 }
291 } 222#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
292 list_for_each_entry_safe(iter6, tmp6, &iface->addr6_list, list) 223 netlbl_af6list_foreach_safe(iter6, tmp6, &iface->addr6_list) {
293 if (iter6->valid) { 224 netlbl_af6list_remove_entry(iter6);
294 list_del_rcu(&iter6->list); 225 kfree(netlbl_unlhsh_addr6_entry(iter6));
295 kfree(iter6); 226 }
296 } 227#endif /* IPv6 */
297 kfree(iface); 228 kfree(iface);
298} 229}
299 230
@@ -316,59 +247,6 @@ static u32 netlbl_unlhsh_hash(int ifindex)
316} 247}
317 248
318/** 249/**
319 * netlbl_unlhsh_search_addr4 - Search for a matching IPv4 address entry
320 * @addr: IPv4 address
321 * @iface: the network interface entry
322 *
323 * Description:
324 * Searches the IPv4 address list of the network interface specified by @iface.
325 * If a matching address entry is found it is returned, otherwise NULL is
326 * returned. The caller is responsible for calling the rcu_read_[un]lock()
327 * functions.
328 *
329 */
330static struct netlbl_unlhsh_addr4 *netlbl_unlhsh_search_addr4(
331 __be32 addr,
332 const struct netlbl_unlhsh_iface *iface)
333{
334 struct netlbl_unlhsh_addr4 *iter;
335
336 list_for_each_entry_rcu(iter, &iface->addr4_list, list)
337 if (iter->valid && (addr & iter->mask) == iter->addr)
338 return iter;
339
340 return NULL;
341}
342
343#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
344/**
345 * netlbl_unlhsh_search_addr6 - Search for a matching IPv6 address entry
346 * @addr: IPv6 address
347 * @iface: the network interface entry
348 *
349 * Description:
350 * Searches the IPv6 address list of the network interface specified by @iface.
351 * If a matching address entry is found it is returned, otherwise NULL is
352 * returned. The caller is responsible for calling the rcu_read_[un]lock()
353 * functions.
354 *
355 */
356static struct netlbl_unlhsh_addr6 *netlbl_unlhsh_search_addr6(
357 const struct in6_addr *addr,
358 const struct netlbl_unlhsh_iface *iface)
359{
360 struct netlbl_unlhsh_addr6 *iter;
361
362 list_for_each_entry_rcu(iter, &iface->addr6_list, list)
363 if (iter->valid &&
364 ipv6_masked_addr_cmp(&iter->addr, &iter->mask, addr) == 0)
365 return iter;
366
367 return NULL;
368}
369#endif /* IPv6 */
370
371/**
372 * netlbl_unlhsh_search_iface - Search for a matching interface entry 250 * netlbl_unlhsh_search_iface - Search for a matching interface entry
373 * @ifindex: the network interface 251 * @ifindex: the network interface
374 * 252 *
@@ -381,12 +259,12 @@ static struct netlbl_unlhsh_addr6 *netlbl_unlhsh_search_addr6(
381static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex) 259static struct netlbl_unlhsh_iface *netlbl_unlhsh_search_iface(int ifindex)
382{ 260{
383 u32 bkt; 261 u32 bkt;
262 struct list_head *bkt_list;
384 struct netlbl_unlhsh_iface *iter; 263 struct netlbl_unlhsh_iface *iter;
385 264
386 bkt = netlbl_unlhsh_hash(ifindex); 265 bkt = netlbl_unlhsh_hash(ifindex);
387 list_for_each_entry_rcu(iter, 266 bkt_list = &rcu_dereference(netlbl_unlhsh)->tbl[bkt];
388 &rcu_dereference(netlbl_unlhsh)->tbl[bkt], 267 list_for_each_entry_rcu(iter, bkt_list, list)
389 list)
390 if (iter->valid && iter->ifindex == ifindex) 268 if (iter->valid && iter->ifindex == ifindex)
391 return iter; 269 return iter;
392 270
@@ -439,43 +317,26 @@ static int netlbl_unlhsh_add_addr4(struct netlbl_unlhsh_iface *iface,
439 const struct in_addr *mask, 317 const struct in_addr *mask,
440 u32 secid) 318 u32 secid)
441{ 319{
320 int ret_val;
442 struct netlbl_unlhsh_addr4 *entry; 321 struct netlbl_unlhsh_addr4 *entry;
443 struct netlbl_unlhsh_addr4 *iter;
444 322
445 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 323 entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
446 if (entry == NULL) 324 if (entry == NULL)
447 return -ENOMEM; 325 return -ENOMEM;
448 326
449 entry->addr = addr->s_addr & mask->s_addr; 327 entry->list.addr = addr->s_addr & mask->s_addr;
450 entry->mask = mask->s_addr; 328 entry->list.mask = mask->s_addr;
451 entry->secid = secid; 329 entry->list.valid = 1;
452 entry->valid = 1;
453 INIT_RCU_HEAD(&entry->rcu); 330 INIT_RCU_HEAD(&entry->rcu);
331 entry->secid = secid;
454 332
455 spin_lock(&netlbl_unlhsh_lock); 333 spin_lock(&netlbl_unlhsh_lock);
456 iter = netlbl_unlhsh_search_addr4(entry->addr, iface); 334 ret_val = netlbl_af4list_add(&entry->list, &iface->addr4_list);
457 if (iter != NULL &&
458 iter->addr == addr->s_addr && iter->mask == mask->s_addr) {
459 spin_unlock(&netlbl_unlhsh_lock);
460 kfree(entry);
461 return -EEXIST;
462 }
463 /* in order to speed up address searches through the list (the common
464 * case) we need to keep the list in order based on the size of the
465 * address mask such that the entry with the widest mask (smallest
466 * numerical value) appears first in the list */
467 list_for_each_entry_rcu(iter, &iface->addr4_list, list)
468 if (iter->valid &&
469 ntohl(entry->mask) > ntohl(iter->mask)) {
470 __list_add_rcu(&entry->list,
471 iter->list.prev,
472 &iter->list);
473 spin_unlock(&netlbl_unlhsh_lock);
474 return 0;
475 }
476 list_add_tail_rcu(&entry->list, &iface->addr4_list);
477 spin_unlock(&netlbl_unlhsh_lock); 335 spin_unlock(&netlbl_unlhsh_lock);
478 return 0; 336
337 if (ret_val != 0)
338 kfree(entry);
339 return ret_val;
479} 340}
480 341
481#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 342#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
@@ -498,47 +359,29 @@ static int netlbl_unlhsh_add_addr6(struct netlbl_unlhsh_iface *iface,
498 const struct in6_addr *mask, 359 const struct in6_addr *mask,
499 u32 secid) 360 u32 secid)
500{ 361{
362 int ret_val;
501 struct netlbl_unlhsh_addr6 *entry; 363 struct netlbl_unlhsh_addr6 *entry;
502 struct netlbl_unlhsh_addr6 *iter;
503 364
504 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 365 entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
505 if (entry == NULL) 366 if (entry == NULL)
506 return -ENOMEM; 367 return -ENOMEM;
507 368
508 ipv6_addr_copy(&entry->addr, addr); 369 ipv6_addr_copy(&entry->list.addr, addr);
509 entry->addr.s6_addr32[0] &= mask->s6_addr32[0]; 370 entry->list.addr.s6_addr32[0] &= mask->s6_addr32[0];
510 entry->addr.s6_addr32[1] &= mask->s6_addr32[1]; 371 entry->list.addr.s6_addr32[1] &= mask->s6_addr32[1];
511 entry->addr.s6_addr32[2] &= mask->s6_addr32[2]; 372 entry->list.addr.s6_addr32[2] &= mask->s6_addr32[2];
512 entry->addr.s6_addr32[3] &= mask->s6_addr32[3]; 373 entry->list.addr.s6_addr32[3] &= mask->s6_addr32[3];
513 ipv6_addr_copy(&entry->mask, mask); 374 ipv6_addr_copy(&entry->list.mask, mask);
514 entry->secid = secid; 375 entry->list.valid = 1;
515 entry->valid = 1;
516 INIT_RCU_HEAD(&entry->rcu); 376 INIT_RCU_HEAD(&entry->rcu);
377 entry->secid = secid;
517 378
518 spin_lock(&netlbl_unlhsh_lock); 379 spin_lock(&netlbl_unlhsh_lock);
519 iter = netlbl_unlhsh_search_addr6(&entry->addr, iface); 380 ret_val = netlbl_af6list_add(&entry->list, &iface->addr6_list);
520 if (iter != NULL &&
521 (ipv6_addr_equal(&iter->addr, addr) &&
522 ipv6_addr_equal(&iter->mask, mask))) {
523 spin_unlock(&netlbl_unlhsh_lock);
524 kfree(entry);
525 return -EEXIST;
526 }
527 /* in order to speed up address searches through the list (the common
528 * case) we need to keep the list in order based on the size of the
529 * address mask such that the entry with the widest mask (smallest
530 * numerical value) appears first in the list */
531 list_for_each_entry_rcu(iter, &iface->addr6_list, list)
532 if (iter->valid &&
533 ipv6_addr_cmp(&entry->mask, &iter->mask) > 0) {
534 __list_add_rcu(&entry->list,
535 iter->list.prev,
536 &iter->list);
537 spin_unlock(&netlbl_unlhsh_lock);
538 return 0;
539 }
540 list_add_tail_rcu(&entry->list, &iface->addr6_list);
541 spin_unlock(&netlbl_unlhsh_lock); 381 spin_unlock(&netlbl_unlhsh_lock);
382
383 if (ret_val != 0)
384 kfree(entry);
542 return 0; 385 return 0;
543} 386}
544#endif /* IPv6 */ 387#endif /* IPv6 */
@@ -658,10 +501,10 @@ static int netlbl_unlhsh_add(struct net *net,
658 mask4 = (struct in_addr *)mask; 501 mask4 = (struct in_addr *)mask;
659 ret_val = netlbl_unlhsh_add_addr4(iface, addr4, mask4, secid); 502 ret_val = netlbl_unlhsh_add_addr4(iface, addr4, mask4, secid);
660 if (audit_buf != NULL) 503 if (audit_buf != NULL)
661 netlbl_unlabel_audit_addr4(audit_buf, 504 netlbl_af4list_audit_addr(audit_buf, 1,
662 dev_name, 505 dev_name,
663 addr4->s_addr, 506 addr4->s_addr,
664 mask4->s_addr); 507 mask4->s_addr);
665 break; 508 break;
666 } 509 }
667#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 510#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
@@ -672,9 +515,9 @@ static int netlbl_unlhsh_add(struct net *net,
672 mask6 = (struct in6_addr *)mask; 515 mask6 = (struct in6_addr *)mask;
673 ret_val = netlbl_unlhsh_add_addr6(iface, addr6, mask6, secid); 516 ret_val = netlbl_unlhsh_add_addr6(iface, addr6, mask6, secid);
674 if (audit_buf != NULL) 517 if (audit_buf != NULL)
675 netlbl_unlabel_audit_addr6(audit_buf, 518 netlbl_af6list_audit_addr(audit_buf, 1,
676 dev_name, 519 dev_name,
677 addr6, mask6); 520 addr6, mask6);
678 break; 521 break;
679 } 522 }
680#endif /* IPv6 */ 523#endif /* IPv6 */
@@ -719,35 +562,34 @@ static int netlbl_unlhsh_remove_addr4(struct net *net,
719 const struct in_addr *mask, 562 const struct in_addr *mask,
720 struct netlbl_audit *audit_info) 563 struct netlbl_audit *audit_info)
721{ 564{
722 int ret_val = -ENOENT; 565 int ret_val = 0;
566 struct netlbl_af4list *list_entry;
723 struct netlbl_unlhsh_addr4 *entry; 567 struct netlbl_unlhsh_addr4 *entry;
724 struct audit_buffer *audit_buf = NULL; 568 struct audit_buffer *audit_buf;
725 struct net_device *dev; 569 struct net_device *dev;
726 char *secctx = NULL; 570 char *secctx;
727 u32 secctx_len; 571 u32 secctx_len;
728 572
729 spin_lock(&netlbl_unlhsh_lock); 573 spin_lock(&netlbl_unlhsh_lock);
730 entry = netlbl_unlhsh_search_addr4(addr->s_addr, iface); 574 list_entry = netlbl_af4list_remove(addr->s_addr, mask->s_addr,
731 if (entry != NULL && 575 &iface->addr4_list);
732 entry->addr == addr->s_addr && entry->mask == mask->s_addr) {
733 entry->valid = 0;
734 list_del_rcu(&entry->list);
735 ret_val = 0;
736 }
737 spin_unlock(&netlbl_unlhsh_lock); 576 spin_unlock(&netlbl_unlhsh_lock);
577 if (list_entry == NULL)
578 ret_val = -ENOENT;
579 entry = netlbl_unlhsh_addr4_entry(list_entry);
738 580
739 audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCDEL, 581 audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCDEL,
740 audit_info); 582 audit_info);
741 if (audit_buf != NULL) { 583 if (audit_buf != NULL) {
742 dev = dev_get_by_index(net, iface->ifindex); 584 dev = dev_get_by_index(net, iface->ifindex);
743 netlbl_unlabel_audit_addr4(audit_buf, 585 netlbl_af4list_audit_addr(audit_buf, 1,
744 (dev != NULL ? dev->name : NULL), 586 (dev != NULL ? dev->name : NULL),
745 entry->addr, entry->mask); 587 addr->s_addr, mask->s_addr);
746 if (dev != NULL) 588 if (dev != NULL)
747 dev_put(dev); 589 dev_put(dev);
748 if (security_secid_to_secctx(entry->secid, 590 if (entry && security_secid_to_secctx(entry->secid,
749 &secctx, 591 &secctx,
750 &secctx_len) == 0) { 592 &secctx_len) == 0) {
751 audit_log_format(audit_buf, " sec_obj=%s", secctx); 593 audit_log_format(audit_buf, " sec_obj=%s", secctx);
752 security_release_secctx(secctx, secctx_len); 594 security_release_secctx(secctx, secctx_len);
753 } 595 }
@@ -781,36 +623,33 @@ static int netlbl_unlhsh_remove_addr6(struct net *net,
781 const struct in6_addr *mask, 623 const struct in6_addr *mask,
782 struct netlbl_audit *audit_info) 624 struct netlbl_audit *audit_info)
783{ 625{
784 int ret_val = -ENOENT; 626 int ret_val = 0;
627 struct netlbl_af6list *list_entry;
785 struct netlbl_unlhsh_addr6 *entry; 628 struct netlbl_unlhsh_addr6 *entry;
786 struct audit_buffer *audit_buf = NULL; 629 struct audit_buffer *audit_buf;
787 struct net_device *dev; 630 struct net_device *dev;
788 char *secctx = NULL; 631 char *secctx;
789 u32 secctx_len; 632 u32 secctx_len;
790 633
791 spin_lock(&netlbl_unlhsh_lock); 634 spin_lock(&netlbl_unlhsh_lock);
792 entry = netlbl_unlhsh_search_addr6(addr, iface); 635 list_entry = netlbl_af6list_remove(addr, mask, &iface->addr6_list);
793 if (entry != NULL &&
794 (ipv6_addr_equal(&entry->addr, addr) &&
795 ipv6_addr_equal(&entry->mask, mask))) {
796 entry->valid = 0;
797 list_del_rcu(&entry->list);
798 ret_val = 0;
799 }
800 spin_unlock(&netlbl_unlhsh_lock); 636 spin_unlock(&netlbl_unlhsh_lock);
637 if (list_entry == NULL)
638 ret_val = -ENOENT;
639 entry = netlbl_unlhsh_addr6_entry(list_entry);
801 640
802 audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCDEL, 641 audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCDEL,
803 audit_info); 642 audit_info);
804 if (audit_buf != NULL) { 643 if (audit_buf != NULL) {
805 dev = dev_get_by_index(net, iface->ifindex); 644 dev = dev_get_by_index(net, iface->ifindex);
806 netlbl_unlabel_audit_addr6(audit_buf, 645 netlbl_af6list_audit_addr(audit_buf, 1,
807 (dev != NULL ? dev->name : NULL), 646 (dev != NULL ? dev->name : NULL),
808 addr, mask); 647 addr, mask);
809 if (dev != NULL) 648 if (dev != NULL)
810 dev_put(dev); 649 dev_put(dev);
811 if (security_secid_to_secctx(entry->secid, 650 if (entry && security_secid_to_secctx(entry->secid,
812 &secctx, 651 &secctx,
813 &secctx_len) == 0) { 652 &secctx_len) == 0) {
814 audit_log_format(audit_buf, " sec_obj=%s", secctx); 653 audit_log_format(audit_buf, " sec_obj=%s", secctx);
815 security_release_secctx(secctx, secctx_len); 654 security_release_secctx(secctx, secctx_len);
816 } 655 }
@@ -836,16 +675,18 @@ static int netlbl_unlhsh_remove_addr6(struct net *net,
836 */ 675 */
837static void netlbl_unlhsh_condremove_iface(struct netlbl_unlhsh_iface *iface) 676static void netlbl_unlhsh_condremove_iface(struct netlbl_unlhsh_iface *iface)
838{ 677{
839 struct netlbl_unlhsh_addr4 *iter4; 678 struct netlbl_af4list *iter4;
840 struct netlbl_unlhsh_addr6 *iter6; 679#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
680 struct netlbl_af6list *iter6;
681#endif /* IPv6 */
841 682
842 spin_lock(&netlbl_unlhsh_lock); 683 spin_lock(&netlbl_unlhsh_lock);
843 list_for_each_entry_rcu(iter4, &iface->addr4_list, list) 684 netlbl_af4list_foreach_rcu(iter4, &iface->addr4_list)
844 if (iter4->valid) 685 goto unlhsh_condremove_failure;
845 goto unlhsh_condremove_failure; 686#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
846 list_for_each_entry_rcu(iter6, &iface->addr6_list, list) 687 netlbl_af6list_foreach_rcu(iter6, &iface->addr6_list)
847 if (iter6->valid) 688 goto unlhsh_condremove_failure;
848 goto unlhsh_condremove_failure; 689#endif /* IPv6 */
849 iface->valid = 0; 690 iface->valid = 0;
850 if (iface->ifindex > 0) 691 if (iface->ifindex > 0)
851 list_del_rcu(&iface->list); 692 list_del_rcu(&iface->list);
@@ -1349,7 +1190,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd,
1349 if (addr4) { 1190 if (addr4) {
1350 struct in_addr addr_struct; 1191 struct in_addr addr_struct;
1351 1192
1352 addr_struct.s_addr = addr4->addr; 1193 addr_struct.s_addr = addr4->list.addr;
1353 ret_val = nla_put(cb_arg->skb, 1194 ret_val = nla_put(cb_arg->skb,
1354 NLBL_UNLABEL_A_IPV4ADDR, 1195 NLBL_UNLABEL_A_IPV4ADDR,
1355 sizeof(struct in_addr), 1196 sizeof(struct in_addr),
@@ -1357,7 +1198,7 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd,
1357 if (ret_val != 0) 1198 if (ret_val != 0)
1358 goto list_cb_failure; 1199 goto list_cb_failure;
1359 1200
1360 addr_struct.s_addr = addr4->mask; 1201 addr_struct.s_addr = addr4->list.mask;
1361 ret_val = nla_put(cb_arg->skb, 1202 ret_val = nla_put(cb_arg->skb,
1362 NLBL_UNLABEL_A_IPV4MASK, 1203 NLBL_UNLABEL_A_IPV4MASK,
1363 sizeof(struct in_addr), 1204 sizeof(struct in_addr),
@@ -1370,14 +1211,14 @@ static int netlbl_unlabel_staticlist_gen(u32 cmd,
1370 ret_val = nla_put(cb_arg->skb, 1211 ret_val = nla_put(cb_arg->skb,
1371 NLBL_UNLABEL_A_IPV6ADDR, 1212 NLBL_UNLABEL_A_IPV6ADDR,
1372 sizeof(struct in6_addr), 1213 sizeof(struct in6_addr),
1373 &addr6->addr); 1214 &addr6->list.addr);
1374 if (ret_val != 0) 1215 if (ret_val != 0)
1375 goto list_cb_failure; 1216 goto list_cb_failure;
1376 1217
1377 ret_val = nla_put(cb_arg->skb, 1218 ret_val = nla_put(cb_arg->skb,
1378 NLBL_UNLABEL_A_IPV6MASK, 1219 NLBL_UNLABEL_A_IPV6MASK,
1379 sizeof(struct in6_addr), 1220 sizeof(struct in6_addr),
1380 &addr6->mask); 1221 &addr6->list.mask);
1381 if (ret_val != 0) 1222 if (ret_val != 0)
1382 goto list_cb_failure; 1223 goto list_cb_failure;
1383 1224
@@ -1425,8 +1266,11 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
1425 u32 iter_bkt; 1266 u32 iter_bkt;
1426 u32 iter_chain = 0, iter_addr4 = 0, iter_addr6 = 0; 1267 u32 iter_chain = 0, iter_addr4 = 0, iter_addr6 = 0;
1427 struct netlbl_unlhsh_iface *iface; 1268 struct netlbl_unlhsh_iface *iface;
1428 struct netlbl_unlhsh_addr4 *addr4; 1269 struct list_head *iter_list;
1429 struct netlbl_unlhsh_addr6 *addr6; 1270 struct netlbl_af4list *addr4;
1271#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1272 struct netlbl_af6list *addr6;
1273#endif
1430 1274
1431 cb_arg.nl_cb = cb; 1275 cb_arg.nl_cb = cb;
1432 cb_arg.skb = skb; 1276 cb_arg.skb = skb;
@@ -1436,44 +1280,43 @@ static int netlbl_unlabel_staticlist(struct sk_buff *skb,
1436 for (iter_bkt = skip_bkt; 1280 for (iter_bkt = skip_bkt;
1437 iter_bkt < rcu_dereference(netlbl_unlhsh)->size; 1281 iter_bkt < rcu_dereference(netlbl_unlhsh)->size;
1438 iter_bkt++, iter_chain = 0, iter_addr4 = 0, iter_addr6 = 0) { 1282 iter_bkt++, iter_chain = 0, iter_addr4 = 0, iter_addr6 = 0) {
1439 list_for_each_entry_rcu(iface, 1283 iter_list = &rcu_dereference(netlbl_unlhsh)->tbl[iter_bkt];
1440 &rcu_dereference(netlbl_unlhsh)->tbl[iter_bkt], 1284 list_for_each_entry_rcu(iface, iter_list, list) {
1441 list) {
1442 if (!iface->valid || 1285 if (!iface->valid ||
1443 iter_chain++ < skip_chain) 1286 iter_chain++ < skip_chain)
1444 continue; 1287 continue;
1445 list_for_each_entry_rcu(addr4, 1288 netlbl_af4list_foreach_rcu(addr4,
1446 &iface->addr4_list, 1289 &iface->addr4_list) {
1447 list) { 1290 if (iter_addr4++ < skip_addr4)
1448 if (!addr4->valid || iter_addr4++ < skip_addr4)
1449 continue; 1291 continue;
1450 if (netlbl_unlabel_staticlist_gen( 1292 if (netlbl_unlabel_staticlist_gen(
1451 NLBL_UNLABEL_C_STATICLIST, 1293 NLBL_UNLABEL_C_STATICLIST,
1452 iface, 1294 iface,
1453 addr4, 1295 netlbl_unlhsh_addr4_entry(addr4),
1454 NULL, 1296 NULL,
1455 &cb_arg) < 0) { 1297 &cb_arg) < 0) {
1456 iter_addr4--; 1298 iter_addr4--;
1457 iter_chain--; 1299 iter_chain--;
1458 goto unlabel_staticlist_return; 1300 goto unlabel_staticlist_return;
1459 } 1301 }
1460 } 1302 }
1461 list_for_each_entry_rcu(addr6, 1303#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1462 &iface->addr6_list, 1304 netlbl_af6list_foreach_rcu(addr6,
1463 list) { 1305 &iface->addr6_list) {
1464 if (!addr6->valid || iter_addr6++ < skip_addr6) 1306 if (iter_addr6++ < skip_addr6)
1465 continue; 1307 continue;
1466 if (netlbl_unlabel_staticlist_gen( 1308 if (netlbl_unlabel_staticlist_gen(
1467 NLBL_UNLABEL_C_STATICLIST, 1309 NLBL_UNLABEL_C_STATICLIST,
1468 iface, 1310 iface,
1469 NULL, 1311 NULL,
1470 addr6, 1312 netlbl_unlhsh_addr6_entry(addr6),
1471 &cb_arg) < 0) { 1313 &cb_arg) < 0) {
1472 iter_addr6--; 1314 iter_addr6--;
1473 iter_chain--; 1315 iter_chain--;
1474 goto unlabel_staticlist_return; 1316 goto unlabel_staticlist_return;
1475 } 1317 }
1476 } 1318 }
1319#endif /* IPv6 */
1477 } 1320 }
1478 } 1321 }
1479 1322
@@ -1504,9 +1347,12 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
1504 struct netlbl_unlhsh_iface *iface; 1347 struct netlbl_unlhsh_iface *iface;
1505 u32 skip_addr4 = cb->args[0]; 1348 u32 skip_addr4 = cb->args[0];
1506 u32 skip_addr6 = cb->args[1]; 1349 u32 skip_addr6 = cb->args[1];
1507 u32 iter_addr4 = 0, iter_addr6 = 0; 1350 u32 iter_addr4 = 0;
1508 struct netlbl_unlhsh_addr4 *addr4; 1351 struct netlbl_af4list *addr4;
1509 struct netlbl_unlhsh_addr6 *addr6; 1352#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1353 u32 iter_addr6 = 0;
1354 struct netlbl_af6list *addr6;
1355#endif
1510 1356
1511 cb_arg.nl_cb = cb; 1357 cb_arg.nl_cb = cb;
1512 cb_arg.skb = skb; 1358 cb_arg.skb = skb;
@@ -1517,30 +1363,32 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
1517 if (iface == NULL || !iface->valid) 1363 if (iface == NULL || !iface->valid)
1518 goto unlabel_staticlistdef_return; 1364 goto unlabel_staticlistdef_return;
1519 1365
1520 list_for_each_entry_rcu(addr4, &iface->addr4_list, list) { 1366 netlbl_af4list_foreach_rcu(addr4, &iface->addr4_list) {
1521 if (!addr4->valid || iter_addr4++ < skip_addr4) 1367 if (iter_addr4++ < skip_addr4)
1522 continue; 1368 continue;
1523 if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF, 1369 if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF,
1524 iface, 1370 iface,
1525 addr4, 1371 netlbl_unlhsh_addr4_entry(addr4),
1526 NULL, 1372 NULL,
1527 &cb_arg) < 0) { 1373 &cb_arg) < 0) {
1528 iter_addr4--; 1374 iter_addr4--;
1529 goto unlabel_staticlistdef_return; 1375 goto unlabel_staticlistdef_return;
1530 } 1376 }
1531 } 1377 }
1532 list_for_each_entry_rcu(addr6, &iface->addr6_list, list) { 1378#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1533 if (!addr6->valid || iter_addr6++ < skip_addr6) 1379 netlbl_af6list_foreach_rcu(addr6, &iface->addr6_list) {
1380 if (iter_addr6++ < skip_addr6)
1534 continue; 1381 continue;
1535 if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF, 1382 if (netlbl_unlabel_staticlist_gen(NLBL_UNLABEL_C_STATICLISTDEF,
1536 iface, 1383 iface,
1537 NULL, 1384 NULL,
1538 addr6, 1385 netlbl_unlhsh_addr6_entry(addr6),
1539 &cb_arg) < 0) { 1386 &cb_arg) < 0) {
1540 iter_addr6--; 1387 iter_addr6--;
1541 goto unlabel_staticlistdef_return; 1388 goto unlabel_staticlistdef_return;
1542 } 1389 }
1543 } 1390 }
1391#endif /* IPv6 */
1544 1392
1545unlabel_staticlistdef_return: 1393unlabel_staticlistdef_return:
1546 rcu_read_unlock(); 1394 rcu_read_unlock();
@@ -1718,25 +1566,27 @@ int netlbl_unlabel_getattr(const struct sk_buff *skb,
1718 switch (family) { 1566 switch (family) {
1719 case PF_INET: { 1567 case PF_INET: {
1720 struct iphdr *hdr4; 1568 struct iphdr *hdr4;
1721 struct netlbl_unlhsh_addr4 *addr4; 1569 struct netlbl_af4list *addr4;
1722 1570
1723 hdr4 = ip_hdr(skb); 1571 hdr4 = ip_hdr(skb);
1724 addr4 = netlbl_unlhsh_search_addr4(hdr4->saddr, iface); 1572 addr4 = netlbl_af4list_search(hdr4->saddr,
1573 &iface->addr4_list);
1725 if (addr4 == NULL) 1574 if (addr4 == NULL)
1726 goto unlabel_getattr_nolabel; 1575 goto unlabel_getattr_nolabel;
1727 secattr->attr.secid = addr4->secid; 1576 secattr->attr.secid = netlbl_unlhsh_addr4_entry(addr4)->secid;
1728 break; 1577 break;
1729 } 1578 }
1730#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 1579#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1731 case PF_INET6: { 1580 case PF_INET6: {
1732 struct ipv6hdr *hdr6; 1581 struct ipv6hdr *hdr6;
1733 struct netlbl_unlhsh_addr6 *addr6; 1582 struct netlbl_af6list *addr6;
1734 1583
1735 hdr6 = ipv6_hdr(skb); 1584 hdr6 = ipv6_hdr(skb);
1736 addr6 = netlbl_unlhsh_search_addr6(&hdr6->saddr, iface); 1585 addr6 = netlbl_af6list_search(&hdr6->saddr,
1586 &iface->addr6_list);
1737 if (addr6 == NULL) 1587 if (addr6 == NULL)
1738 goto unlabel_getattr_nolabel; 1588 goto unlabel_getattr_nolabel;
1739 secattr->attr.secid = addr6->secid; 1589 secattr->attr.secid = netlbl_unlhsh_addr6_entry(addr6)->secid;
1740 break; 1590 break;
1741 } 1591 }
1742#endif /* IPv6 */ 1592#endif /* IPv6 */
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index b0eacc0007c..2fd8afac5f7 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * NETLINK Kernel-user communication protocol. 2 * NETLINK Kernel-user communication protocol.
3 * 3 *
4 * Authors: Alan Cox <alan@redhat.com> 4 * Authors: Alan Cox <alan@lxorguk.ukuu.org.uk>
5 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> 5 * Alexey Kuznetsov <kuznet@ms2.inr.ac.ru>
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index 532e4faa29f..9f1ea4a27b3 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 00000000000..51a5669573f
--- /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 00000000000..d62bbba649b
--- /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 00000000000..9e9c6fce11a
--- /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 00000000000..e087862ed7e
--- /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 00000000000..9978afbd9f2
--- /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 00000000000..bc6d50f8324
--- /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 00000000000..53be9fc82aa
--- /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 00000000000..b1770d66bc8
--- /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 00000000000..d81740187fb
--- /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 00000000000..600a4309b8c
--- /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.c b/net/rfkill/rfkill-input.c
index e5b69556bb5..21124ec0a73 100644
--- a/net/rfkill/rfkill-input.c
+++ b/net/rfkill/rfkill-input.c
@@ -16,6 +16,7 @@
16#include <linux/workqueue.h> 16#include <linux/workqueue.h>
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/rfkill.h> 18#include <linux/rfkill.h>
19#include <linux/sched.h>
19 20
20#include "rfkill-input.h" 21#include "rfkill-input.h"
21 22
diff --git a/net/rfkill/rfkill-input.h b/net/rfkill/rfkill-input.h
index f63d0504568..bbfa646157c 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 74aecc098ba..f949a482b00 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 9437b27ff84..6767e54155d 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 1d2b0f7df84..e60c9925b26 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 d1263b3c96c..0453d79ebf5 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 00000000000..fe9777e77f3
--- /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_flow.c b/net/sched/cls_flow.c
index 8f63a1a9401..0ebaff637e3 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/em_cmp.c b/net/sched/em_cmp.c
index cc49c932641..bc450397487 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_dsmark.c b/net/sched/sch_dsmark.c
index edd1298f85f..ba43aab3a85 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 9634091ee2f..7b5572d6beb 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_multiq.c b/net/sched/sch_multiq.c
new file mode 100644
index 00000000000..915f3149dde
--- /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 3781e55046d..a11959908d9 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -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 a6697c686c7..504a78cdb71 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 6e041d10dbd..fe1508ef0d3 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/sctp/associola.c b/net/sctp/associola.c
index 8472b8b349c..f4b23043b61 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 f62bc246893..6d5944a745d 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 47f91afa021..4124bbb9994 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 0dc4a7dfb23..c3f417f7ec6 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 4328ad5439c..247ebc95c1e 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 e8ca4e54981..fd8acb48c3f 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 9732c797e8e..e1d6076b4f5 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 8848d329aa2..d4c3fbc4671 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 d991237fb40..dd4ddc40c0a 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 5ffb9dec1c3..a1b904529d5 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 f3e58b27590..35c73e82553 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 a1f654aea26..5f186ca550d 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 5061a26c502..7b23803343c 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 8ef8ba81b9e..3e8d4e35c08 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/clnt.c b/net/sunrpc/clnt.c
index 76739e928d0..4895c341e46 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -174,7 +174,7 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru
174 clnt->cl_procinfo = version->procs; 174 clnt->cl_procinfo = version->procs;
175 clnt->cl_maxproc = version->nrprocs; 175 clnt->cl_maxproc = version->nrprocs;
176 clnt->cl_protname = program->name; 176 clnt->cl_protname = program->name;
177 clnt->cl_prog = program->number; 177 clnt->cl_prog = args->prognumber ? : program->number;
178 clnt->cl_vers = version->number; 178 clnt->cl_vers = version->number;
179 clnt->cl_stats = program->stats; 179 clnt->cl_stats = program->stats;
180 clnt->cl_metrics = rpc_alloc_iostats(clnt); 180 clnt->cl_metrics = rpc_alloc_iostats(clnt);
@@ -213,10 +213,10 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru
213 } 213 }
214 214
215 /* save the nodename */ 215 /* save the nodename */
216 clnt->cl_nodelen = strlen(utsname()->nodename); 216 clnt->cl_nodelen = strlen(init_utsname()->nodename);
217 if (clnt->cl_nodelen > UNX_MAXNODENAME) 217 if (clnt->cl_nodelen > UNX_MAXNODENAME)
218 clnt->cl_nodelen = UNX_MAXNODENAME; 218 clnt->cl_nodelen = UNX_MAXNODENAME;
219 memcpy(clnt->cl_nodename, utsname()->nodename, clnt->cl_nodelen); 219 memcpy(clnt->cl_nodename, init_utsname()->nodename, clnt->cl_nodelen);
220 rpc_register_client(clnt); 220 rpc_register_client(clnt);
221 return clnt; 221 return clnt;
222 222
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 24db2b4d12d..41013dd66ac 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -20,6 +20,7 @@
20#include <linux/in6.h> 20#include <linux/in6.h>
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/errno.h> 22#include <linux/errno.h>
23#include <net/ipv6.h>
23 24
24#include <linux/sunrpc/clnt.h> 25#include <linux/sunrpc/clnt.h>
25#include <linux/sunrpc/sched.h> 26#include <linux/sunrpc/sched.h>
@@ -176,13 +177,12 @@ static struct rpc_clnt *rpcb_create(char *hostname, struct sockaddr *srvaddr,
176} 177}
177 178
178static int rpcb_register_call(struct sockaddr *addr, size_t addrlen, 179static int rpcb_register_call(struct sockaddr *addr, size_t addrlen,
179 u32 version, struct rpc_message *msg, 180 u32 version, struct rpc_message *msg)
180 int *result)
181{ 181{
182 struct rpc_clnt *rpcb_clnt; 182 struct rpc_clnt *rpcb_clnt;
183 int error = 0; 183 int result, error = 0;
184 184
185 *result = 0; 185 msg->rpc_resp = &result;
186 186
187 rpcb_clnt = rpcb_create_local(addr, addrlen, version); 187 rpcb_clnt = rpcb_create_local(addr, addrlen, version);
188 if (!IS_ERR(rpcb_clnt)) { 188 if (!IS_ERR(rpcb_clnt)) {
@@ -191,12 +191,15 @@ static int rpcb_register_call(struct sockaddr *addr, size_t addrlen,
191 } else 191 } else
192 error = PTR_ERR(rpcb_clnt); 192 error = PTR_ERR(rpcb_clnt);
193 193
194 if (error < 0) 194 if (error < 0) {
195 printk(KERN_WARNING "RPC: failed to contact local rpcbind " 195 printk(KERN_WARNING "RPC: failed to contact local rpcbind "
196 "server (errno %d).\n", -error); 196 "server (errno %d).\n", -error);
197 dprintk("RPC: registration status %d/%d\n", error, *result); 197 return error;
198 }
198 199
199 return error; 200 if (!result)
201 return -EACCES;
202 return 0;
200} 203}
201 204
202/** 205/**
@@ -205,7 +208,11 @@ static int rpcb_register_call(struct sockaddr *addr, size_t addrlen,
205 * @vers: RPC version number to bind 208 * @vers: RPC version number to bind
206 * @prot: transport protocol to register 209 * @prot: transport protocol to register
207 * @port: port value to register 210 * @port: port value to register
208 * @okay: OUT: result code 211 *
212 * Returns zero if the registration request was dispatched successfully
213 * and the rpcbind daemon returned success. Otherwise, returns an errno
214 * value that reflects the nature of the error (request could not be
215 * dispatched, timed out, or rpcbind returned an error).
209 * 216 *
210 * RPC services invoke this function to advertise their contact 217 * RPC services invoke this function to advertise their contact
211 * information via the system's rpcbind daemon. RPC services 218 * information via the system's rpcbind daemon. RPC services
@@ -217,15 +224,6 @@ static int rpcb_register_call(struct sockaddr *addr, size_t addrlen,
217 * all registered transports for [program, version] from the local 224 * all registered transports for [program, version] from the local
218 * rpcbind database. 225 * rpcbind database.
219 * 226 *
220 * Returns zero if the registration request was dispatched
221 * successfully and a reply was received. The rpcbind daemon's
222 * boolean result code is stored in *okay.
223 *
224 * Returns an errno value and sets *result to zero if there was
225 * some problem that prevented the rpcbind request from being
226 * dispatched, or if the rpcbind daemon did not respond within
227 * the timeout.
228 *
229 * This function uses rpcbind protocol version 2 to contact the 227 * This function uses rpcbind protocol version 2 to contact the
230 * local rpcbind daemon. 228 * local rpcbind daemon.
231 * 229 *
@@ -236,7 +234,7 @@ static int rpcb_register_call(struct sockaddr *addr, size_t addrlen,
236 * IN6ADDR_ANY (ie available for all AF_INET and AF_INET6 234 * IN6ADDR_ANY (ie available for all AF_INET and AF_INET6
237 * addresses). 235 * addresses).
238 */ 236 */
239int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay) 237int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
240{ 238{
241 struct rpcbind_args map = { 239 struct rpcbind_args map = {
242 .r_prog = prog, 240 .r_prog = prog,
@@ -246,7 +244,6 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay)
246 }; 244 };
247 struct rpc_message msg = { 245 struct rpc_message msg = {
248 .rpc_argp = &map, 246 .rpc_argp = &map,
249 .rpc_resp = okay,
250 }; 247 };
251 248
252 dprintk("RPC: %sregistering (%u, %u, %d, %u) with local " 249 dprintk("RPC: %sregistering (%u, %u, %d, %u) with local "
@@ -259,7 +256,7 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port, int *okay)
259 256
260 return rpcb_register_call((struct sockaddr *)&rpcb_inaddr_loopback, 257 return rpcb_register_call((struct sockaddr *)&rpcb_inaddr_loopback,
261 sizeof(rpcb_inaddr_loopback), 258 sizeof(rpcb_inaddr_loopback),
262 RPCBVERS_2, &msg, okay); 259 RPCBVERS_2, &msg);
263} 260}
264 261
265/* 262/*
@@ -290,7 +287,7 @@ static int rpcb_register_netid4(struct sockaddr_in *address_to_register,
290 287
291 return rpcb_register_call((struct sockaddr *)&rpcb_inaddr_loopback, 288 return rpcb_register_call((struct sockaddr *)&rpcb_inaddr_loopback,
292 sizeof(rpcb_inaddr_loopback), 289 sizeof(rpcb_inaddr_loopback),
293 RPCBVERS_4, msg, msg->rpc_resp); 290 RPCBVERS_4, msg);
294} 291}
295 292
296/* 293/*
@@ -304,10 +301,13 @@ static int rpcb_register_netid6(struct sockaddr_in6 *address_to_register,
304 char buf[64]; 301 char buf[64];
305 302
306 /* Construct AF_INET6 universal address */ 303 /* Construct AF_INET6 universal address */
307 snprintf(buf, sizeof(buf), 304 if (ipv6_addr_any(&address_to_register->sin6_addr))
308 NIP6_FMT".%u.%u", 305 snprintf(buf, sizeof(buf), "::.%u.%u",
309 NIP6(address_to_register->sin6_addr), 306 port >> 8, port & 0xff);
310 port >> 8, port & 0xff); 307 else
308 snprintf(buf, sizeof(buf), NIP6_FMT".%u.%u",
309 NIP6(address_to_register->sin6_addr),
310 port >> 8, port & 0xff);
311 map->r_addr = buf; 311 map->r_addr = buf;
312 312
313 dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with " 313 dprintk("RPC: %sregistering [%u, %u, %s, '%s'] with "
@@ -321,7 +321,7 @@ static int rpcb_register_netid6(struct sockaddr_in6 *address_to_register,
321 321
322 return rpcb_register_call((struct sockaddr *)&rpcb_in6addr_loopback, 322 return rpcb_register_call((struct sockaddr *)&rpcb_in6addr_loopback,
323 sizeof(rpcb_in6addr_loopback), 323 sizeof(rpcb_in6addr_loopback),
324 RPCBVERS_4, msg, msg->rpc_resp); 324 RPCBVERS_4, msg);
325} 325}
326 326
327/** 327/**
@@ -330,7 +330,11 @@ static int rpcb_register_netid6(struct sockaddr_in6 *address_to_register,
330 * @version: RPC version number of service to (un)register 330 * @version: RPC version number of service to (un)register
331 * @address: address family, IP address, and port to (un)register 331 * @address: address family, IP address, and port to (un)register
332 * @netid: netid of transport protocol to (un)register 332 * @netid: netid of transport protocol to (un)register
333 * @result: result code from rpcbind RPC call 333 *
334 * Returns zero if the registration request was dispatched successfully
335 * and the rpcbind daemon returned success. Otherwise, returns an errno
336 * value that reflects the nature of the error (request could not be
337 * dispatched, timed out, or rpcbind returned an error).
334 * 338 *
335 * RPC services invoke this function to advertise their contact 339 * RPC services invoke this function to advertise their contact
336 * information via the system's rpcbind daemon. RPC services 340 * information via the system's rpcbind daemon. RPC services
@@ -342,15 +346,6 @@ static int rpcb_register_netid6(struct sockaddr_in6 *address_to_register,
342 * to zero. Callers pass a netid of "" to unregister all 346 * to zero. Callers pass a netid of "" to unregister all
343 * transport netids associated with [program, version, address]. 347 * transport netids associated with [program, version, address].
344 * 348 *
345 * Returns zero if the registration request was dispatched
346 * successfully and a reply was received. The rpcbind daemon's
347 * result code is stored in *result.
348 *
349 * Returns an errno value and sets *result to zero if there was
350 * some problem that prevented the rpcbind request from being
351 * dispatched, or if the rpcbind daemon did not respond within
352 * the timeout.
353 *
354 * This function uses rpcbind protocol version 4 to contact the 349 * This function uses rpcbind protocol version 4 to contact the
355 * local rpcbind daemon. The local rpcbind daemon must support 350 * local rpcbind daemon. The local rpcbind daemon must support
356 * version 4 of the rpcbind protocol in order for these functions 351 * version 4 of the rpcbind protocol in order for these functions
@@ -372,8 +367,7 @@ static int rpcb_register_netid6(struct sockaddr_in6 *address_to_register,
372 * advertises the service on all IPv4 and IPv6 addresses. 367 * advertises the service on all IPv4 and IPv6 addresses.
373 */ 368 */
374int rpcb_v4_register(const u32 program, const u32 version, 369int rpcb_v4_register(const u32 program, const u32 version,
375 const struct sockaddr *address, const char *netid, 370 const struct sockaddr *address, const char *netid)
376 int *result)
377{ 371{
378 struct rpcbind_args map = { 372 struct rpcbind_args map = {
379 .r_prog = program, 373 .r_prog = program,
@@ -383,11 +377,8 @@ int rpcb_v4_register(const u32 program, const u32 version,
383 }; 377 };
384 struct rpc_message msg = { 378 struct rpc_message msg = {
385 .rpc_argp = &map, 379 .rpc_argp = &map,
386 .rpc_resp = result,
387 }; 380 };
388 381
389 *result = 0;
390
391 switch (address->sa_family) { 382 switch (address->sa_family) {
392 case AF_INET: 383 case AF_INET:
393 return rpcb_register_netid4((struct sockaddr_in *)address, 384 return rpcb_register_netid4((struct sockaddr_in *)address,
@@ -469,6 +460,28 @@ static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbi
469 return rpc_run_task(&task_setup_data); 460 return rpc_run_task(&task_setup_data);
470} 461}
471 462
463/*
464 * In the case where rpc clients have been cloned, we want to make
465 * sure that we use the program number/version etc of the actual
466 * owner of the xprt. To do so, we walk back up the tree of parents
467 * to find whoever created the transport and/or whoever has the
468 * autobind flag set.
469 */
470static struct rpc_clnt *rpcb_find_transport_owner(struct rpc_clnt *clnt)
471{
472 struct rpc_clnt *parent = clnt->cl_parent;
473
474 while (parent != clnt) {
475 if (parent->cl_xprt != clnt->cl_xprt)
476 break;
477 if (clnt->cl_autobind)
478 break;
479 clnt = parent;
480 parent = parent->cl_parent;
481 }
482 return clnt;
483}
484
472/** 485/**
473 * rpcb_getport_async - obtain the port for a given RPC service on a given host 486 * rpcb_getport_async - obtain the port for a given RPC service on a given host
474 * @task: task that is waiting for portmapper request 487 * @task: task that is waiting for portmapper request
@@ -478,10 +491,10 @@ static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbi
478 */ 491 */
479void rpcb_getport_async(struct rpc_task *task) 492void rpcb_getport_async(struct rpc_task *task)
480{ 493{
481 struct rpc_clnt *clnt = task->tk_client; 494 struct rpc_clnt *clnt;
482 struct rpc_procinfo *proc; 495 struct rpc_procinfo *proc;
483 u32 bind_version; 496 u32 bind_version;
484 struct rpc_xprt *xprt = task->tk_xprt; 497 struct rpc_xprt *xprt;
485 struct rpc_clnt *rpcb_clnt; 498 struct rpc_clnt *rpcb_clnt;
486 static struct rpcbind_args *map; 499 static struct rpcbind_args *map;
487 struct rpc_task *child; 500 struct rpc_task *child;
@@ -490,13 +503,13 @@ void rpcb_getport_async(struct rpc_task *task)
490 size_t salen; 503 size_t salen;
491 int status; 504 int status;
492 505
506 clnt = rpcb_find_transport_owner(task->tk_client);
507 xprt = clnt->cl_xprt;
508
493 dprintk("RPC: %5u %s(%s, %u, %u, %d)\n", 509 dprintk("RPC: %5u %s(%s, %u, %u, %d)\n",
494 task->tk_pid, __func__, 510 task->tk_pid, __func__,
495 clnt->cl_server, clnt->cl_prog, clnt->cl_vers, xprt->prot); 511 clnt->cl_server, clnt->cl_prog, clnt->cl_vers, xprt->prot);
496 512
497 /* Autobind on cloned rpc clients is discouraged */
498 BUG_ON(clnt->cl_parent != clnt);
499
500 /* Put self on the wait queue to ensure we get notified if 513 /* Put self on the wait queue to ensure we get notified if
501 * some other task is already attempting to bind the port */ 514 * some other task is already attempting to bind the port */
502 rpc_sleep_on(&xprt->binding, task, NULL); 515 rpc_sleep_on(&xprt->binding, task, NULL);
@@ -558,7 +571,7 @@ void rpcb_getport_async(struct rpc_task *task)
558 status = -ENOMEM; 571 status = -ENOMEM;
559 dprintk("RPC: %5u %s: no memory available\n", 572 dprintk("RPC: %5u %s: no memory available\n",
560 task->tk_pid, __func__); 573 task->tk_pid, __func__);
561 goto bailout_nofree; 574 goto bailout_release_client;
562 } 575 }
563 map->r_prog = clnt->cl_prog; 576 map->r_prog = clnt->cl_prog;
564 map->r_vers = clnt->cl_vers; 577 map->r_vers = clnt->cl_vers;
@@ -578,11 +591,13 @@ void rpcb_getport_async(struct rpc_task *task)
578 task->tk_pid, __func__); 591 task->tk_pid, __func__);
579 return; 592 return;
580 } 593 }
581 rpc_put_task(child);
582 594
583 task->tk_xprt->stat.bind_count++; 595 xprt->stat.bind_count++;
596 rpc_put_task(child);
584 return; 597 return;
585 598
599bailout_release_client:
600 rpc_release_client(rpcb_clnt);
586bailout_nofree: 601bailout_nofree:
587 rpcb_wake_rpcbind_waiters(xprt, status); 602 rpcb_wake_rpcbind_waiters(xprt, status);
588 task->tk_status = status; 603 task->tk_status = status;
@@ -633,7 +648,7 @@ static void rpcb_getport_done(struct rpc_task *child, void *data)
633static int rpcb_encode_mapping(struct rpc_rqst *req, __be32 *p, 648static int rpcb_encode_mapping(struct rpc_rqst *req, __be32 *p,
634 struct rpcbind_args *rpcb) 649 struct rpcbind_args *rpcb)
635{ 650{
636 dprintk("RPC: rpcb_encode_mapping(%u, %u, %d, %u)\n", 651 dprintk("RPC: encoding rpcb request (%u, %u, %d, %u)\n",
637 rpcb->r_prog, rpcb->r_vers, rpcb->r_prot, rpcb->r_port); 652 rpcb->r_prog, rpcb->r_vers, rpcb->r_prot, rpcb->r_port);
638 *p++ = htonl(rpcb->r_prog); 653 *p++ = htonl(rpcb->r_prog);
639 *p++ = htonl(rpcb->r_vers); 654 *p++ = htonl(rpcb->r_vers);
@@ -648,7 +663,7 @@ static int rpcb_decode_getport(struct rpc_rqst *req, __be32 *p,
648 unsigned short *portp) 663 unsigned short *portp)
649{ 664{
650 *portp = (unsigned short) ntohl(*p++); 665 *portp = (unsigned short) ntohl(*p++);
651 dprintk("RPC: rpcb_decode_getport result %u\n", 666 dprintk("RPC: rpcb getport result: %u\n",
652 *portp); 667 *portp);
653 return 0; 668 return 0;
654} 669}
@@ -657,7 +672,7 @@ static int rpcb_decode_set(struct rpc_rqst *req, __be32 *p,
657 unsigned int *boolp) 672 unsigned int *boolp)
658{ 673{
659 *boolp = (unsigned int) ntohl(*p++); 674 *boolp = (unsigned int) ntohl(*p++);
660 dprintk("RPC: rpcb_decode_set: call %s\n", 675 dprintk("RPC: rpcb set/unset call %s\n",
661 (*boolp ? "succeeded" : "failed")); 676 (*boolp ? "succeeded" : "failed"));
662 return 0; 677 return 0;
663} 678}
@@ -665,7 +680,7 @@ static int rpcb_decode_set(struct rpc_rqst *req, __be32 *p,
665static int rpcb_encode_getaddr(struct rpc_rqst *req, __be32 *p, 680static int rpcb_encode_getaddr(struct rpc_rqst *req, __be32 *p,
666 struct rpcbind_args *rpcb) 681 struct rpcbind_args *rpcb)
667{ 682{
668 dprintk("RPC: rpcb_encode_getaddr(%u, %u, %s)\n", 683 dprintk("RPC: encoding rpcb request (%u, %u, %s)\n",
669 rpcb->r_prog, rpcb->r_vers, rpcb->r_addr); 684 rpcb->r_prog, rpcb->r_vers, rpcb->r_addr);
670 *p++ = htonl(rpcb->r_prog); 685 *p++ = htonl(rpcb->r_prog);
671 *p++ = htonl(rpcb->r_vers); 686 *p++ = htonl(rpcb->r_vers);
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 5a32cb7c4bb..54c98d87684 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -28,6 +28,8 @@
28 28
29#define RPCDBG_FACILITY RPCDBG_SVCDSP 29#define RPCDBG_FACILITY RPCDBG_SVCDSP
30 30
31static void svc_unregister(const struct svc_serv *serv);
32
31#define svc_serv_is_pooled(serv) ((serv)->sv_function) 33#define svc_serv_is_pooled(serv) ((serv)->sv_function)
32 34
33/* 35/*
@@ -357,7 +359,7 @@ svc_pool_for_cpu(struct svc_serv *serv, int cpu)
357 */ 359 */
358static struct svc_serv * 360static struct svc_serv *
359__svc_create(struct svc_program *prog, unsigned int bufsize, int npools, 361__svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
360 void (*shutdown)(struct svc_serv *serv)) 362 sa_family_t family, void (*shutdown)(struct svc_serv *serv))
361{ 363{
362 struct svc_serv *serv; 364 struct svc_serv *serv;
363 unsigned int vers; 365 unsigned int vers;
@@ -366,6 +368,7 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
366 368
367 if (!(serv = kzalloc(sizeof(*serv), GFP_KERNEL))) 369 if (!(serv = kzalloc(sizeof(*serv), GFP_KERNEL)))
368 return NULL; 370 return NULL;
371 serv->sv_family = family;
369 serv->sv_name = prog->pg_name; 372 serv->sv_name = prog->pg_name;
370 serv->sv_program = prog; 373 serv->sv_program = prog;
371 serv->sv_nrthreads = 1; 374 serv->sv_nrthreads = 1;
@@ -416,30 +419,29 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
416 spin_lock_init(&pool->sp_lock); 419 spin_lock_init(&pool->sp_lock);
417 } 420 }
418 421
419
420 /* Remove any stale portmap registrations */ 422 /* Remove any stale portmap registrations */
421 svc_register(serv, 0, 0); 423 svc_unregister(serv);
422 424
423 return serv; 425 return serv;
424} 426}
425 427
426struct svc_serv * 428struct svc_serv *
427svc_create(struct svc_program *prog, unsigned int bufsize, 429svc_create(struct svc_program *prog, unsigned int bufsize,
428 void (*shutdown)(struct svc_serv *serv)) 430 sa_family_t family, void (*shutdown)(struct svc_serv *serv))
429{ 431{
430 return __svc_create(prog, bufsize, /*npools*/1, shutdown); 432 return __svc_create(prog, bufsize, /*npools*/1, family, shutdown);
431} 433}
432EXPORT_SYMBOL(svc_create); 434EXPORT_SYMBOL(svc_create);
433 435
434struct svc_serv * 436struct svc_serv *
435svc_create_pooled(struct svc_program *prog, unsigned int bufsize, 437svc_create_pooled(struct svc_program *prog, unsigned int bufsize,
436 void (*shutdown)(struct svc_serv *serv), 438 sa_family_t family, void (*shutdown)(struct svc_serv *serv),
437 svc_thread_fn func, struct module *mod) 439 svc_thread_fn func, struct module *mod)
438{ 440{
439 struct svc_serv *serv; 441 struct svc_serv *serv;
440 unsigned int npools = svc_pool_map_get(); 442 unsigned int npools = svc_pool_map_get();
441 443
442 serv = __svc_create(prog, bufsize, npools, shutdown); 444 serv = __svc_create(prog, bufsize, npools, family, shutdown);
443 445
444 if (serv != NULL) { 446 if (serv != NULL) {
445 serv->sv_function = func; 447 serv->sv_function = func;
@@ -486,8 +488,7 @@ svc_destroy(struct svc_serv *serv)
486 if (svc_serv_is_pooled(serv)) 488 if (svc_serv_is_pooled(serv))
487 svc_pool_map_put(); 489 svc_pool_map_put();
488 490
489 /* Unregister service with the portmapper */ 491 svc_unregister(serv);
490 svc_register(serv, 0, 0);
491 kfree(serv->sv_pools); 492 kfree(serv->sv_pools);
492 kfree(serv); 493 kfree(serv);
493} 494}
@@ -718,55 +719,245 @@ svc_exit_thread(struct svc_rqst *rqstp)
718} 719}
719EXPORT_SYMBOL(svc_exit_thread); 720EXPORT_SYMBOL(svc_exit_thread);
720 721
722#ifdef CONFIG_SUNRPC_REGISTER_V4
723
721/* 724/*
722 * Register an RPC service with the local portmapper. 725 * Register an "inet" protocol family netid with the local
723 * To unregister a service, call this routine with 726 * rpcbind daemon via an rpcbind v4 SET request.
724 * proto and port == 0. 727 *
728 * No netconfig infrastructure is available in the kernel, so
729 * we map IP_ protocol numbers to netids by hand.
730 *
731 * Returns zero on success; a negative errno value is returned
732 * if any error occurs.
725 */ 733 */
726int 734static int __svc_rpcb_register4(const u32 program, const u32 version,
727svc_register(struct svc_serv *serv, int proto, unsigned short port) 735 const unsigned short protocol,
736 const unsigned short port)
737{
738 struct sockaddr_in sin = {
739 .sin_family = AF_INET,
740 .sin_addr.s_addr = htonl(INADDR_ANY),
741 .sin_port = htons(port),
742 };
743 char *netid;
744
745 switch (protocol) {
746 case IPPROTO_UDP:
747 netid = RPCBIND_NETID_UDP;
748 break;
749 case IPPROTO_TCP:
750 netid = RPCBIND_NETID_TCP;
751 break;
752 default:
753 return -EPROTONOSUPPORT;
754 }
755
756 return rpcb_v4_register(program, version,
757 (struct sockaddr *)&sin, netid);
758}
759
760/*
761 * Register an "inet6" protocol family netid with the local
762 * rpcbind daemon via an rpcbind v4 SET request.
763 *
764 * No netconfig infrastructure is available in the kernel, so
765 * we map IP_ protocol numbers to netids by hand.
766 *
767 * Returns zero on success; a negative errno value is returned
768 * if any error occurs.
769 */
770static int __svc_rpcb_register6(const u32 program, const u32 version,
771 const unsigned short protocol,
772 const unsigned short port)
773{
774 struct sockaddr_in6 sin6 = {
775 .sin6_family = AF_INET6,
776 .sin6_addr = IN6ADDR_ANY_INIT,
777 .sin6_port = htons(port),
778 };
779 char *netid;
780
781 switch (protocol) {
782 case IPPROTO_UDP:
783 netid = RPCBIND_NETID_UDP6;
784 break;
785 case IPPROTO_TCP:
786 netid = RPCBIND_NETID_TCP6;
787 break;
788 default:
789 return -EPROTONOSUPPORT;
790 }
791
792 return rpcb_v4_register(program, version,
793 (struct sockaddr *)&sin6, netid);
794}
795
796/*
797 * Register a kernel RPC service via rpcbind version 4.
798 *
799 * Returns zero on success; a negative errno value is returned
800 * if any error occurs.
801 */
802static int __svc_register(const u32 program, const u32 version,
803 const sa_family_t family,
804 const unsigned short protocol,
805 const unsigned short port)
806{
807 int error;
808
809 switch (family) {
810 case AF_INET:
811 return __svc_rpcb_register4(program, version,
812 protocol, port);
813 case AF_INET6:
814 error = __svc_rpcb_register6(program, version,
815 protocol, port);
816 if (error < 0)
817 return error;
818
819 /*
820 * Work around bug in some versions of Linux rpcbind
821 * which don't allow registration of both inet and
822 * inet6 netids.
823 *
824 * Error return ignored for now.
825 */
826 __svc_rpcb_register4(program, version,
827 protocol, port);
828 return 0;
829 }
830
831 return -EAFNOSUPPORT;
832}
833
834#else /* CONFIG_SUNRPC_REGISTER_V4 */
835
836/*
837 * Register a kernel RPC service via rpcbind version 2.
838 *
839 * Returns zero on success; a negative errno value is returned
840 * if any error occurs.
841 */
842static int __svc_register(const u32 program, const u32 version,
843 sa_family_t family,
844 const unsigned short protocol,
845 const unsigned short port)
846{
847 if (family != AF_INET)
848 return -EAFNOSUPPORT;
849
850 return rpcb_register(program, version, protocol, port);
851}
852
853#endif /* CONFIG_SUNRPC_REGISTER_V4 */
854
855/**
856 * svc_register - register an RPC service with the local portmapper
857 * @serv: svc_serv struct for the service to register
858 * @proto: transport protocol number to advertise
859 * @port: port to advertise
860 *
861 * Service is registered for any address in serv's address family
862 */
863int svc_register(const struct svc_serv *serv, const unsigned short proto,
864 const unsigned short port)
728{ 865{
729 struct svc_program *progp; 866 struct svc_program *progp;
730 unsigned long flags;
731 unsigned int i; 867 unsigned int i;
732 int error = 0, dummy; 868 int error = 0;
733 869
734 if (!port) 870 BUG_ON(proto == 0 && port == 0);
735 clear_thread_flag(TIF_SIGPENDING);
736 871
737 for (progp = serv->sv_program; progp; progp = progp->pg_next) { 872 for (progp = serv->sv_program; progp; progp = progp->pg_next) {
738 for (i = 0; i < progp->pg_nvers; i++) { 873 for (i = 0; i < progp->pg_nvers; i++) {
739 if (progp->pg_vers[i] == NULL) 874 if (progp->pg_vers[i] == NULL)
740 continue; 875 continue;
741 876
742 dprintk("svc: svc_register(%s, %s, %d, %d)%s\n", 877 dprintk("svc: svc_register(%sv%d, %s, %u, %u)%s\n",
743 progp->pg_name, 878 progp->pg_name,
879 i,
744 proto == IPPROTO_UDP? "udp" : "tcp", 880 proto == IPPROTO_UDP? "udp" : "tcp",
745 port, 881 port,
746 i, 882 serv->sv_family,
747 progp->pg_vers[i]->vs_hidden? 883 progp->pg_vers[i]->vs_hidden?
748 " (but not telling portmap)" : ""); 884 " (but not telling portmap)" : "");
749 885
750 if (progp->pg_vers[i]->vs_hidden) 886 if (progp->pg_vers[i]->vs_hidden)
751 continue; 887 continue;
752 888
753 error = rpcb_register(progp->pg_prog, i, proto, port, &dummy); 889 error = __svc_register(progp->pg_prog, i,
890 serv->sv_family, proto, port);
754 if (error < 0) 891 if (error < 0)
755 break; 892 break;
756 if (port && !dummy) {
757 error = -EACCES;
758 break;
759 }
760 } 893 }
761 } 894 }
762 895
763 if (!port) { 896 return error;
764 spin_lock_irqsave(&current->sighand->siglock, flags); 897}
765 recalc_sigpending(); 898
766 spin_unlock_irqrestore(&current->sighand->siglock, flags); 899#ifdef CONFIG_SUNRPC_REGISTER_V4
900
901static void __svc_unregister(const u32 program, const u32 version,
902 const char *progname)
903{
904 struct sockaddr_in6 sin6 = {
905 .sin6_family = AF_INET6,
906 .sin6_addr = IN6ADDR_ANY_INIT,
907 .sin6_port = 0,
908 };
909 int error;
910
911 error = rpcb_v4_register(program, version,
912 (struct sockaddr *)&sin6, "");
913 dprintk("svc: %s(%sv%u), error %d\n",
914 __func__, progname, version, error);
915}
916
917#else /* CONFIG_SUNRPC_REGISTER_V4 */
918
919static void __svc_unregister(const u32 program, const u32 version,
920 const char *progname)
921{
922 int error;
923
924 error = rpcb_register(program, version, 0, 0);
925 dprintk("svc: %s(%sv%u), error %d\n",
926 __func__, progname, version, error);
927}
928
929#endif /* CONFIG_SUNRPC_REGISTER_V4 */
930
931/*
932 * All netids, bind addresses and ports registered for [program, version]
933 * are removed from the local rpcbind database (if the service is not
934 * hidden) to make way for a new instance of the service.
935 *
936 * The result of unregistration is reported via dprintk for those who want
937 * verification of the result, but is otherwise not important.
938 */
939static void svc_unregister(const struct svc_serv *serv)
940{
941 struct svc_program *progp;
942 unsigned long flags;
943 unsigned int i;
944
945 clear_thread_flag(TIF_SIGPENDING);
946
947 for (progp = serv->sv_program; progp; progp = progp->pg_next) {
948 for (i = 0; i < progp->pg_nvers; i++) {
949 if (progp->pg_vers[i] == NULL)
950 continue;
951 if (progp->pg_vers[i]->vs_hidden)
952 continue;
953
954 __svc_unregister(progp->pg_prog, i, progp->pg_name);
955 }
767 } 956 }
768 957
769 return error; 958 spin_lock_irqsave(&current->sighand->siglock, flags);
959 recalc_sigpending();
960 spin_unlock_irqrestore(&current->sighand->siglock, flags);
770} 961}
771 962
772/* 963/*
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index e46c825f495..bf5b5cdafeb 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -159,15 +159,44 @@ void svc_xprt_init(struct svc_xprt_class *xcl, struct svc_xprt *xprt,
159} 159}
160EXPORT_SYMBOL_GPL(svc_xprt_init); 160EXPORT_SYMBOL_GPL(svc_xprt_init);
161 161
162int svc_create_xprt(struct svc_serv *serv, char *xprt_name, unsigned short port, 162static struct svc_xprt *__svc_xpo_create(struct svc_xprt_class *xcl,
163 int flags) 163 struct svc_serv *serv,
164 unsigned short port, int flags)
164{ 165{
165 struct svc_xprt_class *xcl;
166 struct sockaddr_in sin = { 166 struct sockaddr_in sin = {
167 .sin_family = AF_INET, 167 .sin_family = AF_INET,
168 .sin_addr.s_addr = htonl(INADDR_ANY), 168 .sin_addr.s_addr = htonl(INADDR_ANY),
169 .sin_port = htons(port), 169 .sin_port = htons(port),
170 }; 170 };
171 struct sockaddr_in6 sin6 = {
172 .sin6_family = AF_INET6,
173 .sin6_addr = IN6ADDR_ANY_INIT,
174 .sin6_port = htons(port),
175 };
176 struct sockaddr *sap;
177 size_t len;
178
179 switch (serv->sv_family) {
180 case AF_INET:
181 sap = (struct sockaddr *)&sin;
182 len = sizeof(sin);
183 break;
184 case AF_INET6:
185 sap = (struct sockaddr *)&sin6;
186 len = sizeof(sin6);
187 break;
188 default:
189 return ERR_PTR(-EAFNOSUPPORT);
190 }
191
192 return xcl->xcl_ops->xpo_create(serv, sap, len, flags);
193}
194
195int svc_create_xprt(struct svc_serv *serv, char *xprt_name, unsigned short port,
196 int flags)
197{
198 struct svc_xprt_class *xcl;
199
171 dprintk("svc: creating transport %s[%d]\n", xprt_name, port); 200 dprintk("svc: creating transport %s[%d]\n", xprt_name, port);
172 spin_lock(&svc_xprt_class_lock); 201 spin_lock(&svc_xprt_class_lock);
173 list_for_each_entry(xcl, &svc_xprt_class_list, xcl_list) { 202 list_for_each_entry(xcl, &svc_xprt_class_list, xcl_list) {
@@ -180,9 +209,7 @@ int svc_create_xprt(struct svc_serv *serv, char *xprt_name, unsigned short port,
180 goto err; 209 goto err;
181 210
182 spin_unlock(&svc_xprt_class_lock); 211 spin_unlock(&svc_xprt_class_lock);
183 newxprt = xcl->xcl_ops-> 212 newxprt = __svc_xpo_create(xcl, serv, port, flags);
184 xpo_create(serv, (struct sockaddr *)&sin, sizeof(sin),
185 flags);
186 if (IS_ERR(newxprt)) { 213 if (IS_ERR(newxprt)) {
187 module_put(xcl->xcl_owner); 214 module_put(xcl->xcl_owner);
188 return PTR_ERR(newxprt); 215 return PTR_ERR(newxprt);
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 3e65719f1ef..95293f549e9 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -1114,6 +1114,7 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
1114 struct svc_sock *svsk; 1114 struct svc_sock *svsk;
1115 struct sock *inet; 1115 struct sock *inet;
1116 int pmap_register = !(flags & SVC_SOCK_ANONYMOUS); 1116 int pmap_register = !(flags & SVC_SOCK_ANONYMOUS);
1117 int val;
1117 1118
1118 dprintk("svc: svc_setup_socket %p\n", sock); 1119 dprintk("svc: svc_setup_socket %p\n", sock);
1119 if (!(svsk = kzalloc(sizeof(*svsk), GFP_KERNEL))) { 1120 if (!(svsk = kzalloc(sizeof(*svsk), GFP_KERNEL))) {
@@ -1146,6 +1147,18 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
1146 else 1147 else
1147 svc_tcp_init(svsk, serv); 1148 svc_tcp_init(svsk, serv);
1148 1149
1150 /*
1151 * We start one listener per sv_serv. We want AF_INET
1152 * requests to be automatically shunted to our AF_INET6
1153 * listener using a mapped IPv4 address. Make sure
1154 * no-one starts an equivalent IPv4 listener, which
1155 * would steal our incoming connections.
1156 */
1157 val = 0;
1158 if (serv->sv_family == AF_INET6)
1159 kernel_setsockopt(sock, SOL_IPV6, IPV6_V6ONLY,
1160 (char *)&val, sizeof(val));
1161
1149 dprintk("svc: svc_setup_socket created %p (inet %p)\n", 1162 dprintk("svc: svc_setup_socket created %p (inet %p)\n",
1150 svsk, svsk->sk_sk); 1163 svsk, svsk->sk_sk);
1151 1164
@@ -1154,8 +1167,7 @@ static struct svc_sock *svc_setup_socket(struct svc_serv *serv,
1154 1167
1155int svc_addsock(struct svc_serv *serv, 1168int svc_addsock(struct svc_serv *serv,
1156 int fd, 1169 int fd,
1157 char *name_return, 1170 char *name_return)
1158 int *proto)
1159{ 1171{
1160 int err = 0; 1172 int err = 0;
1161 struct socket *so = sockfd_lookup(fd, &err); 1173 struct socket *so = sockfd_lookup(fd, &err);
@@ -1190,7 +1202,6 @@ int svc_addsock(struct svc_serv *serv,
1190 sockfd_put(so); 1202 sockfd_put(so);
1191 return err; 1203 return err;
1192 } 1204 }
1193 if (proto) *proto = so->sk->sk_protocol;
1194 return one_sock_name(name_return, svsk); 1205 return one_sock_name(name_return, svsk);
1195} 1206}
1196EXPORT_SYMBOL_GPL(svc_addsock); 1207EXPORT_SYMBOL_GPL(svc_addsock);
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 99a52aabe33..29e401bb612 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -108,13 +108,10 @@ int xprt_register_transport(struct xprt_class *transport)
108 goto out; 108 goto out;
109 } 109 }
110 110
111 result = -EINVAL; 111 list_add_tail(&transport->list, &xprt_list);
112 if (try_module_get(THIS_MODULE)) { 112 printk(KERN_INFO "RPC: Registered %s transport module.\n",
113 list_add_tail(&transport->list, &xprt_list); 113 transport->name);
114 printk(KERN_INFO "RPC: Registered %s transport module.\n", 114 result = 0;
115 transport->name);
116 result = 0;
117 }
118 115
119out: 116out:
120 spin_unlock(&xprt_list_lock); 117 spin_unlock(&xprt_list_lock);
@@ -143,7 +140,6 @@ int xprt_unregister_transport(struct xprt_class *transport)
143 "RPC: Unregistered %s transport module.\n", 140 "RPC: Unregistered %s transport module.\n",
144 transport->name); 141 transport->name);
145 list_del_init(&transport->list); 142 list_del_init(&transport->list);
146 module_put(THIS_MODULE);
147 goto out; 143 goto out;
148 } 144 }
149 } 145 }
diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c
index e55427f73df..14106d26bb9 100644
--- a/net/sunrpc/xprtrdma/rpc_rdma.c
+++ b/net/sunrpc/xprtrdma/rpc_rdma.c
@@ -118,6 +118,10 @@ rpcrdma_convert_iovs(struct xdr_buf *xdrbuf, unsigned int pos,
118 } 118 }
119 119
120 if (xdrbuf->tail[0].iov_len) { 120 if (xdrbuf->tail[0].iov_len) {
121 /* the rpcrdma protocol allows us to omit any trailing
122 * xdr pad bytes, saving the server an RDMA operation. */
123 if (xdrbuf->tail[0].iov_len < 4 && xprt_rdma_pad_optimize)
124 return n;
121 if (n == nsegs) 125 if (n == nsegs)
122 return 0; 126 return 0;
123 seg[n].mr_page = NULL; 127 seg[n].mr_page = NULL;
@@ -508,8 +512,8 @@ rpcrdma_marshal_req(struct rpc_rqst *rqst)
508 if (hdrlen == 0) 512 if (hdrlen == 0)
509 return -1; 513 return -1;
510 514
511 dprintk("RPC: %s: %s: hdrlen %zd rpclen %zd padlen %zd\n" 515 dprintk("RPC: %s: %s: hdrlen %zd rpclen %zd padlen %zd"
512 " headerp 0x%p base 0x%p lkey 0x%x\n", 516 " headerp 0x%p base 0x%p lkey 0x%x\n",
513 __func__, transfertypes[wtype], hdrlen, rpclen, padlen, 517 __func__, transfertypes[wtype], hdrlen, rpclen, padlen,
514 headerp, base, req->rl_iov.lkey); 518 headerp, base, req->rl_iov.lkey);
515 519
@@ -594,7 +598,7 @@ rpcrdma_count_chunks(struct rpcrdma_rep *rep, unsigned int max, int wrchunk, __b
594 * Scatter inline received data back into provided iov's. 598 * Scatter inline received data back into provided iov's.
595 */ 599 */
596static void 600static void
597rpcrdma_inline_fixup(struct rpc_rqst *rqst, char *srcp, int copy_len) 601rpcrdma_inline_fixup(struct rpc_rqst *rqst, char *srcp, int copy_len, int pad)
598{ 602{
599 int i, npages, curlen, olen; 603 int i, npages, curlen, olen;
600 char *destp; 604 char *destp;
@@ -660,6 +664,13 @@ rpcrdma_inline_fixup(struct rpc_rqst *rqst, char *srcp, int copy_len)
660 } else 664 } else
661 rqst->rq_rcv_buf.tail[0].iov_len = 0; 665 rqst->rq_rcv_buf.tail[0].iov_len = 0;
662 666
667 if (pad) {
668 /* implicit padding on terminal chunk */
669 unsigned char *p = rqst->rq_rcv_buf.tail[0].iov_base;
670 while (pad--)
671 p[rqst->rq_rcv_buf.tail[0].iov_len++] = 0;
672 }
673
663 if (copy_len) 674 if (copy_len)
664 dprintk("RPC: %s: %d bytes in" 675 dprintk("RPC: %s: %d bytes in"
665 " %d extra segments (%d lost)\n", 676 " %d extra segments (%d lost)\n",
@@ -681,12 +692,14 @@ rpcrdma_conn_func(struct rpcrdma_ep *ep)
681 struct rpc_xprt *xprt = ep->rep_xprt; 692 struct rpc_xprt *xprt = ep->rep_xprt;
682 693
683 spin_lock_bh(&xprt->transport_lock); 694 spin_lock_bh(&xprt->transport_lock);
695 if (++xprt->connect_cookie == 0) /* maintain a reserved value */
696 ++xprt->connect_cookie;
684 if (ep->rep_connected > 0) { 697 if (ep->rep_connected > 0) {
685 if (!xprt_test_and_set_connected(xprt)) 698 if (!xprt_test_and_set_connected(xprt))
686 xprt_wake_pending_tasks(xprt, 0); 699 xprt_wake_pending_tasks(xprt, 0);
687 } else { 700 } else {
688 if (xprt_test_and_clear_connected(xprt)) 701 if (xprt_test_and_clear_connected(xprt))
689 xprt_wake_pending_tasks(xprt, ep->rep_connected); 702 xprt_wake_pending_tasks(xprt, -ENOTCONN);
690 } 703 }
691 spin_unlock_bh(&xprt->transport_lock); 704 spin_unlock_bh(&xprt->transport_lock);
692} 705}
@@ -769,7 +782,7 @@ repost:
769 /* check for expected message types */ 782 /* check for expected message types */
770 /* The order of some of these tests is important. */ 783 /* The order of some of these tests is important. */
771 switch (headerp->rm_type) { 784 switch (headerp->rm_type) {
772 case __constant_htonl(RDMA_MSG): 785 case htonl(RDMA_MSG):
773 /* never expect read chunks */ 786 /* never expect read chunks */
774 /* never expect reply chunks (two ways to check) */ 787 /* never expect reply chunks (two ways to check) */
775 /* never expect write chunks without having offered RDMA */ 788 /* never expect write chunks without having offered RDMA */
@@ -792,17 +805,23 @@ repost:
792 ((unsigned char *)iptr - (unsigned char *)headerp); 805 ((unsigned char *)iptr - (unsigned char *)headerp);
793 status = rep->rr_len + rdmalen; 806 status = rep->rr_len + rdmalen;
794 r_xprt->rx_stats.total_rdma_reply += rdmalen; 807 r_xprt->rx_stats.total_rdma_reply += rdmalen;
808 /* special case - last chunk may omit padding */
809 if (rdmalen &= 3) {
810 rdmalen = 4 - rdmalen;
811 status += rdmalen;
812 }
795 } else { 813 } else {
796 /* else ordinary inline */ 814 /* else ordinary inline */
815 rdmalen = 0;
797 iptr = (__be32 *)((unsigned char *)headerp + 28); 816 iptr = (__be32 *)((unsigned char *)headerp + 28);
798 rep->rr_len -= 28; /*sizeof *headerp;*/ 817 rep->rr_len -= 28; /*sizeof *headerp;*/
799 status = rep->rr_len; 818 status = rep->rr_len;
800 } 819 }
801 /* Fix up the rpc results for upper layer */ 820 /* Fix up the rpc results for upper layer */
802 rpcrdma_inline_fixup(rqst, (char *)iptr, rep->rr_len); 821 rpcrdma_inline_fixup(rqst, (char *)iptr, rep->rr_len, rdmalen);
803 break; 822 break;
804 823
805 case __constant_htonl(RDMA_NOMSG): 824 case htonl(RDMA_NOMSG):
806 /* never expect read or write chunks, always reply chunks */ 825 /* never expect read or write chunks, always reply chunks */
807 if (headerp->rm_body.rm_chunks[0] != xdr_zero || 826 if (headerp->rm_body.rm_chunks[0] != xdr_zero ||
808 headerp->rm_body.rm_chunks[1] != xdr_zero || 827 headerp->rm_body.rm_chunks[1] != xdr_zero ||
diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
index 74de31a0661..a4756576d68 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
@@ -116,7 +116,7 @@ static void rdma_build_arg_xdr(struct svc_rqst *rqstp,
116 * 116 *
117 * Assumptions: 117 * Assumptions:
118 * - chunk[0]->position points to pages[0] at an offset of 0 118 * - chunk[0]->position points to pages[0] at an offset of 0
119 * - pages[] is not physically or virtually contigous and consists of 119 * - pages[] is not physically or virtually contiguous and consists of
120 * PAGE_SIZE elements. 120 * PAGE_SIZE elements.
121 * 121 *
122 * Output: 122 * Output:
@@ -125,7 +125,7 @@ static void rdma_build_arg_xdr(struct svc_rqst *rqstp,
125 * chunk in the read list 125 * chunk in the read list
126 * 126 *
127 */ 127 */
128static int rdma_rcl_to_sge(struct svcxprt_rdma *xprt, 128static int map_read_chunks(struct svcxprt_rdma *xprt,
129 struct svc_rqst *rqstp, 129 struct svc_rqst *rqstp,
130 struct svc_rdma_op_ctxt *head, 130 struct svc_rdma_op_ctxt *head,
131 struct rpcrdma_msg *rmsgp, 131 struct rpcrdma_msg *rmsgp,
@@ -211,26 +211,128 @@ static int rdma_rcl_to_sge(struct svcxprt_rdma *xprt,
211 return sge_no; 211 return sge_no;
212} 212}
213 213
214static void rdma_set_ctxt_sge(struct svcxprt_rdma *xprt, 214/* Map a read-chunk-list to an XDR and fast register the page-list.
215 struct svc_rdma_op_ctxt *ctxt, 215 *
216 struct kvec *vec, 216 * Assumptions:
217 u64 *sgl_offset, 217 * - chunk[0] position points to pages[0] at an offset of 0
218 int count) 218 * - pages[] will be made physically contiguous by creating a one-off memory
219 * region using the fastreg verb.
220 * - byte_count is # of bytes in read-chunk-list
221 * - ch_count is # of chunks in read-chunk-list
222 *
223 * Output:
224 * - sge array pointing into pages[] array.
225 * - chunk_sge array specifying sge index and count for each
226 * chunk in the read list
227 */
228static int fast_reg_read_chunks(struct svcxprt_rdma *xprt,
229 struct svc_rqst *rqstp,
230 struct svc_rdma_op_ctxt *head,
231 struct rpcrdma_msg *rmsgp,
232 struct svc_rdma_req_map *rpl_map,
233 struct svc_rdma_req_map *chl_map,
234 int ch_count,
235 int byte_count)
236{
237 int page_no;
238 int ch_no;
239 u32 offset;
240 struct rpcrdma_read_chunk *ch;
241 struct svc_rdma_fastreg_mr *frmr;
242 int ret = 0;
243
244 frmr = svc_rdma_get_frmr(xprt);
245 if (IS_ERR(frmr))
246 return -ENOMEM;
247
248 head->frmr = frmr;
249 head->arg.head[0] = rqstp->rq_arg.head[0];
250 head->arg.tail[0] = rqstp->rq_arg.tail[0];
251 head->arg.pages = &head->pages[head->count];
252 head->hdr_count = head->count; /* save count of hdr pages */
253 head->arg.page_base = 0;
254 head->arg.page_len = byte_count;
255 head->arg.len = rqstp->rq_arg.len + byte_count;
256 head->arg.buflen = rqstp->rq_arg.buflen + byte_count;
257
258 /* Fast register the page list */
259 frmr->kva = page_address(rqstp->rq_arg.pages[0]);
260 frmr->direction = DMA_FROM_DEVICE;
261 frmr->access_flags = (IB_ACCESS_LOCAL_WRITE|IB_ACCESS_REMOTE_WRITE);
262 frmr->map_len = byte_count;
263 frmr->page_list_len = PAGE_ALIGN(byte_count) >> PAGE_SHIFT;
264 for (page_no = 0; page_no < frmr->page_list_len; page_no++) {
265 frmr->page_list->page_list[page_no] =
266 ib_dma_map_single(xprt->sc_cm_id->device,
267 page_address(rqstp->rq_arg.pages[page_no]),
268 PAGE_SIZE, DMA_TO_DEVICE);
269 if (ib_dma_mapping_error(xprt->sc_cm_id->device,
270 frmr->page_list->page_list[page_no]))
271 goto fatal_err;
272 atomic_inc(&xprt->sc_dma_used);
273 head->arg.pages[page_no] = rqstp->rq_arg.pages[page_no];
274 }
275 head->count += page_no;
276
277 /* rq_respages points one past arg pages */
278 rqstp->rq_respages = &rqstp->rq_arg.pages[page_no];
279
280 /* Create the reply and chunk maps */
281 offset = 0;
282 ch = (struct rpcrdma_read_chunk *)&rmsgp->rm_body.rm_chunks[0];
283 for (ch_no = 0; ch_no < ch_count; ch_no++) {
284 rpl_map->sge[ch_no].iov_base = frmr->kva + offset;
285 rpl_map->sge[ch_no].iov_len = ch->rc_target.rs_length;
286 chl_map->ch[ch_no].count = 1;
287 chl_map->ch[ch_no].start = ch_no;
288 offset += ch->rc_target.rs_length;
289 ch++;
290 }
291
292 ret = svc_rdma_fastreg(xprt, frmr);
293 if (ret)
294 goto fatal_err;
295
296 return ch_no;
297
298 fatal_err:
299 printk("svcrdma: error fast registering xdr for xprt %p", xprt);
300 svc_rdma_put_frmr(xprt, frmr);
301 return -EIO;
302}
303
304static int rdma_set_ctxt_sge(struct svcxprt_rdma *xprt,
305 struct svc_rdma_op_ctxt *ctxt,
306 struct svc_rdma_fastreg_mr *frmr,
307 struct kvec *vec,
308 u64 *sgl_offset,
309 int count)
219{ 310{
220 int i; 311 int i;
221 312
222 ctxt->count = count; 313 ctxt->count = count;
223 ctxt->direction = DMA_FROM_DEVICE; 314 ctxt->direction = DMA_FROM_DEVICE;
224 for (i = 0; i < count; i++) { 315 for (i = 0; i < count; i++) {
225 atomic_inc(&xprt->sc_dma_used); 316 ctxt->sge[i].length = 0; /* in case map fails */
226 ctxt->sge[i].addr = 317 if (!frmr) {
227 ib_dma_map_single(xprt->sc_cm_id->device, 318 ctxt->sge[i].addr =
228 vec[i].iov_base, vec[i].iov_len, 319 ib_dma_map_single(xprt->sc_cm_id->device,
229 DMA_FROM_DEVICE); 320 vec[i].iov_base,
321 vec[i].iov_len,
322 DMA_FROM_DEVICE);
323 if (ib_dma_mapping_error(xprt->sc_cm_id->device,
324 ctxt->sge[i].addr))
325 return -EINVAL;
326 ctxt->sge[i].lkey = xprt->sc_dma_lkey;
327 atomic_inc(&xprt->sc_dma_used);
328 } else {
329 ctxt->sge[i].addr = (unsigned long)vec[i].iov_base;
330 ctxt->sge[i].lkey = frmr->mr->lkey;
331 }
230 ctxt->sge[i].length = vec[i].iov_len; 332 ctxt->sge[i].length = vec[i].iov_len;
231 ctxt->sge[i].lkey = xprt->sc_phys_mr->lkey;
232 *sgl_offset = *sgl_offset + vec[i].iov_len; 333 *sgl_offset = *sgl_offset + vec[i].iov_len;
233 } 334 }
335 return 0;
234} 336}
235 337
236static int rdma_read_max_sge(struct svcxprt_rdma *xprt, int sge_count) 338static int rdma_read_max_sge(struct svcxprt_rdma *xprt, int sge_count)
@@ -278,6 +380,7 @@ static int rdma_read_xdr(struct svcxprt_rdma *xprt,
278 struct svc_rdma_op_ctxt *hdr_ctxt) 380 struct svc_rdma_op_ctxt *hdr_ctxt)
279{ 381{
280 struct ib_send_wr read_wr; 382 struct ib_send_wr read_wr;
383 struct ib_send_wr inv_wr;
281 int err = 0; 384 int err = 0;
282 int ch_no; 385 int ch_no;
283 int ch_count; 386 int ch_count;
@@ -301,9 +404,20 @@ static int rdma_read_xdr(struct svcxprt_rdma *xprt,
301 svc_rdma_rcl_chunk_counts(ch, &ch_count, &byte_count); 404 svc_rdma_rcl_chunk_counts(ch, &ch_count, &byte_count);
302 if (ch_count > RPCSVC_MAXPAGES) 405 if (ch_count > RPCSVC_MAXPAGES)
303 return -EINVAL; 406 return -EINVAL;
304 sge_count = rdma_rcl_to_sge(xprt, rqstp, hdr_ctxt, rmsgp, 407
305 rpl_map, chl_map, 408 if (!xprt->sc_frmr_pg_list_len)
306 ch_count, byte_count); 409 sge_count = map_read_chunks(xprt, rqstp, hdr_ctxt, rmsgp,
410 rpl_map, chl_map, ch_count,
411 byte_count);
412 else
413 sge_count = fast_reg_read_chunks(xprt, rqstp, hdr_ctxt, rmsgp,
414 rpl_map, chl_map, ch_count,
415 byte_count);
416 if (sge_count < 0) {
417 err = -EIO;
418 goto out;
419 }
420
307 sgl_offset = 0; 421 sgl_offset = 0;
308 ch_no = 0; 422 ch_no = 0;
309 423
@@ -312,13 +426,16 @@ static int rdma_read_xdr(struct svcxprt_rdma *xprt,
312next_sge: 426next_sge:
313 ctxt = svc_rdma_get_context(xprt); 427 ctxt = svc_rdma_get_context(xprt);
314 ctxt->direction = DMA_FROM_DEVICE; 428 ctxt->direction = DMA_FROM_DEVICE;
429 ctxt->frmr = hdr_ctxt->frmr;
430 ctxt->read_hdr = NULL;
315 clear_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags); 431 clear_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags);
432 clear_bit(RDMACTXT_F_FAST_UNREG, &ctxt->flags);
316 433
317 /* Prepare READ WR */ 434 /* Prepare READ WR */
318 memset(&read_wr, 0, sizeof read_wr); 435 memset(&read_wr, 0, sizeof read_wr);
319 ctxt->wr_op = IB_WR_RDMA_READ;
320 read_wr.wr_id = (unsigned long)ctxt; 436 read_wr.wr_id = (unsigned long)ctxt;
321 read_wr.opcode = IB_WR_RDMA_READ; 437 read_wr.opcode = IB_WR_RDMA_READ;
438 ctxt->wr_op = read_wr.opcode;
322 read_wr.send_flags = IB_SEND_SIGNALED; 439 read_wr.send_flags = IB_SEND_SIGNALED;
323 read_wr.wr.rdma.rkey = ch->rc_target.rs_handle; 440 read_wr.wr.rdma.rkey = ch->rc_target.rs_handle;
324 read_wr.wr.rdma.remote_addr = 441 read_wr.wr.rdma.remote_addr =
@@ -327,10 +444,15 @@ next_sge:
327 read_wr.sg_list = ctxt->sge; 444 read_wr.sg_list = ctxt->sge;
328 read_wr.num_sge = 445 read_wr.num_sge =
329 rdma_read_max_sge(xprt, chl_map->ch[ch_no].count); 446 rdma_read_max_sge(xprt, chl_map->ch[ch_no].count);
330 rdma_set_ctxt_sge(xprt, ctxt, 447 err = rdma_set_ctxt_sge(xprt, ctxt, hdr_ctxt->frmr,
331 &rpl_map->sge[chl_map->ch[ch_no].start], 448 &rpl_map->sge[chl_map->ch[ch_no].start],
332 &sgl_offset, 449 &sgl_offset,
333 read_wr.num_sge); 450 read_wr.num_sge);
451 if (err) {
452 svc_rdma_unmap_dma(ctxt);
453 svc_rdma_put_context(ctxt, 0);
454 goto out;
455 }
334 if (((ch+1)->rc_discrim == 0) && 456 if (((ch+1)->rc_discrim == 0) &&
335 (read_wr.num_sge == chl_map->ch[ch_no].count)) { 457 (read_wr.num_sge == chl_map->ch[ch_no].count)) {
336 /* 458 /*
@@ -339,6 +461,29 @@ next_sge:
339 * the client and the RPC needs to be enqueued. 461 * the client and the RPC needs to be enqueued.
340 */ 462 */
341 set_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags); 463 set_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags);
464 if (hdr_ctxt->frmr) {
465 set_bit(RDMACTXT_F_FAST_UNREG, &ctxt->flags);
466 /*
467 * Invalidate the local MR used to map the data
468 * sink.
469 */
470 if (xprt->sc_dev_caps &
471 SVCRDMA_DEVCAP_READ_W_INV) {
472 read_wr.opcode =
473 IB_WR_RDMA_READ_WITH_INV;
474 ctxt->wr_op = read_wr.opcode;
475 read_wr.ex.invalidate_rkey =
476 ctxt->frmr->mr->lkey;
477 } else {
478 /* Prepare INVALIDATE WR */
479 memset(&inv_wr, 0, sizeof inv_wr);
480 inv_wr.opcode = IB_WR_LOCAL_INV;
481 inv_wr.send_flags = IB_SEND_SIGNALED;
482 inv_wr.ex.invalidate_rkey =
483 hdr_ctxt->frmr->mr->lkey;
484 read_wr.next = &inv_wr;
485 }
486 }
342 ctxt->read_hdr = hdr_ctxt; 487 ctxt->read_hdr = hdr_ctxt;
343 } 488 }
344 /* Post the read */ 489 /* Post the read */
diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
index 84d328329d9..9a7a8e7ae03 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
@@ -69,9 +69,127 @@
69 * array is only concerned with the reply we are assured that we have 69 * array is only concerned with the reply we are assured that we have
70 * on extra page for the RPCRMDA header. 70 * on extra page for the RPCRMDA header.
71 */ 71 */
72static void xdr_to_sge(struct svcxprt_rdma *xprt, 72int fast_reg_xdr(struct svcxprt_rdma *xprt,
73 struct xdr_buf *xdr, 73 struct xdr_buf *xdr,
74 struct svc_rdma_req_map *vec) 74 struct svc_rdma_req_map *vec)
75{
76 int sge_no;
77 u32 sge_bytes;
78 u32 page_bytes;
79 u32 page_off;
80 int page_no = 0;
81 u8 *frva;
82 struct svc_rdma_fastreg_mr *frmr;
83
84 frmr = svc_rdma_get_frmr(xprt);
85 if (IS_ERR(frmr))
86 return -ENOMEM;
87 vec->frmr = frmr;
88
89 /* Skip the RPCRDMA header */
90 sge_no = 1;
91
92 /* Map the head. */
93 frva = (void *)((unsigned long)(xdr->head[0].iov_base) & PAGE_MASK);
94 vec->sge[sge_no].iov_base = xdr->head[0].iov_base;
95 vec->sge[sge_no].iov_len = xdr->head[0].iov_len;
96 vec->count = 2;
97 sge_no++;
98
99 /* Build the FRMR */
100 frmr->kva = frva;
101 frmr->direction = DMA_TO_DEVICE;
102 frmr->access_flags = 0;
103 frmr->map_len = PAGE_SIZE;
104 frmr->page_list_len = 1;
105 frmr->page_list->page_list[page_no] =
106 ib_dma_map_single(xprt->sc_cm_id->device,
107 (void *)xdr->head[0].iov_base,
108 PAGE_SIZE, DMA_TO_DEVICE);
109 if (ib_dma_mapping_error(xprt->sc_cm_id->device,
110 frmr->page_list->page_list[page_no]))
111 goto fatal_err;
112 atomic_inc(&xprt->sc_dma_used);
113
114 page_off = xdr->page_base;
115 page_bytes = xdr->page_len + page_off;
116 if (!page_bytes)
117 goto encode_tail;
118
119 /* Map the pages */
120 vec->sge[sge_no].iov_base = frva + frmr->map_len + page_off;
121 vec->sge[sge_no].iov_len = page_bytes;
122 sge_no++;
123 while (page_bytes) {
124 struct page *page;
125
126 page = xdr->pages[page_no++];
127 sge_bytes = min_t(u32, page_bytes, (PAGE_SIZE - page_off));
128 page_bytes -= sge_bytes;
129
130 frmr->page_list->page_list[page_no] =
131 ib_dma_map_page(xprt->sc_cm_id->device, page, 0,
132 PAGE_SIZE, DMA_TO_DEVICE);
133 if (ib_dma_mapping_error(xprt->sc_cm_id->device,
134 frmr->page_list->page_list[page_no]))
135 goto fatal_err;
136
137 atomic_inc(&xprt->sc_dma_used);
138 page_off = 0; /* reset for next time through loop */
139 frmr->map_len += PAGE_SIZE;
140 frmr->page_list_len++;
141 }
142 vec->count++;
143
144 encode_tail:
145 /* Map tail */
146 if (0 == xdr->tail[0].iov_len)
147 goto done;
148
149 vec->count++;
150 vec->sge[sge_no].iov_len = xdr->tail[0].iov_len;
151
152 if (((unsigned long)xdr->tail[0].iov_base & PAGE_MASK) ==
153 ((unsigned long)xdr->head[0].iov_base & PAGE_MASK)) {
154 /*
155 * If head and tail use the same page, we don't need
156 * to map it again.
157 */
158 vec->sge[sge_no].iov_base = xdr->tail[0].iov_base;
159 } else {
160 void *va;
161
162 /* Map another page for the tail */
163 page_off = (unsigned long)xdr->tail[0].iov_base & ~PAGE_MASK;
164 va = (void *)((unsigned long)xdr->tail[0].iov_base & PAGE_MASK);
165 vec->sge[sge_no].iov_base = frva + frmr->map_len + page_off;
166
167 frmr->page_list->page_list[page_no] =
168 ib_dma_map_single(xprt->sc_cm_id->device, va, PAGE_SIZE,
169 DMA_TO_DEVICE);
170 if (ib_dma_mapping_error(xprt->sc_cm_id->device,
171 frmr->page_list->page_list[page_no]))
172 goto fatal_err;
173 atomic_inc(&xprt->sc_dma_used);
174 frmr->map_len += PAGE_SIZE;
175 frmr->page_list_len++;
176 }
177
178 done:
179 if (svc_rdma_fastreg(xprt, frmr))
180 goto fatal_err;
181
182 return 0;
183
184 fatal_err:
185 printk("svcrdma: Error fast registering memory for xprt %p\n", xprt);
186 svc_rdma_put_frmr(xprt, frmr);
187 return -EIO;
188}
189
190static int map_xdr(struct svcxprt_rdma *xprt,
191 struct xdr_buf *xdr,
192 struct svc_rdma_req_map *vec)
75{ 193{
76 int sge_max = (xdr->len+PAGE_SIZE-1) / PAGE_SIZE + 3; 194 int sge_max = (xdr->len+PAGE_SIZE-1) / PAGE_SIZE + 3;
77 int sge_no; 195 int sge_no;
@@ -83,6 +201,9 @@ static void xdr_to_sge(struct svcxprt_rdma *xprt,
83 BUG_ON(xdr->len != 201 BUG_ON(xdr->len !=
84 (xdr->head[0].iov_len + xdr->page_len + xdr->tail[0].iov_len)); 202 (xdr->head[0].iov_len + xdr->page_len + xdr->tail[0].iov_len));
85 203
204 if (xprt->sc_frmr_pg_list_len)
205 return fast_reg_xdr(xprt, xdr, vec);
206
86 /* Skip the first sge, this is for the RPCRDMA header */ 207 /* Skip the first sge, this is for the RPCRDMA header */
87 sge_no = 1; 208 sge_no = 1;
88 209
@@ -116,9 +237,12 @@ static void xdr_to_sge(struct svcxprt_rdma *xprt,
116 237
117 BUG_ON(sge_no > sge_max); 238 BUG_ON(sge_no > sge_max);
118 vec->count = sge_no; 239 vec->count = sge_no;
240 return 0;
119} 241}
120 242
121/* Assumptions: 243/* Assumptions:
244 * - We are using FRMR
245 * - or -
122 * - The specified write_len can be represented in sc_max_sge * PAGE_SIZE 246 * - The specified write_len can be represented in sc_max_sge * PAGE_SIZE
123 */ 247 */
124static int send_write(struct svcxprt_rdma *xprt, struct svc_rqst *rqstp, 248static int send_write(struct svcxprt_rdma *xprt, struct svc_rqst *rqstp,
@@ -158,30 +282,35 @@ static int send_write(struct svcxprt_rdma *xprt, struct svc_rqst *rqstp,
158 sge_no = 0; 282 sge_no = 0;
159 283
160 /* Copy the remaining SGE */ 284 /* Copy the remaining SGE */
161 while (bc != 0 && xdr_sge_no < vec->count) { 285 while (bc != 0) {
162 sge[sge_no].lkey = xprt->sc_phys_mr->lkey; 286 sge_bytes = min_t(size_t,
163 sge_bytes = min((size_t)bc, 287 bc, vec->sge[xdr_sge_no].iov_len-sge_off);
164 (size_t)(vec->sge[xdr_sge_no].iov_len-sge_off));
165 sge[sge_no].length = sge_bytes; 288 sge[sge_no].length = sge_bytes;
166 atomic_inc(&xprt->sc_dma_used); 289 if (!vec->frmr) {
167 sge[sge_no].addr = 290 sge[sge_no].addr =
168 ib_dma_map_single(xprt->sc_cm_id->device, 291 ib_dma_map_single(xprt->sc_cm_id->device,
169 (void *) 292 (void *)
170 vec->sge[xdr_sge_no].iov_base + sge_off, 293 vec->sge[xdr_sge_no].iov_base + sge_off,
171 sge_bytes, DMA_TO_DEVICE); 294 sge_bytes, DMA_TO_DEVICE);
172 if (dma_mapping_error(xprt->sc_cm_id->device->dma_device, 295 if (ib_dma_mapping_error(xprt->sc_cm_id->device,
173 sge[sge_no].addr)) 296 sge[sge_no].addr))
174 goto err; 297 goto err;
298 atomic_inc(&xprt->sc_dma_used);
299 sge[sge_no].lkey = xprt->sc_dma_lkey;
300 } else {
301 sge[sge_no].addr = (unsigned long)
302 vec->sge[xdr_sge_no].iov_base + sge_off;
303 sge[sge_no].lkey = vec->frmr->mr->lkey;
304 }
305 ctxt->count++;
306 ctxt->frmr = vec->frmr;
175 sge_off = 0; 307 sge_off = 0;
176 sge_no++; 308 sge_no++;
177 ctxt->count++;
178 xdr_sge_no++; 309 xdr_sge_no++;
310 BUG_ON(xdr_sge_no > vec->count);
179 bc -= sge_bytes; 311 bc -= sge_bytes;
180 } 312 }
181 313
182 BUG_ON(bc != 0);
183 BUG_ON(xdr_sge_no > vec->count);
184
185 /* Prepare WRITE WR */ 314 /* Prepare WRITE WR */
186 memset(&write_wr, 0, sizeof write_wr); 315 memset(&write_wr, 0, sizeof write_wr);
187 ctxt->wr_op = IB_WR_RDMA_WRITE; 316 ctxt->wr_op = IB_WR_RDMA_WRITE;
@@ -226,7 +355,10 @@ static int send_write_chunks(struct svcxprt_rdma *xprt,
226 res_ary = (struct rpcrdma_write_array *) 355 res_ary = (struct rpcrdma_write_array *)
227 &rdma_resp->rm_body.rm_chunks[1]; 356 &rdma_resp->rm_body.rm_chunks[1];
228 357
229 max_write = xprt->sc_max_sge * PAGE_SIZE; 358 if (vec->frmr)
359 max_write = vec->frmr->map_len;
360 else
361 max_write = xprt->sc_max_sge * PAGE_SIZE;
230 362
231 /* Write chunks start at the pagelist */ 363 /* Write chunks start at the pagelist */
232 for (xdr_off = rqstp->rq_res.head[0].iov_len, chunk_no = 0; 364 for (xdr_off = rqstp->rq_res.head[0].iov_len, chunk_no = 0;
@@ -297,7 +429,10 @@ static int send_reply_chunks(struct svcxprt_rdma *xprt,
297 res_ary = (struct rpcrdma_write_array *) 429 res_ary = (struct rpcrdma_write_array *)
298 &rdma_resp->rm_body.rm_chunks[2]; 430 &rdma_resp->rm_body.rm_chunks[2];
299 431
300 max_write = xprt->sc_max_sge * PAGE_SIZE; 432 if (vec->frmr)
433 max_write = vec->frmr->map_len;
434 else
435 max_write = xprt->sc_max_sge * PAGE_SIZE;
301 436
302 /* xdr offset starts at RPC message */ 437 /* xdr offset starts at RPC message */
303 for (xdr_off = 0, chunk_no = 0; 438 for (xdr_off = 0, chunk_no = 0;
@@ -307,7 +442,6 @@ static int send_reply_chunks(struct svcxprt_rdma *xprt,
307 ch = &arg_ary->wc_array[chunk_no].wc_target; 442 ch = &arg_ary->wc_array[chunk_no].wc_target;
308 write_len = min(xfer_len, ch->rs_length); 443 write_len = min(xfer_len, ch->rs_length);
309 444
310
311 /* Prepare the reply chunk given the length actually 445 /* Prepare the reply chunk given the length actually
312 * written */ 446 * written */
313 rs_offset = get_unaligned(&(ch->rs_offset)); 447 rs_offset = get_unaligned(&(ch->rs_offset));
@@ -366,6 +500,7 @@ static int send_reply(struct svcxprt_rdma *rdma,
366 int byte_count) 500 int byte_count)
367{ 501{
368 struct ib_send_wr send_wr; 502 struct ib_send_wr send_wr;
503 struct ib_send_wr inv_wr;
369 int sge_no; 504 int sge_no;
370 int sge_bytes; 505 int sge_bytes;
371 int page_no; 506 int page_no;
@@ -385,27 +520,45 @@ static int send_reply(struct svcxprt_rdma *rdma,
385 /* Prepare the context */ 520 /* Prepare the context */
386 ctxt->pages[0] = page; 521 ctxt->pages[0] = page;
387 ctxt->count = 1; 522 ctxt->count = 1;
523 ctxt->frmr = vec->frmr;
524 if (vec->frmr)
525 set_bit(RDMACTXT_F_FAST_UNREG, &ctxt->flags);
526 else
527 clear_bit(RDMACTXT_F_FAST_UNREG, &ctxt->flags);
388 528
389 /* Prepare the SGE for the RPCRDMA Header */ 529 /* Prepare the SGE for the RPCRDMA Header */
390 atomic_inc(&rdma->sc_dma_used);
391 ctxt->sge[0].addr = 530 ctxt->sge[0].addr =
392 ib_dma_map_page(rdma->sc_cm_id->device, 531 ib_dma_map_page(rdma->sc_cm_id->device,
393 page, 0, PAGE_SIZE, DMA_TO_DEVICE); 532 page, 0, PAGE_SIZE, DMA_TO_DEVICE);
533 if (ib_dma_mapping_error(rdma->sc_cm_id->device, ctxt->sge[0].addr))
534 goto err;
535 atomic_inc(&rdma->sc_dma_used);
536
394 ctxt->direction = DMA_TO_DEVICE; 537 ctxt->direction = DMA_TO_DEVICE;
538
395 ctxt->sge[0].length = svc_rdma_xdr_get_reply_hdr_len(rdma_resp); 539 ctxt->sge[0].length = svc_rdma_xdr_get_reply_hdr_len(rdma_resp);
396 ctxt->sge[0].lkey = rdma->sc_phys_mr->lkey; 540 ctxt->sge[0].lkey = rdma->sc_dma_lkey;
397 541
398 /* Determine how many of our SGE are to be transmitted */ 542 /* Determine how many of our SGE are to be transmitted */
399 for (sge_no = 1; byte_count && sge_no < vec->count; sge_no++) { 543 for (sge_no = 1; byte_count && sge_no < vec->count; sge_no++) {
400 sge_bytes = min_t(size_t, vec->sge[sge_no].iov_len, byte_count); 544 sge_bytes = min_t(size_t, vec->sge[sge_no].iov_len, byte_count);
401 byte_count -= sge_bytes; 545 byte_count -= sge_bytes;
402 atomic_inc(&rdma->sc_dma_used); 546 if (!vec->frmr) {
403 ctxt->sge[sge_no].addr = 547 ctxt->sge[sge_no].addr =
404 ib_dma_map_single(rdma->sc_cm_id->device, 548 ib_dma_map_single(rdma->sc_cm_id->device,
405 vec->sge[sge_no].iov_base, 549 vec->sge[sge_no].iov_base,
406 sge_bytes, DMA_TO_DEVICE); 550 sge_bytes, DMA_TO_DEVICE);
551 if (ib_dma_mapping_error(rdma->sc_cm_id->device,
552 ctxt->sge[sge_no].addr))
553 goto err;
554 atomic_inc(&rdma->sc_dma_used);
555 ctxt->sge[sge_no].lkey = rdma->sc_dma_lkey;
556 } else {
557 ctxt->sge[sge_no].addr = (unsigned long)
558 vec->sge[sge_no].iov_base;
559 ctxt->sge[sge_no].lkey = vec->frmr->mr->lkey;
560 }
407 ctxt->sge[sge_no].length = sge_bytes; 561 ctxt->sge[sge_no].length = sge_bytes;
408 ctxt->sge[sge_no].lkey = rdma->sc_phys_mr->lkey;
409 } 562 }
410 BUG_ON(byte_count != 0); 563 BUG_ON(byte_count != 0);
411 564
@@ -417,11 +570,16 @@ static int send_reply(struct svcxprt_rdma *rdma,
417 ctxt->pages[page_no+1] = rqstp->rq_respages[page_no]; 570 ctxt->pages[page_no+1] = rqstp->rq_respages[page_no];
418 ctxt->count++; 571 ctxt->count++;
419 rqstp->rq_respages[page_no] = NULL; 572 rqstp->rq_respages[page_no] = NULL;
420 /* If there are more pages than SGE, terminate SGE list */ 573 /*
574 * If there are more pages than SGE, terminate SGE
575 * list so that svc_rdma_unmap_dma doesn't attempt to
576 * unmap garbage.
577 */
421 if (page_no+1 >= sge_no) 578 if (page_no+1 >= sge_no)
422 ctxt->sge[page_no+1].length = 0; 579 ctxt->sge[page_no+1].length = 0;
423 } 580 }
424 BUG_ON(sge_no > rdma->sc_max_sge); 581 BUG_ON(sge_no > rdma->sc_max_sge);
582 BUG_ON(sge_no > ctxt->count);
425 memset(&send_wr, 0, sizeof send_wr); 583 memset(&send_wr, 0, sizeof send_wr);
426 ctxt->wr_op = IB_WR_SEND; 584 ctxt->wr_op = IB_WR_SEND;
427 send_wr.wr_id = (unsigned long)ctxt; 585 send_wr.wr_id = (unsigned long)ctxt;
@@ -429,12 +587,26 @@ static int send_reply(struct svcxprt_rdma *rdma,
429 send_wr.num_sge = sge_no; 587 send_wr.num_sge = sge_no;
430 send_wr.opcode = IB_WR_SEND; 588 send_wr.opcode = IB_WR_SEND;
431 send_wr.send_flags = IB_SEND_SIGNALED; 589 send_wr.send_flags = IB_SEND_SIGNALED;
590 if (vec->frmr) {
591 /* Prepare INVALIDATE WR */
592 memset(&inv_wr, 0, sizeof inv_wr);
593 inv_wr.opcode = IB_WR_LOCAL_INV;
594 inv_wr.send_flags = IB_SEND_SIGNALED;
595 inv_wr.ex.invalidate_rkey =
596 vec->frmr->mr->lkey;
597 send_wr.next = &inv_wr;
598 }
432 599
433 ret = svc_rdma_send(rdma, &send_wr); 600 ret = svc_rdma_send(rdma, &send_wr);
434 if (ret) 601 if (ret)
435 svc_rdma_put_context(ctxt, 1); 602 goto err;
436 603
437 return ret; 604 return 0;
605
606 err:
607 svc_rdma_put_frmr(rdma, vec->frmr);
608 svc_rdma_put_context(ctxt, 1);
609 return -EIO;
438} 610}
439 611
440void svc_rdma_prep_reply_hdr(struct svc_rqst *rqstp) 612void svc_rdma_prep_reply_hdr(struct svc_rqst *rqstp)
@@ -477,8 +649,9 @@ int svc_rdma_sendto(struct svc_rqst *rqstp)
477 ctxt = svc_rdma_get_context(rdma); 649 ctxt = svc_rdma_get_context(rdma);
478 ctxt->direction = DMA_TO_DEVICE; 650 ctxt->direction = DMA_TO_DEVICE;
479 vec = svc_rdma_get_req_map(); 651 vec = svc_rdma_get_req_map();
480 xdr_to_sge(rdma, &rqstp->rq_res, vec); 652 ret = map_xdr(rdma, &rqstp->rq_res, vec);
481 653 if (ret)
654 goto err0;
482 inline_bytes = rqstp->rq_res.len; 655 inline_bytes = rqstp->rq_res.len;
483 656
484 /* Create the RDMA response header */ 657 /* Create the RDMA response header */
@@ -498,7 +671,7 @@ int svc_rdma_sendto(struct svc_rqst *rqstp)
498 if (ret < 0) { 671 if (ret < 0) {
499 printk(KERN_ERR "svcrdma: failed to send write chunks, rc=%d\n", 672 printk(KERN_ERR "svcrdma: failed to send write chunks, rc=%d\n",
500 ret); 673 ret);
501 goto error; 674 goto err1;
502 } 675 }
503 inline_bytes -= ret; 676 inline_bytes -= ret;
504 677
@@ -508,7 +681,7 @@ int svc_rdma_sendto(struct svc_rqst *rqstp)
508 if (ret < 0) { 681 if (ret < 0) {
509 printk(KERN_ERR "svcrdma: failed to send reply chunks, rc=%d\n", 682 printk(KERN_ERR "svcrdma: failed to send reply chunks, rc=%d\n",
510 ret); 683 ret);
511 goto error; 684 goto err1;
512 } 685 }
513 inline_bytes -= ret; 686 inline_bytes -= ret;
514 687
@@ -517,9 +690,11 @@ int svc_rdma_sendto(struct svc_rqst *rqstp)
517 svc_rdma_put_req_map(vec); 690 svc_rdma_put_req_map(vec);
518 dprintk("svcrdma: send_reply returns %d\n", ret); 691 dprintk("svcrdma: send_reply returns %d\n", ret);
519 return ret; 692 return ret;
520 error: 693
694 err1:
695 put_page(res_page);
696 err0:
521 svc_rdma_put_req_map(vec); 697 svc_rdma_put_req_map(vec);
522 svc_rdma_put_context(ctxt, 0); 698 svc_rdma_put_context(ctxt, 0);
523 put_page(res_page);
524 return ret; 699 return ret;
525} 700}
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
index 900cb69728c..6fb493cbd29 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
@@ -100,20 +100,29 @@ struct svc_rdma_op_ctxt *svc_rdma_get_context(struct svcxprt_rdma *xprt)
100 ctxt->xprt = xprt; 100 ctxt->xprt = xprt;
101 INIT_LIST_HEAD(&ctxt->dto_q); 101 INIT_LIST_HEAD(&ctxt->dto_q);
102 ctxt->count = 0; 102 ctxt->count = 0;
103 ctxt->frmr = NULL;
103 atomic_inc(&xprt->sc_ctxt_used); 104 atomic_inc(&xprt->sc_ctxt_used);
104 return ctxt; 105 return ctxt;
105} 106}
106 107
107static void svc_rdma_unmap_dma(struct svc_rdma_op_ctxt *ctxt) 108void svc_rdma_unmap_dma(struct svc_rdma_op_ctxt *ctxt)
108{ 109{
109 struct svcxprt_rdma *xprt = ctxt->xprt; 110 struct svcxprt_rdma *xprt = ctxt->xprt;
110 int i; 111 int i;
111 for (i = 0; i < ctxt->count && ctxt->sge[i].length; i++) { 112 for (i = 0; i < ctxt->count && ctxt->sge[i].length; i++) {
112 atomic_dec(&xprt->sc_dma_used); 113 /*
113 ib_dma_unmap_single(xprt->sc_cm_id->device, 114 * Unmap the DMA addr in the SGE if the lkey matches
114 ctxt->sge[i].addr, 115 * the sc_dma_lkey, otherwise, ignore it since it is
115 ctxt->sge[i].length, 116 * an FRMR lkey and will be unmapped later when the
116 ctxt->direction); 117 * last WR that uses it completes.
118 */
119 if (ctxt->sge[i].lkey == xprt->sc_dma_lkey) {
120 atomic_dec(&xprt->sc_dma_used);
121 ib_dma_unmap_single(xprt->sc_cm_id->device,
122 ctxt->sge[i].addr,
123 ctxt->sge[i].length,
124 ctxt->direction);
125 }
117 } 126 }
118} 127}
119 128
@@ -150,6 +159,7 @@ struct svc_rdma_req_map *svc_rdma_get_req_map(void)
150 schedule_timeout_uninterruptible(msecs_to_jiffies(500)); 159 schedule_timeout_uninterruptible(msecs_to_jiffies(500));
151 } 160 }
152 map->count = 0; 161 map->count = 0;
162 map->frmr = NULL;
153 return map; 163 return map;
154} 164}
155 165
@@ -316,6 +326,50 @@ static void rq_cq_reap(struct svcxprt_rdma *xprt)
316} 326}
317 327
318/* 328/*
329 * Processs a completion context
330 */
331static void process_context(struct svcxprt_rdma *xprt,
332 struct svc_rdma_op_ctxt *ctxt)
333{
334 svc_rdma_unmap_dma(ctxt);
335
336 switch (ctxt->wr_op) {
337 case IB_WR_SEND:
338 if (test_bit(RDMACTXT_F_FAST_UNREG, &ctxt->flags))
339 svc_rdma_put_frmr(xprt, ctxt->frmr);
340 svc_rdma_put_context(ctxt, 1);
341 break;
342
343 case IB_WR_RDMA_WRITE:
344 svc_rdma_put_context(ctxt, 0);
345 break;
346
347 case IB_WR_RDMA_READ:
348 case IB_WR_RDMA_READ_WITH_INV:
349 if (test_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags)) {
350 struct svc_rdma_op_ctxt *read_hdr = ctxt->read_hdr;
351 BUG_ON(!read_hdr);
352 if (test_bit(RDMACTXT_F_FAST_UNREG, &ctxt->flags))
353 svc_rdma_put_frmr(xprt, ctxt->frmr);
354 spin_lock_bh(&xprt->sc_rq_dto_lock);
355 set_bit(XPT_DATA, &xprt->sc_xprt.xpt_flags);
356 list_add_tail(&read_hdr->dto_q,
357 &xprt->sc_read_complete_q);
358 spin_unlock_bh(&xprt->sc_rq_dto_lock);
359 svc_xprt_enqueue(&xprt->sc_xprt);
360 }
361 svc_rdma_put_context(ctxt, 0);
362 break;
363
364 default:
365 printk(KERN_ERR "svcrdma: unexpected completion type, "
366 "opcode=%d\n",
367 ctxt->wr_op);
368 break;
369 }
370}
371
372/*
319 * Send Queue Completion Handler - potentially called on interrupt context. 373 * Send Queue Completion Handler - potentially called on interrupt context.
320 * 374 *
321 * Note that caller must hold a transport reference. 375 * Note that caller must hold a transport reference.
@@ -327,17 +381,12 @@ static void sq_cq_reap(struct svcxprt_rdma *xprt)
327 struct ib_cq *cq = xprt->sc_sq_cq; 381 struct ib_cq *cq = xprt->sc_sq_cq;
328 int ret; 382 int ret;
329 383
330
331 if (!test_and_clear_bit(RDMAXPRT_SQ_PENDING, &xprt->sc_flags)) 384 if (!test_and_clear_bit(RDMAXPRT_SQ_PENDING, &xprt->sc_flags))
332 return; 385 return;
333 386
334 ib_req_notify_cq(xprt->sc_sq_cq, IB_CQ_NEXT_COMP); 387 ib_req_notify_cq(xprt->sc_sq_cq, IB_CQ_NEXT_COMP);
335 atomic_inc(&rdma_stat_sq_poll); 388 atomic_inc(&rdma_stat_sq_poll);
336 while ((ret = ib_poll_cq(cq, 1, &wc)) > 0) { 389 while ((ret = ib_poll_cq(cq, 1, &wc)) > 0) {
337 ctxt = (struct svc_rdma_op_ctxt *)(unsigned long)wc.wr_id;
338 xprt = ctxt->xprt;
339
340 svc_rdma_unmap_dma(ctxt);
341 if (wc.status != IB_WC_SUCCESS) 390 if (wc.status != IB_WC_SUCCESS)
342 /* Close the transport */ 391 /* Close the transport */
343 set_bit(XPT_CLOSE, &xprt->sc_xprt.xpt_flags); 392 set_bit(XPT_CLOSE, &xprt->sc_xprt.xpt_flags);
@@ -346,35 +395,10 @@ static void sq_cq_reap(struct svcxprt_rdma *xprt)
346 atomic_dec(&xprt->sc_sq_count); 395 atomic_dec(&xprt->sc_sq_count);
347 wake_up(&xprt->sc_send_wait); 396 wake_up(&xprt->sc_send_wait);
348 397
349 switch (ctxt->wr_op) { 398 ctxt = (struct svc_rdma_op_ctxt *)(unsigned long)wc.wr_id;
350 case IB_WR_SEND: 399 if (ctxt)
351 svc_rdma_put_context(ctxt, 1); 400 process_context(xprt, ctxt);
352 break;
353
354 case IB_WR_RDMA_WRITE:
355 svc_rdma_put_context(ctxt, 0);
356 break;
357
358 case IB_WR_RDMA_READ:
359 if (test_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags)) {
360 struct svc_rdma_op_ctxt *read_hdr = ctxt->read_hdr;
361 BUG_ON(!read_hdr);
362 spin_lock_bh(&xprt->sc_rq_dto_lock);
363 set_bit(XPT_DATA, &xprt->sc_xprt.xpt_flags);
364 list_add_tail(&read_hdr->dto_q,
365 &xprt->sc_read_complete_q);
366 spin_unlock_bh(&xprt->sc_rq_dto_lock);
367 svc_xprt_enqueue(&xprt->sc_xprt);
368 }
369 svc_rdma_put_context(ctxt, 0);
370 break;
371 401
372 default:
373 printk(KERN_ERR "svcrdma: unexpected completion type, "
374 "opcode=%d, status=%d\n",
375 wc.opcode, wc.status);
376 break;
377 }
378 svc_xprt_put(&xprt->sc_xprt); 402 svc_xprt_put(&xprt->sc_xprt);
379 } 403 }
380 404
@@ -425,10 +449,12 @@ static struct svcxprt_rdma *rdma_create_xprt(struct svc_serv *serv,
425 INIT_LIST_HEAD(&cma_xprt->sc_dto_q); 449 INIT_LIST_HEAD(&cma_xprt->sc_dto_q);
426 INIT_LIST_HEAD(&cma_xprt->sc_rq_dto_q); 450 INIT_LIST_HEAD(&cma_xprt->sc_rq_dto_q);
427 INIT_LIST_HEAD(&cma_xprt->sc_read_complete_q); 451 INIT_LIST_HEAD(&cma_xprt->sc_read_complete_q);
452 INIT_LIST_HEAD(&cma_xprt->sc_frmr_q);
428 init_waitqueue_head(&cma_xprt->sc_send_wait); 453 init_waitqueue_head(&cma_xprt->sc_send_wait);
429 454
430 spin_lock_init(&cma_xprt->sc_lock); 455 spin_lock_init(&cma_xprt->sc_lock);
431 spin_lock_init(&cma_xprt->sc_rq_dto_lock); 456 spin_lock_init(&cma_xprt->sc_rq_dto_lock);
457 spin_lock_init(&cma_xprt->sc_frmr_q_lock);
432 458
433 cma_xprt->sc_ord = svcrdma_ord; 459 cma_xprt->sc_ord = svcrdma_ord;
434 460
@@ -462,7 +488,7 @@ int svc_rdma_post_recv(struct svcxprt_rdma *xprt)
462 struct ib_recv_wr recv_wr, *bad_recv_wr; 488 struct ib_recv_wr recv_wr, *bad_recv_wr;
463 struct svc_rdma_op_ctxt *ctxt; 489 struct svc_rdma_op_ctxt *ctxt;
464 struct page *page; 490 struct page *page;
465 unsigned long pa; 491 dma_addr_t pa;
466 int sge_no; 492 int sge_no;
467 int buflen; 493 int buflen;
468 int ret; 494 int ret;
@@ -474,13 +500,15 @@ int svc_rdma_post_recv(struct svcxprt_rdma *xprt)
474 BUG_ON(sge_no >= xprt->sc_max_sge); 500 BUG_ON(sge_no >= xprt->sc_max_sge);
475 page = svc_rdma_get_page(); 501 page = svc_rdma_get_page();
476 ctxt->pages[sge_no] = page; 502 ctxt->pages[sge_no] = page;
477 atomic_inc(&xprt->sc_dma_used);
478 pa = ib_dma_map_page(xprt->sc_cm_id->device, 503 pa = ib_dma_map_page(xprt->sc_cm_id->device,
479 page, 0, PAGE_SIZE, 504 page, 0, PAGE_SIZE,
480 DMA_FROM_DEVICE); 505 DMA_FROM_DEVICE);
506 if (ib_dma_mapping_error(xprt->sc_cm_id->device, pa))
507 goto err_put_ctxt;
508 atomic_inc(&xprt->sc_dma_used);
481 ctxt->sge[sge_no].addr = pa; 509 ctxt->sge[sge_no].addr = pa;
482 ctxt->sge[sge_no].length = PAGE_SIZE; 510 ctxt->sge[sge_no].length = PAGE_SIZE;
483 ctxt->sge[sge_no].lkey = xprt->sc_phys_mr->lkey; 511 ctxt->sge[sge_no].lkey = xprt->sc_dma_lkey;
484 buflen += PAGE_SIZE; 512 buflen += PAGE_SIZE;
485 } 513 }
486 ctxt->count = sge_no; 514 ctxt->count = sge_no;
@@ -496,6 +524,10 @@ int svc_rdma_post_recv(struct svcxprt_rdma *xprt)
496 svc_rdma_put_context(ctxt, 1); 524 svc_rdma_put_context(ctxt, 1);
497 } 525 }
498 return ret; 526 return ret;
527
528 err_put_ctxt:
529 svc_rdma_put_context(ctxt, 1);
530 return -ENOMEM;
499} 531}
500 532
501/* 533/*
@@ -566,7 +598,7 @@ static int rdma_listen_handler(struct rdma_cm_id *cma_id,
566 dprintk("svcrdma: Connect request on cma_id=%p, xprt = %p, " 598 dprintk("svcrdma: Connect request on cma_id=%p, xprt = %p, "
567 "event=%d\n", cma_id, cma_id->context, event->event); 599 "event=%d\n", cma_id, cma_id->context, event->event);
568 handle_connect_req(cma_id, 600 handle_connect_req(cma_id,
569 event->param.conn.responder_resources); 601 event->param.conn.initiator_depth);
570 break; 602 break;
571 603
572 case RDMA_CM_EVENT_ESTABLISHED: 604 case RDMA_CM_EVENT_ESTABLISHED:
@@ -686,6 +718,97 @@ static struct svc_xprt *svc_rdma_create(struct svc_serv *serv,
686 return ERR_PTR(ret); 718 return ERR_PTR(ret);
687} 719}
688 720
721static struct svc_rdma_fastreg_mr *rdma_alloc_frmr(struct svcxprt_rdma *xprt)
722{
723 struct ib_mr *mr;
724 struct ib_fast_reg_page_list *pl;
725 struct svc_rdma_fastreg_mr *frmr;
726
727 frmr = kmalloc(sizeof(*frmr), GFP_KERNEL);
728 if (!frmr)
729 goto err;
730
731 mr = ib_alloc_fast_reg_mr(xprt->sc_pd, RPCSVC_MAXPAGES);
732 if (!mr)
733 goto err_free_frmr;
734
735 pl = ib_alloc_fast_reg_page_list(xprt->sc_cm_id->device,
736 RPCSVC_MAXPAGES);
737 if (!pl)
738 goto err_free_mr;
739
740 frmr->mr = mr;
741 frmr->page_list = pl;
742 INIT_LIST_HEAD(&frmr->frmr_list);
743 return frmr;
744
745 err_free_mr:
746 ib_dereg_mr(mr);
747 err_free_frmr:
748 kfree(frmr);
749 err:
750 return ERR_PTR(-ENOMEM);
751}
752
753static void rdma_dealloc_frmr_q(struct svcxprt_rdma *xprt)
754{
755 struct svc_rdma_fastreg_mr *frmr;
756
757 while (!list_empty(&xprt->sc_frmr_q)) {
758 frmr = list_entry(xprt->sc_frmr_q.next,
759 struct svc_rdma_fastreg_mr, frmr_list);
760 list_del_init(&frmr->frmr_list);
761 ib_dereg_mr(frmr->mr);
762 ib_free_fast_reg_page_list(frmr->page_list);
763 kfree(frmr);
764 }
765}
766
767struct svc_rdma_fastreg_mr *svc_rdma_get_frmr(struct svcxprt_rdma *rdma)
768{
769 struct svc_rdma_fastreg_mr *frmr = NULL;
770
771 spin_lock_bh(&rdma->sc_frmr_q_lock);
772 if (!list_empty(&rdma->sc_frmr_q)) {
773 frmr = list_entry(rdma->sc_frmr_q.next,
774 struct svc_rdma_fastreg_mr, frmr_list);
775 list_del_init(&frmr->frmr_list);
776 frmr->map_len = 0;
777 frmr->page_list_len = 0;
778 }
779 spin_unlock_bh(&rdma->sc_frmr_q_lock);
780 if (frmr)
781 return frmr;
782
783 return rdma_alloc_frmr(rdma);
784}
785
786static void frmr_unmap_dma(struct svcxprt_rdma *xprt,
787 struct svc_rdma_fastreg_mr *frmr)
788{
789 int page_no;
790 for (page_no = 0; page_no < frmr->page_list_len; page_no++) {
791 dma_addr_t addr = frmr->page_list->page_list[page_no];
792 if (ib_dma_mapping_error(frmr->mr->device, addr))
793 continue;
794 atomic_dec(&xprt->sc_dma_used);
795 ib_dma_unmap_single(frmr->mr->device, addr, PAGE_SIZE,
796 frmr->direction);
797 }
798}
799
800void svc_rdma_put_frmr(struct svcxprt_rdma *rdma,
801 struct svc_rdma_fastreg_mr *frmr)
802{
803 if (frmr) {
804 frmr_unmap_dma(rdma, frmr);
805 spin_lock_bh(&rdma->sc_frmr_q_lock);
806 BUG_ON(!list_empty(&frmr->frmr_list));
807 list_add(&frmr->frmr_list, &rdma->sc_frmr_q);
808 spin_unlock_bh(&rdma->sc_frmr_q_lock);
809 }
810}
811
689/* 812/*
690 * This is the xpo_recvfrom function for listening endpoints. Its 813 * This is the xpo_recvfrom function for listening endpoints. Its
691 * purpose is to accept incoming connections. The CMA callback handler 814 * purpose is to accept incoming connections. The CMA callback handler
@@ -704,6 +827,8 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
704 struct rdma_conn_param conn_param; 827 struct rdma_conn_param conn_param;
705 struct ib_qp_init_attr qp_attr; 828 struct ib_qp_init_attr qp_attr;
706 struct ib_device_attr devattr; 829 struct ib_device_attr devattr;
830 int dma_mr_acc;
831 int need_dma_mr;
707 int ret; 832 int ret;
708 int i; 833 int i;
709 834
@@ -819,15 +944,77 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
819 } 944 }
820 newxprt->sc_qp = newxprt->sc_cm_id->qp; 945 newxprt->sc_qp = newxprt->sc_cm_id->qp;
821 946
822 /* Register all of physical memory */ 947 /*
823 newxprt->sc_phys_mr = ib_get_dma_mr(newxprt->sc_pd, 948 * Use the most secure set of MR resources based on the
824 IB_ACCESS_LOCAL_WRITE | 949 * transport type and available memory management features in
825 IB_ACCESS_REMOTE_WRITE); 950 * the device. Here's the table implemented below:
826 if (IS_ERR(newxprt->sc_phys_mr)) { 951 *
827 dprintk("svcrdma: Failed to create DMA MR ret=%d\n", ret); 952 * Fast Global DMA Remote WR
953 * Reg LKEY MR Access
954 * Sup'd Sup'd Needed Needed
955 *
956 * IWARP N N Y Y
957 * N Y Y Y
958 * Y N Y N
959 * Y Y N -
960 *
961 * IB N N Y N
962 * N Y N -
963 * Y N Y N
964 * Y Y N -
965 *
966 * NB: iWARP requires remote write access for the data sink
967 * of an RDMA_READ. IB does not.
968 */
969 if (devattr.device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS) {
970 newxprt->sc_frmr_pg_list_len =
971 devattr.max_fast_reg_page_list_len;
972 newxprt->sc_dev_caps |= SVCRDMA_DEVCAP_FAST_REG;
973 }
974
975 /*
976 * Determine if a DMA MR is required and if so, what privs are required
977 */
978 switch (rdma_node_get_transport(newxprt->sc_cm_id->device->node_type)) {
979 case RDMA_TRANSPORT_IWARP:
980 newxprt->sc_dev_caps |= SVCRDMA_DEVCAP_READ_W_INV;
981 if (!(newxprt->sc_dev_caps & SVCRDMA_DEVCAP_FAST_REG)) {
982 need_dma_mr = 1;
983 dma_mr_acc =
984 (IB_ACCESS_LOCAL_WRITE |
985 IB_ACCESS_REMOTE_WRITE);
986 } else if (!(devattr.device_cap_flags & IB_DEVICE_LOCAL_DMA_LKEY)) {
987 need_dma_mr = 1;
988 dma_mr_acc = IB_ACCESS_LOCAL_WRITE;
989 } else
990 need_dma_mr = 0;
991 break;
992 case RDMA_TRANSPORT_IB:
993 if (!(devattr.device_cap_flags & IB_DEVICE_LOCAL_DMA_LKEY)) {
994 need_dma_mr = 1;
995 dma_mr_acc = IB_ACCESS_LOCAL_WRITE;
996 } else
997 need_dma_mr = 0;
998 break;
999 default:
828 goto errout; 1000 goto errout;
829 } 1001 }
830 1002
1003 /* Create the DMA MR if needed, otherwise, use the DMA LKEY */
1004 if (need_dma_mr) {
1005 /* Register all of physical memory */
1006 newxprt->sc_phys_mr =
1007 ib_get_dma_mr(newxprt->sc_pd, dma_mr_acc);
1008 if (IS_ERR(newxprt->sc_phys_mr)) {
1009 dprintk("svcrdma: Failed to create DMA MR ret=%d\n",
1010 ret);
1011 goto errout;
1012 }
1013 newxprt->sc_dma_lkey = newxprt->sc_phys_mr->lkey;
1014 } else
1015 newxprt->sc_dma_lkey =
1016 newxprt->sc_cm_id->device->local_dma_lkey;
1017
831 /* Post receive buffers */ 1018 /* Post receive buffers */
832 for (i = 0; i < newxprt->sc_max_requests; i++) { 1019 for (i = 0; i < newxprt->sc_max_requests; i++) {
833 ret = svc_rdma_post_recv(newxprt); 1020 ret = svc_rdma_post_recv(newxprt);
@@ -961,6 +1148,9 @@ static void __svc_rdma_free(struct work_struct *work)
961 WARN_ON(atomic_read(&rdma->sc_ctxt_used) != 0); 1148 WARN_ON(atomic_read(&rdma->sc_ctxt_used) != 0);
962 WARN_ON(atomic_read(&rdma->sc_dma_used) != 0); 1149 WARN_ON(atomic_read(&rdma->sc_dma_used) != 0);
963 1150
1151 /* De-allocate fastreg mr */
1152 rdma_dealloc_frmr_q(rdma);
1153
964 /* Destroy the QP if present (not a listener) */ 1154 /* Destroy the QP if present (not a listener) */
965 if (rdma->sc_qp && !IS_ERR(rdma->sc_qp)) 1155 if (rdma->sc_qp && !IS_ERR(rdma->sc_qp))
966 ib_destroy_qp(rdma->sc_qp); 1156 ib_destroy_qp(rdma->sc_qp);
@@ -1014,21 +1204,59 @@ static int svc_rdma_has_wspace(struct svc_xprt *xprt)
1014 return 1; 1204 return 1;
1015} 1205}
1016 1206
1207/*
1208 * Attempt to register the kvec representing the RPC memory with the
1209 * device.
1210 *
1211 * Returns:
1212 * NULL : The device does not support fastreg or there were no more
1213 * fastreg mr.
1214 * frmr : The kvec register request was successfully posted.
1215 * <0 : An error was encountered attempting to register the kvec.
1216 */
1217int svc_rdma_fastreg(struct svcxprt_rdma *xprt,
1218 struct svc_rdma_fastreg_mr *frmr)
1219{
1220 struct ib_send_wr fastreg_wr;
1221 u8 key;
1222
1223 /* Bump the key */
1224 key = (u8)(frmr->mr->lkey & 0x000000FF);
1225 ib_update_fast_reg_key(frmr->mr, ++key);
1226
1227 /* Prepare FASTREG WR */
1228 memset(&fastreg_wr, 0, sizeof fastreg_wr);
1229 fastreg_wr.opcode = IB_WR_FAST_REG_MR;
1230 fastreg_wr.send_flags = IB_SEND_SIGNALED;
1231 fastreg_wr.wr.fast_reg.iova_start = (unsigned long)frmr->kva;
1232 fastreg_wr.wr.fast_reg.page_list = frmr->page_list;
1233 fastreg_wr.wr.fast_reg.page_list_len = frmr->page_list_len;
1234 fastreg_wr.wr.fast_reg.page_shift = PAGE_SHIFT;
1235 fastreg_wr.wr.fast_reg.length = frmr->map_len;
1236 fastreg_wr.wr.fast_reg.access_flags = frmr->access_flags;
1237 fastreg_wr.wr.fast_reg.rkey = frmr->mr->lkey;
1238 return svc_rdma_send(xprt, &fastreg_wr);
1239}
1240
1017int svc_rdma_send(struct svcxprt_rdma *xprt, struct ib_send_wr *wr) 1241int svc_rdma_send(struct svcxprt_rdma *xprt, struct ib_send_wr *wr)
1018{ 1242{
1019 struct ib_send_wr *bad_wr; 1243 struct ib_send_wr *bad_wr, *n_wr;
1244 int wr_count;
1245 int i;
1020 int ret; 1246 int ret;
1021 1247
1022 if (test_bit(XPT_CLOSE, &xprt->sc_xprt.xpt_flags)) 1248 if (test_bit(XPT_CLOSE, &xprt->sc_xprt.xpt_flags))
1023 return -ENOTCONN; 1249 return -ENOTCONN;
1024 1250
1025 BUG_ON(wr->send_flags != IB_SEND_SIGNALED); 1251 BUG_ON(wr->send_flags != IB_SEND_SIGNALED);
1026 BUG_ON(((struct svc_rdma_op_ctxt *)(unsigned long)wr->wr_id)->wr_op != 1252 wr_count = 1;
1027 wr->opcode); 1253 for (n_wr = wr->next; n_wr; n_wr = n_wr->next)
1254 wr_count++;
1255
1028 /* If the SQ is full, wait until an SQ entry is available */ 1256 /* If the SQ is full, wait until an SQ entry is available */
1029 while (1) { 1257 while (1) {
1030 spin_lock_bh(&xprt->sc_lock); 1258 spin_lock_bh(&xprt->sc_lock);
1031 if (xprt->sc_sq_depth == atomic_read(&xprt->sc_sq_count)) { 1259 if (xprt->sc_sq_depth < atomic_read(&xprt->sc_sq_count) + wr_count) {
1032 spin_unlock_bh(&xprt->sc_lock); 1260 spin_unlock_bh(&xprt->sc_lock);
1033 atomic_inc(&rdma_stat_sq_starve); 1261 atomic_inc(&rdma_stat_sq_starve);
1034 1262
@@ -1043,19 +1271,26 @@ int svc_rdma_send(struct svcxprt_rdma *xprt, struct ib_send_wr *wr)
1043 return 0; 1271 return 0;
1044 continue; 1272 continue;
1045 } 1273 }
1046 /* Bumped used SQ WR count and post */ 1274 /* Take a transport ref for each WR posted */
1047 svc_xprt_get(&xprt->sc_xprt); 1275 for (i = 0; i < wr_count; i++)
1276 svc_xprt_get(&xprt->sc_xprt);
1277
1278 /* Bump used SQ WR count and post */
1279 atomic_add(wr_count, &xprt->sc_sq_count);
1048 ret = ib_post_send(xprt->sc_qp, wr, &bad_wr); 1280 ret = ib_post_send(xprt->sc_qp, wr, &bad_wr);
1049 if (!ret) 1281 if (ret) {
1050 atomic_inc(&xprt->sc_sq_count); 1282 set_bit(XPT_CLOSE, &xprt->sc_xprt.xpt_flags);
1051 else { 1283 atomic_sub(wr_count, &xprt->sc_sq_count);
1052 svc_xprt_put(&xprt->sc_xprt); 1284 for (i = 0; i < wr_count; i ++)
1285 svc_xprt_put(&xprt->sc_xprt);
1053 dprintk("svcrdma: failed to post SQ WR rc=%d, " 1286 dprintk("svcrdma: failed to post SQ WR rc=%d, "
1054 "sc_sq_count=%d, sc_sq_depth=%d\n", 1287 "sc_sq_count=%d, sc_sq_depth=%d\n",
1055 ret, atomic_read(&xprt->sc_sq_count), 1288 ret, atomic_read(&xprt->sc_sq_count),
1056 xprt->sc_sq_depth); 1289 xprt->sc_sq_depth);
1057 } 1290 }
1058 spin_unlock_bh(&xprt->sc_lock); 1291 spin_unlock_bh(&xprt->sc_lock);
1292 if (ret)
1293 wake_up(&xprt->sc_send_wait);
1059 break; 1294 break;
1060 } 1295 }
1061 return ret; 1296 return ret;
@@ -1079,10 +1314,14 @@ void svc_rdma_send_error(struct svcxprt_rdma *xprt, struct rpcrdma_msg *rmsgp,
1079 length = svc_rdma_xdr_encode_error(xprt, rmsgp, err, va); 1314 length = svc_rdma_xdr_encode_error(xprt, rmsgp, err, va);
1080 1315
1081 /* Prepare SGE for local address */ 1316 /* Prepare SGE for local address */
1082 atomic_inc(&xprt->sc_dma_used);
1083 sge.addr = ib_dma_map_page(xprt->sc_cm_id->device, 1317 sge.addr = ib_dma_map_page(xprt->sc_cm_id->device,
1084 p, 0, PAGE_SIZE, DMA_FROM_DEVICE); 1318 p, 0, PAGE_SIZE, DMA_FROM_DEVICE);
1085 sge.lkey = xprt->sc_phys_mr->lkey; 1319 if (ib_dma_mapping_error(xprt->sc_cm_id->device, sge.addr)) {
1320 put_page(p);
1321 return;
1322 }
1323 atomic_inc(&xprt->sc_dma_used);
1324 sge.lkey = xprt->sc_dma_lkey;
1086 sge.length = length; 1325 sge.length = length;
1087 1326
1088 ctxt = svc_rdma_get_context(xprt); 1327 ctxt = svc_rdma_get_context(xprt);
@@ -1103,6 +1342,9 @@ void svc_rdma_send_error(struct svcxprt_rdma *xprt, struct rpcrdma_msg *rmsgp,
1103 if (ret) { 1342 if (ret) {
1104 dprintk("svcrdma: Error %d posting send for protocol error\n", 1343 dprintk("svcrdma: Error %d posting send for protocol error\n",
1105 ret); 1344 ret);
1345 ib_dma_unmap_page(xprt->sc_cm_id->device,
1346 sge.addr, PAGE_SIZE,
1347 DMA_FROM_DEVICE);
1106 svc_rdma_put_context(ctxt, 1); 1348 svc_rdma_put_context(ctxt, 1);
1107 } 1349 }
1108} 1350}
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c
index a564c1a39ec..9839c3d9414 100644
--- a/net/sunrpc/xprtrdma/transport.c
+++ b/net/sunrpc/xprtrdma/transport.c
@@ -70,11 +70,8 @@ static unsigned int xprt_rdma_slot_table_entries = RPCRDMA_DEF_SLOT_TABLE;
70static unsigned int xprt_rdma_max_inline_read = RPCRDMA_DEF_INLINE; 70static unsigned int xprt_rdma_max_inline_read = RPCRDMA_DEF_INLINE;
71static unsigned int xprt_rdma_max_inline_write = RPCRDMA_DEF_INLINE; 71static unsigned int xprt_rdma_max_inline_write = RPCRDMA_DEF_INLINE;
72static unsigned int xprt_rdma_inline_write_padding; 72static unsigned int xprt_rdma_inline_write_padding;
73#if !RPCRDMA_PERSISTENT_REGISTRATION 73static unsigned int xprt_rdma_memreg_strategy = RPCRDMA_FRMR;
74static unsigned int xprt_rdma_memreg_strategy = RPCRDMA_REGISTER; /* FMR? */ 74 int xprt_rdma_pad_optimize = 0;
75#else
76static unsigned int xprt_rdma_memreg_strategy = RPCRDMA_ALLPHYSICAL;
77#endif
78 75
79#ifdef RPC_DEBUG 76#ifdef RPC_DEBUG
80 77
@@ -140,6 +137,14 @@ static ctl_table xr_tunables_table[] = {
140 .extra2 = &max_memreg, 137 .extra2 = &max_memreg,
141 }, 138 },
142 { 139 {
140 .ctl_name = CTL_UNNUMBERED,
141 .procname = "rdma_pad_optimize",
142 .data = &xprt_rdma_pad_optimize,
143 .maxlen = sizeof(unsigned int),
144 .mode = 0644,
145 .proc_handler = &proc_dointvec,
146 },
147 {
143 .ctl_name = 0, 148 .ctl_name = 0,
144 }, 149 },
145}; 150};
@@ -458,6 +463,8 @@ xprt_rdma_close(struct rpc_xprt *xprt)
458 struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt); 463 struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
459 464
460 dprintk("RPC: %s: closing\n", __func__); 465 dprintk("RPC: %s: closing\n", __func__);
466 if (r_xprt->rx_ep.rep_connected > 0)
467 xprt->reestablish_timeout = 0;
461 xprt_disconnect_done(xprt); 468 xprt_disconnect_done(xprt);
462 (void) rpcrdma_ep_disconnect(&r_xprt->rx_ep, &r_xprt->rx_ia); 469 (void) rpcrdma_ep_disconnect(&r_xprt->rx_ep, &r_xprt->rx_ia);
463} 470}
@@ -485,6 +492,11 @@ xprt_rdma_connect(struct rpc_task *task)
485 /* Reconnect */ 492 /* Reconnect */
486 schedule_delayed_work(&r_xprt->rdma_connect, 493 schedule_delayed_work(&r_xprt->rdma_connect,
487 xprt->reestablish_timeout); 494 xprt->reestablish_timeout);
495 xprt->reestablish_timeout <<= 1;
496 if (xprt->reestablish_timeout > (30 * HZ))
497 xprt->reestablish_timeout = (30 * HZ);
498 else if (xprt->reestablish_timeout < (5 * HZ))
499 xprt->reestablish_timeout = (5 * HZ);
488 } else { 500 } else {
489 schedule_delayed_work(&r_xprt->rdma_connect, 0); 501 schedule_delayed_work(&r_xprt->rdma_connect, 0);
490 if (!RPC_IS_ASYNC(task)) 502 if (!RPC_IS_ASYNC(task))
@@ -591,6 +603,7 @@ xprt_rdma_allocate(struct rpc_task *task, size_t size)
591 } 603 }
592 dprintk("RPC: %s: size %zd, request 0x%p\n", __func__, size, req); 604 dprintk("RPC: %s: size %zd, request 0x%p\n", __func__, size, req);
593out: 605out:
606 req->rl_connect_cookie = 0; /* our reserved value */
594 return req->rl_xdr_buf; 607 return req->rl_xdr_buf;
595 608
596outfail: 609outfail:
@@ -694,13 +707,21 @@ xprt_rdma_send_request(struct rpc_task *task)
694 req->rl_reply->rr_xprt = xprt; 707 req->rl_reply->rr_xprt = xprt;
695 } 708 }
696 709
697 if (rpcrdma_ep_post(&r_xprt->rx_ia, &r_xprt->rx_ep, req)) { 710 /* Must suppress retransmit to maintain credits */
698 xprt_disconnect_done(xprt); 711 if (req->rl_connect_cookie == xprt->connect_cookie)
699 return -ENOTCONN; /* implies disconnect */ 712 goto drop_connection;
700 } 713 req->rl_connect_cookie = xprt->connect_cookie;
714
715 if (rpcrdma_ep_post(&r_xprt->rx_ia, &r_xprt->rx_ep, req))
716 goto drop_connection;
701 717
718 task->tk_bytes_sent += rqst->rq_snd_buf.len;
702 rqst->rq_bytes_sent = 0; 719 rqst->rq_bytes_sent = 0;
703 return 0; 720 return 0;
721
722drop_connection:
723 xprt_disconnect_done(xprt);
724 return -ENOTCONN; /* implies disconnect */
704} 725}
705 726
706static void xprt_rdma_print_stats(struct rpc_xprt *xprt, struct seq_file *seq) 727static void xprt_rdma_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
@@ -770,7 +791,7 @@ static void __exit xprt_rdma_cleanup(void)
770{ 791{
771 int rc; 792 int rc;
772 793
773 dprintk("RPCRDMA Module Removed, deregister RPC RDMA transport\n"); 794 dprintk(KERN_INFO "RPCRDMA Module Removed, deregister RPC RDMA transport\n");
774#ifdef RPC_DEBUG 795#ifdef RPC_DEBUG
775 if (sunrpc_table_header) { 796 if (sunrpc_table_header) {
776 unregister_sysctl_table(sunrpc_table_header); 797 unregister_sysctl_table(sunrpc_table_header);
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
index 8ea283ecc52..a5fef5e6c32 100644
--- a/net/sunrpc/xprtrdma/verbs.c
+++ b/net/sunrpc/xprtrdma/verbs.c
@@ -284,6 +284,7 @@ rpcrdma_conn_upcall(struct rdma_cm_id *id, struct rdma_cm_event *event)
284 switch (event->event) { 284 switch (event->event) {
285 case RDMA_CM_EVENT_ADDR_RESOLVED: 285 case RDMA_CM_EVENT_ADDR_RESOLVED:
286 case RDMA_CM_EVENT_ROUTE_RESOLVED: 286 case RDMA_CM_EVENT_ROUTE_RESOLVED:
287 ia->ri_async_rc = 0;
287 complete(&ia->ri_done); 288 complete(&ia->ri_done);
288 break; 289 break;
289 case RDMA_CM_EVENT_ADDR_ERROR: 290 case RDMA_CM_EVENT_ADDR_ERROR:
@@ -338,13 +339,32 @@ connected:
338 wake_up_all(&ep->rep_connect_wait); 339 wake_up_all(&ep->rep_connect_wait);
339 break; 340 break;
340 default: 341 default:
341 ia->ri_async_rc = -EINVAL; 342 dprintk("RPC: %s: unexpected CM event %d\n",
342 dprintk("RPC: %s: unexpected CM event %X\n",
343 __func__, event->event); 343 __func__, event->event);
344 complete(&ia->ri_done);
345 break; 344 break;
346 } 345 }
347 346
347#ifdef RPC_DEBUG
348 if (connstate == 1) {
349 int ird = attr.max_dest_rd_atomic;
350 int tird = ep->rep_remote_cma.responder_resources;
351 printk(KERN_INFO "rpcrdma: connection to %u.%u.%u.%u:%u "
352 "on %s, memreg %d slots %d ird %d%s\n",
353 NIPQUAD(addr->sin_addr.s_addr),
354 ntohs(addr->sin_port),
355 ia->ri_id->device->name,
356 ia->ri_memreg_strategy,
357 xprt->rx_buf.rb_max_requests,
358 ird, ird < 4 && ird < tird / 2 ? " (low!)" : "");
359 } else if (connstate < 0) {
360 printk(KERN_INFO "rpcrdma: connection to %u.%u.%u.%u:%u "
361 "closed (%d)\n",
362 NIPQUAD(addr->sin_addr.s_addr),
363 ntohs(addr->sin_port),
364 connstate);
365 }
366#endif
367
348 return 0; 368 return 0;
349} 369}
350 370
@@ -355,6 +375,8 @@ rpcrdma_create_id(struct rpcrdma_xprt *xprt,
355 struct rdma_cm_id *id; 375 struct rdma_cm_id *id;
356 int rc; 376 int rc;
357 377
378 init_completion(&ia->ri_done);
379
358 id = rdma_create_id(rpcrdma_conn_upcall, xprt, RDMA_PS_TCP); 380 id = rdma_create_id(rpcrdma_conn_upcall, xprt, RDMA_PS_TCP);
359 if (IS_ERR(id)) { 381 if (IS_ERR(id)) {
360 rc = PTR_ERR(id); 382 rc = PTR_ERR(id);
@@ -363,26 +385,28 @@ rpcrdma_create_id(struct rpcrdma_xprt *xprt,
363 return id; 385 return id;
364 } 386 }
365 387
366 ia->ri_async_rc = 0; 388 ia->ri_async_rc = -ETIMEDOUT;
367 rc = rdma_resolve_addr(id, NULL, addr, RDMA_RESOLVE_TIMEOUT); 389 rc = rdma_resolve_addr(id, NULL, addr, RDMA_RESOLVE_TIMEOUT);
368 if (rc) { 390 if (rc) {
369 dprintk("RPC: %s: rdma_resolve_addr() failed %i\n", 391 dprintk("RPC: %s: rdma_resolve_addr() failed %i\n",
370 __func__, rc); 392 __func__, rc);
371 goto out; 393 goto out;
372 } 394 }
373 wait_for_completion(&ia->ri_done); 395 wait_for_completion_interruptible_timeout(&ia->ri_done,
396 msecs_to_jiffies(RDMA_RESOLVE_TIMEOUT) + 1);
374 rc = ia->ri_async_rc; 397 rc = ia->ri_async_rc;
375 if (rc) 398 if (rc)
376 goto out; 399 goto out;
377 400
378 ia->ri_async_rc = 0; 401 ia->ri_async_rc = -ETIMEDOUT;
379 rc = rdma_resolve_route(id, RDMA_RESOLVE_TIMEOUT); 402 rc = rdma_resolve_route(id, RDMA_RESOLVE_TIMEOUT);
380 if (rc) { 403 if (rc) {
381 dprintk("RPC: %s: rdma_resolve_route() failed %i\n", 404 dprintk("RPC: %s: rdma_resolve_route() failed %i\n",
382 __func__, rc); 405 __func__, rc);
383 goto out; 406 goto out;
384 } 407 }
385 wait_for_completion(&ia->ri_done); 408 wait_for_completion_interruptible_timeout(&ia->ri_done,
409 msecs_to_jiffies(RDMA_RESOLVE_TIMEOUT) + 1);
386 rc = ia->ri_async_rc; 410 rc = ia->ri_async_rc;
387 if (rc) 411 if (rc)
388 goto out; 412 goto out;
@@ -423,11 +447,10 @@ rpcrdma_clean_cq(struct ib_cq *cq)
423int 447int
424rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg) 448rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
425{ 449{
426 int rc; 450 int rc, mem_priv;
451 struct ib_device_attr devattr;
427 struct rpcrdma_ia *ia = &xprt->rx_ia; 452 struct rpcrdma_ia *ia = &xprt->rx_ia;
428 453
429 init_completion(&ia->ri_done);
430
431 ia->ri_id = rpcrdma_create_id(xprt, ia, addr); 454 ia->ri_id = rpcrdma_create_id(xprt, ia, addr);
432 if (IS_ERR(ia->ri_id)) { 455 if (IS_ERR(ia->ri_id)) {
433 rc = PTR_ERR(ia->ri_id); 456 rc = PTR_ERR(ia->ri_id);
@@ -443,6 +466,73 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
443 } 466 }
444 467
445 /* 468 /*
469 * Query the device to determine if the requested memory
470 * registration strategy is supported. If it isn't, set the
471 * strategy to a globally supported model.
472 */
473 rc = ib_query_device(ia->ri_id->device, &devattr);
474 if (rc) {
475 dprintk("RPC: %s: ib_query_device failed %d\n",
476 __func__, rc);
477 goto out2;
478 }
479
480 if (devattr.device_cap_flags & IB_DEVICE_LOCAL_DMA_LKEY) {
481 ia->ri_have_dma_lkey = 1;
482 ia->ri_dma_lkey = ia->ri_id->device->local_dma_lkey;
483 }
484
485 switch (memreg) {
486 case RPCRDMA_MEMWINDOWS:
487 case RPCRDMA_MEMWINDOWS_ASYNC:
488 if (!(devattr.device_cap_flags & IB_DEVICE_MEM_WINDOW)) {
489 dprintk("RPC: %s: MEMWINDOWS registration "
490 "specified but not supported by adapter, "
491 "using slower RPCRDMA_REGISTER\n",
492 __func__);
493 memreg = RPCRDMA_REGISTER;
494 }
495 break;
496 case RPCRDMA_MTHCAFMR:
497 if (!ia->ri_id->device->alloc_fmr) {
498#if RPCRDMA_PERSISTENT_REGISTRATION
499 dprintk("RPC: %s: MTHCAFMR registration "
500 "specified but not supported by adapter, "
501 "using riskier RPCRDMA_ALLPHYSICAL\n",
502 __func__);
503 memreg = RPCRDMA_ALLPHYSICAL;
504#else
505 dprintk("RPC: %s: MTHCAFMR registration "
506 "specified but not supported by adapter, "
507 "using slower RPCRDMA_REGISTER\n",
508 __func__);
509 memreg = RPCRDMA_REGISTER;
510#endif
511 }
512 break;
513 case RPCRDMA_FRMR:
514 /* Requires both frmr reg and local dma lkey */
515 if ((devattr.device_cap_flags &
516 (IB_DEVICE_MEM_MGT_EXTENSIONS|IB_DEVICE_LOCAL_DMA_LKEY)) !=
517 (IB_DEVICE_MEM_MGT_EXTENSIONS|IB_DEVICE_LOCAL_DMA_LKEY)) {
518#if RPCRDMA_PERSISTENT_REGISTRATION
519 dprintk("RPC: %s: FRMR registration "
520 "specified but not supported by adapter, "
521 "using riskier RPCRDMA_ALLPHYSICAL\n",
522 __func__);
523 memreg = RPCRDMA_ALLPHYSICAL;
524#else
525 dprintk("RPC: %s: FRMR registration "
526 "specified but not supported by adapter, "
527 "using slower RPCRDMA_REGISTER\n",
528 __func__);
529 memreg = RPCRDMA_REGISTER;
530#endif
531 }
532 break;
533 }
534
535 /*
446 * Optionally obtain an underlying physical identity mapping in 536 * Optionally obtain an underlying physical identity mapping in
447 * order to do a memory window-based bind. This base registration 537 * order to do a memory window-based bind. This base registration
448 * is protected from remote access - that is enabled only by binding 538 * is protected from remote access - that is enabled only by binding
@@ -450,22 +540,28 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
450 * revoked after the corresponding completion similar to a storage 540 * revoked after the corresponding completion similar to a storage
451 * adapter. 541 * adapter.
452 */ 542 */
453 if (memreg > RPCRDMA_REGISTER) { 543 switch (memreg) {
454 int mem_priv = IB_ACCESS_LOCAL_WRITE; 544 case RPCRDMA_BOUNCEBUFFERS:
455 switch (memreg) { 545 case RPCRDMA_REGISTER:
546 case RPCRDMA_FRMR:
547 break;
456#if RPCRDMA_PERSISTENT_REGISTRATION 548#if RPCRDMA_PERSISTENT_REGISTRATION
457 case RPCRDMA_ALLPHYSICAL: 549 case RPCRDMA_ALLPHYSICAL:
458 mem_priv |= IB_ACCESS_REMOTE_WRITE; 550 mem_priv = IB_ACCESS_LOCAL_WRITE |
459 mem_priv |= IB_ACCESS_REMOTE_READ; 551 IB_ACCESS_REMOTE_WRITE |
460 break; 552 IB_ACCESS_REMOTE_READ;
553 goto register_setup;
461#endif 554#endif
462 case RPCRDMA_MEMWINDOWS_ASYNC: 555 case RPCRDMA_MEMWINDOWS_ASYNC:
463 case RPCRDMA_MEMWINDOWS: 556 case RPCRDMA_MEMWINDOWS:
464 mem_priv |= IB_ACCESS_MW_BIND; 557 mem_priv = IB_ACCESS_LOCAL_WRITE |
465 break; 558 IB_ACCESS_MW_BIND;
466 default: 559 goto register_setup;
560 case RPCRDMA_MTHCAFMR:
561 if (ia->ri_have_dma_lkey)
467 break; 562 break;
468 } 563 mem_priv = IB_ACCESS_LOCAL_WRITE;
564 register_setup:
469 ia->ri_bind_mem = ib_get_dma_mr(ia->ri_pd, mem_priv); 565 ia->ri_bind_mem = ib_get_dma_mr(ia->ri_pd, mem_priv);
470 if (IS_ERR(ia->ri_bind_mem)) { 566 if (IS_ERR(ia->ri_bind_mem)) {
471 printk(KERN_ALERT "%s: ib_get_dma_mr for " 567 printk(KERN_ALERT "%s: ib_get_dma_mr for "
@@ -475,7 +571,15 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
475 memreg = RPCRDMA_REGISTER; 571 memreg = RPCRDMA_REGISTER;
476 ia->ri_bind_mem = NULL; 572 ia->ri_bind_mem = NULL;
477 } 573 }
574 break;
575 default:
576 printk(KERN_ERR "%s: invalid memory registration mode %d\n",
577 __func__, memreg);
578 rc = -EINVAL;
579 goto out2;
478 } 580 }
581 dprintk("RPC: %s: memory registration strategy is %d\n",
582 __func__, memreg);
479 583
480 /* Else will do memory reg/dereg for each chunk */ 584 /* Else will do memory reg/dereg for each chunk */
481 ia->ri_memreg_strategy = memreg; 585 ia->ri_memreg_strategy = memreg;
@@ -483,6 +587,7 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
483 return 0; 587 return 0;
484out2: 588out2:
485 rdma_destroy_id(ia->ri_id); 589 rdma_destroy_id(ia->ri_id);
590 ia->ri_id = NULL;
486out1: 591out1:
487 return rc; 592 return rc;
488} 593}
@@ -503,15 +608,17 @@ rpcrdma_ia_close(struct rpcrdma_ia *ia)
503 dprintk("RPC: %s: ib_dereg_mr returned %i\n", 608 dprintk("RPC: %s: ib_dereg_mr returned %i\n",
504 __func__, rc); 609 __func__, rc);
505 } 610 }
506 if (ia->ri_id != NULL && !IS_ERR(ia->ri_id) && ia->ri_id->qp) 611 if (ia->ri_id != NULL && !IS_ERR(ia->ri_id)) {
507 rdma_destroy_qp(ia->ri_id); 612 if (ia->ri_id->qp)
613 rdma_destroy_qp(ia->ri_id);
614 rdma_destroy_id(ia->ri_id);
615 ia->ri_id = NULL;
616 }
508 if (ia->ri_pd != NULL && !IS_ERR(ia->ri_pd)) { 617 if (ia->ri_pd != NULL && !IS_ERR(ia->ri_pd)) {
509 rc = ib_dealloc_pd(ia->ri_pd); 618 rc = ib_dealloc_pd(ia->ri_pd);
510 dprintk("RPC: %s: ib_dealloc_pd returned %i\n", 619 dprintk("RPC: %s: ib_dealloc_pd returned %i\n",
511 __func__, rc); 620 __func__, rc);
512 } 621 }
513 if (ia->ri_id != NULL && !IS_ERR(ia->ri_id))
514 rdma_destroy_id(ia->ri_id);
515} 622}
516 623
517/* 624/*
@@ -541,6 +648,12 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
541 ep->rep_attr.srq = NULL; 648 ep->rep_attr.srq = NULL;
542 ep->rep_attr.cap.max_send_wr = cdata->max_requests; 649 ep->rep_attr.cap.max_send_wr = cdata->max_requests;
543 switch (ia->ri_memreg_strategy) { 650 switch (ia->ri_memreg_strategy) {
651 case RPCRDMA_FRMR:
652 /* Add room for frmr register and invalidate WRs */
653 ep->rep_attr.cap.max_send_wr *= 3;
654 if (ep->rep_attr.cap.max_send_wr > devattr.max_qp_wr)
655 return -EINVAL;
656 break;
544 case RPCRDMA_MEMWINDOWS_ASYNC: 657 case RPCRDMA_MEMWINDOWS_ASYNC:
545 case RPCRDMA_MEMWINDOWS: 658 case RPCRDMA_MEMWINDOWS:
546 /* Add room for mw_binds+unbinds - overkill! */ 659 /* Add room for mw_binds+unbinds - overkill! */
@@ -617,29 +730,13 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
617 ep->rep_remote_cma.private_data_len = 0; 730 ep->rep_remote_cma.private_data_len = 0;
618 731
619 /* Client offers RDMA Read but does not initiate */ 732 /* Client offers RDMA Read but does not initiate */
620 switch (ia->ri_memreg_strategy) { 733 ep->rep_remote_cma.initiator_depth = 0;
621 case RPCRDMA_BOUNCEBUFFERS: 734 if (ia->ri_memreg_strategy == RPCRDMA_BOUNCEBUFFERS)
622 ep->rep_remote_cma.responder_resources = 0; 735 ep->rep_remote_cma.responder_resources = 0;
623 break; 736 else if (devattr.max_qp_rd_atom > 32) /* arbitrary but <= 255 */
624 case RPCRDMA_MTHCAFMR: 737 ep->rep_remote_cma.responder_resources = 32;
625 case RPCRDMA_REGISTER: 738 else
626 ep->rep_remote_cma.responder_resources = cdata->max_requests *
627 (RPCRDMA_MAX_DATA_SEGS / 8);
628 break;
629 case RPCRDMA_MEMWINDOWS:
630 case RPCRDMA_MEMWINDOWS_ASYNC:
631#if RPCRDMA_PERSISTENT_REGISTRATION
632 case RPCRDMA_ALLPHYSICAL:
633#endif
634 ep->rep_remote_cma.responder_resources = cdata->max_requests *
635 (RPCRDMA_MAX_DATA_SEGS / 2);
636 break;
637 default:
638 break;
639 }
640 if (ep->rep_remote_cma.responder_resources > devattr.max_qp_rd_atom)
641 ep->rep_remote_cma.responder_resources = devattr.max_qp_rd_atom; 739 ep->rep_remote_cma.responder_resources = devattr.max_qp_rd_atom;
642 ep->rep_remote_cma.initiator_depth = 0;
643 740
644 ep->rep_remote_cma.retry_count = 7; 741 ep->rep_remote_cma.retry_count = 7;
645 ep->rep_remote_cma.flow_control = 0; 742 ep->rep_remote_cma.flow_control = 0;
@@ -679,21 +776,16 @@ rpcrdma_ep_destroy(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
679 if (rc) 776 if (rc)
680 dprintk("RPC: %s: rpcrdma_ep_disconnect" 777 dprintk("RPC: %s: rpcrdma_ep_disconnect"
681 " returned %i\n", __func__, rc); 778 " returned %i\n", __func__, rc);
779 rdma_destroy_qp(ia->ri_id);
780 ia->ri_id->qp = NULL;
682 } 781 }
683 782
684 ep->rep_func = NULL;
685
686 /* padding - could be done in rpcrdma_buffer_destroy... */ 783 /* padding - could be done in rpcrdma_buffer_destroy... */
687 if (ep->rep_pad_mr) { 784 if (ep->rep_pad_mr) {
688 rpcrdma_deregister_internal(ia, ep->rep_pad_mr, &ep->rep_pad); 785 rpcrdma_deregister_internal(ia, ep->rep_pad_mr, &ep->rep_pad);
689 ep->rep_pad_mr = NULL; 786 ep->rep_pad_mr = NULL;
690 } 787 }
691 788
692 if (ia->ri_id->qp) {
693 rdma_destroy_qp(ia->ri_id);
694 ia->ri_id->qp = NULL;
695 }
696
697 rpcrdma_clean_cq(ep->rep_cq); 789 rpcrdma_clean_cq(ep->rep_cq);
698 rc = ib_destroy_cq(ep->rep_cq); 790 rc = ib_destroy_cq(ep->rep_cq);
699 if (rc) 791 if (rc)
@@ -712,9 +804,8 @@ rpcrdma_ep_connect(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
712 struct rdma_cm_id *id; 804 struct rdma_cm_id *id;
713 int rc = 0; 805 int rc = 0;
714 int retry_count = 0; 806 int retry_count = 0;
715 int reconnect = (ep->rep_connected != 0);
716 807
717 if (reconnect) { 808 if (ep->rep_connected != 0) {
718 struct rpcrdma_xprt *xprt; 809 struct rpcrdma_xprt *xprt;
719retry: 810retry:
720 rc = rpcrdma_ep_disconnect(ep, ia); 811 rc = rpcrdma_ep_disconnect(ep, ia);
@@ -745,6 +836,7 @@ retry:
745 goto out; 836 goto out;
746 } 837 }
747 /* END TEMP */ 838 /* END TEMP */
839 rdma_destroy_qp(ia->ri_id);
748 rdma_destroy_id(ia->ri_id); 840 rdma_destroy_id(ia->ri_id);
749 ia->ri_id = id; 841 ia->ri_id = id;
750 } 842 }
@@ -769,14 +861,6 @@ if (strnicmp(ia->ri_id->device->dma_device->bus->name, "pci", 3) == 0) {
769 } 861 }
770} 862}
771 863
772 /* Theoretically a client initiator_depth > 0 is not needed,
773 * but many peers fail to complete the connection unless they
774 * == responder_resources! */
775 if (ep->rep_remote_cma.initiator_depth !=
776 ep->rep_remote_cma.responder_resources)
777 ep->rep_remote_cma.initiator_depth =
778 ep->rep_remote_cma.responder_resources;
779
780 ep->rep_connected = 0; 864 ep->rep_connected = 0;
781 865
782 rc = rdma_connect(ia->ri_id, &ep->rep_remote_cma); 866 rc = rdma_connect(ia->ri_id, &ep->rep_remote_cma);
@@ -786,9 +870,6 @@ if (strnicmp(ia->ri_id->device->dma_device->bus->name, "pci", 3) == 0) {
786 goto out; 870 goto out;
787 } 871 }
788 872
789 if (reconnect)
790 return 0;
791
792 wait_event_interruptible(ep->rep_connect_wait, ep->rep_connected != 0); 873 wait_event_interruptible(ep->rep_connect_wait, ep->rep_connected != 0);
793 874
794 /* 875 /*
@@ -805,14 +886,16 @@ if (strnicmp(ia->ri_id->device->dma_device->bus->name, "pci", 3) == 0) {
805 if (ep->rep_connected <= 0) { 886 if (ep->rep_connected <= 0) {
806 /* Sometimes, the only way to reliably connect to remote 887 /* Sometimes, the only way to reliably connect to remote
807 * CMs is to use same nonzero values for ORD and IRD. */ 888 * CMs is to use same nonzero values for ORD and IRD. */
808 ep->rep_remote_cma.initiator_depth = 889 if (retry_count++ <= RDMA_CONNECT_RETRY_MAX + 1 &&
809 ep->rep_remote_cma.responder_resources; 890 (ep->rep_remote_cma.responder_resources == 0 ||
810 if (ep->rep_remote_cma.initiator_depth == 0) 891 ep->rep_remote_cma.initiator_depth !=
811 ++ep->rep_remote_cma.initiator_depth; 892 ep->rep_remote_cma.responder_resources)) {
812 if (ep->rep_remote_cma.responder_resources == 0) 893 if (ep->rep_remote_cma.responder_resources == 0)
813 ++ep->rep_remote_cma.responder_resources; 894 ep->rep_remote_cma.responder_resources = 1;
814 if (retry_count++ == 0) 895 ep->rep_remote_cma.initiator_depth =
896 ep->rep_remote_cma.responder_resources;
815 goto retry; 897 goto retry;
898 }
816 rc = ep->rep_connected; 899 rc = ep->rep_connected;
817 } else { 900 } else {
818 dprintk("RPC: %s: connected\n", __func__); 901 dprintk("RPC: %s: connected\n", __func__);
@@ -863,6 +946,7 @@ rpcrdma_buffer_create(struct rpcrdma_buffer *buf, struct rpcrdma_ep *ep,
863 char *p; 946 char *p;
864 size_t len; 947 size_t len;
865 int i, rc; 948 int i, rc;
949 struct rpcrdma_mw *r;
866 950
867 buf->rb_max_requests = cdata->max_requests; 951 buf->rb_max_requests = cdata->max_requests;
868 spin_lock_init(&buf->rb_lock); 952 spin_lock_init(&buf->rb_lock);
@@ -873,7 +957,7 @@ rpcrdma_buffer_create(struct rpcrdma_buffer *buf, struct rpcrdma_ep *ep,
873 * 2. arrays of struct rpcrdma_req to fill in pointers 957 * 2. arrays of struct rpcrdma_req to fill in pointers
874 * 3. array of struct rpcrdma_rep for replies 958 * 3. array of struct rpcrdma_rep for replies
875 * 4. padding, if any 959 * 4. padding, if any
876 * 5. mw's, if any 960 * 5. mw's, fmr's or frmr's, if any
877 * Send/recv buffers in req/rep need to be registered 961 * Send/recv buffers in req/rep need to be registered
878 */ 962 */
879 963
@@ -881,6 +965,10 @@ rpcrdma_buffer_create(struct rpcrdma_buffer *buf, struct rpcrdma_ep *ep,
881 (sizeof(struct rpcrdma_req *) + sizeof(struct rpcrdma_rep *)); 965 (sizeof(struct rpcrdma_req *) + sizeof(struct rpcrdma_rep *));
882 len += cdata->padding; 966 len += cdata->padding;
883 switch (ia->ri_memreg_strategy) { 967 switch (ia->ri_memreg_strategy) {
968 case RPCRDMA_FRMR:
969 len += buf->rb_max_requests * RPCRDMA_MAX_SEGS *
970 sizeof(struct rpcrdma_mw);
971 break;
884 case RPCRDMA_MTHCAFMR: 972 case RPCRDMA_MTHCAFMR:
885 /* TBD we are perhaps overallocating here */ 973 /* TBD we are perhaps overallocating here */
886 len += (buf->rb_max_requests + 1) * RPCRDMA_MAX_SEGS * 974 len += (buf->rb_max_requests + 1) * RPCRDMA_MAX_SEGS *
@@ -927,15 +1015,37 @@ rpcrdma_buffer_create(struct rpcrdma_buffer *buf, struct rpcrdma_ep *ep,
927 * and also reduce unbind-to-bind collision. 1015 * and also reduce unbind-to-bind collision.
928 */ 1016 */
929 INIT_LIST_HEAD(&buf->rb_mws); 1017 INIT_LIST_HEAD(&buf->rb_mws);
1018 r = (struct rpcrdma_mw *)p;
930 switch (ia->ri_memreg_strategy) { 1019 switch (ia->ri_memreg_strategy) {
1020 case RPCRDMA_FRMR:
1021 for (i = buf->rb_max_requests * RPCRDMA_MAX_SEGS; i; i--) {
1022 r->r.frmr.fr_mr = ib_alloc_fast_reg_mr(ia->ri_pd,
1023 RPCRDMA_MAX_SEGS);
1024 if (IS_ERR(r->r.frmr.fr_mr)) {
1025 rc = PTR_ERR(r->r.frmr.fr_mr);
1026 dprintk("RPC: %s: ib_alloc_fast_reg_mr"
1027 " failed %i\n", __func__, rc);
1028 goto out;
1029 }
1030 r->r.frmr.fr_pgl =
1031 ib_alloc_fast_reg_page_list(ia->ri_id->device,
1032 RPCRDMA_MAX_SEGS);
1033 if (IS_ERR(r->r.frmr.fr_pgl)) {
1034 rc = PTR_ERR(r->r.frmr.fr_pgl);
1035 dprintk("RPC: %s: "
1036 "ib_alloc_fast_reg_page_list "
1037 "failed %i\n", __func__, rc);
1038 goto out;
1039 }
1040 list_add(&r->mw_list, &buf->rb_mws);
1041 ++r;
1042 }
1043 break;
931 case RPCRDMA_MTHCAFMR: 1044 case RPCRDMA_MTHCAFMR:
932 {
933 struct rpcrdma_mw *r = (struct rpcrdma_mw *)p;
934 struct ib_fmr_attr fa = {
935 RPCRDMA_MAX_DATA_SEGS, 1, PAGE_SHIFT
936 };
937 /* TBD we are perhaps overallocating here */ 1045 /* TBD we are perhaps overallocating here */
938 for (i = (buf->rb_max_requests+1) * RPCRDMA_MAX_SEGS; i; i--) { 1046 for (i = (buf->rb_max_requests+1) * RPCRDMA_MAX_SEGS; i; i--) {
1047 static struct ib_fmr_attr fa =
1048 { RPCRDMA_MAX_DATA_SEGS, 1, PAGE_SHIFT };
939 r->r.fmr = ib_alloc_fmr(ia->ri_pd, 1049 r->r.fmr = ib_alloc_fmr(ia->ri_pd,
940 IB_ACCESS_REMOTE_WRITE | IB_ACCESS_REMOTE_READ, 1050 IB_ACCESS_REMOTE_WRITE | IB_ACCESS_REMOTE_READ,
941 &fa); 1051 &fa);
@@ -948,12 +1058,9 @@ rpcrdma_buffer_create(struct rpcrdma_buffer *buf, struct rpcrdma_ep *ep,
948 list_add(&r->mw_list, &buf->rb_mws); 1058 list_add(&r->mw_list, &buf->rb_mws);
949 ++r; 1059 ++r;
950 } 1060 }
951 }
952 break; 1061 break;
953 case RPCRDMA_MEMWINDOWS_ASYNC: 1062 case RPCRDMA_MEMWINDOWS_ASYNC:
954 case RPCRDMA_MEMWINDOWS: 1063 case RPCRDMA_MEMWINDOWS:
955 {
956 struct rpcrdma_mw *r = (struct rpcrdma_mw *)p;
957 /* Allocate one extra request's worth, for full cycling */ 1064 /* Allocate one extra request's worth, for full cycling */
958 for (i = (buf->rb_max_requests+1) * RPCRDMA_MAX_SEGS; i; i--) { 1065 for (i = (buf->rb_max_requests+1) * RPCRDMA_MAX_SEGS; i; i--) {
959 r->r.mw = ib_alloc_mw(ia->ri_pd); 1066 r->r.mw = ib_alloc_mw(ia->ri_pd);
@@ -966,7 +1073,6 @@ rpcrdma_buffer_create(struct rpcrdma_buffer *buf, struct rpcrdma_ep *ep,
966 list_add(&r->mw_list, &buf->rb_mws); 1073 list_add(&r->mw_list, &buf->rb_mws);
967 ++r; 1074 ++r;
968 } 1075 }
969 }
970 break; 1076 break;
971 default: 1077 default:
972 break; 1078 break;
@@ -1046,6 +1152,7 @@ rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf)
1046{ 1152{
1047 int rc, i; 1153 int rc, i;
1048 struct rpcrdma_ia *ia = rdmab_to_ia(buf); 1154 struct rpcrdma_ia *ia = rdmab_to_ia(buf);
1155 struct rpcrdma_mw *r;
1049 1156
1050 /* clean up in reverse order from create 1157 /* clean up in reverse order from create
1051 * 1. recv mr memory (mr free, then kfree) 1158 * 1. recv mr memory (mr free, then kfree)
@@ -1065,11 +1172,19 @@ rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf)
1065 } 1172 }
1066 if (buf->rb_send_bufs && buf->rb_send_bufs[i]) { 1173 if (buf->rb_send_bufs && buf->rb_send_bufs[i]) {
1067 while (!list_empty(&buf->rb_mws)) { 1174 while (!list_empty(&buf->rb_mws)) {
1068 struct rpcrdma_mw *r;
1069 r = list_entry(buf->rb_mws.next, 1175 r = list_entry(buf->rb_mws.next,
1070 struct rpcrdma_mw, mw_list); 1176 struct rpcrdma_mw, mw_list);
1071 list_del(&r->mw_list); 1177 list_del(&r->mw_list);
1072 switch (ia->ri_memreg_strategy) { 1178 switch (ia->ri_memreg_strategy) {
1179 case RPCRDMA_FRMR:
1180 rc = ib_dereg_mr(r->r.frmr.fr_mr);
1181 if (rc)
1182 dprintk("RPC: %s:"
1183 " ib_dereg_mr"
1184 " failed %i\n",
1185 __func__, rc);
1186 ib_free_fast_reg_page_list(r->r.frmr.fr_pgl);
1187 break;
1073 case RPCRDMA_MTHCAFMR: 1188 case RPCRDMA_MTHCAFMR:
1074 rc = ib_dealloc_fmr(r->r.fmr); 1189 rc = ib_dealloc_fmr(r->r.fmr);
1075 if (rc) 1190 if (rc)
@@ -1115,6 +1230,8 @@ rpcrdma_buffer_get(struct rpcrdma_buffer *buffers)
1115{ 1230{
1116 struct rpcrdma_req *req; 1231 struct rpcrdma_req *req;
1117 unsigned long flags; 1232 unsigned long flags;
1233 int i;
1234 struct rpcrdma_mw *r;
1118 1235
1119 spin_lock_irqsave(&buffers->rb_lock, flags); 1236 spin_lock_irqsave(&buffers->rb_lock, flags);
1120 if (buffers->rb_send_index == buffers->rb_max_requests) { 1237 if (buffers->rb_send_index == buffers->rb_max_requests) {
@@ -1135,9 +1252,8 @@ rpcrdma_buffer_get(struct rpcrdma_buffer *buffers)
1135 } 1252 }
1136 buffers->rb_send_bufs[buffers->rb_send_index++] = NULL; 1253 buffers->rb_send_bufs[buffers->rb_send_index++] = NULL;
1137 if (!list_empty(&buffers->rb_mws)) { 1254 if (!list_empty(&buffers->rb_mws)) {
1138 int i = RPCRDMA_MAX_SEGS - 1; 1255 i = RPCRDMA_MAX_SEGS - 1;
1139 do { 1256 do {
1140 struct rpcrdma_mw *r;
1141 r = list_entry(buffers->rb_mws.next, 1257 r = list_entry(buffers->rb_mws.next,
1142 struct rpcrdma_mw, mw_list); 1258 struct rpcrdma_mw, mw_list);
1143 list_del(&r->mw_list); 1259 list_del(&r->mw_list);
@@ -1171,6 +1287,7 @@ rpcrdma_buffer_put(struct rpcrdma_req *req)
1171 req->rl_reply = NULL; 1287 req->rl_reply = NULL;
1172 } 1288 }
1173 switch (ia->ri_memreg_strategy) { 1289 switch (ia->ri_memreg_strategy) {
1290 case RPCRDMA_FRMR:
1174 case RPCRDMA_MTHCAFMR: 1291 case RPCRDMA_MTHCAFMR:
1175 case RPCRDMA_MEMWINDOWS_ASYNC: 1292 case RPCRDMA_MEMWINDOWS_ASYNC:
1176 case RPCRDMA_MEMWINDOWS: 1293 case RPCRDMA_MEMWINDOWS:
@@ -1252,7 +1369,11 @@ rpcrdma_register_internal(struct rpcrdma_ia *ia, void *va, int len,
1252 va, len, DMA_BIDIRECTIONAL); 1369 va, len, DMA_BIDIRECTIONAL);
1253 iov->length = len; 1370 iov->length = len;
1254 1371
1255 if (ia->ri_bind_mem != NULL) { 1372 if (ia->ri_have_dma_lkey) {
1373 *mrp = NULL;
1374 iov->lkey = ia->ri_dma_lkey;
1375 return 0;
1376 } else if (ia->ri_bind_mem != NULL) {
1256 *mrp = NULL; 1377 *mrp = NULL;
1257 iov->lkey = ia->ri_bind_mem->lkey; 1378 iov->lkey = ia->ri_bind_mem->lkey;
1258 return 0; 1379 return 0;
@@ -1329,15 +1450,292 @@ rpcrdma_unmap_one(struct rpcrdma_ia *ia, struct rpcrdma_mr_seg *seg)
1329 seg->mr_dma, seg->mr_dmalen, seg->mr_dir); 1450 seg->mr_dma, seg->mr_dmalen, seg->mr_dir);
1330} 1451}
1331 1452
1453static int
1454rpcrdma_register_frmr_external(struct rpcrdma_mr_seg *seg,
1455 int *nsegs, int writing, struct rpcrdma_ia *ia,
1456 struct rpcrdma_xprt *r_xprt)
1457{
1458 struct rpcrdma_mr_seg *seg1 = seg;
1459 struct ib_send_wr frmr_wr, *bad_wr;
1460 u8 key;
1461 int len, pageoff;
1462 int i, rc;
1463
1464 pageoff = offset_in_page(seg1->mr_offset);
1465 seg1->mr_offset -= pageoff; /* start of page */
1466 seg1->mr_len += pageoff;
1467 len = -pageoff;
1468 if (*nsegs > RPCRDMA_MAX_DATA_SEGS)
1469 *nsegs = RPCRDMA_MAX_DATA_SEGS;
1470 for (i = 0; i < *nsegs;) {
1471 rpcrdma_map_one(ia, seg, writing);
1472 seg1->mr_chunk.rl_mw->r.frmr.fr_pgl->page_list[i] = seg->mr_dma;
1473 len += seg->mr_len;
1474 ++seg;
1475 ++i;
1476 /* Check for holes */
1477 if ((i < *nsegs && offset_in_page(seg->mr_offset)) ||
1478 offset_in_page((seg-1)->mr_offset + (seg-1)->mr_len))
1479 break;
1480 }
1481 dprintk("RPC: %s: Using frmr %p to map %d segments\n",
1482 __func__, seg1->mr_chunk.rl_mw, i);
1483
1484 /* Bump the key */
1485 key = (u8)(seg1->mr_chunk.rl_mw->r.frmr.fr_mr->rkey & 0x000000FF);
1486 ib_update_fast_reg_key(seg1->mr_chunk.rl_mw->r.frmr.fr_mr, ++key);
1487
1488 /* Prepare FRMR WR */
1489 memset(&frmr_wr, 0, sizeof frmr_wr);
1490 frmr_wr.opcode = IB_WR_FAST_REG_MR;
1491 frmr_wr.send_flags = 0; /* unsignaled */
1492 frmr_wr.wr.fast_reg.iova_start = (unsigned long)seg1->mr_dma;
1493 frmr_wr.wr.fast_reg.page_list = seg1->mr_chunk.rl_mw->r.frmr.fr_pgl;
1494 frmr_wr.wr.fast_reg.page_list_len = i;
1495 frmr_wr.wr.fast_reg.page_shift = PAGE_SHIFT;
1496 frmr_wr.wr.fast_reg.length = i << PAGE_SHIFT;
1497 frmr_wr.wr.fast_reg.access_flags = (writing ?
1498 IB_ACCESS_REMOTE_WRITE : IB_ACCESS_REMOTE_READ);
1499 frmr_wr.wr.fast_reg.rkey = seg1->mr_chunk.rl_mw->r.frmr.fr_mr->rkey;
1500 DECR_CQCOUNT(&r_xprt->rx_ep);
1501
1502 rc = ib_post_send(ia->ri_id->qp, &frmr_wr, &bad_wr);
1503
1504 if (rc) {
1505 dprintk("RPC: %s: failed ib_post_send for register,"
1506 " status %i\n", __func__, rc);
1507 while (i--)
1508 rpcrdma_unmap_one(ia, --seg);
1509 } else {
1510 seg1->mr_rkey = seg1->mr_chunk.rl_mw->r.frmr.fr_mr->rkey;
1511 seg1->mr_base = seg1->mr_dma + pageoff;
1512 seg1->mr_nsegs = i;
1513 seg1->mr_len = len;
1514 }
1515 *nsegs = i;
1516 return rc;
1517}
1518
1519static int
1520rpcrdma_deregister_frmr_external(struct rpcrdma_mr_seg *seg,
1521 struct rpcrdma_ia *ia, struct rpcrdma_xprt *r_xprt)
1522{
1523 struct rpcrdma_mr_seg *seg1 = seg;
1524 struct ib_send_wr invalidate_wr, *bad_wr;
1525 int rc;
1526
1527 while (seg1->mr_nsegs--)
1528 rpcrdma_unmap_one(ia, seg++);
1529
1530 memset(&invalidate_wr, 0, sizeof invalidate_wr);
1531 invalidate_wr.opcode = IB_WR_LOCAL_INV;
1532 invalidate_wr.send_flags = 0; /* unsignaled */
1533 invalidate_wr.ex.invalidate_rkey = seg1->mr_chunk.rl_mw->r.frmr.fr_mr->rkey;
1534 DECR_CQCOUNT(&r_xprt->rx_ep);
1535
1536 rc = ib_post_send(ia->ri_id->qp, &invalidate_wr, &bad_wr);
1537 if (rc)
1538 dprintk("RPC: %s: failed ib_post_send for invalidate,"
1539 " status %i\n", __func__, rc);
1540 return rc;
1541}
1542
1543static int
1544rpcrdma_register_fmr_external(struct rpcrdma_mr_seg *seg,
1545 int *nsegs, int writing, struct rpcrdma_ia *ia)
1546{
1547 struct rpcrdma_mr_seg *seg1 = seg;
1548 u64 physaddrs[RPCRDMA_MAX_DATA_SEGS];
1549 int len, pageoff, i, rc;
1550
1551 pageoff = offset_in_page(seg1->mr_offset);
1552 seg1->mr_offset -= pageoff; /* start of page */
1553 seg1->mr_len += pageoff;
1554 len = -pageoff;
1555 if (*nsegs > RPCRDMA_MAX_DATA_SEGS)
1556 *nsegs = RPCRDMA_MAX_DATA_SEGS;
1557 for (i = 0; i < *nsegs;) {
1558 rpcrdma_map_one(ia, seg, writing);
1559 physaddrs[i] = seg->mr_dma;
1560 len += seg->mr_len;
1561 ++seg;
1562 ++i;
1563 /* Check for holes */
1564 if ((i < *nsegs && offset_in_page(seg->mr_offset)) ||
1565 offset_in_page((seg-1)->mr_offset + (seg-1)->mr_len))
1566 break;
1567 }
1568 rc = ib_map_phys_fmr(seg1->mr_chunk.rl_mw->r.fmr,
1569 physaddrs, i, seg1->mr_dma);
1570 if (rc) {
1571 dprintk("RPC: %s: failed ib_map_phys_fmr "
1572 "%u@0x%llx+%i (%d)... status %i\n", __func__,
1573 len, (unsigned long long)seg1->mr_dma,
1574 pageoff, i, rc);
1575 while (i--)
1576 rpcrdma_unmap_one(ia, --seg);
1577 } else {
1578 seg1->mr_rkey = seg1->mr_chunk.rl_mw->r.fmr->rkey;
1579 seg1->mr_base = seg1->mr_dma + pageoff;
1580 seg1->mr_nsegs = i;
1581 seg1->mr_len = len;
1582 }
1583 *nsegs = i;
1584 return rc;
1585}
1586
1587static int
1588rpcrdma_deregister_fmr_external(struct rpcrdma_mr_seg *seg,
1589 struct rpcrdma_ia *ia)
1590{
1591 struct rpcrdma_mr_seg *seg1 = seg;
1592 LIST_HEAD(l);
1593 int rc;
1594
1595 list_add(&seg1->mr_chunk.rl_mw->r.fmr->list, &l);
1596 rc = ib_unmap_fmr(&l);
1597 while (seg1->mr_nsegs--)
1598 rpcrdma_unmap_one(ia, seg++);
1599 if (rc)
1600 dprintk("RPC: %s: failed ib_unmap_fmr,"
1601 " status %i\n", __func__, rc);
1602 return rc;
1603}
1604
1605static int
1606rpcrdma_register_memwin_external(struct rpcrdma_mr_seg *seg,
1607 int *nsegs, int writing, struct rpcrdma_ia *ia,
1608 struct rpcrdma_xprt *r_xprt)
1609{
1610 int mem_priv = (writing ? IB_ACCESS_REMOTE_WRITE :
1611 IB_ACCESS_REMOTE_READ);
1612 struct ib_mw_bind param;
1613 int rc;
1614
1615 *nsegs = 1;
1616 rpcrdma_map_one(ia, seg, writing);
1617 param.mr = ia->ri_bind_mem;
1618 param.wr_id = 0ULL; /* no send cookie */
1619 param.addr = seg->mr_dma;
1620 param.length = seg->mr_len;
1621 param.send_flags = 0;
1622 param.mw_access_flags = mem_priv;
1623
1624 DECR_CQCOUNT(&r_xprt->rx_ep);
1625 rc = ib_bind_mw(ia->ri_id->qp, seg->mr_chunk.rl_mw->r.mw, &param);
1626 if (rc) {
1627 dprintk("RPC: %s: failed ib_bind_mw "
1628 "%u@0x%llx status %i\n",
1629 __func__, seg->mr_len,
1630 (unsigned long long)seg->mr_dma, rc);
1631 rpcrdma_unmap_one(ia, seg);
1632 } else {
1633 seg->mr_rkey = seg->mr_chunk.rl_mw->r.mw->rkey;
1634 seg->mr_base = param.addr;
1635 seg->mr_nsegs = 1;
1636 }
1637 return rc;
1638}
1639
1640static int
1641rpcrdma_deregister_memwin_external(struct rpcrdma_mr_seg *seg,
1642 struct rpcrdma_ia *ia,
1643 struct rpcrdma_xprt *r_xprt, void **r)
1644{
1645 struct ib_mw_bind param;
1646 LIST_HEAD(l);
1647 int rc;
1648
1649 BUG_ON(seg->mr_nsegs != 1);
1650 param.mr = ia->ri_bind_mem;
1651 param.addr = 0ULL; /* unbind */
1652 param.length = 0;
1653 param.mw_access_flags = 0;
1654 if (*r) {
1655 param.wr_id = (u64) (unsigned long) *r;
1656 param.send_flags = IB_SEND_SIGNALED;
1657 INIT_CQCOUNT(&r_xprt->rx_ep);
1658 } else {
1659 param.wr_id = 0ULL;
1660 param.send_flags = 0;
1661 DECR_CQCOUNT(&r_xprt->rx_ep);
1662 }
1663 rc = ib_bind_mw(ia->ri_id->qp, seg->mr_chunk.rl_mw->r.mw, &param);
1664 rpcrdma_unmap_one(ia, seg);
1665 if (rc)
1666 dprintk("RPC: %s: failed ib_(un)bind_mw,"
1667 " status %i\n", __func__, rc);
1668 else
1669 *r = NULL; /* will upcall on completion */
1670 return rc;
1671}
1672
1673static int
1674rpcrdma_register_default_external(struct rpcrdma_mr_seg *seg,
1675 int *nsegs, int writing, struct rpcrdma_ia *ia)
1676{
1677 int mem_priv = (writing ? IB_ACCESS_REMOTE_WRITE :
1678 IB_ACCESS_REMOTE_READ);
1679 struct rpcrdma_mr_seg *seg1 = seg;
1680 struct ib_phys_buf ipb[RPCRDMA_MAX_DATA_SEGS];
1681 int len, i, rc = 0;
1682
1683 if (*nsegs > RPCRDMA_MAX_DATA_SEGS)
1684 *nsegs = RPCRDMA_MAX_DATA_SEGS;
1685 for (len = 0, i = 0; i < *nsegs;) {
1686 rpcrdma_map_one(ia, seg, writing);
1687 ipb[i].addr = seg->mr_dma;
1688 ipb[i].size = seg->mr_len;
1689 len += seg->mr_len;
1690 ++seg;
1691 ++i;
1692 /* Check for holes */
1693 if ((i < *nsegs && offset_in_page(seg->mr_offset)) ||
1694 offset_in_page((seg-1)->mr_offset+(seg-1)->mr_len))
1695 break;
1696 }
1697 seg1->mr_base = seg1->mr_dma;
1698 seg1->mr_chunk.rl_mr = ib_reg_phys_mr(ia->ri_pd,
1699 ipb, i, mem_priv, &seg1->mr_base);
1700 if (IS_ERR(seg1->mr_chunk.rl_mr)) {
1701 rc = PTR_ERR(seg1->mr_chunk.rl_mr);
1702 dprintk("RPC: %s: failed ib_reg_phys_mr "
1703 "%u@0x%llx (%d)... status %i\n",
1704 __func__, len,
1705 (unsigned long long)seg1->mr_dma, i, rc);
1706 while (i--)
1707 rpcrdma_unmap_one(ia, --seg);
1708 } else {
1709 seg1->mr_rkey = seg1->mr_chunk.rl_mr->rkey;
1710 seg1->mr_nsegs = i;
1711 seg1->mr_len = len;
1712 }
1713 *nsegs = i;
1714 return rc;
1715}
1716
1717static int
1718rpcrdma_deregister_default_external(struct rpcrdma_mr_seg *seg,
1719 struct rpcrdma_ia *ia)
1720{
1721 struct rpcrdma_mr_seg *seg1 = seg;
1722 int rc;
1723
1724 rc = ib_dereg_mr(seg1->mr_chunk.rl_mr);
1725 seg1->mr_chunk.rl_mr = NULL;
1726 while (seg1->mr_nsegs--)
1727 rpcrdma_unmap_one(ia, seg++);
1728 if (rc)
1729 dprintk("RPC: %s: failed ib_dereg_mr,"
1730 " status %i\n", __func__, rc);
1731 return rc;
1732}
1733
1332int 1734int
1333rpcrdma_register_external(struct rpcrdma_mr_seg *seg, 1735rpcrdma_register_external(struct rpcrdma_mr_seg *seg,
1334 int nsegs, int writing, struct rpcrdma_xprt *r_xprt) 1736 int nsegs, int writing, struct rpcrdma_xprt *r_xprt)
1335{ 1737{
1336 struct rpcrdma_ia *ia = &r_xprt->rx_ia; 1738 struct rpcrdma_ia *ia = &r_xprt->rx_ia;
1337 int mem_priv = (writing ? IB_ACCESS_REMOTE_WRITE :
1338 IB_ACCESS_REMOTE_READ);
1339 struct rpcrdma_mr_seg *seg1 = seg;
1340 int i;
1341 int rc = 0; 1739 int rc = 0;
1342 1740
1343 switch (ia->ri_memreg_strategy) { 1741 switch (ia->ri_memreg_strategy) {
@@ -1352,114 +1750,25 @@ rpcrdma_register_external(struct rpcrdma_mr_seg *seg,
1352 break; 1750 break;
1353#endif 1751#endif
1354 1752
1355 /* Registration using fast memory registration */ 1753 /* Registration using frmr registration */
1754 case RPCRDMA_FRMR:
1755 rc = rpcrdma_register_frmr_external(seg, &nsegs, writing, ia, r_xprt);
1756 break;
1757
1758 /* Registration using fmr memory registration */
1356 case RPCRDMA_MTHCAFMR: 1759 case RPCRDMA_MTHCAFMR:
1357 { 1760 rc = rpcrdma_register_fmr_external(seg, &nsegs, writing, ia);
1358 u64 physaddrs[RPCRDMA_MAX_DATA_SEGS];
1359 int len, pageoff = offset_in_page(seg->mr_offset);
1360 seg1->mr_offset -= pageoff; /* start of page */
1361 seg1->mr_len += pageoff;
1362 len = -pageoff;
1363 if (nsegs > RPCRDMA_MAX_DATA_SEGS)
1364 nsegs = RPCRDMA_MAX_DATA_SEGS;
1365 for (i = 0; i < nsegs;) {
1366 rpcrdma_map_one(ia, seg, writing);
1367 physaddrs[i] = seg->mr_dma;
1368 len += seg->mr_len;
1369 ++seg;
1370 ++i;
1371 /* Check for holes */
1372 if ((i < nsegs && offset_in_page(seg->mr_offset)) ||
1373 offset_in_page((seg-1)->mr_offset+(seg-1)->mr_len))
1374 break;
1375 }
1376 nsegs = i;
1377 rc = ib_map_phys_fmr(seg1->mr_chunk.rl_mw->r.fmr,
1378 physaddrs, nsegs, seg1->mr_dma);
1379 if (rc) {
1380 dprintk("RPC: %s: failed ib_map_phys_fmr "
1381 "%u@0x%llx+%i (%d)... status %i\n", __func__,
1382 len, (unsigned long long)seg1->mr_dma,
1383 pageoff, nsegs, rc);
1384 while (nsegs--)
1385 rpcrdma_unmap_one(ia, --seg);
1386 } else {
1387 seg1->mr_rkey = seg1->mr_chunk.rl_mw->r.fmr->rkey;
1388 seg1->mr_base = seg1->mr_dma + pageoff;
1389 seg1->mr_nsegs = nsegs;
1390 seg1->mr_len = len;
1391 }
1392 }
1393 break; 1761 break;
1394 1762
1395 /* Registration using memory windows */ 1763 /* Registration using memory windows */
1396 case RPCRDMA_MEMWINDOWS_ASYNC: 1764 case RPCRDMA_MEMWINDOWS_ASYNC:
1397 case RPCRDMA_MEMWINDOWS: 1765 case RPCRDMA_MEMWINDOWS:
1398 { 1766 rc = rpcrdma_register_memwin_external(seg, &nsegs, writing, ia, r_xprt);
1399 struct ib_mw_bind param;
1400 rpcrdma_map_one(ia, seg, writing);
1401 param.mr = ia->ri_bind_mem;
1402 param.wr_id = 0ULL; /* no send cookie */
1403 param.addr = seg->mr_dma;
1404 param.length = seg->mr_len;
1405 param.send_flags = 0;
1406 param.mw_access_flags = mem_priv;
1407
1408 DECR_CQCOUNT(&r_xprt->rx_ep);
1409 rc = ib_bind_mw(ia->ri_id->qp,
1410 seg->mr_chunk.rl_mw->r.mw, &param);
1411 if (rc) {
1412 dprintk("RPC: %s: failed ib_bind_mw "
1413 "%u@0x%llx status %i\n",
1414 __func__, seg->mr_len,
1415 (unsigned long long)seg->mr_dma, rc);
1416 rpcrdma_unmap_one(ia, seg);
1417 } else {
1418 seg->mr_rkey = seg->mr_chunk.rl_mw->r.mw->rkey;
1419 seg->mr_base = param.addr;
1420 seg->mr_nsegs = 1;
1421 nsegs = 1;
1422 }
1423 }
1424 break; 1767 break;
1425 1768
1426 /* Default registration each time */ 1769 /* Default registration each time */
1427 default: 1770 default:
1428 { 1771 rc = rpcrdma_register_default_external(seg, &nsegs, writing, ia);
1429 struct ib_phys_buf ipb[RPCRDMA_MAX_DATA_SEGS];
1430 int len = 0;
1431 if (nsegs > RPCRDMA_MAX_DATA_SEGS)
1432 nsegs = RPCRDMA_MAX_DATA_SEGS;
1433 for (i = 0; i < nsegs;) {
1434 rpcrdma_map_one(ia, seg, writing);
1435 ipb[i].addr = seg->mr_dma;
1436 ipb[i].size = seg->mr_len;
1437 len += seg->mr_len;
1438 ++seg;
1439 ++i;
1440 /* Check for holes */
1441 if ((i < nsegs && offset_in_page(seg->mr_offset)) ||
1442 offset_in_page((seg-1)->mr_offset+(seg-1)->mr_len))
1443 break;
1444 }
1445 nsegs = i;
1446 seg1->mr_base = seg1->mr_dma;
1447 seg1->mr_chunk.rl_mr = ib_reg_phys_mr(ia->ri_pd,
1448 ipb, nsegs, mem_priv, &seg1->mr_base);
1449 if (IS_ERR(seg1->mr_chunk.rl_mr)) {
1450 rc = PTR_ERR(seg1->mr_chunk.rl_mr);
1451 dprintk("RPC: %s: failed ib_reg_phys_mr "
1452 "%u@0x%llx (%d)... status %i\n",
1453 __func__, len,
1454 (unsigned long long)seg1->mr_dma, nsegs, rc);
1455 while (nsegs--)
1456 rpcrdma_unmap_one(ia, --seg);
1457 } else {
1458 seg1->mr_rkey = seg1->mr_chunk.rl_mr->rkey;
1459 seg1->mr_nsegs = nsegs;
1460 seg1->mr_len = len;
1461 }
1462 }
1463 break; 1772 break;
1464 } 1773 }
1465 if (rc) 1774 if (rc)
@@ -1473,7 +1782,6 @@ rpcrdma_deregister_external(struct rpcrdma_mr_seg *seg,
1473 struct rpcrdma_xprt *r_xprt, void *r) 1782 struct rpcrdma_xprt *r_xprt, void *r)
1474{ 1783{
1475 struct rpcrdma_ia *ia = &r_xprt->rx_ia; 1784 struct rpcrdma_ia *ia = &r_xprt->rx_ia;
1476 struct rpcrdma_mr_seg *seg1 = seg;
1477 int nsegs = seg->mr_nsegs, rc; 1785 int nsegs = seg->mr_nsegs, rc;
1478 1786
1479 switch (ia->ri_memreg_strategy) { 1787 switch (ia->ri_memreg_strategy) {
@@ -1486,56 +1794,21 @@ rpcrdma_deregister_external(struct rpcrdma_mr_seg *seg,
1486 break; 1794 break;
1487#endif 1795#endif
1488 1796
1797 case RPCRDMA_FRMR:
1798 rc = rpcrdma_deregister_frmr_external(seg, ia, r_xprt);
1799 break;
1800
1489 case RPCRDMA_MTHCAFMR: 1801 case RPCRDMA_MTHCAFMR:
1490 { 1802 rc = rpcrdma_deregister_fmr_external(seg, ia);
1491 LIST_HEAD(l);
1492 list_add(&seg->mr_chunk.rl_mw->r.fmr->list, &l);
1493 rc = ib_unmap_fmr(&l);
1494 while (seg1->mr_nsegs--)
1495 rpcrdma_unmap_one(ia, seg++);
1496 }
1497 if (rc)
1498 dprintk("RPC: %s: failed ib_unmap_fmr,"
1499 " status %i\n", __func__, rc);
1500 break; 1803 break;
1501 1804
1502 case RPCRDMA_MEMWINDOWS_ASYNC: 1805 case RPCRDMA_MEMWINDOWS_ASYNC:
1503 case RPCRDMA_MEMWINDOWS: 1806 case RPCRDMA_MEMWINDOWS:
1504 { 1807 rc = rpcrdma_deregister_memwin_external(seg, ia, r_xprt, &r);
1505 struct ib_mw_bind param;
1506 BUG_ON(nsegs != 1);
1507 param.mr = ia->ri_bind_mem;
1508 param.addr = 0ULL; /* unbind */
1509 param.length = 0;
1510 param.mw_access_flags = 0;
1511 if (r) {
1512 param.wr_id = (u64) (unsigned long) r;
1513 param.send_flags = IB_SEND_SIGNALED;
1514 INIT_CQCOUNT(&r_xprt->rx_ep);
1515 } else {
1516 param.wr_id = 0ULL;
1517 param.send_flags = 0;
1518 DECR_CQCOUNT(&r_xprt->rx_ep);
1519 }
1520 rc = ib_bind_mw(ia->ri_id->qp,
1521 seg->mr_chunk.rl_mw->r.mw, &param);
1522 rpcrdma_unmap_one(ia, seg);
1523 }
1524 if (rc)
1525 dprintk("RPC: %s: failed ib_(un)bind_mw,"
1526 " status %i\n", __func__, rc);
1527 else
1528 r = NULL; /* will upcall on completion */
1529 break; 1808 break;
1530 1809
1531 default: 1810 default:
1532 rc = ib_dereg_mr(seg1->mr_chunk.rl_mr); 1811 rc = rpcrdma_deregister_default_external(seg, ia);
1533 seg1->mr_chunk.rl_mr = NULL;
1534 while (seg1->mr_nsegs--)
1535 rpcrdma_unmap_one(ia, seg++);
1536 if (rc)
1537 dprintk("RPC: %s: failed ib_dereg_mr,"
1538 " status %i\n", __func__, rc);
1539 break; 1812 break;
1540 } 1813 }
1541 if (r) { 1814 if (r) {
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h
index 2427822f8bd..c7a7eba991b 100644
--- a/net/sunrpc/xprtrdma/xprt_rdma.h
+++ b/net/sunrpc/xprtrdma/xprt_rdma.h
@@ -51,6 +51,9 @@
51#include <linux/sunrpc/rpc_rdma.h> /* RPC/RDMA protocol */ 51#include <linux/sunrpc/rpc_rdma.h> /* RPC/RDMA protocol */
52#include <linux/sunrpc/xprtrdma.h> /* xprt parameters */ 52#include <linux/sunrpc/xprtrdma.h> /* xprt parameters */
53 53
54#define RDMA_RESOLVE_TIMEOUT (5000) /* 5 seconds */
55#define RDMA_CONNECT_RETRY_MAX (2) /* retries if no listener backlog */
56
54/* 57/*
55 * Interface Adapter -- one per transport instance 58 * Interface Adapter -- one per transport instance
56 */ 59 */
@@ -58,6 +61,8 @@ struct rpcrdma_ia {
58 struct rdma_cm_id *ri_id; 61 struct rdma_cm_id *ri_id;
59 struct ib_pd *ri_pd; 62 struct ib_pd *ri_pd;
60 struct ib_mr *ri_bind_mem; 63 struct ib_mr *ri_bind_mem;
64 u32 ri_dma_lkey;
65 int ri_have_dma_lkey;
61 struct completion ri_done; 66 struct completion ri_done;
62 int ri_async_rc; 67 int ri_async_rc;
63 enum rpcrdma_memreg ri_memreg_strategy; 68 enum rpcrdma_memreg ri_memreg_strategy;
@@ -156,6 +161,10 @@ struct rpcrdma_mr_seg { /* chunk descriptors */
156 union { 161 union {
157 struct ib_mw *mw; 162 struct ib_mw *mw;
158 struct ib_fmr *fmr; 163 struct ib_fmr *fmr;
164 struct {
165 struct ib_fast_reg_page_list *fr_pgl;
166 struct ib_mr *fr_mr;
167 } frmr;
159 } r; 168 } r;
160 struct list_head mw_list; 169 struct list_head mw_list;
161 } *rl_mw; 170 } *rl_mw;
@@ -175,6 +184,7 @@ struct rpcrdma_req {
175 size_t rl_size; /* actual length of buffer */ 184 size_t rl_size; /* actual length of buffer */
176 unsigned int rl_niovs; /* 0, 2 or 4 */ 185 unsigned int rl_niovs; /* 0, 2 or 4 */
177 unsigned int rl_nchunks; /* non-zero if chunks */ 186 unsigned int rl_nchunks; /* non-zero if chunks */
187 unsigned int rl_connect_cookie; /* retry detection */
178 struct rpcrdma_buffer *rl_buffer; /* home base for this structure */ 188 struct rpcrdma_buffer *rl_buffer; /* home base for this structure */
179 struct rpcrdma_rep *rl_reply;/* holder for reply buffer */ 189 struct rpcrdma_rep *rl_reply;/* holder for reply buffer */
180 struct rpcrdma_mr_seg rl_segments[RPCRDMA_MAX_SEGS];/* chunk segments */ 190 struct rpcrdma_mr_seg rl_segments[RPCRDMA_MAX_SEGS];/* chunk segments */
@@ -198,7 +208,7 @@ struct rpcrdma_buffer {
198 atomic_t rb_credits; /* most recent server credits */ 208 atomic_t rb_credits; /* most recent server credits */
199 unsigned long rb_cwndscale; /* cached framework rpc_cwndscale */ 209 unsigned long rb_cwndscale; /* cached framework rpc_cwndscale */
200 int rb_max_requests;/* client max requests */ 210 int rb_max_requests;/* client max requests */
201 struct list_head rb_mws; /* optional memory windows/fmrs */ 211 struct list_head rb_mws; /* optional memory windows/fmrs/frmrs */
202 int rb_send_index; 212 int rb_send_index;
203 struct rpcrdma_req **rb_send_bufs; 213 struct rpcrdma_req **rb_send_bufs;
204 int rb_recv_index; 214 int rb_recv_index;
@@ -273,6 +283,11 @@ struct rpcrdma_xprt {
273#define rpcx_to_rdmax(x) container_of(x, struct rpcrdma_xprt, xprt) 283#define rpcx_to_rdmax(x) container_of(x, struct rpcrdma_xprt, xprt)
274#define rpcx_to_rdmad(x) (rpcx_to_rdmax(x)->rx_data) 284#define rpcx_to_rdmad(x) (rpcx_to_rdmax(x)->rx_data)
275 285
286/* Setting this to 0 ensures interoperability with early servers.
287 * Setting this to 1 enhances certain unaligned read/write performance.
288 * Default is 0, see sysctl entry and rpc_rdma.c rpcrdma_convert_iovs() */
289extern int xprt_rdma_pad_optimize;
290
276/* 291/*
277 * Interface Adapter calls - xprtrdma/verbs.c 292 * Interface Adapter calls - xprtrdma/verbs.c
278 */ 293 */
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 4486c59c3ac..9a288d5eea6 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -3,8 +3,8 @@
3 * 3 *
4 * Client-side transport implementation for sockets. 4 * Client-side transport implementation for sockets.
5 * 5 *
6 * TCP callback races fixes (C) 1998 Red Hat Software <alan@redhat.com> 6 * TCP callback races fixes (C) 1998 Red Hat
7 * TCP send fixes (C) 1998 Red Hat Software <alan@redhat.com> 7 * TCP send fixes (C) 1998 Red Hat
8 * TCP NFS related read + write fixes 8 * TCP NFS related read + write fixes
9 * (C) 1999 Dave Airlie, University of Limerick, Ireland <airlied@linux.ie> 9 * (C) 1999 Dave Airlie, University of Limerick, Ireland <airlied@linux.ie>
10 * 10 *
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 015606b54d9..c647aab8d41 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * NET4: Implementation of BSD Unix domain sockets. 2 * NET4: Implementation of BSD Unix domain sockets.
3 * 3 *
4 * Authors: Alan Cox, <alan.cox@linux.org> 4 * Authors: Alan Cox, <alan@lxorguk.ukuu.org.uk>
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License 7 * modify it under the terms of the GNU General Public License
diff --git a/net/wireless/Kconfig b/net/wireless/Kconfig
index 833b024f8f6..7d82be07fa1 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
diff --git a/net/wireless/core.c b/net/wireless/core.c
index f1da0b93bc5..5031db7b275 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>
@@ -19,6 +19,7 @@
19#include "nl80211.h" 19#include "nl80211.h"
20#include "core.h" 20#include "core.h"
21#include "sysfs.h" 21#include "sysfs.h"
22#include "reg.h"
22 23
23/* name for sysfs, %d is appended */ 24/* name for sysfs, %d is appended */
24#define PHY_NAME "phy" 25#define PHY_NAME "phy"
@@ -32,7 +33,6 @@ MODULE_DESCRIPTION("wireless configuration support");
32 * often because we need to do it for each command */ 33 * often because we need to do it for each command */
33LIST_HEAD(cfg80211_drv_list); 34LIST_HEAD(cfg80211_drv_list);
34DEFINE_MUTEX(cfg80211_drv_mutex); 35DEFINE_MUTEX(cfg80211_drv_mutex);
35static int wiphy_counter;
36 36
37/* for debugfs */ 37/* for debugfs */
38static struct dentry *ieee80211_debugfs_dir; 38static struct dentry *ieee80211_debugfs_dir;
@@ -184,7 +184,8 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
184 if (result) 184 if (result)
185 goto out_unlock; 185 goto out_unlock;
186 186
187 if (!debugfs_rename(rdev->wiphy.debugfsdir->d_parent, 187 if (rdev->wiphy.debugfsdir &&
188 !debugfs_rename(rdev->wiphy.debugfsdir->d_parent,
188 rdev->wiphy.debugfsdir, 189 rdev->wiphy.debugfsdir,
189 rdev->wiphy.debugfsdir->d_parent, 190 rdev->wiphy.debugfsdir->d_parent,
190 newname)) 191 newname))
@@ -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
@@ -309,6 +318,8 @@ int wiphy_register(struct wiphy *wiphy)
309 drv->wiphy.debugfsdir = 318 drv->wiphy.debugfsdir =
310 debugfs_create_dir(wiphy_name(&drv->wiphy), 319 debugfs_create_dir(wiphy_name(&drv->wiphy),
311 ieee80211_debugfs_dir); 320 ieee80211_debugfs_dir);
321 if (IS_ERR(drv->wiphy.debugfsdir))
322 drv->wiphy.debugfsdir = NULL;
312 323
313 res = 0; 324 res = 0;
314out_unlock: 325out_unlock:
@@ -373,6 +384,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
373 384
374 rdev = wiphy_to_dev(dev->ieee80211_ptr->wiphy); 385 rdev = wiphy_to_dev(dev->ieee80211_ptr->wiphy);
375 386
387 WARN_ON(dev->ieee80211_ptr->iftype == NL80211_IFTYPE_UNSPECIFIED);
388
376 switch (state) { 389 switch (state) {
377 case NETDEV_REGISTER: 390 case NETDEV_REGISTER:
378 mutex_lock(&rdev->devlist_mtx); 391 mutex_lock(&rdev->devlist_mtx);
@@ -404,7 +417,9 @@ static struct notifier_block cfg80211_netdev_notifier = {
404 417
405static int cfg80211_init(void) 418static int cfg80211_init(void)
406{ 419{
407 int err = wiphy_sysfs_init(); 420 int err;
421
422 err = wiphy_sysfs_init();
408 if (err) 423 if (err)
409 goto out_fail_sysfs; 424 goto out_fail_sysfs;
410 425
@@ -418,8 +433,14 @@ static int cfg80211_init(void)
418 433
419 ieee80211_debugfs_dir = debugfs_create_dir("ieee80211", NULL); 434 ieee80211_debugfs_dir = debugfs_create_dir("ieee80211", NULL);
420 435
436 err = regulatory_init();
437 if (err)
438 goto out_fail_reg;
439
421 return 0; 440 return 0;
422 441
442out_fail_reg:
443 debugfs_remove(ieee80211_debugfs_dir);
423out_fail_nl80211: 444out_fail_nl80211:
424 unregister_netdevice_notifier(&cfg80211_netdev_notifier); 445 unregister_netdevice_notifier(&cfg80211_netdev_notifier);
425out_fail_notifier: 446out_fail_notifier:
@@ -427,6 +448,7 @@ out_fail_notifier:
427out_fail_sysfs: 448out_fail_sysfs:
428 return err; 449 return err;
429} 450}
451
430subsys_initcall(cfg80211_init); 452subsys_initcall(cfg80211_init);
431 453
432static void cfg80211_exit(void) 454static void cfg80211_exit(void)
@@ -435,5 +457,6 @@ static void cfg80211_exit(void)
435 nl80211_exit(); 457 nl80211_exit();
436 unregister_netdevice_notifier(&cfg80211_netdev_notifier); 458 unregister_netdevice_notifier(&cfg80211_netdev_notifier);
437 wiphy_sysfs_exit(); 459 wiphy_sysfs_exit();
460 regulatory_exit();
438} 461}
439module_exit(cfg80211_exit); 462module_exit(cfg80211_exit);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 7a02c356d63..771cc5cc765 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 59eb2cf42e5..572793c8c7a 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 855bff4b325..626dbb68849 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 00000000000..a33362872f3
--- /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 ac25b4c0e98..dc50f1e71f7 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 46914b79d85..832b47c1de8 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
@@ -2414,9 +2424,7 @@ static void __init xfrm_policy_init(void)
2414 panic("XFRM: failed to allocate bydst hash\n"); 2424 panic("XFRM: failed to allocate bydst hash\n");
2415 } 2425 }
2416 2426
2417 for (dir = 0; dir < XFRM_POLICY_TYPE_MAX; dir++) 2427 INIT_LIST_HEAD(&xfrm_policy_all);
2418 INIT_LIST_HEAD(&xfrm_policy_bytype[dir]);
2419
2420 INIT_WORK(&xfrm_policy_gc_work, xfrm_policy_gc_task); 2428 INIT_WORK(&xfrm_policy_gc_work, xfrm_policy_gc_task);
2421 register_netdevice_notifier(&xfrm_dev_notifier); 2429 register_netdevice_notifier(&xfrm_dev_notifier);
2422} 2430}
@@ -2600,7 +2608,7 @@ static int xfrm_policy_migrate(struct xfrm_policy *pol,
2600 int i, j, n = 0; 2608 int i, j, n = 0;
2601 2609
2602 write_lock_bh(&pol->lock); 2610 write_lock_bh(&pol->lock);
2603 if (unlikely(pol->dead)) { 2611 if (unlikely(pol->walk.dead)) {
2604 /* target policy has been deleted */ 2612 /* target policy has been deleted */
2605 write_unlock_bh(&pol->lock); 2613 write_unlock_bh(&pol->lock);
2606 return -ENOENT; 2614 return -ENOENT;
@@ -2671,7 +2679,8 @@ static int xfrm_migrate_check(struct xfrm_migrate *m, int num_migrate)
2671} 2679}
2672 2680
2673int xfrm_migrate(struct xfrm_selector *sel, u8 dir, u8 type, 2681int xfrm_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
2674 struct xfrm_migrate *m, int num_migrate) 2682 struct xfrm_migrate *m, int num_migrate,
2683 struct xfrm_kmaddress *k)
2675{ 2684{
2676 int i, err, nx_cur = 0, nx_new = 0; 2685 int i, err, nx_cur = 0, nx_new = 0;
2677 struct xfrm_policy *pol = NULL; 2686 struct xfrm_policy *pol = NULL;
@@ -2715,7 +2724,7 @@ int xfrm_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
2715 } 2724 }
2716 2725
2717 /* Stage 5 - announce */ 2726 /* Stage 5 - announce */
2718 km_migrate(sel, dir, type, m, num_migrate); 2727 km_migrate(sel, dir, type, m, num_migrate, k);
2719 2728
2720 xfrm_pol_put(pol); 2729 xfrm_pol_put(pol);
2721 2730
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 7bd62f61593..508337f9724 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)
@@ -858,6 +854,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
858 854
859 if (km_query(x, tmpl, pol) == 0) { 855 if (km_query(x, tmpl, pol) == 0) {
860 x->km.state = XFRM_STATE_ACQ; 856 x->km.state = XFRM_STATE_ACQ;
857 list_add(&x->km.all, &xfrm_state_all);
861 hlist_add_head(&x->bydst, xfrm_state_bydst+h); 858 hlist_add_head(&x->bydst, xfrm_state_bydst+h);
862 h = xfrm_src_hash(daddr, saddr, family); 859 h = xfrm_src_hash(daddr, saddr, family);
863 hlist_add_head(&x->bysrc, xfrm_state_bysrc+h); 860 hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);
@@ -926,7 +923,7 @@ static void __xfrm_state_insert(struct xfrm_state *x)
926 923
927 x->genid = ++xfrm_state_genid; 924 x->genid = ++xfrm_state_genid;
928 925
929 list_add_tail(&x->all, &xfrm_state_all); 926 list_add(&x->km.all, &xfrm_state_all);
930 927
931 h = xfrm_dst_hash(&x->id.daddr, &x->props.saddr, 928 h = xfrm_dst_hash(&x->id.daddr, &x->props.saddr,
932 x->props.reqid, x->props.family); 929 x->props.reqid, x->props.family);
@@ -1055,6 +1052,7 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re
1055 xfrm_state_hold(x); 1052 xfrm_state_hold(x);
1056 x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ; 1053 x->timer.expires = jiffies + sysctl_xfrm_acq_expires*HZ;
1057 add_timer(&x->timer); 1054 add_timer(&x->timer);
1055 list_add(&x->km.all, &xfrm_state_all);
1058 hlist_add_head(&x->bydst, xfrm_state_bydst+h); 1056 hlist_add_head(&x->bydst, xfrm_state_bydst+h);
1059 h = xfrm_src_hash(daddr, saddr, family); 1057 h = xfrm_src_hash(daddr, saddr, family);
1060 hlist_add_head(&x->bysrc, xfrm_state_bysrc+h); 1058 hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);
@@ -1551,47 +1549,62 @@ int xfrm_state_walk(struct xfrm_state_walk *walk,
1551 int (*func)(struct xfrm_state *, int, void*), 1549 int (*func)(struct xfrm_state *, int, void*),
1552 void *data) 1550 void *data)
1553{ 1551{
1554 struct xfrm_state *old, *x, *last = NULL; 1552 struct xfrm_state *state;
1553 struct xfrm_state_walk *x;
1555 int err = 0; 1554 int err = 0;
1556 1555
1557 if (walk->state == NULL && walk->count != 0) 1556 if (walk->seq != 0 && list_empty(&walk->all))
1558 return 0; 1557 return 0;
1559 1558
1560 old = x = walk->state;
1561 walk->state = NULL;
1562 spin_lock_bh(&xfrm_state_lock); 1559 spin_lock_bh(&xfrm_state_lock);
1563 if (x == NULL) 1560 if (list_empty(&walk->all))
1564 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);
1565 list_for_each_entry_from(x, &xfrm_state_all, all) { 1564 list_for_each_entry_from(x, &xfrm_state_all, all) {
1566 if (x->km.state == XFRM_STATE_DEAD) 1565 if (x->state == XFRM_STATE_DEAD)
1567 continue; 1566 continue;
1568 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))
1569 continue; 1569 continue;
1570 if (last) { 1570 err = func(state, walk->seq, data);
1571 err = func(last, walk->count, data); 1571 if (err) {
1572 if (err) { 1572 list_move_tail(&walk->all, &x->all);
1573 xfrm_state_hold(last); 1573 goto out;
1574 walk->state = last;
1575 goto out;
1576 }
1577 } 1574 }
1578 last = x; 1575 walk->seq++;
1579 walk->count++;
1580 } 1576 }
1581 if (walk->count == 0) { 1577 if (walk->seq == 0) {
1582 err = -ENOENT; 1578 err = -ENOENT;
1583 goto out; 1579 goto out;
1584 } 1580 }
1585 if (last) 1581 list_del_init(&walk->all);
1586 err = func(last, 0, data);
1587out: 1582out:
1588 spin_unlock_bh(&xfrm_state_lock); 1583 spin_unlock_bh(&xfrm_state_lock);
1589 if (old != NULL)
1590 xfrm_state_put(old);
1591 return err; 1584 return err;
1592} 1585}
1593EXPORT_SYMBOL(xfrm_state_walk); 1586EXPORT_SYMBOL(xfrm_state_walk);
1594 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
1595 1608
1596void xfrm_replay_notify(struct xfrm_state *x, int event) 1609void xfrm_replay_notify(struct xfrm_state *x, int event)
1597{ 1610{
@@ -1801,7 +1814,8 @@ EXPORT_SYMBOL(km_policy_expired);
1801 1814
1802#ifdef CONFIG_XFRM_MIGRATE 1815#ifdef CONFIG_XFRM_MIGRATE
1803int km_migrate(struct xfrm_selector *sel, u8 dir, u8 type, 1816int km_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
1804 struct xfrm_migrate *m, int num_migrate) 1817 struct xfrm_migrate *m, int num_migrate,
1818 struct xfrm_kmaddress *k)
1805{ 1819{
1806 int err = -EINVAL; 1820 int err = -EINVAL;
1807 int ret; 1821 int ret;
@@ -1810,7 +1824,7 @@ int km_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
1810 read_lock(&xfrm_km_lock); 1824 read_lock(&xfrm_km_lock);
1811 list_for_each_entry(km, &xfrm_km_list, list) { 1825 list_for_each_entry(km, &xfrm_km_list, list) {
1812 if (km->migrate) { 1826 if (km->migrate) {
1813 ret = km->migrate(sel, dir, type, m, num_migrate); 1827 ret = km->migrate(sel, dir, type, m, num_migrate, k);
1814 if (!ret) 1828 if (!ret)
1815 err = ret; 1829 err = ret;
1816 } 1830 }
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 04c41504f84..4a8a1abb59e 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 {