aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2007-01-17 18:34:51 -0500
committerDavid Woodhouse <dwmw2@infradead.org>2007-01-17 18:34:51 -0500
commit9cdf083f981b8d37b3212400a359368661385099 (patch)
treeaa15a6a08ad87e650dea40fb59b3180bef0d345b /net
parente499e01d234a31d59679b7b1e1cf628d917ba49a (diff)
parenta8b3485287731978899ced11f24628c927890e78 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'net')
-rw-r--r--net/802/hippi.c1
-rw-r--r--net/Kconfig29
-rw-r--r--net/appletalk/ddp.c1
-rw-r--r--net/atm/Makefile3
-rw-r--r--net/atm/br2684.c30
-rw-r--r--net/atm/clip.c39
-rw-r--r--net/atm/ipcommon.c63
-rw-r--r--net/atm/ipcommon.h22
-rw-r--r--net/atm/lec.c25
-rw-r--r--net/atm/lec.h8
-rw-r--r--net/atm/mpc.c29
-rw-r--r--net/atm/mpc.h6
-rw-r--r--net/atm/mpoa_caches.c20
-rw-r--r--net/atm/mpoa_caches.h16
-rw-r--r--net/atm/mpoa_proc.c6
-rw-r--r--net/atm/proc.c2
-rw-r--r--net/ax25/af_ax25.c10
-rw-r--r--net/ax25/ax25_addr.c36
-rw-r--r--net/ax25/ax25_iface.c103
-rw-r--r--net/ax25/ax25_out.c4
-rw-r--r--net/ax25/ax25_route.c7
-rw-r--r--net/ax25/sysctl_net_ax25.c5
-rw-r--r--net/bluetooth/bnep/bnep.h4
-rw-r--r--net/bluetooth/bnep/core.c28
-rw-r--r--net/bluetooth/bnep/netdev.c11
-rw-r--r--net/bluetooth/cmtp/capi.c39
-rw-r--r--net/bluetooth/hci_sock.c4
-rw-r--r--net/bluetooth/hci_sysfs.c19
-rw-r--r--net/bluetooth/l2cap.c4
-rw-r--r--net/bluetooth/rfcomm/core.c18
-rw-r--r--net/bluetooth/rfcomm/sock.c9
-rw-r--r--net/bluetooth/rfcomm/tty.c26
-rw-r--r--net/bridge/br_fdb.c2
-rw-r--r--net/bridge/br_if.c10
-rw-r--r--net/bridge/br_netfilter.c227
-rw-r--r--net/bridge/br_netlink.c113
-rw-r--r--net/bridge/br_private.h2
-rw-r--r--net/bridge/netfilter/ebt_802_3.c2
-rw-r--r--net/bridge/netfilter/ebt_among.c22
-rw-r--r--net/bridge/netfilter/ebt_arp.c6
-rw-r--r--net/bridge/netfilter/ebt_ip.c4
-rw-r--r--net/bridge/netfilter/ebt_log.c6
-rw-r--r--net/bridge/netfilter/ebt_mark.c14
-rw-r--r--net/bridge/netfilter/ebt_mark_m.c4
-rw-r--r--net/bridge/netfilter/ebt_snat.c27
-rw-r--r--net/bridge/netfilter/ebt_ulog.c2
-rw-r--r--net/bridge/netfilter/ebt_vlan.c2
-rw-r--r--net/bridge/netfilter/ebtable_broute.c2
-rw-r--r--net/bridge/netfilter/ebtable_filter.c2
-rw-r--r--net/bridge/netfilter/ebtable_nat.c2
-rw-r--r--net/bridge/netfilter/ebtables.c223
-rw-r--r--net/core/Makefile1
-rw-r--r--net/core/datagram.c16
-rw-r--r--net/core/dev.c41
-rw-r--r--net/core/dst.c2
-rw-r--r--net/core/dv.c546
-rw-r--r--net/core/fib_rules.c71
-rw-r--r--net/core/filter.c6
-rw-r--r--net/core/flow.c6
-rw-r--r--net/core/iovec.c4
-rw-r--r--net/core/kmap_skb.h19
-rw-r--r--net/core/link_watch.c13
-rw-r--r--net/core/neighbour.c37
-rw-r--r--net/core/netpoll.c348
-rw-r--r--net/core/pktgen.c224
-rw-r--r--net/core/request_sock.c35
-rw-r--r--net/core/rtnetlink.c60
-rw-r--r--net/core/skbuff.c49
-rw-r--r--net/core/sock.c39
-rw-r--r--net/core/sysctl_net_core.c14
-rw-r--r--net/core/utils.c10
-rw-r--r--net/core/wireless.c4
-rw-r--r--net/dccp/Kconfig5
-rw-r--r--net/dccp/Makefile8
-rw-r--r--net/dccp/ackvec.c122
-rw-r--r--net/dccp/ackvec.h20
-rw-r--r--net/dccp/ccid.c6
-rw-r--r--net/dccp/ccid.h26
-rw-r--r--net/dccp/ccids/Kconfig58
-rw-r--r--net/dccp/ccids/ccid2.c57
-rw-r--r--net/dccp/ccids/ccid2.h3
-rw-r--r--net/dccp/ccids/ccid3.c929
-rw-r--r--net/dccp/ccids/ccid3.h129
-rw-r--r--net/dccp/ccids/lib/loss_interval.c8
-rw-r--r--net/dccp/ccids/lib/loss_interval.h2
-rw-r--r--net/dccp/ccids/lib/packet_history.c219
-rw-r--r--net/dccp/ccids/lib/packet_history.h130
-rw-r--r--net/dccp/ccids/lib/tfrc.h23
-rw-r--r--net/dccp/ccids/lib/tfrc_equation.c241
-rw-r--r--net/dccp/dccp.h109
-rw-r--r--net/dccp/feat.c131
-rw-r--r--net/dccp/feat.h48
-rw-r--r--net/dccp/input.c110
-rw-r--r--net/dccp/ipv4.c551
-rw-r--r--net/dccp/ipv6.c627
-rw-r--r--net/dccp/minisocks.c53
-rw-r--r--net/dccp/options.c66
-rw-r--r--net/dccp/output.c111
-rw-r--r--net/dccp/probe.c6
-rw-r--r--net/dccp/proto.c70
-rw-r--r--net/dccp/sysctl.c60
-rw-r--r--net/dccp/timer.c140
-rw-r--r--net/decnet/Kconfig8
-rw-r--r--net/decnet/dn_dev.c179
-rw-r--r--net/decnet/dn_neigh.c1
-rw-r--r--net/decnet/dn_nsp_in.c2
-rw-r--r--net/decnet/dn_route.c46
-rw-r--r--net/decnet/dn_rules.c43
-rw-r--r--net/decnet/dn_table.c46
-rw-r--r--net/decnet/sysctl_net_decnet.c6
-rw-r--r--net/ethernet/eth.c1
-rw-r--r--net/ieee80211/ieee80211_crypt_tkip.c1
-rw-r--r--net/ieee80211/ieee80211_crypt_wep.c1
-rw-r--r--net/ieee80211/ieee80211_module.c25
-rw-r--r--net/ieee80211/ieee80211_rx.c68
-rw-r--r--net/ieee80211/ieee80211_tx.c4
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_assoc.c34
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_auth.c49
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_event.c12
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_module.c4
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_priv.h15
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_scan.c20
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_wx.c11
-rw-r--r--net/ipv4/Kconfig19
-rw-r--r--net/ipv4/Makefile3
-rw-r--r--net/ipv4/af_inet.c18
-rw-r--r--net/ipv4/ah4.c4
-rw-r--r--net/ipv4/arp.c2
-rw-r--r--net/ipv4/cipso_ipv4.c813
-rw-r--r--net/ipv4/devinet.c41
-rw-r--r--net/ipv4/esp4.c4
-rw-r--r--net/ipv4/fib_frontend.c5
-rw-r--r--net/ipv4/fib_hash.c8
-rw-r--r--net/ipv4/fib_rules.c53
-rw-r--r--net/ipv4/fib_semantics.c36
-rw-r--r--net/ipv4/fib_trie.c6
-rw-r--r--net/ipv4/icmp.c6
-rw-r--r--net/ipv4/igmp.c2
-rw-r--r--net/ipv4/inet_connection_sock.c2
-rw-r--r--net/ipv4/inet_hashtables.c6
-rw-r--r--net/ipv4/inet_timewait_sock.c8
-rw-r--r--net/ipv4/inetpeer.c2
-rw-r--r--net/ipv4/ip_fragment.c2
-rw-r--r--net/ipv4/ip_gre.c56
-rw-r--r--net/ipv4/ip_output.c34
-rw-r--r--net/ipv4/ip_sockglue.c2
-rw-r--r--net/ipv4/ipconfig.c105
-rw-r--r--net/ipv4/ipip.c16
-rw-r--r--net/ipv4/ipmr.c4
-rw-r--r--net/ipv4/ipvs/ip_vs_app.c3
-rw-r--r--net/ipv4/ipvs/ip_vs_conn.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_core.c4
-rw-r--r--net/ipv4/ipvs/ip_vs_ctl.c6
-rw-r--r--net/ipv4/ipvs/ip_vs_lblc.c1
-rw-r--r--net/ipv4/ipvs/ip_vs_lblcr.c1
-rw-r--r--net/ipv4/ipvs/ip_vs_proto.c8
-rw-r--r--net/ipv4/ipvs/ip_vs_proto_tcp.c16
-rw-r--r--net/ipv4/ipvs/ip_vs_proto_udp.c22
-rw-r--r--net/ipv4/ipvs/ip_vs_sync.c17
-rw-r--r--net/ipv4/netfilter.c17
-rw-r--r--net/ipv4/netfilter/Kconfig140
-rw-r--r--net/ipv4/netfilter/Makefile30
-rw-r--r--net/ipv4/netfilter/arp_tables.c53
-rw-r--r--net/ipv4/netfilter/ip_conntrack_amanda.c11
-rw-r--r--net/ipv4/netfilter/ip_conntrack_core.c12
-rw-r--r--net/ipv4/netfilter/ip_conntrack_ftp.c8
-rw-r--r--net/ipv4/netfilter/ip_conntrack_helper_h323.c168
-rw-r--r--net/ipv4/netfilter/ip_conntrack_helper_pptp.c33
-rw-r--r--net/ipv4/netfilter/ip_conntrack_irc.c12
-rw-r--r--net/ipv4/netfilter/ip_conntrack_netlink.c65
-rw-r--r--net/ipv4/netfilter/ip_conntrack_proto_gre.c2
-rw-r--r--net/ipv4/netfilter/ip_conntrack_sip.c118
-rw-r--r--net/ipv4/netfilter/ip_conntrack_standalone.c6
-rw-r--r--net/ipv4/netfilter/ip_conntrack_tftp.c6
-rw-r--r--net/ipv4/netfilter/ip_nat_amanda.c9
-rw-r--r--net/ipv4/netfilter/ip_nat_core.c6
-rw-r--r--net/ipv4/netfilter/ip_nat_ftp.c9
-rw-r--r--net/ipv4/netfilter/ip_nat_helper.c32
-rw-r--r--net/ipv4/netfilter/ip_nat_helper_h323.c58
-rw-r--r--net/ipv4/netfilter/ip_nat_helper_pptp.c29
-rw-r--r--net/ipv4/netfilter/ip_nat_irc.c9
-rw-r--r--net/ipv4/netfilter/ip_nat_proto_gre.c8
-rw-r--r--net/ipv4/netfilter/ip_nat_proto_icmp.c10
-rw-r--r--net/ipv4/netfilter/ip_nat_proto_tcp.c5
-rw-r--r--net/ipv4/netfilter/ip_nat_proto_udp.c9
-rw-r--r--net/ipv4/netfilter/ip_nat_sip.c199
-rw-r--r--net/ipv4/netfilter/ip_nat_snmp_basic.c85
-rw-r--r--net/ipv4/netfilter/ip_nat_standalone.c6
-rw-r--r--net/ipv4/netfilter/ip_nat_tftp.c9
-rw-r--r--net/ipv4/netfilter/ip_queue.c2
-rw-r--r--net/ipv4/netfilter/ip_tables.c243
-rw-r--r--net/ipv4/netfilter/ipt_CLUSTERIP.c35
-rw-r--r--net/ipv4/netfilter/ipt_ECN.c11
-rw-r--r--net/ipv4/netfilter/ipt_LOG.c20
-rw-r--r--net/ipv4/netfilter/ipt_MASQUERADE.c32
-rw-r--r--net/ipv4/netfilter/ipt_NETMAP.c4
-rw-r--r--net/ipv4/netfilter/ipt_REDIRECT.c6
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c2
-rw-r--r--net/ipv4/netfilter/ipt_SAME.c12
-rw-r--r--net/ipv4/netfilter/ipt_TCPMSS.c24
-rw-r--r--net/ipv4/netfilter/ipt_TOS.c5
-rw-r--r--net/ipv4/netfilter/ipt_TTL.c5
-rw-r--r--net/ipv4/netfilter/ipt_ULOG.c2
-rw-r--r--net/ipv4/netfilter/ipt_recent.c2
-rw-r--r--net/ipv4/netfilter/iptable_mangle.c8
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c137
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c412
-rw-r--r--net/ipv4/netfilter/nf_conntrack_proto_icmp.c57
-rw-r--r--net/ipv4/netfilter/nf_nat_amanda.c78
-rw-r--r--net/ipv4/netfilter/nf_nat_core.c647
-rw-r--r--net/ipv4/netfilter/nf_nat_ftp.c179
-rw-r--r--net/ipv4/netfilter/nf_nat_h323.c596
-rw-r--r--net/ipv4/netfilter/nf_nat_helper.c433
-rw-r--r--net/ipv4/netfilter/nf_nat_irc.c101
-rw-r--r--net/ipv4/netfilter/nf_nat_pptp.c315
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_gre.c179
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_icmp.c86
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_tcp.c148
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_udp.c138
-rw-r--r--net/ipv4/netfilter/nf_nat_proto_unknown.c54
-rw-r--r--net/ipv4/netfilter/nf_nat_rule.c343
-rw-r--r--net/ipv4/netfilter/nf_nat_sip.c283
-rw-r--r--net/ipv4/netfilter/nf_nat_snmp_basic.c1332
-rw-r--r--net/ipv4/netfilter/nf_nat_standalone.c406
-rw-r--r--net/ipv4/netfilter/nf_nat_tftp.c52
-rw-r--r--net/ipv4/proc.c13
-rw-r--r--net/ipv4/raw.c4
-rw-r--r--net/ipv4/route.c74
-rw-r--r--net/ipv4/syncookies.c18
-rw-r--r--net/ipv4/sysctl_net_ipv4.c84
-rw-r--r--net/ipv4/tcp.c157
-rw-r--r--net/ipv4/tcp_cong.c91
-rw-r--r--net/ipv4/tcp_htcp.c4
-rw-r--r--net/ipv4/tcp_input.c18
-rw-r--r--net/ipv4/tcp_ipv4.c714
-rw-r--r--net/ipv4/tcp_minisocks.c72
-rw-r--r--net/ipv4/tcp_output.c122
-rw-r--r--net/ipv4/tcp_timer.c2
-rw-r--r--net/ipv4/tcp_vegas.c4
-rw-r--r--net/ipv4/udp.c552
-rw-r--r--net/ipv4/udp_impl.h38
-rw-r--r--net/ipv4/udplite.c119
-rw-r--r--net/ipv4/xfrm4_policy.c9
-rw-r--r--net/ipv6/Kconfig7
-rw-r--r--net/ipv6/Makefile4
-rw-r--r--net/ipv6/addrconf.c197
-rw-r--r--net/ipv6/af_inet6.c35
-rw-r--r--net/ipv6/ah6.c5
-rw-r--r--net/ipv6/datagram.c16
-rw-r--r--net/ipv6/esp6.c2
-rw-r--r--net/ipv6/exthdrs.c59
-rw-r--r--net/ipv6/exthdrs_core.c2
-rw-r--r--net/ipv6/fib6_rules.c60
-rw-r--r--net/ipv6/icmp.c23
-rw-r--r--net/ipv6/inet6_connection_sock.c17
-rw-r--r--net/ipv6/inet6_hashtables.c6
-rw-r--r--net/ipv6/ip6_fib.c12
-rw-r--r--net/ipv6/ip6_flowlabel.c8
-rw-r--r--net/ipv6/ip6_input.c42
-rw-r--r--net/ipv6/ip6_output.c103
-rw-r--r--net/ipv6/ip6_tunnel.c296
-rw-r--r--net/ipv6/ipcomp6.c2
-rw-r--r--net/ipv6/ipv6_sockglue.c34
-rw-r--r--net/ipv6/mcast.c36
-rw-r--r--net/ipv6/mip6.c4
-rw-r--r--net/ipv6/ndisc.c38
-rw-r--r--net/ipv6/netfilter.c11
-rw-r--r--net/ipv6/netfilter/Kconfig7
-rw-r--r--net/ipv6/netfilter/ip6_queue.c4
-rw-r--r--net/ipv6/netfilter/ip6_tables.c67
-rw-r--r--net/ipv6/netfilter/ip6t_LOG.c23
-rw-r--r--net/ipv6/netfilter/ip6table_mangle.c9
-rw-r--r--net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c93
-rw-r--r--net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c40
-rw-r--r--net/ipv6/netfilter/nf_conntrack_reasm.c28
-rw-r--r--net/ipv6/proc.c18
-rw-r--r--net/ipv6/raw.c28
-rw-r--r--net/ipv6/reassembly.c87
-rw-r--r--net/ipv6/route.c99
-rw-r--r--net/ipv6/sit.c22
-rw-r--r--net/ipv6/tcp_ipv6.c607
-rw-r--r--net/ipv6/tunnel6.c2
-rw-r--r--net/ipv6/udp.c426
-rw-r--r--net/ipv6/udp_impl.h34
-rw-r--r--net/ipv6/udplite.c105
-rw-r--r--net/ipv6/xfrm6_policy.c3
-rw-r--r--net/ipv6/xfrm6_tunnel.c12
-rw-r--r--net/irda/discovery.c1
-rw-r--r--net/irda/ircomm/ircomm_tty.c11
-rw-r--r--net/irda/ircomm/ircomm_tty_ioctl.c2
-rw-r--r--net/irda/iriap.c12
-rw-r--r--net/irda/irias_object.c4
-rw-r--r--net/irda/irlan/irlan_common.c2
-rw-r--r--net/irda/irlmp.c4
-rw-r--r--net/irda/irqueue.c3
-rw-r--r--net/irda/irttp.c9
-rw-r--r--net/key/af_key.c69
-rw-r--r--net/llc/af_llc.c2
-rw-r--r--net/llc/llc_input.c4
-rw-r--r--net/netfilter/Kconfig196
-rw-r--r--net/netfilter/Makefile17
-rw-r--r--net/netfilter/core.c31
-rw-r--r--net/netfilter/nf_conntrack_amanda.c238
-rw-r--r--net/netfilter/nf_conntrack_core.c695
-rw-r--r--net/netfilter/nf_conntrack_ecache.c93
-rw-r--r--net/netfilter/nf_conntrack_expect.c445
-rw-r--r--net/netfilter/nf_conntrack_ftp.c42
-rw-r--r--net/netfilter/nf_conntrack_h323_asn1.c (renamed from net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c)4
-rw-r--r--net/netfilter/nf_conntrack_h323_main.c1856
-rw-r--r--net/netfilter/nf_conntrack_h323_types.c (renamed from net/ipv4/netfilter/ip_conntrack_helper_h323_types.c)7
-rw-r--r--net/netfilter/nf_conntrack_helper.c155
-rw-r--r--net/netfilter/nf_conntrack_irc.c281
-rw-r--r--net/netfilter/nf_conntrack_l3proto_generic.c7
-rw-r--r--net/netfilter/nf_conntrack_netbios_ns.c127
-rw-r--r--net/netfilter/nf_conntrack_netlink.c207
-rw-r--r--net/netfilter/nf_conntrack_pptp.c607
-rw-r--r--net/netfilter/nf_conntrack_proto.c410
-rw-r--r--net/netfilter/nf_conntrack_proto_generic.c47
-rw-r--r--net/netfilter/nf_conntrack_proto_gre.c305
-rw-r--r--net/netfilter/nf_conntrack_proto_sctp.c182
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c275
-rw-r--r--net/netfilter/nf_conntrack_proto_udp.c83
-rw-r--r--net/netfilter/nf_conntrack_sip.c531
-rw-r--r--net/netfilter/nf_conntrack_standalone.c444
-rw-r--r--net/netfilter/nf_conntrack_tftp.c160
-rw-r--r--net/netfilter/nf_sysctl.c134
-rw-r--r--net/netfilter/nfnetlink_log.c45
-rw-r--r--net/netfilter/nfnetlink_queue.c23
-rw-r--r--net/netfilter/x_tables.c1
-rw-r--r--net/netfilter/xt_CONNMARK.c27
-rw-r--r--net/netfilter/xt_CONNSECMARK.c14
-rw-r--r--net/netfilter/xt_MARK.c12
-rw-r--r--net/netfilter/xt_NFLOG.c86
-rw-r--r--net/netfilter/xt_connbytes.c14
-rw-r--r--net/netfilter/xt_connmark.c7
-rw-r--r--net/netfilter/xt_conntrack.c8
-rw-r--r--net/netfilter/xt_hashlimit.c (renamed from net/ipv4/netfilter/ipt_hashlimit.c)514
-rw-r--r--net/netfilter/xt_helper.c8
-rw-r--r--net/netfilter/xt_mark.c2
-rw-r--r--net/netfilter/xt_multiport.c9
-rw-r--r--net/netfilter/xt_physdev.c12
-rw-r--r--net/netfilter/xt_sctp.c2
-rw-r--r--net/netfilter/xt_state.c7
-rw-r--r--net/netfilter/xt_tcpudp.c20
-rw-r--r--net/netlabel/netlabel_cipso_v4.c90
-rw-r--r--net/netlabel/netlabel_domainhash.c48
-rw-r--r--net/netlabel/netlabel_kapi.c212
-rw-r--r--net/netlabel/netlabel_mgmt.c42
-rw-r--r--net/netlabel/netlabel_unlabeled.c48
-rw-r--r--net/netlabel/netlabel_user.c7
-rw-r--r--net/netlabel/netlabel_user.h31
-rw-r--r--net/netlink/af_netlink.c19
-rw-r--r--net/netlink/genetlink.c68
-rw-r--r--net/netrom/af_netrom.c15
-rw-r--r--net/netrom/nr_dev.c24
-rw-r--r--net/netrom/nr_route.c31
-rw-r--r--net/packet/af_packet.c21
-rw-r--r--net/rose/af_rose.c18
-rw-r--r--net/rose/rose_dev.c22
-rw-r--r--net/rose/rose_loopback.c5
-rw-r--r--net/rose/rose_route.c51
-rw-r--r--net/rxrpc/krxiod.c1
-rw-r--r--net/rxrpc/krxsecd.c1
-rw-r--r--net/rxrpc/krxtimod.c1
-rw-r--r--net/rxrpc/transport.c1
-rw-r--r--net/sched/Kconfig6
-rw-r--r--net/sched/Makefile3
-rw-r--r--net/sched/act_gact.c4
-rw-r--r--net/sched/act_ipt.c6
-rw-r--r--net/sched/act_police.c26
-rw-r--r--net/sched/act_simple.c3
-rw-r--r--net/sched/cls_api.c3
-rw-r--r--net/sched/cls_fw.c7
-rw-r--r--net/sched/cls_rsvp.h16
-rw-r--r--net/sched/cls_u32.c2
-rw-r--r--net/sched/em_meta.c13
-rw-r--r--net/sched/em_nbyte.c4
-rw-r--r--net/sched/ematch.c3
-rw-r--r--net/sched/sch_api.c41
-rw-r--r--net/sched/sch_atm.c5
-rw-r--r--net/sched/sch_cbq.c31
-rw-r--r--net/sched/sch_dsmark.c9
-rw-r--r--net/sched/sch_generic.c10
-rw-r--r--net/sched/sch_hfsc.c27
-rw-r--r--net/sched/sch_htb.c87
-rw-r--r--net/sched/sch_netem.c10
-rw-r--r--net/sched/sch_prio.c14
-rw-r--r--net/sched/sch_red.c14
-rw-r--r--net/sched/sch_sfq.c3
-rw-r--r--net/sched/sch_tbf.c16
-rw-r--r--net/sctp/associola.c34
-rw-r--r--net/sctp/bind_addr.c4
-rw-r--r--net/sctp/endpointola.c21
-rw-r--r--net/sctp/input.c6
-rw-r--r--net/sctp/inqueue.c9
-rw-r--r--net/sctp/ipv6.c62
-rw-r--r--net/sctp/outqueue.c4
-rw-r--r--net/sctp/proc.c6
-rw-r--r--net/sctp/protocol.c102
-rw-r--r--net/sctp/sm_make_chunk.c97
-rw-r--r--net/sctp/sm_sideeffect.c8
-rw-r--r--net/sctp/sm_statefuns.c87
-rw-r--r--net/sctp/sm_statetable.c696
-rw-r--r--net/sctp/socket.c233
-rw-r--r--net/sctp/tsnmap.c9
-rw-r--r--net/sctp/ulpevent.c26
-rw-r--r--net/socket.c43
-rw-r--r--net/sunrpc/auth_gss/auth_gss.c47
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_crypto.c101
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_mech.c21
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_seal.c55
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_unseal.c87
-rw-r--r--net/sunrpc/auth_gss/gss_krb5_wrap.c153
-rw-r--r--net/sunrpc/auth_gss/gss_spkm3_mech.c136
-rw-r--r--net/sunrpc/auth_gss/gss_spkm3_seal.c101
-rw-r--r--net/sunrpc/auth_gss/gss_spkm3_token.c6
-rw-r--r--net/sunrpc/auth_gss/gss_spkm3_unseal.c92
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c18
-rw-r--r--net/sunrpc/cache.c49
-rw-r--r--net/sunrpc/clnt.c73
-rw-r--r--net/sunrpc/pmap_clnt.c13
-rw-r--r--net/sunrpc/rpc_pipe.c22
-rw-r--r--net/sunrpc/sched.c149
-rw-r--r--net/sunrpc/socklib.c25
-rw-r--r--net/sunrpc/sunrpc_syms.c5
-rw-r--r--net/sunrpc/svc.c2
-rw-r--r--net/sunrpc/svcauth.c3
-rw-r--r--net/sunrpc/svcauth_unix.c13
-rw-r--r--net/sunrpc/svcsock.c32
-rw-r--r--net/sunrpc/sysctl.c50
-rw-r--r--net/sunrpc/xdr.c255
-rw-r--r--net/sunrpc/xprt.c40
-rw-r--r--net/sunrpc/xprtsock.c753
-rw-r--r--net/tipc/bcast.c6
-rw-r--r--net/tipc/config.c34
-rw-r--r--net/tipc/dbg.c3
-rw-r--r--net/tipc/handler.c2
-rw-r--r--net/tipc/name_distr.c10
-rw-r--r--net/tipc/node.c12
-rw-r--r--net/tipc/subscr.c3
-rw-r--r--net/unix/af_unix.c3
-rw-r--r--net/unix/garbage.c2
-rw-r--r--net/wanrouter/af_wanpipe.c4
-rw-r--r--net/wanrouter/wanmain.c59
-rw-r--r--net/x25/af_x25.c2
-rw-r--r--net/x25/x25_facilities.c12
-rw-r--r--net/xfrm/xfrm_algo.c20
-rw-r--r--net/xfrm/xfrm_input.c4
-rw-r--r--net/xfrm/xfrm_policy.c225
-rw-r--r--net/xfrm/xfrm_state.c52
-rw-r--r--net/xfrm/xfrm_user.c211
451 files changed, 24573 insertions, 10677 deletions
diff --git a/net/802/hippi.c b/net/802/hippi.c
index 6d7fed3dd9..579e2ddf5e 100644
--- a/net/802/hippi.c
+++ b/net/802/hippi.c
@@ -36,7 +36,6 @@
36#include <net/arp.h> 36#include <net/arp.h>
37#include <net/sock.h> 37#include <net/sock.h>
38#include <asm/uaccess.h> 38#include <asm/uaccess.h>
39#include <asm/checksum.h>
40#include <asm/system.h> 39#include <asm/system.h>
41 40
42/* 41/*
diff --git a/net/Kconfig b/net/Kconfig
index 67e39ad8b8..7dfc949206 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -75,7 +75,7 @@ config NETWORK_SECMARK
75 If you are unsure how to answer this question, answer N. 75 If you are unsure how to answer this question, answer N.
76 76
77menuconfig NETFILTER 77menuconfig NETFILTER
78 bool "Network packet filtering (replaces ipchains)" 78 bool "Network packet filtering framework (Netfilter)"
79 ---help--- 79 ---help---
80 Netfilter is a framework for filtering and mangling network packets 80 Netfilter is a framework for filtering and mangling network packets
81 that pass through your Linux box. 81 that pass through your Linux box.
@@ -175,33 +175,6 @@ source "net/ipx/Kconfig"
175source "drivers/net/appletalk/Kconfig" 175source "drivers/net/appletalk/Kconfig"
176source "net/x25/Kconfig" 176source "net/x25/Kconfig"
177source "net/lapb/Kconfig" 177source "net/lapb/Kconfig"
178
179config NET_DIVERT
180 bool "Frame Diverter (EXPERIMENTAL)"
181 depends on EXPERIMENTAL && BROKEN
182 ---help---
183 The Frame Diverter allows you to divert packets from the
184 network, that are not aimed at the interface receiving it (in
185 promisc. mode). Typically, a Linux box setup as an Ethernet bridge
186 with the Frames Diverter on, can do some *really* transparent www
187 caching using a Squid proxy for example.
188
189 This is very useful when you don't want to change your router's
190 config (or if you simply don't have access to it).
191
192 The other possible usages of diverting Ethernet Frames are
193 numberous:
194 - reroute smtp traffic to another interface
195 - traffic-shape certain network streams
196 - transparently proxy smtp connections
197 - etc...
198
199 For more informations, please refer to:
200 <http://diverter.sourceforge.net/>
201 <http://perso.wanadoo.fr/magpie/EtherDivert.html>
202
203 If unsure, say N.
204
205source "net/econet/Kconfig" 178source "net/econet/Kconfig"
206source "net/wanrouter/Kconfig" 179source "net/wanrouter/Kconfig"
207source "net/sched/Kconfig" 180source "net/sched/Kconfig"
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 485e35c3b2..3a70522077 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -61,6 +61,7 @@
61#include <net/tcp_states.h> 61#include <net/tcp_states.h>
62#include <net/route.h> 62#include <net/route.h>
63#include <linux/atalk.h> 63#include <linux/atalk.h>
64#include "../core/kmap_skb.h"
64 65
65struct datalink_proto *ddp_dl, *aarp_dl; 66struct datalink_proto *ddp_dl, *aarp_dl;
66static const struct proto_ops atalk_dgram_ops; 67static const struct proto_ops atalk_dgram_ops;
diff --git a/net/atm/Makefile b/net/atm/Makefile
index 89656d6c0b..cc50bd1ff1 100644
--- a/net/atm/Makefile
+++ b/net/atm/Makefile
@@ -7,10 +7,7 @@ mpoa-objs := mpc.o mpoa_caches.o mpoa_proc.o
7 7
8obj-$(CONFIG_ATM) += atm.o 8obj-$(CONFIG_ATM) += atm.o
9obj-$(CONFIG_ATM_CLIP) += clip.o 9obj-$(CONFIG_ATM_CLIP) += clip.o
10atm-$(subst m,y,$(CONFIG_ATM_CLIP)) += ipcommon.o
11obj-$(CONFIG_ATM_BR2684) += br2684.o 10obj-$(CONFIG_ATM_BR2684) += br2684.o
12atm-$(subst m,y,$(CONFIG_ATM_BR2684)) += ipcommon.o
13atm-$(subst m,y,$(CONFIG_NET_SCH_ATM)) += ipcommon.o
14atm-$(CONFIG_PROC_FS) += proc.o 11atm-$(CONFIG_PROC_FS) += proc.o
15 12
16obj-$(CONFIG_ATM_LANE) += lec.o 13obj-$(CONFIG_ATM_LANE) += lec.o
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index d00cca97eb..83a1c1b1d6 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -23,7 +23,6 @@ Author: Marcell GAL, 2000, XDSL Ltd, Hungary
23#include <linux/atmbr2684.h> 23#include <linux/atmbr2684.h>
24 24
25#include "common.h" 25#include "common.h"
26#include "ipcommon.h"
27 26
28/* 27/*
29 * Define this to use a version of the code which interacts with the higher 28 * Define this to use a version of the code which interacts with the higher
@@ -372,7 +371,7 @@ static int br2684_setfilt(struct atm_vcc *atmvcc, void __user *arg)
372 371
373/* Returns 1 if packet should be dropped */ 372/* Returns 1 if packet should be dropped */
374static inline int 373static inline int
375packet_fails_filter(u16 type, struct br2684_vcc *brvcc, struct sk_buff *skb) 374packet_fails_filter(__be16 type, struct br2684_vcc *brvcc, struct sk_buff *skb)
376{ 375{
377 if (brvcc->filter.netmask == 0) 376 if (brvcc->filter.netmask == 0)
378 return 0; /* no filter in place */ 377 return 0; /* no filter in place */
@@ -500,11 +499,12 @@ Note: we do not have explicit unassign, but look at _push()
500*/ 499*/
501 int err; 500 int err;
502 struct br2684_vcc *brvcc; 501 struct br2684_vcc *brvcc;
503 struct sk_buff_head copy;
504 struct sk_buff *skb; 502 struct sk_buff *skb;
503 struct sk_buff_head *rq;
505 struct br2684_dev *brdev; 504 struct br2684_dev *brdev;
506 struct net_device *net_dev; 505 struct net_device *net_dev;
507 struct atm_backend_br2684 be; 506 struct atm_backend_br2684 be;
507 unsigned long flags;
508 508
509 if (copy_from_user(&be, arg, sizeof be)) 509 if (copy_from_user(&be, arg, sizeof be))
510 return -EFAULT; 510 return -EFAULT;
@@ -554,12 +554,30 @@ Note: we do not have explicit unassign, but look at _push()
554 brvcc->old_push = atmvcc->push; 554 brvcc->old_push = atmvcc->push;
555 barrier(); 555 barrier();
556 atmvcc->push = br2684_push; 556 atmvcc->push = br2684_push;
557 skb_queue_head_init(&copy); 557
558 skb_migrate(&sk_atm(atmvcc)->sk_receive_queue, &copy); 558 rq = &sk_atm(atmvcc)->sk_receive_queue;
559 while ((skb = skb_dequeue(&copy)) != NULL) { 559
560 spin_lock_irqsave(&rq->lock, flags);
561 if (skb_queue_empty(rq)) {
562 skb = NULL;
563 } else {
564 /* NULL terminate the list. */
565 rq->prev->next = NULL;
566 skb = rq->next;
567 }
568 rq->prev = rq->next = (struct sk_buff *)rq;
569 rq->qlen = 0;
570 spin_unlock_irqrestore(&rq->lock, flags);
571
572 while (skb) {
573 struct sk_buff *next = skb->next;
574
575 skb->next = skb->prev = NULL;
560 BRPRIV(skb->dev)->stats.rx_bytes -= skb->len; 576 BRPRIV(skb->dev)->stats.rx_bytes -= skb->len;
561 BRPRIV(skb->dev)->stats.rx_packets--; 577 BRPRIV(skb->dev)->stats.rx_packets--;
562 br2684_push(atmvcc, skb); 578 br2684_push(atmvcc, skb);
579
580 skb = next;
563 } 581 }
564 __module_get(THIS_MODULE); 582 __module_get(THIS_MODULE);
565 return 0; 583 return 0;
diff --git a/net/atm/clip.c b/net/atm/clip.c
index 7af2c411da..5f8a1d2227 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -38,7 +38,6 @@
38 38
39#include "common.h" 39#include "common.h"
40#include "resources.h" 40#include "resources.h"
41#include "ipcommon.h"
42#include <net/atmclip.h> 41#include <net/atmclip.h>
43 42
44 43
@@ -54,7 +53,7 @@ static struct atm_vcc *atmarpd;
54static struct neigh_table clip_tbl; 53static struct neigh_table clip_tbl;
55static struct timer_list idle_timer; 54static struct timer_list idle_timer;
56 55
57static int to_atmarpd(enum atmarp_ctrl_type type, int itf, unsigned long ip) 56static int to_atmarpd(enum atmarp_ctrl_type type, int itf, __be32 ip)
58{ 57{
59 struct sock *sk; 58 struct sock *sk;
60 struct atmarp_ctrl *ctrl; 59 struct atmarp_ctrl *ctrl;
@@ -220,7 +219,7 @@ static void clip_push(struct atm_vcc *vcc, struct sk_buff *skb)
220 || memcmp(skb->data, llc_oui, sizeof (llc_oui))) 219 || memcmp(skb->data, llc_oui, sizeof (llc_oui)))
221 skb->protocol = htons(ETH_P_IP); 220 skb->protocol = htons(ETH_P_IP);
222 else { 221 else {
223 skb->protocol = ((u16 *) skb->data)[3]; 222 skb->protocol = ((__be16 *) skb->data)[3];
224 skb_pull(skb, RFC1483LLC_LEN); 223 skb_pull(skb, RFC1483LLC_LEN);
225 if (skb->protocol == htons(ETH_P_ARP)) { 224 if (skb->protocol == htons(ETH_P_ARP)) {
226 PRIV(skb->dev)->stats.rx_packets++; 225 PRIV(skb->dev)->stats.rx_packets++;
@@ -430,7 +429,7 @@ static int clip_start_xmit(struct sk_buff *skb, struct net_device *dev)
430 429
431 here = skb_push(skb, RFC1483LLC_LEN); 430 here = skb_push(skb, RFC1483LLC_LEN);
432 memcpy(here, llc_oui, sizeof(llc_oui)); 431 memcpy(here, llc_oui, sizeof(llc_oui));
433 ((u16 *) here)[3] = skb->protocol; 432 ((__be16 *) here)[3] = skb->protocol;
434 } 433 }
435 atomic_add(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc); 434 atomic_add(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);
436 ATM_SKB(skb)->atm_options = vcc->atm_options; 435 ATM_SKB(skb)->atm_options = vcc->atm_options;
@@ -469,8 +468,9 @@ static struct net_device_stats *clip_get_stats(struct net_device *dev)
469static int clip_mkip(struct atm_vcc *vcc, int timeout) 468static int clip_mkip(struct atm_vcc *vcc, int timeout)
470{ 469{
471 struct clip_vcc *clip_vcc; 470 struct clip_vcc *clip_vcc;
472 struct sk_buff_head copy;
473 struct sk_buff *skb; 471 struct sk_buff *skb;
472 struct sk_buff_head *rq;
473 unsigned long flags;
474 474
475 if (!vcc->push) 475 if (!vcc->push)
476 return -EBADFD; 476 return -EBADFD;
@@ -490,10 +490,26 @@ static int clip_mkip(struct atm_vcc *vcc, int timeout)
490 clip_vcc->old_pop = vcc->pop; 490 clip_vcc->old_pop = vcc->pop;
491 vcc->push = clip_push; 491 vcc->push = clip_push;
492 vcc->pop = clip_pop; 492 vcc->pop = clip_pop;
493 skb_queue_head_init(&copy); 493
494 skb_migrate(&sk_atm(vcc)->sk_receive_queue, &copy); 494 rq = &sk_atm(vcc)->sk_receive_queue;
495
496 spin_lock_irqsave(&rq->lock, flags);
497 if (skb_queue_empty(rq)) {
498 skb = NULL;
499 } else {
500 /* NULL terminate the list. */
501 rq->prev->next = NULL;
502 skb = rq->next;
503 }
504 rq->prev = rq->next = (struct sk_buff *)rq;
505 rq->qlen = 0;
506 spin_unlock_irqrestore(&rq->lock, flags);
507
495 /* re-process everything received between connection setup and MKIP */ 508 /* re-process everything received between connection setup and MKIP */
496 while ((skb = skb_dequeue(&copy)) != NULL) 509 while (skb) {
510 struct sk_buff *next = skb->next;
511
512 skb->next = skb->prev = NULL;
497 if (!clip_devs) { 513 if (!clip_devs) {
498 atm_return(vcc, skb->truesize); 514 atm_return(vcc, skb->truesize);
499 kfree_skb(skb); 515 kfree_skb(skb);
@@ -506,10 +522,13 @@ static int clip_mkip(struct atm_vcc *vcc, int timeout)
506 PRIV(skb->dev)->stats.rx_bytes -= len; 522 PRIV(skb->dev)->stats.rx_bytes -= len;
507 kfree_skb(skb); 523 kfree_skb(skb);
508 } 524 }
525
526 skb = next;
527 }
509 return 0; 528 return 0;
510} 529}
511 530
512static int clip_setentry(struct atm_vcc *vcc, u32 ip) 531static int clip_setentry(struct atm_vcc *vcc, __be32 ip)
513{ 532{
514 struct neighbour *neigh; 533 struct neighbour *neigh;
515 struct atmarp_entry *entry; 534 struct atmarp_entry *entry;
@@ -752,7 +771,7 @@ static int clip_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
752 err = clip_mkip(vcc, arg); 771 err = clip_mkip(vcc, arg);
753 break; 772 break;
754 case ATMARP_SETENTRY: 773 case ATMARP_SETENTRY:
755 err = clip_setentry(vcc, arg); 774 err = clip_setentry(vcc, (__force __be32)arg);
756 break; 775 break;
757 case ATMARP_ENCAP: 776 case ATMARP_ENCAP:
758 err = clip_encap(vcc, arg); 777 err = clip_encap(vcc, arg);
diff --git a/net/atm/ipcommon.c b/net/atm/ipcommon.c
deleted file mode 100644
index 1d3de42fad..0000000000
--- a/net/atm/ipcommon.c
+++ /dev/null
@@ -1,63 +0,0 @@
1/* net/atm/ipcommon.c - Common items for all ways of doing IP over ATM */
2
3/* Written 1996-2000 by Werner Almesberger, EPFL LRC/ICA */
4
5
6#include <linux/module.h>
7#include <linux/string.h>
8#include <linux/skbuff.h>
9#include <linux/netdevice.h>
10#include <linux/in.h>
11#include <linux/atmdev.h>
12#include <linux/atmclip.h>
13
14#include "common.h"
15#include "ipcommon.h"
16
17
18#if 0
19#define DPRINTK(format,args...) printk(KERN_DEBUG format,##args)
20#else
21#define DPRINTK(format,args...)
22#endif
23
24
25/*
26 * skb_migrate appends the list at "from" to "to", emptying "from" in the
27 * process. skb_migrate is atomic with respect to all other skb operations on
28 * "from" and "to". Note that it locks both lists at the same time, so to deal
29 * with the lock ordering, the locks are taken in address order.
30 *
31 * This function should live in skbuff.c or skbuff.h.
32 */
33
34
35void skb_migrate(struct sk_buff_head *from, struct sk_buff_head *to)
36{
37 unsigned long flags;
38 struct sk_buff *skb_from = (struct sk_buff *) from;
39 struct sk_buff *skb_to = (struct sk_buff *) to;
40 struct sk_buff *prev;
41
42 if ((unsigned long) from < (unsigned long) to) {
43 spin_lock_irqsave(&from->lock, flags);
44 spin_lock_nested(&to->lock, SINGLE_DEPTH_NESTING);
45 } else {
46 spin_lock_irqsave(&to->lock, flags);
47 spin_lock_nested(&from->lock, SINGLE_DEPTH_NESTING);
48 }
49 prev = from->prev;
50 from->next->prev = to->prev;
51 prev->next = skb_to;
52 to->prev->next = from->next;
53 to->prev = from->prev;
54 to->qlen += from->qlen;
55 spin_unlock(&to->lock);
56 from->prev = skb_from;
57 from->next = skb_from;
58 from->qlen = 0;
59 spin_unlock_irqrestore(&from->lock, flags);
60}
61
62
63EXPORT_SYMBOL(skb_migrate);
diff --git a/net/atm/ipcommon.h b/net/atm/ipcommon.h
deleted file mode 100644
index d72165f609..0000000000
--- a/net/atm/ipcommon.h
+++ /dev/null
@@ -1,22 +0,0 @@
1/* net/atm/ipcommon.h - Common items for all ways of doing IP over ATM */
2
3/* Written 1996-2000 by Werner Almesberger, EPFL LRC/ICA */
4
5
6#ifndef NET_ATM_IPCOMMON_H
7#define NET_ATM_IPCOMMON_H
8
9
10#include <linux/string.h>
11#include <linux/skbuff.h>
12#include <linux/netdevice.h>
13#include <linux/atmdev.h>
14
15/*
16 * Appends all skbs from "from" to "to". The operation is atomic with respect
17 * to all other skb operations on "from" or "to".
18 */
19
20void skb_migrate(struct sk_buff_head *from,struct sk_buff_head *to);
21
22#endif
diff --git a/net/atm/lec.c b/net/atm/lec.c
index 66c57c1091..3fc0abeeaf 100644
--- a/net/atm/lec.c
+++ b/net/atm/lec.c
@@ -204,9 +204,9 @@ static unsigned char *get_tr_dst(unsigned char *packet, unsigned char *rdesc)
204 memset(rdesc, 0, ETH_ALEN); 204 memset(rdesc, 0, ETH_ALEN);
205 /* offset 4 comes from LAN destination field in LE control frames */ 205 /* offset 4 comes from LAN destination field in LE control frames */
206 if (trh->rcf & htons((uint16_t) TR_RCF_DIR_BIT)) 206 if (trh->rcf & htons((uint16_t) TR_RCF_DIR_BIT))
207 memcpy(&rdesc[4], &trh->rseg[num_rdsc - 2], sizeof(uint16_t)); 207 memcpy(&rdesc[4], &trh->rseg[num_rdsc - 2], sizeof(__be16));
208 else { 208 else {
209 memcpy(&rdesc[4], &trh->rseg[1], sizeof(uint16_t)); 209 memcpy(&rdesc[4], &trh->rseg[1], sizeof(__be16));
210 rdesc[5] = ((ntohs(trh->rseg[0]) & 0x000f) | (rdesc[5] & 0xf0)); 210 rdesc[5] = ((ntohs(trh->rseg[0]) & 0x000f) | (rdesc[5] & 0xf0));
211 } 211 }
212 212
@@ -775,7 +775,7 @@ static void lec_push(struct atm_vcc *vcc, struct sk_buff *skb)
775 unsigned char *src, *dst; 775 unsigned char *src, *dst;
776 776
777 atm_return(vcc, skb->truesize); 777 atm_return(vcc, skb->truesize);
778 if (*(uint16_t *) skb->data == htons(priv->lecid) || 778 if (*(__be16 *) skb->data == htons(priv->lecid) ||
779 !priv->lecd || !(dev->flags & IFF_UP)) { 779 !priv->lecd || !(dev->flags & IFF_UP)) {
780 /* 780 /*
781 * Probably looping back, or if lecd is missing, 781 * Probably looping back, or if lecd is missing,
@@ -1321,11 +1321,10 @@ static int lane2_resolve(struct net_device *dev, u8 *dst_mac, int force,
1321 if (table == NULL) 1321 if (table == NULL)
1322 return -1; 1322 return -1;
1323 1323
1324 *tlvs = kmalloc(table->sizeoftlvs, GFP_ATOMIC); 1324 *tlvs = kmemdup(table->tlvs, table->sizeoftlvs, GFP_ATOMIC);
1325 if (*tlvs == NULL) 1325 if (*tlvs == NULL)
1326 return -1; 1326 return -1;
1327 1327
1328 memcpy(*tlvs, table->tlvs, table->sizeoftlvs);
1329 *sizeoftlvs = table->sizeoftlvs; 1328 *sizeoftlvs = table->sizeoftlvs;
1330 1329
1331 return 0; 1330 return 0;
@@ -1364,11 +1363,10 @@ static int lane2_associate_req(struct net_device *dev, u8 *lan_dst,
1364 1363
1365 kfree(priv->tlvs); /* NULL if there was no previous association */ 1364 kfree(priv->tlvs); /* NULL if there was no previous association */
1366 1365
1367 priv->tlvs = kmalloc(sizeoftlvs, GFP_KERNEL); 1366 priv->tlvs = kmemdup(tlvs, sizeoftlvs, GFP_KERNEL);
1368 if (priv->tlvs == NULL) 1367 if (priv->tlvs == NULL)
1369 return (0); 1368 return (0);
1370 priv->sizeoftlvs = sizeoftlvs; 1369 priv->sizeoftlvs = sizeoftlvs;
1371 memcpy(priv->tlvs, tlvs, sizeoftlvs);
1372 1370
1373 skb = alloc_skb(sizeoftlvs, GFP_ATOMIC); 1371 skb = alloc_skb(sizeoftlvs, GFP_ATOMIC);
1374 if (skb == NULL) 1372 if (skb == NULL)
@@ -1409,12 +1407,10 @@ static void lane2_associate_ind(struct net_device *dev, u8 *mac_addr,
1409 1407
1410 kfree(entry->tlvs); 1408 kfree(entry->tlvs);
1411 1409
1412 entry->tlvs = kmalloc(sizeoftlvs, GFP_KERNEL); 1410 entry->tlvs = kmemdup(tlvs, sizeoftlvs, GFP_KERNEL);
1413 if (entry->tlvs == NULL) 1411 if (entry->tlvs == NULL)
1414 return; 1412 return;
1415
1416 entry->sizeoftlvs = sizeoftlvs; 1413 entry->sizeoftlvs = sizeoftlvs;
1417 memcpy(entry->tlvs, tlvs, sizeoftlvs);
1418#endif 1414#endif
1419#if 0 1415#if 0
1420 printk("lec.c: lane2_associate_ind()\n"); 1416 printk("lec.c: lane2_associate_ind()\n");
@@ -1458,7 +1454,7 @@ static void lane2_associate_ind(struct net_device *dev, u8 *mac_addr,
1458 1454
1459#define LEC_ARP_REFRESH_INTERVAL (3*HZ) 1455#define LEC_ARP_REFRESH_INTERVAL (3*HZ)
1460 1456
1461static void lec_arp_check_expire(void *data); 1457static void lec_arp_check_expire(struct work_struct *work);
1462static void lec_arp_expire_arp(unsigned long data); 1458static void lec_arp_expire_arp(unsigned long data);
1463 1459
1464/* 1460/*
@@ -1481,7 +1477,7 @@ static void lec_arp_init(struct lec_priv *priv)
1481 INIT_HLIST_HEAD(&priv->lec_no_forward); 1477 INIT_HLIST_HEAD(&priv->lec_no_forward);
1482 INIT_HLIST_HEAD(&priv->mcast_fwds); 1478 INIT_HLIST_HEAD(&priv->mcast_fwds);
1483 spin_lock_init(&priv->lec_arp_lock); 1479 spin_lock_init(&priv->lec_arp_lock);
1484 INIT_WORK(&priv->lec_arp_work, lec_arp_check_expire, priv); 1480 INIT_DELAYED_WORK(&priv->lec_arp_work, lec_arp_check_expire);
1485 schedule_delayed_work(&priv->lec_arp_work, LEC_ARP_REFRESH_INTERVAL); 1481 schedule_delayed_work(&priv->lec_arp_work, LEC_ARP_REFRESH_INTERVAL);
1486} 1482}
1487 1483
@@ -1879,10 +1875,11 @@ static void lec_arp_expire_vcc(unsigned long data)
1879 * to ESI_FORWARD_DIRECT. This causes the flush period to end 1875 * to ESI_FORWARD_DIRECT. This causes the flush period to end
1880 * regardless of the progress of the flush protocol. 1876 * regardless of the progress of the flush protocol.
1881 */ 1877 */
1882static void lec_arp_check_expire(void *data) 1878static void lec_arp_check_expire(struct work_struct *work)
1883{ 1879{
1884 unsigned long flags; 1880 unsigned long flags;
1885 struct lec_priv *priv = data; 1881 struct lec_priv *priv =
1882 container_of(work, struct lec_priv, lec_arp_work.work);
1886 struct hlist_node *node, *next; 1883 struct hlist_node *node, *next;
1887 struct lec_arp_table *entry; 1884 struct lec_arp_table *entry;
1888 unsigned long now; 1885 unsigned long now;
diff --git a/net/atm/lec.h b/net/atm/lec.h
index 877f509396..99136babd5 100644
--- a/net/atm/lec.h
+++ b/net/atm/lec.h
@@ -14,14 +14,14 @@
14#define LEC_HEADER_LEN 16 14#define LEC_HEADER_LEN 16
15 15
16struct lecdatahdr_8023 { 16struct lecdatahdr_8023 {
17 unsigned short le_header; 17 __be16 le_header;
18 unsigned char h_dest[ETH_ALEN]; 18 unsigned char h_dest[ETH_ALEN];
19 unsigned char h_source[ETH_ALEN]; 19 unsigned char h_source[ETH_ALEN];
20 unsigned short h_type; 20 __be16 h_type;
21}; 21};
22 22
23struct lecdatahdr_8025 { 23struct lecdatahdr_8025 {
24 unsigned short le_header; 24 __be16 le_header;
25 unsigned char ac_pad; 25 unsigned char ac_pad;
26 unsigned char fc; 26 unsigned char fc;
27 unsigned char h_dest[ETH_ALEN]; 27 unsigned char h_dest[ETH_ALEN];
@@ -92,7 +92,7 @@ struct lec_priv {
92 spinlock_t lec_arp_lock; 92 spinlock_t lec_arp_lock;
93 struct atm_vcc *mcast_vcc; /* Default Multicast Send VCC */ 93 struct atm_vcc *mcast_vcc; /* Default Multicast Send VCC */
94 struct atm_vcc *lecd; 94 struct atm_vcc *lecd;
95 struct work_struct lec_arp_work; /* C10 */ 95 struct delayed_work lec_arp_work; /* C10 */
96 unsigned int maximum_unknown_frame_count; 96 unsigned int maximum_unknown_frame_count;
97 /* 97 /*
98 * Within the period of time defined by this variable, the client will send 98 * Within the period of time defined by this variable, the client will send
diff --git a/net/atm/mpc.c b/net/atm/mpc.c
index 0d2b994af5..c18f73715e 100644
--- a/net/atm/mpc.c
+++ b/net/atm/mpc.c
@@ -152,7 +152,7 @@ static struct mpoa_client *find_mpc_by_lec(struct net_device *dev)
152/* 152/*
153 * Overwrites the old entry or makes a new one. 153 * Overwrites the old entry or makes a new one.
154 */ 154 */
155struct atm_mpoa_qos *atm_mpoa_add_qos(uint32_t dst_ip, struct atm_qos *qos) 155struct atm_mpoa_qos *atm_mpoa_add_qos(__be32 dst_ip, struct atm_qos *qos)
156{ 156{
157 struct atm_mpoa_qos *entry; 157 struct atm_mpoa_qos *entry;
158 158
@@ -177,7 +177,7 @@ struct atm_mpoa_qos *atm_mpoa_add_qos(uint32_t dst_ip, struct atm_qos *qos)
177 return entry; 177 return entry;
178} 178}
179 179
180struct atm_mpoa_qos *atm_mpoa_search_qos(uint32_t dst_ip) 180struct atm_mpoa_qos *atm_mpoa_search_qos(__be32 dst_ip)
181{ 181{
182 struct atm_mpoa_qos *qos; 182 struct atm_mpoa_qos *qos;
183 183
@@ -460,11 +460,11 @@ static int send_via_shortcut(struct sk_buff *skb, struct mpoa_client *mpc)
460 in_cache_entry *entry; 460 in_cache_entry *entry;
461 struct iphdr *iph; 461 struct iphdr *iph;
462 char *buff; 462 char *buff;
463 uint32_t ipaddr = 0; 463 __be32 ipaddr = 0;
464 464
465 static struct { 465 static struct {
466 struct llc_snap_hdr hdr; 466 struct llc_snap_hdr hdr;
467 uint32_t tag; 467 __be32 tag;
468 } tagged_llc_snap_hdr = { 468 } tagged_llc_snap_hdr = {
469 {0xaa, 0xaa, 0x03, {0x00, 0x00, 0x00}, {0x88, 0x4c}}, 469 {0xaa, 0xaa, 0x03, {0x00, 0x00, 0x00}, {0x88, 0x4c}},
470 0 470 0
@@ -559,7 +559,7 @@ static int atm_mpoa_vcc_attach(struct atm_vcc *vcc, void __user *arg)
559 struct mpoa_client *mpc; 559 struct mpoa_client *mpc;
560 struct atmmpc_ioc ioc_data; 560 struct atmmpc_ioc ioc_data;
561 in_cache_entry *in_entry; 561 in_cache_entry *in_entry;
562 uint32_t ipaddr; 562 __be32 ipaddr;
563 563
564 bytes_left = copy_from_user(&ioc_data, arg, sizeof(struct atmmpc_ioc)); 564 bytes_left = copy_from_user(&ioc_data, arg, sizeof(struct atmmpc_ioc));
565 if (bytes_left != 0) { 565 if (bytes_left != 0) {
@@ -638,7 +638,7 @@ static void mpc_push(struct atm_vcc *vcc, struct sk_buff *skb)
638 struct sk_buff *new_skb; 638 struct sk_buff *new_skb;
639 eg_cache_entry *eg; 639 eg_cache_entry *eg;
640 struct mpoa_client *mpc; 640 struct mpoa_client *mpc;
641 uint32_t tag; 641 __be32 tag;
642 char *tmp; 642 char *tmp;
643 643
644 ddprintk("mpoa: (%s) mpc_push:\n", dev->name); 644 ddprintk("mpoa: (%s) mpc_push:\n", dev->name);
@@ -683,7 +683,7 @@ static void mpc_push(struct atm_vcc *vcc, struct sk_buff *skb)
683 } 683 }
684 684
685 tmp = skb->data + sizeof(struct llc_snap_hdr); 685 tmp = skb->data + sizeof(struct llc_snap_hdr);
686 tag = *(uint32_t *)tmp; 686 tag = *(__be32 *)tmp;
687 687
688 eg = mpc->eg_ops->get_by_tag(tag, mpc); 688 eg = mpc->eg_ops->get_by_tag(tag, mpc);
689 if (eg == NULL) { 689 if (eg == NULL) {
@@ -1029,7 +1029,7 @@ static int mpoa_event_listener(struct notifier_block *mpoa_notifier, unsigned lo
1029 1029
1030static void MPOA_trigger_rcvd(struct k_message *msg, struct mpoa_client *mpc) 1030static void MPOA_trigger_rcvd(struct k_message *msg, struct mpoa_client *mpc)
1031{ 1031{
1032 uint32_t dst_ip = msg->content.in_info.in_dst_ip; 1032 __be32 dst_ip = msg->content.in_info.in_dst_ip;
1033 in_cache_entry *entry; 1033 in_cache_entry *entry;
1034 1034
1035 entry = mpc->in_ops->get(dst_ip, mpc); 1035 entry = mpc->in_ops->get(dst_ip, mpc);
@@ -1066,7 +1066,7 @@ static void MPOA_trigger_rcvd(struct k_message *msg, struct mpoa_client *mpc)
1066 */ 1066 */
1067static void check_qos_and_open_shortcut(struct k_message *msg, struct mpoa_client *client, in_cache_entry *entry) 1067static void check_qos_and_open_shortcut(struct k_message *msg, struct mpoa_client *client, in_cache_entry *entry)
1068{ 1068{
1069 uint32_t dst_ip = msg->content.in_info.in_dst_ip; 1069 __be32 dst_ip = msg->content.in_info.in_dst_ip;
1070 struct atm_mpoa_qos *qos = atm_mpoa_search_qos(dst_ip); 1070 struct atm_mpoa_qos *qos = atm_mpoa_search_qos(dst_ip);
1071 eg_cache_entry *eg_entry = client->eg_ops->get_by_src_ip(dst_ip, client); 1071 eg_cache_entry *eg_entry = client->eg_ops->get_by_src_ip(dst_ip, client);
1072 1072
@@ -1102,7 +1102,7 @@ static void check_qos_and_open_shortcut(struct k_message *msg, struct mpoa_clien
1102 1102
1103static void MPOA_res_reply_rcvd(struct k_message *msg, struct mpoa_client *mpc) 1103static void MPOA_res_reply_rcvd(struct k_message *msg, struct mpoa_client *mpc)
1104{ 1104{
1105 uint32_t dst_ip = msg->content.in_info.in_dst_ip; 1105 __be32 dst_ip = msg->content.in_info.in_dst_ip;
1106 in_cache_entry *entry = mpc->in_ops->get(dst_ip, mpc); 1106 in_cache_entry *entry = mpc->in_ops->get(dst_ip, mpc);
1107 1107
1108 dprintk("mpoa: (%s) MPOA_res_reply_rcvd: ip %u.%u.%u.%u\n", mpc->dev->name, NIPQUAD(dst_ip)); 1108 dprintk("mpoa: (%s) MPOA_res_reply_rcvd: ip %u.%u.%u.%u\n", mpc->dev->name, NIPQUAD(dst_ip));
@@ -1148,8 +1148,8 @@ static void MPOA_res_reply_rcvd(struct k_message *msg, struct mpoa_client *mpc)
1148 1148
1149static void ingress_purge_rcvd(struct k_message *msg, struct mpoa_client *mpc) 1149static void ingress_purge_rcvd(struct k_message *msg, struct mpoa_client *mpc)
1150{ 1150{
1151 uint32_t dst_ip = msg->content.in_info.in_dst_ip; 1151 __be32 dst_ip = msg->content.in_info.in_dst_ip;
1152 uint32_t mask = msg->ip_mask; 1152 __be32 mask = msg->ip_mask;
1153 in_cache_entry *entry = mpc->in_ops->get_with_mask(dst_ip, mpc, mask); 1153 in_cache_entry *entry = mpc->in_ops->get_with_mask(dst_ip, mpc, mask);
1154 1154
1155 if(entry == NULL){ 1155 if(entry == NULL){
@@ -1173,7 +1173,7 @@ static void ingress_purge_rcvd(struct k_message *msg, struct mpoa_client *mpc)
1173 1173
1174static void egress_purge_rcvd(struct k_message *msg, struct mpoa_client *mpc) 1174static void egress_purge_rcvd(struct k_message *msg, struct mpoa_client *mpc)
1175{ 1175{
1176 uint32_t cache_id = msg->content.eg_info.cache_id; 1176 __be32 cache_id = msg->content.eg_info.cache_id;
1177 eg_cache_entry *entry = mpc->eg_ops->get_by_cache_id(cache_id, mpc); 1177 eg_cache_entry *entry = mpc->eg_ops->get_by_cache_id(cache_id, mpc);
1178 1178
1179 if (entry == NULL) { 1179 if (entry == NULL) {
@@ -1322,13 +1322,12 @@ static void set_mps_mac_addr_rcvd(struct k_message *msg, struct mpoa_client *cli
1322 if(client->number_of_mps_macs) 1322 if(client->number_of_mps_macs)
1323 kfree(client->mps_macs); 1323 kfree(client->mps_macs);
1324 client->number_of_mps_macs = 0; 1324 client->number_of_mps_macs = 0;
1325 client->mps_macs = kmalloc(ETH_ALEN,GFP_KERNEL); 1325 client->mps_macs = kmemdup(msg->MPS_ctrl, ETH_ALEN, GFP_KERNEL);
1326 if (client->mps_macs == NULL) { 1326 if (client->mps_macs == NULL) {
1327 printk("mpoa: set_mps_mac_addr_rcvd: out of memory\n"); 1327 printk("mpoa: set_mps_mac_addr_rcvd: out of memory\n");
1328 return; 1328 return;
1329 } 1329 }
1330 client->number_of_mps_macs = 1; 1330 client->number_of_mps_macs = 1;
1331 memcpy(client->mps_macs, msg->MPS_ctrl, ETH_ALEN);
1332 1331
1333 return; 1332 return;
1334} 1333}
diff --git a/net/atm/mpc.h b/net/atm/mpc.h
index 3c7981a229..51f460d005 100644
--- a/net/atm/mpc.h
+++ b/net/atm/mpc.h
@@ -36,14 +36,14 @@ struct mpoa_client {
36 36
37struct atm_mpoa_qos { 37struct atm_mpoa_qos {
38 struct atm_mpoa_qos *next; 38 struct atm_mpoa_qos *next;
39 uint32_t ipaddr; 39 __be32 ipaddr;
40 struct atm_qos qos; 40 struct atm_qos qos;
41}; 41};
42 42
43 43
44/* MPOA QoS operations */ 44/* MPOA QoS operations */
45struct atm_mpoa_qos *atm_mpoa_add_qos(uint32_t dst_ip, struct atm_qos *qos); 45struct atm_mpoa_qos *atm_mpoa_add_qos(__be32 dst_ip, struct atm_qos *qos);
46struct atm_mpoa_qos *atm_mpoa_search_qos(uint32_t dst_ip); 46struct atm_mpoa_qos *atm_mpoa_search_qos(__be32 dst_ip);
47int atm_mpoa_delete_qos(struct atm_mpoa_qos *qos); 47int atm_mpoa_delete_qos(struct atm_mpoa_qos *qos);
48 48
49/* Display QoS entries. This is for the procfs */ 49/* Display QoS entries. This is for the procfs */
diff --git a/net/atm/mpoa_caches.c b/net/atm/mpoa_caches.c
index fbf13cdcf4..697a081533 100644
--- a/net/atm/mpoa_caches.c
+++ b/net/atm/mpoa_caches.c
@@ -22,7 +22,7 @@
22#define ddprintk(format,args...) 22#define ddprintk(format,args...)
23#endif 23#endif
24 24
25static in_cache_entry *in_cache_get(uint32_t dst_ip, 25static in_cache_entry *in_cache_get(__be32 dst_ip,
26 struct mpoa_client *client) 26 struct mpoa_client *client)
27{ 27{
28 in_cache_entry *entry; 28 in_cache_entry *entry;
@@ -42,9 +42,9 @@ static in_cache_entry *in_cache_get(uint32_t dst_ip,
42 return NULL; 42 return NULL;
43} 43}
44 44
45static in_cache_entry *in_cache_get_with_mask(uint32_t dst_ip, 45static in_cache_entry *in_cache_get_with_mask(__be32 dst_ip,
46 struct mpoa_client *client, 46 struct mpoa_client *client,
47 uint32_t mask) 47 __be32 mask)
48{ 48{
49 in_cache_entry *entry; 49 in_cache_entry *entry;
50 50
@@ -84,10 +84,10 @@ static in_cache_entry *in_cache_get_by_vcc(struct atm_vcc *vcc,
84 return NULL; 84 return NULL;
85} 85}
86 86
87static in_cache_entry *in_cache_add_entry(uint32_t dst_ip, 87static in_cache_entry *in_cache_add_entry(__be32 dst_ip,
88 struct mpoa_client *client) 88 struct mpoa_client *client)
89{ 89{
90 in_cache_entry* entry = kmalloc(sizeof(in_cache_entry), GFP_KERNEL); 90 in_cache_entry *entry = kzalloc(sizeof(in_cache_entry), GFP_KERNEL);
91 91
92 if (entry == NULL) { 92 if (entry == NULL) {
93 printk("mpoa: mpoa_caches.c: new_in_cache_entry: out of memory\n"); 93 printk("mpoa: mpoa_caches.c: new_in_cache_entry: out of memory\n");
@@ -95,7 +95,6 @@ static in_cache_entry *in_cache_add_entry(uint32_t dst_ip,
95 } 95 }
96 96
97 dprintk("mpoa: mpoa_caches.c: adding an ingress entry, ip = %u.%u.%u.%u\n", NIPQUAD(dst_ip)); 97 dprintk("mpoa: mpoa_caches.c: adding an ingress entry, ip = %u.%u.%u.%u\n", NIPQUAD(dst_ip));
98 memset(entry,0,sizeof(in_cache_entry));
99 98
100 atomic_set(&entry->use, 1); 99 atomic_set(&entry->use, 1);
101 dprintk("mpoa: mpoa_caches.c: new_in_cache_entry: about to lock\n"); 100 dprintk("mpoa: mpoa_caches.c: new_in_cache_entry: about to lock\n");
@@ -319,7 +318,7 @@ static void in_destroy_cache(struct mpoa_client *mpc)
319 return; 318 return;
320} 319}
321 320
322static eg_cache_entry *eg_cache_get_by_cache_id(uint32_t cache_id, struct mpoa_client *mpc) 321static eg_cache_entry *eg_cache_get_by_cache_id(__be32 cache_id, struct mpoa_client *mpc)
323{ 322{
324 eg_cache_entry *entry; 323 eg_cache_entry *entry;
325 324
@@ -339,7 +338,7 @@ static eg_cache_entry *eg_cache_get_by_cache_id(uint32_t cache_id, struct mpoa_c
339} 338}
340 339
341/* This can be called from any context since it saves CPU flags */ 340/* This can be called from any context since it saves CPU flags */
342static eg_cache_entry *eg_cache_get_by_tag(uint32_t tag, struct mpoa_client *mpc) 341static eg_cache_entry *eg_cache_get_by_tag(__be32 tag, struct mpoa_client *mpc)
343{ 342{
344 unsigned long flags; 343 unsigned long flags;
345 eg_cache_entry *entry; 344 eg_cache_entry *entry;
@@ -380,7 +379,7 @@ static eg_cache_entry *eg_cache_get_by_vcc(struct atm_vcc *vcc, struct mpoa_clie
380 return NULL; 379 return NULL;
381} 380}
382 381
383static eg_cache_entry *eg_cache_get_by_src_ip(uint32_t ipaddr, struct mpoa_client *mpc) 382static eg_cache_entry *eg_cache_get_by_src_ip(__be32 ipaddr, struct mpoa_client *mpc)
384{ 383{
385 eg_cache_entry *entry; 384 eg_cache_entry *entry;
386 385
@@ -447,7 +446,7 @@ static void eg_cache_remove_entry(eg_cache_entry *entry,
447 446
448static eg_cache_entry *eg_cache_add_entry(struct k_message *msg, struct mpoa_client *client) 447static eg_cache_entry *eg_cache_add_entry(struct k_message *msg, struct mpoa_client *client)
449{ 448{
450 eg_cache_entry *entry = kmalloc(sizeof(eg_cache_entry), GFP_KERNEL); 449 eg_cache_entry *entry = kzalloc(sizeof(eg_cache_entry), GFP_KERNEL);
451 450
452 if (entry == NULL) { 451 if (entry == NULL) {
453 printk("mpoa: mpoa_caches.c: new_eg_cache_entry: out of memory\n"); 452 printk("mpoa: mpoa_caches.c: new_eg_cache_entry: out of memory\n");
@@ -455,7 +454,6 @@ static eg_cache_entry *eg_cache_add_entry(struct k_message *msg, struct mpoa_cli
455 } 454 }
456 455
457 dprintk("mpoa: mpoa_caches.c: adding an egress entry, ip = %u.%u.%u.%u, this should be our IP\n", NIPQUAD(msg->content.eg_info.eg_dst_ip)); 456 dprintk("mpoa: mpoa_caches.c: adding an egress entry, ip = %u.%u.%u.%u, this should be our IP\n", NIPQUAD(msg->content.eg_info.eg_dst_ip));
458 memset(entry, 0, sizeof(eg_cache_entry));
459 457
460 atomic_set(&entry->use, 1); 458 atomic_set(&entry->use, 1);
461 dprintk("mpoa: mpoa_caches.c: new_eg_cache_entry: about to lock\n"); 459 dprintk("mpoa: mpoa_caches.c: new_eg_cache_entry: about to lock\n");
diff --git a/net/atm/mpoa_caches.h b/net/atm/mpoa_caches.h
index 6c9886a03d..84de977def 100644
--- a/net/atm/mpoa_caches.h
+++ b/net/atm/mpoa_caches.h
@@ -29,12 +29,12 @@ typedef struct in_cache_entry {
29} in_cache_entry; 29} in_cache_entry;
30 30
31struct in_cache_ops{ 31struct in_cache_ops{
32 in_cache_entry *(*add_entry)(uint32_t dst_ip, 32 in_cache_entry *(*add_entry)(__be32 dst_ip,
33 struct mpoa_client *client); 33 struct mpoa_client *client);
34 in_cache_entry *(*get)(uint32_t dst_ip, struct mpoa_client *client); 34 in_cache_entry *(*get)(__be32 dst_ip, struct mpoa_client *client);
35 in_cache_entry *(*get_with_mask)(uint32_t dst_ip, 35 in_cache_entry *(*get_with_mask)(__be32 dst_ip,
36 struct mpoa_client *client, 36 struct mpoa_client *client,
37 uint32_t mask); 37 __be32 mask);
38 in_cache_entry *(*get_by_vcc)(struct atm_vcc *vcc, 38 in_cache_entry *(*get_by_vcc)(struct atm_vcc *vcc,
39 struct mpoa_client *client); 39 struct mpoa_client *client);
40 void (*put)(in_cache_entry *entry); 40 void (*put)(in_cache_entry *entry);
@@ -56,17 +56,17 @@ typedef struct eg_cache_entry{
56 struct atm_vcc *shortcut; 56 struct atm_vcc *shortcut;
57 uint32_t packets_rcvd; 57 uint32_t packets_rcvd;
58 uint16_t entry_state; 58 uint16_t entry_state;
59 uint32_t latest_ip_addr; /* The src IP address of the last packet */ 59 __be32 latest_ip_addr; /* The src IP address of the last packet */
60 struct eg_ctrl_info ctrl_info; 60 struct eg_ctrl_info ctrl_info;
61 atomic_t use; 61 atomic_t use;
62} eg_cache_entry; 62} eg_cache_entry;
63 63
64struct eg_cache_ops{ 64struct eg_cache_ops{
65 eg_cache_entry *(*add_entry)(struct k_message *msg, struct mpoa_client *client); 65 eg_cache_entry *(*add_entry)(struct k_message *msg, struct mpoa_client *client);
66 eg_cache_entry *(*get_by_cache_id)(uint32_t cache_id, struct mpoa_client *client); 66 eg_cache_entry *(*get_by_cache_id)(__be32 cache_id, struct mpoa_client *client);
67 eg_cache_entry *(*get_by_tag)(uint32_t cache_id, struct mpoa_client *client); 67 eg_cache_entry *(*get_by_tag)(__be32 cache_id, struct mpoa_client *client);
68 eg_cache_entry *(*get_by_vcc)(struct atm_vcc *vcc, struct mpoa_client *client); 68 eg_cache_entry *(*get_by_vcc)(struct atm_vcc *vcc, struct mpoa_client *client);
69 eg_cache_entry *(*get_by_src_ip)(uint32_t ipaddr, struct mpoa_client *client); 69 eg_cache_entry *(*get_by_src_ip)(__be32 ipaddr, struct mpoa_client *client);
70 void (*put)(eg_cache_entry *entry); 70 void (*put)(eg_cache_entry *entry);
71 void (*remove_entry)(eg_cache_entry *entry, struct mpoa_client *client); 71 void (*remove_entry)(eg_cache_entry *entry, struct mpoa_client *client);
72 void (*update)(eg_cache_entry *entry, uint16_t holding_time); 72 void (*update)(eg_cache_entry *entry, uint16_t holding_time);
diff --git a/net/atm/mpoa_proc.c b/net/atm/mpoa_proc.c
index d37b8911b3..3844c85d60 100644
--- a/net/atm/mpoa_proc.c
+++ b/net/atm/mpoa_proc.c
@@ -231,14 +231,14 @@ static int parse_qos(const char *buff)
231 */ 231 */
232 unsigned char ip[4]; 232 unsigned char ip[4];
233 int tx_pcr, tx_sdu, rx_pcr, rx_sdu; 233 int tx_pcr, tx_sdu, rx_pcr, rx_sdu;
234 uint32_t ipaddr; 234 __be32 ipaddr;
235 struct atm_qos qos; 235 struct atm_qos qos;
236 236
237 memset(&qos, 0, sizeof(struct atm_qos)); 237 memset(&qos, 0, sizeof(struct atm_qos));
238 238
239 if (sscanf(buff, "del %hhu.%hhu.%hhu.%hhu", 239 if (sscanf(buff, "del %hhu.%hhu.%hhu.%hhu",
240 ip, ip+1, ip+2, ip+3) == 4) { 240 ip, ip+1, ip+2, ip+3) == 4) {
241 ipaddr = *(uint32_t *)ip; 241 ipaddr = *(__be32 *)ip;
242 return atm_mpoa_delete_qos(atm_mpoa_search_qos(ipaddr)); 242 return atm_mpoa_delete_qos(atm_mpoa_search_qos(ipaddr));
243 } 243 }
244 244
@@ -250,7 +250,7 @@ static int parse_qos(const char *buff)
250 ip, ip+1, ip+2, ip+3, &tx_pcr, &tx_sdu, &rx_pcr, &rx_sdu) != 8) 250 ip, ip+1, ip+2, ip+3, &tx_pcr, &tx_sdu, &rx_pcr, &rx_sdu) != 8)
251 return 0; 251 return 0;
252 252
253 ipaddr = *(uint32_t *)ip; 253 ipaddr = *(__be32 *)ip;
254 qos.txtp.traffic_class = ATM_CBR; 254 qos.txtp.traffic_class = ATM_CBR;
255 qos.txtp.max_pcr = tx_pcr; 255 qos.txtp.max_pcr = tx_pcr;
256 qos.txtp.max_sdu = tx_sdu; 256 qos.txtp.max_sdu = tx_sdu;
diff --git a/net/atm/proc.c b/net/atm/proc.c
index 91fe5f53ff..739866bfe9 100644
--- a/net/atm/proc.c
+++ b/net/atm/proc.c
@@ -393,7 +393,7 @@ static ssize_t proc_dev_atm_read(struct file *file, char __user *buf,
393 if (count == 0) return 0; 393 if (count == 0) return 0;
394 page = get_zeroed_page(GFP_KERNEL); 394 page = get_zeroed_page(GFP_KERNEL);
395 if (!page) return -ENOMEM; 395 if (!page) return -ENOMEM;
396 dev = PDE(file->f_dentry->d_inode)->data; 396 dev = PDE(file->f_path.dentry->d_inode)->data;
397 if (!dev->ops->proc_read) 397 if (!dev->ops->proc_read)
398 length = -EINVAL; 398 length = -EINVAL;
399 else { 399 else {
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index 000695c485..42233df2b0 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -906,13 +906,13 @@ struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev)
906 ax25->source_addr = oax25->source_addr; 906 ax25->source_addr = oax25->source_addr;
907 907
908 if (oax25->digipeat != NULL) { 908 if (oax25->digipeat != NULL) {
909 if ((ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) { 909 ax25->digipeat = kmemdup(oax25->digipeat, sizeof(ax25_digi),
910 GFP_ATOMIC);
911 if (ax25->digipeat == NULL) {
910 sk_free(sk); 912 sk_free(sk);
911 ax25_cb_put(ax25); 913 ax25_cb_put(ax25);
912 return NULL; 914 return NULL;
913 } 915 }
914
915 memcpy(ax25->digipeat, oax25->digipeat, sizeof(ax25_digi));
916 } 916 }
917 917
918 sk->sk_protinfo = ax25; 918 sk->sk_protinfo = ax25;
@@ -1088,8 +1088,8 @@ out:
1088/* 1088/*
1089 * FIXME: nonblock behaviour looks like it may have a bug. 1089 * FIXME: nonblock behaviour looks like it may have a bug.
1090 */ 1090 */
1091static int ax25_connect(struct socket *sock, struct sockaddr *uaddr, 1091static int __must_check ax25_connect(struct socket *sock,
1092 int addr_len, int flags) 1092 struct sockaddr *uaddr, int addr_len, int flags)
1093{ 1093{
1094 struct sock *sk = sock->sk; 1094 struct sock *sk = sock->sk;
1095 ax25_cb *ax25 = ax25_sk(sk), *ax25t; 1095 ax25_cb *ax25 = ax25_sk(sk), *ax25t;
diff --git a/net/ax25/ax25_addr.c b/net/ax25/ax25_addr.c
index 5f0896ad00..97a49c79c6 100644
--- a/net/ax25/ax25_addr.c
+++ b/net/ax25/ax25_addr.c
@@ -29,17 +29,26 @@
29#include <linux/interrupt.h> 29#include <linux/interrupt.h>
30 30
31/* 31/*
32 * The null address is defined as a callsign of all spaces with an 32 * The default broadcast address of an interface is QST-0; the default address
33 * SSID of zero. 33 * is LINUX-1. The null address is defined as a callsign of all spaces with
34 * an SSID of zero.
34 */ 35 */
35ax25_address null_ax25_address = {{0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00}};
36 36
37const ax25_address ax25_bcast =
38 {{'Q' << 1, 'S' << 1, 'T' << 1, ' ' << 1, ' ' << 1, ' ' << 1, 0 << 1}};
39const ax25_address ax25_defaddr =
40 {{'L' << 1, 'I' << 1, 'N' << 1, 'U' << 1, 'X' << 1, ' ' << 1, 1 << 1}};
41const ax25_address null_ax25_address =
42 {{' ' << 1, ' ' << 1, ' ' << 1, ' ' << 1, ' ' << 1, ' ' << 1, 0 << 1}};
43
44EXPORT_SYMBOL_GPL(ax25_bcast);
45EXPORT_SYMBOL_GPL(ax25_defaddr);
37EXPORT_SYMBOL(null_ax25_address); 46EXPORT_SYMBOL(null_ax25_address);
38 47
39/* 48/*
40 * ax25 -> ascii conversion 49 * ax25 -> ascii conversion
41 */ 50 */
42char *ax2asc(char *buf, ax25_address *a) 51char *ax2asc(char *buf, const ax25_address *a)
43{ 52{
44 char c, *s; 53 char c, *s;
45 int n; 54 int n;
@@ -72,9 +81,9 @@ EXPORT_SYMBOL(ax2asc);
72/* 81/*
73 * ascii -> ax25 conversion 82 * ascii -> ax25 conversion
74 */ 83 */
75void asc2ax(ax25_address *addr, char *callsign) 84void asc2ax(ax25_address *addr, const char *callsign)
76{ 85{
77 char *s; 86 const char *s;
78 int n; 87 int n;
79 88
80 for (s = callsign, n = 0; n < 6; n++) { 89 for (s = callsign, n = 0; n < 6; n++) {
@@ -107,7 +116,7 @@ EXPORT_SYMBOL(asc2ax);
107/* 116/*
108 * Compare two ax.25 addresses 117 * Compare two ax.25 addresses
109 */ 118 */
110int ax25cmp(ax25_address *a, ax25_address *b) 119int ax25cmp(const ax25_address *a, const ax25_address *b)
111{ 120{
112 int ct = 0; 121 int ct = 0;
113 122
@@ -128,7 +137,7 @@ EXPORT_SYMBOL(ax25cmp);
128/* 137/*
129 * Compare two AX.25 digipeater paths. 138 * Compare two AX.25 digipeater paths.
130 */ 139 */
131int ax25digicmp(ax25_digi *digi1, ax25_digi *digi2) 140int ax25digicmp(const ax25_digi *digi1, const ax25_digi *digi2)
132{ 141{
133 int i; 142 int i;
134 143
@@ -149,7 +158,9 @@ int ax25digicmp(ax25_digi *digi1, ax25_digi *digi2)
149 * Given an AX.25 address pull of to, from, digi list, command/response and the start of data 158 * Given an AX.25 address pull of to, from, digi list, command/response and the start of data
150 * 159 *
151 */ 160 */
152unsigned char *ax25_addr_parse(unsigned char *buf, int len, ax25_address *src, ax25_address *dest, ax25_digi *digi, int *flags, int *dama) 161const unsigned char *ax25_addr_parse(const unsigned char *buf, int len,
162 ax25_address *src, ax25_address *dest, ax25_digi *digi, int *flags,
163 int *dama)
153{ 164{
154 int d = 0; 165 int d = 0;
155 166
@@ -204,7 +215,8 @@ unsigned char *ax25_addr_parse(unsigned char *buf, int len, ax25_address *src, a
204/* 215/*
205 * Assemble an AX.25 header from the bits 216 * Assemble an AX.25 header from the bits
206 */ 217 */
207int ax25_addr_build(unsigned char *buf, ax25_address *src, ax25_address *dest, ax25_digi *d, int flag, int modulus) 218int ax25_addr_build(unsigned char *buf, const ax25_address *src,
219 const ax25_address *dest, const ax25_digi *d, int flag, int modulus)
208{ 220{
209 int len = 0; 221 int len = 0;
210 int ct = 0; 222 int ct = 0;
@@ -261,7 +273,7 @@ int ax25_addr_build(unsigned char *buf, ax25_address *src, ax25_address *dest, a
261 return len; 273 return len;
262} 274}
263 275
264int ax25_addr_size(ax25_digi *dp) 276int ax25_addr_size(const ax25_digi *dp)
265{ 277{
266 if (dp == NULL) 278 if (dp == NULL)
267 return 2 * AX25_ADDR_LEN; 279 return 2 * AX25_ADDR_LEN;
@@ -272,7 +284,7 @@ int ax25_addr_size(ax25_digi *dp)
272/* 284/*
273 * Reverse Digipeat List. May not pass both parameters as same struct 285 * Reverse Digipeat List. May not pass both parameters as same struct
274 */ 286 */
275void ax25_digi_invert(ax25_digi *in, ax25_digi *out) 287void ax25_digi_invert(const ax25_digi *in, ax25_digi *out)
276{ 288{
277 int ct; 289 int ct;
278 290
diff --git a/net/ax25/ax25_iface.c b/net/ax25/ax25_iface.c
index 07ac0207eb..aff3e652c2 100644
--- a/net/ax25/ax25_iface.c
+++ b/net/ax25/ax25_iface.c
@@ -29,17 +29,10 @@
29#include <linux/mm.h> 29#include <linux/mm.h>
30#include <linux/interrupt.h> 30#include <linux/interrupt.h>
31 31
32static struct protocol_struct { 32static struct ax25_protocol *protocol_list;
33 struct protocol_struct *next;
34 unsigned int pid;
35 int (*func)(struct sk_buff *, ax25_cb *);
36} *protocol_list = NULL;
37static DEFINE_RWLOCK(protocol_list_lock); 33static DEFINE_RWLOCK(protocol_list_lock);
38 34
39static struct linkfail_struct { 35static HLIST_HEAD(ax25_linkfail_list);
40 struct linkfail_struct *next;
41 void (*func)(ax25_cb *, int);
42} *linkfail_list = NULL;
43static DEFINE_SPINLOCK(linkfail_lock); 36static DEFINE_SPINLOCK(linkfail_lock);
44 37
45static struct listen_struct { 38static struct listen_struct {
@@ -49,36 +42,23 @@ static struct listen_struct {
49} *listen_list = NULL; 42} *listen_list = NULL;
50static DEFINE_SPINLOCK(listen_lock); 43static DEFINE_SPINLOCK(listen_lock);
51 44
52int ax25_protocol_register(unsigned int pid, 45/*
53 int (*func)(struct sk_buff *, ax25_cb *)) 46 * Do not register the internal protocols AX25_P_TEXT, AX25_P_SEGMENT,
47 * AX25_P_IP or AX25_P_ARP ...
48 */
49void ax25_register_pid(struct ax25_protocol *ap)
54{ 50{
55 struct protocol_struct *protocol;
56
57 if (pid == AX25_P_TEXT || pid == AX25_P_SEGMENT)
58 return 0;
59#ifdef CONFIG_INET
60 if (pid == AX25_P_IP || pid == AX25_P_ARP)
61 return 0;
62#endif
63 if ((protocol = kmalloc(sizeof(*protocol), GFP_ATOMIC)) == NULL)
64 return 0;
65
66 protocol->pid = pid;
67 protocol->func = func;
68
69 write_lock_bh(&protocol_list_lock); 51 write_lock_bh(&protocol_list_lock);
70 protocol->next = protocol_list; 52 ap->next = protocol_list;
71 protocol_list = protocol; 53 protocol_list = ap;
72 write_unlock_bh(&protocol_list_lock); 54 write_unlock_bh(&protocol_list_lock);
73
74 return 1;
75} 55}
76 56
77EXPORT_SYMBOL(ax25_protocol_register); 57EXPORT_SYMBOL_GPL(ax25_register_pid);
78 58
79void ax25_protocol_release(unsigned int pid) 59void ax25_protocol_release(unsigned int pid)
80{ 60{
81 struct protocol_struct *s, *protocol; 61 struct ax25_protocol *s, *protocol;
82 62
83 write_lock_bh(&protocol_list_lock); 63 write_lock_bh(&protocol_list_lock);
84 protocol = protocol_list; 64 protocol = protocol_list;
@@ -110,54 +90,19 @@ void ax25_protocol_release(unsigned int pid)
110 90
111EXPORT_SYMBOL(ax25_protocol_release); 91EXPORT_SYMBOL(ax25_protocol_release);
112 92
113int ax25_linkfail_register(void (*func)(ax25_cb *, int)) 93void ax25_linkfail_register(struct ax25_linkfail *lf)
114{ 94{
115 struct linkfail_struct *linkfail;
116
117 if ((linkfail = kmalloc(sizeof(*linkfail), GFP_ATOMIC)) == NULL)
118 return 0;
119
120 linkfail->func = func;
121
122 spin_lock_bh(&linkfail_lock); 95 spin_lock_bh(&linkfail_lock);
123 linkfail->next = linkfail_list; 96 hlist_add_head(&lf->lf_node, &ax25_linkfail_list);
124 linkfail_list = linkfail;
125 spin_unlock_bh(&linkfail_lock); 97 spin_unlock_bh(&linkfail_lock);
126
127 return 1;
128} 98}
129 99
130EXPORT_SYMBOL(ax25_linkfail_register); 100EXPORT_SYMBOL(ax25_linkfail_register);
131 101
132void ax25_linkfail_release(void (*func)(ax25_cb *, int)) 102void ax25_linkfail_release(struct ax25_linkfail *lf)
133{ 103{
134 struct linkfail_struct *s, *linkfail;
135
136 spin_lock_bh(&linkfail_lock); 104 spin_lock_bh(&linkfail_lock);
137 linkfail = linkfail_list; 105 hlist_del_init(&lf->lf_node);
138 if (linkfail == NULL) {
139 spin_unlock_bh(&linkfail_lock);
140 return;
141 }
142
143 if (linkfail->func == func) {
144 linkfail_list = linkfail->next;
145 spin_unlock_bh(&linkfail_lock);
146 kfree(linkfail);
147 return;
148 }
149
150 while (linkfail != NULL && linkfail->next != NULL) {
151 if (linkfail->next->func == func) {
152 s = linkfail->next;
153 linkfail->next = linkfail->next->next;
154 spin_unlock_bh(&linkfail_lock);
155 kfree(s);
156 return;
157 }
158
159 linkfail = linkfail->next;
160 }
161 spin_unlock_bh(&linkfail_lock); 106 spin_unlock_bh(&linkfail_lock);
162} 107}
163 108
@@ -171,7 +116,7 @@ int ax25_listen_register(ax25_address *callsign, struct net_device *dev)
171 return 0; 116 return 0;
172 117
173 if ((listen = kmalloc(sizeof(*listen), GFP_ATOMIC)) == NULL) 118 if ((listen = kmalloc(sizeof(*listen), GFP_ATOMIC)) == NULL)
174 return 0; 119 return -ENOMEM;
175 120
176 listen->callsign = *callsign; 121 listen->callsign = *callsign;
177 listen->dev = dev; 122 listen->dev = dev;
@@ -181,7 +126,7 @@ int ax25_listen_register(ax25_address *callsign, struct net_device *dev)
181 listen_list = listen; 126 listen_list = listen;
182 spin_unlock_bh(&listen_lock); 127 spin_unlock_bh(&listen_lock);
183 128
184 return 1; 129 return 0;
185} 130}
186 131
187EXPORT_SYMBOL(ax25_listen_register); 132EXPORT_SYMBOL(ax25_listen_register);
@@ -223,7 +168,7 @@ EXPORT_SYMBOL(ax25_listen_release);
223int (*ax25_protocol_function(unsigned int pid))(struct sk_buff *, ax25_cb *) 168int (*ax25_protocol_function(unsigned int pid))(struct sk_buff *, ax25_cb *)
224{ 169{
225 int (*res)(struct sk_buff *, ax25_cb *) = NULL; 170 int (*res)(struct sk_buff *, ax25_cb *) = NULL;
226 struct protocol_struct *protocol; 171 struct ax25_protocol *protocol;
227 172
228 read_lock(&protocol_list_lock); 173 read_lock(&protocol_list_lock);
229 for (protocol = protocol_list; protocol != NULL; protocol = protocol->next) 174 for (protocol = protocol_list; protocol != NULL; protocol = protocol->next)
@@ -242,7 +187,8 @@ int ax25_listen_mine(ax25_address *callsign, struct net_device *dev)
242 187
243 spin_lock_bh(&listen_lock); 188 spin_lock_bh(&listen_lock);
244 for (listen = listen_list; listen != NULL; listen = listen->next) 189 for (listen = listen_list; listen != NULL; listen = listen->next)
245 if (ax25cmp(&listen->callsign, callsign) == 0 && (listen->dev == dev || listen->dev == NULL)) { 190 if (ax25cmp(&listen->callsign, callsign) == 0 &&
191 (listen->dev == dev || listen->dev == NULL)) {
246 spin_unlock_bh(&listen_lock); 192 spin_unlock_bh(&listen_lock);
247 return 1; 193 return 1;
248 } 194 }
@@ -253,17 +199,18 @@ int ax25_listen_mine(ax25_address *callsign, struct net_device *dev)
253 199
254void ax25_link_failed(ax25_cb *ax25, int reason) 200void ax25_link_failed(ax25_cb *ax25, int reason)
255{ 201{
256 struct linkfail_struct *linkfail; 202 struct ax25_linkfail *lf;
203 struct hlist_node *node;
257 204
258 spin_lock_bh(&linkfail_lock); 205 spin_lock_bh(&linkfail_lock);
259 for (linkfail = linkfail_list; linkfail != NULL; linkfail = linkfail->next) 206 hlist_for_each_entry(lf, node, &ax25_linkfail_list, lf_node)
260 (linkfail->func)(ax25, reason); 207 lf->func(ax25, reason);
261 spin_unlock_bh(&linkfail_lock); 208 spin_unlock_bh(&linkfail_lock);
262} 209}
263 210
264int ax25_protocol_is_registered(unsigned int pid) 211int ax25_protocol_is_registered(unsigned int pid)
265{ 212{
266 struct protocol_struct *protocol; 213 struct ax25_protocol *protocol;
267 int res = 0; 214 int res = 0;
268 215
269 read_lock_bh(&protocol_list_lock); 216 read_lock_bh(&protocol_list_lock);
diff --git a/net/ax25/ax25_out.c b/net/ax25/ax25_out.c
index d7736e5853..f84047d1e8 100644
--- a/net/ax25/ax25_out.c
+++ b/net/ax25/ax25_out.c
@@ -70,11 +70,11 @@ ax25_cb *ax25_send_frame(struct sk_buff *skb, int paclen, ax25_address *src, ax2
70 ax25->dest_addr = *dest; 70 ax25->dest_addr = *dest;
71 71
72 if (digi != NULL) { 72 if (digi != NULL) {
73 if ((ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) { 73 ax25->digipeat = kmemdup(digi, sizeof(*digi), GFP_ATOMIC);
74 if (ax25->digipeat == NULL) {
74 ax25_cb_put(ax25); 75 ax25_cb_put(ax25);
75 return NULL; 76 return NULL;
76 } 77 }
77 memcpy(ax25->digipeat, digi, sizeof(ax25_digi));
78 } 78 }
79 79
80 switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) { 80 switch (ax25->ax25_dev->values[AX25_VALUES_PROTOCOL]) {
diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c
index 51b7bdaf27..0a0381622b 100644
--- a/net/ax25/ax25_route.c
+++ b/net/ax25/ax25_route.c
@@ -71,7 +71,7 @@ void ax25_rt_device_down(struct net_device *dev)
71 write_unlock(&ax25_route_lock); 71 write_unlock(&ax25_route_lock);
72} 72}
73 73
74static int ax25_rt_add(struct ax25_routes_struct *route) 74static int __must_check ax25_rt_add(struct ax25_routes_struct *route)
75{ 75{
76 ax25_route *ax25_rt; 76 ax25_route *ax25_rt;
77 ax25_dev *ax25_dev; 77 ax25_dev *ax25_dev;
@@ -432,11 +432,12 @@ int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr)
432 } 432 }
433 433
434 if (ax25_rt->digipeat != NULL) { 434 if (ax25_rt->digipeat != NULL) {
435 if ((ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) { 435 ax25->digipeat = kmemdup(ax25_rt->digipeat, sizeof(ax25_digi),
436 GFP_ATOMIC);
437 if (ax25->digipeat == NULL) {
436 err = -ENOMEM; 438 err = -ENOMEM;
437 goto put; 439 goto put;
438 } 440 }
439 memcpy(ax25->digipeat, ax25_rt->digipeat, sizeof(ax25_digi));
440 ax25_adjust_path(addr, ax25->digipeat); 441 ax25_adjust_path(addr, ax25->digipeat);
441 } 442 }
442 443
diff --git a/net/ax25/sysctl_net_ax25.c b/net/ax25/sysctl_net_ax25.c
index 867d425379..d23a27f25d 100644
--- a/net/ax25/sysctl_net_ax25.c
+++ b/net/ax25/sysctl_net_ax25.c
@@ -209,7 +209,9 @@ void ax25_register_sysctl(void)
209 } 209 }
210 210
211 for (n = 0, ax25_dev = ax25_dev_list; ax25_dev != NULL; ax25_dev = ax25_dev->next) { 211 for (n = 0, ax25_dev = ax25_dev_list; ax25_dev != NULL; ax25_dev = ax25_dev->next) {
212 ctl_table *child = kmalloc(sizeof(ax25_param_table), GFP_ATOMIC); 212 struct ctl_table *child = kmemdup(ax25_param_table,
213 sizeof(ax25_param_table),
214 GFP_ATOMIC);
213 if (!child) { 215 if (!child) {
214 while (n--) 216 while (n--)
215 kfree(ax25_table[n].child); 217 kfree(ax25_table[n].child);
@@ -217,7 +219,6 @@ void ax25_register_sysctl(void)
217 spin_unlock_bh(&ax25_dev_lock); 219 spin_unlock_bh(&ax25_dev_lock);
218 return; 220 return;
219 } 221 }
220 memcpy(child, ax25_param_table, sizeof(ax25_param_table));
221 ax25_table[n].child = ax25_dev->systable = child; 222 ax25_table[n].child = ax25_dev->systable = child;
222 ax25_table[n].ctl_name = n + 1; 223 ax25_table[n].ctl_name = n + 1;
223 ax25_table[n].procname = ax25_dev->dev->name; 224 ax25_table[n].procname = ax25_dev->dev->name;
diff --git a/net/bluetooth/bnep/bnep.h b/net/bluetooth/bnep/bnep.h
index bbb1ed7097..0b6cd0e252 100644
--- a/net/bluetooth/bnep/bnep.h
+++ b/net/bluetooth/bnep/bnep.h
@@ -95,14 +95,14 @@ struct bnep_setup_conn_req {
95struct bnep_set_filter_req { 95struct bnep_set_filter_req {
96 __u8 type; 96 __u8 type;
97 __u8 ctrl; 97 __u8 ctrl;
98 __u16 len; 98 __be16 len;
99 __u8 list[0]; 99 __u8 list[0];
100} __attribute__((packed)); 100} __attribute__((packed));
101 101
102struct bnep_control_rsp { 102struct bnep_control_rsp {
103 __u8 type; 103 __u8 type;
104 __u8 ctrl; 104 __u8 ctrl;
105 __u16 resp; 105 __be16 resp;
106} __attribute__((packed)); 106} __attribute__((packed));
107 107
108struct bnep_ext_hdr { 108struct bnep_ext_hdr {
diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
index 4d3424c242..7ba6470dc5 100644
--- a/net/bluetooth/bnep/core.c
+++ b/net/bluetooth/bnep/core.c
@@ -117,18 +117,18 @@ static int bnep_send_rsp(struct bnep_session *s, u8 ctrl, u16 resp)
117static inline void bnep_set_default_proto_filter(struct bnep_session *s) 117static inline void bnep_set_default_proto_filter(struct bnep_session *s)
118{ 118{
119 /* (IPv4, ARP) */ 119 /* (IPv4, ARP) */
120 s->proto_filter[0].start = htons(0x0800); 120 s->proto_filter[0].start = ETH_P_IP;
121 s->proto_filter[0].end = htons(0x0806); 121 s->proto_filter[0].end = ETH_P_ARP;
122 /* (RARP, AppleTalk) */ 122 /* (RARP, AppleTalk) */
123 s->proto_filter[1].start = htons(0x8035); 123 s->proto_filter[1].start = ETH_P_RARP;
124 s->proto_filter[1].end = htons(0x80F3); 124 s->proto_filter[1].end = ETH_P_AARP;
125 /* (IPX, IPv6) */ 125 /* (IPX, IPv6) */
126 s->proto_filter[2].start = htons(0x8137); 126 s->proto_filter[2].start = ETH_P_IPX;
127 s->proto_filter[2].end = htons(0x86DD); 127 s->proto_filter[2].end = ETH_P_IPV6;
128} 128}
129#endif 129#endif
130 130
131static int bnep_ctrl_set_netfilter(struct bnep_session *s, u16 *data, int len) 131static int bnep_ctrl_set_netfilter(struct bnep_session *s, __be16 *data, int len)
132{ 132{
133 int n; 133 int n;
134 134
@@ -150,8 +150,8 @@ static int bnep_ctrl_set_netfilter(struct bnep_session *s, u16 *data, int len)
150 int i; 150 int i;
151 151
152 for (i = 0; i < n; i++) { 152 for (i = 0; i < n; i++) {
153 f[i].start = get_unaligned(data++); 153 f[i].start = ntohs(get_unaligned(data++));
154 f[i].end = get_unaligned(data++); 154 f[i].end = ntohs(get_unaligned(data++));
155 155
156 BT_DBG("proto filter start %d end %d", 156 BT_DBG("proto filter start %d end %d",
157 f[i].start, f[i].end); 157 f[i].start, f[i].end);
@@ -180,7 +180,7 @@ static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len)
180 if (len < 2) 180 if (len < 2)
181 return -EILSEQ; 181 return -EILSEQ;
182 182
183 n = ntohs(get_unaligned((u16 *) data)); 183 n = ntohs(get_unaligned((__be16 *) data));
184 data += 2; len -= 2; 184 data += 2; len -= 2;
185 185
186 if (len < n) 186 if (len < n)
@@ -332,7 +332,7 @@ static inline int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
332 if (!skb_pull(skb, __bnep_rx_hlen[type & BNEP_TYPE_MASK])) 332 if (!skb_pull(skb, __bnep_rx_hlen[type & BNEP_TYPE_MASK]))
333 goto badframe; 333 goto badframe;
334 334
335 s->eh.h_proto = get_unaligned((u16 *) (skb->data - 2)); 335 s->eh.h_proto = get_unaligned((__be16 *) (skb->data - 2));
336 336
337 if (type & BNEP_EXT_HEADER) { 337 if (type & BNEP_EXT_HEADER) {
338 if (bnep_rx_extension(s, skb) < 0) 338 if (bnep_rx_extension(s, skb) < 0)
@@ -343,7 +343,7 @@ static inline int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
343 if (ntohs(s->eh.h_proto) == 0x8100) { 343 if (ntohs(s->eh.h_proto) == 0x8100) {
344 if (!skb_pull(skb, 4)) 344 if (!skb_pull(skb, 4))
345 goto badframe; 345 goto badframe;
346 s->eh.h_proto = get_unaligned((u16 *) (skb->data - 2)); 346 s->eh.h_proto = get_unaligned((__be16 *) (skb->data - 2));
347 } 347 }
348 348
349 /* We have to alloc new skb and copy data here :(. Because original skb 349 /* We have to alloc new skb and copy data here :(. Because original skb
@@ -365,7 +365,7 @@ static inline int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
365 case BNEP_COMPRESSED_SRC_ONLY: 365 case BNEP_COMPRESSED_SRC_ONLY:
366 memcpy(__skb_put(nskb, ETH_ALEN), s->eh.h_dest, ETH_ALEN); 366 memcpy(__skb_put(nskb, ETH_ALEN), s->eh.h_dest, ETH_ALEN);
367 memcpy(__skb_put(nskb, ETH_ALEN), skb->mac.raw, ETH_ALEN); 367 memcpy(__skb_put(nskb, ETH_ALEN), skb->mac.raw, ETH_ALEN);
368 put_unaligned(s->eh.h_proto, (u16 *) __skb_put(nskb, 2)); 368 put_unaligned(s->eh.h_proto, (__be16 *) __skb_put(nskb, 2));
369 break; 369 break;
370 370
371 case BNEP_COMPRESSED_DST_ONLY: 371 case BNEP_COMPRESSED_DST_ONLY:
@@ -375,7 +375,7 @@ static inline int bnep_rx_frame(struct bnep_session *s, struct sk_buff *skb)
375 375
376 case BNEP_GENERAL: 376 case BNEP_GENERAL:
377 memcpy(__skb_put(nskb, ETH_ALEN * 2), skb->mac.raw, ETH_ALEN * 2); 377 memcpy(__skb_put(nskb, ETH_ALEN * 2), skb->mac.raw, ETH_ALEN * 2);
378 put_unaligned(s->eh.h_proto, (u16 *) __skb_put(nskb, 2)); 378 put_unaligned(s->eh.h_proto, (__be16 *) __skb_put(nskb, 2));
379 break; 379 break;
380 } 380 }
381 381
diff --git a/net/bluetooth/bnep/netdev.c b/net/bluetooth/bnep/netdev.c
index 7f7b27db6a..67a002a975 100644
--- a/net/bluetooth/bnep/netdev.c
+++ b/net/bluetooth/bnep/netdev.c
@@ -158,14 +158,15 @@ static inline int bnep_net_mc_filter(struct sk_buff *skb, struct bnep_session *s
158static inline u16 bnep_net_eth_proto(struct sk_buff *skb) 158static inline u16 bnep_net_eth_proto(struct sk_buff *skb)
159{ 159{
160 struct ethhdr *eh = (void *) skb->data; 160 struct ethhdr *eh = (void *) skb->data;
161 u16 proto = ntohs(eh->h_proto);
161 162
162 if (ntohs(eh->h_proto) >= 1536) 163 if (proto >= 1536)
163 return eh->h_proto; 164 return proto;
164 165
165 if (get_unaligned((u16 *) skb->data) == 0xFFFF) 166 if (get_unaligned((__be16 *) skb->data) == htons(0xFFFF))
166 return htons(ETH_P_802_3); 167 return ETH_P_802_3;
167 168
168 return htons(ETH_P_802_2); 169 return ETH_P_802_2;
169} 170}
170 171
171static inline int bnep_net_proto_filter(struct sk_buff *skb, struct bnep_session *s) 172static inline int bnep_net_proto_filter(struct sk_buff *skb, struct bnep_session *s)
diff --git a/net/bluetooth/cmtp/capi.c b/net/bluetooth/cmtp/capi.c
index be04e9fb11..ab166b48ce 100644
--- a/net/bluetooth/cmtp/capi.c
+++ b/net/bluetooth/cmtp/capi.c
@@ -196,6 +196,9 @@ static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *s
196 196
197 switch (CAPIMSG_SUBCOMMAND(skb->data)) { 197 switch (CAPIMSG_SUBCOMMAND(skb->data)) {
198 case CAPI_CONF: 198 case CAPI_CONF:
199 if (skb->len < CAPI_MSG_BASELEN + 10)
200 break;
201
199 func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 5); 202 func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 5);
200 info = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 8); 203 info = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 8);
201 204
@@ -226,6 +229,9 @@ static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *s
226 break; 229 break;
227 230
228 case CAPI_FUNCTION_GET_PROFILE: 231 case CAPI_FUNCTION_GET_PROFILE:
232 if (skb->len < CAPI_MSG_BASELEN + 11 + sizeof(capi_profile))
233 break;
234
229 controller = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 11); 235 controller = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 11);
230 msgnum = CAPIMSG_MSGID(skb->data); 236 msgnum = CAPIMSG_MSGID(skb->data);
231 237
@@ -246,17 +252,26 @@ static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *s
246 break; 252 break;
247 253
248 case CAPI_FUNCTION_GET_MANUFACTURER: 254 case CAPI_FUNCTION_GET_MANUFACTURER:
255 if (skb->len < CAPI_MSG_BASELEN + 15)
256 break;
257
249 controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 10); 258 controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 10);
250 259
251 if (!info && ctrl) { 260 if (!info && ctrl) {
261 int len = min_t(uint, CAPI_MANUFACTURER_LEN,
262 skb->data[CAPI_MSG_BASELEN + 14]);
263
264 memset(ctrl->manu, 0, CAPI_MANUFACTURER_LEN);
252 strncpy(ctrl->manu, 265 strncpy(ctrl->manu,
253 skb->data + CAPI_MSG_BASELEN + 15, 266 skb->data + CAPI_MSG_BASELEN + 15, len);
254 skb->data[CAPI_MSG_BASELEN + 14]);
255 } 267 }
256 268
257 break; 269 break;
258 270
259 case CAPI_FUNCTION_GET_VERSION: 271 case CAPI_FUNCTION_GET_VERSION:
272 if (skb->len < CAPI_MSG_BASELEN + 32)
273 break;
274
260 controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12); 275 controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
261 276
262 if (!info && ctrl) { 277 if (!info && ctrl) {
@@ -269,13 +284,18 @@ static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *s
269 break; 284 break;
270 285
271 case CAPI_FUNCTION_GET_SERIAL_NUMBER: 286 case CAPI_FUNCTION_GET_SERIAL_NUMBER:
287 if (skb->len < CAPI_MSG_BASELEN + 17)
288 break;
289
272 controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12); 290 controller = CAPIMSG_U32(skb->data, CAPI_MSG_BASELEN + 12);
273 291
274 if (!info && ctrl) { 292 if (!info && ctrl) {
293 int len = min_t(uint, CAPI_SERIAL_LEN,
294 skb->data[CAPI_MSG_BASELEN + 16]);
295
275 memset(ctrl->serial, 0, CAPI_SERIAL_LEN); 296 memset(ctrl->serial, 0, CAPI_SERIAL_LEN);
276 strncpy(ctrl->serial, 297 strncpy(ctrl->serial,
277 skb->data + CAPI_MSG_BASELEN + 17, 298 skb->data + CAPI_MSG_BASELEN + 17, len);
278 skb->data[CAPI_MSG_BASELEN + 16]);
279 } 299 }
280 300
281 break; 301 break;
@@ -284,14 +304,18 @@ static void cmtp_recv_interopmsg(struct cmtp_session *session, struct sk_buff *s
284 break; 304 break;
285 305
286 case CAPI_IND: 306 case CAPI_IND:
307 if (skb->len < CAPI_MSG_BASELEN + 6)
308 break;
309
287 func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 3); 310 func = CAPIMSG_U16(skb->data, CAPI_MSG_BASELEN + 3);
288 311
289 if (func == CAPI_FUNCTION_LOOPBACK) { 312 if (func == CAPI_FUNCTION_LOOPBACK) {
313 int len = min_t(uint, skb->len - CAPI_MSG_BASELEN - 6,
314 skb->data[CAPI_MSG_BASELEN + 5]);
290 appl = CAPIMSG_APPID(skb->data); 315 appl = CAPIMSG_APPID(skb->data);
291 msgnum = CAPIMSG_MSGID(skb->data); 316 msgnum = CAPIMSG_MSGID(skb->data);
292 cmtp_send_interopmsg(session, CAPI_RESP, appl, msgnum, func, 317 cmtp_send_interopmsg(session, CAPI_RESP, appl, msgnum, func,
293 skb->data + CAPI_MSG_BASELEN + 6, 318 skb->data + CAPI_MSG_BASELEN + 6, len);
294 skb->data[CAPI_MSG_BASELEN + 5]);
295 } 319 }
296 320
297 break; 321 break;
@@ -309,6 +333,9 @@ void cmtp_recv_capimsg(struct cmtp_session *session, struct sk_buff *skb)
309 333
310 BT_DBG("session %p skb %p len %d", session, skb, skb->len); 334 BT_DBG("session %p skb %p len %d", session, skb, skb->len);
311 335
336 if (skb->len < CAPI_MSG_BASELEN)
337 return;
338
312 if (CAPIMSG_COMMAND(skb->data) == CAPI_INTEROPERABILITY) { 339 if (CAPIMSG_COMMAND(skb->data) == CAPI_INTEROPERABILITY) {
313 cmtp_recv_interopmsg(session, skb); 340 cmtp_recv_interopmsg(session, skb);
314 return; 341 return;
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c
index 711a085eca..dbf98c49db 100644
--- a/net/bluetooth/hci_sock.c
+++ b/net/bluetooth/hci_sock.c
@@ -123,10 +123,10 @@ void hci_send_to_sock(struct hci_dev *hdev, struct sk_buff *skb)
123 if (flt->opcode && 123 if (flt->opcode &&
124 ((evt == HCI_EV_CMD_COMPLETE && 124 ((evt == HCI_EV_CMD_COMPLETE &&
125 flt->opcode != 125 flt->opcode !=
126 get_unaligned((__u16 *)(skb->data + 3))) || 126 get_unaligned((__le16 *)(skb->data + 3))) ||
127 (evt == HCI_EV_CMD_STATUS && 127 (evt == HCI_EV_CMD_STATUS &&
128 flt->opcode != 128 flt->opcode !=
129 get_unaligned((__u16 *)(skb->data + 4))))) 129 get_unaligned((__le16 *)(skb->data + 4)))))
130 continue; 130 continue;
131 } 131 }
132 132
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 3eeeb7a86e..801d687ea4 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -237,12 +237,12 @@ static void bt_release(struct device *dev)
237 kfree(data); 237 kfree(data);
238} 238}
239 239
240static void add_conn(void *data) 240static void add_conn(struct work_struct *work)
241{ 241{
242 struct hci_conn *conn = data; 242 struct hci_conn *conn = container_of(work, struct hci_conn, work);
243 int i; 243 int i;
244 244
245 if (device_register(&conn->dev) < 0) { 245 if (device_add(&conn->dev) < 0) {
246 BT_ERR("Failed to register connection device"); 246 BT_ERR("Failed to register connection device");
247 return; 247 return;
248 } 248 }
@@ -272,14 +272,16 @@ void hci_conn_add_sysfs(struct hci_conn *conn)
272 272
273 dev_set_drvdata(&conn->dev, conn); 273 dev_set_drvdata(&conn->dev, conn);
274 274
275 INIT_WORK(&conn->work, add_conn, (void *) conn); 275 device_initialize(&conn->dev);
276
277 INIT_WORK(&conn->work, add_conn);
276 278
277 schedule_work(&conn->work); 279 schedule_work(&conn->work);
278} 280}
279 281
280static void del_conn(void *data) 282static void del_conn(struct work_struct *work)
281{ 283{
282 struct hci_conn *conn = data; 284 struct hci_conn *conn = container_of(work, struct hci_conn, work);
283 device_del(&conn->dev); 285 device_del(&conn->dev);
284} 286}
285 287
@@ -287,7 +289,10 @@ void hci_conn_del_sysfs(struct hci_conn *conn)
287{ 289{
288 BT_DBG("conn %p", conn); 290 BT_DBG("conn %p", conn);
289 291
290 INIT_WORK(&conn->work, del_conn, (void *) conn); 292 if (!device_is_registered(&conn->dev))
293 return;
294
295 INIT_WORK(&conn->work, del_conn);
291 296
292 schedule_work(&conn->work); 297 schedule_work(&conn->work);
293} 298}
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index bbf78e6a7b..29a8fa4d37 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -770,7 +770,7 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int fl
770 long timeo; 770 long timeo;
771 int err = 0; 771 int err = 0;
772 772
773 lock_sock(sk); 773 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
774 774
775 if (sk->sk_state != BT_LISTEN) { 775 if (sk->sk_state != BT_LISTEN) {
776 err = -EBADFD; 776 err = -EBADFD;
@@ -792,7 +792,7 @@ static int l2cap_sock_accept(struct socket *sock, struct socket *newsock, int fl
792 792
793 release_sock(sk); 793 release_sock(sk);
794 timeo = schedule_timeout(timeo); 794 timeo = schedule_timeout(timeo);
795 lock_sock(sk); 795 lock_sock_nested(sk, SINGLE_DEPTH_NESTING);
796 796
797 if (sk->sk_state != BT_LISTEN) { 797 if (sk->sk_state != BT_LISTEN) {
798 err = -EBADFD; 798 err = -EBADFD;
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index ddc4e9d596..278c867690 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -854,7 +854,7 @@ int rfcomm_send_rpn(struct rfcomm_session *s, int cr, u8 dlci,
854 rpn->flow_ctrl = flow_ctrl_settings; 854 rpn->flow_ctrl = flow_ctrl_settings;
855 rpn->xon_char = xon_char; 855 rpn->xon_char = xon_char;
856 rpn->xoff_char = xoff_char; 856 rpn->xoff_char = xoff_char;
857 rpn->param_mask = param_mask; 857 rpn->param_mask = cpu_to_le16(param_mask);
858 858
859 *ptr = __fcs(buf); ptr++; 859 *ptr = __fcs(buf); ptr++;
860 860
@@ -1018,7 +1018,7 @@ static void rfcomm_make_uih(struct sk_buff *skb, u8 addr)
1018 1018
1019 if (len > 127) { 1019 if (len > 127) {
1020 hdr = (void *) skb_push(skb, 4); 1020 hdr = (void *) skb_push(skb, 4);
1021 put_unaligned(htobs(__len16(len)), (u16 *) &hdr->len); 1021 put_unaligned(htobs(__len16(len)), (__le16 *) &hdr->len);
1022 } else { 1022 } else {
1023 hdr = (void *) skb_push(skb, 3); 1023 hdr = (void *) skb_push(skb, 3);
1024 hdr->len = __len8(len); 1024 hdr->len = __len8(len);
@@ -1343,7 +1343,7 @@ static int rfcomm_recv_rpn(struct rfcomm_session *s, int cr, int len, struct sk_
1343 /* Check for sane values, ignore/accept bit_rate, 8 bits, 1 stop bit, 1343 /* Check for sane values, ignore/accept bit_rate, 8 bits, 1 stop bit,
1344 * no parity, no flow control lines, normal XON/XOFF chars */ 1344 * no parity, no flow control lines, normal XON/XOFF chars */
1345 1345
1346 if (rpn->param_mask & RFCOMM_RPN_PM_BITRATE) { 1346 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_BITRATE)) {
1347 bit_rate = rpn->bit_rate; 1347 bit_rate = rpn->bit_rate;
1348 if (bit_rate != RFCOMM_RPN_BR_115200) { 1348 if (bit_rate != RFCOMM_RPN_BR_115200) {
1349 BT_DBG("RPN bit rate mismatch 0x%x", bit_rate); 1349 BT_DBG("RPN bit rate mismatch 0x%x", bit_rate);
@@ -1352,7 +1352,7 @@ static int rfcomm_recv_rpn(struct rfcomm_session *s, int cr, int len, struct sk_
1352 } 1352 }
1353 } 1353 }
1354 1354
1355 if (rpn->param_mask & RFCOMM_RPN_PM_DATA) { 1355 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_DATA)) {
1356 data_bits = __get_rpn_data_bits(rpn->line_settings); 1356 data_bits = __get_rpn_data_bits(rpn->line_settings);
1357 if (data_bits != RFCOMM_RPN_DATA_8) { 1357 if (data_bits != RFCOMM_RPN_DATA_8) {
1358 BT_DBG("RPN data bits mismatch 0x%x", data_bits); 1358 BT_DBG("RPN data bits mismatch 0x%x", data_bits);
@@ -1361,7 +1361,7 @@ static int rfcomm_recv_rpn(struct rfcomm_session *s, int cr, int len, struct sk_
1361 } 1361 }
1362 } 1362 }
1363 1363
1364 if (rpn->param_mask & RFCOMM_RPN_PM_STOP) { 1364 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_STOP)) {
1365 stop_bits = __get_rpn_stop_bits(rpn->line_settings); 1365 stop_bits = __get_rpn_stop_bits(rpn->line_settings);
1366 if (stop_bits != RFCOMM_RPN_STOP_1) { 1366 if (stop_bits != RFCOMM_RPN_STOP_1) {
1367 BT_DBG("RPN stop bits mismatch 0x%x", stop_bits); 1367 BT_DBG("RPN stop bits mismatch 0x%x", stop_bits);
@@ -1370,7 +1370,7 @@ static int rfcomm_recv_rpn(struct rfcomm_session *s, int cr, int len, struct sk_
1370 } 1370 }
1371 } 1371 }
1372 1372
1373 if (rpn->param_mask & RFCOMM_RPN_PM_PARITY) { 1373 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_PARITY)) {
1374 parity = __get_rpn_parity(rpn->line_settings); 1374 parity = __get_rpn_parity(rpn->line_settings);
1375 if (parity != RFCOMM_RPN_PARITY_NONE) { 1375 if (parity != RFCOMM_RPN_PARITY_NONE) {
1376 BT_DBG("RPN parity mismatch 0x%x", parity); 1376 BT_DBG("RPN parity mismatch 0x%x", parity);
@@ -1379,7 +1379,7 @@ static int rfcomm_recv_rpn(struct rfcomm_session *s, int cr, int len, struct sk_
1379 } 1379 }
1380 } 1380 }
1381 1381
1382 if (rpn->param_mask & RFCOMM_RPN_PM_FLOW) { 1382 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_FLOW)) {
1383 flow_ctrl = rpn->flow_ctrl; 1383 flow_ctrl = rpn->flow_ctrl;
1384 if (flow_ctrl != RFCOMM_RPN_FLOW_NONE) { 1384 if (flow_ctrl != RFCOMM_RPN_FLOW_NONE) {
1385 BT_DBG("RPN flow ctrl mismatch 0x%x", flow_ctrl); 1385 BT_DBG("RPN flow ctrl mismatch 0x%x", flow_ctrl);
@@ -1388,7 +1388,7 @@ static int rfcomm_recv_rpn(struct rfcomm_session *s, int cr, int len, struct sk_
1388 } 1388 }
1389 } 1389 }
1390 1390
1391 if (rpn->param_mask & RFCOMM_RPN_PM_XON) { 1391 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_XON)) {
1392 xon_char = rpn->xon_char; 1392 xon_char = rpn->xon_char;
1393 if (xon_char != RFCOMM_RPN_XON_CHAR) { 1393 if (xon_char != RFCOMM_RPN_XON_CHAR) {
1394 BT_DBG("RPN XON char mismatch 0x%x", xon_char); 1394 BT_DBG("RPN XON char mismatch 0x%x", xon_char);
@@ -1397,7 +1397,7 @@ static int rfcomm_recv_rpn(struct rfcomm_session *s, int cr, int len, struct sk_
1397 } 1397 }
1398 } 1398 }
1399 1399
1400 if (rpn->param_mask & RFCOMM_RPN_PM_XOFF) { 1400 if (rpn->param_mask & cpu_to_le16(RFCOMM_RPN_PM_XOFF)) {
1401 xoff_char = rpn->xoff_char; 1401 xoff_char = rpn->xoff_char;
1402 if (xoff_char != RFCOMM_RPN_XOFF_CHAR) { 1402 if (xoff_char != RFCOMM_RPN_XOFF_CHAR) {
1403 BT_DBG("RPN XOFF char mismatch 0x%x", xoff_char); 1403 BT_DBG("RPN XOFF char mismatch 0x%x", xoff_char);
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 544d65b7ba..cb7e855f08 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -557,7 +557,6 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
557 struct sock *sk = sock->sk; 557 struct sock *sk = sock->sk;
558 struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc; 558 struct rfcomm_dlc *d = rfcomm_pi(sk)->dlc;
559 struct sk_buff *skb; 559 struct sk_buff *skb;
560 int err;
561 int sent = 0; 560 int sent = 0;
562 561
563 if (msg->msg_flags & MSG_OOB) 562 if (msg->msg_flags & MSG_OOB)
@@ -572,6 +571,7 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
572 571
573 while (len) { 572 while (len) {
574 size_t size = min_t(size_t, len, d->mtu); 573 size_t size = min_t(size_t, len, d->mtu);
574 int err;
575 575
576 skb = sock_alloc_send_skb(sk, size + RFCOMM_SKB_RESERVE, 576 skb = sock_alloc_send_skb(sk, size + RFCOMM_SKB_RESERVE,
577 msg->msg_flags & MSG_DONTWAIT, &err); 577 msg->msg_flags & MSG_DONTWAIT, &err);
@@ -582,13 +582,16 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
582 err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size); 582 err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
583 if (err) { 583 if (err) {
584 kfree_skb(skb); 584 kfree_skb(skb);
585 sent = err; 585 if (sent == 0)
586 sent = err;
586 break; 587 break;
587 } 588 }
588 589
589 err = rfcomm_dlc_send(d, skb); 590 err = rfcomm_dlc_send(d, skb);
590 if (err < 0) { 591 if (err < 0) {
591 kfree_skb(skb); 592 kfree_skb(skb);
593 if (sent == 0)
594 sent = err;
592 break; 595 break;
593 } 596 }
594 597
@@ -598,7 +601,7 @@ static int rfcomm_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
598 601
599 release_sock(sk); 602 release_sock(sk);
600 603
601 return sent ? sent : err; 604 return sent;
602} 605}
603 606
604static long rfcomm_sock_data_wait(struct sock *sk, long timeo) 607static long rfcomm_sock_data_wait(struct sock *sk, long timeo)
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index 1fb5d42f37..eb2b52484c 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -697,9 +697,13 @@ static int rfcomm_tty_write_room(struct tty_struct *tty)
697 697
698 BT_DBG("tty %p", tty); 698 BT_DBG("tty %p", tty);
699 699
700 if (!dev || !dev->dlc)
701 return 0;
702
700 room = rfcomm_room(dev->dlc) - atomic_read(&dev->wmem_alloc); 703 room = rfcomm_room(dev->dlc) - atomic_read(&dev->wmem_alloc);
701 if (room < 0) 704 if (room < 0)
702 room = 0; 705 room = 0;
706
703 return room; 707 return room;
704} 708}
705 709
@@ -752,9 +756,9 @@ static int rfcomm_tty_ioctl(struct tty_struct *tty, struct file *filp, unsigned
752 return -ENOIOCTLCMD; 756 return -ENOIOCTLCMD;
753} 757}
754 758
755static void rfcomm_tty_set_termios(struct tty_struct *tty, struct termios *old) 759static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
756{ 760{
757 struct termios *new = (struct termios *) tty->termios; 761 struct ktermios *new = tty->termios;
758 int old_baud_rate = tty_termios_baud_rate(old); 762 int old_baud_rate = tty_termios_baud_rate(old);
759 int new_baud_rate = tty_termios_baud_rate(new); 763 int new_baud_rate = tty_termios_baud_rate(new);
760 764
@@ -915,12 +919,14 @@ static void rfcomm_tty_unthrottle(struct tty_struct *tty)
915static int rfcomm_tty_chars_in_buffer(struct tty_struct *tty) 919static int rfcomm_tty_chars_in_buffer(struct tty_struct *tty)
916{ 920{
917 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; 921 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
918 struct rfcomm_dlc *dlc = dev->dlc;
919 922
920 BT_DBG("tty %p dev %p", tty, dev); 923 BT_DBG("tty %p dev %p", tty, dev);
921 924
922 if (!skb_queue_empty(&dlc->tx_queue)) 925 if (!dev || !dev->dlc)
923 return dlc->mtu; 926 return 0;
927
928 if (!skb_queue_empty(&dev->dlc->tx_queue))
929 return dev->dlc->mtu;
924 930
925 return 0; 931 return 0;
926} 932}
@@ -928,11 +934,12 @@ static int rfcomm_tty_chars_in_buffer(struct tty_struct *tty)
928static void rfcomm_tty_flush_buffer(struct tty_struct *tty) 934static void rfcomm_tty_flush_buffer(struct tty_struct *tty)
929{ 935{
930 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; 936 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
931 if (!dev)
932 return;
933 937
934 BT_DBG("tty %p dev %p", tty, dev); 938 BT_DBG("tty %p dev %p", tty, dev);
935 939
940 if (!dev || !dev->dlc)
941 return;
942
936 skb_queue_purge(&dev->dlc->tx_queue); 943 skb_queue_purge(&dev->dlc->tx_queue);
937 944
938 if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && tty->ldisc.write_wakeup) 945 if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && tty->ldisc.write_wakeup)
@@ -952,11 +959,12 @@ static void rfcomm_tty_wait_until_sent(struct tty_struct *tty, int timeout)
952static void rfcomm_tty_hangup(struct tty_struct *tty) 959static void rfcomm_tty_hangup(struct tty_struct *tty)
953{ 960{
954 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; 961 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
955 if (!dev)
956 return;
957 962
958 BT_DBG("tty %p dev %p", tty, dev); 963 BT_DBG("tty %p dev %p", tty, dev);
959 964
965 if (!dev)
966 return;
967
960 rfcomm_tty_flush_buffer(tty); 968 rfcomm_tty_flush_buffer(tty);
961 969
962 if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags)) 970 if (test_bit(RFCOMM_RELEASE_ONHUP, &dev->flags))
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
index d9f04864d1..8ca448db7a 100644
--- a/net/bridge/br_fdb.c
+++ b/net/bridge/br_fdb.c
@@ -23,7 +23,7 @@
23#include <asm/atomic.h> 23#include <asm/atomic.h>
24#include "br_private.h" 24#include "br_private.h"
25 25
26static kmem_cache_t *br_fdb_cache __read_mostly; 26static struct kmem_cache *br_fdb_cache __read_mostly;
27static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source, 27static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
28 const unsigned char *addr); 28 const unsigned char *addr);
29 29
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index f753c40c11..55bb2634c0 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -77,12 +77,16 @@ static int port_cost(struct net_device *dev)
77 * Called from work queue to allow for calling functions that 77 * Called from work queue to allow for calling functions that
78 * might sleep (such as speed check), and to debounce. 78 * might sleep (such as speed check), and to debounce.
79 */ 79 */
80static void port_carrier_check(void *arg) 80static void port_carrier_check(struct work_struct *work)
81{ 81{
82 struct net_device *dev = arg;
83 struct net_bridge_port *p; 82 struct net_bridge_port *p;
83 struct net_device *dev;
84 struct net_bridge *br; 84 struct net_bridge *br;
85 85
86 dev = container_of(work, struct net_bridge_port,
87 carrier_check.work)->dev;
88 work_release(work);
89
86 rtnl_lock(); 90 rtnl_lock();
87 p = dev->br_port; 91 p = dev->br_port;
88 if (!p) 92 if (!p)
@@ -276,7 +280,7 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br,
276 p->port_no = index; 280 p->port_no = index;
277 br_init_port(p); 281 br_init_port(p);
278 p->state = BR_STATE_DISABLED; 282 p->state = BR_STATE_DISABLED;
279 INIT_WORK(&p->carrier_check, port_carrier_check, dev); 283 INIT_DELAYED_WORK_NAR(&p->carrier_check, port_carrier_check);
280 br_stp_port_timer_init(p); 284 br_stp_port_timer_init(p);
281 285
282 kobject_init(&p->kobj); 286 kobject_init(&p->kobj);
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index ac181be13d..ea3337ad0e 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -34,13 +34,13 @@
34#include <linux/netfilter_ipv6.h> 34#include <linux/netfilter_ipv6.h>
35#include <linux/netfilter_arp.h> 35#include <linux/netfilter_arp.h>
36#include <linux/in_route.h> 36#include <linux/in_route.h>
37#include <linux/inetdevice.h>
37 38
38#include <net/ip.h> 39#include <net/ip.h>
39#include <net/ipv6.h> 40#include <net/ipv6.h>
40#include <net/route.h> 41#include <net/route.h>
41 42
42#include <asm/uaccess.h> 43#include <asm/uaccess.h>
43#include <asm/checksum.h>
44#include "br_private.h" 44#include "br_private.h"
45#ifdef CONFIG_SYSCTL 45#ifdef CONFIG_SYSCTL
46#include <linux/sysctl.h> 46#include <linux/sysctl.h>
@@ -61,9 +61,6 @@ static int brnf_filter_vlan_tagged __read_mostly = 1;
61#define brnf_filter_vlan_tagged 1 61#define brnf_filter_vlan_tagged 1
62#endif 62#endif
63 63
64int brnf_deferred_hooks;
65EXPORT_SYMBOL_GPL(brnf_deferred_hooks);
66
67static __be16 inline vlan_proto(const struct sk_buff *skb) 64static __be16 inline vlan_proto(const struct sk_buff *skb)
68{ 65{
69 return vlan_eth_hdr(skb)->h_vlan_encapsulated_proto; 66 return vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
@@ -222,10 +219,14 @@ static void __br_dnat_complain(void)
222 * 219 *
223 * Otherwise, the packet is considered to be routed and we just 220 * Otherwise, the packet is considered to be routed and we just
224 * change the destination MAC address so that the packet will 221 * change the destination MAC address so that the packet will
225 * later be passed up to the IP stack to be routed. 222 * later be passed up to the IP stack to be routed. For a redirected
223 * packet, ip_route_input() will give back the localhost as output device,
224 * which differs from the bridge device.
226 * 225 *
227 * Let us now consider the case that ip_route_input() fails: 226 * Let us now consider the case that ip_route_input() fails:
228 * 227 *
228 * This can be because the destination address is martian, in which case
229 * the packet will be dropped.
229 * After a "echo '0' > /proc/sys/net/ipv4/ip_forward" ip_route_input() 230 * After a "echo '0' > /proc/sys/net/ipv4/ip_forward" ip_route_input()
230 * will fail, while __ip_route_output_key() will return success. The source 231 * will fail, while __ip_route_output_key() will return success. The source
231 * address for __ip_route_output_key() is set to zero, so __ip_route_output_key 232 * address for __ip_route_output_key() is set to zero, so __ip_route_output_key
@@ -238,7 +239,8 @@ static void __br_dnat_complain(void)
238 * 239 *
239 * --Lennert, 20020411 240 * --Lennert, 20020411
240 * --Bart, 20020416 (updated) 241 * --Bart, 20020416 (updated)
241 * --Bart, 20021007 (updated) */ 242 * --Bart, 20021007 (updated)
243 * --Bart, 20062711 (updated) */
242static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb) 244static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb)
243{ 245{
244 if (skb->pkt_type == PACKET_OTHERHOST) { 246 if (skb->pkt_type == PACKET_OTHERHOST) {
@@ -265,15 +267,15 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb)
265 struct net_device *dev = skb->dev; 267 struct net_device *dev = skb->dev;
266 struct iphdr *iph = skb->nh.iph; 268 struct iphdr *iph = skb->nh.iph;
267 struct nf_bridge_info *nf_bridge = skb->nf_bridge; 269 struct nf_bridge_info *nf_bridge = skb->nf_bridge;
270 int err;
268 271
269 if (nf_bridge->mask & BRNF_PKT_TYPE) { 272 if (nf_bridge->mask & BRNF_PKT_TYPE) {
270 skb->pkt_type = PACKET_OTHERHOST; 273 skb->pkt_type = PACKET_OTHERHOST;
271 nf_bridge->mask ^= BRNF_PKT_TYPE; 274 nf_bridge->mask ^= BRNF_PKT_TYPE;
272 } 275 }
273 nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING; 276 nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING;
274
275 if (dnat_took_place(skb)) { 277 if (dnat_took_place(skb)) {
276 if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev)) { 278 if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) {
277 struct rtable *rt; 279 struct rtable *rt;
278 struct flowi fl = { 280 struct flowi fl = {
279 .nl_u = { 281 .nl_u = {
@@ -284,19 +286,33 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb)
284 }, 286 },
285 .proto = 0, 287 .proto = 0,
286 }; 288 };
289 struct in_device *in_dev = in_dev_get(dev);
290
291 /* If err equals -EHOSTUNREACH the error is due to a
292 * martian destination or due to the fact that
293 * forwarding is disabled. For most martian packets,
294 * ip_route_output_key() will fail. It won't fail for 2 types of
295 * martian destinations: loopback destinations and destination
296 * 0.0.0.0. In both cases the packet will be dropped because the
297 * destination is the loopback device and not the bridge. */
298 if (err != -EHOSTUNREACH || !in_dev || IN_DEV_FORWARD(in_dev))
299 goto free_skb;
287 300
288 if (!ip_route_output_key(&rt, &fl)) { 301 if (!ip_route_output_key(&rt, &fl)) {
289 /* - Bridged-and-DNAT'ed traffic doesn't 302 /* - Bridged-and-DNAT'ed traffic doesn't
290 * require ip_forwarding. 303 * require ip_forwarding. */
291 * - Deal with redirected traffic. */ 304 if (((struct dst_entry *)rt)->dev == dev) {
292 if (((struct dst_entry *)rt)->dev == dev ||
293 rt->rt_type == RTN_LOCAL) {
294 skb->dst = (struct dst_entry *)rt; 305 skb->dst = (struct dst_entry *)rt;
295 goto bridged_dnat; 306 goto bridged_dnat;
296 } 307 }
308 /* we are sure that forwarding is disabled, so printing
309 * this message is no problem. Note that the packet could
310 * still have a martian destination address, in which case
311 * the packet could be dropped even if forwarding were enabled */
297 __br_dnat_complain(); 312 __br_dnat_complain();
298 dst_release((struct dst_entry *)rt); 313 dst_release((struct dst_entry *)rt);
299 } 314 }
315free_skb:
300 kfree_skb(skb); 316 kfree_skb(skb);
301 return 0; 317 return 0;
302 } else { 318 } else {
@@ -381,7 +397,7 @@ static int check_hbh_len(struct sk_buff *skb)
381 case IPV6_TLV_JUMBO: 397 case IPV6_TLV_JUMBO:
382 if (skb->nh.raw[off + 1] != 4 || (off & 3) != 2) 398 if (skb->nh.raw[off + 1] != 4 || (off & 3) != 2)
383 goto bad; 399 goto bad;
384 pkt_len = ntohl(*(u32 *) (skb->nh.raw + off + 2)); 400 pkt_len = ntohl(*(__be32 *) (skb->nh.raw + off + 2));
385 if (pkt_len <= IPV6_MAXPLEN || 401 if (pkt_len <= IPV6_MAXPLEN ||
386 skb->nh.ipv6h->payload_len) 402 skb->nh.ipv6h->payload_len)
387 goto bad; 403 goto bad;
@@ -666,110 +682,50 @@ static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb,
666 return NF_STOLEN; 682 return NF_STOLEN;
667} 683}
668 684
669/* PF_BRIDGE/LOCAL_OUT ***********************************************/ 685/* PF_BRIDGE/LOCAL_OUT ***********************************************
670static int br_nf_local_out_finish(struct sk_buff *skb) 686 *
671{ 687 * This function sees both locally originated IP packets and forwarded
672 if (skb->protocol == htons(ETH_P_8021Q)) {
673 skb_push(skb, VLAN_HLEN);
674 skb->nh.raw -= VLAN_HLEN;
675 }
676
677 NF_HOOK_THRESH(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev,
678 br_forward_finish, NF_BR_PRI_FIRST + 1);
679
680 return 0;
681}
682
683/* This function sees both locally originated IP packets and forwarded
684 * IP packets (in both cases the destination device is a bridge 688 * IP packets (in both cases the destination device is a bridge
685 * device). It also sees bridged-and-DNAT'ed packets. 689 * device). It also sees bridged-and-DNAT'ed packets.
686 * To be able to filter on the physical bridge devices (with the physdev
687 * module), we steal packets destined to a bridge device away from the
688 * PF_INET/FORWARD and PF_INET/OUTPUT hook functions, and give them back later,
689 * when we have determined the real output device. This is done in here.
690 * 690 *
691 * If (nf_bridge->mask & BRNF_BRIDGED_DNAT) then the packet is bridged 691 * If (nf_bridge->mask & BRNF_BRIDGED_DNAT) then the packet is bridged
692 * and we fake the PF_BRIDGE/FORWARD hook. The function br_nf_forward() 692 * and we fake the PF_BRIDGE/FORWARD hook. The function br_nf_forward()
693 * will then fake the PF_INET/FORWARD hook. br_nf_local_out() has priority 693 * will then fake the PF_INET/FORWARD hook. br_nf_local_out() has priority
694 * NF_BR_PRI_FIRST, so no relevant PF_BRIDGE/INPUT functions have been nor 694 * NF_BR_PRI_FIRST, so no relevant PF_BRIDGE/INPUT functions have been nor
695 * will be executed. 695 * will be executed.
696 * Otherwise, if nf_bridge->physindev is NULL, the bridge-nf code never touched 696 */
697 * this packet before, and so the packet was locally originated. We fake
698 * the PF_INET/LOCAL_OUT hook.
699 * Finally, if nf_bridge->physindev isn't NULL, then the packet was IP routed,
700 * so we fake the PF_INET/FORWARD hook. ip_sabotage_out() makes sure
701 * even routed packets that didn't arrive on a bridge interface have their
702 * nf_bridge->physindev set. */
703static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb, 697static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb,
704 const struct net_device *in, 698 const struct net_device *in,
705 const struct net_device *out, 699 const struct net_device *out,
706 int (*okfn)(struct sk_buff *)) 700 int (*okfn)(struct sk_buff *))
707{ 701{
708 struct net_device *realindev, *realoutdev; 702 struct net_device *realindev;
709 struct sk_buff *skb = *pskb; 703 struct sk_buff *skb = *pskb;
710 struct nf_bridge_info *nf_bridge; 704 struct nf_bridge_info *nf_bridge;
711 int pf;
712 705
713 if (!skb->nf_bridge) 706 if (!skb->nf_bridge)
714 return NF_ACCEPT; 707 return NF_ACCEPT;
715 708
716 if (skb->protocol == htons(ETH_P_IP) || IS_VLAN_IP(skb))
717 pf = PF_INET;
718 else
719 pf = PF_INET6;
720
721 nf_bridge = skb->nf_bridge; 709 nf_bridge = skb->nf_bridge;
722 nf_bridge->physoutdev = skb->dev; 710 if (!(nf_bridge->mask & BRNF_BRIDGED_DNAT))
723 realindev = nf_bridge->physindev; 711 return NF_ACCEPT;
724 712
725 /* Bridged, take PF_BRIDGE/FORWARD. 713 /* Bridged, take PF_BRIDGE/FORWARD.
726 * (see big note in front of br_nf_pre_routing_finish) */ 714 * (see big note in front of br_nf_pre_routing_finish) */
727 if (nf_bridge->mask & BRNF_BRIDGED_DNAT) { 715 nf_bridge->physoutdev = skb->dev;
728 if (nf_bridge->mask & BRNF_PKT_TYPE) { 716 realindev = nf_bridge->physindev;
729 skb->pkt_type = PACKET_OTHERHOST;
730 nf_bridge->mask ^= BRNF_PKT_TYPE;
731 }
732 if (skb->protocol == htons(ETH_P_8021Q)) {
733 skb_push(skb, VLAN_HLEN);
734 skb->nh.raw -= VLAN_HLEN;
735 }
736 717
737 NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, realindev, 718 if (nf_bridge->mask & BRNF_PKT_TYPE) {
738 skb->dev, br_forward_finish); 719 skb->pkt_type = PACKET_OTHERHOST;
739 goto out; 720 nf_bridge->mask ^= BRNF_PKT_TYPE;
740 } 721 }
741 realoutdev = bridge_parent(skb->dev);
742 if (!realoutdev)
743 return NF_DROP;
744
745#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
746 /* iptables should match -o br0.x */
747 if (nf_bridge->netoutdev)
748 realoutdev = nf_bridge->netoutdev;
749#endif
750 if (skb->protocol == htons(ETH_P_8021Q)) { 722 if (skb->protocol == htons(ETH_P_8021Q)) {
751 skb_pull(skb, VLAN_HLEN); 723 skb_push(skb, VLAN_HLEN);
752 (*pskb)->nh.raw += VLAN_HLEN; 724 skb->nh.raw -= VLAN_HLEN;
753 }
754 /* IP forwarded traffic has a physindev, locally
755 * generated traffic hasn't. */
756 if (realindev != NULL) {
757 if (!(nf_bridge->mask & BRNF_DONT_TAKE_PARENT)) {
758 struct net_device *parent = bridge_parent(realindev);
759 if (parent)
760 realindev = parent;
761 }
762
763 NF_HOOK_THRESH(pf, NF_IP_FORWARD, skb, realindev,
764 realoutdev, br_nf_local_out_finish,
765 NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD + 1);
766 } else {
767 NF_HOOK_THRESH(pf, NF_IP_LOCAL_OUT, skb, realindev,
768 realoutdev, br_nf_local_out_finish,
769 NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT + 1);
770 } 725 }
771 726
772out: 727 NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, realindev, skb->dev,
728 br_forward_finish);
773 return NF_STOLEN; 729 return NF_STOLEN;
774} 730}
775 731
@@ -875,69 +831,6 @@ static unsigned int ip_sabotage_in(unsigned int hook, struct sk_buff **pskb,
875 return NF_ACCEPT; 831 return NF_ACCEPT;
876} 832}
877 833
878/* Postpone execution of PF_INET(6)/FORWARD, PF_INET(6)/LOCAL_OUT
879 * and PF_INET(6)/POST_ROUTING until we have done the forwarding
880 * decision in the bridge code and have determined nf_bridge->physoutdev. */
881static unsigned int ip_sabotage_out(unsigned int hook, struct sk_buff **pskb,
882 const struct net_device *in,
883 const struct net_device *out,
884 int (*okfn)(struct sk_buff *))
885{
886 struct sk_buff *skb = *pskb;
887
888 if ((out->hard_start_xmit == br_dev_xmit &&
889 okfn != br_nf_forward_finish &&
890 okfn != br_nf_local_out_finish && okfn != br_nf_dev_queue_xmit)
891#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
892 || ((out->priv_flags & IFF_802_1Q_VLAN) &&
893 VLAN_DEV_INFO(out)->real_dev->hard_start_xmit == br_dev_xmit)
894#endif
895 ) {
896 struct nf_bridge_info *nf_bridge;
897
898 if (!skb->nf_bridge) {
899#ifdef CONFIG_SYSCTL
900 /* This code is executed while in the IP(v6) stack,
901 the version should be 4 or 6. We can't use
902 skb->protocol because that isn't set on
903 PF_INET(6)/LOCAL_OUT. */
904 struct iphdr *ip = skb->nh.iph;
905
906 if (ip->version == 4 && !brnf_call_iptables)
907 return NF_ACCEPT;
908 else if (ip->version == 6 && !brnf_call_ip6tables)
909 return NF_ACCEPT;
910 else if (!brnf_deferred_hooks)
911 return NF_ACCEPT;
912#endif
913 if (hook == NF_IP_POST_ROUTING)
914 return NF_ACCEPT;
915 if (!nf_bridge_alloc(skb))
916 return NF_DROP;
917 }
918
919 nf_bridge = skb->nf_bridge;
920
921 /* This frame will arrive on PF_BRIDGE/LOCAL_OUT and we
922 * will need the indev then. For a brouter, the real indev
923 * can be a bridge port, so we make sure br_nf_local_out()
924 * doesn't use the bridge parent of the indev by using
925 * the BRNF_DONT_TAKE_PARENT mask. */
926 if (hook == NF_IP_FORWARD && nf_bridge->physindev == NULL) {
927 nf_bridge->mask |= BRNF_DONT_TAKE_PARENT;
928 nf_bridge->physindev = (struct net_device *)in;
929 }
930#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
931 /* the iptables outdev is br0.x, not br0 */
932 if (out->priv_flags & IFF_802_1Q_VLAN)
933 nf_bridge->netoutdev = (struct net_device *)out;
934#endif
935 return NF_STOP;
936 }
937
938 return NF_ACCEPT;
939}
940
941/* For br_nf_local_out we need (prio = NF_BR_PRI_FIRST), to insure that innocent 834/* For br_nf_local_out we need (prio = NF_BR_PRI_FIRST), to insure that innocent
942 * PF_BRIDGE/NF_BR_LOCAL_OUT functions don't get bridged traffic as input. 835 * PF_BRIDGE/NF_BR_LOCAL_OUT functions don't get bridged traffic as input.
943 * For br_nf_post_routing, we need (prio = NF_BR_PRI_LAST), because 836 * For br_nf_post_routing, we need (prio = NF_BR_PRI_LAST), because
@@ -983,36 +876,6 @@ static struct nf_hook_ops br_nf_ops[] = {
983 .pf = PF_INET6, 876 .pf = PF_INET6,
984 .hooknum = NF_IP6_PRE_ROUTING, 877 .hooknum = NF_IP6_PRE_ROUTING,
985 .priority = NF_IP6_PRI_FIRST, }, 878 .priority = NF_IP6_PRI_FIRST, },
986 { .hook = ip_sabotage_out,
987 .owner = THIS_MODULE,
988 .pf = PF_INET,
989 .hooknum = NF_IP_FORWARD,
990 .priority = NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD, },
991 { .hook = ip_sabotage_out,
992 .owner = THIS_MODULE,
993 .pf = PF_INET6,
994 .hooknum = NF_IP6_FORWARD,
995 .priority = NF_IP6_PRI_BRIDGE_SABOTAGE_FORWARD, },
996 { .hook = ip_sabotage_out,
997 .owner = THIS_MODULE,
998 .pf = PF_INET,
999 .hooknum = NF_IP_LOCAL_OUT,
1000 .priority = NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT, },
1001 { .hook = ip_sabotage_out,
1002 .owner = THIS_MODULE,
1003 .pf = PF_INET6,
1004 .hooknum = NF_IP6_LOCAL_OUT,
1005 .priority = NF_IP6_PRI_BRIDGE_SABOTAGE_LOCAL_OUT, },
1006 { .hook = ip_sabotage_out,
1007 .owner = THIS_MODULE,
1008 .pf = PF_INET,
1009 .hooknum = NF_IP_POST_ROUTING,
1010 .priority = NF_IP_PRI_FIRST, },
1011 { .hook = ip_sabotage_out,
1012 .owner = THIS_MODULE,
1013 .pf = PF_INET6,
1014 .hooknum = NF_IP6_POST_ROUTING,
1015 .priority = NF_IP6_PRI_FIRST, },
1016}; 879};
1017 880
1018#ifdef CONFIG_SYSCTL 881#ifdef CONFIG_SYSCTL
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index 8f661195d0..a9139682c4 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -15,6 +15,18 @@
15#include <net/netlink.h> 15#include <net/netlink.h>
16#include "br_private.h" 16#include "br_private.h"
17 17
18static inline size_t br_nlmsg_size(void)
19{
20 return NLMSG_ALIGN(sizeof(struct ifinfomsg))
21 + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
22 + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */
23 + nla_total_size(4) /* IFLA_MASTER */
24 + nla_total_size(4) /* IFLA_MTU */
25 + nla_total_size(4) /* IFLA_LINK */
26 + nla_total_size(1) /* IFLA_OPERSTATE */
27 + nla_total_size(1); /* IFLA_PROTINFO */
28}
29
18/* 30/*
19 * Create one netlink message for one interface 31 * Create one netlink message for one interface
20 * Contains port and master info as well as carrier and bridge state. 32 * Contains port and master info as well as carrier and bridge state.
@@ -24,51 +36,43 @@ static int br_fill_ifinfo(struct sk_buff *skb, const struct net_bridge_port *por
24{ 36{
25 const struct net_bridge *br = port->br; 37 const struct net_bridge *br = port->br;
26 const struct net_device *dev = port->dev; 38 const struct net_device *dev = port->dev;
27 struct ifinfomsg *r; 39 struct ifinfomsg *hdr;
28 struct nlmsghdr *nlh; 40 struct nlmsghdr *nlh;
29 unsigned char *b = skb->tail;
30 u32 mtu = dev->mtu;
31 u8 operstate = netif_running(dev) ? dev->operstate : IF_OPER_DOWN; 41 u8 operstate = netif_running(dev) ? dev->operstate : IF_OPER_DOWN;
32 u8 portstate = port->state;
33 42
34 pr_debug("br_fill_info event %d port %s master %s\n", 43 pr_debug("br_fill_info event %d port %s master %s\n",
35 event, dev->name, br->dev->name); 44 event, dev->name, br->dev->name);
36 45
37 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags); 46 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags);
38 r = NLMSG_DATA(nlh); 47 if (nlh == NULL)
39 r->ifi_family = AF_BRIDGE; 48 return -ENOBUFS;
40 r->__ifi_pad = 0;
41 r->ifi_type = dev->type;
42 r->ifi_index = dev->ifindex;
43 r->ifi_flags = dev_get_flags(dev);
44 r->ifi_change = 0;
45 49
46 RTA_PUT(skb, IFLA_IFNAME, strlen(dev->name)+1, dev->name); 50 hdr = nlmsg_data(nlh);
51 hdr->ifi_family = AF_BRIDGE;
52 hdr->__ifi_pad = 0;
53 hdr->ifi_type = dev->type;
54 hdr->ifi_index = dev->ifindex;
55 hdr->ifi_flags = dev_get_flags(dev);
56 hdr->ifi_change = 0;
47 57
48 RTA_PUT(skb, IFLA_MASTER, sizeof(int), &br->dev->ifindex); 58 NLA_PUT_STRING(skb, IFLA_IFNAME, dev->name);
59 NLA_PUT_U32(skb, IFLA_MASTER, br->dev->ifindex);
60 NLA_PUT_U32(skb, IFLA_MTU, dev->mtu);
61 NLA_PUT_U8(skb, IFLA_OPERSTATE, operstate);
49 62
50 if (dev->addr_len) 63 if (dev->addr_len)
51 RTA_PUT(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr); 64 NLA_PUT(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr);
52 65
53 RTA_PUT(skb, IFLA_MTU, sizeof(mtu), &mtu);
54 if (dev->ifindex != dev->iflink) 66 if (dev->ifindex != dev->iflink)
55 RTA_PUT(skb, IFLA_LINK, sizeof(int), &dev->iflink); 67 NLA_PUT_U32(skb, IFLA_LINK, dev->iflink);
56
57
58 RTA_PUT(skb, IFLA_OPERSTATE, sizeof(operstate), &operstate);
59 68
60 if (event == RTM_NEWLINK) 69 if (event == RTM_NEWLINK)
61 RTA_PUT(skb, IFLA_PROTINFO, sizeof(portstate), &portstate); 70 NLA_PUT_U8(skb, IFLA_PROTINFO, port->state);
62
63 nlh->nlmsg_len = skb->tail - b;
64
65 return skb->len;
66 71
67nlmsg_failure: 72 return nlmsg_end(skb, nlh);
68rtattr_failure:
69 73
70 skb_trim(skb, b - skb->data); 74nla_put_failure:
71 return -EINVAL; 75 return nlmsg_cancel(skb, nlh);
72} 76}
73 77
74/* 78/*
@@ -77,19 +81,16 @@ rtattr_failure:
77void br_ifinfo_notify(int event, struct net_bridge_port *port) 81void br_ifinfo_notify(int event, struct net_bridge_port *port)
78{ 82{
79 struct sk_buff *skb; 83 struct sk_buff *skb;
80 int payload = sizeof(struct ifinfomsg) + 128;
81 int err = -ENOBUFS; 84 int err = -ENOBUFS;
82 85
83 pr_debug("bridge notify event=%d\n", event); 86 pr_debug("bridge notify event=%d\n", event);
84 skb = nlmsg_new(nlmsg_total_size(payload), GFP_ATOMIC); 87 skb = nlmsg_new(br_nlmsg_size(), GFP_ATOMIC);
85 if (skb == NULL) 88 if (skb == NULL)
86 goto errout; 89 goto errout;
87 90
88 err = br_fill_ifinfo(skb, port, 0, 0, event, 0); 91 err = br_fill_ifinfo(skb, port, 0, 0, event, 0);
89 if (err < 0) { 92 /* failure implies BUG in br_nlmsg_size() */
90 kfree_skb(skb); 93 BUG_ON(err < 0);
91 goto errout;
92 }
93 94
94 err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC); 95 err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
95errout: 96errout:
@@ -104,25 +105,18 @@ static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
104{ 105{
105 struct net_device *dev; 106 struct net_device *dev;
106 int idx; 107 int idx;
107 int s_idx = cb->args[0];
108 int err = 0;
109 108
110 read_lock(&dev_base_lock); 109 read_lock(&dev_base_lock);
111 for (dev = dev_base, idx = 0; dev; dev = dev->next) { 110 for (dev = dev_base, idx = 0; dev; dev = dev->next) {
112 struct net_bridge_port *p = dev->br_port;
113
114 /* not a bridge port */ 111 /* not a bridge port */
115 if (!p) 112 if (dev->br_port == NULL || idx < cb->args[0])
116 continue; 113 goto skip;
117
118 if (idx < s_idx)
119 goto cont;
120 114
121 err = br_fill_ifinfo(skb, p, NETLINK_CB(cb->skb).pid, 115 if (br_fill_ifinfo(skb, dev->br_port, NETLINK_CB(cb->skb).pid,
122 cb->nlh->nlmsg_seq, RTM_NEWLINK, NLM_F_MULTI); 116 cb->nlh->nlmsg_seq, RTM_NEWLINK,
123 if (err <= 0) 117 NLM_F_MULTI) < 0)
124 break; 118 break;
125cont: 119skip:
126 ++idx; 120 ++idx;
127 } 121 }
128 read_unlock(&dev_base_lock); 122 read_unlock(&dev_base_lock);
@@ -138,26 +132,27 @@ cont:
138 */ 132 */
139static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 133static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
140{ 134{
141 struct rtattr **rta = arg; 135 struct ifinfomsg *ifm;
142 struct ifinfomsg *ifm = NLMSG_DATA(nlh); 136 struct nlattr *protinfo;
143 struct net_device *dev; 137 struct net_device *dev;
144 struct net_bridge_port *p; 138 struct net_bridge_port *p;
145 u8 new_state; 139 u8 new_state;
146 140
141 if (nlmsg_len(nlh) < sizeof(*ifm))
142 return -EINVAL;
143
144 ifm = nlmsg_data(nlh);
147 if (ifm->ifi_family != AF_BRIDGE) 145 if (ifm->ifi_family != AF_BRIDGE)
148 return -EPFNOSUPPORT; 146 return -EPFNOSUPPORT;
149 147
150 /* Must pass valid state as PROTINFO */ 148 protinfo = nlmsg_find_attr(nlh, sizeof(*ifm), IFLA_PROTINFO);
151 if (rta[IFLA_PROTINFO-1]) { 149 if (!protinfo || nla_len(protinfo) < sizeof(u8))
152 u8 *pstate = RTA_DATA(rta[IFLA_PROTINFO-1]);
153 new_state = *pstate;
154 } else
155 return -EINVAL; 150 return -EINVAL;
156 151
152 new_state = nla_get_u8(protinfo);
157 if (new_state > BR_STATE_BLOCKING) 153 if (new_state > BR_STATE_BLOCKING)
158 return -EINVAL; 154 return -EINVAL;
159 155
160 /* Find bridge port */
161 dev = __dev_get_by_index(ifm->ifi_index); 156 dev = __dev_get_by_index(ifm->ifi_index);
162 if (!dev) 157 if (!dev)
163 return -ENODEV; 158 return -ENODEV;
@@ -170,10 +165,8 @@ static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
170 if (p->br->stp_enabled) 165 if (p->br->stp_enabled)
171 return -EBUSY; 166 return -EBUSY;
172 167
173 if (!netif_running(dev)) 168 if (!netif_running(dev) ||
174 return -ENETDOWN; 169 (!netif_carrier_ok(dev) && new_state != BR_STATE_DISABLED))
175
176 if (!netif_carrier_ok(dev) && new_state != BR_STATE_DISABLED)
177 return -ENETDOWN; 170 return -ENETDOWN;
178 171
179 p->state = new_state; 172 p->state = new_state;
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 74258d86f2..3a534e94c7 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -82,7 +82,7 @@ struct net_bridge_port
82 struct timer_list hold_timer; 82 struct timer_list hold_timer;
83 struct timer_list message_age_timer; 83 struct timer_list message_age_timer;
84 struct kobject kobj; 84 struct kobject kobj;
85 struct work_struct carrier_check; 85 struct delayed_work carrier_check;
86 struct rcu_head rcu; 86 struct rcu_head rcu;
87}; 87};
88 88
diff --git a/net/bridge/netfilter/ebt_802_3.c b/net/bridge/netfilter/ebt_802_3.c
index d42f63f5e9..9abbc09ccd 100644
--- a/net/bridge/netfilter/ebt_802_3.c
+++ b/net/bridge/netfilter/ebt_802_3.c
@@ -17,7 +17,7 @@ static int ebt_filter_802_3(const struct sk_buff *skb, const struct net_device *
17{ 17{
18 struct ebt_802_3_info *info = (struct ebt_802_3_info *)data; 18 struct ebt_802_3_info *info = (struct ebt_802_3_info *)data;
19 struct ebt_802_3_hdr *hdr = ebt_802_3_hdr(skb); 19 struct ebt_802_3_hdr *hdr = ebt_802_3_hdr(skb);
20 uint16_t 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))
diff --git a/net/bridge/netfilter/ebt_among.c b/net/bridge/netfilter/ebt_among.c
index a614485828..ce97c4285f 100644
--- a/net/bridge/netfilter/ebt_among.c
+++ b/net/bridge/netfilter/ebt_among.c
@@ -15,7 +15,7 @@
15#include <linux/module.h> 15#include <linux/module.h>
16 16
17static int ebt_mac_wormhash_contains(const struct ebt_mac_wormhash *wh, 17static int ebt_mac_wormhash_contains(const struct ebt_mac_wormhash *wh,
18 const char *mac, uint32_t 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
@@ -70,7 +70,7 @@ static int ebt_mac_wormhash_check_integrity(const struct ebt_mac_wormhash
70 return 0; 70 return 0;
71} 71}
72 72
73static int get_ip_dst(const struct sk_buff *skb, uint32_t *addr) 73static int get_ip_dst(const struct sk_buff *skb, __be32 *addr)
74{ 74{
75 if (eth_hdr(skb)->h_proto == htons(ETH_P_IP)) { 75 if (eth_hdr(skb)->h_proto == htons(ETH_P_IP)) {
76 struct iphdr _iph, *ih; 76 struct iphdr _iph, *ih;
@@ -81,16 +81,16 @@ static int get_ip_dst(const struct sk_buff *skb, uint32_t *addr)
81 *addr = ih->daddr; 81 *addr = ih->daddr;
82 } else if (eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) { 82 } else if (eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) {
83 struct arphdr _arph, *ah; 83 struct arphdr _arph, *ah;
84 uint32_t buf, *bp; 84 __be32 buf, *bp;
85 85
86 ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph); 86 ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph);
87 if (ah == NULL || 87 if (ah == NULL ||
88 ah->ar_pln != sizeof(uint32_t) || 88 ah->ar_pln != sizeof(__be32) ||
89 ah->ar_hln != ETH_ALEN) 89 ah->ar_hln != ETH_ALEN)
90 return -1; 90 return -1;
91 bp = skb_header_pointer(skb, sizeof(struct arphdr) + 91 bp = skb_header_pointer(skb, sizeof(struct arphdr) +
92 2 * ETH_ALEN + sizeof(uint32_t), 92 2 * ETH_ALEN + sizeof(__be32),
93 sizeof(uint32_t), &buf); 93 sizeof(__be32), &buf);
94 if (bp == NULL) 94 if (bp == NULL)
95 return -1; 95 return -1;
96 *addr = *bp; 96 *addr = *bp;
@@ -98,7 +98,7 @@ static int get_ip_dst(const struct sk_buff *skb, uint32_t *addr)
98 return 0; 98 return 0;
99} 99}
100 100
101static int get_ip_src(const struct sk_buff *skb, uint32_t *addr) 101static int get_ip_src(const struct sk_buff *skb, __be32 *addr)
102{ 102{
103 if (eth_hdr(skb)->h_proto == htons(ETH_P_IP)) { 103 if (eth_hdr(skb)->h_proto == htons(ETH_P_IP)) {
104 struct iphdr _iph, *ih; 104 struct iphdr _iph, *ih;
@@ -109,15 +109,15 @@ static int get_ip_src(const struct sk_buff *skb, uint32_t *addr)
109 *addr = ih->saddr; 109 *addr = ih->saddr;
110 } else if (eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) { 110 } else if (eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) {
111 struct arphdr _arph, *ah; 111 struct arphdr _arph, *ah;
112 uint32_t buf, *bp; 112 __be32 buf, *bp;
113 113
114 ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph); 114 ah = skb_header_pointer(skb, 0, sizeof(_arph), &_arph);
115 if (ah == NULL || 115 if (ah == NULL ||
116 ah->ar_pln != sizeof(uint32_t) || 116 ah->ar_pln != sizeof(__be32) ||
117 ah->ar_hln != ETH_ALEN) 117 ah->ar_hln != ETH_ALEN)
118 return -1; 118 return -1;
119 bp = skb_header_pointer(skb, sizeof(struct arphdr) + 119 bp = skb_header_pointer(skb, sizeof(struct arphdr) +
120 ETH_ALEN, sizeof(uint32_t), &buf); 120 ETH_ALEN, sizeof(__be32), &buf);
121 if (bp == NULL) 121 if (bp == NULL)
122 return -1; 122 return -1;
123 *addr = *bp; 123 *addr = *bp;
@@ -133,7 +133,7 @@ static int ebt_filter_among(const struct sk_buff *skb,
133 struct ebt_among_info *info = (struct ebt_among_info *) data; 133 struct ebt_among_info *info = (struct ebt_among_info *) data;
134 const char *dmac, *smac; 134 const char *dmac, *smac;
135 const struct ebt_mac_wormhash *wh_dst, *wh_src; 135 const struct ebt_mac_wormhash *wh_dst, *wh_src;
136 uint32_t dip = 0, sip = 0; 136 __be32 dip = 0, sip = 0;
137 137
138 wh_dst = ebt_among_wh_dst(info); 138 wh_dst = ebt_among_wh_dst(info);
139 wh_src = ebt_among_wh_src(info); 139 wh_src = ebt_among_wh_src(info);
diff --git a/net/bridge/netfilter/ebt_arp.c b/net/bridge/netfilter/ebt_arp.c
index a6c81d9f73..9c599800a9 100644
--- a/net/bridge/netfilter/ebt_arp.c
+++ b/net/bridge/netfilter/ebt_arp.c
@@ -35,10 +35,10 @@ static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in
35 return EBT_NOMATCH; 35 return EBT_NOMATCH;
36 36
37 if (info->bitmask & (EBT_ARP_SRC_IP | EBT_ARP_DST_IP)) { 37 if (info->bitmask & (EBT_ARP_SRC_IP | EBT_ARP_DST_IP)) {
38 uint32_t _addr, *ap; 38 __be32 _addr, *ap;
39 39
40 /* IPv4 addresses are always 4 bytes */ 40 /* IPv4 addresses are always 4 bytes */
41 if (ah->ar_pln != sizeof(uint32_t)) 41 if (ah->ar_pln != sizeof(__be32))
42 return EBT_NOMATCH; 42 return EBT_NOMATCH;
43 if (info->bitmask & EBT_ARP_SRC_IP) { 43 if (info->bitmask & EBT_ARP_SRC_IP) {
44 ap = skb_header_pointer(skb, sizeof(struct arphdr) + 44 ap = skb_header_pointer(skb, sizeof(struct arphdr) +
@@ -53,7 +53,7 @@ static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in
53 53
54 if (info->bitmask & EBT_ARP_DST_IP) { 54 if (info->bitmask & EBT_ARP_DST_IP) {
55 ap = skb_header_pointer(skb, sizeof(struct arphdr) + 55 ap = skb_header_pointer(skb, sizeof(struct arphdr) +
56 2*ah->ar_hln+sizeof(uint32_t), 56 2*ah->ar_hln+sizeof(__be32),
57 sizeof(_addr), &_addr); 57 sizeof(_addr), &_addr);
58 if (ap == NULL) 58 if (ap == NULL)
59 return EBT_NOMATCH; 59 return EBT_NOMATCH;
diff --git a/net/bridge/netfilter/ebt_ip.c b/net/bridge/netfilter/ebt_ip.c
index 65b665ce57..e4c642448e 100644
--- a/net/bridge/netfilter/ebt_ip.c
+++ b/net/bridge/netfilter/ebt_ip.c
@@ -20,8 +20,8 @@
20#include <linux/module.h> 20#include <linux/module.h>
21 21
22struct tcpudphdr { 22struct tcpudphdr {
23 uint16_t src; 23 __be16 src;
24 uint16_t dst; 24 __be16 dst;
25}; 25};
26 26
27static int ebt_filter_ip(const struct sk_buff *skb, const struct net_device *in, 27static int ebt_filter_ip(const struct sk_buff *skb, const struct net_device *in,
diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c
index 466ed3440b..a184f879f2 100644
--- a/net/bridge/netfilter/ebt_log.c
+++ b/net/bridge/netfilter/ebt_log.c
@@ -38,8 +38,8 @@ static int ebt_log_check(const char *tablename, unsigned int hookmask,
38 38
39struct tcpudphdr 39struct tcpudphdr
40{ 40{
41 uint16_t src; 41 __be16 src;
42 uint16_t dst; 42 __be16 dst;
43}; 43};
44 44
45struct arppayload 45struct arppayload
@@ -130,7 +130,7 @@ ebt_log_packet(unsigned int pf, unsigned int hooknum,
130 * then log the ARP payload */ 130 * then log the ARP payload */
131 if (ah->ar_hrd == htons(1) && 131 if (ah->ar_hrd == htons(1) &&
132 ah->ar_hln == ETH_ALEN && 132 ah->ar_hln == ETH_ALEN &&
133 ah->ar_pln == sizeof(uint32_t)) { 133 ah->ar_pln == sizeof(__be32)) {
134 struct arppayload _arpp, *ap; 134 struct arppayload _arpp, *ap;
135 135
136 ap = skb_header_pointer(skb, sizeof(_arph), 136 ap = skb_header_pointer(skb, sizeof(_arph),
diff --git a/net/bridge/netfilter/ebt_mark.c b/net/bridge/netfilter/ebt_mark.c
index b54306a934..62d23c7b25 100644
--- a/net/bridge/netfilter/ebt_mark.c
+++ b/net/bridge/netfilter/ebt_mark.c
@@ -25,15 +25,15 @@ static int ebt_target_mark(struct sk_buff **pskb, unsigned int hooknr,
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)
28 (*pskb)->nfmark = info->mark; 28 (*pskb)->mark = info->mark;
29 else if (action == MARK_OR_VALUE) 29 else if (action == MARK_OR_VALUE)
30 (*pskb)->nfmark |= info->mark; 30 (*pskb)->mark |= info->mark;
31 else if (action == MARK_AND_VALUE) 31 else if (action == MARK_AND_VALUE)
32 (*pskb)->nfmark &= info->mark; 32 (*pskb)->mark &= info->mark;
33 else 33 else
34 (*pskb)->nfmark ^= info->mark; 34 (*pskb)->mark ^= info->mark;
35 35
36 return info->target | -16; 36 return info->target | ~EBT_VERDICT_BITS;
37} 37}
38 38
39static int ebt_target_mark_check(const char *tablename, unsigned int hookmask, 39static int ebt_target_mark_check(const char *tablename, unsigned int hookmask,
@@ -44,13 +44,13 @@ static int ebt_target_mark_check(const char *tablename, unsigned int hookmask,
44 44
45 if (datalen != EBT_ALIGN(sizeof(struct ebt_mark_t_info))) 45 if (datalen != EBT_ALIGN(sizeof(struct ebt_mark_t_info)))
46 return -EINVAL; 46 return -EINVAL;
47 tmp = info->target | -16; 47 tmp = info->target | ~EBT_VERDICT_BITS;
48 if (BASE_CHAIN && tmp == EBT_RETURN) 48 if (BASE_CHAIN && tmp == EBT_RETURN)
49 return -EINVAL; 49 return -EINVAL;
50 CLEAR_BASE_CHAIN_BIT; 50 CLEAR_BASE_CHAIN_BIT;
51 if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0) 51 if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0)
52 return -EINVAL; 52 return -EINVAL;
53 tmp = info->target & -16; 53 tmp = info->target & ~EBT_VERDICT_BITS;
54 if (tmp != MARK_SET_VALUE && tmp != MARK_OR_VALUE && 54 if (tmp != MARK_SET_VALUE && tmp != MARK_OR_VALUE &&
55 tmp != MARK_AND_VALUE && tmp != MARK_XOR_VALUE) 55 tmp != MARK_AND_VALUE && tmp != MARK_XOR_VALUE)
56 return -EINVAL; 56 return -EINVAL;
diff --git a/net/bridge/netfilter/ebt_mark_m.c b/net/bridge/netfilter/ebt_mark_m.c
index a6413e4b49..025869ee0b 100644
--- a/net/bridge/netfilter/ebt_mark_m.c
+++ b/net/bridge/netfilter/ebt_mark_m.c
@@ -19,8 +19,8 @@ static int ebt_filter_mark(const struct sk_buff *skb,
19 struct ebt_mark_m_info *info = (struct ebt_mark_m_info *) data; 19 struct ebt_mark_m_info *info = (struct ebt_mark_m_info *) data;
20 20
21 if (info->bitmask & EBT_MARK_OR) 21 if (info->bitmask & EBT_MARK_OR)
22 return !(!!(skb->nfmark & info->mask) ^ info->invert); 22 return !(!!(skb->mark & info->mask) ^ info->invert);
23 return !(((skb->nfmark & info->mask) == info->mark) ^ info->invert); 23 return !(((skb->mark & info->mask) == info->mark) ^ info->invert);
24} 24}
25 25
26static int ebt_mark_check(const char *tablename, unsigned int hookmask, 26static int ebt_mark_check(const char *tablename, unsigned int hookmask,
diff --git a/net/bridge/netfilter/ebt_snat.c b/net/bridge/netfilter/ebt_snat.c
index cbb33e24ca..a50722182b 100644
--- a/net/bridge/netfilter/ebt_snat.c
+++ b/net/bridge/netfilter/ebt_snat.c
@@ -12,6 +12,8 @@
12#include <linux/netfilter_bridge/ebt_nat.h> 12#include <linux/netfilter_bridge/ebt_nat.h>
13#include <linux/module.h> 13#include <linux/module.h>
14#include <net/sock.h> 14#include <net/sock.h>
15#include <linux/if_arp.h>
16#include <net/arp.h>
15 17
16static int ebt_target_snat(struct sk_buff **pskb, unsigned int hooknr, 18static int ebt_target_snat(struct sk_buff **pskb, unsigned int hooknr,
17 const struct net_device *in, const struct net_device *out, 19 const struct net_device *in, const struct net_device *out,
@@ -31,24 +33,43 @@ static int ebt_target_snat(struct sk_buff **pskb, unsigned int hooknr,
31 *pskb = nskb; 33 *pskb = nskb;
32 } 34 }
33 memcpy(eth_hdr(*pskb)->h_source, info->mac, ETH_ALEN); 35 memcpy(eth_hdr(*pskb)->h_source, info->mac, ETH_ALEN);
34 return info->target; 36 if (!(info->target & NAT_ARP_BIT) &&
37 eth_hdr(*pskb)->h_proto == htons(ETH_P_ARP)) {
38 struct arphdr _ah, *ap;
39
40 ap = skb_header_pointer(*pskb, 0, sizeof(_ah), &_ah);
41 if (ap == NULL)
42 return EBT_DROP;
43 if (ap->ar_hln != ETH_ALEN)
44 goto out;
45 if (skb_store_bits(*pskb, sizeof(_ah), info->mac,ETH_ALEN))
46 return EBT_DROP;
47 }
48out:
49 return info->target | ~EBT_VERDICT_BITS;
35} 50}
36 51
37static int ebt_target_snat_check(const char *tablename, unsigned int hookmask, 52static int ebt_target_snat_check(const char *tablename, unsigned int hookmask,
38 const struct ebt_entry *e, void *data, unsigned int datalen) 53 const struct ebt_entry *e, void *data, unsigned int datalen)
39{ 54{
40 struct ebt_nat_info *info = (struct ebt_nat_info *) data; 55 struct ebt_nat_info *info = (struct ebt_nat_info *) data;
56 int tmp;
41 57
42 if (datalen != EBT_ALIGN(sizeof(struct ebt_nat_info))) 58 if (datalen != EBT_ALIGN(sizeof(struct ebt_nat_info)))
43 return -EINVAL; 59 return -EINVAL;
44 if (BASE_CHAIN && info->target == EBT_RETURN) 60 tmp = info->target | ~EBT_VERDICT_BITS;
61 if (BASE_CHAIN && tmp == EBT_RETURN)
45 return -EINVAL; 62 return -EINVAL;
46 CLEAR_BASE_CHAIN_BIT; 63 CLEAR_BASE_CHAIN_BIT;
47 if (strcmp(tablename, "nat")) 64 if (strcmp(tablename, "nat"))
48 return -EINVAL; 65 return -EINVAL;
49 if (hookmask & ~(1 << NF_BR_POST_ROUTING)) 66 if (hookmask & ~(1 << NF_BR_POST_ROUTING))
50 return -EINVAL; 67 return -EINVAL;
51 if (INVALID_TARGET) 68
69 if (tmp < -NUM_STANDARD_TARGETS || tmp >= 0)
70 return -EINVAL;
71 tmp = info->target | EBT_VERDICT_BITS;
72 if ((tmp & ~NAT_ARP_BIT) != ~NAT_ARP_BIT)
52 return -EINVAL; 73 return -EINVAL;
53 return 0; 74 return 0;
54} 75}
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c
index 9f950db3b7..c1af68b5a2 100644
--- a/net/bridge/netfilter/ebt_ulog.c
+++ b/net/bridge/netfilter/ebt_ulog.c
@@ -168,7 +168,7 @@ static void ebt_ulog_packet(unsigned int hooknr, const struct sk_buff *skb,
168 if (ub->qlen == 1) 168 if (ub->qlen == 1)
169 skb_set_timestamp(ub->skb, &pm->stamp); 169 skb_set_timestamp(ub->skb, &pm->stamp);
170 pm->data_len = copy_len; 170 pm->data_len = copy_len;
171 pm->mark = skb->nfmark; 171 pm->mark = skb->mark;
172 pm->hook = hooknr; 172 pm->hook = hooknr;
173 if (uloginfo->prefix != NULL) 173 if (uloginfo->prefix != NULL)
174 strcpy(pm->prefix, uloginfo->prefix); 174 strcpy(pm->prefix, uloginfo->prefix);
diff --git a/net/bridge/netfilter/ebt_vlan.c b/net/bridge/netfilter/ebt_vlan.c
index a2b452862b..7ee3776229 100644
--- a/net/bridge/netfilter/ebt_vlan.c
+++ b/net/bridge/netfilter/ebt_vlan.c
@@ -55,7 +55,7 @@ ebt_filter_vlan(const struct sk_buff *skb,
55 unsigned short id; /* VLAN ID, given from frame TCI */ 55 unsigned short id; /* VLAN ID, given from frame TCI */
56 unsigned char prio; /* user_priority, given from frame TCI */ 56 unsigned char prio; /* user_priority, given from frame TCI */
57 /* VLAN encapsulated Type/Length field, given from orig frame */ 57 /* VLAN encapsulated Type/Length field, given from orig frame */
58 unsigned short encap; 58 __be16 encap;
59 59
60 fp = skb_header_pointer(skb, 0, sizeof(_frame), &_frame); 60 fp = skb_header_pointer(skb, 0, sizeof(_frame), &_frame);
61 if (fp == NULL) 61 if (fp == NULL)
diff --git a/net/bridge/netfilter/ebtable_broute.c b/net/bridge/netfilter/ebtable_broute.c
index 9a6e548e14..d37ce04789 100644
--- a/net/bridge/netfilter/ebtable_broute.c
+++ b/net/bridge/netfilter/ebtable_broute.c
@@ -23,7 +23,7 @@ static struct ebt_entries initial_chain = {
23 .policy = EBT_ACCEPT, 23 .policy = EBT_ACCEPT,
24}; 24};
25 25
26static struct ebt_replace initial_table = 26static struct ebt_replace_kernel initial_table =
27{ 27{
28 .name = "broute", 28 .name = "broute",
29 .valid_hooks = 1 << NF_BR_BROUTING, 29 .valid_hooks = 1 << NF_BR_BROUTING,
diff --git a/net/bridge/netfilter/ebtable_filter.c b/net/bridge/netfilter/ebtable_filter.c
index 3d5bd44f23..127135ead2 100644
--- a/net/bridge/netfilter/ebtable_filter.c
+++ b/net/bridge/netfilter/ebtable_filter.c
@@ -30,7 +30,7 @@ static struct ebt_entries initial_chains[] =
30 }, 30 },
31}; 31};
32 32
33static struct ebt_replace initial_table = 33static struct ebt_replace_kernel initial_table =
34{ 34{
35 .name = "filter", 35 .name = "filter",
36 .valid_hooks = FILTER_VALID_HOOKS, 36 .valid_hooks = FILTER_VALID_HOOKS,
diff --git a/net/bridge/netfilter/ebtable_nat.c b/net/bridge/netfilter/ebtable_nat.c
index 04dd42efda..9c50488b62 100644
--- a/net/bridge/netfilter/ebtable_nat.c
+++ b/net/bridge/netfilter/ebtable_nat.c
@@ -30,7 +30,7 @@ static struct ebt_entries initial_chains[] =
30 } 30 }
31}; 31};
32 32
33static struct ebt_replace initial_table = 33static struct ebt_replace_kernel initial_table =
34{ 34{
35 .name = "nat", 35 .name = "nat",
36 .valid_hooks = NAT_VALID_HOOKS, 36 .valid_hooks = NAT_VALID_HOOKS,
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index 9f85666f29..6c84ccb8c9 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -338,10 +338,11 @@ ebt_check_match(struct ebt_entry_match *m, struct ebt_entry *e,
338 const char *name, unsigned int hookmask, unsigned int *cnt) 338 const char *name, unsigned int hookmask, unsigned int *cnt)
339{ 339{
340 struct ebt_match *match; 340 struct ebt_match *match;
341 size_t left = ((char *)e + e->watchers_offset) - (char *)m;
341 int ret; 342 int ret;
342 343
343 if (((char *)m) + m->match_size + sizeof(struct ebt_entry_match) > 344 if (left < sizeof(struct ebt_entry_match) ||
344 ((char *)e) + e->watchers_offset) 345 left - sizeof(struct ebt_entry_match) < m->match_size)
345 return -EINVAL; 346 return -EINVAL;
346 match = find_match_lock(m->u.name, &ret, &ebt_mutex); 347 match = find_match_lock(m->u.name, &ret, &ebt_mutex);
347 if (!match) 348 if (!match)
@@ -367,10 +368,11 @@ ebt_check_watcher(struct ebt_entry_watcher *w, struct ebt_entry *e,
367 const char *name, unsigned int hookmask, unsigned int *cnt) 368 const char *name, unsigned int hookmask, unsigned int *cnt)
368{ 369{
369 struct ebt_watcher *watcher; 370 struct ebt_watcher *watcher;
371 size_t left = ((char *)e + e->target_offset) - (char *)w;
370 int ret; 372 int ret;
371 373
372 if (((char *)w) + w->watcher_size + sizeof(struct ebt_entry_watcher) > 374 if (left < sizeof(struct ebt_entry_watcher) ||
373 ((char *)e) + e->target_offset) 375 left - sizeof(struct ebt_entry_watcher) < w->watcher_size)
374 return -EINVAL; 376 return -EINVAL;
375 watcher = find_watcher_lock(w->u.name, &ret, &ebt_mutex); 377 watcher = find_watcher_lock(w->u.name, &ret, &ebt_mutex);
376 if (!watcher) 378 if (!watcher)
@@ -391,35 +393,91 @@ ebt_check_watcher(struct ebt_entry_watcher *w, struct ebt_entry *e,
391 return 0; 393 return 0;
392} 394}
393 395
396static int ebt_verify_pointers(struct ebt_replace *repl,
397 struct ebt_table_info *newinfo)
398{
399 unsigned int limit = repl->entries_size;
400 unsigned int valid_hooks = repl->valid_hooks;
401 unsigned int offset = 0;
402 int i;
403
404 for (i = 0; i < NF_BR_NUMHOOKS; i++)
405 newinfo->hook_entry[i] = NULL;
406
407 newinfo->entries_size = repl->entries_size;
408 newinfo->nentries = repl->nentries;
409
410 while (offset < limit) {
411 size_t left = limit - offset;
412 struct ebt_entry *e = (void *)newinfo->entries + offset;
413
414 if (left < sizeof(unsigned int))
415 break;
416
417 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
418 if ((valid_hooks & (1 << i)) == 0)
419 continue;
420 if ((char __user *)repl->hook_entry[i] ==
421 repl->entries + offset)
422 break;
423 }
424
425 if (i != NF_BR_NUMHOOKS || !(e->bitmask & EBT_ENTRY_OR_ENTRIES)) {
426 if (e->bitmask != 0) {
427 /* we make userspace set this right,
428 so there is no misunderstanding */
429 BUGPRINT("EBT_ENTRY_OR_ENTRIES shouldn't be set "
430 "in distinguisher\n");
431 return -EINVAL;
432 }
433 if (i != NF_BR_NUMHOOKS)
434 newinfo->hook_entry[i] = (struct ebt_entries *)e;
435 if (left < sizeof(struct ebt_entries))
436 break;
437 offset += sizeof(struct ebt_entries);
438 } else {
439 if (left < sizeof(struct ebt_entry))
440 break;
441 if (left < e->next_offset)
442 break;
443 offset += e->next_offset;
444 }
445 }
446 if (offset != limit) {
447 BUGPRINT("entries_size too small\n");
448 return -EINVAL;
449 }
450
451 /* check if all valid hooks have a chain */
452 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
453 if (!newinfo->hook_entry[i] &&
454 (valid_hooks & (1 << i))) {
455 BUGPRINT("Valid hook without chain\n");
456 return -EINVAL;
457 }
458 }
459 return 0;
460}
461
394/* 462/*
395 * this one is very careful, as it is the first function 463 * this one is very careful, as it is the first function
396 * to parse the userspace data 464 * to parse the userspace data
397 */ 465 */
398static inline int 466static inline int
399ebt_check_entry_size_and_hooks(struct ebt_entry *e, 467ebt_check_entry_size_and_hooks(struct ebt_entry *e,
400 struct ebt_table_info *newinfo, char *base, char *limit, 468 struct ebt_table_info *newinfo,
401 struct ebt_entries **hook_entries, unsigned int *n, unsigned int *cnt, 469 unsigned int *n, unsigned int *cnt,
402 unsigned int *totalcnt, unsigned int *udc_cnt, unsigned int valid_hooks) 470 unsigned int *totalcnt, unsigned int *udc_cnt)
403{ 471{
404 int i; 472 int i;
405 473
406 for (i = 0; i < NF_BR_NUMHOOKS; i++) { 474 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
407 if ((valid_hooks & (1 << i)) == 0) 475 if ((void *)e == (void *)newinfo->hook_entry[i])
408 continue;
409 if ( (char *)hook_entries[i] - base ==
410 (char *)e - newinfo->entries)
411 break; 476 break;
412 } 477 }
413 /* beginning of a new chain 478 /* beginning of a new chain
414 if i == NF_BR_NUMHOOKS it must be a user defined chain */ 479 if i == NF_BR_NUMHOOKS it must be a user defined chain */
415 if (i != NF_BR_NUMHOOKS || !(e->bitmask & EBT_ENTRY_OR_ENTRIES)) { 480 if (i != NF_BR_NUMHOOKS || !e->bitmask) {
416 if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) != 0) {
417 /* we make userspace set this right,
418 so there is no misunderstanding */
419 BUGPRINT("EBT_ENTRY_OR_ENTRIES shouldn't be set "
420 "in distinguisher\n");
421 return -EINVAL;
422 }
423 /* this checks if the previous chain has as many entries 481 /* this checks if the previous chain has as many entries
424 as it said it has */ 482 as it said it has */
425 if (*n != *cnt) { 483 if (*n != *cnt) {
@@ -427,12 +485,6 @@ ebt_check_entry_size_and_hooks(struct ebt_entry *e,
427 "in the chain\n"); 485 "in the chain\n");
428 return -EINVAL; 486 return -EINVAL;
429 } 487 }
430 /* before we look at the struct, be sure it is not too big */
431 if ((char *)hook_entries[i] + sizeof(struct ebt_entries)
432 > limit) {
433 BUGPRINT("entries_size too small\n");
434 return -EINVAL;
435 }
436 if (((struct ebt_entries *)e)->policy != EBT_DROP && 488 if (((struct ebt_entries *)e)->policy != EBT_DROP &&
437 ((struct ebt_entries *)e)->policy != EBT_ACCEPT) { 489 ((struct ebt_entries *)e)->policy != EBT_ACCEPT) {
438 /* only RETURN from udc */ 490 /* only RETURN from udc */
@@ -444,8 +496,6 @@ ebt_check_entry_size_and_hooks(struct ebt_entry *e,
444 } 496 }
445 if (i == NF_BR_NUMHOOKS) /* it's a user defined chain */ 497 if (i == NF_BR_NUMHOOKS) /* it's a user defined chain */
446 (*udc_cnt)++; 498 (*udc_cnt)++;
447 else
448 newinfo->hook_entry[i] = (struct ebt_entries *)e;
449 if (((struct ebt_entries *)e)->counter_offset != *totalcnt) { 499 if (((struct ebt_entries *)e)->counter_offset != *totalcnt) {
450 BUGPRINT("counter_offset != totalcnt"); 500 BUGPRINT("counter_offset != totalcnt");
451 return -EINVAL; 501 return -EINVAL;
@@ -466,7 +516,6 @@ ebt_check_entry_size_and_hooks(struct ebt_entry *e,
466 BUGPRINT("target size too small\n"); 516 BUGPRINT("target size too small\n");
467 return -EINVAL; 517 return -EINVAL;
468 } 518 }
469
470 (*cnt)++; 519 (*cnt)++;
471 (*totalcnt)++; 520 (*totalcnt)++;
472 return 0; 521 return 0;
@@ -485,17 +534,14 @@ struct ebt_cl_stack
485 */ 534 */
486static inline int 535static inline int
487ebt_get_udc_positions(struct ebt_entry *e, struct ebt_table_info *newinfo, 536ebt_get_udc_positions(struct ebt_entry *e, struct ebt_table_info *newinfo,
488 struct ebt_entries **hook_entries, unsigned int *n, unsigned int valid_hooks, 537 unsigned int *n, struct ebt_cl_stack *udc)
489 struct ebt_cl_stack *udc)
490{ 538{
491 int i; 539 int i;
492 540
493 /* we're only interested in chain starts */ 541 /* we're only interested in chain starts */
494 if (e->bitmask & EBT_ENTRY_OR_ENTRIES) 542 if (e->bitmask)
495 return 0; 543 return 0;
496 for (i = 0; i < NF_BR_NUMHOOKS; i++) { 544 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
497 if ((valid_hooks & (1 << i)) == 0)
498 continue;
499 if (newinfo->hook_entry[i] == (struct ebt_entries *)e) 545 if (newinfo->hook_entry[i] == (struct ebt_entries *)e)
500 break; 546 break;
501 } 547 }
@@ -541,7 +587,7 @@ ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt)
541{ 587{
542 struct ebt_entry_target *t; 588 struct ebt_entry_target *t;
543 589
544 if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0) 590 if (e->bitmask == 0)
545 return 0; 591 return 0;
546 /* we're done */ 592 /* we're done */
547 if (cnt && (*cnt)-- == 0) 593 if (cnt && (*cnt)-- == 0)
@@ -558,16 +604,17 @@ ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt)
558 604
559static inline int 605static inline int
560ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo, 606ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
561 const char *name, unsigned int *cnt, unsigned int valid_hooks, 607 const char *name, unsigned int *cnt,
562 struct ebt_cl_stack *cl_s, unsigned int udc_cnt) 608 struct ebt_cl_stack *cl_s, unsigned int udc_cnt)
563{ 609{
564 struct ebt_entry_target *t; 610 struct ebt_entry_target *t;
565 struct ebt_target *target; 611 struct ebt_target *target;
566 unsigned int i, j, hook = 0, hookmask = 0; 612 unsigned int i, j, hook = 0, hookmask = 0;
613 size_t gap;
567 int ret; 614 int ret;
568 615
569 /* don't mess with the struct ebt_entries */ 616 /* don't mess with the struct ebt_entries */
570 if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0) 617 if (e->bitmask == 0)
571 return 0; 618 return 0;
572 619
573 if (e->bitmask & ~EBT_F_MASK) { 620 if (e->bitmask & ~EBT_F_MASK) {
@@ -584,7 +631,7 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
584 } 631 }
585 /* what hook do we belong to? */ 632 /* what hook do we belong to? */
586 for (i = 0; i < NF_BR_NUMHOOKS; i++) { 633 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
587 if ((valid_hooks & (1 << i)) == 0) 634 if (!newinfo->hook_entry[i])
588 continue; 635 continue;
589 if ((char *)newinfo->hook_entry[i] < (char *)e) 636 if ((char *)newinfo->hook_entry[i] < (char *)e)
590 hook = i; 637 hook = i;
@@ -613,6 +660,7 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
613 if (ret != 0) 660 if (ret != 0)
614 goto cleanup_watchers; 661 goto cleanup_watchers;
615 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset); 662 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
663 gap = e->next_offset - e->target_offset;
616 target = find_target_lock(t->u.name, &ret, &ebt_mutex); 664 target = find_target_lock(t->u.name, &ret, &ebt_mutex);
617 if (!target) 665 if (!target)
618 goto cleanup_watchers; 666 goto cleanup_watchers;
@@ -625,8 +673,7 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
625 673
626 t->u.target = target; 674 t->u.target = target;
627 if (t->u.target == &ebt_standard_target) { 675 if (t->u.target == &ebt_standard_target) {
628 if (e->target_offset + sizeof(struct ebt_standard_target) > 676 if (gap < sizeof(struct ebt_standard_target)) {
629 e->next_offset) {
630 BUGPRINT("Standard target size too big\n"); 677 BUGPRINT("Standard target size too big\n");
631 ret = -EFAULT; 678 ret = -EFAULT;
632 goto cleanup_watchers; 679 goto cleanup_watchers;
@@ -637,8 +684,7 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
637 ret = -EFAULT; 684 ret = -EFAULT;
638 goto cleanup_watchers; 685 goto cleanup_watchers;
639 } 686 }
640 } else if ((e->target_offset + t->target_size + 687 } else if (t->target_size > gap - sizeof(struct ebt_entry_target) ||
641 sizeof(struct ebt_entry_target) > e->next_offset) ||
642 (t->u.target->check && 688 (t->u.target->check &&
643 t->u.target->check(name, hookmask, e, t->data, t->target_size) != 0)){ 689 t->u.target->check(name, hookmask, e, t->data, t->target_size) != 0)){
644 module_put(t->u.target->me); 690 module_put(t->u.target->me);
@@ -708,7 +754,9 @@ static int check_chainloops(struct ebt_entries *chain, struct ebt_cl_stack *cl_s
708 BUGPRINT("loop\n"); 754 BUGPRINT("loop\n");
709 return -1; 755 return -1;
710 } 756 }
711 /* this can't be 0, so the above test is correct */ 757 if (cl_s[i].hookmask & (1 << hooknr))
758 goto letscontinue;
759 /* this can't be 0, so the loop test is correct */
712 cl_s[i].cs.n = pos + 1; 760 cl_s[i].cs.n = pos + 1;
713 pos = 0; 761 pos = 0;
714 cl_s[i].cs.e = ((void *)e + e->next_offset); 762 cl_s[i].cs.e = ((void *)e + e->next_offset);
@@ -728,42 +776,35 @@ letscontinue:
728} 776}
729 777
730/* do the parsing of the table/chains/entries/matches/watchers/targets, heh */ 778/* do the parsing of the table/chains/entries/matches/watchers/targets, heh */
731static int translate_table(struct ebt_replace *repl, 779static int translate_table(char *name, struct ebt_table_info *newinfo)
732 struct ebt_table_info *newinfo)
733{ 780{
734 unsigned int i, j, k, udc_cnt; 781 unsigned int i, j, k, udc_cnt;
735 int ret; 782 int ret;
736 struct ebt_cl_stack *cl_s = NULL; /* used in the checking for chain loops */ 783 struct ebt_cl_stack *cl_s = NULL; /* used in the checking for chain loops */
737 784
738 i = 0; 785 i = 0;
739 while (i < NF_BR_NUMHOOKS && !(repl->valid_hooks & (1 << i))) 786 while (i < NF_BR_NUMHOOKS && !newinfo->hook_entry[i])
740 i++; 787 i++;
741 if (i == NF_BR_NUMHOOKS) { 788 if (i == NF_BR_NUMHOOKS) {
742 BUGPRINT("No valid hooks specified\n"); 789 BUGPRINT("No valid hooks specified\n");
743 return -EINVAL; 790 return -EINVAL;
744 } 791 }
745 if (repl->hook_entry[i] != (struct ebt_entries *)repl->entries) { 792 if (newinfo->hook_entry[i] != (struct ebt_entries *)newinfo->entries) {
746 BUGPRINT("Chains don't start at beginning\n"); 793 BUGPRINT("Chains don't start at beginning\n");
747 return -EINVAL; 794 return -EINVAL;
748 } 795 }
749 /* make sure chains are ordered after each other in same order 796 /* make sure chains are ordered after each other in same order
750 as their corresponding hooks */ 797 as their corresponding hooks */
751 for (j = i + 1; j < NF_BR_NUMHOOKS; j++) { 798 for (j = i + 1; j < NF_BR_NUMHOOKS; j++) {
752 if (!(repl->valid_hooks & (1 << j))) 799 if (!newinfo->hook_entry[j])
753 continue; 800 continue;
754 if ( repl->hook_entry[j] <= repl->hook_entry[i] ) { 801 if (newinfo->hook_entry[j] <= newinfo->hook_entry[i]) {
755 BUGPRINT("Hook order must be followed\n"); 802 BUGPRINT("Hook order must be followed\n");
756 return -EINVAL; 803 return -EINVAL;
757 } 804 }
758 i = j; 805 i = j;
759 } 806 }
760 807
761 for (i = 0; i < NF_BR_NUMHOOKS; i++)
762 newinfo->hook_entry[i] = NULL;
763
764 newinfo->entries_size = repl->entries_size;
765 newinfo->nentries = repl->nentries;
766
767 /* do some early checkings and initialize some things */ 808 /* do some early checkings and initialize some things */
768 i = 0; /* holds the expected nr. of entries for the chain */ 809 i = 0; /* holds the expected nr. of entries for the chain */
769 j = 0; /* holds the up to now counted entries for the chain */ 810 j = 0; /* holds the up to now counted entries for the chain */
@@ -771,9 +812,8 @@ static int translate_table(struct ebt_replace *repl,
771 newinfo->nentries afterwards */ 812 newinfo->nentries afterwards */
772 udc_cnt = 0; /* will hold the nr. of user defined chains (udc) */ 813 udc_cnt = 0; /* will hold the nr. of user defined chains (udc) */
773 ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size, 814 ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
774 ebt_check_entry_size_and_hooks, newinfo, repl->entries, 815 ebt_check_entry_size_and_hooks, newinfo,
775 repl->entries + repl->entries_size, repl->hook_entry, &i, &j, &k, 816 &i, &j, &k, &udc_cnt);
776 &udc_cnt, repl->valid_hooks);
777 817
778 if (ret != 0) 818 if (ret != 0)
779 return ret; 819 return ret;
@@ -788,15 +828,6 @@ static int translate_table(struct ebt_replace *repl,
788 return -EINVAL; 828 return -EINVAL;
789 } 829 }
790 830
791 /* check if all valid hooks have a chain */
792 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
793 if (newinfo->hook_entry[i] == NULL &&
794 (repl->valid_hooks & (1 << i))) {
795 BUGPRINT("Valid hook without chain\n");
796 return -EINVAL;
797 }
798 }
799
800 /* get the location of the udc, put them in an array 831 /* get the location of the udc, put them in an array
801 while we're at it, allocate the chainstack */ 832 while we're at it, allocate the chainstack */
802 if (udc_cnt) { 833 if (udc_cnt) {
@@ -824,8 +855,7 @@ static int translate_table(struct ebt_replace *repl,
824 return -ENOMEM; 855 return -ENOMEM;
825 i = 0; /* the i'th udc */ 856 i = 0; /* the i'th udc */
826 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size, 857 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
827 ebt_get_udc_positions, newinfo, repl->hook_entry, &i, 858 ebt_get_udc_positions, newinfo, &i, cl_s);
828 repl->valid_hooks, cl_s);
829 /* sanity check */ 859 /* sanity check */
830 if (i != udc_cnt) { 860 if (i != udc_cnt) {
831 BUGPRINT("i != udc_cnt\n"); 861 BUGPRINT("i != udc_cnt\n");
@@ -836,7 +866,7 @@ static int translate_table(struct ebt_replace *repl,
836 866
837 /* Check for loops */ 867 /* Check for loops */
838 for (i = 0; i < NF_BR_NUMHOOKS; i++) 868 for (i = 0; i < NF_BR_NUMHOOKS; i++)
839 if (repl->valid_hooks & (1 << i)) 869 if (newinfo->hook_entry[i])
840 if (check_chainloops(newinfo->hook_entry[i], 870 if (check_chainloops(newinfo->hook_entry[i],
841 cl_s, udc_cnt, i, newinfo->entries)) { 871 cl_s, udc_cnt, i, newinfo->entries)) {
842 vfree(cl_s); 872 vfree(cl_s);
@@ -856,8 +886,7 @@ static int translate_table(struct ebt_replace *repl,
856 /* used to know what we need to clean up if something goes wrong */ 886 /* used to know what we need to clean up if something goes wrong */
857 i = 0; 887 i = 0;
858 ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size, 888 ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
859 ebt_check_entry, newinfo, repl->name, &i, repl->valid_hooks, 889 ebt_check_entry, newinfo, name, &i, cl_s, udc_cnt);
860 cl_s, udc_cnt);
861 if (ret != 0) { 890 if (ret != 0) {
862 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size, 891 EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size,
863 ebt_cleanup_entry, &i); 892 ebt_cleanup_entry, &i);
@@ -954,7 +983,11 @@ static int do_replace(void __user *user, unsigned int len)
954 983
955 /* this can get initialized by translate_table() */ 984 /* this can get initialized by translate_table() */
956 newinfo->chainstack = NULL; 985 newinfo->chainstack = NULL;
957 ret = translate_table(&tmp, newinfo); 986 ret = ebt_verify_pointers(&tmp, newinfo);
987 if (ret != 0)
988 goto free_counterstmp;
989
990 ret = translate_table(tmp.name, newinfo);
958 991
959 if (ret != 0) 992 if (ret != 0)
960 goto free_counterstmp; 993 goto free_counterstmp;
@@ -1125,35 +1158,47 @@ int ebt_register_table(struct ebt_table *table)
1125{ 1158{
1126 struct ebt_table_info *newinfo; 1159 struct ebt_table_info *newinfo;
1127 struct ebt_table *t; 1160 struct ebt_table *t;
1161 struct ebt_replace_kernel *repl;
1128 int ret, i, countersize; 1162 int ret, i, countersize;
1163 void *p;
1129 1164
1130 if (!table || !table->table ||!table->table->entries || 1165 if (!table || !(repl = table->table) || !repl->entries ||
1131 table->table->entries_size == 0 || 1166 repl->entries_size == 0 ||
1132 table->table->counters || table->private) { 1167 repl->counters || table->private) {
1133 BUGPRINT("Bad table data for ebt_register_table!!!\n"); 1168 BUGPRINT("Bad table data for ebt_register_table!!!\n");
1134 return -EINVAL; 1169 return -EINVAL;
1135 } 1170 }
1136 1171
1137 countersize = COUNTER_OFFSET(table->table->nentries) * 1172 countersize = COUNTER_OFFSET(repl->nentries) *
1138 (highest_possible_processor_id()+1); 1173 (highest_possible_processor_id()+1);
1139 newinfo = vmalloc(sizeof(*newinfo) + countersize); 1174 newinfo = vmalloc(sizeof(*newinfo) + countersize);
1140 ret = -ENOMEM; 1175 ret = -ENOMEM;
1141 if (!newinfo) 1176 if (!newinfo)
1142 return -ENOMEM; 1177 return -ENOMEM;
1143 1178
1144 newinfo->entries = vmalloc(table->table->entries_size); 1179 p = vmalloc(repl->entries_size);
1145 if (!(newinfo->entries)) 1180 if (!p)
1146 goto free_newinfo; 1181 goto free_newinfo;
1147 1182
1148 memcpy(newinfo->entries, table->table->entries, 1183 memcpy(p, repl->entries, repl->entries_size);
1149 table->table->entries_size); 1184 newinfo->entries = p;
1185
1186 newinfo->entries_size = repl->entries_size;
1187 newinfo->nentries = repl->nentries;
1150 1188
1151 if (countersize) 1189 if (countersize)
1152 memset(newinfo->counters, 0, countersize); 1190 memset(newinfo->counters, 0, countersize);
1153 1191
1154 /* fill in newinfo and parse the entries */ 1192 /* fill in newinfo and parse the entries */
1155 newinfo->chainstack = NULL; 1193 newinfo->chainstack = NULL;
1156 ret = translate_table(table->table, newinfo); 1194 for (i = 0; i < NF_BR_NUMHOOKS; i++) {
1195 if ((repl->valid_hooks & (1 << i)) == 0)
1196 newinfo->hook_entry[i] = NULL;
1197 else
1198 newinfo->hook_entry[i] = p +
1199 ((char *)repl->hook_entry[i] - repl->entries);
1200 }
1201 ret = translate_table(repl->name, newinfo);
1157 if (ret != 0) { 1202 if (ret != 0) {
1158 BUGPRINT("Translate_table failed\n"); 1203 BUGPRINT("Translate_table failed\n");
1159 goto free_chainstack; 1204 goto free_chainstack;
@@ -1277,33 +1322,33 @@ free_tmp:
1277} 1322}
1278 1323
1279static inline int ebt_make_matchname(struct ebt_entry_match *m, 1324static inline int ebt_make_matchname(struct ebt_entry_match *m,
1280 char *base, char *ubase) 1325 char *base, char __user *ubase)
1281{ 1326{
1282 char *hlp = ubase - base + (char *)m; 1327 char __user *hlp = ubase + ((char *)m - base);
1283 if (copy_to_user(hlp, m->u.match->name, EBT_FUNCTION_MAXNAMELEN)) 1328 if (copy_to_user(hlp, m->u.match->name, EBT_FUNCTION_MAXNAMELEN))
1284 return -EFAULT; 1329 return -EFAULT;
1285 return 0; 1330 return 0;
1286} 1331}
1287 1332
1288static inline int ebt_make_watchername(struct ebt_entry_watcher *w, 1333static inline int ebt_make_watchername(struct ebt_entry_watcher *w,
1289 char *base, char *ubase) 1334 char *base, char __user *ubase)
1290{ 1335{
1291 char *hlp = ubase - base + (char *)w; 1336 char __user *hlp = ubase + ((char *)w - base);
1292 if (copy_to_user(hlp , w->u.watcher->name, EBT_FUNCTION_MAXNAMELEN)) 1337 if (copy_to_user(hlp , w->u.watcher->name, EBT_FUNCTION_MAXNAMELEN))
1293 return -EFAULT; 1338 return -EFAULT;
1294 return 0; 1339 return 0;
1295} 1340}
1296 1341
1297static inline int ebt_make_names(struct ebt_entry *e, char *base, char *ubase) 1342static inline int ebt_make_names(struct ebt_entry *e, char *base, char __user *ubase)
1298{ 1343{
1299 int ret; 1344 int ret;
1300 char *hlp; 1345 char __user *hlp;
1301 struct ebt_entry_target *t; 1346 struct ebt_entry_target *t;
1302 1347
1303 if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0) 1348 if (e->bitmask == 0)
1304 return 0; 1349 return 0;
1305 1350
1306 hlp = ubase - base + (char *)e + e->target_offset; 1351 hlp = ubase + (((char *)e + e->target_offset) - base);
1307 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset); 1352 t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
1308 1353
1309 ret = EBT_MATCH_ITERATE(e, ebt_make_matchname, base, ubase); 1354 ret = EBT_MATCH_ITERATE(e, ebt_make_matchname, base, ubase);
diff --git a/net/core/Makefile b/net/core/Makefile
index 119568077d..73272d506e 100644
--- a/net/core/Makefile
+++ b/net/core/Makefile
@@ -12,7 +12,6 @@ obj-y += dev.o ethtool.o dev_mcast.o dst.o netevent.o \
12 12
13obj-$(CONFIG_XFRM) += flow.o 13obj-$(CONFIG_XFRM) += flow.o
14obj-$(CONFIG_SYSFS) += net-sysfs.o 14obj-$(CONFIG_SYSFS) += net-sysfs.o
15obj-$(CONFIG_NET_DIVERT) += dv.o
16obj-$(CONFIG_NET_PKTGEN) += pktgen.o 15obj-$(CONFIG_NET_PKTGEN) += pktgen.o
17obj-$(CONFIG_WIRELESS_EXT) += wireless.o 16obj-$(CONFIG_WIRELESS_EXT) += wireless.o
18obj-$(CONFIG_NETPOLL) += netpoll.o 17obj-$(CONFIG_NETPOLL) += netpoll.o
diff --git a/net/core/datagram.c b/net/core/datagram.c
index f558c61aec..797fdd4352 100644
--- a/net/core/datagram.c
+++ b/net/core/datagram.c
@@ -321,7 +321,7 @@ fault:
321 321
322static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset, 322static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
323 u8 __user *to, int len, 323 u8 __user *to, int len,
324 unsigned int *csump) 324 __wsum *csump)
325{ 325{
326 int start = skb_headlen(skb); 326 int start = skb_headlen(skb);
327 int pos = 0; 327 int pos = 0;
@@ -350,7 +350,7 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
350 350
351 end = start + skb_shinfo(skb)->frags[i].size; 351 end = start + skb_shinfo(skb)->frags[i].size;
352 if ((copy = end - offset) > 0) { 352 if ((copy = end - offset) > 0) {
353 unsigned int csum2; 353 __wsum csum2;
354 int err = 0; 354 int err = 0;
355 u8 *vaddr; 355 u8 *vaddr;
356 skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 356 skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
@@ -386,7 +386,7 @@ static int skb_copy_and_csum_datagram(const struct sk_buff *skb, int offset,
386 386
387 end = start + list->len; 387 end = start + list->len;
388 if ((copy = end - offset) > 0) { 388 if ((copy = end - offset) > 0) {
389 unsigned int csum2 = 0; 389 __wsum csum2 = 0;
390 if (copy > len) 390 if (copy > len)
391 copy = len; 391 copy = len;
392 if (skb_copy_and_csum_datagram(list, 392 if (skb_copy_and_csum_datagram(list,
@@ -411,11 +411,11 @@ fault:
411 return -EFAULT; 411 return -EFAULT;
412} 412}
413 413
414unsigned int __skb_checksum_complete(struct sk_buff *skb) 414__sum16 __skb_checksum_complete(struct sk_buff *skb)
415{ 415{
416 unsigned int sum; 416 __sum16 sum;
417 417
418 sum = (u16)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum)); 418 sum = csum_fold(skb_checksum(skb, 0, skb->len, skb->csum));
419 if (likely(!sum)) { 419 if (likely(!sum)) {
420 if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE)) 420 if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE))
421 netdev_rx_csum_fault(skb->dev); 421 netdev_rx_csum_fault(skb->dev);
@@ -441,7 +441,7 @@ EXPORT_SYMBOL(__skb_checksum_complete);
441int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb, 441int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb,
442 int hlen, struct iovec *iov) 442 int hlen, struct iovec *iov)
443{ 443{
444 unsigned int csum; 444 __wsum csum;
445 int chunk = skb->len - hlen; 445 int chunk = skb->len - hlen;
446 446
447 /* Skip filled elements. 447 /* Skip filled elements.
@@ -460,7 +460,7 @@ int skb_copy_and_csum_datagram_iovec(struct sk_buff *skb,
460 if (skb_copy_and_csum_datagram(skb, hlen, iov->iov_base, 460 if (skb_copy_and_csum_datagram(skb, hlen, iov->iov_base,
461 chunk, &csum)) 461 chunk, &csum))
462 goto fault; 462 goto fault;
463 if ((unsigned short)csum_fold(csum)) 463 if (csum_fold(csum))
464 goto csum_error; 464 goto csum_error;
465 if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE)) 465 if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE))
466 netdev_rx_csum_fault(skb->dev); 466 netdev_rx_csum_fault(skb->dev);
diff --git a/net/core/dev.c b/net/core/dev.c
index 81c426adcd..e660cb57e4 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -98,7 +98,6 @@
98#include <linux/seq_file.h> 98#include <linux/seq_file.h>
99#include <linux/stat.h> 99#include <linux/stat.h>
100#include <linux/if_bridge.h> 100#include <linux/if_bridge.h>
101#include <linux/divert.h>
102#include <net/dst.h> 101#include <net/dst.h>
103#include <net/pkt_sched.h> 102#include <net/pkt_sched.h>
104#include <net/checksum.h> 103#include <net/checksum.h>
@@ -1170,7 +1169,7 @@ EXPORT_SYMBOL(netif_device_attach);
1170 */ 1169 */
1171int skb_checksum_help(struct sk_buff *skb) 1170int skb_checksum_help(struct sk_buff *skb)
1172{ 1171{
1173 unsigned int csum; 1172 __wsum csum;
1174 int ret = 0, offset = skb->h.raw - skb->data; 1173 int ret = 0, offset = skb->h.raw - skb->data;
1175 1174
1176 if (skb->ip_summed == CHECKSUM_COMPLETE) 1175 if (skb->ip_summed == CHECKSUM_COMPLETE)
@@ -1192,9 +1191,9 @@ int skb_checksum_help(struct sk_buff *skb)
1192 1191
1193 offset = skb->tail - skb->h.raw; 1192 offset = skb->tail - skb->h.raw;
1194 BUG_ON(offset <= 0); 1193 BUG_ON(offset <= 0);
1195 BUG_ON(skb->csum + 2 > offset); 1194 BUG_ON(skb->csum_offset + 2 > offset);
1196 1195
1197 *(u16*)(skb->h.raw + skb->csum) = csum_fold(csum); 1196 *(__sum16*)(skb->h.raw + skb->csum_offset) = csum_fold(csum);
1198 1197
1199out_set_summed: 1198out_set_summed:
1200 skb->ip_summed = CHECKSUM_NONE; 1199 skb->ip_summed = CHECKSUM_NONE;
@@ -1216,7 +1215,7 @@ struct sk_buff *skb_gso_segment(struct sk_buff *skb, int features)
1216{ 1215{
1217 struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT); 1216 struct sk_buff *segs = ERR_PTR(-EPROTONOSUPPORT);
1218 struct packet_type *ptype; 1217 struct packet_type *ptype;
1219 int type = skb->protocol; 1218 __be16 type = skb->protocol;
1220 int err; 1219 int err;
1221 1220
1222 BUG_ON(skb_shinfo(skb)->frag_list); 1221 BUG_ON(skb_shinfo(skb)->frag_list);
@@ -1767,7 +1766,7 @@ int netif_receive_skb(struct sk_buff *skb)
1767 struct packet_type *ptype, *pt_prev; 1766 struct packet_type *ptype, *pt_prev;
1768 struct net_device *orig_dev; 1767 struct net_device *orig_dev;
1769 int ret = NET_RX_DROP; 1768 int ret = NET_RX_DROP;
1770 unsigned short type; 1769 __be16 type;
1771 1770
1772 /* if we've gotten here through NAPI, check netpoll */ 1771 /* if we've gotten here through NAPI, check netpoll */
1773 if (skb->dev->poll && netpoll_rx(skb)) 1772 if (skb->dev->poll && netpoll_rx(skb))
@@ -1827,8 +1826,6 @@ int netif_receive_skb(struct sk_buff *skb)
1827ncls: 1826ncls:
1828#endif 1827#endif
1829 1828
1830 handle_diverter(skb);
1831
1832 if (handle_bridge(&skb, &pt_prev, &ret, orig_dev)) 1829 if (handle_bridge(&skb, &pt_prev, &ret, orig_dev))
1833 goto out; 1830 goto out;
1834 1831
@@ -2898,10 +2895,6 @@ int register_netdevice(struct net_device *dev)
2898 spin_lock_init(&dev->ingress_lock); 2895 spin_lock_init(&dev->ingress_lock);
2899#endif 2896#endif
2900 2897
2901 ret = alloc_divert_blk(dev);
2902 if (ret)
2903 goto out;
2904
2905 dev->iflink = -1; 2898 dev->iflink = -1;
2906 2899
2907 /* Init, if this function is available */ 2900 /* Init, if this function is available */
@@ -2910,13 +2903,13 @@ int register_netdevice(struct net_device *dev)
2910 if (ret) { 2903 if (ret) {
2911 if (ret > 0) 2904 if (ret > 0)
2912 ret = -EIO; 2905 ret = -EIO;
2913 goto out_err; 2906 goto out;
2914 } 2907 }
2915 } 2908 }
2916 2909
2917 if (!dev_valid_name(dev->name)) { 2910 if (!dev_valid_name(dev->name)) {
2918 ret = -EINVAL; 2911 ret = -EINVAL;
2919 goto out_err; 2912 goto out;
2920 } 2913 }
2921 2914
2922 dev->ifindex = dev_new_index(); 2915 dev->ifindex = dev_new_index();
@@ -2930,7 +2923,7 @@ int register_netdevice(struct net_device *dev)
2930 = hlist_entry(p, struct net_device, name_hlist); 2923 = hlist_entry(p, struct net_device, name_hlist);
2931 if (!strncmp(d->name, dev->name, IFNAMSIZ)) { 2924 if (!strncmp(d->name, dev->name, IFNAMSIZ)) {
2932 ret = -EEXIST; 2925 ret = -EEXIST;
2933 goto out_err; 2926 goto out;
2934 } 2927 }
2935 } 2928 }
2936 2929
@@ -2974,7 +2967,7 @@ int register_netdevice(struct net_device *dev)
2974 2967
2975 ret = netdev_register_sysfs(dev); 2968 ret = netdev_register_sysfs(dev);
2976 if (ret) 2969 if (ret)
2977 goto out_err; 2970 goto out;
2978 dev->reg_state = NETREG_REGISTERED; 2971 dev->reg_state = NETREG_REGISTERED;
2979 2972
2980 /* 2973 /*
@@ -3001,9 +2994,6 @@ int register_netdevice(struct net_device *dev)
3001 2994
3002out: 2995out:
3003 return ret; 2996 return ret;
3004out_err:
3005 free_divert_blk(dev);
3006 goto out;
3007} 2997}
3008 2998
3009/** 2999/**
@@ -3035,15 +3025,6 @@ int register_netdev(struct net_device *dev)
3035 goto out; 3025 goto out;
3036 } 3026 }
3037 3027
3038 /*
3039 * Back compatibility hook. Kill this one in 2.5
3040 */
3041 if (dev->name[0] == 0 || dev->name[0] == ' ') {
3042 err = dev_alloc_name(dev, "eth%d");
3043 if (err < 0)
3044 goto out;
3045 }
3046
3047 err = register_netdevice(dev); 3028 err = register_netdevice(dev);
3048out: 3029out:
3049 rtnl_unlock(); 3030 rtnl_unlock();
@@ -3329,8 +3310,6 @@ int unregister_netdevice(struct net_device *dev)
3329 /* Notifier chain MUST detach us from master device. */ 3310 /* Notifier chain MUST detach us from master device. */
3330 BUG_TRAP(!dev->master); 3311 BUG_TRAP(!dev->master);
3331 3312
3332 free_divert_blk(dev);
3333
3334 /* Finish processing unregister after unlock */ 3313 /* Finish processing unregister after unlock */
3335 net_set_todo(dev); 3314 net_set_todo(dev);
3336 3315
@@ -3361,7 +3340,6 @@ void unregister_netdev(struct net_device *dev)
3361 3340
3362EXPORT_SYMBOL(unregister_netdev); 3341EXPORT_SYMBOL(unregister_netdev);
3363 3342
3364#ifdef CONFIG_HOTPLUG_CPU
3365static int dev_cpu_callback(struct notifier_block *nfb, 3343static int dev_cpu_callback(struct notifier_block *nfb,
3366 unsigned long action, 3344 unsigned long action,
3367 void *ocpu) 3345 void *ocpu)
@@ -3405,7 +3383,6 @@ static int dev_cpu_callback(struct notifier_block *nfb,
3405 3383
3406 return NOTIFY_OK; 3384 return NOTIFY_OK;
3407} 3385}
3408#endif /* CONFIG_HOTPLUG_CPU */
3409 3386
3410#ifdef CONFIG_NET_DMA 3387#ifdef CONFIG_NET_DMA
3411/** 3388/**
diff --git a/net/core/dst.c b/net/core/dst.c
index 1a5e49da0e..836ec66069 100644
--- a/net/core/dst.c
+++ b/net/core/dst.c
@@ -125,7 +125,7 @@ void * dst_alloc(struct dst_ops * ops)
125 if (ops->gc()) 125 if (ops->gc())
126 return NULL; 126 return NULL;
127 } 127 }
128 dst = kmem_cache_alloc(ops->kmem_cachep, SLAB_ATOMIC); 128 dst = kmem_cache_alloc(ops->kmem_cachep, GFP_ATOMIC);
129 if (!dst) 129 if (!dst)
130 return NULL; 130 return NULL;
131 memset(dst, 0, ops->entry_size); 131 memset(dst, 0, ops->entry_size);
diff --git a/net/core/dv.c b/net/core/dv.c
deleted file mode 100644
index 29ee77f159..0000000000
--- a/net/core/dv.c
+++ /dev/null
@@ -1,546 +0,0 @@
1/*
2 * INET An implementation of the TCP/IP protocol suite for the LINUX
3 * operating system. INET is implemented using the BSD Socket
4 * interface as the means of communication with the user level.
5 *
6 * Generic frame diversion
7 *
8 * Authors:
9 * Benoit LOCHER: initial integration within the kernel with support for ethernet
10 * Dave Miller: improvement on the code (correctness, performance and source files)
11 *
12 */
13#include <linux/module.h>
14#include <linux/types.h>
15#include <linux/kernel.h>
16#include <linux/sched.h>
17#include <linux/string.h>
18#include <linux/mm.h>
19#include <linux/socket.h>
20#include <linux/in.h>
21#include <linux/inet.h>
22#include <linux/ip.h>
23#include <linux/udp.h>
24#include <linux/netdevice.h>
25#include <linux/etherdevice.h>
26#include <linux/skbuff.h>
27#include <linux/capability.h>
28#include <linux/errno.h>
29#include <linux/init.h>
30#include <net/dst.h>
31#include <net/arp.h>
32#include <net/sock.h>
33#include <net/ipv6.h>
34#include <net/ip.h>
35#include <asm/uaccess.h>
36#include <asm/system.h>
37#include <asm/checksum.h>
38#include <linux/divert.h>
39#include <linux/sockios.h>
40
41const char sysctl_divert_version[32]="0.46"; /* Current version */
42
43static int __init dv_init(void)
44{
45 return 0;
46}
47module_init(dv_init);
48
49/*
50 * Allocate a divert_blk for a device. This must be an ethernet nic.
51 */
52int alloc_divert_blk(struct net_device *dev)
53{
54 int alloc_size = (sizeof(struct divert_blk) + 3) & ~3;
55
56 dev->divert = NULL;
57 if (dev->type == ARPHRD_ETHER) {
58 dev->divert = kzalloc(alloc_size, GFP_KERNEL);
59 if (dev->divert == NULL) {
60 printk(KERN_INFO "divert: unable to allocate divert_blk for %s\n",
61 dev->name);
62 return -ENOMEM;
63 }
64 dev_hold(dev);
65 }
66
67 return 0;
68}
69
70/*
71 * Free a divert_blk allocated by the above function, if it was
72 * allocated on that device.
73 */
74void free_divert_blk(struct net_device *dev)
75{
76 if (dev->divert) {
77 kfree(dev->divert);
78 dev->divert=NULL;
79 dev_put(dev);
80 }
81}
82
83/*
84 * Adds a tcp/udp (source or dest) port to an array
85 */
86static int add_port(u16 ports[], u16 port)
87{
88 int i;
89
90 if (port == 0)
91 return -EINVAL;
92
93 /* Storing directly in network format for performance,
94 * thanks Dave :)
95 */
96 port = htons(port);
97
98 for (i = 0; i < MAX_DIVERT_PORTS; i++) {
99 if (ports[i] == port)
100 return -EALREADY;
101 }
102
103 for (i = 0; i < MAX_DIVERT_PORTS; i++) {
104 if (ports[i] == 0) {
105 ports[i] = port;
106 return 0;
107 }
108 }
109
110 return -ENOBUFS;
111}
112
113/*
114 * Removes a port from an array tcp/udp (source or dest)
115 */
116static int remove_port(u16 ports[], u16 port)
117{
118 int i;
119
120 if (port == 0)
121 return -EINVAL;
122
123 /* Storing directly in network format for performance,
124 * thanks Dave !
125 */
126 port = htons(port);
127
128 for (i = 0; i < MAX_DIVERT_PORTS; i++) {
129 if (ports[i] == port) {
130 ports[i] = 0;
131 return 0;
132 }
133 }
134
135 return -EINVAL;
136}
137
138/* Some basic sanity checks on the arguments passed to divert_ioctl() */
139static int check_args(struct divert_cf *div_cf, struct net_device **dev)
140{
141 char devname[32];
142 int ret;
143
144 if (dev == NULL)
145 return -EFAULT;
146
147 /* GETVERSION: all other args are unused */
148 if (div_cf->cmd == DIVCMD_GETVERSION)
149 return 0;
150
151 /* Network device index should reasonably be between 0 and 1000 :) */
152 if (div_cf->dev_index < 0 || div_cf->dev_index > 1000)
153 return -EINVAL;
154
155 /* Let's try to find the ifname */
156 sprintf(devname, "eth%d", div_cf->dev_index);
157 *dev = dev_get_by_name(devname);
158
159 /* dev should NOT be null */
160 if (*dev == NULL)
161 return -EINVAL;
162
163 ret = 0;
164
165 /* user issuing the ioctl must be a super one :) */
166 if (!capable(CAP_SYS_ADMIN)) {
167 ret = -EPERM;
168 goto out;
169 }
170
171 /* Device must have a divert_blk member NOT null */
172 if ((*dev)->divert == NULL)
173 ret = -EINVAL;
174out:
175 dev_put(*dev);
176 return ret;
177}
178
179/*
180 * control function of the diverter
181 */
182#if 0
183#define DVDBG(a) \
184 printk(KERN_DEBUG "divert_ioctl() line %d %s\n", __LINE__, (a))
185#else
186#define DVDBG(a)
187#endif
188
189int divert_ioctl(unsigned int cmd, struct divert_cf __user *arg)
190{
191 struct divert_cf div_cf;
192 struct divert_blk *div_blk;
193 struct net_device *dev;
194 int ret;
195
196 switch (cmd) {
197 case SIOCGIFDIVERT:
198 DVDBG("SIOCGIFDIVERT, copy_from_user");
199 if (copy_from_user(&div_cf, arg, sizeof(struct divert_cf)))
200 return -EFAULT;
201 DVDBG("before check_args");
202 ret = check_args(&div_cf, &dev);
203 if (ret)
204 return ret;
205 DVDBG("after checkargs");
206 div_blk = dev->divert;
207
208 DVDBG("befre switch()");
209 switch (div_cf.cmd) {
210 case DIVCMD_GETSTATUS:
211 /* Now, just give the user the raw divert block
212 * for him to play with :)
213 */
214 if (copy_to_user(div_cf.arg1.ptr, dev->divert,
215 sizeof(struct divert_blk)))
216 return -EFAULT;
217 break;
218
219 case DIVCMD_GETVERSION:
220 DVDBG("GETVERSION: checking ptr");
221 if (div_cf.arg1.ptr == NULL)
222 return -EINVAL;
223 DVDBG("GETVERSION: copying data to userland");
224 if (copy_to_user(div_cf.arg1.ptr,
225 sysctl_divert_version, 32))
226 return -EFAULT;
227 DVDBG("GETVERSION: data copied");
228 break;
229
230 default:
231 return -EINVAL;
232 }
233
234 break;
235
236 case SIOCSIFDIVERT:
237 if (copy_from_user(&div_cf, arg, sizeof(struct divert_cf)))
238 return -EFAULT;
239
240 ret = check_args(&div_cf, &dev);
241 if (ret)
242 return ret;
243
244 div_blk = dev->divert;
245
246 switch(div_cf.cmd) {
247 case DIVCMD_RESET:
248 div_blk->divert = 0;
249 div_blk->protos = DIVERT_PROTO_NONE;
250 memset(div_blk->tcp_dst, 0,
251 MAX_DIVERT_PORTS * sizeof(u16));
252 memset(div_blk->tcp_src, 0,
253 MAX_DIVERT_PORTS * sizeof(u16));
254 memset(div_blk->udp_dst, 0,
255 MAX_DIVERT_PORTS * sizeof(u16));
256 memset(div_blk->udp_src, 0,
257 MAX_DIVERT_PORTS * sizeof(u16));
258 return 0;
259
260 case DIVCMD_DIVERT:
261 switch(div_cf.arg1.int32) {
262 case DIVARG1_ENABLE:
263 if (div_blk->divert)
264 return -EALREADY;
265 div_blk->divert = 1;
266 break;
267
268 case DIVARG1_DISABLE:
269 if (!div_blk->divert)
270 return -EALREADY;
271 div_blk->divert = 0;
272 break;
273
274 default:
275 return -EINVAL;
276 }
277
278 break;
279
280 case DIVCMD_IP:
281 switch(div_cf.arg1.int32) {
282 case DIVARG1_ENABLE:
283 if (div_blk->protos & DIVERT_PROTO_IP)
284 return -EALREADY;
285 div_blk->protos |= DIVERT_PROTO_IP;
286 break;
287
288 case DIVARG1_DISABLE:
289 if (!(div_blk->protos & DIVERT_PROTO_IP))
290 return -EALREADY;
291 div_blk->protos &= ~DIVERT_PROTO_IP;
292 break;
293
294 default:
295 return -EINVAL;
296 }
297
298 break;
299
300 case DIVCMD_TCP:
301 switch(div_cf.arg1.int32) {
302 case DIVARG1_ENABLE:
303 if (div_blk->protos & DIVERT_PROTO_TCP)
304 return -EALREADY;
305 div_blk->protos |= DIVERT_PROTO_TCP;
306 break;
307
308 case DIVARG1_DISABLE:
309 if (!(div_blk->protos & DIVERT_PROTO_TCP))
310 return -EALREADY;
311 div_blk->protos &= ~DIVERT_PROTO_TCP;
312 break;
313
314 default:
315 return -EINVAL;
316 }
317
318 break;
319
320 case DIVCMD_TCPDST:
321 switch(div_cf.arg1.int32) {
322 case DIVARG1_ADD:
323 return add_port(div_blk->tcp_dst,
324 div_cf.arg2.uint16);
325
326 case DIVARG1_REMOVE:
327 return remove_port(div_blk->tcp_dst,
328 div_cf.arg2.uint16);
329
330 default:
331 return -EINVAL;
332 }
333
334 break;
335
336 case DIVCMD_TCPSRC:
337 switch(div_cf.arg1.int32) {
338 case DIVARG1_ADD:
339 return add_port(div_blk->tcp_src,
340 div_cf.arg2.uint16);
341
342 case DIVARG1_REMOVE:
343 return remove_port(div_blk->tcp_src,
344 div_cf.arg2.uint16);
345
346 default:
347 return -EINVAL;
348 }
349
350 break;
351
352 case DIVCMD_UDP:
353 switch(div_cf.arg1.int32) {
354 case DIVARG1_ENABLE:
355 if (div_blk->protos & DIVERT_PROTO_UDP)
356 return -EALREADY;
357 div_blk->protos |= DIVERT_PROTO_UDP;
358 break;
359
360 case DIVARG1_DISABLE:
361 if (!(div_blk->protos & DIVERT_PROTO_UDP))
362 return -EALREADY;
363 div_blk->protos &= ~DIVERT_PROTO_UDP;
364 break;
365
366 default:
367 return -EINVAL;
368 }
369
370 break;
371
372 case DIVCMD_UDPDST:
373 switch(div_cf.arg1.int32) {
374 case DIVARG1_ADD:
375 return add_port(div_blk->udp_dst,
376 div_cf.arg2.uint16);
377
378 case DIVARG1_REMOVE:
379 return remove_port(div_blk->udp_dst,
380 div_cf.arg2.uint16);
381
382 default:
383 return -EINVAL;
384 }
385
386 break;
387
388 case DIVCMD_UDPSRC:
389 switch(div_cf.arg1.int32) {
390 case DIVARG1_ADD:
391 return add_port(div_blk->udp_src,
392 div_cf.arg2.uint16);
393
394 case DIVARG1_REMOVE:
395 return remove_port(div_blk->udp_src,
396 div_cf.arg2.uint16);
397
398 default:
399 return -EINVAL;
400 }
401
402 break;
403
404 case DIVCMD_ICMP:
405 switch(div_cf.arg1.int32) {
406 case DIVARG1_ENABLE:
407 if (div_blk->protos & DIVERT_PROTO_ICMP)
408 return -EALREADY;
409 div_blk->protos |= DIVERT_PROTO_ICMP;
410 break;
411
412 case DIVARG1_DISABLE:
413 if (!(div_blk->protos & DIVERT_PROTO_ICMP))
414 return -EALREADY;
415 div_blk->protos &= ~DIVERT_PROTO_ICMP;
416 break;
417
418 default:
419 return -EINVAL;
420 }
421
422 break;
423
424 default:
425 return -EINVAL;
426 }
427
428 break;
429
430 default:
431 return -EINVAL;
432 }
433
434 return 0;
435}
436
437
438/*
439 * Check if packet should have its dest mac address set to the box itself
440 * for diversion
441 */
442
443#define ETH_DIVERT_FRAME(skb) \
444 memcpy(eth_hdr(skb), skb->dev->dev_addr, ETH_ALEN); \
445 skb->pkt_type=PACKET_HOST
446
447void divert_frame(struct sk_buff *skb)
448{
449 struct ethhdr *eth = eth_hdr(skb);
450 struct iphdr *iph;
451 struct tcphdr *tcph;
452 struct udphdr *udph;
453 struct divert_blk *divert = skb->dev->divert;
454 int i, src, dst;
455 unsigned char *skb_data_end = skb->data + skb->len;
456
457 /* Packet is already aimed at us, return */
458 if (!compare_ether_addr(eth->h_dest, skb->dev->dev_addr))
459 return;
460
461 /* proto is not IP, do nothing */
462 if (eth->h_proto != htons(ETH_P_IP))
463 return;
464
465 /* Divert all IP frames ? */
466 if (divert->protos & DIVERT_PROTO_IP) {
467 ETH_DIVERT_FRAME(skb);
468 return;
469 }
470
471 /* Check for possible (maliciously) malformed IP frame (thanks Dave) */
472 iph = (struct iphdr *) skb->data;
473 if (((iph->ihl<<2)+(unsigned char*)(iph)) >= skb_data_end) {
474 printk(KERN_INFO "divert: malformed IP packet !\n");
475 return;
476 }
477
478 switch (iph->protocol) {
479 /* Divert all ICMP frames ? */
480 case IPPROTO_ICMP:
481 if (divert->protos & DIVERT_PROTO_ICMP) {
482 ETH_DIVERT_FRAME(skb);
483 return;
484 }
485 break;
486
487 /* Divert all TCP frames ? */
488 case IPPROTO_TCP:
489 if (divert->protos & DIVERT_PROTO_TCP) {
490 ETH_DIVERT_FRAME(skb);
491 return;
492 }
493
494 /* Check for possible (maliciously) malformed IP
495 * frame (thanx Dave)
496 */
497 tcph = (struct tcphdr *)
498 (((unsigned char *)iph) + (iph->ihl<<2));
499 if (((unsigned char *)(tcph+1)) >= skb_data_end) {
500 printk(KERN_INFO "divert: malformed TCP packet !\n");
501 return;
502 }
503
504 /* Divert some tcp dst/src ports only ?*/
505 for (i = 0; i < MAX_DIVERT_PORTS; i++) {
506 dst = divert->tcp_dst[i];
507 src = divert->tcp_src[i];
508 if ((dst && dst == tcph->dest) ||
509 (src && src == tcph->source)) {
510 ETH_DIVERT_FRAME(skb);
511 return;
512 }
513 }
514 break;
515
516 /* Divert all UDP frames ? */
517 case IPPROTO_UDP:
518 if (divert->protos & DIVERT_PROTO_UDP) {
519 ETH_DIVERT_FRAME(skb);
520 return;
521 }
522
523 /* Check for possible (maliciously) malformed IP
524 * packet (thanks Dave)
525 */
526 udph = (struct udphdr *)
527 (((unsigned char *)iph) + (iph->ihl<<2));
528 if (((unsigned char *)(udph+1)) >= skb_data_end) {
529 printk(KERN_INFO
530 "divert: malformed UDP packet !\n");
531 return;
532 }
533
534 /* Divert some udp dst/src ports only ? */
535 for (i = 0; i < MAX_DIVERT_PORTS; i++) {
536 dst = divert->udp_dst[i];
537 src = divert->udp_src[i];
538 if ((dst && dst == udph->dest) ||
539 (src && src == udph->source)) {
540 ETH_DIVERT_FRAME(skb);
541 return;
542 }
543 }
544 break;
545 }
546}
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index 6b0e63cacd..1df6cd4568 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -107,6 +107,22 @@ out:
107 107
108EXPORT_SYMBOL_GPL(fib_rules_unregister); 108EXPORT_SYMBOL_GPL(fib_rules_unregister);
109 109
110static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops,
111 struct flowi *fl, int flags)
112{
113 int ret = 0;
114
115 if (rule->ifindex && (rule->ifindex != fl->iif))
116 goto out;
117
118 if ((rule->mark ^ fl->mark) & rule->mark_mask)
119 goto out;
120
121 ret = ops->match(rule, fl, flags);
122out:
123 return (rule->flags & FIB_RULE_INVERT) ? !ret : ret;
124}
125
110int fib_rules_lookup(struct fib_rules_ops *ops, struct flowi *fl, 126int fib_rules_lookup(struct fib_rules_ops *ops, struct flowi *fl,
111 int flags, struct fib_lookup_arg *arg) 127 int flags, struct fib_lookup_arg *arg)
112{ 128{
@@ -116,10 +132,7 @@ int fib_rules_lookup(struct fib_rules_ops *ops, struct flowi *fl,
116 rcu_read_lock(); 132 rcu_read_lock();
117 133
118 list_for_each_entry_rcu(rule, ops->rules_list, list) { 134 list_for_each_entry_rcu(rule, ops->rules_list, list) {
119 if (rule->ifindex && (rule->ifindex != fl->iif)) 135 if (!fib_rule_match(rule, ops, fl, flags))
120 continue;
121
122 if (!ops->match(rule, fl, flags))
123 continue; 136 continue;
124 137
125 err = ops->action(rule, fl, flags, arg); 138 err = ops->action(rule, fl, flags, arg);
@@ -179,6 +192,18 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
179 rule->ifindex = dev->ifindex; 192 rule->ifindex = dev->ifindex;
180 } 193 }
181 194
195 if (tb[FRA_FWMARK]) {
196 rule->mark = nla_get_u32(tb[FRA_FWMARK]);
197 if (rule->mark)
198 /* compatibility: if the mark value is non-zero all bits
199 * are compared unless a mask is explicitly specified.
200 */
201 rule->mark_mask = 0xFFFFFFFF;
202 }
203
204 if (tb[FRA_FWMASK])
205 rule->mark_mask = nla_get_u32(tb[FRA_FWMASK]);
206
182 rule->action = frh->action; 207 rule->action = frh->action;
183 rule->flags = frh->flags; 208 rule->flags = frh->flags;
184 rule->table = frh_get_table(frh, tb); 209 rule->table = frh_get_table(frh, tb);
@@ -250,6 +275,14 @@ int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
250 nla_strcmp(tb[FRA_IFNAME], rule->ifname)) 275 nla_strcmp(tb[FRA_IFNAME], rule->ifname))
251 continue; 276 continue;
252 277
278 if (tb[FRA_FWMARK] &&
279 (rule->mark != nla_get_u32(tb[FRA_FWMARK])))
280 continue;
281
282 if (tb[FRA_FWMASK] &&
283 (rule->mark_mask != nla_get_u32(tb[FRA_FWMASK])))
284 continue;
285
253 if (!ops->compare(rule, frh, tb)) 286 if (!ops->compare(rule, frh, tb))
254 continue; 287 continue;
255 288
@@ -273,6 +306,22 @@ errout:
273 return err; 306 return err;
274} 307}
275 308
309static inline size_t fib_rule_nlmsg_size(struct fib_rules_ops *ops,
310 struct fib_rule *rule)
311{
312 size_t payload = NLMSG_ALIGN(sizeof(struct fib_rule_hdr))
313 + nla_total_size(IFNAMSIZ) /* FRA_IFNAME */
314 + nla_total_size(4) /* FRA_PRIORITY */
315 + nla_total_size(4) /* FRA_TABLE */
316 + nla_total_size(4) /* FRA_FWMARK */
317 + nla_total_size(4); /* FRA_FWMASK */
318
319 if (ops->nlmsg_payload)
320 payload += ops->nlmsg_payload(rule);
321
322 return payload;
323}
324
276static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule, 325static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule,
277 u32 pid, u32 seq, int type, int flags, 326 u32 pid, u32 seq, int type, int flags,
278 struct fib_rules_ops *ops) 327 struct fib_rules_ops *ops)
@@ -298,6 +347,12 @@ static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule,
298 if (rule->pref) 347 if (rule->pref)
299 NLA_PUT_U32(skb, FRA_PRIORITY, rule->pref); 348 NLA_PUT_U32(skb, FRA_PRIORITY, rule->pref);
300 349
350 if (rule->mark)
351 NLA_PUT_U32(skb, FRA_FWMARK, rule->mark);
352
353 if (rule->mark_mask || rule->mark)
354 NLA_PUT_U32(skb, FRA_FWMASK, rule->mark_mask);
355
301 if (ops->fill(rule, skb, nlh, frh) < 0) 356 if (ops->fill(rule, skb, nlh, frh) < 0)
302 goto nla_put_failure; 357 goto nla_put_failure;
303 358
@@ -345,15 +400,13 @@ static void notify_rule_change(int event, struct fib_rule *rule,
345 struct sk_buff *skb; 400 struct sk_buff *skb;
346 int err = -ENOBUFS; 401 int err = -ENOBUFS;
347 402
348 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 403 skb = nlmsg_new(fib_rule_nlmsg_size(ops, rule), GFP_KERNEL);
349 if (skb == NULL) 404 if (skb == NULL)
350 goto errout; 405 goto errout;
351 406
352 err = fib_nl_fill_rule(skb, rule, pid, nlh->nlmsg_seq, event, 0, ops); 407 err = fib_nl_fill_rule(skb, rule, pid, nlh->nlmsg_seq, event, 0, ops);
353 if (err < 0) { 408 /* failure implies BUG in fib_rule_nlmsg_size() */
354 kfree_skb(skb); 409 BUG_ON(err < 0);
355 goto errout;
356 }
357 410
358 err = rtnl_notify(skb, pid, ops->nlgroup, nlh, GFP_KERNEL); 411 err = rtnl_notify(skb, pid, ops->nlgroup, nlh, GFP_KERNEL);
359errout: 412errout:
diff --git a/net/core/filter.c b/net/core/filter.c
index 6732782a5a..0df843b667 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -178,7 +178,7 @@ unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int
178load_w: 178load_w:
179 ptr = load_pointer(skb, k, 4, &tmp); 179 ptr = load_pointer(skb, k, 4, &tmp);
180 if (ptr != NULL) { 180 if (ptr != NULL) {
181 A = ntohl(get_unaligned((u32 *)ptr)); 181 A = ntohl(get_unaligned((__be32 *)ptr));
182 continue; 182 continue;
183 } 183 }
184 break; 184 break;
@@ -187,7 +187,7 @@ load_w:
187load_h: 187load_h:
188 ptr = load_pointer(skb, k, 2, &tmp); 188 ptr = load_pointer(skb, k, 2, &tmp);
189 if (ptr != NULL) { 189 if (ptr != NULL) {
190 A = ntohs(get_unaligned((u16 *)ptr)); 190 A = ntohs(get_unaligned((__be16 *)ptr));
191 continue; 191 continue;
192 } 192 }
193 break; 193 break;
@@ -261,7 +261,7 @@ load_b:
261 */ 261 */
262 switch (k-SKF_AD_OFF) { 262 switch (k-SKF_AD_OFF) {
263 case SKF_AD_PROTOCOL: 263 case SKF_AD_PROTOCOL:
264 A = htons(skb->protocol); 264 A = ntohs(skb->protocol);
265 continue; 265 continue;
266 case SKF_AD_PKTTYPE: 266 case SKF_AD_PKTTYPE:
267 A = skb->pkt_type; 267 A = skb->pkt_type;
diff --git a/net/core/flow.c b/net/core/flow.c
index b16d31ae5e..d137f971f9 100644
--- a/net/core/flow.c
+++ b/net/core/flow.c
@@ -44,7 +44,7 @@ static DEFINE_PER_CPU(struct flow_cache_entry **, flow_tables) = { NULL };
44 44
45#define flow_table(cpu) (per_cpu(flow_tables, cpu)) 45#define flow_table(cpu) (per_cpu(flow_tables, cpu))
46 46
47static kmem_cache_t *flow_cachep __read_mostly; 47static struct kmem_cache *flow_cachep __read_mostly;
48 48
49static int flow_lwm, flow_hwm; 49static int flow_lwm, flow_hwm;
50 50
@@ -211,7 +211,7 @@ void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir,
211 if (flow_count(cpu) > flow_hwm) 211 if (flow_count(cpu) > flow_hwm)
212 flow_cache_shrink(cpu); 212 flow_cache_shrink(cpu);
213 213
214 fle = kmem_cache_alloc(flow_cachep, SLAB_ATOMIC); 214 fle = kmem_cache_alloc(flow_cachep, GFP_ATOMIC);
215 if (fle) { 215 if (fle) {
216 fle->next = *head; 216 fle->next = *head;
217 *head = fle; 217 *head = fle;
@@ -340,7 +340,6 @@ static void __devinit flow_cache_cpu_prepare(int cpu)
340 tasklet_init(tasklet, flow_cache_flush_tasklet, 0); 340 tasklet_init(tasklet, flow_cache_flush_tasklet, 0);
341} 341}
342 342
343#ifdef CONFIG_HOTPLUG_CPU
344static int flow_cache_cpu(struct notifier_block *nfb, 343static int flow_cache_cpu(struct notifier_block *nfb,
345 unsigned long action, 344 unsigned long action,
346 void *hcpu) 345 void *hcpu)
@@ -349,7 +348,6 @@ static int flow_cache_cpu(struct notifier_block *nfb,
349 __flow_cache_shrink((unsigned long)hcpu, 0); 348 __flow_cache_shrink((unsigned long)hcpu, 0);
350 return NOTIFY_OK; 349 return NOTIFY_OK;
351} 350}
352#endif /* CONFIG_HOTPLUG_CPU */
353 351
354static int __init flow_cache_init(void) 352static int __init flow_cache_init(void)
355{ 353{
diff --git a/net/core/iovec.c b/net/core/iovec.c
index 65e4b56fbc..04b249c40b 100644
--- a/net/core/iovec.c
+++ b/net/core/iovec.c
@@ -158,9 +158,9 @@ int memcpy_fromiovecend(unsigned char *kdata, struct iovec *iov, int offset,
158 * call to this function will be unaligned also. 158 * call to this function will be unaligned also.
159 */ 159 */
160int csum_partial_copy_fromiovecend(unsigned char *kdata, struct iovec *iov, 160int csum_partial_copy_fromiovecend(unsigned char *kdata, struct iovec *iov,
161 int offset, unsigned int len, int *csump) 161 int offset, unsigned int len, __wsum *csump)
162{ 162{
163 int csum = *csump; 163 __wsum csum = *csump;
164 int partial_cnt = 0, err = 0; 164 int partial_cnt = 0, err = 0;
165 165
166 /* Skip over the finished iovecs */ 166 /* Skip over the finished iovecs */
diff --git a/net/core/kmap_skb.h b/net/core/kmap_skb.h
new file mode 100644
index 0000000000..283c2b993f
--- /dev/null
+++ b/net/core/kmap_skb.h
@@ -0,0 +1,19 @@
1#include <linux/highmem.h>
2
3static inline void *kmap_skb_frag(const skb_frag_t *frag)
4{
5#ifdef CONFIG_HIGHMEM
6 BUG_ON(in_irq());
7
8 local_bh_disable();
9#endif
10 return kmap_atomic(frag->page, KM_SKB_DATA_SOFTIRQ);
11}
12
13static inline void kunmap_skb_frag(void *vaddr)
14{
15 kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ);
16#ifdef CONFIG_HIGHMEM
17 local_bh_enable();
18#endif
19}
diff --git a/net/core/link_watch.c b/net/core/link_watch.c
index 4b36114744..549a2ce951 100644
--- a/net/core/link_watch.c
+++ b/net/core/link_watch.c
@@ -34,8 +34,8 @@ enum lw_bits {
34static unsigned long linkwatch_flags; 34static unsigned long linkwatch_flags;
35static unsigned long linkwatch_nextevent; 35static unsigned long linkwatch_nextevent;
36 36
37static void linkwatch_event(void *dummy); 37static void linkwatch_event(struct work_struct *dummy);
38static DECLARE_WORK(linkwatch_work, linkwatch_event, NULL); 38static DECLARE_DELAYED_WORK(linkwatch_work, linkwatch_event);
39 39
40static LIST_HEAD(lweventlist); 40static LIST_HEAD(lweventlist);
41static DEFINE_SPINLOCK(lweventlist_lock); 41static DEFINE_SPINLOCK(lweventlist_lock);
@@ -127,7 +127,7 @@ void linkwatch_run_queue(void)
127} 127}
128 128
129 129
130static void linkwatch_event(void *dummy) 130static void linkwatch_event(struct work_struct *dummy)
131{ 131{
132 /* Limit the number of linkwatch events to one 132 /* Limit the number of linkwatch events to one
133 * per second so that a runaway driver does not 133 * per second so that a runaway driver does not
@@ -171,10 +171,9 @@ void linkwatch_fire_event(struct net_device *dev)
171 unsigned long delay = linkwatch_nextevent - jiffies; 171 unsigned long delay = linkwatch_nextevent - jiffies;
172 172
173 /* If we wrap around we'll delay it by at most HZ. */ 173 /* If we wrap around we'll delay it by at most HZ. */
174 if (!delay || delay > HZ) 174 if (delay > HZ)
175 schedule_work(&linkwatch_work); 175 delay = 0;
176 else 176 schedule_delayed_work(&linkwatch_work, delay);
177 schedule_delayed_work(&linkwatch_work, delay);
178 } 177 }
179 } 178 }
180} 179}
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index b4b478353b..e7300b6b40 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -251,7 +251,7 @@ static struct neighbour *neigh_alloc(struct neigh_table *tbl)
251 goto out_entries; 251 goto out_entries;
252 } 252 }
253 253
254 n = kmem_cache_alloc(tbl->kmem_cachep, SLAB_ATOMIC); 254 n = kmem_cache_alloc(tbl->kmem_cachep, GFP_ATOMIC);
255 if (!n) 255 if (!n)
256 goto out_entries; 256 goto out_entries;
257 257
@@ -577,9 +577,10 @@ void neigh_destroy(struct neighbour *neigh)
577 while ((hh = neigh->hh) != NULL) { 577 while ((hh = neigh->hh) != NULL) {
578 neigh->hh = hh->hh_next; 578 neigh->hh = hh->hh_next;
579 hh->hh_next = NULL; 579 hh->hh_next = NULL;
580 write_lock_bh(&hh->hh_lock); 580
581 write_seqlock_bh(&hh->hh_lock);
581 hh->hh_output = neigh_blackhole; 582 hh->hh_output = neigh_blackhole;
582 write_unlock_bh(&hh->hh_lock); 583 write_sequnlock_bh(&hh->hh_lock);
583 if (atomic_dec_and_test(&hh->hh_refcnt)) 584 if (atomic_dec_and_test(&hh->hh_refcnt))
584 kfree(hh); 585 kfree(hh);
585 } 586 }
@@ -897,9 +898,9 @@ static void neigh_update_hhs(struct neighbour *neigh)
897 898
898 if (update) { 899 if (update) {
899 for (hh = neigh->hh; hh; hh = hh->hh_next) { 900 for (hh = neigh->hh; hh; hh = hh->hh_next) {
900 write_lock_bh(&hh->hh_lock); 901 write_seqlock_bh(&hh->hh_lock);
901 update(hh, neigh->dev, neigh->ha); 902 update(hh, neigh->dev, neigh->ha);
902 write_unlock_bh(&hh->hh_lock); 903 write_sequnlock_bh(&hh->hh_lock);
903 } 904 }
904 } 905 }
905} 906}
@@ -1089,7 +1090,7 @@ static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst,
1089 break; 1090 break;
1090 1091
1091 if (!hh && (hh = kzalloc(sizeof(*hh), GFP_ATOMIC)) != NULL) { 1092 if (!hh && (hh = kzalloc(sizeof(*hh), GFP_ATOMIC)) != NULL) {
1092 rwlock_init(&hh->hh_lock); 1093 seqlock_init(&hh->hh_lock);
1093 hh->hh_type = protocol; 1094 hh->hh_type = protocol;
1094 atomic_set(&hh->hh_refcnt, 0); 1095 atomic_set(&hh->hh_refcnt, 0);
1095 hh->hh_next = NULL; 1096 hh->hh_next = NULL;
@@ -1266,10 +1267,9 @@ void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
1266struct neigh_parms *neigh_parms_alloc(struct net_device *dev, 1267struct neigh_parms *neigh_parms_alloc(struct net_device *dev,
1267 struct neigh_table *tbl) 1268 struct neigh_table *tbl)
1268{ 1269{
1269 struct neigh_parms *p = kmalloc(sizeof(*p), GFP_KERNEL); 1270 struct neigh_parms *p = kmemdup(&tbl->parms, sizeof(*p), GFP_KERNEL);
1270 1271
1271 if (p) { 1272 if (p) {
1272 memcpy(p, &tbl->parms, sizeof(*p));
1273 p->tbl = tbl; 1273 p->tbl = tbl;
1274 atomic_set(&p->refcnt, 1); 1274 atomic_set(&p->refcnt, 1);
1275 INIT_RCU_HEAD(&p->rcu_head); 1275 INIT_RCU_HEAD(&p->rcu_head);
@@ -2410,20 +2410,27 @@ static struct file_operations neigh_stat_seq_fops = {
2410#endif /* CONFIG_PROC_FS */ 2410#endif /* CONFIG_PROC_FS */
2411 2411
2412#ifdef CONFIG_ARPD 2412#ifdef CONFIG_ARPD
2413static inline size_t neigh_nlmsg_size(void)
2414{
2415 return NLMSG_ALIGN(sizeof(struct ndmsg))
2416 + nla_total_size(MAX_ADDR_LEN) /* NDA_DST */
2417 + nla_total_size(MAX_ADDR_LEN) /* NDA_LLADDR */
2418 + nla_total_size(sizeof(struct nda_cacheinfo))
2419 + nla_total_size(4); /* NDA_PROBES */
2420}
2421
2413static void __neigh_notify(struct neighbour *n, int type, int flags) 2422static void __neigh_notify(struct neighbour *n, int type, int flags)
2414{ 2423{
2415 struct sk_buff *skb; 2424 struct sk_buff *skb;
2416 int err = -ENOBUFS; 2425 int err = -ENOBUFS;
2417 2426
2418 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC); 2427 skb = nlmsg_new(neigh_nlmsg_size(), GFP_ATOMIC);
2419 if (skb == NULL) 2428 if (skb == NULL)
2420 goto errout; 2429 goto errout;
2421 2430
2422 err = neigh_fill_info(skb, n, 0, 0, type, flags); 2431 err = neigh_fill_info(skb, n, 0, 0, type, flags);
2423 if (err < 0) { 2432 /* failure implies BUG in neigh_nlmsg_size() */
2424 kfree_skb(skb); 2433 BUG_ON(err < 0);
2425 goto errout;
2426 }
2427 2434
2428 err = rtnl_notify(skb, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); 2435 err = rtnl_notify(skb, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
2429errout: 2436errout:
@@ -2618,14 +2625,14 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
2618 int p_id, int pdev_id, char *p_name, 2625 int p_id, int pdev_id, char *p_name,
2619 proc_handler *handler, ctl_handler *strategy) 2626 proc_handler *handler, ctl_handler *strategy)
2620{ 2627{
2621 struct neigh_sysctl_table *t = kmalloc(sizeof(*t), GFP_KERNEL); 2628 struct neigh_sysctl_table *t = kmemdup(&neigh_sysctl_template,
2629 sizeof(*t), GFP_KERNEL);
2622 const char *dev_name_source = NULL; 2630 const char *dev_name_source = NULL;
2623 char *dev_name = NULL; 2631 char *dev_name = NULL;
2624 int err = 0; 2632 int err = 0;
2625 2633
2626 if (!t) 2634 if (!t)
2627 return -ENOBUFS; 2635 return -ENOBUFS;
2628 memcpy(t, &neigh_sysctl_template, sizeof(*t));
2629 t->neigh_vars[0].data = &p->mcast_probes; 2636 t->neigh_vars[0].data = &p->mcast_probes;
2630 t->neigh_vars[1].data = &p->ucast_probes; 2637 t->neigh_vars[1].data = &p->ucast_probes;
2631 t->neigh_vars[2].data = &p->app_probes; 2638 t->neigh_vars[2].data = &p->app_probes;
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 6589adb14c..823215d8e9 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -34,18 +34,12 @@
34#define MAX_UDP_CHUNK 1460 34#define MAX_UDP_CHUNK 1460
35#define MAX_SKBS 32 35#define MAX_SKBS 32
36#define MAX_QUEUE_DEPTH (MAX_SKBS / 2) 36#define MAX_QUEUE_DEPTH (MAX_SKBS / 2)
37#define MAX_RETRIES 20000
38 37
39static DEFINE_SPINLOCK(skb_list_lock); 38static struct sk_buff_head skb_pool;
40static int nr_skbs;
41static struct sk_buff *skbs;
42
43static DEFINE_SPINLOCK(queue_lock);
44static int queue_depth;
45static struct sk_buff *queue_head, *queue_tail;
46 39
47static atomic_t trapped; 40static atomic_t trapped;
48 41
42#define USEC_PER_POLL 50
49#define NETPOLL_RX_ENABLED 1 43#define NETPOLL_RX_ENABLED 1
50#define NETPOLL_RX_DROP 2 44#define NETPOLL_RX_DROP 2
51 45
@@ -56,54 +50,41 @@ static atomic_t trapped;
56static void zap_completion_queue(void); 50static void zap_completion_queue(void);
57static void arp_reply(struct sk_buff *skb); 51static void arp_reply(struct sk_buff *skb);
58 52
59static void queue_process(void *p) 53static void queue_process(struct work_struct *work)
60{ 54{
61 unsigned long flags; 55 struct netpoll_info *npinfo =
56 container_of(work, struct netpoll_info, tx_work.work);
62 struct sk_buff *skb; 57 struct sk_buff *skb;
63
64 while (queue_head) {
65 spin_lock_irqsave(&queue_lock, flags);
66
67 skb = queue_head;
68 queue_head = skb->next;
69 if (skb == queue_tail)
70 queue_head = NULL;
71
72 queue_depth--;
73
74 spin_unlock_irqrestore(&queue_lock, flags);
75
76 dev_queue_xmit(skb);
77 }
78}
79
80static DECLARE_WORK(send_queue, queue_process, NULL);
81
82void netpoll_queue(struct sk_buff *skb)
83{
84 unsigned long flags; 58 unsigned long flags;
85 59
86 if (queue_depth == MAX_QUEUE_DEPTH) { 60 while ((skb = skb_dequeue(&npinfo->txq))) {
87 __kfree_skb(skb); 61 struct net_device *dev = skb->dev;
88 return;
89 }
90 62
91 spin_lock_irqsave(&queue_lock, flags); 63 if (!netif_device_present(dev) || !netif_running(dev)) {
92 if (!queue_head) 64 __kfree_skb(skb);
93 queue_head = skb; 65 continue;
94 else 66 }
95 queue_tail->next = skb;
96 queue_tail = skb;
97 queue_depth++;
98 spin_unlock_irqrestore(&queue_lock, flags);
99 67
100 schedule_work(&send_queue); 68 local_irq_save(flags);
69 netif_tx_lock(dev);
70 if (netif_queue_stopped(dev) ||
71 dev->hard_start_xmit(skb, dev) != NETDEV_TX_OK) {
72 skb_queue_head(&npinfo->txq, skb);
73 netif_tx_unlock(dev);
74 local_irq_restore(flags);
75
76 schedule_delayed_work(&npinfo->tx_work, HZ/10);
77 return;
78 }
79 netif_tx_unlock(dev);
80 local_irq_restore(flags);
81 }
101} 82}
102 83
103static int checksum_udp(struct sk_buff *skb, struct udphdr *uh, 84static __sum16 checksum_udp(struct sk_buff *skb, struct udphdr *uh,
104 unsigned short ulen, u32 saddr, u32 daddr) 85 unsigned short ulen, __be32 saddr, __be32 daddr)
105{ 86{
106 unsigned int psum; 87 __wsum psum;
107 88
108 if (uh->check == 0 || skb->ip_summed == CHECKSUM_UNNECESSARY) 89 if (uh->check == 0 || skb->ip_summed == CHECKSUM_UNNECESSARY)
109 return 0; 90 return 0;
@@ -111,7 +92,7 @@ static int checksum_udp(struct sk_buff *skb, struct udphdr *uh,
111 psum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, 0); 92 psum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, 0);
112 93
113 if (skb->ip_summed == CHECKSUM_COMPLETE && 94 if (skb->ip_summed == CHECKSUM_COMPLETE &&
114 !(u16)csum_fold(csum_add(psum, skb->csum))) 95 !csum_fold(csum_add(psum, skb->csum)))
115 return 0; 96 return 0;
116 97
117 skb->csum = psum; 98 skb->csum = psum;
@@ -167,12 +148,11 @@ static void service_arp_queue(struct netpoll_info *npi)
167 arp_reply(skb); 148 arp_reply(skb);
168 skb = skb_dequeue(&npi->arp_tx); 149 skb = skb_dequeue(&npi->arp_tx);
169 } 150 }
170 return;
171} 151}
172 152
173void netpoll_poll(struct netpoll *np) 153void netpoll_poll(struct netpoll *np)
174{ 154{
175 if(!np->dev || !netif_running(np->dev) || !np->dev->poll_controller) 155 if (!np->dev || !netif_running(np->dev) || !np->dev->poll_controller)
176 return; 156 return;
177 157
178 /* Process pending work on NIC */ 158 /* Process pending work on NIC */
@@ -190,17 +170,15 @@ static void refill_skbs(void)
190 struct sk_buff *skb; 170 struct sk_buff *skb;
191 unsigned long flags; 171 unsigned long flags;
192 172
193 spin_lock_irqsave(&skb_list_lock, flags); 173 spin_lock_irqsave(&skb_pool.lock, flags);
194 while (nr_skbs < MAX_SKBS) { 174 while (skb_pool.qlen < MAX_SKBS) {
195 skb = alloc_skb(MAX_SKB_SIZE, GFP_ATOMIC); 175 skb = alloc_skb(MAX_SKB_SIZE, GFP_ATOMIC);
196 if (!skb) 176 if (!skb)
197 break; 177 break;
198 178
199 skb->next = skbs; 179 __skb_queue_tail(&skb_pool, skb);
200 skbs = skb;
201 nr_skbs++;
202 } 180 }
203 spin_unlock_irqrestore(&skb_list_lock, flags); 181 spin_unlock_irqrestore(&skb_pool.lock, flags);
204} 182}
205 183
206static void zap_completion_queue(void) 184static void zap_completion_queue(void)
@@ -219,7 +197,7 @@ static void zap_completion_queue(void)
219 while (clist != NULL) { 197 while (clist != NULL) {
220 struct sk_buff *skb = clist; 198 struct sk_buff *skb = clist;
221 clist = clist->next; 199 clist = clist->next;
222 if(skb->destructor) 200 if (skb->destructor)
223 dev_kfree_skb_any(skb); /* put this one back */ 201 dev_kfree_skb_any(skb); /* put this one back */
224 else 202 else
225 __kfree_skb(skb); 203 __kfree_skb(skb);
@@ -229,38 +207,25 @@ static void zap_completion_queue(void)
229 put_cpu_var(softnet_data); 207 put_cpu_var(softnet_data);
230} 208}
231 209
232static struct sk_buff * find_skb(struct netpoll *np, int len, int reserve) 210static struct sk_buff *find_skb(struct netpoll *np, int len, int reserve)
233{ 211{
234 int once = 1, count = 0; 212 int count = 0;
235 unsigned long flags; 213 struct sk_buff *skb;
236 struct sk_buff *skb = NULL;
237 214
238 zap_completion_queue(); 215 zap_completion_queue();
216 refill_skbs();
239repeat: 217repeat:
240 if (nr_skbs < MAX_SKBS)
241 refill_skbs();
242 218
243 skb = alloc_skb(len, GFP_ATOMIC); 219 skb = alloc_skb(len, GFP_ATOMIC);
220 if (!skb)
221 skb = skb_dequeue(&skb_pool);
244 222
245 if (!skb) { 223 if (!skb) {
246 spin_lock_irqsave(&skb_list_lock, flags); 224 if (++count < 10) {
247 skb = skbs; 225 netpoll_poll(np);
248 if (skb) { 226 goto repeat;
249 skbs = skb->next;
250 skb->next = NULL;
251 nr_skbs--;
252 }
253 spin_unlock_irqrestore(&skb_list_lock, flags);
254 }
255
256 if(!skb) {
257 count++;
258 if (once && (count == 1000000)) {
259 printk("out of netpoll skbs!\n");
260 once = 0;
261 } 227 }
262 netpoll_poll(np); 228 return NULL;
263 goto repeat;
264 } 229 }
265 230
266 atomic_set(&skb->users, 1); 231 atomic_set(&skb->users, 1);
@@ -270,50 +235,46 @@ repeat:
270 235
271static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) 236static void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb)
272{ 237{
273 int status; 238 int status = NETDEV_TX_BUSY;
274 struct netpoll_info *npinfo; 239 unsigned long tries;
240 struct net_device *dev = np->dev;
241 struct netpoll_info *npinfo = np->dev->npinfo;
275 242
276 if (!np || !np->dev || !netif_running(np->dev)) { 243 if (!npinfo || !netif_running(dev) || !netif_device_present(dev)) {
277 __kfree_skb(skb); 244 __kfree_skb(skb);
278 return; 245 return;
279 } 246 }
280 247
281 npinfo = np->dev->npinfo; 248 /* don't get messages out of order, and no recursion */
249 if (skb_queue_len(&npinfo->txq) == 0 &&
250 npinfo->poll_owner != smp_processor_id()) {
251 unsigned long flags;
282 252
283 /* avoid recursion */ 253 local_irq_save(flags);
284 if (npinfo->poll_owner == smp_processor_id() || 254 if (netif_tx_trylock(dev)) {
285 np->dev->xmit_lock_owner == smp_processor_id()) { 255 /* try until next clock tick */
286 if (np->drop) 256 for (tries = jiffies_to_usecs(1)/USEC_PER_POLL;
287 np->drop(skb); 257 tries > 0; --tries) {
288 else 258 if (!netif_queue_stopped(dev))
289 __kfree_skb(skb); 259 status = dev->hard_start_xmit(skb, dev);
290 return;
291 }
292
293 do {
294 npinfo->tries--;
295 netif_tx_lock(np->dev);
296 260
297 /* 261 if (status == NETDEV_TX_OK)
298 * network drivers do not expect to be called if the queue is 262 break;
299 * stopped.
300 */
301 status = NETDEV_TX_BUSY;
302 if (!netif_queue_stopped(np->dev))
303 status = np->dev->hard_start_xmit(skb, np->dev);
304 263
305 netif_tx_unlock(np->dev); 264 /* tickle device maybe there is some cleanup */
265 netpoll_poll(np);
306 266
307 /* success */ 267 udelay(USEC_PER_POLL);
308 if(!status) { 268 }
309 npinfo->tries = MAX_RETRIES; /* reset */ 269 netif_tx_unlock(dev);
310 return;
311 } 270 }
271 local_irq_restore(flags);
272 }
312 273
313 /* transmit busy */ 274 if (status != NETDEV_TX_OK) {
314 netpoll_poll(np); 275 skb_queue_tail(&npinfo->txq, skb);
315 udelay(50); 276 schedule_delayed_work(&npinfo->tx_work,0);
316 } while (npinfo->tries > 0); 277 }
317} 278}
318 279
319void netpoll_send_udp(struct netpoll *np, const char *msg, int len) 280void netpoll_send_udp(struct netpoll *np, const char *msg, int len)
@@ -345,7 +306,7 @@ void netpoll_send_udp(struct netpoll *np, const char *msg, int len)
345 udp_len, IPPROTO_UDP, 306 udp_len, IPPROTO_UDP,
346 csum_partial((unsigned char *)udph, udp_len, 0)); 307 csum_partial((unsigned char *)udph, udp_len, 0));
347 if (udph->check == 0) 308 if (udph->check == 0)
348 udph->check = -1; 309 udph->check = CSUM_MANGLED_0;
349 310
350 skb->nh.iph = iph = (struct iphdr *)skb_push(skb, sizeof(*iph)); 311 skb->nh.iph = iph = (struct iphdr *)skb_push(skb, sizeof(*iph));
351 312
@@ -379,7 +340,8 @@ static void arp_reply(struct sk_buff *skb)
379 struct arphdr *arp; 340 struct arphdr *arp;
380 unsigned char *arp_ptr; 341 unsigned char *arp_ptr;
381 int size, type = ARPOP_REPLY, ptype = ETH_P_ARP; 342 int size, type = ARPOP_REPLY, ptype = ETH_P_ARP;
382 u32 sip, tip; 343 __be32 sip, tip;
344 unsigned char *sha;
383 struct sk_buff *send_skb; 345 struct sk_buff *send_skb;
384 struct netpoll *np = NULL; 346 struct netpoll *np = NULL;
385 347
@@ -406,9 +368,14 @@ static void arp_reply(struct sk_buff *skb)
406 arp->ar_op != htons(ARPOP_REQUEST)) 368 arp->ar_op != htons(ARPOP_REQUEST))
407 return; 369 return;
408 370
409 arp_ptr = (unsigned char *)(arp+1) + skb->dev->addr_len; 371 arp_ptr = (unsigned char *)(arp+1);
372 /* save the location of the src hw addr */
373 sha = arp_ptr;
374 arp_ptr += skb->dev->addr_len;
410 memcpy(&sip, arp_ptr, 4); 375 memcpy(&sip, arp_ptr, 4);
411 arp_ptr += 4 + skb->dev->addr_len; 376 arp_ptr += 4;
377 /* if we actually cared about dst hw addr, it would get copied here */
378 arp_ptr += skb->dev->addr_len;
412 memcpy(&tip, arp_ptr, 4); 379 memcpy(&tip, arp_ptr, 4);
413 380
414 /* Should we ignore arp? */ 381 /* Should we ignore arp? */
@@ -431,8 +398,8 @@ static void arp_reply(struct sk_buff *skb)
431 398
432 if (np->dev->hard_header && 399 if (np->dev->hard_header &&
433 np->dev->hard_header(send_skb, skb->dev, ptype, 400 np->dev->hard_header(send_skb, skb->dev, ptype,
434 np->remote_mac, np->local_mac, 401 sha, np->local_mac,
435 send_skb->len) < 0) { 402 send_skb->len) < 0) {
436 kfree_skb(send_skb); 403 kfree_skb(send_skb);
437 return; 404 return;
438 } 405 }
@@ -455,7 +422,7 @@ static void arp_reply(struct sk_buff *skb)
455 arp_ptr += np->dev->addr_len; 422 arp_ptr += np->dev->addr_len;
456 memcpy(arp_ptr, &tip, 4); 423 memcpy(arp_ptr, &tip, 4);
457 arp_ptr += 4; 424 arp_ptr += 4;
458 memcpy(arp_ptr, np->remote_mac, np->dev->addr_len); 425 memcpy(arp_ptr, sha, np->dev->addr_len);
459 arp_ptr += np->dev->addr_len; 426 arp_ptr += np->dev->addr_len;
460 memcpy(arp_ptr, &sip, 4); 427 memcpy(arp_ptr, &sip, 4);
461 428
@@ -470,7 +437,6 @@ int __netpoll_rx(struct sk_buff *skb)
470 struct netpoll_info *npi = skb->dev->npinfo; 437 struct netpoll_info *npi = skb->dev->npinfo;
471 struct netpoll *np = npi->rx_np; 438 struct netpoll *np = npi->rx_np;
472 439
473
474 if (!np) 440 if (!np)
475 goto out; 441 goto out;
476 if (skb->dev->type != ARPHRD_ETHER) 442 if (skb->dev->type != ARPHRD_ETHER)
@@ -543,47 +509,47 @@ int netpoll_parse_options(struct netpoll *np, char *opt)
543{ 509{
544 char *cur=opt, *delim; 510 char *cur=opt, *delim;
545 511
546 if(*cur != '@') { 512 if (*cur != '@') {
547 if ((delim = strchr(cur, '@')) == NULL) 513 if ((delim = strchr(cur, '@')) == NULL)
548 goto parse_failed; 514 goto parse_failed;
549 *delim=0; 515 *delim = 0;
550 np->local_port=simple_strtol(cur, NULL, 10); 516 np->local_port = simple_strtol(cur, NULL, 10);
551 cur=delim; 517 cur = delim;
552 } 518 }
553 cur++; 519 cur++;
554 printk(KERN_INFO "%s: local port %d\n", np->name, np->local_port); 520 printk(KERN_INFO "%s: local port %d\n", np->name, np->local_port);
555 521
556 if(*cur != '/') { 522 if (*cur != '/') {
557 if ((delim = strchr(cur, '/')) == NULL) 523 if ((delim = strchr(cur, '/')) == NULL)
558 goto parse_failed; 524 goto parse_failed;
559 *delim=0; 525 *delim = 0;
560 np->local_ip=ntohl(in_aton(cur)); 526 np->local_ip = ntohl(in_aton(cur));
561 cur=delim; 527 cur = delim;
562 528
563 printk(KERN_INFO "%s: local IP %d.%d.%d.%d\n", 529 printk(KERN_INFO "%s: local IP %d.%d.%d.%d\n",
564 np->name, HIPQUAD(np->local_ip)); 530 np->name, HIPQUAD(np->local_ip));
565 } 531 }
566 cur++; 532 cur++;
567 533
568 if ( *cur != ',') { 534 if (*cur != ',') {
569 /* parse out dev name */ 535 /* parse out dev name */
570 if ((delim = strchr(cur, ',')) == NULL) 536 if ((delim = strchr(cur, ',')) == NULL)
571 goto parse_failed; 537 goto parse_failed;
572 *delim=0; 538 *delim = 0;
573 strlcpy(np->dev_name, cur, sizeof(np->dev_name)); 539 strlcpy(np->dev_name, cur, sizeof(np->dev_name));
574 cur=delim; 540 cur = delim;
575 } 541 }
576 cur++; 542 cur++;
577 543
578 printk(KERN_INFO "%s: interface %s\n", np->name, np->dev_name); 544 printk(KERN_INFO "%s: interface %s\n", np->name, np->dev_name);
579 545
580 if ( *cur != '@' ) { 546 if (*cur != '@') {
581 /* dst port */ 547 /* dst port */
582 if ((delim = strchr(cur, '@')) == NULL) 548 if ((delim = strchr(cur, '@')) == NULL)
583 goto parse_failed; 549 goto parse_failed;
584 *delim=0; 550 *delim = 0;
585 np->remote_port=simple_strtol(cur, NULL, 10); 551 np->remote_port = simple_strtol(cur, NULL, 10);
586 cur=delim; 552 cur = delim;
587 } 553 }
588 cur++; 554 cur++;
589 printk(KERN_INFO "%s: remote port %d\n", np->name, np->remote_port); 555 printk(KERN_INFO "%s: remote port %d\n", np->name, np->remote_port);
@@ -591,42 +557,41 @@ int netpoll_parse_options(struct netpoll *np, char *opt)
591 /* dst ip */ 557 /* dst ip */
592 if ((delim = strchr(cur, '/')) == NULL) 558 if ((delim = strchr(cur, '/')) == NULL)
593 goto parse_failed; 559 goto parse_failed;
594 *delim=0; 560 *delim = 0;
595 np->remote_ip=ntohl(in_aton(cur)); 561 np->remote_ip = ntohl(in_aton(cur));
596 cur=delim+1; 562 cur = delim + 1;
597 563
598 printk(KERN_INFO "%s: remote IP %d.%d.%d.%d\n", 564 printk(KERN_INFO "%s: remote IP %d.%d.%d.%d\n",
599 np->name, HIPQUAD(np->remote_ip)); 565 np->name, HIPQUAD(np->remote_ip));
600 566
601 if( *cur != 0 ) 567 if (*cur != 0) {
602 {
603 /* MAC address */ 568 /* MAC address */
604 if ((delim = strchr(cur, ':')) == NULL) 569 if ((delim = strchr(cur, ':')) == NULL)
605 goto parse_failed; 570 goto parse_failed;
606 *delim=0; 571 *delim = 0;
607 np->remote_mac[0]=simple_strtol(cur, NULL, 16); 572 np->remote_mac[0] = simple_strtol(cur, NULL, 16);
608 cur=delim+1; 573 cur = delim + 1;
609 if ((delim = strchr(cur, ':')) == NULL) 574 if ((delim = strchr(cur, ':')) == NULL)
610 goto parse_failed; 575 goto parse_failed;
611 *delim=0; 576 *delim = 0;
612 np->remote_mac[1]=simple_strtol(cur, NULL, 16); 577 np->remote_mac[1] = simple_strtol(cur, NULL, 16);
613 cur=delim+1; 578 cur = delim + 1;
614 if ((delim = strchr(cur, ':')) == NULL) 579 if ((delim = strchr(cur, ':')) == NULL)
615 goto parse_failed; 580 goto parse_failed;
616 *delim=0; 581 *delim = 0;
617 np->remote_mac[2]=simple_strtol(cur, NULL, 16); 582 np->remote_mac[2] = simple_strtol(cur, NULL, 16);
618 cur=delim+1; 583 cur = delim + 1;
619 if ((delim = strchr(cur, ':')) == NULL) 584 if ((delim = strchr(cur, ':')) == NULL)
620 goto parse_failed; 585 goto parse_failed;
621 *delim=0; 586 *delim = 0;
622 np->remote_mac[3]=simple_strtol(cur, NULL, 16); 587 np->remote_mac[3] = simple_strtol(cur, NULL, 16);
623 cur=delim+1; 588 cur = delim + 1;
624 if ((delim = strchr(cur, ':')) == NULL) 589 if ((delim = strchr(cur, ':')) == NULL)
625 goto parse_failed; 590 goto parse_failed;
626 *delim=0; 591 *delim = 0;
627 np->remote_mac[4]=simple_strtol(cur, NULL, 16); 592 np->remote_mac[4] = simple_strtol(cur, NULL, 16);
628 cur=delim+1; 593 cur = delim + 1;
629 np->remote_mac[5]=simple_strtol(cur, NULL, 16); 594 np->remote_mac[5] = simple_strtol(cur, NULL, 16);
630 } 595 }
631 596
632 printk(KERN_INFO "%s: remote ethernet address " 597 printk(KERN_INFO "%s: remote ethernet address "
@@ -653,34 +618,44 @@ int netpoll_setup(struct netpoll *np)
653 struct in_device *in_dev; 618 struct in_device *in_dev;
654 struct netpoll_info *npinfo; 619 struct netpoll_info *npinfo;
655 unsigned long flags; 620 unsigned long flags;
621 int err;
656 622
657 if (np->dev_name) 623 if (np->dev_name)
658 ndev = dev_get_by_name(np->dev_name); 624 ndev = dev_get_by_name(np->dev_name);
659 if (!ndev) { 625 if (!ndev) {
660 printk(KERN_ERR "%s: %s doesn't exist, aborting.\n", 626 printk(KERN_ERR "%s: %s doesn't exist, aborting.\n",
661 np->name, np->dev_name); 627 np->name, np->dev_name);
662 return -1; 628 return -ENODEV;
663 } 629 }
664 630
665 np->dev = ndev; 631 np->dev = ndev;
666 if (!ndev->npinfo) { 632 if (!ndev->npinfo) {
667 npinfo = kmalloc(sizeof(*npinfo), GFP_KERNEL); 633 npinfo = kmalloc(sizeof(*npinfo), GFP_KERNEL);
668 if (!npinfo) 634 if (!npinfo) {
635 err = -ENOMEM;
669 goto release; 636 goto release;
637 }
670 638
671 npinfo->rx_flags = 0; 639 npinfo->rx_flags = 0;
672 npinfo->rx_np = NULL; 640 npinfo->rx_np = NULL;
673 spin_lock_init(&npinfo->poll_lock); 641 spin_lock_init(&npinfo->poll_lock);
674 npinfo->poll_owner = -1; 642 npinfo->poll_owner = -1;
675 npinfo->tries = MAX_RETRIES; 643
676 spin_lock_init(&npinfo->rx_lock); 644 spin_lock_init(&npinfo->rx_lock);
677 skb_queue_head_init(&npinfo->arp_tx); 645 skb_queue_head_init(&npinfo->arp_tx);
678 } else 646 skb_queue_head_init(&npinfo->txq);
647 INIT_DELAYED_WORK(&npinfo->tx_work, queue_process);
648
649 atomic_set(&npinfo->refcnt, 1);
650 } else {
679 npinfo = ndev->npinfo; 651 npinfo = ndev->npinfo;
652 atomic_inc(&npinfo->refcnt);
653 }
680 654
681 if (!ndev->poll_controller) { 655 if (!ndev->poll_controller) {
682 printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n", 656 printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n",
683 np->name, np->dev_name); 657 np->name, np->dev_name);
658 err = -ENOTSUPP;
684 goto release; 659 goto release;
685 } 660 }
686 661
@@ -691,13 +666,14 @@ int netpoll_setup(struct netpoll *np)
691 np->name, np->dev_name); 666 np->name, np->dev_name);
692 667
693 rtnl_lock(); 668 rtnl_lock();
694 if (dev_change_flags(ndev, ndev->flags | IFF_UP) < 0) { 669 err = dev_open(ndev);
670 rtnl_unlock();
671
672 if (err) {
695 printk(KERN_ERR "%s: failed to open %s\n", 673 printk(KERN_ERR "%s: failed to open %s\n",
696 np->name, np->dev_name); 674 np->name, ndev->name);
697 rtnl_unlock();
698 goto release; 675 goto release;
699 } 676 }
700 rtnl_unlock();
701 677
702 atleast = jiffies + HZ/10; 678 atleast = jiffies + HZ/10;
703 atmost = jiffies + 4*HZ; 679 atmost = jiffies + 4*HZ;
@@ -735,6 +711,7 @@ int netpoll_setup(struct netpoll *np)
735 rcu_read_unlock(); 711 rcu_read_unlock();
736 printk(KERN_ERR "%s: no IP address for %s, aborting\n", 712 printk(KERN_ERR "%s: no IP address for %s, aborting\n",
737 np->name, np->dev_name); 713 np->name, np->dev_name);
714 err = -EDESTADDRREQ;
738 goto release; 715 goto release;
739 } 716 }
740 717
@@ -767,9 +744,16 @@ int netpoll_setup(struct netpoll *np)
767 kfree(npinfo); 744 kfree(npinfo);
768 np->dev = NULL; 745 np->dev = NULL;
769 dev_put(ndev); 746 dev_put(ndev);
770 return -1; 747 return err;
771} 748}
772 749
750static int __init netpoll_init(void)
751{
752 skb_queue_head_init(&skb_pool);
753 return 0;
754}
755core_initcall(netpoll_init);
756
773void netpoll_cleanup(struct netpoll *np) 757void netpoll_cleanup(struct netpoll *np)
774{ 758{
775 struct netpoll_info *npinfo; 759 struct netpoll_info *npinfo;
@@ -777,12 +761,25 @@ void netpoll_cleanup(struct netpoll *np)
777 761
778 if (np->dev) { 762 if (np->dev) {
779 npinfo = np->dev->npinfo; 763 npinfo = np->dev->npinfo;
780 if (npinfo && npinfo->rx_np == np) { 764 if (npinfo) {
781 spin_lock_irqsave(&npinfo->rx_lock, flags); 765 if (npinfo->rx_np == np) {
782 npinfo->rx_np = NULL; 766 spin_lock_irqsave(&npinfo->rx_lock, flags);
783 npinfo->rx_flags &= ~NETPOLL_RX_ENABLED; 767 npinfo->rx_np = NULL;
784 spin_unlock_irqrestore(&npinfo->rx_lock, flags); 768 npinfo->rx_flags &= ~NETPOLL_RX_ENABLED;
769 spin_unlock_irqrestore(&npinfo->rx_lock, flags);
770 }
771
772 np->dev->npinfo = NULL;
773 if (atomic_dec_and_test(&npinfo->refcnt)) {
774 skb_queue_purge(&npinfo->arp_tx);
775 skb_queue_purge(&npinfo->txq);
776 cancel_rearming_delayed_work(&npinfo->tx_work);
777 flush_scheduled_work();
778
779 kfree(npinfo);
780 }
785 } 781 }
782
786 dev_put(np->dev); 783 dev_put(np->dev);
787 } 784 }
788 785
@@ -809,4 +806,3 @@ EXPORT_SYMBOL(netpoll_setup);
809EXPORT_SYMBOL(netpoll_cleanup); 806EXPORT_SYMBOL(netpoll_cleanup);
810EXPORT_SYMBOL(netpoll_send_udp); 807EXPORT_SYMBOL(netpoll_send_udp);
811EXPORT_SYMBOL(netpoll_poll); 808EXPORT_SYMBOL(netpoll_poll);
812EXPORT_SYMBOL(netpoll_queue);
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index 733d86d0a4..04d4b93c68 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -148,6 +148,7 @@
148#include <linux/seq_file.h> 148#include <linux/seq_file.h>
149#include <linux/wait.h> 149#include <linux/wait.h>
150#include <linux/etherdevice.h> 150#include <linux/etherdevice.h>
151#include <linux/kthread.h>
151#include <net/checksum.h> 152#include <net/checksum.h>
152#include <net/ipv6.h> 153#include <net/ipv6.h>
153#include <net/addrconf.h> 154#include <net/addrconf.h>
@@ -207,7 +208,7 @@ static struct proc_dir_entry *pg_proc_dir = NULL;
207#define SVLAN_TAG_SIZE(x) ((x)->svlan_id == 0xffff ? 0 : 4) 208#define SVLAN_TAG_SIZE(x) ((x)->svlan_id == 0xffff ? 0 : 4)
208 209
209struct flow_state { 210struct flow_state {
210 __u32 cur_daddr; 211 __be32 cur_daddr;
211 int count; 212 int count;
212}; 213};
213 214
@@ -282,10 +283,10 @@ struct pktgen_dev {
282 /* If we're doing ranges, random or incremental, then this 283 /* If we're doing ranges, random or incremental, then this
283 * defines the min/max for those ranges. 284 * defines the min/max for those ranges.
284 */ 285 */
285 __u32 saddr_min; /* inclusive, source IP address */ 286 __be32 saddr_min; /* inclusive, source IP address */
286 __u32 saddr_max; /* exclusive, source IP address */ 287 __be32 saddr_max; /* exclusive, source IP address */
287 __u32 daddr_min; /* inclusive, dest IP address */ 288 __be32 daddr_min; /* inclusive, dest IP address */
288 __u32 daddr_max; /* exclusive, dest IP address */ 289 __be32 daddr_max; /* exclusive, dest IP address */
289 290
290 __u16 udp_src_min; /* inclusive, source UDP port */ 291 __u16 udp_src_min; /* inclusive, source UDP port */
291 __u16 udp_src_max; /* exclusive, source UDP port */ 292 __u16 udp_src_max; /* exclusive, source UDP port */
@@ -317,8 +318,8 @@ struct pktgen_dev {
317 318
318 __u32 cur_dst_mac_offset; 319 __u32 cur_dst_mac_offset;
319 __u32 cur_src_mac_offset; 320 __u32 cur_src_mac_offset;
320 __u32 cur_saddr; 321 __be32 cur_saddr;
321 __u32 cur_daddr; 322 __be32 cur_daddr;
322 __u16 cur_udp_dst; 323 __u16 cur_udp_dst;
323 __u16 cur_udp_src; 324 __u16 cur_udp_src;
324 __u32 cur_pkt_size; 325 __u32 cur_pkt_size;
@@ -350,18 +351,17 @@ struct pktgen_dev {
350}; 351};
351 352
352struct pktgen_hdr { 353struct pktgen_hdr {
353 __u32 pgh_magic; 354 __be32 pgh_magic;
354 __u32 seq_num; 355 __be32 seq_num;
355 __u32 tv_sec; 356 __be32 tv_sec;
356 __u32 tv_usec; 357 __be32 tv_usec;
357}; 358};
358 359
359struct pktgen_thread { 360struct pktgen_thread {
360 spinlock_t if_lock; 361 spinlock_t if_lock;
361 struct list_head if_list; /* All device here */ 362 struct list_head if_list; /* All device here */
362 struct list_head th_list; 363 struct list_head th_list;
363 int removed; 364 struct task_struct *tsk;
364 char name[32];
365 char result[512]; 365 char result[512];
366 u32 max_before_softirq; /* We'll call do_softirq to prevent starvation. */ 366 u32 max_before_softirq; /* We'll call do_softirq to prevent starvation. */
367 367
@@ -1689,7 +1689,7 @@ static int pktgen_thread_show(struct seq_file *seq, void *v)
1689 BUG_ON(!t); 1689 BUG_ON(!t);
1690 1690
1691 seq_printf(seq, "Name: %s max_before_softirq: %d\n", 1691 seq_printf(seq, "Name: %s max_before_softirq: %d\n",
1692 t->name, t->max_before_softirq); 1692 t->tsk->comm, t->max_before_softirq);
1693 1693
1694 seq_printf(seq, "Running: "); 1694 seq_printf(seq, "Running: ");
1695 1695
@@ -2160,7 +2160,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
2160 for(i = 0; i < pkt_dev->nr_labels; i++) 2160 for(i = 0; i < pkt_dev->nr_labels; i++)
2161 if (pkt_dev->labels[i] & MPLS_STACK_BOTTOM) 2161 if (pkt_dev->labels[i] & MPLS_STACK_BOTTOM)
2162 pkt_dev->labels[i] = MPLS_STACK_BOTTOM | 2162 pkt_dev->labels[i] = MPLS_STACK_BOTTOM |
2163 (pktgen_random() & 2163 ((__force __be32)pktgen_random() &
2164 htonl(0x000fffff)); 2164 htonl(0x000fffff));
2165 } 2165 }
2166 2166
@@ -2220,29 +2220,25 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
2220 if (pkt_dev->cflows && pkt_dev->flows[flow].count != 0) { 2220 if (pkt_dev->cflows && pkt_dev->flows[flow].count != 0) {
2221 pkt_dev->cur_daddr = pkt_dev->flows[flow].cur_daddr; 2221 pkt_dev->cur_daddr = pkt_dev->flows[flow].cur_daddr;
2222 } else { 2222 } else {
2223 2223 imn = ntohl(pkt_dev->daddr_min);
2224 if ((imn = ntohl(pkt_dev->daddr_min)) < (imx = 2224 imx = ntohl(pkt_dev->daddr_max);
2225 ntohl(pkt_dev-> 2225 if (imn < imx) {
2226 daddr_max)))
2227 {
2228 __u32 t; 2226 __u32 t;
2227 __be32 s;
2229 if (pkt_dev->flags & F_IPDST_RND) { 2228 if (pkt_dev->flags & F_IPDST_RND) {
2230 2229
2231 t = ((pktgen_random() % (imx - imn)) + 2230 t = pktgen_random() % (imx - imn) + imn;
2232 imn); 2231 s = htonl(t);
2233 t = htonl(t);
2234 2232
2235 while (LOOPBACK(t) || MULTICAST(t) 2233 while (LOOPBACK(s) || MULTICAST(s)
2236 || BADCLASS(t) || ZERONET(t) 2234 || BADCLASS(s) || ZERONET(s)
2237 || LOCAL_MCAST(t)) { 2235 || LOCAL_MCAST(s)) {
2238 t = ((pktgen_random() % 2236 t = (pktgen_random() %
2239 (imx - imn)) + imn); 2237 (imx - imn)) + imn;
2240 t = htonl(t); 2238 s = htonl(t);
2241 } 2239 }
2242 pkt_dev->cur_daddr = t; 2240 pkt_dev->cur_daddr = s;
2243 } 2241 } else {
2244
2245 else {
2246 t = ntohl(pkt_dev->cur_daddr); 2242 t = ntohl(pkt_dev->cur_daddr);
2247 t++; 2243 t++;
2248 if (t > imx) { 2244 if (t > imx) {
@@ -2270,7 +2266,7 @@ static void mod_cur_headers(struct pktgen_dev *pkt_dev)
2270 2266
2271 for (i = 0; i < 4; i++) { 2267 for (i = 0; i < 4; i++) {
2272 pkt_dev->cur_in6_daddr.s6_addr32[i] = 2268 pkt_dev->cur_in6_daddr.s6_addr32[i] =
2273 ((pktgen_random() | 2269 (((__force __be32)pktgen_random() |
2274 pkt_dev->min_in6_daddr.s6_addr32[i]) & 2270 pkt_dev->min_in6_daddr.s6_addr32[i]) &
2275 pkt_dev->max_in6_daddr.s6_addr32[i]); 2271 pkt_dev->max_in6_daddr.s6_addr32[i]);
2276 } 2272 }
@@ -2377,7 +2373,7 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
2377 udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr)); 2373 udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr));
2378 2374
2379 memcpy(eth, pkt_dev->hh, 12); 2375 memcpy(eth, pkt_dev->hh, 12);
2380 *(u16 *) & eth[12] = protocol; 2376 *(__be16 *) & eth[12] = protocol;
2381 2377
2382 /* Eth + IPh + UDPh + mpls */ 2378 /* Eth + IPh + UDPh + mpls */
2383 datalen = pkt_dev->cur_pkt_size - 14 - 20 - 8 - 2379 datalen = pkt_dev->cur_pkt_size - 14 - 20 - 8 -
@@ -2497,7 +2493,7 @@ static unsigned int scan_ip6(const char *s, char ip[16])
2497 char suffix[16]; 2493 char suffix[16];
2498 unsigned int prefixlen = 0; 2494 unsigned int prefixlen = 0;
2499 unsigned int suffixlen = 0; 2495 unsigned int suffixlen = 0;
2500 __u32 tmp; 2496 __be32 tmp;
2501 2497
2502 for (i = 0; i < 16; i++) 2498 for (i = 0; i < 16; i++)
2503 ip[i] = 0; 2499 ip[i] = 0;
@@ -2713,7 +2709,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
2713 udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr)); 2709 udph = (struct udphdr *)skb_put(skb, sizeof(struct udphdr));
2714 2710
2715 memcpy(eth, pkt_dev->hh, 12); 2711 memcpy(eth, pkt_dev->hh, 12);
2716 *(u16 *) & eth[12] = protocol; 2712 *(__be16 *) & eth[12] = protocol;
2717 2713
2718 /* Eth + IPh + UDPh + mpls */ 2714 /* Eth + IPh + UDPh + mpls */
2719 datalen = pkt_dev->cur_pkt_size - 14 - 2715 datalen = pkt_dev->cur_pkt_size - 14 -
@@ -2732,11 +2728,11 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
2732 udph->len = htons(datalen + sizeof(struct udphdr)); 2728 udph->len = htons(datalen + sizeof(struct udphdr));
2733 udph->check = 0; /* No checksum */ 2729 udph->check = 0; /* No checksum */
2734 2730
2735 *(u32 *) iph = __constant_htonl(0x60000000); /* Version + flow */ 2731 *(__be32 *) iph = __constant_htonl(0x60000000); /* Version + flow */
2736 2732
2737 if (pkt_dev->traffic_class) { 2733 if (pkt_dev->traffic_class) {
2738 /* Version + traffic class + flow (0) */ 2734 /* Version + traffic class + flow (0) */
2739 *(u32 *)iph |= htonl(0x60000000 | (pkt_dev->traffic_class << 20)); 2735 *(__be32 *)iph |= htonl(0x60000000 | (pkt_dev->traffic_class << 20));
2740 } 2736 }
2741 2737
2742 iph->hop_limit = 32; 2738 iph->hop_limit = 32;
@@ -3116,7 +3112,7 @@ static void pktgen_rem_thread(struct pktgen_thread *t)
3116{ 3112{
3117 /* Remove from the thread list */ 3113 /* Remove from the thread list */
3118 3114
3119 remove_proc_entry(t->name, pg_proc_dir); 3115 remove_proc_entry(t->tsk->comm, pg_proc_dir);
3120 3116
3121 mutex_lock(&pktgen_thread_lock); 3117 mutex_lock(&pktgen_thread_lock);
3122 3118
@@ -3264,58 +3260,40 @@ out:;
3264 * Main loop of the thread goes here 3260 * Main loop of the thread goes here
3265 */ 3261 */
3266 3262
3267static void pktgen_thread_worker(struct pktgen_thread *t) 3263static int pktgen_thread_worker(void *arg)
3268{ 3264{
3269 DEFINE_WAIT(wait); 3265 DEFINE_WAIT(wait);
3266 struct pktgen_thread *t = arg;
3270 struct pktgen_dev *pkt_dev = NULL; 3267 struct pktgen_dev *pkt_dev = NULL;
3271 int cpu = t->cpu; 3268 int cpu = t->cpu;
3272 sigset_t tmpsig;
3273 u32 max_before_softirq; 3269 u32 max_before_softirq;
3274 u32 tx_since_softirq = 0; 3270 u32 tx_since_softirq = 0;
3275 3271
3276 daemonize("pktgen/%d", cpu); 3272 BUG_ON(smp_processor_id() != cpu);
3277
3278 /* Block all signals except SIGKILL, SIGSTOP and SIGTERM */
3279
3280 spin_lock_irq(&current->sighand->siglock);
3281 tmpsig = current->blocked;
3282 siginitsetinv(&current->blocked,
3283 sigmask(SIGKILL) | sigmask(SIGSTOP) | sigmask(SIGTERM));
3284
3285 recalc_sigpending();
3286 spin_unlock_irq(&current->sighand->siglock);
3287
3288 /* Migrate to the right CPU */
3289 set_cpus_allowed(current, cpumask_of_cpu(cpu));
3290 if (smp_processor_id() != cpu)
3291 BUG();
3292 3273
3293 init_waitqueue_head(&t->queue); 3274 init_waitqueue_head(&t->queue);
3294 3275
3295 t->control &= ~(T_TERMINATE);
3296 t->control &= ~(T_RUN);
3297 t->control &= ~(T_STOP);
3298 t->control &= ~(T_REMDEVALL);
3299 t->control &= ~(T_REMDEV);
3300
3301 t->pid = current->pid; 3276 t->pid = current->pid;
3302 3277
3303 PG_DEBUG(printk("pktgen: starting pktgen/%d: pid=%d\n", cpu, current->pid)); 3278 PG_DEBUG(printk("pktgen: starting pktgen/%d: pid=%d\n", cpu, current->pid));
3304 3279
3305 max_before_softirq = t->max_before_softirq; 3280 max_before_softirq = t->max_before_softirq;
3306 3281
3307 __set_current_state(TASK_INTERRUPTIBLE); 3282 set_current_state(TASK_INTERRUPTIBLE);
3308 mb();
3309 3283
3310 while (1) { 3284 while (!kthread_should_stop()) {
3311 3285 pkt_dev = next_to_run(t);
3312 __set_current_state(TASK_RUNNING);
3313 3286
3314 /* 3287 if (!pkt_dev &&
3315 * Get next dev to xmit -- if any. 3288 (t->control & (T_STOP | T_RUN | T_REMDEVALL | T_REMDEV))
3316 */ 3289 == 0) {
3290 prepare_to_wait(&(t->queue), &wait,
3291 TASK_INTERRUPTIBLE);
3292 schedule_timeout(HZ / 10);
3293 finish_wait(&(t->queue), &wait);
3294 }
3317 3295
3318 pkt_dev = next_to_run(t); 3296 __set_current_state(TASK_RUNNING);
3319 3297
3320 if (pkt_dev) { 3298 if (pkt_dev) {
3321 3299
@@ -3333,21 +3311,8 @@ static void pktgen_thread_worker(struct pktgen_thread *t)
3333 do_softirq(); 3311 do_softirq();
3334 tx_since_softirq = 0; 3312 tx_since_softirq = 0;
3335 } 3313 }
3336 } else {
3337 prepare_to_wait(&(t->queue), &wait, TASK_INTERRUPTIBLE);
3338 schedule_timeout(HZ / 10);
3339 finish_wait(&(t->queue), &wait);
3340 } 3314 }
3341 3315
3342 /*
3343 * Back from sleep, either due to the timeout or signal.
3344 * We check if we have any "posted" work for us.
3345 */
3346
3347 if (t->control & T_TERMINATE || signal_pending(current))
3348 /* we received a request to terminate ourself */
3349 break;
3350
3351 if (t->control & T_STOP) { 3316 if (t->control & T_STOP) {
3352 pktgen_stop(t); 3317 pktgen_stop(t);
3353 t->control &= ~(T_STOP); 3318 t->control &= ~(T_STOP);
@@ -3368,20 +3333,19 @@ static void pktgen_thread_worker(struct pktgen_thread *t)
3368 t->control &= ~(T_REMDEV); 3333 t->control &= ~(T_REMDEV);
3369 } 3334 }
3370 3335
3371 if (need_resched()) 3336 set_current_state(TASK_INTERRUPTIBLE);
3372 schedule();
3373 } 3337 }
3374 3338
3375 PG_DEBUG(printk("pktgen: %s stopping all device\n", t->name)); 3339 PG_DEBUG(printk("pktgen: %s stopping all device\n", t->tsk->comm));
3376 pktgen_stop(t); 3340 pktgen_stop(t);
3377 3341
3378 PG_DEBUG(printk("pktgen: %s removing all device\n", t->name)); 3342 PG_DEBUG(printk("pktgen: %s removing all device\n", t->tsk->comm));
3379 pktgen_rem_all_ifs(t); 3343 pktgen_rem_all_ifs(t);
3380 3344
3381 PG_DEBUG(printk("pktgen: %s removing thread.\n", t->name)); 3345 PG_DEBUG(printk("pktgen: %s removing thread.\n", t->tsk->comm));
3382 pktgen_rem_thread(t); 3346 pktgen_rem_thread(t);
3383 3347
3384 t->removed = 1; 3348 return 0;
3385} 3349}
3386 3350
3387static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, 3351static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t,
@@ -3499,37 +3463,11 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)
3499 return add_dev_to_thread(t, pkt_dev); 3463 return add_dev_to_thread(t, pkt_dev);
3500} 3464}
3501 3465
3502static struct pktgen_thread *__init pktgen_find_thread(const char *name) 3466static int __init pktgen_create_thread(int cpu)
3503{ 3467{
3504 struct pktgen_thread *t; 3468 struct pktgen_thread *t;
3505
3506 mutex_lock(&pktgen_thread_lock);
3507
3508 list_for_each_entry(t, &pktgen_threads, th_list)
3509 if (strcmp(t->name, name) == 0) {
3510 mutex_unlock(&pktgen_thread_lock);
3511 return t;
3512 }
3513
3514 mutex_unlock(&pktgen_thread_lock);
3515 return NULL;
3516}
3517
3518static int __init pktgen_create_thread(const char *name, int cpu)
3519{
3520 int err;
3521 struct pktgen_thread *t = NULL;
3522 struct proc_dir_entry *pe; 3469 struct proc_dir_entry *pe;
3523 3470 struct task_struct *p;
3524 if (strlen(name) > 31) {
3525 printk("pktgen: ERROR: Thread name cannot be more than 31 characters.\n");
3526 return -EINVAL;
3527 }
3528
3529 if (pktgen_find_thread(name)) {
3530 printk("pktgen: ERROR: thread: %s already exists\n", name);
3531 return -EINVAL;
3532 }
3533 3471
3534 t = kzalloc(sizeof(struct pktgen_thread), GFP_KERNEL); 3472 t = kzalloc(sizeof(struct pktgen_thread), GFP_KERNEL);
3535 if (!t) { 3473 if (!t) {
@@ -3537,14 +3475,29 @@ static int __init pktgen_create_thread(const char *name, int cpu)
3537 return -ENOMEM; 3475 return -ENOMEM;
3538 } 3476 }
3539 3477
3540 strcpy(t->name, name);
3541 spin_lock_init(&t->if_lock); 3478 spin_lock_init(&t->if_lock);
3542 t->cpu = cpu; 3479 t->cpu = cpu;
3543 3480
3544 pe = create_proc_entry(t->name, 0600, pg_proc_dir); 3481 INIT_LIST_HEAD(&t->if_list);
3482
3483 list_add_tail(&t->th_list, &pktgen_threads);
3484
3485 p = kthread_create(pktgen_thread_worker, t, "kpktgend_%d", cpu);
3486 if (IS_ERR(p)) {
3487 printk("pktgen: kernel_thread() failed for cpu %d\n", t->cpu);
3488 list_del(&t->th_list);
3489 kfree(t);
3490 return PTR_ERR(p);
3491 }
3492 kthread_bind(p, cpu);
3493 t->tsk = p;
3494
3495 pe = create_proc_entry(t->tsk->comm, 0600, pg_proc_dir);
3545 if (!pe) { 3496 if (!pe) {
3546 printk("pktgen: cannot create %s/%s procfs entry.\n", 3497 printk("pktgen: cannot create %s/%s procfs entry.\n",
3547 PG_PROC_DIR, t->name); 3498 PG_PROC_DIR, t->tsk->comm);
3499 kthread_stop(p);
3500 list_del(&t->th_list);
3548 kfree(t); 3501 kfree(t);
3549 return -EINVAL; 3502 return -EINVAL;
3550 } 3503 }
@@ -3552,21 +3505,7 @@ static int __init pktgen_create_thread(const char *name, int cpu)
3552 pe->proc_fops = &pktgen_thread_fops; 3505 pe->proc_fops = &pktgen_thread_fops;
3553 pe->data = t; 3506 pe->data = t;
3554 3507
3555 INIT_LIST_HEAD(&t->if_list); 3508 wake_up_process(p);
3556
3557 list_add_tail(&t->th_list, &pktgen_threads);
3558
3559 t->removed = 0;
3560
3561 err = kernel_thread((void *)pktgen_thread_worker, (void *)t,
3562 CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
3563 if (err < 0) {
3564 printk("pktgen: kernel_thread() failed for cpu %d\n", t->cpu);
3565 remove_proc_entry(t->name, pg_proc_dir);
3566 list_del(&t->th_list);
3567 kfree(t);
3568 return err;
3569 }
3570 3509
3571 return 0; 3510 return 0;
3572} 3511}
@@ -3647,10 +3586,8 @@ static int __init pg_init(void)
3647 3586
3648 for_each_online_cpu(cpu) { 3587 for_each_online_cpu(cpu) {
3649 int err; 3588 int err;
3650 char buf[30];
3651 3589
3652 sprintf(buf, "kpktgend_%i", cpu); 3590 err = pktgen_create_thread(cpu);
3653 err = pktgen_create_thread(buf, cpu);
3654 if (err) 3591 if (err)
3655 printk("pktgen: WARNING: Cannot create thread for cpu %d (%d)\n", 3592 printk("pktgen: WARNING: Cannot create thread for cpu %d (%d)\n",
3656 cpu, err); 3593 cpu, err);
@@ -3678,9 +3615,8 @@ static void __exit pg_cleanup(void)
3678 3615
3679 list_for_each_safe(q, n, &pktgen_threads) { 3616 list_for_each_safe(q, n, &pktgen_threads) {
3680 t = list_entry(q, struct pktgen_thread, th_list); 3617 t = list_entry(q, struct pktgen_thread, th_list);
3681 t->control |= (T_TERMINATE); 3618 kthread_stop(t->tsk);
3682 3619 kfree(t);
3683 wait_event_interruptible_timeout(queue, (t->removed == 1), HZ);
3684 } 3620 }
3685 3621
3686 /* Un-register us from receiving netdevice events */ 3622 /* Un-register us from receiving netdevice events */
diff --git a/net/core/request_sock.c b/net/core/request_sock.c
index 79ebd75fbe..5f0818d815 100644
--- a/net/core/request_sock.c
+++ b/net/core/request_sock.c
@@ -15,6 +15,7 @@
15#include <linux/random.h> 15#include <linux/random.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <linux/string.h> 17#include <linux/string.h>
18#include <linux/vmalloc.h>
18 19
19#include <net/request_sock.h> 20#include <net/request_sock.h>
20 21
@@ -29,22 +30,31 @@
29 * it is absolutely not enough even at 100conn/sec. 256 cures most 30 * it is absolutely not enough even at 100conn/sec. 256 cures most
30 * of problems. This value is adjusted to 128 for very small machines 31 * of problems. This value is adjusted to 128 for very small machines
31 * (<=32Mb of memory) and to 1024 on normal or better ones (>=256Mb). 32 * (<=32Mb of memory) and to 1024 on normal or better ones (>=256Mb).
32 * Further increasing requires to change hash table size. 33 * Note : Dont forget somaxconn that may limit backlog too.
33 */ 34 */
34int sysctl_max_syn_backlog = 256; 35int sysctl_max_syn_backlog = 256;
35 36
36int reqsk_queue_alloc(struct request_sock_queue *queue, 37int reqsk_queue_alloc(struct request_sock_queue *queue,
37 const int nr_table_entries) 38 unsigned int nr_table_entries)
38{ 39{
39 const int lopt_size = sizeof(struct listen_sock) + 40 size_t lopt_size = sizeof(struct listen_sock);
40 nr_table_entries * sizeof(struct request_sock *); 41 struct listen_sock *lopt;
41 struct listen_sock *lopt = kzalloc(lopt_size, GFP_KERNEL); 42
42 43 nr_table_entries = min_t(u32, nr_table_entries, sysctl_max_syn_backlog);
44 nr_table_entries = max_t(u32, nr_table_entries, 8);
45 nr_table_entries = roundup_pow_of_two(nr_table_entries + 1);
46 lopt_size += nr_table_entries * sizeof(struct request_sock *);
47 if (lopt_size > PAGE_SIZE)
48 lopt = __vmalloc(lopt_size,
49 GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO,
50 PAGE_KERNEL);
51 else
52 lopt = kzalloc(lopt_size, GFP_KERNEL);
43 if (lopt == NULL) 53 if (lopt == NULL)
44 return -ENOMEM; 54 return -ENOMEM;
45 55
46 for (lopt->max_qlen_log = 6; 56 for (lopt->max_qlen_log = 3;
47 (1 << lopt->max_qlen_log) < sysctl_max_syn_backlog; 57 (1 << lopt->max_qlen_log) < nr_table_entries;
48 lopt->max_qlen_log++); 58 lopt->max_qlen_log++);
49 59
50 get_random_bytes(&lopt->hash_rnd, sizeof(lopt->hash_rnd)); 60 get_random_bytes(&lopt->hash_rnd, sizeof(lopt->hash_rnd));
@@ -65,9 +75,11 @@ void reqsk_queue_destroy(struct request_sock_queue *queue)
65{ 75{
66 /* make all the listen_opt local to us */ 76 /* make all the listen_opt local to us */
67 struct listen_sock *lopt = reqsk_queue_yank_listen_sk(queue); 77 struct listen_sock *lopt = reqsk_queue_yank_listen_sk(queue);
78 size_t lopt_size = sizeof(struct listen_sock) +
79 lopt->nr_table_entries * sizeof(struct request_sock *);
68 80
69 if (lopt->qlen != 0) { 81 if (lopt->qlen != 0) {
70 int i; 82 unsigned int i;
71 83
72 for (i = 0; i < lopt->nr_table_entries; i++) { 84 for (i = 0; i < lopt->nr_table_entries; i++) {
73 struct request_sock *req; 85 struct request_sock *req;
@@ -81,7 +93,10 @@ void reqsk_queue_destroy(struct request_sock_queue *queue)
81 } 93 }
82 94
83 BUG_TRAP(lopt->qlen == 0); 95 BUG_TRAP(lopt->qlen == 0);
84 kfree(lopt); 96 if (lopt_size > PAGE_SIZE)
97 vfree(lopt);
98 else
99 kfree(lopt);
85} 100}
86 101
87EXPORT_SYMBOL(reqsk_queue_destroy); 102EXPORT_SYMBOL(reqsk_queue_destroy);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 02f3c79478..e76539a5eb 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -108,7 +108,6 @@ static const int rtm_min[RTM_NR_FAMILIES] =
108 [RTM_FAM(RTM_NEWTCLASS)] = NLMSG_LENGTH(sizeof(struct tcmsg)), 108 [RTM_FAM(RTM_NEWTCLASS)] = NLMSG_LENGTH(sizeof(struct tcmsg)),
109 [RTM_FAM(RTM_NEWTFILTER)] = NLMSG_LENGTH(sizeof(struct tcmsg)), 109 [RTM_FAM(RTM_NEWTFILTER)] = NLMSG_LENGTH(sizeof(struct tcmsg)),
110 [RTM_FAM(RTM_NEWACTION)] = NLMSG_LENGTH(sizeof(struct tcamsg)), 110 [RTM_FAM(RTM_NEWACTION)] = NLMSG_LENGTH(sizeof(struct tcamsg)),
111 [RTM_FAM(RTM_NEWPREFIX)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
112 [RTM_FAM(RTM_GETMULTICAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), 111 [RTM_FAM(RTM_GETMULTICAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
113 [RTM_FAM(RTM_GETANYCAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)), 112 [RTM_FAM(RTM_GETANYCAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
114}; 113};
@@ -213,6 +212,26 @@ nla_put_failure:
213 return nla_nest_cancel(skb, mx); 212 return nla_nest_cancel(skb, mx);
214} 213}
215 214
215int rtnl_put_cacheinfo(struct sk_buff *skb, struct dst_entry *dst, u32 id,
216 u32 ts, u32 tsage, long expires, u32 error)
217{
218 struct rta_cacheinfo ci = {
219 .rta_lastuse = jiffies_to_clock_t(jiffies - dst->lastuse),
220 .rta_used = dst->__use,
221 .rta_clntref = atomic_read(&(dst->__refcnt)),
222 .rta_error = error,
223 .rta_id = id,
224 .rta_ts = ts,
225 .rta_tsage = tsage,
226 };
227
228 if (expires)
229 ci.rta_expires = jiffies_to_clock_t(expires);
230
231 return nla_put(skb, RTA_CACHEINFO, sizeof(ci), &ci);
232}
233
234EXPORT_SYMBOL_GPL(rtnl_put_cacheinfo);
216 235
217static void set_operstate(struct net_device *dev, unsigned char transition) 236static void set_operstate(struct net_device *dev, unsigned char transition)
218{ 237{
@@ -273,6 +292,25 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a,
273 a->tx_compressed = b->tx_compressed; 292 a->tx_compressed = b->tx_compressed;
274}; 293};
275 294
295static inline size_t if_nlmsg_size(int iwbuflen)
296{
297 return NLMSG_ALIGN(sizeof(struct ifinfomsg))
298 + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
299 + nla_total_size(IFNAMSIZ) /* IFLA_QDISC */
300 + nla_total_size(sizeof(struct rtnl_link_ifmap))
301 + nla_total_size(sizeof(struct rtnl_link_stats))
302 + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */
303 + nla_total_size(MAX_ADDR_LEN) /* IFLA_BROADCAST */
304 + nla_total_size(4) /* IFLA_TXQLEN */
305 + nla_total_size(4) /* IFLA_WEIGHT */
306 + nla_total_size(4) /* IFLA_MTU */
307 + nla_total_size(4) /* IFLA_LINK */
308 + nla_total_size(4) /* IFLA_MASTER */
309 + nla_total_size(1) /* IFLA_OPERSTATE */
310 + nla_total_size(1) /* IFLA_LINKMODE */
311 + nla_total_size(iwbuflen);
312}
313
276static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, 314static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
277 void *iwbuf, int iwbuflen, int type, u32 pid, 315 void *iwbuf, int iwbuflen, int type, u32 pid,
278 u32 seq, u32 change, unsigned int flags) 316 u32 seq, u32 change, unsigned int flags)
@@ -558,7 +596,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
558 struct sk_buff *nskb; 596 struct sk_buff *nskb;
559 char *iw_buf = NULL, *iw = NULL; 597 char *iw_buf = NULL, *iw = NULL;
560 int iw_buf_len = 0; 598 int iw_buf_len = 0;
561 int err, payload; 599 int err;
562 600
563 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy); 601 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
564 if (err < 0) 602 if (err < 0)
@@ -587,9 +625,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
587 } 625 }
588#endif /* CONFIG_NET_WIRELESS_RTNETLINK */ 626#endif /* CONFIG_NET_WIRELESS_RTNETLINK */
589 627
590 payload = NLMSG_ALIGN(sizeof(struct ifinfomsg) + 628 nskb = nlmsg_new(if_nlmsg_size(iw_buf_len), GFP_KERNEL);
591 nla_total_size(iw_buf_len));
592 nskb = nlmsg_new(nlmsg_total_size(payload), GFP_KERNEL);
593 if (nskb == NULL) { 629 if (nskb == NULL) {
594 err = -ENOBUFS; 630 err = -ENOBUFS;
595 goto errout; 631 goto errout;
@@ -597,10 +633,8 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
597 633
598 err = rtnl_fill_ifinfo(nskb, dev, iw, iw_buf_len, RTM_NEWLINK, 634 err = rtnl_fill_ifinfo(nskb, dev, iw, iw_buf_len, RTM_NEWLINK,
599 NETLINK_CB(skb).pid, nlh->nlmsg_seq, 0, 0); 635 NETLINK_CB(skb).pid, nlh->nlmsg_seq, 0, 0);
600 if (err <= 0) { 636 /* failure impilies BUG in if_nlmsg_size or wireless_rtnetlink_get */
601 kfree_skb(nskb); 637 BUG_ON(err < 0);
602 goto errout;
603 }
604 638
605 err = rtnl_unicast(nskb, NETLINK_CB(skb).pid); 639 err = rtnl_unicast(nskb, NETLINK_CB(skb).pid);
606errout: 640errout:
@@ -639,15 +673,13 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change)
639 struct sk_buff *skb; 673 struct sk_buff *skb;
640 int err = -ENOBUFS; 674 int err = -ENOBUFS;
641 675
642 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 676 skb = nlmsg_new(if_nlmsg_size(0), GFP_KERNEL);
643 if (skb == NULL) 677 if (skb == NULL)
644 goto errout; 678 goto errout;
645 679
646 err = rtnl_fill_ifinfo(skb, dev, NULL, 0, type, 0, 0, change, 0); 680 err = rtnl_fill_ifinfo(skb, dev, NULL, 0, type, 0, 0, change, 0);
647 if (err < 0) { 681 /* failure implies BUG in if_nlmsg_size() */
648 kfree_skb(skb); 682 BUG_ON(err < 0);
649 goto errout;
650 }
651 683
652 err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_KERNEL); 684 err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_KERNEL);
653errout: 685errout:
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index b8b1063580..de7801d589 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -56,7 +56,6 @@
56#include <linux/cache.h> 56#include <linux/cache.h>
57#include <linux/rtnetlink.h> 57#include <linux/rtnetlink.h>
58#include <linux/init.h> 58#include <linux/init.h>
59#include <linux/highmem.h>
60 59
61#include <net/protocol.h> 60#include <net/protocol.h>
62#include <net/dst.h> 61#include <net/dst.h>
@@ -67,8 +66,10 @@
67#include <asm/uaccess.h> 66#include <asm/uaccess.h>
68#include <asm/system.h> 67#include <asm/system.h>
69 68
70static kmem_cache_t *skbuff_head_cache __read_mostly; 69#include "kmap_skb.h"
71static kmem_cache_t *skbuff_fclone_cache __read_mostly; 70
71static struct kmem_cache *skbuff_head_cache __read_mostly;
72static struct kmem_cache *skbuff_fclone_cache __read_mostly;
72 73
73/* 74/*
74 * Keep out-of-line to prevent kernel bloat. 75 * Keep out-of-line to prevent kernel bloat.
@@ -131,6 +132,7 @@ EXPORT_SYMBOL(skb_truesize_bug);
131 * @gfp_mask: allocation mask 132 * @gfp_mask: allocation mask
132 * @fclone: allocate from fclone cache instead of head cache 133 * @fclone: allocate from fclone cache instead of head cache
133 * and allocate a cloned (child) skb 134 * and allocate a cloned (child) skb
135 * @node: numa node to allocate memory on
134 * 136 *
135 * Allocate a new &sk_buff. The returned buffer has no headroom and a 137 * Allocate a new &sk_buff. The returned buffer has no headroom and a
136 * tail room of size bytes. The object has a reference count of one. 138 * tail room of size bytes. The object has a reference count of one.
@@ -140,9 +142,9 @@ EXPORT_SYMBOL(skb_truesize_bug);
140 * %GFP_ATOMIC. 142 * %GFP_ATOMIC.
141 */ 143 */
142struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, 144struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
143 int fclone) 145 int fclone, int node)
144{ 146{
145 kmem_cache_t *cache; 147 struct kmem_cache *cache;
146 struct skb_shared_info *shinfo; 148 struct skb_shared_info *shinfo;
147 struct sk_buff *skb; 149 struct sk_buff *skb;
148 u8 *data; 150 u8 *data;
@@ -150,14 +152,14 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
150 cache = fclone ? skbuff_fclone_cache : skbuff_head_cache; 152 cache = fclone ? skbuff_fclone_cache : skbuff_head_cache;
151 153
152 /* Get the HEAD */ 154 /* Get the HEAD */
153 skb = kmem_cache_alloc(cache, gfp_mask & ~__GFP_DMA); 155 skb = kmem_cache_alloc_node(cache, gfp_mask & ~__GFP_DMA, node);
154 if (!skb) 156 if (!skb)
155 goto out; 157 goto out;
156 158
157 /* Get the DATA. Size must match skb_add_mtu(). */ 159 /* Get the DATA. Size must match skb_add_mtu(). */
158 size = SKB_DATA_ALIGN(size); 160 size = SKB_DATA_ALIGN(size);
159 data = kmalloc_track_caller(size + sizeof(struct skb_shared_info), 161 data = kmalloc_node_track_caller(size + sizeof(struct skb_shared_info),
160 gfp_mask); 162 gfp_mask, node);
161 if (!data) 163 if (!data)
162 goto nodata; 164 goto nodata;
163 165
@@ -209,7 +211,7 @@ nodata:
209 * Buffers may only be allocated from interrupts using a @gfp_mask of 211 * Buffers may only be allocated from interrupts using a @gfp_mask of
210 * %GFP_ATOMIC. 212 * %GFP_ATOMIC.
211 */ 213 */
212struct sk_buff *alloc_skb_from_cache(kmem_cache_t *cp, 214struct sk_buff *alloc_skb_from_cache(struct kmem_cache *cp,
213 unsigned int size, 215 unsigned int size,
214 gfp_t gfp_mask) 216 gfp_t gfp_mask)
215{ 217{
@@ -266,9 +268,10 @@ nodata:
266struct sk_buff *__netdev_alloc_skb(struct net_device *dev, 268struct sk_buff *__netdev_alloc_skb(struct net_device *dev,
267 unsigned int length, gfp_t gfp_mask) 269 unsigned int length, gfp_t gfp_mask)
268{ 270{
271 int node = dev->class_dev.dev ? dev_to_node(dev->class_dev.dev) : -1;
269 struct sk_buff *skb; 272 struct sk_buff *skb;
270 273
271 skb = alloc_skb(length + NET_SKB_PAD, gfp_mask); 274 skb = __alloc_skb(length + NET_SKB_PAD, gfp_mask, 0, node);
272 if (likely(skb)) { 275 if (likely(skb)) {
273 skb_reserve(skb, NET_SKB_PAD); 276 skb_reserve(skb, NET_SKB_PAD);
274 skb->dev = dev; 277 skb->dev = dev;
@@ -473,8 +476,8 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
473#endif 476#endif
474 C(protocol); 477 C(protocol);
475 n->destructor = NULL; 478 n->destructor = NULL;
479 C(mark);
476#ifdef CONFIG_NETFILTER 480#ifdef CONFIG_NETFILTER
477 C(nfmark);
478 C(nfct); 481 C(nfct);
479 nf_conntrack_get(skb->nfct); 482 nf_conntrack_get(skb->nfct);
480 C(nfctinfo); 483 C(nfctinfo);
@@ -534,8 +537,8 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
534 new->pkt_type = old->pkt_type; 537 new->pkt_type = old->pkt_type;
535 new->tstamp = old->tstamp; 538 new->tstamp = old->tstamp;
536 new->destructor = NULL; 539 new->destructor = NULL;
540 new->mark = old->mark;
537#ifdef CONFIG_NETFILTER 541#ifdef CONFIG_NETFILTER
538 new->nfmark = old->nfmark;
539 new->nfct = old->nfct; 542 new->nfct = old->nfct;
540 nf_conntrack_get(old->nfct); 543 nf_conntrack_get(old->nfct);
541 new->nfctinfo = old->nfctinfo; 544 new->nfctinfo = old->nfctinfo;
@@ -1240,8 +1243,8 @@ EXPORT_SYMBOL(skb_store_bits);
1240 1243
1241/* Checksum skb data. */ 1244/* Checksum skb data. */
1242 1245
1243unsigned int skb_checksum(const struct sk_buff *skb, int offset, 1246__wsum skb_checksum(const struct sk_buff *skb, int offset,
1244 int len, unsigned int csum) 1247 int len, __wsum csum)
1245{ 1248{
1246 int start = skb_headlen(skb); 1249 int start = skb_headlen(skb);
1247 int i, copy = start - offset; 1250 int i, copy = start - offset;
@@ -1265,7 +1268,7 @@ unsigned int skb_checksum(const struct sk_buff *skb, int offset,
1265 1268
1266 end = start + skb_shinfo(skb)->frags[i].size; 1269 end = start + skb_shinfo(skb)->frags[i].size;
1267 if ((copy = end - offset) > 0) { 1270 if ((copy = end - offset) > 0) {
1268 unsigned int csum2; 1271 __wsum csum2;
1269 u8 *vaddr; 1272 u8 *vaddr;
1270 skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 1273 skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
1271 1274
@@ -1294,7 +1297,7 @@ unsigned int skb_checksum(const struct sk_buff *skb, int offset,
1294 1297
1295 end = start + list->len; 1298 end = start + list->len;
1296 if ((copy = end - offset) > 0) { 1299 if ((copy = end - offset) > 0) {
1297 unsigned int csum2; 1300 __wsum csum2;
1298 if (copy > len) 1301 if (copy > len)
1299 copy = len; 1302 copy = len;
1300 csum2 = skb_checksum(list, offset - start, 1303 csum2 = skb_checksum(list, offset - start,
@@ -1315,8 +1318,8 @@ unsigned int skb_checksum(const struct sk_buff *skb, int offset,
1315 1318
1316/* Both of above in one bottle. */ 1319/* Both of above in one bottle. */
1317 1320
1318unsigned int skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, 1321__wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset,
1319 u8 *to, int len, unsigned int csum) 1322 u8 *to, int len, __wsum csum)
1320{ 1323{
1321 int start = skb_headlen(skb); 1324 int start = skb_headlen(skb);
1322 int i, copy = start - offset; 1325 int i, copy = start - offset;
@@ -1342,7 +1345,7 @@ unsigned int skb_copy_and_csum_bits(const struct sk_buff *skb, int offset,
1342 1345
1343 end = start + skb_shinfo(skb)->frags[i].size; 1346 end = start + skb_shinfo(skb)->frags[i].size;
1344 if ((copy = end - offset) > 0) { 1347 if ((copy = end - offset) > 0) {
1345 unsigned int csum2; 1348 __wsum csum2;
1346 u8 *vaddr; 1349 u8 *vaddr;
1347 skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; 1350 skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
1348 1351
@@ -1368,7 +1371,7 @@ unsigned int skb_copy_and_csum_bits(const struct sk_buff *skb, int offset,
1368 struct sk_buff *list = skb_shinfo(skb)->frag_list; 1371 struct sk_buff *list = skb_shinfo(skb)->frag_list;
1369 1372
1370 for (; list; list = list->next) { 1373 for (; list; list = list->next) {
1371 unsigned int csum2; 1374 __wsum csum2;
1372 int end; 1375 int end;
1373 1376
1374 BUG_TRAP(start <= offset + len); 1377 BUG_TRAP(start <= offset + len);
@@ -1396,7 +1399,7 @@ unsigned int skb_copy_and_csum_bits(const struct sk_buff *skb, int offset,
1396 1399
1397void skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to) 1400void skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to)
1398{ 1401{
1399 unsigned int csum; 1402 __wsum csum;
1400 long csstart; 1403 long csstart;
1401 1404
1402 if (skb->ip_summed == CHECKSUM_PARTIAL) 1405 if (skb->ip_summed == CHECKSUM_PARTIAL)
@@ -1414,9 +1417,9 @@ void skb_copy_and_csum_dev(const struct sk_buff *skb, u8 *to)
1414 skb->len - csstart, 0); 1417 skb->len - csstart, 0);
1415 1418
1416 if (skb->ip_summed == CHECKSUM_PARTIAL) { 1419 if (skb->ip_summed == CHECKSUM_PARTIAL) {
1417 long csstuff = csstart + skb->csum; 1420 long csstuff = csstart + skb->csum_offset;
1418 1421
1419 *((unsigned short *)(to + csstuff)) = csum_fold(csum); 1422 *((__sum16 *)(to + csstuff)) = csum_fold(csum);
1420 } 1423 }
1421} 1424}
1422 1425
diff --git a/net/core/sock.c b/net/core/sock.c
index ee6cd2541d..0ed5b4f0bc 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -111,6 +111,7 @@
111#include <linux/poll.h> 111#include <linux/poll.h>
112#include <linux/tcp.h> 112#include <linux/tcp.h>
113#include <linux/init.h> 113#include <linux/init.h>
114#include <linux/highmem.h>
114 115
115#include <asm/uaccess.h> 116#include <asm/uaccess.h>
116#include <asm/system.h> 117#include <asm/system.h>
@@ -270,7 +271,7 @@ out:
270} 271}
271EXPORT_SYMBOL(sock_queue_rcv_skb); 272EXPORT_SYMBOL(sock_queue_rcv_skb);
272 273
273int sk_receive_skb(struct sock *sk, struct sk_buff *skb) 274int sk_receive_skb(struct sock *sk, struct sk_buff *skb, const int nested)
274{ 275{
275 int rc = NET_RX_SUCCESS; 276 int rc = NET_RX_SUCCESS;
276 277
@@ -279,7 +280,10 @@ int sk_receive_skb(struct sock *sk, struct sk_buff *skb)
279 280
280 skb->dev = NULL; 281 skb->dev = NULL;
281 282
282 bh_lock_sock(sk); 283 if (nested)
284 bh_lock_sock_nested(sk);
285 else
286 bh_lock_sock(sk);
283 if (!sock_owned_by_user(sk)) { 287 if (!sock_owned_by_user(sk)) {
284 /* 288 /*
285 * trylock + unlock semantics: 289 * trylock + unlock semantics:
@@ -806,24 +810,11 @@ lenout:
806 */ 810 */
807static void inline sock_lock_init(struct sock *sk) 811static void inline sock_lock_init(struct sock *sk)
808{ 812{
809 spin_lock_init(&sk->sk_lock.slock); 813 sock_lock_init_class_and_name(sk,
810 sk->sk_lock.owner = NULL; 814 af_family_slock_key_strings[sk->sk_family],
811 init_waitqueue_head(&sk->sk_lock.wq); 815 af_family_slock_keys + sk->sk_family,
812 /* 816 af_family_key_strings[sk->sk_family],
813 * Make sure we are not reinitializing a held lock: 817 af_family_keys + sk->sk_family);
814 */
815 debug_check_no_locks_freed((void *)&sk->sk_lock, sizeof(sk->sk_lock));
816
817 /*
818 * Mark both the sk_lock and the sk_lock.slock as a
819 * per-address-family lock class:
820 */
821 lockdep_set_class_and_name(&sk->sk_lock.slock,
822 af_family_slock_keys + sk->sk_family,
823 af_family_slock_key_strings[sk->sk_family]);
824 lockdep_init_map(&sk->sk_lock.dep_map,
825 af_family_key_strings[sk->sk_family],
826 af_family_keys + sk->sk_family, 0);
827} 818}
828 819
829/** 820/**
@@ -837,7 +828,7 @@ struct sock *sk_alloc(int family, gfp_t priority,
837 struct proto *prot, int zero_it) 828 struct proto *prot, int zero_it)
838{ 829{
839 struct sock *sk = NULL; 830 struct sock *sk = NULL;
840 kmem_cache_t *slab = prot->slab; 831 struct kmem_cache *slab = prot->slab;
841 832
842 if (slab != NULL) 833 if (slab != NULL)
843 sk = kmem_cache_alloc(slab, priority); 834 sk = kmem_cache_alloc(slab, priority);
@@ -1527,7 +1518,7 @@ void sock_init_data(struct socket *sock, struct sock *sk)
1527 atomic_set(&sk->sk_refcnt, 1); 1518 atomic_set(&sk->sk_refcnt, 1);
1528} 1519}
1529 1520
1530void fastcall lock_sock(struct sock *sk) 1521void fastcall lock_sock_nested(struct sock *sk, int subclass)
1531{ 1522{
1532 might_sleep(); 1523 might_sleep();
1533 spin_lock_bh(&sk->sk_lock.slock); 1524 spin_lock_bh(&sk->sk_lock.slock);
@@ -1538,11 +1529,11 @@ void fastcall lock_sock(struct sock *sk)
1538 /* 1529 /*
1539 * The sk_lock has mutex_lock() semantics here: 1530 * The sk_lock has mutex_lock() semantics here:
1540 */ 1531 */
1541 mutex_acquire(&sk->sk_lock.dep_map, 0, 0, _RET_IP_); 1532 mutex_acquire(&sk->sk_lock.dep_map, subclass, 0, _RET_IP_);
1542 local_bh_enable(); 1533 local_bh_enable();
1543} 1534}
1544 1535
1545EXPORT_SYMBOL(lock_sock); 1536EXPORT_SYMBOL(lock_sock_nested);
1546 1537
1547void fastcall release_sock(struct sock *sk) 1538void fastcall release_sock(struct sock *sk)
1548{ 1539{
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
index 02534131d8..1e75b15854 100644
--- a/net/core/sysctl_net_core.c
+++ b/net/core/sysctl_net_core.c
@@ -21,10 +21,6 @@ extern __u32 sysctl_rmem_max;
21 21
22extern int sysctl_core_destroy_delay; 22extern int sysctl_core_destroy_delay;
23 23
24#ifdef CONFIG_NET_DIVERT
25extern char sysctl_divert_version[];
26#endif /* CONFIG_NET_DIVERT */
27
28#ifdef CONFIG_XFRM 24#ifdef CONFIG_XFRM
29extern u32 sysctl_xfrm_aevent_etime; 25extern u32 sysctl_xfrm_aevent_etime;
30extern u32 sysctl_xfrm_aevent_rseqth; 26extern u32 sysctl_xfrm_aevent_rseqth;
@@ -105,16 +101,6 @@ ctl_table core_table[] = {
105 .mode = 0644, 101 .mode = 0644,
106 .proc_handler = &proc_dointvec 102 .proc_handler = &proc_dointvec
107 }, 103 },
108#ifdef CONFIG_NET_DIVERT
109 {
110 .ctl_name = NET_CORE_DIVERT_VERSION,
111 .procname = "divert_version",
112 .data = (void *)sysctl_divert_version,
113 .maxlen = 32,
114 .mode = 0444,
115 .proc_handler = &proc_dostring
116 },
117#endif /* CONFIG_NET_DIVERT */
118#ifdef CONFIG_XFRM 104#ifdef CONFIG_XFRM
119 { 105 {
120 .ctl_name = NET_CORE_AEVENT_ETIME, 106 .ctl_name = NET_CORE_AEVENT_ETIME,
diff --git a/net/core/utils.c b/net/core/utils.c
index d93fe64f66..61556065f0 100644
--- a/net/core/utils.c
+++ b/net/core/utils.c
@@ -88,7 +88,7 @@ EXPORT_SYMBOL(in_aton);
88#define IN6PTON_NULL 0x20000000 /* first/tail */ 88#define IN6PTON_NULL 0x20000000 /* first/tail */
89#define IN6PTON_UNKNOWN 0x40000000 89#define IN6PTON_UNKNOWN 0x40000000
90 90
91static inline int digit2bin(char c, char delim) 91static inline int digit2bin(char c, int delim)
92{ 92{
93 if (c == delim || c == '\0') 93 if (c == delim || c == '\0')
94 return IN6PTON_DELIM; 94 return IN6PTON_DELIM;
@@ -99,7 +99,7 @@ static inline int digit2bin(char c, char delim)
99 return IN6PTON_UNKNOWN; 99 return IN6PTON_UNKNOWN;
100} 100}
101 101
102static inline int xdigit2bin(char c, char delim) 102static inline int xdigit2bin(char c, int delim)
103{ 103{
104 if (c == delim || c == '\0') 104 if (c == delim || c == '\0')
105 return IN6PTON_DELIM; 105 return IN6PTON_DELIM;
@@ -113,12 +113,14 @@ static inline int xdigit2bin(char c, char delim)
113 return (IN6PTON_XDIGIT | (c - 'a' + 10)); 113 return (IN6PTON_XDIGIT | (c - 'a' + 10));
114 if (c >= 'A' && c <= 'F') 114 if (c >= 'A' && c <= 'F')
115 return (IN6PTON_XDIGIT | (c - 'A' + 10)); 115 return (IN6PTON_XDIGIT | (c - 'A' + 10));
116 if (delim == -1)
117 return IN6PTON_DELIM;
116 return IN6PTON_UNKNOWN; 118 return IN6PTON_UNKNOWN;
117} 119}
118 120
119int in4_pton(const char *src, int srclen, 121int in4_pton(const char *src, int srclen,
120 u8 *dst, 122 u8 *dst,
121 char delim, const char **end) 123 int delim, const char **end)
122{ 124{
123 const char *s; 125 const char *s;
124 u8 *d; 126 u8 *d;
@@ -173,7 +175,7 @@ EXPORT_SYMBOL(in4_pton);
173 175
174int in6_pton(const char *src, int srclen, 176int in6_pton(const char *src, int srclen,
175 u8 *dst, 177 u8 *dst,
176 char delim, const char **end) 178 int delim, const char **end)
177{ 179{
178 const char *s, *tok = NULL; 180 const char *s, *tok = NULL;
179 u8 *d, *dc = NULL; 181 u8 *d, *dc = NULL;
diff --git a/net/core/wireless.c b/net/core/wireless.c
index cb1b8728d7..f69ab7b440 100644
--- a/net/core/wireless.c
+++ b/net/core/wireless.c
@@ -2130,7 +2130,7 @@ int iw_handler_set_spy(struct net_device * dev,
2130 * The rtnl_lock() make sure we don't race with the other iw_handlers. 2130 * The rtnl_lock() make sure we don't race with the other iw_handlers.
2131 * This make sure wireless_spy_update() "see" that the spy list 2131 * This make sure wireless_spy_update() "see" that the spy list
2132 * is temporarily disabled. */ 2132 * is temporarily disabled. */
2133 wmb(); 2133 smp_wmb();
2134 2134
2135 /* Are there are addresses to copy? */ 2135 /* Are there are addresses to copy? */
2136 if(wrqu->data.length > 0) { 2136 if(wrqu->data.length > 0) {
@@ -2159,7 +2159,7 @@ int iw_handler_set_spy(struct net_device * dev,
2159 } 2159 }
2160 2160
2161 /* Make sure above is updated before re-enabling */ 2161 /* Make sure above is updated before re-enabling */
2162 wmb(); 2162 smp_wmb();
2163 2163
2164 /* Enable addresses */ 2164 /* Enable addresses */
2165 spydata->spy_number = wrqu->data.length; 2165 spydata->spy_number = wrqu->data.length;
diff --git a/net/dccp/Kconfig b/net/dccp/Kconfig
index ef8919cca7..b8a68dd410 100644
--- a/net/dccp/Kconfig
+++ b/net/dccp/Kconfig
@@ -38,6 +38,9 @@ config IP_DCCP_DEBUG
38 ---help--- 38 ---help---
39 Only use this if you're hacking DCCP. 39 Only use this if you're hacking DCCP.
40 40
41 When compiling DCCP as a module, this debugging output can be toggled
42 by setting the parameter dccp_debug of the `dccp' module to 0 or 1.
43
41 Just say N. 44 Just say N.
42 45
43config NET_DCCPPROBE 46config NET_DCCPPROBE
@@ -49,7 +52,7 @@ config NET_DCCPPROBE
49 DCCP congestion avoidance modules. If you don't understand 52 DCCP congestion avoidance modules. If you don't understand
50 what was just said, you don't need it: say N. 53 what was just said, you don't need it: say N.
51 54
52 Documentation on how to use the packet generator can be found 55 Documentation on how to use DCCP connection probing can be found
53 at http://linux-net.osdl.org/index.php/DccpProbe 56 at http://linux-net.osdl.org/index.php/DccpProbe
54 57
55 To compile this code as a module, choose M here: the 58 To compile this code as a module, choose M here: the
diff --git a/net/dccp/Makefile b/net/dccp/Makefile
index 17ed99c466..f4f8793aaf 100644
--- a/net/dccp/Makefile
+++ b/net/dccp/Makefile
@@ -1,13 +1,13 @@
1obj-$(CONFIG_IPV6) += dccp_ipv6.o
2
3dccp_ipv6-y := ipv6.o
4
5obj-$(CONFIG_IP_DCCP) += dccp.o dccp_ipv4.o 1obj-$(CONFIG_IP_DCCP) += dccp.o dccp_ipv4.o
6 2
7dccp-y := ccid.o feat.o input.o minisocks.o options.o output.o proto.o timer.o 3dccp-y := ccid.o feat.o input.o minisocks.o options.o output.o proto.o timer.o
8 4
9dccp_ipv4-y := ipv4.o 5dccp_ipv4-y := ipv4.o
10 6
7# build dccp_ipv6 as module whenever either IPv6 or DCCP is a module
8obj-$(subst y,$(CONFIG_IP_DCCP),$(CONFIG_IPV6)) += dccp_ipv6.o
9dccp_ipv6-y := ipv6.o
10
11dccp-$(CONFIG_IP_DCCP_ACKVEC) += ackvec.o 11dccp-$(CONFIG_IP_DCCP_ACKVEC) += ackvec.o
12 12
13obj-$(CONFIG_INET_DCCP_DIAG) += dccp_diag.o 13obj-$(CONFIG_INET_DCCP_DIAG) += dccp_diag.o
diff --git a/net/dccp/ackvec.c b/net/dccp/ackvec.c
index f8208874ac..a086c6312d 100644
--- a/net/dccp/ackvec.c
+++ b/net/dccp/ackvec.c
@@ -21,8 +21,8 @@
21 21
22#include <net/sock.h> 22#include <net/sock.h>
23 23
24static kmem_cache_t *dccp_ackvec_slab; 24static struct kmem_cache *dccp_ackvec_slab;
25static kmem_cache_t *dccp_ackvec_record_slab; 25static struct kmem_cache *dccp_ackvec_record_slab;
26 26
27static struct dccp_ackvec_record *dccp_ackvec_record_new(void) 27static struct dccp_ackvec_record *dccp_ackvec_record_new(void)
28{ 28{
@@ -67,15 +67,16 @@ static void dccp_ackvec_insert_avr(struct dccp_ackvec *av,
67int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb) 67int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb)
68{ 68{
69 struct dccp_sock *dp = dccp_sk(sk); 69 struct dccp_sock *dp = dccp_sk(sk);
70#ifdef CONFIG_IP_DCCP_DEBUG
71 const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ?
72 "CLIENT tx: " : "server tx: ";
73#endif
74 struct dccp_ackvec *av = dp->dccps_hc_rx_ackvec; 70 struct dccp_ackvec *av = dp->dccps_hc_rx_ackvec;
75 int len = av->dccpav_vec_len + 2; 71 /* Figure out how many options do we need to represent the ackvec */
72 const u16 nr_opts = (av->dccpav_vec_len +
73 DCCP_MAX_ACKVEC_OPT_LEN - 1) /
74 DCCP_MAX_ACKVEC_OPT_LEN;
75 u16 len = av->dccpav_vec_len + 2 * nr_opts, i;
76 struct timeval now; 76 struct timeval now;
77 u32 elapsed_time; 77 u32 elapsed_time;
78 unsigned char *to, *from; 78 const unsigned char *tail, *from;
79 unsigned char *to;
79 struct dccp_ackvec_record *avr; 80 struct dccp_ackvec_record *avr;
80 81
81 if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN) 82 if (DCCP_SKB_CB(skb)->dccpd_opt_len + len > DCCP_MAX_OPT_LEN)
@@ -94,24 +95,37 @@ int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb)
94 95
95 DCCP_SKB_CB(skb)->dccpd_opt_len += len; 96 DCCP_SKB_CB(skb)->dccpd_opt_len += len;
96 97
97 to = skb_push(skb, len); 98 to = skb_push(skb, len);
98 *to++ = DCCPO_ACK_VECTOR_0;
99 *to++ = len;
100
101 len = av->dccpav_vec_len; 99 len = av->dccpav_vec_len;
102 from = av->dccpav_buf + av->dccpav_buf_head; 100 from = av->dccpav_buf + av->dccpav_buf_head;
101 tail = av->dccpav_buf + DCCP_MAX_ACKVEC_LEN;
102
103 for (i = 0; i < nr_opts; ++i) {
104 int copylen = len;
105
106 if (len > DCCP_MAX_ACKVEC_OPT_LEN)
107 copylen = DCCP_MAX_ACKVEC_OPT_LEN;
103 108
104 /* Check if buf_head wraps */ 109 *to++ = DCCPO_ACK_VECTOR_0;
105 if ((int)av->dccpav_buf_head + len > DCCP_MAX_ACKVEC_LEN) { 110 *to++ = copylen + 2;
106 const u32 tailsize = DCCP_MAX_ACKVEC_LEN - av->dccpav_buf_head;
107 111
108 memcpy(to, from, tailsize); 112 /* Check if buf_head wraps */
109 to += tailsize; 113 if (from + copylen > tail) {
110 len -= tailsize; 114 const u16 tailsize = tail - from;
111 from = av->dccpav_buf; 115
116 memcpy(to, from, tailsize);
117 to += tailsize;
118 len -= tailsize;
119 copylen -= tailsize;
120 from = av->dccpav_buf;
121 }
122
123 memcpy(to, from, copylen);
124 from += copylen;
125 to += copylen;
126 len -= copylen;
112 } 127 }
113 128
114 memcpy(to, from, len);
115 /* 129 /*
116 * From RFC 4340, A.2: 130 * From RFC 4340, A.2:
117 * 131 *
@@ -129,9 +143,9 @@ int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb)
129 143
130 dccp_ackvec_insert_avr(av, avr); 144 dccp_ackvec_insert_avr(av, avr);
131 145
132 dccp_pr_debug("%sACK Vector 0, len=%d, ack_seqno=%llu, " 146 dccp_pr_debug("%s ACK Vector 0, len=%d, ack_seqno=%llu, "
133 "ack_ackno=%llu\n", 147 "ack_ackno=%llu\n",
134 debug_prefix, avr->dccpavr_sent_len, 148 dccp_role(sk), avr->dccpavr_sent_len,
135 (unsigned long long)avr->dccpavr_ack_seqno, 149 (unsigned long long)avr->dccpavr_ack_seqno,
136 (unsigned long long)avr->dccpavr_ack_ackno); 150 (unsigned long long)avr->dccpavr_ack_ackno);
137 return 0; 151 return 0;
@@ -145,7 +159,6 @@ struct dccp_ackvec *dccp_ackvec_alloc(const gfp_t priority)
145 av->dccpav_buf_head = DCCP_MAX_ACKVEC_LEN - 1; 159 av->dccpav_buf_head = DCCP_MAX_ACKVEC_LEN - 1;
146 av->dccpav_buf_ackno = DCCP_MAX_SEQNO + 1; 160 av->dccpav_buf_ackno = DCCP_MAX_SEQNO + 1;
147 av->dccpav_buf_nonce = av->dccpav_buf_nonce = 0; 161 av->dccpav_buf_nonce = av->dccpav_buf_nonce = 0;
148 av->dccpav_ack_ptr = 0;
149 av->dccpav_time.tv_sec = 0; 162 av->dccpav_time.tv_sec = 0;
150 av->dccpav_time.tv_usec = 0; 163 av->dccpav_time.tv_usec = 0;
151 av->dccpav_vec_len = 0; 164 av->dccpav_vec_len = 0;
@@ -174,13 +187,13 @@ void dccp_ackvec_free(struct dccp_ackvec *av)
174} 187}
175 188
176static inline u8 dccp_ackvec_state(const struct dccp_ackvec *av, 189static inline u8 dccp_ackvec_state(const struct dccp_ackvec *av,
177 const u8 index) 190 const u32 index)
178{ 191{
179 return av->dccpav_buf[index] & DCCP_ACKVEC_STATE_MASK; 192 return av->dccpav_buf[index] & DCCP_ACKVEC_STATE_MASK;
180} 193}
181 194
182static inline u8 dccp_ackvec_len(const struct dccp_ackvec *av, 195static inline u8 dccp_ackvec_len(const struct dccp_ackvec *av,
183 const u8 index) 196 const u32 index)
184{ 197{
185 return av->dccpav_buf[index] & DCCP_ACKVEC_LEN_MASK; 198 return av->dccpav_buf[index] & DCCP_ACKVEC_LEN_MASK;
186} 199}
@@ -210,7 +223,7 @@ static inline int dccp_ackvec_set_buf_head_state(struct dccp_ackvec *av,
210 gap = -new_head; 223 gap = -new_head;
211 } 224 }
212 new_head += DCCP_MAX_ACKVEC_LEN; 225 new_head += DCCP_MAX_ACKVEC_LEN;
213 } 226 }
214 227
215 av->dccpav_buf_head = new_head; 228 av->dccpav_buf_head = new_head;
216 229
@@ -280,7 +293,7 @@ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk,
280 * could reduce the complexity of this scan.) 293 * could reduce the complexity of this scan.)
281 */ 294 */
282 u64 delta = dccp_delta_seqno(ackno, av->dccpav_buf_ackno); 295 u64 delta = dccp_delta_seqno(ackno, av->dccpav_buf_ackno);
283 u8 index = av->dccpav_buf_head; 296 u32 index = av->dccpav_buf_head;
284 297
285 while (1) { 298 while (1) {
286 const u8 len = dccp_ackvec_len(av, index); 299 const u8 len = dccp_ackvec_len(av, index);
@@ -322,21 +335,18 @@ out_duplicate:
322#ifdef CONFIG_IP_DCCP_DEBUG 335#ifdef CONFIG_IP_DCCP_DEBUG
323void dccp_ackvector_print(const u64 ackno, const unsigned char *vector, int len) 336void dccp_ackvector_print(const u64 ackno, const unsigned char *vector, int len)
324{ 337{
325 if (!dccp_debug) 338 dccp_pr_debug_cat("ACK vector len=%d, ackno=%llu |", len,
326 return; 339 (unsigned long long)ackno);
327
328 printk("ACK vector len=%d, ackno=%llu |", len,
329 (unsigned long long)ackno);
330 340
331 while (len--) { 341 while (len--) {
332 const u8 state = (*vector & DCCP_ACKVEC_STATE_MASK) >> 6; 342 const u8 state = (*vector & DCCP_ACKVEC_STATE_MASK) >> 6;
333 const u8 rl = *vector & DCCP_ACKVEC_LEN_MASK; 343 const u8 rl = *vector & DCCP_ACKVEC_LEN_MASK;
334 344
335 printk("%d,%d|", state, rl); 345 dccp_pr_debug_cat("%d,%d|", state, rl);
336 ++vector; 346 ++vector;
337 } 347 }
338 348
339 printk("\n"); 349 dccp_pr_debug_cat("\n");
340} 350}
341 351
342void dccp_ackvec_print(const struct dccp_ackvec *av) 352void dccp_ackvec_print(const struct dccp_ackvec *av)
@@ -380,24 +390,20 @@ void dccp_ackvec_check_rcv_ackno(struct dccp_ackvec *av, struct sock *sk,
380 */ 390 */
381 list_for_each_entry_reverse(avr, &av->dccpav_records, dccpavr_node) { 391 list_for_each_entry_reverse(avr, &av->dccpav_records, dccpavr_node) {
382 if (ackno == avr->dccpavr_ack_seqno) { 392 if (ackno == avr->dccpavr_ack_seqno) {
383#ifdef CONFIG_IP_DCCP_DEBUG 393 dccp_pr_debug("%s ACK packet 0, len=%d, ack_seqno=%llu, "
384 struct dccp_sock *dp = dccp_sk(sk);
385 const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ?
386 "CLIENT rx ack: " : "server rx ack: ";
387#endif
388 dccp_pr_debug("%sACK packet 0, len=%d, ack_seqno=%llu, "
389 "ack_ackno=%llu, ACKED!\n", 394 "ack_ackno=%llu, ACKED!\n",
390 debug_prefix, 1, 395 dccp_role(sk), 1,
391 (unsigned long long)avr->dccpavr_ack_seqno, 396 (unsigned long long)avr->dccpavr_ack_seqno,
392 (unsigned long long)avr->dccpavr_ack_ackno); 397 (unsigned long long)avr->dccpavr_ack_ackno);
393 dccp_ackvec_throw_record(av, avr); 398 dccp_ackvec_throw_record(av, avr);
394 break; 399 break;
395 } 400 } else if (avr->dccpavr_ack_seqno > ackno)
401 break; /* old news */
396 } 402 }
397} 403}
398 404
399static void dccp_ackvec_check_rcv_ackvector(struct dccp_ackvec *av, 405static void dccp_ackvec_check_rcv_ackvector(struct dccp_ackvec *av,
400 struct sock *sk, u64 ackno, 406 struct sock *sk, u64 *ackno,
401 const unsigned char len, 407 const unsigned char len,
402 const unsigned char *vector) 408 const unsigned char *vector)
403{ 409{
@@ -420,7 +426,7 @@ static void dccp_ackvec_check_rcv_ackvector(struct dccp_ackvec *av,
420 const u8 rl = *vector & DCCP_ACKVEC_LEN_MASK; 426 const u8 rl = *vector & DCCP_ACKVEC_LEN_MASK;
421 u64 ackno_end_rl; 427 u64 ackno_end_rl;
422 428
423 dccp_set_seqno(&ackno_end_rl, ackno - rl); 429 dccp_set_seqno(&ackno_end_rl, *ackno - rl);
424 430
425 /* 431 /*
426 * If our AVR sequence number is greater than the ack, go 432 * If our AVR sequence number is greater than the ack, go
@@ -428,25 +434,19 @@ static void dccp_ackvec_check_rcv_ackvector(struct dccp_ackvec *av,
428 */ 434 */
429 list_for_each_entry_from(avr, &av->dccpav_records, 435 list_for_each_entry_from(avr, &av->dccpav_records,
430 dccpavr_node) { 436 dccpavr_node) {
431 if (!after48(avr->dccpavr_ack_seqno, ackno)) 437 if (!after48(avr->dccpavr_ack_seqno, *ackno))
432 goto found; 438 goto found;
433 } 439 }
434 /* End of the dccpav_records list, not found, exit */ 440 /* End of the dccpav_records list, not found, exit */
435 break; 441 break;
436found: 442found:
437 if (between48(avr->dccpavr_ack_seqno, ackno_end_rl, ackno)) { 443 if (between48(avr->dccpavr_ack_seqno, ackno_end_rl, *ackno)) {
438 const u8 state = *vector & DCCP_ACKVEC_STATE_MASK; 444 const u8 state = *vector & DCCP_ACKVEC_STATE_MASK;
439 if (state != DCCP_ACKVEC_STATE_NOT_RECEIVED) { 445 if (state != DCCP_ACKVEC_STATE_NOT_RECEIVED) {
440#ifdef CONFIG_IP_DCCP_DEBUG 446 dccp_pr_debug("%s ACK vector 0, len=%d, "
441 struct dccp_sock *dp = dccp_sk(sk);
442 const char *debug_prefix =
443 dp->dccps_role == DCCP_ROLE_CLIENT ?
444 "CLIENT rx ack: " : "server rx ack: ";
445#endif
446 dccp_pr_debug("%sACK vector 0, len=%d, "
447 "ack_seqno=%llu, ack_ackno=%llu, " 447 "ack_seqno=%llu, ack_ackno=%llu, "
448 "ACKED!\n", 448 "ACKED!\n",
449 debug_prefix, len, 449 dccp_role(sk), len,
450 (unsigned long long) 450 (unsigned long long)
451 avr->dccpavr_ack_seqno, 451 avr->dccpavr_ack_seqno,
452 (unsigned long long) 452 (unsigned long long)
@@ -460,27 +460,23 @@ found:
460 */ 460 */
461 } 461 }
462 462
463 dccp_set_seqno(&ackno, ackno_end_rl - 1); 463 dccp_set_seqno(ackno, ackno_end_rl - 1);
464 ++vector; 464 ++vector;
465 } 465 }
466} 466}
467 467
468int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb, 468int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb,
469 const u8 opt, const u8 *value, const u8 len) 469 u64 *ackno, const u8 opt, const u8 *value, const u8 len)
470{ 470{
471 if (len > DCCP_MAX_ACKVEC_LEN) 471 if (len > DCCP_MAX_ACKVEC_OPT_LEN)
472 return -1; 472 return -1;
473 473
474 /* dccp_ackvector_print(DCCP_SKB_CB(skb)->dccpd_ack_seq, value, len); */ 474 /* dccp_ackvector_print(DCCP_SKB_CB(skb)->dccpd_ack_seq, value, len); */
475 dccp_ackvec_check_rcv_ackvector(dccp_sk(sk)->dccps_hc_rx_ackvec, sk, 475 dccp_ackvec_check_rcv_ackvector(dccp_sk(sk)->dccps_hc_rx_ackvec, sk,
476 DCCP_SKB_CB(skb)->dccpd_ack_seq, 476 ackno, len, value);
477 len, value);
478 return 0; 477 return 0;
479} 478}
480 479
481static char dccp_ackvec_slab_msg[] __initdata =
482 KERN_CRIT "DCCP: Unable to create ack vectors slab caches\n";
483
484int __init dccp_ackvec_init(void) 480int __init dccp_ackvec_init(void)
485{ 481{
486 dccp_ackvec_slab = kmem_cache_create("dccp_ackvec", 482 dccp_ackvec_slab = kmem_cache_create("dccp_ackvec",
@@ -502,7 +498,7 @@ out_destroy_slab:
502 kmem_cache_destroy(dccp_ackvec_slab); 498 kmem_cache_destroy(dccp_ackvec_slab);
503 dccp_ackvec_slab = NULL; 499 dccp_ackvec_slab = NULL;
504out_err: 500out_err:
505 printk(dccp_ackvec_slab_msg); 501 DCCP_CRIT("Unable to create Ack Vector slab cache");
506 return -ENOBUFS; 502 return -ENOBUFS;
507} 503}
508 504
diff --git a/net/dccp/ackvec.h b/net/dccp/ackvec.h
index cf8f20ce23..96504a3b16 100644
--- a/net/dccp/ackvec.h
+++ b/net/dccp/ackvec.h
@@ -17,7 +17,9 @@
17#include <linux/types.h> 17#include <linux/types.h>
18 18
19/* Read about the ECN nonce to see why it is 253 */ 19/* Read about the ECN nonce to see why it is 253 */
20#define DCCP_MAX_ACKVEC_LEN 253 20#define DCCP_MAX_ACKVEC_OPT_LEN 253
21/* We can spread an ack vector across multiple options */
22#define DCCP_MAX_ACKVEC_LEN (DCCP_MAX_ACKVEC_OPT_LEN * 2)
21 23
22#define DCCP_ACKVEC_STATE_RECEIVED 0 24#define DCCP_ACKVEC_STATE_RECEIVED 0
23#define DCCP_ACKVEC_STATE_ECN_MARKED (1 << 6) 25#define DCCP_ACKVEC_STATE_ECN_MARKED (1 << 6)
@@ -41,7 +43,6 @@
41 * Ack Vectors it has recently sent. For each packet sent carrying an 43 * Ack Vectors it has recently sent. For each packet sent carrying an
42 * Ack Vector, it remembers four variables: 44 * Ack Vector, it remembers four variables:
43 * 45 *
44 * @dccpav_ack_ptr - the value of buf_head at the time of acknowledgement.
45 * @dccpav_records - list of dccp_ackvec_record 46 * @dccpav_records - list of dccp_ackvec_record
46 * @dccpav_ack_nonce - the one-bit sum of the ECN Nonces for all State 0. 47 * @dccpav_ack_nonce - the one-bit sum of the ECN Nonces for all State 0.
47 * 48 *
@@ -52,9 +53,8 @@ struct dccp_ackvec {
52 u64 dccpav_buf_ackno; 53 u64 dccpav_buf_ackno;
53 struct list_head dccpav_records; 54 struct list_head dccpav_records;
54 struct timeval dccpav_time; 55 struct timeval dccpav_time;
55 u8 dccpav_buf_head; 56 u16 dccpav_buf_head;
56 u8 dccpav_ack_ptr; 57 u16 dccpav_vec_len;
57 u8 dccpav_vec_len;
58 u8 dccpav_buf_nonce; 58 u8 dccpav_buf_nonce;
59 u8 dccpav_ack_nonce; 59 u8 dccpav_ack_nonce;
60 u8 dccpav_buf[DCCP_MAX_ACKVEC_LEN]; 60 u8 dccpav_buf[DCCP_MAX_ACKVEC_LEN];
@@ -77,9 +77,9 @@ struct dccp_ackvec_record {
77 struct list_head dccpavr_node; 77 struct list_head dccpavr_node;
78 u64 dccpavr_ack_seqno; 78 u64 dccpavr_ack_seqno;
79 u64 dccpavr_ack_ackno; 79 u64 dccpavr_ack_ackno;
80 u8 dccpavr_ack_ptr; 80 u16 dccpavr_ack_ptr;
81 u16 dccpavr_sent_len;
81 u8 dccpavr_ack_nonce; 82 u8 dccpavr_ack_nonce;
82 u8 dccpavr_sent_len;
83}; 83};
84 84
85struct sock; 85struct sock;
@@ -98,7 +98,8 @@ extern int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk,
98extern void dccp_ackvec_check_rcv_ackno(struct dccp_ackvec *av, 98extern void dccp_ackvec_check_rcv_ackno(struct dccp_ackvec *av,
99 struct sock *sk, const u64 ackno); 99 struct sock *sk, const u64 ackno);
100extern int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb, 100extern int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb,
101 const u8 opt, const u8 *value, const u8 len); 101 u64 *ackno, const u8 opt,
102 const u8 *value, const u8 len);
102 103
103extern int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb); 104extern int dccp_insert_option_ackvec(struct sock *sk, struct sk_buff *skb);
104 105
@@ -137,7 +138,8 @@ static inline void dccp_ackvec_check_rcv_ackno(struct dccp_ackvec *av,
137} 138}
138 139
139static inline int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb, 140static inline int dccp_ackvec_parse(struct sock *sk, const struct sk_buff *skb,
140 const u8 opt, const u8 *value, const u8 len) 141 const u64 *ackno, const u8 opt,
142 const u8 *value, const u8 len)
141{ 143{
142 return -1; 144 return -1;
143} 145}
diff --git a/net/dccp/ccid.c b/net/dccp/ccid.c
index ff05e59043..d8cf92f09e 100644
--- a/net/dccp/ccid.c
+++ b/net/dccp/ccid.c
@@ -55,9 +55,9 @@ static inline void ccids_read_unlock(void)
55#define ccids_read_unlock() do { } while(0) 55#define ccids_read_unlock() do { } while(0)
56#endif 56#endif
57 57
58static kmem_cache_t *ccid_kmem_cache_create(int obj_size, const char *fmt,...) 58static struct kmem_cache *ccid_kmem_cache_create(int obj_size, const char *fmt,...)
59{ 59{
60 kmem_cache_t *slab; 60 struct kmem_cache *slab;
61 char slab_name_fmt[32], *slab_name; 61 char slab_name_fmt[32], *slab_name;
62 va_list args; 62 va_list args;
63 63
@@ -75,7 +75,7 @@ static kmem_cache_t *ccid_kmem_cache_create(int obj_size, const char *fmt,...)
75 return slab; 75 return slab;
76} 76}
77 77
78static void ccid_kmem_cache_destroy(kmem_cache_t *slab) 78static void ccid_kmem_cache_destroy(struct kmem_cache *slab)
79{ 79{
80 if (slab != NULL) { 80 if (slab != NULL) {
81 const char *name = kmem_cache_name(slab); 81 const char *name = kmem_cache_name(slab);
diff --git a/net/dccp/ccid.h b/net/dccp/ccid.h
index f7eb6c6134..c65cb2453e 100644
--- a/net/dccp/ccid.h
+++ b/net/dccp/ccid.h
@@ -27,9 +27,9 @@ struct ccid_operations {
27 unsigned char ccid_id; 27 unsigned char ccid_id;
28 const char *ccid_name; 28 const char *ccid_name;
29 struct module *ccid_owner; 29 struct module *ccid_owner;
30 kmem_cache_t *ccid_hc_rx_slab; 30 struct kmem_cache *ccid_hc_rx_slab;
31 __u32 ccid_hc_rx_obj_size; 31 __u32 ccid_hc_rx_obj_size;
32 kmem_cache_t *ccid_hc_tx_slab; 32 struct kmem_cache *ccid_hc_tx_slab;
33 __u32 ccid_hc_tx_obj_size; 33 __u32 ccid_hc_tx_obj_size;
34 int (*ccid_hc_rx_init)(struct ccid *ccid, struct sock *sk); 34 int (*ccid_hc_rx_init)(struct ccid *ccid, struct sock *sk);
35 int (*ccid_hc_tx_init)(struct ccid *ccid, struct sock *sk); 35 int (*ccid_hc_tx_init)(struct ccid *ccid, struct sock *sk);
@@ -43,8 +43,6 @@ struct ccid_operations {
43 unsigned char* value); 43 unsigned char* value);
44 int (*ccid_hc_rx_insert_options)(struct sock *sk, 44 int (*ccid_hc_rx_insert_options)(struct sock *sk,
45 struct sk_buff *skb); 45 struct sk_buff *skb);
46 int (*ccid_hc_tx_insert_options)(struct sock *sk,
47 struct sk_buff *skb);
48 void (*ccid_hc_tx_packet_recv)(struct sock *sk, 46 void (*ccid_hc_tx_packet_recv)(struct sock *sk,
49 struct sk_buff *skb); 47 struct sk_buff *skb);
50 int (*ccid_hc_tx_parse_options)(struct sock *sk, 48 int (*ccid_hc_tx_parse_options)(struct sock *sk,
@@ -52,9 +50,9 @@ struct ccid_operations {
52 unsigned char len, u16 idx, 50 unsigned char len, u16 idx,
53 unsigned char* value); 51 unsigned char* value);
54 int (*ccid_hc_tx_send_packet)(struct sock *sk, 52 int (*ccid_hc_tx_send_packet)(struct sock *sk,
55 struct sk_buff *skb, int len); 53 struct sk_buff *skb);
56 void (*ccid_hc_tx_packet_sent)(struct sock *sk, int more, 54 void (*ccid_hc_tx_packet_sent)(struct sock *sk,
57 int len); 55 int more, unsigned int len);
58 void (*ccid_hc_rx_get_info)(struct sock *sk, 56 void (*ccid_hc_rx_get_info)(struct sock *sk,
59 struct tcp_info *info); 57 struct tcp_info *info);
60 void (*ccid_hc_tx_get_info)(struct sock *sk, 58 void (*ccid_hc_tx_get_info)(struct sock *sk,
@@ -94,16 +92,16 @@ extern void ccid_hc_rx_delete(struct ccid *ccid, struct sock *sk);
94extern void ccid_hc_tx_delete(struct ccid *ccid, struct sock *sk); 92extern void ccid_hc_tx_delete(struct ccid *ccid, struct sock *sk);
95 93
96static inline int ccid_hc_tx_send_packet(struct ccid *ccid, struct sock *sk, 94static inline int ccid_hc_tx_send_packet(struct ccid *ccid, struct sock *sk,
97 struct sk_buff *skb, int len) 95 struct sk_buff *skb)
98{ 96{
99 int rc = 0; 97 int rc = 0;
100 if (ccid->ccid_ops->ccid_hc_tx_send_packet != NULL) 98 if (ccid->ccid_ops->ccid_hc_tx_send_packet != NULL)
101 rc = ccid->ccid_ops->ccid_hc_tx_send_packet(sk, skb, len); 99 rc = ccid->ccid_ops->ccid_hc_tx_send_packet(sk, skb);
102 return rc; 100 return rc;
103} 101}
104 102
105static inline void ccid_hc_tx_packet_sent(struct ccid *ccid, struct sock *sk, 103static inline void ccid_hc_tx_packet_sent(struct ccid *ccid, struct sock *sk,
106 int more, int len) 104 int more, unsigned int len)
107{ 105{
108 if (ccid->ccid_ops->ccid_hc_tx_packet_sent != NULL) 106 if (ccid->ccid_ops->ccid_hc_tx_packet_sent != NULL)
109 ccid->ccid_ops->ccid_hc_tx_packet_sent(sk, more, len); 107 ccid->ccid_ops->ccid_hc_tx_packet_sent(sk, more, len);
@@ -146,14 +144,6 @@ static inline int ccid_hc_rx_parse_options(struct ccid *ccid, struct sock *sk,
146 return rc; 144 return rc;
147} 145}
148 146
149static inline int ccid_hc_tx_insert_options(struct ccid *ccid, struct sock *sk,
150 struct sk_buff *skb)
151{
152 if (ccid->ccid_ops->ccid_hc_tx_insert_options != NULL)
153 return ccid->ccid_ops->ccid_hc_tx_insert_options(sk, skb);
154 return 0;
155}
156
157static inline int ccid_hc_rx_insert_options(struct ccid *ccid, struct sock *sk, 147static inline int ccid_hc_rx_insert_options(struct ccid *ccid, struct sock *sk,
158 struct sk_buff *skb) 148 struct sk_buff *skb)
159{ 149{
diff --git a/net/dccp/ccids/Kconfig b/net/dccp/ccids/Kconfig
index 8533dabfb9..80f4698876 100644
--- a/net/dccp/ccids/Kconfig
+++ b/net/dccp/ccids/Kconfig
@@ -28,13 +28,20 @@ config IP_DCCP_CCID2
28 This text was extracted from RFC 4340 (sec. 10.1), 28 This text was extracted from RFC 4340 (sec. 10.1),
29 http://www.ietf.org/rfc/rfc4340.txt 29 http://www.ietf.org/rfc/rfc4340.txt
30 30
31 To compile this CCID as a module, choose M here: the module will be
32 called dccp_ccid2.
33
31 If in doubt, say M. 34 If in doubt, say M.
32 35
33config IP_DCCP_CCID2_DEBUG 36config IP_DCCP_CCID2_DEBUG
34 bool "CCID2 debug" 37 bool "CCID2 debugging messages"
35 depends on IP_DCCP_CCID2 38 depends on IP_DCCP_CCID2
36 ---help--- 39 ---help---
37 Enable CCID2 debug messages. 40 Enable CCID2-specific debugging messages.
41
42 When compiling CCID2 as a module, this debugging output can
43 additionally be toggled by setting the ccid2_debug module
44 parameter to 0 or 1.
38 45
39 If in doubt, say N. 46 If in doubt, say N.
40 47
@@ -62,10 +69,57 @@ config IP_DCCP_CCID3
62 This text was extracted from RFC 4340 (sec. 10.2), 69 This text was extracted from RFC 4340 (sec. 10.2),
63 http://www.ietf.org/rfc/rfc4340.txt 70 http://www.ietf.org/rfc/rfc4340.txt
64 71
72 To compile this CCID as a module, choose M here: the module will be
73 called dccp_ccid3.
74
65 If in doubt, say M. 75 If in doubt, say M.
66 76
67config IP_DCCP_TFRC_LIB 77config IP_DCCP_TFRC_LIB
68 depends on IP_DCCP_CCID3 78 depends on IP_DCCP_CCID3
69 def_tristate IP_DCCP_CCID3 79 def_tristate IP_DCCP_CCID3
70 80
81config IP_DCCP_CCID3_DEBUG
82 bool "CCID3 debugging messages"
83 depends on IP_DCCP_CCID3
84 ---help---
85 Enable CCID3-specific debugging messages.
86
87 When compiling CCID3 as a module, this debugging output can
88 additionally be toggled by setting the ccid3_debug module
89 parameter to 0 or 1.
90
91 If in doubt, say N.
92
93config IP_DCCP_CCID3_RTO
94 int "Use higher bound for nofeedback timer"
95 default 100
96 depends on IP_DCCP_CCID3 && EXPERIMENTAL
97 ---help---
98 Use higher lower bound for nofeedback timer expiration.
99
100 The TFRC nofeedback timer normally expires after the maximum of 4
101 RTTs and twice the current send interval (RFC 3448, 4.3). On LANs
102 with a small RTT this can mean a high processing load and reduced
103 performance, since then the nofeedback timer is triggered very
104 frequently.
105
106 This option enables to set a higher lower bound for the nofeedback
107 value. Values in units of milliseconds can be set here.
108
109 A value of 0 disables this feature by enforcing the value specified
110 in RFC 3448. The following values have been suggested as bounds for
111 experimental use:
112 * 16-20ms to match the typical multimedia inter-frame interval
113 * 100ms as a reasonable compromise [default]
114 * 1000ms corresponds to the lower TCP RTO bound (RFC 2988, 2.4)
115
116 The default of 100ms is a compromise between a large value for
117 efficient DCCP implementations, and a small value to avoid disrupting
118 the network in times of congestion.
119
120 The purpose of the nofeedback timer is to slow DCCP down when there
121 is serious network congestion: experimenting with larger values should
122 therefore not be performed on WANs.
123
124
71endmenu 125endmenu
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c
index 162032baea..fd38b05d6f 100644
--- a/net/dccp/ccids/ccid2.c
+++ b/net/dccp/ccids/ccid2.c
@@ -33,18 +33,11 @@
33#include "../dccp.h" 33#include "../dccp.h"
34#include "ccid2.h" 34#include "ccid2.h"
35 35
36static int ccid2_debug;
37 36
38#ifdef CONFIG_IP_DCCP_CCID2_DEBUG 37#ifdef CONFIG_IP_DCCP_CCID2_DEBUG
39#define ccid2_pr_debug(format, a...) \ 38static int ccid2_debug;
40 do { if (ccid2_debug) \ 39#define ccid2_pr_debug(format, a...) DCCP_PR_DEBUG(ccid2_debug, format, ##a)
41 printk(KERN_DEBUG "%s: " format, __FUNCTION__, ##a); \
42 } while (0)
43#else
44#define ccid2_pr_debug(format, a...)
45#endif
46 40
47#ifdef CONFIG_IP_DCCP_CCID2_DEBUG
48static void ccid2_hc_tx_check_sanity(const struct ccid2_hc_tx_sock *hctx) 41static void ccid2_hc_tx_check_sanity(const struct ccid2_hc_tx_sock *hctx)
49{ 42{
50 int len = 0; 43 int len = 0;
@@ -86,7 +79,8 @@ static void ccid2_hc_tx_check_sanity(const struct ccid2_hc_tx_sock *hctx)
86 BUG_ON(len != hctx->ccid2hctx_seqbufc * CCID2_SEQBUF_LEN); 79 BUG_ON(len != hctx->ccid2hctx_seqbufc * CCID2_SEQBUF_LEN);
87} 80}
88#else 81#else
89#define ccid2_hc_tx_check_sanity(hctx) do {} while (0) 82#define ccid2_pr_debug(format, a...)
83#define ccid2_hc_tx_check_sanity(hctx)
90#endif 84#endif
91 85
92static int ccid2_hc_tx_alloc_seq(struct ccid2_hc_tx_sock *hctx, int num, 86static int ccid2_hc_tx_alloc_seq(struct ccid2_hc_tx_sock *hctx, int num,
@@ -131,8 +125,7 @@ static int ccid2_hc_tx_alloc_seq(struct ccid2_hc_tx_sock *hctx, int num,
131 return 0; 125 return 0;
132} 126}
133 127
134static int ccid2_hc_tx_send_packet(struct sock *sk, 128static int ccid2_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
135 struct sk_buff *skb, int len)
136{ 129{
137 struct ccid2_hc_tx_sock *hctx; 130 struct ccid2_hc_tx_sock *hctx;
138 131
@@ -274,7 +267,7 @@ static void ccid2_start_rto_timer(struct sock *sk)
274 jiffies + hctx->ccid2hctx_rto); 267 jiffies + hctx->ccid2hctx_rto);
275} 268}
276 269
277static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, int len) 270static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len)
278{ 271{
279 struct dccp_sock *dp = dccp_sk(sk); 272 struct dccp_sock *dp = dccp_sk(sk);
280 struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk); 273 struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
@@ -358,7 +351,7 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, int len)
358 351
359 while (seqp != hctx->ccid2hctx_seqh) { 352 while (seqp != hctx->ccid2hctx_seqh) {
360 ccid2_pr_debug("out seq=%llu acked=%d time=%lu\n", 353 ccid2_pr_debug("out seq=%llu acked=%d time=%lu\n",
361 (unsigned long long)seqp->ccid2s_seq, 354 (unsigned long long)seqp->ccid2s_seq,
362 seqp->ccid2s_acked, seqp->ccid2s_sent); 355 seqp->ccid2s_acked, seqp->ccid2s_sent);
363 seqp = seqp->ccid2s_next; 356 seqp = seqp->ccid2s_next;
364 } 357 }
@@ -426,7 +419,7 @@ static int ccid2_ackvector(struct sock *sk, struct sk_buff *skb, int offset,
426 return -1; 419 return -1;
427 420
428out_invalid_option: 421out_invalid_option:
429 BUG_ON(1); /* should never happen... options were previously parsed ! */ 422 DCCP_BUG("Invalid option - this should not happen (previous parsing)!");
430 return -1; 423 return -1;
431} 424}
432 425
@@ -480,7 +473,7 @@ static inline void ccid2_new_ack(struct sock *sk,
480 /* first measurement */ 473 /* first measurement */
481 if (hctx->ccid2hctx_srtt == -1) { 474 if (hctx->ccid2hctx_srtt == -1) {
482 ccid2_pr_debug("R: %lu Time=%lu seq=%llu\n", 475 ccid2_pr_debug("R: %lu Time=%lu seq=%llu\n",
483 r, jiffies, 476 r, jiffies,
484 (unsigned long long)seqp->ccid2s_seq); 477 (unsigned long long)seqp->ccid2s_seq);
485 ccid2_change_srtt(hctx, r); 478 ccid2_change_srtt(hctx, r);
486 hctx->ccid2hctx_rttvar = r >> 1; 479 hctx->ccid2hctx_rttvar = r >> 1;
@@ -525,8 +518,8 @@ static inline void ccid2_new_ack(struct sock *sk,
525 hctx->ccid2hctx_lastrtt = jiffies; 518 hctx->ccid2hctx_lastrtt = jiffies;
526 519
527 ccid2_pr_debug("srtt: %ld rttvar: %ld rto: %ld (HZ=%d) R=%lu\n", 520 ccid2_pr_debug("srtt: %ld rttvar: %ld rto: %ld (HZ=%d) R=%lu\n",
528 hctx->ccid2hctx_srtt, hctx->ccid2hctx_rttvar, 521 hctx->ccid2hctx_srtt, hctx->ccid2hctx_rttvar,
529 hctx->ccid2hctx_rto, HZ, r); 522 hctx->ccid2hctx_rto, HZ, r);
530 hctx->ccid2hctx_sent = 0; 523 hctx->ccid2hctx_sent = 0;
531 } 524 }
532 525
@@ -619,7 +612,17 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
619 } 612 }
620 613
621 ackno = DCCP_SKB_CB(skb)->dccpd_ack_seq; 614 ackno = DCCP_SKB_CB(skb)->dccpd_ack_seq;
622 seqp = hctx->ccid2hctx_seqh->ccid2s_prev; 615 if (after48(ackno, hctx->ccid2hctx_high_ack))
616 hctx->ccid2hctx_high_ack = ackno;
617
618 seqp = hctx->ccid2hctx_seqt;
619 while (before48(seqp->ccid2s_seq, ackno)) {
620 seqp = seqp->ccid2s_next;
621 if (seqp == hctx->ccid2hctx_seqh) {
622 seqp = hctx->ccid2hctx_seqh->ccid2s_prev;
623 break;
624 }
625 }
623 626
624 /* If in slow-start, cwnd can increase at most Ack Ratio / 2 packets for 627 /* If in slow-start, cwnd can increase at most Ack Ratio / 2 packets for
625 * this single ack. I round up. 628 * this single ack. I round up.
@@ -664,9 +667,9 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
664 /* new packet received or marked */ 667 /* new packet received or marked */
665 if (state != DCCP_ACKVEC_STATE_NOT_RECEIVED && 668 if (state != DCCP_ACKVEC_STATE_NOT_RECEIVED &&
666 !seqp->ccid2s_acked) { 669 !seqp->ccid2s_acked) {
667 if (state == 670 if (state ==
668 DCCP_ACKVEC_STATE_ECN_MARKED) { 671 DCCP_ACKVEC_STATE_ECN_MARKED) {
669 ccid2_congestion_event(hctx, 672 ccid2_congestion_event(hctx,
670 seqp); 673 seqp);
671 } else 674 } else
672 ccid2_new_ack(sk, seqp, 675 ccid2_new_ack(sk, seqp,
@@ -697,7 +700,14 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
697 /* The state about what is acked should be correct now 700 /* The state about what is acked should be correct now
698 * Check for NUMDUPACK 701 * Check for NUMDUPACK
699 */ 702 */
700 seqp = hctx->ccid2hctx_seqh->ccid2s_prev; 703 seqp = hctx->ccid2hctx_seqt;
704 while (before48(seqp->ccid2s_seq, hctx->ccid2hctx_high_ack)) {
705 seqp = seqp->ccid2s_next;
706 if (seqp == hctx->ccid2hctx_seqh) {
707 seqp = hctx->ccid2hctx_seqh->ccid2s_prev;
708 break;
709 }
710 }
701 done = 0; 711 done = 0;
702 while (1) { 712 while (1) {
703 if (seqp->ccid2s_acked) { 713 if (seqp->ccid2s_acked) {
@@ -771,6 +781,7 @@ static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk)
771 hctx->ccid2hctx_lastrtt = 0; 781 hctx->ccid2hctx_lastrtt = 0;
772 hctx->ccid2hctx_rpdupack = -1; 782 hctx->ccid2hctx_rpdupack = -1;
773 hctx->ccid2hctx_last_cong = jiffies; 783 hctx->ccid2hctx_last_cong = jiffies;
784 hctx->ccid2hctx_high_ack = 0;
774 785
775 hctx->ccid2hctx_rtotimer.function = &ccid2_hc_tx_rto_expire; 786 hctx->ccid2hctx_rtotimer.function = &ccid2_hc_tx_rto_expire;
776 hctx->ccid2hctx_rtotimer.data = (unsigned long)sk; 787 hctx->ccid2hctx_rtotimer.data = (unsigned long)sk;
@@ -823,8 +834,10 @@ static struct ccid_operations ccid2 = {
823 .ccid_hc_rx_packet_recv = ccid2_hc_rx_packet_recv, 834 .ccid_hc_rx_packet_recv = ccid2_hc_rx_packet_recv,
824}; 835};
825 836
837#ifdef CONFIG_IP_DCCP_CCID2_DEBUG
826module_param(ccid2_debug, int, 0444); 838module_param(ccid2_debug, int, 0444);
827MODULE_PARM_DESC(ccid2_debug, "Enable debug messages"); 839MODULE_PARM_DESC(ccid2_debug, "Enable debug messages");
840#endif
828 841
829static __init int ccid2_module_init(void) 842static __init int ccid2_module_init(void)
830{ 843{
diff --git a/net/dccp/ccids/ccid2.h b/net/dccp/ccids/ccid2.h
index 5b2ef4acb3..ebd79499c8 100644
--- a/net/dccp/ccids/ccid2.h
+++ b/net/dccp/ccids/ccid2.h
@@ -35,7 +35,7 @@ struct ccid2_seq {
35 struct ccid2_seq *ccid2s_next; 35 struct ccid2_seq *ccid2s_next;
36}; 36};
37 37
38#define CCID2_SEQBUF_LEN 256 38#define CCID2_SEQBUF_LEN 1024
39#define CCID2_SEQBUF_MAX 128 39#define CCID2_SEQBUF_MAX 128
40 40
41/** struct ccid2_hc_tx_sock - CCID2 TX half connection 41/** struct ccid2_hc_tx_sock - CCID2 TX half connection
@@ -72,6 +72,7 @@ struct ccid2_hc_tx_sock {
72 int ccid2hctx_rpdupack; 72 int ccid2hctx_rpdupack;
73 int ccid2hctx_sendwait; 73 int ccid2hctx_sendwait;
74 unsigned long ccid2hctx_last_cong; 74 unsigned long ccid2hctx_last_cong;
75 u64 ccid2hctx_high_ack;
75}; 76};
76 77
77struct ccid2_hc_rx_sock { 78struct ccid2_hc_rx_sock {
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index cec23ad286..40402c5950 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -41,32 +41,9 @@
41#include "lib/tfrc.h" 41#include "lib/tfrc.h"
42#include "ccid3.h" 42#include "ccid3.h"
43 43
44/* 44#ifdef CONFIG_IP_DCCP_CCID3_DEBUG
45 * Reason for maths here is to avoid 32 bit overflow when a is big.
46 * With this we get close to the limit.
47 */
48static u32 usecs_div(const u32 a, const u32 b)
49{
50 const u32 div = a < (UINT_MAX / (USEC_PER_SEC / 10)) ? 10 :
51 a < (UINT_MAX / (USEC_PER_SEC / 50)) ? 50 :
52 a < (UINT_MAX / (USEC_PER_SEC / 100)) ? 100 :
53 a < (UINT_MAX / (USEC_PER_SEC / 500)) ? 500 :
54 a < (UINT_MAX / (USEC_PER_SEC / 1000)) ? 1000 :
55 a < (UINT_MAX / (USEC_PER_SEC / 5000)) ? 5000 :
56 a < (UINT_MAX / (USEC_PER_SEC / 10000)) ? 10000 :
57 a < (UINT_MAX / (USEC_PER_SEC / 50000)) ? 50000 :
58 100000;
59 const u32 tmp = a * (USEC_PER_SEC / div);
60 return (b >= 2 * div) ? tmp / (b / div) : tmp;
61}
62
63static int ccid3_debug; 45static int ccid3_debug;
64 46#define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a)
65#ifdef CCID3_DEBUG
66#define ccid3_pr_debug(format, a...) \
67 do { if (ccid3_debug) \
68 printk(KERN_DEBUG "%s: " format, __FUNCTION__, ##a); \
69 } while (0)
70#else 47#else
71#define ccid3_pr_debug(format, a...) 48#define ccid3_pr_debug(format, a...)
72#endif 49#endif
@@ -75,15 +52,7 @@ static struct dccp_tx_hist *ccid3_tx_hist;
75static struct dccp_rx_hist *ccid3_rx_hist; 52static struct dccp_rx_hist *ccid3_rx_hist;
76static struct dccp_li_hist *ccid3_li_hist; 53static struct dccp_li_hist *ccid3_li_hist;
77 54
78/* TFRC sender states */ 55#ifdef CONFIG_IP_DCCP_CCID3_DEBUG
79enum ccid3_hc_tx_states {
80 TFRC_SSTATE_NO_SENT = 1,
81 TFRC_SSTATE_NO_FBACK,
82 TFRC_SSTATE_FBACK,
83 TFRC_SSTATE_TERM,
84};
85
86#ifdef CCID3_DEBUG
87static const char *ccid3_tx_state_name(enum ccid3_hc_tx_states state) 56static const char *ccid3_tx_state_name(enum ccid3_hc_tx_states state)
88{ 57{
89 static char *ccid3_state_names[] = { 58 static char *ccid3_state_names[] = {
@@ -110,324 +79,319 @@ static void ccid3_hc_tx_set_state(struct sock *sk,
110 hctx->ccid3hctx_state = state; 79 hctx->ccid3hctx_state = state;
111} 80}
112 81
113/* Calculate new t_ipi (inter packet interval) by t_ipi = s / X_inst */ 82/*
114static inline void ccid3_calc_new_t_ipi(struct ccid3_hc_tx_sock *hctx) 83 * Recalculate scheduled nominal send time t_nom, inter-packet interval
84 * t_ipi, and delta value. Should be called after each change to X.
85 */
86static inline void ccid3_update_send_time(struct ccid3_hc_tx_sock *hctx)
115{ 87{
116 /* 88 timeval_sub_usecs(&hctx->ccid3hctx_t_nom, hctx->ccid3hctx_t_ipi);
117 * If no feedback spec says t_ipi is 1 second (set elsewhere and then
118 * doubles after every no feedback timer (separate function)
119 */
120 if (hctx->ccid3hctx_state != TFRC_SSTATE_NO_FBACK)
121 hctx->ccid3hctx_t_ipi = usecs_div(hctx->ccid3hctx_s,
122 hctx->ccid3hctx_x);
123}
124 89
125/* Calculate new delta by delta = min(t_ipi / 2, t_gran / 2) */ 90 /* Calculate new t_ipi = s / X_inst (X_inst is in 64 * bytes/second) */
126static inline void ccid3_calc_new_delta(struct ccid3_hc_tx_sock *hctx) 91 hctx->ccid3hctx_t_ipi = scaled_div(hctx->ccid3hctx_s,
127{ 92 hctx->ccid3hctx_x >> 6);
93
94 /* Update nominal send time with regard to the new t_ipi */
95 timeval_add_usecs(&hctx->ccid3hctx_t_nom, hctx->ccid3hctx_t_ipi);
96
97 /* Calculate new delta by delta = min(t_ipi / 2, t_gran / 2) */
128 hctx->ccid3hctx_delta = min_t(u32, hctx->ccid3hctx_t_ipi / 2, 98 hctx->ccid3hctx_delta = min_t(u32, hctx->ccid3hctx_t_ipi / 2,
129 TFRC_OPSYS_HALF_TIME_GRAN); 99 TFRC_OPSYS_HALF_TIME_GRAN);
130} 100}
131
132/* 101/*
133 * Update X by 102 * Update X by
134 * If (p > 0) 103 * If (p > 0)
135 * x_calc = calcX(s, R, p); 104 * X_calc = calcX(s, R, p);
136 * X = max(min(X_calc, 2 * X_recv), s / t_mbi); 105 * X = max(min(X_calc, 2 * X_recv), s / t_mbi);
137 * Else 106 * Else
138 * If (now - tld >= R) 107 * If (now - tld >= R)
139 * X = max(min(2 * X, 2 * X_recv), s / R); 108 * X = max(min(2 * X, 2 * X_recv), s / R);
140 * tld = now; 109 * tld = now;
141 */ 110 *
142static void ccid3_hc_tx_update_x(struct sock *sk) 111 * Note: X and X_recv are both stored in units of 64 * bytes/second, to support
112 * fine-grained resolution of sending rates. This requires scaling by 2^6
113 * throughout the code. Only X_calc is unscaled (in bytes/second).
114 *
115 * If X has changed, we also update the scheduled send time t_now,
116 * the inter-packet interval t_ipi, and the delta value.
117 */
118static void ccid3_hc_tx_update_x(struct sock *sk, struct timeval *now)
119
143{ 120{
144 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 121 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
122 const __u64 old_x = hctx->ccid3hctx_x;
145 123
146 /* To avoid large error in calcX */ 124 if (hctx->ccid3hctx_p > 0) {
147 if (hctx->ccid3hctx_p >= TFRC_SMALLEST_P) {
148 hctx->ccid3hctx_x_calc = tfrc_calc_x(hctx->ccid3hctx_s,
149 hctx->ccid3hctx_rtt,
150 hctx->ccid3hctx_p);
151 hctx->ccid3hctx_x = max_t(u32, min_t(u32, hctx->ccid3hctx_x_calc,
152 2 * hctx->ccid3hctx_x_recv),
153 (hctx->ccid3hctx_s /
154 TFRC_MAX_BACK_OFF_TIME));
155 } else {
156 struct timeval now;
157 125
158 dccp_timestamp(sk, &now); 126 hctx->ccid3hctx_x = min(((__u64)hctx->ccid3hctx_x_calc) << 6,
159 if (timeval_delta(&now, &hctx->ccid3hctx_t_ld) >= 127 hctx->ccid3hctx_x_recv * 2);
160 hctx->ccid3hctx_rtt) { 128 hctx->ccid3hctx_x = max(hctx->ccid3hctx_x,
161 hctx->ccid3hctx_x = max_t(u32, min_t(u32, hctx->ccid3hctx_x_recv, 129 (((__u64)hctx->ccid3hctx_s) << 6) /
162 hctx->ccid3hctx_x) * 2, 130 TFRC_T_MBI);
163 usecs_div(hctx->ccid3hctx_s, 131
164 hctx->ccid3hctx_rtt)); 132 } else if (timeval_delta(now, &hctx->ccid3hctx_t_ld) -
165 hctx->ccid3hctx_t_ld = now; 133 (suseconds_t)hctx->ccid3hctx_rtt >= 0) {
166 } 134
135 hctx->ccid3hctx_x =
136 max(2 * min(hctx->ccid3hctx_x, hctx->ccid3hctx_x_recv),
137 scaled_div(((__u64)hctx->ccid3hctx_s) << 6,
138 hctx->ccid3hctx_rtt));
139 hctx->ccid3hctx_t_ld = *now;
140 }
141
142 if (hctx->ccid3hctx_x != old_x)
143 ccid3_update_send_time(hctx);
144}
145
146/*
147 * Track the mean packet size `s' (cf. RFC 4342, 5.3 and RFC 3448, 4.1)
148 * @len: DCCP packet payload size in bytes
149 */
150static inline void ccid3_hc_tx_update_s(struct ccid3_hc_tx_sock *hctx, int len)
151{
152 if (unlikely(len == 0))
153 ccid3_pr_debug("Packet payload length is 0 - not updating\n");
154 else
155 hctx->ccid3hctx_s = hctx->ccid3hctx_s == 0 ? len :
156 (9 * hctx->ccid3hctx_s + len) / 10;
157 /*
158 * Note: We could do a potential optimisation here - when `s' changes,
159 * recalculate sending rate and consequently t_ipi, t_delta, and
160 * t_now. This is however non-standard, and the benefits are not
161 * clear, so it is currently left out.
162 */
163}
164
165/*
166 * Update Window Counter using the algorithm from [RFC 4342, 8.1].
167 * The algorithm is not applicable if RTT < 4 microseconds.
168 */
169static inline void ccid3_hc_tx_update_win_count(struct ccid3_hc_tx_sock *hctx,
170 struct timeval *now)
171{
172 suseconds_t delta;
173 u32 quarter_rtts;
174
175 if (unlikely(hctx->ccid3hctx_rtt < 4)) /* avoid divide-by-zero */
176 return;
177
178 delta = timeval_delta(now, &hctx->ccid3hctx_t_last_win_count);
179 DCCP_BUG_ON(delta < 0);
180
181 quarter_rtts = (u32)delta / (hctx->ccid3hctx_rtt / 4);
182
183 if (quarter_rtts > 0) {
184 hctx->ccid3hctx_t_last_win_count = *now;
185 hctx->ccid3hctx_last_win_count += min_t(u32, quarter_rtts, 5);
186 hctx->ccid3hctx_last_win_count &= 0xF; /* mod 16 */
187
188 ccid3_pr_debug("now at %#X\n", hctx->ccid3hctx_last_win_count);
167 } 189 }
168} 190}
169 191
170static void ccid3_hc_tx_no_feedback_timer(unsigned long data) 192static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
171{ 193{
172 struct sock *sk = (struct sock *)data; 194 struct sock *sk = (struct sock *)data;
173 unsigned long next_tmout = 0;
174 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 195 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
196 unsigned long t_nfb = USEC_PER_SEC / 5;
175 197
176 bh_lock_sock(sk); 198 bh_lock_sock(sk);
177 if (sock_owned_by_user(sk)) { 199 if (sock_owned_by_user(sk)) {
178 /* Try again later. */ 200 /* Try again later. */
179 /* XXX: set some sensible MIB */ 201 /* XXX: set some sensible MIB */
180 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, 202 goto restart_timer;
181 jiffies + HZ / 5);
182 goto out;
183 } 203 }
184 204
185 ccid3_pr_debug("%s, sk=%p, state=%s\n", dccp_role(sk), sk, 205 ccid3_pr_debug("%s(%p, state=%s) - entry \n", dccp_role(sk), sk,
186 ccid3_tx_state_name(hctx->ccid3hctx_state)); 206 ccid3_tx_state_name(hctx->ccid3hctx_state));
187 207
188 switch (hctx->ccid3hctx_state) { 208 switch (hctx->ccid3hctx_state) {
189 case TFRC_SSTATE_TERM:
190 goto out;
191 case TFRC_SSTATE_NO_FBACK: 209 case TFRC_SSTATE_NO_FBACK:
192 /* Halve send rate */ 210 /* RFC 3448, 4.4: Halve send rate directly */
193 hctx->ccid3hctx_x /= 2; 211 hctx->ccid3hctx_x = max(hctx->ccid3hctx_x / 2,
194 if (hctx->ccid3hctx_x < (hctx->ccid3hctx_s / 212 (((__u64)hctx->ccid3hctx_s) << 6) /
195 TFRC_MAX_BACK_OFF_TIME)) 213 TFRC_T_MBI);
196 hctx->ccid3hctx_x = (hctx->ccid3hctx_s / 214
197 TFRC_MAX_BACK_OFF_TIME); 215 ccid3_pr_debug("%s(%p, state=%s), updated tx rate to %u "
198 216 "bytes/s\n", dccp_role(sk), sk,
199 ccid3_pr_debug("%s, sk=%p, state=%s, updated tx rate to %d "
200 "bytes/s\n",
201 dccp_role(sk), sk,
202 ccid3_tx_state_name(hctx->ccid3hctx_state), 217 ccid3_tx_state_name(hctx->ccid3hctx_state),
203 hctx->ccid3hctx_x); 218 (unsigned)(hctx->ccid3hctx_x >> 6));
204 next_tmout = max_t(u32, 2 * usecs_div(hctx->ccid3hctx_s, 219 /* The value of R is still undefined and so we can not recompute
205 hctx->ccid3hctx_x), 220 * the timout value. Keep initial value as per [RFC 4342, 5]. */
206 TFRC_INITIAL_TIMEOUT); 221 t_nfb = TFRC_INITIAL_TIMEOUT;
207 /* 222 ccid3_update_send_time(hctx);
208 * FIXME - not sure above calculation is correct. See section
209 * 5 of CCID3 11 should adjust tx_t_ipi and double that to
210 * achieve it really
211 */
212 break; 223 break;
213 case TFRC_SSTATE_FBACK: 224 case TFRC_SSTATE_FBACK:
214 /* 225 /*
215 * Check if IDLE since last timeout and recv rate is less than 226 * Check if IDLE since last timeout and recv rate is less than
216 * 4 packets per RTT 227 * 4 packets (in units of 64*bytes/sec) per RTT
217 */ 228 */
218 if (!hctx->ccid3hctx_idle || 229 if (!hctx->ccid3hctx_idle ||
219 (hctx->ccid3hctx_x_recv >= 230 (hctx->ccid3hctx_x_recv >= 4 *
220 4 * usecs_div(hctx->ccid3hctx_s, hctx->ccid3hctx_rtt))) { 231 scaled_div(((__u64)hctx->ccid3hctx_s) << 6,
221 ccid3_pr_debug("%s, sk=%p, state=%s, not idle\n", 232 hctx->ccid3hctx_rtt))) {
233 struct timeval now;
234
235 ccid3_pr_debug("%s(%p, state=%s), not idle\n",
222 dccp_role(sk), sk, 236 dccp_role(sk), sk,
223 ccid3_tx_state_name(hctx->ccid3hctx_state)); 237 ccid3_tx_state_name(hctx->ccid3hctx_state));
224 /* Halve sending rate */
225 238
226 /* If (X_calc > 2 * X_recv) 239 /*
240 * Modify the cached value of X_recv [RFC 3448, 4.4]
241 *
242 * If (p == 0 || X_calc > 2 * X_recv)
227 * X_recv = max(X_recv / 2, s / (2 * t_mbi)); 243 * X_recv = max(X_recv / 2, s / (2 * t_mbi));
228 * Else 244 * Else
229 * X_recv = X_calc / 4; 245 * X_recv = X_calc / 4;
246 *
247 * Note that X_recv is scaled by 2^6 while X_calc is not
230 */ 248 */
231 BUG_ON(hctx->ccid3hctx_p >= TFRC_SMALLEST_P && 249 BUG_ON(hctx->ccid3hctx_p && !hctx->ccid3hctx_x_calc);
232 hctx->ccid3hctx_x_calc == 0); 250
233 251 if (hctx->ccid3hctx_p == 0 ||
234 /* check also if p is zero -> x_calc is infinity? */ 252 (hctx->ccid3hctx_x_calc >
235 if (hctx->ccid3hctx_p < TFRC_SMALLEST_P || 253 (hctx->ccid3hctx_x_recv >> 5))) {
236 hctx->ccid3hctx_x_calc > 2 * hctx->ccid3hctx_x_recv) 254
237 hctx->ccid3hctx_x_recv = max_t(u32, hctx->ccid3hctx_x_recv / 2, 255 hctx->ccid3hctx_x_recv =
238 hctx->ccid3hctx_s / (2 * TFRC_MAX_BACK_OFF_TIME)); 256 max(hctx->ccid3hctx_x_recv / 2,
239 else 257 (((__u64)hctx->ccid3hctx_s) << 6) /
240 hctx->ccid3hctx_x_recv = hctx->ccid3hctx_x_calc / 4; 258 (2 * TFRC_T_MBI));
241 259
242 /* Update sending rate */ 260 if (hctx->ccid3hctx_p == 0)
243 ccid3_hc_tx_update_x(sk); 261 dccp_timestamp(sk, &now);
262 } else {
263 hctx->ccid3hctx_x_recv = hctx->ccid3hctx_x_calc;
264 hctx->ccid3hctx_x_recv <<= 4;
265 }
266 /* Now recalculate X [RFC 3448, 4.3, step (4)] */
267 ccid3_hc_tx_update_x(sk, &now);
244 } 268 }
245 /* 269 /*
246 * Schedule no feedback timer to expire in 270 * Schedule no feedback timer to expire in
247 * max(4 * R, 2 * s / X) 271 * max(t_RTO, 2 * s/X) = max(t_RTO, 2 * t_ipi)
272 * See comments in packet_recv() regarding the value of t_RTO.
248 */ 273 */
249 next_tmout = max_t(u32, hctx->ccid3hctx_t_rto, 274 t_nfb = max(hctx->ccid3hctx_t_rto, 2 * hctx->ccid3hctx_t_ipi);
250 2 * usecs_div(hctx->ccid3hctx_s,
251 hctx->ccid3hctx_x));
252 break; 275 break;
253 default: 276 case TFRC_SSTATE_NO_SENT:
254 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n", 277 DCCP_BUG("%s(%p) - Illegal state NO_SENT", dccp_role(sk), sk);
255 __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state); 278 /* fall through */
256 dump_stack(); 279 case TFRC_SSTATE_TERM:
257 goto out; 280 goto out;
258 } 281 }
259 282
260 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
261 jiffies + max_t(u32, 1, usecs_to_jiffies(next_tmout)));
262 hctx->ccid3hctx_idle = 1; 283 hctx->ccid3hctx_idle = 1;
284
285restart_timer:
286 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
287 jiffies + usecs_to_jiffies(t_nfb));
263out: 288out:
264 bh_unlock_sock(sk); 289 bh_unlock_sock(sk);
265 sock_put(sk); 290 sock_put(sk);
266} 291}
267 292
268static int ccid3_hc_tx_send_packet(struct sock *sk, 293/*
269 struct sk_buff *skb, int len) 294 * returns
295 * > 0: delay (in msecs) that should pass before actually sending
296 * = 0: can send immediately
297 * < 0: error condition; do not send packet
298 */
299static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
270{ 300{
271 struct dccp_sock *dp = dccp_sk(sk); 301 struct dccp_sock *dp = dccp_sk(sk);
272 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 302 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
273 struct dccp_tx_hist_entry *new_packet;
274 struct timeval now; 303 struct timeval now;
275 long delay; 304 suseconds_t delay;
276 int rc = -ENOTCONN;
277 305
278 BUG_ON(hctx == NULL || hctx->ccid3hctx_state == TFRC_SSTATE_TERM); 306 BUG_ON(hctx == NULL);
279 307
280 /* Check if pure ACK or Terminating*/
281 /* 308 /*
282 * XXX: We only call this function for DATA and DATAACK, on, these 309 * This function is called only for Data and DataAck packets. Sending
283 * packets can have zero length, but why the comment about "pure ACK"? 310 * zero-sized Data(Ack)s is theoretically possible, but for congestion
311 * control this case is pathological - ignore it.
284 */ 312 */
285 if (unlikely(len == 0)) 313 if (unlikely(skb->len == 0))
286 goto out; 314 return -EBADMSG;
287
288 /* See if last packet allocated was not sent */
289 new_packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist);
290 if (new_packet == NULL || new_packet->dccphtx_sent) {
291 new_packet = dccp_tx_hist_entry_new(ccid3_tx_hist,
292 SLAB_ATOMIC);
293
294 rc = -ENOBUFS;
295 if (unlikely(new_packet == NULL)) {
296 LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, not enough "
297 "mem to add to history, send refused\n",
298 __FUNCTION__, dccp_role(sk), sk);
299 goto out;
300 }
301
302 dccp_tx_hist_add_entry(&hctx->ccid3hctx_hist, new_packet);
303 }
304 315
305 dccp_timestamp(sk, &now); 316 dccp_timestamp(sk, &now);
306 317
307 switch (hctx->ccid3hctx_state) { 318 switch (hctx->ccid3hctx_state) {
308 case TFRC_SSTATE_NO_SENT: 319 case TFRC_SSTATE_NO_SENT:
309 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, 320 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
310 jiffies + usecs_to_jiffies(TFRC_INITIAL_TIMEOUT)); 321 (jiffies +
322 usecs_to_jiffies(TFRC_INITIAL_TIMEOUT)));
311 hctx->ccid3hctx_last_win_count = 0; 323 hctx->ccid3hctx_last_win_count = 0;
312 hctx->ccid3hctx_t_last_win_count = now; 324 hctx->ccid3hctx_t_last_win_count = now;
313 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK); 325 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK);
314 hctx->ccid3hctx_t_ipi = TFRC_INITIAL_IPI;
315 326
316 /* Set nominal send time for initial packet */ 327 /* Set initial sending rate X/s to 1pps (X is scaled by 2^6) */
328 ccid3_hc_tx_update_s(hctx, skb->len);
329 hctx->ccid3hctx_x = hctx->ccid3hctx_s;
330 hctx->ccid3hctx_x <<= 6;
331
332 /* First timeout, according to [RFC 3448, 4.2], is 1 second */
333 hctx->ccid3hctx_t_ipi = USEC_PER_SEC;
334 /* Initial delta: minimum of 0.5 sec and t_gran/2 */
335 hctx->ccid3hctx_delta = TFRC_OPSYS_HALF_TIME_GRAN;
336
337 /* Set t_0 for initial packet */
317 hctx->ccid3hctx_t_nom = now; 338 hctx->ccid3hctx_t_nom = now;
318 timeval_add_usecs(&hctx->ccid3hctx_t_nom,
319 hctx->ccid3hctx_t_ipi);
320 ccid3_calc_new_delta(hctx);
321 rc = 0;
322 break; 339 break;
323 case TFRC_SSTATE_NO_FBACK: 340 case TFRC_SSTATE_NO_FBACK:
324 case TFRC_SSTATE_FBACK: 341 case TFRC_SSTATE_FBACK:
325 delay = (timeval_delta(&now, &hctx->ccid3hctx_t_nom) - 342 delay = timeval_delta(&hctx->ccid3hctx_t_nom, &now);
326 hctx->ccid3hctx_delta); 343 /*
327 delay /= -1000; 344 * Scheduling of packet transmissions [RFC 3448, 4.6]
328 /* divide by -1000 is to convert to ms and get sign right */ 345 *
329 rc = delay > 0 ? delay : 0; 346 * if (t_now > t_nom - delta)
330 break; 347 * // send the packet now
331 default: 348 * else
332 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n", 349 * // send the packet in (t_nom - t_now) milliseconds.
333 __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state); 350 */
334 dump_stack(); 351 if (delay - (suseconds_t)hctx->ccid3hctx_delta >= 0)
335 rc = -EINVAL; 352 return delay / 1000L;
353
354 ccid3_hc_tx_update_win_count(hctx, &now);
336 break; 355 break;
356 case TFRC_SSTATE_TERM:
357 DCCP_BUG("%s(%p) - Illegal state TERM", dccp_role(sk), sk);
358 return -EINVAL;
337 } 359 }
338 360
339 /* Can we send? if so add options and add to packet history */ 361 /* prepare to send now (add options etc.) */
340 if (rc == 0) { 362 dp->dccps_hc_tx_insert_options = 1;
341 dp->dccps_hc_tx_insert_options = 1; 363 DCCP_SKB_CB(skb)->dccpd_ccval = hctx->ccid3hctx_last_win_count;
342 new_packet->dccphtx_ccval = 364
343 DCCP_SKB_CB(skb)->dccpd_ccval = 365 /* set the nominal send time for the next following packet */
344 hctx->ccid3hctx_last_win_count; 366 timeval_add_usecs(&hctx->ccid3hctx_t_nom, hctx->ccid3hctx_t_ipi);
345 timeval_add_usecs(&hctx->ccid3hctx_t_nom, 367
346 hctx->ccid3hctx_t_ipi); 368 return 0;
347 }
348out:
349 return rc;
350} 369}
351 370
352static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len) 371static void ccid3_hc_tx_packet_sent(struct sock *sk, int more,
372 unsigned int len)
353{ 373{
354 const struct dccp_sock *dp = dccp_sk(sk);
355 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 374 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
356 struct timeval now; 375 struct timeval now;
376 struct dccp_tx_hist_entry *packet;
357 377
358 BUG_ON(hctx == NULL || hctx->ccid3hctx_state == TFRC_SSTATE_TERM); 378 BUG_ON(hctx == NULL);
359
360 dccp_timestamp(sk, &now);
361
362 /* check if we have sent a data packet */
363 if (len > 0) {
364 unsigned long quarter_rtt;
365 struct dccp_tx_hist_entry *packet;
366
367 packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist);
368 if (unlikely(packet == NULL)) {
369 LIMIT_NETDEBUG(KERN_WARNING "%s: packet doesn't "
370 "exists in history!\n", __FUNCTION__);
371 return;
372 }
373 if (unlikely(packet->dccphtx_sent)) {
374 LIMIT_NETDEBUG(KERN_WARNING "%s: no unsent packet in "
375 "history!\n", __FUNCTION__);
376 return;
377 }
378 packet->dccphtx_tstamp = now;
379 packet->dccphtx_seqno = dp->dccps_gss;
380 /*
381 * Check if win_count have changed
382 * Algorithm in "8.1. Window Counter Value" in RFC 4342.
383 */
384 quarter_rtt = timeval_delta(&now, &hctx->ccid3hctx_t_last_win_count);
385 if (likely(hctx->ccid3hctx_rtt > 8))
386 quarter_rtt /= hctx->ccid3hctx_rtt / 4;
387
388 if (quarter_rtt > 0) {
389 hctx->ccid3hctx_t_last_win_count = now;
390 hctx->ccid3hctx_last_win_count = (hctx->ccid3hctx_last_win_count +
391 min_t(unsigned long, quarter_rtt, 5)) % 16;
392 ccid3_pr_debug("%s, sk=%p, window changed from "
393 "%u to %u!\n",
394 dccp_role(sk), sk,
395 packet->dccphtx_ccval,
396 hctx->ccid3hctx_last_win_count);
397 }
398 379
399 hctx->ccid3hctx_idle = 0; 380 ccid3_hc_tx_update_s(hctx, len);
400 packet->dccphtx_rtt = hctx->ccid3hctx_rtt;
401 packet->dccphtx_sent = 1;
402 } else
403 ccid3_pr_debug("%s, sk=%p, seqno=%llu NOT inserted!\n",
404 dccp_role(sk), sk, dp->dccps_gss);
405 381
406 switch (hctx->ccid3hctx_state) { 382 packet = dccp_tx_hist_entry_new(ccid3_tx_hist, GFP_ATOMIC);
407 case TFRC_SSTATE_NO_SENT: 383 if (unlikely(packet == NULL)) {
408 /* if first wasn't pure ack */ 384 DCCP_CRIT("packet history - out of memory!");
409 if (len != 0)
410 printk(KERN_CRIT "%s: %s, First packet sent is noted "
411 "as a data packet\n",
412 __FUNCTION__, dccp_role(sk));
413 return; 385 return;
414 case TFRC_SSTATE_NO_FBACK:
415 case TFRC_SSTATE_FBACK:
416 if (len > 0) {
417 timeval_sub_usecs(&hctx->ccid3hctx_t_nom,
418 hctx->ccid3hctx_t_ipi);
419 ccid3_calc_new_t_ipi(hctx);
420 ccid3_calc_new_delta(hctx);
421 timeval_add_usecs(&hctx->ccid3hctx_t_nom,
422 hctx->ccid3hctx_t_ipi);
423 }
424 break;
425 default:
426 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
427 __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
428 dump_stack();
429 break;
430 } 386 }
387 dccp_tx_hist_add_entry(&hctx->ccid3hctx_hist, packet);
388
389 dccp_timestamp(sk, &now);
390 packet->dccphtx_tstamp = now;
391 packet->dccphtx_seqno = dccp_sk(sk)->dccps_gss;
392 packet->dccphtx_rtt = hctx->ccid3hctx_rtt;
393 packet->dccphtx_sent = 1;
394 hctx->ccid3hctx_idle = 0;
431} 395}
432 396
433static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) 397static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
@@ -437,13 +401,11 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
437 struct ccid3_options_received *opt_recv; 401 struct ccid3_options_received *opt_recv;
438 struct dccp_tx_hist_entry *packet; 402 struct dccp_tx_hist_entry *packet;
439 struct timeval now; 403 struct timeval now;
440 unsigned long next_tmout; 404 unsigned long t_nfb;
441 u32 t_elapsed;
442 u32 pinv; 405 u32 pinv;
443 u32 x_recv; 406 suseconds_t r_sample, t_elapsed;
444 u32 r_sample;
445 407
446 BUG_ON(hctx == NULL || hctx->ccid3hctx_state == TFRC_SSTATE_TERM); 408 BUG_ON(hctx == NULL);
447 409
448 /* we are only interested in ACKs */ 410 /* we are only interested in ACKs */
449 if (!(DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK || 411 if (!(DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK ||
@@ -452,41 +414,49 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
452 414
453 opt_recv = &hctx->ccid3hctx_options_received; 415 opt_recv = &hctx->ccid3hctx_options_received;
454 416
455 t_elapsed = dp->dccps_options_received.dccpor_elapsed_time * 10;
456 x_recv = opt_recv->ccid3or_receive_rate;
457 pinv = opt_recv->ccid3or_loss_event_rate;
458
459 switch (hctx->ccid3hctx_state) { 417 switch (hctx->ccid3hctx_state) {
460 case TFRC_SSTATE_NO_SENT:
461 /* FIXME: what to do here? */
462 return;
463 case TFRC_SSTATE_NO_FBACK: 418 case TFRC_SSTATE_NO_FBACK:
464 case TFRC_SSTATE_FBACK: 419 case TFRC_SSTATE_FBACK:
465 /* Calculate new round trip sample by 420 /* get packet from history to look up t_recvdata */
466 * R_sample = (now - t_recvdata) - t_delay */
467 /* get t_recvdata from history */
468 packet = dccp_tx_hist_find_entry(&hctx->ccid3hctx_hist, 421 packet = dccp_tx_hist_find_entry(&hctx->ccid3hctx_hist,
469 DCCP_SKB_CB(skb)->dccpd_ack_seq); 422 DCCP_SKB_CB(skb)->dccpd_ack_seq);
470 if (unlikely(packet == NULL)) { 423 if (unlikely(packet == NULL)) {
471 LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, seqno " 424 DCCP_WARN("%s(%p), seqno %llu(%s) doesn't exist "
472 "%llu(%s) does't exist in history!\n", 425 "in history!\n", dccp_role(sk), sk,
473 __FUNCTION__, dccp_role(sk), sk,
474 (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq, 426 (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq,
475 dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type)); 427 dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
476 return; 428 return;
477 } 429 }
478 430
479 /* Update RTT */ 431 /* Update receive rate in units of 64 * bytes/second */
432 hctx->ccid3hctx_x_recv = opt_recv->ccid3or_receive_rate;
433 hctx->ccid3hctx_x_recv <<= 6;
434
435 /* Update loss event rate */
436 pinv = opt_recv->ccid3or_loss_event_rate;
437 if (pinv == ~0U || pinv == 0) /* see RFC 4342, 8.5 */
438 hctx->ccid3hctx_p = 0;
439 else /* can not exceed 100% */
440 hctx->ccid3hctx_p = 1000000 / pinv;
441
480 dccp_timestamp(sk, &now); 442 dccp_timestamp(sk, &now);
481 r_sample = timeval_delta(&now, &packet->dccphtx_tstamp); 443
444 /*
445 * Calculate new round trip sample as per [RFC 3448, 4.3] by
446 * R_sample = (now - t_recvdata) - t_elapsed
447 */
448 r_sample = timeval_delta(&now, &packet->dccphtx_tstamp);
449 t_elapsed = dp->dccps_options_received.dccpor_elapsed_time * 10;
450
451 DCCP_BUG_ON(r_sample < 0);
482 if (unlikely(r_sample <= t_elapsed)) 452 if (unlikely(r_sample <= t_elapsed))
483 LIMIT_NETDEBUG(KERN_WARNING "%s: r_sample=%uus, " 453 DCCP_WARN("WARNING: r_sample=%dus <= t_elapsed=%dus\n",
484 "t_elapsed=%uus\n", 454 (int)r_sample, (int)t_elapsed);
485 __FUNCTION__, r_sample, t_elapsed);
486 else 455 else
487 r_sample -= t_elapsed; 456 r_sample -= t_elapsed;
457 CCID3_RTT_SANITY_CHECK(r_sample);
488 458
489 /* Update RTT estimate by 459 /* Update RTT estimate by
490 * If (No feedback recv) 460 * If (No feedback recv)
491 * R = R_sample; 461 * R = R_sample;
492 * Else 462 * Else
@@ -495,97 +465,96 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
495 * q is a constant, RFC 3448 recomments 0.9 465 * q is a constant, RFC 3448 recomments 0.9
496 */ 466 */
497 if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) { 467 if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) {
498 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK); 468 /*
499 hctx->ccid3hctx_rtt = r_sample; 469 * Larger Initial Windows [RFC 4342, sec. 5]
500 } else 470 * We deviate in that we use `s' instead of `MSS'.
501 hctx->ccid3hctx_rtt = (hctx->ccid3hctx_rtt * 9) / 10 + 471 */
502 r_sample / 10; 472 __u64 w_init = min(4 * hctx->ccid3hctx_s,
503 473 max(2 * hctx->ccid3hctx_s, 4380));
504 ccid3_pr_debug("%s, sk=%p, New RTT estimate=%uus, " 474 hctx->ccid3hctx_rtt = r_sample;
505 "r_sample=%us\n", dccp_role(sk), sk, 475 hctx->ccid3hctx_x = scaled_div(w_init << 6, r_sample);
506 hctx->ccid3hctx_rtt, r_sample); 476 hctx->ccid3hctx_t_ld = now;
507
508 /* Update timeout interval */
509 hctx->ccid3hctx_t_rto = max_t(u32, 4 * hctx->ccid3hctx_rtt,
510 USEC_PER_SEC);
511 477
512 /* Update receive rate */ 478 ccid3_update_send_time(hctx);
513 hctx->ccid3hctx_x_recv = x_recv;/* X_recv in bytes per sec */
514 479
515 /* Update loss event rate */ 480 ccid3_pr_debug("%s(%p), s=%u, w_init=%llu, "
516 if (pinv == ~0 || pinv == 0) 481 "R_sample=%dus, X=%u\n", dccp_role(sk),
517 hctx->ccid3hctx_p = 0; 482 sk, hctx->ccid3hctx_s, w_init,
518 else { 483 (int)r_sample,
519 hctx->ccid3hctx_p = 1000000 / pinv; 484 (unsigned)(hctx->ccid3hctx_x >> 6));
520 485
521 if (hctx->ccid3hctx_p < TFRC_SMALLEST_P) { 486 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK);
522 hctx->ccid3hctx_p = TFRC_SMALLEST_P; 487 } else {
523 ccid3_pr_debug("%s, sk=%p, Smallest p used!\n", 488 hctx->ccid3hctx_rtt = (9 * hctx->ccid3hctx_rtt +
524 dccp_role(sk), sk); 489 (u32)r_sample) / 10;
525 } 490
491 /* Update sending rate (step 4 of [RFC 3448, 4.3]) */
492 if (hctx->ccid3hctx_p > 0)
493 hctx->ccid3hctx_x_calc =
494 tfrc_calc_x(hctx->ccid3hctx_s,
495 hctx->ccid3hctx_rtt,
496 hctx->ccid3hctx_p);
497 ccid3_hc_tx_update_x(sk, &now);
498
499 ccid3_pr_debug("%s(%p), RTT=%uus (sample=%dus), s=%u, "
500 "p=%u, X_calc=%u, X_recv=%u, X=%u\n",
501 dccp_role(sk),
502 sk, hctx->ccid3hctx_rtt, (int)r_sample,
503 hctx->ccid3hctx_s, hctx->ccid3hctx_p,
504 hctx->ccid3hctx_x_calc,
505 (unsigned)(hctx->ccid3hctx_x_recv >> 6),
506 (unsigned)(hctx->ccid3hctx_x >> 6));
526 } 507 }
527 508
528 /* unschedule no feedback timer */ 509 /* unschedule no feedback timer */
529 sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer); 510 sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer);
530 511
531 /* Update sending rate */
532 ccid3_hc_tx_update_x(sk);
533
534 /* Update next send time */
535 timeval_sub_usecs(&hctx->ccid3hctx_t_nom,
536 hctx->ccid3hctx_t_ipi);
537 ccid3_calc_new_t_ipi(hctx);
538 timeval_add_usecs(&hctx->ccid3hctx_t_nom,
539 hctx->ccid3hctx_t_ipi);
540 ccid3_calc_new_delta(hctx);
541
542 /* remove all packets older than the one acked from history */ 512 /* remove all packets older than the one acked from history */
543 dccp_tx_hist_purge_older(ccid3_tx_hist, 513 dccp_tx_hist_purge_older(ccid3_tx_hist,
544 &hctx->ccid3hctx_hist, packet); 514 &hctx->ccid3hctx_hist, packet);
545 /* 515 /*
546 * As we have calculated new ipi, delta, t_nom it is possible that 516 * As we have calculated new ipi, delta, t_nom it is possible
547 * we now can send a packet, so wake up dccp_wait_for_ccids. 517 * that we now can send a packet, so wake up dccp_wait_for_ccid
548 */ 518 */
549 sk->sk_write_space(sk); 519 sk->sk_write_space(sk);
550 520
551 /* 521 /*
522 * Update timeout interval for the nofeedback timer.
523 * We use a configuration option to increase the lower bound.
524 * This can help avoid triggering the nofeedback timer too
525 * often ('spinning') on LANs with small RTTs.
526 */
527 hctx->ccid3hctx_t_rto = max_t(u32, 4 * hctx->ccid3hctx_rtt,
528 CONFIG_IP_DCCP_CCID3_RTO *
529 (USEC_PER_SEC/1000));
530 /*
552 * Schedule no feedback timer to expire in 531 * Schedule no feedback timer to expire in
553 * max(4 * R, 2 * s / X) 532 * max(t_RTO, 2 * s/X) = max(t_RTO, 2 * t_ipi)
554 */ 533 */
555 next_tmout = max(hctx->ccid3hctx_t_rto, 534 t_nfb = max(hctx->ccid3hctx_t_rto, 2 * hctx->ccid3hctx_t_ipi);
556 2 * usecs_div(hctx->ccid3hctx_s, 535
557 hctx->ccid3hctx_x)); 536 ccid3_pr_debug("%s(%p), Scheduled no feedback timer to "
558
559 ccid3_pr_debug("%s, sk=%p, Scheduled no feedback timer to "
560 "expire in %lu jiffies (%luus)\n", 537 "expire in %lu jiffies (%luus)\n",
561 dccp_role(sk), sk, 538 dccp_role(sk),
562 usecs_to_jiffies(next_tmout), next_tmout); 539 sk, usecs_to_jiffies(t_nfb), t_nfb);
563 540
564 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, 541 sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
565 jiffies + max_t(u32, 1, usecs_to_jiffies(next_tmout))); 542 jiffies + usecs_to_jiffies(t_nfb));
566 543
567 /* set idle flag */ 544 /* set idle flag */
568 hctx->ccid3hctx_idle = 1; 545 hctx->ccid3hctx_idle = 1;
569 break; 546 break;
570 default: 547 case TFRC_SSTATE_NO_SENT:
571 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n", 548 /*
572 __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state); 549 * XXX when implementing bidirectional rx/tx check this again
573 dump_stack(); 550 */
551 DCCP_WARN("Illegal ACK received - no packet sent\n");
552 /* fall through */
553 case TFRC_SSTATE_TERM: /* ignore feedback when closing */
574 break; 554 break;
575 } 555 }
576} 556}
577 557
578static int ccid3_hc_tx_insert_options(struct sock *sk, struct sk_buff *skb)
579{
580 const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
581
582 BUG_ON(hctx == NULL);
583
584 if (sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN)
585 DCCP_SKB_CB(skb)->dccpd_ccval = hctx->ccid3hctx_last_win_count;
586 return 0;
587}
588
589static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, 558static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
590 unsigned char len, u16 idx, 559 unsigned char len, u16 idx,
591 unsigned char *value) 560 unsigned char *value)
@@ -610,13 +579,14 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
610 switch (option) { 579 switch (option) {
611 case TFRC_OPT_LOSS_EVENT_RATE: 580 case TFRC_OPT_LOSS_EVENT_RATE:
612 if (unlikely(len != 4)) { 581 if (unlikely(len != 4)) {
613 LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, invalid " 582 DCCP_WARN("%s(%p), invalid len %d "
614 "len for TFRC_OPT_LOSS_EVENT_RATE\n", 583 "for TFRC_OPT_LOSS_EVENT_RATE\n",
615 __FUNCTION__, dccp_role(sk), sk); 584 dccp_role(sk), sk, len);
616 rc = -EINVAL; 585 rc = -EINVAL;
617 } else { 586 } else {
618 opt_recv->ccid3or_loss_event_rate = ntohl(*(__be32 *)value); 587 opt_recv->ccid3or_loss_event_rate =
619 ccid3_pr_debug("%s, sk=%p, LOSS_EVENT_RATE=%u\n", 588 ntohl(*(__be32 *)value);
589 ccid3_pr_debug("%s(%p), LOSS_EVENT_RATE=%u\n",
620 dccp_role(sk), sk, 590 dccp_role(sk), sk,
621 opt_recv->ccid3or_loss_event_rate); 591 opt_recv->ccid3or_loss_event_rate);
622 } 592 }
@@ -624,20 +594,21 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
624 case TFRC_OPT_LOSS_INTERVALS: 594 case TFRC_OPT_LOSS_INTERVALS:
625 opt_recv->ccid3or_loss_intervals_idx = idx; 595 opt_recv->ccid3or_loss_intervals_idx = idx;
626 opt_recv->ccid3or_loss_intervals_len = len; 596 opt_recv->ccid3or_loss_intervals_len = len;
627 ccid3_pr_debug("%s, sk=%p, LOSS_INTERVALS=(%u, %u)\n", 597 ccid3_pr_debug("%s(%p), LOSS_INTERVALS=(%u, %u)\n",
628 dccp_role(sk), sk, 598 dccp_role(sk), sk,
629 opt_recv->ccid3or_loss_intervals_idx, 599 opt_recv->ccid3or_loss_intervals_idx,
630 opt_recv->ccid3or_loss_intervals_len); 600 opt_recv->ccid3or_loss_intervals_len);
631 break; 601 break;
632 case TFRC_OPT_RECEIVE_RATE: 602 case TFRC_OPT_RECEIVE_RATE:
633 if (unlikely(len != 4)) { 603 if (unlikely(len != 4)) {
634 LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, invalid " 604 DCCP_WARN("%s(%p), invalid len %d "
635 "len for TFRC_OPT_RECEIVE_RATE\n", 605 "for TFRC_OPT_RECEIVE_RATE\n",
636 __FUNCTION__, dccp_role(sk), sk); 606 dccp_role(sk), sk, len);
637 rc = -EINVAL; 607 rc = -EINVAL;
638 } else { 608 } else {
639 opt_recv->ccid3or_receive_rate = ntohl(*(__be32 *)value); 609 opt_recv->ccid3or_receive_rate =
640 ccid3_pr_debug("%s, sk=%p, RECEIVE_RATE=%u\n", 610 ntohl(*(__be32 *)value);
611 ccid3_pr_debug("%s(%p), RECEIVE_RATE=%u\n",
641 dccp_role(sk), sk, 612 dccp_role(sk), sk,
642 opt_recv->ccid3or_receive_rate); 613 opt_recv->ccid3or_receive_rate);
643 } 614 }
@@ -649,22 +620,15 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
649 620
650static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk) 621static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk)
651{ 622{
652 struct dccp_sock *dp = dccp_sk(sk);
653 struct ccid3_hc_tx_sock *hctx = ccid_priv(ccid); 623 struct ccid3_hc_tx_sock *hctx = ccid_priv(ccid);
654 624
655 if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE && 625 hctx->ccid3hctx_s = 0;
656 dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE) 626 hctx->ccid3hctx_rtt = 0;
657 hctx->ccid3hctx_s = dp->dccps_packet_size;
658 else
659 hctx->ccid3hctx_s = TFRC_STD_PACKET_SIZE;
660
661 /* Set transmission rate to 1 packet per second */
662 hctx->ccid3hctx_x = hctx->ccid3hctx_s;
663 hctx->ccid3hctx_t_rto = USEC_PER_SEC;
664 hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT; 627 hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT;
665 INIT_LIST_HEAD(&hctx->ccid3hctx_hist); 628 INIT_LIST_HEAD(&hctx->ccid3hctx_hist);
666 629
667 hctx->ccid3hctx_no_feedback_timer.function = ccid3_hc_tx_no_feedback_timer; 630 hctx->ccid3hctx_no_feedback_timer.function =
631 ccid3_hc_tx_no_feedback_timer;
668 hctx->ccid3hctx_no_feedback_timer.data = (unsigned long)sk; 632 hctx->ccid3hctx_no_feedback_timer.data = (unsigned long)sk;
669 init_timer(&hctx->ccid3hctx_no_feedback_timer); 633 init_timer(&hctx->ccid3hctx_no_feedback_timer);
670 634
@@ -688,14 +652,7 @@ static void ccid3_hc_tx_exit(struct sock *sk)
688 * RX Half Connection methods 652 * RX Half Connection methods
689 */ 653 */
690 654
691/* TFRC receiver states */ 655#ifdef CONFIG_IP_DCCP_CCID3_DEBUG
692enum ccid3_hc_rx_states {
693 TFRC_RSTATE_NO_DATA = 1,
694 TFRC_RSTATE_DATA,
695 TFRC_RSTATE_TERM = 127,
696};
697
698#ifdef CCID3_DEBUG
699static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state) 656static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state)
700{ 657{
701 static char *ccid3_rx_state_names[] = { 658 static char *ccid3_rx_state_names[] = {
@@ -721,14 +678,24 @@ static void ccid3_hc_rx_set_state(struct sock *sk,
721 hcrx->ccid3hcrx_state = state; 678 hcrx->ccid3hcrx_state = state;
722} 679}
723 680
681static inline void ccid3_hc_rx_update_s(struct ccid3_hc_rx_sock *hcrx, int len)
682{
683 if (unlikely(len == 0)) /* don't update on empty packets (e.g. ACKs) */
684 ccid3_pr_debug("Packet payload length is 0 - not updating\n");
685 else
686 hcrx->ccid3hcrx_s = hcrx->ccid3hcrx_s == 0 ? len :
687 (9 * hcrx->ccid3hcrx_s + len) / 10;
688}
689
724static void ccid3_hc_rx_send_feedback(struct sock *sk) 690static void ccid3_hc_rx_send_feedback(struct sock *sk)
725{ 691{
726 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); 692 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
727 struct dccp_sock *dp = dccp_sk(sk); 693 struct dccp_sock *dp = dccp_sk(sk);
728 struct dccp_rx_hist_entry *packet; 694 struct dccp_rx_hist_entry *packet;
729 struct timeval now; 695 struct timeval now;
696 suseconds_t delta;
730 697
731 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk); 698 ccid3_pr_debug("%s(%p) - entry \n", dccp_role(sk), sk);
732 699
733 dccp_timestamp(sk, &now); 700 dccp_timestamp(sk, &now);
734 701
@@ -736,25 +703,22 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk)
736 case TFRC_RSTATE_NO_DATA: 703 case TFRC_RSTATE_NO_DATA:
737 hcrx->ccid3hcrx_x_recv = 0; 704 hcrx->ccid3hcrx_x_recv = 0;
738 break; 705 break;
739 case TFRC_RSTATE_DATA: { 706 case TFRC_RSTATE_DATA:
740 const u32 delta = timeval_delta(&now, 707 delta = timeval_delta(&now,
741 &hcrx->ccid3hcrx_tstamp_last_feedback); 708 &hcrx->ccid3hcrx_tstamp_last_feedback);
742 hcrx->ccid3hcrx_x_recv = usecs_div(hcrx->ccid3hcrx_bytes_recv, 709 DCCP_BUG_ON(delta < 0);
743 delta); 710 hcrx->ccid3hcrx_x_recv =
744 } 711 scaled_div32(hcrx->ccid3hcrx_bytes_recv, delta);
745 break; 712 break;
746 default: 713 case TFRC_RSTATE_TERM:
747 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n", 714 DCCP_BUG("%s(%p) - Illegal state TERM", dccp_role(sk), sk);
748 __FUNCTION__, dccp_role(sk), sk, hcrx->ccid3hcrx_state);
749 dump_stack();
750 return; 715 return;
751 } 716 }
752 717
753 packet = dccp_rx_hist_find_data_packet(&hcrx->ccid3hcrx_hist); 718 packet = dccp_rx_hist_find_data_packet(&hcrx->ccid3hcrx_hist);
754 if (unlikely(packet == NULL)) { 719 if (unlikely(packet == NULL)) {
755 LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, no data packet " 720 DCCP_WARN("%s(%p), no data packet in history!\n",
756 "in history!\n", 721 dccp_role(sk), sk);
757 __FUNCTION__, dccp_role(sk), sk);
758 return; 722 return;
759 } 723 }
760 724
@@ -762,13 +726,19 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk)
762 hcrx->ccid3hcrx_ccval_last_counter = packet->dccphrx_ccval; 726 hcrx->ccid3hcrx_ccval_last_counter = packet->dccphrx_ccval;
763 hcrx->ccid3hcrx_bytes_recv = 0; 727 hcrx->ccid3hcrx_bytes_recv = 0;
764 728
765 /* Convert to multiples of 10us */ 729 /* Elapsed time information [RFC 4340, 13.2] in units of 10 * usecs */
766 hcrx->ccid3hcrx_elapsed_time = 730 delta = timeval_delta(&now, &packet->dccphrx_tstamp);
767 timeval_delta(&now, &packet->dccphrx_tstamp) / 10; 731 DCCP_BUG_ON(delta < 0);
732 hcrx->ccid3hcrx_elapsed_time = delta / 10;
733
768 if (hcrx->ccid3hcrx_p == 0) 734 if (hcrx->ccid3hcrx_p == 0)
769 hcrx->ccid3hcrx_pinv = ~0; 735 hcrx->ccid3hcrx_pinv = ~0U; /* see RFC 4342, 8.5 */
770 else 736 else if (hcrx->ccid3hcrx_p > 1000000) {
737 DCCP_WARN("p (%u) > 100%%\n", hcrx->ccid3hcrx_p);
738 hcrx->ccid3hcrx_pinv = 1; /* use 100% in this case */
739 } else
771 hcrx->ccid3hcrx_pinv = 1000000 / hcrx->ccid3hcrx_p; 740 hcrx->ccid3hcrx_pinv = 1000000 / hcrx->ccid3hcrx_p;
741
772 dp->dccps_hc_rx_insert_options = 1; 742 dp->dccps_hc_rx_insert_options = 1;
773 dccp_send_ack(sk); 743 dccp_send_ack(sk);
774} 744}
@@ -796,9 +766,9 @@ static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
796 hcrx->ccid3hcrx_elapsed_time)) || 766 hcrx->ccid3hcrx_elapsed_time)) ||
797 dccp_insert_option_timestamp(sk, skb) || 767 dccp_insert_option_timestamp(sk, skb) ||
798 dccp_insert_option(sk, skb, TFRC_OPT_LOSS_EVENT_RATE, 768 dccp_insert_option(sk, skb, TFRC_OPT_LOSS_EVENT_RATE,
799 &pinv, sizeof(pinv)) || 769 &pinv, sizeof(pinv)) ||
800 dccp_insert_option(sk, skb, TFRC_OPT_RECEIVE_RATE, 770 dccp_insert_option(sk, skb, TFRC_OPT_RECEIVE_RATE,
801 &x_recv, sizeof(x_recv))) 771 &x_recv, sizeof(x_recv)))
802 return -1; 772 return -1;
803 773
804 return 0; 774 return 0;
@@ -812,12 +782,13 @@ static u32 ccid3_hc_rx_calc_first_li(struct sock *sk)
812{ 782{
813 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); 783 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
814 struct dccp_rx_hist_entry *entry, *next, *tail = NULL; 784 struct dccp_rx_hist_entry *entry, *next, *tail = NULL;
815 u32 rtt, delta, x_recv, fval, p, tmp2; 785 u32 x_recv, p;
786 suseconds_t rtt, delta;
816 struct timeval tstamp = { 0, }; 787 struct timeval tstamp = { 0, };
817 int interval = 0; 788 int interval = 0;
818 int win_count = 0; 789 int win_count = 0;
819 int step = 0; 790 int step = 0;
820 u64 tmp1; 791 u64 fval;
821 792
822 list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist, 793 list_for_each_entry_safe(entry, next, &hcrx->ccid3hcrx_hist,
823 dccphrx_node) { 794 dccphrx_node) {
@@ -842,58 +813,66 @@ static u32 ccid3_hc_rx_calc_first_li(struct sock *sk)
842 } 813 }
843 814
844 if (unlikely(step == 0)) { 815 if (unlikely(step == 0)) {
845 LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, packet history " 816 DCCP_WARN("%s(%p), packet history has no data packets!\n",
846 "contains no data packets!\n", 817 dccp_role(sk), sk);
847 __FUNCTION__, dccp_role(sk), sk);
848 return ~0; 818 return ~0;
849 } 819 }
850 820
851 if (unlikely(interval == 0)) { 821 if (unlikely(interval == 0)) {
852 LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, Could not find a " 822 DCCP_WARN("%s(%p), Could not find a win_count interval > 0."
853 "win_count interval > 0. Defaulting to 1\n", 823 "Defaulting to 1\n", dccp_role(sk), sk);
854 __FUNCTION__, dccp_role(sk), sk);
855 interval = 1; 824 interval = 1;
856 } 825 }
857found: 826found:
858 if (!tail) { 827 if (!tail) {
859 LIMIT_NETDEBUG(KERN_WARNING "%s: tail is null\n", 828 DCCP_CRIT("tail is null\n");
860 __FUNCTION__);
861 return ~0; 829 return ~0;
862 } 830 }
863 rtt = timeval_delta(&tstamp, &tail->dccphrx_tstamp) * 4 / interval;
864 ccid3_pr_debug("%s, sk=%p, approximated RTT to %uus\n",
865 dccp_role(sk), sk, rtt);
866 if (rtt == 0)
867 rtt = 1;
868
869 dccp_timestamp(sk, &tstamp);
870 delta = timeval_delta(&tstamp, &hcrx->ccid3hcrx_tstamp_last_feedback);
871 x_recv = usecs_div(hcrx->ccid3hcrx_bytes_recv, delta);
872 831
873 if (x_recv == 0) 832 delta = timeval_delta(&tstamp, &tail->dccphrx_tstamp);
874 x_recv = hcrx->ccid3hcrx_x_recv; 833 DCCP_BUG_ON(delta < 0);
875 834
876 tmp1 = (u64)x_recv * (u64)rtt; 835 rtt = delta * 4 / interval;
877 do_div(tmp1,10000000); 836 ccid3_pr_debug("%s(%p), approximated RTT to %dus\n",
878 tmp2 = (u32)tmp1; 837 dccp_role(sk), sk, (int)rtt);
879 838
880 if (!tmp2) { 839 /*
881 LIMIT_NETDEBUG(KERN_WARNING "tmp2 = 0 " 840 * Determine the length of the first loss interval via inverse lookup.
882 "%s: x_recv = %u, rtt =%u\n", 841 * Assume that X_recv can be computed by the throughput equation
883 __FUNCTION__, x_recv, rtt); 842 * s
843 * X_recv = --------
844 * R * fval
845 * Find some p such that f(p) = fval; return 1/p [RFC 3448, 6.3.1].
846 */
847 if (rtt == 0) { /* would result in divide-by-zero */
848 DCCP_WARN("RTT==0\n");
884 return ~0; 849 return ~0;
885 } 850 }
886 851
887 fval = (hcrx->ccid3hcrx_s * 100000) / tmp2; 852 dccp_timestamp(sk, &tstamp);
888 /* do not alter order above or you will get overflow on 32 bit */ 853 delta = timeval_delta(&tstamp, &hcrx->ccid3hcrx_tstamp_last_feedback);
854 DCCP_BUG_ON(delta <= 0);
855
856 x_recv = scaled_div32(hcrx->ccid3hcrx_bytes_recv, delta);
857 if (x_recv == 0) { /* would also trigger divide-by-zero */
858 DCCP_WARN("X_recv==0\n");
859 if ((x_recv = hcrx->ccid3hcrx_x_recv) == 0) {
860 DCCP_BUG("stored value of X_recv is zero");
861 return ~0;
862 }
863 }
864
865 fval = scaled_div(hcrx->ccid3hcrx_s, rtt);
866 fval = scaled_div32(fval, x_recv);
889 p = tfrc_calc_x_reverse_lookup(fval); 867 p = tfrc_calc_x_reverse_lookup(fval);
890 ccid3_pr_debug("%s, sk=%p, receive rate=%u bytes/s, implied " 868
869 ccid3_pr_debug("%s(%p), receive rate=%u bytes/s, implied "
891 "loss rate=%u\n", dccp_role(sk), sk, x_recv, p); 870 "loss rate=%u\n", dccp_role(sk), sk, x_recv, p);
892 871
893 if (p == 0) 872 if (p == 0)
894 return ~0; 873 return ~0;
895 else 874 else
896 return 1000000 / p; 875 return 1000000 / p;
897} 876}
898 877
899static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss) 878static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss)
@@ -923,11 +902,10 @@ static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss)
923 /* new loss event detected */ 902 /* new loss event detected */
924 /* calculate last interval length */ 903 /* calculate last interval length */
925 seq_temp = dccp_delta_seqno(head->dccplih_seqno, seq_loss); 904 seq_temp = dccp_delta_seqno(head->dccplih_seqno, seq_loss);
926 entry = dccp_li_hist_entry_new(ccid3_li_hist, SLAB_ATOMIC); 905 entry = dccp_li_hist_entry_new(ccid3_li_hist, GFP_ATOMIC);
927 906
928 if (entry == NULL) { 907 if (entry == NULL) {
929 printk(KERN_CRIT "%s: out of memory\n",__FUNCTION__); 908 DCCP_BUG("out of memory - can not allocate entry");
930 dump_stack();
931 return; 909 return;
932 } 910 }
933 911
@@ -948,7 +926,8 @@ static int ccid3_hc_rx_detect_loss(struct sock *sk,
948 struct dccp_rx_hist_entry *packet) 926 struct dccp_rx_hist_entry *packet)
949{ 927{
950 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk); 928 struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
951 struct dccp_rx_hist_entry *rx_hist = dccp_rx_hist_head(&hcrx->ccid3hcrx_hist); 929 struct dccp_rx_hist_entry *rx_hist =
930 dccp_rx_hist_head(&hcrx->ccid3hcrx_hist);
952 u64 seqno = packet->dccphrx_seqno; 931 u64 seqno = packet->dccphrx_seqno;
953 u64 tmp_seqno; 932 u64 tmp_seqno;
954 int loss = 0; 933 int loss = 0;
@@ -976,7 +955,7 @@ static int ccid3_hc_rx_detect_loss(struct sock *sk,
976 dccp_inc_seqno(&tmp_seqno); 955 dccp_inc_seqno(&tmp_seqno);
977 while (dccp_rx_hist_find_entry(&hcrx->ccid3hcrx_hist, 956 while (dccp_rx_hist_find_entry(&hcrx->ccid3hcrx_hist,
978 tmp_seqno, &ccval)) { 957 tmp_seqno, &ccval)) {
979 hcrx->ccid3hcrx_seqno_nonloss = tmp_seqno; 958 hcrx->ccid3hcrx_seqno_nonloss = tmp_seqno;
980 hcrx->ccid3hcrx_ccval_nonloss = ccval; 959 hcrx->ccid3hcrx_ccval_nonloss = ccval;
981 dccp_inc_seqno(&tmp_seqno); 960 dccp_inc_seqno(&tmp_seqno);
982 } 961 }
@@ -1002,13 +981,11 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
1002 const struct dccp_options_received *opt_recv; 981 const struct dccp_options_received *opt_recv;
1003 struct dccp_rx_hist_entry *packet; 982 struct dccp_rx_hist_entry *packet;
1004 struct timeval now; 983 struct timeval now;
1005 u8 win_count; 984 u32 p_prev, rtt_prev;
1006 u32 p_prev, rtt_prev, r_sample, t_elapsed; 985 suseconds_t r_sample, t_elapsed;
1007 int loss; 986 int loss, payload_size;
1008 987
1009 BUG_ON(hcrx == NULL || 988 BUG_ON(hcrx == NULL);
1010 !(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA ||
1011 hcrx->ccid3hcrx_state == TFRC_RSTATE_DATA));
1012 989
1013 opt_recv = &dccp_sk(sk)->dccps_options_received; 990 opt_recv = &dccp_sk(sk)->dccps_options_received;
1014 991
@@ -1025,12 +1002,13 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
1025 r_sample = timeval_usecs(&now); 1002 r_sample = timeval_usecs(&now);
1026 t_elapsed = opt_recv->dccpor_elapsed_time * 10; 1003 t_elapsed = opt_recv->dccpor_elapsed_time * 10;
1027 1004
1005 DCCP_BUG_ON(r_sample < 0);
1028 if (unlikely(r_sample <= t_elapsed)) 1006 if (unlikely(r_sample <= t_elapsed))
1029 LIMIT_NETDEBUG(KERN_WARNING "%s: r_sample=%uus, " 1007 DCCP_WARN("r_sample=%ldus, t_elapsed=%ldus\n",
1030 "t_elapsed=%uus\n", 1008 r_sample, t_elapsed);
1031 __FUNCTION__, r_sample, t_elapsed);
1032 else 1009 else
1033 r_sample -= t_elapsed; 1010 r_sample -= t_elapsed;
1011 CCID3_RTT_SANITY_CHECK(r_sample);
1034 1012
1035 if (hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA) 1013 if (hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)
1036 hcrx->ccid3hcrx_rtt = r_sample; 1014 hcrx->ccid3hcrx_rtt = r_sample;
@@ -1039,8 +1017,8 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
1039 r_sample / 10; 1017 r_sample / 10;
1040 1018
1041 if (rtt_prev != hcrx->ccid3hcrx_rtt) 1019 if (rtt_prev != hcrx->ccid3hcrx_rtt)
1042 ccid3_pr_debug("%s, New RTT=%uus, elapsed time=%u\n", 1020 ccid3_pr_debug("%s(%p), New RTT=%uus, elapsed time=%u\n",
1043 dccp_role(sk), hcrx->ccid3hcrx_rtt, 1021 dccp_role(sk), sk, hcrx->ccid3hcrx_rtt,
1044 opt_recv->dccpor_elapsed_time); 1022 opt_recv->dccpor_elapsed_time);
1045 break; 1023 break;
1046 case DCCP_PKT_DATA: 1024 case DCCP_PKT_DATA:
@@ -1050,52 +1028,48 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
1050 } 1028 }
1051 1029
1052 packet = dccp_rx_hist_entry_new(ccid3_rx_hist, sk, opt_recv->dccpor_ndp, 1030 packet = dccp_rx_hist_entry_new(ccid3_rx_hist, sk, opt_recv->dccpor_ndp,
1053 skb, SLAB_ATOMIC); 1031 skb, GFP_ATOMIC);
1054 if (unlikely(packet == NULL)) { 1032 if (unlikely(packet == NULL)) {
1055 LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, Not enough mem to " 1033 DCCP_WARN("%s(%p), Not enough mem to add rx packet "
1056 "add rx packet to history, consider it lost!\n", 1034 "to history, consider it lost!\n", dccp_role(sk), sk);
1057 __FUNCTION__, dccp_role(sk), sk);
1058 return; 1035 return;
1059 } 1036 }
1060 1037
1061 win_count = packet->dccphrx_ccval;
1062
1063 loss = ccid3_hc_rx_detect_loss(sk, packet); 1038 loss = ccid3_hc_rx_detect_loss(sk, packet);
1064 1039
1065 if (DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK) 1040 if (DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK)
1066 return; 1041 return;
1067 1042
1043 payload_size = skb->len - dccp_hdr(skb)->dccph_doff * 4;
1044 ccid3_hc_rx_update_s(hcrx, payload_size);
1045
1068 switch (hcrx->ccid3hcrx_state) { 1046 switch (hcrx->ccid3hcrx_state) {
1069 case TFRC_RSTATE_NO_DATA: 1047 case TFRC_RSTATE_NO_DATA:
1070 ccid3_pr_debug("%s, sk=%p(%s), skb=%p, sending initial " 1048 ccid3_pr_debug("%s(%p, state=%s), skb=%p, sending initial "
1071 "feedback\n", 1049 "feedback\n", dccp_role(sk), sk,
1072 dccp_role(sk), sk,
1073 dccp_state_name(sk->sk_state), skb); 1050 dccp_state_name(sk->sk_state), skb);
1074 ccid3_hc_rx_send_feedback(sk); 1051 ccid3_hc_rx_send_feedback(sk);
1075 ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA); 1052 ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA);
1076 return; 1053 return;
1077 case TFRC_RSTATE_DATA: 1054 case TFRC_RSTATE_DATA:
1078 hcrx->ccid3hcrx_bytes_recv += skb->len - 1055 hcrx->ccid3hcrx_bytes_recv += payload_size;
1079 dccp_hdr(skb)->dccph_doff * 4;
1080 if (loss) 1056 if (loss)
1081 break; 1057 break;
1082 1058
1083 dccp_timestamp(sk, &now); 1059 dccp_timestamp(sk, &now);
1084 if (timeval_delta(&now, &hcrx->ccid3hcrx_tstamp_last_ack) >= 1060 if ((timeval_delta(&now, &hcrx->ccid3hcrx_tstamp_last_ack) -
1085 hcrx->ccid3hcrx_rtt) { 1061 (suseconds_t)hcrx->ccid3hcrx_rtt) >= 0) {
1086 hcrx->ccid3hcrx_tstamp_last_ack = now; 1062 hcrx->ccid3hcrx_tstamp_last_ack = now;
1087 ccid3_hc_rx_send_feedback(sk); 1063 ccid3_hc_rx_send_feedback(sk);
1088 } 1064 }
1089 return; 1065 return;
1090 default: 1066 case TFRC_RSTATE_TERM:
1091 printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n", 1067 DCCP_BUG("%s(%p) - Illegal state TERM", dccp_role(sk), sk);
1092 __FUNCTION__, dccp_role(sk), sk, hcrx->ccid3hcrx_state);
1093 dump_stack();
1094 return; 1068 return;
1095 } 1069 }
1096 1070
1097 /* Dealing with packet loss */ 1071 /* Dealing with packet loss */
1098 ccid3_pr_debug("%s, sk=%p(%s), data loss! Reacting...\n", 1072 ccid3_pr_debug("%s(%p, state=%s), data loss! Reacting...\n",
1099 dccp_role(sk), sk, dccp_state_name(sk->sk_state)); 1073 dccp_role(sk), sk, dccp_state_name(sk->sk_state));
1100 1074
1101 p_prev = hcrx->ccid3hcrx_p; 1075 p_prev = hcrx->ccid3hcrx_p;
@@ -1107,10 +1081,8 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
1107 /* Scaling up by 1000000 as fixed decimal */ 1081 /* Scaling up by 1000000 as fixed decimal */
1108 if (i_mean != 0) 1082 if (i_mean != 0)
1109 hcrx->ccid3hcrx_p = 1000000 / i_mean; 1083 hcrx->ccid3hcrx_p = 1000000 / i_mean;
1110 } else { 1084 } else
1111 printk(KERN_CRIT "%s: empty loss hist\n",__FUNCTION__); 1085 DCCP_BUG("empty loss history");
1112 dump_stack();
1113 }
1114 1086
1115 if (hcrx->ccid3hcrx_p > p_prev) { 1087 if (hcrx->ccid3hcrx_p > p_prev) {
1116 ccid3_hc_rx_send_feedback(sk); 1088 ccid3_hc_rx_send_feedback(sk);
@@ -1120,23 +1092,17 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
1120 1092
1121static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk) 1093static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk)
1122{ 1094{
1123 struct dccp_sock *dp = dccp_sk(sk);
1124 struct ccid3_hc_rx_sock *hcrx = ccid_priv(ccid); 1095 struct ccid3_hc_rx_sock *hcrx = ccid_priv(ccid);
1125 1096
1126 ccid3_pr_debug("%s, sk=%p\n", dccp_role(sk), sk); 1097 ccid3_pr_debug("entry\n");
1127
1128 if (dp->dccps_packet_size >= TFRC_MIN_PACKET_SIZE &&
1129 dp->dccps_packet_size <= TFRC_MAX_PACKET_SIZE)
1130 hcrx->ccid3hcrx_s = dp->dccps_packet_size;
1131 else
1132 hcrx->ccid3hcrx_s = TFRC_STD_PACKET_SIZE;
1133 1098
1134 hcrx->ccid3hcrx_state = TFRC_RSTATE_NO_DATA; 1099 hcrx->ccid3hcrx_state = TFRC_RSTATE_NO_DATA;
1135 INIT_LIST_HEAD(&hcrx->ccid3hcrx_hist); 1100 INIT_LIST_HEAD(&hcrx->ccid3hcrx_hist);
1136 INIT_LIST_HEAD(&hcrx->ccid3hcrx_li_hist); 1101 INIT_LIST_HEAD(&hcrx->ccid3hcrx_li_hist);
1137 dccp_timestamp(sk, &hcrx->ccid3hcrx_tstamp_last_ack); 1102 dccp_timestamp(sk, &hcrx->ccid3hcrx_tstamp_last_ack);
1138 hcrx->ccid3hcrx_tstamp_last_feedback = hcrx->ccid3hcrx_tstamp_last_ack; 1103 hcrx->ccid3hcrx_tstamp_last_feedback = hcrx->ccid3hcrx_tstamp_last_ack;
1139 hcrx->ccid3hcrx_rtt = 5000; /* XXX 5ms for now... */ 1104 hcrx->ccid3hcrx_s = 0;
1105 hcrx->ccid3hcrx_rtt = 0;
1140 return 0; 1106 return 0;
1141} 1107}
1142 1108
@@ -1165,9 +1131,9 @@ static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info)
1165 1131
1166 BUG_ON(hcrx == NULL); 1132 BUG_ON(hcrx == NULL);
1167 1133
1168 info->tcpi_ca_state = hcrx->ccid3hcrx_state; 1134 info->tcpi_ca_state = hcrx->ccid3hcrx_state;
1169 info->tcpi_options |= TCPI_OPT_TIMESTAMPS; 1135 info->tcpi_options |= TCPI_OPT_TIMESTAMPS;
1170 info->tcpi_rcv_rtt = hcrx->ccid3hcrx_rtt; 1136 info->tcpi_rcv_rtt = hcrx->ccid3hcrx_rtt;
1171} 1137}
1172 1138
1173static void ccid3_hc_tx_get_info(struct sock *sk, struct tcp_info *info) 1139static void ccid3_hc_tx_get_info(struct sock *sk, struct tcp_info *info)
@@ -1248,7 +1214,6 @@ static struct ccid_operations ccid3 = {
1248 .ccid_hc_tx_send_packet = ccid3_hc_tx_send_packet, 1214 .ccid_hc_tx_send_packet = ccid3_hc_tx_send_packet,
1249 .ccid_hc_tx_packet_sent = ccid3_hc_tx_packet_sent, 1215 .ccid_hc_tx_packet_sent = ccid3_hc_tx_packet_sent,
1250 .ccid_hc_tx_packet_recv = ccid3_hc_tx_packet_recv, 1216 .ccid_hc_tx_packet_recv = ccid3_hc_tx_packet_recv,
1251 .ccid_hc_tx_insert_options = ccid3_hc_tx_insert_options,
1252 .ccid_hc_tx_parse_options = ccid3_hc_tx_parse_options, 1217 .ccid_hc_tx_parse_options = ccid3_hc_tx_parse_options,
1253 .ccid_hc_rx_obj_size = sizeof(struct ccid3_hc_rx_sock), 1218 .ccid_hc_rx_obj_size = sizeof(struct ccid3_hc_rx_sock),
1254 .ccid_hc_rx_init = ccid3_hc_rx_init, 1219 .ccid_hc_rx_init = ccid3_hc_rx_init,
@@ -1260,9 +1225,11 @@ static struct ccid_operations ccid3 = {
1260 .ccid_hc_rx_getsockopt = ccid3_hc_rx_getsockopt, 1225 .ccid_hc_rx_getsockopt = ccid3_hc_rx_getsockopt,
1261 .ccid_hc_tx_getsockopt = ccid3_hc_tx_getsockopt, 1226 .ccid_hc_tx_getsockopt = ccid3_hc_tx_getsockopt,
1262}; 1227};
1263 1228
1229#ifdef CONFIG_IP_DCCP_CCID3_DEBUG
1264module_param(ccid3_debug, int, 0444); 1230module_param(ccid3_debug, int, 0444);
1265MODULE_PARM_DESC(ccid3_debug, "Enable debug messages"); 1231MODULE_PARM_DESC(ccid3_debug, "Enable debug messages");
1232#endif
1266 1233
1267static __init int ccid3_module_init(void) 1234static __init int ccid3_module_init(void)
1268{ 1235{
@@ -1281,7 +1248,7 @@ static __init int ccid3_module_init(void)
1281 goto out_free_tx; 1248 goto out_free_tx;
1282 1249
1283 rc = ccid_register(&ccid3); 1250 rc = ccid_register(&ccid3);
1284 if (rc != 0) 1251 if (rc != 0)
1285 goto out_free_loss_interval_history; 1252 goto out_free_loss_interval_history;
1286out: 1253out:
1287 return rc; 1254 return rc;
diff --git a/net/dccp/ccids/ccid3.h b/net/dccp/ccids/ccid3.h
index 0a2cb7536d..15776a88c0 100644
--- a/net/dccp/ccids/ccid3.h
+++ b/net/dccp/ccids/ccid3.h
@@ -42,22 +42,24 @@
42#include <linux/tfrc.h> 42#include <linux/tfrc.h>
43#include "../ccid.h" 43#include "../ccid.h"
44 44
45#define TFRC_MIN_PACKET_SIZE 16 45/* Two seconds as per RFC 3448 4.2 */
46#define TFRC_STD_PACKET_SIZE 256
47#define TFRC_MAX_PACKET_SIZE 65535
48
49/* Two seconds as per CCID3 spec */
50#define TFRC_INITIAL_TIMEOUT (2 * USEC_PER_SEC) 46#define TFRC_INITIAL_TIMEOUT (2 * USEC_PER_SEC)
51 47
52#define TFRC_INITIAL_IPI (USEC_PER_SEC / 4)
53
54/* In usecs - half the scheduling granularity as per RFC3448 4.6 */ 48/* In usecs - half the scheduling granularity as per RFC3448 4.6 */
55#define TFRC_OPSYS_HALF_TIME_GRAN (USEC_PER_SEC / (2 * HZ)) 49#define TFRC_OPSYS_HALF_TIME_GRAN (USEC_PER_SEC / (2 * HZ))
56 50
57/* In seconds */ 51/* Parameter t_mbi from [RFC 3448, 4.3]: backoff interval in seconds */
58#define TFRC_MAX_BACK_OFF_TIME 64 52#define TFRC_T_MBI 64
53
54/* What we think is a reasonable upper limit on RTT values */
55#define CCID3_SANE_RTT_MAX ((suseconds_t)(4 * USEC_PER_SEC))
59 56
60#define TFRC_SMALLEST_P 40 57#define CCID3_RTT_SANITY_CHECK(rtt) do { \
58 if (rtt > CCID3_SANE_RTT_MAX) { \
59 DCCP_CRIT("RTT (%d) too large, substituting %d", \
60 (int)rtt, (int)CCID3_SANE_RTT_MAX); \
61 rtt = CCID3_SANE_RTT_MAX; \
62 } } while (0)
61 63
62enum ccid3_options { 64enum ccid3_options {
63 TFRC_OPT_LOSS_EVENT_RATE = 192, 65 TFRC_OPT_LOSS_EVENT_RATE = 192,
@@ -73,26 +75,36 @@ struct ccid3_options_received {
73 u32 ccid3or_receive_rate; 75 u32 ccid3or_receive_rate;
74}; 76};
75 77
76/** struct ccid3_hc_tx_sock - CCID3 sender half connection sock 78/* TFRC sender states */
79enum ccid3_hc_tx_states {
80 TFRC_SSTATE_NO_SENT = 1,
81 TFRC_SSTATE_NO_FBACK,
82 TFRC_SSTATE_FBACK,
83 TFRC_SSTATE_TERM,
84};
85
86/** struct ccid3_hc_tx_sock - CCID3 sender half-connection socket
77 * 87 *
78 * @ccid3hctx_state - Sender state 88 * @ccid3hctx_x - Current sending rate in 64 * bytes per second
79 * @ccid3hctx_x - Current sending rate 89 * @ccid3hctx_x_recv - Receive rate in 64 * bytes per second
80 * @ccid3hctx_x_recv - Receive rate 90 * @ccid3hctx_x_calc - Calculated rate in bytes per second
81 * @ccid3hctx_x_calc - Calculated send (?) rate 91 * @ccid3hctx_rtt - Estimate of current round trip time in usecs
82 * @ccid3hctx_s - Packet size 92 * @ccid3hctx_p - Current loss event rate (0-1) scaled by 1000000
83 * @ccid3hctx_rtt - Estimate of current round trip time in usecs 93 * @ccid3hctx_s - Packet size in bytes
84 * @@ccid3hctx_p - Current loss event rate (0-1) scaled by 1000000 94 * @ccid3hctx_t_rto - Nofeedback Timer setting in usecs
85 * @ccid3hctx_last_win_count - Last window counter sent 95 * @ccid3hctx_t_ipi - Interpacket (send) interval (RFC 3448, 4.6) in usecs
86 * @ccid3hctx_t_last_win_count - Timestamp of earliest packet 96 * @ccid3hctx_state - Sender state, one of %ccid3_hc_tx_states
87 * with last_win_count value sent 97 * @ccid3hctx_last_win_count - Last window counter sent
88 * @ccid3hctx_no_feedback_timer - Handle to no feedback timer 98 * @ccid3hctx_t_last_win_count - Timestamp of earliest packet
89 * @ccid3hctx_idle - FIXME 99 * with last_win_count value sent
90 * @ccid3hctx_t_ld - Time last doubled during slow start 100 * @ccid3hctx_no_feedback_timer - Handle to no feedback timer
91 * @ccid3hctx_t_nom - Nominal send time of next packet 101 * @ccid3hctx_idle - Flag indicating that sender is idling
92 * @ccid3hctx_t_ipi - Interpacket (send) interval 102 * @ccid3hctx_t_ld - Time last doubled during slow start
93 * @ccid3hctx_delta - Send timer delta 103 * @ccid3hctx_t_nom - Nominal send time of next packet
94 * @ccid3hctx_hist - Packet history 104 * @ccid3hctx_delta - Send timer delta (RFC 3448, 4.6) in usecs
95 */ 105 * @ccid3hctx_hist - Packet history
106 * @ccid3hctx_options_received - Parsed set of retrieved options
107 */
96struct ccid3_hc_tx_sock { 108struct ccid3_hc_tx_sock {
97 struct tfrc_tx_info ccid3hctx_tfrc; 109 struct tfrc_tx_info ccid3hctx_tfrc;
98#define ccid3hctx_x ccid3hctx_tfrc.tfrctx_x 110#define ccid3hctx_x ccid3hctx_tfrc.tfrctx_x
@@ -103,7 +115,7 @@ struct ccid3_hc_tx_sock {
103#define ccid3hctx_t_rto ccid3hctx_tfrc.tfrctx_rto 115#define ccid3hctx_t_rto ccid3hctx_tfrc.tfrctx_rto
104#define ccid3hctx_t_ipi ccid3hctx_tfrc.tfrctx_ipi 116#define ccid3hctx_t_ipi ccid3hctx_tfrc.tfrctx_ipi
105 u16 ccid3hctx_s; 117 u16 ccid3hctx_s;
106 u8 ccid3hctx_state; 118 enum ccid3_hc_tx_states ccid3hctx_state:8;
107 u8 ccid3hctx_last_win_count; 119 u8 ccid3hctx_last_win_count;
108 u8 ccid3hctx_idle; 120 u8 ccid3hctx_idle;
109 struct timeval ccid3hctx_t_last_win_count; 121 struct timeval ccid3hctx_t_last_win_count;
@@ -115,23 +127,48 @@ struct ccid3_hc_tx_sock {
115 struct ccid3_options_received ccid3hctx_options_received; 127 struct ccid3_options_received ccid3hctx_options_received;
116}; 128};
117 129
130/* TFRC receiver states */
131enum ccid3_hc_rx_states {
132 TFRC_RSTATE_NO_DATA = 1,
133 TFRC_RSTATE_DATA,
134 TFRC_RSTATE_TERM = 127,
135};
136
137/** struct ccid3_hc_rx_sock - CCID3 receiver half-connection socket
138 *
139 * @ccid3hcrx_x_recv - Receiver estimate of send rate (RFC 3448 4.3)
140 * @ccid3hcrx_rtt - Receiver estimate of rtt (non-standard)
141 * @ccid3hcrx_p - current loss event rate (RFC 3448 5.4)
142 * @ccid3hcrx_seqno_nonloss - Last received non-loss sequence number
143 * @ccid3hcrx_ccval_nonloss - Last received non-loss Window CCVal
144 * @ccid3hcrx_ccval_last_counter - Tracks window counter (RFC 4342, 8.1)
145 * @ccid3hcrx_state - receiver state, one of %ccid3_hc_rx_states
146 * @ccid3hcrx_bytes_recv - Total sum of DCCP payload bytes
147 * @ccid3hcrx_tstamp_last_feedback - Time at which last feedback was sent
148 * @ccid3hcrx_tstamp_last_ack - Time at which last feedback was sent
149 * @ccid3hcrx_hist - Packet history
150 * @ccid3hcrx_li_hist - Loss Interval History
151 * @ccid3hcrx_s - Received packet size in bytes
152 * @ccid3hcrx_pinv - Inverse of Loss Event Rate (RFC 4342, sec. 8.5)
153 * @ccid3hcrx_elapsed_time - Time since packet reception
154 */
118struct ccid3_hc_rx_sock { 155struct ccid3_hc_rx_sock {
119 struct tfrc_rx_info ccid3hcrx_tfrc; 156 struct tfrc_rx_info ccid3hcrx_tfrc;
120#define ccid3hcrx_x_recv ccid3hcrx_tfrc.tfrcrx_x_recv 157#define ccid3hcrx_x_recv ccid3hcrx_tfrc.tfrcrx_x_recv
121#define ccid3hcrx_rtt ccid3hcrx_tfrc.tfrcrx_rtt 158#define ccid3hcrx_rtt ccid3hcrx_tfrc.tfrcrx_rtt
122#define ccid3hcrx_p ccid3hcrx_tfrc.tfrcrx_p 159#define ccid3hcrx_p ccid3hcrx_tfrc.tfrcrx_p
123 u64 ccid3hcrx_seqno_nonloss:48, 160 u64 ccid3hcrx_seqno_nonloss:48,
124 ccid3hcrx_ccval_nonloss:4, 161 ccid3hcrx_ccval_nonloss:4,
125 ccid3hcrx_state:8, 162 ccid3hcrx_ccval_last_counter:4;
126 ccid3hcrx_ccval_last_counter:4; 163 enum ccid3_hc_rx_states ccid3hcrx_state:8;
127 u32 ccid3hcrx_bytes_recv; 164 u32 ccid3hcrx_bytes_recv;
128 struct timeval ccid3hcrx_tstamp_last_feedback; 165 struct timeval ccid3hcrx_tstamp_last_feedback;
129 struct timeval ccid3hcrx_tstamp_last_ack; 166 struct timeval ccid3hcrx_tstamp_last_ack;
130 struct list_head ccid3hcrx_hist; 167 struct list_head ccid3hcrx_hist;
131 struct list_head ccid3hcrx_li_hist; 168 struct list_head ccid3hcrx_li_hist;
132 u16 ccid3hcrx_s; 169 u16 ccid3hcrx_s;
133 u32 ccid3hcrx_pinv; 170 u32 ccid3hcrx_pinv;
134 u32 ccid3hcrx_elapsed_time; 171 u32 ccid3hcrx_elapsed_time;
135}; 172};
136 173
137static inline struct ccid3_hc_tx_sock *ccid3_hc_tx_sk(const struct sock *sk) 174static inline struct ccid3_hc_tx_sock *ccid3_hc_tx_sk(const struct sock *sk)
diff --git a/net/dccp/ccids/lib/loss_interval.c b/net/dccp/ccids/lib/loss_interval.c
index 906c81ab9d..0a0baef16b 100644
--- a/net/dccp/ccids/lib/loss_interval.c
+++ b/net/dccp/ccids/lib/loss_interval.c
@@ -13,7 +13,7 @@
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <net/sock.h> 15#include <net/sock.h>
16 16#include "../../dccp.h"
17#include "loss_interval.h" 17#include "loss_interval.h"
18 18
19struct dccp_li_hist *dccp_li_hist_new(const char *name) 19struct dccp_li_hist *dccp_li_hist_new(const char *name)
@@ -109,7 +109,7 @@ u32 dccp_li_hist_calc_i_mean(struct list_head *list)
109 i_tot = max(i_tot0, i_tot1); 109 i_tot = max(i_tot0, i_tot1);
110 110
111 if (!w_tot) { 111 if (!w_tot) {
112 LIMIT_NETDEBUG(KERN_WARNING "%s: w_tot = 0\n", __FUNCTION__); 112 DCCP_WARN("w_tot = 0\n");
113 return 1; 113 return 1;
114 } 114 }
115 115
@@ -125,10 +125,10 @@ int dccp_li_hist_interval_new(struct dccp_li_hist *hist,
125 int i; 125 int i;
126 126
127 for (i = 0; i < DCCP_LI_HIST_IVAL_F_LENGTH; i++) { 127 for (i = 0; i < DCCP_LI_HIST_IVAL_F_LENGTH; i++) {
128 entry = dccp_li_hist_entry_new(hist, SLAB_ATOMIC); 128 entry = dccp_li_hist_entry_new(hist, GFP_ATOMIC);
129 if (entry == NULL) { 129 if (entry == NULL) {
130 dccp_li_hist_purge(hist, list); 130 dccp_li_hist_purge(hist, list);
131 dump_stack(); 131 DCCP_BUG("loss interval list entry is NULL");
132 return 0; 132 return 0;
133 } 133 }
134 entry->dccplih_interval = ~0; 134 entry->dccplih_interval = ~0;
diff --git a/net/dccp/ccids/lib/loss_interval.h b/net/dccp/ccids/lib/loss_interval.h
index 0ae85f0340..eb257014dd 100644
--- a/net/dccp/ccids/lib/loss_interval.h
+++ b/net/dccp/ccids/lib/loss_interval.h
@@ -20,7 +20,7 @@
20#define DCCP_LI_HIST_IVAL_F_LENGTH 8 20#define DCCP_LI_HIST_IVAL_F_LENGTH 8
21 21
22struct dccp_li_hist { 22struct dccp_li_hist {
23 kmem_cache_t *dccplih_slab; 23 struct kmem_cache *dccplih_slab;
24}; 24};
25 25
26extern struct dccp_li_hist *dccp_li_hist_new(const char *name); 26extern struct dccp_li_hist *dccp_li_hist_new(const char *name);
diff --git a/net/dccp/ccids/lib/packet_history.c b/net/dccp/ccids/lib/packet_history.c
index b876c9c81c..2e8ef42721 100644
--- a/net/dccp/ccids/lib/packet_history.c
+++ b/net/dccp/ccids/lib/packet_history.c
@@ -36,9 +36,100 @@
36 36
37#include <linux/module.h> 37#include <linux/module.h>
38#include <linux/string.h> 38#include <linux/string.h>
39
40#include "packet_history.h" 39#include "packet_history.h"
41 40
41/*
42 * Transmitter History Routines
43 */
44struct dccp_tx_hist *dccp_tx_hist_new(const char *name)
45{
46 struct dccp_tx_hist *hist = kmalloc(sizeof(*hist), GFP_ATOMIC);
47 static const char dccp_tx_hist_mask[] = "tx_hist_%s";
48 char *slab_name;
49
50 if (hist == NULL)
51 goto out;
52
53 slab_name = kmalloc(strlen(name) + sizeof(dccp_tx_hist_mask) - 1,
54 GFP_ATOMIC);
55 if (slab_name == NULL)
56 goto out_free_hist;
57
58 sprintf(slab_name, dccp_tx_hist_mask, name);
59 hist->dccptxh_slab = kmem_cache_create(slab_name,
60 sizeof(struct dccp_tx_hist_entry),
61 0, SLAB_HWCACHE_ALIGN,
62 NULL, NULL);
63 if (hist->dccptxh_slab == NULL)
64 goto out_free_slab_name;
65out:
66 return hist;
67out_free_slab_name:
68 kfree(slab_name);
69out_free_hist:
70 kfree(hist);
71 hist = NULL;
72 goto out;
73}
74
75EXPORT_SYMBOL_GPL(dccp_tx_hist_new);
76
77void dccp_tx_hist_delete(struct dccp_tx_hist *hist)
78{
79 const char* name = kmem_cache_name(hist->dccptxh_slab);
80
81 kmem_cache_destroy(hist->dccptxh_slab);
82 kfree(name);
83 kfree(hist);
84}
85
86EXPORT_SYMBOL_GPL(dccp_tx_hist_delete);
87
88struct dccp_tx_hist_entry *
89 dccp_tx_hist_find_entry(const struct list_head *list, const u64 seq)
90{
91 struct dccp_tx_hist_entry *packet = NULL, *entry;
92
93 list_for_each_entry(entry, list, dccphtx_node)
94 if (entry->dccphtx_seqno == seq) {
95 packet = entry;
96 break;
97 }
98
99 return packet;
100}
101
102EXPORT_SYMBOL_GPL(dccp_tx_hist_find_entry);
103
104void dccp_tx_hist_purge(struct dccp_tx_hist *hist, struct list_head *list)
105{
106 struct dccp_tx_hist_entry *entry, *next;
107
108 list_for_each_entry_safe(entry, next, list, dccphtx_node) {
109 list_del_init(&entry->dccphtx_node);
110 dccp_tx_hist_entry_delete(hist, entry);
111 }
112}
113
114EXPORT_SYMBOL_GPL(dccp_tx_hist_purge);
115
116void dccp_tx_hist_purge_older(struct dccp_tx_hist *hist,
117 struct list_head *list,
118 struct dccp_tx_hist_entry *packet)
119{
120 struct dccp_tx_hist_entry *next;
121
122 list_for_each_entry_safe_continue(packet, next, list, dccphtx_node) {
123 list_del_init(&packet->dccphtx_node);
124 dccp_tx_hist_entry_delete(hist, packet);
125 }
126}
127
128EXPORT_SYMBOL_GPL(dccp_tx_hist_purge_older);
129
130/*
131 * Receiver History Routines
132 */
42struct dccp_rx_hist *dccp_rx_hist_new(const char *name) 133struct dccp_rx_hist *dccp_rx_hist_new(const char *name)
43{ 134{
44 struct dccp_rx_hist *hist = kmalloc(sizeof(*hist), GFP_ATOMIC); 135 struct dccp_rx_hist *hist = kmalloc(sizeof(*hist), GFP_ATOMIC);
@@ -83,18 +174,24 @@ void dccp_rx_hist_delete(struct dccp_rx_hist *hist)
83 174
84EXPORT_SYMBOL_GPL(dccp_rx_hist_delete); 175EXPORT_SYMBOL_GPL(dccp_rx_hist_delete);
85 176
86void dccp_rx_hist_purge(struct dccp_rx_hist *hist, struct list_head *list) 177int dccp_rx_hist_find_entry(const struct list_head *list, const u64 seq,
178 u8 *ccval)
87{ 179{
88 struct dccp_rx_hist_entry *entry, *next; 180 struct dccp_rx_hist_entry *packet = NULL, *entry;
89 181
90 list_for_each_entry_safe(entry, next, list, dccphrx_node) { 182 list_for_each_entry(entry, list, dccphrx_node)
91 list_del_init(&entry->dccphrx_node); 183 if (entry->dccphrx_seqno == seq) {
92 kmem_cache_free(hist->dccprxh_slab, entry); 184 packet = entry;
93 } 185 break;
94} 186 }
95 187
96EXPORT_SYMBOL_GPL(dccp_rx_hist_purge); 188 if (packet)
189 *ccval = packet->dccphrx_ccval;
97 190
191 return packet != NULL;
192}
193
194EXPORT_SYMBOL_GPL(dccp_rx_hist_find_entry);
98struct dccp_rx_hist_entry * 195struct dccp_rx_hist_entry *
99 dccp_rx_hist_find_data_packet(const struct list_head *list) 196 dccp_rx_hist_find_data_packet(const struct list_head *list)
100{ 197{
@@ -184,110 +281,18 @@ void dccp_rx_hist_add_packet(struct dccp_rx_hist *hist,
184 281
185EXPORT_SYMBOL_GPL(dccp_rx_hist_add_packet); 282EXPORT_SYMBOL_GPL(dccp_rx_hist_add_packet);
186 283
187struct dccp_tx_hist *dccp_tx_hist_new(const char *name) 284void dccp_rx_hist_purge(struct dccp_rx_hist *hist, struct list_head *list)
188{
189 struct dccp_tx_hist *hist = kmalloc(sizeof(*hist), GFP_ATOMIC);
190 static const char dccp_tx_hist_mask[] = "tx_hist_%s";
191 char *slab_name;
192
193 if (hist == NULL)
194 goto out;
195
196 slab_name = kmalloc(strlen(name) + sizeof(dccp_tx_hist_mask) - 1,
197 GFP_ATOMIC);
198 if (slab_name == NULL)
199 goto out_free_hist;
200
201 sprintf(slab_name, dccp_tx_hist_mask, name);
202 hist->dccptxh_slab = kmem_cache_create(slab_name,
203 sizeof(struct dccp_tx_hist_entry),
204 0, SLAB_HWCACHE_ALIGN,
205 NULL, NULL);
206 if (hist->dccptxh_slab == NULL)
207 goto out_free_slab_name;
208out:
209 return hist;
210out_free_slab_name:
211 kfree(slab_name);
212out_free_hist:
213 kfree(hist);
214 hist = NULL;
215 goto out;
216}
217
218EXPORT_SYMBOL_GPL(dccp_tx_hist_new);
219
220void dccp_tx_hist_delete(struct dccp_tx_hist *hist)
221{
222 const char* name = kmem_cache_name(hist->dccptxh_slab);
223
224 kmem_cache_destroy(hist->dccptxh_slab);
225 kfree(name);
226 kfree(hist);
227}
228
229EXPORT_SYMBOL_GPL(dccp_tx_hist_delete);
230
231struct dccp_tx_hist_entry *
232 dccp_tx_hist_find_entry(const struct list_head *list, const u64 seq)
233{
234 struct dccp_tx_hist_entry *packet = NULL, *entry;
235
236 list_for_each_entry(entry, list, dccphtx_node)
237 if (entry->dccphtx_seqno == seq) {
238 packet = entry;
239 break;
240 }
241
242 return packet;
243}
244
245EXPORT_SYMBOL_GPL(dccp_tx_hist_find_entry);
246
247int dccp_rx_hist_find_entry(const struct list_head *list, const u64 seq,
248 u8 *ccval)
249{
250 struct dccp_rx_hist_entry *packet = NULL, *entry;
251
252 list_for_each_entry(entry, list, dccphrx_node)
253 if (entry->dccphrx_seqno == seq) {
254 packet = entry;
255 break;
256 }
257
258 if (packet)
259 *ccval = packet->dccphrx_ccval;
260
261 return packet != NULL;
262}
263
264EXPORT_SYMBOL_GPL(dccp_rx_hist_find_entry);
265
266void dccp_tx_hist_purge_older(struct dccp_tx_hist *hist,
267 struct list_head *list,
268 struct dccp_tx_hist_entry *packet)
269{ 285{
270 struct dccp_tx_hist_entry *next; 286 struct dccp_rx_hist_entry *entry, *next;
271 287
272 list_for_each_entry_safe_continue(packet, next, list, dccphtx_node) { 288 list_for_each_entry_safe(entry, next, list, dccphrx_node) {
273 list_del_init(&packet->dccphtx_node); 289 list_del_init(&entry->dccphrx_node);
274 dccp_tx_hist_entry_delete(hist, packet); 290 kmem_cache_free(hist->dccprxh_slab, entry);
275 } 291 }
276} 292}
277 293
278EXPORT_SYMBOL_GPL(dccp_tx_hist_purge_older); 294EXPORT_SYMBOL_GPL(dccp_rx_hist_purge);
279
280void dccp_tx_hist_purge(struct dccp_tx_hist *hist, struct list_head *list)
281{
282 struct dccp_tx_hist_entry *entry, *next;
283
284 list_for_each_entry_safe(entry, next, list, dccphtx_node) {
285 list_del_init(&entry->dccphtx_node);
286 dccp_tx_hist_entry_delete(hist, entry);
287 }
288}
289 295
290EXPORT_SYMBOL_GPL(dccp_tx_hist_purge);
291 296
292MODULE_AUTHOR("Ian McDonald <ian.mcdonald@jandi.co.nz>, " 297MODULE_AUTHOR("Ian McDonald <ian.mcdonald@jandi.co.nz>, "
293 "Arnaldo Carvalho de Melo <acme@ghostprotocols.net>"); 298 "Arnaldo Carvalho de Melo <acme@ghostprotocols.net>");
diff --git a/net/dccp/ccids/lib/packet_history.h b/net/dccp/ccids/lib/packet_history.h
index 067cf1c85a..1f960c19ea 100644
--- a/net/dccp/ccids/lib/packet_history.h
+++ b/net/dccp/ccids/lib/packet_history.h
@@ -49,43 +49,27 @@
49#define TFRC_WIN_COUNT_PER_RTT 4 49#define TFRC_WIN_COUNT_PER_RTT 4
50#define TFRC_WIN_COUNT_LIMIT 16 50#define TFRC_WIN_COUNT_LIMIT 16
51 51
52/*
53 * Transmitter History data structures and declarations
54 */
52struct dccp_tx_hist_entry { 55struct dccp_tx_hist_entry {
53 struct list_head dccphtx_node; 56 struct list_head dccphtx_node;
54 u64 dccphtx_seqno:48, 57 u64 dccphtx_seqno:48,
55 dccphtx_ccval:4,
56 dccphtx_sent:1; 58 dccphtx_sent:1;
57 u32 dccphtx_rtt; 59 u32 dccphtx_rtt;
58 struct timeval dccphtx_tstamp; 60 struct timeval dccphtx_tstamp;
59}; 61};
60 62
61struct dccp_rx_hist_entry {
62 struct list_head dccphrx_node;
63 u64 dccphrx_seqno:48,
64 dccphrx_ccval:4,
65 dccphrx_type:4;
66 u32 dccphrx_ndp; /* In fact it is from 8 to 24 bits */
67 struct timeval dccphrx_tstamp;
68};
69
70struct dccp_tx_hist { 63struct dccp_tx_hist {
71 kmem_cache_t *dccptxh_slab; 64 struct kmem_cache *dccptxh_slab;
72}; 65};
73 66
74extern struct dccp_tx_hist *dccp_tx_hist_new(const char *name); 67extern struct dccp_tx_hist *dccp_tx_hist_new(const char *name);
75extern void dccp_tx_hist_delete(struct dccp_tx_hist *hist); 68extern void dccp_tx_hist_delete(struct dccp_tx_hist *hist);
76
77struct dccp_rx_hist {
78 kmem_cache_t *dccprxh_slab;
79};
80
81extern struct dccp_rx_hist *dccp_rx_hist_new(const char *name);
82extern void dccp_rx_hist_delete(struct dccp_rx_hist *hist);
83extern struct dccp_rx_hist_entry *
84 dccp_rx_hist_find_data_packet(const struct list_head *list);
85 69
86static inline struct dccp_tx_hist_entry * 70static inline struct dccp_tx_hist_entry *
87 dccp_tx_hist_entry_new(struct dccp_tx_hist *hist, 71 dccp_tx_hist_entry_new(struct dccp_tx_hist *hist,
88 const gfp_t prio) 72 const gfp_t prio)
89{ 73{
90 struct dccp_tx_hist_entry *entry = kmem_cache_alloc(hist->dccptxh_slab, 74 struct dccp_tx_hist_entry *entry = kmem_cache_alloc(hist->dccptxh_slab,
91 prio); 75 prio);
@@ -96,18 +80,20 @@ static inline struct dccp_tx_hist_entry *
96 return entry; 80 return entry;
97} 81}
98 82
99static inline void dccp_tx_hist_entry_delete(struct dccp_tx_hist *hist, 83static inline struct dccp_tx_hist_entry *
100 struct dccp_tx_hist_entry *entry) 84 dccp_tx_hist_head(struct list_head *list)
101{ 85{
102 if (entry != NULL) 86 struct dccp_tx_hist_entry *head = NULL;
103 kmem_cache_free(hist->dccptxh_slab, entry); 87
88 if (!list_empty(list))
89 head = list_entry(list->next, struct dccp_tx_hist_entry,
90 dccphtx_node);
91 return head;
104} 92}
105 93
106extern struct dccp_tx_hist_entry * 94extern struct dccp_tx_hist_entry *
107 dccp_tx_hist_find_entry(const struct list_head *list, 95 dccp_tx_hist_find_entry(const struct list_head *list,
108 const u64 seq); 96 const u64 seq);
109extern int dccp_rx_hist_find_entry(const struct list_head *list, const u64 seq,
110 u8 *ccval);
111 97
112static inline void dccp_tx_hist_add_entry(struct list_head *list, 98static inline void dccp_tx_hist_add_entry(struct list_head *list,
113 struct dccp_tx_hist_entry *entry) 99 struct dccp_tx_hist_entry *entry)
@@ -115,30 +101,45 @@ static inline void dccp_tx_hist_add_entry(struct list_head *list,
115 list_add(&entry->dccphtx_node, list); 101 list_add(&entry->dccphtx_node, list);
116} 102}
117 103
104static inline void dccp_tx_hist_entry_delete(struct dccp_tx_hist *hist,
105 struct dccp_tx_hist_entry *entry)
106{
107 if (entry != NULL)
108 kmem_cache_free(hist->dccptxh_slab, entry);
109}
110
111extern void dccp_tx_hist_purge(struct dccp_tx_hist *hist,
112 struct list_head *list);
113
118extern void dccp_tx_hist_purge_older(struct dccp_tx_hist *hist, 114extern void dccp_tx_hist_purge_older(struct dccp_tx_hist *hist,
119 struct list_head *list, 115 struct list_head *list,
120 struct dccp_tx_hist_entry *next); 116 struct dccp_tx_hist_entry *next);
121 117
122extern void dccp_tx_hist_purge(struct dccp_tx_hist *hist, 118/*
123 struct list_head *list); 119 * Receiver History data structures and declarations
120 */
121struct dccp_rx_hist_entry {
122 struct list_head dccphrx_node;
123 u64 dccphrx_seqno:48,
124 dccphrx_ccval:4,
125 dccphrx_type:4;
126 u32 dccphrx_ndp; /* In fact it is from 8 to 24 bits */
127 struct timeval dccphrx_tstamp;
128};
124 129
125static inline struct dccp_tx_hist_entry * 130struct dccp_rx_hist {
126 dccp_tx_hist_head(struct list_head *list) 131 struct kmem_cache *dccprxh_slab;
127{ 132};
128 struct dccp_tx_hist_entry *head = NULL;
129 133
130 if (!list_empty(list)) 134extern struct dccp_rx_hist *dccp_rx_hist_new(const char *name);
131 head = list_entry(list->next, struct dccp_tx_hist_entry, 135extern void dccp_rx_hist_delete(struct dccp_rx_hist *hist);
132 dccphtx_node);
133 return head;
134}
135 136
136static inline struct dccp_rx_hist_entry * 137static inline struct dccp_rx_hist_entry *
137 dccp_rx_hist_entry_new(struct dccp_rx_hist *hist, 138 dccp_rx_hist_entry_new(struct dccp_rx_hist *hist,
138 const struct sock *sk, 139 const struct sock *sk,
139 const u32 ndp, 140 const u32 ndp,
140 const struct sk_buff *skb, 141 const struct sk_buff *skb,
141 const gfp_t prio) 142 const gfp_t prio)
142{ 143{
143 struct dccp_rx_hist_entry *entry = kmem_cache_alloc(hist->dccprxh_slab, 144 struct dccp_rx_hist_entry *entry = kmem_cache_alloc(hist->dccprxh_slab,
144 prio); 145 prio);
@@ -156,18 +157,8 @@ static inline struct dccp_rx_hist_entry *
156 return entry; 157 return entry;
157} 158}
158 159
159static inline void dccp_rx_hist_entry_delete(struct dccp_rx_hist *hist,
160 struct dccp_rx_hist_entry *entry)
161{
162 if (entry != NULL)
163 kmem_cache_free(hist->dccprxh_slab, entry);
164}
165
166extern void dccp_rx_hist_purge(struct dccp_rx_hist *hist,
167 struct list_head *list);
168
169static inline struct dccp_rx_hist_entry * 160static inline struct dccp_rx_hist_entry *
170 dccp_rx_hist_head(struct list_head *list) 161 dccp_rx_hist_head(struct list_head *list)
171{ 162{
172 struct dccp_rx_hist_entry *head = NULL; 163 struct dccp_rx_hist_entry *head = NULL;
173 164
@@ -177,6 +168,27 @@ static inline struct dccp_rx_hist_entry *
177 return head; 168 return head;
178} 169}
179 170
171extern int dccp_rx_hist_find_entry(const struct list_head *list, const u64 seq,
172 u8 *ccval);
173extern struct dccp_rx_hist_entry *
174 dccp_rx_hist_find_data_packet(const struct list_head *list);
175
176extern void dccp_rx_hist_add_packet(struct dccp_rx_hist *hist,
177 struct list_head *rx_list,
178 struct list_head *li_list,
179 struct dccp_rx_hist_entry *packet,
180 u64 nonloss_seqno);
181
182static inline void dccp_rx_hist_entry_delete(struct dccp_rx_hist *hist,
183 struct dccp_rx_hist_entry *entry)
184{
185 if (entry != NULL)
186 kmem_cache_free(hist->dccprxh_slab, entry);
187}
188
189extern void dccp_rx_hist_purge(struct dccp_rx_hist *hist,
190 struct list_head *list);
191
180static inline int 192static inline int
181 dccp_rx_hist_entry_data_packet(const struct dccp_rx_hist_entry *entry) 193 dccp_rx_hist_entry_data_packet(const struct dccp_rx_hist_entry *entry)
182{ 194{
@@ -184,12 +196,6 @@ static inline int
184 entry->dccphrx_type == DCCP_PKT_DATAACK; 196 entry->dccphrx_type == DCCP_PKT_DATAACK;
185} 197}
186 198
187extern void dccp_rx_hist_add_packet(struct dccp_rx_hist *hist,
188 struct list_head *rx_list,
189 struct list_head *li_list,
190 struct dccp_rx_hist_entry *packet,
191 u64 nonloss_seqno);
192
193extern u64 dccp_rx_hist_detect_loss(struct list_head *rx_list, 199extern u64 dccp_rx_hist_detect_loss(struct list_head *rx_list,
194 struct list_head *li_list, u8 *win_loss); 200 struct list_head *li_list, u8 *win_loss);
195 201
diff --git a/net/dccp/ccids/lib/tfrc.h b/net/dccp/ccids/lib/tfrc.h
index 45f30f59ea..faf5f7e219 100644
--- a/net/dccp/ccids/lib/tfrc.h
+++ b/net/dccp/ccids/lib/tfrc.h
@@ -13,8 +13,29 @@
13 * the Free Software Foundation; either version 2 of the License, or 13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version. 14 * (at your option) any later version.
15 */ 15 */
16
17#include <linux/types.h> 16#include <linux/types.h>
17#include <asm/div64.h>
18
19/* integer-arithmetic divisions of type (a * 1000000)/b */
20static inline u64 scaled_div(u64 a, u32 b)
21{
22 BUG_ON(b==0);
23 a *= 1000000;
24 do_div(a, b);
25 return a;
26}
27
28static inline u32 scaled_div32(u64 a, u32 b)
29{
30 u64 result = scaled_div(a, b);
31
32 if (result > UINT_MAX) {
33 DCCP_CRIT("Overflow: a(%llu)/b(%u) > ~0U",
34 (unsigned long long)a, b);
35 return UINT_MAX;
36 }
37 return result;
38}
18 39
19extern u32 tfrc_calc_x(u16 s, u32 R, u32 p); 40extern u32 tfrc_calc_x(u16 s, u32 R, u32 p);
20extern u32 tfrc_calc_x_reverse_lookup(u32 fvalue); 41extern u32 tfrc_calc_x_reverse_lookup(u32 fvalue);
diff --git a/net/dccp/ccids/lib/tfrc_equation.c b/net/dccp/ccids/lib/tfrc_equation.c
index 44076e0c65..90009fd77e 100644
--- a/net/dccp/ccids/lib/tfrc_equation.c
+++ b/net/dccp/ccids/lib/tfrc_equation.c
@@ -13,16 +13,83 @@
13 */ 13 */
14 14
15#include <linux/module.h> 15#include <linux/module.h>
16 16#include "../../dccp.h"
17#include <asm/div64.h>
18
19#include "tfrc.h" 17#include "tfrc.h"
20 18
21#define TFRC_CALC_X_ARRSIZE 500 19#define TFRC_CALC_X_ARRSIZE 500
20#define TFRC_CALC_X_SPLIT 50000 /* 0.05 * 1000000, details below */
21#define TFRC_SMALLEST_P (TFRC_CALC_X_SPLIT/TFRC_CALC_X_ARRSIZE)
22 22
23#define TFRC_CALC_X_SPLIT 50000 23/*
24/* equivalent to 0.05 */ 24 TFRC TCP Reno Throughput Equation Lookup Table for f(p)
25 25
26 The following two-column lookup table implements a part of the TCP throughput
27 equation from [RFC 3448, sec. 3.1]:
28
29 s
30 X_calc = --------------------------------------------------------------
31 R * sqrt(2*b*p/3) + (3 * t_RTO * sqrt(3*b*p/8) * (p + 32*p^3))
32
33 Where:
34 X is the transmit rate in bytes/second
35 s is the packet size in bytes
36 R is the round trip time in seconds
37 p is the loss event rate, between 0 and 1.0, of the number of loss
38 events as a fraction of the number of packets transmitted
39 t_RTO is the TCP retransmission timeout value in seconds
40 b is the number of packets acknowledged by a single TCP ACK
41
42 We can assume that b = 1 and t_RTO is 4 * R. The equation now becomes:
43
44 s
45 X_calc = -------------------------------------------------------
46 R * sqrt(p*2/3) + (12 * R * sqrt(p*3/8) * (p + 32*p^3))
47
48 which we can break down into:
49
50 s
51 X_calc = ---------
52 R * f(p)
53
54 where f(p) is given for 0 < p <= 1 by:
55
56 f(p) = sqrt(2*p/3) + 12 * sqrt(3*p/8) * (p + 32*p^3)
57
58 Since this is kernel code, floating-point arithmetic is avoided in favour of
59 integer arithmetic. This means that nearly all fractional parameters are
60 scaled by 1000000:
61 * the parameters p and R
62 * the return result f(p)
63 The lookup table therefore actually tabulates the following function g(q):
64
65 g(q) = 1000000 * f(q/1000000)
66
67 Hence, when p <= 1, q must be less than or equal to 1000000. To achieve finer
68 granularity for the practically more relevant case of small values of p (up to
69 5%), the second column is used; the first one ranges up to 100%. This split
70 corresponds to the value of q = TFRC_CALC_X_SPLIT. At the same time this also
71 determines the smallest resolution possible with this lookup table:
72
73 TFRC_SMALLEST_P = TFRC_CALC_X_SPLIT / TFRC_CALC_X_ARRSIZE
74
75 The entire table is generated by:
76 for(i=0; i < TFRC_CALC_X_ARRSIZE; i++) {
77 lookup[i][0] = g((i+1) * 1000000/TFRC_CALC_X_ARRSIZE);
78 lookup[i][1] = g((i+1) * TFRC_CALC_X_SPLIT/TFRC_CALC_X_ARRSIZE);
79 }
80
81 With the given configuration, we have, with M = TFRC_CALC_X_ARRSIZE-1,
82 lookup[0][0] = g(1000000/(M+1)) = 1000000 * f(0.2%)
83 lookup[M][0] = g(1000000) = 1000000 * f(100%)
84 lookup[0][1] = g(TFRC_SMALLEST_P) = 1000000 * f(0.01%)
85 lookup[M][1] = g(TFRC_CALC_X_SPLIT) = 1000000 * f(5%)
86
87 In summary, the two columns represent f(p) for the following ranges:
88 * The first column is for 0.002 <= p <= 1.0
89 * The second column is for 0.0001 <= p <= 0.05
90 Where the columns overlap, the second (finer-grained) is given preference,
91 i.e. the first column is used only for p >= 0.05.
92 */
26static const u32 tfrc_calc_x_lookup[TFRC_CALC_X_ARRSIZE][2] = { 93static const u32 tfrc_calc_x_lookup[TFRC_CALC_X_ARRSIZE][2] = {
27 { 37172, 8172 }, 94 { 37172, 8172 },
28 { 53499, 11567 }, 95 { 53499, 11567 },
@@ -526,117 +593,105 @@ static const u32 tfrc_calc_x_lookup[TFRC_CALC_X_ARRSIZE][2] = {
526 { 243315981, 271305 } 593 { 243315981, 271305 }
527}; 594};
528 595
529/* Calculate the send rate as per section 3.1 of RFC3448 596/* return largest index i such that fval <= lookup[i][small] */
530 597static inline u32 tfrc_binsearch(u32 fval, u8 small)
531Returns send rate in bytes per second 598{
532 599 u32 try, low = 0, high = TFRC_CALC_X_ARRSIZE - 1;
533Integer maths and lookups are used as not allowed floating point in kernel 600
534 601 while (low < high) {
535The function for Xcalc as per section 3.1 of RFC3448 is: 602 try = (low + high) / 2;
536 603 if (fval <= tfrc_calc_x_lookup[try][small])
537X = s 604 high = try;
538 ------------------------------------------------------------- 605 else
539 R*sqrt(2*b*p/3) + (t_RTO * (3*sqrt(3*b*p/8) * p * (1+32*p^2))) 606 low = try + 1;
540 607 }
541where 608 return high;
542X is the trasmit rate in bytes/second 609}
543s is the packet size in bytes
544R is the round trip time in seconds
545p is the loss event rate, between 0 and 1.0, of the number of loss events
546 as a fraction of the number of packets transmitted
547t_RTO is the TCP retransmission timeout value in seconds
548b is the number of packets acknowledged by a single TCP acknowledgement
549
550we can assume that b = 1 and t_RTO is 4 * R. With this the equation becomes:
551
552X = s
553 -----------------------------------------------------------------------
554 R * sqrt(2 * p / 3) + (12 * R * (sqrt(3 * p / 8) * p * (1 + 32 * p^2)))
555
556
557which we can break down into:
558
559X = s
560 --------
561 R * f(p)
562
563where f(p) = sqrt(2 * p / 3) + (12 * sqrt(3 * p / 8) * p * (1 + 32 * p * p))
564
565Function parameters:
566s - bytes
567R - RTT in usecs
568p - loss rate (decimal fraction multiplied by 1,000,000)
569
570Returns Xcalc in bytes per second
571
572DON'T alter this code unless you run test cases against it as the code
573has been manipulated to stop underflow/overlow.
574 610
575*/ 611/**
612 * tfrc_calc_x - Calculate the send rate as per section 3.1 of RFC3448
613 *
614 * @s: packet size in bytes
615 * @R: RTT scaled by 1000000 (i.e., microseconds)
616 * @p: loss ratio estimate scaled by 1000000
617 * Returns X_calc in bytes per second (not scaled).
618 */
576u32 tfrc_calc_x(u16 s, u32 R, u32 p) 619u32 tfrc_calc_x(u16 s, u32 R, u32 p)
577{ 620{
578 int index; 621 u16 index;
579 u32 f; 622 u32 f;
580 u64 tmp1, tmp2; 623 u64 result;
581 624
582 if (p < TFRC_CALC_X_SPLIT) 625 /* check against invalid parameters and divide-by-zero */
583 index = (p / (TFRC_CALC_X_SPLIT / TFRC_CALC_X_ARRSIZE)) - 1; 626 BUG_ON(p > 1000000); /* p must not exceed 100% */
584 else 627 BUG_ON(p == 0); /* f(0) = 0, divide by zero */
585 index = (p / (1000000 / TFRC_CALC_X_ARRSIZE)) - 1; 628 if (R == 0) { /* possible divide by zero */
629 DCCP_CRIT("WARNING: RTT is 0, returning maximum X_calc.");
630 return ~0U;
631 }
586 632
587 if (index < 0) 633 if (p <= TFRC_CALC_X_SPLIT) { /* 0.0000 < p <= 0.05 */
588 /* p should be 0 unless there is a bug in my code */ 634 if (p < TFRC_SMALLEST_P) { /* 0.0000 < p < 0.0001 */
589 index = 0; 635 DCCP_WARN("Value of p (%d) below resolution. "
636 "Substituting %d\n", p, TFRC_SMALLEST_P);
637 index = 0;
638 } else /* 0.0001 <= p <= 0.05 */
639 index = p/TFRC_SMALLEST_P - 1;
590 640
591 if (R == 0) 641 f = tfrc_calc_x_lookup[index][1];
592 R = 1; /* RTT can't be zero or else divide by zero */
593 642
594 BUG_ON(index >= TFRC_CALC_X_ARRSIZE); 643 } else { /* 0.05 < p <= 1.00 */
644 index = p/(1000000/TFRC_CALC_X_ARRSIZE) - 1;
595 645
596 if (p >= TFRC_CALC_X_SPLIT)
597 f = tfrc_calc_x_lookup[index][0]; 646 f = tfrc_calc_x_lookup[index][0];
598 else 647 }
599 f = tfrc_calc_x_lookup[index][1]; 648
600 649 /*
601 tmp1 = ((u64)s * 100000000); 650 * Compute X = s/(R*f(p)) in bytes per second.
602 tmp2 = ((u64)R * (u64)f); 651 * Since f(p) and R are both scaled by 1000000, we need to multiply by
603 do_div(tmp2, 10000); 652 * 1000000^2. To avoid overflow, the result is computed in two stages.
604 do_div(tmp1, tmp2); 653 * This works under almost all reasonable operational conditions, for a
605 /* Don't alter above math unless you test due to overflow on 32 bit */ 654 * wide range of parameters. Yet, should some strange combination of
606 655 * parameters result in overflow, the use of scaled_div32 will catch
607 return (u32)tmp1; 656 * this and return UINT_MAX - which is a logically adequate consequence.
657 */
658 result = scaled_div(s, R);
659 return scaled_div32(result, f);
608} 660}
609 661
610EXPORT_SYMBOL_GPL(tfrc_calc_x); 662EXPORT_SYMBOL_GPL(tfrc_calc_x);
611 663
612/* 664/*
613 * args: fvalue - function value to match 665 * tfrc_calc_x_reverse_lookup - try to find p given f(p)
614 * returns: p closest to that value
615 * 666 *
616 * both fvalue and p are multiplied by 1,000,000 to use ints 667 * @fvalue: function value to match, scaled by 1000000
668 * Returns closest match for p, also scaled by 1000000
617 */ 669 */
618u32 tfrc_calc_x_reverse_lookup(u32 fvalue) 670u32 tfrc_calc_x_reverse_lookup(u32 fvalue)
619{ 671{
620 int ctr = 0; 672 int index;
621 int small;
622 673
623 if (fvalue < tfrc_calc_x_lookup[0][1]) 674 if (fvalue == 0) /* f(p) = 0 whenever p = 0 */
624 return 0; 675 return 0;
625 676
626 if (fvalue <= tfrc_calc_x_lookup[TFRC_CALC_X_ARRSIZE - 1][1]) 677 /* Error cases. */
627 small = 1; 678 if (fvalue < tfrc_calc_x_lookup[0][1]) {
628 else if (fvalue > tfrc_calc_x_lookup[TFRC_CALC_X_ARRSIZE - 1][0]) 679 DCCP_WARN("fvalue %d smaller than resolution\n", fvalue);
680 return tfrc_calc_x_lookup[0][1];
681 }
682 if (fvalue > tfrc_calc_x_lookup[TFRC_CALC_X_ARRSIZE - 1][0]) {
683 DCCP_WARN("fvalue %d exceeds bounds!\n", fvalue);
629 return 1000000; 684 return 1000000;
630 else 685 }
631 small = 0;
632
633 while (fvalue > tfrc_calc_x_lookup[ctr][small])
634 ctr++;
635 686
636 if (small) 687 if (fvalue <= tfrc_calc_x_lookup[TFRC_CALC_X_ARRSIZE - 1][1]) {
637 return TFRC_CALC_X_SPLIT * ctr / TFRC_CALC_X_ARRSIZE; 688 index = tfrc_binsearch(fvalue, 1);
638 else 689 return (index + 1) * TFRC_CALC_X_SPLIT / TFRC_CALC_X_ARRSIZE;
639 return 1000000 * ctr / TFRC_CALC_X_ARRSIZE; 690 }
691
692 /* else ... it must be in the coarse-grained column */
693 index = tfrc_binsearch(fvalue, 0);
694 return (index + 1) * 1000000 / TFRC_CALC_X_ARRSIZE;
640} 695}
641 696
642EXPORT_SYMBOL_GPL(tfrc_calc_x_reverse_lookup); 697EXPORT_SYMBOL_GPL(tfrc_calc_x_reverse_lookup);
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index 272e858456..a0900bf98e 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -18,15 +18,33 @@
18#include <net/tcp.h> 18#include <net/tcp.h>
19#include "ackvec.h" 19#include "ackvec.h"
20 20
21/*
22 * DCCP - specific warning and debugging macros.
23 */
24#define DCCP_WARN(fmt, a...) LIMIT_NETDEBUG(KERN_WARNING "%s: " fmt, \
25 __FUNCTION__, ##a)
26#define DCCP_CRIT(fmt, a...) printk(KERN_CRIT fmt " at %s:%d/%s()\n", ##a, \
27 __FILE__, __LINE__, __FUNCTION__)
28#define DCCP_BUG(a...) do { DCCP_CRIT("BUG: " a); dump_stack(); } while(0)
29#define DCCP_BUG_ON(cond) do { if (unlikely((cond) != 0)) \
30 DCCP_BUG("\"%s\" holds (exception!)", \
31 __stringify(cond)); \
32 } while (0)
33
34#ifdef MODULE
35#define DCCP_PRINTK(enable, fmt, args...) do { if (enable) \
36 printk(fmt, ##args); \
37 } while(0)
38#else
39#define DCCP_PRINTK(enable, fmt, args...) printk(fmt, ##args)
40#endif
41#define DCCP_PR_DEBUG(enable, fmt, a...) DCCP_PRINTK(enable, KERN_DEBUG \
42 "%s: " fmt, __FUNCTION__, ##a)
43
21#ifdef CONFIG_IP_DCCP_DEBUG 44#ifdef CONFIG_IP_DCCP_DEBUG
22extern int dccp_debug; 45extern int dccp_debug;
23 46#define dccp_pr_debug(format, a...) DCCP_PR_DEBUG(dccp_debug, format, ##a)
24#define dccp_pr_debug(format, a...) \ 47#define dccp_pr_debug_cat(format, a...) DCCP_PRINTK(dccp_debug, format, ##a)
25 do { if (dccp_debug) \
26 printk(KERN_DEBUG "%s: " format, __FUNCTION__ , ##a); \
27 } while (0)
28#define dccp_pr_debug_cat(format, a...) do { if (dccp_debug) \
29 printk(format, ##a); } while (0)
30#else 48#else
31#define dccp_pr_debug(format, a...) 49#define dccp_pr_debug(format, a...)
32#define dccp_pr_debug_cat(format, a...) 50#define dccp_pr_debug_cat(format, a...)
@@ -35,17 +53,21 @@ extern int dccp_debug;
35extern struct inet_hashinfo dccp_hashinfo; 53extern struct inet_hashinfo dccp_hashinfo;
36 54
37extern atomic_t dccp_orphan_count; 55extern atomic_t dccp_orphan_count;
38extern int dccp_tw_count;
39extern void dccp_tw_deschedule(struct inet_timewait_sock *tw);
40 56
41extern void dccp_time_wait(struct sock *sk, int state, int timeo); 57extern void dccp_time_wait(struct sock *sk, int state, int timeo);
42 58
43/* FIXME: Right size this */ 59/*
44#define DCCP_MAX_OPT_LEN 128 60 * Set safe upper bounds for header and option length. Since Data Offset is 8
45 61 * bits (RFC 4340, sec. 5.1), the total header length can never be more than
46#define DCCP_MAX_PACKET_HDR 32 62 * 4 * 255 = 1020 bytes. The largest possible header length is 28 bytes (X=1):
47 63 * - DCCP-Response with ACK Subheader and 4 bytes of Service code OR
48#define MAX_DCCP_HEADER (DCCP_MAX_PACKET_HDR + DCCP_MAX_OPT_LEN + MAX_HEADER) 64 * - DCCP-Reset with ACK Subheader and 4 bytes of Reset Code fields
65 * Hence a safe upper bound for the maximum option length is 1020-28 = 992
66 */
67#define MAX_DCCP_SPECIFIC_HEADER (255 * sizeof(int))
68#define DCCP_MAX_PACKET_HDR 28
69#define DCCP_MAX_OPT_LEN (MAX_DCCP_SPECIFIC_HEADER - DCCP_MAX_PACKET_HDR)
70#define MAX_DCCP_HEADER (MAX_DCCP_SPECIFIC_HEADER + MAX_HEADER)
49 71
50#define DCCP_TIMEWAIT_LEN (60 * HZ) /* how long to wait to destroy TIME-WAIT 72#define DCCP_TIMEWAIT_LEN (60 * HZ) /* how long to wait to destroy TIME-WAIT
51 * state, about 60 seconds */ 73 * state, about 60 seconds */
@@ -58,6 +80,18 @@ extern void dccp_time_wait(struct sock *sk, int state, int timeo);
58 80
59#define DCCP_RTO_MAX ((unsigned)(120 * HZ)) /* FIXME: using TCP value */ 81#define DCCP_RTO_MAX ((unsigned)(120 * HZ)) /* FIXME: using TCP value */
60 82
83/* sysctl variables for DCCP */
84extern int sysctl_dccp_request_retries;
85extern int sysctl_dccp_retries1;
86extern int sysctl_dccp_retries2;
87extern int sysctl_dccp_feat_sequence_window;
88extern int sysctl_dccp_feat_rx_ccid;
89extern int sysctl_dccp_feat_tx_ccid;
90extern int sysctl_dccp_feat_ack_ratio;
91extern int sysctl_dccp_feat_send_ack_vector;
92extern int sysctl_dccp_feat_send_ndp_count;
93extern int sysctl_dccp_tx_qlen;
94
61/* is seq1 < seq2 ? */ 95/* is seq1 < seq2 ? */
62static inline int before48(const u64 seq1, const u64 seq2) 96static inline int before48(const u64 seq1, const u64 seq2)
63{ 97{
@@ -123,10 +157,36 @@ DECLARE_SNMP_STAT(struct dccp_mib, dccp_statistics);
123#define DCCP_ADD_STATS_USER(field, val) \ 157#define DCCP_ADD_STATS_USER(field, val) \
124 SNMP_ADD_STATS_USER(dccp_statistics, field, val) 158 SNMP_ADD_STATS_USER(dccp_statistics, field, val)
125 159
160/*
161 * Checksumming routines
162 */
163static inline int dccp_csum_coverage(const struct sk_buff *skb)
164{
165 const struct dccp_hdr* dh = dccp_hdr(skb);
166
167 if (dh->dccph_cscov == 0)
168 return skb->len;
169 return (dh->dccph_doff + dh->dccph_cscov - 1) * sizeof(u32);
170}
171
172static inline void dccp_csum_outgoing(struct sk_buff *skb)
173{
174 int cov = dccp_csum_coverage(skb);
175
176 if (cov >= skb->len)
177 dccp_hdr(skb)->dccph_cscov = 0;
178
179 skb->csum = skb_checksum(skb, 0, (cov > skb->len)? skb->len : cov, 0);
180}
181
182extern void dccp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb);
183
126extern int dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb); 184extern int dccp_retransmit_skb(struct sock *sk, struct sk_buff *skb);
127 185
128extern void dccp_send_ack(struct sock *sk); 186extern void dccp_send_ack(struct sock *sk);
129extern void dccp_send_delayed_ack(struct sock *sk); 187extern void dccp_send_delayed_ack(struct sock *sk);
188extern void dccp_reqsk_send_ack(struct sk_buff *sk, struct request_sock *rsk);
189
130extern void dccp_send_sync(struct sock *sk, const u64 seq, 190extern void dccp_send_sync(struct sock *sk, const u64 seq,
131 const enum dccp_pkt_type pkt_type); 191 const enum dccp_pkt_type pkt_type);
132 192
@@ -147,18 +207,7 @@ extern const char *dccp_state_name(const int state);
147extern void dccp_set_state(struct sock *sk, const int state); 207extern void dccp_set_state(struct sock *sk, const int state);
148extern void dccp_done(struct sock *sk); 208extern void dccp_done(struct sock *sk);
149 209
150static inline void dccp_openreq_init(struct request_sock *req, 210extern void dccp_reqsk_init(struct request_sock *req, struct sk_buff *skb);
151 struct dccp_sock *dp,
152 struct sk_buff *skb)
153{
154 /*
155 * FIXME: fill in the other req fields from the DCCP options
156 * received
157 */
158 inet_rsk(req)->rmt_port = dccp_hdr(skb)->dccph_sport;
159 inet_rsk(req)->acked = 0;
160 req->rcv_wnd = 0;
161}
162 211
163extern int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb); 212extern int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb);
164 213
@@ -217,14 +266,9 @@ extern void dccp_shutdown(struct sock *sk, int how);
217extern int inet_dccp_listen(struct socket *sock, int backlog); 266extern int inet_dccp_listen(struct socket *sock, int backlog);
218extern unsigned int dccp_poll(struct file *file, struct socket *sock, 267extern unsigned int dccp_poll(struct file *file, struct socket *sock,
219 poll_table *wait); 268 poll_table *wait);
220extern void dccp_v4_send_check(struct sock *sk, int len,
221 struct sk_buff *skb);
222extern int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, 269extern int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr,
223 int addr_len); 270 int addr_len);
224 271
225extern int dccp_v4_checksum(const struct sk_buff *skb,
226 const __be32 saddr, const __be32 daddr);
227
228extern int dccp_send_reset(struct sock *sk, enum dccp_reset_codes code); 272extern int dccp_send_reset(struct sock *sk, enum dccp_reset_codes code);
229extern void dccp_send_close(struct sock *sk, const int active); 273extern void dccp_send_close(struct sock *sk, const int active);
230extern int dccp_invalid_packet(struct sk_buff *skb); 274extern int dccp_invalid_packet(struct sk_buff *skb);
@@ -388,6 +432,7 @@ static inline void timeval_sub_usecs(struct timeval *tv,
388 tv->tv_sec--; 432 tv->tv_sec--;
389 tv->tv_usec += USEC_PER_SEC; 433 tv->tv_usec += USEC_PER_SEC;
390 } 434 }
435 DCCP_BUG_ON(tv->tv_sec < 0);
391} 436}
392 437
393#ifdef CONFIG_SYSCTL 438#ifdef CONFIG_SYSCTL
diff --git a/net/dccp/feat.c b/net/dccp/feat.c
index a1b0682ee7..95b6927ec6 100644
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -12,7 +12,6 @@
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14 14
15#include "dccp.h"
16#include "ccid.h" 15#include "ccid.h"
17#include "feat.h" 16#include "feat.h"
18 17
@@ -23,9 +22,17 @@ int dccp_feat_change(struct dccp_minisock *dmsk, u8 type, u8 feature,
23{ 22{
24 struct dccp_opt_pend *opt; 23 struct dccp_opt_pend *opt;
25 24
26 dccp_pr_debug("feat change type=%d feat=%d\n", type, feature); 25 dccp_feat_debug(type, feature, *val);
27 26
28 /* XXX sanity check feat change request */ 27 if (!dccp_feat_is_valid_type(type)) {
28 DCCP_WARN("option type %d invalid in negotiation\n", type);
29 return 1;
30 }
31 if (!dccp_feat_is_valid_length(type, feature, len)) {
32 DCCP_WARN("invalid length %d\n", len);
33 return 1;
34 }
35 /* XXX add further sanity checks */
29 36
30 /* check if that feature is already being negotiated */ 37 /* check if that feature is already being negotiated */
31 list_for_each_entry(opt, &dmsk->dccpms_pending, dccpop_node) { 38 list_for_each_entry(opt, &dmsk->dccpms_pending, dccpop_node) {
@@ -95,14 +102,14 @@ static int dccp_feat_update_ccid(struct sock *sk, u8 type, u8 new_ccid_nr)
95/* XXX taking only u8 vals */ 102/* XXX taking only u8 vals */
96static int dccp_feat_update(struct sock *sk, u8 type, u8 feat, u8 val) 103static int dccp_feat_update(struct sock *sk, u8 type, u8 feat, u8 val)
97{ 104{
98 dccp_pr_debug("changing [%d] feat %d to %d\n", type, feat, val); 105 dccp_feat_debug(type, feat, val);
99 106
100 switch (feat) { 107 switch (feat) {
101 case DCCPF_CCID: 108 case DCCPF_CCID:
102 return dccp_feat_update_ccid(sk, type, val); 109 return dccp_feat_update_ccid(sk, type, val);
103 default: 110 default:
104 dccp_pr_debug("IMPLEMENT changing [%d] feat %d to %d\n", 111 dccp_pr_debug("UNIMPLEMENTED: %s(%d, ...)\n",
105 type, feat, val); 112 dccp_feat_typename(type), feat);
106 break; 113 break;
107 } 114 }
108 return 0; 115 return 0;
@@ -162,7 +169,8 @@ static int dccp_feat_reconcile(struct sock *sk, struct dccp_opt_pend *opt,
162 break; 169 break;
163 170
164 default: 171 default:
165 WARN_ON(1); /* XXX implement res */ 172 DCCP_BUG("Fell through, feat=%d", opt->dccpop_feat);
173 /* XXX implement res */
166 return -EFAULT; 174 return -EFAULT;
167 } 175 }
168 176
@@ -265,10 +273,10 @@ static int dccp_feat_nn(struct sock *sk, u8 type, u8 feature, u8 *val, u8 len)
265 u8 *copy; 273 u8 *copy;
266 int rc; 274 int rc;
267 275
268 /* NN features must be change L */ 276 /* NN features must be Change L (sec. 6.3.2) */
269 if (type == DCCPO_CHANGE_R) { 277 if (type != DCCPO_CHANGE_L) {
270 dccp_pr_debug("received CHANGE_R %d for NN feat %d\n", 278 dccp_pr_debug("received %s for NN feature %d\n",
271 type, feature); 279 dccp_feat_typename(type), feature);
272 return -EFAULT; 280 return -EFAULT;
273 } 281 }
274 282
@@ -279,12 +287,11 @@ static int dccp_feat_nn(struct sock *sk, u8 type, u8 feature, u8 *val, u8 len)
279 if (opt == NULL) 287 if (opt == NULL)
280 return -ENOMEM; 288 return -ENOMEM;
281 289
282 copy = kmalloc(len, GFP_ATOMIC); 290 copy = kmemdup(val, len, GFP_ATOMIC);
283 if (copy == NULL) { 291 if (copy == NULL) {
284 kfree(opt); 292 kfree(opt);
285 return -ENOMEM; 293 return -ENOMEM;
286 } 294 }
287 memcpy(copy, val, len);
288 295
289 opt->dccpop_type = DCCPO_CONFIRM_R; /* NN can only confirm R */ 296 opt->dccpop_type = DCCPO_CONFIRM_R; /* NN can only confirm R */
290 opt->dccpop_feat = feature; 297 opt->dccpop_feat = feature;
@@ -299,7 +306,8 @@ static int dccp_feat_nn(struct sock *sk, u8 type, u8 feature, u8 *val, u8 len)
299 return rc; 306 return rc;
300 } 307 }
301 308
302 dccp_pr_debug("Confirming NN feature %d (val=%d)\n", feature, *copy); 309 dccp_feat_debug(type, feature, *copy);
310
303 list_add_tail(&opt->dccpop_node, &dmsk->dccpms_conf); 311 list_add_tail(&opt->dccpop_node, &dmsk->dccpms_conf);
304 312
305 return 0; 313 return 0;
@@ -318,14 +326,19 @@ static void dccp_feat_empty_confirm(struct dccp_minisock *dmsk,
318 return; 326 return;
319 } 327 }
320 328
321 opt->dccpop_type = type == DCCPO_CHANGE_L ? DCCPO_CONFIRM_R : 329 switch (type) {
322 DCCPO_CONFIRM_L; 330 case DCCPO_CHANGE_L: opt->dccpop_type = DCCPO_CONFIRM_R; break;
331 case DCCPO_CHANGE_R: opt->dccpop_type = DCCPO_CONFIRM_L; break;
332 default: DCCP_WARN("invalid type %d\n", type); return;
333
334 }
323 opt->dccpop_feat = feature; 335 opt->dccpop_feat = feature;
324 opt->dccpop_val = NULL; 336 opt->dccpop_val = NULL;
325 opt->dccpop_len = 0; 337 opt->dccpop_len = 0;
326 338
327 /* change feature */ 339 /* change feature */
328 dccp_pr_debug("Empty confirm feature %d type %d\n", feature, type); 340 dccp_pr_debug("Empty %s(%d)\n", dccp_feat_typename(type), feature);
341
329 list_add_tail(&opt->dccpop_node, &dmsk->dccpms_conf); 342 list_add_tail(&opt->dccpop_node, &dmsk->dccpms_conf);
330} 343}
331 344
@@ -359,7 +372,7 @@ int dccp_feat_change_recv(struct sock *sk, u8 type, u8 feature, u8 *val, u8 len)
359{ 372{
360 int rc; 373 int rc;
361 374
362 dccp_pr_debug("got feat change type=%d feat=%d\n", type, feature); 375 dccp_feat_debug(type, feature, *val);
363 376
364 /* figure out if it's SP or NN feature */ 377 /* figure out if it's SP or NN feature */
365 switch (feature) { 378 switch (feature) {
@@ -375,6 +388,8 @@ int dccp_feat_change_recv(struct sock *sk, u8 type, u8 feature, u8 *val, u8 len)
375 388
376 /* XXX implement other features */ 389 /* XXX implement other features */
377 default: 390 default:
391 dccp_pr_debug("UNIMPLEMENTED: not handling %s(%d, ...)\n",
392 dccp_feat_typename(type), feature);
378 rc = -EFAULT; 393 rc = -EFAULT;
379 break; 394 break;
380 } 395 }
@@ -403,20 +418,27 @@ int dccp_feat_confirm_recv(struct sock *sk, u8 type, u8 feature,
403 u8 t; 418 u8 t;
404 struct dccp_opt_pend *opt; 419 struct dccp_opt_pend *opt;
405 struct dccp_minisock *dmsk = dccp_msk(sk); 420 struct dccp_minisock *dmsk = dccp_msk(sk);
406 int rc = 1; 421 int found = 0;
407 int all_confirmed = 1; 422 int all_confirmed = 1;
408 423
409 dccp_pr_debug("got feat confirm type=%d feat=%d\n", type, feature); 424 dccp_feat_debug(type, feature, *val);
410
411 /* XXX sanity check type & feat */
412 425
413 /* locate our change request */ 426 /* locate our change request */
414 t = type == DCCPO_CONFIRM_L ? DCCPO_CHANGE_R : DCCPO_CHANGE_L; 427 switch (type) {
428 case DCCPO_CONFIRM_L: t = DCCPO_CHANGE_R; break;
429 case DCCPO_CONFIRM_R: t = DCCPO_CHANGE_L; break;
430 default: DCCP_WARN("invalid type %d\n", type);
431 return 1;
432
433 }
434 /* XXX sanity check feature value */
415 435
416 list_for_each_entry(opt, &dmsk->dccpms_pending, dccpop_node) { 436 list_for_each_entry(opt, &dmsk->dccpms_pending, dccpop_node) {
417 if (!opt->dccpop_conf && opt->dccpop_type == t && 437 if (!opt->dccpop_conf && opt->dccpop_type == t &&
418 opt->dccpop_feat == feature) { 438 opt->dccpop_feat == feature) {
419 /* we found it */ 439 found = 1;
440 dccp_pr_debug("feature %d found\n", opt->dccpop_feat);
441
420 /* XXX do sanity check */ 442 /* XXX do sanity check */
421 443
422 opt->dccpop_conf = 1; 444 opt->dccpop_conf = 1;
@@ -425,9 +447,7 @@ int dccp_feat_confirm_recv(struct sock *sk, u8 type, u8 feature,
425 dccp_feat_update(sk, opt->dccpop_type, 447 dccp_feat_update(sk, opt->dccpop_type,
426 opt->dccpop_feat, *val); 448 opt->dccpop_feat, *val);
427 449
428 dccp_pr_debug("feat %d type %d confirmed %d\n", 450 /* XXX check the return value of dccp_feat_update */
429 feature, type, *val);
430 rc = 0;
431 break; 451 break;
432 } 452 }
433 453
@@ -446,9 +466,9 @@ int dccp_feat_confirm_recv(struct sock *sk, u8 type, u8 feature,
446 inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS); 466 inet_csk_clear_xmit_timer(sk, ICSK_TIME_RETRANS);
447 } 467 }
448 468
449 if (rc) 469 if (!found)
450 dccp_pr_debug("feat %d type %d never requested\n", 470 dccp_pr_debug("%s(%d, ...) never requested\n",
451 feature, type); 471 dccp_feat_typename(type), feature);
452 return 0; 472 return 0;
453} 473}
454 474
@@ -501,20 +521,18 @@ int dccp_feat_clone(struct sock *oldsk, struct sock *newsk)
501 list_for_each_entry(opt, &olddmsk->dccpms_pending, dccpop_node) { 521 list_for_each_entry(opt, &olddmsk->dccpms_pending, dccpop_node) {
502 struct dccp_opt_pend *newopt; 522 struct dccp_opt_pend *newopt;
503 /* copy the value of the option */ 523 /* copy the value of the option */
504 u8 *val = kmalloc(opt->dccpop_len, GFP_ATOMIC); 524 u8 *val = kmemdup(opt->dccpop_val, opt->dccpop_len, GFP_ATOMIC);
505 525
506 if (val == NULL) 526 if (val == NULL)
507 goto out_clean; 527 goto out_clean;
508 memcpy(val, opt->dccpop_val, opt->dccpop_len);
509 528
510 newopt = kmalloc(sizeof(*newopt), GFP_ATOMIC); 529 newopt = kmemdup(opt, sizeof(*newopt), GFP_ATOMIC);
511 if (newopt == NULL) { 530 if (newopt == NULL) {
512 kfree(val); 531 kfree(val);
513 goto out_clean; 532 goto out_clean;
514 } 533 }
515 534
516 /* insert the option */ 535 /* insert the option */
517 memcpy(newopt, opt, sizeof(*newopt));
518 newopt->dccpop_val = val; 536 newopt->dccpop_val = val;
519 list_add_tail(&newopt->dccpop_node, &newdmsk->dccpms_pending); 537 list_add_tail(&newopt->dccpop_node, &newdmsk->dccpms_pending);
520 538
@@ -545,10 +563,9 @@ static int __dccp_feat_init(struct dccp_minisock *dmsk, u8 type, u8 feat,
545 u8 *val, u8 len) 563 u8 *val, u8 len)
546{ 564{
547 int rc = -ENOMEM; 565 int rc = -ENOMEM;
548 u8 *copy = kmalloc(len, GFP_KERNEL); 566 u8 *copy = kmemdup(val, len, GFP_KERNEL);
549 567
550 if (copy != NULL) { 568 if (copy != NULL) {
551 memcpy(copy, val, len);
552 rc = dccp_feat_change(dmsk, type, feat, copy, len, GFP_KERNEL); 569 rc = dccp_feat_change(dmsk, type, feat, copy, len, GFP_KERNEL);
553 if (rc) 570 if (rc)
554 kfree(copy); 571 kfree(copy);
@@ -583,3 +600,45 @@ out:
583} 600}
584 601
585EXPORT_SYMBOL_GPL(dccp_feat_init); 602EXPORT_SYMBOL_GPL(dccp_feat_init);
603
604#ifdef CONFIG_IP_DCCP_DEBUG
605const char *dccp_feat_typename(const u8 type)
606{
607 switch(type) {
608 case DCCPO_CHANGE_L: return("ChangeL");
609 case DCCPO_CONFIRM_L: return("ConfirmL");
610 case DCCPO_CHANGE_R: return("ChangeR");
611 case DCCPO_CONFIRM_R: return("ConfirmR");
612 /* the following case must not appear in feature negotation */
613 default: dccp_pr_debug("unknown type %d [BUG!]\n", type);
614 }
615 return NULL;
616}
617
618EXPORT_SYMBOL_GPL(dccp_feat_typename);
619
620const char *dccp_feat_name(const u8 feat)
621{
622 static const char *feature_names[] = {
623 [DCCPF_RESERVED] = "Reserved",
624 [DCCPF_CCID] = "CCID",
625 [DCCPF_SHORT_SEQNOS] = "Allow Short Seqnos",
626 [DCCPF_SEQUENCE_WINDOW] = "Sequence Window",
627 [DCCPF_ECN_INCAPABLE] = "ECN Incapable",
628 [DCCPF_ACK_RATIO] = "Ack Ratio",
629 [DCCPF_SEND_ACK_VECTOR] = "Send ACK Vector",
630 [DCCPF_SEND_NDP_COUNT] = "Send NDP Count",
631 [DCCPF_MIN_CSUM_COVER] = "Min. Csum Coverage",
632 [DCCPF_DATA_CHECKSUM] = "Send Data Checksum",
633 };
634 if (feat >= DCCPF_MIN_CCID_SPECIFIC)
635 return "CCID-specific";
636
637 if (dccp_feat_is_reserved(feat))
638 return feature_names[DCCPF_RESERVED];
639
640 return feature_names[feat];
641}
642
643EXPORT_SYMBOL_GPL(dccp_feat_name);
644#endif /* CONFIG_IP_DCCP_DEBUG */
diff --git a/net/dccp/feat.h b/net/dccp/feat.h
index cee553d416..2c373ad7ed 100644
--- a/net/dccp/feat.h
+++ b/net/dccp/feat.h
@@ -12,9 +12,46 @@
12 */ 12 */
13 13
14#include <linux/types.h> 14#include <linux/types.h>
15#include "dccp.h"
15 16
16struct sock; 17static inline int dccp_feat_is_valid_length(u8 type, u8 feature, u8 len)
17struct dccp_minisock; 18{
19 /* sec. 6.1: Confirm has at least length 3,
20 * sec. 6.2: Change has at least length 4 */
21 if (len < 3)
22 return 1;
23 if (len < 4 && (type == DCCPO_CHANGE_L || type == DCCPO_CHANGE_R))
24 return 1;
25 /* XXX: add per-feature length validation (sec. 6.6.8) */
26 return 0;
27}
28
29static inline int dccp_feat_is_reserved(const u8 feat)
30{
31 return (feat > DCCPF_DATA_CHECKSUM &&
32 feat < DCCPF_MIN_CCID_SPECIFIC) ||
33 feat == DCCPF_RESERVED;
34}
35
36/* feature negotiation knows only these four option types (RFC 4340, sec. 6) */
37static inline int dccp_feat_is_valid_type(const u8 optnum)
38{
39 return optnum >= DCCPO_CHANGE_L && optnum <= DCCPO_CONFIRM_R;
40
41}
42
43#ifdef CONFIG_IP_DCCP_DEBUG
44extern const char *dccp_feat_typename(const u8 type);
45extern const char *dccp_feat_name(const u8 feat);
46
47static inline void dccp_feat_debug(const u8 type, const u8 feat, const u8 val)
48{
49 dccp_pr_debug("%s(%s (%d), %d)\n", dccp_feat_typename(type),
50 dccp_feat_name(feat), feat, val);
51}
52#else
53#define dccp_feat_debug(type, feat, val)
54#endif /* CONFIG_IP_DCCP_DEBUG */
18 55
19extern int dccp_feat_change(struct dccp_minisock *dmsk, u8 type, u8 feature, 56extern int dccp_feat_change(struct dccp_minisock *dmsk, u8 type, u8 feature,
20 u8 *val, u8 len, gfp_t gfp); 57 u8 *val, u8 len, gfp_t gfp);
@@ -26,11 +63,4 @@ extern void dccp_feat_clean(struct dccp_minisock *dmsk);
26extern int dccp_feat_clone(struct sock *oldsk, struct sock *newsk); 63extern int dccp_feat_clone(struct sock *oldsk, struct sock *newsk);
27extern int dccp_feat_init(struct dccp_minisock *dmsk); 64extern int dccp_feat_init(struct dccp_minisock *dmsk);
28 65
29extern int dccp_feat_default_sequence_window;
30extern int dccp_feat_default_rx_ccid;
31extern int dccp_feat_default_tx_ccid;
32extern int dccp_feat_default_ack_ratio;
33extern int dccp_feat_default_send_ack_vector;
34extern int dccp_feat_default_send_ndp_count;
35
36#endif /* _DCCP_FEAT_H */ 66#endif /* _DCCP_FEAT_H */
diff --git a/net/dccp/input.c b/net/dccp/input.c
index 1d24881ac0..565bc80557 100644
--- a/net/dccp/input.c
+++ b/net/dccp/input.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * net/dccp/input.c 2 * net/dccp/input.c
3 * 3 *
4 * An implementation of the DCCP protocol 4 * An implementation of the DCCP protocol
5 * Arnaldo Carvalho de Melo <acme@conectiva.com.br> 5 * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
6 * 6 *
@@ -82,7 +82,7 @@ static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb)
82 * Otherwise, 82 * Otherwise,
83 * Drop packet and return 83 * Drop packet and return
84 */ 84 */
85 if (dh->dccph_type == DCCP_PKT_SYNC || 85 if (dh->dccph_type == DCCP_PKT_SYNC ||
86 dh->dccph_type == DCCP_PKT_SYNCACK) { 86 dh->dccph_type == DCCP_PKT_SYNCACK) {
87 if (between48(DCCP_SKB_CB(skb)->dccpd_ack_seq, 87 if (between48(DCCP_SKB_CB(skb)->dccpd_ack_seq,
88 dp->dccps_awl, dp->dccps_awh) && 88 dp->dccps_awl, dp->dccps_awh) &&
@@ -128,21 +128,18 @@ static int dccp_check_seqno(struct sock *sk, struct sk_buff *skb)
128 DCCP_PKT_WITHOUT_ACK_SEQ)) 128 DCCP_PKT_WITHOUT_ACK_SEQ))
129 dp->dccps_gar = DCCP_SKB_CB(skb)->dccpd_ack_seq; 129 dp->dccps_gar = DCCP_SKB_CB(skb)->dccpd_ack_seq;
130 } else { 130 } else {
131 LIMIT_NETDEBUG(KERN_WARNING "DCCP: Step 6 failed for %s packet, " 131 DCCP_WARN("DCCP: Step 6 failed for %s packet, "
132 "(LSWL(%llu) <= P.seqno(%llu) <= S.SWH(%llu)) and " 132 "(LSWL(%llu) <= P.seqno(%llu) <= S.SWH(%llu)) and "
133 "(P.ackno %s or LAWL(%llu) <= P.ackno(%llu) <= S.AWH(%llu), " 133 "(P.ackno %s or LAWL(%llu) <= P.ackno(%llu) <= S.AWH(%llu), "
134 "sending SYNC...\n", 134 "sending SYNC...\n", dccp_packet_name(dh->dccph_type),
135 dccp_packet_name(dh->dccph_type), 135 (unsigned long long) lswl,
136 (unsigned long long) lswl, 136 (unsigned long long) DCCP_SKB_CB(skb)->dccpd_seq,
137 (unsigned long long) 137 (unsigned long long) dp->dccps_swh,
138 DCCP_SKB_CB(skb)->dccpd_seq, 138 (DCCP_SKB_CB(skb)->dccpd_ack_seq ==
139 (unsigned long long) dp->dccps_swh,
140 (DCCP_SKB_CB(skb)->dccpd_ack_seq ==
141 DCCP_PKT_WITHOUT_ACK_SEQ) ? "doesn't exist" : "exists", 139 DCCP_PKT_WITHOUT_ACK_SEQ) ? "doesn't exist" : "exists",
142 (unsigned long long) lawl, 140 (unsigned long long) lawl,
143 (unsigned long long) 141 (unsigned long long) DCCP_SKB_CB(skb)->dccpd_ack_seq,
144 DCCP_SKB_CB(skb)->dccpd_ack_seq, 142 (unsigned long long) dp->dccps_awh);
145 (unsigned long long) dp->dccps_awh);
146 dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq, DCCP_PKT_SYNC); 143 dccp_send_sync(sk, DCCP_SKB_CB(skb)->dccpd_seq, DCCP_PKT_SYNC);
147 return -1; 144 return -1;
148 } 145 }
@@ -188,8 +185,8 @@ static int __dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
188 dccp_rcv_close(sk, skb); 185 dccp_rcv_close(sk, skb);
189 return 0; 186 return 0;
190 case DCCP_PKT_REQUEST: 187 case DCCP_PKT_REQUEST:
191 /* Step 7 188 /* Step 7
192 * or (S.is_server and P.type == Response) 189 * or (S.is_server and P.type == Response)
193 * or (S.is_client and P.type == Request) 190 * or (S.is_client and P.type == Request)
194 * or (S.state >= OPEN and P.type == Request 191 * or (S.state >= OPEN and P.type == Request
195 * and P.seqno >= S.OSR) 192 * and P.seqno >= S.OSR)
@@ -251,8 +248,18 @@ int dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
251 DCCP_ACKVEC_STATE_RECEIVED)) 248 DCCP_ACKVEC_STATE_RECEIVED))
252 goto discard; 249 goto discard;
253 250
254 ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb); 251 /*
255 ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb); 252 * Deliver to the CCID module in charge.
253 * FIXME: Currently DCCP operates one-directional only, i.e. a listening
254 * server is not at the same time a connecting client. There is
255 * not much sense in delivering to both rx/tx sides at the moment
256 * (only one is active at a time); when moving to bidirectional
257 * service, this needs to be revised.
258 */
259 if (dccp_sk(sk)->dccps_role == DCCP_ROLE_SERVER)
260 ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
261 else
262 ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
256 263
257 return __dccp_rcv_established(sk, skb, dh, len); 264 return __dccp_rcv_established(sk, skb, dh, len);
258discard: 265discard:
@@ -267,7 +274,7 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
267 const struct dccp_hdr *dh, 274 const struct dccp_hdr *dh,
268 const unsigned len) 275 const unsigned len)
269{ 276{
270 /* 277 /*
271 * Step 4: Prepare sequence numbers in REQUEST 278 * Step 4: Prepare sequence numbers in REQUEST
272 * If S.state == REQUEST, 279 * If S.state == REQUEST,
273 * If (P.type == Response or P.type == Reset) 280 * If (P.type == Response or P.type == Reset)
@@ -335,7 +342,7 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
335 * from the Response * / 342 * from the Response * /
336 * S.state := PARTOPEN 343 * S.state := PARTOPEN
337 * Set PARTOPEN timer 344 * Set PARTOPEN timer
338 * Continue with S.state == PARTOPEN 345 * Continue with S.state == PARTOPEN
339 * / * Step 12 will send the Ack completing the 346 * / * Step 12 will send the Ack completing the
340 * three-way handshake * / 347 * three-way handshake * /
341 */ 348 */
@@ -366,7 +373,7 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
366 */ 373 */
367 __kfree_skb(skb); 374 __kfree_skb(skb);
368 return 0; 375 return 0;
369 } 376 }
370 dccp_send_ack(sk); 377 dccp_send_ack(sk);
371 return -1; 378 return -1;
372 } 379 }
@@ -374,7 +381,7 @@ static int dccp_rcv_request_sent_state_process(struct sock *sk,
374out_invalid_packet: 381out_invalid_packet:
375 /* dccp_v4_do_rcv will send a reset */ 382 /* dccp_v4_do_rcv will send a reset */
376 DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_PACKET_ERROR; 383 DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_PACKET_ERROR;
377 return 1; 384 return 1;
378} 385}
379 386
380static int dccp_rcv_respond_partopen_state_process(struct sock *sk, 387static int dccp_rcv_respond_partopen_state_process(struct sock *sk,
@@ -431,29 +438,25 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
431 438
432 /* 439 /*
433 * Step 3: Process LISTEN state 440 * Step 3: Process LISTEN state
434 * (Continuing from dccp_v4_do_rcv and dccp_v6_do_rcv)
435 * 441 *
436 * If S.state == LISTEN, 442 * If S.state == LISTEN,
437 * If P.type == Request or P contains a valid Init Cookie 443 * If P.type == Request or P contains a valid Init Cookie option,
438 * option, 444 * (* Must scan the packet's options to check for Init
439 * * Must scan the packet's options to check for an Init 445 * Cookies. Only Init Cookies are processed here,
440 * Cookie. Only the Init Cookie is processed here, 446 * however; other options are processed in Step 8. This
441 * however; other options are processed in Step 8. This 447 * scan need only be performed if the endpoint uses Init
442 * scan need only be performed if the endpoint uses Init 448 * Cookies *)
443 * Cookies * 449 * (* Generate a new socket and switch to that socket *)
444 * * Generate a new socket and switch to that socket * 450 * Set S := new socket for this port pair
445 * Set S := new socket for this port pair 451 * S.state = RESPOND
446 * S.state = RESPOND 452 * Choose S.ISS (initial seqno) or set from Init Cookies
447 * Choose S.ISS (initial seqno) or set from Init Cookie 453 * Initialize S.GAR := S.ISS
448 * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie 454 * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init
449 * Continue with S.state == RESPOND 455 * Cookies Continue with S.state == RESPOND
450 * * A Response packet will be generated in Step 11 * 456 * (* A Response packet will be generated in Step 11 *)
451 * Otherwise, 457 * Otherwise,
452 * Generate Reset(No Connection) unless P.type == Reset 458 * Generate Reset(No Connection) unless P.type == Reset
453 * Drop packet and return 459 * Drop packet and return
454 *
455 * NOTE: the check for the packet types is done in
456 * dccp_rcv_state_process
457 */ 460 */
458 if (sk->sk_state == DCCP_LISTEN) { 461 if (sk->sk_state == DCCP_LISTEN) {
459 if (dh->dccph_type == DCCP_PKT_REQUEST) { 462 if (dh->dccph_type == DCCP_PKT_REQUEST) {
@@ -485,14 +488,17 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
485 if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) 488 if (dcb->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
486 dccp_event_ack_recv(sk, skb); 489 dccp_event_ack_recv(sk, skb);
487 490
488 if (dccp_msk(sk)->dccpms_send_ack_vector && 491 if (dccp_msk(sk)->dccpms_send_ack_vector &&
489 dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk, 492 dccp_ackvec_add(dp->dccps_hc_rx_ackvec, sk,
490 DCCP_SKB_CB(skb)->dccpd_seq, 493 DCCP_SKB_CB(skb)->dccpd_seq,
491 DCCP_ACKVEC_STATE_RECEIVED)) 494 DCCP_ACKVEC_STATE_RECEIVED))
492 goto discard; 495 goto discard;
493 496
494 ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb); 497 /* XXX see the comments in dccp_rcv_established about this */
495 ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb); 498 if (dccp_sk(sk)->dccps_role == DCCP_ROLE_SERVER)
499 ccid_hc_rx_packet_recv(dp->dccps_hc_rx_ccid, sk, skb);
500 else
501 ccid_hc_tx_packet_recv(dp->dccps_hc_tx_ccid, sk, skb);
496 } 502 }
497 503
498 /* 504 /*
@@ -574,7 +580,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
574 } 580 }
575 } 581 }
576 582
577 if (!queued) { 583 if (!queued) {
578discard: 584discard:
579 __kfree_skb(skb); 585 __kfree_skb(skb);
580 } 586 }
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index e08e7688a2..90c74b4adb 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -113,13 +113,8 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
113 /* OK, now commit destination to socket. */ 113 /* OK, now commit destination to socket. */
114 sk_setup_caps(sk, &rt->u.dst); 114 sk_setup_caps(sk, &rt->u.dst);
115 115
116 dp->dccps_gar = 116 dp->dccps_iss = secure_dccp_sequence_number(inet->saddr, inet->daddr,
117 dp->dccps_iss = secure_dccp_sequence_number(inet->saddr, 117 inet->sport, inet->dport);
118 inet->daddr,
119 inet->sport,
120 usin->sin_port);
121 dccp_update_gss(sk, dp->dccps_iss);
122
123 inet->id = dp->dccps_iss ^ jiffies; 118 inet->id = dp->dccps_iss ^ jiffies;
124 119
125 err = dccp_connect(sk); 120 err = dccp_connect(sk);
@@ -162,7 +157,7 @@ static inline void dccp_do_pmtu_discovery(struct sock *sk,
162 /* We don't check in the destentry if pmtu discovery is forbidden 157 /* We don't check in the destentry if pmtu discovery is forbidden
163 * on this route. We just assume that no packet_to_big packets 158 * on this route. We just assume that no packet_to_big packets
164 * are send back when pmtu discovery is not active. 159 * are send back when pmtu discovery is not active.
165 * There is a small race when the user changes this flag in the 160 * There is a small race when the user changes this flag in the
166 * route, but I think that's acceptable. 161 * route, but I think that's acceptable.
167 */ 162 */
168 if ((dst = __sk_dst_check(sk, 0)) == NULL) 163 if ((dst = __sk_dst_check(sk, 0)) == NULL)
@@ -193,86 +188,6 @@ static inline void dccp_do_pmtu_discovery(struct sock *sk,
193 } /* else let the usual retransmit timer handle it */ 188 } /* else let the usual retransmit timer handle it */
194} 189}
195 190
196static void dccp_v4_reqsk_send_ack(struct sk_buff *rxskb,
197 struct request_sock *req)
198{
199 int err;
200 struct dccp_hdr *rxdh = dccp_hdr(rxskb), *dh;
201 const u32 dccp_hdr_ack_len = sizeof(struct dccp_hdr) +
202 sizeof(struct dccp_hdr_ext) +
203 sizeof(struct dccp_hdr_ack_bits);
204 struct sk_buff *skb;
205
206 if (((struct rtable *)rxskb->dst)->rt_type != RTN_LOCAL)
207 return;
208
209 skb = alloc_skb(dccp_v4_ctl_socket->sk->sk_prot->max_header, GFP_ATOMIC);
210 if (skb == NULL)
211 return;
212
213 /* Reserve space for headers. */
214 skb_reserve(skb, dccp_v4_ctl_socket->sk->sk_prot->max_header);
215
216 skb->dst = dst_clone(rxskb->dst);
217
218 skb->h.raw = skb_push(skb, dccp_hdr_ack_len);
219 dh = dccp_hdr(skb);
220 memset(dh, 0, dccp_hdr_ack_len);
221
222 /* Build DCCP header and checksum it. */
223 dh->dccph_type = DCCP_PKT_ACK;
224 dh->dccph_sport = rxdh->dccph_dport;
225 dh->dccph_dport = rxdh->dccph_sport;
226 dh->dccph_doff = dccp_hdr_ack_len / 4;
227 dh->dccph_x = 1;
228
229 dccp_hdr_set_seq(dh, DCCP_SKB_CB(rxskb)->dccpd_ack_seq);
230 dccp_hdr_set_ack(dccp_hdr_ack_bits(skb),
231 DCCP_SKB_CB(rxskb)->dccpd_seq);
232
233 bh_lock_sock(dccp_v4_ctl_socket->sk);
234 err = ip_build_and_send_pkt(skb, dccp_v4_ctl_socket->sk,
235 rxskb->nh.iph->daddr,
236 rxskb->nh.iph->saddr, NULL);
237 bh_unlock_sock(dccp_v4_ctl_socket->sk);
238
239 if (err == NET_XMIT_CN || err == 0) {
240 DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS);
241 DCCP_INC_STATS_BH(DCCP_MIB_OUTRSTS);
242 }
243}
244
245static int dccp_v4_send_response(struct sock *sk, struct request_sock *req,
246 struct dst_entry *dst)
247{
248 int err = -1;
249 struct sk_buff *skb;
250
251 /* First, grab a route. */
252
253 if (dst == NULL && (dst = inet_csk_route_req(sk, req)) == NULL)
254 goto out;
255
256 skb = dccp_make_response(sk, dst, req);
257 if (skb != NULL) {
258 const struct inet_request_sock *ireq = inet_rsk(req);
259 struct dccp_hdr *dh = dccp_hdr(skb);
260
261 dh->dccph_checksum = dccp_v4_checksum(skb, ireq->loc_addr,
262 ireq->rmt_addr);
263 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
264 err = ip_build_and_send_pkt(skb, sk, ireq->loc_addr,
265 ireq->rmt_addr,
266 ireq->opt);
267 if (err == NET_XMIT_CN)
268 err = 0;
269 }
270
271out:
272 dst_release(dst);
273 return err;
274}
275
276/* 191/*
277 * This routine is called by the ICMP module when it gets some sort of error 192 * This routine is called by the ICMP module when it gets some sort of error
278 * condition. If err < 0 then the socket should be closed and the error 193 * condition. If err < 0 then the socket should be closed and the error
@@ -329,7 +244,7 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)
329 seq = dccp_hdr_seq(skb); 244 seq = dccp_hdr_seq(skb);
330 if (sk->sk_state != DCCP_LISTEN && 245 if (sk->sk_state != DCCP_LISTEN &&
331 !between48(seq, dp->dccps_swl, dp->dccps_swh)) { 246 !between48(seq, dp->dccps_swl, dp->dccps_swh)) {
332 NET_INC_STATS(LINUX_MIB_OUTOFWINDOWICMPS); 247 NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS);
333 goto out; 248 goto out;
334 } 249 }
335 250
@@ -429,19 +344,24 @@ out:
429 sock_put(sk); 344 sock_put(sk);
430} 345}
431 346
432/* This routine computes an IPv4 DCCP checksum. */ 347static inline __sum16 dccp_v4_csum_finish(struct sk_buff *skb,
433void dccp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb) 348 __be32 src, __be32 dst)
349{
350 return csum_tcpudp_magic(src, dst, skb->len, IPPROTO_DCCP, skb->csum);
351}
352
353void dccp_v4_send_check(struct sock *sk, int unused, struct sk_buff *skb)
434{ 354{
435 const struct inet_sock *inet = inet_sk(sk); 355 const struct inet_sock *inet = inet_sk(sk);
436 struct dccp_hdr *dh = dccp_hdr(skb); 356 struct dccp_hdr *dh = dccp_hdr(skb);
437 357
438 dh->dccph_checksum = dccp_v4_checksum(skb, inet->saddr, inet->daddr); 358 dccp_csum_outgoing(skb);
359 dh->dccph_checksum = dccp_v4_csum_finish(skb, inet->saddr, inet->daddr);
439} 360}
440 361
441EXPORT_SYMBOL_GPL(dccp_v4_send_check); 362EXPORT_SYMBOL_GPL(dccp_v4_send_check);
442 363
443static inline u64 dccp_v4_init_sequence(const struct sock *sk, 364static inline u64 dccp_v4_init_sequence(const struct sk_buff *skb)
444 const struct sk_buff *skb)
445{ 365{
446 return secure_dccp_sequence_number(skb->nh.iph->daddr, 366 return secure_dccp_sequence_number(skb->nh.iph->daddr,
447 skb->nh.iph->saddr, 367 skb->nh.iph->saddr,
@@ -449,95 +369,6 @@ static inline u64 dccp_v4_init_sequence(const struct sock *sk,
449 dccp_hdr(skb)->dccph_sport); 369 dccp_hdr(skb)->dccph_sport);
450} 370}
451 371
452static struct request_sock_ops dccp_request_sock_ops;
453
454int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
455{
456 struct inet_request_sock *ireq;
457 struct dccp_sock dp;
458 struct request_sock *req;
459 struct dccp_request_sock *dreq;
460 const __be32 saddr = skb->nh.iph->saddr;
461 const __be32 daddr = skb->nh.iph->daddr;
462 const __be32 service = dccp_hdr_request(skb)->dccph_req_service;
463 struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
464 __u8 reset_code = DCCP_RESET_CODE_TOO_BUSY;
465
466 /* Never answer to DCCP_PKT_REQUESTs send to broadcast or multicast */
467 if (((struct rtable *)skb->dst)->rt_flags &
468 (RTCF_BROADCAST | RTCF_MULTICAST)) {
469 reset_code = DCCP_RESET_CODE_NO_CONNECTION;
470 goto drop;
471 }
472
473 if (dccp_bad_service_code(sk, service)) {
474 reset_code = DCCP_RESET_CODE_BAD_SERVICE_CODE;
475 goto drop;
476 }
477 /*
478 * TW buckets are converted to open requests without
479 * limitations, they conserve resources and peer is
480 * evidently real one.
481 */
482 if (inet_csk_reqsk_queue_is_full(sk))
483 goto drop;
484
485 /*
486 * Accept backlog is full. If we have already queued enough
487 * of warm entries in syn queue, drop request. It is better than
488 * clogging syn queue with openreqs with exponentially increasing
489 * timeout.
490 */
491 if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1)
492 goto drop;
493
494 req = reqsk_alloc(&dccp_request_sock_ops);
495 if (req == NULL)
496 goto drop;
497
498 if (dccp_parse_options(sk, skb))
499 goto drop_and_free;
500
501 dccp_openreq_init(req, &dp, skb);
502
503 if (security_inet_conn_request(sk, skb, req))
504 goto drop_and_free;
505
506 ireq = inet_rsk(req);
507 ireq->loc_addr = daddr;
508 ireq->rmt_addr = saddr;
509 req->rcv_wnd = dccp_feat_default_sequence_window;
510 ireq->opt = NULL;
511
512 /*
513 * Step 3: Process LISTEN state
514 *
515 * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie
516 *
517 * In fact we defer setting S.GSR, S.SWL, S.SWH to
518 * dccp_create_openreq_child.
519 */
520 dreq = dccp_rsk(req);
521 dreq->dreq_isr = dcb->dccpd_seq;
522 dreq->dreq_iss = dccp_v4_init_sequence(sk, skb);
523 dreq->dreq_service = service;
524
525 if (dccp_v4_send_response(sk, req, NULL))
526 goto drop_and_free;
527
528 inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT);
529 return 0;
530
531drop_and_free:
532 reqsk_free(req);
533drop:
534 DCCP_INC_STATS_BH(DCCP_MIB_ATTEMPTFAILS);
535 dcb->dccpd_reset_code = reset_code;
536 return -1;
537}
538
539EXPORT_SYMBOL_GPL(dccp_v4_conn_request);
540
541/* 372/*
542 * The three way handshake has completed - we got a valid ACK or DATAACK - 373 * The three way handshake has completed - we got a valid ACK or DATAACK -
543 * now create the new socket. 374 * now create the new socket.
@@ -623,47 +454,6 @@ static struct sock *dccp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
623 return sk; 454 return sk;
624} 455}
625 456
626int dccp_v4_checksum(const struct sk_buff *skb, const __be32 saddr,
627 const __be32 daddr)
628{
629 const struct dccp_hdr* dh = dccp_hdr(skb);
630 int checksum_len;
631 u32 tmp;
632
633 if (dh->dccph_cscov == 0)
634 checksum_len = skb->len;
635 else {
636 checksum_len = (dh->dccph_cscov + dh->dccph_x) * sizeof(u32);
637 checksum_len = checksum_len < skb->len ? checksum_len :
638 skb->len;
639 }
640
641 tmp = csum_partial((unsigned char *)dh, checksum_len, 0);
642 return csum_tcpudp_magic(saddr, daddr, checksum_len,
643 IPPROTO_DCCP, tmp);
644}
645
646EXPORT_SYMBOL_GPL(dccp_v4_checksum);
647
648static int dccp_v4_verify_checksum(struct sk_buff *skb,
649 const __be32 saddr, const __be32 daddr)
650{
651 struct dccp_hdr *dh = dccp_hdr(skb);
652 int checksum_len;
653 u32 tmp;
654
655 if (dh->dccph_cscov == 0)
656 checksum_len = skb->len;
657 else {
658 checksum_len = (dh->dccph_cscov + dh->dccph_x) * sizeof(u32);
659 checksum_len = checksum_len < skb->len ? checksum_len :
660 skb->len;
661 }
662 tmp = csum_partial((unsigned char *)dh, checksum_len, 0);
663 return csum_tcpudp_magic(saddr, daddr, checksum_len,
664 IPPROTO_DCCP, tmp) == 0 ? 0 : -1;
665}
666
667static struct dst_entry* dccp_v4_route_skb(struct sock *sk, 457static struct dst_entry* dccp_v4_route_skb(struct sock *sk,
668 struct sk_buff *skb) 458 struct sk_buff *skb)
669{ 459{
@@ -677,7 +467,7 @@ static struct dst_entry* dccp_v4_route_skb(struct sock *sk,
677 .uli_u = { .ports = 467 .uli_u = { .ports =
678 { .sport = dccp_hdr(skb)->dccph_dport, 468 { .sport = dccp_hdr(skb)->dccph_dport,
679 .dport = dccp_hdr(skb)->dccph_sport } 469 .dport = dccp_hdr(skb)->dccph_sport }
680 } 470 }
681 }; 471 };
682 472
683 security_skb_classify_flow(skb, &fl); 473 security_skb_classify_flow(skb, &fl);
@@ -689,7 +479,37 @@ static struct dst_entry* dccp_v4_route_skb(struct sock *sk,
689 return &rt->u.dst; 479 return &rt->u.dst;
690} 480}
691 481
692static void dccp_v4_ctl_send_reset(struct sk_buff *rxskb) 482static int dccp_v4_send_response(struct sock *sk, struct request_sock *req,
483 struct dst_entry *dst)
484{
485 int err = -1;
486 struct sk_buff *skb;
487
488 /* First, grab a route. */
489
490 if (dst == NULL && (dst = inet_csk_route_req(sk, req)) == NULL)
491 goto out;
492
493 skb = dccp_make_response(sk, dst, req);
494 if (skb != NULL) {
495 const struct inet_request_sock *ireq = inet_rsk(req);
496 struct dccp_hdr *dh = dccp_hdr(skb);
497
498 dh->dccph_checksum = dccp_v4_csum_finish(skb, ireq->loc_addr,
499 ireq->rmt_addr);
500 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
501 err = ip_build_and_send_pkt(skb, sk, ireq->loc_addr,
502 ireq->rmt_addr,
503 ireq->opt);
504 err = net_xmit_eval(err);
505 }
506
507out:
508 dst_release(dst);
509 return err;
510}
511
512static void dccp_v4_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb)
693{ 513{
694 int err; 514 int err;
695 struct dccp_hdr *rxdh = dccp_hdr(rxskb), *dh; 515 struct dccp_hdr *rxdh = dccp_hdr(rxskb), *dh;
@@ -698,7 +518,7 @@ static void dccp_v4_ctl_send_reset(struct sk_buff *rxskb)
698 sizeof(struct dccp_hdr_reset); 518 sizeof(struct dccp_hdr_reset);
699 struct sk_buff *skb; 519 struct sk_buff *skb;
700 struct dst_entry *dst; 520 struct dst_entry *dst;
701 u64 seqno; 521 u64 seqno = 0;
702 522
703 /* Never send a reset in response to a reset. */ 523 /* Never send a reset in response to a reset. */
704 if (rxdh->dccph_type == DCCP_PKT_RESET) 524 if (rxdh->dccph_type == DCCP_PKT_RESET)
@@ -720,9 +540,7 @@ static void dccp_v4_ctl_send_reset(struct sk_buff *rxskb)
720 skb_reserve(skb, dccp_v4_ctl_socket->sk->sk_prot->max_header); 540 skb_reserve(skb, dccp_v4_ctl_socket->sk->sk_prot->max_header);
721 skb->dst = dst_clone(dst); 541 skb->dst = dst_clone(dst);
722 542
723 skb->h.raw = skb_push(skb, dccp_hdr_reset_len); 543 dh = dccp_zeroed_hdr(skb, dccp_hdr_reset_len);
724 dh = dccp_hdr(skb);
725 memset(dh, 0, dccp_hdr_reset_len);
726 544
727 /* Build DCCP header and checksum it. */ 545 /* Build DCCP header and checksum it. */
728 dh->dccph_type = DCCP_PKT_RESET; 546 dh->dccph_type = DCCP_PKT_RESET;
@@ -734,16 +552,15 @@ static void dccp_v4_ctl_send_reset(struct sk_buff *rxskb)
734 DCCP_SKB_CB(rxskb)->dccpd_reset_code; 552 DCCP_SKB_CB(rxskb)->dccpd_reset_code;
735 553
736 /* See "8.3.1. Abnormal Termination" in RFC 4340 */ 554 /* See "8.3.1. Abnormal Termination" in RFC 4340 */
737 seqno = 0;
738 if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) 555 if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
739 dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1); 556 dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1);
740 557
741 dccp_hdr_set_seq(dh, seqno); 558 dccp_hdr_set_seq(dh, seqno);
742 dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), 559 dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), DCCP_SKB_CB(rxskb)->dccpd_seq);
743 DCCP_SKB_CB(rxskb)->dccpd_seq);
744 560
745 dh->dccph_checksum = dccp_v4_checksum(skb, rxskb->nh.iph->saddr, 561 dccp_csum_outgoing(skb);
746 rxskb->nh.iph->daddr); 562 dh->dccph_checksum = dccp_v4_csum_finish(skb, rxskb->nh.iph->saddr,
563 rxskb->nh.iph->daddr);
747 564
748 bh_lock_sock(dccp_v4_ctl_socket->sk); 565 bh_lock_sock(dccp_v4_ctl_socket->sk);
749 err = ip_build_and_send_pkt(skb, dccp_v4_ctl_socket->sk, 566 err = ip_build_and_send_pkt(skb, dccp_v4_ctl_socket->sk,
@@ -751,7 +568,7 @@ static void dccp_v4_ctl_send_reset(struct sk_buff *rxskb)
751 rxskb->nh.iph->saddr, NULL); 568 rxskb->nh.iph->saddr, NULL);
752 bh_unlock_sock(dccp_v4_ctl_socket->sk); 569 bh_unlock_sock(dccp_v4_ctl_socket->sk);
753 570
754 if (err == NET_XMIT_CN || err == 0) { 571 if (net_xmit_eval(err) == 0) {
755 DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS); 572 DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS);
756 DCCP_INC_STATS_BH(DCCP_MIB_OUTRSTS); 573 DCCP_INC_STATS_BH(DCCP_MIB_OUTRSTS);
757 } 574 }
@@ -759,6 +576,103 @@ out:
759 dst_release(dst); 576 dst_release(dst);
760} 577}
761 578
579static void dccp_v4_reqsk_destructor(struct request_sock *req)
580{
581 kfree(inet_rsk(req)->opt);
582}
583
584static struct request_sock_ops dccp_request_sock_ops __read_mostly = {
585 .family = PF_INET,
586 .obj_size = sizeof(struct dccp_request_sock),
587 .rtx_syn_ack = dccp_v4_send_response,
588 .send_ack = dccp_reqsk_send_ack,
589 .destructor = dccp_v4_reqsk_destructor,
590 .send_reset = dccp_v4_ctl_send_reset,
591};
592
593int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
594{
595 struct inet_request_sock *ireq;
596 struct request_sock *req;
597 struct dccp_request_sock *dreq;
598 const __be32 service = dccp_hdr_request(skb)->dccph_req_service;
599 struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
600 __u8 reset_code = DCCP_RESET_CODE_TOO_BUSY;
601
602 /* Never answer to DCCP_PKT_REQUESTs send to broadcast or multicast */
603 if (((struct rtable *)skb->dst)->rt_flags &
604 (RTCF_BROADCAST | RTCF_MULTICAST)) {
605 reset_code = DCCP_RESET_CODE_NO_CONNECTION;
606 goto drop;
607 }
608
609 if (dccp_bad_service_code(sk, service)) {
610 reset_code = DCCP_RESET_CODE_BAD_SERVICE_CODE;
611 goto drop;
612 }
613 /*
614 * TW buckets are converted to open requests without
615 * limitations, they conserve resources and peer is
616 * evidently real one.
617 */
618 if (inet_csk_reqsk_queue_is_full(sk))
619 goto drop;
620
621 /*
622 * Accept backlog is full. If we have already queued enough
623 * of warm entries in syn queue, drop request. It is better than
624 * clogging syn queue with openreqs with exponentially increasing
625 * timeout.
626 */
627 if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1)
628 goto drop;
629
630 req = reqsk_alloc(&dccp_request_sock_ops);
631 if (req == NULL)
632 goto drop;
633
634 if (dccp_parse_options(sk, skb))
635 goto drop_and_free;
636
637 dccp_reqsk_init(req, skb);
638
639 if (security_inet_conn_request(sk, skb, req))
640 goto drop_and_free;
641
642 ireq = inet_rsk(req);
643 ireq->loc_addr = skb->nh.iph->daddr;
644 ireq->rmt_addr = skb->nh.iph->saddr;
645 ireq->opt = NULL;
646
647 /*
648 * Step 3: Process LISTEN state
649 *
650 * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie
651 *
652 * In fact we defer setting S.GSR, S.SWL, S.SWH to
653 * dccp_create_openreq_child.
654 */
655 dreq = dccp_rsk(req);
656 dreq->dreq_isr = dcb->dccpd_seq;
657 dreq->dreq_iss = dccp_v4_init_sequence(skb);
658 dreq->dreq_service = service;
659
660 if (dccp_v4_send_response(sk, req, NULL))
661 goto drop_and_free;
662
663 inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT);
664 return 0;
665
666drop_and_free:
667 reqsk_free(req);
668drop:
669 DCCP_INC_STATS_BH(DCCP_MIB_ATTEMPTFAILS);
670 dcb->dccpd_reset_code = reset_code;
671 return -1;
672}
673
674EXPORT_SYMBOL_GPL(dccp_v4_conn_request);
675
762int dccp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) 676int dccp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
763{ 677{
764 struct dccp_hdr *dh = dccp_hdr(skb); 678 struct dccp_hdr *dh = dccp_hdr(skb);
@@ -771,24 +685,23 @@ int dccp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
771 685
772 /* 686 /*
773 * Step 3: Process LISTEN state 687 * Step 3: Process LISTEN state
774 * If S.state == LISTEN, 688 * If P.type == Request or P contains a valid Init Cookie option,
775 * If P.type == Request or P contains a valid Init Cookie 689 * (* Must scan the packet's options to check for Init
776 * option, 690 * Cookies. Only Init Cookies are processed here,
777 * * Must scan the packet's options to check for an Init 691 * however; other options are processed in Step 8. This
778 * Cookie. Only the Init Cookie is processed here, 692 * scan need only be performed if the endpoint uses Init
779 * however; other options are processed in Step 8. This 693 * Cookies *)
780 * scan need only be performed if the endpoint uses Init 694 * (* Generate a new socket and switch to that socket *)
781 * Cookies * 695 * Set S := new socket for this port pair
782 * * Generate a new socket and switch to that socket * 696 * S.state = RESPOND
783 * Set S := new socket for this port pair 697 * Choose S.ISS (initial seqno) or set from Init Cookies
784 * S.state = RESPOND 698 * Initialize S.GAR := S.ISS
785 * Choose S.ISS (initial seqno) or set from Init Cookie 699 * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookies
786 * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie 700 * Continue with S.state == RESPOND
787 * Continue with S.state == RESPOND 701 * (* A Response packet will be generated in Step 11 *)
788 * * A Response packet will be generated in Step 11 * 702 * Otherwise,
789 * Otherwise, 703 * Generate Reset(No Connection) unless P.type == Reset
790 * Generate Reset(No Connection) unless P.type == Reset 704 * Drop packet and return
791 * Drop packet and return
792 * 705 *
793 * NOTE: the check for the packet types is done in 706 * NOTE: the check for the packet types is done in
794 * dccp_rcv_state_process 707 * dccp_rcv_state_process
@@ -811,7 +724,7 @@ int dccp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
811 return 0; 724 return 0;
812 725
813reset: 726reset:
814 dccp_v4_ctl_send_reset(skb); 727 dccp_v4_ctl_send_reset(sk, skb);
815discard: 728discard:
816 kfree_skb(skb); 729 kfree_skb(skb);
817 return 0; 730 return 0;
@@ -819,60 +732,74 @@ discard:
819 732
820EXPORT_SYMBOL_GPL(dccp_v4_do_rcv); 733EXPORT_SYMBOL_GPL(dccp_v4_do_rcv);
821 734
735/**
736 * dccp_invalid_packet - check for malformed packets
737 * Implements RFC 4340, 8.5: Step 1: Check header basics
738 * Packets that fail these checks are ignored and do not receive Resets.
739 */
822int dccp_invalid_packet(struct sk_buff *skb) 740int dccp_invalid_packet(struct sk_buff *skb)
823{ 741{
824 const struct dccp_hdr *dh; 742 const struct dccp_hdr *dh;
743 unsigned int cscov;
825 744
826 if (skb->pkt_type != PACKET_HOST) 745 if (skb->pkt_type != PACKET_HOST)
827 return 1; 746 return 1;
828 747
748 /* If the packet is shorter than 12 bytes, drop packet and return */
829 if (!pskb_may_pull(skb, sizeof(struct dccp_hdr))) { 749 if (!pskb_may_pull(skb, sizeof(struct dccp_hdr))) {
830 LIMIT_NETDEBUG(KERN_WARNING "DCCP: pskb_may_pull failed\n"); 750 DCCP_WARN("pskb_may_pull failed\n");
831 return 1; 751 return 1;
832 } 752 }
833 753
834 dh = dccp_hdr(skb); 754 dh = dccp_hdr(skb);
835 755
836 /* If the packet type is not understood, drop packet and return */ 756 /* If P.type is not understood, drop packet and return */
837 if (dh->dccph_type >= DCCP_PKT_INVALID) { 757 if (dh->dccph_type >= DCCP_PKT_INVALID) {
838 LIMIT_NETDEBUG(KERN_WARNING "DCCP: invalid packet type\n"); 758 DCCP_WARN("invalid packet type\n");
839 return 1; 759 return 1;
840 } 760 }
841 761
842 /* 762 /*
843 * If P.Data Offset is too small for packet type, or too large for 763 * If P.Data Offset is too small for packet type, drop packet and return
844 * packet, drop packet and return
845 */ 764 */
846 if (dh->dccph_doff < dccp_hdr_len(skb) / sizeof(u32)) { 765 if (dh->dccph_doff < dccp_hdr_len(skb) / sizeof(u32)) {
847 LIMIT_NETDEBUG(KERN_WARNING "DCCP: P.Data Offset(%u) " 766 DCCP_WARN("P.Data Offset(%u) too small\n", dh->dccph_doff);
848 "too small 1\n",
849 dh->dccph_doff);
850 return 1; 767 return 1;
851 } 768 }
852 769 /*
770 * If P.Data Offset is too too large for packet, drop packet and return
771 */
853 if (!pskb_may_pull(skb, dh->dccph_doff * sizeof(u32))) { 772 if (!pskb_may_pull(skb, dh->dccph_doff * sizeof(u32))) {
854 LIMIT_NETDEBUG(KERN_WARNING "DCCP: P.Data Offset(%u) " 773 DCCP_WARN("P.Data Offset(%u) too large\n", dh->dccph_doff);
855 "too small 2\n",
856 dh->dccph_doff);
857 return 1; 774 return 1;
858 } 775 }
859 776
860 dh = dccp_hdr(skb);
861
862 /* 777 /*
863 * If P.type is not Data, Ack, or DataAck and P.X == 0 (the packet 778 * If P.type is not Data, Ack, or DataAck and P.X == 0 (the packet
864 * has short sequence numbers), drop packet and return 779 * has short sequence numbers), drop packet and return
865 */ 780 */
866 if (dh->dccph_x == 0 && 781 if (dh->dccph_type >= DCCP_PKT_DATA &&
867 dh->dccph_type != DCCP_PKT_DATA && 782 dh->dccph_type <= DCCP_PKT_DATAACK && dh->dccph_x == 0) {
868 dh->dccph_type != DCCP_PKT_ACK && 783 DCCP_WARN("P.type (%s) not Data || [Data]Ack, while P.X == 0\n",
869 dh->dccph_type != DCCP_PKT_DATAACK) { 784 dccp_packet_name(dh->dccph_type));
870 LIMIT_NETDEBUG(KERN_WARNING "DCCP: P.type (%s) not Data, Ack "
871 "nor DataAck and P.X == 0\n",
872 dccp_packet_name(dh->dccph_type));
873 return 1; 785 return 1;
874 } 786 }
875 787
788 /*
789 * If P.CsCov is too large for the packet size, drop packet and return.
790 * This must come _before_ checksumming (not as RFC 4340 suggests).
791 */
792 cscov = dccp_csum_coverage(skb);
793 if (cscov > skb->len) {
794 DCCP_WARN("P.CsCov %u exceeds packet length %d\n",
795 dh->dccph_cscov, skb->len);
796 return 1;
797 }
798
799 /* If header checksum is incorrect, drop packet and return.
800 * (This step is completed in the AF-dependent functions.) */
801 skb->csum = skb_checksum(skb, 0, cscov, 0);
802
876 return 0; 803 return 0;
877} 804}
878 805
@@ -883,17 +810,16 @@ static int dccp_v4_rcv(struct sk_buff *skb)
883{ 810{
884 const struct dccp_hdr *dh; 811 const struct dccp_hdr *dh;
885 struct sock *sk; 812 struct sock *sk;
813 int min_cov;
886 814
887 /* Step 1: Check header basics: */ 815 /* Step 1: Check header basics */
888 816
889 if (dccp_invalid_packet(skb)) 817 if (dccp_invalid_packet(skb))
890 goto discard_it; 818 goto discard_it;
891 819
892 /* If the header checksum is incorrect, drop packet and return */ 820 /* Step 1: If header checksum is incorrect, drop packet and return */
893 if (dccp_v4_verify_checksum(skb, skb->nh.iph->saddr, 821 if (dccp_v4_csum_finish(skb, skb->nh.iph->saddr, skb->nh.iph->daddr)) {
894 skb->nh.iph->daddr) < 0) { 822 DCCP_WARN("dropped packet with invalid checksum\n");
895 LIMIT_NETDEBUG(KERN_WARNING "%s: incorrect header checksum\n",
896 __FUNCTION__);
897 goto discard_it; 823 goto discard_it;
898 } 824 }
899 825
@@ -915,23 +841,20 @@ static int dccp_v4_rcv(struct sk_buff *skb)
915 dccp_pr_debug_cat("\n"); 841 dccp_pr_debug_cat("\n");
916 } else { 842 } else {
917 DCCP_SKB_CB(skb)->dccpd_ack_seq = dccp_hdr_ack_seq(skb); 843 DCCP_SKB_CB(skb)->dccpd_ack_seq = dccp_hdr_ack_seq(skb);
918 dccp_pr_debug_cat(", ack=%llu\n", 844 dccp_pr_debug_cat(", ack=%llu\n", (unsigned long long)
919 (unsigned long long)
920 DCCP_SKB_CB(skb)->dccpd_ack_seq); 845 DCCP_SKB_CB(skb)->dccpd_ack_seq);
921 } 846 }
922 847
923 /* Step 2: 848 /* Step 2:
924 * Look up flow ID in table and get corresponding socket */ 849 * Look up flow ID in table and get corresponding socket */
925 sk = __inet_lookup(&dccp_hashinfo, 850 sk = __inet_lookup(&dccp_hashinfo,
926 skb->nh.iph->saddr, dh->dccph_sport, 851 skb->nh.iph->saddr, dh->dccph_sport,
927 skb->nh.iph->daddr, dh->dccph_dport, 852 skb->nh.iph->daddr, dh->dccph_dport,
928 inet_iif(skb)); 853 inet_iif(skb));
929 854
930 /* 855 /*
931 * Step 2: 856 * Step 2:
932 * If no socket ... 857 * If no socket ...
933 * Generate Reset(No Connection) unless P.type == Reset
934 * Drop packet and return
935 */ 858 */
936 if (sk == NULL) { 859 if (sk == NULL) {
937 dccp_pr_debug("failed to look up flow ID in table and " 860 dccp_pr_debug("failed to look up flow ID in table and "
@@ -939,51 +862,61 @@ static int dccp_v4_rcv(struct sk_buff *skb)
939 goto no_dccp_socket; 862 goto no_dccp_socket;
940 } 863 }
941 864
942 /* 865 /*
943 * Step 2: 866 * Step 2:
944 * ... or S.state == TIMEWAIT, 867 * ... or S.state == TIMEWAIT,
945 * Generate Reset(No Connection) unless P.type == Reset 868 * Generate Reset(No Connection) unless P.type == Reset
946 * Drop packet and return 869 * Drop packet and return
947 */ 870 */
948
949 if (sk->sk_state == DCCP_TIME_WAIT) { 871 if (sk->sk_state == DCCP_TIME_WAIT) {
950 dccp_pr_debug("sk->sk_state == DCCP_TIME_WAIT: " 872 dccp_pr_debug("sk->sk_state == DCCP_TIME_WAIT: do_time_wait\n");
951 "do_time_wait\n"); 873 inet_twsk_put(inet_twsk(sk));
952 goto do_time_wait; 874 goto no_dccp_socket;
875 }
876
877 /*
878 * RFC 4340, sec. 9.2.1: Minimum Checksum Coverage
879 * o if MinCsCov = 0, only packets with CsCov = 0 are accepted
880 * o if MinCsCov > 0, also accept packets with CsCov >= MinCsCov
881 */
882 min_cov = dccp_sk(sk)->dccps_pcrlen;
883 if (dh->dccph_cscov && (min_cov == 0 || dh->dccph_cscov < min_cov)) {
884 dccp_pr_debug("Packet CsCov %d does not satisfy MinCsCov %d\n",
885 dh->dccph_cscov, min_cov);
886 /* FIXME: "Such packets SHOULD be reported using Data Dropped
887 * options (Section 11.7) with Drop Code 0, Protocol
888 * Constraints." */
889 goto discard_and_relse;
953 } 890 }
954 891
955 if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) 892 if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
956 goto discard_and_relse; 893 goto discard_and_relse;
957 nf_reset(skb); 894 nf_reset(skb);
958 895
959 return sk_receive_skb(sk, skb); 896 return sk_receive_skb(sk, skb, 1);
960 897
961no_dccp_socket: 898no_dccp_socket:
962 if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) 899 if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
963 goto discard_it; 900 goto discard_it;
964 /* 901 /*
965 * Step 2: 902 * Step 2:
903 * If no socket ...
966 * Generate Reset(No Connection) unless P.type == Reset 904 * Generate Reset(No Connection) unless P.type == Reset
967 * Drop packet and return 905 * Drop packet and return
968 */ 906 */
969 if (dh->dccph_type != DCCP_PKT_RESET) { 907 if (dh->dccph_type != DCCP_PKT_RESET) {
970 DCCP_SKB_CB(skb)->dccpd_reset_code = 908 DCCP_SKB_CB(skb)->dccpd_reset_code =
971 DCCP_RESET_CODE_NO_CONNECTION; 909 DCCP_RESET_CODE_NO_CONNECTION;
972 dccp_v4_ctl_send_reset(skb); 910 dccp_v4_ctl_send_reset(sk, skb);
973 } 911 }
974 912
975discard_it: 913discard_it:
976 /* Discard frame. */
977 kfree_skb(skb); 914 kfree_skb(skb);
978 return 0; 915 return 0;
979 916
980discard_and_relse: 917discard_and_relse:
981 sock_put(sk); 918 sock_put(sk);
982 goto discard_it; 919 goto discard_it;
983
984do_time_wait:
985 inet_twsk_put(inet_twsk(sk));
986 goto no_dccp_socket;
987} 920}
988 921
989static struct inet_connection_sock_af_ops dccp_ipv4_af_ops = { 922static struct inet_connection_sock_af_ops dccp_ipv4_af_ops = {
@@ -1017,20 +950,6 @@ static int dccp_v4_init_sock(struct sock *sk)
1017 return err; 950 return err;
1018} 951}
1019 952
1020static void dccp_v4_reqsk_destructor(struct request_sock *req)
1021{
1022 kfree(inet_rsk(req)->opt);
1023}
1024
1025static struct request_sock_ops dccp_request_sock_ops = {
1026 .family = PF_INET,
1027 .obj_size = sizeof(struct dccp_request_sock),
1028 .rtx_syn_ack = dccp_v4_send_response,
1029 .send_ack = dccp_v4_reqsk_send_ack,
1030 .destructor = dccp_v4_reqsk_destructor,
1031 .send_reset = dccp_v4_ctl_send_reset,
1032};
1033
1034static struct timewait_sock_ops dccp_timewait_sock_ops = { 953static struct timewait_sock_ops dccp_timewait_sock_ops = {
1035 .twsk_obj_size = sizeof(struct inet_timewait_sock), 954 .twsk_obj_size = sizeof(struct inet_timewait_sock),
1036}; 955};
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index fc4242c076..6b91a9dd04 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -36,13 +36,6 @@
36/* Socket used for sending RSTs and ACKs */ 36/* Socket used for sending RSTs and ACKs */
37static struct socket *dccp_v6_ctl_socket; 37static struct socket *dccp_v6_ctl_socket;
38 38
39static void dccp_v6_ctl_send_reset(struct sk_buff *skb);
40static void dccp_v6_reqsk_send_ack(struct sk_buff *skb,
41 struct request_sock *req);
42static void dccp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb);
43
44static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb);
45
46static struct inet_connection_sock_af_ops dccp_ipv6_mapped; 39static struct inet_connection_sock_af_ops dccp_ipv6_mapped;
47static struct inet_connection_sock_af_ops dccp_ipv6_af_ops; 40static struct inet_connection_sock_af_ops dccp_ipv6_af_ops;
48 41
@@ -65,205 +58,37 @@ static void dccp_v6_hash(struct sock *sk)
65 } 58 }
66} 59}
67 60
68static inline u16 dccp_v6_check(struct dccp_hdr *dh, int len, 61/* add pseudo-header to DCCP checksum stored in skb->csum */
69 struct in6_addr *saddr, 62static inline __sum16 dccp_v6_csum_finish(struct sk_buff *skb,
70 struct in6_addr *daddr, 63 struct in6_addr *saddr,
71 unsigned long base) 64 struct in6_addr *daddr)
72{ 65{
73 return csum_ipv6_magic(saddr, daddr, len, IPPROTO_DCCP, base); 66 return csum_ipv6_magic(saddr, daddr, skb->len, IPPROTO_DCCP, skb->csum);
74} 67}
75 68
76static __u32 dccp_v6_init_sequence(struct sock *sk, struct sk_buff *skb) 69static inline void dccp_v6_send_check(struct sock *sk, int unused_value,
70 struct sk_buff *skb)
77{ 71{
78 const struct dccp_hdr *dh = dccp_hdr(skb); 72 struct ipv6_pinfo *np = inet6_sk(sk);
79 73 struct dccp_hdr *dh = dccp_hdr(skb);
80 if (skb->protocol == htons(ETH_P_IPV6))
81 return secure_tcpv6_sequence_number(skb->nh.ipv6h->daddr.s6_addr32,
82 skb->nh.ipv6h->saddr.s6_addr32,
83 dh->dccph_dport,
84 dh->dccph_sport);
85 74
86 return secure_dccp_sequence_number(skb->nh.iph->daddr, 75 dccp_csum_outgoing(skb);
87 skb->nh.iph->saddr, 76 dh->dccph_checksum = dccp_v6_csum_finish(skb, &np->saddr, &np->daddr);
88 dh->dccph_dport,
89 dh->dccph_sport);
90} 77}
91 78
92static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, 79static inline __u32 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr,
93 int addr_len) 80 __be16 sport, __be16 dport )
94{ 81{
95 struct sockaddr_in6 *usin = (struct sockaddr_in6 *)uaddr; 82 return secure_tcpv6_sequence_number(saddr, daddr, sport, dport);
96 struct inet_connection_sock *icsk = inet_csk(sk); 83}
97 struct inet_sock *inet = inet_sk(sk);
98 struct ipv6_pinfo *np = inet6_sk(sk);
99 struct dccp_sock *dp = dccp_sk(sk);
100 struct in6_addr *saddr = NULL, *final_p = NULL, final;
101 struct flowi fl;
102 struct dst_entry *dst;
103 int addr_type;
104 int err;
105
106 dp->dccps_role = DCCP_ROLE_CLIENT;
107
108 if (addr_len < SIN6_LEN_RFC2133)
109 return -EINVAL;
110
111 if (usin->sin6_family != AF_INET6)
112 return -EAFNOSUPPORT;
113
114 memset(&fl, 0, sizeof(fl));
115
116 if (np->sndflow) {
117 fl.fl6_flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK;
118 IP6_ECN_flow_init(fl.fl6_flowlabel);
119 if (fl.fl6_flowlabel & IPV6_FLOWLABEL_MASK) {
120 struct ip6_flowlabel *flowlabel;
121 flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
122 if (flowlabel == NULL)
123 return -EINVAL;
124 ipv6_addr_copy(&usin->sin6_addr, &flowlabel->dst);
125 fl6_sock_release(flowlabel);
126 }
127 }
128 /*
129 * connect() to INADDR_ANY means loopback (BSD'ism).
130 */
131 if (ipv6_addr_any(&usin->sin6_addr))
132 usin->sin6_addr.s6_addr[15] = 1;
133
134 addr_type = ipv6_addr_type(&usin->sin6_addr);
135
136 if (addr_type & IPV6_ADDR_MULTICAST)
137 return -ENETUNREACH;
138
139 if (addr_type & IPV6_ADDR_LINKLOCAL) {
140 if (addr_len >= sizeof(struct sockaddr_in6) &&
141 usin->sin6_scope_id) {
142 /* If interface is set while binding, indices
143 * must coincide.
144 */
145 if (sk->sk_bound_dev_if &&
146 sk->sk_bound_dev_if != usin->sin6_scope_id)
147 return -EINVAL;
148
149 sk->sk_bound_dev_if = usin->sin6_scope_id;
150 }
151
152 /* Connect to link-local address requires an interface */
153 if (!sk->sk_bound_dev_if)
154 return -EINVAL;
155 }
156
157 ipv6_addr_copy(&np->daddr, &usin->sin6_addr);
158 np->flow_label = fl.fl6_flowlabel;
159
160 /*
161 * DCCP over IPv4
162 */
163 if (addr_type == IPV6_ADDR_MAPPED) {
164 u32 exthdrlen = icsk->icsk_ext_hdr_len;
165 struct sockaddr_in sin;
166
167 SOCK_DEBUG(sk, "connect: ipv4 mapped\n");
168
169 if (__ipv6_only_sock(sk))
170 return -ENETUNREACH;
171
172 sin.sin_family = AF_INET;
173 sin.sin_port = usin->sin6_port;
174 sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3];
175
176 icsk->icsk_af_ops = &dccp_ipv6_mapped;
177 sk->sk_backlog_rcv = dccp_v4_do_rcv;
178
179 err = dccp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin));
180 if (err) {
181 icsk->icsk_ext_hdr_len = exthdrlen;
182 icsk->icsk_af_ops = &dccp_ipv6_af_ops;
183 sk->sk_backlog_rcv = dccp_v6_do_rcv;
184 goto failure;
185 } else {
186 ipv6_addr_set(&np->saddr, 0, 0, htonl(0x0000FFFF),
187 inet->saddr);
188 ipv6_addr_set(&np->rcv_saddr, 0, 0, htonl(0x0000FFFF),
189 inet->rcv_saddr);
190 }
191
192 return err;
193 }
194
195 if (!ipv6_addr_any(&np->rcv_saddr))
196 saddr = &np->rcv_saddr;
197
198 fl.proto = IPPROTO_DCCP;
199 ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
200 ipv6_addr_copy(&fl.fl6_src, saddr ? saddr : &np->saddr);
201 fl.oif = sk->sk_bound_dev_if;
202 fl.fl_ip_dport = usin->sin6_port;
203 fl.fl_ip_sport = inet->sport;
204 security_sk_classify_flow(sk, &fl);
205
206 if (np->opt != NULL && np->opt->srcrt != NULL) {
207 const struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt;
208
209 ipv6_addr_copy(&final, &fl.fl6_dst);
210 ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
211 final_p = &final;
212 }
213
214 err = ip6_dst_lookup(sk, &dst, &fl);
215 if (err)
216 goto failure;
217
218 if (final_p)
219 ipv6_addr_copy(&fl.fl6_dst, final_p);
220
221 err = xfrm_lookup(&dst, &fl, sk, 0);
222 if (err < 0)
223 goto failure;
224
225 if (saddr == NULL) {
226 saddr = &fl.fl6_src;
227 ipv6_addr_copy(&np->rcv_saddr, saddr);
228 }
229
230 /* set the source address */
231 ipv6_addr_copy(&np->saddr, saddr);
232 inet->rcv_saddr = LOOPBACK4_IPV6;
233
234 __ip6_dst_store(sk, dst, NULL, NULL);
235
236 icsk->icsk_ext_hdr_len = 0;
237 if (np->opt != NULL)
238 icsk->icsk_ext_hdr_len = (np->opt->opt_flen +
239 np->opt->opt_nflen);
240
241 inet->dport = usin->sin6_port;
242
243 dccp_set_state(sk, DCCP_REQUESTING);
244 err = inet6_hash_connect(&dccp_death_row, sk);
245 if (err)
246 goto late_failure;
247 /* FIXME */
248#if 0
249 dp->dccps_gar = secure_dccp_v6_sequence_number(np->saddr.s6_addr32,
250 np->daddr.s6_addr32,
251 inet->sport,
252 inet->dport);
253#endif
254 err = dccp_connect(sk);
255 if (err)
256 goto late_failure;
257 84
258 return 0; 85static inline __u32 dccp_v6_init_sequence(struct sk_buff *skb)
86{
87 return secure_dccpv6_sequence_number(skb->nh.ipv6h->daddr.s6_addr32,
88 skb->nh.ipv6h->saddr.s6_addr32,
89 dccp_hdr(skb)->dccph_dport,
90 dccp_hdr(skb)->dccph_sport );
259 91
260late_failure:
261 dccp_set_state(sk, DCCP_CLOSED);
262 __sk_dst_reset(sk);
263failure:
264 inet->dport = 0;
265 sk->sk_route_caps = 0;
266 return err;
267} 92}
268 93
269static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 94static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
@@ -464,16 +289,12 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req,
464 if (skb != NULL) { 289 if (skb != NULL) {
465 struct dccp_hdr *dh = dccp_hdr(skb); 290 struct dccp_hdr *dh = dccp_hdr(skb);
466 291
467 dh->dccph_checksum = dccp_v6_check(dh, skb->len, 292 dh->dccph_checksum = dccp_v6_csum_finish(skb,
468 &ireq6->loc_addr, 293 &ireq6->loc_addr,
469 &ireq6->rmt_addr, 294 &ireq6->rmt_addr);
470 csum_partial((char *)dh,
471 skb->len,
472 skb->csum));
473 ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr); 295 ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr);
474 err = ip6_xmit(sk, skb, &fl, opt, 0); 296 err = ip6_xmit(sk, skb, &fl, opt, 0);
475 if (err == NET_XMIT_CN) 297 err = net_xmit_eval(err);
476 err = 0;
477 } 298 }
478 299
479done: 300done:
@@ -489,32 +310,7 @@ static void dccp_v6_reqsk_destructor(struct request_sock *req)
489 kfree_skb(inet6_rsk(req)->pktopts); 310 kfree_skb(inet6_rsk(req)->pktopts);
490} 311}
491 312
492static struct request_sock_ops dccp6_request_sock_ops = { 313static void dccp_v6_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb)
493 .family = AF_INET6,
494 .obj_size = sizeof(struct dccp6_request_sock),
495 .rtx_syn_ack = dccp_v6_send_response,
496 .send_ack = dccp_v6_reqsk_send_ack,
497 .destructor = dccp_v6_reqsk_destructor,
498 .send_reset = dccp_v6_ctl_send_reset,
499};
500
501static struct timewait_sock_ops dccp6_timewait_sock_ops = {
502 .twsk_obj_size = sizeof(struct dccp6_timewait_sock),
503};
504
505static void dccp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb)
506{
507 struct ipv6_pinfo *np = inet6_sk(sk);
508 struct dccp_hdr *dh = dccp_hdr(skb);
509
510 dh->dccph_checksum = csum_ipv6_magic(&np->saddr, &np->daddr,
511 len, IPPROTO_DCCP,
512 csum_partial((char *)dh,
513 dh->dccph_doff << 2,
514 skb->csum));
515}
516
517static void dccp_v6_ctl_send_reset(struct sk_buff *rxskb)
518{ 314{
519 struct dccp_hdr *rxdh = dccp_hdr(rxskb), *dh; 315 struct dccp_hdr *rxdh = dccp_hdr(rxskb), *dh;
520 const u32 dccp_hdr_reset_len = sizeof(struct dccp_hdr) + 316 const u32 dccp_hdr_reset_len = sizeof(struct dccp_hdr) +
@@ -522,7 +318,7 @@ static void dccp_v6_ctl_send_reset(struct sk_buff *rxskb)
522 sizeof(struct dccp_hdr_reset); 318 sizeof(struct dccp_hdr_reset);
523 struct sk_buff *skb; 319 struct sk_buff *skb;
524 struct flowi fl; 320 struct flowi fl;
525 u64 seqno; 321 u64 seqno = 0;
526 322
527 if (rxdh->dccph_type == DCCP_PKT_RESET) 323 if (rxdh->dccph_type == DCCP_PKT_RESET)
528 return; 324 return;
@@ -533,13 +329,11 @@ static void dccp_v6_ctl_send_reset(struct sk_buff *rxskb)
533 skb = alloc_skb(dccp_v6_ctl_socket->sk->sk_prot->max_header, 329 skb = alloc_skb(dccp_v6_ctl_socket->sk->sk_prot->max_header,
534 GFP_ATOMIC); 330 GFP_ATOMIC);
535 if (skb == NULL) 331 if (skb == NULL)
536 return; 332 return;
537 333
538 skb_reserve(skb, dccp_v6_ctl_socket->sk->sk_prot->max_header); 334 skb_reserve(skb, dccp_v6_ctl_socket->sk->sk_prot->max_header);
539 335
540 skb->h.raw = skb_push(skb, dccp_hdr_reset_len); 336 dh = dccp_zeroed_hdr(skb, dccp_hdr_reset_len);
541 dh = dccp_hdr(skb);
542 memset(dh, 0, dccp_hdr_reset_len);
543 337
544 /* Swap the send and the receive. */ 338 /* Swap the send and the receive. */
545 dh->dccph_type = DCCP_PKT_RESET; 339 dh->dccph_type = DCCP_PKT_RESET;
@@ -551,20 +345,20 @@ static void dccp_v6_ctl_send_reset(struct sk_buff *rxskb)
551 DCCP_SKB_CB(rxskb)->dccpd_reset_code; 345 DCCP_SKB_CB(rxskb)->dccpd_reset_code;
552 346
553 /* See "8.3.1. Abnormal Termination" in RFC 4340 */ 347 /* See "8.3.1. Abnormal Termination" in RFC 4340 */
554 seqno = 0;
555 if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ) 348 if (DCCP_SKB_CB(rxskb)->dccpd_ack_seq != DCCP_PKT_WITHOUT_ACK_SEQ)
556 dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1); 349 dccp_set_seqno(&seqno, DCCP_SKB_CB(rxskb)->dccpd_ack_seq + 1);
557 350
558 dccp_hdr_set_seq(dh, seqno); 351 dccp_hdr_set_seq(dh, seqno);
559 dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), 352 dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), DCCP_SKB_CB(rxskb)->dccpd_seq);
560 DCCP_SKB_CB(rxskb)->dccpd_seq); 353
354 dccp_csum_outgoing(skb);
355 dh->dccph_checksum = dccp_v6_csum_finish(skb, &rxskb->nh.ipv6h->saddr,
356 &rxskb->nh.ipv6h->daddr);
561 357
562 memset(&fl, 0, sizeof(fl)); 358 memset(&fl, 0, sizeof(fl));
563 ipv6_addr_copy(&fl.fl6_dst, &rxskb->nh.ipv6h->saddr); 359 ipv6_addr_copy(&fl.fl6_dst, &rxskb->nh.ipv6h->saddr);
564 ipv6_addr_copy(&fl.fl6_src, &rxskb->nh.ipv6h->daddr); 360 ipv6_addr_copy(&fl.fl6_src, &rxskb->nh.ipv6h->daddr);
565 dh->dccph_checksum = csum_ipv6_magic(&fl.fl6_src, &fl.fl6_dst, 361
566 sizeof(*dh), IPPROTO_DCCP,
567 skb->csum);
568 fl.proto = IPPROTO_DCCP; 362 fl.proto = IPPROTO_DCCP;
569 fl.oif = inet6_iif(rxskb); 363 fl.oif = inet6_iif(rxskb);
570 fl.fl_ip_dport = dh->dccph_dport; 364 fl.fl_ip_dport = dh->dccph_dport;
@@ -584,60 +378,14 @@ static void dccp_v6_ctl_send_reset(struct sk_buff *rxskb)
584 kfree_skb(skb); 378 kfree_skb(skb);
585} 379}
586 380
587static void dccp_v6_reqsk_send_ack(struct sk_buff *rxskb, 381static struct request_sock_ops dccp6_request_sock_ops = {
588 struct request_sock *req) 382 .family = AF_INET6,
589{ 383 .obj_size = sizeof(struct dccp6_request_sock),
590 struct flowi fl; 384 .rtx_syn_ack = dccp_v6_send_response,
591 struct dccp_hdr *rxdh = dccp_hdr(rxskb), *dh; 385 .send_ack = dccp_reqsk_send_ack,
592 const u32 dccp_hdr_ack_len = sizeof(struct dccp_hdr) + 386 .destructor = dccp_v6_reqsk_destructor,
593 sizeof(struct dccp_hdr_ext) + 387 .send_reset = dccp_v6_ctl_send_reset,
594 sizeof(struct dccp_hdr_ack_bits); 388};
595 struct sk_buff *skb;
596
597 skb = alloc_skb(dccp_v6_ctl_socket->sk->sk_prot->max_header,
598 GFP_ATOMIC);
599 if (skb == NULL)
600 return;
601
602 skb_reserve(skb, dccp_v6_ctl_socket->sk->sk_prot->max_header);
603
604 skb->h.raw = skb_push(skb, dccp_hdr_ack_len);
605 dh = dccp_hdr(skb);
606 memset(dh, 0, dccp_hdr_ack_len);
607
608 /* Build DCCP header and checksum it. */
609 dh->dccph_type = DCCP_PKT_ACK;
610 dh->dccph_sport = rxdh->dccph_dport;
611 dh->dccph_dport = rxdh->dccph_sport;
612 dh->dccph_doff = dccp_hdr_ack_len / 4;
613 dh->dccph_x = 1;
614
615 dccp_hdr_set_seq(dh, DCCP_SKB_CB(rxskb)->dccpd_ack_seq);
616 dccp_hdr_set_ack(dccp_hdr_ack_bits(skb),
617 DCCP_SKB_CB(rxskb)->dccpd_seq);
618
619 memset(&fl, 0, sizeof(fl));
620 ipv6_addr_copy(&fl.fl6_dst, &rxskb->nh.ipv6h->saddr);
621 ipv6_addr_copy(&fl.fl6_src, &rxskb->nh.ipv6h->daddr);
622
623 /* FIXME: calculate checksum, IPv4 also should... */
624
625 fl.proto = IPPROTO_DCCP;
626 fl.oif = inet6_iif(rxskb);
627 fl.fl_ip_dport = dh->dccph_dport;
628 fl.fl_ip_sport = dh->dccph_sport;
629 security_req_classify_flow(req, &fl);
630
631 if (!ip6_dst_lookup(NULL, &skb->dst, &fl)) {
632 if (xfrm_lookup(&skb->dst, &fl, NULL, 0) >= 0) {
633 ip6_xmit(dccp_v6_ctl_socket->sk, skb, &fl, NULL, 0);
634 DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS);
635 return;
636 }
637 }
638
639 kfree_skb(skb);
640}
641 389
642static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb) 390static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
643{ 391{
@@ -672,12 +420,11 @@ static struct sock *dccp_v6_hnd_req(struct sock *sk,struct sk_buff *skb)
672 420
673static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb) 421static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
674{ 422{
675 struct dccp_sock dp;
676 struct request_sock *req; 423 struct request_sock *req;
677 struct dccp_request_sock *dreq; 424 struct dccp_request_sock *dreq;
678 struct inet6_request_sock *ireq6; 425 struct inet6_request_sock *ireq6;
679 struct ipv6_pinfo *np = inet6_sk(sk); 426 struct ipv6_pinfo *np = inet6_sk(sk);
680 const __be32 service = dccp_hdr_request(skb)->dccph_req_service; 427 const __be32 service = dccp_hdr_request(skb)->dccph_req_service;
681 struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb); 428 struct dccp_skb_cb *dcb = DCCP_SKB_CB(skb);
682 __u8 reset_code = DCCP_RESET_CODE_TOO_BUSY; 429 __u8 reset_code = DCCP_RESET_CODE_TOO_BUSY;
683 430
@@ -690,7 +437,7 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
690 if (dccp_bad_service_code(sk, service)) { 437 if (dccp_bad_service_code(sk, service)) {
691 reset_code = DCCP_RESET_CODE_BAD_SERVICE_CODE; 438 reset_code = DCCP_RESET_CODE_BAD_SERVICE_CODE;
692 goto drop; 439 goto drop;
693 } 440 }
694 /* 441 /*
695 * There are no SYN attacks on IPv6, yet... 442 * There are no SYN attacks on IPv6, yet...
696 */ 443 */
@@ -704,9 +451,10 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
704 if (req == NULL) 451 if (req == NULL)
705 goto drop; 452 goto drop;
706 453
707 /* FIXME: process options */ 454 if (dccp_parse_options(sk, skb))
455 goto drop_and_free;
708 456
709 dccp_openreq_init(req, &dp, skb); 457 dccp_reqsk_init(req, skb);
710 458
711 if (security_inet_conn_request(sk, skb, req)) 459 if (security_inet_conn_request(sk, skb, req))
712 goto drop_and_free; 460 goto drop_and_free;
@@ -714,7 +462,6 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
714 ireq6 = inet6_rsk(req); 462 ireq6 = inet6_rsk(req);
715 ipv6_addr_copy(&ireq6->rmt_addr, &skb->nh.ipv6h->saddr); 463 ipv6_addr_copy(&ireq6->rmt_addr, &skb->nh.ipv6h->saddr);
716 ipv6_addr_copy(&ireq6->loc_addr, &skb->nh.ipv6h->daddr); 464 ipv6_addr_copy(&ireq6->loc_addr, &skb->nh.ipv6h->daddr);
717 req->rcv_wnd = dccp_feat_default_sequence_window;
718 ireq6->pktopts = NULL; 465 ireq6->pktopts = NULL;
719 466
720 if (ipv6_opt_accepted(sk, skb) || 467 if (ipv6_opt_accepted(sk, skb) ||
@@ -733,14 +480,14 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
733 /* 480 /*
734 * Step 3: Process LISTEN state 481 * Step 3: Process LISTEN state
735 * 482 *
736 * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie 483 * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookie
737 * 484 *
738 * In fact we defer setting S.GSR, S.SWL, S.SWH to 485 * In fact we defer setting S.GSR, S.SWL, S.SWH to
739 * dccp_create_openreq_child. 486 * dccp_create_openreq_child.
740 */ 487 */
741 dreq = dccp_rsk(req); 488 dreq = dccp_rsk(req);
742 dreq->dreq_isr = dcb->dccpd_seq; 489 dreq->dreq_isr = dcb->dccpd_seq;
743 dreq->dreq_iss = dccp_v6_init_sequence(sk, skb); 490 dreq->dreq_iss = dccp_v6_init_sequence(skb);
744 dreq->dreq_service = service; 491 dreq->dreq_service = service;
745 492
746 if (dccp_v6_send_response(sk, req, NULL)) 493 if (dccp_v6_send_response(sk, req, NULL))
@@ -990,18 +737,46 @@ static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
990 --ANK (980728) 737 --ANK (980728)
991 */ 738 */
992 if (np->rxopt.all) 739 if (np->rxopt.all)
740 /*
741 * FIXME: Add handling of IPV6_PKTOPTIONS skb. See the comments below
742 * (wrt ipv6_pktopions) and net/ipv6/tcp_ipv6.c for an example.
743 */
993 opt_skb = skb_clone(skb, GFP_ATOMIC); 744 opt_skb = skb_clone(skb, GFP_ATOMIC);
994 745
995 if (sk->sk_state == DCCP_OPEN) { /* Fast path */ 746 if (sk->sk_state == DCCP_OPEN) { /* Fast path */
996 if (dccp_rcv_established(sk, skb, dccp_hdr(skb), skb->len)) 747 if (dccp_rcv_established(sk, skb, dccp_hdr(skb), skb->len))
997 goto reset; 748 goto reset;
998 if (opt_skb) { 749 if (opt_skb) {
999 /* This is where we would goto ipv6_pktoptions. */ 750 /* XXX This is where we would goto ipv6_pktoptions. */
1000 __kfree_skb(opt_skb); 751 __kfree_skb(opt_skb);
1001 } 752 }
1002 return 0; 753 return 0;
1003 } 754 }
1004 755
756 /*
757 * Step 3: Process LISTEN state
758 * If S.state == LISTEN,
759 * If P.type == Request or P contains a valid Init Cookie option,
760 * (* Must scan the packet's options to check for Init
761 * Cookies. Only Init Cookies are processed here,
762 * however; other options are processed in Step 8. This
763 * scan need only be performed if the endpoint uses Init
764 * Cookies *)
765 * (* Generate a new socket and switch to that socket *)
766 * Set S := new socket for this port pair
767 * S.state = RESPOND
768 * Choose S.ISS (initial seqno) or set from Init Cookies
769 * Initialize S.GAR := S.ISS
770 * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookies
771 * Continue with S.state == RESPOND
772 * (* A Response packet will be generated in Step 11 *)
773 * Otherwise,
774 * Generate Reset(No Connection) unless P.type == Reset
775 * Drop packet and return
776 *
777 * NOTE: the check for the packet types is done in
778 * dccp_rcv_state_process
779 */
1005 if (sk->sk_state == DCCP_LISTEN) { 780 if (sk->sk_state == DCCP_LISTEN) {
1006 struct sock *nsk = dccp_v6_hnd_req(sk, skb); 781 struct sock *nsk = dccp_v6_hnd_req(sk, skb);
1007 782
@@ -1012,7 +787,7 @@ static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
1012 * otherwise we just shortcircuit this and continue with 787 * otherwise we just shortcircuit this and continue with
1013 * the new socket.. 788 * the new socket..
1014 */ 789 */
1015 if (nsk != sk) { 790 if (nsk != sk) {
1016 if (dccp_child_process(sk, nsk, skb)) 791 if (dccp_child_process(sk, nsk, skb))
1017 goto reset; 792 goto reset;
1018 if (opt_skb != NULL) 793 if (opt_skb != NULL)
@@ -1024,13 +799,13 @@ static int dccp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
1024 if (dccp_rcv_state_process(sk, skb, dccp_hdr(skb), skb->len)) 799 if (dccp_rcv_state_process(sk, skb, dccp_hdr(skb), skb->len))
1025 goto reset; 800 goto reset;
1026 if (opt_skb) { 801 if (opt_skb) {
1027 /* This is where we would goto ipv6_pktoptions. */ 802 /* XXX This is where we would goto ipv6_pktoptions. */
1028 __kfree_skb(opt_skb); 803 __kfree_skb(opt_skb);
1029 } 804 }
1030 return 0; 805 return 0;
1031 806
1032reset: 807reset:
1033 dccp_v6_ctl_send_reset(skb); 808 dccp_v6_ctl_send_reset(sk, skb);
1034discard: 809discard:
1035 if (opt_skb != NULL) 810 if (opt_skb != NULL)
1036 __kfree_skb(opt_skb); 811 __kfree_skb(opt_skb);
@@ -1043,12 +818,20 @@ static int dccp_v6_rcv(struct sk_buff **pskb)
1043 const struct dccp_hdr *dh; 818 const struct dccp_hdr *dh;
1044 struct sk_buff *skb = *pskb; 819 struct sk_buff *skb = *pskb;
1045 struct sock *sk; 820 struct sock *sk;
821 int min_cov;
1046 822
1047 /* Step 1: Check header basics: */ 823 /* Step 1: Check header basics */
1048 824
1049 if (dccp_invalid_packet(skb)) 825 if (dccp_invalid_packet(skb))
1050 goto discard_it; 826 goto discard_it;
1051 827
828 /* Step 1: If header checksum is incorrect, drop packet and return. */
829 if (dccp_v6_csum_finish(skb, &skb->nh.ipv6h->saddr,
830 &skb->nh.ipv6h->daddr)) {
831 DCCP_WARN("dropped packet with invalid checksum\n");
832 goto discard_it;
833 }
834
1052 dh = dccp_hdr(skb); 835 dh = dccp_hdr(skb);
1053 836
1054 DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(skb); 837 DCCP_SKB_CB(skb)->dccpd_seq = dccp_hdr_seq(skb);
@@ -1060,63 +843,247 @@ static int dccp_v6_rcv(struct sk_buff **pskb)
1060 DCCP_SKB_CB(skb)->dccpd_ack_seq = dccp_hdr_ack_seq(skb); 843 DCCP_SKB_CB(skb)->dccpd_ack_seq = dccp_hdr_ack_seq(skb);
1061 844
1062 /* Step 2: 845 /* Step 2:
1063 * Look up flow ID in table and get corresponding socket */ 846 * Look up flow ID in table and get corresponding socket */
1064 sk = __inet6_lookup(&dccp_hashinfo, &skb->nh.ipv6h->saddr, 847 sk = __inet6_lookup(&dccp_hashinfo, &skb->nh.ipv6h->saddr,
1065 dh->dccph_sport, 848 dh->dccph_sport,
1066 &skb->nh.ipv6h->daddr, ntohs(dh->dccph_dport), 849 &skb->nh.ipv6h->daddr, ntohs(dh->dccph_dport),
1067 inet6_iif(skb)); 850 inet6_iif(skb));
1068 /* 851 /*
1069 * Step 2: 852 * Step 2:
1070 * If no socket ... 853 * If no socket ...
1071 * Generate Reset(No Connection) unless P.type == Reset
1072 * Drop packet and return
1073 */ 854 */
1074 if (sk == NULL) 855 if (sk == NULL) {
856 dccp_pr_debug("failed to look up flow ID in table and "
857 "get corresponding socket\n");
1075 goto no_dccp_socket; 858 goto no_dccp_socket;
859 }
1076 860
1077 /* 861 /*
1078 * Step 2: 862 * Step 2:
1079 * ... or S.state == TIMEWAIT, 863 * ... or S.state == TIMEWAIT,
1080 * Generate Reset(No Connection) unless P.type == Reset 864 * Generate Reset(No Connection) unless P.type == Reset
1081 * Drop packet and return 865 * Drop packet and return
1082 */ 866 */
1083 if (sk->sk_state == DCCP_TIME_WAIT) 867 if (sk->sk_state == DCCP_TIME_WAIT) {
1084 goto do_time_wait; 868 dccp_pr_debug("sk->sk_state == DCCP_TIME_WAIT: do_time_wait\n");
869 inet_twsk_put(inet_twsk(sk));
870 goto no_dccp_socket;
871 }
872
873 /*
874 * RFC 4340, sec. 9.2.1: Minimum Checksum Coverage
875 * o if MinCsCov = 0, only packets with CsCov = 0 are accepted
876 * o if MinCsCov > 0, also accept packets with CsCov >= MinCsCov
877 */
878 min_cov = dccp_sk(sk)->dccps_pcrlen;
879 if (dh->dccph_cscov && (min_cov == 0 || dh->dccph_cscov < min_cov)) {
880 dccp_pr_debug("Packet CsCov %d does not satisfy MinCsCov %d\n",
881 dh->dccph_cscov, min_cov);
882 /* FIXME: send Data Dropped option (see also dccp_v4_rcv) */
883 goto discard_and_relse;
884 }
1085 885
1086 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) 886 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
1087 goto discard_and_relse; 887 goto discard_and_relse;
1088 888
1089 return sk_receive_skb(sk, skb) ? -1 : 0; 889 return sk_receive_skb(sk, skb, 1) ? -1 : 0;
1090 890
1091no_dccp_socket: 891no_dccp_socket:
1092 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) 892 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
1093 goto discard_it; 893 goto discard_it;
1094 /* 894 /*
1095 * Step 2: 895 * Step 2:
896 * If no socket ...
1096 * Generate Reset(No Connection) unless P.type == Reset 897 * Generate Reset(No Connection) unless P.type == Reset
1097 * Drop packet and return 898 * Drop packet and return
1098 */ 899 */
1099 if (dh->dccph_type != DCCP_PKT_RESET) { 900 if (dh->dccph_type != DCCP_PKT_RESET) {
1100 DCCP_SKB_CB(skb)->dccpd_reset_code = 901 DCCP_SKB_CB(skb)->dccpd_reset_code =
1101 DCCP_RESET_CODE_NO_CONNECTION; 902 DCCP_RESET_CODE_NO_CONNECTION;
1102 dccp_v6_ctl_send_reset(skb); 903 dccp_v6_ctl_send_reset(sk, skb);
1103 } 904 }
1104discard_it:
1105
1106 /*
1107 * Discard frame
1108 */
1109 905
906discard_it:
1110 kfree_skb(skb); 907 kfree_skb(skb);
1111 return 0; 908 return 0;
1112 909
1113discard_and_relse: 910discard_and_relse:
1114 sock_put(sk); 911 sock_put(sk);
1115 goto discard_it; 912 goto discard_it;
913}
1116 914
1117do_time_wait: 915static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
1118 inet_twsk_put(inet_twsk(sk)); 916 int addr_len)
1119 goto no_dccp_socket; 917{
918 struct sockaddr_in6 *usin = (struct sockaddr_in6 *)uaddr;
919 struct inet_connection_sock *icsk = inet_csk(sk);
920 struct inet_sock *inet = inet_sk(sk);
921 struct ipv6_pinfo *np = inet6_sk(sk);
922 struct dccp_sock *dp = dccp_sk(sk);
923 struct in6_addr *saddr = NULL, *final_p = NULL, final;
924 struct flowi fl;
925 struct dst_entry *dst;
926 int addr_type;
927 int err;
928
929 dp->dccps_role = DCCP_ROLE_CLIENT;
930
931 if (addr_len < SIN6_LEN_RFC2133)
932 return -EINVAL;
933
934 if (usin->sin6_family != AF_INET6)
935 return -EAFNOSUPPORT;
936
937 memset(&fl, 0, sizeof(fl));
938
939 if (np->sndflow) {
940 fl.fl6_flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK;
941 IP6_ECN_flow_init(fl.fl6_flowlabel);
942 if (fl.fl6_flowlabel & IPV6_FLOWLABEL_MASK) {
943 struct ip6_flowlabel *flowlabel;
944 flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel);
945 if (flowlabel == NULL)
946 return -EINVAL;
947 ipv6_addr_copy(&usin->sin6_addr, &flowlabel->dst);
948 fl6_sock_release(flowlabel);
949 }
950 }
951 /*
952 * connect() to INADDR_ANY means loopback (BSD'ism).
953 */
954 if (ipv6_addr_any(&usin->sin6_addr))
955 usin->sin6_addr.s6_addr[15] = 1;
956
957 addr_type = ipv6_addr_type(&usin->sin6_addr);
958
959 if (addr_type & IPV6_ADDR_MULTICAST)
960 return -ENETUNREACH;
961
962 if (addr_type & IPV6_ADDR_LINKLOCAL) {
963 if (addr_len >= sizeof(struct sockaddr_in6) &&
964 usin->sin6_scope_id) {
965 /* If interface is set while binding, indices
966 * must coincide.
967 */
968 if (sk->sk_bound_dev_if &&
969 sk->sk_bound_dev_if != usin->sin6_scope_id)
970 return -EINVAL;
971
972 sk->sk_bound_dev_if = usin->sin6_scope_id;
973 }
974
975 /* Connect to link-local address requires an interface */
976 if (!sk->sk_bound_dev_if)
977 return -EINVAL;
978 }
979
980 ipv6_addr_copy(&np->daddr, &usin->sin6_addr);
981 np->flow_label = fl.fl6_flowlabel;
982
983 /*
984 * DCCP over IPv4
985 */
986 if (addr_type == IPV6_ADDR_MAPPED) {
987 u32 exthdrlen = icsk->icsk_ext_hdr_len;
988 struct sockaddr_in sin;
989
990 SOCK_DEBUG(sk, "connect: ipv4 mapped\n");
991
992 if (__ipv6_only_sock(sk))
993 return -ENETUNREACH;
994
995 sin.sin_family = AF_INET;
996 sin.sin_port = usin->sin6_port;
997 sin.sin_addr.s_addr = usin->sin6_addr.s6_addr32[3];
998
999 icsk->icsk_af_ops = &dccp_ipv6_mapped;
1000 sk->sk_backlog_rcv = dccp_v4_do_rcv;
1001
1002 err = dccp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin));
1003 if (err) {
1004 icsk->icsk_ext_hdr_len = exthdrlen;
1005 icsk->icsk_af_ops = &dccp_ipv6_af_ops;
1006 sk->sk_backlog_rcv = dccp_v6_do_rcv;
1007 goto failure;
1008 } else {
1009 ipv6_addr_set(&np->saddr, 0, 0, htonl(0x0000FFFF),
1010 inet->saddr);
1011 ipv6_addr_set(&np->rcv_saddr, 0, 0, htonl(0x0000FFFF),
1012 inet->rcv_saddr);
1013 }
1014
1015 return err;
1016 }
1017
1018 if (!ipv6_addr_any(&np->rcv_saddr))
1019 saddr = &np->rcv_saddr;
1020
1021 fl.proto = IPPROTO_DCCP;
1022 ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
1023 ipv6_addr_copy(&fl.fl6_src, saddr ? saddr : &np->saddr);
1024 fl.oif = sk->sk_bound_dev_if;
1025 fl.fl_ip_dport = usin->sin6_port;
1026 fl.fl_ip_sport = inet->sport;
1027 security_sk_classify_flow(sk, &fl);
1028
1029 if (np->opt != NULL && np->opt->srcrt != NULL) {
1030 const struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt;
1031
1032 ipv6_addr_copy(&final, &fl.fl6_dst);
1033 ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
1034 final_p = &final;
1035 }
1036
1037 err = ip6_dst_lookup(sk, &dst, &fl);
1038 if (err)
1039 goto failure;
1040
1041 if (final_p)
1042 ipv6_addr_copy(&fl.fl6_dst, final_p);
1043
1044 err = xfrm_lookup(&dst, &fl, sk, 0);
1045 if (err < 0)
1046 goto failure;
1047
1048 if (saddr == NULL) {
1049 saddr = &fl.fl6_src;
1050 ipv6_addr_copy(&np->rcv_saddr, saddr);
1051 }
1052
1053 /* set the source address */
1054 ipv6_addr_copy(&np->saddr, saddr);
1055 inet->rcv_saddr = LOOPBACK4_IPV6;
1056
1057 __ip6_dst_store(sk, dst, NULL, NULL);
1058
1059 icsk->icsk_ext_hdr_len = 0;
1060 if (np->opt != NULL)
1061 icsk->icsk_ext_hdr_len = (np->opt->opt_flen +
1062 np->opt->opt_nflen);
1063
1064 inet->dport = usin->sin6_port;
1065
1066 dccp_set_state(sk, DCCP_REQUESTING);
1067 err = inet6_hash_connect(&dccp_death_row, sk);
1068 if (err)
1069 goto late_failure;
1070
1071 dp->dccps_iss = secure_dccpv6_sequence_number(np->saddr.s6_addr32,
1072 np->daddr.s6_addr32,
1073 inet->sport, inet->dport);
1074 err = dccp_connect(sk);
1075 if (err)
1076 goto late_failure;
1077
1078 return 0;
1079
1080late_failure:
1081 dccp_set_state(sk, DCCP_CLOSED);
1082 __sk_dst_reset(sk);
1083failure:
1084 inet->dport = 0;
1085 sk->sk_route_caps = 0;
1086 return err;
1120} 1087}
1121 1088
1122static struct inet_connection_sock_af_ops dccp_ipv6_af_ops = { 1089static struct inet_connection_sock_af_ops dccp_ipv6_af_ops = {
@@ -1179,6 +1146,10 @@ static int dccp_v6_destroy_sock(struct sock *sk)
1179 return inet6_destroy_sock(sk); 1146 return inet6_destroy_sock(sk);
1180} 1147}
1181 1148
1149static struct timewait_sock_ops dccp6_timewait_sock_ops = {
1150 .twsk_obj_size = sizeof(struct dccp6_timewait_sock),
1151};
1152
1182static struct proto dccp_v6_prot = { 1153static struct proto dccp_v6_prot = {
1183 .name = "DCCPv6", 1154 .name = "DCCPv6",
1184 .owner = THIS_MODULE, 1155 .owner = THIS_MODULE,
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c
index 9045438d6b..6656bb497c 100644
--- a/net/dccp/minisocks.c
+++ b/net/dccp/minisocks.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/dccp.h> 13#include <linux/dccp.h>
14#include <linux/kernel.h>
14#include <linux/skbuff.h> 15#include <linux/skbuff.h>
15#include <linux/timer.h> 16#include <linux/timer.h>
16 17
@@ -31,8 +32,7 @@ struct inet_timewait_death_row dccp_death_row = {
31 .tw_timer = TIMER_INITIALIZER(inet_twdr_hangman, 0, 32 .tw_timer = TIMER_INITIALIZER(inet_twdr_hangman, 0,
32 (unsigned long)&dccp_death_row), 33 (unsigned long)&dccp_death_row),
33 .twkill_work = __WORK_INITIALIZER(dccp_death_row.twkill_work, 34 .twkill_work = __WORK_INITIALIZER(dccp_death_row.twkill_work,
34 inet_twdr_twkill_work, 35 inet_twdr_twkill_work),
35 &dccp_death_row),
36/* Short-time timewait calendar */ 36/* Short-time timewait calendar */
37 37
38 .twcal_hand = -1, 38 .twcal_hand = -1,
@@ -83,8 +83,7 @@ void dccp_time_wait(struct sock *sk, int state, int timeo)
83 * socket up. We've got bigger problems than 83 * socket up. We've got bigger problems than
84 * non-graceful socket closings. 84 * non-graceful socket closings.
85 */ 85 */
86 LIMIT_NETDEBUG(KERN_INFO "DCCP: time wait bucket " 86 DCCP_WARN("time wait bucket table overflow\n");
87 "table overflow\n");
88 } 87 }
89 88
90 dccp_done(sk); 89 dccp_done(sk);
@@ -97,8 +96,8 @@ struct sock *dccp_create_openreq_child(struct sock *sk,
97 /* 96 /*
98 * Step 3: Process LISTEN state 97 * Step 3: Process LISTEN state
99 * 98 *
100 * // Generate a new socket and switch to that socket 99 * (* Generate a new socket and switch to that socket *)
101 * Set S := new socket for this port pair 100 * Set S := new socket for this port pair
102 */ 101 */
103 struct sock *newsk = inet_csk_clone(sk, req, GFP_ATOMIC); 102 struct sock *newsk = inet_csk_clone(sk, req, GFP_ATOMIC);
104 103
@@ -147,9 +146,9 @@ out_free:
147 /* 146 /*
148 * Step 3: Process LISTEN state 147 * Step 3: Process LISTEN state
149 * 148 *
150 * Choose S.ISS (initial seqno) or set from Init Cookie 149 * Choose S.ISS (initial seqno) or set from Init Cookies
151 * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init 150 * Initialize S.GAR := S.ISS
152 * Cookie 151 * Set S.ISR, S.GSR, S.SWL, S.SWH from packet or Init Cookies
153 */ 152 */
154 153
155 /* See dccp_v4_conn_request */ 154 /* See dccp_v4_conn_request */
@@ -183,7 +182,7 @@ out_free:
183 182
184EXPORT_SYMBOL_GPL(dccp_create_openreq_child); 183EXPORT_SYMBOL_GPL(dccp_create_openreq_child);
185 184
186/* 185/*
187 * Process an incoming packet for RESPOND sockets represented 186 * Process an incoming packet for RESPOND sockets represented
188 * as an request_sock. 187 * as an request_sock.
189 */ 188 */
@@ -195,15 +194,17 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb,
195 194
196 /* Check for retransmitted REQUEST */ 195 /* Check for retransmitted REQUEST */
197 if (dccp_hdr(skb)->dccph_type == DCCP_PKT_REQUEST) { 196 if (dccp_hdr(skb)->dccph_type == DCCP_PKT_REQUEST) {
198 if (after48(DCCP_SKB_CB(skb)->dccpd_seq, 197 struct dccp_request_sock *dreq = dccp_rsk(req);
199 dccp_rsk(req)->dreq_isr)) {
200 struct dccp_request_sock *dreq = dccp_rsk(req);
201 198
199 if (after48(DCCP_SKB_CB(skb)->dccpd_seq, dreq->dreq_isr)) {
202 dccp_pr_debug("Retransmitted REQUEST\n"); 200 dccp_pr_debug("Retransmitted REQUEST\n");
203 /* Send another RESPONSE packet */ 201 dreq->dreq_isr = DCCP_SKB_CB(skb)->dccpd_seq;
204 dccp_set_seqno(&dreq->dreq_iss, dreq->dreq_iss + 1); 202 /*
205 dccp_set_seqno(&dreq->dreq_isr, 203 * Send another RESPONSE packet
206 DCCP_SKB_CB(skb)->dccpd_seq); 204 * To protect against Request floods, increment retrans
205 * counter (backoff, monitored by dccp_response_timer).
206 */
207 req->retrans++;
207 req->rsk_ops->rtx_syn_ack(sk, req, NULL); 208 req->rsk_ops->rtx_syn_ack(sk, req, NULL);
208 } 209 }
209 /* Network Duplicate, discard packet */ 210 /* Network Duplicate, discard packet */
@@ -243,7 +244,7 @@ listen_overflow:
243 DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_TOO_BUSY; 244 DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_TOO_BUSY;
244drop: 245drop:
245 if (dccp_hdr(skb)->dccph_type != DCCP_PKT_RESET) 246 if (dccp_hdr(skb)->dccph_type != DCCP_PKT_RESET)
246 req->rsk_ops->send_reset(skb); 247 req->rsk_ops->send_reset(sk, skb);
247 248
248 inet_csk_reqsk_queue_drop(sk, req, prev); 249 inet_csk_reqsk_queue_drop(sk, req, prev);
249 goto out; 250 goto out;
@@ -283,3 +284,19 @@ int dccp_child_process(struct sock *parent, struct sock *child,
283} 284}
284 285
285EXPORT_SYMBOL_GPL(dccp_child_process); 286EXPORT_SYMBOL_GPL(dccp_child_process);
287
288void dccp_reqsk_send_ack(struct sk_buff *skb, struct request_sock *rsk)
289{
290 DCCP_BUG("DCCP-ACK packets are never sent in LISTEN/RESPOND state");
291}
292
293EXPORT_SYMBOL_GPL(dccp_reqsk_send_ack);
294
295void dccp_reqsk_init(struct request_sock *req, struct sk_buff *skb)
296{
297 inet_rsk(req)->rmt_port = dccp_hdr(skb)->dccph_sport;
298 inet_rsk(req)->acked = 0;
299 req->rcv_wnd = sysctl_dccp_feat_sequence_window;
300}
301
302EXPORT_SYMBOL_GPL(dccp_reqsk_init);
diff --git a/net/dccp/options.c b/net/dccp/options.c
index fb0db1f7cd..c03ba61eb6 100644
--- a/net/dccp/options.c
+++ b/net/dccp/options.c
@@ -22,23 +22,23 @@
22#include "dccp.h" 22#include "dccp.h"
23#include "feat.h" 23#include "feat.h"
24 24
25int dccp_feat_default_sequence_window = DCCPF_INITIAL_SEQUENCE_WINDOW; 25int sysctl_dccp_feat_sequence_window = DCCPF_INITIAL_SEQUENCE_WINDOW;
26int dccp_feat_default_rx_ccid = DCCPF_INITIAL_CCID; 26int sysctl_dccp_feat_rx_ccid = DCCPF_INITIAL_CCID;
27int dccp_feat_default_tx_ccid = DCCPF_INITIAL_CCID; 27int sysctl_dccp_feat_tx_ccid = DCCPF_INITIAL_CCID;
28int dccp_feat_default_ack_ratio = DCCPF_INITIAL_ACK_RATIO; 28int sysctl_dccp_feat_ack_ratio = DCCPF_INITIAL_ACK_RATIO;
29int dccp_feat_default_send_ack_vector = DCCPF_INITIAL_SEND_ACK_VECTOR; 29int sysctl_dccp_feat_send_ack_vector = DCCPF_INITIAL_SEND_ACK_VECTOR;
30int dccp_feat_default_send_ndp_count = DCCPF_INITIAL_SEND_NDP_COUNT; 30int sysctl_dccp_feat_send_ndp_count = DCCPF_INITIAL_SEND_NDP_COUNT;
31 31
32EXPORT_SYMBOL_GPL(dccp_feat_default_sequence_window); 32EXPORT_SYMBOL_GPL(sysctl_dccp_feat_sequence_window);
33 33
34void dccp_minisock_init(struct dccp_minisock *dmsk) 34void dccp_minisock_init(struct dccp_minisock *dmsk)
35{ 35{
36 dmsk->dccpms_sequence_window = dccp_feat_default_sequence_window; 36 dmsk->dccpms_sequence_window = sysctl_dccp_feat_sequence_window;
37 dmsk->dccpms_rx_ccid = dccp_feat_default_rx_ccid; 37 dmsk->dccpms_rx_ccid = sysctl_dccp_feat_rx_ccid;
38 dmsk->dccpms_tx_ccid = dccp_feat_default_tx_ccid; 38 dmsk->dccpms_tx_ccid = sysctl_dccp_feat_tx_ccid;
39 dmsk->dccpms_ack_ratio = dccp_feat_default_ack_ratio; 39 dmsk->dccpms_ack_ratio = sysctl_dccp_feat_ack_ratio;
40 dmsk->dccpms_send_ack_vector = dccp_feat_default_send_ack_vector; 40 dmsk->dccpms_send_ack_vector = sysctl_dccp_feat_send_ack_vector;
41 dmsk->dccpms_send_ndp_count = dccp_feat_default_send_ndp_count; 41 dmsk->dccpms_send_ndp_count = sysctl_dccp_feat_send_ndp_count;
42} 42}
43 43
44static u32 dccp_decode_value_var(const unsigned char *bf, const u8 len) 44static u32 dccp_decode_value_var(const unsigned char *bf, const u8 len)
@@ -60,12 +60,9 @@ static u32 dccp_decode_value_var(const unsigned char *bf, const u8 len)
60int dccp_parse_options(struct sock *sk, struct sk_buff *skb) 60int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
61{ 61{
62 struct dccp_sock *dp = dccp_sk(sk); 62 struct dccp_sock *dp = dccp_sk(sk);
63#ifdef CONFIG_IP_DCCP_DEBUG
64 const char *debug_prefix = dp->dccps_role == DCCP_ROLE_CLIENT ?
65 "CLIENT rx opt: " : "server rx opt: ";
66#endif
67 const struct dccp_hdr *dh = dccp_hdr(skb); 63 const struct dccp_hdr *dh = dccp_hdr(skb);
68 const u8 pkt_type = DCCP_SKB_CB(skb)->dccpd_type; 64 const u8 pkt_type = DCCP_SKB_CB(skb)->dccpd_type;
65 u64 ackno = DCCP_SKB_CB(skb)->dccpd_ack_seq;
69 unsigned char *options = (unsigned char *)dh + dccp_hdr_len(skb); 66 unsigned char *options = (unsigned char *)dh + dccp_hdr_len(skb);
70 unsigned char *opt_ptr = options; 67 unsigned char *opt_ptr = options;
71 const unsigned char *opt_end = (unsigned char *)dh + 68 const unsigned char *opt_end = (unsigned char *)dh +
@@ -119,7 +116,7 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
119 goto out_invalid_option; 116 goto out_invalid_option;
120 117
121 opt_recv->dccpor_ndp = dccp_decode_value_var(value, len); 118 opt_recv->dccpor_ndp = dccp_decode_value_var(value, len);
122 dccp_pr_debug("%sNDP count=%d\n", debug_prefix, 119 dccp_pr_debug("%s rx opt: NDP count=%d\n", dccp_role(sk),
123 opt_recv->dccpor_ndp); 120 opt_recv->dccpor_ndp);
124 break; 121 break;
125 case DCCPO_CHANGE_L: 122 case DCCPO_CHANGE_L:
@@ -153,7 +150,7 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
153 break; 150 break;
154 151
155 if (dccp_msk(sk)->dccpms_send_ack_vector && 152 if (dccp_msk(sk)->dccpms_send_ack_vector &&
156 dccp_ackvec_parse(sk, skb, opt, value, len)) 153 dccp_ackvec_parse(sk, skb, &ackno, opt, value, len))
157 goto out_invalid_option; 154 goto out_invalid_option;
158 break; 155 break;
159 case DCCPO_TIMESTAMP: 156 case DCCPO_TIMESTAMP:
@@ -165,8 +162,8 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
165 dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp; 162 dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp;
166 dccp_timestamp(sk, &dp->dccps_timestamp_time); 163 dccp_timestamp(sk, &dp->dccps_timestamp_time);
167 164
168 dccp_pr_debug("%sTIMESTAMP=%u, ackno=%llu\n", 165 dccp_pr_debug("%s rx opt: TIMESTAMP=%u, ackno=%llu\n",
169 debug_prefix, opt_recv->dccpor_timestamp, 166 dccp_role(sk), opt_recv->dccpor_timestamp,
170 (unsigned long long) 167 (unsigned long long)
171 DCCP_SKB_CB(skb)->dccpd_ack_seq); 168 DCCP_SKB_CB(skb)->dccpd_ack_seq);
172 break; 169 break;
@@ -176,8 +173,8 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
176 173
177 opt_recv->dccpor_timestamp_echo = ntohl(*(__be32 *)value); 174 opt_recv->dccpor_timestamp_echo = ntohl(*(__be32 *)value);
178 175
179 dccp_pr_debug("%sTIMESTAMP_ECHO=%u, len=%d, ackno=%llu, ", 176 dccp_pr_debug("%s rx opt: TIMESTAMP_ECHO=%u, len=%d, "
180 debug_prefix, 177 "ackno=%llu, ", dccp_role(sk),
181 opt_recv->dccpor_timestamp_echo, 178 opt_recv->dccpor_timestamp_echo,
182 len + 2, 179 len + 2,
183 (unsigned long long) 180 (unsigned long long)
@@ -211,8 +208,8 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
211 if (elapsed_time > opt_recv->dccpor_elapsed_time) 208 if (elapsed_time > opt_recv->dccpor_elapsed_time)
212 opt_recv->dccpor_elapsed_time = elapsed_time; 209 opt_recv->dccpor_elapsed_time = elapsed_time;
213 210
214 dccp_pr_debug("%sELAPSED_TIME=%d\n", debug_prefix, 211 dccp_pr_debug("%s rx opt: ELAPSED_TIME=%d\n",
215 elapsed_time); 212 dccp_role(sk), elapsed_time);
216 break; 213 break;
217 /* 214 /*
218 * From RFC 4340, sec. 10.3: 215 * From RFC 4340, sec. 10.3:
@@ -242,9 +239,8 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
242 } 239 }
243 break; 240 break;
244 default: 241 default:
245 pr_info("DCCP(%p): option %d(len=%d) not " 242 DCCP_CRIT("DCCP(%p): option %d(len=%d) not "
246 "implemented, ignoring\n", 243 "implemented, ignoring", sk, opt, len);
247 sk, opt, len);
248 break; 244 break;
249 } 245 }
250 246
@@ -261,7 +257,7 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
261out_invalid_option: 257out_invalid_option:
262 DCCP_INC_STATS_BH(DCCP_MIB_INVALIDOPT); 258 DCCP_INC_STATS_BH(DCCP_MIB_INVALIDOPT);
263 DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_OPTION_ERROR; 259 DCCP_SKB_CB(skb)->dccpd_reset_code = DCCP_RESET_CODE_OPTION_ERROR;
264 pr_info("DCCP(%p): invalid option %d, len=%d\n", sk, opt, len); 260 DCCP_WARN("DCCP(%p): invalid option %d, len=%d", sk, opt, len);
265 return -1; 261 return -1;
266} 262}
267 263
@@ -451,8 +447,7 @@ static int dccp_insert_feat_opt(struct sk_buff *skb, u8 type, u8 feat,
451 u8 *to; 447 u8 *to;
452 448
453 if (DCCP_SKB_CB(skb)->dccpd_opt_len + len + 3 > DCCP_MAX_OPT_LEN) { 449 if (DCCP_SKB_CB(skb)->dccpd_opt_len + len + 3 > DCCP_MAX_OPT_LEN) {
454 LIMIT_NETDEBUG(KERN_INFO "DCCP: packet too small" 450 DCCP_WARN("packet too small for feature %d option!\n", feat);
455 " to insert feature %d option!\n", feat);
456 return -1; 451 return -1;
457 } 452 }
458 453
@@ -465,8 +460,10 @@ static int dccp_insert_feat_opt(struct sk_buff *skb, u8 type, u8 feat,
465 460
466 if (len) 461 if (len)
467 memcpy(to, val, len); 462 memcpy(to, val, len);
468 dccp_pr_debug("option %d feat %d len %d\n", type, feat, len);
469 463
464 dccp_pr_debug("%s(%s (%d), ...), length %d\n",
465 dccp_feat_typename(type),
466 dccp_feat_name(feat), feat, len);
470 return 0; 467 return 0;
471} 468}
472 469
@@ -560,11 +557,6 @@ int dccp_insert_options(struct sock *sk, struct sk_buff *skb)
560 return -1; 557 return -1;
561 dp->dccps_hc_rx_insert_options = 0; 558 dp->dccps_hc_rx_insert_options = 0;
562 } 559 }
563 if (dp->dccps_hc_tx_insert_options) {
564 if (ccid_hc_tx_insert_options(dp->dccps_hc_tx_ccid, sk, skb))
565 return -1;
566 dp->dccps_hc_tx_insert_options = 0;
567 }
568 560
569 /* Feature negotiation */ 561 /* Feature negotiation */
570 /* Data packets can't do feat negotiation */ 562 /* Data packets can't do feat negotiation */
diff --git a/net/dccp/output.c b/net/dccp/output.c
index 7102e3aed4..8245696590 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * net/dccp/output.c 2 * net/dccp/output.c
3 * 3 *
4 * An implementation of the DCCP protocol 4 * An implementation of the DCCP protocol
5 * Arnaldo Carvalho de Melo <acme@conectiva.com.br> 5 * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
6 * 6 *
@@ -88,16 +88,15 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
88 return -EPROTO; 88 return -EPROTO;
89 } 89 }
90 90
91 skb->h.raw = skb_push(skb, dccp_header_size);
92 dh = dccp_hdr(skb);
93 91
94 /* Build DCCP header and checksum it. */ 92 /* Build DCCP header and checksum it. */
95 memset(dh, 0, dccp_header_size); 93 dh = dccp_zeroed_hdr(skb, dccp_header_size);
96 dh->dccph_type = dcb->dccpd_type; 94 dh->dccph_type = dcb->dccpd_type;
97 dh->dccph_sport = inet->sport; 95 dh->dccph_sport = inet->sport;
98 dh->dccph_dport = inet->dport; 96 dh->dccph_dport = inet->dport;
99 dh->dccph_doff = (dccp_header_size + dcb->dccpd_opt_len) / 4; 97 dh->dccph_doff = (dccp_header_size + dcb->dccpd_opt_len) / 4;
100 dh->dccph_ccval = dcb->dccpd_ccval; 98 dh->dccph_ccval = dcb->dccpd_ccval;
99 dh->dccph_cscov = dp->dccps_pcslen;
101 /* XXX For now we're using only 48 bits sequence numbers */ 100 /* XXX For now we're using only 48 bits sequence numbers */
102 dh->dccph_x = 1; 101 dh->dccph_x = 1;
103 102
@@ -117,7 +116,7 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
117 break; 116 break;
118 } 117 }
119 118
120 icsk->icsk_af_ops->send_check(sk, skb->len, skb); 119 icsk->icsk_af_ops->send_check(sk, 0, skb);
121 120
122 if (set_ack) 121 if (set_ack)
123 dccp_event_ack_sent(sk); 122 dccp_event_ack_sent(sk);
@@ -125,17 +124,8 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
125 DCCP_INC_STATS(DCCP_MIB_OUTSEGS); 124 DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
126 125
127 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); 126 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
128 err = icsk->icsk_af_ops->queue_xmit(skb, 0); 127 err = icsk->icsk_af_ops->queue_xmit(skb, sk, 0);
129 if (err <= 0) 128 return net_xmit_eval(err);
130 return err;
131
132 /* NET_XMIT_CN is special. It does not guarantee,
133 * that this packet is lost. It tells that device
134 * is about to start to drop packets or already
135 * drops some packets of the same priority and
136 * invokes us to send less aggressively.
137 */
138 return err == NET_XMIT_CN ? 0 : err;
139 } 129 }
140 return -ENOBUFS; 130 return -ENOBUFS;
141} 131}
@@ -185,14 +175,12 @@ void dccp_write_space(struct sock *sk)
185/** 175/**
186 * dccp_wait_for_ccid - Wait for ccid to tell us we can send a packet 176 * dccp_wait_for_ccid - Wait for ccid to tell us we can send a packet
187 * @sk: socket to wait for 177 * @sk: socket to wait for
188 * @timeo: for how long
189 */ 178 */
190static int dccp_wait_for_ccid(struct sock *sk, struct sk_buff *skb, 179static int dccp_wait_for_ccid(struct sock *sk, struct sk_buff *skb)
191 long *timeo)
192{ 180{
193 struct dccp_sock *dp = dccp_sk(sk); 181 struct dccp_sock *dp = dccp_sk(sk);
194 DEFINE_WAIT(wait); 182 DEFINE_WAIT(wait);
195 long delay; 183 unsigned long delay;
196 int rc; 184 int rc;
197 185
198 while (1) { 186 while (1) {
@@ -200,22 +188,16 @@ static int dccp_wait_for_ccid(struct sock *sk, struct sk_buff *skb,
200 188
201 if (sk->sk_err) 189 if (sk->sk_err)
202 goto do_error; 190 goto do_error;
203 if (!*timeo)
204 goto do_nonblock;
205 if (signal_pending(current)) 191 if (signal_pending(current))
206 goto do_interrupted; 192 goto do_interrupted;
207 193
208 rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb, 194 rc = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb);
209 skb->len);
210 if (rc <= 0) 195 if (rc <= 0)
211 break; 196 break;
212 delay = msecs_to_jiffies(rc); 197 delay = msecs_to_jiffies(rc);
213 if (delay > *timeo || delay < 0)
214 goto do_nonblock;
215
216 sk->sk_write_pending++; 198 sk->sk_write_pending++;
217 release_sock(sk); 199 release_sock(sk);
218 *timeo -= schedule_timeout(delay); 200 schedule_timeout(delay);
219 lock_sock(sk); 201 lock_sock(sk);
220 sk->sk_write_pending--; 202 sk->sk_write_pending--;
221 } 203 }
@@ -226,11 +208,8 @@ out:
226do_error: 208do_error:
227 rc = -EPIPE; 209 rc = -EPIPE;
228 goto out; 210 goto out;
229do_nonblock:
230 rc = -EAGAIN;
231 goto out;
232do_interrupted: 211do_interrupted:
233 rc = sock_intr_errno(*timeo); 212 rc = -EINTR;
234 goto out; 213 goto out;
235} 214}
236 215
@@ -251,12 +230,9 @@ void dccp_write_xmit(struct sock *sk, int block)
251{ 230{
252 struct dccp_sock *dp = dccp_sk(sk); 231 struct dccp_sock *dp = dccp_sk(sk);
253 struct sk_buff *skb; 232 struct sk_buff *skb;
254 long timeo = 30000; /* If a packet is taking longer than 2 secs
255 we have other issues */
256 233
257 while ((skb = skb_peek(&sk->sk_write_queue))) { 234 while ((skb = skb_peek(&sk->sk_write_queue))) {
258 int err = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb, 235 int err = ccid_hc_tx_send_packet(dp->dccps_hc_tx_ccid, sk, skb);
259 skb->len);
260 236
261 if (err > 0) { 237 if (err > 0) {
262 if (!block) { 238 if (!block) {
@@ -264,12 +240,9 @@ void dccp_write_xmit(struct sock *sk, int block)
264 msecs_to_jiffies(err)+jiffies); 240 msecs_to_jiffies(err)+jiffies);
265 break; 241 break;
266 } else 242 } else
267 err = dccp_wait_for_ccid(sk, skb, &timeo); 243 err = dccp_wait_for_ccid(sk, skb);
268 if (err) { 244 if (err && err != -EINTR)
269 printk(KERN_CRIT "%s:err at dccp_wait_for_ccid" 245 DCCP_BUG("err=%d after dccp_wait_for_ccid", err);
270 " %d\n", __FUNCTION__, err);
271 dump_stack();
272 }
273 } 246 }
274 247
275 skb_dequeue(&sk->sk_write_queue); 248 skb_dequeue(&sk->sk_write_queue);
@@ -291,14 +264,13 @@ void dccp_write_xmit(struct sock *sk, int block)
291 264
292 err = dccp_transmit_skb(sk, skb); 265 err = dccp_transmit_skb(sk, skb);
293 ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, 0, len); 266 ccid_hc_tx_packet_sent(dp->dccps_hc_tx_ccid, sk, 0, len);
294 if (err) { 267 if (err)
295 printk(KERN_CRIT "%s:err from " 268 DCCP_BUG("err=%d after ccid_hc_tx_packet_sent",
296 "ccid_hc_tx_packet_sent %d\n", 269 err);
297 __FUNCTION__, err); 270 } else {
298 dump_stack(); 271 dccp_pr_debug("packet discarded\n");
299 }
300 } else
301 kfree(skb); 272 kfree(skb);
273 }
302 } 274 }
303} 275}
304 276
@@ -329,9 +301,10 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
329 skb_reserve(skb, sk->sk_prot->max_header); 301 skb_reserve(skb, sk->sk_prot->max_header);
330 302
331 skb->dst = dst_clone(dst); 303 skb->dst = dst_clone(dst);
332 skb->csum = 0;
333 304
334 dreq = dccp_rsk(req); 305 dreq = dccp_rsk(req);
306 if (inet_rsk(req)->acked) /* increase ISS upon retransmission */
307 dccp_inc_seqno(&dreq->dreq_iss);
335 DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESPONSE; 308 DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_RESPONSE;
336 DCCP_SKB_CB(skb)->dccpd_seq = dreq->dreq_iss; 309 DCCP_SKB_CB(skb)->dccpd_seq = dreq->dreq_iss;
337 310
@@ -340,10 +313,8 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
340 return NULL; 313 return NULL;
341 } 314 }
342 315
343 skb->h.raw = skb_push(skb, dccp_header_size); 316 /* Build and checksum header */
344 317 dh = dccp_zeroed_hdr(skb, dccp_header_size);
345 dh = dccp_hdr(skb);
346 memset(dh, 0, dccp_header_size);
347 318
348 dh->dccph_sport = inet_sk(sk)->sport; 319 dh->dccph_sport = inet_sk(sk)->sport;
349 dh->dccph_dport = inet_rsk(req)->rmt_port; 320 dh->dccph_dport = inet_rsk(req)->rmt_port;
@@ -355,6 +326,10 @@ struct sk_buff *dccp_make_response(struct sock *sk, struct dst_entry *dst,
355 dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), dreq->dreq_isr); 326 dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), dreq->dreq_isr);
356 dccp_hdr_response(skb)->dccph_resp_service = dreq->dreq_service; 327 dccp_hdr_response(skb)->dccph_resp_service = dreq->dreq_service;
357 328
329 dccp_csum_outgoing(skb);
330
331 /* We use `acked' to remember that a Response was already sent. */
332 inet_rsk(req)->acked = 1;
358 DCCP_INC_STATS(DCCP_MIB_OUTSEGS); 333 DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
359 return skb; 334 return skb;
360} 335}
@@ -363,7 +338,6 @@ EXPORT_SYMBOL_GPL(dccp_make_response);
363 338
364static struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst, 339static struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst,
365 const enum dccp_reset_codes code) 340 const enum dccp_reset_codes code)
366
367{ 341{
368 struct dccp_hdr *dh; 342 struct dccp_hdr *dh;
369 struct dccp_sock *dp = dccp_sk(sk); 343 struct dccp_sock *dp = dccp_sk(sk);
@@ -379,7 +353,6 @@ static struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst,
379 skb_reserve(skb, sk->sk_prot->max_header); 353 skb_reserve(skb, sk->sk_prot->max_header);
380 354
381 skb->dst = dst_clone(dst); 355 skb->dst = dst_clone(dst);
382 skb->csum = 0;
383 356
384 dccp_inc_seqno(&dp->dccps_gss); 357 dccp_inc_seqno(&dp->dccps_gss);
385 358
@@ -392,10 +365,7 @@ static struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst,
392 return NULL; 365 return NULL;
393 } 366 }
394 367
395 skb->h.raw = skb_push(skb, dccp_header_size); 368 dh = dccp_zeroed_hdr(skb, dccp_header_size);
396
397 dh = dccp_hdr(skb);
398 memset(dh, 0, dccp_header_size);
399 369
400 dh->dccph_sport = inet_sk(sk)->sport; 370 dh->dccph_sport = inet_sk(sk)->sport;
401 dh->dccph_dport = inet_sk(sk)->dport; 371 dh->dccph_dport = inet_sk(sk)->dport;
@@ -407,7 +377,7 @@ static struct sk_buff *dccp_make_reset(struct sock *sk, struct dst_entry *dst,
407 dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), dp->dccps_gsr); 377 dccp_hdr_set_ack(dccp_hdr_ack_bits(skb), dp->dccps_gsr);
408 378
409 dccp_hdr_reset(skb)->dccph_reset_code = code; 379 dccp_hdr_reset(skb)->dccph_reset_code = code;
410 inet_csk(sk)->icsk_af_ops->send_check(sk, skb->len, skb); 380 inet_csk(sk)->icsk_af_ops->send_check(sk, 0, skb);
411 381
412 DCCP_INC_STATS(DCCP_MIB_OUTSEGS); 382 DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
413 return skb; 383 return skb;
@@ -426,9 +396,8 @@ int dccp_send_reset(struct sock *sk, enum dccp_reset_codes code)
426 code); 396 code);
427 if (skb != NULL) { 397 if (skb != NULL) {
428 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); 398 memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
429 err = inet_csk(sk)->icsk_af_ops->queue_xmit(skb, 0); 399 err = inet_csk(sk)->icsk_af_ops->queue_xmit(skb, sk, 0);
430 if (err == NET_XMIT_CN) 400 return net_xmit_eval(err);
431 err = 0;
432 } 401 }
433 } 402 }
434 403
@@ -449,17 +418,21 @@ static inline void dccp_connect_init(struct sock *sk)
449 418
450 dccp_sync_mss(sk, dst_mtu(dst)); 419 dccp_sync_mss(sk, dst_mtu(dst));
451 420
452 dccp_update_gss(sk, dp->dccps_iss); 421 /*
453 /*
454 * SWL and AWL are initially adjusted so that they are not less than 422 * SWL and AWL are initially adjusted so that they are not less than
455 * the initial Sequence Numbers received and sent, respectively: 423 * the initial Sequence Numbers received and sent, respectively:
456 * SWL := max(GSR + 1 - floor(W/4), ISR), 424 * SWL := max(GSR + 1 - floor(W/4), ISR),
457 * AWL := max(GSS - W' + 1, ISS). 425 * AWL := max(GSS - W' + 1, ISS).
458 * These adjustments MUST be applied only at the beginning of the 426 * These adjustments MUST be applied only at the beginning of the
459 * connection. 427 * connection.
460 */ 428 */
429 dccp_update_gss(sk, dp->dccps_iss);
461 dccp_set_seqno(&dp->dccps_awl, max48(dp->dccps_awl, dp->dccps_iss)); 430 dccp_set_seqno(&dp->dccps_awl, max48(dp->dccps_awl, dp->dccps_iss));
462 431
432 /* S.GAR - greatest valid acknowledgement number received on a non-Sync;
433 * initialized to S.ISS (sec. 8.5) */
434 dp->dccps_gar = dp->dccps_iss;
435
463 icsk->icsk_retransmits = 0; 436 icsk->icsk_retransmits = 0;
464 init_timer(&dp->dccps_xmit_timer); 437 init_timer(&dp->dccps_xmit_timer);
465 dp->dccps_xmit_timer.data = (unsigned long)sk; 438 dp->dccps_xmit_timer.data = (unsigned long)sk;
@@ -481,7 +454,6 @@ int dccp_connect(struct sock *sk)
481 skb_reserve(skb, sk->sk_prot->max_header); 454 skb_reserve(skb, sk->sk_prot->max_header);
482 455
483 DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_REQUEST; 456 DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_REQUEST;
484 skb->csum = 0;
485 457
486 dccp_skb_entail(sk, skb); 458 dccp_skb_entail(sk, skb);
487 dccp_transmit_skb(sk, skb_clone(skb, GFP_KERNEL)); 459 dccp_transmit_skb(sk, skb_clone(skb, GFP_KERNEL));
@@ -513,7 +485,6 @@ void dccp_send_ack(struct sock *sk)
513 485
514 /* Reserve space for headers */ 486 /* Reserve space for headers */
515 skb_reserve(skb, sk->sk_prot->max_header); 487 skb_reserve(skb, sk->sk_prot->max_header);
516 skb->csum = 0;
517 DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_ACK; 488 DCCP_SKB_CB(skb)->dccpd_type = DCCP_PKT_ACK;
518 dccp_transmit_skb(sk, skb); 489 dccp_transmit_skb(sk, skb);
519 } 490 }
@@ -567,7 +538,6 @@ void dccp_send_sync(struct sock *sk, const u64 seq,
567 538
568 /* Reserve space for headers and prepare control bits. */ 539 /* Reserve space for headers and prepare control bits. */
569 skb_reserve(skb, sk->sk_prot->max_header); 540 skb_reserve(skb, sk->sk_prot->max_header);
570 skb->csum = 0;
571 DCCP_SKB_CB(skb)->dccpd_type = pkt_type; 541 DCCP_SKB_CB(skb)->dccpd_type = pkt_type;
572 DCCP_SKB_CB(skb)->dccpd_seq = seq; 542 DCCP_SKB_CB(skb)->dccpd_seq = seq;
573 543
@@ -593,7 +563,6 @@ void dccp_send_close(struct sock *sk, const int active)
593 563
594 /* Reserve space for headers and prepare control bits. */ 564 /* Reserve space for headers and prepare control bits. */
595 skb_reserve(skb, sk->sk_prot->max_header); 565 skb_reserve(skb, sk->sk_prot->max_header);
596 skb->csum = 0;
597 DCCP_SKB_CB(skb)->dccpd_type = dp->dccps_role == DCCP_ROLE_CLIENT ? 566 DCCP_SKB_CB(skb)->dccpd_type = dp->dccps_role == DCCP_ROLE_CLIENT ?
598 DCCP_PKT_CLOSE : DCCP_PKT_CLOSEREQ; 567 DCCP_PKT_CLOSE : DCCP_PKT_CLOSEREQ;
599 568
diff --git a/net/dccp/probe.c b/net/dccp/probe.c
index fded1493c1..f81e37de35 100644
--- a/net/dccp/probe.c
+++ b/net/dccp/probe.c
@@ -106,8 +106,10 @@ static int jdccp_sendmsg(struct kiocb *iocb, struct sock *sk,
106} 106}
107 107
108static struct jprobe dccp_send_probe = { 108static struct jprobe dccp_send_probe = {
109 .kp = { .addr = (kprobe_opcode_t *)&dccp_sendmsg, }, 109 .kp = {
110 .entry = (kprobe_opcode_t *)&jdccp_sendmsg, 110 .symbol_name = "dccp_sendmsg",
111 },
112 .entry = JPROBE_ENTRY(jdccp_sendmsg),
111}; 113};
112 114
113static int dccpprobe_open(struct inode *inode, struct file *file) 115static int dccpprobe_open(struct inode *inode, struct file *file)
diff --git a/net/dccp/proto.c b/net/dccp/proto.c
index 72cbdcfc2c..63b3fa20e1 100644
--- a/net/dccp/proto.c
+++ b/net/dccp/proto.c
@@ -52,6 +52,9 @@ struct inet_hashinfo __cacheline_aligned dccp_hashinfo = {
52 52
53EXPORT_SYMBOL_GPL(dccp_hashinfo); 53EXPORT_SYMBOL_GPL(dccp_hashinfo);
54 54
55/* the maximum queue length for tx in packets. 0 is no limit */
56int sysctl_dccp_tx_qlen __read_mostly = 5;
57
55void dccp_set_state(struct sock *sk, const int state) 58void dccp_set_state(struct sock *sk, const int state)
56{ 59{
57 const int oldstate = sk->sk_state; 60 const int oldstate = sk->sk_state;
@@ -193,7 +196,7 @@ int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized)
193 sk, GFP_KERNEL); 196 sk, GFP_KERNEL);
194 dp->dccps_hc_tx_ccid = ccid_hc_tx_new(dmsk->dccpms_tx_ccid, 197 dp->dccps_hc_tx_ccid = ccid_hc_tx_new(dmsk->dccpms_tx_ccid,
195 sk, GFP_KERNEL); 198 sk, GFP_KERNEL);
196 if (unlikely(dp->dccps_hc_rx_ccid == NULL || 199 if (unlikely(dp->dccps_hc_rx_ccid == NULL ||
197 dp->dccps_hc_tx_ccid == NULL)) { 200 dp->dccps_hc_tx_ccid == NULL)) {
198 ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk); 201 ccid_hc_rx_delete(dp->dccps_hc_rx_ccid, sk);
199 ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk); 202 ccid_hc_tx_delete(dp->dccps_hc_tx_ccid, sk);
@@ -212,6 +215,7 @@ int dccp_init_sock(struct sock *sk, const __u8 ctl_sock_initialized)
212 215
213 dccp_init_xmit_timers(sk); 216 dccp_init_xmit_timers(sk);
214 icsk->icsk_rto = DCCP_TIMEOUT_INIT; 217 icsk->icsk_rto = DCCP_TIMEOUT_INIT;
218 icsk->icsk_syn_retries = sysctl_dccp_request_retries;
215 sk->sk_state = DCCP_CLOSED; 219 sk->sk_state = DCCP_CLOSED;
216 sk->sk_write_space = dccp_write_space; 220 sk->sk_write_space = dccp_write_space;
217 icsk->icsk_sync_mss = dccp_sync_mss; 221 icsk->icsk_sync_mss = dccp_sync_mss;
@@ -262,12 +266,12 @@ int dccp_destroy_sock(struct sock *sk)
262 266
263EXPORT_SYMBOL_GPL(dccp_destroy_sock); 267EXPORT_SYMBOL_GPL(dccp_destroy_sock);
264 268
265static inline int dccp_listen_start(struct sock *sk) 269static inline int dccp_listen_start(struct sock *sk, int backlog)
266{ 270{
267 struct dccp_sock *dp = dccp_sk(sk); 271 struct dccp_sock *dp = dccp_sk(sk);
268 272
269 dp->dccps_role = DCCP_ROLE_LISTEN; 273 dp->dccps_role = DCCP_ROLE_LISTEN;
270 return inet_csk_listen_start(sk, TCP_SYNQ_HSIZE); 274 return inet_csk_listen_start(sk, backlog);
271} 275}
272 276
273int dccp_disconnect(struct sock *sk, int flags) 277int dccp_disconnect(struct sock *sk, int flags)
@@ -386,7 +390,7 @@ static int dccp_setsockopt_service(struct sock *sk, const __be32 service,
386 struct dccp_sock *dp = dccp_sk(sk); 390 struct dccp_sock *dp = dccp_sk(sk);
387 struct dccp_service_list *sl = NULL; 391 struct dccp_service_list *sl = NULL;
388 392
389 if (service == DCCP_SERVICE_INVALID_VALUE || 393 if (service == DCCP_SERVICE_INVALID_VALUE ||
390 optlen > DCCP_SERVICE_LIST_MAX_LEN * sizeof(u32)) 394 optlen > DCCP_SERVICE_LIST_MAX_LEN * sizeof(u32))
391 return -EINVAL; 395 return -EINVAL;
392 396
@@ -451,9 +455,8 @@ out_free_val:
451static int do_dccp_setsockopt(struct sock *sk, int level, int optname, 455static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
452 char __user *optval, int optlen) 456 char __user *optval, int optlen)
453{ 457{
454 struct dccp_sock *dp; 458 struct dccp_sock *dp = dccp_sk(sk);
455 int err; 459 int val, err = 0;
456 int val;
457 460
458 if (optlen < sizeof(int)) 461 if (optlen < sizeof(int))
459 return -EINVAL; 462 return -EINVAL;
@@ -465,14 +468,11 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
465 return dccp_setsockopt_service(sk, val, optval, optlen); 468 return dccp_setsockopt_service(sk, val, optval, optlen);
466 469
467 lock_sock(sk); 470 lock_sock(sk);
468 dp = dccp_sk(sk);
469 err = 0;
470
471 switch (optname) { 471 switch (optname) {
472 case DCCP_SOCKOPT_PACKET_SIZE: 472 case DCCP_SOCKOPT_PACKET_SIZE:
473 dp->dccps_packet_size = val; 473 DCCP_WARN("sockopt(PACKET_SIZE) is deprecated: fix your app\n");
474 err = 0;
474 break; 475 break;
475
476 case DCCP_SOCKOPT_CHANGE_L: 476 case DCCP_SOCKOPT_CHANGE_L:
477 if (optlen != sizeof(struct dccp_so_feat)) 477 if (optlen != sizeof(struct dccp_so_feat))
478 err = -EINVAL; 478 err = -EINVAL;
@@ -481,7 +481,6 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
481 (struct dccp_so_feat __user *) 481 (struct dccp_so_feat __user *)
482 optval); 482 optval);
483 break; 483 break;
484
485 case DCCP_SOCKOPT_CHANGE_R: 484 case DCCP_SOCKOPT_CHANGE_R:
486 if (optlen != sizeof(struct dccp_so_feat)) 485 if (optlen != sizeof(struct dccp_so_feat))
487 err = -EINVAL; 486 err = -EINVAL;
@@ -490,12 +489,26 @@ static int do_dccp_setsockopt(struct sock *sk, int level, int optname,
490 (struct dccp_so_feat __user *) 489 (struct dccp_so_feat __user *)
491 optval); 490 optval);
492 break; 491 break;
493 492 case DCCP_SOCKOPT_SEND_CSCOV: /* sender side, RFC 4340, sec. 9.2 */
493 if (val < 0 || val > 15)
494 err = -EINVAL;
495 else
496 dp->dccps_pcslen = val;
497 break;
498 case DCCP_SOCKOPT_RECV_CSCOV: /* receiver side, RFC 4340 sec. 9.2.1 */
499 if (val < 0 || val > 15)
500 err = -EINVAL;
501 else {
502 dp->dccps_pcrlen = val;
503 /* FIXME: add feature negotiation,
504 * ChangeL(MinimumChecksumCoverage, val) */
505 }
506 break;
494 default: 507 default:
495 err = -ENOPROTOOPT; 508 err = -ENOPROTOOPT;
496 break; 509 break;
497 } 510 }
498 511
499 release_sock(sk); 512 release_sock(sk);
500 return err; 513 return err;
501} 514}
@@ -569,12 +582,17 @@ static int do_dccp_getsockopt(struct sock *sk, int level, int optname,
569 582
570 switch (optname) { 583 switch (optname) {
571 case DCCP_SOCKOPT_PACKET_SIZE: 584 case DCCP_SOCKOPT_PACKET_SIZE:
572 val = dp->dccps_packet_size; 585 DCCP_WARN("sockopt(PACKET_SIZE) is deprecated: fix your app\n");
573 len = sizeof(dp->dccps_packet_size); 586 return 0;
574 break;
575 case DCCP_SOCKOPT_SERVICE: 587 case DCCP_SOCKOPT_SERVICE:
576 return dccp_getsockopt_service(sk, len, 588 return dccp_getsockopt_service(sk, len,
577 (__be32 __user *)optval, optlen); 589 (__be32 __user *)optval, optlen);
590 case DCCP_SOCKOPT_SEND_CSCOV:
591 val = dp->dccps_pcslen;
592 break;
593 case DCCP_SOCKOPT_RECV_CSCOV:
594 val = dp->dccps_pcrlen;
595 break;
578 case 128 ... 191: 596 case 128 ... 191:
579 return ccid_hc_rx_getsockopt(dp->dccps_hc_rx_ccid, sk, optname, 597 return ccid_hc_rx_getsockopt(dp->dccps_hc_rx_ccid, sk, optname,
580 len, (u32 __user *)optval, optlen); 598 len, (u32 __user *)optval, optlen);
@@ -630,6 +648,13 @@ int dccp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
630 return -EMSGSIZE; 648 return -EMSGSIZE;
631 649
632 lock_sock(sk); 650 lock_sock(sk);
651
652 if (sysctl_dccp_tx_qlen &&
653 (sk->sk_write_queue.qlen >= sysctl_dccp_tx_qlen)) {
654 rc = -EAGAIN;
655 goto out_release;
656 }
657
633 timeo = sock_sndtimeo(sk, noblock); 658 timeo = sock_sndtimeo(sk, noblock);
634 659
635 /* 660 /*
@@ -788,7 +813,7 @@ int inet_dccp_listen(struct socket *sock, int backlog)
788 * FIXME: here it probably should be sk->sk_prot->listen_start 813 * FIXME: here it probably should be sk->sk_prot->listen_start
789 * see tcp_listen_start 814 * see tcp_listen_start
790 */ 815 */
791 err = dccp_listen_start(sk); 816 err = dccp_listen_start(sk, backlog);
792 if (err) 817 if (err)
793 goto out; 818 goto out;
794 } 819 }
@@ -805,7 +830,7 @@ EXPORT_SYMBOL_GPL(inet_dccp_listen);
805static const unsigned char dccp_new_state[] = { 830static const unsigned char dccp_new_state[] = {
806 /* current state: new state: action: */ 831 /* current state: new state: action: */
807 [0] = DCCP_CLOSED, 832 [0] = DCCP_CLOSED,
808 [DCCP_OPEN] = DCCP_CLOSING | DCCP_ACTION_FIN, 833 [DCCP_OPEN] = DCCP_CLOSING | DCCP_ACTION_FIN,
809 [DCCP_REQUESTING] = DCCP_CLOSED, 834 [DCCP_REQUESTING] = DCCP_CLOSED,
810 [DCCP_PARTOPEN] = DCCP_CLOSING | DCCP_ACTION_FIN, 835 [DCCP_PARTOPEN] = DCCP_CLOSING | DCCP_ACTION_FIN,
811 [DCCP_LISTEN] = DCCP_CLOSED, 836 [DCCP_LISTEN] = DCCP_CLOSED,
@@ -1008,8 +1033,7 @@ static int __init dccp_init(void)
1008 } while (!dccp_hashinfo.ehash && --ehash_order > 0); 1033 } while (!dccp_hashinfo.ehash && --ehash_order > 0);
1009 1034
1010 if (!dccp_hashinfo.ehash) { 1035 if (!dccp_hashinfo.ehash) {
1011 printk(KERN_CRIT "Failed to allocate DCCP " 1036 DCCP_CRIT("Failed to allocate DCCP established hash table");
1012 "established hash table\n");
1013 goto out_free_bind_bucket_cachep; 1037 goto out_free_bind_bucket_cachep;
1014 } 1038 }
1015 1039
@@ -1031,7 +1055,7 @@ static int __init dccp_init(void)
1031 } while (!dccp_hashinfo.bhash && --bhash_order >= 0); 1055 } while (!dccp_hashinfo.bhash && --bhash_order >= 0);
1032 1056
1033 if (!dccp_hashinfo.bhash) { 1057 if (!dccp_hashinfo.bhash) {
1034 printk(KERN_CRIT "Failed to allocate DCCP bind hash table\n"); 1058 DCCP_CRIT("Failed to allocate DCCP bind hash table");
1035 goto out_free_dccp_ehash; 1059 goto out_free_dccp_ehash;
1036 } 1060 }
1037 1061
diff --git a/net/dccp/sysctl.c b/net/dccp/sysctl.c
index 38bc157876..fdcfca3e92 100644
--- a/net/dccp/sysctl.c
+++ b/net/dccp/sysctl.c
@@ -11,6 +11,7 @@
11 11
12#include <linux/mm.h> 12#include <linux/mm.h>
13#include <linux/sysctl.h> 13#include <linux/sysctl.h>
14#include "dccp.h"
14#include "feat.h" 15#include "feat.h"
15 16
16#ifndef CONFIG_SYSCTL 17#ifndef CONFIG_SYSCTL
@@ -19,53 +20,76 @@
19 20
20static struct ctl_table dccp_default_table[] = { 21static struct ctl_table dccp_default_table[] = {
21 { 22 {
22 .ctl_name = NET_DCCP_DEFAULT_SEQ_WINDOW,
23 .procname = "seq_window", 23 .procname = "seq_window",
24 .data = &dccp_feat_default_sequence_window, 24 .data = &sysctl_dccp_feat_sequence_window,
25 .maxlen = sizeof(dccp_feat_default_sequence_window), 25 .maxlen = sizeof(sysctl_dccp_feat_sequence_window),
26 .mode = 0644, 26 .mode = 0644,
27 .proc_handler = proc_dointvec, 27 .proc_handler = proc_dointvec,
28 }, 28 },
29 { 29 {
30 .ctl_name = NET_DCCP_DEFAULT_RX_CCID,
31 .procname = "rx_ccid", 30 .procname = "rx_ccid",
32 .data = &dccp_feat_default_rx_ccid, 31 .data = &sysctl_dccp_feat_rx_ccid,
33 .maxlen = sizeof(dccp_feat_default_rx_ccid), 32 .maxlen = sizeof(sysctl_dccp_feat_rx_ccid),
34 .mode = 0644, 33 .mode = 0644,
35 .proc_handler = proc_dointvec, 34 .proc_handler = proc_dointvec,
36 }, 35 },
37 { 36 {
38 .ctl_name = NET_DCCP_DEFAULT_TX_CCID,
39 .procname = "tx_ccid", 37 .procname = "tx_ccid",
40 .data = &dccp_feat_default_tx_ccid, 38 .data = &sysctl_dccp_feat_tx_ccid,
41 .maxlen = sizeof(dccp_feat_default_tx_ccid), 39 .maxlen = sizeof(sysctl_dccp_feat_tx_ccid),
42 .mode = 0644, 40 .mode = 0644,
43 .proc_handler = proc_dointvec, 41 .proc_handler = proc_dointvec,
44 }, 42 },
45 { 43 {
46 .ctl_name = NET_DCCP_DEFAULT_ACK_RATIO,
47 .procname = "ack_ratio", 44 .procname = "ack_ratio",
48 .data = &dccp_feat_default_ack_ratio, 45 .data = &sysctl_dccp_feat_ack_ratio,
49 .maxlen = sizeof(dccp_feat_default_ack_ratio), 46 .maxlen = sizeof(sysctl_dccp_feat_ack_ratio),
50 .mode = 0644, 47 .mode = 0644,
51 .proc_handler = proc_dointvec, 48 .proc_handler = proc_dointvec,
52 }, 49 },
53 { 50 {
54 .ctl_name = NET_DCCP_DEFAULT_SEND_ACKVEC,
55 .procname = "send_ackvec", 51 .procname = "send_ackvec",
56 .data = &dccp_feat_default_send_ack_vector, 52 .data = &sysctl_dccp_feat_send_ack_vector,
57 .maxlen = sizeof(dccp_feat_default_send_ack_vector), 53 .maxlen = sizeof(sysctl_dccp_feat_send_ack_vector),
58 .mode = 0644, 54 .mode = 0644,
59 .proc_handler = proc_dointvec, 55 .proc_handler = proc_dointvec,
60 }, 56 },
61 { 57 {
62 .ctl_name = NET_DCCP_DEFAULT_SEND_NDP,
63 .procname = "send_ndp", 58 .procname = "send_ndp",
64 .data = &dccp_feat_default_send_ndp_count, 59 .data = &sysctl_dccp_feat_send_ndp_count,
65 .maxlen = sizeof(dccp_feat_default_send_ndp_count), 60 .maxlen = sizeof(sysctl_dccp_feat_send_ndp_count),
66 .mode = 0644, 61 .mode = 0644,
67 .proc_handler = proc_dointvec, 62 .proc_handler = proc_dointvec,
68 }, 63 },
64 {
65 .procname = "request_retries",
66 .data = &sysctl_dccp_request_retries,
67 .maxlen = sizeof(sysctl_dccp_request_retries),
68 .mode = 0644,
69 .proc_handler = proc_dointvec,
70 },
71 {
72 .procname = "retries1",
73 .data = &sysctl_dccp_retries1,
74 .maxlen = sizeof(sysctl_dccp_retries1),
75 .mode = 0644,
76 .proc_handler = proc_dointvec,
77 },
78 {
79 .procname = "retries2",
80 .data = &sysctl_dccp_retries2,
81 .maxlen = sizeof(sysctl_dccp_retries2),
82 .mode = 0644,
83 .proc_handler = proc_dointvec,
84 },
85 {
86 .procname = "tx_qlen",
87 .data = &sysctl_dccp_tx_qlen,
88 .maxlen = sizeof(sysctl_dccp_tx_qlen),
89 .mode = 0644,
90 .proc_handler = proc_dointvec,
91 },
92
69 { .ctl_name = 0, } 93 { .ctl_name = 0, }
70}; 94};
71 95
diff --git a/net/dccp/timer.c b/net/dccp/timer.c
index 8447742f56..e5348f369c 100644
--- a/net/dccp/timer.c
+++ b/net/dccp/timer.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * net/dccp/timer.c 2 * net/dccp/timer.c
3 * 3 *
4 * An implementation of the DCCP protocol 4 * An implementation of the DCCP protocol
5 * Arnaldo Carvalho de Melo <acme@conectiva.com.br> 5 * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
6 * 6 *
@@ -15,15 +15,10 @@
15 15
16#include "dccp.h" 16#include "dccp.h"
17 17
18static void dccp_write_timer(unsigned long data); 18/* sysctl variables governing numbers of retransmission attempts */
19static void dccp_keepalive_timer(unsigned long data); 19int sysctl_dccp_request_retries __read_mostly = TCP_SYN_RETRIES;
20static void dccp_delack_timer(unsigned long data); 20int sysctl_dccp_retries1 __read_mostly = TCP_RETR1;
21 21int sysctl_dccp_retries2 __read_mostly = TCP_RETR2;
22void dccp_init_xmit_timers(struct sock *sk)
23{
24 inet_csk_init_xmit_timers(sk, &dccp_write_timer, &dccp_delack_timer,
25 &dccp_keepalive_timer);
26}
27 22
28static void dccp_write_err(struct sock *sk) 23static void dccp_write_err(struct sock *sk)
29{ 24{
@@ -44,11 +39,10 @@ static int dccp_write_timeout(struct sock *sk)
44 if (sk->sk_state == DCCP_REQUESTING || sk->sk_state == DCCP_PARTOPEN) { 39 if (sk->sk_state == DCCP_REQUESTING || sk->sk_state == DCCP_PARTOPEN) {
45 if (icsk->icsk_retransmits != 0) 40 if (icsk->icsk_retransmits != 0)
46 dst_negative_advice(&sk->sk_dst_cache); 41 dst_negative_advice(&sk->sk_dst_cache);
47 retry_until = icsk->icsk_syn_retries ? : 42 retry_until = icsk->icsk_syn_retries ?
48 /* FIXME! */ 3 /* FIXME! sysctl_tcp_syn_retries */; 43 : sysctl_dccp_request_retries;
49 } else { 44 } else {
50 if (icsk->icsk_retransmits >= 45 if (icsk->icsk_retransmits >= sysctl_dccp_retries1) {
51 /* FIXME! sysctl_tcp_retries1 */ 5 /* FIXME! */) {
52 /* NOTE. draft-ietf-tcpimpl-pmtud-01.txt requires pmtu 46 /* NOTE. draft-ietf-tcpimpl-pmtud-01.txt requires pmtu
53 black hole detection. :-( 47 black hole detection. :-(
54 48
@@ -72,7 +66,7 @@ static int dccp_write_timeout(struct sock *sk)
72 dst_negative_advice(&sk->sk_dst_cache); 66 dst_negative_advice(&sk->sk_dst_cache);
73 } 67 }
74 68
75 retry_until = /* FIXME! */ 15 /* FIXME! sysctl_tcp_retries2 */; 69 retry_until = sysctl_dccp_retries2;
76 /* 70 /*
77 * FIXME: see tcp_write_timout and tcp_out_of_resources 71 * FIXME: see tcp_write_timout and tcp_out_of_resources
78 */ 72 */
@@ -86,53 +80,6 @@ static int dccp_write_timeout(struct sock *sk)
86 return 0; 80 return 0;
87} 81}
88 82
89/* This is the same as tcp_delack_timer, sans prequeue & mem_reclaim stuff */
90static void dccp_delack_timer(unsigned long data)
91{
92 struct sock *sk = (struct sock *)data;
93 struct inet_connection_sock *icsk = inet_csk(sk);
94
95 bh_lock_sock(sk);
96 if (sock_owned_by_user(sk)) {
97 /* Try again later. */
98 icsk->icsk_ack.blocked = 1;
99 NET_INC_STATS_BH(LINUX_MIB_DELAYEDACKLOCKED);
100 sk_reset_timer(sk, &icsk->icsk_delack_timer,
101 jiffies + TCP_DELACK_MIN);
102 goto out;
103 }
104
105 if (sk->sk_state == DCCP_CLOSED ||
106 !(icsk->icsk_ack.pending & ICSK_ACK_TIMER))
107 goto out;
108 if (time_after(icsk->icsk_ack.timeout, jiffies)) {
109 sk_reset_timer(sk, &icsk->icsk_delack_timer,
110 icsk->icsk_ack.timeout);
111 goto out;
112 }
113
114 icsk->icsk_ack.pending &= ~ICSK_ACK_TIMER;
115
116 if (inet_csk_ack_scheduled(sk)) {
117 if (!icsk->icsk_ack.pingpong) {
118 /* Delayed ACK missed: inflate ATO. */
119 icsk->icsk_ack.ato = min(icsk->icsk_ack.ato << 1,
120 icsk->icsk_rto);
121 } else {
122 /* Delayed ACK missed: leave pingpong mode and
123 * deflate ATO.
124 */
125 icsk->icsk_ack.pingpong = 0;
126 icsk->icsk_ack.ato = TCP_ATO_MIN;
127 }
128 dccp_send_ack(sk);
129 NET_INC_STATS_BH(LINUX_MIB_DELAYEDACKS);
130 }
131out:
132 bh_unlock_sock(sk);
133 sock_put(sk);
134}
135
136/* 83/*
137 * The DCCP retransmit timer. 84 * The DCCP retransmit timer.
138 */ 85 */
@@ -142,7 +89,7 @@ static void dccp_retransmit_timer(struct sock *sk)
142 89
143 /* retransmit timer is used for feature negotiation throughout 90 /* retransmit timer is used for feature negotiation throughout
144 * connection. In this case, no packet is re-transmitted, but rather an 91 * connection. In this case, no packet is re-transmitted, but rather an
145 * ack is generated and pending changes are splaced into its options. 92 * ack is generated and pending changes are placed into its options.
146 */ 93 */
147 if (sk->sk_send_head == NULL) { 94 if (sk->sk_send_head == NULL) {
148 dccp_pr_debug("feat negotiation retransmit timeout %p\n", sk); 95 dccp_pr_debug("feat negotiation retransmit timeout %p\n", sk);
@@ -154,12 +101,14 @@ static void dccp_retransmit_timer(struct sock *sk)
154 /* 101 /*
155 * sk->sk_send_head has to have one skb with 102 * sk->sk_send_head has to have one skb with
156 * DCCP_SKB_CB(skb)->dccpd_type set to one of the retransmittable DCCP 103 * DCCP_SKB_CB(skb)->dccpd_type set to one of the retransmittable DCCP
157 * packet types (REQUEST, RESPONSE, the ACK in the 3way handshake 104 * packet types. The only packets eligible for retransmission are:
158 * (PARTOPEN timer), etc). 105 * -- Requests in client-REQUEST state (sec. 8.1.1)
159 */ 106 * -- Acks in client-PARTOPEN state (sec. 8.1.5)
107 * -- CloseReq in server-CLOSEREQ state (sec. 8.3)
108 * -- Close in node-CLOSING state (sec. 8.3) */
160 BUG_TRAP(sk->sk_send_head != NULL); 109 BUG_TRAP(sk->sk_send_head != NULL);
161 110
162 /* 111 /*
163 * More than than 4MSL (8 minutes) has passed, a RESET(aborted) was 112 * More than than 4MSL (8 minutes) has passed, a RESET(aborted) was
164 * sent, no need to retransmit, this sock is dead. 113 * sent, no need to retransmit, this sock is dead.
165 */ 114 */
@@ -194,7 +143,7 @@ backoff:
194 icsk->icsk_rto = min(icsk->icsk_rto << 1, DCCP_RTO_MAX); 143 icsk->icsk_rto = min(icsk->icsk_rto << 1, DCCP_RTO_MAX);
195 inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, 144 inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto,
196 DCCP_RTO_MAX); 145 DCCP_RTO_MAX);
197 if (icsk->icsk_retransmits > 3 /* FIXME: sysctl_dccp_retries1 */) 146 if (icsk->icsk_retransmits > sysctl_dccp_retries1)
198 __sk_dst_reset(sk); 147 __sk_dst_reset(sk);
199out:; 148out:;
200} 149}
@@ -251,7 +200,7 @@ static void dccp_keepalive_timer(unsigned long data)
251 /* Only process if socket is not in use. */ 200 /* Only process if socket is not in use. */
252 bh_lock_sock(sk); 201 bh_lock_sock(sk);
253 if (sock_owned_by_user(sk)) { 202 if (sock_owned_by_user(sk)) {
254 /* Try again later. */ 203 /* Try again later. */
255 inet_csk_reset_keepalive_timer(sk, HZ / 20); 204 inet_csk_reset_keepalive_timer(sk, HZ / 20);
256 goto out; 205 goto out;
257 } 206 }
@@ -264,3 +213,56 @@ out:
264 bh_unlock_sock(sk); 213 bh_unlock_sock(sk);
265 sock_put(sk); 214 sock_put(sk);
266} 215}
216
217/* This is the same as tcp_delack_timer, sans prequeue & mem_reclaim stuff */
218static void dccp_delack_timer(unsigned long data)
219{
220 struct sock *sk = (struct sock *)data;
221 struct inet_connection_sock *icsk = inet_csk(sk);
222
223 bh_lock_sock(sk);
224 if (sock_owned_by_user(sk)) {
225 /* Try again later. */
226 icsk->icsk_ack.blocked = 1;
227 NET_INC_STATS_BH(LINUX_MIB_DELAYEDACKLOCKED);
228 sk_reset_timer(sk, &icsk->icsk_delack_timer,
229 jiffies + TCP_DELACK_MIN);
230 goto out;
231 }
232
233 if (sk->sk_state == DCCP_CLOSED ||
234 !(icsk->icsk_ack.pending & ICSK_ACK_TIMER))
235 goto out;
236 if (time_after(icsk->icsk_ack.timeout, jiffies)) {
237 sk_reset_timer(sk, &icsk->icsk_delack_timer,
238 icsk->icsk_ack.timeout);
239 goto out;
240 }
241
242 icsk->icsk_ack.pending &= ~ICSK_ACK_TIMER;
243
244 if (inet_csk_ack_scheduled(sk)) {
245 if (!icsk->icsk_ack.pingpong) {
246 /* Delayed ACK missed: inflate ATO. */
247 icsk->icsk_ack.ato = min(icsk->icsk_ack.ato << 1,
248 icsk->icsk_rto);
249 } else {
250 /* Delayed ACK missed: leave pingpong mode and
251 * deflate ATO.
252 */
253 icsk->icsk_ack.pingpong = 0;
254 icsk->icsk_ack.ato = TCP_ATO_MIN;
255 }
256 dccp_send_ack(sk);
257 NET_INC_STATS_BH(LINUX_MIB_DELAYEDACKS);
258 }
259out:
260 bh_unlock_sock(sk);
261 sock_put(sk);
262}
263
264void dccp_init_xmit_timers(struct sock *sk)
265{
266 inet_csk_init_xmit_timers(sk, &dccp_write_timer, &dccp_delack_timer,
267 &dccp_keepalive_timer);
268}
diff --git a/net/decnet/Kconfig b/net/decnet/Kconfig
index 36e72cb145..7914fd619c 100644
--- a/net/decnet/Kconfig
+++ b/net/decnet/Kconfig
@@ -41,11 +41,3 @@ config DECNET_ROUTER
41 41
42 See <file:Documentation/networking/decnet.txt> for more information. 42 See <file:Documentation/networking/decnet.txt> for more information.
43 43
44config DECNET_ROUTE_FWMARK
45 bool "DECnet: use FWMARK value as routing key (EXPERIMENTAL)"
46 depends on DECNET_ROUTER && NETFILTER
47 help
48 If you say Y here, you will be able to specify different routes for
49 packets with different FWMARK ("firewalling mark") values
50 (see ipchains(8), "-m" argument).
51
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index 01861feb60..fc6f3c023a 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -38,7 +38,6 @@
38#include <linux/if_arp.h> 38#include <linux/if_arp.h>
39#include <linux/if_ether.h> 39#include <linux/if_ether.h>
40#include <linux/skbuff.h> 40#include <linux/skbuff.h>
41#include <linux/rtnetlink.h>
42#include <linux/sysctl.h> 41#include <linux/sysctl.h>
43#include <linux/notifier.h> 42#include <linux/notifier.h>
44#include <asm/uaccess.h> 43#include <asm/uaccess.h>
@@ -47,6 +46,7 @@
47#include <net/dst.h> 46#include <net/dst.h>
48#include <net/flow.h> 47#include <net/flow.h>
49#include <net/fib_rules.h> 48#include <net/fib_rules.h>
49#include <net/netlink.h>
50#include <net/dn.h> 50#include <net/dn.h>
51#include <net/dn_dev.h> 51#include <net/dn_dev.h>
52#include <net/dn_route.h> 52#include <net/dn_route.h>
@@ -73,7 +73,7 @@ static BLOCKING_NOTIFIER_HEAD(dnaddr_chain);
73 73
74static struct dn_dev *dn_dev_create(struct net_device *dev, int *err); 74static struct dn_dev *dn_dev_create(struct net_device *dev, int *err);
75static void dn_dev_delete(struct net_device *dev); 75static void dn_dev_delete(struct net_device *dev);
76static void rtmsg_ifa(int event, struct dn_ifaddr *ifa); 76static void dn_ifaddr_notify(int event, struct dn_ifaddr *ifa);
77 77
78static int dn_eth_up(struct net_device *); 78static int dn_eth_up(struct net_device *);
79static void dn_eth_down(struct net_device *); 79static void dn_eth_down(struct net_device *);
@@ -167,8 +167,7 @@ static int dn_forwarding_proc(ctl_table *, int, struct file *,
167 void __user *, size_t *, loff_t *); 167 void __user *, size_t *, loff_t *);
168static int dn_forwarding_sysctl(ctl_table *table, int __user *name, int nlen, 168static int dn_forwarding_sysctl(ctl_table *table, int __user *name, int nlen,
169 void __user *oldval, size_t __user *oldlenp, 169 void __user *oldval, size_t __user *oldlenp,
170 void __user *newval, size_t newlen, 170 void __user *newval, size_t newlen);
171 void **context);
172 171
173static struct dn_dev_sysctl_table { 172static struct dn_dev_sysctl_table {
174 struct ctl_table_header *sysctl_header; 173 struct ctl_table_header *sysctl_header;
@@ -255,12 +254,10 @@ static void dn_dev_sysctl_register(struct net_device *dev, struct dn_dev_parms *
255 struct dn_dev_sysctl_table *t; 254 struct dn_dev_sysctl_table *t;
256 int i; 255 int i;
257 256
258 t = kmalloc(sizeof(*t), GFP_KERNEL); 257 t = kmemdup(&dn_dev_sysctl, sizeof(*t), GFP_KERNEL);
259 if (t == NULL) 258 if (t == NULL)
260 return; 259 return;
261 260
262 memcpy(t, &dn_dev_sysctl, sizeof(*t));
263
264 for(i = 0; i < ARRAY_SIZE(t->dn_dev_vars) - 1; i++) { 261 for(i = 0; i < ARRAY_SIZE(t->dn_dev_vars) - 1; i++) {
265 long offset = (long)t->dn_dev_vars[i].data; 262 long offset = (long)t->dn_dev_vars[i].data;
266 t->dn_dev_vars[i].data = ((char *)parms) + offset; 263 t->dn_dev_vars[i].data = ((char *)parms) + offset;
@@ -349,8 +346,7 @@ static int dn_forwarding_proc(ctl_table *table, int write,
349 346
350static int dn_forwarding_sysctl(ctl_table *table, int __user *name, int nlen, 347static int dn_forwarding_sysctl(ctl_table *table, int __user *name, int nlen,
351 void __user *oldval, size_t __user *oldlenp, 348 void __user *oldval, size_t __user *oldlenp,
352 void __user *newval, size_t newlen, 349 void __user *newval, size_t newlen)
353 void **context)
354{ 350{
355#ifdef CONFIG_DECNET_ROUTER 351#ifdef CONFIG_DECNET_ROUTER
356 struct net_device *dev = table->extra1; 352 struct net_device *dev = table->extra1;
@@ -442,7 +438,7 @@ static void dn_dev_del_ifa(struct dn_dev *dn_db, struct dn_ifaddr **ifap, int de
442 } 438 }
443 } 439 }
444 440
445 rtmsg_ifa(RTM_DELADDR, ifa1); 441 dn_ifaddr_notify(RTM_DELADDR, ifa1);
446 blocking_notifier_call_chain(&dnaddr_chain, NETDEV_DOWN, ifa1); 442 blocking_notifier_call_chain(&dnaddr_chain, NETDEV_DOWN, ifa1);
447 if (destroy) { 443 if (destroy) {
448 dn_dev_free_ifa(ifa1); 444 dn_dev_free_ifa(ifa1);
@@ -477,7 +473,7 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa)
477 ifa->ifa_next = dn_db->ifa_list; 473 ifa->ifa_next = dn_db->ifa_list;
478 dn_db->ifa_list = ifa; 474 dn_db->ifa_list = ifa;
479 475
480 rtmsg_ifa(RTM_NEWADDR, ifa); 476 dn_ifaddr_notify(RTM_NEWADDR, ifa);
481 blocking_notifier_call_chain(&dnaddr_chain, NETDEV_UP, ifa); 477 blocking_notifier_call_chain(&dnaddr_chain, NETDEV_UP, ifa);
482 478
483 return 0; 479 return 0;
@@ -647,41 +643,62 @@ static struct dn_dev *dn_dev_by_index(int ifindex)
647 return dn_dev; 643 return dn_dev;
648} 644}
649 645
650static int dn_dev_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 646static struct nla_policy dn_ifa_policy[IFA_MAX+1] __read_mostly = {
647 [IFA_ADDRESS] = { .type = NLA_U16 },
648 [IFA_LOCAL] = { .type = NLA_U16 },
649 [IFA_LABEL] = { .type = NLA_STRING,
650 .len = IFNAMSIZ - 1 },
651};
652
653static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
651{ 654{
652 struct rtattr **rta = arg; 655 struct nlattr *tb[IFA_MAX+1];
653 struct dn_dev *dn_db; 656 struct dn_dev *dn_db;
654 struct ifaddrmsg *ifm = NLMSG_DATA(nlh); 657 struct ifaddrmsg *ifm;
655 struct dn_ifaddr *ifa, **ifap; 658 struct dn_ifaddr *ifa, **ifap;
659 int err = -EADDRNOTAVAIL;
660
661 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy);
662 if (err < 0)
663 goto errout;
656 664
665 ifm = nlmsg_data(nlh);
657 if ((dn_db = dn_dev_by_index(ifm->ifa_index)) == NULL) 666 if ((dn_db = dn_dev_by_index(ifm->ifa_index)) == NULL)
658 return -EADDRNOTAVAIL; 667 goto errout;
668
669 for (ifap = &dn_db->ifa_list; (ifa = *ifap); ifap = &ifa->ifa_next) {
670 if (tb[IFA_LOCAL] &&
671 nla_memcmp(tb[IFA_LOCAL], &ifa->ifa_local, 2))
672 continue;
659 673
660 for(ifap = &dn_db->ifa_list; (ifa=*ifap) != NULL; ifap = &ifa->ifa_next) { 674 if (tb[IFA_LABEL] && nla_strcmp(tb[IFA_LABEL], ifa->ifa_label))
661 void *tmp = rta[IFA_LOCAL-1];
662 if ((tmp && memcmp(RTA_DATA(tmp), &ifa->ifa_local, 2)) ||
663 (rta[IFA_LABEL-1] && rtattr_strcmp(rta[IFA_LABEL-1], ifa->ifa_label)))
664 continue; 675 continue;
665 676
666 dn_dev_del_ifa(dn_db, ifap, 1); 677 dn_dev_del_ifa(dn_db, ifap, 1);
667 return 0; 678 return 0;
668 } 679 }
669 680
670 return -EADDRNOTAVAIL; 681errout:
682 return err;
671} 683}
672 684
673static int dn_dev_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 685static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
674{ 686{
675 struct rtattr **rta = arg; 687 struct nlattr *tb[IFA_MAX+1];
676 struct net_device *dev; 688 struct net_device *dev;
677 struct dn_dev *dn_db; 689 struct dn_dev *dn_db;
678 struct ifaddrmsg *ifm = NLMSG_DATA(nlh); 690 struct ifaddrmsg *ifm;
679 struct dn_ifaddr *ifa; 691 struct dn_ifaddr *ifa;
680 int rv; 692 int err;
681 693
682 if (rta[IFA_LOCAL-1] == NULL) 694 err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, dn_ifa_policy);
695 if (err < 0)
696 return err;
697
698 if (tb[IFA_LOCAL] == NULL)
683 return -EINVAL; 699 return -EINVAL;
684 700
701 ifm = nlmsg_data(nlh);
685 if ((dev = __dev_get_by_index(ifm->ifa_index)) == NULL) 702 if ((dev = __dev_get_by_index(ifm->ifa_index)) == NULL)
686 return -ENODEV; 703 return -ENODEV;
687 704
@@ -695,69 +712,77 @@ static int dn_dev_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *a
695 if ((ifa = dn_dev_alloc_ifa()) == NULL) 712 if ((ifa = dn_dev_alloc_ifa()) == NULL)
696 return -ENOBUFS; 713 return -ENOBUFS;
697 714
698 if (!rta[IFA_ADDRESS - 1]) 715 if (tb[IFA_ADDRESS] == NULL)
699 rta[IFA_ADDRESS - 1] = rta[IFA_LOCAL - 1]; 716 tb[IFA_ADDRESS] = tb[IFA_LOCAL];
700 memcpy(&ifa->ifa_local, RTA_DATA(rta[IFA_LOCAL-1]), 2); 717
701 memcpy(&ifa->ifa_address, RTA_DATA(rta[IFA_ADDRESS-1]), 2); 718 ifa->ifa_local = nla_get_le16(tb[IFA_LOCAL]);
719 ifa->ifa_address = nla_get_le16(tb[IFA_ADDRESS]);
702 ifa->ifa_flags = ifm->ifa_flags; 720 ifa->ifa_flags = ifm->ifa_flags;
703 ifa->ifa_scope = ifm->ifa_scope; 721 ifa->ifa_scope = ifm->ifa_scope;
704 ifa->ifa_dev = dn_db; 722 ifa->ifa_dev = dn_db;
705 if (rta[IFA_LABEL-1]) 723
706 rtattr_strlcpy(ifa->ifa_label, rta[IFA_LABEL-1], IFNAMSIZ); 724 if (tb[IFA_LABEL])
725 nla_strlcpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ);
707 else 726 else
708 memcpy(ifa->ifa_label, dev->name, IFNAMSIZ); 727 memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);
709 728
710 rv = dn_dev_insert_ifa(dn_db, ifa); 729 err = dn_dev_insert_ifa(dn_db, ifa);
711 if (rv) 730 if (err)
712 dn_dev_free_ifa(ifa); 731 dn_dev_free_ifa(ifa);
713 return rv; 732
733 return err;
714} 734}
715 735
716static int dn_dev_fill_ifaddr(struct sk_buff *skb, struct dn_ifaddr *ifa, 736static inline size_t dn_ifaddr_nlmsg_size(void)
717 u32 pid, u32 seq, int event, unsigned int flags) 737{
738 return NLMSG_ALIGN(sizeof(struct ifaddrmsg))
739 + nla_total_size(IFNAMSIZ) /* IFA_LABEL */
740 + nla_total_size(2) /* IFA_ADDRESS */
741 + nla_total_size(2); /* IFA_LOCAL */
742}
743
744static int dn_nl_fill_ifaddr(struct sk_buff *skb, struct dn_ifaddr *ifa,
745 u32 pid, u32 seq, int event, unsigned int flags)
718{ 746{
719 struct ifaddrmsg *ifm; 747 struct ifaddrmsg *ifm;
720 struct nlmsghdr *nlh; 748 struct nlmsghdr *nlh;
721 unsigned char *b = skb->tail;
722 749
723 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*ifm), flags); 750 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*ifm), flags);
724 ifm = NLMSG_DATA(nlh); 751 if (nlh == NULL)
752 return -ENOBUFS;
725 753
754 ifm = nlmsg_data(nlh);
726 ifm->ifa_family = AF_DECnet; 755 ifm->ifa_family = AF_DECnet;
727 ifm->ifa_prefixlen = 16; 756 ifm->ifa_prefixlen = 16;
728 ifm->ifa_flags = ifa->ifa_flags | IFA_F_PERMANENT; 757 ifm->ifa_flags = ifa->ifa_flags | IFA_F_PERMANENT;
729 ifm->ifa_scope = ifa->ifa_scope; 758 ifm->ifa_scope = ifa->ifa_scope;
730 ifm->ifa_index = ifa->ifa_dev->dev->ifindex; 759 ifm->ifa_index = ifa->ifa_dev->dev->ifindex;
760
731 if (ifa->ifa_address) 761 if (ifa->ifa_address)
732 RTA_PUT(skb, IFA_ADDRESS, 2, &ifa->ifa_address); 762 NLA_PUT_LE16(skb, IFA_ADDRESS, ifa->ifa_address);
733 if (ifa->ifa_local) 763 if (ifa->ifa_local)
734 RTA_PUT(skb, IFA_LOCAL, 2, &ifa->ifa_local); 764 NLA_PUT_LE16(skb, IFA_LOCAL, ifa->ifa_local);
735 if (ifa->ifa_label[0]) 765 if (ifa->ifa_label[0])
736 RTA_PUT(skb, IFA_LABEL, IFNAMSIZ, &ifa->ifa_label); 766 NLA_PUT_STRING(skb, IFA_LABEL, ifa->ifa_label);
737 nlh->nlmsg_len = skb->tail - b; 767
738 return skb->len; 768 return nlmsg_end(skb, nlh);
739 769
740nlmsg_failure: 770nla_put_failure:
741rtattr_failure: 771 return nlmsg_cancel(skb, nlh);
742 skb_trim(skb, b - skb->data);
743 return -1;
744} 772}
745 773
746static void rtmsg_ifa(int event, struct dn_ifaddr *ifa) 774static void dn_ifaddr_notify(int event, struct dn_ifaddr *ifa)
747{ 775{
748 struct sk_buff *skb; 776 struct sk_buff *skb;
749 int payload = sizeof(struct ifaddrmsg) + 128;
750 int err = -ENOBUFS; 777 int err = -ENOBUFS;
751 778
752 skb = alloc_skb(nlmsg_total_size(payload), GFP_KERNEL); 779 skb = alloc_skb(dn_ifaddr_nlmsg_size(), GFP_KERNEL);
753 if (skb == NULL) 780 if (skb == NULL)
754 goto errout; 781 goto errout;
755 782
756 err = dn_dev_fill_ifaddr(skb, ifa, 0, 0, event, 0); 783 err = dn_nl_fill_ifaddr(skb, ifa, 0, 0, event, 0);
757 if (err < 0) { 784 /* failure implies BUG in dn_ifaddr_nlmsg_size() */
758 kfree_skb(skb); 785 BUG_ON(err < 0);
759 goto errout;
760 }
761 786
762 err = rtnl_notify(skb, 0, RTNLGRP_DECnet_IFADDR, NULL, GFP_KERNEL); 787 err = rtnl_notify(skb, 0, RTNLGRP_DECnet_IFADDR, NULL, GFP_KERNEL);
763errout: 788errout:
@@ -765,39 +790,43 @@ errout:
765 rtnl_set_sk_err(RTNLGRP_DECnet_IFADDR, err); 790 rtnl_set_sk_err(RTNLGRP_DECnet_IFADDR, err);
766} 791}
767 792
768static int dn_dev_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb) 793static int dn_nl_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
769{ 794{
770 int idx, dn_idx; 795 int idx, dn_idx = 0, skip_ndevs, skip_naddr;
771 int s_idx, s_dn_idx;
772 struct net_device *dev; 796 struct net_device *dev;
773 struct dn_dev *dn_db; 797 struct dn_dev *dn_db;
774 struct dn_ifaddr *ifa; 798 struct dn_ifaddr *ifa;
775 799
776 s_idx = cb->args[0]; 800 skip_ndevs = cb->args[0];
777 s_dn_idx = dn_idx = cb->args[1]; 801 skip_naddr = cb->args[1];
802
778 read_lock(&dev_base_lock); 803 read_lock(&dev_base_lock);
779 for(dev = dev_base, idx = 0; dev; dev = dev->next, idx++) { 804 for (dev = dev_base, idx = 0; dev; dev = dev->next, idx++) {
780 if (idx < s_idx) 805 if (idx < skip_ndevs)
781 continue; 806 continue;
782 if (idx > s_idx) 807 else if (idx > skip_ndevs) {
783 s_dn_idx = 0; 808 /* Only skip over addresses for first dev dumped
809 * in this iteration (idx == skip_ndevs) */
810 skip_naddr = 0;
811 }
812
784 if ((dn_db = dev->dn_ptr) == NULL) 813 if ((dn_db = dev->dn_ptr) == NULL)
785 continue; 814 continue;
786 815
787 for(ifa = dn_db->ifa_list, dn_idx = 0; ifa; ifa = ifa->ifa_next, dn_idx++) { 816 for (ifa = dn_db->ifa_list, dn_idx = 0; ifa;
788 if (dn_idx < s_dn_idx) 817 ifa = ifa->ifa_next, dn_idx++) {
818 if (dn_idx < skip_naddr)
789 continue; 819 continue;
790 820
791 if (dn_dev_fill_ifaddr(skb, ifa, 821 if (dn_nl_fill_ifaddr(skb, ifa, NETLINK_CB(cb->skb).pid,
792 NETLINK_CB(cb->skb).pid, 822 cb->nlh->nlmsg_seq, RTM_NEWADDR,
793 cb->nlh->nlmsg_seq, 823 NLM_F_MULTI) < 0)
794 RTM_NEWADDR,
795 NLM_F_MULTI) <= 0)
796 goto done; 824 goto done;
797 } 825 }
798 } 826 }
799done: 827done:
800 read_unlock(&dev_base_lock); 828 read_unlock(&dev_base_lock);
829
801 cb->args[0] = idx; 830 cb->args[0] = idx;
802 cb->args[1] = dn_idx; 831 cb->args[1] = dn_idx;
803 832
@@ -1414,9 +1443,9 @@ static struct file_operations dn_dev_seq_fops = {
1414 1443
1415static struct rtnetlink_link dnet_rtnetlink_table[RTM_NR_MSGTYPES] = 1444static struct rtnetlink_link dnet_rtnetlink_table[RTM_NR_MSGTYPES] =
1416{ 1445{
1417 [RTM_NEWADDR - RTM_BASE] = { .doit = dn_dev_rtm_newaddr, }, 1446 [RTM_NEWADDR - RTM_BASE] = { .doit = dn_nl_newaddr, },
1418 [RTM_DELADDR - RTM_BASE] = { .doit = dn_dev_rtm_deladdr, }, 1447 [RTM_DELADDR - RTM_BASE] = { .doit = dn_nl_deladdr, },
1419 [RTM_GETADDR - RTM_BASE] = { .dumpit = dn_dev_dump_ifaddr, }, 1448 [RTM_GETADDR - RTM_BASE] = { .dumpit = dn_nl_dump_ifaddr, },
1420#ifdef CONFIG_DECNET_ROUTER 1449#ifdef CONFIG_DECNET_ROUTER
1421 [RTM_NEWROUTE - RTM_BASE] = { .doit = dn_fib_rtm_newroute, }, 1450 [RTM_NEWROUTE - RTM_BASE] = { .doit = dn_fib_rtm_newroute, },
1422 [RTM_DELROUTE - RTM_BASE] = { .doit = dn_fib_rtm_delroute, }, 1451 [RTM_DELROUTE - RTM_BASE] = { .doit = dn_fib_rtm_delroute, },
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c
index ff0ebe9913..7322bb36e8 100644
--- a/net/decnet/dn_neigh.c
+++ b/net/decnet/dn_neigh.c
@@ -591,7 +591,6 @@ static int dn_neigh_seq_open(struct inode *inode, struct file *file)
591 591
592 seq = file->private_data; 592 seq = file->private_data;
593 seq->private = s; 593 seq->private = s;
594 memset(s, 0, sizeof(*s));
595out: 594out:
596 return rc; 595 return rc;
597out_kfree: 596out_kfree:
diff --git a/net/decnet/dn_nsp_in.c b/net/decnet/dn_nsp_in.c
index 7683d4f754..39a6cf7fb5 100644
--- a/net/decnet/dn_nsp_in.c
+++ b/net/decnet/dn_nsp_in.c
@@ -804,7 +804,7 @@ got_it:
804 goto free_out; 804 goto free_out;
805 } 805 }
806 806
807 return sk_receive_skb(sk, skb); 807 return sk_receive_skb(sk, skb, 0);
808 } 808 }
809 809
810 return dn_nsp_no_socket(skb, reason); 810 return dn_nsp_no_socket(skb, reason);
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 23489f7232..9881933167 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -269,9 +269,7 @@ static inline int compare_keys(struct flowi *fl1, struct flowi *fl2)
269{ 269{
270 return ((fl1->nl_u.dn_u.daddr ^ fl2->nl_u.dn_u.daddr) | 270 return ((fl1->nl_u.dn_u.daddr ^ fl2->nl_u.dn_u.daddr) |
271 (fl1->nl_u.dn_u.saddr ^ fl2->nl_u.dn_u.saddr) | 271 (fl1->nl_u.dn_u.saddr ^ fl2->nl_u.dn_u.saddr) |
272#ifdef CONFIG_DECNET_ROUTE_FWMARK 272 (fl1->mark ^ fl2->mark) |
273 (fl1->nl_u.dn_u.fwmark ^ fl2->nl_u.dn_u.fwmark) |
274#endif
275 (fl1->nl_u.dn_u.scope ^ fl2->nl_u.dn_u.scope) | 273 (fl1->nl_u.dn_u.scope ^ fl2->nl_u.dn_u.scope) |
276 (fl1->oif ^ fl2->oif) | 274 (fl1->oif ^ fl2->oif) |
277 (fl1->iif ^ fl2->iif)) == 0; 275 (fl1->iif ^ fl2->iif)) == 0;
@@ -882,10 +880,8 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old
882 { .daddr = oldflp->fld_dst, 880 { .daddr = oldflp->fld_dst,
883 .saddr = oldflp->fld_src, 881 .saddr = oldflp->fld_src,
884 .scope = RT_SCOPE_UNIVERSE, 882 .scope = RT_SCOPE_UNIVERSE,
885#ifdef CONFIG_DECNET_ROUTE_FWMARK
886 .fwmark = oldflp->fld_fwmark
887#endif
888 } }, 883 } },
884 .mark = oldflp->mark,
889 .iif = loopback_dev.ifindex, 885 .iif = loopback_dev.ifindex,
890 .oif = oldflp->oif }; 886 .oif = oldflp->oif };
891 struct dn_route *rt = NULL; 887 struct dn_route *rt = NULL;
@@ -903,7 +899,7 @@ static int dn_route_output_slow(struct dst_entry **pprt, const struct flowi *old
903 "dn_route_output_slow: dst=%04x src=%04x mark=%d" 899 "dn_route_output_slow: dst=%04x src=%04x mark=%d"
904 " iif=%d oif=%d\n", dn_ntohs(oldflp->fld_dst), 900 " iif=%d oif=%d\n", dn_ntohs(oldflp->fld_dst),
905 dn_ntohs(oldflp->fld_src), 901 dn_ntohs(oldflp->fld_src),
906 oldflp->fld_fwmark, loopback_dev.ifindex, oldflp->oif); 902 oldflp->mark, loopback_dev.ifindex, oldflp->oif);
907 903
908 /* If we have an output interface, verify its a DECnet device */ 904 /* If we have an output interface, verify its a DECnet device */
909 if (oldflp->oif) { 905 if (oldflp->oif) {
@@ -1108,9 +1104,7 @@ make_route:
1108 rt->fl.fld_dst = oldflp->fld_dst; 1104 rt->fl.fld_dst = oldflp->fld_dst;
1109 rt->fl.oif = oldflp->oif; 1105 rt->fl.oif = oldflp->oif;
1110 rt->fl.iif = 0; 1106 rt->fl.iif = 0;
1111#ifdef CONFIG_DECNET_ROUTE_FWMARK 1107 rt->fl.mark = oldflp->mark;
1112 rt->fl.fld_fwmark = oldflp->fld_fwmark;
1113#endif
1114 1108
1115 rt->rt_saddr = fl.fld_src; 1109 rt->rt_saddr = fl.fld_src;
1116 rt->rt_daddr = fl.fld_dst; 1110 rt->rt_daddr = fl.fld_dst;
@@ -1178,9 +1172,7 @@ static int __dn_route_output_key(struct dst_entry **pprt, const struct flowi *fl
1178 rt = rcu_dereference(rt->u.rt_next)) { 1172 rt = rcu_dereference(rt->u.rt_next)) {
1179 if ((flp->fld_dst == rt->fl.fld_dst) && 1173 if ((flp->fld_dst == rt->fl.fld_dst) &&
1180 (flp->fld_src == rt->fl.fld_src) && 1174 (flp->fld_src == rt->fl.fld_src) &&
1181#ifdef CONFIG_DECNET_ROUTE_FWMARK 1175 (flp->mark == rt->fl.mark) &&
1182 (flp->fld_fwmark == rt->fl.fld_fwmark) &&
1183#endif
1184 (rt->fl.iif == 0) && 1176 (rt->fl.iif == 0) &&
1185 (rt->fl.oif == flp->oif)) { 1177 (rt->fl.oif == flp->oif)) {
1186 rt->u.dst.lastuse = jiffies; 1178 rt->u.dst.lastuse = jiffies;
@@ -1235,10 +1227,8 @@ static int dn_route_input_slow(struct sk_buff *skb)
1235 { .daddr = cb->dst, 1227 { .daddr = cb->dst,
1236 .saddr = cb->src, 1228 .saddr = cb->src,
1237 .scope = RT_SCOPE_UNIVERSE, 1229 .scope = RT_SCOPE_UNIVERSE,
1238#ifdef CONFIG_DECNET_ROUTE_FWMARK
1239 .fwmark = skb->nfmark
1240#endif
1241 } }, 1230 } },
1231 .mark = skb->mark,
1242 .iif = skb->dev->ifindex }; 1232 .iif = skb->dev->ifindex };
1243 struct dn_fib_res res = { .fi = NULL, .type = RTN_UNREACHABLE }; 1233 struct dn_fib_res res = { .fi = NULL, .type = RTN_UNREACHABLE };
1244 int err = -EINVAL; 1234 int err = -EINVAL;
@@ -1385,7 +1375,7 @@ make_route:
1385 rt->fl.fld_dst = cb->dst; 1375 rt->fl.fld_dst = cb->dst;
1386 rt->fl.oif = 0; 1376 rt->fl.oif = 0;
1387 rt->fl.iif = in_dev->ifindex; 1377 rt->fl.iif = in_dev->ifindex;
1388 rt->fl.fld_fwmark = fl.fld_fwmark; 1378 rt->fl.mark = fl.mark;
1389 1379
1390 rt->u.dst.flags = DST_HOST; 1380 rt->u.dst.flags = DST_HOST;
1391 rt->u.dst.neighbour = neigh; 1381 rt->u.dst.neighbour = neigh;
@@ -1457,9 +1447,7 @@ int dn_route_input(struct sk_buff *skb)
1457 if ((rt->fl.fld_src == cb->src) && 1447 if ((rt->fl.fld_src == cb->src) &&
1458 (rt->fl.fld_dst == cb->dst) && 1448 (rt->fl.fld_dst == cb->dst) &&
1459 (rt->fl.oif == 0) && 1449 (rt->fl.oif == 0) &&
1460#ifdef CONFIG_DECNET_ROUTE_FWMARK 1450 (rt->fl.mark == skb->mark) &&
1461 (rt->fl.fld_fwmark == skb->nfmark) &&
1462#endif
1463 (rt->fl.iif == cb->iif)) { 1451 (rt->fl.iif == cb->iif)) {
1464 rt->u.dst.lastuse = jiffies; 1452 rt->u.dst.lastuse = jiffies;
1465 dst_hold(&rt->u.dst); 1453 dst_hold(&rt->u.dst);
@@ -1481,7 +1469,7 @@ static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
1481 struct rtmsg *r; 1469 struct rtmsg *r;
1482 struct nlmsghdr *nlh; 1470 struct nlmsghdr *nlh;
1483 unsigned char *b = skb->tail; 1471 unsigned char *b = skb->tail;
1484 struct rta_cacheinfo ci; 1472 long expires;
1485 1473
1486 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags); 1474 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags);
1487 r = NLMSG_DATA(nlh); 1475 r = NLMSG_DATA(nlh);
@@ -1514,16 +1502,10 @@ static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
1514 RTA_PUT(skb, RTA_GATEWAY, 2, &rt->rt_gateway); 1502 RTA_PUT(skb, RTA_GATEWAY, 2, &rt->rt_gateway);
1515 if (rtnetlink_put_metrics(skb, rt->u.dst.metrics) < 0) 1503 if (rtnetlink_put_metrics(skb, rt->u.dst.metrics) < 0)
1516 goto rtattr_failure; 1504 goto rtattr_failure;
1517 ci.rta_lastuse = jiffies_to_clock_t(jiffies - rt->u.dst.lastuse); 1505 expires = rt->u.dst.expires ? rt->u.dst.expires - jiffies : 0;
1518 ci.rta_used = rt->u.dst.__use; 1506 if (rtnl_put_cacheinfo(skb, &rt->u.dst, 0, 0, 0, expires,
1519 ci.rta_clntref = atomic_read(&rt->u.dst.__refcnt); 1507 rt->u.dst.error) < 0)
1520 if (rt->u.dst.expires) 1508 goto rtattr_failure;
1521 ci.rta_expires = jiffies_to_clock_t(rt->u.dst.expires - jiffies);
1522 else
1523 ci.rta_expires = 0;
1524 ci.rta_error = rt->u.dst.error;
1525 ci.rta_id = ci.rta_ts = ci.rta_tsage = 0;
1526 RTA_PUT(skb, RTA_CACHEINFO, sizeof(ci), &ci);
1527 if (rt->fl.iif) 1509 if (rt->fl.iif)
1528 RTA_PUT(skb, RTA_IIF, sizeof(int), &rt->fl.iif); 1510 RTA_PUT(skb, RTA_IIF, sizeof(int), &rt->fl.iif);
1529 1511
@@ -1604,8 +1586,6 @@ int dn_cache_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, void *arg)
1604 if (rtm->rtm_flags & RTM_F_NOTIFY) 1586 if (rtm->rtm_flags & RTM_F_NOTIFY)
1605 rt->rt_flags |= RTCF_NOTIFY; 1587 rt->rt_flags |= RTCF_NOTIFY;
1606 1588
1607 NETLINK_CB(skb).dst_pid = NETLINK_CB(in_skb).pid;
1608
1609 err = dn_rt_fill_info(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, RTM_NEWROUTE, 0, 0); 1589 err = dn_rt_fill_info(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, RTM_NEWROUTE, 0, 0);
1610 1590
1611 if (err == 0) 1591 if (err == 0)
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c
index 590e0a7249..e32d0c3d5a 100644
--- a/net/decnet/dn_rules.c
+++ b/net/decnet/dn_rules.c
@@ -45,10 +45,6 @@ struct dn_fib_rule
45 __le16 dstmask; 45 __le16 dstmask;
46 __le16 srcmap; 46 __le16 srcmap;
47 u8 flags; 47 u8 flags;
48#ifdef CONFIG_DECNET_ROUTE_FWMARK
49 u32 fwmark;
50 u32 fwmask;
51#endif
52}; 48};
53 49
54static struct dn_fib_rule default_rule = { 50static struct dn_fib_rule default_rule = {
@@ -112,13 +108,9 @@ errout:
112} 108}
113 109
114static struct nla_policy dn_fib_rule_policy[FRA_MAX+1] __read_mostly = { 110static struct nla_policy dn_fib_rule_policy[FRA_MAX+1] __read_mostly = {
115 [FRA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, 111 FRA_GENERIC_POLICY,
116 [FRA_PRIORITY] = { .type = NLA_U32 },
117 [FRA_SRC] = { .type = NLA_U16 }, 112 [FRA_SRC] = { .type = NLA_U16 },
118 [FRA_DST] = { .type = NLA_U16 }, 113 [FRA_DST] = { .type = NLA_U16 },
119 [FRA_FWMARK] = { .type = NLA_U32 },
120 [FRA_FWMASK] = { .type = NLA_U32 },
121 [FRA_TABLE] = { .type = NLA_U32 },
122}; 114};
123 115
124static int dn_fib_rule_match(struct fib_rule *rule, struct flowi *fl, int flags) 116static int dn_fib_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
@@ -131,11 +123,6 @@ static int dn_fib_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
131 ((daddr ^ r->dst) & r->dstmask)) 123 ((daddr ^ r->dst) & r->dstmask))
132 return 0; 124 return 0;
133 125
134#ifdef CONFIG_DECNET_ROUTE_FWMARK
135 if ((r->fwmark ^ fl->fld_fwmark) & r->fwmask)
136 return 0;
137#endif
138
139 return 1; 126 return 1;
140} 127}
141 128
@@ -169,20 +156,6 @@ static int dn_fib_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
169 if (tb[FRA_DST]) 156 if (tb[FRA_DST])
170 r->dst = nla_get_u16(tb[FRA_DST]); 157 r->dst = nla_get_u16(tb[FRA_DST]);
171 158
172#ifdef CONFIG_DECNET_ROUTE_FWMARK
173 if (tb[FRA_FWMARK]) {
174 r->fwmark = nla_get_u32(tb[FRA_FWMARK]);
175 if (r->fwmark)
176 /* compatibility: if the mark value is non-zero all bits
177 * are compared unless a mask is explicitly specified.
178 */
179 r->fwmask = 0xFFFFFFFF;
180 }
181
182 if (tb[FRA_FWMASK])
183 r->fwmask = nla_get_u32(tb[FRA_FWMASK]);
184#endif
185
186 r->src_len = frh->src_len; 159 r->src_len = frh->src_len;
187 r->srcmask = dnet_make_mask(r->src_len); 160 r->srcmask = dnet_make_mask(r->src_len);
188 r->dst_len = frh->dst_len; 161 r->dst_len = frh->dst_len;
@@ -203,14 +176,6 @@ static int dn_fib_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
203 if (frh->dst_len && (r->dst_len != frh->dst_len)) 176 if (frh->dst_len && (r->dst_len != frh->dst_len))
204 return 0; 177 return 0;
205 178
206#ifdef CONFIG_DECNET_ROUTE_FWMARK
207 if (tb[FRA_FWMARK] && (r->fwmark != nla_get_u32(tb[FRA_FWMARK])))
208 return 0;
209
210 if (tb[FRA_FWMASK] && (r->fwmask != nla_get_u32(tb[FRA_FWMASK])))
211 return 0;
212#endif
213
214 if (tb[FRA_SRC] && (r->src != nla_get_u16(tb[FRA_SRC]))) 179 if (tb[FRA_SRC] && (r->src != nla_get_u16(tb[FRA_SRC])))
215 return 0; 180 return 0;
216 181
@@ -248,12 +213,6 @@ static int dn_fib_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
248 frh->src_len = r->src_len; 213 frh->src_len = r->src_len;
249 frh->tos = 0; 214 frh->tos = 0;
250 215
251#ifdef CONFIG_DECNET_ROUTE_FWMARK
252 if (r->fwmark)
253 NLA_PUT_U32(skb, FRA_FWMARK, r->fwmark);
254 if (r->fwmask || r->fwmark)
255 NLA_PUT_U32(skb, FRA_FWMASK, r->fwmask);
256#endif
257 if (r->dst_len) 216 if (r->dst_len)
258 NLA_PUT_U16(skb, FRA_DST, r->dst); 217 NLA_PUT_U16(skb, FRA_DST, r->dst);
259 if (r->src_len) 218 if (r->src_len)
diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c
index 317904bb58..13b2421991 100644
--- a/net/decnet/dn_table.c
+++ b/net/decnet/dn_table.c
@@ -79,7 +79,7 @@ for( ; ((f) = *(fp)) != NULL && dn_key_eq((f)->fn_key, (key)); (fp) = &(f)->fn_n
79static struct hlist_head dn_fib_table_hash[DN_FIB_TABLE_HASHSZ]; 79static struct hlist_head dn_fib_table_hash[DN_FIB_TABLE_HASHSZ];
80static DEFINE_RWLOCK(dn_fib_tables_lock); 80static DEFINE_RWLOCK(dn_fib_tables_lock);
81 81
82static kmem_cache_t *dn_hash_kmem __read_mostly; 82static struct kmem_cache *dn_hash_kmem __read_mostly;
83static int dn_fib_hash_zombies; 83static int dn_fib_hash_zombies;
84 84
85static inline dn_fib_idx_t dn_hash(dn_fib_key_t key, struct dn_zone *dz) 85static inline dn_fib_idx_t dn_hash(dn_fib_key_t key, struct dn_zone *dz)
@@ -263,6 +263,32 @@ static int dn_fib_nh_match(struct rtmsg *r, struct nlmsghdr *nlh, struct dn_kern
263 return 0; 263 return 0;
264} 264}
265 265
266static inline size_t dn_fib_nlmsg_size(struct dn_fib_info *fi)
267{
268 size_t payload = NLMSG_ALIGN(sizeof(struct rtmsg))
269 + nla_total_size(4) /* RTA_TABLE */
270 + nla_total_size(2) /* RTA_DST */
271 + nla_total_size(4); /* RTA_PRIORITY */
272
273 /* space for nested metrics */
274 payload += nla_total_size((RTAX_MAX * nla_total_size(4)));
275
276 if (fi->fib_nhs) {
277 /* Also handles the special case fib_nhs == 1 */
278
279 /* each nexthop is packed in an attribute */
280 size_t nhsize = nla_total_size(sizeof(struct rtnexthop));
281
282 /* may contain a gateway attribute */
283 nhsize += nla_total_size(4);
284
285 /* all nexthops are packed in a nested attribute */
286 payload += nla_total_size(fi->fib_nhs * nhsize);
287 }
288
289 return payload;
290}
291
266static int dn_fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, 292static int dn_fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
267 u32 tb_id, u8 type, u8 scope, void *dst, int dst_len, 293 u32 tb_id, u8 type, u8 scope, void *dst, int dst_len,
268 struct dn_fib_info *fi, unsigned int flags) 294 struct dn_fib_info *fi, unsigned int flags)
@@ -335,17 +361,15 @@ static void dn_rtmsg_fib(int event, struct dn_fib_node *f, int z, u32 tb_id,
335 u32 pid = req ? req->pid : 0; 361 u32 pid = req ? req->pid : 0;
336 int err = -ENOBUFS; 362 int err = -ENOBUFS;
337 363
338 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 364 skb = nlmsg_new(dn_fib_nlmsg_size(DN_FIB_INFO(f)), GFP_KERNEL);
339 if (skb == NULL) 365 if (skb == NULL)
340 goto errout; 366 goto errout;
341 367
342 err = dn_fib_dump_info(skb, pid, nlh->nlmsg_seq, event, tb_id, 368 err = dn_fib_dump_info(skb, pid, nlh->nlmsg_seq, event, tb_id,
343 f->fn_type, f->fn_scope, &f->fn_key, z, 369 f->fn_type, f->fn_scope, &f->fn_key, z,
344 DN_FIB_INFO(f), 0); 370 DN_FIB_INFO(f), 0);
345 if (err < 0) { 371 /* failure implies BUG in dn_fib_nlmsg_size() */
346 kfree_skb(skb); 372 BUG_ON(err < 0);
347 goto errout;
348 }
349 373
350 err = rtnl_notify(skb, pid, RTNLGRP_DECnet_ROUTE, nlh, GFP_KERNEL); 374 err = rtnl_notify(skb, pid, RTNLGRP_DECnet_ROUTE, nlh, GFP_KERNEL);
351errout: 375errout:
@@ -566,7 +590,7 @@ create:
566 590
567replace: 591replace:
568 err = -ENOBUFS; 592 err = -ENOBUFS;
569 new_f = kmem_cache_alloc(dn_hash_kmem, SLAB_KERNEL); 593 new_f = kmem_cache_alloc(dn_hash_kmem, GFP_KERNEL);
570 if (new_f == NULL) 594 if (new_f == NULL)
571 goto out; 595 goto out;
572 596
@@ -807,10 +831,11 @@ struct dn_fib_table *dn_fib_get_table(u32 n, int create)
807 printk(KERN_DEBUG "DECnet: BUG! Attempt to create routing table from interrupt\n"); 831 printk(KERN_DEBUG "DECnet: BUG! Attempt to create routing table from interrupt\n");
808 return NULL; 832 return NULL;
809 } 833 }
810 if ((t = kmalloc(sizeof(struct dn_fib_table) + sizeof(struct dn_hash), GFP_KERNEL)) == NULL)
811 return NULL;
812 834
813 memset(t, 0, sizeof(struct dn_fib_table)); 835 t = kzalloc(sizeof(struct dn_fib_table) + sizeof(struct dn_hash),
836 GFP_KERNEL);
837 if (t == NULL)
838 return NULL;
814 839
815 t->n = n; 840 t->n = n;
816 t->insert = dn_fib_table_insert; 841 t->insert = dn_fib_table_insert;
@@ -818,7 +843,6 @@ struct dn_fib_table *dn_fib_get_table(u32 n, int create)
818 t->lookup = dn_fib_table_lookup; 843 t->lookup = dn_fib_table_lookup;
819 t->flush = dn_fib_table_flush; 844 t->flush = dn_fib_table_flush;
820 t->dump = dn_fib_table_dump; 845 t->dump = dn_fib_table_dump;
821 memset(t->data, 0, sizeof(struct dn_hash));
822 hlist_add_head_rcu(&t->hlist, &dn_fib_table_hash[h]); 846 hlist_add_head_rcu(&t->hlist, &dn_fib_table_hash[h]);
823 847
824 return t; 848 return t;
diff --git a/net/decnet/sysctl_net_decnet.c b/net/decnet/sysctl_net_decnet.c
index e246f054f3..a4065eb134 100644
--- a/net/decnet/sysctl_net_decnet.c
+++ b/net/decnet/sysctl_net_decnet.c
@@ -134,8 +134,7 @@ static int parse_addr(__le16 *addr, char *str)
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, int __user *name, int nlen,
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 void **context)
139{ 138{
140 size_t len; 139 size_t len;
141 __le16 addr; 140 __le16 addr;
@@ -220,8 +219,7 @@ static int dn_node_address_handler(ctl_table *table, int write,
220 219
221static int dn_def_dev_strategy(ctl_table *table, int __user *name, int nlen, 220static int dn_def_dev_strategy(ctl_table *table, int __user *name, int nlen,
222 void __user *oldval, size_t __user *oldlenp, 221 void __user *oldval, size_t __user *oldlenp,
223 void __user *newval, size_t newlen, 222 void __user *newval, size_t newlen)
224 void **context)
225{ 223{
226 size_t len; 224 size_t len;
227 struct net_device *dev; 225 struct net_device *dev;
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index 4bd78c8cfb..2d31bf3f05 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -60,7 +60,6 @@
60#include <net/ip.h> 60#include <net/ip.h>
61#include <asm/uaccess.h> 61#include <asm/uaccess.h>
62#include <asm/system.h> 62#include <asm/system.h>
63#include <asm/checksum.h>
64 63
65__setup("ether=", netdev_boot_setup); 64__setup("ether=", netdev_boot_setup);
66 65
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
index 4200ec5098..fc1f99a597 100644
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ b/net/ieee80211/ieee80211_crypt_tkip.c
@@ -16,6 +16,7 @@
16#include <linux/random.h> 16#include <linux/random.h>
17#include <linux/skbuff.h> 17#include <linux/skbuff.h>
18#include <linux/netdevice.h> 18#include <linux/netdevice.h>
19#include <linux/mm.h>
19#include <linux/if_ether.h> 20#include <linux/if_ether.h>
20#include <linux/if_arp.h> 21#include <linux/if_arp.h>
21#include <asm/string.h> 22#include <asm/string.h>
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c
index 1b2efff11d..7a95c3d813 100644
--- a/net/ieee80211/ieee80211_crypt_wep.c
+++ b/net/ieee80211/ieee80211_crypt_wep.c
@@ -15,6 +15,7 @@
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/random.h> 16#include <linux/random.h>
17#include <linux/skbuff.h> 17#include <linux/skbuff.h>
18#include <linux/mm.h>
18#include <asm/string.h> 19#include <asm/string.h>
19 20
20#include <net/ieee80211.h> 21#include <net/ieee80211.h>
diff --git a/net/ieee80211/ieee80211_module.c b/net/ieee80211/ieee80211_module.c
index 13b1e5fff7..b1c6d1f717 100644
--- a/net/ieee80211/ieee80211_module.c
+++ b/net/ieee80211/ieee80211_module.c
@@ -67,7 +67,7 @@ static int ieee80211_networks_allocate(struct ieee80211_device *ieee)
67 return 0; 67 return 0;
68 68
69 ieee->networks = 69 ieee->networks =
70 kmalloc(MAX_NETWORK_COUNT * sizeof(struct ieee80211_network), 70 kzalloc(MAX_NETWORK_COUNT * sizeof(struct ieee80211_network),
71 GFP_KERNEL); 71 GFP_KERNEL);
72 if (!ieee->networks) { 72 if (!ieee->networks) {
73 printk(KERN_WARNING "%s: Out of memory allocating beacons\n", 73 printk(KERN_WARNING "%s: Out of memory allocating beacons\n",
@@ -75,9 +75,6 @@ static int ieee80211_networks_allocate(struct ieee80211_device *ieee)
75 return -ENOMEM; 75 return -ENOMEM;
76 } 76 }
77 77
78 memset(ieee->networks, 0,
79 MAX_NETWORK_COUNT * sizeof(struct ieee80211_network));
80
81 return 0; 78 return 0;
82} 79}
83 80
@@ -118,6 +115,21 @@ static void ieee80211_networks_initialize(struct ieee80211_device *ieee)
118 &ieee->network_free_list); 115 &ieee->network_free_list);
119} 116}
120 117
118static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
119{
120 if ((new_mtu < 68) || (new_mtu > IEEE80211_DATA_LEN))
121 return -EINVAL;
122 dev->mtu = new_mtu;
123 return 0;
124}
125
126static struct net_device_stats *ieee80211_generic_get_stats(
127 struct net_device *dev)
128{
129 struct ieee80211_device *ieee = netdev_priv(dev);
130 return &ieee->stats;
131}
132
121struct net_device *alloc_ieee80211(int sizeof_priv) 133struct net_device *alloc_ieee80211(int sizeof_priv)
122{ 134{
123 struct ieee80211_device *ieee; 135 struct ieee80211_device *ieee;
@@ -133,6 +145,11 @@ struct net_device *alloc_ieee80211(int sizeof_priv)
133 } 145 }
134 ieee = netdev_priv(dev); 146 ieee = netdev_priv(dev);
135 dev->hard_start_xmit = ieee80211_xmit; 147 dev->hard_start_xmit = ieee80211_xmit;
148 dev->change_mtu = ieee80211_change_mtu;
149
150 /* Drivers are free to override this if the generic implementation
151 * does not meet their needs. */
152 dev->get_stats = ieee80211_generic_get_stats;
136 153
137 ieee->dev = dev; 154 ieee->dev = dev;
138 155
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
index 2759312a42..d97e5412e3 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -415,17 +415,16 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
415 ieee->host_mc_decrypt : ieee->host_decrypt; 415 ieee->host_mc_decrypt : ieee->host_decrypt;
416 416
417 if (can_be_decrypted) { 417 if (can_be_decrypted) {
418 int idx = 0;
419 if (skb->len >= hdrlen + 3) { 418 if (skb->len >= hdrlen + 3) {
420 /* Top two-bits of byte 3 are the key index */ 419 /* Top two-bits of byte 3 are the key index */
421 idx = skb->data[hdrlen + 3] >> 6; 420 keyidx = skb->data[hdrlen + 3] >> 6;
422 } 421 }
423 422
424 /* ieee->crypt[] is WEP_KEY (4) in length. Given that idx 423 /* ieee->crypt[] is WEP_KEY (4) in length. Given that keyidx
425 * is only allowed 2-bits of storage, no value of idx can 424 * is only allowed 2-bits of storage, no value of keyidx can
426 * be provided via above code that would result in idx 425 * be provided via above code that would result in keyidx
427 * being out of range */ 426 * being out of range */
428 crypt = ieee->crypt[idx]; 427 crypt = ieee->crypt[keyidx];
429 428
430#ifdef NOT_YET 429#ifdef NOT_YET
431 sta = NULL; 430 sta = NULL;
@@ -479,6 +478,11 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
479 goto rx_exit; 478 goto rx_exit;
480 } 479 }
481#endif 480#endif
481 /* drop duplicate 802.11 retransmissions (IEEE 802.11 Chap. 9.29) */
482 if (sc == ieee->prev_seq_ctl)
483 goto rx_dropped;
484 else
485 ieee->prev_seq_ctl = sc;
482 486
483 /* Data frame - extract src/dst addresses */ 487 /* Data frame - extract src/dst addresses */
484 if (skb->len < IEEE80211_3ADDR_LEN) 488 if (skb->len < IEEE80211_3ADDR_LEN)
@@ -655,6 +659,51 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
655 goto rx_dropped; 659 goto rx_dropped;
656 } 660 }
657 661
662 /* If the frame was decrypted in hardware, we may need to strip off
663 * any security data (IV, ICV, etc) that was left behind */
664 if (!can_be_decrypted && (fc & IEEE80211_FCTL_PROTECTED) &&
665 ieee->host_strip_iv_icv) {
666 int trimlen = 0;
667
668 /* Top two-bits of byte 3 are the key index */
669 if (skb->len >= hdrlen + 3)
670 keyidx = skb->data[hdrlen + 3] >> 6;
671
672 /* To strip off any security data which appears before the
673 * payload, we simply increase hdrlen (as the header gets
674 * chopped off immediately below). For the security data which
675 * appears after the payload, we use skb_trim. */
676
677 switch (ieee->sec.encode_alg[keyidx]) {
678 case SEC_ALG_WEP:
679 /* 4 byte IV */
680 hdrlen += 4;
681 /* 4 byte ICV */
682 trimlen = 4;
683 break;
684 case SEC_ALG_TKIP:
685 /* 4 byte IV, 4 byte ExtIV */
686 hdrlen += 8;
687 /* 8 byte MIC, 4 byte ICV */
688 trimlen = 12;
689 break;
690 case SEC_ALG_CCMP:
691 /* 8 byte CCMP header */
692 hdrlen += 8;
693 /* 8 byte MIC */
694 trimlen = 8;
695 break;
696 }
697
698 if (skb->len < trimlen)
699 goto rx_dropped;
700
701 __skb_trim(skb, skb->len - trimlen);
702
703 if (skb->len < hdrlen)
704 goto rx_dropped;
705 }
706
658 /* skb: hdr + (possible reassembled) full plaintext payload */ 707 /* skb: hdr + (possible reassembled) full plaintext payload */
659 708
660 payload = skb->data + hdrlen; 709 payload = skb->data + hdrlen;
@@ -1255,12 +1304,11 @@ static int ieee80211_parse_info_param(struct ieee80211_info_element
1255 case MFIE_TYPE_IBSS_DFS: 1304 case MFIE_TYPE_IBSS_DFS:
1256 if (network->ibss_dfs) 1305 if (network->ibss_dfs)
1257 break; 1306 break;
1258 network->ibss_dfs = 1307 network->ibss_dfs = kmemdup(info_element->data,
1259 kmalloc(info_element->len, GFP_ATOMIC); 1308 info_element->len,
1309 GFP_ATOMIC);
1260 if (!network->ibss_dfs) 1310 if (!network->ibss_dfs)
1261 return 1; 1311 return 1;
1262 memcpy(network->ibss_dfs, info_element->data,
1263 info_element->len);
1264 network->flags |= NETWORK_HAS_IBSS_DFS; 1312 network->flags |= NETWORK_HAS_IBSS_DFS;
1265 break; 1313 break;
1266 1314
diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c
index ae254497ba..854fc13cd7 100644
--- a/net/ieee80211/ieee80211_tx.c
+++ b/net/ieee80211/ieee80211_tx.c
@@ -390,7 +390,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
390 * this stack is providing the full 802.11 header, one will 390 * this stack is providing the full 802.11 header, one will
391 * eventually be affixed to this fragment -- so we must account 391 * eventually be affixed to this fragment -- so we must account
392 * for it when determining the amount of payload space. */ 392 * for it when determining the amount of payload space. */
393 bytes_per_frag = frag_size - IEEE80211_3ADDR_LEN; 393 bytes_per_frag = frag_size - hdr_len;
394 if (ieee->config & 394 if (ieee->config &
395 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) 395 (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
396 bytes_per_frag -= IEEE80211_FCS_LEN; 396 bytes_per_frag -= IEEE80211_FCS_LEN;
@@ -412,7 +412,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
412 } else { 412 } else {
413 nr_frags = 1; 413 nr_frags = 1;
414 bytes_per_frag = bytes_last_frag = bytes; 414 bytes_per_frag = bytes_last_frag = bytes;
415 frag_size = bytes + IEEE80211_3ADDR_LEN; 415 frag_size = bytes + hdr_len;
416 } 416 }
417 417
418 rts_required = (frag_size > ieee->rts 418 rts_required = (frag_size > ieee->rts
diff --git a/net/ieee80211/softmac/ieee80211softmac_assoc.c b/net/ieee80211/softmac/ieee80211softmac_assoc.c
index cf51c87a97..a824852909 100644
--- a/net/ieee80211/softmac/ieee80211softmac_assoc.c
+++ b/net/ieee80211/softmac/ieee80211softmac_assoc.c
@@ -58,9 +58,11 @@ ieee80211softmac_assoc(struct ieee80211softmac_device *mac, struct ieee80211soft
58} 58}
59 59
60void 60void
61ieee80211softmac_assoc_timeout(void *d) 61ieee80211softmac_assoc_timeout(struct work_struct *work)
62{ 62{
63 struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d; 63 struct ieee80211softmac_device *mac =
64 container_of(work, struct ieee80211softmac_device,
65 associnfo.timeout.work);
64 struct ieee80211softmac_network *n; 66 struct ieee80211softmac_network *n;
65 67
66 mutex_lock(&mac->associnfo.mutex); 68 mutex_lock(&mac->associnfo.mutex);
@@ -165,7 +167,7 @@ static void
165ieee80211softmac_assoc_notify_scan(struct net_device *dev, int event_type, void *context) 167ieee80211softmac_assoc_notify_scan(struct net_device *dev, int event_type, void *context)
166{ 168{
167 struct ieee80211softmac_device *mac = ieee80211_priv(dev); 169 struct ieee80211softmac_device *mac = ieee80211_priv(dev);
168 ieee80211softmac_assoc_work((void*)mac); 170 ieee80211softmac_assoc_work(&mac->associnfo.work.work);
169} 171}
170 172
171static void 173static void
@@ -175,7 +177,7 @@ ieee80211softmac_assoc_notify_auth(struct net_device *dev, int event_type, void
175 177
176 switch (event_type) { 178 switch (event_type) {
177 case IEEE80211SOFTMAC_EVENT_AUTHENTICATED: 179 case IEEE80211SOFTMAC_EVENT_AUTHENTICATED:
178 ieee80211softmac_assoc_work((void*)mac); 180 ieee80211softmac_assoc_work(&mac->associnfo.work.work);
179 break; 181 break;
180 case IEEE80211SOFTMAC_EVENT_AUTH_FAILED: 182 case IEEE80211SOFTMAC_EVENT_AUTH_FAILED:
181 case IEEE80211SOFTMAC_EVENT_AUTH_TIMEOUT: 183 case IEEE80211SOFTMAC_EVENT_AUTH_TIMEOUT:
@@ -186,9 +188,11 @@ ieee80211softmac_assoc_notify_auth(struct net_device *dev, int event_type, void
186 188
187/* This function is called to handle userspace requests (asynchronously) */ 189/* This function is called to handle userspace requests (asynchronously) */
188void 190void
189ieee80211softmac_assoc_work(void *d) 191ieee80211softmac_assoc_work(struct work_struct *work)
190{ 192{
191 struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d; 193 struct ieee80211softmac_device *mac =
194 container_of(work, struct ieee80211softmac_device,
195 associnfo.work.work);
192 struct ieee80211softmac_network *found = NULL; 196 struct ieee80211softmac_network *found = NULL;
193 struct ieee80211_network *net = NULL, *best = NULL; 197 struct ieee80211_network *net = NULL, *best = NULL;
194 int bssvalid; 198 int bssvalid;
@@ -412,7 +416,7 @@ ieee80211softmac_handle_assoc_response(struct net_device * dev,
412 network->authenticated = 0; 416 network->authenticated = 0;
413 /* we don't want to do this more than once ... */ 417 /* we don't want to do this more than once ... */
414 network->auth_desynced_once = 1; 418 network->auth_desynced_once = 1;
415 schedule_work(&mac->associnfo.work); 419 schedule_delayed_work(&mac->associnfo.work, 0);
416 break; 420 break;
417 } 421 }
418 default: 422 default:
@@ -427,6 +431,17 @@ ieee80211softmac_handle_assoc_response(struct net_device * dev,
427 return 0; 431 return 0;
428} 432}
429 433
434void
435ieee80211softmac_try_reassoc(struct ieee80211softmac_device *mac)
436{
437 unsigned long flags;
438
439 spin_lock_irqsave(&mac->lock, flags);
440 mac->associnfo.associating = 1;
441 schedule_delayed_work(&mac->associnfo.work, 0);
442 spin_unlock_irqrestore(&mac->lock, flags);
443}
444
430int 445int
431ieee80211softmac_handle_disassoc(struct net_device * dev, 446ieee80211softmac_handle_disassoc(struct net_device * dev,
432 struct ieee80211_disassoc *disassoc) 447 struct ieee80211_disassoc *disassoc)
@@ -445,8 +460,7 @@ ieee80211softmac_handle_disassoc(struct net_device * dev,
445 dprintk(KERN_INFO PFX "got disassoc frame\n"); 460 dprintk(KERN_INFO PFX "got disassoc frame\n");
446 ieee80211softmac_disassoc(mac); 461 ieee80211softmac_disassoc(mac);
447 462
448 /* try to reassociate */ 463 ieee80211softmac_try_reassoc(mac);
449 schedule_work(&mac->associnfo.work);
450 464
451 return 0; 465 return 0;
452} 466}
@@ -466,7 +480,7 @@ ieee80211softmac_handle_reassoc_req(struct net_device * dev,
466 dprintkl(KERN_INFO PFX "reassoc request from unknown network\n"); 480 dprintkl(KERN_INFO PFX "reassoc request from unknown network\n");
467 return 0; 481 return 0;
468 } 482 }
469 schedule_work(&mac->associnfo.work); 483 schedule_delayed_work(&mac->associnfo.work, 0);
470 484
471 return 0; 485 return 0;
472} 486}
diff --git a/net/ieee80211/softmac/ieee80211softmac_auth.c b/net/ieee80211/softmac/ieee80211softmac_auth.c
index 4cef39e171..8ed3e59b80 100644
--- a/net/ieee80211/softmac/ieee80211softmac_auth.c
+++ b/net/ieee80211/softmac/ieee80211softmac_auth.c
@@ -26,7 +26,7 @@
26 26
27#include "ieee80211softmac_priv.h" 27#include "ieee80211softmac_priv.h"
28 28
29static void ieee80211softmac_auth_queue(void *data); 29static void ieee80211softmac_auth_queue(struct work_struct *work);
30 30
31/* Queues an auth request to the desired AP */ 31/* Queues an auth request to the desired AP */
32int 32int
@@ -54,14 +54,14 @@ ieee80211softmac_auth_req(struct ieee80211softmac_device *mac,
54 auth->mac = mac; 54 auth->mac = mac;
55 auth->retry = IEEE80211SOFTMAC_AUTH_RETRY_LIMIT; 55 auth->retry = IEEE80211SOFTMAC_AUTH_RETRY_LIMIT;
56 auth->state = IEEE80211SOFTMAC_AUTH_OPEN_REQUEST; 56 auth->state = IEEE80211SOFTMAC_AUTH_OPEN_REQUEST;
57 INIT_WORK(&auth->work, &ieee80211softmac_auth_queue, (void *)auth); 57 INIT_DELAYED_WORK(&auth->work, ieee80211softmac_auth_queue);
58 58
59 /* Lock (for list) */ 59 /* Lock (for list) */
60 spin_lock_irqsave(&mac->lock, flags); 60 spin_lock_irqsave(&mac->lock, flags);
61 61
62 /* add to list */ 62 /* add to list */
63 list_add_tail(&auth->list, &mac->auth_queue); 63 list_add_tail(&auth->list, &mac->auth_queue);
64 schedule_work(&auth->work); 64 schedule_delayed_work(&auth->work, 0);
65 spin_unlock_irqrestore(&mac->lock, flags); 65 spin_unlock_irqrestore(&mac->lock, flags);
66 66
67 return 0; 67 return 0;
@@ -70,14 +70,15 @@ ieee80211softmac_auth_req(struct ieee80211softmac_device *mac,
70 70
71/* Sends an auth request to the desired AP and handles timeouts */ 71/* Sends an auth request to the desired AP and handles timeouts */
72static void 72static void
73ieee80211softmac_auth_queue(void *data) 73ieee80211softmac_auth_queue(struct work_struct *work)
74{ 74{
75 struct ieee80211softmac_device *mac; 75 struct ieee80211softmac_device *mac;
76 struct ieee80211softmac_auth_queue_item *auth; 76 struct ieee80211softmac_auth_queue_item *auth;
77 struct ieee80211softmac_network *net; 77 struct ieee80211softmac_network *net;
78 unsigned long flags; 78 unsigned long flags;
79 79
80 auth = (struct ieee80211softmac_auth_queue_item *)data; 80 auth = container_of(work, struct ieee80211softmac_auth_queue_item,
81 work.work);
81 net = auth->net; 82 net = auth->net;
82 mac = auth->mac; 83 mac = auth->mac;
83 84
@@ -118,9 +119,11 @@ ieee80211softmac_auth_queue(void *data)
118 119
119/* Sends a response to an auth challenge (for shared key auth). */ 120/* Sends a response to an auth challenge (for shared key auth). */
120static void 121static void
121ieee80211softmac_auth_challenge_response(void *_aq) 122ieee80211softmac_auth_challenge_response(struct work_struct *work)
122{ 123{
123 struct ieee80211softmac_auth_queue_item *aq = _aq; 124 struct ieee80211softmac_auth_queue_item *aq =
125 container_of(work, struct ieee80211softmac_auth_queue_item,
126 work.work);
124 127
125 /* Send our response */ 128 /* Send our response */
126 ieee80211softmac_send_mgt_frame(aq->mac, aq->net, IEEE80211_STYPE_AUTH, aq->state); 129 ieee80211softmac_send_mgt_frame(aq->mac, aq->net, IEEE80211_STYPE_AUTH, aq->state);
@@ -158,7 +161,7 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth)
158 /* Make sure that we've got an auth queue item for this request */ 161 /* Make sure that we've got an auth queue item for this request */
159 if(aq == NULL) 162 if(aq == NULL)
160 { 163 {
161 printkl(KERN_DEBUG PFX "Authentication response received from "MAC_FMT" but no queue item exists.\n", MAC_ARG(auth->header.addr2)); 164 dprintkl(KERN_DEBUG PFX "Authentication response received from "MAC_FMT" but no queue item exists.\n", MAC_ARG(auth->header.addr2));
162 /* Error #? */ 165 /* Error #? */
163 return -1; 166 return -1;
164 } 167 }
@@ -166,7 +169,7 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth)
166 /* Check for out of order authentication */ 169 /* Check for out of order authentication */
167 if(!net->authenticating) 170 if(!net->authenticating)
168 { 171 {
169 printkl(KERN_DEBUG PFX "Authentication response received from "MAC_FMT" but did not request authentication.\n",MAC_ARG(auth->header.addr2)); 172 dprintkl(KERN_DEBUG PFX "Authentication response received from "MAC_FMT" but did not request authentication.\n",MAC_ARG(auth->header.addr2));
170 return -1; 173 return -1;
171 } 174 }
172 175
@@ -216,10 +219,16 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth)
216 net->challenge_len = *data++; 219 net->challenge_len = *data++;
217 if (net->challenge_len > WLAN_AUTH_CHALLENGE_LEN) 220 if (net->challenge_len > WLAN_AUTH_CHALLENGE_LEN)
218 net->challenge_len = WLAN_AUTH_CHALLENGE_LEN; 221 net->challenge_len = WLAN_AUTH_CHALLENGE_LEN;
219 if (net->challenge != NULL) 222 kfree(net->challenge);
220 kfree(net->challenge); 223 net->challenge = kmemdup(data, net->challenge_len,
221 net->challenge = kmalloc(net->challenge_len, GFP_ATOMIC); 224 GFP_ATOMIC);
222 memcpy(net->challenge, data, net->challenge_len); 225 if (net->challenge == NULL) {
226 printkl(KERN_NOTICE PFX "Shared Key "
227 "Authentication failed due to "
228 "memory shortage.\n");
229 spin_unlock_irqrestore(&mac->lock, flags);
230 break;
231 }
223 aq->state = IEEE80211SOFTMAC_AUTH_SHARED_RESPONSE; 232 aq->state = IEEE80211SOFTMAC_AUTH_SHARED_RESPONSE;
224 233
225 /* We reuse the work struct from the auth request here. 234 /* We reuse the work struct from the auth request here.
@@ -228,8 +237,8 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth)
228 * we have obviously already sent the initial auth 237 * we have obviously already sent the initial auth
229 * request. */ 238 * request. */
230 cancel_delayed_work(&aq->work); 239 cancel_delayed_work(&aq->work);
231 INIT_WORK(&aq->work, &ieee80211softmac_auth_challenge_response, (void *)aq); 240 INIT_DELAYED_WORK(&aq->work, &ieee80211softmac_auth_challenge_response);
232 schedule_work(&aq->work); 241 schedule_delayed_work(&aq->work, 0);
233 spin_unlock_irqrestore(&mac->lock, flags); 242 spin_unlock_irqrestore(&mac->lock, flags);
234 return 0; 243 return 0;
235 case IEEE80211SOFTMAC_AUTH_SHARED_PASS: 244 case IEEE80211SOFTMAC_AUTH_SHARED_PASS:
@@ -328,6 +337,8 @@ ieee80211softmac_deauth_from_net(struct ieee80211softmac_device *mac,
328 /* can't transmit data right now... */ 337 /* can't transmit data right now... */
329 netif_carrier_off(mac->dev); 338 netif_carrier_off(mac->dev);
330 spin_unlock_irqrestore(&mac->lock, flags); 339 spin_unlock_irqrestore(&mac->lock, flags);
340
341 ieee80211softmac_try_reassoc(mac);
331} 342}
332 343
333/* 344/*
@@ -342,7 +353,7 @@ ieee80211softmac_deauth_req(struct ieee80211softmac_device *mac,
342 /* Make sure the network is authenticated */ 353 /* Make sure the network is authenticated */
343 if (!net->authenticated) 354 if (!net->authenticated)
344 { 355 {
345 printkl(KERN_DEBUG PFX "Can't send deauthentication packet, network is not authenticated.\n"); 356 dprintkl(KERN_DEBUG PFX "Can't send deauthentication packet, network is not authenticated.\n");
346 /* Error okay? */ 357 /* Error okay? */
347 return -EPERM; 358 return -EPERM;
348 } 359 }
@@ -376,7 +387,7 @@ ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *de
376 net = ieee80211softmac_get_network_by_bssid(mac, deauth->header.addr2); 387 net = ieee80211softmac_get_network_by_bssid(mac, deauth->header.addr2);
377 388
378 if (net == NULL) { 389 if (net == NULL) {
379 printkl(KERN_DEBUG PFX "Received deauthentication packet from "MAC_FMT", but that network is unknown.\n", 390 dprintkl(KERN_DEBUG PFX "Received deauthentication packet from "MAC_FMT", but that network is unknown.\n",
380 MAC_ARG(deauth->header.addr2)); 391 MAC_ARG(deauth->header.addr2));
381 return 0; 392 return 0;
382 } 393 }
@@ -384,7 +395,7 @@ ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *de
384 /* Make sure the network is authenticated */ 395 /* Make sure the network is authenticated */
385 if(!net->authenticated) 396 if(!net->authenticated)
386 { 397 {
387 printkl(KERN_DEBUG PFX "Can't perform deauthentication, network is not authenticated.\n"); 398 dprintkl(KERN_DEBUG PFX "Can't perform deauthentication, network is not authenticated.\n");
388 /* Error okay? */ 399 /* Error okay? */
389 return -EPERM; 400 return -EPERM;
390 } 401 }
@@ -392,6 +403,6 @@ ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *de
392 ieee80211softmac_deauth_from_net(mac, net); 403 ieee80211softmac_deauth_from_net(mac, net);
393 404
394 /* let's try to re-associate */ 405 /* let's try to re-associate */
395 schedule_work(&mac->associnfo.work); 406 schedule_delayed_work(&mac->associnfo.work, 0);
396 return 0; 407 return 0;
397} 408}
diff --git a/net/ieee80211/softmac/ieee80211softmac_event.c b/net/ieee80211/softmac/ieee80211softmac_event.c
index f34fa2ef66..b9015656cf 100644
--- a/net/ieee80211/softmac/ieee80211softmac_event.c
+++ b/net/ieee80211/softmac/ieee80211softmac_event.c
@@ -73,10 +73,12 @@ static char *event_descriptions[IEEE80211SOFTMAC_EVENT_LAST+1] = {
73 73
74 74
75static void 75static void
76ieee80211softmac_notify_callback(void *d) 76ieee80211softmac_notify_callback(struct work_struct *work)
77{ 77{
78 struct ieee80211softmac_event event = *(struct ieee80211softmac_event*) d; 78 struct ieee80211softmac_event *pevent =
79 kfree(d); 79 container_of(work, struct ieee80211softmac_event, work.work);
80 struct ieee80211softmac_event event = *pevent;
81 kfree(pevent);
80 82
81 event.fun(event.mac->dev, event.event_type, event.context); 83 event.fun(event.mac->dev, event.event_type, event.context);
82} 84}
@@ -99,7 +101,7 @@ ieee80211softmac_notify_internal(struct ieee80211softmac_device *mac,
99 return -ENOMEM; 101 return -ENOMEM;
100 102
101 eventptr->event_type = event; 103 eventptr->event_type = event;
102 INIT_WORK(&eventptr->work, ieee80211softmac_notify_callback, eventptr); 104 INIT_DELAYED_WORK(&eventptr->work, ieee80211softmac_notify_callback);
103 eventptr->fun = fun; 105 eventptr->fun = fun;
104 eventptr->context = context; 106 eventptr->context = context;
105 eventptr->mac = mac; 107 eventptr->mac = mac;
@@ -170,7 +172,7 @@ ieee80211softmac_call_events_locked(struct ieee80211softmac_device *mac, int eve
170 /* User may have subscribed to ANY event, so 172 /* User may have subscribed to ANY event, so
171 * we tell them which event triggered it. */ 173 * we tell them which event triggered it. */
172 eventptr->event_type = event; 174 eventptr->event_type = event;
173 schedule_work(&eventptr->work); 175 schedule_delayed_work(&eventptr->work, 0);
174 } 176 }
175 } 177 }
176} 178}
diff --git a/net/ieee80211/softmac/ieee80211softmac_module.c b/net/ieee80211/softmac/ieee80211softmac_module.c
index 33aff4f4a4..256207b71d 100644
--- a/net/ieee80211/softmac/ieee80211softmac_module.c
+++ b/net/ieee80211/softmac/ieee80211softmac_module.c
@@ -58,8 +58,8 @@ struct net_device *alloc_ieee80211softmac(int sizeof_priv)
58 INIT_LIST_HEAD(&softmac->events); 58 INIT_LIST_HEAD(&softmac->events);
59 59
60 mutex_init(&softmac->associnfo.mutex); 60 mutex_init(&softmac->associnfo.mutex);
61 INIT_WORK(&softmac->associnfo.work, ieee80211softmac_assoc_work, softmac); 61 INIT_DELAYED_WORK(&softmac->associnfo.work, ieee80211softmac_assoc_work);
62 INIT_WORK(&softmac->associnfo.timeout, ieee80211softmac_assoc_timeout, softmac); 62 INIT_DELAYED_WORK(&softmac->associnfo.timeout, ieee80211softmac_assoc_timeout);
63 softmac->start_scan = ieee80211softmac_start_scan_implementation; 63 softmac->start_scan = ieee80211softmac_start_scan_implementation;
64 softmac->wait_for_scan = ieee80211softmac_wait_for_scan_implementation; 64 softmac->wait_for_scan = ieee80211softmac_wait_for_scan_implementation;
65 softmac->stop_scan = ieee80211softmac_stop_scan_implementation; 65 softmac->stop_scan = ieee80211softmac_stop_scan_implementation;
diff --git a/net/ieee80211/softmac/ieee80211softmac_priv.h b/net/ieee80211/softmac/ieee80211softmac_priv.h
index 0642e090b8..4c2bba34d3 100644
--- a/net/ieee80211/softmac/ieee80211softmac_priv.h
+++ b/net/ieee80211/softmac/ieee80211softmac_priv.h
@@ -78,7 +78,7 @@
78/* private definitions and prototypes */ 78/* private definitions and prototypes */
79 79
80/*** prototypes from _scan.c */ 80/*** prototypes from _scan.c */
81void ieee80211softmac_scan(void *sm); 81void ieee80211softmac_scan(struct work_struct *work);
82/* for internal use if scanning is needed */ 82/* for internal use if scanning is needed */
83int ieee80211softmac_start_scan(struct ieee80211softmac_device *mac); 83int ieee80211softmac_start_scan(struct ieee80211softmac_device *mac);
84void ieee80211softmac_stop_scan(struct ieee80211softmac_device *mac); 84void ieee80211softmac_stop_scan(struct ieee80211softmac_device *mac);
@@ -149,7 +149,7 @@ int ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *au
149int ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *deauth); 149int ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *deauth);
150 150
151/*** prototypes from _assoc.c */ 151/*** prototypes from _assoc.c */
152void ieee80211softmac_assoc_work(void *d); 152void ieee80211softmac_assoc_work(struct work_struct *work);
153int ieee80211softmac_handle_assoc_response(struct net_device * dev, 153int ieee80211softmac_handle_assoc_response(struct net_device * dev,
154 struct ieee80211_assoc_response * resp, 154 struct ieee80211_assoc_response * resp,
155 struct ieee80211_network * network); 155 struct ieee80211_network * network);
@@ -157,7 +157,7 @@ int ieee80211softmac_handle_disassoc(struct net_device * dev,
157 struct ieee80211_disassoc * disassoc); 157 struct ieee80211_disassoc * disassoc);
158int ieee80211softmac_handle_reassoc_req(struct net_device * dev, 158int ieee80211softmac_handle_reassoc_req(struct net_device * dev,
159 struct ieee80211_reassoc_request * reassoc); 159 struct ieee80211_reassoc_request * reassoc);
160void ieee80211softmac_assoc_timeout(void *d); 160void ieee80211softmac_assoc_timeout(struct work_struct *work);
161void ieee80211softmac_send_disassoc_req(struct ieee80211softmac_device *mac, u16 reason); 161void ieee80211softmac_send_disassoc_req(struct ieee80211softmac_device *mac, u16 reason);
162void ieee80211softmac_disassoc(struct ieee80211softmac_device *mac); 162void ieee80211softmac_disassoc(struct ieee80211softmac_device *mac);
163 163
@@ -207,7 +207,7 @@ struct ieee80211softmac_auth_queue_item {
207 struct ieee80211softmac_device *mac; /* SoftMAC device */ 207 struct ieee80211softmac_device *mac; /* SoftMAC device */
208 u8 retry; /* Retry limit */ 208 u8 retry; /* Retry limit */
209 u8 state; /* Auth State */ 209 u8 state; /* Auth State */
210 struct work_struct work; /* Work queue */ 210 struct delayed_work work; /* Work queue */
211}; 211};
212 212
213/* scanning information */ 213/* scanning information */
@@ -219,7 +219,8 @@ struct ieee80211softmac_scaninfo {
219 stop:1; 219 stop:1;
220 u8 skip_flags; 220 u8 skip_flags;
221 struct completion finished; 221 struct completion finished;
222 struct work_struct softmac_scan; 222 struct delayed_work softmac_scan;
223 struct ieee80211softmac_device *mac;
223}; 224};
224 225
225/* private event struct */ 226/* private event struct */
@@ -227,7 +228,7 @@ struct ieee80211softmac_event {
227 struct list_head list; 228 struct list_head list;
228 int event_type; 229 int event_type;
229 void *event_context; 230 void *event_context;
230 struct work_struct work; 231 struct delayed_work work;
231 notify_function_ptr fun; 232 notify_function_ptr fun;
232 void *context; 233 void *context;
233 struct ieee80211softmac_device *mac; 234 struct ieee80211softmac_device *mac;
@@ -238,4 +239,6 @@ void ieee80211softmac_call_events_locked(struct ieee80211softmac_device *mac, in
238int ieee80211softmac_notify_internal(struct ieee80211softmac_device *mac, 239int ieee80211softmac_notify_internal(struct ieee80211softmac_device *mac,
239 int event, void *event_context, notify_function_ptr fun, void *context, gfp_t gfp_mask); 240 int event, void *event_context, notify_function_ptr fun, void *context, gfp_t gfp_mask);
240 241
242void ieee80211softmac_try_reassoc(struct ieee80211softmac_device *mac);
243
241#endif /* IEEE80211SOFTMAC_PRIV_H_ */ 244#endif /* IEEE80211SOFTMAC_PRIV_H_ */
diff --git a/net/ieee80211/softmac/ieee80211softmac_scan.c b/net/ieee80211/softmac/ieee80211softmac_scan.c
index d31cf77498..0c85d6c24c 100644
--- a/net/ieee80211/softmac/ieee80211softmac_scan.c
+++ b/net/ieee80211/softmac/ieee80211softmac_scan.c
@@ -47,7 +47,6 @@ ieee80211softmac_start_scan(struct ieee80211softmac_device *sm)
47 sm->scanning = 1; 47 sm->scanning = 1;
48 spin_unlock_irqrestore(&sm->lock, flags); 48 spin_unlock_irqrestore(&sm->lock, flags);
49 49
50 netif_tx_disable(sm->ieee->dev);
51 ret = sm->start_scan(sm->dev); 50 ret = sm->start_scan(sm->dev);
52 if (ret) { 51 if (ret) {
53 spin_lock_irqsave(&sm->lock, flags); 52 spin_lock_irqsave(&sm->lock, flags);
@@ -91,12 +90,14 @@ ieee80211softmac_wait_for_scan(struct ieee80211softmac_device *sm)
91 90
92 91
93/* internal scanning implementation follows */ 92/* internal scanning implementation follows */
94void ieee80211softmac_scan(void *d) 93void ieee80211softmac_scan(struct work_struct *work)
95{ 94{
96 int invalid_channel; 95 int invalid_channel;
97 u8 current_channel_idx; 96 u8 current_channel_idx;
98 struct ieee80211softmac_device *sm = (struct ieee80211softmac_device *)d; 97 struct ieee80211softmac_scaninfo *si =
99 struct ieee80211softmac_scaninfo *si = sm->scaninfo; 98 container_of(work, struct ieee80211softmac_scaninfo,
99 softmac_scan.work);
100 struct ieee80211softmac_device *sm = si->mac;
100 unsigned long flags; 101 unsigned long flags;
101 102
102 while (!(si->stop) && (si->current_channel_idx < si->number_channels)) { 103 while (!(si->stop) && (si->current_channel_idx < si->number_channels)) {
@@ -135,7 +136,8 @@ void ieee80211softmac_scan(void *d)
135 si->started = 0; 136 si->started = 0;
136 spin_unlock_irqrestore(&sm->lock, flags); 137 spin_unlock_irqrestore(&sm->lock, flags);
137 138
138 dprintk(PFX "Scanning finished\n"); 139 dprintk(PFX "Scanning finished: scanned %d channels starting with channel %d\n",
140 sm->scaninfo->number_channels, sm->scaninfo->channels[0].channel);
139 ieee80211softmac_scan_finished(sm); 141 ieee80211softmac_scan_finished(sm);
140 complete_all(&sm->scaninfo->finished); 142 complete_all(&sm->scaninfo->finished);
141} 143}
@@ -146,7 +148,8 @@ static inline struct ieee80211softmac_scaninfo *allocate_scaninfo(struct ieee802
146 struct ieee80211softmac_scaninfo *info = kmalloc(sizeof(struct ieee80211softmac_scaninfo), GFP_ATOMIC); 148 struct ieee80211softmac_scaninfo *info = kmalloc(sizeof(struct ieee80211softmac_scaninfo), GFP_ATOMIC);
147 if (unlikely(!info)) 149 if (unlikely(!info))
148 return NULL; 150 return NULL;
149 INIT_WORK(&info->softmac_scan, ieee80211softmac_scan, mac); 151 INIT_DELAYED_WORK(&info->softmac_scan, ieee80211softmac_scan);
152 info->mac = mac;
150 init_completion(&info->finished); 153 init_completion(&info->finished);
151 return info; 154 return info;
152} 155}
@@ -183,13 +186,11 @@ int ieee80211softmac_start_scan_implementation(struct net_device *dev)
183 sm->scaninfo->channels = sm->ieee->geo.bg; 186 sm->scaninfo->channels = sm->ieee->geo.bg;
184 sm->scaninfo->number_channels = sm->ieee->geo.bg_channels; 187 sm->scaninfo->number_channels = sm->ieee->geo.bg_channels;
185 } 188 }
186 dprintk(PFX "Start scanning with channel: %d\n", sm->scaninfo->channels[0].channel);
187 dprintk(PFX "Scanning %d channels\n", sm->scaninfo->number_channels);
188 sm->scaninfo->current_channel_idx = 0; 189 sm->scaninfo->current_channel_idx = 0;
189 sm->scaninfo->started = 1; 190 sm->scaninfo->started = 1;
190 sm->scaninfo->stop = 0; 191 sm->scaninfo->stop = 0;
191 INIT_COMPLETION(sm->scaninfo->finished); 192 INIT_COMPLETION(sm->scaninfo->finished);
192 schedule_work(&sm->scaninfo->softmac_scan); 193 schedule_delayed_work(&sm->scaninfo->softmac_scan, 0);
193 spin_unlock_irqrestore(&sm->lock, flags); 194 spin_unlock_irqrestore(&sm->lock, flags);
194 return 0; 195 return 0;
195} 196}
@@ -248,7 +249,6 @@ void ieee80211softmac_scan_finished(struct ieee80211softmac_device *sm)
248 if (net) 249 if (net)
249 sm->set_channel(sm->dev, net->channel); 250 sm->set_channel(sm->dev, net->channel);
250 } 251 }
251 netif_wake_queue(sm->ieee->dev);
252 ieee80211softmac_call_events(sm, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, NULL); 252 ieee80211softmac_call_events(sm, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, NULL);
253} 253}
254EXPORT_SYMBOL_GPL(ieee80211softmac_scan_finished); 254EXPORT_SYMBOL_GPL(ieee80211softmac_scan_finished);
diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c
index 23068a830f..fa2f7da606 100644
--- a/net/ieee80211/softmac/ieee80211softmac_wx.c
+++ b/net/ieee80211/softmac/ieee80211softmac_wx.c
@@ -122,7 +122,7 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev,
122 122
123 sm->associnfo.associating = 1; 123 sm->associnfo.associating = 1;
124 /* queue lower level code to do work (if necessary) */ 124 /* queue lower level code to do work (if necessary) */
125 schedule_work(&sm->associnfo.work); 125 schedule_delayed_work(&sm->associnfo.work, 0);
126out: 126out:
127 mutex_unlock(&sm->associnfo.mutex); 127 mutex_unlock(&sm->associnfo.mutex);
128 128
@@ -356,7 +356,7 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev,
356 /* force reassociation */ 356 /* force reassociation */
357 mac->associnfo.bssvalid = 0; 357 mac->associnfo.bssvalid = 0;
358 if (mac->associnfo.associated) 358 if (mac->associnfo.associated)
359 schedule_work(&mac->associnfo.work); 359 schedule_delayed_work(&mac->associnfo.work, 0);
360 } else if (is_zero_ether_addr(data->ap_addr.sa_data)) { 360 } else if (is_zero_ether_addr(data->ap_addr.sa_data)) {
361 /* the bssid we have is no longer fixed */ 361 /* the bssid we have is no longer fixed */
362 mac->associnfo.bssfixed = 0; 362 mac->associnfo.bssfixed = 0;
@@ -373,7 +373,7 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev,
373 /* tell the other code that this bssid should be used no matter what */ 373 /* tell the other code that this bssid should be used no matter what */
374 mac->associnfo.bssfixed = 1; 374 mac->associnfo.bssfixed = 1;
375 /* queue associate if new bssid or (old one again and not associated) */ 375 /* queue associate if new bssid or (old one again and not associated) */
376 schedule_work(&mac->associnfo.work); 376 schedule_delayed_work(&mac->associnfo.work, 0);
377 } 377 }
378 378
379 out: 379 out:
@@ -463,7 +463,7 @@ ieee80211softmac_wx_get_genie(struct net_device *dev,
463 err = -E2BIG; 463 err = -E2BIG;
464 } 464 }
465 spin_unlock_irqrestore(&mac->lock, flags); 465 spin_unlock_irqrestore(&mac->lock, flags);
466 mutex_lock(&mac->associnfo.mutex); 466 mutex_unlock(&mac->associnfo.mutex);
467 467
468 return err; 468 return err;
469} 469}
@@ -495,7 +495,8 @@ ieee80211softmac_wx_set_mlme(struct net_device *dev,
495 printk(KERN_DEBUG PFX "wx_set_mlme: we should know the net here...\n"); 495 printk(KERN_DEBUG PFX "wx_set_mlme: we should know the net here...\n");
496 goto out; 496 goto out;
497 } 497 }
498 return ieee80211softmac_deauth_req(mac, net, reason); 498 err = ieee80211softmac_deauth_req(mac, net, reason);
499 goto out;
499 case IW_MLME_DISASSOC: 500 case IW_MLME_DISASSOC:
500 ieee80211softmac_send_disassoc_req(mac, reason); 501 ieee80211softmac_send_disassoc_req(mac, reason);
501 mac->associnfo.associated = 0; 502 mac->associnfo.associated = 0;
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig
index 5572071af7..503e7059e3 100644
--- a/net/ipv4/Kconfig
+++ b/net/ipv4/Kconfig
@@ -104,13 +104,6 @@ config IP_MULTIPLE_TABLES
104 104
105 If unsure, say N. 105 If unsure, say N.
106 106
107config IP_ROUTE_FWMARK
108 bool "IP: use netfilter MARK value as routing key"
109 depends on IP_MULTIPLE_TABLES && NETFILTER
110 help
111 If you say Y here, you will be able to specify different routes for
112 packets with different mark values (see iptables(8), MARK target).
113
114config IP_ROUTE_MULTIPATH 107config IP_ROUTE_MULTIPATH
115 bool "IP: equal cost multipath" 108 bool "IP: equal cost multipath"
116 depends on IP_ADVANCED_ROUTER 109 depends on IP_ADVANCED_ROUTER
@@ -625,5 +618,17 @@ config DEFAULT_TCP_CONG
625 default "reno" if DEFAULT_RENO 618 default "reno" if DEFAULT_RENO
626 default "cubic" 619 default "cubic"
627 620
621config TCP_MD5SIG
622 bool "TCP: MD5 Signature Option support (RFC2385) (EXPERIMENTAL)"
623 depends on EXPERIMENTAL
624 select CRYPTO
625 select CRYPTO_MD5
626 ---help---
627 RFC2385 specifices a method of giving MD5 protection to TCP sessions.
628 Its main (only?) use is to protect BGP sessions between core routers
629 on the Internet.
630
631 If unsure, say N.
632
628source "net/ipv4/ipvs/Kconfig" 633source "net/ipv4/ipvs/Kconfig"
629 634
diff --git a/net/ipv4/Makefile b/net/ipv4/Makefile
index 15645c5152..7a068626fe 100644
--- a/net/ipv4/Makefile
+++ b/net/ipv4/Makefile
@@ -8,7 +8,8 @@ obj-y := route.o inetpeer.o protocol.o \
8 inet_timewait_sock.o inet_connection_sock.o \ 8 inet_timewait_sock.o inet_connection_sock.o \
9 tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o \ 9 tcp.o tcp_input.o tcp_output.o tcp_timer.o tcp_ipv4.o \
10 tcp_minisocks.o tcp_cong.o \ 10 tcp_minisocks.o tcp_cong.o \
11 datagram.o raw.o udp.o arp.o icmp.o devinet.o af_inet.o igmp.o \ 11 datagram.o raw.o udp.o udplite.o \
12 arp.o icmp.o devinet.o af_inet.o igmp.o \
12 sysctl_net_ipv4.o fib_frontend.o fib_semantics.o 13 sysctl_net_ipv4.o fib_frontend.o fib_semantics.o
13 14
14obj-$(CONFIG_IP_FIB_HASH) += fib_hash.o 15obj-$(CONFIG_IP_FIB_HASH) += fib_hash.o
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index edcf0932ac..8640096436 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -104,6 +104,7 @@
104#include <net/inet_connection_sock.h> 104#include <net/inet_connection_sock.h>
105#include <net/tcp.h> 105#include <net/tcp.h>
106#include <net/udp.h> 106#include <net/udp.h>
107#include <net/udplite.h>
107#include <linux/skbuff.h> 108#include <linux/skbuff.h>
108#include <net/sock.h> 109#include <net/sock.h>
109#include <net/raw.h> 110#include <net/raw.h>
@@ -204,7 +205,7 @@ int inet_listen(struct socket *sock, int backlog)
204 * we can only allow the backlog to be adjusted. 205 * we can only allow the backlog to be adjusted.
205 */ 206 */
206 if (old_state != TCP_LISTEN) { 207 if (old_state != TCP_LISTEN) {
207 err = inet_csk_listen_start(sk, TCP_SYNQ_HSIZE); 208 err = inet_csk_listen_start(sk, backlog);
208 if (err) 209 if (err)
209 goto out; 210 goto out;
210 } 211 }
@@ -304,7 +305,7 @@ lookup_protocol:
304 sk->sk_reuse = 1; 305 sk->sk_reuse = 1;
305 306
306 inet = inet_sk(sk); 307 inet = inet_sk(sk);
307 inet->is_icsk = INET_PROTOSW_ICSK & answer_flags; 308 inet->is_icsk = (INET_PROTOSW_ICSK & answer_flags) != 0;
308 309
309 if (SOCK_RAW == sock->type) { 310 if (SOCK_RAW == sock->type) {
310 inet->num = protocol; 311 inet->num = protocol;
@@ -643,7 +644,7 @@ int inet_getname(struct socket *sock, struct sockaddr *uaddr,
643 sin->sin_port = inet->dport; 644 sin->sin_port = inet->dport;
644 sin->sin_addr.s_addr = inet->daddr; 645 sin->sin_addr.s_addr = inet->daddr;
645 } else { 646 } else {
646 __u32 addr = inet->rcv_saddr; 647 __be32 addr = inet->rcv_saddr;
647 if (!addr) 648 if (!addr)
648 addr = inet->saddr; 649 addr = inet->saddr;
649 sin->sin_port = inet->sport; 650 sin->sin_port = inet->sport;
@@ -994,8 +995,8 @@ static int inet_sk_reselect_saddr(struct sock *sk)
994 struct inet_sock *inet = inet_sk(sk); 995 struct inet_sock *inet = inet_sk(sk);
995 int err; 996 int err;
996 struct rtable *rt; 997 struct rtable *rt;
997 __u32 old_saddr = inet->saddr; 998 __be32 old_saddr = inet->saddr;
998 __u32 new_saddr; 999 __be32 new_saddr;
999 __be32 daddr = inet->daddr; 1000 __be32 daddr = inet->daddr;
1000 1001
1001 if (inet->opt && inet->opt->srr) 1002 if (inet->opt && inet->opt->srr)
@@ -1223,10 +1224,13 @@ static int __init init_ipv4_mibs(void)
1223 tcp_statistics[1] = alloc_percpu(struct tcp_mib); 1224 tcp_statistics[1] = alloc_percpu(struct tcp_mib);
1224 udp_statistics[0] = alloc_percpu(struct udp_mib); 1225 udp_statistics[0] = alloc_percpu(struct udp_mib);
1225 udp_statistics[1] = alloc_percpu(struct udp_mib); 1226 udp_statistics[1] = alloc_percpu(struct udp_mib);
1227 udplite_statistics[0] = alloc_percpu(struct udp_mib);
1228 udplite_statistics[1] = alloc_percpu(struct udp_mib);
1226 if (! 1229 if (!
1227 (net_statistics[0] && net_statistics[1] && ip_statistics[0] 1230 (net_statistics[0] && net_statistics[1] && ip_statistics[0]
1228 && ip_statistics[1] && tcp_statistics[0] && tcp_statistics[1] 1231 && ip_statistics[1] && tcp_statistics[0] && tcp_statistics[1]
1229 && udp_statistics[0] && udp_statistics[1])) 1232 && udp_statistics[0] && udp_statistics[1]
1233 && udplite_statistics[0] && udplite_statistics[1] ) )
1230 return -ENOMEM; 1234 return -ENOMEM;
1231 1235
1232 (void) tcp_mib_init(); 1236 (void) tcp_mib_init();
@@ -1313,6 +1317,8 @@ static int __init inet_init(void)
1313 /* Setup TCP slab cache for open requests. */ 1317 /* Setup TCP slab cache for open requests. */
1314 tcp_init(); 1318 tcp_init();
1315 1319
1320 /* Add UDP-Lite (RFC 3828) */
1321 udplite4_register();
1316 1322
1317 /* 1323 /*
1318 * Set the ICMP layer up 1324 * Set the ICMP layer up
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index 99542977e4..67a5509e26 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -14,7 +14,7 @@
14 * into IP header for icv calculation. Options are already checked 14 * into IP header for icv calculation. Options are already checked
15 * for validity, so paranoia is not required. */ 15 * for validity, so paranoia is not required. */
16 16
17static int ip_clear_mutable_options(struct iphdr *iph, u32 *daddr) 17static int ip_clear_mutable_options(struct iphdr *iph, __be32 *daddr)
18{ 18{
19 unsigned char * optptr = (unsigned char*)(iph+1); 19 unsigned char * optptr = (unsigned char*)(iph+1);
20 int l = iph->ihl*4 - sizeof(struct iphdr); 20 int l = iph->ihl*4 - sizeof(struct iphdr);
@@ -162,7 +162,7 @@ static int ah_input(struct xfrm_state *x, struct sk_buff *skb)
162 iph->frag_off = 0; 162 iph->frag_off = 0;
163 iph->check = 0; 163 iph->check = 0;
164 if (ihl > sizeof(*iph)) { 164 if (ihl > sizeof(*iph)) {
165 u32 dummy; 165 __be32 dummy;
166 if (ip_clear_mutable_options(iph, &dummy)) 166 if (ip_clear_mutable_options(iph, &dummy))
167 goto out; 167 goto out;
168 } 168 }
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index cfb5d3de9c..3981e8be9a 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -203,7 +203,7 @@ struct neigh_table arp_tbl = {
203 .gc_thresh3 = 1024, 203 .gc_thresh3 = 1024,
204}; 204};
205 205
206int arp_mc_map(u32 addr, u8 *haddr, struct net_device *dev, int dir) 206int arp_mc_map(__be32 addr, u8 *haddr, struct net_device *dev, int dir)
207{ 207{
208 switch (dev->type) { 208 switch (dev->type) {
209 case ARPHRD_ETHER: 209 case ARPHRD_ETHER:
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c
index 6460233407..60aafb4a8a 100644
--- a/net/ipv4/cipso_ipv4.c
+++ b/net/ipv4/cipso_ipv4.c
@@ -319,6 +319,7 @@ static int cipso_v4_cache_check(const unsigned char *key,
319 entry->activity += 1; 319 entry->activity += 1;
320 atomic_inc(&entry->lsm_data->refcount); 320 atomic_inc(&entry->lsm_data->refcount);
321 secattr->cache = entry->lsm_data; 321 secattr->cache = entry->lsm_data;
322 secattr->flags |= NETLBL_SECATTR_CACHE;
322 if (prev_entry == NULL) { 323 if (prev_entry == NULL) {
323 spin_unlock_bh(&cipso_v4_cache[bkt].lock); 324 spin_unlock_bh(&cipso_v4_cache[bkt].lock);
324 return 0; 325 return 0;
@@ -377,12 +378,11 @@ int cipso_v4_cache_add(const struct sk_buff *skb,
377 entry = kzalloc(sizeof(*entry), GFP_ATOMIC); 378 entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
378 if (entry == NULL) 379 if (entry == NULL)
379 return -ENOMEM; 380 return -ENOMEM;
380 entry->key = kmalloc(cipso_ptr_len, GFP_ATOMIC); 381 entry->key = kmemdup(cipso_ptr, cipso_ptr_len, GFP_ATOMIC);
381 if (entry->key == NULL) { 382 if (entry->key == NULL) {
382 ret_val = -ENOMEM; 383 ret_val = -ENOMEM;
383 goto cache_add_failure; 384 goto cache_add_failure;
384 } 385 }
385 memcpy(entry->key, cipso_ptr, cipso_ptr_len);
386 entry->key_len = cipso_ptr_len; 386 entry->key_len = cipso_ptr_len;
387 entry->hash = cipso_v4_map_cache_hash(cipso_ptr, cipso_ptr_len); 387 entry->hash = cipso_v4_map_cache_hash(cipso_ptr, cipso_ptr_len);
388 atomic_inc(&secattr->cache->refcount); 388 atomic_inc(&secattr->cache->refcount);
@@ -447,8 +447,30 @@ static struct cipso_v4_doi *cipso_v4_doi_search(u32 doi)
447 */ 447 */
448int cipso_v4_doi_add(struct cipso_v4_doi *doi_def) 448int cipso_v4_doi_add(struct cipso_v4_doi *doi_def)
449{ 449{
450 u32 iter;
451
450 if (doi_def == NULL || doi_def->doi == CIPSO_V4_DOI_UNKNOWN) 452 if (doi_def == NULL || doi_def->doi == CIPSO_V4_DOI_UNKNOWN)
451 return -EINVAL; 453 return -EINVAL;
454 for (iter = 0; iter < CIPSO_V4_TAG_MAXCNT; iter++) {
455 switch (doi_def->tags[iter]) {
456 case CIPSO_V4_TAG_RBITMAP:
457 break;
458 case CIPSO_V4_TAG_RANGE:
459 if (doi_def->type != CIPSO_V4_MAP_PASS)
460 return -EINVAL;
461 break;
462 case CIPSO_V4_TAG_INVALID:
463 if (iter == 0)
464 return -EINVAL;
465 break;
466 case CIPSO_V4_TAG_ENUM:
467 if (doi_def->type != CIPSO_V4_MAP_PASS)
468 return -EINVAL;
469 break;
470 default:
471 return -EINVAL;
472 }
473 }
452 474
453 doi_def->valid = 1; 475 doi_def->valid = 1;
454 INIT_RCU_HEAD(&doi_def->rcu); 476 INIT_RCU_HEAD(&doi_def->rcu);
@@ -805,8 +827,7 @@ static int cipso_v4_map_cat_rbm_valid(const struct cipso_v4_doi *doi_def,
805/** 827/**
806 * cipso_v4_map_cat_rbm_hton - Perform a category mapping from host to network 828 * cipso_v4_map_cat_rbm_hton - Perform a category mapping from host to network
807 * @doi_def: the DOI definition 829 * @doi_def: the DOI definition
808 * @host_cat: the category bitmap in host format 830 * @secattr: the security attributes
809 * @host_cat_len: the length of the host's category bitmap in bytes
810 * @net_cat: the zero'd out category bitmap in network/CIPSO format 831 * @net_cat: the zero'd out category bitmap in network/CIPSO format
811 * @net_cat_len: the length of the CIPSO bitmap in bytes 832 * @net_cat_len: the length of the CIPSO bitmap in bytes
812 * 833 *
@@ -817,59 +838,51 @@ static int cipso_v4_map_cat_rbm_valid(const struct cipso_v4_doi *doi_def,
817 * 838 *
818 */ 839 */
819static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def, 840static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def,
820 const unsigned char *host_cat, 841 const struct netlbl_lsm_secattr *secattr,
821 u32 host_cat_len,
822 unsigned char *net_cat, 842 unsigned char *net_cat,
823 u32 net_cat_len) 843 u32 net_cat_len)
824{ 844{
825 int host_spot = -1; 845 int host_spot = -1;
826 u32 net_spot; 846 u32 net_spot = CIPSO_V4_INV_CAT;
827 u32 net_spot_max = 0; 847 u32 net_spot_max = 0;
828 u32 host_clen_bits = host_cat_len * 8;
829 u32 net_clen_bits = net_cat_len * 8; 848 u32 net_clen_bits = net_cat_len * 8;
830 u32 host_cat_size; 849 u32 host_cat_size = 0;
831 u32 *host_cat_array; 850 u32 *host_cat_array = NULL;
832 851
833 switch (doi_def->type) { 852 if (doi_def->type == CIPSO_V4_MAP_STD) {
834 case CIPSO_V4_MAP_PASS:
835 net_spot_max = host_cat_len;
836 while (net_spot_max > 0 && host_cat[net_spot_max - 1] == 0)
837 net_spot_max--;
838 if (net_spot_max > net_cat_len)
839 return -EINVAL;
840 memcpy(net_cat, host_cat, net_spot_max);
841 return net_spot_max;
842 case CIPSO_V4_MAP_STD:
843 host_cat_size = doi_def->map.std->cat.local_size; 853 host_cat_size = doi_def->map.std->cat.local_size;
844 host_cat_array = doi_def->map.std->cat.local; 854 host_cat_array = doi_def->map.std->cat.local;
845 for (;;) { 855 }
846 host_spot = cipso_v4_bitmap_walk(host_cat, 856
847 host_clen_bits, 857 for (;;) {
848 host_spot + 1, 858 host_spot = netlbl_secattr_catmap_walk(secattr->mls_cat,
849 1); 859 host_spot + 1);
850 if (host_spot < 0) 860 if (host_spot < 0)
851 break; 861 break;
862
863 switch (doi_def->type) {
864 case CIPSO_V4_MAP_PASS:
865 net_spot = host_spot;
866 break;
867 case CIPSO_V4_MAP_STD:
852 if (host_spot >= host_cat_size) 868 if (host_spot >= host_cat_size)
853 return -EPERM; 869 return -EPERM;
854
855 net_spot = host_cat_array[host_spot]; 870 net_spot = host_cat_array[host_spot];
856 if (net_spot >= net_clen_bits) 871 if (net_spot >= CIPSO_V4_INV_CAT)
857 return -ENOSPC; 872 return -EPERM;
858 cipso_v4_bitmap_setbit(net_cat, net_spot, 1); 873 break;
859
860 if (net_spot > net_spot_max)
861 net_spot_max = net_spot;
862 } 874 }
875 if (net_spot >= net_clen_bits)
876 return -ENOSPC;
877 cipso_v4_bitmap_setbit(net_cat, net_spot, 1);
863 878
864 if (host_spot == -2) 879 if (net_spot > net_spot_max)
865 return -EFAULT; 880 net_spot_max = net_spot;
866
867 if (++net_spot_max % 8)
868 return net_spot_max / 8 + 1;
869 return net_spot_max / 8;
870 } 881 }
871 882
872 return -EINVAL; 883 if (++net_spot_max % 8)
884 return net_spot_max / 8 + 1;
885 return net_spot_max / 8;
873} 886}
874 887
875/** 888/**
@@ -877,102 +890,333 @@ static int cipso_v4_map_cat_rbm_hton(const struct cipso_v4_doi *doi_def,
877 * @doi_def: the DOI definition 890 * @doi_def: the DOI definition
878 * @net_cat: the category bitmap in network/CIPSO format 891 * @net_cat: the category bitmap in network/CIPSO format
879 * @net_cat_len: the length of the CIPSO bitmap in bytes 892 * @net_cat_len: the length of the CIPSO bitmap in bytes
880 * @host_cat: the zero'd out category bitmap in host format 893 * @secattr: the security attributes
881 * @host_cat_len: the length of the host's category bitmap in bytes
882 * 894 *
883 * Description: 895 * Description:
884 * Perform a label mapping to translate a CIPSO bitmap to the correct local 896 * Perform a label mapping to translate a CIPSO bitmap to the correct local
885 * MLS category bitmap using the given DOI definition. Returns the minimum 897 * MLS category bitmap using the given DOI definition. Returns zero on
886 * size in bytes of the host bitmap on success, negative values otherwise. 898 * success, negative values on failure.
887 * 899 *
888 */ 900 */
889static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def, 901static int cipso_v4_map_cat_rbm_ntoh(const struct cipso_v4_doi *doi_def,
890 const unsigned char *net_cat, 902 const unsigned char *net_cat,
891 u32 net_cat_len, 903 u32 net_cat_len,
892 unsigned char *host_cat, 904 struct netlbl_lsm_secattr *secattr)
893 u32 host_cat_len)
894{ 905{
895 u32 host_spot; 906 int ret_val;
896 u32 host_spot_max = 0;
897 int net_spot = -1; 907 int net_spot = -1;
908 u32 host_spot = CIPSO_V4_INV_CAT;
898 u32 net_clen_bits = net_cat_len * 8; 909 u32 net_clen_bits = net_cat_len * 8;
899 u32 host_clen_bits = host_cat_len * 8; 910 u32 net_cat_size = 0;
900 u32 net_cat_size; 911 u32 *net_cat_array = NULL;
901 u32 *net_cat_array;
902 912
903 switch (doi_def->type) { 913 if (doi_def->type == CIPSO_V4_MAP_STD) {
904 case CIPSO_V4_MAP_PASS:
905 if (net_cat_len > host_cat_len)
906 return -EINVAL;
907 memcpy(host_cat, net_cat, net_cat_len);
908 return net_cat_len;
909 case CIPSO_V4_MAP_STD:
910 net_cat_size = doi_def->map.std->cat.cipso_size; 914 net_cat_size = doi_def->map.std->cat.cipso_size;
911 net_cat_array = doi_def->map.std->cat.cipso; 915 net_cat_array = doi_def->map.std->cat.cipso;
912 for (;;) { 916 }
913 net_spot = cipso_v4_bitmap_walk(net_cat,
914 net_clen_bits,
915 net_spot + 1,
916 1);
917 if (net_spot < 0)
918 break;
919 if (net_spot >= net_cat_size ||
920 net_cat_array[net_spot] >= CIPSO_V4_INV_CAT)
921 return -EPERM;
922 917
923 host_spot = net_cat_array[net_spot]; 918 for (;;) {
924 if (host_spot >= host_clen_bits) 919 net_spot = cipso_v4_bitmap_walk(net_cat,
925 return -ENOSPC; 920 net_clen_bits,
926 cipso_v4_bitmap_setbit(host_cat, host_spot, 1); 921 net_spot + 1,
922 1);
923 if (net_spot < 0) {
924 if (net_spot == -2)
925 return -EFAULT;
926 return 0;
927 }
927 928
928 if (host_spot > host_spot_max) 929 switch (doi_def->type) {
929 host_spot_max = host_spot; 930 case CIPSO_V4_MAP_PASS:
931 host_spot = net_spot;
932 break;
933 case CIPSO_V4_MAP_STD:
934 if (net_spot >= net_cat_size)
935 return -EPERM;
936 host_spot = net_cat_array[net_spot];
937 if (host_spot >= CIPSO_V4_INV_CAT)
938 return -EPERM;
939 break;
930 } 940 }
941 ret_val = netlbl_secattr_catmap_setbit(secattr->mls_cat,
942 host_spot,
943 GFP_ATOMIC);
944 if (ret_val != 0)
945 return ret_val;
946 }
947
948 return -EINVAL;
949}
950
951/**
952 * cipso_v4_map_cat_enum_valid - Checks to see if the categories are valid
953 * @doi_def: the DOI definition
954 * @enumcat: category list
955 * @enumcat_len: length of the category list in bytes
956 *
957 * Description:
958 * Checks the given categories against the given DOI definition and returns a
959 * negative value if any of the categories do not have a valid mapping and a
960 * zero value if all of the categories are valid.
961 *
962 */
963static int cipso_v4_map_cat_enum_valid(const struct cipso_v4_doi *doi_def,
964 const unsigned char *enumcat,
965 u32 enumcat_len)
966{
967 u16 cat;
968 int cat_prev = -1;
969 u32 iter;
970
971 if (doi_def->type != CIPSO_V4_MAP_PASS || enumcat_len & 0x01)
972 return -EFAULT;
973
974 for (iter = 0; iter < enumcat_len; iter += 2) {
975 cat = ntohs(*((__be16 *)&enumcat[iter]));
976 if (cat <= cat_prev)
977 return -EFAULT;
978 cat_prev = cat;
979 }
980
981 return 0;
982}
983
984/**
985 * cipso_v4_map_cat_enum_hton - Perform a category mapping from host to network
986 * @doi_def: the DOI definition
987 * @secattr: the security attributes
988 * @net_cat: the zero'd out category list in network/CIPSO format
989 * @net_cat_len: the length of the CIPSO category list in bytes
990 *
991 * Description:
992 * Perform a label mapping to translate a local MLS category bitmap to the
993 * correct CIPSO category list using the given DOI definition. Returns the
994 * size in bytes of the network category bitmap on success, negative values
995 * otherwise.
996 *
997 */
998static int cipso_v4_map_cat_enum_hton(const struct cipso_v4_doi *doi_def,
999 const struct netlbl_lsm_secattr *secattr,
1000 unsigned char *net_cat,
1001 u32 net_cat_len)
1002{
1003 int cat = -1;
1004 u32 cat_iter = 0;
1005
1006 for (;;) {
1007 cat = netlbl_secattr_catmap_walk(secattr->mls_cat, cat + 1);
1008 if (cat < 0)
1009 break;
1010 if ((cat_iter + 2) > net_cat_len)
1011 return -ENOSPC;
1012
1013 *((__be16 *)&net_cat[cat_iter]) = htons(cat);
1014 cat_iter += 2;
1015 }
1016
1017 return cat_iter;
1018}
1019
1020/**
1021 * cipso_v4_map_cat_enum_ntoh - Perform a category mapping from network to host
1022 * @doi_def: the DOI definition
1023 * @net_cat: the category list in network/CIPSO format
1024 * @net_cat_len: the length of the CIPSO bitmap in bytes
1025 * @secattr: the security attributes
1026 *
1027 * Description:
1028 * Perform a label mapping to translate a CIPSO category list to the correct
1029 * local MLS category bitmap using the given DOI definition. Returns zero on
1030 * success, negative values on failure.
1031 *
1032 */
1033static int cipso_v4_map_cat_enum_ntoh(const struct cipso_v4_doi *doi_def,
1034 const unsigned char *net_cat,
1035 u32 net_cat_len,
1036 struct netlbl_lsm_secattr *secattr)
1037{
1038 int ret_val;
1039 u32 iter;
1040
1041 for (iter = 0; iter < net_cat_len; iter += 2) {
1042 ret_val = netlbl_secattr_catmap_setbit(secattr->mls_cat,
1043 ntohs(*((__be16 *)&net_cat[iter])),
1044 GFP_ATOMIC);
1045 if (ret_val != 0)
1046 return ret_val;
1047 }
1048
1049 return 0;
1050}
1051
1052/**
1053 * cipso_v4_map_cat_rng_valid - Checks to see if the categories are valid
1054 * @doi_def: the DOI definition
1055 * @rngcat: category list
1056 * @rngcat_len: length of the category list in bytes
1057 *
1058 * Description:
1059 * Checks the given categories against the given DOI definition and returns a
1060 * negative value if any of the categories do not have a valid mapping and a
1061 * zero value if all of the categories are valid.
1062 *
1063 */
1064static int cipso_v4_map_cat_rng_valid(const struct cipso_v4_doi *doi_def,
1065 const unsigned char *rngcat,
1066 u32 rngcat_len)
1067{
1068 u16 cat_high;
1069 u16 cat_low;
1070 u32 cat_prev = CIPSO_V4_MAX_REM_CATS + 1;
1071 u32 iter;
931 1072
932 if (net_spot == -2) 1073 if (doi_def->type != CIPSO_V4_MAP_PASS || rngcat_len & 0x01)
1074 return -EFAULT;
1075
1076 for (iter = 0; iter < rngcat_len; iter += 4) {
1077 cat_high = ntohs(*((__be16 *)&rngcat[iter]));
1078 if ((iter + 4) <= rngcat_len)
1079 cat_low = ntohs(*((__be16 *)&rngcat[iter + 2]));
1080 else
1081 cat_low = 0;
1082
1083 if (cat_high > cat_prev)
933 return -EFAULT; 1084 return -EFAULT;
934 1085
935 if (++host_spot_max % 8) 1086 cat_prev = cat_low;
936 return host_spot_max / 8 + 1;
937 return host_spot_max / 8;
938 } 1087 }
939 1088
940 return -EINVAL; 1089 return 0;
1090}
1091
1092/**
1093 * cipso_v4_map_cat_rng_hton - Perform a category mapping from host to network
1094 * @doi_def: the DOI definition
1095 * @secattr: the security attributes
1096 * @net_cat: the zero'd out category list in network/CIPSO format
1097 * @net_cat_len: the length of the CIPSO category list in bytes
1098 *
1099 * Description:
1100 * Perform a label mapping to translate a local MLS category bitmap to the
1101 * correct CIPSO category list using the given DOI definition. Returns the
1102 * size in bytes of the network category bitmap on success, negative values
1103 * otherwise.
1104 *
1105 */
1106static int cipso_v4_map_cat_rng_hton(const struct cipso_v4_doi *doi_def,
1107 const struct netlbl_lsm_secattr *secattr,
1108 unsigned char *net_cat,
1109 u32 net_cat_len)
1110{
1111 /* The constant '16' is not random, it is the maximum number of
1112 * high/low category range pairs as permitted by the CIPSO draft based
1113 * on a maximum IPv4 header length of 60 bytes - the BUG_ON() assertion
1114 * does a sanity check to make sure we don't overflow the array. */
1115 int iter = -1;
1116 u16 array[16];
1117 u32 array_cnt = 0;
1118 u32 cat_size = 0;
1119
1120 BUG_ON(net_cat_len > 30);
1121
1122 for (;;) {
1123 iter = netlbl_secattr_catmap_walk(secattr->mls_cat, iter + 1);
1124 if (iter < 0)
1125 break;
1126 cat_size += (iter == 0 ? 0 : sizeof(u16));
1127 if (cat_size > net_cat_len)
1128 return -ENOSPC;
1129 array[array_cnt++] = iter;
1130
1131 iter = netlbl_secattr_catmap_walk_rng(secattr->mls_cat, iter);
1132 if (iter < 0)
1133 return -EFAULT;
1134 cat_size += sizeof(u16);
1135 if (cat_size > net_cat_len)
1136 return -ENOSPC;
1137 array[array_cnt++] = iter;
1138 }
1139
1140 for (iter = 0; array_cnt > 0;) {
1141 *((__be16 *)&net_cat[iter]) = htons(array[--array_cnt]);
1142 iter += 2;
1143 array_cnt--;
1144 if (array[array_cnt] != 0) {
1145 *((__be16 *)&net_cat[iter]) = htons(array[array_cnt]);
1146 iter += 2;
1147 }
1148 }
1149
1150 return cat_size;
1151}
1152
1153/**
1154 * cipso_v4_map_cat_rng_ntoh - Perform a category mapping from network to host
1155 * @doi_def: the DOI definition
1156 * @net_cat: the category list in network/CIPSO format
1157 * @net_cat_len: the length of the CIPSO bitmap in bytes
1158 * @secattr: the security attributes
1159 *
1160 * Description:
1161 * Perform a label mapping to translate a CIPSO category list to the correct
1162 * local MLS category bitmap using the given DOI definition. Returns zero on
1163 * success, negative values on failure.
1164 *
1165 */
1166static int cipso_v4_map_cat_rng_ntoh(const struct cipso_v4_doi *doi_def,
1167 const unsigned char *net_cat,
1168 u32 net_cat_len,
1169 struct netlbl_lsm_secattr *secattr)
1170{
1171 int ret_val;
1172 u32 net_iter;
1173 u16 cat_low;
1174 u16 cat_high;
1175
1176 for(net_iter = 0; net_iter < net_cat_len; net_iter += 4) {
1177 cat_high = ntohs(*((__be16 *)&net_cat[net_iter]));
1178 if ((net_iter + 4) <= net_cat_len)
1179 cat_low = ntohs(*((__be16 *)&net_cat[net_iter + 2]));
1180 else
1181 cat_low = 0;
1182
1183 ret_val = netlbl_secattr_catmap_setrng(secattr->mls_cat,
1184 cat_low,
1185 cat_high,
1186 GFP_ATOMIC);
1187 if (ret_val != 0)
1188 return ret_val;
1189 }
1190
1191 return 0;
941} 1192}
942 1193
943/* 1194/*
944 * Protocol Handling Functions 1195 * Protocol Handling Functions
945 */ 1196 */
946 1197
1198#define CIPSO_V4_OPT_LEN_MAX 40
947#define CIPSO_V4_HDR_LEN 6 1199#define CIPSO_V4_HDR_LEN 6
948 1200
949/** 1201/**
950 * cipso_v4_gentag_hdr - Generate a CIPSO option header 1202 * cipso_v4_gentag_hdr - Generate a CIPSO option header
951 * @doi_def: the DOI definition 1203 * @doi_def: the DOI definition
952 * @len: the total tag length in bytes 1204 * @len: the total tag length in bytes, not including this header
953 * @buf: the CIPSO option buffer 1205 * @buf: the CIPSO option buffer
954 * 1206 *
955 * Description: 1207 * Description:
956 * Write a CIPSO header into the beginning of @buffer. Return zero on success, 1208 * Write a CIPSO header into the beginning of @buffer.
957 * negative values on failure.
958 * 1209 *
959 */ 1210 */
960static int cipso_v4_gentag_hdr(const struct cipso_v4_doi *doi_def, 1211static void cipso_v4_gentag_hdr(const struct cipso_v4_doi *doi_def,
961 u32 len, 1212 unsigned char *buf,
962 unsigned char *buf) 1213 u32 len)
963{ 1214{
964 if (CIPSO_V4_HDR_LEN + len > 40)
965 return -ENOSPC;
966
967 buf[0] = IPOPT_CIPSO; 1215 buf[0] = IPOPT_CIPSO;
968 buf[1] = CIPSO_V4_HDR_LEN + len; 1216 buf[1] = CIPSO_V4_HDR_LEN + len;
969 *(u32 *)&buf[2] = htonl(doi_def->doi); 1217 *(__be32 *)&buf[2] = htonl(doi_def->doi);
970
971 return 0;
972} 1218}
973 1219
974#define CIPSO_V4_TAG1_CAT_LEN 30
975
976/** 1220/**
977 * cipso_v4_gentag_rbm - Generate a CIPSO restricted bitmap tag (type #1) 1221 * cipso_v4_gentag_rbm - Generate a CIPSO restricted bitmap tag (type #1)
978 * @doi_def: the DOI definition 1222 * @doi_def: the DOI definition
@@ -983,83 +1227,249 @@ static int cipso_v4_gentag_hdr(const struct cipso_v4_doi *doi_def,
983 * Description: 1227 * Description:
984 * Generate a CIPSO option using the restricted bitmap tag, tag type #1. The 1228 * Generate a CIPSO option using the restricted bitmap tag, tag type #1. The
985 * actual buffer length may be larger than the indicated size due to 1229 * actual buffer length may be larger than the indicated size due to
986 * translation between host and network category bitmaps. Returns zero on 1230 * translation between host and network category bitmaps. Returns the size of
987 * success, negative values on failure. 1231 * the tag on success, negative values on failure.
988 * 1232 *
989 */ 1233 */
990static int cipso_v4_gentag_rbm(const struct cipso_v4_doi *doi_def, 1234static int cipso_v4_gentag_rbm(const struct cipso_v4_doi *doi_def,
991 const struct netlbl_lsm_secattr *secattr, 1235 const struct netlbl_lsm_secattr *secattr,
992 unsigned char **buffer, 1236 unsigned char *buffer,
993 u32 *buffer_len) 1237 u32 buffer_len)
994{ 1238{
995 int ret_val = -EPERM; 1239 int ret_val;
996 unsigned char *buf = NULL; 1240 u32 tag_len;
997 u32 buf_len;
998 u32 level; 1241 u32 level;
999 1242
1000 if (secattr->mls_cat) { 1243 if ((secattr->flags & NETLBL_SECATTR_MLS_LVL) == 0)
1001 buf = kzalloc(CIPSO_V4_HDR_LEN + 4 + CIPSO_V4_TAG1_CAT_LEN, 1244 return -EPERM;
1002 GFP_ATOMIC); 1245
1003 if (buf == NULL) 1246 ret_val = cipso_v4_map_lvl_hton(doi_def, secattr->mls_lvl, &level);
1004 return -ENOMEM; 1247 if (ret_val != 0)
1248 return ret_val;
1005 1249
1250 if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
1006 ret_val = cipso_v4_map_cat_rbm_hton(doi_def, 1251 ret_val = cipso_v4_map_cat_rbm_hton(doi_def,
1007 secattr->mls_cat, 1252 secattr,
1008 secattr->mls_cat_len, 1253 &buffer[4],
1009 &buf[CIPSO_V4_HDR_LEN + 4], 1254 buffer_len - 4);
1010 CIPSO_V4_TAG1_CAT_LEN);
1011 if (ret_val < 0) 1255 if (ret_val < 0)
1012 goto gentag_failure; 1256 return ret_val;
1013 1257
1014 /* This will send packets using the "optimized" format when 1258 /* This will send packets using the "optimized" format when
1015 * possibile as specified in section 3.4.2.6 of the 1259 * possibile as specified in section 3.4.2.6 of the
1016 * CIPSO draft. */ 1260 * CIPSO draft. */
1017 if (cipso_v4_rbm_optfmt && (ret_val > 0 && ret_val < 10)) 1261 if (cipso_v4_rbm_optfmt && ret_val > 0 && ret_val <= 10)
1018 ret_val = 10; 1262 tag_len = 14;
1263 else
1264 tag_len = 4 + ret_val;
1265 } else
1266 tag_len = 4;
1267
1268 buffer[0] = 0x01;
1269 buffer[1] = tag_len;
1270 buffer[3] = level;
1271
1272 return tag_len;
1273}
1019 1274
1020 buf_len = 4 + ret_val; 1275/**
1021 } else { 1276 * cipso_v4_parsetag_rbm - Parse a CIPSO restricted bitmap tag
1022 buf = kzalloc(CIPSO_V4_HDR_LEN + 4, GFP_ATOMIC); 1277 * @doi_def: the DOI definition
1023 if (buf == NULL) 1278 * @tag: the CIPSO tag
1279 * @secattr: the security attributes
1280 *
1281 * Description:
1282 * Parse a CIPSO restricted bitmap tag (tag type #1) and return the security
1283 * attributes in @secattr. Return zero on success, negatives values on
1284 * failure.
1285 *
1286 */
1287static int cipso_v4_parsetag_rbm(const struct cipso_v4_doi *doi_def,
1288 const unsigned char *tag,
1289 struct netlbl_lsm_secattr *secattr)
1290{
1291 int ret_val;
1292 u8 tag_len = tag[1];
1293 u32 level;
1294
1295 ret_val = cipso_v4_map_lvl_ntoh(doi_def, tag[3], &level);
1296 if (ret_val != 0)
1297 return ret_val;
1298 secattr->mls_lvl = level;
1299 secattr->flags |= NETLBL_SECATTR_MLS_LVL;
1300
1301 if (tag_len > 4) {
1302 secattr->mls_cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
1303 if (secattr->mls_cat == NULL)
1024 return -ENOMEM; 1304 return -ENOMEM;
1025 buf_len = 4; 1305
1306 ret_val = cipso_v4_map_cat_rbm_ntoh(doi_def,
1307 &tag[4],
1308 tag_len - 4,
1309 secattr);
1310 if (ret_val != 0) {
1311 netlbl_secattr_catmap_free(secattr->mls_cat);
1312 return ret_val;
1313 }
1314
1315 secattr->flags |= NETLBL_SECATTR_MLS_CAT;
1026 } 1316 }
1027 1317
1318 return 0;
1319}
1320
1321/**
1322 * cipso_v4_gentag_enum - Generate a CIPSO enumerated tag (type #2)
1323 * @doi_def: the DOI definition
1324 * @secattr: the security attributes
1325 * @buffer: the option buffer
1326 * @buffer_len: length of buffer in bytes
1327 *
1328 * Description:
1329 * Generate a CIPSO option using the enumerated tag, tag type #2. Returns the
1330 * size of the tag on success, negative values on failure.
1331 *
1332 */
1333static int cipso_v4_gentag_enum(const struct cipso_v4_doi *doi_def,
1334 const struct netlbl_lsm_secattr *secattr,
1335 unsigned char *buffer,
1336 u32 buffer_len)
1337{
1338 int ret_val;
1339 u32 tag_len;
1340 u32 level;
1341
1342 if (!(secattr->flags & NETLBL_SECATTR_MLS_LVL))
1343 return -EPERM;
1344
1028 ret_val = cipso_v4_map_lvl_hton(doi_def, secattr->mls_lvl, &level); 1345 ret_val = cipso_v4_map_lvl_hton(doi_def, secattr->mls_lvl, &level);
1029 if (ret_val != 0) 1346 if (ret_val != 0)
1030 goto gentag_failure; 1347 return ret_val;
1348
1349 if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
1350 ret_val = cipso_v4_map_cat_enum_hton(doi_def,
1351 secattr,
1352 &buffer[4],
1353 buffer_len - 4);
1354 if (ret_val < 0)
1355 return ret_val;
1356
1357 tag_len = 4 + ret_val;
1358 } else
1359 tag_len = 4;
1360
1361 buffer[0] = 0x02;
1362 buffer[1] = tag_len;
1363 buffer[3] = level;
1031 1364
1032 ret_val = cipso_v4_gentag_hdr(doi_def, buf_len, buf); 1365 return tag_len;
1366}
1367
1368/**
1369 * cipso_v4_parsetag_enum - Parse a CIPSO enumerated tag
1370 * @doi_def: the DOI definition
1371 * @tag: the CIPSO tag
1372 * @secattr: the security attributes
1373 *
1374 * Description:
1375 * Parse a CIPSO enumerated tag (tag type #2) and return the security
1376 * attributes in @secattr. Return zero on success, negatives values on
1377 * failure.
1378 *
1379 */
1380static int cipso_v4_parsetag_enum(const struct cipso_v4_doi *doi_def,
1381 const unsigned char *tag,
1382 struct netlbl_lsm_secattr *secattr)
1383{
1384 int ret_val;
1385 u8 tag_len = tag[1];
1386 u32 level;
1387
1388 ret_val = cipso_v4_map_lvl_ntoh(doi_def, tag[3], &level);
1033 if (ret_val != 0) 1389 if (ret_val != 0)
1034 goto gentag_failure; 1390 return ret_val;
1391 secattr->mls_lvl = level;
1392 secattr->flags |= NETLBL_SECATTR_MLS_LVL;
1393
1394 if (tag_len > 4) {
1395 secattr->mls_cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
1396 if (secattr->mls_cat == NULL)
1397 return -ENOMEM;
1035 1398
1036 buf[CIPSO_V4_HDR_LEN] = 0x01; 1399 ret_val = cipso_v4_map_cat_enum_ntoh(doi_def,
1037 buf[CIPSO_V4_HDR_LEN + 1] = buf_len; 1400 &tag[4],
1038 buf[CIPSO_V4_HDR_LEN + 3] = level; 1401 tag_len - 4,
1402 secattr);
1403 if (ret_val != 0) {
1404 netlbl_secattr_catmap_free(secattr->mls_cat);
1405 return ret_val;
1406 }
1039 1407
1040 *buffer = buf; 1408 secattr->flags |= NETLBL_SECATTR_MLS_CAT;
1041 *buffer_len = CIPSO_V4_HDR_LEN + buf_len; 1409 }
1042 1410
1043 return 0; 1411 return 0;
1412}
1044 1413
1045gentag_failure: 1414/**
1046 kfree(buf); 1415 * cipso_v4_gentag_rng - Generate a CIPSO ranged tag (type #5)
1047 return ret_val; 1416 * @doi_def: the DOI definition
1417 * @secattr: the security attributes
1418 * @buffer: the option buffer
1419 * @buffer_len: length of buffer in bytes
1420 *
1421 * Description:
1422 * Generate a CIPSO option using the ranged tag, tag type #5. Returns the
1423 * size of the tag on success, negative values on failure.
1424 *
1425 */
1426static int cipso_v4_gentag_rng(const struct cipso_v4_doi *doi_def,
1427 const struct netlbl_lsm_secattr *secattr,
1428 unsigned char *buffer,
1429 u32 buffer_len)
1430{
1431 int ret_val;
1432 u32 tag_len;
1433 u32 level;
1434
1435 if (!(secattr->flags & NETLBL_SECATTR_MLS_LVL))
1436 return -EPERM;
1437
1438 ret_val = cipso_v4_map_lvl_hton(doi_def, secattr->mls_lvl, &level);
1439 if (ret_val != 0)
1440 return ret_val;
1441
1442 if (secattr->flags & NETLBL_SECATTR_MLS_CAT) {
1443 ret_val = cipso_v4_map_cat_rng_hton(doi_def,
1444 secattr,
1445 &buffer[4],
1446 buffer_len - 4);
1447 if (ret_val < 0)
1448 return ret_val;
1449
1450 tag_len = 4 + ret_val;
1451 } else
1452 tag_len = 4;
1453
1454 buffer[0] = 0x05;
1455 buffer[1] = tag_len;
1456 buffer[3] = level;
1457
1458 return tag_len;
1048} 1459}
1049 1460
1050/** 1461/**
1051 * cipso_v4_parsetag_rbm - Parse a CIPSO restricted bitmap tag 1462 * cipso_v4_parsetag_rng - Parse a CIPSO ranged tag
1052 * @doi_def: the DOI definition 1463 * @doi_def: the DOI definition
1053 * @tag: the CIPSO tag 1464 * @tag: the CIPSO tag
1054 * @secattr: the security attributes 1465 * @secattr: the security attributes
1055 * 1466 *
1056 * Description: 1467 * Description:
1057 * Parse a CIPSO restricted bitmap tag (tag type #1) and return the security 1468 * Parse a CIPSO ranged tag (tag type #5) and return the security attributes
1058 * attributes in @secattr. Return zero on success, negatives values on 1469 * in @secattr. Return zero on success, negatives values on failure.
1059 * failure.
1060 * 1470 *
1061 */ 1471 */
1062static int cipso_v4_parsetag_rbm(const struct cipso_v4_doi *doi_def, 1472static int cipso_v4_parsetag_rng(const struct cipso_v4_doi *doi_def,
1063 const unsigned char *tag, 1473 const unsigned char *tag,
1064 struct netlbl_lsm_secattr *secattr) 1474 struct netlbl_lsm_secattr *secattr)
1065{ 1475{
@@ -1071,32 +1481,23 @@ static int cipso_v4_parsetag_rbm(const struct cipso_v4_doi *doi_def,
1071 if (ret_val != 0) 1481 if (ret_val != 0)
1072 return ret_val; 1482 return ret_val;
1073 secattr->mls_lvl = level; 1483 secattr->mls_lvl = level;
1074 secattr->mls_lvl_vld = 1; 1484 secattr->flags |= NETLBL_SECATTR_MLS_LVL;
1075 1485
1076 if (tag_len > 4) { 1486 if (tag_len > 4) {
1077 switch (doi_def->type) { 1487 secattr->mls_cat = netlbl_secattr_catmap_alloc(GFP_ATOMIC);
1078 case CIPSO_V4_MAP_PASS:
1079 secattr->mls_cat_len = tag_len - 4;
1080 break;
1081 case CIPSO_V4_MAP_STD:
1082 secattr->mls_cat_len =
1083 doi_def->map.std->cat.local_size;
1084 break;
1085 }
1086 secattr->mls_cat = kzalloc(secattr->mls_cat_len, GFP_ATOMIC);
1087 if (secattr->mls_cat == NULL) 1488 if (secattr->mls_cat == NULL)
1088 return -ENOMEM; 1489 return -ENOMEM;
1089 1490
1090 ret_val = cipso_v4_map_cat_rbm_ntoh(doi_def, 1491 ret_val = cipso_v4_map_cat_rng_ntoh(doi_def,
1091 &tag[4], 1492 &tag[4],
1092 tag_len - 4, 1493 tag_len - 4,
1093 secattr->mls_cat, 1494 secattr);
1094 secattr->mls_cat_len); 1495 if (ret_val != 0) {
1095 if (ret_val < 0) { 1496 netlbl_secattr_catmap_free(secattr->mls_cat);
1096 kfree(secattr->mls_cat);
1097 return ret_val; 1497 return ret_val;
1098 } 1498 }
1099 secattr->mls_cat_len = ret_val; 1499
1500 secattr->flags |= NETLBL_SECATTR_MLS_CAT;
1100 } 1501 }
1101 1502
1102 return 0; 1503 return 0;
@@ -1140,7 +1541,7 @@ int cipso_v4_validate(unsigned char **option)
1140 } 1541 }
1141 1542
1142 rcu_read_lock(); 1543 rcu_read_lock();
1143 doi_def = cipso_v4_doi_getdef(ntohl(*((u32 *)&opt[2]))); 1544 doi_def = cipso_v4_doi_search(ntohl(*((__be32 *)&opt[2])));
1144 if (doi_def == NULL) { 1545 if (doi_def == NULL) {
1145 err_offset = 2; 1546 err_offset = 2;
1146 goto validate_return_locked; 1547 goto validate_return_locked;
@@ -1191,6 +1592,44 @@ int cipso_v4_validate(unsigned char **option)
1191 } 1592 }
1192 } 1593 }
1193 break; 1594 break;
1595 case CIPSO_V4_TAG_ENUM:
1596 if (tag_len < 4) {
1597 err_offset = opt_iter + 1;
1598 goto validate_return_locked;
1599 }
1600
1601 if (cipso_v4_map_lvl_valid(doi_def,
1602 tag[3]) < 0) {
1603 err_offset = opt_iter + 3;
1604 goto validate_return_locked;
1605 }
1606 if (tag_len > 4 &&
1607 cipso_v4_map_cat_enum_valid(doi_def,
1608 &tag[4],
1609 tag_len - 4) < 0) {
1610 err_offset = opt_iter + 4;
1611 goto validate_return_locked;
1612 }
1613 break;
1614 case CIPSO_V4_TAG_RANGE:
1615 if (tag_len < 4) {
1616 err_offset = opt_iter + 1;
1617 goto validate_return_locked;
1618 }
1619
1620 if (cipso_v4_map_lvl_valid(doi_def,
1621 tag[3]) < 0) {
1622 err_offset = opt_iter + 3;
1623 goto validate_return_locked;
1624 }
1625 if (tag_len > 4 &&
1626 cipso_v4_map_cat_rng_valid(doi_def,
1627 &tag[4],
1628 tag_len - 4) < 0) {
1629 err_offset = opt_iter + 4;
1630 goto validate_return_locked;
1631 }
1632 break;
1194 default: 1633 default:
1195 err_offset = opt_iter; 1634 err_offset = opt_iter;
1196 goto validate_return_locked; 1635 goto validate_return_locked;
@@ -1265,7 +1704,7 @@ int cipso_v4_socket_setattr(const struct socket *sock,
1265{ 1704{
1266 int ret_val = -EPERM; 1705 int ret_val = -EPERM;
1267 u32 iter; 1706 u32 iter;
1268 unsigned char *buf = NULL; 1707 unsigned char *buf;
1269 u32 buf_len = 0; 1708 u32 buf_len = 0;
1270 u32 opt_len; 1709 u32 opt_len;
1271 struct ip_options *opt = NULL; 1710 struct ip_options *opt = NULL;
@@ -1281,17 +1720,40 @@ int cipso_v4_socket_setattr(const struct socket *sock,
1281 if (sk == NULL) 1720 if (sk == NULL)
1282 return 0; 1721 return 0;
1283 1722
1723 /* We allocate the maximum CIPSO option size here so we are probably
1724 * being a little wasteful, but it makes our life _much_ easier later
1725 * on and after all we are only talking about 40 bytes. */
1726 buf_len = CIPSO_V4_OPT_LEN_MAX;
1727 buf = kmalloc(buf_len, GFP_ATOMIC);
1728 if (buf == NULL) {
1729 ret_val = -ENOMEM;
1730 goto socket_setattr_failure;
1731 }
1732
1284 /* XXX - This code assumes only one tag per CIPSO option which isn't 1733 /* XXX - This code assumes only one tag per CIPSO option which isn't
1285 * really a good assumption to make but since we only support the MAC 1734 * really a good assumption to make but since we only support the MAC
1286 * tags right now it is a safe assumption. */ 1735 * tags right now it is a safe assumption. */
1287 iter = 0; 1736 iter = 0;
1288 do { 1737 do {
1738 memset(buf, 0, buf_len);
1289 switch (doi_def->tags[iter]) { 1739 switch (doi_def->tags[iter]) {
1290 case CIPSO_V4_TAG_RBITMAP: 1740 case CIPSO_V4_TAG_RBITMAP:
1291 ret_val = cipso_v4_gentag_rbm(doi_def, 1741 ret_val = cipso_v4_gentag_rbm(doi_def,
1292 secattr, 1742 secattr,
1293 &buf, 1743 &buf[CIPSO_V4_HDR_LEN],
1294 &buf_len); 1744 buf_len - CIPSO_V4_HDR_LEN);
1745 break;
1746 case CIPSO_V4_TAG_ENUM:
1747 ret_val = cipso_v4_gentag_enum(doi_def,
1748 secattr,
1749 &buf[CIPSO_V4_HDR_LEN],
1750 buf_len - CIPSO_V4_HDR_LEN);
1751 break;
1752 case CIPSO_V4_TAG_RANGE:
1753 ret_val = cipso_v4_gentag_rng(doi_def,
1754 secattr,
1755 &buf[CIPSO_V4_HDR_LEN],
1756 buf_len - CIPSO_V4_HDR_LEN);
1295 break; 1757 break;
1296 default: 1758 default:
1297 ret_val = -EPERM; 1759 ret_val = -EPERM;
@@ -1299,11 +1761,13 @@ int cipso_v4_socket_setattr(const struct socket *sock,
1299 } 1761 }
1300 1762
1301 iter++; 1763 iter++;
1302 } while (ret_val != 0 && 1764 } while (ret_val < 0 &&
1303 iter < CIPSO_V4_TAG_MAXCNT && 1765 iter < CIPSO_V4_TAG_MAXCNT &&
1304 doi_def->tags[iter] != CIPSO_V4_TAG_INVALID); 1766 doi_def->tags[iter] != CIPSO_V4_TAG_INVALID);
1305 if (ret_val != 0) 1767 if (ret_val < 0)
1306 goto socket_setattr_failure; 1768 goto socket_setattr_failure;
1769 cipso_v4_gentag_hdr(doi_def, buf, ret_val);
1770 buf_len = CIPSO_V4_HDR_LEN + ret_val;
1307 1771
1308 /* We can't use ip_options_get() directly because it makes a call to 1772 /* We can't use ip_options_get() directly because it makes a call to
1309 * ip_options_get_alloc() which allocates memory with GFP_KERNEL and 1773 * ip_options_get_alloc() which allocates memory with GFP_KERNEL and
@@ -1370,19 +1834,33 @@ int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
1370 if (ret_val == 0) 1834 if (ret_val == 0)
1371 return ret_val; 1835 return ret_val;
1372 1836
1373 doi = ntohl(*(u32 *)&cipso_ptr[2]); 1837 doi = ntohl(*(__be32 *)&cipso_ptr[2]);
1374 rcu_read_lock(); 1838 rcu_read_lock();
1375 doi_def = cipso_v4_doi_getdef(doi); 1839 doi_def = cipso_v4_doi_search(doi);
1376 if (doi_def == NULL) { 1840 if (doi_def == NULL) {
1377 rcu_read_unlock(); 1841 rcu_read_unlock();
1378 return -ENOMSG; 1842 return -ENOMSG;
1379 } 1843 }
1844
1845 /* XXX - This code assumes only one tag per CIPSO option which isn't
1846 * really a good assumption to make but since we only support the MAC
1847 * tags right now it is a safe assumption. */
1380 switch (cipso_ptr[6]) { 1848 switch (cipso_ptr[6]) {
1381 case CIPSO_V4_TAG_RBITMAP: 1849 case CIPSO_V4_TAG_RBITMAP:
1382 ret_val = cipso_v4_parsetag_rbm(doi_def, 1850 ret_val = cipso_v4_parsetag_rbm(doi_def,
1383 &cipso_ptr[6], 1851 &cipso_ptr[6],
1384 secattr); 1852 secattr);
1385 break; 1853 break;
1854 case CIPSO_V4_TAG_ENUM:
1855 ret_val = cipso_v4_parsetag_enum(doi_def,
1856 &cipso_ptr[6],
1857 secattr);
1858 break;
1859 case CIPSO_V4_TAG_RANGE:
1860 ret_val = cipso_v4_parsetag_rng(doi_def,
1861 &cipso_ptr[6],
1862 secattr);
1863 break;
1386 } 1864 }
1387 rcu_read_unlock(); 1865 rcu_read_unlock();
1388 1866
@@ -1430,23 +1908,30 @@ int cipso_v4_skbuff_getattr(const struct sk_buff *skb,
1430 u32 doi; 1908 u32 doi;
1431 struct cipso_v4_doi *doi_def; 1909 struct cipso_v4_doi *doi_def;
1432 1910
1433 if (!CIPSO_V4_OPTEXIST(skb))
1434 return -ENOMSG;
1435 cipso_ptr = CIPSO_V4_OPTPTR(skb); 1911 cipso_ptr = CIPSO_V4_OPTPTR(skb);
1436 if (cipso_v4_cache_check(cipso_ptr, cipso_ptr[1], secattr) == 0) 1912 if (cipso_v4_cache_check(cipso_ptr, cipso_ptr[1], secattr) == 0)
1437 return 0; 1913 return 0;
1438 1914
1439 doi = ntohl(*(u32 *)&cipso_ptr[2]); 1915 doi = ntohl(*(__be32 *)&cipso_ptr[2]);
1440 rcu_read_lock(); 1916 rcu_read_lock();
1441 doi_def = cipso_v4_doi_getdef(doi); 1917 doi_def = cipso_v4_doi_search(doi);
1442 if (doi_def == NULL) 1918 if (doi_def == NULL)
1443 goto skbuff_getattr_return; 1919 goto skbuff_getattr_return;
1920
1921 /* XXX - This code assumes only one tag per CIPSO option which isn't
1922 * really a good assumption to make but since we only support the MAC
1923 * tags right now it is a safe assumption. */
1444 switch (cipso_ptr[6]) { 1924 switch (cipso_ptr[6]) {
1445 case CIPSO_V4_TAG_RBITMAP: 1925 case CIPSO_V4_TAG_RBITMAP:
1446 ret_val = cipso_v4_parsetag_rbm(doi_def, 1926 ret_val = cipso_v4_parsetag_rbm(doi_def,
1447 &cipso_ptr[6], 1927 &cipso_ptr[6],
1448 secattr); 1928 secattr);
1449 break; 1929 break;
1930 case CIPSO_V4_TAG_ENUM:
1931 ret_val = cipso_v4_parsetag_enum(doi_def,
1932 &cipso_ptr[6],
1933 secattr);
1934 break;
1450 } 1935 }
1451 1936
1452skbuff_getattr_return: 1937skbuff_getattr_return:
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 7602c79a38..480ace9819 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -165,9 +165,8 @@ struct in_device *inetdev_init(struct net_device *dev)
165 NET_IPV4_NEIGH, "ipv4", NULL, NULL); 165 NET_IPV4_NEIGH, "ipv4", NULL, NULL);
166#endif 166#endif
167 167
168 /* Account for reference dev->ip_ptr */ 168 /* Account for reference dev->ip_ptr (below) */
169 in_dev_hold(in_dev); 169 in_dev_hold(in_dev);
170 rcu_assign_pointer(dev->ip_ptr, in_dev);
171 170
172#ifdef CONFIG_SYSCTL 171#ifdef CONFIG_SYSCTL
173 devinet_sysctl_register(in_dev, &in_dev->cnf); 172 devinet_sysctl_register(in_dev, &in_dev->cnf);
@@ -175,6 +174,9 @@ struct in_device *inetdev_init(struct net_device *dev)
175 ip_mc_init_dev(in_dev); 174 ip_mc_init_dev(in_dev);
176 if (dev->flags & IFF_UP) 175 if (dev->flags & IFF_UP)
177 ip_mc_up(in_dev); 176 ip_mc_up(in_dev);
177
178 /* we can receive as soon as ip_ptr is set -- do this last */
179 rcu_assign_pointer(dev->ip_ptr, in_dev);
178out: 180out:
179 return in_dev; 181 return in_dev;
180out_kfree: 182out_kfree:
@@ -577,20 +579,20 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg
577 * Determine a default network mask, based on the IP address. 579 * Determine a default network mask, based on the IP address.
578 */ 580 */
579 581
580static __inline__ int inet_abc_len(u32 addr) 582static __inline__ int inet_abc_len(__be32 addr)
581{ 583{
582 int rc = -1; /* Something else, probably a multicast. */ 584 int rc = -1; /* Something else, probably a multicast. */
583 585
584 if (ZERONET(addr)) 586 if (ZERONET(addr))
585 rc = 0; 587 rc = 0;
586 else { 588 else {
587 addr = ntohl(addr); 589 __u32 haddr = ntohl(addr);
588 590
589 if (IN_CLASSA(addr)) 591 if (IN_CLASSA(haddr))
590 rc = 8; 592 rc = 8;
591 else if (IN_CLASSB(addr)) 593 else if (IN_CLASSB(haddr))
592 rc = 16; 594 rc = 16;
593 else if (IN_CLASSC(addr)) 595 else if (IN_CLASSC(haddr))
594 rc = 24; 596 rc = 24;
595 } 597 }
596 598
@@ -1120,6 +1122,16 @@ static struct notifier_block ip_netdev_notifier = {
1120 .notifier_call =inetdev_event, 1122 .notifier_call =inetdev_event,
1121}; 1123};
1122 1124
1125static inline size_t inet_nlmsg_size(void)
1126{
1127 return NLMSG_ALIGN(sizeof(struct ifaddrmsg))
1128 + nla_total_size(4) /* IFA_ADDRESS */
1129 + nla_total_size(4) /* IFA_LOCAL */
1130 + nla_total_size(4) /* IFA_BROADCAST */
1131 + nla_total_size(4) /* IFA_ANYCAST */
1132 + nla_total_size(IFNAMSIZ); /* IFA_LABEL */
1133}
1134
1123static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa, 1135static int inet_fill_ifaddr(struct sk_buff *skb, struct in_ifaddr *ifa,
1124 u32 pid, u32 seq, int event, unsigned int flags) 1136 u32 pid, u32 seq, int event, unsigned int flags)
1125{ 1137{
@@ -1208,15 +1220,13 @@ static void rtmsg_ifa(int event, struct in_ifaddr* ifa, struct nlmsghdr *nlh,
1208 u32 seq = nlh ? nlh->nlmsg_seq : 0; 1220 u32 seq = nlh ? nlh->nlmsg_seq : 0;
1209 int err = -ENOBUFS; 1221 int err = -ENOBUFS;
1210 1222
1211 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 1223 skb = nlmsg_new(inet_nlmsg_size(), GFP_KERNEL);
1212 if (skb == NULL) 1224 if (skb == NULL)
1213 goto errout; 1225 goto errout;
1214 1226
1215 err = inet_fill_ifaddr(skb, ifa, pid, seq, event, 0); 1227 err = inet_fill_ifaddr(skb, ifa, pid, seq, event, 0);
1216 if (err < 0) { 1228 /* failure implies BUG in inet_nlmsg_size() */
1217 kfree_skb(skb); 1229 BUG_ON(err < 0);
1218 goto errout;
1219 }
1220 1230
1221 err = rtnl_notify(skb, pid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL); 1231 err = rtnl_notify(skb, pid, RTNLGRP_IPV4_IFADDR, nlh, GFP_KERNEL);
1222errout: 1232errout:
@@ -1295,8 +1305,7 @@ int ipv4_doint_and_flush(ctl_table *ctl, int write,
1295 1305
1296int ipv4_doint_and_flush_strategy(ctl_table *table, int __user *name, int nlen, 1306int ipv4_doint_and_flush_strategy(ctl_table *table, int __user *name, int nlen,
1297 void __user *oldval, size_t __user *oldlenp, 1307 void __user *oldval, size_t __user *oldlenp,
1298 void __user *newval, size_t newlen, 1308 void __user *newval, size_t newlen)
1299 void **context)
1300{ 1309{
1301 int *valp = table->data; 1310 int *valp = table->data;
1302 int new; 1311 int new;
@@ -1556,12 +1565,12 @@ static void devinet_sysctl_register(struct in_device *in_dev,
1556{ 1565{
1557 int i; 1566 int i;
1558 struct net_device *dev = in_dev ? in_dev->dev : NULL; 1567 struct net_device *dev = in_dev ? in_dev->dev : NULL;
1559 struct devinet_sysctl_table *t = kmalloc(sizeof(*t), GFP_KERNEL); 1568 struct devinet_sysctl_table *t = kmemdup(&devinet_sysctl, sizeof(*t),
1569 GFP_KERNEL);
1560 char *dev_name = NULL; 1570 char *dev_name = NULL;
1561 1571
1562 if (!t) 1572 if (!t)
1563 return; 1573 return;
1564 memcpy(t, &devinet_sysctl, sizeof(*t));
1565 for (i = 0; i < ARRAY_SIZE(t->devinet_vars) - 1; i++) { 1574 for (i = 0; i < ARRAY_SIZE(t->devinet_vars) - 1; i++) {
1566 t->devinet_vars[i].data += (char *)p - (char *)&ipv4_devconf; 1575 t->devinet_vars[i].data += (char *)p - (char *)&ipv4_devconf;
1567 t->devinet_vars[i].de = NULL; 1576 t->devinet_vars[i].de = NULL;
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index b5c205b576..f2c6776ea0 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -67,7 +67,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
67 if (x->encap) { 67 if (x->encap) {
68 struct xfrm_encap_tmpl *encap = x->encap; 68 struct xfrm_encap_tmpl *encap = x->encap;
69 struct udphdr *uh; 69 struct udphdr *uh;
70 u32 *udpdata32; 70 __be32 *udpdata32;
71 71
72 uh = (struct udphdr *)esph; 72 uh = (struct udphdr *)esph;
73 uh->source = encap->encap_sport; 73 uh->source = encap->encap_sport;
@@ -81,7 +81,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
81 esph = (struct ip_esp_hdr *)(uh + 1); 81 esph = (struct ip_esp_hdr *)(uh + 1);
82 break; 82 break;
83 case UDP_ENCAP_ESPINUDP_NON_IKE: 83 case UDP_ENCAP_ESPINUDP_NON_IKE:
84 udpdata32 = (u32 *)(uh + 1); 84 udpdata32 = (__be32 *)(uh + 1);
85 udpdata32[0] = udpdata32[1] = 0; 85 udpdata32[0] = udpdata32[1] = 0;
86 esph = (struct ip_esp_hdr *)(udpdata32 + 2); 86 esph = (struct ip_esp_hdr *)(udpdata32 + 2);
87 break; 87 break;
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index af0190d8b6..d47b72af89 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -768,8 +768,8 @@ static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb )
768{ 768{
769 769
770 struct fib_result res; 770 struct fib_result res;
771 struct flowi fl = { .nl_u = { .ip4_u = { .daddr = frn->fl_addr, 771 struct flowi fl = { .mark = frn->fl_mark,
772 .fwmark = frn->fl_fwmark, 772 .nl_u = { .ip4_u = { .daddr = frn->fl_addr,
773 .tos = frn->fl_tos, 773 .tos = frn->fl_tos,
774 .scope = frn->fl_scope } } }; 774 .scope = frn->fl_scope } } };
775 if (tb) { 775 if (tb) {
@@ -811,7 +811,6 @@ static void nl_fib_input(struct sock *sk, int len)
811 811
812 pid = nlh->nlmsg_pid; /*pid of sending process */ 812 pid = nlh->nlmsg_pid; /*pid of sending process */
813 NETLINK_CB(skb).pid = 0; /* from kernel */ 813 NETLINK_CB(skb).pid = 0; /* from kernel */
814 NETLINK_CB(skb).dst_pid = pid;
815 NETLINK_CB(skb).dst_group = 0; /* unicast */ 814 NETLINK_CB(skb).dst_group = 0; /* unicast */
816 netlink_unicast(sk, skb, pid, MSG_DONTWAIT); 815 netlink_unicast(sk, skb, pid, MSG_DONTWAIT);
817} 816}
diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c
index 107bb6cbb0..648f47c1c3 100644
--- a/net/ipv4/fib_hash.c
+++ b/net/ipv4/fib_hash.c
@@ -45,8 +45,8 @@
45 45
46#include "fib_lookup.h" 46#include "fib_lookup.h"
47 47
48static kmem_cache_t *fn_hash_kmem __read_mostly; 48static struct kmem_cache *fn_hash_kmem __read_mostly;
49static kmem_cache_t *fn_alias_kmem __read_mostly; 49static struct kmem_cache *fn_alias_kmem __read_mostly;
50 50
51struct fib_node { 51struct fib_node {
52 struct hlist_node fn_hash; 52 struct hlist_node fn_hash;
@@ -485,13 +485,13 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg)
485 goto out; 485 goto out;
486 486
487 err = -ENOBUFS; 487 err = -ENOBUFS;
488 new_fa = kmem_cache_alloc(fn_alias_kmem, SLAB_KERNEL); 488 new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL);
489 if (new_fa == NULL) 489 if (new_fa == NULL)
490 goto out; 490 goto out;
491 491
492 new_f = NULL; 492 new_f = NULL;
493 if (!f) { 493 if (!f) {
494 new_f = kmem_cache_alloc(fn_hash_kmem, SLAB_KERNEL); 494 new_f = kmem_cache_alloc(fn_hash_kmem, GFP_KERNEL);
495 if (new_f == NULL) 495 if (new_f == NULL)
496 goto out_free_new_fa; 496 goto out_free_new_fa;
497 497
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index 0852b9cd06..b837c33e04 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -44,10 +44,6 @@ struct fib4_rule
44 __be32 srcmask; 44 __be32 srcmask;
45 __be32 dst; 45 __be32 dst;
46 __be32 dstmask; 46 __be32 dstmask;
47#ifdef CONFIG_IP_ROUTE_FWMARK
48 u32 fwmark;
49 u32 fwmask;
50#endif
51#ifdef CONFIG_NET_CLS_ROUTE 47#ifdef CONFIG_NET_CLS_ROUTE
52 u32 tclassid; 48 u32 tclassid;
53#endif 49#endif
@@ -160,11 +156,6 @@ static int fib4_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
160 if (r->tos && (r->tos != fl->fl4_tos)) 156 if (r->tos && (r->tos != fl->fl4_tos))
161 return 0; 157 return 0;
162 158
163#ifdef CONFIG_IP_ROUTE_FWMARK
164 if ((r->fwmark ^ fl->fl4_fwmark) & r->fwmask)
165 return 0;
166#endif
167
168 return 1; 159 return 1;
169} 160}
170 161
@@ -179,14 +170,10 @@ static struct fib_table *fib_empty_table(void)
179} 170}
180 171
181static struct nla_policy fib4_rule_policy[FRA_MAX+1] __read_mostly = { 172static struct nla_policy fib4_rule_policy[FRA_MAX+1] __read_mostly = {
182 [FRA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, 173 FRA_GENERIC_POLICY,
183 [FRA_PRIORITY] = { .type = NLA_U32 },
184 [FRA_SRC] = { .type = NLA_U32 }, 174 [FRA_SRC] = { .type = NLA_U32 },
185 [FRA_DST] = { .type = NLA_U32 }, 175 [FRA_DST] = { .type = NLA_U32 },
186 [FRA_FWMARK] = { .type = NLA_U32 },
187 [FRA_FWMASK] = { .type = NLA_U32 },
188 [FRA_FLOW] = { .type = NLA_U32 }, 176 [FRA_FLOW] = { .type = NLA_U32 },
189 [FRA_TABLE] = { .type = NLA_U32 },
190}; 177};
191 178
192static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb, 179static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
@@ -220,20 +207,6 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
220 if (tb[FRA_DST]) 207 if (tb[FRA_DST])
221 rule4->dst = nla_get_be32(tb[FRA_DST]); 208 rule4->dst = nla_get_be32(tb[FRA_DST]);
222 209
223#ifdef CONFIG_IP_ROUTE_FWMARK
224 if (tb[FRA_FWMARK]) {
225 rule4->fwmark = nla_get_u32(tb[FRA_FWMARK]);
226 if (rule4->fwmark)
227 /* compatibility: if the mark value is non-zero all bits
228 * are compared unless a mask is explicitly specified.
229 */
230 rule4->fwmask = 0xFFFFFFFF;
231 }
232
233 if (tb[FRA_FWMASK])
234 rule4->fwmask = nla_get_u32(tb[FRA_FWMASK]);
235#endif
236
237#ifdef CONFIG_NET_CLS_ROUTE 210#ifdef CONFIG_NET_CLS_ROUTE
238 if (tb[FRA_FLOW]) 211 if (tb[FRA_FLOW])
239 rule4->tclassid = nla_get_u32(tb[FRA_FLOW]); 212 rule4->tclassid = nla_get_u32(tb[FRA_FLOW]);
@@ -264,14 +237,6 @@ static int fib4_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
264 if (frh->tos && (rule4->tos != frh->tos)) 237 if (frh->tos && (rule4->tos != frh->tos))
265 return 0; 238 return 0;
266 239
267#ifdef CONFIG_IP_ROUTE_FWMARK
268 if (tb[FRA_FWMARK] && (rule4->fwmark != nla_get_u32(tb[FRA_FWMARK])))
269 return 0;
270
271 if (tb[FRA_FWMASK] && (rule4->fwmask != nla_get_u32(tb[FRA_FWMASK])))
272 return 0;
273#endif
274
275#ifdef CONFIG_NET_CLS_ROUTE 240#ifdef CONFIG_NET_CLS_ROUTE
276 if (tb[FRA_FLOW] && (rule4->tclassid != nla_get_u32(tb[FRA_FLOW]))) 241 if (tb[FRA_FLOW] && (rule4->tclassid != nla_get_u32(tb[FRA_FLOW])))
277 return 0; 242 return 0;
@@ -296,14 +261,6 @@ static int fib4_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
296 frh->src_len = rule4->src_len; 261 frh->src_len = rule4->src_len;
297 frh->tos = rule4->tos; 262 frh->tos = rule4->tos;
298 263
299#ifdef CONFIG_IP_ROUTE_FWMARK
300 if (rule4->fwmark)
301 NLA_PUT_U32(skb, FRA_FWMARK, rule4->fwmark);
302
303 if (rule4->fwmask || rule4->fwmark)
304 NLA_PUT_U32(skb, FRA_FWMASK, rule4->fwmask);
305#endif
306
307 if (rule4->dst_len) 264 if (rule4->dst_len)
308 NLA_PUT_BE32(skb, FRA_DST, rule4->dst); 265 NLA_PUT_BE32(skb, FRA_DST, rule4->dst);
309 266
@@ -342,6 +299,13 @@ static u32 fib4_rule_default_pref(void)
342 return 0; 299 return 0;
343} 300}
344 301
302static size_t fib4_rule_nlmsg_payload(struct fib_rule *rule)
303{
304 return nla_total_size(4) /* dst */
305 + nla_total_size(4) /* src */
306 + nla_total_size(4); /* flow */
307}
308
345static struct fib_rules_ops fib4_rules_ops = { 309static struct fib_rules_ops fib4_rules_ops = {
346 .family = AF_INET, 310 .family = AF_INET,
347 .rule_size = sizeof(struct fib4_rule), 311 .rule_size = sizeof(struct fib4_rule),
@@ -351,6 +315,7 @@ static struct fib_rules_ops fib4_rules_ops = {
351 .compare = fib4_rule_compare, 315 .compare = fib4_rule_compare,
352 .fill = fib4_rule_fill, 316 .fill = fib4_rule_fill,
353 .default_pref = fib4_rule_default_pref, 317 .default_pref = fib4_rule_default_pref,
318 .nlmsg_payload = fib4_rule_nlmsg_payload,
354 .nlgroup = RTNLGRP_IPV4_RULE, 319 .nlgroup = RTNLGRP_IPV4_RULE,
355 .policy = fib4_rule_policy, 320 .policy = fib4_rule_policy,
356 .rules_list = &fib4_rules, 321 .rules_list = &fib4_rules,
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 884d176e00..e63b8a98fb 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -273,25 +273,49 @@ int ip_fib_check_default(__be32 gw, struct net_device *dev)
273 return -1; 273 return -1;
274} 274}
275 275
276static inline size_t fib_nlmsg_size(struct fib_info *fi)
277{
278 size_t payload = NLMSG_ALIGN(sizeof(struct rtmsg))
279 + nla_total_size(4) /* RTA_TABLE */
280 + nla_total_size(4) /* RTA_DST */
281 + nla_total_size(4) /* RTA_PRIORITY */
282 + nla_total_size(4); /* RTA_PREFSRC */
283
284 /* space for nested metrics */
285 payload += nla_total_size((RTAX_MAX * nla_total_size(4)));
286
287 if (fi->fib_nhs) {
288 /* Also handles the special case fib_nhs == 1 */
289
290 /* each nexthop is packed in an attribute */
291 size_t nhsize = nla_total_size(sizeof(struct rtnexthop));
292
293 /* may contain flow and gateway attribute */
294 nhsize += 2 * nla_total_size(4);
295
296 /* all nexthops are packed in a nested attribute */
297 payload += nla_total_size(fi->fib_nhs * nhsize);
298 }
299
300 return payload;
301}
302
276void rtmsg_fib(int event, __be32 key, struct fib_alias *fa, 303void rtmsg_fib(int event, __be32 key, struct fib_alias *fa,
277 int dst_len, u32 tb_id, struct nl_info *info) 304 int dst_len, u32 tb_id, struct nl_info *info)
278{ 305{
279 struct sk_buff *skb; 306 struct sk_buff *skb;
280 int payload = sizeof(struct rtmsg) + 256;
281 u32 seq = info->nlh ? info->nlh->nlmsg_seq : 0; 307 u32 seq = info->nlh ? info->nlh->nlmsg_seq : 0;
282 int err = -ENOBUFS; 308 int err = -ENOBUFS;
283 309
284 skb = nlmsg_new(nlmsg_total_size(payload), GFP_KERNEL); 310 skb = nlmsg_new(fib_nlmsg_size(fa->fa_info), GFP_KERNEL);
285 if (skb == NULL) 311 if (skb == NULL)
286 goto errout; 312 goto errout;
287 313
288 err = fib_dump_info(skb, info->pid, seq, event, tb_id, 314 err = fib_dump_info(skb, info->pid, seq, event, tb_id,
289 fa->fa_type, fa->fa_scope, key, dst_len, 315 fa->fa_type, fa->fa_scope, key, dst_len,
290 fa->fa_tos, fa->fa_info, 0); 316 fa->fa_tos, fa->fa_info, 0);
291 if (err < 0) { 317 /* failure implies BUG in fib_nlmsg_size() */
292 kfree_skb(skb); 318 BUG_ON(err < 0);
293 goto errout;
294 }
295 319
296 err = rtnl_notify(skb, info->pid, RTNLGRP_IPV4_ROUTE, 320 err = rtnl_notify(skb, info->pid, RTNLGRP_IPV4_ROUTE,
297 info->nlh, GFP_KERNEL); 321 info->nlh, GFP_KERNEL);
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index d17990ec72..cfb249cc0a 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -172,7 +172,7 @@ static struct tnode *inflate(struct trie *t, struct tnode *tn);
172static struct tnode *halve(struct trie *t, struct tnode *tn); 172static struct tnode *halve(struct trie *t, struct tnode *tn);
173static void tnode_free(struct tnode *tn); 173static void tnode_free(struct tnode *tn);
174 174
175static kmem_cache_t *fn_alias_kmem __read_mostly; 175static struct kmem_cache *fn_alias_kmem __read_mostly;
176static struct trie *trie_local = NULL, *trie_main = NULL; 176static struct trie *trie_local = NULL, *trie_main = NULL;
177 177
178 178
@@ -1187,7 +1187,7 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg)
1187 u8 state; 1187 u8 state;
1188 1188
1189 err = -ENOBUFS; 1189 err = -ENOBUFS;
1190 new_fa = kmem_cache_alloc(fn_alias_kmem, SLAB_KERNEL); 1190 new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL);
1191 if (new_fa == NULL) 1191 if (new_fa == NULL)
1192 goto out; 1192 goto out;
1193 1193
@@ -1232,7 +1232,7 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg)
1232 goto out; 1232 goto out;
1233 1233
1234 err = -ENOBUFS; 1234 err = -ENOBUFS;
1235 new_fa = kmem_cache_alloc(fn_alias_kmem, SLAB_KERNEL); 1235 new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL);
1236 if (new_fa == NULL) 1236 if (new_fa == NULL)
1237 goto out; 1237 goto out;
1238 1238
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index b39a37a475..40cf0d0e1b 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -332,7 +332,7 @@ static int icmp_glue_bits(void *from, char *to, int offset, int len, int odd,
332 struct sk_buff *skb) 332 struct sk_buff *skb)
333{ 333{
334 struct icmp_bxm *icmp_param = (struct icmp_bxm *)from; 334 struct icmp_bxm *icmp_param = (struct icmp_bxm *)from;
335 unsigned int csum; 335 __wsum csum;
336 336
337 csum = skb_copy_and_csum_bits(icmp_param->skb, 337 csum = skb_copy_and_csum_bits(icmp_param->skb,
338 icmp_param->offset + offset, 338 icmp_param->offset + offset,
@@ -356,7 +356,7 @@ static void icmp_push_reply(struct icmp_bxm *icmp_param,
356 ip_flush_pending_frames(icmp_socket->sk); 356 ip_flush_pending_frames(icmp_socket->sk);
357 else if ((skb = skb_peek(&icmp_socket->sk->sk_write_queue)) != NULL) { 357 else if ((skb = skb_peek(&icmp_socket->sk->sk_write_queue)) != NULL) {
358 struct icmphdr *icmph = skb->h.icmph; 358 struct icmphdr *icmph = skb->h.icmph;
359 unsigned int csum = 0; 359 __wsum csum = 0;
360 struct sk_buff *skb1; 360 struct sk_buff *skb1;
361 361
362 skb_queue_walk(&icmp_socket->sk->sk_write_queue, skb1) { 362 skb_queue_walk(&icmp_socket->sk->sk_write_queue, skb1) {
@@ -931,7 +931,7 @@ int icmp_rcv(struct sk_buff *skb)
931 931
932 switch (skb->ip_summed) { 932 switch (skb->ip_summed) {
933 case CHECKSUM_COMPLETE: 933 case CHECKSUM_COMPLETE:
934 if (!(u16)csum_fold(skb->csum)) 934 if (!csum_fold(skb->csum))
935 break; 935 break;
936 /* fall through */ 936 /* fall through */
937 case CHECKSUM_NONE: 937 case CHECKSUM_NONE:
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 6eee71647b..0017ccb01d 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -932,7 +932,7 @@ int igmp_rcv(struct sk_buff *skb)
932 932
933 switch (skb->ip_summed) { 933 switch (skb->ip_summed) {
934 case CHECKSUM_COMPLETE: 934 case CHECKSUM_COMPLETE:
935 if (!(u16)csum_fold(skb->csum)) 935 if (!csum_fold(skb->csum))
936 break; 936 break;
937 /* fall through */ 937 /* fall through */
938 case CHECKSUM_NONE: 938 case CHECKSUM_NONE:
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 96bbe2a0aa..9d68837888 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -343,7 +343,7 @@ struct dst_entry* inet_csk_route_req(struct sock *sk,
343EXPORT_SYMBOL_GPL(inet_csk_route_req); 343EXPORT_SYMBOL_GPL(inet_csk_route_req);
344 344
345static inline u32 inet_synq_hash(const __be32 raddr, const __be16 rport, 345static inline u32 inet_synq_hash(const __be32 raddr, const __be16 rport,
346 const u32 rnd, const u16 synq_hsize) 346 const u32 rnd, const u32 synq_hsize)
347{ 347{
348 return jhash_2words((__force u32)raddr, (__force u32)rport, rnd) & (synq_hsize - 1); 348 return jhash_2words((__force u32)raddr, (__force u32)rport, rnd) & (synq_hsize - 1);
349} 349}
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index 244c4f445c..8c79c8a4ea 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -27,11 +27,11 @@
27 * Allocate and initialize a new local port bind bucket. 27 * Allocate and initialize a new local port bind bucket.
28 * The bindhash mutex for snum's hash chain must be held here. 28 * The bindhash mutex for snum's hash chain must be held here.
29 */ 29 */
30struct inet_bind_bucket *inet_bind_bucket_create(kmem_cache_t *cachep, 30struct inet_bind_bucket *inet_bind_bucket_create(struct kmem_cache *cachep,
31 struct inet_bind_hashbucket *head, 31 struct inet_bind_hashbucket *head,
32 const unsigned short snum) 32 const unsigned short snum)
33{ 33{
34 struct inet_bind_bucket *tb = kmem_cache_alloc(cachep, SLAB_ATOMIC); 34 struct inet_bind_bucket *tb = kmem_cache_alloc(cachep, GFP_ATOMIC);
35 35
36 if (tb != NULL) { 36 if (tb != NULL) {
37 tb->port = snum; 37 tb->port = snum;
@@ -45,7 +45,7 @@ struct inet_bind_bucket *inet_bind_bucket_create(kmem_cache_t *cachep,
45/* 45/*
46 * Caller must hold hashbucket lock for this tb with local BH disabled 46 * Caller must hold hashbucket lock for this tb with local BH disabled
47 */ 47 */
48void inet_bind_bucket_destroy(kmem_cache_t *cachep, struct inet_bind_bucket *tb) 48void inet_bind_bucket_destroy(struct kmem_cache *cachep, struct inet_bind_bucket *tb)
49{ 49{
50 if (hlist_empty(&tb->owners)) { 50 if (hlist_empty(&tb->owners)) {
51 __hlist_del(&tb->node); 51 __hlist_del(&tb->node);
diff --git a/net/ipv4/inet_timewait_sock.c b/net/ipv4/inet_timewait_sock.c
index cdd805344c..9f414e35c4 100644
--- a/net/ipv4/inet_timewait_sock.c
+++ b/net/ipv4/inet_timewait_sock.c
@@ -91,7 +91,7 @@ struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, const int stat
91{ 91{
92 struct inet_timewait_sock *tw = 92 struct inet_timewait_sock *tw =
93 kmem_cache_alloc(sk->sk_prot_creator->twsk_prot->twsk_slab, 93 kmem_cache_alloc(sk->sk_prot_creator->twsk_prot->twsk_slab,
94 SLAB_ATOMIC); 94 GFP_ATOMIC);
95 if (tw != NULL) { 95 if (tw != NULL) {
96 const struct inet_sock *inet = inet_sk(sk); 96 const struct inet_sock *inet = inet_sk(sk);
97 97
@@ -178,7 +178,6 @@ void inet_twdr_hangman(unsigned long data)
178 need_timer = 0; 178 need_timer = 0;
179 if (inet_twdr_do_twkill_work(twdr, twdr->slot)) { 179 if (inet_twdr_do_twkill_work(twdr, twdr->slot)) {
180 twdr->thread_slots |= (1 << twdr->slot); 180 twdr->thread_slots |= (1 << twdr->slot);
181 mb();
182 schedule_work(&twdr->twkill_work); 181 schedule_work(&twdr->twkill_work);
183 need_timer = 1; 182 need_timer = 1;
184 } else { 183 } else {
@@ -197,9 +196,10 @@ EXPORT_SYMBOL_GPL(inet_twdr_hangman);
197 196
198extern void twkill_slots_invalid(void); 197extern void twkill_slots_invalid(void);
199 198
200void inet_twdr_twkill_work(void *data) 199void inet_twdr_twkill_work(struct work_struct *work)
201{ 200{
202 struct inet_timewait_death_row *twdr = data; 201 struct inet_timewait_death_row *twdr =
202 container_of(work, struct inet_timewait_death_row, twkill_work);
203 int i; 203 int i;
204 204
205 if ((INET_TWDR_TWKILL_SLOTS - 1) > (sizeof(twdr->thread_slots) * 8)) 205 if ((INET_TWDR_TWKILL_SLOTS - 1) > (sizeof(twdr->thread_slots) * 8))
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
index f072f3875a..711eb6d028 100644
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -73,7 +73,7 @@
73/* Exported for inet_getid inline function. */ 73/* Exported for inet_getid inline function. */
74DEFINE_SPINLOCK(inet_peer_idlock); 74DEFINE_SPINLOCK(inet_peer_idlock);
75 75
76static kmem_cache_t *peer_cachep __read_mostly; 76static struct kmem_cache *peer_cachep __read_mostly;
77 77
78#define node_height(x) x->avl_height 78#define node_height(x) x->avl_height
79static struct inet_peer peer_fake_node = { 79static struct inet_peer peer_fake_node = {
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index 74046efdf8..8ce00d3703 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -565,7 +565,7 @@ static void ip_frag_queue(struct ipq *qp, struct sk_buff *skb)
565 } else { 565 } else {
566 struct sk_buff *free_it = next; 566 struct sk_buff *free_it = next;
567 567
568 /* Old fragmnet is completely overridden with 568 /* Old fragment is completely overridden with
569 * new one drop it. 569 * new one drop it.
570 */ 570 */
571 next = next->next; 571 next = next->next;
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index d5b5dec075..476cb6084c 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -144,7 +144,7 @@ static struct net_device *ipgre_fb_tunnel_dev;
144 */ 144 */
145 145
146#define HASH_SIZE 16 146#define HASH_SIZE 16
147#define HASH(addr) ((addr^(addr>>4))&0xF) 147#define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF)
148 148
149static struct ip_tunnel *tunnels[4][HASH_SIZE]; 149static struct ip_tunnel *tunnels[4][HASH_SIZE];
150 150
@@ -157,7 +157,7 @@ static DEFINE_RWLOCK(ipgre_lock);
157 157
158/* Given src, dst and key, find appropriate for input tunnel. */ 158/* Given src, dst and key, find appropriate for input tunnel. */
159 159
160static struct ip_tunnel * ipgre_tunnel_lookup(u32 remote, u32 local, u32 key) 160static struct ip_tunnel * ipgre_tunnel_lookup(__be32 remote, __be32 local, __be32 key)
161{ 161{
162 unsigned h0 = HASH(remote); 162 unsigned h0 = HASH(remote);
163 unsigned h1 = HASH(key); 163 unsigned h1 = HASH(key);
@@ -194,9 +194,9 @@ static struct ip_tunnel * ipgre_tunnel_lookup(u32 remote, u32 local, u32 key)
194 194
195static struct ip_tunnel **ipgre_bucket(struct ip_tunnel *t) 195static struct ip_tunnel **ipgre_bucket(struct ip_tunnel *t)
196{ 196{
197 u32 remote = t->parms.iph.daddr; 197 __be32 remote = t->parms.iph.daddr;
198 u32 local = t->parms.iph.saddr; 198 __be32 local = t->parms.iph.saddr;
199 u32 key = t->parms.i_key; 199 __be32 key = t->parms.i_key;
200 unsigned h = HASH(key); 200 unsigned h = HASH(key);
201 int prio = 0; 201 int prio = 0;
202 202
@@ -236,9 +236,9 @@ static void ipgre_tunnel_unlink(struct ip_tunnel *t)
236 236
237static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int create) 237static struct ip_tunnel * ipgre_tunnel_locate(struct ip_tunnel_parm *parms, int create)
238{ 238{
239 u32 remote = parms->iph.daddr; 239 __be32 remote = parms->iph.daddr;
240 u32 local = parms->iph.saddr; 240 __be32 local = parms->iph.saddr;
241 u32 key = parms->i_key; 241 __be32 key = parms->i_key;
242 struct ip_tunnel *t, **tp, *nt; 242 struct ip_tunnel *t, **tp, *nt;
243 struct net_device *dev; 243 struct net_device *dev;
244 unsigned h = HASH(key); 244 unsigned h = HASH(key);
@@ -319,12 +319,12 @@ static void ipgre_err(struct sk_buff *skb, u32 info)
319 */ 319 */
320 320
321 struct iphdr *iph = (struct iphdr*)skb->data; 321 struct iphdr *iph = (struct iphdr*)skb->data;
322 u16 *p = (u16*)(skb->data+(iph->ihl<<2)); 322 __be16 *p = (__be16*)(skb->data+(iph->ihl<<2));
323 int grehlen = (iph->ihl<<2) + 4; 323 int grehlen = (iph->ihl<<2) + 4;
324 int type = skb->h.icmph->type; 324 int type = skb->h.icmph->type;
325 int code = skb->h.icmph->code; 325 int code = skb->h.icmph->code;
326 struct ip_tunnel *t; 326 struct ip_tunnel *t;
327 u16 flags; 327 __be16 flags;
328 328
329 flags = p[0]; 329 flags = p[0];
330 if (flags&(GRE_CSUM|GRE_KEY|GRE_SEQ|GRE_ROUTING|GRE_VERSION)) { 330 if (flags&(GRE_CSUM|GRE_KEY|GRE_SEQ|GRE_ROUTING|GRE_VERSION)) {
@@ -370,7 +370,7 @@ static void ipgre_err(struct sk_buff *skb, u32 info)
370 } 370 }
371 371
372 read_lock(&ipgre_lock); 372 read_lock(&ipgre_lock);
373 t = ipgre_tunnel_lookup(iph->daddr, iph->saddr, (flags&GRE_KEY) ? *(((u32*)p) + (grehlen>>2) - 1) : 0); 373 t = ipgre_tunnel_lookup(iph->daddr, iph->saddr, (flags&GRE_KEY) ? *(((__be32*)p) + (grehlen>>2) - 1) : 0);
374 if (t == NULL || t->parms.iph.daddr == 0 || MULTICAST(t->parms.iph.daddr)) 374 if (t == NULL || t->parms.iph.daddr == 0 || MULTICAST(t->parms.iph.daddr))
375 goto out; 375 goto out;
376 376
@@ -388,14 +388,14 @@ out:
388#else 388#else
389 struct iphdr *iph = (struct iphdr*)dp; 389 struct iphdr *iph = (struct iphdr*)dp;
390 struct iphdr *eiph; 390 struct iphdr *eiph;
391 u16 *p = (u16*)(dp+(iph->ihl<<2)); 391 __be16 *p = (__be16*)(dp+(iph->ihl<<2));
392 int type = skb->h.icmph->type; 392 int type = skb->h.icmph->type;
393 int code = skb->h.icmph->code; 393 int code = skb->h.icmph->code;
394 int rel_type = 0; 394 int rel_type = 0;
395 int rel_code = 0; 395 int rel_code = 0;
396 __be32 rel_info = 0; 396 __be32 rel_info = 0;
397 __u32 n = 0; 397 __u32 n = 0;
398 u16 flags; 398 __be16 flags;
399 int grehlen = (iph->ihl<<2) + 4; 399 int grehlen = (iph->ihl<<2) + 4;
400 struct sk_buff *skb2; 400 struct sk_buff *skb2;
401 struct flowi fl; 401 struct flowi fl;
@@ -556,9 +556,9 @@ static int ipgre_rcv(struct sk_buff *skb)
556{ 556{
557 struct iphdr *iph; 557 struct iphdr *iph;
558 u8 *h; 558 u8 *h;
559 u16 flags; 559 __be16 flags;
560 u16 csum = 0; 560 __sum16 csum = 0;
561 u32 key = 0; 561 __be32 key = 0;
562 u32 seqno = 0; 562 u32 seqno = 0;
563 struct ip_tunnel *tunnel; 563 struct ip_tunnel *tunnel;
564 int offset = 4; 564 int offset = 4;
@@ -568,7 +568,7 @@ static int ipgre_rcv(struct sk_buff *skb)
568 568
569 iph = skb->nh.iph; 569 iph = skb->nh.iph;
570 h = skb->data; 570 h = skb->data;
571 flags = *(u16*)h; 571 flags = *(__be16*)h;
572 572
573 if (flags&(GRE_CSUM|GRE_KEY|GRE_ROUTING|GRE_SEQ|GRE_VERSION)) { 573 if (flags&(GRE_CSUM|GRE_KEY|GRE_ROUTING|GRE_SEQ|GRE_VERSION)) {
574 /* - Version must be 0. 574 /* - Version must be 0.
@@ -580,7 +580,7 @@ static int ipgre_rcv(struct sk_buff *skb)
580 if (flags&GRE_CSUM) { 580 if (flags&GRE_CSUM) {
581 switch (skb->ip_summed) { 581 switch (skb->ip_summed) {
582 case CHECKSUM_COMPLETE: 582 case CHECKSUM_COMPLETE:
583 csum = (u16)csum_fold(skb->csum); 583 csum = csum_fold(skb->csum);
584 if (!csum) 584 if (!csum)
585 break; 585 break;
586 /* fall through */ 586 /* fall through */
@@ -592,11 +592,11 @@ static int ipgre_rcv(struct sk_buff *skb)
592 offset += 4; 592 offset += 4;
593 } 593 }
594 if (flags&GRE_KEY) { 594 if (flags&GRE_KEY) {
595 key = *(u32*)(h + offset); 595 key = *(__be32*)(h + offset);
596 offset += 4; 596 offset += 4;
597 } 597 }
598 if (flags&GRE_SEQ) { 598 if (flags&GRE_SEQ) {
599 seqno = ntohl(*(u32*)(h + offset)); 599 seqno = ntohl(*(__be32*)(h + offset));
600 offset += 4; 600 offset += 4;
601 } 601 }
602 } 602 }
@@ -605,7 +605,7 @@ static int ipgre_rcv(struct sk_buff *skb)
605 if ((tunnel = ipgre_tunnel_lookup(iph->saddr, iph->daddr, key)) != NULL) { 605 if ((tunnel = ipgre_tunnel_lookup(iph->saddr, iph->daddr, key)) != NULL) {
606 secpath_reset(skb); 606 secpath_reset(skb);
607 607
608 skb->protocol = *(u16*)(h + 2); 608 skb->protocol = *(__be16*)(h + 2);
609 /* WCCP version 1 and 2 protocol decoding. 609 /* WCCP version 1 and 2 protocol decoding.
610 * - Change protocol to IP 610 * - Change protocol to IP
611 * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header 611 * - When dealing with WCCPv2, Skip extra 4 bytes in GRE header
@@ -673,13 +673,13 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
673 struct iphdr *old_iph = skb->nh.iph; 673 struct iphdr *old_iph = skb->nh.iph;
674 struct iphdr *tiph; 674 struct iphdr *tiph;
675 u8 tos; 675 u8 tos;
676 u16 df; 676 __be16 df;
677 struct rtable *rt; /* Route to the other host */ 677 struct rtable *rt; /* Route to the other host */
678 struct net_device *tdev; /* Device to other host */ 678 struct net_device *tdev; /* Device to other host */
679 struct iphdr *iph; /* Our new IP header */ 679 struct iphdr *iph; /* Our new IP header */
680 int max_headroom; /* The extra header space needed */ 680 int max_headroom; /* The extra header space needed */
681 int gre_hlen; 681 int gre_hlen;
682 u32 dst; 682 __be32 dst;
683 int mtu; 683 int mtu;
684 684
685 if (tunnel->recursion++) { 685 if (tunnel->recursion++) {
@@ -860,11 +860,11 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
860 iph->ttl = dst_metric(&rt->u.dst, RTAX_HOPLIMIT); 860 iph->ttl = dst_metric(&rt->u.dst, RTAX_HOPLIMIT);
861 } 861 }
862 862
863 ((u16*)(iph+1))[0] = tunnel->parms.o_flags; 863 ((__be16*)(iph+1))[0] = tunnel->parms.o_flags;
864 ((u16*)(iph+1))[1] = skb->protocol; 864 ((__be16*)(iph+1))[1] = skb->protocol;
865 865
866 if (tunnel->parms.o_flags&(GRE_KEY|GRE_CSUM|GRE_SEQ)) { 866 if (tunnel->parms.o_flags&(GRE_KEY|GRE_CSUM|GRE_SEQ)) {
867 u32 *ptr = (u32*)(((u8*)iph) + tunnel->hlen - 4); 867 __be32 *ptr = (__be32*)(((u8*)iph) + tunnel->hlen - 4);
868 868
869 if (tunnel->parms.o_flags&GRE_SEQ) { 869 if (tunnel->parms.o_flags&GRE_SEQ) {
870 ++tunnel->o_seqno; 870 ++tunnel->o_seqno;
@@ -877,7 +877,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
877 } 877 }
878 if (tunnel->parms.o_flags&GRE_CSUM) { 878 if (tunnel->parms.o_flags&GRE_CSUM) {
879 *ptr = 0; 879 *ptr = 0;
880 *(__u16*)ptr = ip_compute_csum((void*)(iph+1), skb->len - sizeof(struct iphdr)); 880 *(__sum16*)ptr = ip_compute_csum((void*)(iph+1), skb->len - sizeof(struct iphdr));
881 } 881 }
882 } 882 }
883 883
@@ -1068,7 +1068,7 @@ static int ipgre_header(struct sk_buff *skb, struct net_device *dev, unsigned sh
1068{ 1068{
1069 struct ip_tunnel *t = netdev_priv(dev); 1069 struct ip_tunnel *t = netdev_priv(dev);
1070 struct iphdr *iph = (struct iphdr *)skb_push(skb, t->hlen); 1070 struct iphdr *iph = (struct iphdr *)skb_push(skb, t->hlen);
1071 u16 *p = (u16*)(iph+1); 1071 __be16 *p = (__be16*)(iph+1);
1072 1072
1073 memcpy(iph, &t->parms.iph, sizeof(struct iphdr)); 1073 memcpy(iph, &t->parms.iph, sizeof(struct iphdr));
1074 p[0] = t->parms.o_flags; 1074 p[0] = t->parms.o_flags;
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index fc195a44fc..f071f84808 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -53,6 +53,7 @@
53#include <linux/mm.h> 53#include <linux/mm.h>
54#include <linux/string.h> 54#include <linux/string.h>
55#include <linux/errno.h> 55#include <linux/errno.h>
56#include <linux/highmem.h>
56 57
57#include <linux/socket.h> 58#include <linux/socket.h>
58#include <linux/sockios.h> 59#include <linux/sockios.h>
@@ -163,7 +164,6 @@ EXPORT_SYMBOL_GPL(ip_build_and_send_pkt);
163static inline int ip_finish_output2(struct sk_buff *skb) 164static inline int ip_finish_output2(struct sk_buff *skb)
164{ 165{
165 struct dst_entry *dst = skb->dst; 166 struct dst_entry *dst = skb->dst;
166 struct hh_cache *hh = dst->hh;
167 struct net_device *dev = dst->dev; 167 struct net_device *dev = dst->dev;
168 int hh_len = LL_RESERVED_SPACE(dev); 168 int hh_len = LL_RESERVED_SPACE(dev);
169 169
@@ -182,16 +182,9 @@ static inline int ip_finish_output2(struct sk_buff *skb)
182 skb = skb2; 182 skb = skb2;
183 } 183 }
184 184
185 if (hh) { 185 if (dst->hh)
186 int hh_alen; 186 return neigh_hh_output(dst->hh, skb);
187 187 else if (dst->neighbour)
188 read_lock_bh(&hh->hh_lock);
189 hh_alen = HH_DATA_ALIGN(hh->hh_len);
190 memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
191 read_unlock_bh(&hh->hh_lock);
192 skb_push(skb, hh->hh_len);
193 return hh->hh_output(skb);
194 } else if (dst->neighbour)
195 return dst->neighbour->output(skb); 188 return dst->neighbour->output(skb);
196 189
197 if (net_ratelimit()) 190 if (net_ratelimit())
@@ -288,9 +281,8 @@ int ip_output(struct sk_buff *skb)
288 !(IPCB(skb)->flags & IPSKB_REROUTED)); 281 !(IPCB(skb)->flags & IPSKB_REROUTED));
289} 282}
290 283
291int ip_queue_xmit(struct sk_buff *skb, int ipfragok) 284int ip_queue_xmit(struct sk_buff *skb, struct sock *sk, int ipfragok)
292{ 285{
293 struct sock *sk = skb->sk;
294 struct inet_sock *inet = inet_sk(sk); 286 struct inet_sock *inet = inet_sk(sk);
295 struct ip_options *opt = inet->opt; 287 struct ip_options *opt = inet->opt;
296 struct rtable *rt; 288 struct rtable *rt;
@@ -342,7 +334,7 @@ packet_routed:
342 334
343 /* OK, we know where to send it, allocate and build IP header. */ 335 /* OK, we know where to send it, allocate and build IP header. */
344 iph = (struct iphdr *) skb_push(skb, sizeof(struct iphdr) + (opt ? opt->optlen : 0)); 336 iph = (struct iphdr *) skb_push(skb, sizeof(struct iphdr) + (opt ? opt->optlen : 0));
345 *((__u16 *)iph) = htons((4 << 12) | (5 << 8) | (inet->tos & 0xff)); 337 *((__be16 *)iph) = htons((4 << 12) | (5 << 8) | (inet->tos & 0xff));
346 iph->tot_len = htons(skb->len); 338 iph->tot_len = htons(skb->len);
347 if (ip_dont_fragment(sk, &rt->u.dst) && !ipfragok) 339 if (ip_dont_fragment(sk, &rt->u.dst) && !ipfragok)
348 iph->frag_off = htons(IP_DF); 340 iph->frag_off = htons(IP_DF);
@@ -386,6 +378,7 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from)
386 dst_release(to->dst); 378 dst_release(to->dst);
387 to->dst = dst_clone(from->dst); 379 to->dst = dst_clone(from->dst);
388 to->dev = from->dev; 380 to->dev = from->dev;
381 to->mark = from->mark;
389 382
390 /* Copy the flags to each fragment. */ 383 /* Copy the flags to each fragment. */
391 IPCB(to)->flags = IPCB(from)->flags; 384 IPCB(to)->flags = IPCB(from)->flags;
@@ -394,7 +387,6 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from)
394 to->tc_index = from->tc_index; 387 to->tc_index = from->tc_index;
395#endif 388#endif
396#ifdef CONFIG_NETFILTER 389#ifdef CONFIG_NETFILTER
397 to->nfmark = from->nfmark;
398 /* Connection association is same as pre-frag packet */ 390 /* Connection association is same as pre-frag packet */
399 nf_conntrack_put(to->nfct); 391 nf_conntrack_put(to->nfct);
400 to->nfct = from->nfct; 392 to->nfct = from->nfct;
@@ -683,7 +675,7 @@ ip_generic_getfrag(void *from, char *to, int offset, int len, int odd, struct sk
683 if (memcpy_fromiovecend(to, iov, offset, len) < 0) 675 if (memcpy_fromiovecend(to, iov, offset, len) < 0)
684 return -EFAULT; 676 return -EFAULT;
685 } else { 677 } else {
686 unsigned int csum = 0; 678 __wsum csum = 0;
687 if (csum_partial_copy_fromiovecend(to, iov, offset, len, &csum) < 0) 679 if (csum_partial_copy_fromiovecend(to, iov, offset, len, &csum) < 0)
688 return -EFAULT; 680 return -EFAULT;
689 skb->csum = csum_block_add(skb->csum, csum, odd); 681 skb->csum = csum_block_add(skb->csum, csum, odd);
@@ -691,11 +683,11 @@ ip_generic_getfrag(void *from, char *to, int offset, int len, int odd, struct sk
691 return 0; 683 return 0;
692} 684}
693 685
694static inline unsigned int 686static inline __wsum
695csum_page(struct page *page, int offset, int copy) 687csum_page(struct page *page, int offset, int copy)
696{ 688{
697 char *kaddr; 689 char *kaddr;
698 unsigned int csum; 690 __wsum csum;
699 kaddr = kmap(page); 691 kaddr = kmap(page);
700 csum = csum_partial(kaddr + offset, copy, 0); 692 csum = csum_partial(kaddr + offset, copy, 0);
701 kunmap(page); 693 kunmap(page);
@@ -1167,7 +1159,7 @@ ssize_t ip_append_page(struct sock *sk, struct page *page,
1167 } 1159 }
1168 1160
1169 if (skb->ip_summed == CHECKSUM_NONE) { 1161 if (skb->ip_summed == CHECKSUM_NONE) {
1170 unsigned int csum; 1162 __wsum csum;
1171 csum = csum_page(page, offset, len); 1163 csum = csum_page(page, offset, len);
1172 skb->csum = csum_block_add(skb->csum, csum, skb->len); 1164 skb->csum = csum_block_add(skb->csum, csum, skb->len);
1173 } 1165 }
@@ -1315,7 +1307,7 @@ void ip_flush_pending_frames(struct sock *sk)
1315static int ip_reply_glue_bits(void *dptr, char *to, int offset, 1307static int ip_reply_glue_bits(void *dptr, char *to, int offset,
1316 int len, int odd, struct sk_buff *skb) 1308 int len, int odd, struct sk_buff *skb)
1317{ 1309{
1318 unsigned int csum; 1310 __wsum csum;
1319 1311
1320 csum = csum_partial_copy_nocheck(dptr+offset, to, len, 0); 1312 csum = csum_partial_copy_nocheck(dptr+offset, to, len, 0);
1321 skb->csum = csum_block_add(skb->csum, csum, odd); 1313 skb->csum = csum_block_add(skb->csum, csum, odd);
@@ -1385,7 +1377,7 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
1385 &ipc, rt, MSG_DONTWAIT); 1377 &ipc, rt, MSG_DONTWAIT);
1386 if ((skb = skb_peek(&sk->sk_write_queue)) != NULL) { 1378 if ((skb = skb_peek(&sk->sk_write_queue)) != NULL) {
1387 if (arg->csumoffset >= 0) 1379 if (arg->csumoffset >= 0)
1388 *((u16 *)skb->h.raw + arg->csumoffset) = csum_fold(csum_add(skb->csum, arg->csum)); 1380 *((__sum16 *)skb->h.raw + arg->csumoffset) = csum_fold(csum_add(skb->csum, arg->csum));
1389 skb->ip_summed = CHECKSUM_NONE; 1381 skb->ip_summed = CHECKSUM_NONE;
1390 ip_push_pending_frames(sk); 1382 ip_push_pending_frames(sk);
1391 } 1383 }
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
index 4b132953bc..57d4bae6f0 100644
--- a/net/ipv4/ip_sockglue.c
+++ b/net/ipv4/ip_sockglue.c
@@ -355,7 +355,7 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len)
355 sin = (struct sockaddr_in *)msg->msg_name; 355 sin = (struct sockaddr_in *)msg->msg_name;
356 if (sin) { 356 if (sin) {
357 sin->sin_family = AF_INET; 357 sin->sin_family = AF_INET;
358 sin->sin_addr.s_addr = *(u32*)(skb->nh.raw + serr->addr_offset); 358 sin->sin_addr.s_addr = *(__be32*)(skb->nh.raw + serr->addr_offset);
359 sin->sin_port = serr->port; 359 sin->sin_port = serr->port;
360 memset(&sin->sin_zero, 0, sizeof(sin->sin_zero)); 360 memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
361 } 361 }
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index 955a07abb9..afa60b9a00 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -101,6 +101,7 @@
101#define CONF_NAMESERVERS_MAX 3 /* Maximum number of nameservers 101#define CONF_NAMESERVERS_MAX 3 /* Maximum number of nameservers
102 - '3' from resolv.h */ 102 - '3' from resolv.h */
103 103
104#define NONE __constant_htonl(INADDR_NONE)
104 105
105/* 106/*
106 * Public IP configuration 107 * Public IP configuration
@@ -129,19 +130,19 @@ int ic_proto_enabled __initdata = 0
129 130
130static int ic_host_name_set __initdata = 0; /* Host name set by us? */ 131static int ic_host_name_set __initdata = 0; /* Host name set by us? */
131 132
132u32 ic_myaddr = INADDR_NONE; /* My IP address */ 133__be32 ic_myaddr = NONE; /* My IP address */
133static u32 ic_netmask = INADDR_NONE; /* Netmask for local subnet */ 134static __be32 ic_netmask = NONE; /* Netmask for local subnet */
134u32 ic_gateway = INADDR_NONE; /* Gateway IP address */ 135__be32 ic_gateway = NONE; /* Gateway IP address */
135 136
136u32 ic_servaddr = INADDR_NONE; /* Boot server IP address */ 137__be32 ic_servaddr = NONE; /* Boot server IP address */
137 138
138u32 root_server_addr = INADDR_NONE; /* Address of NFS server */ 139__be32 root_server_addr = NONE; /* Address of NFS server */
139u8 root_server_path[256] = { 0, }; /* Path to mount as root */ 140u8 root_server_path[256] = { 0, }; /* Path to mount as root */
140 141
141/* Persistent data: */ 142/* Persistent data: */
142 143
143static int ic_proto_used; /* Protocol used, if any */ 144static int ic_proto_used; /* Protocol used, if any */
144static u32 ic_nameservers[CONF_NAMESERVERS_MAX]; /* DNS Server IP addresses */ 145static __be32 ic_nameservers[CONF_NAMESERVERS_MAX]; /* DNS Server IP addresses */
145static u8 ic_domain[64]; /* DNS (not NIS) domain name */ 146static u8 ic_domain[64]; /* DNS (not NIS) domain name */
146 147
147/* 148/*
@@ -172,7 +173,7 @@ struct ic_device {
172 struct net_device *dev; 173 struct net_device *dev;
173 unsigned short flags; 174 unsigned short flags;
174 short able; 175 short able;
175 u32 xid; 176 __be32 xid;
176}; 177};
177 178
178static struct ic_device *ic_first_dev __initdata = NULL;/* List of open device */ 179static struct ic_device *ic_first_dev __initdata = NULL;/* List of open device */
@@ -223,7 +224,7 @@ static int __init ic_open_devs(void)
223 d->flags = oflags; 224 d->flags = oflags;
224 d->able = able; 225 d->able = able;
225 if (able & IC_BOOTP) 226 if (able & IC_BOOTP)
226 get_random_bytes(&d->xid, sizeof(u32)); 227 get_random_bytes(&d->xid, sizeof(__be32));
227 else 228 else
228 d->xid = 0; 229 d->xid = 0;
229 ic_proto_have_if |= able; 230 ic_proto_have_if |= able;
@@ -269,7 +270,7 @@ static void __init ic_close_devs(void)
269 */ 270 */
270 271
271static inline void 272static inline void
272set_sockaddr(struct sockaddr_in *sin, u32 addr, u16 port) 273set_sockaddr(struct sockaddr_in *sin, __be32 addr, __be16 port)
273{ 274{
274 sin->sin_family = AF_INET; 275 sin->sin_family = AF_INET;
275 sin->sin_addr.s_addr = addr; 276 sin->sin_addr.s_addr = addr;
@@ -332,7 +333,7 @@ static int __init ic_setup_routes(void)
332{ 333{
333 /* No need to setup device routes, only the default route... */ 334 /* No need to setup device routes, only the default route... */
334 335
335 if (ic_gateway != INADDR_NONE) { 336 if (ic_gateway != NONE) {
336 struct rtentry rm; 337 struct rtentry rm;
337 int err; 338 int err;
338 339
@@ -368,10 +369,10 @@ static int __init ic_defaults(void)
368 if (!ic_host_name_set) 369 if (!ic_host_name_set)
369 sprintf(init_utsname()->nodename, "%u.%u.%u.%u", NIPQUAD(ic_myaddr)); 370 sprintf(init_utsname()->nodename, "%u.%u.%u.%u", NIPQUAD(ic_myaddr));
370 371
371 if (root_server_addr == INADDR_NONE) 372 if (root_server_addr == NONE)
372 root_server_addr = ic_servaddr; 373 root_server_addr = ic_servaddr;
373 374
374 if (ic_netmask == INADDR_NONE) { 375 if (ic_netmask == NONE) {
375 if (IN_CLASSA(ntohl(ic_myaddr))) 376 if (IN_CLASSA(ntohl(ic_myaddr)))
376 ic_netmask = htonl(IN_CLASSA_NET); 377 ic_netmask = htonl(IN_CLASSA_NET);
377 else if (IN_CLASSB(ntohl(ic_myaddr))) 378 else if (IN_CLASSB(ntohl(ic_myaddr)))
@@ -420,7 +421,7 @@ ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
420{ 421{
421 struct arphdr *rarp; 422 struct arphdr *rarp;
422 unsigned char *rarp_ptr; 423 unsigned char *rarp_ptr;
423 u32 sip, tip; 424 __be32 sip, tip;
424 unsigned char *sha, *tha; /* s for "source", t for "target" */ 425 unsigned char *sha, *tha; /* s for "source", t for "target" */
425 struct ic_device *d; 426 struct ic_device *d;
426 427
@@ -485,12 +486,12 @@ ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
485 goto drop_unlock; 486 goto drop_unlock;
486 487
487 /* Discard packets which are not from specified server. */ 488 /* Discard packets which are not from specified server. */
488 if (ic_servaddr != INADDR_NONE && ic_servaddr != sip) 489 if (ic_servaddr != NONE && ic_servaddr != sip)
489 goto drop_unlock; 490 goto drop_unlock;
490 491
491 /* We have a winner! */ 492 /* We have a winner! */
492 ic_dev = dev; 493 ic_dev = dev;
493 if (ic_myaddr == INADDR_NONE) 494 if (ic_myaddr == NONE)
494 ic_myaddr = tip; 495 ic_myaddr = tip;
495 ic_servaddr = sip; 496 ic_servaddr = sip;
496 ic_got_reply = IC_RARP; 497 ic_got_reply = IC_RARP;
@@ -530,13 +531,13 @@ struct bootp_pkt { /* BOOTP packet format */
530 u8 htype; /* HW address type */ 531 u8 htype; /* HW address type */
531 u8 hlen; /* HW address length */ 532 u8 hlen; /* HW address length */
532 u8 hops; /* Used only by gateways */ 533 u8 hops; /* Used only by gateways */
533 u32 xid; /* Transaction ID */ 534 __be32 xid; /* Transaction ID */
534 u16 secs; /* Seconds since we started */ 535 __be16 secs; /* Seconds since we started */
535 u16 flags; /* Just what it says */ 536 __be16 flags; /* Just what it says */
536 u32 client_ip; /* Client's IP address if known */ 537 __be32 client_ip; /* Client's IP address if known */
537 u32 your_ip; /* Assigned IP address */ 538 __be32 your_ip; /* Assigned IP address */
538 u32 server_ip; /* (Next, e.g. NFS) Server's IP address */ 539 __be32 server_ip; /* (Next, e.g. NFS) Server's IP address */
539 u32 relay_ip; /* IP address of BOOTP relay */ 540 __be32 relay_ip; /* IP address of BOOTP relay */
540 u8 hw_addr[16]; /* Client's HW address */ 541 u8 hw_addr[16]; /* Client's HW address */
541 u8 serv_name[64]; /* Server host name */ 542 u8 serv_name[64]; /* Server host name */
542 u8 boot_file[128]; /* Name of boot file */ 543 u8 boot_file[128]; /* Name of boot file */
@@ -576,7 +577,7 @@ static const u8 ic_bootp_cookie[4] = { 99, 130, 83, 99 };
576static void __init 577static void __init
577ic_dhcp_init_options(u8 *options) 578ic_dhcp_init_options(u8 *options)
578{ 579{
579 u8 mt = ((ic_servaddr == INADDR_NONE) 580 u8 mt = ((ic_servaddr == NONE)
580 ? DHCPDISCOVER : DHCPREQUEST); 581 ? DHCPDISCOVER : DHCPREQUEST);
581 u8 *e = options; 582 u8 *e = options;
582 583
@@ -666,7 +667,7 @@ static inline void ic_bootp_init(void)
666 int i; 667 int i;
667 668
668 for (i = 0; i < CONF_NAMESERVERS_MAX; i++) 669 for (i = 0; i < CONF_NAMESERVERS_MAX; i++)
669 ic_nameservers[i] = INADDR_NONE; 670 ic_nameservers[i] = NONE;
670 671
671 dev_add_pack(&bootp_packet_type); 672 dev_add_pack(&bootp_packet_type);
672} 673}
@@ -708,7 +709,7 @@ static void __init ic_bootp_send_if(struct ic_device *d, unsigned long jiffies_d
708 h->frag_off = htons(IP_DF); 709 h->frag_off = htons(IP_DF);
709 h->ttl = 64; 710 h->ttl = 64;
710 h->protocol = IPPROTO_UDP; 711 h->protocol = IPPROTO_UDP;
711 h->daddr = INADDR_BROADCAST; 712 h->daddr = htonl(INADDR_BROADCAST);
712 h->check = ip_fast_csum((unsigned char *) h, h->ihl); 713 h->check = ip_fast_csum((unsigned char *) h, h->ihl);
713 714
714 /* Construct UDP header */ 715 /* Construct UDP header */
@@ -730,8 +731,8 @@ static void __init ic_bootp_send_if(struct ic_device *d, unsigned long jiffies_d
730 b->htype = dev->type; /* can cause undefined behavior */ 731 b->htype = dev->type; /* can cause undefined behavior */
731 } 732 }
732 b->hlen = dev->addr_len; 733 b->hlen = dev->addr_len;
733 b->your_ip = INADDR_NONE; 734 b->your_ip = NONE;
734 b->server_ip = INADDR_NONE; 735 b->server_ip = NONE;
735 memcpy(b->hw_addr, dev->dev_addr, dev->addr_len); 736 memcpy(b->hw_addr, dev->dev_addr, dev->addr_len);
736 b->secs = htons(jiffies_diff / HZ); 737 b->secs = htons(jiffies_diff / HZ);
737 b->xid = d->xid; 738 b->xid = d->xid;
@@ -788,11 +789,11 @@ static void __init ic_do_bootp_ext(u8 *ext)
788 789
789 switch (*ext++) { 790 switch (*ext++) {
790 case 1: /* Subnet mask */ 791 case 1: /* Subnet mask */
791 if (ic_netmask == INADDR_NONE) 792 if (ic_netmask == NONE)
792 memcpy(&ic_netmask, ext+1, 4); 793 memcpy(&ic_netmask, ext+1, 4);
793 break; 794 break;
794 case 3: /* Default gateway */ 795 case 3: /* Default gateway */
795 if (ic_gateway == INADDR_NONE) 796 if (ic_gateway == NONE)
796 memcpy(&ic_gateway, ext+1, 4); 797 memcpy(&ic_gateway, ext+1, 4);
797 break; 798 break;
798 case 6: /* DNS server */ 799 case 6: /* DNS server */
@@ -800,7 +801,7 @@ static void __init ic_do_bootp_ext(u8 *ext)
800 if (servers > CONF_NAMESERVERS_MAX) 801 if (servers > CONF_NAMESERVERS_MAX)
801 servers = CONF_NAMESERVERS_MAX; 802 servers = CONF_NAMESERVERS_MAX;
802 for (i = 0; i < servers; i++) { 803 for (i = 0; i < servers; i++) {
803 if (ic_nameservers[i] == INADDR_NONE) 804 if (ic_nameservers[i] == NONE)
804 memcpy(&ic_nameservers[i], ext+1+4*i, 4); 805 memcpy(&ic_nameservers[i], ext+1+4*i, 4);
805 } 806 }
806 break; 807 break;
@@ -917,7 +918,7 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
917 918
918#ifdef IPCONFIG_DHCP 919#ifdef IPCONFIG_DHCP
919 if (ic_proto_enabled & IC_USE_DHCP) { 920 if (ic_proto_enabled & IC_USE_DHCP) {
920 u32 server_id = INADDR_NONE; 921 __be32 server_id = NONE;
921 int mt = 0; 922 int mt = 0;
922 923
923 ext = &b->exten[4]; 924 ext = &b->exten[4];
@@ -949,7 +950,7 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
949 /* While in the process of accepting one offer, 950 /* While in the process of accepting one offer,
950 * ignore all others. 951 * ignore all others.
951 */ 952 */
952 if (ic_myaddr != INADDR_NONE) 953 if (ic_myaddr != NONE)
953 goto drop_unlock; 954 goto drop_unlock;
954 955
955 /* Let's accept that offer. */ 956 /* Let's accept that offer. */
@@ -965,7 +966,7 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
965 * precedence over the bootp header one if 966 * precedence over the bootp header one if
966 * they are different. 967 * they are different.
967 */ 968 */
968 if ((server_id != INADDR_NONE) && 969 if ((server_id != NONE) &&
969 (b->server_ip != server_id)) 970 (b->server_ip != server_id))
970 b->server_ip = ic_servaddr; 971 b->server_ip = ic_servaddr;
971 break; 972 break;
@@ -979,8 +980,8 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
979 980
980 default: 981 default:
981 /* Urque. Forget it*/ 982 /* Urque. Forget it*/
982 ic_myaddr = INADDR_NONE; 983 ic_myaddr = NONE;
983 ic_servaddr = INADDR_NONE; 984 ic_servaddr = NONE;
984 goto drop_unlock; 985 goto drop_unlock;
985 }; 986 };
986 987
@@ -1004,9 +1005,9 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
1004 ic_dev = dev; 1005 ic_dev = dev;
1005 ic_myaddr = b->your_ip; 1006 ic_myaddr = b->your_ip;
1006 ic_servaddr = b->server_ip; 1007 ic_servaddr = b->server_ip;
1007 if (ic_gateway == INADDR_NONE && b->relay_ip) 1008 if (ic_gateway == NONE && b->relay_ip)
1008 ic_gateway = b->relay_ip; 1009 ic_gateway = b->relay_ip;
1009 if (ic_nameservers[0] == INADDR_NONE) 1010 if (ic_nameservers[0] == NONE)
1010 ic_nameservers[0] = ic_servaddr; 1011 ic_nameservers[0] = ic_servaddr;
1011 ic_got_reply = IC_BOOTP; 1012 ic_got_reply = IC_BOOTP;
1012 1013
@@ -1150,7 +1151,7 @@ static int __init ic_dynamic(void)
1150#endif 1151#endif
1151 1152
1152 if (!ic_got_reply) { 1153 if (!ic_got_reply) {
1153 ic_myaddr = INADDR_NONE; 1154 ic_myaddr = NONE;
1154 return -1; 1155 return -1;
1155 } 1156 }
1156 1157
@@ -1182,12 +1183,12 @@ static int pnp_seq_show(struct seq_file *seq, void *v)
1182 seq_printf(seq, 1183 seq_printf(seq,
1183 "domain %s\n", ic_domain); 1184 "domain %s\n", ic_domain);
1184 for (i = 0; i < CONF_NAMESERVERS_MAX; i++) { 1185 for (i = 0; i < CONF_NAMESERVERS_MAX; i++) {
1185 if (ic_nameservers[i] != INADDR_NONE) 1186 if (ic_nameservers[i] != NONE)
1186 seq_printf(seq, 1187 seq_printf(seq,
1187 "nameserver %u.%u.%u.%u\n", 1188 "nameserver %u.%u.%u.%u\n",
1188 NIPQUAD(ic_nameservers[i])); 1189 NIPQUAD(ic_nameservers[i]));
1189 } 1190 }
1190 if (ic_servaddr != INADDR_NONE) 1191 if (ic_servaddr != NONE)
1191 seq_printf(seq, 1192 seq_printf(seq,
1192 "bootserver %u.%u.%u.%u\n", 1193 "bootserver %u.%u.%u.%u\n",
1193 NIPQUAD(ic_servaddr)); 1194 NIPQUAD(ic_servaddr));
@@ -1213,9 +1214,9 @@ static struct file_operations pnp_seq_fops = {
1213 * need to have root_server_addr set _before_ IPConfig gets called as it 1214 * need to have root_server_addr set _before_ IPConfig gets called as it
1214 * can override it. 1215 * can override it.
1215 */ 1216 */
1216u32 __init root_nfs_parse_addr(char *name) 1217__be32 __init root_nfs_parse_addr(char *name)
1217{ 1218{
1218 u32 addr; 1219 __be32 addr;
1219 int octets = 0; 1220 int octets = 0;
1220 char *cp, *cq; 1221 char *cp, *cq;
1221 1222
@@ -1237,7 +1238,7 @@ u32 __init root_nfs_parse_addr(char *name)
1237 addr = in_aton(name); 1238 addr = in_aton(name);
1238 memmove(name, cp, strlen(cp) + 1); 1239 memmove(name, cp, strlen(cp) + 1);
1239 } else 1240 } else
1240 addr = INADDR_NONE; 1241 addr = NONE;
1241 1242
1242 return addr; 1243 return addr;
1243} 1244}
@@ -1248,7 +1249,7 @@ u32 __init root_nfs_parse_addr(char *name)
1248 1249
1249static int __init ip_auto_config(void) 1250static int __init ip_auto_config(void)
1250{ 1251{
1251 u32 addr; 1252 __be32 addr;
1252 1253
1253#ifdef CONFIG_PROC_FS 1254#ifdef CONFIG_PROC_FS
1254 proc_net_fops_create("pnp", S_IRUGO, &pnp_seq_fops); 1255 proc_net_fops_create("pnp", S_IRUGO, &pnp_seq_fops);
@@ -1277,11 +1278,11 @@ static int __init ip_auto_config(void)
1277 * interfaces and no default was set), use BOOTP or RARP to get the 1278 * interfaces and no default was set), use BOOTP or RARP to get the
1278 * missing values. 1279 * missing values.
1279 */ 1280 */
1280 if (ic_myaddr == INADDR_NONE || 1281 if (ic_myaddr == NONE ||
1281#ifdef CONFIG_ROOT_NFS 1282#ifdef CONFIG_ROOT_NFS
1282 (MAJOR(ROOT_DEV) == UNNAMED_MAJOR 1283 (MAJOR(ROOT_DEV) == UNNAMED_MAJOR
1283 && root_server_addr == INADDR_NONE 1284 && root_server_addr == NONE
1284 && ic_servaddr == INADDR_NONE) || 1285 && ic_servaddr == NONE) ||
1285#endif 1286#endif
1286 ic_first_dev->next) { 1287 ic_first_dev->next) {
1287#ifdef IPCONFIG_DYNAMIC 1288#ifdef IPCONFIG_DYNAMIC
@@ -1334,7 +1335,7 @@ static int __init ip_auto_config(void)
1334 } 1335 }
1335 1336
1336 addr = root_nfs_parse_addr(root_server_path); 1337 addr = root_nfs_parse_addr(root_server_path);
1337 if (root_server_addr == INADDR_NONE) 1338 if (root_server_addr == NONE)
1338 root_server_addr = addr; 1339 root_server_addr = addr;
1339 1340
1340 /* 1341 /*
@@ -1461,19 +1462,19 @@ static int __init ip_auto_config_setup(char *addrs)
1461 switch (num) { 1462 switch (num) {
1462 case 0: 1463 case 0:
1463 if ((ic_myaddr = in_aton(ip)) == INADDR_ANY) 1464 if ((ic_myaddr = in_aton(ip)) == INADDR_ANY)
1464 ic_myaddr = INADDR_NONE; 1465 ic_myaddr = NONE;
1465 break; 1466 break;
1466 case 1: 1467 case 1:
1467 if ((ic_servaddr = in_aton(ip)) == INADDR_ANY) 1468 if ((ic_servaddr = in_aton(ip)) == INADDR_ANY)
1468 ic_servaddr = INADDR_NONE; 1469 ic_servaddr = NONE;
1469 break; 1470 break;
1470 case 2: 1471 case 2:
1471 if ((ic_gateway = in_aton(ip)) == INADDR_ANY) 1472 if ((ic_gateway = in_aton(ip)) == INADDR_ANY)
1472 ic_gateway = INADDR_NONE; 1473 ic_gateway = NONE;
1473 break; 1474 break;
1474 case 3: 1475 case 3:
1475 if ((ic_netmask = in_aton(ip)) == INADDR_ANY) 1476 if ((ic_netmask = in_aton(ip)) == INADDR_ANY)
1476 ic_netmask = INADDR_NONE; 1477 ic_netmask = NONE;
1477 break; 1478 break;
1478 case 4: 1479 case 4:
1479 if ((dp = strchr(ip, '.'))) { 1480 if ((dp = strchr(ip, '.'))) {
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index 0c45565292..9d719d664e 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -118,7 +118,7 @@
118#include <net/xfrm.h> 118#include <net/xfrm.h>
119 119
120#define HASH_SIZE 16 120#define HASH_SIZE 16
121#define HASH(addr) ((addr^(addr>>4))&0xF) 121#define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF)
122 122
123static int ipip_fb_tunnel_init(struct net_device *dev); 123static int ipip_fb_tunnel_init(struct net_device *dev);
124static int ipip_tunnel_init(struct net_device *dev); 124static int ipip_tunnel_init(struct net_device *dev);
@@ -134,7 +134,7 @@ static struct ip_tunnel **tunnels[4] = { tunnels_wc, tunnels_l, tunnels_r, tunne
134 134
135static DEFINE_RWLOCK(ipip_lock); 135static DEFINE_RWLOCK(ipip_lock);
136 136
137static struct ip_tunnel * ipip_tunnel_lookup(u32 remote, u32 local) 137static struct ip_tunnel * ipip_tunnel_lookup(__be32 remote, __be32 local)
138{ 138{
139 unsigned h0 = HASH(remote); 139 unsigned h0 = HASH(remote);
140 unsigned h1 = HASH(local); 140 unsigned h1 = HASH(local);
@@ -160,8 +160,8 @@ static struct ip_tunnel * ipip_tunnel_lookup(u32 remote, u32 local)
160 160
161static struct ip_tunnel **ipip_bucket(struct ip_tunnel *t) 161static struct ip_tunnel **ipip_bucket(struct ip_tunnel *t)
162{ 162{
163 u32 remote = t->parms.iph.daddr; 163 __be32 remote = t->parms.iph.daddr;
164 u32 local = t->parms.iph.saddr; 164 __be32 local = t->parms.iph.saddr;
165 unsigned h = 0; 165 unsigned h = 0;
166 int prio = 0; 166 int prio = 0;
167 167
@@ -203,8 +203,8 @@ static void ipip_tunnel_link(struct ip_tunnel *t)
203 203
204static struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int create) 204static struct ip_tunnel * ipip_tunnel_locate(struct ip_tunnel_parm *parms, int create)
205{ 205{
206 u32 remote = parms->iph.daddr; 206 __be32 remote = parms->iph.daddr;
207 u32 local = parms->iph.saddr; 207 __be32 local = parms->iph.saddr;
208 struct ip_tunnel *t, **tp, *nt; 208 struct ip_tunnel *t, **tp, *nt;
209 struct net_device *dev; 209 struct net_device *dev;
210 unsigned h = 0; 210 unsigned h = 0;
@@ -519,13 +519,13 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
519 struct net_device_stats *stats = &tunnel->stat; 519 struct net_device_stats *stats = &tunnel->stat;
520 struct iphdr *tiph = &tunnel->parms.iph; 520 struct iphdr *tiph = &tunnel->parms.iph;
521 u8 tos = tunnel->parms.iph.tos; 521 u8 tos = tunnel->parms.iph.tos;
522 u16 df = tiph->frag_off; 522 __be16 df = tiph->frag_off;
523 struct rtable *rt; /* Route to the other host */ 523 struct rtable *rt; /* Route to the other host */
524 struct net_device *tdev; /* Device to other host */ 524 struct net_device *tdev; /* Device to other host */
525 struct iphdr *old_iph = skb->nh.iph; 525 struct iphdr *old_iph = skb->nh.iph;
526 struct iphdr *iph; /* Our new IP header */ 526 struct iphdr *iph; /* Our new IP header */
527 int max_headroom; /* The extra header space needed */ 527 int max_headroom; /* The extra header space needed */
528 u32 dst = tiph->daddr; 528 __be32 dst = tiph->daddr;
529 int mtu; 529 int mtu;
530 530
531 if (tunnel->recursion++) { 531 if (tunnel->recursion++) {
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 97cfa97c8a..ecb5422ea2 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -105,7 +105,7 @@ static DEFINE_SPINLOCK(mfc_unres_lock);
105 In this case data path is free of exclusive locks at all. 105 In this case data path is free of exclusive locks at all.
106 */ 106 */
107 107
108static kmem_cache_t *mrt_cachep __read_mostly; 108static struct kmem_cache *mrt_cachep __read_mostly;
109 109
110static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local); 110static int ip_mr_forward(struct sk_buff *skb, struct mfc_cache *cache, int local);
111static int ipmr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert); 111static int ipmr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert);
@@ -1493,7 +1493,7 @@ static int pim_rcv(struct sk_buff * skb)
1493 if (pim->type != ((PIM_VERSION<<4)|(PIM_REGISTER)) || 1493 if (pim->type != ((PIM_VERSION<<4)|(PIM_REGISTER)) ||
1494 (pim->flags&PIM_NULL_REGISTER) || 1494 (pim->flags&PIM_NULL_REGISTER) ||
1495 (ip_compute_csum((void *)pim, sizeof(*pim)) != 0 && 1495 (ip_compute_csum((void *)pim, sizeof(*pim)) != 0 &&
1496 (u16)csum_fold(skb_checksum(skb, 0, skb->len, 0)))) 1496 csum_fold(skb_checksum(skb, 0, skb->len, 0))))
1497 goto drop; 1497 goto drop;
1498 1498
1499 /* check if the inner packet is destined to mcast group */ 1499 /* check if the inner packet is destined to mcast group */
diff --git a/net/ipv4/ipvs/ip_vs_app.c b/net/ipv4/ipvs/ip_vs_app.c
index e7752334d2..6c40899aa1 100644
--- a/net/ipv4/ipvs/ip_vs_app.c
+++ b/net/ipv4/ipvs/ip_vs_app.c
@@ -80,10 +80,9 @@ ip_vs_app_inc_new(struct ip_vs_app *app, __u16 proto, __u16 port)
80 if (!pp->unregister_app) 80 if (!pp->unregister_app)
81 return -EOPNOTSUPP; 81 return -EOPNOTSUPP;
82 82
83 inc = kmalloc(sizeof(struct ip_vs_app), GFP_KERNEL); 83 inc = kmemdup(app, sizeof(*inc), GFP_KERNEL);
84 if (!inc) 84 if (!inc)
85 return -ENOMEM; 85 return -ENOMEM;
86 memcpy(inc, app, sizeof(*inc));
87 INIT_LIST_HEAD(&inc->p_list); 86 INIT_LIST_HEAD(&inc->p_list);
88 INIT_LIST_HEAD(&inc->incs_list); 87 INIT_LIST_HEAD(&inc->incs_list);
89 inc->app = app; 88 inc->app = app;
diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c
index 8832eb517d..8086787a2c 100644
--- a/net/ipv4/ipvs/ip_vs_conn.c
+++ b/net/ipv4/ipvs/ip_vs_conn.c
@@ -44,7 +44,7 @@
44static struct list_head *ip_vs_conn_tab; 44static struct list_head *ip_vs_conn_tab;
45 45
46/* SLAB cache for IPVS connections */ 46/* SLAB cache for IPVS connections */
47static kmem_cache_t *ip_vs_conn_cachep __read_mostly; 47static struct kmem_cache *ip_vs_conn_cachep __read_mostly;
48 48
49/* counter for current IPVS connections */ 49/* counter for current IPVS connections */
50static atomic_t ip_vs_conn_count = ATOMIC_INIT(0); 50static atomic_t ip_vs_conn_count = ATOMIC_INIT(0);
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
index 1445bb47fe..34257520a3 100644
--- a/net/ipv4/ipvs/ip_vs_core.c
+++ b/net/ipv4/ipvs/ip_vs_core.c
@@ -536,9 +536,9 @@ static unsigned int ip_vs_post_routing(unsigned int hooknum,
536 return NF_STOP; 536 return NF_STOP;
537} 537}
538 538
539u16 ip_vs_checksum_complete(struct sk_buff *skb, int offset) 539__sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset)
540{ 540{
541 return (u16) csum_fold(skb_checksum(skb, offset, skb->len - offset, 0)); 541 return csum_fold(skb_checksum(skb, offset, skb->len - offset, 0));
542} 542}
543 543
544static inline struct sk_buff * 544static inline struct sk_buff *
diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c
index f261616e46..9b933381eb 100644
--- a/net/ipv4/ipvs/ip_vs_ctl.c
+++ b/net/ipv4/ipvs/ip_vs_ctl.c
@@ -221,10 +221,10 @@ static void update_defense_level(void)
221 * Timer for checking the defense 221 * Timer for checking the defense
222 */ 222 */
223#define DEFENSE_TIMER_PERIOD 1*HZ 223#define DEFENSE_TIMER_PERIOD 1*HZ
224static void defense_work_handler(void *data); 224static void defense_work_handler(struct work_struct *work);
225static DECLARE_WORK(defense_work, defense_work_handler, NULL); 225static DECLARE_DELAYED_WORK(defense_work, defense_work_handler);
226 226
227static void defense_work_handler(void *data) 227static void defense_work_handler(struct work_struct *work)
228{ 228{
229 update_defense_level(); 229 update_defense_level();
230 if (atomic_read(&ip_vs_dropentry)) 230 if (atomic_read(&ip_vs_dropentry))
diff --git a/net/ipv4/ipvs/ip_vs_lblc.c b/net/ipv4/ipvs/ip_vs_lblc.c
index 524751e031..a4385a2180 100644
--- a/net/ipv4/ipvs/ip_vs_lblc.c
+++ b/net/ipv4/ipvs/ip_vs_lblc.c
@@ -45,6 +45,7 @@
45#include <linux/module.h> 45#include <linux/module.h>
46#include <linux/kernel.h> 46#include <linux/kernel.h>
47#include <linux/skbuff.h> 47#include <linux/skbuff.h>
48#include <linux/jiffies.h>
48 49
49/* for sysctl */ 50/* for sysctl */
50#include <linux/fs.h> 51#include <linux/fs.h>
diff --git a/net/ipv4/ipvs/ip_vs_lblcr.c b/net/ipv4/ipvs/ip_vs_lblcr.c
index 08990192b6..fe1af5d079 100644
--- a/net/ipv4/ipvs/ip_vs_lblcr.c
+++ b/net/ipv4/ipvs/ip_vs_lblcr.c
@@ -43,6 +43,7 @@
43#include <linux/module.h> 43#include <linux/module.h>
44#include <linux/kernel.h> 44#include <linux/kernel.h>
45#include <linux/skbuff.h> 45#include <linux/skbuff.h>
46#include <linux/jiffies.h>
46 47
47/* for sysctl */ 48/* for sysctl */
48#include <linux/fs.h> 49#include <linux/fs.h>
diff --git a/net/ipv4/ipvs/ip_vs_proto.c b/net/ipv4/ipvs/ip_vs_proto.c
index c4528b5c80..e844ddb82b 100644
--- a/net/ipv4/ipvs/ip_vs_proto.c
+++ b/net/ipv4/ipvs/ip_vs_proto.c
@@ -118,13 +118,7 @@ void ip_vs_protocol_timeout_change(int flags)
118int * 118int *
119ip_vs_create_timeout_table(int *table, int size) 119ip_vs_create_timeout_table(int *table, int size)
120{ 120{
121 int *t; 121 return kmemdup(table, size, GFP_ATOMIC);
122
123 t = kmalloc(size, GFP_ATOMIC);
124 if (t == NULL)
125 return NULL;
126 memcpy(t, table, size);
127 return t;
128} 122}
129 123
130 124
diff --git a/net/ipv4/ipvs/ip_vs_proto_tcp.c b/net/ipv4/ipvs/ip_vs_proto_tcp.c
index 6ff05c3a32..16a9ebee2f 100644
--- a/net/ipv4/ipvs/ip_vs_proto_tcp.c
+++ b/net/ipv4/ipvs/ip_vs_proto_tcp.c
@@ -84,7 +84,7 @@ tcp_conn_schedule(struct sk_buff *skb,
84 } 84 }
85 85
86 if (th->syn && 86 if (th->syn &&
87 (svc = ip_vs_service_get(skb->nfmark, skb->nh.iph->protocol, 87 (svc = ip_vs_service_get(skb->mark, skb->nh.iph->protocol,
88 skb->nh.iph->daddr, th->dest))) { 88 skb->nh.iph->daddr, th->dest))) {
89 if (ip_vs_todrop()) { 89 if (ip_vs_todrop()) {
90 /* 90 /*
@@ -116,9 +116,9 @@ tcp_fast_csum_update(struct tcphdr *tcph, __be32 oldip, __be32 newip,
116 __be16 oldport, __be16 newport) 116 __be16 oldport, __be16 newport)
117{ 117{
118 tcph->check = 118 tcph->check =
119 ip_vs_check_diff(~oldip, newip, 119 csum_fold(ip_vs_check_diff4(oldip, newip,
120 ip_vs_check_diff(oldport ^ htons(0xFFFF), 120 ip_vs_check_diff2(oldport, newport,
121 newport, tcph->check)); 121 ~csum_unfold(tcph->check))));
122} 122}
123 123
124 124
@@ -490,16 +490,18 @@ tcp_state_transition(struct ip_vs_conn *cp, int direction,
490static struct list_head tcp_apps[TCP_APP_TAB_SIZE]; 490static struct list_head tcp_apps[TCP_APP_TAB_SIZE];
491static DEFINE_SPINLOCK(tcp_app_lock); 491static DEFINE_SPINLOCK(tcp_app_lock);
492 492
493static inline __u16 tcp_app_hashkey(__u16 port) 493static inline __u16 tcp_app_hashkey(__be16 port)
494{ 494{
495 return ((port >> TCP_APP_TAB_BITS) ^ port) & TCP_APP_TAB_MASK; 495 return (((__force u16)port >> TCP_APP_TAB_BITS) ^ (__force u16)port)
496 & TCP_APP_TAB_MASK;
496} 497}
497 498
498 499
499static int tcp_register_app(struct ip_vs_app *inc) 500static int tcp_register_app(struct ip_vs_app *inc)
500{ 501{
501 struct ip_vs_app *i; 502 struct ip_vs_app *i;
502 __u16 hash, port = inc->port; 503 __u16 hash;
504 __be16 port = inc->port;
503 int ret = 0; 505 int ret = 0;
504 506
505 hash = tcp_app_hashkey(port); 507 hash = tcp_app_hashkey(port);
diff --git a/net/ipv4/ipvs/ip_vs_proto_udp.c b/net/ipv4/ipvs/ip_vs_proto_udp.c
index 691c8b637b..03f0a414cf 100644
--- a/net/ipv4/ipvs/ip_vs_proto_udp.c
+++ b/net/ipv4/ipvs/ip_vs_proto_udp.c
@@ -89,7 +89,7 @@ udp_conn_schedule(struct sk_buff *skb, struct ip_vs_protocol *pp,
89 return 0; 89 return 0;
90 } 90 }
91 91
92 if ((svc = ip_vs_service_get(skb->nfmark, skb->nh.iph->protocol, 92 if ((svc = ip_vs_service_get(skb->mark, skb->nh.iph->protocol,
93 skb->nh.iph->daddr, uh->dest))) { 93 skb->nh.iph->daddr, uh->dest))) {
94 if (ip_vs_todrop()) { 94 if (ip_vs_todrop()) {
95 /* 95 /*
@@ -121,11 +121,11 @@ udp_fast_csum_update(struct udphdr *uhdr, __be32 oldip, __be32 newip,
121 __be16 oldport, __be16 newport) 121 __be16 oldport, __be16 newport)
122{ 122{
123 uhdr->check = 123 uhdr->check =
124 ip_vs_check_diff(~oldip, newip, 124 csum_fold(ip_vs_check_diff4(oldip, newip,
125 ip_vs_check_diff(oldport ^ htons(0xFFFF), 125 ip_vs_check_diff2(oldport, newport,
126 newport, uhdr->check)); 126 ~csum_unfold(uhdr->check))));
127 if (!uhdr->check) 127 if (!uhdr->check)
128 uhdr->check = -1; 128 uhdr->check = CSUM_MANGLED_0;
129} 129}
130 130
131static int 131static int
@@ -173,7 +173,7 @@ udp_snat_handler(struct sk_buff **pskb,
173 cp->protocol, 173 cp->protocol,
174 (*pskb)->csum); 174 (*pskb)->csum);
175 if (udph->check == 0) 175 if (udph->check == 0)
176 udph->check = -1; 176 udph->check = CSUM_MANGLED_0;
177 IP_VS_DBG(11, "O-pkt: %s O-csum=%d (+%zd)\n", 177 IP_VS_DBG(11, "O-pkt: %s O-csum=%d (+%zd)\n",
178 pp->name, udph->check, 178 pp->name, udph->check,
179 (char*)&(udph->check) - (char*)udph); 179 (char*)&(udph->check) - (char*)udph);
@@ -228,7 +228,7 @@ udp_dnat_handler(struct sk_buff **pskb,
228 cp->protocol, 228 cp->protocol,
229 (*pskb)->csum); 229 (*pskb)->csum);
230 if (udph->check == 0) 230 if (udph->check == 0)
231 udph->check = -1; 231 udph->check = CSUM_MANGLED_0;
232 (*pskb)->ip_summed = CHECKSUM_UNNECESSARY; 232 (*pskb)->ip_summed = CHECKSUM_UNNECESSARY;
233 } 233 }
234 return 1; 234 return 1;
@@ -282,16 +282,18 @@ udp_csum_check(struct sk_buff *skb, struct ip_vs_protocol *pp)
282static struct list_head udp_apps[UDP_APP_TAB_SIZE]; 282static struct list_head udp_apps[UDP_APP_TAB_SIZE];
283static DEFINE_SPINLOCK(udp_app_lock); 283static DEFINE_SPINLOCK(udp_app_lock);
284 284
285static inline __u16 udp_app_hashkey(__u16 port) 285static inline __u16 udp_app_hashkey(__be16 port)
286{ 286{
287 return ((port >> UDP_APP_TAB_BITS) ^ port) & UDP_APP_TAB_MASK; 287 return (((__force u16)port >> UDP_APP_TAB_BITS) ^ (__force u16)port)
288 & UDP_APP_TAB_MASK;
288} 289}
289 290
290 291
291static int udp_register_app(struct ip_vs_app *inc) 292static int udp_register_app(struct ip_vs_app *inc)
292{ 293{
293 struct ip_vs_app *i; 294 struct ip_vs_app *i;
294 __u16 hash, port = inc->port; 295 __u16 hash;
296 __be16 port = inc->port;
295 int ret = 0; 297 int ret = 0;
296 298
297 hash = udp_app_hashkey(port); 299 hash = udp_app_hashkey(port);
diff --git a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c
index 91a075edd6..7ea2d981a9 100644
--- a/net/ipv4/ipvs/ip_vs_sync.c
+++ b/net/ipv4/ipvs/ip_vs_sync.c
@@ -657,7 +657,7 @@ static void sync_master_loop(void)
657 if (stop_master_sync) 657 if (stop_master_sync)
658 break; 658 break;
659 659
660 ssleep(1); 660 msleep_interruptible(1000);
661 } 661 }
662 662
663 /* clean up the sync_buff queue */ 663 /* clean up the sync_buff queue */
@@ -714,7 +714,7 @@ static void sync_backup_loop(void)
714 if (stop_backup_sync) 714 if (stop_backup_sync)
715 break; 715 break;
716 716
717 ssleep(1); 717 msleep_interruptible(1000);
718 } 718 }
719 719
720 /* release the sending multicast socket */ 720 /* release the sending multicast socket */
@@ -826,7 +826,7 @@ static int fork_sync_thread(void *startup)
826 if ((pid = kernel_thread(sync_thread, startup, 0)) < 0) { 826 if ((pid = kernel_thread(sync_thread, startup, 0)) < 0) {
827 IP_VS_ERR("could not create sync_thread due to %d... " 827 IP_VS_ERR("could not create sync_thread due to %d... "
828 "retrying.\n", pid); 828 "retrying.\n", pid);
829 ssleep(1); 829 msleep_interruptible(1000);
830 goto repeat; 830 goto repeat;
831 } 831 }
832 832
@@ -849,10 +849,12 @@ int start_sync_thread(int state, char *mcast_ifn, __u8 syncid)
849 849
850 ip_vs_sync_state |= state; 850 ip_vs_sync_state |= state;
851 if (state == IP_VS_STATE_MASTER) { 851 if (state == IP_VS_STATE_MASTER) {
852 strlcpy(ip_vs_master_mcast_ifn, mcast_ifn, sizeof(ip_vs_master_mcast_ifn)); 852 strlcpy(ip_vs_master_mcast_ifn, mcast_ifn,
853 sizeof(ip_vs_master_mcast_ifn));
853 ip_vs_master_syncid = syncid; 854 ip_vs_master_syncid = syncid;
854 } else { 855 } else {
855 strlcpy(ip_vs_backup_mcast_ifn, mcast_ifn, sizeof(ip_vs_backup_mcast_ifn)); 856 strlcpy(ip_vs_backup_mcast_ifn, mcast_ifn,
857 sizeof(ip_vs_backup_mcast_ifn));
856 ip_vs_backup_syncid = syncid; 858 ip_vs_backup_syncid = syncid;
857 } 859 }
858 860
@@ -860,7 +862,7 @@ int start_sync_thread(int state, char *mcast_ifn, __u8 syncid)
860 if ((pid = kernel_thread(fork_sync_thread, &startup, 0)) < 0) { 862 if ((pid = kernel_thread(fork_sync_thread, &startup, 0)) < 0) {
861 IP_VS_ERR("could not create fork_sync_thread due to %d... " 863 IP_VS_ERR("could not create fork_sync_thread due to %d... "
862 "retrying.\n", pid); 864 "retrying.\n", pid);
863 ssleep(1); 865 msleep_interruptible(1000);
864 goto repeat; 866 goto repeat;
865 } 867 }
866 868
@@ -880,7 +882,8 @@ int stop_sync_thread(int state)
880 882
881 IP_VS_DBG(7, "%s: pid %d\n", __FUNCTION__, current->pid); 883 IP_VS_DBG(7, "%s: pid %d\n", __FUNCTION__, current->pid);
882 IP_VS_INFO("stopping sync thread %d ...\n", 884 IP_VS_INFO("stopping sync thread %d ...\n",
883 (state == IP_VS_STATE_MASTER) ? sync_master_pid : sync_backup_pid); 885 (state == IP_VS_STATE_MASTER) ?
886 sync_master_pid : sync_backup_pid);
884 887
885 __set_current_state(TASK_UNINTERRUPTIBLE); 888 __set_current_state(TASK_UNINTERRUPTIBLE);
886 add_wait_queue(&stop_sync_wait, &wait); 889 add_wait_queue(&stop_sync_wait, &wait);
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index e2005c6810..c47ce7076b 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -15,21 +15,22 @@ int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type)
15 struct flowi fl = {}; 15 struct flowi fl = {};
16 struct dst_entry *odst; 16 struct dst_entry *odst;
17 unsigned int hh_len; 17 unsigned int hh_len;
18 unsigned int type;
18 19
20 type = inet_addr_type(iph->saddr);
19 if (addr_type == RTN_UNSPEC) 21 if (addr_type == RTN_UNSPEC)
20 addr_type = inet_addr_type(iph->saddr); 22 addr_type = type;
21 23
22 /* some non-standard hacks like ipt_REJECT.c:send_reset() can cause 24 /* some non-standard hacks like ipt_REJECT.c:send_reset() can cause
23 * packets with foreign saddr to appear on the NF_IP_LOCAL_OUT hook. 25 * packets with foreign saddr to appear on the NF_IP_LOCAL_OUT hook.
24 */ 26 */
25 if (addr_type == RTN_LOCAL) { 27 if (addr_type == RTN_LOCAL) {
26 fl.nl_u.ip4_u.daddr = iph->daddr; 28 fl.nl_u.ip4_u.daddr = iph->daddr;
27 fl.nl_u.ip4_u.saddr = iph->saddr; 29 if (type == RTN_LOCAL)
30 fl.nl_u.ip4_u.saddr = iph->saddr;
28 fl.nl_u.ip4_u.tos = RT_TOS(iph->tos); 31 fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
29 fl.oif = (*pskb)->sk ? (*pskb)->sk->sk_bound_dev_if : 0; 32 fl.oif = (*pskb)->sk ? (*pskb)->sk->sk_bound_dev_if : 0;
30#ifdef CONFIG_IP_ROUTE_FWMARK 33 fl.mark = (*pskb)->mark;
31 fl.nl_u.ip4_u.fwmark = (*pskb)->nfmark;
32#endif
33 if (ip_route_output_key(&rt, &fl) != 0) 34 if (ip_route_output_key(&rt, &fl) != 0)
34 return -1; 35 return -1;
35 36
@@ -164,17 +165,17 @@ static int nf_ip_reroute(struct sk_buff **pskb, const struct nf_info *info)
164 return 0; 165 return 0;
165} 166}
166 167
167unsigned int nf_ip_checksum(struct sk_buff *skb, unsigned int hook, 168__sum16 nf_ip_checksum(struct sk_buff *skb, unsigned int hook,
168 unsigned int dataoff, u_int8_t protocol) 169 unsigned int dataoff, u_int8_t protocol)
169{ 170{
170 struct iphdr *iph = skb->nh.iph; 171 struct iphdr *iph = skb->nh.iph;
171 unsigned int csum = 0; 172 __sum16 csum = 0;
172 173
173 switch (skb->ip_summed) { 174 switch (skb->ip_summed) {
174 case CHECKSUM_COMPLETE: 175 case CHECKSUM_COMPLETE:
175 if (hook != NF_IP_PRE_ROUTING && hook != NF_IP_LOCAL_IN) 176 if (hook != NF_IP_PRE_ROUTING && hook != NF_IP_LOCAL_IN)
176 break; 177 break;
177 if ((protocol == 0 && !(u16)csum_fold(skb->csum)) || 178 if ((protocol == 0 && !csum_fold(skb->csum)) ||
178 !csum_tcpudp_magic(iph->saddr, iph->daddr, 179 !csum_tcpudp_magic(iph->saddr, iph->daddr,
179 skb->len - dataoff, protocol, 180 skb->len - dataoff, protocol,
180 skb->csum)) { 181 skb->csum)) {
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig
index d88c292f11..47bd3ad18b 100644
--- a/net/ipv4/netfilter/Kconfig
+++ b/net/ipv4/netfilter/Kconfig
@@ -6,8 +6,8 @@ menu "IP: Netfilter Configuration"
6 depends on INET && NETFILTER 6 depends on INET && NETFILTER
7 7
8config NF_CONNTRACK_IPV4 8config NF_CONNTRACK_IPV4
9 tristate "IPv4 support for new connection tracking (EXPERIMENTAL)" 9 tristate "IPv4 connection tracking support (required for NAT)"
10 depends on EXPERIMENTAL && NF_CONNTRACK 10 depends on NF_CONNTRACK
11 ---help--- 11 ---help---
12 Connection tracking keeps a record of what packets have passed 12 Connection tracking keeps a record of what packets have passed
13 through your machine, in order to figure out how they are related 13 through your machine, in order to figure out how they are related
@@ -19,21 +19,18 @@ config NF_CONNTRACK_IPV4
19 19
20 To compile it as a module, choose M here. If unsure, say N. 20 To compile it as a module, choose M here. If unsure, say N.
21 21
22# connection tracking, helpers and protocols 22config NF_CONNTRACK_PROC_COMPAT
23config IP_NF_CONNTRACK 23 bool "proc/sysctl compatibility with old connection tracking"
24 tristate "Connection tracking (required for masq/NAT)" 24 depends on NF_CONNTRACK_IPV4
25 ---help--- 25 default y
26 Connection tracking keeps a record of what packets have passed 26 help
27 through your machine, in order to figure out how they are related 27 This option enables /proc and sysctl compatibility with the old
28 into connections. 28 layer 3 dependant connection tracking. This is needed to keep
29 29 old programs that have not been adapted to the new names working.
30 This is required to do Masquerading or other kinds of Network
31 Address Translation (except for Fast NAT). It can also be used to
32 enhance packet filtering (see `Connection state match support'
33 below).
34 30
35 To compile it as a module, choose M here. If unsure, say N. 31 If unsure, say Y.
36 32
33# connection tracking, helpers and protocols
37config IP_NF_CT_ACCT 34config IP_NF_CT_ACCT
38 bool "Connection tracking flow accounting" 35 bool "Connection tracking flow accounting"
39 depends on IP_NF_CONNTRACK 36 depends on IP_NF_CONNTRACK
@@ -315,20 +312,6 @@ config IP_NF_MATCH_ADDRTYPE
315 If you want to compile it as a module, say M here and read 312 If you want to compile it as a module, say M here and read
316 <file:Documentation/modules.txt>. If unsure, say `N'. 313 <file:Documentation/modules.txt>. If unsure, say `N'.
317 314
318config IP_NF_MATCH_HASHLIMIT
319 tristate 'hashlimit match support'
320 depends on IP_NF_IPTABLES
321 help
322 This option adds a new iptables `hashlimit' match.
323
324 As opposed to `limit', this match dynamically creates a hash table
325 of limit buckets, based on your selection of source/destination
326 ip addresses and/or ports.
327
328 It enables you to express policies like `10kpps for any given
329 destination IP' or `500pps from any given source IP' with a single
330 IPtables rule.
331
332# `filter', generic and specific targets 315# `filter', generic and specific targets
333config IP_NF_FILTER 316config IP_NF_FILTER
334 tristate "Packet filtering" 317 tristate "Packet filtering"
@@ -404,7 +387,7 @@ config IP_NF_TARGET_TCPMSS
404 387
405 To compile it as a module, choose M here. If unsure, say N. 388 To compile it as a module, choose M here. If unsure, say N.
406 389
407# NAT + specific targets 390# NAT + specific targets: ip_conntrack
408config IP_NF_NAT 391config IP_NF_NAT
409 tristate "Full NAT" 392 tristate "Full NAT"
410 depends on IP_NF_IPTABLES && IP_NF_CONNTRACK 393 depends on IP_NF_IPTABLES && IP_NF_CONNTRACK
@@ -415,14 +398,30 @@ config IP_NF_NAT
415 398
416 To compile it as a module, choose M here. If unsure, say N. 399 To compile it as a module, choose M here. If unsure, say N.
417 400
401# NAT + specific targets: nf_conntrack
402config NF_NAT
403 tristate "Full NAT"
404 depends on IP_NF_IPTABLES && NF_CONNTRACK_IPV4
405 help
406 The Full NAT option allows masquerading, port forwarding and other
407 forms of full Network Address Port Translation. It is controlled by
408 the `nat' table in iptables: see the man page for iptables(8).
409
410 To compile it as a module, choose M here. If unsure, say N.
411
418config IP_NF_NAT_NEEDED 412config IP_NF_NAT_NEEDED
419 bool 413 bool
420 depends on IP_NF_NAT != n 414 depends on IP_NF_NAT
415 default y
416
417config NF_NAT_NEEDED
418 bool
419 depends on NF_NAT
421 default y 420 default y
422 421
423config IP_NF_TARGET_MASQUERADE 422config IP_NF_TARGET_MASQUERADE
424 tristate "MASQUERADE target support" 423 tristate "MASQUERADE target support"
425 depends on IP_NF_NAT 424 depends on (NF_NAT || IP_NF_NAT)
426 help 425 help
427 Masquerading is a special case of NAT: all outgoing connections are 426 Masquerading is a special case of NAT: all outgoing connections are
428 changed to seem to come from a particular interface's address, and 427 changed to seem to come from a particular interface's address, and
@@ -434,7 +433,7 @@ config IP_NF_TARGET_MASQUERADE
434 433
435config IP_NF_TARGET_REDIRECT 434config IP_NF_TARGET_REDIRECT
436 tristate "REDIRECT target support" 435 tristate "REDIRECT target support"
437 depends on IP_NF_NAT 436 depends on (NF_NAT || IP_NF_NAT)
438 help 437 help
439 REDIRECT is a special case of NAT: all incoming connections are 438 REDIRECT is a special case of NAT: all incoming connections are
440 mapped onto the incoming interface's address, causing the packets to 439 mapped onto the incoming interface's address, causing the packets to
@@ -445,7 +444,7 @@ config IP_NF_TARGET_REDIRECT
445 444
446config IP_NF_TARGET_NETMAP 445config IP_NF_TARGET_NETMAP
447 tristate "NETMAP target support" 446 tristate "NETMAP target support"
448 depends on IP_NF_NAT 447 depends on (NF_NAT || IP_NF_NAT)
449 help 448 help
450 NETMAP is an implementation of static 1:1 NAT mapping of network 449 NETMAP is an implementation of static 1:1 NAT mapping of network
451 addresses. It maps the network address part, while keeping the host 450 addresses. It maps the network address part, while keeping the host
@@ -456,7 +455,7 @@ config IP_NF_TARGET_NETMAP
456 455
457config IP_NF_TARGET_SAME 456config IP_NF_TARGET_SAME
458 tristate "SAME target support" 457 tristate "SAME target support"
459 depends on IP_NF_NAT 458 depends on (NF_NAT || IP_NF_NAT)
460 help 459 help
461 This option adds a `SAME' target, which works like the standard SNAT 460 This option adds a `SAME' target, which works like the standard SNAT
462 target, but attempts to give clients the same IP for all connections. 461 target, but attempts to give clients the same IP for all connections.
@@ -478,19 +477,52 @@ config IP_NF_NAT_SNMP_BASIC
478 477
479 To compile it as a module, choose M here. If unsure, say N. 478 To compile it as a module, choose M here. If unsure, say N.
480 479
480config NF_NAT_SNMP_BASIC
481 tristate "Basic SNMP-ALG support (EXPERIMENTAL)"
482 depends on EXPERIMENTAL && NF_NAT
483 ---help---
484
485 This module implements an Application Layer Gateway (ALG) for
486 SNMP payloads. In conjunction with NAT, it allows a network
487 management system to access multiple private networks with
488 conflicting addresses. It works by modifying IP addresses
489 inside SNMP payloads to match IP-layer NAT mapping.
490
491 This is the "basic" form of SNMP-ALG, as described in RFC 2962
492
493 To compile it as a module, choose M here. If unsure, say N.
494
495# If they want FTP, set to $CONFIG_IP_NF_NAT (m or y),
496# or $CONFIG_IP_NF_FTP (m or y), whichever is weaker.
497# From kconfig-language.txt:
498#
499# <expr> '&&' <expr> (6)
500#
501# (6) Returns the result of min(/expr/, /expr/).
502config NF_NAT_PROTO_GRE
503 tristate
504 depends on NF_NAT && NF_CT_PROTO_GRE
505
506config IP_NF_NAT_FTP
507 tristate
508 depends on IP_NF_IPTABLES && IP_NF_CONNTRACK && IP_NF_NAT
509 default IP_NF_NAT && IP_NF_FTP
510
511config NF_NAT_FTP
512 tristate
513 depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
514 default NF_NAT && NF_CONNTRACK_FTP
515
481config IP_NF_NAT_IRC 516config IP_NF_NAT_IRC
482 tristate 517 tristate
483 depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n 518 depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
484 default IP_NF_NAT if IP_NF_IRC=y 519 default IP_NF_NAT if IP_NF_IRC=y
485 default m if IP_NF_IRC=m 520 default m if IP_NF_IRC=m
486 521
487# If they want FTP, set to $CONFIG_IP_NF_NAT (m or y), 522config NF_NAT_IRC
488# or $CONFIG_IP_NF_FTP (m or y), whichever is weaker. Argh.
489config IP_NF_NAT_FTP
490 tristate 523 tristate
491 depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n 524 depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
492 default IP_NF_NAT if IP_NF_FTP=y 525 default NF_NAT && NF_CONNTRACK_IRC
493 default m if IP_NF_FTP=m
494 526
495config IP_NF_NAT_TFTP 527config IP_NF_NAT_TFTP
496 tristate 528 tristate
@@ -498,30 +530,56 @@ config IP_NF_NAT_TFTP
498 default IP_NF_NAT if IP_NF_TFTP=y 530 default IP_NF_NAT if IP_NF_TFTP=y
499 default m if IP_NF_TFTP=m 531 default m if IP_NF_TFTP=m
500 532
533config NF_NAT_TFTP
534 tristate
535 depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
536 default NF_NAT && NF_CONNTRACK_TFTP
537
501config IP_NF_NAT_AMANDA 538config IP_NF_NAT_AMANDA
502 tristate 539 tristate
503 depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n 540 depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
504 default IP_NF_NAT if IP_NF_AMANDA=y 541 default IP_NF_NAT if IP_NF_AMANDA=y
505 default m if IP_NF_AMANDA=m 542 default m if IP_NF_AMANDA=m
506 543
544config NF_NAT_AMANDA
545 tristate
546 depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
547 default NF_NAT && NF_CONNTRACK_AMANDA
548
507config IP_NF_NAT_PPTP 549config IP_NF_NAT_PPTP
508 tristate 550 tristate
509 depends on IP_NF_NAT!=n && IP_NF_PPTP!=n 551 depends on IP_NF_NAT!=n && IP_NF_PPTP!=n
510 default IP_NF_NAT if IP_NF_PPTP=y 552 default IP_NF_NAT if IP_NF_PPTP=y
511 default m if IP_NF_PPTP=m 553 default m if IP_NF_PPTP=m
512 554
555config NF_NAT_PPTP
556 tristate
557 depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
558 default NF_NAT && NF_CONNTRACK_PPTP
559 select NF_NAT_PROTO_GRE
560
513config IP_NF_NAT_H323 561config IP_NF_NAT_H323
514 tristate 562 tristate
515 depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n 563 depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
516 default IP_NF_NAT if IP_NF_H323=y 564 default IP_NF_NAT if IP_NF_H323=y
517 default m if IP_NF_H323=m 565 default m if IP_NF_H323=m
518 566
567config NF_NAT_H323
568 tristate
569 depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
570 default NF_NAT && NF_CONNTRACK_H323
571
519config IP_NF_NAT_SIP 572config IP_NF_NAT_SIP
520 tristate 573 tristate
521 depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n 574 depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n
522 default IP_NF_NAT if IP_NF_SIP=y 575 default IP_NF_NAT if IP_NF_SIP=y
523 default m if IP_NF_SIP=m 576 default m if IP_NF_SIP=m
524 577
578config NF_NAT_SIP
579 tristate
580 depends on IP_NF_IPTABLES && NF_CONNTRACK && NF_NAT
581 default NF_NAT && NF_CONNTRACK_SIP
582
525# mangle + specific targets 583# mangle + specific targets
526config IP_NF_MANGLE 584config IP_NF_MANGLE
527 tristate "Packet mangling" 585 tristate "Packet mangling"
diff --git a/net/ipv4/netfilter/Makefile b/net/ipv4/netfilter/Makefile
index 09aaed1a80..15e741aeb2 100644
--- a/net/ipv4/netfilter/Makefile
+++ b/net/ipv4/netfilter/Makefile
@@ -5,17 +5,23 @@
5# objects for the standalone - connection tracking / NAT 5# objects for the standalone - connection tracking / NAT
6ip_conntrack-objs := ip_conntrack_standalone.o ip_conntrack_core.o ip_conntrack_proto_generic.o ip_conntrack_proto_tcp.o ip_conntrack_proto_udp.o ip_conntrack_proto_icmp.o 6ip_conntrack-objs := ip_conntrack_standalone.o ip_conntrack_core.o ip_conntrack_proto_generic.o ip_conntrack_proto_tcp.o ip_conntrack_proto_udp.o ip_conntrack_proto_icmp.o
7ip_nat-objs := ip_nat_core.o ip_nat_helper.o ip_nat_proto_unknown.o ip_nat_proto_tcp.o ip_nat_proto_udp.o ip_nat_proto_icmp.o 7ip_nat-objs := ip_nat_core.o ip_nat_helper.o ip_nat_proto_unknown.o ip_nat_proto_tcp.o ip_nat_proto_udp.o ip_nat_proto_icmp.o
8nf_nat-objs := nf_nat_core.o nf_nat_helper.o nf_nat_proto_unknown.o nf_nat_proto_tcp.o nf_nat_proto_udp.o nf_nat_proto_icmp.o
9ifneq ($(CONFIG_NF_NAT),)
10iptable_nat-objs := nf_nat_rule.o nf_nat_standalone.o
11else
8iptable_nat-objs := ip_nat_rule.o ip_nat_standalone.o 12iptable_nat-objs := ip_nat_rule.o ip_nat_standalone.o
13endif
9 14
10ip_conntrack_pptp-objs := ip_conntrack_helper_pptp.o ip_conntrack_proto_gre.o 15ip_conntrack_pptp-objs := ip_conntrack_helper_pptp.o ip_conntrack_proto_gre.o
11ip_nat_pptp-objs := ip_nat_helper_pptp.o ip_nat_proto_gre.o 16ip_nat_pptp-objs := ip_nat_helper_pptp.o ip_nat_proto_gre.o
12 17
13ip_conntrack_h323-objs := ip_conntrack_helper_h323.o ip_conntrack_helper_h323_asn1.o 18ip_conntrack_h323-objs := ip_conntrack_helper_h323.o ../../netfilter/nf_conntrack_h323_asn1.o
14ip_nat_h323-objs := ip_nat_helper_h323.o 19ip_nat_h323-objs := ip_nat_helper_h323.o
15 20
16# connection tracking 21# connection tracking
17obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o 22obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o
18obj-$(CONFIG_IP_NF_NAT) += ip_nat.o 23obj-$(CONFIG_IP_NF_NAT) += ip_nat.o
24obj-$(CONFIG_NF_NAT) += nf_nat.o
19 25
20# conntrack netlink interface 26# conntrack netlink interface
21obj-$(CONFIG_IP_NF_CONNTRACK_NETLINK) += ip_conntrack_netlink.o 27obj-$(CONFIG_IP_NF_CONNTRACK_NETLINK) += ip_conntrack_netlink.o
@@ -34,7 +40,7 @@ obj-$(CONFIG_IP_NF_IRC) += ip_conntrack_irc.o
34obj-$(CONFIG_IP_NF_SIP) += ip_conntrack_sip.o 40obj-$(CONFIG_IP_NF_SIP) += ip_conntrack_sip.o
35obj-$(CONFIG_IP_NF_NETBIOS_NS) += ip_conntrack_netbios_ns.o 41obj-$(CONFIG_IP_NF_NETBIOS_NS) += ip_conntrack_netbios_ns.o
36 42
37# NAT helpers 43# NAT helpers (ip_conntrack)
38obj-$(CONFIG_IP_NF_NAT_H323) += ip_nat_h323.o 44obj-$(CONFIG_IP_NF_NAT_H323) += ip_nat_h323.o
39obj-$(CONFIG_IP_NF_NAT_PPTP) += ip_nat_pptp.o 45obj-$(CONFIG_IP_NF_NAT_PPTP) += ip_nat_pptp.o
40obj-$(CONFIG_IP_NF_NAT_AMANDA) += ip_nat_amanda.o 46obj-$(CONFIG_IP_NF_NAT_AMANDA) += ip_nat_amanda.o
@@ -43,6 +49,19 @@ obj-$(CONFIG_IP_NF_NAT_FTP) += ip_nat_ftp.o
43obj-$(CONFIG_IP_NF_NAT_IRC) += ip_nat_irc.o 49obj-$(CONFIG_IP_NF_NAT_IRC) += ip_nat_irc.o
44obj-$(CONFIG_IP_NF_NAT_SIP) += ip_nat_sip.o 50obj-$(CONFIG_IP_NF_NAT_SIP) += ip_nat_sip.o
45 51
52# NAT helpers (nf_conntrack)
53obj-$(CONFIG_NF_NAT_AMANDA) += nf_nat_amanda.o
54obj-$(CONFIG_NF_NAT_FTP) += nf_nat_ftp.o
55obj-$(CONFIG_NF_NAT_H323) += nf_nat_h323.o
56obj-$(CONFIG_NF_NAT_IRC) += nf_nat_irc.o
57obj-$(CONFIG_NF_NAT_PPTP) += nf_nat_pptp.o
58obj-$(CONFIG_NF_NAT_SIP) += nf_nat_sip.o
59obj-$(CONFIG_NF_NAT_SNMP_BASIC) += nf_nat_snmp_basic.o
60obj-$(CONFIG_NF_NAT_TFTP) += nf_nat_tftp.o
61
62# NAT protocols (nf_nat)
63obj-$(CONFIG_NF_NAT_PROTO_GRE) += nf_nat_proto_gre.o
64
46# generic IP tables 65# generic IP tables
47obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o 66obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o
48 67
@@ -50,10 +69,10 @@ obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o
50obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o 69obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o
51obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o 70obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o
52obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o 71obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o
72obj-$(CONFIG_NF_NAT) += iptable_nat.o
53obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o 73obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
54 74
55# matches 75# matches
56obj-$(CONFIG_IP_NF_MATCH_HASHLIMIT) += ipt_hashlimit.o
57obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o 76obj-$(CONFIG_IP_NF_MATCH_IPRANGE) += ipt_iprange.o
58obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o 77obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o
59obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o 78obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o
@@ -89,6 +108,11 @@ obj-$(CONFIG_IP_NF_QUEUE) += ip_queue.o
89 108
90# objects for l3 independent conntrack 109# objects for l3 independent conntrack
91nf_conntrack_ipv4-objs := nf_conntrack_l3proto_ipv4.o nf_conntrack_proto_icmp.o 110nf_conntrack_ipv4-objs := nf_conntrack_l3proto_ipv4.o nf_conntrack_proto_icmp.o
111ifeq ($(CONFIG_NF_CONNTRACK_PROC_COMPAT),y)
112ifeq ($(CONFIG_PROC_FS),y)
113nf_conntrack_ipv4-objs += nf_conntrack_l3proto_ipv4_compat.o
114endif
115endif
92 116
93# l3 independent conntrack 117# l3 independent conntrack
94obj-$(CONFIG_NF_CONNTRACK_IPV4) += nf_conntrack_ipv4.o 118obj-$(CONFIG_NF_CONNTRACK_IPV4) += nf_conntrack_ipv4.o
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 413c2d0a1f..9aa22398b3 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -358,6 +358,7 @@ static int mark_source_chains(struct xt_table_info *newinfo,
358 for (;;) { 358 for (;;) {
359 struct arpt_standard_target *t 359 struct arpt_standard_target *t
360 = (void *)arpt_get_target(e); 360 = (void *)arpt_get_target(e);
361 int visited = e->comefrom & (1 << hook);
361 362
362 if (e->comefrom & (1 << NF_ARP_NUMHOOKS)) { 363 if (e->comefrom & (1 << NF_ARP_NUMHOOKS)) {
363 printk("arptables: loop hook %u pos %u %08X.\n", 364 printk("arptables: loop hook %u pos %u %08X.\n",
@@ -368,13 +369,20 @@ static int mark_source_chains(struct xt_table_info *newinfo,
368 |= ((1 << hook) | (1 << NF_ARP_NUMHOOKS)); 369 |= ((1 << hook) | (1 << NF_ARP_NUMHOOKS));
369 370
370 /* Unconditional return/END. */ 371 /* Unconditional return/END. */
371 if (e->target_offset == sizeof(struct arpt_entry) 372 if ((e->target_offset == sizeof(struct arpt_entry)
372 && (strcmp(t->target.u.user.name, 373 && (strcmp(t->target.u.user.name,
373 ARPT_STANDARD_TARGET) == 0) 374 ARPT_STANDARD_TARGET) == 0)
374 && t->verdict < 0 375 && t->verdict < 0
375 && unconditional(&e->arp)) { 376 && unconditional(&e->arp)) || visited) {
376 unsigned int oldpos, size; 377 unsigned int oldpos, size;
377 378
379 if (t->verdict < -NF_MAX_VERDICT - 1) {
380 duprintf("mark_source_chains: bad "
381 "negative verdict (%i)\n",
382 t->verdict);
383 return 0;
384 }
385
378 /* Return: backtrack through the last 386 /* Return: backtrack through the last
379 * big jump. 387 * big jump.
380 */ 388 */
@@ -404,6 +412,14 @@ static int mark_source_chains(struct xt_table_info *newinfo,
404 if (strcmp(t->target.u.user.name, 412 if (strcmp(t->target.u.user.name,
405 ARPT_STANDARD_TARGET) == 0 413 ARPT_STANDARD_TARGET) == 0
406 && newpos >= 0) { 414 && newpos >= 0) {
415 if (newpos > newinfo->size -
416 sizeof(struct arpt_entry)) {
417 duprintf("mark_source_chains: "
418 "bad verdict (%i)\n",
419 newpos);
420 return 0;
421 }
422
407 /* This a jump; chase it. */ 423 /* This a jump; chase it. */
408 duprintf("Jump rule %u -> %u\n", 424 duprintf("Jump rule %u -> %u\n",
409 pos, newpos); 425 pos, newpos);
@@ -426,8 +442,6 @@ static int mark_source_chains(struct xt_table_info *newinfo,
426static inline int standard_check(const struct arpt_entry_target *t, 442static inline int standard_check(const struct arpt_entry_target *t,
427 unsigned int max_offset) 443 unsigned int max_offset)
428{ 444{
429 struct arpt_standard_target *targ = (void *)t;
430
431 /* Check standard info. */ 445 /* Check standard info. */
432 if (t->u.target_size 446 if (t->u.target_size
433 != ARPT_ALIGN(sizeof(struct arpt_standard_target))) { 447 != ARPT_ALIGN(sizeof(struct arpt_standard_target))) {
@@ -437,18 +451,6 @@ static inline int standard_check(const struct arpt_entry_target *t,
437 return 0; 451 return 0;
438 } 452 }
439 453
440 if (targ->verdict >= 0
441 && targ->verdict > max_offset - sizeof(struct arpt_entry)) {
442 duprintf("arpt_standard_check: bad verdict (%i)\n",
443 targ->verdict);
444 return 0;
445 }
446
447 if (targ->verdict < -NF_MAX_VERDICT - 1) {
448 duprintf("arpt_standard_check: bad negative verdict (%i)\n",
449 targ->verdict);
450 return 0;
451 }
452 return 1; 454 return 1;
453} 455}
454 456
@@ -627,18 +629,20 @@ static int translate_table(const char *name,
627 } 629 }
628 } 630 }
629 631
632 if (!mark_source_chains(newinfo, valid_hooks, entry0)) {
633 duprintf("Looping hook\n");
634 return -ELOOP;
635 }
636
630 /* Finally, each sanity check must pass */ 637 /* Finally, each sanity check must pass */
631 i = 0; 638 i = 0;
632 ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size, 639 ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size,
633 check_entry, name, size, &i); 640 check_entry, name, size, &i);
634 641
635 if (ret != 0) 642 if (ret != 0) {
636 goto cleanup; 643 ARPT_ENTRY_ITERATE(entry0, newinfo->size,
637 644 cleanup_entry, &i);
638 ret = -ELOOP; 645 return ret;
639 if (!mark_source_chains(newinfo, valid_hooks, entry0)) {
640 duprintf("Looping hook\n");
641 goto cleanup;
642 } 646 }
643 647
644 /* And one copy for every other CPU */ 648 /* And one copy for every other CPU */
@@ -647,9 +651,6 @@ static int translate_table(const char *name,
647 memcpy(newinfo->entries[i], entry0, newinfo->size); 651 memcpy(newinfo->entries[i], entry0, newinfo->size);
648 } 652 }
649 653
650 return 0;
651cleanup:
652 ARPT_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i);
653 return ret; 654 return ret;
654} 655}
655 656
diff --git a/net/ipv4/netfilter/ip_conntrack_amanda.c b/net/ipv4/netfilter/ip_conntrack_amanda.c
index 6c7383a8e4..ad246ba779 100644
--- a/net/ipv4/netfilter/ip_conntrack_amanda.c
+++ b/net/ipv4/netfilter/ip_conntrack_amanda.c
@@ -92,6 +92,7 @@ static int help(struct sk_buff **pskb,
92 char pbuf[sizeof("65535")], *tmp; 92 char pbuf[sizeof("65535")], *tmp;
93 u_int16_t port, len; 93 u_int16_t port, len;
94 int ret = NF_ACCEPT; 94 int ret = NF_ACCEPT;
95 typeof(ip_nat_amanda_hook) ip_nat_amanda;
95 96
96 /* Only look at packets from the Amanda server */ 97 /* Only look at packets from the Amanda server */
97 if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) 98 if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL)
@@ -161,9 +162,11 @@ static int help(struct sk_buff **pskb,
161 exp->mask.dst.protonum = 0xFF; 162 exp->mask.dst.protonum = 0xFF;
162 exp->mask.dst.u.tcp.port = htons(0xFFFF); 163 exp->mask.dst.u.tcp.port = htons(0xFFFF);
163 164
164 if (ip_nat_amanda_hook) 165 /* RCU read locked by nf_hook_slow */
165 ret = ip_nat_amanda_hook(pskb, ctinfo, off - dataoff, 166 ip_nat_amanda = rcu_dereference(ip_nat_amanda_hook);
166 len, exp); 167 if (ip_nat_amanda)
168 ret = ip_nat_amanda(pskb, ctinfo, off - dataoff,
169 len, exp);
167 else if (ip_conntrack_expect_related(exp) != 0) 170 else if (ip_conntrack_expect_related(exp) != 0)
168 ret = NF_DROP; 171 ret = NF_DROP;
169 ip_conntrack_expect_put(exp); 172 ip_conntrack_expect_put(exp);
@@ -180,7 +183,7 @@ static struct ip_conntrack_helper amanda_helper = {
180 .help = help, 183 .help = help,
181 .name = "amanda", 184 .name = "amanda",
182 185
183 .tuple = { .src = { .u = { __constant_htons(10080) } }, 186 .tuple = { .src = { .u = { .udp = {.port = __constant_htons(10080) } } },
184 .dst = { .protonum = IPPROTO_UDP }, 187 .dst = { .protonum = IPPROTO_UDP },
185 }, 188 },
186 .mask = { .src = { .u = { 0xFFFF } }, 189 .mask = { .src = { .u = { 0xFFFF } },
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
index 8b848aa77b..8556a4f4f6 100644
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -40,9 +40,6 @@
40 40
41/* ip_conntrack_lock protects the main hash table, protocol/helper/expected 41/* ip_conntrack_lock protects the main hash table, protocol/helper/expected
42 registrations, conntrack timers*/ 42 registrations, conntrack timers*/
43#define ASSERT_READ_LOCK(x)
44#define ASSERT_WRITE_LOCK(x)
45
46#include <linux/netfilter_ipv4/ip_conntrack.h> 43#include <linux/netfilter_ipv4/ip_conntrack.h>
47#include <linux/netfilter_ipv4/ip_conntrack_protocol.h> 44#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
48#include <linux/netfilter_ipv4/ip_conntrack_helper.h> 45#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
@@ -68,8 +65,8 @@ static LIST_HEAD(helpers);
68unsigned int ip_conntrack_htable_size __read_mostly = 0; 65unsigned int ip_conntrack_htable_size __read_mostly = 0;
69int ip_conntrack_max __read_mostly; 66int ip_conntrack_max __read_mostly;
70struct list_head *ip_conntrack_hash __read_mostly; 67struct list_head *ip_conntrack_hash __read_mostly;
71static kmem_cache_t *ip_conntrack_cachep __read_mostly; 68static struct kmem_cache *ip_conntrack_cachep __read_mostly;
72static kmem_cache_t *ip_conntrack_expect_cachep __read_mostly; 69static struct kmem_cache *ip_conntrack_expect_cachep __read_mostly;
73struct ip_conntrack ip_conntrack_untracked; 70struct ip_conntrack ip_conntrack_untracked;
74unsigned int ip_ct_log_invalid __read_mostly; 71unsigned int ip_ct_log_invalid __read_mostly;
75static LIST_HEAD(unconfirmed); 72static LIST_HEAD(unconfirmed);
@@ -201,7 +198,6 @@ ip_ct_invert_tuple(struct ip_conntrack_tuple *inverse,
201/* ip_conntrack_expect helper functions */ 198/* ip_conntrack_expect helper functions */
202void ip_ct_unlink_expect(struct ip_conntrack_expect *exp) 199void ip_ct_unlink_expect(struct ip_conntrack_expect *exp)
203{ 200{
204 ASSERT_WRITE_LOCK(&ip_conntrack_lock);
205 IP_NF_ASSERT(!timer_pending(&exp->timeout)); 201 IP_NF_ASSERT(!timer_pending(&exp->timeout));
206 list_del(&exp->list); 202 list_del(&exp->list);
207 CONNTRACK_STAT_INC(expect_delete); 203 CONNTRACK_STAT_INC(expect_delete);
@@ -233,7 +229,7 @@ __ip_conntrack_expect_find(const struct ip_conntrack_tuple *tuple)
233 229
234/* Just find a expectation corresponding to a tuple. */ 230/* Just find a expectation corresponding to a tuple. */
235struct ip_conntrack_expect * 231struct ip_conntrack_expect *
236ip_conntrack_expect_find(const struct ip_conntrack_tuple *tuple) 232ip_conntrack_expect_find_get(const struct ip_conntrack_tuple *tuple)
237{ 233{
238 struct ip_conntrack_expect *i; 234 struct ip_conntrack_expect *i;
239 235
@@ -294,7 +290,6 @@ static void
294clean_from_lists(struct ip_conntrack *ct) 290clean_from_lists(struct ip_conntrack *ct)
295{ 291{
296 DEBUGP("clean_from_lists(%p)\n", ct); 292 DEBUGP("clean_from_lists(%p)\n", ct);
297 ASSERT_WRITE_LOCK(&ip_conntrack_lock);
298 list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list); 293 list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list);
299 list_del(&ct->tuplehash[IP_CT_DIR_REPLY].list); 294 list_del(&ct->tuplehash[IP_CT_DIR_REPLY].list);
300 295
@@ -373,7 +368,6 @@ __ip_conntrack_find(const struct ip_conntrack_tuple *tuple,
373 struct ip_conntrack_tuple_hash *h; 368 struct ip_conntrack_tuple_hash *h;
374 unsigned int hash = hash_conntrack(tuple); 369 unsigned int hash = hash_conntrack(tuple);
375 370
376 ASSERT_READ_LOCK(&ip_conntrack_lock);
377 list_for_each_entry(h, &ip_conntrack_hash[hash], list) { 371 list_for_each_entry(h, &ip_conntrack_hash[hash], list) {
378 if (tuplehash_to_ctrack(h) != ignored_conntrack && 372 if (tuplehash_to_ctrack(h) != ignored_conntrack &&
379 ip_ct_tuple_equal(tuple, &h->tuple)) { 373 ip_ct_tuple_equal(tuple, &h->tuple)) {
diff --git a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c
index 93dcf96066..0410c99cac 100644
--- a/net/ipv4/netfilter/ip_conntrack_ftp.c
+++ b/net/ipv4/netfilter/ip_conntrack_ftp.c
@@ -310,6 +310,7 @@ static int help(struct sk_buff **pskb,
310 struct ip_conntrack_expect *exp; 310 struct ip_conntrack_expect *exp;
311 unsigned int i; 311 unsigned int i;
312 int found = 0, ends_in_nl; 312 int found = 0, ends_in_nl;
313 typeof(ip_nat_ftp_hook) ip_nat_ftp;
313 314
314 /* Until there's been traffic both ways, don't look in packets. */ 315 /* Until there's been traffic both ways, don't look in packets. */
315 if (ctinfo != IP_CT_ESTABLISHED 316 if (ctinfo != IP_CT_ESTABLISHED
@@ -433,9 +434,10 @@ static int help(struct sk_buff **pskb,
433 434
434 /* Now, NAT might want to mangle the packet, and register the 435 /* Now, NAT might want to mangle the packet, and register the
435 * (possibly changed) expectation itself. */ 436 * (possibly changed) expectation itself. */
436 if (ip_nat_ftp_hook) 437 ip_nat_ftp = rcu_dereference(ip_nat_ftp_hook);
437 ret = ip_nat_ftp_hook(pskb, ctinfo, search[dir][i].ftptype, 438 if (ip_nat_ftp)
438 matchoff, matchlen, exp, &seq); 439 ret = ip_nat_ftp(pskb, ctinfo, search[dir][i].ftptype,
440 matchoff, matchlen, exp, &seq);
439 else { 441 else {
440 /* Can't expect this? Best to drop packet now. */ 442 /* Can't expect this? Best to drop packet now. */
441 if (ip_conntrack_expect_related(exp) != 0) 443 if (ip_conntrack_expect_related(exp) != 0)
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323.c b/net/ipv4/netfilter/ip_conntrack_helper_h323.c
index 6cb9070cd0..aabfe1c069 100644
--- a/net/ipv4/netfilter/ip_conntrack_helper_h323.c
+++ b/net/ipv4/netfilter/ip_conntrack_helper_h323.c
@@ -237,6 +237,7 @@ static int expect_rtp_rtcp(struct sk_buff **pskb, struct ip_conntrack *ct,
237 u_int16_t rtp_port; 237 u_int16_t rtp_port;
238 struct ip_conntrack_expect *rtp_exp; 238 struct ip_conntrack_expect *rtp_exp;
239 struct ip_conntrack_expect *rtcp_exp; 239 struct ip_conntrack_expect *rtcp_exp;
240 typeof(nat_rtp_rtcp_hook) nat_rtp_rtcp;
240 241
241 /* Read RTP or RTCP address */ 242 /* Read RTP or RTCP address */
242 if (!get_h245_addr(*data, addr, &ip, &port) || 243 if (!get_h245_addr(*data, addr, &ip, &port) ||
@@ -279,11 +280,11 @@ static int expect_rtp_rtcp(struct sk_buff **pskb, struct ip_conntrack *ct,
279 rtcp_exp->flags = 0; 280 rtcp_exp->flags = 0;
280 281
281 if (ct->tuplehash[dir].tuple.src.ip != 282 if (ct->tuplehash[dir].tuple.src.ip !=
282 ct->tuplehash[!dir].tuple.dst.ip && nat_rtp_rtcp_hook) { 283 ct->tuplehash[!dir].tuple.dst.ip &&
284 (nat_rtp_rtcp = rcu_dereference(nat_rtp_rtcp_hook))) {
283 /* NAT needed */ 285 /* NAT needed */
284 ret = nat_rtp_rtcp_hook(pskb, ct, ctinfo, data, dataoff, 286 ret = nat_rtp_rtcp(pskb, ct, ctinfo, data, dataoff,
285 addr, port, rtp_port, rtp_exp, 287 addr, port, rtp_port, rtp_exp, rtcp_exp);
286 rtcp_exp);
287 } else { /* Conntrack only */ 288 } else { /* Conntrack only */
288 rtp_exp->expectfn = NULL; 289 rtp_exp->expectfn = NULL;
289 rtcp_exp->expectfn = NULL; 290 rtcp_exp->expectfn = NULL;
@@ -328,6 +329,7 @@ static int expect_t120(struct sk_buff **pskb,
328 __be32 ip; 329 __be32 ip;
329 u_int16_t port; 330 u_int16_t port;
330 struct ip_conntrack_expect *exp = NULL; 331 struct ip_conntrack_expect *exp = NULL;
332 typeof(nat_t120_hook) nat_t120;
331 333
332 /* Read T.120 address */ 334 /* Read T.120 address */
333 if (!get_h245_addr(*data, addr, &ip, &port) || 335 if (!get_h245_addr(*data, addr, &ip, &port) ||
@@ -350,10 +352,11 @@ static int expect_t120(struct sk_buff **pskb,
350 exp->flags = IP_CT_EXPECT_PERMANENT; /* Accept multiple channels */ 352 exp->flags = IP_CT_EXPECT_PERMANENT; /* Accept multiple channels */
351 353
352 if (ct->tuplehash[dir].tuple.src.ip != 354 if (ct->tuplehash[dir].tuple.src.ip !=
353 ct->tuplehash[!dir].tuple.dst.ip && nat_t120_hook) { 355 ct->tuplehash[!dir].tuple.dst.ip &&
356 (nat_t120 = rcu_dereference(nat_t120_hook))) {
354 /* NAT needed */ 357 /* NAT needed */
355 ret = nat_t120_hook(pskb, ct, ctinfo, data, dataoff, addr, 358 ret = nat_t120(pskb, ct, ctinfo, data, dataoff, addr,
356 port, exp); 359 port, exp);
357 } else { /* Conntrack only */ 360 } else { /* Conntrack only */
358 exp->expectfn = NULL; 361 exp->expectfn = NULL;
359 if (ip_conntrack_expect_related(exp) == 0) { 362 if (ip_conntrack_expect_related(exp) == 0) {
@@ -651,6 +654,7 @@ static int expect_h245(struct sk_buff **pskb, struct ip_conntrack *ct,
651 __be32 ip; 654 __be32 ip;
652 u_int16_t port; 655 u_int16_t port;
653 struct ip_conntrack_expect *exp = NULL; 656 struct ip_conntrack_expect *exp = NULL;
657 typeof(nat_h245_hook) nat_h245;
654 658
655 /* Read h245Address */ 659 /* Read h245Address */
656 if (!get_h225_addr(*data, addr, &ip, &port) || 660 if (!get_h225_addr(*data, addr, &ip, &port) ||
@@ -673,10 +677,11 @@ static int expect_h245(struct sk_buff **pskb, struct ip_conntrack *ct,
673 exp->flags = 0; 677 exp->flags = 0;
674 678
675 if (ct->tuplehash[dir].tuple.src.ip != 679 if (ct->tuplehash[dir].tuple.src.ip !=
676 ct->tuplehash[!dir].tuple.dst.ip && nat_h245_hook) { 680 ct->tuplehash[!dir].tuple.dst.ip &&
681 (nat_h245 = rcu_dereference(nat_h245_hook))) {
677 /* NAT needed */ 682 /* NAT needed */
678 ret = nat_h245_hook(pskb, ct, ctinfo, data, dataoff, addr, 683 ret = nat_h245(pskb, ct, ctinfo, data, dataoff, addr,
679 port, exp); 684 port, exp);
680 } else { /* Conntrack only */ 685 } else { /* Conntrack only */
681 exp->expectfn = ip_conntrack_h245_expect; 686 exp->expectfn = ip_conntrack_h245_expect;
682 687
@@ -712,6 +717,7 @@ static int expect_callforwarding(struct sk_buff **pskb,
712 __be32 ip; 717 __be32 ip;
713 u_int16_t port; 718 u_int16_t port;
714 struct ip_conntrack_expect *exp = NULL; 719 struct ip_conntrack_expect *exp = NULL;
720 typeof(nat_callforwarding_hook) nat_callforwarding;
715 721
716 /* Read alternativeAddress */ 722 /* Read alternativeAddress */
717 if (!get_h225_addr(*data, addr, &ip, &port) || port == 0) 723 if (!get_h225_addr(*data, addr, &ip, &port) || port == 0)
@@ -759,10 +765,11 @@ static int expect_callforwarding(struct sk_buff **pskb,
759 exp->flags = 0; 765 exp->flags = 0;
760 766
761 if (ct->tuplehash[dir].tuple.src.ip != 767 if (ct->tuplehash[dir].tuple.src.ip !=
762 ct->tuplehash[!dir].tuple.dst.ip && nat_callforwarding_hook) { 768 ct->tuplehash[!dir].tuple.dst.ip &&
769 (nat_callforwarding = rcu_dereference(nat_callforwarding_hook))) {
763 /* Need NAT */ 770 /* Need NAT */
764 ret = nat_callforwarding_hook(pskb, ct, ctinfo, data, dataoff, 771 ret = nat_callforwarding(pskb, ct, ctinfo, data, dataoff,
765 addr, port, exp); 772 addr, port, exp);
766 } else { /* Conntrack only */ 773 } else { /* Conntrack only */
767 exp->expectfn = ip_conntrack_q931_expect; 774 exp->expectfn = ip_conntrack_q931_expect;
768 775
@@ -793,6 +800,7 @@ static int process_setup(struct sk_buff **pskb, struct ip_conntrack *ct,
793 int i; 800 int i;
794 __be32 ip; 801 __be32 ip;
795 u_int16_t port; 802 u_int16_t port;
803 typeof(set_h225_addr_hook) set_h225_addr;
796 804
797 DEBUGP("ip_ct_q931: Setup\n"); 805 DEBUGP("ip_ct_q931: Setup\n");
798 806
@@ -803,8 +811,10 @@ static int process_setup(struct sk_buff **pskb, struct ip_conntrack *ct,
803 return -1; 811 return -1;
804 } 812 }
805 813
814 set_h225_addr = rcu_dereference(set_h225_addr_hook);
815
806 if ((setup->options & eSetup_UUIE_destCallSignalAddress) && 816 if ((setup->options & eSetup_UUIE_destCallSignalAddress) &&
807 (set_h225_addr_hook) && 817 (set_h225_addr) &&
808 get_h225_addr(*data, &setup->destCallSignalAddress, &ip, &port) && 818 get_h225_addr(*data, &setup->destCallSignalAddress, &ip, &port) &&
809 ip != ct->tuplehash[!dir].tuple.src.ip) { 819 ip != ct->tuplehash[!dir].tuple.src.ip) {
810 DEBUGP("ip_ct_q931: set destCallSignalAddress " 820 DEBUGP("ip_ct_q931: set destCallSignalAddress "
@@ -812,17 +822,17 @@ static int process_setup(struct sk_buff **pskb, struct ip_conntrack *ct,
812 NIPQUAD(ip), port, 822 NIPQUAD(ip), port,
813 NIPQUAD(ct->tuplehash[!dir].tuple.src.ip), 823 NIPQUAD(ct->tuplehash[!dir].tuple.src.ip),
814 ntohs(ct->tuplehash[!dir].tuple.src.u.tcp.port)); 824 ntohs(ct->tuplehash[!dir].tuple.src.u.tcp.port));
815 ret = set_h225_addr_hook(pskb, data, dataoff, 825 ret = set_h225_addr(pskb, data, dataoff,
816 &setup->destCallSignalAddress, 826 &setup->destCallSignalAddress,
817 ct->tuplehash[!dir].tuple.src.ip, 827 ct->tuplehash[!dir].tuple.src.ip,
818 ntohs(ct->tuplehash[!dir].tuple.src. 828 ntohs(ct->tuplehash[!dir].tuple.src.
819 u.tcp.port)); 829 u.tcp.port));
820 if (ret < 0) 830 if (ret < 0)
821 return -1; 831 return -1;
822 } 832 }
823 833
824 if ((setup->options & eSetup_UUIE_sourceCallSignalAddress) && 834 if ((setup->options & eSetup_UUIE_sourceCallSignalAddress) &&
825 (set_h225_addr_hook) && 835 (set_h225_addr) &&
826 get_h225_addr(*data, &setup->sourceCallSignalAddress, &ip, &port) 836 get_h225_addr(*data, &setup->sourceCallSignalAddress, &ip, &port)
827 && ip != ct->tuplehash[!dir].tuple.dst.ip) { 837 && ip != ct->tuplehash[!dir].tuple.dst.ip) {
828 DEBUGP("ip_ct_q931: set sourceCallSignalAddress " 838 DEBUGP("ip_ct_q931: set sourceCallSignalAddress "
@@ -830,11 +840,11 @@ static int process_setup(struct sk_buff **pskb, struct ip_conntrack *ct,
830 NIPQUAD(ip), port, 840 NIPQUAD(ip), port,
831 NIPQUAD(ct->tuplehash[!dir].tuple.dst.ip), 841 NIPQUAD(ct->tuplehash[!dir].tuple.dst.ip),
832 ntohs(ct->tuplehash[!dir].tuple.dst.u.tcp.port)); 842 ntohs(ct->tuplehash[!dir].tuple.dst.u.tcp.port));
833 ret = set_h225_addr_hook(pskb, data, dataoff, 843 ret = set_h225_addr(pskb, data, dataoff,
834 &setup->sourceCallSignalAddress, 844 &setup->sourceCallSignalAddress,
835 ct->tuplehash[!dir].tuple.dst.ip, 845 ct->tuplehash[!dir].tuple.dst.ip,
836 ntohs(ct->tuplehash[!dir].tuple.dst. 846 ntohs(ct->tuplehash[!dir].tuple.dst.
837 u.tcp.port)); 847 u.tcp.port));
838 if (ret < 0) 848 if (ret < 0)
839 return -1; 849 return -1;
840 } 850 }
@@ -1153,7 +1163,7 @@ static struct ip_conntrack_helper ip_conntrack_helper_q931 = {
1153 .me = THIS_MODULE, 1163 .me = THIS_MODULE,
1154 .max_expected = H323_RTP_CHANNEL_MAX * 4 + 4 /* T.120 and H.245 */ , 1164 .max_expected = H323_RTP_CHANNEL_MAX * 4 + 4 /* T.120 and H.245 */ ,
1155 .timeout = 240, 1165 .timeout = 240,
1156 .tuple = {.src = {.u = {__constant_htons(Q931_PORT)}}, 1166 .tuple = {.src = {.u = {.tcp = {.port = __constant_htons(Q931_PORT)}}},
1157 .dst = {.protonum = IPPROTO_TCP}}, 1167 .dst = {.protonum = IPPROTO_TCP}},
1158 .mask = {.src = {.u = {0xFFFF}}, 1168 .mask = {.src = {.u = {0xFFFF}},
1159 .dst = {.protonum = 0xFF}}, 1169 .dst = {.protonum = 0xFF}},
@@ -1231,6 +1241,7 @@ static int expect_q931(struct sk_buff **pskb, struct ip_conntrack *ct,
1231 __be32 ip; 1241 __be32 ip;
1232 u_int16_t port; 1242 u_int16_t port;
1233 struct ip_conntrack_expect *exp; 1243 struct ip_conntrack_expect *exp;
1244 typeof(nat_q931_hook) nat_q931;
1234 1245
1235 /* Look for the first related address */ 1246 /* Look for the first related address */
1236 for (i = 0; i < count; i++) { 1247 for (i = 0; i < count; i++) {
@@ -1258,9 +1269,9 @@ static int expect_q931(struct sk_buff **pskb, struct ip_conntrack *ct,
1258 exp->mask.dst.protonum = 0xFF; 1269 exp->mask.dst.protonum = 0xFF;
1259 exp->flags = IP_CT_EXPECT_PERMANENT; /* Accept multiple calls */ 1270 exp->flags = IP_CT_EXPECT_PERMANENT; /* Accept multiple calls */
1260 1271
1261 if (nat_q931_hook) { /* Need NAT */ 1272 nat_q931 = rcu_dereference(nat_q931_hook);
1262 ret = nat_q931_hook(pskb, ct, ctinfo, data, addr, i, 1273 if (nat_q931) { /* Need NAT */
1263 port, exp); 1274 ret = nat_q931(pskb, ct, ctinfo, data, addr, i, port, exp);
1264 } else { /* Conntrack only */ 1275 } else { /* Conntrack only */
1265 exp->expectfn = ip_conntrack_q931_expect; 1276 exp->expectfn = ip_conntrack_q931_expect;
1266 1277
@@ -1288,11 +1299,14 @@ static int process_grq(struct sk_buff **pskb, struct ip_conntrack *ct,
1288 enum ip_conntrack_info ctinfo, 1299 enum ip_conntrack_info ctinfo,
1289 unsigned char **data, GatekeeperRequest * grq) 1300 unsigned char **data, GatekeeperRequest * grq)
1290{ 1301{
1302 typeof(set_ras_addr_hook) set_ras_addr;
1303
1291 DEBUGP("ip_ct_ras: GRQ\n"); 1304 DEBUGP("ip_ct_ras: GRQ\n");
1292 1305
1293 if (set_ras_addr_hook) /* NATed */ 1306 set_ras_addr = rcu_dereference(set_ras_addr_hook);
1294 return set_ras_addr_hook(pskb, ct, ctinfo, data, 1307 if (set_ras_addr) /* NATed */
1295 &grq->rasAddress, 1); 1308 return set_ras_addr(pskb, ct, ctinfo, data,
1309 &grq->rasAddress, 1);
1296 return 0; 1310 return 0;
1297} 1311}
1298 1312
@@ -1362,6 +1376,7 @@ static int process_rrq(struct sk_buff **pskb, struct ip_conntrack *ct,
1362{ 1376{
1363 struct ip_ct_h323_master *info = &ct->help.ct_h323_info; 1377 struct ip_ct_h323_master *info = &ct->help.ct_h323_info;
1364 int ret; 1378 int ret;
1379 typeof(set_ras_addr_hook) set_ras_addr;
1365 1380
1366 DEBUGP("ip_ct_ras: RRQ\n"); 1381 DEBUGP("ip_ct_ras: RRQ\n");
1367 1382
@@ -1371,10 +1386,11 @@ static int process_rrq(struct sk_buff **pskb, struct ip_conntrack *ct,
1371 if (ret < 0) 1386 if (ret < 0)
1372 return -1; 1387 return -1;
1373 1388
1374 if (set_ras_addr_hook) { 1389 set_ras_addr = rcu_dereference(set_ras_addr_hook);
1375 ret = set_ras_addr_hook(pskb, ct, ctinfo, data, 1390 if (set_ras_addr) {
1376 rrq->rasAddress.item, 1391 ret = set_ras_addr(pskb, ct, ctinfo, data,
1377 rrq->rasAddress.count); 1392 rrq->rasAddress.item,
1393 rrq->rasAddress.count);
1378 if (ret < 0) 1394 if (ret < 0)
1379 return -1; 1395 return -1;
1380 } 1396 }
@@ -1397,13 +1413,15 @@ static int process_rcf(struct sk_buff **pskb, struct ip_conntrack *ct,
1397 int dir = CTINFO2DIR(ctinfo); 1413 int dir = CTINFO2DIR(ctinfo);
1398 int ret; 1414 int ret;
1399 struct ip_conntrack_expect *exp; 1415 struct ip_conntrack_expect *exp;
1416 typeof(set_sig_addr_hook) set_sig_addr;
1400 1417
1401 DEBUGP("ip_ct_ras: RCF\n"); 1418 DEBUGP("ip_ct_ras: RCF\n");
1402 1419
1403 if (set_sig_addr_hook) { 1420 set_sig_addr = rcu_dereference(set_sig_addr_hook);
1404 ret = set_sig_addr_hook(pskb, ct, ctinfo, data, 1421 if (set_sig_addr) {
1405 rcf->callSignalAddress.item, 1422 ret = set_sig_addr(pskb, ct, ctinfo, data,
1406 rcf->callSignalAddress.count); 1423 rcf->callSignalAddress.item,
1424 rcf->callSignalAddress.count);
1407 if (ret < 0) 1425 if (ret < 0)
1408 return -1; 1426 return -1;
1409 } 1427 }
@@ -1448,13 +1466,15 @@ static int process_urq(struct sk_buff **pskb, struct ip_conntrack *ct,
1448 struct ip_ct_h323_master *info = &ct->help.ct_h323_info; 1466 struct ip_ct_h323_master *info = &ct->help.ct_h323_info;
1449 int dir = CTINFO2DIR(ctinfo); 1467 int dir = CTINFO2DIR(ctinfo);
1450 int ret; 1468 int ret;
1469 typeof(set_sig_addr_hook) set_sig_addr;
1451 1470
1452 DEBUGP("ip_ct_ras: URQ\n"); 1471 DEBUGP("ip_ct_ras: URQ\n");
1453 1472
1454 if (set_sig_addr_hook) { 1473 set_sig_addr = rcu_dereference(set_sig_addr_hook);
1455 ret = set_sig_addr_hook(pskb, ct, ctinfo, data, 1474 if (set_sig_addr) {
1456 urq->callSignalAddress.item, 1475 ret = set_sig_addr(pskb, ct, ctinfo, data,
1457 urq->callSignalAddress.count); 1476 urq->callSignalAddress.item,
1477 urq->callSignalAddress.count);
1458 if (ret < 0) 1478 if (ret < 0)
1459 return -1; 1479 return -1;
1460 } 1480 }
@@ -1479,28 +1499,30 @@ static int process_arq(struct sk_buff **pskb, struct ip_conntrack *ct,
1479 int dir = CTINFO2DIR(ctinfo); 1499 int dir = CTINFO2DIR(ctinfo);
1480 __be32 ip; 1500 __be32 ip;
1481 u_int16_t port; 1501 u_int16_t port;
1502 typeof(set_h225_addr_hook) set_h225_addr;
1482 1503
1483 DEBUGP("ip_ct_ras: ARQ\n"); 1504 DEBUGP("ip_ct_ras: ARQ\n");
1484 1505
1506 set_h225_addr = rcu_dereference(set_h225_addr_hook);
1485 if ((arq->options & eAdmissionRequest_destCallSignalAddress) && 1507 if ((arq->options & eAdmissionRequest_destCallSignalAddress) &&
1486 get_h225_addr(*data, &arq->destCallSignalAddress, &ip, &port) && 1508 get_h225_addr(*data, &arq->destCallSignalAddress, &ip, &port) &&
1487 ip == ct->tuplehash[dir].tuple.src.ip && 1509 ip == ct->tuplehash[dir].tuple.src.ip &&
1488 port == info->sig_port[dir] && set_h225_addr_hook) { 1510 port == info->sig_port[dir] && set_h225_addr) {
1489 /* Answering ARQ */ 1511 /* Answering ARQ */
1490 return set_h225_addr_hook(pskb, data, 0, 1512 return set_h225_addr(pskb, data, 0,
1491 &arq->destCallSignalAddress, 1513 &arq->destCallSignalAddress,
1492 ct->tuplehash[!dir].tuple.dst.ip, 1514 ct->tuplehash[!dir].tuple.dst.ip,
1493 info->sig_port[!dir]); 1515 info->sig_port[!dir]);
1494 } 1516 }
1495 1517
1496 if ((arq->options & eAdmissionRequest_srcCallSignalAddress) && 1518 if ((arq->options & eAdmissionRequest_srcCallSignalAddress) &&
1497 get_h225_addr(*data, &arq->srcCallSignalAddress, &ip, &port) && 1519 get_h225_addr(*data, &arq->srcCallSignalAddress, &ip, &port) &&
1498 ip == ct->tuplehash[dir].tuple.src.ip && set_h225_addr_hook) { 1520 ip == ct->tuplehash[dir].tuple.src.ip && set_h225_addr) {
1499 /* Calling ARQ */ 1521 /* Calling ARQ */
1500 return set_h225_addr_hook(pskb, data, 0, 1522 return set_h225_addr(pskb, data, 0,
1501 &arq->srcCallSignalAddress, 1523 &arq->srcCallSignalAddress,
1502 ct->tuplehash[!dir].tuple.dst.ip, 1524 ct->tuplehash[!dir].tuple.dst.ip,
1503 port); 1525 port);
1504 } 1526 }
1505 1527
1506 return 0; 1528 return 0;
@@ -1516,6 +1538,7 @@ static int process_acf(struct sk_buff **pskb, struct ip_conntrack *ct,
1516 __be32 ip; 1538 __be32 ip;
1517 u_int16_t port; 1539 u_int16_t port;
1518 struct ip_conntrack_expect *exp; 1540 struct ip_conntrack_expect *exp;
1541 typeof(set_sig_addr_hook) set_sig_addr;
1519 1542
1520 DEBUGP("ip_ct_ras: ACF\n"); 1543 DEBUGP("ip_ct_ras: ACF\n");
1521 1544
@@ -1523,10 +1546,10 @@ static int process_acf(struct sk_buff **pskb, struct ip_conntrack *ct,
1523 return 0; 1546 return 0;
1524 1547
1525 if (ip == ct->tuplehash[dir].tuple.dst.ip) { /* Answering ACF */ 1548 if (ip == ct->tuplehash[dir].tuple.dst.ip) { /* Answering ACF */
1526 if (set_sig_addr_hook) 1549 set_sig_addr = rcu_dereference(set_sig_addr_hook);
1527 return set_sig_addr_hook(pskb, ct, ctinfo, data, 1550 if (set_sig_addr)
1528 &acf->destCallSignalAddress, 1551 return set_sig_addr(pskb, ct, ctinfo, data,
1529 1); 1552 &acf->destCallSignalAddress, 1);
1530 return 0; 1553 return 0;
1531 } 1554 }
1532 1555
@@ -1566,11 +1589,14 @@ static int process_lrq(struct sk_buff **pskb, struct ip_conntrack *ct,
1566 enum ip_conntrack_info ctinfo, 1589 enum ip_conntrack_info ctinfo,
1567 unsigned char **data, LocationRequest * lrq) 1590 unsigned char **data, LocationRequest * lrq)
1568{ 1591{
1592 typeof(set_ras_addr_hook) set_ras_addr;
1593
1569 DEBUGP("ip_ct_ras: LRQ\n"); 1594 DEBUGP("ip_ct_ras: LRQ\n");
1570 1595
1571 if (set_ras_addr_hook) 1596 set_ras_addr = rcu_dereference(set_ras_addr_hook);
1572 return set_ras_addr_hook(pskb, ct, ctinfo, data, 1597 if (set_ras_addr)
1573 &lrq->replyAddress, 1); 1598 return set_ras_addr(pskb, ct, ctinfo, data,
1599 &lrq->replyAddress, 1);
1574 return 0; 1600 return 0;
1575} 1601}
1576 1602
@@ -1629,20 +1655,24 @@ static int process_irr(struct sk_buff **pskb, struct ip_conntrack *ct,
1629 unsigned char **data, InfoRequestResponse * irr) 1655 unsigned char **data, InfoRequestResponse * irr)
1630{ 1656{
1631 int ret; 1657 int ret;
1658 typeof(set_ras_addr_hook) set_ras_addr;
1659 typeof(set_sig_addr_hook) set_sig_addr;
1632 1660
1633 DEBUGP("ip_ct_ras: IRR\n"); 1661 DEBUGP("ip_ct_ras: IRR\n");
1634 1662
1635 if (set_ras_addr_hook) { 1663 set_ras_addr = rcu_dereference(set_ras_addr_hook);
1636 ret = set_ras_addr_hook(pskb, ct, ctinfo, data, 1664 if (set_ras_addr) {
1637 &irr->rasAddress, 1); 1665 ret = set_ras_addr(pskb, ct, ctinfo, data,
1666 &irr->rasAddress, 1);
1638 if (ret < 0) 1667 if (ret < 0)
1639 return -1; 1668 return -1;
1640 } 1669 }
1641 1670
1642 if (set_sig_addr_hook) { 1671 set_sig_addr = rcu_dereference(set_sig_addr_hook);
1643 ret = set_sig_addr_hook(pskb, ct, ctinfo, data, 1672 if (set_sig_addr) {
1644 irr->callSignalAddress.item, 1673 ret = set_sig_addr(pskb, ct, ctinfo, data,
1645 irr->callSignalAddress.count); 1674 irr->callSignalAddress.item,
1675 irr->callSignalAddress.count);
1646 if (ret < 0) 1676 if (ret < 0)
1647 return -1; 1677 return -1;
1648 } 1678 }
@@ -1746,7 +1776,7 @@ static struct ip_conntrack_helper ip_conntrack_helper_ras = {
1746 .me = THIS_MODULE, 1776 .me = THIS_MODULE,
1747 .max_expected = 32, 1777 .max_expected = 32,
1748 .timeout = 240, 1778 .timeout = 240,
1749 .tuple = {.src = {.u = {__constant_htons(RAS_PORT)}}, 1779 .tuple = {.src = {.u = {.tcp = {.port = __constant_htons(RAS_PORT)}}},
1750 .dst = {.protonum = IPPROTO_UDP}}, 1780 .dst = {.protonum = IPPROTO_UDP}},
1751 .mask = {.src = {.u = {0xFFFE}}, 1781 .mask = {.src = {.u = {0xFFFE}},
1752 .dst = {.protonum = 0xFF}}, 1782 .dst = {.protonum = 0xFF}},
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_pptp.c b/net/ipv4/netfilter/ip_conntrack_helper_pptp.c
index a2af5e0c7f..4d19373bbf 100644
--- a/net/ipv4/netfilter/ip_conntrack_helper_pptp.c
+++ b/net/ipv4/netfilter/ip_conntrack_helper_pptp.c
@@ -124,6 +124,8 @@ EXPORT_SYMBOL(pptp_msg_name);
124static void pptp_expectfn(struct ip_conntrack *ct, 124static void pptp_expectfn(struct ip_conntrack *ct,
125 struct ip_conntrack_expect *exp) 125 struct ip_conntrack_expect *exp)
126{ 126{
127 typeof(ip_nat_pptp_hook_expectfn) ip_nat_pptp_expectfn;
128
127 DEBUGP("increasing timeouts\n"); 129 DEBUGP("increasing timeouts\n");
128 130
129 /* increase timeout of GRE data channel conntrack entry */ 131 /* increase timeout of GRE data channel conntrack entry */
@@ -133,7 +135,9 @@ static void pptp_expectfn(struct ip_conntrack *ct,
133 /* Can you see how rusty this code is, compared with the pre-2.6.11 135 /* Can you see how rusty this code is, compared with the pre-2.6.11
134 * one? That's what happened to my shiny newnat of 2002 ;( -HW */ 136 * one? That's what happened to my shiny newnat of 2002 ;( -HW */
135 137
136 if (!ip_nat_pptp_hook_expectfn) { 138 rcu_read_lock();
139 ip_nat_pptp_expectfn = rcu_dereference(ip_nat_pptp_hook_expectfn);
140 if (!ip_nat_pptp_expectfn) {
137 struct ip_conntrack_tuple inv_t; 141 struct ip_conntrack_tuple inv_t;
138 struct ip_conntrack_expect *exp_other; 142 struct ip_conntrack_expect *exp_other;
139 143
@@ -142,7 +146,7 @@ static void pptp_expectfn(struct ip_conntrack *ct,
142 DEBUGP("trying to unexpect other dir: "); 146 DEBUGP("trying to unexpect other dir: ");
143 DUMP_TUPLE(&inv_t); 147 DUMP_TUPLE(&inv_t);
144 148
145 exp_other = ip_conntrack_expect_find(&inv_t); 149 exp_other = ip_conntrack_expect_find_get(&inv_t);
146 if (exp_other) { 150 if (exp_other) {
147 /* delete other expectation. */ 151 /* delete other expectation. */
148 DEBUGP("found\n"); 152 DEBUGP("found\n");
@@ -153,8 +157,9 @@ static void pptp_expectfn(struct ip_conntrack *ct,
153 } 157 }
154 } else { 158 } else {
155 /* we need more than simple inversion */ 159 /* we need more than simple inversion */
156 ip_nat_pptp_hook_expectfn(ct, exp); 160 ip_nat_pptp_expectfn(ct, exp);
157 } 161 }
162 rcu_read_unlock();
158} 163}
159 164
160static int destroy_sibling_or_exp(const struct ip_conntrack_tuple *t) 165static int destroy_sibling_or_exp(const struct ip_conntrack_tuple *t)
@@ -176,7 +181,7 @@ static int destroy_sibling_or_exp(const struct ip_conntrack_tuple *t)
176 ip_conntrack_put(sibling); 181 ip_conntrack_put(sibling);
177 return 1; 182 return 1;
178 } else { 183 } else {
179 exp = ip_conntrack_expect_find(t); 184 exp = ip_conntrack_expect_find_get(t);
180 if (exp) { 185 if (exp) {
181 DEBUGP("unexpect_related of expect %p\n", exp); 186 DEBUGP("unexpect_related of expect %p\n", exp);
182 ip_conntrack_unexpect_related(exp); 187 ip_conntrack_unexpect_related(exp);
@@ -226,6 +231,7 @@ exp_gre(struct ip_conntrack *ct,
226{ 231{
227 struct ip_conntrack_expect *exp_orig, *exp_reply; 232 struct ip_conntrack_expect *exp_orig, *exp_reply;
228 int ret = 1; 233 int ret = 1;
234 typeof(ip_nat_pptp_hook_exp_gre) ip_nat_pptp_exp_gre;
229 235
230 exp_orig = ip_conntrack_expect_alloc(ct); 236 exp_orig = ip_conntrack_expect_alloc(ct);
231 if (exp_orig == NULL) 237 if (exp_orig == NULL)
@@ -262,8 +268,9 @@ exp_gre(struct ip_conntrack *ct,
262 exp_reply->tuple.dst.u.gre.key = peer_callid; 268 exp_reply->tuple.dst.u.gre.key = peer_callid;
263 exp_reply->tuple.dst.protonum = IPPROTO_GRE; 269 exp_reply->tuple.dst.protonum = IPPROTO_GRE;
264 270
265 if (ip_nat_pptp_hook_exp_gre) 271 ip_nat_pptp_exp_gre = rcu_dereference(ip_nat_pptp_hook_exp_gre);
266 ip_nat_pptp_hook_exp_gre(exp_orig, exp_reply); 272 if (ip_nat_pptp_exp_gre)
273 ip_nat_pptp_exp_gre(exp_orig, exp_reply);
267 if (ip_conntrack_expect_related(exp_orig) != 0) 274 if (ip_conntrack_expect_related(exp_orig) != 0)
268 goto out_put_both; 275 goto out_put_both;
269 if (ip_conntrack_expect_related(exp_reply) != 0) 276 if (ip_conntrack_expect_related(exp_reply) != 0)
@@ -303,6 +310,7 @@ pptp_inbound_pkt(struct sk_buff **pskb,
303 struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info; 310 struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info;
304 u_int16_t msg; 311 u_int16_t msg;
305 __be16 cid = 0, pcid = 0; 312 __be16 cid = 0, pcid = 0;
313 typeof(ip_nat_pptp_hook_inbound) ip_nat_pptp_inbound;
306 314
307 msg = ntohs(ctlh->messageType); 315 msg = ntohs(ctlh->messageType);
308 DEBUGP("inbound control message %s\n", pptp_msg_name[msg]); 316 DEBUGP("inbound control message %s\n", pptp_msg_name[msg]);
@@ -402,9 +410,9 @@ pptp_inbound_pkt(struct sk_buff **pskb,
402 goto invalid; 410 goto invalid;
403 } 411 }
404 412
405 if (ip_nat_pptp_hook_inbound) 413 ip_nat_pptp_inbound = rcu_dereference(ip_nat_pptp_hook_inbound);
406 return ip_nat_pptp_hook_inbound(pskb, ct, ctinfo, ctlh, 414 if (ip_nat_pptp_inbound)
407 pptpReq); 415 return ip_nat_pptp_inbound(pskb, ct, ctinfo, ctlh, pptpReq);
408 return NF_ACCEPT; 416 return NF_ACCEPT;
409 417
410invalid: 418invalid:
@@ -427,6 +435,7 @@ pptp_outbound_pkt(struct sk_buff **pskb,
427 struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info; 435 struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info;
428 u_int16_t msg; 436 u_int16_t msg;
429 __be16 cid = 0, pcid = 0; 437 __be16 cid = 0, pcid = 0;
438 typeof(ip_nat_pptp_hook_outbound) ip_nat_pptp_outbound;
430 439
431 msg = ntohs(ctlh->messageType); 440 msg = ntohs(ctlh->messageType);
432 DEBUGP("outbound control message %s\n", pptp_msg_name[msg]); 441 DEBUGP("outbound control message %s\n", pptp_msg_name[msg]);
@@ -492,9 +501,9 @@ pptp_outbound_pkt(struct sk_buff **pskb,
492 goto invalid; 501 goto invalid;
493 } 502 }
494 503
495 if (ip_nat_pptp_hook_outbound) 504 ip_nat_pptp_outbound = rcu_dereference(ip_nat_pptp_hook_outbound);
496 return ip_nat_pptp_hook_outbound(pskb, ct, ctinfo, ctlh, 505 if (ip_nat_pptp_outbound)
497 pptpReq); 506 return ip_nat_pptp_outbound(pskb, ct, ctinfo, ctlh, pptpReq);
498 return NF_ACCEPT; 507 return NF_ACCEPT;
499 508
500invalid: 509invalid:
diff --git a/net/ipv4/netfilter/ip_conntrack_irc.c b/net/ipv4/netfilter/ip_conntrack_irc.c
index 75f7c3db16..91832eca41 100644
--- a/net/ipv4/netfilter/ip_conntrack_irc.c
+++ b/net/ipv4/netfilter/ip_conntrack_irc.c
@@ -114,6 +114,7 @@ static int help(struct sk_buff **pskb,
114 u_int16_t dcc_port; 114 u_int16_t dcc_port;
115 int i, ret = NF_ACCEPT; 115 int i, ret = NF_ACCEPT;
116 char *addr_beg_p, *addr_end_p; 116 char *addr_beg_p, *addr_end_p;
117 typeof(ip_nat_irc_hook) ip_nat_irc;
117 118
118 DEBUGP("entered\n"); 119 DEBUGP("entered\n");
119 120
@@ -222,11 +223,12 @@ static int help(struct sk_buff **pskb,
222 { .tcp = { htons(0xFFFF) } }, 0xFF }}); 223 { .tcp = { htons(0xFFFF) } }, 0xFF }});
223 exp->expectfn = NULL; 224 exp->expectfn = NULL;
224 exp->flags = 0; 225 exp->flags = 0;
225 if (ip_nat_irc_hook) 226 ip_nat_irc = rcu_dereference(ip_nat_irc_hook);
226 ret = ip_nat_irc_hook(pskb, ctinfo, 227 if (ip_nat_irc)
227 addr_beg_p - ib_ptr, 228 ret = ip_nat_irc(pskb, ctinfo,
228 addr_end_p - addr_beg_p, 229 addr_beg_p - ib_ptr,
229 exp); 230 addr_end_p - addr_beg_p,
231 exp);
230 else if (ip_conntrack_expect_related(exp) != 0) 232 else if (ip_conntrack_expect_related(exp) != 0)
231 ret = NF_DROP; 233 ret = NF_DROP;
232 ip_conntrack_expect_put(exp); 234 ip_conntrack_expect_put(exp);
diff --git a/net/ipv4/netfilter/ip_conntrack_netlink.c b/net/ipv4/netfilter/ip_conntrack_netlink.c
index 55f0ae6410..5fcf91d617 100644
--- a/net/ipv4/netfilter/ip_conntrack_netlink.c
+++ b/net/ipv4/netfilter/ip_conntrack_netlink.c
@@ -320,8 +320,6 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
320 } else if (events & (IPCT_NEW | IPCT_RELATED)) { 320 } else if (events & (IPCT_NEW | IPCT_RELATED)) {
321 type = IPCTNL_MSG_CT_NEW; 321 type = IPCTNL_MSG_CT_NEW;
322 flags = NLM_F_CREATE|NLM_F_EXCL; 322 flags = NLM_F_CREATE|NLM_F_EXCL;
323 /* dump everything */
324 events = ~0UL;
325 group = NFNLGRP_CONNTRACK_NEW; 323 group = NFNLGRP_CONNTRACK_NEW;
326 } else if (events & (IPCT_STATUS | IPCT_PROTOINFO)) { 324 } else if (events & (IPCT_STATUS | IPCT_PROTOINFO)) {
327 type = IPCTNL_MSG_CT_NEW; 325 type = IPCTNL_MSG_CT_NEW;
@@ -356,28 +354,35 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
356 if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_REPLY)) < 0) 354 if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_REPLY)) < 0)
357 goto nfattr_failure; 355 goto nfattr_failure;
358 NFA_NEST_END(skb, nest_parms); 356 NFA_NEST_END(skb, nest_parms);
359
360 /* NAT stuff is now a status flag */
361 if ((events & IPCT_STATUS || events & IPCT_NATINFO)
362 && ctnetlink_dump_status(skb, ct) < 0)
363 goto nfattr_failure;
364 if (events & IPCT_REFRESH
365 && ctnetlink_dump_timeout(skb, ct) < 0)
366 goto nfattr_failure;
367 if (events & IPCT_PROTOINFO
368 && ctnetlink_dump_protoinfo(skb, ct) < 0)
369 goto nfattr_failure;
370 if (events & IPCT_HELPINFO
371 && ctnetlink_dump_helpinfo(skb, ct) < 0)
372 goto nfattr_failure;
373 357
374 if (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 || 358 if (events & IPCT_DESTROY) {
375 ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0) 359 if (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 ||
376 goto nfattr_failure; 360 ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0)
361 goto nfattr_failure;
362 } else {
363 if (ctnetlink_dump_status(skb, ct) < 0)
364 goto nfattr_failure;
377 365
378 if (events & IPCT_MARK 366 if (ctnetlink_dump_timeout(skb, ct) < 0)
379 && ctnetlink_dump_mark(skb, ct) < 0) 367 goto nfattr_failure;
380 goto nfattr_failure; 368
369 if (events & IPCT_PROTOINFO
370 && ctnetlink_dump_protoinfo(skb, ct) < 0)
371 goto nfattr_failure;
372
373 if ((events & IPCT_HELPER || ct->helper)
374 && ctnetlink_dump_helpinfo(skb, ct) < 0)
375 goto nfattr_failure;
376
377 if ((events & IPCT_MARK || ct->mark)
378 && ctnetlink_dump_mark(skb, ct) < 0)
379 goto nfattr_failure;
380
381 if (events & IPCT_COUNTER_FILLING &&
382 (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 ||
383 ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0))
384 goto nfattr_failure;
385 }
381 386
382 nlh->nlmsg_len = skb->tail - b; 387 nlh->nlmsg_len = skb->tail - b;
383 nfnetlink_send(skb, 0, group, 0); 388 nfnetlink_send(skb, 0, group, 0);
@@ -743,7 +748,6 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
743 ip_conntrack_put(ct); 748 ip_conntrack_put(ct);
744 return -ENOMEM; 749 return -ENOMEM;
745 } 750 }
746 NETLINK_CB(skb2).dst_pid = NETLINK_CB(skb).pid;
747 751
748 err = ctnetlink_fill_info(skb2, NETLINK_CB(skb).pid, nlh->nlmsg_seq, 752 err = ctnetlink_fill_info(skb2, NETLINK_CB(skb).pid, nlh->nlmsg_seq,
749 IPCTNL_MSG_CT_NEW, 1, ct); 753 IPCTNL_MSG_CT_NEW, 1, ct);
@@ -946,9 +950,11 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
946 ct->timeout.expires = jiffies + ct->timeout.expires * HZ; 950 ct->timeout.expires = jiffies + ct->timeout.expires * HZ;
947 ct->status |= IPS_CONFIRMED; 951 ct->status |= IPS_CONFIRMED;
948 952
949 err = ctnetlink_change_status(ct, cda); 953 if (cda[CTA_STATUS-1]) {
950 if (err < 0) 954 err = ctnetlink_change_status(ct, cda);
951 goto err; 955 if (err < 0)
956 goto err;
957 }
952 958
953 if (cda[CTA_PROTOINFO-1]) { 959 if (cda[CTA_PROTOINFO-1]) {
954 err = ctnetlink_change_protoinfo(ct, cda); 960 err = ctnetlink_change_protoinfo(ct, cda);
@@ -1257,7 +1263,7 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
1257 if (err < 0) 1263 if (err < 0)
1258 return err; 1264 return err;
1259 1265
1260 exp = ip_conntrack_expect_find(&tuple); 1266 exp = ip_conntrack_expect_find_get(&tuple);
1261 if (!exp) 1267 if (!exp)
1262 return -ENOENT; 1268 return -ENOENT;
1263 1269
@@ -1273,8 +1279,7 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
1273 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 1279 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
1274 if (!skb2) 1280 if (!skb2)
1275 goto out; 1281 goto out;
1276 NETLINK_CB(skb2).dst_pid = NETLINK_CB(skb).pid; 1282
1277
1278 err = ctnetlink_exp_fill_info(skb2, NETLINK_CB(skb).pid, 1283 err = ctnetlink_exp_fill_info(skb2, NETLINK_CB(skb).pid,
1279 nlh->nlmsg_seq, IPCTNL_MSG_EXP_NEW, 1284 nlh->nlmsg_seq, IPCTNL_MSG_EXP_NEW,
1280 1, exp); 1285 1, exp);
@@ -1311,7 +1316,7 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1311 return err; 1316 return err;
1312 1317
1313 /* bump usage count to 2 */ 1318 /* bump usage count to 2 */
1314 exp = ip_conntrack_expect_find(&tuple); 1319 exp = ip_conntrack_expect_find_get(&tuple);
1315 if (!exp) 1320 if (!exp)
1316 return -ENOENT; 1321 return -ENOENT;
1317 1322
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_gre.c b/net/ipv4/netfilter/ip_conntrack_proto_gre.c
index 5fe026f467..ac1c49ef36 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_gre.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_gre.c
@@ -34,8 +34,6 @@
34#include <linux/interrupt.h> 34#include <linux/interrupt.h>
35 35
36static DEFINE_RWLOCK(ip_ct_gre_lock); 36static DEFINE_RWLOCK(ip_ct_gre_lock);
37#define ASSERT_READ_LOCK(x)
38#define ASSERT_WRITE_LOCK(x)
39 37
40#include <linux/netfilter_ipv4/ip_conntrack_protocol.h> 38#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
41#include <linux/netfilter_ipv4/ip_conntrack_helper.h> 39#include <linux/netfilter_ipv4/ip_conntrack_helper.h>
diff --git a/net/ipv4/netfilter/ip_conntrack_sip.c b/net/ipv4/netfilter/ip_conntrack_sip.c
index f4f75995a9..3a26d63eed 100644
--- a/net/ipv4/netfilter/ip_conntrack_sip.c
+++ b/net/ipv4/netfilter/ip_conntrack_sip.c
@@ -52,20 +52,56 @@ unsigned int (*ip_nat_sdp_hook)(struct sk_buff **pskb,
52 const char *dptr); 52 const char *dptr);
53EXPORT_SYMBOL_GPL(ip_nat_sdp_hook); 53EXPORT_SYMBOL_GPL(ip_nat_sdp_hook);
54 54
55int ct_sip_get_info(const char *dptr, size_t dlen,
56 unsigned int *matchoff,
57 unsigned int *matchlen,
58 struct sip_header_nfo *hnfo);
59EXPORT_SYMBOL_GPL(ct_sip_get_info);
60
61
62static int digits_len(const char *dptr, const char *limit, int *shift); 55static int digits_len(const char *dptr, const char *limit, int *shift);
63static int epaddr_len(const char *dptr, const char *limit, int *shift); 56static int epaddr_len(const char *dptr, const char *limit, int *shift);
64static int skp_digits_len(const char *dptr, const char *limit, int *shift); 57static int skp_digits_len(const char *dptr, const char *limit, int *shift);
65static int skp_epaddr_len(const char *dptr, const char *limit, int *shift); 58static int skp_epaddr_len(const char *dptr, const char *limit, int *shift);
66 59
67struct sip_header_nfo ct_sip_hdrs[] = { 60struct sip_header_nfo {
68 { /* Via header */ 61 const char *lname;
62 const char *sname;
63 const char *ln_str;
64 size_t lnlen;
65 size_t snlen;
66 size_t ln_strlen;
67 int case_sensitive;
68 int (*match_len)(const char *, const char *, int *);
69};
70
71static struct sip_header_nfo ct_sip_hdrs[] = {
72 [POS_REG_REQ_URI] = { /* SIP REGISTER request URI */
73 .lname = "sip:",
74 .lnlen = sizeof("sip:") - 1,
75 .ln_str = ":",
76 .ln_strlen = sizeof(":") - 1,
77 .match_len = epaddr_len
78 },
79 [POS_REQ_URI] = { /* SIP request URI */
80 .lname = "sip:",
81 .lnlen = sizeof("sip:") - 1,
82 .ln_str = "@",
83 .ln_strlen = sizeof("@") - 1,
84 .match_len = epaddr_len
85 },
86 [POS_FROM] = { /* SIP From header */
87 .lname = "From:",
88 .lnlen = sizeof("From:") - 1,
89 .sname = "\r\nf:",
90 .snlen = sizeof("\r\nf:") - 1,
91 .ln_str = "sip:",
92 .ln_strlen = sizeof("sip:") - 1,
93 .match_len = skp_epaddr_len,
94 },
95 [POS_TO] = { /* SIP To header */
96 .lname = "To:",
97 .lnlen = sizeof("To:") - 1,
98 .sname = "\r\nt:",
99 .snlen = sizeof("\r\nt:") - 1,
100 .ln_str = "sip:",
101 .ln_strlen = sizeof("sip:") - 1,
102 .match_len = skp_epaddr_len,
103 },
104 [POS_VIA] = { /* SIP Via header */
69 .lname = "Via:", 105 .lname = "Via:",
70 .lnlen = sizeof("Via:") - 1, 106 .lnlen = sizeof("Via:") - 1,
71 .sname = "\r\nv:", 107 .sname = "\r\nv:",
@@ -74,7 +110,7 @@ struct sip_header_nfo ct_sip_hdrs[] = {
74 .ln_strlen = sizeof("UDP ") - 1, 110 .ln_strlen = sizeof("UDP ") - 1,
75 .match_len = epaddr_len, 111 .match_len = epaddr_len,
76 }, 112 },
77 { /* Contact header */ 113 [POS_CONTACT] = { /* SIP Contact header */
78 .lname = "Contact:", 114 .lname = "Contact:",
79 .lnlen = sizeof("Contact:") - 1, 115 .lnlen = sizeof("Contact:") - 1,
80 .sname = "\r\nm:", 116 .sname = "\r\nm:",
@@ -83,7 +119,7 @@ struct sip_header_nfo ct_sip_hdrs[] = {
83 .ln_strlen = sizeof("sip:") - 1, 119 .ln_strlen = sizeof("sip:") - 1,
84 .match_len = skp_epaddr_len 120 .match_len = skp_epaddr_len
85 }, 121 },
86 { /* Content length header */ 122 [POS_CONTENT] = { /* SIP Content length header */
87 .lname = "Content-Length:", 123 .lname = "Content-Length:",
88 .lnlen = sizeof("Content-Length:") - 1, 124 .lnlen = sizeof("Content-Length:") - 1,
89 .sname = "\r\nl:", 125 .sname = "\r\nl:",
@@ -92,7 +128,8 @@ struct sip_header_nfo ct_sip_hdrs[] = {
92 .ln_strlen = sizeof(":") - 1, 128 .ln_strlen = sizeof(":") - 1,
93 .match_len = skp_digits_len 129 .match_len = skp_digits_len
94 }, 130 },
95 { /* SDP media info */ 131 [POS_MEDIA] = { /* SDP media info */
132 .case_sensitive = 1,
96 .lname = "\nm=", 133 .lname = "\nm=",
97 .lnlen = sizeof("\nm=") - 1, 134 .lnlen = sizeof("\nm=") - 1,
98 .sname = "\rm=", 135 .sname = "\rm=",
@@ -101,7 +138,8 @@ struct sip_header_nfo ct_sip_hdrs[] = {
101 .ln_strlen = sizeof("audio ") - 1, 138 .ln_strlen = sizeof("audio ") - 1,
102 .match_len = digits_len 139 .match_len = digits_len
103 }, 140 },
104 { /* SDP owner address*/ 141 [POS_OWNER] = { /* SDP owner address*/
142 .case_sensitive = 1,
105 .lname = "\no=", 143 .lname = "\no=",
106 .lnlen = sizeof("\no=") - 1, 144 .lnlen = sizeof("\no=") - 1,
107 .sname = "\ro=", 145 .sname = "\ro=",
@@ -110,7 +148,8 @@ struct sip_header_nfo ct_sip_hdrs[] = {
110 .ln_strlen = sizeof("IN IP4 ") - 1, 148 .ln_strlen = sizeof("IN IP4 ") - 1,
111 .match_len = epaddr_len 149 .match_len = epaddr_len
112 }, 150 },
113 { /* SDP connection info */ 151 [POS_CONNECTION] = { /* SDP connection info */
152 .case_sensitive = 1,
114 .lname = "\nc=", 153 .lname = "\nc=",
115 .lnlen = sizeof("\nc=") - 1, 154 .lnlen = sizeof("\nc=") - 1,
116 .sname = "\rc=", 155 .sname = "\rc=",
@@ -119,16 +158,8 @@ struct sip_header_nfo ct_sip_hdrs[] = {
119 .ln_strlen = sizeof("IN IP4 ") - 1, 158 .ln_strlen = sizeof("IN IP4 ") - 1,
120 .match_len = epaddr_len 159 .match_len = epaddr_len
121 }, 160 },
122 { /* Requests headers */ 161 [POS_SDP_HEADER] = { /* SDP version header */
123 .lname = "sip:", 162 .case_sensitive = 1,
124 .lnlen = sizeof("sip:") - 1,
125 .sname = "sip:",
126 .snlen = sizeof("sip:") - 1, /* yes, i know.. ;) */
127 .ln_str = "@",
128 .ln_strlen = sizeof("@") - 1,
129 .match_len = epaddr_len
130 },
131 { /* SDP version header */
132 .lname = "\nv=", 163 .lname = "\nv=",
133 .lnlen = sizeof("\nv=") - 1, 164 .lnlen = sizeof("\nv=") - 1,
134 .sname = "\rv=", 165 .sname = "\rv=",
@@ -138,7 +169,6 @@ struct sip_header_nfo ct_sip_hdrs[] = {
138 .match_len = digits_len 169 .match_len = digits_len
139 } 170 }
140}; 171};
141EXPORT_SYMBOL_GPL(ct_sip_hdrs);
142 172
143/* get line lenght until first CR or LF seen. */ 173/* get line lenght until first CR or LF seen. */
144int ct_sip_lnlen(const char *line, const char *limit) 174int ct_sip_lnlen(const char *line, const char *limit)
@@ -159,13 +189,19 @@ EXPORT_SYMBOL_GPL(ct_sip_lnlen);
159 189
160/* Linear string search, case sensitive. */ 190/* Linear string search, case sensitive. */
161const char *ct_sip_search(const char *needle, const char *haystack, 191const char *ct_sip_search(const char *needle, const char *haystack,
162 size_t needle_len, size_t haystack_len) 192 size_t needle_len, size_t haystack_len,
193 int case_sensitive)
163{ 194{
164 const char *limit = haystack + (haystack_len - needle_len); 195 const char *limit = haystack + (haystack_len - needle_len);
165 196
166 while (haystack <= limit) { 197 while (haystack <= limit) {
167 if (memcmp(haystack, needle, needle_len) == 0) 198 if (case_sensitive) {
168 return haystack; 199 if (strncmp(haystack, needle, needle_len) == 0)
200 return haystack;
201 } else {
202 if (strnicmp(haystack, needle, needle_len) == 0)
203 return haystack;
204 }
169 haystack++; 205 haystack++;
170 } 206 }
171 return NULL; 207 return NULL;
@@ -263,8 +299,9 @@ static int skp_epaddr_len(const char *dptr, const char *limit, int *shift)
263int ct_sip_get_info(const char *dptr, size_t dlen, 299int ct_sip_get_info(const char *dptr, size_t dlen,
264 unsigned int *matchoff, 300 unsigned int *matchoff,
265 unsigned int *matchlen, 301 unsigned int *matchlen,
266 struct sip_header_nfo *hnfo) 302 enum sip_header_pos pos)
267{ 303{
304 struct sip_header_nfo *hnfo = &ct_sip_hdrs[pos];
268 const char *limit, *aux, *k = dptr; 305 const char *limit, *aux, *k = dptr;
269 int shift = 0; 306 int shift = 0;
270 307
@@ -272,12 +309,14 @@ int ct_sip_get_info(const char *dptr, size_t dlen,
272 309
273 while (dptr <= limit) { 310 while (dptr <= limit) {
274 if ((strncmp(dptr, hnfo->lname, hnfo->lnlen) != 0) && 311 if ((strncmp(dptr, hnfo->lname, hnfo->lnlen) != 0) &&
275 (strncmp(dptr, hnfo->sname, hnfo->snlen) != 0)) { 312 (hnfo->sname == NULL ||
313 strncmp(dptr, hnfo->sname, hnfo->snlen) != 0)) {
276 dptr++; 314 dptr++;
277 continue; 315 continue;
278 } 316 }
279 aux = ct_sip_search(hnfo->ln_str, dptr, hnfo->ln_strlen, 317 aux = ct_sip_search(hnfo->ln_str, dptr, hnfo->ln_strlen,
280 ct_sip_lnlen(dptr, limit)); 318 ct_sip_lnlen(dptr, limit),
319 hnfo->case_sensitive);
281 if (!aux) { 320 if (!aux) {
282 DEBUGP("'%s' not found in '%s'.\n", hnfo->ln_str, 321 DEBUGP("'%s' not found in '%s'.\n", hnfo->ln_str,
283 hnfo->lname); 322 hnfo->lname);
@@ -298,6 +337,7 @@ int ct_sip_get_info(const char *dptr, size_t dlen,
298 DEBUGP("%s header not found.\n", hnfo->lname); 337 DEBUGP("%s header not found.\n", hnfo->lname);
299 return 0; 338 return 0;
300} 339}
340EXPORT_SYMBOL_GPL(ct_sip_get_info);
301 341
302static int set_expected_rtp(struct sk_buff **pskb, 342static int set_expected_rtp(struct sk_buff **pskb,
303 struct ip_conntrack *ct, 343 struct ip_conntrack *ct,
@@ -308,6 +348,7 @@ static int set_expected_rtp(struct sk_buff **pskb,
308 struct ip_conntrack_expect *exp; 348 struct ip_conntrack_expect *exp;
309 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 349 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
310 int ret; 350 int ret;
351 typeof(ip_nat_sdp_hook) ip_nat_sdp;
311 352
312 exp = ip_conntrack_expect_alloc(ct); 353 exp = ip_conntrack_expect_alloc(ct);
313 if (exp == NULL) 354 if (exp == NULL)
@@ -328,8 +369,9 @@ static int set_expected_rtp(struct sk_buff **pskb,
328 exp->expectfn = NULL; 369 exp->expectfn = NULL;
329 exp->flags = 0; 370 exp->flags = 0;
330 371
331 if (ip_nat_sdp_hook) 372 ip_nat_sdp = rcu_dereference(ip_nat_sdp_hook);
332 ret = ip_nat_sdp_hook(pskb, ctinfo, exp, dptr); 373 if (ip_nat_sdp)
374 ret = ip_nat_sdp(pskb, ctinfo, exp, dptr);
333 else { 375 else {
334 if (ip_conntrack_expect_related(exp) != 0) 376 if (ip_conntrack_expect_related(exp) != 0)
335 ret = NF_DROP; 377 ret = NF_DROP;
@@ -351,6 +393,7 @@ static int sip_help(struct sk_buff **pskb,
351 int matchoff, matchlen; 393 int matchoff, matchlen;
352 __be32 ipaddr; 394 __be32 ipaddr;
353 u_int16_t port; 395 u_int16_t port;
396 typeof(ip_nat_sip_hook) ip_nat_sip;
354 397
355 /* No Data ? */ 398 /* No Data ? */
356 dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr); 399 dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);
@@ -368,8 +411,9 @@ static int sip_help(struct sk_buff **pskb,
368 goto out; 411 goto out;
369 } 412 }
370 413
371 if (ip_nat_sip_hook) { 414 ip_nat_sip = rcu_dereference(ip_nat_sip_hook);
372 if (!ip_nat_sip_hook(pskb, ctinfo, ct, &dptr)) { 415 if (ip_nat_sip) {
416 if (!ip_nat_sip(pskb, ctinfo, ct, &dptr)) {
373 ret = NF_DROP; 417 ret = NF_DROP;
374 goto out; 418 goto out;
375 } 419 }
@@ -389,7 +433,7 @@ static int sip_help(struct sk_buff **pskb,
389 } 433 }
390 /* Get ip and port address from SDP packet. */ 434 /* Get ip and port address from SDP packet. */
391 if (ct_sip_get_info(dptr, datalen, &matchoff, &matchlen, 435 if (ct_sip_get_info(dptr, datalen, &matchoff, &matchlen,
392 &ct_sip_hdrs[POS_CONNECTION]) > 0) { 436 POS_CONNECTION) > 0) {
393 437
394 /* We'll drop only if there are parse problems. */ 438 /* We'll drop only if there are parse problems. */
395 if (parse_ipaddr(dptr + matchoff, NULL, &ipaddr, 439 if (parse_ipaddr(dptr + matchoff, NULL, &ipaddr,
@@ -398,7 +442,7 @@ static int sip_help(struct sk_buff **pskb,
398 goto out; 442 goto out;
399 } 443 }
400 if (ct_sip_get_info(dptr, datalen, &matchoff, &matchlen, 444 if (ct_sip_get_info(dptr, datalen, &matchoff, &matchlen,
401 &ct_sip_hdrs[POS_MEDIA]) > 0) { 445 POS_MEDIA) > 0) {
402 446
403 port = simple_strtoul(dptr + matchoff, NULL, 10); 447 port = simple_strtoul(dptr + matchoff, NULL, 10);
404 if (port < 1024) { 448 if (port < 1024) {
diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
index 0213575656..86efb54496 100644
--- a/net/ipv4/netfilter/ip_conntrack_standalone.c
+++ b/net/ipv4/netfilter/ip_conntrack_standalone.c
@@ -28,9 +28,6 @@
28#include <net/ip.h> 28#include <net/ip.h>
29#include <net/route.h> 29#include <net/route.h>
30 30
31#define ASSERT_READ_LOCK(x)
32#define ASSERT_WRITE_LOCK(x)
33
34#include <linux/netfilter_ipv4/ip_conntrack.h> 31#include <linux/netfilter_ipv4/ip_conntrack.h>
35#include <linux/netfilter_ipv4/ip_conntrack_protocol.h> 32#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
36#include <linux/netfilter_ipv4/ip_conntrack_core.h> 33#include <linux/netfilter_ipv4/ip_conntrack_core.h>
@@ -139,7 +136,6 @@ static int ct_seq_show(struct seq_file *s, void *v)
139 const struct ip_conntrack *conntrack = tuplehash_to_ctrack(hash); 136 const struct ip_conntrack *conntrack = tuplehash_to_ctrack(hash);
140 struct ip_conntrack_protocol *proto; 137 struct ip_conntrack_protocol *proto;
141 138
142 ASSERT_READ_LOCK(&ip_conntrack_lock);
143 IP_NF_ASSERT(conntrack); 139 IP_NF_ASSERT(conntrack);
144 140
145 /* we only want to print DIR_ORIGINAL */ 141 /* we only want to print DIR_ORIGINAL */
@@ -926,7 +922,7 @@ EXPORT_SYMBOL(__ip_ct_refresh_acct);
926EXPORT_SYMBOL(ip_conntrack_expect_alloc); 922EXPORT_SYMBOL(ip_conntrack_expect_alloc);
927EXPORT_SYMBOL(ip_conntrack_expect_put); 923EXPORT_SYMBOL(ip_conntrack_expect_put);
928EXPORT_SYMBOL_GPL(__ip_conntrack_expect_find); 924EXPORT_SYMBOL_GPL(__ip_conntrack_expect_find);
929EXPORT_SYMBOL_GPL(ip_conntrack_expect_find); 925EXPORT_SYMBOL_GPL(ip_conntrack_expect_find_get);
930EXPORT_SYMBOL(ip_conntrack_expect_related); 926EXPORT_SYMBOL(ip_conntrack_expect_related);
931EXPORT_SYMBOL(ip_conntrack_unexpect_related); 927EXPORT_SYMBOL(ip_conntrack_unexpect_related);
932EXPORT_SYMBOL_GPL(ip_conntrack_expect_list); 928EXPORT_SYMBOL_GPL(ip_conntrack_expect_list);
diff --git a/net/ipv4/netfilter/ip_conntrack_tftp.c b/net/ipv4/netfilter/ip_conntrack_tftp.c
index fe0b634dd3..ef56de2eff 100644
--- a/net/ipv4/netfilter/ip_conntrack_tftp.c
+++ b/net/ipv4/netfilter/ip_conntrack_tftp.c
@@ -50,6 +50,7 @@ static int tftp_help(struct sk_buff **pskb,
50 struct tftphdr _tftph, *tfh; 50 struct tftphdr _tftph, *tfh;
51 struct ip_conntrack_expect *exp; 51 struct ip_conntrack_expect *exp;
52 unsigned int ret = NF_ACCEPT; 52 unsigned int ret = NF_ACCEPT;
53 typeof(ip_nat_tftp_hook) ip_nat_tftp;
53 54
54 tfh = skb_header_pointer(*pskb, 55 tfh = skb_header_pointer(*pskb,
55 (*pskb)->nh.iph->ihl*4+sizeof(struct udphdr), 56 (*pskb)->nh.iph->ihl*4+sizeof(struct udphdr),
@@ -81,8 +82,9 @@ static int tftp_help(struct sk_buff **pskb,
81 DEBUGP("expect: "); 82 DEBUGP("expect: ");
82 DUMP_TUPLE(&exp->tuple); 83 DUMP_TUPLE(&exp->tuple);
83 DUMP_TUPLE(&exp->mask); 84 DUMP_TUPLE(&exp->mask);
84 if (ip_nat_tftp_hook) 85 ip_nat_tftp = rcu_dereference(ip_nat_tftp_hook);
85 ret = ip_nat_tftp_hook(pskb, ctinfo, exp); 86 if (ip_nat_tftp)
87 ret = ip_nat_tftp(pskb, ctinfo, exp);
86 else if (ip_conntrack_expect_related(exp) != 0) 88 else if (ip_conntrack_expect_related(exp) != 0)
87 ret = NF_DROP; 89 ret = NF_DROP;
88 ip_conntrack_expect_put(exp); 90 ip_conntrack_expect_put(exp);
diff --git a/net/ipv4/netfilter/ip_nat_amanda.c b/net/ipv4/netfilter/ip_nat_amanda.c
index 3a888715bb..85df1a9aed 100644
--- a/net/ipv4/netfilter/ip_nat_amanda.c
+++ b/net/ipv4/netfilter/ip_nat_amanda.c
@@ -70,15 +70,14 @@ static unsigned int help(struct sk_buff **pskb,
70 70
71static void __exit ip_nat_amanda_fini(void) 71static void __exit ip_nat_amanda_fini(void)
72{ 72{
73 ip_nat_amanda_hook = NULL; 73 rcu_assign_pointer(ip_nat_amanda_hook, NULL);
74 /* Make sure noone calls it, meanwhile. */ 74 synchronize_rcu();
75 synchronize_net();
76} 75}
77 76
78static int __init ip_nat_amanda_init(void) 77static int __init ip_nat_amanda_init(void)
79{ 78{
80 BUG_ON(ip_nat_amanda_hook); 79 BUG_ON(rcu_dereference(ip_nat_amanda_hook));
81 ip_nat_amanda_hook = help; 80 rcu_assign_pointer(ip_nat_amanda_hook, help);
82 return 0; 81 return 0;
83} 82}
84 83
diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
index 4b6260a974..9d1a5175dc 100644
--- a/net/ipv4/netfilter/ip_nat_core.c
+++ b/net/ipv4/netfilter/ip_nat_core.c
@@ -362,12 +362,10 @@ manip_pkt(u_int16_t proto,
362 iph = (void *)(*pskb)->data + iphdroff; 362 iph = (void *)(*pskb)->data + iphdroff;
363 363
364 if (maniptype == IP_NAT_MANIP_SRC) { 364 if (maniptype == IP_NAT_MANIP_SRC) {
365 iph->check = nf_csum_update(~iph->saddr, target->src.ip, 365 nf_csum_replace4(&iph->check, iph->saddr, target->src.ip);
366 iph->check);
367 iph->saddr = target->src.ip; 366 iph->saddr = target->src.ip;
368 } else { 367 } else {
369 iph->check = nf_csum_update(~iph->daddr, target->dst.ip, 368 nf_csum_replace4(&iph->check, iph->daddr, target->dst.ip);
370 iph->check);
371 iph->daddr = target->dst.ip; 369 iph->daddr = target->dst.ip;
372 } 370 }
373 return 1; 371 return 1;
diff --git a/net/ipv4/netfilter/ip_nat_ftp.c b/net/ipv4/netfilter/ip_nat_ftp.c
index a71c233d81..913960e138 100644
--- a/net/ipv4/netfilter/ip_nat_ftp.c
+++ b/net/ipv4/netfilter/ip_nat_ftp.c
@@ -156,15 +156,14 @@ static unsigned int ip_nat_ftp(struct sk_buff **pskb,
156 156
157static void __exit ip_nat_ftp_fini(void) 157static void __exit ip_nat_ftp_fini(void)
158{ 158{
159 ip_nat_ftp_hook = NULL; 159 rcu_assign_pointer(ip_nat_ftp_hook, NULL);
160 /* Make sure noone calls it, meanwhile. */ 160 synchronize_rcu();
161 synchronize_net();
162} 161}
163 162
164static int __init ip_nat_ftp_init(void) 163static int __init ip_nat_ftp_init(void)
165{ 164{
166 BUG_ON(ip_nat_ftp_hook); 165 BUG_ON(rcu_dereference(ip_nat_ftp_hook));
167 ip_nat_ftp_hook = ip_nat_ftp; 166 rcu_assign_pointer(ip_nat_ftp_hook, ip_nat_ftp);
168 return 0; 167 return 0;
169} 168}
170 169
diff --git a/net/ipv4/netfilter/ip_nat_helper.c b/net/ipv4/netfilter/ip_nat_helper.c
index 3bf8584805..ee80feb4b2 100644
--- a/net/ipv4/netfilter/ip_nat_helper.c
+++ b/net/ipv4/netfilter/ip_nat_helper.c
@@ -188,10 +188,8 @@ ip_nat_mangle_tcp_packet(struct sk_buff **pskb,
188 csum_partial((char *)tcph, 188 csum_partial((char *)tcph,
189 datalen, 0)); 189 datalen, 0));
190 } else 190 } else
191 tcph->check = nf_proto_csum_update(*pskb, 191 nf_proto_csum_replace2(&tcph->check, *pskb,
192 htons(oldlen) ^ htons(0xFFFF), 192 htons(oldlen), htons(datalen), 1);
193 htons(datalen),
194 tcph->check, 1);
195 193
196 if (rep_len != match_len) { 194 if (rep_len != match_len) {
197 set_bit(IPS_SEQ_ADJUST_BIT, &ct->status); 195 set_bit(IPS_SEQ_ADJUST_BIT, &ct->status);
@@ -264,12 +262,10 @@ ip_nat_mangle_udp_packet(struct sk_buff **pskb,
264 csum_partial((char *)udph, 262 csum_partial((char *)udph,
265 datalen, 0)); 263 datalen, 0));
266 if (!udph->check) 264 if (!udph->check)
267 udph->check = -1; 265 udph->check = CSUM_MANGLED_0;
268 } else 266 } else
269 udph->check = nf_proto_csum_update(*pskb, 267 nf_proto_csum_replace2(&udph->check, *pskb,
270 htons(oldlen) ^ htons(0xFFFF), 268 htons(oldlen), htons(datalen), 1);
271 htons(datalen),
272 udph->check, 1);
273 return 1; 269 return 1;
274} 270}
275EXPORT_SYMBOL(ip_nat_mangle_udp_packet); 271EXPORT_SYMBOL(ip_nat_mangle_udp_packet);
@@ -307,14 +303,10 @@ sack_adjust(struct sk_buff *skb,
307 ntohl(sack->start_seq), new_start_seq, 303 ntohl(sack->start_seq), new_start_seq,
308 ntohl(sack->end_seq), new_end_seq); 304 ntohl(sack->end_seq), new_end_seq);
309 305
310 tcph->check = nf_proto_csum_update(skb, 306 nf_proto_csum_replace4(&tcph->check, skb,
311 ~sack->start_seq, 307 sack->start_seq, new_start_seq, 0);
312 new_start_seq, 308 nf_proto_csum_replace4(&tcph->check, skb,
313 tcph->check, 0); 309 sack->end_seq, new_end_seq, 0);
314 tcph->check = nf_proto_csum_update(skb,
315 ~sack->end_seq,
316 new_end_seq,
317 tcph->check, 0);
318 sack->start_seq = new_start_seq; 310 sack->start_seq = new_start_seq;
319 sack->end_seq = new_end_seq; 311 sack->end_seq = new_end_seq;
320 sackoff += sizeof(*sack); 312 sackoff += sizeof(*sack);
@@ -397,10 +389,8 @@ ip_nat_seq_adjust(struct sk_buff **pskb,
397 else 389 else
398 newack = htonl(ntohl(tcph->ack_seq) - other_way->offset_before); 390 newack = htonl(ntohl(tcph->ack_seq) - other_way->offset_before);
399 391
400 tcph->check = nf_proto_csum_update(*pskb, ~tcph->seq, newseq, 392 nf_proto_csum_replace4(&tcph->check, *pskb, tcph->seq, newseq, 0);
401 tcph->check, 0); 393 nf_proto_csum_replace4(&tcph->check, *pskb, tcph->ack_seq, newack, 0);
402 tcph->check = nf_proto_csum_update(*pskb, ~tcph->ack_seq, newack,
403 tcph->check, 0);
404 394
405 DEBUGP("Adjusting sequence number from %u->%u, ack from %u->%u\n", 395 DEBUGP("Adjusting sequence number from %u->%u, ack from %u->%u\n",
406 ntohl(tcph->seq), ntohl(newseq), ntohl(tcph->ack_seq), 396 ntohl(tcph->seq), ntohl(newseq), ntohl(tcph->ack_seq),
diff --git a/net/ipv4/netfilter/ip_nat_helper_h323.c b/net/ipv4/netfilter/ip_nat_helper_h323.c
index 4a7d34466e..bdc99ef615 100644
--- a/net/ipv4/netfilter/ip_nat_helper_h323.c
+++ b/net/ipv4/netfilter/ip_nat_helper_h323.c
@@ -563,25 +563,25 @@ static int nat_callforwarding(struct sk_buff **pskb, struct ip_conntrack *ct,
563/****************************************************************************/ 563/****************************************************************************/
564static int __init init(void) 564static int __init init(void)
565{ 565{
566 BUG_ON(set_h245_addr_hook != NULL); 566 BUG_ON(rcu_dereference(set_h245_addr_hook) != NULL);
567 BUG_ON(set_h225_addr_hook != NULL); 567 BUG_ON(rcu_dereference(set_h225_addr_hook) != NULL);
568 BUG_ON(set_sig_addr_hook != NULL); 568 BUG_ON(rcu_dereference(set_sig_addr_hook) != NULL);
569 BUG_ON(set_ras_addr_hook != NULL); 569 BUG_ON(rcu_dereference(set_ras_addr_hook) != NULL);
570 BUG_ON(nat_rtp_rtcp_hook != NULL); 570 BUG_ON(rcu_dereference(nat_rtp_rtcp_hook) != NULL);
571 BUG_ON(nat_t120_hook != NULL); 571 BUG_ON(rcu_dereference(nat_t120_hook) != NULL);
572 BUG_ON(nat_h245_hook != NULL); 572 BUG_ON(rcu_dereference(nat_h245_hook) != NULL);
573 BUG_ON(nat_callforwarding_hook != NULL); 573 BUG_ON(rcu_dereference(nat_callforwarding_hook) != NULL);
574 BUG_ON(nat_q931_hook != NULL); 574 BUG_ON(rcu_dereference(nat_q931_hook) != NULL);
575 575
576 set_h245_addr_hook = set_h245_addr; 576 rcu_assign_pointer(set_h245_addr_hook, set_h245_addr);
577 set_h225_addr_hook = set_h225_addr; 577 rcu_assign_pointer(set_h225_addr_hook, set_h225_addr);
578 set_sig_addr_hook = set_sig_addr; 578 rcu_assign_pointer(set_sig_addr_hook, set_sig_addr);
579 set_ras_addr_hook = set_ras_addr; 579 rcu_assign_pointer(set_ras_addr_hook, set_ras_addr);
580 nat_rtp_rtcp_hook = nat_rtp_rtcp; 580 rcu_assign_pointer(nat_rtp_rtcp_hook, nat_rtp_rtcp);
581 nat_t120_hook = nat_t120; 581 rcu_assign_pointer(nat_t120_hook, nat_t120);
582 nat_h245_hook = nat_h245; 582 rcu_assign_pointer(nat_h245_hook, nat_h245);
583 nat_callforwarding_hook = nat_callforwarding; 583 rcu_assign_pointer(nat_callforwarding_hook, nat_callforwarding);
584 nat_q931_hook = nat_q931; 584 rcu_assign_pointer(nat_q931_hook, nat_q931);
585 585
586 DEBUGP("ip_nat_h323: init success\n"); 586 DEBUGP("ip_nat_h323: init success\n");
587 return 0; 587 return 0;
@@ -590,16 +590,16 @@ static int __init init(void)
590/****************************************************************************/ 590/****************************************************************************/
591static void __exit fini(void) 591static void __exit fini(void)
592{ 592{
593 set_h245_addr_hook = NULL; 593 rcu_assign_pointer(set_h245_addr_hook, NULL);
594 set_h225_addr_hook = NULL; 594 rcu_assign_pointer(set_h225_addr_hook, NULL);
595 set_sig_addr_hook = NULL; 595 rcu_assign_pointer(set_sig_addr_hook, NULL);
596 set_ras_addr_hook = NULL; 596 rcu_assign_pointer(set_ras_addr_hook, NULL);
597 nat_rtp_rtcp_hook = NULL; 597 rcu_assign_pointer(nat_rtp_rtcp_hook, NULL);
598 nat_t120_hook = NULL; 598 rcu_assign_pointer(nat_t120_hook, NULL);
599 nat_h245_hook = NULL; 599 rcu_assign_pointer(nat_h245_hook, NULL);
600 nat_callforwarding_hook = NULL; 600 rcu_assign_pointer(nat_callforwarding_hook, NULL);
601 nat_q931_hook = NULL; 601 rcu_assign_pointer(nat_q931_hook, NULL);
602 synchronize_net(); 602 synchronize_rcu();
603} 603}
604 604
605/****************************************************************************/ 605/****************************************************************************/
diff --git a/net/ipv4/netfilter/ip_nat_helper_pptp.c b/net/ipv4/netfilter/ip_nat_helper_pptp.c
index 329fdcd7d7..ec957bbb53 100644
--- a/net/ipv4/netfilter/ip_nat_helper_pptp.c
+++ b/net/ipv4/netfilter/ip_nat_helper_pptp.c
@@ -101,7 +101,7 @@ static void pptp_nat_expected(struct ip_conntrack *ct,
101 101
102 DEBUGP("trying to unexpect other dir: "); 102 DEBUGP("trying to unexpect other dir: ");
103 DUMP_TUPLE(&t); 103 DUMP_TUPLE(&t);
104 other_exp = ip_conntrack_expect_find(&t); 104 other_exp = ip_conntrack_expect_find_get(&t);
105 if (other_exp) { 105 if (other_exp) {
106 ip_conntrack_unexpect_related(other_exp); 106 ip_conntrack_unexpect_related(other_exp);
107 ip_conntrack_expect_put(other_exp); 107 ip_conntrack_expect_put(other_exp);
@@ -315,17 +315,17 @@ static int __init ip_nat_helper_pptp_init(void)
315 if (ret < 0) 315 if (ret < 0)
316 return ret; 316 return ret;
317 317
318 BUG_ON(ip_nat_pptp_hook_outbound); 318 BUG_ON(rcu_dereference(ip_nat_pptp_hook_outbound));
319 ip_nat_pptp_hook_outbound = &pptp_outbound_pkt; 319 rcu_assign_pointer(ip_nat_pptp_hook_outbound, pptp_outbound_pkt);
320 320
321 BUG_ON(ip_nat_pptp_hook_inbound); 321 BUG_ON(rcu_dereference(ip_nat_pptp_hook_inbound));
322 ip_nat_pptp_hook_inbound = &pptp_inbound_pkt; 322 rcu_assign_pointer(ip_nat_pptp_hook_inbound, pptp_inbound_pkt);
323 323
324 BUG_ON(ip_nat_pptp_hook_exp_gre); 324 BUG_ON(rcu_dereference(ip_nat_pptp_hook_exp_gre));
325 ip_nat_pptp_hook_exp_gre = &pptp_exp_gre; 325 rcu_assign_pointer(ip_nat_pptp_hook_exp_gre, pptp_exp_gre);
326 326
327 BUG_ON(ip_nat_pptp_hook_expectfn); 327 BUG_ON(rcu_dereference(ip_nat_pptp_hook_expectfn));
328 ip_nat_pptp_hook_expectfn = &pptp_nat_expected; 328 rcu_assign_pointer(ip_nat_pptp_hook_expectfn, pptp_nat_expected);
329 329
330 printk("ip_nat_pptp version %s loaded\n", IP_NAT_PPTP_VERSION); 330 printk("ip_nat_pptp version %s loaded\n", IP_NAT_PPTP_VERSION);
331 return 0; 331 return 0;
@@ -335,14 +335,13 @@ static void __exit ip_nat_helper_pptp_fini(void)
335{ 335{
336 DEBUGP("cleanup_module\n" ); 336 DEBUGP("cleanup_module\n" );
337 337
338 ip_nat_pptp_hook_expectfn = NULL; 338 rcu_assign_pointer(ip_nat_pptp_hook_expectfn, NULL);
339 ip_nat_pptp_hook_exp_gre = NULL; 339 rcu_assign_pointer(ip_nat_pptp_hook_exp_gre, NULL);
340 ip_nat_pptp_hook_inbound = NULL; 340 rcu_assign_pointer(ip_nat_pptp_hook_inbound, NULL);
341 ip_nat_pptp_hook_outbound = NULL; 341 rcu_assign_pointer(ip_nat_pptp_hook_outbound, NULL);
342 synchronize_rcu();
342 343
343 ip_nat_proto_gre_fini(); 344 ip_nat_proto_gre_fini();
344 /* Make sure noone calls it, meanwhile */
345 synchronize_net();
346 345
347 printk("ip_nat_pptp version %s unloaded\n", IP_NAT_PPTP_VERSION); 346 printk("ip_nat_pptp version %s unloaded\n", IP_NAT_PPTP_VERSION);
348} 347}
diff --git a/net/ipv4/netfilter/ip_nat_irc.c b/net/ipv4/netfilter/ip_nat_irc.c
index a767123e08..feb26b48f1 100644
--- a/net/ipv4/netfilter/ip_nat_irc.c
+++ b/net/ipv4/netfilter/ip_nat_irc.c
@@ -98,15 +98,14 @@ static unsigned int help(struct sk_buff **pskb,
98 98
99static void __exit ip_nat_irc_fini(void) 99static void __exit ip_nat_irc_fini(void)
100{ 100{
101 ip_nat_irc_hook = NULL; 101 rcu_assign_pointer(ip_nat_irc_hook, NULL);
102 /* Make sure noone calls it, meanwhile. */ 102 synchronize_rcu();
103 synchronize_net();
104} 103}
105 104
106static int __init ip_nat_irc_init(void) 105static int __init ip_nat_irc_init(void)
107{ 106{
108 BUG_ON(ip_nat_irc_hook); 107 BUG_ON(rcu_dereference(ip_nat_irc_hook));
109 ip_nat_irc_hook = help; 108 rcu_assign_pointer(ip_nat_irc_hook, help);
110 return 0; 109 return 0;
111} 110}
112 111
diff --git a/net/ipv4/netfilter/ip_nat_proto_gre.c b/net/ipv4/netfilter/ip_nat_proto_gre.c
index bf91f9312b..95810202d8 100644
--- a/net/ipv4/netfilter/ip_nat_proto_gre.c
+++ b/net/ipv4/netfilter/ip_nat_proto_gre.c
@@ -129,11 +129,9 @@ gre_manip_pkt(struct sk_buff **pskb,
129 } 129 }
130 if (greh->csum) { 130 if (greh->csum) {
131 /* FIXME: Never tested this code... */ 131 /* FIXME: Never tested this code... */
132 *(gre_csum(greh)) = 132 nf_proto_csum_replace4(gre_csum(greh), *pskb,
133 nf_proto_csum_update(*pskb, 133 *(gre_key(greh)),
134 ~*(gre_key(greh)), 134 tuple->dst.u.gre.key, 0);
135 tuple->dst.u.gre.key,
136 *(gre_csum(greh)), 0);
137 } 135 }
138 *(gre_key(greh)) = tuple->dst.u.gre.key; 136 *(gre_key(greh)) = tuple->dst.u.gre.key;
139 break; 137 break;
diff --git a/net/ipv4/netfilter/ip_nat_proto_icmp.c b/net/ipv4/netfilter/ip_nat_proto_icmp.c
index 3f6efc13ac..fb716edd5b 100644
--- a/net/ipv4/netfilter/ip_nat_proto_icmp.c
+++ b/net/ipv4/netfilter/ip_nat_proto_icmp.c
@@ -24,8 +24,8 @@ icmp_in_range(const struct ip_conntrack_tuple *tuple,
24 const union ip_conntrack_manip_proto *min, 24 const union ip_conntrack_manip_proto *min,
25 const union ip_conntrack_manip_proto *max) 25 const union ip_conntrack_manip_proto *max)
26{ 26{
27 return (tuple->src.u.icmp.id >= min->icmp.id 27 return ntohs(tuple->src.u.icmp.id) >= ntohs(min->icmp.id) &&
28 && tuple->src.u.icmp.id <= max->icmp.id); 28 ntohs(tuple->src.u.icmp.id) <= ntohs(max->icmp.id);
29} 29}
30 30
31static int 31static int
@@ -66,10 +66,8 @@ icmp_manip_pkt(struct sk_buff **pskb,
66 return 0; 66 return 0;
67 67
68 hdr = (struct icmphdr *)((*pskb)->data + hdroff); 68 hdr = (struct icmphdr *)((*pskb)->data + hdroff);
69 hdr->checksum = nf_proto_csum_update(*pskb, 69 nf_proto_csum_replace2(&hdr->checksum, *pskb,
70 hdr->un.echo.id ^ htons(0xFFFF), 70 hdr->un.echo.id, tuple->src.u.icmp.id, 0);
71 tuple->src.u.icmp.id,
72 hdr->checksum, 0);
73 hdr->un.echo.id = tuple->src.u.icmp.id; 71 hdr->un.echo.id = tuple->src.u.icmp.id;
74 return 1; 72 return 1;
75} 73}
diff --git a/net/ipv4/netfilter/ip_nat_proto_tcp.c b/net/ipv4/netfilter/ip_nat_proto_tcp.c
index 12deb13b93..b586d18b3f 100644
--- a/net/ipv4/netfilter/ip_nat_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_nat_proto_tcp.c
@@ -129,9 +129,8 @@ tcp_manip_pkt(struct sk_buff **pskb,
129 if (hdrsize < sizeof(*hdr)) 129 if (hdrsize < sizeof(*hdr))
130 return 1; 130 return 1;
131 131
132 hdr->check = nf_proto_csum_update(*pskb, ~oldip, newip, hdr->check, 1); 132 nf_proto_csum_replace4(&hdr->check, *pskb, oldip, newip, 1);
133 hdr->check = nf_proto_csum_update(*pskb, oldport ^ htons(0xFFFF), newport, 133 nf_proto_csum_replace2(&hdr->check, *pskb, oldport, newport, 0);
134 hdr->check, 0);
135 return 1; 134 return 1;
136} 135}
137 136
diff --git a/net/ipv4/netfilter/ip_nat_proto_udp.c b/net/ipv4/netfilter/ip_nat_proto_udp.c
index 4bbec7730d..5ced0877b3 100644
--- a/net/ipv4/netfilter/ip_nat_proto_udp.c
+++ b/net/ipv4/netfilter/ip_nat_proto_udp.c
@@ -115,13 +115,10 @@ udp_manip_pkt(struct sk_buff **pskb,
115 } 115 }
116 116
117 if (hdr->check || (*pskb)->ip_summed == CHECKSUM_PARTIAL) { 117 if (hdr->check || (*pskb)->ip_summed == CHECKSUM_PARTIAL) {
118 hdr->check = nf_proto_csum_update(*pskb, ~oldip, newip, 118 nf_proto_csum_replace4(&hdr->check, *pskb, oldip, newip, 1);
119 hdr->check, 1); 119 nf_proto_csum_replace2(&hdr->check, *pskb, *portptr, newport, 0);
120 hdr->check = nf_proto_csum_update(*pskb,
121 *portptr ^ htons(0xFFFF), newport,
122 hdr->check, 0);
123 if (!hdr->check) 120 if (!hdr->check)
124 hdr->check = -1; 121 hdr->check = CSUM_MANGLED_0;
125 } 122 }
126 *portptr = newport; 123 *portptr = newport;
127 return 1; 124 return 1;
diff --git a/net/ipv4/netfilter/ip_nat_sip.c b/net/ipv4/netfilter/ip_nat_sip.c
index 71fc2730a0..6223abc924 100644
--- a/net/ipv4/netfilter/ip_nat_sip.c
+++ b/net/ipv4/netfilter/ip_nat_sip.c
@@ -29,27 +29,70 @@ MODULE_DESCRIPTION("SIP NAT helper");
29#define DEBUGP(format, args...) 29#define DEBUGP(format, args...)
30#endif 30#endif
31 31
32extern struct sip_header_nfo ct_sip_hdrs[]; 32struct addr_map {
33 struct {
34 char src[sizeof("nnn.nnn.nnn.nnn:nnnnn")];
35 char dst[sizeof("nnn.nnn.nnn.nnn:nnnnn")];
36 unsigned int srclen, srciplen;
37 unsigned int dstlen, dstiplen;
38 } addr[IP_CT_DIR_MAX];
39};
40
41static void addr_map_init(struct ip_conntrack *ct, struct addr_map *map)
42{
43 struct ip_conntrack_tuple *t;
44 enum ip_conntrack_dir dir;
45 unsigned int n;
46
47 for (dir = 0; dir < IP_CT_DIR_MAX; dir++) {
48 t = &ct->tuplehash[dir].tuple;
49
50 n = sprintf(map->addr[dir].src, "%u.%u.%u.%u",
51 NIPQUAD(t->src.ip));
52 map->addr[dir].srciplen = n;
53 n += sprintf(map->addr[dir].src + n, ":%u",
54 ntohs(t->src.u.udp.port));
55 map->addr[dir].srclen = n;
56
57 n = sprintf(map->addr[dir].dst, "%u.%u.%u.%u",
58 NIPQUAD(t->dst.ip));
59 map->addr[dir].dstiplen = n;
60 n += sprintf(map->addr[dir].dst + n, ":%u",
61 ntohs(t->dst.u.udp.port));
62 map->addr[dir].dstlen = n;
63 }
64}
33 65
34static unsigned int mangle_sip_packet(struct sk_buff **pskb, 66static int map_sip_addr(struct sk_buff **pskb, enum ip_conntrack_info ctinfo,
35 enum ip_conntrack_info ctinfo, 67 struct ip_conntrack *ct, const char **dptr, size_t dlen,
36 struct ip_conntrack *ct, 68 enum sip_header_pos pos, struct addr_map *map)
37 const char **dptr, size_t dlen,
38 char *buffer, int bufflen,
39 struct sip_header_nfo *hnfo)
40{ 69{
41 unsigned int matchlen, matchoff; 70 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
71 unsigned int matchlen, matchoff, addrlen;
72 char *addr;
42 73
43 if (ct_sip_get_info(*dptr, dlen, &matchoff, &matchlen, hnfo) <= 0) 74 if (ct_sip_get_info(*dptr, dlen, &matchoff, &matchlen, pos) <= 0)
44 return 0; 75 return 1;
76
77 if ((matchlen == map->addr[dir].srciplen ||
78 matchlen == map->addr[dir].srclen) &&
79 memcmp(*dptr + matchoff, map->addr[dir].src, matchlen) == 0) {
80 addr = map->addr[!dir].dst;
81 addrlen = map->addr[!dir].dstlen;
82 } else if ((matchlen == map->addr[dir].dstiplen ||
83 matchlen == map->addr[dir].dstlen) &&
84 memcmp(*dptr + matchoff, map->addr[dir].dst, matchlen) == 0) {
85 addr = map->addr[!dir].src;
86 addrlen = map->addr[!dir].srclen;
87 } else
88 return 1;
45 89
46 if (!ip_nat_mangle_udp_packet(pskb, ct, ctinfo, 90 if (!ip_nat_mangle_udp_packet(pskb, ct, ctinfo,
47 matchoff, matchlen, buffer, bufflen)) 91 matchoff, matchlen, addr, addrlen))
48 return 0; 92 return 0;
49
50 /* We need to reload this. Thanks Patrick. */
51 *dptr = (*pskb)->data + (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr); 93 *dptr = (*pskb)->data + (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);
52 return 1; 94 return 1;
95
53} 96}
54 97
55static unsigned int ip_nat_sip(struct sk_buff **pskb, 98static unsigned int ip_nat_sip(struct sk_buff **pskb,
@@ -57,70 +100,61 @@ static unsigned int ip_nat_sip(struct sk_buff **pskb,
57 struct ip_conntrack *ct, 100 struct ip_conntrack *ct,
58 const char **dptr) 101 const char **dptr)
59{ 102{
60 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 103 enum sip_header_pos pos;
61 char buffer[sizeof("nnn.nnn.nnn.nnn:nnnnn")]; 104 struct addr_map map;
62 unsigned int bufflen, dataoff; 105 int dataoff, datalen;
63 __be32 ip;
64 __be16 port;
65 106
66 dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr); 107 dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);
108 datalen = (*pskb)->len - dataoff;
109 if (datalen < sizeof("SIP/2.0") - 1)
110 return NF_DROP;
111
112 addr_map_init(ct, &map);
113
114 /* Basic rules: requests and responses. */
115 if (strncmp(*dptr, "SIP/2.0", sizeof("SIP/2.0") - 1) != 0) {
116 /* 10.2: Constructing the REGISTER Request:
117 *
118 * The "userinfo" and "@" components of the SIP URI MUST NOT
119 * be present.
120 */
121 if (datalen >= sizeof("REGISTER") - 1 &&
122 strncmp(*dptr, "REGISTER", sizeof("REGISTER") - 1) == 0)
123 pos = POS_REG_REQ_URI;
124 else
125 pos = POS_REQ_URI;
126
127 if (!map_sip_addr(pskb, ctinfo, ct, dptr, datalen, pos, &map))
128 return NF_DROP;
129 }
130
131 if (!map_sip_addr(pskb, ctinfo, ct, dptr, datalen, POS_FROM, &map) ||
132 !map_sip_addr(pskb, ctinfo, ct, dptr, datalen, POS_TO, &map) ||
133 !map_sip_addr(pskb, ctinfo, ct, dptr, datalen, POS_VIA, &map) ||
134 !map_sip_addr(pskb, ctinfo, ct, dptr, datalen, POS_CONTACT, &map))
135 return NF_DROP;
136 return NF_ACCEPT;
137}
67 138
68 ip = ct->tuplehash[!dir].tuple.dst.ip; 139static unsigned int mangle_sip_packet(struct sk_buff **pskb,
69 port = ct->tuplehash[!dir].tuple.dst.u.udp.port; 140 enum ip_conntrack_info ctinfo,
70 bufflen = sprintf(buffer, "%u.%u.%u.%u:%u", NIPQUAD(ip), ntohs(port)); 141 struct ip_conntrack *ct,
142 const char **dptr, size_t dlen,
143 char *buffer, int bufflen,
144 enum sip_header_pos pos)
145{
146 unsigned int matchlen, matchoff;
71 147
72 /* short packet ? */ 148 if (ct_sip_get_info(*dptr, dlen, &matchoff, &matchlen, pos) <= 0)
73 if (((*pskb)->len - dataoff) < (sizeof("SIP/2.0") - 1))
74 return 0; 149 return 0;
75 150
76 /* Basic rules: requests and responses. */ 151 if (!ip_nat_mangle_udp_packet(pskb, ct, ctinfo,
77 if (memcmp(*dptr, "SIP/2.0", sizeof("SIP/2.0") - 1) == 0) { 152 matchoff, matchlen, buffer, bufflen))
78 const char *aux; 153 return 0;
79
80 if ((ctinfo) < IP_CT_IS_REPLY) {
81 mangle_sip_packet(pskb, ctinfo, ct, dptr,
82 (*pskb)->len - dataoff,
83 buffer, bufflen,
84 &ct_sip_hdrs[POS_CONTACT]);
85 return 1;
86 }
87 154
88 if (!mangle_sip_packet(pskb, ctinfo, ct, dptr, 155 /* We need to reload this. Thanks Patrick. */
89 (*pskb)->len - dataoff, 156 *dptr = (*pskb)->data + (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);
90 buffer, bufflen, &ct_sip_hdrs[POS_VIA])) 157 return 1;
91 return 0;
92
93 /* This search should ignore case, but later.. */
94 aux = ct_sip_search("CSeq:", *dptr, sizeof("CSeq:") - 1,
95 (*pskb)->len - dataoff);
96 if (!aux)
97 return 0;
98
99 if (!ct_sip_search("REGISTER", aux, sizeof("REGISTER"),
100 ct_sip_lnlen(aux, *dptr + (*pskb)->len - dataoff)))
101 return 1;
102
103 return mangle_sip_packet(pskb, ctinfo, ct, dptr,
104 (*pskb)->len - dataoff,
105 buffer, bufflen,
106 &ct_sip_hdrs[POS_CONTACT]);
107 }
108 if ((ctinfo) < IP_CT_IS_REPLY) {
109 if (!mangle_sip_packet(pskb, ctinfo, ct, dptr,
110 (*pskb)->len - dataoff,
111 buffer, bufflen, &ct_sip_hdrs[POS_VIA]))
112 return 0;
113
114 /* Mangle Contact if exists only. - watch udp_nat_mangle()! */
115 mangle_sip_packet(pskb, ctinfo, ct, dptr, (*pskb)->len - dataoff,
116 buffer, bufflen, &ct_sip_hdrs[POS_CONTACT]);
117 return 1;
118 }
119 /* This mangle requests headers. */
120 return mangle_sip_packet(pskb, ctinfo, ct, dptr,
121 ct_sip_lnlen(*dptr,
122 *dptr + (*pskb)->len - dataoff),
123 buffer, bufflen, &ct_sip_hdrs[POS_REQ_HEADER]);
124} 158}
125 159
126static int mangle_content_len(struct sk_buff **pskb, 160static int mangle_content_len(struct sk_buff **pskb,
@@ -136,7 +170,7 @@ static int mangle_content_len(struct sk_buff **pskb,
136 170
137 /* Get actual SDP lenght */ 171 /* Get actual SDP lenght */
138 if (ct_sip_get_info(dptr, (*pskb)->len - dataoff, &matchoff, 172 if (ct_sip_get_info(dptr, (*pskb)->len - dataoff, &matchoff,
139 &matchlen, &ct_sip_hdrs[POS_SDP_HEADER]) > 0) { 173 &matchlen, POS_SDP_HEADER) > 0) {
140 174
141 /* since ct_sip_get_info() give us a pointer passing 'v=' 175 /* since ct_sip_get_info() give us a pointer passing 'v='
142 we need to add 2 bytes in this count. */ 176 we need to add 2 bytes in this count. */
@@ -144,7 +178,7 @@ static int mangle_content_len(struct sk_buff **pskb,
144 178
145 /* Now, update SDP lenght */ 179 /* Now, update SDP lenght */
146 if (ct_sip_get_info(dptr, (*pskb)->len - dataoff, &matchoff, 180 if (ct_sip_get_info(dptr, (*pskb)->len - dataoff, &matchoff,
147 &matchlen, &ct_sip_hdrs[POS_CONTENT]) > 0) { 181 &matchlen, POS_CONTENT) > 0) {
148 182
149 bufflen = sprintf(buffer, "%u", c_len); 183 bufflen = sprintf(buffer, "%u", c_len);
150 184
@@ -170,17 +204,17 @@ static unsigned int mangle_sdp(struct sk_buff **pskb,
170 /* Mangle owner and contact info. */ 204 /* Mangle owner and contact info. */
171 bufflen = sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(newip)); 205 bufflen = sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(newip));
172 if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff, 206 if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff,
173 buffer, bufflen, &ct_sip_hdrs[POS_OWNER])) 207 buffer, bufflen, POS_OWNER))
174 return 0; 208 return 0;
175 209
176 if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff, 210 if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff,
177 buffer, bufflen, &ct_sip_hdrs[POS_CONNECTION])) 211 buffer, bufflen, POS_CONNECTION))
178 return 0; 212 return 0;
179 213
180 /* Mangle media port. */ 214 /* Mangle media port. */
181 bufflen = sprintf(buffer, "%u", port); 215 bufflen = sprintf(buffer, "%u", port);
182 if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff, 216 if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff,
183 buffer, bufflen, &ct_sip_hdrs[POS_MEDIA])) 217 buffer, bufflen, POS_MEDIA))
184 return 0; 218 return 0;
185 219
186 return mangle_content_len(pskb, ctinfo, ct, dptr); 220 return mangle_content_len(pskb, ctinfo, ct, dptr);
@@ -230,18 +264,17 @@ static unsigned int ip_nat_sdp(struct sk_buff **pskb,
230 264
231static void __exit fini(void) 265static void __exit fini(void)
232{ 266{
233 ip_nat_sip_hook = NULL; 267 rcu_assign_pointer(ip_nat_sip_hook, NULL);
234 ip_nat_sdp_hook = NULL; 268 rcu_assign_pointer(ip_nat_sdp_hook, NULL);
235 /* Make sure noone calls it, meanwhile. */ 269 synchronize_rcu();
236 synchronize_net();
237} 270}
238 271
239static int __init init(void) 272static int __init init(void)
240{ 273{
241 BUG_ON(ip_nat_sip_hook); 274 BUG_ON(rcu_dereference(ip_nat_sip_hook));
242 BUG_ON(ip_nat_sdp_hook); 275 BUG_ON(rcu_dereference(ip_nat_sdp_hook));
243 ip_nat_sip_hook = ip_nat_sip; 276 rcu_assign_pointer(ip_nat_sip_hook, ip_nat_sip);
244 ip_nat_sdp_hook = ip_nat_sdp; 277 rcu_assign_pointer(ip_nat_sdp_hook, ip_nat_sdp);
245 return 0; 278 return 0;
246} 279}
247 280
diff --git a/net/ipv4/netfilter/ip_nat_snmp_basic.c b/net/ipv4/netfilter/ip_nat_snmp_basic.c
index 168f45fa18..c3d9f3b090 100644
--- a/net/ipv4/netfilter/ip_nat_snmp_basic.c
+++ b/net/ipv4/netfilter/ip_nat_snmp_basic.c
@@ -64,7 +64,7 @@ MODULE_DESCRIPTION("Basic SNMP Application Layer Gateway");
64 64
65#define SNMP_PORT 161 65#define SNMP_PORT 161
66#define SNMP_TRAP_PORT 162 66#define SNMP_TRAP_PORT 162
67#define NOCT1(n) (u_int8_t )((n) & 0xff) 67#define NOCT1(n) (*(u8 *)n)
68 68
69static int debug; 69static int debug;
70static DEFINE_SPINLOCK(snmp_lock); 70static DEFINE_SPINLOCK(snmp_lock);
@@ -613,7 +613,7 @@ struct snmp_v1_trap
613static inline void mangle_address(unsigned char *begin, 613static inline void mangle_address(unsigned char *begin,
614 unsigned char *addr, 614 unsigned char *addr,
615 const struct oct1_map *map, 615 const struct oct1_map *map,
616 u_int16_t *check); 616 __sum16 *check);
617struct snmp_cnv 617struct snmp_cnv
618{ 618{
619 unsigned int class; 619 unsigned int class;
@@ -873,38 +873,24 @@ static unsigned char snmp_request_decode(struct asn1_ctx *ctx,
873 * Fast checksum update for possibly oddly-aligned UDP byte, from the 873 * Fast checksum update for possibly oddly-aligned UDP byte, from the
874 * code example in the draft. 874 * code example in the draft.
875 */ 875 */
876static void fast_csum(unsigned char *csum, 876static void fast_csum(__sum16 *csum,
877 const unsigned char *optr, 877 const unsigned char *optr,
878 const unsigned char *nptr, 878 const unsigned char *nptr,
879 int odd) 879 int offset)
880{ 880{
881 long x, old, new; 881 unsigned char s[4];
882 882
883 x = csum[0] * 256 + csum[1]; 883 if (offset & 1) {
884 884 s[0] = s[2] = 0;
885 x =~ x & 0xFFFF; 885 s[1] = ~*optr;
886 886 s[3] = *nptr;
887 if (odd) old = optr[0] * 256; 887 } else {
888 else old = optr[0]; 888 s[1] = s[3] = 0;
889 889 s[0] = ~*optr;
890 x -= old & 0xFFFF; 890 s[2] = *nptr;
891 if (x <= 0) {
892 x--;
893 x &= 0xFFFF;
894 }
895
896 if (odd) new = nptr[0] * 256;
897 else new = nptr[0];
898
899 x += new & 0xFFFF;
900 if (x & 0x10000) {
901 x++;
902 x &= 0xFFFF;
903 } 891 }
904 892
905 x =~ x & 0xFFFF; 893 *csum = csum_fold(csum_partial(s, 4, ~csum_unfold(*csum)));
906 csum[0] = x / 256;
907 csum[1] = x & 0xFF;
908} 894}
909 895
910/* 896/*
@@ -915,9 +901,9 @@ static void fast_csum(unsigned char *csum,
915static inline void mangle_address(unsigned char *begin, 901static inline void mangle_address(unsigned char *begin,
916 unsigned char *addr, 902 unsigned char *addr,
917 const struct oct1_map *map, 903 const struct oct1_map *map,
918 u_int16_t *check) 904 __sum16 *check)
919{ 905{
920 if (map->from == NOCT1(*addr)) { 906 if (map->from == NOCT1(addr)) {
921 u_int32_t old; 907 u_int32_t old;
922 908
923 if (debug) 909 if (debug)
@@ -927,11 +913,8 @@ static inline void mangle_address(unsigned char *begin,
927 913
928 /* Update UDP checksum if being used */ 914 /* Update UDP checksum if being used */
929 if (*check) { 915 if (*check) {
930 unsigned char odd = !((addr - begin) % 2); 916 fast_csum(check,
931 917 &map->from, &map->to, addr - begin);
932 fast_csum((unsigned char *)check,
933 &map->from, &map->to, odd);
934
935 } 918 }
936 919
937 if (debug) 920 if (debug)
@@ -943,7 +926,7 @@ static inline void mangle_address(unsigned char *begin,
943static unsigned char snmp_trap_decode(struct asn1_ctx *ctx, 926static unsigned char snmp_trap_decode(struct asn1_ctx *ctx,
944 struct snmp_v1_trap *trap, 927 struct snmp_v1_trap *trap,
945 const struct oct1_map *map, 928 const struct oct1_map *map,
946 u_int16_t *check) 929 __sum16 *check)
947{ 930{
948 unsigned int cls, con, tag, len; 931 unsigned int cls, con, tag, len;
949 unsigned char *end; 932 unsigned char *end;
@@ -1037,7 +1020,7 @@ static void hex_dump(unsigned char *buf, size_t len)
1037static int snmp_parse_mangle(unsigned char *msg, 1020static int snmp_parse_mangle(unsigned char *msg,
1038 u_int16_t len, 1021 u_int16_t len,
1039 const struct oct1_map *map, 1022 const struct oct1_map *map,
1040 u_int16_t *check) 1023 __sum16 *check)
1041{ 1024{
1042 unsigned char *eoc, *end; 1025 unsigned char *eoc, *end;
1043 unsigned int cls, con, tag, vers, pdutype; 1026 unsigned int cls, con, tag, vers, pdutype;
@@ -1223,12 +1206,12 @@ static int snmp_translate(struct ip_conntrack *ct,
1223 */ 1206 */
1224 if (dir == IP_CT_DIR_ORIGINAL) { 1207 if (dir == IP_CT_DIR_ORIGINAL) {
1225 /* SNAT traps */ 1208 /* SNAT traps */
1226 map.from = NOCT1(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip); 1209 map.from = NOCT1(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip);
1227 map.to = NOCT1(ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip); 1210 map.to = NOCT1(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip);
1228 } else { 1211 } else {
1229 /* DNAT replies */ 1212 /* DNAT replies */
1230 map.from = NOCT1(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip); 1213 map.from = NOCT1(&ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip);
1231 map.to = NOCT1(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip); 1214 map.to = NOCT1(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip);
1232 } 1215 }
1233 1216
1234 if (map.from == map.to) 1217 if (map.from == map.to)
@@ -1294,11 +1277,11 @@ static struct ip_conntrack_helper snmp_helper = {
1294 .help = help, 1277 .help = help,
1295 .name = "snmp", 1278 .name = "snmp",
1296 1279
1297 .tuple = { .src = { .u = { __constant_htons(SNMP_PORT) } }, 1280 .tuple = {.src = {.u = {.udp = {.port = __constant_htons(SNMP_PORT)}}},
1298 .dst = { .protonum = IPPROTO_UDP }, 1281 .dst = {.protonum = IPPROTO_UDP},
1299 }, 1282 },
1300 .mask = { .src = { .u = { 0xFFFF } }, 1283 .mask = {.src = {.u = {0xFFFF}},
1301 .dst = { .protonum = 0xFF }, 1284 .dst = {.protonum = 0xFF},
1302 }, 1285 },
1303}; 1286};
1304 1287
@@ -1309,11 +1292,11 @@ static struct ip_conntrack_helper snmp_trap_helper = {
1309 .help = help, 1292 .help = help,
1310 .name = "snmp_trap", 1293 .name = "snmp_trap",
1311 1294
1312 .tuple = { .src = { .u = { __constant_htons(SNMP_TRAP_PORT) } }, 1295 .tuple = {.src = {.u = {.udp = {.port = __constant_htons(SNMP_TRAP_PORT)}}},
1313 .dst = { .protonum = IPPROTO_UDP }, 1296 .dst = {.protonum = IPPROTO_UDP},
1314 }, 1297 },
1315 .mask = { .src = { .u = { 0xFFFF } }, 1298 .mask = {.src = {.u = {0xFFFF}},
1316 .dst = { .protonum = 0xFF }, 1299 .dst = {.protonum = 0xFF},
1317 }, 1300 },
1318}; 1301};
1319 1302
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index d85d2de504..ad66328baa 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -44,12 +44,6 @@
44#define DEBUGP(format, args...) 44#define DEBUGP(format, args...)
45#endif 45#endif
46 46
47#define HOOKNAME(hooknum) ((hooknum) == NF_IP_POST_ROUTING ? "POST_ROUTING" \
48 : ((hooknum) == NF_IP_PRE_ROUTING ? "PRE_ROUTING" \
49 : ((hooknum) == NF_IP_LOCAL_OUT ? "LOCAL_OUT" \
50 : ((hooknum) == NF_IP_LOCAL_IN ? "LOCAL_IN" \
51 : "*ERROR*")))
52
53#ifdef CONFIG_XFRM 47#ifdef CONFIG_XFRM
54static void nat_decode_session(struct sk_buff *skb, struct flowi *fl) 48static void nat_decode_session(struct sk_buff *skb, struct flowi *fl)
55{ 49{
diff --git a/net/ipv4/netfilter/ip_nat_tftp.c b/net/ipv4/netfilter/ip_nat_tftp.c
index 94a7801545..604793536f 100644
--- a/net/ipv4/netfilter/ip_nat_tftp.c
+++ b/net/ipv4/netfilter/ip_nat_tftp.c
@@ -55,15 +55,14 @@ static unsigned int help(struct sk_buff **pskb,
55 55
56static void __exit ip_nat_tftp_fini(void) 56static void __exit ip_nat_tftp_fini(void)
57{ 57{
58 ip_nat_tftp_hook = NULL; 58 rcu_assign_pointer(ip_nat_tftp_hook, NULL);
59 /* Make sure noone calls it, meanwhile. */ 59 synchronize_rcu();
60 synchronize_net();
61} 60}
62 61
63static int __init ip_nat_tftp_init(void) 62static int __init ip_nat_tftp_init(void)
64{ 63{
65 BUG_ON(ip_nat_tftp_hook); 64 BUG_ON(rcu_dereference(ip_nat_tftp_hook));
66 ip_nat_tftp_hook = help; 65 rcu_assign_pointer(ip_nat_tftp_hook, help);
67 return 0; 66 return 0;
68} 67}
69 68
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index 97556cc2e4..cd520df4dc 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -243,7 +243,7 @@ ipq_build_packet_message(struct ipq_queue_entry *entry, int *errp)
243 pmsg->data_len = data_len; 243 pmsg->data_len = data_len;
244 pmsg->timestamp_sec = entry->skb->tstamp.off_sec; 244 pmsg->timestamp_sec = entry->skb->tstamp.off_sec;
245 pmsg->timestamp_usec = entry->skb->tstamp.off_usec; 245 pmsg->timestamp_usec = entry->skb->tstamp.off_usec;
246 pmsg->mark = entry->skb->nfmark; 246 pmsg->mark = entry->skb->mark;
247 pmsg->hook = entry->info->hook; 247 pmsg->hook = entry->info->hook;
248 pmsg->hw_protocol = entry->skb->protocol; 248 pmsg->hw_protocol = entry->skb->protocol;
249 249
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 8a455439b1..fc1f153c86 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -384,6 +384,7 @@ mark_source_chains(struct xt_table_info *newinfo,
384 for (;;) { 384 for (;;) {
385 struct ipt_standard_target *t 385 struct ipt_standard_target *t
386 = (void *)ipt_get_target(e); 386 = (void *)ipt_get_target(e);
387 int visited = e->comefrom & (1 << hook);
387 388
388 if (e->comefrom & (1 << NF_IP_NUMHOOKS)) { 389 if (e->comefrom & (1 << NF_IP_NUMHOOKS)) {
389 printk("iptables: loop hook %u pos %u %08X.\n", 390 printk("iptables: loop hook %u pos %u %08X.\n",
@@ -394,13 +395,20 @@ mark_source_chains(struct xt_table_info *newinfo,
394 |= ((1 << hook) | (1 << NF_IP_NUMHOOKS)); 395 |= ((1 << hook) | (1 << NF_IP_NUMHOOKS));
395 396
396 /* Unconditional return/END. */ 397 /* Unconditional return/END. */
397 if (e->target_offset == sizeof(struct ipt_entry) 398 if ((e->target_offset == sizeof(struct ipt_entry)
398 && (strcmp(t->target.u.user.name, 399 && (strcmp(t->target.u.user.name,
399 IPT_STANDARD_TARGET) == 0) 400 IPT_STANDARD_TARGET) == 0)
400 && t->verdict < 0 401 && t->verdict < 0
401 && unconditional(&e->ip)) { 402 && unconditional(&e->ip)) || visited) {
402 unsigned int oldpos, size; 403 unsigned int oldpos, size;
403 404
405 if (t->verdict < -NF_MAX_VERDICT - 1) {
406 duprintf("mark_source_chains: bad "
407 "negative verdict (%i)\n",
408 t->verdict);
409 return 0;
410 }
411
404 /* Return: backtrack through the last 412 /* Return: backtrack through the last
405 big jump. */ 413 big jump. */
406 do { 414 do {
@@ -438,6 +446,13 @@ mark_source_chains(struct xt_table_info *newinfo,
438 if (strcmp(t->target.u.user.name, 446 if (strcmp(t->target.u.user.name,
439 IPT_STANDARD_TARGET) == 0 447 IPT_STANDARD_TARGET) == 0
440 && newpos >= 0) { 448 && newpos >= 0) {
449 if (newpos > newinfo->size -
450 sizeof(struct ipt_entry)) {
451 duprintf("mark_source_chains: "
452 "bad verdict (%i)\n",
453 newpos);
454 return 0;
455 }
441 /* This a jump; chase it. */ 456 /* This a jump; chase it. */
442 duprintf("Jump rule %u -> %u\n", 457 duprintf("Jump rule %u -> %u\n",
443 pos, newpos); 458 pos, newpos);
@@ -470,28 +485,47 @@ cleanup_match(struct ipt_entry_match *m, unsigned int *i)
470} 485}
471 486
472static inline int 487static inline int
473standard_check(const struct ipt_entry_target *t, 488check_entry(struct ipt_entry *e, const char *name)
474 unsigned int max_offset)
475{ 489{
476 struct ipt_standard_target *targ = (void *)t; 490 struct ipt_entry_target *t;
477 491
478 /* Check standard info. */ 492 if (!ip_checkentry(&e->ip)) {
479 if (targ->verdict >= 0 493 duprintf("ip_tables: ip check failed %p %s.\n", e, name);
480 && targ->verdict > max_offset - sizeof(struct ipt_entry)) { 494 return -EINVAL;
481 duprintf("ipt_standard_check: bad verdict (%i)\n",
482 targ->verdict);
483 return 0;
484 } 495 }
485 if (targ->verdict < -NF_MAX_VERDICT - 1) { 496
486 duprintf("ipt_standard_check: bad negative verdict (%i)\n", 497 if (e->target_offset + sizeof(struct ipt_entry_target) > e->next_offset)
487 targ->verdict); 498 return -EINVAL;
488 return 0; 499
500 t = ipt_get_target(e);
501 if (e->target_offset + t->u.target_size > e->next_offset)
502 return -EINVAL;
503
504 return 0;
505}
506
507static inline int check_match(struct ipt_entry_match *m, const char *name,
508 const struct ipt_ip *ip, unsigned int hookmask)
509{
510 struct ipt_match *match;
511 int ret;
512
513 match = m->u.kernel.match;
514 ret = xt_check_match(match, AF_INET, m->u.match_size - sizeof(*m),
515 name, hookmask, ip->proto,
516 ip->invflags & IPT_INV_PROTO);
517 if (!ret && m->u.kernel.match->checkentry
518 && !m->u.kernel.match->checkentry(name, ip, match, m->data,
519 hookmask)) {
520 duprintf("ip_tables: check failed for `%s'.\n",
521 m->u.kernel.match->name);
522 ret = -EINVAL;
489 } 523 }
490 return 1; 524 return ret;
491} 525}
492 526
493static inline int 527static inline int
494check_match(struct ipt_entry_match *m, 528find_check_match(struct ipt_entry_match *m,
495 const char *name, 529 const char *name,
496 const struct ipt_ip *ip, 530 const struct ipt_ip *ip,
497 unsigned int hookmask, 531 unsigned int hookmask,
@@ -504,26 +538,15 @@ check_match(struct ipt_entry_match *m,
504 m->u.user.revision), 538 m->u.user.revision),
505 "ipt_%s", m->u.user.name); 539 "ipt_%s", m->u.user.name);
506 if (IS_ERR(match) || !match) { 540 if (IS_ERR(match) || !match) {
507 duprintf("check_match: `%s' not found\n", m->u.user.name); 541 duprintf("find_check_match: `%s' not found\n", m->u.user.name);
508 return match ? PTR_ERR(match) : -ENOENT; 542 return match ? PTR_ERR(match) : -ENOENT;
509 } 543 }
510 m->u.kernel.match = match; 544 m->u.kernel.match = match;
511 545
512 ret = xt_check_match(match, AF_INET, m->u.match_size - sizeof(*m), 546 ret = check_match(m, name, ip, hookmask);
513 name, hookmask, ip->proto,
514 ip->invflags & IPT_INV_PROTO);
515 if (ret) 547 if (ret)
516 goto err; 548 goto err;
517 549
518 if (m->u.kernel.match->checkentry
519 && !m->u.kernel.match->checkentry(name, ip, match, m->data,
520 hookmask)) {
521 duprintf("ip_tables: check failed for `%s'.\n",
522 m->u.kernel.match->name);
523 ret = -EINVAL;
524 goto err;
525 }
526
527 (*i)++; 550 (*i)++;
528 return 0; 551 return 0;
529err: 552err:
@@ -531,10 +554,29 @@ err:
531 return ret; 554 return ret;
532} 555}
533 556
534static struct ipt_target ipt_standard_target; 557static inline int check_target(struct ipt_entry *e, const char *name)
558{
559 struct ipt_entry_target *t;
560 struct ipt_target *target;
561 int ret;
562
563 t = ipt_get_target(e);
564 target = t->u.kernel.target;
565 ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t),
566 name, e->comefrom, e->ip.proto,
567 e->ip.invflags & IPT_INV_PROTO);
568 if (!ret && t->u.kernel.target->checkentry
569 && !t->u.kernel.target->checkentry(name, e, target,
570 t->data, e->comefrom)) {
571 duprintf("ip_tables: check failed for `%s'.\n",
572 t->u.kernel.target->name);
573 ret = -EINVAL;
574 }
575 return ret;
576}
535 577
536static inline int 578static inline int
537check_entry(struct ipt_entry *e, const char *name, unsigned int size, 579find_check_entry(struct ipt_entry *e, const char *name, unsigned int size,
538 unsigned int *i) 580 unsigned int *i)
539{ 581{
540 struct ipt_entry_target *t; 582 struct ipt_entry_target *t;
@@ -542,54 +584,32 @@ check_entry(struct ipt_entry *e, const char *name, unsigned int size,
542 int ret; 584 int ret;
543 unsigned int j; 585 unsigned int j;
544 586
545 if (!ip_checkentry(&e->ip)) { 587 ret = check_entry(e, name);
546 duprintf("ip_tables: ip check failed %p %s.\n", e, name); 588 if (ret)
547 return -EINVAL; 589 return ret;
548 }
549
550 if (e->target_offset + sizeof(struct ipt_entry_target) > e->next_offset)
551 return -EINVAL;
552 590
553 j = 0; 591 j = 0;
554 ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom, &j); 592 ret = IPT_MATCH_ITERATE(e, find_check_match, name, &e->ip,
593 e->comefrom, &j);
555 if (ret != 0) 594 if (ret != 0)
556 goto cleanup_matches; 595 goto cleanup_matches;
557 596
558 t = ipt_get_target(e); 597 t = ipt_get_target(e);
559 ret = -EINVAL;
560 if (e->target_offset + t->u.target_size > e->next_offset)
561 goto cleanup_matches;
562 target = try_then_request_module(xt_find_target(AF_INET, 598 target = try_then_request_module(xt_find_target(AF_INET,
563 t->u.user.name, 599 t->u.user.name,
564 t->u.user.revision), 600 t->u.user.revision),
565 "ipt_%s", t->u.user.name); 601 "ipt_%s", t->u.user.name);
566 if (IS_ERR(target) || !target) { 602 if (IS_ERR(target) || !target) {
567 duprintf("check_entry: `%s' not found\n", t->u.user.name); 603 duprintf("find_check_entry: `%s' not found\n", t->u.user.name);
568 ret = target ? PTR_ERR(target) : -ENOENT; 604 ret = target ? PTR_ERR(target) : -ENOENT;
569 goto cleanup_matches; 605 goto cleanup_matches;
570 } 606 }
571 t->u.kernel.target = target; 607 t->u.kernel.target = target;
572 608
573 ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t), 609 ret = check_target(e, name);
574 name, e->comefrom, e->ip.proto,
575 e->ip.invflags & IPT_INV_PROTO);
576 if (ret) 610 if (ret)
577 goto err; 611 goto err;
578 612
579 if (t->u.kernel.target == &ipt_standard_target) {
580 if (!standard_check(t, size)) {
581 ret = -EINVAL;
582 goto err;
583 }
584 } else if (t->u.kernel.target->checkentry
585 && !t->u.kernel.target->checkentry(name, e, target, t->data,
586 e->comefrom)) {
587 duprintf("ip_tables: check failed for `%s'.\n",
588 t->u.kernel.target->name);
589 ret = -EINVAL;
590 goto err;
591 }
592
593 (*i)++; 613 (*i)++;
594 return 0; 614 return 0;
595 err: 615 err:
@@ -718,17 +738,19 @@ translate_table(const char *name,
718 } 738 }
719 } 739 }
720 740
741 if (!mark_source_chains(newinfo, valid_hooks, entry0))
742 return -ELOOP;
743
721 /* Finally, each sanity check must pass */ 744 /* Finally, each sanity check must pass */
722 i = 0; 745 i = 0;
723 ret = IPT_ENTRY_ITERATE(entry0, newinfo->size, 746 ret = IPT_ENTRY_ITERATE(entry0, newinfo->size,
724 check_entry, name, size, &i); 747 find_check_entry, name, size, &i);
725 748
726 if (ret != 0) 749 if (ret != 0) {
727 goto cleanup; 750 IPT_ENTRY_ITERATE(entry0, newinfo->size,
728 751 cleanup_entry, &i);
729 ret = -ELOOP; 752 return ret;
730 if (!mark_source_chains(newinfo, valid_hooks, entry0)) 753 }
731 goto cleanup;
732 754
733 /* And one copy for every other CPU */ 755 /* And one copy for every other CPU */
734 for_each_possible_cpu(i) { 756 for_each_possible_cpu(i) {
@@ -736,9 +758,6 @@ translate_table(const char *name,
736 memcpy(newinfo->entries[i], entry0, newinfo->size); 758 memcpy(newinfo->entries[i], entry0, newinfo->size);
737 } 759 }
738 760
739 return 0;
740cleanup:
741 IPT_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i);
742 return ret; 761 return ret;
743} 762}
744 763
@@ -900,13 +919,13 @@ copy_entries_to_user(unsigned int total_size,
900#ifdef CONFIG_COMPAT 919#ifdef CONFIG_COMPAT
901struct compat_delta { 920struct compat_delta {
902 struct compat_delta *next; 921 struct compat_delta *next;
903 u_int16_t offset; 922 unsigned int offset;
904 short delta; 923 short delta;
905}; 924};
906 925
907static struct compat_delta *compat_offsets = NULL; 926static struct compat_delta *compat_offsets = NULL;
908 927
909static int compat_add_offset(u_int16_t offset, short delta) 928static int compat_add_offset(unsigned int offset, short delta)
910{ 929{
911 struct compat_delta *tmp; 930 struct compat_delta *tmp;
912 931
@@ -938,7 +957,7 @@ static void compat_flush_offsets(void)
938 } 957 }
939} 958}
940 959
941static short compat_calc_jump(u_int16_t offset) 960static short compat_calc_jump(unsigned int offset)
942{ 961{
943 struct compat_delta *tmp; 962 struct compat_delta *tmp;
944 short delta; 963 short delta;
@@ -978,7 +997,7 @@ static int compat_calc_entry(struct ipt_entry *e, struct xt_table_info *info,
978 void *base, struct xt_table_info *newinfo) 997 void *base, struct xt_table_info *newinfo)
979{ 998{
980 struct ipt_entry_target *t; 999 struct ipt_entry_target *t;
981 u_int16_t entry_offset; 1000 unsigned int entry_offset;
982 int off, i, ret; 1001 int off, i, ret;
983 1002
984 off = 0; 1003 off = 0;
@@ -1448,7 +1467,7 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
1448{ 1467{
1449 struct ipt_entry_target *t; 1468 struct ipt_entry_target *t;
1450 struct ipt_target *target; 1469 struct ipt_target *target;
1451 u_int16_t entry_offset; 1470 unsigned int entry_offset;
1452 int ret, off, h, j; 1471 int ret, off, h, j;
1453 1472
1454 duprintf("check_compat_entry_size_and_hooks %p\n", e); 1473 duprintf("check_compat_entry_size_and_hooks %p\n", e);
@@ -1465,14 +1484,9 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
1465 return -EINVAL; 1484 return -EINVAL;
1466 } 1485 }
1467 1486
1468 if (!ip_checkentry(&e->ip)) { 1487 ret = check_entry(e, name);
1469 duprintf("ip_tables: ip check failed %p %s.\n", e, name); 1488 if (ret)
1470 return -EINVAL; 1489 return ret;
1471 }
1472
1473 if (e->target_offset + sizeof(struct compat_xt_entry_target) >
1474 e->next_offset)
1475 return -EINVAL;
1476 1490
1477 off = 0; 1491 off = 0;
1478 entry_offset = (void *)e - (void *)base; 1492 entry_offset = (void *)e - (void *)base;
@@ -1483,15 +1497,13 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
1483 goto cleanup_matches; 1497 goto cleanup_matches;
1484 1498
1485 t = ipt_get_target(e); 1499 t = ipt_get_target(e);
1486 ret = -EINVAL;
1487 if (e->target_offset + t->u.target_size > e->next_offset)
1488 goto cleanup_matches;
1489 target = try_then_request_module(xt_find_target(AF_INET, 1500 target = try_then_request_module(xt_find_target(AF_INET,
1490 t->u.user.name, 1501 t->u.user.name,
1491 t->u.user.revision), 1502 t->u.user.revision),
1492 "ipt_%s", t->u.user.name); 1503 "ipt_%s", t->u.user.name);
1493 if (IS_ERR(target) || !target) { 1504 if (IS_ERR(target) || !target) {
1494 duprintf("check_entry: `%s' not found\n", t->u.user.name); 1505 duprintf("check_compat_entry_size_and_hooks: `%s' not found\n",
1506 t->u.user.name);
1495 ret = target ? PTR_ERR(target) : -ENOENT; 1507 ret = target ? PTR_ERR(target) : -ENOENT;
1496 goto cleanup_matches; 1508 goto cleanup_matches;
1497 } 1509 }
@@ -1529,25 +1541,8 @@ static inline int compat_copy_match_from_user(struct ipt_entry_match *m,
1529 void **dstptr, compat_uint_t *size, const char *name, 1541 void **dstptr, compat_uint_t *size, const char *name,
1530 const struct ipt_ip *ip, unsigned int hookmask) 1542 const struct ipt_ip *ip, unsigned int hookmask)
1531{ 1543{
1532 struct ipt_entry_match *dm;
1533 struct ipt_match *match;
1534 int ret;
1535
1536 dm = (struct ipt_entry_match *)*dstptr;
1537 match = m->u.kernel.match;
1538 xt_compat_match_from_user(m, dstptr, size); 1544 xt_compat_match_from_user(m, dstptr, size);
1539 1545 return 0;
1540 ret = xt_check_match(match, AF_INET, dm->u.match_size - sizeof(*dm),
1541 name, hookmask, ip->proto,
1542 ip->invflags & IPT_INV_PROTO);
1543 if (!ret && m->u.kernel.match->checkentry
1544 && !m->u.kernel.match->checkentry(name, ip, match, dm->data,
1545 hookmask)) {
1546 duprintf("ip_tables: check failed for `%s'.\n",
1547 m->u.kernel.match->name);
1548 ret = -EINVAL;
1549 }
1550 return ret;
1551} 1546}
1552 1547
1553static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr, 1548static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr,
@@ -1569,7 +1564,7 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr,
1569 ret = IPT_MATCH_ITERATE(e, compat_copy_match_from_user, dstptr, size, 1564 ret = IPT_MATCH_ITERATE(e, compat_copy_match_from_user, dstptr, size,
1570 name, &de->ip, de->comefrom); 1565 name, &de->ip, de->comefrom);
1571 if (ret) 1566 if (ret)
1572 goto err; 1567 return ret;
1573 de->target_offset = e->target_offset - (origsize - *size); 1568 de->target_offset = e->target_offset - (origsize - *size);
1574 t = ipt_get_target(e); 1569 t = ipt_get_target(e);
1575 target = t->u.kernel.target; 1570 target = t->u.kernel.target;
@@ -1582,29 +1577,18 @@ static int compat_copy_entry_from_user(struct ipt_entry *e, void **dstptr,
1582 if ((unsigned char *)de - base < newinfo->underflow[h]) 1577 if ((unsigned char *)de - base < newinfo->underflow[h])
1583 newinfo->underflow[h] -= origsize - *size; 1578 newinfo->underflow[h] -= origsize - *size;
1584 } 1579 }
1580 return ret;
1581}
1585 1582
1586 t = ipt_get_target(de); 1583static inline int compat_check_entry(struct ipt_entry *e, const char *name)
1587 target = t->u.kernel.target; 1584{
1588 ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t), 1585 int ret;
1589 name, e->comefrom, e->ip.proto, 1586
1590 e->ip.invflags & IPT_INV_PROTO); 1587 ret = IPT_MATCH_ITERATE(e, check_match, name, &e->ip, e->comefrom);
1591 if (ret) 1588 if (ret)
1592 goto err; 1589 return ret;
1593 1590
1594 ret = -EINVAL; 1591 return check_target(e, name);
1595 if (t->u.kernel.target == &ipt_standard_target) {
1596 if (!standard_check(t, *size))
1597 goto err;
1598 } else if (t->u.kernel.target->checkentry
1599 && !t->u.kernel.target->checkentry(name, de, target,
1600 t->data, de->comefrom)) {
1601 duprintf("ip_tables: compat: check failed for `%s'.\n",
1602 t->u.kernel.target->name);
1603 goto err;
1604 }
1605 ret = 0;
1606err:
1607 return ret;
1608} 1592}
1609 1593
1610static int 1594static int
@@ -1695,6 +1679,11 @@ translate_compat_table(const char *name,
1695 if (!mark_source_chains(newinfo, valid_hooks, entry1)) 1679 if (!mark_source_chains(newinfo, valid_hooks, entry1))
1696 goto free_newinfo; 1680 goto free_newinfo;
1697 1681
1682 ret = IPT_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry,
1683 name);
1684 if (ret)
1685 goto free_newinfo;
1686
1698 /* And one copy for every other CPU */ 1687 /* And one copy for every other CPU */
1699 for_each_possible_cpu(i) 1688 for_each_possible_cpu(i)
1700 if (newinfo->entries[i] && newinfo->entries[i] != entry1) 1689 if (newinfo->entries[i] && newinfo->entries[i] != entry1)
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index 7a29d6e7ba..b1c11160b9 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -40,8 +40,6 @@
40#define DEBUGP 40#define DEBUGP
41#endif 41#endif
42 42
43#define ASSERT_READ_LOCK(x)
44
45MODULE_LICENSE("GPL"); 43MODULE_LICENSE("GPL");
46MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 44MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
47MODULE_DESCRIPTION("iptables target for CLUSTERIP"); 45MODULE_DESCRIPTION("iptables target for CLUSTERIP");
@@ -123,7 +121,6 @@ __clusterip_config_find(__be32 clusterip)
123{ 121{
124 struct list_head *pos; 122 struct list_head *pos;
125 123
126 ASSERT_READ_LOCK(&clusterip_lock);
127 list_for_each(pos, &clusterip_configs) { 124 list_for_each(pos, &clusterip_configs) {
128 struct clusterip_config *c = list_entry(pos, 125 struct clusterip_config *c = list_entry(pos,
129 struct clusterip_config, list); 126 struct clusterip_config, list);
@@ -170,7 +167,6 @@ clusterip_config_init(struct ipt_clusterip_tgt_info *i, __be32 ip,
170 struct net_device *dev) 167 struct net_device *dev)
171{ 168{
172 struct clusterip_config *c; 169 struct clusterip_config *c;
173 char buffer[16];
174 170
175 c = kzalloc(sizeof(*c), GFP_ATOMIC); 171 c = kzalloc(sizeof(*c), GFP_ATOMIC);
176 if (!c) 172 if (!c)
@@ -187,12 +183,17 @@ clusterip_config_init(struct ipt_clusterip_tgt_info *i, __be32 ip,
187 atomic_set(&c->entries, 1); 183 atomic_set(&c->entries, 1);
188 184
189#ifdef CONFIG_PROC_FS 185#ifdef CONFIG_PROC_FS
190 /* create proc dir entry */ 186 {
191 sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(ip)); 187 char buffer[16];
192 c->pde = create_proc_entry(buffer, S_IWUSR|S_IRUSR, clusterip_procdir); 188
193 if (!c->pde) { 189 /* create proc dir entry */
194 kfree(c); 190 sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(ip));
195 return NULL; 191 c->pde = create_proc_entry(buffer, S_IWUSR|S_IRUSR,
192 clusterip_procdir);
193 if (!c->pde) {
194 kfree(c);
195 return NULL;
196 }
196 } 197 }
197 c->pde->proc_fops = &clusterip_proc_fops; 198 c->pde->proc_fops = &clusterip_proc_fops;
198 c->pde->data = c; 199 c->pde->data = c;
@@ -205,6 +206,7 @@ clusterip_config_init(struct ipt_clusterip_tgt_info *i, __be32 ip,
205 return c; 206 return c;
206} 207}
207 208
209#ifdef CONFIG_PROC_FS
208static int 210static int
209clusterip_add_node(struct clusterip_config *c, u_int16_t nodenum) 211clusterip_add_node(struct clusterip_config *c, u_int16_t nodenum)
210{ 212{
@@ -232,6 +234,7 @@ clusterip_del_node(struct clusterip_config *c, u_int16_t nodenum)
232 234
233 return 1; 235 return 1;
234} 236}
237#endif
235 238
236static inline u_int32_t 239static inline u_int32_t
237clusterip_hashfn(struct sk_buff *skb, struct clusterip_config *config) 240clusterip_hashfn(struct sk_buff *skb, struct clusterip_config *config)
@@ -444,6 +447,12 @@ checkentry(const char *tablename,
444 cipinfo->config = config; 447 cipinfo->config = config;
445 } 448 }
446 449
450 if (nf_ct_l3proto_try_module_get(target->family) < 0) {
451 printk(KERN_WARNING "can't load conntrack support for "
452 "proto=%d\n", target->family);
453 return 0;
454 }
455
447 return 1; 456 return 1;
448} 457}
449 458
@@ -457,6 +466,8 @@ static void destroy(const struct xt_target *target, void *targinfo)
457 clusterip_config_entry_put(cipinfo->config); 466 clusterip_config_entry_put(cipinfo->config);
458 467
459 clusterip_config_put(cipinfo->config); 468 clusterip_config_put(cipinfo->config);
469
470 nf_ct_l3proto_module_put(target->family);
460} 471}
461 472
462static struct ipt_target clusterip_tgt = { 473static struct ipt_target clusterip_tgt = {
@@ -680,7 +691,7 @@ static ssize_t clusterip_proc_write(struct file *file, const char __user *input,
680{ 691{
681#define PROC_WRITELEN 10 692#define PROC_WRITELEN 10
682 char buffer[PROC_WRITELEN+1]; 693 char buffer[PROC_WRITELEN+1];
683 struct proc_dir_entry *pde = PDE(file->f_dentry->d_inode); 694 struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode);
684 struct clusterip_config *c = pde->data; 695 struct clusterip_config *c = pde->data;
685 unsigned long nodenum; 696 unsigned long nodenum;
686 697
@@ -737,8 +748,10 @@ static int __init ipt_clusterip_init(void)
737 CLUSTERIP_VERSION); 748 CLUSTERIP_VERSION);
738 return 0; 749 return 0;
739 750
751#ifdef CONFIG_PROC_FS
740cleanup_hook: 752cleanup_hook:
741 nf_unregister_hook(&cip_arp_ops); 753 nf_unregister_hook(&cip_arp_ops);
754#endif /* CONFIG_PROC_FS */
742cleanup_target: 755cleanup_target:
743 ipt_unregister_target(&clusterip_tgt); 756 ipt_unregister_target(&clusterip_tgt);
744 return ret; 757 return ret;
diff --git a/net/ipv4/netfilter/ipt_ECN.c b/net/ipv4/netfilter/ipt_ECN.c
index 1aa4517fbc..b55d670a24 100644
--- a/net/ipv4/netfilter/ipt_ECN.c
+++ b/net/ipv4/netfilter/ipt_ECN.c
@@ -28,17 +28,16 @@ static inline int
28set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo) 28set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
29{ 29{
30 struct iphdr *iph = (*pskb)->nh.iph; 30 struct iphdr *iph = (*pskb)->nh.iph;
31 u_int16_t oldtos;
32 31
33 if ((iph->tos & IPT_ECN_IP_MASK) != (einfo->ip_ect & IPT_ECN_IP_MASK)) { 32 if ((iph->tos & IPT_ECN_IP_MASK) != (einfo->ip_ect & IPT_ECN_IP_MASK)) {
33 __u8 oldtos;
34 if (!skb_make_writable(pskb, sizeof(struct iphdr))) 34 if (!skb_make_writable(pskb, sizeof(struct iphdr)))
35 return 0; 35 return 0;
36 iph = (*pskb)->nh.iph; 36 iph = (*pskb)->nh.iph;
37 oldtos = iph->tos; 37 oldtos = iph->tos;
38 iph->tos &= ~IPT_ECN_IP_MASK; 38 iph->tos &= ~IPT_ECN_IP_MASK;
39 iph->tos |= (einfo->ip_ect & IPT_ECN_IP_MASK); 39 iph->tos |= (einfo->ip_ect & IPT_ECN_IP_MASK);
40 iph->check = nf_csum_update(htons(oldtos) ^ htons(0xFFFF), 40 nf_csum_replace2(&iph->check, htons(oldtos), htons(iph->tos));
41 htons(iph->tos), iph->check);
42 } 41 }
43 return 1; 42 return 1;
44} 43}
@@ -72,10 +71,8 @@ set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
72 if (einfo->operation & IPT_ECN_OP_SET_CWR) 71 if (einfo->operation & IPT_ECN_OP_SET_CWR)
73 tcph->cwr = einfo->proto.tcp.cwr; 72 tcph->cwr = einfo->proto.tcp.cwr;
74 73
75 tcph->check = nf_proto_csum_update((*pskb), 74 nf_proto_csum_replace2(&tcph->check, *pskb,
76 oldval ^ htons(0xFFFF), 75 oldval, ((__be16 *)tcph)[6], 0);
77 ((__be16 *)tcph)[6],
78 tcph->check, 0);
79 return 1; 76 return 1;
80} 77}
81 78
diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c
index 7dc820df8b..c96de16fef 100644
--- a/net/ipv4/netfilter/ipt_LOG.c
+++ b/net/ipv4/netfilter/ipt_LOG.c
@@ -171,11 +171,15 @@ static void dump_packet(const struct nf_loginfo *info,
171 } 171 }
172 break; 172 break;
173 } 173 }
174 case IPPROTO_UDP: { 174 case IPPROTO_UDP:
175 case IPPROTO_UDPLITE: {
175 struct udphdr _udph, *uh; 176 struct udphdr _udph, *uh;
176 177
177 /* Max length: 10 "PROTO=UDP " */ 178 if (ih->protocol == IPPROTO_UDP)
178 printk("PROTO=UDP "); 179 /* Max length: 10 "PROTO=UDP " */
180 printk("PROTO=UDP " );
181 else /* Max length: 14 "PROTO=UDPLITE " */
182 printk("PROTO=UDPLITE ");
179 183
180 if (ntohs(ih->frag_off) & IP_OFFSET) 184 if (ntohs(ih->frag_off) & IP_OFFSET)
181 break; 185 break;
@@ -341,6 +345,7 @@ static void dump_packet(const struct nf_loginfo *info,
341 /* IP: 40+46+6+11+127 = 230 */ 345 /* IP: 40+46+6+11+127 = 230 */
342 /* TCP: 10+max(25,20+30+13+9+32+11+127) = 252 */ 346 /* TCP: 10+max(25,20+30+13+9+32+11+127) = 252 */
343 /* UDP: 10+max(25,20) = 35 */ 347 /* UDP: 10+max(25,20) = 35 */
348 /* UDPLITE: 14+max(25,20) = 39 */
344 /* ICMP: 11+max(25, 18+25+max(19,14,24+3+n+10,3+n+10)) = 91+n */ 349 /* ICMP: 11+max(25, 18+25+max(19,14,24+3+n+10,3+n+10)) = 91+n */
345 /* ESP: 10+max(25)+15 = 50 */ 350 /* ESP: 10+max(25)+15 = 50 */
346 /* AH: 9+max(25)+15 = 49 */ 351 /* AH: 9+max(25)+15 = 49 */
@@ -425,13 +430,8 @@ ipt_log_target(struct sk_buff **pskb,
425 li.u.log.level = loginfo->level; 430 li.u.log.level = loginfo->level;
426 li.u.log.logflags = loginfo->logflags; 431 li.u.log.logflags = loginfo->logflags;
427 432
428 if (loginfo->logflags & IPT_LOG_NFLOG) 433 ipt_log_packet(PF_INET, hooknum, *pskb, in, out, &li,
429 nf_log_packet(PF_INET, hooknum, *pskb, in, out, &li, 434 loginfo->prefix);
430 "%s", loginfo->prefix);
431 else
432 ipt_log_packet(PF_INET, hooknum, *pskb, in, out, &li,
433 loginfo->prefix);
434
435 return IPT_CONTINUE; 435 return IPT_CONTINUE;
436} 436}
437 437
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
index 3dbfcfac8a..d669685afd 100644
--- a/net/ipv4/netfilter/ipt_MASQUERADE.c
+++ b/net/ipv4/netfilter/ipt_MASQUERADE.c
@@ -2,7 +2,7 @@
2 (depending on route). */ 2 (depending on route). */
3 3
4/* (C) 1999-2001 Paul `Rusty' Russell 4/* (C) 1999-2001 Paul `Rusty' Russell
5 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> 5 * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as 8 * it under the terms of the GNU General Public License version 2 as
@@ -20,7 +20,11 @@
20#include <net/checksum.h> 20#include <net/checksum.h>
21#include <net/route.h> 21#include <net/route.h>
22#include <linux/netfilter_ipv4.h> 22#include <linux/netfilter_ipv4.h>
23#ifdef CONFIG_NF_NAT_NEEDED
24#include <net/netfilter/nf_nat_rule.h>
25#else
23#include <linux/netfilter_ipv4/ip_nat_rule.h> 26#include <linux/netfilter_ipv4/ip_nat_rule.h>
27#endif
24#include <linux/netfilter_ipv4/ip_tables.h> 28#include <linux/netfilter_ipv4/ip_tables.h>
25 29
26MODULE_LICENSE("GPL"); 30MODULE_LICENSE("GPL");
@@ -65,23 +69,33 @@ masquerade_target(struct sk_buff **pskb,
65 const struct xt_target *target, 69 const struct xt_target *target,
66 const void *targinfo) 70 const void *targinfo)
67{ 71{
72#ifdef CONFIG_NF_NAT_NEEDED
73 struct nf_conn_nat *nat;
74#endif
68 struct ip_conntrack *ct; 75 struct ip_conntrack *ct;
69 enum ip_conntrack_info ctinfo; 76 enum ip_conntrack_info ctinfo;
70 const struct ip_nat_multi_range_compat *mr;
71 struct ip_nat_range newrange; 77 struct ip_nat_range newrange;
78 const struct ip_nat_multi_range_compat *mr;
72 struct rtable *rt; 79 struct rtable *rt;
73 __be32 newsrc; 80 __be32 newsrc;
74 81
75 IP_NF_ASSERT(hooknum == NF_IP_POST_ROUTING); 82 IP_NF_ASSERT(hooknum == NF_IP_POST_ROUTING);
76 83
77 ct = ip_conntrack_get(*pskb, &ctinfo); 84 ct = ip_conntrack_get(*pskb, &ctinfo);
85#ifdef CONFIG_NF_NAT_NEEDED
86 nat = nfct_nat(ct);
87#endif
78 IP_NF_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED 88 IP_NF_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED
79 || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY)); 89 || ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY));
80 90
81 /* Source address is 0.0.0.0 - locally generated packet that is 91 /* Source address is 0.0.0.0 - locally generated packet that is
82 * probably not supposed to be masqueraded. 92 * probably not supposed to be masqueraded.
83 */ 93 */
94#ifdef CONFIG_NF_NAT_NEEDED
95 if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u3.ip == 0)
96#else
84 if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip == 0) 97 if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip == 0)
98#endif
85 return NF_ACCEPT; 99 return NF_ACCEPT;
86 100
87 mr = targinfo; 101 mr = targinfo;
@@ -93,7 +107,11 @@ masquerade_target(struct sk_buff **pskb,
93 } 107 }
94 108
95 write_lock_bh(&masq_lock); 109 write_lock_bh(&masq_lock);
110#ifdef CONFIG_NF_NAT_NEEDED
111 nat->masq_index = out->ifindex;
112#else
96 ct->nat.masq_index = out->ifindex; 113 ct->nat.masq_index = out->ifindex;
114#endif
97 write_unlock_bh(&masq_lock); 115 write_unlock_bh(&masq_lock);
98 116
99 /* Transfer from original range. */ 117 /* Transfer from original range. */
@@ -110,9 +128,19 @@ static inline int
110device_cmp(struct ip_conntrack *i, void *ifindex) 128device_cmp(struct ip_conntrack *i, void *ifindex)
111{ 129{
112 int ret; 130 int ret;
131#ifdef CONFIG_NF_NAT_NEEDED
132 struct nf_conn_nat *nat = nfct_nat(i);
133
134 if (!nat)
135 return 0;
136#endif
113 137
114 read_lock_bh(&masq_lock); 138 read_lock_bh(&masq_lock);
139#ifdef CONFIG_NF_NAT_NEEDED
140 ret = (nat->masq_index == (int)(long)ifindex);
141#else
115 ret = (i->nat.masq_index == (int)(long)ifindex); 142 ret = (i->nat.masq_index == (int)(long)ifindex);
143#endif
116 read_unlock_bh(&masq_lock); 144 read_unlock_bh(&masq_lock);
117 145
118 return ret; 146 return ret;
diff --git a/net/ipv4/netfilter/ipt_NETMAP.c b/net/ipv4/netfilter/ipt_NETMAP.c
index 58a88f2271..9390e90f2b 100644
--- a/net/ipv4/netfilter/ipt_NETMAP.c
+++ b/net/ipv4/netfilter/ipt_NETMAP.c
@@ -15,7 +15,11 @@
15#include <linux/netdevice.h> 15#include <linux/netdevice.h>
16#include <linux/netfilter.h> 16#include <linux/netfilter.h>
17#include <linux/netfilter_ipv4.h> 17#include <linux/netfilter_ipv4.h>
18#ifdef CONFIG_NF_NAT_NEEDED
19#include <net/netfilter/nf_nat_rule.h>
20#else
18#include <linux/netfilter_ipv4/ip_nat_rule.h> 21#include <linux/netfilter_ipv4/ip_nat_rule.h>
22#endif
19 23
20#define MODULENAME "NETMAP" 24#define MODULENAME "NETMAP"
21MODULE_LICENSE("GPL"); 25MODULE_LICENSE("GPL");
diff --git a/net/ipv4/netfilter/ipt_REDIRECT.c b/net/ipv4/netfilter/ipt_REDIRECT.c
index c0dcfe9d61..462eceb3a1 100644
--- a/net/ipv4/netfilter/ipt_REDIRECT.c
+++ b/net/ipv4/netfilter/ipt_REDIRECT.c
@@ -1,6 +1,6 @@
1/* Redirect. Simple mapping which alters dst to a local IP address. */ 1/* Redirect. Simple mapping which alters dst to a local IP address. */
2/* (C) 1999-2001 Paul `Rusty' Russell 2/* (C) 1999-2001 Paul `Rusty' Russell
3 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> 3 * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
4 * 4 *
5 * 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
6 * 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
@@ -18,7 +18,11 @@
18#include <net/protocol.h> 18#include <net/protocol.h>
19#include <net/checksum.h> 19#include <net/checksum.h>
20#include <linux/netfilter_ipv4.h> 20#include <linux/netfilter_ipv4.h>
21#ifdef CONFIG_NF_NAT_NEEDED
22#include <net/netfilter/nf_nat_rule.h>
23#else
21#include <linux/netfilter_ipv4/ip_nat_rule.h> 24#include <linux/netfilter_ipv4/ip_nat_rule.h>
25#endif
22 26
23MODULE_LICENSE("GPL"); 27MODULE_LICENSE("GPL");
24MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>"); 28MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index 264763adc3..f0319e5ee4 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -76,7 +76,7 @@ static void send_reset(struct sk_buff *oldskb, int hook)
76 76
77 /* This packet will not be the same as the other: clear nf fields */ 77 /* This packet will not be the same as the other: clear nf fields */
78 nf_reset(nskb); 78 nf_reset(nskb);
79 nskb->nfmark = 0; 79 nskb->mark = 0;
80 skb_init_secmark(nskb); 80 skb_init_secmark(nskb);
81 81
82 tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl); 82 tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl);
diff --git a/net/ipv4/netfilter/ipt_SAME.c b/net/ipv4/netfilter/ipt_SAME.c
index b38b13328d..3dcf294113 100644
--- a/net/ipv4/netfilter/ipt_SAME.c
+++ b/net/ipv4/netfilter/ipt_SAME.c
@@ -34,7 +34,11 @@
34#include <net/protocol.h> 34#include <net/protocol.h>
35#include <net/checksum.h> 35#include <net/checksum.h>
36#include <linux/netfilter_ipv4.h> 36#include <linux/netfilter_ipv4.h>
37#ifdef CONFIG_NF_NAT_NEEDED
38#include <net/netfilter/nf_nat_rule.h>
39#else
37#include <linux/netfilter_ipv4/ip_nat_rule.h> 40#include <linux/netfilter_ipv4/ip_nat_rule.h>
41#endif
38#include <linux/netfilter_ipv4/ipt_SAME.h> 42#include <linux/netfilter_ipv4/ipt_SAME.h>
39 43
40MODULE_LICENSE("GPL"); 44MODULE_LICENSE("GPL");
@@ -152,11 +156,17 @@ same_target(struct sk_buff **pskb,
152 Here we calculate the index in same->iparray which 156 Here we calculate the index in same->iparray which
153 holds the ipaddress we should use */ 157 holds the ipaddress we should use */
154 158
159#ifdef CONFIG_NF_NAT_NEEDED
160 tmpip = ntohl(t->src.u3.ip);
161
162 if (!(same->info & IPT_SAME_NODST))
163 tmpip += ntohl(t->dst.u3.ip);
164#else
155 tmpip = ntohl(t->src.ip); 165 tmpip = ntohl(t->src.ip);
156 166
157 if (!(same->info & IPT_SAME_NODST)) 167 if (!(same->info & IPT_SAME_NODST))
158 tmpip += ntohl(t->dst.ip); 168 tmpip += ntohl(t->dst.ip);
159 169#endif
160 aindex = tmpip % same->ipnum; 170 aindex = tmpip % same->ipnum;
161 171
162 new_ip = htonl(same->iparray[aindex]); 172 new_ip = htonl(same->iparray[aindex]);
diff --git a/net/ipv4/netfilter/ipt_TCPMSS.c b/net/ipv4/netfilter/ipt_TCPMSS.c
index 108b6b7631..93eb5c3c18 100644
--- a/net/ipv4/netfilter/ipt_TCPMSS.c
+++ b/net/ipv4/netfilter/ipt_TCPMSS.c
@@ -97,10 +97,8 @@ ipt_tcpmss_target(struct sk_buff **pskb,
97 opt[i+2] = (newmss & 0xff00) >> 8; 97 opt[i+2] = (newmss & 0xff00) >> 8;
98 opt[i+3] = (newmss & 0x00ff); 98 opt[i+3] = (newmss & 0x00ff);
99 99
100 tcph->check = nf_proto_csum_update(*pskb, 100 nf_proto_csum_replace2(&tcph->check, *pskb,
101 htons(oldmss)^htons(0xFFFF), 101 htons(oldmss), htons(newmss), 0);
102 htons(newmss),
103 tcph->check, 0);
104 return IPT_CONTINUE; 102 return IPT_CONTINUE;
105 } 103 }
106 } 104 }
@@ -126,28 +124,22 @@ ipt_tcpmss_target(struct sk_buff **pskb,
126 opt = (u_int8_t *)tcph + sizeof(struct tcphdr); 124 opt = (u_int8_t *)tcph + sizeof(struct tcphdr);
127 memmove(opt + TCPOLEN_MSS, opt, tcplen - sizeof(struct tcphdr)); 125 memmove(opt + TCPOLEN_MSS, opt, tcplen - sizeof(struct tcphdr));
128 126
129 tcph->check = nf_proto_csum_update(*pskb, 127 nf_proto_csum_replace2(&tcph->check, *pskb,
130 htons(tcplen) ^ htons(0xFFFF), 128 htons(tcplen), htons(tcplen + TCPOLEN_MSS), 1);
131 htons(tcplen + TCPOLEN_MSS),
132 tcph->check, 1);
133 opt[0] = TCPOPT_MSS; 129 opt[0] = TCPOPT_MSS;
134 opt[1] = TCPOLEN_MSS; 130 opt[1] = TCPOLEN_MSS;
135 opt[2] = (newmss & 0xff00) >> 8; 131 opt[2] = (newmss & 0xff00) >> 8;
136 opt[3] = (newmss & 0x00ff); 132 opt[3] = (newmss & 0x00ff);
137 133
138 tcph->check = nf_proto_csum_update(*pskb, htonl(~0), *((__be32 *)opt), 134 nf_proto_csum_replace4(&tcph->check, *pskb, 0, *((__be32 *)opt), 0);
139 tcph->check, 0);
140 135
141 oldval = ((__be16 *)tcph)[6]; 136 oldval = ((__be16 *)tcph)[6];
142 tcph->doff += TCPOLEN_MSS/4; 137 tcph->doff += TCPOLEN_MSS/4;
143 tcph->check = nf_proto_csum_update(*pskb, 138 nf_proto_csum_replace2(&tcph->check, *pskb,
144 oldval ^ htons(0xFFFF), 139 oldval, ((__be16 *)tcph)[6], 0);
145 ((__be16 *)tcph)[6],
146 tcph->check, 0);
147 140
148 newtotlen = htons(ntohs(iph->tot_len) + TCPOLEN_MSS); 141 newtotlen = htons(ntohs(iph->tot_len) + TCPOLEN_MSS);
149 iph->check = nf_csum_update(iph->tot_len ^ htons(0xFFFF), 142 nf_csum_replace2(&iph->check, iph->tot_len, newtotlen);
150 newtotlen, iph->check);
151 iph->tot_len = newtotlen; 143 iph->tot_len = newtotlen;
152 return IPT_CONTINUE; 144 return IPT_CONTINUE;
153} 145}
diff --git a/net/ipv4/netfilter/ipt_TOS.c b/net/ipv4/netfilter/ipt_TOS.c
index 83b80b3a5d..18e74ac4d4 100644
--- a/net/ipv4/netfilter/ipt_TOS.c
+++ b/net/ipv4/netfilter/ipt_TOS.c
@@ -30,16 +30,15 @@ target(struct sk_buff **pskb,
30{ 30{
31 const struct ipt_tos_target_info *tosinfo = targinfo; 31 const struct ipt_tos_target_info *tosinfo = targinfo;
32 struct iphdr *iph = (*pskb)->nh.iph; 32 struct iphdr *iph = (*pskb)->nh.iph;
33 u_int16_t oldtos;
34 33
35 if ((iph->tos & IPTOS_TOS_MASK) != tosinfo->tos) { 34 if ((iph->tos & IPTOS_TOS_MASK) != tosinfo->tos) {
35 __u8 oldtos;
36 if (!skb_make_writable(pskb, sizeof(struct iphdr))) 36 if (!skb_make_writable(pskb, sizeof(struct iphdr)))
37 return NF_DROP; 37 return NF_DROP;
38 iph = (*pskb)->nh.iph; 38 iph = (*pskb)->nh.iph;
39 oldtos = iph->tos; 39 oldtos = iph->tos;
40 iph->tos = (iph->tos & IPTOS_PREC_MASK) | tosinfo->tos; 40 iph->tos = (iph->tos & IPTOS_PREC_MASK) | tosinfo->tos;
41 iph->check = nf_csum_update(htons(oldtos) ^ htons(0xFFFF), 41 nf_csum_replace2(&iph->check, htons(oldtos), htons(iph->tos));
42 htons(iph->tos), iph->check);
43 } 42 }
44 return IPT_CONTINUE; 43 return IPT_CONTINUE;
45} 44}
diff --git a/net/ipv4/netfilter/ipt_TTL.c b/net/ipv4/netfilter/ipt_TTL.c
index ac9517d62a..fffe5ca82e 100644
--- a/net/ipv4/netfilter/ipt_TTL.c
+++ b/net/ipv4/netfilter/ipt_TTL.c
@@ -54,9 +54,8 @@ ipt_ttl_target(struct sk_buff **pskb,
54 } 54 }
55 55
56 if (new_ttl != iph->ttl) { 56 if (new_ttl != iph->ttl) {
57 iph->check = nf_csum_update(htons((iph->ttl << 8)) ^ htons(0xFFFF), 57 nf_csum_replace2(&iph->check, htons(iph->ttl << 8),
58 htons(new_ttl << 8), 58 htons(new_ttl << 8));
59 iph->check);
60 iph->ttl = new_ttl; 59 iph->ttl = new_ttl;
61 } 60 }
62 61
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
index 2b104ea54f..dbd34783a6 100644
--- a/net/ipv4/netfilter/ipt_ULOG.c
+++ b/net/ipv4/netfilter/ipt_ULOG.c
@@ -239,7 +239,7 @@ static void ipt_ulog_packet(unsigned int hooknum,
239 pm->data_len = copy_len; 239 pm->data_len = copy_len;
240 pm->timestamp_sec = skb->tstamp.off_sec; 240 pm->timestamp_sec = skb->tstamp.off_sec;
241 pm->timestamp_usec = skb->tstamp.off_usec; 241 pm->timestamp_usec = skb->tstamp.off_usec;
242 pm->mark = skb->nfmark; 242 pm->mark = skb->mark;
243 pm->hook = hooknum; 243 pm->hook = hooknum;
244 if (prefix != NULL) 244 if (prefix != NULL)
245 strncpy(pm->prefix, prefix, sizeof(pm->prefix)); 245 strncpy(pm->prefix, prefix, sizeof(pm->prefix));
diff --git a/net/ipv4/netfilter/ipt_recent.c b/net/ipv4/netfilter/ipt_recent.c
index 126db44e71..4db0e73c56 100644
--- a/net/ipv4/netfilter/ipt_recent.c
+++ b/net/ipv4/netfilter/ipt_recent.c
@@ -401,7 +401,7 @@ static int recent_seq_open(struct inode *inode, struct file *file)
401static ssize_t recent_proc_write(struct file *file, const char __user *input, 401static ssize_t recent_proc_write(struct file *file, const char __user *input,
402 size_t size, loff_t *loff) 402 size_t size, loff_t *loff)
403{ 403{
404 struct proc_dir_entry *pde = PDE(file->f_dentry->d_inode); 404 struct proc_dir_entry *pde = PDE(file->f_path.dentry->d_inode);
405 struct recent_table *t = pde->data; 405 struct recent_table *t = pde->data;
406 struct recent_entry *e; 406 struct recent_entry *e;
407 char buf[sizeof("+255.255.255.255")], *c = buf; 407 char buf[sizeof("+255.255.255.255")], *c = buf;
diff --git a/net/ipv4/netfilter/iptable_mangle.c b/net/ipv4/netfilter/iptable_mangle.c
index b91f358235..af29398894 100644
--- a/net/ipv4/netfilter/iptable_mangle.c
+++ b/net/ipv4/netfilter/iptable_mangle.c
@@ -132,7 +132,7 @@ ipt_local_hook(unsigned int hook,
132 unsigned int ret; 132 unsigned int ret;
133 u_int8_t tos; 133 u_int8_t tos;
134 __be32 saddr, daddr; 134 __be32 saddr, daddr;
135 unsigned long nfmark; 135 u_int32_t mark;
136 136
137 /* root is playing with raw sockets. */ 137 /* root is playing with raw sockets. */
138 if ((*pskb)->len < sizeof(struct iphdr) 138 if ((*pskb)->len < sizeof(struct iphdr)
@@ -143,7 +143,7 @@ ipt_local_hook(unsigned int hook,
143 } 143 }
144 144
145 /* Save things which could affect route */ 145 /* Save things which could affect route */
146 nfmark = (*pskb)->nfmark; 146 mark = (*pskb)->mark;
147 saddr = (*pskb)->nh.iph->saddr; 147 saddr = (*pskb)->nh.iph->saddr;
148 daddr = (*pskb)->nh.iph->daddr; 148 daddr = (*pskb)->nh.iph->daddr;
149 tos = (*pskb)->nh.iph->tos; 149 tos = (*pskb)->nh.iph->tos;
@@ -153,9 +153,7 @@ ipt_local_hook(unsigned int hook,
153 if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE 153 if (ret != NF_DROP && ret != NF_STOLEN && ret != NF_QUEUE
154 && ((*pskb)->nh.iph->saddr != saddr 154 && ((*pskb)->nh.iph->saddr != saddr
155 || (*pskb)->nh.iph->daddr != daddr 155 || (*pskb)->nh.iph->daddr != daddr
156#ifdef CONFIG_IP_ROUTE_FWMARK 156 || (*pskb)->mark != mark
157 || (*pskb)->nfmark != nfmark
158#endif
159 || (*pskb)->nh.iph->tos != tos)) 157 || (*pskb)->nh.iph->tos != tos))
160 if (ip_route_me_harder(pskb, RTN_UNSPEC)) 158 if (ip_route_me_harder(pskb, RTN_UNSPEC))
161 ret = NF_DROP; 159 ret = NF_DROP;
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
index 0af803df82..471b638ced 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -27,7 +27,7 @@
27#include <linux/netfilter_ipv4.h> 27#include <linux/netfilter_ipv4.h>
28#include <net/netfilter/nf_conntrack.h> 28#include <net/netfilter/nf_conntrack.h>
29#include <net/netfilter/nf_conntrack_helper.h> 29#include <net/netfilter/nf_conntrack_helper.h>
30#include <net/netfilter/nf_conntrack_protocol.h> 30#include <net/netfilter/nf_conntrack_l4proto.h>
31#include <net/netfilter/nf_conntrack_l3proto.h> 31#include <net/netfilter/nf_conntrack_l3proto.h>
32#include <net/netfilter/nf_conntrack_core.h> 32#include <net/netfilter/nf_conntrack_core.h>
33#include <net/netfilter/ipv4/nf_conntrack_ipv4.h> 33#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
@@ -38,12 +38,10 @@
38#define DEBUGP(format, args...) 38#define DEBUGP(format, args...)
39#endif 39#endif
40 40
41DECLARE_PER_CPU(struct nf_conntrack_stat, nf_conntrack_stat);
42
43static int ipv4_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff, 41static int ipv4_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
44 struct nf_conntrack_tuple *tuple) 42 struct nf_conntrack_tuple *tuple)
45{ 43{
46 u_int32_t _addrs[2], *ap; 44 __be32 _addrs[2], *ap;
47 ap = skb_header_pointer(skb, nhoff + offsetof(struct iphdr, saddr), 45 ap = skb_header_pointer(skb, nhoff + offsetof(struct iphdr, saddr),
48 sizeof(u_int32_t) * 2, _addrs); 46 sizeof(u_int32_t) * 2, _addrs);
49 if (ap == NULL) 47 if (ap == NULL)
@@ -113,10 +111,12 @@ ipv4_prepare(struct sk_buff **pskb, unsigned int hooknum, unsigned int *dataoff,
113 return NF_ACCEPT; 111 return NF_ACCEPT;
114} 112}
115 113
116int nat_module_is_loaded = 0; 114int nf_nat_module_is_loaded = 0;
115EXPORT_SYMBOL_GPL(nf_nat_module_is_loaded);
116
117static u_int32_t ipv4_get_features(const struct nf_conntrack_tuple *tuple) 117static u_int32_t ipv4_get_features(const struct nf_conntrack_tuple *tuple)
118{ 118{
119 if (nat_module_is_loaded) 119 if (nf_nat_module_is_loaded)
120 return NF_CT_F_NAT; 120 return NF_CT_F_NAT;
121 121
122 return NF_CT_F_BASIC; 122 return NF_CT_F_BASIC;
@@ -268,43 +268,59 @@ static struct nf_hook_ops ipv4_conntrack_ops[] = {
268 }, 268 },
269}; 269};
270 270
271#ifdef CONFIG_SYSCTL 271#if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
272/* From nf_conntrack_proto_icmp.c */ 272static int log_invalid_proto_min = 0;
273extern unsigned int nf_ct_icmp_timeout; 273static int log_invalid_proto_max = 255;
274static struct ctl_table_header *nf_ct_ipv4_sysctl_header;
275 274
276static ctl_table nf_ct_sysctl_table[] = { 275static ctl_table ip_ct_sysctl_table[] = {
277 { 276 {
278 .ctl_name = NET_NF_CONNTRACK_ICMP_TIMEOUT, 277 .ctl_name = NET_IPV4_NF_CONNTRACK_MAX,
279 .procname = "nf_conntrack_icmp_timeout", 278 .procname = "ip_conntrack_max",
280 .data = &nf_ct_icmp_timeout, 279 .data = &nf_conntrack_max,
281 .maxlen = sizeof(unsigned int), 280 .maxlen = sizeof(int),
282 .mode = 0644, 281 .mode = 0644,
283 .proc_handler = &proc_dointvec_jiffies, 282 .proc_handler = &proc_dointvec,
284 }, 283 },
285 { .ctl_name = 0 }
286};
287
288static ctl_table nf_ct_netfilter_table[] = {
289 { 284 {
290 .ctl_name = NET_NETFILTER, 285 .ctl_name = NET_IPV4_NF_CONNTRACK_COUNT,
291 .procname = "netfilter", 286 .procname = "ip_conntrack_count",
292 .mode = 0555, 287 .data = &nf_conntrack_count,
293 .child = nf_ct_sysctl_table, 288 .maxlen = sizeof(int),
289 .mode = 0444,
290 .proc_handler = &proc_dointvec,
291 },
292 {
293 .ctl_name = NET_IPV4_NF_CONNTRACK_BUCKETS,
294 .procname = "ip_conntrack_buckets",
295 .data = &nf_conntrack_htable_size,
296 .maxlen = sizeof(unsigned int),
297 .mode = 0444,
298 .proc_handler = &proc_dointvec,
299 },
300 {
301 .ctl_name = NET_IPV4_NF_CONNTRACK_CHECKSUM,
302 .procname = "ip_conntrack_checksum",
303 .data = &nf_conntrack_checksum,
304 .maxlen = sizeof(int),
305 .mode = 0644,
306 .proc_handler = &proc_dointvec,
294 }, 307 },
295 { .ctl_name = 0 }
296};
297
298static ctl_table nf_ct_net_table[] = {
299 { 308 {
300 .ctl_name = CTL_NET, 309 .ctl_name = NET_IPV4_NF_CONNTRACK_LOG_INVALID,
301 .procname = "net", 310 .procname = "ip_conntrack_log_invalid",
302 .mode = 0555, 311 .data = &nf_ct_log_invalid,
303 .child = nf_ct_netfilter_table, 312 .maxlen = sizeof(unsigned int),
313 .mode = 0644,
314 .proc_handler = &proc_dointvec_minmax,
315 .strategy = &sysctl_intvec,
316 .extra1 = &log_invalid_proto_min,
317 .extra2 = &log_invalid_proto_max,
304 }, 318 },
305 { .ctl_name = 0 } 319 {
320 .ctl_name = 0
321 }
306}; 322};
307#endif 323#endif /* CONFIG_SYSCTL && CONFIG_NF_CONNTRACK_PROC_COMPAT */
308 324
309/* Fast function for those who don't want to parse /proc (and I don't 325/* Fast function for those who don't want to parse /proc (and I don't
310 blame them). */ 326 blame them). */
@@ -396,10 +412,8 @@ static int ipv4_nfattr_to_tuple(struct nfattr *tb[],
396 if (nfattr_bad_size(tb, CTA_IP_MAX, cta_min_ip)) 412 if (nfattr_bad_size(tb, CTA_IP_MAX, cta_min_ip))
397 return -EINVAL; 413 return -EINVAL;
398 414
399 t->src.u3.ip = 415 t->src.u3.ip = *(__be32 *)NFA_DATA(tb[CTA_IP_V4_SRC-1]);
400 *(u_int32_t *)NFA_DATA(tb[CTA_IP_V4_SRC-1]); 416 t->dst.u3.ip = *(__be32 *)NFA_DATA(tb[CTA_IP_V4_DST-1]);
401 t->dst.u3.ip =
402 *(u_int32_t *)NFA_DATA(tb[CTA_IP_V4_DST-1]);
403 417
404 return 0; 418 return 0;
405} 419}
@@ -426,14 +440,15 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 = {
426 .tuple_to_nfattr = ipv4_tuple_to_nfattr, 440 .tuple_to_nfattr = ipv4_tuple_to_nfattr,
427 .nfattr_to_tuple = ipv4_nfattr_to_tuple, 441 .nfattr_to_tuple = ipv4_nfattr_to_tuple,
428#endif 442#endif
443#if defined(CONFIG_SYSCTL) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
444 .ctl_table_path = nf_net_ipv4_netfilter_sysctl_path,
445 .ctl_table = ip_ct_sysctl_table,
446#endif
429 .me = THIS_MODULE, 447 .me = THIS_MODULE,
430}; 448};
431 449
432extern struct nf_conntrack_protocol nf_conntrack_protocol_tcp4;
433extern struct nf_conntrack_protocol nf_conntrack_protocol_udp4;
434extern struct nf_conntrack_protocol nf_conntrack_protocol_icmp;
435
436MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET)); 450MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET));
451MODULE_ALIAS("ip_conntrack");
437MODULE_LICENSE("GPL"); 452MODULE_LICENSE("GPL");
438 453
439static int __init nf_conntrack_l3proto_ipv4_init(void) 454static int __init nf_conntrack_l3proto_ipv4_init(void)
@@ -448,19 +463,19 @@ static int __init nf_conntrack_l3proto_ipv4_init(void)
448 return ret; 463 return ret;
449 } 464 }
450 465
451 ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_tcp4); 466 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_tcp4);
452 if (ret < 0) { 467 if (ret < 0) {
453 printk("nf_conntrack_ipv4: can't register tcp.\n"); 468 printk("nf_conntrack_ipv4: can't register tcp.\n");
454 goto cleanup_sockopt; 469 goto cleanup_sockopt;
455 } 470 }
456 471
457 ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_udp4); 472 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udp4);
458 if (ret < 0) { 473 if (ret < 0) {
459 printk("nf_conntrack_ipv4: can't register udp.\n"); 474 printk("nf_conntrack_ipv4: can't register udp.\n");
460 goto cleanup_tcp; 475 goto cleanup_tcp;
461 } 476 }
462 477
463 ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_icmp); 478 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_icmp);
464 if (ret < 0) { 479 if (ret < 0) {
465 printk("nf_conntrack_ipv4: can't register icmp.\n"); 480 printk("nf_conntrack_ipv4: can't register icmp.\n");
466 goto cleanup_udp; 481 goto cleanup_udp;
@@ -478,28 +493,24 @@ static int __init nf_conntrack_l3proto_ipv4_init(void)
478 printk("nf_conntrack_ipv4: can't register hooks.\n"); 493 printk("nf_conntrack_ipv4: can't register hooks.\n");
479 goto cleanup_ipv4; 494 goto cleanup_ipv4;
480 } 495 }
481#ifdef CONFIG_SYSCTL 496#if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
482 nf_ct_ipv4_sysctl_header = register_sysctl_table(nf_ct_net_table, 0); 497 ret = nf_conntrack_ipv4_compat_init();
483 if (nf_ct_ipv4_sysctl_header == NULL) { 498 if (ret < 0)
484 printk("nf_conntrack: can't register to sysctl.\n");
485 ret = -ENOMEM;
486 goto cleanup_hooks; 499 goto cleanup_hooks;
487 }
488#endif 500#endif
489 return ret; 501 return ret;
490 502#if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
491#ifdef CONFIG_SYSCTL
492 cleanup_hooks: 503 cleanup_hooks:
493 nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops)); 504 nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops));
494#endif 505#endif
495 cleanup_ipv4: 506 cleanup_ipv4:
496 nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4); 507 nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4);
497 cleanup_icmp: 508 cleanup_icmp:
498 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_icmp); 509 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmp);
499 cleanup_udp: 510 cleanup_udp:
500 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_udp4); 511 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp4);
501 cleanup_tcp: 512 cleanup_tcp:
502 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_tcp4); 513 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp4);
503 cleanup_sockopt: 514 cleanup_sockopt:
504 nf_unregister_sockopt(&so_getorigdst); 515 nf_unregister_sockopt(&so_getorigdst);
505 return ret; 516 return ret;
@@ -508,18 +519,16 @@ static int __init nf_conntrack_l3proto_ipv4_init(void)
508static void __exit nf_conntrack_l3proto_ipv4_fini(void) 519static void __exit nf_conntrack_l3proto_ipv4_fini(void)
509{ 520{
510 synchronize_net(); 521 synchronize_net();
511#ifdef CONFIG_SYSCTL 522#if defined(CONFIG_PROC_FS) && defined(CONFIG_NF_CONNTRACK_PROC_COMPAT)
512 unregister_sysctl_table(nf_ct_ipv4_sysctl_header); 523 nf_conntrack_ipv4_compat_fini();
513#endif 524#endif
514 nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops)); 525 nf_unregister_hooks(ipv4_conntrack_ops, ARRAY_SIZE(ipv4_conntrack_ops));
515 nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4); 526 nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv4);
516 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_icmp); 527 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmp);
517 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_udp4); 528 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp4);
518 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_tcp4); 529 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp4);
519 nf_unregister_sockopt(&so_getorigdst); 530 nf_unregister_sockopt(&so_getorigdst);
520} 531}
521 532
522module_init(nf_conntrack_l3proto_ipv4_init); 533module_init(nf_conntrack_l3proto_ipv4_init);
523module_exit(nf_conntrack_l3proto_ipv4_fini); 534module_exit(nf_conntrack_l3proto_ipv4_fini);
524
525EXPORT_SYMBOL(nf_ct_ipv4_gather_frags);
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
new file mode 100644
index 0000000000..3b31bc6496
--- /dev/null
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
@@ -0,0 +1,412 @@
1/* ip_conntrack proc compat - based on ip_conntrack_standalone.c
2 *
3 * (C) 1999-2001 Paul `Rusty' Russell
4 * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
5 *
6 * 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 * published by the Free Software Foundation.
9 */
10#include <linux/types.h>
11#include <linux/proc_fs.h>
12#include <linux/seq_file.h>
13#include <linux/percpu.h>
14
15#include <linux/netfilter.h>
16#include <net/netfilter/nf_conntrack_core.h>
17#include <net/netfilter/nf_conntrack_l3proto.h>
18#include <net/netfilter/nf_conntrack_l4proto.h>
19#include <net/netfilter/nf_conntrack_expect.h>
20
21#if 0
22#define DEBUGP printk
23#else
24#define DEBUGP(format, args...)
25#endif
26
27#ifdef CONFIG_NF_CT_ACCT
28static unsigned int
29seq_print_counters(struct seq_file *s,
30 const struct ip_conntrack_counter *counter)
31{
32 return seq_printf(s, "packets=%llu bytes=%llu ",
33 (unsigned long long)counter->packets,
34 (unsigned long long)counter->bytes);
35}
36#else
37#define seq_print_counters(x, y) 0
38#endif
39
40struct ct_iter_state {
41 unsigned int bucket;
42};
43
44static struct list_head *ct_get_first(struct seq_file *seq)
45{
46 struct ct_iter_state *st = seq->private;
47
48 for (st->bucket = 0;
49 st->bucket < nf_conntrack_htable_size;
50 st->bucket++) {
51 if (!list_empty(&nf_conntrack_hash[st->bucket]))
52 return nf_conntrack_hash[st->bucket].next;
53 }
54 return NULL;
55}
56
57static struct list_head *ct_get_next(struct seq_file *seq, struct list_head *head)
58{
59 struct ct_iter_state *st = seq->private;
60
61 head = head->next;
62 while (head == &nf_conntrack_hash[st->bucket]) {
63 if (++st->bucket >= nf_conntrack_htable_size)
64 return NULL;
65 head = nf_conntrack_hash[st->bucket].next;
66 }
67 return head;
68}
69
70static struct list_head *ct_get_idx(struct seq_file *seq, loff_t pos)
71{
72 struct list_head *head = ct_get_first(seq);
73
74 if (head)
75 while (pos && (head = ct_get_next(seq, head)))
76 pos--;
77 return pos ? NULL : head;
78}
79
80static void *ct_seq_start(struct seq_file *seq, loff_t *pos)
81{
82 read_lock_bh(&nf_conntrack_lock);
83 return ct_get_idx(seq, *pos);
84}
85
86static void *ct_seq_next(struct seq_file *s, void *v, loff_t *pos)
87{
88 (*pos)++;
89 return ct_get_next(s, v);
90}
91
92static void ct_seq_stop(struct seq_file *s, void *v)
93{
94 read_unlock_bh(&nf_conntrack_lock);
95}
96
97static int ct_seq_show(struct seq_file *s, void *v)
98{
99 const struct nf_conntrack_tuple_hash *hash = v;
100 const struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(hash);
101 struct nf_conntrack_l3proto *l3proto;
102 struct nf_conntrack_l4proto *l4proto;
103
104 NF_CT_ASSERT(ct);
105
106 /* we only want to print DIR_ORIGINAL */
107 if (NF_CT_DIRECTION(hash))
108 return 0;
109 if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num != AF_INET)
110 return 0;
111
112 l3proto = __nf_ct_l3proto_find(ct->tuplehash[IP_CT_DIR_ORIGINAL]
113 .tuple.src.l3num);
114 NF_CT_ASSERT(l3proto);
115 l4proto = __nf_ct_l4proto_find(ct->tuplehash[IP_CT_DIR_ORIGINAL]
116 .tuple.src.l3num,
117 ct->tuplehash[IP_CT_DIR_ORIGINAL]
118 .tuple.dst.protonum);
119 NF_CT_ASSERT(l4proto);
120
121 if (seq_printf(s, "%-8s %u %ld ",
122 l4proto->name,
123 ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum,
124 timer_pending(&ct->timeout)
125 ? (long)(ct->timeout.expires - jiffies)/HZ : 0) != 0)
126 return -ENOSPC;
127
128 if (l3proto->print_conntrack(s, ct))
129 return -ENOSPC;
130
131 if (l4proto->print_conntrack(s, ct))
132 return -ENOSPC;
133
134 if (print_tuple(s, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
135 l3proto, l4proto))
136 return -ENOSPC;
137
138 if (seq_print_counters(s, &ct->counters[IP_CT_DIR_ORIGINAL]))
139 return -ENOSPC;
140
141 if (!(test_bit(IPS_SEEN_REPLY_BIT, &ct->status)))
142 if (seq_printf(s, "[UNREPLIED] "))
143 return -ENOSPC;
144
145 if (print_tuple(s, &ct->tuplehash[IP_CT_DIR_REPLY].tuple,
146 l3proto, l4proto))
147 return -ENOSPC;
148
149 if (seq_print_counters(s, &ct->counters[IP_CT_DIR_REPLY]))
150 return -ENOSPC;
151
152 if (test_bit(IPS_ASSURED_BIT, &ct->status))
153 if (seq_printf(s, "[ASSURED] "))
154 return -ENOSPC;
155
156#ifdef CONFIG_NF_CONNTRACK_MARK
157 if (seq_printf(s, "mark=%u ", ct->mark))
158 return -ENOSPC;
159#endif
160
161#ifdef CONFIG_NF_CONNTRACK_SECMARK
162 if (seq_printf(s, "secmark=%u ", ct->secmark))
163 return -ENOSPC;
164#endif
165
166 if (seq_printf(s, "use=%u\n", atomic_read(&ct->ct_general.use)))
167 return -ENOSPC;
168
169 return 0;
170}
171
172static struct seq_operations ct_seq_ops = {
173 .start = ct_seq_start,
174 .next = ct_seq_next,
175 .stop = ct_seq_stop,
176 .show = ct_seq_show
177};
178
179static int ct_open(struct inode *inode, struct file *file)
180{
181 struct seq_file *seq;
182 struct ct_iter_state *st;
183 int ret;
184
185 st = kmalloc(sizeof(struct ct_iter_state), GFP_KERNEL);
186 if (st == NULL)
187 return -ENOMEM;
188 ret = seq_open(file, &ct_seq_ops);
189 if (ret)
190 goto out_free;
191 seq = file->private_data;
192 seq->private = st;
193 memset(st, 0, sizeof(struct ct_iter_state));
194 return ret;
195out_free:
196 kfree(st);
197 return ret;
198}
199
200static struct file_operations ct_file_ops = {
201 .owner = THIS_MODULE,
202 .open = ct_open,
203 .read = seq_read,
204 .llseek = seq_lseek,
205 .release = seq_release_private,
206};
207
208/* expects */
209static void *exp_seq_start(struct seq_file *s, loff_t *pos)
210{
211 struct list_head *e = &nf_conntrack_expect_list;
212 loff_t i;
213
214 /* strange seq_file api calls stop even if we fail,
215 * thus we need to grab lock since stop unlocks */
216 read_lock_bh(&nf_conntrack_lock);
217
218 if (list_empty(e))
219 return NULL;
220
221 for (i = 0; i <= *pos; i++) {
222 e = e->next;
223 if (e == &nf_conntrack_expect_list)
224 return NULL;
225 }
226 return e;
227}
228
229static void *exp_seq_next(struct seq_file *s, void *v, loff_t *pos)
230{
231 struct list_head *e = v;
232
233 ++*pos;
234 e = e->next;
235
236 if (e == &nf_conntrack_expect_list)
237 return NULL;
238
239 return e;
240}
241
242static void exp_seq_stop(struct seq_file *s, void *v)
243{
244 read_unlock_bh(&nf_conntrack_lock);
245}
246
247static int exp_seq_show(struct seq_file *s, void *v)
248{
249 struct nf_conntrack_expect *exp = v;
250
251 if (exp->tuple.src.l3num != AF_INET)
252 return 0;
253
254 if (exp->timeout.function)
255 seq_printf(s, "%ld ", timer_pending(&exp->timeout)
256 ? (long)(exp->timeout.expires - jiffies)/HZ : 0);
257 else
258 seq_printf(s, "- ");
259
260 seq_printf(s, "proto=%u ", exp->tuple.dst.protonum);
261
262 print_tuple(s, &exp->tuple,
263 __nf_ct_l3proto_find(exp->tuple.src.l3num),
264 __nf_ct_l4proto_find(exp->tuple.src.l3num,
265 exp->tuple.dst.protonum));
266 return seq_putc(s, '\n');
267}
268
269static struct seq_operations exp_seq_ops = {
270 .start = exp_seq_start,
271 .next = exp_seq_next,
272 .stop = exp_seq_stop,
273 .show = exp_seq_show
274};
275
276static int exp_open(struct inode *inode, struct file *file)
277{
278 return seq_open(file, &exp_seq_ops);
279}
280
281static struct file_operations ip_exp_file_ops = {
282 .owner = THIS_MODULE,
283 .open = exp_open,
284 .read = seq_read,
285 .llseek = seq_lseek,
286 .release = seq_release
287};
288
289static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
290{
291 int cpu;
292
293 if (*pos == 0)
294 return SEQ_START_TOKEN;
295
296 for (cpu = *pos-1; cpu < NR_CPUS; ++cpu) {
297 if (!cpu_possible(cpu))
298 continue;
299 *pos = cpu+1;
300 return &per_cpu(nf_conntrack_stat, cpu);
301 }
302
303 return NULL;
304}
305
306static void *ct_cpu_seq_next(struct seq_file *seq, void *v, loff_t *pos)
307{
308 int cpu;
309
310 for (cpu = *pos; cpu < NR_CPUS; ++cpu) {
311 if (!cpu_possible(cpu))
312 continue;
313 *pos = cpu+1;
314 return &per_cpu(nf_conntrack_stat, cpu);
315 }
316
317 return NULL;
318}
319
320static void ct_cpu_seq_stop(struct seq_file *seq, void *v)
321{
322}
323
324static int ct_cpu_seq_show(struct seq_file *seq, void *v)
325{
326 unsigned int nr_conntracks = atomic_read(&nf_conntrack_count);
327 struct ip_conntrack_stat *st = v;
328
329 if (v == SEQ_START_TOKEN) {
330 seq_printf(seq, "entries searched found new invalid ignore delete delete_list insert insert_failed drop early_drop icmp_error expect_new expect_create expect_delete\n");
331 return 0;
332 }
333
334 seq_printf(seq, "%08x %08x %08x %08x %08x %08x %08x %08x "
335 "%08x %08x %08x %08x %08x %08x %08x %08x \n",
336 nr_conntracks,
337 st->searched,
338 st->found,
339 st->new,
340 st->invalid,
341 st->ignore,
342 st->delete,
343 st->delete_list,
344 st->insert,
345 st->insert_failed,
346 st->drop,
347 st->early_drop,
348 st->error,
349
350 st->expect_new,
351 st->expect_create,
352 st->expect_delete
353 );
354 return 0;
355}
356
357static struct seq_operations ct_cpu_seq_ops = {
358 .start = ct_cpu_seq_start,
359 .next = ct_cpu_seq_next,
360 .stop = ct_cpu_seq_stop,
361 .show = ct_cpu_seq_show,
362};
363
364static int ct_cpu_seq_open(struct inode *inode, struct file *file)
365{
366 return seq_open(file, &ct_cpu_seq_ops);
367}
368
369static struct file_operations ct_cpu_seq_fops = {
370 .owner = THIS_MODULE,
371 .open = ct_cpu_seq_open,
372 .read = seq_read,
373 .llseek = seq_lseek,
374 .release = seq_release_private,
375};
376
377int __init nf_conntrack_ipv4_compat_init(void)
378{
379 struct proc_dir_entry *proc, *proc_exp, *proc_stat;
380
381 proc = proc_net_fops_create("ip_conntrack", 0440, &ct_file_ops);
382 if (!proc)
383 goto err1;
384
385 proc_exp = proc_net_fops_create("ip_conntrack_expect", 0440,
386 &ip_exp_file_ops);
387 if (!proc_exp)
388 goto err2;
389
390 proc_stat = create_proc_entry("ip_conntrack", S_IRUGO, proc_net_stat);
391 if (!proc_stat)
392 goto err3;
393
394 proc_stat->proc_fops = &ct_cpu_seq_fops;
395 proc_stat->owner = THIS_MODULE;
396
397 return 0;
398
399err3:
400 proc_net_remove("ip_conntrack_expect");
401err2:
402 proc_net_remove("ip_conntrack");
403err1:
404 return -ENOMEM;
405}
406
407void __exit nf_conntrack_ipv4_compat_fini(void)
408{
409 remove_proc_entry("ip_conntrack", proc_net_stat);
410 proc_net_remove("ip_conntrack_expect");
411 proc_net_remove("ip_conntrack");
412}
diff --git a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
index 790f00d500..db9e7c45d3 100644
--- a/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_conntrack_proto_icmp.c
@@ -22,10 +22,10 @@
22#include <net/checksum.h> 22#include <net/checksum.h>
23#include <linux/netfilter_ipv4.h> 23#include <linux/netfilter_ipv4.h>
24#include <net/netfilter/nf_conntrack_tuple.h> 24#include <net/netfilter/nf_conntrack_tuple.h>
25#include <net/netfilter/nf_conntrack_protocol.h> 25#include <net/netfilter/nf_conntrack_l4proto.h>
26#include <net/netfilter/nf_conntrack_core.h> 26#include <net/netfilter/nf_conntrack_core.h>
27 27
28unsigned long nf_ct_icmp_timeout __read_mostly = 30*HZ; 28static unsigned long nf_ct_icmp_timeout __read_mostly = 30*HZ;
29 29
30#if 0 30#if 0
31#define DEBUGP printk 31#define DEBUGP printk
@@ -152,7 +152,7 @@ icmp_error_message(struct sk_buff *skb,
152 struct icmphdr icmp; 152 struct icmphdr icmp;
153 struct iphdr ip; 153 struct iphdr ip;
154 } _in, *inside; 154 } _in, *inside;
155 struct nf_conntrack_protocol *innerproto; 155 struct nf_conntrack_l4proto *innerproto;
156 struct nf_conntrack_tuple_hash *h; 156 struct nf_conntrack_tuple_hash *h;
157 int dataoff; 157 int dataoff;
158 158
@@ -170,7 +170,7 @@ icmp_error_message(struct sk_buff *skb,
170 return -NF_ACCEPT; 170 return -NF_ACCEPT;
171 } 171 }
172 172
173 innerproto = __nf_ct_proto_find(PF_INET, inside->ip.protocol); 173 innerproto = __nf_ct_l4proto_find(PF_INET, inside->ip.protocol);
174 dataoff = skb->nh.iph->ihl*4 + sizeof(inside->icmp); 174 dataoff = skb->nh.iph->ihl*4 + sizeof(inside->icmp);
175 /* Are they talking about one of our connections? */ 175 /* Are they talking about one of our connections? */
176 if (!nf_ct_get_tuple(skb, dataoff, dataoff + inside->ip.ihl*4, PF_INET, 176 if (!nf_ct_get_tuple(skb, dataoff, dataoff + inside->ip.ihl*4, PF_INET,
@@ -311,7 +311,7 @@ static int icmp_nfattr_to_tuple(struct nfattr *tb[],
311 tuple->dst.u.icmp.code = 311 tuple->dst.u.icmp.code =
312 *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_CODE-1]); 312 *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMP_CODE-1]);
313 tuple->src.u.icmp.id = 313 tuple->src.u.icmp.id =
314 *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]); 314 *(__be16 *)NFA_DATA(tb[CTA_PROTO_ICMP_ID-1]);
315 315
316 if (tuple->dst.u.icmp.type >= sizeof(invmap) 316 if (tuple->dst.u.icmp.type >= sizeof(invmap)
317 || !invmap[tuple->dst.u.icmp.type]) 317 || !invmap[tuple->dst.u.icmp.type])
@@ -321,11 +321,42 @@ static int icmp_nfattr_to_tuple(struct nfattr *tb[],
321} 321}
322#endif 322#endif
323 323
324struct nf_conntrack_protocol nf_conntrack_protocol_icmp = 324#ifdef CONFIG_SYSCTL
325static struct ctl_table_header *icmp_sysctl_header;
326static struct ctl_table icmp_sysctl_table[] = {
327 {
328 .ctl_name = NET_NF_CONNTRACK_ICMP_TIMEOUT,
329 .procname = "nf_conntrack_icmp_timeout",
330 .data = &nf_ct_icmp_timeout,
331 .maxlen = sizeof(unsigned int),
332 .mode = 0644,
333 .proc_handler = &proc_dointvec_jiffies,
334 },
335 {
336 .ctl_name = 0
337 }
338};
339#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
340static struct ctl_table icmp_compat_sysctl_table[] = {
341 {
342 .ctl_name = NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT,
343 .procname = "ip_conntrack_icmp_timeout",
344 .data = &nf_ct_icmp_timeout,
345 .maxlen = sizeof(unsigned int),
346 .mode = 0644,
347 .proc_handler = &proc_dointvec_jiffies,
348 },
349 {
350 .ctl_name = 0
351 }
352};
353#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
354#endif /* CONFIG_SYSCTL */
355
356struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp =
325{ 357{
326 .list = { NULL, NULL },
327 .l3proto = PF_INET, 358 .l3proto = PF_INET,
328 .proto = IPPROTO_ICMP, 359 .l4proto = IPPROTO_ICMP,
329 .name = "icmp", 360 .name = "icmp",
330 .pkt_to_tuple = icmp_pkt_to_tuple, 361 .pkt_to_tuple = icmp_pkt_to_tuple,
331 .invert_tuple = icmp_invert_tuple, 362 .invert_tuple = icmp_invert_tuple,
@@ -341,6 +372,12 @@ struct nf_conntrack_protocol nf_conntrack_protocol_icmp =
341 .tuple_to_nfattr = icmp_tuple_to_nfattr, 372 .tuple_to_nfattr = icmp_tuple_to_nfattr,
342 .nfattr_to_tuple = icmp_nfattr_to_tuple, 373 .nfattr_to_tuple = icmp_nfattr_to_tuple,
343#endif 374#endif
375#ifdef CONFIG_SYSCTL
376 .ctl_table_header = &icmp_sysctl_header,
377 .ctl_table = icmp_sysctl_table,
378#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
379 .ctl_compat_table = icmp_compat_sysctl_table,
380#endif
381#endif
344}; 382};
345 383EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_icmp);
346EXPORT_SYMBOL(nf_conntrack_protocol_icmp);
diff --git a/net/ipv4/netfilter/nf_nat_amanda.c b/net/ipv4/netfilter/nf_nat_amanda.c
new file mode 100644
index 0000000000..0f17098917
--- /dev/null
+++ b/net/ipv4/netfilter/nf_nat_amanda.c
@@ -0,0 +1,78 @@
1/* Amanda extension for TCP NAT alteration.
2 * (C) 2002 by Brian J. Murrell <netfilter@interlinx.bc.ca>
3 * based on a copy of HW's ip_nat_irc.c as well as other modules
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version
8 * 2 of the License, or (at your option) any later version.
9 */
10
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/skbuff.h>
14#include <linux/udp.h>
15
16#include <net/netfilter/nf_nat_helper.h>
17#include <net/netfilter/nf_nat_rule.h>
18#include <net/netfilter/nf_conntrack_helper.h>
19#include <net/netfilter/nf_conntrack_expect.h>
20#include <linux/netfilter/nf_conntrack_amanda.h>
21
22MODULE_AUTHOR("Brian J. Murrell <netfilter@interlinx.bc.ca>");
23MODULE_DESCRIPTION("Amanda NAT helper");
24MODULE_LICENSE("GPL");
25MODULE_ALIAS("ip_nat_amanda");
26
27static unsigned int help(struct sk_buff **pskb,
28 enum ip_conntrack_info ctinfo,
29 unsigned int matchoff,
30 unsigned int matchlen,
31 struct nf_conntrack_expect *exp)
32{
33 char buffer[sizeof("65535")];
34 u_int16_t port;
35 unsigned int ret;
36
37 /* Connection comes from client. */
38 exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
39 exp->dir = IP_CT_DIR_ORIGINAL;
40
41 /* When you see the packet, we need to NAT it the same as the
42 * this one (ie. same IP: it will be TCP and master is UDP). */
43 exp->expectfn = nf_nat_follow_master;
44
45 /* Try to get same port: if not, try to change it. */
46 for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) {
47 exp->tuple.dst.u.tcp.port = htons(port);
48 if (nf_conntrack_expect_related(exp) == 0)
49 break;
50 }
51
52 if (port == 0)
53 return NF_DROP;
54
55 sprintf(buffer, "%u", port);
56 ret = nf_nat_mangle_udp_packet(pskb, exp->master, ctinfo,
57 matchoff, matchlen,
58 buffer, strlen(buffer));
59 if (ret != NF_ACCEPT)
60 nf_conntrack_unexpect_related(exp);
61 return ret;
62}
63
64static void __exit nf_nat_amanda_fini(void)
65{
66 rcu_assign_pointer(nf_nat_amanda_hook, NULL);
67 synchronize_rcu();
68}
69
70static int __init nf_nat_amanda_init(void)
71{
72 BUG_ON(rcu_dereference(nf_nat_amanda_hook));
73 rcu_assign_pointer(nf_nat_amanda_hook, help);
74 return 0;
75}
76
77module_init(nf_nat_amanda_init);
78module_exit(nf_nat_amanda_fini);
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
new file mode 100644
index 0000000000..86a92272b0
--- /dev/null
+++ b/net/ipv4/netfilter/nf_nat_core.c
@@ -0,0 +1,647 @@
1/* NAT for netfilter; shared with compatibility layer. */
2
3/* (C) 1999-2001 Paul `Rusty' Russell
4 * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
5 *
6 * 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 * published by the Free Software Foundation.
9 */
10
11#include <linux/module.h>
12#include <linux/types.h>
13#include <linux/timer.h>
14#include <linux/skbuff.h>
15#include <linux/vmalloc.h>
16#include <net/checksum.h>
17#include <net/icmp.h>
18#include <net/ip.h>
19#include <net/tcp.h> /* For tcp_prot in getorigdst */
20#include <linux/icmp.h>
21#include <linux/udp.h>
22#include <linux/jhash.h>
23
24#include <linux/netfilter_ipv4.h>
25#include <net/netfilter/nf_conntrack.h>
26#include <net/netfilter/nf_conntrack_core.h>
27#include <net/netfilter/nf_nat.h>
28#include <net/netfilter/nf_nat_protocol.h>
29#include <net/netfilter/nf_nat_core.h>
30#include <net/netfilter/nf_nat_helper.h>
31#include <net/netfilter/nf_conntrack_helper.h>
32#include <net/netfilter/nf_conntrack_l3proto.h>
33#include <net/netfilter/nf_conntrack_l4proto.h>
34
35#if 0
36#define DEBUGP printk
37#else
38#define DEBUGP(format, args...)
39#endif
40
41static DEFINE_RWLOCK(nf_nat_lock);
42
43static struct nf_conntrack_l3proto *l3proto = NULL;
44
45/* Calculated at init based on memory size */
46static unsigned int nf_nat_htable_size;
47
48static struct list_head *bysource;
49
50#define MAX_IP_NAT_PROTO 256
51static struct nf_nat_protocol *nf_nat_protos[MAX_IP_NAT_PROTO];
52
53static inline struct nf_nat_protocol *
54__nf_nat_proto_find(u_int8_t protonum)
55{
56 return nf_nat_protos[protonum];
57}
58
59struct nf_nat_protocol *
60nf_nat_proto_find_get(u_int8_t protonum)
61{
62 struct nf_nat_protocol *p;
63
64 /* we need to disable preemption to make sure 'p' doesn't get
65 * removed until we've grabbed the reference */
66 preempt_disable();
67 p = __nf_nat_proto_find(protonum);
68 if (!try_module_get(p->me))
69 p = &nf_nat_unknown_protocol;
70 preempt_enable();
71
72 return p;
73}
74EXPORT_SYMBOL_GPL(nf_nat_proto_find_get);
75
76void
77nf_nat_proto_put(struct nf_nat_protocol *p)
78{
79 module_put(p->me);
80}
81EXPORT_SYMBOL_GPL(nf_nat_proto_put);
82
83/* We keep an extra hash for each conntrack, for fast searching. */
84static inline unsigned int
85hash_by_src(const struct nf_conntrack_tuple *tuple)
86{
87 /* Original src, to ensure we map it consistently if poss. */
88 return jhash_3words((__force u32)tuple->src.u3.ip, tuple->src.u.all,
89 tuple->dst.protonum, 0) % nf_nat_htable_size;
90}
91
92/* Noone using conntrack by the time this called. */
93static void nf_nat_cleanup_conntrack(struct nf_conn *conn)
94{
95 struct nf_conn_nat *nat;
96 if (!(conn->status & IPS_NAT_DONE_MASK))
97 return;
98
99 nat = nfct_nat(conn);
100 write_lock_bh(&nf_nat_lock);
101 list_del(&nat->info.bysource);
102 write_unlock_bh(&nf_nat_lock);
103}
104
105/* Is this tuple already taken? (not by us) */
106int
107nf_nat_used_tuple(const struct nf_conntrack_tuple *tuple,
108 const struct nf_conn *ignored_conntrack)
109{
110 /* Conntrack tracking doesn't keep track of outgoing tuples; only
111 incoming ones. NAT means they don't have a fixed mapping,
112 so we invert the tuple and look for the incoming reply.
113
114 We could keep a separate hash if this proves too slow. */
115 struct nf_conntrack_tuple reply;
116
117 nf_ct_invert_tuplepr(&reply, tuple);
118 return nf_conntrack_tuple_taken(&reply, ignored_conntrack);
119}
120EXPORT_SYMBOL(nf_nat_used_tuple);
121
122/* If we source map this tuple so reply looks like reply_tuple, will
123 * that meet the constraints of range. */
124static int
125in_range(const struct nf_conntrack_tuple *tuple,
126 const struct nf_nat_range *range)
127{
128 struct nf_nat_protocol *proto;
129
130 proto = __nf_nat_proto_find(tuple->dst.protonum);
131 /* If we are supposed to map IPs, then we must be in the
132 range specified, otherwise let this drag us onto a new src IP. */
133 if (range->flags & IP_NAT_RANGE_MAP_IPS) {
134 if (ntohl(tuple->src.u3.ip) < ntohl(range->min_ip) ||
135 ntohl(tuple->src.u3.ip) > ntohl(range->max_ip))
136 return 0;
137 }
138
139 if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED) ||
140 proto->in_range(tuple, IP_NAT_MANIP_SRC,
141 &range->min, &range->max))
142 return 1;
143
144 return 0;
145}
146
147static inline int
148same_src(const struct nf_conn *ct,
149 const struct nf_conntrack_tuple *tuple)
150{
151 const struct nf_conntrack_tuple *t;
152
153 t = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
154 return (t->dst.protonum == tuple->dst.protonum &&
155 t->src.u3.ip == tuple->src.u3.ip &&
156 t->src.u.all == tuple->src.u.all);
157}
158
159/* Only called for SRC manip */
160static int
161find_appropriate_src(const struct nf_conntrack_tuple *tuple,
162 struct nf_conntrack_tuple *result,
163 const struct nf_nat_range *range)
164{
165 unsigned int h = hash_by_src(tuple);
166 struct nf_conn_nat *nat;
167 struct nf_conn *ct;
168
169 read_lock_bh(&nf_nat_lock);
170 list_for_each_entry(nat, &bysource[h], info.bysource) {
171 ct = (struct nf_conn *)((char *)nat - offsetof(struct nf_conn, data));
172 if (same_src(ct, tuple)) {
173 /* Copy source part from reply tuple. */
174 nf_ct_invert_tuplepr(result,
175 &ct->tuplehash[IP_CT_DIR_REPLY].tuple);
176 result->dst = tuple->dst;
177
178 if (in_range(result, range)) {
179 read_unlock_bh(&nf_nat_lock);
180 return 1;
181 }
182 }
183 }
184 read_unlock_bh(&nf_nat_lock);
185 return 0;
186}
187
188/* For [FUTURE] fragmentation handling, we want the least-used
189 src-ip/dst-ip/proto triple. Fairness doesn't come into it. Thus
190 if the range specifies 1.2.3.4 ports 10000-10005 and 1.2.3.5 ports
191 1-65535, we don't do pro-rata allocation based on ports; we choose
192 the ip with the lowest src-ip/dst-ip/proto usage.
193*/
194static void
195find_best_ips_proto(struct nf_conntrack_tuple *tuple,
196 const struct nf_nat_range *range,
197 const struct nf_conn *ct,
198 enum nf_nat_manip_type maniptype)
199{
200 __be32 *var_ipp;
201 /* Host order */
202 u_int32_t minip, maxip, j;
203
204 /* No IP mapping? Do nothing. */
205 if (!(range->flags & IP_NAT_RANGE_MAP_IPS))
206 return;
207
208 if (maniptype == IP_NAT_MANIP_SRC)
209 var_ipp = &tuple->src.u3.ip;
210 else
211 var_ipp = &tuple->dst.u3.ip;
212
213 /* Fast path: only one choice. */
214 if (range->min_ip == range->max_ip) {
215 *var_ipp = range->min_ip;
216 return;
217 }
218
219 /* Hashing source and destination IPs gives a fairly even
220 * spread in practice (if there are a small number of IPs
221 * involved, there usually aren't that many connections
222 * anyway). The consistency means that servers see the same
223 * client coming from the same IP (some Internet Banking sites
224 * like this), even across reboots. */
225 minip = ntohl(range->min_ip);
226 maxip = ntohl(range->max_ip);
227 j = jhash_2words((__force u32)tuple->src.u3.ip,
228 (__force u32)tuple->dst.u3.ip, 0);
229 *var_ipp = htonl(minip + j % (maxip - minip + 1));
230}
231
232/* Manipulate the tuple into the range given. For NF_IP_POST_ROUTING,
233 * we change the source to map into the range. For NF_IP_PRE_ROUTING
234 * and NF_IP_LOCAL_OUT, we change the destination to map into the
235 * range. It might not be possible to get a unique tuple, but we try.
236 * At worst (or if we race), we will end up with a final duplicate in
237 * __ip_conntrack_confirm and drop the packet. */
238static void
239get_unique_tuple(struct nf_conntrack_tuple *tuple,
240 const struct nf_conntrack_tuple *orig_tuple,
241 const struct nf_nat_range *range,
242 struct nf_conn *ct,
243 enum nf_nat_manip_type maniptype)
244{
245 struct nf_nat_protocol *proto;
246
247 /* 1) If this srcip/proto/src-proto-part is currently mapped,
248 and that same mapping gives a unique tuple within the given
249 range, use that.
250
251 This is only required for source (ie. NAT/masq) mappings.
252 So far, we don't do local source mappings, so multiple
253 manips not an issue. */
254 if (maniptype == IP_NAT_MANIP_SRC) {
255 if (find_appropriate_src(orig_tuple, tuple, range)) {
256 DEBUGP("get_unique_tuple: Found current src map\n");
257 if (!nf_nat_used_tuple(tuple, ct))
258 return;
259 }
260 }
261
262 /* 2) Select the least-used IP/proto combination in the given
263 range. */
264 *tuple = *orig_tuple;
265 find_best_ips_proto(tuple, range, ct, maniptype);
266
267 /* 3) The per-protocol part of the manip is made to map into
268 the range to make a unique tuple. */
269
270 proto = nf_nat_proto_find_get(orig_tuple->dst.protonum);
271
272 /* Only bother mapping if it's not already in range and unique */
273 if ((!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED) ||
274 proto->in_range(tuple, maniptype, &range->min, &range->max)) &&
275 !nf_nat_used_tuple(tuple, ct)) {
276 nf_nat_proto_put(proto);
277 return;
278 }
279
280 /* Last change: get protocol to try to obtain unique tuple. */
281 proto->unique_tuple(tuple, range, maniptype, ct);
282
283 nf_nat_proto_put(proto);
284}
285
286unsigned int
287nf_nat_setup_info(struct nf_conn *ct,
288 const struct nf_nat_range *range,
289 unsigned int hooknum)
290{
291 struct nf_conntrack_tuple curr_tuple, new_tuple;
292 struct nf_conn_nat *nat = nfct_nat(ct);
293 struct nf_nat_info *info = &nat->info;
294 int have_to_hash = !(ct->status & IPS_NAT_DONE_MASK);
295 enum nf_nat_manip_type maniptype = HOOK2MANIP(hooknum);
296
297 NF_CT_ASSERT(hooknum == NF_IP_PRE_ROUTING ||
298 hooknum == NF_IP_POST_ROUTING ||
299 hooknum == NF_IP_LOCAL_IN ||
300 hooknum == NF_IP_LOCAL_OUT);
301 BUG_ON(nf_nat_initialized(ct, maniptype));
302
303 /* What we've got will look like inverse of reply. Normally
304 this is what is in the conntrack, except for prior
305 manipulations (future optimization: if num_manips == 0,
306 orig_tp =
307 conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple) */
308 nf_ct_invert_tuplepr(&curr_tuple,
309 &ct->tuplehash[IP_CT_DIR_REPLY].tuple);
310
311 get_unique_tuple(&new_tuple, &curr_tuple, range, ct, maniptype);
312
313 if (!nf_ct_tuple_equal(&new_tuple, &curr_tuple)) {
314 struct nf_conntrack_tuple reply;
315
316 /* Alter conntrack table so will recognize replies. */
317 nf_ct_invert_tuplepr(&reply, &new_tuple);
318 nf_conntrack_alter_reply(ct, &reply);
319
320 /* Non-atomic: we own this at the moment. */
321 if (maniptype == IP_NAT_MANIP_SRC)
322 ct->status |= IPS_SRC_NAT;
323 else
324 ct->status |= IPS_DST_NAT;
325 }
326
327 /* Place in source hash if this is the first time. */
328 if (have_to_hash) {
329 unsigned int srchash;
330
331 srchash = hash_by_src(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
332 write_lock_bh(&nf_nat_lock);
333 list_add(&info->bysource, &bysource[srchash]);
334 write_unlock_bh(&nf_nat_lock);
335 }
336
337 /* It's done. */
338 if (maniptype == IP_NAT_MANIP_DST)
339 set_bit(IPS_DST_NAT_DONE_BIT, &ct->status);
340 else
341 set_bit(IPS_SRC_NAT_DONE_BIT, &ct->status);
342
343 return NF_ACCEPT;
344}
345EXPORT_SYMBOL(nf_nat_setup_info);
346
347/* Returns true if succeeded. */
348static int
349manip_pkt(u_int16_t proto,
350 struct sk_buff **pskb,
351 unsigned int iphdroff,
352 const struct nf_conntrack_tuple *target,
353 enum nf_nat_manip_type maniptype)
354{
355 struct iphdr *iph;
356 struct nf_nat_protocol *p;
357
358 if (!skb_make_writable(pskb, iphdroff + sizeof(*iph)))
359 return 0;
360
361 iph = (void *)(*pskb)->data + iphdroff;
362
363 /* Manipulate protcol part. */
364 p = nf_nat_proto_find_get(proto);
365 if (!p->manip_pkt(pskb, iphdroff, target, maniptype)) {
366 nf_nat_proto_put(p);
367 return 0;
368 }
369 nf_nat_proto_put(p);
370
371 iph = (void *)(*pskb)->data + iphdroff;
372
373 if (maniptype == IP_NAT_MANIP_SRC) {
374 nf_csum_replace4(&iph->check, iph->saddr, target->src.u3.ip);
375 iph->saddr = target->src.u3.ip;
376 } else {
377 nf_csum_replace4(&iph->check, iph->daddr, target->dst.u3.ip);
378 iph->daddr = target->dst.u3.ip;
379 }
380 return 1;
381}
382
383/* Do packet manipulations according to nf_nat_setup_info. */
384unsigned int nf_nat_packet(struct nf_conn *ct,
385 enum ip_conntrack_info ctinfo,
386 unsigned int hooknum,
387 struct sk_buff **pskb)
388{
389 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
390 unsigned long statusbit;
391 enum nf_nat_manip_type mtype = HOOK2MANIP(hooknum);
392
393 if (mtype == IP_NAT_MANIP_SRC)
394 statusbit = IPS_SRC_NAT;
395 else
396 statusbit = IPS_DST_NAT;
397
398 /* Invert if this is reply dir. */
399 if (dir == IP_CT_DIR_REPLY)
400 statusbit ^= IPS_NAT_MASK;
401
402 /* Non-atomic: these bits don't change. */
403 if (ct->status & statusbit) {
404 struct nf_conntrack_tuple target;
405
406 /* We are aiming to look like inverse of other direction. */
407 nf_ct_invert_tuplepr(&target, &ct->tuplehash[!dir].tuple);
408
409 if (!manip_pkt(target.dst.protonum, pskb, 0, &target, mtype))
410 return NF_DROP;
411 }
412 return NF_ACCEPT;
413}
414EXPORT_SYMBOL_GPL(nf_nat_packet);
415
416/* Dir is direction ICMP is coming from (opposite to packet it contains) */
417int nf_nat_icmp_reply_translation(struct nf_conn *ct,
418 enum ip_conntrack_info ctinfo,
419 unsigned int hooknum,
420 struct sk_buff **pskb)
421{
422 struct {
423 struct icmphdr icmp;
424 struct iphdr ip;
425 } *inside;
426 struct nf_conntrack_tuple inner, target;
427 int hdrlen = (*pskb)->nh.iph->ihl * 4;
428 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
429 unsigned long statusbit;
430 enum nf_nat_manip_type manip = HOOK2MANIP(hooknum);
431
432 if (!skb_make_writable(pskb, hdrlen + sizeof(*inside)))
433 return 0;
434
435 inside = (void *)(*pskb)->data + (*pskb)->nh.iph->ihl*4;
436
437 /* We're actually going to mangle it beyond trivial checksum
438 adjustment, so make sure the current checksum is correct. */
439 if (nf_ip_checksum(*pskb, hooknum, hdrlen, 0))
440 return 0;
441
442 /* Must be RELATED */
443 NF_CT_ASSERT((*pskb)->nfctinfo == IP_CT_RELATED ||
444 (*pskb)->nfctinfo == IP_CT_RELATED+IP_CT_IS_REPLY);
445
446 /* Redirects on non-null nats must be dropped, else they'll
447 start talking to each other without our translation, and be
448 confused... --RR */
449 if (inside->icmp.type == ICMP_REDIRECT) {
450 /* If NAT isn't finished, assume it and drop. */
451 if ((ct->status & IPS_NAT_DONE_MASK) != IPS_NAT_DONE_MASK)
452 return 0;
453
454 if (ct->status & IPS_NAT_MASK)
455 return 0;
456 }
457
458 DEBUGP("icmp_reply_translation: translating error %p manp %u dir %s\n",
459 *pskb, manip, dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY");
460
461 if (!nf_ct_get_tuple(*pskb,
462 (*pskb)->nh.iph->ihl*4 + sizeof(struct icmphdr),
463 (*pskb)->nh.iph->ihl*4 +
464 sizeof(struct icmphdr) + inside->ip.ihl*4,
465 (u_int16_t)AF_INET,
466 inside->ip.protocol,
467 &inner,
468 l3proto,
469 __nf_ct_l4proto_find((u_int16_t)PF_INET,
470 inside->ip.protocol)))
471 return 0;
472
473 /* Change inner back to look like incoming packet. We do the
474 opposite manip on this hook to normal, because it might not
475 pass all hooks (locally-generated ICMP). Consider incoming
476 packet: PREROUTING (DST manip), routing produces ICMP, goes
477 through POSTROUTING (which must correct the DST manip). */
478 if (!manip_pkt(inside->ip.protocol, pskb,
479 (*pskb)->nh.iph->ihl*4 + sizeof(inside->icmp),
480 &ct->tuplehash[!dir].tuple,
481 !manip))
482 return 0;
483
484 if ((*pskb)->ip_summed != CHECKSUM_PARTIAL) {
485 /* Reloading "inside" here since manip_pkt inner. */
486 inside = (void *)(*pskb)->data + (*pskb)->nh.iph->ihl*4;
487 inside->icmp.checksum = 0;
488 inside->icmp.checksum =
489 csum_fold(skb_checksum(*pskb, hdrlen,
490 (*pskb)->len - hdrlen, 0));
491 }
492
493 /* Change outer to look the reply to an incoming packet
494 * (proto 0 means don't invert per-proto part). */
495 if (manip == IP_NAT_MANIP_SRC)
496 statusbit = IPS_SRC_NAT;
497 else
498 statusbit = IPS_DST_NAT;
499
500 /* Invert if this is reply dir. */
501 if (dir == IP_CT_DIR_REPLY)
502 statusbit ^= IPS_NAT_MASK;
503
504 if (ct->status & statusbit) {
505 nf_ct_invert_tuplepr(&target, &ct->tuplehash[!dir].tuple);
506 if (!manip_pkt(0, pskb, 0, &target, manip))
507 return 0;
508 }
509
510 return 1;
511}
512EXPORT_SYMBOL_GPL(nf_nat_icmp_reply_translation);
513
514/* Protocol registration. */
515int nf_nat_protocol_register(struct nf_nat_protocol *proto)
516{
517 int ret = 0;
518
519 write_lock_bh(&nf_nat_lock);
520 if (nf_nat_protos[proto->protonum] != &nf_nat_unknown_protocol) {
521 ret = -EBUSY;
522 goto out;
523 }
524 nf_nat_protos[proto->protonum] = proto;
525 out:
526 write_unlock_bh(&nf_nat_lock);
527 return ret;
528}
529EXPORT_SYMBOL(nf_nat_protocol_register);
530
531/* Noone stores the protocol anywhere; simply delete it. */
532void nf_nat_protocol_unregister(struct nf_nat_protocol *proto)
533{
534 write_lock_bh(&nf_nat_lock);
535 nf_nat_protos[proto->protonum] = &nf_nat_unknown_protocol;
536 write_unlock_bh(&nf_nat_lock);
537
538 /* Someone could be still looking at the proto in a bh. */
539 synchronize_net();
540}
541EXPORT_SYMBOL(nf_nat_protocol_unregister);
542
543#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
544 defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
545int
546nf_nat_port_range_to_nfattr(struct sk_buff *skb,
547 const struct nf_nat_range *range)
548{
549 NFA_PUT(skb, CTA_PROTONAT_PORT_MIN, sizeof(__be16),
550 &range->min.tcp.port);
551 NFA_PUT(skb, CTA_PROTONAT_PORT_MAX, sizeof(__be16),
552 &range->max.tcp.port);
553
554 return 0;
555
556nfattr_failure:
557 return -1;
558}
559EXPORT_SYMBOL_GPL(nf_nat_port_nfattr_to_range);
560
561int
562nf_nat_port_nfattr_to_range(struct nfattr *tb[], struct nf_nat_range *range)
563{
564 int ret = 0;
565
566 /* we have to return whether we actually parsed something or not */
567
568 if (tb[CTA_PROTONAT_PORT_MIN-1]) {
569 ret = 1;
570 range->min.tcp.port =
571 *(__be16 *)NFA_DATA(tb[CTA_PROTONAT_PORT_MIN-1]);
572 }
573
574 if (!tb[CTA_PROTONAT_PORT_MAX-1]) {
575 if (ret)
576 range->max.tcp.port = range->min.tcp.port;
577 } else {
578 ret = 1;
579 range->max.tcp.port =
580 *(__be16 *)NFA_DATA(tb[CTA_PROTONAT_PORT_MAX-1]);
581 }
582
583 return ret;
584}
585EXPORT_SYMBOL_GPL(nf_nat_port_range_to_nfattr);
586#endif
587
588static int __init nf_nat_init(void)
589{
590 size_t i;
591
592 /* Leave them the same for the moment. */
593 nf_nat_htable_size = nf_conntrack_htable_size;
594
595 /* One vmalloc for both hash tables */
596 bysource = vmalloc(sizeof(struct list_head) * nf_nat_htable_size);
597 if (!bysource)
598 return -ENOMEM;
599
600 /* Sew in builtin protocols. */
601 write_lock_bh(&nf_nat_lock);
602 for (i = 0; i < MAX_IP_NAT_PROTO; i++)
603 nf_nat_protos[i] = &nf_nat_unknown_protocol;
604 nf_nat_protos[IPPROTO_TCP] = &nf_nat_protocol_tcp;
605 nf_nat_protos[IPPROTO_UDP] = &nf_nat_protocol_udp;
606 nf_nat_protos[IPPROTO_ICMP] = &nf_nat_protocol_icmp;
607 write_unlock_bh(&nf_nat_lock);
608
609 for (i = 0; i < nf_nat_htable_size; i++) {
610 INIT_LIST_HEAD(&bysource[i]);
611 }
612
613 /* FIXME: Man, this is a hack. <SIGH> */
614 NF_CT_ASSERT(nf_conntrack_destroyed == NULL);
615 nf_conntrack_destroyed = &nf_nat_cleanup_conntrack;
616
617 /* Initialize fake conntrack so that NAT will skip it */
618 nf_conntrack_untracked.status |= IPS_NAT_DONE_MASK;
619
620 l3proto = nf_ct_l3proto_find_get((u_int16_t)AF_INET);
621 return 0;
622}
623
624/* Clear NAT section of all conntracks, in case we're loaded again. */
625static int clean_nat(struct nf_conn *i, void *data)
626{
627 struct nf_conn_nat *nat = nfct_nat(i);
628
629 if (!nat)
630 return 0;
631 memset(nat, 0, sizeof(nat));
632 i->status &= ~(IPS_NAT_MASK | IPS_NAT_DONE_MASK | IPS_SEQ_ADJUST);
633 return 0;
634}
635
636static void __exit nf_nat_cleanup(void)
637{
638 nf_ct_iterate_cleanup(&clean_nat, NULL);
639 nf_conntrack_destroyed = NULL;
640 vfree(bysource);
641 nf_ct_l3proto_put(l3proto);
642}
643
644MODULE_LICENSE("GPL");
645
646module_init(nf_nat_init);
647module_exit(nf_nat_cleanup);
diff --git a/net/ipv4/netfilter/nf_nat_ftp.c b/net/ipv4/netfilter/nf_nat_ftp.c
new file mode 100644
index 0000000000..751b598017
--- /dev/null
+++ b/net/ipv4/netfilter/nf_nat_ftp.c
@@ -0,0 +1,179 @@
1/* FTP extension for TCP NAT alteration. */
2
3/* (C) 1999-2001 Paul `Rusty' Russell
4 * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
5 *
6 * 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 * published by the Free Software Foundation.
9 */
10
11#include <linux/module.h>
12#include <linux/moduleparam.h>
13#include <linux/ip.h>
14#include <linux/tcp.h>
15#include <linux/netfilter_ipv4.h>
16#include <net/netfilter/nf_nat.h>
17#include <net/netfilter/nf_nat_helper.h>
18#include <net/netfilter/nf_nat_rule.h>
19#include <net/netfilter/nf_conntrack_helper.h>
20#include <net/netfilter/nf_conntrack_expect.h>
21#include <linux/netfilter/nf_conntrack_ftp.h>
22
23MODULE_LICENSE("GPL");
24MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>");
25MODULE_DESCRIPTION("ftp NAT helper");
26MODULE_ALIAS("ip_nat_ftp");
27
28#if 0
29#define DEBUGP printk
30#else
31#define DEBUGP(format, args...)
32#endif
33
34/* FIXME: Time out? --RR */
35
36static int
37mangle_rfc959_packet(struct sk_buff **pskb,
38 __be32 newip,
39 u_int16_t port,
40 unsigned int matchoff,
41 unsigned int matchlen,
42 struct nf_conn *ct,
43 enum ip_conntrack_info ctinfo,
44 u32 *seq)
45{
46 char buffer[sizeof("nnn,nnn,nnn,nnn,nnn,nnn")];
47
48 sprintf(buffer, "%u,%u,%u,%u,%u,%u",
49 NIPQUAD(newip), port>>8, port&0xFF);
50
51 DEBUGP("calling nf_nat_mangle_tcp_packet\n");
52
53 *seq += strlen(buffer) - matchlen;
54 return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff,
55 matchlen, buffer, strlen(buffer));
56}
57
58/* |1|132.235.1.2|6275| */
59static int
60mangle_eprt_packet(struct sk_buff **pskb,
61 __be32 newip,
62 u_int16_t port,
63 unsigned int matchoff,
64 unsigned int matchlen,
65 struct nf_conn *ct,
66 enum ip_conntrack_info ctinfo,
67 u32 *seq)
68{
69 char buffer[sizeof("|1|255.255.255.255|65535|")];
70
71 sprintf(buffer, "|1|%u.%u.%u.%u|%u|", NIPQUAD(newip), port);
72
73 DEBUGP("calling nf_nat_mangle_tcp_packet\n");
74
75 *seq += strlen(buffer) - matchlen;
76 return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff,
77 matchlen, buffer, strlen(buffer));
78}
79
80/* |1|132.235.1.2|6275| */
81static int
82mangle_epsv_packet(struct sk_buff **pskb,
83 __be32 newip,
84 u_int16_t port,
85 unsigned int matchoff,
86 unsigned int matchlen,
87 struct nf_conn *ct,
88 enum ip_conntrack_info ctinfo,
89 u32 *seq)
90{
91 char buffer[sizeof("|||65535|")];
92
93 sprintf(buffer, "|||%u|", port);
94
95 DEBUGP("calling nf_nat_mangle_tcp_packet\n");
96
97 *seq += strlen(buffer) - matchlen;
98 return nf_nat_mangle_tcp_packet(pskb, ct, ctinfo, matchoff,
99 matchlen, buffer, strlen(buffer));
100}
101
102static int (*mangle[])(struct sk_buff **, __be32, u_int16_t,
103 unsigned int, unsigned int, struct nf_conn *,
104 enum ip_conntrack_info, u32 *seq)
105= {
106 [NF_CT_FTP_PORT] = mangle_rfc959_packet,
107 [NF_CT_FTP_PASV] = mangle_rfc959_packet,
108 [NF_CT_FTP_EPRT] = mangle_eprt_packet,
109 [NF_CT_FTP_EPSV] = mangle_epsv_packet
110};
111
112/* So, this packet has hit the connection tracking matching code.
113 Mangle it, and change the expectation to match the new version. */
114static unsigned int nf_nat_ftp(struct sk_buff **pskb,
115 enum ip_conntrack_info ctinfo,
116 enum nf_ct_ftp_type type,
117 unsigned int matchoff,
118 unsigned int matchlen,
119 struct nf_conntrack_expect *exp,
120 u32 *seq)
121{
122 __be32 newip;
123 u_int16_t port;
124 int dir = CTINFO2DIR(ctinfo);
125 struct nf_conn *ct = exp->master;
126
127 DEBUGP("FTP_NAT: type %i, off %u len %u\n", type, matchoff, matchlen);
128
129 /* Connection will come from wherever this packet goes, hence !dir */
130 newip = ct->tuplehash[!dir].tuple.dst.u3.ip;
131 exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
132 exp->dir = !dir;
133
134 /* When you see the packet, we need to NAT it the same as the
135 * this one. */
136 exp->expectfn = nf_nat_follow_master;
137
138 /* Try to get same port: if not, try to change it. */
139 for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) {
140 exp->tuple.dst.u.tcp.port = htons(port);
141 if (nf_conntrack_expect_related(exp) == 0)
142 break;
143 }
144
145 if (port == 0)
146 return NF_DROP;
147
148 if (!mangle[type](pskb, newip, port, matchoff, matchlen, ct, ctinfo,
149 seq)) {
150 nf_conntrack_unexpect_related(exp);
151 return NF_DROP;
152 }
153 return NF_ACCEPT;
154}
155
156static void __exit nf_nat_ftp_fini(void)
157{
158 rcu_assign_pointer(nf_nat_ftp_hook, NULL);
159 synchronize_rcu();
160}
161
162static int __init nf_nat_ftp_init(void)
163{
164 BUG_ON(rcu_dereference(nf_nat_ftp_hook));
165 rcu_assign_pointer(nf_nat_ftp_hook, nf_nat_ftp);
166 return 0;
167}
168
169/* Prior to 2.6.11, we had a ports param. No longer, but don't break users. */
170static int warn_set(const char *val, struct kernel_param *kp)
171{
172 printk(KERN_INFO KBUILD_MODNAME
173 ": kernel >= 2.6.10 only uses 'ports' for conntrack modules\n");
174 return 0;
175}
176module_param_call(ports, warn_set, NULL, NULL, 0);
177
178module_init(nf_nat_ftp_init);
179module_exit(nf_nat_ftp_fini);
diff --git a/net/ipv4/netfilter/nf_nat_h323.c b/net/ipv4/netfilter/nf_nat_h323.c
new file mode 100644
index 0000000000..fb9ab0114c
--- /dev/null
+++ b/net/ipv4/netfilter/nf_nat_h323.c
@@ -0,0 +1,596 @@
1/*
2 * H.323 extension for NAT alteration.
3 *
4 * Copyright (c) 2006 Jing Min Zhao <zhaojingmin@users.sourceforge.net>
5 *
6 * This source code is licensed under General Public License version 2.
7 *
8 * Based on the 'brute force' H.323 NAT module by
9 * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
10 */
11
12#include <linux/module.h>
13#include <linux/moduleparam.h>
14#include <linux/tcp.h>
15#include <net/tcp.h>
16
17#include <net/netfilter/nf_nat.h>
18#include <net/netfilter/nf_nat_helper.h>
19#include <net/netfilter/nf_nat_rule.h>
20#include <net/netfilter/nf_conntrack_helper.h>
21#include <net/netfilter/nf_conntrack_expect.h>
22#include <linux/netfilter/nf_conntrack_h323.h>
23
24#if 0
25#define DEBUGP printk
26#else
27#define DEBUGP(format, args...)
28#endif
29
30/****************************************************************************/
31static int set_addr(struct sk_buff **pskb,
32 unsigned char **data, int dataoff,
33 unsigned int addroff, __be32 ip, __be16 port)
34{
35 enum ip_conntrack_info ctinfo;
36 struct nf_conn *ct = ip_conntrack_get(*pskb, &ctinfo);
37 struct {
38 __be32 ip;
39 __be16 port;
40 } __attribute__ ((__packed__)) buf;
41 struct tcphdr _tcph, *th;
42
43 buf.ip = ip;
44 buf.port = port;
45 addroff += dataoff;
46
47 if ((*pskb)->nh.iph->protocol == IPPROTO_TCP) {
48 if (!nf_nat_mangle_tcp_packet(pskb, ct, ctinfo,
49 addroff, sizeof(buf),
50 (char *) &buf, sizeof(buf))) {
51 if (net_ratelimit())
52 printk("nf_nat_h323: nf_nat_mangle_tcp_packet"
53 " error\n");
54 return -1;
55 }
56
57 /* Relocate data pointer */
58 th = skb_header_pointer(*pskb, (*pskb)->nh.iph->ihl * 4,
59 sizeof(_tcph), &_tcph);
60 if (th == NULL)
61 return -1;
62 *data = (*pskb)->data + (*pskb)->nh.iph->ihl * 4 +
63 th->doff * 4 + dataoff;
64 } else {
65 if (!nf_nat_mangle_udp_packet(pskb, ct, ctinfo,
66 addroff, sizeof(buf),
67 (char *) &buf, sizeof(buf))) {
68 if (net_ratelimit())
69 printk("nf_nat_h323: nf_nat_mangle_udp_packet"
70 " error\n");
71 return -1;
72 }
73 /* nf_nat_mangle_udp_packet uses skb_make_writable() to copy
74 * or pull everything in a linear buffer, so we can safely
75 * use the skb pointers now */
76 *data = (*pskb)->data + (*pskb)->nh.iph->ihl * 4 +
77 sizeof(struct udphdr);
78 }
79
80 return 0;
81}
82
83/****************************************************************************/
84static int set_h225_addr(struct sk_buff **pskb,
85 unsigned char **data, int dataoff,
86 TransportAddress *taddr,
87 union nf_conntrack_address *addr, __be16 port)
88{
89 return set_addr(pskb, data, dataoff, taddr->ipAddress.ip,
90 addr->ip, port);
91}
92
93/****************************************************************************/
94static int set_h245_addr(struct sk_buff **pskb,
95 unsigned char **data, int dataoff,
96 H245_TransportAddress *taddr,
97 union nf_conntrack_address *addr, __be16 port)
98{
99 return set_addr(pskb, data, dataoff,
100 taddr->unicastAddress.iPAddress.network,
101 addr->ip, port);
102}
103
104/****************************************************************************/
105static int set_sig_addr(struct sk_buff **pskb, struct nf_conn *ct,
106 enum ip_conntrack_info ctinfo,
107 unsigned char **data,
108 TransportAddress *taddr, int count)
109{
110 struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;
111 int dir = CTINFO2DIR(ctinfo);
112 int i;
113 __be16 port;
114 union nf_conntrack_address addr;
115
116 for (i = 0; i < count; i++) {
117 if (get_h225_addr(ct, *data, &taddr[i], &addr, &port)) {
118 if (addr.ip == ct->tuplehash[dir].tuple.src.u3.ip &&
119 port == info->sig_port[dir]) {
120 /* GW->GK */
121
122 /* Fix for Gnomemeeting */
123 if (i > 0 &&
124 get_h225_addr(ct, *data, &taddr[0],
125 &addr, &port) &&
126 (ntohl(addr.ip) & 0xff000000) == 0x7f000000)
127 i = 0;
128
129 DEBUGP
130 ("nf_nat_ras: set signal address "
131 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
132 NIPQUAD(ip), port,
133 NIPQUAD(ct->tuplehash[!dir].tuple.dst.
134 ip), info->sig_port[!dir]);
135 return set_h225_addr(pskb, data, 0, &taddr[i],
136 &ct->tuplehash[!dir].
137 tuple.dst.u3,
138 info->sig_port[!dir]);
139 } else if (addr.ip == ct->tuplehash[dir].tuple.dst.u3.ip &&
140 port == info->sig_port[dir]) {
141 /* GK->GW */
142 DEBUGP
143 ("nf_nat_ras: set signal address "
144 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
145 NIPQUAD(ip), port,
146 NIPQUAD(ct->tuplehash[!dir].tuple.src.
147 ip), info->sig_port[!dir]);
148 return set_h225_addr(pskb, data, 0, &taddr[i],
149 &ct->tuplehash[!dir].
150 tuple.src.u3,
151 info->sig_port[!dir]);
152 }
153 }
154 }
155
156 return 0;
157}
158
159/****************************************************************************/
160static int set_ras_addr(struct sk_buff **pskb, struct nf_conn *ct,
161 enum ip_conntrack_info ctinfo,
162 unsigned char **data,
163 TransportAddress *taddr, int count)
164{
165 int dir = CTINFO2DIR(ctinfo);
166 int i;
167 __be16 port;
168 union nf_conntrack_address addr;
169
170 for (i = 0; i < count; i++) {
171 if (get_h225_addr(ct, *data, &taddr[i], &addr, &port) &&
172 addr.ip == ct->tuplehash[dir].tuple.src.u3.ip &&
173 port == ct->tuplehash[dir].tuple.src.u.udp.port) {
174 DEBUGP("nf_nat_ras: set rasAddress "
175 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
176 NIPQUAD(ip), ntohs(port),
177 NIPQUAD(ct->tuplehash[!dir].tuple.dst.u3.ip),
178 ntohs(ct->tuplehash[!dir].tuple.dst.u.udp.
179 port));
180 return set_h225_addr(pskb, data, 0, &taddr[i],
181 &ct->tuplehash[!dir].tuple.dst.u3,
182 ct->tuplehash[!dir].tuple.
183 dst.u.udp.port);
184 }
185 }
186
187 return 0;
188}
189
190/****************************************************************************/
191static int nat_rtp_rtcp(struct sk_buff **pskb, struct nf_conn *ct,
192 enum ip_conntrack_info ctinfo,
193 unsigned char **data, int dataoff,
194 H245_TransportAddress *taddr,
195 __be16 port, __be16 rtp_port,
196 struct nf_conntrack_expect *rtp_exp,
197 struct nf_conntrack_expect *rtcp_exp)
198{
199 struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;
200 int dir = CTINFO2DIR(ctinfo);
201 int i;
202 u_int16_t nated_port;
203
204 /* Set expectations for NAT */
205 rtp_exp->saved_proto.udp.port = rtp_exp->tuple.dst.u.udp.port;
206 rtp_exp->expectfn = nf_nat_follow_master;
207 rtp_exp->dir = !dir;
208 rtcp_exp->saved_proto.udp.port = rtcp_exp->tuple.dst.u.udp.port;
209 rtcp_exp->expectfn = nf_nat_follow_master;
210 rtcp_exp->dir = !dir;
211
212 /* Lookup existing expects */
213 for (i = 0; i < H323_RTP_CHANNEL_MAX; i++) {
214 if (info->rtp_port[i][dir] == rtp_port) {
215 /* Expected */
216
217 /* Use allocated ports first. This will refresh
218 * the expects */
219 rtp_exp->tuple.dst.u.udp.port = info->rtp_port[i][dir];
220 rtcp_exp->tuple.dst.u.udp.port =
221 htons(ntohs(info->rtp_port[i][dir]) + 1);
222 break;
223 } else if (info->rtp_port[i][dir] == 0) {
224 /* Not expected */
225 break;
226 }
227 }
228
229 /* Run out of expectations */
230 if (i >= H323_RTP_CHANNEL_MAX) {
231 if (net_ratelimit())
232 printk("nf_nat_h323: out of expectations\n");
233 return 0;
234 }
235
236 /* Try to get a pair of ports. */
237 for (nated_port = ntohs(rtp_exp->tuple.dst.u.udp.port);
238 nated_port != 0; nated_port += 2) {
239 rtp_exp->tuple.dst.u.udp.port = htons(nated_port);
240 if (nf_conntrack_expect_related(rtp_exp) == 0) {
241 rtcp_exp->tuple.dst.u.udp.port =
242 htons(nated_port + 1);
243 if (nf_conntrack_expect_related(rtcp_exp) == 0)
244 break;
245 nf_conntrack_unexpect_related(rtp_exp);
246 }
247 }
248
249 if (nated_port == 0) { /* No port available */
250 if (net_ratelimit())
251 printk("nf_nat_h323: out of RTP ports\n");
252 return 0;
253 }
254
255 /* Modify signal */
256 if (set_h245_addr(pskb, data, dataoff, taddr,
257 &ct->tuplehash[!dir].tuple.dst.u3,
258 htons((port & htons(1)) ? nated_port + 1 :
259 nated_port)) == 0) {
260 /* Save ports */
261 info->rtp_port[i][dir] = rtp_port;
262 info->rtp_port[i][!dir] = htons(nated_port);
263 } else {
264 nf_conntrack_unexpect_related(rtp_exp);
265 nf_conntrack_unexpect_related(rtcp_exp);
266 return -1;
267 }
268
269 /* Success */
270 DEBUGP("nf_nat_h323: expect RTP %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
271 NIPQUAD(rtp_exp->tuple.src.ip),
272 ntohs(rtp_exp->tuple.src.u.udp.port),
273 NIPQUAD(rtp_exp->tuple.dst.ip),
274 ntohs(rtp_exp->tuple.dst.u.udp.port));
275 DEBUGP("nf_nat_h323: expect RTCP %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
276 NIPQUAD(rtcp_exp->tuple.src.ip),
277 ntohs(rtcp_exp->tuple.src.u.udp.port),
278 NIPQUAD(rtcp_exp->tuple.dst.ip),
279 ntohs(rtcp_exp->tuple.dst.u.udp.port));
280
281 return 0;
282}
283
284/****************************************************************************/
285static int nat_t120(struct sk_buff **pskb, struct nf_conn *ct,
286 enum ip_conntrack_info ctinfo,
287 unsigned char **data, int dataoff,
288 H245_TransportAddress *taddr, __be16 port,
289 struct nf_conntrack_expect *exp)
290{
291 int dir = CTINFO2DIR(ctinfo);
292 u_int16_t nated_port = ntohs(port);
293
294 /* Set expectations for NAT */
295 exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
296 exp->expectfn = nf_nat_follow_master;
297 exp->dir = !dir;
298
299 /* Try to get same port: if not, try to change it. */
300 for (; nated_port != 0; nated_port++) {
301 exp->tuple.dst.u.tcp.port = htons(nated_port);
302 if (nf_conntrack_expect_related(exp) == 0)
303 break;
304 }
305
306 if (nated_port == 0) { /* No port available */
307 if (net_ratelimit())
308 printk("nf_nat_h323: out of TCP ports\n");
309 return 0;
310 }
311
312 /* Modify signal */
313 if (set_h245_addr(pskb, data, dataoff, taddr,
314 &ct->tuplehash[!dir].tuple.dst.u3,
315 htons(nated_port)) < 0) {
316 nf_conntrack_unexpect_related(exp);
317 return -1;
318 }
319
320 DEBUGP("nf_nat_h323: expect T.120 %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
321 NIPQUAD(exp->tuple.src.ip), ntohs(exp->tuple.src.u.tcp.port),
322 NIPQUAD(exp->tuple.dst.ip), ntohs(exp->tuple.dst.u.tcp.port));
323
324 return 0;
325}
326
327/****************************************************************************/
328static int nat_h245(struct sk_buff **pskb, struct nf_conn *ct,
329 enum ip_conntrack_info ctinfo,
330 unsigned char **data, int dataoff,
331 TransportAddress *taddr, __be16 port,
332 struct nf_conntrack_expect *exp)
333{
334 struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;
335 int dir = CTINFO2DIR(ctinfo);
336 u_int16_t nated_port = ntohs(port);
337
338 /* Set expectations for NAT */
339 exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
340 exp->expectfn = nf_nat_follow_master;
341 exp->dir = !dir;
342
343 /* Check existing expects */
344 if (info->sig_port[dir] == port)
345 nated_port = ntohs(info->sig_port[!dir]);
346
347 /* Try to get same port: if not, try to change it. */
348 for (; nated_port != 0; nated_port++) {
349 exp->tuple.dst.u.tcp.port = htons(nated_port);
350 if (nf_conntrack_expect_related(exp) == 0)
351 break;
352 }
353
354 if (nated_port == 0) { /* No port available */
355 if (net_ratelimit())
356 printk("nf_nat_q931: out of TCP ports\n");
357 return 0;
358 }
359
360 /* Modify signal */
361 if (set_h225_addr(pskb, data, dataoff, taddr,
362 &ct->tuplehash[!dir].tuple.dst.u3,
363 htons(nated_port)) == 0) {
364 /* Save ports */
365 info->sig_port[dir] = port;
366 info->sig_port[!dir] = htons(nated_port);
367 } else {
368 nf_conntrack_unexpect_related(exp);
369 return -1;
370 }
371
372 DEBUGP("nf_nat_q931: expect H.245 %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
373 NIPQUAD(exp->tuple.src.ip), ntohs(exp->tuple.src.u.tcp.port),
374 NIPQUAD(exp->tuple.dst.ip), ntohs(exp->tuple.dst.u.tcp.port));
375
376 return 0;
377}
378
379/****************************************************************************
380 * This conntrack expect function replaces nf_conntrack_q931_expect()
381 * which was set by nf_conntrack_h323.c.
382 ****************************************************************************/
383static void ip_nat_q931_expect(struct nf_conn *new,
384 struct nf_conntrack_expect *this)
385{
386 struct ip_nat_range range;
387
388 if (this->tuple.src.u3.ip != 0) { /* Only accept calls from GK */
389 nf_nat_follow_master(new, this);
390 return;
391 }
392
393 /* This must be a fresh one. */
394 BUG_ON(new->status & IPS_NAT_DONE_MASK);
395
396 /* Change src to where master sends to */
397 range.flags = IP_NAT_RANGE_MAP_IPS;
398 range.min_ip = range.max_ip = new->tuplehash[!this->dir].tuple.src.u3.ip;
399
400 /* hook doesn't matter, but it has to do source manip */
401 nf_nat_setup_info(new, &range, NF_IP_POST_ROUTING);
402
403 /* For DST manip, map port here to where it's expected. */
404 range.flags = (IP_NAT_RANGE_MAP_IPS | IP_NAT_RANGE_PROTO_SPECIFIED);
405 range.min = range.max = this->saved_proto;
406 range.min_ip = range.max_ip =
407 new->master->tuplehash[!this->dir].tuple.src.u3.ip;
408
409 /* hook doesn't matter, but it has to do destination manip */
410 nf_nat_setup_info(new, &range, NF_IP_PRE_ROUTING);
411}
412
413/****************************************************************************/
414static int nat_q931(struct sk_buff **pskb, struct nf_conn *ct,
415 enum ip_conntrack_info ctinfo,
416 unsigned char **data, TransportAddress *taddr, int idx,
417 __be16 port, struct nf_conntrack_expect *exp)
418{
419 struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;
420 int dir = CTINFO2DIR(ctinfo);
421 u_int16_t nated_port = ntohs(port);
422 union nf_conntrack_address addr;
423
424 /* Set expectations for NAT */
425 exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
426 exp->expectfn = ip_nat_q931_expect;
427 exp->dir = !dir;
428
429 /* Check existing expects */
430 if (info->sig_port[dir] == port)
431 nated_port = ntohs(info->sig_port[!dir]);
432
433 /* Try to get same port: if not, try to change it. */
434 for (; nated_port != 0; nated_port++) {
435 exp->tuple.dst.u.tcp.port = htons(nated_port);
436 if (nf_conntrack_expect_related(exp) == 0)
437 break;
438 }
439
440 if (nated_port == 0) { /* No port available */
441 if (net_ratelimit())
442 printk("nf_nat_ras: out of TCP ports\n");
443 return 0;
444 }
445
446 /* Modify signal */
447 if (set_h225_addr(pskb, data, 0, &taddr[idx],
448 &ct->tuplehash[!dir].tuple.dst.u3,
449 htons(nated_port)) == 0) {
450 /* Save ports */
451 info->sig_port[dir] = port;
452 info->sig_port[!dir] = htons(nated_port);
453
454 /* Fix for Gnomemeeting */
455 if (idx > 0 &&
456 get_h225_addr(ct, *data, &taddr[0], &addr, &port) &&
457 (ntohl(addr.ip) & 0xff000000) == 0x7f000000) {
458 set_h225_addr_hook(pskb, data, 0, &taddr[0],
459 &ct->tuplehash[!dir].tuple.dst.u3,
460 info->sig_port[!dir]);
461 }
462 } else {
463 nf_conntrack_unexpect_related(exp);
464 return -1;
465 }
466
467 /* Success */
468 DEBUGP("nf_nat_ras: expect Q.931 %u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
469 NIPQUAD(exp->tuple.src.ip), ntohs(exp->tuple.src.u.tcp.port),
470 NIPQUAD(exp->tuple.dst.ip), ntohs(exp->tuple.dst.u.tcp.port));
471
472 return 0;
473}
474
475/****************************************************************************/
476static void ip_nat_callforwarding_expect(struct nf_conn *new,
477 struct nf_conntrack_expect *this)
478{
479 struct nf_nat_range range;
480
481 /* This must be a fresh one. */
482 BUG_ON(new->status & IPS_NAT_DONE_MASK);
483
484 /* Change src to where master sends to */
485 range.flags = IP_NAT_RANGE_MAP_IPS;
486 range.min_ip = range.max_ip = new->tuplehash[!this->dir].tuple.src.u3.ip;
487
488 /* hook doesn't matter, but it has to do source manip */
489 nf_nat_setup_info(new, &range, NF_IP_POST_ROUTING);
490
491 /* For DST manip, map port here to where it's expected. */
492 range.flags = (IP_NAT_RANGE_MAP_IPS | IP_NAT_RANGE_PROTO_SPECIFIED);
493 range.min = range.max = this->saved_proto;
494 range.min_ip = range.max_ip = this->saved_ip;
495
496 /* hook doesn't matter, but it has to do destination manip */
497 nf_nat_setup_info(new, &range, NF_IP_PRE_ROUTING);
498}
499
500/****************************************************************************/
501static int nat_callforwarding(struct sk_buff **pskb, struct nf_conn *ct,
502 enum ip_conntrack_info ctinfo,
503 unsigned char **data, int dataoff,
504 TransportAddress *taddr, __be16 port,
505 struct nf_conntrack_expect *exp)
506{
507 int dir = CTINFO2DIR(ctinfo);
508 u_int16_t nated_port;
509
510 /* Set expectations for NAT */
511 exp->saved_ip = exp->tuple.dst.u3.ip;
512 exp->tuple.dst.u3.ip = ct->tuplehash[!dir].tuple.dst.u3.ip;
513 exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
514 exp->expectfn = ip_nat_callforwarding_expect;
515 exp->dir = !dir;
516
517 /* Try to get same port: if not, try to change it. */
518 for (nated_port = ntohs(port); nated_port != 0; nated_port++) {
519 exp->tuple.dst.u.tcp.port = htons(nated_port);
520 if (nf_conntrack_expect_related(exp) == 0)
521 break;
522 }
523
524 if (nated_port == 0) { /* No port available */
525 if (net_ratelimit())
526 printk("nf_nat_q931: out of TCP ports\n");
527 return 0;
528 }
529
530 /* Modify signal */
531 if (!set_h225_addr(pskb, data, dataoff, taddr,
532 &ct->tuplehash[!dir].tuple.dst.u3,
533 htons(nated_port)) == 0) {
534 nf_conntrack_unexpect_related(exp);
535 return -1;
536 }
537
538 /* Success */
539 DEBUGP("nf_nat_q931: expect Call Forwarding "
540 "%u.%u.%u.%u:%hu->%u.%u.%u.%u:%hu\n",
541 NIPQUAD(exp->tuple.src.ip), ntohs(exp->tuple.src.u.tcp.port),
542 NIPQUAD(exp->tuple.dst.ip), ntohs(exp->tuple.dst.u.tcp.port));
543
544 return 0;
545}
546
547/****************************************************************************/
548static int __init init(void)
549{
550 BUG_ON(rcu_dereference(set_h245_addr_hook) != NULL);
551 BUG_ON(rcu_dereference(set_h225_addr_hook) != NULL);
552 BUG_ON(rcu_dereference(set_sig_addr_hook) != NULL);
553 BUG_ON(rcu_dereference(set_ras_addr_hook) != NULL);
554 BUG_ON(rcu_dereference(nat_rtp_rtcp_hook) != NULL);
555 BUG_ON(rcu_dereference(nat_t120_hook) != NULL);
556 BUG_ON(rcu_dereference(nat_h245_hook) != NULL);
557 BUG_ON(rcu_dereference(nat_callforwarding_hook) != NULL);
558 BUG_ON(rcu_dereference(nat_q931_hook) != NULL);
559
560 rcu_assign_pointer(set_h245_addr_hook, set_h245_addr);
561 rcu_assign_pointer(set_h225_addr_hook, set_h225_addr);
562 rcu_assign_pointer(set_sig_addr_hook, set_sig_addr);
563 rcu_assign_pointer(set_ras_addr_hook, set_ras_addr);
564 rcu_assign_pointer(nat_rtp_rtcp_hook, nat_rtp_rtcp);
565 rcu_assign_pointer(nat_t120_hook, nat_t120);
566 rcu_assign_pointer(nat_h245_hook, nat_h245);
567 rcu_assign_pointer(nat_callforwarding_hook, nat_callforwarding);
568 rcu_assign_pointer(nat_q931_hook, nat_q931);
569
570 DEBUGP("nf_nat_h323: init success\n");
571 return 0;
572}
573
574/****************************************************************************/
575static void __exit fini(void)
576{
577 rcu_assign_pointer(set_h245_addr_hook, NULL);
578 rcu_assign_pointer(set_h225_addr_hook, NULL);
579 rcu_assign_pointer(set_sig_addr_hook, NULL);
580 rcu_assign_pointer(set_ras_addr_hook, NULL);
581 rcu_assign_pointer(nat_rtp_rtcp_hook, NULL);
582 rcu_assign_pointer(nat_t120_hook, NULL);
583 rcu_assign_pointer(nat_h245_hook, NULL);
584 rcu_assign_pointer(nat_callforwarding_hook, NULL);
585 rcu_assign_pointer(nat_q931_hook, NULL);
586 synchronize_rcu();
587}
588
589/****************************************************************************/
590module_init(init);
591module_exit(fini);
592
593MODULE_AUTHOR("Jing Min Zhao <zhaojingmin@users.sourceforge.net>");
594MODULE_DESCRIPTION("H.323 NAT helper");
595MODULE_LICENSE("GPL");
596MODULE_ALIAS("ip_nat_h323");
diff --git a/net/ipv4/netfilter/nf_nat_helper.c b/net/ipv4/netfilter/nf_nat_helper.c
new file mode 100644
index 0000000000..98fbfc84d1
--- /dev/null
+++ b/net/ipv4/netfilter/nf_nat_helper.c
@@ -0,0 +1,433 @@
1/* ip_nat_helper.c - generic support functions for NAT helpers
2 *
3 * (C) 2000-2002 Harald Welte <laforge@netfilter.org>
4 * (C) 2003-2006 Netfilter Core Team <coreteam@netfilter.org>
5 *
6 * 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 * published by the Free Software Foundation.
9 */
10#include <linux/module.h>
11#include <linux/kmod.h>
12#include <linux/types.h>
13#include <linux/timer.h>
14#include <linux/skbuff.h>
15#include <linux/tcp.h>
16#include <linux/udp.h>
17#include <net/checksum.h>
18#include <net/tcp.h>
19
20#include <linux/netfilter_ipv4.h>
21#include <net/netfilter/nf_conntrack.h>
22#include <net/netfilter/nf_conntrack_helper.h>
23#include <net/netfilter/nf_conntrack_expect.h>
24#include <net/netfilter/nf_nat.h>
25#include <net/netfilter/nf_nat_protocol.h>
26#include <net/netfilter/nf_nat_core.h>
27#include <net/netfilter/nf_nat_helper.h>
28
29#if 0
30#define DEBUGP printk
31#define DUMP_OFFSET(x) printk("offset_before=%d, offset_after=%d, correction_pos=%u\n", x->offset_before, x->offset_after, x->correction_pos);
32#else
33#define DEBUGP(format, args...)
34#define DUMP_OFFSET(x)
35#endif
36
37static DEFINE_SPINLOCK(nf_nat_seqofs_lock);
38
39/* Setup TCP sequence correction given this change at this sequence */
40static inline void
41adjust_tcp_sequence(u32 seq,
42 int sizediff,
43 struct nf_conn *ct,
44 enum ip_conntrack_info ctinfo)
45{
46 int dir;
47 struct nf_nat_seq *this_way, *other_way;
48 struct nf_conn_nat *nat = nfct_nat(ct);
49
50 DEBUGP("nf_nat_resize_packet: old_size = %u, new_size = %u\n",
51 (*skb)->len, new_size);
52
53 dir = CTINFO2DIR(ctinfo);
54
55 this_way = &nat->info.seq[dir];
56 other_way = &nat->info.seq[!dir];
57
58 DEBUGP("nf_nat_resize_packet: Seq_offset before: ");
59 DUMP_OFFSET(this_way);
60
61 spin_lock_bh(&nf_nat_seqofs_lock);
62
63 /* SYN adjust. If it's uninitialized, or this is after last
64 * correction, record it: we don't handle more than one
65 * adjustment in the window, but do deal with common case of a
66 * retransmit */
67 if (this_way->offset_before == this_way->offset_after ||
68 before(this_way->correction_pos, seq)) {
69 this_way->correction_pos = seq;
70 this_way->offset_before = this_way->offset_after;
71 this_way->offset_after += sizediff;
72 }
73 spin_unlock_bh(&nf_nat_seqofs_lock);
74
75 DEBUGP("nf_nat_resize_packet: Seq_offset after: ");
76 DUMP_OFFSET(this_way);
77}
78
79/* Frobs data inside this packet, which is linear. */
80static void mangle_contents(struct sk_buff *skb,
81 unsigned int dataoff,
82 unsigned int match_offset,
83 unsigned int match_len,
84 const char *rep_buffer,
85 unsigned int rep_len)
86{
87 unsigned char *data;
88
89 BUG_ON(skb_is_nonlinear(skb));
90 data = (unsigned char *)skb->nh.iph + dataoff;
91
92 /* move post-replacement */
93 memmove(data + match_offset + rep_len,
94 data + match_offset + match_len,
95 skb->tail - (data + match_offset + match_len));
96
97 /* insert data from buffer */
98 memcpy(data + match_offset, rep_buffer, rep_len);
99
100 /* update skb info */
101 if (rep_len > match_len) {
102 DEBUGP("nf_nat_mangle_packet: Extending packet by "
103 "%u from %u bytes\n", rep_len - match_len,
104 skb->len);
105 skb_put(skb, rep_len - match_len);
106 } else {
107 DEBUGP("nf_nat_mangle_packet: Shrinking packet from "
108 "%u from %u bytes\n", match_len - rep_len,
109 skb->len);
110 __skb_trim(skb, skb->len + rep_len - match_len);
111 }
112
113 /* fix IP hdr checksum information */
114 skb->nh.iph->tot_len = htons(skb->len);
115 ip_send_check(skb->nh.iph);
116}
117
118/* Unusual, but possible case. */
119static int enlarge_skb(struct sk_buff **pskb, unsigned int extra)
120{
121 struct sk_buff *nskb;
122
123 if ((*pskb)->len + extra > 65535)
124 return 0;
125
126 nskb = skb_copy_expand(*pskb, skb_headroom(*pskb), extra, GFP_ATOMIC);
127 if (!nskb)
128 return 0;
129
130 /* Transfer socket to new skb. */
131 if ((*pskb)->sk)
132 skb_set_owner_w(nskb, (*pskb)->sk);
133 kfree_skb(*pskb);
134 *pskb = nskb;
135 return 1;
136}
137
138/* Generic function for mangling variable-length address changes inside
139 * NATed TCP connections (like the PORT XXX,XXX,XXX,XXX,XXX,XXX
140 * command in FTP).
141 *
142 * Takes care about all the nasty sequence number changes, checksumming,
143 * skb enlargement, ...
144 *
145 * */
146int
147nf_nat_mangle_tcp_packet(struct sk_buff **pskb,
148 struct nf_conn *ct,
149 enum ip_conntrack_info ctinfo,
150 unsigned int match_offset,
151 unsigned int match_len,
152 const char *rep_buffer,
153 unsigned int rep_len)
154{
155 struct iphdr *iph;
156 struct tcphdr *tcph;
157 int oldlen, datalen;
158
159 if (!skb_make_writable(pskb, (*pskb)->len))
160 return 0;
161
162 if (rep_len > match_len &&
163 rep_len - match_len > skb_tailroom(*pskb) &&
164 !enlarge_skb(pskb, rep_len - match_len))
165 return 0;
166
167 SKB_LINEAR_ASSERT(*pskb);
168
169 iph = (*pskb)->nh.iph;
170 tcph = (void *)iph + iph->ihl*4;
171
172 oldlen = (*pskb)->len - iph->ihl*4;
173 mangle_contents(*pskb, iph->ihl*4 + tcph->doff*4,
174 match_offset, match_len, rep_buffer, rep_len);
175
176 datalen = (*pskb)->len - iph->ihl*4;
177 if ((*pskb)->ip_summed != CHECKSUM_PARTIAL) {
178 tcph->check = 0;
179 tcph->check = tcp_v4_check(tcph, datalen,
180 iph->saddr, iph->daddr,
181 csum_partial((char *)tcph,
182 datalen, 0));
183 } else
184 nf_proto_csum_replace2(&tcph->check, *pskb,
185 htons(oldlen), htons(datalen), 1);
186
187 if (rep_len != match_len) {
188 set_bit(IPS_SEQ_ADJUST_BIT, &ct->status);
189 adjust_tcp_sequence(ntohl(tcph->seq),
190 (int)rep_len - (int)match_len,
191 ct, ctinfo);
192 /* Tell TCP window tracking about seq change */
193 nf_conntrack_tcp_update(*pskb, (*pskb)->nh.iph->ihl*4,
194 ct, CTINFO2DIR(ctinfo));
195 }
196 return 1;
197}
198EXPORT_SYMBOL(nf_nat_mangle_tcp_packet);
199
200/* Generic function for mangling variable-length address changes inside
201 * NATed UDP connections (like the CONNECT DATA XXXXX MESG XXXXX INDEX XXXXX
202 * command in the Amanda protocol)
203 *
204 * Takes care about all the nasty sequence number changes, checksumming,
205 * skb enlargement, ...
206 *
207 * XXX - This function could be merged with nf_nat_mangle_tcp_packet which
208 * should be fairly easy to do.
209 */
210int
211nf_nat_mangle_udp_packet(struct sk_buff **pskb,
212 struct nf_conn *ct,
213 enum ip_conntrack_info ctinfo,
214 unsigned int match_offset,
215 unsigned int match_len,
216 const char *rep_buffer,
217 unsigned int rep_len)
218{
219 struct iphdr *iph;
220 struct udphdr *udph;
221 int datalen, oldlen;
222
223 /* UDP helpers might accidentally mangle the wrong packet */
224 iph = (*pskb)->nh.iph;
225 if ((*pskb)->len < iph->ihl*4 + sizeof(*udph) +
226 match_offset + match_len)
227 return 0;
228
229 if (!skb_make_writable(pskb, (*pskb)->len))
230 return 0;
231
232 if (rep_len > match_len &&
233 rep_len - match_len > skb_tailroom(*pskb) &&
234 !enlarge_skb(pskb, rep_len - match_len))
235 return 0;
236
237 iph = (*pskb)->nh.iph;
238 udph = (void *)iph + iph->ihl*4;
239
240 oldlen = (*pskb)->len - iph->ihl*4;
241 mangle_contents(*pskb, iph->ihl*4 + sizeof(*udph),
242 match_offset, match_len, rep_buffer, rep_len);
243
244 /* update the length of the UDP packet */
245 datalen = (*pskb)->len - iph->ihl*4;
246 udph->len = htons(datalen);
247
248 /* fix udp checksum if udp checksum was previously calculated */
249 if (!udph->check && (*pskb)->ip_summed != CHECKSUM_PARTIAL)
250 return 1;
251
252 if ((*pskb)->ip_summed != CHECKSUM_PARTIAL) {
253 udph->check = 0;
254 udph->check = csum_tcpudp_magic(iph->saddr, iph->daddr,
255 datalen, IPPROTO_UDP,
256 csum_partial((char *)udph,
257 datalen, 0));
258 if (!udph->check)
259 udph->check = CSUM_MANGLED_0;
260 } else
261 nf_proto_csum_replace2(&udph->check, *pskb,
262 htons(oldlen), htons(datalen), 1);
263
264 return 1;
265}
266EXPORT_SYMBOL(nf_nat_mangle_udp_packet);
267
268/* Adjust one found SACK option including checksum correction */
269static void
270sack_adjust(struct sk_buff *skb,
271 struct tcphdr *tcph,
272 unsigned int sackoff,
273 unsigned int sackend,
274 struct nf_nat_seq *natseq)
275{
276 while (sackoff < sackend) {
277 struct tcp_sack_block_wire *sack;
278 __be32 new_start_seq, new_end_seq;
279
280 sack = (void *)skb->data + sackoff;
281 if (after(ntohl(sack->start_seq) - natseq->offset_before,
282 natseq->correction_pos))
283 new_start_seq = htonl(ntohl(sack->start_seq)
284 - natseq->offset_after);
285 else
286 new_start_seq = htonl(ntohl(sack->start_seq)
287 - natseq->offset_before);
288
289 if (after(ntohl(sack->end_seq) - natseq->offset_before,
290 natseq->correction_pos))
291 new_end_seq = htonl(ntohl(sack->end_seq)
292 - natseq->offset_after);
293 else
294 new_end_seq = htonl(ntohl(sack->end_seq)
295 - natseq->offset_before);
296
297 DEBUGP("sack_adjust: start_seq: %d->%d, end_seq: %d->%d\n",
298 ntohl(sack->start_seq), new_start_seq,
299 ntohl(sack->end_seq), new_end_seq);
300
301 nf_proto_csum_replace4(&tcph->check, skb,
302 sack->start_seq, new_start_seq, 0);
303 nf_proto_csum_replace4(&tcph->check, skb,
304 sack->end_seq, new_end_seq, 0);
305 sack->start_seq = new_start_seq;
306 sack->end_seq = new_end_seq;
307 sackoff += sizeof(*sack);
308 }
309}
310
311/* TCP SACK sequence number adjustment */
312static inline unsigned int
313nf_nat_sack_adjust(struct sk_buff **pskb,
314 struct tcphdr *tcph,
315 struct nf_conn *ct,
316 enum ip_conntrack_info ctinfo)
317{
318 unsigned int dir, optoff, optend;
319 struct nf_conn_nat *nat = nfct_nat(ct);
320
321 optoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct tcphdr);
322 optend = (*pskb)->nh.iph->ihl*4 + tcph->doff*4;
323
324 if (!skb_make_writable(pskb, optend))
325 return 0;
326
327 dir = CTINFO2DIR(ctinfo);
328
329 while (optoff < optend) {
330 /* Usually: option, length. */
331 unsigned char *op = (*pskb)->data + optoff;
332
333 switch (op[0]) {
334 case TCPOPT_EOL:
335 return 1;
336 case TCPOPT_NOP:
337 optoff++;
338 continue;
339 default:
340 /* no partial options */
341 if (optoff + 1 == optend ||
342 optoff + op[1] > optend ||
343 op[1] < 2)
344 return 0;
345 if (op[0] == TCPOPT_SACK &&
346 op[1] >= 2+TCPOLEN_SACK_PERBLOCK &&
347 ((op[1] - 2) % TCPOLEN_SACK_PERBLOCK) == 0)
348 sack_adjust(*pskb, tcph, optoff+2,
349 optoff+op[1],
350 &nat->info.seq[!dir]);
351 optoff += op[1];
352 }
353 }
354 return 1;
355}
356
357/* TCP sequence number adjustment. Returns 1 on success, 0 on failure */
358int
359nf_nat_seq_adjust(struct sk_buff **pskb,
360 struct nf_conn *ct,
361 enum ip_conntrack_info ctinfo)
362{
363 struct tcphdr *tcph;
364 int dir;
365 __be32 newseq, newack;
366 struct nf_conn_nat *nat = nfct_nat(ct);
367 struct nf_nat_seq *this_way, *other_way;
368
369 dir = CTINFO2DIR(ctinfo);
370
371 this_way = &nat->info.seq[dir];
372 other_way = &nat->info.seq[!dir];
373
374 if (!skb_make_writable(pskb, (*pskb)->nh.iph->ihl*4+sizeof(*tcph)))
375 return 0;
376
377 tcph = (void *)(*pskb)->data + (*pskb)->nh.iph->ihl*4;
378 if (after(ntohl(tcph->seq), this_way->correction_pos))
379 newseq = htonl(ntohl(tcph->seq) + this_way->offset_after);
380 else
381 newseq = htonl(ntohl(tcph->seq) + this_way->offset_before);
382
383 if (after(ntohl(tcph->ack_seq) - other_way->offset_before,
384 other_way->correction_pos))
385 newack = htonl(ntohl(tcph->ack_seq) - other_way->offset_after);
386 else
387 newack = htonl(ntohl(tcph->ack_seq) - other_way->offset_before);
388
389 nf_proto_csum_replace4(&tcph->check, *pskb, tcph->seq, newseq, 0);
390 nf_proto_csum_replace4(&tcph->check, *pskb, tcph->ack_seq, newack, 0);
391
392 DEBUGP("Adjusting sequence number from %u->%u, ack from %u->%u\n",
393 ntohl(tcph->seq), ntohl(newseq), ntohl(tcph->ack_seq),
394 ntohl(newack));
395
396 tcph->seq = newseq;
397 tcph->ack_seq = newack;
398
399 if (!nf_nat_sack_adjust(pskb, tcph, ct, ctinfo))
400 return 0;
401
402 nf_conntrack_tcp_update(*pskb, (*pskb)->nh.iph->ihl*4, ct, dir);
403
404 return 1;
405}
406EXPORT_SYMBOL(nf_nat_seq_adjust);
407
408/* Setup NAT on this expected conntrack so it follows master. */
409/* If we fail to get a free NAT slot, we'll get dropped on confirm */
410void nf_nat_follow_master(struct nf_conn *ct,
411 struct nf_conntrack_expect *exp)
412{
413 struct nf_nat_range range;
414
415 /* This must be a fresh one. */
416 BUG_ON(ct->status & IPS_NAT_DONE_MASK);
417
418 /* Change src to where master sends to */
419 range.flags = IP_NAT_RANGE_MAP_IPS;
420 range.min_ip = range.max_ip
421 = ct->master->tuplehash[!exp->dir].tuple.dst.u3.ip;
422 /* hook doesn't matter, but it has to do source manip */
423 nf_nat_setup_info(ct, &range, NF_IP_POST_ROUTING);
424
425 /* For DST manip, map port here to where it's expected. */
426 range.flags = (IP_NAT_RANGE_MAP_IPS | IP_NAT_RANGE_PROTO_SPECIFIED);
427 range.min = range.max = exp->saved_proto;
428 range.min_ip = range.max_ip
429 = ct->master->tuplehash[!exp->dir].tuple.src.u3.ip;
430 /* hook doesn't matter, but it has to do destination manip */
431 nf_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING);
432}
433EXPORT_SYMBOL(nf_nat_follow_master);
diff --git a/net/ipv4/netfilter/nf_nat_irc.c b/net/ipv4/netfilter/nf_nat_irc.c
new file mode 100644
index 0000000000..9b8c0daea7
--- /dev/null
+++ b/net/ipv4/netfilter/nf_nat_irc.c
@@ -0,0 +1,101 @@
1/* IRC extension for TCP NAT alteration.
2 *
3 * (C) 2000-2001 by Harald Welte <laforge@gnumonks.org>
4 * (C) 2004 Rusty Russell <rusty@rustcorp.com.au> IBM Corporation
5 * based on a copy of RR's ip_nat_ftp.c
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 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/tcp.h>
16#include <linux/kernel.h>
17
18#include <net/netfilter/nf_nat.h>
19#include <net/netfilter/nf_nat_helper.h>
20#include <net/netfilter/nf_nat_rule.h>
21#include <net/netfilter/nf_conntrack_helper.h>
22#include <net/netfilter/nf_conntrack_expect.h>
23#include <linux/netfilter/nf_conntrack_irc.h>
24
25#if 0
26#define DEBUGP printk
27#else
28#define DEBUGP(format, args...)
29#endif
30
31MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
32MODULE_DESCRIPTION("IRC (DCC) NAT helper");
33MODULE_LICENSE("GPL");
34MODULE_ALIAS("ip_nat_irc");
35
36static unsigned int help(struct sk_buff **pskb,
37 enum ip_conntrack_info ctinfo,
38 unsigned int matchoff,
39 unsigned int matchlen,
40 struct nf_conntrack_expect *exp)
41{
42 char buffer[sizeof("4294967296 65635")];
43 u_int32_t ip;
44 u_int16_t port;
45 unsigned int ret;
46
47 DEBUGP("IRC_NAT: info (seq %u + %u) in %u\n",
48 expect->seq, exp_irc_info->len, ntohl(tcph->seq));
49
50 /* Reply comes from server. */
51 exp->saved_proto.tcp.port = exp->tuple.dst.u.tcp.port;
52 exp->dir = IP_CT_DIR_REPLY;
53 exp->expectfn = nf_nat_follow_master;
54
55 /* Try to get same port: if not, try to change it. */
56 for (port = ntohs(exp->saved_proto.tcp.port); port != 0; port++) {
57 exp->tuple.dst.u.tcp.port = htons(port);
58 if (nf_conntrack_expect_related(exp) == 0)
59 break;
60 }
61
62 if (port == 0)
63 return NF_DROP;
64
65 ip = ntohl(exp->master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip);
66 sprintf(buffer, "%u %u", ip, port);
67 DEBUGP("nf_nat_irc: inserting '%s' == %u.%u.%u.%u, port %u\n",
68 buffer, NIPQUAD(ip), port);
69
70 ret = nf_nat_mangle_tcp_packet(pskb, exp->master, ctinfo,
71 matchoff, matchlen, buffer,
72 strlen(buffer));
73 if (ret != NF_ACCEPT)
74 nf_conntrack_unexpect_related(exp);
75 return ret;
76}
77
78static void __exit nf_nat_irc_fini(void)
79{
80 rcu_assign_pointer(nf_nat_irc_hook, NULL);
81 synchronize_rcu();
82}
83
84static int __init nf_nat_irc_init(void)
85{
86 BUG_ON(rcu_dereference(nf_nat_irc_hook));
87 rcu_assign_pointer(nf_nat_irc_hook, help);
88 return 0;
89}
90
91/* Prior to 2.6.11, we had a ports param. No longer, but don't break users. */
92static int warn_set(const char *val, struct kernel_param *kp)
93{
94 printk(KERN_INFO KBUILD_MODNAME
95 ": kernel >= 2.6.10 only uses 'ports' for conntrack modules\n");
96 return 0;
97}
98module_param_call(ports, warn_set, NULL, NULL, 0);
99
100module_init(nf_nat_irc_init);
101module_exit(nf_nat_irc_fini);
diff --git a/net/ipv4/netfilter/nf_nat_pptp.c b/net/ipv4/netfilter/nf_nat_pptp.c
new file mode 100644
index 0000000000..0ae45b79a4
--- /dev/null
+++ b/net/ipv4/netfilter/nf_nat_pptp.c
@@ -0,0 +1,315 @@
1/*
2 * nf_nat_pptp.c
3 *
4 * NAT support for PPTP (Point to Point Tunneling Protocol).
5 * PPTP is a a protocol for creating virtual private networks.
6 * It is a specification defined by Microsoft and some vendors
7 * working with Microsoft. PPTP is built on top of a modified
8 * version of the Internet Generic Routing Encapsulation Protocol.
9 * GRE is defined in RFC 1701 and RFC 1702. Documentation of
10 * PPTP can be found in RFC 2637
11 *
12 * (C) 2000-2005 by Harald Welte <laforge@gnumonks.org>
13 *
14 * Development of this code funded by Astaro AG (http://www.astaro.com/)
15 *
16 * TODO: - NAT to a unique tuple, not to TCP source port
17 * (needs netfilter tuple reservation)
18 */
19
20#include <linux/module.h>
21#include <linux/tcp.h>
22
23#include <net/netfilter/nf_nat.h>
24#include <net/netfilter/nf_nat_helper.h>
25#include <net/netfilter/nf_nat_rule.h>
26#include <net/netfilter/nf_conntrack_helper.h>
27#include <net/netfilter/nf_conntrack_expect.h>
28#include <linux/netfilter/nf_conntrack_proto_gre.h>
29#include <linux/netfilter/nf_conntrack_pptp.h>
30
31#define NF_NAT_PPTP_VERSION "3.0"
32
33#define REQ_CID(req, off) (*(__be16 *)((char *)(req) + (off)))
34
35MODULE_LICENSE("GPL");
36MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
37MODULE_DESCRIPTION("Netfilter NAT helper module for PPTP");
38MODULE_ALIAS("ip_nat_pptp");
39
40#if 0
41extern const char *pptp_msg_name[];
42#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s: " format, __FILE__, \
43 __FUNCTION__, ## args)
44#else
45#define DEBUGP(format, args...)
46#endif
47
48static void pptp_nat_expected(struct nf_conn *ct,
49 struct nf_conntrack_expect *exp)
50{
51 struct nf_conn *master = ct->master;
52 struct nf_conntrack_expect *other_exp;
53 struct nf_conntrack_tuple t;
54 struct nf_ct_pptp_master *ct_pptp_info;
55 struct nf_nat_pptp *nat_pptp_info;
56 struct ip_nat_range range;
57
58 ct_pptp_info = &nfct_help(master)->help.ct_pptp_info;
59 nat_pptp_info = &nfct_nat(master)->help.nat_pptp_info;
60
61 /* And here goes the grand finale of corrosion... */
62 if (exp->dir == IP_CT_DIR_ORIGINAL) {
63 DEBUGP("we are PNS->PAC\n");
64 /* therefore, build tuple for PAC->PNS */
65 t.src.l3num = AF_INET;
66 t.src.u3.ip = master->tuplehash[!exp->dir].tuple.src.u3.ip;
67 t.src.u.gre.key = ct_pptp_info->pac_call_id;
68 t.dst.u3.ip = master->tuplehash[!exp->dir].tuple.dst.u3.ip;
69 t.dst.u.gre.key = ct_pptp_info->pns_call_id;
70 t.dst.protonum = IPPROTO_GRE;
71 } else {
72 DEBUGP("we are PAC->PNS\n");
73 /* build tuple for PNS->PAC */
74 t.src.l3num = AF_INET;
75 t.src.u3.ip = master->tuplehash[exp->dir].tuple.src.u3.ip;
76 t.src.u.gre.key = nat_pptp_info->pns_call_id;
77 t.dst.u3.ip = master->tuplehash[exp->dir].tuple.dst.u3.ip;
78 t.dst.u.gre.key = nat_pptp_info->pac_call_id;
79 t.dst.protonum = IPPROTO_GRE;
80 }
81
82 DEBUGP("trying to unexpect other dir: ");
83 NF_CT_DUMP_TUPLE(&t);
84 other_exp = nf_conntrack_expect_find_get(&t);
85 if (other_exp) {
86 nf_conntrack_unexpect_related(other_exp);
87 nf_conntrack_expect_put(other_exp);
88 DEBUGP("success\n");
89 } else {
90 DEBUGP("not found!\n");
91 }
92
93 /* This must be a fresh one. */
94 BUG_ON(ct->status & IPS_NAT_DONE_MASK);
95
96 /* Change src to where master sends to */
97 range.flags = IP_NAT_RANGE_MAP_IPS;
98 range.min_ip = range.max_ip
99 = ct->master->tuplehash[!exp->dir].tuple.dst.u3.ip;
100 if (exp->dir == IP_CT_DIR_ORIGINAL) {
101 range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
102 range.min = range.max = exp->saved_proto;
103 }
104 /* hook doesn't matter, but it has to do source manip */
105 nf_nat_setup_info(ct, &range, NF_IP_POST_ROUTING);
106
107 /* For DST manip, map port here to where it's expected. */
108 range.flags = IP_NAT_RANGE_MAP_IPS;
109 range.min_ip = range.max_ip
110 = ct->master->tuplehash[!exp->dir].tuple.src.u3.ip;
111 if (exp->dir == IP_CT_DIR_REPLY) {
112 range.flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
113 range.min = range.max = exp->saved_proto;
114 }
115 /* hook doesn't matter, but it has to do destination manip */
116 nf_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING);
117}
118
119/* outbound packets == from PNS to PAC */
120static int
121pptp_outbound_pkt(struct sk_buff **pskb,
122 struct nf_conn *ct,
123 enum ip_conntrack_info ctinfo,
124 struct PptpControlHeader *ctlh,
125 union pptp_ctrl_union *pptpReq)
126
127{
128 struct nf_ct_pptp_master *ct_pptp_info;
129 struct nf_nat_pptp *nat_pptp_info;
130 u_int16_t msg;
131 __be16 new_callid;
132 unsigned int cid_off;
133
134 ct_pptp_info = &nfct_help(ct)->help.ct_pptp_info;
135 nat_pptp_info = &nfct_nat(ct)->help.nat_pptp_info;
136
137 new_callid = ct_pptp_info->pns_call_id;
138
139 switch (msg = ntohs(ctlh->messageType)) {
140 case PPTP_OUT_CALL_REQUEST:
141 cid_off = offsetof(union pptp_ctrl_union, ocreq.callID);
142 /* FIXME: ideally we would want to reserve a call ID
143 * here. current netfilter NAT core is not able to do
144 * this :( For now we use TCP source port. This breaks
145 * multiple calls within one control session */
146
147 /* save original call ID in nat_info */
148 nat_pptp_info->pns_call_id = ct_pptp_info->pns_call_id;
149
150 /* don't use tcph->source since we are at a DSTmanip
151 * hook (e.g. PREROUTING) and pkt is not mangled yet */
152 new_callid = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.tcp.port;
153
154 /* save new call ID in ct info */
155 ct_pptp_info->pns_call_id = new_callid;
156 break;
157 case PPTP_IN_CALL_REPLY:
158 cid_off = offsetof(union pptp_ctrl_union, icack.callID);
159 break;
160 case PPTP_CALL_CLEAR_REQUEST:
161 cid_off = offsetof(union pptp_ctrl_union, clrreq.callID);
162 break;
163 default:
164 DEBUGP("unknown outbound packet 0x%04x:%s\n", msg,
165 (msg <= PPTP_MSG_MAX)?
166 pptp_msg_name[msg]:pptp_msg_name[0]);
167 /* fall through */
168 case PPTP_SET_LINK_INFO:
169 /* only need to NAT in case PAC is behind NAT box */
170 case PPTP_START_SESSION_REQUEST:
171 case PPTP_START_SESSION_REPLY:
172 case PPTP_STOP_SESSION_REQUEST:
173 case PPTP_STOP_SESSION_REPLY:
174 case PPTP_ECHO_REQUEST:
175 case PPTP_ECHO_REPLY:
176 /* no need to alter packet */
177 return NF_ACCEPT;
178 }
179
180 /* only OUT_CALL_REQUEST, IN_CALL_REPLY, CALL_CLEAR_REQUEST pass
181 * down to here */
182 DEBUGP("altering call id from 0x%04x to 0x%04x\n",
183 ntohs(REQ_CID(pptpReq, cid_off)), ntohs(new_callid));
184
185 /* mangle packet */
186 if (nf_nat_mangle_tcp_packet(pskb, ct, ctinfo,
187 cid_off + sizeof(struct pptp_pkt_hdr) +
188 sizeof(struct PptpControlHeader),
189 sizeof(new_callid), (char *)&new_callid,
190 sizeof(new_callid)) == 0)
191 return NF_DROP;
192 return NF_ACCEPT;
193}
194
195static void
196pptp_exp_gre(struct nf_conntrack_expect *expect_orig,
197 struct nf_conntrack_expect *expect_reply)
198{
199 struct nf_conn *ct = expect_orig->master;
200 struct nf_ct_pptp_master *ct_pptp_info;
201 struct nf_nat_pptp *nat_pptp_info;
202
203 ct_pptp_info = &nfct_help(ct)->help.ct_pptp_info;
204 nat_pptp_info = &nfct_nat(ct)->help.nat_pptp_info;
205
206 /* save original PAC call ID in nat_info */
207 nat_pptp_info->pac_call_id = ct_pptp_info->pac_call_id;
208
209 /* alter expectation for PNS->PAC direction */
210 expect_orig->saved_proto.gre.key = ct_pptp_info->pns_call_id;
211 expect_orig->tuple.src.u.gre.key = nat_pptp_info->pns_call_id;
212 expect_orig->tuple.dst.u.gre.key = ct_pptp_info->pac_call_id;
213 expect_orig->dir = IP_CT_DIR_ORIGINAL;
214
215 /* alter expectation for PAC->PNS direction */
216 expect_reply->saved_proto.gre.key = nat_pptp_info->pns_call_id;
217 expect_reply->tuple.src.u.gre.key = nat_pptp_info->pac_call_id;
218 expect_reply->tuple.dst.u.gre.key = ct_pptp_info->pns_call_id;
219 expect_reply->dir = IP_CT_DIR_REPLY;
220}
221
222/* inbound packets == from PAC to PNS */
223static int
224pptp_inbound_pkt(struct sk_buff **pskb,
225 struct nf_conn *ct,
226 enum ip_conntrack_info ctinfo,
227 struct PptpControlHeader *ctlh,
228 union pptp_ctrl_union *pptpReq)
229{
230 struct nf_nat_pptp *nat_pptp_info;
231 u_int16_t msg;
232 __be16 new_pcid;
233 unsigned int pcid_off;
234
235 nat_pptp_info = &nfct_nat(ct)->help.nat_pptp_info;
236 new_pcid = nat_pptp_info->pns_call_id;
237
238 switch (msg = ntohs(ctlh->messageType)) {
239 case PPTP_OUT_CALL_REPLY:
240 pcid_off = offsetof(union pptp_ctrl_union, ocack.peersCallID);
241 break;
242 case PPTP_IN_CALL_CONNECT:
243 pcid_off = offsetof(union pptp_ctrl_union, iccon.peersCallID);
244 break;
245 case PPTP_IN_CALL_REQUEST:
246 /* only need to nat in case PAC is behind NAT box */
247 return NF_ACCEPT;
248 case PPTP_WAN_ERROR_NOTIFY:
249 pcid_off = offsetof(union pptp_ctrl_union, wanerr.peersCallID);
250 break;
251 case PPTP_CALL_DISCONNECT_NOTIFY:
252 pcid_off = offsetof(union pptp_ctrl_union, disc.callID);
253 break;
254 case PPTP_SET_LINK_INFO:
255 pcid_off = offsetof(union pptp_ctrl_union, setlink.peersCallID);
256 break;
257 default:
258 DEBUGP("unknown inbound packet %s\n", (msg <= PPTP_MSG_MAX)?
259 pptp_msg_name[msg]:pptp_msg_name[0]);
260 /* fall through */
261 case PPTP_START_SESSION_REQUEST:
262 case PPTP_START_SESSION_REPLY:
263 case PPTP_STOP_SESSION_REQUEST:
264 case PPTP_STOP_SESSION_REPLY:
265 case PPTP_ECHO_REQUEST:
266 case PPTP_ECHO_REPLY:
267 /* no need to alter packet */
268 return NF_ACCEPT;
269 }
270
271 /* only OUT_CALL_REPLY, IN_CALL_CONNECT, IN_CALL_REQUEST,
272 * WAN_ERROR_NOTIFY, CALL_DISCONNECT_NOTIFY pass down here */
273
274 /* mangle packet */
275 DEBUGP("altering peer call id from 0x%04x to 0x%04x\n",
276 ntohs(REQ_CID(pptpReq, pcid_off)), ntohs(new_pcid));
277
278 if (nf_nat_mangle_tcp_packet(pskb, ct, ctinfo,
279 pcid_off + sizeof(struct pptp_pkt_hdr) +
280 sizeof(struct PptpControlHeader),
281 sizeof(new_pcid), (char *)&new_pcid,
282 sizeof(new_pcid)) == 0)
283 return NF_DROP;
284 return NF_ACCEPT;
285}
286
287static int __init nf_nat_helper_pptp_init(void)
288{
289 nf_nat_need_gre();
290
291 BUG_ON(rcu_dereference(nf_nat_pptp_hook_outbound));
292 rcu_assign_pointer(nf_nat_pptp_hook_outbound, pptp_outbound_pkt);
293
294 BUG_ON(rcu_dereference(nf_nat_pptp_hook_inbound));
295 rcu_assign_pointer(nf_nat_pptp_hook_inbound, pptp_inbound_pkt);
296
297 BUG_ON(rcu_dereference(nf_nat_pptp_hook_exp_gre));
298 rcu_assign_pointer(nf_nat_pptp_hook_exp_gre, pptp_exp_gre);
299
300 BUG_ON(rcu_dereference(nf_nat_pptp_hook_expectfn));
301 rcu_assign_pointer(nf_nat_pptp_hook_expectfn, pptp_nat_expected);
302 return 0;
303}
304
305static void __exit nf_nat_helper_pptp_fini(void)
306{
307 rcu_assign_pointer(nf_nat_pptp_hook_expectfn, NULL);
308 rcu_assign_pointer(nf_nat_pptp_hook_exp_gre, NULL);
309 rcu_assign_pointer(nf_nat_pptp_hook_inbound, NULL);
310 rcu_assign_pointer(nf_nat_pptp_hook_outbound, NULL);
311 synchronize_rcu();
312}
313
314module_init(nf_nat_helper_pptp_init);
315module_exit(nf_nat_helper_pptp_fini);
diff --git a/net/ipv4/netfilter/nf_nat_proto_gre.c b/net/ipv4/netfilter/nf_nat_proto_gre.c
new file mode 100644
index 0000000000..d3de579e09
--- /dev/null
+++ b/net/ipv4/netfilter/nf_nat_proto_gre.c
@@ -0,0 +1,179 @@
1/*
2 * nf_nat_proto_gre.c
3 *
4 * NAT protocol helper module for GRE.
5 *
6 * GRE is a generic encapsulation protocol, which is generally not very
7 * suited for NAT, as it has no protocol-specific part as port numbers.
8 *
9 * It has an optional key field, which may help us distinguishing two
10 * connections between the same two hosts.
11 *
12 * GRE is defined in RFC 1701 and RFC 1702, as well as RFC 2784
13 *
14 * PPTP is built on top of a modified version of GRE, and has a mandatory
15 * field called "CallID", which serves us for the same purpose as the key
16 * field in plain GRE.
17 *
18 * Documentation about PPTP can be found in RFC 2637
19 *
20 * (C) 2000-2005 by Harald Welte <laforge@gnumonks.org>
21 *
22 * Development of this code funded by Astaro AG (http://www.astaro.com/)
23 *
24 */
25
26#include <linux/module.h>
27#include <linux/skbuff.h>
28#include <linux/ip.h>
29
30#include <net/netfilter/nf_nat.h>
31#include <net/netfilter/nf_nat_rule.h>
32#include <net/netfilter/nf_nat_protocol.h>
33#include <linux/netfilter/nf_conntrack_proto_gre.h>
34
35MODULE_LICENSE("GPL");
36MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
37MODULE_DESCRIPTION("Netfilter NAT protocol helper module for GRE");
38
39#if 0
40#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s: " format, __FILE__, \
41 __FUNCTION__, ## args)
42#else
43#define DEBUGP(x, args...)
44#endif
45
46/* is key in given range between min and max */
47static int
48gre_in_range(const struct nf_conntrack_tuple *tuple,
49 enum nf_nat_manip_type maniptype,
50 const union nf_conntrack_man_proto *min,
51 const union nf_conntrack_man_proto *max)
52{
53 __be16 key;
54
55 if (maniptype == IP_NAT_MANIP_SRC)
56 key = tuple->src.u.gre.key;
57 else
58 key = tuple->dst.u.gre.key;
59
60 return ntohs(key) >= ntohs(min->gre.key) &&
61 ntohs(key) <= ntohs(max->gre.key);
62}
63
64/* generate unique tuple ... */
65static int
66gre_unique_tuple(struct nf_conntrack_tuple *tuple,
67 const struct nf_nat_range *range,
68 enum nf_nat_manip_type maniptype,
69 const struct nf_conn *conntrack)
70{
71 static u_int16_t key;
72 __be16 *keyptr;
73 unsigned int min, i, range_size;
74
75 if (maniptype == IP_NAT_MANIP_SRC)
76 keyptr = &tuple->src.u.gre.key;
77 else
78 keyptr = &tuple->dst.u.gre.key;
79
80 if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) {
81 DEBUGP("%p: NATing GRE PPTP\n", conntrack);
82 min = 1;
83 range_size = 0xffff;
84 } else {
85 min = ntohs(range->min.gre.key);
86 range_size = ntohs(range->max.gre.key) - min + 1;
87 }
88
89 DEBUGP("min = %u, range_size = %u\n", min, range_size);
90
91 for (i = 0; i < range_size; i++, key++) {
92 *keyptr = htons(min + key % range_size);
93 if (!nf_nat_used_tuple(tuple, conntrack))
94 return 1;
95 }
96
97 DEBUGP("%p: no NAT mapping\n", conntrack);
98 return 0;
99}
100
101/* manipulate a GRE packet according to maniptype */
102static int
103gre_manip_pkt(struct sk_buff **pskb, unsigned int iphdroff,
104 const struct nf_conntrack_tuple *tuple,
105 enum nf_nat_manip_type maniptype)
106{
107 struct gre_hdr *greh;
108 struct gre_hdr_pptp *pgreh;
109 struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
110 unsigned int hdroff = iphdroff + iph->ihl * 4;
111
112 /* pgreh includes two optional 32bit fields which are not required
113 * to be there. That's where the magic '8' comes from */
114 if (!skb_make_writable(pskb, hdroff + sizeof(*pgreh) - 8))
115 return 0;
116
117 greh = (void *)(*pskb)->data + hdroff;
118 pgreh = (struct gre_hdr_pptp *)greh;
119
120 /* we only have destination manip of a packet, since 'source key'
121 * is not present in the packet itself */
122 if (maniptype != IP_NAT_MANIP_DST)
123 return 1;
124 switch (greh->version) {
125 case 0:
126 if (!greh->key) {
127 DEBUGP("can't nat GRE w/o key\n");
128 break;
129 }
130 if (greh->csum) {
131 /* FIXME: Never tested this code... */
132 nf_proto_csum_replace4(gre_csum(greh), *pskb,
133 *(gre_key(greh)),
134 tuple->dst.u.gre.key, 0);
135 }
136 *(gre_key(greh)) = tuple->dst.u.gre.key;
137 break;
138 case GRE_VERSION_PPTP:
139 DEBUGP("call_id -> 0x%04x\n", ntohs(tuple->dst.u.gre.key));
140 pgreh->call_id = tuple->dst.u.gre.key;
141 break;
142 default:
143 DEBUGP("can't nat unknown GRE version\n");
144 return 0;
145 }
146 return 1;
147}
148
149static struct nf_nat_protocol gre __read_mostly = {
150 .name = "GRE",
151 .protonum = IPPROTO_GRE,
152 .manip_pkt = gre_manip_pkt,
153 .in_range = gre_in_range,
154 .unique_tuple = gre_unique_tuple,
155#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
156 defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
157 .range_to_nfattr = nf_nat_port_range_to_nfattr,
158 .nfattr_to_range = nf_nat_port_nfattr_to_range,
159#endif
160};
161
162int __init nf_nat_proto_gre_init(void)
163{
164 return nf_nat_protocol_register(&gre);
165}
166
167void __exit nf_nat_proto_gre_fini(void)
168{
169 nf_nat_protocol_unregister(&gre);
170}
171
172module_init(nf_nat_proto_gre_init);
173module_exit(nf_nat_proto_gre_fini);
174
175void nf_nat_need_gre(void)
176{
177 return;
178}
179EXPORT_SYMBOL_GPL(nf_nat_need_gre);
diff --git a/net/ipv4/netfilter/nf_nat_proto_icmp.c b/net/ipv4/netfilter/nf_nat_proto_icmp.c
new file mode 100644
index 0000000000..dcfd772972
--- /dev/null
+++ b/net/ipv4/netfilter/nf_nat_proto_icmp.c
@@ -0,0 +1,86 @@
1/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2006 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/init.h>
11#include <linux/ip.h>
12#include <linux/icmp.h>
13
14#include <linux/netfilter.h>
15#include <net/netfilter/nf_nat.h>
16#include <net/netfilter/nf_nat_core.h>
17#include <net/netfilter/nf_nat_rule.h>
18#include <net/netfilter/nf_nat_protocol.h>
19
20static int
21icmp_in_range(const struct nf_conntrack_tuple *tuple,
22 enum nf_nat_manip_type maniptype,
23 const union nf_conntrack_man_proto *min,
24 const union nf_conntrack_man_proto *max)
25{
26 return ntohs(tuple->src.u.icmp.id) >= ntohs(min->icmp.id) &&
27 ntohs(tuple->src.u.icmp.id) <= ntohs(max->icmp.id);
28}
29
30static int
31icmp_unique_tuple(struct nf_conntrack_tuple *tuple,
32 const struct nf_nat_range *range,
33 enum nf_nat_manip_type maniptype,
34 const struct nf_conn *ct)
35{
36 static u_int16_t id;
37 unsigned int range_size;
38 unsigned int i;
39
40 range_size = ntohs(range->max.icmp.id) - ntohs(range->min.icmp.id) + 1;
41 /* If no range specified... */
42 if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED))
43 range_size = 0xFFFF;
44
45 for (i = 0; i < range_size; i++, id++) {
46 tuple->src.u.icmp.id = htons(ntohs(range->min.icmp.id) +
47 (id % range_size));
48 if (!nf_nat_used_tuple(tuple, ct))
49 return 1;
50 }
51 return 0;
52}
53
54static int
55icmp_manip_pkt(struct sk_buff **pskb,
56 unsigned int iphdroff,
57 const struct nf_conntrack_tuple *tuple,
58 enum nf_nat_manip_type maniptype)
59{
60 struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
61 struct icmphdr *hdr;
62 unsigned int hdroff = iphdroff + iph->ihl*4;
63
64 if (!skb_make_writable(pskb, hdroff + sizeof(*hdr)))
65 return 0;
66
67 hdr = (struct icmphdr *)((*pskb)->data + hdroff);
68 nf_proto_csum_replace2(&hdr->checksum, *pskb,
69 hdr->un.echo.id, tuple->src.u.icmp.id, 0);
70 hdr->un.echo.id = tuple->src.u.icmp.id;
71 return 1;
72}
73
74struct nf_nat_protocol nf_nat_protocol_icmp = {
75 .name = "ICMP",
76 .protonum = IPPROTO_ICMP,
77 .me = THIS_MODULE,
78 .manip_pkt = icmp_manip_pkt,
79 .in_range = icmp_in_range,
80 .unique_tuple = icmp_unique_tuple,
81#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
82 defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
83 .range_to_nfattr = nf_nat_port_range_to_nfattr,
84 .nfattr_to_range = nf_nat_port_nfattr_to_range,
85#endif
86};
diff --git a/net/ipv4/netfilter/nf_nat_proto_tcp.c b/net/ipv4/netfilter/nf_nat_proto_tcp.c
new file mode 100644
index 0000000000..7e26a7e9be
--- /dev/null
+++ b/net/ipv4/netfilter/nf_nat_proto_tcp.c
@@ -0,0 +1,148 @@
1/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2006 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/init.h>
11#include <linux/ip.h>
12#include <linux/tcp.h>
13
14#include <linux/netfilter.h>
15#include <linux/netfilter/nfnetlink_conntrack.h>
16#include <net/netfilter/nf_nat.h>
17#include <net/netfilter/nf_nat_rule.h>
18#include <net/netfilter/nf_nat_protocol.h>
19#include <net/netfilter/nf_nat_core.h>
20
21static int
22tcp_in_range(const struct nf_conntrack_tuple *tuple,
23 enum nf_nat_manip_type maniptype,
24 const union nf_conntrack_man_proto *min,
25 const union nf_conntrack_man_proto *max)
26{
27 __be16 port;
28
29 if (maniptype == IP_NAT_MANIP_SRC)
30 port = tuple->src.u.tcp.port;
31 else
32 port = tuple->dst.u.tcp.port;
33
34 return ntohs(port) >= ntohs(min->tcp.port) &&
35 ntohs(port) <= ntohs(max->tcp.port);
36}
37
38static int
39tcp_unique_tuple(struct nf_conntrack_tuple *tuple,
40 const struct nf_nat_range *range,
41 enum nf_nat_manip_type maniptype,
42 const struct nf_conn *ct)
43{
44 static u_int16_t port;
45 __be16 *portptr;
46 unsigned int range_size, min, i;
47
48 if (maniptype == IP_NAT_MANIP_SRC)
49 portptr = &tuple->src.u.tcp.port;
50 else
51 portptr = &tuple->dst.u.tcp.port;
52
53 /* If no range specified... */
54 if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) {
55 /* If it's dst rewrite, can't change port */
56 if (maniptype == IP_NAT_MANIP_DST)
57 return 0;
58
59 /* Map privileged onto privileged. */
60 if (ntohs(*portptr) < 1024) {
61 /* Loose convention: >> 512 is credential passing */
62 if (ntohs(*portptr)<512) {
63 min = 1;
64 range_size = 511 - min + 1;
65 } else {
66 min = 600;
67 range_size = 1023 - min + 1;
68 }
69 } else {
70 min = 1024;
71 range_size = 65535 - 1024 + 1;
72 }
73 } else {
74 min = ntohs(range->min.tcp.port);
75 range_size = ntohs(range->max.tcp.port) - min + 1;
76 }
77
78 for (i = 0; i < range_size; i++, port++) {
79 *portptr = htons(min + port % range_size);
80 if (!nf_nat_used_tuple(tuple, ct))
81 return 1;
82 }
83 return 0;
84}
85
86static int
87tcp_manip_pkt(struct sk_buff **pskb,
88 unsigned int iphdroff,
89 const struct nf_conntrack_tuple *tuple,
90 enum nf_nat_manip_type maniptype)
91{
92 struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
93 struct tcphdr *hdr;
94 unsigned int hdroff = iphdroff + iph->ihl*4;
95 __be32 oldip, newip;
96 __be16 *portptr, newport, oldport;
97 int hdrsize = 8; /* TCP connection tracking guarantees this much */
98
99 /* this could be a inner header returned in icmp packet; in such
100 cases we cannot update the checksum field since it is outside of
101 the 8 bytes of transport layer headers we are guaranteed */
102 if ((*pskb)->len >= hdroff + sizeof(struct tcphdr))
103 hdrsize = sizeof(struct tcphdr);
104
105 if (!skb_make_writable(pskb, hdroff + hdrsize))
106 return 0;
107
108 iph = (struct iphdr *)((*pskb)->data + iphdroff);
109 hdr = (struct tcphdr *)((*pskb)->data + hdroff);
110
111 if (maniptype == IP_NAT_MANIP_SRC) {
112 /* Get rid of src ip and src pt */
113 oldip = iph->saddr;
114 newip = tuple->src.u3.ip;
115 newport = tuple->src.u.tcp.port;
116 portptr = &hdr->source;
117 } else {
118 /* Get rid of dst ip and dst pt */
119 oldip = iph->daddr;
120 newip = tuple->dst.u3.ip;
121 newport = tuple->dst.u.tcp.port;
122 portptr = &hdr->dest;
123 }
124
125 oldport = *portptr;
126 *portptr = newport;
127
128 if (hdrsize < sizeof(*hdr))
129 return 1;
130
131 nf_proto_csum_replace4(&hdr->check, *pskb, oldip, newip, 1);
132 nf_proto_csum_replace2(&hdr->check, *pskb, oldport, newport, 0);
133 return 1;
134}
135
136struct nf_nat_protocol nf_nat_protocol_tcp = {
137 .name = "TCP",
138 .protonum = IPPROTO_TCP,
139 .me = THIS_MODULE,
140 .manip_pkt = tcp_manip_pkt,
141 .in_range = tcp_in_range,
142 .unique_tuple = tcp_unique_tuple,
143#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
144 defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
145 .range_to_nfattr = nf_nat_port_range_to_nfattr,
146 .nfattr_to_range = nf_nat_port_nfattr_to_range,
147#endif
148};
diff --git a/net/ipv4/netfilter/nf_nat_proto_udp.c b/net/ipv4/netfilter/nf_nat_proto_udp.c
new file mode 100644
index 0000000000..ab0ce4c869
--- /dev/null
+++ b/net/ipv4/netfilter/nf_nat_proto_udp.c
@@ -0,0 +1,138 @@
1/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2006 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/init.h>
11#include <linux/ip.h>
12#include <linux/udp.h>
13
14#include <linux/netfilter.h>
15#include <net/netfilter/nf_nat.h>
16#include <net/netfilter/nf_nat_core.h>
17#include <net/netfilter/nf_nat_rule.h>
18#include <net/netfilter/nf_nat_protocol.h>
19
20static int
21udp_in_range(const struct nf_conntrack_tuple *tuple,
22 enum nf_nat_manip_type maniptype,
23 const union nf_conntrack_man_proto *min,
24 const union nf_conntrack_man_proto *max)
25{
26 __be16 port;
27
28 if (maniptype == IP_NAT_MANIP_SRC)
29 port = tuple->src.u.udp.port;
30 else
31 port = tuple->dst.u.udp.port;
32
33 return ntohs(port) >= ntohs(min->udp.port) &&
34 ntohs(port) <= ntohs(max->udp.port);
35}
36
37static int
38udp_unique_tuple(struct nf_conntrack_tuple *tuple,
39 const struct nf_nat_range *range,
40 enum nf_nat_manip_type maniptype,
41 const struct nf_conn *ct)
42{
43 static u_int16_t port;
44 __be16 *portptr;
45 unsigned int range_size, min, i;
46
47 if (maniptype == IP_NAT_MANIP_SRC)
48 portptr = &tuple->src.u.udp.port;
49 else
50 portptr = &tuple->dst.u.udp.port;
51
52 /* If no range specified... */
53 if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) {
54 /* If it's dst rewrite, can't change port */
55 if (maniptype == IP_NAT_MANIP_DST)
56 return 0;
57
58 if (ntohs(*portptr) < 1024) {
59 /* Loose convention: >> 512 is credential passing */
60 if (ntohs(*portptr)<512) {
61 min = 1;
62 range_size = 511 - min + 1;
63 } else {
64 min = 600;
65 range_size = 1023 - min + 1;
66 }
67 } else {
68 min = 1024;
69 range_size = 65535 - 1024 + 1;
70 }
71 } else {
72 min = ntohs(range->min.udp.port);
73 range_size = ntohs(range->max.udp.port) - min + 1;
74 }
75
76 for (i = 0; i < range_size; i++, port++) {
77 *portptr = htons(min + port % range_size);
78 if (!nf_nat_used_tuple(tuple, ct))
79 return 1;
80 }
81 return 0;
82}
83
84static int
85udp_manip_pkt(struct sk_buff **pskb,
86 unsigned int iphdroff,
87 const struct nf_conntrack_tuple *tuple,
88 enum nf_nat_manip_type maniptype)
89{
90 struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);
91 struct udphdr *hdr;
92 unsigned int hdroff = iphdroff + iph->ihl*4;
93 __be32 oldip, newip;
94 __be16 *portptr, newport;
95
96 if (!skb_make_writable(pskb, hdroff + sizeof(*hdr)))
97 return 0;
98
99 iph = (struct iphdr *)((*pskb)->data + iphdroff);
100 hdr = (struct udphdr *)((*pskb)->data + hdroff);
101
102 if (maniptype == IP_NAT_MANIP_SRC) {
103 /* Get rid of src ip and src pt */
104 oldip = iph->saddr;
105 newip = tuple->src.u3.ip;
106 newport = tuple->src.u.udp.port;
107 portptr = &hdr->source;
108 } else {
109 /* Get rid of dst ip and dst pt */
110 oldip = iph->daddr;
111 newip = tuple->dst.u3.ip;
112 newport = tuple->dst.u.udp.port;
113 portptr = &hdr->dest;
114 }
115 if (hdr->check || (*pskb)->ip_summed == CHECKSUM_PARTIAL) {
116 nf_proto_csum_replace4(&hdr->check, *pskb, oldip, newip, 1);
117 nf_proto_csum_replace2(&hdr->check, *pskb, *portptr, newport,
118 0);
119 if (!hdr->check)
120 hdr->check = CSUM_MANGLED_0;
121 }
122 *portptr = newport;
123 return 1;
124}
125
126struct nf_nat_protocol nf_nat_protocol_udp = {
127 .name = "UDP",
128 .protonum = IPPROTO_UDP,
129 .me = THIS_MODULE,
130 .manip_pkt = udp_manip_pkt,
131 .in_range = udp_in_range,
132 .unique_tuple = udp_unique_tuple,
133#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
134 defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
135 .range_to_nfattr = nf_nat_port_range_to_nfattr,
136 .nfattr_to_range = nf_nat_port_nfattr_to_range,
137#endif
138};
diff --git a/net/ipv4/netfilter/nf_nat_proto_unknown.c b/net/ipv4/netfilter/nf_nat_proto_unknown.c
new file mode 100644
index 0000000000..f50d0203f9
--- /dev/null
+++ b/net/ipv4/netfilter/nf_nat_proto_unknown.c
@@ -0,0 +1,54 @@
1/* The "unknown" protocol. This is what is used for protocols we
2 * don't understand. It's returned by ip_ct_find_proto().
3 */
4
5/* (C) 1999-2001 Paul `Rusty' Russell
6 * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/types.h>
14#include <linux/init.h>
15
16#include <linux/netfilter.h>
17#include <net/netfilter/nf_nat.h>
18#include <net/netfilter/nf_nat_rule.h>
19#include <net/netfilter/nf_nat_protocol.h>
20
21static int unknown_in_range(const struct nf_conntrack_tuple *tuple,
22 enum nf_nat_manip_type manip_type,
23 const union nf_conntrack_man_proto *min,
24 const union nf_conntrack_man_proto *max)
25{
26 return 1;
27}
28
29static int unknown_unique_tuple(struct nf_conntrack_tuple *tuple,
30 const struct nf_nat_range *range,
31 enum nf_nat_manip_type maniptype,
32 const struct nf_conn *ct)
33{
34 /* Sorry: we can't help you; if it's not unique, we can't frob
35 anything. */
36 return 0;
37}
38
39static int
40unknown_manip_pkt(struct sk_buff **pskb,
41 unsigned int iphdroff,
42 const struct nf_conntrack_tuple *tuple,
43 enum nf_nat_manip_type maniptype)
44{
45 return 1;
46}
47
48struct nf_nat_protocol nf_nat_unknown_protocol = {
49 .name = "unknown",
50 /* .me isn't set: getting a ref to this cannot fail. */
51 .manip_pkt = unknown_manip_pkt,
52 .in_range = unknown_in_range,
53 .unique_tuple = unknown_unique_tuple,
54};
diff --git a/net/ipv4/netfilter/nf_nat_rule.c b/net/ipv4/netfilter/nf_nat_rule.c
new file mode 100644
index 0000000000..b868ee0195
--- /dev/null
+++ b/net/ipv4/netfilter/nf_nat_rule.c
@@ -0,0 +1,343 @@
1/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2006 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/* Everything about the rules for NAT. */
10#include <linux/types.h>
11#include <linux/ip.h>
12#include <linux/netfilter.h>
13#include <linux/netfilter_ipv4.h>
14#include <linux/module.h>
15#include <linux/kmod.h>
16#include <linux/skbuff.h>
17#include <linux/proc_fs.h>
18#include <net/checksum.h>
19#include <net/route.h>
20#include <linux/bitops.h>
21
22#include <linux/netfilter_ipv4/ip_tables.h>
23#include <net/netfilter/nf_nat.h>
24#include <net/netfilter/nf_nat_core.h>
25#include <net/netfilter/nf_nat_rule.h>
26
27#if 0
28#define DEBUGP printk
29#else
30#define DEBUGP(format, args...)
31#endif
32
33#define NAT_VALID_HOOKS ((1<<NF_IP_PRE_ROUTING) | (1<<NF_IP_POST_ROUTING) | (1<<NF_IP_LOCAL_OUT))
34
35static struct
36{
37 struct ipt_replace repl;
38 struct ipt_standard entries[3];
39 struct ipt_error term;
40} nat_initial_table __initdata = {
41 .repl = {
42 .name = "nat",
43 .valid_hooks = NAT_VALID_HOOKS,
44 .num_entries = 4,
45 .size = sizeof(struct ipt_standard) * 3 + sizeof(struct ipt_error),
46 .hook_entry = {
47 [NF_IP_PRE_ROUTING] = 0,
48 [NF_IP_POST_ROUTING] = sizeof(struct ipt_standard),
49 [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 },
50 .underflow = {
51 [NF_IP_PRE_ROUTING] = 0,
52 [NF_IP_POST_ROUTING] = sizeof(struct ipt_standard),
53 [NF_IP_LOCAL_OUT] = sizeof(struct ipt_standard) * 2 },
54 },
55 .entries = {
56 /* PRE_ROUTING */
57 {
58 .entry = {
59 .target_offset = sizeof(struct ipt_entry),
60 .next_offset = sizeof(struct ipt_standard),
61 },
62 .target = {
63 .target = {
64 .u = {
65 .target_size = IPT_ALIGN(sizeof(struct ipt_standard_target)),
66 },
67 },
68 .verdict = -NF_ACCEPT - 1,
69 },
70 },
71 /* POST_ROUTING */
72 {
73 .entry = {
74 .target_offset = sizeof(struct ipt_entry),
75 .next_offset = sizeof(struct ipt_standard),
76 },
77 .target = {
78 .target = {
79 .u = {
80 .target_size = IPT_ALIGN(sizeof(struct ipt_standard_target)),
81 },
82 },
83 .verdict = -NF_ACCEPT - 1,
84 },
85 },
86 /* LOCAL_OUT */
87 {
88 .entry = {
89 .target_offset = sizeof(struct ipt_entry),
90 .next_offset = sizeof(struct ipt_standard),
91 },
92 .target = {
93 .target = {
94 .u = {
95 .target_size = IPT_ALIGN(sizeof(struct ipt_standard_target)),
96 },
97 },
98 .verdict = -NF_ACCEPT - 1,
99 },
100 },
101 },
102 /* ERROR */
103 .term = {
104 .entry = {
105 .target_offset = sizeof(struct ipt_entry),
106 .next_offset = sizeof(struct ipt_error),
107 },
108 .target = {
109 .target = {
110 .u = {
111 .user = {
112 .target_size = IPT_ALIGN(sizeof(struct ipt_error_target)),
113 .name = IPT_ERROR_TARGET,
114 },
115 },
116 },
117 .errorname = "ERROR",
118 },
119 }
120};
121
122static struct ipt_table nat_table = {
123 .name = "nat",
124 .valid_hooks = NAT_VALID_HOOKS,
125 .lock = RW_LOCK_UNLOCKED,
126 .me = THIS_MODULE,
127 .af = AF_INET,
128};
129
130/* Source NAT */
131static unsigned int ipt_snat_target(struct sk_buff **pskb,
132 const struct net_device *in,
133 const struct net_device *out,
134 unsigned int hooknum,
135 const struct xt_target *target,
136 const void *targinfo)
137{
138 struct nf_conn *ct;
139 enum ip_conntrack_info ctinfo;
140 const struct nf_nat_multi_range_compat *mr = targinfo;
141
142 NF_CT_ASSERT(hooknum == NF_IP_POST_ROUTING);
143
144 ct = nf_ct_get(*pskb, &ctinfo);
145
146 /* Connection must be valid and new. */
147 NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
148 ctinfo == IP_CT_RELATED + IP_CT_IS_REPLY));
149 NF_CT_ASSERT(out);
150
151 return nf_nat_setup_info(ct, &mr->range[0], hooknum);
152}
153
154/* Before 2.6.11 we did implicit source NAT if required. Warn about change. */
155static void warn_if_extra_mangle(__be32 dstip, __be32 srcip)
156{
157 static int warned = 0;
158 struct flowi fl = { .nl_u = { .ip4_u = { .daddr = dstip } } };
159 struct rtable *rt;
160
161 if (ip_route_output_key(&rt, &fl) != 0)
162 return;
163
164 if (rt->rt_src != srcip && !warned) {
165 printk("NAT: no longer support implicit source local NAT\n");
166 printk("NAT: packet src %u.%u.%u.%u -> dst %u.%u.%u.%u\n",
167 NIPQUAD(srcip), NIPQUAD(dstip));
168 warned = 1;
169 }
170 ip_rt_put(rt);
171}
172
173static unsigned int ipt_dnat_target(struct sk_buff **pskb,
174 const struct net_device *in,
175 const struct net_device *out,
176 unsigned int hooknum,
177 const struct xt_target *target,
178 const void *targinfo)
179{
180 struct nf_conn *ct;
181 enum ip_conntrack_info ctinfo;
182 const struct nf_nat_multi_range_compat *mr = targinfo;
183
184 NF_CT_ASSERT(hooknum == NF_IP_PRE_ROUTING ||
185 hooknum == NF_IP_LOCAL_OUT);
186
187 ct = nf_ct_get(*pskb, &ctinfo);
188
189 /* Connection must be valid and new. */
190 NF_CT_ASSERT(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED));
191
192 if (hooknum == NF_IP_LOCAL_OUT &&
193 mr->range[0].flags & IP_NAT_RANGE_MAP_IPS)
194 warn_if_extra_mangle((*pskb)->nh.iph->daddr,
195 mr->range[0].min_ip);
196
197 return nf_nat_setup_info(ct, &mr->range[0], hooknum);
198}
199
200static int ipt_snat_checkentry(const char *tablename,
201 const void *entry,
202 const struct xt_target *target,
203 void *targinfo,
204 unsigned int hook_mask)
205{
206 struct nf_nat_multi_range_compat *mr = targinfo;
207
208 /* Must be a valid range */
209 if (mr->rangesize != 1) {
210 printk("SNAT: multiple ranges no longer supported\n");
211 return 0;
212 }
213 return 1;
214}
215
216static int ipt_dnat_checkentry(const char *tablename,
217 const void *entry,
218 const struct xt_target *target,
219 void *targinfo,
220 unsigned int hook_mask)
221{
222 struct nf_nat_multi_range_compat *mr = targinfo;
223
224 /* Must be a valid range */
225 if (mr->rangesize != 1) {
226 printk("DNAT: multiple ranges no longer supported\n");
227 return 0;
228 }
229 return 1;
230}
231
232inline unsigned int
233alloc_null_binding(struct nf_conn *ct,
234 struct nf_nat_info *info,
235 unsigned int hooknum)
236{
237 /* Force range to this IP; let proto decide mapping for
238 per-proto parts (hence not IP_NAT_RANGE_PROTO_SPECIFIED).
239 Use reply in case it's already been mangled (eg local packet).
240 */
241 __be32 ip
242 = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC
243 ? ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip
244 : ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip);
245 struct nf_nat_range range
246 = { IP_NAT_RANGE_MAP_IPS, ip, ip, { 0 }, { 0 } };
247
248 DEBUGP("Allocating NULL binding for %p (%u.%u.%u.%u)\n",
249 ct, NIPQUAD(ip));
250 return nf_nat_setup_info(ct, &range, hooknum);
251}
252
253unsigned int
254alloc_null_binding_confirmed(struct nf_conn *ct,
255 struct nf_nat_info *info,
256 unsigned int hooknum)
257{
258 __be32 ip
259 = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC
260 ? ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip
261 : ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip);
262 u_int16_t all
263 = (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC
264 ? ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.all
265 : ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u.all);
266 struct nf_nat_range range
267 = { IP_NAT_RANGE_MAP_IPS, ip, ip, { all }, { all } };
268
269 DEBUGP("Allocating NULL binding for confirmed %p (%u.%u.%u.%u)\n",
270 ct, NIPQUAD(ip));
271 return nf_nat_setup_info(ct, &range, hooknum);
272}
273
274int nf_nat_rule_find(struct sk_buff **pskb,
275 unsigned int hooknum,
276 const struct net_device *in,
277 const struct net_device *out,
278 struct nf_conn *ct,
279 struct nf_nat_info *info)
280{
281 int ret;
282
283 ret = ipt_do_table(pskb, hooknum, in, out, &nat_table);
284
285 if (ret == NF_ACCEPT) {
286 if (!nf_nat_initialized(ct, HOOK2MANIP(hooknum)))
287 /* NUL mapping */
288 ret = alloc_null_binding(ct, info, hooknum);
289 }
290 return ret;
291}
292
293static struct ipt_target ipt_snat_reg = {
294 .name = "SNAT",
295 .target = ipt_snat_target,
296 .targetsize = sizeof(struct nf_nat_multi_range_compat),
297 .table = "nat",
298 .hooks = 1 << NF_IP_POST_ROUTING,
299 .checkentry = ipt_snat_checkentry,
300 .family = AF_INET,
301};
302
303static struct xt_target ipt_dnat_reg = {
304 .name = "DNAT",
305 .target = ipt_dnat_target,
306 .targetsize = sizeof(struct nf_nat_multi_range_compat),
307 .table = "nat",
308 .hooks = (1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_OUT),
309 .checkentry = ipt_dnat_checkentry,
310 .family = AF_INET,
311};
312
313int __init nf_nat_rule_init(void)
314{
315 int ret;
316
317 ret = ipt_register_table(&nat_table, &nat_initial_table.repl);
318 if (ret != 0)
319 return ret;
320 ret = xt_register_target(&ipt_snat_reg);
321 if (ret != 0)
322 goto unregister_table;
323
324 ret = xt_register_target(&ipt_dnat_reg);
325 if (ret != 0)
326 goto unregister_snat;
327
328 return ret;
329
330 unregister_snat:
331 xt_unregister_target(&ipt_snat_reg);
332 unregister_table:
333 ipt_unregister_table(&nat_table);
334
335 return ret;
336}
337
338void nf_nat_rule_cleanup(void)
339{
340 xt_unregister_target(&ipt_dnat_reg);
341 xt_unregister_target(&ipt_snat_reg);
342 ipt_unregister_table(&nat_table);
343}
diff --git a/net/ipv4/netfilter/nf_nat_sip.c b/net/ipv4/netfilter/nf_nat_sip.c
new file mode 100644
index 0000000000..3d524b9573
--- /dev/null
+++ b/net/ipv4/netfilter/nf_nat_sip.c
@@ -0,0 +1,283 @@
1/* SIP extension for UDP NAT alteration.
2 *
3 * (C) 2005 by Christian Hentschel <chentschel@arnet.com.ar>
4 * based on RR's ip_nat_ftp.c and other modules.
5 *
6 * 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 * published by the Free Software Foundation.
9 */
10
11#include <linux/module.h>
12#include <linux/skbuff.h>
13#include <linux/ip.h>
14#include <linux/udp.h>
15
16#include <net/netfilter/nf_nat.h>
17#include <net/netfilter/nf_nat_helper.h>
18#include <net/netfilter/nf_nat_rule.h>
19#include <net/netfilter/nf_conntrack_helper.h>
20#include <net/netfilter/nf_conntrack_expect.h>
21#include <linux/netfilter/nf_conntrack_sip.h>
22
23MODULE_LICENSE("GPL");
24MODULE_AUTHOR("Christian Hentschel <chentschel@arnet.com.ar>");
25MODULE_DESCRIPTION("SIP NAT helper");
26MODULE_ALIAS("ip_nat_sip");
27
28#if 0
29#define DEBUGP printk
30#else
31#define DEBUGP(format, args...)
32#endif
33
34struct addr_map {
35 struct {
36 char src[sizeof("nnn.nnn.nnn.nnn:nnnnn")];
37 char dst[sizeof("nnn.nnn.nnn.nnn:nnnnn")];
38 unsigned int srclen, srciplen;
39 unsigned int dstlen, dstiplen;
40 } addr[IP_CT_DIR_MAX];
41};
42
43static void addr_map_init(struct nf_conn *ct, struct addr_map *map)
44{
45 struct nf_conntrack_tuple *t;
46 enum ip_conntrack_dir dir;
47 unsigned int n;
48
49 for (dir = 0; dir < IP_CT_DIR_MAX; dir++) {
50 t = &ct->tuplehash[dir].tuple;
51
52 n = sprintf(map->addr[dir].src, "%u.%u.%u.%u",
53 NIPQUAD(t->src.u3.ip));
54 map->addr[dir].srciplen = n;
55 n += sprintf(map->addr[dir].src + n, ":%u",
56 ntohs(t->src.u.udp.port));
57 map->addr[dir].srclen = n;
58
59 n = sprintf(map->addr[dir].dst, "%u.%u.%u.%u",
60 NIPQUAD(t->dst.u3.ip));
61 map->addr[dir].dstiplen = n;
62 n += sprintf(map->addr[dir].dst + n, ":%u",
63 ntohs(t->dst.u.udp.port));
64 map->addr[dir].dstlen = n;
65 }
66}
67
68static int map_sip_addr(struct sk_buff **pskb, enum ip_conntrack_info ctinfo,
69 struct nf_conn *ct, const char **dptr, size_t dlen,
70 enum sip_header_pos pos, struct addr_map *map)
71{
72 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
73 unsigned int matchlen, matchoff, addrlen;
74 char *addr;
75
76 if (ct_sip_get_info(ct, *dptr, dlen, &matchoff, &matchlen, pos) <= 0)
77 return 1;
78
79 if ((matchlen == map->addr[dir].srciplen ||
80 matchlen == map->addr[dir].srclen) &&
81 memcmp(*dptr + matchoff, map->addr[dir].src, matchlen) == 0) {
82 addr = map->addr[!dir].dst;
83 addrlen = map->addr[!dir].dstlen;
84 } else if ((matchlen == map->addr[dir].dstiplen ||
85 matchlen == map->addr[dir].dstlen) &&
86 memcmp(*dptr + matchoff, map->addr[dir].dst, matchlen) == 0) {
87 addr = map->addr[!dir].src;
88 addrlen = map->addr[!dir].srclen;
89 } else
90 return 1;
91
92 if (!nf_nat_mangle_udp_packet(pskb, ct, ctinfo,
93 matchoff, matchlen, addr, addrlen))
94 return 0;
95 *dptr = (*pskb)->data + (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);
96 return 1;
97
98}
99
100static unsigned int ip_nat_sip(struct sk_buff **pskb,
101 enum ip_conntrack_info ctinfo,
102 struct nf_conn *ct,
103 const char **dptr)
104{
105 enum sip_header_pos pos;
106 struct addr_map map;
107 int dataoff, datalen;
108
109 dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);
110 datalen = (*pskb)->len - dataoff;
111 if (datalen < sizeof("SIP/2.0") - 1)
112 return NF_DROP;
113
114 addr_map_init(ct, &map);
115
116 /* Basic rules: requests and responses. */
117 if (strncmp(*dptr, "SIP/2.0", sizeof("SIP/2.0") - 1) != 0) {
118 /* 10.2: Constructing the REGISTER Request:
119 *
120 * The "userinfo" and "@" components of the SIP URI MUST NOT
121 * be present.
122 */
123 if (datalen >= sizeof("REGISTER") - 1 &&
124 strncmp(*dptr, "REGISTER", sizeof("REGISTER") - 1) == 0)
125 pos = POS_REG_REQ_URI;
126 else
127 pos = POS_REQ_URI;
128
129 if (!map_sip_addr(pskb, ctinfo, ct, dptr, datalen, pos, &map))
130 return NF_DROP;
131 }
132
133 if (!map_sip_addr(pskb, ctinfo, ct, dptr, datalen, POS_FROM, &map) ||
134 !map_sip_addr(pskb, ctinfo, ct, dptr, datalen, POS_TO, &map) ||
135 !map_sip_addr(pskb, ctinfo, ct, dptr, datalen, POS_VIA, &map) ||
136 !map_sip_addr(pskb, ctinfo, ct, dptr, datalen, POS_CONTACT, &map))
137 return NF_DROP;
138 return NF_ACCEPT;
139}
140
141static unsigned int mangle_sip_packet(struct sk_buff **pskb,
142 enum ip_conntrack_info ctinfo,
143 struct nf_conn *ct,
144 const char **dptr, size_t dlen,
145 char *buffer, int bufflen,
146 enum sip_header_pos pos)
147{
148 unsigned int matchlen, matchoff;
149
150 if (ct_sip_get_info(ct, *dptr, dlen, &matchoff, &matchlen, pos) <= 0)
151 return 0;
152
153 if (!nf_nat_mangle_udp_packet(pskb, ct, ctinfo,
154 matchoff, matchlen, buffer, bufflen))
155 return 0;
156
157 /* We need to reload this. Thanks Patrick. */
158 *dptr = (*pskb)->data + (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);
159 return 1;
160}
161
162static int mangle_content_len(struct sk_buff **pskb,
163 enum ip_conntrack_info ctinfo,
164 struct nf_conn *ct,
165 const char *dptr)
166{
167 unsigned int dataoff, matchoff, matchlen;
168 char buffer[sizeof("65536")];
169 int bufflen;
170
171 dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);
172
173 /* Get actual SDP lenght */
174 if (ct_sip_get_info(ct, dptr, (*pskb)->len - dataoff, &matchoff,
175 &matchlen, POS_SDP_HEADER) > 0) {
176
177 /* since ct_sip_get_info() give us a pointer passing 'v='
178 we need to add 2 bytes in this count. */
179 int c_len = (*pskb)->len - dataoff - matchoff + 2;
180
181 /* Now, update SDP length */
182 if (ct_sip_get_info(ct, dptr, (*pskb)->len - dataoff, &matchoff,
183 &matchlen, POS_CONTENT) > 0) {
184
185 bufflen = sprintf(buffer, "%u", c_len);
186 return nf_nat_mangle_udp_packet(pskb, ct, ctinfo,
187 matchoff, matchlen,
188 buffer, bufflen);
189 }
190 }
191 return 0;
192}
193
194static unsigned int mangle_sdp(struct sk_buff **pskb,
195 enum ip_conntrack_info ctinfo,
196 struct nf_conn *ct,
197 __be32 newip, u_int16_t port,
198 const char *dptr)
199{
200 char buffer[sizeof("nnn.nnn.nnn.nnn")];
201 unsigned int dataoff, bufflen;
202
203 dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);
204
205 /* Mangle owner and contact info. */
206 bufflen = sprintf(buffer, "%u.%u.%u.%u", NIPQUAD(newip));
207 if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff,
208 buffer, bufflen, POS_OWNER_IP4))
209 return 0;
210
211 if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff,
212 buffer, bufflen, POS_CONNECTION_IP4))
213 return 0;
214
215 /* Mangle media port. */
216 bufflen = sprintf(buffer, "%u", port);
217 if (!mangle_sip_packet(pskb, ctinfo, ct, &dptr, (*pskb)->len - dataoff,
218 buffer, bufflen, POS_MEDIA))
219 return 0;
220
221 return mangle_content_len(pskb, ctinfo, ct, dptr);
222}
223
224/* So, this packet has hit the connection tracking matching code.
225 Mangle it, and change the expectation to match the new version. */
226static unsigned int ip_nat_sdp(struct sk_buff **pskb,
227 enum ip_conntrack_info ctinfo,
228 struct nf_conntrack_expect *exp,
229 const char *dptr)
230{
231 struct nf_conn *ct = exp->master;
232 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
233 __be32 newip;
234 u_int16_t port;
235
236 DEBUGP("ip_nat_sdp():\n");
237
238 /* Connection will come from reply */
239 newip = ct->tuplehash[!dir].tuple.dst.u3.ip;
240
241 exp->tuple.dst.u3.ip = newip;
242 exp->saved_proto.udp.port = exp->tuple.dst.u.udp.port;
243 exp->dir = !dir;
244
245 /* When you see the packet, we need to NAT it the same as the
246 this one. */
247 exp->expectfn = nf_nat_follow_master;
248
249 /* Try to get same port: if not, try to change it. */
250 for (port = ntohs(exp->saved_proto.udp.port); port != 0; port++) {
251 exp->tuple.dst.u.udp.port = htons(port);
252 if (nf_conntrack_expect_related(exp) == 0)
253 break;
254 }
255
256 if (port == 0)
257 return NF_DROP;
258
259 if (!mangle_sdp(pskb, ctinfo, ct, newip, port, dptr)) {
260 nf_conntrack_unexpect_related(exp);
261 return NF_DROP;
262 }
263 return NF_ACCEPT;
264}
265
266static void __exit nf_nat_sip_fini(void)
267{
268 rcu_assign_pointer(nf_nat_sip_hook, NULL);
269 rcu_assign_pointer(nf_nat_sdp_hook, NULL);
270 synchronize_rcu();
271}
272
273static int __init nf_nat_sip_init(void)
274{
275 BUG_ON(rcu_dereference(nf_nat_sip_hook));
276 BUG_ON(rcu_dereference(nf_nat_sdp_hook));
277 rcu_assign_pointer(nf_nat_sip_hook, ip_nat_sip);
278 rcu_assign_pointer(nf_nat_sdp_hook, ip_nat_sdp);
279 return 0;
280}
281
282module_init(nf_nat_sip_init);
283module_exit(nf_nat_sip_fini);
diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c
new file mode 100644
index 0000000000..f12528fe1b
--- /dev/null
+++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c
@@ -0,0 +1,1332 @@
1/*
2 * nf_nat_snmp_basic.c
3 *
4 * Basic SNMP Application Layer Gateway
5 *
6 * This IP NAT module is intended for use with SNMP network
7 * discovery and monitoring applications where target networks use
8 * conflicting private address realms.
9 *
10 * Static NAT is used to remap the networks from the view of the network
11 * management system at the IP layer, and this module remaps some application
12 * layer addresses to match.
13 *
14 * The simplest form of ALG is performed, where only tagged IP addresses
15 * are modified. The module does not need to be MIB aware and only scans
16 * messages at the ASN.1/BER level.
17 *
18 * Currently, only SNMPv1 and SNMPv2 are supported.
19 *
20 * More information on ALG and associated issues can be found in
21 * RFC 2962
22 *
23 * The ASB.1/BER parsing code is derived from the gxsnmp package by Gregory
24 * McLean & Jochen Friedrich, stripped down for use in the kernel.
25 *
26 * Copyright (c) 2000 RP Internet (www.rpi.net.au).
27 *
28 * This program is free software; you can redistribute it and/or modify
29 * it under the terms of the GNU General Public License as published by
30 * the Free Software Foundation; either version 2 of the License, or
31 * (at your option) any later version.
32 * This program is distributed in the hope that it will be useful,
33 * but WITHOUT ANY WARRANTY; without even the implied warranty of
34 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35 * GNU General Public License for more details.
36 * You should have received a copy of the GNU General Public License
37 * along with this program; if not, write to the Free Software
38 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
39 *
40 * Author: James Morris <jmorris@intercode.com.au>
41 *
42 * Updates:
43 * 2000-08-06: Convert to new helper API (Harald Welte).
44 *
45 */
46#include <linux/module.h>
47#include <linux/moduleparam.h>
48#include <linux/types.h>
49#include <linux/kernel.h>
50#include <linux/in.h>
51#include <linux/ip.h>
52#include <linux/udp.h>
53#include <net/checksum.h>
54#include <net/udp.h>
55
56#include <net/netfilter/nf_nat.h>
57#include <net/netfilter/nf_conntrack_helper.h>
58#include <net/netfilter/nf_nat_helper.h>
59
60MODULE_LICENSE("GPL");
61MODULE_AUTHOR("James Morris <jmorris@intercode.com.au>");
62MODULE_DESCRIPTION("Basic SNMP Application Layer Gateway");
63MODULE_ALIAS("ip_nat_snmp_basic");
64
65#define SNMP_PORT 161
66#define SNMP_TRAP_PORT 162
67#define NOCT1(n) (*(u8 *)n)
68
69static int debug;
70static DEFINE_SPINLOCK(snmp_lock);
71
72/*
73 * Application layer address mapping mimics the NAT mapping, but
74 * only for the first octet in this case (a more flexible system
75 * can be implemented if needed).
76 */
77struct oct1_map
78{
79 u_int8_t from;
80 u_int8_t to;
81};
82
83
84/*****************************************************************************
85 *
86 * Basic ASN.1 decoding routines (gxsnmp author Dirk Wisse)
87 *
88 *****************************************************************************/
89
90/* Class */
91#define ASN1_UNI 0 /* Universal */
92#define ASN1_APL 1 /* Application */
93#define ASN1_CTX 2 /* Context */
94#define ASN1_PRV 3 /* Private */
95
96/* Tag */
97#define ASN1_EOC 0 /* End Of Contents */
98#define ASN1_BOL 1 /* Boolean */
99#define ASN1_INT 2 /* Integer */
100#define ASN1_BTS 3 /* Bit String */
101#define ASN1_OTS 4 /* Octet String */
102#define ASN1_NUL 5 /* Null */
103#define ASN1_OJI 6 /* Object Identifier */
104#define ASN1_OJD 7 /* Object Description */
105#define ASN1_EXT 8 /* External */
106#define ASN1_SEQ 16 /* Sequence */
107#define ASN1_SET 17 /* Set */
108#define ASN1_NUMSTR 18 /* Numerical String */
109#define ASN1_PRNSTR 19 /* Printable String */
110#define ASN1_TEXSTR 20 /* Teletext String */
111#define ASN1_VIDSTR 21 /* Video String */
112#define ASN1_IA5STR 22 /* IA5 String */
113#define ASN1_UNITIM 23 /* Universal Time */
114#define ASN1_GENTIM 24 /* General Time */
115#define ASN1_GRASTR 25 /* Graphical String */
116#define ASN1_VISSTR 26 /* Visible String */
117#define ASN1_GENSTR 27 /* General String */
118
119/* Primitive / Constructed methods*/
120#define ASN1_PRI 0 /* Primitive */
121#define ASN1_CON 1 /* Constructed */
122
123/*
124 * Error codes.
125 */
126#define ASN1_ERR_NOERROR 0
127#define ASN1_ERR_DEC_EMPTY 2
128#define ASN1_ERR_DEC_EOC_MISMATCH 3
129#define ASN1_ERR_DEC_LENGTH_MISMATCH 4
130#define ASN1_ERR_DEC_BADVALUE 5
131
132/*
133 * ASN.1 context.
134 */
135struct asn1_ctx
136{
137 int error; /* Error condition */
138 unsigned char *pointer; /* Octet just to be decoded */
139 unsigned char *begin; /* First octet */
140 unsigned char *end; /* Octet after last octet */
141};
142
143/*
144 * Octet string (not null terminated)
145 */
146struct asn1_octstr
147{
148 unsigned char *data;
149 unsigned int len;
150};
151
152static void asn1_open(struct asn1_ctx *ctx,
153 unsigned char *buf,
154 unsigned int len)
155{
156 ctx->begin = buf;
157 ctx->end = buf + len;
158 ctx->pointer = buf;
159 ctx->error = ASN1_ERR_NOERROR;
160}
161
162static unsigned char asn1_octet_decode(struct asn1_ctx *ctx, unsigned char *ch)
163{
164 if (ctx->pointer >= ctx->end) {
165 ctx->error = ASN1_ERR_DEC_EMPTY;
166 return 0;
167 }
168 *ch = *(ctx->pointer)++;
169 return 1;
170}
171
172static unsigned char asn1_tag_decode(struct asn1_ctx *ctx, unsigned int *tag)
173{
174 unsigned char ch;
175
176 *tag = 0;
177
178 do
179 {
180 if (!asn1_octet_decode(ctx, &ch))
181 return 0;
182 *tag <<= 7;
183 *tag |= ch & 0x7F;
184 } while ((ch & 0x80) == 0x80);
185 return 1;
186}
187
188static unsigned char asn1_id_decode(struct asn1_ctx *ctx,
189 unsigned int *cls,
190 unsigned int *con,
191 unsigned int *tag)
192{
193 unsigned char ch;
194
195 if (!asn1_octet_decode(ctx, &ch))
196 return 0;
197
198 *cls = (ch & 0xC0) >> 6;
199 *con = (ch & 0x20) >> 5;
200 *tag = (ch & 0x1F);
201
202 if (*tag == 0x1F) {
203 if (!asn1_tag_decode(ctx, tag))
204 return 0;
205 }
206 return 1;
207}
208
209static unsigned char asn1_length_decode(struct asn1_ctx *ctx,
210 unsigned int *def,
211 unsigned int *len)
212{
213 unsigned char ch, cnt;
214
215 if (!asn1_octet_decode(ctx, &ch))
216 return 0;
217
218 if (ch == 0x80)
219 *def = 0;
220 else {
221 *def = 1;
222
223 if (ch < 0x80)
224 *len = ch;
225 else {
226 cnt = (unsigned char) (ch & 0x7F);
227 *len = 0;
228
229 while (cnt > 0) {
230 if (!asn1_octet_decode(ctx, &ch))
231 return 0;
232 *len <<= 8;
233 *len |= ch;
234 cnt--;
235 }
236 }
237 }
238 return 1;
239}
240
241static unsigned char asn1_header_decode(struct asn1_ctx *ctx,
242 unsigned char **eoc,
243 unsigned int *cls,
244 unsigned int *con,
245 unsigned int *tag)
246{
247 unsigned int def, len;
248
249 if (!asn1_id_decode(ctx, cls, con, tag))
250 return 0;
251
252 def = len = 0;
253 if (!asn1_length_decode(ctx, &def, &len))
254 return 0;
255
256 if (def)
257 *eoc = ctx->pointer + len;
258 else
259 *eoc = NULL;
260 return 1;
261}
262
263static unsigned char asn1_eoc_decode(struct asn1_ctx *ctx, unsigned char *eoc)
264{
265 unsigned char ch;
266
267 if (eoc == 0) {
268 if (!asn1_octet_decode(ctx, &ch))
269 return 0;
270
271 if (ch != 0x00) {
272 ctx->error = ASN1_ERR_DEC_EOC_MISMATCH;
273 return 0;
274 }
275
276 if (!asn1_octet_decode(ctx, &ch))
277 return 0;
278
279 if (ch != 0x00) {
280 ctx->error = ASN1_ERR_DEC_EOC_MISMATCH;
281 return 0;
282 }
283 return 1;
284 } else {
285 if (ctx->pointer != eoc) {
286 ctx->error = ASN1_ERR_DEC_LENGTH_MISMATCH;
287 return 0;
288 }
289 return 1;
290 }
291}
292
293static unsigned char asn1_null_decode(struct asn1_ctx *ctx, unsigned char *eoc)
294{
295 ctx->pointer = eoc;
296 return 1;
297}
298
299static unsigned char asn1_long_decode(struct asn1_ctx *ctx,
300 unsigned char *eoc,
301 long *integer)
302{
303 unsigned char ch;
304 unsigned int len;
305
306 if (!asn1_octet_decode(ctx, &ch))
307 return 0;
308
309 *integer = (signed char) ch;
310 len = 1;
311
312 while (ctx->pointer < eoc) {
313 if (++len > sizeof (long)) {
314 ctx->error = ASN1_ERR_DEC_BADVALUE;
315 return 0;
316 }
317
318 if (!asn1_octet_decode(ctx, &ch))
319 return 0;
320
321 *integer <<= 8;
322 *integer |= ch;
323 }
324 return 1;
325}
326
327static unsigned char asn1_uint_decode(struct asn1_ctx *ctx,
328 unsigned char *eoc,
329 unsigned int *integer)
330{
331 unsigned char ch;
332 unsigned int len;
333
334 if (!asn1_octet_decode(ctx, &ch))
335 return 0;
336
337 *integer = ch;
338 if (ch == 0) len = 0;
339 else len = 1;
340
341 while (ctx->pointer < eoc) {
342 if (++len > sizeof (unsigned int)) {
343 ctx->error = ASN1_ERR_DEC_BADVALUE;
344 return 0;
345 }
346
347 if (!asn1_octet_decode(ctx, &ch))
348 return 0;
349
350 *integer <<= 8;
351 *integer |= ch;
352 }
353 return 1;
354}
355
356static unsigned char asn1_ulong_decode(struct asn1_ctx *ctx,
357 unsigned char *eoc,
358 unsigned long *integer)
359{
360 unsigned char ch;
361 unsigned int len;
362
363 if (!asn1_octet_decode(ctx, &ch))
364 return 0;
365
366 *integer = ch;
367 if (ch == 0) len = 0;
368 else len = 1;
369
370 while (ctx->pointer < eoc) {
371 if (++len > sizeof (unsigned long)) {
372 ctx->error = ASN1_ERR_DEC_BADVALUE;
373 return 0;
374 }
375
376 if (!asn1_octet_decode(ctx, &ch))
377 return 0;
378
379 *integer <<= 8;
380 *integer |= ch;
381 }
382 return 1;
383}
384
385static unsigned char asn1_octets_decode(struct asn1_ctx *ctx,
386 unsigned char *eoc,
387 unsigned char **octets,
388 unsigned int *len)
389{
390 unsigned char *ptr;
391
392 *len = 0;
393
394 *octets = kmalloc(eoc - ctx->pointer, GFP_ATOMIC);
395 if (*octets == NULL) {
396 if (net_ratelimit())
397 printk("OOM in bsalg (%d)\n", __LINE__);
398 return 0;
399 }
400
401 ptr = *octets;
402 while (ctx->pointer < eoc) {
403 if (!asn1_octet_decode(ctx, (unsigned char *)ptr++)) {
404 kfree(*octets);
405 *octets = NULL;
406 return 0;
407 }
408 (*len)++;
409 }
410 return 1;
411}
412
413static unsigned char asn1_subid_decode(struct asn1_ctx *ctx,
414 unsigned long *subid)
415{
416 unsigned char ch;
417
418 *subid = 0;
419
420 do {
421 if (!asn1_octet_decode(ctx, &ch))
422 return 0;
423
424 *subid <<= 7;
425 *subid |= ch & 0x7F;
426 } while ((ch & 0x80) == 0x80);
427 return 1;
428}
429
430static unsigned char asn1_oid_decode(struct asn1_ctx *ctx,
431 unsigned char *eoc,
432 unsigned long **oid,
433 unsigned int *len)
434{
435 unsigned long subid;
436 unsigned int size;
437 unsigned long *optr;
438
439 size = eoc - ctx->pointer + 1;
440 *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC);
441 if (*oid == NULL) {
442 if (net_ratelimit())
443 printk("OOM in bsalg (%d)\n", __LINE__);
444 return 0;
445 }
446
447 optr = *oid;
448
449 if (!asn1_subid_decode(ctx, &subid)) {
450 kfree(*oid);
451 *oid = NULL;
452 return 0;
453 }
454
455 if (subid < 40) {
456 optr [0] = 0;
457 optr [1] = subid;
458 } else if (subid < 80) {
459 optr [0] = 1;
460 optr [1] = subid - 40;
461 } else {
462 optr [0] = 2;
463 optr [1] = subid - 80;
464 }
465
466 *len = 2;
467 optr += 2;
468
469 while (ctx->pointer < eoc) {
470 if (++(*len) > size) {
471 ctx->error = ASN1_ERR_DEC_BADVALUE;
472 kfree(*oid);
473 *oid = NULL;
474 return 0;
475 }
476
477 if (!asn1_subid_decode(ctx, optr++)) {
478 kfree(*oid);
479 *oid = NULL;
480 return 0;
481 }
482 }
483 return 1;
484}
485
486/*****************************************************************************
487 *
488 * SNMP decoding routines (gxsnmp author Dirk Wisse)
489 *
490 *****************************************************************************/
491
492/* SNMP Versions */
493#define SNMP_V1 0
494#define SNMP_V2C 1
495#define SNMP_V2 2
496#define SNMP_V3 3
497
498/* Default Sizes */
499#define SNMP_SIZE_COMM 256
500#define SNMP_SIZE_OBJECTID 128
501#define SNMP_SIZE_BUFCHR 256
502#define SNMP_SIZE_BUFINT 128
503#define SNMP_SIZE_SMALLOBJECTID 16
504
505/* Requests */
506#define SNMP_PDU_GET 0
507#define SNMP_PDU_NEXT 1
508#define SNMP_PDU_RESPONSE 2
509#define SNMP_PDU_SET 3
510#define SNMP_PDU_TRAP1 4
511#define SNMP_PDU_BULK 5
512#define SNMP_PDU_INFORM 6
513#define SNMP_PDU_TRAP2 7
514
515/* Errors */
516#define SNMP_NOERROR 0
517#define SNMP_TOOBIG 1
518#define SNMP_NOSUCHNAME 2
519#define SNMP_BADVALUE 3
520#define SNMP_READONLY 4
521#define SNMP_GENERROR 5
522#define SNMP_NOACCESS 6
523#define SNMP_WRONGTYPE 7
524#define SNMP_WRONGLENGTH 8
525#define SNMP_WRONGENCODING 9
526#define SNMP_WRONGVALUE 10
527#define SNMP_NOCREATION 11
528#define SNMP_INCONSISTENTVALUE 12
529#define SNMP_RESOURCEUNAVAILABLE 13
530#define SNMP_COMMITFAILED 14
531#define SNMP_UNDOFAILED 15
532#define SNMP_AUTHORIZATIONERROR 16
533#define SNMP_NOTWRITABLE 17
534#define SNMP_INCONSISTENTNAME 18
535
536/* General SNMP V1 Traps */
537#define SNMP_TRAP_COLDSTART 0
538#define SNMP_TRAP_WARMSTART 1
539#define SNMP_TRAP_LINKDOWN 2
540#define SNMP_TRAP_LINKUP 3
541#define SNMP_TRAP_AUTFAILURE 4
542#define SNMP_TRAP_EQPNEIGHBORLOSS 5
543#define SNMP_TRAP_ENTSPECIFIC 6
544
545/* SNMPv1 Types */
546#define SNMP_NULL 0
547#define SNMP_INTEGER 1 /* l */
548#define SNMP_OCTETSTR 2 /* c */
549#define SNMP_DISPLAYSTR 2 /* c */
550#define SNMP_OBJECTID 3 /* ul */
551#define SNMP_IPADDR 4 /* uc */
552#define SNMP_COUNTER 5 /* ul */
553#define SNMP_GAUGE 6 /* ul */
554#define SNMP_TIMETICKS 7 /* ul */
555#define SNMP_OPAQUE 8 /* c */
556
557/* Additional SNMPv2 Types */
558#define SNMP_UINTEGER 5 /* ul */
559#define SNMP_BITSTR 9 /* uc */
560#define SNMP_NSAP 10 /* uc */
561#define SNMP_COUNTER64 11 /* ul */
562#define SNMP_NOSUCHOBJECT 12
563#define SNMP_NOSUCHINSTANCE 13
564#define SNMP_ENDOFMIBVIEW 14
565
566union snmp_syntax
567{
568 unsigned char uc[0]; /* 8 bit unsigned */
569 char c[0]; /* 8 bit signed */
570 unsigned long ul[0]; /* 32 bit unsigned */
571 long l[0]; /* 32 bit signed */
572};
573
574struct snmp_object
575{
576 unsigned long *id;
577 unsigned int id_len;
578 unsigned short type;
579 unsigned int syntax_len;
580 union snmp_syntax syntax;
581};
582
583struct snmp_request
584{
585 unsigned long id;
586 unsigned int error_status;
587 unsigned int error_index;
588};
589
590struct snmp_v1_trap
591{
592 unsigned long *id;
593 unsigned int id_len;
594 unsigned long ip_address; /* pointer */
595 unsigned int general;
596 unsigned int specific;
597 unsigned long time;
598};
599
600/* SNMP types */
601#define SNMP_IPA 0
602#define SNMP_CNT 1
603#define SNMP_GGE 2
604#define SNMP_TIT 3
605#define SNMP_OPQ 4
606#define SNMP_C64 6
607
608/* SNMP errors */
609#define SERR_NSO 0
610#define SERR_NSI 1
611#define SERR_EOM 2
612
613static inline void mangle_address(unsigned char *begin,
614 unsigned char *addr,
615 const struct oct1_map *map,
616 __sum16 *check);
617struct snmp_cnv
618{
619 unsigned int class;
620 unsigned int tag;
621 int syntax;
622};
623
624static struct snmp_cnv snmp_conv [] =
625{
626 {ASN1_UNI, ASN1_NUL, SNMP_NULL},
627 {ASN1_UNI, ASN1_INT, SNMP_INTEGER},
628 {ASN1_UNI, ASN1_OTS, SNMP_OCTETSTR},
629 {ASN1_UNI, ASN1_OTS, SNMP_DISPLAYSTR},
630 {ASN1_UNI, ASN1_OJI, SNMP_OBJECTID},
631 {ASN1_APL, SNMP_IPA, SNMP_IPADDR},
632 {ASN1_APL, SNMP_CNT, SNMP_COUNTER}, /* Counter32 */
633 {ASN1_APL, SNMP_GGE, SNMP_GAUGE}, /* Gauge32 == Unsigned32 */
634 {ASN1_APL, SNMP_TIT, SNMP_TIMETICKS},
635 {ASN1_APL, SNMP_OPQ, SNMP_OPAQUE},
636
637 /* SNMPv2 data types and errors */
638 {ASN1_UNI, ASN1_BTS, SNMP_BITSTR},
639 {ASN1_APL, SNMP_C64, SNMP_COUNTER64},
640 {ASN1_CTX, SERR_NSO, SNMP_NOSUCHOBJECT},
641 {ASN1_CTX, SERR_NSI, SNMP_NOSUCHINSTANCE},
642 {ASN1_CTX, SERR_EOM, SNMP_ENDOFMIBVIEW},
643 {0, 0, -1}
644};
645
646static unsigned char snmp_tag_cls2syntax(unsigned int tag,
647 unsigned int cls,
648 unsigned short *syntax)
649{
650 struct snmp_cnv *cnv;
651
652 cnv = snmp_conv;
653
654 while (cnv->syntax != -1) {
655 if (cnv->tag == tag && cnv->class == cls) {
656 *syntax = cnv->syntax;
657 return 1;
658 }
659 cnv++;
660 }
661 return 0;
662}
663
664static unsigned char snmp_object_decode(struct asn1_ctx *ctx,
665 struct snmp_object **obj)
666{
667 unsigned int cls, con, tag, len, idlen;
668 unsigned short type;
669 unsigned char *eoc, *end, *p;
670 unsigned long *lp, *id;
671 unsigned long ul;
672 long l;
673
674 *obj = NULL;
675 id = NULL;
676
677 if (!asn1_header_decode(ctx, &eoc, &cls, &con, &tag))
678 return 0;
679
680 if (cls != ASN1_UNI || con != ASN1_CON || tag != ASN1_SEQ)
681 return 0;
682
683 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
684 return 0;
685
686 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_OJI)
687 return 0;
688
689 if (!asn1_oid_decode(ctx, end, &id, &idlen))
690 return 0;
691
692 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag)) {
693 kfree(id);
694 return 0;
695 }
696
697 if (con != ASN1_PRI) {
698 kfree(id);
699 return 0;
700 }
701
702 type = 0;
703 if (!snmp_tag_cls2syntax(tag, cls, &type)) {
704 kfree(id);
705 return 0;
706 }
707
708 l = 0;
709 switch (type) {
710 case SNMP_INTEGER:
711 len = sizeof(long);
712 if (!asn1_long_decode(ctx, end, &l)) {
713 kfree(id);
714 return 0;
715 }
716 *obj = kmalloc(sizeof(struct snmp_object) + len,
717 GFP_ATOMIC);
718 if (*obj == NULL) {
719 kfree(id);
720 if (net_ratelimit())
721 printk("OOM in bsalg (%d)\n", __LINE__);
722 return 0;
723 }
724 (*obj)->syntax.l[0] = l;
725 break;
726 case SNMP_OCTETSTR:
727 case SNMP_OPAQUE:
728 if (!asn1_octets_decode(ctx, end, &p, &len)) {
729 kfree(id);
730 return 0;
731 }
732 *obj = kmalloc(sizeof(struct snmp_object) + len,
733 GFP_ATOMIC);
734 if (*obj == NULL) {
735 kfree(id);
736 if (net_ratelimit())
737 printk("OOM in bsalg (%d)\n", __LINE__);
738 return 0;
739 }
740 memcpy((*obj)->syntax.c, p, len);
741 kfree(p);
742 break;
743 case SNMP_NULL:
744 case SNMP_NOSUCHOBJECT:
745 case SNMP_NOSUCHINSTANCE:
746 case SNMP_ENDOFMIBVIEW:
747 len = 0;
748 *obj = kmalloc(sizeof(struct snmp_object), GFP_ATOMIC);
749 if (*obj == NULL) {
750 kfree(id);
751 if (net_ratelimit())
752 printk("OOM in bsalg (%d)\n", __LINE__);
753 return 0;
754 }
755 if (!asn1_null_decode(ctx, end)) {
756 kfree(id);
757 kfree(*obj);
758 *obj = NULL;
759 return 0;
760 }
761 break;
762 case SNMP_OBJECTID:
763 if (!asn1_oid_decode(ctx, end, (unsigned long **)&lp, &len)) {
764 kfree(id);
765 return 0;
766 }
767 len *= sizeof(unsigned long);
768 *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC);
769 if (*obj == NULL) {
770 kfree(lp);
771 kfree(id);
772 if (net_ratelimit())
773 printk("OOM in bsalg (%d)\n", __LINE__);
774 return 0;
775 }
776 memcpy((*obj)->syntax.ul, lp, len);
777 kfree(lp);
778 break;
779 case SNMP_IPADDR:
780 if (!asn1_octets_decode(ctx, end, &p, &len)) {
781 kfree(id);
782 return 0;
783 }
784 if (len != 4) {
785 kfree(p);
786 kfree(id);
787 return 0;
788 }
789 *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC);
790 if (*obj == NULL) {
791 kfree(p);
792 kfree(id);
793 if (net_ratelimit())
794 printk("OOM in bsalg (%d)\n", __LINE__);
795 return 0;
796 }
797 memcpy((*obj)->syntax.uc, p, len);
798 kfree(p);
799 break;
800 case SNMP_COUNTER:
801 case SNMP_GAUGE:
802 case SNMP_TIMETICKS:
803 len = sizeof(unsigned long);
804 if (!asn1_ulong_decode(ctx, end, &ul)) {
805 kfree(id);
806 return 0;
807 }
808 *obj = kmalloc(sizeof(struct snmp_object) + len, GFP_ATOMIC);
809 if (*obj == NULL) {
810 kfree(id);
811 if (net_ratelimit())
812 printk("OOM in bsalg (%d)\n", __LINE__);
813 return 0;
814 }
815 (*obj)->syntax.ul[0] = ul;
816 break;
817 default:
818 kfree(id);
819 return 0;
820 }
821
822 (*obj)->syntax_len = len;
823 (*obj)->type = type;
824 (*obj)->id = id;
825 (*obj)->id_len = idlen;
826
827 if (!asn1_eoc_decode(ctx, eoc)) {
828 kfree(id);
829 kfree(*obj);
830 *obj = NULL;
831 return 0;
832 }
833 return 1;
834}
835
836static unsigned char snmp_request_decode(struct asn1_ctx *ctx,
837 struct snmp_request *request)
838{
839 unsigned int cls, con, tag;
840 unsigned char *end;
841
842 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
843 return 0;
844
845 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT)
846 return 0;
847
848 if (!asn1_ulong_decode(ctx, end, &request->id))
849 return 0;
850
851 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
852 return 0;
853
854 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT)
855 return 0;
856
857 if (!asn1_uint_decode(ctx, end, &request->error_status))
858 return 0;
859
860 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
861 return 0;
862
863 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT)
864 return 0;
865
866 if (!asn1_uint_decode(ctx, end, &request->error_index))
867 return 0;
868
869 return 1;
870}
871
872/*
873 * Fast checksum update for possibly oddly-aligned UDP byte, from the
874 * code example in the draft.
875 */
876static void fast_csum(__sum16 *csum,
877 const unsigned char *optr,
878 const unsigned char *nptr,
879 int offset)
880{
881 unsigned char s[4];
882
883 if (offset & 1) {
884 s[0] = s[2] = 0;
885 s[1] = ~*optr;
886 s[3] = *nptr;
887 } else {
888 s[1] = s[3] = 0;
889 s[0] = ~*optr;
890 s[2] = *nptr;
891 }
892
893 *csum = csum_fold(csum_partial(s, 4, ~csum_unfold(*csum)));
894}
895
896/*
897 * Mangle IP address.
898 * - begin points to the start of the snmp messgae
899 * - addr points to the start of the address
900 */
901static inline void mangle_address(unsigned char *begin,
902 unsigned char *addr,
903 const struct oct1_map *map,
904 __sum16 *check)
905{
906 if (map->from == NOCT1(addr)) {
907 u_int32_t old;
908
909 if (debug)
910 memcpy(&old, (unsigned char *)addr, sizeof(old));
911
912 *addr = map->to;
913
914 /* Update UDP checksum if being used */
915 if (*check) {
916 fast_csum(check,
917 &map->from, &map->to, addr - begin);
918
919 }
920
921 if (debug)
922 printk(KERN_DEBUG "bsalg: mapped %u.%u.%u.%u to "
923 "%u.%u.%u.%u\n", NIPQUAD(old), NIPQUAD(*addr));
924 }
925}
926
927static unsigned char snmp_trap_decode(struct asn1_ctx *ctx,
928 struct snmp_v1_trap *trap,
929 const struct oct1_map *map,
930 __sum16 *check)
931{
932 unsigned int cls, con, tag, len;
933 unsigned char *end;
934
935 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
936 return 0;
937
938 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_OJI)
939 return 0;
940
941 if (!asn1_oid_decode(ctx, end, &trap->id, &trap->id_len))
942 return 0;
943
944 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
945 goto err_id_free;
946
947 if (!((cls == ASN1_APL && con == ASN1_PRI && tag == SNMP_IPA) ||
948 (cls == ASN1_UNI && con == ASN1_PRI && tag == ASN1_OTS)))
949 goto err_id_free;
950
951 if (!asn1_octets_decode(ctx, end, (unsigned char **)&trap->ip_address, &len))
952 goto err_id_free;
953
954 /* IPv4 only */
955 if (len != 4)
956 goto err_addr_free;
957
958 mangle_address(ctx->begin, ctx->pointer - 4, map, check);
959
960 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
961 goto err_addr_free;
962
963 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT)
964 goto err_addr_free;
965
966 if (!asn1_uint_decode(ctx, end, &trap->general))
967 goto err_addr_free;
968
969 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
970 goto err_addr_free;
971
972 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT)
973 goto err_addr_free;
974
975 if (!asn1_uint_decode(ctx, end, &trap->specific))
976 goto err_addr_free;
977
978 if (!asn1_header_decode(ctx, &end, &cls, &con, &tag))
979 goto err_addr_free;
980
981 if (!((cls == ASN1_APL && con == ASN1_PRI && tag == SNMP_TIT) ||
982 (cls == ASN1_UNI && con == ASN1_PRI && tag == ASN1_INT)))
983 goto err_addr_free;
984
985 if (!asn1_ulong_decode(ctx, end, &trap->time))
986 goto err_addr_free;
987
988 return 1;
989
990err_addr_free:
991 kfree((unsigned long *)trap->ip_address);
992
993err_id_free:
994 kfree(trap->id);
995
996 return 0;
997}
998
999/*****************************************************************************
1000 *
1001 * Misc. routines
1002 *
1003 *****************************************************************************/
1004
1005static void hex_dump(unsigned char *buf, size_t len)
1006{
1007 size_t i;
1008
1009 for (i = 0; i < len; i++) {
1010 if (i && !(i % 16))
1011 printk("\n");
1012 printk("%02x ", *(buf + i));
1013 }
1014 printk("\n");
1015}
1016
1017/*
1018 * Parse and mangle SNMP message according to mapping.
1019 * (And this is the fucking 'basic' method).
1020 */
1021static int snmp_parse_mangle(unsigned char *msg,
1022 u_int16_t len,
1023 const struct oct1_map *map,
1024 __sum16 *check)
1025{
1026 unsigned char *eoc, *end;
1027 unsigned int cls, con, tag, vers, pdutype;
1028 struct asn1_ctx ctx;
1029 struct asn1_octstr comm;
1030 struct snmp_object **obj;
1031
1032 if (debug > 1)
1033 hex_dump(msg, len);
1034
1035 asn1_open(&ctx, msg, len);
1036
1037 /*
1038 * Start of SNMP message.
1039 */
1040 if (!asn1_header_decode(&ctx, &eoc, &cls, &con, &tag))
1041 return 0;
1042 if (cls != ASN1_UNI || con != ASN1_CON || tag != ASN1_SEQ)
1043 return 0;
1044
1045 /*
1046 * Version 1 or 2 handled.
1047 */
1048 if (!asn1_header_decode(&ctx, &end, &cls, &con, &tag))
1049 return 0;
1050 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_INT)
1051 return 0;
1052 if (!asn1_uint_decode (&ctx, end, &vers))
1053 return 0;
1054 if (debug > 1)
1055 printk(KERN_DEBUG "bsalg: snmp version: %u\n", vers + 1);
1056 if (vers > 1)
1057 return 1;
1058
1059 /*
1060 * Community.
1061 */
1062 if (!asn1_header_decode (&ctx, &end, &cls, &con, &tag))
1063 return 0;
1064 if (cls != ASN1_UNI || con != ASN1_PRI || tag != ASN1_OTS)
1065 return 0;
1066 if (!asn1_octets_decode(&ctx, end, &comm.data, &comm.len))
1067 return 0;
1068 if (debug > 1) {
1069 unsigned int i;
1070
1071 printk(KERN_DEBUG "bsalg: community: ");
1072 for (i = 0; i < comm.len; i++)
1073 printk("%c", comm.data[i]);
1074 printk("\n");
1075 }
1076 kfree(comm.data);
1077
1078 /*
1079 * PDU type
1080 */
1081 if (!asn1_header_decode(&ctx, &eoc, &cls, &con, &pdutype))
1082 return 0;
1083 if (cls != ASN1_CTX || con != ASN1_CON)
1084 return 0;
1085 if (debug > 1) {
1086 unsigned char *pdus[] = {
1087 [SNMP_PDU_GET] = "get",
1088 [SNMP_PDU_NEXT] = "get-next",
1089 [SNMP_PDU_RESPONSE] = "response",
1090 [SNMP_PDU_SET] = "set",
1091 [SNMP_PDU_TRAP1] = "trapv1",
1092 [SNMP_PDU_BULK] = "bulk",
1093 [SNMP_PDU_INFORM] = "inform",
1094 [SNMP_PDU_TRAP2] = "trapv2"
1095 };
1096
1097 if (pdutype > SNMP_PDU_TRAP2)
1098 printk(KERN_DEBUG "bsalg: bad pdu type %u\n", pdutype);
1099 else
1100 printk(KERN_DEBUG "bsalg: pdu: %s\n", pdus[pdutype]);
1101 }
1102 if (pdutype != SNMP_PDU_RESPONSE &&
1103 pdutype != SNMP_PDU_TRAP1 && pdutype != SNMP_PDU_TRAP2)
1104 return 1;
1105
1106 /*
1107 * Request header or v1 trap
1108 */
1109 if (pdutype == SNMP_PDU_TRAP1) {
1110 struct snmp_v1_trap trap;
1111 unsigned char ret = snmp_trap_decode(&ctx, &trap, map, check);
1112
1113 if (ret) {
1114 kfree(trap.id);
1115 kfree((unsigned long *)trap.ip_address);
1116 } else
1117 return ret;
1118
1119 } else {
1120 struct snmp_request req;
1121
1122 if (!snmp_request_decode(&ctx, &req))
1123 return 0;
1124
1125 if (debug > 1)
1126 printk(KERN_DEBUG "bsalg: request: id=0x%lx error_status=%u "
1127 "error_index=%u\n", req.id, req.error_status,
1128 req.error_index);
1129 }
1130
1131 /*
1132 * Loop through objects, look for IP addresses to mangle.
1133 */
1134 if (!asn1_header_decode(&ctx, &eoc, &cls, &con, &tag))
1135 return 0;
1136
1137 if (cls != ASN1_UNI || con != ASN1_CON || tag != ASN1_SEQ)
1138 return 0;
1139
1140 obj = kmalloc(sizeof(struct snmp_object), GFP_ATOMIC);
1141 if (obj == NULL) {
1142 if (net_ratelimit())
1143 printk(KERN_WARNING "OOM in bsalg(%d)\n", __LINE__);
1144 return 0;
1145 }
1146
1147 while (!asn1_eoc_decode(&ctx, eoc)) {
1148 unsigned int i;
1149
1150 if (!snmp_object_decode(&ctx, obj)) {
1151 if (*obj) {
1152 kfree((*obj)->id);
1153 kfree(*obj);
1154 }
1155 kfree(obj);
1156 return 0;
1157 }
1158
1159 if (debug > 1) {
1160 printk(KERN_DEBUG "bsalg: object: ");
1161 for (i = 0; i < (*obj)->id_len; i++) {
1162 if (i > 0)
1163 printk(".");
1164 printk("%lu", (*obj)->id[i]);
1165 }
1166 printk(": type=%u\n", (*obj)->type);
1167
1168 }
1169
1170 if ((*obj)->type == SNMP_IPADDR)
1171 mangle_address(ctx.begin, ctx.pointer - 4 , map, check);
1172
1173 kfree((*obj)->id);
1174 kfree(*obj);
1175 }
1176 kfree(obj);
1177
1178 if (!asn1_eoc_decode(&ctx, eoc))
1179 return 0;
1180
1181 return 1;
1182}
1183
1184/*****************************************************************************
1185 *
1186 * NAT routines.
1187 *
1188 *****************************************************************************/
1189
1190/*
1191 * SNMP translation routine.
1192 */
1193static int snmp_translate(struct nf_conn *ct,
1194 enum ip_conntrack_info ctinfo,
1195 struct sk_buff **pskb)
1196{
1197 struct iphdr *iph = (*pskb)->nh.iph;
1198 struct udphdr *udph = (struct udphdr *)((__be32 *)iph + iph->ihl);
1199 u_int16_t udplen = ntohs(udph->len);
1200 u_int16_t paylen = udplen - sizeof(struct udphdr);
1201 int dir = CTINFO2DIR(ctinfo);
1202 struct oct1_map map;
1203
1204 /*
1205 * Determine mappping for application layer addresses based
1206 * on NAT manipulations for the packet.
1207 */
1208 if (dir == IP_CT_DIR_ORIGINAL) {
1209 /* SNAT traps */
1210 map.from = NOCT1(&ct->tuplehash[dir].tuple.src.u3.ip);
1211 map.to = NOCT1(&ct->tuplehash[!dir].tuple.dst.u3.ip);
1212 } else {
1213 /* DNAT replies */
1214 map.from = NOCT1(&ct->tuplehash[dir].tuple.src.u3.ip);
1215 map.to = NOCT1(&ct->tuplehash[!dir].tuple.dst.u3.ip);
1216 }
1217
1218 if (map.from == map.to)
1219 return NF_ACCEPT;
1220
1221 if (!snmp_parse_mangle((unsigned char *)udph + sizeof(struct udphdr),
1222 paylen, &map, &udph->check)) {
1223 if (net_ratelimit())
1224 printk(KERN_WARNING "bsalg: parser failed\n");
1225 return NF_DROP;
1226 }
1227 return NF_ACCEPT;
1228}
1229
1230/* We don't actually set up expectations, just adjust internal IP
1231 * addresses if this is being NATted */
1232static int help(struct sk_buff **pskb, unsigned int protoff,
1233 struct nf_conn *ct,
1234 enum ip_conntrack_info ctinfo)
1235{
1236 int dir = CTINFO2DIR(ctinfo);
1237 unsigned int ret;
1238 struct iphdr *iph = (*pskb)->nh.iph;
1239 struct udphdr *udph = (struct udphdr *)((u_int32_t *)iph + iph->ihl);
1240
1241 /* SNMP replies and originating SNMP traps get mangled */
1242 if (udph->source == htons(SNMP_PORT) && dir != IP_CT_DIR_REPLY)
1243 return NF_ACCEPT;
1244 if (udph->dest == htons(SNMP_TRAP_PORT) && dir != IP_CT_DIR_ORIGINAL)
1245 return NF_ACCEPT;
1246
1247 /* No NAT? */
1248 if (!(ct->status & IPS_NAT_MASK))
1249 return NF_ACCEPT;
1250
1251 /*
1252 * Make sure the packet length is ok. So far, we were only guaranteed
1253 * to have a valid length IP header plus 8 bytes, which means we have
1254 * enough room for a UDP header. Just verify the UDP length field so we
1255 * can mess around with the payload.
1256 */
1257 if (ntohs(udph->len) != (*pskb)->len - (iph->ihl << 2)) {
1258 if (net_ratelimit())
1259 printk(KERN_WARNING "SNMP: dropping malformed packet "
1260 "src=%u.%u.%u.%u dst=%u.%u.%u.%u\n",
1261 NIPQUAD(iph->saddr), NIPQUAD(iph->daddr));
1262 return NF_DROP;
1263 }
1264
1265 if (!skb_make_writable(pskb, (*pskb)->len))
1266 return NF_DROP;
1267
1268 spin_lock_bh(&snmp_lock);
1269 ret = snmp_translate(ct, ctinfo, pskb);
1270 spin_unlock_bh(&snmp_lock);
1271 return ret;
1272}
1273
1274static struct nf_conntrack_helper snmp_helper __read_mostly = {
1275 .max_expected = 0,
1276 .timeout = 180,
1277 .me = THIS_MODULE,
1278 .help = help,
1279 .name = "snmp",
1280 .tuple.src.l3num = AF_INET,
1281 .tuple.src.u.udp.port = __constant_htons(SNMP_PORT),
1282 .tuple.dst.protonum = IPPROTO_UDP,
1283 .mask.src.l3num = 0xFFFF,
1284 .mask.src.u.udp.port = __constant_htons(0xFFFF),
1285 .mask.dst.protonum = 0xFF,
1286};
1287
1288static struct nf_conntrack_helper snmp_trap_helper __read_mostly = {
1289 .max_expected = 0,
1290 .timeout = 180,
1291 .me = THIS_MODULE,
1292 .help = help,
1293 .name = "snmp_trap",
1294 .tuple.src.l3num = AF_INET,
1295 .tuple.src.u.udp.port = __constant_htons(SNMP_TRAP_PORT),
1296 .tuple.dst.protonum = IPPROTO_UDP,
1297 .mask.src.l3num = 0xFFFF,
1298 .mask.src.u.udp.port = __constant_htons(0xFFFF),
1299 .mask.dst.protonum = 0xFF,
1300};
1301
1302/*****************************************************************************
1303 *
1304 * Module stuff.
1305 *
1306 *****************************************************************************/
1307
1308static int __init nf_nat_snmp_basic_init(void)
1309{
1310 int ret = 0;
1311
1312 ret = nf_conntrack_helper_register(&snmp_helper);
1313 if (ret < 0)
1314 return ret;
1315 ret = nf_conntrack_helper_register(&snmp_trap_helper);
1316 if (ret < 0) {
1317 nf_conntrack_helper_unregister(&snmp_helper);
1318 return ret;
1319 }
1320 return ret;
1321}
1322
1323static void __exit nf_nat_snmp_basic_fini(void)
1324{
1325 nf_conntrack_helper_unregister(&snmp_helper);
1326 nf_conntrack_helper_unregister(&snmp_trap_helper);
1327}
1328
1329module_init(nf_nat_snmp_basic_init);
1330module_exit(nf_nat_snmp_basic_fini);
1331
1332module_param(debug, int, 0600);
diff --git a/net/ipv4/netfilter/nf_nat_standalone.c b/net/ipv4/netfilter/nf_nat_standalone.c
new file mode 100644
index 0000000000..00d6dea9f7
--- /dev/null
+++ b/net/ipv4/netfilter/nf_nat_standalone.c
@@ -0,0 +1,406 @@
1/* (C) 1999-2001 Paul `Rusty' Russell
2 * (C) 2002-2006 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#include <linux/types.h>
9#include <linux/icmp.h>
10#include <linux/ip.h>
11#include <linux/netfilter.h>
12#include <linux/netfilter_ipv4.h>
13#include <linux/module.h>
14#include <linux/skbuff.h>
15#include <linux/proc_fs.h>
16#include <net/ip.h>
17#include <net/checksum.h>
18#include <linux/spinlock.h>
19
20#include <net/netfilter/nf_conntrack.h>
21#include <net/netfilter/nf_conntrack_core.h>
22#include <net/netfilter/nf_nat.h>
23#include <net/netfilter/nf_nat_rule.h>
24#include <net/netfilter/nf_nat_protocol.h>
25#include <net/netfilter/nf_nat_core.h>
26#include <net/netfilter/nf_nat_helper.h>
27#include <linux/netfilter_ipv4/ip_tables.h>
28
29#if 0
30#define DEBUGP printk
31#else
32#define DEBUGP(format, args...)
33#endif
34
35#define HOOKNAME(hooknum) ((hooknum) == NF_IP_POST_ROUTING ? "POST_ROUTING" \
36 : ((hooknum) == NF_IP_PRE_ROUTING ? "PRE_ROUTING" \
37 : ((hooknum) == NF_IP_LOCAL_OUT ? "LOCAL_OUT" \
38 : ((hooknum) == NF_IP_LOCAL_IN ? "LOCAL_IN" \
39 : "*ERROR*")))
40
41#ifdef CONFIG_XFRM
42static void nat_decode_session(struct sk_buff *skb, struct flowi *fl)
43{
44 struct nf_conn *ct;
45 struct nf_conntrack_tuple *t;
46 enum ip_conntrack_info ctinfo;
47 enum ip_conntrack_dir dir;
48 unsigned long statusbit;
49
50 ct = nf_ct_get(skb, &ctinfo);
51 if (ct == NULL)
52 return;
53 dir = CTINFO2DIR(ctinfo);
54 t = &ct->tuplehash[dir].tuple;
55
56 if (dir == IP_CT_DIR_ORIGINAL)
57 statusbit = IPS_DST_NAT;
58 else
59 statusbit = IPS_SRC_NAT;
60
61 if (ct->status & statusbit) {
62 fl->fl4_dst = t->dst.u3.ip;
63 if (t->dst.protonum == IPPROTO_TCP ||
64 t->dst.protonum == IPPROTO_UDP)
65 fl->fl_ip_dport = t->dst.u.tcp.port;
66 }
67
68 statusbit ^= IPS_NAT_MASK;
69
70 if (ct->status & statusbit) {
71 fl->fl4_src = t->src.u3.ip;
72 if (t->dst.protonum == IPPROTO_TCP ||
73 t->dst.protonum == IPPROTO_UDP)
74 fl->fl_ip_sport = t->src.u.tcp.port;
75 }
76}
77#endif
78
79static unsigned int
80nf_nat_fn(unsigned int hooknum,
81 struct sk_buff **pskb,
82 const struct net_device *in,
83 const struct net_device *out,
84 int (*okfn)(struct sk_buff *))
85{
86 struct nf_conn *ct;
87 enum ip_conntrack_info ctinfo;
88 struct nf_conn_nat *nat;
89 struct nf_nat_info *info;
90 /* maniptype == SRC for postrouting. */
91 enum nf_nat_manip_type maniptype = HOOK2MANIP(hooknum);
92
93 /* We never see fragments: conntrack defrags on pre-routing
94 and local-out, and nf_nat_out protects post-routing. */
95 NF_CT_ASSERT(!((*pskb)->nh.iph->frag_off
96 & htons(IP_MF|IP_OFFSET)));
97
98 ct = nf_ct_get(*pskb, &ctinfo);
99 /* Can't track? It's not due to stress, or conntrack would
100 have dropped it. Hence it's the user's responsibilty to
101 packet filter it out, or implement conntrack/NAT for that
102 protocol. 8) --RR */
103 if (!ct) {
104 /* Exception: ICMP redirect to new connection (not in
105 hash table yet). We must not let this through, in
106 case we're doing NAT to the same network. */
107 if ((*pskb)->nh.iph->protocol == IPPROTO_ICMP) {
108 struct icmphdr _hdr, *hp;
109
110 hp = skb_header_pointer(*pskb,
111 (*pskb)->nh.iph->ihl*4,
112 sizeof(_hdr), &_hdr);
113 if (hp != NULL &&
114 hp->type == ICMP_REDIRECT)
115 return NF_DROP;
116 }
117 return NF_ACCEPT;
118 }
119
120 /* Don't try to NAT if this packet is not conntracked */
121 if (ct == &nf_conntrack_untracked)
122 return NF_ACCEPT;
123
124 nat = nfct_nat(ct);
125 if (!nat)
126 return NF_ACCEPT;
127
128 switch (ctinfo) {
129 case IP_CT_RELATED:
130 case IP_CT_RELATED+IP_CT_IS_REPLY:
131 if ((*pskb)->nh.iph->protocol == IPPROTO_ICMP) {
132 if (!nf_nat_icmp_reply_translation(ct, ctinfo,
133 hooknum, pskb))
134 return NF_DROP;
135 else
136 return NF_ACCEPT;
137 }
138 /* Fall thru... (Only ICMPs can be IP_CT_IS_REPLY) */
139 case IP_CT_NEW:
140 info = &nat->info;
141
142 /* Seen it before? This can happen for loopback, retrans,
143 or local packets.. */
144 if (!nf_nat_initialized(ct, maniptype)) {
145 unsigned int ret;
146
147 if (unlikely(nf_ct_is_confirmed(ct)))
148 /* NAT module was loaded late */
149 ret = alloc_null_binding_confirmed(ct, info,
150 hooknum);
151 else if (hooknum == NF_IP_LOCAL_IN)
152 /* LOCAL_IN hook doesn't have a chain! */
153 ret = alloc_null_binding(ct, info, hooknum);
154 else
155 ret = nf_nat_rule_find(pskb, hooknum, in, out,
156 ct, info);
157
158 if (ret != NF_ACCEPT) {
159 return ret;
160 }
161 } else
162 DEBUGP("Already setup manip %s for ct %p\n",
163 maniptype == IP_NAT_MANIP_SRC ? "SRC" : "DST",
164 ct);
165 break;
166
167 default:
168 /* ESTABLISHED */
169 NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED ||
170 ctinfo == (IP_CT_ESTABLISHED+IP_CT_IS_REPLY));
171 info = &nat->info;
172 }
173
174 NF_CT_ASSERT(info);
175 return nf_nat_packet(ct, ctinfo, hooknum, pskb);
176}
177
178static unsigned int
179nf_nat_in(unsigned int hooknum,
180 struct sk_buff **pskb,
181 const struct net_device *in,
182 const struct net_device *out,
183 int (*okfn)(struct sk_buff *))
184{
185 unsigned int ret;
186 __be32 daddr = (*pskb)->nh.iph->daddr;
187
188 ret = nf_nat_fn(hooknum, pskb, in, out, okfn);
189 if (ret != NF_DROP && ret != NF_STOLEN &&
190 daddr != (*pskb)->nh.iph->daddr) {
191 dst_release((*pskb)->dst);
192 (*pskb)->dst = NULL;
193 }
194 return ret;
195}
196
197static unsigned int
198nf_nat_out(unsigned int hooknum,
199 struct sk_buff **pskb,
200 const struct net_device *in,
201 const struct net_device *out,
202 int (*okfn)(struct sk_buff *))
203{
204#ifdef CONFIG_XFRM
205 struct nf_conn *ct;
206 enum ip_conntrack_info ctinfo;
207#endif
208 unsigned int ret;
209
210 /* root is playing with raw sockets. */
211 if ((*pskb)->len < sizeof(struct iphdr) ||
212 (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
213 return NF_ACCEPT;
214
215 ret = nf_nat_fn(hooknum, pskb, in, out, okfn);
216#ifdef CONFIG_XFRM
217 if (ret != NF_DROP && ret != NF_STOLEN &&
218 (ct = nf_ct_get(*pskb, &ctinfo)) != NULL) {
219 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
220
221 if (ct->tuplehash[dir].tuple.src.u3.ip !=
222 ct->tuplehash[!dir].tuple.dst.u3.ip
223 || ct->tuplehash[dir].tuple.src.u.all !=
224 ct->tuplehash[!dir].tuple.dst.u.all
225 )
226 return ip_xfrm_me_harder(pskb) == 0 ? ret : NF_DROP;
227 }
228#endif
229 return ret;
230}
231
232static unsigned int
233nf_nat_local_fn(unsigned int hooknum,
234 struct sk_buff **pskb,
235 const struct net_device *in,
236 const struct net_device *out,
237 int (*okfn)(struct sk_buff *))
238{
239 struct nf_conn *ct;
240 enum ip_conntrack_info ctinfo;
241 unsigned int ret;
242
243 /* root is playing with raw sockets. */
244 if ((*pskb)->len < sizeof(struct iphdr) ||
245 (*pskb)->nh.iph->ihl * 4 < sizeof(struct iphdr))
246 return NF_ACCEPT;
247
248 ret = nf_nat_fn(hooknum, pskb, in, out, okfn);
249 if (ret != NF_DROP && ret != NF_STOLEN &&
250 (ct = nf_ct_get(*pskb, &ctinfo)) != NULL) {
251 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
252
253 if (ct->tuplehash[dir].tuple.dst.u3.ip !=
254 ct->tuplehash[!dir].tuple.src.u3.ip
255#ifdef CONFIG_XFRM
256 || ct->tuplehash[dir].tuple.dst.u.all !=
257 ct->tuplehash[!dir].tuple.src.u.all
258#endif
259 )
260 if (ip_route_me_harder(pskb, RTN_UNSPEC))
261 ret = NF_DROP;
262 }
263 return ret;
264}
265
266static unsigned int
267nf_nat_adjust(unsigned int hooknum,
268 struct sk_buff **pskb,
269 const struct net_device *in,
270 const struct net_device *out,
271 int (*okfn)(struct sk_buff *))
272{
273 struct nf_conn *ct;
274 enum ip_conntrack_info ctinfo;
275
276 ct = nf_ct_get(*pskb, &ctinfo);
277 if (ct && test_bit(IPS_SEQ_ADJUST_BIT, &ct->status)) {
278 DEBUGP("nf_nat_standalone: adjusting sequence number\n");
279 if (!nf_nat_seq_adjust(pskb, ct, ctinfo))
280 return NF_DROP;
281 }
282 return NF_ACCEPT;
283}
284
285/* We must be after connection tracking and before packet filtering. */
286
287static struct nf_hook_ops nf_nat_ops[] = {
288 /* Before packet filtering, change destination */
289 {
290 .hook = nf_nat_in,
291 .owner = THIS_MODULE,
292 .pf = PF_INET,
293 .hooknum = NF_IP_PRE_ROUTING,
294 .priority = NF_IP_PRI_NAT_DST,
295 },
296 /* After packet filtering, change source */
297 {
298 .hook = nf_nat_out,
299 .owner = THIS_MODULE,
300 .pf = PF_INET,
301 .hooknum = NF_IP_POST_ROUTING,
302 .priority = NF_IP_PRI_NAT_SRC,
303 },
304 /* After conntrack, adjust sequence number */
305 {
306 .hook = nf_nat_adjust,
307 .owner = THIS_MODULE,
308 .pf = PF_INET,
309 .hooknum = NF_IP_POST_ROUTING,
310 .priority = NF_IP_PRI_NAT_SEQ_ADJUST,
311 },
312 /* Before packet filtering, change destination */
313 {
314 .hook = nf_nat_local_fn,
315 .owner = THIS_MODULE,
316 .pf = PF_INET,
317 .hooknum = NF_IP_LOCAL_OUT,
318 .priority = NF_IP_PRI_NAT_DST,
319 },
320 /* After packet filtering, change source */
321 {
322 .hook = nf_nat_fn,
323 .owner = THIS_MODULE,
324 .pf = PF_INET,
325 .hooknum = NF_IP_LOCAL_IN,
326 .priority = NF_IP_PRI_NAT_SRC,
327 },
328 /* After conntrack, adjust sequence number */
329 {
330 .hook = nf_nat_adjust,
331 .owner = THIS_MODULE,
332 .pf = PF_INET,
333 .hooknum = NF_IP_LOCAL_IN,
334 .priority = NF_IP_PRI_NAT_SEQ_ADJUST,
335 },
336};
337
338static int __init nf_nat_standalone_init(void)
339{
340 int size, ret = 0;
341
342 need_conntrack();
343
344 size = ALIGN(sizeof(struct nf_conn), __alignof__(struct nf_conn_nat)) +
345 sizeof(struct nf_conn_nat);
346 ret = nf_conntrack_register_cache(NF_CT_F_NAT, "nf_nat:base", size);
347 if (ret < 0) {
348 printk(KERN_ERR "nf_nat_init: Unable to create slab cache\n");
349 return ret;
350 }
351
352 size = ALIGN(size, __alignof__(struct nf_conn_help)) +
353 sizeof(struct nf_conn_help);
354 ret = nf_conntrack_register_cache(NF_CT_F_NAT|NF_CT_F_HELP,
355 "nf_nat:help", size);
356 if (ret < 0) {
357 printk(KERN_ERR "nf_nat_init: Unable to create slab cache\n");
358 goto cleanup_register_cache;
359 }
360#ifdef CONFIG_XFRM
361 BUG_ON(ip_nat_decode_session != NULL);
362 ip_nat_decode_session = nat_decode_session;
363#endif
364 ret = nf_nat_rule_init();
365 if (ret < 0) {
366 printk("nf_nat_init: can't setup rules.\n");
367 goto cleanup_decode_session;
368 }
369 ret = nf_register_hooks(nf_nat_ops, ARRAY_SIZE(nf_nat_ops));
370 if (ret < 0) {
371 printk("nf_nat_init: can't register hooks.\n");
372 goto cleanup_rule_init;
373 }
374 nf_nat_module_is_loaded = 1;
375 return ret;
376
377 cleanup_rule_init:
378 nf_nat_rule_cleanup();
379 cleanup_decode_session:
380#ifdef CONFIG_XFRM
381 ip_nat_decode_session = NULL;
382 synchronize_net();
383#endif
384 nf_conntrack_unregister_cache(NF_CT_F_NAT|NF_CT_F_HELP);
385 cleanup_register_cache:
386 nf_conntrack_unregister_cache(NF_CT_F_NAT);
387 return ret;
388}
389
390static void __exit nf_nat_standalone_fini(void)
391{
392 nf_unregister_hooks(nf_nat_ops, ARRAY_SIZE(nf_nat_ops));
393 nf_nat_rule_cleanup();
394 nf_nat_module_is_loaded = 0;
395#ifdef CONFIG_XFRM
396 ip_nat_decode_session = NULL;
397 synchronize_net();
398#endif
399 /* Conntrack caches are unregistered in nf_conntrack_cleanup */
400}
401
402module_init(nf_nat_standalone_init);
403module_exit(nf_nat_standalone_fini);
404
405MODULE_LICENSE("GPL");
406MODULE_ALIAS("ip_nat");
diff --git a/net/ipv4/netfilter/nf_nat_tftp.c b/net/ipv4/netfilter/nf_nat_tftp.c
new file mode 100644
index 0000000000..2566b79de2
--- /dev/null
+++ b/net/ipv4/netfilter/nf_nat_tftp.c
@@ -0,0 +1,52 @@
1/* (C) 2001-2002 Magnus Boden <mb@ozaba.mine.nu>
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 as
5 * published by the Free Software Foundation.
6 */
7
8#include <linux/module.h>
9#include <linux/moduleparam.h>
10#include <linux/udp.h>
11
12#include <net/netfilter/nf_nat_helper.h>
13#include <net/netfilter/nf_nat_rule.h>
14#include <net/netfilter/nf_conntrack_helper.h>
15#include <net/netfilter/nf_conntrack_expect.h>
16#include <linux/netfilter/nf_conntrack_tftp.h>
17
18MODULE_AUTHOR("Magnus Boden <mb@ozaba.mine.nu>");
19MODULE_DESCRIPTION("TFTP NAT helper");
20MODULE_LICENSE("GPL");
21MODULE_ALIAS("ip_nat_tftp");
22
23static unsigned int help(struct sk_buff **pskb,
24 enum ip_conntrack_info ctinfo,
25 struct nf_conntrack_expect *exp)
26{
27 struct nf_conn *ct = exp->master;
28
29 exp->saved_proto.udp.port
30 = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port;
31 exp->dir = IP_CT_DIR_REPLY;
32 exp->expectfn = nf_nat_follow_master;
33 if (nf_conntrack_expect_related(exp) != 0)
34 return NF_DROP;
35 return NF_ACCEPT;
36}
37
38static void __exit nf_nat_tftp_fini(void)
39{
40 rcu_assign_pointer(nf_nat_tftp_hook, NULL);
41 synchronize_rcu();
42}
43
44static int __init nf_nat_tftp_init(void)
45{
46 BUG_ON(rcu_dereference(nf_nat_tftp_hook));
47 rcu_assign_pointer(nf_nat_tftp_hook, help);
48 return 0;
49}
50
51module_init(nf_nat_tftp_init);
52module_exit(nf_nat_tftp_fini);
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index 9c6cbe3d9f..cd873da54c 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -38,6 +38,7 @@
38#include <net/protocol.h> 38#include <net/protocol.h>
39#include <net/tcp.h> 39#include <net/tcp.h>
40#include <net/udp.h> 40#include <net/udp.h>
41#include <net/udplite.h>
41#include <linux/inetdevice.h> 42#include <linux/inetdevice.h>
42#include <linux/proc_fs.h> 43#include <linux/proc_fs.h>
43#include <linux/seq_file.h> 44#include <linux/seq_file.h>
@@ -66,6 +67,7 @@ static int sockstat_seq_show(struct seq_file *seq, void *v)
66 tcp_death_row.tw_count, atomic_read(&tcp_sockets_allocated), 67 tcp_death_row.tw_count, atomic_read(&tcp_sockets_allocated),
67 atomic_read(&tcp_memory_allocated)); 68 atomic_read(&tcp_memory_allocated));
68 seq_printf(seq, "UDP: inuse %d\n", fold_prot_inuse(&udp_prot)); 69 seq_printf(seq, "UDP: inuse %d\n", fold_prot_inuse(&udp_prot));
70 seq_printf(seq, "UDPLITE: inuse %d\n", fold_prot_inuse(&udplite_prot));
69 seq_printf(seq, "RAW: inuse %d\n", fold_prot_inuse(&raw_prot)); 71 seq_printf(seq, "RAW: inuse %d\n", fold_prot_inuse(&raw_prot));
70 seq_printf(seq, "FRAG: inuse %d memory %d\n", ip_frag_nqueues, 72 seq_printf(seq, "FRAG: inuse %d memory %d\n", ip_frag_nqueues,
71 atomic_read(&ip_frag_mem)); 73 atomic_read(&ip_frag_mem));
@@ -304,6 +306,17 @@ static int snmp_seq_show(struct seq_file *seq, void *v)
304 fold_field((void **) udp_statistics, 306 fold_field((void **) udp_statistics,
305 snmp4_udp_list[i].entry)); 307 snmp4_udp_list[i].entry));
306 308
309 /* the UDP and UDP-Lite MIBs are the same */
310 seq_puts(seq, "\nUdpLite:");
311 for (i = 0; snmp4_udp_list[i].name != NULL; i++)
312 seq_printf(seq, " %s", snmp4_udp_list[i].name);
313
314 seq_puts(seq, "\nUdpLite:");
315 for (i = 0; snmp4_udp_list[i].name != NULL; i++)
316 seq_printf(seq, " %lu",
317 fold_field((void **) udplite_statistics,
318 snmp4_udp_list[i].entry) );
319
307 seq_putc(seq, '\n'); 320 seq_putc(seq, '\n');
308 return 0; 321 return 0;
309} 322}
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 5c31dead2b..a6c63bbd9d 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -854,8 +854,8 @@ static void raw_seq_stop(struct seq_file *seq, void *v)
854static __inline__ char *get_raw_sock(struct sock *sp, char *tmpbuf, int i) 854static __inline__ char *get_raw_sock(struct sock *sp, char *tmpbuf, int i)
855{ 855{
856 struct inet_sock *inet = inet_sk(sp); 856 struct inet_sock *inet = inet_sk(sp);
857 unsigned int dest = inet->daddr, 857 __be32 dest = inet->daddr,
858 src = inet->rcv_saddr; 858 src = inet->rcv_saddr;
859 __u16 destp = 0, 859 __u16 destp = 0,
860 srcp = inet->num; 860 srcp = inet->num;
861 861
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 925ee4dfc3..2daa0dc19d 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -566,11 +566,9 @@ static inline u32 rt_score(struct rtable *rt)
566 566
567static inline int compare_keys(struct flowi *fl1, struct flowi *fl2) 567static inline int compare_keys(struct flowi *fl1, struct flowi *fl2)
568{ 568{
569 return ((fl1->nl_u.ip4_u.daddr ^ fl2->nl_u.ip4_u.daddr) | 569 return ((__force u32)((fl1->nl_u.ip4_u.daddr ^ fl2->nl_u.ip4_u.daddr) |
570 (fl1->nl_u.ip4_u.saddr ^ fl2->nl_u.ip4_u.saddr) | 570 (fl1->nl_u.ip4_u.saddr ^ fl2->nl_u.ip4_u.saddr)) |
571#ifdef CONFIG_IP_ROUTE_FWMARK 571 (fl1->mark ^ fl2->mark) |
572 (fl1->nl_u.ip4_u.fwmark ^ fl2->nl_u.ip4_u.fwmark) |
573#endif
574 (*(u16 *)&fl1->nl_u.ip4_u.tos ^ 572 (*(u16 *)&fl1->nl_u.ip4_u.tos ^
575 *(u16 *)&fl2->nl_u.ip4_u.tos) | 573 *(u16 *)&fl2->nl_u.ip4_u.tos) |
576 (fl1->oif ^ fl2->oif) | 574 (fl1->oif ^ fl2->oif) |
@@ -1327,7 +1325,8 @@ void ip_rt_send_redirect(struct sk_buff *skb)
1327 /* Check for load limit; set rate_last to the latest sent 1325 /* Check for load limit; set rate_last to the latest sent
1328 * redirect. 1326 * redirect.
1329 */ 1327 */
1330 if (time_after(jiffies, 1328 if (rt->u.dst.rate_tokens == 0 ||
1329 time_after(jiffies,
1331 (rt->u.dst.rate_last + 1330 (rt->u.dst.rate_last +
1332 (ip_rt_redirect_load << rt->u.dst.rate_tokens)))) { 1331 (ip_rt_redirect_load << rt->u.dst.rate_tokens)))) {
1333 icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, rt->rt_gateway); 1332 icmp_send(skb, ICMP_REDIRECT, ICMP_REDIR_HOST, rt->rt_gateway);
@@ -1643,9 +1642,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
1643 rth->fl.fl4_dst = daddr; 1642 rth->fl.fl4_dst = daddr;
1644 rth->rt_dst = daddr; 1643 rth->rt_dst = daddr;
1645 rth->fl.fl4_tos = tos; 1644 rth->fl.fl4_tos = tos;
1646#ifdef CONFIG_IP_ROUTE_FWMARK 1645 rth->fl.mark = skb->mark;
1647 rth->fl.fl4_fwmark= skb->nfmark;
1648#endif
1649 rth->fl.fl4_src = saddr; 1646 rth->fl.fl4_src = saddr;
1650 rth->rt_src = saddr; 1647 rth->rt_src = saddr;
1651#ifdef CONFIG_NET_CLS_ROUTE 1648#ifdef CONFIG_NET_CLS_ROUTE
@@ -1784,14 +1781,12 @@ static inline int __mkroute_input(struct sk_buff *skb,
1784#endif 1781#endif
1785 if (in_dev->cnf.no_policy) 1782 if (in_dev->cnf.no_policy)
1786 rth->u.dst.flags |= DST_NOPOLICY; 1783 rth->u.dst.flags |= DST_NOPOLICY;
1787 if (in_dev->cnf.no_xfrm) 1784 if (out_dev->cnf.no_xfrm)
1788 rth->u.dst.flags |= DST_NOXFRM; 1785 rth->u.dst.flags |= DST_NOXFRM;
1789 rth->fl.fl4_dst = daddr; 1786 rth->fl.fl4_dst = daddr;
1790 rth->rt_dst = daddr; 1787 rth->rt_dst = daddr;
1791 rth->fl.fl4_tos = tos; 1788 rth->fl.fl4_tos = tos;
1792#ifdef CONFIG_IP_ROUTE_FWMARK 1789 rth->fl.mark = skb->mark;
1793 rth->fl.fl4_fwmark= skb->nfmark;
1794#endif
1795 rth->fl.fl4_src = saddr; 1790 rth->fl.fl4_src = saddr;
1796 rth->rt_src = saddr; 1791 rth->rt_src = saddr;
1797 rth->rt_gateway = daddr; 1792 rth->rt_gateway = daddr;
@@ -1920,10 +1915,8 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
1920 .saddr = saddr, 1915 .saddr = saddr,
1921 .tos = tos, 1916 .tos = tos,
1922 .scope = RT_SCOPE_UNIVERSE, 1917 .scope = RT_SCOPE_UNIVERSE,
1923#ifdef CONFIG_IP_ROUTE_FWMARK
1924 .fwmark = skb->nfmark
1925#endif
1926 } }, 1918 } },
1919 .mark = skb->mark,
1927 .iif = dev->ifindex }; 1920 .iif = dev->ifindex };
1928 unsigned flags = 0; 1921 unsigned flags = 0;
1929 u32 itag = 0; 1922 u32 itag = 0;
@@ -2034,9 +2027,7 @@ local_input:
2034 rth->fl.fl4_dst = daddr; 2027 rth->fl.fl4_dst = daddr;
2035 rth->rt_dst = daddr; 2028 rth->rt_dst = daddr;
2036 rth->fl.fl4_tos = tos; 2029 rth->fl.fl4_tos = tos;
2037#ifdef CONFIG_IP_ROUTE_FWMARK 2030 rth->fl.mark = skb->mark;
2038 rth->fl.fl4_fwmark= skb->nfmark;
2039#endif
2040 rth->fl.fl4_src = saddr; 2031 rth->fl.fl4_src = saddr;
2041 rth->rt_src = saddr; 2032 rth->rt_src = saddr;
2042#ifdef CONFIG_NET_CLS_ROUTE 2033#ifdef CONFIG_NET_CLS_ROUTE
@@ -2113,9 +2104,7 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr,
2113 rth->fl.fl4_src == saddr && 2104 rth->fl.fl4_src == saddr &&
2114 rth->fl.iif == iif && 2105 rth->fl.iif == iif &&
2115 rth->fl.oif == 0 && 2106 rth->fl.oif == 0 &&
2116#ifdef CONFIG_IP_ROUTE_FWMARK 2107 rth->fl.mark == skb->mark &&
2117 rth->fl.fl4_fwmark == skb->nfmark &&
2118#endif
2119 rth->fl.fl4_tos == tos) { 2108 rth->fl.fl4_tos == tos) {
2120 rth->u.dst.lastuse = jiffies; 2109 rth->u.dst.lastuse = jiffies;
2121 dst_hold(&rth->u.dst); 2110 dst_hold(&rth->u.dst);
@@ -2239,9 +2228,7 @@ static inline int __mkroute_output(struct rtable **result,
2239 rth->fl.fl4_tos = tos; 2228 rth->fl.fl4_tos = tos;
2240 rth->fl.fl4_src = oldflp->fl4_src; 2229 rth->fl.fl4_src = oldflp->fl4_src;
2241 rth->fl.oif = oldflp->oif; 2230 rth->fl.oif = oldflp->oif;
2242#ifdef CONFIG_IP_ROUTE_FWMARK 2231 rth->fl.mark = oldflp->mark;
2243 rth->fl.fl4_fwmark= oldflp->fl4_fwmark;
2244#endif
2245 rth->rt_dst = fl->fl4_dst; 2232 rth->rt_dst = fl->fl4_dst;
2246 rth->rt_src = fl->fl4_src; 2233 rth->rt_src = fl->fl4_src;
2247 rth->rt_iif = oldflp->oif ? : dev_out->ifindex; 2234 rth->rt_iif = oldflp->oif ? : dev_out->ifindex;
@@ -2385,10 +2372,8 @@ static int ip_route_output_slow(struct rtable **rp, const struct flowi *oldflp)
2385 .scope = ((tos & RTO_ONLINK) ? 2372 .scope = ((tos & RTO_ONLINK) ?
2386 RT_SCOPE_LINK : 2373 RT_SCOPE_LINK :
2387 RT_SCOPE_UNIVERSE), 2374 RT_SCOPE_UNIVERSE),
2388#ifdef CONFIG_IP_ROUTE_FWMARK
2389 .fwmark = oldflp->fl4_fwmark
2390#endif
2391 } }, 2375 } },
2376 .mark = oldflp->mark,
2392 .iif = loopback_dev.ifindex, 2377 .iif = loopback_dev.ifindex,
2393 .oif = oldflp->oif }; 2378 .oif = oldflp->oif };
2394 struct fib_result res; 2379 struct fib_result res;
@@ -2583,9 +2568,7 @@ int __ip_route_output_key(struct rtable **rp, const struct flowi *flp)
2583 rth->fl.fl4_src == flp->fl4_src && 2568 rth->fl.fl4_src == flp->fl4_src &&
2584 rth->fl.iif == 0 && 2569 rth->fl.iif == 0 &&
2585 rth->fl.oif == flp->oif && 2570 rth->fl.oif == flp->oif &&
2586#ifdef CONFIG_IP_ROUTE_FWMARK 2571 rth->fl.mark == flp->mark &&
2587 rth->fl.fl4_fwmark == flp->fl4_fwmark &&
2588#endif
2589 !((rth->fl.fl4_tos ^ flp->fl4_tos) & 2572 !((rth->fl.fl4_tos ^ flp->fl4_tos) &
2590 (IPTOS_RT_MASK | RTO_ONLINK))) { 2573 (IPTOS_RT_MASK | RTO_ONLINK))) {
2591 2574
@@ -2647,7 +2630,8 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
2647 struct rtable *rt = (struct rtable*)skb->dst; 2630 struct rtable *rt = (struct rtable*)skb->dst;
2648 struct rtmsg *r; 2631 struct rtmsg *r;
2649 struct nlmsghdr *nlh; 2632 struct nlmsghdr *nlh;
2650 struct rta_cacheinfo ci; 2633 long expires;
2634 u32 id = 0, ts = 0, tsage = 0, error;
2651 2635
2652 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*r), flags); 2636 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*r), flags);
2653 if (nlh == NULL) 2637 if (nlh == NULL)
@@ -2694,20 +2678,13 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
2694 if (rtnetlink_put_metrics(skb, rt->u.dst.metrics) < 0) 2678 if (rtnetlink_put_metrics(skb, rt->u.dst.metrics) < 0)
2695 goto nla_put_failure; 2679 goto nla_put_failure;
2696 2680
2697 ci.rta_lastuse = jiffies_to_clock_t(jiffies - rt->u.dst.lastuse); 2681 error = rt->u.dst.error;
2698 ci.rta_used = rt->u.dst.__use; 2682 expires = rt->u.dst.expires ? rt->u.dst.expires - jiffies : 0;
2699 ci.rta_clntref = atomic_read(&rt->u.dst.__refcnt);
2700 if (rt->u.dst.expires)
2701 ci.rta_expires = jiffies_to_clock_t(rt->u.dst.expires - jiffies);
2702 else
2703 ci.rta_expires = 0;
2704 ci.rta_error = rt->u.dst.error;
2705 ci.rta_id = ci.rta_ts = ci.rta_tsage = 0;
2706 if (rt->peer) { 2683 if (rt->peer) {
2707 ci.rta_id = rt->peer->ip_id_count; 2684 id = rt->peer->ip_id_count;
2708 if (rt->peer->tcp_ts_stamp) { 2685 if (rt->peer->tcp_ts_stamp) {
2709 ci.rta_ts = rt->peer->tcp_ts; 2686 ts = rt->peer->tcp_ts;
2710 ci.rta_tsage = xtime.tv_sec - rt->peer->tcp_ts_stamp; 2687 tsage = xtime.tv_sec - rt->peer->tcp_ts_stamp;
2711 } 2688 }
2712 } 2689 }
2713 2690
@@ -2726,7 +2703,7 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
2726 } else { 2703 } else {
2727 if (err == -EMSGSIZE) 2704 if (err == -EMSGSIZE)
2728 goto nla_put_failure; 2705 goto nla_put_failure;
2729 ci.rta_error = err; 2706 error = err;
2730 } 2707 }
2731 } 2708 }
2732 } else 2709 } else
@@ -2734,7 +2711,9 @@ static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
2734 NLA_PUT_U32(skb, RTA_IIF, rt->fl.iif); 2711 NLA_PUT_U32(skb, RTA_IIF, rt->fl.iif);
2735 } 2712 }
2736 2713
2737 NLA_PUT(skb, RTA_CACHEINFO, sizeof(ci), &ci); 2714 if (rtnl_put_cacheinfo(skb, &rt->u.dst, id, ts, tsage,
2715 expires, error) < 0)
2716 goto nla_put_failure;
2738 2717
2739 return nlmsg_end(skb, nlh); 2718 return nlmsg_end(skb, nlh);
2740 2719
@@ -2894,8 +2873,7 @@ static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table,
2894 void __user *oldval, 2873 void __user *oldval,
2895 size_t __user *oldlenp, 2874 size_t __user *oldlenp,
2896 void __user *newval, 2875 void __user *newval,
2897 size_t newlen, 2876 size_t newlen)
2898 void **context)
2899{ 2877{
2900 int delay; 2878 int delay;
2901 if (newlen != sizeof(int)) 2879 if (newlen != sizeof(int))
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index 661e0a4bca..6b19530905 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -35,23 +35,23 @@ module_init(init_syncookies);
35#define COOKIEBITS 24 /* Upper bits store count */ 35#define COOKIEBITS 24 /* Upper bits store count */
36#define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1) 36#define COOKIEMASK (((__u32)1 << COOKIEBITS) - 1)
37 37
38static u32 cookie_hash(u32 saddr, u32 daddr, u32 sport, u32 dport, 38static u32 cookie_hash(__be32 saddr, __be32 daddr, __be16 sport, __be16 dport,
39 u32 count, int c) 39 u32 count, int c)
40{ 40{
41 __u32 tmp[16 + 5 + SHA_WORKSPACE_WORDS]; 41 __u32 tmp[16 + 5 + SHA_WORKSPACE_WORDS];
42 42
43 memcpy(tmp + 3, syncookie_secret[c], sizeof(syncookie_secret[c])); 43 memcpy(tmp + 3, syncookie_secret[c], sizeof(syncookie_secret[c]));
44 tmp[0] = saddr; 44 tmp[0] = (__force u32)saddr;
45 tmp[1] = daddr; 45 tmp[1] = (__force u32)daddr;
46 tmp[2] = (sport << 16) + dport; 46 tmp[2] = ((__force u32)sport << 16) + (__force u32)dport;
47 tmp[3] = count; 47 tmp[3] = count;
48 sha_transform(tmp + 16, (__u8 *)tmp, tmp + 16 + 5); 48 sha_transform(tmp + 16, (__u8 *)tmp, tmp + 16 + 5);
49 49
50 return tmp[17]; 50 return tmp[17];
51} 51}
52 52
53static __u32 secure_tcp_syn_cookie(__u32 saddr, __u32 daddr, __u16 sport, 53static __u32 secure_tcp_syn_cookie(__be32 saddr, __be32 daddr, __be16 sport,
54 __u16 dport, __u32 sseq, __u32 count, 54 __be16 dport, __u32 sseq, __u32 count,
55 __u32 data) 55 __u32 data)
56{ 56{
57 /* 57 /*
@@ -80,8 +80,8 @@ static __u32 secure_tcp_syn_cookie(__u32 saddr, __u32 daddr, __u16 sport,
80 * "maxdiff" if the current (passed-in) "count". The return value 80 * "maxdiff" if the current (passed-in) "count". The return value
81 * is (__u32)-1 if this test fails. 81 * is (__u32)-1 if this test fails.
82 */ 82 */
83static __u32 check_tcp_syn_cookie(__u32 cookie, __u32 saddr, __u32 daddr, 83static __u32 check_tcp_syn_cookie(__u32 cookie, __be32 saddr, __be32 daddr,
84 __u16 sport, __u16 dport, __u32 sseq, 84 __be16 sport, __be16 dport, __u32 sseq,
85 __u32 count, __u32 maxdiff) 85 __u32 count, __u32 maxdiff)
86{ 86{
87 __u32 diff; 87 __u32 diff;
@@ -220,7 +220,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
220 } 220 }
221 ireq = inet_rsk(req); 221 ireq = inet_rsk(req);
222 treq = tcp_rsk(req); 222 treq = tcp_rsk(req);
223 treq->rcv_isn = htonl(skb->h.th->seq) - 1; 223 treq->rcv_isn = ntohl(skb->h.th->seq) - 1;
224 treq->snt_isn = cookie; 224 treq->snt_isn = cookie;
225 req->mss = mss; 225 req->mss = mss;
226 ireq->rmt_port = skb->h.th->source; 226 ireq->rmt_port = skb->h.th->source;
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 15061b3144..fabf69a910 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -51,8 +51,7 @@ int ipv4_sysctl_forward(ctl_table *ctl, int write, struct file * filp,
51static int ipv4_sysctl_forward_strategy(ctl_table *table, 51static int ipv4_sysctl_forward_strategy(ctl_table *table,
52 int __user *name, int nlen, 52 int __user *name, int nlen,
53 void __user *oldval, size_t __user *oldlenp, 53 void __user *oldval, size_t __user *oldlenp,
54 void __user *newval, size_t newlen, 54 void __user *newval, size_t newlen)
55 void **context)
56{ 55{
57 int *valp = table->data; 56 int *valp = table->data;
58 int new; 57 int new;
@@ -111,8 +110,7 @@ static int proc_tcp_congestion_control(ctl_table *ctl, int write, struct file *
111static int sysctl_tcp_congestion_control(ctl_table *table, int __user *name, 110static int sysctl_tcp_congestion_control(ctl_table *table, int __user *name,
112 int nlen, void __user *oldval, 111 int nlen, void __user *oldval,
113 size_t __user *oldlenp, 112 size_t __user *oldlenp,
114 void __user *newval, size_t newlen, 113 void __user *newval, size_t newlen)
115 void **context)
116{ 114{
117 char val[TCP_CA_NAME_MAX]; 115 char val[TCP_CA_NAME_MAX];
118 ctl_table tbl = { 116 ctl_table tbl = {
@@ -122,13 +120,72 @@ static int sysctl_tcp_congestion_control(ctl_table *table, int __user *name,
122 int ret; 120 int ret;
123 121
124 tcp_get_default_congestion_control(val); 122 tcp_get_default_congestion_control(val);
125 ret = sysctl_string(&tbl, name, nlen, oldval, oldlenp, newval, newlen, 123 ret = sysctl_string(&tbl, name, nlen, oldval, oldlenp, newval, newlen);
126 context);
127 if (ret == 0 && newval && newlen) 124 if (ret == 0 && newval && newlen)
128 ret = tcp_set_default_congestion_control(val); 125 ret = tcp_set_default_congestion_control(val);
129 return ret; 126 return ret;
130} 127}
131 128
129static int proc_tcp_available_congestion_control(ctl_table *ctl,
130 int write, struct file * filp,
131 void __user *buffer, size_t *lenp,
132 loff_t *ppos)
133{
134 ctl_table tbl = { .maxlen = TCP_CA_BUF_MAX, };
135 int ret;
136
137 tbl.data = kmalloc(tbl.maxlen, GFP_USER);
138 if (!tbl.data)
139 return -ENOMEM;
140 tcp_get_available_congestion_control(tbl.data, TCP_CA_BUF_MAX);
141 ret = proc_dostring(&tbl, write, filp, buffer, lenp, ppos);
142 kfree(tbl.data);
143 return ret;
144}
145
146static int proc_allowed_congestion_control(ctl_table *ctl,
147 int write, struct file * filp,
148 void __user *buffer, size_t *lenp,
149 loff_t *ppos)
150{
151 ctl_table tbl = { .maxlen = TCP_CA_BUF_MAX };
152 int ret;
153
154 tbl.data = kmalloc(tbl.maxlen, GFP_USER);
155 if (!tbl.data)
156 return -ENOMEM;
157
158 tcp_get_allowed_congestion_control(tbl.data, tbl.maxlen);
159 ret = proc_dostring(&tbl, write, filp, buffer, lenp, ppos);
160 if (write && ret == 0)
161 ret = tcp_set_allowed_congestion_control(tbl.data);
162 kfree(tbl.data);
163 return ret;
164}
165
166static int strategy_allowed_congestion_control(ctl_table *table, int __user *name,
167 int nlen, void __user *oldval,
168 size_t __user *oldlenp,
169 void __user *newval,
170 size_t newlen)
171{
172 ctl_table tbl = { .maxlen = TCP_CA_BUF_MAX };
173 int ret;
174
175 tbl.data = kmalloc(tbl.maxlen, GFP_USER);
176 if (!tbl.data)
177 return -ENOMEM;
178
179 tcp_get_available_congestion_control(tbl.data, tbl.maxlen);
180 ret = sysctl_string(&tbl, name, nlen, oldval, oldlenp, newval, newlen);
181 if (ret == 0 && newval && newlen)
182 ret = tcp_set_allowed_congestion_control(tbl.data);
183 kfree(tbl.data);
184
185 return ret;
186
187}
188
132ctl_table ipv4_table[] = { 189ctl_table ipv4_table[] = {
133 { 190 {
134 .ctl_name = NET_IPV4_TCP_TIMESTAMPS, 191 .ctl_name = NET_IPV4_TCP_TIMESTAMPS,
@@ -731,6 +788,21 @@ ctl_table ipv4_table[] = {
731 .proc_handler = &proc_dointvec, 788 .proc_handler = &proc_dointvec,
732 }, 789 },
733#endif /* CONFIG_NETLABEL */ 790#endif /* CONFIG_NETLABEL */
791 {
792 .ctl_name = NET_TCP_AVAIL_CONG_CONTROL,
793 .procname = "tcp_available_congestion_control",
794 .maxlen = TCP_CA_BUF_MAX,
795 .mode = 0444,
796 .proc_handler = &proc_tcp_available_congestion_control,
797 },
798 {
799 .ctl_name = NET_TCP_ALLOWED_CONG_CONTROL,
800 .procname = "tcp_allowed_congestion_control",
801 .maxlen = TCP_CA_BUF_MAX,
802 .mode = 0644,
803 .proc_handler = &proc_allowed_congestion_control,
804 .strategy = &strategy_allowed_congestion_control,
805 },
734 { .ctl_name = 0 } 806 { .ctl_name = 0 }
735}; 807};
736 808
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index c05e8edaf5..b67e0dd743 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -258,6 +258,7 @@
258#include <linux/bootmem.h> 258#include <linux/bootmem.h>
259#include <linux/cache.h> 259#include <linux/cache.h>
260#include <linux/err.h> 260#include <linux/err.h>
261#include <linux/crypto.h>
261 262
262#include <net/icmp.h> 263#include <net/icmp.h>
263#include <net/tcp.h> 264#include <net/tcp.h>
@@ -462,11 +463,12 @@ static inline int forced_push(struct tcp_sock *tp)
462static inline void skb_entail(struct sock *sk, struct tcp_sock *tp, 463static inline void skb_entail(struct sock *sk, struct tcp_sock *tp,
463 struct sk_buff *skb) 464 struct sk_buff *skb)
464{ 465{
465 skb->csum = 0; 466 struct tcp_skb_cb *tcb = TCP_SKB_CB(skb);
466 TCP_SKB_CB(skb)->seq = tp->write_seq; 467
467 TCP_SKB_CB(skb)->end_seq = tp->write_seq; 468 skb->csum = 0;
468 TCP_SKB_CB(skb)->flags = TCPCB_FLAG_ACK; 469 tcb->seq = tcb->end_seq = tp->write_seq;
469 TCP_SKB_CB(skb)->sacked = 0; 470 tcb->flags = TCPCB_FLAG_ACK;
471 tcb->sacked = 0;
470 skb_header_release(skb); 472 skb_header_release(skb);
471 __skb_queue_tail(&sk->sk_write_queue, skb); 473 __skb_queue_tail(&sk->sk_write_queue, skb);
472 sk_charge_skb(sk, skb); 474 sk_charge_skb(sk, skb);
@@ -1942,6 +1944,13 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
1942 } 1944 }
1943 break; 1945 break;
1944 1946
1947#ifdef CONFIG_TCP_MD5SIG
1948 case TCP_MD5SIG:
1949 /* Read the IP->Key mappings from userspace */
1950 err = tp->af_specific->md5_parse(sk, optval, optlen);
1951 break;
1952#endif
1953
1945 default: 1954 default:
1946 err = -ENOPROTOOPT; 1955 err = -ENOPROTOOPT;
1947 break; 1956 break;
@@ -2154,7 +2163,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
2154 struct tcphdr *th; 2163 struct tcphdr *th;
2155 unsigned thlen; 2164 unsigned thlen;
2156 unsigned int seq; 2165 unsigned int seq;
2157 unsigned int delta; 2166 __be32 delta;
2158 unsigned int oldlen; 2167 unsigned int oldlen;
2159 unsigned int len; 2168 unsigned int len;
2160 2169
@@ -2207,7 +2216,8 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
2207 do { 2216 do {
2208 th->fin = th->psh = 0; 2217 th->fin = th->psh = 0;
2209 2218
2210 th->check = ~csum_fold(th->check + delta); 2219 th->check = ~csum_fold((__force __wsum)((__force u32)th->check +
2220 (__force u32)delta));
2211 if (skb->ip_summed != CHECKSUM_PARTIAL) 2221 if (skb->ip_summed != CHECKSUM_PARTIAL)
2212 th->check = csum_fold(csum_partial(skb->h.raw, thlen, 2222 th->check = csum_fold(csum_partial(skb->h.raw, thlen,
2213 skb->csum)); 2223 skb->csum));
@@ -2221,7 +2231,8 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb, int features)
2221 } while (skb->next); 2231 } while (skb->next);
2222 2232
2223 delta = htonl(oldlen + (skb->tail - skb->h.raw) + skb->data_len); 2233 delta = htonl(oldlen + (skb->tail - skb->h.raw) + skb->data_len);
2224 th->check = ~csum_fold(th->check + delta); 2234 th->check = ~csum_fold((__force __wsum)((__force u32)th->check +
2235 (__force u32)delta));
2225 if (skb->ip_summed != CHECKSUM_PARTIAL) 2236 if (skb->ip_summed != CHECKSUM_PARTIAL)
2226 th->check = csum_fold(csum_partial(skb->h.raw, thlen, 2237 th->check = csum_fold(csum_partial(skb->h.raw, thlen,
2227 skb->csum)); 2238 skb->csum));
@@ -2231,6 +2242,136 @@ out:
2231} 2242}
2232EXPORT_SYMBOL(tcp_tso_segment); 2243EXPORT_SYMBOL(tcp_tso_segment);
2233 2244
2245#ifdef CONFIG_TCP_MD5SIG
2246static unsigned long tcp_md5sig_users;
2247static struct tcp_md5sig_pool **tcp_md5sig_pool;
2248static DEFINE_SPINLOCK(tcp_md5sig_pool_lock);
2249
2250static void __tcp_free_md5sig_pool(struct tcp_md5sig_pool **pool)
2251{
2252 int cpu;
2253 for_each_possible_cpu(cpu) {
2254 struct tcp_md5sig_pool *p = *per_cpu_ptr(pool, cpu);
2255 if (p) {
2256 if (p->md5_desc.tfm)
2257 crypto_free_hash(p->md5_desc.tfm);
2258 kfree(p);
2259 p = NULL;
2260 }
2261 }
2262 free_percpu(pool);
2263}
2264
2265void tcp_free_md5sig_pool(void)
2266{
2267 struct tcp_md5sig_pool **pool = NULL;
2268
2269 spin_lock(&tcp_md5sig_pool_lock);
2270 if (--tcp_md5sig_users == 0) {
2271 pool = tcp_md5sig_pool;
2272 tcp_md5sig_pool = NULL;
2273 }
2274 spin_unlock(&tcp_md5sig_pool_lock);
2275 if (pool)
2276 __tcp_free_md5sig_pool(pool);
2277}
2278
2279EXPORT_SYMBOL(tcp_free_md5sig_pool);
2280
2281static struct tcp_md5sig_pool **__tcp_alloc_md5sig_pool(void)
2282{
2283 int cpu;
2284 struct tcp_md5sig_pool **pool;
2285
2286 pool = alloc_percpu(struct tcp_md5sig_pool *);
2287 if (!pool)
2288 return NULL;
2289
2290 for_each_possible_cpu(cpu) {
2291 struct tcp_md5sig_pool *p;
2292 struct crypto_hash *hash;
2293
2294 p = kzalloc(sizeof(*p), GFP_KERNEL);
2295 if (!p)
2296 goto out_free;
2297 *per_cpu_ptr(pool, cpu) = p;
2298
2299 hash = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC);
2300 if (!hash || IS_ERR(hash))
2301 goto out_free;
2302
2303 p->md5_desc.tfm = hash;
2304 }
2305 return pool;
2306out_free:
2307 __tcp_free_md5sig_pool(pool);
2308 return NULL;
2309}
2310
2311struct tcp_md5sig_pool **tcp_alloc_md5sig_pool(void)
2312{
2313 struct tcp_md5sig_pool **pool;
2314 int alloc = 0;
2315
2316retry:
2317 spin_lock(&tcp_md5sig_pool_lock);
2318 pool = tcp_md5sig_pool;
2319 if (tcp_md5sig_users++ == 0) {
2320 alloc = 1;
2321 spin_unlock(&tcp_md5sig_pool_lock);
2322 } else if (!pool) {
2323 tcp_md5sig_users--;
2324 spin_unlock(&tcp_md5sig_pool_lock);
2325 cpu_relax();
2326 goto retry;
2327 } else
2328 spin_unlock(&tcp_md5sig_pool_lock);
2329
2330 if (alloc) {
2331 /* we cannot hold spinlock here because this may sleep. */
2332 struct tcp_md5sig_pool **p = __tcp_alloc_md5sig_pool();
2333 spin_lock(&tcp_md5sig_pool_lock);
2334 if (!p) {
2335 tcp_md5sig_users--;
2336 spin_unlock(&tcp_md5sig_pool_lock);
2337 return NULL;
2338 }
2339 pool = tcp_md5sig_pool;
2340 if (pool) {
2341 /* oops, it has already been assigned. */
2342 spin_unlock(&tcp_md5sig_pool_lock);
2343 __tcp_free_md5sig_pool(p);
2344 } else {
2345 tcp_md5sig_pool = pool = p;
2346 spin_unlock(&tcp_md5sig_pool_lock);
2347 }
2348 }
2349 return pool;
2350}
2351
2352EXPORT_SYMBOL(tcp_alloc_md5sig_pool);
2353
2354struct tcp_md5sig_pool *__tcp_get_md5sig_pool(int cpu)
2355{
2356 struct tcp_md5sig_pool **p;
2357 spin_lock(&tcp_md5sig_pool_lock);
2358 p = tcp_md5sig_pool;
2359 if (p)
2360 tcp_md5sig_users++;
2361 spin_unlock(&tcp_md5sig_pool_lock);
2362 return (p ? *per_cpu_ptr(p, cpu) : NULL);
2363}
2364
2365EXPORT_SYMBOL(__tcp_get_md5sig_pool);
2366
2367void __tcp_put_md5sig_pool(void)
2368{
2369 tcp_free_md5sig_pool();
2370}
2371
2372EXPORT_SYMBOL(__tcp_put_md5sig_pool);
2373#endif
2374
2234extern void __skb_cb_too_small_for_tcp(int, int); 2375extern void __skb_cb_too_small_for_tcp(int, int);
2235extern struct tcp_congestion_ops tcp_reno; 2376extern struct tcp_congestion_ops tcp_reno;
2236 2377
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c
index 1e2982f4ac..5ca7723d07 100644
--- a/net/ipv4/tcp_cong.c
+++ b/net/ipv4/tcp_cong.c
@@ -113,7 +113,7 @@ int tcp_set_default_congestion_control(const char *name)
113 spin_lock(&tcp_cong_list_lock); 113 spin_lock(&tcp_cong_list_lock);
114 ca = tcp_ca_find(name); 114 ca = tcp_ca_find(name);
115#ifdef CONFIG_KMOD 115#ifdef CONFIG_KMOD
116 if (!ca) { 116 if (!ca && capable(CAP_SYS_MODULE)) {
117 spin_unlock(&tcp_cong_list_lock); 117 spin_unlock(&tcp_cong_list_lock);
118 118
119 request_module("tcp_%s", name); 119 request_module("tcp_%s", name);
@@ -123,6 +123,7 @@ int tcp_set_default_congestion_control(const char *name)
123#endif 123#endif
124 124
125 if (ca) { 125 if (ca) {
126 ca->non_restricted = 1; /* default is always allowed */
126 list_move(&ca->list, &tcp_cong_list); 127 list_move(&ca->list, &tcp_cong_list);
127 ret = 0; 128 ret = 0;
128 } 129 }
@@ -139,6 +140,22 @@ static int __init tcp_congestion_default(void)
139late_initcall(tcp_congestion_default); 140late_initcall(tcp_congestion_default);
140 141
141 142
143/* Build string with list of available congestion control values */
144void tcp_get_available_congestion_control(char *buf, size_t maxlen)
145{
146 struct tcp_congestion_ops *ca;
147 size_t offs = 0;
148
149 rcu_read_lock();
150 list_for_each_entry_rcu(ca, &tcp_cong_list, list) {
151 offs += snprintf(buf + offs, maxlen - offs,
152 "%s%s",
153 offs == 0 ? "" : " ", ca->name);
154
155 }
156 rcu_read_unlock();
157}
158
142/* Get current default congestion control */ 159/* Get current default congestion control */
143void tcp_get_default_congestion_control(char *name) 160void tcp_get_default_congestion_control(char *name)
144{ 161{
@@ -152,6 +169,64 @@ void tcp_get_default_congestion_control(char *name)
152 rcu_read_unlock(); 169 rcu_read_unlock();
153} 170}
154 171
172/* Built list of non-restricted congestion control values */
173void tcp_get_allowed_congestion_control(char *buf, size_t maxlen)
174{
175 struct tcp_congestion_ops *ca;
176 size_t offs = 0;
177
178 *buf = '\0';
179 rcu_read_lock();
180 list_for_each_entry_rcu(ca, &tcp_cong_list, list) {
181 if (!ca->non_restricted)
182 continue;
183 offs += snprintf(buf + offs, maxlen - offs,
184 "%s%s",
185 offs == 0 ? "" : " ", ca->name);
186
187 }
188 rcu_read_unlock();
189}
190
191/* Change list of non-restricted congestion control */
192int tcp_set_allowed_congestion_control(char *val)
193{
194 struct tcp_congestion_ops *ca;
195 char *clone, *name;
196 int ret = 0;
197
198 clone = kstrdup(val, GFP_USER);
199 if (!clone)
200 return -ENOMEM;
201
202 spin_lock(&tcp_cong_list_lock);
203 /* pass 1 check for bad entries */
204 while ((name = strsep(&clone, " ")) && *name) {
205 ca = tcp_ca_find(name);
206 if (!ca) {
207 ret = -ENOENT;
208 goto out;
209 }
210 }
211
212 /* pass 2 clear */
213 list_for_each_entry_rcu(ca, &tcp_cong_list, list)
214 ca->non_restricted = 0;
215
216 /* pass 3 mark as allowed */
217 while ((name = strsep(&val, " ")) && *name) {
218 ca = tcp_ca_find(name);
219 WARN_ON(!ca);
220 if (ca)
221 ca->non_restricted = 1;
222 }
223out:
224 spin_unlock(&tcp_cong_list_lock);
225
226 return ret;
227}
228
229
155/* Change congestion control for socket */ 230/* Change congestion control for socket */
156int tcp_set_congestion_control(struct sock *sk, const char *name) 231int tcp_set_congestion_control(struct sock *sk, const char *name)
157{ 232{
@@ -161,12 +236,25 @@ int tcp_set_congestion_control(struct sock *sk, const char *name)
161 236
162 rcu_read_lock(); 237 rcu_read_lock();
163 ca = tcp_ca_find(name); 238 ca = tcp_ca_find(name);
239 /* no change asking for existing value */
164 if (ca == icsk->icsk_ca_ops) 240 if (ca == icsk->icsk_ca_ops)
165 goto out; 241 goto out;
166 242
243#ifdef CONFIG_KMOD
244 /* not found attempt to autoload module */
245 if (!ca && capable(CAP_SYS_MODULE)) {
246 rcu_read_unlock();
247 request_module("tcp_%s", name);
248 rcu_read_lock();
249 ca = tcp_ca_find(name);
250 }
251#endif
167 if (!ca) 252 if (!ca)
168 err = -ENOENT; 253 err = -ENOENT;
169 254
255 else if (!(ca->non_restricted || capable(CAP_NET_ADMIN)))
256 err = -EPERM;
257
170 else if (!try_module_get(ca->owner)) 258 else if (!try_module_get(ca->owner))
171 err = -EBUSY; 259 err = -EBUSY;
172 260
@@ -268,6 +356,7 @@ EXPORT_SYMBOL_GPL(tcp_reno_min_cwnd);
268 356
269struct tcp_congestion_ops tcp_reno = { 357struct tcp_congestion_ops tcp_reno = {
270 .name = "reno", 358 .name = "reno",
359 .non_restricted = 1,
271 .owner = THIS_MODULE, 360 .owner = THIS_MODULE,
272 .ssthresh = tcp_reno_ssthresh, 361 .ssthresh = tcp_reno_ssthresh,
273 .cong_avoid = tcp_reno_cong_avoid, 362 .cong_avoid = tcp_reno_cong_avoid,
diff --git a/net/ipv4/tcp_htcp.c b/net/ipv4/tcp_htcp.c
index 283be3cb46..753987a104 100644
--- a/net/ipv4/tcp_htcp.c
+++ b/net/ipv4/tcp_htcp.c
@@ -26,12 +26,12 @@ struct htcp {
26 u32 alpha; /* Fixed point arith, << 7 */ 26 u32 alpha; /* Fixed point arith, << 7 */
27 u8 beta; /* Fixed point arith, << 7 */ 27 u8 beta; /* Fixed point arith, << 7 */
28 u8 modeswitch; /* Delay modeswitch until we had at least one congestion event */ 28 u8 modeswitch; /* Delay modeswitch until we had at least one congestion event */
29 u32 last_cong; /* Time since last congestion event end */
30 u32 undo_last_cong;
31 u16 pkts_acked; 29 u16 pkts_acked;
32 u32 packetcount; 30 u32 packetcount;
33 u32 minRTT; 31 u32 minRTT;
34 u32 maxRTT; 32 u32 maxRTT;
33 u32 last_cong; /* Time since last congestion event end */
34 u32 undo_last_cong;
35 35
36 u32 undo_maxRTT; 36 u32 undo_maxRTT;
37 u32 undo_old_maxB; 37 u32 undo_old_maxB;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index cf06accbe6..c701f6abbf 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2677,6 +2677,14 @@ void tcp_parse_options(struct sk_buff *skb, struct tcp_options_received *opt_rx,
2677 opt_rx->sack_ok) { 2677 opt_rx->sack_ok) {
2678 TCP_SKB_CB(skb)->sacked = (ptr - 2) - (unsigned char *)th; 2678 TCP_SKB_CB(skb)->sacked = (ptr - 2) - (unsigned char *)th;
2679 } 2679 }
2680#ifdef CONFIG_TCP_MD5SIG
2681 case TCPOPT_MD5SIG:
2682 /*
2683 * The MD5 Hash has already been
2684 * checked (see tcp_v{4,6}_do_rcv()).
2685 */
2686 break;
2687#endif
2680 }; 2688 };
2681 ptr+=opsize-2; 2689 ptr+=opsize-2;
2682 length-=opsize; 2690 length-=opsize;
@@ -3782,9 +3790,9 @@ static int tcp_copy_to_iovec(struct sock *sk, struct sk_buff *skb, int hlen)
3782 return err; 3790 return err;
3783} 3791}
3784 3792
3785static int __tcp_checksum_complete_user(struct sock *sk, struct sk_buff *skb) 3793static __sum16 __tcp_checksum_complete_user(struct sock *sk, struct sk_buff *skb)
3786{ 3794{
3787 int result; 3795 __sum16 result;
3788 3796
3789 if (sock_owned_by_user(sk)) { 3797 if (sock_owned_by_user(sk)) {
3790 local_bh_enable(); 3798 local_bh_enable();
@@ -4227,9 +4235,11 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
4227 * Change state from SYN-SENT only after copied_seq 4235 * Change state from SYN-SENT only after copied_seq
4228 * is initialized. */ 4236 * is initialized. */
4229 tp->copied_seq = tp->rcv_nxt; 4237 tp->copied_seq = tp->rcv_nxt;
4230 mb(); 4238 smp_mb();
4231 tcp_set_state(sk, TCP_ESTABLISHED); 4239 tcp_set_state(sk, TCP_ESTABLISHED);
4232 4240
4241 security_inet_conn_established(sk, skb);
4242
4233 /* Make sure socket is routed, for correct metrics. */ 4243 /* Make sure socket is routed, for correct metrics. */
4234 icsk->icsk_af_ops->rebuild_header(sk); 4244 icsk->icsk_af_ops->rebuild_header(sk);
4235 4245
@@ -4473,7 +4483,7 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
4473 case TCP_SYN_RECV: 4483 case TCP_SYN_RECV:
4474 if (acceptable) { 4484 if (acceptable) {
4475 tp->copied_seq = tp->rcv_nxt; 4485 tp->copied_seq = tp->rcv_nxt;
4476 mb(); 4486 smp_mb();
4477 tcp_set_state(sk, TCP_ESTABLISHED); 4487 tcp_set_state(sk, TCP_ESTABLISHED);
4478 sk->sk_state_change(sk); 4488 sk->sk_state_change(sk);
4479 4489
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 22ef8bd266..12de90a504 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -78,6 +78,9 @@
78#include <linux/proc_fs.h> 78#include <linux/proc_fs.h>
79#include <linux/seq_file.h> 79#include <linux/seq_file.h>
80 80
81#include <linux/crypto.h>
82#include <linux/scatterlist.h>
83
81int sysctl_tcp_tw_reuse __read_mostly; 84int sysctl_tcp_tw_reuse __read_mostly;
82int sysctl_tcp_low_latency __read_mostly; 85int sysctl_tcp_low_latency __read_mostly;
83 86
@@ -89,10 +92,19 @@ static struct socket *tcp_socket;
89 92
90void tcp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb); 93void tcp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb);
91 94
95#ifdef CONFIG_TCP_MD5SIG
96static struct tcp_md5sig_key *tcp_v4_md5_do_lookup(struct sock *sk,
97 __be32 addr);
98static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
99 __be32 saddr, __be32 daddr,
100 struct tcphdr *th, int protocol,
101 int tcplen);
102#endif
103
92struct inet_hashinfo __cacheline_aligned tcp_hashinfo = { 104struct inet_hashinfo __cacheline_aligned tcp_hashinfo = {
93 .lhash_lock = __RW_LOCK_UNLOCKED(tcp_hashinfo.lhash_lock), 105 .lhash_lock = __RW_LOCK_UNLOCKED(tcp_hashinfo.lhash_lock),
94 .lhash_users = ATOMIC_INIT(0), 106 .lhash_users = ATOMIC_INIT(0),
95 .lhash_wait = __WAIT_QUEUE_HEAD_INITIALIZER(tcp_hashinfo.lhash_wait), 107 .lhash_wait = __WAIT_QUEUE_HEAD_INITIALIZER(tcp_hashinfo.lhash_wait),
96}; 108};
97 109
98static int tcp_v4_get_port(struct sock *sk, unsigned short snum) 110static int tcp_v4_get_port(struct sock *sk, unsigned short snum)
@@ -111,7 +123,7 @@ void tcp_unhash(struct sock *sk)
111 inet_unhash(&tcp_hashinfo, sk); 123 inet_unhash(&tcp_hashinfo, sk);
112} 124}
113 125
114static inline __u32 tcp_v4_init_sequence(struct sock *sk, struct sk_buff *skb) 126static inline __u32 tcp_v4_init_sequence(struct sk_buff *skb)
115{ 127{
116 return secure_tcp_sequence_number(skb->nh.iph->daddr, 128 return secure_tcp_sequence_number(skb->nh.iph->daddr,
117 skb->nh.iph->saddr, 129 skb->nh.iph->saddr,
@@ -205,13 +217,14 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
205 if (tcp_death_row.sysctl_tw_recycle && 217 if (tcp_death_row.sysctl_tw_recycle &&
206 !tp->rx_opt.ts_recent_stamp && rt->rt_dst == daddr) { 218 !tp->rx_opt.ts_recent_stamp && rt->rt_dst == daddr) {
207 struct inet_peer *peer = rt_get_peer(rt); 219 struct inet_peer *peer = rt_get_peer(rt);
208 220 /*
209 /* VJ's idea. We save last timestamp seen from 221 * VJ's idea. We save last timestamp seen from
210 * the destination in peer table, when entering state TIME-WAIT 222 * the destination in peer table, when entering state
211 * and initialize rx_opt.ts_recent from it, when trying new connection. 223 * TIME-WAIT * and initialize rx_opt.ts_recent from it,
224 * when trying new connection.
212 */ 225 */
213 226 if (peer != NULL &&
214 if (peer && peer->tcp_ts_stamp + TCP_PAWS_MSL >= xtime.tv_sec) { 227 peer->tcp_ts_stamp + TCP_PAWS_MSL >= xtime.tv_sec) {
215 tp->rx_opt.ts_recent_stamp = peer->tcp_ts_stamp; 228 tp->rx_opt.ts_recent_stamp = peer->tcp_ts_stamp;
216 tp->rx_opt.ts_recent = peer->tcp_ts; 229 tp->rx_opt.ts_recent = peer->tcp_ts;
217 } 230 }
@@ -236,7 +249,8 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
236 if (err) 249 if (err)
237 goto failure; 250 goto failure;
238 251
239 err = ip_route_newports(&rt, IPPROTO_TCP, inet->sport, inet->dport, sk); 252 err = ip_route_newports(&rt, IPPROTO_TCP,
253 inet->sport, inet->dport, sk);
240 if (err) 254 if (err)
241 goto failure; 255 goto failure;
242 256
@@ -260,7 +274,10 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
260 return 0; 274 return 0;
261 275
262failure: 276failure:
263 /* This unhashes the socket and releases the local port, if necessary. */ 277 /*
278 * This unhashes the socket and releases the local port,
279 * if necessary.
280 */
264 tcp_set_state(sk, TCP_CLOSE); 281 tcp_set_state(sk, TCP_CLOSE);
265 ip_rt_put(rt); 282 ip_rt_put(rt);
266 sk->sk_route_caps = 0; 283 sk->sk_route_caps = 0;
@@ -485,8 +502,9 @@ void tcp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb)
485 struct tcphdr *th = skb->h.th; 502 struct tcphdr *th = skb->h.th;
486 503
487 if (skb->ip_summed == CHECKSUM_PARTIAL) { 504 if (skb->ip_summed == CHECKSUM_PARTIAL) {
488 th->check = ~tcp_v4_check(th, len, inet->saddr, inet->daddr, 0); 505 th->check = ~tcp_v4_check(th, len,
489 skb->csum = offsetof(struct tcphdr, check); 506 inet->saddr, inet->daddr, 0);
507 skb->csum_offset = offsetof(struct tcphdr, check);
490 } else { 508 } else {
491 th->check = tcp_v4_check(th, len, inet->saddr, inet->daddr, 509 th->check = tcp_v4_check(th, len, inet->saddr, inet->daddr,
492 csum_partial((char *)th, 510 csum_partial((char *)th,
@@ -508,7 +526,7 @@ int tcp_v4_gso_send_check(struct sk_buff *skb)
508 526
509 th->check = 0; 527 th->check = 0;
510 th->check = ~tcp_v4_check(th, skb->len, iph->saddr, iph->daddr, 0); 528 th->check = ~tcp_v4_check(th, skb->len, iph->saddr, iph->daddr, 0);
511 skb->csum = offsetof(struct tcphdr, check); 529 skb->csum_offset = offsetof(struct tcphdr, check);
512 skb->ip_summed = CHECKSUM_PARTIAL; 530 skb->ip_summed = CHECKSUM_PARTIAL;
513 return 0; 531 return 0;
514} 532}
@@ -526,11 +544,19 @@ int tcp_v4_gso_send_check(struct sk_buff *skb)
526 * Exception: precedence violation. We do not implement it in any case. 544 * Exception: precedence violation. We do not implement it in any case.
527 */ 545 */
528 546
529static void tcp_v4_send_reset(struct sk_buff *skb) 547static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
530{ 548{
531 struct tcphdr *th = skb->h.th; 549 struct tcphdr *th = skb->h.th;
532 struct tcphdr rth; 550 struct {
551 struct tcphdr th;
552#ifdef CONFIG_TCP_MD5SIG
553 __be32 opt[(TCPOLEN_MD5SIG_ALIGNED >> 2)];
554#endif
555 } rep;
533 struct ip_reply_arg arg; 556 struct ip_reply_arg arg;
557#ifdef CONFIG_TCP_MD5SIG
558 struct tcp_md5sig_key *key;
559#endif
534 560
535 /* Never send a reset in response to a reset. */ 561 /* Never send a reset in response to a reset. */
536 if (th->rst) 562 if (th->rst)
@@ -540,29 +566,49 @@ static void tcp_v4_send_reset(struct sk_buff *skb)
540 return; 566 return;
541 567
542 /* Swap the send and the receive. */ 568 /* Swap the send and the receive. */
543 memset(&rth, 0, sizeof(struct tcphdr)); 569 memset(&rep, 0, sizeof(rep));
544 rth.dest = th->source; 570 rep.th.dest = th->source;
545 rth.source = th->dest; 571 rep.th.source = th->dest;
546 rth.doff = sizeof(struct tcphdr) / 4; 572 rep.th.doff = sizeof(struct tcphdr) / 4;
547 rth.rst = 1; 573 rep.th.rst = 1;
548 574
549 if (th->ack) { 575 if (th->ack) {
550 rth.seq = th->ack_seq; 576 rep.th.seq = th->ack_seq;
551 } else { 577 } else {
552 rth.ack = 1; 578 rep.th.ack = 1;
553 rth.ack_seq = htonl(ntohl(th->seq) + th->syn + th->fin + 579 rep.th.ack_seq = htonl(ntohl(th->seq) + th->syn + th->fin +
554 skb->len - (th->doff << 2)); 580 skb->len - (th->doff << 2));
555 } 581 }
556 582
557 memset(&arg, 0, sizeof arg); 583 memset(&arg, 0, sizeof(arg));
558 arg.iov[0].iov_base = (unsigned char *)&rth; 584 arg.iov[0].iov_base = (unsigned char *)&rep;
559 arg.iov[0].iov_len = sizeof rth; 585 arg.iov[0].iov_len = sizeof(rep.th);
586
587#ifdef CONFIG_TCP_MD5SIG
588 key = sk ? tcp_v4_md5_do_lookup(sk, skb->nh.iph->daddr) : NULL;
589 if (key) {
590 rep.opt[0] = htonl((TCPOPT_NOP << 24) |
591 (TCPOPT_NOP << 16) |
592 (TCPOPT_MD5SIG << 8) |
593 TCPOLEN_MD5SIG);
594 /* Update length and the length the header thinks exists */
595 arg.iov[0].iov_len += TCPOLEN_MD5SIG_ALIGNED;
596 rep.th.doff = arg.iov[0].iov_len / 4;
597
598 tcp_v4_do_calc_md5_hash((__u8 *)&rep.opt[1],
599 key,
600 skb->nh.iph->daddr,
601 skb->nh.iph->saddr,
602 &rep.th, IPPROTO_TCP,
603 arg.iov[0].iov_len);
604 }
605#endif
560 arg.csum = csum_tcpudp_nofold(skb->nh.iph->daddr, 606 arg.csum = csum_tcpudp_nofold(skb->nh.iph->daddr,
561 skb->nh.iph->saddr, /*XXX*/ 607 skb->nh.iph->saddr, /* XXX */
562 sizeof(struct tcphdr), IPPROTO_TCP, 0); 608 sizeof(struct tcphdr), IPPROTO_TCP, 0);
563 arg.csumoffset = offsetof(struct tcphdr, check) / 2; 609 arg.csumoffset = offsetof(struct tcphdr, check) / 2;
564 610
565 ip_send_reply(tcp_socket->sk, skb, &arg, sizeof rth); 611 ip_send_reply(tcp_socket->sk, skb, &arg, arg.iov[0].iov_len);
566 612
567 TCP_INC_STATS_BH(TCP_MIB_OUTSEGS); 613 TCP_INC_STATS_BH(TCP_MIB_OUTSEGS);
568 TCP_INC_STATS_BH(TCP_MIB_OUTRSTS); 614 TCP_INC_STATS_BH(TCP_MIB_OUTRSTS);
@@ -572,28 +618,37 @@ static void tcp_v4_send_reset(struct sk_buff *skb)
572 outside socket context is ugly, certainly. What can I do? 618 outside socket context is ugly, certainly. What can I do?
573 */ 619 */
574 620
575static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack, 621static void tcp_v4_send_ack(struct tcp_timewait_sock *twsk,
622 struct sk_buff *skb, u32 seq, u32 ack,
576 u32 win, u32 ts) 623 u32 win, u32 ts)
577{ 624{
578 struct tcphdr *th = skb->h.th; 625 struct tcphdr *th = skb->h.th;
579 struct { 626 struct {
580 struct tcphdr th; 627 struct tcphdr th;
581 u32 tsopt[TCPOLEN_TSTAMP_ALIGNED >> 2]; 628 __be32 opt[(TCPOLEN_TSTAMP_ALIGNED >> 2)
629#ifdef CONFIG_TCP_MD5SIG
630 + (TCPOLEN_MD5SIG_ALIGNED >> 2)
631#endif
632 ];
582 } rep; 633 } rep;
583 struct ip_reply_arg arg; 634 struct ip_reply_arg arg;
635#ifdef CONFIG_TCP_MD5SIG
636 struct tcp_md5sig_key *key;
637 struct tcp_md5sig_key tw_key;
638#endif
584 639
585 memset(&rep.th, 0, sizeof(struct tcphdr)); 640 memset(&rep.th, 0, sizeof(struct tcphdr));
586 memset(&arg, 0, sizeof arg); 641 memset(&arg, 0, sizeof(arg));
587 642
588 arg.iov[0].iov_base = (unsigned char *)&rep; 643 arg.iov[0].iov_base = (unsigned char *)&rep;
589 arg.iov[0].iov_len = sizeof(rep.th); 644 arg.iov[0].iov_len = sizeof(rep.th);
590 if (ts) { 645 if (ts) {
591 rep.tsopt[0] = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | 646 rep.opt[0] = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
592 (TCPOPT_TIMESTAMP << 8) | 647 (TCPOPT_TIMESTAMP << 8) |
593 TCPOLEN_TIMESTAMP); 648 TCPOLEN_TIMESTAMP);
594 rep.tsopt[1] = htonl(tcp_time_stamp); 649 rep.opt[1] = htonl(tcp_time_stamp);
595 rep.tsopt[2] = htonl(ts); 650 rep.opt[2] = htonl(ts);
596 arg.iov[0].iov_len = sizeof(rep); 651 arg.iov[0].iov_len += TCPOLEN_TSTAMP_ALIGNED;
597 } 652 }
598 653
599 /* Swap the send and the receive. */ 654 /* Swap the send and the receive. */
@@ -605,8 +660,44 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
605 rep.th.ack = 1; 660 rep.th.ack = 1;
606 rep.th.window = htons(win); 661 rep.th.window = htons(win);
607 662
663#ifdef CONFIG_TCP_MD5SIG
664 /*
665 * The SKB holds an imcoming packet, but may not have a valid ->sk
666 * pointer. This is especially the case when we're dealing with a
667 * TIME_WAIT ack, because the sk structure is long gone, and only
668 * the tcp_timewait_sock remains. So the md5 key is stashed in that
669 * structure, and we use it in preference. I believe that (twsk ||
670 * skb->sk) holds true, but we program defensively.
671 */
672 if (!twsk && skb->sk) {
673 key = tcp_v4_md5_do_lookup(skb->sk, skb->nh.iph->daddr);
674 } else if (twsk && twsk->tw_md5_keylen) {
675 tw_key.key = twsk->tw_md5_key;
676 tw_key.keylen = twsk->tw_md5_keylen;
677 key = &tw_key;
678 } else
679 key = NULL;
680
681 if (key) {
682 int offset = (ts) ? 3 : 0;
683
684 rep.opt[offset++] = htonl((TCPOPT_NOP << 24) |
685 (TCPOPT_NOP << 16) |
686 (TCPOPT_MD5SIG << 8) |
687 TCPOLEN_MD5SIG);
688 arg.iov[0].iov_len += TCPOLEN_MD5SIG_ALIGNED;
689 rep.th.doff = arg.iov[0].iov_len/4;
690
691 tcp_v4_do_calc_md5_hash((__u8 *)&rep.opt[offset],
692 key,
693 skb->nh.iph->daddr,
694 skb->nh.iph->saddr,
695 &rep.th, IPPROTO_TCP,
696 arg.iov[0].iov_len);
697 }
698#endif
608 arg.csum = csum_tcpudp_nofold(skb->nh.iph->daddr, 699 arg.csum = csum_tcpudp_nofold(skb->nh.iph->daddr,
609 skb->nh.iph->saddr, /*XXX*/ 700 skb->nh.iph->saddr, /* XXX */
610 arg.iov[0].iov_len, IPPROTO_TCP, 0); 701 arg.iov[0].iov_len, IPPROTO_TCP, 0);
611 arg.csumoffset = offsetof(struct tcphdr, check) / 2; 702 arg.csumoffset = offsetof(struct tcphdr, check) / 2;
612 703
@@ -618,17 +709,20 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
618static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb) 709static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb)
619{ 710{
620 struct inet_timewait_sock *tw = inet_twsk(sk); 711 struct inet_timewait_sock *tw = inet_twsk(sk);
621 const struct tcp_timewait_sock *tcptw = tcp_twsk(sk); 712 struct tcp_timewait_sock *tcptw = tcp_twsk(sk);
622 713
623 tcp_v4_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, 714 tcp_v4_send_ack(tcptw, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
624 tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, tcptw->tw_ts_recent); 715 tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
716 tcptw->tw_ts_recent);
625 717
626 inet_twsk_put(tw); 718 inet_twsk_put(tw);
627} 719}
628 720
629static void tcp_v4_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req) 721static void tcp_v4_reqsk_send_ack(struct sk_buff *skb,
722 struct request_sock *req)
630{ 723{
631 tcp_v4_send_ack(skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, 724 tcp_v4_send_ack(NULL, skb, tcp_rsk(req)->snt_isn + 1,
725 tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd,
632 req->ts_recent); 726 req->ts_recent);
633} 727}
634 728
@@ -662,8 +756,7 @@ static int tcp_v4_send_synack(struct sock *sk, struct request_sock *req,
662 err = ip_build_and_send_pkt(skb, sk, ireq->loc_addr, 756 err = ip_build_and_send_pkt(skb, sk, ireq->loc_addr,
663 ireq->rmt_addr, 757 ireq->rmt_addr,
664 ireq->opt); 758 ireq->opt);
665 if (err == NET_XMIT_CN) 759 err = net_xmit_eval(err);
666 err = 0;
667 } 760 }
668 761
669out: 762out:
@@ -715,7 +808,424 @@ static struct ip_options *tcp_v4_save_options(struct sock *sk,
715 return dopt; 808 return dopt;
716} 809}
717 810
718struct request_sock_ops tcp_request_sock_ops = { 811#ifdef CONFIG_TCP_MD5SIG
812/*
813 * RFC2385 MD5 checksumming requires a mapping of
814 * IP address->MD5 Key.
815 * We need to maintain these in the sk structure.
816 */
817
818/* Find the Key structure for an address. */
819static struct tcp_md5sig_key *
820 tcp_v4_md5_do_lookup(struct sock *sk, __be32 addr)
821{
822 struct tcp_sock *tp = tcp_sk(sk);
823 int i;
824
825 if (!tp->md5sig_info || !tp->md5sig_info->entries4)
826 return NULL;
827 for (i = 0; i < tp->md5sig_info->entries4; i++) {
828 if (tp->md5sig_info->keys4[i].addr == addr)
829 return (struct tcp_md5sig_key *)
830 &tp->md5sig_info->keys4[i];
831 }
832 return NULL;
833}
834
835struct tcp_md5sig_key *tcp_v4_md5_lookup(struct sock *sk,
836 struct sock *addr_sk)
837{
838 return tcp_v4_md5_do_lookup(sk, inet_sk(addr_sk)->daddr);
839}
840
841EXPORT_SYMBOL(tcp_v4_md5_lookup);
842
843static struct tcp_md5sig_key *tcp_v4_reqsk_md5_lookup(struct sock *sk,
844 struct request_sock *req)
845{
846 return tcp_v4_md5_do_lookup(sk, inet_rsk(req)->rmt_addr);
847}
848
849/* This can be called on a newly created socket, from other files */
850int tcp_v4_md5_do_add(struct sock *sk, __be32 addr,
851 u8 *newkey, u8 newkeylen)
852{
853 /* Add Key to the list */
854 struct tcp4_md5sig_key *key;
855 struct tcp_sock *tp = tcp_sk(sk);
856 struct tcp4_md5sig_key *keys;
857
858 key = (struct tcp4_md5sig_key *)tcp_v4_md5_do_lookup(sk, addr);
859 if (key) {
860 /* Pre-existing entry - just update that one. */
861 kfree(key->key);
862 key->key = newkey;
863 key->keylen = newkeylen;
864 } else {
865 struct tcp_md5sig_info *md5sig;
866
867 if (!tp->md5sig_info) {
868 tp->md5sig_info = kzalloc(sizeof(*tp->md5sig_info),
869 GFP_ATOMIC);
870 if (!tp->md5sig_info) {
871 kfree(newkey);
872 return -ENOMEM;
873 }
874 }
875 if (tcp_alloc_md5sig_pool() == NULL) {
876 kfree(newkey);
877 return -ENOMEM;
878 }
879 md5sig = tp->md5sig_info;
880
881 if (md5sig->alloced4 == md5sig->entries4) {
882 keys = kmalloc((sizeof(*keys) *
883 (md5sig->entries4 + 1)), GFP_ATOMIC);
884 if (!keys) {
885 kfree(newkey);
886 tcp_free_md5sig_pool();
887 return -ENOMEM;
888 }
889
890 if (md5sig->entries4)
891 memcpy(keys, md5sig->keys4,
892 sizeof(*keys) * md5sig->entries4);
893
894 /* Free old key list, and reference new one */
895 if (md5sig->keys4)
896 kfree(md5sig->keys4);
897 md5sig->keys4 = keys;
898 md5sig->alloced4++;
899 }
900 md5sig->entries4++;
901 md5sig->keys4[md5sig->entries4 - 1].addr = addr;
902 md5sig->keys4[md5sig->entries4 - 1].key = newkey;
903 md5sig->keys4[md5sig->entries4 - 1].keylen = newkeylen;
904 }
905 return 0;
906}
907
908EXPORT_SYMBOL(tcp_v4_md5_do_add);
909
910static int tcp_v4_md5_add_func(struct sock *sk, struct sock *addr_sk,
911 u8 *newkey, u8 newkeylen)
912{
913 return tcp_v4_md5_do_add(sk, inet_sk(addr_sk)->daddr,
914 newkey, newkeylen);
915}
916
917int tcp_v4_md5_do_del(struct sock *sk, __be32 addr)
918{
919 struct tcp_sock *tp = tcp_sk(sk);
920 int i;
921
922 for (i = 0; i < tp->md5sig_info->entries4; i++) {
923 if (tp->md5sig_info->keys4[i].addr == addr) {
924 /* Free the key */
925 kfree(tp->md5sig_info->keys4[i].key);
926 tp->md5sig_info->entries4--;
927
928 if (tp->md5sig_info->entries4 == 0) {
929 kfree(tp->md5sig_info->keys4);
930 tp->md5sig_info->keys4 = NULL;
931 tp->md5sig_info->alloced4 = 0;
932 } else if (tp->md5sig_info->entries4 != i) {
933 /* Need to do some manipulation */
934 memcpy(&tp->md5sig_info->keys4[i],
935 &tp->md5sig_info->keys4[i+1],
936 (tp->md5sig_info->entries4 - i) *
937 sizeof(struct tcp4_md5sig_key));
938 }
939 tcp_free_md5sig_pool();
940 return 0;
941 }
942 }
943 return -ENOENT;
944}
945
946EXPORT_SYMBOL(tcp_v4_md5_do_del);
947
948static void tcp_v4_clear_md5_list(struct sock *sk)
949{
950 struct tcp_sock *tp = tcp_sk(sk);
951
952 /* Free each key, then the set of key keys,
953 * the crypto element, and then decrement our
954 * hold on the last resort crypto.
955 */
956 if (tp->md5sig_info->entries4) {
957 int i;
958 for (i = 0; i < tp->md5sig_info->entries4; i++)
959 kfree(tp->md5sig_info->keys4[i].key);
960 tp->md5sig_info->entries4 = 0;
961 tcp_free_md5sig_pool();
962 }
963 if (tp->md5sig_info->keys4) {
964 kfree(tp->md5sig_info->keys4);
965 tp->md5sig_info->keys4 = NULL;
966 tp->md5sig_info->alloced4 = 0;
967 }
968}
969
970static int tcp_v4_parse_md5_keys(struct sock *sk, char __user *optval,
971 int optlen)
972{
973 struct tcp_md5sig cmd;
974 struct sockaddr_in *sin = (struct sockaddr_in *)&cmd.tcpm_addr;
975 u8 *newkey;
976
977 if (optlen < sizeof(cmd))
978 return -EINVAL;
979
980 if (copy_from_user(&cmd, optval, sizeof(cmd)))
981 return -EFAULT;
982
983 if (sin->sin_family != AF_INET)
984 return -EINVAL;
985
986 if (!cmd.tcpm_key || !cmd.tcpm_keylen) {
987 if (!tcp_sk(sk)->md5sig_info)
988 return -ENOENT;
989 return tcp_v4_md5_do_del(sk, sin->sin_addr.s_addr);
990 }
991
992 if (cmd.tcpm_keylen > TCP_MD5SIG_MAXKEYLEN)
993 return -EINVAL;
994
995 if (!tcp_sk(sk)->md5sig_info) {
996 struct tcp_sock *tp = tcp_sk(sk);
997 struct tcp_md5sig_info *p = kzalloc(sizeof(*p), GFP_KERNEL);
998
999 if (!p)
1000 return -EINVAL;
1001
1002 tp->md5sig_info = p;
1003
1004 }
1005
1006 newkey = kmemdup(cmd.tcpm_key, cmd.tcpm_keylen, GFP_KERNEL);
1007 if (!newkey)
1008 return -ENOMEM;
1009 return tcp_v4_md5_do_add(sk, sin->sin_addr.s_addr,
1010 newkey, cmd.tcpm_keylen);
1011}
1012
1013static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
1014 __be32 saddr, __be32 daddr,
1015 struct tcphdr *th, int protocol,
1016 int tcplen)
1017{
1018 struct scatterlist sg[4];
1019 __u16 data_len;
1020 int block = 0;
1021 __sum16 old_checksum;
1022 struct tcp_md5sig_pool *hp;
1023 struct tcp4_pseudohdr *bp;
1024 struct hash_desc *desc;
1025 int err;
1026 unsigned int nbytes = 0;
1027
1028 /*
1029 * Okay, so RFC2385 is turned on for this connection,
1030 * so we need to generate the MD5 hash for the packet now.
1031 */
1032
1033 hp = tcp_get_md5sig_pool();
1034 if (!hp)
1035 goto clear_hash_noput;
1036
1037 bp = &hp->md5_blk.ip4;
1038 desc = &hp->md5_desc;
1039
1040 /*
1041 * 1. the TCP pseudo-header (in the order: source IP address,
1042 * destination IP address, zero-padded protocol number, and
1043 * segment length)
1044 */
1045 bp->saddr = saddr;
1046 bp->daddr = daddr;
1047 bp->pad = 0;
1048 bp->protocol = protocol;
1049 bp->len = htons(tcplen);
1050 sg_set_buf(&sg[block++], bp, sizeof(*bp));
1051 nbytes += sizeof(*bp);
1052
1053 /* 2. the TCP header, excluding options, and assuming a
1054 * checksum of zero/
1055 */
1056 old_checksum = th->check;
1057 th->check = 0;
1058 sg_set_buf(&sg[block++], th, sizeof(struct tcphdr));
1059 nbytes += sizeof(struct tcphdr);
1060
1061 /* 3. the TCP segment data (if any) */
1062 data_len = tcplen - (th->doff << 2);
1063 if (data_len > 0) {
1064 unsigned char *data = (unsigned char *)th + (th->doff << 2);
1065 sg_set_buf(&sg[block++], data, data_len);
1066 nbytes += data_len;
1067 }
1068
1069 /* 4. an independently-specified key or password, known to both
1070 * TCPs and presumably connection-specific
1071 */
1072 sg_set_buf(&sg[block++], key->key, key->keylen);
1073 nbytes += key->keylen;
1074
1075 /* Now store the Hash into the packet */
1076 err = crypto_hash_init(desc);
1077 if (err)
1078 goto clear_hash;
1079 err = crypto_hash_update(desc, sg, nbytes);
1080 if (err)
1081 goto clear_hash;
1082 err = crypto_hash_final(desc, md5_hash);
1083 if (err)
1084 goto clear_hash;
1085
1086 /* Reset header, and free up the crypto */
1087 tcp_put_md5sig_pool();
1088 th->check = old_checksum;
1089
1090out:
1091 return 0;
1092clear_hash:
1093 tcp_put_md5sig_pool();
1094clear_hash_noput:
1095 memset(md5_hash, 0, 16);
1096 goto out;
1097}
1098
1099int tcp_v4_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
1100 struct sock *sk,
1101 struct dst_entry *dst,
1102 struct request_sock *req,
1103 struct tcphdr *th, int protocol,
1104 int tcplen)
1105{
1106 __be32 saddr, daddr;
1107
1108 if (sk) {
1109 saddr = inet_sk(sk)->saddr;
1110 daddr = inet_sk(sk)->daddr;
1111 } else {
1112 struct rtable *rt = (struct rtable *)dst;
1113 BUG_ON(!rt);
1114 saddr = rt->rt_src;
1115 daddr = rt->rt_dst;
1116 }
1117 return tcp_v4_do_calc_md5_hash(md5_hash, key,
1118 saddr, daddr,
1119 th, protocol, tcplen);
1120}
1121
1122EXPORT_SYMBOL(tcp_v4_calc_md5_hash);
1123
1124static int tcp_v4_inbound_md5_hash(struct sock *sk, struct sk_buff *skb)
1125{
1126 /*
1127 * This gets called for each TCP segment that arrives
1128 * so we want to be efficient.
1129 * We have 3 drop cases:
1130 * o No MD5 hash and one expected.
1131 * o MD5 hash and we're not expecting one.
1132 * o MD5 hash and its wrong.
1133 */
1134 __u8 *hash_location = NULL;
1135 struct tcp_md5sig_key *hash_expected;
1136 struct iphdr *iph = skb->nh.iph;
1137 struct tcphdr *th = skb->h.th;
1138 int length = (th->doff << 2) - sizeof(struct tcphdr);
1139 int genhash;
1140 unsigned char *ptr;
1141 unsigned char newhash[16];
1142
1143 hash_expected = tcp_v4_md5_do_lookup(sk, iph->saddr);
1144
1145 /*
1146 * If the TCP option length is less than the TCP_MD5SIG
1147 * option length, then we can shortcut
1148 */
1149 if (length < TCPOLEN_MD5SIG) {
1150 if (hash_expected)
1151 return 1;
1152 else
1153 return 0;
1154 }
1155
1156 /* Okay, we can't shortcut - we have to grub through the options */
1157 ptr = (unsigned char *)(th + 1);
1158 while (length > 0) {
1159 int opcode = *ptr++;
1160 int opsize;
1161
1162 switch (opcode) {
1163 case TCPOPT_EOL:
1164 goto done_opts;
1165 case TCPOPT_NOP:
1166 length--;
1167 continue;
1168 default:
1169 opsize = *ptr++;
1170 if (opsize < 2)
1171 goto done_opts;
1172 if (opsize > length)
1173 goto done_opts;
1174
1175 if (opcode == TCPOPT_MD5SIG) {
1176 hash_location = ptr;
1177 goto done_opts;
1178 }
1179 }
1180 ptr += opsize-2;
1181 length -= opsize;
1182 }
1183done_opts:
1184 /* We've parsed the options - do we have a hash? */
1185 if (!hash_expected && !hash_location)
1186 return 0;
1187
1188 if (hash_expected && !hash_location) {
1189 LIMIT_NETDEBUG(KERN_INFO "MD5 Hash expected but NOT found "
1190 "(" NIPQUAD_FMT ", %d)->(" NIPQUAD_FMT ", %d)\n",
1191 NIPQUAD(iph->saddr), ntohs(th->source),
1192 NIPQUAD(iph->daddr), ntohs(th->dest));
1193 return 1;
1194 }
1195
1196 if (!hash_expected && hash_location) {
1197 LIMIT_NETDEBUG(KERN_INFO "MD5 Hash NOT expected but found "
1198 "(" NIPQUAD_FMT ", %d)->(" NIPQUAD_FMT ", %d)\n",
1199 NIPQUAD(iph->saddr), ntohs(th->source),
1200 NIPQUAD(iph->daddr), ntohs(th->dest));
1201 return 1;
1202 }
1203
1204 /* Okay, so this is hash_expected and hash_location -
1205 * so we need to calculate the checksum.
1206 */
1207 genhash = tcp_v4_do_calc_md5_hash(newhash,
1208 hash_expected,
1209 iph->saddr, iph->daddr,
1210 th, sk->sk_protocol,
1211 skb->len);
1212
1213 if (genhash || memcmp(hash_location, newhash, 16) != 0) {
1214 if (net_ratelimit()) {
1215 printk(KERN_INFO "MD5 Hash failed for "
1216 "(" NIPQUAD_FMT ", %d)->(" NIPQUAD_FMT ", %d)%s\n",
1217 NIPQUAD(iph->saddr), ntohs(th->source),
1218 NIPQUAD(iph->daddr), ntohs(th->dest),
1219 genhash ? " tcp_v4_calc_md5_hash failed" : "");
1220 }
1221 return 1;
1222 }
1223 return 0;
1224}
1225
1226#endif
1227
1228struct request_sock_ops tcp_request_sock_ops __read_mostly = {
719 .family = PF_INET, 1229 .family = PF_INET,
720 .obj_size = sizeof(struct tcp_request_sock), 1230 .obj_size = sizeof(struct tcp_request_sock),
721 .rtx_syn_ack = tcp_v4_send_synack, 1231 .rtx_syn_ack = tcp_v4_send_synack,
@@ -724,9 +1234,16 @@ struct request_sock_ops tcp_request_sock_ops = {
724 .send_reset = tcp_v4_send_reset, 1234 .send_reset = tcp_v4_send_reset,
725}; 1235};
726 1236
1237#ifdef CONFIG_TCP_MD5SIG
1238static struct tcp_request_sock_ops tcp_request_sock_ipv4_ops = {
1239 .md5_lookup = tcp_v4_reqsk_md5_lookup,
1240};
1241#endif
1242
727static struct timewait_sock_ops tcp_timewait_sock_ops = { 1243static struct timewait_sock_ops tcp_timewait_sock_ops = {
728 .twsk_obj_size = sizeof(struct tcp_timewait_sock), 1244 .twsk_obj_size = sizeof(struct tcp_timewait_sock),
729 .twsk_unique = tcp_twsk_unique, 1245 .twsk_unique = tcp_twsk_unique,
1246 .twsk_destructor= tcp_twsk_destructor,
730}; 1247};
731 1248
732int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb) 1249int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
@@ -774,6 +1291,10 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
774 if (!req) 1291 if (!req)
775 goto drop; 1292 goto drop;
776 1293
1294#ifdef CONFIG_TCP_MD5SIG
1295 tcp_rsk(req)->af_specific = &tcp_request_sock_ipv4_ops;
1296#endif
1297
777 tcp_clear_options(&tmp_opt); 1298 tcp_clear_options(&tmp_opt);
778 tmp_opt.mss_clamp = 536; 1299 tmp_opt.mss_clamp = 536;
779 tmp_opt.user_mss = tcp_sk(sk)->rx_opt.user_mss; 1300 tmp_opt.user_mss = tcp_sk(sk)->rx_opt.user_mss;
@@ -859,7 +1380,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
859 goto drop_and_free; 1380 goto drop_and_free;
860 } 1381 }
861 1382
862 isn = tcp_v4_init_sequence(sk, skb); 1383 isn = tcp_v4_init_sequence(skb);
863 } 1384 }
864 tcp_rsk(req)->snt_isn = isn; 1385 tcp_rsk(req)->snt_isn = isn;
865 1386
@@ -892,6 +1413,9 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
892 struct inet_sock *newinet; 1413 struct inet_sock *newinet;
893 struct tcp_sock *newtp; 1414 struct tcp_sock *newtp;
894 struct sock *newsk; 1415 struct sock *newsk;
1416#ifdef CONFIG_TCP_MD5SIG
1417 struct tcp_md5sig_key *key;
1418#endif
895 1419
896 if (sk_acceptq_is_full(sk)) 1420 if (sk_acceptq_is_full(sk))
897 goto exit_overflow; 1421 goto exit_overflow;
@@ -926,6 +1450,22 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
926 newtp->advmss = dst_metric(dst, RTAX_ADVMSS); 1450 newtp->advmss = dst_metric(dst, RTAX_ADVMSS);
927 tcp_initialize_rcv_mss(newsk); 1451 tcp_initialize_rcv_mss(newsk);
928 1452
1453#ifdef CONFIG_TCP_MD5SIG
1454 /* Copy over the MD5 key from the original socket */
1455 if ((key = tcp_v4_md5_do_lookup(sk, newinet->daddr)) != NULL) {
1456 /*
1457 * We're using one, so create a matching key
1458 * on the newsk structure. If we fail to get
1459 * memory, then we end up not copying the key
1460 * across. Shucks.
1461 */
1462 char *newkey = kmemdup(key->key, key->keylen, GFP_ATOMIC);
1463 if (newkey != NULL)
1464 tcp_v4_md5_do_add(newsk, inet_sk(sk)->daddr,
1465 newkey, key->keylen);
1466 }
1467#endif
1468
929 __inet_hash(&tcp_hashinfo, newsk, 0); 1469 __inet_hash(&tcp_hashinfo, newsk, 0);
930 __inet_inherit_port(&tcp_hashinfo, sk, newsk); 1470 __inet_inherit_port(&tcp_hashinfo, sk, newsk);
931 1471
@@ -971,7 +1511,7 @@ static struct sock *tcp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
971 return sk; 1511 return sk;
972} 1512}
973 1513
974static int tcp_v4_checksum_init(struct sk_buff *skb) 1514static __sum16 tcp_v4_checksum_init(struct sk_buff *skb)
975{ 1515{
976 if (skb->ip_summed == CHECKSUM_COMPLETE) { 1516 if (skb->ip_summed == CHECKSUM_COMPLETE) {
977 if (!tcp_v4_check(skb->h.th, skb->len, skb->nh.iph->saddr, 1517 if (!tcp_v4_check(skb->h.th, skb->len, skb->nh.iph->saddr,
@@ -1001,10 +1541,24 @@ static int tcp_v4_checksum_init(struct sk_buff *skb)
1001 */ 1541 */
1002int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) 1542int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
1003{ 1543{
1544 struct sock *rsk;
1545#ifdef CONFIG_TCP_MD5SIG
1546 /*
1547 * We really want to reject the packet as early as possible
1548 * if:
1549 * o We're expecting an MD5'd packet and this is no MD5 tcp option
1550 * o There is an MD5 option and we're not expecting one
1551 */
1552 if (tcp_v4_inbound_md5_hash(sk, skb))
1553 goto discard;
1554#endif
1555
1004 if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */ 1556 if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
1005 TCP_CHECK_TIMER(sk); 1557 TCP_CHECK_TIMER(sk);
1006 if (tcp_rcv_established(sk, skb, skb->h.th, skb->len)) 1558 if (tcp_rcv_established(sk, skb, skb->h.th, skb->len)) {
1559 rsk = sk;
1007 goto reset; 1560 goto reset;
1561 }
1008 TCP_CHECK_TIMER(sk); 1562 TCP_CHECK_TIMER(sk);
1009 return 0; 1563 return 0;
1010 } 1564 }
@@ -1018,20 +1572,24 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)
1018 goto discard; 1572 goto discard;
1019 1573
1020 if (nsk != sk) { 1574 if (nsk != sk) {
1021 if (tcp_child_process(sk, nsk, skb)) 1575 if (tcp_child_process(sk, nsk, skb)) {
1576 rsk = nsk;
1022 goto reset; 1577 goto reset;
1578 }
1023 return 0; 1579 return 0;
1024 } 1580 }
1025 } 1581 }
1026 1582
1027 TCP_CHECK_TIMER(sk); 1583 TCP_CHECK_TIMER(sk);
1028 if (tcp_rcv_state_process(sk, skb, skb->h.th, skb->len)) 1584 if (tcp_rcv_state_process(sk, skb, skb->h.th, skb->len)) {
1585 rsk = sk;
1029 goto reset; 1586 goto reset;
1587 }
1030 TCP_CHECK_TIMER(sk); 1588 TCP_CHECK_TIMER(sk);
1031 return 0; 1589 return 0;
1032 1590
1033reset: 1591reset:
1034 tcp_v4_send_reset(skb); 1592 tcp_v4_send_reset(rsk, skb);
1035discard: 1593discard:
1036 kfree_skb(skb); 1594 kfree_skb(skb);
1037 /* Be careful here. If this function gets more complicated and 1595 /* Be careful here. If this function gets more complicated and
@@ -1140,7 +1698,7 @@ no_tcp_socket:
1140bad_packet: 1698bad_packet:
1141 TCP_INC_STATS_BH(TCP_MIB_INERRS); 1699 TCP_INC_STATS_BH(TCP_MIB_INERRS);
1142 } else { 1700 } else {
1143 tcp_v4_send_reset(skb); 1701 tcp_v4_send_reset(NULL, skb);
1144 } 1702 }
1145 1703
1146discard_it: 1704discard_it:
@@ -1263,6 +1821,15 @@ struct inet_connection_sock_af_ops ipv4_specific = {
1263#endif 1821#endif
1264}; 1822};
1265 1823
1824#ifdef CONFIG_TCP_MD5SIG
1825static struct tcp_sock_af_ops tcp_sock_ipv4_specific = {
1826 .md5_lookup = tcp_v4_md5_lookup,
1827 .calc_md5_hash = tcp_v4_calc_md5_hash,
1828 .md5_add = tcp_v4_md5_add_func,
1829 .md5_parse = tcp_v4_parse_md5_keys,
1830};
1831#endif
1832
1266/* NOTE: A lot of things set to zero explicitly by call to 1833/* NOTE: A lot of things set to zero explicitly by call to
1267 * sk_alloc() so need not be done here. 1834 * sk_alloc() so need not be done here.
1268 */ 1835 */
@@ -1302,6 +1869,9 @@ static int tcp_v4_init_sock(struct sock *sk)
1302 1869
1303 icsk->icsk_af_ops = &ipv4_specific; 1870 icsk->icsk_af_ops = &ipv4_specific;
1304 icsk->icsk_sync_mss = tcp_sync_mss; 1871 icsk->icsk_sync_mss = tcp_sync_mss;
1872#ifdef CONFIG_TCP_MD5SIG
1873 tp->af_specific = &tcp_sock_ipv4_specific;
1874#endif
1305 1875
1306 sk->sk_sndbuf = sysctl_tcp_wmem[1]; 1876 sk->sk_sndbuf = sysctl_tcp_wmem[1];
1307 sk->sk_rcvbuf = sysctl_tcp_rmem[1]; 1877 sk->sk_rcvbuf = sysctl_tcp_rmem[1];
@@ -1325,6 +1895,15 @@ int tcp_v4_destroy_sock(struct sock *sk)
1325 /* Cleans up our, hopefully empty, out_of_order_queue. */ 1895 /* Cleans up our, hopefully empty, out_of_order_queue. */
1326 __skb_queue_purge(&tp->out_of_order_queue); 1896 __skb_queue_purge(&tp->out_of_order_queue);
1327 1897
1898#ifdef CONFIG_TCP_MD5SIG
1899 /* Clean up the MD5 key list, if any */
1900 if (tp->md5sig_info) {
1901 tcp_v4_clear_md5_list(sk);
1902 kfree(tp->md5sig_info);
1903 tp->md5sig_info = NULL;
1904 }
1905#endif
1906
1328#ifdef CONFIG_NET_DMA 1907#ifdef CONFIG_NET_DMA
1329 /* Cleans up our sk_async_wait_queue */ 1908 /* Cleans up our sk_async_wait_queue */
1330 __skb_queue_purge(&sk->sk_async_wait_queue); 1909 __skb_queue_purge(&sk->sk_async_wait_queue);
@@ -1385,7 +1964,7 @@ static void *listening_get_next(struct seq_file *seq, void *cur)
1385 if (st->state == TCP_SEQ_STATE_OPENREQ) { 1964 if (st->state == TCP_SEQ_STATE_OPENREQ) {
1386 struct request_sock *req = cur; 1965 struct request_sock *req = cur;
1387 1966
1388 icsk = inet_csk(st->syn_wait_sk); 1967 icsk = inet_csk(st->syn_wait_sk);
1389 req = req->dl_next; 1968 req = req->dl_next;
1390 while (1) { 1969 while (1) {
1391 while (req) { 1970 while (req) {
@@ -1395,7 +1974,7 @@ static void *listening_get_next(struct seq_file *seq, void *cur)
1395 } 1974 }
1396 req = req->dl_next; 1975 req = req->dl_next;
1397 } 1976 }
1398 if (++st->sbucket >= TCP_SYNQ_HSIZE) 1977 if (++st->sbucket >= icsk->icsk_accept_queue.listen_opt->nr_table_entries)
1399 break; 1978 break;
1400get_req: 1979get_req:
1401 req = icsk->icsk_accept_queue.listen_opt->syn_table[st->sbucket]; 1980 req = icsk->icsk_accept_queue.listen_opt->syn_table[st->sbucket];
@@ -1543,7 +2122,7 @@ static void *established_get_idx(struct seq_file *seq, loff_t pos)
1543 while (rc && pos) { 2122 while (rc && pos) {
1544 rc = established_get_next(seq, rc); 2123 rc = established_get_next(seq, rc);
1545 --pos; 2124 --pos;
1546 } 2125 }
1547 return rc; 2126 return rc;
1548} 2127}
1549 2128
@@ -1672,7 +2251,7 @@ int tcp_proc_register(struct tcp_seq_afinfo *afinfo)
1672 afinfo->seq_fops->read = seq_read; 2251 afinfo->seq_fops->read = seq_read;
1673 afinfo->seq_fops->llseek = seq_lseek; 2252 afinfo->seq_fops->llseek = seq_lseek;
1674 afinfo->seq_fops->release = seq_release_private; 2253 afinfo->seq_fops->release = seq_release_private;
1675 2254
1676 p = proc_net_fops_create(afinfo->name, S_IRUGO, afinfo->seq_fops); 2255 p = proc_net_fops_create(afinfo->name, S_IRUGO, afinfo->seq_fops);
1677 if (p) 2256 if (p)
1678 p->data = afinfo; 2257 p->data = afinfo;
@@ -1686,7 +2265,7 @@ void tcp_proc_unregister(struct tcp_seq_afinfo *afinfo)
1686 if (!afinfo) 2265 if (!afinfo)
1687 return; 2266 return;
1688 proc_net_remove(afinfo->name); 2267 proc_net_remove(afinfo->name);
1689 memset(afinfo->seq_fops, 0, sizeof(*afinfo->seq_fops)); 2268 memset(afinfo->seq_fops, 0, sizeof(*afinfo->seq_fops));
1690} 2269}
1691 2270
1692static void get_openreq4(struct sock *sk, struct request_sock *req, 2271static void get_openreq4(struct sock *sk, struct request_sock *req,
@@ -1721,8 +2300,8 @@ static void get_tcp4_sock(struct sock *sp, char *tmpbuf, int i)
1721 struct tcp_sock *tp = tcp_sk(sp); 2300 struct tcp_sock *tp = tcp_sk(sp);
1722 const struct inet_connection_sock *icsk = inet_csk(sp); 2301 const struct inet_connection_sock *icsk = inet_csk(sp);
1723 struct inet_sock *inet = inet_sk(sp); 2302 struct inet_sock *inet = inet_sk(sp);
1724 unsigned int dest = inet->daddr; 2303 __be32 dest = inet->daddr;
1725 unsigned int src = inet->rcv_saddr; 2304 __be32 src = inet->rcv_saddr;
1726 __u16 destp = ntohs(inet->dport); 2305 __u16 destp = ntohs(inet->dport);
1727 __u16 srcp = ntohs(inet->sport); 2306 __u16 srcp = ntohs(inet->sport);
1728 2307
@@ -1744,7 +2323,8 @@ static void get_tcp4_sock(struct sock *sp, char *tmpbuf, int i)
1744 "%08X %5d %8d %lu %d %p %u %u %u %u %d", 2323 "%08X %5d %8d %lu %d %p %u %u %u %u %d",
1745 i, src, srcp, dest, destp, sp->sk_state, 2324 i, src, srcp, dest, destp, sp->sk_state,
1746 tp->write_seq - tp->snd_una, 2325 tp->write_seq - tp->snd_una,
1747 (sp->sk_state == TCP_LISTEN) ? sp->sk_ack_backlog : (tp->rcv_nxt - tp->copied_seq), 2326 sp->sk_state == TCP_LISTEN ? sp->sk_ack_backlog :
2327 (tp->rcv_nxt - tp->copied_seq),
1748 timer_active, 2328 timer_active,
1749 jiffies_to_clock_t(timer_expires - jiffies), 2329 jiffies_to_clock_t(timer_expires - jiffies),
1750 icsk->icsk_retransmits, 2330 icsk->icsk_retransmits,
@@ -1759,7 +2339,8 @@ static void get_tcp4_sock(struct sock *sp, char *tmpbuf, int i)
1759 tp->snd_ssthresh >= 0xFFFF ? -1 : tp->snd_ssthresh); 2339 tp->snd_ssthresh >= 0xFFFF ? -1 : tp->snd_ssthresh);
1760} 2340}
1761 2341
1762static void get_timewait4_sock(struct inet_timewait_sock *tw, char *tmpbuf, int i) 2342static void get_timewait4_sock(struct inet_timewait_sock *tw,
2343 char *tmpbuf, int i)
1763{ 2344{
1764 __be32 dest, src; 2345 __be32 dest, src;
1765 __u16 destp, srcp; 2346 __u16 destp, srcp;
@@ -1872,7 +2453,8 @@ struct proto tcp_prot = {
1872 2453
1873void __init tcp_v4_init(struct net_proto_family *ops) 2454void __init tcp_v4_init(struct net_proto_family *ops)
1874{ 2455{
1875 if (inet_csk_ctl_sock_create(&tcp_socket, PF_INET, SOCK_RAW, IPPROTO_TCP) < 0) 2456 if (inet_csk_ctl_sock_create(&tcp_socket, PF_INET, SOCK_RAW,
2457 IPPROTO_TCP) < 0)
1876 panic("Failed to create the TCP control socket.\n"); 2458 panic("Failed to create the TCP control socket.\n");
1877} 2459}
1878 2460
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index 0163d98269..4a3889dd19 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -45,8 +45,7 @@ struct inet_timewait_death_row tcp_death_row = {
45 .tw_timer = TIMER_INITIALIZER(inet_twdr_hangman, 0, 45 .tw_timer = TIMER_INITIALIZER(inet_twdr_hangman, 0,
46 (unsigned long)&tcp_death_row), 46 (unsigned long)&tcp_death_row),
47 .twkill_work = __WORK_INITIALIZER(tcp_death_row.twkill_work, 47 .twkill_work = __WORK_INITIALIZER(tcp_death_row.twkill_work,
48 inet_twdr_twkill_work, 48 inet_twdr_twkill_work),
49 &tcp_death_row),
50/* Short-time timewait calendar */ 49/* Short-time timewait calendar */
51 50
52 .twcal_hand = -1, 51 .twcal_hand = -1,
@@ -306,6 +305,28 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)
306 tw->tw_ipv6only = np->ipv6only; 305 tw->tw_ipv6only = np->ipv6only;
307 } 306 }
308#endif 307#endif
308
309#ifdef CONFIG_TCP_MD5SIG
310 /*
311 * The timewait bucket does not have the key DB from the
312 * sock structure. We just make a quick copy of the
313 * md5 key being used (if indeed we are using one)
314 * so the timewait ack generating code has the key.
315 */
316 do {
317 struct tcp_md5sig_key *key;
318 memset(tcptw->tw_md5_key, 0, sizeof(tcptw->tw_md5_key));
319 tcptw->tw_md5_keylen = 0;
320 key = tp->af_specific->md5_lookup(sk, sk);
321 if (key != NULL) {
322 memcpy(&tcptw->tw_md5_key, key->key, key->keylen);
323 tcptw->tw_md5_keylen = key->keylen;
324 if (tcp_alloc_md5sig_pool() == NULL)
325 BUG();
326 }
327 } while(0);
328#endif
329
309 /* Linkage updates. */ 330 /* Linkage updates. */
310 __inet_twsk_hashdance(tw, sk, &tcp_hashinfo); 331 __inet_twsk_hashdance(tw, sk, &tcp_hashinfo);
311 332
@@ -329,14 +350,24 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)
329 * socket up. We've got bigger problems than 350 * socket up. We've got bigger problems than
330 * non-graceful socket closings. 351 * non-graceful socket closings.
331 */ 352 */
332 if (net_ratelimit()) 353 LIMIT_NETDEBUG(KERN_INFO "TCP: time wait bucket table overflow\n");
333 printk(KERN_INFO "TCP: time wait bucket table overflow\n");
334 } 354 }
335 355
336 tcp_update_metrics(sk); 356 tcp_update_metrics(sk);
337 tcp_done(sk); 357 tcp_done(sk);
338} 358}
339 359
360void tcp_twsk_destructor(struct sock *sk)
361{
362#ifdef CONFIG_TCP_MD5SIG
363 struct tcp_timewait_sock *twsk = tcp_twsk(sk);
364 if (twsk->tw_md5_keylen)
365 tcp_put_md5sig_pool();
366#endif
367}
368
369EXPORT_SYMBOL_GPL(tcp_twsk_destructor);
370
340/* This is not only more efficient than what we used to do, it eliminates 371/* This is not only more efficient than what we used to do, it eliminates
341 * a lot of code duplication between IPv4/IPv6 SYN recv processing. -DaveM 372 * a lot of code duplication between IPv4/IPv6 SYN recv processing. -DaveM
342 * 373 *
@@ -435,6 +466,11 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req,
435 newtp->rx_opt.ts_recent_stamp = 0; 466 newtp->rx_opt.ts_recent_stamp = 0;
436 newtp->tcp_header_len = sizeof(struct tcphdr); 467 newtp->tcp_header_len = sizeof(struct tcphdr);
437 } 468 }
469#ifdef CONFIG_TCP_MD5SIG
470 newtp->md5sig_info = NULL; /*XXX*/
471 if (newtp->af_specific->md5_lookup(sk, newsk))
472 newtp->tcp_header_len += TCPOLEN_MD5SIG_ALIGNED;
473#endif
438 if (skb->len >= TCP_MIN_RCVMSS+newtp->tcp_header_len) 474 if (skb->len >= TCP_MIN_RCVMSS+newtp->tcp_header_len)
439 newicsk->icsk_ack.last_seg_size = skb->len - newtp->tcp_header_len; 475 newicsk->icsk_ack.last_seg_size = skb->len - newtp->tcp_header_len;
440 newtp->rx_opt.mss_clamp = req->mss; 476 newtp->rx_opt.mss_clamp = req->mss;
@@ -455,7 +491,7 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
455 struct request_sock **prev) 491 struct request_sock **prev)
456{ 492{
457 struct tcphdr *th = skb->h.th; 493 struct tcphdr *th = skb->h.th;
458 u32 flg = tcp_flag_word(th) & (TCP_FLAG_RST|TCP_FLAG_SYN|TCP_FLAG_ACK); 494 __be32 flg = tcp_flag_word(th) & (TCP_FLAG_RST|TCP_FLAG_SYN|TCP_FLAG_ACK);
459 int paws_reject = 0; 495 int paws_reject = 0;
460 struct tcp_options_received tmp_opt; 496 struct tcp_options_received tmp_opt;
461 struct sock *child; 497 struct sock *child;
@@ -617,6 +653,30 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
617 req, NULL); 653 req, NULL);
618 if (child == NULL) 654 if (child == NULL)
619 goto listen_overflow; 655 goto listen_overflow;
656#ifdef CONFIG_TCP_MD5SIG
657 else {
658 /* Copy over the MD5 key from the original socket */
659 struct tcp_md5sig_key *key;
660 struct tcp_sock *tp = tcp_sk(sk);
661 key = tp->af_specific->md5_lookup(sk, child);
662 if (key != NULL) {
663 /*
664 * We're using one, so create a matching key on the
665 * newsk structure. If we fail to get memory then we
666 * end up not copying the key across. Shucks.
667 */
668 char *newkey = kmemdup(key->key, key->keylen,
669 GFP_ATOMIC);
670 if (newkey) {
671 if (!tcp_alloc_md5sig_pool())
672 BUG();
673 tp->af_specific->md5_add(child, child,
674 newkey,
675 key->keylen);
676 }
677 }
678 }
679#endif
620 680
621 inet_csk_reqsk_queue_unlink(sk, req, prev); 681 inet_csk_reqsk_queue_unlink(sk, req, prev);
622 inet_csk_reqsk_queue_removed(sk, req); 682 inet_csk_reqsk_queue_removed(sk, req);
@@ -633,7 +693,7 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
633 embryonic_reset: 693 embryonic_reset:
634 NET_INC_STATS_BH(LINUX_MIB_EMBRYONICRSTS); 694 NET_INC_STATS_BH(LINUX_MIB_EMBRYONICRSTS);
635 if (!(flg & TCP_FLAG_RST)) 695 if (!(flg & TCP_FLAG_RST))
636 req->rsk_ops->send_reset(skb); 696 req->rsk_ops->send_reset(sk, skb);
637 697
638 inet_csk_reqsk_queue_drop(sk, req, prev); 698 inet_csk_reqsk_queue_drop(sk, req, prev);
639 return NULL; 699 return NULL;
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index ca40615772..32c1a972fa 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -270,7 +270,7 @@ static u16 tcp_select_window(struct sock *sk)
270} 270}
271 271
272static void tcp_build_and_update_options(__be32 *ptr, struct tcp_sock *tp, 272static void tcp_build_and_update_options(__be32 *ptr, struct tcp_sock *tp,
273 __u32 tstamp) 273 __u32 tstamp, __u8 **md5_hash)
274{ 274{
275 if (tp->rx_opt.tstamp_ok) { 275 if (tp->rx_opt.tstamp_ok) {
276 *ptr++ = htonl((TCPOPT_NOP << 24) | 276 *ptr++ = htonl((TCPOPT_NOP << 24) |
@@ -298,16 +298,29 @@ static void tcp_build_and_update_options(__be32 *ptr, struct tcp_sock *tp,
298 tp->rx_opt.eff_sacks--; 298 tp->rx_opt.eff_sacks--;
299 } 299 }
300 } 300 }
301#ifdef CONFIG_TCP_MD5SIG
302 if (md5_hash) {
303 *ptr++ = htonl((TCPOPT_NOP << 24) |
304 (TCPOPT_NOP << 16) |
305 (TCPOPT_MD5SIG << 8) |
306 TCPOLEN_MD5SIG);
307 *md5_hash = (__u8 *)ptr;
308 }
309#endif
301} 310}
302 311
303/* Construct a tcp options header for a SYN or SYN_ACK packet. 312/* Construct a tcp options header for a SYN or SYN_ACK packet.
304 * If this is every changed make sure to change the definition of 313 * If this is every changed make sure to change the definition of
305 * MAX_SYN_SIZE to match the new maximum number of options that you 314 * MAX_SYN_SIZE to match the new maximum number of options that you
306 * can generate. 315 * can generate.
316 *
317 * Note - that with the RFC2385 TCP option, we make room for the
318 * 16 byte MD5 hash. This will be filled in later, so the pointer for the
319 * location to be filled is passed back up.
307 */ 320 */
308static void tcp_syn_build_options(__be32 *ptr, int mss, int ts, int sack, 321static void tcp_syn_build_options(__be32 *ptr, int mss, int ts, int sack,
309 int offer_wscale, int wscale, __u32 tstamp, 322 int offer_wscale, int wscale, __u32 tstamp,
310 __u32 ts_recent) 323 __u32 ts_recent, __u8 **md5_hash)
311{ 324{
312 /* We always get an MSS option. 325 /* We always get an MSS option.
313 * The option bytes which will be seen in normal data 326 * The option bytes which will be seen in normal data
@@ -346,6 +359,20 @@ static void tcp_syn_build_options(__be32 *ptr, int mss, int ts, int sack,
346 (TCPOPT_WINDOW << 16) | 359 (TCPOPT_WINDOW << 16) |
347 (TCPOLEN_WINDOW << 8) | 360 (TCPOLEN_WINDOW << 8) |
348 (wscale)); 361 (wscale));
362#ifdef CONFIG_TCP_MD5SIG
363 /*
364 * If MD5 is enabled, then we set the option, and include the size
365 * (always 18). The actual MD5 hash is added just before the
366 * packet is sent.
367 */
368 if (md5_hash) {
369 *ptr++ = htonl((TCPOPT_NOP << 24) |
370 (TCPOPT_NOP << 16) |
371 (TCPOPT_MD5SIG << 8) |
372 TCPOLEN_MD5SIG);
373 *md5_hash = (__u8 *) ptr;
374 }
375#endif
349} 376}
350 377
351/* This routine actually transmits TCP packets queued in by 378/* This routine actually transmits TCP packets queued in by
@@ -366,6 +393,10 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
366 struct tcp_sock *tp; 393 struct tcp_sock *tp;
367 struct tcp_skb_cb *tcb; 394 struct tcp_skb_cb *tcb;
368 int tcp_header_size; 395 int tcp_header_size;
396#ifdef CONFIG_TCP_MD5SIG
397 struct tcp_md5sig_key *md5;
398 __u8 *md5_hash_location;
399#endif
369 struct tcphdr *th; 400 struct tcphdr *th;
370 int sysctl_flags; 401 int sysctl_flags;
371 int err; 402 int err;
@@ -424,9 +455,18 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
424 if (tcp_packets_in_flight(tp) == 0) 455 if (tcp_packets_in_flight(tp) == 0)
425 tcp_ca_event(sk, CA_EVENT_TX_START); 456 tcp_ca_event(sk, CA_EVENT_TX_START);
426 457
458#ifdef CONFIG_TCP_MD5SIG
459 /*
460 * Are we doing MD5 on this segment? If so - make
461 * room for it.
462 */
463 md5 = tp->af_specific->md5_lookup(sk, sk);
464 if (md5)
465 tcp_header_size += TCPOLEN_MD5SIG_ALIGNED;
466#endif
467
427 th = (struct tcphdr *) skb_push(skb, tcp_header_size); 468 th = (struct tcphdr *) skb_push(skb, tcp_header_size);
428 skb->h.th = th; 469 skb->h.th = th;
429 skb_set_owner_w(skb, sk);
430 470
431 /* Build TCP header and checksum it. */ 471 /* Build TCP header and checksum it. */
432 th->source = inet->sport; 472 th->source = inet->sport;
@@ -461,13 +501,34 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
461 (sysctl_flags & SYSCTL_FLAG_WSCALE), 501 (sysctl_flags & SYSCTL_FLAG_WSCALE),
462 tp->rx_opt.rcv_wscale, 502 tp->rx_opt.rcv_wscale,
463 tcb->when, 503 tcb->when,
464 tp->rx_opt.ts_recent); 504 tp->rx_opt.ts_recent,
505
506#ifdef CONFIG_TCP_MD5SIG
507 md5 ? &md5_hash_location :
508#endif
509 NULL);
465 } else { 510 } else {
466 tcp_build_and_update_options((__be32 *)(th + 1), 511 tcp_build_and_update_options((__be32 *)(th + 1),
467 tp, tcb->when); 512 tp, tcb->when,
513#ifdef CONFIG_TCP_MD5SIG
514 md5 ? &md5_hash_location :
515#endif
516 NULL);
468 TCP_ECN_send(sk, tp, skb, tcp_header_size); 517 TCP_ECN_send(sk, tp, skb, tcp_header_size);
469 } 518 }
470 519
520#ifdef CONFIG_TCP_MD5SIG
521 /* Calculate the MD5 hash, as we have all we need now */
522 if (md5) {
523 tp->af_specific->calc_md5_hash(md5_hash_location,
524 md5,
525 sk, NULL, NULL,
526 skb->h.th,
527 sk->sk_protocol,
528 skb->len);
529 }
530#endif
531
471 icsk->icsk_af_ops->send_check(sk, skb->len, skb); 532 icsk->icsk_af_ops->send_check(sk, skb->len, skb);
472 533
473 if (likely(tcb->flags & TCPCB_FLAG_ACK)) 534 if (likely(tcb->flags & TCPCB_FLAG_ACK))
@@ -479,19 +540,13 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
479 if (after(tcb->end_seq, tp->snd_nxt) || tcb->seq == tcb->end_seq) 540 if (after(tcb->end_seq, tp->snd_nxt) || tcb->seq == tcb->end_seq)
480 TCP_INC_STATS(TCP_MIB_OUTSEGS); 541 TCP_INC_STATS(TCP_MIB_OUTSEGS);
481 542
482 err = icsk->icsk_af_ops->queue_xmit(skb, 0); 543 err = icsk->icsk_af_ops->queue_xmit(skb, sk, 0);
483 if (likely(err <= 0)) 544 if (likely(err <= 0))
484 return err; 545 return err;
485 546
486 tcp_enter_cwr(sk); 547 tcp_enter_cwr(sk);
487 548
488 /* NET_XMIT_CN is special. It does not guarantee, 549 return net_xmit_eval(err);
489 * that this packet is lost. It tells that device
490 * is about to start to drop packets or already
491 * drops some packets of the same priority and
492 * invokes us to send less aggressively.
493 */
494 return err == NET_XMIT_CN ? 0 : err;
495 550
496#undef SYSCTL_FLAG_TSTAMPS 551#undef SYSCTL_FLAG_TSTAMPS
497#undef SYSCTL_FLAG_WSCALE 552#undef SYSCTL_FLAG_WSCALE
@@ -847,6 +902,11 @@ unsigned int tcp_current_mss(struct sock *sk, int large_allowed)
847 mss_now -= (TCPOLEN_SACK_BASE_ALIGNED + 902 mss_now -= (TCPOLEN_SACK_BASE_ALIGNED +
848 (tp->rx_opt.eff_sacks * TCPOLEN_SACK_PERBLOCK)); 903 (tp->rx_opt.eff_sacks * TCPOLEN_SACK_PERBLOCK));
849 904
905#ifdef CONFIG_TCP_MD5SIG
906 if (tp->af_specific->md5_lookup(sk, sk))
907 mss_now -= TCPOLEN_MD5SIG_ALIGNED;
908#endif
909
850 xmit_size_goal = mss_now; 910 xmit_size_goal = mss_now;
851 911
852 if (doing_tso) { 912 if (doing_tso) {
@@ -2040,6 +2100,10 @@ struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst,
2040 struct tcphdr *th; 2100 struct tcphdr *th;
2041 int tcp_header_size; 2101 int tcp_header_size;
2042 struct sk_buff *skb; 2102 struct sk_buff *skb;
2103#ifdef CONFIG_TCP_MD5SIG
2104 struct tcp_md5sig_key *md5;
2105 __u8 *md5_hash_location;
2106#endif
2043 2107
2044 skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15, 1, GFP_ATOMIC); 2108 skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15, 1, GFP_ATOMIC);
2045 if (skb == NULL) 2109 if (skb == NULL)
@@ -2055,6 +2119,13 @@ struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst,
2055 (ireq->wscale_ok ? TCPOLEN_WSCALE_ALIGNED : 0) + 2119 (ireq->wscale_ok ? TCPOLEN_WSCALE_ALIGNED : 0) +
2056 /* SACK_PERM is in the place of NOP NOP of TS */ 2120 /* SACK_PERM is in the place of NOP NOP of TS */
2057 ((ireq->sack_ok && !ireq->tstamp_ok) ? TCPOLEN_SACKPERM_ALIGNED : 0)); 2121 ((ireq->sack_ok && !ireq->tstamp_ok) ? TCPOLEN_SACKPERM_ALIGNED : 0));
2122
2123#ifdef CONFIG_TCP_MD5SIG
2124 /* Are we doing MD5 on this segment? If so - make room for it */
2125 md5 = tcp_rsk(req)->af_specific->md5_lookup(sk, req);
2126 if (md5)
2127 tcp_header_size += TCPOLEN_MD5SIG_ALIGNED;
2128#endif
2058 skb->h.th = th = (struct tcphdr *) skb_push(skb, tcp_header_size); 2129 skb->h.th = th = (struct tcphdr *) skb_push(skb, tcp_header_size);
2059 2130
2060 memset(th, 0, sizeof(struct tcphdr)); 2131 memset(th, 0, sizeof(struct tcphdr));
@@ -2092,11 +2163,29 @@ struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst,
2092 tcp_syn_build_options((__be32 *)(th + 1), dst_metric(dst, RTAX_ADVMSS), ireq->tstamp_ok, 2163 tcp_syn_build_options((__be32 *)(th + 1), dst_metric(dst, RTAX_ADVMSS), ireq->tstamp_ok,
2093 ireq->sack_ok, ireq->wscale_ok, ireq->rcv_wscale, 2164 ireq->sack_ok, ireq->wscale_ok, ireq->rcv_wscale,
2094 TCP_SKB_CB(skb)->when, 2165 TCP_SKB_CB(skb)->when,
2095 req->ts_recent); 2166 req->ts_recent,
2167 (
2168#ifdef CONFIG_TCP_MD5SIG
2169 md5 ? &md5_hash_location :
2170#endif
2171 NULL)
2172 );
2096 2173
2097 skb->csum = 0; 2174 skb->csum = 0;
2098 th->doff = (tcp_header_size >> 2); 2175 th->doff = (tcp_header_size >> 2);
2099 TCP_INC_STATS(TCP_MIB_OUTSEGS); 2176 TCP_INC_STATS(TCP_MIB_OUTSEGS);
2177
2178#ifdef CONFIG_TCP_MD5SIG
2179 /* Okay, we have all we need - do the md5 hash if needed */
2180 if (md5) {
2181 tp->af_specific->calc_md5_hash(md5_hash_location,
2182 md5,
2183 NULL, dst, req,
2184 skb->h.th, sk->sk_protocol,
2185 skb->len);
2186 }
2187#endif
2188
2100 return skb; 2189 return skb;
2101} 2190}
2102 2191
@@ -2115,6 +2204,11 @@ static void tcp_connect_init(struct sock *sk)
2115 tp->tcp_header_len = sizeof(struct tcphdr) + 2204 tp->tcp_header_len = sizeof(struct tcphdr) +
2116 (sysctl_tcp_timestamps ? TCPOLEN_TSTAMP_ALIGNED : 0); 2205 (sysctl_tcp_timestamps ? TCPOLEN_TSTAMP_ALIGNED : 0);
2117 2206
2207#ifdef CONFIG_TCP_MD5SIG
2208 if (tp->af_specific->md5_lookup(sk, sk) != NULL)
2209 tp->tcp_header_len += TCPOLEN_MD5SIG_ALIGNED;
2210#endif
2211
2118 /* If user gave his TCP_MAXSEG, record it to clamp */ 2212 /* If user gave his TCP_MAXSEG, record it to clamp */
2119 if (tp->rx_opt.user_mss) 2213 if (tp->rx_opt.user_mss)
2120 tp->rx_opt.mss_clamp = tp->rx_opt.user_mss; 2214 tp->rx_opt.mss_clamp = tp->rx_opt.user_mss;
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index fb09ade589..3355c276b6 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -297,7 +297,7 @@ static void tcp_retransmit_timer(struct sock *sk)
297 if (net_ratelimit()) { 297 if (net_ratelimit()) {
298 struct inet_sock *inet = inet_sk(sk); 298 struct inet_sock *inet = inet_sk(sk);
299 printk(KERN_DEBUG "TCP: Treason uncloaked! Peer %u.%u.%u.%u:%u/%u shrinks window %u:%u. Repaired.\n", 299 printk(KERN_DEBUG "TCP: Treason uncloaked! Peer %u.%u.%u.%u:%u/%u shrinks window %u:%u. Repaired.\n",
300 NIPQUAD(inet->daddr), htons(inet->dport), 300 NIPQUAD(inet->daddr), ntohs(inet->dport),
301 inet->num, tp->snd_una, tp->snd_nxt); 301 inet->num, tp->snd_una, tp->snd_nxt);
302 } 302 }
303#endif 303#endif
diff --git a/net/ipv4/tcp_vegas.c b/net/ipv4/tcp_vegas.c
index a3b7aa015a..ddc4bcc578 100644
--- a/net/ipv4/tcp_vegas.c
+++ b/net/ipv4/tcp_vegas.c
@@ -42,8 +42,8 @@
42 * with V_PARAM_SHIFT bits to the right of the binary point. 42 * with V_PARAM_SHIFT bits to the right of the binary point.
43 */ 43 */
44#define V_PARAM_SHIFT 1 44#define V_PARAM_SHIFT 1
45static int alpha = 1<<V_PARAM_SHIFT; 45static int alpha = 2<<V_PARAM_SHIFT;
46static int beta = 3<<V_PARAM_SHIFT; 46static int beta = 4<<V_PARAM_SHIFT;
47static int gamma = 1<<V_PARAM_SHIFT; 47static int gamma = 1<<V_PARAM_SHIFT;
48 48
49module_param(alpha, int, 0644); 49module_param(alpha, int, 0644);
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 9e1bd37487..cfff930f2b 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -92,22 +92,16 @@
92#include <linux/timer.h> 92#include <linux/timer.h>
93#include <linux/mm.h> 93#include <linux/mm.h>
94#include <linux/inet.h> 94#include <linux/inet.h>
95#include <linux/ipv6.h>
96#include <linux/netdevice.h> 95#include <linux/netdevice.h>
97#include <net/snmp.h>
98#include <net/ip.h>
99#include <net/tcp_states.h> 96#include <net/tcp_states.h>
100#include <net/protocol.h>
101#include <linux/skbuff.h> 97#include <linux/skbuff.h>
102#include <linux/proc_fs.h> 98#include <linux/proc_fs.h>
103#include <linux/seq_file.h> 99#include <linux/seq_file.h>
104#include <net/sock.h>
105#include <net/udp.h>
106#include <net/icmp.h> 100#include <net/icmp.h>
107#include <net/route.h> 101#include <net/route.h>
108#include <net/inet_common.h>
109#include <net/checksum.h> 102#include <net/checksum.h>
110#include <net/xfrm.h> 103#include <net/xfrm.h>
104#include "udp_impl.h"
111 105
112/* 106/*
113 * Snmp MIB for the UDP layer 107 * Snmp MIB for the UDP layer
@@ -120,26 +114,30 @@ DEFINE_RWLOCK(udp_hash_lock);
120 114
121static int udp_port_rover; 115static int udp_port_rover;
122 116
123static inline int udp_lport_inuse(u16 num) 117static inline int __udp_lib_lport_inuse(__u16 num, struct hlist_head udptable[])
124{ 118{
125 struct sock *sk; 119 struct sock *sk;
126 struct hlist_node *node; 120 struct hlist_node *node;
127 121
128 sk_for_each(sk, node, &udp_hash[num & (UDP_HTABLE_SIZE - 1)]) 122 sk_for_each(sk, node, &udptable[num & (UDP_HTABLE_SIZE - 1)])
129 if (inet_sk(sk)->num == num) 123 if (inet_sk(sk)->num == num)
130 return 1; 124 return 1;
131 return 0; 125 return 0;
132} 126}
133 127
134/** 128/**
135 * udp_get_port - common port lookup for IPv4 and IPv6 129 * __udp_lib_get_port - UDP/-Lite port lookup for IPv4 and IPv6
136 * 130 *
137 * @sk: socket struct in question 131 * @sk: socket struct in question
138 * @snum: port number to look up 132 * @snum: port number to look up
133 * @udptable: hash list table, must be of UDP_HTABLE_SIZE
134 * @port_rover: pointer to record of last unallocated port
139 * @saddr_comp: AF-dependent comparison of bound local IP addresses 135 * @saddr_comp: AF-dependent comparison of bound local IP addresses
140 */ 136 */
141int udp_get_port(struct sock *sk, unsigned short snum, 137int __udp_lib_get_port(struct sock *sk, unsigned short snum,
142 int (*saddr_cmp)(const struct sock *sk1, const struct sock *sk2)) 138 struct hlist_head udptable[], int *port_rover,
139 int (*saddr_comp)(const struct sock *sk1,
140 const struct sock *sk2 ) )
143{ 141{
144 struct hlist_node *node; 142 struct hlist_node *node;
145 struct hlist_head *head; 143 struct hlist_head *head;
@@ -150,15 +148,15 @@ int udp_get_port(struct sock *sk, unsigned short snum,
150 if (snum == 0) { 148 if (snum == 0) {
151 int best_size_so_far, best, result, i; 149 int best_size_so_far, best, result, i;
152 150
153 if (udp_port_rover > sysctl_local_port_range[1] || 151 if (*port_rover > sysctl_local_port_range[1] ||
154 udp_port_rover < sysctl_local_port_range[0]) 152 *port_rover < sysctl_local_port_range[0])
155 udp_port_rover = sysctl_local_port_range[0]; 153 *port_rover = sysctl_local_port_range[0];
156 best_size_so_far = 32767; 154 best_size_so_far = 32767;
157 best = result = udp_port_rover; 155 best = result = *port_rover;
158 for (i = 0; i < UDP_HTABLE_SIZE; i++, result++) { 156 for (i = 0; i < UDP_HTABLE_SIZE; i++, result++) {
159 int size; 157 int size;
160 158
161 head = &udp_hash[result & (UDP_HTABLE_SIZE - 1)]; 159 head = &udptable[result & (UDP_HTABLE_SIZE - 1)];
162 if (hlist_empty(head)) { 160 if (hlist_empty(head)) {
163 if (result > sysctl_local_port_range[1]) 161 if (result > sysctl_local_port_range[1])
164 result = sysctl_local_port_range[0] + 162 result = sysctl_local_port_range[0] +
@@ -167,11 +165,14 @@ int udp_get_port(struct sock *sk, unsigned short snum,
167 goto gotit; 165 goto gotit;
168 } 166 }
169 size = 0; 167 size = 0;
170 sk_for_each(sk2, node, head) 168 sk_for_each(sk2, node, head) {
171 if (++size < best_size_so_far) { 169 if (++size >= best_size_so_far)
172 best_size_so_far = size; 170 goto next;
173 best = result; 171 }
174 } 172 best_size_so_far = size;
173 best = result;
174 next:
175 ;
175 } 176 }
176 result = best; 177 result = best;
177 for(i = 0; i < (1 << 16) / UDP_HTABLE_SIZE; i++, result += UDP_HTABLE_SIZE) { 178 for(i = 0; i < (1 << 16) / UDP_HTABLE_SIZE; i++, result += UDP_HTABLE_SIZE) {
@@ -179,15 +180,15 @@ int udp_get_port(struct sock *sk, unsigned short snum,
179 result = sysctl_local_port_range[0] 180 result = sysctl_local_port_range[0]
180 + ((result - sysctl_local_port_range[0]) & 181 + ((result - sysctl_local_port_range[0]) &
181 (UDP_HTABLE_SIZE - 1)); 182 (UDP_HTABLE_SIZE - 1));
182 if (!udp_lport_inuse(result)) 183 if (! __udp_lib_lport_inuse(result, udptable))
183 break; 184 break;
184 } 185 }
185 if (i >= (1 << 16) / UDP_HTABLE_SIZE) 186 if (i >= (1 << 16) / UDP_HTABLE_SIZE)
186 goto fail; 187 goto fail;
187gotit: 188gotit:
188 udp_port_rover = snum = result; 189 *port_rover = snum = result;
189 } else { 190 } else {
190 head = &udp_hash[snum & (UDP_HTABLE_SIZE - 1)]; 191 head = &udptable[snum & (UDP_HTABLE_SIZE - 1)];
191 192
192 sk_for_each(sk2, node, head) 193 sk_for_each(sk2, node, head)
193 if (inet_sk(sk2)->num == snum && 194 if (inet_sk(sk2)->num == snum &&
@@ -195,12 +196,12 @@ gotit:
195 (!sk2->sk_reuse || !sk->sk_reuse) && 196 (!sk2->sk_reuse || !sk->sk_reuse) &&
196 (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if 197 (!sk2->sk_bound_dev_if || !sk->sk_bound_dev_if
197 || sk2->sk_bound_dev_if == sk->sk_bound_dev_if) && 198 || sk2->sk_bound_dev_if == sk->sk_bound_dev_if) &&
198 (*saddr_cmp)(sk, sk2) ) 199 (*saddr_comp)(sk, sk2) )
199 goto fail; 200 goto fail;
200 } 201 }
201 inet_sk(sk)->num = snum; 202 inet_sk(sk)->num = snum;
202 if (sk_unhashed(sk)) { 203 if (sk_unhashed(sk)) {
203 head = &udp_hash[snum & (UDP_HTABLE_SIZE - 1)]; 204 head = &udptable[snum & (UDP_HTABLE_SIZE - 1)];
204 sk_add_node(sk, head); 205 sk_add_node(sk, head);
205 sock_prot_inc_use(sk->sk_prot); 206 sock_prot_inc_use(sk->sk_prot);
206 } 207 }
@@ -210,7 +211,13 @@ fail:
210 return error; 211 return error;
211} 212}
212 213
213static inline int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2) 214__inline__ int udp_get_port(struct sock *sk, unsigned short snum,
215 int (*scmp)(const struct sock *, const struct sock *))
216{
217 return __udp_lib_get_port(sk, snum, udp_hash, &udp_port_rover, scmp);
218}
219
220inline int ipv4_rcv_saddr_equal(const struct sock *sk1, const struct sock *sk2)
214{ 221{
215 struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2); 222 struct inet_sock *inet1 = inet_sk(sk1), *inet2 = inet_sk(sk2);
216 223
@@ -224,34 +231,20 @@ static inline int udp_v4_get_port(struct sock *sk, unsigned short snum)
224 return udp_get_port(sk, snum, ipv4_rcv_saddr_equal); 231 return udp_get_port(sk, snum, ipv4_rcv_saddr_equal);
225} 232}
226 233
227
228static void udp_v4_hash(struct sock *sk)
229{
230 BUG();
231}
232
233static void udp_v4_unhash(struct sock *sk)
234{
235 write_lock_bh(&udp_hash_lock);
236 if (sk_del_node_init(sk)) {
237 inet_sk(sk)->num = 0;
238 sock_prot_dec_use(sk->sk_prot);
239 }
240 write_unlock_bh(&udp_hash_lock);
241}
242
243/* UDP is nearly always wildcards out the wazoo, it makes no sense to try 234/* UDP is nearly always wildcards out the wazoo, it makes no sense to try
244 * harder than this. -DaveM 235 * harder than this. -DaveM
245 */ 236 */
246static struct sock *udp_v4_lookup_longway(__be32 saddr, __be16 sport, 237static struct sock *__udp4_lib_lookup(__be32 saddr, __be16 sport,
247 __be32 daddr, __be16 dport, int dif) 238 __be32 daddr, __be16 dport,
239 int dif, struct hlist_head udptable[])
248{ 240{
249 struct sock *sk, *result = NULL; 241 struct sock *sk, *result = NULL;
250 struct hlist_node *node; 242 struct hlist_node *node;
251 unsigned short hnum = ntohs(dport); 243 unsigned short hnum = ntohs(dport);
252 int badness = -1; 244 int badness = -1;
253 245
254 sk_for_each(sk, node, &udp_hash[hnum & (UDP_HTABLE_SIZE - 1)]) { 246 read_lock(&udp_hash_lock);
247 sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) {
255 struct inet_sock *inet = inet_sk(sk); 248 struct inet_sock *inet = inet_sk(sk);
256 249
257 if (inet->num == hnum && !ipv6_only_sock(sk)) { 250 if (inet->num == hnum && !ipv6_only_sock(sk)) {
@@ -285,20 +278,10 @@ static struct sock *udp_v4_lookup_longway(__be32 saddr, __be16 sport,
285 } 278 }
286 } 279 }
287 } 280 }
288 return result; 281 if (result)
289} 282 sock_hold(result);
290
291static __inline__ struct sock *udp_v4_lookup(__be32 saddr, __be16 sport,
292 __be32 daddr, __be16 dport, int dif)
293{
294 struct sock *sk;
295
296 read_lock(&udp_hash_lock);
297 sk = udp_v4_lookup_longway(saddr, sport, daddr, dport, dif);
298 if (sk)
299 sock_hold(sk);
300 read_unlock(&udp_hash_lock); 283 read_unlock(&udp_hash_lock);
301 return sk; 284 return result;
302} 285}
303 286
304static inline struct sock *udp_v4_mcast_next(struct sock *sk, 287static inline struct sock *udp_v4_mcast_next(struct sock *sk,
@@ -340,7 +323,7 @@ found:
340 * to find the appropriate port. 323 * to find the appropriate port.
341 */ 324 */
342 325
343void udp_err(struct sk_buff *skb, u32 info) 326void __udp4_lib_err(struct sk_buff *skb, u32 info, struct hlist_head udptable[])
344{ 327{
345 struct inet_sock *inet; 328 struct inet_sock *inet;
346 struct iphdr *iph = (struct iphdr*)skb->data; 329 struct iphdr *iph = (struct iphdr*)skb->data;
@@ -351,7 +334,8 @@ void udp_err(struct sk_buff *skb, u32 info)
351 int harderr; 334 int harderr;
352 int err; 335 int err;
353 336
354 sk = udp_v4_lookup(iph->daddr, uh->dest, iph->saddr, uh->source, skb->dev->ifindex); 337 sk = __udp4_lib_lookup(iph->daddr, uh->dest, iph->saddr, uh->source,
338 skb->dev->ifindex, udptable );
355 if (sk == NULL) { 339 if (sk == NULL) {
356 ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); 340 ICMP_INC_STATS_BH(ICMP_MIB_INERRORS);
357 return; /* No socket for error */ 341 return; /* No socket for error */
@@ -405,6 +389,11 @@ out:
405 sock_put(sk); 389 sock_put(sk);
406} 390}
407 391
392__inline__ void udp_err(struct sk_buff *skb, u32 info)
393{
394 return __udp4_lib_err(skb, info, udp_hash);
395}
396
408/* 397/*
409 * Throw away all pending data and cancel the corking. Socket is locked. 398 * Throw away all pending data and cancel the corking. Socket is locked.
410 */ 399 */
@@ -419,16 +408,58 @@ static void udp_flush_pending_frames(struct sock *sk)
419 } 408 }
420} 409}
421 410
411/**
412 * udp4_hwcsum_outgoing - handle outgoing HW checksumming
413 * @sk: socket we are sending on
414 * @skb: sk_buff containing the filled-in UDP header
415 * (checksum field must be zeroed out)
416 */
417static void udp4_hwcsum_outgoing(struct sock *sk, struct sk_buff *skb,
418 __be32 src, __be32 dst, int len )
419{
420 unsigned int offset;
421 struct udphdr *uh = skb->h.uh;
422 __wsum csum = 0;
423
424 if (skb_queue_len(&sk->sk_write_queue) == 1) {
425 /*
426 * Only one fragment on the socket.
427 */
428 skb->csum_offset = offsetof(struct udphdr, check);
429 uh->check = ~csum_tcpudp_magic(src, dst, len, IPPROTO_UDP, 0);
430 } else {
431 /*
432 * HW-checksum won't work as there are two or more
433 * fragments on the socket so that all csums of sk_buffs
434 * should be together
435 */
436 offset = skb->h.raw - skb->data;
437 skb->csum = skb_checksum(skb, offset, skb->len - offset, 0);
438
439 skb->ip_summed = CHECKSUM_NONE;
440
441 skb_queue_walk(&sk->sk_write_queue, skb) {
442 csum = csum_add(csum, skb->csum);
443 }
444
445 uh->check = csum_tcpudp_magic(src, dst, len, IPPROTO_UDP, csum);
446 if (uh->check == 0)
447 uh->check = CSUM_MANGLED_0;
448 }
449}
450
422/* 451/*
423 * Push out all pending data as one UDP datagram. Socket is locked. 452 * Push out all pending data as one UDP datagram. Socket is locked.
424 */ 453 */
425static int udp_push_pending_frames(struct sock *sk, struct udp_sock *up) 454static int udp_push_pending_frames(struct sock *sk)
426{ 455{
456 struct udp_sock *up = udp_sk(sk);
427 struct inet_sock *inet = inet_sk(sk); 457 struct inet_sock *inet = inet_sk(sk);
428 struct flowi *fl = &inet->cork.fl; 458 struct flowi *fl = &inet->cork.fl;
429 struct sk_buff *skb; 459 struct sk_buff *skb;
430 struct udphdr *uh; 460 struct udphdr *uh;
431 int err = 0; 461 int err = 0;
462 __wsum csum = 0;
432 463
433 /* Grab the skbuff where UDP header space exists. */ 464 /* Grab the skbuff where UDP header space exists. */
434 if ((skb = skb_peek(&sk->sk_write_queue)) == NULL) 465 if ((skb = skb_peek(&sk->sk_write_queue)) == NULL)
@@ -443,52 +474,28 @@ static int udp_push_pending_frames(struct sock *sk, struct udp_sock *up)
443 uh->len = htons(up->len); 474 uh->len = htons(up->len);
444 uh->check = 0; 475 uh->check = 0;
445 476
446 if (sk->sk_no_check == UDP_CSUM_NOXMIT) { 477 if (up->pcflag) /* UDP-Lite */
478 csum = udplite_csum_outgoing(sk, skb);
479
480 else if (sk->sk_no_check == UDP_CSUM_NOXMIT) { /* UDP csum disabled */
481
447 skb->ip_summed = CHECKSUM_NONE; 482 skb->ip_summed = CHECKSUM_NONE;
448 goto send; 483 goto send;
449 }
450 484
451 if (skb_queue_len(&sk->sk_write_queue) == 1) { 485 } else if (skb->ip_summed == CHECKSUM_PARTIAL) { /* UDP hardware csum */
452 /*
453 * Only one fragment on the socket.
454 */
455 if (skb->ip_summed == CHECKSUM_PARTIAL) {
456 skb->csum = offsetof(struct udphdr, check);
457 uh->check = ~csum_tcpudp_magic(fl->fl4_src, fl->fl4_dst,
458 up->len, IPPROTO_UDP, 0);
459 } else {
460 skb->csum = csum_partial((char *)uh,
461 sizeof(struct udphdr), skb->csum);
462 uh->check = csum_tcpudp_magic(fl->fl4_src, fl->fl4_dst,
463 up->len, IPPROTO_UDP, skb->csum);
464 if (uh->check == 0)
465 uh->check = -1;
466 }
467 } else {
468 unsigned int csum = 0;
469 /*
470 * HW-checksum won't work as there are two or more
471 * fragments on the socket so that all csums of sk_buffs
472 * should be together.
473 */
474 if (skb->ip_summed == CHECKSUM_PARTIAL) {
475 int offset = (unsigned char *)uh - skb->data;
476 skb->csum = skb_checksum(skb, offset, skb->len - offset, 0);
477 486
478 skb->ip_summed = CHECKSUM_NONE; 487 udp4_hwcsum_outgoing(sk, skb, fl->fl4_src,fl->fl4_dst, up->len);
479 } else { 488 goto send;
480 skb->csum = csum_partial((char *)uh, 489
481 sizeof(struct udphdr), skb->csum); 490 } else /* `normal' UDP */
482 } 491 csum = udp_csum_outgoing(sk, skb);
492
493 /* add protocol-dependent pseudo-header */
494 uh->check = csum_tcpudp_magic(fl->fl4_src, fl->fl4_dst, up->len,
495 sk->sk_protocol, csum );
496 if (uh->check == 0)
497 uh->check = CSUM_MANGLED_0;
483 498
484 skb_queue_walk(&sk->sk_write_queue, skb) {
485 csum = csum_add(csum, skb->csum);
486 }
487 uh->check = csum_tcpudp_magic(fl->fl4_src, fl->fl4_dst,
488 up->len, IPPROTO_UDP, csum);
489 if (uh->check == 0)
490 uh->check = -1;
491 }
492send: 499send:
493 err = ip_push_pending_frames(sk); 500 err = ip_push_pending_frames(sk);
494out: 501out:
@@ -497,12 +504,6 @@ out:
497 return err; 504 return err;
498} 505}
499 506
500
501static unsigned short udp_check(struct udphdr *uh, int len, __be32 saddr, __be32 daddr, unsigned long base)
502{
503 return(csum_tcpudp_magic(saddr, daddr, len, IPPROTO_UDP, base));
504}
505
506int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, 507int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
507 size_t len) 508 size_t len)
508{ 509{
@@ -516,8 +517,9 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
516 __be32 daddr, faddr, saddr; 517 __be32 daddr, faddr, saddr;
517 __be16 dport; 518 __be16 dport;
518 u8 tos; 519 u8 tos;
519 int err; 520 int err, is_udplite = up->pcflag;
520 int corkreq = up->corkflag || msg->msg_flags&MSG_MORE; 521 int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
522 int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
521 523
522 if (len > 0xFFFF) 524 if (len > 0xFFFF)
523 return -EMSGSIZE; 525 return -EMSGSIZE;
@@ -622,7 +624,7 @@ int udp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
622 { .daddr = faddr, 624 { .daddr = faddr,
623 .saddr = saddr, 625 .saddr = saddr,
624 .tos = tos } }, 626 .tos = tos } },
625 .proto = IPPROTO_UDP, 627 .proto = sk->sk_protocol,
626 .uli_u = { .ports = 628 .uli_u = { .ports =
627 { .sport = inet->sport, 629 { .sport = inet->sport,
628 .dport = dport } } }; 630 .dport = dport } } };
@@ -668,13 +670,14 @@ back_from_confirm:
668 670
669do_append_data: 671do_append_data:
670 up->len += ulen; 672 up->len += ulen;
671 err = ip_append_data(sk, ip_generic_getfrag, msg->msg_iov, ulen, 673 getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag;
672 sizeof(struct udphdr), &ipc, rt, 674 err = ip_append_data(sk, getfrag, msg->msg_iov, ulen,
675 sizeof(struct udphdr), &ipc, rt,
673 corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags); 676 corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
674 if (err) 677 if (err)
675 udp_flush_pending_frames(sk); 678 udp_flush_pending_frames(sk);
676 else if (!corkreq) 679 else if (!corkreq)
677 err = udp_push_pending_frames(sk, up); 680 err = udp_push_pending_frames(sk);
678 else if (unlikely(skb_queue_empty(&sk->sk_write_queue))) 681 else if (unlikely(skb_queue_empty(&sk->sk_write_queue)))
679 up->pending = 0; 682 up->pending = 0;
680 release_sock(sk); 683 release_sock(sk);
@@ -684,7 +687,7 @@ out:
684 if (free) 687 if (free)
685 kfree(ipc.opt); 688 kfree(ipc.opt);
686 if (!err) { 689 if (!err) {
687 UDP_INC_STATS_USER(UDP_MIB_OUTDATAGRAMS); 690 UDP_INC_STATS_USER(UDP_MIB_OUTDATAGRAMS, is_udplite);
688 return len; 691 return len;
689 } 692 }
690 /* 693 /*
@@ -695,7 +698,7 @@ out:
695 * seems like overkill. 698 * seems like overkill.
696 */ 699 */
697 if (err == -ENOBUFS || test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) { 700 if (err == -ENOBUFS || test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) {
698 UDP_INC_STATS_USER(UDP_MIB_SNDBUFERRORS); 701 UDP_INC_STATS_USER(UDP_MIB_SNDBUFERRORS, is_udplite);
699 } 702 }
700 return err; 703 return err;
701 704
@@ -707,8 +710,8 @@ do_confirm:
707 goto out; 710 goto out;
708} 711}
709 712
710static int udp_sendpage(struct sock *sk, struct page *page, int offset, 713int udp_sendpage(struct sock *sk, struct page *page, int offset,
711 size_t size, int flags) 714 size_t size, int flags)
712{ 715{
713 struct udp_sock *up = udp_sk(sk); 716 struct udp_sock *up = udp_sk(sk);
714 int ret; 717 int ret;
@@ -747,7 +750,7 @@ static int udp_sendpage(struct sock *sk, struct page *page, int offset,
747 750
748 up->len += size; 751 up->len += size;
749 if (!(up->corkflag || (flags&MSG_MORE))) 752 if (!(up->corkflag || (flags&MSG_MORE)))
750 ret = udp_push_pending_frames(sk, up); 753 ret = udp_push_pending_frames(sk);
751 if (!ret) 754 if (!ret)
752 ret = size; 755 ret = size;
753out: 756out:
@@ -795,29 +798,18 @@ int udp_ioctl(struct sock *sk, int cmd, unsigned long arg)
795 return(0); 798 return(0);
796} 799}
797 800
798static __inline__ int __udp_checksum_complete(struct sk_buff *skb)
799{
800 return __skb_checksum_complete(skb);
801}
802
803static __inline__ int udp_checksum_complete(struct sk_buff *skb)
804{
805 return skb->ip_summed != CHECKSUM_UNNECESSARY &&
806 __udp_checksum_complete(skb);
807}
808
809/* 801/*
810 * This should be easy, if there is something there we 802 * This should be easy, if there is something there we
811 * return it, otherwise we block. 803 * return it, otherwise we block.
812 */ 804 */
813 805
814static int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, 806int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
815 size_t len, int noblock, int flags, int *addr_len) 807 size_t len, int noblock, int flags, int *addr_len)
816{ 808{
817 struct inet_sock *inet = inet_sk(sk); 809 struct inet_sock *inet = inet_sk(sk);
818 struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name; 810 struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name;
819 struct sk_buff *skb; 811 struct sk_buff *skb;
820 int copied, err; 812 int copied, err, copy_only, is_udplite = IS_UDPLITE(sk);
821 813
822 /* 814 /*
823 * Check any passed addresses 815 * Check any passed addresses
@@ -839,15 +831,25 @@ try_again:
839 msg->msg_flags |= MSG_TRUNC; 831 msg->msg_flags |= MSG_TRUNC;
840 } 832 }
841 833
842 if (skb->ip_summed==CHECKSUM_UNNECESSARY) { 834 /*
843 err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov, 835 * Decide whether to checksum and/or copy data.
844 copied); 836 *
845 } else if (msg->msg_flags&MSG_TRUNC) { 837 * UDP: checksum may have been computed in HW,
846 if (__udp_checksum_complete(skb)) 838 * (re-)compute it if message is truncated.
839 * UDP-Lite: always needs to checksum, no HW support.
840 */
841 copy_only = (skb->ip_summed==CHECKSUM_UNNECESSARY);
842
843 if (is_udplite || (!copy_only && msg->msg_flags&MSG_TRUNC)) {
844 if (__udp_lib_checksum_complete(skb))
847 goto csum_copy_err; 845 goto csum_copy_err;
848 err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov, 846 copy_only = 1;
849 copied); 847 }
850 } else { 848
849 if (copy_only)
850 err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
851 msg->msg_iov, copied );
852 else {
851 err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov); 853 err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov);
852 854
853 if (err == -EINVAL) 855 if (err == -EINVAL)
@@ -880,7 +882,7 @@ out:
880 return err; 882 return err;
881 883
882csum_copy_err: 884csum_copy_err:
883 UDP_INC_STATS_BH(UDP_MIB_INERRORS); 885 UDP_INC_STATS_BH(UDP_MIB_INERRORS, is_udplite);
884 886
885 skb_kill_datagram(sk, skb, flags); 887 skb_kill_datagram(sk, skb, flags);
886 888
@@ -912,11 +914,6 @@ int udp_disconnect(struct sock *sk, int flags)
912 return 0; 914 return 0;
913} 915}
914 916
915static void udp_close(struct sock *sk, long timeout)
916{
917 sk_common_release(sk);
918}
919
920/* return: 917/* return:
921 * 1 if the the UDP system should process it 918 * 1 if the the UDP system should process it
922 * 0 if we should drop this packet 919 * 0 if we should drop this packet
@@ -1022,7 +1019,7 @@ static int udp_encap_rcv(struct sock * sk, struct sk_buff *skb)
1022 * Note that in the success and error cases, the skb is assumed to 1019 * Note that in the success and error cases, the skb is assumed to
1023 * have either been requeued or freed. 1020 * have either been requeued or freed.
1024 */ 1021 */
1025static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) 1022int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
1026{ 1023{
1027 struct udp_sock *up = udp_sk(sk); 1024 struct udp_sock *up = udp_sk(sk);
1028 int rc; 1025 int rc;
@@ -1030,10 +1027,8 @@ static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
1030 /* 1027 /*
1031 * Charge it to the socket, dropping if the queue is full. 1028 * Charge it to the socket, dropping if the queue is full.
1032 */ 1029 */
1033 if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb)) { 1030 if (!xfrm4_policy_check(sk, XFRM_POLICY_IN, skb))
1034 kfree_skb(skb); 1031 goto drop;
1035 return -1;
1036 }
1037 nf_reset(skb); 1032 nf_reset(skb);
1038 1033
1039 if (up->encap_type) { 1034 if (up->encap_type) {
@@ -1057,31 +1052,68 @@ static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
1057 if (ret < 0) { 1052 if (ret < 0) {
1058 /* process the ESP packet */ 1053 /* process the ESP packet */
1059 ret = xfrm4_rcv_encap(skb, up->encap_type); 1054 ret = xfrm4_rcv_encap(skb, up->encap_type);
1060 UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS); 1055 UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS, up->pcflag);
1061 return -ret; 1056 return -ret;
1062 } 1057 }
1063 /* FALLTHROUGH -- it's a UDP Packet */ 1058 /* FALLTHROUGH -- it's a UDP Packet */
1064 } 1059 }
1065 1060
1066 if (sk->sk_filter && skb->ip_summed != CHECKSUM_UNNECESSARY) { 1061 /*
1067 if (__udp_checksum_complete(skb)) { 1062 * UDP-Lite specific tests, ignored on UDP sockets
1068 UDP_INC_STATS_BH(UDP_MIB_INERRORS); 1063 */
1069 kfree_skb(skb); 1064 if ((up->pcflag & UDPLITE_RECV_CC) && UDP_SKB_CB(skb)->partial_cov) {
1070 return -1; 1065
1066 /*
1067 * MIB statistics other than incrementing the error count are
1068 * disabled for the following two types of errors: these depend
1069 * on the application settings, not on the functioning of the
1070 * protocol stack as such.
1071 *
1072 * RFC 3828 here recommends (sec 3.3): "There should also be a
1073 * way ... to ... at least let the receiving application block
1074 * delivery of packets with coverage values less than a value
1075 * provided by the application."
1076 */
1077 if (up->pcrlen == 0) { /* full coverage was set */
1078 LIMIT_NETDEBUG(KERN_WARNING "UDPLITE: partial coverage "
1079 "%d while full coverage %d requested\n",
1080 UDP_SKB_CB(skb)->cscov, skb->len);
1081 goto drop;
1071 } 1082 }
1083 /* The next case involves violating the min. coverage requested
1084 * by the receiver. This is subtle: if receiver wants x and x is
1085 * greater than the buffersize/MTU then receiver will complain
1086 * that it wants x while sender emits packets of smaller size y.
1087 * Therefore the above ...()->partial_cov statement is essential.
1088 */
1089 if (UDP_SKB_CB(skb)->cscov < up->pcrlen) {
1090 LIMIT_NETDEBUG(KERN_WARNING
1091 "UDPLITE: coverage %d too small, need min %d\n",
1092 UDP_SKB_CB(skb)->cscov, up->pcrlen);
1093 goto drop;
1094 }
1095 }
1096
1097 if (sk->sk_filter && skb->ip_summed != CHECKSUM_UNNECESSARY) {
1098 if (__udp_lib_checksum_complete(skb))
1099 goto drop;
1072 skb->ip_summed = CHECKSUM_UNNECESSARY; 1100 skb->ip_summed = CHECKSUM_UNNECESSARY;
1073 } 1101 }
1074 1102
1075 if ((rc = sock_queue_rcv_skb(sk,skb)) < 0) { 1103 if ((rc = sock_queue_rcv_skb(sk,skb)) < 0) {
1076 /* Note that an ENOMEM error is charged twice */ 1104 /* Note that an ENOMEM error is charged twice */
1077 if (rc == -ENOMEM) 1105 if (rc == -ENOMEM)
1078 UDP_INC_STATS_BH(UDP_MIB_RCVBUFERRORS); 1106 UDP_INC_STATS_BH(UDP_MIB_RCVBUFERRORS, up->pcflag);
1079 UDP_INC_STATS_BH(UDP_MIB_INERRORS); 1107 goto drop;
1080 kfree_skb(skb);
1081 return -1;
1082 } 1108 }
1083 UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS); 1109
1110 UDP_INC_STATS_BH(UDP_MIB_INDATAGRAMS, up->pcflag);
1084 return 0; 1111 return 0;
1112
1113drop:
1114 UDP_INC_STATS_BH(UDP_MIB_INERRORS, up->pcflag);
1115 kfree_skb(skb);
1116 return -1;
1085} 1117}
1086 1118
1087/* 1119/*
@@ -1090,14 +1122,16 @@ static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
1090 * Note: called only from the BH handler context, 1122 * Note: called only from the BH handler context,
1091 * so we don't need to lock the hashes. 1123 * so we don't need to lock the hashes.
1092 */ 1124 */
1093static int udp_v4_mcast_deliver(struct sk_buff *skb, struct udphdr *uh, 1125static int __udp4_lib_mcast_deliver(struct sk_buff *skb,
1094 __be32 saddr, __be32 daddr) 1126 struct udphdr *uh,
1127 __be32 saddr, __be32 daddr,
1128 struct hlist_head udptable[])
1095{ 1129{
1096 struct sock *sk; 1130 struct sock *sk;
1097 int dif; 1131 int dif;
1098 1132
1099 read_lock(&udp_hash_lock); 1133 read_lock(&udp_hash_lock);
1100 sk = sk_head(&udp_hash[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]); 1134 sk = sk_head(&udptable[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]);
1101 dif = skb->dev->ifindex; 1135 dif = skb->dev->ifindex;
1102 sk = udp_v4_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif); 1136 sk = udp_v4_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif);
1103 if (sk) { 1137 if (sk) {
@@ -1131,65 +1165,75 @@ static int udp_v4_mcast_deliver(struct sk_buff *skb, struct udphdr *uh,
1131 * Otherwise, csum completion requires chacksumming packet body, 1165 * Otherwise, csum completion requires chacksumming packet body,
1132 * including udp header and folding it to skb->csum. 1166 * including udp header and folding it to skb->csum.
1133 */ 1167 */
1134static void udp_checksum_init(struct sk_buff *skb, struct udphdr *uh, 1168static inline void udp4_csum_init(struct sk_buff *skb, struct udphdr *uh)
1135 unsigned short ulen, __be32 saddr, __be32 daddr)
1136{ 1169{
1137 if (uh->check == 0) { 1170 if (uh->check == 0) {
1138 skb->ip_summed = CHECKSUM_UNNECESSARY; 1171 skb->ip_summed = CHECKSUM_UNNECESSARY;
1139 } else if (skb->ip_summed == CHECKSUM_COMPLETE) { 1172 } else if (skb->ip_summed == CHECKSUM_COMPLETE) {
1140 if (!udp_check(uh, ulen, saddr, daddr, skb->csum)) 1173 if (!csum_tcpudp_magic(skb->nh.iph->saddr, skb->nh.iph->daddr,
1174 skb->len, IPPROTO_UDP, skb->csum ))
1141 skb->ip_summed = CHECKSUM_UNNECESSARY; 1175 skb->ip_summed = CHECKSUM_UNNECESSARY;
1142 } 1176 }
1143 if (skb->ip_summed != CHECKSUM_UNNECESSARY) 1177 if (skb->ip_summed != CHECKSUM_UNNECESSARY)
1144 skb->csum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, 0); 1178 skb->csum = csum_tcpudp_nofold(skb->nh.iph->saddr,
1179 skb->nh.iph->daddr,
1180 skb->len, IPPROTO_UDP, 0);
1145 /* Probably, we should checksum udp header (it should be in cache 1181 /* Probably, we should checksum udp header (it should be in cache
1146 * in any case) and data in tiny packets (< rx copybreak). 1182 * in any case) and data in tiny packets (< rx copybreak).
1147 */ 1183 */
1184
1185 /* UDP = UDP-Lite with a non-partial checksum coverage */
1186 UDP_SKB_CB(skb)->partial_cov = 0;
1148} 1187}
1149 1188
1150/* 1189/*
1151 * All we need to do is get the socket, and then do a checksum. 1190 * All we need to do is get the socket, and then do a checksum.
1152 */ 1191 */
1153 1192
1154int udp_rcv(struct sk_buff *skb) 1193int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
1194 int is_udplite)
1155{ 1195{
1156 struct sock *sk; 1196 struct sock *sk;
1157 struct udphdr *uh; 1197 struct udphdr *uh = skb->h.uh;
1158 unsigned short ulen; 1198 unsigned short ulen;
1159 struct rtable *rt = (struct rtable*)skb->dst; 1199 struct rtable *rt = (struct rtable*)skb->dst;
1160 __be32 saddr = skb->nh.iph->saddr; 1200 __be32 saddr = skb->nh.iph->saddr;
1161 __be32 daddr = skb->nh.iph->daddr; 1201 __be32 daddr = skb->nh.iph->daddr;
1162 int len = skb->len;
1163 1202
1164 /* 1203 /*
1165 * Validate the packet and the UDP length. 1204 * Validate the packet.
1166 */ 1205 */
1167 if (!pskb_may_pull(skb, sizeof(struct udphdr))) 1206 if (!pskb_may_pull(skb, sizeof(struct udphdr)))
1168 goto no_header; 1207 goto drop; /* No space for header. */
1169
1170 uh = skb->h.uh;
1171 1208
1172 ulen = ntohs(uh->len); 1209 ulen = ntohs(uh->len);
1173 1210 if (ulen > skb->len)
1174 if (ulen > len || ulen < sizeof(*uh))
1175 goto short_packet; 1211 goto short_packet;
1176 1212
1177 if (pskb_trim_rcsum(skb, ulen)) 1213 if(! is_udplite ) { /* UDP validates ulen. */
1178 goto short_packet; 1214
1215 if (ulen < sizeof(*uh) || pskb_trim_rcsum(skb, ulen))
1216 goto short_packet;
1179 1217
1180 udp_checksum_init(skb, uh, ulen, saddr, daddr); 1218 udp4_csum_init(skb, uh);
1219
1220 } else { /* UDP-Lite validates cscov. */
1221 if (udplite4_csum_init(skb, uh))
1222 goto csum_error;
1223 }
1181 1224
1182 if(rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST)) 1225 if(rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST))
1183 return udp_v4_mcast_deliver(skb, uh, saddr, daddr); 1226 return __udp4_lib_mcast_deliver(skb, uh, saddr, daddr, udptable);
1184 1227
1185 sk = udp_v4_lookup(saddr, uh->source, daddr, uh->dest, skb->dev->ifindex); 1228 sk = __udp4_lib_lookup(saddr, uh->source, daddr, uh->dest,
1229 skb->dev->ifindex, udptable );
1186 1230
1187 if (sk != NULL) { 1231 if (sk != NULL) {
1188 int ret = udp_queue_rcv_skb(sk, skb); 1232 int ret = udp_queue_rcv_skb(sk, skb);
1189 sock_put(sk); 1233 sock_put(sk);
1190 1234
1191 /* a return value > 0 means to resubmit the input, but 1235 /* a return value > 0 means to resubmit the input, but
1192 * it it wants the return to be -protocol, or 0 1236 * it wants the return to be -protocol, or 0
1193 */ 1237 */
1194 if (ret > 0) 1238 if (ret > 0)
1195 return -ret; 1239 return -ret;
@@ -1201,10 +1245,10 @@ int udp_rcv(struct sk_buff *skb)
1201 nf_reset(skb); 1245 nf_reset(skb);
1202 1246
1203 /* No socket. Drop packet silently, if checksum is wrong */ 1247 /* No socket. Drop packet silently, if checksum is wrong */
1204 if (udp_checksum_complete(skb)) 1248 if (udp_lib_checksum_complete(skb))
1205 goto csum_error; 1249 goto csum_error;
1206 1250
1207 UDP_INC_STATS_BH(UDP_MIB_NOPORTS); 1251 UDP_INC_STATS_BH(UDP_MIB_NOPORTS, is_udplite);
1208 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); 1252 icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0);
1209 1253
1210 /* 1254 /*
@@ -1215,36 +1259,40 @@ int udp_rcv(struct sk_buff *skb)
1215 return(0); 1259 return(0);
1216 1260
1217short_packet: 1261short_packet:
1218 LIMIT_NETDEBUG(KERN_DEBUG "UDP: short packet: From %u.%u.%u.%u:%u %d/%d to %u.%u.%u.%u:%u\n", 1262 LIMIT_NETDEBUG(KERN_DEBUG "UDP%s: short packet: From %u.%u.%u.%u:%u %d/%d to %u.%u.%u.%u:%u\n",
1263 is_udplite? "-Lite" : "",
1219 NIPQUAD(saddr), 1264 NIPQUAD(saddr),
1220 ntohs(uh->source), 1265 ntohs(uh->source),
1221 ulen, 1266 ulen,
1222 len, 1267 skb->len,
1223 NIPQUAD(daddr), 1268 NIPQUAD(daddr),
1224 ntohs(uh->dest)); 1269 ntohs(uh->dest));
1225no_header: 1270 goto drop;
1226 UDP_INC_STATS_BH(UDP_MIB_INERRORS);
1227 kfree_skb(skb);
1228 return(0);
1229 1271
1230csum_error: 1272csum_error:
1231 /* 1273 /*
1232 * RFC1122: OK. Discards the bad packet silently (as far as 1274 * RFC1122: OK. Discards the bad packet silently (as far as
1233 * the network is concerned, anyway) as per 4.1.3.4 (MUST). 1275 * the network is concerned, anyway) as per 4.1.3.4 (MUST).
1234 */ 1276 */
1235 LIMIT_NETDEBUG(KERN_DEBUG "UDP: bad checksum. From %d.%d.%d.%d:%d to %d.%d.%d.%d:%d ulen %d\n", 1277 LIMIT_NETDEBUG(KERN_DEBUG "UDP%s: bad checksum. From %d.%d.%d.%d:%d to %d.%d.%d.%d:%d ulen %d\n",
1278 is_udplite? "-Lite" : "",
1236 NIPQUAD(saddr), 1279 NIPQUAD(saddr),
1237 ntohs(uh->source), 1280 ntohs(uh->source),
1238 NIPQUAD(daddr), 1281 NIPQUAD(daddr),
1239 ntohs(uh->dest), 1282 ntohs(uh->dest),
1240 ulen); 1283 ulen);
1241drop: 1284drop:
1242 UDP_INC_STATS_BH(UDP_MIB_INERRORS); 1285 UDP_INC_STATS_BH(UDP_MIB_INERRORS, is_udplite);
1243 kfree_skb(skb); 1286 kfree_skb(skb);
1244 return(0); 1287 return(0);
1245} 1288}
1246 1289
1247static int udp_destroy_sock(struct sock *sk) 1290__inline__ int udp_rcv(struct sk_buff *skb)
1291{
1292 return __udp4_lib_rcv(skb, udp_hash, 0);
1293}
1294
1295int udp_destroy_sock(struct sock *sk)
1248{ 1296{
1249 lock_sock(sk); 1297 lock_sock(sk);
1250 udp_flush_pending_frames(sk); 1298 udp_flush_pending_frames(sk);
@@ -1255,8 +1303,9 @@ static int udp_destroy_sock(struct sock *sk)
1255/* 1303/*
1256 * Socket option code for UDP 1304 * Socket option code for UDP
1257 */ 1305 */
1258static int do_udp_setsockopt(struct sock *sk, int level, int optname, 1306int udp_lib_setsockopt(struct sock *sk, int level, int optname,
1259 char __user *optval, int optlen) 1307 char __user *optval, int optlen,
1308 int (*push_pending_frames)(struct sock *))
1260{ 1309{
1261 struct udp_sock *up = udp_sk(sk); 1310 struct udp_sock *up = udp_sk(sk);
1262 int val; 1311 int val;
@@ -1275,7 +1324,7 @@ static int do_udp_setsockopt(struct sock *sk, int level, int optname,
1275 } else { 1324 } else {
1276 up->corkflag = 0; 1325 up->corkflag = 0;
1277 lock_sock(sk); 1326 lock_sock(sk);
1278 udp_push_pending_frames(sk, up); 1327 (*push_pending_frames)(sk);
1279 release_sock(sk); 1328 release_sock(sk);
1280 } 1329 }
1281 break; 1330 break;
@@ -1293,6 +1342,32 @@ static int do_udp_setsockopt(struct sock *sk, int level, int optname,
1293 } 1342 }
1294 break; 1343 break;
1295 1344
1345 /*
1346 * UDP-Lite's partial checksum coverage (RFC 3828).
1347 */
1348 /* The sender sets actual checksum coverage length via this option.
1349 * The case coverage > packet length is handled by send module. */
1350 case UDPLITE_SEND_CSCOV:
1351 if (!up->pcflag) /* Disable the option on UDP sockets */
1352 return -ENOPROTOOPT;
1353 if (val != 0 && val < 8) /* Illegal coverage: use default (8) */
1354 val = 8;
1355 up->pcslen = val;
1356 up->pcflag |= UDPLITE_SEND_CC;
1357 break;
1358
1359 /* The receiver specifies a minimum checksum coverage value. To make
1360 * sense, this should be set to at least 8 (as done below). If zero is
1361 * used, this again means full checksum coverage. */
1362 case UDPLITE_RECV_CSCOV:
1363 if (!up->pcflag) /* Disable the option on UDP sockets */
1364 return -ENOPROTOOPT;
1365 if (val != 0 && val < 8) /* Avoid silly minimal values. */
1366 val = 8;
1367 up->pcrlen = val;
1368 up->pcflag |= UDPLITE_RECV_CC;
1369 break;
1370
1296 default: 1371 default:
1297 err = -ENOPROTOOPT; 1372 err = -ENOPROTOOPT;
1298 break; 1373 break;
@@ -1301,26 +1376,28 @@ static int do_udp_setsockopt(struct sock *sk, int level, int optname,
1301 return err; 1376 return err;
1302} 1377}
1303 1378
1304static int udp_setsockopt(struct sock *sk, int level, int optname, 1379int udp_setsockopt(struct sock *sk, int level, int optname,
1305 char __user *optval, int optlen) 1380 char __user *optval, int optlen)
1306{ 1381{
1307 if (level != SOL_UDP) 1382 if (level == SOL_UDP || level == SOL_UDPLITE)
1308 return ip_setsockopt(sk, level, optname, optval, optlen); 1383 return udp_lib_setsockopt(sk, level, optname, optval, optlen,
1309 return do_udp_setsockopt(sk, level, optname, optval, optlen); 1384 udp_push_pending_frames);
1385 return ip_setsockopt(sk, level, optname, optval, optlen);
1310} 1386}
1311 1387
1312#ifdef CONFIG_COMPAT 1388#ifdef CONFIG_COMPAT
1313static int compat_udp_setsockopt(struct sock *sk, int level, int optname, 1389int compat_udp_setsockopt(struct sock *sk, int level, int optname,
1314 char __user *optval, int optlen) 1390 char __user *optval, int optlen)
1315{ 1391{
1316 if (level != SOL_UDP) 1392 if (level == SOL_UDP || level == SOL_UDPLITE)
1317 return compat_ip_setsockopt(sk, level, optname, optval, optlen); 1393 return udp_lib_setsockopt(sk, level, optname, optval, optlen,
1318 return do_udp_setsockopt(sk, level, optname, optval, optlen); 1394 udp_push_pending_frames);
1395 return compat_ip_setsockopt(sk, level, optname, optval, optlen);
1319} 1396}
1320#endif 1397#endif
1321 1398
1322static int do_udp_getsockopt(struct sock *sk, int level, int optname, 1399int udp_lib_getsockopt(struct sock *sk, int level, int optname,
1323 char __user *optval, int __user *optlen) 1400 char __user *optval, int __user *optlen)
1324{ 1401{
1325 struct udp_sock *up = udp_sk(sk); 1402 struct udp_sock *up = udp_sk(sk);
1326 int val, len; 1403 int val, len;
@@ -1342,6 +1419,16 @@ static int do_udp_getsockopt(struct sock *sk, int level, int optname,
1342 val = up->encap_type; 1419 val = up->encap_type;
1343 break; 1420 break;
1344 1421
1422 /* The following two cannot be changed on UDP sockets, the return is
1423 * always 0 (which corresponds to the full checksum coverage of UDP). */
1424 case UDPLITE_SEND_CSCOV:
1425 val = up->pcslen;
1426 break;
1427
1428 case UDPLITE_RECV_CSCOV:
1429 val = up->pcrlen;
1430 break;
1431
1345 default: 1432 default:
1346 return -ENOPROTOOPT; 1433 return -ENOPROTOOPT;
1347 }; 1434 };
@@ -1353,21 +1440,21 @@ static int do_udp_getsockopt(struct sock *sk, int level, int optname,
1353 return 0; 1440 return 0;
1354} 1441}
1355 1442
1356static int udp_getsockopt(struct sock *sk, int level, int optname, 1443int udp_getsockopt(struct sock *sk, int level, int optname,
1357 char __user *optval, int __user *optlen) 1444 char __user *optval, int __user *optlen)
1358{ 1445{
1359 if (level != SOL_UDP) 1446 if (level == SOL_UDP || level == SOL_UDPLITE)
1360 return ip_getsockopt(sk, level, optname, optval, optlen); 1447 return udp_lib_getsockopt(sk, level, optname, optval, optlen);
1361 return do_udp_getsockopt(sk, level, optname, optval, optlen); 1448 return ip_getsockopt(sk, level, optname, optval, optlen);
1362} 1449}
1363 1450
1364#ifdef CONFIG_COMPAT 1451#ifdef CONFIG_COMPAT
1365static int compat_udp_getsockopt(struct sock *sk, int level, int optname, 1452int compat_udp_getsockopt(struct sock *sk, int level, int optname,
1366 char __user *optval, int __user *optlen) 1453 char __user *optval, int __user *optlen)
1367{ 1454{
1368 if (level != SOL_UDP) 1455 if (level == SOL_UDP || level == SOL_UDPLITE)
1369 return compat_ip_getsockopt(sk, level, optname, optval, optlen); 1456 return udp_lib_getsockopt(sk, level, optname, optval, optlen);
1370 return do_udp_getsockopt(sk, level, optname, optval, optlen); 1457 return compat_ip_getsockopt(sk, level, optname, optval, optlen);
1371} 1458}
1372#endif 1459#endif
1373/** 1460/**
@@ -1387,7 +1474,8 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait)
1387{ 1474{
1388 unsigned int mask = datagram_poll(file, sock, wait); 1475 unsigned int mask = datagram_poll(file, sock, wait);
1389 struct sock *sk = sock->sk; 1476 struct sock *sk = sock->sk;
1390 1477 int is_lite = IS_UDPLITE(sk);
1478
1391 /* Check for false positives due to checksum errors */ 1479 /* Check for false positives due to checksum errors */
1392 if ( (mask & POLLRDNORM) && 1480 if ( (mask & POLLRDNORM) &&
1393 !(file->f_flags & O_NONBLOCK) && 1481 !(file->f_flags & O_NONBLOCK) &&
@@ -1397,8 +1485,8 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait)
1397 1485
1398 spin_lock_bh(&rcvq->lock); 1486 spin_lock_bh(&rcvq->lock);
1399 while ((skb = skb_peek(rcvq)) != NULL) { 1487 while ((skb = skb_peek(rcvq)) != NULL) {
1400 if (udp_checksum_complete(skb)) { 1488 if (udp_lib_checksum_complete(skb)) {
1401 UDP_INC_STATS_BH(UDP_MIB_INERRORS); 1489 UDP_INC_STATS_BH(UDP_MIB_INERRORS, is_lite);
1402 __skb_unlink(skb, rcvq); 1490 __skb_unlink(skb, rcvq);
1403 kfree_skb(skb); 1491 kfree_skb(skb);
1404 } else { 1492 } else {
@@ -1420,7 +1508,7 @@ unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait)
1420struct proto udp_prot = { 1508struct proto udp_prot = {
1421 .name = "UDP", 1509 .name = "UDP",
1422 .owner = THIS_MODULE, 1510 .owner = THIS_MODULE,
1423 .close = udp_close, 1511 .close = udp_lib_close,
1424 .connect = ip4_datagram_connect, 1512 .connect = ip4_datagram_connect,
1425 .disconnect = udp_disconnect, 1513 .disconnect = udp_disconnect,
1426 .ioctl = udp_ioctl, 1514 .ioctl = udp_ioctl,
@@ -1431,8 +1519,8 @@ struct proto udp_prot = {
1431 .recvmsg = udp_recvmsg, 1519 .recvmsg = udp_recvmsg,
1432 .sendpage = udp_sendpage, 1520 .sendpage = udp_sendpage,
1433 .backlog_rcv = udp_queue_rcv_skb, 1521 .backlog_rcv = udp_queue_rcv_skb,
1434 .hash = udp_v4_hash, 1522 .hash = udp_lib_hash,
1435 .unhash = udp_v4_unhash, 1523 .unhash = udp_lib_unhash,
1436 .get_port = udp_v4_get_port, 1524 .get_port = udp_v4_get_port,
1437 .obj_size = sizeof(struct udp_sock), 1525 .obj_size = sizeof(struct udp_sock),
1438#ifdef CONFIG_COMPAT 1526#ifdef CONFIG_COMPAT
@@ -1451,7 +1539,7 @@ static struct sock *udp_get_first(struct seq_file *seq)
1451 1539
1452 for (state->bucket = 0; state->bucket < UDP_HTABLE_SIZE; ++state->bucket) { 1540 for (state->bucket = 0; state->bucket < UDP_HTABLE_SIZE; ++state->bucket) {
1453 struct hlist_node *node; 1541 struct hlist_node *node;
1454 sk_for_each(sk, node, &udp_hash[state->bucket]) { 1542 sk_for_each(sk, node, state->hashtable + state->bucket) {
1455 if (sk->sk_family == state->family) 1543 if (sk->sk_family == state->family)
1456 goto found; 1544 goto found;
1457 } 1545 }
@@ -1472,7 +1560,7 @@ try_again:
1472 } while (sk && sk->sk_family != state->family); 1560 } while (sk && sk->sk_family != state->family);
1473 1561
1474 if (!sk && ++state->bucket < UDP_HTABLE_SIZE) { 1562 if (!sk && ++state->bucket < UDP_HTABLE_SIZE) {
1475 sk = sk_head(&udp_hash[state->bucket]); 1563 sk = sk_head(state->hashtable + state->bucket);
1476 goto try_again; 1564 goto try_again;
1477 } 1565 }
1478 return sk; 1566 return sk;
@@ -1522,6 +1610,7 @@ static int udp_seq_open(struct inode *inode, struct file *file)
1522 if (!s) 1610 if (!s)
1523 goto out; 1611 goto out;
1524 s->family = afinfo->family; 1612 s->family = afinfo->family;
1613 s->hashtable = afinfo->hashtable;
1525 s->seq_ops.start = udp_seq_start; 1614 s->seq_ops.start = udp_seq_start;
1526 s->seq_ops.next = udp_seq_next; 1615 s->seq_ops.next = udp_seq_next;
1527 s->seq_ops.show = afinfo->seq_show; 1616 s->seq_ops.show = afinfo->seq_show;
@@ -1588,7 +1677,7 @@ static void udp4_format_sock(struct sock *sp, char *tmpbuf, int bucket)
1588 atomic_read(&sp->sk_refcnt), sp); 1677 atomic_read(&sp->sk_refcnt), sp);
1589} 1678}
1590 1679
1591static int udp4_seq_show(struct seq_file *seq, void *v) 1680int udp4_seq_show(struct seq_file *seq, void *v)
1592{ 1681{
1593 if (v == SEQ_START_TOKEN) 1682 if (v == SEQ_START_TOKEN)
1594 seq_printf(seq, "%-127s\n", 1683 seq_printf(seq, "%-127s\n",
@@ -1611,6 +1700,7 @@ static struct udp_seq_afinfo udp4_seq_afinfo = {
1611 .owner = THIS_MODULE, 1700 .owner = THIS_MODULE,
1612 .name = "udp", 1701 .name = "udp",
1613 .family = AF_INET, 1702 .family = AF_INET,
1703 .hashtable = udp_hash,
1614 .seq_show = udp4_seq_show, 1704 .seq_show = udp4_seq_show,
1615 .seq_fops = &udp4_seq_fops, 1705 .seq_fops = &udp4_seq_fops,
1616}; 1706};
@@ -1633,6 +1723,8 @@ EXPORT_SYMBOL(udp_ioctl);
1633EXPORT_SYMBOL(udp_get_port); 1723EXPORT_SYMBOL(udp_get_port);
1634EXPORT_SYMBOL(udp_prot); 1724EXPORT_SYMBOL(udp_prot);
1635EXPORT_SYMBOL(udp_sendmsg); 1725EXPORT_SYMBOL(udp_sendmsg);
1726EXPORT_SYMBOL(udp_lib_getsockopt);
1727EXPORT_SYMBOL(udp_lib_setsockopt);
1636EXPORT_SYMBOL(udp_poll); 1728EXPORT_SYMBOL(udp_poll);
1637 1729
1638#ifdef CONFIG_PROC_FS 1730#ifdef CONFIG_PROC_FS
diff --git a/net/ipv4/udp_impl.h b/net/ipv4/udp_impl.h
new file mode 100644
index 0000000000..f6f4277ba6
--- /dev/null
+++ b/net/ipv4/udp_impl.h
@@ -0,0 +1,38 @@
1#ifndef _UDP4_IMPL_H
2#define _UDP4_IMPL_H
3#include <net/udp.h>
4#include <net/udplite.h>
5#include <net/protocol.h>
6#include <net/inet_common.h>
7
8extern int __udp4_lib_rcv(struct sk_buff *, struct hlist_head [], int );
9extern void __udp4_lib_err(struct sk_buff *, u32, struct hlist_head []);
10
11extern int __udp_lib_get_port(struct sock *sk, unsigned short snum,
12 struct hlist_head udptable[], int *port_rover,
13 int (*)(const struct sock*,const struct sock*));
14extern int ipv4_rcv_saddr_equal(const struct sock *, const struct sock *);
15
16
17extern int udp_setsockopt(struct sock *sk, int level, int optname,
18 char __user *optval, int optlen);
19extern int udp_getsockopt(struct sock *sk, int level, int optname,
20 char __user *optval, int __user *optlen);
21
22#ifdef CONFIG_COMPAT
23extern int compat_udp_setsockopt(struct sock *sk, int level, int optname,
24 char __user *optval, int optlen);
25extern int compat_udp_getsockopt(struct sock *sk, int level, int optname,
26 char __user *optval, int __user *optlen);
27#endif
28extern int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
29 size_t len, int noblock, int flags, int *addr_len);
30extern int udp_sendpage(struct sock *sk, struct page *page, int offset,
31 size_t size, int flags);
32extern int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb);
33extern int udp_destroy_sock(struct sock *sk);
34
35#ifdef CONFIG_PROC_FS
36extern int udp4_seq_show(struct seq_file *seq, void *v);
37#endif
38#endif /* _UDP4_IMPL_H */
diff --git a/net/ipv4/udplite.c b/net/ipv4/udplite.c
new file mode 100644
index 0000000000..b28fe1edf9
--- /dev/null
+++ b/net/ipv4/udplite.c
@@ -0,0 +1,119 @@
1/*
2 * UDPLITE An implementation of the UDP-Lite protocol (RFC 3828).
3 *
4 * Version: $Id: udplite.c,v 1.25 2006/10/19 07:22:36 gerrit Exp $
5 *
6 * Authors: Gerrit Renker <gerrit@erg.abdn.ac.uk>
7 *
8 * Changes:
9 * Fixes:
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 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 */
15#include "udp_impl.h"
16DEFINE_SNMP_STAT(struct udp_mib, udplite_statistics) __read_mostly;
17
18struct hlist_head udplite_hash[UDP_HTABLE_SIZE];
19static int udplite_port_rover;
20
21int udplite_get_port(struct sock *sk, unsigned short p,
22 int (*c)(const struct sock *, const struct sock *))
23{
24 return __udp_lib_get_port(sk, p, udplite_hash, &udplite_port_rover, c);
25}
26
27static int udplite_v4_get_port(struct sock *sk, unsigned short snum)
28{
29 return udplite_get_port(sk, snum, ipv4_rcv_saddr_equal);
30}
31
32static int udplite_rcv(struct sk_buff *skb)
33{
34 return __udp4_lib_rcv(skb, udplite_hash, 1);
35}
36
37static void udplite_err(struct sk_buff *skb, u32 info)
38{
39 return __udp4_lib_err(skb, info, udplite_hash);
40}
41
42static struct net_protocol udplite_protocol = {
43 .handler = udplite_rcv,
44 .err_handler = udplite_err,
45 .no_policy = 1,
46};
47
48struct proto udplite_prot = {
49 .name = "UDP-Lite",
50 .owner = THIS_MODULE,
51 .close = udp_lib_close,
52 .connect = ip4_datagram_connect,
53 .disconnect = udp_disconnect,
54 .ioctl = udp_ioctl,
55 .init = udplite_sk_init,
56 .destroy = udp_destroy_sock,
57 .setsockopt = udp_setsockopt,
58 .getsockopt = udp_getsockopt,
59 .sendmsg = udp_sendmsg,
60 .recvmsg = udp_recvmsg,
61 .sendpage = udp_sendpage,
62 .backlog_rcv = udp_queue_rcv_skb,
63 .hash = udp_lib_hash,
64 .unhash = udp_lib_unhash,
65 .get_port = udplite_v4_get_port,
66 .obj_size = sizeof(struct udp_sock),
67#ifdef CONFIG_COMPAT
68 .compat_setsockopt = compat_udp_setsockopt,
69 .compat_getsockopt = compat_udp_getsockopt,
70#endif
71};
72
73static struct inet_protosw udplite4_protosw = {
74 .type = SOCK_DGRAM,
75 .protocol = IPPROTO_UDPLITE,
76 .prot = &udplite_prot,
77 .ops = &inet_dgram_ops,
78 .capability = -1,
79 .no_check = 0, /* must checksum (RFC 3828) */
80 .flags = INET_PROTOSW_PERMANENT,
81};
82
83#ifdef CONFIG_PROC_FS
84static struct file_operations udplite4_seq_fops;
85static struct udp_seq_afinfo udplite4_seq_afinfo = {
86 .owner = THIS_MODULE,
87 .name = "udplite",
88 .family = AF_INET,
89 .hashtable = udplite_hash,
90 .seq_show = udp4_seq_show,
91 .seq_fops = &udplite4_seq_fops,
92};
93#endif
94
95void __init udplite4_register(void)
96{
97 if (proto_register(&udplite_prot, 1))
98 goto out_register_err;
99
100 if (inet_add_protocol(&udplite_protocol, IPPROTO_UDPLITE) < 0)
101 goto out_unregister_proto;
102
103 inet_register_protosw(&udplite4_protosw);
104
105#ifdef CONFIG_PROC_FS
106 if (udp_proc_register(&udplite4_seq_afinfo)) /* udplite4_proc_init() */
107 printk(KERN_ERR "%s: Cannot register /proc!\n", __FUNCTION__);
108#endif
109 return;
110
111out_unregister_proto:
112 proto_unregister(&udplite_prot);
113out_register_err:
114 printk(KERN_CRIT "%s: Cannot add UDP-Lite protocol.\n", __FUNCTION__);
115}
116
117EXPORT_SYMBOL(udplite_hash);
118EXPORT_SYMBOL(udplite_prot);
119EXPORT_SYMBOL(udplite_get_port);
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 1bed0cdf53..fb9f69c616 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -72,8 +72,8 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
72 struct dst_entry *dst, *dst_prev; 72 struct dst_entry *dst, *dst_prev;
73 struct rtable *rt0 = (struct rtable*)(*dst_p); 73 struct rtable *rt0 = (struct rtable*)(*dst_p);
74 struct rtable *rt = rt0; 74 struct rtable *rt = rt0;
75 u32 remote = fl->fl4_dst; 75 __be32 remote = fl->fl4_dst;
76 u32 local = fl->fl4_src; 76 __be32 local = fl->fl4_src;
77 struct flowi fl_tunnel = { 77 struct flowi fl_tunnel = {
78 .nl_u = { 78 .nl_u = {
79 .ip4_u = { 79 .ip4_u = {
@@ -199,11 +199,12 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl)
199 if (!(iph->frag_off & htons(IP_MF | IP_OFFSET))) { 199 if (!(iph->frag_off & htons(IP_MF | IP_OFFSET))) {
200 switch (iph->protocol) { 200 switch (iph->protocol) {
201 case IPPROTO_UDP: 201 case IPPROTO_UDP:
202 case IPPROTO_UDPLITE:
202 case IPPROTO_TCP: 203 case IPPROTO_TCP:
203 case IPPROTO_SCTP: 204 case IPPROTO_SCTP:
204 case IPPROTO_DCCP: 205 case IPPROTO_DCCP:
205 if (pskb_may_pull(skb, xprth + 4 - skb->data)) { 206 if (pskb_may_pull(skb, xprth + 4 - skb->data)) {
206 u16 *ports = (u16 *)xprth; 207 __be16 *ports = (__be16 *)xprth;
207 208
208 fl->fl_ip_sport = ports[0]; 209 fl->fl_ip_sport = ports[0];
209 fl->fl_ip_dport = ports[1]; 210 fl->fl_ip_dport = ports[1];
@@ -273,6 +274,8 @@ static void xfrm4_dst_destroy(struct dst_entry *dst)
273 274
274 if (likely(xdst->u.rt.idev)) 275 if (likely(xdst->u.rt.idev))
275 in_dev_put(xdst->u.rt.idev); 276 in_dev_put(xdst->u.rt.idev);
277 if (likely(xdst->u.rt.peer))
278 inet_putpeer(xdst->u.rt.peer);
276 xfrm_dst_destroy(xdst); 279 xfrm_dst_destroy(xdst);
277} 280}
278 281
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig
index 6e48f52e19..deb4101a2a 100644
--- a/net/ipv6/Kconfig
+++ b/net/ipv6/Kconfig
@@ -196,10 +196,3 @@ config IPV6_SUBTREES
196 196
197 If unsure, say N. 197 If unsure, say N.
198 198
199config IPV6_ROUTE_FWMARK
200 bool "IPv6: use netfilter MARK value as routing key"
201 depends on IPV6_MULTIPLE_TABLES && NETFILTER
202 ---help---
203 If you say Y here, you will be able to specify different routes for
204 packets with different mark values (see iptables(8), MARK target).
205
diff --git a/net/ipv6/Makefile b/net/ipv6/Makefile
index addcc011bc..8bacda109b 100644
--- a/net/ipv6/Makefile
+++ b/net/ipv6/Makefile
@@ -5,8 +5,8 @@
5obj-$(CONFIG_IPV6) += ipv6.o 5obj-$(CONFIG_IPV6) += ipv6.o
6 6
7ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o \ 7ipv6-objs := af_inet6.o anycast.o ip6_output.o ip6_input.o addrconf.o \
8 route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o raw.o \ 8 route.o ip6_fib.o ipv6_sockglue.o ndisc.o udp.o udplite.o \
9 protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \ 9 raw.o protocol.o icmp.o mcast.o reassembly.o tcp_ipv6.o \
10 exthdrs.o sysctl_net_ipv6.o datagram.o proc.o \ 10 exthdrs.o sysctl_net_ipv6.o datagram.o proc.o \
11 ip6_flowlabel.o ipv6_syms.o inet6_connection_sock.o 11 ip6_flowlabel.o ipv6_syms.o inet6_connection_sock.o
12 12
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index b312a5f7a7..171e5b55d7 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -232,7 +232,7 @@ static inline unsigned ipv6_addr_scope2type(unsigned scope)
232 232
233int __ipv6_addr_type(const struct in6_addr *addr) 233int __ipv6_addr_type(const struct in6_addr *addr)
234{ 234{
235 u32 st; 235 __be32 st;
236 236
237 st = addr->s6_addr32[0]; 237 st = addr->s6_addr32[0];
238 238
@@ -413,8 +413,6 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
413 if (netif_carrier_ok(dev)) 413 if (netif_carrier_ok(dev))
414 ndev->if_flags |= IF_READY; 414 ndev->if_flags |= IF_READY;
415 415
416 /* protected by rtnl_lock */
417 rcu_assign_pointer(dev->ip6_ptr, ndev);
418 416
419 ipv6_mc_init_dev(ndev); 417 ipv6_mc_init_dev(ndev);
420 ndev->tstamp = jiffies; 418 ndev->tstamp = jiffies;
@@ -425,6 +423,8 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
425 NULL); 423 NULL);
426 addrconf_sysctl_register(ndev, &ndev->cnf); 424 addrconf_sysctl_register(ndev, &ndev->cnf);
427#endif 425#endif
426 /* protected by rtnl_lock */
427 rcu_assign_pointer(dev->ip6_ptr, ndev);
428 return ndev; 428 return ndev;
429} 429}
430 430
@@ -1164,7 +1164,7 @@ record_it:
1164int ipv6_get_saddr(struct dst_entry *dst, 1164int ipv6_get_saddr(struct dst_entry *dst,
1165 struct in6_addr *daddr, struct in6_addr *saddr) 1165 struct in6_addr *daddr, struct in6_addr *saddr)
1166{ 1166{
1167 return ipv6_dev_get_saddr(dst ? ((struct rt6_info *)dst)->rt6i_idev->dev : NULL, daddr, saddr); 1167 return ipv6_dev_get_saddr(dst ? ip6_dst_idev(dst)->dev : NULL, daddr, saddr);
1168} 1168}
1169 1169
1170 1170
@@ -3098,10 +3098,9 @@ static inline int rt_scope(int ifa_scope)
3098 3098
3099static inline int inet6_ifaddr_msgsize(void) 3099static inline int inet6_ifaddr_msgsize(void)
3100{ 3100{
3101 return nlmsg_total_size(sizeof(struct ifaddrmsg) + 3101 return NLMSG_ALIGN(sizeof(struct ifaddrmsg))
3102 nla_total_size(16) + 3102 + nla_total_size(16) /* IFA_ADDRESS */
3103 nla_total_size(sizeof(struct ifa_cacheinfo)) + 3103 + nla_total_size(sizeof(struct ifa_cacheinfo));
3104 128);
3105} 3104}
3106 3105
3107static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa, 3106static int inet6_fill_ifaddr(struct sk_buff *skb, struct inet6_ifaddr *ifa,
@@ -3329,10 +3328,8 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh,
3329 3328
3330 err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).pid, 3329 err = inet6_fill_ifaddr(skb, ifa, NETLINK_CB(in_skb).pid,
3331 nlh->nlmsg_seq, RTM_NEWADDR, 0); 3330 nlh->nlmsg_seq, RTM_NEWADDR, 0);
3332 if (err < 0) { 3331 /* failure implies BUG in inet6_ifaddr_msgsize() */
3333 kfree_skb(skb); 3332 BUG_ON(err < 0);
3334 goto errout_ifa;
3335 }
3336 3333
3337 err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid); 3334 err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
3338errout_ifa: 3335errout_ifa:
@@ -3351,10 +3348,8 @@ static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
3351 goto errout; 3348 goto errout;
3352 3349
3353 err = inet6_fill_ifaddr(skb, ifa, 0, 0, event, 0); 3350 err = inet6_fill_ifaddr(skb, ifa, 0, 0, event, 0);
3354 if (err < 0) { 3351 /* failure implies BUG in inet6_ifaddr_msgsize() */
3355 kfree_skb(skb); 3352 BUG_ON(err < 0);
3356 goto errout;
3357 }
3358 3353
3359 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); 3354 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
3360errout: 3355errout:
@@ -3365,6 +3360,8 @@ errout:
3365static void inline ipv6_store_devconf(struct ipv6_devconf *cnf, 3360static void inline ipv6_store_devconf(struct ipv6_devconf *cnf,
3366 __s32 *array, int bytes) 3361 __s32 *array, int bytes)
3367{ 3362{
3363 BUG_ON(bytes < (DEVCONF_MAX * 4));
3364
3368 memset(array, 0, bytes); 3365 memset(array, 0, bytes);
3369 array[DEVCONF_FORWARDING] = cnf->forwarding; 3366 array[DEVCONF_FORWARDING] = cnf->forwarding;
3370 array[DEVCONF_HOPLIMIT] = cnf->hop_limit; 3367 array[DEVCONF_HOPLIMIT] = cnf->hop_limit;
@@ -3397,80 +3394,76 @@ static void inline ipv6_store_devconf(struct ipv6_devconf *cnf,
3397 array[DEVCONF_PROXY_NDP] = cnf->proxy_ndp; 3394 array[DEVCONF_PROXY_NDP] = cnf->proxy_ndp;
3398} 3395}
3399 3396
3400/* Maximum length of ifinfomsg attributes */ 3397static inline size_t inet6_if_nlmsg_size(void)
3401#define INET6_IFINFO_RTA_SPACE \ 3398{
3402 RTA_SPACE(IFNAMSIZ) /* IFNAME */ + \ 3399 return NLMSG_ALIGN(sizeof(struct ifinfomsg))
3403 RTA_SPACE(MAX_ADDR_LEN) /* ADDRESS */ + \ 3400 + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
3404 RTA_SPACE(sizeof(u32)) /* MTU */ + \ 3401 + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */
3405 RTA_SPACE(sizeof(int)) /* LINK */ + \ 3402 + nla_total_size(4) /* IFLA_MTU */
3406 RTA_SPACE(0) /* PROTINFO */ + \ 3403 + nla_total_size(4) /* IFLA_LINK */
3407 RTA_SPACE(sizeof(u32)) /* FLAGS */ + \ 3404 + nla_total_size( /* IFLA_PROTINFO */
3408 RTA_SPACE(sizeof(struct ifla_cacheinfo)) /* CACHEINFO */ + \ 3405 nla_total_size(4) /* IFLA_INET6_FLAGS */
3409 RTA_SPACE(sizeof(__s32[DEVCONF_MAX])) /* CONF */ 3406 + nla_total_size(sizeof(struct ifla_cacheinfo))
3407 + nla_total_size(DEVCONF_MAX * 4) /* IFLA_INET6_CONF */
3408 );
3409}
3410 3410
3411static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, 3411static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
3412 u32 pid, u32 seq, int event, unsigned int flags) 3412 u32 pid, u32 seq, int event, unsigned int flags)
3413{ 3413{
3414 struct net_device *dev = idev->dev; 3414 struct net_device *dev = idev->dev;
3415 __s32 *array = NULL; 3415 struct nlattr *conf;
3416 struct ifinfomsg *r; 3416 struct ifinfomsg *hdr;
3417 struct nlmsghdr *nlh; 3417 struct nlmsghdr *nlh;
3418 unsigned char *b = skb->tail; 3418 void *protoinfo;
3419 struct rtattr *subattr; 3419 struct ifla_cacheinfo ci;
3420 __u32 mtu = dev->mtu; 3420
3421 struct ifla_cacheinfo ci; 3421 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags);
3422 3422 if (nlh == NULL)
3423 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*r), flags); 3423 return -ENOBUFS;
3424 r = NLMSG_DATA(nlh); 3424
3425 r->ifi_family = AF_INET6; 3425 hdr = nlmsg_data(nlh);
3426 r->__ifi_pad = 0; 3426 hdr->ifi_family = AF_INET6;
3427 r->ifi_type = dev->type; 3427 hdr->__ifi_pad = 0;
3428 r->ifi_index = dev->ifindex; 3428 hdr->ifi_type = dev->type;
3429 r->ifi_flags = dev_get_flags(dev); 3429 hdr->ifi_index = dev->ifindex;
3430 r->ifi_change = 0; 3430 hdr->ifi_flags = dev_get_flags(dev);
3431 3431 hdr->ifi_change = 0;
3432 RTA_PUT(skb, IFLA_IFNAME, strlen(dev->name)+1, dev->name); 3432
3433 NLA_PUT_STRING(skb, IFLA_IFNAME, dev->name);
3433 3434
3434 if (dev->addr_len) 3435 if (dev->addr_len)
3435 RTA_PUT(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr); 3436 NLA_PUT(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr);
3436 3437
3437 RTA_PUT(skb, IFLA_MTU, sizeof(mtu), &mtu); 3438 NLA_PUT_U32(skb, IFLA_MTU, dev->mtu);
3438 if (dev->ifindex != dev->iflink) 3439 if (dev->ifindex != dev->iflink)
3439 RTA_PUT(skb, IFLA_LINK, sizeof(int), &dev->iflink); 3440 NLA_PUT_U32(skb, IFLA_LINK, dev->iflink);
3440
3441 subattr = (struct rtattr*)skb->tail;
3442 3441
3443 RTA_PUT(skb, IFLA_PROTINFO, 0, NULL); 3442 protoinfo = nla_nest_start(skb, IFLA_PROTINFO);
3443 if (protoinfo == NULL)
3444 goto nla_put_failure;
3444 3445
3445 /* return the device flags */ 3446 NLA_PUT_U32(skb, IFLA_INET6_FLAGS, idev->if_flags);
3446 RTA_PUT(skb, IFLA_INET6_FLAGS, sizeof(__u32), &idev->if_flags);
3447 3447
3448 /* return interface cacheinfo */
3449 ci.max_reasm_len = IPV6_MAXPLEN; 3448 ci.max_reasm_len = IPV6_MAXPLEN;
3450 ci.tstamp = (__u32)(TIME_DELTA(idev->tstamp, INITIAL_JIFFIES) / HZ * 100 3449 ci.tstamp = (__u32)(TIME_DELTA(idev->tstamp, INITIAL_JIFFIES) / HZ * 100
3451 + TIME_DELTA(idev->tstamp, INITIAL_JIFFIES) % HZ * 100 / HZ); 3450 + TIME_DELTA(idev->tstamp, INITIAL_JIFFIES) % HZ * 100 / HZ);
3452 ci.reachable_time = idev->nd_parms->reachable_time; 3451 ci.reachable_time = idev->nd_parms->reachable_time;
3453 ci.retrans_time = idev->nd_parms->retrans_time; 3452 ci.retrans_time = idev->nd_parms->retrans_time;
3454 RTA_PUT(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci); 3453 NLA_PUT(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci);
3455 3454
3456 /* return the device sysctl params */ 3455 conf = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32));
3457 if ((array = kmalloc(DEVCONF_MAX * sizeof(*array), GFP_ATOMIC)) == NULL) 3456 if (conf == NULL)
3458 goto rtattr_failure; 3457 goto nla_put_failure;
3459 ipv6_store_devconf(&idev->cnf, array, DEVCONF_MAX * sizeof(*array)); 3458 ipv6_store_devconf(&idev->cnf, nla_data(conf), nla_len(conf));
3460 RTA_PUT(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(*array), array);
3461 3459
3462 /* XXX - Statistics/MC not implemented */ 3460 /* XXX - Statistics/MC not implemented */
3463 subattr->rta_len = skb->tail - (u8*)subattr;
3464 3461
3465 nlh->nlmsg_len = skb->tail - b; 3462 nla_nest_end(skb, protoinfo);
3466 kfree(array); 3463 return nlmsg_end(skb, nlh);
3467 return skb->len;
3468 3464
3469nlmsg_failure: 3465nla_put_failure:
3470rtattr_failure: 3466 return nlmsg_cancel(skb, nlh);
3471 kfree(array);
3472 skb_trim(skb, b - skb->data);
3473 return -1;
3474} 3467}
3475 3468
3476static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) 3469static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
@@ -3501,18 +3494,15 @@ static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
3501void inet6_ifinfo_notify(int event, struct inet6_dev *idev) 3494void inet6_ifinfo_notify(int event, struct inet6_dev *idev)
3502{ 3495{
3503 struct sk_buff *skb; 3496 struct sk_buff *skb;
3504 int payload = sizeof(struct ifinfomsg) + INET6_IFINFO_RTA_SPACE;
3505 int err = -ENOBUFS; 3497 int err = -ENOBUFS;
3506 3498
3507 skb = nlmsg_new(nlmsg_total_size(payload), GFP_ATOMIC); 3499 skb = nlmsg_new(inet6_if_nlmsg_size(), GFP_ATOMIC);
3508 if (skb == NULL) 3500 if (skb == NULL)
3509 goto errout; 3501 goto errout;
3510 3502
3511 err = inet6_fill_ifinfo(skb, idev, 0, 0, event, 0); 3503 err = inet6_fill_ifinfo(skb, idev, 0, 0, event, 0);
3512 if (err < 0) { 3504 /* failure implies BUG in inet6_if_nlmsg_size() */
3513 kfree_skb(skb); 3505 BUG_ON(err < 0);
3514 goto errout;
3515 }
3516 3506
3517 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); 3507 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
3518errout: 3508errout:
@@ -3520,22 +3510,26 @@ errout:
3520 rtnl_set_sk_err(RTNLGRP_IPV6_IFADDR, err); 3510 rtnl_set_sk_err(RTNLGRP_IPV6_IFADDR, err);
3521} 3511}
3522 3512
3523/* Maximum length of prefix_cacheinfo attributes */ 3513static inline size_t inet6_prefix_nlmsg_size(void)
3524#define INET6_PREFIX_RTA_SPACE \ 3514{
3525 RTA_SPACE(sizeof(((struct prefix_info *)NULL)->prefix)) /* ADDRESS */ + \ 3515 return NLMSG_ALIGN(sizeof(struct prefixmsg))
3526 RTA_SPACE(sizeof(struct prefix_cacheinfo)) /* CACHEINFO */ 3516 + nla_total_size(sizeof(struct in6_addr))
3517 + nla_total_size(sizeof(struct prefix_cacheinfo));
3518}
3527 3519
3528static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev, 3520static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev,
3529 struct prefix_info *pinfo, u32 pid, u32 seq, 3521 struct prefix_info *pinfo, u32 pid, u32 seq,
3530 int event, unsigned int flags) 3522 int event, unsigned int flags)
3531{ 3523{
3532 struct prefixmsg *pmsg; 3524 struct prefixmsg *pmsg;
3533 struct nlmsghdr *nlh; 3525 struct nlmsghdr *nlh;
3534 unsigned char *b = skb->tail;
3535 struct prefix_cacheinfo ci; 3526 struct prefix_cacheinfo ci;
3536 3527
3537 nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*pmsg), flags); 3528 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*pmsg), flags);
3538 pmsg = NLMSG_DATA(nlh); 3529 if (nlh == NULL)
3530 return -ENOBUFS;
3531
3532 pmsg = nlmsg_data(nlh);
3539 pmsg->prefix_family = AF_INET6; 3533 pmsg->prefix_family = AF_INET6;
3540 pmsg->prefix_pad1 = 0; 3534 pmsg->prefix_pad1 = 0;
3541 pmsg->prefix_pad2 = 0; 3535 pmsg->prefix_pad2 = 0;
@@ -3543,44 +3537,37 @@ static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev,
3543 pmsg->prefix_len = pinfo->prefix_len; 3537 pmsg->prefix_len = pinfo->prefix_len;
3544 pmsg->prefix_type = pinfo->type; 3538 pmsg->prefix_type = pinfo->type;
3545 pmsg->prefix_pad3 = 0; 3539 pmsg->prefix_pad3 = 0;
3546
3547 pmsg->prefix_flags = 0; 3540 pmsg->prefix_flags = 0;
3548 if (pinfo->onlink) 3541 if (pinfo->onlink)
3549 pmsg->prefix_flags |= IF_PREFIX_ONLINK; 3542 pmsg->prefix_flags |= IF_PREFIX_ONLINK;
3550 if (pinfo->autoconf) 3543 if (pinfo->autoconf)
3551 pmsg->prefix_flags |= IF_PREFIX_AUTOCONF; 3544 pmsg->prefix_flags |= IF_PREFIX_AUTOCONF;
3552 3545
3553 RTA_PUT(skb, PREFIX_ADDRESS, sizeof(pinfo->prefix), &pinfo->prefix); 3546 NLA_PUT(skb, PREFIX_ADDRESS, sizeof(pinfo->prefix), &pinfo->prefix);
3554 3547
3555 ci.preferred_time = ntohl(pinfo->prefered); 3548 ci.preferred_time = ntohl(pinfo->prefered);
3556 ci.valid_time = ntohl(pinfo->valid); 3549 ci.valid_time = ntohl(pinfo->valid);
3557 RTA_PUT(skb, PREFIX_CACHEINFO, sizeof(ci), &ci); 3550 NLA_PUT(skb, PREFIX_CACHEINFO, sizeof(ci), &ci);
3558 3551
3559 nlh->nlmsg_len = skb->tail - b; 3552 return nlmsg_end(skb, nlh);
3560 return skb->len;
3561 3553
3562nlmsg_failure: 3554nla_put_failure:
3563rtattr_failure: 3555 return nlmsg_cancel(skb, nlh);
3564 skb_trim(skb, b - skb->data);
3565 return -1;
3566} 3556}
3567 3557
3568static void inet6_prefix_notify(int event, struct inet6_dev *idev, 3558static void inet6_prefix_notify(int event, struct inet6_dev *idev,
3569 struct prefix_info *pinfo) 3559 struct prefix_info *pinfo)
3570{ 3560{
3571 struct sk_buff *skb; 3561 struct sk_buff *skb;
3572 int payload = sizeof(struct prefixmsg) + INET6_PREFIX_RTA_SPACE;
3573 int err = -ENOBUFS; 3562 int err = -ENOBUFS;
3574 3563
3575 skb = nlmsg_new(nlmsg_total_size(payload), GFP_ATOMIC); 3564 skb = nlmsg_new(inet6_prefix_nlmsg_size(), GFP_ATOMIC);
3576 if (skb == NULL) 3565 if (skb == NULL)
3577 goto errout; 3566 goto errout;
3578 3567
3579 err = inet6_fill_prefix(skb, idev, pinfo, 0, 0, event, 0); 3568 err = inet6_fill_prefix(skb, idev, pinfo, 0, 0, event, 0);
3580 if (err < 0) { 3569 /* failure implies BUG in inet6_prefix_nlmsg_size() */
3581 kfree_skb(skb); 3570 BUG_ON(err < 0);
3582 goto errout;
3583 }
3584 3571
3585 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC); 3572 err = rtnl_notify(skb, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC);
3586errout: 3573errout:
@@ -3669,8 +3656,7 @@ static int addrconf_sysctl_forward_strategy(ctl_table *table,
3669 int __user *name, int nlen, 3656 int __user *name, int nlen,
3670 void __user *oldval, 3657 void __user *oldval,
3671 size_t __user *oldlenp, 3658 size_t __user *oldlenp,
3672 void __user *newval, size_t newlen, 3659 void __user *newval, size_t newlen)
3673 void **context)
3674{ 3660{
3675 int *valp = table->data; 3661 int *valp = table->data;
3676 int new; 3662 int new;
@@ -3982,10 +3968,9 @@ static void addrconf_sysctl_register(struct inet6_dev *idev, struct ipv6_devconf
3982 struct addrconf_sysctl_table *t; 3968 struct addrconf_sysctl_table *t;
3983 char *dev_name = NULL; 3969 char *dev_name = NULL;
3984 3970
3985 t = kmalloc(sizeof(*t), GFP_KERNEL); 3971 t = kmemdup(&addrconf_sysctl, sizeof(*t), GFP_KERNEL);
3986 if (t == NULL) 3972 if (t == NULL)
3987 return; 3973 return;
3988 memcpy(t, &addrconf_sysctl, sizeof(*t));
3989 for (i=0; t->addrconf_vars[i].data; i++) { 3974 for (i=0; t->addrconf_vars[i].data; i++) {
3990 t->addrconf_vars[i].data += (char*)p - (char*)&ipv6_devconf; 3975 t->addrconf_vars[i].data += (char*)p - (char*)&ipv6_devconf;
3991 t->addrconf_vars[i].de = NULL; 3976 t->addrconf_vars[i].de = NULL;
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 858cae2958..0e0e4262f4 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -49,6 +49,7 @@
49#include <net/ip.h> 49#include <net/ip.h>
50#include <net/ipv6.h> 50#include <net/ipv6.h>
51#include <net/udp.h> 51#include <net/udp.h>
52#include <net/udplite.h>
52#include <net/tcp.h> 53#include <net/tcp.h>
53#include <net/ipip.h> 54#include <net/ipip.h>
54#include <net/protocol.h> 55#include <net/protocol.h>
@@ -170,7 +171,7 @@ lookup_protocol:
170 sk->sk_reuse = 1; 171 sk->sk_reuse = 1;
171 172
172 inet = inet_sk(sk); 173 inet = inet_sk(sk);
173 inet->is_icsk = INET_PROTOSW_ICSK & answer_flags; 174 inet->is_icsk = (INET_PROTOSW_ICSK & answer_flags) != 0;
174 175
175 if (SOCK_RAW == sock->type) { 176 if (SOCK_RAW == sock->type) {
176 inet->num = protocol; 177 inet->num = protocol;
@@ -221,7 +222,7 @@ lookup_protocol:
221 * the user to assign a number at socket 222 * the user to assign a number at socket
222 * creation time automatically shares. 223 * creation time automatically shares.
223 */ 224 */
224 inet->sport = ntohs(inet->num); 225 inet->sport = htons(inet->num);
225 sk->sk_prot->hash(sk); 226 sk->sk_prot->hash(sk);
226 } 227 }
227 if (sk->sk_prot->init) { 228 if (sk->sk_prot->init) {
@@ -341,7 +342,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
341 sk->sk_userlocks |= SOCK_BINDADDR_LOCK; 342 sk->sk_userlocks |= SOCK_BINDADDR_LOCK;
342 if (snum) 343 if (snum)
343 sk->sk_userlocks |= SOCK_BINDPORT_LOCK; 344 sk->sk_userlocks |= SOCK_BINDPORT_LOCK;
344 inet->sport = ntohs(inet->num); 345 inet->sport = htons(inet->num);
345 inet->dport = 0; 346 inet->dport = 0;
346 inet->daddr = 0; 347 inet->daddr = 0;
347out: 348out:
@@ -678,7 +679,7 @@ int ipv6_opt_accepted(struct sock *sk, struct sk_buff *skb)
678 if (np->rxopt.all) { 679 if (np->rxopt.all) {
679 if ((opt->hop && (np->rxopt.bits.hopopts || 680 if ((opt->hop && (np->rxopt.bits.hopopts ||
680 np->rxopt.bits.ohopopts)) || 681 np->rxopt.bits.ohopopts)) ||
681 ((IPV6_FLOWINFO_MASK & *(u32*)skb->nh.raw) && 682 ((IPV6_FLOWINFO_MASK & *(__be32*)skb->nh.raw) &&
682 np->rxopt.bits.rxflow) || 683 np->rxopt.bits.rxflow) ||
683 (opt->srcrt && (np->rxopt.bits.srcrt || 684 (opt->srcrt && (np->rxopt.bits.srcrt ||
684 np->rxopt.bits.osrcrt)) || 685 np->rxopt.bits.osrcrt)) ||
@@ -719,10 +720,8 @@ snmp6_mib_free(void *ptr[2])
719{ 720{
720 if (ptr == NULL) 721 if (ptr == NULL)
721 return; 722 return;
722 if (ptr[0]) 723 free_percpu(ptr[0]);
723 free_percpu(ptr[0]); 724 free_percpu(ptr[1]);
724 if (ptr[1])
725 free_percpu(ptr[1]);
726 ptr[0] = ptr[1] = NULL; 725 ptr[0] = ptr[1] = NULL;
727} 726}
728 727
@@ -737,8 +736,13 @@ static int __init init_ipv6_mibs(void)
737 if (snmp6_mib_init((void **)udp_stats_in6, sizeof (struct udp_mib), 736 if (snmp6_mib_init((void **)udp_stats_in6, sizeof (struct udp_mib),
738 __alignof__(struct udp_mib)) < 0) 737 __alignof__(struct udp_mib)) < 0)
739 goto err_udp_mib; 738 goto err_udp_mib;
739 if (snmp6_mib_init((void **)udplite_stats_in6, sizeof (struct udp_mib),
740 __alignof__(struct udp_mib)) < 0)
741 goto err_udplite_mib;
740 return 0; 742 return 0;
741 743
744err_udplite_mib:
745 snmp6_mib_free((void **)udp_stats_in6);
742err_udp_mib: 746err_udp_mib:
743 snmp6_mib_free((void **)icmpv6_statistics); 747 snmp6_mib_free((void **)icmpv6_statistics);
744err_icmp_mib: 748err_icmp_mib:
@@ -753,6 +757,7 @@ static void cleanup_ipv6_mibs(void)
753 snmp6_mib_free((void **)ipv6_statistics); 757 snmp6_mib_free((void **)ipv6_statistics);
754 snmp6_mib_free((void **)icmpv6_statistics); 758 snmp6_mib_free((void **)icmpv6_statistics);
755 snmp6_mib_free((void **)udp_stats_in6); 759 snmp6_mib_free((void **)udp_stats_in6);
760 snmp6_mib_free((void **)udplite_stats_in6);
756} 761}
757 762
758static int __init inet6_init(void) 763static int __init inet6_init(void)
@@ -780,10 +785,14 @@ static int __init inet6_init(void)
780 if (err) 785 if (err)
781 goto out_unregister_tcp_proto; 786 goto out_unregister_tcp_proto;
782 787
783 err = proto_register(&rawv6_prot, 1); 788 err = proto_register(&udplitev6_prot, 1);
784 if (err) 789 if (err)
785 goto out_unregister_udp_proto; 790 goto out_unregister_udp_proto;
786 791
792 err = proto_register(&rawv6_prot, 1);
793 if (err)
794 goto out_unregister_udplite_proto;
795
787 796
788 /* Register the socket-side information for inet6_create. */ 797 /* Register the socket-side information for inet6_create. */
789 for(r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r) 798 for(r = &inetsw6[0]; r < &inetsw6[SOCK_MAX]; ++r)
@@ -837,6 +846,8 @@ static int __init inet6_init(void)
837 goto proc_tcp6_fail; 846 goto proc_tcp6_fail;
838 if (udp6_proc_init()) 847 if (udp6_proc_init())
839 goto proc_udp6_fail; 848 goto proc_udp6_fail;
849 if (udplite6_proc_init())
850 goto proc_udplite6_fail;
840 if (ipv6_misc_proc_init()) 851 if (ipv6_misc_proc_init())
841 goto proc_misc6_fail; 852 goto proc_misc6_fail;
842 853
@@ -862,6 +873,7 @@ static int __init inet6_init(void)
862 873
863 /* Init v6 transport protocols. */ 874 /* Init v6 transport protocols. */
864 udpv6_init(); 875 udpv6_init();
876 udplitev6_init();
865 tcpv6_init(); 877 tcpv6_init();
866 878
867 ipv6_packet_init(); 879 ipv6_packet_init();
@@ -879,6 +891,8 @@ proc_if6_fail:
879proc_anycast6_fail: 891proc_anycast6_fail:
880 ipv6_misc_proc_exit(); 892 ipv6_misc_proc_exit();
881proc_misc6_fail: 893proc_misc6_fail:
894 udplite6_proc_exit();
895proc_udplite6_fail:
882 udp6_proc_exit(); 896 udp6_proc_exit();
883proc_udp6_fail: 897proc_udp6_fail:
884 tcp6_proc_exit(); 898 tcp6_proc_exit();
@@ -902,6 +916,8 @@ out_unregister_sock:
902 sock_unregister(PF_INET6); 916 sock_unregister(PF_INET6);
903out_unregister_raw_proto: 917out_unregister_raw_proto:
904 proto_unregister(&rawv6_prot); 918 proto_unregister(&rawv6_prot);
919out_unregister_udplite_proto:
920 proto_unregister(&udplitev6_prot);
905out_unregister_udp_proto: 921out_unregister_udp_proto:
906 proto_unregister(&udpv6_prot); 922 proto_unregister(&udpv6_prot);
907out_unregister_tcp_proto: 923out_unregister_tcp_proto:
@@ -919,6 +935,7 @@ static void __exit inet6_exit(void)
919 ac6_proc_exit(); 935 ac6_proc_exit();
920 ipv6_misc_proc_exit(); 936 ipv6_misc_proc_exit();
921 udp6_proc_exit(); 937 udp6_proc_exit();
938 udplite6_proc_exit();
922 tcp6_proc_exit(); 939 tcp6_proc_exit();
923 raw6_proc_exit(); 940 raw6_proc_exit();
924#endif 941#endif
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index b0d83e8e42..12c5a4dec0 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -354,10 +354,9 @@ static int ah6_input(struct xfrm_state *x, struct sk_buff *skb)
354 if (!pskb_may_pull(skb, ah_hlen)) 354 if (!pskb_may_pull(skb, ah_hlen))
355 goto out; 355 goto out;
356 356
357 tmp_hdr = kmalloc(hdr_len, GFP_ATOMIC); 357 tmp_hdr = kmemdup(skb->nh.raw, hdr_len, GFP_ATOMIC);
358 if (!tmp_hdr) 358 if (!tmp_hdr)
359 goto out; 359 goto out;
360 memcpy(tmp_hdr, skb->nh.raw, hdr_len);
361 if (ipv6_clear_mutable_options(skb->nh.ipv6h, hdr_len, XFRM_POLICY_IN)) 360 if (ipv6_clear_mutable_options(skb->nh.ipv6h, hdr_len, XFRM_POLICY_IN))
362 goto free_out; 361 goto free_out;
363 skb->nh.ipv6h->priority = 0; 362 skb->nh.ipv6h->priority = 0;
@@ -397,7 +396,7 @@ out:
397} 396}
398 397
399static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 398static void ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
400 int type, int code, int offset, __u32 info) 399 int type, int code, int offset, __be32 info)
401{ 400{
402 struct ipv6hdr *iph = (struct ipv6hdr*)skb->data; 401 struct ipv6hdr *iph = (struct ipv6hdr*)skb->data;
403 struct ip_auth_hdr *ah = (struct ip_auth_hdr*)(skb->data+offset); 402 struct ip_auth_hdr *ah = (struct ip_auth_hdr*)(skb->data+offset);
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 7206747022..5c94fea90e 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -207,7 +207,7 @@ out:
207} 207}
208 208
209void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, 209void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
210 u16 port, u32 info, u8 *payload) 210 __be16 port, u32 info, u8 *payload)
211{ 211{
212 struct ipv6_pinfo *np = inet6_sk(sk); 212 struct ipv6_pinfo *np = inet6_sk(sk);
213 struct icmp6hdr *icmph = (struct icmp6hdr *)skb->h.raw; 213 struct icmp6hdr *icmph = (struct icmp6hdr *)skb->h.raw;
@@ -318,13 +318,13 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
318 ipv6_addr_copy(&sin->sin6_addr, 318 ipv6_addr_copy(&sin->sin6_addr,
319 (struct in6_addr *)(skb->nh.raw + serr->addr_offset)); 319 (struct in6_addr *)(skb->nh.raw + serr->addr_offset));
320 if (np->sndflow) 320 if (np->sndflow)
321 sin->sin6_flowinfo = *(u32*)(skb->nh.raw + serr->addr_offset - 24) & IPV6_FLOWINFO_MASK; 321 sin->sin6_flowinfo = *(__be32*)(skb->nh.raw + serr->addr_offset - 24) & IPV6_FLOWINFO_MASK;
322 if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL) 322 if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL)
323 sin->sin6_scope_id = IP6CB(skb)->iif; 323 sin->sin6_scope_id = IP6CB(skb)->iif;
324 } else { 324 } else {
325 ipv6_addr_set(&sin->sin6_addr, 0, 0, 325 ipv6_addr_set(&sin->sin6_addr, 0, 0,
326 htonl(0xffff), 326 htonl(0xffff),
327 *(u32*)(skb->nh.raw + serr->addr_offset)); 327 *(__be32*)(skb->nh.raw + serr->addr_offset));
328 } 328 }
329 } 329 }
330 330
@@ -397,12 +397,12 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
397 } 397 }
398 398
399 if (np->rxopt.bits.rxtclass) { 399 if (np->rxopt.bits.rxtclass) {
400 int tclass = (ntohl(*(u32 *)skb->nh.ipv6h) >> 20) & 0xff; 400 int tclass = (ntohl(*(__be32 *)skb->nh.ipv6h) >> 20) & 0xff;
401 put_cmsg(msg, SOL_IPV6, IPV6_TCLASS, sizeof(tclass), &tclass); 401 put_cmsg(msg, SOL_IPV6, IPV6_TCLASS, sizeof(tclass), &tclass);
402 } 402 }
403 403
404 if (np->rxopt.bits.rxflow && (*(u32*)skb->nh.raw & IPV6_FLOWINFO_MASK)) { 404 if (np->rxopt.bits.rxflow && (*(__be32*)skb->nh.raw & IPV6_FLOWINFO_MASK)) {
405 u32 flowinfo = *(u32*)skb->nh.raw & IPV6_FLOWINFO_MASK; 405 __be32 flowinfo = *(__be32*)skb->nh.raw & IPV6_FLOWINFO_MASK;
406 put_cmsg(msg, SOL_IPV6, IPV6_FLOWINFO, sizeof(flowinfo), &flowinfo); 406 put_cmsg(msg, SOL_IPV6, IPV6_FLOWINFO, sizeof(flowinfo), &flowinfo);
407 } 407 }
408 408
@@ -560,12 +560,12 @@ int datagram_send_ctl(struct msghdr *msg, struct flowi *fl,
560 } 560 }
561 561
562 if (fl->fl6_flowlabel&IPV6_FLOWINFO_MASK) { 562 if (fl->fl6_flowlabel&IPV6_FLOWINFO_MASK) {
563 if ((fl->fl6_flowlabel^*(u32 *)CMSG_DATA(cmsg))&~IPV6_FLOWINFO_MASK) { 563 if ((fl->fl6_flowlabel^*(__be32 *)CMSG_DATA(cmsg))&~IPV6_FLOWINFO_MASK) {
564 err = -EINVAL; 564 err = -EINVAL;
565 goto exit_f; 565 goto exit_f;
566 } 566 }
567 } 567 }
568 fl->fl6_flowlabel = IPV6_FLOWINFO_MASK & *(u32 *)CMSG_DATA(cmsg); 568 fl->fl6_flowlabel = IPV6_FLOWINFO_MASK & *(__be32 *)CMSG_DATA(cmsg);
569 break; 569 break;
570 570
571 case IPV6_2292HOPOPTS: 571 case IPV6_2292HOPOPTS:
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index e78680a998..25dcf69cd8 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -256,7 +256,7 @@ static u32 esp6_get_max_size(struct xfrm_state *x, int mtu)
256} 256}
257 257
258static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 258static void esp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
259 int type, int code, int offset, __u32 info) 259 int type, int code, int offset, __be32 info)
260{ 260{
261 struct ipv6hdr *iph = (struct ipv6hdr*)skb->data; 261 struct ipv6hdr *iph = (struct ipv6hdr*)skb->data;
262 struct ipv6_esp_hdr *esph = (struct ipv6_esp_hdr*)(skb->data+offset); 262 struct ipv6_esp_hdr *esph = (struct ipv6_esp_hdr*)(skb->data+offset);
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 88c96b1068..0711f92d6a 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -284,10 +284,12 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp)
284#ifdef CONFIG_IPV6_MIP6 284#ifdef CONFIG_IPV6_MIP6
285 __u16 dstbuf; 285 __u16 dstbuf;
286#endif 286#endif
287 struct dst_entry *dst;
287 288
288 if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) || 289 if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
289 !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) { 290 !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
290 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 291 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
292 IPSTATS_MIB_INHDRERRORS);
291 kfree_skb(skb); 293 kfree_skb(skb);
292 return -1; 294 return -1;
293 } 295 }
@@ -298,7 +300,9 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp)
298 dstbuf = opt->dst1; 300 dstbuf = opt->dst1;
299#endif 301#endif
300 302
303 dst = dst_clone(skb->dst);
301 if (ip6_parse_tlv(tlvprocdestopt_lst, skbp)) { 304 if (ip6_parse_tlv(tlvprocdestopt_lst, skbp)) {
305 dst_release(dst);
302 skb = *skbp; 306 skb = *skbp;
303 skb->h.raw += ((skb->h.raw[1]+1)<<3); 307 skb->h.raw += ((skb->h.raw[1]+1)<<3);
304 opt = IP6CB(skb); 308 opt = IP6CB(skb);
@@ -310,7 +314,8 @@ static int ipv6_destopt_rcv(struct sk_buff **skbp)
310 return 1; 314 return 1;
311 } 315 }
312 316
313 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 317 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS);
318 dst_release(dst);
314 return -1; 319 return -1;
315} 320}
316 321
@@ -365,7 +370,8 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp)
365 370
366 if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) || 371 if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
367 !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) { 372 !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
368 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 373 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
374 IPSTATS_MIB_INHDRERRORS);
369 kfree_skb(skb); 375 kfree_skb(skb);
370 return -1; 376 return -1;
371 } 377 }
@@ -374,7 +380,8 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp)
374 380
375 if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr) || 381 if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr) ||
376 skb->pkt_type != PACKET_HOST) { 382 skb->pkt_type != PACKET_HOST) {
377 IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); 383 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
384 IPSTATS_MIB_INADDRERRORS);
378 kfree_skb(skb); 385 kfree_skb(skb);
379 return -1; 386 return -1;
380 } 387 }
@@ -388,7 +395,8 @@ looped_back:
388 * processed by own 395 * processed by own
389 */ 396 */
390 if (!addr) { 397 if (!addr) {
391 IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); 398 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
399 IPSTATS_MIB_INADDRERRORS);
392 kfree_skb(skb); 400 kfree_skb(skb);
393 return -1; 401 return -1;
394 } 402 }
@@ -410,7 +418,8 @@ looped_back:
410 switch (hdr->type) { 418 switch (hdr->type) {
411 case IPV6_SRCRT_TYPE_0: 419 case IPV6_SRCRT_TYPE_0:
412 if (hdr->hdrlen & 0x01) { 420 if (hdr->hdrlen & 0x01) {
413 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 421 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
422 IPSTATS_MIB_INHDRERRORS);
414 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->hdrlen) - skb->nh.raw); 423 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->hdrlen) - skb->nh.raw);
415 return -1; 424 return -1;
416 } 425 }
@@ -419,14 +428,16 @@ looped_back:
419 case IPV6_SRCRT_TYPE_2: 428 case IPV6_SRCRT_TYPE_2:
420 /* Silently discard invalid RTH type 2 */ 429 /* Silently discard invalid RTH type 2 */
421 if (hdr->hdrlen != 2 || hdr->segments_left != 1) { 430 if (hdr->hdrlen != 2 || hdr->segments_left != 1) {
422 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 431 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
432 IPSTATS_MIB_INHDRERRORS);
423 kfree_skb(skb); 433 kfree_skb(skb);
424 return -1; 434 return -1;
425 } 435 }
426 break; 436 break;
427#endif 437#endif
428 default: 438 default:
429 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 439 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
440 IPSTATS_MIB_INHDRERRORS);
430 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw); 441 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw);
431 return -1; 442 return -1;
432 } 443 }
@@ -439,7 +450,8 @@ looped_back:
439 n = hdr->hdrlen >> 1; 450 n = hdr->hdrlen >> 1;
440 451
441 if (hdr->segments_left > n) { 452 if (hdr->segments_left > n) {
442 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 453 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
454 IPSTATS_MIB_INHDRERRORS);
443 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->segments_left) - skb->nh.raw); 455 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->segments_left) - skb->nh.raw);
444 return -1; 456 return -1;
445 } 457 }
@@ -449,12 +461,14 @@ looped_back:
449 */ 461 */
450 if (skb_cloned(skb)) { 462 if (skb_cloned(skb)) {
451 struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC); 463 struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
452 kfree_skb(skb);
453 /* the copy is a forwarded packet */ 464 /* the copy is a forwarded packet */
454 if (skb2 == NULL) { 465 if (skb2 == NULL) {
455 IP6_INC_STATS_BH(IPSTATS_MIB_OUTDISCARDS); 466 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
467 IPSTATS_MIB_OUTDISCARDS);
468 kfree_skb(skb);
456 return -1; 469 return -1;
457 } 470 }
471 kfree_skb(skb);
458 *skbp = skb = skb2; 472 *skbp = skb = skb2;
459 opt = IP6CB(skb2); 473 opt = IP6CB(skb2);
460 hdr = (struct ipv6_rt_hdr *) skb2->h.raw; 474 hdr = (struct ipv6_rt_hdr *) skb2->h.raw;
@@ -475,12 +489,14 @@ looped_back:
475 if (xfrm6_input_addr(skb, (xfrm_address_t *)addr, 489 if (xfrm6_input_addr(skb, (xfrm_address_t *)addr,
476 (xfrm_address_t *)&skb->nh.ipv6h->saddr, 490 (xfrm_address_t *)&skb->nh.ipv6h->saddr,
477 IPPROTO_ROUTING) < 0) { 491 IPPROTO_ROUTING) < 0) {
478 IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); 492 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
493 IPSTATS_MIB_INADDRERRORS);
479 kfree_skb(skb); 494 kfree_skb(skb);
480 return -1; 495 return -1;
481 } 496 }
482 if (!ipv6_chk_home_addr(addr)) { 497 if (!ipv6_chk_home_addr(addr)) {
483 IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); 498 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
499 IPSTATS_MIB_INADDRERRORS);
484 kfree_skb(skb); 500 kfree_skb(skb);
485 return -1; 501 return -1;
486 } 502 }
@@ -491,7 +507,8 @@ looped_back:
491 } 507 }
492 508
493 if (ipv6_addr_is_multicast(addr)) { 509 if (ipv6_addr_is_multicast(addr)) {
494 IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); 510 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
511 IPSTATS_MIB_INADDRERRORS);
495 kfree_skb(skb); 512 kfree_skb(skb);
496 return -1; 513 return -1;
497 } 514 }
@@ -510,7 +527,8 @@ looped_back:
510 527
511 if (skb->dst->dev->flags&IFF_LOOPBACK) { 528 if (skb->dst->dev->flags&IFF_LOOPBACK) {
512 if (skb->nh.ipv6h->hop_limit <= 1) { 529 if (skb->nh.ipv6h->hop_limit <= 1) {
513 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 530 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
531 IPSTATS_MIB_INHDRERRORS);
514 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 532 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
515 0, skb->dev); 533 0, skb->dev);
516 kfree_skb(skb); 534 kfree_skb(skb);
@@ -632,24 +650,25 @@ static int ipv6_hop_jumbo(struct sk_buff **skbp, int optoff)
632 if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) { 650 if (skb->nh.raw[optoff+1] != 4 || (optoff&3) != 2) {
633 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n", 651 LIMIT_NETDEBUG(KERN_DEBUG "ipv6_hop_jumbo: wrong jumbo opt length/alignment %d\n",
634 skb->nh.raw[optoff+1]); 652 skb->nh.raw[optoff+1]);
635 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 653 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
654 IPSTATS_MIB_INHDRERRORS);
636 goto drop; 655 goto drop;
637 } 656 }
638 657
639 pkt_len = ntohl(*(u32*)(skb->nh.raw+optoff+2)); 658 pkt_len = ntohl(*(__be32*)(skb->nh.raw+optoff+2));
640 if (pkt_len <= IPV6_MAXPLEN) { 659 if (pkt_len <= IPV6_MAXPLEN) {
641 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 660 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
642 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2); 661 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff+2);
643 return 0; 662 return 0;
644 } 663 }
645 if (skb->nh.ipv6h->payload_len) { 664 if (skb->nh.ipv6h->payload_len) {
646 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 665 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
647 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff); 666 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, optoff);
648 return 0; 667 return 0;
649 } 668 }
650 669
651 if (pkt_len > skb->len - sizeof(struct ipv6hdr)) { 670 if (pkt_len > skb->len - sizeof(struct ipv6hdr)) {
652 IP6_INC_STATS_BH(IPSTATS_MIB_INTRUNCATEDPKTS); 671 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INTRUNCATEDPKTS);
653 goto drop; 672 goto drop;
654 } 673 }
655 674
diff --git a/net/ipv6/exthdrs_core.c b/net/ipv6/exthdrs_core.c
index 315bc1fbec..21cbbbddaf 100644
--- a/net/ipv6/exthdrs_core.c
+++ b/net/ipv6/exthdrs_core.c
@@ -77,7 +77,7 @@ int ipv6_skip_exthdr(const struct sk_buff *skb, int start, u8 *nexthdrp)
77 if (hp == NULL) 77 if (hp == NULL)
78 return -1; 78 return -1;
79 if (nexthdr == NEXTHDR_FRAGMENT) { 79 if (nexthdr == NEXTHDR_FRAGMENT) {
80 unsigned short _frag_off, *fp; 80 __be16 _frag_off, *fp;
81 fp = skb_header_pointer(skb, 81 fp = skb_header_pointer(skb,
82 start+offsetof(struct frag_hdr, 82 start+offsetof(struct frag_hdr,
83 frag_off), 83 frag_off),
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index 1896ecb528..0862809ffc 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -25,10 +25,6 @@ struct fib6_rule
25 struct fib_rule common; 25 struct fib_rule common;
26 struct rt6key src; 26 struct rt6key src;
27 struct rt6key dst; 27 struct rt6key dst;
28#ifdef CONFIG_IPV6_ROUTE_FWMARK
29 u32 fwmark;
30 u32 fwmask;
31#endif
32 u8 tclass; 28 u8 tclass;
33}; 29};
34 30
@@ -67,7 +63,7 @@ struct dst_entry *fib6_rule_lookup(struct flowi *fl, int flags,
67 fib_rule_put(arg.rule); 63 fib_rule_put(arg.rule);
68 64
69 if (arg.result) 65 if (arg.result)
70 return (struct dst_entry *) arg.result; 66 return arg.result;
71 67
72 dst_hold(&ip6_null_entry.u.dst); 68 dst_hold(&ip6_null_entry.u.dst);
73 return &ip6_null_entry.u.dst; 69 return &ip6_null_entry.u.dst;
@@ -130,22 +126,13 @@ static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags)
130 if (r->tclass && r->tclass != ((ntohl(fl->fl6_flowlabel) >> 20) & 0xff)) 126 if (r->tclass && r->tclass != ((ntohl(fl->fl6_flowlabel) >> 20) & 0xff))
131 return 0; 127 return 0;
132 128
133#ifdef CONFIG_IPV6_ROUTE_FWMARK
134 if ((r->fwmark ^ fl->fl6_fwmark) & r->fwmask)
135 return 0;
136#endif
137
138 return 1; 129 return 1;
139} 130}
140 131
141static struct nla_policy fib6_rule_policy[FRA_MAX+1] __read_mostly = { 132static struct nla_policy fib6_rule_policy[FRA_MAX+1] __read_mostly = {
142 [FRA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, 133 FRA_GENERIC_POLICY,
143 [FRA_PRIORITY] = { .type = NLA_U32 },
144 [FRA_SRC] = { .len = sizeof(struct in6_addr) }, 134 [FRA_SRC] = { .len = sizeof(struct in6_addr) },
145 [FRA_DST] = { .len = sizeof(struct in6_addr) }, 135 [FRA_DST] = { .len = sizeof(struct in6_addr) },
146 [FRA_FWMARK] = { .type = NLA_U32 },
147 [FRA_FWMASK] = { .type = NLA_U32 },
148 [FRA_TABLE] = { .type = NLA_U32 },
149}; 136};
150 137
151static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb, 138static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
@@ -155,8 +142,7 @@ static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
155 int err = -EINVAL; 142 int err = -EINVAL;
156 struct fib6_rule *rule6 = (struct fib6_rule *) rule; 143 struct fib6_rule *rule6 = (struct fib6_rule *) rule;
157 144
158 if (frh->src_len > 128 || frh->dst_len > 128 || 145 if (frh->src_len > 128 || frh->dst_len > 128)
159 (frh->tos & ~IPV6_FLOWINFO_MASK))
160 goto errout; 146 goto errout;
161 147
162 if (rule->action == FR_ACT_TO_TBL) { 148 if (rule->action == FR_ACT_TO_TBL) {
@@ -177,23 +163,6 @@ static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
177 nla_memcpy(&rule6->dst.addr, tb[FRA_DST], 163 nla_memcpy(&rule6->dst.addr, tb[FRA_DST],
178 sizeof(struct in6_addr)); 164 sizeof(struct in6_addr));
179 165
180#ifdef CONFIG_IPV6_ROUTE_FWMARK
181 if (tb[FRA_FWMARK]) {
182 rule6->fwmark = nla_get_u32(tb[FRA_FWMARK]);
183 if (rule6->fwmark) {
184 /*
185 * if the mark value is non-zero,
186 * all bits are compared by default
187 * unless a mask is explicitly specified.
188 */
189 rule6->fwmask = 0xFFFFFFFF;
190 }
191 }
192
193 if (tb[FRA_FWMASK])
194 rule6->fwmask = nla_get_u32(tb[FRA_FWMASK]);
195#endif
196
197 rule6->src.plen = frh->src_len; 166 rule6->src.plen = frh->src_len;
198 rule6->dst.plen = frh->dst_len; 167 rule6->dst.plen = frh->dst_len;
199 rule6->tclass = frh->tos; 168 rule6->tclass = frh->tos;
@@ -225,14 +194,6 @@ static int fib6_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
225 nla_memcmp(tb[FRA_DST], &rule6->dst.addr, sizeof(struct in6_addr))) 194 nla_memcmp(tb[FRA_DST], &rule6->dst.addr, sizeof(struct in6_addr)))
226 return 0; 195 return 0;
227 196
228#ifdef CONFIG_IPV6_ROUTE_FWMARK
229 if (tb[FRA_FWMARK] && (rule6->fwmark != nla_get_u32(tb[FRA_FWMARK])))
230 return 0;
231
232 if (tb[FRA_FWMASK] && (rule6->fwmask != nla_get_u32(tb[FRA_FWMASK])))
233 return 0;
234#endif
235
236 return 1; 197 return 1;
237} 198}
238 199
@@ -254,14 +215,6 @@ static int fib6_rule_fill(struct fib_rule *rule, struct sk_buff *skb,
254 NLA_PUT(skb, FRA_SRC, sizeof(struct in6_addr), 215 NLA_PUT(skb, FRA_SRC, sizeof(struct in6_addr),
255 &rule6->src.addr); 216 &rule6->src.addr);
256 217
257#ifdef CONFIG_IPV6_ROUTE_FWMARK
258 if (rule6->fwmark)
259 NLA_PUT_U32(skb, FRA_FWMARK, rule6->fwmark);
260
261 if (rule6->fwmask || rule6->fwmark)
262 NLA_PUT_U32(skb, FRA_FWMASK, rule6->fwmask);
263#endif
264
265 return 0; 218 return 0;
266 219
267nla_put_failure: 220nla_put_failure:
@@ -278,6 +231,12 @@ static u32 fib6_rule_default_pref(void)
278 return 0x3FFF; 231 return 0x3FFF;
279} 232}
280 233
234static size_t fib6_rule_nlmsg_payload(struct fib_rule *rule)
235{
236 return nla_total_size(16) /* dst */
237 + nla_total_size(16); /* src */
238}
239
281static struct fib_rules_ops fib6_rules_ops = { 240static struct fib_rules_ops fib6_rules_ops = {
282 .family = AF_INET6, 241 .family = AF_INET6,
283 .rule_size = sizeof(struct fib6_rule), 242 .rule_size = sizeof(struct fib6_rule),
@@ -287,6 +246,7 @@ static struct fib_rules_ops fib6_rules_ops = {
287 .compare = fib6_rule_compare, 246 .compare = fib6_rule_compare,
288 .fill = fib6_rule_fill, 247 .fill = fib6_rule_fill,
289 .default_pref = fib6_rule_default_pref, 248 .default_pref = fib6_rule_default_pref,
249 .nlmsg_payload = fib6_rule_nlmsg_payload,
290 .nlgroup = RTNLGRP_IPV6_RULE, 250 .nlgroup = RTNLGRP_IPV6_RULE,
291 .policy = fib6_rule_policy, 251 .policy = fib6_rule_policy,
292 .rules_list = &fib6_rules, 252 .rules_list = &fib6_rules,
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 4ec876066b..3dcc4b7f41 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -177,7 +177,8 @@ static inline int icmpv6_xrlim_allow(struct sock *sk, int type,
177 */ 177 */
178 dst = ip6_route_output(sk, fl); 178 dst = ip6_route_output(sk, fl);
179 if (dst->error) { 179 if (dst->error) {
180 IP6_INC_STATS(IPSTATS_MIB_OUTNOROUTES); 180 IP6_INC_STATS(ip6_dst_idev(dst),
181 IPSTATS_MIB_OUTNOROUTES);
181 } else if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) { 182 } else if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) {
182 res = 1; 183 res = 1;
183 } else { 184 } else {
@@ -233,7 +234,7 @@ static int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct
233 len, fl->proto, 234 len, fl->proto,
234 skb->csum); 235 skb->csum);
235 } else { 236 } else {
236 u32 tmp_csum = 0; 237 __wsum tmp_csum = 0;
237 238
238 skb_queue_walk(&sk->sk_write_queue, skb) { 239 skb_queue_walk(&sk->sk_write_queue, skb) {
239 tmp_csum = csum_add(tmp_csum, skb->csum); 240 tmp_csum = csum_add(tmp_csum, skb->csum);
@@ -241,13 +242,11 @@ static int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct
241 242
242 tmp_csum = csum_partial((char *)icmp6h, 243 tmp_csum = csum_partial((char *)icmp6h,
243 sizeof(struct icmp6hdr), tmp_csum); 244 sizeof(struct icmp6hdr), tmp_csum);
244 tmp_csum = csum_ipv6_magic(&fl->fl6_src, 245 icmp6h->icmp6_cksum = csum_ipv6_magic(&fl->fl6_src,
245 &fl->fl6_dst, 246 &fl->fl6_dst,
246 len, fl->proto, tmp_csum); 247 len, fl->proto,
247 icmp6h->icmp6_cksum = tmp_csum; 248 tmp_csum);
248 } 249 }
249 if (icmp6h->icmp6_cksum == 0)
250 icmp6h->icmp6_cksum = -1;
251 ip6_push_pending_frames(sk); 250 ip6_push_pending_frames(sk);
252out: 251out:
253 return err; 252 return err;
@@ -263,7 +262,7 @@ static int icmpv6_getfrag(void *from, char *to, int offset, int len, int odd, st
263{ 262{
264 struct icmpv6_msg *msg = (struct icmpv6_msg *) from; 263 struct icmpv6_msg *msg = (struct icmpv6_msg *) from;
265 struct sk_buff *org_skb = msg->skb; 264 struct sk_buff *org_skb = msg->skb;
266 __u32 csum = 0; 265 __wsum csum = 0;
267 266
268 csum = skb_copy_and_csum_bits(org_skb, msg->offset + offset, 267 csum = skb_copy_and_csum_bits(org_skb, msg->offset + offset,
269 to, len, csum); 268 to, len, csum);
@@ -555,7 +554,7 @@ out:
555 icmpv6_xmit_unlock(); 554 icmpv6_xmit_unlock();
556} 555}
557 556
558static void icmpv6_notify(struct sk_buff *skb, int type, int code, u32 info) 557static void icmpv6_notify(struct sk_buff *skb, int type, int code, __be32 info)
559{ 558{
560 struct in6_addr *saddr, *daddr; 559 struct in6_addr *saddr, *daddr;
561 struct inet6_protocol *ipprot; 560 struct inet6_protocol *ipprot;
@@ -637,8 +636,8 @@ static int icmpv6_rcv(struct sk_buff **pskb)
637 break; 636 break;
638 /* fall through */ 637 /* fall through */
639 case CHECKSUM_NONE: 638 case CHECKSUM_NONE:
640 skb->csum = ~csum_ipv6_magic(saddr, daddr, skb->len, 639 skb->csum = ~csum_unfold(csum_ipv6_magic(saddr, daddr, skb->len,
641 IPPROTO_ICMPV6, 0); 640 IPPROTO_ICMPV6, 0));
642 if (__skb_checksum_complete(skb)) { 641 if (__skb_checksum_complete(skb)) {
643 LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 checksum failed [" NIP6_FMT " > " NIP6_FMT "]\n", 642 LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 checksum failed [" NIP6_FMT " > " NIP6_FMT "]\n",
644 NIP6(*saddr), NIP6(*daddr)); 643 NIP6(*saddr), NIP6(*daddr));
diff --git a/net/ipv6/inet6_connection_sock.c b/net/ipv6/inet6_connection_sock.c
index 827f41d147..c700302ad5 100644
--- a/net/ipv6/inet6_connection_sock.c
+++ b/net/ipv6/inet6_connection_sock.c
@@ -52,20 +52,20 @@ EXPORT_SYMBOL_GPL(inet6_csk_bind_conflict);
52/* 52/*
53 * request_sock (formerly open request) hash tables. 53 * request_sock (formerly open request) hash tables.
54 */ 54 */
55static u32 inet6_synq_hash(const struct in6_addr *raddr, const u16 rport, 55static u32 inet6_synq_hash(const struct in6_addr *raddr, const __be16 rport,
56 const u32 rnd, const u16 synq_hsize) 56 const u32 rnd, const u16 synq_hsize)
57{ 57{
58 u32 a = raddr->s6_addr32[0]; 58 u32 a = (__force u32)raddr->s6_addr32[0];
59 u32 b = raddr->s6_addr32[1]; 59 u32 b = (__force u32)raddr->s6_addr32[1];
60 u32 c = raddr->s6_addr32[2]; 60 u32 c = (__force u32)raddr->s6_addr32[2];
61 61
62 a += JHASH_GOLDEN_RATIO; 62 a += JHASH_GOLDEN_RATIO;
63 b += JHASH_GOLDEN_RATIO; 63 b += JHASH_GOLDEN_RATIO;
64 c += rnd; 64 c += rnd;
65 __jhash_mix(a, b, c); 65 __jhash_mix(a, b, c);
66 66
67 a += raddr->s6_addr32[3]; 67 a += (__force u32)raddr->s6_addr32[3];
68 b += (u32)rport; 68 b += (__force u32)rport;
69 __jhash_mix(a, b, c); 69 __jhash_mix(a, b, c);
70 70
71 return c & (synq_hsize - 1); 71 return c & (synq_hsize - 1);
@@ -73,7 +73,7 @@ static u32 inet6_synq_hash(const struct in6_addr *raddr, const u16 rport,
73 73
74struct request_sock *inet6_csk_search_req(const struct sock *sk, 74struct request_sock *inet6_csk_search_req(const struct sock *sk,
75 struct request_sock ***prevp, 75 struct request_sock ***prevp,
76 const __u16 rport, 76 const __be16 rport,
77 const struct in6_addr *raddr, 77 const struct in6_addr *raddr,
78 const struct in6_addr *laddr, 78 const struct in6_addr *laddr,
79 const int iif) 79 const int iif)
@@ -139,9 +139,8 @@ void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr * uaddr)
139 139
140EXPORT_SYMBOL_GPL(inet6_csk_addr2sockaddr); 140EXPORT_SYMBOL_GPL(inet6_csk_addr2sockaddr);
141 141
142int inet6_csk_xmit(struct sk_buff *skb, int ipfragok) 142int inet6_csk_xmit(struct sk_buff *skb, struct sock *sk, int ipfragok)
143{ 143{
144 struct sock *sk = skb->sk;
145 struct inet_sock *inet = inet_sk(sk); 144 struct inet_sock *inet = inet_sk(sk);
146 struct ipv6_pinfo *np = inet6_sk(sk); 145 struct ipv6_pinfo *np = inet6_sk(sk);
147 struct flowi fl; 146 struct flowi fl;
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
index 8accd1fbee..b7e5bae0e3 100644
--- a/net/ipv6/inet6_hashtables.c
+++ b/net/ipv6/inet6_hashtables.c
@@ -57,7 +57,7 @@ EXPORT_SYMBOL(__inet6_hash);
57 */ 57 */
58struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo, 58struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo,
59 const struct in6_addr *saddr, 59 const struct in6_addr *saddr,
60 const u16 sport, 60 const __be16 sport,
61 const struct in6_addr *daddr, 61 const struct in6_addr *daddr,
62 const u16 hnum, 62 const u16 hnum,
63 const int dif) 63 const int dif)
@@ -146,8 +146,8 @@ struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo,
146EXPORT_SYMBOL_GPL(inet6_lookup_listener); 146EXPORT_SYMBOL_GPL(inet6_lookup_listener);
147 147
148struct sock *inet6_lookup(struct inet_hashinfo *hashinfo, 148struct sock *inet6_lookup(struct inet_hashinfo *hashinfo,
149 const struct in6_addr *saddr, const u16 sport, 149 const struct in6_addr *saddr, const __be16 sport,
150 const struct in6_addr *daddr, const u16 dport, 150 const struct in6_addr *daddr, const __be16 dport,
151 const int dif) 151 const int dif)
152{ 152{
153 struct sock *sk; 153 struct sock *sk;
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index f98ca30d7c..96d8310ae9 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -50,7 +50,7 @@
50 50
51struct rt6_statistics rt6_stats; 51struct rt6_statistics rt6_stats;
52 52
53static kmem_cache_t * fib6_node_kmem __read_mostly; 53static struct kmem_cache * fib6_node_kmem __read_mostly;
54 54
55enum fib_walk_state_t 55enum fib_walk_state_t
56{ 56{
@@ -139,9 +139,9 @@ static __inline__ u32 fib6_new_sernum(void)
139 * test bit 139 * test bit
140 */ 140 */
141 141
142static __inline__ int addr_bit_set(void *token, int fn_bit) 142static __inline__ __be32 addr_bit_set(void *token, int fn_bit)
143{ 143{
144 __u32 *addr = token; 144 __be32 *addr = token;
145 145
146 return htonl(1 << ((~fn_bit)&0x1F)) & addr[fn_bit>>5]; 146 return htonl(1 << ((~fn_bit)&0x1F)) & addr[fn_bit>>5];
147} 147}
@@ -150,7 +150,7 @@ static __inline__ struct fib6_node * node_alloc(void)
150{ 150{
151 struct fib6_node *fn; 151 struct fib6_node *fn;
152 152
153 if ((fn = kmem_cache_alloc(fib6_node_kmem, SLAB_ATOMIC)) != NULL) 153 if ((fn = kmem_cache_alloc(fib6_node_kmem, GFP_ATOMIC)) != NULL)
154 memset(fn, 0, sizeof(struct fib6_node)); 154 memset(fn, 0, sizeof(struct fib6_node));
155 155
156 return fn; 156 return fn;
@@ -434,7 +434,7 @@ static struct fib6_node * fib6_add_1(struct fib6_node *root, void *addr,
434 struct fib6_node *pn = NULL; 434 struct fib6_node *pn = NULL;
435 struct rt6key *key; 435 struct rt6key *key;
436 int bit; 436 int bit;
437 int dir = 0; 437 __be32 dir = 0;
438 __u32 sernum = fib6_new_sernum(); 438 __u32 sernum = fib6_new_sernum();
439 439
440 RT6_TRACE("fib6_add_1\n"); 440 RT6_TRACE("fib6_add_1\n");
@@ -829,7 +829,7 @@ static struct fib6_node * fib6_lookup_1(struct fib6_node *root,
829 struct lookup_args *args) 829 struct lookup_args *args)
830{ 830{
831 struct fib6_node *fn; 831 struct fib6_node *fn;
832 int dir; 832 __be32 dir;
833 833
834 if (unlikely(args->offset == 0)) 834 if (unlikely(args->offset == 0))
835 return NULL; 835 return NULL;
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 6d4533b58d..624fae251f 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -61,7 +61,7 @@ static DEFINE_RWLOCK(ip6_fl_lock);
61static DEFINE_RWLOCK(ip6_sk_fl_lock); 61static DEFINE_RWLOCK(ip6_sk_fl_lock);
62 62
63 63
64static __inline__ struct ip6_flowlabel * __fl_lookup(u32 label) 64static __inline__ struct ip6_flowlabel * __fl_lookup(__be32 label)
65{ 65{
66 struct ip6_flowlabel *fl; 66 struct ip6_flowlabel *fl;
67 67
@@ -72,7 +72,7 @@ static __inline__ struct ip6_flowlabel * __fl_lookup(u32 label)
72 return NULL; 72 return NULL;
73} 73}
74 74
75static struct ip6_flowlabel * fl_lookup(u32 label) 75static struct ip6_flowlabel * fl_lookup(__be32 label)
76{ 76{
77 struct ip6_flowlabel *fl; 77 struct ip6_flowlabel *fl;
78 78
@@ -153,7 +153,7 @@ static void ip6_fl_gc(unsigned long dummy)
153 write_unlock(&ip6_fl_lock); 153 write_unlock(&ip6_fl_lock);
154} 154}
155 155
156static int fl_intern(struct ip6_flowlabel *fl, __u32 label) 156static int fl_intern(struct ip6_flowlabel *fl, __be32 label)
157{ 157{
158 fl->label = label & IPV6_FLOWLABEL_MASK; 158 fl->label = label & IPV6_FLOWLABEL_MASK;
159 159
@@ -182,7 +182,7 @@ static int fl_intern(struct ip6_flowlabel *fl, __u32 label)
182 182
183/* Socket flowlabel lists */ 183/* Socket flowlabel lists */
184 184
185struct ip6_flowlabel * fl6_sock_lookup(struct sock *sk, u32 label) 185struct ip6_flowlabel * fl6_sock_lookup(struct sock *sk, __be32 label)
186{ 186{
187 struct ipv6_fl_socklist *sfl; 187 struct ipv6_fl_socklist *sfl;
188 struct ipv6_pinfo *np = inet6_sk(sk); 188 struct ipv6_pinfo *np = inet6_sk(sk);
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 6b8e6d76a5..ad0b8abcdf 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -60,14 +60,22 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
60{ 60{
61 struct ipv6hdr *hdr; 61 struct ipv6hdr *hdr;
62 u32 pkt_len; 62 u32 pkt_len;
63 struct inet6_dev *idev;
63 64
64 if (skb->pkt_type == PACKET_OTHERHOST) 65 if (skb->pkt_type == PACKET_OTHERHOST) {
65 goto drop; 66 kfree_skb(skb);
67 return 0;
68 }
69
70 rcu_read_lock();
66 71
67 IP6_INC_STATS_BH(IPSTATS_MIB_INRECEIVES); 72 idev = __in6_dev_get(skb->dev);
73
74 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INRECEIVES);
68 75
69 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { 76 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
70 IP6_INC_STATS_BH(IPSTATS_MIB_INDISCARDS); 77 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDISCARDS);
78 rcu_read_unlock();
71 goto out; 79 goto out;
72 } 80 }
73 81
@@ -84,7 +92,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
84 * arrived via the sending interface (ethX), because of the 92 * arrived via the sending interface (ethX), because of the
85 * nature of scoping architecture. --yoshfuji 93 * nature of scoping architecture. --yoshfuji
86 */ 94 */
87 IP6CB(skb)->iif = skb->dst ? ((struct rt6_info *)skb->dst)->rt6i_idev->dev->ifindex : dev->ifindex; 95 IP6CB(skb)->iif = skb->dst ? ip6_dst_idev(skb->dst)->dev->ifindex : dev->ifindex;
88 96
89 if (unlikely(!pskb_may_pull(skb, sizeof(*hdr)))) 97 if (unlikely(!pskb_may_pull(skb, sizeof(*hdr))))
90 goto err; 98 goto err;
@@ -104,7 +112,7 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
104 if (pkt_len + sizeof(struct ipv6hdr) > skb->len) 112 if (pkt_len + sizeof(struct ipv6hdr) > skb->len)
105 goto truncated; 113 goto truncated;
106 if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr))) { 114 if (pskb_trim_rcsum(skb, pkt_len + sizeof(struct ipv6hdr))) {
107 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 115 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INHDRERRORS);
108 goto drop; 116 goto drop;
109 } 117 }
110 hdr = skb->nh.ipv6h; 118 hdr = skb->nh.ipv6h;
@@ -112,17 +120,21 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
112 120
113 if (hdr->nexthdr == NEXTHDR_HOP) { 121 if (hdr->nexthdr == NEXTHDR_HOP) {
114 if (ipv6_parse_hopopts(&skb) < 0) { 122 if (ipv6_parse_hopopts(&skb) < 0) {
115 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 123 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INHDRERRORS);
124 rcu_read_unlock();
116 return 0; 125 return 0;
117 } 126 }
118 } 127 }
119 128
129 rcu_read_unlock();
130
120 return NF_HOOK(PF_INET6,NF_IP6_PRE_ROUTING, skb, dev, NULL, ip6_rcv_finish); 131 return NF_HOOK(PF_INET6,NF_IP6_PRE_ROUTING, skb, dev, NULL, ip6_rcv_finish);
121truncated: 132truncated:
122 IP6_INC_STATS_BH(IPSTATS_MIB_INTRUNCATEDPKTS); 133 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INTRUNCATEDPKTS);
123err: 134err:
124 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 135 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INHDRERRORS);
125drop: 136drop:
137 rcu_read_unlock();
126 kfree_skb(skb); 138 kfree_skb(skb);
127out: 139out:
128 return 0; 140 return 0;
@@ -140,6 +152,7 @@ static inline int ip6_input_finish(struct sk_buff *skb)
140 unsigned int nhoff; 152 unsigned int nhoff;
141 int nexthdr; 153 int nexthdr;
142 u8 hash; 154 u8 hash;
155 struct inet6_dev *idev;
143 156
144 /* 157 /*
145 * Parse extension headers 158 * Parse extension headers
@@ -147,6 +160,7 @@ static inline int ip6_input_finish(struct sk_buff *skb)
147 160
148 rcu_read_lock(); 161 rcu_read_lock();
149resubmit: 162resubmit:
163 idev = ip6_dst_idev(skb->dst);
150 if (!pskb_pull(skb, skb->h.raw - skb->data)) 164 if (!pskb_pull(skb, skb->h.raw - skb->data))
151 goto discard; 165 goto discard;
152 nhoff = IP6CB(skb)->nhoff; 166 nhoff = IP6CB(skb)->nhoff;
@@ -185,24 +199,24 @@ resubmit:
185 if (ret > 0) 199 if (ret > 0)
186 goto resubmit; 200 goto resubmit;
187 else if (ret == 0) 201 else if (ret == 0)
188 IP6_INC_STATS_BH(IPSTATS_MIB_INDELIVERS); 202 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDELIVERS);
189 } else { 203 } else {
190 if (!raw_sk) { 204 if (!raw_sk) {
191 if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { 205 if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
192 IP6_INC_STATS_BH(IPSTATS_MIB_INUNKNOWNPROTOS); 206 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INUNKNOWNPROTOS);
193 icmpv6_send(skb, ICMPV6_PARAMPROB, 207 icmpv6_send(skb, ICMPV6_PARAMPROB,
194 ICMPV6_UNK_NEXTHDR, nhoff, 208 ICMPV6_UNK_NEXTHDR, nhoff,
195 skb->dev); 209 skb->dev);
196 } 210 }
197 } else 211 } else
198 IP6_INC_STATS_BH(IPSTATS_MIB_INDELIVERS); 212 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDELIVERS);
199 kfree_skb(skb); 213 kfree_skb(skb);
200 } 214 }
201 rcu_read_unlock(); 215 rcu_read_unlock();
202 return 0; 216 return 0;
203 217
204discard: 218discard:
205 IP6_INC_STATS_BH(IPSTATS_MIB_INDISCARDS); 219 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDISCARDS);
206 rcu_read_unlock(); 220 rcu_read_unlock();
207 kfree_skb(skb); 221 kfree_skb(skb);
208 return 0; 222 return 0;
@@ -219,7 +233,7 @@ int ip6_mc_input(struct sk_buff *skb)
219 struct ipv6hdr *hdr; 233 struct ipv6hdr *hdr;
220 int deliver; 234 int deliver;
221 235
222 IP6_INC_STATS_BH(IPSTATS_MIB_INMCASTPKTS); 236 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_INMCASTPKTS);
223 237
224 hdr = skb->nh.ipv6h; 238 hdr = skb->nh.ipv6h;
225 deliver = likely(!(skb->dev->flags & (IFF_PROMISC|IFF_ALLMULTI))) || 239 deliver = likely(!(skb->dev->flags & (IFF_PROMISC|IFF_ALLMULTI))) ||
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 6671691196..7b7bd44fbf 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -72,23 +72,14 @@ static __inline__ void ipv6_select_ident(struct sk_buff *skb, struct frag_hdr *f
72 72
73static inline int ip6_output_finish(struct sk_buff *skb) 73static inline int ip6_output_finish(struct sk_buff *skb)
74{ 74{
75
76 struct dst_entry *dst = skb->dst; 75 struct dst_entry *dst = skb->dst;
77 struct hh_cache *hh = dst->hh; 76
78 77 if (dst->hh)
79 if (hh) { 78 return neigh_hh_output(dst->hh, skb);
80 int hh_alen; 79 else if (dst->neighbour)
81
82 read_lock_bh(&hh->hh_lock);
83 hh_alen = HH_DATA_ALIGN(hh->hh_len);
84 memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
85 read_unlock_bh(&hh->hh_lock);
86 skb_push(skb, hh->hh_len);
87 return hh->hh_output(skb);
88 } else if (dst->neighbour)
89 return dst->neighbour->output(skb); 80 return dst->neighbour->output(skb);
90 81
91 IP6_INC_STATS_BH(IPSTATS_MIB_OUTNOROUTES); 82 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
92 kfree_skb(skb); 83 kfree_skb(skb);
93 return -EINVAL; 84 return -EINVAL;
94 85
@@ -118,6 +109,7 @@ static int ip6_output2(struct sk_buff *skb)
118 109
119 if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr)) { 110 if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr)) {
120 struct ipv6_pinfo* np = skb->sk ? inet6_sk(skb->sk) : NULL; 111 struct ipv6_pinfo* np = skb->sk ? inet6_sk(skb->sk) : NULL;
112 struct inet6_dev *idev = ip6_dst_idev(skb->dst);
121 113
122 if (!(dev->flags & IFF_LOOPBACK) && (!np || np->mc_loop) && 114 if (!(dev->flags & IFF_LOOPBACK) && (!np || np->mc_loop) &&
123 ipv6_chk_mcast_addr(dev, &skb->nh.ipv6h->daddr, 115 ipv6_chk_mcast_addr(dev, &skb->nh.ipv6h->daddr,
@@ -133,13 +125,13 @@ static int ip6_output2(struct sk_buff *skb)
133 ip6_dev_loopback_xmit); 125 ip6_dev_loopback_xmit);
134 126
135 if (skb->nh.ipv6h->hop_limit == 0) { 127 if (skb->nh.ipv6h->hop_limit == 0) {
136 IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); 128 IP6_INC_STATS(idev, IPSTATS_MIB_OUTDISCARDS);
137 kfree_skb(skb); 129 kfree_skb(skb);
138 return 0; 130 return 0;
139 } 131 }
140 } 132 }
141 133
142 IP6_INC_STATS(IPSTATS_MIB_OUTMCASTPKTS); 134 IP6_INC_STATS(idev, IPSTATS_MIB_OUTMCASTPKTS);
143 } 135 }
144 136
145 return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb,NULL, skb->dev,ip6_output_finish); 137 return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb,NULL, skb->dev,ip6_output_finish);
@@ -182,12 +174,14 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
182 174
183 if (skb_headroom(skb) < head_room) { 175 if (skb_headroom(skb) < head_room) {
184 struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room); 176 struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room);
185 kfree_skb(skb); 177 if (skb2 == NULL) {
186 skb = skb2; 178 IP6_INC_STATS(ip6_dst_idev(skb->dst),
187 if (skb == NULL) { 179 IPSTATS_MIB_OUTDISCARDS);
188 IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); 180 kfree_skb(skb);
189 return -ENOBUFS; 181 return -ENOBUFS;
190 } 182 }
183 kfree_skb(skb);
184 skb = skb2;
191 if (sk) 185 if (sk)
192 skb_set_owner_w(skb, sk); 186 skb_set_owner_w(skb, sk);
193 } 187 }
@@ -217,7 +211,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
217 if (tclass < 0) 211 if (tclass < 0)
218 tclass = 0; 212 tclass = 0;
219 213
220 *(u32 *)hdr = htonl(0x60000000 | (tclass << 20)) | fl->fl6_flowlabel; 214 *(__be32 *)hdr = htonl(0x60000000 | (tclass << 20)) | fl->fl6_flowlabel;
221 215
222 hdr->payload_len = htons(seg_len); 216 hdr->payload_len = htons(seg_len);
223 hdr->nexthdr = proto; 217 hdr->nexthdr = proto;
@@ -230,7 +224,8 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
230 224
231 mtu = dst_mtu(dst); 225 mtu = dst_mtu(dst);
232 if ((skb->len <= mtu) || ipfragok || skb_is_gso(skb)) { 226 if ((skb->len <= mtu) || ipfragok || skb_is_gso(skb)) {
233 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS); 227 IP6_INC_STATS(ip6_dst_idev(skb->dst),
228 IPSTATS_MIB_OUTREQUESTS);
234 return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, 229 return NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev,
235 dst_output); 230 dst_output);
236 } 231 }
@@ -239,7 +234,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
239 printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n"); 234 printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n");
240 skb->dev = dst->dev; 235 skb->dev = dst->dev;
241 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); 236 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
242 IP6_INC_STATS(IPSTATS_MIB_FRAGFAILS); 237 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS);
243 kfree_skb(skb); 238 kfree_skb(skb);
244 return -EMSGSIZE; 239 return -EMSGSIZE;
245} 240}
@@ -267,7 +262,7 @@ int ip6_nd_hdr(struct sock *sk, struct sk_buff *skb, struct net_device *dev,
267 hdr = (struct ipv6hdr *) skb_put(skb, sizeof(struct ipv6hdr)); 262 hdr = (struct ipv6hdr *) skb_put(skb, sizeof(struct ipv6hdr));
268 skb->nh.ipv6h = hdr; 263 skb->nh.ipv6h = hdr;
269 264
270 *(u32*)hdr = htonl(0x60000000); 265 *(__be32*)hdr = htonl(0x60000000);
271 266
272 hdr->payload_len = htons(len); 267 hdr->payload_len = htons(len);
273 hdr->nexthdr = proto; 268 hdr->nexthdr = proto;
@@ -373,7 +368,7 @@ int ip6_forward(struct sk_buff *skb)
373 goto error; 368 goto error;
374 369
375 if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) { 370 if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) {
376 IP6_INC_STATS(IPSTATS_MIB_INDISCARDS); 371 IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS);
377 goto drop; 372 goto drop;
378 } 373 }
379 374
@@ -406,7 +401,7 @@ int ip6_forward(struct sk_buff *skb)
406 skb->dev = dst->dev; 401 skb->dev = dst->dev;
407 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 402 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT,
408 0, skb->dev); 403 0, skb->dev);
409 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 404 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS);
410 405
411 kfree_skb(skb); 406 kfree_skb(skb);
412 return -ETIMEDOUT; 407 return -ETIMEDOUT;
@@ -419,13 +414,13 @@ int ip6_forward(struct sk_buff *skb)
419 if (proxied > 0) 414 if (proxied > 0)
420 return ip6_input(skb); 415 return ip6_input(skb);
421 else if (proxied < 0) { 416 else if (proxied < 0) {
422 IP6_INC_STATS(IPSTATS_MIB_INDISCARDS); 417 IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS);
423 goto drop; 418 goto drop;
424 } 419 }
425 } 420 }
426 421
427 if (!xfrm6_route_forward(skb)) { 422 if (!xfrm6_route_forward(skb)) {
428 IP6_INC_STATS(IPSTATS_MIB_INDISCARDS); 423 IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_INDISCARDS);
429 goto drop; 424 goto drop;
430 } 425 }
431 dst = skb->dst; 426 dst = skb->dst;
@@ -464,14 +459,14 @@ int ip6_forward(struct sk_buff *skb)
464 /* Again, force OUTPUT device used as source address */ 459 /* Again, force OUTPUT device used as source address */
465 skb->dev = dst->dev; 460 skb->dev = dst->dev;
466 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst_mtu(dst), skb->dev); 461 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst_mtu(dst), skb->dev);
467 IP6_INC_STATS_BH(IPSTATS_MIB_INTOOBIGERRORS); 462 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INTOOBIGERRORS);
468 IP6_INC_STATS_BH(IPSTATS_MIB_FRAGFAILS); 463 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_FRAGFAILS);
469 kfree_skb(skb); 464 kfree_skb(skb);
470 return -EMSGSIZE; 465 return -EMSGSIZE;
471 } 466 }
472 467
473 if (skb_cow(skb, dst->dev->hard_header_len)) { 468 if (skb_cow(skb, dst->dev->hard_header_len)) {
474 IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); 469 IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_OUTDISCARDS);
475 goto drop; 470 goto drop;
476 } 471 }
477 472
@@ -481,11 +476,11 @@ int ip6_forward(struct sk_buff *skb)
481 476
482 hdr->hop_limit--; 477 hdr->hop_limit--;
483 478
484 IP6_INC_STATS_BH(IPSTATS_MIB_OUTFORWDATAGRAMS); 479 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_OUTFORWDATAGRAMS);
485 return NF_HOOK(PF_INET6,NF_IP6_FORWARD, skb, skb->dev, dst->dev, ip6_forward_finish); 480 return NF_HOOK(PF_INET6,NF_IP6_FORWARD, skb, skb->dev, dst->dev, ip6_forward_finish);
486 481
487error: 482error:
488 IP6_INC_STATS_BH(IPSTATS_MIB_INADDRERRORS); 483 IP6_INC_STATS_BH(ip6_dst_idev(dst), IPSTATS_MIB_INADDRERRORS);
489drop: 484drop:
490 kfree_skb(skb); 485 kfree_skb(skb);
491 return -EINVAL; 486 return -EINVAL;
@@ -499,12 +494,12 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)
499 dst_release(to->dst); 494 dst_release(to->dst);
500 to->dst = dst_clone(from->dst); 495 to->dst = dst_clone(from->dst);
501 to->dev = from->dev; 496 to->dev = from->dev;
497 to->mark = from->mark;
502 498
503#ifdef CONFIG_NET_SCHED 499#ifdef CONFIG_NET_SCHED
504 to->tc_index = from->tc_index; 500 to->tc_index = from->tc_index;
505#endif 501#endif
506#ifdef CONFIG_NETFILTER 502#ifdef CONFIG_NETFILTER
507 to->nfmark = from->nfmark;
508 /* Connection association is same as pre-frag packet */ 503 /* Connection association is same as pre-frag packet */
509 nf_conntrack_put(to->nfct); 504 nf_conntrack_put(to->nfct);
510 to->nfct = from->nfct; 505 to->nfct = from->nfct;
@@ -571,7 +566,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
571 struct ipv6hdr *tmp_hdr; 566 struct ipv6hdr *tmp_hdr;
572 struct frag_hdr *fh; 567 struct frag_hdr *fh;
573 unsigned int mtu, hlen, left, len; 568 unsigned int mtu, hlen, left, len;
574 u32 frag_id = 0; 569 __be32 frag_id = 0;
575 int ptr, offset = 0, err=0; 570 int ptr, offset = 0, err=0;
576 u8 *prevhdr, nexthdr = 0; 571 u8 *prevhdr, nexthdr = 0;
577 572
@@ -620,14 +615,13 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
620 skb_shinfo(skb)->frag_list = NULL; 615 skb_shinfo(skb)->frag_list = NULL;
621 /* BUILD HEADER */ 616 /* BUILD HEADER */
622 617
623 tmp_hdr = kmalloc(hlen, GFP_ATOMIC); 618 *prevhdr = NEXTHDR_FRAGMENT;
619 tmp_hdr = kmemdup(skb->nh.raw, hlen, GFP_ATOMIC);
624 if (!tmp_hdr) { 620 if (!tmp_hdr) {
625 IP6_INC_STATS(IPSTATS_MIB_FRAGFAILS); 621 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS);
626 return -ENOMEM; 622 return -ENOMEM;
627 } 623 }
628 624
629 *prevhdr = NEXTHDR_FRAGMENT;
630 memcpy(tmp_hdr, skb->nh.raw, hlen);
631 __skb_pull(skb, hlen); 625 __skb_pull(skb, hlen);
632 fh = (struct frag_hdr*)__skb_push(skb, sizeof(struct frag_hdr)); 626 fh = (struct frag_hdr*)__skb_push(skb, sizeof(struct frag_hdr));
633 skb->nh.raw = __skb_push(skb, hlen); 627 skb->nh.raw = __skb_push(skb, hlen);
@@ -643,7 +637,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
643 skb->data_len = first_len - skb_headlen(skb); 637 skb->data_len = first_len - skb_headlen(skb);
644 skb->len = first_len; 638 skb->len = first_len;
645 skb->nh.ipv6h->payload_len = htons(first_len - sizeof(struct ipv6hdr)); 639 skb->nh.ipv6h->payload_len = htons(first_len - sizeof(struct ipv6hdr));
646 640
641 dst_hold(&rt->u.dst);
647 642
648 for (;;) { 643 for (;;) {
649 /* Prepare header of the next frame, 644 /* Prepare header of the next frame,
@@ -667,7 +662,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
667 662
668 err = output(skb); 663 err = output(skb);
669 if(!err) 664 if(!err)
670 IP6_INC_STATS(IPSTATS_MIB_FRAGCREATES); 665 IP6_INC_STATS(ip6_dst_idev(&rt->u.dst), IPSTATS_MIB_FRAGCREATES);
671 666
672 if (err || !frag) 667 if (err || !frag)
673 break; 668 break;
@@ -680,7 +675,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
680 kfree(tmp_hdr); 675 kfree(tmp_hdr);
681 676
682 if (err == 0) { 677 if (err == 0) {
683 IP6_INC_STATS(IPSTATS_MIB_FRAGOKS); 678 IP6_INC_STATS(ip6_dst_idev(&rt->u.dst), IPSTATS_MIB_FRAGOKS);
679 dst_release(&rt->u.dst);
684 return 0; 680 return 0;
685 } 681 }
686 682
@@ -690,7 +686,8 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
690 frag = skb; 686 frag = skb;
691 } 687 }
692 688
693 IP6_INC_STATS(IPSTATS_MIB_FRAGFAILS); 689 IP6_INC_STATS(ip6_dst_idev(&rt->u.dst), IPSTATS_MIB_FRAGFAILS);
690 dst_release(&rt->u.dst);
694 return err; 691 return err;
695 } 692 }
696 693
@@ -723,7 +720,8 @@ slow_path:
723 720
724 if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_RESERVED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) { 721 if ((frag = alloc_skb(len+hlen+sizeof(struct frag_hdr)+LL_RESERVED_SPACE(rt->u.dst.dev), GFP_ATOMIC)) == NULL) {
725 NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n"); 722 NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n");
726 IP6_INC_STATS(IPSTATS_MIB_FRAGFAILS); 723 IP6_INC_STATS(ip6_dst_idev(skb->dst),
724 IPSTATS_MIB_FRAGFAILS);
727 err = -ENOMEM; 725 err = -ENOMEM;
728 goto fail; 726 goto fail;
729 } 727 }
@@ -784,15 +782,17 @@ slow_path:
784 if (err) 782 if (err)
785 goto fail; 783 goto fail;
786 784
787 IP6_INC_STATS(IPSTATS_MIB_FRAGCREATES); 785 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGCREATES);
788 } 786 }
787 IP6_INC_STATS(ip6_dst_idev(skb->dst),
788 IPSTATS_MIB_FRAGOKS);
789 kfree_skb(skb); 789 kfree_skb(skb);
790 IP6_INC_STATS(IPSTATS_MIB_FRAGOKS);
791 return err; 790 return err;
792 791
793fail: 792fail:
793 IP6_INC_STATS(ip6_dst_idev(skb->dst),
794 IPSTATS_MIB_FRAGFAILS);
794 kfree_skb(skb); 795 kfree_skb(skb);
795 IP6_INC_STATS(IPSTATS_MIB_FRAGFAILS);
796 return err; 796 return err;
797} 797}
798 798
@@ -1265,7 +1265,7 @@ alloc_new_skb:
1265 return 0; 1265 return 0;
1266error: 1266error:
1267 inet->cork.length -= length; 1267 inet->cork.length -= length;
1268 IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); 1268 IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS);
1269 return err; 1269 return err;
1270} 1270}
1271 1271
@@ -1311,7 +1311,7 @@ int ip6_push_pending_frames(struct sock *sk)
1311 1311
1312 skb->nh.ipv6h = hdr = (struct ipv6hdr*) skb_push(skb, sizeof(struct ipv6hdr)); 1312 skb->nh.ipv6h = hdr = (struct ipv6hdr*) skb_push(skb, sizeof(struct ipv6hdr));
1313 1313
1314 *(u32*)hdr = fl->fl6_flowlabel | 1314 *(__be32*)hdr = fl->fl6_flowlabel |
1315 htonl(0x60000000 | ((int)np->cork.tclass << 20)); 1315 htonl(0x60000000 | ((int)np->cork.tclass << 20));
1316 1316
1317 if (skb->len <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) 1317 if (skb->len <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN)
@@ -1326,7 +1326,7 @@ int ip6_push_pending_frames(struct sock *sk)
1326 skb->priority = sk->sk_priority; 1326 skb->priority = sk->sk_priority;
1327 1327
1328 skb->dst = dst_clone(&rt->u.dst); 1328 skb->dst = dst_clone(&rt->u.dst);
1329 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS); 1329 IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS);
1330 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output); 1330 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, skb->dst->dev, dst_output);
1331 if (err) { 1331 if (err) {
1332 if (err > 0) 1332 if (err > 0)
@@ -1357,7 +1357,8 @@ void ip6_flush_pending_frames(struct sock *sk)
1357 struct sk_buff *skb; 1357 struct sk_buff *skb;
1358 1358
1359 while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) { 1359 while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) {
1360 IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); 1360 IP6_INC_STATS(ip6_dst_idev(skb->dst),
1361 IPSTATS_MIB_OUTDISCARDS);
1361 kfree_skb(skb); 1362 kfree_skb(skb);
1362 } 1363 }
1363 1364
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index b9f40290d1..8d918348f5 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -66,7 +66,7 @@ MODULE_LICENSE("GPL");
66 66
67#define HASH_SIZE 32 67#define HASH_SIZE 32
68 68
69#define HASH(addr) (((addr)->s6_addr32[0] ^ (addr)->s6_addr32[1] ^ \ 69#define HASH(addr) ((__force u32)((addr)->s6_addr32[0] ^ (addr)->s6_addr32[1] ^ \
70 (addr)->s6_addr32[2] ^ (addr)->s6_addr32[3]) & \ 70 (addr)->s6_addr32[2] ^ (addr)->s6_addr32[3]) & \
71 (HASH_SIZE - 1)) 71 (HASH_SIZE - 1))
72 72
@@ -215,11 +215,10 @@ ip6ip6_tnl_unlink(struct ip6_tnl *t)
215 * Create tunnel matching given parameters. 215 * Create tunnel matching given parameters.
216 * 216 *
217 * Return: 217 * Return:
218 * 0 on success 218 * created tunnel or NULL
219 **/ 219 **/
220 220
221static int 221static struct ip6_tnl *ip6_tnl_create(struct ip6_tnl_parm *p)
222ip6_tnl_create(struct ip6_tnl_parm *p, struct ip6_tnl **pt)
223{ 222{
224 struct net_device *dev; 223 struct net_device *dev;
225 struct ip6_tnl *t; 224 struct ip6_tnl *t;
@@ -236,11 +235,11 @@ ip6_tnl_create(struct ip6_tnl_parm *p, struct ip6_tnl **pt)
236 break; 235 break;
237 } 236 }
238 if (i == IP6_TNL_MAX) 237 if (i == IP6_TNL_MAX)
239 return -ENOBUFS; 238 goto failed;
240 } 239 }
241 dev = alloc_netdev(sizeof (*t), name, ip6ip6_tnl_dev_setup); 240 dev = alloc_netdev(sizeof (*t), name, ip6ip6_tnl_dev_setup);
242 if (dev == NULL) 241 if (dev == NULL)
243 return -ENOMEM; 242 goto failed;
244 243
245 t = netdev_priv(dev); 244 t = netdev_priv(dev);
246 dev->init = ip6ip6_tnl_dev_init; 245 dev->init = ip6ip6_tnl_dev_init;
@@ -248,13 +247,13 @@ ip6_tnl_create(struct ip6_tnl_parm *p, struct ip6_tnl **pt)
248 247
249 if ((err = register_netdevice(dev)) < 0) { 248 if ((err = register_netdevice(dev)) < 0) {
250 free_netdev(dev); 249 free_netdev(dev);
251 return err; 250 goto failed;
252 } 251 }
253 dev_hold(dev); 252 dev_hold(dev);
254
255 ip6ip6_tnl_link(t); 253 ip6ip6_tnl_link(t);
256 *pt = t; 254 return t;
257 return 0; 255failed:
256 return NULL;
258} 257}
259 258
260/** 259/**
@@ -268,32 +267,23 @@ ip6_tnl_create(struct ip6_tnl_parm *p, struct ip6_tnl **pt)
268 * tunnel device is created and registered for use. 267 * tunnel device is created and registered for use.
269 * 268 *
270 * Return: 269 * Return:
271 * 0 if tunnel located or created, 270 * matching tunnel or NULL
272 * -EINVAL if parameters incorrect,
273 * -ENODEV if no matching tunnel available
274 **/ 271 **/
275 272
276static int 273static struct ip6_tnl *ip6ip6_tnl_locate(struct ip6_tnl_parm *p, int create)
277ip6ip6_tnl_locate(struct ip6_tnl_parm *p, struct ip6_tnl **pt, int create)
278{ 274{
279 struct in6_addr *remote = &p->raddr; 275 struct in6_addr *remote = &p->raddr;
280 struct in6_addr *local = &p->laddr; 276 struct in6_addr *local = &p->laddr;
281 struct ip6_tnl *t; 277 struct ip6_tnl *t;
282 278
283 if (p->proto != IPPROTO_IPV6)
284 return -EINVAL;
285
286 for (t = *ip6ip6_bucket(p); t; t = t->next) { 279 for (t = *ip6ip6_bucket(p); t; t = t->next) {
287 if (ipv6_addr_equal(local, &t->parms.laddr) && 280 if (ipv6_addr_equal(local, &t->parms.laddr) &&
288 ipv6_addr_equal(remote, &t->parms.raddr)) { 281 ipv6_addr_equal(remote, &t->parms.raddr))
289 *pt = t; 282 return t;
290 return (create ? -EEXIST : 0);
291 }
292 } 283 }
293 if (!create) 284 if (!create)
294 return -ENODEV; 285 return NULL;
295 286 return ip6_tnl_create(p);
296 return ip6_tnl_create(p, pt);
297} 287}
298 288
299/** 289/**
@@ -391,7 +381,7 @@ parse_tlv_tnl_enc_lim(struct sk_buff *skb, __u8 * raw)
391 381
392static int 382static int
393ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 383ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
394 int type, int code, int offset, __u32 info) 384 int type, int code, int offset, __be32 info)
395{ 385{
396 struct ipv6hdr *ipv6h = (struct ipv6hdr *) skb->data; 386 struct ipv6hdr *ipv6h = (struct ipv6hdr *) skb->data;
397 struct ip6_tnl *t; 387 struct ip6_tnl *t;
@@ -434,12 +424,9 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
434 } 424 }
435 break; 425 break;
436 case ICMPV6_PARAMPROB: 426 case ICMPV6_PARAMPROB:
437 /* ignore if parameter problem not caused by a tunnel 427 teli = 0;
438 encapsulation limit sub-option */ 428 if (code == ICMPV6_HDR_FIELD)
439 if (code != ICMPV6_HDR_FIELD) { 429 teli = parse_tlv_tnl_enc_lim(skb, skb->data);
440 break;
441 }
442 teli = parse_tlv_tnl_enc_lim(skb, skb->data);
443 430
444 if (teli && teli == ntohl(info) - 2) { 431 if (teli && teli == ntohl(info) - 2) {
445 tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->data[teli]; 432 tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->data[teli];
@@ -451,6 +438,10 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
451 "tunnel!\n", t->parms.name); 438 "tunnel!\n", t->parms.name);
452 rel_msg = 1; 439 rel_msg = 1;
453 } 440 }
441 } else if (net_ratelimit()) {
442 printk(KERN_WARNING
443 "%s: Recipient unable to parse tunneled "
444 "packet!\n ", t->parms.name);
454 } 445 }
455 break; 446 break;
456 case ICMPV6_PKT_TOOBIG: 447 case ICMPV6_PKT_TOOBIG:
@@ -470,6 +461,7 @@ ip6ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
470 if (rel_msg && pskb_may_pull(skb, offset + sizeof (*ipv6h))) { 461 if (rel_msg && pskb_may_pull(skb, offset + sizeof (*ipv6h))) {
471 struct rt6_info *rt; 462 struct rt6_info *rt;
472 struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); 463 struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
464
473 if (!skb2) 465 if (!skb2)
474 goto out; 466 goto out;
475 467
@@ -504,6 +496,27 @@ static inline void ip6ip6_ecn_decapsulate(struct ipv6hdr *outer_iph,
504 if (INET_ECN_is_ce(ipv6_get_dsfield(outer_iph))) 496 if (INET_ECN_is_ce(ipv6_get_dsfield(outer_iph)))
505 IP6_ECN_set_ce(inner_iph); 497 IP6_ECN_set_ce(inner_iph);
506} 498}
499static inline int ip6_tnl_rcv_ctl(struct ip6_tnl *t)
500{
501 struct ip6_tnl_parm *p = &t->parms;
502 int ret = 0;
503
504 if (p->flags & IP6_TNL_F_CAP_RCV) {
505 struct net_device *ldev = NULL;
506
507 if (p->link)
508 ldev = dev_get_by_index(p->link);
509
510 if ((ipv6_addr_is_multicast(&p->laddr) ||
511 likely(ipv6_chk_addr(&p->laddr, ldev, 0))) &&
512 likely(!ipv6_chk_addr(&p->raddr, NULL, 0)))
513 ret = 1;
514
515 if (ldev)
516 dev_put(ldev);
517 }
518 return ret;
519}
507 520
508/** 521/**
509 * ip6ip6_rcv - decapsulate IPv6 packet and retransmit it locally 522 * ip6ip6_rcv - decapsulate IPv6 packet and retransmit it locally
@@ -528,7 +541,7 @@ ip6ip6_rcv(struct sk_buff *skb)
528 goto discard; 541 goto discard;
529 } 542 }
530 543
531 if (!(t->parms.flags & IP6_TNL_F_CAP_RCV)) { 544 if (!ip6_tnl_rcv_ctl(t)) {
532 t->stat.rx_dropped++; 545 t->stat.rx_dropped++;
533 read_unlock(&ip6ip6_lock); 546 read_unlock(&ip6ip6_lock);
534 goto discard; 547 goto discard;
@@ -560,31 +573,23 @@ discard:
560 return 0; 573 return 0;
561} 574}
562 575
563static inline struct ipv6_txoptions *create_tel(__u8 encap_limit) 576struct ipv6_tel_txoption {
564{ 577 struct ipv6_txoptions ops;
565 struct ipv6_tlv_tnl_enc_lim *tel; 578 __u8 dst_opt[8];
566 struct ipv6_txoptions *opt; 579};
567 __u8 *raw;
568
569 int opt_len = sizeof(*opt) + 8;
570
571 if (!(opt = kzalloc(opt_len, GFP_ATOMIC))) {
572 return NULL;
573 }
574 opt->tot_len = opt_len;
575 opt->dst0opt = (struct ipv6_opt_hdr *) (opt + 1);
576 opt->opt_nflen = 8;
577 580
578 tel = (struct ipv6_tlv_tnl_enc_lim *) (opt->dst0opt + 1); 581static void init_tel_txopt(struct ipv6_tel_txoption *opt, __u8 encap_limit)
579 tel->type = IPV6_TLV_TNL_ENCAP_LIMIT; 582{
580 tel->length = 1; 583 memset(opt, 0, sizeof(struct ipv6_tel_txoption));
581 tel->encap_limit = encap_limit;
582 584
583 raw = (__u8 *) opt->dst0opt; 585 opt->dst_opt[2] = IPV6_TLV_TNL_ENCAP_LIMIT;
584 raw[5] = IPV6_TLV_PADN; 586 opt->dst_opt[3] = 1;
585 raw[6] = 1; 587 opt->dst_opt[4] = encap_limit;
588 opt->dst_opt[5] = IPV6_TLV_PADN;
589 opt->dst_opt[6] = 1;
586 590
587 return opt; 591 opt->ops.dst0opt = (struct ipv6_opt_hdr *) opt->dst_opt;
592 opt->ops.opt_nflen = 8;
588} 593}
589 594
590/** 595/**
@@ -607,6 +612,34 @@ ip6ip6_tnl_addr_conflict(struct ip6_tnl *t, struct ipv6hdr *hdr)
607 return ipv6_addr_equal(&t->parms.raddr, &hdr->saddr); 612 return ipv6_addr_equal(&t->parms.raddr, &hdr->saddr);
608} 613}
609 614
615static inline int ip6_tnl_xmit_ctl(struct ip6_tnl *t)
616{
617 struct ip6_tnl_parm *p = &t->parms;
618 int ret = 0;
619
620 if (p->flags & IP6_TNL_F_CAP_XMIT) {
621 struct net_device *ldev = NULL;
622
623 if (p->link)
624 ldev = dev_get_by_index(p->link);
625
626 if (unlikely(!ipv6_chk_addr(&p->laddr, ldev, 0)))
627 printk(KERN_WARNING
628 "%s xmit: Local address not yet configured!\n",
629 p->name);
630 else if (!ipv6_addr_is_multicast(&p->raddr) &&
631 unlikely(ipv6_chk_addr(&p->raddr, NULL, 0)))
632 printk(KERN_WARNING
633 "%s xmit: Routing loop! "
634 "Remote address found on this node!\n",
635 p->name);
636 else
637 ret = 1;
638 if (ldev)
639 dev_put(ldev);
640 }
641 return ret;
642}
610/** 643/**
611 * ip6ip6_tnl_xmit - encapsulate packet and send 644 * ip6ip6_tnl_xmit - encapsulate packet and send
612 * @skb: the outgoing socket buffer 645 * @skb: the outgoing socket buffer
@@ -626,8 +659,8 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
626 struct ip6_tnl *t = netdev_priv(dev); 659 struct ip6_tnl *t = netdev_priv(dev);
627 struct net_device_stats *stats = &t->stat; 660 struct net_device_stats *stats = &t->stat;
628 struct ipv6hdr *ipv6h = skb->nh.ipv6h; 661 struct ipv6hdr *ipv6h = skb->nh.ipv6h;
629 struct ipv6_txoptions *opt = NULL;
630 int encap_limit = -1; 662 int encap_limit = -1;
663 struct ipv6_tel_txoption opt;
631 __u16 offset; 664 __u16 offset;
632 struct flowi fl; 665 struct flowi fl;
633 struct dst_entry *dst; 666 struct dst_entry *dst;
@@ -644,10 +677,9 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
644 goto tx_err; 677 goto tx_err;
645 } 678 }
646 if (skb->protocol != htons(ETH_P_IPV6) || 679 if (skb->protocol != htons(ETH_P_IPV6) ||
647 !(t->parms.flags & IP6_TNL_F_CAP_XMIT) || 680 !ip6_tnl_xmit_ctl(t) || ip6ip6_tnl_addr_conflict(t, ipv6h))
648 ip6ip6_tnl_addr_conflict(t, ipv6h)) {
649 goto tx_err; 681 goto tx_err;
650 } 682
651 if ((offset = parse_tlv_tnl_enc_lim(skb, skb->nh.raw)) > 0) { 683 if ((offset = parse_tlv_tnl_enc_lim(skb, skb->nh.raw)) > 0) {
652 struct ipv6_tlv_tnl_enc_lim *tel; 684 struct ipv6_tlv_tnl_enc_lim *tel;
653 tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->nh.raw[offset]; 685 tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->nh.raw[offset];
@@ -657,20 +689,17 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
657 goto tx_err; 689 goto tx_err;
658 } 690 }
659 encap_limit = tel->encap_limit - 1; 691 encap_limit = tel->encap_limit - 1;
660 } else if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) { 692 } else if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
661 encap_limit = t->parms.encap_limit; 693 encap_limit = t->parms.encap_limit;
662 } 694
663 memcpy(&fl, &t->fl, sizeof (fl)); 695 memcpy(&fl, &t->fl, sizeof (fl));
664 proto = fl.proto; 696 proto = fl.proto;
665 697
666 dsfield = ipv6_get_dsfield(ipv6h); 698 dsfield = ipv6_get_dsfield(ipv6h);
667 if ((t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)) 699 if ((t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS))
668 fl.fl6_flowlabel |= (*(__u32 *) ipv6h & IPV6_TCLASS_MASK); 700 fl.fl6_flowlabel |= (*(__be32 *) ipv6h & IPV6_TCLASS_MASK);
669 if ((t->parms.flags & IP6_TNL_F_USE_ORIG_FLOWLABEL)) 701 if ((t->parms.flags & IP6_TNL_F_USE_ORIG_FLOWLABEL))
670 fl.fl6_flowlabel |= (*(__u32 *) ipv6h & IPV6_FLOWLABEL_MASK); 702 fl.fl6_flowlabel |= (*(__be32 *) ipv6h & IPV6_FLOWLABEL_MASK);
671
672 if (encap_limit >= 0 && (opt = create_tel(encap_limit)) == NULL)
673 goto tx_err;
674 703
675 if ((dst = ip6_tnl_dst_check(t)) != NULL) 704 if ((dst = ip6_tnl_dst_check(t)) != NULL)
676 dst_hold(dst); 705 dst_hold(dst);
@@ -692,7 +721,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
692 goto tx_err_dst_release; 721 goto tx_err_dst_release;
693 } 722 }
694 mtu = dst_mtu(dst) - sizeof (*ipv6h); 723 mtu = dst_mtu(dst) - sizeof (*ipv6h);
695 if (opt) { 724 if (encap_limit >= 0) {
696 max_headroom += 8; 725 max_headroom += 8;
697 mtu -= 8; 726 mtu -= 8;
698 } 727 }
@@ -730,12 +759,13 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
730 759
731 skb->h.raw = skb->nh.raw; 760 skb->h.raw = skb->nh.raw;
732 761
733 if (opt) 762 if (encap_limit >= 0) {
734 ipv6_push_nfrag_opts(skb, opt, &proto, NULL); 763 init_tel_txopt(&opt, encap_limit);
735 764 ipv6_push_nfrag_opts(skb, &opt.ops, &proto, NULL);
765 }
736 skb->nh.raw = skb_push(skb, sizeof(struct ipv6hdr)); 766 skb->nh.raw = skb_push(skb, sizeof(struct ipv6hdr));
737 ipv6h = skb->nh.ipv6h; 767 ipv6h = skb->nh.ipv6h;
738 *(u32*)ipv6h = fl.fl6_flowlabel | htonl(0x60000000); 768 *(__be32*)ipv6h = fl.fl6_flowlabel | htonl(0x60000000);
739 dsfield = INET_ECN_encapsulate(0, dsfield); 769 dsfield = INET_ECN_encapsulate(0, dsfield);
740 ipv6_change_dsfield(ipv6h, ~INET_ECN_MASK, dsfield); 770 ipv6_change_dsfield(ipv6h, ~INET_ECN_MASK, dsfield);
741 ipv6h->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); 771 ipv6h->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
@@ -748,7 +778,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
748 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, 778 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL,
749 skb->dst->dev, dst_output); 779 skb->dst->dev, dst_output);
750 780
751 if (err == NET_XMIT_SUCCESS || err == NET_XMIT_CN) { 781 if (net_xmit_eval(err) == 0) {
752 stats->tx_bytes += pkt_len; 782 stats->tx_bytes += pkt_len;
753 stats->tx_packets++; 783 stats->tx_packets++;
754 } else { 784 } else {
@@ -756,9 +786,6 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
756 stats->tx_aborted_errors++; 786 stats->tx_aborted_errors++;
757 } 787 }
758 ip6_tnl_dst_store(t, dst); 788 ip6_tnl_dst_store(t, dst);
759
760 kfree(opt);
761
762 t->recursion--; 789 t->recursion--;
763 return 0; 790 return 0;
764tx_err_link_failure: 791tx_err_link_failure:
@@ -766,7 +793,6 @@ tx_err_link_failure:
766 dst_link_failure(skb); 793 dst_link_failure(skb);
767tx_err_dst_release: 794tx_err_dst_release:
768 dst_release(dst); 795 dst_release(dst);
769 kfree(opt);
770tx_err: 796tx_err:
771 stats->tx_errors++; 797 stats->tx_errors++;
772 stats->tx_dropped++; 798 stats->tx_dropped++;
@@ -778,39 +804,19 @@ tx_err:
778static void ip6_tnl_set_cap(struct ip6_tnl *t) 804static void ip6_tnl_set_cap(struct ip6_tnl *t)
779{ 805{
780 struct ip6_tnl_parm *p = &t->parms; 806 struct ip6_tnl_parm *p = &t->parms;
781 struct in6_addr *laddr = &p->laddr; 807 int ltype = ipv6_addr_type(&p->laddr);
782 struct in6_addr *raddr = &p->raddr; 808 int rtype = ipv6_addr_type(&p->raddr);
783 int ltype = ipv6_addr_type(laddr);
784 int rtype = ipv6_addr_type(raddr);
785 809
786 p->flags &= ~(IP6_TNL_F_CAP_XMIT|IP6_TNL_F_CAP_RCV); 810 p->flags &= ~(IP6_TNL_F_CAP_XMIT|IP6_TNL_F_CAP_RCV);
787 811
788 if (ltype != IPV6_ADDR_ANY && rtype != IPV6_ADDR_ANY && 812 if (ltype & (IPV6_ADDR_UNICAST|IPV6_ADDR_MULTICAST) &&
789 ((ltype|rtype) & 813 rtype & (IPV6_ADDR_UNICAST|IPV6_ADDR_MULTICAST) &&
790 (IPV6_ADDR_UNICAST| 814 !((ltype|rtype) & IPV6_ADDR_LOOPBACK) &&
791 IPV6_ADDR_LOOPBACK|IPV6_ADDR_LINKLOCAL| 815 (!((ltype|rtype) & IPV6_ADDR_LINKLOCAL) || p->link)) {
792 IPV6_ADDR_MAPPED|IPV6_ADDR_RESERVED)) == IPV6_ADDR_UNICAST) { 816 if (ltype&IPV6_ADDR_UNICAST)
793 struct net_device *ldev = NULL; 817 p->flags |= IP6_TNL_F_CAP_XMIT;
794 int l_ok = 1; 818 if (rtype&IPV6_ADDR_UNICAST)
795 int r_ok = 1; 819 p->flags |= IP6_TNL_F_CAP_RCV;
796
797 if (p->link)
798 ldev = dev_get_by_index(p->link);
799
800 if (ltype&IPV6_ADDR_UNICAST && !ipv6_chk_addr(laddr, ldev, 0))
801 l_ok = 0;
802
803 if (rtype&IPV6_ADDR_UNICAST && ipv6_chk_addr(raddr, NULL, 0))
804 r_ok = 0;
805
806 if (l_ok && r_ok) {
807 if (ltype&IPV6_ADDR_UNICAST)
808 p->flags |= IP6_TNL_F_CAP_XMIT;
809 if (rtype&IPV6_ADDR_UNICAST)
810 p->flags |= IP6_TNL_F_CAP_RCV;
811 }
812 if (ldev)
813 dev_put(ldev);
814 } 820 }
815} 821}
816 822
@@ -844,8 +850,11 @@ static void ip6ip6_tnl_link_config(struct ip6_tnl *t)
844 dev->iflink = p->link; 850 dev->iflink = p->link;
845 851
846 if (p->flags & IP6_TNL_F_CAP_XMIT) { 852 if (p->flags & IP6_TNL_F_CAP_XMIT) {
853 int strict = (ipv6_addr_type(&p->raddr) &
854 (IPV6_ADDR_MULTICAST|IPV6_ADDR_LINKLOCAL));
855
847 struct rt6_info *rt = rt6_lookup(&p->raddr, &p->laddr, 856 struct rt6_info *rt = rt6_lookup(&p->raddr, &p->laddr,
848 p->link, 0); 857 p->link, strict);
849 858
850 if (rt == NULL) 859 if (rt == NULL)
851 return; 860 return;
@@ -920,26 +929,20 @@ static int
920ip6ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 929ip6ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
921{ 930{
922 int err = 0; 931 int err = 0;
923 int create;
924 struct ip6_tnl_parm p; 932 struct ip6_tnl_parm p;
925 struct ip6_tnl *t = NULL; 933 struct ip6_tnl *t = NULL;
926 934
927 switch (cmd) { 935 switch (cmd) {
928 case SIOCGETTUNNEL: 936 case SIOCGETTUNNEL:
929 if (dev == ip6ip6_fb_tnl_dev) { 937 if (dev == ip6ip6_fb_tnl_dev) {
930 if (copy_from_user(&p, 938 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof (p))) {
931 ifr->ifr_ifru.ifru_data,
932 sizeof (p))) {
933 err = -EFAULT; 939 err = -EFAULT;
934 break; 940 break;
935 } 941 }
936 if ((err = ip6ip6_tnl_locate(&p, &t, 0)) == -ENODEV) 942 t = ip6ip6_tnl_locate(&p, 0);
937 t = netdev_priv(dev); 943 }
938 else if (err) 944 if (t == NULL)
939 break;
940 } else
941 t = netdev_priv(dev); 945 t = netdev_priv(dev);
942
943 memcpy(&p, &t->parms, sizeof (p)); 946 memcpy(&p, &t->parms, sizeof (p));
944 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof (p))) { 947 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof (p))) {
945 err = -EFAULT; 948 err = -EFAULT;
@@ -948,35 +951,36 @@ ip6ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
948 case SIOCADDTUNNEL: 951 case SIOCADDTUNNEL:
949 case SIOCCHGTUNNEL: 952 case SIOCCHGTUNNEL:
950 err = -EPERM; 953 err = -EPERM;
951 create = (cmd == SIOCADDTUNNEL);
952 if (!capable(CAP_NET_ADMIN)) 954 if (!capable(CAP_NET_ADMIN))
953 break; 955 break;
954 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof (p))) { 956 err = -EFAULT;
955 err = -EFAULT; 957 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof (p)))
956 break; 958 break;
957 } 959 err = -EINVAL;
958 if (!create && dev != ip6ip6_fb_tnl_dev) { 960 if (p.proto != IPPROTO_IPV6)
959 t = netdev_priv(dev);
960 }
961 if (!t && (err = ip6ip6_tnl_locate(&p, &t, create))) {
962 break; 961 break;
963 } 962 t = ip6ip6_tnl_locate(&p, cmd == SIOCADDTUNNEL);
964 if (cmd == SIOCCHGTUNNEL) { 963 if (dev != ip6ip6_fb_tnl_dev && cmd == SIOCCHGTUNNEL) {
965 if (t->dev != dev) { 964 if (t != NULL) {
966 err = -EEXIST; 965 if (t->dev != dev) {
967 break; 966 err = -EEXIST;
968 } 967 break;
968 }
969 } else
970 t = netdev_priv(dev);
971
969 ip6ip6_tnl_unlink(t); 972 ip6ip6_tnl_unlink(t);
970 err = ip6ip6_tnl_change(t, &p); 973 err = ip6ip6_tnl_change(t, &p);
971 ip6ip6_tnl_link(t); 974 ip6ip6_tnl_link(t);
972 netdev_state_change(dev); 975 netdev_state_change(dev);
973 } 976 }
974 if (copy_to_user(ifr->ifr_ifru.ifru_data, 977 if (t) {
975 &t->parms, sizeof (p))) {
976 err = -EFAULT;
977 } else {
978 err = 0; 978 err = 0;
979 } 979 if (copy_to_user(ifr->ifr_ifru.ifru_data, &t->parms, sizeof (p)))
980 err = -EFAULT;
981
982 } else
983 err = (cmd == SIOCADDTUNNEL ? -ENOBUFS : -ENOENT);
980 break; 984 break;
981 case SIOCDELTUNNEL: 985 case SIOCDELTUNNEL:
982 err = -EPERM; 986 err = -EPERM;
@@ -984,22 +988,18 @@ ip6ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
984 break; 988 break;
985 989
986 if (dev == ip6ip6_fb_tnl_dev) { 990 if (dev == ip6ip6_fb_tnl_dev) {
987 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, 991 err = -EFAULT;
988 sizeof (p))) { 992 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof (p)))
989 err = -EFAULT;
990 break; 993 break;
991 } 994 err = -ENOENT;
992 err = ip6ip6_tnl_locate(&p, &t, 0); 995 if ((t = ip6ip6_tnl_locate(&p, 0)) == NULL)
993 if (err)
994 break; 996 break;
995 if (t == netdev_priv(ip6ip6_fb_tnl_dev)) { 997 err = -EPERM;
996 err = -EPERM; 998 if (t->dev == ip6ip6_fb_tnl_dev)
997 break; 999 break;
998 } 1000 dev = t->dev;
999 } else {
1000 t = netdev_priv(dev);
1001 } 1001 }
1002 err = unregister_netdevice(t->dev); 1002 err = unregister_netdevice(dev);
1003 break; 1003 break;
1004 default: 1004 default:
1005 err = -EINVAL; 1005 err = -EINVAL;
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 71f59f18ed..511730b67e 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -176,7 +176,7 @@ out_ok:
176} 176}
177 177
178static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 178static void ipcomp6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
179 int type, int code, int offset, __u32 info) 179 int type, int code, int offset, __be32 info)
180{ 180{
181 __be32 spi; 181 __be32 spi;
182 struct ipv6hdr *iph = (struct ipv6hdr*)skb->data; 182 struct ipv6hdr *iph = (struct ipv6hdr*)skb->data;
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index de6b91981b..352690e2ab 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -51,6 +51,7 @@
51#include <net/inet_common.h> 51#include <net/inet_common.h>
52#include <net/tcp.h> 52#include <net/tcp.h>
53#include <net/udp.h> 53#include <net/udp.h>
54#include <net/udplite.h>
54#include <net/xfrm.h> 55#include <net/xfrm.h>
55 56
56#include <asm/uaccess.h> 57#include <asm/uaccess.h>
@@ -239,6 +240,7 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
239 struct sk_buff *pktopt; 240 struct sk_buff *pktopt;
240 241
241 if (sk->sk_protocol != IPPROTO_UDP && 242 if (sk->sk_protocol != IPPROTO_UDP &&
243 sk->sk_protocol != IPPROTO_UDPLITE &&
242 sk->sk_protocol != IPPROTO_TCP) 244 sk->sk_protocol != IPPROTO_TCP)
243 break; 245 break;
244 246
@@ -276,11 +278,15 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
276 sk->sk_family = PF_INET; 278 sk->sk_family = PF_INET;
277 tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); 279 tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
278 } else { 280 } else {
281 struct proto *prot = &udp_prot;
282
283 if (sk->sk_protocol == IPPROTO_UDPLITE)
284 prot = &udplite_prot;
279 local_bh_disable(); 285 local_bh_disable();
280 sock_prot_dec_use(sk->sk_prot); 286 sock_prot_dec_use(sk->sk_prot);
281 sock_prot_inc_use(&udp_prot); 287 sock_prot_inc_use(prot);
282 local_bh_enable(); 288 local_bh_enable();
283 sk->sk_prot = &udp_prot; 289 sk->sk_prot = prot;
284 sk->sk_socket->ops = &inet_dgram_ops; 290 sk->sk_socket->ops = &inet_dgram_ops;
285 sk->sk_family = PF_INET; 291 sk->sk_family = PF_INET;
286 } 292 }
@@ -813,6 +819,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
813 switch (optname) { 819 switch (optname) {
814 case IPV6_ADDRFORM: 820 case IPV6_ADDRFORM:
815 if (sk->sk_protocol != IPPROTO_UDP && 821 if (sk->sk_protocol != IPPROTO_UDP &&
822 sk->sk_protocol != IPPROTO_UDPLITE &&
816 sk->sk_protocol != IPPROTO_TCP) 823 sk->sk_protocol != IPPROTO_TCP)
817 return -EINVAL; 824 return -EINVAL;
818 if (sk->sk_state != TCP_ESTABLISHED) 825 if (sk->sk_state != TCP_ESTABLISHED)
@@ -971,12 +978,27 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
971 break; 978 break;
972 979
973 case IPV6_UNICAST_HOPS: 980 case IPV6_UNICAST_HOPS:
974 val = np->hop_limit;
975 break;
976
977 case IPV6_MULTICAST_HOPS: 981 case IPV6_MULTICAST_HOPS:
978 val = np->mcast_hops; 982 {
983 struct dst_entry *dst;
984
985 if (optname == IPV6_UNICAST_HOPS)
986 val = np->hop_limit;
987 else
988 val = np->mcast_hops;
989
990 dst = sk_dst_get(sk);
991 if (dst) {
992 if (val < 0)
993 val = dst_metric(dst, RTAX_HOPLIMIT);
994 if (val < 0)
995 val = ipv6_get_hoplimit(dst->dev);
996 dst_release(dst);
997 }
998 if (val < 0)
999 val = ipv6_devconf.hop_limit;
979 break; 1000 break;
1001 }
980 1002
981 case IPV6_MULTICAST_LOOP: 1003 case IPV6_MULTICAST_LOOP:
982 val = np->mc_loop; 1004 val = np->mc_loop;
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 3b114e3fa2..a1c231a04a 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -83,7 +83,7 @@
83struct mld2_grec { 83struct mld2_grec {
84 __u8 grec_type; 84 __u8 grec_type;
85 __u8 grec_auxwords; 85 __u8 grec_auxwords;
86 __u16 grec_nsrcs; 86 __be16 grec_nsrcs;
87 struct in6_addr grec_mca; 87 struct in6_addr grec_mca;
88 struct in6_addr grec_src[0]; 88 struct in6_addr grec_src[0];
89}; 89};
@@ -91,18 +91,18 @@ struct mld2_grec {
91struct mld2_report { 91struct mld2_report {
92 __u8 type; 92 __u8 type;
93 __u8 resv1; 93 __u8 resv1;
94 __u16 csum; 94 __sum16 csum;
95 __u16 resv2; 95 __be16 resv2;
96 __u16 ngrec; 96 __be16 ngrec;
97 struct mld2_grec grec[0]; 97 struct mld2_grec grec[0];
98}; 98};
99 99
100struct mld2_query { 100struct mld2_query {
101 __u8 type; 101 __u8 type;
102 __u8 code; 102 __u8 code;
103 __u16 csum; 103 __sum16 csum;
104 __u16 mrc; 104 __be16 mrc;
105 __u16 resv1; 105 __be16 resv1;
106 struct in6_addr mca; 106 struct in6_addr mca;
107#if defined(__LITTLE_ENDIAN_BITFIELD) 107#if defined(__LITTLE_ENDIAN_BITFIELD)
108 __u8 qrv:3, 108 __u8 qrv:3,
@@ -116,7 +116,7 @@ struct mld2_query {
116#error "Please fix <asm/byteorder.h>" 116#error "Please fix <asm/byteorder.h>"
117#endif 117#endif
118 __u8 qqic; 118 __u8 qqic;
119 __u16 nsrcs; 119 __be16 nsrcs;
120 struct in6_addr srcs[0]; 120 struct in6_addr srcs[0];
121}; 121};
122 122
@@ -1465,7 +1465,7 @@ static void mld_sendpack(struct sk_buff *skb)
1465 struct inet6_dev *idev = in6_dev_get(skb->dev); 1465 struct inet6_dev *idev = in6_dev_get(skb->dev);
1466 int err; 1466 int err;
1467 1467
1468 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS); 1468 IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS);
1469 payload_len = skb->tail - (unsigned char *)skb->nh.ipv6h - 1469 payload_len = skb->tail - (unsigned char *)skb->nh.ipv6h -
1470 sizeof(struct ipv6hdr); 1470 sizeof(struct ipv6hdr);
1471 mldlen = skb->tail - skb->h.raw; 1471 mldlen = skb->tail - skb->h.raw;
@@ -1477,9 +1477,9 @@ static void mld_sendpack(struct sk_buff *skb)
1477 mld_dev_queue_xmit); 1477 mld_dev_queue_xmit);
1478 if (!err) { 1478 if (!err) {
1479 ICMP6_INC_STATS(idev,ICMP6_MIB_OUTMSGS); 1479 ICMP6_INC_STATS(idev,ICMP6_MIB_OUTMSGS);
1480 IP6_INC_STATS(IPSTATS_MIB_OUTMCASTPKTS); 1480 IP6_INC_STATS(idev, IPSTATS_MIB_OUTMCASTPKTS);
1481 } else 1481 } else
1482 IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); 1482 IP6_INC_STATS(idev, IPSTATS_MIB_OUTDISCARDS);
1483 1483
1484 if (likely(idev != NULL)) 1484 if (likely(idev != NULL))
1485 in6_dev_put(idev); 1485 in6_dev_put(idev);
@@ -1763,7 +1763,10 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1763 IPV6_TLV_ROUTERALERT, 2, 0, 0, 1763 IPV6_TLV_ROUTERALERT, 2, 0, 0,
1764 IPV6_TLV_PADN, 0 }; 1764 IPV6_TLV_PADN, 0 };
1765 1765
1766 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS); 1766 rcu_read_lock();
1767 IP6_INC_STATS(__in6_dev_get(dev),
1768 IPSTATS_MIB_OUTREQUESTS);
1769 rcu_read_unlock();
1767 snd_addr = addr; 1770 snd_addr = addr;
1768 if (type == ICMPV6_MGM_REDUCTION) { 1771 if (type == ICMPV6_MGM_REDUCTION) {
1769 snd_addr = &all_routers; 1772 snd_addr = &all_routers;
@@ -1777,7 +1780,10 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1777 skb = sock_alloc_send_skb(sk, LL_RESERVED_SPACE(dev) + full_len, 1, &err); 1780 skb = sock_alloc_send_skb(sk, LL_RESERVED_SPACE(dev) + full_len, 1, &err);
1778 1781
1779 if (skb == NULL) { 1782 if (skb == NULL) {
1780 IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); 1783 rcu_read_lock();
1784 IP6_INC_STATS(__in6_dev_get(dev),
1785 IPSTATS_MIB_OUTDISCARDS);
1786 rcu_read_unlock();
1781 return; 1787 return;
1782 } 1788 }
1783 1789
@@ -1816,9 +1822,9 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1816 else 1822 else
1817 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTGROUPMEMBRESPONSES); 1823 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTGROUPMEMBRESPONSES);
1818 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS); 1824 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTMSGS);
1819 IP6_INC_STATS(IPSTATS_MIB_OUTMCASTPKTS); 1825 IP6_INC_STATS(idev, IPSTATS_MIB_OUTMCASTPKTS);
1820 } else 1826 } else
1821 IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); 1827 IP6_INC_STATS(idev, IPSTATS_MIB_OUTDISCARDS);
1822 1828
1823 if (likely(idev != NULL)) 1829 if (likely(idev != NULL))
1824 in6_dev_put(idev); 1830 in6_dev_put(idev);
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c
index 7ccdc8fc5a..be7dd7db65 100644
--- a/net/ipv6/mip6.c
+++ b/net/ipv6/mip6.c
@@ -262,10 +262,10 @@ static int mip6_destopt_reject(struct xfrm_state *x, struct sk_buff *skb, struct
262 sel.proto = fl->proto; 262 sel.proto = fl->proto;
263 sel.dport = xfrm_flowi_dport(fl); 263 sel.dport = xfrm_flowi_dport(fl);
264 if (sel.dport) 264 if (sel.dport)
265 sel.dport_mask = ~((__u16)0); 265 sel.dport_mask = htons(~0);
266 sel.sport = xfrm_flowi_sport(fl); 266 sel.sport = xfrm_flowi_sport(fl);
267 if (sel.sport) 267 if (sel.sport)
268 sel.sport_mask = ~((__u16)0); 268 sel.sport_mask = htons(~0);
269 sel.ifindex = fl->oif; 269 sel.ifindex = fl->oif;
270 270
271 err = km_report(IPPROTO_DSTOPTS, &sel, 271 err = km_report(IPPROTO_DSTOPTS, &sel,
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 73eb8c33e9..6a9f616de3 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -472,7 +472,9 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
472 inc_opt = 0; 472 inc_opt = 0;
473 } 473 }
474 474
475 skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev), 475 skb = sock_alloc_send_skb(sk,
476 (MAX_HEADER + sizeof(struct ipv6hdr) +
477 len + LL_RESERVED_SPACE(dev)),
476 1, &err); 478 1, &err);
477 479
478 if (skb == NULL) { 480 if (skb == NULL) {
@@ -513,7 +515,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
513 515
514 skb->dst = dst; 516 skb->dst = dst;
515 idev = in6_dev_get(dst->dev); 517 idev = in6_dev_get(dst->dev);
516 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS); 518 IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS);
517 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output); 519 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
518 if (!err) { 520 if (!err) {
519 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTNEIGHBORADVERTISEMENTS); 521 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTNEIGHBORADVERTISEMENTS);
@@ -561,7 +563,9 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
561 if (send_llinfo) 563 if (send_llinfo)
562 len += ndisc_opt_addr_space(dev); 564 len += ndisc_opt_addr_space(dev);
563 565
564 skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev), 566 skb = sock_alloc_send_skb(sk,
567 (MAX_HEADER + sizeof(struct ipv6hdr) +
568 len + LL_RESERVED_SPACE(dev)),
565 1, &err); 569 1, &err);
566 if (skb == NULL) { 570 if (skb == NULL) {
567 ND_PRINTK0(KERN_ERR 571 ND_PRINTK0(KERN_ERR
@@ -597,7 +601,7 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
597 /* send it! */ 601 /* send it! */
598 skb->dst = dst; 602 skb->dst = dst;
599 idev = in6_dev_get(dst->dev); 603 idev = in6_dev_get(dst->dev);
600 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS); 604 IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS);
601 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output); 605 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
602 if (!err) { 606 if (!err) {
603 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTNEIGHBORSOLICITS); 607 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTNEIGHBORSOLICITS);
@@ -636,7 +640,9 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
636 if (dev->addr_len) 640 if (dev->addr_len)
637 len += ndisc_opt_addr_space(dev); 641 len += ndisc_opt_addr_space(dev);
638 642
639 skb = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev), 643 skb = sock_alloc_send_skb(sk,
644 (MAX_HEADER + sizeof(struct ipv6hdr) +
645 len + LL_RESERVED_SPACE(dev)),
640 1, &err); 646 1, &err);
641 if (skb == NULL) { 647 if (skb == NULL) {
642 ND_PRINTK0(KERN_ERR 648 ND_PRINTK0(KERN_ERR
@@ -670,7 +676,7 @@ void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr,
670 /* send it! */ 676 /* send it! */
671 skb->dst = dst; 677 skb->dst = dst;
672 idev = in6_dev_get(dst->dev); 678 idev = in6_dev_get(dst->dev);
673 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS); 679 IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS);
674 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output); 680 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, dst->dev, dst_output);
675 if (!err) { 681 if (!err) {
676 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTROUTERSOLICITS); 682 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTROUTERSOLICITS);
@@ -1261,10 +1267,11 @@ skip_defrtr:
1261 } 1267 }
1262 1268
1263 if (ndopts.nd_opts_mtu) { 1269 if (ndopts.nd_opts_mtu) {
1270 __be32 n;
1264 u32 mtu; 1271 u32 mtu;
1265 1272
1266 memcpy(&mtu, ((u8*)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu)); 1273 memcpy(&n, ((u8*)(ndopts.nd_opts_mtu+1))+2, sizeof(mtu));
1267 mtu = ntohl(mtu); 1274 mtu = ntohl(n);
1268 1275
1269 if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) { 1276 if (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) {
1270 ND_PRINTK2(KERN_WARNING 1277 ND_PRINTK2(KERN_WARNING
@@ -1446,7 +1453,9 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1446 rd_len &= ~0x7; 1453 rd_len &= ~0x7;
1447 len += rd_len; 1454 len += rd_len;
1448 1455
1449 buff = sock_alloc_send_skb(sk, MAX_HEADER + len + LL_RESERVED_SPACE(dev), 1456 buff = sock_alloc_send_skb(sk,
1457 (MAX_HEADER + sizeof(struct ipv6hdr) +
1458 len + LL_RESERVED_SPACE(dev)),
1450 1, &err); 1459 1, &err);
1451 if (buff == NULL) { 1460 if (buff == NULL) {
1452 ND_PRINTK0(KERN_ERR 1461 ND_PRINTK0(KERN_ERR
@@ -1504,7 +1513,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1504 1513
1505 buff->dst = dst; 1514 buff->dst = dst;
1506 idev = in6_dev_get(dst->dev); 1515 idev = in6_dev_get(dst->dev);
1507 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS); 1516 IP6_INC_STATS(idev, IPSTATS_MIB_OUTREQUESTS);
1508 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, buff, NULL, dst->dev, dst_output); 1517 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, buff, NULL, dst->dev, dst_output);
1509 if (!err) { 1518 if (!err) {
1510 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTREDIRECTS); 1519 ICMP6_INC_STATS(idev, ICMP6_MIB_OUTREDIRECTS);
@@ -1658,8 +1667,7 @@ int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, struct file * f
1658static int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl, int __user *name, 1667static int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl, int __user *name,
1659 int nlen, void __user *oldval, 1668 int nlen, void __user *oldval,
1660 size_t __user *oldlenp, 1669 size_t __user *oldlenp,
1661 void __user *newval, size_t newlen, 1670 void __user *newval, size_t newlen)
1662 void **context)
1663{ 1671{
1664 struct net_device *dev = ctl->extra1; 1672 struct net_device *dev = ctl->extra1;
1665 struct inet6_dev *idev; 1673 struct inet6_dev *idev;
@@ -1672,14 +1680,12 @@ static int ndisc_ifinfo_sysctl_strategy(ctl_table *ctl, int __user *name,
1672 switch (ctl->ctl_name) { 1680 switch (ctl->ctl_name) {
1673 case NET_NEIGH_REACHABLE_TIME: 1681 case NET_NEIGH_REACHABLE_TIME:
1674 ret = sysctl_jiffies(ctl, name, nlen, 1682 ret = sysctl_jiffies(ctl, name, nlen,
1675 oldval, oldlenp, newval, newlen, 1683 oldval, oldlenp, newval, newlen);
1676 context);
1677 break; 1684 break;
1678 case NET_NEIGH_RETRANS_TIME_MS: 1685 case NET_NEIGH_RETRANS_TIME_MS:
1679 case NET_NEIGH_REACHABLE_TIME_MS: 1686 case NET_NEIGH_REACHABLE_TIME_MS:
1680 ret = sysctl_ms_jiffies(ctl, name, nlen, 1687 ret = sysctl_ms_jiffies(ctl, name, nlen,
1681 oldval, oldlenp, newval, newlen, 1688 oldval, oldlenp, newval, newlen);
1682 context);
1683 break; 1689 break;
1684 default: 1690 default:
1685 ret = 0; 1691 ret = 0;
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index 580b1aba67..f6294e5bcb 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -31,7 +31,7 @@ int ip6_route_me_harder(struct sk_buff *skb)
31#endif 31#endif
32 32
33 if (dst->error) { 33 if (dst->error) {
34 IP6_INC_STATS(IPSTATS_MIB_OUTNOROUTES); 34 IP6_INC_STATS(ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
35 LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n"); 35 LIMIT_NETDEBUG(KERN_DEBUG "ip6_route_me_harder: No more route.\n");
36 dst_release(dst); 36 dst_release(dst);
37 return -EINVAL; 37 return -EINVAL;
@@ -80,11 +80,11 @@ static int nf_ip6_reroute(struct sk_buff **pskb, const struct nf_info *info)
80 return 0; 80 return 0;
81} 81}
82 82
83unsigned int nf_ip6_checksum(struct sk_buff *skb, unsigned int hook, 83__sum16 nf_ip6_checksum(struct sk_buff *skb, unsigned int hook,
84 unsigned int dataoff, u_int8_t protocol) 84 unsigned int dataoff, u_int8_t protocol)
85{ 85{
86 struct ipv6hdr *ip6h = skb->nh.ipv6h; 86 struct ipv6hdr *ip6h = skb->nh.ipv6h;
87 unsigned int csum = 0; 87 __sum16 csum = 0;
88 88
89 switch (skb->ip_summed) { 89 switch (skb->ip_summed) {
90 case CHECKSUM_COMPLETE: 90 case CHECKSUM_COMPLETE:
@@ -100,12 +100,13 @@ unsigned int nf_ip6_checksum(struct sk_buff *skb, unsigned int hook,
100 } 100 }
101 /* fall through */ 101 /* fall through */
102 case CHECKSUM_NONE: 102 case CHECKSUM_NONE:
103 skb->csum = ~csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, 103 skb->csum = ~csum_unfold(
104 csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr,
104 skb->len - dataoff, 105 skb->len - dataoff,
105 protocol, 106 protocol,
106 csum_sub(0, 107 csum_sub(0,
107 skb_checksum(skb, 0, 108 skb_checksum(skb, 0,
108 dataoff, 0))); 109 dataoff, 0))));
109 csum = __skb_checksum_complete(skb); 110 csum = __skb_checksum_complete(skb);
110 } 111 }
111 return csum; 112 return csum;
diff --git a/net/ipv6/netfilter/Kconfig b/net/ipv6/netfilter/Kconfig
index d7c45a9c15..adcd6131df 100644
--- a/net/ipv6/netfilter/Kconfig
+++ b/net/ipv6/netfilter/Kconfig
@@ -6,8 +6,8 @@ menu "IPv6: Netfilter Configuration (EXPERIMENTAL)"
6 depends on INET && IPV6 && NETFILTER && EXPERIMENTAL 6 depends on INET && IPV6 && NETFILTER && EXPERIMENTAL
7 7
8config NF_CONNTRACK_IPV6 8config NF_CONNTRACK_IPV6
9 tristate "IPv6 support for new connection tracking (EXPERIMENTAL)" 9 tristate "IPv6 connection tracking support (EXPERIMENTAL)"
10 depends on EXPERIMENTAL && NF_CONNTRACK 10 depends on INET && IPV6 && EXPERIMENTAL && NF_CONNTRACK
11 ---help--- 11 ---help---
12 Connection tracking keeps a record of what packets have passed 12 Connection tracking keeps a record of what packets have passed
13 through your machine, in order to figure out how they are related 13 through your machine, in order to figure out how they are related
@@ -21,6 +21,7 @@ config NF_CONNTRACK_IPV6
21 21
22config IP6_NF_QUEUE 22config IP6_NF_QUEUE
23 tristate "IP6 Userspace queueing via NETLINK (OBSOLETE)" 23 tristate "IP6 Userspace queueing via NETLINK (OBSOLETE)"
24 depends on INET && IPV6 && NETFILTER && EXPERIMENTAL
24 ---help--- 25 ---help---
25 26
26 This option adds a queue handler to the kernel for IPv6 27 This option adds a queue handler to the kernel for IPv6
@@ -41,7 +42,7 @@ config IP6_NF_QUEUE
41 42
42config IP6_NF_IPTABLES 43config IP6_NF_IPTABLES
43 tristate "IP6 tables support (required for filtering)" 44 tristate "IP6 tables support (required for filtering)"
44 depends on NETFILTER_XTABLES 45 depends on INET && IPV6 && EXPERIMENTAL && NETFILTER_XTABLES
45 help 46 help
46 ip6tables is a general, extensible packet identification framework. 47 ip6tables is a general, extensible packet identification framework.
47 Currently only the packet filtering and packet mangling subsystem 48 Currently only the packet filtering and packet mangling subsystem
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index 9fec832ee0..d4d9f18244 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -241,7 +241,7 @@ ipq_build_packet_message(struct ipq_queue_entry *entry, int *errp)
241 pmsg->data_len = data_len; 241 pmsg->data_len = data_len;
242 pmsg->timestamp_sec = entry->skb->tstamp.off_sec; 242 pmsg->timestamp_sec = entry->skb->tstamp.off_sec;
243 pmsg->timestamp_usec = entry->skb->tstamp.off_usec; 243 pmsg->timestamp_usec = entry->skb->tstamp.off_usec;
244 pmsg->mark = entry->skb->nfmark; 244 pmsg->mark = entry->skb->mark;
245 pmsg->hook = entry->info->hook; 245 pmsg->hook = entry->info->hook;
246 pmsg->hw_protocol = entry->skb->protocol; 246 pmsg->hw_protocol = entry->skb->protocol;
247 247
@@ -620,6 +620,7 @@ static ctl_table ipq_root_table[] = {
620 { .ctl_name = 0 } 620 { .ctl_name = 0 }
621}; 621};
622 622
623#ifdef CONFIG_PROC_FS
623static int 624static int
624ipq_get_info(char *buffer, char **start, off_t offset, int length) 625ipq_get_info(char *buffer, char **start, off_t offset, int length)
625{ 626{
@@ -653,6 +654,7 @@ ipq_get_info(char *buffer, char **start, off_t offset, int length)
653 len = 0; 654 len = 0;
654 return len; 655 return len;
655} 656}
657#endif /* CONFIG_PROC_FS */
656 658
657static struct nf_queue_handler nfqh = { 659static struct nf_queue_handler nfqh = {
658 .name = "ip6_queue", 660 .name = "ip6_queue",
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 204e02162d..99502c5da4 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -413,6 +413,7 @@ mark_source_chains(struct xt_table_info *newinfo,
413 unsigned int pos = newinfo->hook_entry[hook]; 413 unsigned int pos = newinfo->hook_entry[hook];
414 struct ip6t_entry *e 414 struct ip6t_entry *e
415 = (struct ip6t_entry *)(entry0 + pos); 415 = (struct ip6t_entry *)(entry0 + pos);
416 int visited = e->comefrom & (1 << hook);
416 417
417 if (!(valid_hooks & (1 << hook))) 418 if (!(valid_hooks & (1 << hook)))
418 continue; 419 continue;
@@ -433,13 +434,20 @@ mark_source_chains(struct xt_table_info *newinfo,
433 |= ((1 << hook) | (1 << NF_IP6_NUMHOOKS)); 434 |= ((1 << hook) | (1 << NF_IP6_NUMHOOKS));
434 435
435 /* Unconditional return/END. */ 436 /* Unconditional return/END. */
436 if (e->target_offset == sizeof(struct ip6t_entry) 437 if ((e->target_offset == sizeof(struct ip6t_entry)
437 && (strcmp(t->target.u.user.name, 438 && (strcmp(t->target.u.user.name,
438 IP6T_STANDARD_TARGET) == 0) 439 IP6T_STANDARD_TARGET) == 0)
439 && t->verdict < 0 440 && t->verdict < 0
440 && unconditional(&e->ipv6)) { 441 && unconditional(&e->ipv6)) || visited) {
441 unsigned int oldpos, size; 442 unsigned int oldpos, size;
442 443
444 if (t->verdict < -NF_MAX_VERDICT - 1) {
445 duprintf("mark_source_chains: bad "
446 "negative verdict (%i)\n",
447 t->verdict);
448 return 0;
449 }
450
443 /* Return: backtrack through the last 451 /* Return: backtrack through the last
444 big jump. */ 452 big jump. */
445 do { 453 do {
@@ -477,6 +485,13 @@ mark_source_chains(struct xt_table_info *newinfo,
477 if (strcmp(t->target.u.user.name, 485 if (strcmp(t->target.u.user.name,
478 IP6T_STANDARD_TARGET) == 0 486 IP6T_STANDARD_TARGET) == 0
479 && newpos >= 0) { 487 && newpos >= 0) {
488 if (newpos > newinfo->size -
489 sizeof(struct ip6t_entry)) {
490 duprintf("mark_source_chains: "
491 "bad verdict (%i)\n",
492 newpos);
493 return 0;
494 }
480 /* This a jump; chase it. */ 495 /* This a jump; chase it. */
481 duprintf("Jump rule %u -> %u\n", 496 duprintf("Jump rule %u -> %u\n",
482 pos, newpos); 497 pos, newpos);
@@ -509,27 +524,6 @@ cleanup_match(struct ip6t_entry_match *m, unsigned int *i)
509} 524}
510 525
511static inline int 526static inline int
512standard_check(const struct ip6t_entry_target *t,
513 unsigned int max_offset)
514{
515 struct ip6t_standard_target *targ = (void *)t;
516
517 /* Check standard info. */
518 if (targ->verdict >= 0
519 && targ->verdict > max_offset - sizeof(struct ip6t_entry)) {
520 duprintf("ip6t_standard_check: bad verdict (%i)\n",
521 targ->verdict);
522 return 0;
523 }
524 if (targ->verdict < -NF_MAX_VERDICT - 1) {
525 duprintf("ip6t_standard_check: bad negative verdict (%i)\n",
526 targ->verdict);
527 return 0;
528 }
529 return 1;
530}
531
532static inline int
533check_match(struct ip6t_entry_match *m, 527check_match(struct ip6t_entry_match *m,
534 const char *name, 528 const char *name,
535 const struct ip6t_ip6 *ipv6, 529 const struct ip6t_ip6 *ipv6,
@@ -616,12 +610,7 @@ check_entry(struct ip6t_entry *e, const char *name, unsigned int size,
616 if (ret) 610 if (ret)
617 goto err; 611 goto err;
618 612
619 if (t->u.kernel.target == &ip6t_standard_target) { 613 if (t->u.kernel.target->checkentry
620 if (!standard_check(t, size)) {
621 ret = -EINVAL;
622 goto err;
623 }
624 } else if (t->u.kernel.target->checkentry
625 && !t->u.kernel.target->checkentry(name, e, target, t->data, 614 && !t->u.kernel.target->checkentry(name, e, target, t->data,
626 e->comefrom)) { 615 e->comefrom)) {
627 duprintf("ip_tables: check failed for `%s'.\n", 616 duprintf("ip_tables: check failed for `%s'.\n",
@@ -758,17 +747,19 @@ translate_table(const char *name,
758 } 747 }
759 } 748 }
760 749
750 if (!mark_source_chains(newinfo, valid_hooks, entry0))
751 return -ELOOP;
752
761 /* Finally, each sanity check must pass */ 753 /* Finally, each sanity check must pass */
762 i = 0; 754 i = 0;
763 ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size, 755 ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size,
764 check_entry, name, size, &i); 756 check_entry, name, size, &i);
765 757
766 if (ret != 0) 758 if (ret != 0) {
767 goto cleanup; 759 IP6T_ENTRY_ITERATE(entry0, newinfo->size,
768 760 cleanup_entry, &i);
769 ret = -ELOOP; 761 return ret;
770 if (!mark_source_chains(newinfo, valid_hooks, entry0)) 762 }
771 goto cleanup;
772 763
773 /* And one copy for every other CPU */ 764 /* And one copy for every other CPU */
774 for_each_possible_cpu(i) { 765 for_each_possible_cpu(i) {
@@ -777,9 +768,6 @@ translate_table(const char *name,
777 } 768 }
778 769
779 return 0; 770 return 0;
780cleanup:
781 IP6T_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i);
782 return ret;
783} 771}
784 772
785/* Gets counters. */ 773/* Gets counters. */
@@ -1481,7 +1469,8 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,
1481 if (hp == NULL) 1469 if (hp == NULL)
1482 return -EBADMSG; 1470 return -EBADMSG;
1483 if (nexthdr == NEXTHDR_FRAGMENT) { 1471 if (nexthdr == NEXTHDR_FRAGMENT) {
1484 unsigned short _frag_off, *fp; 1472 unsigned short _frag_off;
1473 __be16 *fp;
1485 fp = skb_header_pointer(skb, 1474 fp = skb_header_pointer(skb,
1486 start+offsetof(struct frag_hdr, 1475 start+offsetof(struct frag_hdr,
1487 frag_off), 1476 frag_off),
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
index 0cf537d301..33b1faa90d 100644
--- a/net/ipv6/netfilter/ip6t_LOG.c
+++ b/net/ipv6/netfilter/ip6t_LOG.c
@@ -69,9 +69,9 @@ static void dump_packet(const struct nf_loginfo *info,
69 /* Max length: 44 "LEN=65535 TC=255 HOPLIMIT=255 FLOWLBL=FFFFF " */ 69 /* Max length: 44 "LEN=65535 TC=255 HOPLIMIT=255 FLOWLBL=FFFFF " */
70 printk("LEN=%Zu TC=%u HOPLIMIT=%u FLOWLBL=%u ", 70 printk("LEN=%Zu TC=%u HOPLIMIT=%u FLOWLBL=%u ",
71 ntohs(ih->payload_len) + sizeof(struct ipv6hdr), 71 ntohs(ih->payload_len) + sizeof(struct ipv6hdr),
72 (ntohl(*(u_int32_t *)ih) & 0x0ff00000) >> 20, 72 (ntohl(*(__be32 *)ih) & 0x0ff00000) >> 20,
73 ih->hop_limit, 73 ih->hop_limit,
74 (ntohl(*(u_int32_t *)ih) & 0x000fffff)); 74 (ntohl(*(__be32 *)ih) & 0x000fffff));
75 75
76 fragment = 0; 76 fragment = 0;
77 ptr = ip6hoff + sizeof(struct ipv6hdr); 77 ptr = ip6hoff + sizeof(struct ipv6hdr);
@@ -270,11 +270,15 @@ static void dump_packet(const struct nf_loginfo *info,
270 } 270 }
271 break; 271 break;
272 } 272 }
273 case IPPROTO_UDP: { 273 case IPPROTO_UDP:
274 case IPPROTO_UDPLITE: {
274 struct udphdr _udph, *uh; 275 struct udphdr _udph, *uh;
275 276
276 /* Max length: 10 "PROTO=UDP " */ 277 if (currenthdr == IPPROTO_UDP)
277 printk("PROTO=UDP "); 278 /* Max length: 10 "PROTO=UDP " */
279 printk("PROTO=UDP " );
280 else /* Max length: 14 "PROTO=UDPLITE " */
281 printk("PROTO=UDPLITE ");
278 282
279 if (fragment) 283 if (fragment)
280 break; 284 break;
@@ -436,13 +440,8 @@ ip6t_log_target(struct sk_buff **pskb,
436 li.u.log.level = loginfo->level; 440 li.u.log.level = loginfo->level;
437 li.u.log.logflags = loginfo->logflags; 441 li.u.log.logflags = loginfo->logflags;
438 442
439 if (loginfo->logflags & IP6T_LOG_NFLOG) 443 ip6t_log_packet(PF_INET6, hooknum, *pskb, in, out, &li,
440 nf_log_packet(PF_INET6, hooknum, *pskb, in, out, &li, 444 loginfo->prefix);
441 "%s", loginfo->prefix);
442 else
443 ip6t_log_packet(PF_INET6, hooknum, *pskb, in, out, &li,
444 loginfo->prefix);
445
446 return IP6T_CONTINUE; 445 return IP6T_CONTINUE;
447} 446}
448 447
diff --git a/net/ipv6/netfilter/ip6table_mangle.c b/net/ipv6/netfilter/ip6table_mangle.c
index 386ea260e7..6250e86a6d 100644
--- a/net/ipv6/netfilter/ip6table_mangle.c
+++ b/net/ipv6/netfilter/ip6table_mangle.c
@@ -149,11 +149,10 @@ ip6t_local_hook(unsigned int hook,
149 int (*okfn)(struct sk_buff *)) 149 int (*okfn)(struct sk_buff *))
150{ 150{
151 151
152 unsigned long nfmark;
153 unsigned int ret; 152 unsigned int ret;
154 struct in6_addr saddr, daddr; 153 struct in6_addr saddr, daddr;
155 u_int8_t hop_limit; 154 u_int8_t hop_limit;
156 u_int32_t flowlabel; 155 u_int32_t flowlabel, mark;
157 156
158#if 0 157#if 0
159 /* root is playing with raw sockets. */ 158 /* root is playing with raw sockets. */
@@ -165,10 +164,10 @@ ip6t_local_hook(unsigned int hook,
165 } 164 }
166#endif 165#endif
167 166
168 /* save source/dest address, nfmark, hoplimit, flowlabel, priority, */ 167 /* save source/dest address, mark, hoplimit, flowlabel, priority, */
169 memcpy(&saddr, &(*pskb)->nh.ipv6h->saddr, sizeof(saddr)); 168 memcpy(&saddr, &(*pskb)->nh.ipv6h->saddr, sizeof(saddr));
170 memcpy(&daddr, &(*pskb)->nh.ipv6h->daddr, sizeof(daddr)); 169 memcpy(&daddr, &(*pskb)->nh.ipv6h->daddr, sizeof(daddr));
171 nfmark = (*pskb)->nfmark; 170 mark = (*pskb)->mark;
172 hop_limit = (*pskb)->nh.ipv6h->hop_limit; 171 hop_limit = (*pskb)->nh.ipv6h->hop_limit;
173 172
174 /* flowlabel and prio (includes version, which shouldn't change either */ 173 /* flowlabel and prio (includes version, which shouldn't change either */
@@ -179,7 +178,7 @@ ip6t_local_hook(unsigned int hook,
179 if (ret != NF_DROP && ret != NF_STOLEN 178 if (ret != NF_DROP && ret != NF_STOLEN
180 && (memcmp(&(*pskb)->nh.ipv6h->saddr, &saddr, sizeof(saddr)) 179 && (memcmp(&(*pskb)->nh.ipv6h->saddr, &saddr, sizeof(saddr))
181 || memcmp(&(*pskb)->nh.ipv6h->daddr, &daddr, sizeof(daddr)) 180 || memcmp(&(*pskb)->nh.ipv6h->daddr, &daddr, sizeof(daddr))
182 || (*pskb)->nfmark != nfmark 181 || (*pskb)->mark != mark
183 || (*pskb)->nh.ipv6h->hop_limit != hop_limit)) 182 || (*pskb)->nh.ipv6h->hop_limit != hop_limit))
184 return ip6_route_me_harder(*pskb) == 0 ? ret : NF_DROP; 183 return ip6_route_me_harder(*pskb) == 0 ? ret : NF_DROP;
185 184
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index e5e53fff9e..a20615ffcc 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -33,7 +33,7 @@
33#include <linux/netfilter_ipv6.h> 33#include <linux/netfilter_ipv6.h>
34#include <net/netfilter/nf_conntrack.h> 34#include <net/netfilter/nf_conntrack.h>
35#include <net/netfilter/nf_conntrack_helper.h> 35#include <net/netfilter/nf_conntrack_helper.h>
36#include <net/netfilter/nf_conntrack_protocol.h> 36#include <net/netfilter/nf_conntrack_l4proto.h>
37#include <net/netfilter/nf_conntrack_l3proto.h> 37#include <net/netfilter/nf_conntrack_l3proto.h>
38#include <net/netfilter/nf_conntrack_core.h> 38#include <net/netfilter/nf_conntrack_core.h>
39 39
@@ -43,8 +43,6 @@
43#define DEBUGP(format, args...) 43#define DEBUGP(format, args...)
44#endif 44#endif
45 45
46DECLARE_PER_CPU(struct ip_conntrack_stat, nf_conntrack_stat);
47
48static int ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff, 46static int ipv6_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
49 struct nf_conntrack_tuple *tuple) 47 struct nf_conntrack_tuple *tuple)
50{ 48{
@@ -211,11 +209,6 @@ out:
211 return nf_conntrack_confirm(pskb); 209 return nf_conntrack_confirm(pskb);
212} 210}
213 211
214extern struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb);
215extern void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
216 struct net_device *in,
217 struct net_device *out,
218 int (*okfn)(struct sk_buff *));
219static unsigned int ipv6_defrag(unsigned int hooknum, 212static unsigned int ipv6_defrag(unsigned int hooknum,
220 struct sk_buff **pskb, 213 struct sk_buff **pskb,
221 const struct net_device *in, 214 const struct net_device *in,
@@ -331,26 +324,7 @@ static struct nf_hook_ops ipv6_conntrack_ops[] = {
331}; 324};
332 325
333#ifdef CONFIG_SYSCTL 326#ifdef CONFIG_SYSCTL
334 327static ctl_table nf_ct_ipv6_sysctl_table[] = {
335/* From nf_conntrack_proto_icmpv6.c */
336extern unsigned int nf_ct_icmpv6_timeout;
337
338/* From nf_conntrack_reasm.c */
339extern unsigned int nf_ct_frag6_timeout;
340extern unsigned int nf_ct_frag6_low_thresh;
341extern unsigned int nf_ct_frag6_high_thresh;
342
343static struct ctl_table_header *nf_ct_ipv6_sysctl_header;
344
345static ctl_table nf_ct_sysctl_table[] = {
346 {
347 .ctl_name = NET_NF_CONNTRACK_ICMPV6_TIMEOUT,
348 .procname = "nf_conntrack_icmpv6_timeout",
349 .data = &nf_ct_icmpv6_timeout,
350 .maxlen = sizeof(unsigned int),
351 .mode = 0644,
352 .proc_handler = &proc_dointvec_jiffies,
353 },
354 { 328 {
355 .ctl_name = NET_NF_CONNTRACK_FRAG6_TIMEOUT, 329 .ctl_name = NET_NF_CONNTRACK_FRAG6_TIMEOUT,
356 .procname = "nf_conntrack_frag6_timeout", 330 .procname = "nf_conntrack_frag6_timeout",
@@ -377,26 +351,6 @@ static ctl_table nf_ct_sysctl_table[] = {
377 }, 351 },
378 { .ctl_name = 0 } 352 { .ctl_name = 0 }
379}; 353};
380
381static ctl_table nf_ct_netfilter_table[] = {
382 {
383 .ctl_name = NET_NETFILTER,
384 .procname = "netfilter",
385 .mode = 0555,
386 .child = nf_ct_sysctl_table,
387 },
388 { .ctl_name = 0 }
389};
390
391static ctl_table nf_ct_net_table[] = {
392 {
393 .ctl_name = CTL_NET,
394 .procname = "net",
395 .mode = 0555,
396 .child = nf_ct_netfilter_table,
397 },
398 { .ctl_name = 0 }
399};
400#endif 354#endif
401 355
402#if defined(CONFIG_NF_CT_NETLINK) || \ 356#if defined(CONFIG_NF_CT_NETLINK) || \
@@ -454,16 +408,14 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6 = {
454 .tuple_to_nfattr = ipv6_tuple_to_nfattr, 408 .tuple_to_nfattr = ipv6_tuple_to_nfattr,
455 .nfattr_to_tuple = ipv6_nfattr_to_tuple, 409 .nfattr_to_tuple = ipv6_nfattr_to_tuple,
456#endif 410#endif
411#ifdef CONFIG_SYSCTL
412 .ctl_table_path = nf_net_netfilter_sysctl_path,
413 .ctl_table = nf_ct_ipv6_sysctl_table,
414#endif
457 .get_features = ipv6_get_features, 415 .get_features = ipv6_get_features,
458 .me = THIS_MODULE, 416 .me = THIS_MODULE,
459}; 417};
460 418
461extern struct nf_conntrack_protocol nf_conntrack_protocol_tcp6;
462extern struct nf_conntrack_protocol nf_conntrack_protocol_udp6;
463extern struct nf_conntrack_protocol nf_conntrack_protocol_icmpv6;
464extern int nf_ct_frag6_init(void);
465extern void nf_ct_frag6_cleanup(void);
466
467MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET6)); 419MODULE_ALIAS("nf_conntrack-" __stringify(AF_INET6));
468MODULE_LICENSE("GPL"); 420MODULE_LICENSE("GPL");
469MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI <yasuyuki.kozakai@toshiba.co.jp>"); 421MODULE_AUTHOR("Yasuyuki KOZAKAI @USAGI <yasuyuki.kozakai@toshiba.co.jp>");
@@ -479,19 +431,19 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
479 printk("nf_conntrack_ipv6: can't initialize frag6.\n"); 431 printk("nf_conntrack_ipv6: can't initialize frag6.\n");
480 return ret; 432 return ret;
481 } 433 }
482 ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_tcp6); 434 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_tcp6);
483 if (ret < 0) { 435 if (ret < 0) {
484 printk("nf_conntrack_ipv6: can't register tcp.\n"); 436 printk("nf_conntrack_ipv6: can't register tcp.\n");
485 goto cleanup_frag6; 437 goto cleanup_frag6;
486 } 438 }
487 439
488 ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_udp6); 440 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_udp6);
489 if (ret < 0) { 441 if (ret < 0) {
490 printk("nf_conntrack_ipv6: can't register udp.\n"); 442 printk("nf_conntrack_ipv6: can't register udp.\n");
491 goto cleanup_tcp; 443 goto cleanup_tcp;
492 } 444 }
493 445
494 ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_icmpv6); 446 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_icmpv6);
495 if (ret < 0) { 447 if (ret < 0) {
496 printk("nf_conntrack_ipv6: can't register icmpv6.\n"); 448 printk("nf_conntrack_ipv6: can't register icmpv6.\n");
497 goto cleanup_udp; 449 goto cleanup_udp;
@@ -510,28 +462,16 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
510 "hook.\n"); 462 "hook.\n");
511 goto cleanup_ipv6; 463 goto cleanup_ipv6;
512 } 464 }
513#ifdef CONFIG_SYSCTL
514 nf_ct_ipv6_sysctl_header = register_sysctl_table(nf_ct_net_table, 0);
515 if (nf_ct_ipv6_sysctl_header == NULL) {
516 printk("nf_conntrack: can't register to sysctl.\n");
517 ret = -ENOMEM;
518 goto cleanup_hooks;
519 }
520#endif
521 return ret; 465 return ret;
522 466
523#ifdef CONFIG_SYSCTL
524 cleanup_hooks:
525 nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops));
526#endif
527 cleanup_ipv6: 467 cleanup_ipv6:
528 nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6); 468 nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6);
529 cleanup_icmpv6: 469 cleanup_icmpv6:
530 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_icmpv6); 470 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmpv6);
531 cleanup_udp: 471 cleanup_udp:
532 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_udp6); 472 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6);
533 cleanup_tcp: 473 cleanup_tcp:
534 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_tcp6); 474 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6);
535 cleanup_frag6: 475 cleanup_frag6:
536 nf_ct_frag6_cleanup(); 476 nf_ct_frag6_cleanup();
537 return ret; 477 return ret;
@@ -540,14 +480,11 @@ static int __init nf_conntrack_l3proto_ipv6_init(void)
540static void __exit nf_conntrack_l3proto_ipv6_fini(void) 480static void __exit nf_conntrack_l3proto_ipv6_fini(void)
541{ 481{
542 synchronize_net(); 482 synchronize_net();
543#ifdef CONFIG_SYSCTL
544 unregister_sysctl_table(nf_ct_ipv6_sysctl_header);
545#endif
546 nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops)); 483 nf_unregister_hooks(ipv6_conntrack_ops, ARRAY_SIZE(ipv6_conntrack_ops));
547 nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6); 484 nf_conntrack_l3proto_unregister(&nf_conntrack_l3proto_ipv6);
548 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_icmpv6); 485 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_icmpv6);
549 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_udp6); 486 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_udp6);
550 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_tcp6); 487 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_tcp6);
551 nf_ct_frag6_cleanup(); 488 nf_ct_frag6_cleanup();
552} 489}
553 490
diff --git a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
index 34d447208f..3905cacc69 100644
--- a/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_proto_icmpv6.c
@@ -29,11 +29,11 @@
29#include <linux/seq_file.h> 29#include <linux/seq_file.h>
30#include <linux/netfilter_ipv6.h> 30#include <linux/netfilter_ipv6.h>
31#include <net/netfilter/nf_conntrack_tuple.h> 31#include <net/netfilter/nf_conntrack_tuple.h>
32#include <net/netfilter/nf_conntrack_protocol.h> 32#include <net/netfilter/nf_conntrack_l4proto.h>
33#include <net/netfilter/nf_conntrack_core.h> 33#include <net/netfilter/nf_conntrack_core.h>
34#include <net/netfilter/ipv6/nf_conntrack_icmpv6.h> 34#include <net/netfilter/ipv6/nf_conntrack_icmpv6.h>
35 35
36unsigned long nf_ct_icmpv6_timeout __read_mostly = 30*HZ; 36static unsigned long nf_ct_icmpv6_timeout __read_mostly = 30*HZ;
37 37
38#if 0 38#if 0
39#define DEBUGP printk 39#define DEBUGP printk
@@ -142,9 +142,6 @@ static int icmpv6_new(struct nf_conn *conntrack,
142 return 1; 142 return 1;
143} 143}
144 144
145extern int
146nf_ct_ipv6_skip_exthdr(struct sk_buff *skb, int start, u8 *nexthdrp, int len);
147extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6;
148static int 145static int
149icmpv6_error_message(struct sk_buff *skb, 146icmpv6_error_message(struct sk_buff *skb,
150 unsigned int icmp6off, 147 unsigned int icmp6off,
@@ -155,7 +152,7 @@ icmpv6_error_message(struct sk_buff *skb,
155 struct nf_conntrack_tuple_hash *h; 152 struct nf_conntrack_tuple_hash *h;
156 struct icmp6hdr _hdr, *hp; 153 struct icmp6hdr _hdr, *hp;
157 unsigned int inip6off; 154 unsigned int inip6off;
158 struct nf_conntrack_protocol *inproto; 155 struct nf_conntrack_l4proto *inproto;
159 u_int8_t inprotonum; 156 u_int8_t inprotonum;
160 unsigned int inprotoff; 157 unsigned int inprotoff;
161 158
@@ -185,7 +182,7 @@ icmpv6_error_message(struct sk_buff *skb,
185 return -NF_ACCEPT; 182 return -NF_ACCEPT;
186 } 183 }
187 184
188 inproto = __nf_ct_proto_find(PF_INET6, inprotonum); 185 inproto = __nf_ct_l4proto_find(PF_INET6, inprotonum);
189 186
190 /* Are they talking about one of our connections? */ 187 /* Are they talking about one of our connections? */
191 if (!nf_ct_get_tuple(skb, inip6off, inprotoff, PF_INET6, inprotonum, 188 if (!nf_ct_get_tuple(skb, inip6off, inprotoff, PF_INET6, inprotonum,
@@ -290,7 +287,7 @@ static int icmpv6_nfattr_to_tuple(struct nfattr *tb[],
290 tuple->dst.u.icmp.code = 287 tuple->dst.u.icmp.code =
291 *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMPV6_CODE-1]); 288 *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_ICMPV6_CODE-1]);
292 tuple->src.u.icmp.id = 289 tuple->src.u.icmp.id =
293 *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_ICMPV6_ID-1]); 290 *(__be16 *)NFA_DATA(tb[CTA_PROTO_ICMPV6_ID-1]);
294 291
295 if (tuple->dst.u.icmp.type < 128 292 if (tuple->dst.u.icmp.type < 128
296 || tuple->dst.u.icmp.type - 128 >= sizeof(invmap) 293 || tuple->dst.u.icmp.type - 128 >= sizeof(invmap)
@@ -301,10 +298,27 @@ static int icmpv6_nfattr_to_tuple(struct nfattr *tb[],
301} 298}
302#endif 299#endif
303 300
304struct nf_conntrack_protocol nf_conntrack_protocol_icmpv6 = 301#ifdef CONFIG_SYSCTL
302static struct ctl_table_header *icmpv6_sysctl_header;
303static struct ctl_table icmpv6_sysctl_table[] = {
304 {
305 .ctl_name = NET_NF_CONNTRACK_ICMPV6_TIMEOUT,
306 .procname = "nf_conntrack_icmpv6_timeout",
307 .data = &nf_ct_icmpv6_timeout,
308 .maxlen = sizeof(unsigned int),
309 .mode = 0644,
310 .proc_handler = &proc_dointvec_jiffies,
311 },
312 {
313 .ctl_name = 0
314 }
315};
316#endif /* CONFIG_SYSCTL */
317
318struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6 =
305{ 319{
306 .l3proto = PF_INET6, 320 .l3proto = PF_INET6,
307 .proto = IPPROTO_ICMPV6, 321 .l4proto = IPPROTO_ICMPV6,
308 .name = "icmpv6", 322 .name = "icmpv6",
309 .pkt_to_tuple = icmpv6_pkt_to_tuple, 323 .pkt_to_tuple = icmpv6_pkt_to_tuple,
310 .invert_tuple = icmpv6_invert_tuple, 324 .invert_tuple = icmpv6_invert_tuple,
@@ -318,6 +332,10 @@ struct nf_conntrack_protocol nf_conntrack_protocol_icmpv6 =
318 .tuple_to_nfattr = icmpv6_tuple_to_nfattr, 332 .tuple_to_nfattr = icmpv6_tuple_to_nfattr,
319 .nfattr_to_tuple = icmpv6_nfattr_to_tuple, 333 .nfattr_to_tuple = icmpv6_nfattr_to_tuple,
320#endif 334#endif
335#ifdef CONFIG_SYSCTL
336 .ctl_table_header = &icmpv6_sysctl_header,
337 .ctl_table = icmpv6_sysctl_table,
338#endif
321}; 339};
322 340
323EXPORT_SYMBOL(nf_conntrack_protocol_icmpv6); 341EXPORT_SYMBOL(nf_conntrack_l4proto_icmpv6);
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index bf93c1ea6b..d9c15402ba 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -72,7 +72,7 @@ struct nf_ct_frag6_queue
72 struct hlist_node list; 72 struct hlist_node list;
73 struct list_head lru_list; /* lru list member */ 73 struct list_head lru_list; /* lru list member */
74 74
75 __u32 id; /* fragment id */ 75 __be32 id; /* fragment id */
76 struct in6_addr saddr; 76 struct in6_addr saddr;
77 struct in6_addr daddr; 77 struct in6_addr daddr;
78 78
@@ -115,28 +115,28 @@ static __inline__ void fq_unlink(struct nf_ct_frag6_queue *fq)
115 write_unlock(&nf_ct_frag6_lock); 115 write_unlock(&nf_ct_frag6_lock);
116} 116}
117 117
118static unsigned int ip6qhashfn(u32 id, struct in6_addr *saddr, 118static unsigned int ip6qhashfn(__be32 id, struct in6_addr *saddr,
119 struct in6_addr *daddr) 119 struct in6_addr *daddr)
120{ 120{
121 u32 a, b, c; 121 u32 a, b, c;
122 122
123 a = saddr->s6_addr32[0]; 123 a = (__force u32)saddr->s6_addr32[0];
124 b = saddr->s6_addr32[1]; 124 b = (__force u32)saddr->s6_addr32[1];
125 c = saddr->s6_addr32[2]; 125 c = (__force u32)saddr->s6_addr32[2];
126 126
127 a += JHASH_GOLDEN_RATIO; 127 a += JHASH_GOLDEN_RATIO;
128 b += JHASH_GOLDEN_RATIO; 128 b += JHASH_GOLDEN_RATIO;
129 c += nf_ct_frag6_hash_rnd; 129 c += nf_ct_frag6_hash_rnd;
130 __jhash_mix(a, b, c); 130 __jhash_mix(a, b, c);
131 131
132 a += saddr->s6_addr32[3]; 132 a += (__force u32)saddr->s6_addr32[3];
133 b += daddr->s6_addr32[0]; 133 b += (__force u32)daddr->s6_addr32[0];
134 c += daddr->s6_addr32[1]; 134 c += (__force u32)daddr->s6_addr32[1];
135 __jhash_mix(a, b, c); 135 __jhash_mix(a, b, c);
136 136
137 a += daddr->s6_addr32[2]; 137 a += (__force u32)daddr->s6_addr32[2];
138 b += daddr->s6_addr32[3]; 138 b += (__force u32)daddr->s6_addr32[3];
139 c += id; 139 c += (__force u32)id;
140 __jhash_mix(a, b, c); 140 __jhash_mix(a, b, c);
141 141
142 return c & (FRAG6Q_HASHSZ - 1); 142 return c & (FRAG6Q_HASHSZ - 1);
@@ -338,7 +338,7 @@ static struct nf_ct_frag6_queue *nf_ct_frag6_intern(unsigned int hash,
338 338
339 339
340static struct nf_ct_frag6_queue * 340static struct nf_ct_frag6_queue *
341nf_ct_frag6_create(unsigned int hash, u32 id, struct in6_addr *src, struct in6_addr *dst) 341nf_ct_frag6_create(unsigned int hash, __be32 id, struct in6_addr *src, struct in6_addr *dst)
342{ 342{
343 struct nf_ct_frag6_queue *fq; 343 struct nf_ct_frag6_queue *fq;
344 344
@@ -366,7 +366,7 @@ oom:
366} 366}
367 367
368static __inline__ struct nf_ct_frag6_queue * 368static __inline__ struct nf_ct_frag6_queue *
369fq_find(u32 id, struct in6_addr *src, struct in6_addr *dst) 369fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst)
370{ 370{
371 struct nf_ct_frag6_queue *fq; 371 struct nf_ct_frag6_queue *fq;
372 struct hlist_node *n; 372 struct hlist_node *n;
@@ -835,6 +835,8 @@ void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
835 s->nfct_reasm = skb; 835 s->nfct_reasm = skb;
836 836
837 s2 = s->next; 837 s2 = s->next;
838 s->next = NULL;
839
838 NF_HOOK_THRESH(PF_INET6, hooknum, s, in, out, okfn, 840 NF_HOOK_THRESH(PF_INET6, hooknum, s, in, out, okfn,
839 NF_IP6_PRI_CONNTRACK_DEFRAG + 1); 841 NF_IP6_PRI_CONNTRACK_DEFRAG + 1);
840 s = s2; 842 s = s2;
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index efee7a6301..35249d8487 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -49,6 +49,8 @@ static int sockstat6_seq_show(struct seq_file *seq, void *v)
49 fold_prot_inuse(&tcpv6_prot)); 49 fold_prot_inuse(&tcpv6_prot));
50 seq_printf(seq, "UDP6: inuse %d\n", 50 seq_printf(seq, "UDP6: inuse %d\n",
51 fold_prot_inuse(&udpv6_prot)); 51 fold_prot_inuse(&udpv6_prot));
52 seq_printf(seq, "UDPLITE6: inuse %d\n",
53 fold_prot_inuse(&udplitev6_prot));
52 seq_printf(seq, "RAW6: inuse %d\n", 54 seq_printf(seq, "RAW6: inuse %d\n",
53 fold_prot_inuse(&rawv6_prot)); 55 fold_prot_inuse(&rawv6_prot));
54 seq_printf(seq, "FRAG6: inuse %d memory %d\n", 56 seq_printf(seq, "FRAG6: inuse %d memory %d\n",
@@ -133,6 +135,14 @@ static struct snmp_mib snmp6_udp6_list[] = {
133 SNMP_MIB_SENTINEL 135 SNMP_MIB_SENTINEL
134}; 136};
135 137
138static struct snmp_mib snmp6_udplite6_list[] = {
139 SNMP_MIB_ITEM("UdpLite6InDatagrams", UDP_MIB_INDATAGRAMS),
140 SNMP_MIB_ITEM("UdpLite6NoPorts", UDP_MIB_NOPORTS),
141 SNMP_MIB_ITEM("UdpLite6InErrors", UDP_MIB_INERRORS),
142 SNMP_MIB_ITEM("UdpLite6OutDatagrams", UDP_MIB_OUTDATAGRAMS),
143 SNMP_MIB_SENTINEL
144};
145
136static unsigned long 146static unsigned long
137fold_field(void *mib[], int offt) 147fold_field(void *mib[], int offt)
138{ 148{
@@ -161,11 +171,13 @@ static int snmp6_seq_show(struct seq_file *seq, void *v)
161 171
162 if (idev) { 172 if (idev) {
163 seq_printf(seq, "%-32s\t%u\n", "ifIndex", idev->dev->ifindex); 173 seq_printf(seq, "%-32s\t%u\n", "ifIndex", idev->dev->ifindex);
174 snmp6_seq_show_item(seq, (void **)idev->stats.ipv6, snmp6_ipstats_list);
164 snmp6_seq_show_item(seq, (void **)idev->stats.icmpv6, snmp6_icmp6_list); 175 snmp6_seq_show_item(seq, (void **)idev->stats.icmpv6, snmp6_icmp6_list);
165 } else { 176 } else {
166 snmp6_seq_show_item(seq, (void **)ipv6_statistics, snmp6_ipstats_list); 177 snmp6_seq_show_item(seq, (void **)ipv6_statistics, snmp6_ipstats_list);
167 snmp6_seq_show_item(seq, (void **)icmpv6_statistics, snmp6_icmp6_list); 178 snmp6_seq_show_item(seq, (void **)icmpv6_statistics, snmp6_icmp6_list);
168 snmp6_seq_show_item(seq, (void **)udp_stats_in6, snmp6_udp6_list); 179 snmp6_seq_show_item(seq, (void **)udp_stats_in6, snmp6_udp6_list);
180 snmp6_seq_show_item(seq, (void **)udplite_stats_in6, snmp6_udplite6_list);
169 } 181 }
170 return 0; 182 return 0;
171} 183}
@@ -281,6 +293,9 @@ int snmp6_alloc_dev(struct inet6_dev *idev)
281 if (!idev || !idev->dev) 293 if (!idev || !idev->dev)
282 return -EINVAL; 294 return -EINVAL;
283 295
296 if (snmp6_mib_init((void **)idev->stats.ipv6, sizeof(struct ipstats_mib),
297 __alignof__(struct ipstats_mib)) < 0)
298 goto err_ip;
284 if (snmp6_mib_init((void **)idev->stats.icmpv6, sizeof(struct icmpv6_mib), 299 if (snmp6_mib_init((void **)idev->stats.icmpv6, sizeof(struct icmpv6_mib),
285 __alignof__(struct icmpv6_mib)) < 0) 300 __alignof__(struct icmpv6_mib)) < 0)
286 goto err_icmp; 301 goto err_icmp;
@@ -288,12 +303,15 @@ int snmp6_alloc_dev(struct inet6_dev *idev)
288 return 0; 303 return 0;
289 304
290err_icmp: 305err_icmp:
306 snmp6_mib_free((void **)idev->stats.ipv6);
307err_ip:
291 return err; 308 return err;
292} 309}
293 310
294int snmp6_free_dev(struct inet6_dev *idev) 311int snmp6_free_dev(struct inet6_dev *idev)
295{ 312{
296 snmp6_mib_free((void **)idev->stats.icmpv6); 313 snmp6_mib_free((void **)idev->stats.icmpv6);
314 snmp6_mib_free((void **)idev->stats.ipv6);
297 return 0; 315 return 0;
298} 316}
299 317
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index d6dedc4aec..4ae1b19ada 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -220,7 +220,7 @@ static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
220 struct inet_sock *inet = inet_sk(sk); 220 struct inet_sock *inet = inet_sk(sk);
221 struct ipv6_pinfo *np = inet6_sk(sk); 221 struct ipv6_pinfo *np = inet6_sk(sk);
222 struct sockaddr_in6 *addr = (struct sockaddr_in6 *) uaddr; 222 struct sockaddr_in6 *addr = (struct sockaddr_in6 *) uaddr;
223 __u32 v4addr = 0; 223 __be32 v4addr = 0;
224 int addr_type; 224 int addr_type;
225 int err; 225 int err;
226 226
@@ -290,7 +290,7 @@ out:
290 290
291void rawv6_err(struct sock *sk, struct sk_buff *skb, 291void rawv6_err(struct sock *sk, struct sk_buff *skb,
292 struct inet6_skb_parm *opt, 292 struct inet6_skb_parm *opt,
293 int type, int code, int offset, u32 info) 293 int type, int code, int offset, __be32 info)
294{ 294{
295 struct inet_sock *inet = inet_sk(sk); 295 struct inet_sock *inet = inet_sk(sk);
296 struct ipv6_pinfo *np = inet6_sk(sk); 296 struct ipv6_pinfo *np = inet6_sk(sk);
@@ -370,9 +370,9 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb)
370 skb->ip_summed = CHECKSUM_UNNECESSARY; 370 skb->ip_summed = CHECKSUM_UNNECESSARY;
371 } 371 }
372 if (skb->ip_summed != CHECKSUM_UNNECESSARY) 372 if (skb->ip_summed != CHECKSUM_UNNECESSARY)
373 skb->csum = ~csum_ipv6_magic(&skb->nh.ipv6h->saddr, 373 skb->csum = ~csum_unfold(csum_ipv6_magic(&skb->nh.ipv6h->saddr,
374 &skb->nh.ipv6h->daddr, 374 &skb->nh.ipv6h->daddr,
375 skb->len, inet->num, 0); 375 skb->len, inet->num, 0));
376 376
377 if (inet->hdrincl) { 377 if (inet->hdrincl) {
378 if (skb_checksum_complete(skb)) { 378 if (skb_checksum_complete(skb)) {
@@ -479,8 +479,8 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl,
479 int offset; 479 int offset;
480 int len; 480 int len;
481 int total_len; 481 int total_len;
482 u32 tmp_csum; 482 __wsum tmp_csum;
483 u16 csum; 483 __sum16 csum;
484 484
485 if (!rp->checksum) 485 if (!rp->checksum)
486 goto send; 486 goto send;
@@ -530,16 +530,15 @@ static int rawv6_push_pending_frames(struct sock *sk, struct flowi *fl,
530 530
531 /* in case cksum was not initialized */ 531 /* in case cksum was not initialized */
532 if (unlikely(csum)) 532 if (unlikely(csum))
533 tmp_csum = csum_sub(tmp_csum, csum); 533 tmp_csum = csum_sub(tmp_csum, csum_unfold(csum));
534 534
535 tmp_csum = csum_ipv6_magic(&fl->fl6_src, 535 csum = csum_ipv6_magic(&fl->fl6_src,
536 &fl->fl6_dst, 536 &fl->fl6_dst,
537 total_len, fl->proto, tmp_csum); 537 total_len, fl->proto, tmp_csum);
538 538
539 if (tmp_csum == 0) 539 if (csum == 0 && fl->proto == IPPROTO_UDP)
540 tmp_csum = -1; 540 csum = CSUM_MANGLED_0;
541 541
542 csum = tmp_csum;
543 if (skb_store_bits(skb, offset, &csum, 2)) 542 if (skb_store_bits(skb, offset, &csum, 2))
544 BUG(); 543 BUG();
545 544
@@ -586,7 +585,7 @@ static int rawv6_send_hdrinc(struct sock *sk, void *from, int length,
586 if (err) 585 if (err)
587 goto error_fault; 586 goto error_fault;
588 587
589 IP6_INC_STATS(IPSTATS_MIB_OUTREQUESTS); 588 IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS);
590 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, rt->u.dst.dev, 589 err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL, rt->u.dst.dev,
591 dst_output); 590 dst_output);
592 if (err > 0) 591 if (err > 0)
@@ -600,7 +599,7 @@ error_fault:
600 err = -EFAULT; 599 err = -EFAULT;
601 kfree_skb(skb); 600 kfree_skb(skb);
602error: 601error:
603 IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS); 602 IP6_INC_STATS(rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS);
604 return err; 603 return err;
605} 604}
606 605
@@ -855,7 +854,8 @@ back_from_confirm:
855 } 854 }
856done: 855done:
857 dst_release(dst); 856 dst_release(dst);
858 release_sock(sk); 857 if (!inet->hdrincl)
858 release_sock(sk);
859out: 859out:
860 fl6_sock_release(flowlabel); 860 fl6_sock_release(flowlabel);
861 return err<0?err:len; 861 return err<0?err:len;
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index f39bbedd13..6f9a904651 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -47,6 +47,7 @@
47#include <net/snmp.h> 47#include <net/snmp.h>
48 48
49#include <net/ipv6.h> 49#include <net/ipv6.h>
50#include <net/ip6_route.h>
50#include <net/protocol.h> 51#include <net/protocol.h>
51#include <net/transp_v6.h> 52#include <net/transp_v6.h>
52#include <net/rawv6.h> 53#include <net/rawv6.h>
@@ -76,7 +77,7 @@ struct frag_queue
76 struct hlist_node list; 77 struct hlist_node list;
77 struct list_head lru_list; /* lru list member */ 78 struct list_head lru_list; /* lru list member */
78 79
79 __u32 id; /* fragment id */ 80 __be32 id; /* fragment id */
80 struct in6_addr saddr; 81 struct in6_addr saddr;
81 struct in6_addr daddr; 82 struct in6_addr daddr;
82 83
@@ -124,28 +125,28 @@ static __inline__ void fq_unlink(struct frag_queue *fq)
124 * callers should be careful not to use the hash value outside the ipfrag_lock 125 * callers should be careful not to use the hash value outside the ipfrag_lock
125 * as doing so could race with ipfrag_hash_rnd being recalculated. 126 * as doing so could race with ipfrag_hash_rnd being recalculated.
126 */ 127 */
127static unsigned int ip6qhashfn(u32 id, struct in6_addr *saddr, 128static unsigned int ip6qhashfn(__be32 id, struct in6_addr *saddr,
128 struct in6_addr *daddr) 129 struct in6_addr *daddr)
129{ 130{
130 u32 a, b, c; 131 u32 a, b, c;
131 132
132 a = saddr->s6_addr32[0]; 133 a = (__force u32)saddr->s6_addr32[0];
133 b = saddr->s6_addr32[1]; 134 b = (__force u32)saddr->s6_addr32[1];
134 c = saddr->s6_addr32[2]; 135 c = (__force u32)saddr->s6_addr32[2];
135 136
136 a += JHASH_GOLDEN_RATIO; 137 a += JHASH_GOLDEN_RATIO;
137 b += JHASH_GOLDEN_RATIO; 138 b += JHASH_GOLDEN_RATIO;
138 c += ip6_frag_hash_rnd; 139 c += ip6_frag_hash_rnd;
139 __jhash_mix(a, b, c); 140 __jhash_mix(a, b, c);
140 141
141 a += saddr->s6_addr32[3]; 142 a += (__force u32)saddr->s6_addr32[3];
142 b += daddr->s6_addr32[0]; 143 b += (__force u32)daddr->s6_addr32[0];
143 c += daddr->s6_addr32[1]; 144 c += (__force u32)daddr->s6_addr32[1];
144 __jhash_mix(a, b, c); 145 __jhash_mix(a, b, c);
145 146
146 a += daddr->s6_addr32[2]; 147 a += (__force u32)daddr->s6_addr32[2];
147 b += daddr->s6_addr32[3]; 148 b += (__force u32)daddr->s6_addr32[3];
148 c += id; 149 c += (__force u32)id;
149 __jhash_mix(a, b, c); 150 __jhash_mix(a, b, c);
150 151
151 return c & (IP6Q_HASHSZ - 1); 152 return c & (IP6Q_HASHSZ - 1);
@@ -257,7 +258,7 @@ static __inline__ void fq_kill(struct frag_queue *fq)
257 } 258 }
258} 259}
259 260
260static void ip6_evictor(void) 261static void ip6_evictor(struct inet6_dev *idev)
261{ 262{
262 struct frag_queue *fq; 263 struct frag_queue *fq;
263 struct list_head *tmp; 264 struct list_head *tmp;
@@ -284,14 +285,14 @@ static void ip6_evictor(void)
284 spin_unlock(&fq->lock); 285 spin_unlock(&fq->lock);
285 286
286 fq_put(fq, &work); 287 fq_put(fq, &work);
287 IP6_INC_STATS_BH(IPSTATS_MIB_REASMFAILS); 288 IP6_INC_STATS_BH(idev, IPSTATS_MIB_REASMFAILS);
288 } 289 }
289} 290}
290 291
291static void ip6_frag_expire(unsigned long data) 292static void ip6_frag_expire(unsigned long data)
292{ 293{
293 struct frag_queue *fq = (struct frag_queue *) data; 294 struct frag_queue *fq = (struct frag_queue *) data;
294 struct net_device *dev; 295 struct net_device *dev = NULL;
295 296
296 spin_lock(&fq->lock); 297 spin_lock(&fq->lock);
297 298
@@ -300,17 +301,19 @@ static void ip6_frag_expire(unsigned long data)
300 301
301 fq_kill(fq); 302 fq_kill(fq);
302 303
303 IP6_INC_STATS_BH(IPSTATS_MIB_REASMTIMEOUT); 304 dev = dev_get_by_index(fq->iif);
304 IP6_INC_STATS_BH(IPSTATS_MIB_REASMFAILS); 305 if (!dev)
306 goto out;
307
308 rcu_read_lock();
309 IP6_INC_STATS_BH(__in6_dev_get(dev), IPSTATS_MIB_REASMTIMEOUT);
310 IP6_INC_STATS_BH(__in6_dev_get(dev), IPSTATS_MIB_REASMFAILS);
311 rcu_read_unlock();
305 312
306 /* Don't send error if the first segment did not arrive. */ 313 /* Don't send error if the first segment did not arrive. */
307 if (!(fq->last_in&FIRST_IN) || !fq->fragments) 314 if (!(fq->last_in&FIRST_IN) || !fq->fragments)
308 goto out; 315 goto out;
309 316
310 dev = dev_get_by_index(fq->iif);
311 if (!dev)
312 goto out;
313
314 /* 317 /*
315 But use as source device on which LAST ARRIVED 318 But use as source device on which LAST ARRIVED
316 segment was received. And do not use fq->dev 319 segment was received. And do not use fq->dev
@@ -318,8 +321,9 @@ static void ip6_frag_expire(unsigned long data)
318 */ 321 */
319 fq->fragments->dev = dev; 322 fq->fragments->dev = dev;
320 icmpv6_send(fq->fragments, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0, dev); 323 icmpv6_send(fq->fragments, ICMPV6_TIME_EXCEED, ICMPV6_EXC_FRAGTIME, 0, dev);
321 dev_put(dev);
322out: 324out:
325 if (dev)
326 dev_put(dev);
323 spin_unlock(&fq->lock); 327 spin_unlock(&fq->lock);
324 fq_put(fq, NULL); 328 fq_put(fq, NULL);
325} 329}
@@ -366,7 +370,8 @@ static struct frag_queue *ip6_frag_intern(struct frag_queue *fq_in)
366 370
367 371
368static struct frag_queue * 372static struct frag_queue *
369ip6_frag_create(u32 id, struct in6_addr *src, struct in6_addr *dst) 373ip6_frag_create(__be32 id, struct in6_addr *src, struct in6_addr *dst,
374 struct inet6_dev *idev)
370{ 375{
371 struct frag_queue *fq; 376 struct frag_queue *fq;
372 377
@@ -386,12 +391,13 @@ ip6_frag_create(u32 id, struct in6_addr *src, struct in6_addr *dst)
386 return ip6_frag_intern(fq); 391 return ip6_frag_intern(fq);
387 392
388oom: 393oom:
389 IP6_INC_STATS_BH(IPSTATS_MIB_REASMFAILS); 394 IP6_INC_STATS_BH(idev, IPSTATS_MIB_REASMFAILS);
390 return NULL; 395 return NULL;
391} 396}
392 397
393static __inline__ struct frag_queue * 398static __inline__ struct frag_queue *
394fq_find(u32 id, struct in6_addr *src, struct in6_addr *dst) 399fq_find(__be32 id, struct in6_addr *src, struct in6_addr *dst,
400 struct inet6_dev *idev)
395{ 401{
396 struct frag_queue *fq; 402 struct frag_queue *fq;
397 struct hlist_node *n; 403 struct hlist_node *n;
@@ -410,7 +416,7 @@ fq_find(u32 id, struct in6_addr *src, struct in6_addr *dst)
410 } 416 }
411 read_unlock(&ip6_frag_lock); 417 read_unlock(&ip6_frag_lock);
412 418
413 return ip6_frag_create(id, src, dst); 419 return ip6_frag_create(id, src, dst, idev);
414} 420}
415 421
416 422
@@ -428,7 +434,8 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
428 ((u8 *) (fhdr + 1) - (u8 *) (skb->nh.ipv6h + 1))); 434 ((u8 *) (fhdr + 1) - (u8 *) (skb->nh.ipv6h + 1)));
429 435
430 if ((unsigned int)end > IPV6_MAXPLEN) { 436 if ((unsigned int)end > IPV6_MAXPLEN) {
431 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 437 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
438 IPSTATS_MIB_INHDRERRORS);
432 icmpv6_param_prob(skb,ICMPV6_HDR_FIELD, (u8*)&fhdr->frag_off - skb->nh.raw); 439 icmpv6_param_prob(skb,ICMPV6_HDR_FIELD, (u8*)&fhdr->frag_off - skb->nh.raw);
433 return; 440 return;
434 } 441 }
@@ -455,7 +462,8 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
455 /* RFC2460 says always send parameter problem in 462 /* RFC2460 says always send parameter problem in
456 * this case. -DaveM 463 * this case. -DaveM
457 */ 464 */
458 IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); 465 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
466 IPSTATS_MIB_INHDRERRORS);
459 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, 467 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD,
460 offsetof(struct ipv6hdr, payload_len)); 468 offsetof(struct ipv6hdr, payload_len));
461 return; 469 return;
@@ -571,7 +579,7 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
571 return; 579 return;
572 580
573err: 581err:
574 IP6_INC_STATS(IPSTATS_MIB_REASMFAILS); 582 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMFAILS);
575 kfree_skb(skb); 583 kfree_skb(skb);
576} 584}
577 585
@@ -665,7 +673,9 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff **skb_in,
665 if (head->ip_summed == CHECKSUM_COMPLETE) 673 if (head->ip_summed == CHECKSUM_COMPLETE)
666 head->csum = csum_partial(head->nh.raw, head->h.raw-head->nh.raw, head->csum); 674 head->csum = csum_partial(head->nh.raw, head->h.raw-head->nh.raw, head->csum);
667 675
668 IP6_INC_STATS_BH(IPSTATS_MIB_REASMOKS); 676 rcu_read_lock();
677 IP6_INC_STATS_BH(__in6_dev_get(dev), IPSTATS_MIB_REASMOKS);
678 rcu_read_unlock();
669 fq->fragments = NULL; 679 fq->fragments = NULL;
670 return 1; 680 return 1;
671 681
@@ -677,7 +687,9 @@ out_oom:
677 if (net_ratelimit()) 687 if (net_ratelimit())
678 printk(KERN_DEBUG "ip6_frag_reasm: no memory for reassembly\n"); 688 printk(KERN_DEBUG "ip6_frag_reasm: no memory for reassembly\n");
679out_fail: 689out_fail:
680 IP6_INC_STATS_BH(IPSTATS_MIB_REASMFAILS); 690 rcu_read_lock();
691 IP6_INC_STATS_BH(__in6_dev_get(dev), IPSTATS_MIB_REASMFAILS);
692 rcu_read_unlock();
681 return -1; 693 return -1;
682} 694}
683 695
@@ -691,16 +703,16 @@ static int ipv6_frag_rcv(struct sk_buff **skbp)
691 703
692 hdr = skb->nh.ipv6h; 704 hdr = skb->nh.ipv6h;
693 705
694 IP6_INC_STATS_BH(IPSTATS_MIB_REASMREQDS); 706 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMREQDS);
695 707
696 /* Jumbo payload inhibits frag. header */ 708 /* Jumbo payload inhibits frag. header */
697 if (hdr->payload_len==0) { 709 if (hdr->payload_len==0) {
698 IP6_INC_STATS(IPSTATS_MIB_INHDRERRORS); 710 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
699 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb->h.raw-skb->nh.raw); 711 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb->h.raw-skb->nh.raw);
700 return -1; 712 return -1;
701 } 713 }
702 if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+sizeof(struct frag_hdr))) { 714 if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+sizeof(struct frag_hdr))) {
703 IP6_INC_STATS(IPSTATS_MIB_INHDRERRORS); 715 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_INHDRERRORS);
704 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb->h.raw-skb->nh.raw); 716 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, skb->h.raw-skb->nh.raw);
705 return -1; 717 return -1;
706 } 718 }
@@ -711,16 +723,17 @@ static int ipv6_frag_rcv(struct sk_buff **skbp)
711 if (!(fhdr->frag_off & htons(0xFFF9))) { 723 if (!(fhdr->frag_off & htons(0xFFF9))) {
712 /* It is not a fragmented frame */ 724 /* It is not a fragmented frame */
713 skb->h.raw += sizeof(struct frag_hdr); 725 skb->h.raw += sizeof(struct frag_hdr);
714 IP6_INC_STATS_BH(IPSTATS_MIB_REASMOKS); 726 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMOKS);
715 727
716 IP6CB(skb)->nhoff = (u8*)fhdr - skb->nh.raw; 728 IP6CB(skb)->nhoff = (u8*)fhdr - skb->nh.raw;
717 return 1; 729 return 1;
718 } 730 }
719 731
720 if (atomic_read(&ip6_frag_mem) > sysctl_ip6frag_high_thresh) 732 if (atomic_read(&ip6_frag_mem) > sysctl_ip6frag_high_thresh)
721 ip6_evictor(); 733 ip6_evictor(ip6_dst_idev(skb->dst));
722 734
723 if ((fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr)) != NULL) { 735 if ((fq = fq_find(fhdr->identification, &hdr->saddr, &hdr->daddr,
736 ip6_dst_idev(skb->dst))) != NULL) {
724 int ret = -1; 737 int ret = -1;
725 738
726 spin_lock(&fq->lock); 739 spin_lock(&fq->lock);
@@ -736,7 +749,7 @@ static int ipv6_frag_rcv(struct sk_buff **skbp)
736 return ret; 749 return ret;
737 } 750 }
738 751
739 IP6_INC_STATS_BH(IPSTATS_MIB_REASMFAILS); 752 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), IPSTATS_MIB_REASMFAILS);
740 kfree_skb(skb); 753 kfree_skb(skb);
741 return -1; 754 return -1;
742} 755}
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index b39ae99122..8c3d56871b 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -440,7 +440,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
440 if (pref == ICMPV6_ROUTER_PREF_INVALID) 440 if (pref == ICMPV6_ROUTER_PREF_INVALID)
441 pref = ICMPV6_ROUTER_PREF_MEDIUM; 441 pref = ICMPV6_ROUTER_PREF_MEDIUM;
442 442
443 lifetime = htonl(rinfo->lifetime); 443 lifetime = ntohl(rinfo->lifetime);
444 if (lifetime == 0xffffffff) { 444 if (lifetime == 0xffffffff) {
445 /* infinity */ 445 /* infinity */
446 } else if (lifetime > 0x7fffffff/HZ) { 446 } else if (lifetime > 0x7fffffff/HZ) {
@@ -494,7 +494,7 @@ do { \
494 goto out; \ 494 goto out; \
495 pn = fn->parent; \ 495 pn = fn->parent; \
496 if (FIB6_SUBTREE(pn) && FIB6_SUBTREE(pn) != fn) \ 496 if (FIB6_SUBTREE(pn) && FIB6_SUBTREE(pn) != fn) \
497 fn = fib6_lookup(pn->subtree, NULL, saddr); \ 497 fn = fib6_lookup(FIB6_SUBTREE(pn), NULL, saddr); \
498 else \ 498 else \
499 fn = pn; \ 499 fn = pn; \
500 if (fn->fn_flags & RTN_RTINFO) \ 500 if (fn->fn_flags & RTN_RTINFO) \
@@ -711,12 +711,10 @@ void ip6_route_input(struct sk_buff *skb)
711 .ip6_u = { 711 .ip6_u = {
712 .daddr = iph->daddr, 712 .daddr = iph->daddr,
713 .saddr = iph->saddr, 713 .saddr = iph->saddr,
714#ifdef CONFIG_IPV6_ROUTE_FWMARK 714 .flowlabel = (* (__be32 *) iph)&IPV6_FLOWINFO_MASK,
715 .fwmark = skb->nfmark,
716#endif
717 .flowlabel = (* (u32 *) iph)&IPV6_FLOWINFO_MASK,
718 }, 715 },
719 }, 716 },
717 .mark = skb->mark,
720 .proto = iph->nexthdr, 718 .proto = iph->nexthdr,
721 }; 719 };
722 720
@@ -942,7 +940,7 @@ struct dst_entry *ndisc_dst_alloc(struct net_device *dev,
942 fib6_force_start_gc(); 940 fib6_force_start_gc();
943 941
944out: 942out:
945 return (struct dst_entry *)rt; 943 return &rt->u.dst;
946} 944}
947 945
948int ndisc_dst_gc(int *more) 946int ndisc_dst_gc(int *more)
@@ -1225,7 +1223,7 @@ out:
1225 if (idev) 1223 if (idev)
1226 in6_dev_put(idev); 1224 in6_dev_put(idev);
1227 if (rt) 1225 if (rt)
1228 dst_free((struct dst_entry *) rt); 1226 dst_free(&rt->u.dst);
1229 return err; 1227 return err;
1230} 1228}
1231 1229
@@ -1751,9 +1749,9 @@ static inline int ip6_pkt_drop(struct sk_buff *skb, int code)
1751{ 1749{
1752 int type = ipv6_addr_type(&skb->nh.ipv6h->daddr); 1750 int type = ipv6_addr_type(&skb->nh.ipv6h->daddr);
1753 if (type == IPV6_ADDR_ANY || type == IPV6_ADDR_RESERVED) 1751 if (type == IPV6_ADDR_ANY || type == IPV6_ADDR_RESERVED)
1754 IP6_INC_STATS(IPSTATS_MIB_INADDRERRORS); 1752 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_INADDRERRORS);
1755 1753
1756 IP6_INC_STATS(IPSTATS_MIB_OUTNOROUTES); 1754 IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_OUTNOROUTES);
1757 icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0, skb->dev); 1755 icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0, skb->dev);
1758 kfree_skb(skb); 1756 kfree_skb(skb);
1759 return 0; 1757 return 0;
@@ -1824,7 +1822,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
1824 rt->rt6i_flags |= RTF_LOCAL; 1822 rt->rt6i_flags |= RTF_LOCAL;
1825 rt->rt6i_nexthop = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_gateway); 1823 rt->rt6i_nexthop = ndisc_get_neigh(rt->rt6i_dev, &rt->rt6i_gateway);
1826 if (rt->rt6i_nexthop == NULL) { 1824 if (rt->rt6i_nexthop == NULL) {
1827 dst_free((struct dst_entry *) rt); 1825 dst_free(&rt->u.dst);
1828 return ERR_PTR(-ENOMEM); 1826 return ERR_PTR(-ENOMEM);
1829 } 1827 }
1830 1828
@@ -2008,6 +2006,20 @@ int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
2008 return ip6_route_add(&cfg); 2006 return ip6_route_add(&cfg);
2009} 2007}
2010 2008
2009static inline size_t rt6_nlmsg_size(void)
2010{
2011 return NLMSG_ALIGN(sizeof(struct rtmsg))
2012 + nla_total_size(16) /* RTA_SRC */
2013 + nla_total_size(16) /* RTA_DST */
2014 + nla_total_size(16) /* RTA_GATEWAY */
2015 + nla_total_size(16) /* RTA_PREFSRC */
2016 + nla_total_size(4) /* RTA_TABLE */
2017 + nla_total_size(4) /* RTA_IIF */
2018 + nla_total_size(4) /* RTA_OIF */
2019 + nla_total_size(4) /* RTA_PRIORITY */
2020 + nla_total_size(sizeof(struct rta_cacheinfo));
2021}
2022
2011static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, 2023static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
2012 struct in6_addr *dst, struct in6_addr *src, 2024 struct in6_addr *dst, struct in6_addr *src,
2013 int iif, int type, u32 pid, u32 seq, 2025 int iif, int type, u32 pid, u32 seq,
@@ -2015,7 +2027,7 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
2015{ 2027{
2016 struct rtmsg *rtm; 2028 struct rtmsg *rtm;
2017 struct nlmsghdr *nlh; 2029 struct nlmsghdr *nlh;
2018 struct rta_cacheinfo ci; 2030 long expires;
2019 u32 table; 2031 u32 table;
2020 2032
2021 if (prefix) { /* user wants prefix routes only */ 2033 if (prefix) { /* user wants prefix routes only */
@@ -2089,18 +2101,11 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
2089 NLA_PUT_U32(skb, RTA_OIF, rt->rt6i_dev->ifindex); 2101 NLA_PUT_U32(skb, RTA_OIF, rt->rt6i_dev->ifindex);
2090 2102
2091 NLA_PUT_U32(skb, RTA_PRIORITY, rt->rt6i_metric); 2103 NLA_PUT_U32(skb, RTA_PRIORITY, rt->rt6i_metric);
2092 ci.rta_lastuse = jiffies_to_clock_t(jiffies - rt->u.dst.lastuse); 2104
2093 if (rt->rt6i_expires) 2105 expires = rt->rt6i_expires ? rt->rt6i_expires - jiffies : 0;
2094 ci.rta_expires = jiffies_to_clock_t(rt->rt6i_expires - jiffies); 2106 if (rtnl_put_cacheinfo(skb, &rt->u.dst, 0, 0, 0,
2095 else 2107 expires, rt->u.dst.error) < 0)
2096 ci.rta_expires = 0; 2108 goto nla_put_failure;
2097 ci.rta_used = rt->u.dst.__use;
2098 ci.rta_clntref = atomic_read(&rt->u.dst.__refcnt);
2099 ci.rta_error = rt->u.dst.error;
2100 ci.rta_id = 0;
2101 ci.rta_ts = 0;
2102 ci.rta_tsage = 0;
2103 NLA_PUT(skb, RTA_CACHEINFO, sizeof(ci), &ci);
2104 2109
2105 return nlmsg_end(skb, nlh); 2110 return nlmsg_end(skb, nlh);
2106 2111
@@ -2202,7 +2207,6 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info)
2202 struct sk_buff *skb; 2207 struct sk_buff *skb;
2203 u32 pid = 0, seq = 0; 2208 u32 pid = 0, seq = 0;
2204 struct nlmsghdr *nlh = NULL; 2209 struct nlmsghdr *nlh = NULL;
2205 int payload = sizeof(struct rtmsg) + 256;
2206 int err = -ENOBUFS; 2210 int err = -ENOBUFS;
2207 2211
2208 if (info) { 2212 if (info) {
@@ -2212,15 +2216,13 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info)
2212 seq = nlh->nlmsg_seq; 2216 seq = nlh->nlmsg_seq;
2213 } 2217 }
2214 2218
2215 skb = nlmsg_new(nlmsg_total_size(payload), gfp_any()); 2219 skb = nlmsg_new(rt6_nlmsg_size(), gfp_any());
2216 if (skb == NULL) 2220 if (skb == NULL)
2217 goto errout; 2221 goto errout;
2218 2222
2219 err = rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0); 2223 err = rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0);
2220 if (err < 0) { 2224 /* failure implies BUG in rt6_nlmsg_size() */
2221 kfree_skb(skb); 2225 BUG_ON(err < 0);
2222 goto errout;
2223 }
2224 2226
2225 err = rtnl_notify(skb, pid, RTNLGRP_IPV6_ROUTE, nlh, gfp_any()); 2227 err = rtnl_notify(skb, pid, RTNLGRP_IPV6_ROUTE, nlh, gfp_any());
2226errout: 2228errout:
@@ -2248,7 +2250,6 @@ struct rt6_proc_arg
2248static int rt6_info_route(struct rt6_info *rt, void *p_arg) 2250static int rt6_info_route(struct rt6_info *rt, void *p_arg)
2249{ 2251{
2250 struct rt6_proc_arg *arg = (struct rt6_proc_arg *) p_arg; 2252 struct rt6_proc_arg *arg = (struct rt6_proc_arg *) p_arg;
2251 int i;
2252 2253
2253 if (arg->skip < arg->offset / RT6_INFO_LEN) { 2254 if (arg->skip < arg->offset / RT6_INFO_LEN) {
2254 arg->skip++; 2255 arg->skip++;
@@ -2258,38 +2259,28 @@ static int rt6_info_route(struct rt6_info *rt, void *p_arg)
2258 if (arg->len >= arg->length) 2259 if (arg->len >= arg->length)
2259 return 0; 2260 return 0;
2260 2261
2261 for (i=0; i<16; i++) { 2262 arg->len += sprintf(arg->buffer + arg->len,
2262 sprintf(arg->buffer + arg->len, "%02x", 2263 NIP6_SEQFMT " %02x ",
2263 rt->rt6i_dst.addr.s6_addr[i]); 2264 NIP6(rt->rt6i_dst.addr),
2264 arg->len += 2;
2265 }
2266 arg->len += sprintf(arg->buffer + arg->len, " %02x ",
2267 rt->rt6i_dst.plen); 2265 rt->rt6i_dst.plen);
2268 2266
2269#ifdef CONFIG_IPV6_SUBTREES 2267#ifdef CONFIG_IPV6_SUBTREES
2270 for (i=0; i<16; i++) { 2268 arg->len += sprintf(arg->buffer + arg->len,
2271 sprintf(arg->buffer + arg->len, "%02x", 2269 NIP6_SEQFMT " %02x ",
2272 rt->rt6i_src.addr.s6_addr[i]); 2270 NIP6(rt->rt6i_src.addr),
2273 arg->len += 2;
2274 }
2275 arg->len += sprintf(arg->buffer + arg->len, " %02x ",
2276 rt->rt6i_src.plen); 2271 rt->rt6i_src.plen);
2277#else 2272#else
2278 sprintf(arg->buffer + arg->len, 2273 arg->len += sprintf(arg->buffer + arg->len,
2279 "00000000000000000000000000000000 00 "); 2274 "00000000000000000000000000000000 00 ");
2280 arg->len += 36;
2281#endif 2275#endif
2282 2276
2283 if (rt->rt6i_nexthop) { 2277 if (rt->rt6i_nexthop) {
2284 for (i=0; i<16; i++) { 2278 arg->len += sprintf(arg->buffer + arg->len,
2285 sprintf(arg->buffer + arg->len, "%02x", 2279 NIP6_SEQFMT,
2286 rt->rt6i_nexthop->primary_key[i]); 2280 NIP6(*((struct in6_addr *)rt->rt6i_nexthop->primary_key)));
2287 arg->len += 2;
2288 }
2289 } else { 2281 } else {
2290 sprintf(arg->buffer + arg->len, 2282 arg->len += sprintf(arg->buffer + arg->len,
2291 "00000000000000000000000000000000"); 2283 "00000000000000000000000000000000");
2292 arg->len += 32;
2293 } 2284 }
2294 arg->len += sprintf(arg->buffer + arg->len, 2285 arg->len += sprintf(arg->buffer + arg->len,
2295 " %08x %08x %08x %08x %8s\n", 2286 " %08x %08x %08x %08x %8s\n",
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index be699f85b2..77b7b09114 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -60,7 +60,7 @@
60 */ 60 */
61 61
62#define HASH_SIZE 16 62#define HASH_SIZE 16
63#define HASH(addr) ((addr^(addr>>4))&0xF) 63#define HASH(addr) (((__force u32)addr^((__force u32)addr>>4))&0xF)
64 64
65static int ipip6_fb_tunnel_init(struct net_device *dev); 65static int ipip6_fb_tunnel_init(struct net_device *dev);
66static int ipip6_tunnel_init(struct net_device *dev); 66static int ipip6_tunnel_init(struct net_device *dev);
@@ -76,7 +76,7 @@ static struct ip_tunnel **tunnels[4] = { tunnels_wc, tunnels_l, tunnels_r, tunne
76 76
77static DEFINE_RWLOCK(ipip6_lock); 77static DEFINE_RWLOCK(ipip6_lock);
78 78
79static struct ip_tunnel * ipip6_tunnel_lookup(u32 remote, u32 local) 79static struct ip_tunnel * ipip6_tunnel_lookup(__be32 remote, __be32 local)
80{ 80{
81 unsigned h0 = HASH(remote); 81 unsigned h0 = HASH(remote);
82 unsigned h1 = HASH(local); 82 unsigned h1 = HASH(local);
@@ -102,8 +102,8 @@ static struct ip_tunnel * ipip6_tunnel_lookup(u32 remote, u32 local)
102 102
103static struct ip_tunnel ** ipip6_bucket(struct ip_tunnel *t) 103static struct ip_tunnel ** ipip6_bucket(struct ip_tunnel *t)
104{ 104{
105 u32 remote = t->parms.iph.daddr; 105 __be32 remote = t->parms.iph.daddr;
106 u32 local = t->parms.iph.saddr; 106 __be32 local = t->parms.iph.saddr;
107 unsigned h = 0; 107 unsigned h = 0;
108 int prio = 0; 108 int prio = 0;
109 109
@@ -144,8 +144,8 @@ static void ipip6_tunnel_link(struct ip_tunnel *t)
144 144
145static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int create) 145static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int create)
146{ 146{
147 u32 remote = parms->iph.daddr; 147 __be32 remote = parms->iph.daddr;
148 u32 local = parms->iph.saddr; 148 __be32 local = parms->iph.saddr;
149 struct ip_tunnel *t, **tp, *nt; 149 struct ip_tunnel *t, **tp, *nt;
150 struct net_device *dev; 150 struct net_device *dev;
151 unsigned h = 0; 151 unsigned h = 0;
@@ -405,9 +405,9 @@ out:
405/* Returns the embedded IPv4 address if the IPv6 address 405/* Returns the embedded IPv4 address if the IPv6 address
406 comes from 6to4 (RFC 3056) addr space */ 406 comes from 6to4 (RFC 3056) addr space */
407 407
408static inline u32 try_6to4(struct in6_addr *v6dst) 408static inline __be32 try_6to4(struct in6_addr *v6dst)
409{ 409{
410 u32 dst = 0; 410 __be32 dst = 0;
411 411
412 if (v6dst->s6_addr16[0] == htons(0x2002)) { 412 if (v6dst->s6_addr16[0] == htons(0x2002)) {
413 /* 6to4 v6 addr has 16 bits prefix, 32 v4addr, 16 SLA, ... */ 413 /* 6to4 v6 addr has 16 bits prefix, 32 v4addr, 16 SLA, ... */
@@ -432,7 +432,7 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
432 struct net_device *tdev; /* Device to other host */ 432 struct net_device *tdev; /* Device to other host */
433 struct iphdr *iph; /* Our new IP header */ 433 struct iphdr *iph; /* Our new IP header */
434 int max_headroom; /* The extra header space needed */ 434 int max_headroom; /* The extra header space needed */
435 u32 dst = tiph->daddr; 435 __be32 dst = tiph->daddr;
436 int mtu; 436 int mtu;
437 struct in6_addr *addr6; 437 struct in6_addr *addr6;
438 int addr_type; 438 int addr_type;
@@ -809,7 +809,7 @@ static void __exit sit_destroy_tunnels(void)
809 } 809 }
810} 810}
811 811
812void __exit sit_cleanup(void) 812static void __exit sit_cleanup(void)
813{ 813{
814 inet_del_protocol(&sit_protocol, IPPROTO_IPV6); 814 inet_del_protocol(&sit_protocol, IPPROTO_IPV6);
815 815
@@ -819,7 +819,7 @@ void __exit sit_cleanup(void)
819 rtnl_unlock(); 819 rtnl_unlock();
820} 820}
821 821
822int __init sit_init(void) 822static int __init sit_init(void)
823{ 823{
824 int err; 824 int err;
825 825
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 4c2a7c0caf..c25e930c2c 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -66,10 +66,13 @@
66#include <linux/proc_fs.h> 66#include <linux/proc_fs.h>
67#include <linux/seq_file.h> 67#include <linux/seq_file.h>
68 68
69#include <linux/crypto.h>
70#include <linux/scatterlist.h>
71
69/* Socket used for sending RSTs and ACKs */ 72/* Socket used for sending RSTs and ACKs */
70static struct socket *tcp6_socket; 73static struct socket *tcp6_socket;
71 74
72static void tcp_v6_send_reset(struct sk_buff *skb); 75static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb);
73static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req); 76static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req);
74static void tcp_v6_send_check(struct sock *sk, int len, 77static void tcp_v6_send_check(struct sock *sk, int len,
75 struct sk_buff *skb); 78 struct sk_buff *skb);
@@ -78,6 +81,10 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb);
78 81
79static struct inet_connection_sock_af_ops ipv6_mapped; 82static struct inet_connection_sock_af_ops ipv6_mapped;
80static struct inet_connection_sock_af_ops ipv6_specific; 83static struct inet_connection_sock_af_ops ipv6_specific;
84#ifdef CONFIG_TCP_MD5SIG
85static struct tcp_sock_af_ops tcp_sock_ipv6_specific;
86static struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific;
87#endif
81 88
82static int tcp_v6_get_port(struct sock *sk, unsigned short snum) 89static int tcp_v6_get_port(struct sock *sk, unsigned short snum)
83{ 90{
@@ -98,27 +105,20 @@ static void tcp_v6_hash(struct sock *sk)
98 } 105 }
99} 106}
100 107
101static __inline__ u16 tcp_v6_check(struct tcphdr *th, int len, 108static __inline__ __sum16 tcp_v6_check(struct tcphdr *th, int len,
102 struct in6_addr *saddr, 109 struct in6_addr *saddr,
103 struct in6_addr *daddr, 110 struct in6_addr *daddr,
104 unsigned long base) 111 __wsum base)
105{ 112{
106 return csum_ipv6_magic(saddr, daddr, len, IPPROTO_TCP, base); 113 return csum_ipv6_magic(saddr, daddr, len, IPPROTO_TCP, base);
107} 114}
108 115
109static __u32 tcp_v6_init_sequence(struct sock *sk, struct sk_buff *skb) 116static __u32 tcp_v6_init_sequence(struct sk_buff *skb)
110{ 117{
111 if (skb->protocol == htons(ETH_P_IPV6)) { 118 return secure_tcpv6_sequence_number(skb->nh.ipv6h->daddr.s6_addr32,
112 return secure_tcpv6_sequence_number(skb->nh.ipv6h->daddr.s6_addr32, 119 skb->nh.ipv6h->saddr.s6_addr32,
113 skb->nh.ipv6h->saddr.s6_addr32, 120 skb->h.th->dest,
114 skb->h.th->dest, 121 skb->h.th->source);
115 skb->h.th->source);
116 } else {
117 return secure_tcp_sequence_number(skb->nh.iph->daddr,
118 skb->nh.iph->saddr,
119 skb->h.th->dest,
120 skb->h.th->source);
121 }
122} 122}
123 123
124static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, 124static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
@@ -215,6 +215,9 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
215 215
216 icsk->icsk_af_ops = &ipv6_mapped; 216 icsk->icsk_af_ops = &ipv6_mapped;
217 sk->sk_backlog_rcv = tcp_v4_do_rcv; 217 sk->sk_backlog_rcv = tcp_v4_do_rcv;
218#ifdef CONFIG_TCP_MD5SIG
219 tp->af_specific = &tcp_sock_ipv6_mapped_specific;
220#endif
218 221
219 err = tcp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin)); 222 err = tcp_v4_connect(sk, (struct sockaddr *)&sin, sizeof(sin));
220 223
@@ -222,6 +225,9 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
222 icsk->icsk_ext_hdr_len = exthdrlen; 225 icsk->icsk_ext_hdr_len = exthdrlen;
223 icsk->icsk_af_ops = &ipv6_specific; 226 icsk->icsk_af_ops = &ipv6_specific;
224 sk->sk_backlog_rcv = tcp_v6_do_rcv; 227 sk->sk_backlog_rcv = tcp_v6_do_rcv;
228#ifdef CONFIG_TCP_MD5SIG
229 tp->af_specific = &tcp_sock_ipv6_specific;
230#endif
225 goto failure; 231 goto failure;
226 } else { 232 } else {
227 ipv6_addr_set(&np->saddr, 0, 0, htonl(0x0000FFFF), 233 ipv6_addr_set(&np->saddr, 0, 0, htonl(0x0000FFFF),
@@ -310,7 +316,7 @@ failure:
310} 316}
311 317
312static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 318static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
313 int type, int code, int offset, __u32 info) 319 int type, int code, int offset, __be32 info)
314{ 320{
315 struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data; 321 struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data;
316 const struct tcphdr *th = (struct tcphdr *)(skb->data+offset); 322 const struct tcphdr *th = (struct tcphdr *)(skb->data+offset);
@@ -509,8 +515,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req,
509 515
510 ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr); 516 ipv6_addr_copy(&fl.fl6_dst, &treq->rmt_addr);
511 err = ip6_xmit(sk, skb, &fl, opt, 0); 517 err = ip6_xmit(sk, skb, &fl, opt, 0);
512 if (err == NET_XMIT_CN) 518 err = net_xmit_eval(err);
513 err = 0;
514 } 519 }
515 520
516done: 521done:
@@ -526,7 +531,396 @@ static void tcp_v6_reqsk_destructor(struct request_sock *req)
526 kfree_skb(inet6_rsk(req)->pktopts); 531 kfree_skb(inet6_rsk(req)->pktopts);
527} 532}
528 533
529static struct request_sock_ops tcp6_request_sock_ops = { 534#ifdef CONFIG_TCP_MD5SIG
535static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(struct sock *sk,
536 struct in6_addr *addr)
537{
538 struct tcp_sock *tp = tcp_sk(sk);
539 int i;
540
541 BUG_ON(tp == NULL);
542
543 if (!tp->md5sig_info || !tp->md5sig_info->entries6)
544 return NULL;
545
546 for (i = 0; i < tp->md5sig_info->entries6; i++) {
547 if (ipv6_addr_cmp(&tp->md5sig_info->keys6[i].addr, addr) == 0)
548 return (struct tcp_md5sig_key *)&tp->md5sig_info->keys6[i];
549 }
550 return NULL;
551}
552
553static struct tcp_md5sig_key *tcp_v6_md5_lookup(struct sock *sk,
554 struct sock *addr_sk)
555{
556 return tcp_v6_md5_do_lookup(sk, &inet6_sk(addr_sk)->daddr);
557}
558
559static struct tcp_md5sig_key *tcp_v6_reqsk_md5_lookup(struct sock *sk,
560 struct request_sock *req)
561{
562 return tcp_v6_md5_do_lookup(sk, &inet6_rsk(req)->rmt_addr);
563}
564
565static int tcp_v6_md5_do_add(struct sock *sk, struct in6_addr *peer,
566 char *newkey, u8 newkeylen)
567{
568 /* Add key to the list */
569 struct tcp6_md5sig_key *key;
570 struct tcp_sock *tp = tcp_sk(sk);
571 struct tcp6_md5sig_key *keys;
572
573 key = (struct tcp6_md5sig_key*) tcp_v6_md5_do_lookup(sk, peer);
574 if (key) {
575 /* modify existing entry - just update that one */
576 kfree(key->key);
577 key->key = newkey;
578 key->keylen = newkeylen;
579 } else {
580 /* reallocate new list if current one is full. */
581 if (!tp->md5sig_info) {
582 tp->md5sig_info = kzalloc(sizeof(*tp->md5sig_info), GFP_ATOMIC);
583 if (!tp->md5sig_info) {
584 kfree(newkey);
585 return -ENOMEM;
586 }
587 }
588 tcp_alloc_md5sig_pool();
589 if (tp->md5sig_info->alloced6 == tp->md5sig_info->entries6) {
590 keys = kmalloc((sizeof (tp->md5sig_info->keys6[0]) *
591 (tp->md5sig_info->entries6 + 1)), GFP_ATOMIC);
592
593 if (!keys) {
594 tcp_free_md5sig_pool();
595 kfree(newkey);
596 return -ENOMEM;
597 }
598
599 if (tp->md5sig_info->entries6)
600 memmove(keys, tp->md5sig_info->keys6,
601 (sizeof (tp->md5sig_info->keys6[0]) *
602 tp->md5sig_info->entries6));
603
604 kfree(tp->md5sig_info->keys6);
605 tp->md5sig_info->keys6 = keys;
606 tp->md5sig_info->alloced6++;
607 }
608
609 ipv6_addr_copy(&tp->md5sig_info->keys6[tp->md5sig_info->entries6].addr,
610 peer);
611 tp->md5sig_info->keys6[tp->md5sig_info->entries6].key = newkey;
612 tp->md5sig_info->keys6[tp->md5sig_info->entries6].keylen = newkeylen;
613
614 tp->md5sig_info->entries6++;
615 }
616 return 0;
617}
618
619static int tcp_v6_md5_add_func(struct sock *sk, struct sock *addr_sk,
620 u8 *newkey, __u8 newkeylen)
621{
622 return tcp_v6_md5_do_add(sk, &inet6_sk(addr_sk)->daddr,
623 newkey, newkeylen);
624}
625
626static int tcp_v6_md5_do_del(struct sock *sk, struct in6_addr *peer)
627{
628 struct tcp_sock *tp = tcp_sk(sk);
629 int i;
630
631 for (i = 0; i < tp->md5sig_info->entries6; i++) {
632 if (ipv6_addr_cmp(&tp->md5sig_info->keys6[i].addr, peer) == 0) {
633 /* Free the key */
634 kfree(tp->md5sig_info->keys6[i].key);
635 tp->md5sig_info->entries6--;
636
637 if (tp->md5sig_info->entries6 == 0) {
638 kfree(tp->md5sig_info->keys6);
639 tp->md5sig_info->keys6 = NULL;
640
641 tcp_free_md5sig_pool();
642
643 return 0;
644 } else {
645 /* shrink the database */
646 if (tp->md5sig_info->entries6 != i)
647 memmove(&tp->md5sig_info->keys6[i],
648 &tp->md5sig_info->keys6[i+1],
649 (tp->md5sig_info->entries6 - i)
650 * sizeof (tp->md5sig_info->keys6[0]));
651 }
652 }
653 }
654 return -ENOENT;
655}
656
657static void tcp_v6_clear_md5_list (struct sock *sk)
658{
659 struct tcp_sock *tp = tcp_sk(sk);
660 int i;
661
662 if (tp->md5sig_info->entries6) {
663 for (i = 0; i < tp->md5sig_info->entries6; i++)
664 kfree(tp->md5sig_info->keys6[i].key);
665 tp->md5sig_info->entries6 = 0;
666 tcp_free_md5sig_pool();
667 }
668
669 kfree(tp->md5sig_info->keys6);
670 tp->md5sig_info->keys6 = NULL;
671 tp->md5sig_info->alloced6 = 0;
672
673 if (tp->md5sig_info->entries4) {
674 for (i = 0; i < tp->md5sig_info->entries4; i++)
675 kfree(tp->md5sig_info->keys4[i].key);
676 tp->md5sig_info->entries4 = 0;
677 tcp_free_md5sig_pool();
678 }
679
680 kfree(tp->md5sig_info->keys4);
681 tp->md5sig_info->keys4 = NULL;
682 tp->md5sig_info->alloced4 = 0;
683}
684
685static int tcp_v6_parse_md5_keys (struct sock *sk, char __user *optval,
686 int optlen)
687{
688 struct tcp_md5sig cmd;
689 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&cmd.tcpm_addr;
690 u8 *newkey;
691
692 if (optlen < sizeof(cmd))
693 return -EINVAL;
694
695 if (copy_from_user(&cmd, optval, sizeof(cmd)))
696 return -EFAULT;
697
698 if (sin6->sin6_family != AF_INET6)
699 return -EINVAL;
700
701 if (!cmd.tcpm_keylen) {
702 if (!tcp_sk(sk)->md5sig_info)
703 return -ENOENT;
704 if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_MAPPED)
705 return tcp_v4_md5_do_del(sk, sin6->sin6_addr.s6_addr32[3]);
706 return tcp_v6_md5_do_del(sk, &sin6->sin6_addr);
707 }
708
709 if (cmd.tcpm_keylen > TCP_MD5SIG_MAXKEYLEN)
710 return -EINVAL;
711
712 if (!tcp_sk(sk)->md5sig_info) {
713 struct tcp_sock *tp = tcp_sk(sk);
714 struct tcp_md5sig_info *p;
715
716 p = kzalloc(sizeof(struct tcp_md5sig_info), GFP_KERNEL);
717 if (!p)
718 return -ENOMEM;
719
720 tp->md5sig_info = p;
721 }
722
723 newkey = kmemdup(cmd.tcpm_key, cmd.tcpm_keylen, GFP_KERNEL);
724 if (!newkey)
725 return -ENOMEM;
726 if (ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_MAPPED) {
727 return tcp_v4_md5_do_add(sk, sin6->sin6_addr.s6_addr32[3],
728 newkey, cmd.tcpm_keylen);
729 }
730 return tcp_v6_md5_do_add(sk, &sin6->sin6_addr, newkey, cmd.tcpm_keylen);
731}
732
733static int tcp_v6_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
734 struct in6_addr *saddr,
735 struct in6_addr *daddr,
736 struct tcphdr *th, int protocol,
737 int tcplen)
738{
739 struct scatterlist sg[4];
740 __u16 data_len;
741 int block = 0;
742 __sum16 cksum;
743 struct tcp_md5sig_pool *hp;
744 struct tcp6_pseudohdr *bp;
745 struct hash_desc *desc;
746 int err;
747 unsigned int nbytes = 0;
748
749 hp = tcp_get_md5sig_pool();
750 if (!hp) {
751 printk(KERN_WARNING "%s(): hash pool not found...\n", __FUNCTION__);
752 goto clear_hash_noput;
753 }
754 bp = &hp->md5_blk.ip6;
755 desc = &hp->md5_desc;
756
757 /* 1. TCP pseudo-header (RFC2460) */
758 ipv6_addr_copy(&bp->saddr, saddr);
759 ipv6_addr_copy(&bp->daddr, daddr);
760 bp->len = htonl(tcplen);
761 bp->protocol = htonl(protocol);
762
763 sg_set_buf(&sg[block++], bp, sizeof(*bp));
764 nbytes += sizeof(*bp);
765
766 /* 2. TCP header, excluding options */
767 cksum = th->check;
768 th->check = 0;
769 sg_set_buf(&sg[block++], th, sizeof(*th));
770 nbytes += sizeof(*th);
771
772 /* 3. TCP segment data (if any) */
773 data_len = tcplen - (th->doff << 2);
774 if (data_len > 0) {
775 u8 *data = (u8 *)th + (th->doff << 2);
776 sg_set_buf(&sg[block++], data, data_len);
777 nbytes += data_len;
778 }
779
780 /* 4. shared key */
781 sg_set_buf(&sg[block++], key->key, key->keylen);
782 nbytes += key->keylen;
783
784 /* Now store the hash into the packet */
785 err = crypto_hash_init(desc);
786 if (err) {
787 printk(KERN_WARNING "%s(): hash_init failed\n", __FUNCTION__);
788 goto clear_hash;
789 }
790 err = crypto_hash_update(desc, sg, nbytes);
791 if (err) {
792 printk(KERN_WARNING "%s(): hash_update failed\n", __FUNCTION__);
793 goto clear_hash;
794 }
795 err = crypto_hash_final(desc, md5_hash);
796 if (err) {
797 printk(KERN_WARNING "%s(): hash_final failed\n", __FUNCTION__);
798 goto clear_hash;
799 }
800
801 /* Reset header, and free up the crypto */
802 tcp_put_md5sig_pool();
803 th->check = cksum;
804out:
805 return 0;
806clear_hash:
807 tcp_put_md5sig_pool();
808clear_hash_noput:
809 memset(md5_hash, 0, 16);
810 goto out;
811}
812
813static int tcp_v6_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
814 struct sock *sk,
815 struct dst_entry *dst,
816 struct request_sock *req,
817 struct tcphdr *th, int protocol,
818 int tcplen)
819{
820 struct in6_addr *saddr, *daddr;
821
822 if (sk) {
823 saddr = &inet6_sk(sk)->saddr;
824 daddr = &inet6_sk(sk)->daddr;
825 } else {
826 saddr = &inet6_rsk(req)->loc_addr;
827 daddr = &inet6_rsk(req)->rmt_addr;
828 }
829 return tcp_v6_do_calc_md5_hash(md5_hash, key,
830 saddr, daddr,
831 th, protocol, tcplen);
832}
833
834static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb)
835{
836 __u8 *hash_location = NULL;
837 struct tcp_md5sig_key *hash_expected;
838 struct ipv6hdr *ip6h = skb->nh.ipv6h;
839 struct tcphdr *th = skb->h.th;
840 int length = (th->doff << 2) - sizeof (*th);
841 int genhash;
842 u8 *ptr;
843 u8 newhash[16];
844
845 hash_expected = tcp_v6_md5_do_lookup(sk, &ip6h->saddr);
846
847 /* If the TCP option is too short, we can short cut */
848 if (length < TCPOLEN_MD5SIG)
849 return hash_expected ? 1 : 0;
850
851 /* parse options */
852 ptr = (u8*)(th + 1);
853 while (length > 0) {
854 int opcode = *ptr++;
855 int opsize;
856
857 switch(opcode) {
858 case TCPOPT_EOL:
859 goto done_opts;
860 case TCPOPT_NOP:
861 length--;
862 continue;
863 default:
864 opsize = *ptr++;
865 if (opsize < 2 || opsize > length)
866 goto done_opts;
867 if (opcode == TCPOPT_MD5SIG) {
868 hash_location = ptr;
869 goto done_opts;
870 }
871 }
872 ptr += opsize - 2;
873 length -= opsize;
874 }
875
876done_opts:
877 /* do we have a hash as expected? */
878 if (!hash_expected) {
879 if (!hash_location)
880 return 0;
881 if (net_ratelimit()) {
882 printk(KERN_INFO "MD5 Hash NOT expected but found "
883 "(" NIP6_FMT ", %u)->"
884 "(" NIP6_FMT ", %u)\n",
885 NIP6(ip6h->saddr), ntohs(th->source),
886 NIP6(ip6h->daddr), ntohs(th->dest));
887 }
888 return 1;
889 }
890
891 if (!hash_location) {
892 if (net_ratelimit()) {
893 printk(KERN_INFO "MD5 Hash expected but NOT found "
894 "(" NIP6_FMT ", %u)->"
895 "(" NIP6_FMT ", %u)\n",
896 NIP6(ip6h->saddr), ntohs(th->source),
897 NIP6(ip6h->daddr), ntohs(th->dest));
898 }
899 return 1;
900 }
901
902 /* check the signature */
903 genhash = tcp_v6_do_calc_md5_hash(newhash,
904 hash_expected,
905 &ip6h->saddr, &ip6h->daddr,
906 th, sk->sk_protocol,
907 skb->len);
908 if (genhash || memcmp(hash_location, newhash, 16) != 0) {
909 if (net_ratelimit()) {
910 printk(KERN_INFO "MD5 Hash %s for "
911 "(" NIP6_FMT ", %u)->"
912 "(" NIP6_FMT ", %u)\n",
913 genhash ? "failed" : "mismatch",
914 NIP6(ip6h->saddr), ntohs(th->source),
915 NIP6(ip6h->daddr), ntohs(th->dest));
916 }
917 return 1;
918 }
919 return 0;
920}
921#endif
922
923static struct request_sock_ops tcp6_request_sock_ops __read_mostly = {
530 .family = AF_INET6, 924 .family = AF_INET6,
531 .obj_size = sizeof(struct tcp6_request_sock), 925 .obj_size = sizeof(struct tcp6_request_sock),
532 .rtx_syn_ack = tcp_v6_send_synack, 926 .rtx_syn_ack = tcp_v6_send_synack,
@@ -535,9 +929,16 @@ static struct request_sock_ops tcp6_request_sock_ops = {
535 .send_reset = tcp_v6_send_reset 929 .send_reset = tcp_v6_send_reset
536}; 930};
537 931
932#ifdef CONFIG_TCP_MD5SIG
933static struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = {
934 .md5_lookup = tcp_v6_reqsk_md5_lookup,
935};
936#endif
937
538static struct timewait_sock_ops tcp6_timewait_sock_ops = { 938static struct timewait_sock_ops tcp6_timewait_sock_ops = {
539 .twsk_obj_size = sizeof(struct tcp6_timewait_sock), 939 .twsk_obj_size = sizeof(struct tcp6_timewait_sock),
540 .twsk_unique = tcp_twsk_unique, 940 .twsk_unique = tcp_twsk_unique,
941 .twsk_destructor= tcp_twsk_destructor,
541}; 942};
542 943
543static void tcp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb) 944static void tcp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb)
@@ -547,7 +948,7 @@ static void tcp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb)
547 948
548 if (skb->ip_summed == CHECKSUM_PARTIAL) { 949 if (skb->ip_summed == CHECKSUM_PARTIAL) {
549 th->check = ~csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP, 0); 950 th->check = ~csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP, 0);
550 skb->csum = offsetof(struct tcphdr, check); 951 skb->csum_offset = offsetof(struct tcphdr, check);
551 } else { 952 } else {
552 th->check = csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP, 953 th->check = csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP,
553 csum_partial((char *)th, th->doff<<2, 954 csum_partial((char *)th, th->doff<<2,
@@ -569,16 +970,20 @@ static int tcp_v6_gso_send_check(struct sk_buff *skb)
569 th->check = 0; 970 th->check = 0;
570 th->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, skb->len, 971 th->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, skb->len,
571 IPPROTO_TCP, 0); 972 IPPROTO_TCP, 0);
572 skb->csum = offsetof(struct tcphdr, check); 973 skb->csum_offset = offsetof(struct tcphdr, check);
573 skb->ip_summed = CHECKSUM_PARTIAL; 974 skb->ip_summed = CHECKSUM_PARTIAL;
574 return 0; 975 return 0;
575} 976}
576 977
577static void tcp_v6_send_reset(struct sk_buff *skb) 978static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
578{ 979{
579 struct tcphdr *th = skb->h.th, *t1; 980 struct tcphdr *th = skb->h.th, *t1;
580 struct sk_buff *buff; 981 struct sk_buff *buff;
581 struct flowi fl; 982 struct flowi fl;
983 int tot_len = sizeof(*th);
984#ifdef CONFIG_TCP_MD5SIG
985 struct tcp_md5sig_key *key;
986#endif
582 987
583 if (th->rst) 988 if (th->rst)
584 return; 989 return;
@@ -586,25 +991,35 @@ static void tcp_v6_send_reset(struct sk_buff *skb)
586 if (!ipv6_unicast_destination(skb)) 991 if (!ipv6_unicast_destination(skb))
587 return; 992 return;
588 993
994#ifdef CONFIG_TCP_MD5SIG
995 if (sk)
996 key = tcp_v6_md5_do_lookup(sk, &skb->nh.ipv6h->daddr);
997 else
998 key = NULL;
999
1000 if (key)
1001 tot_len += TCPOLEN_MD5SIG_ALIGNED;
1002#endif
1003
589 /* 1004 /*
590 * We need to grab some memory, and put together an RST, 1005 * We need to grab some memory, and put together an RST,
591 * and then put it into the queue to be sent. 1006 * and then put it into the queue to be sent.
592 */ 1007 */
593 1008
594 buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + sizeof(struct tcphdr), 1009 buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + tot_len,
595 GFP_ATOMIC); 1010 GFP_ATOMIC);
596 if (buff == NULL) 1011 if (buff == NULL)
597 return; 1012 return;
598 1013
599 skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + sizeof(struct tcphdr)); 1014 skb_reserve(buff, MAX_HEADER + sizeof(struct ipv6hdr) + tot_len);
600 1015
601 t1 = (struct tcphdr *) skb_push(buff,sizeof(struct tcphdr)); 1016 t1 = (struct tcphdr *) skb_push(buff, tot_len);
602 1017
603 /* Swap the send and the receive. */ 1018 /* Swap the send and the receive. */
604 memset(t1, 0, sizeof(*t1)); 1019 memset(t1, 0, sizeof(*t1));
605 t1->dest = th->source; 1020 t1->dest = th->source;
606 t1->source = th->dest; 1021 t1->source = th->dest;
607 t1->doff = sizeof(*t1)/4; 1022 t1->doff = tot_len / 4;
608 t1->rst = 1; 1023 t1->rst = 1;
609 1024
610 if(th->ack) { 1025 if(th->ack) {
@@ -615,6 +1030,22 @@ static void tcp_v6_send_reset(struct sk_buff *skb)
615 + skb->len - (th->doff<<2)); 1030 + skb->len - (th->doff<<2));
616 } 1031 }
617 1032
1033#ifdef CONFIG_TCP_MD5SIG
1034 if (key) {
1035 __be32 *opt = (__be32*)(t1 + 1);
1036 opt[0] = htonl((TCPOPT_NOP << 24) |
1037 (TCPOPT_NOP << 16) |
1038 (TCPOPT_MD5SIG << 8) |
1039 TCPOLEN_MD5SIG);
1040 tcp_v6_do_calc_md5_hash((__u8*)&opt[1],
1041 key,
1042 &skb->nh.ipv6h->daddr,
1043 &skb->nh.ipv6h->saddr,
1044 t1, IPPROTO_TCP,
1045 tot_len);
1046 }
1047#endif
1048
618 buff->csum = csum_partial((char *)t1, sizeof(*t1), 0); 1049 buff->csum = csum_partial((char *)t1, sizeof(*t1), 0);
619 1050
620 memset(&fl, 0, sizeof(fl)); 1051 memset(&fl, 0, sizeof(fl));
@@ -645,15 +1076,37 @@ static void tcp_v6_send_reset(struct sk_buff *skb)
645 kfree_skb(buff); 1076 kfree_skb(buff);
646} 1077}
647 1078
648static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts) 1079static void tcp_v6_send_ack(struct tcp_timewait_sock *tw,
1080 struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts)
649{ 1081{
650 struct tcphdr *th = skb->h.th, *t1; 1082 struct tcphdr *th = skb->h.th, *t1;
651 struct sk_buff *buff; 1083 struct sk_buff *buff;
652 struct flowi fl; 1084 struct flowi fl;
653 int tot_len = sizeof(struct tcphdr); 1085 int tot_len = sizeof(struct tcphdr);
1086 __be32 *topt;
1087#ifdef CONFIG_TCP_MD5SIG
1088 struct tcp_md5sig_key *key;
1089 struct tcp_md5sig_key tw_key;
1090#endif
1091
1092#ifdef CONFIG_TCP_MD5SIG
1093 if (!tw && skb->sk) {
1094 key = tcp_v6_md5_do_lookup(skb->sk, &skb->nh.ipv6h->daddr);
1095 } else if (tw && tw->tw_md5_keylen) {
1096 tw_key.key = tw->tw_md5_key;
1097 tw_key.keylen = tw->tw_md5_keylen;
1098 key = &tw_key;
1099 } else {
1100 key = NULL;
1101 }
1102#endif
654 1103
655 if (ts) 1104 if (ts)
656 tot_len += TCPOLEN_TSTAMP_ALIGNED; 1105 tot_len += TCPOLEN_TSTAMP_ALIGNED;
1106#ifdef CONFIG_TCP_MD5SIG
1107 if (key)
1108 tot_len += TCPOLEN_MD5SIG_ALIGNED;
1109#endif
657 1110
658 buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + tot_len, 1111 buff = alloc_skb(MAX_HEADER + sizeof(struct ipv6hdr) + tot_len,
659 GFP_ATOMIC); 1112 GFP_ATOMIC);
@@ -673,15 +1126,29 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
673 t1->ack_seq = htonl(ack); 1126 t1->ack_seq = htonl(ack);
674 t1->ack = 1; 1127 t1->ack = 1;
675 t1->window = htons(win); 1128 t1->window = htons(win);
1129
1130 topt = (__be32 *)(t1 + 1);
676 1131
677 if (ts) { 1132 if (ts) {
678 u32 *ptr = (u32*)(t1 + 1); 1133 *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
679 *ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) | 1134 (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
680 (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP); 1135 *topt++ = htonl(tcp_time_stamp);
681 *ptr++ = htonl(tcp_time_stamp); 1136 *topt = htonl(ts);
682 *ptr = htonl(ts);
683 } 1137 }
684 1138
1139#ifdef CONFIG_TCP_MD5SIG
1140 if (key) {
1141 *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
1142 (TCPOPT_MD5SIG << 8) | TCPOLEN_MD5SIG);
1143 tcp_v6_do_calc_md5_hash((__u8 *)topt,
1144 key,
1145 &skb->nh.ipv6h->daddr,
1146 &skb->nh.ipv6h->saddr,
1147 t1, IPPROTO_TCP,
1148 tot_len);
1149 }
1150#endif
1151
685 buff->csum = csum_partial((char *)t1, tot_len, 0); 1152 buff->csum = csum_partial((char *)t1, tot_len, 0);
686 1153
687 memset(&fl, 0, sizeof(fl)); 1154 memset(&fl, 0, sizeof(fl));
@@ -712,9 +1179,9 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32
712static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb) 1179static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
713{ 1180{
714 struct inet_timewait_sock *tw = inet_twsk(sk); 1181 struct inet_timewait_sock *tw = inet_twsk(sk);
715 const struct tcp_timewait_sock *tcptw = tcp_twsk(sk); 1182 struct tcp_timewait_sock *tcptw = tcp_twsk(sk);
716 1183
717 tcp_v6_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, 1184 tcp_v6_send_ack(tcptw, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
718 tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, 1185 tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
719 tcptw->tw_ts_recent); 1186 tcptw->tw_ts_recent);
720 1187
@@ -723,7 +1190,7 @@ static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
723 1190
724static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req) 1191static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req)
725{ 1192{
726 tcp_v6_send_ack(skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent); 1193 tcp_v6_send_ack(NULL, skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent);
727} 1194}
728 1195
729 1196
@@ -794,6 +1261,10 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
794 if (req == NULL) 1261 if (req == NULL)
795 goto drop; 1262 goto drop;
796 1263
1264#ifdef CONFIG_TCP_MD5SIG
1265 tcp_rsk(req)->af_specific = &tcp_request_sock_ipv6_ops;
1266#endif
1267
797 tcp_clear_options(&tmp_opt); 1268 tcp_clear_options(&tmp_opt);
798 tmp_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr); 1269 tmp_opt.mss_clamp = IPV6_MIN_MTU - sizeof(struct tcphdr) - sizeof(struct ipv6hdr);
799 tmp_opt.user_mss = tp->rx_opt.user_mss; 1270 tmp_opt.user_mss = tp->rx_opt.user_mss;
@@ -822,7 +1293,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
822 treq->iif = inet6_iif(skb); 1293 treq->iif = inet6_iif(skb);
823 1294
824 if (isn == 0) 1295 if (isn == 0)
825 isn = tcp_v6_init_sequence(sk,skb); 1296 isn = tcp_v6_init_sequence(skb);
826 1297
827 tcp_rsk(req)->snt_isn = isn; 1298 tcp_rsk(req)->snt_isn = isn;
828 1299
@@ -852,6 +1323,9 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
852 struct tcp_sock *newtp; 1323 struct tcp_sock *newtp;
853 struct sock *newsk; 1324 struct sock *newsk;
854 struct ipv6_txoptions *opt; 1325 struct ipv6_txoptions *opt;
1326#ifdef CONFIG_TCP_MD5SIG
1327 struct tcp_md5sig_key *key;
1328#endif
855 1329
856 if (skb->protocol == htons(ETH_P_IP)) { 1330 if (skb->protocol == htons(ETH_P_IP)) {
857 /* 1331 /*
@@ -882,6 +1356,10 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
882 1356
883 inet_csk(newsk)->icsk_af_ops = &ipv6_mapped; 1357 inet_csk(newsk)->icsk_af_ops = &ipv6_mapped;
884 newsk->sk_backlog_rcv = tcp_v4_do_rcv; 1358 newsk->sk_backlog_rcv = tcp_v4_do_rcv;
1359#ifdef CONFIG_TCP_MD5SIG
1360 newtp->af_specific = &tcp_sock_ipv6_mapped_specific;
1361#endif
1362
885 newnp->pktoptions = NULL; 1363 newnp->pktoptions = NULL;
886 newnp->opt = NULL; 1364 newnp->opt = NULL;
887 newnp->mcast_oif = inet6_iif(skb); 1365 newnp->mcast_oif = inet6_iif(skb);
@@ -1016,6 +1494,21 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1016 1494
1017 newinet->daddr = newinet->saddr = newinet->rcv_saddr = LOOPBACK4_IPV6; 1495 newinet->daddr = newinet->saddr = newinet->rcv_saddr = LOOPBACK4_IPV6;
1018 1496
1497#ifdef CONFIG_TCP_MD5SIG
1498 /* Copy over the MD5 key from the original socket */
1499 if ((key = tcp_v6_md5_do_lookup(sk, &newnp->daddr)) != NULL) {
1500 /* We're using one, so create a matching key
1501 * on the newsk structure. If we fail to get
1502 * memory, then we end up not copying the key
1503 * across. Shucks.
1504 */
1505 char *newkey = kmemdup(key->key, key->keylen, GFP_ATOMIC);
1506 if (newkey != NULL)
1507 tcp_v6_md5_do_add(newsk, &inet6_sk(sk)->daddr,
1508 newkey, key->keylen);
1509 }
1510#endif
1511
1019 __inet6_hash(&tcp_hashinfo, newsk); 1512 __inet6_hash(&tcp_hashinfo, newsk);
1020 inet_inherit_port(&tcp_hashinfo, sk, newsk); 1513 inet_inherit_port(&tcp_hashinfo, sk, newsk);
1021 1514
@@ -1031,7 +1524,7 @@ out:
1031 return NULL; 1524 return NULL;
1032} 1525}
1033 1526
1034static int tcp_v6_checksum_init(struct sk_buff *skb) 1527static __sum16 tcp_v6_checksum_init(struct sk_buff *skb)
1035{ 1528{
1036 if (skb->ip_summed == CHECKSUM_COMPLETE) { 1529 if (skb->ip_summed == CHECKSUM_COMPLETE) {
1037 if (!tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr, 1530 if (!tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr,
@@ -1041,8 +1534,8 @@ static int tcp_v6_checksum_init(struct sk_buff *skb)
1041 } 1534 }
1042 } 1535 }
1043 1536
1044 skb->csum = ~tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr, 1537 skb->csum = ~csum_unfold(tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr,
1045 &skb->nh.ipv6h->daddr, 0); 1538 &skb->nh.ipv6h->daddr, 0));
1046 1539
1047 if (skb->len <= 76) { 1540 if (skb->len <= 76) {
1048 return __skb_checksum_complete(skb); 1541 return __skb_checksum_complete(skb);
@@ -1075,6 +1568,11 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
1075 if (skb->protocol == htons(ETH_P_IP)) 1568 if (skb->protocol == htons(ETH_P_IP))
1076 return tcp_v4_do_rcv(sk, skb); 1569 return tcp_v4_do_rcv(sk, skb);
1077 1570
1571#ifdef CONFIG_TCP_MD5SIG
1572 if (tcp_v6_inbound_md5_hash (sk, skb))
1573 goto discard;
1574#endif
1575
1078 if (sk_filter(sk, skb)) 1576 if (sk_filter(sk, skb))
1079 goto discard; 1577 goto discard;
1080 1578
@@ -1140,7 +1638,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
1140 return 0; 1638 return 0;
1141 1639
1142reset: 1640reset:
1143 tcp_v6_send_reset(skb); 1641 tcp_v6_send_reset(sk, skb);
1144discard: 1642discard:
1145 if (opt_skb) 1643 if (opt_skb)
1146 __kfree_skb(opt_skb); 1644 __kfree_skb(opt_skb);
@@ -1265,7 +1763,7 @@ no_tcp_socket:
1265bad_packet: 1763bad_packet:
1266 TCP_INC_STATS_BH(TCP_MIB_INERRS); 1764 TCP_INC_STATS_BH(TCP_MIB_INERRS);
1267 } else { 1765 } else {
1268 tcp_v6_send_reset(skb); 1766 tcp_v6_send_reset(NULL, skb);
1269 } 1767 }
1270 1768
1271discard_it: 1769discard_it:
@@ -1344,6 +1842,15 @@ static struct inet_connection_sock_af_ops ipv6_specific = {
1344#endif 1842#endif
1345}; 1843};
1346 1844
1845#ifdef CONFIG_TCP_MD5SIG
1846static struct tcp_sock_af_ops tcp_sock_ipv6_specific = {
1847 .md5_lookup = tcp_v6_md5_lookup,
1848 .calc_md5_hash = tcp_v6_calc_md5_hash,
1849 .md5_add = tcp_v6_md5_add_func,
1850 .md5_parse = tcp_v6_parse_md5_keys,
1851};
1852#endif
1853
1347/* 1854/*
1348 * TCP over IPv4 via INET6 API 1855 * TCP over IPv4 via INET6 API
1349 */ 1856 */
@@ -1366,6 +1873,15 @@ static struct inet_connection_sock_af_ops ipv6_mapped = {
1366#endif 1873#endif
1367}; 1874};
1368 1875
1876#ifdef CONFIG_TCP_MD5SIG
1877static struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific = {
1878 .md5_lookup = tcp_v4_md5_lookup,
1879 .calc_md5_hash = tcp_v4_calc_md5_hash,
1880 .md5_add = tcp_v6_md5_add_func,
1881 .md5_parse = tcp_v6_parse_md5_keys,
1882};
1883#endif
1884
1369/* NOTE: A lot of things set to zero explicitly by call to 1885/* NOTE: A lot of things set to zero explicitly by call to
1370 * sk_alloc() so need not be done here. 1886 * sk_alloc() so need not be done here.
1371 */ 1887 */
@@ -1405,6 +1921,10 @@ static int tcp_v6_init_sock(struct sock *sk)
1405 sk->sk_write_space = sk_stream_write_space; 1921 sk->sk_write_space = sk_stream_write_space;
1406 sock_set_flag(sk, SOCK_USE_WRITE_QUEUE); 1922 sock_set_flag(sk, SOCK_USE_WRITE_QUEUE);
1407 1923
1924#ifdef CONFIG_TCP_MD5SIG
1925 tp->af_specific = &tcp_sock_ipv6_specific;
1926#endif
1927
1408 sk->sk_sndbuf = sysctl_tcp_wmem[1]; 1928 sk->sk_sndbuf = sysctl_tcp_wmem[1];
1409 sk->sk_rcvbuf = sysctl_tcp_rmem[1]; 1929 sk->sk_rcvbuf = sysctl_tcp_rmem[1];
1410 1930
@@ -1415,6 +1935,11 @@ static int tcp_v6_init_sock(struct sock *sk)
1415 1935
1416static int tcp_v6_destroy_sock(struct sock *sk) 1936static int tcp_v6_destroy_sock(struct sock *sk)
1417{ 1937{
1938#ifdef CONFIG_TCP_MD5SIG
1939 /* Clean up the MD5 key list */
1940 if (tcp_sk(sk)->md5sig_info)
1941 tcp_v6_clear_md5_list(sk);
1942#endif
1418 tcp_v4_destroy_sock(sk); 1943 tcp_v4_destroy_sock(sk);
1419 return inet6_destroy_sock(sk); 1944 return inet6_destroy_sock(sk);
1420} 1945}
diff --git a/net/ipv6/tunnel6.c b/net/ipv6/tunnel6.c
index 0ef9a35798..918d07dd12 100644
--- a/net/ipv6/tunnel6.c
+++ b/net/ipv6/tunnel6.c
@@ -104,7 +104,7 @@ drop:
104} 104}
105 105
106static void tunnel6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 106static void tunnel6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
107 int type, int code, int offset, __u32 info) 107 int type, int code, int offset, __be32 info)
108{ 108{
109 struct xfrm6_tunnel *handler; 109 struct xfrm6_tunnel *handler;
110 110
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index c83f23e51c..f52a5c3cc0 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -38,26 +38,18 @@
38#include <linux/skbuff.h> 38#include <linux/skbuff.h>
39#include <asm/uaccess.h> 39#include <asm/uaccess.h>
40 40
41#include <net/sock.h>
42#include <net/snmp.h>
43
44#include <net/ipv6.h>
45#include <net/ndisc.h> 41#include <net/ndisc.h>
46#include <net/protocol.h> 42#include <net/protocol.h>
47#include <net/transp_v6.h> 43#include <net/transp_v6.h>
48#include <net/ip6_route.h> 44#include <net/ip6_route.h>
49#include <net/addrconf.h>
50#include <net/ip.h>
51#include <net/udp.h>
52#include <net/raw.h> 45#include <net/raw.h>
53#include <net/inet_common.h>
54#include <net/tcp_states.h> 46#include <net/tcp_states.h>
55
56#include <net/ip6_checksum.h> 47#include <net/ip6_checksum.h>
57#include <net/xfrm.h> 48#include <net/xfrm.h>
58 49
59#include <linux/proc_fs.h> 50#include <linux/proc_fs.h>
60#include <linux/seq_file.h> 51#include <linux/seq_file.h>
52#include "udp_impl.h"
61 53
62DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly; 54DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6) __read_mostly;
63 55
@@ -66,23 +58,9 @@ static inline int udp_v6_get_port(struct sock *sk, unsigned short snum)
66 return udp_get_port(sk, snum, ipv6_rcv_saddr_equal); 58 return udp_get_port(sk, snum, ipv6_rcv_saddr_equal);
67} 59}
68 60
69static void udp_v6_hash(struct sock *sk) 61static struct sock *__udp6_lib_lookup(struct in6_addr *saddr, __be16 sport,
70{ 62 struct in6_addr *daddr, __be16 dport,
71 BUG(); 63 int dif, struct hlist_head udptable[])
72}
73
74static void udp_v6_unhash(struct sock *sk)
75{
76 write_lock_bh(&udp_hash_lock);
77 if (sk_del_node_init(sk)) {
78 inet_sk(sk)->num = 0;
79 sock_prot_dec_use(sk->sk_prot);
80 }
81 write_unlock_bh(&udp_hash_lock);
82}
83
84static struct sock *udp_v6_lookup(struct in6_addr *saddr, u16 sport,
85 struct in6_addr *daddr, u16 dport, int dif)
86{ 64{
87 struct sock *sk, *result = NULL; 65 struct sock *sk, *result = NULL;
88 struct hlist_node *node; 66 struct hlist_node *node;
@@ -90,7 +68,7 @@ static struct sock *udp_v6_lookup(struct in6_addr *saddr, u16 sport,
90 int badness = -1; 68 int badness = -1;
91 69
92 read_lock(&udp_hash_lock); 70 read_lock(&udp_hash_lock);
93 sk_for_each(sk, node, &udp_hash[hnum & (UDP_HTABLE_SIZE - 1)]) { 71 sk_for_each(sk, node, &udptable[hnum & (UDP_HTABLE_SIZE - 1)]) {
94 struct inet_sock *inet = inet_sk(sk); 72 struct inet_sock *inet = inet_sk(sk);
95 73
96 if (inet->num == hnum && sk->sk_family == PF_INET6) { 74 if (inet->num == hnum && sk->sk_family == PF_INET6) {
@@ -132,20 +110,11 @@ static struct sock *udp_v6_lookup(struct in6_addr *saddr, u16 sport,
132} 110}
133 111
134/* 112/*
135 *
136 */
137
138static void udpv6_close(struct sock *sk, long timeout)
139{
140 sk_common_release(sk);
141}
142
143/*
144 * This should be easy, if there is something there we 113 * This should be easy, if there is something there we
145 * return it, otherwise we block. 114 * return it, otherwise we block.
146 */ 115 */
147 116
148static int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk, 117int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
149 struct msghdr *msg, size_t len, 118 struct msghdr *msg, size_t len,
150 int noblock, int flags, int *addr_len) 119 int noblock, int flags, int *addr_len)
151{ 120{
@@ -153,7 +122,7 @@ static int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
153 struct inet_sock *inet = inet_sk(sk); 122 struct inet_sock *inet = inet_sk(sk);
154 struct sk_buff *skb; 123 struct sk_buff *skb;
155 size_t copied; 124 size_t copied;
156 int err; 125 int err, copy_only, is_udplite = IS_UDPLITE(sk);
157 126
158 if (addr_len) 127 if (addr_len)
159 *addr_len=sizeof(struct sockaddr_in6); 128 *addr_len=sizeof(struct sockaddr_in6);
@@ -172,15 +141,21 @@ try_again:
172 msg->msg_flags |= MSG_TRUNC; 141 msg->msg_flags |= MSG_TRUNC;
173 } 142 }
174 143
175 if (skb->ip_summed==CHECKSUM_UNNECESSARY) { 144 /*
176 err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov, 145 * Decide whether to checksum and/or copy data.
177 copied); 146 */
178 } else if (msg->msg_flags&MSG_TRUNC) { 147 copy_only = (skb->ip_summed==CHECKSUM_UNNECESSARY);
179 if (__skb_checksum_complete(skb)) 148
149 if (is_udplite || (!copy_only && msg->msg_flags&MSG_TRUNC)) {
150 if (__udp_lib_checksum_complete(skb))
180 goto csum_copy_err; 151 goto csum_copy_err;
181 err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov, 152 copy_only = 1;
182 copied); 153 }
183 } else { 154
155 if (copy_only)
156 err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
157 msg->msg_iov, copied );
158 else {
184 err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov); 159 err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov);
185 if (err == -EINVAL) 160 if (err == -EINVAL)
186 goto csum_copy_err; 161 goto csum_copy_err;
@@ -231,14 +206,15 @@ csum_copy_err:
231 skb_kill_datagram(sk, skb, flags); 206 skb_kill_datagram(sk, skb, flags);
232 207
233 if (flags & MSG_DONTWAIT) { 208 if (flags & MSG_DONTWAIT) {
234 UDP6_INC_STATS_USER(UDP_MIB_INERRORS); 209 UDP6_INC_STATS_USER(UDP_MIB_INERRORS, is_udplite);
235 return -EAGAIN; 210 return -EAGAIN;
236 } 211 }
237 goto try_again; 212 goto try_again;
238} 213}
239 214
240static void udpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 215void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
241 int type, int code, int offset, __u32 info) 216 int type, int code, int offset, __be32 info,
217 struct hlist_head udptable[] )
242{ 218{
243 struct ipv6_pinfo *np; 219 struct ipv6_pinfo *np;
244 struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data; 220 struct ipv6hdr *hdr = (struct ipv6hdr*)skb->data;
@@ -248,8 +224,8 @@ static void udpv6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
248 struct sock *sk; 224 struct sock *sk;
249 int err; 225 int err;
250 226
251 sk = udp_v6_lookup(daddr, uh->dest, saddr, uh->source, inet6_iif(skb)); 227 sk = __udp6_lib_lookup(daddr, uh->dest,
252 228 saddr, uh->source, inet6_iif(skb), udptable);
253 if (sk == NULL) 229 if (sk == NULL)
254 return; 230 return;
255 231
@@ -270,36 +246,60 @@ out:
270 sock_put(sk); 246 sock_put(sk);
271} 247}
272 248
273static inline int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb) 249static __inline__ void udpv6_err(struct sk_buff *skb,
250 struct inet6_skb_parm *opt, int type,
251 int code, int offset, __be32 info )
252{
253 return __udp6_lib_err(skb, opt, type, code, offset, info, udp_hash);
254}
255
256int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
274{ 257{
258 struct udp_sock *up = udp_sk(sk);
275 int rc; 259 int rc;
276 260
277 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) { 261 if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
278 kfree_skb(skb); 262 goto drop;
279 return -1;
280 }
281 263
282 if (skb_checksum_complete(skb)) { 264 /*
283 UDP6_INC_STATS_BH(UDP_MIB_INERRORS); 265 * UDP-Lite specific tests, ignored on UDP sockets (see net/ipv4/udp.c).
284 kfree_skb(skb); 266 */
285 return 0; 267 if ((up->pcflag & UDPLITE_RECV_CC) && UDP_SKB_CB(skb)->partial_cov) {
268
269 if (up->pcrlen == 0) { /* full coverage was set */
270 LIMIT_NETDEBUG(KERN_WARNING "UDPLITE6: partial coverage"
271 " %d while full coverage %d requested\n",
272 UDP_SKB_CB(skb)->cscov, skb->len);
273 goto drop;
274 }
275 if (UDP_SKB_CB(skb)->cscov < up->pcrlen) {
276 LIMIT_NETDEBUG(KERN_WARNING "UDPLITE6: coverage %d "
277 "too small, need min %d\n",
278 UDP_SKB_CB(skb)->cscov, up->pcrlen);
279 goto drop;
280 }
286 } 281 }
287 282
283 if (udp_lib_checksum_complete(skb))
284 goto drop;
285
288 if ((rc = sock_queue_rcv_skb(sk,skb)) < 0) { 286 if ((rc = sock_queue_rcv_skb(sk,skb)) < 0) {
289 /* Note that an ENOMEM error is charged twice */ 287 /* Note that an ENOMEM error is charged twice */
290 if (rc == -ENOMEM) 288 if (rc == -ENOMEM)
291 UDP6_INC_STATS_BH(UDP_MIB_RCVBUFERRORS); 289 UDP6_INC_STATS_BH(UDP_MIB_RCVBUFERRORS, up->pcflag);
292 UDP6_INC_STATS_BH(UDP_MIB_INERRORS); 290 goto drop;
293 kfree_skb(skb);
294 return 0;
295 } 291 }
296 UDP6_INC_STATS_BH(UDP_MIB_INDATAGRAMS); 292 UDP6_INC_STATS_BH(UDP_MIB_INDATAGRAMS, up->pcflag);
297 return 0; 293 return 0;
294drop:
295 UDP6_INC_STATS_BH(UDP_MIB_INERRORS, up->pcflag);
296 kfree_skb(skb);
297 return -1;
298} 298}
299 299
300static struct sock *udp_v6_mcast_next(struct sock *sk, 300static struct sock *udp_v6_mcast_next(struct sock *sk,
301 u16 loc_port, struct in6_addr *loc_addr, 301 __be16 loc_port, struct in6_addr *loc_addr,
302 u16 rmt_port, struct in6_addr *rmt_addr, 302 __be16 rmt_port, struct in6_addr *rmt_addr,
303 int dif) 303 int dif)
304{ 304{
305 struct hlist_node *node; 305 struct hlist_node *node;
@@ -338,15 +338,15 @@ static struct sock *udp_v6_mcast_next(struct sock *sk,
338 * Note: called only from the BH handler context, 338 * Note: called only from the BH handler context,
339 * so we don't need to lock the hashes. 339 * so we don't need to lock the hashes.
340 */ 340 */
341static void udpv6_mcast_deliver(struct udphdr *uh, 341static int __udp6_lib_mcast_deliver(struct sk_buff *skb, struct in6_addr *saddr,
342 struct in6_addr *saddr, struct in6_addr *daddr, 342 struct in6_addr *daddr, struct hlist_head udptable[])
343 struct sk_buff *skb)
344{ 343{
345 struct sock *sk, *sk2; 344 struct sock *sk, *sk2;
345 const struct udphdr *uh = skb->h.uh;
346 int dif; 346 int dif;
347 347
348 read_lock(&udp_hash_lock); 348 read_lock(&udp_hash_lock);
349 sk = sk_head(&udp_hash[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]); 349 sk = sk_head(&udptable[ntohs(uh->dest) & (UDP_HTABLE_SIZE - 1)]);
350 dif = inet6_iif(skb); 350 dif = inet6_iif(skb);
351 sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif); 351 sk = udp_v6_mcast_next(sk, uh->dest, daddr, uh->source, saddr, dif);
352 if (!sk) { 352 if (!sk) {
@@ -364,9 +364,35 @@ static void udpv6_mcast_deliver(struct udphdr *uh,
364 udpv6_queue_rcv_skb(sk, skb); 364 udpv6_queue_rcv_skb(sk, skb);
365out: 365out:
366 read_unlock(&udp_hash_lock); 366 read_unlock(&udp_hash_lock);
367 return 0;
368}
369
370static inline int udp6_csum_init(struct sk_buff *skb, struct udphdr *uh)
371
372{
373 if (uh->check == 0) {
374 /* RFC 2460 section 8.1 says that we SHOULD log
375 this error. Well, it is reasonable.
376 */
377 LIMIT_NETDEBUG(KERN_INFO "IPv6: udp checksum is 0\n");
378 return 1;
379 }
380 if (skb->ip_summed == CHECKSUM_COMPLETE &&
381 !csum_ipv6_magic(&skb->nh.ipv6h->saddr, &skb->nh.ipv6h->daddr,
382 skb->len, IPPROTO_UDP, skb->csum ))
383 skb->ip_summed = CHECKSUM_UNNECESSARY;
384
385 if (skb->ip_summed != CHECKSUM_UNNECESSARY)
386 skb->csum = ~csum_unfold(csum_ipv6_magic(&skb->nh.ipv6h->saddr,
387 &skb->nh.ipv6h->daddr,
388 skb->len, IPPROTO_UDP,
389 0));
390
391 return (UDP_SKB_CB(skb)->partial_cov = 0);
367} 392}
368 393
369static int udpv6_rcv(struct sk_buff **pskb) 394int __udp6_lib_rcv(struct sk_buff **pskb, struct hlist_head udptable[],
395 int is_udplite)
370{ 396{
371 struct sk_buff *skb = *pskb; 397 struct sk_buff *skb = *pskb;
372 struct sock *sk; 398 struct sock *sk;
@@ -383,44 +409,39 @@ static int udpv6_rcv(struct sk_buff **pskb)
383 uh = skb->h.uh; 409 uh = skb->h.uh;
384 410
385 ulen = ntohs(uh->len); 411 ulen = ntohs(uh->len);
412 if (ulen > skb->len)
413 goto short_packet;
386 414
387 /* Check for jumbo payload */ 415 if(! is_udplite ) { /* UDP validates ulen. */
388 if (ulen == 0)
389 ulen = skb->len;
390 416
391 if (ulen > skb->len || ulen < sizeof(*uh)) 417 /* Check for jumbo payload */
392 goto short_packet; 418 if (ulen == 0)
419 ulen = skb->len;
393 420
394 if (uh->check == 0) { 421 if (ulen < sizeof(*uh))
395 /* RFC 2460 section 8.1 says that we SHOULD log 422 goto short_packet;
396 this error. Well, it is reasonable.
397 */
398 LIMIT_NETDEBUG(KERN_INFO "IPv6: udp checksum is 0\n");
399 goto discard;
400 }
401 423
402 if (ulen < skb->len) { 424 if (ulen < skb->len) {
403 if (pskb_trim_rcsum(skb, ulen)) 425 if (pskb_trim_rcsum(skb, ulen))
404 goto discard; 426 goto short_packet;
405 saddr = &skb->nh.ipv6h->saddr; 427 saddr = &skb->nh.ipv6h->saddr;
406 daddr = &skb->nh.ipv6h->daddr; 428 daddr = &skb->nh.ipv6h->daddr;
407 uh = skb->h.uh; 429 uh = skb->h.uh;
408 } 430 }
409 431
410 if (skb->ip_summed == CHECKSUM_COMPLETE && 432 if (udp6_csum_init(skb, uh))
411 !csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, skb->csum)) 433 goto discard;
412 skb->ip_summed = CHECKSUM_UNNECESSARY;
413 434
414 if (skb->ip_summed != CHECKSUM_UNNECESSARY) 435 } else { /* UDP-Lite validates cscov. */
415 skb->csum = ~csum_ipv6_magic(saddr, daddr, ulen, IPPROTO_UDP, 0); 436 if (udplite6_csum_init(skb, uh))
437 goto discard;
438 }
416 439
417 /* 440 /*
418 * Multicast receive code 441 * Multicast receive code
419 */ 442 */
420 if (ipv6_addr_is_multicast(daddr)) { 443 if (ipv6_addr_is_multicast(daddr))
421 udpv6_mcast_deliver(uh, saddr, daddr, skb); 444 return __udp6_lib_mcast_deliver(skb, saddr, daddr, udptable);
422 return 0;
423 }
424 445
425 /* Unicast */ 446 /* Unicast */
426 447
@@ -428,15 +449,16 @@ static int udpv6_rcv(struct sk_buff **pskb)
428 * check socket cache ... must talk to Alan about his plans 449 * check socket cache ... must talk to Alan about his plans
429 * for sock caches... i'll skip this for now. 450 * for sock caches... i'll skip this for now.
430 */ 451 */
431 sk = udp_v6_lookup(saddr, uh->source, daddr, uh->dest, inet6_iif(skb)); 452 sk = __udp6_lib_lookup(saddr, uh->source,
453 daddr, uh->dest, inet6_iif(skb), udptable);
432 454
433 if (sk == NULL) { 455 if (sk == NULL) {
434 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) 456 if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
435 goto discard; 457 goto discard;
436 458
437 if (skb_checksum_complete(skb)) 459 if (udp_lib_checksum_complete(skb))
438 goto discard; 460 goto discard;
439 UDP6_INC_STATS_BH(UDP_MIB_NOPORTS); 461 UDP6_INC_STATS_BH(UDP_MIB_NOPORTS, is_udplite);
440 462
441 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, dev); 463 icmpv6_send(skb, ICMPV6_DEST_UNREACH, ICMPV6_PORT_UNREACH, 0, dev);
442 464
@@ -451,14 +473,20 @@ static int udpv6_rcv(struct sk_buff **pskb)
451 return(0); 473 return(0);
452 474
453short_packet: 475short_packet:
454 if (net_ratelimit()) 476 LIMIT_NETDEBUG(KERN_DEBUG "UDP%sv6: short packet: %d/%u\n",
455 printk(KERN_DEBUG "UDP: short packet: %d/%u\n", ulen, skb->len); 477 is_udplite? "-Lite" : "", ulen, skb->len);
456 478
457discard: 479discard:
458 UDP6_INC_STATS_BH(UDP_MIB_INERRORS); 480 UDP6_INC_STATS_BH(UDP_MIB_INERRORS, is_udplite);
459 kfree_skb(skb); 481 kfree_skb(skb);
460 return(0); 482 return(0);
461} 483}
484
485static __inline__ int udpv6_rcv(struct sk_buff **pskb)
486{
487 return __udp6_lib_rcv(pskb, udp_hash, 0);
488}
489
462/* 490/*
463 * Throw away all pending data and cancel the corking. Socket is locked. 491 * Throw away all pending data and cancel the corking. Socket is locked.
464 */ 492 */
@@ -477,13 +505,15 @@ static void udp_v6_flush_pending_frames(struct sock *sk)
477 * Sending 505 * Sending
478 */ 506 */
479 507
480static int udp_v6_push_pending_frames(struct sock *sk, struct udp_sock *up) 508static int udp_v6_push_pending_frames(struct sock *sk)
481{ 509{
482 struct sk_buff *skb; 510 struct sk_buff *skb;
483 struct udphdr *uh; 511 struct udphdr *uh;
512 struct udp_sock *up = udp_sk(sk);
484 struct inet_sock *inet = inet_sk(sk); 513 struct inet_sock *inet = inet_sk(sk);
485 struct flowi *fl = &inet->cork.fl; 514 struct flowi *fl = &inet->cork.fl;
486 int err = 0; 515 int err = 0;
516 __wsum csum = 0;
487 517
488 /* Grab the skbuff where UDP header space exists. */ 518 /* Grab the skbuff where UDP header space exists. */
489 if ((skb = skb_peek(&sk->sk_write_queue)) == NULL) 519 if ((skb = skb_peek(&sk->sk_write_queue)) == NULL)
@@ -498,35 +528,17 @@ static int udp_v6_push_pending_frames(struct sock *sk, struct udp_sock *up)
498 uh->len = htons(up->len); 528 uh->len = htons(up->len);
499 uh->check = 0; 529 uh->check = 0;
500 530
501 if (sk->sk_no_check == UDP_CSUM_NOXMIT) { 531 if (up->pcflag)
502 skb->ip_summed = CHECKSUM_NONE; 532 csum = udplite_csum_outgoing(sk, skb);
503 goto send; 533 else
504 } 534 csum = udp_csum_outgoing(sk, skb);
505
506 if (skb_queue_len(&sk->sk_write_queue) == 1) {
507 skb->csum = csum_partial((char *)uh,
508 sizeof(struct udphdr), skb->csum);
509 uh->check = csum_ipv6_magic(&fl->fl6_src,
510 &fl->fl6_dst,
511 up->len, fl->proto, skb->csum);
512 } else {
513 u32 tmp_csum = 0;
514
515 skb_queue_walk(&sk->sk_write_queue, skb) {
516 tmp_csum = csum_add(tmp_csum, skb->csum);
517 }
518 tmp_csum = csum_partial((char *)uh,
519 sizeof(struct udphdr), tmp_csum);
520 tmp_csum = csum_ipv6_magic(&fl->fl6_src,
521 &fl->fl6_dst,
522 up->len, fl->proto, tmp_csum);
523 uh->check = tmp_csum;
524 535
525 } 536 /* add protocol-dependent pseudo-header */
537 uh->check = csum_ipv6_magic(&fl->fl6_src, &fl->fl6_dst,
538 up->len, fl->proto, csum );
526 if (uh->check == 0) 539 if (uh->check == 0)
527 uh->check = -1; 540 uh->check = CSUM_MANGLED_0;
528 541
529send:
530 err = ip6_push_pending_frames(sk); 542 err = ip6_push_pending_frames(sk);
531out: 543out:
532 up->len = 0; 544 up->len = 0;
@@ -534,7 +546,7 @@ out:
534 return err; 546 return err;
535} 547}
536 548
537static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk, 549int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
538 struct msghdr *msg, size_t len) 550 struct msghdr *msg, size_t len)
539{ 551{
540 struct ipv6_txoptions opt_space; 552 struct ipv6_txoptions opt_space;
@@ -554,6 +566,8 @@ static int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
554 int corkreq = up->corkflag || msg->msg_flags&MSG_MORE; 566 int corkreq = up->corkflag || msg->msg_flags&MSG_MORE;
555 int err; 567 int err;
556 int connected = 0; 568 int connected = 0;
569 int is_udplite = up->pcflag;
570 int (*getfrag)(void *, char *, int, int, int, struct sk_buff *);
557 571
558 /* destination address check */ 572 /* destination address check */
559 if (sin6) { 573 if (sin6) {
@@ -694,7 +708,7 @@ do_udp_sendmsg:
694 opt = fl6_merge_options(&opt_space, flowlabel, opt); 708 opt = fl6_merge_options(&opt_space, flowlabel, opt);
695 opt = ipv6_fixup_options(&opt_space, opt); 709 opt = ipv6_fixup_options(&opt_space, opt);
696 710
697 fl.proto = IPPROTO_UDP; 711 fl.proto = sk->sk_protocol;
698 ipv6_addr_copy(&fl.fl6_dst, daddr); 712 ipv6_addr_copy(&fl.fl6_dst, daddr);
699 if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr)) 713 if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr))
700 ipv6_addr_copy(&fl.fl6_src, &np->saddr); 714 ipv6_addr_copy(&fl.fl6_src, &np->saddr);
@@ -761,14 +775,15 @@ back_from_confirm:
761 775
762do_append_data: 776do_append_data:
763 up->len += ulen; 777 up->len += ulen;
764 err = ip6_append_data(sk, ip_generic_getfrag, msg->msg_iov, ulen, 778 getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag;
779 err = ip6_append_data(sk, getfrag, msg->msg_iov, ulen,
765 sizeof(struct udphdr), hlimit, tclass, opt, &fl, 780 sizeof(struct udphdr), hlimit, tclass, opt, &fl,
766 (struct rt6_info*)dst, 781 (struct rt6_info*)dst,
767 corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags); 782 corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags);
768 if (err) 783 if (err)
769 udp_v6_flush_pending_frames(sk); 784 udp_v6_flush_pending_frames(sk);
770 else if (!corkreq) 785 else if (!corkreq)
771 err = udp_v6_push_pending_frames(sk, up); 786 err = udp_v6_push_pending_frames(sk);
772 else if (unlikely(skb_queue_empty(&sk->sk_write_queue))) 787 else if (unlikely(skb_queue_empty(&sk->sk_write_queue)))
773 up->pending = 0; 788 up->pending = 0;
774 789
@@ -793,7 +808,7 @@ do_append_data:
793out: 808out:
794 fl6_sock_release(flowlabel); 809 fl6_sock_release(flowlabel);
795 if (!err) { 810 if (!err) {
796 UDP6_INC_STATS_USER(UDP_MIB_OUTDATAGRAMS); 811 UDP6_INC_STATS_USER(UDP_MIB_OUTDATAGRAMS, is_udplite);
797 return len; 812 return len;
798 } 813 }
799 /* 814 /*
@@ -804,7 +819,7 @@ out:
804 * seems like overkill. 819 * seems like overkill.
805 */ 820 */
806 if (err == -ENOBUFS || test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) { 821 if (err == -ENOBUFS || test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) {
807 UDP6_INC_STATS_USER(UDP_MIB_SNDBUFERRORS); 822 UDP6_INC_STATS_USER(UDP_MIB_SNDBUFERRORS, is_udplite);
808 } 823 }
809 return err; 824 return err;
810 825
@@ -816,7 +831,7 @@ do_confirm:
816 goto out; 831 goto out;
817} 832}
818 833
819static int udpv6_destroy_sock(struct sock *sk) 834int udpv6_destroy_sock(struct sock *sk)
820{ 835{
821 lock_sock(sk); 836 lock_sock(sk);
822 udp_v6_flush_pending_frames(sk); 837 udp_v6_flush_pending_frames(sk);
@@ -830,119 +845,41 @@ static int udpv6_destroy_sock(struct sock *sk)
830/* 845/*
831 * Socket option code for UDP 846 * Socket option code for UDP
832 */ 847 */
833static int do_udpv6_setsockopt(struct sock *sk, int level, int optname, 848int udpv6_setsockopt(struct sock *sk, int level, int optname,
834 char __user *optval, int optlen) 849 char __user *optval, int optlen)
835{
836 struct udp_sock *up = udp_sk(sk);
837 int val;
838 int err = 0;
839
840 if(optlen<sizeof(int))
841 return -EINVAL;
842
843 if (get_user(val, (int __user *)optval))
844 return -EFAULT;
845
846 switch(optname) {
847 case UDP_CORK:
848 if (val != 0) {
849 up->corkflag = 1;
850 } else {
851 up->corkflag = 0;
852 lock_sock(sk);
853 udp_v6_push_pending_frames(sk, up);
854 release_sock(sk);
855 }
856 break;
857
858 case UDP_ENCAP:
859 switch (val) {
860 case 0:
861 up->encap_type = val;
862 break;
863 default:
864 err = -ENOPROTOOPT;
865 break;
866 }
867 break;
868
869 default:
870 err = -ENOPROTOOPT;
871 break;
872 };
873
874 return err;
875}
876
877static int udpv6_setsockopt(struct sock *sk, int level, int optname,
878 char __user *optval, int optlen)
879{ 850{
880 if (level != SOL_UDP) 851 if (level == SOL_UDP || level == SOL_UDPLITE)
881 return ipv6_setsockopt(sk, level, optname, optval, optlen); 852 return udp_lib_setsockopt(sk, level, optname, optval, optlen,
882 return do_udpv6_setsockopt(sk, level, optname, optval, optlen); 853 udp_v6_push_pending_frames);
854 return ipv6_setsockopt(sk, level, optname, optval, optlen);
883} 855}
884 856
885#ifdef CONFIG_COMPAT 857#ifdef CONFIG_COMPAT
886static int compat_udpv6_setsockopt(struct sock *sk, int level, int optname, 858int compat_udpv6_setsockopt(struct sock *sk, int level, int optname,
887 char __user *optval, int optlen) 859 char __user *optval, int optlen)
888{ 860{
889 if (level != SOL_UDP) 861 if (level == SOL_UDP || level == SOL_UDPLITE)
890 return compat_ipv6_setsockopt(sk, level, optname, 862 return udp_lib_setsockopt(sk, level, optname, optval, optlen,
891 optval, optlen); 863 udp_v6_push_pending_frames);
892 return do_udpv6_setsockopt(sk, level, optname, optval, optlen); 864 return compat_ipv6_setsockopt(sk, level, optname, optval, optlen);
893} 865}
894#endif 866#endif
895 867
896static int do_udpv6_getsockopt(struct sock *sk, int level, int optname, 868int udpv6_getsockopt(struct sock *sk, int level, int optname,
897 char __user *optval, int __user *optlen) 869 char __user *optval, int __user *optlen)
898{
899 struct udp_sock *up = udp_sk(sk);
900 int val, len;
901
902 if(get_user(len,optlen))
903 return -EFAULT;
904
905 len = min_t(unsigned int, len, sizeof(int));
906
907 if(len < 0)
908 return -EINVAL;
909
910 switch(optname) {
911 case UDP_CORK:
912 val = up->corkflag;
913 break;
914
915 case UDP_ENCAP:
916 val = up->encap_type;
917 break;
918
919 default:
920 return -ENOPROTOOPT;
921 };
922
923 if(put_user(len, optlen))
924 return -EFAULT;
925 if(copy_to_user(optval, &val,len))
926 return -EFAULT;
927 return 0;
928}
929
930static int udpv6_getsockopt(struct sock *sk, int level, int optname,
931 char __user *optval, int __user *optlen)
932{ 870{
933 if (level != SOL_UDP) 871 if (level == SOL_UDP || level == SOL_UDPLITE)
934 return ipv6_getsockopt(sk, level, optname, optval, optlen); 872 return udp_lib_getsockopt(sk, level, optname, optval, optlen);
935 return do_udpv6_getsockopt(sk, level, optname, optval, optlen); 873 return ipv6_getsockopt(sk, level, optname, optval, optlen);
936} 874}
937 875
938#ifdef CONFIG_COMPAT 876#ifdef CONFIG_COMPAT
939static int compat_udpv6_getsockopt(struct sock *sk, int level, int optname, 877int compat_udpv6_getsockopt(struct sock *sk, int level, int optname,
940 char __user *optval, int __user *optlen) 878 char __user *optval, int __user *optlen)
941{ 879{
942 if (level != SOL_UDP) 880 if (level == SOL_UDP || level == SOL_UDPLITE)
943 return compat_ipv6_getsockopt(sk, level, optname, 881 return udp_lib_getsockopt(sk, level, optname, optval, optlen);
944 optval, optlen); 882 return compat_ipv6_getsockopt(sk, level, optname, optval, optlen);
945 return do_udpv6_getsockopt(sk, level, optname, optval, optlen);
946} 883}
947#endif 884#endif
948 885
@@ -983,7 +920,7 @@ static void udp6_sock_seq_show(struct seq_file *seq, struct sock *sp, int bucket
983 atomic_read(&sp->sk_refcnt), sp); 920 atomic_read(&sp->sk_refcnt), sp);
984} 921}
985 922
986static int udp6_seq_show(struct seq_file *seq, void *v) 923int udp6_seq_show(struct seq_file *seq, void *v)
987{ 924{
988 if (v == SEQ_START_TOKEN) 925 if (v == SEQ_START_TOKEN)
989 seq_printf(seq, 926 seq_printf(seq,
@@ -1002,6 +939,7 @@ static struct udp_seq_afinfo udp6_seq_afinfo = {
1002 .owner = THIS_MODULE, 939 .owner = THIS_MODULE,
1003 .name = "udp6", 940 .name = "udp6",
1004 .family = AF_INET6, 941 .family = AF_INET6,
942 .hashtable = udp_hash,
1005 .seq_show = udp6_seq_show, 943 .seq_show = udp6_seq_show,
1006 .seq_fops = &udp6_seq_fops, 944 .seq_fops = &udp6_seq_fops,
1007}; 945};
@@ -1021,7 +959,7 @@ void udp6_proc_exit(void) {
1021struct proto udpv6_prot = { 959struct proto udpv6_prot = {
1022 .name = "UDPv6", 960 .name = "UDPv6",
1023 .owner = THIS_MODULE, 961 .owner = THIS_MODULE,
1024 .close = udpv6_close, 962 .close = udp_lib_close,
1025 .connect = ip6_datagram_connect, 963 .connect = ip6_datagram_connect,
1026 .disconnect = udp_disconnect, 964 .disconnect = udp_disconnect,
1027 .ioctl = udp_ioctl, 965 .ioctl = udp_ioctl,
@@ -1031,8 +969,8 @@ struct proto udpv6_prot = {
1031 .sendmsg = udpv6_sendmsg, 969 .sendmsg = udpv6_sendmsg,
1032 .recvmsg = udpv6_recvmsg, 970 .recvmsg = udpv6_recvmsg,
1033 .backlog_rcv = udpv6_queue_rcv_skb, 971 .backlog_rcv = udpv6_queue_rcv_skb,
1034 .hash = udp_v6_hash, 972 .hash = udp_lib_hash,
1035 .unhash = udp_v6_unhash, 973 .unhash = udp_lib_unhash,
1036 .get_port = udp_v6_get_port, 974 .get_port = udp_v6_get_port,
1037 .obj_size = sizeof(struct udp6_sock), 975 .obj_size = sizeof(struct udp6_sock),
1038#ifdef CONFIG_COMPAT 976#ifdef CONFIG_COMPAT
diff --git a/net/ipv6/udp_impl.h b/net/ipv6/udp_impl.h
new file mode 100644
index 0000000000..ec98788991
--- /dev/null
+++ b/net/ipv6/udp_impl.h
@@ -0,0 +1,34 @@
1#ifndef _UDP6_IMPL_H
2#define _UDP6_IMPL_H
3#include <net/udp.h>
4#include <net/udplite.h>
5#include <net/protocol.h>
6#include <net/addrconf.h>
7#include <net/inet_common.h>
8
9extern int __udp6_lib_rcv(struct sk_buff **, struct hlist_head [], int );
10extern void __udp6_lib_err(struct sk_buff *, struct inet6_skb_parm *,
11 int , int , int , __be32 , struct hlist_head []);
12
13extern int udpv6_getsockopt(struct sock *sk, int level, int optname,
14 char __user *optval, int __user *optlen);
15extern int udpv6_setsockopt(struct sock *sk, int level, int optname,
16 char __user *optval, int optlen);
17#ifdef CONFIG_COMPAT
18extern int compat_udpv6_setsockopt(struct sock *sk, int level, int optname,
19 char __user *optval, int optlen);
20extern int compat_udpv6_getsockopt(struct sock *sk, int level, int optname,
21 char __user *optval, int __user *optlen);
22#endif
23extern int udpv6_sendmsg(struct kiocb *iocb, struct sock *sk,
24 struct msghdr *msg, size_t len);
25extern int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
26 struct msghdr *msg, size_t len,
27 int noblock, int flags, int *addr_len);
28extern int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb);
29extern int udpv6_destroy_sock(struct sock *sk);
30
31#ifdef CONFIG_PROC_FS
32extern int udp6_seq_show(struct seq_file *seq, void *v);
33#endif
34#endif /* _UDP6_IMPL_H */
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c
new file mode 100644
index 0000000000..629f97162f
--- /dev/null
+++ b/net/ipv6/udplite.c
@@ -0,0 +1,105 @@
1/*
2 * UDPLITEv6 An implementation of the UDP-Lite protocol over IPv6.
3 * See also net/ipv4/udplite.c
4 *
5 * Version: $Id: udplite.c,v 1.9 2006/10/19 08:28:10 gerrit Exp $
6 *
7 * Authors: Gerrit Renker <gerrit@erg.abdn.ac.uk>
8 *
9 * Changes:
10 * Fixes:
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 * as published by the Free Software Foundation; either version
14 * 2 of the License, or (at your option) any later version.
15 */
16#include "udp_impl.h"
17
18DEFINE_SNMP_STAT(struct udp_mib, udplite_stats_in6) __read_mostly;
19
20static int udplitev6_rcv(struct sk_buff **pskb)
21{
22 return __udp6_lib_rcv(pskb, udplite_hash, 1);
23}
24
25static void udplitev6_err(struct sk_buff *skb,
26 struct inet6_skb_parm *opt,
27 int type, int code, int offset, __be32 info)
28{
29 return __udp6_lib_err(skb, opt, type, code, offset, info, udplite_hash);
30}
31
32static struct inet6_protocol udplitev6_protocol = {
33 .handler = udplitev6_rcv,
34 .err_handler = udplitev6_err,
35 .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
36};
37
38static int udplite_v6_get_port(struct sock *sk, unsigned short snum)
39{
40 return udplite_get_port(sk, snum, ipv6_rcv_saddr_equal);
41}
42
43struct proto udplitev6_prot = {
44 .name = "UDPLITEv6",
45 .owner = THIS_MODULE,
46 .close = udp_lib_close,
47 .connect = ip6_datagram_connect,
48 .disconnect = udp_disconnect,
49 .ioctl = udp_ioctl,
50 .init = udplite_sk_init,
51 .destroy = udpv6_destroy_sock,
52 .setsockopt = udpv6_setsockopt,
53 .getsockopt = udpv6_getsockopt,
54 .sendmsg = udpv6_sendmsg,
55 .recvmsg = udpv6_recvmsg,
56 .backlog_rcv = udpv6_queue_rcv_skb,
57 .hash = udp_lib_hash,
58 .unhash = udp_lib_unhash,
59 .get_port = udplite_v6_get_port,
60 .obj_size = sizeof(struct udp6_sock),
61#ifdef CONFIG_COMPAT
62 .compat_setsockopt = compat_udpv6_setsockopt,
63 .compat_getsockopt = compat_udpv6_getsockopt,
64#endif
65};
66
67static struct inet_protosw udplite6_protosw = {
68 .type = SOCK_DGRAM,
69 .protocol = IPPROTO_UDPLITE,
70 .prot = &udplitev6_prot,
71 .ops = &inet6_dgram_ops,
72 .capability = -1,
73 .no_check = 0,
74 .flags = INET_PROTOSW_PERMANENT,
75};
76
77void __init udplitev6_init(void)
78{
79 if (inet6_add_protocol(&udplitev6_protocol, IPPROTO_UDPLITE) < 0)
80 printk(KERN_ERR "%s: Could not register.\n", __FUNCTION__);
81
82 inet6_register_protosw(&udplite6_protosw);
83}
84
85#ifdef CONFIG_PROC_FS
86static struct file_operations udplite6_seq_fops;
87static struct udp_seq_afinfo udplite6_seq_afinfo = {
88 .owner = THIS_MODULE,
89 .name = "udplite6",
90 .family = AF_INET6,
91 .hashtable = udplite_hash,
92 .seq_show = udp6_seq_show,
93 .seq_fops = &udplite6_seq_fops,
94};
95
96int __init udplite6_proc_init(void)
97{
98 return udp_proc_register(&udplite6_seq_afinfo);
99}
100
101void udplite6_proc_exit(void)
102{
103 udp_proc_unregister(&udplite6_seq_afinfo);
104}
105#endif
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index d400f8fae1..8dffd4daae 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -274,11 +274,12 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl)
274 break; 274 break;
275 275
276 case IPPROTO_UDP: 276 case IPPROTO_UDP:
277 case IPPROTO_UDPLITE:
277 case IPPROTO_TCP: 278 case IPPROTO_TCP:
278 case IPPROTO_SCTP: 279 case IPPROTO_SCTP:
279 case IPPROTO_DCCP: 280 case IPPROTO_DCCP:
280 if (pskb_may_pull(skb, skb->nh.raw + offset + 4 - skb->data)) { 281 if (pskb_may_pull(skb, skb->nh.raw + offset + 4 - skb->data)) {
281 u16 *ports = (u16 *)exthdr; 282 __be16 *ports = (__be16 *)exthdr;
282 283
283 fl->fl_ip_sport = ports[0]; 284 fl->fl_ip_sport = ports[0];
284 fl->fl_ip_dport = ports[1]; 285 fl->fl_ip_dport = ports[1];
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index 7931e4f898..12e426b9aa 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -50,7 +50,7 @@ static u32 xfrm6_tunnel_spi;
50#define XFRM6_TUNNEL_SPI_MIN 1 50#define XFRM6_TUNNEL_SPI_MIN 1
51#define XFRM6_TUNNEL_SPI_MAX 0xffffffff 51#define XFRM6_TUNNEL_SPI_MAX 0xffffffff
52 52
53static kmem_cache_t *xfrm6_tunnel_spi_kmem __read_mostly; 53static struct kmem_cache *xfrm6_tunnel_spi_kmem __read_mostly;
54 54
55#define XFRM6_TUNNEL_SPI_BYADDR_HSIZE 256 55#define XFRM6_TUNNEL_SPI_BYADDR_HSIZE 256
56#define XFRM6_TUNNEL_SPI_BYSPI_HSIZE 256 56#define XFRM6_TUNNEL_SPI_BYSPI_HSIZE 256
@@ -62,7 +62,7 @@ static unsigned inline xfrm6_tunnel_spi_hash_byaddr(xfrm_address_t *addr)
62{ 62{
63 unsigned h; 63 unsigned h;
64 64
65 h = addr->a6[0] ^ addr->a6[1] ^ addr->a6[2] ^ addr->a6[3]; 65 h = (__force u32)(addr->a6[0] ^ addr->a6[1] ^ addr->a6[2] ^ addr->a6[3]);
66 h ^= h >> 16; 66 h ^= h >> 16;
67 h ^= h >> 8; 67 h ^= h >> 8;
68 h &= XFRM6_TUNNEL_SPI_BYADDR_HSIZE - 1; 68 h &= XFRM6_TUNNEL_SPI_BYADDR_HSIZE - 1;
@@ -126,7 +126,7 @@ static struct xfrm6_tunnel_spi *__xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)
126 return NULL; 126 return NULL;
127} 127}
128 128
129u32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr) 129__be32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr)
130{ 130{
131 struct xfrm6_tunnel_spi *x6spi; 131 struct xfrm6_tunnel_spi *x6spi;
132 u32 spi; 132 u32 spi;
@@ -180,7 +180,7 @@ try_next_2:;
180 spi = 0; 180 spi = 0;
181 goto out; 181 goto out;
182alloc_spi: 182alloc_spi:
183 x6spi = kmem_cache_alloc(xfrm6_tunnel_spi_kmem, SLAB_ATOMIC); 183 x6spi = kmem_cache_alloc(xfrm6_tunnel_spi_kmem, GFP_ATOMIC);
184 if (!x6spi) 184 if (!x6spi)
185 goto out; 185 goto out;
186 186
@@ -196,7 +196,7 @@ out:
196 return spi; 196 return spi;
197} 197}
198 198
199u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr) 199__be32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr)
200{ 200{
201 struct xfrm6_tunnel_spi *x6spi; 201 struct xfrm6_tunnel_spi *x6spi;
202 u32 spi; 202 u32 spi;
@@ -265,7 +265,7 @@ static int xfrm6_tunnel_rcv(struct sk_buff *skb)
265} 265}
266 266
267static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 267static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
268 int type, int code, int offset, __u32 info) 268 int type, int code, int offset, __be32 info)
269{ 269{
270 /* xfrm6_tunnel native err handling */ 270 /* xfrm6_tunnel native err handling */
271 switch (type) { 271 switch (type) {
diff --git a/net/irda/discovery.c b/net/irda/discovery.c
index 3fefc822c1..89fd2a2cbc 100644
--- a/net/irda/discovery.c
+++ b/net/irda/discovery.c
@@ -32,6 +32,7 @@
32 32
33#include <linux/string.h> 33#include <linux/string.h>
34#include <linux/socket.h> 34#include <linux/socket.h>
35#include <linux/fs.h>
35#include <linux/seq_file.h> 36#include <linux/seq_file.h>
36 37
37#include <net/irda/irda.h> 38#include <net/irda/irda.h>
diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c
index d50a02030a..262bda808d 100644
--- a/net/irda/ircomm/ircomm_tty.c
+++ b/net/irda/ircomm/ircomm_tty.c
@@ -61,7 +61,7 @@ static void ircomm_tty_flush_buffer(struct tty_struct *tty);
61static void ircomm_tty_send_xchar(struct tty_struct *tty, char ch); 61static void ircomm_tty_send_xchar(struct tty_struct *tty, char ch);
62static void ircomm_tty_wait_until_sent(struct tty_struct *tty, int timeout); 62static void ircomm_tty_wait_until_sent(struct tty_struct *tty, int timeout);
63static void ircomm_tty_hangup(struct tty_struct *tty); 63static void ircomm_tty_hangup(struct tty_struct *tty);
64static void ircomm_tty_do_softint(void *private_); 64static void ircomm_tty_do_softint(struct work_struct *work);
65static void ircomm_tty_shutdown(struct ircomm_tty_cb *self); 65static void ircomm_tty_shutdown(struct ircomm_tty_cb *self);
66static void ircomm_tty_stop(struct tty_struct *tty); 66static void ircomm_tty_stop(struct tty_struct *tty);
67 67
@@ -389,7 +389,7 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
389 self->flow = FLOW_STOP; 389 self->flow = FLOW_STOP;
390 390
391 self->line = line; 391 self->line = line;
392 INIT_WORK(&self->tqueue, ircomm_tty_do_softint, self); 392 INIT_WORK(&self->tqueue, ircomm_tty_do_softint);
393 self->max_header_size = IRCOMM_TTY_HDR_UNINITIALISED; 393 self->max_header_size = IRCOMM_TTY_HDR_UNINITIALISED;
394 self->max_data_size = IRCOMM_TTY_DATA_UNINITIALISED; 394 self->max_data_size = IRCOMM_TTY_DATA_UNINITIALISED;
395 self->close_delay = 5*HZ/10; 395 self->close_delay = 5*HZ/10;
@@ -594,15 +594,16 @@ static void ircomm_tty_flush_buffer(struct tty_struct *tty)
594} 594}
595 595
596/* 596/*
597 * Function ircomm_tty_do_softint (private_) 597 * Function ircomm_tty_do_softint (work)
598 * 598 *
599 * We use this routine to give the write wakeup to the user at at a 599 * We use this routine to give the write wakeup to the user at at a
600 * safe time (as fast as possible after write have completed). This 600 * safe time (as fast as possible after write have completed). This
601 * can be compared to the Tx interrupt. 601 * can be compared to the Tx interrupt.
602 */ 602 */
603static void ircomm_tty_do_softint(void *private_) 603static void ircomm_tty_do_softint(struct work_struct *work)
604{ 604{
605 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) private_; 605 struct ircomm_tty_cb *self =
606 container_of(work, struct ircomm_tty_cb, tqueue);
606 struct tty_struct *tty; 607 struct tty_struct *tty;
607 unsigned long flags; 608 unsigned long flags;
608 struct sk_buff *skb, *ctrl_skb; 609 struct sk_buff *skb, *ctrl_skb;
diff --git a/net/irda/ircomm/ircomm_tty_ioctl.c b/net/irda/ircomm/ircomm_tty_ioctl.c
index 197e3e7ed7..75e39ea599 100644
--- a/net/irda/ircomm/ircomm_tty_ioctl.c
+++ b/net/irda/ircomm/ircomm_tty_ioctl.c
@@ -146,7 +146,7 @@ static void ircomm_tty_change_speed(struct ircomm_tty_cb *self)
146 * do something rational. 146 * do something rational.
147 */ 147 */
148void ircomm_tty_set_termios(struct tty_struct *tty, 148void ircomm_tty_set_termios(struct tty_struct *tty,
149 struct termios *old_termios) 149 struct ktermios *old_termios)
150{ 150{
151 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data; 151 struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
152 unsigned int cflag = tty->termios->c_cflag; 152 unsigned int cflag = tty->termios->c_cflag;
diff --git a/net/irda/iriap.c b/net/irda/iriap.c
index 415cf4eec2..8f1c6d65b2 100644
--- a/net/irda/iriap.c
+++ b/net/irda/iriap.c
@@ -27,6 +27,7 @@
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/types.h> 28#include <linux/types.h>
29#include <linux/skbuff.h> 29#include <linux/skbuff.h>
30#include <linux/fs.h>
30#include <linux/string.h> 31#include <linux/string.h>
31#include <linux/init.h> 32#include <linux/init.h>
32#include <linux/seq_file.h> 33#include <linux/seq_file.h>
@@ -172,7 +173,7 @@ struct iriap_cb *iriap_open(__u8 slsap_sel, int mode, void *priv,
172 173
173 IRDA_DEBUG(2, "%s()\n", __FUNCTION__); 174 IRDA_DEBUG(2, "%s()\n", __FUNCTION__);
174 175
175 self = kmalloc(sizeof(struct iriap_cb), GFP_ATOMIC); 176 self = kzalloc(sizeof(*self), GFP_ATOMIC);
176 if (!self) { 177 if (!self) {
177 IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__); 178 IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
178 return NULL; 179 return NULL;
@@ -181,7 +182,6 @@ struct iriap_cb *iriap_open(__u8 slsap_sel, int mode, void *priv,
181 /* 182 /*
182 * Initialize instance 183 * Initialize instance
183 */ 184 */
184 memset(self, 0, sizeof(struct iriap_cb));
185 185
186 self->magic = IAS_MAGIC; 186 self->magic = IAS_MAGIC;
187 self->mode = mode; 187 self->mode = mode;
@@ -451,12 +451,12 @@ static void iriap_getvaluebyclass_confirm(struct iriap_cb *self,
451 n = 2; 451 n = 2;
452 452
453 /* Get length, MSB first */ 453 /* Get length, MSB first */
454 len = be16_to_cpu(get_unaligned((__u16 *)(fp+n))); n += 2; 454 len = be16_to_cpu(get_unaligned((__be16 *)(fp+n))); n += 2;
455 455
456 IRDA_DEBUG(4, "%s(), len=%d\n", __FUNCTION__, len); 456 IRDA_DEBUG(4, "%s(), len=%d\n", __FUNCTION__, len);
457 457
458 /* Get object ID, MSB first */ 458 /* Get object ID, MSB first */
459 obj_id = be16_to_cpu(get_unaligned((__u16 *)(fp+n))); n += 2; 459 obj_id = be16_to_cpu(get_unaligned((__be16 *)(fp+n))); n += 2;
460 460
461 type = fp[n++]; 461 type = fp[n++];
462 IRDA_DEBUG(4, "%s(), Value type = %d\n", __FUNCTION__, type); 462 IRDA_DEBUG(4, "%s(), Value type = %d\n", __FUNCTION__, type);
@@ -506,7 +506,7 @@ static void iriap_getvaluebyclass_confirm(struct iriap_cb *self,
506 value = irias_new_string_value(fp+n); 506 value = irias_new_string_value(fp+n);
507 break; 507 break;
508 case IAS_OCT_SEQ: 508 case IAS_OCT_SEQ:
509 value_len = be16_to_cpu(get_unaligned((__u16 *)(fp+n))); 509 value_len = be16_to_cpu(get_unaligned((__be16 *)(fp+n)));
510 n += 2; 510 n += 2;
511 511
512 /* Will truncate to IAS_MAX_OCTET_STRING bytes */ 512 /* Will truncate to IAS_MAX_OCTET_STRING bytes */
@@ -544,7 +544,7 @@ static void iriap_getvaluebyclass_response(struct iriap_cb *self,
544{ 544{
545 struct sk_buff *tx_skb; 545 struct sk_buff *tx_skb;
546 int n; 546 int n;
547 __u32 tmp_be32; 547 __be32 tmp_be32;
548 __be16 tmp_be16; 548 __be16 tmp_be16;
549 __u8 *fp; 549 __u8 *fp;
550 550
diff --git a/net/irda/irias_object.c b/net/irda/irias_object.c
index 56292ab7d6..b1ee99a59c 100644
--- a/net/irda/irias_object.c
+++ b/net/irda/irias_object.c
@@ -501,13 +501,12 @@ struct ias_value *irias_new_octseq_value(__u8 *octseq , int len)
501 len = IAS_MAX_OCTET_STRING; 501 len = IAS_MAX_OCTET_STRING;
502 value->len = len; 502 value->len = len;
503 503
504 value->t.oct_seq = kmalloc(len, GFP_ATOMIC); 504 value->t.oct_seq = kmemdup(octseq, len, GFP_ATOMIC);
505 if (value->t.oct_seq == NULL){ 505 if (value->t.oct_seq == NULL){
506 IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__); 506 IRDA_WARNING("%s: Unable to kmalloc!\n", __FUNCTION__);
507 kfree(value); 507 kfree(value);
508 return NULL; 508 return NULL;
509 } 509 }
510 memcpy(value->t.oct_seq, octseq , len);
511 return value; 510 return value;
512} 511}
513 512
@@ -522,7 +521,6 @@ struct ias_value *irias_new_missing_value(void)
522 } 521 }
523 522
524 value->type = IAS_MISSING; 523 value->type = IAS_MISSING;
525 value->len = 0;
526 524
527 return value; 525 return value;
528} 526}
diff --git a/net/irda/irlan/irlan_common.c b/net/irda/irlan/irlan_common.c
index 9b962f2477..2bb04ac093 100644
--- a/net/irda/irlan/irlan_common.c
+++ b/net/irda/irlan/irlan_common.c
@@ -995,7 +995,7 @@ static int __irlan_insert_param(struct sk_buff *skb, char *param, int type,
995{ 995{
996 __u8 *frame; 996 __u8 *frame;
997 __u8 param_len; 997 __u8 param_len;
998 __u16 tmp_le; /* Temporary value in little endian format */ 998 __le16 tmp_le; /* Temporary value in little endian format */
999 int n=0; 999 int n=0;
1000 1000
1001 if (skb == NULL) { 1001 if (skb == NULL) {
diff --git a/net/irda/irlmp.c b/net/irda/irlmp.c
index fede837630..7e5d12ab3b 100644
--- a/net/irda/irlmp.c
+++ b/net/irda/irlmp.c
@@ -641,15 +641,13 @@ struct lsap_cb *irlmp_dup(struct lsap_cb *orig, void *instance)
641 } 641 }
642 642
643 /* Allocate a new instance */ 643 /* Allocate a new instance */
644 new = kmalloc(sizeof(struct lsap_cb), GFP_ATOMIC); 644 new = kmemdup(orig, sizeof(*new), GFP_ATOMIC);
645 if (!new) { 645 if (!new) {
646 IRDA_DEBUG(0, "%s(), unable to kmalloc\n", __FUNCTION__); 646 IRDA_DEBUG(0, "%s(), unable to kmalloc\n", __FUNCTION__);
647 spin_unlock_irqrestore(&irlmp->unconnected_lsaps->hb_spinlock, 647 spin_unlock_irqrestore(&irlmp->unconnected_lsaps->hb_spinlock,
648 flags); 648 flags);
649 return NULL; 649 return NULL;
650 } 650 }
651 /* Dup */
652 memcpy(new, orig, sizeof(struct lsap_cb));
653 /* new->lap = orig->lap; => done in the memcpy() */ 651 /* new->lap = orig->lap; => done in the memcpy() */
654 /* new->slsap_sel = orig->slsap_sel; => done in the memcpy() */ 652 /* new->slsap_sel = orig->slsap_sel; => done in the memcpy() */
655 new->conn_skb = NULL; 653 new->conn_skb = NULL;
diff --git a/net/irda/irqueue.c b/net/irda/irqueue.c
index 1ba8c71066..1d26cd33ea 100644
--- a/net/irda/irqueue.c
+++ b/net/irda/irqueue.c
@@ -356,14 +356,13 @@ hashbin_t *hashbin_new(int type)
356 /* 356 /*
357 * Allocate new hashbin 357 * Allocate new hashbin
358 */ 358 */
359 hashbin = kmalloc( sizeof(hashbin_t), GFP_ATOMIC); 359 hashbin = kzalloc(sizeof(*hashbin), GFP_ATOMIC);
360 if (!hashbin) 360 if (!hashbin)
361 return NULL; 361 return NULL;
362 362
363 /* 363 /*
364 * Initialize structure 364 * Initialize structure
365 */ 365 */
366 memset(hashbin, 0, sizeof(hashbin_t));
367 hashbin->hb_type = type; 366 hashbin->hb_type = type;
368 hashbin->magic = HB_MAGIC; 367 hashbin->magic = HB_MAGIC;
369 //hashbin->hb_current = NULL; 368 //hashbin->hb_current = NULL;
diff --git a/net/irda/irttp.c b/net/irda/irttp.c
index 3c2e70b77d..03504f3e49 100644
--- a/net/irda/irttp.c
+++ b/net/irda/irttp.c
@@ -26,6 +26,7 @@
26 26
27#include <linux/skbuff.h> 27#include <linux/skbuff.h>
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/fs.h>
29#include <linux/seq_file.h> 30#include <linux/seq_file.h>
30 31
31#include <asm/byteorder.h> 32#include <asm/byteorder.h>
@@ -1099,7 +1100,7 @@ int irttp_connect_request(struct tsap_cb *self, __u8 dtsap_sel,
1099 return -ENOMEM; 1100 return -ENOMEM;
1100 1101
1101 /* Reserve space for MUX_CONTROL and LAP header */ 1102 /* Reserve space for MUX_CONTROL and LAP header */
1102 skb_reserve(tx_skb, TTP_MAX_HEADER); 1103 skb_reserve(tx_skb, TTP_MAX_HEADER + TTP_SAR_HEADER);
1103 } else { 1104 } else {
1104 tx_skb = userdata; 1105 tx_skb = userdata;
1105 /* 1106 /*
@@ -1147,7 +1148,7 @@ int irttp_connect_request(struct tsap_cb *self, __u8 dtsap_sel,
1147 frame[3] = 0x02; /* Value length */ 1148 frame[3] = 0x02; /* Value length */
1148 1149
1149 put_unaligned(cpu_to_be16((__u16) max_sdu_size), 1150 put_unaligned(cpu_to_be16((__u16) max_sdu_size),
1150 (__u16 *)(frame+4)); 1151 (__be16 *)(frame+4));
1151 } else { 1152 } else {
1152 /* Insert plain TTP header */ 1153 /* Insert plain TTP header */
1153 frame = skb_push(tx_skb, TTP_HEADER); 1154 frame = skb_push(tx_skb, TTP_HEADER);
@@ -1348,7 +1349,7 @@ int irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size,
1348 return -ENOMEM; 1349 return -ENOMEM;
1349 1350
1350 /* Reserve space for MUX_CONTROL and LAP header */ 1351 /* Reserve space for MUX_CONTROL and LAP header */
1351 skb_reserve(tx_skb, TTP_MAX_HEADER); 1352 skb_reserve(tx_skb, TTP_MAX_HEADER + TTP_SAR_HEADER);
1352 } else { 1353 } else {
1353 tx_skb = userdata; 1354 tx_skb = userdata;
1354 /* 1355 /*
@@ -1394,7 +1395,7 @@ int irttp_connect_response(struct tsap_cb *self, __u32 max_sdu_size,
1394 frame[3] = 0x02; /* Value length */ 1395 frame[3] = 0x02; /* Value length */
1395 1396
1396 put_unaligned(cpu_to_be16((__u16) max_sdu_size), 1397 put_unaligned(cpu_to_be16((__u16) max_sdu_size),
1397 (__u16 *)(frame+4)); 1398 (__be16 *)(frame+4));
1398 } else { 1399 } else {
1399 /* Insert TTP header */ 1400 /* Insert TTP header */
1400 frame = skb_push(tx_skb, TTP_HEADER); 1401 frame = skb_push(tx_skb, TTP_HEADER);
diff --git a/net/key/af_key.c b/net/key/af_key.c
index 20ff7cca1d..5dd5094659 100644
--- a/net/key/af_key.c
+++ b/net/key/af_key.c
@@ -27,6 +27,7 @@
27#include <linux/proc_fs.h> 27#include <linux/proc_fs.h>
28#include <linux/init.h> 28#include <linux/init.h>
29#include <net/xfrm.h> 29#include <net/xfrm.h>
30#include <linux/audit.h>
30 31
31#include <net/sock.h> 32#include <net/sock.h>
32 33
@@ -1420,6 +1421,9 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr,
1420 else 1421 else
1421 err = xfrm_state_update(x); 1422 err = xfrm_state_update(x);
1422 1423
1424 xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
1425 AUDIT_MAC_IPSEC_ADDSA, err ? 0 : 1, NULL, x);
1426
1423 if (err < 0) { 1427 if (err < 0) {
1424 x->km.state = XFRM_STATE_DEAD; 1428 x->km.state = XFRM_STATE_DEAD;
1425 __xfrm_state_put(x); 1429 __xfrm_state_put(x);
@@ -1460,8 +1464,12 @@ static int pfkey_delete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
1460 err = -EPERM; 1464 err = -EPERM;
1461 goto out; 1465 goto out;
1462 } 1466 }
1463 1467
1464 err = xfrm_state_delete(x); 1468 err = xfrm_state_delete(x);
1469
1470 xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
1471 AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x);
1472
1465 if (err < 0) 1473 if (err < 0)
1466 goto out; 1474 goto out;
1467 1475
@@ -1637,12 +1645,15 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hd
1637{ 1645{
1638 unsigned proto; 1646 unsigned proto;
1639 struct km_event c; 1647 struct km_event c;
1648 struct xfrm_audit audit_info;
1640 1649
1641 proto = pfkey_satype2proto(hdr->sadb_msg_satype); 1650 proto = pfkey_satype2proto(hdr->sadb_msg_satype);
1642 if (proto == 0) 1651 if (proto == 0)
1643 return -EINVAL; 1652 return -EINVAL;
1644 1653
1645 xfrm_state_flush(proto); 1654 audit_info.loginuid = audit_get_loginuid(current->audit_context);
1655 audit_info.secid = 0;
1656 xfrm_state_flush(proto, &audit_info);
1646 c.data.proto = proto; 1657 c.data.proto = proto;
1647 c.seq = hdr->sadb_msg_seq; 1658 c.seq = hdr->sadb_msg_seq;
1648 c.pid = hdr->sadb_msg_pid; 1659 c.pid = hdr->sadb_msg_pid;
@@ -1767,11 +1778,11 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
1767 1778
1768 /* addresses present only in tunnel mode */ 1779 /* addresses present only in tunnel mode */
1769 if (t->mode == XFRM_MODE_TUNNEL) { 1780 if (t->mode == XFRM_MODE_TUNNEL) {
1770 switch (xp->family) { 1781 struct sockaddr *sa;
1782 sa = (struct sockaddr *)(rq+1);
1783 switch(sa->sa_family) {
1771 case AF_INET: 1784 case AF_INET:
1772 sin = (void*)(rq+1); 1785 sin = (struct sockaddr_in*)sa;
1773 if (sin->sin_family != AF_INET)
1774 return -EINVAL;
1775 t->saddr.a4 = sin->sin_addr.s_addr; 1786 t->saddr.a4 = sin->sin_addr.s_addr;
1776 sin++; 1787 sin++;
1777 if (sin->sin_family != AF_INET) 1788 if (sin->sin_family != AF_INET)
@@ -1780,9 +1791,7 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
1780 break; 1791 break;
1781#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 1792#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
1782 case AF_INET6: 1793 case AF_INET6:
1783 sin6 = (void *)(rq+1); 1794 sin6 = (struct sockaddr_in6*)sa;
1784 if (sin6->sin6_family != AF_INET6)
1785 return -EINVAL;
1786 memcpy(t->saddr.a6, &sin6->sin6_addr, sizeof(struct in6_addr)); 1795 memcpy(t->saddr.a6, &sin6->sin6_addr, sizeof(struct in6_addr));
1787 sin6++; 1796 sin6++;
1788 if (sin6->sin6_family != AF_INET6) 1797 if (sin6->sin6_family != AF_INET6)
@@ -1793,7 +1802,10 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq)
1793 default: 1802 default:
1794 return -EINVAL; 1803 return -EINVAL;
1795 } 1804 }
1796 } 1805 t->encap_family = sa->sa_family;
1806 } else
1807 t->encap_family = xp->family;
1808
1797 /* No way to set this via kame pfkey */ 1809 /* No way to set this via kame pfkey */
1798 t->aalgos = t->ealgos = t->calgos = ~0; 1810 t->aalgos = t->ealgos = t->calgos = ~0;
1799 xp->xfrm_nr++; 1811 xp->xfrm_nr++;
@@ -1830,18 +1842,25 @@ static inline int pfkey_xfrm_policy2sec_ctx_size(struct xfrm_policy *xp)
1830 1842
1831static int pfkey_xfrm_policy2msg_size(struct xfrm_policy *xp) 1843static int pfkey_xfrm_policy2msg_size(struct xfrm_policy *xp)
1832{ 1844{
1845 struct xfrm_tmpl *t;
1833 int sockaddr_size = pfkey_sockaddr_size(xp->family); 1846 int sockaddr_size = pfkey_sockaddr_size(xp->family);
1834 int socklen = (xp->family == AF_INET ? 1847 int socklen = 0;
1835 sizeof(struct sockaddr_in) : 1848 int i;
1836 sizeof(struct sockaddr_in6)); 1849
1850 for (i=0; i<xp->xfrm_nr; i++) {
1851 t = xp->xfrm_vec + i;
1852 socklen += (t->encap_family == AF_INET ?
1853 sizeof(struct sockaddr_in) :
1854 sizeof(struct sockaddr_in6));
1855 }
1837 1856
1838 return sizeof(struct sadb_msg) + 1857 return sizeof(struct sadb_msg) +
1839 (sizeof(struct sadb_lifetime) * 3) + 1858 (sizeof(struct sadb_lifetime) * 3) +
1840 (sizeof(struct sadb_address) * 2) + 1859 (sizeof(struct sadb_address) * 2) +
1841 (sockaddr_size * 2) + 1860 (sockaddr_size * 2) +
1842 sizeof(struct sadb_x_policy) + 1861 sizeof(struct sadb_x_policy) +
1843 (xp->xfrm_nr * (sizeof(struct sadb_x_ipsecrequest) + 1862 (xp->xfrm_nr * sizeof(struct sadb_x_ipsecrequest)) +
1844 (socklen * 2))) + 1863 (socklen * 2) +
1845 pfkey_xfrm_policy2sec_ctx_size(xp); 1864 pfkey_xfrm_policy2sec_ctx_size(xp);
1846} 1865}
1847 1866
@@ -1999,7 +2018,9 @@ static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, i
1999 2018
2000 req_size = sizeof(struct sadb_x_ipsecrequest); 2019 req_size = sizeof(struct sadb_x_ipsecrequest);
2001 if (t->mode == XFRM_MODE_TUNNEL) 2020 if (t->mode == XFRM_MODE_TUNNEL)
2002 req_size += 2*socklen; 2021 req_size += ((t->encap_family == AF_INET ?
2022 sizeof(struct sockaddr_in) :
2023 sizeof(struct sockaddr_in6)) * 2);
2003 else 2024 else
2004 size -= 2*socklen; 2025 size -= 2*socklen;
2005 rq = (void*)skb_put(skb, req_size); 2026 rq = (void*)skb_put(skb, req_size);
@@ -2015,7 +2036,7 @@ static void pfkey_xfrm_policy2msg(struct sk_buff *skb, struct xfrm_policy *xp, i
2015 rq->sadb_x_ipsecrequest_level = IPSEC_LEVEL_USE; 2036 rq->sadb_x_ipsecrequest_level = IPSEC_LEVEL_USE;
2016 rq->sadb_x_ipsecrequest_reqid = t->reqid; 2037 rq->sadb_x_ipsecrequest_reqid = t->reqid;
2017 if (t->mode == XFRM_MODE_TUNNEL) { 2038 if (t->mode == XFRM_MODE_TUNNEL) {
2018 switch (xp->family) { 2039 switch (t->encap_family) {
2019 case AF_INET: 2040 case AF_INET:
2020 sin = (void*)(rq+1); 2041 sin = (void*)(rq+1);
2021 sin->sin_family = AF_INET; 2042 sin->sin_family = AF_INET;
@@ -2195,6 +2216,9 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h
2195 err = xfrm_policy_insert(pol->sadb_x_policy_dir-1, xp, 2216 err = xfrm_policy_insert(pol->sadb_x_policy_dir-1, xp,
2196 hdr->sadb_msg_type != SADB_X_SPDUPDATE); 2217 hdr->sadb_msg_type != SADB_X_SPDUPDATE);
2197 2218
2219 xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
2220 AUDIT_MAC_IPSEC_ADDSPD, err ? 0 : 1, xp, NULL);
2221
2198 if (err) 2222 if (err)
2199 goto out; 2223 goto out;
2200 2224
@@ -2272,6 +2296,10 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg
2272 xp = xfrm_policy_bysel_ctx(XFRM_POLICY_TYPE_MAIN, pol->sadb_x_policy_dir-1, 2296 xp = xfrm_policy_bysel_ctx(XFRM_POLICY_TYPE_MAIN, pol->sadb_x_policy_dir-1,
2273 &sel, tmp.security, 1); 2297 &sel, tmp.security, 1);
2274 security_xfrm_policy_free(&tmp); 2298 security_xfrm_policy_free(&tmp);
2299
2300 xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
2301 AUDIT_MAC_IPSEC_DELSPD, (xp) ? 1 : 0, xp, NULL);
2302
2275 if (xp == NULL) 2303 if (xp == NULL)
2276 return -ENOENT; 2304 return -ENOENT;
2277 2305
@@ -2406,8 +2434,11 @@ static int key_notify_policy_flush(struct km_event *c)
2406static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs) 2434static int pfkey_spdflush(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr, void **ext_hdrs)
2407{ 2435{
2408 struct km_event c; 2436 struct km_event c;
2437 struct xfrm_audit audit_info;
2409 2438
2410 xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN); 2439 audit_info.loginuid = audit_get_loginuid(current->audit_context);
2440 audit_info.secid = 0;
2441 xfrm_policy_flush(XFRM_POLICY_TYPE_MAIN, &audit_info);
2411 c.data.type = XFRM_POLICY_TYPE_MAIN; 2442 c.data.type = XFRM_POLICY_TYPE_MAIN;
2412 c.event = XFRM_MSG_FLUSHPOLICY; 2443 c.event = XFRM_MSG_FLUSHPOLICY;
2413 c.pid = hdr->sadb_msg_pid; 2444 c.pid = hdr->sadb_msg_pid;
@@ -2938,7 +2969,7 @@ out:
2938 return NULL; 2969 return NULL;
2939} 2970}
2940 2971
2941static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport) 2972static int pfkey_send_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport)
2942{ 2973{
2943 struct sk_buff *skb; 2974 struct sk_buff *skb;
2944 struct sadb_msg *hdr; 2975 struct sadb_msg *hdr;
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index 2652ead96c..190bb3e051 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -64,7 +64,7 @@ static inline u16 llc_ui_next_link_no(int sap)
64 * 64 *
65 * Given an ARP header type return the corresponding ethernet protocol. 65 * Given an ARP header type return the corresponding ethernet protocol.
66 */ 66 */
67static inline u16 llc_proto_type(u16 arphrd) 67static inline __be16 llc_proto_type(u16 arphrd)
68{ 68{
69 return arphrd == ARPHRD_IEEE802_TR ? 69 return arphrd == ARPHRD_IEEE802_TR ?
70 htons(ETH_P_TR_802_2) : htons(ETH_P_802_2); 70 htons(ETH_P_TR_802_2) : htons(ETH_P_802_2);
diff --git a/net/llc/llc_input.c b/net/llc/llc_input.c
index 94d2368ade..db82aff6e4 100644
--- a/net/llc/llc_input.c
+++ b/net/llc/llc_input.c
@@ -115,8 +115,8 @@ static inline int llc_fixup_skb(struct sk_buff *skb)
115 skb->h.raw += llc_len; 115 skb->h.raw += llc_len;
116 skb_pull(skb, llc_len); 116 skb_pull(skb, llc_len);
117 if (skb->protocol == htons(ETH_P_802_2)) { 117 if (skb->protocol == htons(ETH_P_802_2)) {
118 u16 pdulen = eth_hdr(skb)->h_proto, 118 __be16 pdulen = eth_hdr(skb)->h_proto;
119 data_size = ntohs(pdulen) - llc_len; 119 u16 data_size = ntohs(pdulen) - llc_len;
120 120
121 if (unlikely(pskb_trim_rcsum(skb, data_size))) 121 if (unlikely(pskb_trim_rcsum(skb, data_size)))
122 return 0; 122 return 0;
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index f619c65272..cd10e44db0 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -1,5 +1,5 @@
1menu "Core Netfilter Configuration" 1menu "Core Netfilter Configuration"
2 depends on NET && NETFILTER 2 depends on NET && INET && NETFILTER
3 3
4config NETFILTER_NETLINK 4config NETFILTER_NETLINK
5 tristate "Netfilter netlink interface" 5 tristate "Netfilter netlink interface"
@@ -25,19 +25,56 @@ config NETFILTER_NETLINK_LOG
25 and is also scheduled to replace the old syslog-based ipt_LOG 25 and is also scheduled to replace the old syslog-based ipt_LOG
26 and ip6t_LOG modules. 26 and ip6t_LOG modules.
27 27
28config NF_CONNTRACK 28config NF_CONNTRACK_ENABLED
29 tristate "Layer 3 Independent Connection tracking (EXPERIMENTAL)" 29 tristate "Netfilter connection tracking support"
30 depends on EXPERIMENTAL && IP_NF_CONNTRACK=n 30 help
31 default n
32 ---help---
33 Connection tracking keeps a record of what packets have passed 31 Connection tracking keeps a record of what packets have passed
34 through your machine, in order to figure out how they are related 32 through your machine, in order to figure out how they are related
35 into connections. 33 into connections.
36 34
35 This is required to do Masquerading or other kinds of Network
36 Address Translation (except for Fast NAT). It can also be used to
37 enhance packet filtering (see `Connection state match support'
38 below).
39
40 To compile it as a module, choose M here. If unsure, say N.
41
42choice
43 prompt "Netfilter connection tracking support"
44 depends on NF_CONNTRACK_ENABLED
45
46config NF_CONNTRACK_SUPPORT
47 bool "Layer 3 Independent Connection tracking"
48 help
37 Layer 3 independent connection tracking is experimental scheme 49 Layer 3 independent connection tracking is experimental scheme
38 which generalize ip_conntrack to support other layer 3 protocols. 50 which generalize ip_conntrack to support other layer 3 protocols.
39 51
40 To compile it as a module, choose M here. If unsure, say N. 52 This is required to do Masquerading or other kinds of Network
53 Address Translation (except for Fast NAT). It can also be used to
54 enhance packet filtering (see `Connection state match support'
55 below).
56
57config IP_NF_CONNTRACK_SUPPORT
58 bool "Layer 3 Dependent Connection tracking (OBSOLETE)"
59 help
60 The old, Layer 3 dependent ip_conntrack subsystem of netfilter.
61
62 This is required to do Masquerading or other kinds of Network
63 Address Translation (except for Fast NAT). It can also be used to
64 enhance packet filtering (see `Connection state match support'
65 below).
66
67endchoice
68
69config NF_CONNTRACK
70 tristate
71 default m if NF_CONNTRACK_SUPPORT && NF_CONNTRACK_ENABLED=m
72 default y if NF_CONNTRACK_SUPPORT && NF_CONNTRACK_ENABLED=y
73
74config IP_NF_CONNTRACK
75 tristate
76 default m if IP_NF_CONNTRACK_SUPPORT && NF_CONNTRACK_ENABLED=m
77 default y if IP_NF_CONNTRACK_SUPPORT && NF_CONNTRACK_ENABLED=y
41 78
42config NF_CT_ACCT 79config NF_CT_ACCT
43 bool "Connection tracking flow accounting" 80 bool "Connection tracking flow accounting"
@@ -82,8 +119,12 @@ config NF_CONNTRACK_EVENTS
82 119
83 If unsure, say `N'. 120 If unsure, say `N'.
84 121
122config NF_CT_PROTO_GRE
123 tristate
124 depends on NF_CONNTRACK
125
85config NF_CT_PROTO_SCTP 126config NF_CT_PROTO_SCTP
86 tristate 'SCTP protocol on new connection tracking support (EXPERIMENTAL)' 127 tristate 'SCTP protocol connection tracking support (EXPERIMENTAL)'
87 depends on EXPERIMENTAL && NF_CONNTRACK 128 depends on EXPERIMENTAL && NF_CONNTRACK
88 default n 129 default n
89 help 130 help
@@ -93,9 +134,24 @@ config NF_CT_PROTO_SCTP
93 If you want to compile it as a module, say M here and read 134 If you want to compile it as a module, say M here and read
94 Documentation/modules.txt. If unsure, say `N'. 135 Documentation/modules.txt. If unsure, say `N'.
95 136
137config NF_CONNTRACK_AMANDA
138 tristate "Amanda backup protocol support"
139 depends on NF_CONNTRACK
140 select TEXTSEARCH
141 select TEXTSEARCH_KMP
142 help
143 If you are running the Amanda backup package <http://www.amanda.org/>
144 on this machine or machines that will be MASQUERADED through this
145 machine, then you may want to enable this feature. This allows the
146 connection tracking and natting code to allow the sub-channels that
147 Amanda requires for communication of the backup data, messages and
148 index.
149
150 To compile it as a module, choose M here. If unsure, say N.
151
96config NF_CONNTRACK_FTP 152config NF_CONNTRACK_FTP
97 tristate "FTP support on new connection tracking (EXPERIMENTAL)" 153 tristate "FTP protocol support"
98 depends on EXPERIMENTAL && NF_CONNTRACK 154 depends on NF_CONNTRACK
99 help 155 help
100 Tracking FTP connections is problematic: special helpers are 156 Tracking FTP connections is problematic: special helpers are
101 required for tracking them, and doing masquerading and other forms 157 required for tracking them, and doing masquerading and other forms
@@ -107,6 +163,101 @@ config NF_CONNTRACK_FTP
107 163
108 To compile it as a module, choose M here. If unsure, say N. 164 To compile it as a module, choose M here. If unsure, say N.
109 165
166config NF_CONNTRACK_H323
167 tristate "H.323 protocol support (EXPERIMENTAL)"
168 depends on EXPERIMENTAL && NF_CONNTRACK
169 help
170 H.323 is a VoIP signalling protocol from ITU-T. As one of the most
171 important VoIP protocols, it is widely used by voice hardware and
172 software including voice gateways, IP phones, Netmeeting, OpenPhone,
173 Gnomemeeting, etc.
174
175 With this module you can support H.323 on a connection tracking/NAT
176 firewall.
177
178 This module supports RAS, Fast Start, H.245 Tunnelling, Call
179 Forwarding, RTP/RTCP and T.120 based audio, video, fax, chat,
180 whiteboard, file transfer, etc. For more information, please
181 visit http://nath323.sourceforge.net/.
182
183 To compile it as a module, choose M here. If unsure, say N.
184
185config NF_CONNTRACK_IRC
186 tristate "IRC protocol support"
187 depends on NF_CONNTRACK
188 help
189 There is a commonly-used extension to IRC called
190 Direct Client-to-Client Protocol (DCC). This enables users to send
191 files to each other, and also chat to each other without the need
192 of a server. DCC Sending is used anywhere you send files over IRC,
193 and DCC Chat is most commonly used by Eggdrop bots. If you are
194 using NAT, this extension will enable you to send files and initiate
195 chats. Note that you do NOT need this extension to get files or
196 have others initiate chats, or everything else in IRC.
197
198 To compile it as a module, choose M here. If unsure, say N.
199
200config NF_CONNTRACK_NETBIOS_NS
201 tristate "NetBIOS name service protocol support (EXPERIMENTAL)"
202 depends on EXPERIMENTAL && NF_CONNTRACK
203 help
204 NetBIOS name service requests are sent as broadcast messages from an
205 unprivileged port and responded to with unicast messages to the
206 same port. This make them hard to firewall properly because connection
207 tracking doesn't deal with broadcasts. This helper tracks locally
208 originating NetBIOS name service requests and the corresponding
209 responses. It relies on correct IP address configuration, specifically
210 netmask and broadcast address. When properly configured, the output
211 of "ip address show" should look similar to this:
212
213 $ ip -4 address show eth0
214 4: eth0: <BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast qlen 1000
215 inet 172.16.2.252/24 brd 172.16.2.255 scope global eth0
216
217 To compile it as a module, choose M here. If unsure, say N.
218
219config NF_CONNTRACK_PPTP
220 tristate "PPtP protocol support"
221 depends on NF_CONNTRACK
222 select NF_CT_PROTO_GRE
223 help
224 This module adds support for PPTP (Point to Point Tunnelling
225 Protocol, RFC2637) connection tracking and NAT.
226
227 If you are running PPTP sessions over a stateful firewall or NAT
228 box, you may want to enable this feature.
229
230 Please note that not all PPTP modes of operation are supported yet.
231 Specifically these limitations exist:
232 - Blindy assumes that control connections are always established
233 in PNS->PAC direction. This is a violation of RFC2637.
234 - Only supports a single call within each session
235
236 To compile it as a module, choose M here. If unsure, say N.
237
238config NF_CONNTRACK_SIP
239 tristate "SIP protocol support (EXPERIMENTAL)"
240 depends on EXPERIMENTAL && NF_CONNTRACK
241 help
242 SIP is an application-layer control protocol that can establish,
243 modify, and terminate multimedia sessions (conferences) such as
244 Internet telephony calls. With the ip_conntrack_sip and
245 the nf_nat_sip modules you can support the protocol on a connection
246 tracking/NATing firewall.
247
248 To compile it as a module, choose M here. If unsure, say N.
249
250config NF_CONNTRACK_TFTP
251 tristate "TFTP protocol support"
252 depends on NF_CONNTRACK
253 help
254 TFTP connection tracking helper, this is required depending
255 on how restrictive your ruleset is.
256 If you are using a tftp client behind -j SNAT or -j MASQUERADING
257 you will need this.
258
259 To compile it as a module, choose M here. If unsure, say N.
260
110config NF_CT_NETLINK 261config NF_CT_NETLINK
111 tristate 'Connection tracking netlink interface (EXPERIMENTAL)' 262 tristate 'Connection tracking netlink interface (EXPERIMENTAL)'
112 depends on EXPERIMENTAL && NF_CONNTRACK && NETFILTER_NETLINK 263 depends on EXPERIMENTAL && NF_CONNTRACK && NETFILTER_NETLINK
@@ -184,6 +335,17 @@ config NETFILTER_XT_TARGET_NFQUEUE
184 335
185 To compile it as a module, choose M here. If unsure, say N. 336 To compile it as a module, choose M here. If unsure, say N.
186 337
338config NETFILTER_XT_TARGET_NFLOG
339 tristate '"NFLOG" target support'
340 depends on NETFILTER_XTABLES
341 help
342 This option enables the NFLOG target, which allows to LOG
343 messages through the netfilter logging API, which can use
344 either the old LOG target, the old ULOG target or nfnetlink_log
345 as backend.
346
347 To compile it as a module, choose M here. If unsure, say N.
348
187config NETFILTER_XT_TARGET_NOTRACK 349config NETFILTER_XT_TARGET_NOTRACK
188 tristate '"NOTRACK" target support' 350 tristate '"NOTRACK" target support'
189 depends on NETFILTER_XTABLES 351 depends on NETFILTER_XTABLES
@@ -464,5 +626,19 @@ config NETFILTER_XT_MATCH_TCPMSS
464 626
465 To compile it as a module, choose M here. If unsure, say N. 627 To compile it as a module, choose M here. If unsure, say N.
466 628
629config NETFILTER_XT_MATCH_HASHLIMIT
630 tristate '"hashlimit" match support'
631 depends on NETFILTER_XTABLES
632 help
633 This option adds a `hashlimit' match.
634
635 As opposed to `limit', this match dynamically creates a hash table
636 of limit buckets, based on your selection of source/destination
637 addresses and/or ports.
638
639 It enables you to express policies like `10kpps for any given
640 destination address' or `500pps from any given source address'
641 with a single rule.
642
467endmenu 643endmenu
468 644
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index a74be492fd..5dc5574f7e 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -1,7 +1,10 @@
1netfilter-objs := core.o nf_log.o nf_queue.o nf_sockopt.o 1netfilter-objs := core.o nf_log.o nf_queue.o nf_sockopt.o
2nf_conntrack-objs := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o 2
3nf_conntrack-y := nf_conntrack_core.o nf_conntrack_standalone.o nf_conntrack_expect.o nf_conntrack_helper.o nf_conntrack_proto.o nf_conntrack_l3proto_generic.o nf_conntrack_proto_generic.o nf_conntrack_proto_tcp.o nf_conntrack_proto_udp.o
4nf_conntrack-$(CONFIG_NF_CONNTRACK_EVENTS) += nf_conntrack_ecache.o
3 5
4obj-$(CONFIG_NETFILTER) = netfilter.o 6obj-$(CONFIG_NETFILTER) = netfilter.o
7obj-$(CONFIG_SYSCTL) += nf_sysctl.o
5 8
6obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.o 9obj-$(CONFIG_NETFILTER_NETLINK) += nfnetlink.o
7obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o 10obj-$(CONFIG_NETFILTER_NETLINK_QUEUE) += nfnetlink_queue.o
@@ -11,13 +14,23 @@ obj-$(CONFIG_NETFILTER_NETLINK_LOG) += nfnetlink_log.o
11obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o 14obj-$(CONFIG_NF_CONNTRACK) += nf_conntrack.o
12 15
13# SCTP protocol connection tracking 16# SCTP protocol connection tracking
17obj-$(CONFIG_NF_CT_PROTO_GRE) += nf_conntrack_proto_gre.o
14obj-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o 18obj-$(CONFIG_NF_CT_PROTO_SCTP) += nf_conntrack_proto_sctp.o
15 19
16# netlink interface for nf_conntrack 20# netlink interface for nf_conntrack
17obj-$(CONFIG_NF_CT_NETLINK) += nf_conntrack_netlink.o 21obj-$(CONFIG_NF_CT_NETLINK) += nf_conntrack_netlink.o
18 22
19# connection tracking helpers 23# connection tracking helpers
24nf_conntrack_h323-objs := nf_conntrack_h323_main.o nf_conntrack_h323_asn1.o
25
26obj-$(CONFIG_NF_CONNTRACK_AMANDA) += nf_conntrack_amanda.o
20obj-$(CONFIG_NF_CONNTRACK_FTP) += nf_conntrack_ftp.o 27obj-$(CONFIG_NF_CONNTRACK_FTP) += nf_conntrack_ftp.o
28obj-$(CONFIG_NF_CONNTRACK_H323) += nf_conntrack_h323.o
29obj-$(CONFIG_NF_CONNTRACK_IRC) += nf_conntrack_irc.o
30obj-$(CONFIG_NF_CONNTRACK_NETBIOS_NS) += nf_conntrack_netbios_ns.o
31obj-$(CONFIG_NF_CONNTRACK_PPTP) += nf_conntrack_pptp.o
32obj-$(CONFIG_NF_CONNTRACK_SIP) += nf_conntrack_sip.o
33obj-$(CONFIG_NF_CONNTRACK_TFTP) += nf_conntrack_tftp.o
21 34
22# generic X tables 35# generic X tables
23obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o 36obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o
@@ -28,6 +41,7 @@ obj-$(CONFIG_NETFILTER_XT_TARGET_CONNMARK) += xt_CONNMARK.o
28obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o 41obj-$(CONFIG_NETFILTER_XT_TARGET_DSCP) += xt_DSCP.o
29obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o 42obj-$(CONFIG_NETFILTER_XT_TARGET_MARK) += xt_MARK.o
30obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o 43obj-$(CONFIG_NETFILTER_XT_TARGET_NFQUEUE) += xt_NFQUEUE.o
44obj-$(CONFIG_NETFILTER_XT_TARGET_NFLOG) += xt_NFLOG.o
31obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o 45obj-$(CONFIG_NETFILTER_XT_TARGET_NOTRACK) += xt_NOTRACK.o
32obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o 46obj-$(CONFIG_NETFILTER_XT_TARGET_SECMARK) += xt_SECMARK.o
33obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o 47obj-$(CONFIG_NETFILTER_XT_TARGET_CONNSECMARK) += xt_CONNSECMARK.o
@@ -56,3 +70,4 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o
56obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o 70obj-$(CONFIG_NETFILTER_XT_MATCH_STRING) += xt_string.o
57obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o 71obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o
58obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o 72obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o
73obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index d80b935b3a..291b8c6862 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -28,7 +28,7 @@
28 28
29static DEFINE_SPINLOCK(afinfo_lock); 29static DEFINE_SPINLOCK(afinfo_lock);
30 30
31struct nf_afinfo *nf_afinfo[NPROTO]; 31struct nf_afinfo *nf_afinfo[NPROTO] __read_mostly;
32EXPORT_SYMBOL(nf_afinfo); 32EXPORT_SYMBOL(nf_afinfo);
33 33
34int nf_register_afinfo(struct nf_afinfo *afinfo) 34int nf_register_afinfo(struct nf_afinfo *afinfo)
@@ -54,7 +54,7 @@ EXPORT_SYMBOL_GPL(nf_unregister_afinfo);
54 * of skbuffs queued for userspace, and not deregister a hook unless 54 * of skbuffs queued for userspace, and not deregister a hook unless
55 * this is zero, but that sucks. Now, we simply check when the 55 * this is zero, but that sucks. Now, we simply check when the
56 * packets come back: if the hook is gone, the packet is discarded. */ 56 * packets come back: if the hook is gone, the packet is discarded. */
57struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS]; 57struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS] __read_mostly;
58EXPORT_SYMBOL(nf_hooks); 58EXPORT_SYMBOL(nf_hooks);
59static DEFINE_SPINLOCK(nf_hook_lock); 59static DEFINE_SPINLOCK(nf_hook_lock);
60 60
@@ -222,28 +222,21 @@ copy_skb:
222} 222}
223EXPORT_SYMBOL(skb_make_writable); 223EXPORT_SYMBOL(skb_make_writable);
224 224
225u_int16_t nf_csum_update(u_int32_t oldval, u_int32_t newval, u_int32_t csum) 225void nf_proto_csum_replace4(__sum16 *sum, struct sk_buff *skb,
226{ 226 __be32 from, __be32 to, int pseudohdr)
227 u_int32_t diff[] = { oldval, newval };
228
229 return csum_fold(csum_partial((char *)diff, sizeof(diff), ~csum));
230}
231EXPORT_SYMBOL(nf_csum_update);
232
233u_int16_t nf_proto_csum_update(struct sk_buff *skb,
234 u_int32_t oldval, u_int32_t newval,
235 u_int16_t csum, int pseudohdr)
236{ 227{
228 __be32 diff[] = { ~from, to };
237 if (skb->ip_summed != CHECKSUM_PARTIAL) { 229 if (skb->ip_summed != CHECKSUM_PARTIAL) {
238 csum = nf_csum_update(oldval, newval, csum); 230 *sum = csum_fold(csum_partial((char *)diff, sizeof(diff),
231 ~csum_unfold(*sum)));
239 if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr) 232 if (skb->ip_summed == CHECKSUM_COMPLETE && pseudohdr)
240 skb->csum = nf_csum_update(oldval, newval, skb->csum); 233 skb->csum = ~csum_partial((char *)diff, sizeof(diff),
234 ~skb->csum);
241 } else if (pseudohdr) 235 } else if (pseudohdr)
242 csum = ~nf_csum_update(oldval, newval, ~csum); 236 *sum = ~csum_fold(csum_partial((char *)diff, sizeof(diff),
243 237 csum_unfold(*sum)));
244 return csum;
245} 238}
246EXPORT_SYMBOL(nf_proto_csum_update); 239EXPORT_SYMBOL(nf_proto_csum_replace4);
247 240
248/* This does not belong here, but locally generated errors need it if connection 241/* This does not belong here, but locally generated errors need it if connection
249 tracking in use: without this, connection may not be in hash table, and hence 242 tracking in use: without this, connection may not be in hash table, and hence
diff --git a/net/netfilter/nf_conntrack_amanda.c b/net/netfilter/nf_conntrack_amanda.c
new file mode 100644
index 0000000000..b8869eab76
--- /dev/null
+++ b/net/netfilter/nf_conntrack_amanda.c
@@ -0,0 +1,238 @@
1/* Amanda extension for IP connection tracking
2 *
3 * (C) 2002 by Brian J. Murrell <netfilter@interlinx.bc.ca>
4 * based on HW's ip_conntrack_irc.c as well as other modules
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/moduleparam.h>
14#include <linux/textsearch.h>
15#include <linux/skbuff.h>
16#include <linux/in.h>
17#include <linux/udp.h>
18#include <linux/netfilter.h>
19
20#include <net/netfilter/nf_conntrack.h>
21#include <net/netfilter/nf_conntrack_expect.h>
22#include <net/netfilter/nf_conntrack_ecache.h>
23#include <net/netfilter/nf_conntrack_helper.h>
24#include <linux/netfilter/nf_conntrack_amanda.h>
25
26static unsigned int master_timeout __read_mostly = 300;
27static char *ts_algo = "kmp";
28
29MODULE_AUTHOR("Brian J. Murrell <netfilter@interlinx.bc.ca>");
30MODULE_DESCRIPTION("Amanda connection tracking module");
31MODULE_LICENSE("GPL");
32MODULE_ALIAS("ip_conntrack_amanda");
33
34module_param(master_timeout, uint, 0600);
35MODULE_PARM_DESC(master_timeout, "timeout for the master connection");
36module_param(ts_algo, charp, 0400);
37MODULE_PARM_DESC(ts_algo, "textsearch algorithm to use (default kmp)");
38
39unsigned int (*nf_nat_amanda_hook)(struct sk_buff **pskb,
40 enum ip_conntrack_info ctinfo,
41 unsigned int matchoff,
42 unsigned int matchlen,
43 struct nf_conntrack_expect *exp)
44 __read_mostly;
45EXPORT_SYMBOL_GPL(nf_nat_amanda_hook);
46
47enum amanda_strings {
48 SEARCH_CONNECT,
49 SEARCH_NEWLINE,
50 SEARCH_DATA,
51 SEARCH_MESG,
52 SEARCH_INDEX,
53};
54
55static struct {
56 char *string;
57 size_t len;
58 struct ts_config *ts;
59} search[] __read_mostly = {
60 [SEARCH_CONNECT] = {
61 .string = "CONNECT ",
62 .len = 8,
63 },
64 [SEARCH_NEWLINE] = {
65 .string = "\n",
66 .len = 1,
67 },
68 [SEARCH_DATA] = {
69 .string = "DATA ",
70 .len = 5,
71 },
72 [SEARCH_MESG] = {
73 .string = "MESG ",
74 .len = 5,
75 },
76 [SEARCH_INDEX] = {
77 .string = "INDEX ",
78 .len = 6,
79 },
80};
81
82static int amanda_help(struct sk_buff **pskb,
83 unsigned int protoff,
84 struct nf_conn *ct,
85 enum ip_conntrack_info ctinfo)
86{
87 struct ts_state ts;
88 struct nf_conntrack_expect *exp;
89 struct nf_conntrack_tuple *tuple;
90 unsigned int dataoff, start, stop, off, i;
91 char pbuf[sizeof("65535")], *tmp;
92 u_int16_t len;
93 __be16 port;
94 int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
95 int ret = NF_ACCEPT;
96 typeof(nf_nat_amanda_hook) nf_nat_amanda;
97
98 /* Only look at packets from the Amanda server */
99 if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL)
100 return NF_ACCEPT;
101
102 /* increase the UDP timeout of the master connection as replies from
103 * Amanda clients to the server can be quite delayed */
104 nf_ct_refresh(ct, *pskb, master_timeout * HZ);
105
106 /* No data? */
107 dataoff = protoff + sizeof(struct udphdr);
108 if (dataoff >= (*pskb)->len) {
109 if (net_ratelimit())
110 printk("amanda_help: skblen = %u\n", (*pskb)->len);
111 return NF_ACCEPT;
112 }
113
114 memset(&ts, 0, sizeof(ts));
115 start = skb_find_text(*pskb, dataoff, (*pskb)->len,
116 search[SEARCH_CONNECT].ts, &ts);
117 if (start == UINT_MAX)
118 goto out;
119 start += dataoff + search[SEARCH_CONNECT].len;
120
121 memset(&ts, 0, sizeof(ts));
122 stop = skb_find_text(*pskb, start, (*pskb)->len,
123 search[SEARCH_NEWLINE].ts, &ts);
124 if (stop == UINT_MAX)
125 goto out;
126 stop += start;
127
128 for (i = SEARCH_DATA; i <= SEARCH_INDEX; i++) {
129 memset(&ts, 0, sizeof(ts));
130 off = skb_find_text(*pskb, start, stop, search[i].ts, &ts);
131 if (off == UINT_MAX)
132 continue;
133 off += start + search[i].len;
134
135 len = min_t(unsigned int, sizeof(pbuf) - 1, stop - off);
136 if (skb_copy_bits(*pskb, off, pbuf, len))
137 break;
138 pbuf[len] = '\0';
139
140 port = htons(simple_strtoul(pbuf, &tmp, 10));
141 len = tmp - pbuf;
142 if (port == 0 || len > 5)
143 break;
144
145 exp = nf_conntrack_expect_alloc(ct);
146 if (exp == NULL) {
147 ret = NF_DROP;
148 goto out;
149 }
150 tuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
151 nf_conntrack_expect_init(exp, family,
152 &tuple->src.u3, &tuple->dst.u3,
153 IPPROTO_TCP, NULL, &port);
154
155 nf_nat_amanda = rcu_dereference(nf_nat_amanda_hook);
156 if (nf_nat_amanda && ct->status & IPS_NAT_MASK)
157 ret = nf_nat_amanda(pskb, ctinfo, off - dataoff,
158 len, exp);
159 else if (nf_conntrack_expect_related(exp) != 0)
160 ret = NF_DROP;
161 nf_conntrack_expect_put(exp);
162 }
163
164out:
165 return ret;
166}
167
168static struct nf_conntrack_helper amanda_helper[2] __read_mostly = {
169 {
170 .name = "amanda",
171 .max_expected = 3,
172 .timeout = 180,
173 .me = THIS_MODULE,
174 .help = amanda_help,
175 .tuple.src.l3num = AF_INET,
176 .tuple.src.u.udp.port = __constant_htons(10080),
177 .tuple.dst.protonum = IPPROTO_UDP,
178 .mask.src.l3num = 0xFFFF,
179 .mask.src.u.udp.port = __constant_htons(0xFFFF),
180 .mask.dst.protonum = 0xFF,
181 },
182 {
183 .name = "amanda",
184 .max_expected = 3,
185 .timeout = 180,
186 .me = THIS_MODULE,
187 .help = amanda_help,
188 .tuple.src.l3num = AF_INET6,
189 .tuple.src.u.udp.port = __constant_htons(10080),
190 .tuple.dst.protonum = IPPROTO_UDP,
191 .mask.src.l3num = 0xFFFF,
192 .mask.src.u.udp.port = __constant_htons(0xFFFF),
193 .mask.dst.protonum = 0xFF,
194 },
195};
196
197static void __exit nf_conntrack_amanda_fini(void)
198{
199 int i;
200
201 nf_conntrack_helper_unregister(&amanda_helper[0]);
202 nf_conntrack_helper_unregister(&amanda_helper[1]);
203 for (i = 0; i < ARRAY_SIZE(search); i++)
204 textsearch_destroy(search[i].ts);
205}
206
207static int __init nf_conntrack_amanda_init(void)
208{
209 int ret, i;
210
211 ret = -ENOMEM;
212 for (i = 0; i < ARRAY_SIZE(search); i++) {
213 search[i].ts = textsearch_prepare(ts_algo, search[i].string,
214 search[i].len,
215 GFP_KERNEL, TS_AUTOLOAD);
216 if (search[i].ts == NULL)
217 goto err1;
218 }
219 ret = nf_conntrack_helper_register(&amanda_helper[0]);
220 if (ret < 0)
221 goto err1;
222 ret = nf_conntrack_helper_register(&amanda_helper[1]);
223 if (ret < 0)
224 goto err2;
225 return 0;
226
227err2:
228 nf_conntrack_helper_unregister(&amanda_helper[0]);
229err1:
230 for (; i >= 0; i--) {
231 if (search[i].ts)
232 textsearch_destroy(search[i].ts);
233 }
234 return ret;
235}
236
237module_init(nf_conntrack_amanda_init);
238module_exit(nf_conntrack_amanda_fini);
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index de0567b1f4..9b02ec4012 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -46,15 +46,12 @@
46#include <linux/kernel.h> 46#include <linux/kernel.h>
47#include <linux/netdevice.h> 47#include <linux/netdevice.h>
48#include <linux/socket.h> 48#include <linux/socket.h>
49 49#include <linux/mm.h>
50/* This rwlock protects the main hash table, protocol/helper/expected
51 registrations, conntrack timers*/
52#define ASSERT_READ_LOCK(x)
53#define ASSERT_WRITE_LOCK(x)
54 50
55#include <net/netfilter/nf_conntrack.h> 51#include <net/netfilter/nf_conntrack.h>
56#include <net/netfilter/nf_conntrack_l3proto.h> 52#include <net/netfilter/nf_conntrack_l3proto.h>
57#include <net/netfilter/nf_conntrack_protocol.h> 53#include <net/netfilter/nf_conntrack_l4proto.h>
54#include <net/netfilter/nf_conntrack_expect.h>
58#include <net/netfilter/nf_conntrack_helper.h> 55#include <net/netfilter/nf_conntrack_helper.h>
59#include <net/netfilter/nf_conntrack_core.h> 56#include <net/netfilter/nf_conntrack_core.h>
60 57
@@ -67,92 +64,32 @@
67#endif 64#endif
68 65
69DEFINE_RWLOCK(nf_conntrack_lock); 66DEFINE_RWLOCK(nf_conntrack_lock);
67EXPORT_SYMBOL_GPL(nf_conntrack_lock);
70 68
71/* nf_conntrack_standalone needs this */ 69/* nf_conntrack_standalone needs this */
72atomic_t nf_conntrack_count = ATOMIC_INIT(0); 70atomic_t nf_conntrack_count = ATOMIC_INIT(0);
71EXPORT_SYMBOL_GPL(nf_conntrack_count);
73 72
74void (*nf_conntrack_destroyed)(struct nf_conn *conntrack) = NULL; 73void (*nf_conntrack_destroyed)(struct nf_conn *conntrack);
75LIST_HEAD(nf_conntrack_expect_list); 74EXPORT_SYMBOL_GPL(nf_conntrack_destroyed);
76struct nf_conntrack_protocol **nf_ct_protos[PF_MAX] __read_mostly;
77struct nf_conntrack_l3proto *nf_ct_l3protos[PF_MAX] __read_mostly;
78static LIST_HEAD(helpers);
79unsigned int nf_conntrack_htable_size __read_mostly = 0;
80int nf_conntrack_max __read_mostly;
81struct list_head *nf_conntrack_hash __read_mostly;
82static kmem_cache_t *nf_conntrack_expect_cachep __read_mostly;
83struct nf_conn nf_conntrack_untracked;
84unsigned int nf_ct_log_invalid __read_mostly;
85static LIST_HEAD(unconfirmed);
86static int nf_conntrack_vmalloc __read_mostly;
87
88static unsigned int nf_conntrack_next_id;
89static unsigned int nf_conntrack_expect_next_id;
90#ifdef CONFIG_NF_CONNTRACK_EVENTS
91ATOMIC_NOTIFIER_HEAD(nf_conntrack_chain);
92ATOMIC_NOTIFIER_HEAD(nf_conntrack_expect_chain);
93
94DEFINE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache);
95 75
96/* deliver cached events and clear cache entry - must be called with locally 76unsigned int nf_conntrack_htable_size __read_mostly;
97 * disabled softirqs */ 77EXPORT_SYMBOL_GPL(nf_conntrack_htable_size);
98static inline void
99__nf_ct_deliver_cached_events(struct nf_conntrack_ecache *ecache)
100{
101 DEBUGP("ecache: delivering events for %p\n", ecache->ct);
102 if (nf_ct_is_confirmed(ecache->ct) && !nf_ct_is_dying(ecache->ct)
103 && ecache->events)
104 atomic_notifier_call_chain(&nf_conntrack_chain, ecache->events,
105 ecache->ct);
106
107 ecache->events = 0;
108 nf_ct_put(ecache->ct);
109 ecache->ct = NULL;
110}
111 78
112/* Deliver all cached events for a particular conntrack. This is called 79int nf_conntrack_max __read_mostly;
113 * by code prior to async packet handling for freeing the skb */ 80EXPORT_SYMBOL_GPL(nf_conntrack_max);
114void nf_ct_deliver_cached_events(const struct nf_conn *ct)
115{
116 struct nf_conntrack_ecache *ecache;
117 81
118 local_bh_disable(); 82struct list_head *nf_conntrack_hash __read_mostly;
119 ecache = &__get_cpu_var(nf_conntrack_ecache); 83EXPORT_SYMBOL_GPL(nf_conntrack_hash);
120 if (ecache->ct == ct)
121 __nf_ct_deliver_cached_events(ecache);
122 local_bh_enable();
123}
124 84
125/* Deliver cached events for old pending events, if current conntrack != old */ 85struct nf_conn nf_conntrack_untracked __read_mostly;
126void __nf_ct_event_cache_init(struct nf_conn *ct) 86EXPORT_SYMBOL_GPL(nf_conntrack_untracked);
127{
128 struct nf_conntrack_ecache *ecache;
129
130 /* take care of delivering potentially old events */
131 ecache = &__get_cpu_var(nf_conntrack_ecache);
132 BUG_ON(ecache->ct == ct);
133 if (ecache->ct)
134 __nf_ct_deliver_cached_events(ecache);
135 /* initialize for this conntrack/packet */
136 ecache->ct = ct;
137 nf_conntrack_get(&ct->ct_general);
138}
139 87
140/* flush the event cache - touches other CPU's data and must not be called 88unsigned int nf_ct_log_invalid __read_mostly;
141 * while packets are still passing through the code */ 89LIST_HEAD(unconfirmed);
142static void nf_ct_event_cache_flush(void) 90static int nf_conntrack_vmalloc __read_mostly;
143{
144 struct nf_conntrack_ecache *ecache;
145 int cpu;
146 91
147 for_each_possible_cpu(cpu) { 92static unsigned int nf_conntrack_next_id;
148 ecache = &per_cpu(nf_conntrack_ecache, cpu);
149 if (ecache->ct)
150 nf_ct_put(ecache->ct);
151 }
152}
153#else
154static inline void nf_ct_event_cache_flush(void) {}
155#endif /* CONFIG_NF_CONNTRACK_EVENTS */
156 93
157DEFINE_PER_CPU(struct ip_conntrack_stat, nf_conntrack_stat); 94DEFINE_PER_CPU(struct ip_conntrack_stat, nf_conntrack_stat);
158EXPORT_PER_CPU_SYMBOL(nf_conntrack_stat); 95EXPORT_PER_CPU_SYMBOL(nf_conntrack_stat);
@@ -171,7 +108,7 @@ static struct {
171 size_t size; 108 size_t size;
172 109
173 /* slab cache pointer */ 110 /* slab cache pointer */
174 kmem_cache_t *cachep; 111 struct kmem_cache *cachep;
175 112
176 /* allocated slab cache + modules which uses this slab cache */ 113 /* allocated slab cache + modules which uses this slab cache */
177 int use; 114 int use;
@@ -184,85 +121,6 @@ DEFINE_RWLOCK(nf_ct_cache_lock);
184/* This avoids calling kmem_cache_create() with same name simultaneously */ 121/* This avoids calling kmem_cache_create() with same name simultaneously */
185static DEFINE_MUTEX(nf_ct_cache_mutex); 122static DEFINE_MUTEX(nf_ct_cache_mutex);
186 123
187extern struct nf_conntrack_protocol nf_conntrack_generic_protocol;
188struct nf_conntrack_protocol *
189__nf_ct_proto_find(u_int16_t l3proto, u_int8_t protocol)
190{
191 if (unlikely(l3proto >= AF_MAX || nf_ct_protos[l3proto] == NULL))
192 return &nf_conntrack_generic_protocol;
193
194 return nf_ct_protos[l3proto][protocol];
195}
196
197/* this is guaranteed to always return a valid protocol helper, since
198 * it falls back to generic_protocol */
199struct nf_conntrack_protocol *
200nf_ct_proto_find_get(u_int16_t l3proto, u_int8_t protocol)
201{
202 struct nf_conntrack_protocol *p;
203
204 preempt_disable();
205 p = __nf_ct_proto_find(l3proto, protocol);
206 if (!try_module_get(p->me))
207 p = &nf_conntrack_generic_protocol;
208 preempt_enable();
209
210 return p;
211}
212
213void nf_ct_proto_put(struct nf_conntrack_protocol *p)
214{
215 module_put(p->me);
216}
217
218struct nf_conntrack_l3proto *
219nf_ct_l3proto_find_get(u_int16_t l3proto)
220{
221 struct nf_conntrack_l3proto *p;
222
223 preempt_disable();
224 p = __nf_ct_l3proto_find(l3proto);
225 if (!try_module_get(p->me))
226 p = &nf_conntrack_generic_l3proto;
227 preempt_enable();
228
229 return p;
230}
231
232void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p)
233{
234 module_put(p->me);
235}
236
237int
238nf_ct_l3proto_try_module_get(unsigned short l3proto)
239{
240 int ret;
241 struct nf_conntrack_l3proto *p;
242
243retry: p = nf_ct_l3proto_find_get(l3proto);
244 if (p == &nf_conntrack_generic_l3proto) {
245 ret = request_module("nf_conntrack-%d", l3proto);
246 if (!ret)
247 goto retry;
248
249 return -EPROTOTYPE;
250 }
251
252 return 0;
253}
254
255void nf_ct_l3proto_module_put(unsigned short l3proto)
256{
257 struct nf_conntrack_l3proto *p;
258
259 preempt_disable();
260 p = __nf_ct_l3proto_find(l3proto);
261 preempt_enable();
262
263 module_put(p->me);
264}
265
266static int nf_conntrack_hash_rnd_initted; 124static int nf_conntrack_hash_rnd_initted;
267static unsigned int nf_conntrack_hash_rnd; 125static unsigned int nf_conntrack_hash_rnd;
268 126
@@ -289,7 +147,7 @@ int nf_conntrack_register_cache(u_int32_t features, const char *name,
289{ 147{
290 int ret = 0; 148 int ret = 0;
291 char *cache_name; 149 char *cache_name;
292 kmem_cache_t *cachep; 150 struct kmem_cache *cachep;
293 151
294 DEBUGP("nf_conntrack_register_cache: features=0x%x, name=%s, size=%d\n", 152 DEBUGP("nf_conntrack_register_cache: features=0x%x, name=%s, size=%d\n",
295 features, name, size); 153 features, name, size);
@@ -363,11 +221,12 @@ out_up_mutex:
363 mutex_unlock(&nf_ct_cache_mutex); 221 mutex_unlock(&nf_ct_cache_mutex);
364 return ret; 222 return ret;
365} 223}
224EXPORT_SYMBOL_GPL(nf_conntrack_register_cache);
366 225
367/* FIXME: In the current, only nf_conntrack_cleanup() can call this function. */ 226/* FIXME: In the current, only nf_conntrack_cleanup() can call this function. */
368void nf_conntrack_unregister_cache(u_int32_t features) 227void nf_conntrack_unregister_cache(u_int32_t features)
369{ 228{
370 kmem_cache_t *cachep; 229 struct kmem_cache *cachep;
371 char *name; 230 char *name;
372 231
373 /* 232 /*
@@ -397,6 +256,7 @@ void nf_conntrack_unregister_cache(u_int32_t features)
397 256
398 mutex_unlock(&nf_ct_cache_mutex); 257 mutex_unlock(&nf_ct_cache_mutex);
399} 258}
259EXPORT_SYMBOL_GPL(nf_conntrack_unregister_cache);
400 260
401int 261int
402nf_ct_get_tuple(const struct sk_buff *skb, 262nf_ct_get_tuple(const struct sk_buff *skb,
@@ -406,7 +266,7 @@ nf_ct_get_tuple(const struct sk_buff *skb,
406 u_int8_t protonum, 266 u_int8_t protonum,
407 struct nf_conntrack_tuple *tuple, 267 struct nf_conntrack_tuple *tuple,
408 const struct nf_conntrack_l3proto *l3proto, 268 const struct nf_conntrack_l3proto *l3proto,
409 const struct nf_conntrack_protocol *protocol) 269 const struct nf_conntrack_l4proto *l4proto)
410{ 270{
411 NF_CT_TUPLE_U_BLANK(tuple); 271 NF_CT_TUPLE_U_BLANK(tuple);
412 272
@@ -417,14 +277,15 @@ nf_ct_get_tuple(const struct sk_buff *skb,
417 tuple->dst.protonum = protonum; 277 tuple->dst.protonum = protonum;
418 tuple->dst.dir = IP_CT_DIR_ORIGINAL; 278 tuple->dst.dir = IP_CT_DIR_ORIGINAL;
419 279
420 return protocol->pkt_to_tuple(skb, dataoff, tuple); 280 return l4proto->pkt_to_tuple(skb, dataoff, tuple);
421} 281}
282EXPORT_SYMBOL_GPL(nf_ct_get_tuple);
422 283
423int 284int
424nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse, 285nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,
425 const struct nf_conntrack_tuple *orig, 286 const struct nf_conntrack_tuple *orig,
426 const struct nf_conntrack_l3proto *l3proto, 287 const struct nf_conntrack_l3proto *l3proto,
427 const struct nf_conntrack_protocol *protocol) 288 const struct nf_conntrack_l4proto *l4proto)
428{ 289{
429 NF_CT_TUPLE_U_BLANK(inverse); 290 NF_CT_TUPLE_U_BLANK(inverse);
430 291
@@ -435,111 +296,14 @@ nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse,
435 inverse->dst.dir = !orig->dst.dir; 296 inverse->dst.dir = !orig->dst.dir;
436 297
437 inverse->dst.protonum = orig->dst.protonum; 298 inverse->dst.protonum = orig->dst.protonum;
438 return protocol->invert_tuple(inverse, orig); 299 return l4proto->invert_tuple(inverse, orig);
439}
440
441/* nf_conntrack_expect helper functions */
442void nf_ct_unlink_expect(struct nf_conntrack_expect *exp)
443{
444 struct nf_conn_help *master_help = nfct_help(exp->master);
445
446 NF_CT_ASSERT(master_help);
447 ASSERT_WRITE_LOCK(&nf_conntrack_lock);
448 NF_CT_ASSERT(!timer_pending(&exp->timeout));
449
450 list_del(&exp->list);
451 NF_CT_STAT_INC(expect_delete);
452 master_help->expecting--;
453 nf_conntrack_expect_put(exp);
454}
455
456static void expectation_timed_out(unsigned long ul_expect)
457{
458 struct nf_conntrack_expect *exp = (void *)ul_expect;
459
460 write_lock_bh(&nf_conntrack_lock);
461 nf_ct_unlink_expect(exp);
462 write_unlock_bh(&nf_conntrack_lock);
463 nf_conntrack_expect_put(exp);
464}
465
466struct nf_conntrack_expect *
467__nf_conntrack_expect_find(const struct nf_conntrack_tuple *tuple)
468{
469 struct nf_conntrack_expect *i;
470
471 list_for_each_entry(i, &nf_conntrack_expect_list, list) {
472 if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask))
473 return i;
474 }
475 return NULL;
476}
477
478/* Just find a expectation corresponding to a tuple. */
479struct nf_conntrack_expect *
480nf_conntrack_expect_find(const struct nf_conntrack_tuple *tuple)
481{
482 struct nf_conntrack_expect *i;
483
484 read_lock_bh(&nf_conntrack_lock);
485 i = __nf_conntrack_expect_find(tuple);
486 if (i)
487 atomic_inc(&i->use);
488 read_unlock_bh(&nf_conntrack_lock);
489
490 return i;
491}
492
493/* If an expectation for this connection is found, it gets delete from
494 * global list then returned. */
495static struct nf_conntrack_expect *
496find_expectation(const struct nf_conntrack_tuple *tuple)
497{
498 struct nf_conntrack_expect *i;
499
500 list_for_each_entry(i, &nf_conntrack_expect_list, list) {
501 /* If master is not in hash table yet (ie. packet hasn't left
502 this machine yet), how can other end know about expected?
503 Hence these are not the droids you are looking for (if
504 master ct never got confirmed, we'd hold a reference to it
505 and weird things would happen to future packets). */
506 if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask)
507 && nf_ct_is_confirmed(i->master)) {
508 if (i->flags & NF_CT_EXPECT_PERMANENT) {
509 atomic_inc(&i->use);
510 return i;
511 } else if (del_timer(&i->timeout)) {
512 nf_ct_unlink_expect(i);
513 return i;
514 }
515 }
516 }
517 return NULL;
518}
519
520/* delete all expectations for this conntrack */
521void nf_ct_remove_expectations(struct nf_conn *ct)
522{
523 struct nf_conntrack_expect *i, *tmp;
524 struct nf_conn_help *help = nfct_help(ct);
525
526 /* Optimization: most connection never expect any others. */
527 if (!help || help->expecting == 0)
528 return;
529
530 list_for_each_entry_safe(i, tmp, &nf_conntrack_expect_list, list) {
531 if (i->master == ct && del_timer(&i->timeout)) {
532 nf_ct_unlink_expect(i);
533 nf_conntrack_expect_put(i);
534 }
535 }
536} 300}
301EXPORT_SYMBOL_GPL(nf_ct_invert_tuple);
537 302
538static void 303static void
539clean_from_lists(struct nf_conn *ct) 304clean_from_lists(struct nf_conn *ct)
540{ 305{
541 DEBUGP("clean_from_lists(%p)\n", ct); 306 DEBUGP("clean_from_lists(%p)\n", ct);
542 ASSERT_WRITE_LOCK(&nf_conntrack_lock);
543 list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list); 307 list_del(&ct->tuplehash[IP_CT_DIR_ORIGINAL].list);
544 list_del(&ct->tuplehash[IP_CT_DIR_REPLY].list); 308 list_del(&ct->tuplehash[IP_CT_DIR_REPLY].list);
545 309
@@ -551,8 +315,9 @@ static void
551destroy_conntrack(struct nf_conntrack *nfct) 315destroy_conntrack(struct nf_conntrack *nfct)
552{ 316{
553 struct nf_conn *ct = (struct nf_conn *)nfct; 317 struct nf_conn *ct = (struct nf_conn *)nfct;
318 struct nf_conn_help *help = nfct_help(ct);
554 struct nf_conntrack_l3proto *l3proto; 319 struct nf_conntrack_l3proto *l3proto;
555 struct nf_conntrack_protocol *proto; 320 struct nf_conntrack_l4proto *l4proto;
556 321
557 DEBUGP("destroy_conntrack(%p)\n", ct); 322 DEBUGP("destroy_conntrack(%p)\n", ct);
558 NF_CT_ASSERT(atomic_read(&nfct->use) == 0); 323 NF_CT_ASSERT(atomic_read(&nfct->use) == 0);
@@ -561,6 +326,9 @@ destroy_conntrack(struct nf_conntrack *nfct)
561 nf_conntrack_event(IPCT_DESTROY, ct); 326 nf_conntrack_event(IPCT_DESTROY, ct);
562 set_bit(IPS_DYING_BIT, &ct->status); 327 set_bit(IPS_DYING_BIT, &ct->status);
563 328
329 if (help && help->helper && help->helper->destroy)
330 help->helper->destroy(ct);
331
564 /* To make sure we don't get any weird locking issues here: 332 /* To make sure we don't get any weird locking issues here:
565 * destroy_conntrack() MUST NOT be called with a write lock 333 * destroy_conntrack() MUST NOT be called with a write lock
566 * to nf_conntrack_lock!!! -HW */ 334 * to nf_conntrack_lock!!! -HW */
@@ -568,9 +336,9 @@ destroy_conntrack(struct nf_conntrack *nfct)
568 if (l3proto && l3proto->destroy) 336 if (l3proto && l3proto->destroy)
569 l3proto->destroy(ct); 337 l3proto->destroy(ct);
570 338
571 proto = __nf_ct_proto_find(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.l3num, ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.protonum); 339 l4proto = __nf_ct_l4proto_find(ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.l3num, ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.protonum);
572 if (proto && proto->destroy) 340 if (l4proto && l4proto->destroy)
573 proto->destroy(ct); 341 l4proto->destroy(ct);
574 342
575 if (nf_conntrack_destroyed) 343 if (nf_conntrack_destroyed)
576 nf_conntrack_destroyed(ct); 344 nf_conntrack_destroyed(ct);
@@ -618,7 +386,6 @@ __nf_conntrack_find(const struct nf_conntrack_tuple *tuple,
618 struct nf_conntrack_tuple_hash *h; 386 struct nf_conntrack_tuple_hash *h;
619 unsigned int hash = hash_conntrack(tuple); 387 unsigned int hash = hash_conntrack(tuple);
620 388
621 ASSERT_READ_LOCK(&nf_conntrack_lock);
622 list_for_each_entry(h, &nf_conntrack_hash[hash], list) { 389 list_for_each_entry(h, &nf_conntrack_hash[hash], list) {
623 if (nf_ct_tuplehash_to_ctrack(h) != ignored_conntrack && 390 if (nf_ct_tuplehash_to_ctrack(h) != ignored_conntrack &&
624 nf_ct_tuple_equal(tuple, &h->tuple)) { 391 nf_ct_tuple_equal(tuple, &h->tuple)) {
@@ -630,6 +397,7 @@ __nf_conntrack_find(const struct nf_conntrack_tuple *tuple,
630 397
631 return NULL; 398 return NULL;
632} 399}
400EXPORT_SYMBOL_GPL(__nf_conntrack_find);
633 401
634/* Find a connection corresponding to a tuple. */ 402/* Find a connection corresponding to a tuple. */
635struct nf_conntrack_tuple_hash * 403struct nf_conntrack_tuple_hash *
@@ -646,6 +414,7 @@ nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple,
646 414
647 return h; 415 return h;
648} 416}
417EXPORT_SYMBOL_GPL(nf_conntrack_find_get);
649 418
650static void __nf_conntrack_hash_insert(struct nf_conn *ct, 419static void __nf_conntrack_hash_insert(struct nf_conn *ct,
651 unsigned int hash, 420 unsigned int hash,
@@ -669,6 +438,7 @@ void nf_conntrack_hash_insert(struct nf_conn *ct)
669 __nf_conntrack_hash_insert(ct, hash, repl_hash); 438 __nf_conntrack_hash_insert(ct, hash, repl_hash);
670 write_unlock_bh(&nf_conntrack_lock); 439 write_unlock_bh(&nf_conntrack_lock);
671} 440}
441EXPORT_SYMBOL_GPL(nf_conntrack_hash_insert);
672 442
673/* Confirm a connection given skb; places it in hash table */ 443/* Confirm a connection given skb; places it in hash table */
674int 444int
@@ -746,6 +516,7 @@ out:
746 write_unlock_bh(&nf_conntrack_lock); 516 write_unlock_bh(&nf_conntrack_lock);
747 return NF_DROP; 517 return NF_DROP;
748} 518}
519EXPORT_SYMBOL_GPL(__nf_conntrack_confirm);
749 520
750/* Returns true if a connection correspondings to the tuple (required 521/* Returns true if a connection correspondings to the tuple (required
751 for NAT). */ 522 for NAT). */
@@ -761,6 +532,7 @@ nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
761 532
762 return h != NULL; 533 return h != NULL;
763} 534}
535EXPORT_SYMBOL_GPL(nf_conntrack_tuple_taken);
764 536
765/* There's a small race here where we may free a just-assured 537/* There's a small race here where we may free a just-assured
766 connection. Too bad: we're in trouble anyway. */ 538 connection. Too bad: we're in trouble anyway. */
@@ -794,53 +566,13 @@ static int early_drop(struct list_head *chain)
794 return dropped; 566 return dropped;
795} 567}
796 568
797static struct nf_conntrack_helper *
798__nf_ct_helper_find(const struct nf_conntrack_tuple *tuple)
799{
800 struct nf_conntrack_helper *h;
801
802 list_for_each_entry(h, &helpers, list) {
803 if (nf_ct_tuple_mask_cmp(tuple, &h->tuple, &h->mask))
804 return h;
805 }
806 return NULL;
807}
808
809struct nf_conntrack_helper *
810nf_ct_helper_find_get( const struct nf_conntrack_tuple *tuple)
811{
812 struct nf_conntrack_helper *helper;
813
814 /* need nf_conntrack_lock to assure that helper exists until
815 * try_module_get() is called */
816 read_lock_bh(&nf_conntrack_lock);
817
818 helper = __nf_ct_helper_find(tuple);
819 if (helper) {
820 /* need to increase module usage count to assure helper will
821 * not go away while the caller is e.g. busy putting a
822 * conntrack in the hash that uses the helper */
823 if (!try_module_get(helper->me))
824 helper = NULL;
825 }
826
827 read_unlock_bh(&nf_conntrack_lock);
828
829 return helper;
830}
831
832void nf_ct_helper_put(struct nf_conntrack_helper *helper)
833{
834 module_put(helper->me);
835}
836
837static struct nf_conn * 569static struct nf_conn *
838__nf_conntrack_alloc(const struct nf_conntrack_tuple *orig, 570__nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
839 const struct nf_conntrack_tuple *repl, 571 const struct nf_conntrack_tuple *repl,
840 const struct nf_conntrack_l3proto *l3proto) 572 const struct nf_conntrack_l3proto *l3proto,
573 u_int32_t features)
841{ 574{
842 struct nf_conn *conntrack = NULL; 575 struct nf_conn *conntrack = NULL;
843 u_int32_t features = 0;
844 struct nf_conntrack_helper *helper; 576 struct nf_conntrack_helper *helper;
845 577
846 if (unlikely(!nf_conntrack_hash_rnd_initted)) { 578 if (unlikely(!nf_conntrack_hash_rnd_initted)) {
@@ -866,12 +598,13 @@ __nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
866 } 598 }
867 599
868 /* find features needed by this conntrack. */ 600 /* find features needed by this conntrack. */
869 features = l3proto->get_features(orig); 601 features |= l3proto->get_features(orig);
870 602
871 /* FIXME: protect helper list per RCU */ 603 /* FIXME: protect helper list per RCU */
872 read_lock_bh(&nf_conntrack_lock); 604 read_lock_bh(&nf_conntrack_lock);
873 helper = __nf_ct_helper_find(repl); 605 helper = __nf_ct_helper_find(repl);
874 if (helper) 606 /* NAT might want to assign a helper later */
607 if (helper || features & NF_CT_F_NAT)
875 features |= NF_CT_F_HELP; 608 features |= NF_CT_F_HELP;
876 read_unlock_bh(&nf_conntrack_lock); 609 read_unlock_bh(&nf_conntrack_lock);
877 610
@@ -916,8 +649,9 @@ struct nf_conn *nf_conntrack_alloc(const struct nf_conntrack_tuple *orig,
916 struct nf_conntrack_l3proto *l3proto; 649 struct nf_conntrack_l3proto *l3proto;
917 650
918 l3proto = __nf_ct_l3proto_find(orig->src.l3num); 651 l3proto = __nf_ct_l3proto_find(orig->src.l3num);
919 return __nf_conntrack_alloc(orig, repl, l3proto); 652 return __nf_conntrack_alloc(orig, repl, l3proto, 0);
920} 653}
654EXPORT_SYMBOL_GPL(nf_conntrack_alloc);
921 655
922void nf_conntrack_free(struct nf_conn *conntrack) 656void nf_conntrack_free(struct nf_conn *conntrack)
923{ 657{
@@ -928,32 +662,40 @@ void nf_conntrack_free(struct nf_conn *conntrack)
928 kmem_cache_free(nf_ct_cache[features].cachep, conntrack); 662 kmem_cache_free(nf_ct_cache[features].cachep, conntrack);
929 atomic_dec(&nf_conntrack_count); 663 atomic_dec(&nf_conntrack_count);
930} 664}
665EXPORT_SYMBOL_GPL(nf_conntrack_free);
931 666
932/* Allocate a new conntrack: we return -ENOMEM if classification 667/* Allocate a new conntrack: we return -ENOMEM if classification
933 failed due to stress. Otherwise it really is unclassifiable. */ 668 failed due to stress. Otherwise it really is unclassifiable. */
934static struct nf_conntrack_tuple_hash * 669static struct nf_conntrack_tuple_hash *
935init_conntrack(const struct nf_conntrack_tuple *tuple, 670init_conntrack(const struct nf_conntrack_tuple *tuple,
936 struct nf_conntrack_l3proto *l3proto, 671 struct nf_conntrack_l3proto *l3proto,
937 struct nf_conntrack_protocol *protocol, 672 struct nf_conntrack_l4proto *l4proto,
938 struct sk_buff *skb, 673 struct sk_buff *skb,
939 unsigned int dataoff) 674 unsigned int dataoff)
940{ 675{
941 struct nf_conn *conntrack; 676 struct nf_conn *conntrack;
942 struct nf_conntrack_tuple repl_tuple; 677 struct nf_conntrack_tuple repl_tuple;
943 struct nf_conntrack_expect *exp; 678 struct nf_conntrack_expect *exp;
679 u_int32_t features = 0;
944 680
945 if (!nf_ct_invert_tuple(&repl_tuple, tuple, l3proto, protocol)) { 681 if (!nf_ct_invert_tuple(&repl_tuple, tuple, l3proto, l4proto)) {
946 DEBUGP("Can't invert tuple.\n"); 682 DEBUGP("Can't invert tuple.\n");
947 return NULL; 683 return NULL;
948 } 684 }
949 685
950 conntrack = __nf_conntrack_alloc(tuple, &repl_tuple, l3proto); 686 read_lock_bh(&nf_conntrack_lock);
687 exp = __nf_conntrack_expect_find(tuple);
688 if (exp && exp->helper)
689 features = NF_CT_F_HELP;
690 read_unlock_bh(&nf_conntrack_lock);
691
692 conntrack = __nf_conntrack_alloc(tuple, &repl_tuple, l3proto, features);
951 if (conntrack == NULL || IS_ERR(conntrack)) { 693 if (conntrack == NULL || IS_ERR(conntrack)) {
952 DEBUGP("Can't allocate conntrack.\n"); 694 DEBUGP("Can't allocate conntrack.\n");
953 return (struct nf_conntrack_tuple_hash *)conntrack; 695 return (struct nf_conntrack_tuple_hash *)conntrack;
954 } 696 }
955 697
956 if (!protocol->new(conntrack, skb, dataoff)) { 698 if (!l4proto->new(conntrack, skb, dataoff)) {
957 nf_conntrack_free(conntrack); 699 nf_conntrack_free(conntrack);
958 DEBUGP("init conntrack: can't track with proto module\n"); 700 DEBUGP("init conntrack: can't track with proto module\n");
959 return NULL; 701 return NULL;
@@ -968,6 +710,8 @@ init_conntrack(const struct nf_conntrack_tuple *tuple,
968 /* Welcome, Mr. Bond. We've been expecting you... */ 710 /* Welcome, Mr. Bond. We've been expecting you... */
969 __set_bit(IPS_EXPECTED_BIT, &conntrack->status); 711 __set_bit(IPS_EXPECTED_BIT, &conntrack->status);
970 conntrack->master = exp->master; 712 conntrack->master = exp->master;
713 if (exp->helper)
714 nfct_help(conntrack)->helper = exp->helper;
971#ifdef CONFIG_NF_CONNTRACK_MARK 715#ifdef CONFIG_NF_CONNTRACK_MARK
972 conntrack->mark = exp->master->mark; 716 conntrack->mark = exp->master->mark;
973#endif 717#endif
@@ -1005,7 +749,7 @@ resolve_normal_ct(struct sk_buff *skb,
1005 u_int16_t l3num, 749 u_int16_t l3num,
1006 u_int8_t protonum, 750 u_int8_t protonum,
1007 struct nf_conntrack_l3proto *l3proto, 751 struct nf_conntrack_l3proto *l3proto,
1008 struct nf_conntrack_protocol *proto, 752 struct nf_conntrack_l4proto *l4proto,
1009 int *set_reply, 753 int *set_reply,
1010 enum ip_conntrack_info *ctinfo) 754 enum ip_conntrack_info *ctinfo)
1011{ 755{
@@ -1015,7 +759,7 @@ resolve_normal_ct(struct sk_buff *skb,
1015 759
1016 if (!nf_ct_get_tuple(skb, (unsigned int)(skb->nh.raw - skb->data), 760 if (!nf_ct_get_tuple(skb, (unsigned int)(skb->nh.raw - skb->data),
1017 dataoff, l3num, protonum, &tuple, l3proto, 761 dataoff, l3num, protonum, &tuple, l3proto,
1018 proto)) { 762 l4proto)) {
1019 DEBUGP("resolve_normal_ct: Can't get tuple\n"); 763 DEBUGP("resolve_normal_ct: Can't get tuple\n");
1020 return NULL; 764 return NULL;
1021 } 765 }
@@ -1023,7 +767,7 @@ resolve_normal_ct(struct sk_buff *skb,
1023 /* look for tuple match */ 767 /* look for tuple match */
1024 h = nf_conntrack_find_get(&tuple, NULL); 768 h = nf_conntrack_find_get(&tuple, NULL);
1025 if (!h) { 769 if (!h) {
1026 h = init_conntrack(&tuple, l3proto, proto, skb, dataoff); 770 h = init_conntrack(&tuple, l3proto, l4proto, skb, dataoff);
1027 if (!h) 771 if (!h)
1028 return NULL; 772 return NULL;
1029 if (IS_ERR(h)) 773 if (IS_ERR(h))
@@ -1061,7 +805,7 @@ nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff **pskb)
1061 struct nf_conn *ct; 805 struct nf_conn *ct;
1062 enum ip_conntrack_info ctinfo; 806 enum ip_conntrack_info ctinfo;
1063 struct nf_conntrack_l3proto *l3proto; 807 struct nf_conntrack_l3proto *l3proto;
1064 struct nf_conntrack_protocol *proto; 808 struct nf_conntrack_l4proto *l4proto;
1065 unsigned int dataoff; 809 unsigned int dataoff;
1066 u_int8_t protonum; 810 u_int8_t protonum;
1067 int set_reply = 0; 811 int set_reply = 0;
@@ -1079,19 +823,19 @@ nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff **pskb)
1079 return -ret; 823 return -ret;
1080 } 824 }
1081 825
1082 proto = __nf_ct_proto_find((u_int16_t)pf, protonum); 826 l4proto = __nf_ct_l4proto_find((u_int16_t)pf, protonum);
1083 827
1084 /* It may be an special packet, error, unclean... 828 /* It may be an special packet, error, unclean...
1085 * inverse of the return code tells to the netfilter 829 * inverse of the return code tells to the netfilter
1086 * core what to do with the packet. */ 830 * core what to do with the packet. */
1087 if (proto->error != NULL && 831 if (l4proto->error != NULL &&
1088 (ret = proto->error(*pskb, dataoff, &ctinfo, pf, hooknum)) <= 0) { 832 (ret = l4proto->error(*pskb, dataoff, &ctinfo, pf, hooknum)) <= 0) {
1089 NF_CT_STAT_INC(error); 833 NF_CT_STAT_INC(error);
1090 NF_CT_STAT_INC(invalid); 834 NF_CT_STAT_INC(invalid);
1091 return -ret; 835 return -ret;
1092 } 836 }
1093 837
1094 ct = resolve_normal_ct(*pskb, dataoff, pf, protonum, l3proto, proto, 838 ct = resolve_normal_ct(*pskb, dataoff, pf, protonum, l3proto, l4proto,
1095 &set_reply, &ctinfo); 839 &set_reply, &ctinfo);
1096 if (!ct) { 840 if (!ct) {
1097 /* Not valid part of a connection */ 841 /* Not valid part of a connection */
@@ -1107,7 +851,7 @@ nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff **pskb)
1107 851
1108 NF_CT_ASSERT((*pskb)->nfct); 852 NF_CT_ASSERT((*pskb)->nfct);
1109 853
1110 ret = proto->packet(ct, *pskb, dataoff, ctinfo, pf, hooknum); 854 ret = l4proto->packet(ct, *pskb, dataoff, ctinfo, pf, hooknum);
1111 if (ret < 0) { 855 if (ret < 0) {
1112 /* Invalid: inverse of the return code tells 856 /* Invalid: inverse of the return code tells
1113 * the netfilter core what to do */ 857 * the netfilter core what to do */
@@ -1123,255 +867,38 @@ nf_conntrack_in(int pf, unsigned int hooknum, struct sk_buff **pskb)
1123 867
1124 return ret; 868 return ret;
1125} 869}
870EXPORT_SYMBOL_GPL(nf_conntrack_in);
1126 871
1127int nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse, 872int nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse,
1128 const struct nf_conntrack_tuple *orig) 873 const struct nf_conntrack_tuple *orig)
1129{ 874{
1130 return nf_ct_invert_tuple(inverse, orig, 875 return nf_ct_invert_tuple(inverse, orig,
1131 __nf_ct_l3proto_find(orig->src.l3num), 876 __nf_ct_l3proto_find(orig->src.l3num),
1132 __nf_ct_proto_find(orig->src.l3num, 877 __nf_ct_l4proto_find(orig->src.l3num,
1133 orig->dst.protonum)); 878 orig->dst.protonum));
1134} 879}
880EXPORT_SYMBOL_GPL(nf_ct_invert_tuplepr);
1135 881
1136/* Would two expected things clash? */ 882/* Alter reply tuple (maybe alter helper). This is for NAT, and is
1137static inline int expect_clash(const struct nf_conntrack_expect *a, 883 implicitly racy: see __nf_conntrack_confirm */
1138 const struct nf_conntrack_expect *b) 884void nf_conntrack_alter_reply(struct nf_conn *ct,
1139{ 885 const struct nf_conntrack_tuple *newreply)
1140 /* Part covered by intersection of masks must be unequal,
1141 otherwise they clash */
1142 struct nf_conntrack_tuple intersect_mask;
1143 int count;
1144
1145 intersect_mask.src.l3num = a->mask.src.l3num & b->mask.src.l3num;
1146 intersect_mask.src.u.all = a->mask.src.u.all & b->mask.src.u.all;
1147 intersect_mask.dst.u.all = a->mask.dst.u.all & b->mask.dst.u.all;
1148 intersect_mask.dst.protonum = a->mask.dst.protonum
1149 & b->mask.dst.protonum;
1150
1151 for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
1152 intersect_mask.src.u3.all[count] =
1153 a->mask.src.u3.all[count] & b->mask.src.u3.all[count];
1154 }
1155
1156 for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
1157 intersect_mask.dst.u3.all[count] =
1158 a->mask.dst.u3.all[count] & b->mask.dst.u3.all[count];
1159 }
1160
1161 return nf_ct_tuple_mask_cmp(&a->tuple, &b->tuple, &intersect_mask);
1162}
1163
1164static inline int expect_matches(const struct nf_conntrack_expect *a,
1165 const struct nf_conntrack_expect *b)
1166{
1167 return a->master == b->master
1168 && nf_ct_tuple_equal(&a->tuple, &b->tuple)
1169 && nf_ct_tuple_equal(&a->mask, &b->mask);
1170}
1171
1172/* Generally a bad idea to call this: could have matched already. */
1173void nf_conntrack_unexpect_related(struct nf_conntrack_expect *exp)
1174{
1175 struct nf_conntrack_expect *i;
1176
1177 write_lock_bh(&nf_conntrack_lock);
1178 /* choose the the oldest expectation to evict */
1179 list_for_each_entry_reverse(i, &nf_conntrack_expect_list, list) {
1180 if (expect_matches(i, exp) && del_timer(&i->timeout)) {
1181 nf_ct_unlink_expect(i);
1182 write_unlock_bh(&nf_conntrack_lock);
1183 nf_conntrack_expect_put(i);
1184 return;
1185 }
1186 }
1187 write_unlock_bh(&nf_conntrack_lock);
1188}
1189
1190/* We don't increase the master conntrack refcount for non-fulfilled
1191 * conntracks. During the conntrack destruction, the expectations are
1192 * always killed before the conntrack itself */
1193struct nf_conntrack_expect *nf_conntrack_expect_alloc(struct nf_conn *me)
1194{
1195 struct nf_conntrack_expect *new;
1196
1197 new = kmem_cache_alloc(nf_conntrack_expect_cachep, GFP_ATOMIC);
1198 if (!new) {
1199 DEBUGP("expect_related: OOM allocating expect\n");
1200 return NULL;
1201 }
1202 new->master = me;
1203 atomic_set(&new->use, 1);
1204 return new;
1205}
1206
1207void nf_conntrack_expect_put(struct nf_conntrack_expect *exp)
1208{
1209 if (atomic_dec_and_test(&exp->use))
1210 kmem_cache_free(nf_conntrack_expect_cachep, exp);
1211}
1212
1213static void nf_conntrack_expect_insert(struct nf_conntrack_expect *exp)
1214{
1215 struct nf_conn_help *master_help = nfct_help(exp->master);
1216
1217 atomic_inc(&exp->use);
1218 master_help->expecting++;
1219 list_add(&exp->list, &nf_conntrack_expect_list);
1220
1221 init_timer(&exp->timeout);
1222 exp->timeout.data = (unsigned long)exp;
1223 exp->timeout.function = expectation_timed_out;
1224 exp->timeout.expires = jiffies + master_help->helper->timeout * HZ;
1225 add_timer(&exp->timeout);
1226
1227 exp->id = ++nf_conntrack_expect_next_id;
1228 atomic_inc(&exp->use);
1229 NF_CT_STAT_INC(expect_create);
1230}
1231
1232/* Race with expectations being used means we could have none to find; OK. */
1233static void evict_oldest_expect(struct nf_conn *master)
1234{
1235 struct nf_conntrack_expect *i;
1236
1237 list_for_each_entry_reverse(i, &nf_conntrack_expect_list, list) {
1238 if (i->master == master) {
1239 if (del_timer(&i->timeout)) {
1240 nf_ct_unlink_expect(i);
1241 nf_conntrack_expect_put(i);
1242 }
1243 break;
1244 }
1245 }
1246}
1247
1248static inline int refresh_timer(struct nf_conntrack_expect *i)
1249{
1250 struct nf_conn_help *master_help = nfct_help(i->master);
1251
1252 if (!del_timer(&i->timeout))
1253 return 0;
1254
1255 i->timeout.expires = jiffies + master_help->helper->timeout*HZ;
1256 add_timer(&i->timeout);
1257 return 1;
1258}
1259
1260int nf_conntrack_expect_related(struct nf_conntrack_expect *expect)
1261{
1262 struct nf_conntrack_expect *i;
1263 struct nf_conn *master = expect->master;
1264 struct nf_conn_help *master_help = nfct_help(master);
1265 int ret;
1266
1267 NF_CT_ASSERT(master_help);
1268
1269 DEBUGP("nf_conntrack_expect_related %p\n", related_to);
1270 DEBUGP("tuple: "); NF_CT_DUMP_TUPLE(&expect->tuple);
1271 DEBUGP("mask: "); NF_CT_DUMP_TUPLE(&expect->mask);
1272
1273 write_lock_bh(&nf_conntrack_lock);
1274 list_for_each_entry(i, &nf_conntrack_expect_list, list) {
1275 if (expect_matches(i, expect)) {
1276 /* Refresh timer: if it's dying, ignore.. */
1277 if (refresh_timer(i)) {
1278 ret = 0;
1279 goto out;
1280 }
1281 } else if (expect_clash(i, expect)) {
1282 ret = -EBUSY;
1283 goto out;
1284 }
1285 }
1286 /* Will be over limit? */
1287 if (master_help->helper->max_expected &&
1288 master_help->expecting >= master_help->helper->max_expected)
1289 evict_oldest_expect(master);
1290
1291 nf_conntrack_expect_insert(expect);
1292 nf_conntrack_expect_event(IPEXP_NEW, expect);
1293 ret = 0;
1294out:
1295 write_unlock_bh(&nf_conntrack_lock);
1296 return ret;
1297}
1298
1299int nf_conntrack_helper_register(struct nf_conntrack_helper *me)
1300{
1301 int ret;
1302 BUG_ON(me->timeout == 0);
1303
1304 ret = nf_conntrack_register_cache(NF_CT_F_HELP, "nf_conntrack:help",
1305 sizeof(struct nf_conn)
1306 + sizeof(struct nf_conn_help)
1307 + __alignof__(struct nf_conn_help));
1308 if (ret < 0) {
1309 printk(KERN_ERR "nf_conntrack_helper_reigster: Unable to create slab cache for conntracks\n");
1310 return ret;
1311 }
1312 write_lock_bh(&nf_conntrack_lock);
1313 list_add(&me->list, &helpers);
1314 write_unlock_bh(&nf_conntrack_lock);
1315
1316 return 0;
1317}
1318
1319struct nf_conntrack_helper *
1320__nf_conntrack_helper_find_byname(const char *name)
1321{ 886{
1322 struct nf_conntrack_helper *h;
1323
1324 list_for_each_entry(h, &helpers, list) {
1325 if (!strcmp(h->name, name))
1326 return h;
1327 }
1328
1329 return NULL;
1330}
1331
1332static inline void unhelp(struct nf_conntrack_tuple_hash *i,
1333 const struct nf_conntrack_helper *me)
1334{
1335 struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(i);
1336 struct nf_conn_help *help = nfct_help(ct); 887 struct nf_conn_help *help = nfct_help(ct);
1337 888
1338 if (help && help->helper == me) {
1339 nf_conntrack_event(IPCT_HELPER, ct);
1340 help->helper = NULL;
1341 }
1342}
1343
1344void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
1345{
1346 unsigned int i;
1347 struct nf_conntrack_tuple_hash *h;
1348 struct nf_conntrack_expect *exp, *tmp;
1349
1350 /* Need write lock here, to delete helper. */
1351 write_lock_bh(&nf_conntrack_lock); 889 write_lock_bh(&nf_conntrack_lock);
1352 list_del(&me->list); 890 /* Should be unconfirmed, so not in hash table yet */
1353 891 NF_CT_ASSERT(!nf_ct_is_confirmed(ct));
1354 /* Get rid of expectations */
1355 list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list, list) {
1356 struct nf_conn_help *help = nfct_help(exp->master);
1357 if (help->helper == me && del_timer(&exp->timeout)) {
1358 nf_ct_unlink_expect(exp);
1359 nf_conntrack_expect_put(exp);
1360 }
1361 }
1362 892
1363 /* Get rid of expecteds, set helpers to NULL. */ 893 DEBUGP("Altering reply tuple of %p to ", ct);
1364 list_for_each_entry(h, &unconfirmed, list) 894 NF_CT_DUMP_TUPLE(newreply);
1365 unhelp(h, me);
1366 for (i = 0; i < nf_conntrack_htable_size; i++) {
1367 list_for_each_entry(h, &nf_conntrack_hash[i], list)
1368 unhelp(h, me);
1369 }
1370 write_unlock_bh(&nf_conntrack_lock);
1371 895
1372 /* Someone could be still looking at the helper in a bh. */ 896 ct->tuplehash[IP_CT_DIR_REPLY].tuple = *newreply;
1373 synchronize_net(); 897 if (!ct->master && help && help->expecting == 0)
898 help->helper = __nf_ct_helper_find(newreply);
899 write_unlock_bh(&nf_conntrack_lock);
1374} 900}
901EXPORT_SYMBOL_GPL(nf_conntrack_alter_reply);
1375 902
1376/* Refresh conntrack for this many jiffies and do accounting if do_acct is 1 */ 903/* Refresh conntrack for this many jiffies and do accounting if do_acct is 1 */
1377void __nf_ct_refresh_acct(struct nf_conn *ct, 904void __nf_ct_refresh_acct(struct nf_conn *ct,
@@ -1398,9 +925,14 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,
1398 ct->timeout.expires = extra_jiffies; 925 ct->timeout.expires = extra_jiffies;
1399 event = IPCT_REFRESH; 926 event = IPCT_REFRESH;
1400 } else { 927 } else {
1401 /* Need del_timer for race avoidance (may already be dying). */ 928 unsigned long newtime = jiffies + extra_jiffies;
1402 if (del_timer(&ct->timeout)) { 929
1403 ct->timeout.expires = jiffies + extra_jiffies; 930 /* Only update the timeout if the new timeout is at least
931 HZ jiffies from the old timeout. Need del_timer for race
932 avoidance (may already be dying). */
933 if (newtime - ct->timeout.expires >= HZ
934 && del_timer(&ct->timeout)) {
935 ct->timeout.expires = newtime;
1404 add_timer(&ct->timeout); 936 add_timer(&ct->timeout);
1405 event = IPCT_REFRESH; 937 event = IPCT_REFRESH;
1406 } 938 }
@@ -1411,9 +943,10 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,
1411 ct->counters[CTINFO2DIR(ctinfo)].packets++; 943 ct->counters[CTINFO2DIR(ctinfo)].packets++;
1412 ct->counters[CTINFO2DIR(ctinfo)].bytes += 944 ct->counters[CTINFO2DIR(ctinfo)].bytes +=
1413 skb->len - (unsigned int)(skb->nh.raw - skb->data); 945 skb->len - (unsigned int)(skb->nh.raw - skb->data);
1414 if ((ct->counters[CTINFO2DIR(ctinfo)].packets & 0x80000000) 946
1415 || (ct->counters[CTINFO2DIR(ctinfo)].bytes & 0x80000000)) 947 if ((ct->counters[CTINFO2DIR(ctinfo)].packets & 0x80000000)
1416 event |= IPCT_COUNTER_FILLING; 948 || (ct->counters[CTINFO2DIR(ctinfo)].bytes & 0x80000000))
949 event |= IPCT_COUNTER_FILLING;
1417 } 950 }
1418#endif 951#endif
1419 952
@@ -1423,6 +956,7 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,
1423 if (event) 956 if (event)
1424 nf_conntrack_event_cache(event, skb); 957 nf_conntrack_event_cache(event, skb);
1425} 958}
959EXPORT_SYMBOL_GPL(__nf_ct_refresh_acct);
1426 960
1427#if defined(CONFIG_NF_CT_NETLINK) || \ 961#if defined(CONFIG_NF_CT_NETLINK) || \
1428 defined(CONFIG_NF_CT_NETLINK_MODULE) 962 defined(CONFIG_NF_CT_NETLINK_MODULE)
@@ -1447,6 +981,7 @@ int nf_ct_port_tuple_to_nfattr(struct sk_buff *skb,
1447nfattr_failure: 981nfattr_failure:
1448 return -1; 982 return -1;
1449} 983}
984EXPORT_SYMBOL_GPL(nf_ct_port_tuple_to_nfattr);
1450 985
1451static const size_t cta_min_proto[CTA_PROTO_MAX] = { 986static const size_t cta_min_proto[CTA_PROTO_MAX] = {
1452 [CTA_PROTO_SRC_PORT-1] = sizeof(u_int16_t), 987 [CTA_PROTO_SRC_PORT-1] = sizeof(u_int16_t),
@@ -1462,13 +997,12 @@ int nf_ct_port_nfattr_to_tuple(struct nfattr *tb[],
1462 if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto)) 997 if (nfattr_bad_size(tb, CTA_PROTO_MAX, cta_min_proto))
1463 return -EINVAL; 998 return -EINVAL;
1464 999
1465 t->src.u.tcp.port = 1000 t->src.u.tcp.port = *(__be16 *)NFA_DATA(tb[CTA_PROTO_SRC_PORT-1]);
1466 *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_SRC_PORT-1]); 1001 t->dst.u.tcp.port = *(__be16 *)NFA_DATA(tb[CTA_PROTO_DST_PORT-1]);
1467 t->dst.u.tcp.port =
1468 *(u_int16_t *)NFA_DATA(tb[CTA_PROTO_DST_PORT-1]);
1469 1002
1470 return 0; 1003 return 0;
1471} 1004}
1005EXPORT_SYMBOL_GPL(nf_ct_port_nfattr_to_tuple);
1472#endif 1006#endif
1473 1007
1474/* Used by ipt_REJECT and ip6t_REJECT. */ 1008/* Used by ipt_REJECT and ip6t_REJECT. */
@@ -1489,6 +1023,7 @@ void __nf_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb)
1489 nskb->nfctinfo = ctinfo; 1023 nskb->nfctinfo = ctinfo;
1490 nf_conntrack_get(nskb->nfct); 1024 nf_conntrack_get(nskb->nfct);
1491} 1025}
1026EXPORT_SYMBOL_GPL(__nf_conntrack_attach);
1492 1027
1493static inline int 1028static inline int
1494do_iter(const struct nf_conntrack_tuple_hash *i, 1029do_iter(const struct nf_conntrack_tuple_hash *i,
@@ -1542,6 +1077,7 @@ nf_ct_iterate_cleanup(int (*iter)(struct nf_conn *i, void *data), void *data)
1542 nf_ct_put(ct); 1077 nf_ct_put(ct);
1543 } 1078 }
1544} 1079}
1080EXPORT_SYMBOL_GPL(nf_ct_iterate_cleanup);
1545 1081
1546static int kill_all(struct nf_conn *i, void *data) 1082static int kill_all(struct nf_conn *i, void *data)
1547{ 1083{
@@ -1557,10 +1093,11 @@ static void free_conntrack_hash(struct list_head *hash, int vmalloced, int size)
1557 get_order(sizeof(struct list_head) * size)); 1093 get_order(sizeof(struct list_head) * size));
1558} 1094}
1559 1095
1560void nf_conntrack_flush() 1096void nf_conntrack_flush(void)
1561{ 1097{
1562 nf_ct_iterate_cleanup(kill_all, NULL); 1098 nf_ct_iterate_cleanup(kill_all, NULL);
1563} 1099}
1100EXPORT_SYMBOL_GPL(nf_conntrack_flush);
1564 1101
1565/* Mishearing the voices in his head, our hero wonders how he's 1102/* Mishearing the voices in his head, our hero wonders how he's
1566 supposed to kill the mall. */ 1103 supposed to kill the mall. */
@@ -1598,6 +1135,8 @@ void nf_conntrack_cleanup(void)
1598 free_conntrack_hash(nf_conntrack_hash, nf_conntrack_vmalloc, 1135 free_conntrack_hash(nf_conntrack_hash, nf_conntrack_vmalloc,
1599 nf_conntrack_htable_size); 1136 nf_conntrack_htable_size);
1600 1137
1138 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_generic);
1139
1601 /* free l3proto protocol tables */ 1140 /* free l3proto protocol tables */
1602 for (i = 0; i < PF_MAX; i++) 1141 for (i = 0; i < PF_MAX; i++)
1603 if (nf_ct_protos[i]) { 1142 if (nf_ct_protos[i]) {
@@ -1723,10 +1262,14 @@ int __init nf_conntrack_init(void)
1723 goto err_free_conntrack_slab; 1262 goto err_free_conntrack_slab;
1724 } 1263 }
1725 1264
1265 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_generic);
1266 if (ret < 0)
1267 goto out_free_expect_slab;
1268
1726 /* Don't NEED lock here, but good form anyway. */ 1269 /* Don't NEED lock here, but good form anyway. */
1727 write_lock_bh(&nf_conntrack_lock); 1270 write_lock_bh(&nf_conntrack_lock);
1728 for (i = 0; i < PF_MAX; i++) 1271 for (i = 0; i < AF_MAX; i++)
1729 nf_ct_l3protos[i] = &nf_conntrack_generic_l3proto; 1272 nf_ct_l3protos[i] = &nf_conntrack_l3proto_generic;
1730 write_unlock_bh(&nf_conntrack_lock); 1273 write_unlock_bh(&nf_conntrack_lock);
1731 1274
1732 /* For use by REJECT target */ 1275 /* For use by REJECT target */
@@ -1740,6 +1283,8 @@ int __init nf_conntrack_init(void)
1740 1283
1741 return ret; 1284 return ret;
1742 1285
1286out_free_expect_slab:
1287 kmem_cache_destroy(nf_conntrack_expect_cachep);
1743err_free_conntrack_slab: 1288err_free_conntrack_slab:
1744 nf_conntrack_unregister_cache(NF_CT_F_BASIC); 1289 nf_conntrack_unregister_cache(NF_CT_F_BASIC);
1745err_free_hash: 1290err_free_hash:
diff --git a/net/netfilter/nf_conntrack_ecache.c b/net/netfilter/nf_conntrack_ecache.c
new file mode 100644
index 0000000000..1a223e0c08
--- /dev/null
+++ b/net/netfilter/nf_conntrack_ecache.c
@@ -0,0 +1,93 @@
1/* Event cache for netfilter. */
2
3/* (C) 1999-2001 Paul `Rusty' Russell
4 * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
5 * (C) 2003,2004 USAGI/WIDE Project <http://www.linux-ipv6.org>
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#include <linux/types.h>
13#include <linux/netfilter.h>
14#include <linux/skbuff.h>
15#include <linux/vmalloc.h>
16#include <linux/stddef.h>
17#include <linux/err.h>
18#include <linux/percpu.h>
19#include <linux/notifier.h>
20#include <linux/kernel.h>
21#include <linux/netdevice.h>
22
23#include <net/netfilter/nf_conntrack.h>
24#include <net/netfilter/nf_conntrack_core.h>
25
26ATOMIC_NOTIFIER_HEAD(nf_conntrack_chain);
27EXPORT_SYMBOL_GPL(nf_conntrack_chain);
28
29ATOMIC_NOTIFIER_HEAD(nf_conntrack_expect_chain);
30EXPORT_SYMBOL_GPL(nf_conntrack_expect_chain);
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
36 * disabled softirqs */
37static inline void
38__nf_ct_deliver_cached_events(struct nf_conntrack_ecache *ecache)
39{
40 if (nf_ct_is_confirmed(ecache->ct) && !nf_ct_is_dying(ecache->ct)
41 && ecache->events)
42 atomic_notifier_call_chain(&nf_conntrack_chain, ecache->events,
43 ecache->ct);
44
45 ecache->events = 0;
46 nf_ct_put(ecache->ct);
47 ecache->ct = NULL;
48}
49
50/* Deliver all cached events for a particular conntrack. This is called
51 * by code prior to async packet handling for freeing the skb */
52void nf_ct_deliver_cached_events(const struct nf_conn *ct)
53{
54 struct nf_conntrack_ecache *ecache;
55
56 local_bh_disable();
57 ecache = &__get_cpu_var(nf_conntrack_ecache);
58 if (ecache->ct == ct)
59 __nf_ct_deliver_cached_events(ecache);
60 local_bh_enable();
61}
62EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
63
64/* Deliver cached events for old pending events, if current conntrack != old */
65void __nf_ct_event_cache_init(struct nf_conn *ct)
66{
67 struct nf_conntrack_ecache *ecache;
68
69 /* take care of delivering potentially old events */
70 ecache = &__get_cpu_var(nf_conntrack_ecache);
71 BUG_ON(ecache->ct == ct);
72 if (ecache->ct)
73 __nf_ct_deliver_cached_events(ecache);
74 /* initialize for this conntrack/packet */
75 ecache->ct = ct;
76 nf_conntrack_get(&ct->ct_general);
77}
78EXPORT_SYMBOL_GPL(__nf_ct_event_cache_init);
79
80/* flush the event cache - touches other CPU's data and must not be called
81 * while packets are still passing through the code */
82void nf_ct_event_cache_flush(void)
83{
84 struct nf_conntrack_ecache *ecache;
85 int cpu;
86
87 for_each_possible_cpu(cpu) {
88 ecache = &per_cpu(nf_conntrack_ecache, cpu);
89 if (ecache->ct)
90 nf_ct_put(ecache->ct);
91 }
92}
93
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
new file mode 100644
index 0000000000..9cbf926cdd
--- /dev/null
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -0,0 +1,445 @@
1/* Expectation handling for nf_conntrack. */
2
3/* (C) 1999-2001 Paul `Rusty' Russell
4 * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
5 * (C) 2003,2004 USAGI/WIDE Project <http://www.linux-ipv6.org>
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#include <linux/types.h>
13#include <linux/netfilter.h>
14#include <linux/skbuff.h>
15#include <linux/proc_fs.h>
16#include <linux/seq_file.h>
17#include <linux/stddef.h>
18#include <linux/slab.h>
19#include <linux/err.h>
20#include <linux/percpu.h>
21#include <linux/kernel.h>
22
23#include <net/netfilter/nf_conntrack.h>
24#include <net/netfilter/nf_conntrack_core.h>
25#include <net/netfilter/nf_conntrack_expect.h>
26#include <net/netfilter/nf_conntrack_helper.h>
27#include <net/netfilter/nf_conntrack_tuple.h>
28
29LIST_HEAD(nf_conntrack_expect_list);
30EXPORT_SYMBOL_GPL(nf_conntrack_expect_list);
31
32struct kmem_cache *nf_conntrack_expect_cachep __read_mostly;
33static unsigned int nf_conntrack_expect_next_id;
34
35/* nf_conntrack_expect helper functions */
36void nf_ct_unlink_expect(struct nf_conntrack_expect *exp)
37{
38 struct nf_conn_help *master_help = nfct_help(exp->master);
39
40 NF_CT_ASSERT(master_help);
41 NF_CT_ASSERT(!timer_pending(&exp->timeout));
42
43 list_del(&exp->list);
44 NF_CT_STAT_INC(expect_delete);
45 master_help->expecting--;
46 nf_conntrack_expect_put(exp);
47}
48EXPORT_SYMBOL_GPL(nf_ct_unlink_expect);
49
50static void expectation_timed_out(unsigned long ul_expect)
51{
52 struct nf_conntrack_expect *exp = (void *)ul_expect;
53
54 write_lock_bh(&nf_conntrack_lock);
55 nf_ct_unlink_expect(exp);
56 write_unlock_bh(&nf_conntrack_lock);
57 nf_conntrack_expect_put(exp);
58}
59
60struct nf_conntrack_expect *
61__nf_conntrack_expect_find(const struct nf_conntrack_tuple *tuple)
62{
63 struct nf_conntrack_expect *i;
64
65 list_for_each_entry(i, &nf_conntrack_expect_list, list) {
66 if (nf_ct_tuple_mask_cmp(tuple, &i->tuple, &i->mask))
67 return i;
68 }
69 return NULL;
70}
71EXPORT_SYMBOL_GPL(__nf_conntrack_expect_find);
72
73/* Just find a expectation corresponding to a tuple. */
74struct nf_conntrack_expect *
75nf_conntrack_expect_find_get(const struct nf_conntrack_tuple *tuple)
76{
77 struct nf_conntrack_expect *i;
78
79 read_lock_bh(&nf_conntrack_lock);
80 i = __nf_conntrack_expect_find(tuple);
81 if (i)
82 atomic_inc(&i->use);
83 read_unlock_bh(&nf_conntrack_lock);
84
85 return i;
86}
87EXPORT_SYMBOL_GPL(nf_conntrack_expect_find_get);
88
89/* If an expectation for this connection is found, it gets delete from
90 * global list then returned. */
91struct nf_conntrack_expect *
92find_expectation(const struct nf_conntrack_tuple *tuple)
93{
94 struct nf_conntrack_expect *exp;
95
96 exp = __nf_conntrack_expect_find(tuple);
97 if (!exp)
98 return NULL;
99
100 /* If master is not in hash table yet (ie. packet hasn't left
101 this machine yet), how can other end know about expected?
102 Hence these are not the droids you are looking for (if
103 master ct never got confirmed, we'd hold a reference to it
104 and weird things would happen to future packets). */
105 if (!nf_ct_is_confirmed(exp->master))
106 return NULL;
107
108 if (exp->flags & NF_CT_EXPECT_PERMANENT) {
109 atomic_inc(&exp->use);
110 return exp;
111 } else if (del_timer(&exp->timeout)) {
112 nf_ct_unlink_expect(exp);
113 return exp;
114 }
115
116 return NULL;
117}
118
119/* delete all expectations for this conntrack */
120void nf_ct_remove_expectations(struct nf_conn *ct)
121{
122 struct nf_conntrack_expect *i, *tmp;
123 struct nf_conn_help *help = nfct_help(ct);
124
125 /* Optimization: most connection never expect any others. */
126 if (!help || help->expecting == 0)
127 return;
128
129 list_for_each_entry_safe(i, tmp, &nf_conntrack_expect_list, list) {
130 if (i->master == ct && del_timer(&i->timeout)) {
131 nf_ct_unlink_expect(i);
132 nf_conntrack_expect_put(i);
133 }
134 }
135}
136EXPORT_SYMBOL_GPL(nf_ct_remove_expectations);
137
138/* Would two expected things clash? */
139static inline int expect_clash(const struct nf_conntrack_expect *a,
140 const struct nf_conntrack_expect *b)
141{
142 /* Part covered by intersection of masks must be unequal,
143 otherwise they clash */
144 struct nf_conntrack_tuple intersect_mask;
145 int count;
146
147 intersect_mask.src.l3num = a->mask.src.l3num & b->mask.src.l3num;
148 intersect_mask.src.u.all = a->mask.src.u.all & b->mask.src.u.all;
149 intersect_mask.dst.u.all = a->mask.dst.u.all & b->mask.dst.u.all;
150 intersect_mask.dst.protonum = a->mask.dst.protonum
151 & b->mask.dst.protonum;
152
153 for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
154 intersect_mask.src.u3.all[count] =
155 a->mask.src.u3.all[count] & b->mask.src.u3.all[count];
156 }
157
158 for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
159 intersect_mask.dst.u3.all[count] =
160 a->mask.dst.u3.all[count] & b->mask.dst.u3.all[count];
161 }
162
163 return nf_ct_tuple_mask_cmp(&a->tuple, &b->tuple, &intersect_mask);
164}
165
166static inline int expect_matches(const struct nf_conntrack_expect *a,
167 const struct nf_conntrack_expect *b)
168{
169 return a->master == b->master
170 && nf_ct_tuple_equal(&a->tuple, &b->tuple)
171 && nf_ct_tuple_equal(&a->mask, &b->mask);
172}
173
174/* Generally a bad idea to call this: could have matched already. */
175void nf_conntrack_unexpect_related(struct nf_conntrack_expect *exp)
176{
177 struct nf_conntrack_expect *i;
178
179 write_lock_bh(&nf_conntrack_lock);
180 /* choose the the oldest expectation to evict */
181 list_for_each_entry_reverse(i, &nf_conntrack_expect_list, list) {
182 if (expect_matches(i, exp) && del_timer(&i->timeout)) {
183 nf_ct_unlink_expect(i);
184 write_unlock_bh(&nf_conntrack_lock);
185 nf_conntrack_expect_put(i);
186 return;
187 }
188 }
189 write_unlock_bh(&nf_conntrack_lock);
190}
191EXPORT_SYMBOL_GPL(nf_conntrack_unexpect_related);
192
193/* We don't increase the master conntrack refcount for non-fulfilled
194 * conntracks. During the conntrack destruction, the expectations are
195 * always killed before the conntrack itself */
196struct nf_conntrack_expect *nf_conntrack_expect_alloc(struct nf_conn *me)
197{
198 struct nf_conntrack_expect *new;
199
200 new = kmem_cache_alloc(nf_conntrack_expect_cachep, GFP_ATOMIC);
201 if (!new)
202 return NULL;
203
204 new->master = me;
205 atomic_set(&new->use, 1);
206 return new;
207}
208EXPORT_SYMBOL_GPL(nf_conntrack_expect_alloc);
209
210void nf_conntrack_expect_init(struct nf_conntrack_expect *exp, int family,
211 union nf_conntrack_address *saddr,
212 union nf_conntrack_address *daddr,
213 u_int8_t proto, __be16 *src, __be16 *dst)
214{
215 int len;
216
217 if (family == AF_INET)
218 len = 4;
219 else
220 len = 16;
221
222 exp->flags = 0;
223 exp->expectfn = NULL;
224 exp->helper = NULL;
225 exp->tuple.src.l3num = family;
226 exp->tuple.dst.protonum = proto;
227 exp->mask.src.l3num = 0xFFFF;
228 exp->mask.dst.protonum = 0xFF;
229
230 if (saddr) {
231 memcpy(&exp->tuple.src.u3, saddr, len);
232 if (sizeof(exp->tuple.src.u3) > len)
233 /* address needs to be cleared for nf_ct_tuple_equal */
234 memset((void *)&exp->tuple.src.u3 + len, 0x00,
235 sizeof(exp->tuple.src.u3) - len);
236 memset(&exp->mask.src.u3, 0xFF, len);
237 if (sizeof(exp->mask.src.u3) > len)
238 memset((void *)&exp->mask.src.u3 + len, 0x00,
239 sizeof(exp->mask.src.u3) - len);
240 } else {
241 memset(&exp->tuple.src.u3, 0x00, sizeof(exp->tuple.src.u3));
242 memset(&exp->mask.src.u3, 0x00, sizeof(exp->mask.src.u3));
243 }
244
245 if (daddr) {
246 memcpy(&exp->tuple.dst.u3, daddr, len);
247 if (sizeof(exp->tuple.dst.u3) > len)
248 /* address needs to be cleared for nf_ct_tuple_equal */
249 memset((void *)&exp->tuple.dst.u3 + len, 0x00,
250 sizeof(exp->tuple.dst.u3) - len);
251 memset(&exp->mask.dst.u3, 0xFF, len);
252 if (sizeof(exp->mask.dst.u3) > len)
253 memset((void *)&exp->mask.dst.u3 + len, 0x00,
254 sizeof(exp->mask.dst.u3) - len);
255 } else {
256 memset(&exp->tuple.dst.u3, 0x00, sizeof(exp->tuple.dst.u3));
257 memset(&exp->mask.dst.u3, 0x00, sizeof(exp->mask.dst.u3));
258 }
259
260 if (src) {
261 exp->tuple.src.u.all = (__force u16)*src;
262 exp->mask.src.u.all = 0xFFFF;
263 } else {
264 exp->tuple.src.u.all = 0;
265 exp->mask.src.u.all = 0;
266 }
267
268 if (dst) {
269 exp->tuple.dst.u.all = (__force u16)*dst;
270 exp->mask.dst.u.all = 0xFFFF;
271 } else {
272 exp->tuple.dst.u.all = 0;
273 exp->mask.dst.u.all = 0;
274 }
275}
276EXPORT_SYMBOL_GPL(nf_conntrack_expect_init);
277
278void nf_conntrack_expect_put(struct nf_conntrack_expect *exp)
279{
280 if (atomic_dec_and_test(&exp->use))
281 kmem_cache_free(nf_conntrack_expect_cachep, exp);
282}
283EXPORT_SYMBOL_GPL(nf_conntrack_expect_put);
284
285static void nf_conntrack_expect_insert(struct nf_conntrack_expect *exp)
286{
287 struct nf_conn_help *master_help = nfct_help(exp->master);
288
289 atomic_inc(&exp->use);
290 master_help->expecting++;
291 list_add(&exp->list, &nf_conntrack_expect_list);
292
293 init_timer(&exp->timeout);
294 exp->timeout.data = (unsigned long)exp;
295 exp->timeout.function = expectation_timed_out;
296 exp->timeout.expires = jiffies + master_help->helper->timeout * HZ;
297 add_timer(&exp->timeout);
298
299 exp->id = ++nf_conntrack_expect_next_id;
300 atomic_inc(&exp->use);
301 NF_CT_STAT_INC(expect_create);
302}
303
304/* Race with expectations being used means we could have none to find; OK. */
305static void evict_oldest_expect(struct nf_conn *master)
306{
307 struct nf_conntrack_expect *i;
308
309 list_for_each_entry_reverse(i, &nf_conntrack_expect_list, list) {
310 if (i->master == master) {
311 if (del_timer(&i->timeout)) {
312 nf_ct_unlink_expect(i);
313 nf_conntrack_expect_put(i);
314 }
315 break;
316 }
317 }
318}
319
320static inline int refresh_timer(struct nf_conntrack_expect *i)
321{
322 struct nf_conn_help *master_help = nfct_help(i->master);
323
324 if (!del_timer(&i->timeout))
325 return 0;
326
327 i->timeout.expires = jiffies + master_help->helper->timeout*HZ;
328 add_timer(&i->timeout);
329 return 1;
330}
331
332int nf_conntrack_expect_related(struct nf_conntrack_expect *expect)
333{
334 struct nf_conntrack_expect *i;
335 struct nf_conn *master = expect->master;
336 struct nf_conn_help *master_help = nfct_help(master);
337 int ret;
338
339 NF_CT_ASSERT(master_help);
340
341 write_lock_bh(&nf_conntrack_lock);
342 list_for_each_entry(i, &nf_conntrack_expect_list, list) {
343 if (expect_matches(i, expect)) {
344 /* Refresh timer: if it's dying, ignore.. */
345 if (refresh_timer(i)) {
346 ret = 0;
347 goto out;
348 }
349 } else if (expect_clash(i, expect)) {
350 ret = -EBUSY;
351 goto out;
352 }
353 }
354 /* Will be over limit? */
355 if (master_help->helper->max_expected &&
356 master_help->expecting >= master_help->helper->max_expected)
357 evict_oldest_expect(master);
358
359 nf_conntrack_expect_insert(expect);
360 nf_conntrack_expect_event(IPEXP_NEW, expect);
361 ret = 0;
362out:
363 write_unlock_bh(&nf_conntrack_lock);
364 return ret;
365}
366EXPORT_SYMBOL_GPL(nf_conntrack_expect_related);
367
368#ifdef CONFIG_PROC_FS
369static void *exp_seq_start(struct seq_file *s, loff_t *pos)
370{
371 struct list_head *e = &nf_conntrack_expect_list;
372 loff_t i;
373
374 /* strange seq_file api calls stop even if we fail,
375 * thus we need to grab lock since stop unlocks */
376 read_lock_bh(&nf_conntrack_lock);
377
378 if (list_empty(e))
379 return NULL;
380
381 for (i = 0; i <= *pos; i++) {
382 e = e->next;
383 if (e == &nf_conntrack_expect_list)
384 return NULL;
385 }
386 return e;
387}
388
389static void *exp_seq_next(struct seq_file *s, void *v, loff_t *pos)
390{
391 struct list_head *e = v;
392
393 ++*pos;
394 e = e->next;
395
396 if (e == &nf_conntrack_expect_list)
397 return NULL;
398
399 return e;
400}
401
402static void exp_seq_stop(struct seq_file *s, void *v)
403{
404 read_unlock_bh(&nf_conntrack_lock);
405}
406
407static int exp_seq_show(struct seq_file *s, void *v)
408{
409 struct nf_conntrack_expect *expect = v;
410
411 if (expect->timeout.function)
412 seq_printf(s, "%ld ", timer_pending(&expect->timeout)
413 ? (long)(expect->timeout.expires - jiffies)/HZ : 0);
414 else
415 seq_printf(s, "- ");
416 seq_printf(s, "l3proto = %u proto=%u ",
417 expect->tuple.src.l3num,
418 expect->tuple.dst.protonum);
419 print_tuple(s, &expect->tuple,
420 __nf_ct_l3proto_find(expect->tuple.src.l3num),
421 __nf_ct_l4proto_find(expect->tuple.src.l3num,
422 expect->tuple.dst.protonum));
423 return seq_putc(s, '\n');
424}
425
426static struct seq_operations exp_seq_ops = {
427 .start = exp_seq_start,
428 .next = exp_seq_next,
429 .stop = exp_seq_stop,
430 .show = exp_seq_show
431};
432
433static int exp_open(struct inode *inode, struct file *file)
434{
435 return seq_open(file, &exp_seq_ops);
436}
437
438struct file_operations exp_file_ops = {
439 .owner = THIS_MODULE,
440 .open = exp_open,
441 .read = seq_read,
442 .llseek = seq_lseek,
443 .release = seq_release
444};
445#endif /* CONFIG_PROC_FS */
diff --git a/net/netfilter/nf_conntrack_ftp.c b/net/netfilter/nf_conntrack_ftp.c
index 0c17a5bd11..92a9471687 100644
--- a/net/netfilter/nf_conntrack_ftp.c
+++ b/net/netfilter/nf_conntrack_ftp.c
@@ -26,12 +26,15 @@
26#include <net/tcp.h> 26#include <net/tcp.h>
27 27
28#include <net/netfilter/nf_conntrack.h> 28#include <net/netfilter/nf_conntrack.h>
29#include <net/netfilter/nf_conntrack_expect.h>
30#include <net/netfilter/nf_conntrack_ecache.h>
29#include <net/netfilter/nf_conntrack_helper.h> 31#include <net/netfilter/nf_conntrack_helper.h>
30#include <linux/netfilter/nf_conntrack_ftp.h> 32#include <linux/netfilter/nf_conntrack_ftp.h>
31 33
32MODULE_LICENSE("GPL"); 34MODULE_LICENSE("GPL");
33MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>"); 35MODULE_AUTHOR("Rusty Russell <rusty@rustcorp.com.au>");
34MODULE_DESCRIPTION("ftp connection tracking helper"); 36MODULE_DESCRIPTION("ftp connection tracking helper");
37MODULE_ALIAS("ip_conntrack_ftp");
35 38
36/* This is slow, but it's simple. --RR */ 39/* This is slow, but it's simple. --RR */
37static char *ftp_buffer; 40static char *ftp_buffer;
@@ -48,7 +51,7 @@ module_param(loose, bool, 0600);
48 51
49unsigned int (*nf_nat_ftp_hook)(struct sk_buff **pskb, 52unsigned int (*nf_nat_ftp_hook)(struct sk_buff **pskb,
50 enum ip_conntrack_info ctinfo, 53 enum ip_conntrack_info ctinfo,
51 enum ip_ct_ftp_type type, 54 enum nf_ct_ftp_type type,
52 unsigned int matchoff, 55 unsigned int matchoff,
53 unsigned int matchlen, 56 unsigned int matchlen,
54 struct nf_conntrack_expect *exp, 57 struct nf_conntrack_expect *exp,
@@ -71,7 +74,7 @@ static struct ftp_search {
71 size_t plen; 74 size_t plen;
72 char skip; 75 char skip;
73 char term; 76 char term;
74 enum ip_ct_ftp_type ftptype; 77 enum nf_ct_ftp_type ftptype;
75 int (*getnum)(const char *, size_t, struct nf_conntrack_man *, char); 78 int (*getnum)(const char *, size_t, struct nf_conntrack_man *, char);
76} search[IP_CT_DIR_MAX][2] = { 79} search[IP_CT_DIR_MAX][2] = {
77 [IP_CT_DIR_ORIGINAL] = { 80 [IP_CT_DIR_ORIGINAL] = {
@@ -80,7 +83,7 @@ static struct ftp_search {
80 .plen = sizeof("PORT") - 1, 83 .plen = sizeof("PORT") - 1,
81 .skip = ' ', 84 .skip = ' ',
82 .term = '\r', 85 .term = '\r',
83 .ftptype = IP_CT_FTP_PORT, 86 .ftptype = NF_CT_FTP_PORT,
84 .getnum = try_rfc959, 87 .getnum = try_rfc959,
85 }, 88 },
86 { 89 {
@@ -88,7 +91,7 @@ static struct ftp_search {
88 .plen = sizeof("EPRT") - 1, 91 .plen = sizeof("EPRT") - 1,
89 .skip = ' ', 92 .skip = ' ',
90 .term = '\r', 93 .term = '\r',
91 .ftptype = IP_CT_FTP_EPRT, 94 .ftptype = NF_CT_FTP_EPRT,
92 .getnum = try_eprt, 95 .getnum = try_eprt,
93 }, 96 },
94 }, 97 },
@@ -98,7 +101,7 @@ static struct ftp_search {
98 .plen = sizeof("227 ") - 1, 101 .plen = sizeof("227 ") - 1,
99 .skip = '(', 102 .skip = '(',
100 .term = ')', 103 .term = ')',
101 .ftptype = IP_CT_FTP_PASV, 104 .ftptype = NF_CT_FTP_PASV,
102 .getnum = try_rfc959, 105 .getnum = try_rfc959,
103 }, 106 },
104 { 107 {
@@ -106,7 +109,7 @@ static struct ftp_search {
106 .plen = sizeof("229 ") - 1, 109 .plen = sizeof("229 ") - 1,
107 .skip = '(', 110 .skip = '(',
108 .term = ')', 111 .term = ')',
109 .ftptype = IP_CT_FTP_EPSV, 112 .ftptype = NF_CT_FTP_EPSV,
110 .getnum = try_epsv_response, 113 .getnum = try_epsv_response,
111 }, 114 },
112 }, 115 },
@@ -171,7 +174,7 @@ static int try_rfc959(const char *data, size_t dlen,
171 174
172/* Grab port: number up to delimiter */ 175/* Grab port: number up to delimiter */
173static int get_port(const char *data, int start, size_t dlen, char delim, 176static int get_port(const char *data, int start, size_t dlen, char delim,
174 u_int16_t *port) 177 __be16 *port)
175{ 178{
176 u_int16_t tmp_port = 0; 179 u_int16_t tmp_port = 0;
177 int i; 180 int i;
@@ -317,7 +320,7 @@ static int find_pattern(const char *data, size_t dlen,
317} 320}
318 321
319/* Look up to see if we're just after a \n. */ 322/* Look up to see if we're just after a \n. */
320static int find_nl_seq(u32 seq, const struct ip_ct_ftp_master *info, int dir) 323static int find_nl_seq(u32 seq, const struct nf_ct_ftp_master *info, int dir)
321{ 324{
322 unsigned int i; 325 unsigned int i;
323 326
@@ -328,7 +331,7 @@ static int find_nl_seq(u32 seq, const struct ip_ct_ftp_master *info, int dir)
328} 331}
329 332
330/* We don't update if it's older than what we have. */ 333/* We don't update if it's older than what we have. */
331static void update_nl_seq(u32 nl_seq, struct ip_ct_ftp_master *info, int dir, 334static void update_nl_seq(u32 nl_seq, struct nf_ct_ftp_master *info, int dir,
332 struct sk_buff *skb) 335 struct sk_buff *skb)
333{ 336{
334 unsigned int i, oldest = NUM_SEQ_TO_REMEMBER; 337 unsigned int i, oldest = NUM_SEQ_TO_REMEMBER;
@@ -364,12 +367,12 @@ static int help(struct sk_buff **pskb,
364 u32 seq; 367 u32 seq;
365 int dir = CTINFO2DIR(ctinfo); 368 int dir = CTINFO2DIR(ctinfo);
366 unsigned int matchlen, matchoff; 369 unsigned int matchlen, matchoff;
367 struct ip_ct_ftp_master *ct_ftp_info = &nfct_help(ct)->help.ct_ftp_info; 370 struct nf_ct_ftp_master *ct_ftp_info = &nfct_help(ct)->help.ct_ftp_info;
368 struct nf_conntrack_expect *exp; 371 struct nf_conntrack_expect *exp;
369 struct nf_conntrack_man cmd = {}; 372 struct nf_conntrack_man cmd = {};
370
371 unsigned int i; 373 unsigned int i;
372 int found = 0, ends_in_nl; 374 int found = 0, ends_in_nl;
375 typeof(nf_nat_ftp_hook) nf_nat_ftp;
373 376
374 /* Until there's been traffic both ways, don't look in packets. */ 377 /* Until there's been traffic both ways, don't look in packets. */
375 if (ctinfo != IP_CT_ESTABLISHED 378 if (ctinfo != IP_CT_ESTABLISHED
@@ -500,12 +503,12 @@ static int help(struct sk_buff **pskb,
500 .u = { .tcp = { 0 }}, 503 .u = { .tcp = { 0 }},
501 }, 504 },
502 .dst = { .protonum = 0xFF, 505 .dst = { .protonum = 0xFF,
503 .u = { .tcp = { 0xFFFF }}, 506 .u = { .tcp = { __constant_htons(0xFFFF) }},
504 }, 507 },
505 }; 508 };
506 if (cmd.l3num == PF_INET) { 509 if (cmd.l3num == PF_INET) {
507 exp->mask.src.u3.ip = 0xFFFFFFFF; 510 exp->mask.src.u3.ip = htonl(0xFFFFFFFF);
508 exp->mask.dst.u3.ip = 0xFFFFFFFF; 511 exp->mask.dst.u3.ip = htonl(0xFFFFFFFF);
509 } else { 512 } else {
510 memset(exp->mask.src.u3.ip6, 0xFF, 513 memset(exp->mask.src.u3.ip6, 0xFF,
511 sizeof(exp->mask.src.u3.ip6)); 514 sizeof(exp->mask.src.u3.ip6));
@@ -514,13 +517,15 @@ static int help(struct sk_buff **pskb,
514 } 517 }
515 518
516 exp->expectfn = NULL; 519 exp->expectfn = NULL;
520 exp->helper = NULL;
517 exp->flags = 0; 521 exp->flags = 0;
518 522
519 /* Now, NAT might want to mangle the packet, and register the 523 /* Now, NAT might want to mangle the packet, and register the
520 * (possibly changed) expectation itself. */ 524 * (possibly changed) expectation itself. */
521 if (nf_nat_ftp_hook) 525 nf_nat_ftp = rcu_dereference(nf_nat_ftp_hook);
522 ret = nf_nat_ftp_hook(pskb, ctinfo, search[dir][i].ftptype, 526 if (nf_nat_ftp && ct->status & IPS_NAT_MASK)
523 matchoff, matchlen, exp, &seq); 527 ret = nf_nat_ftp(pskb, ctinfo, search[dir][i].ftptype,
528 matchoff, matchlen, exp, &seq);
524 else { 529 else {
525 /* Can't expect this? Best to drop packet now. */ 530 /* Can't expect this? Best to drop packet now. */
526 if (nf_conntrack_expect_related(exp) != 0) 531 if (nf_conntrack_expect_related(exp) != 0)
@@ -584,7 +589,8 @@ static int __init nf_conntrack_ftp_init(void)
584 for (j = 0; j < 2; j++) { 589 for (j = 0; j < 2; j++) {
585 ftp[i][j].tuple.src.u.tcp.port = htons(ports[i]); 590 ftp[i][j].tuple.src.u.tcp.port = htons(ports[i]);
586 ftp[i][j].tuple.dst.protonum = IPPROTO_TCP; 591 ftp[i][j].tuple.dst.protonum = IPPROTO_TCP;
587 ftp[i][j].mask.src.u.tcp.port = 0xFFFF; 592 ftp[i][j].mask.src.l3num = 0xFFFF;
593 ftp[i][j].mask.src.u.tcp.port = htons(0xFFFF);
588 ftp[i][j].mask.dst.protonum = 0xFF; 594 ftp[i][j].mask.dst.protonum = 0xFF;
589 ftp[i][j].max_expected = 1; 595 ftp[i][j].max_expected = 1;
590 ftp[i][j].timeout = 5 * 60; /* 5 Minutes */ 596 ftp[i][j].timeout = 5 * 60; /* 5 Minutes */
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c b/net/netfilter/nf_conntrack_h323_asn1.c
index 26dfecadb3..f6fad713d4 100644
--- a/net/ipv4/netfilter/ip_conntrack_helper_h323_asn1.c
+++ b/net/netfilter/nf_conntrack_h323_asn1.c
@@ -15,7 +15,7 @@
15#else 15#else
16#include <stdio.h> 16#include <stdio.h>
17#endif 17#endif
18#include <linux/netfilter_ipv4/ip_conntrack_helper_h323_asn1.h> 18#include <linux/netfilter/nf_conntrack_h323_asn1.h>
19 19
20/* Trace Flag */ 20/* Trace Flag */
21#ifndef H323_TRACE 21#ifndef H323_TRACE
@@ -144,7 +144,7 @@ static decoder_t Decoders[] = {
144/**************************************************************************** 144/****************************************************************************
145 * H.323 Types 145 * H.323 Types
146 ****************************************************************************/ 146 ****************************************************************************/
147#include "ip_conntrack_helper_h323_types.c" 147#include "nf_conntrack_h323_types.c"
148 148
149/**************************************************************************** 149/****************************************************************************
150 * Functions 150 * Functions
diff --git a/net/netfilter/nf_conntrack_h323_main.c b/net/netfilter/nf_conntrack_h323_main.c
new file mode 100644
index 0000000000..6d8568959f
--- /dev/null
+++ b/net/netfilter/nf_conntrack_h323_main.c
@@ -0,0 +1,1856 @@
1/*
2 * H.323 connection tracking helper
3 *
4 * Copyright (c) 2006 Jing Min Zhao <zhaojingmin@users.sourceforge.net>
5 *
6 * This source code is licensed under General Public License version 2.
7 *
8 * Based on the 'brute force' H.323 connection tracking module by
9 * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
10 *
11 * For more information, please see http://nath323.sourceforge.net/
12 */
13
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/ctype.h>
17#include <linux/inet.h>
18#include <linux/in.h>
19#include <linux/ip.h>
20#include <linux/udp.h>
21#include <linux/tcp.h>
22#include <linux/skbuff.h>
23#include <net/route.h>
24#include <net/ip6_route.h>
25
26#include <net/netfilter/nf_conntrack.h>
27#include <net/netfilter/nf_conntrack_core.h>
28#include <net/netfilter/nf_conntrack_tuple.h>
29#include <net/netfilter/nf_conntrack_expect.h>
30#include <net/netfilter/nf_conntrack_ecache.h>
31#include <net/netfilter/nf_conntrack_helper.h>
32#include <linux/netfilter/nf_conntrack_h323.h>
33
34#if 0
35#define DEBUGP printk
36#else
37#define DEBUGP(format, args...)
38#endif
39
40/* Parameters */
41static unsigned int default_rrq_ttl __read_mostly = 300;
42module_param(default_rrq_ttl, uint, 0600);
43MODULE_PARM_DESC(default_rrq_ttl, "use this TTL if it's missing in RRQ");
44
45static int gkrouted_only __read_mostly = 1;
46module_param(gkrouted_only, int, 0600);
47MODULE_PARM_DESC(gkrouted_only, "only accept calls from gatekeeper");
48
49static int callforward_filter __read_mostly = 1;
50module_param(callforward_filter, bool, 0600);
51MODULE_PARM_DESC(callforward_filter, "only create call forwarding expectations "
52 "if both endpoints are on different sides "
53 "(determined by routing information)");
54
55/* Hooks for NAT */
56int (*set_h245_addr_hook) (struct sk_buff **pskb,
57 unsigned char **data, int dataoff,
58 H245_TransportAddress *taddr,
59 union nf_conntrack_address *addr, __be16 port)
60 __read_mostly;
61int (*set_h225_addr_hook) (struct sk_buff **pskb,
62 unsigned char **data, int dataoff,
63 TransportAddress *taddr,
64 union nf_conntrack_address *addr, __be16 port)
65 __read_mostly;
66int (*set_sig_addr_hook) (struct sk_buff **pskb,
67 struct nf_conn *ct,
68 enum ip_conntrack_info ctinfo,
69 unsigned char **data,
70 TransportAddress *taddr, int count) __read_mostly;
71int (*set_ras_addr_hook) (struct sk_buff **pskb,
72 struct nf_conn *ct,
73 enum ip_conntrack_info ctinfo,
74 unsigned char **data,
75 TransportAddress *taddr, int count) __read_mostly;
76int (*nat_rtp_rtcp_hook) (struct sk_buff **pskb,
77 struct nf_conn *ct,
78 enum ip_conntrack_info ctinfo,
79 unsigned char **data, int dataoff,
80 H245_TransportAddress *taddr,
81 __be16 port, __be16 rtp_port,
82 struct nf_conntrack_expect *rtp_exp,
83 struct nf_conntrack_expect *rtcp_exp) __read_mostly;
84int (*nat_t120_hook) (struct sk_buff **pskb,
85 struct nf_conn *ct,
86 enum ip_conntrack_info ctinfo,
87 unsigned char **data, int dataoff,
88 H245_TransportAddress *taddr, __be16 port,
89 struct nf_conntrack_expect *exp) __read_mostly;
90int (*nat_h245_hook) (struct sk_buff **pskb,
91 struct nf_conn *ct,
92 enum ip_conntrack_info ctinfo,
93 unsigned char **data, int dataoff,
94 TransportAddress *taddr, __be16 port,
95 struct nf_conntrack_expect *exp) __read_mostly;
96int (*nat_callforwarding_hook) (struct sk_buff **pskb,
97 struct nf_conn *ct,
98 enum ip_conntrack_info ctinfo,
99 unsigned char **data, int dataoff,
100 TransportAddress *taddr, __be16 port,
101 struct nf_conntrack_expect *exp) __read_mostly;
102int (*nat_q931_hook) (struct sk_buff **pskb,
103 struct nf_conn *ct,
104 enum ip_conntrack_info ctinfo,
105 unsigned char **data, TransportAddress *taddr, int idx,
106 __be16 port, struct nf_conntrack_expect *exp)
107 __read_mostly;
108
109static DEFINE_SPINLOCK(nf_h323_lock);
110static char *h323_buffer;
111
112static struct nf_conntrack_helper nf_conntrack_helper_h245;
113static struct nf_conntrack_helper nf_conntrack_helper_q931[];
114static struct nf_conntrack_helper nf_conntrack_helper_ras[];
115
116/****************************************************************************/
117static int get_tpkt_data(struct sk_buff **pskb, unsigned int protoff,
118 struct nf_conn *ct, enum ip_conntrack_info ctinfo,
119 unsigned char **data, int *datalen, int *dataoff)
120{
121 struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;
122 int dir = CTINFO2DIR(ctinfo);
123 struct tcphdr _tcph, *th;
124 int tcpdatalen;
125 int tcpdataoff;
126 unsigned char *tpkt;
127 int tpktlen;
128 int tpktoff;
129
130 /* Get TCP header */
131 th = skb_header_pointer(*pskb, protoff, sizeof(_tcph), &_tcph);
132 if (th == NULL)
133 return 0;
134
135 /* Get TCP data offset */
136 tcpdataoff = protoff + th->doff * 4;
137
138 /* Get TCP data length */
139 tcpdatalen = (*pskb)->len - tcpdataoff;
140 if (tcpdatalen <= 0) /* No TCP data */
141 goto clear_out;
142
143 if (*data == NULL) { /* first TPKT */
144 /* Get first TPKT pointer */
145 tpkt = skb_header_pointer(*pskb, tcpdataoff, tcpdatalen,
146 h323_buffer);
147 BUG_ON(tpkt == NULL);
148
149 /* Validate TPKT identifier */
150 if (tcpdatalen < 4 || tpkt[0] != 0x03 || tpkt[1] != 0) {
151 /* Netmeeting sends TPKT header and data separately */
152 if (info->tpkt_len[dir] > 0) {
153 DEBUGP("nf_ct_h323: previous packet "
154 "indicated separate TPKT data of %hu "
155 "bytes\n", info->tpkt_len[dir]);
156 if (info->tpkt_len[dir] <= tcpdatalen) {
157 /* Yes, there was a TPKT header
158 * received */
159 *data = tpkt;
160 *datalen = info->tpkt_len[dir];
161 *dataoff = 0;
162 goto out;
163 }
164
165 /* Fragmented TPKT */
166 if (net_ratelimit())
167 printk("nf_ct_h323: "
168 "fragmented TPKT\n");
169 goto clear_out;
170 }
171
172 /* It is not even a TPKT */
173 return 0;
174 }
175 tpktoff = 0;
176 } else { /* Next TPKT */
177 tpktoff = *dataoff + *datalen;
178 tcpdatalen -= tpktoff;
179 if (tcpdatalen <= 4) /* No more TPKT */
180 goto clear_out;
181 tpkt = *data + *datalen;
182
183 /* Validate TPKT identifier */
184 if (tpkt[0] != 0x03 || tpkt[1] != 0)
185 goto clear_out;
186 }
187
188 /* Validate TPKT length */
189 tpktlen = tpkt[2] * 256 + tpkt[3];
190 if (tpktlen < 4)
191 goto clear_out;
192 if (tpktlen > tcpdatalen) {
193 if (tcpdatalen == 4) { /* Separate TPKT header */
194 /* Netmeeting sends TPKT header and data separately */
195 DEBUGP("nf_ct_h323: separate TPKT header indicates "
196 "there will be TPKT data of %hu bytes\n",
197 tpktlen - 4);
198 info->tpkt_len[dir] = tpktlen - 4;
199 return 0;
200 }
201
202 if (net_ratelimit())
203 printk("nf_ct_h323: incomplete TPKT (fragmented?)\n");
204 goto clear_out;
205 }
206
207 /* This is the encapsulated data */
208 *data = tpkt + 4;
209 *datalen = tpktlen - 4;
210 *dataoff = tpktoff + 4;
211
212 out:
213 /* Clear TPKT length */
214 info->tpkt_len[dir] = 0;
215 return 1;
216
217 clear_out:
218 info->tpkt_len[dir] = 0;
219 return 0;
220}
221
222/****************************************************************************/
223static int get_h245_addr(struct nf_conn *ct, unsigned char *data,
224 H245_TransportAddress *taddr,
225 union nf_conntrack_address *addr, __be16 *port)
226{
227 unsigned char *p;
228 int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
229 int len;
230
231 if (taddr->choice != eH245_TransportAddress_unicastAddress)
232 return 0;
233
234 switch (taddr->unicastAddress.choice) {
235 case eUnicastAddress_iPAddress:
236 if (family != AF_INET)
237 return 0;
238 p = data + taddr->unicastAddress.iPAddress.network;
239 len = 4;
240 break;
241 case eUnicastAddress_iP6Address:
242 if (family != AF_INET6)
243 return 0;
244 p = data + taddr->unicastAddress.iP6Address.network;
245 len = 16;
246 break;
247 default:
248 return 0;
249 }
250
251 memcpy(addr, p, len);
252 memset((void *)addr + len, 0, sizeof(*addr) - len);
253 memcpy(port, p + len, sizeof(__be16));
254
255 return 1;
256}
257
258/****************************************************************************/
259static int expect_rtp_rtcp(struct sk_buff **pskb, struct nf_conn *ct,
260 enum ip_conntrack_info ctinfo,
261 unsigned char **data, int dataoff,
262 H245_TransportAddress *taddr)
263{
264 int dir = CTINFO2DIR(ctinfo);
265 int ret = 0;
266 __be16 port;
267 __be16 rtp_port, rtcp_port;
268 union nf_conntrack_address addr;
269 struct nf_conntrack_expect *rtp_exp;
270 struct nf_conntrack_expect *rtcp_exp;
271 typeof(nat_rtp_rtcp_hook) nat_rtp_rtcp;
272
273 /* Read RTP or RTCP address */
274 if (!get_h245_addr(ct, *data, taddr, &addr, &port) ||
275 memcmp(&addr, &ct->tuplehash[dir].tuple.src.u3, sizeof(addr)) ||
276 port == 0)
277 return 0;
278
279 /* RTP port is even */
280 port &= htons(~1);
281 rtp_port = port;
282 rtcp_port = htons(ntohs(port) + 1);
283
284 /* Create expect for RTP */
285 if ((rtp_exp = nf_conntrack_expect_alloc(ct)) == NULL)
286 return -1;
287 nf_conntrack_expect_init(rtp_exp, ct->tuplehash[!dir].tuple.src.l3num,
288 &ct->tuplehash[!dir].tuple.src.u3,
289 &ct->tuplehash[!dir].tuple.dst.u3,
290 IPPROTO_UDP, NULL, &rtp_port);
291
292 /* Create expect for RTCP */
293 if ((rtcp_exp = nf_conntrack_expect_alloc(ct)) == NULL) {
294 nf_conntrack_expect_put(rtp_exp);
295 return -1;
296 }
297 nf_conntrack_expect_init(rtcp_exp, ct->tuplehash[!dir].tuple.src.l3num,
298 &ct->tuplehash[!dir].tuple.src.u3,
299 &ct->tuplehash[!dir].tuple.dst.u3,
300 IPPROTO_UDP, NULL, &rtcp_port);
301
302 if (memcmp(&ct->tuplehash[dir].tuple.src.u3,
303 &ct->tuplehash[!dir].tuple.dst.u3,
304 sizeof(ct->tuplehash[dir].tuple.src.u3)) &&
305 (nat_rtp_rtcp = rcu_dereference(nat_rtp_rtcp_hook)) &&
306 ct->status & IPS_NAT_MASK) {
307 /* NAT needed */
308 ret = nat_rtp_rtcp(pskb, ct, ctinfo, data, dataoff,
309 taddr, port, rtp_port, rtp_exp, rtcp_exp);
310 } else { /* Conntrack only */
311 if (nf_conntrack_expect_related(rtp_exp) == 0) {
312 if (nf_conntrack_expect_related(rtcp_exp) == 0) {
313 DEBUGP("nf_ct_h323: expect RTP ");
314 NF_CT_DUMP_TUPLE(&rtp_exp->tuple);
315 DEBUGP("nf_ct_h323: expect RTCP ");
316 NF_CT_DUMP_TUPLE(&rtcp_exp->tuple);
317 } else {
318 nf_conntrack_unexpect_related(rtp_exp);
319 ret = -1;
320 }
321 } else
322 ret = -1;
323 }
324
325 nf_conntrack_expect_put(rtp_exp);
326 nf_conntrack_expect_put(rtcp_exp);
327
328 return ret;
329}
330
331/****************************************************************************/
332static int expect_t120(struct sk_buff **pskb,
333 struct nf_conn *ct,
334 enum ip_conntrack_info ctinfo,
335 unsigned char **data, int dataoff,
336 H245_TransportAddress *taddr)
337{
338 int dir = CTINFO2DIR(ctinfo);
339 int ret = 0;
340 __be16 port;
341 union nf_conntrack_address addr;
342 struct nf_conntrack_expect *exp;
343 typeof(nat_t120_hook) nat_t120;
344
345 /* Read T.120 address */
346 if (!get_h245_addr(ct, *data, taddr, &addr, &port) ||
347 memcmp(&addr, &ct->tuplehash[dir].tuple.src.u3, sizeof(addr)) ||
348 port == 0)
349 return 0;
350
351 /* Create expect for T.120 connections */
352 if ((exp = nf_conntrack_expect_alloc(ct)) == NULL)
353 return -1;
354 nf_conntrack_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
355 &ct->tuplehash[!dir].tuple.src.u3,
356 &ct->tuplehash[!dir].tuple.dst.u3,
357 IPPROTO_TCP, NULL, &port);
358 exp->flags = NF_CT_EXPECT_PERMANENT; /* Accept multiple channels */
359
360 if (memcmp(&ct->tuplehash[dir].tuple.src.u3,
361 &ct->tuplehash[!dir].tuple.dst.u3,
362 sizeof(ct->tuplehash[dir].tuple.src.u3)) &&
363 (nat_t120 = rcu_dereference(nat_t120_hook)) &&
364 ct->status & IPS_NAT_MASK) {
365 /* NAT needed */
366 ret = nat_t120(pskb, ct, ctinfo, data, dataoff, taddr,
367 port, exp);
368 } else { /* Conntrack only */
369 if (nf_conntrack_expect_related(exp) == 0) {
370 DEBUGP("nf_ct_h323: expect T.120 ");
371 NF_CT_DUMP_TUPLE(&exp->tuple);
372 } else
373 ret = -1;
374 }
375
376 nf_conntrack_expect_put(exp);
377
378 return ret;
379}
380
381/****************************************************************************/
382static int process_h245_channel(struct sk_buff **pskb,
383 struct nf_conn *ct,
384 enum ip_conntrack_info ctinfo,
385 unsigned char **data, int dataoff,
386 H2250LogicalChannelParameters *channel)
387{
388 int ret;
389
390 if (channel->options & eH2250LogicalChannelParameters_mediaChannel) {
391 /* RTP */
392 ret = expect_rtp_rtcp(pskb, ct, ctinfo, data, dataoff,
393 &channel->mediaChannel);
394 if (ret < 0)
395 return -1;
396 }
397
398 if (channel->
399 options & eH2250LogicalChannelParameters_mediaControlChannel) {
400 /* RTCP */
401 ret = expect_rtp_rtcp(pskb, ct, ctinfo, data, dataoff,
402 &channel->mediaControlChannel);
403 if (ret < 0)
404 return -1;
405 }
406
407 return 0;
408}
409
410/****************************************************************************/
411static int process_olc(struct sk_buff **pskb, struct nf_conn *ct,
412 enum ip_conntrack_info ctinfo,
413 unsigned char **data, int dataoff,
414 OpenLogicalChannel *olc)
415{
416 int ret;
417
418 DEBUGP("nf_ct_h323: OpenLogicalChannel\n");
419
420 if (olc->forwardLogicalChannelParameters.multiplexParameters.choice ==
421 eOpenLogicalChannel_forwardLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters)
422 {
423 ret = process_h245_channel(pskb, ct, ctinfo, data, dataoff,
424 &olc->
425 forwardLogicalChannelParameters.
426 multiplexParameters.
427 h2250LogicalChannelParameters);
428 if (ret < 0)
429 return -1;
430 }
431
432 if ((olc->options &
433 eOpenLogicalChannel_reverseLogicalChannelParameters) &&
434 (olc->reverseLogicalChannelParameters.options &
435 eOpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters)
436 && (olc->reverseLogicalChannelParameters.multiplexParameters.
437 choice ==
438 eOpenLogicalChannel_reverseLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters))
439 {
440 ret =
441 process_h245_channel(pskb, ct, ctinfo, data, dataoff,
442 &olc->
443 reverseLogicalChannelParameters.
444 multiplexParameters.
445 h2250LogicalChannelParameters);
446 if (ret < 0)
447 return -1;
448 }
449
450 if ((olc->options & eOpenLogicalChannel_separateStack) &&
451 olc->forwardLogicalChannelParameters.dataType.choice ==
452 eDataType_data &&
453 olc->forwardLogicalChannelParameters.dataType.data.application.
454 choice == eDataApplicationCapability_application_t120 &&
455 olc->forwardLogicalChannelParameters.dataType.data.application.
456 t120.choice == eDataProtocolCapability_separateLANStack &&
457 olc->separateStack.networkAddress.choice ==
458 eNetworkAccessParameters_networkAddress_localAreaAddress) {
459 ret = expect_t120(pskb, ct, ctinfo, data, dataoff,
460 &olc->separateStack.networkAddress.
461 localAreaAddress);
462 if (ret < 0)
463 return -1;
464 }
465
466 return 0;
467}
468
469/****************************************************************************/
470static int process_olca(struct sk_buff **pskb, struct nf_conn *ct,
471 enum ip_conntrack_info ctinfo,
472 unsigned char **data, int dataoff,
473 OpenLogicalChannelAck *olca)
474{
475 H2250LogicalChannelAckParameters *ack;
476 int ret;
477
478 DEBUGP("nf_ct_h323: OpenLogicalChannelAck\n");
479
480 if ((olca->options &
481 eOpenLogicalChannelAck_reverseLogicalChannelParameters) &&
482 (olca->reverseLogicalChannelParameters.options &
483 eOpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters)
484 && (olca->reverseLogicalChannelParameters.multiplexParameters.
485 choice ==
486 eOpenLogicalChannelAck_reverseLogicalChannelParameters_multiplexParameters_h2250LogicalChannelParameters))
487 {
488 ret = process_h245_channel(pskb, ct, ctinfo, data, dataoff,
489 &olca->
490 reverseLogicalChannelParameters.
491 multiplexParameters.
492 h2250LogicalChannelParameters);
493 if (ret < 0)
494 return -1;
495 }
496
497 if ((olca->options &
498 eOpenLogicalChannelAck_forwardMultiplexAckParameters) &&
499 (olca->forwardMultiplexAckParameters.choice ==
500 eOpenLogicalChannelAck_forwardMultiplexAckParameters_h2250LogicalChannelAckParameters))
501 {
502 ack = &olca->forwardMultiplexAckParameters.
503 h2250LogicalChannelAckParameters;
504 if (ack->options &
505 eH2250LogicalChannelAckParameters_mediaChannel) {
506 /* RTP */
507 ret = expect_rtp_rtcp(pskb, ct, ctinfo, data, dataoff,
508 &ack->mediaChannel);
509 if (ret < 0)
510 return -1;
511 }
512
513 if (ack->options &
514 eH2250LogicalChannelAckParameters_mediaControlChannel) {
515 /* RTCP */
516 ret = expect_rtp_rtcp(pskb, ct, ctinfo, data, dataoff,
517 &ack->mediaControlChannel);
518 if (ret < 0)
519 return -1;
520 }
521 }
522
523 return 0;
524}
525
526/****************************************************************************/
527static int process_h245(struct sk_buff **pskb, struct nf_conn *ct,
528 enum ip_conntrack_info ctinfo,
529 unsigned char **data, int dataoff,
530 MultimediaSystemControlMessage *mscm)
531{
532 switch (mscm->choice) {
533 case eMultimediaSystemControlMessage_request:
534 if (mscm->request.choice ==
535 eRequestMessage_openLogicalChannel) {
536 return process_olc(pskb, ct, ctinfo, data, dataoff,
537 &mscm->request.openLogicalChannel);
538 }
539 DEBUGP("nf_ct_h323: H.245 Request %d\n",
540 mscm->request.choice);
541 break;
542 case eMultimediaSystemControlMessage_response:
543 if (mscm->response.choice ==
544 eResponseMessage_openLogicalChannelAck) {
545 return process_olca(pskb, ct, ctinfo, data, dataoff,
546 &mscm->response.
547 openLogicalChannelAck);
548 }
549 DEBUGP("nf_ct_h323: H.245 Response %d\n",
550 mscm->response.choice);
551 break;
552 default:
553 DEBUGP("nf_ct_h323: H.245 signal %d\n", mscm->choice);
554 break;
555 }
556
557 return 0;
558}
559
560/****************************************************************************/
561static int h245_help(struct sk_buff **pskb, unsigned int protoff,
562 struct nf_conn *ct, enum ip_conntrack_info ctinfo)
563{
564 static MultimediaSystemControlMessage mscm;
565 unsigned char *data = NULL;
566 int datalen;
567 int dataoff;
568 int ret;
569
570 /* Until there's been traffic both ways, don't look in packets. */
571 if (ctinfo != IP_CT_ESTABLISHED &&
572 ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
573 return NF_ACCEPT;
574 }
575 DEBUGP("nf_ct_h245: skblen = %u\n", (*pskb)->len);
576
577 spin_lock_bh(&nf_h323_lock);
578
579 /* Process each TPKT */
580 while (get_tpkt_data(pskb, protoff, ct, ctinfo,
581 &data, &datalen, &dataoff)) {
582 DEBUGP("nf_ct_h245: TPKT len=%d ", datalen);
583 NF_CT_DUMP_TUPLE(&ct->tuplehash[CTINFO2DIR(ctinfo)].tuple);
584
585 /* Decode H.245 signal */
586 ret = DecodeMultimediaSystemControlMessage(data, datalen,
587 &mscm);
588 if (ret < 0) {
589 if (net_ratelimit())
590 printk("nf_ct_h245: decoding error: %s\n",
591 ret == H323_ERROR_BOUND ?
592 "out of bound" : "out of range");
593 /* We don't drop when decoding error */
594 break;
595 }
596
597 /* Process H.245 signal */
598 if (process_h245(pskb, ct, ctinfo, &data, dataoff, &mscm) < 0)
599 goto drop;
600 }
601
602 spin_unlock_bh(&nf_h323_lock);
603 return NF_ACCEPT;
604
605 drop:
606 spin_unlock_bh(&nf_h323_lock);
607 if (net_ratelimit())
608 printk("nf_ct_h245: packet dropped\n");
609 return NF_DROP;
610}
611
612/****************************************************************************/
613static struct nf_conntrack_helper nf_conntrack_helper_h245 __read_mostly = {
614 .name = "H.245",
615 .me = THIS_MODULE,
616 .max_expected = H323_RTP_CHANNEL_MAX * 4 + 2 /* T.120 */,
617 .timeout = 240,
618 .tuple.dst.protonum = IPPROTO_UDP,
619 .mask.src.u.udp.port = __constant_htons(0xFFFF),
620 .mask.dst.protonum = 0xFF,
621 .help = h245_help
622};
623
624/****************************************************************************/
625int get_h225_addr(struct nf_conn *ct, unsigned char *data,
626 TransportAddress *taddr,
627 union nf_conntrack_address *addr, __be16 *port)
628{
629 unsigned char *p;
630 int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
631 int len;
632
633 switch (taddr->choice) {
634 case eTransportAddress_ipAddress:
635 if (family != AF_INET)
636 return 0;
637 p = data + taddr->ipAddress.ip;
638 len = 4;
639 break;
640 case eTransportAddress_ip6Address:
641 if (family != AF_INET6)
642 return 0;
643 p = data + taddr->ip6Address.ip6;
644 len = 16;
645 break;
646 default:
647 return 0;
648 }
649
650 memcpy(addr, p, len);
651 memset((void *)addr + len, 0, sizeof(*addr) - len);
652 memcpy(port, p + len, sizeof(__be16));
653
654 return 1;
655}
656
657/****************************************************************************/
658static int expect_h245(struct sk_buff **pskb, struct nf_conn *ct,
659 enum ip_conntrack_info ctinfo,
660 unsigned char **data, int dataoff,
661 TransportAddress *taddr)
662{
663 int dir = CTINFO2DIR(ctinfo);
664 int ret = 0;
665 __be16 port;
666 union nf_conntrack_address addr;
667 struct nf_conntrack_expect *exp;
668 typeof(nat_h245_hook) nat_h245;
669
670 /* Read h245Address */
671 if (!get_h225_addr(ct, *data, taddr, &addr, &port) ||
672 memcmp(&addr, &ct->tuplehash[dir].tuple.src.u3, sizeof(addr)) ||
673 port == 0)
674 return 0;
675
676 /* Create expect for h245 connection */
677 if ((exp = nf_conntrack_expect_alloc(ct)) == NULL)
678 return -1;
679 nf_conntrack_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
680 &ct->tuplehash[!dir].tuple.src.u3,
681 &ct->tuplehash[!dir].tuple.dst.u3,
682 IPPROTO_TCP, NULL, &port);
683 exp->helper = &nf_conntrack_helper_h245;
684
685 if (memcmp(&ct->tuplehash[dir].tuple.src.u3,
686 &ct->tuplehash[!dir].tuple.dst.u3,
687 sizeof(ct->tuplehash[dir].tuple.src.u3)) &&
688 (nat_h245 = rcu_dereference(nat_h245_hook)) &&
689 ct->status & IPS_NAT_MASK) {
690 /* NAT needed */
691 ret = nat_h245(pskb, ct, ctinfo, data, dataoff, taddr,
692 port, exp);
693 } else { /* Conntrack only */
694 if (nf_conntrack_expect_related(exp) == 0) {
695 DEBUGP("nf_ct_q931: expect H.245 ");
696 NF_CT_DUMP_TUPLE(&exp->tuple);
697 } else
698 ret = -1;
699 }
700
701 nf_conntrack_expect_put(exp);
702
703 return ret;
704}
705
706/* If the calling party is on the same side of the forward-to party,
707 * we don't need to track the second call */
708static int callforward_do_filter(union nf_conntrack_address *src,
709 union nf_conntrack_address *dst,
710 int family)
711{
712 struct flowi fl1, fl2;
713 int ret = 0;
714
715 memset(&fl1, 0, sizeof(fl1));
716 memset(&fl2, 0, sizeof(fl2));
717
718 switch (family) {
719 case AF_INET: {
720 struct rtable *rt1, *rt2;
721
722 fl1.fl4_dst = src->ip;
723 fl2.fl4_dst = dst->ip;
724 if (ip_route_output_key(&rt1, &fl1) == 0) {
725 if (ip_route_output_key(&rt2, &fl2) == 0) {
726 if (rt1->rt_gateway == rt2->rt_gateway &&
727 rt1->u.dst.dev == rt2->u.dst.dev)
728 ret = 1;
729 dst_release(&rt2->u.dst);
730 }
731 dst_release(&rt1->u.dst);
732 }
733 break;
734 }
735#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
736 case AF_INET6: {
737 struct rt6_info *rt1, *rt2;
738
739 memcpy(&fl1.fl6_dst, src, sizeof(fl1.fl6_dst));
740 memcpy(&fl2.fl6_dst, dst, sizeof(fl2.fl6_dst));
741 rt1 = (struct rt6_info *)ip6_route_output(NULL, &fl1);
742 if (rt1) {
743 rt2 = (struct rt6_info *)ip6_route_output(NULL, &fl2);
744 if (rt2) {
745 if (!memcmp(&rt1->rt6i_gateway, &rt2->rt6i_gateway,
746 sizeof(rt1->rt6i_gateway)) &&
747 rt1->u.dst.dev == rt2->u.dst.dev)
748 ret = 1;
749 dst_release(&rt2->u.dst);
750 }
751 dst_release(&rt1->u.dst);
752 }
753 break;
754 }
755#endif
756 }
757 return ret;
758
759}
760
761/****************************************************************************/
762static int expect_callforwarding(struct sk_buff **pskb,
763 struct nf_conn *ct,
764 enum ip_conntrack_info ctinfo,
765 unsigned char **data, int dataoff,
766 TransportAddress *taddr)
767{
768 int dir = CTINFO2DIR(ctinfo);
769 int ret = 0;
770 __be16 port;
771 union nf_conntrack_address addr;
772 struct nf_conntrack_expect *exp;
773 typeof(nat_callforwarding_hook) nat_callforwarding;
774
775 /* Read alternativeAddress */
776 if (!get_h225_addr(ct, *data, taddr, &addr, &port) || port == 0)
777 return 0;
778
779 /* If the calling party is on the same side of the forward-to party,
780 * we don't need to track the second call */
781 if (callforward_filter &&
782 callforward_do_filter(&addr, &ct->tuplehash[!dir].tuple.src.u3,
783 ct->tuplehash[!dir].tuple.src.l3num)) {
784 DEBUGP("nf_ct_q931: Call Forwarding not tracked\n");
785 return 0;
786 }
787
788 /* Create expect for the second call leg */
789 if ((exp = nf_conntrack_expect_alloc(ct)) == NULL)
790 return -1;
791 nf_conntrack_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
792 &ct->tuplehash[!dir].tuple.src.u3, &addr,
793 IPPROTO_TCP, NULL, &port);
794 exp->helper = nf_conntrack_helper_q931;
795
796 if (memcmp(&ct->tuplehash[dir].tuple.src.u3,
797 &ct->tuplehash[!dir].tuple.dst.u3,
798 sizeof(ct->tuplehash[dir].tuple.src.u3)) &&
799 (nat_callforwarding = rcu_dereference(nat_callforwarding_hook)) &&
800 ct->status & IPS_NAT_MASK) {
801 /* Need NAT */
802 ret = nat_callforwarding(pskb, ct, ctinfo, data, dataoff,
803 taddr, port, exp);
804 } else { /* Conntrack only */
805 if (nf_conntrack_expect_related(exp) == 0) {
806 DEBUGP("nf_ct_q931: expect Call Forwarding ");
807 NF_CT_DUMP_TUPLE(&exp->tuple);
808 } else
809 ret = -1;
810 }
811
812 nf_conntrack_expect_put(exp);
813
814 return ret;
815}
816
817/****************************************************************************/
818static int process_setup(struct sk_buff **pskb, struct nf_conn *ct,
819 enum ip_conntrack_info ctinfo,
820 unsigned char **data, int dataoff,
821 Setup_UUIE *setup)
822{
823 int dir = CTINFO2DIR(ctinfo);
824 int ret;
825 int i;
826 __be16 port;
827 union nf_conntrack_address addr;
828 typeof(set_h225_addr_hook) set_h225_addr;
829
830 DEBUGP("nf_ct_q931: Setup\n");
831
832 if (setup->options & eSetup_UUIE_h245Address) {
833 ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
834 &setup->h245Address);
835 if (ret < 0)
836 return -1;
837 }
838
839 set_h225_addr = rcu_dereference(set_h225_addr_hook);
840 if ((setup->options & eSetup_UUIE_destCallSignalAddress) &&
841 (set_h225_addr) && ct->status && IPS_NAT_MASK &&
842 get_h225_addr(ct, *data, &setup->destCallSignalAddress,
843 &addr, &port) &&
844 memcmp(&addr, &ct->tuplehash[!dir].tuple.src.u3, sizeof(addr))) {
845 DEBUGP("nf_ct_q931: set destCallSignalAddress "
846 NIP6_FMT ":%hu->" NIP6_FMT ":%hu\n",
847 NIP6(*(struct in6_addr *)&addr), ntohs(port),
848 NIP6(*(struct in6_addr *)&ct->tuplehash[!dir].tuple.src.u3),
849 ntohs(ct->tuplehash[!dir].tuple.src.u.tcp.port));
850 ret = set_h225_addr(pskb, data, dataoff,
851 &setup->destCallSignalAddress,
852 &ct->tuplehash[!dir].tuple.src.u3,
853 ct->tuplehash[!dir].tuple.src.u.tcp.port);
854 if (ret < 0)
855 return -1;
856 }
857
858 if ((setup->options & eSetup_UUIE_sourceCallSignalAddress) &&
859 (set_h225_addr) && ct->status & IPS_NAT_MASK &&
860 get_h225_addr(ct, *data, &setup->sourceCallSignalAddress,
861 &addr, &port) &&
862 memcmp(&addr, &ct->tuplehash[!dir].tuple.dst.u3, sizeof(addr))) {
863 DEBUGP("nf_ct_q931: set sourceCallSignalAddress "
864 NIP6_FMT ":%hu->" NIP6_FMT ":%hu\n",
865 NIP6(*(struct in6_addr *)&addr), ntohs(port),
866 NIP6(*(struct in6_addr *)&ct->tuplehash[!dir].tuple.dst.u3),
867 ntohs(ct->tuplehash[!dir].tuple.dst.u.tcp.port));
868 ret = set_h225_addr(pskb, data, dataoff,
869 &setup->sourceCallSignalAddress,
870 &ct->tuplehash[!dir].tuple.dst.u3,
871 ct->tuplehash[!dir].tuple.dst.u.tcp.port);
872 if (ret < 0)
873 return -1;
874 }
875
876 if (setup->options & eSetup_UUIE_fastStart) {
877 for (i = 0; i < setup->fastStart.count; i++) {
878 ret = process_olc(pskb, ct, ctinfo, data, dataoff,
879 &setup->fastStart.item[i]);
880 if (ret < 0)
881 return -1;
882 }
883 }
884
885 return 0;
886}
887
888/****************************************************************************/
889static int process_callproceeding(struct sk_buff **pskb,
890 struct nf_conn *ct,
891 enum ip_conntrack_info ctinfo,
892 unsigned char **data, int dataoff,
893 CallProceeding_UUIE *callproc)
894{
895 int ret;
896 int i;
897
898 DEBUGP("nf_ct_q931: CallProceeding\n");
899
900 if (callproc->options & eCallProceeding_UUIE_h245Address) {
901 ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
902 &callproc->h245Address);
903 if (ret < 0)
904 return -1;
905 }
906
907 if (callproc->options & eCallProceeding_UUIE_fastStart) {
908 for (i = 0; i < callproc->fastStart.count; i++) {
909 ret = process_olc(pskb, ct, ctinfo, data, dataoff,
910 &callproc->fastStart.item[i]);
911 if (ret < 0)
912 return -1;
913 }
914 }
915
916 return 0;
917}
918
919/****************************************************************************/
920static int process_connect(struct sk_buff **pskb, struct nf_conn *ct,
921 enum ip_conntrack_info ctinfo,
922 unsigned char **data, int dataoff,
923 Connect_UUIE *connect)
924{
925 int ret;
926 int i;
927
928 DEBUGP("nf_ct_q931: Connect\n");
929
930 if (connect->options & eConnect_UUIE_h245Address) {
931 ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
932 &connect->h245Address);
933 if (ret < 0)
934 return -1;
935 }
936
937 if (connect->options & eConnect_UUIE_fastStart) {
938 for (i = 0; i < connect->fastStart.count; i++) {
939 ret = process_olc(pskb, ct, ctinfo, data, dataoff,
940 &connect->fastStart.item[i]);
941 if (ret < 0)
942 return -1;
943 }
944 }
945
946 return 0;
947}
948
949/****************************************************************************/
950static int process_alerting(struct sk_buff **pskb, struct nf_conn *ct,
951 enum ip_conntrack_info ctinfo,
952 unsigned char **data, int dataoff,
953 Alerting_UUIE *alert)
954{
955 int ret;
956 int i;
957
958 DEBUGP("nf_ct_q931: Alerting\n");
959
960 if (alert->options & eAlerting_UUIE_h245Address) {
961 ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
962 &alert->h245Address);
963 if (ret < 0)
964 return -1;
965 }
966
967 if (alert->options & eAlerting_UUIE_fastStart) {
968 for (i = 0; i < alert->fastStart.count; i++) {
969 ret = process_olc(pskb, ct, ctinfo, data, dataoff,
970 &alert->fastStart.item[i]);
971 if (ret < 0)
972 return -1;
973 }
974 }
975
976 return 0;
977}
978
979/****************************************************************************/
980static int process_information(struct sk_buff **pskb,
981 struct nf_conn *ct,
982 enum ip_conntrack_info ctinfo,
983 unsigned char **data, int dataoff,
984 Information_UUIE *info)
985{
986 int ret;
987 int i;
988
989 DEBUGP("nf_ct_q931: Information\n");
990
991 if (info->options & eInformation_UUIE_fastStart) {
992 for (i = 0; i < info->fastStart.count; i++) {
993 ret = process_olc(pskb, ct, ctinfo, data, dataoff,
994 &info->fastStart.item[i]);
995 if (ret < 0)
996 return -1;
997 }
998 }
999
1000 return 0;
1001}
1002
1003/****************************************************************************/
1004static int process_facility(struct sk_buff **pskb, struct nf_conn *ct,
1005 enum ip_conntrack_info ctinfo,
1006 unsigned char **data, int dataoff,
1007 Facility_UUIE *facility)
1008{
1009 int ret;
1010 int i;
1011
1012 DEBUGP("nf_ct_q931: Facility\n");
1013
1014 if (facility->reason.choice == eFacilityReason_callForwarded) {
1015 if (facility->options & eFacility_UUIE_alternativeAddress)
1016 return expect_callforwarding(pskb, ct, ctinfo, data,
1017 dataoff,
1018 &facility->
1019 alternativeAddress);
1020 return 0;
1021 }
1022
1023 if (facility->options & eFacility_UUIE_h245Address) {
1024 ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
1025 &facility->h245Address);
1026 if (ret < 0)
1027 return -1;
1028 }
1029
1030 if (facility->options & eFacility_UUIE_fastStart) {
1031 for (i = 0; i < facility->fastStart.count; i++) {
1032 ret = process_olc(pskb, ct, ctinfo, data, dataoff,
1033 &facility->fastStart.item[i]);
1034 if (ret < 0)
1035 return -1;
1036 }
1037 }
1038
1039 return 0;
1040}
1041
1042/****************************************************************************/
1043static int process_progress(struct sk_buff **pskb, struct nf_conn *ct,
1044 enum ip_conntrack_info ctinfo,
1045 unsigned char **data, int dataoff,
1046 Progress_UUIE *progress)
1047{
1048 int ret;
1049 int i;
1050
1051 DEBUGP("nf_ct_q931: Progress\n");
1052
1053 if (progress->options & eProgress_UUIE_h245Address) {
1054 ret = expect_h245(pskb, ct, ctinfo, data, dataoff,
1055 &progress->h245Address);
1056 if (ret < 0)
1057 return -1;
1058 }
1059
1060 if (progress->options & eProgress_UUIE_fastStart) {
1061 for (i = 0; i < progress->fastStart.count; i++) {
1062 ret = process_olc(pskb, ct, ctinfo, data, dataoff,
1063 &progress->fastStart.item[i]);
1064 if (ret < 0)
1065 return -1;
1066 }
1067 }
1068
1069 return 0;
1070}
1071
1072/****************************************************************************/
1073static int process_q931(struct sk_buff **pskb, struct nf_conn *ct,
1074 enum ip_conntrack_info ctinfo,
1075 unsigned char **data, int dataoff, Q931 *q931)
1076{
1077 H323_UU_PDU *pdu = &q931->UUIE.h323_uu_pdu;
1078 int i;
1079 int ret = 0;
1080
1081 switch (pdu->h323_message_body.choice) {
1082 case eH323_UU_PDU_h323_message_body_setup:
1083 ret = process_setup(pskb, ct, ctinfo, data, dataoff,
1084 &pdu->h323_message_body.setup);
1085 break;
1086 case eH323_UU_PDU_h323_message_body_callProceeding:
1087 ret = process_callproceeding(pskb, ct, ctinfo, data, dataoff,
1088 &pdu->h323_message_body.
1089 callProceeding);
1090 break;
1091 case eH323_UU_PDU_h323_message_body_connect:
1092 ret = process_connect(pskb, ct, ctinfo, data, dataoff,
1093 &pdu->h323_message_body.connect);
1094 break;
1095 case eH323_UU_PDU_h323_message_body_alerting:
1096 ret = process_alerting(pskb, ct, ctinfo, data, dataoff,
1097 &pdu->h323_message_body.alerting);
1098 break;
1099 case eH323_UU_PDU_h323_message_body_information:
1100 ret = process_information(pskb, ct, ctinfo, data, dataoff,
1101 &pdu->h323_message_body.
1102 information);
1103 break;
1104 case eH323_UU_PDU_h323_message_body_facility:
1105 ret = process_facility(pskb, ct, ctinfo, data, dataoff,
1106 &pdu->h323_message_body.facility);
1107 break;
1108 case eH323_UU_PDU_h323_message_body_progress:
1109 ret = process_progress(pskb, ct, ctinfo, data, dataoff,
1110 &pdu->h323_message_body.progress);
1111 break;
1112 default:
1113 DEBUGP("nf_ct_q931: Q.931 signal %d\n",
1114 pdu->h323_message_body.choice);
1115 break;
1116 }
1117
1118 if (ret < 0)
1119 return -1;
1120
1121 if (pdu->options & eH323_UU_PDU_h245Control) {
1122 for (i = 0; i < pdu->h245Control.count; i++) {
1123 ret = process_h245(pskb, ct, ctinfo, data, dataoff,
1124 &pdu->h245Control.item[i]);
1125 if (ret < 0)
1126 return -1;
1127 }
1128 }
1129
1130 return 0;
1131}
1132
1133/****************************************************************************/
1134static int q931_help(struct sk_buff **pskb, unsigned int protoff,
1135 struct nf_conn *ct, enum ip_conntrack_info ctinfo)
1136{
1137 static Q931 q931;
1138 unsigned char *data = NULL;
1139 int datalen;
1140 int dataoff;
1141 int ret;
1142
1143 /* Until there's been traffic both ways, don't look in packets. */
1144 if (ctinfo != IP_CT_ESTABLISHED &&
1145 ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) {
1146 return NF_ACCEPT;
1147 }
1148 DEBUGP("nf_ct_q931: skblen = %u\n", (*pskb)->len);
1149
1150 spin_lock_bh(&nf_h323_lock);
1151
1152 /* Process each TPKT */
1153 while (get_tpkt_data(pskb, protoff, ct, ctinfo,
1154 &data, &datalen, &dataoff)) {
1155 DEBUGP("nf_ct_q931: TPKT len=%d ", datalen);
1156 NF_CT_DUMP_TUPLE(&ct->tuplehash[CTINFO2DIR(ctinfo)].tuple);
1157
1158 /* Decode Q.931 signal */
1159 ret = DecodeQ931(data, datalen, &q931);
1160 if (ret < 0) {
1161 if (net_ratelimit())
1162 printk("nf_ct_q931: decoding error: %s\n",
1163 ret == H323_ERROR_BOUND ?
1164 "out of bound" : "out of range");
1165 /* We don't drop when decoding error */
1166 break;
1167 }
1168
1169 /* Process Q.931 signal */
1170 if (process_q931(pskb, ct, ctinfo, &data, dataoff, &q931) < 0)
1171 goto drop;
1172 }
1173
1174 spin_unlock_bh(&nf_h323_lock);
1175 return NF_ACCEPT;
1176
1177 drop:
1178 spin_unlock_bh(&nf_h323_lock);
1179 if (net_ratelimit())
1180 printk("nf_ct_q931: packet dropped\n");
1181 return NF_DROP;
1182}
1183
1184/****************************************************************************/
1185static struct nf_conntrack_helper nf_conntrack_helper_q931[] __read_mostly = {
1186 {
1187 .name = "Q.931",
1188 .me = THIS_MODULE,
1189 /* T.120 and H.245 */
1190 .max_expected = H323_RTP_CHANNEL_MAX * 4 + 4,
1191 .timeout = 240,
1192 .tuple.src.l3num = AF_INET,
1193 .tuple.src.u.tcp.port = __constant_htons(Q931_PORT),
1194 .tuple.dst.protonum = IPPROTO_TCP,
1195 .mask.src.l3num = 0xFFFF,
1196 .mask.src.u.tcp.port = __constant_htons(0xFFFF),
1197 .mask.dst.protonum = 0xFF,
1198 .help = q931_help
1199 },
1200 {
1201 .name = "Q.931",
1202 .me = THIS_MODULE,
1203 /* T.120 and H.245 */
1204 .max_expected = H323_RTP_CHANNEL_MAX * 4 + 4,
1205 .timeout = 240,
1206 .tuple.src.l3num = AF_INET6,
1207 .tuple.src.u.tcp.port = __constant_htons(Q931_PORT),
1208 .tuple.dst.protonum = IPPROTO_TCP,
1209 .mask.src.l3num = 0xFFFF,
1210 .mask.src.u.tcp.port = __constant_htons(0xFFFF),
1211 .mask.dst.protonum = 0xFF,
1212 .help = q931_help
1213 },
1214};
1215
1216/****************************************************************************/
1217static unsigned char *get_udp_data(struct sk_buff **pskb, unsigned int protoff,
1218 int *datalen)
1219{
1220 struct udphdr _uh, *uh;
1221 int dataoff;
1222
1223 uh = skb_header_pointer(*pskb, protoff, sizeof(_uh), &_uh);
1224 if (uh == NULL)
1225 return NULL;
1226 dataoff = protoff + sizeof(_uh);
1227 if (dataoff >= (*pskb)->len)
1228 return NULL;
1229 *datalen = (*pskb)->len - dataoff;
1230 return skb_header_pointer(*pskb, dataoff, *datalen, h323_buffer);
1231}
1232
1233/****************************************************************************/
1234static struct nf_conntrack_expect *find_expect(struct nf_conn *ct,
1235 union nf_conntrack_address *addr,
1236 __be16 port)
1237{
1238 struct nf_conntrack_expect *exp;
1239 struct nf_conntrack_tuple tuple;
1240
1241 memset(&tuple.src.u3, 0, sizeof(tuple.src.u3));
1242 tuple.src.u.tcp.port = 0;
1243 memcpy(&tuple.dst.u3, addr, sizeof(tuple.dst.u3));
1244 tuple.dst.u.tcp.port = port;
1245 tuple.dst.protonum = IPPROTO_TCP;
1246
1247 exp = __nf_conntrack_expect_find(&tuple);
1248 if (exp && exp->master == ct)
1249 return exp;
1250 return NULL;
1251}
1252
1253/****************************************************************************/
1254static int set_expect_timeout(struct nf_conntrack_expect *exp,
1255 unsigned timeout)
1256{
1257 if (!exp || !del_timer(&exp->timeout))
1258 return 0;
1259
1260 exp->timeout.expires = jiffies + timeout * HZ;
1261 add_timer(&exp->timeout);
1262
1263 return 1;
1264}
1265
1266/****************************************************************************/
1267static int expect_q931(struct sk_buff **pskb, struct nf_conn *ct,
1268 enum ip_conntrack_info ctinfo,
1269 unsigned char **data,
1270 TransportAddress *taddr, int count)
1271{
1272 struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;
1273 int dir = CTINFO2DIR(ctinfo);
1274 int ret = 0;
1275 int i;
1276 __be16 port;
1277 union nf_conntrack_address addr;
1278 struct nf_conntrack_expect *exp;
1279 typeof(nat_q931_hook) nat_q931;
1280
1281 /* Look for the first related address */
1282 for (i = 0; i < count; i++) {
1283 if (get_h225_addr(ct, *data, &taddr[i], &addr, &port) &&
1284 memcmp(&addr, &ct->tuplehash[dir].tuple.src.u3,
1285 sizeof(addr)) == 0 && port != 0)
1286 break;
1287 }
1288
1289 if (i >= count) /* Not found */
1290 return 0;
1291
1292 /* Create expect for Q.931 */
1293 if ((exp = nf_conntrack_expect_alloc(ct)) == NULL)
1294 return -1;
1295 nf_conntrack_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
1296 gkrouted_only ? /* only accept calls from GK? */
1297 &ct->tuplehash[!dir].tuple.src.u3 :
1298 NULL,
1299 &ct->tuplehash[!dir].tuple.dst.u3,
1300 IPPROTO_TCP, NULL, &port);
1301 exp->helper = nf_conntrack_helper_q931;
1302 exp->flags = NF_CT_EXPECT_PERMANENT; /* Accept multiple calls */
1303
1304 nat_q931 = rcu_dereference(nat_q931_hook);
1305 if (nat_q931 && ct->status & IPS_NAT_MASK) { /* Need NAT */
1306 ret = nat_q931(pskb, ct, ctinfo, data, taddr, i, port, exp);
1307 } else { /* Conntrack only */
1308 if (nf_conntrack_expect_related(exp) == 0) {
1309 DEBUGP("nf_ct_ras: expect Q.931 ");
1310 NF_CT_DUMP_TUPLE(&exp->tuple);
1311
1312 /* Save port for looking up expect in processing RCF */
1313 info->sig_port[dir] = port;
1314 } else
1315 ret = -1;
1316 }
1317
1318 nf_conntrack_expect_put(exp);
1319
1320 return ret;
1321}
1322
1323/****************************************************************************/
1324static int process_grq(struct sk_buff **pskb, struct nf_conn *ct,
1325 enum ip_conntrack_info ctinfo,
1326 unsigned char **data, GatekeeperRequest *grq)
1327{
1328 typeof(set_ras_addr_hook) set_ras_addr;
1329
1330 DEBUGP("nf_ct_ras: GRQ\n");
1331
1332 set_ras_addr = rcu_dereference(set_ras_addr_hook);
1333 if (set_ras_addr && ct->status & IPS_NAT_MASK) /* NATed */
1334 return set_ras_addr(pskb, ct, ctinfo, data,
1335 &grq->rasAddress, 1);
1336 return 0;
1337}
1338
1339/****************************************************************************/
1340static int process_gcf(struct sk_buff **pskb, struct nf_conn *ct,
1341 enum ip_conntrack_info ctinfo,
1342 unsigned char **data, GatekeeperConfirm *gcf)
1343{
1344 int dir = CTINFO2DIR(ctinfo);
1345 int ret = 0;
1346 __be16 port;
1347 union nf_conntrack_address addr;
1348 struct nf_conntrack_expect *exp;
1349
1350 DEBUGP("nf_ct_ras: GCF\n");
1351
1352 if (!get_h225_addr(ct, *data, &gcf->rasAddress, &addr, &port))
1353 return 0;
1354
1355 /* Registration port is the same as discovery port */
1356 if (!memcmp(&addr, &ct->tuplehash[dir].tuple.src.u3, sizeof(addr)) &&
1357 port == ct->tuplehash[dir].tuple.src.u.udp.port)
1358 return 0;
1359
1360 /* Avoid RAS expectation loops. A GCF is never expected. */
1361 if (test_bit(IPS_EXPECTED_BIT, &ct->status))
1362 return 0;
1363
1364 /* Need new expect */
1365 if ((exp = nf_conntrack_expect_alloc(ct)) == NULL)
1366 return -1;
1367 nf_conntrack_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
1368 &ct->tuplehash[!dir].tuple.src.u3, &addr,
1369 IPPROTO_UDP, NULL, &port);
1370 exp->helper = nf_conntrack_helper_ras;
1371
1372 if (nf_conntrack_expect_related(exp) == 0) {
1373 DEBUGP("nf_ct_ras: expect RAS ");
1374 NF_CT_DUMP_TUPLE(&exp->tuple);
1375 } else
1376 ret = -1;
1377
1378 nf_conntrack_expect_put(exp);
1379
1380 return ret;
1381}
1382
1383/****************************************************************************/
1384static int process_rrq(struct sk_buff **pskb, struct nf_conn *ct,
1385 enum ip_conntrack_info ctinfo,
1386 unsigned char **data, RegistrationRequest *rrq)
1387{
1388 struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;
1389 int ret;
1390 typeof(set_ras_addr_hook) set_ras_addr;
1391
1392 DEBUGP("nf_ct_ras: RRQ\n");
1393
1394 ret = expect_q931(pskb, ct, ctinfo, data,
1395 rrq->callSignalAddress.item,
1396 rrq->callSignalAddress.count);
1397 if (ret < 0)
1398 return -1;
1399
1400 set_ras_addr = rcu_dereference(set_ras_addr_hook);
1401 if (set_ras_addr && ct->status & IPS_NAT_MASK) {
1402 ret = set_ras_addr(pskb, ct, ctinfo, data,
1403 rrq->rasAddress.item,
1404 rrq->rasAddress.count);
1405 if (ret < 0)
1406 return -1;
1407 }
1408
1409 if (rrq->options & eRegistrationRequest_timeToLive) {
1410 DEBUGP("nf_ct_ras: RRQ TTL = %u seconds\n", rrq->timeToLive);
1411 info->timeout = rrq->timeToLive;
1412 } else
1413 info->timeout = default_rrq_ttl;
1414
1415 return 0;
1416}
1417
1418/****************************************************************************/
1419static int process_rcf(struct sk_buff **pskb, struct nf_conn *ct,
1420 enum ip_conntrack_info ctinfo,
1421 unsigned char **data, RegistrationConfirm *rcf)
1422{
1423 struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;
1424 int dir = CTINFO2DIR(ctinfo);
1425 int ret;
1426 struct nf_conntrack_expect *exp;
1427 typeof(set_sig_addr_hook) set_sig_addr;
1428
1429 DEBUGP("nf_ct_ras: RCF\n");
1430
1431 set_sig_addr = rcu_dereference(set_sig_addr_hook);
1432 if (set_sig_addr && ct->status & IPS_NAT_MASK) {
1433 ret = set_sig_addr(pskb, ct, ctinfo, data,
1434 rcf->callSignalAddress.item,
1435 rcf->callSignalAddress.count);
1436 if (ret < 0)
1437 return -1;
1438 }
1439
1440 if (rcf->options & eRegistrationConfirm_timeToLive) {
1441 DEBUGP("nf_ct_ras: RCF TTL = %u seconds\n", rcf->timeToLive);
1442 info->timeout = rcf->timeToLive;
1443 }
1444
1445 if (info->timeout > 0) {
1446 DEBUGP
1447 ("nf_ct_ras: set RAS connection timeout to %u seconds\n",
1448 info->timeout);
1449 nf_ct_refresh(ct, *pskb, info->timeout * HZ);
1450
1451 /* Set expect timeout */
1452 read_lock_bh(&nf_conntrack_lock);
1453 exp = find_expect(ct, &ct->tuplehash[dir].tuple.dst.u3,
1454 info->sig_port[!dir]);
1455 if (exp) {
1456 DEBUGP("nf_ct_ras: set Q.931 expect "
1457 "timeout to %u seconds for",
1458 info->timeout);
1459 NF_CT_DUMP_TUPLE(&exp->tuple);
1460 set_expect_timeout(exp, info->timeout);
1461 }
1462 read_unlock_bh(&nf_conntrack_lock);
1463 }
1464
1465 return 0;
1466}
1467
1468/****************************************************************************/
1469static int process_urq(struct sk_buff **pskb, struct nf_conn *ct,
1470 enum ip_conntrack_info ctinfo,
1471 unsigned char **data, UnregistrationRequest *urq)
1472{
1473 struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;
1474 int dir = CTINFO2DIR(ctinfo);
1475 int ret;
1476 typeof(set_sig_addr_hook) set_sig_addr;
1477
1478 DEBUGP("nf_ct_ras: URQ\n");
1479
1480 set_sig_addr = rcu_dereference(set_sig_addr_hook);
1481 if (set_sig_addr && ct->status & IPS_NAT_MASK) {
1482 ret = set_sig_addr(pskb, ct, ctinfo, data,
1483 urq->callSignalAddress.item,
1484 urq->callSignalAddress.count);
1485 if (ret < 0)
1486 return -1;
1487 }
1488
1489 /* Clear old expect */
1490 nf_ct_remove_expectations(ct);
1491 info->sig_port[dir] = 0;
1492 info->sig_port[!dir] = 0;
1493
1494 /* Give it 30 seconds for UCF or URJ */
1495 nf_ct_refresh(ct, *pskb, 30 * HZ);
1496
1497 return 0;
1498}
1499
1500/****************************************************************************/
1501static int process_arq(struct sk_buff **pskb, struct nf_conn *ct,
1502 enum ip_conntrack_info ctinfo,
1503 unsigned char **data, AdmissionRequest *arq)
1504{
1505 struct nf_ct_h323_master *info = &nfct_help(ct)->help.ct_h323_info;
1506 int dir = CTINFO2DIR(ctinfo);
1507 __be16 port;
1508 union nf_conntrack_address addr;
1509 typeof(set_h225_addr_hook) set_h225_addr;
1510
1511 DEBUGP("nf_ct_ras: ARQ\n");
1512
1513 set_h225_addr = rcu_dereference(set_h225_addr_hook);
1514 if ((arq->options & eAdmissionRequest_destCallSignalAddress) &&
1515 get_h225_addr(ct, *data, &arq->destCallSignalAddress,
1516 &addr, &port) &&
1517 !memcmp(&addr, &ct->tuplehash[dir].tuple.src.u3, sizeof(addr)) &&
1518 port == info->sig_port[dir] &&
1519 set_h225_addr && ct->status & IPS_NAT_MASK) {
1520 /* Answering ARQ */
1521 return set_h225_addr(pskb, data, 0,
1522 &arq->destCallSignalAddress,
1523 &ct->tuplehash[!dir].tuple.dst.u3,
1524 info->sig_port[!dir]);
1525 }
1526
1527 if ((arq->options & eAdmissionRequest_srcCallSignalAddress) &&
1528 get_h225_addr(ct, *data, &arq->srcCallSignalAddress,
1529 &addr, &port) &&
1530 !memcmp(&addr, &ct->tuplehash[dir].tuple.src.u3, sizeof(addr)) &&
1531 set_h225_addr && ct->status & IPS_NAT_MASK) {
1532 /* Calling ARQ */
1533 return set_h225_addr(pskb, data, 0,
1534 &arq->srcCallSignalAddress,
1535 &ct->tuplehash[!dir].tuple.dst.u3,
1536 port);
1537 }
1538
1539 return 0;
1540}
1541
1542/****************************************************************************/
1543static int process_acf(struct sk_buff **pskb, struct nf_conn *ct,
1544 enum ip_conntrack_info ctinfo,
1545 unsigned char **data, AdmissionConfirm *acf)
1546{
1547 int dir = CTINFO2DIR(ctinfo);
1548 int ret = 0;
1549 __be16 port;
1550 union nf_conntrack_address addr;
1551 struct nf_conntrack_expect *exp;
1552 typeof(set_sig_addr_hook) set_sig_addr;
1553
1554 DEBUGP("nf_ct_ras: ACF\n");
1555
1556 if (!get_h225_addr(ct, *data, &acf->destCallSignalAddress,
1557 &addr, &port))
1558 return 0;
1559
1560 if (!memcmp(&addr, &ct->tuplehash[dir].tuple.dst.u3, sizeof(addr))) {
1561 /* Answering ACF */
1562 set_sig_addr = rcu_dereference(set_sig_addr_hook);
1563 if (set_sig_addr && ct->status & IPS_NAT_MASK)
1564 return set_sig_addr(pskb, ct, ctinfo, data,
1565 &acf->destCallSignalAddress, 1);
1566 return 0;
1567 }
1568
1569 /* Need new expect */
1570 if ((exp = nf_conntrack_expect_alloc(ct)) == NULL)
1571 return -1;
1572 nf_conntrack_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
1573 &ct->tuplehash[!dir].tuple.src.u3, &addr,
1574 IPPROTO_TCP, NULL, &port);
1575 exp->flags = NF_CT_EXPECT_PERMANENT;
1576 exp->helper = nf_conntrack_helper_q931;
1577
1578 if (nf_conntrack_expect_related(exp) == 0) {
1579 DEBUGP("nf_ct_ras: expect Q.931 ");
1580 NF_CT_DUMP_TUPLE(&exp->tuple);
1581 } else
1582 ret = -1;
1583
1584 nf_conntrack_expect_put(exp);
1585
1586 return ret;
1587}
1588
1589/****************************************************************************/
1590static int process_lrq(struct sk_buff **pskb, struct nf_conn *ct,
1591 enum ip_conntrack_info ctinfo,
1592 unsigned char **data, LocationRequest *lrq)
1593{
1594 typeof(set_ras_addr_hook) set_ras_addr;
1595
1596 DEBUGP("nf_ct_ras: LRQ\n");
1597
1598 set_ras_addr = rcu_dereference(set_ras_addr_hook);
1599 if (set_ras_addr && ct->status & IPS_NAT_MASK)
1600 return set_ras_addr(pskb, ct, ctinfo, data,
1601 &lrq->replyAddress, 1);
1602 return 0;
1603}
1604
1605/****************************************************************************/
1606static int process_lcf(struct sk_buff **pskb, struct nf_conn *ct,
1607 enum ip_conntrack_info ctinfo,
1608 unsigned char **data, LocationConfirm *lcf)
1609{
1610 int dir = CTINFO2DIR(ctinfo);
1611 int ret = 0;
1612 __be16 port;
1613 union nf_conntrack_address addr;
1614 struct nf_conntrack_expect *exp;
1615
1616 DEBUGP("nf_ct_ras: LCF\n");
1617
1618 if (!get_h225_addr(ct, *data, &lcf->callSignalAddress,
1619 &addr, &port))
1620 return 0;
1621
1622 /* Need new expect for call signal */
1623 if ((exp = nf_conntrack_expect_alloc(ct)) == NULL)
1624 return -1;
1625 nf_conntrack_expect_init(exp, ct->tuplehash[!dir].tuple.src.l3num,
1626 &ct->tuplehash[!dir].tuple.src.u3, &addr,
1627 IPPROTO_TCP, NULL, &port);
1628 exp->flags = NF_CT_EXPECT_PERMANENT;
1629 exp->helper = nf_conntrack_helper_q931;
1630
1631 if (nf_conntrack_expect_related(exp) == 0) {
1632 DEBUGP("nf_ct_ras: expect Q.931 ");
1633 NF_CT_DUMP_TUPLE(&exp->tuple);
1634 } else
1635 ret = -1;
1636
1637 nf_conntrack_expect_put(exp);
1638
1639 /* Ignore rasAddress */
1640
1641 return ret;
1642}
1643
1644/****************************************************************************/
1645static int process_irr(struct sk_buff **pskb, struct nf_conn *ct,
1646 enum ip_conntrack_info ctinfo,
1647 unsigned char **data, InfoRequestResponse *irr)
1648{
1649 int ret;
1650 typeof(set_ras_addr_hook) set_ras_addr;
1651 typeof(set_sig_addr_hook) set_sig_addr;
1652
1653 DEBUGP("nf_ct_ras: IRR\n");
1654
1655 set_ras_addr = rcu_dereference(set_ras_addr_hook);
1656 if (set_ras_addr && ct->status & IPS_NAT_MASK) {
1657 ret = set_ras_addr(pskb, ct, ctinfo, data,
1658 &irr->rasAddress, 1);
1659 if (ret < 0)
1660 return -1;
1661 }
1662
1663 set_sig_addr = rcu_dereference(set_sig_addr_hook);
1664 if (set_sig_addr && ct->status & IPS_NAT_MASK) {
1665 ret = set_sig_addr(pskb, ct, ctinfo, data,
1666 irr->callSignalAddress.item,
1667 irr->callSignalAddress.count);
1668 if (ret < 0)
1669 return -1;
1670 }
1671
1672 return 0;
1673}
1674
1675/****************************************************************************/
1676static int process_ras(struct sk_buff **pskb, struct nf_conn *ct,
1677 enum ip_conntrack_info ctinfo,
1678 unsigned char **data, RasMessage *ras)
1679{
1680 switch (ras->choice) {
1681 case eRasMessage_gatekeeperRequest:
1682 return process_grq(pskb, ct, ctinfo, data,
1683 &ras->gatekeeperRequest);
1684 case eRasMessage_gatekeeperConfirm:
1685 return process_gcf(pskb, ct, ctinfo, data,
1686 &ras->gatekeeperConfirm);
1687 case eRasMessage_registrationRequest:
1688 return process_rrq(pskb, ct, ctinfo, data,
1689 &ras->registrationRequest);
1690 case eRasMessage_registrationConfirm:
1691 return process_rcf(pskb, ct, ctinfo, data,
1692 &ras->registrationConfirm);
1693 case eRasMessage_unregistrationRequest:
1694 return process_urq(pskb, ct, ctinfo, data,
1695 &ras->unregistrationRequest);
1696 case eRasMessage_admissionRequest:
1697 return process_arq(pskb, ct, ctinfo, data,
1698 &ras->admissionRequest);
1699 case eRasMessage_admissionConfirm:
1700 return process_acf(pskb, ct, ctinfo, data,
1701 &ras->admissionConfirm);
1702 case eRasMessage_locationRequest:
1703 return process_lrq(pskb, ct, ctinfo, data,
1704 &ras->locationRequest);
1705 case eRasMessage_locationConfirm:
1706 return process_lcf(pskb, ct, ctinfo, data,
1707 &ras->locationConfirm);
1708 case eRasMessage_infoRequestResponse:
1709 return process_irr(pskb, ct, ctinfo, data,
1710 &ras->infoRequestResponse);
1711 default:
1712 DEBUGP("nf_ct_ras: RAS message %d\n", ras->choice);
1713 break;
1714 }
1715
1716 return 0;
1717}
1718
1719/****************************************************************************/
1720static int ras_help(struct sk_buff **pskb, unsigned int protoff,
1721 struct nf_conn *ct, enum ip_conntrack_info ctinfo)
1722{
1723 static RasMessage ras;
1724 unsigned char *data;
1725 int datalen = 0;
1726 int ret;
1727
1728 DEBUGP("nf_ct_ras: skblen = %u\n", (*pskb)->len);
1729
1730 spin_lock_bh(&nf_h323_lock);
1731
1732 /* Get UDP data */
1733 data = get_udp_data(pskb, protoff, &datalen);
1734 if (data == NULL)
1735 goto accept;
1736 DEBUGP("nf_ct_ras: RAS message len=%d ", datalen);
1737 NF_CT_DUMP_TUPLE(&ct->tuplehash[CTINFO2DIR(ctinfo)].tuple);
1738
1739 /* Decode RAS message */
1740 ret = DecodeRasMessage(data, datalen, &ras);
1741 if (ret < 0) {
1742 if (net_ratelimit())
1743 printk("nf_ct_ras: decoding error: %s\n",
1744 ret == H323_ERROR_BOUND ?
1745 "out of bound" : "out of range");
1746 goto accept;
1747 }
1748
1749 /* Process RAS message */
1750 if (process_ras(pskb, ct, ctinfo, &data, &ras) < 0)
1751 goto drop;
1752
1753 accept:
1754 spin_unlock_bh(&nf_h323_lock);
1755 return NF_ACCEPT;
1756
1757 drop:
1758 spin_unlock_bh(&nf_h323_lock);
1759 if (net_ratelimit())
1760 printk("nf_ct_ras: packet dropped\n");
1761 return NF_DROP;
1762}
1763
1764/****************************************************************************/
1765static struct nf_conntrack_helper nf_conntrack_helper_ras[] __read_mostly = {
1766 {
1767 .name = "RAS",
1768 .me = THIS_MODULE,
1769 .max_expected = 32,
1770 .timeout = 240,
1771 .tuple.src.l3num = AF_INET,
1772 .tuple.src.u.udp.port = __constant_htons(RAS_PORT),
1773 .tuple.dst.protonum = IPPROTO_UDP,
1774 .mask.src.l3num = 0xFFFF,
1775 .mask.src.u.udp.port = __constant_htons(0xFFFF),
1776 .mask.dst.protonum = 0xFF,
1777 .help = ras_help,
1778 },
1779 {
1780 .name = "RAS",
1781 .me = THIS_MODULE,
1782 .max_expected = 32,
1783 .timeout = 240,
1784 .tuple.src.l3num = AF_INET6,
1785 .tuple.src.u.udp.port = __constant_htons(RAS_PORT),
1786 .tuple.dst.protonum = IPPROTO_UDP,
1787 .mask.src.l3num = 0xFFFF,
1788 .mask.src.u.udp.port = __constant_htons(0xFFFF),
1789 .mask.dst.protonum = 0xFF,
1790 .help = ras_help,
1791 },
1792};
1793
1794/****************************************************************************/
1795static void __exit nf_conntrack_h323_fini(void)
1796{
1797 nf_conntrack_helper_unregister(&nf_conntrack_helper_ras[1]);
1798 nf_conntrack_helper_unregister(&nf_conntrack_helper_ras[0]);
1799 nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[1]);
1800 nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[0]);
1801 kfree(h323_buffer);
1802 DEBUGP("nf_ct_h323: fini\n");
1803}
1804
1805/****************************************************************************/
1806static int __init nf_conntrack_h323_init(void)
1807{
1808 int ret;
1809
1810 h323_buffer = kmalloc(65536, GFP_KERNEL);
1811 if (!h323_buffer)
1812 return -ENOMEM;
1813 ret = nf_conntrack_helper_register(&nf_conntrack_helper_q931[0]);
1814 if (ret < 0)
1815 goto err1;
1816 ret = nf_conntrack_helper_register(&nf_conntrack_helper_q931[1]);
1817 if (ret < 0)
1818 goto err2;
1819 ret = nf_conntrack_helper_register(&nf_conntrack_helper_ras[0]);
1820 if (ret < 0)
1821 goto err3;
1822 ret = nf_conntrack_helper_register(&nf_conntrack_helper_ras[1]);
1823 if (ret < 0)
1824 goto err4;
1825 DEBUGP("nf_ct_h323: init success\n");
1826 return 0;
1827
1828err4:
1829 nf_conntrack_helper_unregister(&nf_conntrack_helper_ras[0]);
1830err3:
1831 nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[1]);
1832err2:
1833 nf_conntrack_helper_unregister(&nf_conntrack_helper_q931[0]);
1834err1:
1835 return ret;
1836}
1837
1838/****************************************************************************/
1839module_init(nf_conntrack_h323_init);
1840module_exit(nf_conntrack_h323_fini);
1841
1842EXPORT_SYMBOL_GPL(get_h225_addr);
1843EXPORT_SYMBOL_GPL(set_h245_addr_hook);
1844EXPORT_SYMBOL_GPL(set_h225_addr_hook);
1845EXPORT_SYMBOL_GPL(set_sig_addr_hook);
1846EXPORT_SYMBOL_GPL(set_ras_addr_hook);
1847EXPORT_SYMBOL_GPL(nat_rtp_rtcp_hook);
1848EXPORT_SYMBOL_GPL(nat_t120_hook);
1849EXPORT_SYMBOL_GPL(nat_h245_hook);
1850EXPORT_SYMBOL_GPL(nat_callforwarding_hook);
1851EXPORT_SYMBOL_GPL(nat_q931_hook);
1852
1853MODULE_AUTHOR("Jing Min Zhao <zhaojingmin@users.sourceforge.net>");
1854MODULE_DESCRIPTION("H.323 connection tracking helper");
1855MODULE_LICENSE("GPL");
1856MODULE_ALIAS("ip_conntrack_h323");
diff --git a/net/ipv4/netfilter/ip_conntrack_helper_h323_types.c b/net/netfilter/nf_conntrack_h323_types.c
index 4b359618be..4c6f8b3b12 100644
--- a/net/ipv4/netfilter/ip_conntrack_helper_h323_types.c
+++ b/net/netfilter/nf_conntrack_h323_types.c
@@ -36,7 +36,8 @@ static field_t _TransportAddress_ipxAddress[] = { /* SEQUENCE */
36}; 36};
37 37
38static field_t _TransportAddress_ip6Address[] = { /* SEQUENCE */ 38static field_t _TransportAddress_ip6Address[] = { /* SEQUENCE */
39 {FNAME("ip") OCTSTR, FIXD, 16, 0, SKIP, 0, NULL}, 39 {FNAME("ip") OCTSTR, FIXD, 16, 0, DECODE,
40 offsetof(TransportAddress_ip6Address, ip6), NULL},
40 {FNAME("port") INT, WORD, 0, 0, SKIP, 0, NULL}, 41 {FNAME("port") INT, WORD, 0, 0, SKIP, 0, NULL},
41}; 42};
42 43
@@ -65,8 +66,8 @@ static field_t _TransportAddress[] = { /* CHOICE */
65 _TransportAddress_ipSourceRoute}, 66 _TransportAddress_ipSourceRoute},
66 {FNAME("ipxAddress") SEQ, 0, 3, 3, SKIP, 0, 67 {FNAME("ipxAddress") SEQ, 0, 3, 3, SKIP, 0,
67 _TransportAddress_ipxAddress}, 68 _TransportAddress_ipxAddress},
68 {FNAME("ip6Address") SEQ, 0, 2, 2, SKIP | EXT, 0, 69 {FNAME("ip6Address") SEQ, 0, 2, 2, DECODE | EXT,
69 _TransportAddress_ip6Address}, 70 offsetof(TransportAddress, ip6Address), _TransportAddress_ip6Address},
70 {FNAME("netBios") OCTSTR, FIXD, 16, 0, SKIP, 0, NULL}, 71 {FNAME("netBios") OCTSTR, FIXD, 16, 0, SKIP, 0, NULL},
71 {FNAME("nsap") OCTSTR, 5, 1, 0, SKIP, 0, NULL}, 72 {FNAME("nsap") OCTSTR, 5, 1, 0, SKIP, 0, NULL},
72 {FNAME("nonStandardAddress") SEQ, 0, 2, 2, SKIP, 0, 73 {FNAME("nonStandardAddress") SEQ, 0, 2, 2, SKIP, 0,
diff --git a/net/netfilter/nf_conntrack_helper.c b/net/netfilter/nf_conntrack_helper.c
new file mode 100644
index 0000000000..0743be4434
--- /dev/null
+++ b/net/netfilter/nf_conntrack_helper.c
@@ -0,0 +1,155 @@
1/* Helper handling for netfilter. */
2
3/* (C) 1999-2001 Paul `Rusty' Russell
4 * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
5 * (C) 2003,2004 USAGI/WIDE Project <http://www.linux-ipv6.org>
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#include <linux/types.h>
13#include <linux/netfilter.h>
14#include <linux/module.h>
15#include <linux/skbuff.h>
16#include <linux/vmalloc.h>
17#include <linux/stddef.h>
18#include <linux/slab.h>
19#include <linux/random.h>
20#include <linux/err.h>
21#include <linux/kernel.h>
22#include <linux/netdevice.h>
23
24#include <net/netfilter/nf_conntrack.h>
25#include <net/netfilter/nf_conntrack_l3proto.h>
26#include <net/netfilter/nf_conntrack_l4proto.h>
27#include <net/netfilter/nf_conntrack_helper.h>
28#include <net/netfilter/nf_conntrack_core.h>
29
30static __read_mostly LIST_HEAD(helpers);
31
32struct nf_conntrack_helper *
33__nf_ct_helper_find(const struct nf_conntrack_tuple *tuple)
34{
35 struct nf_conntrack_helper *h;
36
37 list_for_each_entry(h, &helpers, list) {
38 if (nf_ct_tuple_mask_cmp(tuple, &h->tuple, &h->mask))
39 return h;
40 }
41 return NULL;
42}
43
44struct nf_conntrack_helper *
45nf_ct_helper_find_get( const struct nf_conntrack_tuple *tuple)
46{
47 struct nf_conntrack_helper *helper;
48
49 /* need nf_conntrack_lock to assure that helper exists until
50 * try_module_get() is called */
51 read_lock_bh(&nf_conntrack_lock);
52
53 helper = __nf_ct_helper_find(tuple);
54 if (helper) {
55 /* need to increase module usage count to assure helper will
56 * not go away while the caller is e.g. busy putting a
57 * conntrack in the hash that uses the helper */
58 if (!try_module_get(helper->me))
59 helper = NULL;
60 }
61
62 read_unlock_bh(&nf_conntrack_lock);
63
64 return helper;
65}
66EXPORT_SYMBOL_GPL(nf_ct_helper_find_get);
67
68void nf_ct_helper_put(struct nf_conntrack_helper *helper)
69{
70 module_put(helper->me);
71}
72EXPORT_SYMBOL_GPL(nf_ct_helper_put);
73
74struct nf_conntrack_helper *
75__nf_conntrack_helper_find_byname(const char *name)
76{
77 struct nf_conntrack_helper *h;
78
79 list_for_each_entry(h, &helpers, list) {
80 if (!strcmp(h->name, name))
81 return h;
82 }
83
84 return NULL;
85}
86EXPORT_SYMBOL_GPL(__nf_conntrack_helper_find_byname);
87
88static inline int unhelp(struct nf_conntrack_tuple_hash *i,
89 const struct nf_conntrack_helper *me)
90{
91 struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(i);
92 struct nf_conn_help *help = nfct_help(ct);
93
94 if (help && help->helper == me) {
95 nf_conntrack_event(IPCT_HELPER, ct);
96 help->helper = NULL;
97 }
98 return 0;
99}
100
101int nf_conntrack_helper_register(struct nf_conntrack_helper *me)
102{
103 int size, ret;
104
105 BUG_ON(me->timeout == 0);
106
107 size = ALIGN(sizeof(struct nf_conn), __alignof__(struct nf_conn_help)) +
108 sizeof(struct nf_conn_help);
109 ret = nf_conntrack_register_cache(NF_CT_F_HELP, "nf_conntrack:help",
110 size);
111 if (ret < 0) {
112 printk(KERN_ERR "nf_conntrack_helper_register: Unable to create slab cache for conntracks\n");
113 return ret;
114 }
115 write_lock_bh(&nf_conntrack_lock);
116 list_add(&me->list, &helpers);
117 write_unlock_bh(&nf_conntrack_lock);
118
119 return 0;
120}
121EXPORT_SYMBOL_GPL(nf_conntrack_helper_register);
122
123void nf_conntrack_helper_unregister(struct nf_conntrack_helper *me)
124{
125 unsigned int i;
126 struct nf_conntrack_tuple_hash *h;
127 struct nf_conntrack_expect *exp, *tmp;
128
129 /* Need write lock here, to delete helper. */
130 write_lock_bh(&nf_conntrack_lock);
131 list_del(&me->list);
132
133 /* Get rid of expectations */
134 list_for_each_entry_safe(exp, tmp, &nf_conntrack_expect_list, list) {
135 struct nf_conn_help *help = nfct_help(exp->master);
136 if ((help->helper == me || exp->helper == me) &&
137 del_timer(&exp->timeout)) {
138 nf_ct_unlink_expect(exp);
139 nf_conntrack_expect_put(exp);
140 }
141 }
142
143 /* Get rid of expecteds, set helpers to NULL. */
144 list_for_each_entry(h, &unconfirmed, list)
145 unhelp(h, me);
146 for (i = 0; i < nf_conntrack_htable_size; i++) {
147 list_for_each_entry(h, &nf_conntrack_hash[i], list)
148 unhelp(h, me);
149 }
150 write_unlock_bh(&nf_conntrack_lock);
151
152 /* Someone could be still looking at the helper in a bh. */
153 synchronize_net();
154}
155EXPORT_SYMBOL_GPL(nf_conntrack_helper_unregister);
diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c
new file mode 100644
index 0000000000..ed01db6343
--- /dev/null
+++ b/net/netfilter/nf_conntrack_irc.c
@@ -0,0 +1,281 @@
1/* IRC extension for IP connection tracking, Version 1.21
2 * (C) 2000-2002 by Harald Welte <laforge@gnumonks.org>
3 * based on RR's ip_conntrack_ftp.c
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version
8 * 2 of the License, or (at your option) any later version.
9 */
10
11#include <linux/module.h>
12#include <linux/moduleparam.h>
13#include <linux/skbuff.h>
14#include <linux/in.h>
15#include <linux/tcp.h>
16#include <linux/netfilter.h>
17
18#include <net/netfilter/nf_conntrack.h>
19#include <net/netfilter/nf_conntrack_expect.h>
20#include <net/netfilter/nf_conntrack_helper.h>
21#include <linux/netfilter/nf_conntrack_irc.h>
22
23#define MAX_PORTS 8
24static unsigned short ports[MAX_PORTS];
25static int ports_c;
26static unsigned int max_dcc_channels = 8;
27static unsigned int dcc_timeout __read_mostly = 300;
28/* This is slow, but it's simple. --RR */
29static char *irc_buffer;
30static DEFINE_SPINLOCK(irc_buffer_lock);
31
32unsigned int (*nf_nat_irc_hook)(struct sk_buff **pskb,
33 enum ip_conntrack_info ctinfo,
34 unsigned int matchoff,
35 unsigned int matchlen,
36 struct nf_conntrack_expect *exp) __read_mostly;
37EXPORT_SYMBOL_GPL(nf_nat_irc_hook);
38
39MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
40MODULE_DESCRIPTION("IRC (DCC) connection tracking helper");
41MODULE_LICENSE("GPL");
42MODULE_ALIAS("ip_conntrack_irc");
43
44module_param_array(ports, ushort, &ports_c, 0400);
45MODULE_PARM_DESC(ports, "port numbers of IRC servers");
46module_param(max_dcc_channels, uint, 0400);
47MODULE_PARM_DESC(max_dcc_channels, "max number of expected DCC channels per "
48 "IRC session");
49module_param(dcc_timeout, uint, 0400);
50MODULE_PARM_DESC(dcc_timeout, "timeout on for unestablished DCC channels");
51
52static const char *dccprotos[] = {
53 "SEND ", "CHAT ", "MOVE ", "TSEND ", "SCHAT "
54};
55
56#define MINMATCHLEN 5
57
58#if 0
59#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s:" format, \
60 __FILE__, __FUNCTION__ , ## args)
61#else
62#define DEBUGP(format, args...)
63#endif
64
65/* tries to get the ip_addr and port out of a dcc command
66 * return value: -1 on failure, 0 on success
67 * data pointer to first byte of DCC command data
68 * data_end pointer to last byte of dcc command data
69 * ip returns parsed ip of dcc command
70 * port returns parsed port of dcc command
71 * ad_beg_p returns pointer to first byte of addr data
72 * ad_end_p returns pointer to last byte of addr data
73 */
74static int parse_dcc(char *data, char *data_end, u_int32_t *ip,
75 u_int16_t *port, char **ad_beg_p, char **ad_end_p)
76{
77 /* at least 12: "AAAAAAAA P\1\n" */
78 while (*data++ != ' ')
79 if (data > data_end - 12)
80 return -1;
81
82 *ad_beg_p = data;
83 *ip = simple_strtoul(data, &data, 10);
84
85 /* skip blanks between ip and port */
86 while (*data == ' ') {
87 if (data >= data_end)
88 return -1;
89 data++;
90 }
91
92 *port = simple_strtoul(data, &data, 10);
93 *ad_end_p = data;
94
95 return 0;
96}
97
98static int help(struct sk_buff **pskb, unsigned int protoff,
99 struct nf_conn *ct, enum ip_conntrack_info ctinfo)
100{
101 unsigned int dataoff;
102 struct tcphdr _tcph, *th;
103 char *data, *data_limit, *ib_ptr;
104 int dir = CTINFO2DIR(ctinfo);
105 struct nf_conntrack_expect *exp;
106 struct nf_conntrack_tuple *tuple;
107 u_int32_t dcc_ip;
108 u_int16_t dcc_port;
109 __be16 port;
110 int i, ret = NF_ACCEPT;
111 char *addr_beg_p, *addr_end_p;
112 typeof(nf_nat_irc_hook) nf_nat_irc;
113
114 /* If packet is coming from IRC server */
115 if (dir == IP_CT_DIR_REPLY)
116 return NF_ACCEPT;
117
118 /* Until there's been traffic both ways, don't look in packets. */
119 if (ctinfo != IP_CT_ESTABLISHED &&
120 ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY)
121 return NF_ACCEPT;
122
123 /* Not a full tcp header? */
124 th = skb_header_pointer(*pskb, protoff, sizeof(_tcph), &_tcph);
125 if (th == NULL)
126 return NF_ACCEPT;
127
128 /* No data? */
129 dataoff = protoff + th->doff*4;
130 if (dataoff >= (*pskb)->len)
131 return NF_ACCEPT;
132
133 spin_lock_bh(&irc_buffer_lock);
134 ib_ptr = skb_header_pointer(*pskb, dataoff, (*pskb)->len - dataoff,
135 irc_buffer);
136 BUG_ON(ib_ptr == NULL);
137
138 data = ib_ptr;
139 data_limit = ib_ptr + (*pskb)->len - dataoff;
140
141 /* strlen("\1DCC SENT t AAAAAAAA P\1\n")=24
142 * 5+MINMATCHLEN+strlen("t AAAAAAAA P\1\n")=14 */
143 while (data < data_limit - (19 + MINMATCHLEN)) {
144 if (memcmp(data, "\1DCC ", 5)) {
145 data++;
146 continue;
147 }
148 data += 5;
149 /* we have at least (19+MINMATCHLEN)-5 bytes valid data left */
150
151 DEBUGP("DCC found in master %u.%u.%u.%u:%u %u.%u.%u.%u:%u...\n",
152 NIPQUAD(iph->saddr), ntohs(th->source),
153 NIPQUAD(iph->daddr), ntohs(th->dest));
154
155 for (i = 0; i < ARRAY_SIZE(dccprotos); i++) {
156 if (memcmp(data, dccprotos[i], strlen(dccprotos[i]))) {
157 /* no match */
158 continue;
159 }
160 data += strlen(dccprotos[i]);
161 DEBUGP("DCC %s detected\n", dccprotos[i]);
162
163 /* we have at least
164 * (19+MINMATCHLEN)-5-dccprotos[i].matchlen bytes valid
165 * data left (== 14/13 bytes) */
166 if (parse_dcc((char *)data, data_limit, &dcc_ip,
167 &dcc_port, &addr_beg_p, &addr_end_p)) {
168 DEBUGP("unable to parse dcc command\n");
169 continue;
170 }
171 DEBUGP("DCC bound ip/port: %u.%u.%u.%u:%u\n",
172 HIPQUAD(dcc_ip), dcc_port);
173
174 /* dcc_ip can be the internal OR external (NAT'ed) IP */
175 tuple = &ct->tuplehash[dir].tuple;
176 if (tuple->src.u3.ip != htonl(dcc_ip) &&
177 tuple->dst.u3.ip != htonl(dcc_ip)) {
178 if (net_ratelimit())
179 printk(KERN_WARNING
180 "Forged DCC command from "
181 "%u.%u.%u.%u: %u.%u.%u.%u:%u\n",
182 NIPQUAD(tuple->src.u3.ip),
183 HIPQUAD(dcc_ip), dcc_port);
184 continue;
185 }
186
187 exp = nf_conntrack_expect_alloc(ct);
188 if (exp == NULL) {
189 ret = NF_DROP;
190 goto out;
191 }
192 tuple = &ct->tuplehash[!dir].tuple;
193 port = htons(dcc_port);
194 nf_conntrack_expect_init(exp, tuple->src.l3num,
195 NULL, &tuple->dst.u3,
196 IPPROTO_TCP, NULL, &port);
197
198 nf_nat_irc = rcu_dereference(nf_nat_irc_hook);
199 if (nf_nat_irc && ct->status & IPS_NAT_MASK)
200 ret = nf_nat_irc(pskb, ctinfo,
201 addr_beg_p - ib_ptr,
202 addr_end_p - addr_beg_p,
203 exp);
204 else if (nf_conntrack_expect_related(exp) != 0)
205 ret = NF_DROP;
206 nf_conntrack_expect_put(exp);
207 goto out;
208 }
209 }
210 out:
211 spin_unlock_bh(&irc_buffer_lock);
212 return ret;
213}
214
215static struct nf_conntrack_helper irc[MAX_PORTS] __read_mostly;
216static char irc_names[MAX_PORTS][sizeof("irc-65535")] __read_mostly;
217
218static void nf_conntrack_irc_fini(void);
219
220static int __init nf_conntrack_irc_init(void)
221{
222 int i, ret;
223 char *tmpname;
224
225 if (max_dcc_channels < 1) {
226 printk("nf_ct_irc: max_dcc_channels must not be zero\n");
227 return -EINVAL;
228 }
229
230 irc_buffer = kmalloc(65536, GFP_KERNEL);
231 if (!irc_buffer)
232 return -ENOMEM;
233
234 /* If no port given, default to standard irc port */
235 if (ports_c == 0)
236 ports[ports_c++] = IRC_PORT;
237
238 for (i = 0; i < ports_c; i++) {
239 irc[i].tuple.src.l3num = AF_INET;
240 irc[i].tuple.src.u.tcp.port = htons(ports[i]);
241 irc[i].tuple.dst.protonum = IPPROTO_TCP;
242 irc[i].mask.src.l3num = 0xFFFF;
243 irc[i].mask.src.u.tcp.port = htons(0xFFFF);
244 irc[i].mask.dst.protonum = 0xFF;
245 irc[i].max_expected = max_dcc_channels;
246 irc[i].timeout = dcc_timeout;
247 irc[i].me = THIS_MODULE;
248 irc[i].help = help;
249
250 tmpname = &irc_names[i][0];
251 if (ports[i] == IRC_PORT)
252 sprintf(tmpname, "irc");
253 else
254 sprintf(tmpname, "irc-%u", i);
255 irc[i].name = tmpname;
256
257 ret = nf_conntrack_helper_register(&irc[i]);
258 if (ret) {
259 printk("nf_ct_irc: failed to register helper "
260 "for pf: %u port: %u\n",
261 irc[i].tuple.src.l3num, ports[i]);
262 nf_conntrack_irc_fini();
263 return ret;
264 }
265 }
266 return 0;
267}
268
269/* This function is intentionally _NOT_ defined as __exit, because
270 * it is needed by the init function */
271static void nf_conntrack_irc_fini(void)
272{
273 int i;
274
275 for (i = 0; i < ports_c; i++)
276 nf_conntrack_helper_unregister(&irc[i]);
277 kfree(irc_buffer);
278}
279
280module_init(nf_conntrack_irc_init);
281module_exit(nf_conntrack_irc_fini);
diff --git a/net/netfilter/nf_conntrack_l3proto_generic.c b/net/netfilter/nf_conntrack_l3proto_generic.c
index 21e0bc91cf..a3d31c3ac8 100644
--- a/net/netfilter/nf_conntrack_l3proto_generic.c
+++ b/net/netfilter/nf_conntrack_l3proto_generic.c
@@ -26,7 +26,7 @@
26 26
27#include <linux/netfilter_ipv4.h> 27#include <linux/netfilter_ipv4.h>
28#include <net/netfilter/nf_conntrack.h> 28#include <net/netfilter/nf_conntrack.h>
29#include <net/netfilter/nf_conntrack_protocol.h> 29#include <net/netfilter/nf_conntrack_l4proto.h>
30#include <net/netfilter/nf_conntrack_l3proto.h> 30#include <net/netfilter/nf_conntrack_l3proto.h>
31#include <net/netfilter/nf_conntrack_core.h> 31#include <net/netfilter/nf_conntrack_core.h>
32#include <net/netfilter/ipv4/nf_conntrack_ipv4.h> 32#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
@@ -37,8 +37,6 @@
37#define DEBUGP(format, args...) 37#define DEBUGP(format, args...)
38#endif 38#endif
39 39
40DECLARE_PER_CPU(struct nf_conntrack_stat, nf_conntrack_stat);
41
42static int generic_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff, 40static int generic_pkt_to_tuple(const struct sk_buff *skb, unsigned int nhoff,
43 struct nf_conntrack_tuple *tuple) 41 struct nf_conntrack_tuple *tuple)
44{ 42{
@@ -84,7 +82,7 @@ static u_int32_t generic_get_features(const struct nf_conntrack_tuple *tuple)
84 return NF_CT_F_BASIC; 82 return NF_CT_F_BASIC;
85} 83}
86 84
87struct nf_conntrack_l3proto nf_conntrack_generic_l3proto = { 85struct nf_conntrack_l3proto nf_conntrack_l3proto_generic = {
88 .l3proto = PF_UNSPEC, 86 .l3proto = PF_UNSPEC,
89 .name = "unknown", 87 .name = "unknown",
90 .pkt_to_tuple = generic_pkt_to_tuple, 88 .pkt_to_tuple = generic_pkt_to_tuple,
@@ -94,3 +92,4 @@ struct nf_conntrack_l3proto nf_conntrack_generic_l3proto = {
94 .prepare = generic_prepare, 92 .prepare = generic_prepare,
95 .get_features = generic_get_features, 93 .get_features = generic_get_features,
96}; 94};
95EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_generic);
diff --git a/net/netfilter/nf_conntrack_netbios_ns.c b/net/netfilter/nf_conntrack_netbios_ns.c
new file mode 100644
index 0000000000..2a48efdf0d
--- /dev/null
+++ b/net/netfilter/nf_conntrack_netbios_ns.c
@@ -0,0 +1,127 @@
1/*
2 * NetBIOS name service broadcast connection tracking helper
3 *
4 * (c) 2005 Patrick McHardy <kaber@trash.net>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11/*
12 * This helper tracks locally originating NetBIOS name service
13 * requests by issuing permanent expectations (valid until
14 * timing out) matching all reply connections from the
15 * destination network. The only NetBIOS specific thing is
16 * actually the port number.
17 */
18#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/skbuff.h>
22#include <linux/netdevice.h>
23#include <linux/inetdevice.h>
24#include <linux/if_addr.h>
25#include <linux/in.h>
26#include <linux/ip.h>
27#include <linux/netfilter.h>
28#include <net/route.h>
29
30#include <net/netfilter/nf_conntrack.h>
31#include <net/netfilter/nf_conntrack_helper.h>
32#include <net/netfilter/nf_conntrack_expect.h>
33
34#define NMBD_PORT 137
35
36MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
37MODULE_DESCRIPTION("NetBIOS name service broadcast connection tracking helper");
38MODULE_LICENSE("GPL");
39MODULE_ALIAS("ip_conntrack_netbios_ns");
40
41static unsigned int timeout __read_mostly = 3;
42module_param(timeout, uint, 0400);
43MODULE_PARM_DESC(timeout, "timeout for master connection/replies in seconds");
44
45static int help(struct sk_buff **pskb, unsigned int protoff,
46 struct nf_conn *ct, enum ip_conntrack_info ctinfo)
47{
48 struct nf_conntrack_expect *exp;
49 struct iphdr *iph = (*pskb)->nh.iph;
50 struct rtable *rt = (struct rtable *)(*pskb)->dst;
51 struct in_device *in_dev;
52 __be32 mask = 0;
53
54 /* we're only interested in locally generated packets */
55 if ((*pskb)->sk == NULL)
56 goto out;
57 if (rt == NULL || !(rt->rt_flags & RTCF_BROADCAST))
58 goto out;
59 if (CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL)
60 goto out;
61
62 rcu_read_lock();
63 in_dev = __in_dev_get_rcu(rt->u.dst.dev);
64 if (in_dev != NULL) {
65 for_primary_ifa(in_dev) {
66 if (ifa->ifa_broadcast == iph->daddr) {
67 mask = ifa->ifa_mask;
68 break;
69 }
70 } endfor_ifa(in_dev);
71 }
72 rcu_read_unlock();
73
74 if (mask == 0)
75 goto out;
76
77 exp = nf_conntrack_expect_alloc(ct);
78 if (exp == NULL)
79 goto out;
80
81 exp->tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple;
82 exp->tuple.src.u.udp.port = htons(NMBD_PORT);
83
84 exp->mask.src.u3.ip = mask;
85 exp->mask.src.u.udp.port = htons(0xFFFF);
86 exp->mask.dst.u3.ip = htonl(0xFFFFFFFF);
87 exp->mask.dst.u.udp.port = htons(0xFFFF);
88 exp->mask.dst.protonum = 0xFF;
89
90 exp->expectfn = NULL;
91 exp->flags = NF_CT_EXPECT_PERMANENT;
92 exp->helper = NULL;
93
94 nf_conntrack_expect_related(exp);
95 nf_conntrack_expect_put(exp);
96
97 nf_ct_refresh(ct, *pskb, timeout * HZ);
98out:
99 return NF_ACCEPT;
100}
101
102static struct nf_conntrack_helper helper __read_mostly = {
103 .name = "netbios-ns",
104 .tuple.src.l3num = AF_INET,
105 .tuple.src.u.udp.port = __constant_htons(NMBD_PORT),
106 .tuple.dst.protonum = IPPROTO_UDP,
107 .mask.src.l3num = 0xFFFF,
108 .mask.src.u.udp.port = __constant_htons(0xFFFF),
109 .mask.dst.protonum = 0xFF,
110 .max_expected = 1,
111 .me = THIS_MODULE,
112 .help = help,
113};
114
115static int __init nf_conntrack_netbios_ns_init(void)
116{
117 helper.timeout = timeout;
118 return nf_conntrack_helper_register(&helper);
119}
120
121static void __exit nf_conntrack_netbios_ns_fini(void)
122{
123 nf_conntrack_helper_unregister(&helper);
124}
125
126module_init(nf_conntrack_netbios_ns_init);
127module_exit(nf_conntrack_netbios_ns_fini);
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index ab67c2be2b..bd1d2de75e 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -35,10 +35,15 @@
35#include <linux/netfilter.h> 35#include <linux/netfilter.h>
36#include <net/netfilter/nf_conntrack.h> 36#include <net/netfilter/nf_conntrack.h>
37#include <net/netfilter/nf_conntrack_core.h> 37#include <net/netfilter/nf_conntrack_core.h>
38#include <net/netfilter/nf_conntrack_expect.h>
38#include <net/netfilter/nf_conntrack_helper.h> 39#include <net/netfilter/nf_conntrack_helper.h>
39#include <net/netfilter/nf_conntrack_l3proto.h> 40#include <net/netfilter/nf_conntrack_l3proto.h>
40#include <net/netfilter/nf_conntrack_protocol.h> 41#include <net/netfilter/nf_conntrack_l4proto.h>
41#include <linux/netfilter_ipv4/ip_nat_protocol.h> 42#include <net/netfilter/nf_conntrack_tuple.h>
43#ifdef CONFIG_NF_NAT_NEEDED
44#include <net/netfilter/nf_nat_core.h>
45#include <net/netfilter/nf_nat_protocol.h>
46#endif
42 47
43#include <linux/netfilter/nfnetlink.h> 48#include <linux/netfilter/nfnetlink.h>
44#include <linux/netfilter/nfnetlink_conntrack.h> 49#include <linux/netfilter/nfnetlink_conntrack.h>
@@ -50,15 +55,15 @@ static char __initdata version[] = "0.93";
50static inline int 55static inline int
51ctnetlink_dump_tuples_proto(struct sk_buff *skb, 56ctnetlink_dump_tuples_proto(struct sk_buff *skb,
52 const struct nf_conntrack_tuple *tuple, 57 const struct nf_conntrack_tuple *tuple,
53 struct nf_conntrack_protocol *proto) 58 struct nf_conntrack_l4proto *l4proto)
54{ 59{
55 int ret = 0; 60 int ret = 0;
56 struct nfattr *nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO); 61 struct nfattr *nest_parms = NFA_NEST(skb, CTA_TUPLE_PROTO);
57 62
58 NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum); 63 NFA_PUT(skb, CTA_PROTO_NUM, sizeof(u_int8_t), &tuple->dst.protonum);
59 64
60 if (likely(proto->tuple_to_nfattr)) 65 if (likely(l4proto->tuple_to_nfattr))
61 ret = proto->tuple_to_nfattr(skb, tuple); 66 ret = l4proto->tuple_to_nfattr(skb, tuple);
62 67
63 NFA_NEST_END(skb, nest_parms); 68 NFA_NEST_END(skb, nest_parms);
64 69
@@ -93,7 +98,7 @@ ctnetlink_dump_tuples(struct sk_buff *skb,
93{ 98{
94 int ret; 99 int ret;
95 struct nf_conntrack_l3proto *l3proto; 100 struct nf_conntrack_l3proto *l3proto;
96 struct nf_conntrack_protocol *proto; 101 struct nf_conntrack_l4proto *l4proto;
97 102
98 l3proto = nf_ct_l3proto_find_get(tuple->src.l3num); 103 l3proto = nf_ct_l3proto_find_get(tuple->src.l3num);
99 ret = ctnetlink_dump_tuples_ip(skb, tuple, l3proto); 104 ret = ctnetlink_dump_tuples_ip(skb, tuple, l3proto);
@@ -102,9 +107,9 @@ ctnetlink_dump_tuples(struct sk_buff *skb,
102 if (unlikely(ret < 0)) 107 if (unlikely(ret < 0))
103 return ret; 108 return ret;
104 109
105 proto = nf_ct_proto_find_get(tuple->src.l3num, tuple->dst.protonum); 110 l4proto = nf_ct_l4proto_find_get(tuple->src.l3num, tuple->dst.protonum);
106 ret = ctnetlink_dump_tuples_proto(skb, tuple, proto); 111 ret = ctnetlink_dump_tuples_proto(skb, tuple, l4proto);
107 nf_ct_proto_put(proto); 112 nf_ct_l4proto_put(l4proto);
108 113
109 return ret; 114 return ret;
110} 115}
@@ -112,7 +117,7 @@ ctnetlink_dump_tuples(struct sk_buff *skb,
112static inline int 117static inline int
113ctnetlink_dump_status(struct sk_buff *skb, const struct nf_conn *ct) 118ctnetlink_dump_status(struct sk_buff *skb, const struct nf_conn *ct)
114{ 119{
115 u_int32_t status = htonl((u_int32_t) ct->status); 120 __be32 status = htonl((u_int32_t) ct->status);
116 NFA_PUT(skb, CTA_STATUS, sizeof(status), &status); 121 NFA_PUT(skb, CTA_STATUS, sizeof(status), &status);
117 return 0; 122 return 0;
118 123
@@ -124,7 +129,7 @@ static inline int
124ctnetlink_dump_timeout(struct sk_buff *skb, const struct nf_conn *ct) 129ctnetlink_dump_timeout(struct sk_buff *skb, const struct nf_conn *ct)
125{ 130{
126 long timeout_l = ct->timeout.expires - jiffies; 131 long timeout_l = ct->timeout.expires - jiffies;
127 u_int32_t timeout; 132 __be32 timeout;
128 133
129 if (timeout_l < 0) 134 if (timeout_l < 0)
130 timeout = 0; 135 timeout = 0;
@@ -141,27 +146,27 @@ nfattr_failure:
141static inline int 146static inline int
142ctnetlink_dump_protoinfo(struct sk_buff *skb, const struct nf_conn *ct) 147ctnetlink_dump_protoinfo(struct sk_buff *skb, const struct nf_conn *ct)
143{ 148{
144 struct nf_conntrack_protocol *proto = nf_ct_proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num, ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum); 149 struct nf_conntrack_l4proto *l4proto = nf_ct_l4proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num, ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum);
145 struct nfattr *nest_proto; 150 struct nfattr *nest_proto;
146 int ret; 151 int ret;
147 152
148 if (!proto->to_nfattr) { 153 if (!l4proto->to_nfattr) {
149 nf_ct_proto_put(proto); 154 nf_ct_l4proto_put(l4proto);
150 return 0; 155 return 0;
151 } 156 }
152 157
153 nest_proto = NFA_NEST(skb, CTA_PROTOINFO); 158 nest_proto = NFA_NEST(skb, CTA_PROTOINFO);
154 159
155 ret = proto->to_nfattr(skb, nest_proto, ct); 160 ret = l4proto->to_nfattr(skb, nest_proto, ct);
156 161
157 nf_ct_proto_put(proto); 162 nf_ct_l4proto_put(l4proto);
158 163
159 NFA_NEST_END(skb, nest_proto); 164 NFA_NEST_END(skb, nest_proto);
160 165
161 return ret; 166 return ret;
162 167
163nfattr_failure: 168nfattr_failure:
164 nf_ct_proto_put(proto); 169 nf_ct_l4proto_put(l4proto);
165 return -1; 170 return -1;
166} 171}
167 172
@@ -195,7 +200,7 @@ ctnetlink_dump_counters(struct sk_buff *skb, const struct nf_conn *ct,
195{ 200{
196 enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG; 201 enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG;
197 struct nfattr *nest_count = NFA_NEST(skb, type); 202 struct nfattr *nest_count = NFA_NEST(skb, type);
198 u_int32_t tmp; 203 __be32 tmp;
199 204
200 tmp = htonl(ct->counters[dir].packets); 205 tmp = htonl(ct->counters[dir].packets);
201 NFA_PUT(skb, CTA_COUNTERS32_PACKETS, sizeof(u_int32_t), &tmp); 206 NFA_PUT(skb, CTA_COUNTERS32_PACKETS, sizeof(u_int32_t), &tmp);
@@ -218,7 +223,7 @@ nfattr_failure:
218static inline int 223static inline int
219ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct) 224ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct)
220{ 225{
221 u_int32_t mark = htonl(ct->mark); 226 __be32 mark = htonl(ct->mark);
222 227
223 NFA_PUT(skb, CTA_MARK, sizeof(u_int32_t), &mark); 228 NFA_PUT(skb, CTA_MARK, sizeof(u_int32_t), &mark);
224 return 0; 229 return 0;
@@ -233,7 +238,7 @@ nfattr_failure:
233static inline int 238static inline int
234ctnetlink_dump_id(struct sk_buff *skb, const struct nf_conn *ct) 239ctnetlink_dump_id(struct sk_buff *skb, const struct nf_conn *ct)
235{ 240{
236 u_int32_t id = htonl(ct->id); 241 __be32 id = htonl(ct->id);
237 NFA_PUT(skb, CTA_ID, sizeof(u_int32_t), &id); 242 NFA_PUT(skb, CTA_ID, sizeof(u_int32_t), &id);
238 return 0; 243 return 0;
239 244
@@ -244,7 +249,7 @@ nfattr_failure:
244static inline int 249static inline int
245ctnetlink_dump_use(struct sk_buff *skb, const struct nf_conn *ct) 250ctnetlink_dump_use(struct sk_buff *skb, const struct nf_conn *ct)
246{ 251{
247 u_int32_t use = htonl(atomic_read(&ct->ct_general.use)); 252 __be32 use = htonl(atomic_read(&ct->ct_general.use));
248 253
249 NFA_PUT(skb, CTA_USE, sizeof(u_int32_t), &use); 254 NFA_PUT(skb, CTA_USE, sizeof(u_int32_t), &use);
250 return 0; 255 return 0;
@@ -330,8 +335,6 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
330 } else if (events & (IPCT_NEW | IPCT_RELATED)) { 335 } else if (events & (IPCT_NEW | IPCT_RELATED)) {
331 type = IPCTNL_MSG_CT_NEW; 336 type = IPCTNL_MSG_CT_NEW;
332 flags = NLM_F_CREATE|NLM_F_EXCL; 337 flags = NLM_F_CREATE|NLM_F_EXCL;
333 /* dump everything */
334 events = ~0UL;
335 group = NFNLGRP_CONNTRACK_NEW; 338 group = NFNLGRP_CONNTRACK_NEW;
336 } else if (events & (IPCT_STATUS | IPCT_PROTOINFO)) { 339 } else if (events & (IPCT_STATUS | IPCT_PROTOINFO)) {
337 type = IPCTNL_MSG_CT_NEW; 340 type = IPCTNL_MSG_CT_NEW;
@@ -366,28 +369,35 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
366 if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_REPLY)) < 0) 369 if (ctnetlink_dump_tuples(skb, tuple(ct, IP_CT_DIR_REPLY)) < 0)
367 goto nfattr_failure; 370 goto nfattr_failure;
368 NFA_NEST_END(skb, nest_parms); 371 NFA_NEST_END(skb, nest_parms);
369
370 /* NAT stuff is now a status flag */
371 if ((events & IPCT_STATUS || events & IPCT_NATINFO)
372 && ctnetlink_dump_status(skb, ct) < 0)
373 goto nfattr_failure;
374 if (events & IPCT_REFRESH
375 && ctnetlink_dump_timeout(skb, ct) < 0)
376 goto nfattr_failure;
377 if (events & IPCT_PROTOINFO
378 && ctnetlink_dump_protoinfo(skb, ct) < 0)
379 goto nfattr_failure;
380 if (events & IPCT_HELPINFO
381 && ctnetlink_dump_helpinfo(skb, ct) < 0)
382 goto nfattr_failure;
383 372
384 if (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 || 373 if (events & IPCT_DESTROY) {
385 ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0) 374 if (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 ||
386 goto nfattr_failure; 375 ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0)
376 goto nfattr_failure;
377 } else {
378 if (ctnetlink_dump_status(skb, ct) < 0)
379 goto nfattr_failure;
387 380
388 if (events & IPCT_MARK 381 if (ctnetlink_dump_timeout(skb, ct) < 0)
389 && ctnetlink_dump_mark(skb, ct) < 0) 382 goto nfattr_failure;
390 goto nfattr_failure; 383
384 if (events & IPCT_PROTOINFO
385 && ctnetlink_dump_protoinfo(skb, ct) < 0)
386 goto nfattr_failure;
387
388 if ((events & IPCT_HELPER || nfct_help(ct))
389 && ctnetlink_dump_helpinfo(skb, ct) < 0)
390 goto nfattr_failure;
391
392 if ((events & IPCT_MARK || ct->mark)
393 && ctnetlink_dump_mark(skb, ct) < 0)
394 goto nfattr_failure;
395
396 if (events & IPCT_COUNTER_FILLING &&
397 (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 ||
398 ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0))
399 goto nfattr_failure;
400 }
391 401
392 nlh->nlmsg_len = skb->tail - b; 402 nlh->nlmsg_len = skb->tail - b;
393 nfnetlink_send(skb, 0, group, 0); 403 nfnetlink_send(skb, 0, group, 0);
@@ -424,7 +434,7 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
424restart: 434restart:
425 list_for_each_prev(i, &nf_conntrack_hash[cb->args[0]]) { 435 list_for_each_prev(i, &nf_conntrack_hash[cb->args[0]]) {
426 h = (struct nf_conntrack_tuple_hash *) i; 436 h = (struct nf_conntrack_tuple_hash *) i;
427 if (DIRECTION(h) != IP_CT_DIR_ORIGINAL) 437 if (NF_CT_DIRECTION(h) != IP_CT_DIR_ORIGINAL)
428 continue; 438 continue;
429 ct = nf_ct_tuplehash_to_ctrack(h); 439 ct = nf_ct_tuplehash_to_ctrack(h);
430 /* Dump entries of a given L3 protocol number. 440 /* Dump entries of a given L3 protocol number.
@@ -492,7 +502,7 @@ ctnetlink_parse_tuple_proto(struct nfattr *attr,
492 struct nf_conntrack_tuple *tuple) 502 struct nf_conntrack_tuple *tuple)
493{ 503{
494 struct nfattr *tb[CTA_PROTO_MAX]; 504 struct nfattr *tb[CTA_PROTO_MAX];
495 struct nf_conntrack_protocol *proto; 505 struct nf_conntrack_l4proto *l4proto;
496 int ret = 0; 506 int ret = 0;
497 507
498 nfattr_parse_nested(tb, CTA_PROTO_MAX, attr); 508 nfattr_parse_nested(tb, CTA_PROTO_MAX, attr);
@@ -504,12 +514,12 @@ ctnetlink_parse_tuple_proto(struct nfattr *attr,
504 return -EINVAL; 514 return -EINVAL;
505 tuple->dst.protonum = *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_NUM-1]); 515 tuple->dst.protonum = *(u_int8_t *)NFA_DATA(tb[CTA_PROTO_NUM-1]);
506 516
507 proto = nf_ct_proto_find_get(tuple->src.l3num, tuple->dst.protonum); 517 l4proto = nf_ct_l4proto_find_get(tuple->src.l3num, tuple->dst.protonum);
508 518
509 if (likely(proto->nfattr_to_tuple)) 519 if (likely(l4proto->nfattr_to_tuple))
510 ret = proto->nfattr_to_tuple(tb, tuple); 520 ret = l4proto->nfattr_to_tuple(tb, tuple);
511 521
512 nf_ct_proto_put(proto); 522 nf_ct_l4proto_put(l4proto);
513 523
514 return ret; 524 return ret;
515} 525}
@@ -550,28 +560,28 @@ ctnetlink_parse_tuple(struct nfattr *cda[], struct nf_conntrack_tuple *tuple,
550 return 0; 560 return 0;
551} 561}
552 562
553#ifdef CONFIG_IP_NF_NAT_NEEDED 563#ifdef CONFIG_NF_NAT_NEEDED
554static const size_t cta_min_protonat[CTA_PROTONAT_MAX] = { 564static const size_t cta_min_protonat[CTA_PROTONAT_MAX] = {
555 [CTA_PROTONAT_PORT_MIN-1] = sizeof(u_int16_t), 565 [CTA_PROTONAT_PORT_MIN-1] = sizeof(u_int16_t),
556 [CTA_PROTONAT_PORT_MAX-1] = sizeof(u_int16_t), 566 [CTA_PROTONAT_PORT_MAX-1] = sizeof(u_int16_t),
557}; 567};
558 568
559static int ctnetlink_parse_nat_proto(struct nfattr *attr, 569static int nfnetlink_parse_nat_proto(struct nfattr *attr,
560 const struct nf_conn *ct, 570 const struct nf_conn *ct,
561 struct ip_nat_range *range) 571 struct nf_nat_range *range)
562{ 572{
563 struct nfattr *tb[CTA_PROTONAT_MAX]; 573 struct nfattr *tb[CTA_PROTONAT_MAX];
564 struct ip_nat_protocol *npt; 574 struct nf_nat_protocol *npt;
565 575
566 nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr); 576 nfattr_parse_nested(tb, CTA_PROTONAT_MAX, attr);
567 577
568 if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat)) 578 if (nfattr_bad_size(tb, CTA_PROTONAT_MAX, cta_min_protonat))
569 return -EINVAL; 579 return -EINVAL;
570 580
571 npt = ip_nat_proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum); 581 npt = nf_nat_proto_find_get(ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum);
572 582
573 if (!npt->nfattr_to_range) { 583 if (!npt->nfattr_to_range) {
574 ip_nat_proto_put(npt); 584 nf_nat_proto_put(npt);
575 return 0; 585 return 0;
576 } 586 }
577 587
@@ -579,7 +589,7 @@ static int ctnetlink_parse_nat_proto(struct nfattr *attr,
579 if (npt->nfattr_to_range(tb, range) > 0) 589 if (npt->nfattr_to_range(tb, range) > 0)
580 range->flags |= IP_NAT_RANGE_PROTO_SPECIFIED; 590 range->flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
581 591
582 ip_nat_proto_put(npt); 592 nf_nat_proto_put(npt);
583 593
584 return 0; 594 return 0;
585} 595}
@@ -590,8 +600,8 @@ static const size_t cta_min_nat[CTA_NAT_MAX] = {
590}; 600};
591 601
592static inline int 602static inline int
593ctnetlink_parse_nat(struct nfattr *nat, 603nfnetlink_parse_nat(struct nfattr *nat,
594 const struct nf_conn *ct, struct ip_nat_range *range) 604 const struct nf_conn *ct, struct nf_nat_range *range)
595{ 605{
596 struct nfattr *tb[CTA_NAT_MAX]; 606 struct nfattr *tb[CTA_NAT_MAX];
597 int err; 607 int err;
@@ -604,12 +614,12 @@ ctnetlink_parse_nat(struct nfattr *nat,
604 return -EINVAL; 614 return -EINVAL;
605 615
606 if (tb[CTA_NAT_MINIP-1]) 616 if (tb[CTA_NAT_MINIP-1])
607 range->min_ip = *(u_int32_t *)NFA_DATA(tb[CTA_NAT_MINIP-1]); 617 range->min_ip = *(__be32 *)NFA_DATA(tb[CTA_NAT_MINIP-1]);
608 618
609 if (!tb[CTA_NAT_MAXIP-1]) 619 if (!tb[CTA_NAT_MAXIP-1])
610 range->max_ip = range->min_ip; 620 range->max_ip = range->min_ip;
611 else 621 else
612 range->max_ip = *(u_int32_t *)NFA_DATA(tb[CTA_NAT_MAXIP-1]); 622 range->max_ip = *(__be32 *)NFA_DATA(tb[CTA_NAT_MAXIP-1]);
613 623
614 if (range->min_ip) 624 if (range->min_ip)
615 range->flags |= IP_NAT_RANGE_MAP_IPS; 625 range->flags |= IP_NAT_RANGE_MAP_IPS;
@@ -617,7 +627,7 @@ ctnetlink_parse_nat(struct nfattr *nat,
617 if (!tb[CTA_NAT_PROTO-1]) 627 if (!tb[CTA_NAT_PROTO-1])
618 return 0; 628 return 0;
619 629
620 err = ctnetlink_parse_nat_proto(tb[CTA_NAT_PROTO-1], ct, range); 630 err = nfnetlink_parse_nat_proto(tb[CTA_NAT_PROTO-1], ct, range);
621 if (err < 0) 631 if (err < 0)
622 return err; 632 return err;
623 633
@@ -682,7 +692,7 @@ ctnetlink_del_conntrack(struct sock *ctnl, struct sk_buff *skb,
682 ct = nf_ct_tuplehash_to_ctrack(h); 692 ct = nf_ct_tuplehash_to_ctrack(h);
683 693
684 if (cda[CTA_ID-1]) { 694 if (cda[CTA_ID-1]) {
685 u_int32_t id = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_ID-1])); 695 u_int32_t id = ntohl(*(__be32 *)NFA_DATA(cda[CTA_ID-1]));
686 if (ct->id != id) { 696 if (ct->id != id) {
687 nf_ct_put(ct); 697 nf_ct_put(ct);
688 return -ENOENT; 698 return -ENOENT;
@@ -752,7 +762,6 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
752 nf_ct_put(ct); 762 nf_ct_put(ct);
753 return -ENOMEM; 763 return -ENOMEM;
754 } 764 }
755 NETLINK_CB(skb2).dst_pid = NETLINK_CB(skb).pid;
756 765
757 err = ctnetlink_fill_info(skb2, NETLINK_CB(skb).pid, nlh->nlmsg_seq, 766 err = ctnetlink_fill_info(skb2, NETLINK_CB(skb).pid, nlh->nlmsg_seq,
758 IPCTNL_MSG_CT_NEW, 1, ct); 767 IPCTNL_MSG_CT_NEW, 1, ct);
@@ -776,7 +785,7 @@ static inline int
776ctnetlink_change_status(struct nf_conn *ct, struct nfattr *cda[]) 785ctnetlink_change_status(struct nf_conn *ct, struct nfattr *cda[])
777{ 786{
778 unsigned long d; 787 unsigned long d;
779 unsigned status = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_STATUS-1])); 788 unsigned int status = ntohl(*(__be32 *)NFA_DATA(cda[CTA_STATUS-1]));
780 d = ct->status ^ status; 789 d = ct->status ^ status;
781 790
782 if (d & (IPS_EXPECTED|IPS_CONFIRMED|IPS_DYING)) 791 if (d & (IPS_EXPECTED|IPS_CONFIRMED|IPS_DYING))
@@ -793,35 +802,35 @@ ctnetlink_change_status(struct nf_conn *ct, struct nfattr *cda[])
793 return -EINVAL; 802 return -EINVAL;
794 803
795 if (cda[CTA_NAT_SRC-1] || cda[CTA_NAT_DST-1]) { 804 if (cda[CTA_NAT_SRC-1] || cda[CTA_NAT_DST-1]) {
796#ifndef CONFIG_IP_NF_NAT_NEEDED 805#ifndef CONFIG_NF_NAT_NEEDED
797 return -EINVAL; 806 return -EINVAL;
798#else 807#else
799 struct ip_nat_range range; 808 struct nf_nat_range range;
800 809
801 if (cda[CTA_NAT_DST-1]) { 810 if (cda[CTA_NAT_DST-1]) {
802 if (ctnetlink_parse_nat(cda[CTA_NAT_DST-1], ct, 811 if (nfnetlink_parse_nat(cda[CTA_NAT_DST-1], ct,
803 &range) < 0) 812 &range) < 0)
804 return -EINVAL; 813 return -EINVAL;
805 if (ip_nat_initialized(ct, 814 if (nf_nat_initialized(ct,
806 HOOK2MANIP(NF_IP_PRE_ROUTING))) 815 HOOK2MANIP(NF_IP_PRE_ROUTING)))
807 return -EEXIST; 816 return -EEXIST;
808 ip_nat_setup_info(ct, &range, hooknum); 817 nf_nat_setup_info(ct, &range, NF_IP_PRE_ROUTING);
809 } 818 }
810 if (cda[CTA_NAT_SRC-1]) { 819 if (cda[CTA_NAT_SRC-1]) {
811 if (ctnetlink_parse_nat(cda[CTA_NAT_SRC-1], ct, 820 if (nfnetlink_parse_nat(cda[CTA_NAT_SRC-1], ct,
812 &range) < 0) 821 &range) < 0)
813 return -EINVAL; 822 return -EINVAL;
814 if (ip_nat_initialized(ct, 823 if (nf_nat_initialized(ct,
815 HOOK2MANIP(NF_IP_POST_ROUTING))) 824 HOOK2MANIP(NF_IP_POST_ROUTING)))
816 return -EEXIST; 825 return -EEXIST;
817 ip_nat_setup_info(ct, &range, hooknum); 826 nf_nat_setup_info(ct, &range, NF_IP_POST_ROUTING);
818 } 827 }
819#endif 828#endif
820 } 829 }
821 830
822 /* Be careful here, modifying NAT bits can screw up things, 831 /* Be careful here, modifying NAT bits can screw up things,
823 * so don't let users modify them directly if they don't pass 832 * so don't let users modify them directly if they don't pass
824 * ip_nat_range. */ 833 * nf_nat_range. */
825 ct->status |= status & ~(IPS_NAT_DONE_MASK | IPS_NAT_MASK); 834 ct->status |= status & ~(IPS_NAT_DONE_MASK | IPS_NAT_MASK);
826 return 0; 835 return 0;
827} 836}
@@ -875,7 +884,7 @@ ctnetlink_change_helper(struct nf_conn *ct, struct nfattr *cda[])
875static inline int 884static inline int
876ctnetlink_change_timeout(struct nf_conn *ct, struct nfattr *cda[]) 885ctnetlink_change_timeout(struct nf_conn *ct, struct nfattr *cda[])
877{ 886{
878 u_int32_t timeout = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_TIMEOUT-1])); 887 u_int32_t timeout = ntohl(*(__be32 *)NFA_DATA(cda[CTA_TIMEOUT-1]));
879 888
880 if (!del_timer(&ct->timeout)) 889 if (!del_timer(&ct->timeout))
881 return -ETIME; 890 return -ETIME;
@@ -890,18 +899,18 @@ static inline int
890ctnetlink_change_protoinfo(struct nf_conn *ct, struct nfattr *cda[]) 899ctnetlink_change_protoinfo(struct nf_conn *ct, struct nfattr *cda[])
891{ 900{
892 struct nfattr *tb[CTA_PROTOINFO_MAX], *attr = cda[CTA_PROTOINFO-1]; 901 struct nfattr *tb[CTA_PROTOINFO_MAX], *attr = cda[CTA_PROTOINFO-1];
893 struct nf_conntrack_protocol *proto; 902 struct nf_conntrack_l4proto *l4proto;
894 u_int16_t npt = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum; 903 u_int16_t npt = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum;
895 u_int16_t l3num = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num; 904 u_int16_t l3num = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
896 int err = 0; 905 int err = 0;
897 906
898 nfattr_parse_nested(tb, CTA_PROTOINFO_MAX, attr); 907 nfattr_parse_nested(tb, CTA_PROTOINFO_MAX, attr);
899 908
900 proto = nf_ct_proto_find_get(l3num, npt); 909 l4proto = nf_ct_l4proto_find_get(l3num, npt);
901 910
902 if (proto->from_nfattr) 911 if (l4proto->from_nfattr)
903 err = proto->from_nfattr(tb, ct); 912 err = l4proto->from_nfattr(tb, ct);
904 nf_ct_proto_put(proto); 913 nf_ct_l4proto_put(l4proto);
905 914
906 return err; 915 return err;
907} 916}
@@ -937,7 +946,7 @@ ctnetlink_change_conntrack(struct nf_conn *ct, struct nfattr *cda[])
937 946
938#if defined(CONFIG_NF_CONNTRACK_MARK) 947#if defined(CONFIG_NF_CONNTRACK_MARK)
939 if (cda[CTA_MARK-1]) 948 if (cda[CTA_MARK-1])
940 ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1])); 949 ct->mark = ntohl(*(__be32 *)NFA_DATA(cda[CTA_MARK-1]));
941#endif 950#endif
942 951
943 return 0; 952 return 0;
@@ -958,14 +967,16 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
958 967
959 if (!cda[CTA_TIMEOUT-1]) 968 if (!cda[CTA_TIMEOUT-1])
960 goto err; 969 goto err;
961 ct->timeout.expires = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_TIMEOUT-1])); 970 ct->timeout.expires = ntohl(*(__be32 *)NFA_DATA(cda[CTA_TIMEOUT-1]));
962 971
963 ct->timeout.expires = jiffies + ct->timeout.expires * HZ; 972 ct->timeout.expires = jiffies + ct->timeout.expires * HZ;
964 ct->status |= IPS_CONFIRMED; 973 ct->status |= IPS_CONFIRMED;
965 974
966 err = ctnetlink_change_status(ct, cda); 975 if (cda[CTA_STATUS-1]) {
967 if (err < 0) 976 err = ctnetlink_change_status(ct, cda);
968 goto err; 977 if (err < 0)
978 goto err;
979 }
969 980
970 if (cda[CTA_PROTOINFO-1]) { 981 if (cda[CTA_PROTOINFO-1]) {
971 err = ctnetlink_change_protoinfo(ct, cda); 982 err = ctnetlink_change_protoinfo(ct, cda);
@@ -975,7 +986,7 @@ ctnetlink_create_conntrack(struct nfattr *cda[],
975 986
976#if defined(CONFIG_NF_CONNTRACK_MARK) 987#if defined(CONFIG_NF_CONNTRACK_MARK)
977 if (cda[CTA_MARK-1]) 988 if (cda[CTA_MARK-1])
978 ct->mark = ntohl(*(u_int32_t *)NFA_DATA(cda[CTA_MARK-1])); 989 ct->mark = ntohl(*(__be32 *)NFA_DATA(cda[CTA_MARK-1]));
979#endif 990#endif
980 991
981 help = nfct_help(ct); 992 help = nfct_help(ct);
@@ -1081,7 +1092,7 @@ ctnetlink_exp_dump_mask(struct sk_buff *skb,
1081{ 1092{
1082 int ret; 1093 int ret;
1083 struct nf_conntrack_l3proto *l3proto; 1094 struct nf_conntrack_l3proto *l3proto;
1084 struct nf_conntrack_protocol *proto; 1095 struct nf_conntrack_l4proto *l4proto;
1085 struct nfattr *nest_parms = NFA_NEST(skb, CTA_EXPECT_MASK); 1096 struct nfattr *nest_parms = NFA_NEST(skb, CTA_EXPECT_MASK);
1086 1097
1087 l3proto = nf_ct_l3proto_find_get(tuple->src.l3num); 1098 l3proto = nf_ct_l3proto_find_get(tuple->src.l3num);
@@ -1091,9 +1102,9 @@ ctnetlink_exp_dump_mask(struct sk_buff *skb,
1091 if (unlikely(ret < 0)) 1102 if (unlikely(ret < 0))
1092 goto nfattr_failure; 1103 goto nfattr_failure;
1093 1104
1094 proto = nf_ct_proto_find_get(tuple->src.l3num, tuple->dst.protonum); 1105 l4proto = nf_ct_l4proto_find_get(tuple->src.l3num, tuple->dst.protonum);
1095 ret = ctnetlink_dump_tuples_proto(skb, mask, proto); 1106 ret = ctnetlink_dump_tuples_proto(skb, mask, l4proto);
1096 nf_ct_proto_put(proto); 1107 nf_ct_l4proto_put(l4proto);
1097 if (unlikely(ret < 0)) 1108 if (unlikely(ret < 0))
1098 goto nfattr_failure; 1109 goto nfattr_failure;
1099 1110
@@ -1110,8 +1121,8 @@ ctnetlink_exp_dump_expect(struct sk_buff *skb,
1110 const struct nf_conntrack_expect *exp) 1121 const struct nf_conntrack_expect *exp)
1111{ 1122{
1112 struct nf_conn *master = exp->master; 1123 struct nf_conn *master = exp->master;
1113 u_int32_t timeout = htonl((exp->timeout.expires - jiffies) / HZ); 1124 __be32 timeout = htonl((exp->timeout.expires - jiffies) / HZ);
1114 u_int32_t id = htonl(exp->id); 1125 __be32 id = htonl(exp->id);
1115 1126
1116 if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0) 1127 if (ctnetlink_exp_dump_tuple(skb, &exp->tuple, CTA_EXPECT_TUPLE) < 0)
1117 goto nfattr_failure; 1128 goto nfattr_failure;
@@ -1284,12 +1295,12 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
1284 if (err < 0) 1295 if (err < 0)
1285 return err; 1296 return err;
1286 1297
1287 exp = nf_conntrack_expect_find(&tuple); 1298 exp = nf_conntrack_expect_find_get(&tuple);
1288 if (!exp) 1299 if (!exp)
1289 return -ENOENT; 1300 return -ENOENT;
1290 1301
1291 if (cda[CTA_EXPECT_ID-1]) { 1302 if (cda[CTA_EXPECT_ID-1]) {
1292 u_int32_t id = *(u_int32_t *)NFA_DATA(cda[CTA_EXPECT_ID-1]); 1303 __be32 id = *(__be32 *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
1293 if (exp->id != ntohl(id)) { 1304 if (exp->id != ntohl(id)) {
1294 nf_conntrack_expect_put(exp); 1305 nf_conntrack_expect_put(exp);
1295 return -ENOENT; 1306 return -ENOENT;
@@ -1300,8 +1311,7 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
1300 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 1311 skb2 = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
1301 if (!skb2) 1312 if (!skb2)
1302 goto out; 1313 goto out;
1303 NETLINK_CB(skb2).dst_pid = NETLINK_CB(skb).pid; 1314
1304
1305 err = ctnetlink_exp_fill_info(skb2, NETLINK_CB(skb).pid, 1315 err = ctnetlink_exp_fill_info(skb2, NETLINK_CB(skb).pid,
1306 nlh->nlmsg_seq, IPCTNL_MSG_EXP_NEW, 1316 nlh->nlmsg_seq, IPCTNL_MSG_EXP_NEW,
1307 1, exp); 1317 1, exp);
@@ -1340,13 +1350,12 @@ ctnetlink_del_expect(struct sock *ctnl, struct sk_buff *skb,
1340 return err; 1350 return err;
1341 1351
1342 /* bump usage count to 2 */ 1352 /* bump usage count to 2 */
1343 exp = nf_conntrack_expect_find(&tuple); 1353 exp = nf_conntrack_expect_find_get(&tuple);
1344 if (!exp) 1354 if (!exp)
1345 return -ENOENT; 1355 return -ENOENT;
1346 1356
1347 if (cda[CTA_EXPECT_ID-1]) { 1357 if (cda[CTA_EXPECT_ID-1]) {
1348 u_int32_t id = 1358 __be32 id = *(__be32 *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
1349 *(u_int32_t *)NFA_DATA(cda[CTA_EXPECT_ID-1]);
1350 if (exp->id != ntohl(id)) { 1359 if (exp->id != ntohl(id)) {
1351 nf_conntrack_expect_put(exp); 1360 nf_conntrack_expect_put(exp);
1352 return -ENOENT; 1361 return -ENOENT;
@@ -1442,6 +1451,7 @@ ctnetlink_create_expect(struct nfattr *cda[], u_int8_t u3)
1442 exp->expectfn = NULL; 1451 exp->expectfn = NULL;
1443 exp->flags = 0; 1452 exp->flags = 0;
1444 exp->master = ct; 1453 exp->master = ct;
1454 exp->helper = NULL;
1445 memcpy(&exp->tuple, &tuple, sizeof(struct nf_conntrack_tuple)); 1455 memcpy(&exp->tuple, &tuple, sizeof(struct nf_conntrack_tuple));
1446 memcpy(&exp->mask, &mask, sizeof(struct nf_conntrack_tuple)); 1456 memcpy(&exp->mask, &mask, sizeof(struct nf_conntrack_tuple));
1447 1457
@@ -1538,6 +1548,7 @@ static struct nfnetlink_subsystem ctnl_exp_subsys = {
1538 .cb = ctnl_exp_cb, 1548 .cb = ctnl_exp_cb,
1539}; 1549};
1540 1550
1551MODULE_ALIAS("ip_conntrack_netlink");
1541MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK); 1552MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK);
1542MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK_EXP); 1553MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK_EXP);
1543 1554
diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c
new file mode 100644
index 0000000000..f0ff00e0d0
--- /dev/null
+++ b/net/netfilter/nf_conntrack_pptp.c
@@ -0,0 +1,607 @@
1/*
2 * Connection tracking support for PPTP (Point to Point Tunneling Protocol).
3 * PPTP is a a protocol for creating virtual private networks.
4 * It is a specification defined by Microsoft and some vendors
5 * working with Microsoft. PPTP is built on top of a modified
6 * version of the Internet Generic Routing Encapsulation Protocol.
7 * GRE is defined in RFC 1701 and RFC 1702. Documentation of
8 * PPTP can be found in RFC 2637
9 *
10 * (C) 2000-2005 by Harald Welte <laforge@gnumonks.org>
11 *
12 * Development of this code funded by Astaro AG (http://www.astaro.com/)
13 *
14 * Limitations:
15 * - We blindly assume that control connections are always
16 * established in PNS->PAC direction. This is a violation
17 * of RFFC2673
18 * - We can only support one single call within each session
19 * TODO:
20 * - testing of incoming PPTP calls
21 */
22
23#include <linux/module.h>
24#include <linux/skbuff.h>
25#include <linux/in.h>
26#include <linux/tcp.h>
27
28#include <net/netfilter/nf_conntrack.h>
29#include <net/netfilter/nf_conntrack_core.h>
30#include <net/netfilter/nf_conntrack_helper.h>
31#include <linux/netfilter/nf_conntrack_proto_gre.h>
32#include <linux/netfilter/nf_conntrack_pptp.h>
33
34#define NF_CT_PPTP_VERSION "3.1"
35
36MODULE_LICENSE("GPL");
37MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");
38MODULE_DESCRIPTION("Netfilter connection tracking helper module for PPTP");
39MODULE_ALIAS("ip_conntrack_pptp");
40
41static DEFINE_SPINLOCK(nf_pptp_lock);
42
43int
44(*nf_nat_pptp_hook_outbound)(struct sk_buff **pskb,
45 struct nf_conn *ct, enum ip_conntrack_info ctinfo,
46 struct PptpControlHeader *ctlh,
47 union pptp_ctrl_union *pptpReq) __read_mostly;
48EXPORT_SYMBOL_GPL(nf_nat_pptp_hook_outbound);
49
50int
51(*nf_nat_pptp_hook_inbound)(struct sk_buff **pskb,
52 struct nf_conn *ct, enum ip_conntrack_info ctinfo,
53 struct PptpControlHeader *ctlh,
54 union pptp_ctrl_union *pptpReq) __read_mostly;
55EXPORT_SYMBOL_GPL(nf_nat_pptp_hook_inbound);
56
57void
58(*nf_nat_pptp_hook_exp_gre)(struct nf_conntrack_expect *expect_orig,
59 struct nf_conntrack_expect *expect_reply)
60 __read_mostly;
61EXPORT_SYMBOL_GPL(nf_nat_pptp_hook_exp_gre);
62
63void
64(*nf_nat_pptp_hook_expectfn)(struct nf_conn *ct,
65 struct nf_conntrack_expect *exp) __read_mostly;
66EXPORT_SYMBOL_GPL(nf_nat_pptp_hook_expectfn);
67
68#if 0
69/* PptpControlMessageType names */
70const char *pptp_msg_name[] = {
71 "UNKNOWN_MESSAGE",
72 "START_SESSION_REQUEST",
73 "START_SESSION_REPLY",
74 "STOP_SESSION_REQUEST",
75 "STOP_SESSION_REPLY",
76 "ECHO_REQUEST",
77 "ECHO_REPLY",
78 "OUT_CALL_REQUEST",
79 "OUT_CALL_REPLY",
80 "IN_CALL_REQUEST",
81 "IN_CALL_REPLY",
82 "IN_CALL_CONNECT",
83 "CALL_CLEAR_REQUEST",
84 "CALL_DISCONNECT_NOTIFY",
85 "WAN_ERROR_NOTIFY",
86 "SET_LINK_INFO"
87};
88EXPORT_SYMBOL(pptp_msg_name);
89#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s: " format, __FILE__, __FUNCTION__, ## args)
90#else
91#define DEBUGP(format, args...)
92#endif
93
94#define SECS *HZ
95#define MINS * 60 SECS
96#define HOURS * 60 MINS
97
98#define PPTP_GRE_TIMEOUT (10 MINS)
99#define PPTP_GRE_STREAM_TIMEOUT (5 HOURS)
100
101static void pptp_expectfn(struct nf_conn *ct,
102 struct nf_conntrack_expect *exp)
103{
104 typeof(nf_nat_pptp_hook_expectfn) nf_nat_pptp_expectfn;
105 DEBUGP("increasing timeouts\n");
106
107 /* increase timeout of GRE data channel conntrack entry */
108 ct->proto.gre.timeout = PPTP_GRE_TIMEOUT;
109 ct->proto.gre.stream_timeout = PPTP_GRE_STREAM_TIMEOUT;
110
111 /* Can you see how rusty this code is, compared with the pre-2.6.11
112 * one? That's what happened to my shiny newnat of 2002 ;( -HW */
113
114 rcu_read_lock();
115 nf_nat_pptp_expectfn = rcu_dereference(nf_nat_pptp_hook_expectfn);
116 if (nf_nat_pptp_expectfn && ct->status & IPS_NAT_MASK)
117 nf_nat_pptp_expectfn(ct, exp);
118 else {
119 struct nf_conntrack_tuple inv_t;
120 struct nf_conntrack_expect *exp_other;
121
122 /* obviously this tuple inversion only works until you do NAT */
123 nf_ct_invert_tuplepr(&inv_t, &exp->tuple);
124 DEBUGP("trying to unexpect other dir: ");
125 NF_CT_DUMP_TUPLE(&inv_t);
126
127 exp_other = nf_conntrack_expect_find_get(&inv_t);
128 if (exp_other) {
129 /* delete other expectation. */
130 DEBUGP("found\n");
131 nf_conntrack_unexpect_related(exp_other);
132 nf_conntrack_expect_put(exp_other);
133 } else {
134 DEBUGP("not found\n");
135 }
136 }
137 rcu_read_unlock();
138}
139
140static int destroy_sibling_or_exp(const struct nf_conntrack_tuple *t)
141{
142 struct nf_conntrack_tuple_hash *h;
143 struct nf_conntrack_expect *exp;
144 struct nf_conn *sibling;
145
146 DEBUGP("trying to timeout ct or exp for tuple ");
147 NF_CT_DUMP_TUPLE(t);
148
149 h = nf_conntrack_find_get(t, NULL);
150 if (h) {
151 sibling = nf_ct_tuplehash_to_ctrack(h);
152 DEBUGP("setting timeout of conntrack %p to 0\n", sibling);
153 sibling->proto.gre.timeout = 0;
154 sibling->proto.gre.stream_timeout = 0;
155 if (del_timer(&sibling->timeout))
156 sibling->timeout.function((unsigned long)sibling);
157 nf_ct_put(sibling);
158 return 1;
159 } else {
160 exp = nf_conntrack_expect_find_get(t);
161 if (exp) {
162 DEBUGP("unexpect_related of expect %p\n", exp);
163 nf_conntrack_unexpect_related(exp);
164 nf_conntrack_expect_put(exp);
165 return 1;
166 }
167 }
168 return 0;
169}
170
171/* timeout GRE data connections */
172static void pptp_destroy_siblings(struct nf_conn *ct)
173{
174 struct nf_conn_help *help = nfct_help(ct);
175 struct nf_conntrack_tuple t;
176
177 nf_ct_gre_keymap_destroy(ct);
178
179 /* try original (pns->pac) tuple */
180 memcpy(&t, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, sizeof(t));
181 t.dst.protonum = IPPROTO_GRE;
182 t.src.u.gre.key = help->help.ct_pptp_info.pns_call_id;
183 t.dst.u.gre.key = help->help.ct_pptp_info.pac_call_id;
184 if (!destroy_sibling_or_exp(&t))
185 DEBUGP("failed to timeout original pns->pac ct/exp\n");
186
187 /* try reply (pac->pns) tuple */
188 memcpy(&t, &ct->tuplehash[IP_CT_DIR_REPLY].tuple, sizeof(t));
189 t.dst.protonum = IPPROTO_GRE;
190 t.src.u.gre.key = help->help.ct_pptp_info.pac_call_id;
191 t.dst.u.gre.key = help->help.ct_pptp_info.pns_call_id;
192 if (!destroy_sibling_or_exp(&t))
193 DEBUGP("failed to timeout reply pac->pns ct/exp\n");
194}
195
196/* expect GRE connections (PNS->PAC and PAC->PNS direction) */
197static int exp_gre(struct nf_conn *ct, __be16 callid, __be16 peer_callid)
198{
199 struct nf_conntrack_expect *exp_orig, *exp_reply;
200 enum ip_conntrack_dir dir;
201 int ret = 1;
202 typeof(nf_nat_pptp_hook_exp_gre) nf_nat_pptp_exp_gre;
203
204 exp_orig = nf_conntrack_expect_alloc(ct);
205 if (exp_orig == NULL)
206 goto out;
207
208 exp_reply = nf_conntrack_expect_alloc(ct);
209 if (exp_reply == NULL)
210 goto out_put_orig;
211
212 /* original direction, PNS->PAC */
213 dir = IP_CT_DIR_ORIGINAL;
214 nf_conntrack_expect_init(exp_orig, ct->tuplehash[dir].tuple.src.l3num,
215 &ct->tuplehash[dir].tuple.src.u3,
216 &ct->tuplehash[dir].tuple.dst.u3,
217 IPPROTO_GRE, &peer_callid, &callid);
218 exp_orig->expectfn = pptp_expectfn;
219
220 /* reply direction, PAC->PNS */
221 dir = IP_CT_DIR_REPLY;
222 nf_conntrack_expect_init(exp_reply, ct->tuplehash[dir].tuple.src.l3num,
223 &ct->tuplehash[dir].tuple.src.u3,
224 &ct->tuplehash[dir].tuple.dst.u3,
225 IPPROTO_GRE, &callid, &peer_callid);
226 exp_reply->expectfn = pptp_expectfn;
227
228 nf_nat_pptp_exp_gre = rcu_dereference(nf_nat_pptp_hook_exp_gre);
229 if (nf_nat_pptp_exp_gre && ct->status & IPS_NAT_MASK)
230 nf_nat_pptp_exp_gre(exp_orig, exp_reply);
231 if (nf_conntrack_expect_related(exp_orig) != 0)
232 goto out_put_both;
233 if (nf_conntrack_expect_related(exp_reply) != 0)
234 goto out_unexpect_orig;
235
236 /* Add GRE keymap entries */
237 if (nf_ct_gre_keymap_add(ct, IP_CT_DIR_ORIGINAL, &exp_orig->tuple) != 0)
238 goto out_unexpect_both;
239 if (nf_ct_gre_keymap_add(ct, IP_CT_DIR_REPLY, &exp_reply->tuple) != 0) {
240 nf_ct_gre_keymap_destroy(ct);
241 goto out_unexpect_both;
242 }
243 ret = 0;
244
245out_put_both:
246 nf_conntrack_expect_put(exp_reply);
247out_put_orig:
248 nf_conntrack_expect_put(exp_orig);
249out:
250 return ret;
251
252out_unexpect_both:
253 nf_conntrack_unexpect_related(exp_reply);
254out_unexpect_orig:
255 nf_conntrack_unexpect_related(exp_orig);
256 goto out_put_both;
257}
258
259static inline int
260pptp_inbound_pkt(struct sk_buff **pskb,
261 struct PptpControlHeader *ctlh,
262 union pptp_ctrl_union *pptpReq,
263 unsigned int reqlen,
264 struct nf_conn *ct,
265 enum ip_conntrack_info ctinfo)
266{
267 struct nf_ct_pptp_master *info = &nfct_help(ct)->help.ct_pptp_info;
268 u_int16_t msg;
269 __be16 cid = 0, pcid = 0;
270 typeof(nf_nat_pptp_hook_inbound) nf_nat_pptp_inbound;
271
272 msg = ntohs(ctlh->messageType);
273 DEBUGP("inbound control message %s\n", pptp_msg_name[msg]);
274
275 switch (msg) {
276 case PPTP_START_SESSION_REPLY:
277 /* server confirms new control session */
278 if (info->sstate < PPTP_SESSION_REQUESTED)
279 goto invalid;
280 if (pptpReq->srep.resultCode == PPTP_START_OK)
281 info->sstate = PPTP_SESSION_CONFIRMED;
282 else
283 info->sstate = PPTP_SESSION_ERROR;
284 break;
285
286 case PPTP_STOP_SESSION_REPLY:
287 /* server confirms end of control session */
288 if (info->sstate > PPTP_SESSION_STOPREQ)
289 goto invalid;
290 if (pptpReq->strep.resultCode == PPTP_STOP_OK)
291 info->sstate = PPTP_SESSION_NONE;
292 else
293 info->sstate = PPTP_SESSION_ERROR;
294 break;
295
296 case PPTP_OUT_CALL_REPLY:
297 /* server accepted call, we now expect GRE frames */
298 if (info->sstate != PPTP_SESSION_CONFIRMED)
299 goto invalid;
300 if (info->cstate != PPTP_CALL_OUT_REQ &&
301 info->cstate != PPTP_CALL_OUT_CONF)
302 goto invalid;
303
304 cid = pptpReq->ocack.callID;
305 pcid = pptpReq->ocack.peersCallID;
306 if (info->pns_call_id != pcid)
307 goto invalid;
308 DEBUGP("%s, CID=%X, PCID=%X\n", pptp_msg_name[msg],
309 ntohs(cid), ntohs(pcid));
310
311 if (pptpReq->ocack.resultCode == PPTP_OUTCALL_CONNECT) {
312 info->cstate = PPTP_CALL_OUT_CONF;
313 info->pac_call_id = cid;
314 exp_gre(ct, cid, pcid);
315 } else
316 info->cstate = PPTP_CALL_NONE;
317 break;
318
319 case PPTP_IN_CALL_REQUEST:
320 /* server tells us about incoming call request */
321 if (info->sstate != PPTP_SESSION_CONFIRMED)
322 goto invalid;
323
324 cid = pptpReq->icreq.callID;
325 DEBUGP("%s, CID=%X\n", pptp_msg_name[msg], ntohs(cid));
326 info->cstate = PPTP_CALL_IN_REQ;
327 info->pac_call_id = cid;
328 break;
329
330 case PPTP_IN_CALL_CONNECT:
331 /* server tells us about incoming call established */
332 if (info->sstate != PPTP_SESSION_CONFIRMED)
333 goto invalid;
334 if (info->cstate != PPTP_CALL_IN_REP &&
335 info->cstate != PPTP_CALL_IN_CONF)
336 goto invalid;
337
338 pcid = pptpReq->iccon.peersCallID;
339 cid = info->pac_call_id;
340
341 if (info->pns_call_id != pcid)
342 goto invalid;
343
344 DEBUGP("%s, PCID=%X\n", pptp_msg_name[msg], ntohs(pcid));
345 info->cstate = PPTP_CALL_IN_CONF;
346
347 /* we expect a GRE connection from PAC to PNS */
348 exp_gre(ct, cid, pcid);
349 break;
350
351 case PPTP_CALL_DISCONNECT_NOTIFY:
352 /* server confirms disconnect */
353 cid = pptpReq->disc.callID;
354 DEBUGP("%s, CID=%X\n", pptp_msg_name[msg], ntohs(cid));
355 info->cstate = PPTP_CALL_NONE;
356
357 /* untrack this call id, unexpect GRE packets */
358 pptp_destroy_siblings(ct);
359 break;
360
361 case PPTP_WAN_ERROR_NOTIFY:
362 case PPTP_ECHO_REQUEST:
363 case PPTP_ECHO_REPLY:
364 /* I don't have to explain these ;) */
365 break;
366
367 default:
368 goto invalid;
369 }
370
371 nf_nat_pptp_inbound = rcu_dereference(nf_nat_pptp_hook_inbound);
372 if (nf_nat_pptp_inbound && ct->status & IPS_NAT_MASK)
373 return nf_nat_pptp_inbound(pskb, ct, ctinfo, ctlh, pptpReq);
374 return NF_ACCEPT;
375
376invalid:
377 DEBUGP("invalid %s: type=%d cid=%u pcid=%u "
378 "cstate=%d sstate=%d pns_cid=%u pac_cid=%u\n",
379 msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] : pptp_msg_name[0],
380 msg, ntohs(cid), ntohs(pcid), info->cstate, info->sstate,
381 ntohs(info->pns_call_id), ntohs(info->pac_call_id));
382 return NF_ACCEPT;
383}
384
385static inline int
386pptp_outbound_pkt(struct sk_buff **pskb,
387 struct PptpControlHeader *ctlh,
388 union pptp_ctrl_union *pptpReq,
389 unsigned int reqlen,
390 struct nf_conn *ct,
391 enum ip_conntrack_info ctinfo)
392{
393 struct nf_ct_pptp_master *info = &nfct_help(ct)->help.ct_pptp_info;
394 u_int16_t msg;
395 __be16 cid = 0, pcid = 0;
396 typeof(nf_nat_pptp_hook_outbound) nf_nat_pptp_outbound;
397
398 msg = ntohs(ctlh->messageType);
399 DEBUGP("outbound control message %s\n", pptp_msg_name[msg]);
400
401 switch (msg) {
402 case PPTP_START_SESSION_REQUEST:
403 /* client requests for new control session */
404 if (info->sstate != PPTP_SESSION_NONE)
405 goto invalid;
406 info->sstate = PPTP_SESSION_REQUESTED;
407 break;
408
409 case PPTP_STOP_SESSION_REQUEST:
410 /* client requests end of control session */
411 info->sstate = PPTP_SESSION_STOPREQ;
412 break;
413
414 case PPTP_OUT_CALL_REQUEST:
415 /* client initiating connection to server */
416 if (info->sstate != PPTP_SESSION_CONFIRMED)
417 goto invalid;
418 info->cstate = PPTP_CALL_OUT_REQ;
419 /* track PNS call id */
420 cid = pptpReq->ocreq.callID;
421 DEBUGP("%s, CID=%X\n", pptp_msg_name[msg], ntohs(cid));
422 info->pns_call_id = cid;
423 break;
424
425 case PPTP_IN_CALL_REPLY:
426 /* client answers incoming call */
427 if (info->cstate != PPTP_CALL_IN_REQ &&
428 info->cstate != PPTP_CALL_IN_REP)
429 goto invalid;
430
431 cid = pptpReq->icack.callID;
432 pcid = pptpReq->icack.peersCallID;
433 if (info->pac_call_id != pcid)
434 goto invalid;
435 DEBUGP("%s, CID=%X PCID=%X\n", pptp_msg_name[msg],
436 ntohs(cid), ntohs(pcid));
437
438 if (pptpReq->icack.resultCode == PPTP_INCALL_ACCEPT) {
439 /* part two of the three-way handshake */
440 info->cstate = PPTP_CALL_IN_REP;
441 info->pns_call_id = cid;
442 } else
443 info->cstate = PPTP_CALL_NONE;
444 break;
445
446 case PPTP_CALL_CLEAR_REQUEST:
447 /* client requests hangup of call */
448 if (info->sstate != PPTP_SESSION_CONFIRMED)
449 goto invalid;
450 /* FUTURE: iterate over all calls and check if
451 * call ID is valid. We don't do this without newnat,
452 * because we only know about last call */
453 info->cstate = PPTP_CALL_CLEAR_REQ;
454 break;
455
456 case PPTP_SET_LINK_INFO:
457 case PPTP_ECHO_REQUEST:
458 case PPTP_ECHO_REPLY:
459 /* I don't have to explain these ;) */
460 break;
461
462 default:
463 goto invalid;
464 }
465
466 nf_nat_pptp_outbound = rcu_dereference(nf_nat_pptp_hook_outbound);
467 if (nf_nat_pptp_outbound && ct->status & IPS_NAT_MASK)
468 return nf_nat_pptp_outbound(pskb, ct, ctinfo, ctlh, pptpReq);
469 return NF_ACCEPT;
470
471invalid:
472 DEBUGP("invalid %s: type=%d cid=%u pcid=%u "
473 "cstate=%d sstate=%d pns_cid=%u pac_cid=%u\n",
474 msg <= PPTP_MSG_MAX ? pptp_msg_name[msg] : pptp_msg_name[0],
475 msg, ntohs(cid), ntohs(pcid), info->cstate, info->sstate,
476 ntohs(info->pns_call_id), ntohs(info->pac_call_id));
477 return NF_ACCEPT;
478}
479
480static const unsigned int pptp_msg_size[] = {
481 [PPTP_START_SESSION_REQUEST] = sizeof(struct PptpStartSessionRequest),
482 [PPTP_START_SESSION_REPLY] = sizeof(struct PptpStartSessionReply),
483 [PPTP_STOP_SESSION_REQUEST] = sizeof(struct PptpStopSessionRequest),
484 [PPTP_STOP_SESSION_REPLY] = sizeof(struct PptpStopSessionReply),
485 [PPTP_OUT_CALL_REQUEST] = sizeof(struct PptpOutCallRequest),
486 [PPTP_OUT_CALL_REPLY] = sizeof(struct PptpOutCallReply),
487 [PPTP_IN_CALL_REQUEST] = sizeof(struct PptpInCallRequest),
488 [PPTP_IN_CALL_REPLY] = sizeof(struct PptpInCallReply),
489 [PPTP_IN_CALL_CONNECT] = sizeof(struct PptpInCallConnected),
490 [PPTP_CALL_CLEAR_REQUEST] = sizeof(struct PptpClearCallRequest),
491 [PPTP_CALL_DISCONNECT_NOTIFY] = sizeof(struct PptpCallDisconnectNotify),
492 [PPTP_WAN_ERROR_NOTIFY] = sizeof(struct PptpWanErrorNotify),
493 [PPTP_SET_LINK_INFO] = sizeof(struct PptpSetLinkInfo),
494};
495
496/* track caller id inside control connection, call expect_related */
497static int
498conntrack_pptp_help(struct sk_buff **pskb, unsigned int protoff,
499 struct nf_conn *ct, enum ip_conntrack_info ctinfo)
500
501{
502 int dir = CTINFO2DIR(ctinfo);
503 struct nf_ct_pptp_master *info = &nfct_help(ct)->help.ct_pptp_info;
504 struct tcphdr _tcph, *tcph;
505 struct pptp_pkt_hdr _pptph, *pptph;
506 struct PptpControlHeader _ctlh, *ctlh;
507 union pptp_ctrl_union _pptpReq, *pptpReq;
508 unsigned int tcplen = (*pskb)->len - protoff;
509 unsigned int datalen, reqlen, nexthdr_off;
510 int oldsstate, oldcstate;
511 int ret;
512 u_int16_t msg;
513
514 /* don't do any tracking before tcp handshake complete */
515 if (ctinfo != IP_CT_ESTABLISHED &&
516 ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY)
517 return NF_ACCEPT;
518
519 nexthdr_off = protoff;
520 tcph = skb_header_pointer(*pskb, nexthdr_off, sizeof(_tcph), &_tcph);
521 BUG_ON(!tcph);
522 nexthdr_off += tcph->doff * 4;
523 datalen = tcplen - tcph->doff * 4;
524
525 pptph = skb_header_pointer(*pskb, nexthdr_off, sizeof(_pptph), &_pptph);
526 if (!pptph) {
527 DEBUGP("no full PPTP header, can't track\n");
528 return NF_ACCEPT;
529 }
530 nexthdr_off += sizeof(_pptph);
531 datalen -= sizeof(_pptph);
532
533 /* if it's not a control message we can't do anything with it */
534 if (ntohs(pptph->packetType) != PPTP_PACKET_CONTROL ||
535 ntohl(pptph->magicCookie) != PPTP_MAGIC_COOKIE) {
536 DEBUGP("not a control packet\n");
537 return NF_ACCEPT;
538 }
539
540 ctlh = skb_header_pointer(*pskb, nexthdr_off, sizeof(_ctlh), &_ctlh);
541 if (!ctlh)
542 return NF_ACCEPT;
543 nexthdr_off += sizeof(_ctlh);
544 datalen -= sizeof(_ctlh);
545
546 reqlen = datalen;
547 msg = ntohs(ctlh->messageType);
548 if (msg > 0 && msg <= PPTP_MSG_MAX && reqlen < pptp_msg_size[msg])
549 return NF_ACCEPT;
550 if (reqlen > sizeof(*pptpReq))
551 reqlen = sizeof(*pptpReq);
552
553 pptpReq = skb_header_pointer(*pskb, nexthdr_off, reqlen, &_pptpReq);
554 if (!pptpReq)
555 return NF_ACCEPT;
556
557 oldsstate = info->sstate;
558 oldcstate = info->cstate;
559
560 spin_lock_bh(&nf_pptp_lock);
561
562 /* FIXME: We just blindly assume that the control connection is always
563 * established from PNS->PAC. However, RFC makes no guarantee */
564 if (dir == IP_CT_DIR_ORIGINAL)
565 /* client -> server (PNS -> PAC) */
566 ret = pptp_outbound_pkt(pskb, ctlh, pptpReq, reqlen, ct,
567 ctinfo);
568 else
569 /* server -> client (PAC -> PNS) */
570 ret = pptp_inbound_pkt(pskb, ctlh, pptpReq, reqlen, ct,
571 ctinfo);
572 DEBUGP("sstate: %d->%d, cstate: %d->%d\n",
573 oldsstate, info->sstate, oldcstate, info->cstate);
574 spin_unlock_bh(&nf_pptp_lock);
575
576 return ret;
577}
578
579/* control protocol helper */
580static struct nf_conntrack_helper pptp __read_mostly = {
581 .name = "pptp",
582 .me = THIS_MODULE,
583 .max_expected = 2,
584 .timeout = 5 * 60,
585 .tuple.src.l3num = AF_INET,
586 .tuple.src.u.tcp.port = __constant_htons(PPTP_CONTROL_PORT),
587 .tuple.dst.protonum = IPPROTO_TCP,
588 .mask.src.l3num = 0xffff,
589 .mask.src.u.tcp.port = __constant_htons(0xffff),
590 .mask.dst.protonum = 0xff,
591 .help = conntrack_pptp_help,
592 .destroy = pptp_destroy_siblings,
593};
594
595static int __init nf_conntrack_pptp_init(void)
596{
597 return nf_conntrack_helper_register(&pptp);
598}
599
600static void __exit nf_conntrack_pptp_fini(void)
601{
602 nf_conntrack_helper_unregister(&pptp);
603 nf_ct_gre_keymap_flush();
604}
605
606module_init(nf_conntrack_pptp_init);
607module_exit(nf_conntrack_pptp_fini);
diff --git a/net/netfilter/nf_conntrack_proto.c b/net/netfilter/nf_conntrack_proto.c
new file mode 100644
index 0000000000..1a61b72712
--- /dev/null
+++ b/net/netfilter/nf_conntrack_proto.c
@@ -0,0 +1,410 @@
1/* L3/L4 protocol support for nf_conntrack. */
2
3/* (C) 1999-2001 Paul `Rusty' Russell
4 * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
5 * (C) 2003,2004 USAGI/WIDE Project <http://www.linux-ipv6.org>
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#include <linux/types.h>
13#include <linux/netfilter.h>
14#include <linux/module.h>
15#include <linux/mutex.h>
16#include <linux/skbuff.h>
17#include <linux/vmalloc.h>
18#include <linux/stddef.h>
19#include <linux/err.h>
20#include <linux/percpu.h>
21#include <linux/moduleparam.h>
22#include <linux/notifier.h>
23#include <linux/kernel.h>
24#include <linux/netdevice.h>
25
26#include <net/netfilter/nf_conntrack.h>
27#include <net/netfilter/nf_conntrack_l3proto.h>
28#include <net/netfilter/nf_conntrack_l4proto.h>
29#include <net/netfilter/nf_conntrack_core.h>
30
31struct nf_conntrack_l4proto **nf_ct_protos[PF_MAX] __read_mostly;
32struct nf_conntrack_l3proto *nf_ct_l3protos[AF_MAX] __read_mostly;
33EXPORT_SYMBOL_GPL(nf_ct_l3protos);
34
35#ifdef CONFIG_SYSCTL
36static DEFINE_MUTEX(nf_ct_proto_sysctl_mutex);
37
38static int
39nf_ct_register_sysctl(struct ctl_table_header **header, struct ctl_table *path,
40 struct ctl_table *table, unsigned int *users)
41{
42 if (*header == NULL) {
43 *header = nf_register_sysctl_table(path, table);
44 if (*header == NULL)
45 return -ENOMEM;
46 }
47 if (users != NULL)
48 (*users)++;
49 return 0;
50}
51
52static void
53nf_ct_unregister_sysctl(struct ctl_table_header **header,
54 struct ctl_table *table, unsigned int *users)
55{
56 if (users != NULL && --*users > 0)
57 return;
58 nf_unregister_sysctl_table(*header, table);
59 *header = NULL;
60}
61#endif
62
63struct nf_conntrack_l4proto *
64__nf_ct_l4proto_find(u_int16_t l3proto, u_int8_t l4proto)
65{
66 if (unlikely(l3proto >= AF_MAX || nf_ct_protos[l3proto] == NULL))
67 return &nf_conntrack_l4proto_generic;
68
69 return nf_ct_protos[l3proto][l4proto];
70}
71EXPORT_SYMBOL_GPL(__nf_ct_l4proto_find);
72
73/* this is guaranteed to always return a valid protocol helper, since
74 * it falls back to generic_protocol */
75struct nf_conntrack_l4proto *
76nf_ct_l4proto_find_get(u_int16_t l3proto, u_int8_t l4proto)
77{
78 struct nf_conntrack_l4proto *p;
79
80 preempt_disable();
81 p = __nf_ct_l4proto_find(l3proto, l4proto);
82 if (!try_module_get(p->me))
83 p = &nf_conntrack_l4proto_generic;
84 preempt_enable();
85
86 return p;
87}
88EXPORT_SYMBOL_GPL(nf_ct_l4proto_find_get);
89
90void nf_ct_l4proto_put(struct nf_conntrack_l4proto *p)
91{
92 module_put(p->me);
93}
94EXPORT_SYMBOL_GPL(nf_ct_l4proto_put);
95
96struct nf_conntrack_l3proto *
97nf_ct_l3proto_find_get(u_int16_t l3proto)
98{
99 struct nf_conntrack_l3proto *p;
100
101 preempt_disable();
102 p = __nf_ct_l3proto_find(l3proto);
103 if (!try_module_get(p->me))
104 p = &nf_conntrack_l3proto_generic;
105 preempt_enable();
106
107 return p;
108}
109EXPORT_SYMBOL_GPL(nf_ct_l3proto_find_get);
110
111void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p)
112{
113 module_put(p->me);
114}
115EXPORT_SYMBOL_GPL(nf_ct_l3proto_put);
116
117int
118nf_ct_l3proto_try_module_get(unsigned short l3proto)
119{
120 int ret;
121 struct nf_conntrack_l3proto *p;
122
123retry: p = nf_ct_l3proto_find_get(l3proto);
124 if (p == &nf_conntrack_l3proto_generic) {
125 ret = request_module("nf_conntrack-%d", l3proto);
126 if (!ret)
127 goto retry;
128
129 return -EPROTOTYPE;
130 }
131
132 return 0;
133}
134EXPORT_SYMBOL_GPL(nf_ct_l3proto_try_module_get);
135
136void nf_ct_l3proto_module_put(unsigned short l3proto)
137{
138 struct nf_conntrack_l3proto *p;
139
140 preempt_disable();
141 p = __nf_ct_l3proto_find(l3proto);
142 preempt_enable();
143
144 module_put(p->me);
145}
146EXPORT_SYMBOL_GPL(nf_ct_l3proto_module_put);
147
148static int kill_l3proto(struct nf_conn *i, void *data)
149{
150 return (i->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num ==
151 ((struct nf_conntrack_l3proto *)data)->l3proto);
152}
153
154static int kill_l4proto(struct nf_conn *i, void *data)
155{
156 struct nf_conntrack_l4proto *l4proto;
157 l4proto = (struct nf_conntrack_l4proto *)data;
158 return (i->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum ==
159 l4proto->l4proto) &&
160 (i->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num ==
161 l4proto->l3proto);
162}
163
164static int nf_ct_l3proto_register_sysctl(struct nf_conntrack_l3proto *l3proto)
165{
166 int err = 0;
167
168#ifdef CONFIG_SYSCTL
169 mutex_lock(&nf_ct_proto_sysctl_mutex);
170 if (l3proto->ctl_table != NULL) {
171 err = nf_ct_register_sysctl(&l3proto->ctl_table_header,
172 l3proto->ctl_table_path,
173 l3proto->ctl_table, NULL);
174 }
175 mutex_unlock(&nf_ct_proto_sysctl_mutex);
176#endif
177 return err;
178}
179
180static void nf_ct_l3proto_unregister_sysctl(struct nf_conntrack_l3proto *l3proto)
181{
182#ifdef CONFIG_SYSCTL
183 mutex_lock(&nf_ct_proto_sysctl_mutex);
184 if (l3proto->ctl_table_header != NULL)
185 nf_ct_unregister_sysctl(&l3proto->ctl_table_header,
186 l3proto->ctl_table, NULL);
187 mutex_unlock(&nf_ct_proto_sysctl_mutex);
188#endif
189}
190
191int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto)
192{
193 int ret = 0;
194
195 if (proto->l3proto >= AF_MAX) {
196 ret = -EBUSY;
197 goto out;
198 }
199
200 write_lock_bh(&nf_conntrack_lock);
201 if (nf_ct_l3protos[proto->l3proto] != &nf_conntrack_l3proto_generic) {
202 ret = -EBUSY;
203 goto out_unlock;
204 }
205 nf_ct_l3protos[proto->l3proto] = proto;
206 write_unlock_bh(&nf_conntrack_lock);
207
208 ret = nf_ct_l3proto_register_sysctl(proto);
209 if (ret < 0)
210 nf_conntrack_l3proto_unregister(proto);
211 return ret;
212
213out_unlock:
214 write_unlock_bh(&nf_conntrack_lock);
215out:
216 return ret;
217}
218EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_register);
219
220int nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto)
221{
222 int ret = 0;
223
224 if (proto->l3proto >= AF_MAX) {
225 ret = -EBUSY;
226 goto out;
227 }
228
229 write_lock_bh(&nf_conntrack_lock);
230 if (nf_ct_l3protos[proto->l3proto] != proto) {
231 write_unlock_bh(&nf_conntrack_lock);
232 ret = -EBUSY;
233 goto out;
234 }
235
236 nf_ct_l3protos[proto->l3proto] = &nf_conntrack_l3proto_generic;
237 write_unlock_bh(&nf_conntrack_lock);
238
239 nf_ct_l3proto_unregister_sysctl(proto);
240
241 /* Somebody could be still looking at the proto in bh. */
242 synchronize_net();
243
244 /* Remove all contrack entries for this protocol */
245 nf_ct_iterate_cleanup(kill_l3proto, proto);
246
247out:
248 return ret;
249}
250EXPORT_SYMBOL_GPL(nf_conntrack_l3proto_unregister);
251
252static int nf_ct_l4proto_register_sysctl(struct nf_conntrack_l4proto *l4proto)
253{
254 int err = 0;
255
256#ifdef CONFIG_SYSCTL
257 mutex_lock(&nf_ct_proto_sysctl_mutex);
258 if (l4proto->ctl_table != NULL) {
259 err = nf_ct_register_sysctl(l4proto->ctl_table_header,
260 nf_net_netfilter_sysctl_path,
261 l4proto->ctl_table,
262 l4proto->ctl_table_users);
263 if (err < 0)
264 goto out;
265 }
266#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
267 if (l4proto->ctl_compat_table != NULL) {
268 err = nf_ct_register_sysctl(&l4proto->ctl_compat_table_header,
269 nf_net_ipv4_netfilter_sysctl_path,
270 l4proto->ctl_compat_table, NULL);
271 if (err == 0)
272 goto out;
273 nf_ct_unregister_sysctl(l4proto->ctl_table_header,
274 l4proto->ctl_table,
275 l4proto->ctl_table_users);
276 }
277#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
278out:
279 mutex_unlock(&nf_ct_proto_sysctl_mutex);
280#endif /* CONFIG_SYSCTL */
281 return err;
282}
283
284static void nf_ct_l4proto_unregister_sysctl(struct nf_conntrack_l4proto *l4proto)
285{
286#ifdef CONFIG_SYSCTL
287 mutex_lock(&nf_ct_proto_sysctl_mutex);
288 if (l4proto->ctl_table_header != NULL &&
289 *l4proto->ctl_table_header != NULL)
290 nf_ct_unregister_sysctl(l4proto->ctl_table_header,
291 l4proto->ctl_table,
292 l4proto->ctl_table_users);
293#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
294 if (l4proto->ctl_compat_table_header != NULL)
295 nf_ct_unregister_sysctl(&l4proto->ctl_compat_table_header,
296 l4proto->ctl_compat_table, NULL);
297#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
298 mutex_unlock(&nf_ct_proto_sysctl_mutex);
299#endif /* CONFIG_SYSCTL */
300}
301
302/* FIXME: Allow NULL functions and sub in pointers to generic for
303 them. --RR */
304int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *l4proto)
305{
306 int ret = 0;
307
308 if (l4proto->l3proto >= PF_MAX) {
309 ret = -EBUSY;
310 goto out;
311 }
312
313 if (l4proto == &nf_conntrack_l4proto_generic)
314 return nf_ct_l4proto_register_sysctl(l4proto);
315
316retry:
317 write_lock_bh(&nf_conntrack_lock);
318 if (nf_ct_protos[l4proto->l3proto]) {
319 if (nf_ct_protos[l4proto->l3proto][l4proto->l4proto]
320 != &nf_conntrack_l4proto_generic) {
321 ret = -EBUSY;
322 goto out_unlock;
323 }
324 } else {
325 /* l3proto may be loaded latter. */
326 struct nf_conntrack_l4proto **proto_array;
327 int i;
328
329 write_unlock_bh(&nf_conntrack_lock);
330
331 proto_array = (struct nf_conntrack_l4proto **)
332 kmalloc(MAX_NF_CT_PROTO *
333 sizeof(struct nf_conntrack_l4proto *),
334 GFP_KERNEL);
335 if (proto_array == NULL) {
336 ret = -ENOMEM;
337 goto out;
338 }
339 for (i = 0; i < MAX_NF_CT_PROTO; i++)
340 proto_array[i] = &nf_conntrack_l4proto_generic;
341
342 write_lock_bh(&nf_conntrack_lock);
343 if (nf_ct_protos[l4proto->l3proto]) {
344 /* bad timing, but no problem */
345 write_unlock_bh(&nf_conntrack_lock);
346 kfree(proto_array);
347 } else {
348 nf_ct_protos[l4proto->l3proto] = proto_array;
349 write_unlock_bh(&nf_conntrack_lock);
350 }
351
352 /*
353 * Just once because array is never freed until unloading
354 * nf_conntrack.ko
355 */
356 goto retry;
357 }
358
359 nf_ct_protos[l4proto->l3proto][l4proto->l4proto] = l4proto;
360 write_unlock_bh(&nf_conntrack_lock);
361
362 ret = nf_ct_l4proto_register_sysctl(l4proto);
363 if (ret < 0)
364 nf_conntrack_l4proto_unregister(l4proto);
365 return ret;
366
367out_unlock:
368 write_unlock_bh(&nf_conntrack_lock);
369out:
370 return ret;
371}
372EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_register);
373
374int nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *l4proto)
375{
376 int ret = 0;
377
378 if (l4proto->l3proto >= PF_MAX) {
379 ret = -EBUSY;
380 goto out;
381 }
382
383 if (l4proto == &nf_conntrack_l4proto_generic) {
384 nf_ct_l4proto_unregister_sysctl(l4proto);
385 goto out;
386 }
387
388 write_lock_bh(&nf_conntrack_lock);
389 if (nf_ct_protos[l4proto->l3proto][l4proto->l4proto]
390 != l4proto) {
391 write_unlock_bh(&nf_conntrack_lock);
392 ret = -EBUSY;
393 goto out;
394 }
395 nf_ct_protos[l4proto->l3proto][l4proto->l4proto]
396 = &nf_conntrack_l4proto_generic;
397 write_unlock_bh(&nf_conntrack_lock);
398
399 nf_ct_l4proto_unregister_sysctl(l4proto);
400
401 /* Somebody could be still looking at the proto in bh. */
402 synchronize_net();
403
404 /* Remove all contrack entries for this protocol */
405 nf_ct_iterate_cleanup(kill_l4proto, l4proto);
406
407out:
408 return ret;
409}
410EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_unregister);
diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c
index 26408bb095..69902531c2 100644
--- a/net/netfilter/nf_conntrack_proto_generic.c
+++ b/net/netfilter/nf_conntrack_proto_generic.c
@@ -15,9 +15,9 @@
15#include <linux/sched.h> 15#include <linux/sched.h>
16#include <linux/timer.h> 16#include <linux/timer.h>
17#include <linux/netfilter.h> 17#include <linux/netfilter.h>
18#include <net/netfilter/nf_conntrack_protocol.h> 18#include <net/netfilter/nf_conntrack_l4proto.h>
19 19
20unsigned int nf_ct_generic_timeout __read_mostly = 600*HZ; 20static unsigned int nf_ct_generic_timeout __read_mostly = 600*HZ;
21 21
22static int generic_pkt_to_tuple(const struct sk_buff *skb, 22static int generic_pkt_to_tuple(const struct sk_buff *skb,
23 unsigned int dataoff, 23 unsigned int dataoff,
@@ -71,10 +71,42 @@ static int new(struct nf_conn *conntrack, const struct sk_buff *skb,
71 return 1; 71 return 1;
72} 72}
73 73
74struct nf_conntrack_protocol nf_conntrack_generic_protocol = 74#ifdef CONFIG_SYSCTL
75static struct ctl_table_header *generic_sysctl_header;
76static struct ctl_table generic_sysctl_table[] = {
77 {
78 .ctl_name = NET_NF_CONNTRACK_GENERIC_TIMEOUT,
79 .procname = "nf_conntrack_generic_timeout",
80 .data = &nf_ct_generic_timeout,
81 .maxlen = sizeof(unsigned int),
82 .mode = 0644,
83 .proc_handler = &proc_dointvec_jiffies,
84 },
85 {
86 .ctl_name = 0
87 }
88};
89#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
90static struct ctl_table generic_compat_sysctl_table[] = {
91 {
92 .ctl_name = NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT,
93 .procname = "ip_conntrack_generic_timeout",
94 .data = &nf_ct_generic_timeout,
95 .maxlen = sizeof(unsigned int),
96 .mode = 0644,
97 .proc_handler = &proc_dointvec_jiffies,
98 },
99 {
100 .ctl_name = 0
101 }
102};
103#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
104#endif /* CONFIG_SYSCTL */
105
106struct nf_conntrack_l4proto nf_conntrack_l4proto_generic =
75{ 107{
76 .l3proto = PF_UNSPEC, 108 .l3proto = PF_UNSPEC,
77 .proto = 0, 109 .l4proto = 0,
78 .name = "unknown", 110 .name = "unknown",
79 .pkt_to_tuple = generic_pkt_to_tuple, 111 .pkt_to_tuple = generic_pkt_to_tuple,
80 .invert_tuple = generic_invert_tuple, 112 .invert_tuple = generic_invert_tuple,
@@ -82,4 +114,11 @@ struct nf_conntrack_protocol nf_conntrack_generic_protocol =
82 .print_conntrack = generic_print_conntrack, 114 .print_conntrack = generic_print_conntrack,
83 .packet = packet, 115 .packet = packet,
84 .new = new, 116 .new = new,
117#ifdef CONFIG_SYSCTL
118 .ctl_table_header = &generic_sysctl_header,
119 .ctl_table = generic_sysctl_table,
120#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
121 .ctl_compat_table = generic_compat_sysctl_table,
122#endif
123#endif
85}; 124};
diff --git a/net/netfilter/nf_conntrack_proto_gre.c b/net/netfilter/nf_conntrack_proto_gre.c
new file mode 100644
index 0000000000..ac193ce702
--- /dev/null
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -0,0 +1,305 @@
1/*
2 * ip_conntrack_proto_gre.c - Version 3.0
3 *
4 * Connection tracking protocol helper module for GRE.
5 *
6 * GRE is a generic encapsulation protocol, which is generally not very
7 * suited for NAT, as it has no protocol-specific part as port numbers.
8 *
9 * It has an optional key field, which may help us distinguishing two
10 * connections between the same two hosts.
11 *
12 * GRE is defined in RFC 1701 and RFC 1702, as well as RFC 2784
13 *
14 * PPTP is built on top of a modified version of GRE, and has a mandatory
15 * field called "CallID", which serves us for the same purpose as the key
16 * field in plain GRE.
17 *
18 * Documentation about PPTP can be found in RFC 2637
19 *
20 * (C) 2000-2005 by Harald Welte <laforge@gnumonks.org>
21 *
22 * Development of this code funded by Astaro AG (http://www.astaro.com/)
23 *
24 */
25
26#include <linux/module.h>
27#include <linux/types.h>
28#include <linux/timer.h>
29#include <linux/list.h>
30#include <linux/seq_file.h>
31#include <linux/in.h>
32#include <linux/skbuff.h>
33
34#include <net/netfilter/nf_conntrack_l4proto.h>
35#include <net/netfilter/nf_conntrack_helper.h>
36#include <net/netfilter/nf_conntrack_core.h>
37#include <linux/netfilter/nf_conntrack_proto_gre.h>
38#include <linux/netfilter/nf_conntrack_pptp.h>
39
40#define GRE_TIMEOUT (30 * HZ)
41#define GRE_STREAM_TIMEOUT (180 * HZ)
42
43#if 0
44#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s: " format, __FILE__, __FUNCTION__, ## args)
45#else
46#define DEBUGP(x, args...)
47#endif
48
49static DEFINE_RWLOCK(nf_ct_gre_lock);
50static LIST_HEAD(gre_keymap_list);
51
52void nf_ct_gre_keymap_flush(void)
53{
54 struct list_head *pos, *n;
55
56 write_lock_bh(&nf_ct_gre_lock);
57 list_for_each_safe(pos, n, &gre_keymap_list) {
58 list_del(pos);
59 kfree(pos);
60 }
61 write_unlock_bh(&nf_ct_gre_lock);
62}
63EXPORT_SYMBOL(nf_ct_gre_keymap_flush);
64
65static inline int gre_key_cmpfn(const struct nf_ct_gre_keymap *km,
66 const struct nf_conntrack_tuple *t)
67{
68 return km->tuple.src.l3num == t->src.l3num &&
69 !memcmp(&km->tuple.src.u3, &t->src.u3, sizeof(t->src.u3)) &&
70 !memcmp(&km->tuple.dst.u3, &t->dst.u3, sizeof(t->dst.u3)) &&
71 km->tuple.dst.protonum == t->dst.protonum &&
72 km->tuple.dst.u.all == t->dst.u.all;
73}
74
75/* look up the source key for a given tuple */
76static __be16 gre_keymap_lookup(struct nf_conntrack_tuple *t)
77{
78 struct nf_ct_gre_keymap *km;
79 __be16 key = 0;
80
81 read_lock_bh(&nf_ct_gre_lock);
82 list_for_each_entry(km, &gre_keymap_list, list) {
83 if (gre_key_cmpfn(km, t)) {
84 key = km->tuple.src.u.gre.key;
85 break;
86 }
87 }
88 read_unlock_bh(&nf_ct_gre_lock);
89
90 DEBUGP("lookup src key 0x%x for ", key);
91 NF_CT_DUMP_TUPLE(t);
92
93 return key;
94}
95
96/* add a single keymap entry, associate with specified master ct */
97int nf_ct_gre_keymap_add(struct nf_conn *ct, enum ip_conntrack_dir dir,
98 struct nf_conntrack_tuple *t)
99{
100 struct nf_conn_help *help = nfct_help(ct);
101 struct nf_ct_gre_keymap **kmp, *km;
102
103 BUG_ON(strcmp(help->helper->name, "pptp"));
104 kmp = &help->help.ct_pptp_info.keymap[dir];
105 if (*kmp) {
106 /* check whether it's a retransmission */
107 list_for_each_entry(km, &gre_keymap_list, list) {
108 if (gre_key_cmpfn(km, t) && km == *kmp)
109 return 0;
110 }
111 DEBUGP("trying to override keymap_%s for ct %p\n",
112 dir == IP_CT_DIR_REPLY ? "reply" : "orig", ct);
113 return -EEXIST;
114 }
115
116 km = kmalloc(sizeof(*km), GFP_ATOMIC);
117 if (!km)
118 return -ENOMEM;
119 memcpy(&km->tuple, t, sizeof(*t));
120 *kmp = km;
121
122 DEBUGP("adding new entry %p: ", km);
123 NF_CT_DUMP_TUPLE(&km->tuple);
124
125 write_lock_bh(&nf_ct_gre_lock);
126 list_add_tail(&km->list, &gre_keymap_list);
127 write_unlock_bh(&nf_ct_gre_lock);
128
129 return 0;
130}
131EXPORT_SYMBOL_GPL(nf_ct_gre_keymap_add);
132
133/* destroy the keymap entries associated with specified master ct */
134void nf_ct_gre_keymap_destroy(struct nf_conn *ct)
135{
136 struct nf_conn_help *help = nfct_help(ct);
137 enum ip_conntrack_dir dir;
138
139 DEBUGP("entering for ct %p\n", ct);
140 BUG_ON(strcmp(help->helper->name, "pptp"));
141
142 write_lock_bh(&nf_ct_gre_lock);
143 for (dir = IP_CT_DIR_ORIGINAL; dir < IP_CT_DIR_MAX; dir++) {
144 if (help->help.ct_pptp_info.keymap[dir]) {
145 DEBUGP("removing %p from list\n",
146 help->help.ct_pptp_info.keymap[dir]);
147 list_del(&help->help.ct_pptp_info.keymap[dir]->list);
148 kfree(help->help.ct_pptp_info.keymap[dir]);
149 help->help.ct_pptp_info.keymap[dir] = NULL;
150 }
151 }
152 write_unlock_bh(&nf_ct_gre_lock);
153}
154EXPORT_SYMBOL_GPL(nf_ct_gre_keymap_destroy);
155
156/* PUBLIC CONNTRACK PROTO HELPER FUNCTIONS */
157
158/* invert gre part of tuple */
159static int gre_invert_tuple(struct nf_conntrack_tuple *tuple,
160 const struct nf_conntrack_tuple *orig)
161{
162 tuple->dst.u.gre.key = orig->src.u.gre.key;
163 tuple->src.u.gre.key = orig->dst.u.gre.key;
164 return 1;
165}
166
167/* gre hdr info to tuple */
168static int gre_pkt_to_tuple(const struct sk_buff *skb,
169 unsigned int dataoff,
170 struct nf_conntrack_tuple *tuple)
171{
172 struct gre_hdr_pptp _pgrehdr, *pgrehdr;
173 __be16 srckey;
174 struct gre_hdr _grehdr, *grehdr;
175
176 /* first only delinearize old RFC1701 GRE header */
177 grehdr = skb_header_pointer(skb, dataoff, sizeof(_grehdr), &_grehdr);
178 if (!grehdr || grehdr->version != GRE_VERSION_PPTP) {
179 /* try to behave like "nf_conntrack_proto_generic" */
180 tuple->src.u.all = 0;
181 tuple->dst.u.all = 0;
182 return 1;
183 }
184
185 /* PPTP header is variable length, only need up to the call_id field */
186 pgrehdr = skb_header_pointer(skb, dataoff, 8, &_pgrehdr);
187 if (!pgrehdr)
188 return 1;
189
190 if (ntohs(grehdr->protocol) != GRE_PROTOCOL_PPTP) {
191 DEBUGP("GRE_VERSION_PPTP but unknown proto\n");
192 return 0;
193 }
194
195 tuple->dst.u.gre.key = pgrehdr->call_id;
196 srckey = gre_keymap_lookup(tuple);
197 tuple->src.u.gre.key = srckey;
198
199 return 1;
200}
201
202/* print gre part of tuple */
203static int gre_print_tuple(struct seq_file *s,
204 const struct nf_conntrack_tuple *tuple)
205{
206 return seq_printf(s, "srckey=0x%x dstkey=0x%x ",
207 ntohs(tuple->src.u.gre.key),
208 ntohs(tuple->dst.u.gre.key));
209}
210
211/* print private data for conntrack */
212static int gre_print_conntrack(struct seq_file *s,
213 const struct nf_conn *ct)
214{
215 return seq_printf(s, "timeout=%u, stream_timeout=%u ",
216 (ct->proto.gre.timeout / HZ),
217 (ct->proto.gre.stream_timeout / HZ));
218}
219
220/* Returns verdict for packet, and may modify conntrack */
221static int gre_packet(struct nf_conn *ct,
222 const struct sk_buff *skb,
223 unsigned int dataoff,
224 enum ip_conntrack_info ctinfo,
225 int pf,
226 unsigned int hooknum)
227{
228 /* If we've seen traffic both ways, this is a GRE connection.
229 * Extend timeout. */
230 if (ct->status & IPS_SEEN_REPLY) {
231 nf_ct_refresh_acct(ct, ctinfo, skb,
232 ct->proto.gre.stream_timeout);
233 /* Also, more likely to be important, and not a probe. */
234 set_bit(IPS_ASSURED_BIT, &ct->status);
235 nf_conntrack_event_cache(IPCT_STATUS, skb);
236 } else
237 nf_ct_refresh_acct(ct, ctinfo, skb,
238 ct->proto.gre.timeout);
239
240 return NF_ACCEPT;
241}
242
243/* Called when a new connection for this protocol found. */
244static int gre_new(struct nf_conn *ct, const struct sk_buff *skb,
245 unsigned int dataoff)
246{
247 DEBUGP(": ");
248 NF_CT_DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
249
250 /* initialize to sane value. Ideally a conntrack helper
251 * (e.g. in case of pptp) is increasing them */
252 ct->proto.gre.stream_timeout = GRE_STREAM_TIMEOUT;
253 ct->proto.gre.timeout = GRE_TIMEOUT;
254
255 return 1;
256}
257
258/* Called when a conntrack entry has already been removed from the hashes
259 * and is about to be deleted from memory */
260static void gre_destroy(struct nf_conn *ct)
261{
262 struct nf_conn *master = ct->master;
263 DEBUGP(" entering\n");
264
265 if (!master)
266 DEBUGP("no master !?!\n");
267 else
268 nf_ct_gre_keymap_destroy(master);
269}
270
271/* protocol helper struct */
272static struct nf_conntrack_l4proto nf_conntrack_l4proto_gre4 = {
273 .l3proto = AF_INET,
274 .l4proto = IPPROTO_GRE,
275 .name = "gre",
276 .pkt_to_tuple = gre_pkt_to_tuple,
277 .invert_tuple = gre_invert_tuple,
278 .print_tuple = gre_print_tuple,
279 .print_conntrack = gre_print_conntrack,
280 .packet = gre_packet,
281 .new = gre_new,
282 .destroy = gre_destroy,
283 .me = THIS_MODULE,
284#if defined(CONFIG_NF_CONNTRACK_NETLINK) || \
285 defined(CONFIG_NF_CONNTRACK_NETLINK_MODULE)
286 .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr,
287 .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple,
288#endif
289};
290
291static int __init nf_ct_proto_gre_init(void)
292{
293 return nf_conntrack_l4proto_register(&nf_conntrack_l4proto_gre4);
294}
295
296static void nf_ct_proto_gre_fini(void)
297{
298 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_gre4);
299 nf_ct_gre_keymap_flush();
300}
301
302module_init(nf_ct_proto_gre_init);
303module_exit(nf_ct_proto_gre_fini);
304
305MODULE_LICENSE("GPL");
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index af56877737..76e2636682 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -32,7 +32,8 @@
32#include <linux/interrupt.h> 32#include <linux/interrupt.h>
33 33
34#include <net/netfilter/nf_conntrack.h> 34#include <net/netfilter/nf_conntrack.h>
35#include <net/netfilter/nf_conntrack_protocol.h> 35#include <net/netfilter/nf_conntrack_l4proto.h>
36#include <net/netfilter/nf_conntrack_ecache.h>
36 37
37#if 0 38#if 0
38#define DEBUGP(format, ...) printk(format, ## __VA_ARGS__) 39#define DEBUGP(format, ...) printk(format, ## __VA_ARGS__)
@@ -216,7 +217,7 @@ static int sctp_print_conntrack(struct seq_file *s,
216for (offset = dataoff + sizeof(sctp_sctphdr_t), count = 0; \ 217for (offset = dataoff + sizeof(sctp_sctphdr_t), count = 0; \
217 offset < skb->len && \ 218 offset < skb->len && \
218 (sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch)); \ 219 (sch = skb_header_pointer(skb, offset, sizeof(_sch), &_sch)); \
219 offset += (htons(sch->length) + 3) & ~3, count++) 220 offset += (ntohs(sch->length) + 3) & ~3, count++)
220 221
221/* Some validity checks to make sure the chunks are fine */ 222/* Some validity checks to make sure the chunks are fine */
222static int do_basic_checks(struct nf_conn *conntrack, 223static int do_basic_checks(struct nf_conn *conntrack,
@@ -508,36 +509,10 @@ static int sctp_new(struct nf_conn *conntrack, const struct sk_buff *skb,
508 return 1; 509 return 1;
509} 510}
510 511
511struct nf_conntrack_protocol nf_conntrack_protocol_sctp4 = {
512 .l3proto = PF_INET,
513 .proto = IPPROTO_SCTP,
514 .name = "sctp",
515 .pkt_to_tuple = sctp_pkt_to_tuple,
516 .invert_tuple = sctp_invert_tuple,
517 .print_tuple = sctp_print_tuple,
518 .print_conntrack = sctp_print_conntrack,
519 .packet = sctp_packet,
520 .new = sctp_new,
521 .destroy = NULL,
522 .me = THIS_MODULE
523};
524
525struct nf_conntrack_protocol nf_conntrack_protocol_sctp6 = {
526 .l3proto = PF_INET6,
527 .proto = IPPROTO_SCTP,
528 .name = "sctp",
529 .pkt_to_tuple = sctp_pkt_to_tuple,
530 .invert_tuple = sctp_invert_tuple,
531 .print_tuple = sctp_print_tuple,
532 .print_conntrack = sctp_print_conntrack,
533 .packet = sctp_packet,
534 .new = sctp_new,
535 .destroy = NULL,
536 .me = THIS_MODULE
537};
538
539#ifdef CONFIG_SYSCTL 512#ifdef CONFIG_SYSCTL
540static ctl_table nf_ct_sysctl_table[] = { 513static unsigned int sctp_sysctl_table_users;
514static struct ctl_table_header *sctp_sysctl_header;
515static struct ctl_table sctp_sysctl_table[] = {
541 { 516 {
542 .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED, 517 .ctl_name = NET_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED,
543 .procname = "nf_conntrack_sctp_timeout_closed", 518 .procname = "nf_conntrack_sctp_timeout_closed",
@@ -594,63 +569,134 @@ static ctl_table nf_ct_sysctl_table[] = {
594 .mode = 0644, 569 .mode = 0644,
595 .proc_handler = &proc_dointvec_jiffies, 570 .proc_handler = &proc_dointvec_jiffies,
596 }, 571 },
597 { .ctl_name = 0 } 572 {
573 .ctl_name = 0
574 }
598}; 575};
599 576
600static ctl_table nf_ct_netfilter_table[] = { 577#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
578static struct ctl_table sctp_compat_sysctl_table[] = {
601 { 579 {
602 .ctl_name = NET_NETFILTER, 580 .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_CLOSED,
603 .procname = "netfilter", 581 .procname = "ip_conntrack_sctp_timeout_closed",
604 .mode = 0555, 582 .data = &nf_ct_sctp_timeout_closed,
605 .child = nf_ct_sysctl_table, 583 .maxlen = sizeof(unsigned int),
584 .mode = 0644,
585 .proc_handler = &proc_dointvec_jiffies,
586 },
587 {
588 .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_WAIT,
589 .procname = "ip_conntrack_sctp_timeout_cookie_wait",
590 .data = &nf_ct_sctp_timeout_cookie_wait,
591 .maxlen = sizeof(unsigned int),
592 .mode = 0644,
593 .proc_handler = &proc_dointvec_jiffies,
594 },
595 {
596 .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_COOKIE_ECHOED,
597 .procname = "ip_conntrack_sctp_timeout_cookie_echoed",
598 .data = &nf_ct_sctp_timeout_cookie_echoed,
599 .maxlen = sizeof(unsigned int),
600 .mode = 0644,
601 .proc_handler = &proc_dointvec_jiffies,
602 },
603 {
604 .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_ESTABLISHED,
605 .procname = "ip_conntrack_sctp_timeout_established",
606 .data = &nf_ct_sctp_timeout_established,
607 .maxlen = sizeof(unsigned int),
608 .mode = 0644,
609 .proc_handler = &proc_dointvec_jiffies,
610 },
611 {
612 .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_SENT,
613 .procname = "ip_conntrack_sctp_timeout_shutdown_sent",
614 .data = &nf_ct_sctp_timeout_shutdown_sent,
615 .maxlen = sizeof(unsigned int),
616 .mode = 0644,
617 .proc_handler = &proc_dointvec_jiffies,
618 },
619 {
620 .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_RECD,
621 .procname = "ip_conntrack_sctp_timeout_shutdown_recd",
622 .data = &nf_ct_sctp_timeout_shutdown_recd,
623 .maxlen = sizeof(unsigned int),
624 .mode = 0644,
625 .proc_handler = &proc_dointvec_jiffies,
606 }, 626 },
607 { .ctl_name = 0 }
608};
609
610static ctl_table nf_ct_net_table[] = {
611 { 627 {
612 .ctl_name = CTL_NET, 628 .ctl_name = NET_IPV4_NF_CONNTRACK_SCTP_TIMEOUT_SHUTDOWN_ACK_SENT,
613 .procname = "net", 629 .procname = "ip_conntrack_sctp_timeout_shutdown_ack_sent",
614 .mode = 0555, 630 .data = &nf_ct_sctp_timeout_shutdown_ack_sent,
615 .child = nf_ct_netfilter_table, 631 .maxlen = sizeof(unsigned int),
632 .mode = 0644,
633 .proc_handler = &proc_dointvec_jiffies,
616 }, 634 },
617 { .ctl_name = 0 } 635 {
636 .ctl_name = 0
637 }
638};
639#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
640#endif
641
642struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4 = {
643 .l3proto = PF_INET,
644 .l4proto = IPPROTO_SCTP,
645 .name = "sctp",
646 .pkt_to_tuple = sctp_pkt_to_tuple,
647 .invert_tuple = sctp_invert_tuple,
648 .print_tuple = sctp_print_tuple,
649 .print_conntrack = sctp_print_conntrack,
650 .packet = sctp_packet,
651 .new = sctp_new,
652 .me = THIS_MODULE,
653#ifdef CONFIG_SYSCTL
654 .ctl_table_users = &sctp_sysctl_table_users,
655 .ctl_table_header = &sctp_sysctl_header,
656 .ctl_table = sctp_sysctl_table,
657#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
658 .ctl_compat_table = sctp_compat_sysctl_table,
659#endif
660#endif
618}; 661};
619 662
620static struct ctl_table_header *nf_ct_sysctl_header; 663struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6 = {
664 .l3proto = PF_INET6,
665 .l4proto = IPPROTO_SCTP,
666 .name = "sctp",
667 .pkt_to_tuple = sctp_pkt_to_tuple,
668 .invert_tuple = sctp_invert_tuple,
669 .print_tuple = sctp_print_tuple,
670 .print_conntrack = sctp_print_conntrack,
671 .packet = sctp_packet,
672 .new = sctp_new,
673 .me = THIS_MODULE,
674#ifdef CONFIG_SYSCTL
675 .ctl_table_users = &sctp_sysctl_table_users,
676 .ctl_table_header = &sctp_sysctl_header,
677 .ctl_table = sctp_sysctl_table,
621#endif 678#endif
679};
622 680
623int __init nf_conntrack_proto_sctp_init(void) 681int __init nf_conntrack_proto_sctp_init(void)
624{ 682{
625 int ret; 683 int ret;
626 684
627 ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_sctp4); 685 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_sctp4);
628 if (ret) { 686 if (ret) {
629 printk("nf_conntrack_proto_sctp4: protocol register failed\n"); 687 printk("nf_conntrack_l4proto_sctp4: protocol register failed\n");
630 goto out; 688 goto out;
631 } 689 }
632 ret = nf_conntrack_protocol_register(&nf_conntrack_protocol_sctp6); 690 ret = nf_conntrack_l4proto_register(&nf_conntrack_l4proto_sctp6);
633 if (ret) { 691 if (ret) {
634 printk("nf_conntrack_proto_sctp6: protocol register failed\n"); 692 printk("nf_conntrack_l4proto_sctp6: protocol register failed\n");
635 goto cleanup_sctp4; 693 goto cleanup_sctp4;
636 } 694 }
637 695
638#ifdef CONFIG_SYSCTL
639 nf_ct_sysctl_header = register_sysctl_table(nf_ct_net_table, 0);
640 if (nf_ct_sysctl_header == NULL) {
641 printk("nf_conntrack_proto_sctp: can't register to sysctl.\n");
642 goto cleanup;
643 }
644#endif
645
646 return ret; 696 return ret;
647 697
648#ifdef CONFIG_SYSCTL
649 cleanup:
650 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_sctp6);
651#endif
652 cleanup_sctp4: 698 cleanup_sctp4:
653 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_sctp4); 699 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
654 out: 700 out:
655 DEBUGP("SCTP conntrack module loading %s\n", 701 DEBUGP("SCTP conntrack module loading %s\n",
656 ret ? "failed": "succeeded"); 702 ret ? "failed": "succeeded");
@@ -659,11 +705,8 @@ int __init nf_conntrack_proto_sctp_init(void)
659 705
660void __exit nf_conntrack_proto_sctp_fini(void) 706void __exit nf_conntrack_proto_sctp_fini(void)
661{ 707{
662 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_sctp6); 708 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp6);
663 nf_conntrack_protocol_unregister(&nf_conntrack_protocol_sctp4); 709 nf_conntrack_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
664#ifdef CONFIG_SYSCTL
665 unregister_sysctl_table(nf_ct_sysctl_header);
666#endif
667 DEBUGP("SCTP conntrack module unloaded\n"); 710 DEBUGP("SCTP conntrack module unloaded\n");
668} 711}
669 712
@@ -673,3 +716,4 @@ module_exit(nf_conntrack_proto_sctp_fini);
673MODULE_LICENSE("GPL"); 716MODULE_LICENSE("GPL");
674MODULE_AUTHOR("Kiran Kumar Immidi"); 717MODULE_AUTHOR("Kiran Kumar Immidi");
675MODULE_DESCRIPTION("Netfilter connection tracking protocol helper for SCTP"); 718MODULE_DESCRIPTION("Netfilter connection tracking protocol helper for SCTP");
719MODULE_ALIAS("ip_conntrack_proto_sctp");
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 238bbb5b72..626b0011dd 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -42,7 +42,8 @@
42#include <linux/netfilter_ipv4.h> 42#include <linux/netfilter_ipv4.h>
43#include <linux/netfilter_ipv6.h> 43#include <linux/netfilter_ipv6.h>
44#include <net/netfilter/nf_conntrack.h> 44#include <net/netfilter/nf_conntrack.h>
45#include <net/netfilter/nf_conntrack_protocol.h> 45#include <net/netfilter/nf_conntrack_l4proto.h>
46#include <net/netfilter/nf_conntrack_ecache.h>
46 47
47#if 0 48#if 0
48#define DEBUGP printk 49#define DEBUGP printk
@@ -92,22 +93,22 @@ static const char *tcp_conntrack_names[] = {
92#define HOURS * 60 MINS 93#define HOURS * 60 MINS
93#define DAYS * 24 HOURS 94#define DAYS * 24 HOURS
94 95
95unsigned int nf_ct_tcp_timeout_syn_sent __read_mostly = 2 MINS; 96static unsigned int nf_ct_tcp_timeout_syn_sent __read_mostly = 2 MINS;
96unsigned int nf_ct_tcp_timeout_syn_recv __read_mostly = 60 SECS; 97static unsigned int nf_ct_tcp_timeout_syn_recv __read_mostly = 60 SECS;
97unsigned int nf_ct_tcp_timeout_established __read_mostly = 5 DAYS; 98static unsigned int nf_ct_tcp_timeout_established __read_mostly = 5 DAYS;
98unsigned int nf_ct_tcp_timeout_fin_wait __read_mostly = 2 MINS; 99static unsigned int nf_ct_tcp_timeout_fin_wait __read_mostly = 2 MINS;
99unsigned int nf_ct_tcp_timeout_close_wait __read_mostly = 60 SECS; 100static unsigned int nf_ct_tcp_timeout_close_wait __read_mostly = 60 SECS;
100unsigned int nf_ct_tcp_timeout_last_ack __read_mostly = 30 SECS; 101static unsigned int nf_ct_tcp_timeout_last_ack __read_mostly = 30 SECS;
101unsigned int nf_ct_tcp_timeout_time_wait __read_mostly = 2 MINS; 102static unsigned int nf_ct_tcp_timeout_time_wait __read_mostly = 2 MINS;
102unsigned int nf_ct_tcp_timeout_close __read_mostly = 10 SECS; 103static unsigned int nf_ct_tcp_timeout_close __read_mostly = 10 SECS;
103 104
104/* RFC1122 says the R2 limit should be at least 100 seconds. 105/* RFC1122 says the R2 limit should be at least 100 seconds.
105 Linux uses 15 packets as limit, which corresponds 106 Linux uses 15 packets as limit, which corresponds
106 to ~13-30min depending on RTO. */ 107 to ~13-30min depending on RTO. */
107unsigned int nf_ct_tcp_timeout_max_retrans __read_mostly = 5 MINS; 108static unsigned int nf_ct_tcp_timeout_max_retrans __read_mostly = 5 MINS;
108 109
109static unsigned int * tcp_timeouts[] 110static unsigned int * tcp_timeouts[] = {
110= { NULL, /* TCP_CONNTRACK_NONE */ 111 NULL, /* TCP_CONNTRACK_NONE */
111 &nf_ct_tcp_timeout_syn_sent, /* TCP_CONNTRACK_SYN_SENT, */ 112 &nf_ct_tcp_timeout_syn_sent, /* TCP_CONNTRACK_SYN_SENT, */
112 &nf_ct_tcp_timeout_syn_recv, /* TCP_CONNTRACK_SYN_RECV, */ 113 &nf_ct_tcp_timeout_syn_recv, /* TCP_CONNTRACK_SYN_RECV, */
113 &nf_ct_tcp_timeout_established, /* TCP_CONNTRACK_ESTABLISHED, */ 114 &nf_ct_tcp_timeout_established, /* TCP_CONNTRACK_ESTABLISHED, */
@@ -473,8 +474,8 @@ static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff,
473 474
474 /* Fast path for timestamp-only option */ 475 /* Fast path for timestamp-only option */
475 if (length == TCPOLEN_TSTAMP_ALIGNED*4 476 if (length == TCPOLEN_TSTAMP_ALIGNED*4
476 && *(__u32 *)ptr == 477 && *(__be32 *)ptr ==
477 __constant_ntohl((TCPOPT_NOP << 24) 478 __constant_htonl((TCPOPT_NOP << 24)
478 | (TCPOPT_NOP << 16) 479 | (TCPOPT_NOP << 16)
479 | (TCPOPT_TIMESTAMP << 8) 480 | (TCPOPT_TIMESTAMP << 8)
480 | TCPOLEN_TIMESTAMP)) 481 | TCPOLEN_TIMESTAMP))
@@ -505,9 +506,7 @@ static void tcp_sack(const struct sk_buff *skb, unsigned int dataoff,
505 for (i = 0; 506 for (i = 0;
506 i < (opsize - TCPOLEN_SACK_BASE); 507 i < (opsize - TCPOLEN_SACK_BASE);
507 i += TCPOLEN_SACK_PERBLOCK) { 508 i += TCPOLEN_SACK_PERBLOCK) {
508 memcpy(&tmp, (__u32 *)(ptr + i) + 1, 509 tmp = ntohl(*((__be32 *)(ptr+i)+1));
509 sizeof(__u32));
510 tmp = ntohl(tmp);
511 510
512 if (after(tmp, *sack)) 511 if (after(tmp, *sack))
513 *sack = tmp; 512 *sack = tmp;
@@ -731,7 +730,7 @@ static int tcp_in_window(struct ip_ct_tcp *state,
731 return res; 730 return res;
732} 731}
733 732
734#ifdef CONFIG_IP_NF_NAT_NEEDED 733#ifdef CONFIG_NF_NAT_NEEDED
735/* Update sender->td_end after NAT successfully mangled the packet */ 734/* Update sender->td_end after NAT successfully mangled the packet */
736/* Caller must linearize skb at tcp header. */ 735/* Caller must linearize skb at tcp header. */
737void nf_conntrack_tcp_update(struct sk_buff *skb, 736void nf_conntrack_tcp_update(struct sk_buff *skb,
@@ -763,7 +762,7 @@ void nf_conntrack_tcp_update(struct sk_buff *skb,
763 receiver->td_end, receiver->td_maxend, receiver->td_maxwin, 762 receiver->td_end, receiver->td_maxend, receiver->td_maxwin,
764 receiver->td_scale); 763 receiver->td_scale);
765} 764}
766 765EXPORT_SYMBOL_GPL(nf_conntrack_tcp_update);
767#endif 766#endif
768 767
769#define TH_FIN 0x01 768#define TH_FIN 0x01
@@ -1167,11 +1166,221 @@ static int nfattr_to_tcp(struct nfattr *cda[], struct nf_conn *ct)
1167 return 0; 1166 return 0;
1168} 1167}
1169#endif 1168#endif
1170 1169
1171struct nf_conntrack_protocol nf_conntrack_protocol_tcp4 = 1170#ifdef CONFIG_SYSCTL
1171static unsigned int tcp_sysctl_table_users;
1172static struct ctl_table_header *tcp_sysctl_header;
1173static struct ctl_table tcp_sysctl_table[] = {
1174 {
1175 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT,
1176 .procname = "nf_conntrack_tcp_timeout_syn_sent",
1177 .data = &nf_ct_tcp_timeout_syn_sent,
1178 .maxlen = sizeof(unsigned int),
1179 .mode = 0644,
1180 .proc_handler = &proc_dointvec_jiffies,
1181 },
1182 {
1183 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV,
1184 .procname = "nf_conntrack_tcp_timeout_syn_recv",
1185 .data = &nf_ct_tcp_timeout_syn_recv,
1186 .maxlen = sizeof(unsigned int),
1187 .mode = 0644,
1188 .proc_handler = &proc_dointvec_jiffies,
1189 },
1190 {
1191 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED,
1192 .procname = "nf_conntrack_tcp_timeout_established",
1193 .data = &nf_ct_tcp_timeout_established,
1194 .maxlen = sizeof(unsigned int),
1195 .mode = 0644,
1196 .proc_handler = &proc_dointvec_jiffies,
1197 },
1198 {
1199 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT,
1200 .procname = "nf_conntrack_tcp_timeout_fin_wait",
1201 .data = &nf_ct_tcp_timeout_fin_wait,
1202 .maxlen = sizeof(unsigned int),
1203 .mode = 0644,
1204 .proc_handler = &proc_dointvec_jiffies,
1205 },
1206 {
1207 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT,
1208 .procname = "nf_conntrack_tcp_timeout_close_wait",
1209 .data = &nf_ct_tcp_timeout_close_wait,
1210 .maxlen = sizeof(unsigned int),
1211 .mode = 0644,
1212 .proc_handler = &proc_dointvec_jiffies,
1213 },
1214 {
1215 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK,
1216 .procname = "nf_conntrack_tcp_timeout_last_ack",
1217 .data = &nf_ct_tcp_timeout_last_ack,
1218 .maxlen = sizeof(unsigned int),
1219 .mode = 0644,
1220 .proc_handler = &proc_dointvec_jiffies,
1221 },
1222 {
1223 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT,
1224 .procname = "nf_conntrack_tcp_timeout_time_wait",
1225 .data = &nf_ct_tcp_timeout_time_wait,
1226 .maxlen = sizeof(unsigned int),
1227 .mode = 0644,
1228 .proc_handler = &proc_dointvec_jiffies,
1229 },
1230 {
1231 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE,
1232 .procname = "nf_conntrack_tcp_timeout_close",
1233 .data = &nf_ct_tcp_timeout_close,
1234 .maxlen = sizeof(unsigned int),
1235 .mode = 0644,
1236 .proc_handler = &proc_dointvec_jiffies,
1237 },
1238 {
1239 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS,
1240 .procname = "nf_conntrack_tcp_timeout_max_retrans",
1241 .data = &nf_ct_tcp_timeout_max_retrans,
1242 .maxlen = sizeof(unsigned int),
1243 .mode = 0644,
1244 .proc_handler = &proc_dointvec_jiffies,
1245 },
1246 {
1247 .ctl_name = NET_NF_CONNTRACK_TCP_LOOSE,
1248 .procname = "nf_conntrack_tcp_loose",
1249 .data = &nf_ct_tcp_loose,
1250 .maxlen = sizeof(unsigned int),
1251 .mode = 0644,
1252 .proc_handler = &proc_dointvec,
1253 },
1254 {
1255 .ctl_name = NET_NF_CONNTRACK_TCP_BE_LIBERAL,
1256 .procname = "nf_conntrack_tcp_be_liberal",
1257 .data = &nf_ct_tcp_be_liberal,
1258 .maxlen = sizeof(unsigned int),
1259 .mode = 0644,
1260 .proc_handler = &proc_dointvec,
1261 },
1262 {
1263 .ctl_name = NET_NF_CONNTRACK_TCP_MAX_RETRANS,
1264 .procname = "nf_conntrack_tcp_max_retrans",
1265 .data = &nf_ct_tcp_max_retrans,
1266 .maxlen = sizeof(unsigned int),
1267 .mode = 0644,
1268 .proc_handler = &proc_dointvec,
1269 },
1270 {
1271 .ctl_name = 0
1272 }
1273};
1274
1275#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
1276static struct ctl_table tcp_compat_sysctl_table[] = {
1277 {
1278 .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT,
1279 .procname = "ip_conntrack_tcp_timeout_syn_sent",
1280 .data = &nf_ct_tcp_timeout_syn_sent,
1281 .maxlen = sizeof(unsigned int),
1282 .mode = 0644,
1283 .proc_handler = &proc_dointvec_jiffies,
1284 },
1285 {
1286 .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV,
1287 .procname = "ip_conntrack_tcp_timeout_syn_recv",
1288 .data = &nf_ct_tcp_timeout_syn_recv,
1289 .maxlen = sizeof(unsigned int),
1290 .mode = 0644,
1291 .proc_handler = &proc_dointvec_jiffies,
1292 },
1293 {
1294 .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED,
1295 .procname = "ip_conntrack_tcp_timeout_established",
1296 .data = &nf_ct_tcp_timeout_established,
1297 .maxlen = sizeof(unsigned int),
1298 .mode = 0644,
1299 .proc_handler = &proc_dointvec_jiffies,
1300 },
1301 {
1302 .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT,
1303 .procname = "ip_conntrack_tcp_timeout_fin_wait",
1304 .data = &nf_ct_tcp_timeout_fin_wait,
1305 .maxlen = sizeof(unsigned int),
1306 .mode = 0644,
1307 .proc_handler = &proc_dointvec_jiffies,
1308 },
1309 {
1310 .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT,
1311 .procname = "ip_conntrack_tcp_timeout_close_wait",
1312 .data = &nf_ct_tcp_timeout_close_wait,
1313 .maxlen = sizeof(unsigned int),
1314 .mode = 0644,
1315 .proc_handler = &proc_dointvec_jiffies,
1316 },
1317 {
1318 .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK,
1319 .procname = "ip_conntrack_tcp_timeout_last_ack",
1320 .data = &nf_ct_tcp_timeout_last_ack,
1321 .maxlen = sizeof(unsigned int),
1322 .mode = 0644,
1323 .proc_handler = &proc_dointvec_jiffies,
1324 },
1325 {
1326 .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT,
1327 .procname = "ip_conntrack_tcp_timeout_time_wait",
1328 .data = &nf_ct_tcp_timeout_time_wait,
1329 .maxlen = sizeof(unsigned int),
1330 .mode = 0644,
1331 .proc_handler = &proc_dointvec_jiffies,
1332 },
1333 {
1334 .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE,
1335 .procname = "ip_conntrack_tcp_timeout_close",
1336 .data = &nf_ct_tcp_timeout_close,
1337 .maxlen = sizeof(unsigned int),
1338 .mode = 0644,
1339 .proc_handler = &proc_dointvec_jiffies,
1340 },
1341 {
1342 .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS,
1343 .procname = "ip_conntrack_tcp_timeout_max_retrans",
1344 .data = &nf_ct_tcp_timeout_max_retrans,
1345 .maxlen = sizeof(unsigned int),
1346 .mode = 0644,
1347 .proc_handler = &proc_dointvec_jiffies,
1348 },
1349 {
1350 .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_LOOSE,
1351 .procname = "ip_conntrack_tcp_loose",
1352 .data = &nf_ct_tcp_loose,
1353 .maxlen = sizeof(unsigned int),
1354 .mode = 0644,
1355 .proc_handler = &proc_dointvec,
1356 },
1357 {
1358 .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_BE_LIBERAL,
1359 .procname = "ip_conntrack_tcp_be_liberal",
1360 .data = &nf_ct_tcp_be_liberal,
1361 .maxlen = sizeof(unsigned int),
1362 .mode = 0644,
1363 .proc_handler = &proc_dointvec,
1364 },
1365 {
1366 .ctl_name = NET_IPV4_NF_CONNTRACK_TCP_MAX_RETRANS,
1367 .procname = "ip_conntrack_tcp_max_retrans",
1368 .data = &nf_ct_tcp_max_retrans,
1369 .maxlen = sizeof(unsigned int),
1370 .mode = 0644,
1371 .proc_handler = &proc_dointvec,
1372 },
1373 {
1374 .ctl_name = 0
1375 }
1376};
1377#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
1378#endif /* CONFIG_SYSCTL */
1379
1380struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4 =
1172{ 1381{
1173 .l3proto = PF_INET, 1382 .l3proto = PF_INET,
1174 .proto = IPPROTO_TCP, 1383 .l4proto = IPPROTO_TCP,
1175 .name = "tcp", 1384 .name = "tcp",
1176 .pkt_to_tuple = tcp_pkt_to_tuple, 1385 .pkt_to_tuple = tcp_pkt_to_tuple,
1177 .invert_tuple = tcp_invert_tuple, 1386 .invert_tuple = tcp_invert_tuple,
@@ -1187,12 +1396,21 @@ struct nf_conntrack_protocol nf_conntrack_protocol_tcp4 =
1187 .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr, 1396 .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr,
1188 .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple, 1397 .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple,
1189#endif 1398#endif
1399#ifdef CONFIG_SYSCTL
1400 .ctl_table_users = &tcp_sysctl_table_users,
1401 .ctl_table_header = &tcp_sysctl_header,
1402 .ctl_table = tcp_sysctl_table,
1403#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
1404 .ctl_compat_table = tcp_compat_sysctl_table,
1405#endif
1406#endif
1190}; 1407};
1408EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp4);
1191 1409
1192struct nf_conntrack_protocol nf_conntrack_protocol_tcp6 = 1410struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6 =
1193{ 1411{
1194 .l3proto = PF_INET6, 1412 .l3proto = PF_INET6,
1195 .proto = IPPROTO_TCP, 1413 .l4proto = IPPROTO_TCP,
1196 .name = "tcp", 1414 .name = "tcp",
1197 .pkt_to_tuple = tcp_pkt_to_tuple, 1415 .pkt_to_tuple = tcp_pkt_to_tuple,
1198 .invert_tuple = tcp_invert_tuple, 1416 .invert_tuple = tcp_invert_tuple,
@@ -1208,7 +1426,10 @@ struct nf_conntrack_protocol nf_conntrack_protocol_tcp6 =
1208 .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr, 1426 .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr,
1209 .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple, 1427 .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple,
1210#endif 1428#endif
1429#ifdef CONFIG_SYSCTL
1430 .ctl_table_users = &tcp_sysctl_table_users,
1431 .ctl_table_header = &tcp_sysctl_header,
1432 .ctl_table = tcp_sysctl_table,
1433#endif
1211}; 1434};
1212 1435EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_tcp6);
1213EXPORT_SYMBOL(nf_conntrack_protocol_tcp4);
1214EXPORT_SYMBOL(nf_conntrack_protocol_tcp6);
diff --git a/net/netfilter/nf_conntrack_proto_udp.c b/net/netfilter/nf_conntrack_proto_udp.c
index d28981cf9a..e49cd25998 100644
--- a/net/netfilter/nf_conntrack_proto_udp.c
+++ b/net/netfilter/nf_conntrack_proto_udp.c
@@ -22,13 +22,15 @@
22#include <linux/ipv6.h> 22#include <linux/ipv6.h>
23#include <net/ip6_checksum.h> 23#include <net/ip6_checksum.h>
24#include <net/checksum.h> 24#include <net/checksum.h>
25
25#include <linux/netfilter.h> 26#include <linux/netfilter.h>
26#include <linux/netfilter_ipv4.h> 27#include <linux/netfilter_ipv4.h>
27#include <linux/netfilter_ipv6.h> 28#include <linux/netfilter_ipv6.h>
28#include <net/netfilter/nf_conntrack_protocol.h> 29#include <net/netfilter/nf_conntrack_l4proto.h>
30#include <net/netfilter/nf_conntrack_ecache.h>
29 31
30unsigned int nf_ct_udp_timeout __read_mostly = 30*HZ; 32static unsigned int nf_ct_udp_timeout __read_mostly = 30*HZ;
31unsigned int nf_ct_udp_timeout_stream __read_mostly = 180*HZ; 33static unsigned int nf_ct_udp_timeout_stream __read_mostly = 180*HZ;
32 34
33static int udp_pkt_to_tuple(const struct sk_buff *skb, 35static int udp_pkt_to_tuple(const struct sk_buff *skb,
34 unsigned int dataoff, 36 unsigned int dataoff,
@@ -146,10 +148,59 @@ static int udp_error(struct sk_buff *skb, unsigned int dataoff,
146 return NF_ACCEPT; 148 return NF_ACCEPT;
147} 149}
148 150
149struct nf_conntrack_protocol nf_conntrack_protocol_udp4 = 151#ifdef CONFIG_SYSCTL
152static unsigned int udp_sysctl_table_users;
153static struct ctl_table_header *udp_sysctl_header;
154static struct ctl_table udp_sysctl_table[] = {
155 {
156 .ctl_name = NET_NF_CONNTRACK_UDP_TIMEOUT,
157 .procname = "nf_conntrack_udp_timeout",
158 .data = &nf_ct_udp_timeout,
159 .maxlen = sizeof(unsigned int),
160 .mode = 0644,
161 .proc_handler = &proc_dointvec_jiffies,
162 },
163 {
164 .ctl_name = NET_NF_CONNTRACK_UDP_TIMEOUT_STREAM,
165 .procname = "nf_conntrack_udp_timeout_stream",
166 .data = &nf_ct_udp_timeout_stream,
167 .maxlen = sizeof(unsigned int),
168 .mode = 0644,
169 .proc_handler = &proc_dointvec_jiffies,
170 },
171 {
172 .ctl_name = 0
173 }
174};
175#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
176static struct ctl_table udp_compat_sysctl_table[] = {
177 {
178 .ctl_name = NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT,
179 .procname = "ip_conntrack_udp_timeout",
180 .data = &nf_ct_udp_timeout,
181 .maxlen = sizeof(unsigned int),
182 .mode = 0644,
183 .proc_handler = &proc_dointvec_jiffies,
184 },
185 {
186 .ctl_name = NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT_STREAM,
187 .procname = "ip_conntrack_udp_timeout_stream",
188 .data = &nf_ct_udp_timeout_stream,
189 .maxlen = sizeof(unsigned int),
190 .mode = 0644,
191 .proc_handler = &proc_dointvec_jiffies,
192 },
193 {
194 .ctl_name = 0
195 }
196};
197#endif /* CONFIG_NF_CONNTRACK_PROC_COMPAT */
198#endif /* CONFIG_SYSCTL */
199
200struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4 =
150{ 201{
151 .l3proto = PF_INET, 202 .l3proto = PF_INET,
152 .proto = IPPROTO_UDP, 203 .l4proto = IPPROTO_UDP,
153 .name = "udp", 204 .name = "udp",
154 .pkt_to_tuple = udp_pkt_to_tuple, 205 .pkt_to_tuple = udp_pkt_to_tuple,
155 .invert_tuple = udp_invert_tuple, 206 .invert_tuple = udp_invert_tuple,
@@ -163,12 +214,21 @@ struct nf_conntrack_protocol nf_conntrack_protocol_udp4 =
163 .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr, 214 .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr,
164 .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple, 215 .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple,
165#endif 216#endif
217#ifdef CONFIG_SYSCTL
218 .ctl_table_users = &udp_sysctl_table_users,
219 .ctl_table_header = &udp_sysctl_header,
220 .ctl_table = udp_sysctl_table,
221#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT
222 .ctl_compat_table = udp_compat_sysctl_table,
223#endif
224#endif
166}; 225};
226EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udp4);
167 227
168struct nf_conntrack_protocol nf_conntrack_protocol_udp6 = 228struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6 =
169{ 229{
170 .l3proto = PF_INET6, 230 .l3proto = PF_INET6,
171 .proto = IPPROTO_UDP, 231 .l4proto = IPPROTO_UDP,
172 .name = "udp", 232 .name = "udp",
173 .pkt_to_tuple = udp_pkt_to_tuple, 233 .pkt_to_tuple = udp_pkt_to_tuple,
174 .invert_tuple = udp_invert_tuple, 234 .invert_tuple = udp_invert_tuple,
@@ -182,7 +242,10 @@ struct nf_conntrack_protocol nf_conntrack_protocol_udp6 =
182 .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr, 242 .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr,
183 .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple, 243 .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple,
184#endif 244#endif
245#ifdef CONFIG_SYSCTL
246 .ctl_table_users = &udp_sysctl_table_users,
247 .ctl_table_header = &udp_sysctl_header,
248 .ctl_table = udp_sysctl_table,
249#endif
185}; 250};
186 251EXPORT_SYMBOL_GPL(nf_conntrack_l4proto_udp6);
187EXPORT_SYMBOL(nf_conntrack_protocol_udp4);
188EXPORT_SYMBOL(nf_conntrack_protocol_udp6);
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
new file mode 100644
index 0000000000..eb2a2411f9
--- /dev/null
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -0,0 +1,531 @@
1/* SIP extension for IP connection tracking.
2 *
3 * (C) 2005 by Christian Hentschel <chentschel@arnet.com.ar>
4 * based on RR's ip_conntrack_ftp.c and other modules.
5 *
6 * 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 * published by the Free Software Foundation.
9 */
10
11#include <linux/module.h>
12#include <linux/ctype.h>
13#include <linux/skbuff.h>
14#include <linux/inet.h>
15#include <linux/in.h>
16#include <linux/udp.h>
17#include <linux/netfilter.h>
18
19#include <net/netfilter/nf_conntrack.h>
20#include <net/netfilter/nf_conntrack_expect.h>
21#include <net/netfilter/nf_conntrack_helper.h>
22#include <linux/netfilter/nf_conntrack_sip.h>
23
24#if 0
25#define DEBUGP printk
26#else
27#define DEBUGP(format, args...)
28#endif
29
30MODULE_LICENSE("GPL");
31MODULE_AUTHOR("Christian Hentschel <chentschel@arnet.com.ar>");
32MODULE_DESCRIPTION("SIP connection tracking helper");
33MODULE_ALIAS("ip_conntrack_sip");
34
35#define MAX_PORTS 8
36static unsigned short ports[MAX_PORTS];
37static int ports_c;
38module_param_array(ports, ushort, &ports_c, 0400);
39MODULE_PARM_DESC(ports, "port numbers of SIP servers");
40
41static unsigned int sip_timeout __read_mostly = SIP_TIMEOUT;
42module_param(sip_timeout, uint, 0600);
43MODULE_PARM_DESC(sip_timeout, "timeout for the master SIP session");
44
45unsigned int (*nf_nat_sip_hook)(struct sk_buff **pskb,
46 enum ip_conntrack_info ctinfo,
47 struct nf_conn *ct,
48 const char **dptr) __read_mostly;
49EXPORT_SYMBOL_GPL(nf_nat_sip_hook);
50
51unsigned int (*nf_nat_sdp_hook)(struct sk_buff **pskb,
52 enum ip_conntrack_info ctinfo,
53 struct nf_conntrack_expect *exp,
54 const char *dptr) __read_mostly;
55EXPORT_SYMBOL_GPL(nf_nat_sdp_hook);
56
57static int digits_len(struct nf_conn *, const char *, const char *, int *);
58static int epaddr_len(struct nf_conn *, const char *, const char *, int *);
59static int skp_digits_len(struct nf_conn *, const char *, const char *, int *);
60static int skp_epaddr_len(struct nf_conn *, const char *, const char *, int *);
61
62struct sip_header_nfo {
63 const char *lname;
64 const char *sname;
65 const char *ln_str;
66 size_t lnlen;
67 size_t snlen;
68 size_t ln_strlen;
69 int case_sensitive;
70 int (*match_len)(struct nf_conn *, const char *,
71 const char *, int *);
72};
73
74static const struct sip_header_nfo ct_sip_hdrs[] = {
75 [POS_REG_REQ_URI] = { /* SIP REGISTER request URI */
76 .lname = "sip:",
77 .lnlen = sizeof("sip:") - 1,
78 .ln_str = ":",
79 .ln_strlen = sizeof(":") - 1,
80 .match_len = epaddr_len,
81 },
82 [POS_REQ_URI] = { /* SIP request URI */
83 .lname = "sip:",
84 .lnlen = sizeof("sip:") - 1,
85 .ln_str = "@",
86 .ln_strlen = sizeof("@") - 1,
87 .match_len = epaddr_len,
88 },
89 [POS_FROM] = { /* SIP From header */
90 .lname = "From:",
91 .lnlen = sizeof("From:") - 1,
92 .sname = "\r\nf:",
93 .snlen = sizeof("\r\nf:") - 1,
94 .ln_str = "sip:",
95 .ln_strlen = sizeof("sip:") - 1,
96 .match_len = skp_epaddr_len,
97 },
98 [POS_TO] = { /* SIP To header */
99 .lname = "To:",
100 .lnlen = sizeof("To:") - 1,
101 .sname = "\r\nt:",
102 .snlen = sizeof("\r\nt:") - 1,
103 .ln_str = "sip:",
104 .ln_strlen = sizeof("sip:") - 1,
105 .match_len = skp_epaddr_len
106 },
107 [POS_VIA] = { /* SIP Via header */
108 .lname = "Via:",
109 .lnlen = sizeof("Via:") - 1,
110 .sname = "\r\nv:",
111 .snlen = sizeof("\r\nv:") - 1, /* rfc3261 "\r\n" */
112 .ln_str = "UDP ",
113 .ln_strlen = sizeof("UDP ") - 1,
114 .match_len = epaddr_len,
115 },
116 [POS_CONTACT] = { /* SIP Contact header */
117 .lname = "Contact:",
118 .lnlen = sizeof("Contact:") - 1,
119 .sname = "\r\nm:",
120 .snlen = sizeof("\r\nm:") - 1,
121 .ln_str = "sip:",
122 .ln_strlen = sizeof("sip:") - 1,
123 .match_len = skp_epaddr_len
124 },
125 [POS_CONTENT] = { /* SIP Content length header */
126 .lname = "Content-Length:",
127 .lnlen = sizeof("Content-Length:") - 1,
128 .sname = "\r\nl:",
129 .snlen = sizeof("\r\nl:") - 1,
130 .ln_str = ":",
131 .ln_strlen = sizeof(":") - 1,
132 .match_len = skp_digits_len
133 },
134 [POS_MEDIA] = { /* SDP media info */
135 .case_sensitive = 1,
136 .lname = "\nm=",
137 .lnlen = sizeof("\nm=") - 1,
138 .sname = "\rm=",
139 .snlen = sizeof("\rm=") - 1,
140 .ln_str = "audio ",
141 .ln_strlen = sizeof("audio ") - 1,
142 .match_len = digits_len
143 },
144 [POS_OWNER_IP4] = { /* SDP owner address*/
145 .case_sensitive = 1,
146 .lname = "\no=",
147 .lnlen = sizeof("\no=") - 1,
148 .sname = "\ro=",
149 .snlen = sizeof("\ro=") - 1,
150 .ln_str = "IN IP4 ",
151 .ln_strlen = sizeof("IN IP4 ") - 1,
152 .match_len = epaddr_len
153 },
154 [POS_CONNECTION_IP4] = {/* SDP connection info */
155 .case_sensitive = 1,
156 .lname = "\nc=",
157 .lnlen = sizeof("\nc=") - 1,
158 .sname = "\rc=",
159 .snlen = sizeof("\rc=") - 1,
160 .ln_str = "IN IP4 ",
161 .ln_strlen = sizeof("IN IP4 ") - 1,
162 .match_len = epaddr_len
163 },
164 [POS_OWNER_IP6] = { /* SDP owner address*/
165 .case_sensitive = 1,
166 .lname = "\no=",
167 .lnlen = sizeof("\no=") - 1,
168 .sname = "\ro=",
169 .snlen = sizeof("\ro=") - 1,
170 .ln_str = "IN IP6 ",
171 .ln_strlen = sizeof("IN IP6 ") - 1,
172 .match_len = epaddr_len
173 },
174 [POS_CONNECTION_IP6] = {/* SDP connection info */
175 .case_sensitive = 1,
176 .lname = "\nc=",
177 .lnlen = sizeof("\nc=") - 1,
178 .sname = "\rc=",
179 .snlen = sizeof("\rc=") - 1,
180 .ln_str = "IN IP6 ",
181 .ln_strlen = sizeof("IN IP6 ") - 1,
182 .match_len = epaddr_len
183 },
184 [POS_SDP_HEADER] = { /* SDP version header */
185 .case_sensitive = 1,
186 .lname = "\nv=",
187 .lnlen = sizeof("\nv=") - 1,
188 .sname = "\rv=",
189 .snlen = sizeof("\rv=") - 1,
190 .ln_str = "=",
191 .ln_strlen = sizeof("=") - 1,
192 .match_len = digits_len
193 }
194};
195
196/* get line lenght until first CR or LF seen. */
197int ct_sip_lnlen(const char *line, const char *limit)
198{
199 const char *k = line;
200
201 while ((line <= limit) && (*line == '\r' || *line == '\n'))
202 line++;
203
204 while (line <= limit) {
205 if (*line == '\r' || *line == '\n')
206 break;
207 line++;
208 }
209 return line - k;
210}
211EXPORT_SYMBOL_GPL(ct_sip_lnlen);
212
213/* Linear string search, case sensitive. */
214const char *ct_sip_search(const char *needle, const char *haystack,
215 size_t needle_len, size_t haystack_len,
216 int case_sensitive)
217{
218 const char *limit = haystack + (haystack_len - needle_len);
219
220 while (haystack <= limit) {
221 if (case_sensitive) {
222 if (strncmp(haystack, needle, needle_len) == 0)
223 return haystack;
224 } else {
225 if (strnicmp(haystack, needle, needle_len) == 0)
226 return haystack;
227 }
228 haystack++;
229 }
230 return NULL;
231}
232EXPORT_SYMBOL_GPL(ct_sip_search);
233
234static int digits_len(struct nf_conn *ct, const char *dptr,
235 const char *limit, int *shift)
236{
237 int len = 0;
238 while (dptr <= limit && isdigit(*dptr)) {
239 dptr++;
240 len++;
241 }
242 return len;
243}
244
245/* get digits lenght, skiping blank spaces. */
246static int skp_digits_len(struct nf_conn *ct, const char *dptr,
247 const char *limit, int *shift)
248{
249 for (; dptr <= limit && *dptr == ' '; dptr++)
250 (*shift)++;
251
252 return digits_len(ct, dptr, limit, shift);
253}
254
255static int parse_addr(struct nf_conn *ct, const char *cp, const char **endp,
256 union nf_conntrack_address *addr, const char *limit)
257{
258 const char *end;
259 int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
260 int ret = 0;
261
262 switch (family) {
263 case AF_INET:
264 ret = in4_pton(cp, limit - cp, (u8 *)&addr->ip, -1, &end);
265 break;
266 case AF_INET6:
267 ret = in6_pton(cp, limit - cp, (u8 *)&addr->ip6, -1, &end);
268 break;
269 default:
270 BUG();
271 }
272
273 if (ret == 0 || end == cp)
274 return 0;
275 if (endp)
276 *endp = end;
277 return 1;
278}
279
280/* skip ip address. returns its length. */
281static int epaddr_len(struct nf_conn *ct, const char *dptr,
282 const char *limit, int *shift)
283{
284 union nf_conntrack_address addr;
285 const char *aux = dptr;
286
287 if (!parse_addr(ct, dptr, &dptr, &addr, limit)) {
288 DEBUGP("ip: %s parse failed.!\n", dptr);
289 return 0;
290 }
291
292 /* Port number */
293 if (*dptr == ':') {
294 dptr++;
295 dptr += digits_len(ct, dptr, limit, shift);
296 }
297 return dptr - aux;
298}
299
300/* get address length, skiping user info. */
301static int skp_epaddr_len(struct nf_conn *ct, const char *dptr,
302 const char *limit, int *shift)
303{
304 int s = *shift;
305
306 for (; dptr <= limit && *dptr != '@'; dptr++)
307 (*shift)++;
308
309 if (*dptr == '@') {
310 dptr++;
311 (*shift)++;
312 } else
313 *shift = s;
314
315 return epaddr_len(ct, dptr, limit, shift);
316}
317
318/* Returns 0 if not found, -1 error parsing. */
319int ct_sip_get_info(struct nf_conn *ct,
320 const char *dptr, size_t dlen,
321 unsigned int *matchoff,
322 unsigned int *matchlen,
323 enum sip_header_pos pos)
324{
325 const struct sip_header_nfo *hnfo = &ct_sip_hdrs[pos];
326 const char *limit, *aux, *k = dptr;
327 int shift = 0;
328
329 limit = dptr + (dlen - hnfo->lnlen);
330
331 while (dptr <= limit) {
332 if ((strncmp(dptr, hnfo->lname, hnfo->lnlen) != 0) &&
333 (strncmp(dptr, hnfo->sname, hnfo->snlen) != 0)) {
334 dptr++;
335 continue;
336 }
337 aux = ct_sip_search(hnfo->ln_str, dptr, hnfo->ln_strlen,
338 ct_sip_lnlen(dptr, limit),
339 hnfo->case_sensitive);
340 if (!aux) {
341 DEBUGP("'%s' not found in '%s'.\n", hnfo->ln_str,
342 hnfo->lname);
343 return -1;
344 }
345 aux += hnfo->ln_strlen;
346
347 *matchlen = hnfo->match_len(ct, aux, limit, &shift);
348 if (!*matchlen)
349 return -1;
350
351 *matchoff = (aux - k) + shift;
352
353 DEBUGP("%s match succeeded! - len: %u\n", hnfo->lname,
354 *matchlen);
355 return 1;
356 }
357 DEBUGP("%s header not found.\n", hnfo->lname);
358 return 0;
359}
360EXPORT_SYMBOL_GPL(ct_sip_get_info);
361
362static int set_expected_rtp(struct sk_buff **pskb,
363 struct nf_conn *ct,
364 enum ip_conntrack_info ctinfo,
365 union nf_conntrack_address *addr,
366 __be16 port,
367 const char *dptr)
368{
369 struct nf_conntrack_expect *exp;
370 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
371 int family = ct->tuplehash[!dir].tuple.src.l3num;
372 int ret;
373 typeof(nf_nat_sdp_hook) nf_nat_sdp;
374
375 exp = nf_conntrack_expect_alloc(ct);
376 if (exp == NULL)
377 return NF_DROP;
378 nf_conntrack_expect_init(exp, family,
379 &ct->tuplehash[!dir].tuple.src.u3, addr,
380 IPPROTO_UDP, NULL, &port);
381
382 nf_nat_sdp = rcu_dereference(nf_nat_sdp_hook);
383 if (nf_nat_sdp && ct->status & IPS_NAT_MASK)
384 ret = nf_nat_sdp(pskb, ctinfo, exp, dptr);
385 else {
386 if (nf_conntrack_expect_related(exp) != 0)
387 ret = NF_DROP;
388 else
389 ret = NF_ACCEPT;
390 }
391 nf_conntrack_expect_put(exp);
392
393 return ret;
394}
395
396static int sip_help(struct sk_buff **pskb,
397 unsigned int protoff,
398 struct nf_conn *ct,
399 enum ip_conntrack_info ctinfo)
400{
401 int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
402 union nf_conntrack_address addr;
403 unsigned int dataoff, datalen;
404 const char *dptr;
405 int ret = NF_ACCEPT;
406 int matchoff, matchlen;
407 u_int16_t port;
408 enum sip_header_pos pos;
409 typeof(nf_nat_sip_hook) nf_nat_sip;
410
411 /* No Data ? */
412 dataoff = protoff + sizeof(struct udphdr);
413 if (dataoff >= (*pskb)->len)
414 return NF_ACCEPT;
415
416 nf_ct_refresh(ct, *pskb, sip_timeout * HZ);
417
418 if (!skb_is_nonlinear(*pskb))
419 dptr = (*pskb)->data + dataoff;
420 else {
421 DEBUGP("Copy of skbuff not supported yet.\n");
422 goto out;
423 }
424
425 nf_nat_sip = rcu_dereference(nf_nat_sip_hook);
426 if (nf_nat_sip && ct->status & IPS_NAT_MASK) {
427 if (!nf_nat_sip(pskb, ctinfo, ct, &dptr)) {
428 ret = NF_DROP;
429 goto out;
430 }
431 }
432
433 datalen = (*pskb)->len - dataoff;
434 if (datalen < sizeof("SIP/2.0 200") - 1)
435 goto out;
436
437 /* RTP info only in some SDP pkts */
438 if (memcmp(dptr, "INVITE", sizeof("INVITE") - 1) != 0 &&
439 memcmp(dptr, "SIP/2.0 200", sizeof("SIP/2.0 200") - 1) != 0) {
440 goto out;
441 }
442 /* Get address and port from SDP packet. */
443 pos = family == AF_INET ? POS_CONNECTION_IP4 : POS_CONNECTION_IP6;
444 if (ct_sip_get_info(ct, dptr, datalen, &matchoff, &matchlen, pos) > 0) {
445
446 /* We'll drop only if there are parse problems. */
447 if (!parse_addr(ct, dptr + matchoff, NULL, &addr,
448 dptr + datalen)) {
449 ret = NF_DROP;
450 goto out;
451 }
452 if (ct_sip_get_info(ct, dptr, datalen, &matchoff, &matchlen,
453 POS_MEDIA) > 0) {
454
455 port = simple_strtoul(dptr + matchoff, NULL, 10);
456 if (port < 1024) {
457 ret = NF_DROP;
458 goto out;
459 }
460 ret = set_expected_rtp(pskb, ct, ctinfo, &addr,
461 htons(port), dptr);
462 }
463 }
464out:
465 return ret;
466}
467
468static struct nf_conntrack_helper sip[MAX_PORTS][2] __read_mostly;
469static char sip_names[MAX_PORTS][2][sizeof("sip-65535")] __read_mostly;
470
471static void nf_conntrack_sip_fini(void)
472{
473 int i, j;
474
475 for (i = 0; i < ports_c; i++) {
476 for (j = 0; j < 2; j++) {
477 if (sip[i][j].me == NULL)
478 continue;
479 nf_conntrack_helper_unregister(&sip[i][j]);
480 }
481 }
482}
483
484static int __init nf_conntrack_sip_init(void)
485{
486 int i, j, ret;
487 char *tmpname;
488
489 if (ports_c == 0)
490 ports[ports_c++] = SIP_PORT;
491
492 for (i = 0; i < ports_c; i++) {
493 memset(&sip[i], 0, sizeof(sip[i]));
494
495 sip[i][0].tuple.src.l3num = AF_INET;
496 sip[i][1].tuple.src.l3num = AF_INET6;
497 for (j = 0; j < 2; j++) {
498 sip[i][j].tuple.dst.protonum = IPPROTO_UDP;
499 sip[i][j].tuple.src.u.udp.port = htons(ports[i]);
500 sip[i][j].mask.src.l3num = 0xFFFF;
501 sip[i][j].mask.src.u.udp.port = htons(0xFFFF);
502 sip[i][j].mask.dst.protonum = 0xFF;
503 sip[i][j].max_expected = 2;
504 sip[i][j].timeout = 3 * 60; /* 3 minutes */
505 sip[i][j].me = THIS_MODULE;
506 sip[i][j].help = sip_help;
507
508 tmpname = &sip_names[i][j][0];
509 if (ports[i] == SIP_PORT)
510 sprintf(tmpname, "sip");
511 else
512 sprintf(tmpname, "sip-%u", i);
513 sip[i][j].name = tmpname;
514
515 DEBUGP("port #%u: %u\n", i, ports[i]);
516
517 ret = nf_conntrack_helper_register(&sip[i][j]);
518 if (ret) {
519 printk("nf_ct_sip: failed to register helper "
520 "for pf: %u port: %u\n",
521 sip[i][j].tuple.src.l3num, ports[i]);
522 nf_conntrack_sip_fini();
523 return ret;
524 }
525 }
526 }
527 return 0;
528}
529
530module_init(nf_conntrack_sip_init);
531module_exit(nf_conntrack_sip_fini);
diff --git a/net/netfilter/nf_conntrack_standalone.c b/net/netfilter/nf_conntrack_standalone.c
index 5954f67738..f1cb60ff93 100644
--- a/net/netfilter/nf_conntrack_standalone.c
+++ b/net/netfilter/nf_conntrack_standalone.c
@@ -29,13 +29,11 @@
29#include <linux/sysctl.h> 29#include <linux/sysctl.h>
30#endif 30#endif
31 31
32#define ASSERT_READ_LOCK(x)
33#define ASSERT_WRITE_LOCK(x)
34
35#include <net/netfilter/nf_conntrack.h> 32#include <net/netfilter/nf_conntrack.h>
36#include <net/netfilter/nf_conntrack_l3proto.h>
37#include <net/netfilter/nf_conntrack_protocol.h>
38#include <net/netfilter/nf_conntrack_core.h> 33#include <net/netfilter/nf_conntrack_core.h>
34#include <net/netfilter/nf_conntrack_l3proto.h>
35#include <net/netfilter/nf_conntrack_l4proto.h>
36#include <net/netfilter/nf_conntrack_expect.h>
39#include <net/netfilter/nf_conntrack_helper.h> 37#include <net/netfilter/nf_conntrack_helper.h>
40 38
41#if 0 39#if 0
@@ -46,33 +44,15 @@
46 44
47MODULE_LICENSE("GPL"); 45MODULE_LICENSE("GPL");
48 46
49extern atomic_t nf_conntrack_count;
50DECLARE_PER_CPU(struct ip_conntrack_stat, nf_conntrack_stat);
51
52static int kill_l3proto(struct nf_conn *i, void *data)
53{
54 return (i->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num ==
55 ((struct nf_conntrack_l3proto *)data)->l3proto);
56}
57
58static int kill_proto(struct nf_conn *i, void *data)
59{
60 struct nf_conntrack_protocol *proto;
61 proto = (struct nf_conntrack_protocol *)data;
62 return (i->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum ==
63 proto->proto) &&
64 (i->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num ==
65 proto->l3proto);
66}
67
68#ifdef CONFIG_PROC_FS 47#ifdef CONFIG_PROC_FS
69static int 48int
70print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple, 49print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple,
71 struct nf_conntrack_l3proto *l3proto, 50 struct nf_conntrack_l3proto *l3proto,
72 struct nf_conntrack_protocol *proto) 51 struct nf_conntrack_l4proto *l4proto)
73{ 52{
74 return l3proto->print_tuple(s, tuple) || proto->print_tuple(s, tuple); 53 return l3proto->print_tuple(s, tuple) || l4proto->print_tuple(s, tuple);
75} 54}
55EXPORT_SYMBOL_GPL(print_tuple);
76 56
77#ifdef CONFIG_NF_CT_ACCT 57#ifdef CONFIG_NF_CT_ACCT
78static unsigned int 58static unsigned int
@@ -150,9 +130,8 @@ static int ct_seq_show(struct seq_file *s, void *v)
150 const struct nf_conntrack_tuple_hash *hash = v; 130 const struct nf_conntrack_tuple_hash *hash = v;
151 const struct nf_conn *conntrack = nf_ct_tuplehash_to_ctrack(hash); 131 const struct nf_conn *conntrack = nf_ct_tuplehash_to_ctrack(hash);
152 struct nf_conntrack_l3proto *l3proto; 132 struct nf_conntrack_l3proto *l3proto;
153 struct nf_conntrack_protocol *proto; 133 struct nf_conntrack_l4proto *l4proto;
154 134
155 ASSERT_READ_LOCK(&nf_conntrack_lock);
156 NF_CT_ASSERT(conntrack); 135 NF_CT_ASSERT(conntrack);
157 136
158 /* we only want to print DIR_ORIGINAL */ 137 /* we only want to print DIR_ORIGINAL */
@@ -163,16 +142,16 @@ static int ct_seq_show(struct seq_file *s, void *v)
163 .tuple.src.l3num); 142 .tuple.src.l3num);
164 143
165 NF_CT_ASSERT(l3proto); 144 NF_CT_ASSERT(l3proto);
166 proto = __nf_ct_proto_find(conntrack->tuplehash[IP_CT_DIR_ORIGINAL] 145 l4proto = __nf_ct_l4proto_find(conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
167 .tuple.src.l3num, 146 .tuple.src.l3num,
168 conntrack->tuplehash[IP_CT_DIR_ORIGINAL] 147 conntrack->tuplehash[IP_CT_DIR_ORIGINAL]
169 .tuple.dst.protonum); 148 .tuple.dst.protonum);
170 NF_CT_ASSERT(proto); 149 NF_CT_ASSERT(l4proto);
171 150
172 if (seq_printf(s, "%-8s %u %-8s %u %ld ", 151 if (seq_printf(s, "%-8s %u %-8s %u %ld ",
173 l3proto->name, 152 l3proto->name,
174 conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num, 153 conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num,
175 proto->name, 154 l4proto->name,
176 conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum, 155 conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.protonum,
177 timer_pending(&conntrack->timeout) 156 timer_pending(&conntrack->timeout)
178 ? (long)(conntrack->timeout.expires - jiffies)/HZ : 0) != 0) 157 ? (long)(conntrack->timeout.expires - jiffies)/HZ : 0) != 0)
@@ -181,11 +160,11 @@ static int ct_seq_show(struct seq_file *s, void *v)
181 if (l3proto->print_conntrack(s, conntrack)) 160 if (l3proto->print_conntrack(s, conntrack))
182 return -ENOSPC; 161 return -ENOSPC;
183 162
184 if (proto->print_conntrack(s, conntrack)) 163 if (l4proto->print_conntrack(s, conntrack))
185 return -ENOSPC; 164 return -ENOSPC;
186 165
187 if (print_tuple(s, &conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple, 166 if (print_tuple(s, &conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
188 l3proto, proto)) 167 l3proto, l4proto))
189 return -ENOSPC; 168 return -ENOSPC;
190 169
191 if (seq_print_counters(s, &conntrack->counters[IP_CT_DIR_ORIGINAL])) 170 if (seq_print_counters(s, &conntrack->counters[IP_CT_DIR_ORIGINAL]))
@@ -196,7 +175,7 @@ static int ct_seq_show(struct seq_file *s, void *v)
196 return -ENOSPC; 175 return -ENOSPC;
197 176
198 if (print_tuple(s, &conntrack->tuplehash[IP_CT_DIR_REPLY].tuple, 177 if (print_tuple(s, &conntrack->tuplehash[IP_CT_DIR_REPLY].tuple,
199 l3proto, proto)) 178 l3proto, l4proto))
200 return -ENOSPC; 179 return -ENOSPC;
201 180
202 if (seq_print_counters(s, &conntrack->counters[IP_CT_DIR_REPLY])) 181 if (seq_print_counters(s, &conntrack->counters[IP_CT_DIR_REPLY]))
@@ -258,84 +237,6 @@ static struct file_operations ct_file_ops = {
258 .release = seq_release_private, 237 .release = seq_release_private,
259}; 238};
260 239
261/* expects */
262static void *exp_seq_start(struct seq_file *s, loff_t *pos)
263{
264 struct list_head *e = &nf_conntrack_expect_list;
265 loff_t i;
266
267 /* strange seq_file api calls stop even if we fail,
268 * thus we need to grab lock since stop unlocks */
269 read_lock_bh(&nf_conntrack_lock);
270
271 if (list_empty(e))
272 return NULL;
273
274 for (i = 0; i <= *pos; i++) {
275 e = e->next;
276 if (e == &nf_conntrack_expect_list)
277 return NULL;
278 }
279 return e;
280}
281
282static void *exp_seq_next(struct seq_file *s, void *v, loff_t *pos)
283{
284 struct list_head *e = v;
285
286 ++*pos;
287 e = e->next;
288
289 if (e == &nf_conntrack_expect_list)
290 return NULL;
291
292 return e;
293}
294
295static void exp_seq_stop(struct seq_file *s, void *v)
296{
297 read_unlock_bh(&nf_conntrack_lock);
298}
299
300static int exp_seq_show(struct seq_file *s, void *v)
301{
302 struct nf_conntrack_expect *expect = v;
303
304 if (expect->timeout.function)
305 seq_printf(s, "%ld ", timer_pending(&expect->timeout)
306 ? (long)(expect->timeout.expires - jiffies)/HZ : 0);
307 else
308 seq_printf(s, "- ");
309 seq_printf(s, "l3proto = %u proto=%u ",
310 expect->tuple.src.l3num,
311 expect->tuple.dst.protonum);
312 print_tuple(s, &expect->tuple,
313 __nf_ct_l3proto_find(expect->tuple.src.l3num),
314 __nf_ct_proto_find(expect->tuple.src.l3num,
315 expect->tuple.dst.protonum));
316 return seq_putc(s, '\n');
317}
318
319static struct seq_operations exp_seq_ops = {
320 .start = exp_seq_start,
321 .next = exp_seq_next,
322 .stop = exp_seq_stop,
323 .show = exp_seq_show
324};
325
326static int exp_open(struct inode *inode, struct file *file)
327{
328 return seq_open(file, &exp_seq_ops);
329}
330
331static struct file_operations exp_file_ops = {
332 .owner = THIS_MODULE,
333 .open = exp_open,
334 .read = seq_read,
335 .llseek = seq_lseek,
336 .release = seq_release
337};
338
339static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos) 240static void *ct_cpu_seq_start(struct seq_file *seq, loff_t *pos)
340{ 241{
341 int cpu; 242 int cpu;
@@ -428,34 +329,9 @@ static struct file_operations ct_cpu_seq_fops = {
428/* Sysctl support */ 329/* Sysctl support */
429 330
430int nf_conntrack_checksum __read_mostly = 1; 331int nf_conntrack_checksum __read_mostly = 1;
332EXPORT_SYMBOL_GPL(nf_conntrack_checksum);
431 333
432#ifdef CONFIG_SYSCTL 334#ifdef CONFIG_SYSCTL
433
434/* From nf_conntrack_core.c */
435extern int nf_conntrack_max;
436extern unsigned int nf_conntrack_htable_size;
437
438/* From nf_conntrack_proto_tcp.c */
439extern unsigned int nf_ct_tcp_timeout_syn_sent;
440extern unsigned int nf_ct_tcp_timeout_syn_recv;
441extern unsigned int nf_ct_tcp_timeout_established;
442extern unsigned int nf_ct_tcp_timeout_fin_wait;
443extern unsigned int nf_ct_tcp_timeout_close_wait;
444extern unsigned int nf_ct_tcp_timeout_last_ack;
445extern unsigned int nf_ct_tcp_timeout_time_wait;
446extern unsigned int nf_ct_tcp_timeout_close;
447extern unsigned int nf_ct_tcp_timeout_max_retrans;
448extern int nf_ct_tcp_loose;
449extern int nf_ct_tcp_be_liberal;
450extern int nf_ct_tcp_max_retrans;
451
452/* From nf_conntrack_proto_udp.c */
453extern unsigned int nf_ct_udp_timeout;
454extern unsigned int nf_ct_udp_timeout_stream;
455
456/* From nf_conntrack_proto_generic.c */
457extern unsigned int nf_ct_generic_timeout;
458
459/* Log invalid packets of a given protocol */ 335/* Log invalid packets of a given protocol */
460static int log_invalid_proto_min = 0; 336static int log_invalid_proto_min = 0;
461static int log_invalid_proto_max = 255; 337static int log_invalid_proto_max = 255;
@@ -496,94 +372,6 @@ static ctl_table nf_ct_sysctl_table[] = {
496 .proc_handler = &proc_dointvec, 372 .proc_handler = &proc_dointvec,
497 }, 373 },
498 { 374 {
499 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT,
500 .procname = "nf_conntrack_tcp_timeout_syn_sent",
501 .data = &nf_ct_tcp_timeout_syn_sent,
502 .maxlen = sizeof(unsigned int),
503 .mode = 0644,
504 .proc_handler = &proc_dointvec_jiffies,
505 },
506 {
507 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV,
508 .procname = "nf_conntrack_tcp_timeout_syn_recv",
509 .data = &nf_ct_tcp_timeout_syn_recv,
510 .maxlen = sizeof(unsigned int),
511 .mode = 0644,
512 .proc_handler = &proc_dointvec_jiffies,
513 },
514 {
515 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED,
516 .procname = "nf_conntrack_tcp_timeout_established",
517 .data = &nf_ct_tcp_timeout_established,
518 .maxlen = sizeof(unsigned int),
519 .mode = 0644,
520 .proc_handler = &proc_dointvec_jiffies,
521 },
522 {
523 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT,
524 .procname = "nf_conntrack_tcp_timeout_fin_wait",
525 .data = &nf_ct_tcp_timeout_fin_wait,
526 .maxlen = sizeof(unsigned int),
527 .mode = 0644,
528 .proc_handler = &proc_dointvec_jiffies,
529 },
530 {
531 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT,
532 .procname = "nf_conntrack_tcp_timeout_close_wait",
533 .data = &nf_ct_tcp_timeout_close_wait,
534 .maxlen = sizeof(unsigned int),
535 .mode = 0644,
536 .proc_handler = &proc_dointvec_jiffies,
537 },
538 {
539 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK,
540 .procname = "nf_conntrack_tcp_timeout_last_ack",
541 .data = &nf_ct_tcp_timeout_last_ack,
542 .maxlen = sizeof(unsigned int),
543 .mode = 0644,
544 .proc_handler = &proc_dointvec_jiffies,
545 },
546 {
547 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT,
548 .procname = "nf_conntrack_tcp_timeout_time_wait",
549 .data = &nf_ct_tcp_timeout_time_wait,
550 .maxlen = sizeof(unsigned int),
551 .mode = 0644,
552 .proc_handler = &proc_dointvec_jiffies,
553 },
554 {
555 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_CLOSE,
556 .procname = "nf_conntrack_tcp_timeout_close",
557 .data = &nf_ct_tcp_timeout_close,
558 .maxlen = sizeof(unsigned int),
559 .mode = 0644,
560 .proc_handler = &proc_dointvec_jiffies,
561 },
562 {
563 .ctl_name = NET_NF_CONNTRACK_UDP_TIMEOUT,
564 .procname = "nf_conntrack_udp_timeout",
565 .data = &nf_ct_udp_timeout,
566 .maxlen = sizeof(unsigned int),
567 .mode = 0644,
568 .proc_handler = &proc_dointvec_jiffies,
569 },
570 {
571 .ctl_name = NET_NF_CONNTRACK_UDP_TIMEOUT_STREAM,
572 .procname = "nf_conntrack_udp_timeout_stream",
573 .data = &nf_ct_udp_timeout_stream,
574 .maxlen = sizeof(unsigned int),
575 .mode = 0644,
576 .proc_handler = &proc_dointvec_jiffies,
577 },
578 {
579 .ctl_name = NET_NF_CONNTRACK_GENERIC_TIMEOUT,
580 .procname = "nf_conntrack_generic_timeout",
581 .data = &nf_ct_generic_timeout,
582 .maxlen = sizeof(unsigned int),
583 .mode = 0644,
584 .proc_handler = &proc_dointvec_jiffies,
585 },
586 {
587 .ctl_name = NET_NF_CONNTRACK_LOG_INVALID, 375 .ctl_name = NET_NF_CONNTRACK_LOG_INVALID,
588 .procname = "nf_conntrack_log_invalid", 376 .procname = "nf_conntrack_log_invalid",
589 .data = &nf_ct_log_invalid, 377 .data = &nf_ct_log_invalid,
@@ -594,38 +382,6 @@ static ctl_table nf_ct_sysctl_table[] = {
594 .extra1 = &log_invalid_proto_min, 382 .extra1 = &log_invalid_proto_min,
595 .extra2 = &log_invalid_proto_max, 383 .extra2 = &log_invalid_proto_max,
596 }, 384 },
597 {
598 .ctl_name = NET_NF_CONNTRACK_TCP_TIMEOUT_MAX_RETRANS,
599 .procname = "nf_conntrack_tcp_timeout_max_retrans",
600 .data = &nf_ct_tcp_timeout_max_retrans,
601 .maxlen = sizeof(unsigned int),
602 .mode = 0644,
603 .proc_handler = &proc_dointvec_jiffies,
604 },
605 {
606 .ctl_name = NET_NF_CONNTRACK_TCP_LOOSE,
607 .procname = "nf_conntrack_tcp_loose",
608 .data = &nf_ct_tcp_loose,
609 .maxlen = sizeof(unsigned int),
610 .mode = 0644,
611 .proc_handler = &proc_dointvec,
612 },
613 {
614 .ctl_name = NET_NF_CONNTRACK_TCP_BE_LIBERAL,
615 .procname = "nf_conntrack_tcp_be_liberal",
616 .data = &nf_ct_tcp_be_liberal,
617 .maxlen = sizeof(unsigned int),
618 .mode = 0644,
619 .proc_handler = &proc_dointvec,
620 },
621 {
622 .ctl_name = NET_NF_CONNTRACK_TCP_MAX_RETRANS,
623 .procname = "nf_conntrack_tcp_max_retrans",
624 .data = &nf_ct_tcp_max_retrans,
625 .maxlen = sizeof(unsigned int),
626 .mode = 0644,
627 .proc_handler = &proc_dointvec,
628 },
629 385
630 { .ctl_name = 0 } 386 { .ctl_name = 0 }
631}; 387};
@@ -659,109 +415,9 @@ static ctl_table nf_ct_net_table[] = {
659 }, 415 },
660 { .ctl_name = 0 } 416 { .ctl_name = 0 }
661}; 417};
662EXPORT_SYMBOL(nf_ct_log_invalid); 418EXPORT_SYMBOL_GPL(nf_ct_log_invalid);
663#endif /* CONFIG_SYSCTL */ 419#endif /* CONFIG_SYSCTL */
664 420
665int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto)
666{
667 int ret = 0;
668
669 write_lock_bh(&nf_conntrack_lock);
670 if (nf_ct_l3protos[proto->l3proto] != &nf_conntrack_generic_l3proto) {
671 ret = -EBUSY;
672 goto out;
673 }
674 nf_ct_l3protos[proto->l3proto] = proto;
675out:
676 write_unlock_bh(&nf_conntrack_lock);
677
678 return ret;
679}
680
681void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto)
682{
683 write_lock_bh(&nf_conntrack_lock);
684 nf_ct_l3protos[proto->l3proto] = &nf_conntrack_generic_l3proto;
685 write_unlock_bh(&nf_conntrack_lock);
686
687 /* Somebody could be still looking at the proto in bh. */
688 synchronize_net();
689
690 /* Remove all contrack entries for this protocol */
691 nf_ct_iterate_cleanup(kill_l3proto, proto);
692}
693
694/* FIXME: Allow NULL functions and sub in pointers to generic for
695 them. --RR */
696int nf_conntrack_protocol_register(struct nf_conntrack_protocol *proto)
697{
698 int ret = 0;
699
700retry:
701 write_lock_bh(&nf_conntrack_lock);
702 if (nf_ct_protos[proto->l3proto]) {
703 if (nf_ct_protos[proto->l3proto][proto->proto]
704 != &nf_conntrack_generic_protocol) {
705 ret = -EBUSY;
706 goto out_unlock;
707 }
708 } else {
709 /* l3proto may be loaded latter. */
710 struct nf_conntrack_protocol **proto_array;
711 int i;
712
713 write_unlock_bh(&nf_conntrack_lock);
714
715 proto_array = (struct nf_conntrack_protocol **)
716 kmalloc(MAX_NF_CT_PROTO *
717 sizeof(struct nf_conntrack_protocol *),
718 GFP_KERNEL);
719 if (proto_array == NULL) {
720 ret = -ENOMEM;
721 goto out;
722 }
723 for (i = 0; i < MAX_NF_CT_PROTO; i++)
724 proto_array[i] = &nf_conntrack_generic_protocol;
725
726 write_lock_bh(&nf_conntrack_lock);
727 if (nf_ct_protos[proto->l3proto]) {
728 /* bad timing, but no problem */
729 write_unlock_bh(&nf_conntrack_lock);
730 kfree(proto_array);
731 } else {
732 nf_ct_protos[proto->l3proto] = proto_array;
733 write_unlock_bh(&nf_conntrack_lock);
734 }
735
736 /*
737 * Just once because array is never freed until unloading
738 * nf_conntrack.ko
739 */
740 goto retry;
741 }
742
743 nf_ct_protos[proto->l3proto][proto->proto] = proto;
744
745out_unlock:
746 write_unlock_bh(&nf_conntrack_lock);
747out:
748 return ret;
749}
750
751void nf_conntrack_protocol_unregister(struct nf_conntrack_protocol *proto)
752{
753 write_lock_bh(&nf_conntrack_lock);
754 nf_ct_protos[proto->l3proto][proto->proto]
755 = &nf_conntrack_generic_protocol;
756 write_unlock_bh(&nf_conntrack_lock);
757
758 /* Somebody could be still looking at the proto in bh. */
759 synchronize_net();
760
761 /* Remove all contrack entries for this protocol */
762 nf_ct_iterate_cleanup(kill_proto, proto);
763}
764
765static int __init nf_conntrack_standalone_init(void) 421static int __init nf_conntrack_standalone_init(void)
766{ 422{
767#ifdef CONFIG_PROC_FS 423#ifdef CONFIG_PROC_FS
@@ -834,70 +490,4 @@ module_exit(nf_conntrack_standalone_fini);
834void need_conntrack(void) 490void need_conntrack(void)
835{ 491{
836} 492}
837 493EXPORT_SYMBOL_GPL(need_conntrack);
838#ifdef CONFIG_NF_CONNTRACK_EVENTS
839EXPORT_SYMBOL_GPL(nf_conntrack_chain);
840EXPORT_SYMBOL_GPL(nf_conntrack_expect_chain);
841EXPORT_SYMBOL_GPL(nf_conntrack_register_notifier);
842EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
843EXPORT_SYMBOL_GPL(__nf_ct_event_cache_init);
844EXPORT_PER_CPU_SYMBOL_GPL(nf_conntrack_ecache);
845EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
846#endif
847EXPORT_SYMBOL(nf_ct_l3proto_try_module_get);
848EXPORT_SYMBOL(nf_ct_l3proto_module_put);
849EXPORT_SYMBOL(nf_conntrack_l3proto_register);
850EXPORT_SYMBOL(nf_conntrack_l3proto_unregister);
851EXPORT_SYMBOL(nf_conntrack_protocol_register);
852EXPORT_SYMBOL(nf_conntrack_protocol_unregister);
853EXPORT_SYMBOL(nf_ct_invert_tuplepr);
854EXPORT_SYMBOL(nf_conntrack_destroyed);
855EXPORT_SYMBOL(need_conntrack);
856EXPORT_SYMBOL(nf_conntrack_helper_register);
857EXPORT_SYMBOL(nf_conntrack_helper_unregister);
858EXPORT_SYMBOL(nf_ct_iterate_cleanup);
859EXPORT_SYMBOL(__nf_ct_refresh_acct);
860EXPORT_SYMBOL(nf_ct_protos);
861EXPORT_SYMBOL(__nf_ct_proto_find);
862EXPORT_SYMBOL(nf_ct_proto_find_get);
863EXPORT_SYMBOL(nf_ct_proto_put);
864EXPORT_SYMBOL(nf_ct_l3proto_find_get);
865EXPORT_SYMBOL(nf_ct_l3proto_put);
866EXPORT_SYMBOL(nf_ct_l3protos);
867EXPORT_SYMBOL_GPL(nf_conntrack_checksum);
868EXPORT_SYMBOL(nf_conntrack_expect_alloc);
869EXPORT_SYMBOL(nf_conntrack_expect_put);
870EXPORT_SYMBOL(nf_conntrack_expect_related);
871EXPORT_SYMBOL(nf_conntrack_unexpect_related);
872EXPORT_SYMBOL(nf_conntrack_tuple_taken);
873EXPORT_SYMBOL(nf_conntrack_htable_size);
874EXPORT_SYMBOL(nf_conntrack_lock);
875EXPORT_SYMBOL(nf_conntrack_hash);
876EXPORT_SYMBOL(nf_conntrack_untracked);
877EXPORT_SYMBOL_GPL(nf_conntrack_find_get);
878#ifdef CONFIG_IP_NF_NAT_NEEDED
879EXPORT_SYMBOL(nf_conntrack_tcp_update);
880#endif
881EXPORT_SYMBOL(__nf_conntrack_confirm);
882EXPORT_SYMBOL(nf_ct_get_tuple);
883EXPORT_SYMBOL(nf_ct_invert_tuple);
884EXPORT_SYMBOL(nf_conntrack_in);
885EXPORT_SYMBOL(__nf_conntrack_attach);
886EXPORT_SYMBOL(nf_conntrack_alloc);
887EXPORT_SYMBOL(nf_conntrack_free);
888EXPORT_SYMBOL(nf_conntrack_flush);
889EXPORT_SYMBOL(nf_ct_remove_expectations);
890EXPORT_SYMBOL(nf_ct_helper_find_get);
891EXPORT_SYMBOL(nf_ct_helper_put);
892EXPORT_SYMBOL(__nf_conntrack_helper_find_byname);
893EXPORT_SYMBOL(__nf_conntrack_find);
894EXPORT_SYMBOL(nf_ct_unlink_expect);
895EXPORT_SYMBOL(nf_conntrack_hash_insert);
896EXPORT_SYMBOL(__nf_conntrack_expect_find);
897EXPORT_SYMBOL(nf_conntrack_expect_find);
898EXPORT_SYMBOL(nf_conntrack_expect_list);
899#if defined(CONFIG_NF_CT_NETLINK) || \
900 defined(CONFIG_NF_CT_NETLINK_MODULE)
901EXPORT_SYMBOL(nf_ct_port_tuple_to_nfattr);
902EXPORT_SYMBOL(nf_ct_port_nfattr_to_tuple);
903#endif
diff --git a/net/netfilter/nf_conntrack_tftp.c b/net/netfilter/nf_conntrack_tftp.c
new file mode 100644
index 0000000000..f5bffe24b0
--- /dev/null
+++ b/net/netfilter/nf_conntrack_tftp.c
@@ -0,0 +1,160 @@
1/* (C) 2001-2002 Magnus Boden <mb@ozaba.mine.nu>
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 as
5 * published by the Free Software Foundation.
6 */
7
8#include <linux/module.h>
9#include <linux/moduleparam.h>
10#include <linux/in.h>
11#include <linux/udp.h>
12#include <linux/netfilter.h>
13
14#include <net/netfilter/nf_conntrack.h>
15#include <net/netfilter/nf_conntrack_tuple.h>
16#include <net/netfilter/nf_conntrack_expect.h>
17#include <net/netfilter/nf_conntrack_ecache.h>
18#include <net/netfilter/nf_conntrack_helper.h>
19#include <linux/netfilter/nf_conntrack_tftp.h>
20
21MODULE_AUTHOR("Magnus Boden <mb@ozaba.mine.nu>");
22MODULE_DESCRIPTION("TFTP connection tracking helper");
23MODULE_LICENSE("GPL");
24MODULE_ALIAS("ip_conntrack_tftp");
25
26#define MAX_PORTS 8
27static unsigned short ports[MAX_PORTS];
28static int ports_c;
29module_param_array(ports, ushort, &ports_c, 0400);
30MODULE_PARM_DESC(ports, "Port numbers of TFTP servers");
31
32#if 0
33#define DEBUGP(format, args...) printk("%s:%s:" format, \
34 __FILE__, __FUNCTION__ , ## args)
35#else
36#define DEBUGP(format, args...)
37#endif
38
39unsigned int (*nf_nat_tftp_hook)(struct sk_buff **pskb,
40 enum ip_conntrack_info ctinfo,
41 struct nf_conntrack_expect *exp) __read_mostly;
42EXPORT_SYMBOL_GPL(nf_nat_tftp_hook);
43
44static int tftp_help(struct sk_buff **pskb,
45 unsigned int protoff,
46 struct nf_conn *ct,
47 enum ip_conntrack_info ctinfo)
48{
49 struct tftphdr _tftph, *tfh;
50 struct nf_conntrack_expect *exp;
51 struct nf_conntrack_tuple *tuple;
52 unsigned int ret = NF_ACCEPT;
53 int family = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.l3num;
54 typeof(nf_nat_tftp_hook) nf_nat_tftp;
55
56 tfh = skb_header_pointer(*pskb, protoff + sizeof(struct udphdr),
57 sizeof(_tftph), &_tftph);
58 if (tfh == NULL)
59 return NF_ACCEPT;
60
61 switch (ntohs(tfh->opcode)) {
62 case TFTP_OPCODE_READ:
63 case TFTP_OPCODE_WRITE:
64 /* RRQ and WRQ works the same way */
65 DEBUGP("");
66 NF_CT_DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
67 NF_CT_DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
68
69 exp = nf_conntrack_expect_alloc(ct);
70 if (exp == NULL)
71 return NF_DROP;
72 tuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
73 nf_conntrack_expect_init(exp, family,
74 &tuple->src.u3, &tuple->dst.u3,
75 IPPROTO_UDP,
76 NULL, &tuple->dst.u.udp.port);
77
78 DEBUGP("expect: ");
79 NF_CT_DUMP_TUPLE(&exp->tuple);
80 NF_CT_DUMP_TUPLE(&exp->mask);
81
82 nf_nat_tftp = rcu_dereference(nf_nat_tftp_hook);
83 if (nf_nat_tftp && ct->status & IPS_NAT_MASK)
84 ret = nf_nat_tftp(pskb, ctinfo, exp);
85 else if (nf_conntrack_expect_related(exp) != 0)
86 ret = NF_DROP;
87 nf_conntrack_expect_put(exp);
88 break;
89 case TFTP_OPCODE_DATA:
90 case TFTP_OPCODE_ACK:
91 DEBUGP("Data/ACK opcode\n");
92 break;
93 case TFTP_OPCODE_ERROR:
94 DEBUGP("Error opcode\n");
95 break;
96 default:
97 DEBUGP("Unknown opcode\n");
98 }
99 return ret;
100}
101
102static struct nf_conntrack_helper tftp[MAX_PORTS][2] __read_mostly;
103static char tftp_names[MAX_PORTS][2][sizeof("tftp-65535")] __read_mostly;
104
105static void nf_conntrack_tftp_fini(void)
106{
107 int i, j;
108
109 for (i = 0; i < ports_c; i++) {
110 for (j = 0; j < 2; j++)
111 nf_conntrack_helper_unregister(&tftp[i][j]);
112 }
113}
114
115static int __init nf_conntrack_tftp_init(void)
116{
117 int i, j, ret;
118 char *tmpname;
119
120 if (ports_c == 0)
121 ports[ports_c++] = TFTP_PORT;
122
123 for (i = 0; i < ports_c; i++) {
124 memset(&tftp[i], 0, sizeof(tftp[i]));
125
126 tftp[i][0].tuple.src.l3num = AF_INET;
127 tftp[i][1].tuple.src.l3num = AF_INET6;
128 for (j = 0; j < 2; j++) {
129 tftp[i][j].tuple.dst.protonum = IPPROTO_UDP;
130 tftp[i][j].tuple.src.u.udp.port = htons(ports[i]);
131 tftp[i][j].mask.src.l3num = 0xFFFF;
132 tftp[i][j].mask.dst.protonum = 0xFF;
133 tftp[i][j].mask.src.u.udp.port = htons(0xFFFF);
134 tftp[i][j].max_expected = 1;
135 tftp[i][j].timeout = 5 * 60; /* 5 minutes */
136 tftp[i][j].me = THIS_MODULE;
137 tftp[i][j].help = tftp_help;
138
139 tmpname = &tftp_names[i][j][0];
140 if (ports[i] == TFTP_PORT)
141 sprintf(tmpname, "tftp");
142 else
143 sprintf(tmpname, "tftp-%u", i);
144 tftp[i][j].name = tmpname;
145
146 ret = nf_conntrack_helper_register(&tftp[i][j]);
147 if (ret) {
148 printk("nf_ct_tftp: failed to register helper "
149 "for pf: %u port: %u\n",
150 tftp[i][j].tuple.src.l3num, ports[i]);
151 nf_conntrack_tftp_fini();
152 return ret;
153 }
154 }
155 }
156 return 0;
157}
158
159module_init(nf_conntrack_tftp_init);
160module_exit(nf_conntrack_tftp_fini);
diff --git a/net/netfilter/nf_sysctl.c b/net/netfilter/nf_sysctl.c
new file mode 100644
index 0000000000..06ddddb291
--- /dev/null
+++ b/net/netfilter/nf_sysctl.c
@@ -0,0 +1,134 @@
1/* nf_sysctl.c netfilter sysctl registration/unregistation
2 *
3 * Copyright (c) 2006 Patrick McHardy <kaber@trash.net>
4 */
5#include <linux/module.h>
6#include <linux/sysctl.h>
7#include <linux/string.h>
8#include <linux/slab.h>
9
10static void
11path_free(struct ctl_table *path, struct ctl_table *table)
12{
13 struct ctl_table *t, *next;
14
15 for (t = path; t != NULL && t != table; t = next) {
16 next = t->child;
17 kfree(t);
18 }
19}
20
21static struct ctl_table *
22path_dup(struct ctl_table *path, struct ctl_table *table)
23{
24 struct ctl_table *t, *last = NULL, *tmp;
25
26 for (t = path; t != NULL; t = t->child) {
27 /* twice the size since path elements are terminated by an
28 * empty element */
29 tmp = kmemdup(t, 2 * sizeof(*t), GFP_KERNEL);
30 if (tmp == NULL) {
31 if (last != NULL)
32 path_free(path, table);
33 return NULL;
34 }
35
36 if (last != NULL)
37 last->child = tmp;
38 else
39 path = tmp;
40 last = tmp;
41 }
42
43 if (last != NULL)
44 last->child = table;
45 else
46 path = table;
47
48 return path;
49}
50
51struct ctl_table_header *
52nf_register_sysctl_table(struct ctl_table *path, struct ctl_table *table)
53{
54 struct ctl_table_header *header;
55
56 path = path_dup(path, table);
57 if (path == NULL)
58 return NULL;
59 header = register_sysctl_table(path, 0);
60 if (header == NULL)
61 path_free(path, table);
62 return header;
63}
64EXPORT_SYMBOL_GPL(nf_register_sysctl_table);
65
66void
67nf_unregister_sysctl_table(struct ctl_table_header *header,
68 struct ctl_table *table)
69{
70 struct ctl_table *path = header->ctl_table;
71
72 unregister_sysctl_table(header);
73 path_free(path, table);
74}
75EXPORT_SYMBOL_GPL(nf_unregister_sysctl_table);
76
77/* net/netfilter */
78static struct ctl_table nf_net_netfilter_table[] = {
79 {
80 .ctl_name = NET_NETFILTER,
81 .procname = "netfilter",
82 .mode = 0555,
83 },
84 {
85 .ctl_name = 0
86 }
87};
88struct ctl_table nf_net_netfilter_sysctl_path[] = {
89 {
90 .ctl_name = CTL_NET,
91 .procname = "net",
92 .mode = 0555,
93 .child = nf_net_netfilter_table,
94 },
95 {
96 .ctl_name = 0
97 }
98};
99EXPORT_SYMBOL_GPL(nf_net_netfilter_sysctl_path);
100
101/* net/ipv4/netfilter */
102static struct ctl_table nf_net_ipv4_netfilter_table[] = {
103 {
104 .ctl_name = NET_IPV4_NETFILTER,
105 .procname = "netfilter",
106 .mode = 0555,
107 },
108 {
109 .ctl_name = 0
110 }
111};
112static struct ctl_table nf_net_ipv4_table[] = {
113 {
114 .ctl_name = NET_IPV4,
115 .procname = "ipv4",
116 .mode = 0555,
117 .child = nf_net_ipv4_netfilter_table,
118 },
119 {
120 .ctl_name = 0
121 }
122};
123struct ctl_table nf_net_ipv4_netfilter_sysctl_path[] = {
124 {
125 .ctl_name = CTL_NET,
126 .procname = "net",
127 .mode = 0555,
128 .child = nf_net_ipv4_table,
129 },
130 {
131 .ctl_name = 0
132 }
133};
134EXPORT_SYMBOL_GPL(nf_net_ipv4_netfilter_sysctl_path);
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 1e5207b80f..d1505dd25c 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -408,13 +408,13 @@ __build_packet_message(struct nfulnl_instance *inst,
408 const struct net_device *indev, 408 const struct net_device *indev,
409 const struct net_device *outdev, 409 const struct net_device *outdev,
410 const struct nf_loginfo *li, 410 const struct nf_loginfo *li,
411 const char *prefix) 411 const char *prefix, unsigned int plen)
412{ 412{
413 unsigned char *old_tail; 413 unsigned char *old_tail;
414 struct nfulnl_msg_packet_hdr pmsg; 414 struct nfulnl_msg_packet_hdr pmsg;
415 struct nlmsghdr *nlh; 415 struct nlmsghdr *nlh;
416 struct nfgenmsg *nfmsg; 416 struct nfgenmsg *nfmsg;
417 u_int32_t tmp_uint; 417 __be32 tmp_uint;
418 418
419 UDEBUG("entered\n"); 419 UDEBUG("entered\n");
420 420
@@ -432,12 +432,8 @@ __build_packet_message(struct nfulnl_instance *inst,
432 432
433 NFA_PUT(inst->skb, NFULA_PACKET_HDR, sizeof(pmsg), &pmsg); 433 NFA_PUT(inst->skb, NFULA_PACKET_HDR, sizeof(pmsg), &pmsg);
434 434
435 if (prefix) { 435 if (prefix)
436 int slen = strlen(prefix); 436 NFA_PUT(inst->skb, NFULA_PREFIX, plen, prefix);
437 if (slen > NFULNL_PREFIXLEN)
438 slen = NFULNL_PREFIXLEN;
439 NFA_PUT(inst->skb, NFULA_PREFIX, slen, prefix);
440 }
441 437
442 if (indev) { 438 if (indev) {
443 tmp_uint = htonl(indev->ifindex); 439 tmp_uint = htonl(indev->ifindex);
@@ -501,18 +497,16 @@ __build_packet_message(struct nfulnl_instance *inst,
501#endif 497#endif
502 } 498 }
503 499
504 if (skb->nfmark) { 500 if (skb->mark) {
505 tmp_uint = htonl(skb->nfmark); 501 tmp_uint = htonl(skb->mark);
506 NFA_PUT(inst->skb, NFULA_MARK, sizeof(tmp_uint), &tmp_uint); 502 NFA_PUT(inst->skb, NFULA_MARK, sizeof(tmp_uint), &tmp_uint);
507 } 503 }
508 504
509 if (indev && skb->dev && skb->dev->hard_header_parse) { 505 if (indev && skb->dev && skb->dev->hard_header_parse) {
510 struct nfulnl_msg_packet_hw phw; 506 struct nfulnl_msg_packet_hw phw;
511 507 int len = skb->dev->hard_header_parse((struct sk_buff *)skb,
512 phw.hw_addrlen =
513 skb->dev->hard_header_parse((struct sk_buff *)skb,
514 phw.hw_addr); 508 phw.hw_addr);
515 phw.hw_addrlen = htons(phw.hw_addrlen); 509 phw.hw_addrlen = htons(len);
516 NFA_PUT(inst->skb, NFULA_HWADDR, sizeof(phw), &phw); 510 NFA_PUT(inst->skb, NFULA_HWADDR, sizeof(phw), &phw);
517 } 511 }
518 512
@@ -529,7 +523,7 @@ __build_packet_message(struct nfulnl_instance *inst,
529 if (skb->sk) { 523 if (skb->sk) {
530 read_lock_bh(&skb->sk->sk_callback_lock); 524 read_lock_bh(&skb->sk->sk_callback_lock);
531 if (skb->sk->sk_socket && skb->sk->sk_socket->file) { 525 if (skb->sk->sk_socket && skb->sk->sk_socket->file) {
532 u_int32_t uid = htonl(skb->sk->sk_socket->file->f_uid); 526 __be32 uid = htonl(skb->sk->sk_socket->file->f_uid);
533 /* need to unlock here since NFA_PUT may goto */ 527 /* need to unlock here since NFA_PUT may goto */
534 read_unlock_bh(&skb->sk->sk_callback_lock); 528 read_unlock_bh(&skb->sk->sk_callback_lock);
535 NFA_PUT(inst->skb, NFULA_UID, sizeof(uid), &uid); 529 NFA_PUT(inst->skb, NFULA_UID, sizeof(uid), &uid);
@@ -603,6 +597,7 @@ nfulnl_log_packet(unsigned int pf,
603 const struct nf_loginfo *li; 597 const struct nf_loginfo *li;
604 unsigned int qthreshold; 598 unsigned int qthreshold;
605 unsigned int nlbufsiz; 599 unsigned int nlbufsiz;
600 unsigned int plen;
606 601
607 if (li_user && li_user->type == NF_LOG_TYPE_ULOG) 602 if (li_user && li_user->type == NF_LOG_TYPE_ULOG)
608 li = li_user; 603 li = li_user;
@@ -618,6 +613,10 @@ nfulnl_log_packet(unsigned int pf,
618 return; 613 return;
619 } 614 }
620 615
616 plen = 0;
617 if (prefix)
618 plen = strlen(prefix);
619
621 /* all macros expand to constant values at compile time */ 620 /* all macros expand to constant values at compile time */
622 /* FIXME: do we want to make the size calculation conditional based on 621 /* FIXME: do we want to make the size calculation conditional based on
623 * what is actually present? way more branches and checks, but more 622 * what is actually present? way more branches and checks, but more
@@ -632,7 +631,7 @@ nfulnl_log_packet(unsigned int pf,
632#endif 631#endif
633 + NFA_SPACE(sizeof(u_int32_t)) /* mark */ 632 + NFA_SPACE(sizeof(u_int32_t)) /* mark */
634 + NFA_SPACE(sizeof(u_int32_t)) /* uid */ 633 + NFA_SPACE(sizeof(u_int32_t)) /* uid */
635 + NFA_SPACE(NFULNL_PREFIXLEN) /* prefix */ 634 + NFA_SPACE(plen) /* prefix */
636 + NFA_SPACE(sizeof(struct nfulnl_msg_packet_hw)) 635 + NFA_SPACE(sizeof(struct nfulnl_msg_packet_hw))
637 + NFA_SPACE(sizeof(struct nfulnl_msg_packet_timestamp)); 636 + NFA_SPACE(sizeof(struct nfulnl_msg_packet_timestamp));
638 637
@@ -703,7 +702,7 @@ nfulnl_log_packet(unsigned int pf,
703 inst->qlen++; 702 inst->qlen++;
704 703
705 __build_packet_message(inst, skb, data_len, pf, 704 __build_packet_message(inst, skb, data_len, pf,
706 hooknum, in, out, li, prefix); 705 hooknum, in, out, li, prefix, plen);
707 706
708 /* timer_pending always called within inst->lock, so there 707 /* timer_pending always called within inst->lock, so there
709 * is no chance of a race here */ 708 * is no chance of a race here */
@@ -882,15 +881,15 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
882 } 881 }
883 882
884 if (nfula[NFULA_CFG_TIMEOUT-1]) { 883 if (nfula[NFULA_CFG_TIMEOUT-1]) {
885 u_int32_t timeout = 884 __be32 timeout =
886 *(u_int32_t *)NFA_DATA(nfula[NFULA_CFG_TIMEOUT-1]); 885 *(__be32 *)NFA_DATA(nfula[NFULA_CFG_TIMEOUT-1]);
887 886
888 nfulnl_set_timeout(inst, ntohl(timeout)); 887 nfulnl_set_timeout(inst, ntohl(timeout));
889 } 888 }
890 889
891 if (nfula[NFULA_CFG_NLBUFSIZ-1]) { 890 if (nfula[NFULA_CFG_NLBUFSIZ-1]) {
892 u_int32_t nlbufsiz = 891 __be32 nlbufsiz =
893 *(u_int32_t *)NFA_DATA(nfula[NFULA_CFG_NLBUFSIZ-1]); 892 *(__be32 *)NFA_DATA(nfula[NFULA_CFG_NLBUFSIZ-1]);
894 893
895 nfulnl_set_nlbufsiz(inst, ntohl(nlbufsiz)); 894 nfulnl_set_nlbufsiz(inst, ntohl(nlbufsiz));
896 } 895 }
@@ -903,8 +902,8 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
903 } 902 }
904 903
905 if (nfula[NFULA_CFG_FLAGS-1]) { 904 if (nfula[NFULA_CFG_FLAGS-1]) {
906 u_int16_t flags = 905 __be16 flags =
907 *(u_int16_t *)NFA_DATA(nfula[NFULA_CFG_FLAGS-1]); 906 *(__be16 *)NFA_DATA(nfula[NFULA_CFG_FLAGS-1]);
908 nfulnl_set_flags(inst, ntohs(flags)); 907 nfulnl_set_flags(inst, ntohs(flags));
909 } 908 }
910 909
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index e815a9aa6e..a88a017da2 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -349,7 +349,7 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
349 struct sk_buff *entskb = entry->skb; 349 struct sk_buff *entskb = entry->skb;
350 struct net_device *indev; 350 struct net_device *indev;
351 struct net_device *outdev; 351 struct net_device *outdev;
352 unsigned int tmp_uint; 352 __be32 tmp_uint;
353 353
354 QDEBUG("entered\n"); 354 QDEBUG("entered\n");
355 355
@@ -480,8 +480,8 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
480#endif 480#endif
481 } 481 }
482 482
483 if (entskb->nfmark) { 483 if (entskb->mark) {
484 tmp_uint = htonl(entskb->nfmark); 484 tmp_uint = htonl(entskb->mark);
485 NFA_PUT(skb, NFQA_MARK, sizeof(u_int32_t), &tmp_uint); 485 NFA_PUT(skb, NFQA_MARK, sizeof(u_int32_t), &tmp_uint);
486 } 486 }
487 487
@@ -489,10 +489,9 @@ nfqnl_build_packet_message(struct nfqnl_instance *queue,
489 && entskb->dev->hard_header_parse) { 489 && entskb->dev->hard_header_parse) {
490 struct nfqnl_msg_packet_hw phw; 490 struct nfqnl_msg_packet_hw phw;
491 491
492 phw.hw_addrlen = 492 int len = entskb->dev->hard_header_parse(entskb,
493 entskb->dev->hard_header_parse(entskb,
494 phw.hw_addr); 493 phw.hw_addr);
495 phw.hw_addrlen = htons(phw.hw_addrlen); 494 phw.hw_addrlen = htons(len);
496 NFA_PUT(skb, NFQA_HWADDR, sizeof(phw), &phw); 495 NFA_PUT(skb, NFQA_HWADDR, sizeof(phw), &phw);
497 } 496 }
498 497
@@ -835,8 +834,8 @@ nfqnl_recv_verdict(struct sock *ctnl, struct sk_buff *skb,
835 } 834 }
836 835
837 if (nfqa[NFQA_MARK-1]) 836 if (nfqa[NFQA_MARK-1])
838 entry->skb->nfmark = ntohl(*(u_int32_t *) 837 entry->skb->mark = ntohl(*(__be32 *)
839 NFA_DATA(nfqa[NFQA_MARK-1])); 838 NFA_DATA(nfqa[NFQA_MARK-1]));
840 839
841 issue_verdict(entry, verdict); 840 issue_verdict(entry, verdict);
842 instance_put(queue); 841 instance_put(queue);
@@ -948,6 +947,14 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
948 ntohl(params->copy_range)); 947 ntohl(params->copy_range));
949 } 948 }
950 949
950 if (nfqa[NFQA_CFG_QUEUE_MAXLEN-1]) {
951 __be32 *queue_maxlen;
952 queue_maxlen = NFA_DATA(nfqa[NFQA_CFG_QUEUE_MAXLEN-1]);
953 spin_lock_bh(&queue->lock);
954 queue->queue_maxlen = ntohl(*queue_maxlen);
955 spin_unlock_bh(&queue->lock);
956 }
957
951out_put: 958out_put:
952 instance_put(queue); 959 instance_put(queue);
953 return ret; 960 return ret;
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 58522fc65d..8996584b84 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -21,6 +21,7 @@
21#include <linux/string.h> 21#include <linux/string.h>
22#include <linux/vmalloc.h> 22#include <linux/vmalloc.h>
23#include <linux/mutex.h> 23#include <linux/mutex.h>
24#include <linux/mm.h>
24 25
25#include <linux/netfilter/x_tables.h> 26#include <linux/netfilter/x_tables.h>
26#include <linux/netfilter_arp.h> 27#include <linux/netfilter_arp.h>
diff --git a/net/netfilter/xt_CONNMARK.c b/net/netfilter/xt_CONNMARK.c
index c01524f817..0534bfa65c 100644
--- a/net/netfilter/xt_CONNMARK.c
+++ b/net/netfilter/xt_CONNMARK.c
@@ -31,6 +31,9 @@ MODULE_ALIAS("ipt_CONNMARK");
31#include <linux/netfilter/x_tables.h> 31#include <linux/netfilter/x_tables.h>
32#include <linux/netfilter/xt_CONNMARK.h> 32#include <linux/netfilter/xt_CONNMARK.h>
33#include <net/netfilter/nf_conntrack_compat.h> 33#include <net/netfilter/nf_conntrack_compat.h>
34#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
35#include <net/netfilter/nf_conntrack_ecache.h>
36#endif
34 37
35static unsigned int 38static unsigned int
36target(struct sk_buff **pskb, 39target(struct sk_buff **pskb,
@@ -42,7 +45,7 @@ target(struct sk_buff **pskb,
42{ 45{
43 const struct xt_connmark_target_info *markinfo = targinfo; 46 const struct xt_connmark_target_info *markinfo = targinfo;
44 u_int32_t diff; 47 u_int32_t diff;
45 u_int32_t nfmark; 48 u_int32_t mark;
46 u_int32_t newmark; 49 u_int32_t newmark;
47 u_int32_t ctinfo; 50 u_int32_t ctinfo;
48 u_int32_t *ctmark = nf_ct_get_mark(*pskb, &ctinfo); 51 u_int32_t *ctmark = nf_ct_get_mark(*pskb, &ctinfo);
@@ -62,7 +65,7 @@ target(struct sk_buff **pskb,
62 break; 65 break;
63 case XT_CONNMARK_SAVE: 66 case XT_CONNMARK_SAVE:
64 newmark = (*ctmark & ~markinfo->mask) | 67 newmark = (*ctmark & ~markinfo->mask) |
65 ((*pskb)->nfmark & markinfo->mask); 68 ((*pskb)->mark & markinfo->mask);
66 if (*ctmark != newmark) { 69 if (*ctmark != newmark) {
67 *ctmark = newmark; 70 *ctmark = newmark;
68#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE) 71#if defined(CONFIG_IP_NF_CONNTRACK) || defined(CONFIG_IP_NF_CONNTRACK_MODULE)
@@ -73,10 +76,10 @@ target(struct sk_buff **pskb,
73 } 76 }
74 break; 77 break;
75 case XT_CONNMARK_RESTORE: 78 case XT_CONNMARK_RESTORE:
76 nfmark = (*pskb)->nfmark; 79 mark = (*pskb)->mark;
77 diff = (*ctmark ^ nfmark) & markinfo->mask; 80 diff = (*ctmark ^ mark) & markinfo->mask;
78 if (diff != 0) 81 if (diff != 0)
79 (*pskb)->nfmark = nfmark ^ diff; 82 (*pskb)->mark = mark ^ diff;
80 break; 83 break;
81 } 84 }
82 } 85 }
@@ -93,6 +96,11 @@ checkentry(const char *tablename,
93{ 96{
94 struct xt_connmark_target_info *matchinfo = targinfo; 97 struct xt_connmark_target_info *matchinfo = targinfo;
95 98
99 if (nf_ct_l3proto_try_module_get(target->family) < 0) {
100 printk(KERN_WARNING "can't load conntrack support for "
101 "proto=%d\n", target->family);
102 return 0;
103 }
96 if (matchinfo->mode == XT_CONNMARK_RESTORE) { 104 if (matchinfo->mode == XT_CONNMARK_RESTORE) {
97 if (strcmp(tablename, "mangle") != 0) { 105 if (strcmp(tablename, "mangle") != 0) {
98 printk(KERN_WARNING "CONNMARK: restore can only be " 106 printk(KERN_WARNING "CONNMARK: restore can only be "
@@ -108,6 +116,12 @@ checkentry(const char *tablename,
108 return 1; 116 return 1;
109} 117}
110 118
119static void
120destroy(const struct xt_target *target, void *targinfo)
121{
122 nf_ct_l3proto_module_put(target->family);
123}
124
111#ifdef CONFIG_COMPAT 125#ifdef CONFIG_COMPAT
112struct compat_xt_connmark_target_info { 126struct compat_xt_connmark_target_info {
113 compat_ulong_t mark, mask; 127 compat_ulong_t mark, mask;
@@ -144,6 +158,7 @@ static struct xt_target xt_connmark_target[] = {
144 .name = "CONNMARK", 158 .name = "CONNMARK",
145 .family = AF_INET, 159 .family = AF_INET,
146 .checkentry = checkentry, 160 .checkentry = checkentry,
161 .destroy = destroy,
147 .target = target, 162 .target = target,
148 .targetsize = sizeof(struct xt_connmark_target_info), 163 .targetsize = sizeof(struct xt_connmark_target_info),
149#ifdef CONFIG_COMPAT 164#ifdef CONFIG_COMPAT
@@ -157,6 +172,7 @@ static struct xt_target xt_connmark_target[] = {
157 .name = "CONNMARK", 172 .name = "CONNMARK",
158 .family = AF_INET6, 173 .family = AF_INET6,
159 .checkentry = checkentry, 174 .checkentry = checkentry,
175 .destroy = destroy,
160 .target = target, 176 .target = target,
161 .targetsize = sizeof(struct xt_connmark_target_info), 177 .targetsize = sizeof(struct xt_connmark_target_info),
162 .me = THIS_MODULE 178 .me = THIS_MODULE
@@ -165,7 +181,6 @@ static struct xt_target xt_connmark_target[] = {
165 181
166static int __init xt_connmark_init(void) 182static int __init xt_connmark_init(void)
167{ 183{
168 need_conntrack();
169 return xt_register_targets(xt_connmark_target, 184 return xt_register_targets(xt_connmark_target,
170 ARRAY_SIZE(xt_connmark_target)); 185 ARRAY_SIZE(xt_connmark_target));
171} 186}
diff --git a/net/netfilter/xt_CONNSECMARK.c b/net/netfilter/xt_CONNSECMARK.c
index 4673862666..a3fe3c334b 100644
--- a/net/netfilter/xt_CONNSECMARK.c
+++ b/net/netfilter/xt_CONNSECMARK.c
@@ -93,6 +93,11 @@ static int checkentry(const char *tablename, const void *entry,
93{ 93{
94 struct xt_connsecmark_target_info *info = targinfo; 94 struct xt_connsecmark_target_info *info = targinfo;
95 95
96 if (nf_ct_l3proto_try_module_get(target->family) < 0) {
97 printk(KERN_WARNING "can't load conntrack support for "
98 "proto=%d\n", target->family);
99 return 0;
100 }
96 switch (info->mode) { 101 switch (info->mode) {
97 case CONNSECMARK_SAVE: 102 case CONNSECMARK_SAVE:
98 case CONNSECMARK_RESTORE: 103 case CONNSECMARK_RESTORE:
@@ -106,11 +111,18 @@ static int checkentry(const char *tablename, const void *entry,
106 return 1; 111 return 1;
107} 112}
108 113
114static void
115destroy(const struct xt_target *target, void *targinfo)
116{
117 nf_ct_l3proto_module_put(target->family);
118}
119
109static struct xt_target xt_connsecmark_target[] = { 120static struct xt_target xt_connsecmark_target[] = {
110 { 121 {
111 .name = "CONNSECMARK", 122 .name = "CONNSECMARK",
112 .family = AF_INET, 123 .family = AF_INET,
113 .checkentry = checkentry, 124 .checkentry = checkentry,
125 .destroy = destroy,
114 .target = target, 126 .target = target,
115 .targetsize = sizeof(struct xt_connsecmark_target_info), 127 .targetsize = sizeof(struct xt_connsecmark_target_info),
116 .table = "mangle", 128 .table = "mangle",
@@ -120,6 +132,7 @@ static struct xt_target xt_connsecmark_target[] = {
120 .name = "CONNSECMARK", 132 .name = "CONNSECMARK",
121 .family = AF_INET6, 133 .family = AF_INET6,
122 .checkentry = checkentry, 134 .checkentry = checkentry,
135 .destroy = destroy,
123 .target = target, 136 .target = target,
124 .targetsize = sizeof(struct xt_connsecmark_target_info), 137 .targetsize = sizeof(struct xt_connsecmark_target_info),
125 .table = "mangle", 138 .table = "mangle",
@@ -129,7 +142,6 @@ static struct xt_target xt_connsecmark_target[] = {
129 142
130static int __init xt_connsecmark_init(void) 143static int __init xt_connsecmark_init(void)
131{ 144{
132 need_conntrack();
133 return xt_register_targets(xt_connsecmark_target, 145 return xt_register_targets(xt_connsecmark_target,
134 ARRAY_SIZE(xt_connsecmark_target)); 146 ARRAY_SIZE(xt_connsecmark_target));
135} 147}
diff --git a/net/netfilter/xt_MARK.c b/net/netfilter/xt_MARK.c
index c6e860a711..0b48547e8d 100644
--- a/net/netfilter/xt_MARK.c
+++ b/net/netfilter/xt_MARK.c
@@ -31,8 +31,8 @@ target_v0(struct sk_buff **pskb,
31{ 31{
32 const struct xt_mark_target_info *markinfo = targinfo; 32 const struct xt_mark_target_info *markinfo = targinfo;
33 33
34 if((*pskb)->nfmark != markinfo->mark) 34 if((*pskb)->mark != markinfo->mark)
35 (*pskb)->nfmark = markinfo->mark; 35 (*pskb)->mark = markinfo->mark;
36 36
37 return XT_CONTINUE; 37 return XT_CONTINUE;
38} 38}
@@ -54,16 +54,16 @@ target_v1(struct sk_buff **pskb,
54 break; 54 break;
55 55
56 case XT_MARK_AND: 56 case XT_MARK_AND:
57 mark = (*pskb)->nfmark & markinfo->mark; 57 mark = (*pskb)->mark & markinfo->mark;
58 break; 58 break;
59 59
60 case XT_MARK_OR: 60 case XT_MARK_OR:
61 mark = (*pskb)->nfmark | markinfo->mark; 61 mark = (*pskb)->mark | markinfo->mark;
62 break; 62 break;
63 } 63 }
64 64
65 if((*pskb)->nfmark != mark) 65 if((*pskb)->mark != mark)
66 (*pskb)->nfmark = mark; 66 (*pskb)->mark = mark;
67 67
68 return XT_CONTINUE; 68 return XT_CONTINUE;
69} 69}
diff --git a/net/netfilter/xt_NFLOG.c b/net/netfilter/xt_NFLOG.c
new file mode 100644
index 0000000000..901ed7abaa
--- /dev/null
+++ b/net/netfilter/xt_NFLOG.c
@@ -0,0 +1,86 @@
1/*
2 * Copyright (c) 2006 Patrick McHardy <kaber@trash.net>
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/module.h>
10#include <linux/init.h>
11#include <linux/skbuff.h>
12
13#include <linux/netfilter/x_tables.h>
14#include <linux/netfilter/xt_NFLOG.h>
15
16MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
17MODULE_DESCRIPTION("x_tables NFLOG target");
18MODULE_LICENSE("GPL");
19MODULE_ALIAS("ipt_NFLOG");
20MODULE_ALIAS("ip6t_NFLOG");
21
22static unsigned int
23nflog_target(struct sk_buff **pskb,
24 const struct net_device *in, const struct net_device *out,
25 unsigned int hooknum, const struct xt_target *target,
26 const void *targinfo)
27{
28 const struct xt_nflog_info *info = targinfo;
29 struct nf_loginfo li;
30
31 li.type = NF_LOG_TYPE_ULOG;
32 li.u.ulog.copy_len = info->len;
33 li.u.ulog.group = info->group;
34 li.u.ulog.qthreshold = info->threshold;
35
36 nf_log_packet(target->family, hooknum, *pskb, in, out, &li,
37 "%s", info->prefix);
38 return XT_CONTINUE;
39}
40
41static int
42nflog_checkentry(const char *tablename, const void *entry,
43 const struct xt_target *target, void *targetinfo,
44 unsigned int hookmask)
45{
46 struct xt_nflog_info *info = targetinfo;
47
48 if (info->flags & ~XT_NFLOG_MASK)
49 return 0;
50 if (info->prefix[sizeof(info->prefix) - 1] != '\0')
51 return 0;
52 return 1;
53}
54
55static struct xt_target xt_nflog_target[] = {
56 {
57 .name = "NFLOG",
58 .family = AF_INET,
59 .checkentry = nflog_checkentry,
60 .target = nflog_target,
61 .targetsize = sizeof(struct xt_nflog_info),
62 .me = THIS_MODULE,
63 },
64 {
65 .name = "NFLOG",
66 .family = AF_INET6,
67 .checkentry = nflog_checkentry,
68 .target = nflog_target,
69 .targetsize = sizeof(struct xt_nflog_info),
70 .me = THIS_MODULE,
71 },
72};
73
74static int __init xt_nflog_init(void)
75{
76 return xt_register_targets(xt_nflog_target,
77 ARRAY_SIZE(xt_nflog_target));
78}
79
80static void __exit xt_nflog_fini(void)
81{
82 xt_unregister_targets(xt_nflog_target, ARRAY_SIZE(xt_nflog_target));
83}
84
85module_init(xt_nflog_init);
86module_exit(xt_nflog_fini);
diff --git a/net/netfilter/xt_connbytes.c b/net/netfilter/xt_connbytes.c
index dcc497ea81..d93cb096a6 100644
--- a/net/netfilter/xt_connbytes.c
+++ b/net/netfilter/xt_connbytes.c
@@ -139,15 +139,28 @@ static int check(const char *tablename,
139 sinfo->direction != XT_CONNBYTES_DIR_BOTH) 139 sinfo->direction != XT_CONNBYTES_DIR_BOTH)
140 return 0; 140 return 0;
141 141
142 if (nf_ct_l3proto_try_module_get(match->family) < 0) {
143 printk(KERN_WARNING "can't load conntrack support for "
144 "proto=%d\n", match->family);
145 return 0;
146 }
147
142 return 1; 148 return 1;
143} 149}
144 150
151static void
152destroy(const struct xt_match *match, void *matchinfo)
153{
154 nf_ct_l3proto_module_put(match->family);
155}
156
145static struct xt_match xt_connbytes_match[] = { 157static struct xt_match xt_connbytes_match[] = {
146 { 158 {
147 .name = "connbytes", 159 .name = "connbytes",
148 .family = AF_INET, 160 .family = AF_INET,
149 .checkentry = check, 161 .checkentry = check,
150 .match = match, 162 .match = match,
163 .destroy = destroy,
151 .matchsize = sizeof(struct xt_connbytes_info), 164 .matchsize = sizeof(struct xt_connbytes_info),
152 .me = THIS_MODULE 165 .me = THIS_MODULE
153 }, 166 },
@@ -156,6 +169,7 @@ static struct xt_match xt_connbytes_match[] = {
156 .family = AF_INET6, 169 .family = AF_INET6,
157 .checkentry = check, 170 .checkentry = check,
158 .match = match, 171 .match = match,
172 .destroy = destroy,
159 .matchsize = sizeof(struct xt_connbytes_info), 173 .matchsize = sizeof(struct xt_connbytes_info),
160 .me = THIS_MODULE 174 .me = THIS_MODULE
161 }, 175 },
diff --git a/net/netfilter/xt_connmark.c b/net/netfilter/xt_connmark.c
index a8f03057db..36c2defff2 100644
--- a/net/netfilter/xt_connmark.c
+++ b/net/netfilter/xt_connmark.c
@@ -63,22 +63,18 @@ checkentry(const char *tablename,
63 printk(KERN_WARNING "connmark: only support 32bit mark\n"); 63 printk(KERN_WARNING "connmark: only support 32bit mark\n");
64 return 0; 64 return 0;
65 } 65 }
66#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
67 if (nf_ct_l3proto_try_module_get(match->family) < 0) { 66 if (nf_ct_l3proto_try_module_get(match->family) < 0) {
68 printk(KERN_WARNING "can't load nf_conntrack support for " 67 printk(KERN_WARNING "can't load conntrack support for "
69 "proto=%d\n", match->family); 68 "proto=%d\n", match->family);
70 return 0; 69 return 0;
71 } 70 }
72#endif
73 return 1; 71 return 1;
74} 72}
75 73
76static void 74static void
77destroy(const struct xt_match *match, void *matchinfo) 75destroy(const struct xt_match *match, void *matchinfo)
78{ 76{
79#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
80 nf_ct_l3proto_module_put(match->family); 77 nf_ct_l3proto_module_put(match->family);
81#endif
82} 78}
83 79
84#ifdef CONFIG_COMPAT 80#ifdef CONFIG_COMPAT
@@ -140,7 +136,6 @@ static struct xt_match xt_connmark_match[] = {
140 136
141static int __init xt_connmark_init(void) 137static int __init xt_connmark_init(void)
142{ 138{
143 need_conntrack();
144 return xt_register_matches(xt_connmark_match, 139 return xt_register_matches(xt_connmark_match,
145 ARRAY_SIZE(xt_connmark_match)); 140 ARRAY_SIZE(xt_connmark_match));
146} 141}
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c
index 0ea501a2fd..3dc2357b8d 100644
--- a/net/netfilter/xt_conntrack.c
+++ b/net/netfilter/xt_conntrack.c
@@ -20,6 +20,7 @@
20 20
21#include <linux/netfilter/x_tables.h> 21#include <linux/netfilter/x_tables.h>
22#include <linux/netfilter/xt_conntrack.h> 22#include <linux/netfilter/xt_conntrack.h>
23#include <net/netfilter/nf_conntrack_compat.h>
23 24
24MODULE_LICENSE("GPL"); 25MODULE_LICENSE("GPL");
25MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>"); 26MODULE_AUTHOR("Marc Boucher <marc@mbsi.ca>");
@@ -228,21 +229,17 @@ checkentry(const char *tablename,
228 void *matchinfo, 229 void *matchinfo,
229 unsigned int hook_mask) 230 unsigned int hook_mask)
230{ 231{
231#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
232 if (nf_ct_l3proto_try_module_get(match->family) < 0) { 232 if (nf_ct_l3proto_try_module_get(match->family) < 0) {
233 printk(KERN_WARNING "can't load nf_conntrack support for " 233 printk(KERN_WARNING "can't load conntrack support for "
234 "proto=%d\n", match->family); 234 "proto=%d\n", match->family);
235 return 0; 235 return 0;
236 } 236 }
237#endif
238 return 1; 237 return 1;
239} 238}
240 239
241static void destroy(const struct xt_match *match, void *matchinfo) 240static void destroy(const struct xt_match *match, void *matchinfo)
242{ 241{
243#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
244 nf_ct_l3proto_module_put(match->family); 242 nf_ct_l3proto_module_put(match->family);
245#endif
246} 243}
247 244
248static struct xt_match conntrack_match = { 245static struct xt_match conntrack_match = {
@@ -257,7 +254,6 @@ static struct xt_match conntrack_match = {
257 254
258static int __init xt_conntrack_init(void) 255static int __init xt_conntrack_init(void)
259{ 256{
260 need_conntrack();
261 return xt_register_match(&conntrack_match); 257 return xt_register_match(&conntrack_match);
262} 258}
263 259
diff --git a/net/ipv4/netfilter/ipt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index 33ccdbf8e7..f28bf69d3d 100644
--- a/net/ipv4/netfilter/ipt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -6,23 +6,8 @@
6 * $Id: ipt_hashlimit.c 3244 2004-10-20 16:24:29Z laforge@netfilter.org $ 6 * $Id: ipt_hashlimit.c 3244 2004-10-20 16:24:29Z laforge@netfilter.org $
7 * 7 *
8 * Development of this code was funded by Astaro AG, http://www.astaro.com/ 8 * Development of this code was funded by Astaro AG, http://www.astaro.com/
9 *
10 * based on ipt_limit.c by:
11 * Jérôme de Vivie <devivie@info.enserb.u-bordeaux.fr>
12 * Hervé Eychenne <eychenne@info.enserb.u-bordeaux.fr>
13 * Rusty Russell <rusty@rustcorp.com.au>
14 *
15 * The general idea is to create a hash table for every dstip and have a
16 * seperate limit counter per tuple. This way you can do something like 'limit
17 * the number of syn packets for each of my internal addresses.
18 *
19 * Ideally this would just be implemented as a general 'hash' match, which would
20 * allow us to attach any iptables target to it's hash buckets. But this is
21 * not possible in the current iptables architecture. As always, pkttables for
22 * 2.7.x will help ;)
23 */ 9 */
24#include <linux/module.h> 10#include <linux/module.h>
25#include <linux/skbuff.h>
26#include <linux/spinlock.h> 11#include <linux/spinlock.h>
27#include <linux/random.h> 12#include <linux/random.h>
28#include <linux/jhash.h> 13#include <linux/jhash.h>
@@ -31,28 +16,41 @@
31#include <linux/proc_fs.h> 16#include <linux/proc_fs.h>
32#include <linux/seq_file.h> 17#include <linux/seq_file.h>
33#include <linux/list.h> 18#include <linux/list.h>
19#include <linux/skbuff.h>
20#include <linux/mm.h>
21#include <linux/in.h>
22#include <linux/ip.h>
23#include <linux/ipv6.h>
34 24
25#include <linux/netfilter/x_tables.h>
35#include <linux/netfilter_ipv4/ip_tables.h> 26#include <linux/netfilter_ipv4/ip_tables.h>
36#include <linux/netfilter_ipv4/ipt_hashlimit.h> 27#include <linux/netfilter_ipv6/ip6_tables.h>
37 28#include <linux/netfilter/xt_hashlimit.h>
38/* FIXME: this is just for IP_NF_ASSERRT */
39#include <linux/netfilter_ipv4/ip_conntrack.h>
40#include <linux/mutex.h> 29#include <linux/mutex.h>
41 30
42MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
43MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); 32MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>");
44MODULE_DESCRIPTION("iptables match for limiting per hash-bucket"); 33MODULE_DESCRIPTION("iptables match for limiting per hash-bucket");
34MODULE_ALIAS("ipt_hashlimit");
35MODULE_ALIAS("ip6t_hashlimit");
45 36
46/* need to declare this at the top */ 37/* need to declare this at the top */
47static struct proc_dir_entry *hashlimit_procdir; 38static struct proc_dir_entry *hashlimit_procdir4;
39static struct proc_dir_entry *hashlimit_procdir6;
48static struct file_operations dl_file_ops; 40static struct file_operations dl_file_ops;
49 41
50/* hash table crap */ 42/* hash table crap */
51
52struct dsthash_dst { 43struct dsthash_dst {
53 __be32 src_ip; 44 union {
54 __be32 dst_ip; 45 struct {
55 /* ports have to be consecutive !!! */ 46 __be32 src;
47 __be32 dst;
48 } ip;
49 struct {
50 __be32 src[4];
51 __be32 dst[4];
52 } ip6;
53 } addr;
56 __be16 src_port; 54 __be16 src_port;
57 __be16 dst_port; 55 __be16 dst_port;
58}; 56};
@@ -71,9 +69,10 @@ struct dsthash_ent {
71 } rateinfo; 69 } rateinfo;
72}; 70};
73 71
74struct ipt_hashlimit_htable { 72struct xt_hashlimit_htable {
75 struct hlist_node node; /* global list of all htables */ 73 struct hlist_node node; /* global list of all htables */
76 atomic_t use; 74 atomic_t use;
75 int family;
77 76
78 struct hashlimit_cfg cfg; /* config */ 77 struct hashlimit_cfg cfg; /* config */
79 78
@@ -81,8 +80,8 @@ struct ipt_hashlimit_htable {
81 spinlock_t lock; /* lock for list_head */ 80 spinlock_t lock; /* lock for list_head */
82 u_int32_t rnd; /* random seed for hash */ 81 u_int32_t rnd; /* random seed for hash */
83 int rnd_initialized; 82 int rnd_initialized;
83 unsigned int count; /* number entries in table */
84 struct timer_list timer; /* timer for gc */ 84 struct timer_list timer; /* timer for gc */
85 atomic_t count; /* number entries in table */
86 85
87 /* seq_file stuff */ 86 /* seq_file stuff */
88 struct proc_dir_entry *pde; 87 struct proc_dir_entry *pde;
@@ -93,45 +92,37 @@ struct ipt_hashlimit_htable {
93static DEFINE_SPINLOCK(hashlimit_lock); /* protects htables list */ 92static DEFINE_SPINLOCK(hashlimit_lock); /* protects htables list */
94static DEFINE_MUTEX(hlimit_mutex); /* additional checkentry protection */ 93static DEFINE_MUTEX(hlimit_mutex); /* additional checkentry protection */
95static HLIST_HEAD(hashlimit_htables); 94static HLIST_HEAD(hashlimit_htables);
96static kmem_cache_t *hashlimit_cachep __read_mostly; 95static struct kmem_cache *hashlimit_cachep __read_mostly;
97 96
98static inline int dst_cmp(const struct dsthash_ent *ent, struct dsthash_dst *b) 97static inline int dst_cmp(const struct dsthash_ent *ent, struct dsthash_dst *b)
99{ 98{
100 return (ent->dst.dst_ip == b->dst_ip 99 return !memcmp(&ent->dst, b, sizeof(ent->dst));
101 && ent->dst.dst_port == b->dst_port
102 && ent->dst.src_port == b->src_port
103 && ent->dst.src_ip == b->src_ip);
104} 100}
105 101
106static inline u_int32_t 102static u_int32_t
107hash_dst(const struct ipt_hashlimit_htable *ht, const struct dsthash_dst *dst) 103hash_dst(const struct xt_hashlimit_htable *ht, const struct dsthash_dst *dst)
108{ 104{
109 return (jhash_3words((__force u32)dst->dst_ip, 105 return jhash(dst, sizeof(*dst), ht->rnd) % ht->cfg.size;
110 ((__force u32)dst->dst_port<<16 |
111 (__force u32)dst->src_port),
112 (__force u32)dst->src_ip, ht->rnd) % ht->cfg.size);
113} 106}
114 107
115static inline struct dsthash_ent * 108static struct dsthash_ent *
116__dsthash_find(const struct ipt_hashlimit_htable *ht, struct dsthash_dst *dst) 109dsthash_find(const struct xt_hashlimit_htable *ht, struct dsthash_dst *dst)
117{ 110{
118 struct dsthash_ent *ent; 111 struct dsthash_ent *ent;
119 struct hlist_node *pos; 112 struct hlist_node *pos;
120 u_int32_t hash = hash_dst(ht, dst); 113 u_int32_t hash = hash_dst(ht, dst);
121 114
122 if (!hlist_empty(&ht->hash[hash])) 115 if (!hlist_empty(&ht->hash[hash])) {
123 hlist_for_each_entry(ent, pos, &ht->hash[hash], node) { 116 hlist_for_each_entry(ent, pos, &ht->hash[hash], node)
124 if (dst_cmp(ent, dst)) { 117 if (dst_cmp(ent, dst))
125 return ent; 118 return ent;
126 } 119 }
127 }
128
129 return NULL; 120 return NULL;
130} 121}
131 122
132/* allocate dsthash_ent, initialize dst, put in htable and lock it */ 123/* allocate dsthash_ent, initialize dst, put in htable and lock it */
133static struct dsthash_ent * 124static struct dsthash_ent *
134__dsthash_alloc_init(struct ipt_hashlimit_htable *ht, struct dsthash_dst *dst) 125dsthash_alloc_init(struct xt_hashlimit_htable *ht, struct dsthash_dst *dst)
135{ 126{
136 struct dsthash_ent *ent; 127 struct dsthash_ent *ent;
137 128
@@ -142,12 +133,11 @@ __dsthash_alloc_init(struct ipt_hashlimit_htable *ht, struct dsthash_dst *dst)
142 ht->rnd_initialized = 1; 133 ht->rnd_initialized = 1;
143 } 134 }
144 135
145 if (ht->cfg.max && 136 if (ht->cfg.max && ht->count >= ht->cfg.max) {
146 atomic_read(&ht->count) >= ht->cfg.max) {
147 /* FIXME: do something. question is what.. */ 137 /* FIXME: do something. question is what.. */
148 if (net_ratelimit()) 138 if (net_ratelimit())
149 printk(KERN_WARNING 139 printk(KERN_WARNING
150 "ipt_hashlimit: max count of %u reached\n", 140 "xt_hashlimit: max count of %u reached\n",
151 ht->cfg.max); 141 ht->cfg.max);
152 return NULL; 142 return NULL;
153 } 143 }
@@ -155,53 +145,47 @@ __dsthash_alloc_init(struct ipt_hashlimit_htable *ht, struct dsthash_dst *dst)
155 ent = kmem_cache_alloc(hashlimit_cachep, GFP_ATOMIC); 145 ent = kmem_cache_alloc(hashlimit_cachep, GFP_ATOMIC);
156 if (!ent) { 146 if (!ent) {
157 if (net_ratelimit()) 147 if (net_ratelimit())
158 printk(KERN_ERR 148 printk(KERN_ERR
159 "ipt_hashlimit: can't allocate dsthash_ent\n"); 149 "xt_hashlimit: can't allocate dsthash_ent\n");
160 return NULL; 150 return NULL;
161 } 151 }
162 152 memcpy(&ent->dst, dst, sizeof(ent->dst));
163 atomic_inc(&ht->count);
164
165 ent->dst.dst_ip = dst->dst_ip;
166 ent->dst.dst_port = dst->dst_port;
167 ent->dst.src_ip = dst->src_ip;
168 ent->dst.src_port = dst->src_port;
169 153
170 hlist_add_head(&ent->node, &ht->hash[hash_dst(ht, dst)]); 154 hlist_add_head(&ent->node, &ht->hash[hash_dst(ht, dst)]);
171 155 ht->count++;
172 return ent; 156 return ent;
173} 157}
174 158
175static inline void 159static inline void
176__dsthash_free(struct ipt_hashlimit_htable *ht, struct dsthash_ent *ent) 160dsthash_free(struct xt_hashlimit_htable *ht, struct dsthash_ent *ent)
177{ 161{
178 hlist_del(&ent->node); 162 hlist_del(&ent->node);
179 kmem_cache_free(hashlimit_cachep, ent); 163 kmem_cache_free(hashlimit_cachep, ent);
180 atomic_dec(&ht->count); 164 ht->count--;
181} 165}
182static void htable_gc(unsigned long htlong); 166static void htable_gc(unsigned long htlong);
183 167
184static int htable_create(struct ipt_hashlimit_info *minfo) 168static int htable_create(struct xt_hashlimit_info *minfo, int family)
185{ 169{
186 int i; 170 struct xt_hashlimit_htable *hinfo;
187 unsigned int size; 171 unsigned int size;
188 struct ipt_hashlimit_htable *hinfo; 172 unsigned int i;
189 173
190 if (minfo->cfg.size) 174 if (minfo->cfg.size)
191 size = minfo->cfg.size; 175 size = minfo->cfg.size;
192 else { 176 else {
193 size = (((num_physpages << PAGE_SHIFT) / 16384) 177 size = ((num_physpages << PAGE_SHIFT) / 16384) /
194 / sizeof(struct list_head)); 178 sizeof(struct list_head);
195 if (num_physpages > (1024 * 1024 * 1024 / PAGE_SIZE)) 179 if (num_physpages > (1024 * 1024 * 1024 / PAGE_SIZE))
196 size = 8192; 180 size = 8192;
197 if (size < 16) 181 if (size < 16)
198 size = 16; 182 size = 16;
199 } 183 }
200 /* FIXME: don't use vmalloc() here or anywhere else -HW */ 184 /* FIXME: don't use vmalloc() here or anywhere else -HW */
201 hinfo = vmalloc(sizeof(struct ipt_hashlimit_htable) 185 hinfo = vmalloc(sizeof(struct xt_hashlimit_htable) +
202 + (sizeof(struct list_head) * size)); 186 sizeof(struct list_head) * size);
203 if (!hinfo) { 187 if (!hinfo) {
204 printk(KERN_ERR "ipt_hashlimit: Unable to create hashtable\n"); 188 printk(KERN_ERR "xt_hashlimit: unable to create hashtable\n");
205 return -1; 189 return -1;
206 } 190 }
207 minfo->hinfo = hinfo; 191 minfo->hinfo = hinfo;
@@ -217,11 +201,14 @@ static int htable_create(struct ipt_hashlimit_info *minfo)
217 for (i = 0; i < hinfo->cfg.size; i++) 201 for (i = 0; i < hinfo->cfg.size; i++)
218 INIT_HLIST_HEAD(&hinfo->hash[i]); 202 INIT_HLIST_HEAD(&hinfo->hash[i]);
219 203
220 atomic_set(&hinfo->count, 0);
221 atomic_set(&hinfo->use, 1); 204 atomic_set(&hinfo->use, 1);
205 hinfo->count = 0;
206 hinfo->family = family;
222 hinfo->rnd_initialized = 0; 207 hinfo->rnd_initialized = 0;
223 spin_lock_init(&hinfo->lock); 208 spin_lock_init(&hinfo->lock);
224 hinfo->pde = create_proc_entry(minfo->name, 0, hashlimit_procdir); 209 hinfo->pde = create_proc_entry(minfo->name, 0,
210 family == AF_INET ? hashlimit_procdir4 :
211 hashlimit_procdir6);
225 if (!hinfo->pde) { 212 if (!hinfo->pde) {
226 vfree(hinfo); 213 vfree(hinfo);
227 return -1; 214 return -1;
@@ -242,23 +229,21 @@ static int htable_create(struct ipt_hashlimit_info *minfo)
242 return 0; 229 return 0;
243} 230}
244 231
245static int select_all(struct ipt_hashlimit_htable *ht, struct dsthash_ent *he) 232static int select_all(struct xt_hashlimit_htable *ht, struct dsthash_ent *he)
246{ 233{
247 return 1; 234 return 1;
248} 235}
249 236
250static int select_gc(struct ipt_hashlimit_htable *ht, struct dsthash_ent *he) 237static int select_gc(struct xt_hashlimit_htable *ht, struct dsthash_ent *he)
251{ 238{
252 return (jiffies >= he->expires); 239 return (jiffies >= he->expires);
253} 240}
254 241
255static void htable_selective_cleanup(struct ipt_hashlimit_htable *ht, 242static void htable_selective_cleanup(struct xt_hashlimit_htable *ht,
256 int (*select)(struct ipt_hashlimit_htable *ht, 243 int (*select)(struct xt_hashlimit_htable *ht,
257 struct dsthash_ent *he)) 244 struct dsthash_ent *he))
258{ 245{
259 int i; 246 unsigned int i;
260
261 IP_NF_ASSERT(ht->cfg.size && ht->cfg.max);
262 247
263 /* lock hash table and iterate over it */ 248 /* lock hash table and iterate over it */
264 spin_lock_bh(&ht->lock); 249 spin_lock_bh(&ht->lock);
@@ -267,7 +252,7 @@ static void htable_selective_cleanup(struct ipt_hashlimit_htable *ht,
267 struct hlist_node *pos, *n; 252 struct hlist_node *pos, *n;
268 hlist_for_each_entry_safe(dh, pos, n, &ht->hash[i], node) { 253 hlist_for_each_entry_safe(dh, pos, n, &ht->hash[i], node) {
269 if ((*select)(ht, dh)) 254 if ((*select)(ht, dh))
270 __dsthash_free(ht, dh); 255 dsthash_free(ht, dh);
271 } 256 }
272 } 257 }
273 spin_unlock_bh(&ht->lock); 258 spin_unlock_bh(&ht->lock);
@@ -276,7 +261,7 @@ static void htable_selective_cleanup(struct ipt_hashlimit_htable *ht,
276/* hash table garbage collector, run by timer */ 261/* hash table garbage collector, run by timer */
277static void htable_gc(unsigned long htlong) 262static void htable_gc(unsigned long htlong)
278{ 263{
279 struct ipt_hashlimit_htable *ht = (struct ipt_hashlimit_htable *)htlong; 264 struct xt_hashlimit_htable *ht = (struct xt_hashlimit_htable *)htlong;
280 265
281 htable_selective_cleanup(ht, select_gc); 266 htable_selective_cleanup(ht, select_gc);
282 267
@@ -285,38 +270,39 @@ static void htable_gc(unsigned long htlong)
285 add_timer(&ht->timer); 270 add_timer(&ht->timer);
286} 271}
287 272
288static void htable_destroy(struct ipt_hashlimit_htable *hinfo) 273static void htable_destroy(struct xt_hashlimit_htable *hinfo)
289{ 274{
290 /* remove timer, if it is pending */ 275 /* remove timer, if it is pending */
291 if (timer_pending(&hinfo->timer)) 276 if (timer_pending(&hinfo->timer))
292 del_timer(&hinfo->timer); 277 del_timer(&hinfo->timer);
293 278
294 /* remove proc entry */ 279 /* remove proc entry */
295 remove_proc_entry(hinfo->pde->name, hashlimit_procdir); 280 remove_proc_entry(hinfo->pde->name,
296 281 hinfo->family == AF_INET ? hashlimit_procdir4 :
282 hashlimit_procdir6);
297 htable_selective_cleanup(hinfo, select_all); 283 htable_selective_cleanup(hinfo, select_all);
298 vfree(hinfo); 284 vfree(hinfo);
299} 285}
300 286
301static struct ipt_hashlimit_htable *htable_find_get(char *name) 287static struct xt_hashlimit_htable *htable_find_get(char *name, int family)
302{ 288{
303 struct ipt_hashlimit_htable *hinfo; 289 struct xt_hashlimit_htable *hinfo;
304 struct hlist_node *pos; 290 struct hlist_node *pos;
305 291
306 spin_lock_bh(&hashlimit_lock); 292 spin_lock_bh(&hashlimit_lock);
307 hlist_for_each_entry(hinfo, pos, &hashlimit_htables, node) { 293 hlist_for_each_entry(hinfo, pos, &hashlimit_htables, node) {
308 if (!strcmp(name, hinfo->pde->name)) { 294 if (!strcmp(name, hinfo->pde->name) &&
295 hinfo->family == family) {
309 atomic_inc(&hinfo->use); 296 atomic_inc(&hinfo->use);
310 spin_unlock_bh(&hashlimit_lock); 297 spin_unlock_bh(&hashlimit_lock);
311 return hinfo; 298 return hinfo;
312 } 299 }
313 } 300 }
314 spin_unlock_bh(&hashlimit_lock); 301 spin_unlock_bh(&hashlimit_lock);
315
316 return NULL; 302 return NULL;
317} 303}
318 304
319static void htable_put(struct ipt_hashlimit_htable *hinfo) 305static void htable_put(struct xt_hashlimit_htable *hinfo)
320{ 306{
321 if (atomic_dec_and_test(&hinfo->use)) { 307 if (atomic_dec_and_test(&hinfo->use)) {
322 spin_lock_bh(&hashlimit_lock); 308 spin_lock_bh(&hashlimit_lock);
@@ -326,7 +312,6 @@ static void htable_put(struct ipt_hashlimit_htable *hinfo)
326 } 312 }
327} 313}
328 314
329
330/* The algorithm used is the Simple Token Bucket Filter (TBF) 315/* The algorithm used is the Simple Token Bucket Filter (TBF)
331 * see net/sched/sch_tbf.c in the linux source tree 316 * see net/sched/sch_tbf.c in the linux source tree
332 */ 317 */
@@ -370,17 +355,82 @@ user2credits(u_int32_t user)
370 /* If multiplying would overflow... */ 355 /* If multiplying would overflow... */
371 if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY)) 356 if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY))
372 /* Divide first. */ 357 /* Divide first. */
373 return (user / IPT_HASHLIMIT_SCALE) * HZ * CREDITS_PER_JIFFY; 358 return (user / XT_HASHLIMIT_SCALE) * HZ * CREDITS_PER_JIFFY;
374 359
375 return (user * HZ * CREDITS_PER_JIFFY) / IPT_HASHLIMIT_SCALE; 360 return (user * HZ * CREDITS_PER_JIFFY) / XT_HASHLIMIT_SCALE;
376} 361}
377 362
378static inline void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now) 363static inline void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now)
379{ 364{
380 dh->rateinfo.credit += (now - xchg(&dh->rateinfo.prev, now)) 365 dh->rateinfo.credit += (now - dh->rateinfo.prev) * CREDITS_PER_JIFFY;
381 * CREDITS_PER_JIFFY;
382 if (dh->rateinfo.credit > dh->rateinfo.credit_cap) 366 if (dh->rateinfo.credit > dh->rateinfo.credit_cap)
383 dh->rateinfo.credit = dh->rateinfo.credit_cap; 367 dh->rateinfo.credit = dh->rateinfo.credit_cap;
368 dh->rateinfo.prev = now;
369}
370
371static int
372hashlimit_init_dst(struct xt_hashlimit_htable *hinfo, struct dsthash_dst *dst,
373 const struct sk_buff *skb, unsigned int protoff)
374{
375 __be16 _ports[2], *ports;
376 int nexthdr;
377
378 memset(dst, 0, sizeof(*dst));
379
380 switch (hinfo->family) {
381 case AF_INET:
382 if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_DIP)
383 dst->addr.ip.dst = skb->nh.iph->daddr;
384 if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_SIP)
385 dst->addr.ip.src = skb->nh.iph->saddr;
386
387 if (!(hinfo->cfg.mode &
388 (XT_HASHLIMIT_HASH_DPT | XT_HASHLIMIT_HASH_SPT)))
389 return 0;
390 nexthdr = skb->nh.iph->protocol;
391 break;
392#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
393 case AF_INET6:
394 if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_DIP)
395 memcpy(&dst->addr.ip6.dst, &skb->nh.ipv6h->daddr,
396 sizeof(dst->addr.ip6.dst));
397 if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_SIP)
398 memcpy(&dst->addr.ip6.src, &skb->nh.ipv6h->saddr,
399 sizeof(dst->addr.ip6.src));
400
401 if (!(hinfo->cfg.mode &
402 (XT_HASHLIMIT_HASH_DPT | XT_HASHLIMIT_HASH_SPT)))
403 return 0;
404 nexthdr = ipv6_find_hdr(skb, &protoff, -1, NULL);
405 if (nexthdr < 0)
406 return -1;
407 break;
408#endif
409 default:
410 BUG();
411 return 0;
412 }
413
414 switch (nexthdr) {
415 case IPPROTO_TCP:
416 case IPPROTO_UDP:
417 case IPPROTO_SCTP:
418 case IPPROTO_DCCP:
419 ports = skb_header_pointer(skb, protoff, sizeof(_ports),
420 &_ports);
421 break;
422 default:
423 _ports[0] = _ports[1] = 0;
424 ports = _ports;
425 break;
426 }
427 if (!ports)
428 return -1;
429 if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_SPT)
430 dst->src_port = ports[0];
431 if (hinfo->cfg.mode & XT_HASHLIMIT_HASH_DPT)
432 dst->dst_port = ports[1];
433 return 0;
384} 434}
385 435
386static int 436static int
@@ -393,68 +443,31 @@ hashlimit_match(const struct sk_buff *skb,
393 unsigned int protoff, 443 unsigned int protoff,
394 int *hotdrop) 444 int *hotdrop)
395{ 445{
396 struct ipt_hashlimit_info *r = 446 struct xt_hashlimit_info *r =
397 ((struct ipt_hashlimit_info *)matchinfo)->u.master; 447 ((struct xt_hashlimit_info *)matchinfo)->u.master;
398 struct ipt_hashlimit_htable *hinfo = r->hinfo; 448 struct xt_hashlimit_htable *hinfo = r->hinfo;
399 unsigned long now = jiffies; 449 unsigned long now = jiffies;
400 struct dsthash_ent *dh; 450 struct dsthash_ent *dh;
401 struct dsthash_dst dst; 451 struct dsthash_dst dst;
402 452
403 /* build 'dst' according to hinfo->cfg and current packet */ 453 if (hashlimit_init_dst(hinfo, &dst, skb, protoff) < 0)
404 memset(&dst, 0, sizeof(dst)); 454 goto hotdrop;
405 if (hinfo->cfg.mode & IPT_HASHLIMIT_HASH_DIP)
406 dst.dst_ip = skb->nh.iph->daddr;
407 if (hinfo->cfg.mode & IPT_HASHLIMIT_HASH_SIP)
408 dst.src_ip = skb->nh.iph->saddr;
409 if (hinfo->cfg.mode & IPT_HASHLIMIT_HASH_DPT
410 ||hinfo->cfg.mode & IPT_HASHLIMIT_HASH_SPT) {
411 __be16 _ports[2], *ports;
412
413 switch (skb->nh.iph->protocol) {
414 case IPPROTO_TCP:
415 case IPPROTO_UDP:
416 case IPPROTO_SCTP:
417 case IPPROTO_DCCP:
418 ports = skb_header_pointer(skb, skb->nh.iph->ihl*4,
419 sizeof(_ports), &_ports);
420 break;
421 default:
422 _ports[0] = _ports[1] = 0;
423 ports = _ports;
424 break;
425 }
426 if (!ports) {
427 /* We've been asked to examine this packet, and we
428 can't. Hence, no choice but to drop. */
429 *hotdrop = 1;
430 return 0;
431 }
432 if (hinfo->cfg.mode & IPT_HASHLIMIT_HASH_SPT)
433 dst.src_port = ports[0];
434 if (hinfo->cfg.mode & IPT_HASHLIMIT_HASH_DPT)
435 dst.dst_port = ports[1];
436 }
437 455
438 spin_lock_bh(&hinfo->lock); 456 spin_lock_bh(&hinfo->lock);
439 dh = __dsthash_find(hinfo, &dst); 457 dh = dsthash_find(hinfo, &dst);
440 if (!dh) { 458 if (!dh) {
441 dh = __dsthash_alloc_init(hinfo, &dst); 459 dh = dsthash_alloc_init(hinfo, &dst);
442
443 if (!dh) { 460 if (!dh) {
444 /* enomem... don't match == DROP */
445 if (net_ratelimit())
446 printk(KERN_ERR "%s: ENOMEM\n", __FUNCTION__);
447 spin_unlock_bh(&hinfo->lock); 461 spin_unlock_bh(&hinfo->lock);
448 return 0; 462 goto hotdrop;
449 } 463 }
450 464
451 dh->expires = jiffies + msecs_to_jiffies(hinfo->cfg.expire); 465 dh->expires = jiffies + msecs_to_jiffies(hinfo->cfg.expire);
452
453 dh->rateinfo.prev = jiffies; 466 dh->rateinfo.prev = jiffies;
454 dh->rateinfo.credit = user2credits(hinfo->cfg.avg * 467 dh->rateinfo.credit = user2credits(hinfo->cfg.avg *
455 hinfo->cfg.burst); 468 hinfo->cfg.burst);
456 dh->rateinfo.credit_cap = user2credits(hinfo->cfg.avg * 469 dh->rateinfo.credit_cap = user2credits(hinfo->cfg.avg *
457 hinfo->cfg.burst); 470 hinfo->cfg.burst);
458 dh->rateinfo.cost = user2credits(hinfo->cfg.avg); 471 dh->rateinfo.cost = user2credits(hinfo->cfg.avg);
459 } else { 472 } else {
460 /* update expiration timeout */ 473 /* update expiration timeout */
@@ -473,6 +486,10 @@ hashlimit_match(const struct sk_buff *skb,
473 486
474 /* default case: we're overlimit, thus don't match */ 487 /* default case: we're overlimit, thus don't match */
475 return 0; 488 return 0;
489
490hotdrop:
491 *hotdrop = 1;
492 return 0;
476} 493}
477 494
478static int 495static int
@@ -482,42 +499,37 @@ hashlimit_checkentry(const char *tablename,
482 void *matchinfo, 499 void *matchinfo,
483 unsigned int hook_mask) 500 unsigned int hook_mask)
484{ 501{
485 struct ipt_hashlimit_info *r = matchinfo; 502 struct xt_hashlimit_info *r = matchinfo;
486 503
487 /* Check for overflow. */ 504 /* Check for overflow. */
488 if (r->cfg.burst == 0 505 if (r->cfg.burst == 0 ||
489 || user2credits(r->cfg.avg * r->cfg.burst) < 506 user2credits(r->cfg.avg * r->cfg.burst) < user2credits(r->cfg.avg)) {
490 user2credits(r->cfg.avg)) { 507 printk(KERN_ERR "xt_hashlimit: overflow, try lower: %u/%u\n",
491 printk(KERN_ERR "ipt_hashlimit: Overflow, try lower: %u/%u\n",
492 r->cfg.avg, r->cfg.burst); 508 r->cfg.avg, r->cfg.burst);
493 return 0; 509 return 0;
494 } 510 }
495 511 if (r->cfg.mode == 0 ||
496 if (r->cfg.mode == 0 512 r->cfg.mode > (XT_HASHLIMIT_HASH_DPT |
497 || r->cfg.mode > (IPT_HASHLIMIT_HASH_DPT 513 XT_HASHLIMIT_HASH_DIP |
498 |IPT_HASHLIMIT_HASH_DIP 514 XT_HASHLIMIT_HASH_SIP |
499 |IPT_HASHLIMIT_HASH_SIP 515 XT_HASHLIMIT_HASH_SPT))
500 |IPT_HASHLIMIT_HASH_SPT))
501 return 0; 516 return 0;
502
503 if (!r->cfg.gc_interval) 517 if (!r->cfg.gc_interval)
504 return 0; 518 return 0;
505
506 if (!r->cfg.expire) 519 if (!r->cfg.expire)
507 return 0; 520 return 0;
508
509 if (r->name[sizeof(r->name) - 1] != '\0') 521 if (r->name[sizeof(r->name) - 1] != '\0')
510 return 0; 522 return 0;
511 523
512 /* This is the best we've got: We cannot release and re-grab lock, 524 /* This is the best we've got: We cannot release and re-grab lock,
513 * since checkentry() is called before ip_tables.c grabs ipt_mutex. 525 * since checkentry() is called before x_tables.c grabs xt_mutex.
514 * We also cannot grab the hashtable spinlock, since htable_create will 526 * We also cannot grab the hashtable spinlock, since htable_create will
515 * call vmalloc, and that can sleep. And we cannot just re-search 527 * call vmalloc, and that can sleep. And we cannot just re-search
516 * the list of htable's in htable_create(), since then we would 528 * the list of htable's in htable_create(), since then we would
517 * create duplicate proc files. -HW */ 529 * create duplicate proc files. -HW */
518 mutex_lock(&hlimit_mutex); 530 mutex_lock(&hlimit_mutex);
519 r->hinfo = htable_find_get(r->name); 531 r->hinfo = htable_find_get(r->name, match->family);
520 if (!r->hinfo && (htable_create(r) != 0)) { 532 if (!r->hinfo && htable_create(r, match->family) != 0) {
521 mutex_unlock(&hlimit_mutex); 533 mutex_unlock(&hlimit_mutex);
522 return 0; 534 return 0;
523 } 535 }
@@ -525,20 +537,19 @@ hashlimit_checkentry(const char *tablename,
525 537
526 /* Ugly hack: For SMP, we only want to use one set */ 538 /* Ugly hack: For SMP, we only want to use one set */
527 r->u.master = r; 539 r->u.master = r;
528
529 return 1; 540 return 1;
530} 541}
531 542
532static void 543static void
533hashlimit_destroy(const struct xt_match *match, void *matchinfo) 544hashlimit_destroy(const struct xt_match *match, void *matchinfo)
534{ 545{
535 struct ipt_hashlimit_info *r = matchinfo; 546 struct xt_hashlimit_info *r = matchinfo;
536 547
537 htable_put(r->hinfo); 548 htable_put(r->hinfo);
538} 549}
539 550
540#ifdef CONFIG_COMPAT 551#ifdef CONFIG_COMPAT
541struct compat_ipt_hashlimit_info { 552struct compat_xt_hashlimit_info {
542 char name[IFNAMSIZ]; 553 char name[IFNAMSIZ];
543 struct hashlimit_cfg cfg; 554 struct hashlimit_cfg cfg;
544 compat_uptr_t hinfo; 555 compat_uptr_t hinfo;
@@ -547,40 +558,56 @@ struct compat_ipt_hashlimit_info {
547 558
548static void compat_from_user(void *dst, void *src) 559static void compat_from_user(void *dst, void *src)
549{ 560{
550 int off = offsetof(struct compat_ipt_hashlimit_info, hinfo); 561 int off = offsetof(struct compat_xt_hashlimit_info, hinfo);
551 562
552 memcpy(dst, src, off); 563 memcpy(dst, src, off);
553 memset(dst + off, 0, sizeof(struct compat_ipt_hashlimit_info) - off); 564 memset(dst + off, 0, sizeof(struct compat_xt_hashlimit_info) - off);
554} 565}
555 566
556static int compat_to_user(void __user *dst, void *src) 567static int compat_to_user(void __user *dst, void *src)
557{ 568{
558 int off = offsetof(struct compat_ipt_hashlimit_info, hinfo); 569 int off = offsetof(struct compat_xt_hashlimit_info, hinfo);
559 570
560 return copy_to_user(dst, src, off) ? -EFAULT : 0; 571 return copy_to_user(dst, src, off) ? -EFAULT : 0;
561} 572}
562#endif 573#endif
563 574
564static struct ipt_match ipt_hashlimit = { 575static struct xt_match xt_hashlimit[] = {
565 .name = "hashlimit", 576 {
566 .match = hashlimit_match, 577 .name = "hashlimit",
567 .matchsize = sizeof(struct ipt_hashlimit_info), 578 .family = AF_INET,
579 .match = hashlimit_match,
580 .matchsize = sizeof(struct xt_hashlimit_info),
581#ifdef CONFIG_COMPAT
582 .compatsize = sizeof(struct compat_xt_hashlimit_info),
583 .compat_from_user = compat_from_user,
584 .compat_to_user = compat_to_user,
585#endif
586 .checkentry = hashlimit_checkentry,
587 .destroy = hashlimit_destroy,
588 .me = THIS_MODULE
589 },
590 {
591 .name = "hashlimit",
592 .family = AF_INET6,
593 .match = hashlimit_match,
594 .matchsize = sizeof(struct xt_hashlimit_info),
568#ifdef CONFIG_COMPAT 595#ifdef CONFIG_COMPAT
569 .compatsize = sizeof(struct compat_ipt_hashlimit_info), 596 .compatsize = sizeof(struct compat_xt_hashlimit_info),
570 .compat_from_user = compat_from_user, 597 .compat_from_user = compat_from_user,
571 .compat_to_user = compat_to_user, 598 .compat_to_user = compat_to_user,
572#endif 599#endif
573 .checkentry = hashlimit_checkentry, 600 .checkentry = hashlimit_checkentry,
574 .destroy = hashlimit_destroy, 601 .destroy = hashlimit_destroy,
575 .me = THIS_MODULE 602 .me = THIS_MODULE
603 },
576}; 604};
577 605
578/* PROC stuff */ 606/* PROC stuff */
579
580static void *dl_seq_start(struct seq_file *s, loff_t *pos) 607static void *dl_seq_start(struct seq_file *s, loff_t *pos)
581{ 608{
582 struct proc_dir_entry *pde = s->private; 609 struct proc_dir_entry *pde = s->private;
583 struct ipt_hashlimit_htable *htable = pde->data; 610 struct xt_hashlimit_htable *htable = pde->data;
584 unsigned int *bucket; 611 unsigned int *bucket;
585 612
586 spin_lock_bh(&htable->lock); 613 spin_lock_bh(&htable->lock);
@@ -598,7 +625,7 @@ static void *dl_seq_start(struct seq_file *s, loff_t *pos)
598static void *dl_seq_next(struct seq_file *s, void *v, loff_t *pos) 625static void *dl_seq_next(struct seq_file *s, void *v, loff_t *pos)
599{ 626{
600 struct proc_dir_entry *pde = s->private; 627 struct proc_dir_entry *pde = s->private;
601 struct ipt_hashlimit_htable *htable = pde->data; 628 struct xt_hashlimit_htable *htable = pde->data;
602 unsigned int *bucket = (unsigned int *)v; 629 unsigned int *bucket = (unsigned int *)v;
603 630
604 *pos = ++(*bucket); 631 *pos = ++(*bucket);
@@ -612,43 +639,59 @@ static void *dl_seq_next(struct seq_file *s, void *v, loff_t *pos)
612static void dl_seq_stop(struct seq_file *s, void *v) 639static void dl_seq_stop(struct seq_file *s, void *v)
613{ 640{
614 struct proc_dir_entry *pde = s->private; 641 struct proc_dir_entry *pde = s->private;
615 struct ipt_hashlimit_htable *htable = pde->data; 642 struct xt_hashlimit_htable *htable = pde->data;
616 unsigned int *bucket = (unsigned int *)v; 643 unsigned int *bucket = (unsigned int *)v;
617 644
618 kfree(bucket); 645 kfree(bucket);
619
620 spin_unlock_bh(&htable->lock); 646 spin_unlock_bh(&htable->lock);
621} 647}
622 648
623static inline int dl_seq_real_show(struct dsthash_ent *ent, struct seq_file *s) 649static int dl_seq_real_show(struct dsthash_ent *ent, int family,
650 struct seq_file *s)
624{ 651{
625 /* recalculate to show accurate numbers */ 652 /* recalculate to show accurate numbers */
626 rateinfo_recalc(ent, jiffies); 653 rateinfo_recalc(ent, jiffies);
627 654
628 return seq_printf(s, "%ld %u.%u.%u.%u:%u->%u.%u.%u.%u:%u %u %u %u\n", 655 switch (family) {
629 (long)(ent->expires - jiffies)/HZ, 656 case AF_INET:
630 NIPQUAD(ent->dst.src_ip), ntohs(ent->dst.src_port), 657 return seq_printf(s, "%ld %u.%u.%u.%u:%u->"
631 NIPQUAD(ent->dst.dst_ip), ntohs(ent->dst.dst_port), 658 "%u.%u.%u.%u:%u %u %u %u\n",
632 ent->rateinfo.credit, ent->rateinfo.credit_cap, 659 (long)(ent->expires - jiffies)/HZ,
633 ent->rateinfo.cost); 660 NIPQUAD(ent->dst.addr.ip.src),
661 ntohs(ent->dst.src_port),
662 NIPQUAD(ent->dst.addr.ip.dst),
663 ntohs(ent->dst.dst_port),
664 ent->rateinfo.credit, ent->rateinfo.credit_cap,
665 ent->rateinfo.cost);
666 case AF_INET6:
667 return seq_printf(s, "%ld " NIP6_FMT ":%u->"
668 NIP6_FMT ":%u %u %u %u\n",
669 (long)(ent->expires - jiffies)/HZ,
670 NIP6(*(struct in6_addr *)&ent->dst.addr.ip6.src),
671 ntohs(ent->dst.src_port),
672 NIP6(*(struct in6_addr *)&ent->dst.addr.ip6.dst),
673 ntohs(ent->dst.dst_port),
674 ent->rateinfo.credit, ent->rateinfo.credit_cap,
675 ent->rateinfo.cost);
676 default:
677 BUG();
678 return 0;
679 }
634} 680}
635 681
636static int dl_seq_show(struct seq_file *s, void *v) 682static int dl_seq_show(struct seq_file *s, void *v)
637{ 683{
638 struct proc_dir_entry *pde = s->private; 684 struct proc_dir_entry *pde = s->private;
639 struct ipt_hashlimit_htable *htable = pde->data; 685 struct xt_hashlimit_htable *htable = pde->data;
640 unsigned int *bucket = (unsigned int *)v; 686 unsigned int *bucket = (unsigned int *)v;
641 struct dsthash_ent *ent; 687 struct dsthash_ent *ent;
642 struct hlist_node *pos; 688 struct hlist_node *pos;
643 689
644 if (!hlist_empty(&htable->hash[*bucket])) 690 if (!hlist_empty(&htable->hash[*bucket])) {
645 hlist_for_each_entry(ent, pos, &htable->hash[*bucket], node) { 691 hlist_for_each_entry(ent, pos, &htable->hash[*bucket], node)
646 if (dl_seq_real_show(ent, s)) { 692 if (dl_seq_real_show(ent, htable->family, s))
647 /* buffer was filled and unable to print that tuple */
648 return 1; 693 return 1;
649 } 694 }
650 }
651
652 return 0; 695 return 0;
653} 696}
654 697
@@ -678,56 +721,53 @@ static struct file_operations dl_file_ops = {
678 .release = seq_release 721 .release = seq_release
679}; 722};
680 723
681static int init_or_fini(int fini) 724static int __init xt_hashlimit_init(void)
682{ 725{
683 int ret = 0; 726 int err;
684
685 if (fini)
686 goto cleanup;
687 727
688 if (ipt_register_match(&ipt_hashlimit)) { 728 err = xt_register_matches(xt_hashlimit, ARRAY_SIZE(xt_hashlimit));
689 ret = -EINVAL; 729 if (err < 0)
690 goto cleanup_nothing; 730 goto err1;
691 }
692 731
693 hashlimit_cachep = kmem_cache_create("ipt_hashlimit", 732 err = -ENOMEM;
694 sizeof(struct dsthash_ent), 0, 733 hashlimit_cachep = kmem_cache_create("xt_hashlimit",
695 0, NULL, NULL); 734 sizeof(struct dsthash_ent), 0, 0,
735 NULL, NULL);
696 if (!hashlimit_cachep) { 736 if (!hashlimit_cachep) {
697 printk(KERN_ERR "Unable to create ipt_hashlimit slab cache\n"); 737 printk(KERN_ERR "xt_hashlimit: unable to create slab cache\n");
698 ret = -ENOMEM; 738 goto err2;
699 goto cleanup_unreg_match;
700 } 739 }
701 740 hashlimit_procdir4 = proc_mkdir("ipt_hashlimit", proc_net);
702 hashlimit_procdir = proc_mkdir("ipt_hashlimit", proc_net); 741 if (!hashlimit_procdir4) {
703 if (!hashlimit_procdir) { 742 printk(KERN_ERR "xt_hashlimit: unable to create proc dir "
704 printk(KERN_ERR "Unable to create proc dir entry\n"); 743 "entry\n");
705 ret = -ENOMEM; 744 goto err3;
706 goto cleanup_free_slab;
707 } 745 }
708 746 hashlimit_procdir6 = proc_mkdir("ip6t_hashlimit", proc_net);
709 return ret; 747 if (!hashlimit_procdir6) {
710 748 printk(KERN_ERR "xt_hashlimit: unable to create proc dir "
711cleanup: 749 "entry\n");
750 goto err4;
751 }
752 return 0;
753err4:
712 remove_proc_entry("ipt_hashlimit", proc_net); 754 remove_proc_entry("ipt_hashlimit", proc_net);
713cleanup_free_slab: 755err3:
714 kmem_cache_destroy(hashlimit_cachep); 756 kmem_cache_destroy(hashlimit_cachep);
715cleanup_unreg_match: 757err2:
716 ipt_unregister_match(&ipt_hashlimit); 758 xt_unregister_matches(xt_hashlimit, ARRAY_SIZE(xt_hashlimit));
717cleanup_nothing: 759err1:
718 return ret; 760 return err;
719
720}
721 761
722static int __init ipt_hashlimit_init(void)
723{
724 return init_or_fini(0);
725} 762}
726 763
727static void __exit ipt_hashlimit_fini(void) 764static void __exit xt_hashlimit_fini(void)
728{ 765{
729 init_or_fini(1); 766 remove_proc_entry("ipt_hashlimit", proc_net);
767 remove_proc_entry("ip6t_hashlimit", proc_net);
768 kmem_cache_destroy(hashlimit_cachep);
769 xt_unregister_matches(xt_hashlimit, ARRAY_SIZE(xt_hashlimit));
730} 770}
731 771
732module_init(ipt_hashlimit_init); 772module_init(xt_hashlimit_init);
733module_exit(ipt_hashlimit_fini); 773module_exit(xt_hashlimit_fini);
diff --git a/net/netfilter/xt_helper.c b/net/netfilter/xt_helper.c
index 5d7818b73e..04bc32ba71 100644
--- a/net/netfilter/xt_helper.c
+++ b/net/netfilter/xt_helper.c
@@ -24,6 +24,7 @@
24#endif 24#endif
25#include <linux/netfilter/x_tables.h> 25#include <linux/netfilter/x_tables.h>
26#include <linux/netfilter/xt_helper.h> 26#include <linux/netfilter/xt_helper.h>
27#include <net/netfilter/nf_conntrack_compat.h>
27 28
28MODULE_LICENSE("GPL"); 29MODULE_LICENSE("GPL");
29MODULE_AUTHOR("Martin Josefsson <gandalf@netfilter.org>"); 30MODULE_AUTHOR("Martin Josefsson <gandalf@netfilter.org>");
@@ -143,13 +144,11 @@ static int check(const char *tablename,
143{ 144{
144 struct xt_helper_info *info = matchinfo; 145 struct xt_helper_info *info = matchinfo;
145 146
146#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
147 if (nf_ct_l3proto_try_module_get(match->family) < 0) { 147 if (nf_ct_l3proto_try_module_get(match->family) < 0) {
148 printk(KERN_WARNING "can't load nf_conntrack support for " 148 printk(KERN_WARNING "can't load conntrack support for "
149 "proto=%d\n", match->family); 149 "proto=%d\n", match->family);
150 return 0; 150 return 0;
151 } 151 }
152#endif
153 info->name[29] = '\0'; 152 info->name[29] = '\0';
154 return 1; 153 return 1;
155} 154}
@@ -157,9 +156,7 @@ static int check(const char *tablename,
157static void 156static void
158destroy(const struct xt_match *match, void *matchinfo) 157destroy(const struct xt_match *match, void *matchinfo)
159{ 158{
160#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
161 nf_ct_l3proto_module_put(match->family); 159 nf_ct_l3proto_module_put(match->family);
162#endif
163} 160}
164 161
165static struct xt_match xt_helper_match[] = { 162static struct xt_match xt_helper_match[] = {
@@ -185,7 +182,6 @@ static struct xt_match xt_helper_match[] = {
185 182
186static int __init xt_helper_init(void) 183static int __init xt_helper_init(void)
187{ 184{
188 need_conntrack();
189 return xt_register_matches(xt_helper_match, 185 return xt_register_matches(xt_helper_match,
190 ARRAY_SIZE(xt_helper_match)); 186 ARRAY_SIZE(xt_helper_match));
191} 187}
diff --git a/net/netfilter/xt_mark.c b/net/netfilter/xt_mark.c
index 934dddfbcd..dfa1ee6914 100644
--- a/net/netfilter/xt_mark.c
+++ b/net/netfilter/xt_mark.c
@@ -31,7 +31,7 @@ match(const struct sk_buff *skb,
31{ 31{
32 const struct xt_mark_info *info = matchinfo; 32 const struct xt_mark_info *info = matchinfo;
33 33
34 return ((skb->nfmark & info->mask) == info->mark) ^ info->invert; 34 return ((skb->mark & info->mask) == info->mark) ^ info->invert;
35} 35}
36 36
37static int 37static int
diff --git a/net/netfilter/xt_multiport.c b/net/netfilter/xt_multiport.c
index d3aefd3809..1602086c7f 100644
--- a/net/netfilter/xt_multiport.c
+++ b/net/netfilter/xt_multiport.c
@@ -1,5 +1,5 @@
1/* Kernel module to match one of a list of TCP/UDP/SCTP/DCCP ports: ports are in 1/* Kernel module to match one of a list of TCP/UDP(-Lite)/SCTP/DCCP ports:
2 the same place so we can treat them as equal. */ 2 ports are in the same place so we can treat them as equal. */
3 3
4/* (C) 1999-2001 Paul `Rusty' Russell 4/* (C) 1999-2001 Paul `Rusty' Russell
5 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> 5 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
@@ -104,7 +104,7 @@ match(const struct sk_buff *skb,
104 unsigned int protoff, 104 unsigned int protoff,
105 int *hotdrop) 105 int *hotdrop)
106{ 106{
107 u16 _ports[2], *pptr; 107 __be16 _ports[2], *pptr;
108 const struct xt_multiport *multiinfo = matchinfo; 108 const struct xt_multiport *multiinfo = matchinfo;
109 109
110 if (offset) 110 if (offset)
@@ -135,7 +135,7 @@ match_v1(const struct sk_buff *skb,
135 unsigned int protoff, 135 unsigned int protoff,
136 int *hotdrop) 136 int *hotdrop)
137{ 137{
138 u16 _ports[2], *pptr; 138 __be16 _ports[2], *pptr;
139 const struct xt_multiport_v1 *multiinfo = matchinfo; 139 const struct xt_multiport_v1 *multiinfo = matchinfo;
140 140
141 if (offset) 141 if (offset)
@@ -162,6 +162,7 @@ check(u_int16_t proto,
162{ 162{
163 /* Must specify supported protocol, no unknown flags or bad count */ 163 /* Must specify supported protocol, no unknown flags or bad count */
164 return (proto == IPPROTO_TCP || proto == IPPROTO_UDP 164 return (proto == IPPROTO_TCP || proto == IPPROTO_UDP
165 || proto == IPPROTO_UDPLITE
165 || proto == IPPROTO_SCTP || proto == IPPROTO_DCCP) 166 || proto == IPPROTO_SCTP || proto == IPPROTO_DCCP)
166 && !(ip_invflags & XT_INV_PROTO) 167 && !(ip_invflags & XT_INV_PROTO)
167 && (match_flags == XT_MULTIPORT_SOURCE 168 && (match_flags == XT_MULTIPORT_SOURCE
diff --git a/net/netfilter/xt_physdev.c b/net/netfilter/xt_physdev.c
index fd8f954cde..b9b3ffc545 100644
--- a/net/netfilter/xt_physdev.c
+++ b/net/netfilter/xt_physdev.c
@@ -113,20 +113,16 @@ checkentry(const char *tablename,
113 if (!(info->bitmask & XT_PHYSDEV_OP_MASK) || 113 if (!(info->bitmask & XT_PHYSDEV_OP_MASK) ||
114 info->bitmask & ~XT_PHYSDEV_OP_MASK) 114 info->bitmask & ~XT_PHYSDEV_OP_MASK)
115 return 0; 115 return 0;
116 if (brnf_deferred_hooks == 0 && 116 if (info->bitmask & XT_PHYSDEV_OP_OUT &&
117 info->bitmask & XT_PHYSDEV_OP_OUT &&
118 (!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) || 117 (!(info->bitmask & XT_PHYSDEV_OP_BRIDGED) ||
119 info->invert & XT_PHYSDEV_OP_BRIDGED) && 118 info->invert & XT_PHYSDEV_OP_BRIDGED) &&
120 hook_mask & ((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) | 119 hook_mask & ((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) |
121 (1 << NF_IP_POST_ROUTING))) { 120 (1 << NF_IP_POST_ROUTING))) {
122 printk(KERN_WARNING "physdev match: using --physdev-out in the " 121 printk(KERN_WARNING "physdev match: using --physdev-out in the "
123 "OUTPUT, FORWARD and POSTROUTING chains for non-bridged " 122 "OUTPUT, FORWARD and POSTROUTING chains for non-bridged "
124 "traffic is deprecated and breaks other things, it will " 123 "traffic is not supported anymore.\n");
125 "be removed in January 2007. See Documentation/" 124 if (hook_mask & (1 << NF_IP_LOCAL_OUT))
126 "feature-removal-schedule.txt for details. This doesn't " 125 return 0;
127 "affect you in case you're using it for purely bridged "
128 "traffic.\n");
129 brnf_deferred_hooks = 1;
130 } 126 }
131 return 1; 127 return 1;
132} 128}
diff --git a/net/netfilter/xt_sctp.c b/net/netfilter/xt_sctp.c
index 7956acaaa2..71bf036f83 100644
--- a/net/netfilter/xt_sctp.c
+++ b/net/netfilter/xt_sctp.c
@@ -71,7 +71,7 @@ match_packet(const struct sk_buff *skb,
71 duprintf("Chunk num: %d\toffset: %d\ttype: %d\tlength: %d\tflags: %x\n", 71 duprintf("Chunk num: %d\toffset: %d\ttype: %d\tlength: %d\tflags: %x\n",
72 ++i, offset, sch->type, htons(sch->length), sch->flags); 72 ++i, offset, sch->type, htons(sch->length), sch->flags);
73 73
74 offset += (htons(sch->length) + 3) & ~3; 74 offset += (ntohs(sch->length) + 3) & ~3;
75 75
76 duprintf("skb->len: %d\toffset: %d\n", skb->len, offset); 76 duprintf("skb->len: %d\toffset: %d\n", skb->len, offset);
77 77
diff --git a/net/netfilter/xt_state.c b/net/netfilter/xt_state.c
index d9010b16a1..df37b91216 100644
--- a/net/netfilter/xt_state.c
+++ b/net/netfilter/xt_state.c
@@ -50,22 +50,18 @@ static int check(const char *tablename,
50 void *matchinfo, 50 void *matchinfo,
51 unsigned int hook_mask) 51 unsigned int hook_mask)
52{ 52{
53#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
54 if (nf_ct_l3proto_try_module_get(match->family) < 0) { 53 if (nf_ct_l3proto_try_module_get(match->family) < 0) {
55 printk(KERN_WARNING "can't load nf_conntrack support for " 54 printk(KERN_WARNING "can't load conntrack support for "
56 "proto=%d\n", match->family); 55 "proto=%d\n", match->family);
57 return 0; 56 return 0;
58 } 57 }
59#endif
60 return 1; 58 return 1;
61} 59}
62 60
63static void 61static void
64destroy(const struct xt_match *match, void *matchinfo) 62destroy(const struct xt_match *match, void *matchinfo)
65{ 63{
66#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
67 nf_ct_l3proto_module_put(match->family); 64 nf_ct_l3proto_module_put(match->family);
68#endif
69} 65}
70 66
71static struct xt_match xt_state_match[] = { 67static struct xt_match xt_state_match[] = {
@@ -91,7 +87,6 @@ static struct xt_match xt_state_match[] = {
91 87
92static int __init xt_state_init(void) 88static int __init xt_state_init(void)
93{ 89{
94 need_conntrack();
95 return xt_register_matches(xt_state_match, ARRAY_SIZE(xt_state_match)); 90 return xt_register_matches(xt_state_match, ARRAY_SIZE(xt_state_match));
96} 91}
97 92
diff --git a/net/netfilter/xt_tcpudp.c b/net/netfilter/xt_tcpudp.c
index e76a68e0bc..46414b562a 100644
--- a/net/netfilter/xt_tcpudp.c
+++ b/net/netfilter/xt_tcpudp.c
@@ -10,7 +10,7 @@
10#include <linux/netfilter_ipv4/ip_tables.h> 10#include <linux/netfilter_ipv4/ip_tables.h>
11#include <linux/netfilter_ipv6/ip6_tables.h> 11#include <linux/netfilter_ipv6/ip6_tables.h>
12 12
13MODULE_DESCRIPTION("x_tables match for TCP and UDP, supports IPv4 and IPv6"); 13MODULE_DESCRIPTION("x_tables match for TCP and UDP(-Lite), supports IPv4 and IPv6");
14MODULE_LICENSE("GPL"); 14MODULE_LICENSE("GPL");
15MODULE_ALIAS("xt_tcp"); 15MODULE_ALIAS("xt_tcp");
16MODULE_ALIAS("xt_udp"); 16MODULE_ALIAS("xt_udp");
@@ -234,6 +234,24 @@ static struct xt_match xt_tcpudp_match[] = {
234 .proto = IPPROTO_UDP, 234 .proto = IPPROTO_UDP,
235 .me = THIS_MODULE, 235 .me = THIS_MODULE,
236 }, 236 },
237 {
238 .name = "udplite",
239 .family = AF_INET,
240 .checkentry = udp_checkentry,
241 .match = udp_match,
242 .matchsize = sizeof(struct xt_udp),
243 .proto = IPPROTO_UDPLITE,
244 .me = THIS_MODULE,
245 },
246 {
247 .name = "udplite",
248 .family = AF_INET6,
249 .checkentry = udp_checkentry,
250 .match = udp_match,
251 .matchsize = sizeof(struct xt_udp),
252 .proto = IPPROTO_UDPLITE,
253 .me = THIS_MODULE,
254 },
237}; 255};
238 256
239static int __init xt_tcpudp_init(void) 257static int __init xt_tcpudp_init(void)
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c
index a6ce1d6d5c..73e0ff469b 100644
--- a/net/netlabel/netlabel_cipso_v4.c
+++ b/net/netlabel/netlabel_cipso_v4.c
@@ -130,12 +130,12 @@ static int netlbl_cipsov4_add_common(struct genl_info *info,
130 130
131 nla_for_each_nested(nla, info->attrs[NLBL_CIPSOV4_A_TAGLST], nla_rem) 131 nla_for_each_nested(nla, info->attrs[NLBL_CIPSOV4_A_TAGLST], nla_rem)
132 if (nla->nla_type == NLBL_CIPSOV4_A_TAG) { 132 if (nla->nla_type == NLBL_CIPSOV4_A_TAG) {
133 if (iter > CIPSO_V4_TAG_MAXCNT) 133 if (iter >= CIPSO_V4_TAG_MAXCNT)
134 return -EINVAL; 134 return -EINVAL;
135 doi_def->tags[iter++] = nla_get_u8(nla); 135 doi_def->tags[iter++] = nla_get_u8(nla);
136 } 136 }
137 if (iter < CIPSO_V4_TAG_MAXCNT) 137 while (iter < CIPSO_V4_TAG_MAXCNT)
138 doi_def->tags[iter] = CIPSO_V4_TAG_INVALID; 138 doi_def->tags[iter++] = CIPSO_V4_TAG_INVALID;
139 139
140 return 0; 140 return 0;
141} 141}
@@ -162,6 +162,7 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
162 struct nlattr *nla_b; 162 struct nlattr *nla_b;
163 int nla_a_rem; 163 int nla_a_rem;
164 int nla_b_rem; 164 int nla_b_rem;
165 u32 iter;
165 166
166 if (!info->attrs[NLBL_CIPSOV4_A_TAGLST] || 167 if (!info->attrs[NLBL_CIPSOV4_A_TAGLST] ||
167 !info->attrs[NLBL_CIPSOV4_A_MLSLVLLST]) 168 !info->attrs[NLBL_CIPSOV4_A_MLSLVLLST])
@@ -185,20 +186,31 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
185 ret_val = netlbl_cipsov4_add_common(info, doi_def); 186 ret_val = netlbl_cipsov4_add_common(info, doi_def);
186 if (ret_val != 0) 187 if (ret_val != 0)
187 goto add_std_failure; 188 goto add_std_failure;
189 ret_val = -EINVAL;
188 190
189 nla_for_each_nested(nla_a, 191 nla_for_each_nested(nla_a,
190 info->attrs[NLBL_CIPSOV4_A_MLSLVLLST], 192 info->attrs[NLBL_CIPSOV4_A_MLSLVLLST],
191 nla_a_rem) 193 nla_a_rem)
192 if (nla_a->nla_type == NLBL_CIPSOV4_A_MLSLVL) { 194 if (nla_a->nla_type == NLBL_CIPSOV4_A_MLSLVL) {
195 if (nla_validate_nested(nla_a,
196 NLBL_CIPSOV4_A_MAX,
197 netlbl_cipsov4_genl_policy) != 0)
198 goto add_std_failure;
193 nla_for_each_nested(nla_b, nla_a, nla_b_rem) 199 nla_for_each_nested(nla_b, nla_a, nla_b_rem)
194 switch (nla_b->nla_type) { 200 switch (nla_b->nla_type) {
195 case NLBL_CIPSOV4_A_MLSLVLLOC: 201 case NLBL_CIPSOV4_A_MLSLVLLOC:
202 if (nla_get_u32(nla_b) >
203 CIPSO_V4_MAX_LOC_LVLS)
204 goto add_std_failure;
196 if (nla_get_u32(nla_b) >= 205 if (nla_get_u32(nla_b) >=
197 doi_def->map.std->lvl.local_size) 206 doi_def->map.std->lvl.local_size)
198 doi_def->map.std->lvl.local_size = 207 doi_def->map.std->lvl.local_size =
199 nla_get_u32(nla_b) + 1; 208 nla_get_u32(nla_b) + 1;
200 break; 209 break;
201 case NLBL_CIPSOV4_A_MLSLVLREM: 210 case NLBL_CIPSOV4_A_MLSLVLREM:
211 if (nla_get_u32(nla_b) >
212 CIPSO_V4_MAX_REM_LVLS)
213 goto add_std_failure;
202 if (nla_get_u32(nla_b) >= 214 if (nla_get_u32(nla_b) >=
203 doi_def->map.std->lvl.cipso_size) 215 doi_def->map.std->lvl.cipso_size)
204 doi_def->map.std->lvl.cipso_size = 216 doi_def->map.std->lvl.cipso_size =
@@ -206,9 +218,6 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
206 break; 218 break;
207 } 219 }
208 } 220 }
209 if (doi_def->map.std->lvl.local_size > CIPSO_V4_MAX_LOC_LVLS ||
210 doi_def->map.std->lvl.cipso_size > CIPSO_V4_MAX_REM_LVLS)
211 goto add_std_failure;
212 doi_def->map.std->lvl.local = kcalloc(doi_def->map.std->lvl.local_size, 221 doi_def->map.std->lvl.local = kcalloc(doi_def->map.std->lvl.local_size,
213 sizeof(u32), 222 sizeof(u32),
214 GFP_KERNEL); 223 GFP_KERNEL);
@@ -223,6 +232,10 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
223 ret_val = -ENOMEM; 232 ret_val = -ENOMEM;
224 goto add_std_failure; 233 goto add_std_failure;
225 } 234 }
235 for (iter = 0; iter < doi_def->map.std->lvl.local_size; iter++)
236 doi_def->map.std->lvl.local[iter] = CIPSO_V4_INV_LVL;
237 for (iter = 0; iter < doi_def->map.std->lvl.cipso_size; iter++)
238 doi_def->map.std->lvl.cipso[iter] = CIPSO_V4_INV_LVL;
226 nla_for_each_nested(nla_a, 239 nla_for_each_nested(nla_a,
227 info->attrs[NLBL_CIPSOV4_A_MLSLVLLST], 240 info->attrs[NLBL_CIPSOV4_A_MLSLVLLST],
228 nla_a_rem) 241 nla_a_rem)
@@ -230,11 +243,6 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
230 struct nlattr *lvl_loc; 243 struct nlattr *lvl_loc;
231 struct nlattr *lvl_rem; 244 struct nlattr *lvl_rem;
232 245
233 if (nla_validate_nested(nla_a,
234 NLBL_CIPSOV4_A_MAX,
235 netlbl_cipsov4_genl_policy) != 0)
236 goto add_std_failure;
237
238 lvl_loc = nla_find_nested(nla_a, 246 lvl_loc = nla_find_nested(nla_a,
239 NLBL_CIPSOV4_A_MLSLVLLOC); 247 NLBL_CIPSOV4_A_MLSLVLLOC);
240 lvl_rem = nla_find_nested(nla_a, 248 lvl_rem = nla_find_nested(nla_a,
@@ -264,12 +272,18 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
264 nla_for_each_nested(nla_b, nla_a, nla_b_rem) 272 nla_for_each_nested(nla_b, nla_a, nla_b_rem)
265 switch (nla_b->nla_type) { 273 switch (nla_b->nla_type) {
266 case NLBL_CIPSOV4_A_MLSCATLOC: 274 case NLBL_CIPSOV4_A_MLSCATLOC:
275 if (nla_get_u32(nla_b) >
276 CIPSO_V4_MAX_LOC_CATS)
277 goto add_std_failure;
267 if (nla_get_u32(nla_b) >= 278 if (nla_get_u32(nla_b) >=
268 doi_def->map.std->cat.local_size) 279 doi_def->map.std->cat.local_size)
269 doi_def->map.std->cat.local_size = 280 doi_def->map.std->cat.local_size =
270 nla_get_u32(nla_b) + 1; 281 nla_get_u32(nla_b) + 1;
271 break; 282 break;
272 case NLBL_CIPSOV4_A_MLSCATREM: 283 case NLBL_CIPSOV4_A_MLSCATREM:
284 if (nla_get_u32(nla_b) >
285 CIPSO_V4_MAX_REM_CATS)
286 goto add_std_failure;
273 if (nla_get_u32(nla_b) >= 287 if (nla_get_u32(nla_b) >=
274 doi_def->map.std->cat.cipso_size) 288 doi_def->map.std->cat.cipso_size)
275 doi_def->map.std->cat.cipso_size = 289 doi_def->map.std->cat.cipso_size =
@@ -277,9 +291,6 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
277 break; 291 break;
278 } 292 }
279 } 293 }
280 if (doi_def->map.std->cat.local_size > CIPSO_V4_MAX_LOC_CATS ||
281 doi_def->map.std->cat.cipso_size > CIPSO_V4_MAX_REM_CATS)
282 goto add_std_failure;
283 doi_def->map.std->cat.local = kcalloc( 294 doi_def->map.std->cat.local = kcalloc(
284 doi_def->map.std->cat.local_size, 295 doi_def->map.std->cat.local_size,
285 sizeof(u32), 296 sizeof(u32),
@@ -296,6 +307,10 @@ static int netlbl_cipsov4_add_std(struct genl_info *info)
296 ret_val = -ENOMEM; 307 ret_val = -ENOMEM;
297 goto add_std_failure; 308 goto add_std_failure;
298 } 309 }
310 for (iter = 0; iter < doi_def->map.std->cat.local_size; iter++)
311 doi_def->map.std->cat.local[iter] = CIPSO_V4_INV_CAT;
312 for (iter = 0; iter < doi_def->map.std->cat.cipso_size; iter++)
313 doi_def->map.std->cat.cipso[iter] = CIPSO_V4_INV_CAT;
299 nla_for_each_nested(nla_a, 314 nla_for_each_nested(nla_a,
300 info->attrs[NLBL_CIPSOV4_A_MLSCATLST], 315 info->attrs[NLBL_CIPSOV4_A_MLSCATLST],
301 nla_a_rem) 316 nla_a_rem)
@@ -407,12 +422,14 @@ static int netlbl_cipsov4_add(struct sk_buff *skb, struct genl_info *info)
407 422
408 audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD, 423 audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD,
409 &audit_info); 424 &audit_info);
410 audit_log_format(audit_buf, 425 if (audit_buf != NULL) {
411 " cipso_doi=%u cipso_type=%s res=%u", 426 audit_log_format(audit_buf,
412 doi, 427 " cipso_doi=%u cipso_type=%s res=%u",
413 type_str, 428 doi,
414 ret_val == 0 ? 1 : 0); 429 type_str,
415 audit_log_end(audit_buf); 430 ret_val == 0 ? 1 : 0);
431 audit_log_end(audit_buf);
432 }
416 433
417 return ret_val; 434 return ret_val;
418} 435}
@@ -452,17 +469,13 @@ static int netlbl_cipsov4_list(struct sk_buff *skb, struct genl_info *info)
452 } 469 }
453 470
454list_start: 471list_start:
455 ans_skb = nlmsg_new(NLMSG_GOODSIZE * nlsze_mult, GFP_KERNEL); 472 ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE * nlsze_mult, GFP_KERNEL);
456 if (ans_skb == NULL) { 473 if (ans_skb == NULL) {
457 ret_val = -ENOMEM; 474 ret_val = -ENOMEM;
458 goto list_failure; 475 goto list_failure;
459 } 476 }
460 data = netlbl_netlink_hdr_put(ans_skb, 477 data = genlmsg_put_reply(ans_skb, info, &netlbl_cipsov4_gnl_family,
461 info->snd_pid, 478 0, NLBL_CIPSOV4_C_LIST);
462 info->snd_seq,
463 netlbl_cipsov4_gnl_family.id,
464 0,
465 NLBL_CIPSOV4_C_LIST);
466 if (data == NULL) { 479 if (data == NULL) {
467 ret_val = -ENOMEM; 480 ret_val = -ENOMEM;
468 goto list_failure; 481 goto list_failure;
@@ -568,7 +581,7 @@ list_start:
568 581
569 genlmsg_end(ans_skb, data); 582 genlmsg_end(ans_skb, data);
570 583
571 ret_val = genlmsg_unicast(ans_skb, info->snd_pid); 584 ret_val = genlmsg_reply(ans_skb, info);
572 if (ret_val != 0) 585 if (ret_val != 0)
573 goto list_failure; 586 goto list_failure;
574 587
@@ -607,12 +620,9 @@ static int netlbl_cipsov4_listall_cb(struct cipso_v4_doi *doi_def, void *arg)
607 struct netlbl_cipsov4_doiwalk_arg *cb_arg = arg; 620 struct netlbl_cipsov4_doiwalk_arg *cb_arg = arg;
608 void *data; 621 void *data;
609 622
610 data = netlbl_netlink_hdr_put(cb_arg->skb, 623 data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).pid,
611 NETLINK_CB(cb_arg->nl_cb->skb).pid, 624 cb_arg->seq, &netlbl_cipsov4_gnl_family,
612 cb_arg->seq, 625 NLM_F_MULTI, NLBL_CIPSOV4_C_LISTALL);
613 netlbl_cipsov4_gnl_family.id,
614 NLM_F_MULTI,
615 NLBL_CIPSOV4_C_LISTALL);
616 if (data == NULL) 626 if (data == NULL)
617 goto listall_cb_failure; 627 goto listall_cb_failure;
618 628
@@ -687,11 +697,13 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info)
687 697
688 audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_DEL, 698 audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_DEL,
689 &audit_info); 699 &audit_info);
690 audit_log_format(audit_buf, 700 if (audit_buf != NULL) {
691 " cipso_doi=%u res=%u", 701 audit_log_format(audit_buf,
692 doi, 702 " cipso_doi=%u res=%u",
693 ret_val == 0 ? 1 : 0); 703 doi,
694 audit_log_end(audit_buf); 704 ret_val == 0 ? 1 : 0);
705 audit_log_end(audit_buf);
706 }
695 707
696 return ret_val; 708 return ret_val;
697} 709}
diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c
index af4371d3b4..f46a0aeec4 100644
--- a/net/netlabel/netlabel_domainhash.c
+++ b/net/netlabel/netlabel_domainhash.c
@@ -202,7 +202,6 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
202 int ret_val; 202 int ret_val;
203 u32 bkt; 203 u32 bkt;
204 struct audit_buffer *audit_buf; 204 struct audit_buffer *audit_buf;
205 char *audit_domain;
206 205
207 switch (entry->type) { 206 switch (entry->type) {
208 case NETLBL_NLTYPE_UNLABELED: 207 case NETLBL_NLTYPE_UNLABELED:
@@ -243,24 +242,24 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
243 } else 242 } else
244 ret_val = -EINVAL; 243 ret_val = -EINVAL;
245 244
246 if (entry->domain != NULL)
247 audit_domain = entry->domain;
248 else
249 audit_domain = "(default)";
250 audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_ADD, audit_info); 245 audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_ADD, audit_info);
251 audit_log_format(audit_buf, " nlbl_domain=%s", audit_domain); 246 if (audit_buf != NULL) {
252 switch (entry->type) {
253 case NETLBL_NLTYPE_UNLABELED:
254 audit_log_format(audit_buf, " nlbl_protocol=unlbl");
255 break;
256 case NETLBL_NLTYPE_CIPSOV4:
257 audit_log_format(audit_buf, 247 audit_log_format(audit_buf,
258 " nlbl_protocol=cipsov4 cipso_doi=%u", 248 " nlbl_domain=%s",
259 entry->type_def.cipsov4->doi); 249 entry->domain ? entry->domain : "(default)");
260 break; 250 switch (entry->type) {
251 case NETLBL_NLTYPE_UNLABELED:
252 audit_log_format(audit_buf, " nlbl_protocol=unlbl");
253 break;
254 case NETLBL_NLTYPE_CIPSOV4:
255 audit_log_format(audit_buf,
256 " nlbl_protocol=cipsov4 cipso_doi=%u",
257 entry->type_def.cipsov4->doi);
258 break;
259 }
260 audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0);
261 audit_log_end(audit_buf);
261 } 262 }
262 audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0);
263 audit_log_end(audit_buf);
264 263
265 rcu_read_unlock(); 264 rcu_read_unlock();
266 265
@@ -310,7 +309,6 @@ int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info)
310 int ret_val = -ENOENT; 309 int ret_val = -ENOENT;
311 struct netlbl_dom_map *entry; 310 struct netlbl_dom_map *entry;
312 struct audit_buffer *audit_buf; 311 struct audit_buffer *audit_buf;
313 char *audit_domain;
314 312
315 rcu_read_lock(); 313 rcu_read_lock();
316 if (domain != NULL) 314 if (domain != NULL)
@@ -348,16 +346,14 @@ int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info)
348 spin_unlock(&netlbl_domhsh_def_lock); 346 spin_unlock(&netlbl_domhsh_def_lock);
349 } 347 }
350 348
351 if (entry->domain != NULL)
352 audit_domain = entry->domain;
353 else
354 audit_domain = "(default)";
355 audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_DEL, audit_info); 349 audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_DEL, audit_info);
356 audit_log_format(audit_buf, 350 if (audit_buf != NULL) {
357 " nlbl_domain=%s res=%u", 351 audit_log_format(audit_buf,
358 audit_domain, 352 " nlbl_domain=%s res=%u",
359 ret_val == 0 ? 1 : 0); 353 entry->domain ? entry->domain : "(default)",
360 audit_log_end(audit_buf); 354 ret_val == 0 ? 1 : 0);
355 audit_log_end(audit_buf);
356 }
361 357
362 if (ret_val == 0) 358 if (ret_val == 0)
363 call_rcu(&entry->rcu, netlbl_domhsh_free_entry); 359 call_rcu(&entry->rcu, netlbl_domhsh_free_entry);
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index ff971103fd..e03a3282c5 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -40,6 +40,207 @@
40#include "netlabel_user.h" 40#include "netlabel_user.h"
41 41
42/* 42/*
43 * Security Attribute Functions
44 */
45
46/**
47 * netlbl_secattr_catmap_walk - Walk a LSM secattr catmap looking for a bit
48 * @catmap: the category bitmap
49 * @offset: the offset to start searching at, in bits
50 *
51 * Description:
52 * This function walks a LSM secattr category bitmap starting at @offset and
53 * returns the spot of the first set bit or -ENOENT if no bits are set.
54 *
55 */
56int netlbl_secattr_catmap_walk(struct netlbl_lsm_secattr_catmap *catmap,
57 u32 offset)
58{
59 struct netlbl_lsm_secattr_catmap *iter = catmap;
60 u32 node_idx;
61 u32 node_bit;
62 NETLBL_CATMAP_MAPTYPE bitmap;
63
64 if (offset > iter->startbit) {
65 while (offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) {
66 iter = iter->next;
67 if (iter == NULL)
68 return -ENOENT;
69 }
70 node_idx = (offset - iter->startbit) / NETLBL_CATMAP_MAPSIZE;
71 node_bit = offset - iter->startbit -
72 (NETLBL_CATMAP_MAPSIZE * node_idx);
73 } else {
74 node_idx = 0;
75 node_bit = 0;
76 }
77 bitmap = iter->bitmap[node_idx] >> node_bit;
78
79 for (;;) {
80 if (bitmap != 0) {
81 while ((bitmap & NETLBL_CATMAP_BIT) == 0) {
82 bitmap >>= 1;
83 node_bit++;
84 }
85 return iter->startbit +
86 (NETLBL_CATMAP_MAPSIZE * node_idx) + node_bit;
87 }
88 if (++node_idx >= NETLBL_CATMAP_MAPCNT) {
89 if (iter->next != NULL) {
90 iter = iter->next;
91 node_idx = 0;
92 } else
93 return -ENOENT;
94 }
95 bitmap = iter->bitmap[node_idx];
96 node_bit = 0;
97 }
98
99 return -ENOENT;
100}
101
102/**
103 * netlbl_secattr_catmap_walk_rng - Find the end of a string of set bits
104 * @catmap: the category bitmap
105 * @offset: the offset to start searching at, in bits
106 *
107 * Description:
108 * This function walks a LSM secattr category bitmap starting at @offset and
109 * returns the spot of the first cleared bit or -ENOENT if the offset is past
110 * the end of the bitmap.
111 *
112 */
113int netlbl_secattr_catmap_walk_rng(struct netlbl_lsm_secattr_catmap *catmap,
114 u32 offset)
115{
116 struct netlbl_lsm_secattr_catmap *iter = catmap;
117 u32 node_idx;
118 u32 node_bit;
119 NETLBL_CATMAP_MAPTYPE bitmask;
120 NETLBL_CATMAP_MAPTYPE bitmap;
121
122 if (offset > iter->startbit) {
123 while (offset >= (iter->startbit + NETLBL_CATMAP_SIZE)) {
124 iter = iter->next;
125 if (iter == NULL)
126 return -ENOENT;
127 }
128 node_idx = (offset - iter->startbit) / NETLBL_CATMAP_MAPSIZE;
129 node_bit = offset - iter->startbit -
130 (NETLBL_CATMAP_MAPSIZE * node_idx);
131 } else {
132 node_idx = 0;
133 node_bit = 0;
134 }
135 bitmask = NETLBL_CATMAP_BIT << node_bit;
136
137 for (;;) {
138 bitmap = iter->bitmap[node_idx];
139 while (bitmask != 0 && (bitmap & bitmask) != 0) {
140 bitmask <<= 1;
141 node_bit++;
142 }
143
144 if (bitmask != 0)
145 return iter->startbit +
146 (NETLBL_CATMAP_MAPSIZE * node_idx) +
147 node_bit - 1;
148 else if (++node_idx >= NETLBL_CATMAP_MAPCNT) {
149 if (iter->next == NULL)
150 return iter->startbit + NETLBL_CATMAP_SIZE - 1;
151 iter = iter->next;
152 node_idx = 0;
153 }
154 bitmask = NETLBL_CATMAP_BIT;
155 node_bit = 0;
156 }
157
158 return -ENOENT;
159}
160
161/**
162 * netlbl_secattr_catmap_setbit - Set a bit in a LSM secattr catmap
163 * @catmap: the category bitmap
164 * @bit: the bit to set
165 * @flags: memory allocation flags
166 *
167 * Description:
168 * Set the bit specified by @bit in @catmap. Returns zero on success,
169 * negative values on failure.
170 *
171 */
172int netlbl_secattr_catmap_setbit(struct netlbl_lsm_secattr_catmap *catmap,
173 u32 bit,
174 gfp_t flags)
175{
176 struct netlbl_lsm_secattr_catmap *iter = catmap;
177 u32 node_bit;
178 u32 node_idx;
179
180 while (iter->next != NULL &&
181 bit >= (iter->startbit + NETLBL_CATMAP_SIZE))
182 iter = iter->next;
183 if (bit >= (iter->startbit + NETLBL_CATMAP_SIZE)) {
184 iter->next = netlbl_secattr_catmap_alloc(flags);
185 if (iter->next == NULL)
186 return -ENOMEM;
187 iter = iter->next;
188 iter->startbit = bit & ~(NETLBL_CATMAP_SIZE - 1);
189 }
190
191 /* gcc always rounds to zero when doing integer division */
192 node_idx = (bit - iter->startbit) / NETLBL_CATMAP_MAPSIZE;
193 node_bit = bit - iter->startbit - (NETLBL_CATMAP_MAPSIZE * node_idx);
194 iter->bitmap[node_idx] |= NETLBL_CATMAP_BIT << node_bit;
195
196 return 0;
197}
198
199/**
200 * netlbl_secattr_catmap_setrng - Set a range of bits in a LSM secattr catmap
201 * @catmap: the category bitmap
202 * @start: the starting bit
203 * @end: the last bit in the string
204 * @flags: memory allocation flags
205 *
206 * Description:
207 * Set a range of bits, starting at @start and ending with @end. Returns zero
208 * on success, negative values on failure.
209 *
210 */
211int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap,
212 u32 start,
213 u32 end,
214 gfp_t flags)
215{
216 int ret_val = 0;
217 struct netlbl_lsm_secattr_catmap *iter = catmap;
218 u32 iter_max_spot;
219 u32 spot;
220
221 /* XXX - This could probably be made a bit faster by combining writes
222 * to the catmap instead of setting a single bit each time, but for
223 * right now skipping to the start of the range in the catmap should
224 * be a nice improvement over calling the individual setbit function
225 * repeatedly from a loop. */
226
227 while (iter->next != NULL &&
228 start >= (iter->startbit + NETLBL_CATMAP_SIZE))
229 iter = iter->next;
230 iter_max_spot = iter->startbit + NETLBL_CATMAP_SIZE;
231
232 for (spot = start; spot <= end && ret_val == 0; spot++) {
233 if (spot >= iter_max_spot && iter->next != NULL) {
234 iter = iter->next;
235 iter_max_spot = iter->startbit + NETLBL_CATMAP_SIZE;
236 }
237 ret_val = netlbl_secattr_catmap_setbit(iter, spot, GFP_ATOMIC);
238 }
239
240 return ret_val;
241}
242
243/*
43 * LSM Functions 244 * LSM Functions
44 */ 245 */
45 246
@@ -62,6 +263,9 @@ int netlbl_socket_setattr(const struct socket *sock,
62 int ret_val = -ENOENT; 263 int ret_val = -ENOENT;
63 struct netlbl_dom_map *dom_entry; 264 struct netlbl_dom_map *dom_entry;
64 265
266 if ((secattr->flags & NETLBL_SECATTR_DOMAIN) == 0)
267 return -ENOENT;
268
65 rcu_read_lock(); 269 rcu_read_lock();
66 dom_entry = netlbl_domhsh_getentry(secattr->domain); 270 dom_entry = netlbl_domhsh_getentry(secattr->domain);
67 if (dom_entry == NULL) 271 if (dom_entry == NULL)
@@ -146,10 +350,8 @@ int netlbl_socket_getattr(const struct socket *sock,
146int netlbl_skbuff_getattr(const struct sk_buff *skb, 350int netlbl_skbuff_getattr(const struct sk_buff *skb,
147 struct netlbl_lsm_secattr *secattr) 351 struct netlbl_lsm_secattr *secattr)
148{ 352{
149 int ret_val; 353 if (CIPSO_V4_OPTEXIST(skb) &&
150 354 cipso_v4_skbuff_getattr(skb, secattr) == 0)
151 ret_val = cipso_v4_skbuff_getattr(skb, secattr);
152 if (ret_val == 0)
153 return 0; 355 return 0;
154 356
155 return netlbl_unlabel_getattr(secattr); 357 return netlbl_unlabel_getattr(secattr);
@@ -200,7 +402,7 @@ void netlbl_cache_invalidate(void)
200int netlbl_cache_add(const struct sk_buff *skb, 402int netlbl_cache_add(const struct sk_buff *skb,
201 const struct netlbl_lsm_secattr *secattr) 403 const struct netlbl_lsm_secattr *secattr)
202{ 404{
203 if (secattr->cache == NULL) 405 if ((secattr->flags & NETLBL_SECATTR_CACHE) == 0)
204 return -ENOMSG; 406 return -ENOMSG;
205 407
206 if (CIPSO_V4_OPTEXIST(skb)) 408 if (CIPSO_V4_OPTEXIST(skb))
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
index 53c9079ad2..e8c80f33f3 100644
--- a/net/netlabel/netlabel_mgmt.c
+++ b/net/netlabel/netlabel_mgmt.c
@@ -188,12 +188,9 @@ static int netlbl_mgmt_listall_cb(struct netlbl_dom_map *entry, void *arg)
188 struct netlbl_domhsh_walk_arg *cb_arg = arg; 188 struct netlbl_domhsh_walk_arg *cb_arg = arg;
189 void *data; 189 void *data;
190 190
191 data = netlbl_netlink_hdr_put(cb_arg->skb, 191 data = genlmsg_put(cb_arg->skb, NETLINK_CB(cb_arg->nl_cb->skb).pid,
192 NETLINK_CB(cb_arg->nl_cb->skb).pid, 192 cb_arg->seq, &netlbl_mgmt_gnl_family,
193 cb_arg->seq, 193 NLM_F_MULTI, NLBL_MGMT_C_LISTALL);
194 netlbl_mgmt_gnl_family.id,
195 NLM_F_MULTI,
196 NLBL_MGMT_C_LISTALL);
197 if (data == NULL) 194 if (data == NULL)
198 goto listall_cb_failure; 195 goto listall_cb_failure;
199 196
@@ -356,15 +353,11 @@ static int netlbl_mgmt_listdef(struct sk_buff *skb, struct genl_info *info)
356 void *data; 353 void *data;
357 struct netlbl_dom_map *entry; 354 struct netlbl_dom_map *entry;
358 355
359 ans_skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 356 ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
360 if (ans_skb == NULL) 357 if (ans_skb == NULL)
361 return -ENOMEM; 358 return -ENOMEM;
362 data = netlbl_netlink_hdr_put(ans_skb, 359 data = genlmsg_put_reply(ans_skb, info, &netlbl_mgmt_gnl_family,
363 info->snd_pid, 360 0, NLBL_MGMT_C_LISTDEF);
364 info->snd_seq,
365 netlbl_mgmt_gnl_family.id,
366 0,
367 NLBL_MGMT_C_LISTDEF);
368 if (data == NULL) 361 if (data == NULL)
369 goto listdef_failure; 362 goto listdef_failure;
370 363
@@ -390,7 +383,7 @@ static int netlbl_mgmt_listdef(struct sk_buff *skb, struct genl_info *info)
390 383
391 genlmsg_end(ans_skb, data); 384 genlmsg_end(ans_skb, data);
392 385
393 ret_val = genlmsg_unicast(ans_skb, info->snd_pid); 386 ret_val = genlmsg_reply(ans_skb, info);
394 if (ret_val != 0) 387 if (ret_val != 0)
395 goto listdef_failure; 388 goto listdef_failure;
396 return 0; 389 return 0;
@@ -422,12 +415,9 @@ static int netlbl_mgmt_protocols_cb(struct sk_buff *skb,
422 int ret_val = -ENOMEM; 415 int ret_val = -ENOMEM;
423 void *data; 416 void *data;
424 417
425 data = netlbl_netlink_hdr_put(skb, 418 data = genlmsg_put(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq,
426 NETLINK_CB(cb->skb).pid, 419 &netlbl_mgmt_gnl_family, NLM_F_MULTI,
427 cb->nlh->nlmsg_seq, 420 NLBL_MGMT_C_PROTOCOLS);
428 netlbl_mgmt_gnl_family.id,
429 NLM_F_MULTI,
430 NLBL_MGMT_C_PROTOCOLS);
431 if (data == NULL) 421 if (data == NULL)
432 goto protocols_cb_failure; 422 goto protocols_cb_failure;
433 423
@@ -492,15 +482,11 @@ static int netlbl_mgmt_version(struct sk_buff *skb, struct genl_info *info)
492 struct sk_buff *ans_skb = NULL; 482 struct sk_buff *ans_skb = NULL;
493 void *data; 483 void *data;
494 484
495 ans_skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 485 ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
496 if (ans_skb == NULL) 486 if (ans_skb == NULL)
497 return -ENOMEM; 487 return -ENOMEM;
498 data = netlbl_netlink_hdr_put(ans_skb, 488 data = genlmsg_put_reply(ans_skb, info, &netlbl_mgmt_gnl_family,
499 info->snd_pid, 489 0, NLBL_MGMT_C_VERSION);
500 info->snd_seq,
501 netlbl_mgmt_gnl_family.id,
502 0,
503 NLBL_MGMT_C_VERSION);
504 if (data == NULL) 490 if (data == NULL)
505 goto version_failure; 491 goto version_failure;
506 492
@@ -512,7 +498,7 @@ static int netlbl_mgmt_version(struct sk_buff *skb, struct genl_info *info)
512 498
513 genlmsg_end(ans_skb, data); 499 genlmsg_end(ans_skb, data);
514 500
515 ret_val = genlmsg_unicast(ans_skb, info->snd_pid); 501 ret_val = genlmsg_reply(ans_skb, info);
516 if (ret_val != 0) 502 if (ret_val != 0)
517 goto version_failure; 503 goto version_failure;
518 return 0; 504 return 0;
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index 1833ad233b..5bc3718166 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -35,6 +35,7 @@
35#include <linux/socket.h> 35#include <linux/socket.h>
36#include <linux/string.h> 36#include <linux/string.h>
37#include <linux/skbuff.h> 37#include <linux/skbuff.h>
38#include <linux/audit.h>
38#include <net/sock.h> 39#include <net/sock.h>
39#include <net/netlink.h> 40#include <net/netlink.h>
40#include <net/genetlink.h> 41#include <net/genetlink.h>
@@ -47,7 +48,8 @@
47#include "netlabel_unlabeled.h" 48#include "netlabel_unlabeled.h"
48 49
49/* Accept unlabeled packets flag */ 50/* Accept unlabeled packets flag */
50static atomic_t netlabel_unlabel_accept_flg = ATOMIC_INIT(0); 51static DEFINE_SPINLOCK(netlabel_unlabel_acceptflg_lock);
52static u8 netlabel_unlabel_acceptflg = 0;
51 53
52/* NetLabel Generic NETLINK CIPSOv4 family */ 54/* NetLabel Generic NETLINK CIPSOv4 family */
53static struct genl_family netlbl_unlabel_gnl_family = { 55static struct genl_family netlbl_unlabel_gnl_family = {
@@ -82,13 +84,20 @@ static void netlbl_unlabel_acceptflg_set(u8 value,
82 struct audit_buffer *audit_buf; 84 struct audit_buffer *audit_buf;
83 u8 old_val; 85 u8 old_val;
84 86
85 old_val = atomic_read(&netlabel_unlabel_accept_flg); 87 rcu_read_lock();
86 atomic_set(&netlabel_unlabel_accept_flg, value); 88 old_val = netlabel_unlabel_acceptflg;
89 spin_lock(&netlabel_unlabel_acceptflg_lock);
90 netlabel_unlabel_acceptflg = value;
91 spin_unlock(&netlabel_unlabel_acceptflg_lock);
92 rcu_read_unlock();
87 93
88 audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_ALLOW, 94 audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_ALLOW,
89 audit_info); 95 audit_info);
90 audit_log_format(audit_buf, " unlbl_accept=%u old=%u", value, old_val); 96 if (audit_buf != NULL) {
91 audit_log_end(audit_buf); 97 audit_log_format(audit_buf,
98 " unlbl_accept=%u old=%u", value, old_val);
99 audit_log_end(audit_buf);
100 }
92} 101}
93 102
94/* 103/*
@@ -138,29 +147,27 @@ static int netlbl_unlabel_list(struct sk_buff *skb, struct genl_info *info)
138 struct sk_buff *ans_skb; 147 struct sk_buff *ans_skb;
139 void *data; 148 void *data;
140 149
141 ans_skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 150 ans_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
142 if (ans_skb == NULL) 151 if (ans_skb == NULL)
143 goto list_failure; 152 goto list_failure;
144 data = netlbl_netlink_hdr_put(ans_skb, 153 data = genlmsg_put_reply(ans_skb, info, &netlbl_unlabel_gnl_family,
145 info->snd_pid, 154 0, NLBL_UNLABEL_C_LIST);
146 info->snd_seq,
147 netlbl_unlabel_gnl_family.id,
148 0,
149 NLBL_UNLABEL_C_LIST);
150 if (data == NULL) { 155 if (data == NULL) {
151 ret_val = -ENOMEM; 156 ret_val = -ENOMEM;
152 goto list_failure; 157 goto list_failure;
153 } 158 }
154 159
160 rcu_read_lock();
155 ret_val = nla_put_u8(ans_skb, 161 ret_val = nla_put_u8(ans_skb,
156 NLBL_UNLABEL_A_ACPTFLG, 162 NLBL_UNLABEL_A_ACPTFLG,
157 atomic_read(&netlabel_unlabel_accept_flg)); 163 netlabel_unlabel_acceptflg);
164 rcu_read_unlock();
158 if (ret_val != 0) 165 if (ret_val != 0)
159 goto list_failure; 166 goto list_failure;
160 167
161 genlmsg_end(ans_skb, data); 168 genlmsg_end(ans_skb, data);
162 169
163 ret_val = genlmsg_unicast(ans_skb, info->snd_pid); 170 ret_val = genlmsg_reply(ans_skb, info);
164 if (ret_val != 0) 171 if (ret_val != 0)
165 goto list_failure; 172 goto list_failure;
166 return 0; 173 return 0;
@@ -240,10 +247,17 @@ int netlbl_unlabel_genl_init(void)
240 */ 247 */
241int netlbl_unlabel_getattr(struct netlbl_lsm_secattr *secattr) 248int netlbl_unlabel_getattr(struct netlbl_lsm_secattr *secattr)
242{ 249{
243 if (atomic_read(&netlabel_unlabel_accept_flg) == 1) 250 int ret_val;
244 return netlbl_secattr_init(secattr);
245 251
246 return -ENOMSG; 252 rcu_read_lock();
253 if (netlabel_unlabel_acceptflg == 1) {
254 netlbl_secattr_init(secattr);
255 ret_val = 0;
256 } else
257 ret_val = -ENOMSG;
258 rcu_read_unlock();
259
260 return ret_val;
247} 261}
248 262
249/** 263/**
diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c
index 98a416381e..42f12bd659 100644
--- a/net/netlabel/netlabel_user.c
+++ b/net/netlabel/netlabel_user.c
@@ -46,6 +46,10 @@
46#include "netlabel_cipso_v4.h" 46#include "netlabel_cipso_v4.h"
47#include "netlabel_user.h" 47#include "netlabel_user.h"
48 48
49/* do not do any auditing if audit_enabled == 0, see kernel/audit.c for
50 * details */
51extern int audit_enabled;
52
49/* 53/*
50 * NetLabel NETLINK Setup Functions 54 * NetLabel NETLINK Setup Functions
51 */ 55 */
@@ -101,6 +105,9 @@ struct audit_buffer *netlbl_audit_start_common(int type,
101 char *secctx; 105 char *secctx;
102 u32 secctx_len; 106 u32 secctx_len;
103 107
108 if (audit_enabled == 0)
109 return NULL;
110
104 audit_buf = audit_log_start(audit_ctx, GFP_ATOMIC, type); 111 audit_buf = audit_log_start(audit_ctx, GFP_ATOMIC, type);
105 if (audit_buf == NULL) 112 if (audit_buf == NULL)
106 return NULL; 113 return NULL;
diff --git a/net/netlabel/netlabel_user.h b/net/netlabel/netlabel_user.h
index 47967ef329..6d7f4ab46c 100644
--- a/net/netlabel/netlabel_user.h
+++ b/net/netlabel/netlabel_user.h
@@ -42,37 +42,6 @@
42/* NetLabel NETLINK helper functions */ 42/* NetLabel NETLINK helper functions */
43 43
44/** 44/**
45 * netlbl_netlink_hdr_put - Write the NETLINK buffers into a sk_buff
46 * @skb: the packet
47 * @pid: the PID of the receipient
48 * @seq: the sequence number
49 * @type: the generic NETLINK message family type
50 * @cmd: command
51 *
52 * Description:
53 * Write both a NETLINK nlmsghdr structure and a Generic NETLINK genlmsghdr
54 * struct to the packet. Returns a pointer to the start of the payload buffer
55 * on success or NULL on failure.
56 *
57 */
58static inline void *netlbl_netlink_hdr_put(struct sk_buff *skb,
59 u32 pid,
60 u32 seq,
61 int type,
62 int flags,
63 u8 cmd)
64{
65 return genlmsg_put(skb,
66 pid,
67 seq,
68 type,
69 0,
70 flags,
71 cmd,
72 NETLBL_PROTO_VERSION);
73}
74
75/**
76 * netlbl_netlink_auditinfo - Fetch the audit information from a NETLINK msg 45 * netlbl_netlink_auditinfo - Fetch the audit information from a NETLINK msg
77 * @skb: the packet 46 * @skb: the packet
78 * @audit_info: NetLabel audit information 47 * @audit_info: NetLabel audit information
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index d527c8977b..383dd4e82e 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -472,8 +472,7 @@ static int netlink_release(struct socket *sock)
472 NETLINK_URELEASE, &n); 472 NETLINK_URELEASE, &n);
473 } 473 }
474 474
475 if (nlk->module) 475 module_put(nlk->module);
476 module_put(nlk->module);
477 476
478 netlink_table_grab(); 477 netlink_table_grab();
479 if (nlk->flags & NETLINK_KERNEL_SOCKET) { 478 if (nlk->flags & NETLINK_KERNEL_SOCKET) {
@@ -699,7 +698,7 @@ static struct sock *netlink_getsockbypid(struct sock *ssk, u32 pid)
699 698
700struct sock *netlink_getsockbyfilp(struct file *filp) 699struct sock *netlink_getsockbyfilp(struct file *filp)
701{ 700{
702 struct inode *inode = filp->f_dentry->d_inode; 701 struct inode *inode = filp->f_path.dentry->d_inode;
703 struct sock *sock; 702 struct sock *sock;
704 703
705 if (!S_ISSOCK(inode->i_mode)) 704 if (!S_ISSOCK(inode->i_mode))
@@ -1148,12 +1147,11 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
1148 if (len > sk->sk_sndbuf - 32) 1147 if (len > sk->sk_sndbuf - 32)
1149 goto out; 1148 goto out;
1150 err = -ENOBUFS; 1149 err = -ENOBUFS;
1151 skb = nlmsg_new(len, GFP_KERNEL); 1150 skb = alloc_skb(len, GFP_KERNEL);
1152 if (skb==NULL) 1151 if (skb==NULL)
1153 goto out; 1152 goto out;
1154 1153
1155 NETLINK_CB(skb).pid = nlk->pid; 1154 NETLINK_CB(skb).pid = nlk->pid;
1156 NETLINK_CB(skb).dst_pid = dst_pid;
1157 NETLINK_CB(skb).dst_group = dst_group; 1155 NETLINK_CB(skb).dst_group = dst_group;
1158 NETLINK_CB(skb).loginuid = audit_get_loginuid(current->audit_context); 1156 NETLINK_CB(skb).loginuid = audit_get_loginuid(current->audit_context);
1159 selinux_get_task_sid(current, &(NETLINK_CB(skb).sid)); 1157 selinux_get_task_sid(current, &(NETLINK_CB(skb).sid));
@@ -1435,14 +1433,13 @@ void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err)
1435 struct sk_buff *skb; 1433 struct sk_buff *skb;
1436 struct nlmsghdr *rep; 1434 struct nlmsghdr *rep;
1437 struct nlmsgerr *errmsg; 1435 struct nlmsgerr *errmsg;
1438 int size; 1436 size_t payload = sizeof(*errmsg);
1439 1437
1440 if (err == 0) 1438 /* error messages get the original request appened */
1441 size = nlmsg_total_size(sizeof(*errmsg)); 1439 if (err)
1442 else 1440 payload += nlmsg_len(nlh);
1443 size = nlmsg_total_size(sizeof(*errmsg) + nlmsg_len(nlh));
1444 1441
1445 skb = nlmsg_new(size, GFP_KERNEL); 1442 skb = nlmsg_new(payload, GFP_KERNEL);
1446 if (!skb) { 1443 if (!skb) {
1447 struct sock *sk; 1444 struct sock *sk;
1448 1445
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 49bc2db798..548e4e6e69 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -143,6 +143,13 @@ int genl_register_ops(struct genl_family *family, struct genl_ops *ops)
143 goto errout; 143 goto errout;
144 } 144 }
145 145
146 if (ops->dumpit)
147 ops->flags |= GENL_CMD_CAP_DUMP;
148 if (ops->doit)
149 ops->flags |= GENL_CMD_CAP_DO;
150 if (ops->policy)
151 ops->flags |= GENL_CMD_CAP_HASPOL;
152
146 genl_lock(); 153 genl_lock();
147 list_add_tail(&ops->ops_list, &family->ops_list); 154 list_add_tail(&ops->ops_list, &family->ops_list);
148 genl_unlock(); 155 genl_unlock();
@@ -331,7 +338,7 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
331 } 338 }
332 339
333 *errp = err = netlink_dump_start(genl_sock, skb, nlh, 340 *errp = err = netlink_dump_start(genl_sock, skb, nlh,
334 ops->dumpit, NULL); 341 ops->dumpit, ops->done);
335 if (err == 0) 342 if (err == 0)
336 skb_pull(skb, min(NLMSG_ALIGN(nlh->nlmsg_len), 343 skb_pull(skb, min(NLMSG_ALIGN(nlh->nlmsg_len),
337 skb->len)); 344 skb->len));
@@ -384,16 +391,19 @@ static void genl_rcv(struct sock *sk, int len)
384 * Controller 391 * Controller
385 **************************************************************************/ 392 **************************************************************************/
386 393
394static struct genl_family genl_ctrl = {
395 .id = GENL_ID_CTRL,
396 .name = "nlctrl",
397 .version = 0x2,
398 .maxattr = CTRL_ATTR_MAX,
399};
400
387static int ctrl_fill_info(struct genl_family *family, u32 pid, u32 seq, 401static int ctrl_fill_info(struct genl_family *family, u32 pid, u32 seq,
388 u32 flags, struct sk_buff *skb, u8 cmd) 402 u32 flags, struct sk_buff *skb, u8 cmd)
389{ 403{
390 struct nlattr *nla_ops;
391 struct genl_ops *ops;
392 void *hdr; 404 void *hdr;
393 int idx = 1;
394 405
395 hdr = genlmsg_put(skb, pid, seq, GENL_ID_CTRL, 0, flags, cmd, 406 hdr = genlmsg_put(skb, pid, seq, &genl_ctrl, flags, cmd);
396 family->version);
397 if (hdr == NULL) 407 if (hdr == NULL)
398 return -1; 408 return -1;
399 409
@@ -403,34 +413,31 @@ static int ctrl_fill_info(struct genl_family *family, u32 pid, u32 seq,
403 NLA_PUT_U32(skb, CTRL_ATTR_HDRSIZE, family->hdrsize); 413 NLA_PUT_U32(skb, CTRL_ATTR_HDRSIZE, family->hdrsize);
404 NLA_PUT_U32(skb, CTRL_ATTR_MAXATTR, family->maxattr); 414 NLA_PUT_U32(skb, CTRL_ATTR_MAXATTR, family->maxattr);
405 415
406 nla_ops = nla_nest_start(skb, CTRL_ATTR_OPS); 416 if (!list_empty(&family->ops_list)) {
407 if (nla_ops == NULL) 417 struct nlattr *nla_ops;
408 goto nla_put_failure; 418 struct genl_ops *ops;
409 419 int idx = 1;
410 list_for_each_entry(ops, &family->ops_list, ops_list) {
411 struct nlattr *nest;
412 420
413 nest = nla_nest_start(skb, idx++); 421 nla_ops = nla_nest_start(skb, CTRL_ATTR_OPS);
414 if (nest == NULL) 422 if (nla_ops == NULL)
415 goto nla_put_failure; 423 goto nla_put_failure;
416 424
417 NLA_PUT_U32(skb, CTRL_ATTR_OP_ID, ops->cmd); 425 list_for_each_entry(ops, &family->ops_list, ops_list) {
418 NLA_PUT_U32(skb, CTRL_ATTR_OP_FLAGS, ops->flags); 426 struct nlattr *nest;
419 427
420 if (ops->policy) 428 nest = nla_nest_start(skb, idx++);
421 NLA_PUT_FLAG(skb, CTRL_ATTR_OP_POLICY); 429 if (nest == NULL)
430 goto nla_put_failure;
422 431
423 if (ops->doit) 432 NLA_PUT_U32(skb, CTRL_ATTR_OP_ID, ops->cmd);
424 NLA_PUT_FLAG(skb, CTRL_ATTR_OP_DOIT); 433 NLA_PUT_U32(skb, CTRL_ATTR_OP_FLAGS, ops->flags);
425 434
426 if (ops->dumpit) 435 nla_nest_end(skb, nest);
427 NLA_PUT_FLAG(skb, CTRL_ATTR_OP_DUMPIT); 436 }
428 437
429 nla_nest_end(skb, nest); 438 nla_nest_end(skb, nla_ops);
430 } 439 }
431 440
432 nla_nest_end(skb, nla_ops);
433
434 return genlmsg_end(skb, hdr); 441 return genlmsg_end(skb, hdr);
435 442
436nla_put_failure: 443nla_put_failure:
@@ -480,7 +487,7 @@ static struct sk_buff *ctrl_build_msg(struct genl_family *family, u32 pid,
480 struct sk_buff *skb; 487 struct sk_buff *skb;
481 int err; 488 int err;
482 489
483 skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); 490 skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
484 if (skb == NULL) 491 if (skb == NULL)
485 return ERR_PTR(-ENOBUFS); 492 return ERR_PTR(-ENOBUFS);
486 493
@@ -529,7 +536,7 @@ static int ctrl_getfamily(struct sk_buff *skb, struct genl_info *info)
529 goto errout; 536 goto errout;
530 } 537 }
531 538
532 err = genlmsg_unicast(msg, info->snd_pid); 539 err = genlmsg_reply(msg, info);
533errout: 540errout:
534 return err; 541 return err;
535} 542}
@@ -562,13 +569,6 @@ static struct genl_ops genl_ctrl_ops = {
562 .policy = ctrl_policy, 569 .policy = ctrl_policy,
563}; 570};
564 571
565static struct genl_family genl_ctrl = {
566 .id = GENL_ID_CTRL,
567 .name = "nlctrl",
568 .version = 0x1,
569 .maxattr = CTRL_ATTR_MAX,
570};
571
572static int __init genl_init(void) 572static int __init genl_init(void)
573{ 573{
574 int i, err; 574 int i, err;
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c
index 1d50f801f1..43bbe2c9e4 100644
--- a/net/netrom/af_netrom.c
+++ b/net/netrom/af_netrom.c
@@ -1377,6 +1377,15 @@ static struct notifier_block nr_dev_notifier = {
1377 1377
1378static struct net_device **dev_nr; 1378static struct net_device **dev_nr;
1379 1379
1380static struct ax25_protocol nr_pid = {
1381 .pid = AX25_P_NETROM,
1382 .func = nr_route_frame
1383};
1384
1385static struct ax25_linkfail nr_linkfail_notifier = {
1386 .func = nr_link_failed,
1387};
1388
1380static int __init nr_proto_init(void) 1389static int __init nr_proto_init(void)
1381{ 1390{
1382 int i; 1391 int i;
@@ -1424,8 +1433,8 @@ static int __init nr_proto_init(void)
1424 1433
1425 register_netdevice_notifier(&nr_dev_notifier); 1434 register_netdevice_notifier(&nr_dev_notifier);
1426 1435
1427 ax25_protocol_register(AX25_P_NETROM, nr_route_frame); 1436 ax25_register_pid(&nr_pid);
1428 ax25_linkfail_register(nr_link_failed); 1437 ax25_linkfail_register(&nr_linkfail_notifier);
1429 1438
1430#ifdef CONFIG_SYSCTL 1439#ifdef CONFIG_SYSCTL
1431 nr_register_sysctl(); 1440 nr_register_sysctl();
@@ -1474,7 +1483,7 @@ static void __exit nr_exit(void)
1474 nr_unregister_sysctl(); 1483 nr_unregister_sysctl();
1475#endif 1484#endif
1476 1485
1477 ax25_linkfail_release(nr_link_failed); 1486 ax25_linkfail_release(&nr_linkfail_notifier);
1478 ax25_protocol_release(AX25_P_NETROM); 1487 ax25_protocol_release(AX25_P_NETROM);
1479 1488
1480 unregister_netdevice_notifier(&nr_dev_notifier); 1489 unregister_netdevice_notifier(&nr_dev_notifier);
diff --git a/net/netrom/nr_dev.c b/net/netrom/nr_dev.c
index 9b8eb54971..4700d5225b 100644
--- a/net/netrom/nr_dev.c
+++ b/net/netrom/nr_dev.c
@@ -128,25 +128,37 @@ static int nr_header(struct sk_buff *skb, struct net_device *dev, unsigned short
128 return -37; 128 return -37;
129} 129}
130 130
131static int nr_set_mac_address(struct net_device *dev, void *addr) 131static int __must_check nr_set_mac_address(struct net_device *dev, void *addr)
132{ 132{
133 struct sockaddr *sa = addr; 133 struct sockaddr *sa = addr;
134 int err;
135
136 if (!memcmp(dev->dev_addr, sa->sa_data, dev->addr_len))
137 return 0;
138
139 if (dev->flags & IFF_UP) {
140 err = ax25_listen_register((ax25_address *)sa->sa_data, NULL);
141 if (err)
142 return err;
134 143
135 if (dev->flags & IFF_UP)
136 ax25_listen_release((ax25_address *)dev->dev_addr, NULL); 144 ax25_listen_release((ax25_address *)dev->dev_addr, NULL);
145 }
137 146
138 memcpy(dev->dev_addr, sa->sa_data, dev->addr_len); 147 memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
139 148
140 if (dev->flags & IFF_UP)
141 ax25_listen_register((ax25_address *)dev->dev_addr, NULL);
142
143 return 0; 149 return 0;
144} 150}
145 151
146static int nr_open(struct net_device *dev) 152static int nr_open(struct net_device *dev)
147{ 153{
154 int err;
155
156 err = ax25_listen_register((ax25_address *)dev->dev_addr, NULL);
157 if (err)
158 return err;
159
148 netif_start_queue(dev); 160 netif_start_queue(dev);
149 ax25_listen_register((ax25_address *)dev->dev_addr, NULL); 161
150 return 0; 162 return 0;
151} 163}
152 164
diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c
index c11737f472..8f88964099 100644
--- a/net/netrom/nr_route.c
+++ b/net/netrom/nr_route.c
@@ -87,8 +87,9 @@ static void nr_remove_neigh(struct nr_neigh *);
87 * Add a new route to a node, and in the process add the node and the 87 * Add a new route to a node, and in the process add the node and the
88 * neighbour if it is new. 88 * neighbour if it is new.
89 */ 89 */
90static int nr_add_node(ax25_address *nr, const char *mnemonic, ax25_address *ax25, 90static int __must_check nr_add_node(ax25_address *nr, const char *mnemonic,
91 ax25_digi *ax25_digi, struct net_device *dev, int quality, int obs_count) 91 ax25_address *ax25, ax25_digi *ax25_digi, struct net_device *dev,
92 int quality, int obs_count)
92{ 93{
93 struct nr_node *nr_node; 94 struct nr_node *nr_node;
94 struct nr_neigh *nr_neigh; 95 struct nr_neigh *nr_neigh;
@@ -155,14 +156,15 @@ static int nr_add_node(ax25_address *nr, const char *mnemonic, ax25_address *ax2
155 atomic_set(&nr_neigh->refcount, 1); 156 atomic_set(&nr_neigh->refcount, 1);
156 157
157 if (ax25_digi != NULL && ax25_digi->ndigi > 0) { 158 if (ax25_digi != NULL && ax25_digi->ndigi > 0) {
158 if ((nr_neigh->digipeat = kmalloc(sizeof(*ax25_digi), GFP_KERNEL)) == NULL) { 159 nr_neigh->digipeat = kmemdup(ax25_digi,
160 sizeof(*ax25_digi),
161 GFP_KERNEL);
162 if (nr_neigh->digipeat == NULL) {
159 kfree(nr_neigh); 163 kfree(nr_neigh);
160 if (nr_node) 164 if (nr_node)
161 nr_node_put(nr_node); 165 nr_node_put(nr_node);
162 return -ENOMEM; 166 return -ENOMEM;
163 } 167 }
164 memcpy(nr_neigh->digipeat, ax25_digi,
165 sizeof(*ax25_digi));
166 } 168 }
167 169
168 spin_lock_bh(&nr_neigh_list_lock); 170 spin_lock_bh(&nr_neigh_list_lock);
@@ -405,7 +407,8 @@ static int nr_del_node(ax25_address *callsign, ax25_address *neighbour, struct n
405/* 407/*
406 * Lock a neighbour with a quality. 408 * Lock a neighbour with a quality.
407 */ 409 */
408static int nr_add_neigh(ax25_address *callsign, ax25_digi *ax25_digi, struct net_device *dev, unsigned int quality) 410static int __must_check nr_add_neigh(ax25_address *callsign,
411 ax25_digi *ax25_digi, struct net_device *dev, unsigned int quality)
409{ 412{
410 struct nr_neigh *nr_neigh; 413 struct nr_neigh *nr_neigh;
411 414
@@ -432,11 +435,12 @@ static int nr_add_neigh(ax25_address *callsign, ax25_digi *ax25_digi, struct net
432 atomic_set(&nr_neigh->refcount, 1); 435 atomic_set(&nr_neigh->refcount, 1);
433 436
434 if (ax25_digi != NULL && ax25_digi->ndigi > 0) { 437 if (ax25_digi != NULL && ax25_digi->ndigi > 0) {
435 if ((nr_neigh->digipeat = kmalloc(sizeof(*ax25_digi), GFP_KERNEL)) == NULL) { 438 nr_neigh->digipeat = kmemdup(ax25_digi, sizeof(*ax25_digi),
439 GFP_KERNEL);
440 if (nr_neigh->digipeat == NULL) {
436 kfree(nr_neigh); 441 kfree(nr_neigh);
437 return -ENOMEM; 442 return -ENOMEM;
438 } 443 }
439 memcpy(nr_neigh->digipeat, ax25_digi, sizeof(*ax25_digi));
440 } 444 }
441 445
442 spin_lock_bh(&nr_neigh_list_lock); 446 spin_lock_bh(&nr_neigh_list_lock);
@@ -775,9 +779,13 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
775 nr_src = (ax25_address *)(skb->data + 0); 779 nr_src = (ax25_address *)(skb->data + 0);
776 nr_dest = (ax25_address *)(skb->data + 7); 780 nr_dest = (ax25_address *)(skb->data + 7);
777 781
778 if (ax25 != NULL) 782 if (ax25 != NULL) {
779 nr_add_node(nr_src, "", &ax25->dest_addr, ax25->digipeat, 783 ret = nr_add_node(nr_src, "", &ax25->dest_addr, ax25->digipeat,
780 ax25->ax25_dev->dev, 0, sysctl_netrom_obsolescence_count_initialiser); 784 ax25->ax25_dev->dev, 0,
785 sysctl_netrom_obsolescence_count_initialiser);
786 if (ret)
787 return ret;
788 }
781 789
782 if ((dev = nr_dev_get(nr_dest)) != NULL) { /* Its for me */ 790 if ((dev = nr_dev_get(nr_dest)) != NULL) { /* Its for me */
783 if (ax25 == NULL) /* Its from me */ 791 if (ax25 == NULL) /* Its from me */
@@ -842,6 +850,7 @@ int nr_route_frame(struct sk_buff *skb, ax25_cb *ax25)
842 ret = (nr_neigh->ax25 != NULL); 850 ret = (nr_neigh->ax25 != NULL);
843 nr_node_unlock(nr_node); 851 nr_node_unlock(nr_node);
844 nr_node_put(nr_node); 852 nr_node_put(nr_node);
853
845 return ret; 854 return ret;
846} 855}
847 856
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index f4ccb90e67..da73e8a8c1 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -71,6 +71,7 @@
71#include <asm/uaccess.h> 71#include <asm/uaccess.h>
72#include <asm/ioctls.h> 72#include <asm/ioctls.h>
73#include <asm/page.h> 73#include <asm/page.h>
74#include <asm/cacheflush.h>
74#include <asm/io.h> 75#include <asm/io.h>
75#include <linux/proc_fs.h> 76#include <linux/proc_fs.h>
76#include <linux/seq_file.h> 77#include <linux/seq_file.h>
@@ -201,7 +202,7 @@ struct packet_sock {
201 spinlock_t bind_lock; 202 spinlock_t bind_lock;
202 char running; /* prot_hook is attached*/ 203 char running; /* prot_hook is attached*/
203 int ifindex; /* bound device */ 204 int ifindex; /* bound device */
204 unsigned short num; 205 __be16 num;
205#ifdef CONFIG_PACKET_MULTICAST 206#ifdef CONFIG_PACKET_MULTICAST
206 struct packet_mclist *mclist; 207 struct packet_mclist *mclist;
207#endif 208#endif
@@ -331,7 +332,7 @@ static int packet_sendmsg_spkt(struct kiocb *iocb, struct socket *sock,
331 struct sockaddr_pkt *saddr=(struct sockaddr_pkt *)msg->msg_name; 332 struct sockaddr_pkt *saddr=(struct sockaddr_pkt *)msg->msg_name;
332 struct sk_buff *skb; 333 struct sk_buff *skb;
333 struct net_device *dev; 334 struct net_device *dev;
334 unsigned short proto=0; 335 __be16 proto=0;
335 int err; 336 int err;
336 337
337 /* 338 /*
@@ -659,7 +660,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
659 sll->sll_ifindex = dev->ifindex; 660 sll->sll_ifindex = dev->ifindex;
660 661
661 h->tp_status = status; 662 h->tp_status = status;
662 mb(); 663 smp_mb();
663 664
664 { 665 {
665 struct page *p_start, *p_end; 666 struct page *p_start, *p_end;
@@ -704,7 +705,7 @@ static int packet_sendmsg(struct kiocb *iocb, struct socket *sock,
704 struct sockaddr_ll *saddr=(struct sockaddr_ll *)msg->msg_name; 705 struct sockaddr_ll *saddr=(struct sockaddr_ll *)msg->msg_name;
705 struct sk_buff *skb; 706 struct sk_buff *skb;
706 struct net_device *dev; 707 struct net_device *dev;
707 unsigned short proto; 708 __be16 proto;
708 unsigned char *addr; 709 unsigned char *addr;
709 int ifindex, err, reserve = 0; 710 int ifindex, err, reserve = 0;
710 711
@@ -858,7 +859,7 @@ static int packet_release(struct socket *sock)
858 * Attach a packet hook. 859 * Attach a packet hook.
859 */ 860 */
860 861
861static int packet_do_bind(struct sock *sk, struct net_device *dev, int protocol) 862static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 protocol)
862{ 863{
863 struct packet_sock *po = pkt_sk(sk); 864 struct packet_sock *po = pkt_sk(sk);
864 /* 865 /*
@@ -983,6 +984,7 @@ static int packet_create(struct socket *sock, int protocol)
983{ 984{
984 struct sock *sk; 985 struct sock *sk;
985 struct packet_sock *po; 986 struct packet_sock *po;
987 __be16 proto = (__force __be16)protocol; /* weird, but documented */
986 int err; 988 int err;
987 989
988 if (!capable(CAP_NET_RAW)) 990 if (!capable(CAP_NET_RAW))
@@ -1010,7 +1012,7 @@ static int packet_create(struct socket *sock, int protocol)
1010 1012
1011 po = pkt_sk(sk); 1013 po = pkt_sk(sk);
1012 sk->sk_family = PF_PACKET; 1014 sk->sk_family = PF_PACKET;
1013 po->num = protocol; 1015 po->num = proto;
1014 1016
1015 sk->sk_destruct = packet_sock_destruct; 1017 sk->sk_destruct = packet_sock_destruct;
1016 atomic_inc(&packet_socks_nr); 1018 atomic_inc(&packet_socks_nr);
@@ -1027,8 +1029,8 @@ static int packet_create(struct socket *sock, int protocol)
1027#endif 1029#endif
1028 po->prot_hook.af_packet_priv = sk; 1030 po->prot_hook.af_packet_priv = sk;
1029 1031
1030 if (protocol) { 1032 if (proto) {
1031 po->prot_hook.type = protocol; 1033 po->prot_hook.type = proto;
1032 dev_add_pack(&po->prot_hook); 1034 dev_add_pack(&po->prot_hook);
1033 sock_hold(sk); 1035 sock_hold(sk);
1034 po->running = 1; 1036 po->running = 1;
@@ -1624,7 +1626,8 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing
1624{ 1626{
1625 char **pg_vec = NULL; 1627 char **pg_vec = NULL;
1626 struct packet_sock *po = pkt_sk(sk); 1628 struct packet_sock *po = pkt_sk(sk);
1627 int was_running, num, order = 0; 1629 int was_running, order = 0;
1630 __be16 num;
1628 int err = 0; 1631 int err = 0;
1629 1632
1630 if (req->tp_block_nr) { 1633 if (req->tp_block_nr) {
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index 08a5428556..9e279464c9 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -1314,7 +1314,8 @@ static int rose_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1314 if (copy_from_user(&rose_callsign, argp, sizeof(ax25_address))) 1314 if (copy_from_user(&rose_callsign, argp, sizeof(ax25_address)))
1315 return -EFAULT; 1315 return -EFAULT;
1316 if (ax25cmp(&rose_callsign, &null_ax25_address) != 0) 1316 if (ax25cmp(&rose_callsign, &null_ax25_address) != 0)
1317 ax25_listen_register(&rose_callsign, NULL); 1317 return ax25_listen_register(&rose_callsign, NULL);
1318
1318 return 0; 1319 return 0;
1319 1320
1320 case SIOCRSGL2CALL: 1321 case SIOCRSGL2CALL:
@@ -1481,6 +1482,15 @@ static struct notifier_block rose_dev_notifier = {
1481 1482
1482static struct net_device **dev_rose; 1483static struct net_device **dev_rose;
1483 1484
1485static struct ax25_protocol rose_pid = {
1486 .pid = AX25_P_ROSE,
1487 .func = rose_route_frame
1488};
1489
1490static struct ax25_linkfail rose_linkfail_notifier = {
1491 .func = rose_link_failed
1492};
1493
1484static int __init rose_proto_init(void) 1494static int __init rose_proto_init(void)
1485{ 1495{
1486 int i; 1496 int i;
@@ -1530,8 +1540,8 @@ static int __init rose_proto_init(void)
1530 sock_register(&rose_family_ops); 1540 sock_register(&rose_family_ops);
1531 register_netdevice_notifier(&rose_dev_notifier); 1541 register_netdevice_notifier(&rose_dev_notifier);
1532 1542
1533 ax25_protocol_register(AX25_P_ROSE, rose_route_frame); 1543 ax25_register_pid(&rose_pid);
1534 ax25_linkfail_register(rose_link_failed); 1544 ax25_linkfail_register(&rose_linkfail_notifier);
1535 1545
1536#ifdef CONFIG_SYSCTL 1546#ifdef CONFIG_SYSCTL
1537 rose_register_sysctl(); 1547 rose_register_sysctl();
@@ -1579,7 +1589,7 @@ static void __exit rose_exit(void)
1579 rose_rt_free(); 1589 rose_rt_free();
1580 1590
1581 ax25_protocol_release(AX25_P_ROSE); 1591 ax25_protocol_release(AX25_P_ROSE);
1582 ax25_linkfail_release(rose_link_failed); 1592 ax25_linkfail_release(&rose_linkfail_notifier);
1583 1593
1584 if (ax25cmp(&rose_callsign, &null_ax25_address) != 0) 1594 if (ax25cmp(&rose_callsign, &null_ax25_address) != 0)
1585 ax25_listen_release(&rose_callsign, NULL); 1595 ax25_listen_release(&rose_callsign, NULL);
diff --git a/net/rose/rose_dev.c b/net/rose/rose_dev.c
index 7c279e2659..50824d345f 100644
--- a/net/rose/rose_dev.c
+++ b/net/rose/rose_dev.c
@@ -93,20 +93,34 @@ static int rose_rebuild_header(struct sk_buff *skb)
93static int rose_set_mac_address(struct net_device *dev, void *addr) 93static int rose_set_mac_address(struct net_device *dev, void *addr)
94{ 94{
95 struct sockaddr *sa = addr; 95 struct sockaddr *sa = addr;
96 int err;
96 97
97 rose_del_loopback_node((rose_address *)dev->dev_addr); 98 if (!memcpy(dev->dev_addr, sa->sa_data, dev->addr_len))
99 return 0;
98 100
99 memcpy(dev->dev_addr, sa->sa_data, dev->addr_len); 101 if (dev->flags & IFF_UP) {
102 err = rose_add_loopback_node((rose_address *)dev->dev_addr);
103 if (err)
104 return err;
105
106 rose_del_loopback_node((rose_address *)dev->dev_addr);
107 }
100 108
101 rose_add_loopback_node((rose_address *)dev->dev_addr); 109 memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
102 110
103 return 0; 111 return 0;
104} 112}
105 113
106static int rose_open(struct net_device *dev) 114static int rose_open(struct net_device *dev)
107{ 115{
116 int err;
117
118 err = rose_add_loopback_node((rose_address *)dev->dev_addr);
119 if (err)
120 return err;
121
108 netif_start_queue(dev); 122 netif_start_queue(dev);
109 rose_add_loopback_node((rose_address *)dev->dev_addr); 123
110 return 0; 124 return 0;
111} 125}
112 126
diff --git a/net/rose/rose_loopback.c b/net/rose/rose_loopback.c
index 103b4d38f8..3e41bd93ab 100644
--- a/net/rose/rose_loopback.c
+++ b/net/rose/rose_loopback.c
@@ -79,7 +79,8 @@ static void rose_loopback_timer(unsigned long param)
79 79
80 skb->h.raw = skb->data; 80 skb->h.raw = skb->data;
81 81
82 if ((sk = rose_find_socket(lci_o, rose_loopback_neigh)) != NULL) { 82 sk = rose_find_socket(lci_o, &rose_loopback_neigh);
83 if (sk) {
83 if (rose_process_rx_frame(sk, skb) == 0) 84 if (rose_process_rx_frame(sk, skb) == 0)
84 kfree_skb(skb); 85 kfree_skb(skb);
85 continue; 86 continue;
@@ -87,7 +88,7 @@ static void rose_loopback_timer(unsigned long param)
87 88
88 if (frametype == ROSE_CALL_REQUEST) { 89 if (frametype == ROSE_CALL_REQUEST) {
89 if ((dev = rose_dev_get(dest)) != NULL) { 90 if ((dev = rose_dev_get(dest)) != NULL) {
90 if (rose_rx_call_request(skb, dev, rose_loopback_neigh, lci_o) == 0) 91 if (rose_rx_call_request(skb, dev, &rose_loopback_neigh, lci_o) == 0)
91 kfree_skb(skb); 92 kfree_skb(skb);
92 } else { 93 } else {
93 kfree_skb(skb); 94 kfree_skb(skb);
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
index a22542fa1b..8028c0d425 100644
--- a/net/rose/rose_route.c
+++ b/net/rose/rose_route.c
@@ -46,13 +46,13 @@ static DEFINE_SPINLOCK(rose_neigh_list_lock);
46static struct rose_route *rose_route_list; 46static struct rose_route *rose_route_list;
47static DEFINE_SPINLOCK(rose_route_list_lock); 47static DEFINE_SPINLOCK(rose_route_list_lock);
48 48
49struct rose_neigh *rose_loopback_neigh; 49struct rose_neigh rose_loopback_neigh;
50 50
51/* 51/*
52 * Add a new route to a node, and in the process add the node and the 52 * Add a new route to a node, and in the process add the node and the
53 * neighbour if it is new. 53 * neighbour if it is new.
54 */ 54 */
55static int rose_add_node(struct rose_route_struct *rose_route, 55static int __must_check rose_add_node(struct rose_route_struct *rose_route,
56 struct net_device *dev) 56 struct net_device *dev)
57{ 57{
58 struct rose_node *rose_node, *rose_tmpn, *rose_tmpp; 58 struct rose_node *rose_node, *rose_tmpn, *rose_tmpp;
@@ -361,33 +361,30 @@ out:
361/* 361/*
362 * Add the loopback neighbour. 362 * Add the loopback neighbour.
363 */ 363 */
364int rose_add_loopback_neigh(void) 364void rose_add_loopback_neigh(void)
365{ 365{
366 if ((rose_loopback_neigh = kmalloc(sizeof(struct rose_neigh), GFP_ATOMIC)) == NULL) 366 struct rose_neigh *sn = &rose_loopback_neigh;
367 return -ENOMEM;
368 367
369 rose_loopback_neigh->callsign = null_ax25_address; 368 sn->callsign = null_ax25_address;
370 rose_loopback_neigh->digipeat = NULL; 369 sn->digipeat = NULL;
371 rose_loopback_neigh->ax25 = NULL; 370 sn->ax25 = NULL;
372 rose_loopback_neigh->dev = NULL; 371 sn->dev = NULL;
373 rose_loopback_neigh->count = 0; 372 sn->count = 0;
374 rose_loopback_neigh->use = 0; 373 sn->use = 0;
375 rose_loopback_neigh->dce_mode = 1; 374 sn->dce_mode = 1;
376 rose_loopback_neigh->loopback = 1; 375 sn->loopback = 1;
377 rose_loopback_neigh->number = rose_neigh_no++; 376 sn->number = rose_neigh_no++;
378 rose_loopback_neigh->restarted = 1; 377 sn->restarted = 1;
379 378
380 skb_queue_head_init(&rose_loopback_neigh->queue); 379 skb_queue_head_init(&sn->queue);
381 380
382 init_timer(&rose_loopback_neigh->ftimer); 381 init_timer(&sn->ftimer);
383 init_timer(&rose_loopback_neigh->t0timer); 382 init_timer(&sn->t0timer);
384 383
385 spin_lock_bh(&rose_neigh_list_lock); 384 spin_lock_bh(&rose_neigh_list_lock);
386 rose_loopback_neigh->next = rose_neigh_list; 385 sn->next = rose_neigh_list;
387 rose_neigh_list = rose_loopback_neigh; 386 rose_neigh_list = sn;
388 spin_unlock_bh(&rose_neigh_list_lock); 387 spin_unlock_bh(&rose_neigh_list_lock);
389
390 return 0;
391} 388}
392 389
393/* 390/*
@@ -396,7 +393,7 @@ int rose_add_loopback_neigh(void)
396int rose_add_loopback_node(rose_address *address) 393int rose_add_loopback_node(rose_address *address)
397{ 394{
398 struct rose_node *rose_node; 395 struct rose_node *rose_node;
399 unsigned int err = 0; 396 int err = 0;
400 397
401 spin_lock_bh(&rose_node_list_lock); 398 spin_lock_bh(&rose_node_list_lock);
402 399
@@ -421,18 +418,18 @@ int rose_add_loopback_node(rose_address *address)
421 rose_node->mask = 10; 418 rose_node->mask = 10;
422 rose_node->count = 1; 419 rose_node->count = 1;
423 rose_node->loopback = 1; 420 rose_node->loopback = 1;
424 rose_node->neighbour[0] = rose_loopback_neigh; 421 rose_node->neighbour[0] = &rose_loopback_neigh;
425 422
426 /* Insert at the head of list. Address is always mask=10 */ 423 /* Insert at the head of list. Address is always mask=10 */
427 rose_node->next = rose_node_list; 424 rose_node->next = rose_node_list;
428 rose_node_list = rose_node; 425 rose_node_list = rose_node;
429 426
430 rose_loopback_neigh->count++; 427 rose_loopback_neigh.count++;
431 428
432out: 429out:
433 spin_unlock_bh(&rose_node_list_lock); 430 spin_unlock_bh(&rose_node_list_lock);
434 431
435 return 0; 432 return err;
436} 433}
437 434
438/* 435/*
@@ -458,7 +455,7 @@ void rose_del_loopback_node(rose_address *address)
458 455
459 rose_remove_node(rose_node); 456 rose_remove_node(rose_node);
460 457
461 rose_loopback_neigh->count--; 458 rose_loopback_neigh.count--;
462 459
463out: 460out:
464 spin_unlock_bh(&rose_node_list_lock); 461 spin_unlock_bh(&rose_node_list_lock);
diff --git a/net/rxrpc/krxiod.c b/net/rxrpc/krxiod.c
index dada34a77b..49effd9214 100644
--- a/net/rxrpc/krxiod.c
+++ b/net/rxrpc/krxiod.c
@@ -13,6 +13,7 @@
13#include <linux/completion.h> 13#include <linux/completion.h>
14#include <linux/spinlock.h> 14#include <linux/spinlock.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/freezer.h>
16#include <rxrpc/krxiod.h> 17#include <rxrpc/krxiod.h>
17#include <rxrpc/transport.h> 18#include <rxrpc/transport.h>
18#include <rxrpc/peer.h> 19#include <rxrpc/peer.h>
diff --git a/net/rxrpc/krxsecd.c b/net/rxrpc/krxsecd.c
index cea4eb5e24..3ab0f77409 100644
--- a/net/rxrpc/krxsecd.c
+++ b/net/rxrpc/krxsecd.c
@@ -27,6 +27,7 @@
27#include <rxrpc/call.h> 27#include <rxrpc/call.h>
28#include <linux/udp.h> 28#include <linux/udp.h>
29#include <linux/ip.h> 29#include <linux/ip.h>
30#include <linux/freezer.h>
30#include <net/sock.h> 31#include <net/sock.h>
31#include "internal.h" 32#include "internal.h"
32 33
diff --git a/net/rxrpc/krxtimod.c b/net/rxrpc/krxtimod.c
index 3e7466900b..9a9b6132db 100644
--- a/net/rxrpc/krxtimod.c
+++ b/net/rxrpc/krxtimod.c
@@ -13,6 +13,7 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/sched.h> 14#include <linux/sched.h>
15#include <linux/completion.h> 15#include <linux/completion.h>
16#include <linux/freezer.h>
16#include <rxrpc/rxrpc.h> 17#include <rxrpc/rxrpc.h>
17#include <rxrpc/krxtimod.h> 18#include <rxrpc/krxtimod.h>
18#include <asm/errno.h> 19#include <asm/errno.h>
diff --git a/net/rxrpc/transport.c b/net/rxrpc/transport.c
index 94b2e2fe6f..4268b38d92 100644
--- a/net/rxrpc/transport.c
+++ b/net/rxrpc/transport.c
@@ -31,7 +31,6 @@
31#endif 31#endif
32#include <linux/errqueue.h> 32#include <linux/errqueue.h>
33#include <asm/uaccess.h> 33#include <asm/uaccess.h>
34#include <asm/checksum.h>
35#include "internal.h" 34#include "internal.h"
36 35
37struct errormsg { 36struct errormsg {
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index 8298ea9ffe..f4544dd864 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -6,6 +6,7 @@ menu "QoS and/or fair queueing"
6 6
7config NET_SCHED 7config NET_SCHED
8 bool "QoS and/or fair queueing" 8 bool "QoS and/or fair queueing"
9 select NET_SCH_FIFO
9 ---help--- 10 ---help---
10 When the kernel has several packets to send out over a network 11 When the kernel has several packets to send out over a network
11 device, it has to decide which ones to send first, which ones to 12 device, it has to decide which ones to send first, which ones to
@@ -40,6 +41,9 @@ config NET_SCHED
40 The available schedulers are listed in the following questions; you 41 The available schedulers are listed in the following questions; you
41 can say Y to as many as you like. If unsure, say N now. 42 can say Y to as many as you like. If unsure, say N now.
42 43
44config NET_SCH_FIFO
45 bool
46
43if NET_SCHED 47if NET_SCHED
44 48
45choice 49choice
@@ -320,7 +324,7 @@ config CLS_U32_PERF
320 324
321config CLS_U32_MARK 325config CLS_U32_MARK
322 bool "Netfilter marks support" 326 bool "Netfilter marks support"
323 depends on NET_CLS_U32 && NETFILTER 327 depends on NET_CLS_U32
324 ---help--- 328 ---help---
325 Say Y here to be able to use netfilter marks as u32 key. 329 Say Y here to be able to use netfilter marks as u32 key.
326 330
diff --git a/net/sched/Makefile b/net/sched/Makefile
index 0f06aec660..ff2d6e5e28 100644
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -4,7 +4,7 @@
4 4
5obj-y := sch_generic.o 5obj-y := sch_generic.o
6 6
7obj-$(CONFIG_NET_SCHED) += sch_api.o sch_fifo.o sch_blackhole.o 7obj-$(CONFIG_NET_SCHED) += sch_api.o sch_blackhole.o
8obj-$(CONFIG_NET_CLS) += cls_api.o 8obj-$(CONFIG_NET_CLS) += cls_api.o
9obj-$(CONFIG_NET_CLS_ACT) += act_api.o 9obj-$(CONFIG_NET_CLS_ACT) += act_api.o
10obj-$(CONFIG_NET_ACT_POLICE) += act_police.o 10obj-$(CONFIG_NET_ACT_POLICE) += act_police.o
@@ -14,6 +14,7 @@ obj-$(CONFIG_NET_ACT_MIRRED) += act_mirred.o
14obj-$(CONFIG_NET_ACT_IPT) += act_ipt.o 14obj-$(CONFIG_NET_ACT_IPT) += act_ipt.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_SCH_FIFO) += sch_fifo.o
17obj-$(CONFIG_NET_SCH_CBQ) += sch_cbq.o 18obj-$(CONFIG_NET_SCH_CBQ) += sch_cbq.o
18obj-$(CONFIG_NET_SCH_HTB) += sch_htb.o 19obj-$(CONFIG_NET_SCH_HTB) += sch_htb.o
19obj-$(CONFIG_NET_SCH_HPFQ) += sch_hpfq.o 20obj-$(CONFIG_NET_SCH_HPFQ) += sch_hpfq.o
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c
index 6cff56696a..85de7efd5f 100644
--- a/net/sched/act_gact.c
+++ b/net/sched/act_gact.c
@@ -48,14 +48,14 @@ static struct tcf_hashinfo gact_hash_info = {
48#ifdef CONFIG_GACT_PROB 48#ifdef CONFIG_GACT_PROB
49static int gact_net_rand(struct tcf_gact *gact) 49static int gact_net_rand(struct tcf_gact *gact)
50{ 50{
51 if (net_random() % gact->tcfg_pval) 51 if (!gact->tcfg_pval || net_random() % gact->tcfg_pval)
52 return gact->tcf_action; 52 return gact->tcf_action;
53 return gact->tcfg_paction; 53 return gact->tcfg_paction;
54} 54}
55 55
56static int gact_determ(struct tcf_gact *gact) 56static int gact_determ(struct tcf_gact *gact)
57{ 57{
58 if (gact->tcf_bstats.packets % gact->tcfg_pval) 58 if (!gact->tcfg_pval || gact->tcf_bstats.packets % gact->tcfg_pval)
59 return gact->tcf_action; 59 return gact->tcf_action;
60 return gact->tcfg_paction; 60 return gact->tcfg_paction;
61} 61}
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
index d8c9310da6..a9608064a4 100644
--- a/net/sched/act_ipt.c
+++ b/net/sched/act_ipt.c
@@ -156,10 +156,9 @@ static int tcf_ipt_init(struct rtattr *rta, struct rtattr *est,
156 rtattr_strlcpy(tname, tb[TCA_IPT_TABLE-1], IFNAMSIZ) >= IFNAMSIZ) 156 rtattr_strlcpy(tname, tb[TCA_IPT_TABLE-1], IFNAMSIZ) >= IFNAMSIZ)
157 strcpy(tname, "mangle"); 157 strcpy(tname, "mangle");
158 158
159 t = kmalloc(td->u.target_size, GFP_KERNEL); 159 t = kmemdup(td, td->u.target_size, GFP_KERNEL);
160 if (unlikely(!t)) 160 if (unlikely(!t))
161 goto err2; 161 goto err2;
162 memcpy(t, td, td->u.target_size);
163 162
164 if ((err = ipt_init_target(t, tname, hook)) < 0) 163 if ((err = ipt_init_target(t, tname, hook)) < 0)
165 goto err3; 164 goto err3;
@@ -256,13 +255,12 @@ static int tcf_ipt_dump(struct sk_buff *skb, struct tc_action *a, int bind, int
256 ** for foolproof you need to not assume this 255 ** for foolproof you need to not assume this
257 */ 256 */
258 257
259 t = kmalloc(ipt->tcfi_t->u.user.target_size, GFP_ATOMIC); 258 t = kmemdup(ipt->tcfi_t, ipt->tcfi_t->u.user.target_size, GFP_ATOMIC);
260 if (unlikely(!t)) 259 if (unlikely(!t))
261 goto rtattr_failure; 260 goto rtattr_failure;
262 261
263 c.bindcnt = ipt->tcf_bindcnt - bind; 262 c.bindcnt = ipt->tcf_bindcnt - bind;
264 c.refcnt = ipt->tcf_refcnt - ref; 263 c.refcnt = ipt->tcf_refcnt - ref;
265 memcpy(t, ipt->tcfi_t, ipt->tcfi_t->u.user.target_size);
266 strcpy(t->u.user.name, ipt->tcfi_t->u.kernel.target->name); 264 strcpy(t->u.user.name, ipt->tcfi_t->u.kernel.target->name);
267 265
268 RTA_PUT(skb, TCA_IPT_TARG, ipt->tcfi_t->u.user.target_size, t); 266 RTA_PUT(skb, TCA_IPT_TARG, ipt->tcfi_t->u.user.target_size, t);
diff --git a/net/sched/act_police.c b/net/sched/act_police.c
index fed47b6588..af68e1e832 100644
--- a/net/sched/act_police.c
+++ b/net/sched/act_police.c
@@ -46,6 +46,18 @@ static struct tcf_hashinfo police_hash_info = {
46 .lock = &police_lock, 46 .lock = &police_lock,
47}; 47};
48 48
49/* old policer structure from before tc actions */
50struct tc_police_compat
51{
52 u32 index;
53 int action;
54 u32 limit;
55 u32 burst;
56 u32 mtu;
57 struct tc_ratespec rate;
58 struct tc_ratespec peakrate;
59};
60
49/* Each policer is serialized by its individual spinlock */ 61/* Each policer is serialized by its individual spinlock */
50 62
51#ifdef CONFIG_NET_CLS_ACT 63#ifdef CONFIG_NET_CLS_ACT
@@ -131,12 +143,15 @@ static int tcf_act_police_locate(struct rtattr *rta, struct rtattr *est,
131 struct tc_police *parm; 143 struct tc_police *parm;
132 struct tcf_police *police; 144 struct tcf_police *police;
133 struct qdisc_rate_table *R_tab = NULL, *P_tab = NULL; 145 struct qdisc_rate_table *R_tab = NULL, *P_tab = NULL;
146 int size;
134 147
135 if (rta == NULL || rtattr_parse_nested(tb, TCA_POLICE_MAX, rta) < 0) 148 if (rta == NULL || rtattr_parse_nested(tb, TCA_POLICE_MAX, rta) < 0)
136 return -EINVAL; 149 return -EINVAL;
137 150
138 if (tb[TCA_POLICE_TBF-1] == NULL || 151 if (tb[TCA_POLICE_TBF-1] == NULL)
139 RTA_PAYLOAD(tb[TCA_POLICE_TBF-1]) != sizeof(*parm)) 152 return -EINVAL;
153 size = RTA_PAYLOAD(tb[TCA_POLICE_TBF-1]);
154 if (size != sizeof(*parm) && size != sizeof(struct tc_police_compat))
140 return -EINVAL; 155 return -EINVAL;
141 parm = RTA_DATA(tb[TCA_POLICE_TBF-1]); 156 parm = RTA_DATA(tb[TCA_POLICE_TBF-1]);
142 157
@@ -415,12 +430,15 @@ struct tcf_police *tcf_police_locate(struct rtattr *rta, struct rtattr *est)
415 struct tcf_police *police; 430 struct tcf_police *police;
416 struct rtattr *tb[TCA_POLICE_MAX]; 431 struct rtattr *tb[TCA_POLICE_MAX];
417 struct tc_police *parm; 432 struct tc_police *parm;
433 int size;
418 434
419 if (rtattr_parse_nested(tb, TCA_POLICE_MAX, rta) < 0) 435 if (rtattr_parse_nested(tb, TCA_POLICE_MAX, rta) < 0)
420 return NULL; 436 return NULL;
421 437
422 if (tb[TCA_POLICE_TBF-1] == NULL || 438 if (tb[TCA_POLICE_TBF-1] == NULL)
423 RTA_PAYLOAD(tb[TCA_POLICE_TBF-1]) != sizeof(*parm)) 439 return NULL;
440 size = RTA_PAYLOAD(tb[TCA_POLICE_TBF-1]);
441 if (size != sizeof(*parm) && size != sizeof(struct tc_police_compat))
424 return NULL; 442 return NULL;
425 443
426 parm = RTA_DATA(tb[TCA_POLICE_TBF-1]); 444 parm = RTA_DATA(tb[TCA_POLICE_TBF-1]);
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c
index 901571a677..5fe80854ca 100644
--- a/net/sched/act_simple.c
+++ b/net/sched/act_simple.c
@@ -71,11 +71,10 @@ static int tcf_simp_release(struct tcf_defact *d, int bind)
71 71
72static int alloc_defdata(struct tcf_defact *d, u32 datalen, void *defdata) 72static int alloc_defdata(struct tcf_defact *d, u32 datalen, void *defdata)
73{ 73{
74 d->tcfd_defdata = kmalloc(datalen, GFP_KERNEL); 74 d->tcfd_defdata = kmemdup(defdata, datalen, GFP_KERNEL);
75 if (unlikely(!d->tcfd_defdata)) 75 if (unlikely(!d->tcfd_defdata))
76 return -ENOMEM; 76 return -ENOMEM;
77 d->tcfd_datalen = datalen; 77 d->tcfd_datalen = datalen;
78 memcpy(d->tcfd_defdata, defdata, datalen);
79 return 0; 78 return 0;
80} 79}
81 80
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 37a1840216..edb8fc97ae 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -217,7 +217,7 @@ replay:
217 /* Create new proto tcf */ 217 /* Create new proto tcf */
218 218
219 err = -ENOBUFS; 219 err = -ENOBUFS;
220 if ((tp = kmalloc(sizeof(*tp), GFP_KERNEL)) == NULL) 220 if ((tp = kzalloc(sizeof(*tp), GFP_KERNEL)) == NULL)
221 goto errout; 221 goto errout;
222 err = -EINVAL; 222 err = -EINVAL;
223 tp_ops = tcf_proto_lookup_ops(tca[TCA_KIND-1]); 223 tp_ops = tcf_proto_lookup_ops(tca[TCA_KIND-1]);
@@ -247,7 +247,6 @@ replay:
247 kfree(tp); 247 kfree(tp);
248 goto errout; 248 goto errout;
249 } 249 }
250 memset(tp, 0, sizeof(*tp));
251 tp->ops = tp_ops; 250 tp->ops = tp_ops;
252 tp->protocol = protocol; 251 tp->protocol = protocol;
253 tp->prio = nprio ? : tcf_auto_prio(*back); 252 tp->prio = nprio ? : tcf_auto_prio(*back);
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index e54acc6bcc..c797d6ada7 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -101,13 +101,10 @@ static int fw_classify(struct sk_buff *skb, struct tcf_proto *tp,
101 struct fw_head *head = (struct fw_head*)tp->root; 101 struct fw_head *head = (struct fw_head*)tp->root;
102 struct fw_filter *f; 102 struct fw_filter *f;
103 int r; 103 int r;
104#ifdef CONFIG_NETFILTER 104 u32 id = skb->mark;
105 u32 id = skb->nfmark & head->mask;
106#else
107 u32 id = 0;
108#endif
109 105
110 if (head != NULL) { 106 if (head != NULL) {
107 id &= head->mask;
111 for (f=head->ht[fw_hash(id)]; f; f=f->next) { 108 for (f=head->ht[fw_hash(id)]; f; f=f->next) {
112 if (f->id == id) { 109 if (f->id == id) {
113 *res = f->res; 110 *res = f->res;
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h
index 6e230ecfba..587b9adab3 100644
--- a/net/sched/cls_rsvp.h
+++ b/net/sched/cls_rsvp.h
@@ -77,7 +77,7 @@ struct rsvp_head
77struct rsvp_session 77struct rsvp_session
78{ 78{
79 struct rsvp_session *next; 79 struct rsvp_session *next;
80 u32 dst[RSVP_DST_LEN]; 80 __be32 dst[RSVP_DST_LEN];
81 struct tc_rsvp_gpi dpi; 81 struct tc_rsvp_gpi dpi;
82 u8 protocol; 82 u8 protocol;
83 u8 tunnelid; 83 u8 tunnelid;
@@ -89,7 +89,7 @@ struct rsvp_session
89struct rsvp_filter 89struct rsvp_filter
90{ 90{
91 struct rsvp_filter *next; 91 struct rsvp_filter *next;
92 u32 src[RSVP_DST_LEN]; 92 __be32 src[RSVP_DST_LEN];
93 struct tc_rsvp_gpi spi; 93 struct tc_rsvp_gpi spi;
94 u8 tunnelhdr; 94 u8 tunnelhdr;
95 95
@@ -100,17 +100,17 @@ struct rsvp_filter
100 struct rsvp_session *sess; 100 struct rsvp_session *sess;
101}; 101};
102 102
103static __inline__ unsigned hash_dst(u32 *dst, u8 protocol, u8 tunnelid) 103static __inline__ unsigned hash_dst(__be32 *dst, u8 protocol, u8 tunnelid)
104{ 104{
105 unsigned h = dst[RSVP_DST_LEN-1]; 105 unsigned h = (__force __u32)dst[RSVP_DST_LEN-1];
106 h ^= h>>16; 106 h ^= h>>16;
107 h ^= h>>8; 107 h ^= h>>8;
108 return (h ^ protocol ^ tunnelid) & 0xFF; 108 return (h ^ protocol ^ tunnelid) & 0xFF;
109} 109}
110 110
111static __inline__ unsigned hash_src(u32 *src) 111static __inline__ unsigned hash_src(__be32 *src)
112{ 112{
113 unsigned h = src[RSVP_DST_LEN-1]; 113 unsigned h = (__force __u32)src[RSVP_DST_LEN-1];
114 h ^= h>>16; 114 h ^= h>>16;
115 h ^= h>>8; 115 h ^= h>>8;
116 h ^= h>>4; 116 h ^= h>>4;
@@ -138,7 +138,7 @@ static int rsvp_classify(struct sk_buff *skb, struct tcf_proto *tp,
138 struct rsvp_session *s; 138 struct rsvp_session *s;
139 struct rsvp_filter *f; 139 struct rsvp_filter *f;
140 unsigned h1, h2; 140 unsigned h1, h2;
141 u32 *dst, *src; 141 __be32 *dst, *src;
142 u8 protocol; 142 u8 protocol;
143 u8 tunnelid = 0; 143 u8 tunnelid = 0;
144 u8 *xprt; 144 u8 *xprt;
@@ -410,7 +410,7 @@ static int rsvp_change(struct tcf_proto *tp, unsigned long base,
410 struct rtattr *tb[TCA_RSVP_MAX]; 410 struct rtattr *tb[TCA_RSVP_MAX];
411 struct tcf_exts e; 411 struct tcf_exts e;
412 unsigned h1, h2; 412 unsigned h1, h2;
413 u32 *dst; 413 __be32 *dst;
414 int err; 414 int err;
415 415
416 if (opt == NULL) 416 if (opt == NULL)
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 0a6cfa0005..8b51948019 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -143,7 +143,7 @@ next_knode:
143#endif 143#endif
144 144
145#ifdef CONFIG_CLS_U32_MARK 145#ifdef CONFIG_CLS_U32_MARK
146 if ((skb->nfmark & n->mark.mask) != n->mark.val) { 146 if ((skb->mark & n->mark.mask) != n->mark.val) {
147 n = n->next; 147 n = n->next;
148 goto next_knode; 148 goto next_knode;
149 } else { 149 } else {
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c
index 61e3b740ab..45d47d3715 100644
--- a/net/sched/em_meta.c
+++ b/net/sched/em_meta.c
@@ -208,13 +208,9 @@ META_COLLECTOR(int_maclen)
208 * Netfilter 208 * Netfilter
209 **************************************************************************/ 209 **************************************************************************/
210 210
211META_COLLECTOR(int_nfmark) 211META_COLLECTOR(int_mark)
212{ 212{
213#ifdef CONFIG_NETFILTER 213 dst->value = skb->mark;
214 dst->value = skb->nfmark;
215#else
216 dst->value = 0;
217#endif
218} 214}
219 215
220/************************************************************************** 216/**************************************************************************
@@ -490,7 +486,7 @@ static struct meta_ops __meta_ops[TCF_META_TYPE_MAX+1][TCF_META_ID_MAX+1] = {
490 [META_ID(PKTLEN)] = META_FUNC(int_pktlen), 486 [META_ID(PKTLEN)] = META_FUNC(int_pktlen),
491 [META_ID(DATALEN)] = META_FUNC(int_datalen), 487 [META_ID(DATALEN)] = META_FUNC(int_datalen),
492 [META_ID(MACLEN)] = META_FUNC(int_maclen), 488 [META_ID(MACLEN)] = META_FUNC(int_maclen),
493 [META_ID(NFMARK)] = META_FUNC(int_nfmark), 489 [META_ID(NFMARK)] = META_FUNC(int_mark),
494 [META_ID(TCINDEX)] = META_FUNC(int_tcindex), 490 [META_ID(TCINDEX)] = META_FUNC(int_tcindex),
495 [META_ID(RTCLASSID)] = META_FUNC(int_rtclassid), 491 [META_ID(RTCLASSID)] = META_FUNC(int_rtclassid),
496 [META_ID(RTIIF)] = META_FUNC(int_rtiif), 492 [META_ID(RTIIF)] = META_FUNC(int_rtiif),
@@ -550,10 +546,9 @@ static int meta_var_change(struct meta_value *dst, struct rtattr *rta)
550{ 546{
551 int len = RTA_PAYLOAD(rta); 547 int len = RTA_PAYLOAD(rta);
552 548
553 dst->val = (unsigned long) kmalloc(len, GFP_KERNEL); 549 dst->val = (unsigned long)kmemdup(RTA_DATA(rta), len, GFP_KERNEL);
554 if (dst->val == 0UL) 550 if (dst->val == 0UL)
555 return -ENOMEM; 551 return -ENOMEM;
556 memcpy((void *) dst->val, RTA_DATA(rta), len);
557 dst->len = len; 552 dst->len = len;
558 return 0; 553 return 0;
559} 554}
diff --git a/net/sched/em_nbyte.c b/net/sched/em_nbyte.c
index cc80babfd7..005db409be 100644
--- a/net/sched/em_nbyte.c
+++ b/net/sched/em_nbyte.c
@@ -34,12 +34,10 @@ static int em_nbyte_change(struct tcf_proto *tp, void *data, int data_len,
34 return -EINVAL; 34 return -EINVAL;
35 35
36 em->datalen = sizeof(*nbyte) + nbyte->len; 36 em->datalen = sizeof(*nbyte) + nbyte->len;
37 em->data = (unsigned long) kmalloc(em->datalen, GFP_KERNEL); 37 em->data = (unsigned long)kmemdup(data, em->datalen, GFP_KERNEL);
38 if (em->data == 0UL) 38 if (em->data == 0UL)
39 return -ENOBUFS; 39 return -ENOBUFS;
40 40
41 memcpy((void *) em->data, data, em->datalen);
42
43 return 0; 41 return 0;
44} 42}
45 43
diff --git a/net/sched/ematch.c b/net/sched/ematch.c
index 0fd0768a17..8f8a16da72 100644
--- a/net/sched/ematch.c
+++ b/net/sched/ematch.c
@@ -251,12 +251,11 @@ static int tcf_em_validate(struct tcf_proto *tp,
251 goto errout; 251 goto errout;
252 em->data = *(u32 *) data; 252 em->data = *(u32 *) data;
253 } else { 253 } else {
254 void *v = kmalloc(data_len, GFP_KERNEL); 254 void *v = kmemdup(data, data_len, GFP_KERNEL);
255 if (v == NULL) { 255 if (v == NULL) {
256 err = -ENOBUFS; 256 err = -ENOBUFS;
257 goto errout; 257 goto errout;
258 } 258 }
259 memcpy(v, data, data_len);
260 em->data = (unsigned long) v; 259 em->data = (unsigned long) v;
261 } 260 }
262 } 261 }
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 0b64892911..65825f4409 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -191,21 +191,27 @@ int unregister_qdisc(struct Qdisc_ops *qops)
191 (root qdisc, all its children, children of children etc.) 191 (root qdisc, all its children, children of children etc.)
192 */ 192 */
193 193
194struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle) 194static struct Qdisc *__qdisc_lookup(struct net_device *dev, u32 handle)
195{ 195{
196 struct Qdisc *q; 196 struct Qdisc *q;
197 197
198 read_lock(&qdisc_tree_lock);
199 list_for_each_entry(q, &dev->qdisc_list, list) { 198 list_for_each_entry(q, &dev->qdisc_list, list) {
200 if (q->handle == handle) { 199 if (q->handle == handle)
201 read_unlock(&qdisc_tree_lock);
202 return q; 200 return q;
203 }
204 } 201 }
205 read_unlock(&qdisc_tree_lock);
206 return NULL; 202 return NULL;
207} 203}
208 204
205struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle)
206{
207 struct Qdisc *q;
208
209 read_lock(&qdisc_tree_lock);
210 q = __qdisc_lookup(dev, handle);
211 read_unlock(&qdisc_tree_lock);
212 return q;
213}
214
209static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid) 215static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid)
210{ 216{
211 unsigned long cl; 217 unsigned long cl;
@@ -348,6 +354,26 @@ dev_graft_qdisc(struct net_device *dev, struct Qdisc *qdisc)
348 return oqdisc; 354 return oqdisc;
349} 355}
350 356
357void qdisc_tree_decrease_qlen(struct Qdisc *sch, unsigned int n)
358{
359 struct Qdisc_class_ops *cops;
360 unsigned long cl;
361 u32 parentid;
362
363 if (n == 0)
364 return;
365 while ((parentid = sch->parent)) {
366 sch = __qdisc_lookup(sch->dev, TC_H_MAJ(parentid));
367 cops = sch->ops->cl_ops;
368 if (cops->qlen_notify) {
369 cl = cops->get(sch, parentid);
370 cops->qlen_notify(sch, cl);
371 cops->put(sch, cl);
372 }
373 sch->q.qlen -= n;
374 }
375}
376EXPORT_SYMBOL(qdisc_tree_decrease_qlen);
351 377
352/* Graft qdisc "new" to class "classid" of qdisc "parent" or 378/* Graft qdisc "new" to class "classid" of qdisc "parent" or
353 to device "dev". 379 to device "dev".
@@ -1112,7 +1138,7 @@ int tc_classify(struct sk_buff *skb, struct tcf_proto *tp,
1112 struct tcf_result *res) 1138 struct tcf_result *res)
1113{ 1139{
1114 int err = 0; 1140 int err = 0;
1115 u32 protocol = skb->protocol; 1141 __be16 protocol = skb->protocol;
1116#ifdef CONFIG_NET_CLS_ACT 1142#ifdef CONFIG_NET_CLS_ACT
1117 struct tcf_proto *otp = tp; 1143 struct tcf_proto *otp = tp;
1118reclassify: 1144reclassify:
@@ -1277,7 +1303,6 @@ static int __init pktsched_init(void)
1277 1303
1278subsys_initcall(pktsched_init); 1304subsys_initcall(pktsched_init);
1279 1305
1280EXPORT_SYMBOL(qdisc_lookup);
1281EXPORT_SYMBOL(qdisc_get_rtab); 1306EXPORT_SYMBOL(qdisc_get_rtab);
1282EXPORT_SYMBOL(qdisc_put_rtab); 1307EXPORT_SYMBOL(qdisc_put_rtab);
1283EXPORT_SYMBOL(register_qdisc); 1308EXPORT_SYMBOL(register_qdisc);
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
index dbf44da091..edc7bb0b9c 100644
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -316,7 +316,7 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
316 } 316 }
317 memset(flow,0,sizeof(*flow)); 317 memset(flow,0,sizeof(*flow));
318 flow->filter_list = NULL; 318 flow->filter_list = NULL;
319 if (!(flow->q = qdisc_create_dflt(sch->dev,&pfifo_qdisc_ops))) 319 if (!(flow->q = qdisc_create_dflt(sch->dev,&pfifo_qdisc_ops,classid)))
320 flow->q = &noop_qdisc; 320 flow->q = &noop_qdisc;
321 DPRINTK("atm_tc_change: qdisc %p\n",flow->q); 321 DPRINTK("atm_tc_change: qdisc %p\n",flow->q);
322 flow->sock = sock; 322 flow->sock = sock;
@@ -576,7 +576,8 @@ static int atm_tc_init(struct Qdisc *sch,struct rtattr *opt)
576 576
577 DPRINTK("atm_tc_init(sch %p,[qdisc %p],opt %p)\n",sch,p,opt); 577 DPRINTK("atm_tc_init(sch %p,[qdisc %p],opt %p)\n",sch,p,opt);
578 p->flows = &p->link; 578 p->flows = &p->link;
579 if(!(p->link.q = qdisc_create_dflt(sch->dev,&pfifo_qdisc_ops))) 579 if(!(p->link.q = qdisc_create_dflt(sch->dev,&pfifo_qdisc_ops,
580 sch->handle)))
580 p->link.q = &noop_qdisc; 581 p->link.q = &noop_qdisc;
581 DPRINTK("atm_tc_init: link (%p) qdisc %p\n",&p->link,p->link.q); 582 DPRINTK("atm_tc_init: link (%p) qdisc %p\n",&p->link,p->link.q);
582 p->link.filter_list = NULL; 583 p->link.filter_list = NULL;
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index bac881bfe3..f79a4f3d0a 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -371,8 +371,6 @@ static void cbq_deactivate_class(struct cbq_class *this)
371 return; 371 return;
372 } 372 }
373 } 373 }
374
375 cl = cl_prev->next_alive;
376 return; 374 return;
377 } 375 }
378 } while ((cl_prev = cl) != q->active[prio]); 376 } while ((cl_prev = cl) != q->active[prio]);
@@ -1258,6 +1256,8 @@ static unsigned int cbq_drop(struct Qdisc* sch)
1258 do { 1256 do {
1259 if (cl->q->ops->drop && (len = cl->q->ops->drop(cl->q))) { 1257 if (cl->q->ops->drop && (len = cl->q->ops->drop(cl->q))) {
1260 sch->q.qlen--; 1258 sch->q.qlen--;
1259 if (!cl->q->q.qlen)
1260 cbq_deactivate_class(cl);
1261 return len; 1261 return len;
1262 } 1262 }
1263 } while ((cl = cl->next_alive) != cl_head); 1263 } while ((cl = cl->next_alive) != cl_head);
@@ -1429,7 +1429,8 @@ static int cbq_init(struct Qdisc *sch, struct rtattr *opt)
1429 q->link.sibling = &q->link; 1429 q->link.sibling = &q->link;
1430 q->link.classid = sch->handle; 1430 q->link.classid = sch->handle;
1431 q->link.qdisc = sch; 1431 q->link.qdisc = sch;
1432 if (!(q->link.q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops))) 1432 if (!(q->link.q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops,
1433 sch->handle)))
1433 q->link.q = &noop_qdisc; 1434 q->link.q = &noop_qdisc;
1434 1435
1435 q->link.priority = TC_CBQ_MAXPRIO-1; 1436 q->link.priority = TC_CBQ_MAXPRIO-1;
@@ -1674,7 +1675,8 @@ static int cbq_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
1674 1675
1675 if (cl) { 1676 if (cl) {
1676 if (new == NULL) { 1677 if (new == NULL) {
1677 if ((new = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops)) == NULL) 1678 if ((new = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops,
1679 cl->classid)) == NULL)
1678 return -ENOBUFS; 1680 return -ENOBUFS;
1679 } else { 1681 } else {
1680#ifdef CONFIG_NET_CLS_POLICE 1682#ifdef CONFIG_NET_CLS_POLICE
@@ -1683,9 +1685,8 @@ static int cbq_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
1683#endif 1685#endif
1684 } 1686 }
1685 sch_tree_lock(sch); 1687 sch_tree_lock(sch);
1686 *old = cl->q; 1688 *old = xchg(&cl->q, new);
1687 cl->q = new; 1689 qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
1688 sch->q.qlen -= (*old)->q.qlen;
1689 qdisc_reset(*old); 1690 qdisc_reset(*old);
1690 sch_tree_unlock(sch); 1691 sch_tree_unlock(sch);
1691 1692
@@ -1702,6 +1703,14 @@ cbq_leaf(struct Qdisc *sch, unsigned long arg)
1702 return cl ? cl->q : NULL; 1703 return cl ? cl->q : NULL;
1703} 1704}
1704 1705
1706static void cbq_qlen_notify(struct Qdisc *sch, unsigned long arg)
1707{
1708 struct cbq_class *cl = (struct cbq_class *)arg;
1709
1710 if (cl->q->q.qlen == 0)
1711 cbq_deactivate_class(cl);
1712}
1713
1705static unsigned long cbq_get(struct Qdisc *sch, u32 classid) 1714static unsigned long cbq_get(struct Qdisc *sch, u32 classid)
1706{ 1715{
1707 struct cbq_sched_data *q = qdisc_priv(sch); 1716 struct cbq_sched_data *q = qdisc_priv(sch);
@@ -1932,7 +1941,7 @@ cbq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, struct rtattr **t
1932 cl->R_tab = rtab; 1941 cl->R_tab = rtab;
1933 rtab = NULL; 1942 rtab = NULL;
1934 cl->refcnt = 1; 1943 cl->refcnt = 1;
1935 if (!(cl->q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops))) 1944 if (!(cl->q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops, classid)))
1936 cl->q = &noop_qdisc; 1945 cl->q = &noop_qdisc;
1937 cl->classid = classid; 1946 cl->classid = classid;
1938 cl->tparent = parent; 1947 cl->tparent = parent;
@@ -1986,12 +1995,17 @@ static int cbq_delete(struct Qdisc *sch, unsigned long arg)
1986{ 1995{
1987 struct cbq_sched_data *q = qdisc_priv(sch); 1996 struct cbq_sched_data *q = qdisc_priv(sch);
1988 struct cbq_class *cl = (struct cbq_class*)arg; 1997 struct cbq_class *cl = (struct cbq_class*)arg;
1998 unsigned int qlen;
1989 1999
1990 if (cl->filters || cl->children || cl == &q->link) 2000 if (cl->filters || cl->children || cl == &q->link)
1991 return -EBUSY; 2001 return -EBUSY;
1992 2002
1993 sch_tree_lock(sch); 2003 sch_tree_lock(sch);
1994 2004
2005 qlen = cl->q->q.qlen;
2006 qdisc_reset(cl->q);
2007 qdisc_tree_decrease_qlen(cl->q, qlen);
2008
1995 if (cl->next_alive) 2009 if (cl->next_alive)
1996 cbq_deactivate_class(cl); 2010 cbq_deactivate_class(cl);
1997 2011
@@ -2082,6 +2096,7 @@ static void cbq_walk(struct Qdisc *sch, struct qdisc_walker *arg)
2082static struct Qdisc_class_ops cbq_class_ops = { 2096static struct Qdisc_class_ops cbq_class_ops = {
2083 .graft = cbq_graft, 2097 .graft = cbq_graft,
2084 .leaf = cbq_leaf, 2098 .leaf = cbq_leaf,
2099 .qlen_notify = cbq_qlen_notify,
2085 .get = cbq_get, 2100 .get = cbq_get,
2086 .put = cbq_put, 2101 .put = cbq_put,
2087 .change = cbq_change_class, 2102 .change = cbq_change_class,
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
index 11c8a2119b..d5421816f0 100644
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -88,15 +88,16 @@ static int dsmark_graft(struct Qdisc *sch, unsigned long arg,
88 sch, p, new, old); 88 sch, p, new, old);
89 89
90 if (new == NULL) { 90 if (new == NULL) {
91 new = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops); 91 new = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops,
92 sch->handle);
92 if (new == NULL) 93 if (new == NULL)
93 new = &noop_qdisc; 94 new = &noop_qdisc;
94 } 95 }
95 96
96 sch_tree_lock(sch); 97 sch_tree_lock(sch);
97 *old = xchg(&p->q, new); 98 *old = xchg(&p->q, new);
99 qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
98 qdisc_reset(*old); 100 qdisc_reset(*old);
99 sch->q.qlen = 0;
100 sch_tree_unlock(sch); 101 sch_tree_unlock(sch);
101 102
102 return 0; 103 return 0;
@@ -307,7 +308,7 @@ static struct sk_buff *dsmark_dequeue(struct Qdisc *sch)
307 if (p->mask[index] != 0xff || p->value[index]) 308 if (p->mask[index] != 0xff || p->value[index])
308 printk(KERN_WARNING "dsmark_dequeue: " 309 printk(KERN_WARNING "dsmark_dequeue: "
309 "unsupported protocol %d\n", 310 "unsupported protocol %d\n",
310 htons(skb->protocol)); 311 ntohs(skb->protocol));
311 break; 312 break;
312 }; 313 };
313 314
@@ -387,7 +388,7 @@ static int dsmark_init(struct Qdisc *sch, struct rtattr *opt)
387 p->default_index = default_index; 388 p->default_index = default_index;
388 p->set_tc_index = RTA_GET_FLAG(tb[TCA_DSMARK_SET_TC_INDEX-1]); 389 p->set_tc_index = RTA_GET_FLAG(tb[TCA_DSMARK_SET_TC_INDEX-1]);
389 390
390 p->q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops); 391 p->q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops, sch->handle);
391 if (p->q == NULL) 392 if (p->q == NULL)
392 p->q = &noop_qdisc; 393 p->q = &noop_qdisc;
393 394
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 88c6a99ce5..bc116bd693 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -450,13 +450,15 @@ errout:
450 return ERR_PTR(-err); 450 return ERR_PTR(-err);
451} 451}
452 452
453struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops) 453struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops,
454 unsigned int parentid)
454{ 455{
455 struct Qdisc *sch; 456 struct Qdisc *sch;
456 457
457 sch = qdisc_alloc(dev, ops); 458 sch = qdisc_alloc(dev, ops);
458 if (IS_ERR(sch)) 459 if (IS_ERR(sch))
459 goto errout; 460 goto errout;
461 sch->parent = parentid;
460 462
461 if (!ops->init || ops->init(sch, NULL) == 0) 463 if (!ops->init || ops->init(sch, NULL) == 0)
462 return sch; 464 return sch;
@@ -520,7 +522,8 @@ void dev_activate(struct net_device *dev)
520 if (dev->qdisc_sleeping == &noop_qdisc) { 522 if (dev->qdisc_sleeping == &noop_qdisc) {
521 struct Qdisc *qdisc; 523 struct Qdisc *qdisc;
522 if (dev->tx_queue_len) { 524 if (dev->tx_queue_len) {
523 qdisc = qdisc_create_dflt(dev, &pfifo_fast_ops); 525 qdisc = qdisc_create_dflt(dev, &pfifo_fast_ops,
526 TC_H_ROOT);
524 if (qdisc == NULL) { 527 if (qdisc == NULL) {
525 printk(KERN_INFO "%s: activation failed\n", dev->name); 528 printk(KERN_INFO "%s: activation failed\n", dev->name);
526 return; 529 return;
@@ -606,13 +609,10 @@ void dev_shutdown(struct net_device *dev)
606 qdisc_unlock_tree(dev); 609 qdisc_unlock_tree(dev);
607} 610}
608 611
609EXPORT_SYMBOL(__netdev_watchdog_up);
610EXPORT_SYMBOL(netif_carrier_on); 612EXPORT_SYMBOL(netif_carrier_on);
611EXPORT_SYMBOL(netif_carrier_off); 613EXPORT_SYMBOL(netif_carrier_off);
612EXPORT_SYMBOL(noop_qdisc); 614EXPORT_SYMBOL(noop_qdisc);
613EXPORT_SYMBOL(noop_qdisc_ops);
614EXPORT_SYMBOL(qdisc_create_dflt); 615EXPORT_SYMBOL(qdisc_create_dflt);
615EXPORT_SYMBOL(qdisc_alloc);
616EXPORT_SYMBOL(qdisc_destroy); 616EXPORT_SYMBOL(qdisc_destroy);
617EXPORT_SYMBOL(qdisc_reset); 617EXPORT_SYMBOL(qdisc_reset);
618EXPORT_SYMBOL(qdisc_lock_tree); 618EXPORT_SYMBOL(qdisc_lock_tree);
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index 6a6735a2ed..6eefa69957 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -946,6 +946,7 @@ qdisc_peek_len(struct Qdisc *sch)
946 if (unlikely(sch->ops->requeue(skb, sch) != NET_XMIT_SUCCESS)) { 946 if (unlikely(sch->ops->requeue(skb, sch) != NET_XMIT_SUCCESS)) {
947 if (net_ratelimit()) 947 if (net_ratelimit())
948 printk("qdisc_peek_len: failed to requeue\n"); 948 printk("qdisc_peek_len: failed to requeue\n");
949 qdisc_tree_decrease_qlen(sch, 1);
949 return 0; 950 return 0;
950 } 951 }
951 return len; 952 return len;
@@ -957,11 +958,7 @@ hfsc_purge_queue(struct Qdisc *sch, struct hfsc_class *cl)
957 unsigned int len = cl->qdisc->q.qlen; 958 unsigned int len = cl->qdisc->q.qlen;
958 959
959 qdisc_reset(cl->qdisc); 960 qdisc_reset(cl->qdisc);
960 if (len > 0) { 961 qdisc_tree_decrease_qlen(cl->qdisc, len);
961 update_vf(cl, 0, 0);
962 set_passive(cl);
963 sch->q.qlen -= len;
964 }
965} 962}
966 963
967static void 964static void
@@ -1138,7 +1135,7 @@ hfsc_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
1138 cl->classid = classid; 1135 cl->classid = classid;
1139 cl->sched = q; 1136 cl->sched = q;
1140 cl->cl_parent = parent; 1137 cl->cl_parent = parent;
1141 cl->qdisc = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops); 1138 cl->qdisc = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops, classid);
1142 if (cl->qdisc == NULL) 1139 if (cl->qdisc == NULL)
1143 cl->qdisc = &noop_qdisc; 1140 cl->qdisc = &noop_qdisc;
1144 cl->stats_lock = &sch->dev->queue_lock; 1141 cl->stats_lock = &sch->dev->queue_lock;
@@ -1271,7 +1268,8 @@ hfsc_graft_class(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
1271 if (cl->level > 0) 1268 if (cl->level > 0)
1272 return -EINVAL; 1269 return -EINVAL;
1273 if (new == NULL) { 1270 if (new == NULL) {
1274 new = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops); 1271 new = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops,
1272 cl->classid);
1275 if (new == NULL) 1273 if (new == NULL)
1276 new = &noop_qdisc; 1274 new = &noop_qdisc;
1277 } 1275 }
@@ -1294,6 +1292,17 @@ hfsc_class_leaf(struct Qdisc *sch, unsigned long arg)
1294 return NULL; 1292 return NULL;
1295} 1293}
1296 1294
1295static void
1296hfsc_qlen_notify(struct Qdisc *sch, unsigned long arg)
1297{
1298 struct hfsc_class *cl = (struct hfsc_class *)arg;
1299
1300 if (cl->qdisc->q.qlen == 0) {
1301 update_vf(cl, 0, 0);
1302 set_passive(cl);
1303 }
1304}
1305
1297static unsigned long 1306static unsigned long
1298hfsc_get_class(struct Qdisc *sch, u32 classid) 1307hfsc_get_class(struct Qdisc *sch, u32 classid)
1299{ 1308{
@@ -1514,7 +1523,8 @@ hfsc_init_qdisc(struct Qdisc *sch, struct rtattr *opt)
1514 q->root.refcnt = 1; 1523 q->root.refcnt = 1;
1515 q->root.classid = sch->handle; 1524 q->root.classid = sch->handle;
1516 q->root.sched = q; 1525 q->root.sched = q;
1517 q->root.qdisc = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops); 1526 q->root.qdisc = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops,
1527 sch->handle);
1518 if (q->root.qdisc == NULL) 1528 if (q->root.qdisc == NULL)
1519 q->root.qdisc = &noop_qdisc; 1529 q->root.qdisc = &noop_qdisc;
1520 q->root.stats_lock = &sch->dev->queue_lock; 1530 q->root.stats_lock = &sch->dev->queue_lock;
@@ -1777,6 +1787,7 @@ static struct Qdisc_class_ops hfsc_class_ops = {
1777 .delete = hfsc_delete_class, 1787 .delete = hfsc_delete_class,
1778 .graft = hfsc_graft_class, 1788 .graft = hfsc_graft_class,
1779 .leaf = hfsc_class_leaf, 1789 .leaf = hfsc_class_leaf,
1790 .qlen_notify = hfsc_qlen_notify,
1780 .get = hfsc_get_class, 1791 .get = hfsc_get_class,
1781 .put = hfsc_put_class, 1792 .put = hfsc_put_class,
1782 .bind_tcf = hfsc_bind_tcf, 1793 .bind_tcf = hfsc_bind_tcf,
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 4b52fa7893..15f23c5511 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -147,6 +147,10 @@ struct htb_class {
147 psched_tdiff_t mbuffer; /* max wait time */ 147 psched_tdiff_t mbuffer; /* max wait time */
148 long tokens, ctokens; /* current number of tokens */ 148 long tokens, ctokens; /* current number of tokens */
149 psched_time_t t_c; /* checkpoint time */ 149 psched_time_t t_c; /* checkpoint time */
150
151 int prio; /* For parent to leaf return possible here */
152 int quantum; /* we do backup. Finally full replacement */
153 /* of un.leaf originals should be done. */
150}; 154};
151 155
152/* TODO: maybe compute rate when size is too large .. or drop ? */ 156/* TODO: maybe compute rate when size is too large .. or drop ? */
@@ -1223,17 +1227,14 @@ static int htb_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
1223 struct htb_class *cl = (struct htb_class *)arg; 1227 struct htb_class *cl = (struct htb_class *)arg;
1224 1228
1225 if (cl && !cl->level) { 1229 if (cl && !cl->level) {
1226 if (new == NULL && (new = qdisc_create_dflt(sch->dev, 1230 if (new == NULL &&
1227 &pfifo_qdisc_ops)) 1231 (new = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops,
1232 cl->classid))
1228 == NULL) 1233 == NULL)
1229 return -ENOBUFS; 1234 return -ENOBUFS;
1230 sch_tree_lock(sch); 1235 sch_tree_lock(sch);
1231 if ((*old = xchg(&cl->un.leaf.q, new)) != NULL) { 1236 if ((*old = xchg(&cl->un.leaf.q, new)) != NULL) {
1232 if (cl->prio_activity) 1237 qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
1233 htb_deactivate(qdisc_priv(sch), cl);
1234
1235 /* TODO: is it correct ? Why CBQ doesn't do it ? */
1236 sch->q.qlen -= (*old)->q.qlen;
1237 qdisc_reset(*old); 1238 qdisc_reset(*old);
1238 } 1239 }
1239 sch_tree_unlock(sch); 1240 sch_tree_unlock(sch);
@@ -1248,6 +1249,14 @@ static struct Qdisc *htb_leaf(struct Qdisc *sch, unsigned long arg)
1248 return (cl && !cl->level) ? cl->un.leaf.q : NULL; 1249 return (cl && !cl->level) ? cl->un.leaf.q : NULL;
1249} 1250}
1250 1251
1252static void htb_qlen_notify(struct Qdisc *sch, unsigned long arg)
1253{
1254 struct htb_class *cl = (struct htb_class *)arg;
1255
1256 if (cl->un.leaf.q->q.qlen == 0)
1257 htb_deactivate(qdisc_priv(sch), cl);
1258}
1259
1251static unsigned long htb_get(struct Qdisc *sch, u32 classid) 1260static unsigned long htb_get(struct Qdisc *sch, u32 classid)
1252{ 1261{
1253 struct htb_class *cl = htb_find(classid, sch); 1262 struct htb_class *cl = htb_find(classid, sch);
@@ -1266,12 +1275,44 @@ static void htb_destroy_filters(struct tcf_proto **fl)
1266 } 1275 }
1267} 1276}
1268 1277
1278static inline int htb_parent_last_child(struct htb_class *cl)
1279{
1280 if (!cl->parent)
1281 /* the root class */
1282 return 0;
1283
1284 if (!(cl->parent->children.next == &cl->sibling &&
1285 cl->parent->children.prev == &cl->sibling))
1286 /* not the last child */
1287 return 0;
1288
1289 return 1;
1290}
1291
1292static void htb_parent_to_leaf(struct htb_class *cl, struct Qdisc *new_q)
1293{
1294 struct htb_class *parent = cl->parent;
1295
1296 BUG_TRAP(!cl->level && cl->un.leaf.q && !cl->prio_activity);
1297
1298 parent->level = 0;
1299 memset(&parent->un.inner, 0, sizeof(parent->un.inner));
1300 INIT_LIST_HEAD(&parent->un.leaf.drop_list);
1301 parent->un.leaf.q = new_q ? new_q : &noop_qdisc;
1302 parent->un.leaf.quantum = parent->quantum;
1303 parent->un.leaf.prio = parent->prio;
1304 parent->tokens = parent->buffer;
1305 parent->ctokens = parent->cbuffer;
1306 PSCHED_GET_TIME(parent->t_c);
1307 parent->cmode = HTB_CAN_SEND;
1308}
1309
1269static void htb_destroy_class(struct Qdisc *sch, struct htb_class *cl) 1310static void htb_destroy_class(struct Qdisc *sch, struct htb_class *cl)
1270{ 1311{
1271 struct htb_sched *q = qdisc_priv(sch); 1312 struct htb_sched *q = qdisc_priv(sch);
1313
1272 if (!cl->level) { 1314 if (!cl->level) {
1273 BUG_TRAP(cl->un.leaf.q); 1315 BUG_TRAP(cl->un.leaf.q);
1274 sch->q.qlen -= cl->un.leaf.q->q.qlen;
1275 qdisc_destroy(cl->un.leaf.q); 1316 qdisc_destroy(cl->un.leaf.q);
1276 } 1317 }
1277 qdisc_put_rtab(cl->rate); 1318 qdisc_put_rtab(cl->rate);
@@ -1322,6 +1363,9 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg)
1322{ 1363{
1323 struct htb_sched *q = qdisc_priv(sch); 1364 struct htb_sched *q = qdisc_priv(sch);
1324 struct htb_class *cl = (struct htb_class *)arg; 1365 struct htb_class *cl = (struct htb_class *)arg;
1366 unsigned int qlen;
1367 struct Qdisc *new_q = NULL;
1368 int last_child = 0;
1325 1369
1326 // TODO: why don't allow to delete subtree ? references ? does 1370 // TODO: why don't allow to delete subtree ? references ? does
1327 // tc subsys quarantee us that in htb_destroy it holds no class 1371 // tc subsys quarantee us that in htb_destroy it holds no class
@@ -1329,14 +1373,29 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg)
1329 if (!list_empty(&cl->children) || cl->filter_cnt) 1373 if (!list_empty(&cl->children) || cl->filter_cnt)
1330 return -EBUSY; 1374 return -EBUSY;
1331 1375
1376 if (!cl->level && htb_parent_last_child(cl)) {
1377 new_q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops,
1378 cl->parent->classid);
1379 last_child = 1;
1380 }
1381
1332 sch_tree_lock(sch); 1382 sch_tree_lock(sch);
1333 1383
1334 /* delete from hash and active; remainder in destroy_class */ 1384 /* delete from hash and active; remainder in destroy_class */
1335 hlist_del_init(&cl->hlist); 1385 hlist_del_init(&cl->hlist);
1336 1386
1387 if (!cl->level) {
1388 qlen = cl->un.leaf.q->q.qlen;
1389 qdisc_reset(cl->un.leaf.q);
1390 qdisc_tree_decrease_qlen(cl->un.leaf.q, qlen);
1391 }
1392
1337 if (cl->prio_activity) 1393 if (cl->prio_activity)
1338 htb_deactivate(q, cl); 1394 htb_deactivate(q, cl);
1339 1395
1396 if (last_child)
1397 htb_parent_to_leaf(cl, new_q);
1398
1340 if (--cl->refcnt == 0) 1399 if (--cl->refcnt == 0)
1341 htb_destroy_class(sch, cl); 1400 htb_destroy_class(sch, cl);
1342 1401
@@ -1410,11 +1469,14 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
1410 /* create leaf qdisc early because it uses kmalloc(GFP_KERNEL) 1469 /* create leaf qdisc early because it uses kmalloc(GFP_KERNEL)
1411 so that can't be used inside of sch_tree_lock 1470 so that can't be used inside of sch_tree_lock
1412 -- thanks to Karlis Peisenieks */ 1471 -- thanks to Karlis Peisenieks */
1413 new_q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops); 1472 new_q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops, classid);
1414 sch_tree_lock(sch); 1473 sch_tree_lock(sch);
1415 if (parent && !parent->level) { 1474 if (parent && !parent->level) {
1475 unsigned int qlen = parent->un.leaf.q->q.qlen;
1476
1416 /* turn parent into inner node */ 1477 /* turn parent into inner node */
1417 sch->q.qlen -= parent->un.leaf.q->q.qlen; 1478 qdisc_reset(parent->un.leaf.q);
1479 qdisc_tree_decrease_qlen(parent->un.leaf.q, qlen);
1418 qdisc_destroy(parent->un.leaf.q); 1480 qdisc_destroy(parent->un.leaf.q);
1419 if (parent->prio_activity) 1481 if (parent->prio_activity)
1420 htb_deactivate(q, parent); 1482 htb_deactivate(q, parent);
@@ -1468,6 +1530,10 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
1468 cl->un.leaf.quantum = hopt->quantum; 1530 cl->un.leaf.quantum = hopt->quantum;
1469 if ((cl->un.leaf.prio = hopt->prio) >= TC_HTB_NUMPRIO) 1531 if ((cl->un.leaf.prio = hopt->prio) >= TC_HTB_NUMPRIO)
1470 cl->un.leaf.prio = TC_HTB_NUMPRIO - 1; 1532 cl->un.leaf.prio = TC_HTB_NUMPRIO - 1;
1533
1534 /* backup for htb_parent_to_leaf */
1535 cl->quantum = cl->un.leaf.quantum;
1536 cl->prio = cl->un.leaf.prio;
1471 } 1537 }
1472 1538
1473 cl->buffer = hopt->buffer; 1539 cl->buffer = hopt->buffer;
@@ -1562,6 +1628,7 @@ static void htb_walk(struct Qdisc *sch, struct qdisc_walker *arg)
1562static struct Qdisc_class_ops htb_class_ops = { 1628static struct Qdisc_class_ops htb_class_ops = {
1563 .graft = htb_graft, 1629 .graft = htb_graft,
1564 .leaf = htb_leaf, 1630 .leaf = htb_leaf,
1631 .qlen_notify = htb_qlen_notify,
1565 .get = htb_get, 1632 .get = htb_get,
1566 .put = htb_put, 1633 .put = htb_put,
1567 .change = htb_change_class, 1634 .change = htb_change_class,
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 0441876aa1..79542af9da 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -287,13 +287,10 @@ static struct sk_buff *netem_dequeue(struct Qdisc *sch)
287 psched_tdiff_t delay = PSCHED_TDIFF(cb->time_to_send, now); 287 psched_tdiff_t delay = PSCHED_TDIFF(cb->time_to_send, now);
288 288
289 if (q->qdisc->ops->requeue(skb, q->qdisc) != NET_XMIT_SUCCESS) { 289 if (q->qdisc->ops->requeue(skb, q->qdisc) != NET_XMIT_SUCCESS) {
290 qdisc_tree_decrease_qlen(q->qdisc, 1);
290 sch->qstats.drops++; 291 sch->qstats.drops++;
291
292 /* After this qlen is confused */
293 printk(KERN_ERR "netem: queue discpline %s could not requeue\n", 292 printk(KERN_ERR "netem: queue discpline %s could not requeue\n",
294 q->qdisc->ops->id); 293 q->qdisc->ops->id);
295
296 sch->q.qlen--;
297 } 294 }
298 295
299 mod_timer(&q->timer, jiffies + PSCHED_US2JIFFIE(delay)); 296 mod_timer(&q->timer, jiffies + PSCHED_US2JIFFIE(delay));
@@ -574,7 +571,8 @@ static int netem_init(struct Qdisc *sch, struct rtattr *opt)
574 q->timer.function = netem_watchdog; 571 q->timer.function = netem_watchdog;
575 q->timer.data = (unsigned long) sch; 572 q->timer.data = (unsigned long) sch;
576 573
577 q->qdisc = qdisc_create_dflt(sch->dev, &tfifo_qdisc_ops); 574 q->qdisc = qdisc_create_dflt(sch->dev, &tfifo_qdisc_ops,
575 TC_H_MAKE(sch->handle, 1));
578 if (!q->qdisc) { 576 if (!q->qdisc) {
579 pr_debug("netem: qdisc create failed\n"); 577 pr_debug("netem: qdisc create failed\n");
580 return -ENOMEM; 578 return -ENOMEM;
@@ -661,8 +659,8 @@ static int netem_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
661 659
662 sch_tree_lock(sch); 660 sch_tree_lock(sch);
663 *old = xchg(&q->qdisc, new); 661 *old = xchg(&q->qdisc, new);
662 qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
664 qdisc_reset(*old); 663 qdisc_reset(*old);
665 sch->q.qlen = 0;
666 sch_tree_unlock(sch); 664 sch_tree_unlock(sch);
667 665
668 return 0; 666 return 0;
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index a5fa03c0c1..2567b4c96c 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -222,21 +222,27 @@ static int prio_tune(struct Qdisc *sch, struct rtattr *opt)
222 222
223 for (i=q->bands; i<TCQ_PRIO_BANDS; i++) { 223 for (i=q->bands; i<TCQ_PRIO_BANDS; i++) {
224 struct Qdisc *child = xchg(&q->queues[i], &noop_qdisc); 224 struct Qdisc *child = xchg(&q->queues[i], &noop_qdisc);
225 if (child != &noop_qdisc) 225 if (child != &noop_qdisc) {
226 qdisc_tree_decrease_qlen(child, child->q.qlen);
226 qdisc_destroy(child); 227 qdisc_destroy(child);
228 }
227 } 229 }
228 sch_tree_unlock(sch); 230 sch_tree_unlock(sch);
229 231
230 for (i=0; i<q->bands; i++) { 232 for (i=0; i<q->bands; i++) {
231 if (q->queues[i] == &noop_qdisc) { 233 if (q->queues[i] == &noop_qdisc) {
232 struct Qdisc *child; 234 struct Qdisc *child;
233 child = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops); 235 child = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops,
236 TC_H_MAKE(sch->handle, i + 1));
234 if (child) { 237 if (child) {
235 sch_tree_lock(sch); 238 sch_tree_lock(sch);
236 child = xchg(&q->queues[i], child); 239 child = xchg(&q->queues[i], child);
237 240
238 if (child != &noop_qdisc) 241 if (child != &noop_qdisc) {
242 qdisc_tree_decrease_qlen(child,
243 child->q.qlen);
239 qdisc_destroy(child); 244 qdisc_destroy(child);
245 }
240 sch_tree_unlock(sch); 246 sch_tree_unlock(sch);
241 } 247 }
242 } 248 }
@@ -294,7 +300,7 @@ static int prio_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
294 sch_tree_lock(sch); 300 sch_tree_lock(sch);
295 *old = q->queues[band]; 301 *old = q->queues[band];
296 q->queues[band] = new; 302 q->queues[band] = new;
297 sch->q.qlen -= (*old)->q.qlen; 303 qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
298 qdisc_reset(*old); 304 qdisc_reset(*old);
299 sch_tree_unlock(sch); 305 sch_tree_unlock(sch);
300 306
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
index d65cadddea..acddad0885 100644
--- a/net/sched/sch_red.c
+++ b/net/sched/sch_red.c
@@ -175,12 +175,14 @@ static void red_destroy(struct Qdisc *sch)
175 qdisc_destroy(q->qdisc); 175 qdisc_destroy(q->qdisc);
176} 176}
177 177
178static struct Qdisc *red_create_dflt(struct net_device *dev, u32 limit) 178static struct Qdisc *red_create_dflt(struct Qdisc *sch, u32 limit)
179{ 179{
180 struct Qdisc *q = qdisc_create_dflt(dev, &bfifo_qdisc_ops); 180 struct Qdisc *q;
181 struct rtattr *rta; 181 struct rtattr *rta;
182 int ret; 182 int ret;
183 183
184 q = qdisc_create_dflt(sch->dev, &bfifo_qdisc_ops,
185 TC_H_MAKE(sch->handle, 1));
184 if (q) { 186 if (q) {
185 rta = kmalloc(RTA_LENGTH(sizeof(struct tc_fifo_qopt)), 187 rta = kmalloc(RTA_LENGTH(sizeof(struct tc_fifo_qopt)),
186 GFP_KERNEL); 188 GFP_KERNEL);
@@ -219,7 +221,7 @@ static int red_change(struct Qdisc *sch, struct rtattr *opt)
219 ctl = RTA_DATA(tb[TCA_RED_PARMS-1]); 221 ctl = RTA_DATA(tb[TCA_RED_PARMS-1]);
220 222
221 if (ctl->limit > 0) { 223 if (ctl->limit > 0) {
222 child = red_create_dflt(sch->dev, ctl->limit); 224 child = red_create_dflt(sch, ctl->limit);
223 if (child == NULL) 225 if (child == NULL)
224 return -ENOMEM; 226 return -ENOMEM;
225 } 227 }
@@ -227,8 +229,10 @@ static int red_change(struct Qdisc *sch, struct rtattr *opt)
227 sch_tree_lock(sch); 229 sch_tree_lock(sch);
228 q->flags = ctl->flags; 230 q->flags = ctl->flags;
229 q->limit = ctl->limit; 231 q->limit = ctl->limit;
230 if (child) 232 if (child) {
233 qdisc_tree_decrease_qlen(q->qdisc, q->qdisc->q.qlen);
231 qdisc_destroy(xchg(&q->qdisc, child)); 234 qdisc_destroy(xchg(&q->qdisc, child));
235 }
232 236
233 red_set_parms(&q->parms, ctl->qth_min, ctl->qth_max, ctl->Wlog, 237 red_set_parms(&q->parms, ctl->qth_min, ctl->qth_max, ctl->Wlog,
234 ctl->Plog, ctl->Scell_log, 238 ctl->Plog, ctl->Scell_log,
@@ -306,8 +310,8 @@ static int red_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
306 310
307 sch_tree_lock(sch); 311 sch_tree_lock(sch);
308 *old = xchg(&q->qdisc, new); 312 *old = xchg(&q->qdisc, new);
313 qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
309 qdisc_reset(*old); 314 qdisc_reset(*old);
310 sch->q.qlen = 0;
311 sch_tree_unlock(sch); 315 sch_tree_unlock(sch);
312 return 0; 316 return 0;
313} 317}
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index d0d6e595a7..459cda258a 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -393,6 +393,7 @@ static int sfq_change(struct Qdisc *sch, struct rtattr *opt)
393{ 393{
394 struct sfq_sched_data *q = qdisc_priv(sch); 394 struct sfq_sched_data *q = qdisc_priv(sch);
395 struct tc_sfq_qopt *ctl = RTA_DATA(opt); 395 struct tc_sfq_qopt *ctl = RTA_DATA(opt);
396 unsigned int qlen;
396 397
397 if (opt->rta_len < RTA_LENGTH(sizeof(*ctl))) 398 if (opt->rta_len < RTA_LENGTH(sizeof(*ctl)))
398 return -EINVAL; 399 return -EINVAL;
@@ -403,8 +404,10 @@ static int sfq_change(struct Qdisc *sch, struct rtattr *opt)
403 if (ctl->limit) 404 if (ctl->limit)
404 q->limit = min_t(u32, ctl->limit, SFQ_DEPTH); 405 q->limit = min_t(u32, ctl->limit, SFQ_DEPTH);
405 406
407 qlen = sch->q.qlen;
406 while (sch->q.qlen >= q->limit-1) 408 while (sch->q.qlen >= q->limit-1)
407 sfq_drop(sch); 409 sfq_drop(sch);
410 qdisc_tree_decrease_qlen(sch, qlen - sch->q.qlen);
408 411
409 del_timer(&q->perturb_timer); 412 del_timer(&q->perturb_timer);
410 if (q->perturb_period) { 413 if (q->perturb_period) {
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index d9a5d298d7..ed9b6d9385 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -250,7 +250,7 @@ static struct sk_buff *tbf_dequeue(struct Qdisc* sch)
250 250
251 if (q->qdisc->ops->requeue(skb, q->qdisc) != NET_XMIT_SUCCESS) { 251 if (q->qdisc->ops->requeue(skb, q->qdisc) != NET_XMIT_SUCCESS) {
252 /* When requeue fails skb is dropped */ 252 /* When requeue fails skb is dropped */
253 sch->q.qlen--; 253 qdisc_tree_decrease_qlen(q->qdisc, 1);
254 sch->qstats.drops++; 254 sch->qstats.drops++;
255 } 255 }
256 256
@@ -273,12 +273,14 @@ static void tbf_reset(struct Qdisc* sch)
273 del_timer(&q->wd_timer); 273 del_timer(&q->wd_timer);
274} 274}
275 275
276static struct Qdisc *tbf_create_dflt_qdisc(struct net_device *dev, u32 limit) 276static struct Qdisc *tbf_create_dflt_qdisc(struct Qdisc *sch, u32 limit)
277{ 277{
278 struct Qdisc *q = qdisc_create_dflt(dev, &bfifo_qdisc_ops); 278 struct Qdisc *q;
279 struct rtattr *rta; 279 struct rtattr *rta;
280 int ret; 280 int ret;
281 281
282 q = qdisc_create_dflt(sch->dev, &bfifo_qdisc_ops,
283 TC_H_MAKE(sch->handle, 1));
282 if (q) { 284 if (q) {
283 rta = kmalloc(RTA_LENGTH(sizeof(struct tc_fifo_qopt)), GFP_KERNEL); 285 rta = kmalloc(RTA_LENGTH(sizeof(struct tc_fifo_qopt)), GFP_KERNEL);
284 if (rta) { 286 if (rta) {
@@ -341,13 +343,15 @@ static int tbf_change(struct Qdisc* sch, struct rtattr *opt)
341 goto done; 343 goto done;
342 344
343 if (qopt->limit > 0) { 345 if (qopt->limit > 0) {
344 if ((child = tbf_create_dflt_qdisc(sch->dev, qopt->limit)) == NULL) 346 if ((child = tbf_create_dflt_qdisc(sch, qopt->limit)) == NULL)
345 goto done; 347 goto done;
346 } 348 }
347 349
348 sch_tree_lock(sch); 350 sch_tree_lock(sch);
349 if (child) 351 if (child) {
352 qdisc_tree_decrease_qlen(q->qdisc, q->qdisc->q.qlen);
350 qdisc_destroy(xchg(&q->qdisc, child)); 353 qdisc_destroy(xchg(&q->qdisc, child));
354 }
351 q->limit = qopt->limit; 355 q->limit = qopt->limit;
352 q->mtu = qopt->mtu; 356 q->mtu = qopt->mtu;
353 q->max_size = max_size; 357 q->max_size = max_size;
@@ -449,8 +453,8 @@ static int tbf_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
449 453
450 sch_tree_lock(sch); 454 sch_tree_lock(sch);
451 *old = xchg(&q->qdisc, new); 455 *old = xchg(&q->qdisc, new);
456 qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
452 qdisc_reset(*old); 457 qdisc_reset(*old);
453 sch->q.qlen = 0;
454 sch_tree_unlock(sch); 458 sch_tree_unlock(sch);
455 459
456 return 0; 460 return 0;
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index ed0445fe85..5db95caed0 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -61,7 +61,7 @@
61#include <net/sctp/sm.h> 61#include <net/sctp/sm.h>
62 62
63/* Forward declarations for internal functions. */ 63/* Forward declarations for internal functions. */
64static void sctp_assoc_bh_rcv(struct sctp_association *asoc); 64static void sctp_assoc_bh_rcv(struct work_struct *work);
65 65
66 66
67/* 1st Level Abstractions. */ 67/* 1st Level Abstractions. */
@@ -269,9 +269,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
269 269
270 /* Create an input queue. */ 270 /* Create an input queue. */
271 sctp_inq_init(&asoc->base.inqueue); 271 sctp_inq_init(&asoc->base.inqueue);
272 sctp_inq_set_th_handler(&asoc->base.inqueue, 272 sctp_inq_set_th_handler(&asoc->base.inqueue, sctp_assoc_bh_rcv);
273 (void (*)(void *))sctp_assoc_bh_rcv,
274 asoc);
275 273
276 /* Create an output queue. */ 274 /* Create an output queue. */
277 sctp_outq_init(asoc, &asoc->outqueue); 275 sctp_outq_init(asoc, &asoc->outqueue);
@@ -300,6 +298,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
300 asoc->default_flags = sp->default_flags; 298 asoc->default_flags = sp->default_flags;
301 asoc->default_context = sp->default_context; 299 asoc->default_context = sp->default_context;
302 asoc->default_timetolive = sp->default_timetolive; 300 asoc->default_timetolive = sp->default_timetolive;
301 asoc->default_rcv_context = sp->default_rcv_context;
303 302
304 return asoc; 303 return asoc;
305 304
@@ -488,7 +487,7 @@ void sctp_assoc_rm_peer(struct sctp_association *asoc,
488 " port: %d\n", 487 " port: %d\n",
489 asoc, 488 asoc,
490 (&peer->ipaddr), 489 (&peer->ipaddr),
491 peer->ipaddr.v4.sin_port); 490 ntohs(peer->ipaddr.v4.sin_port));
492 491
493 /* If we are to remove the current retran_path, update it 492 /* If we are to remove the current retran_path, update it
494 * to the next peer before removing this peer from the list. 493 * to the next peer before removing this peer from the list.
@@ -537,13 +536,13 @@ struct sctp_transport *sctp_assoc_add_peer(struct sctp_association *asoc,
537 sp = sctp_sk(asoc->base.sk); 536 sp = sctp_sk(asoc->base.sk);
538 537
539 /* AF_INET and AF_INET6 share common port field. */ 538 /* AF_INET and AF_INET6 share common port field. */
540 port = addr->v4.sin_port; 539 port = ntohs(addr->v4.sin_port);
541 540
542 SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_add_peer:association %p addr: ", 541 SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_add_peer:association %p addr: ",
543 " port: %d state:%d\n", 542 " port: %d state:%d\n",
544 asoc, 543 asoc,
545 addr, 544 addr,
546 addr->v4.sin_port, 545 port,
547 peer_state); 546 peer_state);
548 547
549 /* Set the port if it has not been set yet. */ 548 /* Set the port if it has not been set yet. */
@@ -709,6 +708,7 @@ void sctp_assoc_control_transport(struct sctp_association *asoc,
709 struct sctp_transport *first; 708 struct sctp_transport *first;
710 struct sctp_transport *second; 709 struct sctp_transport *second;
711 struct sctp_ulpevent *event; 710 struct sctp_ulpevent *event;
711 struct sockaddr_storage addr;
712 struct list_head *pos; 712 struct list_head *pos;
713 int spc_state = 0; 713 int spc_state = 0;
714 714
@@ -731,8 +731,9 @@ void sctp_assoc_control_transport(struct sctp_association *asoc,
731 /* Generate and send a SCTP_PEER_ADDR_CHANGE notification to the 731 /* Generate and send a SCTP_PEER_ADDR_CHANGE notification to the
732 * user. 732 * user.
733 */ 733 */
734 event = sctp_ulpevent_make_peer_addr_change(asoc, 734 memset(&addr, 0, sizeof(struct sockaddr_storage));
735 (struct sockaddr_storage *) &transport->ipaddr, 735 memcpy(&addr, &transport->ipaddr, transport->af_specific->sockaddr_len);
736 event = sctp_ulpevent_make_peer_addr_change(asoc, &addr,
736 0, spc_state, error, GFP_ATOMIC); 737 0, spc_state, error, GFP_ATOMIC);
737 if (event) 738 if (event)
738 sctp_ulpq_tail_event(&asoc->ulpq, event); 739 sctp_ulpq_tail_event(&asoc->ulpq, event);
@@ -868,7 +869,7 @@ struct sctp_transport *sctp_assoc_lookup_tsn(struct sctp_association *asoc,
868 struct list_head *entry, *pos; 869 struct list_head *entry, *pos;
869 struct sctp_transport *transport; 870 struct sctp_transport *transport;
870 struct sctp_chunk *chunk; 871 struct sctp_chunk *chunk;
871 __u32 key = htonl(tsn); 872 __be32 key = htonl(tsn);
872 873
873 match = NULL; 874 match = NULL;
874 875
@@ -926,8 +927,8 @@ struct sctp_transport *sctp_assoc_is_match(struct sctp_association *asoc,
926 927
927 sctp_read_lock(&asoc->base.addr_lock); 928 sctp_read_lock(&asoc->base.addr_lock);
928 929
929 if ((asoc->base.bind_addr.port == laddr->v4.sin_port) && 930 if ((htons(asoc->base.bind_addr.port) == laddr->v4.sin_port) &&
930 (asoc->peer.port == paddr->v4.sin_port)) { 931 (htons(asoc->peer.port) == paddr->v4.sin_port)) {
931 transport = sctp_assoc_lookup_paddr(asoc, paddr); 932 transport = sctp_assoc_lookup_paddr(asoc, paddr);
932 if (!transport) 933 if (!transport)
933 goto out; 934 goto out;
@@ -944,8 +945,11 @@ out:
944} 945}
945 946
946/* Do delayed input processing. This is scheduled by sctp_rcv(). */ 947/* Do delayed input processing. This is scheduled by sctp_rcv(). */
947static void sctp_assoc_bh_rcv(struct sctp_association *asoc) 948static void sctp_assoc_bh_rcv(struct work_struct *work)
948{ 949{
950 struct sctp_association *asoc =
951 container_of(work, struct sctp_association,
952 base.inqueue.immediate);
949 struct sctp_endpoint *ep; 953 struct sctp_endpoint *ep;
950 struct sctp_chunk *chunk; 954 struct sctp_chunk *chunk;
951 struct sock *sk; 955 struct sock *sk;
@@ -1135,7 +1139,7 @@ void sctp_assoc_update_retran_path(struct sctp_association *asoc)
1135 " port: %d\n", 1139 " port: %d\n",
1136 asoc, 1140 asoc,
1137 (&t->ipaddr), 1141 (&t->ipaddr),
1138 t->ipaddr.v4.sin_port); 1142 ntohs(t->ipaddr.v4.sin_port));
1139} 1143}
1140 1144
1141/* Choose the transport for sending a INIT packet. */ 1145/* Choose the transport for sending a INIT packet. */
@@ -1160,7 +1164,7 @@ struct sctp_transport *sctp_assoc_choose_init_transport(
1160 " port: %d\n", 1164 " port: %d\n",
1161 asoc, 1165 asoc,
1162 (&t->ipaddr), 1166 (&t->ipaddr),
1163 t->ipaddr.v4.sin_port); 1167 ntohs(t->ipaddr.v4.sin_port));
1164 1168
1165 return t; 1169 return t;
1166} 1170}
diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c
index 2b9c12a170..00994158e4 100644
--- a/net/sctp/bind_addr.c
+++ b/net/sctp/bind_addr.c
@@ -161,7 +161,7 @@ int sctp_add_bind_addr(struct sctp_bind_addr *bp, union sctp_addr *new,
161 * Both v4 and v6 have the port at the same offset. 161 * Both v4 and v6 have the port at the same offset.
162 */ 162 */
163 if (!addr->a.v4.sin_port) 163 if (!addr->a.v4.sin_port)
164 addr->a.v4.sin_port = bp->port; 164 addr->a.v4.sin_port = htons(bp->port);
165 165
166 addr->use_as_src = use_as_src; 166 addr->use_as_src = use_as_src;
167 167
@@ -275,7 +275,7 @@ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw_addr_list,
275 break; 275 break;
276 } 276 }
277 277
278 af->from_addr_param(&addr, rawaddr, port, 0); 278 af->from_addr_param(&addr, rawaddr, htons(port), 0);
279 retval = sctp_add_bind_addr(bp, &addr, 1, gfp); 279 retval = sctp_add_bind_addr(bp, &addr, 1, gfp);
280 if (retval) { 280 if (retval) {
281 /* Can't finish building the list, clean up. */ 281 /* Can't finish building the list, clean up. */
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index 9b6b394b66..129756908d 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -61,7 +61,7 @@
61#include <net/sctp/sm.h> 61#include <net/sctp/sm.h>
62 62
63/* Forward declarations for internal helpers. */ 63/* Forward declarations for internal helpers. */
64static void sctp_endpoint_bh_rcv(struct sctp_endpoint *ep); 64static void sctp_endpoint_bh_rcv(struct work_struct *work);
65 65
66/* 66/*
67 * Initialize the base fields of the endpoint structure. 67 * Initialize the base fields of the endpoint structure.
@@ -72,6 +72,10 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
72{ 72{
73 memset(ep, 0, sizeof(struct sctp_endpoint)); 73 memset(ep, 0, sizeof(struct sctp_endpoint));
74 74
75 ep->digest = kzalloc(SCTP_SIGNATURE_SIZE, gfp);
76 if (!ep->digest)
77 return NULL;
78
75 /* Initialize the base structure. */ 79 /* Initialize the base structure. */
76 /* What type of endpoint are we? */ 80 /* What type of endpoint are we? */
77 ep->base.type = SCTP_EP_TYPE_SOCKET; 81 ep->base.type = SCTP_EP_TYPE_SOCKET;
@@ -85,8 +89,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
85 sctp_inq_init(&ep->base.inqueue); 89 sctp_inq_init(&ep->base.inqueue);
86 90
87 /* Set its top-half handler */ 91 /* Set its top-half handler */
88 sctp_inq_set_th_handler(&ep->base.inqueue, 92 sctp_inq_set_th_handler(&ep->base.inqueue, sctp_endpoint_bh_rcv);
89 (void (*)(void *))sctp_endpoint_bh_rcv, ep);
90 93
91 /* Initialize the bind addr area */ 94 /* Initialize the bind addr area */
92 sctp_bind_addr_init(&ep->base.bind_addr, 0); 95 sctp_bind_addr_init(&ep->base.bind_addr, 0);
@@ -182,6 +185,9 @@ static void sctp_endpoint_destroy(struct sctp_endpoint *ep)
182 /* Free up the HMAC transform. */ 185 /* Free up the HMAC transform. */
183 crypto_free_hash(sctp_sk(ep->base.sk)->hmac); 186 crypto_free_hash(sctp_sk(ep->base.sk)->hmac);
184 187
188 /* Free the digest buffer */
189 kfree(ep->digest);
190
185 /* Cleanup. */ 191 /* Cleanup. */
186 sctp_inq_free(&ep->base.inqueue); 192 sctp_inq_free(&ep->base.inqueue);
187 sctp_bind_addr_free(&ep->base.bind_addr); 193 sctp_bind_addr_free(&ep->base.bind_addr);
@@ -223,7 +229,7 @@ struct sctp_endpoint *sctp_endpoint_is_match(struct sctp_endpoint *ep,
223 struct sctp_endpoint *retval; 229 struct sctp_endpoint *retval;
224 230
225 sctp_read_lock(&ep->base.addr_lock); 231 sctp_read_lock(&ep->base.addr_lock);
226 if (ep->base.bind_addr.port == laddr->v4.sin_port) { 232 if (htons(ep->base.bind_addr.port) == laddr->v4.sin_port) {
227 if (sctp_bind_addr_match(&ep->base.bind_addr, laddr, 233 if (sctp_bind_addr_match(&ep->base.bind_addr, laddr,
228 sctp_sk(ep->base.sk))) { 234 sctp_sk(ep->base.sk))) {
229 retval = ep; 235 retval = ep;
@@ -251,7 +257,7 @@ static struct sctp_association *__sctp_endpoint_lookup_assoc(
251 struct sctp_association *asoc; 257 struct sctp_association *asoc;
252 struct list_head *pos; 258 struct list_head *pos;
253 259
254 rport = paddr->v4.sin_port; 260 rport = ntohs(paddr->v4.sin_port);
255 261
256 list_for_each(pos, &ep->asocs) { 262 list_for_each(pos, &ep->asocs) {
257 asoc = list_entry(pos, struct sctp_association, asocs); 263 asoc = list_entry(pos, struct sctp_association, asocs);
@@ -311,8 +317,11 @@ int sctp_endpoint_is_peeled_off(struct sctp_endpoint *ep,
311/* Do delayed input processing. This is scheduled by sctp_rcv(). 317/* Do delayed input processing. This is scheduled by sctp_rcv().
312 * This may be called on BH or task time. 318 * This may be called on BH or task time.
313 */ 319 */
314static void sctp_endpoint_bh_rcv(struct sctp_endpoint *ep) 320static void sctp_endpoint_bh_rcv(struct work_struct *work)
315{ 321{
322 struct sctp_endpoint *ep =
323 container_of(work, struct sctp_endpoint,
324 base.inqueue.immediate);
316 struct sctp_association *asoc; 325 struct sctp_association *asoc;
317 struct sock *sk; 326 struct sock *sk;
318 struct sctp_transport *transport; 327 struct sctp_transport *transport;
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 6d82f400d1..33111873a4 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -726,7 +726,7 @@ static struct sctp_endpoint *__sctp_rcv_lookup_endpoint(const union sctp_addr *l
726 struct sctp_endpoint *ep; 726 struct sctp_endpoint *ep;
727 int hash; 727 int hash;
728 728
729 hash = sctp_ep_hashfn(laddr->v4.sin_port); 729 hash = sctp_ep_hashfn(ntohs(laddr->v4.sin_port));
730 head = &sctp_ep_hashtable[hash]; 730 head = &sctp_ep_hashtable[hash];
731 read_lock(&head->lock); 731 read_lock(&head->lock);
732 for (epb = head->chain; epb; epb = epb->next) { 732 for (epb = head->chain; epb; epb = epb->next) {
@@ -830,7 +830,7 @@ static struct sctp_association *__sctp_lookup_association(
830 /* Optimize here for direct hit, only listening connections can 830 /* Optimize here for direct hit, only listening connections can
831 * have wildcards anyways. 831 * have wildcards anyways.
832 */ 832 */
833 hash = sctp_assoc_hashfn(local->v4.sin_port, peer->v4.sin_port); 833 hash = sctp_assoc_hashfn(ntohs(local->v4.sin_port), ntohs(peer->v4.sin_port));
834 head = &sctp_assoc_hashtable[hash]; 834 head = &sctp_assoc_hashtable[hash];
835 read_lock(&head->lock); 835 read_lock(&head->lock);
836 for (epb = head->chain; epb; epb = epb->next) { 836 for (epb = head->chain; epb; epb = epb->next) {
@@ -957,7 +957,7 @@ static struct sctp_association *__sctp_rcv_init_lookup(struct sk_buff *skb,
957 if (!af) 957 if (!af)
958 continue; 958 continue;
959 959
960 af->from_addr_param(paddr, params.addr, ntohs(sh->source), 0); 960 af->from_addr_param(paddr, params.addr, sh->source, 0);
961 961
962 asoc = __sctp_lookup_association(laddr, paddr, &transport); 962 asoc = __sctp_lookup_association(laddr, paddr, &transport);
963 if (asoc) 963 if (asoc)
diff --git a/net/sctp/inqueue.c b/net/sctp/inqueue.c
index cf6deed7e8..71b07466e8 100644
--- a/net/sctp/inqueue.c
+++ b/net/sctp/inqueue.c
@@ -54,7 +54,7 @@ void sctp_inq_init(struct sctp_inq *queue)
54 queue->in_progress = NULL; 54 queue->in_progress = NULL;
55 55
56 /* Create a task for delivering data. */ 56 /* Create a task for delivering data. */
57 INIT_WORK(&queue->immediate, NULL, NULL); 57 INIT_WORK(&queue->immediate, NULL);
58 58
59 queue->malloced = 0; 59 queue->malloced = 0;
60} 60}
@@ -97,7 +97,7 @@ void sctp_inq_push(struct sctp_inq *q, struct sctp_chunk *chunk)
97 * on the BH related data structures. 97 * on the BH related data structures.
98 */ 98 */
99 list_add_tail(&chunk->list, &q->in_chunk_list); 99 list_add_tail(&chunk->list, &q->in_chunk_list);
100 q->immediate.func(q->immediate.data); 100 q->immediate.func(&q->immediate);
101} 101}
102 102
103/* Extract a chunk from an SCTP inqueue. 103/* Extract a chunk from an SCTP inqueue.
@@ -205,9 +205,8 @@ struct sctp_chunk *sctp_inq_pop(struct sctp_inq *queue)
205 * The intent is that this routine will pull stuff out of the 205 * The intent is that this routine will pull stuff out of the
206 * inqueue and process it. 206 * inqueue and process it.
207 */ 207 */
208void sctp_inq_set_th_handler(struct sctp_inq *q, 208void sctp_inq_set_th_handler(struct sctp_inq *q, work_func_t callback)
209 void (*callback)(void *), void *arg)
210{ 209{
211 INIT_WORK(&q->immediate, callback, arg); 210 INIT_WORK(&q->immediate, callback);
212} 211}
213 212
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
index 78071c6e6c..ef36be073a 100644
--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -78,13 +78,49 @@
78 78
79#include <asm/uaccess.h> 79#include <asm/uaccess.h>
80 80
81/* Event handler for inet6 address addition/deletion events. */
82static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev,
83 void *ptr)
84{
85 struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr;
86 struct sctp_sockaddr_entry *addr;
87 struct list_head *pos, *temp;
88
89 switch (ev) {
90 case NETDEV_UP:
91 addr = kmalloc(sizeof(struct sctp_sockaddr_entry), GFP_ATOMIC);
92 if (addr) {
93 addr->a.v6.sin6_family = AF_INET6;
94 addr->a.v6.sin6_port = 0;
95 memcpy(&addr->a.v6.sin6_addr, &ifa->addr,
96 sizeof(struct in6_addr));
97 addr->a.v6.sin6_scope_id = ifa->idev->dev->ifindex;
98 list_add_tail(&addr->list, &sctp_local_addr_list);
99 }
100 break;
101 case NETDEV_DOWN:
102 list_for_each_safe(pos, temp, &sctp_local_addr_list) {
103 addr = list_entry(pos, struct sctp_sockaddr_entry, list);
104 if (ipv6_addr_equal(&addr->a.v6.sin6_addr, &ifa->addr)) {
105 list_del(pos);
106 kfree(addr);
107 break;
108 }
109 }
110
111 break;
112 }
113
114 return NOTIFY_DONE;
115}
116
81static struct notifier_block sctp_inet6addr_notifier = { 117static struct notifier_block sctp_inet6addr_notifier = {
82 .notifier_call = sctp_inetaddr_event, 118 .notifier_call = sctp_inet6addr_event,
83}; 119};
84 120
85/* ICMP error handler. */ 121/* ICMP error handler. */
86SCTP_STATIC void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, 122SCTP_STATIC void sctp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
87 int type, int code, int offset, __u32 info) 123 int type, int code, int offset, __be32 info)
88{ 124{
89 struct inet6_dev *idev; 125 struct inet6_dev *idev;
90 struct ipv6hdr *iph = (struct ipv6hdr *)skb->data; 126 struct ipv6hdr *iph = (struct ipv6hdr *)skb->data;
@@ -170,8 +206,6 @@ static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport,
170 fl.oif = transport->saddr.v6.sin6_scope_id; 206 fl.oif = transport->saddr.v6.sin6_scope_id;
171 else 207 else
172 fl.oif = sk->sk_bound_dev_if; 208 fl.oif = sk->sk_bound_dev_if;
173 fl.fl_ip_sport = inet_sk(sk)->sport;
174 fl.fl_ip_dport = transport->ipaddr.v6.sin6_port;
175 209
176 if (np->opt && np->opt->srcrt) { 210 if (np->opt && np->opt->srcrt) {
177 struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt; 211 struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
@@ -239,7 +273,7 @@ static inline int sctp_v6_addr_match_len(union sctp_addr *s1,
239 int i, j; 273 int i, j;
240 274
241 for (i = 0; i < 4 ; i++) { 275 for (i = 0; i < 4 ; i++) {
242 __u32 a1xora2; 276 __be32 a1xora2;
243 277
244 a1xora2 = a1->s6_addr32[i] ^ a2->s6_addr32[i]; 278 a1xora2 = a1->s6_addr32[i] ^ a2->s6_addr32[i];
245 279
@@ -350,7 +384,7 @@ static void sctp_v6_from_skb(union sctp_addr *addr,struct sk_buff *skb,
350 int is_saddr) 384 int is_saddr)
351{ 385{
352 void *from; 386 void *from;
353 __u16 *port; 387 __be16 *port;
354 struct sctphdr *sh; 388 struct sctphdr *sh;
355 389
356 port = &addr->v6.sin6_port; 390 port = &addr->v6.sin6_port;
@@ -360,10 +394,10 @@ static void sctp_v6_from_skb(union sctp_addr *addr,struct sk_buff *skb,
360 394
361 sh = (struct sctphdr *) skb->h.raw; 395 sh = (struct sctphdr *) skb->h.raw;
362 if (is_saddr) { 396 if (is_saddr) {
363 *port = ntohs(sh->source); 397 *port = sh->source;
364 from = &skb->nh.ipv6h->saddr; 398 from = &skb->nh.ipv6h->saddr;
365 } else { 399 } else {
366 *port = ntohs(sh->dest); 400 *port = sh->dest;
367 from = &skb->nh.ipv6h->daddr; 401 from = &skb->nh.ipv6h->daddr;
368 } 402 }
369 ipv6_addr_copy(&addr->v6.sin6_addr, from); 403 ipv6_addr_copy(&addr->v6.sin6_addr, from);
@@ -373,7 +407,7 @@ static void sctp_v6_from_skb(union sctp_addr *addr,struct sk_buff *skb,
373static void sctp_v6_from_sk(union sctp_addr *addr, struct sock *sk) 407static void sctp_v6_from_sk(union sctp_addr *addr, struct sock *sk)
374{ 408{
375 addr->v6.sin6_family = AF_INET6; 409 addr->v6.sin6_family = AF_INET6;
376 addr->v6.sin6_port = inet_sk(sk)->num; 410 addr->v6.sin6_port = 0;
377 addr->v6.sin6_addr = inet6_sk(sk)->rcv_saddr; 411 addr->v6.sin6_addr = inet6_sk(sk)->rcv_saddr;
378} 412}
379 413
@@ -407,7 +441,7 @@ static void sctp_v6_to_sk_daddr(union sctp_addr *addr, struct sock *sk)
407/* Initialize a sctp_addr from an address parameter. */ 441/* Initialize a sctp_addr from an address parameter. */
408static void sctp_v6_from_addr_param(union sctp_addr *addr, 442static void sctp_v6_from_addr_param(union sctp_addr *addr,
409 union sctp_addr_param *param, 443 union sctp_addr_param *param,
410 __u16 port, int iif) 444 __be16 port, int iif)
411{ 445{
412 addr->v6.sin6_family = AF_INET6; 446 addr->v6.sin6_family = AF_INET6;
413 addr->v6.sin6_port = port; 447 addr->v6.sin6_port = port;
@@ -425,7 +459,7 @@ static int sctp_v6_to_addr_param(const union sctp_addr *addr,
425 int length = sizeof(sctp_ipv6addr_param_t); 459 int length = sizeof(sctp_ipv6addr_param_t);
426 460
427 param->v6.param_hdr.type = SCTP_PARAM_IPV6_ADDRESS; 461 param->v6.param_hdr.type = SCTP_PARAM_IPV6_ADDRESS;
428 param->v6.param_hdr.length = ntohs(length); 462 param->v6.param_hdr.length = htons(length);
429 ipv6_addr_copy(&param->v6.addr, &addr->v6.sin6_addr); 463 ipv6_addr_copy(&param->v6.addr, &addr->v6.sin6_addr);
430 464
431 return length; 465 return length;
@@ -433,7 +467,7 @@ static int sctp_v6_to_addr_param(const union sctp_addr *addr,
433 467
434/* Initialize a sctp_addr from a dst_entry. */ 468/* Initialize a sctp_addr from a dst_entry. */
435static void sctp_v6_dst_saddr(union sctp_addr *addr, struct dst_entry *dst, 469static void sctp_v6_dst_saddr(union sctp_addr *addr, struct dst_entry *dst,
436 unsigned short port) 470 __be16 port)
437{ 471{
438 struct rt6_info *rt = (struct rt6_info *)dst; 472 struct rt6_info *rt = (struct rt6_info *)dst;
439 addr->sa.sa_family = AF_INET6; 473 addr->sa.sa_family = AF_INET6;
@@ -480,7 +514,7 @@ static int sctp_v6_cmp_addr(const union sctp_addr *addr1,
480} 514}
481 515
482/* Initialize addr struct to INADDR_ANY. */ 516/* Initialize addr struct to INADDR_ANY. */
483static void sctp_v6_inaddr_any(union sctp_addr *addr, unsigned short port) 517static void sctp_v6_inaddr_any(union sctp_addr *addr, __be16 port)
484{ 518{
485 memset(addr, 0x00, sizeof(union sctp_addr)); 519 memset(addr, 0x00, sizeof(union sctp_addr));
486 addr->v6.sin6_family = AF_INET6; 520 addr->v6.sin6_family = AF_INET6;
@@ -855,7 +889,7 @@ static int sctp_inet6_send_verify(struct sctp_sock *opt, union sctp_addr *addr)
855 * Returns number of addresses supported. 889 * Returns number of addresses supported.
856 */ 890 */
857static int sctp_inet6_supported_addrs(const struct sctp_sock *opt, 891static int sctp_inet6_supported_addrs(const struct sctp_sock *opt,
858 __u16 *types) 892 __be16 *types)
859{ 893{
860 types[0] = SCTP_PARAM_IPV4_ADDRESS; 894 types[0] = SCTP_PARAM_IPV4_ADDRESS;
861 types[1] = SCTP_PARAM_IPV6_ADDRESS; 895 types[1] = SCTP_PARAM_IPV6_ADDRESS;
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index 739582415b..fba567a7cb 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -1065,7 +1065,7 @@ int sctp_outq_sack(struct sctp_outq *q, struct sctp_sackhdr *sack)
1065 * A) Initialize the cacc_saw_newack to 0 for all destination 1065 * A) Initialize the cacc_saw_newack to 0 for all destination
1066 * addresses. 1066 * addresses.
1067 */ 1067 */
1068 if (sack->num_gap_ack_blocks > 0 && 1068 if (sack->num_gap_ack_blocks &&
1069 primary->cacc.changeover_active) { 1069 primary->cacc.changeover_active) {
1070 list_for_each(pos, transport_list) { 1070 list_for_each(pos, transport_list) {
1071 transport = list_entry(pos, struct sctp_transport, 1071 transport = list_entry(pos, struct sctp_transport,
@@ -1632,7 +1632,7 @@ pass:
1632} 1632}
1633 1633
1634static inline int sctp_get_skip_pos(struct sctp_fwdtsn_skip *skiplist, 1634static inline int sctp_get_skip_pos(struct sctp_fwdtsn_skip *skiplist,
1635 int nskips, __u16 stream) 1635 int nskips, __be16 stream)
1636{ 1636{
1637 int i; 1637 int i;
1638 1638
diff --git a/net/sctp/proc.c b/net/sctp/proc.c
index 7f49e76908..b3493bdbca 100644
--- a/net/sctp/proc.c
+++ b/net/sctp/proc.c
@@ -160,7 +160,7 @@ static void sctp_seq_dump_local_addrs(struct seq_file *seq, struct sctp_ep_commo
160 160
161 list_for_each(pos, &epb->bind_addr.address_list) { 161 list_for_each(pos, &epb->bind_addr.address_list) {
162 laddr = list_entry(pos, struct sctp_sockaddr_entry, list); 162 laddr = list_entry(pos, struct sctp_sockaddr_entry, list);
163 addr = (union sctp_addr *)&laddr->a; 163 addr = &laddr->a;
164 af = sctp_get_af_specific(addr->sa.sa_family); 164 af = sctp_get_af_specific(addr->sa.sa_family);
165 if (primary && af->cmp_addr(addr, primary)) { 165 if (primary && af->cmp_addr(addr, primary)) {
166 seq_printf(seq, "*"); 166 seq_printf(seq, "*");
@@ -177,10 +177,10 @@ static void sctp_seq_dump_remote_addrs(struct seq_file *seq, struct sctp_associa
177 union sctp_addr *addr, *primary; 177 union sctp_addr *addr, *primary;
178 struct sctp_af *af; 178 struct sctp_af *af;
179 179
180 primary = &(assoc->peer.primary_addr); 180 primary = &assoc->peer.primary_addr;
181 list_for_each(pos, &assoc->peer.transport_addr_list) { 181 list_for_each(pos, &assoc->peer.transport_addr_list) {
182 transport = list_entry(pos, struct sctp_transport, transports); 182 transport = list_entry(pos, struct sctp_transport, transports);
183 addr = (union sctp_addr *)&transport->ipaddr; 183 addr = &transport->ipaddr;
184 af = sctp_get_af_specific(addr->sa.sa_family); 184 af = sctp_get_af_specific(addr->sa.sa_family);
185 if (af->cmp_addr(addr, primary)) { 185 if (af->cmp_addr(addr, primary)) {
186 seq_printf(seq, "*"); 186 seq_printf(seq, "*");
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 5b4f82fd98..225f39b5d5 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -79,8 +79,8 @@ static struct sctp_pf *sctp_pf_inet_specific;
79static struct sctp_af *sctp_af_v4_specific; 79static struct sctp_af *sctp_af_v4_specific;
80static struct sctp_af *sctp_af_v6_specific; 80static struct sctp_af *sctp_af_v6_specific;
81 81
82kmem_cache_t *sctp_chunk_cachep __read_mostly; 82struct kmem_cache *sctp_chunk_cachep __read_mostly;
83kmem_cache_t *sctp_bucket_cachep __read_mostly; 83struct kmem_cache *sctp_bucket_cachep __read_mostly;
84 84
85/* Return the address of the control sock. */ 85/* Return the address of the control sock. */
86struct sock *sctp_get_ctl_sock(void) 86struct sock *sctp_get_ctl_sock(void)
@@ -163,7 +163,7 @@ static void sctp_v4_copy_addrlist(struct list_head *addrlist,
163/* Extract our IP addresses from the system and stash them in the 163/* Extract our IP addresses from the system and stash them in the
164 * protocol structure. 164 * protocol structure.
165 */ 165 */
166static void __sctp_get_local_addr_list(void) 166static void sctp_get_local_addr_list(void)
167{ 167{
168 struct net_device *dev; 168 struct net_device *dev;
169 struct list_head *pos; 169 struct list_head *pos;
@@ -179,17 +179,8 @@ static void __sctp_get_local_addr_list(void)
179 read_unlock(&dev_base_lock); 179 read_unlock(&dev_base_lock);
180} 180}
181 181
182static void sctp_get_local_addr_list(void)
183{
184 unsigned long flags;
185
186 sctp_spin_lock_irqsave(&sctp_local_addr_lock, flags);
187 __sctp_get_local_addr_list();
188 sctp_spin_unlock_irqrestore(&sctp_local_addr_lock, flags);
189}
190
191/* Free the existing local addresses. */ 182/* Free the existing local addresses. */
192static void __sctp_free_local_addr_list(void) 183static void sctp_free_local_addr_list(void)
193{ 184{
194 struct sctp_sockaddr_entry *addr; 185 struct sctp_sockaddr_entry *addr;
195 struct list_head *pos, *temp; 186 struct list_head *pos, *temp;
@@ -201,27 +192,15 @@ static void __sctp_free_local_addr_list(void)
201 } 192 }
202} 193}
203 194
204/* Free the existing local addresses. */
205static void sctp_free_local_addr_list(void)
206{
207 unsigned long flags;
208
209 sctp_spin_lock_irqsave(&sctp_local_addr_lock, flags);
210 __sctp_free_local_addr_list();
211 sctp_spin_unlock_irqrestore(&sctp_local_addr_lock, flags);
212}
213
214/* Copy the local addresses which are valid for 'scope' into 'bp'. */ 195/* Copy the local addresses which are valid for 'scope' into 'bp'. */
215int sctp_copy_local_addr_list(struct sctp_bind_addr *bp, sctp_scope_t scope, 196int sctp_copy_local_addr_list(struct sctp_bind_addr *bp, sctp_scope_t scope,
216 gfp_t gfp, int copy_flags) 197 gfp_t gfp, int copy_flags)
217{ 198{
218 struct sctp_sockaddr_entry *addr; 199 struct sctp_sockaddr_entry *addr;
219 int error = 0; 200 int error = 0;
220 struct list_head *pos; 201 struct list_head *pos, *temp;
221 unsigned long flags;
222 202
223 sctp_spin_lock_irqsave(&sctp_local_addr_lock, flags); 203 list_for_each_safe(pos, temp, &sctp_local_addr_list) {
224 list_for_each(pos, &sctp_local_addr_list) {
225 addr = list_entry(pos, struct sctp_sockaddr_entry, list); 204 addr = list_entry(pos, struct sctp_sockaddr_entry, list);
226 if (sctp_in_scope(&addr->a, scope)) { 205 if (sctp_in_scope(&addr->a, scope)) {
227 /* Now that the address is in scope, check to see if 206 /* Now that the address is in scope, check to see if
@@ -242,7 +221,6 @@ int sctp_copy_local_addr_list(struct sctp_bind_addr *bp, sctp_scope_t scope,
242 } 221 }
243 222
244end_copy: 223end_copy:
245 sctp_spin_unlock_irqrestore(&sctp_local_addr_lock, flags);
246 return error; 224 return error;
247} 225}
248 226
@@ -251,7 +229,7 @@ static void sctp_v4_from_skb(union sctp_addr *addr, struct sk_buff *skb,
251 int is_saddr) 229 int is_saddr)
252{ 230{
253 void *from; 231 void *from;
254 __u16 *port; 232 __be16 *port;
255 struct sctphdr *sh; 233 struct sctphdr *sh;
256 234
257 port = &addr->v4.sin_port; 235 port = &addr->v4.sin_port;
@@ -259,10 +237,10 @@ static void sctp_v4_from_skb(union sctp_addr *addr, struct sk_buff *skb,
259 237
260 sh = (struct sctphdr *) skb->h.raw; 238 sh = (struct sctphdr *) skb->h.raw;
261 if (is_saddr) { 239 if (is_saddr) {
262 *port = ntohs(sh->source); 240 *port = sh->source;
263 from = &skb->nh.iph->saddr; 241 from = &skb->nh.iph->saddr;
264 } else { 242 } else {
265 *port = ntohs(sh->dest); 243 *port = sh->dest;
266 from = &skb->nh.iph->daddr; 244 from = &skb->nh.iph->daddr;
267 } 245 }
268 memcpy(&addr->v4.sin_addr.s_addr, from, sizeof(struct in_addr)); 246 memcpy(&addr->v4.sin_addr.s_addr, from, sizeof(struct in_addr));
@@ -272,7 +250,7 @@ static void sctp_v4_from_skb(union sctp_addr *addr, struct sk_buff *skb,
272static void sctp_v4_from_sk(union sctp_addr *addr, struct sock *sk) 250static void sctp_v4_from_sk(union sctp_addr *addr, struct sock *sk)
273{ 251{
274 addr->v4.sin_family = AF_INET; 252 addr->v4.sin_family = AF_INET;
275 addr->v4.sin_port = inet_sk(sk)->num; 253 addr->v4.sin_port = 0;
276 addr->v4.sin_addr.s_addr = inet_sk(sk)->rcv_saddr; 254 addr->v4.sin_addr.s_addr = inet_sk(sk)->rcv_saddr;
277} 255}
278 256
@@ -291,7 +269,7 @@ static void sctp_v4_to_sk_daddr(union sctp_addr *addr, struct sock *sk)
291/* Initialize a sctp_addr from an address parameter. */ 269/* Initialize a sctp_addr from an address parameter. */
292static void sctp_v4_from_addr_param(union sctp_addr *addr, 270static void sctp_v4_from_addr_param(union sctp_addr *addr,
293 union sctp_addr_param *param, 271 union sctp_addr_param *param,
294 __u16 port, int iif) 272 __be16 port, int iif)
295{ 273{
296 addr->v4.sin_family = AF_INET; 274 addr->v4.sin_family = AF_INET;
297 addr->v4.sin_port = port; 275 addr->v4.sin_port = port;
@@ -307,7 +285,7 @@ static int sctp_v4_to_addr_param(const union sctp_addr *addr,
307 int length = sizeof(sctp_ipv4addr_param_t); 285 int length = sizeof(sctp_ipv4addr_param_t);
308 286
309 param->v4.param_hdr.type = SCTP_PARAM_IPV4_ADDRESS; 287 param->v4.param_hdr.type = SCTP_PARAM_IPV4_ADDRESS;
310 param->v4.param_hdr.length = ntohs(length); 288 param->v4.param_hdr.length = htons(length);
311 param->v4.addr.s_addr = addr->v4.sin_addr.s_addr; 289 param->v4.addr.s_addr = addr->v4.sin_addr.s_addr;
312 290
313 return length; 291 return length;
@@ -315,7 +293,7 @@ static int sctp_v4_to_addr_param(const union sctp_addr *addr,
315 293
316/* Initialize a sctp_addr from a dst_entry. */ 294/* Initialize a sctp_addr from a dst_entry. */
317static void sctp_v4_dst_saddr(union sctp_addr *saddr, struct dst_entry *dst, 295static void sctp_v4_dst_saddr(union sctp_addr *saddr, struct dst_entry *dst,
318 unsigned short port) 296 __be16 port)
319{ 297{
320 struct rtable *rt = (struct rtable *)dst; 298 struct rtable *rt = (struct rtable *)dst;
321 saddr->v4.sin_family = AF_INET; 299 saddr->v4.sin_family = AF_INET;
@@ -338,7 +316,7 @@ static int sctp_v4_cmp_addr(const union sctp_addr *addr1,
338} 316}
339 317
340/* Initialize addr struct to INADDR_ANY. */ 318/* Initialize addr struct to INADDR_ANY. */
341static void sctp_v4_inaddr_any(union sctp_addr *addr, unsigned short port) 319static void sctp_v4_inaddr_any(union sctp_addr *addr, __be16 port)
342{ 320{
343 addr->v4.sin_family = AF_INET; 321 addr->v4.sin_family = AF_INET;
344 addr->v4.sin_addr.s_addr = INADDR_ANY; 322 addr->v4.sin_addr.s_addr = INADDR_ANY;
@@ -481,7 +459,7 @@ static struct dst_entry *sctp_v4_get_dst(struct sctp_association *asoc,
481 list); 459 list);
482 if (!laddr->use_as_src) 460 if (!laddr->use_as_src)
483 continue; 461 continue;
484 sctp_v4_dst_saddr(&dst_saddr, dst, bp->port); 462 sctp_v4_dst_saddr(&dst_saddr, dst, htons(bp->port));
485 if (sctp_v4_cmp_addr(&dst_saddr, &laddr->a)) 463 if (sctp_v4_cmp_addr(&dst_saddr, &laddr->a))
486 goto out_unlock; 464 goto out_unlock;
487 } 465 }
@@ -538,7 +516,7 @@ static void sctp_v4_get_saddr(struct sctp_association *asoc,
538 516
539 if (rt) { 517 if (rt) {
540 saddr->v4.sin_family = AF_INET; 518 saddr->v4.sin_family = AF_INET;
541 saddr->v4.sin_port = asoc->base.bind_addr.port; 519 saddr->v4.sin_port = htons(asoc->base.bind_addr.port);
542 saddr->v4.sin_addr.s_addr = rt->rt_src; 520 saddr->v4.sin_addr.s_addr = rt->rt_src;
543 } 521 }
544} 522}
@@ -622,18 +600,36 @@ static void sctp_v4_seq_dump_addr(struct seq_file *seq, union sctp_addr *addr)
622 seq_printf(seq, "%d.%d.%d.%d ", NIPQUAD(addr->v4.sin_addr)); 600 seq_printf(seq, "%d.%d.%d.%d ", NIPQUAD(addr->v4.sin_addr));
623} 601}
624 602
625/* Event handler for inet address addition/deletion events. 603/* Event handler for inet address addition/deletion events. */
626 * Basically, whenever there is an event, we re-build our local address list. 604static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev,
627 */ 605 void *ptr)
628int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev,
629 void *ptr)
630{ 606{
631 unsigned long flags; 607 struct in_ifaddr *ifa = (struct in_ifaddr *)ptr;
608 struct sctp_sockaddr_entry *addr;
609 struct list_head *pos, *temp;
632 610
633 sctp_spin_lock_irqsave(&sctp_local_addr_lock, flags); 611 switch (ev) {
634 __sctp_free_local_addr_list(); 612 case NETDEV_UP:
635 __sctp_get_local_addr_list(); 613 addr = kmalloc(sizeof(struct sctp_sockaddr_entry), GFP_ATOMIC);
636 sctp_spin_unlock_irqrestore(&sctp_local_addr_lock, flags); 614 if (addr) {
615 addr->a.v4.sin_family = AF_INET;
616 addr->a.v4.sin_port = 0;
617 addr->a.v4.sin_addr.s_addr = ifa->ifa_local;
618 list_add_tail(&addr->list, &sctp_local_addr_list);
619 }
620 break;
621 case NETDEV_DOWN:
622 list_for_each_safe(pos, temp, &sctp_local_addr_list) {
623 addr = list_entry(pos, struct sctp_sockaddr_entry, list);
624 if (addr->a.v4.sin_addr.s_addr == ifa->ifa_local) {
625 list_del(pos);
626 kfree(addr);
627 break;
628 }
629 }
630
631 break;
632 }
637 633
638 return NOTIFY_DONE; 634 return NOTIFY_DONE;
639} 635}
@@ -791,7 +787,7 @@ static int sctp_inet_send_verify(struct sctp_sock *opt, union sctp_addr *addr)
791 * chunks. Returns number of addresses supported. 787 * chunks. Returns number of addresses supported.
792 */ 788 */
793static int sctp_inet_supported_addrs(const struct sctp_sock *opt, 789static int sctp_inet_supported_addrs(const struct sctp_sock *opt,
794 __u16 *types) 790 __be16 *types)
795{ 791{
796 types[0] = SCTP_PARAM_IPV4_ADDRESS; 792 types[0] = SCTP_PARAM_IPV4_ADDRESS;
797 return 1; 793 return 1;
@@ -808,7 +804,7 @@ static inline int sctp_v4_xmit(struct sk_buff *skb,
808 NIPQUAD(((struct rtable *)skb->dst)->rt_dst)); 804 NIPQUAD(((struct rtable *)skb->dst)->rt_dst));
809 805
810 SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS); 806 SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS);
811 return ip_queue_xmit(skb, ipfragok); 807 return ip_queue_xmit(skb, skb->sk, ipfragok);
812} 808}
813 809
814static struct sctp_af sctp_ipv4_specific; 810static struct sctp_af sctp_ipv4_specific;
@@ -1172,13 +1168,12 @@ SCTP_STATIC __init int sctp_init(void)
1172 1168
1173 /* Initialize the local address list. */ 1169 /* Initialize the local address list. */
1174 INIT_LIST_HEAD(&sctp_local_addr_list); 1170 INIT_LIST_HEAD(&sctp_local_addr_list);
1175 spin_lock_init(&sctp_local_addr_lock); 1171
1172 sctp_get_local_addr_list();
1176 1173
1177 /* Register notifier for inet address additions/deletions. */ 1174 /* Register notifier for inet address additions/deletions. */
1178 register_inetaddr_notifier(&sctp_inetaddr_notifier); 1175 register_inetaddr_notifier(&sctp_inetaddr_notifier);
1179 1176
1180 sctp_get_local_addr_list();
1181
1182 __unsafe(THIS_MODULE); 1177 __unsafe(THIS_MODULE);
1183 status = 0; 1178 status = 0;
1184out: 1179out:
@@ -1263,6 +1258,7 @@ module_exit(sctp_exit);
1263 * __stringify doesn't likes enums, so use IPPROTO_SCTP value (132) directly. 1258 * __stringify doesn't likes enums, so use IPPROTO_SCTP value (132) directly.
1264 */ 1259 */
1265MODULE_ALIAS("net-pf-" __stringify(PF_INET) "-proto-132"); 1260MODULE_ALIAS("net-pf-" __stringify(PF_INET) "-proto-132");
1261MODULE_ALIAS("net-pf-" __stringify(PF_INET6) "-proto-132");
1266MODULE_AUTHOR("Linux Kernel SCTP developers <lksctp-developers@lists.sourceforge.net>"); 1262MODULE_AUTHOR("Linux Kernel SCTP developers <lksctp-developers@lists.sourceforge.net>");
1267MODULE_DESCRIPTION("Support for the SCTP protocol (RFC2960)"); 1263MODULE_DESCRIPTION("Support for the SCTP protocol (RFC2960)");
1268MODULE_LICENSE("GPL"); 1264MODULE_LICENSE("GPL");
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 507dff72c5..167d888d1d 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -65,7 +65,7 @@
65#include <net/sctp/sctp.h> 65#include <net/sctp/sctp.h>
66#include <net/sctp/sm.h> 66#include <net/sctp/sm.h>
67 67
68extern kmem_cache_t *sctp_chunk_cachep; 68extern struct kmem_cache *sctp_chunk_cachep;
69 69
70SCTP_STATIC 70SCTP_STATIC
71struct sctp_chunk *sctp_make_chunk(const struct sctp_association *asoc, 71struct sctp_chunk *sctp_make_chunk(const struct sctp_association *asoc,
@@ -111,7 +111,7 @@ static const struct sctp_paramhdr prsctp_param = {
111 * provided chunk, as most cause codes will be embedded inside an 111 * provided chunk, as most cause codes will be embedded inside an
112 * abort chunk. 112 * abort chunk.
113 */ 113 */
114void sctp_init_cause(struct sctp_chunk *chunk, __u16 cause_code, 114void sctp_init_cause(struct sctp_chunk *chunk, __be16 cause_code,
115 const void *payload, size_t paylen) 115 const void *payload, size_t paylen)
116{ 116{
117 sctp_errhdr_t err; 117 sctp_errhdr_t err;
@@ -124,8 +124,8 @@ void sctp_init_cause(struct sctp_chunk *chunk, __u16 cause_code,
124 padlen = len % 4; 124 padlen = len % 4;
125 err.length = htons(len); 125 err.length = htons(len);
126 len += padlen; 126 len += padlen;
127 sctp_addto_chunk(chunk, sizeof(sctp_errhdr_t), &err); 127 chunk->subh.err_hdr = sctp_addto_chunk(chunk, sizeof(sctp_errhdr_t), &err);
128 chunk->subh.err_hdr = sctp_addto_chunk(chunk, paylen, payload); 128 sctp_addto_chunk(chunk, paylen, payload);
129} 129}
130 130
131/* 3.3.2 Initiation (INIT) (1) 131/* 3.3.2 Initiation (INIT) (1)
@@ -183,8 +183,8 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
183 int num_types, addrs_len = 0; 183 int num_types, addrs_len = 0;
184 struct sctp_sock *sp; 184 struct sctp_sock *sp;
185 sctp_supported_addrs_param_t sat; 185 sctp_supported_addrs_param_t sat;
186 __u16 types[2]; 186 __be16 types[2];
187 sctp_adaption_ind_param_t aiparam; 187 sctp_adaptation_ind_param_t aiparam;
188 188
189 /* RFC 2960 3.3.2 Initiation (INIT) (1) 189 /* RFC 2960 3.3.2 Initiation (INIT) (1)
190 * 190 *
@@ -249,9 +249,9 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
249 sctp_addto_chunk(retval, sizeof(ecap_param), &ecap_param); 249 sctp_addto_chunk(retval, sizeof(ecap_param), &ecap_param);
250 if (sctp_prsctp_enable) 250 if (sctp_prsctp_enable)
251 sctp_addto_chunk(retval, sizeof(prsctp_param), &prsctp_param); 251 sctp_addto_chunk(retval, sizeof(prsctp_param), &prsctp_param);
252 aiparam.param_hdr.type = SCTP_PARAM_ADAPTION_LAYER_IND; 252 aiparam.param_hdr.type = SCTP_PARAM_ADAPTATION_LAYER_IND;
253 aiparam.param_hdr.length = htons(sizeof(aiparam)); 253 aiparam.param_hdr.length = htons(sizeof(aiparam));
254 aiparam.adaption_ind = htonl(sp->adaption_ind); 254 aiparam.adaptation_ind = htonl(sp->adaptation_ind);
255 sctp_addto_chunk(retval, sizeof(aiparam), &aiparam); 255 sctp_addto_chunk(retval, sizeof(aiparam), &aiparam);
256nodata: 256nodata:
257 kfree(addrs.v); 257 kfree(addrs.v);
@@ -269,7 +269,7 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
269 sctp_cookie_param_t *cookie; 269 sctp_cookie_param_t *cookie;
270 int cookie_len; 270 int cookie_len;
271 size_t chunksize; 271 size_t chunksize;
272 sctp_adaption_ind_param_t aiparam; 272 sctp_adaptation_ind_param_t aiparam;
273 273
274 retval = NULL; 274 retval = NULL;
275 275
@@ -323,9 +323,9 @@ struct sctp_chunk *sctp_make_init_ack(const struct sctp_association *asoc,
323 if (asoc->peer.prsctp_capable) 323 if (asoc->peer.prsctp_capable)
324 sctp_addto_chunk(retval, sizeof(prsctp_param), &prsctp_param); 324 sctp_addto_chunk(retval, sizeof(prsctp_param), &prsctp_param);
325 325
326 aiparam.param_hdr.type = SCTP_PARAM_ADAPTION_LAYER_IND; 326 aiparam.param_hdr.type = SCTP_PARAM_ADAPTATION_LAYER_IND;
327 aiparam.param_hdr.length = htons(sizeof(aiparam)); 327 aiparam.param_hdr.length = htons(sizeof(aiparam));
328 aiparam.adaption_ind = htonl(sctp_sk(asoc->base.sk)->adaption_ind); 328 aiparam.adaptation_ind = htonl(sctp_sk(asoc->base.sk)->adaptation_ind);
329 sctp_addto_chunk(retval, sizeof(aiparam), &aiparam); 329 sctp_addto_chunk(retval, sizeof(aiparam), &aiparam);
330 330
331 /* We need to remove the const qualifier at this point. */ 331 /* We need to remove the const qualifier at this point. */
@@ -775,7 +775,7 @@ struct sctp_chunk *sctp_make_abort_no_data(
775 const struct sctp_chunk *chunk, __u32 tsn) 775 const struct sctp_chunk *chunk, __u32 tsn)
776{ 776{
777 struct sctp_chunk *retval; 777 struct sctp_chunk *retval;
778 __u32 payload; 778 __be32 payload;
779 779
780 retval = sctp_make_abort(asoc, chunk, sizeof(sctp_errhdr_t) 780 retval = sctp_make_abort(asoc, chunk, sizeof(sctp_errhdr_t)
781 + sizeof(tsn)); 781 + sizeof(tsn));
@@ -951,7 +951,7 @@ nodata:
951/* Create an Operation Error chunk. */ 951/* Create an Operation Error chunk. */
952struct sctp_chunk *sctp_make_op_error(const struct sctp_association *asoc, 952struct sctp_chunk *sctp_make_op_error(const struct sctp_association *asoc,
953 const struct sctp_chunk *chunk, 953 const struct sctp_chunk *chunk,
954 __u16 cause_code, const void *payload, 954 __be16 cause_code, const void *payload,
955 size_t paylen) 955 size_t paylen)
956{ 956{
957 struct sctp_chunk *retval; 957 struct sctp_chunk *retval;
@@ -979,7 +979,7 @@ struct sctp_chunk *sctp_chunkify(struct sk_buff *skb,
979{ 979{
980 struct sctp_chunk *retval; 980 struct sctp_chunk *retval;
981 981
982 retval = kmem_cache_alloc(sctp_chunk_cachep, SLAB_ATOMIC); 982 retval = kmem_cache_alloc(sctp_chunk_cachep, GFP_ATOMIC);
983 983
984 if (!retval) 984 if (!retval)
985 goto nodata; 985 goto nodata;
@@ -1190,15 +1190,14 @@ void sctp_chunk_assign_ssn(struct sctp_chunk *chunk)
1190 if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) { 1190 if (chunk->chunk_hdr->flags & SCTP_DATA_UNORDERED) {
1191 ssn = 0; 1191 ssn = 0;
1192 } else { 1192 } else {
1193 sid = htons(chunk->subh.data_hdr->stream); 1193 sid = ntohs(chunk->subh.data_hdr->stream);
1194 if (chunk->chunk_hdr->flags & SCTP_DATA_LAST_FRAG) 1194 if (chunk->chunk_hdr->flags & SCTP_DATA_LAST_FRAG)
1195 ssn = sctp_ssn_next(&chunk->asoc->ssnmap->out, sid); 1195 ssn = sctp_ssn_next(&chunk->asoc->ssnmap->out, sid);
1196 else 1196 else
1197 ssn = sctp_ssn_peek(&chunk->asoc->ssnmap->out, sid); 1197 ssn = sctp_ssn_peek(&chunk->asoc->ssnmap->out, sid);
1198 ssn = htons(ssn);
1199 } 1198 }
1200 1199
1201 chunk->subh.data_hdr->ssn = ssn; 1200 chunk->subh.data_hdr->ssn = htons(ssn);
1202 chunk->has_ssn = 1; 1201 chunk->has_ssn = 1;
1203} 1202}
1204 1203
@@ -1280,15 +1279,13 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
1280 - (bodysize % SCTP_COOKIE_MULTIPLE); 1279 - (bodysize % SCTP_COOKIE_MULTIPLE);
1281 *cookie_len = headersize + bodysize; 1280 *cookie_len = headersize + bodysize;
1282 1281
1283 retval = kmalloc(*cookie_len, GFP_ATOMIC);
1284
1285 if (!retval)
1286 goto nodata;
1287
1288 /* Clear this memory since we are sending this data structure 1282 /* Clear this memory since we are sending this data structure
1289 * out on the network. 1283 * out on the network.
1290 */ 1284 */
1291 memset(retval, 0x00, *cookie_len); 1285 retval = kzalloc(*cookie_len, GFP_ATOMIC);
1286 if (!retval)
1287 goto nodata;
1288
1292 cookie = (struct sctp_signed_cookie *) retval->body; 1289 cookie = (struct sctp_signed_cookie *) retval->body;
1293 1290
1294 /* Set up the parameter header. */ 1291 /* Set up the parameter header. */
@@ -1303,8 +1300,8 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
1303 /* Remember PR-SCTP capability. */ 1300 /* Remember PR-SCTP capability. */
1304 cookie->c.prsctp_capable = asoc->peer.prsctp_capable; 1301 cookie->c.prsctp_capable = asoc->peer.prsctp_capable;
1305 1302
1306 /* Save adaption indication in the cookie. */ 1303 /* Save adaptation indication in the cookie. */
1307 cookie->c.adaption_ind = asoc->peer.adaption_ind; 1304 cookie->c.adaptation_ind = asoc->peer.adaptation_ind;
1308 1305
1309 /* Set an expiration time for the cookie. */ 1306 /* Set an expiration time for the cookie. */
1310 do_gettimeofday(&cookie->c.expiration); 1307 do_gettimeofday(&cookie->c.expiration);
@@ -1438,7 +1435,7 @@ no_hmac:
1438 goto fail; 1435 goto fail;
1439 } 1436 }
1440 1437
1441 if (ntohs(chunk->sctp_hdr->source) != bear_cookie->peer_addr.v4.sin_port || 1438 if (chunk->sctp_hdr->source != bear_cookie->peer_addr.v4.sin_port ||
1442 ntohs(chunk->sctp_hdr->dest) != bear_cookie->my_port) { 1439 ntohs(chunk->sctp_hdr->dest) != bear_cookie->my_port) {
1443 *error = -SCTP_IERROR_BAD_PORTS; 1440 *error = -SCTP_IERROR_BAD_PORTS;
1444 goto fail; 1441 goto fail;
@@ -1473,10 +1470,10 @@ no_hmac:
1473 suseconds_t usecs = (tv.tv_sec - 1470 suseconds_t usecs = (tv.tv_sec -
1474 bear_cookie->expiration.tv_sec) * 1000000L + 1471 bear_cookie->expiration.tv_sec) * 1000000L +
1475 tv.tv_usec - bear_cookie->expiration.tv_usec; 1472 tv.tv_usec - bear_cookie->expiration.tv_usec;
1473 __be32 n = htonl(usecs);
1476 1474
1477 usecs = htonl(usecs);
1478 sctp_init_cause(*errp, SCTP_ERROR_STALE_COOKIE, 1475 sctp_init_cause(*errp, SCTP_ERROR_STALE_COOKIE,
1479 &usecs, sizeof(usecs)); 1476 &n, sizeof(n));
1480 *error = -SCTP_IERROR_STALE_COOKIE; 1477 *error = -SCTP_IERROR_STALE_COOKIE;
1481 } else 1478 } else
1482 *error = -SCTP_IERROR_NOMEM; 1479 *error = -SCTP_IERROR_NOMEM;
@@ -1515,7 +1512,7 @@ no_hmac:
1515 retval->addip_serial = retval->c.initial_tsn; 1512 retval->addip_serial = retval->c.initial_tsn;
1516 retval->adv_peer_ack_point = retval->ctsn_ack_point; 1513 retval->adv_peer_ack_point = retval->ctsn_ack_point;
1517 retval->peer.prsctp_capable = retval->c.prsctp_capable; 1514 retval->peer.prsctp_capable = retval->c.prsctp_capable;
1518 retval->peer.adaption_ind = retval->c.adaption_ind; 1515 retval->peer.adaptation_ind = retval->c.adaptation_ind;
1519 1516
1520 /* The INIT stuff will be done by the side effects. */ 1517 /* The INIT stuff will be done by the side effects. */
1521 return retval; 1518 return retval;
@@ -1539,8 +1536,8 @@ malformed:
1539 ********************************************************************/ 1536 ********************************************************************/
1540 1537
1541struct __sctp_missing { 1538struct __sctp_missing {
1542 __u32 num_missing; 1539 __be32 num_missing;
1543 __u16 type; 1540 __be16 type;
1544} __attribute__((packed)); 1541} __attribute__((packed));
1545 1542
1546/* 1543/*
@@ -1746,7 +1743,7 @@ static int sctp_verify_param(const struct sctp_association *asoc,
1746 case SCTP_PARAM_HEARTBEAT_INFO: 1743 case SCTP_PARAM_HEARTBEAT_INFO:
1747 case SCTP_PARAM_UNRECOGNIZED_PARAMETERS: 1744 case SCTP_PARAM_UNRECOGNIZED_PARAMETERS:
1748 case SCTP_PARAM_ECN_CAPABLE: 1745 case SCTP_PARAM_ECN_CAPABLE:
1749 case SCTP_PARAM_ADAPTION_LAYER_IND: 1746 case SCTP_PARAM_ADAPTATION_LAYER_IND:
1750 break; 1747 break;
1751 1748
1752 case SCTP_PARAM_HOST_NAME_ADDRESS: 1749 case SCTP_PARAM_HOST_NAME_ADDRESS:
@@ -1852,9 +1849,10 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
1852 * added as the primary transport. The source address seems to 1849 * added as the primary transport. The source address seems to
1853 * be a a better choice than any of the embedded addresses. 1850 * be a a better choice than any of the embedded addresses.
1854 */ 1851 */
1855 if (peer_addr) 1852 if (peer_addr) {
1856 if(!sctp_assoc_add_peer(asoc, peer_addr, gfp, SCTP_ACTIVE)) 1853 if(!sctp_assoc_add_peer(asoc, peer_addr, gfp, SCTP_ACTIVE))
1857 goto nomem; 1854 goto nomem;
1855 }
1858 1856
1859 /* Process the initialization parameters. */ 1857 /* Process the initialization parameters. */
1860 1858
@@ -1910,10 +1908,9 @@ int sctp_process_init(struct sctp_association *asoc, sctp_cid_t cid,
1910 /* Copy cookie in case we need to resend COOKIE-ECHO. */ 1908 /* Copy cookie in case we need to resend COOKIE-ECHO. */
1911 cookie = asoc->peer.cookie; 1909 cookie = asoc->peer.cookie;
1912 if (cookie) { 1910 if (cookie) {
1913 asoc->peer.cookie = kmalloc(asoc->peer.cookie_len, gfp); 1911 asoc->peer.cookie = kmemdup(cookie, asoc->peer.cookie_len, gfp);
1914 if (!asoc->peer.cookie) 1912 if (!asoc->peer.cookie)
1915 goto clean_up; 1913 goto clean_up;
1916 memcpy(asoc->peer.cookie, cookie, asoc->peer.cookie_len);
1917 } 1914 }
1918 1915
1919 /* RFC 2960 7.2.1 The initial value of ssthresh MAY be arbitrarily 1916 /* RFC 2960 7.2.1 The initial value of ssthresh MAY be arbitrarily
@@ -2027,7 +2024,7 @@ static int sctp_process_param(struct sctp_association *asoc,
2027 /* Fall through. */ 2024 /* Fall through. */
2028 case SCTP_PARAM_IPV4_ADDRESS: 2025 case SCTP_PARAM_IPV4_ADDRESS:
2029 af = sctp_get_af_specific(param_type2af(param.p->type)); 2026 af = sctp_get_af_specific(param_type2af(param.p->type));
2030 af->from_addr_param(&addr, param.addr, asoc->peer.port, 0); 2027 af->from_addr_param(&addr, param.addr, htons(asoc->peer.port), 0);
2031 scope = sctp_scope(peer_addr); 2028 scope = sctp_scope(peer_addr);
2032 if (sctp_in_scope(&addr, scope)) 2029 if (sctp_in_scope(&addr, scope))
2033 if (!sctp_assoc_add_peer(asoc, &addr, gfp, SCTP_UNCONFIRMED)) 2030 if (!sctp_assoc_add_peer(asoc, &addr, gfp, SCTP_UNCONFIRMED))
@@ -2101,8 +2098,8 @@ static int sctp_process_param(struct sctp_association *asoc,
2101 asoc->peer.ecn_capable = 1; 2098 asoc->peer.ecn_capable = 1;
2102 break; 2099 break;
2103 2100
2104 case SCTP_PARAM_ADAPTION_LAYER_IND: 2101 case SCTP_PARAM_ADAPTATION_LAYER_IND:
2105 asoc->peer.adaption_ind = param.aind->adaption_ind; 2102 asoc->peer.adaptation_ind = param.aind->adaptation_ind;
2106 break; 2103 break;
2107 2104
2108 case SCTP_PARAM_FWD_TSN_SUPPORT: 2105 case SCTP_PARAM_FWD_TSN_SUPPORT:
@@ -2230,7 +2227,7 @@ struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *asoc,
2230 union sctp_addr *laddr, 2227 union sctp_addr *laddr,
2231 struct sockaddr *addrs, 2228 struct sockaddr *addrs,
2232 int addrcnt, 2229 int addrcnt,
2233 __u16 flags) 2230 __be16 flags)
2234{ 2231{
2235 sctp_addip_param_t param; 2232 sctp_addip_param_t param;
2236 struct sctp_chunk *retval; 2233 struct sctp_chunk *retval;
@@ -2363,14 +2360,14 @@ static struct sctp_chunk *sctp_make_asconf_ack(const struct sctp_association *as
2363} 2360}
2364 2361
2365/* Add response parameters to an ASCONF_ACK chunk. */ 2362/* Add response parameters to an ASCONF_ACK chunk. */
2366static void sctp_add_asconf_response(struct sctp_chunk *chunk, __u32 crr_id, 2363static void sctp_add_asconf_response(struct sctp_chunk *chunk, __be32 crr_id,
2367 __u16 err_code, sctp_addip_param_t *asconf_param) 2364 __be16 err_code, sctp_addip_param_t *asconf_param)
2368{ 2365{
2369 sctp_addip_param_t ack_param; 2366 sctp_addip_param_t ack_param;
2370 sctp_errhdr_t err_param; 2367 sctp_errhdr_t err_param;
2371 int asconf_param_len = 0; 2368 int asconf_param_len = 0;
2372 int err_param_len = 0; 2369 int err_param_len = 0;
2373 __u16 response_type; 2370 __be16 response_type;
2374 2371
2375 if (SCTP_ERROR_NO_ERROR == err_code) { 2372 if (SCTP_ERROR_NO_ERROR == err_code) {
2376 response_type = SCTP_PARAM_SUCCESS_REPORT; 2373 response_type = SCTP_PARAM_SUCCESS_REPORT;
@@ -2404,7 +2401,7 @@ static void sctp_add_asconf_response(struct sctp_chunk *chunk, __u32 crr_id,
2404} 2401}
2405 2402
2406/* Process a asconf parameter. */ 2403/* Process a asconf parameter. */
2407static __u16 sctp_process_asconf_param(struct sctp_association *asoc, 2404static __be16 sctp_process_asconf_param(struct sctp_association *asoc,
2408 struct sctp_chunk *asconf, 2405 struct sctp_chunk *asconf,
2409 sctp_addip_param_t *asconf_param) 2406 sctp_addip_param_t *asconf_param)
2410{ 2407{
@@ -2413,7 +2410,7 @@ static __u16 sctp_process_asconf_param(struct sctp_association *asoc,
2413 union sctp_addr addr; 2410 union sctp_addr addr;
2414 struct list_head *pos; 2411 struct list_head *pos;
2415 union sctp_addr_param *addr_param; 2412 union sctp_addr_param *addr_param;
2416 2413
2417 addr_param = (union sctp_addr_param *) 2414 addr_param = (union sctp_addr_param *)
2418 ((void *)asconf_param + sizeof(sctp_addip_param_t)); 2415 ((void *)asconf_param + sizeof(sctp_addip_param_t));
2419 2416
@@ -2421,7 +2418,7 @@ static __u16 sctp_process_asconf_param(struct sctp_association *asoc,
2421 if (unlikely(!af)) 2418 if (unlikely(!af))
2422 return SCTP_ERROR_INV_PARAM; 2419 return SCTP_ERROR_INV_PARAM;
2423 2420
2424 af->from_addr_param(&addr, addr_param, asoc->peer.port, 0); 2421 af->from_addr_param(&addr, addr_param, htons(asoc->peer.port), 0);
2425 switch (asconf_param->param_hdr.type) { 2422 switch (asconf_param->param_hdr.type) {
2426 case SCTP_PARAM_ADD_IP: 2423 case SCTP_PARAM_ADD_IP:
2427 /* ADDIP 4.3 D9) If an endpoint receives an ADD IP address 2424 /* ADDIP 4.3 D9) If an endpoint receives an ADD IP address
@@ -2487,7 +2484,7 @@ struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc,
2487 sctp_addip_param_t *asconf_param; 2484 sctp_addip_param_t *asconf_param;
2488 struct sctp_chunk *asconf_ack; 2485 struct sctp_chunk *asconf_ack;
2489 2486
2490 __u16 err_code; 2487 __be16 err_code;
2491 int length = 0; 2488 int length = 0;
2492 int chunk_len = asconf->skb->len; 2489 int chunk_len = asconf->skb->len;
2493 __u32 serial; 2490 __u32 serial;
@@ -2586,7 +2583,7 @@ static int sctp_asconf_param_success(struct sctp_association *asoc,
2586 2583
2587 /* We have checked the packet before, so we do not check again. */ 2584 /* We have checked the packet before, so we do not check again. */
2588 af = sctp_get_af_specific(param_type2af(addr_param->v4.param_hdr.type)); 2585 af = sctp_get_af_specific(param_type2af(addr_param->v4.param_hdr.type));
2589 af->from_addr_param(&addr, addr_param, bp->port, 0); 2586 af->from_addr_param(&addr, addr_param, htons(bp->port), 0);
2590 2587
2591 switch (asconf_param->param_hdr.type) { 2588 switch (asconf_param->param_hdr.type) {
2592 case SCTP_PARAM_ADD_IP: 2589 case SCTP_PARAM_ADD_IP:
@@ -2630,7 +2627,7 @@ static int sctp_asconf_param_success(struct sctp_association *asoc,
2630 * All TLVs after the failed response are considered unsuccessful unless a 2627 * All TLVs after the failed response are considered unsuccessful unless a
2631 * specific success indication is present for the parameter. 2628 * specific success indication is present for the parameter.
2632 */ 2629 */
2633static __u16 sctp_get_asconf_response(struct sctp_chunk *asconf_ack, 2630static __be16 sctp_get_asconf_response(struct sctp_chunk *asconf_ack,
2634 sctp_addip_param_t *asconf_param, 2631 sctp_addip_param_t *asconf_param,
2635 int no_err) 2632 int no_err)
2636{ 2633{
@@ -2638,7 +2635,7 @@ static __u16 sctp_get_asconf_response(struct sctp_chunk *asconf_ack,
2638 sctp_errhdr_t *err_param; 2635 sctp_errhdr_t *err_param;
2639 int length; 2636 int length;
2640 int asconf_ack_len = asconf_ack->skb->len; 2637 int asconf_ack_len = asconf_ack->skb->len;
2641 __u16 err_code; 2638 __be16 err_code;
2642 2639
2643 if (no_err) 2640 if (no_err)
2644 err_code = SCTP_ERROR_NO_ERROR; 2641 err_code = SCTP_ERROR_NO_ERROR;
@@ -2694,7 +2691,7 @@ int sctp_process_asconf_ack(struct sctp_association *asoc,
2694 int all_param_pass = 0; 2691 int all_param_pass = 0;
2695 int no_err = 1; 2692 int no_err = 1;
2696 int retval = 0; 2693 int retval = 0;
2697 __u16 err_code = SCTP_ERROR_NO_ERROR; 2694 __be16 err_code = SCTP_ERROR_NO_ERROR;
2698 2695
2699 /* Skip the chunkhdr and addiphdr from the last asconf sent and store 2696 /* Skip the chunkhdr and addiphdr from the last asconf sent and store
2700 * a pointer to address parameter. 2697 * a pointer to address parameter.
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 9c10bdec1a..7bbc6156e4 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -442,7 +442,7 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc,
442 " transport IP: port:%d failed.\n", 442 " transport IP: port:%d failed.\n",
443 asoc, 443 asoc,
444 (&transport->ipaddr), 444 (&transport->ipaddr),
445 transport->ipaddr.v4.sin_port); 445 ntohs(transport->ipaddr.v4.sin_port));
446 sctp_assoc_control_transport(asoc, transport, 446 sctp_assoc_control_transport(asoc, transport,
447 SCTP_TRANSPORT_DOWN, 447 SCTP_TRANSPORT_DOWN,
448 SCTP_FAILED_THRESHOLD); 448 SCTP_FAILED_THRESHOLD);
@@ -1360,12 +1360,12 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1360 break; 1360 break;
1361 1361
1362 case SCTP_CMD_INIT_FAILED: 1362 case SCTP_CMD_INIT_FAILED:
1363 sctp_cmd_init_failed(commands, asoc, cmd->obj.u32); 1363 sctp_cmd_init_failed(commands, asoc, cmd->obj.err);
1364 break; 1364 break;
1365 1365
1366 case SCTP_CMD_ASSOC_FAILED: 1366 case SCTP_CMD_ASSOC_FAILED:
1367 sctp_cmd_assoc_failed(commands, asoc, event_type, 1367 sctp_cmd_assoc_failed(commands, asoc, event_type,
1368 subtype, chunk, cmd->obj.u32); 1368 subtype, chunk, cmd->obj.err);
1369 break; 1369 break;
1370 1370
1371 case SCTP_CMD_INIT_COUNTER_INC: 1371 case SCTP_CMD_INIT_COUNTER_INC:
@@ -1420,7 +1420,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
1420 1420
1421 case SCTP_CMD_PROCESS_CTSN: 1421 case SCTP_CMD_PROCESS_CTSN:
1422 /* Dummy up a SACK for processing. */ 1422 /* Dummy up a SACK for processing. */
1423 sackh.cum_tsn_ack = cmd->obj.u32; 1423 sackh.cum_tsn_ack = cmd->obj.be32;
1424 sackh.a_rwnd = 0; 1424 sackh.a_rwnd = 0;
1425 sackh.num_gap_ack_blocks = 0; 1425 sackh.num_gap_ack_blocks = 0;
1426 sackh.num_dup_tsns = 0; 1426 sackh.num_dup_tsns = 0;
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 1c42fe983a..aa51d190bf 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -93,7 +93,7 @@ static sctp_disposition_t sctp_sf_shut_8_4_5(const struct sctp_endpoint *ep,
93static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk); 93static struct sctp_sackhdr *sctp_sm_pull_sack(struct sctp_chunk *chunk);
94 94
95static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, 95static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
96 __u16 error, int sk_err, 96 __be16 error, int sk_err,
97 const struct sctp_association *asoc, 97 const struct sctp_association *asoc,
98 struct sctp_transport *transport); 98 struct sctp_transport *transport);
99 99
@@ -443,7 +443,7 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const struct sctp_endpoint *ep,
443 __u32 init_tag; 443 __u32 init_tag;
444 struct sctp_chunk *err_chunk; 444 struct sctp_chunk *err_chunk;
445 struct sctp_packet *packet; 445 struct sctp_packet *packet;
446 __u16 error; 446 sctp_error_t error;
447 447
448 if (!sctp_vtag_verify(chunk, asoc)) 448 if (!sctp_vtag_verify(chunk, asoc))
449 return sctp_sf_pdiscard(ep, asoc, type, arg, commands); 449 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
@@ -688,12 +688,12 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(const struct sctp_endpoint *ep,
688 goto nomem_ev; 688 goto nomem_ev;
689 689
690 /* Sockets API Draft Section 5.3.1.6 690 /* Sockets API Draft Section 5.3.1.6
691 * When a peer sends a Adaption Layer Indication parameter , SCTP 691 * When a peer sends a Adaptation Layer Indication parameter , SCTP
692 * delivers this notification to inform the application that of the 692 * delivers this notification to inform the application that of the
693 * peers requested adaption layer. 693 * peers requested adaptation layer.
694 */ 694 */
695 if (new_asoc->peer.adaption_ind) { 695 if (new_asoc->peer.adaptation_ind) {
696 ai_ev = sctp_ulpevent_make_adaption_indication(new_asoc, 696 ai_ev = sctp_ulpevent_make_adaptation_indication(new_asoc,
697 GFP_ATOMIC); 697 GFP_ATOMIC);
698 if (!ai_ev) 698 if (!ai_ev)
699 goto nomem_aiev; 699 goto nomem_aiev;
@@ -820,12 +820,12 @@ sctp_disposition_t sctp_sf_do_5_1E_ca(const struct sctp_endpoint *ep,
820 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev)); 820 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
821 821
822 /* Sockets API Draft Section 5.3.1.6 822 /* Sockets API Draft Section 5.3.1.6
823 * When a peer sends a Adaption Layer Indication parameter , SCTP 823 * When a peer sends a Adaptation Layer Indication parameter , SCTP
824 * delivers this notification to inform the application that of the 824 * delivers this notification to inform the application that of the
825 * peers requested adaption layer. 825 * peers requested adaptation layer.
826 */ 826 */
827 if (asoc->peer.adaption_ind) { 827 if (asoc->peer.adaptation_ind) {
828 ev = sctp_ulpevent_make_adaption_indication(asoc, GFP_ATOMIC); 828 ev = sctp_ulpevent_make_adaptation_indication(asoc, GFP_ATOMIC);
829 if (!ev) 829 if (!ev)
830 goto nomem; 830 goto nomem;
831 831
@@ -886,7 +886,7 @@ sctp_disposition_t sctp_sf_sendbeat_8_3(const struct sctp_endpoint *ep,
886 SCTP_ERROR(ETIMEDOUT)); 886 SCTP_ERROR(ETIMEDOUT));
887 /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */ 887 /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
888 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, 888 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
889 SCTP_U32(SCTP_ERROR_NO_ERROR)); 889 SCTP_PERR(SCTP_ERROR_NO_ERROR));
890 SCTP_INC_STATS(SCTP_MIB_ABORTEDS); 890 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
891 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); 891 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
892 return SCTP_DISPOSITION_DELETE_TCB; 892 return SCTP_DISPOSITION_DELETE_TCB;
@@ -1698,12 +1698,12 @@ static sctp_disposition_t sctp_sf_do_dupcook_b(const struct sctp_endpoint *ep,
1698 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev)); 1698 sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));
1699 1699
1700 /* Sockets API Draft Section 5.3.1.6 1700 /* Sockets API Draft Section 5.3.1.6
1701 * When a peer sends a Adaption Layer Indication parameter , SCTP 1701 * When a peer sends a Adaptation Layer Indication parameter , SCTP
1702 * delivers this notification to inform the application that of the 1702 * delivers this notification to inform the application that of the
1703 * peers requested adaption layer. 1703 * peers requested adaptation layer.
1704 */ 1704 */
1705 if (asoc->peer.adaption_ind) { 1705 if (asoc->peer.adaptation_ind) {
1706 ev = sctp_ulpevent_make_adaption_indication(asoc, GFP_ATOMIC); 1706 ev = sctp_ulpevent_make_adaptation_indication(asoc, GFP_ATOMIC);
1707 if (!ev) 1707 if (!ev)
1708 goto nomem_ev; 1708 goto nomem_ev;
1709 1709
@@ -1791,12 +1791,12 @@ static sctp_disposition_t sctp_sf_do_dupcook_d(const struct sctp_endpoint *ep,
1791 goto nomem; 1791 goto nomem;
1792 1792
1793 /* Sockets API Draft Section 5.3.1.6 1793 /* Sockets API Draft Section 5.3.1.6
1794 * When a peer sends a Adaption Layer Indication parameter, 1794 * When a peer sends a Adaptation Layer Indication parameter,
1795 * SCTP delivers this notification to inform the application 1795 * SCTP delivers this notification to inform the application
1796 * that of the peers requested adaption layer. 1796 * that of the peers requested adaptation layer.
1797 */ 1797 */
1798 if (asoc->peer.adaption_ind) { 1798 if (asoc->peer.adaptation_ind) {
1799 ai_ev = sctp_ulpevent_make_adaption_indication(asoc, 1799 ai_ev = sctp_ulpevent_make_adaptation_indication(asoc,
1800 GFP_ATOMIC); 1800 GFP_ATOMIC);
1801 if (!ai_ev) 1801 if (!ai_ev)
1802 goto nomem; 1802 goto nomem;
@@ -2138,7 +2138,7 @@ static sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
2138 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, 2138 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
2139 SCTP_ERROR(ETIMEDOUT)); 2139 SCTP_ERROR(ETIMEDOUT));
2140 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, 2140 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
2141 SCTP_U32(SCTP_ERROR_STALE_COOKIE)); 2141 SCTP_PERR(SCTP_ERROR_STALE_COOKIE));
2142 return SCTP_DISPOSITION_DELETE_TCB; 2142 return SCTP_DISPOSITION_DELETE_TCB;
2143 } 2143 }
2144 2144
@@ -2158,7 +2158,7 @@ static sctp_disposition_t sctp_sf_do_5_2_6_stale(const struct sctp_endpoint *ep,
2158 * to give ample time to retransmit the new cookie and thus 2158 * to give ample time to retransmit the new cookie and thus
2159 * yield a higher probability of success on the reattempt. 2159 * yield a higher probability of success on the reattempt.
2160 */ 2160 */
2161 stale = ntohl(*(suseconds_t *)((u8 *)err + sizeof(sctp_errhdr_t))); 2161 stale = ntohl(*(__be32 *)((u8 *)err + sizeof(sctp_errhdr_t)));
2162 stale = (stale * 2) / 1000; 2162 stale = (stale * 2) / 1000;
2163 2163
2164 bht.param_hdr.type = SCTP_PARAM_COOKIE_PRESERVATIVE; 2164 bht.param_hdr.type = SCTP_PARAM_COOKIE_PRESERVATIVE;
@@ -2250,7 +2250,7 @@ sctp_disposition_t sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep,
2250{ 2250{
2251 struct sctp_chunk *chunk = arg; 2251 struct sctp_chunk *chunk = arg;
2252 unsigned len; 2252 unsigned len;
2253 __u16 error = SCTP_ERROR_NO_ERROR; 2253 __be16 error = SCTP_ERROR_NO_ERROR;
2254 2254
2255 if (!sctp_vtag_verify_either(chunk, asoc)) 2255 if (!sctp_vtag_verify_either(chunk, asoc))
2256 return sctp_sf_pdiscard(ep, asoc, type, arg, commands); 2256 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
@@ -2275,7 +2275,7 @@ sctp_disposition_t sctp_sf_do_9_1_abort(const struct sctp_endpoint *ep,
2275 2275
2276 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNRESET)); 2276 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(ECONNRESET));
2277 /* ASSOC_FAILED will DELETE_TCB. */ 2277 /* ASSOC_FAILED will DELETE_TCB. */
2278 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_U32(error)); 2278 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, SCTP_PERR(error));
2279 SCTP_INC_STATS(SCTP_MIB_ABORTEDS); 2279 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
2280 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); 2280 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
2281 2281
@@ -2295,7 +2295,7 @@ sctp_disposition_t sctp_sf_cookie_wait_abort(const struct sctp_endpoint *ep,
2295{ 2295{
2296 struct sctp_chunk *chunk = arg; 2296 struct sctp_chunk *chunk = arg;
2297 unsigned len; 2297 unsigned len;
2298 __u16 error = SCTP_ERROR_NO_ERROR; 2298 __be16 error = SCTP_ERROR_NO_ERROR;
2299 2299
2300 if (!sctp_vtag_verify_either(chunk, asoc)) 2300 if (!sctp_vtag_verify_either(chunk, asoc))
2301 return sctp_sf_pdiscard(ep, asoc, type, arg, commands); 2301 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
@@ -2357,7 +2357,7 @@ sctp_disposition_t sctp_sf_cookie_echoed_abort(const struct sctp_endpoint *ep,
2357 * This is common code called by several sctp_sf_*_abort() functions above. 2357 * This is common code called by several sctp_sf_*_abort() functions above.
2358 */ 2358 */
2359static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands, 2359static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
2360 __u16 error, int sk_err, 2360 __be16 error, int sk_err,
2361 const struct sctp_association *asoc, 2361 const struct sctp_association *asoc,
2362 struct sctp_transport *transport) 2362 struct sctp_transport *transport)
2363{ 2363{
@@ -2370,7 +2370,7 @@ static sctp_disposition_t sctp_stop_t1_and_abort(sctp_cmd_seq_t *commands,
2370 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(sk_err)); 2370 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, SCTP_ERROR(sk_err));
2371 /* CMD_INIT_FAILED will DELETE_TCB. */ 2371 /* CMD_INIT_FAILED will DELETE_TCB. */
2372 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, 2372 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
2373 SCTP_U32(error)); 2373 SCTP_PERR(error));
2374 return SCTP_DISPOSITION_ABORT; 2374 return SCTP_DISPOSITION_ABORT;
2375} 2375}
2376 2376
@@ -2466,7 +2466,7 @@ sctp_disposition_t sctp_sf_do_9_2_shutdown(const struct sctp_endpoint *ep,
2466 * received by the SHUTDOWN sender. 2466 * received by the SHUTDOWN sender.
2467 */ 2467 */
2468 sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_CTSN, 2468 sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_CTSN,
2469 SCTP_U32(chunk->subh.shutdown_hdr->cum_tsn_ack)); 2469 SCTP_BE32(chunk->subh.shutdown_hdr->cum_tsn_ack));
2470 2470
2471out: 2471out:
2472 return disposition; 2472 return disposition;
@@ -2545,6 +2545,7 @@ sctp_disposition_t sctp_sf_do_ecn_cwr(const struct sctp_endpoint *ep,
2545{ 2545{
2546 sctp_cwrhdr_t *cwr; 2546 sctp_cwrhdr_t *cwr;
2547 struct sctp_chunk *chunk = arg; 2547 struct sctp_chunk *chunk = arg;
2548 u32 lowest_tsn;
2548 2549
2549 if (!sctp_vtag_verify(chunk, asoc)) 2550 if (!sctp_vtag_verify(chunk, asoc))
2550 return sctp_sf_pdiscard(ep, asoc, type, arg, commands); 2551 return sctp_sf_pdiscard(ep, asoc, type, arg, commands);
@@ -2556,14 +2557,14 @@ sctp_disposition_t sctp_sf_do_ecn_cwr(const struct sctp_endpoint *ep,
2556 cwr = (sctp_cwrhdr_t *) chunk->skb->data; 2557 cwr = (sctp_cwrhdr_t *) chunk->skb->data;
2557 skb_pull(chunk->skb, sizeof(sctp_cwrhdr_t)); 2558 skb_pull(chunk->skb, sizeof(sctp_cwrhdr_t));
2558 2559
2559 cwr->lowest_tsn = ntohl(cwr->lowest_tsn); 2560 lowest_tsn = ntohl(cwr->lowest_tsn);
2560 2561
2561 /* Does this CWR ack the last sent congestion notification? */ 2562 /* Does this CWR ack the last sent congestion notification? */
2562 if (TSN_lte(asoc->last_ecne_tsn, cwr->lowest_tsn)) { 2563 if (TSN_lte(asoc->last_ecne_tsn, lowest_tsn)) {
2563 /* Stop sending ECNE. */ 2564 /* Stop sending ECNE. */
2564 sctp_add_cmd_sf(commands, 2565 sctp_add_cmd_sf(commands,
2565 SCTP_CMD_ECN_CWR, 2566 SCTP_CMD_ECN_CWR,
2566 SCTP_U32(cwr->lowest_tsn)); 2567 SCTP_U32(lowest_tsn));
2567 } 2568 }
2568 return SCTP_DISPOSITION_CONSUME; 2569 return SCTP_DISPOSITION_CONSUME;
2569} 2570}
@@ -3360,7 +3361,7 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
3360 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, 3361 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
3361 SCTP_ERROR(ECONNABORTED)); 3362 SCTP_ERROR(ECONNABORTED));
3362 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, 3363 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
3363 SCTP_U32(SCTP_ERROR_ASCONF_ACK)); 3364 SCTP_PERR(SCTP_ERROR_ASCONF_ACK));
3364 SCTP_INC_STATS(SCTP_MIB_ABORTEDS); 3365 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
3365 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); 3366 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
3366 return SCTP_DISPOSITION_ABORT; 3367 return SCTP_DISPOSITION_ABORT;
@@ -3388,7 +3389,7 @@ sctp_disposition_t sctp_sf_do_asconf_ack(const struct sctp_endpoint *ep,
3388 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, 3389 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
3389 SCTP_ERROR(ECONNABORTED)); 3390 SCTP_ERROR(ECONNABORTED));
3390 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, 3391 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
3391 SCTP_U32(SCTP_ERROR_ASCONF_ACK)); 3392 SCTP_PERR(SCTP_ERROR_ASCONF_ACK));
3392 SCTP_INC_STATS(SCTP_MIB_ABORTEDS); 3393 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
3393 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); 3394 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
3394 return SCTP_DISPOSITION_ABORT; 3395 return SCTP_DISPOSITION_ABORT;
@@ -3743,12 +3744,12 @@ static sctp_disposition_t sctp_sf_violation_chunklen(
3743 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, 3744 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
3744 SCTP_ERROR(ECONNREFUSED)); 3745 SCTP_ERROR(ECONNREFUSED));
3745 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, 3746 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
3746 SCTP_U32(SCTP_ERROR_PROTO_VIOLATION)); 3747 SCTP_PERR(SCTP_ERROR_PROTO_VIOLATION));
3747 } else { 3748 } else {
3748 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, 3749 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
3749 SCTP_ERROR(ECONNABORTED)); 3750 SCTP_ERROR(ECONNABORTED));
3750 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, 3751 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
3751 SCTP_U32(SCTP_ERROR_PROTO_VIOLATION)); 3752 SCTP_PERR(SCTP_ERROR_PROTO_VIOLATION));
3752 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); 3753 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
3753 } 3754 }
3754 3755
@@ -4062,7 +4063,7 @@ sctp_disposition_t sctp_sf_do_9_1_prm_abort(
4062 SCTP_ERROR(ECONNABORTED)); 4063 SCTP_ERROR(ECONNABORTED));
4063 /* Delete the established association. */ 4064 /* Delete the established association. */
4064 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, 4065 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
4065 SCTP_U32(SCTP_ERROR_USER_ABORT)); 4066 SCTP_PERR(SCTP_ERROR_USER_ABORT));
4066 4067
4067 SCTP_INC_STATS(SCTP_MIB_ABORTEDS); 4068 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
4068 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); 4069 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
@@ -4199,7 +4200,7 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_abort(
4199 SCTP_ERROR(ECONNREFUSED)); 4200 SCTP_ERROR(ECONNREFUSED));
4200 /* Delete the established association. */ 4201 /* Delete the established association. */
4201 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, 4202 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
4202 SCTP_U32(SCTP_ERROR_USER_ABORT)); 4203 SCTP_PERR(SCTP_ERROR_USER_ABORT));
4203 4204
4204 return retval; 4205 return retval;
4205} 4206}
@@ -4571,7 +4572,7 @@ sctp_disposition_t sctp_sf_do_6_3_3_rtx(const struct sctp_endpoint *ep,
4571 SCTP_ERROR(ETIMEDOUT)); 4572 SCTP_ERROR(ETIMEDOUT));
4572 /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */ 4573 /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
4573 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, 4574 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
4574 SCTP_U32(SCTP_ERROR_NO_ERROR)); 4575 SCTP_PERR(SCTP_ERROR_NO_ERROR));
4575 SCTP_INC_STATS(SCTP_MIB_ABORTEDS); 4576 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
4576 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); 4577 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
4577 return SCTP_DISPOSITION_DELETE_TCB; 4578 return SCTP_DISPOSITION_DELETE_TCB;
@@ -4693,7 +4694,7 @@ sctp_disposition_t sctp_sf_t1_init_timer_expire(const struct sctp_endpoint *ep,
4693 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, 4694 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
4694 SCTP_ERROR(ETIMEDOUT)); 4695 SCTP_ERROR(ETIMEDOUT));
4695 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, 4696 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
4696 SCTP_U32(SCTP_ERROR_NO_ERROR)); 4697 SCTP_PERR(SCTP_ERROR_NO_ERROR));
4697 return SCTP_DISPOSITION_DELETE_TCB; 4698 return SCTP_DISPOSITION_DELETE_TCB;
4698 } 4699 }
4699 4700
@@ -4745,7 +4746,7 @@ sctp_disposition_t sctp_sf_t1_cookie_timer_expire(const struct sctp_endpoint *ep
4745 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, 4746 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
4746 SCTP_ERROR(ETIMEDOUT)); 4747 SCTP_ERROR(ETIMEDOUT));
4747 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, 4748 sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED,
4748 SCTP_U32(SCTP_ERROR_NO_ERROR)); 4749 SCTP_PERR(SCTP_ERROR_NO_ERROR));
4749 return SCTP_DISPOSITION_DELETE_TCB; 4750 return SCTP_DISPOSITION_DELETE_TCB;
4750 } 4751 }
4751 4752
@@ -4781,7 +4782,7 @@ sctp_disposition_t sctp_sf_t2_timer_expire(const struct sctp_endpoint *ep,
4781 SCTP_ERROR(ETIMEDOUT)); 4782 SCTP_ERROR(ETIMEDOUT));
4782 /* Note: CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */ 4783 /* Note: CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */
4783 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, 4784 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
4784 SCTP_U32(SCTP_ERROR_NO_ERROR)); 4785 SCTP_PERR(SCTP_ERROR_NO_ERROR));
4785 SCTP_INC_STATS(SCTP_MIB_ABORTEDS); 4786 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
4786 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); 4787 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
4787 return SCTP_DISPOSITION_DELETE_TCB; 4788 return SCTP_DISPOSITION_DELETE_TCB;
@@ -4859,7 +4860,7 @@ sctp_disposition_t sctp_sf_t4_timer_expire(
4859 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, 4860 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
4860 SCTP_ERROR(ETIMEDOUT)); 4861 SCTP_ERROR(ETIMEDOUT));
4861 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, 4862 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
4862 SCTP_U32(SCTP_ERROR_NO_ERROR)); 4863 SCTP_PERR(SCTP_ERROR_NO_ERROR));
4863 SCTP_INC_STATS(SCTP_MIB_ABORTEDS); 4864 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
4864 SCTP_INC_STATS(SCTP_MIB_CURRESTAB); 4865 SCTP_INC_STATS(SCTP_MIB_CURRESTAB);
4865 return SCTP_DISPOSITION_ABORT; 4866 return SCTP_DISPOSITION_ABORT;
@@ -4915,7 +4916,7 @@ sctp_disposition_t sctp_sf_t5_timer_expire(const struct sctp_endpoint *ep,
4915 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, 4916 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
4916 SCTP_ERROR(ETIMEDOUT)); 4917 SCTP_ERROR(ETIMEDOUT));
4917 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, 4918 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
4918 SCTP_U32(SCTP_ERROR_NO_ERROR)); 4919 SCTP_PERR(SCTP_ERROR_NO_ERROR));
4919 4920
4920 return SCTP_DISPOSITION_DELETE_TCB; 4921 return SCTP_DISPOSITION_DELETE_TCB;
4921nomem: 4922nomem:
@@ -5365,7 +5366,7 @@ static int sctp_eat_data(const struct sctp_association *asoc,
5365 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, 5366 sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR,
5366 SCTP_ERROR(ECONNABORTED)); 5367 SCTP_ERROR(ECONNABORTED));
5367 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, 5368 sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED,
5368 SCTP_U32(SCTP_ERROR_NO_DATA)); 5369 SCTP_PERR(SCTP_ERROR_NO_DATA));
5369 SCTP_INC_STATS(SCTP_MIB_ABORTEDS); 5370 SCTP_INC_STATS(SCTP_MIB_ABORTEDS);
5370 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); 5371 SCTP_DEC_STATS(SCTP_MIB_CURRESTAB);
5371 return SCTP_IERROR_NO_DATA; 5372 return SCTP_IERROR_NO_DATA;
diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c
index 8bcca56761..733dd87b3a 100644
--- a/net/sctp/sm_statetable.c
+++ b/net/sctp/sm_statetable.c
@@ -104,325 +104,322 @@ const sctp_sm_table_entry_t *sctp_sm_lookup_event(sctp_event_t event_type,
104 }; 104 };
105} 105}
106 106
107#define TYPE_SCTP_FUNC(func) {.fn = func, .name = #func}
108
107#define TYPE_SCTP_DATA { \ 109#define TYPE_SCTP_DATA { \
108 /* SCTP_STATE_EMPTY */ \ 110 /* SCTP_STATE_EMPTY */ \
109 {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \ 111 TYPE_SCTP_FUNC(sctp_sf_ootb), \
110 /* SCTP_STATE_CLOSED */ \ 112 /* SCTP_STATE_CLOSED */ \
111 {.fn = sctp_sf_tabort_8_4_8, .name = "sctp_sf_tabort_8_4_8"}, \ 113 TYPE_SCTP_FUNC(sctp_sf_tabort_8_4_8), \
112 /* SCTP_STATE_COOKIE_WAIT */ \ 114 /* SCTP_STATE_COOKIE_WAIT */ \
113 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 115 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
114 /* SCTP_STATE_COOKIE_ECHOED */ \ 116 /* SCTP_STATE_COOKIE_ECHOED */ \
115 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 117 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
116 /* SCTP_STATE_ESTABLISHED */ \ 118 /* SCTP_STATE_ESTABLISHED */ \
117 {.fn = sctp_sf_eat_data_6_2, .name = "sctp_sf_eat_data_6_2"}, \ 119 TYPE_SCTP_FUNC(sctp_sf_eat_data_6_2), \
118 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 120 /* SCTP_STATE_SHUTDOWN_PENDING */ \
119 {.fn = sctp_sf_eat_data_6_2, .name = "sctp_sf_eat_data_6_2"}, \ 121 TYPE_SCTP_FUNC(sctp_sf_eat_data_6_2), \
120 /* SCTP_STATE_SHUTDOWN_SENT */ \ 122 /* SCTP_STATE_SHUTDOWN_SENT */ \
121 {.fn = sctp_sf_eat_data_fast_4_4, .name = "sctp_sf_eat_data_fast_4_4"}, \ 123 TYPE_SCTP_FUNC(sctp_sf_eat_data_fast_4_4), \
122 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 124 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
123 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 125 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
124 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 126 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
125 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 127 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
126} /* TYPE_SCTP_DATA */ 128} /* TYPE_SCTP_DATA */
127 129
128#define TYPE_SCTP_INIT { \ 130#define TYPE_SCTP_INIT { \
129 /* SCTP_STATE_EMPTY */ \ 131 /* SCTP_STATE_EMPTY */ \
130 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ 132 TYPE_SCTP_FUNC(sctp_sf_bug), \
131 /* SCTP_STATE_CLOSED */ \ 133 /* SCTP_STATE_CLOSED */ \
132 {.fn = sctp_sf_do_5_1B_init, .name = "sctp_sf_do_5_1B_init"}, \ 134 TYPE_SCTP_FUNC(sctp_sf_do_5_1B_init), \
133 /* SCTP_STATE_COOKIE_WAIT */ \ 135 /* SCTP_STATE_COOKIE_WAIT */ \
134 {.fn = sctp_sf_do_5_2_1_siminit, .name = "sctp_sf_do_5_2_1_siminit"}, \ 136 TYPE_SCTP_FUNC(sctp_sf_do_5_2_1_siminit), \
135 /* SCTP_STATE_COOKIE_ECHOED */ \ 137 /* SCTP_STATE_COOKIE_ECHOED */ \
136 {.fn = sctp_sf_do_5_2_1_siminit, .name = "sctp_sf_do_5_2_1_siminit"}, \ 138 TYPE_SCTP_FUNC(sctp_sf_do_5_2_1_siminit), \
137 /* SCTP_STATE_ESTABLISHED */ \ 139 /* SCTP_STATE_ESTABLISHED */ \
138 {.fn = sctp_sf_do_5_2_2_dupinit, .name = "sctp_sf_do_5_2_2_dupinit"}, \ 140 TYPE_SCTP_FUNC(sctp_sf_do_5_2_2_dupinit), \
139 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 141 /* SCTP_STATE_SHUTDOWN_PENDING */ \
140 {.fn = sctp_sf_do_5_2_2_dupinit, .name = "sctp_sf_do_5_2_2_dupinit"}, \ 142 TYPE_SCTP_FUNC(sctp_sf_do_5_2_2_dupinit), \
141 /* SCTP_STATE_SHUTDOWN_SENT */ \ 143 /* SCTP_STATE_SHUTDOWN_SENT */ \
142 {.fn = sctp_sf_do_5_2_2_dupinit, .name = "sctp_sf_do_5_2_2_dupinit"}, \ 144 TYPE_SCTP_FUNC(sctp_sf_do_5_2_2_dupinit), \
143 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 145 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
144 {.fn = sctp_sf_do_5_2_2_dupinit, .name = "sctp_sf_do_5_2_2_dupinit"}, \ 146 TYPE_SCTP_FUNC(sctp_sf_do_5_2_2_dupinit), \
145 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 147 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
146 {.fn = sctp_sf_do_9_2_reshutack, .name = "sctp_sf_do_9_2_reshutack"}, \ 148 TYPE_SCTP_FUNC(sctp_sf_do_9_2_reshutack), \
147} /* TYPE_SCTP_INIT */ 149} /* TYPE_SCTP_INIT */
148 150
149#define TYPE_SCTP_INIT_ACK { \ 151#define TYPE_SCTP_INIT_ACK { \
150 /* SCTP_STATE_EMPTY */ \ 152 /* SCTP_STATE_EMPTY */ \
151 {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \ 153 TYPE_SCTP_FUNC(sctp_sf_ootb), \
152 /* SCTP_STATE_CLOSED */ \ 154 /* SCTP_STATE_CLOSED */ \
153 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 155 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
154 /* SCTP_STATE_COOKIE_WAIT */ \ 156 /* SCTP_STATE_COOKIE_WAIT */ \
155 {.fn = sctp_sf_do_5_1C_ack, .name = "sctp_sf_do_5_1C_ack"}, \ 157 TYPE_SCTP_FUNC(sctp_sf_do_5_1C_ack), \
156 /* SCTP_STATE_COOKIE_ECHOED */ \ 158 /* SCTP_STATE_COOKIE_ECHOED */ \
157 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 159 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
158 /* SCTP_STATE_ESTABLISHED */ \ 160 /* SCTP_STATE_ESTABLISHED */ \
159 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 161 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
160 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 162 /* SCTP_STATE_SHUTDOWN_PENDING */ \
161 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 163 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
162 /* SCTP_STATE_SHUTDOWN_SENT */ \ 164 /* SCTP_STATE_SHUTDOWN_SENT */ \
163 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 165 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
164 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 166 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
165 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 167 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
166 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 168 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
167 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 169 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
168} /* TYPE_SCTP_INIT_ACK */ 170} /* TYPE_SCTP_INIT_ACK */
169 171
170#define TYPE_SCTP_SACK { \ 172#define TYPE_SCTP_SACK { \
171 /* SCTP_STATE_EMPTY */ \ 173 /* SCTP_STATE_EMPTY */ \
172 {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \ 174 TYPE_SCTP_FUNC(sctp_sf_ootb), \
173 /* SCTP_STATE_CLOSED */ \ 175 /* SCTP_STATE_CLOSED */ \
174 {.fn = sctp_sf_tabort_8_4_8, .name = "sctp_sf_tabort_8_4_8"}, \ 176 TYPE_SCTP_FUNC(sctp_sf_tabort_8_4_8), \
175 /* SCTP_STATE_COOKIE_WAIT */ \ 177 /* SCTP_STATE_COOKIE_WAIT */ \
176 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 178 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
177 /* SCTP_STATE_COOKIE_ECHOED */ \ 179 /* SCTP_STATE_COOKIE_ECHOED */ \
178 {.fn = sctp_sf_eat_sack_6_2, .name = "sctp_sf_eat_sack_6_2"}, \ 180 TYPE_SCTP_FUNC(sctp_sf_eat_sack_6_2), \
179 /* SCTP_STATE_ESTABLISHED */ \ 181 /* SCTP_STATE_ESTABLISHED */ \
180 {.fn = sctp_sf_eat_sack_6_2, .name = "sctp_sf_eat_sack_6_2"}, \ 182 TYPE_SCTP_FUNC(sctp_sf_eat_sack_6_2), \
181 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 183 /* SCTP_STATE_SHUTDOWN_PENDING */ \
182 {.fn = sctp_sf_eat_sack_6_2, .name = "sctp_sf_eat_sack_6_2"}, \ 184 TYPE_SCTP_FUNC(sctp_sf_eat_sack_6_2), \
183 /* SCTP_STATE_SHUTDOWN_SENT */ \ 185 /* SCTP_STATE_SHUTDOWN_SENT */ \
184 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 186 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
185 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 187 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
186 {.fn = sctp_sf_eat_sack_6_2, .name = "sctp_sf_eat_sack_6_2"}, \ 188 TYPE_SCTP_FUNC(sctp_sf_eat_sack_6_2), \
187 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 189 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
188 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 190 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
189} /* TYPE_SCTP_SACK */ 191} /* TYPE_SCTP_SACK */
190 192
191#define TYPE_SCTP_HEARTBEAT { \ 193#define TYPE_SCTP_HEARTBEAT { \
192 /* SCTP_STATE_EMPTY */ \ 194 /* SCTP_STATE_EMPTY */ \
193 {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \ 195 TYPE_SCTP_FUNC(sctp_sf_ootb), \
194 /* SCTP_STATE_CLOSED */ \ 196 /* SCTP_STATE_CLOSED */ \
195 {.fn = sctp_sf_tabort_8_4_8, .name = "sctp_sf_tabort_8_4_8"}, \ 197 TYPE_SCTP_FUNC(sctp_sf_tabort_8_4_8), \
196 /* SCTP_STATE_COOKIE_WAIT */ \ 198 /* SCTP_STATE_COOKIE_WAIT */ \
197 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 199 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
198 /* SCTP_STATE_COOKIE_ECHOED */ \ 200 /* SCTP_STATE_COOKIE_ECHOED */ \
199 {.fn = sctp_sf_beat_8_3, .name = "sctp_sf_beat_8_3"}, \ 201 TYPE_SCTP_FUNC(sctp_sf_beat_8_3), \
200 /* SCTP_STATE_ESTABLISHED */ \ 202 /* SCTP_STATE_ESTABLISHED */ \
201 {.fn = sctp_sf_beat_8_3, .name = "sctp_sf_beat_8_3"}, \ 203 TYPE_SCTP_FUNC(sctp_sf_beat_8_3), \
202 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 204 /* SCTP_STATE_SHUTDOWN_PENDING */ \
203 {.fn = sctp_sf_beat_8_3, .name = "sctp_sf_beat_8_3"}, \ 205 TYPE_SCTP_FUNC(sctp_sf_beat_8_3), \
204 /* SCTP_STATE_SHUTDOWN_SENT */ \ 206 /* SCTP_STATE_SHUTDOWN_SENT */ \
205 {.fn = sctp_sf_beat_8_3, .name = "sctp_sf_beat_8_3"}, \ 207 TYPE_SCTP_FUNC(sctp_sf_beat_8_3), \
206 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 208 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
207 {.fn = sctp_sf_beat_8_3, .name = "sctp_sf_beat_8_3"}, \ 209 TYPE_SCTP_FUNC(sctp_sf_beat_8_3), \
208 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 210 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
209 /* This should not happen, but we are nice. */ \ 211 /* This should not happen, but we are nice. */ \
210 {.fn = sctp_sf_beat_8_3, .name = "sctp_sf_beat_8_3"}, \ 212 TYPE_SCTP_FUNC(sctp_sf_beat_8_3), \
211} /* TYPE_SCTP_HEARTBEAT */ 213} /* TYPE_SCTP_HEARTBEAT */
212 214
213#define TYPE_SCTP_HEARTBEAT_ACK { \ 215#define TYPE_SCTP_HEARTBEAT_ACK { \
214 /* SCTP_STATE_EMPTY */ \ 216 /* SCTP_STATE_EMPTY */ \
215 {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \ 217 TYPE_SCTP_FUNC(sctp_sf_ootb), \
216 /* SCTP_STATE_CLOSED */ \ 218 /* SCTP_STATE_CLOSED */ \
217 {.fn = sctp_sf_tabort_8_4_8, .name = "sctp_sf_tabort_8_4_8"}, \ 219 TYPE_SCTP_FUNC(sctp_sf_tabort_8_4_8), \
218 /* SCTP_STATE_COOKIE_WAIT */ \ 220 /* SCTP_STATE_COOKIE_WAIT */ \
219 {.fn = sctp_sf_violation, .name = "sctp_sf_violation"}, \ 221 TYPE_SCTP_FUNC(sctp_sf_violation), \
220 /* SCTP_STATE_COOKIE_ECHOED */ \ 222 /* SCTP_STATE_COOKIE_ECHOED */ \
221 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 223 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
222 /* SCTP_STATE_ESTABLISHED */ \ 224 /* SCTP_STATE_ESTABLISHED */ \
223 {.fn = sctp_sf_backbeat_8_3, .name = "sctp_sf_backbeat_8_3"}, \ 225 TYPE_SCTP_FUNC(sctp_sf_backbeat_8_3), \
224 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 226 /* SCTP_STATE_SHUTDOWN_PENDING */ \
225 {.fn = sctp_sf_backbeat_8_3, .name = "sctp_sf_backbeat_8_3"}, \ 227 TYPE_SCTP_FUNC(sctp_sf_backbeat_8_3), \
226 /* SCTP_STATE_SHUTDOWN_SENT */ \ 228 /* SCTP_STATE_SHUTDOWN_SENT */ \
227 {.fn = sctp_sf_backbeat_8_3, .name = "sctp_sf_backbeat_8_3"}, \ 229 TYPE_SCTP_FUNC(sctp_sf_backbeat_8_3), \
228 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 230 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
229 {.fn = sctp_sf_backbeat_8_3, .name = "sctp_sf_backbeat_8_3"}, \ 231 TYPE_SCTP_FUNC(sctp_sf_backbeat_8_3), \
230 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 232 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
231 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 233 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
232} /* TYPE_SCTP_HEARTBEAT_ACK */ 234} /* TYPE_SCTP_HEARTBEAT_ACK */
233 235
234#define TYPE_SCTP_ABORT { \ 236#define TYPE_SCTP_ABORT { \
235 /* SCTP_STATE_EMPTY */ \ 237 /* SCTP_STATE_EMPTY */ \
236 {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \ 238 TYPE_SCTP_FUNC(sctp_sf_ootb), \
237 /* SCTP_STATE_CLOSED */ \ 239 /* SCTP_STATE_CLOSED */ \
238 {.fn = sctp_sf_pdiscard, .name = "sctp_sf_pdiscard"}, \ 240 TYPE_SCTP_FUNC(sctp_sf_pdiscard), \
239 /* SCTP_STATE_COOKIE_WAIT */ \ 241 /* SCTP_STATE_COOKIE_WAIT */ \
240 {.fn = sctp_sf_cookie_wait_abort, .name = "sctp_sf_cookie_wait_abort"}, \ 242 TYPE_SCTP_FUNC(sctp_sf_cookie_wait_abort), \
241 /* SCTP_STATE_COOKIE_ECHOED */ \ 243 /* SCTP_STATE_COOKIE_ECHOED */ \
242 {.fn = sctp_sf_cookie_echoed_abort, \ 244 TYPE_SCTP_FUNC(sctp_sf_cookie_echoed_abort), \
243 .name = "sctp_sf_cookie_echoed_abort"}, \
244 /* SCTP_STATE_ESTABLISHED */ \ 245 /* SCTP_STATE_ESTABLISHED */ \
245 {.fn = sctp_sf_do_9_1_abort, .name = "sctp_sf_do_9_1_abort"}, \ 246 TYPE_SCTP_FUNC(sctp_sf_do_9_1_abort), \
246 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 247 /* SCTP_STATE_SHUTDOWN_PENDING */ \
247 {.fn = sctp_sf_shutdown_pending_abort, \ 248 TYPE_SCTP_FUNC(sctp_sf_shutdown_pending_abort), \
248 .name = "sctp_sf_shutdown_pending_abort"}, \
249 /* SCTP_STATE_SHUTDOWN_SENT */ \ 249 /* SCTP_STATE_SHUTDOWN_SENT */ \
250 {.fn = sctp_sf_shutdown_sent_abort, \ 250 TYPE_SCTP_FUNC(sctp_sf_shutdown_sent_abort), \
251 .name = "sctp_sf_shutdown_sent_abort"}, \
252 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 251 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
253 {.fn = sctp_sf_do_9_1_abort, .name = "sctp_sf_do_9_1_abort"}, \ 252 TYPE_SCTP_FUNC(sctp_sf_do_9_1_abort), \
254 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 253 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
255 {.fn = sctp_sf_shutdown_ack_sent_abort, \ 254 TYPE_SCTP_FUNC(sctp_sf_shutdown_ack_sent_abort), \
256 .name = "sctp_sf_shutdown_ack_sent_abort"}, \
257} /* TYPE_SCTP_ABORT */ 255} /* TYPE_SCTP_ABORT */
258 256
259#define TYPE_SCTP_SHUTDOWN { \ 257#define TYPE_SCTP_SHUTDOWN { \
260 /* SCTP_STATE_EMPTY */ \ 258 /* SCTP_STATE_EMPTY */ \
261 {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \ 259 TYPE_SCTP_FUNC(sctp_sf_ootb), \
262 /* SCTP_STATE_CLOSED */ \ 260 /* SCTP_STATE_CLOSED */ \
263 {.fn = sctp_sf_tabort_8_4_8, .name = "sctp_sf_tabort_8_4_8"}, \ 261 TYPE_SCTP_FUNC(sctp_sf_tabort_8_4_8), \
264 /* SCTP_STATE_COOKIE_WAIT */ \ 262 /* SCTP_STATE_COOKIE_WAIT */ \
265 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 263 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
266 /* SCTP_STATE_COOKIE_ECHOED */ \ 264 /* SCTP_STATE_COOKIE_ECHOED */ \
267 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 265 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
268 /* SCTP_STATE_ESTABLISHED */ \ 266 /* SCTP_STATE_ESTABLISHED */ \
269 {.fn = sctp_sf_do_9_2_shutdown, .name = "sctp_sf_do_9_2_shutdown"}, \ 267 TYPE_SCTP_FUNC(sctp_sf_do_9_2_shutdown), \
270 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 268 /* SCTP_STATE_SHUTDOWN_PENDING */ \
271 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 269 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
272 /* SCTP_STATE_SHUTDOWN_SENT */ \ 270 /* SCTP_STATE_SHUTDOWN_SENT */ \
273 {.fn = sctp_sf_do_9_2_shutdown_ack, \ 271 TYPE_SCTP_FUNC(sctp_sf_do_9_2_shutdown_ack), \
274 .name = "sctp_sf_do_9_2_shutdown_ack"}, \
275 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 272 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
276 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 273 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
277 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 274 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
278 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 275 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
279} /* TYPE_SCTP_SHUTDOWN */ 276} /* TYPE_SCTP_SHUTDOWN */
280 277
281#define TYPE_SCTP_SHUTDOWN_ACK { \ 278#define TYPE_SCTP_SHUTDOWN_ACK { \
282 /* SCTP_STATE_EMPTY */ \ 279 /* SCTP_STATE_EMPTY */ \
283 {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \ 280 TYPE_SCTP_FUNC(sctp_sf_ootb), \
284 /* SCTP_STATE_CLOSED */ \ 281 /* SCTP_STATE_CLOSED */ \
285 {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \ 282 TYPE_SCTP_FUNC(sctp_sf_ootb), \
286 /* SCTP_STATE_COOKIE_WAIT */ \ 283 /* SCTP_STATE_COOKIE_WAIT */ \
287 {.fn = sctp_sf_do_8_5_1_E_sa, .name = "sctp_sf_do_8_5_1_E_sa"}, \ 284 TYPE_SCTP_FUNC(sctp_sf_do_8_5_1_E_sa), \
288 /* SCTP_STATE_COOKIE_ECHOED */ \ 285 /* SCTP_STATE_COOKIE_ECHOED */ \
289 {.fn = sctp_sf_do_8_5_1_E_sa, .name = "sctp_sf_do_8_5_1_E_sa"}, \ 286 TYPE_SCTP_FUNC(sctp_sf_do_8_5_1_E_sa), \
290 /* SCTP_STATE_ESTABLISHED */ \ 287 /* SCTP_STATE_ESTABLISHED */ \
291 {.fn = sctp_sf_violation, .name = "sctp_sf_violation"}, \ 288 TYPE_SCTP_FUNC(sctp_sf_violation), \
292 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 289 /* SCTP_STATE_SHUTDOWN_PENDING */ \
293 {.fn = sctp_sf_violation, .name = "sctp_sf_violation"}, \ 290 TYPE_SCTP_FUNC(sctp_sf_violation), \
294 /* SCTP_STATE_SHUTDOWN_SENT */ \ 291 /* SCTP_STATE_SHUTDOWN_SENT */ \
295 {.fn = sctp_sf_do_9_2_final, .name = "sctp_sf_do_9_2_final"}, \ 292 TYPE_SCTP_FUNC(sctp_sf_do_9_2_final), \
296 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 293 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
297 {.fn = sctp_sf_violation, .name = "sctp_sf_violation"}, \ 294 TYPE_SCTP_FUNC(sctp_sf_violation), \
298 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 295 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
299 {.fn = sctp_sf_do_9_2_final, .name = "sctp_sf_do_9_2_final"}, \ 296 TYPE_SCTP_FUNC(sctp_sf_do_9_2_final), \
300} /* TYPE_SCTP_SHUTDOWN_ACK */ 297} /* TYPE_SCTP_SHUTDOWN_ACK */
301 298
302#define TYPE_SCTP_ERROR { \ 299#define TYPE_SCTP_ERROR { \
303 /* SCTP_STATE_EMPTY */ \ 300 /* SCTP_STATE_EMPTY */ \
304 {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \ 301 TYPE_SCTP_FUNC(sctp_sf_ootb), \
305 /* SCTP_STATE_CLOSED */ \ 302 /* SCTP_STATE_CLOSED */ \
306 {.fn = sctp_sf_tabort_8_4_8, .name = "sctp_sf_tabort_8_4_8"}, \ 303 TYPE_SCTP_FUNC(sctp_sf_tabort_8_4_8), \
307 /* SCTP_STATE_COOKIE_WAIT */ \ 304 /* SCTP_STATE_COOKIE_WAIT */ \
308 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 305 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
309 /* SCTP_STATE_COOKIE_ECHOED */ \ 306 /* SCTP_STATE_COOKIE_ECHOED */ \
310 {.fn = sctp_sf_cookie_echoed_err, .name = "sctp_sf_cookie_echoed_err"}, \ 307 TYPE_SCTP_FUNC(sctp_sf_cookie_echoed_err), \
311 /* SCTP_STATE_ESTABLISHED */ \ 308 /* SCTP_STATE_ESTABLISHED */ \
312 {.fn = sctp_sf_operr_notify, .name = "sctp_sf_operr_notify"}, \ 309 TYPE_SCTP_FUNC(sctp_sf_operr_notify), \
313 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 310 /* SCTP_STATE_SHUTDOWN_PENDING */ \
314 {.fn = sctp_sf_operr_notify, .name = "sctp_sf_operr_notify"}, \ 311 TYPE_SCTP_FUNC(sctp_sf_operr_notify), \
315 /* SCTP_STATE_SHUTDOWN_SENT */ \ 312 /* SCTP_STATE_SHUTDOWN_SENT */ \
316 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 313 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
317 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 314 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
318 {.fn = sctp_sf_operr_notify, .name = "sctp_sf_operr_notify"}, \ 315 TYPE_SCTP_FUNC(sctp_sf_operr_notify), \
319 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 316 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
320 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 317 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
321} /* TYPE_SCTP_ERROR */ 318} /* TYPE_SCTP_ERROR */
322 319
323#define TYPE_SCTP_COOKIE_ECHO { \ 320#define TYPE_SCTP_COOKIE_ECHO { \
324 /* SCTP_STATE_EMPTY */ \ 321 /* SCTP_STATE_EMPTY */ \
325 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ 322 TYPE_SCTP_FUNC(sctp_sf_bug), \
326 /* SCTP_STATE_CLOSED */ \ 323 /* SCTP_STATE_CLOSED */ \
327 {.fn = sctp_sf_do_5_1D_ce, .name = "sctp_sf_do_5_1D_ce"}, \ 324 TYPE_SCTP_FUNC(sctp_sf_do_5_1D_ce), \
328 /* SCTP_STATE_COOKIE_WAIT */ \ 325 /* SCTP_STATE_COOKIE_WAIT */ \
329 {.fn = sctp_sf_do_5_2_4_dupcook, .name = "sctp_sf_do_5_2_4_dupcook"}, \ 326 TYPE_SCTP_FUNC(sctp_sf_do_5_2_4_dupcook), \
330 /* SCTP_STATE_COOKIE_ECHOED */ \ 327 /* SCTP_STATE_COOKIE_ECHOED */ \
331 {.fn = sctp_sf_do_5_2_4_dupcook, .name = "sctp_sf_do_5_2_4_dupcook"}, \ 328 TYPE_SCTP_FUNC(sctp_sf_do_5_2_4_dupcook), \
332 /* SCTP_STATE_ESTABLISHED */ \ 329 /* SCTP_STATE_ESTABLISHED */ \
333 {.fn = sctp_sf_do_5_2_4_dupcook, .name = "sctp_sf_do_5_2_4_dupcook"}, \ 330 TYPE_SCTP_FUNC(sctp_sf_do_5_2_4_dupcook), \
334 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 331 /* SCTP_STATE_SHUTDOWN_PENDING */ \
335 {.fn = sctp_sf_do_5_2_4_dupcook, .name = "sctp_sf_do_5_2_4_dupcook"}, \ 332 TYPE_SCTP_FUNC(sctp_sf_do_5_2_4_dupcook), \
336 /* SCTP_STATE_SHUTDOWN_SENT */ \ 333 /* SCTP_STATE_SHUTDOWN_SENT */ \
337 {.fn = sctp_sf_do_5_2_4_dupcook, .name = "sctp_sf_do_5_2_4_dupcook"}, \ 334 TYPE_SCTP_FUNC(sctp_sf_do_5_2_4_dupcook), \
338 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 335 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
339 {.fn = sctp_sf_do_5_2_4_dupcook, .name = "sctp_sf_do_5_2_4_dupcook"}, \ 336 TYPE_SCTP_FUNC(sctp_sf_do_5_2_4_dupcook), \
340 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 337 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
341 {.fn = sctp_sf_do_5_2_4_dupcook, .name = "sctp_sf_do_5_2_4_dupcook"}, \ 338 TYPE_SCTP_FUNC(sctp_sf_do_5_2_4_dupcook), \
342} /* TYPE_SCTP_COOKIE_ECHO */ 339} /* TYPE_SCTP_COOKIE_ECHO */
343 340
344#define TYPE_SCTP_COOKIE_ACK { \ 341#define TYPE_SCTP_COOKIE_ACK { \
345 /* SCTP_STATE_EMPTY */ \ 342 /* SCTP_STATE_EMPTY */ \
346 {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \ 343 TYPE_SCTP_FUNC(sctp_sf_ootb), \
347 /* SCTP_STATE_CLOSED */ \ 344 /* SCTP_STATE_CLOSED */ \
348 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 345 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
349 /* SCTP_STATE_COOKIE_WAIT */ \ 346 /* SCTP_STATE_COOKIE_WAIT */ \
350 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 347 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
351 /* SCTP_STATE_COOKIE_ECHOED */ \ 348 /* SCTP_STATE_COOKIE_ECHOED */ \
352 {.fn = sctp_sf_do_5_1E_ca, .name = "sctp_sf_do_5_1E_ca"}, \ 349 TYPE_SCTP_FUNC(sctp_sf_do_5_1E_ca), \
353 /* SCTP_STATE_ESTABLISHED */ \ 350 /* SCTP_STATE_ESTABLISHED */ \
354 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 351 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
355 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 352 /* SCTP_STATE_SHUTDOWN_PENDING */ \
356 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 353 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
357 /* SCTP_STATE_SHUTDOWN_SENT */ \ 354 /* SCTP_STATE_SHUTDOWN_SENT */ \
358 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 355 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
359 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 356 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
360 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 357 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
361 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 358 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
362 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 359 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
363} /* TYPE_SCTP_COOKIE_ACK */ 360} /* TYPE_SCTP_COOKIE_ACK */
364 361
365#define TYPE_SCTP_ECN_ECNE { \ 362#define TYPE_SCTP_ECN_ECNE { \
366 /* SCTP_STATE_EMPTY */ \ 363 /* SCTP_STATE_EMPTY */ \
367 {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \ 364 TYPE_SCTP_FUNC(sctp_sf_ootb), \
368 /* SCTP_STATE_CLOSED */ \ 365 /* SCTP_STATE_CLOSED */ \
369 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 366 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
370 /* SCTP_STATE_COOKIE_WAIT */ \ 367 /* SCTP_STATE_COOKIE_WAIT */ \
371 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 368 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
372 /* SCTP_STATE_COOKIE_ECHOED */ \ 369 /* SCTP_STATE_COOKIE_ECHOED */ \
373 {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \ 370 TYPE_SCTP_FUNC(sctp_sf_do_ecne), \
374 /* SCTP_STATE_ESTABLISHED */ \ 371 /* SCTP_STATE_ESTABLISHED */ \
375 {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \ 372 TYPE_SCTP_FUNC(sctp_sf_do_ecne), \
376 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 373 /* SCTP_STATE_SHUTDOWN_PENDING */ \
377 {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \ 374 TYPE_SCTP_FUNC(sctp_sf_do_ecne), \
378 /* SCTP_STATE_SHUTDOWN_SENT */ \ 375 /* SCTP_STATE_SHUTDOWN_SENT */ \
379 {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \ 376 TYPE_SCTP_FUNC(sctp_sf_do_ecne), \
380 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 377 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
381 {.fn = sctp_sf_do_ecne, .name = "sctp_sf_do_ecne"}, \ 378 TYPE_SCTP_FUNC(sctp_sf_do_ecne), \
382 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 379 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
383 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 380 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
384} /* TYPE_SCTP_ECN_ECNE */ 381} /* TYPE_SCTP_ECN_ECNE */
385 382
386#define TYPE_SCTP_ECN_CWR { \ 383#define TYPE_SCTP_ECN_CWR { \
387 /* SCTP_STATE_EMPTY */ \ 384 /* SCTP_STATE_EMPTY */ \
388 {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \ 385 TYPE_SCTP_FUNC(sctp_sf_ootb), \
389 /* SCTP_STATE_CLOSED */ \ 386 /* SCTP_STATE_CLOSED */ \
390 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 387 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
391 /* SCTP_STATE_COOKIE_WAIT */ \ 388 /* SCTP_STATE_COOKIE_WAIT */ \
392 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 389 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
393 /* SCTP_STATE_COOKIE_ECHOED */ \ 390 /* SCTP_STATE_COOKIE_ECHOED */ \
394 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 391 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
395 /* SCTP_STATE_ESTABLISHED */ \ 392 /* SCTP_STATE_ESTABLISHED */ \
396 {.fn = sctp_sf_do_ecn_cwr, .name = "sctp_sf_do_ecn_cwr"}, \ 393 TYPE_SCTP_FUNC(sctp_sf_do_ecn_cwr), \
397 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 394 /* SCTP_STATE_SHUTDOWN_PENDING */ \
398 {.fn = sctp_sf_do_ecn_cwr, .name = "sctp_sf_do_ecn_cwr"}, \ 395 TYPE_SCTP_FUNC(sctp_sf_do_ecn_cwr), \
399 /* SCTP_STATE_SHUTDOWN_SENT */ \ 396 /* SCTP_STATE_SHUTDOWN_SENT */ \
400 {.fn = sctp_sf_do_ecn_cwr, .name = "sctp_sf_do_ecn_cwr"}, \ 397 TYPE_SCTP_FUNC(sctp_sf_do_ecn_cwr), \
401 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 398 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
402 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 399 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
403 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 400 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
404 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 401 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
405} /* TYPE_SCTP_ECN_CWR */ 402} /* TYPE_SCTP_ECN_CWR */
406 403
407#define TYPE_SCTP_SHUTDOWN_COMPLETE { \ 404#define TYPE_SCTP_SHUTDOWN_COMPLETE { \
408 /* SCTP_STATE_EMPTY */ \ 405 /* SCTP_STATE_EMPTY */ \
409 {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \ 406 TYPE_SCTP_FUNC(sctp_sf_ootb), \
410 /* SCTP_STATE_CLOSED */ \ 407 /* SCTP_STATE_CLOSED */ \
411 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 408 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
412 /* SCTP_STATE_COOKIE_WAIT */ \ 409 /* SCTP_STATE_COOKIE_WAIT */ \
413 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 410 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
414 /* SCTP_STATE_COOKIE_ECHOED */ \ 411 /* SCTP_STATE_COOKIE_ECHOED */ \
415 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 412 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
416 /* SCTP_STATE_ESTABLISHED */ \ 413 /* SCTP_STATE_ESTABLISHED */ \
417 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 414 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
418 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 415 /* SCTP_STATE_SHUTDOWN_PENDING */ \
419 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 416 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
420 /* SCTP_STATE_SHUTDOWN_SENT */ \ 417 /* SCTP_STATE_SHUTDOWN_SENT */ \
421 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 418 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
422 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 419 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
423 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 420 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
424 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 421 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
425 {.fn = sctp_sf_do_4_C, .name = "sctp_sf_do_4_C"}, \ 422 TYPE_SCTP_FUNC(sctp_sf_do_4_C), \
426} /* TYPE_SCTP_SHUTDOWN_COMPLETE */ 423} /* TYPE_SCTP_SHUTDOWN_COMPLETE */
427 424
428/* The primary index for this table is the chunk type. 425/* The primary index for this table is the chunk type.
@@ -450,44 +447,44 @@ static const sctp_sm_table_entry_t chunk_event_table[SCTP_NUM_BASE_CHUNK_TYPES][
450 447
451#define TYPE_SCTP_ASCONF { \ 448#define TYPE_SCTP_ASCONF { \
452 /* SCTP_STATE_EMPTY */ \ 449 /* SCTP_STATE_EMPTY */ \
453 {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \ 450 TYPE_SCTP_FUNC(sctp_sf_ootb), \
454 /* SCTP_STATE_CLOSED */ \ 451 /* SCTP_STATE_CLOSED */ \
455 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 452 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
456 /* SCTP_STATE_COOKIE_WAIT */ \ 453 /* SCTP_STATE_COOKIE_WAIT */ \
457 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 454 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
458 /* SCTP_STATE_COOKIE_ECHOED */ \ 455 /* SCTP_STATE_COOKIE_ECHOED */ \
459 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 456 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
460 /* SCTP_STATE_ESTABLISHED */ \ 457 /* SCTP_STATE_ESTABLISHED */ \
461 {.fn = sctp_sf_do_asconf, .name = "sctp_sf_do_asconf"}, \ 458 TYPE_SCTP_FUNC(sctp_sf_do_asconf), \
462 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 459 /* SCTP_STATE_SHUTDOWN_PENDING */ \
463 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 460 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
464 /* SCTP_STATE_SHUTDOWN_SENT */ \ 461 /* SCTP_STATE_SHUTDOWN_SENT */ \
465 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 462 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
466 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 463 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
467 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 464 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
468 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 465 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
469 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 466 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
470} /* TYPE_SCTP_ASCONF */ 467} /* TYPE_SCTP_ASCONF */
471 468
472#define TYPE_SCTP_ASCONF_ACK { \ 469#define TYPE_SCTP_ASCONF_ACK { \
473 /* SCTP_STATE_EMPTY */ \ 470 /* SCTP_STATE_EMPTY */ \
474 {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \ 471 TYPE_SCTP_FUNC(sctp_sf_ootb), \
475 /* SCTP_STATE_CLOSED */ \ 472 /* SCTP_STATE_CLOSED */ \
476 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 473 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
477 /* SCTP_STATE_COOKIE_WAIT */ \ 474 /* SCTP_STATE_COOKIE_WAIT */ \
478 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 475 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
479 /* SCTP_STATE_COOKIE_ECHOED */ \ 476 /* SCTP_STATE_COOKIE_ECHOED */ \
480 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 477 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
481 /* SCTP_STATE_ESTABLISHED */ \ 478 /* SCTP_STATE_ESTABLISHED */ \
482 {.fn = sctp_sf_do_asconf_ack, .name = "sctp_sf_do_asconf_ack"}, \ 479 TYPE_SCTP_FUNC(sctp_sf_do_asconf_ack), \
483 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 480 /* SCTP_STATE_SHUTDOWN_PENDING */ \
484 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 481 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
485 /* SCTP_STATE_SHUTDOWN_SENT */ \ 482 /* SCTP_STATE_SHUTDOWN_SENT */ \
486 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 483 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
487 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 484 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
488 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 485 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
489 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 486 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
490 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 487 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
491} /* TYPE_SCTP_ASCONF_ACK */ 488} /* TYPE_SCTP_ASCONF_ACK */
492 489
493/* The primary index for this table is the chunk type. 490/* The primary index for this table is the chunk type.
@@ -500,23 +497,23 @@ static const sctp_sm_table_entry_t addip_chunk_event_table[SCTP_NUM_ADDIP_CHUNK_
500 497
501#define TYPE_SCTP_FWD_TSN { \ 498#define TYPE_SCTP_FWD_TSN { \
502 /* SCTP_STATE_EMPTY */ \ 499 /* SCTP_STATE_EMPTY */ \
503 {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, \ 500 TYPE_SCTP_FUNC(sctp_sf_ootb), \
504 /* SCTP_STATE_CLOSED */ \ 501 /* SCTP_STATE_CLOSED */ \
505 {.fn = sctp_sf_tabort_8_4_8, .name = "sctp_sf_tabort_8_4_8"}, \ 502 TYPE_SCTP_FUNC(sctp_sf_tabort_8_4_8), \
506 /* SCTP_STATE_COOKIE_WAIT */ \ 503 /* SCTP_STATE_COOKIE_WAIT */ \
507 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 504 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
508 /* SCTP_STATE_COOKIE_ECHOED */ \ 505 /* SCTP_STATE_COOKIE_ECHOED */ \
509 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 506 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
510 /* SCTP_STATE_ESTABLISHED */ \ 507 /* SCTP_STATE_ESTABLISHED */ \
511 {.fn = sctp_sf_eat_fwd_tsn, .name = "sctp_sf_eat_fwd_tsn"}, \ 508 TYPE_SCTP_FUNC(sctp_sf_eat_fwd_tsn), \
512 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 509 /* SCTP_STATE_SHUTDOWN_PENDING */ \
513 {.fn = sctp_sf_eat_fwd_tsn, .name = "sctp_sf_eat_fwd_tsn"}, \ 510 TYPE_SCTP_FUNC(sctp_sf_eat_fwd_tsn), \
514 /* SCTP_STATE_SHUTDOWN_SENT */ \ 511 /* SCTP_STATE_SHUTDOWN_SENT */ \
515 {.fn = sctp_sf_eat_fwd_tsn_fast, .name = "sctp_sf_eat_fwd_tsn_fast"}, \ 512 TYPE_SCTP_FUNC(sctp_sf_eat_fwd_tsn_fast), \
516 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 513 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
517 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 514 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
518 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 515 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
519 {.fn = sctp_sf_discard_chunk, .name = "sctp_sf_discard_chunk"}, \ 516 TYPE_SCTP_FUNC(sctp_sf_discard_chunk), \
520} /* TYPE_SCTP_FWD_TSN */ 517} /* TYPE_SCTP_FWD_TSN */
521 518
522/* The primary index for this table is the chunk type. 519/* The primary index for this table is the chunk type.
@@ -529,167 +526,150 @@ static const sctp_sm_table_entry_t prsctp_chunk_event_table[SCTP_NUM_PRSCTP_CHUN
529static const sctp_sm_table_entry_t 526static const sctp_sm_table_entry_t
530chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = { 527chunk_event_table_unknown[SCTP_STATE_NUM_STATES] = {
531 /* SCTP_STATE_EMPTY */ 528 /* SCTP_STATE_EMPTY */
532 {.fn = sctp_sf_ootb, .name = "sctp_sf_ootb"}, 529 TYPE_SCTP_FUNC(sctp_sf_ootb),
533 /* SCTP_STATE_CLOSED */ 530 /* SCTP_STATE_CLOSED */
534 {.fn = sctp_sf_tabort_8_4_8, .name = "sctp_sf_tabort_8_4_8"}, 531 TYPE_SCTP_FUNC(sctp_sf_tabort_8_4_8),
535 /* SCTP_STATE_COOKIE_WAIT */ 532 /* SCTP_STATE_COOKIE_WAIT */
536 {.fn = sctp_sf_unk_chunk, .name = "sctp_sf_unk_chunk"}, 533 TYPE_SCTP_FUNC(sctp_sf_unk_chunk),
537 /* SCTP_STATE_COOKIE_ECHOED */ 534 /* SCTP_STATE_COOKIE_ECHOED */
538 {.fn = sctp_sf_unk_chunk, .name = "sctp_sf_unk_chunk"}, 535 TYPE_SCTP_FUNC(sctp_sf_unk_chunk),
539 /* SCTP_STATE_ESTABLISHED */ 536 /* SCTP_STATE_ESTABLISHED */
540 {.fn = sctp_sf_unk_chunk, .name = "sctp_sf_unk_chunk"}, 537 TYPE_SCTP_FUNC(sctp_sf_unk_chunk),
541 /* SCTP_STATE_SHUTDOWN_PENDING */ 538 /* SCTP_STATE_SHUTDOWN_PENDING */
542 {.fn = sctp_sf_unk_chunk, .name = "sctp_sf_unk_chunk"}, 539 TYPE_SCTP_FUNC(sctp_sf_unk_chunk),
543 /* SCTP_STATE_SHUTDOWN_SENT */ 540 /* SCTP_STATE_SHUTDOWN_SENT */
544 {.fn = sctp_sf_unk_chunk, .name = "sctp_sf_unk_chunk"}, 541 TYPE_SCTP_FUNC(sctp_sf_unk_chunk),
545 /* SCTP_STATE_SHUTDOWN_RECEIVED */ 542 /* SCTP_STATE_SHUTDOWN_RECEIVED */
546 {.fn = sctp_sf_unk_chunk, .name = "sctp_sf_unk_chunk"}, 543 TYPE_SCTP_FUNC(sctp_sf_unk_chunk),
547 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ 544 /* SCTP_STATE_SHUTDOWN_ACK_SENT */
548 {.fn = sctp_sf_unk_chunk, .name = "sctp_sf_unk_chunk"}, 545 TYPE_SCTP_FUNC(sctp_sf_unk_chunk),
549}; /* chunk unknown */ 546}; /* chunk unknown */
550 547
551 548
552#define TYPE_SCTP_PRIMITIVE_ASSOCIATE { \ 549#define TYPE_SCTP_PRIMITIVE_ASSOCIATE { \
553 /* SCTP_STATE_EMPTY */ \ 550 /* SCTP_STATE_EMPTY */ \
554 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ 551 TYPE_SCTP_FUNC(sctp_sf_bug), \
555 /* SCTP_STATE_CLOSED */ \ 552 /* SCTP_STATE_CLOSED */ \
556 {.fn = sctp_sf_do_prm_asoc, .name = "sctp_sf_do_prm_asoc"}, \ 553 TYPE_SCTP_FUNC(sctp_sf_do_prm_asoc), \
557 /* SCTP_STATE_COOKIE_WAIT */ \ 554 /* SCTP_STATE_COOKIE_WAIT */ \
558 {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ 555 TYPE_SCTP_FUNC(sctp_sf_not_impl), \
559 /* SCTP_STATE_COOKIE_ECHOED */ \ 556 /* SCTP_STATE_COOKIE_ECHOED */ \
560 {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ 557 TYPE_SCTP_FUNC(sctp_sf_not_impl), \
561 /* SCTP_STATE_ESTABLISHED */ \ 558 /* SCTP_STATE_ESTABLISHED */ \
562 {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ 559 TYPE_SCTP_FUNC(sctp_sf_not_impl), \
563 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 560 /* SCTP_STATE_SHUTDOWN_PENDING */ \
564 {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ 561 TYPE_SCTP_FUNC(sctp_sf_not_impl), \
565 /* SCTP_STATE_SHUTDOWN_SENT */ \ 562 /* SCTP_STATE_SHUTDOWN_SENT */ \
566 {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ 563 TYPE_SCTP_FUNC(sctp_sf_not_impl), \
567 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 564 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
568 {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ 565 TYPE_SCTP_FUNC(sctp_sf_not_impl), \
569 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 566 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
570 {.fn = sctp_sf_not_impl, .name = "sctp_sf_not_impl"}, \ 567 TYPE_SCTP_FUNC(sctp_sf_not_impl), \
571} /* TYPE_SCTP_PRIMITIVE_ASSOCIATE */ 568} /* TYPE_SCTP_PRIMITIVE_ASSOCIATE */
572 569
573#define TYPE_SCTP_PRIMITIVE_SHUTDOWN { \ 570#define TYPE_SCTP_PRIMITIVE_SHUTDOWN { \
574 /* SCTP_STATE_EMPTY */ \ 571 /* SCTP_STATE_EMPTY */ \
575 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ 572 TYPE_SCTP_FUNC(sctp_sf_bug), \
576 /* SCTP_STATE_CLOSED */ \ 573 /* SCTP_STATE_CLOSED */ \
577 {.fn = sctp_sf_error_closed, .name = "sctp_sf_error_closed"}, \ 574 TYPE_SCTP_FUNC(sctp_sf_error_closed), \
578 /* SCTP_STATE_COOKIE_WAIT */ \ 575 /* SCTP_STATE_COOKIE_WAIT */ \
579 {.fn = sctp_sf_cookie_wait_prm_shutdown, \ 576 TYPE_SCTP_FUNC(sctp_sf_cookie_wait_prm_shutdown), \
580 .name = "sctp_sf_cookie_wait_prm_shutdown"}, \
581 /* SCTP_STATE_COOKIE_ECHOED */ \ 577 /* SCTP_STATE_COOKIE_ECHOED */ \
582 {.fn = sctp_sf_cookie_echoed_prm_shutdown, \ 578 TYPE_SCTP_FUNC(sctp_sf_cookie_echoed_prm_shutdown),\
583 .name = "sctp_sf_cookie_echoed_prm_shutdown"},\
584 /* SCTP_STATE_ESTABLISHED */ \ 579 /* SCTP_STATE_ESTABLISHED */ \
585 {.fn = sctp_sf_do_9_2_prm_shutdown, \ 580 TYPE_SCTP_FUNC(sctp_sf_do_9_2_prm_shutdown), \
586 .name = "sctp_sf_do_9_2_prm_shutdown"}, \
587 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 581 /* SCTP_STATE_SHUTDOWN_PENDING */ \
588 {.fn = sctp_sf_ignore_primitive, .name = "sctp_sf_ignore_primitive"}, \ 582 TYPE_SCTP_FUNC(sctp_sf_ignore_primitive), \
589 /* SCTP_STATE_SHUTDOWN_SENT */ \ 583 /* SCTP_STATE_SHUTDOWN_SENT */ \
590 {.fn = sctp_sf_ignore_primitive, .name = "sctp_sf_ignore_primitive"}, \ 584 TYPE_SCTP_FUNC(sctp_sf_ignore_primitive), \
591 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 585 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
592 {.fn = sctp_sf_ignore_primitive, .name = "sctp_sf_ignore_primitive"}, \ 586 TYPE_SCTP_FUNC(sctp_sf_ignore_primitive), \
593 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 587 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
594 {.fn = sctp_sf_ignore_primitive, .name = "sctp_sf_ignore_primitive"}, \ 588 TYPE_SCTP_FUNC(sctp_sf_ignore_primitive), \
595} /* TYPE_SCTP_PRIMITIVE_SHUTDOWN */ 589} /* TYPE_SCTP_PRIMITIVE_SHUTDOWN */
596 590
597#define TYPE_SCTP_PRIMITIVE_ABORT { \ 591#define TYPE_SCTP_PRIMITIVE_ABORT { \
598 /* SCTP_STATE_EMPTY */ \ 592 /* SCTP_STATE_EMPTY */ \
599 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ 593 TYPE_SCTP_FUNC(sctp_sf_bug), \
600 /* SCTP_STATE_CLOSED */ \ 594 /* SCTP_STATE_CLOSED */ \
601 {.fn = sctp_sf_error_closed, .name = "sctp_sf_error_closed"}, \ 595 TYPE_SCTP_FUNC(sctp_sf_error_closed), \
602 /* SCTP_STATE_COOKIE_WAIT */ \ 596 /* SCTP_STATE_COOKIE_WAIT */ \
603 {.fn = sctp_sf_cookie_wait_prm_abort, \ 597 TYPE_SCTP_FUNC(sctp_sf_cookie_wait_prm_abort), \
604 .name = "sctp_sf_cookie_wait_prm_abort"}, \
605 /* SCTP_STATE_COOKIE_ECHOED */ \ 598 /* SCTP_STATE_COOKIE_ECHOED */ \
606 {.fn = sctp_sf_cookie_echoed_prm_abort, \ 599 TYPE_SCTP_FUNC(sctp_sf_cookie_echoed_prm_abort), \
607 .name = "sctp_sf_cookie_echoed_prm_abort"}, \
608 /* SCTP_STATE_ESTABLISHED */ \ 600 /* SCTP_STATE_ESTABLISHED */ \
609 {.fn = sctp_sf_do_9_1_prm_abort, \ 601 TYPE_SCTP_FUNC(sctp_sf_do_9_1_prm_abort), \
610 .name = "sctp_sf_do_9_1_prm_abort"}, \
611 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 602 /* SCTP_STATE_SHUTDOWN_PENDING */ \
612 {.fn = sctp_sf_shutdown_pending_prm_abort, \ 603 TYPE_SCTP_FUNC(sctp_sf_shutdown_pending_prm_abort), \
613 .name = "sctp_sf_shutdown_pending_prm_abort"}, \
614 /* SCTP_STATE_SHUTDOWN_SENT */ \ 604 /* SCTP_STATE_SHUTDOWN_SENT */ \
615 {.fn = sctp_sf_shutdown_sent_prm_abort, \ 605 TYPE_SCTP_FUNC(sctp_sf_shutdown_sent_prm_abort), \
616 .name = "sctp_sf_shutdown_sent_prm_abort"}, \
617 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 606 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
618 {.fn = sctp_sf_do_9_1_prm_abort, \ 607 TYPE_SCTP_FUNC(sctp_sf_do_9_1_prm_abort), \
619 .name = "sctp_sf_do_9_1_prm_abort"}, \
620 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 608 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
621 {.fn = sctp_sf_shutdown_ack_sent_prm_abort, \ 609 TYPE_SCTP_FUNC(sctp_sf_shutdown_ack_sent_prm_abort), \
622 .name = "sctp_sf_shutdown_ack_sent_prm_abort"}, \
623} /* TYPE_SCTP_PRIMITIVE_ABORT */ 610} /* TYPE_SCTP_PRIMITIVE_ABORT */
624 611
625#define TYPE_SCTP_PRIMITIVE_SEND { \ 612#define TYPE_SCTP_PRIMITIVE_SEND { \
626 /* SCTP_STATE_EMPTY */ \ 613 /* SCTP_STATE_EMPTY */ \
627 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ 614 TYPE_SCTP_FUNC(sctp_sf_bug), \
628 /* SCTP_STATE_CLOSED */ \ 615 /* SCTP_STATE_CLOSED */ \
629 {.fn = sctp_sf_error_closed, .name = "sctp_sf_error_closed"}, \ 616 TYPE_SCTP_FUNC(sctp_sf_error_closed), \
630 /* SCTP_STATE_COOKIE_WAIT */ \ 617 /* SCTP_STATE_COOKIE_WAIT */ \
631 {.fn = sctp_sf_do_prm_send, .name = "sctp_sf_do_prm_send"}, \ 618 TYPE_SCTP_FUNC(sctp_sf_do_prm_send), \
632 /* SCTP_STATE_COOKIE_ECHOED */ \ 619 /* SCTP_STATE_COOKIE_ECHOED */ \
633 {.fn = sctp_sf_do_prm_send, .name = "sctp_sf_do_prm_send"}, \ 620 TYPE_SCTP_FUNC(sctp_sf_do_prm_send), \
634 /* SCTP_STATE_ESTABLISHED */ \ 621 /* SCTP_STATE_ESTABLISHED */ \
635 {.fn = sctp_sf_do_prm_send, .name = "sctp_sf_do_prm_send"}, \ 622 TYPE_SCTP_FUNC(sctp_sf_do_prm_send), \
636 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 623 /* SCTP_STATE_SHUTDOWN_PENDING */ \
637 {.fn = sctp_sf_error_shutdown, .name = "sctp_sf_error_shutdown"}, \ 624 TYPE_SCTP_FUNC(sctp_sf_error_shutdown), \
638 /* SCTP_STATE_SHUTDOWN_SENT */ \ 625 /* SCTP_STATE_SHUTDOWN_SENT */ \
639 {.fn = sctp_sf_error_shutdown, .name = "sctp_sf_error_shutdown"}, \ 626 TYPE_SCTP_FUNC(sctp_sf_error_shutdown), \
640 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 627 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
641 {.fn = sctp_sf_error_shutdown, .name = "sctp_sf_error_shutdown"}, \ 628 TYPE_SCTP_FUNC(sctp_sf_error_shutdown), \
642 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 629 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
643 {.fn = sctp_sf_error_shutdown, .name = "sctp_sf_error_shutdown"}, \ 630 TYPE_SCTP_FUNC(sctp_sf_error_shutdown), \
644} /* TYPE_SCTP_PRIMITIVE_SEND */ 631} /* TYPE_SCTP_PRIMITIVE_SEND */
645 632
646#define TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT { \ 633#define TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT { \
647 /* SCTP_STATE_EMPTY */ \ 634 /* SCTP_STATE_EMPTY */ \
648 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ 635 TYPE_SCTP_FUNC(sctp_sf_bug), \
649 /* SCTP_STATE_CLOSED */ \ 636 /* SCTP_STATE_CLOSED */ \
650 {.fn = sctp_sf_error_closed, .name = "sctp_sf_error_closed"}, \ 637 TYPE_SCTP_FUNC(sctp_sf_error_closed), \
651 /* SCTP_STATE_COOKIE_WAIT */ \ 638 /* SCTP_STATE_COOKIE_WAIT */ \
652 {.fn = sctp_sf_do_prm_requestheartbeat, \ 639 TYPE_SCTP_FUNC(sctp_sf_do_prm_requestheartbeat), \
653 .name = "sctp_sf_do_prm_requestheartbeat"}, \
654 /* SCTP_STATE_COOKIE_ECHOED */ \ 640 /* SCTP_STATE_COOKIE_ECHOED */ \
655 {.fn = sctp_sf_do_prm_requestheartbeat, \ 641 TYPE_SCTP_FUNC(sctp_sf_do_prm_requestheartbeat), \
656 .name = "sctp_sf_do_prm_requestheartbeat"}, \
657 /* SCTP_STATE_ESTABLISHED */ \ 642 /* SCTP_STATE_ESTABLISHED */ \
658 {.fn = sctp_sf_do_prm_requestheartbeat, \ 643 TYPE_SCTP_FUNC(sctp_sf_do_prm_requestheartbeat), \
659 .name = "sctp_sf_do_prm_requestheartbeat"}, \
660 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 644 /* SCTP_STATE_SHUTDOWN_PENDING */ \
661 {.fn = sctp_sf_do_prm_requestheartbeat, \ 645 TYPE_SCTP_FUNC(sctp_sf_do_prm_requestheartbeat), \
662 .name = "sctp_sf_do_prm_requestheartbeat"}, \
663 /* SCTP_STATE_SHUTDOWN_SENT */ \ 646 /* SCTP_STATE_SHUTDOWN_SENT */ \
664 {.fn = sctp_sf_do_prm_requestheartbeat, \ 647 TYPE_SCTP_FUNC(sctp_sf_do_prm_requestheartbeat), \
665 .name = "sctp_sf_do_prm_requestheartbeat"}, \
666 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 648 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
667 {.fn = sctp_sf_do_prm_requestheartbeat, \ 649 TYPE_SCTP_FUNC(sctp_sf_do_prm_requestheartbeat), \
668 .name = "sctp_sf_do_prm_requestheartbeat"}, \
669 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 650 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
670 {.fn = sctp_sf_do_prm_requestheartbeat, \ 651 TYPE_SCTP_FUNC(sctp_sf_do_prm_requestheartbeat), \
671 .name = "sctp_sf_do_prm_requestheartbeat"}, \
672} /* TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT */ 652} /* TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT */
673 653
674#define TYPE_SCTP_PRIMITIVE_ASCONF { \ 654#define TYPE_SCTP_PRIMITIVE_ASCONF { \
675 /* SCTP_STATE_EMPTY */ \ 655 /* SCTP_STATE_EMPTY */ \
676 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ 656 TYPE_SCTP_FUNC(sctp_sf_bug), \
677 /* SCTP_STATE_CLOSED */ \ 657 /* SCTP_STATE_CLOSED */ \
678 {.fn = sctp_sf_error_closed, .name = "sctp_sf_error_closed"}, \ 658 TYPE_SCTP_FUNC(sctp_sf_error_closed), \
679 /* SCTP_STATE_COOKIE_WAIT */ \ 659 /* SCTP_STATE_COOKIE_WAIT */ \
680 {.fn = sctp_sf_error_closed, .name = "sctp_sf_error_closed"}, \ 660 TYPE_SCTP_FUNC(sctp_sf_error_closed), \
681 /* SCTP_STATE_COOKIE_ECHOED */ \ 661 /* SCTP_STATE_COOKIE_ECHOED */ \
682 {.fn = sctp_sf_error_closed, .name = "sctp_sf_error_closed"}, \ 662 TYPE_SCTP_FUNC(sctp_sf_error_closed), \
683 /* SCTP_STATE_ESTABLISHED */ \ 663 /* SCTP_STATE_ESTABLISHED */ \
684 {.fn = sctp_sf_do_prm_asconf, .name = "sctp_sf_do_prm_asconf"}, \ 664 TYPE_SCTP_FUNC(sctp_sf_do_prm_asconf), \
685 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 665 /* SCTP_STATE_SHUTDOWN_PENDING */ \
686 {.fn = sctp_sf_error_shutdown, .name = "sctp_sf_error_shutdown"}, \ 666 TYPE_SCTP_FUNC(sctp_sf_error_shutdown), \
687 /* SCTP_STATE_SHUTDOWN_SENT */ \ 667 /* SCTP_STATE_SHUTDOWN_SENT */ \
688 {.fn = sctp_sf_error_shutdown, .name = "sctp_sf_error_shutdown"}, \ 668 TYPE_SCTP_FUNC(sctp_sf_error_shutdown), \
689 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 669 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
690 {.fn = sctp_sf_error_shutdown, .name = "sctp_sf_error_shutdown"}, \ 670 TYPE_SCTP_FUNC(sctp_sf_error_shutdown), \
691 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 671 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
692 {.fn = sctp_sf_error_shutdown, .name = "sctp_sf_error_shutdown"}, \ 672 TYPE_SCTP_FUNC(sctp_sf_error_shutdown), \
693} /* TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT */ 673} /* TYPE_SCTP_PRIMITIVE_REQUESTHEARTBEAT */
694 674
695/* The primary index for this table is the primitive type. 675/* The primary index for this table is the primitive type.
@@ -706,47 +686,44 @@ static const sctp_sm_table_entry_t primitive_event_table[SCTP_NUM_PRIMITIVE_TYPE
706 686
707#define TYPE_SCTP_OTHER_NO_PENDING_TSN { \ 687#define TYPE_SCTP_OTHER_NO_PENDING_TSN { \
708 /* SCTP_STATE_EMPTY */ \ 688 /* SCTP_STATE_EMPTY */ \
709 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ 689 TYPE_SCTP_FUNC(sctp_sf_bug), \
710 /* SCTP_STATE_CLOSED */ \ 690 /* SCTP_STATE_CLOSED */ \
711 {.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \ 691 TYPE_SCTP_FUNC(sctp_sf_ignore_other), \
712 /* SCTP_STATE_COOKIE_WAIT */ \ 692 /* SCTP_STATE_COOKIE_WAIT */ \
713 {.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \ 693 TYPE_SCTP_FUNC(sctp_sf_ignore_other), \
714 /* SCTP_STATE_COOKIE_ECHOED */ \ 694 /* SCTP_STATE_COOKIE_ECHOED */ \
715 {.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \ 695 TYPE_SCTP_FUNC(sctp_sf_ignore_other), \
716 /* SCTP_STATE_ESTABLISHED */ \ 696 /* SCTP_STATE_ESTABLISHED */ \
717 {.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \ 697 TYPE_SCTP_FUNC(sctp_sf_ignore_other), \
718 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 698 /* SCTP_STATE_SHUTDOWN_PENDING */ \
719 {.fn = sctp_sf_do_9_2_start_shutdown, \ 699 TYPE_SCTP_FUNC(sctp_sf_do_9_2_start_shutdown), \
720 .name = "sctp_do_9_2_start_shutdown"}, \
721 /* SCTP_STATE_SHUTDOWN_SENT */ \ 700 /* SCTP_STATE_SHUTDOWN_SENT */ \
722 {.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \ 701 TYPE_SCTP_FUNC(sctp_sf_ignore_other), \
723 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 702 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
724 {.fn = sctp_sf_do_9_2_shutdown_ack, \ 703 TYPE_SCTP_FUNC(sctp_sf_do_9_2_shutdown_ack), \
725 .name = "sctp_sf_do_9_2_shutdown_ack"}, \
726 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 704 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
727 {.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \ 705 TYPE_SCTP_FUNC(sctp_sf_ignore_other), \
728} 706}
729 707
730#define TYPE_SCTP_OTHER_ICMP_PROTO_UNREACH { \ 708#define TYPE_SCTP_OTHER_ICMP_PROTO_UNREACH { \
731 /* SCTP_STATE_EMPTY */ \ 709 /* SCTP_STATE_EMPTY */ \
732 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ 710 TYPE_SCTP_FUNC(sctp_sf_bug), \
733 /* SCTP_STATE_CLOSED */ \ 711 /* SCTP_STATE_CLOSED */ \
734 {.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \ 712 TYPE_SCTP_FUNC(sctp_sf_ignore_other), \
735 /* SCTP_STATE_COOKIE_WAIT */ \ 713 /* SCTP_STATE_COOKIE_WAIT */ \
736 {.fn = sctp_sf_cookie_wait_icmp_abort, \ 714 TYPE_SCTP_FUNC(sctp_sf_cookie_wait_icmp_abort), \
737 .name = "sctp_sf_cookie_wait_icmp_abort"}, \
738 /* SCTP_STATE_COOKIE_ECHOED */ \ 715 /* SCTP_STATE_COOKIE_ECHOED */ \
739 {.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \ 716 TYPE_SCTP_FUNC(sctp_sf_ignore_other), \
740 /* SCTP_STATE_ESTABLISHED */ \ 717 /* SCTP_STATE_ESTABLISHED */ \
741 {.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \ 718 TYPE_SCTP_FUNC(sctp_sf_ignore_other), \
742 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 719 /* SCTP_STATE_SHUTDOWN_PENDING */ \
743 {.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \ 720 TYPE_SCTP_FUNC(sctp_sf_ignore_other), \
744 /* SCTP_STATE_SHUTDOWN_SENT */ \ 721 /* SCTP_STATE_SHUTDOWN_SENT */ \
745 {.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \ 722 TYPE_SCTP_FUNC(sctp_sf_ignore_other), \
746 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 723 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
747 {.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \ 724 TYPE_SCTP_FUNC(sctp_sf_ignore_other), \
748 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 725 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
749 {.fn = sctp_sf_ignore_other, .name = "sctp_sf_ignore_other"}, \ 726 TYPE_SCTP_FUNC(sctp_sf_ignore_other), \
750} 727}
751 728
752static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES] = { 729static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_STATE_NUM_STATES] = {
@@ -756,215 +733,212 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_
756 733
757#define TYPE_SCTP_EVENT_TIMEOUT_NONE { \ 734#define TYPE_SCTP_EVENT_TIMEOUT_NONE { \
758 /* SCTP_STATE_EMPTY */ \ 735 /* SCTP_STATE_EMPTY */ \
759 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ 736 TYPE_SCTP_FUNC(sctp_sf_bug), \
760 /* SCTP_STATE_CLOSED */ \ 737 /* SCTP_STATE_CLOSED */ \
761 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ 738 TYPE_SCTP_FUNC(sctp_sf_bug), \
762 /* SCTP_STATE_COOKIE_WAIT */ \ 739 /* SCTP_STATE_COOKIE_WAIT */ \
763 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ 740 TYPE_SCTP_FUNC(sctp_sf_bug), \
764 /* SCTP_STATE_COOKIE_ECHOED */ \ 741 /* SCTP_STATE_COOKIE_ECHOED */ \
765 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ 742 TYPE_SCTP_FUNC(sctp_sf_bug), \
766 /* SCTP_STATE_ESTABLISHED */ \ 743 /* SCTP_STATE_ESTABLISHED */ \
767 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ 744 TYPE_SCTP_FUNC(sctp_sf_bug), \
768 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 745 /* SCTP_STATE_SHUTDOWN_PENDING */ \
769 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ 746 TYPE_SCTP_FUNC(sctp_sf_bug), \
770 /* SCTP_STATE_SHUTDOWN_SENT */ \ 747 /* SCTP_STATE_SHUTDOWN_SENT */ \
771 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ 748 TYPE_SCTP_FUNC(sctp_sf_bug), \
772 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 749 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
773 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ 750 TYPE_SCTP_FUNC(sctp_sf_bug), \
774 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 751 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
775 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ 752 TYPE_SCTP_FUNC(sctp_sf_bug), \
776} 753}
777 754
778#define TYPE_SCTP_EVENT_TIMEOUT_T1_COOKIE { \ 755#define TYPE_SCTP_EVENT_TIMEOUT_T1_COOKIE { \
779 /* SCTP_STATE_EMPTY */ \ 756 /* SCTP_STATE_EMPTY */ \
780 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ 757 TYPE_SCTP_FUNC(sctp_sf_bug), \
781 /* SCTP_STATE_CLOSED */ \ 758 /* SCTP_STATE_CLOSED */ \
782 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 759 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
783 /* SCTP_STATE_COOKIE_WAIT */ \ 760 /* SCTP_STATE_COOKIE_WAIT */ \
784 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ 761 TYPE_SCTP_FUNC(sctp_sf_bug), \
785 /* SCTP_STATE_COOKIE_ECHOED */ \ 762 /* SCTP_STATE_COOKIE_ECHOED */ \
786 {.fn = sctp_sf_t1_cookie_timer_expire, \ 763 TYPE_SCTP_FUNC(sctp_sf_t1_cookie_timer_expire), \
787 .name = "sctp_sf_t1_cookie_timer_expire"}, \
788 /* SCTP_STATE_ESTABLISHED */ \ 764 /* SCTP_STATE_ESTABLISHED */ \
789 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 765 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
790 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 766 /* SCTP_STATE_SHUTDOWN_PENDING */ \
791 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 767 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
792 /* SCTP_STATE_SHUTDOWN_SENT */ \ 768 /* SCTP_STATE_SHUTDOWN_SENT */ \
793 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 769 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
794 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 770 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
795 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 771 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
796 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 772 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
797 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 773 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
798} 774}
799 775
800#define TYPE_SCTP_EVENT_TIMEOUT_T1_INIT { \ 776#define TYPE_SCTP_EVENT_TIMEOUT_T1_INIT { \
801 /* SCTP_STATE_EMPTY */ \ 777 /* SCTP_STATE_EMPTY */ \
802 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ 778 TYPE_SCTP_FUNC(sctp_sf_bug), \
803 /* SCTP_STATE_CLOSED */ \ 779 /* SCTP_STATE_CLOSED */ \
804 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 780 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
805 /* SCTP_STATE_COOKIE_WAIT */ \ 781 /* SCTP_STATE_COOKIE_WAIT */ \
806 {.fn = sctp_sf_t1_init_timer_expire, \ 782 TYPE_SCTP_FUNC(sctp_sf_t1_init_timer_expire), \
807 .name = "sctp_sf_t1_init_timer_expire"}, \
808 /* SCTP_STATE_COOKIE_ECHOED */ \ 783 /* SCTP_STATE_COOKIE_ECHOED */ \
809 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 784 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
810 /* SCTP_STATE_ESTABLISHED */ \ 785 /* SCTP_STATE_ESTABLISHED */ \
811 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 786 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
812 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 787 /* SCTP_STATE_SHUTDOWN_PENDING */ \
813 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 788 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
814 /* SCTP_STATE_SHUTDOWN_SENT */ \ 789 /* SCTP_STATE_SHUTDOWN_SENT */ \
815 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 790 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
816 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 791 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
817 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 792 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
818 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 793 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
819 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 794 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
820} 795}
821 796
822#define TYPE_SCTP_EVENT_TIMEOUT_T2_SHUTDOWN { \ 797#define TYPE_SCTP_EVENT_TIMEOUT_T2_SHUTDOWN { \
823 /* SCTP_STATE_EMPTY */ \ 798 /* SCTP_STATE_EMPTY */ \
824 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ 799 TYPE_SCTP_FUNC(sctp_sf_bug), \
825 /* SCTP_STATE_CLOSED */ \ 800 /* SCTP_STATE_CLOSED */ \
826 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 801 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
827 /* SCTP_STATE_COOKIE_WAIT */ \ 802 /* SCTP_STATE_COOKIE_WAIT */ \
828 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 803 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
829 /* SCTP_STATE_COOKIE_ECHOED */ \ 804 /* SCTP_STATE_COOKIE_ECHOED */ \
830 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 805 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
831 /* SCTP_STATE_ESTABLISHED */ \ 806 /* SCTP_STATE_ESTABLISHED */ \
832 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 807 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
833 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 808 /* SCTP_STATE_SHUTDOWN_PENDING */ \
834 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 809 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
835 /* SCTP_STATE_SHUTDOWN_SENT */ \ 810 /* SCTP_STATE_SHUTDOWN_SENT */ \
836 {.fn = sctp_sf_t2_timer_expire, .name = "sctp_sf_t2_timer_expire"}, \ 811 TYPE_SCTP_FUNC(sctp_sf_t2_timer_expire), \
837 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 812 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
838 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 813 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
839 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 814 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
840 {.fn = sctp_sf_t2_timer_expire, .name = "sctp_sf_t2_timer_expire"}, \ 815 TYPE_SCTP_FUNC(sctp_sf_t2_timer_expire), \
841} 816}
842 817
843#define TYPE_SCTP_EVENT_TIMEOUT_T3_RTX { \ 818#define TYPE_SCTP_EVENT_TIMEOUT_T3_RTX { \
844 /* SCTP_STATE_EMPTY */ \ 819 /* SCTP_STATE_EMPTY */ \
845 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ 820 TYPE_SCTP_FUNC(sctp_sf_bug), \
846 /* SCTP_STATE_CLOSED */ \ 821 /* SCTP_STATE_CLOSED */ \
847 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 822 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
848 /* SCTP_STATE_COOKIE_WAIT */ \ 823 /* SCTP_STATE_COOKIE_WAIT */ \
849 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 824 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
850 /* SCTP_STATE_COOKIE_ECHOED */ \ 825 /* SCTP_STATE_COOKIE_ECHOED */ \
851 {.fn = sctp_sf_do_6_3_3_rtx, .name = "sctp_sf_do_6_3_3_rtx"}, \ 826 TYPE_SCTP_FUNC(sctp_sf_do_6_3_3_rtx), \
852 /* SCTP_STATE_ESTABLISHED */ \ 827 /* SCTP_STATE_ESTABLISHED */ \
853 {.fn = sctp_sf_do_6_3_3_rtx, .name = "sctp_sf_do_6_3_3_rtx"}, \ 828 TYPE_SCTP_FUNC(sctp_sf_do_6_3_3_rtx), \
854 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 829 /* SCTP_STATE_SHUTDOWN_PENDING */ \
855 {.fn = sctp_sf_do_6_3_3_rtx, .name = "sctp_sf_do_6_3_3_rtx"}, \ 830 TYPE_SCTP_FUNC(sctp_sf_do_6_3_3_rtx), \
856 /* SCTP_STATE_SHUTDOWN_SENT */ \ 831 /* SCTP_STATE_SHUTDOWN_SENT */ \
857 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 832 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
858 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 833 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
859 {.fn = sctp_sf_do_6_3_3_rtx, .name = "sctp_sf_do_6_3_3_rtx"}, \ 834 TYPE_SCTP_FUNC(sctp_sf_do_6_3_3_rtx), \
860 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 835 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
861 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 836 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
862} 837}
863 838
864#define TYPE_SCTP_EVENT_TIMEOUT_T4_RTO { \ 839#define TYPE_SCTP_EVENT_TIMEOUT_T4_RTO { \
865 /* SCTP_STATE_EMPTY */ \ 840 /* SCTP_STATE_EMPTY */ \
866 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ 841 TYPE_SCTP_FUNC(sctp_sf_bug), \
867 /* SCTP_STATE_CLOSED */ \ 842 /* SCTP_STATE_CLOSED */ \
868 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 843 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
869 /* SCTP_STATE_COOKIE_WAIT */ \ 844 /* SCTP_STATE_COOKIE_WAIT */ \
870 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 845 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
871 /* SCTP_STATE_COOKIE_ECHOED */ \ 846 /* SCTP_STATE_COOKIE_ECHOED */ \
872 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 847 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
873 /* SCTP_STATE_ESTABLISHED */ \ 848 /* SCTP_STATE_ESTABLISHED */ \
874 {.fn = sctp_sf_t4_timer_expire, .name = "sctp_sf_t4_timer_expire"}, \ 849 TYPE_SCTP_FUNC(sctp_sf_t4_timer_expire), \
875 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 850 /* SCTP_STATE_SHUTDOWN_PENDING */ \
876 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 851 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
877 /* SCTP_STATE_SHUTDOWN_SENT */ \ 852 /* SCTP_STATE_SHUTDOWN_SENT */ \
878 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 853 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
879 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 854 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
880 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 855 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
881 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 856 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
882 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 857 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
883} 858}
884 859
885#define TYPE_SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD { \ 860#define TYPE_SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD { \
886 /* SCTP_STATE_EMPTY */ \ 861 /* SCTP_STATE_EMPTY */ \
887 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ 862 TYPE_SCTP_FUNC(sctp_sf_bug), \
888 /* SCTP_STATE_CLOSED */ \ 863 /* SCTP_STATE_CLOSED */ \
889 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 864 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
890 /* SCTP_STATE_COOKIE_WAIT */ \ 865 /* SCTP_STATE_COOKIE_WAIT */ \
891 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 866 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
892 /* SCTP_STATE_COOKIE_ECHOED */ \ 867 /* SCTP_STATE_COOKIE_ECHOED */ \
893 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 868 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
894 /* SCTP_STATE_ESTABLISHED */ \ 869 /* SCTP_STATE_ESTABLISHED */ \
895 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 870 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
896 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 871 /* SCTP_STATE_SHUTDOWN_PENDING */ \
897 {.fn = sctp_sf_t5_timer_expire, .name = "sctp_sf_t5_timer_expire"}, \ 872 TYPE_SCTP_FUNC(sctp_sf_t5_timer_expire), \
898 /* SCTP_STATE_SHUTDOWN_SENT */ \ 873 /* SCTP_STATE_SHUTDOWN_SENT */ \
899 {.fn = sctp_sf_t5_timer_expire, .name = "sctp_sf_t5_timer_expire"}, \ 874 TYPE_SCTP_FUNC(sctp_sf_t5_timer_expire), \
900 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 875 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
901 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 876 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
902 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 877 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
903 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 878 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
904} 879}
905 880
906#define TYPE_SCTP_EVENT_TIMEOUT_HEARTBEAT { \ 881#define TYPE_SCTP_EVENT_TIMEOUT_HEARTBEAT { \
907 /* SCTP_STATE_EMPTY */ \ 882 /* SCTP_STATE_EMPTY */ \
908 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ 883 TYPE_SCTP_FUNC(sctp_sf_bug), \
909 /* SCTP_STATE_CLOSED */ \ 884 /* SCTP_STATE_CLOSED */ \
910 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 885 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
911 /* SCTP_STATE_COOKIE_WAIT */ \ 886 /* SCTP_STATE_COOKIE_WAIT */ \
912 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 887 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
913 /* SCTP_STATE_COOKIE_ECHOED */ \ 888 /* SCTP_STATE_COOKIE_ECHOED */ \
914 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 889 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
915 /* SCTP_STATE_ESTABLISHED */ \ 890 /* SCTP_STATE_ESTABLISHED */ \
916 {.fn = sctp_sf_sendbeat_8_3, .name = "sctp_sf_sendbeat_8_3"}, \ 891 TYPE_SCTP_FUNC(sctp_sf_sendbeat_8_3), \
917 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 892 /* SCTP_STATE_SHUTDOWN_PENDING */ \
918 {.fn = sctp_sf_sendbeat_8_3, .name = "sctp_sf_sendbeat_8_3"}, \ 893 TYPE_SCTP_FUNC(sctp_sf_sendbeat_8_3), \
919 /* SCTP_STATE_SHUTDOWN_SENT */ \ 894 /* SCTP_STATE_SHUTDOWN_SENT */ \
920 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 895 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
921 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 896 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
922 {.fn = sctp_sf_sendbeat_8_3, .name = "sctp_sf_sendbeat_8_3"}, \ 897 TYPE_SCTP_FUNC(sctp_sf_sendbeat_8_3), \
923 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 898 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
924 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 899 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
925} 900}
926 901
927#define TYPE_SCTP_EVENT_TIMEOUT_SACK { \ 902#define TYPE_SCTP_EVENT_TIMEOUT_SACK { \
928 /* SCTP_STATE_EMPTY */ \ 903 /* SCTP_STATE_EMPTY */ \
929 {.fn = sctp_sf_bug, .name = "sctp_sf_bug"}, \ 904 TYPE_SCTP_FUNC(sctp_sf_bug), \
930 /* SCTP_STATE_CLOSED */ \ 905 /* SCTP_STATE_CLOSED */ \
931 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 906 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
932 /* SCTP_STATE_COOKIE_WAIT */ \ 907 /* SCTP_STATE_COOKIE_WAIT */ \
933 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 908 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
934 /* SCTP_STATE_COOKIE_ECHOED */ \ 909 /* SCTP_STATE_COOKIE_ECHOED */ \
935 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 910 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
936 /* SCTP_STATE_ESTABLISHED */ \ 911 /* SCTP_STATE_ESTABLISHED */ \
937 {.fn = sctp_sf_do_6_2_sack, .name = "sctp_sf_do_6_2_sack"}, \ 912 TYPE_SCTP_FUNC(sctp_sf_do_6_2_sack), \
938 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 913 /* SCTP_STATE_SHUTDOWN_PENDING */ \
939 {.fn = sctp_sf_do_6_2_sack, .name = "sctp_sf_do_6_2_sack"}, \ 914 TYPE_SCTP_FUNC(sctp_sf_do_6_2_sack), \
940 /* SCTP_STATE_SHUTDOWN_SENT */ \ 915 /* SCTP_STATE_SHUTDOWN_SENT */ \
941 {.fn = sctp_sf_do_6_2_sack, .name = "sctp_sf_do_6_2_sack"}, \ 916 TYPE_SCTP_FUNC(sctp_sf_do_6_2_sack), \
942 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 917 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
943 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 918 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
944 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 919 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
945 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 920 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
946} 921}
947 922
948#define TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE { \ 923#define TYPE_SCTP_EVENT_TIMEOUT_AUTOCLOSE { \
949 /* SCTP_STATE_EMPTY */ \ 924 /* SCTP_STATE_EMPTY */ \
950 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 925 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
951 /* SCTP_STATE_CLOSED */ \ 926 /* SCTP_STATE_CLOSED */ \
952 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 927 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
953 /* SCTP_STATE_COOKIE_WAIT */ \ 928 /* SCTP_STATE_COOKIE_WAIT */ \
954 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 929 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
955 /* SCTP_STATE_COOKIE_ECHOED */ \ 930 /* SCTP_STATE_COOKIE_ECHOED */ \
956 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 931 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
957 /* SCTP_STATE_ESTABLISHED */ \ 932 /* SCTP_STATE_ESTABLISHED */ \
958 {.fn = sctp_sf_autoclose_timer_expire, \ 933 TYPE_SCTP_FUNC(sctp_sf_autoclose_timer_expire), \
959 .name = "sctp_sf_autoclose_timer_expire"}, \
960 /* SCTP_STATE_SHUTDOWN_PENDING */ \ 934 /* SCTP_STATE_SHUTDOWN_PENDING */ \
961 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 935 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
962 /* SCTP_STATE_SHUTDOWN_SENT */ \ 936 /* SCTP_STATE_SHUTDOWN_SENT */ \
963 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 937 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
964 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ 938 /* SCTP_STATE_SHUTDOWN_RECEIVED */ \
965 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 939 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
966 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \ 940 /* SCTP_STATE_SHUTDOWN_ACK_SENT */ \
967 {.fn = sctp_sf_timer_ignore, .name = "sctp_sf_timer_ignore"}, \ 941 TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \
968} 942}
969 943
970static const sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES] = { 944static const sctp_sm_table_entry_t timeout_event_table[SCTP_NUM_TIMEOUT_TYPES][SCTP_STATE_NUM_STATES] = {
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 935bc9187f..388d0fb1a3 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -107,7 +107,7 @@ static void sctp_sock_migrate(struct sock *, struct sock *,
107 struct sctp_association *, sctp_socket_type_t); 107 struct sctp_association *, sctp_socket_type_t);
108static char *sctp_hmac_alg = SCTP_COOKIE_HMAC_ALG; 108static char *sctp_hmac_alg = SCTP_COOKIE_HMAC_ALG;
109 109
110extern kmem_cache_t *sctp_bucket_cachep; 110extern struct kmem_cache *sctp_bucket_cachep;
111 111
112/* Get the sndbuf space available at the time on the association. */ 112/* Get the sndbuf space available at the time on the association. */
113static inline int sctp_wspace(struct sctp_association *asoc) 113static inline int sctp_wspace(struct sctp_association *asoc)
@@ -229,11 +229,9 @@ static struct sctp_transport *sctp_addr_id2transport(struct sock *sk,
229 struct sctp_transport *transport; 229 struct sctp_transport *transport;
230 union sctp_addr *laddr = (union sctp_addr *)addr; 230 union sctp_addr *laddr = (union sctp_addr *)addr;
231 231
232 laddr->v4.sin_port = ntohs(laddr->v4.sin_port);
233 addr_asoc = sctp_endpoint_lookup_assoc(sctp_sk(sk)->ep, 232 addr_asoc = sctp_endpoint_lookup_assoc(sctp_sk(sk)->ep,
234 (union sctp_addr *)addr, 233 laddr,
235 &transport); 234 &transport);
236 laddr->v4.sin_port = htons(laddr->v4.sin_port);
237 235
238 if (!addr_asoc) 236 if (!addr_asoc)
239 return NULL; 237 return NULL;
@@ -368,9 +366,7 @@ SCTP_STATIC int sctp_do_bind(struct sock *sk, union sctp_addr *addr, int len)
368 sctp_write_lock(&ep->base.addr_lock); 366 sctp_write_lock(&ep->base.addr_lock);
369 367
370 /* Use GFP_ATOMIC since BHs are disabled. */ 368 /* Use GFP_ATOMIC since BHs are disabled. */
371 addr->v4.sin_port = ntohs(addr->v4.sin_port);
372 ret = sctp_add_bind_addr(bp, addr, 1, GFP_ATOMIC); 369 ret = sctp_add_bind_addr(bp, addr, 1, GFP_ATOMIC);
373 addr->v4.sin_port = htons(addr->v4.sin_port);
374 sctp_write_unlock(&ep->base.addr_lock); 370 sctp_write_unlock(&ep->base.addr_lock);
375 sctp_local_bh_enable(); 371 sctp_local_bh_enable();
376 372
@@ -572,7 +568,6 @@ static int sctp_send_asconf_add_ip(struct sock *sk,
572 addr = (union sctp_addr *)addr_buf; 568 addr = (union sctp_addr *)addr_buf;
573 af = sctp_get_af_specific(addr->v4.sin_family); 569 af = sctp_get_af_specific(addr->v4.sin_family);
574 memcpy(&saveaddr, addr, af->sockaddr_len); 570 memcpy(&saveaddr, addr, af->sockaddr_len);
575 saveaddr.v4.sin_port = ntohs(saveaddr.v4.sin_port);
576 retval = sctp_add_bind_addr(bp, &saveaddr, 0, 571 retval = sctp_add_bind_addr(bp, &saveaddr, 0,
577 GFP_ATOMIC); 572 GFP_ATOMIC);
578 addr_buf += af->sockaddr_len; 573 addr_buf += af->sockaddr_len;
@@ -607,9 +602,8 @@ int sctp_bindx_rem(struct sock *sk, struct sockaddr *addrs, int addrcnt)
607 int cnt; 602 int cnt;
608 struct sctp_bind_addr *bp = &ep->base.bind_addr; 603 struct sctp_bind_addr *bp = &ep->base.bind_addr;
609 int retval = 0; 604 int retval = 0;
610 union sctp_addr saveaddr;
611 void *addr_buf; 605 void *addr_buf;
612 struct sockaddr *sa_addr; 606 union sctp_addr *sa_addr;
613 struct sctp_af *af; 607 struct sctp_af *af;
614 608
615 SCTP_DEBUG_PRINTK("sctp_bindx_rem (sk: %p, addrs: %p, addrcnt: %d)\n", 609 SCTP_DEBUG_PRINTK("sctp_bindx_rem (sk: %p, addrs: %p, addrcnt: %d)\n",
@@ -627,19 +621,13 @@ int sctp_bindx_rem(struct sock *sk, struct sockaddr *addrs, int addrcnt)
627 goto err_bindx_rem; 621 goto err_bindx_rem;
628 } 622 }
629 623
630 /* The list may contain either IPv4 or IPv6 address; 624 sa_addr = (union sctp_addr *)addr_buf;
631 * determine the address length to copy the address to 625 af = sctp_get_af_specific(sa_addr->sa.sa_family);
632 * saveaddr.
633 */
634 sa_addr = (struct sockaddr *)addr_buf;
635 af = sctp_get_af_specific(sa_addr->sa_family);
636 if (!af) { 626 if (!af) {
637 retval = -EINVAL; 627 retval = -EINVAL;
638 goto err_bindx_rem; 628 goto err_bindx_rem;
639 } 629 }
640 memcpy(&saveaddr, sa_addr, af->sockaddr_len); 630 if (sa_addr->v4.sin_port != htons(bp->port)) {
641 saveaddr.v4.sin_port = ntohs(saveaddr.v4.sin_port);
642 if (saveaddr.v4.sin_port != bp->port) {
643 retval = -EINVAL; 631 retval = -EINVAL;
644 goto err_bindx_rem; 632 goto err_bindx_rem;
645 } 633 }
@@ -654,7 +642,7 @@ int sctp_bindx_rem(struct sock *sk, struct sockaddr *addrs, int addrcnt)
654 sctp_local_bh_disable(); 642 sctp_local_bh_disable();
655 sctp_write_lock(&ep->base.addr_lock); 643 sctp_write_lock(&ep->base.addr_lock);
656 644
657 retval = sctp_del_bind_addr(bp, &saveaddr); 645 retval = sctp_del_bind_addr(bp, sa_addr);
658 646
659 sctp_write_unlock(&ep->base.addr_lock); 647 sctp_write_unlock(&ep->base.addr_lock);
660 sctp_local_bh_enable(); 648 sctp_local_bh_enable();
@@ -693,7 +681,6 @@ static int sctp_send_asconf_del_ip(struct sock *sk,
693 struct sctp_bind_addr *bp; 681 struct sctp_bind_addr *bp;
694 struct sctp_chunk *chunk; 682 struct sctp_chunk *chunk;
695 union sctp_addr *laddr; 683 union sctp_addr *laddr;
696 union sctp_addr saveaddr;
697 void *addr_buf; 684 void *addr_buf;
698 struct sctp_af *af; 685 struct sctp_af *af;
699 struct list_head *pos, *pos1; 686 struct list_head *pos, *pos1;
@@ -773,13 +760,11 @@ static int sctp_send_asconf_del_ip(struct sock *sk,
773 for (i = 0; i < addrcnt; i++) { 760 for (i = 0; i < addrcnt; i++) {
774 laddr = (union sctp_addr *)addr_buf; 761 laddr = (union sctp_addr *)addr_buf;
775 af = sctp_get_af_specific(laddr->v4.sin_family); 762 af = sctp_get_af_specific(laddr->v4.sin_family);
776 memcpy(&saveaddr, laddr, af->sockaddr_len);
777 saveaddr.v4.sin_port = ntohs(saveaddr.v4.sin_port);
778 list_for_each(pos1, &bp->address_list) { 763 list_for_each(pos1, &bp->address_list) {
779 saddr = list_entry(pos1, 764 saddr = list_entry(pos1,
780 struct sctp_sockaddr_entry, 765 struct sctp_sockaddr_entry,
781 list); 766 list);
782 if (sctp_cmp_addr_exact(&saddr->a, &saveaddr)) 767 if (sctp_cmp_addr_exact(&saddr->a, laddr))
783 saddr->use_as_src = 0; 768 saddr->use_as_src = 0;
784 } 769 }
785 addr_buf += af->sockaddr_len; 770 addr_buf += af->sockaddr_len;
@@ -979,7 +964,7 @@ static int __sctp_connect(struct sock* sk,
979 int err = 0; 964 int err = 0;
980 int addrcnt = 0; 965 int addrcnt = 0;
981 int walk_size = 0; 966 int walk_size = 0;
982 struct sockaddr *sa_addr; 967 union sctp_addr *sa_addr;
983 void *addr_buf; 968 void *addr_buf;
984 969
985 sp = sctp_sk(sk); 970 sp = sctp_sk(sk);
@@ -999,8 +984,8 @@ static int __sctp_connect(struct sock* sk,
999 /* Walk through the addrs buffer and count the number of addresses. */ 984 /* Walk through the addrs buffer and count the number of addresses. */
1000 addr_buf = kaddrs; 985 addr_buf = kaddrs;
1001 while (walk_size < addrs_size) { 986 while (walk_size < addrs_size) {
1002 sa_addr = (struct sockaddr *)addr_buf; 987 sa_addr = (union sctp_addr *)addr_buf;
1003 af = sctp_get_af_specific(sa_addr->sa_family); 988 af = sctp_get_af_specific(sa_addr->sa.sa_family);
1004 989
1005 /* If the address family is not supported or if this address 990 /* If the address family is not supported or if this address
1006 * causes the address buffer to overflow return EINVAL. 991 * causes the address buffer to overflow return EINVAL.
@@ -1010,18 +995,16 @@ static int __sctp_connect(struct sock* sk,
1010 goto out_free; 995 goto out_free;
1011 } 996 }
1012 997
1013 err = sctp_verify_addr(sk, (union sctp_addr *)sa_addr, 998 err = sctp_verify_addr(sk, sa_addr, af->sockaddr_len);
1014 af->sockaddr_len);
1015 if (err) 999 if (err)
1016 goto out_free; 1000 goto out_free;
1017 1001
1018 memcpy(&to, sa_addr, af->sockaddr_len); 1002 memcpy(&to, sa_addr, af->sockaddr_len);
1019 to.v4.sin_port = ntohs(to.v4.sin_port);
1020 1003
1021 /* Check if there already is a matching association on the 1004 /* Check if there already is a matching association on the
1022 * endpoint (other than the one created here). 1005 * endpoint (other than the one created here).
1023 */ 1006 */
1024 asoc2 = sctp_endpoint_lookup_assoc(ep, &to, &transport); 1007 asoc2 = sctp_endpoint_lookup_assoc(ep, sa_addr, &transport);
1025 if (asoc2 && asoc2 != asoc) { 1008 if (asoc2 && asoc2 != asoc) {
1026 if (asoc2->state >= SCTP_STATE_ESTABLISHED) 1009 if (asoc2->state >= SCTP_STATE_ESTABLISHED)
1027 err = -EISCONN; 1010 err = -EISCONN;
@@ -1034,7 +1017,7 @@ static int __sctp_connect(struct sock* sk,
1034 * make sure that there is no peeled-off association matching 1017 * make sure that there is no peeled-off association matching
1035 * the peer address even on another socket. 1018 * the peer address even on another socket.
1036 */ 1019 */
1037 if (sctp_endpoint_is_peeled_off(ep, &to)) { 1020 if (sctp_endpoint_is_peeled_off(ep, sa_addr)) {
1038 err = -EADDRNOTAVAIL; 1021 err = -EADDRNOTAVAIL;
1039 goto out_free; 1022 goto out_free;
1040 } 1023 }
@@ -1065,7 +1048,7 @@ static int __sctp_connect(struct sock* sk,
1065 } 1048 }
1066 } 1049 }
1067 1050
1068 scope = sctp_scope(&to); 1051 scope = sctp_scope(sa_addr);
1069 asoc = sctp_association_new(ep, sk, scope, GFP_KERNEL); 1052 asoc = sctp_association_new(ep, sk, scope, GFP_KERNEL);
1070 if (!asoc) { 1053 if (!asoc) {
1071 err = -ENOMEM; 1054 err = -ENOMEM;
@@ -1074,7 +1057,7 @@ static int __sctp_connect(struct sock* sk,
1074 } 1057 }
1075 1058
1076 /* Prime the peer's transport structures. */ 1059 /* Prime the peer's transport structures. */
1077 transport = sctp_assoc_add_peer(asoc, &to, GFP_KERNEL, 1060 transport = sctp_assoc_add_peer(asoc, sa_addr, GFP_KERNEL,
1078 SCTP_UNKNOWN); 1061 SCTP_UNKNOWN);
1079 if (!transport) { 1062 if (!transport) {
1080 err = -ENOMEM; 1063 err = -ENOMEM;
@@ -1427,11 +1410,6 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
1427 if (msg_namelen > sizeof(to)) 1410 if (msg_namelen > sizeof(to))
1428 msg_namelen = sizeof(to); 1411 msg_namelen = sizeof(to);
1429 memcpy(&to, msg->msg_name, msg_namelen); 1412 memcpy(&to, msg->msg_name, msg_namelen);
1430 SCTP_DEBUG_PRINTK("Just memcpy'd. msg_name is "
1431 "0x%x:%u.\n",
1432 to.v4.sin_addr.s_addr, to.v4.sin_port);
1433
1434 to.v4.sin_port = ntohs(to.v4.sin_port);
1435 msg_name = msg->msg_name; 1413 msg_name = msg->msg_name;
1436 } 1414 }
1437 1415
@@ -2753,17 +2731,57 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva
2753 return err; 2731 return err;
2754} 2732}
2755 2733
2756static int sctp_setsockopt_adaption_layer(struct sock *sk, char __user *optval, 2734static int sctp_setsockopt_adaptation_layer(struct sock *sk, char __user *optval,
2757 int optlen) 2735 int optlen)
2758{ 2736{
2759 struct sctp_setadaption adaption; 2737 struct sctp_setadaptation adaptation;
2738
2739 if (optlen != sizeof(struct sctp_setadaptation))
2740 return -EINVAL;
2741 if (copy_from_user(&adaptation, optval, optlen))
2742 return -EFAULT;
2743
2744 sctp_sk(sk)->adaptation_ind = adaptation.ssb_adaptation_ind;
2745
2746 return 0;
2747}
2748
2749/*
2750 * 7.1.29. Set or Get the default context (SCTP_CONTEXT)
2751 *
2752 * The context field in the sctp_sndrcvinfo structure is normally only
2753 * used when a failed message is retrieved holding the value that was
2754 * sent down on the actual send call. This option allows the setting of
2755 * a default context on an association basis that will be received on
2756 * reading messages from the peer. This is especially helpful in the
2757 * one-2-many model for an application to keep some reference to an
2758 * internal state machine that is processing messages on the
2759 * association. Note that the setting of this value only effects
2760 * received messages from the peer and does not effect the value that is
2761 * saved with outbound messages.
2762 */
2763static int sctp_setsockopt_context(struct sock *sk, char __user *optval,
2764 int optlen)
2765{
2766 struct sctp_assoc_value params;
2767 struct sctp_sock *sp;
2768 struct sctp_association *asoc;
2760 2769
2761 if (optlen != sizeof(struct sctp_setadaption)) 2770 if (optlen != sizeof(struct sctp_assoc_value))
2762 return -EINVAL; 2771 return -EINVAL;
2763 if (copy_from_user(&adaption, optval, optlen)) 2772 if (copy_from_user(&params, optval, optlen))
2764 return -EFAULT; 2773 return -EFAULT;
2765 2774
2766 sctp_sk(sk)->adaption_ind = adaption.ssb_adaption_ind; 2775 sp = sctp_sk(sk);
2776
2777 if (params.assoc_id != 0) {
2778 asoc = sctp_id2assoc(sk, params.assoc_id);
2779 if (!asoc)
2780 return -EINVAL;
2781 asoc->default_rcv_context = params.assoc_value;
2782 } else {
2783 sp->default_rcv_context = params.assoc_value;
2784 }
2767 2785
2768 return 0; 2786 return 0;
2769} 2787}
@@ -2876,8 +2894,11 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname,
2876 case SCTP_MAXSEG: 2894 case SCTP_MAXSEG:
2877 retval = sctp_setsockopt_maxseg(sk, optval, optlen); 2895 retval = sctp_setsockopt_maxseg(sk, optval, optlen);
2878 break; 2896 break;
2879 case SCTP_ADAPTION_LAYER: 2897 case SCTP_ADAPTATION_LAYER:
2880 retval = sctp_setsockopt_adaption_layer(sk, optval, optlen); 2898 retval = sctp_setsockopt_adaptation_layer(sk, optval, optlen);
2899 break;
2900 case SCTP_CONTEXT:
2901 retval = sctp_setsockopt_context(sk, optval, optlen);
2881 break; 2902 break;
2882 2903
2883 default: 2904 default:
@@ -3038,6 +3059,8 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
3038 sp->default_context = 0; 3059 sp->default_context = 0;
3039 sp->default_timetolive = 0; 3060 sp->default_timetolive = 0;
3040 3061
3062 sp->default_rcv_context = 0;
3063
3041 /* Initialize default setup parameters. These parameters 3064 /* Initialize default setup parameters. These parameters
3042 * can be modified with the SCTP_INITMSG socket option or 3065 * can be modified with the SCTP_INITMSG socket option or
3043 * overridden by the SCTP_INIT CMSG. 3066 * overridden by the SCTP_INIT CMSG.
@@ -3100,7 +3123,7 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
3100 /* User specified fragmentation limit. */ 3123 /* User specified fragmentation limit. */
3101 sp->user_frag = 0; 3124 sp->user_frag = 0;
3102 3125
3103 sp->adaption_ind = 0; 3126 sp->adaptation_ind = 0;
3104 3127
3105 sp->pf = sctp_get_pf_specific(sk->sk_family); 3128 sp->pf = sctp_get_pf_specific(sk->sk_family);
3106 3129
@@ -3217,8 +3240,8 @@ static int sctp_getsockopt_sctp_status(struct sock *sk, int len,
3217 status.sstat_outstrms = asoc->c.sinit_num_ostreams; 3240 status.sstat_outstrms = asoc->c.sinit_num_ostreams;
3218 status.sstat_fragmentation_point = asoc->frag_point; 3241 status.sstat_fragmentation_point = asoc->frag_point;
3219 status.sstat_primary.spinfo_assoc_id = sctp_assoc2id(transport->asoc); 3242 status.sstat_primary.spinfo_assoc_id = sctp_assoc2id(transport->asoc);
3220 memcpy(&status.sstat_primary.spinfo_address, 3243 memcpy(&status.sstat_primary.spinfo_address, &transport->ipaddr,
3221 &(transport->ipaddr), sizeof(union sctp_addr)); 3244 transport->af_specific->sockaddr_len);
3222 /* Map ipv4 address into v4-mapped-on-v6 address. */ 3245 /* Map ipv4 address into v4-mapped-on-v6 address. */
3223 sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk), 3246 sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk),
3224 (union sctp_addr *)&status.sstat_primary.spinfo_address); 3247 (union sctp_addr *)&status.sstat_primary.spinfo_address);
@@ -3770,7 +3793,6 @@ static int sctp_getsockopt_peer_addrs_old(struct sock *sk, int len,
3770 memcpy(&temp, &from->ipaddr, sizeof(temp)); 3793 memcpy(&temp, &from->ipaddr, sizeof(temp));
3771 sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); 3794 sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp);
3772 addrlen = sctp_get_af_specific(sk->sk_family)->sockaddr_len; 3795 addrlen = sctp_get_af_specific(sk->sk_family)->sockaddr_len;
3773 temp.v4.sin_port = htons(temp.v4.sin_port);
3774 if (copy_to_user(to, &temp, addrlen)) 3796 if (copy_to_user(to, &temp, addrlen))
3775 return -EFAULT; 3797 return -EFAULT;
3776 to += addrlen ; 3798 to += addrlen ;
@@ -3821,7 +3843,6 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
3821 addrlen = sctp_get_af_specific(sk->sk_family)->sockaddr_len; 3843 addrlen = sctp_get_af_specific(sk->sk_family)->sockaddr_len;
3822 if(space_left < addrlen) 3844 if(space_left < addrlen)
3823 return -ENOMEM; 3845 return -ENOMEM;
3824 temp.v4.sin_port = htons(temp.v4.sin_port);
3825 if (copy_to_user(to, &temp, addrlen)) 3846 if (copy_to_user(to, &temp, addrlen))
3826 return -EFAULT; 3847 return -EFAULT;
3827 to += addrlen; 3848 to += addrlen;
@@ -3845,10 +3866,9 @@ static int sctp_getsockopt_local_addrs_num_old(struct sock *sk, int len,
3845 sctp_assoc_t id; 3866 sctp_assoc_t id;
3846 struct sctp_bind_addr *bp; 3867 struct sctp_bind_addr *bp;
3847 struct sctp_association *asoc; 3868 struct sctp_association *asoc;
3848 struct list_head *pos; 3869 struct list_head *pos, *temp;
3849 struct sctp_sockaddr_entry *addr; 3870 struct sctp_sockaddr_entry *addr;
3850 rwlock_t *addr_lock; 3871 rwlock_t *addr_lock;
3851 unsigned long flags;
3852 int cnt = 0; 3872 int cnt = 0;
3853 3873
3854 if (len != sizeof(sctp_assoc_t)) 3874 if (len != sizeof(sctp_assoc_t))
@@ -3883,18 +3903,15 @@ static int sctp_getsockopt_local_addrs_num_old(struct sock *sk, int len,
3883 addr = list_entry(bp->address_list.next, 3903 addr = list_entry(bp->address_list.next,
3884 struct sctp_sockaddr_entry, list); 3904 struct sctp_sockaddr_entry, list);
3885 if (sctp_is_any(&addr->a)) { 3905 if (sctp_is_any(&addr->a)) {
3886 sctp_spin_lock_irqsave(&sctp_local_addr_lock, flags); 3906 list_for_each_safe(pos, temp, &sctp_local_addr_list) {
3887 list_for_each(pos, &sctp_local_addr_list) {
3888 addr = list_entry(pos, 3907 addr = list_entry(pos,
3889 struct sctp_sockaddr_entry, 3908 struct sctp_sockaddr_entry,
3890 list); 3909 list);
3891 if ((PF_INET == sk->sk_family) && 3910 if ((PF_INET == sk->sk_family) &&
3892 (AF_INET6 == addr->a.sa.sa_family)) 3911 (AF_INET6 == addr->a.sa.sa_family))
3893 continue; 3912 continue;
3894 cnt++; 3913 cnt++;
3895 } 3914 }
3896 sctp_spin_unlock_irqrestore(&sctp_local_addr_lock,
3897 flags);
3898 } else { 3915 } else {
3899 cnt = 1; 3916 cnt = 1;
3900 } 3917 }
@@ -3916,15 +3933,13 @@ done:
3916static int sctp_copy_laddrs_to_user_old(struct sock *sk, __u16 port, int max_addrs, 3933static int sctp_copy_laddrs_to_user_old(struct sock *sk, __u16 port, int max_addrs,
3917 void __user *to) 3934 void __user *to)
3918{ 3935{
3919 struct list_head *pos; 3936 struct list_head *pos, *next;
3920 struct sctp_sockaddr_entry *addr; 3937 struct sctp_sockaddr_entry *addr;
3921 unsigned long flags;
3922 union sctp_addr temp; 3938 union sctp_addr temp;
3923 int cnt = 0; 3939 int cnt = 0;
3924 int addrlen; 3940 int addrlen;
3925 3941
3926 sctp_spin_lock_irqsave(&sctp_local_addr_lock, flags); 3942 list_for_each_safe(pos, next, &sctp_local_addr_list) {
3927 list_for_each(pos, &sctp_local_addr_list) {
3928 addr = list_entry(pos, struct sctp_sockaddr_entry, list); 3943 addr = list_entry(pos, struct sctp_sockaddr_entry, list);
3929 if ((PF_INET == sk->sk_family) && 3944 if ((PF_INET == sk->sk_family) &&
3930 (AF_INET6 == addr->a.sa.sa_family)) 3945 (AF_INET6 == addr->a.sa.sa_family))
@@ -3933,17 +3948,13 @@ static int sctp_copy_laddrs_to_user_old(struct sock *sk, __u16 port, int max_add
3933 sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk), 3948 sctp_get_pf_specific(sk->sk_family)->addr_v4map(sctp_sk(sk),
3934 &temp); 3949 &temp);
3935 addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; 3950 addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len;
3936 temp.v4.sin_port = htons(port); 3951 if (copy_to_user(to, &temp, addrlen))
3937 if (copy_to_user(to, &temp, addrlen)) {
3938 sctp_spin_unlock_irqrestore(&sctp_local_addr_lock,
3939 flags);
3940 return -EFAULT; 3952 return -EFAULT;
3941 } 3953
3942 to += addrlen; 3954 to += addrlen;
3943 cnt ++; 3955 cnt ++;
3944 if (cnt >= max_addrs) break; 3956 if (cnt >= max_addrs) break;
3945 } 3957 }
3946 sctp_spin_unlock_irqrestore(&sctp_local_addr_lock, flags);
3947 3958
3948 return cnt; 3959 return cnt;
3949} 3960}
@@ -3951,15 +3962,13 @@ static int sctp_copy_laddrs_to_user_old(struct sock *sk, __u16 port, int max_add
3951static int sctp_copy_laddrs_to_user(struct sock *sk, __u16 port, 3962static int sctp_copy_laddrs_to_user(struct sock *sk, __u16 port,
3952 void __user **to, size_t space_left) 3963 void __user **to, size_t space_left)
3953{ 3964{
3954 struct list_head *pos; 3965 struct list_head *pos, *next;
3955 struct sctp_sockaddr_entry *addr; 3966 struct sctp_sockaddr_entry *addr;
3956 unsigned long flags;
3957 union sctp_addr temp; 3967 union sctp_addr temp;
3958 int cnt = 0; 3968 int cnt = 0;
3959 int addrlen; 3969 int addrlen;
3960 3970
3961 sctp_spin_lock_irqsave(&sctp_local_addr_lock, flags); 3971 list_for_each_safe(pos, next, &sctp_local_addr_list) {
3962 list_for_each(pos, &sctp_local_addr_list) {
3963 addr = list_entry(pos, struct sctp_sockaddr_entry, list); 3972 addr = list_entry(pos, struct sctp_sockaddr_entry, list);
3964 if ((PF_INET == sk->sk_family) && 3973 if ((PF_INET == sk->sk_family) &&
3965 (AF_INET6 == addr->a.sa.sa_family)) 3974 (AF_INET6 == addr->a.sa.sa_family))
@@ -3970,17 +3979,13 @@ static int sctp_copy_laddrs_to_user(struct sock *sk, __u16 port,
3970 addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; 3979 addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len;
3971 if(space_left<addrlen) 3980 if(space_left<addrlen)
3972 return -ENOMEM; 3981 return -ENOMEM;
3973 temp.v4.sin_port = htons(port); 3982 if (copy_to_user(*to, &temp, addrlen))
3974 if (copy_to_user(*to, &temp, addrlen)) {
3975 sctp_spin_unlock_irqrestore(&sctp_local_addr_lock,
3976 flags);
3977 return -EFAULT; 3983 return -EFAULT;
3978 } 3984
3979 *to += addrlen; 3985 *to += addrlen;
3980 cnt ++; 3986 cnt ++;
3981 space_left -= addrlen; 3987 space_left -= addrlen;
3982 } 3988 }
3983 sctp_spin_unlock_irqrestore(&sctp_local_addr_lock, flags);
3984 3989
3985 return cnt; 3990 return cnt;
3986} 3991}
@@ -4055,7 +4060,6 @@ static int sctp_getsockopt_local_addrs_old(struct sock *sk, int len,
4055 memcpy(&temp, &addr->a, sizeof(temp)); 4060 memcpy(&temp, &addr->a, sizeof(temp));
4056 sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp); 4061 sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp);
4057 addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; 4062 addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len;
4058 temp.v4.sin_port = htons(temp.v4.sin_port);
4059 if (copy_to_user(to, &temp, addrlen)) { 4063 if (copy_to_user(to, &temp, addrlen)) {
4060 err = -EFAULT; 4064 err = -EFAULT;
4061 goto unlock; 4065 goto unlock;
@@ -4146,7 +4150,6 @@ static int sctp_getsockopt_local_addrs(struct sock *sk, int len,
4146 addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len; 4150 addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len;
4147 if(space_left < addrlen) 4151 if(space_left < addrlen)
4148 return -ENOMEM; /*fixme: right error?*/ 4152 return -ENOMEM; /*fixme: right error?*/
4149 temp.v4.sin_port = htons(temp.v4.sin_port);
4150 if (copy_to_user(to, &temp, addrlen)) { 4153 if (copy_to_user(to, &temp, addrlen)) {
4151 err = -EFAULT; 4154 err = -EFAULT;
4152 goto unlock; 4155 goto unlock;
@@ -4194,12 +4197,8 @@ static int sctp_getsockopt_primary_addr(struct sock *sk, int len,
4194 if (!asoc->peer.primary_path) 4197 if (!asoc->peer.primary_path)
4195 return -ENOTCONN; 4198 return -ENOTCONN;
4196 4199
4197 asoc->peer.primary_path->ipaddr.v4.sin_port =
4198 htons(asoc->peer.primary_path->ipaddr.v4.sin_port);
4199 memcpy(&prim.ssp_addr, &asoc->peer.primary_path->ipaddr, 4200 memcpy(&prim.ssp_addr, &asoc->peer.primary_path->ipaddr,
4200 sizeof(union sctp_addr)); 4201 asoc->peer.primary_path->af_specific->sockaddr_len);
4201 asoc->peer.primary_path->ipaddr.v4.sin_port =
4202 ntohs(asoc->peer.primary_path->ipaddr.v4.sin_port);
4203 4202
4204 sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, 4203 sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp,
4205 (union sctp_addr *)&prim.ssp_addr); 4204 (union sctp_addr *)&prim.ssp_addr);
@@ -4211,21 +4210,21 @@ static int sctp_getsockopt_primary_addr(struct sock *sk, int len,
4211} 4210}
4212 4211
4213/* 4212/*
4214 * 7.1.11 Set Adaption Layer Indicator (SCTP_ADAPTION_LAYER) 4213 * 7.1.11 Set Adaptation Layer Indicator (SCTP_ADAPTATION_LAYER)
4215 * 4214 *
4216 * Requests that the local endpoint set the specified Adaption Layer 4215 * Requests that the local endpoint set the specified Adaptation Layer
4217 * Indication parameter for all future INIT and INIT-ACK exchanges. 4216 * Indication parameter for all future INIT and INIT-ACK exchanges.
4218 */ 4217 */
4219static int sctp_getsockopt_adaption_layer(struct sock *sk, int len, 4218static int sctp_getsockopt_adaptation_layer(struct sock *sk, int len,
4220 char __user *optval, int __user *optlen) 4219 char __user *optval, int __user *optlen)
4221{ 4220{
4222 struct sctp_setadaption adaption; 4221 struct sctp_setadaptation adaptation;
4223 4222
4224 if (len != sizeof(struct sctp_setadaption)) 4223 if (len != sizeof(struct sctp_setadaptation))
4225 return -EINVAL; 4224 return -EINVAL;
4226 4225
4227 adaption.ssb_adaption_ind = sctp_sk(sk)->adaption_ind; 4226 adaptation.ssb_adaptation_ind = sctp_sk(sk)->adaptation_ind;
4228 if (copy_to_user(optval, &adaption, len)) 4227 if (copy_to_user(optval, &adaptation, len))
4229 return -EFAULT; 4228 return -EFAULT;
4230 4229
4231 return 0; 4230 return 0;
@@ -4467,6 +4466,42 @@ static int sctp_getsockopt_mappedv4(struct sock *sk, int len,
4467} 4466}
4468 4467
4469/* 4468/*
4469 * 7.1.29. Set or Get the default context (SCTP_CONTEXT)
4470 * (chapter and verse is quoted at sctp_setsockopt_context())
4471 */
4472static int sctp_getsockopt_context(struct sock *sk, int len,
4473 char __user *optval, int __user *optlen)
4474{
4475 struct sctp_assoc_value params;
4476 struct sctp_sock *sp;
4477 struct sctp_association *asoc;
4478
4479 if (len != sizeof(struct sctp_assoc_value))
4480 return -EINVAL;
4481
4482 if (copy_from_user(&params, optval, len))
4483 return -EFAULT;
4484
4485 sp = sctp_sk(sk);
4486
4487 if (params.assoc_id != 0) {
4488 asoc = sctp_id2assoc(sk, params.assoc_id);
4489 if (!asoc)
4490 return -EINVAL;
4491 params.assoc_value = asoc->default_rcv_context;
4492 } else {
4493 params.assoc_value = sp->default_rcv_context;
4494 }
4495
4496 if (put_user(len, optlen))
4497 return -EFAULT;
4498 if (copy_to_user(optval, &params, len))
4499 return -EFAULT;
4500
4501 return 0;
4502}
4503
4504/*
4470 * 7.1.17 Set the maximum fragrmentation size (SCTP_MAXSEG) 4505 * 7.1.17 Set the maximum fragrmentation size (SCTP_MAXSEG)
4471 * 4506 *
4472 * This socket option specifies the maximum size to put in any outgoing 4507 * This socket option specifies the maximum size to put in any outgoing
@@ -4600,10 +4635,13 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
4600 retval = sctp_getsockopt_peer_addr_info(sk, len, optval, 4635 retval = sctp_getsockopt_peer_addr_info(sk, len, optval,
4601 optlen); 4636 optlen);
4602 break; 4637 break;
4603 case SCTP_ADAPTION_LAYER: 4638 case SCTP_ADAPTATION_LAYER:
4604 retval = sctp_getsockopt_adaption_layer(sk, len, optval, 4639 retval = sctp_getsockopt_adaptation_layer(sk, len, optval,
4605 optlen); 4640 optlen);
4606 break; 4641 break;
4642 case SCTP_CONTEXT:
4643 retval = sctp_getsockopt_context(sk, len, optval, optlen);
4644 break;
4607 default: 4645 default:
4608 retval = -ENOPROTOOPT; 4646 retval = -ENOPROTOOPT;
4609 break; 4647 break;
@@ -4645,9 +4683,7 @@ static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr)
4645 unsigned short snum; 4683 unsigned short snum;
4646 int ret; 4684 int ret;
4647 4685
4648 /* NOTE: Remember to put this back to net order. */ 4686 snum = ntohs(addr->v4.sin_port);
4649 addr->v4.sin_port = ntohs(addr->v4.sin_port);
4650 snum = addr->v4.sin_port;
4651 4687
4652 SCTP_DEBUG_PRINTK("sctp_get_port() begins, snum=%d\n", snum); 4688 SCTP_DEBUG_PRINTK("sctp_get_port() begins, snum=%d\n", snum);
4653 sctp_local_bh_disable(); 4689 sctp_local_bh_disable();
@@ -4784,7 +4820,6 @@ fail_unlock:
4784 4820
4785fail: 4821fail:
4786 sctp_local_bh_enable(); 4822 sctp_local_bh_enable();
4787 addr->v4.sin_port = htons(addr->v4.sin_port);
4788 return ret; 4823 return ret;
4789} 4824}
4790 4825
@@ -5024,7 +5059,7 @@ static struct sctp_bind_bucket *sctp_bucket_create(
5024{ 5059{
5025 struct sctp_bind_bucket *pp; 5060 struct sctp_bind_bucket *pp;
5026 5061
5027 pp = kmem_cache_alloc(sctp_bucket_cachep, SLAB_ATOMIC); 5062 pp = kmem_cache_alloc(sctp_bucket_cachep, GFP_ATOMIC);
5028 SCTP_DBG_OBJCNT_INC(bind_bucket); 5063 SCTP_DBG_OBJCNT_INC(bind_bucket);
5029 if (pp) { 5064 if (pp) {
5030 pp->port = snum; 5065 pp->port = snum;
@@ -5083,7 +5118,7 @@ static int sctp_autobind(struct sock *sk)
5083{ 5118{
5084 union sctp_addr autoaddr; 5119 union sctp_addr autoaddr;
5085 struct sctp_af *af; 5120 struct sctp_af *af;
5086 unsigned short port; 5121 __be16 port;
5087 5122
5088 /* Initialize a local sockaddr structure to INADDR_ANY. */ 5123 /* Initialize a local sockaddr structure to INADDR_ANY. */
5089 af = sctp_sk(sk)->pf->af; 5124 af = sctp_sk(sk)->pf->af;
diff --git a/net/sctp/tsnmap.c b/net/sctp/tsnmap.c
index ac4fae161b..42d9498c64 100644
--- a/net/sctp/tsnmap.c
+++ b/net/sctp/tsnmap.c
@@ -401,13 +401,14 @@ __u16 sctp_tsnmap_num_gabs(struct sctp_tsnmap *map)
401 401
402 /* Refresh the gap ack information. */ 402 /* Refresh the gap ack information. */
403 if (sctp_tsnmap_has_gap(map)) { 403 if (sctp_tsnmap_has_gap(map)) {
404 __u16 start, end;
404 sctp_tsnmap_iter_init(map, &iter); 405 sctp_tsnmap_iter_init(map, &iter);
405 while (sctp_tsnmap_next_gap_ack(map, &iter, 406 while (sctp_tsnmap_next_gap_ack(map, &iter,
406 &map->gabs[gabs].start, 407 &start,
407 &map->gabs[gabs].end)) { 408 &end)) {
408 409
409 map->gabs[gabs].start = htons(map->gabs[gabs].start); 410 map->gabs[gabs].start = htons(start);
410 map->gabs[gabs].end = htons(map->gabs[gabs].end); 411 map->gabs[gabs].end = htons(end);
411 gabs++; 412 gabs++;
412 if (gabs >= SCTP_MAX_GABS) 413 if (gabs >= SCTP_MAX_GABS)
413 break; 414 break;
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
index a015283a90..445e07a7ac 100644
--- a/net/sctp/ulpevent.c
+++ b/net/sctp/ulpevent.c
@@ -351,7 +351,7 @@ struct sctp_ulpevent *sctp_ulpevent_make_remote_error(
351 struct sctp_remote_error *sre; 351 struct sctp_remote_error *sre;
352 struct sk_buff *skb; 352 struct sk_buff *skb;
353 sctp_errhdr_t *ch; 353 sctp_errhdr_t *ch;
354 __u16 cause; 354 __be16 cause;
355 int elen; 355 int elen;
356 356
357 ch = (sctp_errhdr_t *)(chunk->skb->data); 357 ch = (sctp_errhdr_t *)(chunk->skb->data);
@@ -609,31 +609,31 @@ fail:
609 return NULL; 609 return NULL;
610} 610}
611 611
612/* Create and initialize a SCTP_ADAPTION_INDICATION notification. 612/* Create and initialize a SCTP_ADAPTATION_INDICATION notification.
613 * 613 *
614 * Socket Extensions for SCTP 614 * Socket Extensions for SCTP
615 * 5.3.1.6 SCTP_ADAPTION_INDICATION 615 * 5.3.1.6 SCTP_ADAPTATION_INDICATION
616 */ 616 */
617struct sctp_ulpevent *sctp_ulpevent_make_adaption_indication( 617struct sctp_ulpevent *sctp_ulpevent_make_adaptation_indication(
618 const struct sctp_association *asoc, gfp_t gfp) 618 const struct sctp_association *asoc, gfp_t gfp)
619{ 619{
620 struct sctp_ulpevent *event; 620 struct sctp_ulpevent *event;
621 struct sctp_adaption_event *sai; 621 struct sctp_adaptation_event *sai;
622 struct sk_buff *skb; 622 struct sk_buff *skb;
623 623
624 event = sctp_ulpevent_new(sizeof(struct sctp_adaption_event), 624 event = sctp_ulpevent_new(sizeof(struct sctp_adaptation_event),
625 MSG_NOTIFICATION, gfp); 625 MSG_NOTIFICATION, gfp);
626 if (!event) 626 if (!event)
627 goto fail; 627 goto fail;
628 628
629 skb = sctp_event2skb(event); 629 skb = sctp_event2skb(event);
630 sai = (struct sctp_adaption_event *) 630 sai = (struct sctp_adaptation_event *)
631 skb_put(skb, sizeof(struct sctp_adaption_event)); 631 skb_put(skb, sizeof(struct sctp_adaptation_event));
632 632
633 sai->sai_type = SCTP_ADAPTION_INDICATION; 633 sai->sai_type = SCTP_ADAPTATION_INDICATION;
634 sai->sai_flags = 0; 634 sai->sai_flags = 0;
635 sai->sai_length = sizeof(struct sctp_adaption_event); 635 sai->sai_length = sizeof(struct sctp_adaptation_event);
636 sai->sai_adaption_ind = asoc->peer.adaption_ind; 636 sai->sai_adaptation_ind = asoc->peer.adaptation_ind;
637 sctp_ulpevent_set_owner(event, asoc); 637 sctp_ulpevent_set_owner(event, asoc);
638 sai->sai_assoc_id = sctp_assoc2id(asoc); 638 sai->sai_assoc_id = sctp_assoc2id(asoc);
639 639
@@ -849,8 +849,10 @@ void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event,
849 */ 849 */
850 sinfo.sinfo_assoc_id = sctp_assoc2id(event->asoc); 850 sinfo.sinfo_assoc_id = sctp_assoc2id(event->asoc);
851 851
852 /* context value that is set via SCTP_CONTEXT socket option. */
853 sinfo.sinfo_context = event->asoc->default_rcv_context;
854
852 /* These fields are not used while receiving. */ 855 /* These fields are not used while receiving. */
853 sinfo.sinfo_context = 0;
854 sinfo.sinfo_timetolive = 0; 856 sinfo.sinfo_timetolive = 0;
855 857
856 put_cmsg(msghdr, IPPROTO_SCTP, SCTP_SNDRCV, 858 put_cmsg(msghdr, IPPROTO_SCTP, SCTP_SNDRCV,
diff --git a/net/socket.c b/net/socket.c
index 6c9b9b326d..4e396312f8 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -77,7 +77,6 @@
77#include <linux/cache.h> 77#include <linux/cache.h>
78#include <linux/module.h> 78#include <linux/module.h>
79#include <linux/highmem.h> 79#include <linux/highmem.h>
80#include <linux/divert.h>
81#include <linux/mount.h> 80#include <linux/mount.h>
82#include <linux/security.h> 81#include <linux/security.h>
83#include <linux/syscalls.h> 82#include <linux/syscalls.h>
@@ -231,13 +230,13 @@ int move_addr_to_user(void *kaddr, int klen, void __user *uaddr,
231 230
232#define SOCKFS_MAGIC 0x534F434B 231#define SOCKFS_MAGIC 0x534F434B
233 232
234static kmem_cache_t *sock_inode_cachep __read_mostly; 233static struct kmem_cache *sock_inode_cachep __read_mostly;
235 234
236static struct inode *sock_alloc_inode(struct super_block *sb) 235static struct inode *sock_alloc_inode(struct super_block *sb)
237{ 236{
238 struct socket_alloc *ei; 237 struct socket_alloc *ei;
239 238
240 ei = kmem_cache_alloc(sock_inode_cachep, SLAB_KERNEL); 239 ei = kmem_cache_alloc(sock_inode_cachep, GFP_KERNEL);
241 if (!ei) 240 if (!ei)
242 return NULL; 241 return NULL;
243 init_waitqueue_head(&ei->socket.wait); 242 init_waitqueue_head(&ei->socket.wait);
@@ -258,7 +257,7 @@ static void sock_destroy_inode(struct inode *inode)
258 container_of(inode, struct socket_alloc, vfs_inode)); 257 container_of(inode, struct socket_alloc, vfs_inode));
259} 258}
260 259
261static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags) 260static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags)
262{ 261{
263 struct socket_alloc *ei = (struct socket_alloc *)foo; 262 struct socket_alloc *ei = (struct socket_alloc *)foo;
264 263
@@ -306,7 +305,14 @@ static struct file_system_type sock_fs_type = {
306 305
307static int sockfs_delete_dentry(struct dentry *dentry) 306static int sockfs_delete_dentry(struct dentry *dentry)
308{ 307{
309 return 1; 308 /*
309 * At creation time, we pretended this dentry was hashed
310 * (by clearing DCACHE_UNHASHED bit in d_flags)
311 * At delete time, we restore the truth : not hashed.
312 * (so that dput() can proceed correctly)
313 */
314 dentry->d_flags |= DCACHE_UNHASHED;
315 return 0;
310} 316}
311static struct dentry_operations sockfs_dentry_operations = { 317static struct dentry_operations sockfs_dentry_operations = {
312 .d_delete = sockfs_delete_dentry, 318 .d_delete = sockfs_delete_dentry,
@@ -354,16 +360,22 @@ static int sock_attach_fd(struct socket *sock, struct file *file)
354 360
355 this.len = sprintf(name, "[%lu]", SOCK_INODE(sock)->i_ino); 361 this.len = sprintf(name, "[%lu]", SOCK_INODE(sock)->i_ino);
356 this.name = name; 362 this.name = name;
357 this.hash = SOCK_INODE(sock)->i_ino; 363 this.hash = 0;
358 364
359 file->f_dentry = d_alloc(sock_mnt->mnt_sb->s_root, &this); 365 file->f_path.dentry = d_alloc(sock_mnt->mnt_sb->s_root, &this);
360 if (unlikely(!file->f_dentry)) 366 if (unlikely(!file->f_path.dentry))
361 return -ENOMEM; 367 return -ENOMEM;
362 368
363 file->f_dentry->d_op = &sockfs_dentry_operations; 369 file->f_path.dentry->d_op = &sockfs_dentry_operations;
364 d_add(file->f_dentry, SOCK_INODE(sock)); 370 /*
365 file->f_vfsmnt = mntget(sock_mnt); 371 * We dont want to push this dentry into global dentry hash table.
366 file->f_mapping = file->f_dentry->d_inode->i_mapping; 372 * We pretend dentry is already hashed, by unsetting DCACHE_UNHASHED
373 * This permits a working /proc/$pid/fd/XXX on sockets
374 */
375 file->f_path.dentry->d_flags &= ~DCACHE_UNHASHED;
376 d_instantiate(file->f_path.dentry, SOCK_INODE(sock));
377 file->f_path.mnt = mntget(sock_mnt);
378 file->f_mapping = file->f_path.dentry->d_inode->i_mapping;
367 379
368 sock->file = file; 380 sock->file = file;
369 file->f_op = SOCK_INODE(sock)->i_fop = &socket_file_ops; 381 file->f_op = SOCK_INODE(sock)->i_fop = &socket_file_ops;
@@ -401,7 +413,7 @@ static struct socket *sock_from_file(struct file *file, int *err)
401 if (file->f_op == &socket_file_ops) 413 if (file->f_op == &socket_file_ops)
402 return file->private_data; /* set in sock_map_fd */ 414 return file->private_data; /* set in sock_map_fd */
403 415
404 inode = file->f_dentry->d_inode; 416 inode = file->f_path.dentry->d_inode;
405 if (!S_ISSOCK(inode->i_mode)) { 417 if (!S_ISSOCK(inode->i_mode)) {
406 *err = -ENOTSOCK; 418 *err = -ENOTSOCK;
407 return NULL; 419 return NULL;
@@ -852,11 +864,6 @@ static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg)
852 err = vlan_ioctl_hook(argp); 864 err = vlan_ioctl_hook(argp);
853 mutex_unlock(&vlan_ioctl_mutex); 865 mutex_unlock(&vlan_ioctl_mutex);
854 break; 866 break;
855 case SIOCGIFDIVERT:
856 case SIOCSIFDIVERT:
857 /* Convert this to call through a hook */
858 err = divert_ioctl(cmd, argp);
859 break;
860 case SIOCADDDLCI: 867 case SIOCADDDLCI:
861 case SIOCDELDLCI: 868 case SIOCDELDLCI:
862 err = -ENOPKG; 869 err = -ENOPKG;
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
index b36b9463f5..e1a104abb7 100644
--- a/net/sunrpc/auth_gss/auth_gss.c
+++ b/net/sunrpc/auth_gss/auth_gss.c
@@ -68,7 +68,7 @@ static struct rpc_credops gss_credops;
68#define GSS_CRED_SLACK 1024 /* XXX: unused */ 68#define GSS_CRED_SLACK 1024 /* XXX: unused */
69/* length of a krb5 verifier (48), plus data added before arguments when 69/* length of a krb5 verifier (48), plus data added before arguments when
70 * using integrity (two 4-byte integers): */ 70 * using integrity (two 4-byte integers): */
71#define GSS_VERF_SLACK 56 71#define GSS_VERF_SLACK 100
72 72
73/* XXX this define must match the gssd define 73/* XXX this define must match the gssd define
74* as it is passed to gssd to signal the use of 74* as it is passed to gssd to signal the use of
@@ -94,46 +94,6 @@ struct gss_auth {
94static void gss_destroy_ctx(struct gss_cl_ctx *); 94static void gss_destroy_ctx(struct gss_cl_ctx *);
95static struct rpc_pipe_ops gss_upcall_ops; 95static struct rpc_pipe_ops gss_upcall_ops;
96 96
97void
98print_hexl(u32 *p, u_int length, u_int offset)
99{
100 u_int i, j, jm;
101 u8 c, *cp;
102
103 dprintk("RPC: print_hexl: length %d\n",length);
104 dprintk("\n");
105 cp = (u8 *) p;
106
107 for (i = 0; i < length; i += 0x10) {
108 dprintk(" %04x: ", (u_int)(i + offset));
109 jm = length - i;
110 jm = jm > 16 ? 16 : jm;
111
112 for (j = 0; j < jm; j++) {
113 if ((j % 2) == 1)
114 dprintk("%02x ", (u_int)cp[i+j]);
115 else
116 dprintk("%02x", (u_int)cp[i+j]);
117 }
118 for (; j < 16; j++) {
119 if ((j % 2) == 1)
120 dprintk(" ");
121 else
122 dprintk(" ");
123 }
124 dprintk(" ");
125
126 for (j = 0; j < jm; j++) {
127 c = cp[i+j];
128 c = isprint(c) ? c : '.';
129 dprintk("%c", c);
130 }
131 dprintk("\n");
132 }
133}
134
135EXPORT_SYMBOL(print_hexl);
136
137static inline struct gss_cl_ctx * 97static inline struct gss_cl_ctx *
138gss_get_ctx(struct gss_cl_ctx *ctx) 98gss_get_ctx(struct gss_cl_ctx *ctx)
139{ 99{
@@ -198,11 +158,10 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *dest)
198 q = (const void *)((const char *)p + len); 158 q = (const void *)((const char *)p + len);
199 if (unlikely(q > end || q < p)) 159 if (unlikely(q > end || q < p))
200 return ERR_PTR(-EFAULT); 160 return ERR_PTR(-EFAULT);
201 dest->data = kmalloc(len, GFP_KERNEL); 161 dest->data = kmemdup(p, len, GFP_KERNEL);
202 if (unlikely(dest->data == NULL)) 162 if (unlikely(dest->data == NULL))
203 return ERR_PTR(-ENOMEM); 163 return ERR_PTR(-ENOMEM);
204 dest->len = len; 164 dest->len = len;
205 memcpy(dest->data, p, len);
206 return q; 165 return q;
207} 166}
208 167
@@ -542,7 +501,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
542 if (!buf) 501 if (!buf)
543 goto out; 502 goto out;
544 503
545 clnt = RPC_I(filp->f_dentry->d_inode)->private; 504 clnt = RPC_I(filp->f_path.dentry->d_inode)->private;
546 err = -EFAULT; 505 err = -EFAULT;
547 if (copy_from_user(buf, src, mlen)) 506 if (copy_from_user(buf, src, mlen))
548 goto err; 507 goto err;
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c
index e11a40b25c..d926cda886 100644
--- a/net/sunrpc/auth_gss/gss_krb5_crypto.c
+++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c
@@ -43,6 +43,7 @@
43#include <linux/highmem.h> 43#include <linux/highmem.h>
44#include <linux/pagemap.h> 44#include <linux/pagemap.h>
45#include <linux/sunrpc/gss_krb5.h> 45#include <linux/sunrpc/gss_krb5.h>
46#include <linux/sunrpc/xdr.h>
46 47
47#ifdef RPC_DEBUG 48#ifdef RPC_DEBUG
48# define RPCDBG_FACILITY RPCDBG_AUTH 49# define RPCDBG_FACILITY RPCDBG_AUTH
@@ -61,9 +62,6 @@ krb5_encrypt(
61 u8 local_iv[16] = {0}; 62 u8 local_iv[16] = {0};
62 struct blkcipher_desc desc = { .tfm = tfm, .info = local_iv }; 63 struct blkcipher_desc desc = { .tfm = tfm, .info = local_iv };
63 64
64 dprintk("RPC: krb5_encrypt: input data:\n");
65 print_hexl((u32 *)in, length, 0);
66
67 if (length % crypto_blkcipher_blocksize(tfm) != 0) 65 if (length % crypto_blkcipher_blocksize(tfm) != 0)
68 goto out; 66 goto out;
69 67
@@ -80,12 +78,9 @@ krb5_encrypt(
80 sg_set_buf(sg, out, length); 78 sg_set_buf(sg, out, length);
81 79
82 ret = crypto_blkcipher_encrypt_iv(&desc, sg, sg, length); 80 ret = crypto_blkcipher_encrypt_iv(&desc, sg, sg, length);
83
84 dprintk("RPC: krb5_encrypt: output data:\n");
85 print_hexl((u32 *)out, length, 0);
86out: 81out:
87 dprintk("RPC: krb5_encrypt returns %d\n",ret); 82 dprintk("RPC: krb5_encrypt returns %d\n",ret);
88 return(ret); 83 return ret;
89} 84}
90 85
91EXPORT_SYMBOL(krb5_encrypt); 86EXPORT_SYMBOL(krb5_encrypt);
@@ -103,9 +98,6 @@ krb5_decrypt(
103 u8 local_iv[16] = {0}; 98 u8 local_iv[16] = {0};
104 struct blkcipher_desc desc = { .tfm = tfm, .info = local_iv }; 99 struct blkcipher_desc desc = { .tfm = tfm, .info = local_iv };
105 100
106 dprintk("RPC: krb5_decrypt: input data:\n");
107 print_hexl((u32 *)in, length, 0);
108
109 if (length % crypto_blkcipher_blocksize(tfm) != 0) 101 if (length % crypto_blkcipher_blocksize(tfm) != 0)
110 goto out; 102 goto out;
111 103
@@ -121,83 +113,14 @@ krb5_decrypt(
121 sg_set_buf(sg, out, length); 113 sg_set_buf(sg, out, length);
122 114
123 ret = crypto_blkcipher_decrypt_iv(&desc, sg, sg, length); 115 ret = crypto_blkcipher_decrypt_iv(&desc, sg, sg, length);
124
125 dprintk("RPC: krb5_decrypt: output_data:\n");
126 print_hexl((u32 *)out, length, 0);
127out: 116out:
128 dprintk("RPC: gss_k5decrypt returns %d\n",ret); 117 dprintk("RPC: gss_k5decrypt returns %d\n",ret);
129 return(ret); 118 return ret;
130} 119}
131 120
132EXPORT_SYMBOL(krb5_decrypt); 121EXPORT_SYMBOL(krb5_decrypt);
133 122
134static int 123static int
135process_xdr_buf(struct xdr_buf *buf, int offset, int len,
136 int (*actor)(struct scatterlist *, void *), void *data)
137{
138 int i, page_len, thislen, page_offset, ret = 0;
139 struct scatterlist sg[1];
140
141 if (offset >= buf->head[0].iov_len) {
142 offset -= buf->head[0].iov_len;
143 } else {
144 thislen = buf->head[0].iov_len - offset;
145 if (thislen > len)
146 thislen = len;
147 sg_set_buf(sg, buf->head[0].iov_base + offset, thislen);
148 ret = actor(sg, data);
149 if (ret)
150 goto out;
151 offset = 0;
152 len -= thislen;
153 }
154 if (len == 0)
155 goto out;
156
157 if (offset >= buf->page_len) {
158 offset -= buf->page_len;
159 } else {
160 page_len = buf->page_len - offset;
161 if (page_len > len)
162 page_len = len;
163 len -= page_len;
164 page_offset = (offset + buf->page_base) & (PAGE_CACHE_SIZE - 1);
165 i = (offset + buf->page_base) >> PAGE_CACHE_SHIFT;
166 thislen = PAGE_CACHE_SIZE - page_offset;
167 do {
168 if (thislen > page_len)
169 thislen = page_len;
170 sg->page = buf->pages[i];
171 sg->offset = page_offset;
172 sg->length = thislen;
173 ret = actor(sg, data);
174 if (ret)
175 goto out;
176 page_len -= thislen;
177 i++;
178 page_offset = 0;
179 thislen = PAGE_CACHE_SIZE;
180 } while (page_len != 0);
181 offset = 0;
182 }
183 if (len == 0)
184 goto out;
185
186 if (offset < buf->tail[0].iov_len) {
187 thislen = buf->tail[0].iov_len - offset;
188 if (thislen > len)
189 thislen = len;
190 sg_set_buf(sg, buf->tail[0].iov_base + offset, thislen);
191 ret = actor(sg, data);
192 len -= thislen;
193 }
194 if (len != 0)
195 ret = -EINVAL;
196out:
197 return ret;
198}
199
200static int
201checksummer(struct scatterlist *sg, void *data) 124checksummer(struct scatterlist *sg, void *data)
202{ 125{
203 struct hash_desc *desc = data; 126 struct hash_desc *desc = data;
@@ -207,23 +130,13 @@ checksummer(struct scatterlist *sg, void *data)
207 130
208/* checksum the plaintext data and hdrlen bytes of the token header */ 131/* checksum the plaintext data and hdrlen bytes of the token header */
209s32 132s32
210make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body, 133make_checksum(char *cksumname, char *header, int hdrlen, struct xdr_buf *body,
211 int body_offset, struct xdr_netobj *cksum) 134 int body_offset, struct xdr_netobj *cksum)
212{ 135{
213 char *cksumname;
214 struct hash_desc desc; /* XXX add to ctx? */ 136 struct hash_desc desc; /* XXX add to ctx? */
215 struct scatterlist sg[1]; 137 struct scatterlist sg[1];
216 int err; 138 int err;
217 139
218 switch (cksumtype) {
219 case CKSUMTYPE_RSA_MD5:
220 cksumname = "md5";
221 break;
222 default:
223 dprintk("RPC: krb5_make_checksum:"
224 " unsupported checksum %d", cksumtype);
225 return GSS_S_FAILURE;
226 }
227 desc.tfm = crypto_alloc_hash(cksumname, 0, CRYPTO_ALG_ASYNC); 140 desc.tfm = crypto_alloc_hash(cksumname, 0, CRYPTO_ALG_ASYNC);
228 if (IS_ERR(desc.tfm)) 141 if (IS_ERR(desc.tfm))
229 return GSS_S_FAILURE; 142 return GSS_S_FAILURE;
@@ -237,7 +150,7 @@ make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body,
237 err = crypto_hash_update(&desc, sg, hdrlen); 150 err = crypto_hash_update(&desc, sg, hdrlen);
238 if (err) 151 if (err)
239 goto out; 152 goto out;
240 err = process_xdr_buf(body, body_offset, body->len - body_offset, 153 err = xdr_process_buf(body, body_offset, body->len - body_offset,
241 checksummer, &desc); 154 checksummer, &desc);
242 if (err) 155 if (err)
243 goto out; 156 goto out;
@@ -335,7 +248,7 @@ gss_encrypt_xdr_buf(struct crypto_blkcipher *tfm, struct xdr_buf *buf,
335 desc.fragno = 0; 248 desc.fragno = 0;
336 desc.fraglen = 0; 249 desc.fraglen = 0;
337 250
338 ret = process_xdr_buf(buf, offset, buf->len - offset, encryptor, &desc); 251 ret = xdr_process_buf(buf, offset, buf->len - offset, encryptor, &desc);
339 return ret; 252 return ret;
340} 253}
341 254
@@ -401,7 +314,7 @@ gss_decrypt_xdr_buf(struct crypto_blkcipher *tfm, struct xdr_buf *buf,
401 desc.desc.flags = 0; 314 desc.desc.flags = 0;
402 desc.fragno = 0; 315 desc.fragno = 0;
403 desc.fraglen = 0; 316 desc.fraglen = 0;
404 return process_xdr_buf(buf, offset, buf->len - offset, decryptor, &desc); 317 return xdr_process_buf(buf, offset, buf->len - offset, decryptor, &desc);
405} 318}
406 319
407EXPORT_SYMBOL(gss_decrypt_xdr_buf); 320EXPORT_SYMBOL(gss_decrypt_xdr_buf);
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c
index 325e72e4fd..05d4bee86f 100644
--- a/net/sunrpc/auth_gss/gss_krb5_mech.c
+++ b/net/sunrpc/auth_gss/gss_krb5_mech.c
@@ -70,10 +70,9 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res)
70 q = (const void *)((const char *)p + len); 70 q = (const void *)((const char *)p + len);
71 if (unlikely(q > end || q < p)) 71 if (unlikely(q > end || q < p))
72 return ERR_PTR(-EFAULT); 72 return ERR_PTR(-EFAULT);
73 res->data = kmalloc(len, GFP_KERNEL); 73 res->data = kmemdup(p, len, GFP_KERNEL);
74 if (unlikely(res->data == NULL)) 74 if (unlikely(res->data == NULL))
75 return ERR_PTR(-ENOMEM); 75 return ERR_PTR(-ENOMEM);
76 memcpy(res->data, p, len);
77 res->len = len; 76 res->len = len;
78 return q; 77 return q;
79} 78}
@@ -130,6 +129,7 @@ gss_import_sec_context_kerberos(const void *p,
130{ 129{
131 const void *end = (const void *)((const char *)p + len); 130 const void *end = (const void *)((const char *)p + len);
132 struct krb5_ctx *ctx; 131 struct krb5_ctx *ctx;
132 int tmp;
133 133
134 if (!(ctx = kzalloc(sizeof(*ctx), GFP_KERNEL))) 134 if (!(ctx = kzalloc(sizeof(*ctx), GFP_KERNEL)))
135 goto out_err; 135 goto out_err;
@@ -137,18 +137,23 @@ gss_import_sec_context_kerberos(const void *p,
137 p = simple_get_bytes(p, end, &ctx->initiate, sizeof(ctx->initiate)); 137 p = simple_get_bytes(p, end, &ctx->initiate, sizeof(ctx->initiate));
138 if (IS_ERR(p)) 138 if (IS_ERR(p))
139 goto out_err_free_ctx; 139 goto out_err_free_ctx;
140 p = simple_get_bytes(p, end, &ctx->seed_init, sizeof(ctx->seed_init)); 140 /* The downcall format was designed before we completely understood
141 if (IS_ERR(p)) 141 * the uses of the context fields; so it includes some stuff we
142 * just give some minimal sanity-checking, and some we ignore
143 * completely (like the next twenty bytes): */
144 if (unlikely(p + 20 > end || p + 20 < p))
142 goto out_err_free_ctx; 145 goto out_err_free_ctx;
143 p = simple_get_bytes(p, end, ctx->seed, sizeof(ctx->seed)); 146 p += 20;
147 p = simple_get_bytes(p, end, &tmp, sizeof(tmp));
144 if (IS_ERR(p)) 148 if (IS_ERR(p))
145 goto out_err_free_ctx; 149 goto out_err_free_ctx;
146 p = simple_get_bytes(p, end, &ctx->signalg, sizeof(ctx->signalg)); 150 if (tmp != SGN_ALG_DES_MAC_MD5)
147 if (IS_ERR(p))
148 goto out_err_free_ctx; 151 goto out_err_free_ctx;
149 p = simple_get_bytes(p, end, &ctx->sealalg, sizeof(ctx->sealalg)); 152 p = simple_get_bytes(p, end, &tmp, sizeof(tmp));
150 if (IS_ERR(p)) 153 if (IS_ERR(p))
151 goto out_err_free_ctx; 154 goto out_err_free_ctx;
155 if (tmp != SEAL_ALG_DES)
156 goto out_err_free_ctx;
152 p = simple_get_bytes(p, end, &ctx->endtime, sizeof(ctx->endtime)); 157 p = simple_get_bytes(p, end, &ctx->endtime, sizeof(ctx->endtime));
153 if (IS_ERR(p)) 158 if (IS_ERR(p))
154 goto out_err_free_ctx; 159 goto out_err_free_ctx;
diff --git a/net/sunrpc/auth_gss/gss_krb5_seal.c b/net/sunrpc/auth_gss/gss_krb5_seal.c
index 08601ee4cd..d0bb5064f8 100644
--- a/net/sunrpc/auth_gss/gss_krb5_seal.c
+++ b/net/sunrpc/auth_gss/gss_krb5_seal.c
@@ -77,7 +77,6 @@ gss_get_mic_kerberos(struct gss_ctx *gss_ctx, struct xdr_buf *text,
77 struct xdr_netobj *token) 77 struct xdr_netobj *token)
78{ 78{
79 struct krb5_ctx *ctx = gss_ctx->internal_ctx_id; 79 struct krb5_ctx *ctx = gss_ctx->internal_ctx_id;
80 s32 checksum_type;
81 char cksumdata[16]; 80 char cksumdata[16];
82 struct xdr_netobj md5cksum = {.len = 0, .data = cksumdata}; 81 struct xdr_netobj md5cksum = {.len = 0, .data = cksumdata};
83 unsigned char *ptr, *krb5_hdr, *msg_start; 82 unsigned char *ptr, *krb5_hdr, *msg_start;
@@ -88,21 +87,6 @@ gss_get_mic_kerberos(struct gss_ctx *gss_ctx, struct xdr_buf *text,
88 87
89 now = get_seconds(); 88 now = get_seconds();
90 89
91 switch (ctx->signalg) {
92 case SGN_ALG_DES_MAC_MD5:
93 checksum_type = CKSUMTYPE_RSA_MD5;
94 break;
95 default:
96 dprintk("RPC: gss_krb5_seal: ctx->signalg %d not"
97 " supported\n", ctx->signalg);
98 goto out_err;
99 }
100 if (ctx->sealalg != SEAL_ALG_NONE && ctx->sealalg != SEAL_ALG_DES) {
101 dprintk("RPC: gss_krb5_seal: ctx->sealalg %d not supported\n",
102 ctx->sealalg);
103 goto out_err;
104 }
105
106 token->len = g_token_size(&ctx->mech_used, 22); 90 token->len = g_token_size(&ctx->mech_used, 22);
107 91
108 ptr = token->data; 92 ptr = token->data;
@@ -115,37 +99,26 @@ gss_get_mic_kerberos(struct gss_ctx *gss_ctx, struct xdr_buf *text,
115 krb5_hdr = ptr - 2; 99 krb5_hdr = ptr - 2;
116 msg_start = krb5_hdr + 24; 100 msg_start = krb5_hdr + 24;
117 101
118 *(__be16 *)(krb5_hdr + 2) = htons(ctx->signalg); 102 *(__be16 *)(krb5_hdr + 2) = htons(SGN_ALG_DES_MAC_MD5);
119 memset(krb5_hdr + 4, 0xff, 4); 103 memset(krb5_hdr + 4, 0xff, 4);
120 104
121 if (make_checksum(checksum_type, krb5_hdr, 8, text, 0, &md5cksum)) 105 if (make_checksum("md5", krb5_hdr, 8, text, 0, &md5cksum))
122 goto out_err; 106 return GSS_S_FAILURE;
123 107
124 switch (ctx->signalg) { 108 if (krb5_encrypt(ctx->seq, NULL, md5cksum.data,
125 case SGN_ALG_DES_MAC_MD5: 109 md5cksum.data, md5cksum.len))
126 if (krb5_encrypt(ctx->seq, NULL, md5cksum.data, 110 return GSS_S_FAILURE;
127 md5cksum.data, md5cksum.len)) 111
128 goto out_err; 112 memcpy(krb5_hdr + 16, md5cksum.data + md5cksum.len - KRB5_CKSUM_LENGTH,
129 memcpy(krb5_hdr + 16, 113 KRB5_CKSUM_LENGTH);
130 md5cksum.data + md5cksum.len - KRB5_CKSUM_LENGTH,
131 KRB5_CKSUM_LENGTH);
132
133 dprintk("RPC: make_seal_token: cksum data: \n");
134 print_hexl((u32 *) (krb5_hdr + 16), KRB5_CKSUM_LENGTH, 0);
135 break;
136 default:
137 BUG();
138 }
139 114
140 spin_lock(&krb5_seq_lock); 115 spin_lock(&krb5_seq_lock);
141 seq_send = ctx->seq_send++; 116 seq_send = ctx->seq_send++;
142 spin_unlock(&krb5_seq_lock); 117 spin_unlock(&krb5_seq_lock);
143 118
144 if ((krb5_make_seq_num(ctx->seq, ctx->initiate ? 0 : 0xff, 119 if (krb5_make_seq_num(ctx->seq, ctx->initiate ? 0 : 0xff,
145 seq_send, krb5_hdr + 16, krb5_hdr + 8))) 120 ctx->seq_send, krb5_hdr + 16, krb5_hdr + 8))
146 goto out_err; 121 return GSS_S_FAILURE;
147 122
148 return ((ctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE); 123 return (ctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE;
149out_err:
150 return GSS_S_FAILURE;
151} 124}
diff --git a/net/sunrpc/auth_gss/gss_krb5_unseal.c b/net/sunrpc/auth_gss/gss_krb5_unseal.c
index 0828cf6410..87f8977cce 100644
--- a/net/sunrpc/auth_gss/gss_krb5_unseal.c
+++ b/net/sunrpc/auth_gss/gss_krb5_unseal.c
@@ -78,7 +78,6 @@ gss_verify_mic_kerberos(struct gss_ctx *gss_ctx,
78 struct krb5_ctx *ctx = gss_ctx->internal_ctx_id; 78 struct krb5_ctx *ctx = gss_ctx->internal_ctx_id;
79 int signalg; 79 int signalg;
80 int sealalg; 80 int sealalg;
81 s32 checksum_type;
82 char cksumdata[16]; 81 char cksumdata[16];
83 struct xdr_netobj md5cksum = {.len = 0, .data = cksumdata}; 82 struct xdr_netobj md5cksum = {.len = 0, .data = cksumdata};
84 s32 now; 83 s32 now;
@@ -86,96 +85,54 @@ gss_verify_mic_kerberos(struct gss_ctx *gss_ctx,
86 s32 seqnum; 85 s32 seqnum;
87 unsigned char *ptr = (unsigned char *)read_token->data; 86 unsigned char *ptr = (unsigned char *)read_token->data;
88 int bodysize; 87 int bodysize;
89 u32 ret = GSS_S_DEFECTIVE_TOKEN;
90 88
91 dprintk("RPC: krb5_read_token\n"); 89 dprintk("RPC: krb5_read_token\n");
92 90
93 if (g_verify_token_header(&ctx->mech_used, &bodysize, &ptr, 91 if (g_verify_token_header(&ctx->mech_used, &bodysize, &ptr,
94 read_token->len)) 92 read_token->len))
95 goto out; 93 return GSS_S_DEFECTIVE_TOKEN;
96 94
97 if ((*ptr++ != ((KG_TOK_MIC_MSG>>8)&0xff)) || 95 if ((*ptr++ != ((KG_TOK_MIC_MSG>>8)&0xff)) ||
98 (*ptr++ != ( KG_TOK_MIC_MSG &0xff)) ) 96 (*ptr++ != ( KG_TOK_MIC_MSG &0xff)) )
99 goto out; 97 return GSS_S_DEFECTIVE_TOKEN;
100 98
101 /* XXX sanity-check bodysize?? */ 99 /* XXX sanity-check bodysize?? */
102 100
103 /* get the sign and seal algorithms */
104
105 signalg = ptr[0] + (ptr[1] << 8); 101 signalg = ptr[0] + (ptr[1] << 8);
106 sealalg = ptr[2] + (ptr[3] << 8); 102 if (signalg != SGN_ALG_DES_MAC_MD5)
103 return GSS_S_DEFECTIVE_TOKEN;
107 104
108 /* Sanity checks */ 105 sealalg = ptr[2] + (ptr[3] << 8);
106 if (sealalg != SEAL_ALG_NONE)
107 return GSS_S_DEFECTIVE_TOKEN;
109 108
110 if ((ptr[4] != 0xff) || (ptr[5] != 0xff)) 109 if ((ptr[4] != 0xff) || (ptr[5] != 0xff))
111 goto out; 110 return GSS_S_DEFECTIVE_TOKEN;
112 111
113 if (sealalg != 0xffff) 112 if (make_checksum("md5", ptr - 2, 8, message_buffer, 0, &md5cksum))
114 goto out; 113 return GSS_S_FAILURE;
115 114
116 /* there are several mappings of seal algorithms to sign algorithms, 115 if (krb5_encrypt(ctx->seq, NULL, md5cksum.data, md5cksum.data, 16))
117 but few enough that we can try them all. */ 116 return GSS_S_FAILURE;
118 117
119 if ((ctx->sealalg == SEAL_ALG_NONE && signalg > 1) || 118 if (memcmp(md5cksum.data + 8, ptr + 14, 8))
120 (ctx->sealalg == SEAL_ALG_1 && signalg != SGN_ALG_3) || 119 return GSS_S_BAD_SIG;
121 (ctx->sealalg == SEAL_ALG_DES3KD &&
122 signalg != SGN_ALG_HMAC_SHA1_DES3_KD))
123 goto out;
124
125 /* compute the checksum of the message */
126
127 /* initialize the the cksum */
128 switch (signalg) {
129 case SGN_ALG_DES_MAC_MD5:
130 checksum_type = CKSUMTYPE_RSA_MD5;
131 break;
132 default:
133 ret = GSS_S_DEFECTIVE_TOKEN;
134 goto out;
135 }
136
137 switch (signalg) {
138 case SGN_ALG_DES_MAC_MD5:
139 ret = make_checksum(checksum_type, ptr - 2, 8,
140 message_buffer, 0, &md5cksum);
141 if (ret)
142 goto out;
143
144 ret = krb5_encrypt(ctx->seq, NULL, md5cksum.data,
145 md5cksum.data, 16);
146 if (ret)
147 goto out;
148
149 if (memcmp(md5cksum.data + 8, ptr + 14, 8)) {
150 ret = GSS_S_BAD_SIG;
151 goto out;
152 }
153 break;
154 default:
155 ret = GSS_S_DEFECTIVE_TOKEN;
156 goto out;
157 }
158 120
159 /* it got through unscathed. Make sure the context is unexpired */ 121 /* it got through unscathed. Make sure the context is unexpired */
160 122
161 now = get_seconds(); 123 now = get_seconds();
162 124
163 ret = GSS_S_CONTEXT_EXPIRED;
164 if (now > ctx->endtime) 125 if (now > ctx->endtime)
165 goto out; 126 return GSS_S_CONTEXT_EXPIRED;
166 127
167 /* do sequencing checks */ 128 /* do sequencing checks */
168 129
169 ret = GSS_S_BAD_SIG; 130 if (krb5_get_seq_num(ctx->seq, ptr + 14, ptr + 6, &direction, &seqnum))
170 if ((ret = krb5_get_seq_num(ctx->seq, ptr + 14, ptr + 6, &direction, 131 return GSS_S_FAILURE;
171 &seqnum)))
172 goto out;
173 132
174 if ((ctx->initiate && direction != 0xff) || 133 if ((ctx->initiate && direction != 0xff) ||
175 (!ctx->initiate && direction != 0)) 134 (!ctx->initiate && direction != 0))
176 goto out; 135 return GSS_S_BAD_SIG;
177 136
178 ret = GSS_S_COMPLETE; 137 return GSS_S_COMPLETE;
179out:
180 return ret;
181} 138}
diff --git a/net/sunrpc/auth_gss/gss_krb5_wrap.c b/net/sunrpc/auth_gss/gss_krb5_wrap.c
index cc45c1605f..fe25b3d898 100644
--- a/net/sunrpc/auth_gss/gss_krb5_wrap.c
+++ b/net/sunrpc/auth_gss/gss_krb5_wrap.c
@@ -57,9 +57,9 @@ gss_krb5_remove_padding(struct xdr_buf *buf, int blocksize)
57 >>PAGE_CACHE_SHIFT; 57 >>PAGE_CACHE_SHIFT;
58 int offset = (buf->page_base + len - 1) 58 int offset = (buf->page_base + len - 1)
59 & (PAGE_CACHE_SIZE - 1); 59 & (PAGE_CACHE_SIZE - 1);
60 ptr = kmap_atomic(buf->pages[last], KM_SKB_SUNRPC_DATA); 60 ptr = kmap_atomic(buf->pages[last], KM_USER0);
61 pad = *(ptr + offset); 61 pad = *(ptr + offset);
62 kunmap_atomic(ptr, KM_SKB_SUNRPC_DATA); 62 kunmap_atomic(ptr, KM_USER0);
63 goto out; 63 goto out;
64 } else 64 } else
65 len -= buf->page_len; 65 len -= buf->page_len;
@@ -120,7 +120,6 @@ gss_wrap_kerberos(struct gss_ctx *ctx, int offset,
120 struct xdr_buf *buf, struct page **pages) 120 struct xdr_buf *buf, struct page **pages)
121{ 121{
122 struct krb5_ctx *kctx = ctx->internal_ctx_id; 122 struct krb5_ctx *kctx = ctx->internal_ctx_id;
123 s32 checksum_type;
124 char cksumdata[16]; 123 char cksumdata[16];
125 struct xdr_netobj md5cksum = {.len = 0, .data = cksumdata}; 124 struct xdr_netobj md5cksum = {.len = 0, .data = cksumdata};
126 int blocksize = 0, plainlen; 125 int blocksize = 0, plainlen;
@@ -134,21 +133,6 @@ gss_wrap_kerberos(struct gss_ctx *ctx, int offset,
134 133
135 now = get_seconds(); 134 now = get_seconds();
136 135
137 switch (kctx->signalg) {
138 case SGN_ALG_DES_MAC_MD5:
139 checksum_type = CKSUMTYPE_RSA_MD5;
140 break;
141 default:
142 dprintk("RPC: gss_krb5_seal: kctx->signalg %d not"
143 " supported\n", kctx->signalg);
144 goto out_err;
145 }
146 if (kctx->sealalg != SEAL_ALG_NONE && kctx->sealalg != SEAL_ALG_DES) {
147 dprintk("RPC: gss_krb5_seal: kctx->sealalg %d not supported\n",
148 kctx->sealalg);
149 goto out_err;
150 }
151
152 blocksize = crypto_blkcipher_blocksize(kctx->enc); 136 blocksize = crypto_blkcipher_blocksize(kctx->enc);
153 gss_krb5_add_padding(buf, offset, blocksize); 137 gss_krb5_add_padding(buf, offset, blocksize);
154 BUG_ON((buf->len - offset) % blocksize); 138 BUG_ON((buf->len - offset) % blocksize);
@@ -175,37 +159,27 @@ gss_wrap_kerberos(struct gss_ctx *ctx, int offset,
175 /* ptr now at byte 2 of header described in rfc 1964, section 1.2.1: */ 159 /* ptr now at byte 2 of header described in rfc 1964, section 1.2.1: */
176 krb5_hdr = ptr - 2; 160 krb5_hdr = ptr - 2;
177 msg_start = krb5_hdr + 24; 161 msg_start = krb5_hdr + 24;
178 /* XXXJBF: */ BUG_ON(buf->head[0].iov_base + offset + headlen != msg_start + blocksize);
179 162
180 *(__be16 *)(krb5_hdr + 2) = htons(kctx->signalg); 163 *(__be16 *)(krb5_hdr + 2) = htons(SGN_ALG_DES_MAC_MD5);
181 memset(krb5_hdr + 4, 0xff, 4); 164 memset(krb5_hdr + 4, 0xff, 4);
182 *(__be16 *)(krb5_hdr + 4) = htons(kctx->sealalg); 165 *(__be16 *)(krb5_hdr + 4) = htons(SEAL_ALG_DES);
183 166
184 make_confounder(msg_start, blocksize); 167 make_confounder(msg_start, blocksize);
185 168
186 /* XXXJBF: UGH!: */ 169 /* XXXJBF: UGH!: */
187 tmp_pages = buf->pages; 170 tmp_pages = buf->pages;
188 buf->pages = pages; 171 buf->pages = pages;
189 if (make_checksum(checksum_type, krb5_hdr, 8, buf, 172 if (make_checksum("md5", krb5_hdr, 8, buf,
190 offset + headlen - blocksize, &md5cksum)) 173 offset + headlen - blocksize, &md5cksum))
191 goto out_err; 174 return GSS_S_FAILURE;
192 buf->pages = tmp_pages; 175 buf->pages = tmp_pages;
193 176
194 switch (kctx->signalg) { 177 if (krb5_encrypt(kctx->seq, NULL, md5cksum.data,
195 case SGN_ALG_DES_MAC_MD5: 178 md5cksum.data, md5cksum.len))
196 if (krb5_encrypt(kctx->seq, NULL, md5cksum.data, 179 return GSS_S_FAILURE;
197 md5cksum.data, md5cksum.len)) 180 memcpy(krb5_hdr + 16,
198 goto out_err; 181 md5cksum.data + md5cksum.len - KRB5_CKSUM_LENGTH,
199 memcpy(krb5_hdr + 16, 182 KRB5_CKSUM_LENGTH);
200 md5cksum.data + md5cksum.len - KRB5_CKSUM_LENGTH,
201 KRB5_CKSUM_LENGTH);
202
203 dprintk("RPC: make_seal_token: cksum data: \n");
204 print_hexl((u32 *) (krb5_hdr + 16), KRB5_CKSUM_LENGTH, 0);
205 break;
206 default:
207 BUG();
208 }
209 183
210 spin_lock(&krb5_seq_lock); 184 spin_lock(&krb5_seq_lock);
211 seq_send = kctx->seq_send++; 185 seq_send = kctx->seq_send++;
@@ -215,15 +189,13 @@ gss_wrap_kerberos(struct gss_ctx *ctx, int offset,
215 * and encrypt at the same time: */ 189 * and encrypt at the same time: */
216 if ((krb5_make_seq_num(kctx->seq, kctx->initiate ? 0 : 0xff, 190 if ((krb5_make_seq_num(kctx->seq, kctx->initiate ? 0 : 0xff,
217 seq_send, krb5_hdr + 16, krb5_hdr + 8))) 191 seq_send, krb5_hdr + 16, krb5_hdr + 8)))
218 goto out_err; 192 return GSS_S_FAILURE;
219 193
220 if (gss_encrypt_xdr_buf(kctx->enc, buf, offset + headlen - blocksize, 194 if (gss_encrypt_xdr_buf(kctx->enc, buf, offset + headlen - blocksize,
221 pages)) 195 pages))
222 goto out_err; 196 return GSS_S_FAILURE;
223 197
224 return ((kctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE); 198 return (kctx->endtime < now) ? GSS_S_CONTEXT_EXPIRED : GSS_S_COMPLETE;
225out_err:
226 return GSS_S_FAILURE;
227} 199}
228 200
229u32 201u32
@@ -232,7 +204,6 @@ gss_unwrap_kerberos(struct gss_ctx *ctx, int offset, struct xdr_buf *buf)
232 struct krb5_ctx *kctx = ctx->internal_ctx_id; 204 struct krb5_ctx *kctx = ctx->internal_ctx_id;
233 int signalg; 205 int signalg;
234 int sealalg; 206 int sealalg;
235 s32 checksum_type;
236 char cksumdata[16]; 207 char cksumdata[16];
237 struct xdr_netobj md5cksum = {.len = 0, .data = cksumdata}; 208 struct xdr_netobj md5cksum = {.len = 0, .data = cksumdata};
238 s32 now; 209 s32 now;
@@ -240,7 +211,6 @@ gss_unwrap_kerberos(struct gss_ctx *ctx, int offset, struct xdr_buf *buf)
240 s32 seqnum; 211 s32 seqnum;
241 unsigned char *ptr; 212 unsigned char *ptr;
242 int bodysize; 213 int bodysize;
243 u32 ret = GSS_S_DEFECTIVE_TOKEN;
244 void *data_start, *orig_start; 214 void *data_start, *orig_start;
245 int data_len; 215 int data_len;
246 int blocksize; 216 int blocksize;
@@ -250,98 +220,58 @@ gss_unwrap_kerberos(struct gss_ctx *ctx, int offset, struct xdr_buf *buf)
250 ptr = (u8 *)buf->head[0].iov_base + offset; 220 ptr = (u8 *)buf->head[0].iov_base + offset;
251 if (g_verify_token_header(&kctx->mech_used, &bodysize, &ptr, 221 if (g_verify_token_header(&kctx->mech_used, &bodysize, &ptr,
252 buf->len - offset)) 222 buf->len - offset))
253 goto out; 223 return GSS_S_DEFECTIVE_TOKEN;
254 224
255 if ((*ptr++ != ((KG_TOK_WRAP_MSG>>8)&0xff)) || 225 if ((*ptr++ != ((KG_TOK_WRAP_MSG>>8)&0xff)) ||
256 (*ptr++ != (KG_TOK_WRAP_MSG &0xff)) ) 226 (*ptr++ != (KG_TOK_WRAP_MSG &0xff)) )
257 goto out; 227 return GSS_S_DEFECTIVE_TOKEN;
258 228
259 /* XXX sanity-check bodysize?? */ 229 /* XXX sanity-check bodysize?? */
260 230
261 /* get the sign and seal algorithms */ 231 /* get the sign and seal algorithms */
262 232
263 signalg = ptr[0] + (ptr[1] << 8); 233 signalg = ptr[0] + (ptr[1] << 8);
264 sealalg = ptr[2] + (ptr[3] << 8); 234 if (signalg != SGN_ALG_DES_MAC_MD5)
235 return GSS_S_DEFECTIVE_TOKEN;
265 236
266 /* Sanity checks */ 237 sealalg = ptr[2] + (ptr[3] << 8);
238 if (sealalg != SEAL_ALG_DES)
239 return GSS_S_DEFECTIVE_TOKEN;
267 240
268 if ((ptr[4] != 0xff) || (ptr[5] != 0xff)) 241 if ((ptr[4] != 0xff) || (ptr[5] != 0xff))
269 goto out; 242 return GSS_S_DEFECTIVE_TOKEN;
270
271 if (sealalg == 0xffff)
272 goto out;
273
274 /* in the current spec, there is only one valid seal algorithm per
275 key type, so a simple comparison is ok */
276
277 if (sealalg != kctx->sealalg)
278 goto out;
279
280 /* there are several mappings of seal algorithms to sign algorithms,
281 but few enough that we can try them all. */
282
283 if ((kctx->sealalg == SEAL_ALG_NONE && signalg > 1) ||
284 (kctx->sealalg == SEAL_ALG_1 && signalg != SGN_ALG_3) ||
285 (kctx->sealalg == SEAL_ALG_DES3KD &&
286 signalg != SGN_ALG_HMAC_SHA1_DES3_KD))
287 goto out;
288 243
289 if (gss_decrypt_xdr_buf(kctx->enc, buf, 244 if (gss_decrypt_xdr_buf(kctx->enc, buf,
290 ptr + 22 - (unsigned char *)buf->head[0].iov_base)) 245 ptr + 22 - (unsigned char *)buf->head[0].iov_base))
291 goto out; 246 return GSS_S_DEFECTIVE_TOKEN;
292 247
293 /* compute the checksum of the message */ 248 if (make_checksum("md5", ptr - 2, 8, buf,
249 ptr + 22 - (unsigned char *)buf->head[0].iov_base, &md5cksum))
250 return GSS_S_FAILURE;
294 251
295 /* initialize the the cksum */ 252 if (krb5_encrypt(kctx->seq, NULL, md5cksum.data,
296 switch (signalg) { 253 md5cksum.data, md5cksum.len))
297 case SGN_ALG_DES_MAC_MD5: 254 return GSS_S_FAILURE;
298 checksum_type = CKSUMTYPE_RSA_MD5; 255
299 break; 256 if (memcmp(md5cksum.data + 8, ptr + 14, 8))
300 default: 257 return GSS_S_BAD_SIG;
301 ret = GSS_S_DEFECTIVE_TOKEN;
302 goto out;
303 }
304
305 switch (signalg) {
306 case SGN_ALG_DES_MAC_MD5:
307 ret = make_checksum(checksum_type, ptr - 2, 8, buf,
308 ptr + 22 - (unsigned char *)buf->head[0].iov_base, &md5cksum);
309 if (ret)
310 goto out;
311
312 ret = krb5_encrypt(kctx->seq, NULL, md5cksum.data,
313 md5cksum.data, md5cksum.len);
314 if (ret)
315 goto out;
316
317 if (memcmp(md5cksum.data + 8, ptr + 14, 8)) {
318 ret = GSS_S_BAD_SIG;
319 goto out;
320 }
321 break;
322 default:
323 ret = GSS_S_DEFECTIVE_TOKEN;
324 goto out;
325 }
326 258
327 /* it got through unscathed. Make sure the context is unexpired */ 259 /* it got through unscathed. Make sure the context is unexpired */
328 260
329 now = get_seconds(); 261 now = get_seconds();
330 262
331 ret = GSS_S_CONTEXT_EXPIRED;
332 if (now > kctx->endtime) 263 if (now > kctx->endtime)
333 goto out; 264 return GSS_S_CONTEXT_EXPIRED;
334 265
335 /* do sequencing checks */ 266 /* do sequencing checks */
336 267
337 ret = GSS_S_BAD_SIG; 268 if (krb5_get_seq_num(kctx->seq, ptr + 14, ptr + 6, &direction,
338 if ((ret = krb5_get_seq_num(kctx->seq, ptr + 14, ptr + 6, &direction, 269 &seqnum))
339 &seqnum))) 270 return GSS_S_BAD_SIG;
340 goto out;
341 271
342 if ((kctx->initiate && direction != 0xff) || 272 if ((kctx->initiate && direction != 0xff) ||
343 (!kctx->initiate && direction != 0)) 273 (!kctx->initiate && direction != 0))
344 goto out; 274 return GSS_S_BAD_SIG;
345 275
346 /* Copy the data back to the right position. XXX: Would probably be 276 /* Copy the data back to the right position. XXX: Would probably be
347 * better to copy and encrypt at the same time. */ 277 * better to copy and encrypt at the same time. */
@@ -354,11 +284,8 @@ gss_unwrap_kerberos(struct gss_ctx *ctx, int offset, struct xdr_buf *buf)
354 buf->head[0].iov_len -= (data_start - orig_start); 284 buf->head[0].iov_len -= (data_start - orig_start);
355 buf->len -= (data_start - orig_start); 285 buf->len -= (data_start - orig_start);
356 286
357 ret = GSS_S_DEFECTIVE_TOKEN;
358 if (gss_krb5_remove_padding(buf, blocksize)) 287 if (gss_krb5_remove_padding(buf, blocksize))
359 goto out; 288 return GSS_S_DEFECTIVE_TOKEN;
360 289
361 ret = GSS_S_COMPLETE; 290 return GSS_S_COMPLETE;
362out:
363 return ret;
364} 291}
diff --git a/net/sunrpc/auth_gss/gss_spkm3_mech.c b/net/sunrpc/auth_gss/gss_spkm3_mech.c
index bdedf456bc..8ef3f1c194 100644
--- a/net/sunrpc/auth_gss/gss_spkm3_mech.c
+++ b/net/sunrpc/auth_gss/gss_spkm3_mech.c
@@ -76,140 +76,79 @@ simple_get_netobj(const void *p, const void *end, struct xdr_netobj *res)
76 q = (const void *)((const char *)p + len); 76 q = (const void *)((const char *)p + len);
77 if (unlikely(q > end || q < p)) 77 if (unlikely(q > end || q < p))
78 return ERR_PTR(-EFAULT); 78 return ERR_PTR(-EFAULT);
79 res->data = kmalloc(len, GFP_KERNEL); 79 res->data = kmemdup(p, len, GFP_KERNEL);
80 if (unlikely(res->data == NULL)) 80 if (unlikely(res->data == NULL))
81 return ERR_PTR(-ENOMEM); 81 return ERR_PTR(-ENOMEM);
82 memcpy(res->data, p, len);
83 return q; 82 return q;
84} 83}
85 84
86static inline const void *
87get_key(const void *p, const void *end, struct crypto_blkcipher **res,
88 int *resalg)
89{
90 struct xdr_netobj key = { 0 };
91 int setkey = 0;
92 char *alg_name;
93
94 p = simple_get_bytes(p, end, resalg, sizeof(*resalg));
95 if (IS_ERR(p))
96 goto out_err;
97 p = simple_get_netobj(p, end, &key);
98 if (IS_ERR(p))
99 goto out_err;
100
101 switch (*resalg) {
102 case NID_des_cbc:
103 alg_name = "cbc(des)";
104 setkey = 1;
105 break;
106 case NID_cast5_cbc:
107 /* XXXX here in name only, not used */
108 alg_name = "cbc(cast5)";
109 setkey = 0; /* XXX will need to set to 1 */
110 break;
111 case NID_md5:
112 if (key.len == 0) {
113 dprintk("RPC: SPKM3 get_key: NID_md5 zero Key length\n");
114 }
115 alg_name = "md5";
116 setkey = 0;
117 break;
118 default:
119 dprintk("gss_spkm3_mech: unsupported algorithm %d\n", *resalg);
120 goto out_err_free_key;
121 }
122 *res = crypto_alloc_blkcipher(alg_name, 0, CRYPTO_ALG_ASYNC);
123 if (IS_ERR(*res)) {
124 printk("gss_spkm3_mech: unable to initialize crypto algorthm %s\n", alg_name);
125 *res = NULL;
126 goto out_err_free_key;
127 }
128 if (setkey) {
129 if (crypto_blkcipher_setkey(*res, key.data, key.len)) {
130 printk("gss_spkm3_mech: error setting key for crypto algorthm %s\n", alg_name);
131 goto out_err_free_tfm;
132 }
133 }
134
135 if(key.len > 0)
136 kfree(key.data);
137 return p;
138
139out_err_free_tfm:
140 crypto_free_blkcipher(*res);
141out_err_free_key:
142 if(key.len > 0)
143 kfree(key.data);
144 p = ERR_PTR(-EINVAL);
145out_err:
146 return p;
147}
148
149static int 85static int
150gss_import_sec_context_spkm3(const void *p, size_t len, 86gss_import_sec_context_spkm3(const void *p, size_t len,
151 struct gss_ctx *ctx_id) 87 struct gss_ctx *ctx_id)
152{ 88{
153 const void *end = (const void *)((const char *)p + len); 89 const void *end = (const void *)((const char *)p + len);
154 struct spkm3_ctx *ctx; 90 struct spkm3_ctx *ctx;
91 int version;
155 92
156 if (!(ctx = kzalloc(sizeof(*ctx), GFP_KERNEL))) 93 if (!(ctx = kzalloc(sizeof(*ctx), GFP_KERNEL)))
157 goto out_err; 94 goto out_err;
158 95
96 p = simple_get_bytes(p, end, &version, sizeof(version));
97 if (IS_ERR(p))
98 goto out_err_free_ctx;
99 if (version != 1) {
100 dprintk("RPC: unknown spkm3 token format: obsolete nfs-utils?\n");
101 goto out_err_free_ctx;
102 }
103
159 p = simple_get_netobj(p, end, &ctx->ctx_id); 104 p = simple_get_netobj(p, end, &ctx->ctx_id);
160 if (IS_ERR(p)) 105 if (IS_ERR(p))
161 goto out_err_free_ctx; 106 goto out_err_free_ctx;
162 107
163 p = simple_get_bytes(p, end, &ctx->qop, sizeof(ctx->qop)); 108 p = simple_get_bytes(p, end, &ctx->endtime, sizeof(ctx->endtime));
164 if (IS_ERR(p)) 109 if (IS_ERR(p))
165 goto out_err_free_ctx_id; 110 goto out_err_free_ctx_id;
166 111
167 p = simple_get_netobj(p, end, &ctx->mech_used); 112 p = simple_get_netobj(p, end, &ctx->mech_used);
168 if (IS_ERR(p)) 113 if (IS_ERR(p))
169 goto out_err_free_mech; 114 goto out_err_free_ctx_id;
170 115
171 p = simple_get_bytes(p, end, &ctx->ret_flags, sizeof(ctx->ret_flags)); 116 p = simple_get_bytes(p, end, &ctx->ret_flags, sizeof(ctx->ret_flags));
172 if (IS_ERR(p)) 117 if (IS_ERR(p))
173 goto out_err_free_mech; 118 goto out_err_free_mech;
174 119
175 p = simple_get_bytes(p, end, &ctx->req_flags, sizeof(ctx->req_flags)); 120 p = simple_get_netobj(p, end, &ctx->conf_alg);
176 if (IS_ERR(p)) 121 if (IS_ERR(p))
177 goto out_err_free_mech; 122 goto out_err_free_mech;
178 123
179 p = simple_get_netobj(p, end, &ctx->share_key); 124 p = simple_get_netobj(p, end, &ctx->derived_conf_key);
180 if (IS_ERR(p)) 125 if (IS_ERR(p))
181 goto out_err_free_s_key; 126 goto out_err_free_conf_alg;
182 127
183 p = get_key(p, end, &ctx->derived_conf_key, &ctx->conf_alg); 128 p = simple_get_netobj(p, end, &ctx->intg_alg);
184 if (IS_ERR(p)) 129 if (IS_ERR(p))
185 goto out_err_free_s_key; 130 goto out_err_free_conf_key;
186 131
187 p = get_key(p, end, &ctx->derived_integ_key, &ctx->intg_alg); 132 p = simple_get_netobj(p, end, &ctx->derived_integ_key);
188 if (IS_ERR(p)) 133 if (IS_ERR(p))
189 goto out_err_free_key1; 134 goto out_err_free_intg_alg;
190
191 p = simple_get_bytes(p, end, &ctx->keyestb_alg, sizeof(ctx->keyestb_alg));
192 if (IS_ERR(p))
193 goto out_err_free_key2;
194
195 p = simple_get_bytes(p, end, &ctx->owf_alg, sizeof(ctx->owf_alg));
196 if (IS_ERR(p))
197 goto out_err_free_key2;
198 135
199 if (p != end) 136 if (p != end)
200 goto out_err_free_key2; 137 goto out_err_free_intg_key;
201 138
202 ctx_id->internal_ctx_id = ctx; 139 ctx_id->internal_ctx_id = ctx;
203 140
204 dprintk("Successfully imported new spkm context.\n"); 141 dprintk("Successfully imported new spkm context.\n");
205 return 0; 142 return 0;
206 143
207out_err_free_key2: 144out_err_free_intg_key:
208 crypto_free_blkcipher(ctx->derived_integ_key); 145 kfree(ctx->derived_integ_key.data);
209out_err_free_key1: 146out_err_free_intg_alg:
210 crypto_free_blkcipher(ctx->derived_conf_key); 147 kfree(ctx->intg_alg.data);
211out_err_free_s_key: 148out_err_free_conf_key:
212 kfree(ctx->share_key.data); 149 kfree(ctx->derived_conf_key.data);
150out_err_free_conf_alg:
151 kfree(ctx->conf_alg.data);
213out_err_free_mech: 152out_err_free_mech:
214 kfree(ctx->mech_used.data); 153 kfree(ctx->mech_used.data);
215out_err_free_ctx_id: 154out_err_free_ctx_id:
@@ -221,13 +160,16 @@ out_err:
221} 160}
222 161
223static void 162static void
224gss_delete_sec_context_spkm3(void *internal_ctx) { 163gss_delete_sec_context_spkm3(void *internal_ctx)
164{
225 struct spkm3_ctx *sctx = internal_ctx; 165 struct spkm3_ctx *sctx = internal_ctx;
226 166
227 crypto_free_blkcipher(sctx->derived_integ_key); 167 kfree(sctx->derived_integ_key.data);
228 crypto_free_blkcipher(sctx->derived_conf_key); 168 kfree(sctx->intg_alg.data);
229 kfree(sctx->share_key.data); 169 kfree(sctx->derived_conf_key.data);
170 kfree(sctx->conf_alg.data);
230 kfree(sctx->mech_used.data); 171 kfree(sctx->mech_used.data);
172 kfree(sctx->ctx_id.data);
231 kfree(sctx); 173 kfree(sctx);
232} 174}
233 175
@@ -239,7 +181,6 @@ gss_verify_mic_spkm3(struct gss_ctx *ctx,
239 u32 maj_stat = 0; 181 u32 maj_stat = 0;
240 struct spkm3_ctx *sctx = ctx->internal_ctx_id; 182 struct spkm3_ctx *sctx = ctx->internal_ctx_id;
241 183
242 dprintk("RPC: gss_verify_mic_spkm3 calling spkm3_read_token\n");
243 maj_stat = spkm3_read_token(sctx, checksum, signbuf, SPKM_MIC_TOK); 184 maj_stat = spkm3_read_token(sctx, checksum, signbuf, SPKM_MIC_TOK);
244 185
245 dprintk("RPC: gss_verify_mic_spkm3 returning %d\n", maj_stat); 186 dprintk("RPC: gss_verify_mic_spkm3 returning %d\n", maj_stat);
@@ -254,10 +195,9 @@ gss_get_mic_spkm3(struct gss_ctx *ctx,
254 u32 err = 0; 195 u32 err = 0;
255 struct spkm3_ctx *sctx = ctx->internal_ctx_id; 196 struct spkm3_ctx *sctx = ctx->internal_ctx_id;
256 197
257 dprintk("RPC: gss_get_mic_spkm3\n");
258
259 err = spkm3_make_token(sctx, message_buffer, 198 err = spkm3_make_token(sctx, message_buffer,
260 message_token, SPKM_MIC_TOK); 199 message_token, SPKM_MIC_TOK);
200 dprintk("RPC: gss_get_mic_spkm3 returning %d\n", err);
261 return err; 201 return err;
262} 202}
263 203
@@ -288,7 +228,7 @@ static int __init init_spkm3_module(void)
288 status = gss_mech_register(&gss_spkm3_mech); 228 status = gss_mech_register(&gss_spkm3_mech);
289 if (status) 229 if (status)
290 printk("Failed to register spkm3 gss mechanism!\n"); 230 printk("Failed to register spkm3 gss mechanism!\n");
291 return 0; 231 return status;
292} 232}
293 233
294static void __exit cleanup_spkm3_module(void) 234static void __exit cleanup_spkm3_module(void)
diff --git a/net/sunrpc/auth_gss/gss_spkm3_seal.c b/net/sunrpc/auth_gss/gss_spkm3_seal.c
index 18c7862bc2..b179d58c62 100644
--- a/net/sunrpc/auth_gss/gss_spkm3_seal.c
+++ b/net/sunrpc/auth_gss/gss_spkm3_seal.c
@@ -39,11 +39,17 @@
39#include <linux/sunrpc/gss_spkm3.h> 39#include <linux/sunrpc/gss_spkm3.h>
40#include <linux/random.h> 40#include <linux/random.h>
41#include <linux/crypto.h> 41#include <linux/crypto.h>
42#include <linux/pagemap.h>
43#include <linux/scatterlist.h>
44#include <linux/sunrpc/xdr.h>
42 45
43#ifdef RPC_DEBUG 46#ifdef RPC_DEBUG
44# define RPCDBG_FACILITY RPCDBG_AUTH 47# define RPCDBG_FACILITY RPCDBG_AUTH
45#endif 48#endif
46 49
50const struct xdr_netobj hmac_md5_oid = { 8, "\x2B\x06\x01\x05\x05\x08\x01\x01"};
51const struct xdr_netobj cast5_cbc_oid = {9, "\x2A\x86\x48\x86\xF6\x7D\x07\x42\x0A"};
52
47/* 53/*
48 * spkm3_make_token() 54 * spkm3_make_token()
49 * 55 *
@@ -66,29 +72,23 @@ spkm3_make_token(struct spkm3_ctx *ctx,
66 int ctxelen = 0, ctxzbit = 0; 72 int ctxelen = 0, ctxzbit = 0;
67 int md5elen = 0, md5zbit = 0; 73 int md5elen = 0, md5zbit = 0;
68 74
69 dprintk("RPC: spkm3_make_token\n");
70
71 now = jiffies; 75 now = jiffies;
72 76
73 if (ctx->ctx_id.len != 16) { 77 if (ctx->ctx_id.len != 16) {
74 dprintk("RPC: spkm3_make_token BAD ctx_id.len %d\n", 78 dprintk("RPC: spkm3_make_token BAD ctx_id.len %d\n",
75 ctx->ctx_id.len); 79 ctx->ctx_id.len);
76 goto out_err; 80 goto out_err;
77 } 81 }
78 82
79 switch (ctx->intg_alg) { 83 if (!g_OID_equal(&ctx->intg_alg, &hmac_md5_oid)) {
80 case NID_md5: 84 dprintk("RPC: gss_spkm3_seal: unsupported I-ALG algorithm."
81 checksum_type = CKSUMTYPE_RSA_MD5; 85 "only support hmac-md5 I-ALG.\n");
82 break; 86 goto out_err;
83 default: 87 } else
84 dprintk("RPC: gss_spkm3_seal: ctx->signalg %d not" 88 checksum_type = CKSUMTYPE_HMAC_MD5;
85 " supported\n", ctx->intg_alg); 89
86 goto out_err; 90 if (!g_OID_equal(&ctx->conf_alg, &cast5_cbc_oid)) {
87 } 91 dprintk("RPC: gss_spkm3_seal: unsupported C-ALG algorithm\n");
88 /* XXX since we don't support WRAP, perhaps we don't care... */
89 if (ctx->conf_alg != NID_cast5_cbc) {
90 dprintk("RPC: gss_spkm3_seal: ctx->sealalg %d not supported\n",
91 ctx->conf_alg);
92 goto out_err; 92 goto out_err;
93 } 93 }
94 94
@@ -96,10 +96,10 @@ spkm3_make_token(struct spkm3_ctx *ctx,
96 /* Calculate checksum over the mic-header */ 96 /* Calculate checksum over the mic-header */
97 asn1_bitstring_len(&ctx->ctx_id, &ctxelen, &ctxzbit); 97 asn1_bitstring_len(&ctx->ctx_id, &ctxelen, &ctxzbit);
98 spkm3_mic_header(&mic_hdr.data, &mic_hdr.len, ctx->ctx_id.data, 98 spkm3_mic_header(&mic_hdr.data, &mic_hdr.len, ctx->ctx_id.data,
99 ctxelen, ctxzbit); 99 ctxelen, ctxzbit);
100 100 if (make_spkm3_checksum(checksum_type, &ctx->derived_integ_key,
101 if (make_checksum(checksum_type, mic_hdr.data, mic_hdr.len, 101 (char *)mic_hdr.data, mic_hdr.len,
102 text, 0, &md5cksum)) 102 text, 0, &md5cksum))
103 goto out_err; 103 goto out_err;
104 104
105 asn1_bitstring_len(&md5cksum, &md5elen, &md5zbit); 105 asn1_bitstring_len(&md5cksum, &md5elen, &md5zbit);
@@ -121,7 +121,66 @@ spkm3_make_token(struct spkm3_ctx *ctx,
121 121
122 return GSS_S_COMPLETE; 122 return GSS_S_COMPLETE;
123out_err: 123out_err:
124 if (md5cksum.data)
125 kfree(md5cksum.data);
126
124 token->data = NULL; 127 token->data = NULL;
125 token->len = 0; 128 token->len = 0;
126 return GSS_S_FAILURE; 129 return GSS_S_FAILURE;
127} 130}
131
132static int
133spkm3_checksummer(struct scatterlist *sg, void *data)
134{
135 struct hash_desc *desc = data;
136
137 return crypto_hash_update(desc, sg, sg->length);
138}
139
140/* checksum the plaintext data and hdrlen bytes of the token header */
141s32
142make_spkm3_checksum(s32 cksumtype, struct xdr_netobj *key, char *header,
143 unsigned int hdrlen, struct xdr_buf *body,
144 unsigned int body_offset, struct xdr_netobj *cksum)
145{
146 char *cksumname;
147 struct hash_desc desc; /* XXX add to ctx? */
148 struct scatterlist sg[1];
149 int err;
150
151 switch (cksumtype) {
152 case CKSUMTYPE_HMAC_MD5:
153 cksumname = "md5";
154 break;
155 default:
156 dprintk("RPC: spkm3_make_checksum:"
157 " unsupported checksum %d", cksumtype);
158 return GSS_S_FAILURE;
159 }
160
161 if (key->data == NULL || key->len <= 0) return GSS_S_FAILURE;
162
163 desc.tfm = crypto_alloc_hash(cksumname, 0, CRYPTO_ALG_ASYNC);
164 if (IS_ERR(desc.tfm))
165 return GSS_S_FAILURE;
166 cksum->len = crypto_hash_digestsize(desc.tfm);
167 desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
168
169 err = crypto_hash_setkey(desc.tfm, key->data, key->len);
170 if (err)
171 goto out;
172
173 sg_set_buf(sg, header, hdrlen);
174 crypto_hash_update(&desc, sg, 1);
175
176 xdr_process_buf(body, body_offset, body->len - body_offset,
177 spkm3_checksummer, &desc);
178 crypto_hash_final(&desc, cksum->data);
179
180out:
181 crypto_free_hash(desc.tfm);
182
183 return err ? GSS_S_FAILURE : 0;
184}
185
186EXPORT_SYMBOL(make_spkm3_checksum);
diff --git a/net/sunrpc/auth_gss/gss_spkm3_token.c b/net/sunrpc/auth_gss/gss_spkm3_token.c
index 854a983ccf..35188b6ea8 100644
--- a/net/sunrpc/auth_gss/gss_spkm3_token.c
+++ b/net/sunrpc/auth_gss/gss_spkm3_token.c
@@ -172,10 +172,10 @@ spkm3_mic_header(unsigned char **hdrbuf, unsigned int *hdrlen, unsigned char *ct
172 *(u8 *)hptr++ = zbit; 172 *(u8 *)hptr++ = zbit;
173 memcpy(hptr, ctxdata, elen); 173 memcpy(hptr, ctxdata, elen);
174 hptr += elen; 174 hptr += elen;
175 *hdrlen = hptr - top; 175 *hdrlen = hptr - top;
176} 176}
177 177
178/* 178/*
179 * spkm3_mic_innercontext_token() 179 * spkm3_mic_innercontext_token()
180 * 180 *
181 * *tokp points to the beginning of the SPKM_MIC token described 181 * *tokp points to the beginning of the SPKM_MIC token described
diff --git a/net/sunrpc/auth_gss/gss_spkm3_unseal.c b/net/sunrpc/auth_gss/gss_spkm3_unseal.c
index 8537f581ef..e54581ca75 100644
--- a/net/sunrpc/auth_gss/gss_spkm3_unseal.c
+++ b/net/sunrpc/auth_gss/gss_spkm3_unseal.c
@@ -54,70 +54,70 @@ spkm3_read_token(struct spkm3_ctx *ctx,
54 struct xdr_buf *message_buffer, /* signbuf */ 54 struct xdr_buf *message_buffer, /* signbuf */
55 int toktype) 55 int toktype)
56{ 56{
57 s32 checksum_type;
57 s32 code; 58 s32 code;
58 struct xdr_netobj wire_cksum = {.len =0, .data = NULL}; 59 struct xdr_netobj wire_cksum = {.len =0, .data = NULL};
59 char cksumdata[16]; 60 char cksumdata[16];
60 struct xdr_netobj md5cksum = {.len = 0, .data = cksumdata}; 61 struct xdr_netobj md5cksum = {.len = 0, .data = cksumdata};
61 unsigned char *ptr = (unsigned char *)read_token->data; 62 unsigned char *ptr = (unsigned char *)read_token->data;
62 unsigned char *cksum; 63 unsigned char *cksum;
63 int bodysize, md5elen; 64 int bodysize, md5elen;
64 int mic_hdrlen; 65 int mic_hdrlen;
65 u32 ret = GSS_S_DEFECTIVE_TOKEN; 66 u32 ret = GSS_S_DEFECTIVE_TOKEN;
66 67
67 dprintk("RPC: spkm3_read_token read_token->len %d\n", read_token->len);
68
69 if (g_verify_token_header((struct xdr_netobj *) &ctx->mech_used, 68 if (g_verify_token_header((struct xdr_netobj *) &ctx->mech_used,
70 &bodysize, &ptr, read_token->len)) 69 &bodysize, &ptr, read_token->len))
71 goto out; 70 goto out;
72 71
73 /* decode the token */ 72 /* decode the token */
74 73
75 if (toktype == SPKM_MIC_TOK) { 74 if (toktype != SPKM_MIC_TOK) {
76 75 dprintk("RPC: BAD SPKM3 token type: %d\n", toktype);
77 if ((ret = spkm3_verify_mic_token(&ptr, &mic_hdrlen, &cksum))) 76 goto out;
78 goto out; 77 }
79 78
80 if (*cksum++ != 0x03) { 79 if ((ret = spkm3_verify_mic_token(&ptr, &mic_hdrlen, &cksum)))
81 dprintk("RPC: spkm3_read_token BAD checksum type\n"); 80 goto out;
82 goto out; 81
83 } 82 if (*cksum++ != 0x03) {
84 md5elen = *cksum++; 83 dprintk("RPC: spkm3_read_token BAD checksum type\n");
85 cksum++; /* move past the zbit */ 84 goto out;
86 85 }
87 if(!decode_asn1_bitstring(&wire_cksum, cksum, md5elen - 1, 16)) 86 md5elen = *cksum++;
88 goto out; 87 cksum++; /* move past the zbit */
89 88
90 /* HARD CODED FOR MD5 */ 89 if (!decode_asn1_bitstring(&wire_cksum, cksum, md5elen - 1, 16))
91 90 goto out;
92 /* compute the checksum of the message. 91
93 * ptr + 2 = start of header piece of checksum 92 /* HARD CODED FOR MD5 */
94 * mic_hdrlen + 2 = length of header piece of checksum 93
95 */ 94 /* compute the checksum of the message.
96 ret = GSS_S_DEFECTIVE_TOKEN; 95 * ptr + 2 = start of header piece of checksum
97 code = make_checksum(CKSUMTYPE_RSA_MD5, ptr + 2, 96 * mic_hdrlen + 2 = length of header piece of checksum
98 mic_hdrlen + 2, 97 */
99 message_buffer, 0, &md5cksum); 98 ret = GSS_S_DEFECTIVE_TOKEN;
100 99 if (!g_OID_equal(&ctx->intg_alg, &hmac_md5_oid)) {
101 if (code) 100 dprintk("RPC: gss_spkm3_seal: unsupported I-ALG algorithm\n");
102 goto out; 101 goto out;
103 102 }
104 dprintk("RPC: spkm3_read_token: digest wire_cksum.len %d:\n", 103
105 wire_cksum.len); 104 checksum_type = CKSUMTYPE_HMAC_MD5;
106 dprintk(" md5cksum.data\n"); 105
107 print_hexl((u32 *) md5cksum.data, 16, 0); 106 code = make_spkm3_checksum(checksum_type,
108 dprintk(" cksum.data:\n"); 107 &ctx->derived_integ_key, ptr + 2, mic_hdrlen + 2,
109 print_hexl((u32 *) wire_cksum.data, wire_cksum.len, 0); 108 message_buffer, 0, &md5cksum);
110 109
111 ret = GSS_S_BAD_SIG; 110 if (code)
112 code = memcmp(md5cksum.data, wire_cksum.data, wire_cksum.len); 111 goto out;
113 if (code) 112
114 goto out; 113 ret = GSS_S_BAD_SIG;
115 114 code = memcmp(md5cksum.data, wire_cksum.data, wire_cksum.len);
116 } else { 115 if (code) {
117 dprintk("RPC: BAD or UNSUPPORTED SPKM3 token type: %d\n",toktype); 116 dprintk("RPC: bad MIC checksum\n");
118 goto out; 117 goto out;
119 } 118 }
120 119
120
121 /* XXX: need to add expiration and sequencing */ 121 /* XXX: need to add expiration and sequencing */
122 ret = GSS_S_COMPLETE; 122 ret = GSS_S_COMPLETE;
123out: 123out:
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 1f0f079ffa..066c64a97f 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -113,9 +113,7 @@ static int rsi_match(struct cache_head *a, struct cache_head *b)
113static int dup_to_netobj(struct xdr_netobj *dst, char *src, int len) 113static int dup_to_netobj(struct xdr_netobj *dst, char *src, int len)
114{ 114{
115 dst->len = len; 115 dst->len = len;
116 dst->data = (len ? kmalloc(len, GFP_KERNEL) : NULL); 116 dst->data = (len ? kmemdup(src, len, GFP_KERNEL) : NULL);
117 if (dst->data)
118 memcpy(dst->data, src, len);
119 if (len && !dst->data) 117 if (len && !dst->data)
120 return -ENOMEM; 118 return -ENOMEM;
121 return 0; 119 return 0;
@@ -756,10 +754,9 @@ svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name)
756 if (!new) 754 if (!new)
757 goto out; 755 goto out;
758 kref_init(&new->h.ref); 756 kref_init(&new->h.ref);
759 new->h.name = kmalloc(strlen(name) + 1, GFP_KERNEL); 757 new->h.name = kstrdup(name, GFP_KERNEL);
760 if (!new->h.name) 758 if (!new->h.name)
761 goto out_free_dom; 759 goto out_free_dom;
762 strcpy(new->h.name, name);
763 new->h.flavour = &svcauthops_gss; 760 new->h.flavour = &svcauthops_gss;
764 new->pseudoflavor = pseudoflavor; 761 new->pseudoflavor = pseudoflavor;
765 762
@@ -807,19 +804,19 @@ unwrap_integ_data(struct xdr_buf *buf, u32 seq, struct gss_ctx *ctx)
807 804
808 integ_len = svc_getnl(&buf->head[0]); 805 integ_len = svc_getnl(&buf->head[0]);
809 if (integ_len & 3) 806 if (integ_len & 3)
810 goto out; 807 return stat;
811 if (integ_len > buf->len) 808 if (integ_len > buf->len)
812 goto out; 809 return stat;
813 if (xdr_buf_subsegment(buf, &integ_buf, 0, integ_len)) 810 if (xdr_buf_subsegment(buf, &integ_buf, 0, integ_len))
814 BUG(); 811 BUG();
815 /* copy out mic... */ 812 /* copy out mic... */
816 if (read_u32_from_xdr_buf(buf, integ_len, &mic.len)) 813 if (read_u32_from_xdr_buf(buf, integ_len, &mic.len))
817 BUG(); 814 BUG();
818 if (mic.len > RPC_MAX_AUTH_SIZE) 815 if (mic.len > RPC_MAX_AUTH_SIZE)
819 goto out; 816 return stat;
820 mic.data = kmalloc(mic.len, GFP_KERNEL); 817 mic.data = kmalloc(mic.len, GFP_KERNEL);
821 if (!mic.data) 818 if (!mic.data)
822 goto out; 819 return stat;
823 if (read_bytes_from_xdr_buf(buf, integ_len + 4, mic.data, mic.len)) 820 if (read_bytes_from_xdr_buf(buf, integ_len + 4, mic.data, mic.len))
824 goto out; 821 goto out;
825 maj_stat = gss_verify_mic(ctx, &integ_buf, &mic); 822 maj_stat = gss_verify_mic(ctx, &integ_buf, &mic);
@@ -829,6 +826,7 @@ unwrap_integ_data(struct xdr_buf *buf, u32 seq, struct gss_ctx *ctx)
829 goto out; 826 goto out;
830 stat = 0; 827 stat = 0;
831out: 828out:
829 kfree(mic.data);
832 return stat; 830 return stat;
833} 831}
834 832
@@ -1068,7 +1066,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, __be32 *authp)
1068 } 1066 }
1069 switch(cache_check(&rsi_cache, &rsip->h, &rqstp->rq_chandle)) { 1067 switch(cache_check(&rsi_cache, &rsip->h, &rqstp->rq_chandle)) {
1070 case -EAGAIN: 1068 case -EAGAIN:
1071 goto drop; 1069 case -ETIMEDOUT:
1072 case -ENOENT: 1070 case -ENOENT:
1073 goto drop; 1071 goto drop;
1074 case 0: 1072 case 0:
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 00cb388ece..14274490f9 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -34,7 +34,7 @@
34 34
35#define RPCDBG_FACILITY RPCDBG_CACHE 35#define RPCDBG_FACILITY RPCDBG_CACHE
36 36
37static void cache_defer_req(struct cache_req *req, struct cache_head *item); 37static int cache_defer_req(struct cache_req *req, struct cache_head *item);
38static void cache_revisit_request(struct cache_head *item); 38static void cache_revisit_request(struct cache_head *item);
39 39
40static void cache_init(struct cache_head *h) 40static void cache_init(struct cache_head *h)
@@ -185,6 +185,7 @@ static int cache_make_upcall(struct cache_detail *detail, struct cache_head *h);
185 * 185 *
186 * Returns 0 if the cache_head can be used, or cache_puts it and returns 186 * Returns 0 if the cache_head can be used, or cache_puts it and returns
187 * -EAGAIN if upcall is pending, 187 * -EAGAIN if upcall is pending,
188 * -ETIMEDOUT if upcall failed and should be retried,
188 * -ENOENT if cache entry was negative 189 * -ENOENT if cache entry was negative
189 */ 190 */
190int cache_check(struct cache_detail *detail, 191int cache_check(struct cache_detail *detail,
@@ -236,7 +237,8 @@ int cache_check(struct cache_detail *detail,
236 } 237 }
237 238
238 if (rv == -EAGAIN) 239 if (rv == -EAGAIN)
239 cache_defer_req(rqstp, h); 240 if (cache_defer_req(rqstp, h) != 0)
241 rv = -ETIMEDOUT;
240 242
241 if (rv) 243 if (rv)
242 cache_put(h, detail); 244 cache_put(h, detail);
@@ -284,8 +286,8 @@ static struct file_operations cache_file_operations;
284static struct file_operations content_file_operations; 286static struct file_operations content_file_operations;
285static struct file_operations cache_flush_operations; 287static struct file_operations cache_flush_operations;
286 288
287static void do_cache_clean(void *data); 289static void do_cache_clean(struct work_struct *work);
288static DECLARE_WORK(cache_cleaner, do_cache_clean, NULL); 290static DECLARE_DELAYED_WORK(cache_cleaner, do_cache_clean);
289 291
290void cache_register(struct cache_detail *cd) 292void cache_register(struct cache_detail *cd)
291{ 293{
@@ -337,7 +339,7 @@ void cache_register(struct cache_detail *cd)
337 spin_unlock(&cache_list_lock); 339 spin_unlock(&cache_list_lock);
338 340
339 /* start the cleaning process */ 341 /* start the cleaning process */
340 schedule_work(&cache_cleaner); 342 schedule_delayed_work(&cache_cleaner, 0);
341} 343}
342 344
343int cache_unregister(struct cache_detail *cd) 345int cache_unregister(struct cache_detail *cd)
@@ -461,7 +463,7 @@ static int cache_clean(void)
461/* 463/*
462 * We want to regularly clean the cache, so we need to schedule some work ... 464 * We want to regularly clean the cache, so we need to schedule some work ...
463 */ 465 */
464static void do_cache_clean(void *data) 466static void do_cache_clean(struct work_struct *work)
465{ 467{
466 int delay = 5; 468 int delay = 5;
467 if (cache_clean() == -1) 469 if (cache_clean() == -1)
@@ -523,14 +525,21 @@ static LIST_HEAD(cache_defer_list);
523static struct list_head cache_defer_hash[DFR_HASHSIZE]; 525static struct list_head cache_defer_hash[DFR_HASHSIZE];
524static int cache_defer_cnt; 526static int cache_defer_cnt;
525 527
526static void cache_defer_req(struct cache_req *req, struct cache_head *item) 528static int cache_defer_req(struct cache_req *req, struct cache_head *item)
527{ 529{
528 struct cache_deferred_req *dreq; 530 struct cache_deferred_req *dreq;
529 int hash = DFR_HASH(item); 531 int hash = DFR_HASH(item);
530 532
533 if (cache_defer_cnt >= DFR_MAX) {
534 /* too much in the cache, randomly drop this one,
535 * or continue and drop the oldest below
536 */
537 if (net_random()&1)
538 return -ETIMEDOUT;
539 }
531 dreq = req->defer(req); 540 dreq = req->defer(req);
532 if (dreq == NULL) 541 if (dreq == NULL)
533 return; 542 return -ETIMEDOUT;
534 543
535 dreq->item = item; 544 dreq->item = item;
536 dreq->recv_time = get_seconds(); 545 dreq->recv_time = get_seconds();
@@ -546,17 +555,8 @@ static void cache_defer_req(struct cache_req *req, struct cache_head *item)
546 /* it is in, now maybe clean up */ 555 /* it is in, now maybe clean up */
547 dreq = NULL; 556 dreq = NULL;
548 if (++cache_defer_cnt > DFR_MAX) { 557 if (++cache_defer_cnt > DFR_MAX) {
549 /* too much in the cache, randomly drop 558 dreq = list_entry(cache_defer_list.prev,
550 * first or last 559 struct cache_deferred_req, recent);
551 */
552 if (net_random()&1)
553 dreq = list_entry(cache_defer_list.next,
554 struct cache_deferred_req,
555 recent);
556 else
557 dreq = list_entry(cache_defer_list.prev,
558 struct cache_deferred_req,
559 recent);
560 list_del(&dreq->recent); 560 list_del(&dreq->recent);
561 list_del(&dreq->hash); 561 list_del(&dreq->hash);
562 cache_defer_cnt--; 562 cache_defer_cnt--;
@@ -571,6 +571,7 @@ static void cache_defer_req(struct cache_req *req, struct cache_head *item)
571 /* must have just been validated... */ 571 /* must have just been validated... */
572 cache_revisit_request(item); 572 cache_revisit_request(item);
573 } 573 }
574 return 0;
574} 575}
575 576
576static void cache_revisit_request(struct cache_head *item) 577static void cache_revisit_request(struct cache_head *item)
@@ -670,7 +671,7 @@ cache_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
670{ 671{
671 struct cache_reader *rp = filp->private_data; 672 struct cache_reader *rp = filp->private_data;
672 struct cache_request *rq; 673 struct cache_request *rq;
673 struct cache_detail *cd = PDE(filp->f_dentry->d_inode)->data; 674 struct cache_detail *cd = PDE(filp->f_path.dentry->d_inode)->data;
674 int err; 675 int err;
675 676
676 if (count == 0) 677 if (count == 0)
@@ -747,7 +748,7 @@ cache_write(struct file *filp, const char __user *buf, size_t count,
747 loff_t *ppos) 748 loff_t *ppos)
748{ 749{
749 int err; 750 int err;
750 struct cache_detail *cd = PDE(filp->f_dentry->d_inode)->data; 751 struct cache_detail *cd = PDE(filp->f_path.dentry->d_inode)->data;
751 752
752 if (count == 0) 753 if (count == 0)
753 return 0; 754 return 0;
@@ -778,7 +779,7 @@ cache_poll(struct file *filp, poll_table *wait)
778 unsigned int mask; 779 unsigned int mask;
779 struct cache_reader *rp = filp->private_data; 780 struct cache_reader *rp = filp->private_data;
780 struct cache_queue *cq; 781 struct cache_queue *cq;
781 struct cache_detail *cd = PDE(filp->f_dentry->d_inode)->data; 782 struct cache_detail *cd = PDE(filp->f_path.dentry->d_inode)->data;
782 783
783 poll_wait(filp, &queue_wait, wait); 784 poll_wait(filp, &queue_wait, wait);
784 785
@@ -1254,7 +1255,7 @@ static struct file_operations content_file_operations = {
1254static ssize_t read_flush(struct file *file, char __user *buf, 1255static ssize_t read_flush(struct file *file, char __user *buf,
1255 size_t count, loff_t *ppos) 1256 size_t count, loff_t *ppos)
1256{ 1257{
1257 struct cache_detail *cd = PDE(file->f_dentry->d_inode)->data; 1258 struct cache_detail *cd = PDE(file->f_path.dentry->d_inode)->data;
1258 char tbuf[20]; 1259 char tbuf[20];
1259 unsigned long p = *ppos; 1260 unsigned long p = *ppos;
1260 int len; 1261 int len;
@@ -1275,7 +1276,7 @@ static ssize_t read_flush(struct file *file, char __user *buf,
1275static ssize_t write_flush(struct file * file, const char __user * buf, 1276static ssize_t write_flush(struct file * file, const char __user * buf,
1276 size_t count, loff_t *ppos) 1277 size_t count, loff_t *ppos)
1277{ 1278{
1278 struct cache_detail *cd = PDE(file->f_dentry->d_inode)->data; 1279 struct cache_detail *cd = PDE(file->f_path.dentry->d_inode)->data;
1279 char tbuf[20]; 1280 char tbuf[20];
1280 char *ep; 1281 char *ep;
1281 long flushtime; 1282 long flushtime;
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 78696f2dc7..aba528b9ae 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -27,6 +27,7 @@
27#include <linux/types.h> 27#include <linux/types.h>
28#include <linux/mm.h> 28#include <linux/mm.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30#include <linux/smp_lock.h>
30#include <linux/utsname.h> 31#include <linux/utsname.h>
31#include <linux/workqueue.h> 32#include <linux/workqueue.h>
32 33
@@ -141,6 +142,10 @@ static struct rpc_clnt * rpc_new_client(struct rpc_xprt *xprt, char *servname, s
141 clnt->cl_vers = version->number; 142 clnt->cl_vers = version->number;
142 clnt->cl_stats = program->stats; 143 clnt->cl_stats = program->stats;
143 clnt->cl_metrics = rpc_alloc_iostats(clnt); 144 clnt->cl_metrics = rpc_alloc_iostats(clnt);
145 err = -ENOMEM;
146 if (clnt->cl_metrics == NULL)
147 goto out_no_stats;
148 clnt->cl_program = program;
144 149
145 if (!xprt_bound(clnt->cl_xprt)) 150 if (!xprt_bound(clnt->cl_xprt))
146 clnt->cl_autobind = 1; 151 clnt->cl_autobind = 1;
@@ -173,6 +178,8 @@ out_no_auth:
173 rpc_put_mount(); 178 rpc_put_mount();
174 } 179 }
175out_no_path: 180out_no_path:
181 rpc_free_iostats(clnt->cl_metrics);
182out_no_stats:
176 if (clnt->cl_server != clnt->cl_inline_name) 183 if (clnt->cl_server != clnt->cl_inline_name)
177 kfree(clnt->cl_server); 184 kfree(clnt->cl_server);
178 kfree(clnt); 185 kfree(clnt);
@@ -252,13 +259,19 @@ struct rpc_clnt *
252rpc_clone_client(struct rpc_clnt *clnt) 259rpc_clone_client(struct rpc_clnt *clnt)
253{ 260{
254 struct rpc_clnt *new; 261 struct rpc_clnt *new;
262 int err = -ENOMEM;
255 263
256 new = kmalloc(sizeof(*new), GFP_KERNEL); 264 new = kmemdup(clnt, sizeof(*new), GFP_KERNEL);
257 if (!new) 265 if (!new)
258 goto out_no_clnt; 266 goto out_no_clnt;
259 memcpy(new, clnt, sizeof(*new));
260 atomic_set(&new->cl_count, 1); 267 atomic_set(&new->cl_count, 1);
261 atomic_set(&new->cl_users, 0); 268 atomic_set(&new->cl_users, 0);
269 new->cl_metrics = rpc_alloc_iostats(clnt);
270 if (new->cl_metrics == NULL)
271 goto out_no_stats;
272 err = rpc_setup_pipedir(new, clnt->cl_program->pipe_dir_name);
273 if (err != 0)
274 goto out_no_path;
262 new->cl_parent = clnt; 275 new->cl_parent = clnt;
263 atomic_inc(&clnt->cl_count); 276 atomic_inc(&clnt->cl_count);
264 new->cl_xprt = xprt_get(clnt->cl_xprt); 277 new->cl_xprt = xprt_get(clnt->cl_xprt);
@@ -266,16 +279,17 @@ rpc_clone_client(struct rpc_clnt *clnt)
266 new->cl_autobind = 0; 279 new->cl_autobind = 0;
267 new->cl_oneshot = 0; 280 new->cl_oneshot = 0;
268 new->cl_dead = 0; 281 new->cl_dead = 0;
269 if (!IS_ERR(new->cl_dentry))
270 dget(new->cl_dentry);
271 rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval); 282 rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval);
272 if (new->cl_auth) 283 if (new->cl_auth)
273 atomic_inc(&new->cl_auth->au_count); 284 atomic_inc(&new->cl_auth->au_count);
274 new->cl_metrics = rpc_alloc_iostats(clnt);
275 return new; 285 return new;
286out_no_path:
287 rpc_free_iostats(new->cl_metrics);
288out_no_stats:
289 kfree(new);
276out_no_clnt: 290out_no_clnt:
277 printk(KERN_INFO "RPC: out of memory in %s\n", __FUNCTION__); 291 dprintk("RPC: %s returned error %d\n", __FUNCTION__, err);
278 return ERR_PTR(-ENOMEM); 292 return ERR_PTR(err);
279} 293}
280 294
281/* 295/*
@@ -328,16 +342,14 @@ rpc_destroy_client(struct rpc_clnt *clnt)
328 rpcauth_destroy(clnt->cl_auth); 342 rpcauth_destroy(clnt->cl_auth);
329 clnt->cl_auth = NULL; 343 clnt->cl_auth = NULL;
330 } 344 }
331 if (clnt->cl_parent != clnt) {
332 if (!IS_ERR(clnt->cl_dentry))
333 dput(clnt->cl_dentry);
334 rpc_destroy_client(clnt->cl_parent);
335 goto out_free;
336 }
337 if (!IS_ERR(clnt->cl_dentry)) { 345 if (!IS_ERR(clnt->cl_dentry)) {
338 rpc_rmdir(clnt->cl_dentry); 346 rpc_rmdir(clnt->cl_dentry);
339 rpc_put_mount(); 347 rpc_put_mount();
340 } 348 }
349 if (clnt->cl_parent != clnt) {
350 rpc_destroy_client(clnt->cl_parent);
351 goto out_free;
352 }
341 if (clnt->cl_server != clnt->cl_inline_name) 353 if (clnt->cl_server != clnt->cl_inline_name)
342 kfree(clnt->cl_server); 354 kfree(clnt->cl_server);
343out_free: 355out_free:
@@ -467,10 +479,9 @@ int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
467 479
468 BUG_ON(flags & RPC_TASK_ASYNC); 480 BUG_ON(flags & RPC_TASK_ASYNC);
469 481
470 status = -ENOMEM;
471 task = rpc_new_task(clnt, flags, &rpc_default_ops, NULL); 482 task = rpc_new_task(clnt, flags, &rpc_default_ops, NULL);
472 if (task == NULL) 483 if (task == NULL)
473 goto out; 484 return -ENOMEM;
474 485
475 /* Mask signals on RPC calls _and_ GSS_AUTH upcalls */ 486 /* Mask signals on RPC calls _and_ GSS_AUTH upcalls */
476 rpc_task_sigmask(task, &oldset); 487 rpc_task_sigmask(task, &oldset);
@@ -479,15 +490,17 @@ int rpc_call_sync(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
479 490
480 /* Set up the call info struct and execute the task */ 491 /* Set up the call info struct and execute the task */
481 status = task->tk_status; 492 status = task->tk_status;
482 if (status == 0) { 493 if (status != 0) {
483 atomic_inc(&task->tk_count); 494 rpc_release_task(task);
484 status = rpc_execute(task); 495 goto out;
485 if (status == 0)
486 status = task->tk_status;
487 } 496 }
488 rpc_restore_sigmask(&oldset); 497 atomic_inc(&task->tk_count);
489 rpc_release_task(task); 498 status = rpc_execute(task);
499 if (status == 0)
500 status = task->tk_status;
501 rpc_put_task(task);
490out: 502out:
503 rpc_restore_sigmask(&oldset);
491 return status; 504 return status;
492} 505}
493 506
@@ -529,8 +542,7 @@ rpc_call_async(struct rpc_clnt *clnt, struct rpc_message *msg, int flags,
529 rpc_restore_sigmask(&oldset); 542 rpc_restore_sigmask(&oldset);
530 return status; 543 return status;
531out_release: 544out_release:
532 if (tk_ops->rpc_release != NULL) 545 rpc_release_calldata(tk_ops, data);
533 tk_ops->rpc_release(data);
534 return status; 546 return status;
535} 547}
536 548
@@ -582,7 +594,11 @@ EXPORT_SYMBOL_GPL(rpc_peeraddr);
582char *rpc_peeraddr2str(struct rpc_clnt *clnt, enum rpc_display_format_t format) 594char *rpc_peeraddr2str(struct rpc_clnt *clnt, enum rpc_display_format_t format)
583{ 595{
584 struct rpc_xprt *xprt = clnt->cl_xprt; 596 struct rpc_xprt *xprt = clnt->cl_xprt;
585 return xprt->ops->print_addr(xprt, format); 597
598 if (xprt->address_strings[format] != NULL)
599 return xprt->address_strings[format];
600 else
601 return "unprintable";
586} 602}
587EXPORT_SYMBOL_GPL(rpc_peeraddr2str); 603EXPORT_SYMBOL_GPL(rpc_peeraddr2str);
588 604
@@ -812,8 +828,10 @@ call_encode(struct rpc_task *task)
812 if (encode == NULL) 828 if (encode == NULL)
813 return; 829 return;
814 830
831 lock_kernel();
815 task->tk_status = rpcauth_wrap_req(task, encode, req, p, 832 task->tk_status = rpcauth_wrap_req(task, encode, req, p,
816 task->tk_msg.rpc_argp); 833 task->tk_msg.rpc_argp);
834 unlock_kernel();
817 if (task->tk_status == -ENOMEM) { 835 if (task->tk_status == -ENOMEM) {
818 /* XXX: Is this sane? */ 836 /* XXX: Is this sane? */
819 rpc_delay(task, 3*HZ); 837 rpc_delay(task, 3*HZ);
@@ -1144,9 +1162,12 @@ call_decode(struct rpc_task *task)
1144 1162
1145 task->tk_action = rpc_exit_task; 1163 task->tk_action = rpc_exit_task;
1146 1164
1147 if (decode) 1165 if (decode) {
1166 lock_kernel();
1148 task->tk_status = rpcauth_unwrap_resp(task, decode, req, p, 1167 task->tk_status = rpcauth_unwrap_resp(task, decode, req, p,
1149 task->tk_msg.rpc_resp); 1168 task->tk_msg.rpc_resp);
1169 unlock_kernel();
1170 }
1150 dprintk("RPC: %4d call_decode result %d\n", task->tk_pid, 1171 dprintk("RPC: %4d call_decode result %d\n", task->tk_pid,
1151 task->tk_status); 1172 task->tk_status);
1152 return; 1173 return;
diff --git a/net/sunrpc/pmap_clnt.c b/net/sunrpc/pmap_clnt.c
index e52afab413..3946ec3eb5 100644
--- a/net/sunrpc/pmap_clnt.c
+++ b/net/sunrpc/pmap_clnt.c
@@ -101,14 +101,14 @@ void rpc_getport(struct rpc_task *task)
101 /* Autobind on cloned rpc clients is discouraged */ 101 /* Autobind on cloned rpc clients is discouraged */
102 BUG_ON(clnt->cl_parent != clnt); 102 BUG_ON(clnt->cl_parent != clnt);
103 103
104 status = -EACCES; /* tell caller to check again */
105 if (xprt_test_and_set_binding(xprt))
106 goto bailout_nowake;
107
104 /* Put self on queue before sending rpcbind request, in case 108 /* Put self on queue before sending rpcbind request, in case
105 * pmap_getport_done completes before we return from rpc_run_task */ 109 * pmap_getport_done completes before we return from rpc_run_task */
106 rpc_sleep_on(&xprt->binding, task, NULL, NULL); 110 rpc_sleep_on(&xprt->binding, task, NULL, NULL);
107 111
108 status = -EACCES; /* tell caller to check again */
109 if (xprt_test_and_set_binding(xprt))
110 goto bailout_nofree;
111
112 /* Someone else may have bound if we slept */ 112 /* Someone else may have bound if we slept */
113 status = 0; 113 status = 0;
114 if (xprt_bound(xprt)) 114 if (xprt_bound(xprt))
@@ -134,7 +134,7 @@ void rpc_getport(struct rpc_task *task)
134 child = rpc_run_task(pmap_clnt, RPC_TASK_ASYNC, &pmap_getport_ops, map); 134 child = rpc_run_task(pmap_clnt, RPC_TASK_ASYNC, &pmap_getport_ops, map);
135 if (IS_ERR(child)) 135 if (IS_ERR(child))
136 goto bailout; 136 goto bailout;
137 rpc_release_task(child); 137 rpc_put_task(child);
138 138
139 task->tk_xprt->stat.bind_count++; 139 task->tk_xprt->stat.bind_count++;
140 return; 140 return;
@@ -143,8 +143,9 @@ bailout:
143 pmap_map_free(map); 143 pmap_map_free(map);
144 xprt_put(xprt); 144 xprt_put(xprt);
145bailout_nofree: 145bailout_nofree:
146 task->tk_status = status;
147 pmap_wake_portmap_waiters(xprt, status); 146 pmap_wake_portmap_waiters(xprt, status);
147bailout_nowake:
148 task->tk_status = status;
148} 149}
149 150
150#ifdef CONFIG_ROOT_NFS 151#ifdef CONFIG_ROOT_NFS
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 9a0b41a97f..89273d35e0 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -33,7 +33,7 @@ static int rpc_mount_count;
33static struct file_system_type rpc_pipe_fs_type; 33static struct file_system_type rpc_pipe_fs_type;
34 34
35 35
36static kmem_cache_t *rpc_inode_cachep __read_mostly; 36static struct kmem_cache *rpc_inode_cachep __read_mostly;
37 37
38#define RPC_UPCALL_TIMEOUT (30*HZ) 38#define RPC_UPCALL_TIMEOUT (30*HZ)
39 39
@@ -54,10 +54,11 @@ static void rpc_purge_list(struct rpc_inode *rpci, struct list_head *head,
54} 54}
55 55
56static void 56static void
57rpc_timeout_upcall_queue(void *data) 57rpc_timeout_upcall_queue(struct work_struct *work)
58{ 58{
59 LIST_HEAD(free_list); 59 LIST_HEAD(free_list);
60 struct rpc_inode *rpci = (struct rpc_inode *)data; 60 struct rpc_inode *rpci =
61 container_of(work, struct rpc_inode, queue_timeout.work);
61 struct inode *inode = &rpci->vfs_inode; 62 struct inode *inode = &rpci->vfs_inode;
62 void (*destroy_msg)(struct rpc_pipe_msg *); 63 void (*destroy_msg)(struct rpc_pipe_msg *);
63 64
@@ -142,7 +143,7 @@ static struct inode *
142rpc_alloc_inode(struct super_block *sb) 143rpc_alloc_inode(struct super_block *sb)
143{ 144{
144 struct rpc_inode *rpci; 145 struct rpc_inode *rpci;
145 rpci = (struct rpc_inode *)kmem_cache_alloc(rpc_inode_cachep, SLAB_KERNEL); 146 rpci = (struct rpc_inode *)kmem_cache_alloc(rpc_inode_cachep, GFP_KERNEL);
146 if (!rpci) 147 if (!rpci)
147 return NULL; 148 return NULL;
148 return &rpci->vfs_inode; 149 return &rpci->vfs_inode;
@@ -213,7 +214,7 @@ out:
213static ssize_t 214static ssize_t
214rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset) 215rpc_pipe_read(struct file *filp, char __user *buf, size_t len, loff_t *offset)
215{ 216{
216 struct inode *inode = filp->f_dentry->d_inode; 217 struct inode *inode = filp->f_path.dentry->d_inode;
217 struct rpc_inode *rpci = RPC_I(inode); 218 struct rpc_inode *rpci = RPC_I(inode);
218 struct rpc_pipe_msg *msg; 219 struct rpc_pipe_msg *msg;
219 int res = 0; 220 int res = 0;
@@ -256,7 +257,7 @@ out_unlock:
256static ssize_t 257static ssize_t
257rpc_pipe_write(struct file *filp, const char __user *buf, size_t len, loff_t *offset) 258rpc_pipe_write(struct file *filp, const char __user *buf, size_t len, loff_t *offset)
258{ 259{
259 struct inode *inode = filp->f_dentry->d_inode; 260 struct inode *inode = filp->f_path.dentry->d_inode;
260 struct rpc_inode *rpci = RPC_I(inode); 261 struct rpc_inode *rpci = RPC_I(inode);
261 int res; 262 int res;
262 263
@@ -274,7 +275,7 @@ rpc_pipe_poll(struct file *filp, struct poll_table_struct *wait)
274 struct rpc_inode *rpci; 275 struct rpc_inode *rpci;
275 unsigned int mask = 0; 276 unsigned int mask = 0;
276 277
277 rpci = RPC_I(filp->f_dentry->d_inode); 278 rpci = RPC_I(filp->f_path.dentry->d_inode);
278 poll_wait(filp, &rpci->waitq, wait); 279 poll_wait(filp, &rpci->waitq, wait);
279 280
280 mask = POLLOUT | POLLWRNORM; 281 mask = POLLOUT | POLLWRNORM;
@@ -289,7 +290,7 @@ static int
289rpc_pipe_ioctl(struct inode *ino, struct file *filp, 290rpc_pipe_ioctl(struct inode *ino, struct file *filp,
290 unsigned int cmd, unsigned long arg) 291 unsigned int cmd, unsigned long arg)
291{ 292{
292 struct rpc_inode *rpci = RPC_I(filp->f_dentry->d_inode); 293 struct rpc_inode *rpci = RPC_I(filp->f_path.dentry->d_inode);
293 int len; 294 int len;
294 295
295 switch (cmd) { 296 switch (cmd) {
@@ -823,7 +824,7 @@ static struct file_system_type rpc_pipe_fs_type = {
823}; 824};
824 825
825static void 826static void
826init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) 827init_once(void * foo, struct kmem_cache * cachep, unsigned long flags)
827{ 828{
828 struct rpc_inode *rpci = (struct rpc_inode *) foo; 829 struct rpc_inode *rpci = (struct rpc_inode *) foo;
829 830
@@ -837,7 +838,8 @@ init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
837 INIT_LIST_HEAD(&rpci->pipe); 838 INIT_LIST_HEAD(&rpci->pipe);
838 rpci->pipelen = 0; 839 rpci->pipelen = 0;
839 init_waitqueue_head(&rpci->waitq); 840 init_waitqueue_head(&rpci->waitq);
840 INIT_WORK(&rpci->queue_timeout, rpc_timeout_upcall_queue, rpci); 841 INIT_DELAYED_WORK(&rpci->queue_timeout,
842 rpc_timeout_upcall_queue);
841 rpci->ops = NULL; 843 rpci->ops = NULL;
842 } 844 }
843} 845}
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index a1ab4eed41..79bc4cdf5d 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -34,14 +34,14 @@ static int rpc_task_id;
34#define RPC_BUFFER_MAXSIZE (2048) 34#define RPC_BUFFER_MAXSIZE (2048)
35#define RPC_BUFFER_POOLSIZE (8) 35#define RPC_BUFFER_POOLSIZE (8)
36#define RPC_TASK_POOLSIZE (8) 36#define RPC_TASK_POOLSIZE (8)
37static kmem_cache_t *rpc_task_slabp __read_mostly; 37static struct kmem_cache *rpc_task_slabp __read_mostly;
38static kmem_cache_t *rpc_buffer_slabp __read_mostly; 38static struct kmem_cache *rpc_buffer_slabp __read_mostly;
39static mempool_t *rpc_task_mempool __read_mostly; 39static mempool_t *rpc_task_mempool __read_mostly;
40static mempool_t *rpc_buffer_mempool __read_mostly; 40static mempool_t *rpc_buffer_mempool __read_mostly;
41 41
42static void __rpc_default_timer(struct rpc_task *task); 42static void __rpc_default_timer(struct rpc_task *task);
43static void rpciod_killall(void); 43static void rpciod_killall(void);
44static void rpc_async_schedule(void *); 44static void rpc_async_schedule(struct work_struct *);
45 45
46/* 46/*
47 * RPC tasks sit here while waiting for conditions to improve. 47 * RPC tasks sit here while waiting for conditions to improve.
@@ -266,12 +266,28 @@ static int rpc_wait_bit_interruptible(void *word)
266 return 0; 266 return 0;
267} 267}
268 268
269static void rpc_set_active(struct rpc_task *task)
270{
271 if (test_and_set_bit(RPC_TASK_ACTIVE, &task->tk_runstate) != 0)
272 return;
273 spin_lock(&rpc_sched_lock);
274#ifdef RPC_DEBUG
275 task->tk_magic = RPC_TASK_MAGIC_ID;
276 task->tk_pid = rpc_task_id++;
277#endif
278 /* Add to global list of all tasks */
279 list_add_tail(&task->tk_task, &all_tasks);
280 spin_unlock(&rpc_sched_lock);
281}
282
269/* 283/*
270 * Mark an RPC call as having completed by clearing the 'active' bit 284 * Mark an RPC call as having completed by clearing the 'active' bit
271 */ 285 */
272static inline void rpc_mark_complete_task(struct rpc_task *task) 286static void rpc_mark_complete_task(struct rpc_task *task)
273{ 287{
274 rpc_clear_active(task); 288 smp_mb__before_clear_bit();
289 clear_bit(RPC_TASK_ACTIVE, &task->tk_runstate);
290 smp_mb__after_clear_bit();
275 wake_up_bit(&task->tk_runstate, RPC_TASK_ACTIVE); 291 wake_up_bit(&task->tk_runstate, RPC_TASK_ACTIVE);
276} 292}
277 293
@@ -295,17 +311,19 @@ EXPORT_SYMBOL(__rpc_wait_for_completion_task);
295 */ 311 */
296static void rpc_make_runnable(struct rpc_task *task) 312static void rpc_make_runnable(struct rpc_task *task)
297{ 313{
298 int do_ret;
299
300 BUG_ON(task->tk_timeout_fn); 314 BUG_ON(task->tk_timeout_fn);
301 do_ret = rpc_test_and_set_running(task);
302 rpc_clear_queued(task); 315 rpc_clear_queued(task);
303 if (do_ret) 316 if (rpc_test_and_set_running(task))
304 return; 317 return;
318 /* We might have raced */
319 if (RPC_IS_QUEUED(task)) {
320 rpc_clear_running(task);
321 return;
322 }
305 if (RPC_IS_ASYNC(task)) { 323 if (RPC_IS_ASYNC(task)) {
306 int status; 324 int status;
307 325
308 INIT_WORK(&task->u.tk_work, rpc_async_schedule, (void *)task); 326 INIT_WORK(&task->u.tk_work, rpc_async_schedule);
309 status = queue_work(task->tk_workqueue, &task->u.tk_work); 327 status = queue_work(task->tk_workqueue, &task->u.tk_work);
310 if (status < 0) { 328 if (status < 0) {
311 printk(KERN_WARNING "RPC: failed to add task to queue: error: %d!\n", status); 329 printk(KERN_WARNING "RPC: failed to add task to queue: error: %d!\n", status);
@@ -333,9 +351,6 @@ static void __rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
333 return; 351 return;
334 } 352 }
335 353
336 /* Mark the task as being activated if so needed */
337 rpc_set_active(task);
338
339 __rpc_add_wait_queue(q, task); 354 __rpc_add_wait_queue(q, task);
340 355
341 BUG_ON(task->tk_callback != NULL); 356 BUG_ON(task->tk_callback != NULL);
@@ -346,6 +361,9 @@ static void __rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
346void rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task, 361void rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task,
347 rpc_action action, rpc_action timer) 362 rpc_action action, rpc_action timer)
348{ 363{
364 /* Mark the task as being activated if so needed */
365 rpc_set_active(task);
366
349 /* 367 /*
350 * Protect the queue operations. 368 * Protect the queue operations.
351 */ 369 */
@@ -409,16 +427,19 @@ __rpc_default_timer(struct rpc_task *task)
409 */ 427 */
410void rpc_wake_up_task(struct rpc_task *task) 428void rpc_wake_up_task(struct rpc_task *task)
411{ 429{
430 rcu_read_lock_bh();
412 if (rpc_start_wakeup(task)) { 431 if (rpc_start_wakeup(task)) {
413 if (RPC_IS_QUEUED(task)) { 432 if (RPC_IS_QUEUED(task)) {
414 struct rpc_wait_queue *queue = task->u.tk_wait.rpc_waitq; 433 struct rpc_wait_queue *queue = task->u.tk_wait.rpc_waitq;
415 434
416 spin_lock_bh(&queue->lock); 435 /* Note: we're already in a bh-safe context */
436 spin_lock(&queue->lock);
417 __rpc_do_wake_up_task(task); 437 __rpc_do_wake_up_task(task);
418 spin_unlock_bh(&queue->lock); 438 spin_unlock(&queue->lock);
419 } 439 }
420 rpc_finish_wakeup(task); 440 rpc_finish_wakeup(task);
421 } 441 }
442 rcu_read_unlock_bh();
422} 443}
423 444
424/* 445/*
@@ -481,14 +502,16 @@ struct rpc_task * rpc_wake_up_next(struct rpc_wait_queue *queue)
481 struct rpc_task *task = NULL; 502 struct rpc_task *task = NULL;
482 503
483 dprintk("RPC: wake_up_next(%p \"%s\")\n", queue, rpc_qname(queue)); 504 dprintk("RPC: wake_up_next(%p \"%s\")\n", queue, rpc_qname(queue));
484 spin_lock_bh(&queue->lock); 505 rcu_read_lock_bh();
506 spin_lock(&queue->lock);
485 if (RPC_IS_PRIORITY(queue)) 507 if (RPC_IS_PRIORITY(queue))
486 task = __rpc_wake_up_next_priority(queue); 508 task = __rpc_wake_up_next_priority(queue);
487 else { 509 else {
488 task_for_first(task, &queue->tasks[0]) 510 task_for_first(task, &queue->tasks[0])
489 __rpc_wake_up_task(task); 511 __rpc_wake_up_task(task);
490 } 512 }
491 spin_unlock_bh(&queue->lock); 513 spin_unlock(&queue->lock);
514 rcu_read_unlock_bh();
492 515
493 return task; 516 return task;
494} 517}
@@ -504,7 +527,8 @@ void rpc_wake_up(struct rpc_wait_queue *queue)
504 struct rpc_task *task, *next; 527 struct rpc_task *task, *next;
505 struct list_head *head; 528 struct list_head *head;
506 529
507 spin_lock_bh(&queue->lock); 530 rcu_read_lock_bh();
531 spin_lock(&queue->lock);
508 head = &queue->tasks[queue->maxpriority]; 532 head = &queue->tasks[queue->maxpriority];
509 for (;;) { 533 for (;;) {
510 list_for_each_entry_safe(task, next, head, u.tk_wait.list) 534 list_for_each_entry_safe(task, next, head, u.tk_wait.list)
@@ -513,7 +537,8 @@ void rpc_wake_up(struct rpc_wait_queue *queue)
513 break; 537 break;
514 head--; 538 head--;
515 } 539 }
516 spin_unlock_bh(&queue->lock); 540 spin_unlock(&queue->lock);
541 rcu_read_unlock_bh();
517} 542}
518 543
519/** 544/**
@@ -528,7 +553,8 @@ void rpc_wake_up_status(struct rpc_wait_queue *queue, int status)
528 struct rpc_task *task, *next; 553 struct rpc_task *task, *next;
529 struct list_head *head; 554 struct list_head *head;
530 555
531 spin_lock_bh(&queue->lock); 556 rcu_read_lock_bh();
557 spin_lock(&queue->lock);
532 head = &queue->tasks[queue->maxpriority]; 558 head = &queue->tasks[queue->maxpriority];
533 for (;;) { 559 for (;;) {
534 list_for_each_entry_safe(task, next, head, u.tk_wait.list) { 560 list_for_each_entry_safe(task, next, head, u.tk_wait.list) {
@@ -539,7 +565,8 @@ void rpc_wake_up_status(struct rpc_wait_queue *queue, int status)
539 break; 565 break;
540 head--; 566 head--;
541 } 567 }
542 spin_unlock_bh(&queue->lock); 568 spin_unlock(&queue->lock);
569 rcu_read_unlock_bh();
543} 570}
544 571
545static void __rpc_atrun(struct rpc_task *task) 572static void __rpc_atrun(struct rpc_task *task)
@@ -561,7 +588,9 @@ void rpc_delay(struct rpc_task *task, unsigned long delay)
561 */ 588 */
562static void rpc_prepare_task(struct rpc_task *task) 589static void rpc_prepare_task(struct rpc_task *task)
563{ 590{
591 lock_kernel();
564 task->tk_ops->rpc_call_prepare(task, task->tk_calldata); 592 task->tk_ops->rpc_call_prepare(task, task->tk_calldata);
593 unlock_kernel();
565} 594}
566 595
567/* 596/*
@@ -571,7 +600,9 @@ void rpc_exit_task(struct rpc_task *task)
571{ 600{
572 task->tk_action = NULL; 601 task->tk_action = NULL;
573 if (task->tk_ops->rpc_call_done != NULL) { 602 if (task->tk_ops->rpc_call_done != NULL) {
603 lock_kernel();
574 task->tk_ops->rpc_call_done(task, task->tk_calldata); 604 task->tk_ops->rpc_call_done(task, task->tk_calldata);
605 unlock_kernel();
575 if (task->tk_action != NULL) { 606 if (task->tk_action != NULL) {
576 WARN_ON(RPC_ASSASSINATED(task)); 607 WARN_ON(RPC_ASSASSINATED(task));
577 /* Always release the RPC slot and buffer memory */ 608 /* Always release the RPC slot and buffer memory */
@@ -581,6 +612,15 @@ void rpc_exit_task(struct rpc_task *task)
581} 612}
582EXPORT_SYMBOL(rpc_exit_task); 613EXPORT_SYMBOL(rpc_exit_task);
583 614
615void rpc_release_calldata(const struct rpc_call_ops *ops, void *calldata)
616{
617 if (ops->rpc_release != NULL) {
618 lock_kernel();
619 ops->rpc_release(calldata);
620 unlock_kernel();
621 }
622}
623
584/* 624/*
585 * This is the RPC `scheduler' (or rather, the finite state machine). 625 * This is the RPC `scheduler' (or rather, the finite state machine).
586 */ 626 */
@@ -615,9 +655,7 @@ static int __rpc_execute(struct rpc_task *task)
615 */ 655 */
616 save_callback=task->tk_callback; 656 save_callback=task->tk_callback;
617 task->tk_callback=NULL; 657 task->tk_callback=NULL;
618 lock_kernel();
619 save_callback(task); 658 save_callback(task);
620 unlock_kernel();
621 } 659 }
622 660
623 /* 661 /*
@@ -628,9 +666,7 @@ static int __rpc_execute(struct rpc_task *task)
628 if (!RPC_IS_QUEUED(task)) { 666 if (!RPC_IS_QUEUED(task)) {
629 if (task->tk_action == NULL) 667 if (task->tk_action == NULL)
630 break; 668 break;
631 lock_kernel();
632 task->tk_action(task); 669 task->tk_action(task);
633 unlock_kernel();
634 } 670 }
635 671
636 /* 672 /*
@@ -671,8 +707,6 @@ static int __rpc_execute(struct rpc_task *task)
671 } 707 }
672 708
673 dprintk("RPC: %4d, return %d, status %d\n", task->tk_pid, status, task->tk_status); 709 dprintk("RPC: %4d, return %d, status %d\n", task->tk_pid, status, task->tk_status);
674 /* Wake up anyone who is waiting for task completion */
675 rpc_mark_complete_task(task);
676 /* Release all resources associated with the task */ 710 /* Release all resources associated with the task */
677 rpc_release_task(task); 711 rpc_release_task(task);
678 return status; 712 return status;
@@ -695,9 +729,9 @@ rpc_execute(struct rpc_task *task)
695 return __rpc_execute(task); 729 return __rpc_execute(task);
696} 730}
697 731
698static void rpc_async_schedule(void *arg) 732static void rpc_async_schedule(struct work_struct *work)
699{ 733{
700 __rpc_execute((struct rpc_task *)arg); 734 __rpc_execute(container_of(work, struct rpc_task, u.tk_work));
701} 735}
702 736
703/** 737/**
@@ -786,15 +820,6 @@ void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, int flags, cons
786 task->tk_flags |= RPC_TASK_NOINTR; 820 task->tk_flags |= RPC_TASK_NOINTR;
787 } 821 }
788 822
789#ifdef RPC_DEBUG
790 task->tk_magic = RPC_TASK_MAGIC_ID;
791 task->tk_pid = rpc_task_id++;
792#endif
793 /* Add to global list of all tasks */
794 spin_lock(&rpc_sched_lock);
795 list_add_tail(&task->tk_task, &all_tasks);
796 spin_unlock(&rpc_sched_lock);
797
798 BUG_ON(task->tk_ops == NULL); 823 BUG_ON(task->tk_ops == NULL);
799 824
800 /* starting timestamp */ 825 /* starting timestamp */
@@ -810,8 +835,9 @@ rpc_alloc_task(void)
810 return (struct rpc_task *)mempool_alloc(rpc_task_mempool, GFP_NOFS); 835 return (struct rpc_task *)mempool_alloc(rpc_task_mempool, GFP_NOFS);
811} 836}
812 837
813static void rpc_free_task(struct rpc_task *task) 838static void rpc_free_task(struct rcu_head *rcu)
814{ 839{
840 struct rpc_task *task = container_of(rcu, struct rpc_task, u.tk_rcu);
815 dprintk("RPC: %4d freeing task\n", task->tk_pid); 841 dprintk("RPC: %4d freeing task\n", task->tk_pid);
816 mempool_free(task, rpc_task_mempool); 842 mempool_free(task, rpc_task_mempool);
817} 843}
@@ -847,16 +873,34 @@ cleanup:
847 goto out; 873 goto out;
848} 874}
849 875
850void rpc_release_task(struct rpc_task *task) 876
877void rpc_put_task(struct rpc_task *task)
851{ 878{
852 const struct rpc_call_ops *tk_ops = task->tk_ops; 879 const struct rpc_call_ops *tk_ops = task->tk_ops;
853 void *calldata = task->tk_calldata; 880 void *calldata = task->tk_calldata;
854 881
882 if (!atomic_dec_and_test(&task->tk_count))
883 return;
884 /* Release resources */
885 if (task->tk_rqstp)
886 xprt_release(task);
887 if (task->tk_msg.rpc_cred)
888 rpcauth_unbindcred(task);
889 if (task->tk_client) {
890 rpc_release_client(task->tk_client);
891 task->tk_client = NULL;
892 }
893 if (task->tk_flags & RPC_TASK_DYNAMIC)
894 call_rcu_bh(&task->u.tk_rcu, rpc_free_task);
895 rpc_release_calldata(tk_ops, calldata);
896}
897EXPORT_SYMBOL(rpc_put_task);
898
899void rpc_release_task(struct rpc_task *task)
900{
855#ifdef RPC_DEBUG 901#ifdef RPC_DEBUG
856 BUG_ON(task->tk_magic != RPC_TASK_MAGIC_ID); 902 BUG_ON(task->tk_magic != RPC_TASK_MAGIC_ID);
857#endif 903#endif
858 if (!atomic_dec_and_test(&task->tk_count))
859 return;
860 dprintk("RPC: %4d release task\n", task->tk_pid); 904 dprintk("RPC: %4d release task\n", task->tk_pid);
861 905
862 /* Remove from global task list */ 906 /* Remove from global task list */
@@ -869,23 +913,13 @@ void rpc_release_task(struct rpc_task *task)
869 /* Synchronously delete any running timer */ 913 /* Synchronously delete any running timer */
870 rpc_delete_timer(task); 914 rpc_delete_timer(task);
871 915
872 /* Release resources */
873 if (task->tk_rqstp)
874 xprt_release(task);
875 if (task->tk_msg.rpc_cred)
876 rpcauth_unbindcred(task);
877 if (task->tk_client) {
878 rpc_release_client(task->tk_client);
879 task->tk_client = NULL;
880 }
881
882#ifdef RPC_DEBUG 916#ifdef RPC_DEBUG
883 task->tk_magic = 0; 917 task->tk_magic = 0;
884#endif 918#endif
885 if (task->tk_flags & RPC_TASK_DYNAMIC) 919 /* Wake up anyone who is waiting for task completion */
886 rpc_free_task(task); 920 rpc_mark_complete_task(task);
887 if (tk_ops->rpc_release) 921
888 tk_ops->rpc_release(calldata); 922 rpc_put_task(task);
889} 923}
890 924
891/** 925/**
@@ -902,8 +936,7 @@ struct rpc_task *rpc_run_task(struct rpc_clnt *clnt, int flags,
902 struct rpc_task *task; 936 struct rpc_task *task;
903 task = rpc_new_task(clnt, flags, ops, data); 937 task = rpc_new_task(clnt, flags, ops, data);
904 if (task == NULL) { 938 if (task == NULL) {
905 if (ops->rpc_release != NULL) 939 rpc_release_calldata(ops, data);
906 ops->rpc_release(data);
907 return ERR_PTR(-ENOMEM); 940 return ERR_PTR(-ENOMEM);
908 } 941 }
909 atomic_inc(&task->tk_count); 942 atomic_inc(&task->tk_count);
diff --git a/net/sunrpc/socklib.c b/net/sunrpc/socklib.c
index 6f17527b9e..634885b0c0 100644
--- a/net/sunrpc/socklib.c
+++ b/net/sunrpc/socklib.c
@@ -16,7 +16,7 @@
16 16
17 17
18/** 18/**
19 * skb_read_bits - copy some data bits from skb to internal buffer 19 * xdr_skb_read_bits - copy some data bits from skb to internal buffer
20 * @desc: sk_buff copy helper 20 * @desc: sk_buff copy helper
21 * @to: copy destination 21 * @to: copy destination
22 * @len: number of bytes to copy 22 * @len: number of bytes to copy
@@ -24,11 +24,11 @@
24 * Possibly called several times to iterate over an sk_buff and copy 24 * Possibly called several times to iterate over an sk_buff and copy
25 * data out of it. 25 * data out of it.
26 */ 26 */
27static size_t skb_read_bits(skb_reader_t *desc, void *to, size_t len) 27size_t xdr_skb_read_bits(struct xdr_skb_reader *desc, void *to, size_t len)
28{ 28{
29 if (len > desc->count) 29 if (len > desc->count)
30 len = desc->count; 30 len = desc->count;
31 if (skb_copy_bits(desc->skb, desc->offset, to, len)) 31 if (unlikely(skb_copy_bits(desc->skb, desc->offset, to, len)))
32 return 0; 32 return 0;
33 desc->count -= len; 33 desc->count -= len;
34 desc->offset += len; 34 desc->offset += len;
@@ -36,16 +36,17 @@ static size_t skb_read_bits(skb_reader_t *desc, void *to, size_t len)
36} 36}
37 37
38/** 38/**
39 * skb_read_and_csum_bits - copy and checksum from skb to buffer 39 * xdr_skb_read_and_csum_bits - copy and checksum from skb to buffer
40 * @desc: sk_buff copy helper 40 * @desc: sk_buff copy helper
41 * @to: copy destination 41 * @to: copy destination
42 * @len: number of bytes to copy 42 * @len: number of bytes to copy
43 * 43 *
44 * Same as skb_read_bits, but calculate a checksum at the same time. 44 * Same as skb_read_bits, but calculate a checksum at the same time.
45 */ 45 */
46static size_t skb_read_and_csum_bits(skb_reader_t *desc, void *to, size_t len) 46static size_t xdr_skb_read_and_csum_bits(struct xdr_skb_reader *desc, void *to, size_t len)
47{ 47{
48 unsigned int csum2, pos; 48 unsigned int pos;
49 __wsum csum2;
49 50
50 if (len > desc->count) 51 if (len > desc->count)
51 len = desc->count; 52 len = desc->count;
@@ -65,7 +66,7 @@ static size_t skb_read_and_csum_bits(skb_reader_t *desc, void *to, size_t len)
65 * @copy_actor: virtual method for copying data 66 * @copy_actor: virtual method for copying data
66 * 67 *
67 */ 68 */
68ssize_t xdr_partial_copy_from_skb(struct xdr_buf *xdr, unsigned int base, skb_reader_t *desc, skb_read_actor_t copy_actor) 69ssize_t xdr_partial_copy_from_skb(struct xdr_buf *xdr, unsigned int base, struct xdr_skb_reader *desc, xdr_skb_read_actor copy_actor)
69{ 70{
70 struct page **ppage = xdr->pages; 71 struct page **ppage = xdr->pages;
71 unsigned int len, pglen = xdr->page_len; 72 unsigned int len, pglen = xdr->page_len;
@@ -147,7 +148,7 @@ out:
147 */ 148 */
148int csum_partial_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb) 149int csum_partial_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb)
149{ 150{
150 skb_reader_t desc; 151 struct xdr_skb_reader desc;
151 152
152 desc.skb = skb; 153 desc.skb = skb;
153 desc.offset = sizeof(struct udphdr); 154 desc.offset = sizeof(struct udphdr);
@@ -157,22 +158,22 @@ int csum_partial_copy_to_xdr(struct xdr_buf *xdr, struct sk_buff *skb)
157 goto no_checksum; 158 goto no_checksum;
158 159
159 desc.csum = csum_partial(skb->data, desc.offset, skb->csum); 160 desc.csum = csum_partial(skb->data, desc.offset, skb->csum);
160 if (xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_and_csum_bits) < 0) 161 if (xdr_partial_copy_from_skb(xdr, 0, &desc, xdr_skb_read_and_csum_bits) < 0)
161 return -1; 162 return -1;
162 if (desc.offset != skb->len) { 163 if (desc.offset != skb->len) {
163 unsigned int csum2; 164 __wsum csum2;
164 csum2 = skb_checksum(skb, desc.offset, skb->len - desc.offset, 0); 165 csum2 = skb_checksum(skb, desc.offset, skb->len - desc.offset, 0);
165 desc.csum = csum_block_add(desc.csum, csum2, desc.offset); 166 desc.csum = csum_block_add(desc.csum, csum2, desc.offset);
166 } 167 }
167 if (desc.count) 168 if (desc.count)
168 return -1; 169 return -1;
169 if ((unsigned short)csum_fold(desc.csum)) 170 if (csum_fold(desc.csum))
170 return -1; 171 return -1;
171 if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE)) 172 if (unlikely(skb->ip_summed == CHECKSUM_COMPLETE))
172 netdev_rx_csum_fault(skb->dev); 173 netdev_rx_csum_fault(skb->dev);
173 return 0; 174 return 0;
174no_checksum: 175no_checksum:
175 if (xdr_partial_copy_from_skb(xdr, 0, &desc, skb_read_bits) < 0) 176 if (xdr_partial_copy_from_skb(xdr, 0, &desc, xdr_skb_read_bits) < 0)
176 return -1; 177 return -1;
177 if (desc.count) 178 if (desc.count)
178 return -1; 179 return -1;
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index 192dff5dab..d85fddeb63 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -33,7 +33,6 @@ EXPORT_SYMBOL(rpciod_down);
33EXPORT_SYMBOL(rpciod_up); 33EXPORT_SYMBOL(rpciod_up);
34EXPORT_SYMBOL(rpc_new_task); 34EXPORT_SYMBOL(rpc_new_task);
35EXPORT_SYMBOL(rpc_wake_up_status); 35EXPORT_SYMBOL(rpc_wake_up_status);
36EXPORT_SYMBOL(rpc_release_task);
37 36
38/* RPC client functions */ 37/* RPC client functions */
39EXPORT_SYMBOL(rpc_clone_client); 38EXPORT_SYMBOL(rpc_clone_client);
@@ -139,6 +138,8 @@ EXPORT_SYMBOL(nlm_debug);
139extern int register_rpc_pipefs(void); 138extern int register_rpc_pipefs(void);
140extern void unregister_rpc_pipefs(void); 139extern void unregister_rpc_pipefs(void);
141extern struct cache_detail ip_map_cache; 140extern struct cache_detail ip_map_cache;
141extern int init_socket_xprt(void);
142extern void cleanup_socket_xprt(void);
142 143
143static int __init 144static int __init
144init_sunrpc(void) 145init_sunrpc(void)
@@ -156,6 +157,7 @@ init_sunrpc(void)
156 rpc_proc_init(); 157 rpc_proc_init();
157#endif 158#endif
158 cache_register(&ip_map_cache); 159 cache_register(&ip_map_cache);
160 init_socket_xprt();
159out: 161out:
160 return err; 162 return err;
161} 163}
@@ -163,6 +165,7 @@ out:
163static void __exit 165static void __exit
164cleanup_sunrpc(void) 166cleanup_sunrpc(void)
165{ 167{
168 cleanup_socket_xprt();
166 unregister_rpc_pipefs(); 169 unregister_rpc_pipefs();
167 rpc_destroy_mempool(); 170 rpc_destroy_mempool();
168 if (cache_unregister(&ip_map_cache)) 171 if (cache_unregister(&ip_map_cache))
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index eb44ec929c..f3001f3626 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -308,7 +308,7 @@ __svc_create(struct svc_program *prog, unsigned int bufsize, int npools,
308 308
309 serv->sv_nrpools = npools; 309 serv->sv_nrpools = npools;
310 serv->sv_pools = 310 serv->sv_pools =
311 kcalloc(sizeof(struct svc_pool), serv->sv_nrpools, 311 kcalloc(serv->sv_nrpools, sizeof(struct svc_pool),
312 GFP_KERNEL); 312 GFP_KERNEL);
313 if (!serv->sv_pools) { 313 if (!serv->sv_pools) {
314 kfree(serv); 314 kfree(serv);
diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c
index ee9bb1522d..c7bb5f7f21 100644
--- a/net/sunrpc/svcauth.c
+++ b/net/sunrpc/svcauth.c
@@ -119,7 +119,8 @@ EXPORT_SYMBOL(svc_auth_unregister);
119#define DN_HASHMASK (DN_HASHMAX-1) 119#define DN_HASHMASK (DN_HASHMAX-1)
120 120
121static struct hlist_head auth_domain_table[DN_HASHMAX]; 121static struct hlist_head auth_domain_table[DN_HASHMAX];
122static spinlock_t auth_domain_lock = SPIN_LOCK_UNLOCKED; 122static spinlock_t auth_domain_lock =
123 __SPIN_LOCK_UNLOCKED(auth_domain_lock);
123 124
124void auth_domain_put(struct auth_domain *dom) 125void auth_domain_put(struct auth_domain *dom)
125{ 126{
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index e1bd933629..0d1e8fb83b 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -53,6 +53,10 @@ struct auth_domain *unix_domain_find(char *name)
53 return NULL; 53 return NULL;
54 kref_init(&new->h.ref); 54 kref_init(&new->h.ref);
55 new->h.name = kstrdup(name, GFP_KERNEL); 55 new->h.name = kstrdup(name, GFP_KERNEL);
56 if (new->h.name == NULL) {
57 kfree(new);
58 return NULL;
59 }
56 new->h.flavour = &svcauth_unix; 60 new->h.flavour = &svcauth_unix;
57 new->addr_changes = 0; 61 new->addr_changes = 0;
58 rv = auth_domain_lookup(name, &new->h); 62 rv = auth_domain_lookup(name, &new->h);
@@ -101,9 +105,9 @@ static void ip_map_put(struct kref *kref)
101 * IP addresses in reverse-endian (i.e. on a little-endian machine). 105 * IP addresses in reverse-endian (i.e. on a little-endian machine).
102 * So use a trivial but reliable hash instead 106 * So use a trivial but reliable hash instead
103 */ 107 */
104static inline int hash_ip(unsigned long ip) 108static inline int hash_ip(__be32 ip)
105{ 109{
106 int hash = ip ^ (ip>>16); 110 int hash = (__force u32)ip ^ ((__force u32)ip>>16);
107 return (hash ^ (hash>>8)) & 0xff; 111 return (hash ^ (hash>>8)) & 0xff;
108} 112}
109#endif 113#endif
@@ -284,7 +288,7 @@ static struct ip_map *ip_map_lookup(char *class, struct in_addr addr)
284 ip.m_addr = addr; 288 ip.m_addr = addr;
285 ch = sunrpc_cache_lookup(&ip_map_cache, &ip.h, 289 ch = sunrpc_cache_lookup(&ip_map_cache, &ip.h,
286 hash_str(class, IP_HASHBITS) ^ 290 hash_str(class, IP_HASHBITS) ^
287 hash_ip((unsigned long)addr.s_addr)); 291 hash_ip(addr.s_addr));
288 292
289 if (ch) 293 if (ch)
290 return container_of(ch, struct ip_map, h); 294 return container_of(ch, struct ip_map, h);
@@ -313,7 +317,7 @@ static int ip_map_update(struct ip_map *ipm, struct unix_domain *udom, time_t ex
313 ch = sunrpc_cache_update(&ip_map_cache, 317 ch = sunrpc_cache_update(&ip_map_cache,
314 &ip.h, &ipm->h, 318 &ip.h, &ipm->h,
315 hash_str(ipm->m_class, IP_HASHBITS) ^ 319 hash_str(ipm->m_class, IP_HASHBITS) ^
316 hash_ip((unsigned long)ipm->m_addr.s_addr)); 320 hash_ip(ipm->m_addr.s_addr));
317 if (!ch) 321 if (!ch)
318 return -ENOMEM; 322 return -ENOMEM;
319 cache_put(ch, &ip_map_cache); 323 cache_put(ch, &ip_map_cache);
@@ -435,6 +439,7 @@ svcauth_unix_set_client(struct svc_rqst *rqstp)
435 default: 439 default:
436 BUG(); 440 BUG();
437 case -EAGAIN: 441 case -EAGAIN:
442 case -ETIMEDOUT:
438 return SVC_DROP; 443 return SVC_DROP;
439 case -ENOENT: 444 case -ENOENT:
440 return SVC_DENIED; 445 return SVC_DENIED;
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 64ca1f61dd..99f54fb6d6 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -32,6 +32,7 @@
32#include <linux/netdevice.h> 32#include <linux/netdevice.h>
33#include <linux/skbuff.h> 33#include <linux/skbuff.h>
34#include <linux/file.h> 34#include <linux/file.h>
35#include <linux/freezer.h>
35#include <net/sock.h> 36#include <net/sock.h>
36#include <net/checksum.h> 37#include <net/checksum.h>
37#include <net/ip.h> 38#include <net/ip.h>
@@ -84,6 +85,35 @@ static struct cache_deferred_req *svc_defer(struct cache_req *req);
84 */ 85 */
85static int svc_conn_age_period = 6*60; 86static int svc_conn_age_period = 6*60;
86 87
88#ifdef CONFIG_DEBUG_LOCK_ALLOC
89static struct lock_class_key svc_key[2];
90static struct lock_class_key svc_slock_key[2];
91
92static inline void svc_reclassify_socket(struct socket *sock)
93{
94 struct sock *sk = sock->sk;
95 BUG_ON(sk->sk_lock.owner != NULL);
96 switch (sk->sk_family) {
97 case AF_INET:
98 sock_lock_init_class_and_name(sk, "slock-AF_INET-NFSD",
99 &svc_slock_key[0], "sk_lock-AF_INET-NFSD", &svc_key[0]);
100 break;
101
102 case AF_INET6:
103 sock_lock_init_class_and_name(sk, "slock-AF_INET6-NFSD",
104 &svc_slock_key[1], "sk_lock-AF_INET6-NFSD", &svc_key[1]);
105 break;
106
107 default:
108 BUG();
109 }
110}
111#else
112static inline void svc_reclassify_socket(struct socket *sock)
113{
114}
115#endif
116
87/* 117/*
88 * Queue up an idle server thread. Must have pool->sp_lock held. 118 * Queue up an idle server thread. Must have pool->sp_lock held.
89 * Note: this is really a stack rather than a queue, so that we only 119 * Note: this is really a stack rather than a queue, so that we only
@@ -1556,6 +1586,8 @@ svc_create_socket(struct svc_serv *serv, int protocol, struct sockaddr_in *sin)
1556 if ((error = sock_create_kern(PF_INET, type, protocol, &sock)) < 0) 1586 if ((error = sock_create_kern(PF_INET, type, protocol, &sock)) < 0)
1557 return error; 1587 return error;
1558 1588
1589 svc_reclassify_socket(sock);
1590
1559 if (type == SOCK_STREAM) 1591 if (type == SOCK_STREAM)
1560 sock->sk->sk_reuse = 1; /* allow address reuse */ 1592 sock->sk->sk_reuse = 1; /* allow address reuse */
1561 error = kernel_bind(sock, (struct sockaddr *) sin, 1593 error = kernel_bind(sock, (struct sockaddr *) sin,
diff --git a/net/sunrpc/sysctl.c b/net/sunrpc/sysctl.c
index d89b048ad6..82b27528d0 100644
--- a/net/sunrpc/sysctl.c
+++ b/net/sunrpc/sysctl.c
@@ -18,7 +18,6 @@
18#include <linux/sunrpc/types.h> 18#include <linux/sunrpc/types.h>
19#include <linux/sunrpc/sched.h> 19#include <linux/sunrpc/sched.h>
20#include <linux/sunrpc/stats.h> 20#include <linux/sunrpc/stats.h>
21#include <linux/sunrpc/xprt.h>
22 21
23/* 22/*
24 * Declare the debug flags here 23 * Declare the debug flags here
@@ -119,11 +118,6 @@ done:
119} 118}
120 119
121 120
122static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE;
123static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE;
124static unsigned int xprt_min_resvport_limit = RPC_MIN_RESVPORT;
125static unsigned int xprt_max_resvport_limit = RPC_MAX_RESVPORT;
126
127static ctl_table debug_table[] = { 121static ctl_table debug_table[] = {
128 { 122 {
129 .ctl_name = CTL_RPCDEBUG, 123 .ctl_name = CTL_RPCDEBUG,
@@ -157,50 +151,6 @@ static ctl_table debug_table[] = {
157 .mode = 0644, 151 .mode = 0644,
158 .proc_handler = &proc_dodebug 152 .proc_handler = &proc_dodebug
159 }, 153 },
160 {
161 .ctl_name = CTL_SLOTTABLE_UDP,
162 .procname = "udp_slot_table_entries",
163 .data = &xprt_udp_slot_table_entries,
164 .maxlen = sizeof(unsigned int),
165 .mode = 0644,
166 .proc_handler = &proc_dointvec_minmax,
167 .strategy = &sysctl_intvec,
168 .extra1 = &min_slot_table_size,
169 .extra2 = &max_slot_table_size
170 },
171 {
172 .ctl_name = CTL_SLOTTABLE_TCP,
173 .procname = "tcp_slot_table_entries",
174 .data = &xprt_tcp_slot_table_entries,
175 .maxlen = sizeof(unsigned int),
176 .mode = 0644,
177 .proc_handler = &proc_dointvec_minmax,
178 .strategy = &sysctl_intvec,
179 .extra1 = &min_slot_table_size,
180 .extra2 = &max_slot_table_size
181 },
182 {
183 .ctl_name = CTL_MIN_RESVPORT,
184 .procname = "min_resvport",
185 .data = &xprt_min_resvport,
186 .maxlen = sizeof(unsigned int),
187 .mode = 0644,
188 .proc_handler = &proc_dointvec_minmax,
189 .strategy = &sysctl_intvec,
190 .extra1 = &xprt_min_resvport_limit,
191 .extra2 = &xprt_max_resvport_limit
192 },
193 {
194 .ctl_name = CTL_MAX_RESVPORT,
195 .procname = "max_resvport",
196 .data = &xprt_max_resvport,
197 .maxlen = sizeof(unsigned int),
198 .mode = 0644,
199 .proc_handler = &proc_dointvec_minmax,
200 .strategy = &sysctl_intvec,
201 .extra1 = &xprt_min_resvport_limit,
202 .extra2 = &xprt_max_resvport_limit
203 },
204 { .ctl_name = 0 } 154 { .ctl_name = 0 }
205}; 155};
206 156
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index 9022eb8b37..a0af250ca3 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -640,41 +640,30 @@ xdr_buf_from_iov(struct kvec *iov, struct xdr_buf *buf)
640 buf->buflen = buf->len = iov->iov_len; 640 buf->buflen = buf->len = iov->iov_len;
641} 641}
642 642
643/* Sets subiov to the intersection of iov with the buffer of length len
644 * starting base bytes after iov. Indicates empty intersection by setting
645 * length of subiov to zero. Decrements len by length of subiov, sets base
646 * to zero (or decrements it by length of iov if subiov is empty). */
647static void
648iov_subsegment(struct kvec *iov, struct kvec *subiov, int *base, int *len)
649{
650 if (*base > iov->iov_len) {
651 subiov->iov_base = NULL;
652 subiov->iov_len = 0;
653 *base -= iov->iov_len;
654 } else {
655 subiov->iov_base = iov->iov_base + *base;
656 subiov->iov_len = min(*len, (int)iov->iov_len - *base);
657 *base = 0;
658 }
659 *len -= subiov->iov_len;
660}
661
662/* Sets subbuf to the portion of buf of length len beginning base bytes 643/* Sets subbuf to the portion of buf of length len beginning base bytes
663 * from the start of buf. Returns -1 if base of length are out of bounds. */ 644 * from the start of buf. Returns -1 if base of length are out of bounds. */
664int 645int
665xdr_buf_subsegment(struct xdr_buf *buf, struct xdr_buf *subbuf, 646xdr_buf_subsegment(struct xdr_buf *buf, struct xdr_buf *subbuf,
666 int base, int len) 647 unsigned int base, unsigned int len)
667{ 648{
668 int i;
669
670 subbuf->buflen = subbuf->len = len; 649 subbuf->buflen = subbuf->len = len;
671 iov_subsegment(buf->head, subbuf->head, &base, &len); 650 if (base < buf->head[0].iov_len) {
651 subbuf->head[0].iov_base = buf->head[0].iov_base + base;
652 subbuf->head[0].iov_len = min_t(unsigned int, len,
653 buf->head[0].iov_len - base);
654 len -= subbuf->head[0].iov_len;
655 base = 0;
656 } else {
657 subbuf->head[0].iov_base = NULL;
658 subbuf->head[0].iov_len = 0;
659 base -= buf->head[0].iov_len;
660 }
672 661
673 if (base < buf->page_len) { 662 if (base < buf->page_len) {
674 i = (base + buf->page_base) >> PAGE_CACHE_SHIFT; 663 subbuf->page_len = min(buf->page_len - base, len);
675 subbuf->pages = &buf->pages[i]; 664 base += buf->page_base;
676 subbuf->page_base = (base + buf->page_base) & ~PAGE_CACHE_MASK; 665 subbuf->page_base = base & ~PAGE_CACHE_MASK;
677 subbuf->page_len = min((int)buf->page_len - base, len); 666 subbuf->pages = &buf->pages[base >> PAGE_CACHE_SHIFT];
678 len -= subbuf->page_len; 667 len -= subbuf->page_len;
679 base = 0; 668 base = 0;
680 } else { 669 } else {
@@ -682,66 +671,85 @@ xdr_buf_subsegment(struct xdr_buf *buf, struct xdr_buf *subbuf,
682 subbuf->page_len = 0; 671 subbuf->page_len = 0;
683 } 672 }
684 673
685 iov_subsegment(buf->tail, subbuf->tail, &base, &len); 674 if (base < buf->tail[0].iov_len) {
675 subbuf->tail[0].iov_base = buf->tail[0].iov_base + base;
676 subbuf->tail[0].iov_len = min_t(unsigned int, len,
677 buf->tail[0].iov_len - base);
678 len -= subbuf->tail[0].iov_len;
679 base = 0;
680 } else {
681 subbuf->tail[0].iov_base = NULL;
682 subbuf->tail[0].iov_len = 0;
683 base -= buf->tail[0].iov_len;
684 }
685
686 if (base || len) 686 if (base || len)
687 return -1; 687 return -1;
688 return 0; 688 return 0;
689} 689}
690 690
691/* obj is assumed to point to allocated memory of size at least len: */ 691static void __read_bytes_from_xdr_buf(struct xdr_buf *subbuf, void *obj, unsigned int len)
692int
693read_bytes_from_xdr_buf(struct xdr_buf *buf, int base, void *obj, int len)
694{ 692{
695 struct xdr_buf subbuf; 693 unsigned int this_len;
696 int this_len;
697 int status;
698 694
699 status = xdr_buf_subsegment(buf, &subbuf, base, len); 695 this_len = min_t(unsigned int, len, subbuf->head[0].iov_len);
700 if (status) 696 memcpy(obj, subbuf->head[0].iov_base, this_len);
701 goto out;
702 this_len = min(len, (int)subbuf.head[0].iov_len);
703 memcpy(obj, subbuf.head[0].iov_base, this_len);
704 len -= this_len; 697 len -= this_len;
705 obj += this_len; 698 obj += this_len;
706 this_len = min(len, (int)subbuf.page_len); 699 this_len = min_t(unsigned int, len, subbuf->page_len);
707 if (this_len) 700 if (this_len)
708 _copy_from_pages(obj, subbuf.pages, subbuf.page_base, this_len); 701 _copy_from_pages(obj, subbuf->pages, subbuf->page_base, this_len);
709 len -= this_len; 702 len -= this_len;
710 obj += this_len; 703 obj += this_len;
711 this_len = min(len, (int)subbuf.tail[0].iov_len); 704 this_len = min_t(unsigned int, len, subbuf->tail[0].iov_len);
712 memcpy(obj, subbuf.tail[0].iov_base, this_len); 705 memcpy(obj, subbuf->tail[0].iov_base, this_len);
713out:
714 return status;
715} 706}
716 707
717/* obj is assumed to point to allocated memory of size at least len: */ 708/* obj is assumed to point to allocated memory of size at least len: */
718int 709int read_bytes_from_xdr_buf(struct xdr_buf *buf, unsigned int base, void *obj, unsigned int len)
719write_bytes_to_xdr_buf(struct xdr_buf *buf, int base, void *obj, int len)
720{ 710{
721 struct xdr_buf subbuf; 711 struct xdr_buf subbuf;
722 int this_len;
723 int status; 712 int status;
724 713
725 status = xdr_buf_subsegment(buf, &subbuf, base, len); 714 status = xdr_buf_subsegment(buf, &subbuf, base, len);
726 if (status) 715 if (status != 0)
727 goto out; 716 return status;
728 this_len = min(len, (int)subbuf.head[0].iov_len); 717 __read_bytes_from_xdr_buf(&subbuf, obj, len);
729 memcpy(subbuf.head[0].iov_base, obj, this_len); 718 return 0;
719}
720
721static void __write_bytes_to_xdr_buf(struct xdr_buf *subbuf, void *obj, unsigned int len)
722{
723 unsigned int this_len;
724
725 this_len = min_t(unsigned int, len, subbuf->head[0].iov_len);
726 memcpy(subbuf->head[0].iov_base, obj, this_len);
730 len -= this_len; 727 len -= this_len;
731 obj += this_len; 728 obj += this_len;
732 this_len = min(len, (int)subbuf.page_len); 729 this_len = min_t(unsigned int, len, subbuf->page_len);
733 if (this_len) 730 if (this_len)
734 _copy_to_pages(subbuf.pages, subbuf.page_base, obj, this_len); 731 _copy_to_pages(subbuf->pages, subbuf->page_base, obj, this_len);
735 len -= this_len; 732 len -= this_len;
736 obj += this_len; 733 obj += this_len;
737 this_len = min(len, (int)subbuf.tail[0].iov_len); 734 this_len = min_t(unsigned int, len, subbuf->tail[0].iov_len);
738 memcpy(subbuf.tail[0].iov_base, obj, this_len); 735 memcpy(subbuf->tail[0].iov_base, obj, this_len);
739out: 736}
740 return status; 737
738/* obj is assumed to point to allocated memory of size at least len: */
739int write_bytes_to_xdr_buf(struct xdr_buf *buf, unsigned int base, void *obj, unsigned int len)
740{
741 struct xdr_buf subbuf;
742 int status;
743
744 status = xdr_buf_subsegment(buf, &subbuf, base, len);
745 if (status != 0)
746 return status;
747 __write_bytes_to_xdr_buf(&subbuf, obj, len);
748 return 0;
741} 749}
742 750
743int 751int
744xdr_decode_word(struct xdr_buf *buf, int base, u32 *obj) 752xdr_decode_word(struct xdr_buf *buf, unsigned int base, u32 *obj)
745{ 753{
746 __be32 raw; 754 __be32 raw;
747 int status; 755 int status;
@@ -754,7 +762,7 @@ xdr_decode_word(struct xdr_buf *buf, int base, u32 *obj)
754} 762}
755 763
756int 764int
757xdr_encode_word(struct xdr_buf *buf, int base, u32 obj) 765xdr_encode_word(struct xdr_buf *buf, unsigned int base, u32 obj)
758{ 766{
759 __be32 raw = htonl(obj); 767 __be32 raw = htonl(obj);
760 768
@@ -765,44 +773,37 @@ xdr_encode_word(struct xdr_buf *buf, int base, u32 obj)
765 * entirely in the head or the tail, set object to point to it; otherwise 773 * entirely in the head or the tail, set object to point to it; otherwise
766 * try to find space for it at the end of the tail, copy it there, and 774 * try to find space for it at the end of the tail, copy it there, and
767 * set obj to point to it. */ 775 * set obj to point to it. */
768int 776int xdr_buf_read_netobj(struct xdr_buf *buf, struct xdr_netobj *obj, unsigned int offset)
769xdr_buf_read_netobj(struct xdr_buf *buf, struct xdr_netobj *obj, int offset)
770{ 777{
771 u32 tail_offset = buf->head[0].iov_len + buf->page_len; 778 struct xdr_buf subbuf;
772 u32 obj_end_offset;
773 779
774 if (xdr_decode_word(buf, offset, &obj->len)) 780 if (xdr_decode_word(buf, offset, &obj->len))
775 goto out; 781 return -EFAULT;
776 obj_end_offset = offset + 4 + obj->len; 782 if (xdr_buf_subsegment(buf, &subbuf, offset + 4, obj->len))
777 783 return -EFAULT;
778 if (obj_end_offset <= buf->head[0].iov_len) {
779 /* The obj is contained entirely in the head: */
780 obj->data = buf->head[0].iov_base + offset + 4;
781 } else if (offset + 4 >= tail_offset) {
782 if (obj_end_offset - tail_offset
783 > buf->tail[0].iov_len)
784 goto out;
785 /* The obj is contained entirely in the tail: */
786 obj->data = buf->tail[0].iov_base
787 + offset - tail_offset + 4;
788 } else {
789 /* use end of tail as storage for obj:
790 * (We don't copy to the beginning because then we'd have
791 * to worry about doing a potentially overlapping copy.
792 * This assumes the object is at most half the length of the
793 * tail.) */
794 if (obj->len > buf->tail[0].iov_len)
795 goto out;
796 obj->data = buf->tail[0].iov_base + buf->tail[0].iov_len -
797 obj->len;
798 if (read_bytes_from_xdr_buf(buf, offset + 4,
799 obj->data, obj->len))
800 goto out;
801 784
802 } 785 /* Is the obj contained entirely in the head? */
786 obj->data = subbuf.head[0].iov_base;
787 if (subbuf.head[0].iov_len == obj->len)
788 return 0;
789 /* ..or is the obj contained entirely in the tail? */
790 obj->data = subbuf.tail[0].iov_base;
791 if (subbuf.tail[0].iov_len == obj->len)
792 return 0;
793
794 /* use end of tail as storage for obj:
795 * (We don't copy to the beginning because then we'd have
796 * to worry about doing a potentially overlapping copy.
797 * This assumes the object is at most half the length of the
798 * tail.) */
799 if (obj->len > buf->buflen - buf->len)
800 return -ENOMEM;
801 if (buf->tail[0].iov_len != 0)
802 obj->data = buf->tail[0].iov_base + buf->tail[0].iov_len;
803 else
804 obj->data = buf->head[0].iov_base + buf->head[0].iov_len;
805 __read_bytes_from_xdr_buf(&subbuf, obj->data, obj->len);
803 return 0; 806 return 0;
804out:
805 return -1;
806} 807}
807 808
808/* Returns 0 on success, or else a negative error code. */ 809/* Returns 0 on success, or else a negative error code. */
@@ -1020,3 +1021,71 @@ xdr_encode_array2(struct xdr_buf *buf, unsigned int base,
1020 1021
1021 return xdr_xcode_array2(buf, base, desc, 1); 1022 return xdr_xcode_array2(buf, base, desc, 1);
1022} 1023}
1024
1025int
1026xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len,
1027 int (*actor)(struct scatterlist *, void *), void *data)
1028{
1029 int i, ret = 0;
1030 unsigned page_len, thislen, page_offset;
1031 struct scatterlist sg[1];
1032
1033 if (offset >= buf->head[0].iov_len) {
1034 offset -= buf->head[0].iov_len;
1035 } else {
1036 thislen = buf->head[0].iov_len - offset;
1037 if (thislen > len)
1038 thislen = len;
1039 sg_set_buf(sg, buf->head[0].iov_base + offset, thislen);
1040 ret = actor(sg, data);
1041 if (ret)
1042 goto out;
1043 offset = 0;
1044 len -= thislen;
1045 }
1046 if (len == 0)
1047 goto out;
1048
1049 if (offset >= buf->page_len) {
1050 offset -= buf->page_len;
1051 } else {
1052 page_len = buf->page_len - offset;
1053 if (page_len > len)
1054 page_len = len;
1055 len -= page_len;
1056 page_offset = (offset + buf->page_base) & (PAGE_CACHE_SIZE - 1);
1057 i = (offset + buf->page_base) >> PAGE_CACHE_SHIFT;
1058 thislen = PAGE_CACHE_SIZE - page_offset;
1059 do {
1060 if (thislen > page_len)
1061 thislen = page_len;
1062 sg->page = buf->pages[i];
1063 sg->offset = page_offset;
1064 sg->length = thislen;
1065 ret = actor(sg, data);
1066 if (ret)
1067 goto out;
1068 page_len -= thislen;
1069 i++;
1070 page_offset = 0;
1071 thislen = PAGE_CACHE_SIZE;
1072 } while (page_len != 0);
1073 offset = 0;
1074 }
1075 if (len == 0)
1076 goto out;
1077 if (offset < buf->tail[0].iov_len) {
1078 thislen = buf->tail[0].iov_len - offset;
1079 if (thislen > len)
1080 thislen = len;
1081 sg_set_buf(sg, buf->tail[0].iov_base + offset, thislen);
1082 ret = actor(sg, data);
1083 len -= thislen;
1084 }
1085 if (len != 0)
1086 ret = -EINVAL;
1087out:
1088 return ret;
1089}
1090EXPORT_SYMBOL(xdr_process_buf);
1091
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
index 80857470dc..7a3999f0a4 100644
--- a/net/sunrpc/xprt.c
+++ b/net/sunrpc/xprt.c
@@ -459,7 +459,6 @@ int xprt_adjust_timeout(struct rpc_rqst *req)
459 if (to->to_maxval && req->rq_timeout >= to->to_maxval) 459 if (to->to_maxval && req->rq_timeout >= to->to_maxval)
460 req->rq_timeout = to->to_maxval; 460 req->rq_timeout = to->to_maxval;
461 req->rq_retries++; 461 req->rq_retries++;
462 pprintk("RPC: %lu retrans\n", jiffies);
463 } else { 462 } else {
464 req->rq_timeout = to->to_initval; 463 req->rq_timeout = to->to_initval;
465 req->rq_retries = 0; 464 req->rq_retries = 0;
@@ -468,7 +467,6 @@ int xprt_adjust_timeout(struct rpc_rqst *req)
468 spin_lock_bh(&xprt->transport_lock); 467 spin_lock_bh(&xprt->transport_lock);
469 rpc_init_rtt(req->rq_task->tk_client->cl_rtt, to->to_initval); 468 rpc_init_rtt(req->rq_task->tk_client->cl_rtt, to->to_initval);
470 spin_unlock_bh(&xprt->transport_lock); 469 spin_unlock_bh(&xprt->transport_lock);
471 pprintk("RPC: %lu timeout\n", jiffies);
472 status = -ETIMEDOUT; 470 status = -ETIMEDOUT;
473 } 471 }
474 472
@@ -479,9 +477,10 @@ int xprt_adjust_timeout(struct rpc_rqst *req)
479 return status; 477 return status;
480} 478}
481 479
482static void xprt_autoclose(void *args) 480static void xprt_autoclose(struct work_struct *work)
483{ 481{
484 struct rpc_xprt *xprt = (struct rpc_xprt *)args; 482 struct rpc_xprt *xprt =
483 container_of(work, struct rpc_xprt, task_cleanup);
485 484
486 xprt_disconnect(xprt); 485 xprt_disconnect(xprt);
487 xprt->ops->close(xprt); 486 xprt->ops->close(xprt);
@@ -891,39 +890,25 @@ void xprt_set_timeout(struct rpc_timeout *to, unsigned int retr, unsigned long i
891 */ 890 */
892struct rpc_xprt *xprt_create_transport(int proto, struct sockaddr *ap, size_t size, struct rpc_timeout *to) 891struct rpc_xprt *xprt_create_transport(int proto, struct sockaddr *ap, size_t size, struct rpc_timeout *to)
893{ 892{
894 int result;
895 struct rpc_xprt *xprt; 893 struct rpc_xprt *xprt;
896 struct rpc_rqst *req; 894 struct rpc_rqst *req;
897 895
898 if ((xprt = kzalloc(sizeof(struct rpc_xprt), GFP_KERNEL)) == NULL) {
899 dprintk("RPC: xprt_create_transport: no memory\n");
900 return ERR_PTR(-ENOMEM);
901 }
902 if (size <= sizeof(xprt->addr)) {
903 memcpy(&xprt->addr, ap, size);
904 xprt->addrlen = size;
905 } else {
906 kfree(xprt);
907 dprintk("RPC: xprt_create_transport: address too large\n");
908 return ERR_PTR(-EBADF);
909 }
910
911 switch (proto) { 896 switch (proto) {
912 case IPPROTO_UDP: 897 case IPPROTO_UDP:
913 result = xs_setup_udp(xprt, to); 898 xprt = xs_setup_udp(ap, size, to);
914 break; 899 break;
915 case IPPROTO_TCP: 900 case IPPROTO_TCP:
916 result = xs_setup_tcp(xprt, to); 901 xprt = xs_setup_tcp(ap, size, to);
917 break; 902 break;
918 default: 903 default:
919 printk(KERN_ERR "RPC: unrecognized transport protocol: %d\n", 904 printk(KERN_ERR "RPC: unrecognized transport protocol: %d\n",
920 proto); 905 proto);
921 return ERR_PTR(-EIO); 906 return ERR_PTR(-EIO);
922 } 907 }
923 if (result) { 908 if (IS_ERR(xprt)) {
924 kfree(xprt); 909 dprintk("RPC: xprt_create_transport: failed, %ld\n",
925 dprintk("RPC: xprt_create_transport: failed, %d\n", result); 910 -PTR_ERR(xprt));
926 return ERR_PTR(result); 911 return xprt;
927 } 912 }
928 913
929 kref_init(&xprt->kref); 914 kref_init(&xprt->kref);
@@ -932,7 +917,7 @@ struct rpc_xprt *xprt_create_transport(int proto, struct sockaddr *ap, size_t si
932 917
933 INIT_LIST_HEAD(&xprt->free); 918 INIT_LIST_HEAD(&xprt->free);
934 INIT_LIST_HEAD(&xprt->recv); 919 INIT_LIST_HEAD(&xprt->recv);
935 INIT_WORK(&xprt->task_cleanup, xprt_autoclose, xprt); 920 INIT_WORK(&xprt->task_cleanup, xprt_autoclose);
936 init_timer(&xprt->timer); 921 init_timer(&xprt->timer);
937 xprt->timer.function = xprt_init_autodisconnect; 922 xprt->timer.function = xprt_init_autodisconnect;
938 xprt->timer.data = (unsigned long) xprt; 923 xprt->timer.data = (unsigned long) xprt;
@@ -969,8 +954,11 @@ static void xprt_destroy(struct kref *kref)
969 dprintk("RPC: destroying transport %p\n", xprt); 954 dprintk("RPC: destroying transport %p\n", xprt);
970 xprt->shutdown = 1; 955 xprt->shutdown = 1;
971 del_timer_sync(&xprt->timer); 956 del_timer_sync(&xprt->timer);
957
958 /*
959 * Tear down transport state and free the rpc_xprt
960 */
972 xprt->ops->destroy(xprt); 961 xprt->ops->destroy(xprt);
973 kfree(xprt);
974} 962}
975 963
976/** 964/**
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
index 757fc91ef2..49cabffd7f 100644
--- a/net/sunrpc/xprtsock.c
+++ b/net/sunrpc/xprtsock.c
@@ -46,6 +46,92 @@ unsigned int xprt_min_resvport = RPC_DEF_MIN_RESVPORT;
46unsigned int xprt_max_resvport = RPC_DEF_MAX_RESVPORT; 46unsigned int xprt_max_resvport = RPC_DEF_MAX_RESVPORT;
47 47
48/* 48/*
49 * We can register our own files under /proc/sys/sunrpc by
50 * calling register_sysctl_table() again. The files in that
51 * directory become the union of all files registered there.
52 *
53 * We simply need to make sure that we don't collide with
54 * someone else's file names!
55 */
56
57#ifdef RPC_DEBUG
58
59static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE;
60static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE;
61static unsigned int xprt_min_resvport_limit = RPC_MIN_RESVPORT;
62static unsigned int xprt_max_resvport_limit = RPC_MAX_RESVPORT;
63
64static struct ctl_table_header *sunrpc_table_header;
65
66/*
67 * FIXME: changing the UDP slot table size should also resize the UDP
68 * socket buffers for existing UDP transports
69 */
70static ctl_table xs_tunables_table[] = {
71 {
72 .ctl_name = CTL_SLOTTABLE_UDP,
73 .procname = "udp_slot_table_entries",
74 .data = &xprt_udp_slot_table_entries,
75 .maxlen = sizeof(unsigned int),
76 .mode = 0644,
77 .proc_handler = &proc_dointvec_minmax,
78 .strategy = &sysctl_intvec,
79 .extra1 = &min_slot_table_size,
80 .extra2 = &max_slot_table_size
81 },
82 {
83 .ctl_name = CTL_SLOTTABLE_TCP,
84 .procname = "tcp_slot_table_entries",
85 .data = &xprt_tcp_slot_table_entries,
86 .maxlen = sizeof(unsigned int),
87 .mode = 0644,
88 .proc_handler = &proc_dointvec_minmax,
89 .strategy = &sysctl_intvec,
90 .extra1 = &min_slot_table_size,
91 .extra2 = &max_slot_table_size
92 },
93 {
94 .ctl_name = CTL_MIN_RESVPORT,
95 .procname = "min_resvport",
96 .data = &xprt_min_resvport,
97 .maxlen = sizeof(unsigned int),
98 .mode = 0644,
99 .proc_handler = &proc_dointvec_minmax,
100 .strategy = &sysctl_intvec,
101 .extra1 = &xprt_min_resvport_limit,
102 .extra2 = &xprt_max_resvport_limit
103 },
104 {
105 .ctl_name = CTL_MAX_RESVPORT,
106 .procname = "max_resvport",
107 .data = &xprt_max_resvport,
108 .maxlen = sizeof(unsigned int),
109 .mode = 0644,
110 .proc_handler = &proc_dointvec_minmax,
111 .strategy = &sysctl_intvec,
112 .extra1 = &xprt_min_resvport_limit,
113 .extra2 = &xprt_max_resvport_limit
114 },
115 {
116 .ctl_name = 0,
117 },
118};
119
120static ctl_table sunrpc_table[] = {
121 {
122 .ctl_name = CTL_SUNRPC,
123 .procname = "sunrpc",
124 .mode = 0555,
125 .child = xs_tunables_table
126 },
127 {
128 .ctl_name = 0,
129 },
130};
131
132#endif
133
134/*
49 * How many times to try sending a request on a socket before waiting 135 * How many times to try sending a request on a socket before waiting
50 * for the socket buffer to clear. 136 * for the socket buffer to clear.
51 */ 137 */
@@ -125,6 +211,55 @@ static inline void xs_pktdump(char *msg, u32 *packet, unsigned int count)
125} 211}
126#endif 212#endif
127 213
214struct sock_xprt {
215 struct rpc_xprt xprt;
216
217 /*
218 * Network layer
219 */
220 struct socket * sock;
221 struct sock * inet;
222
223 /*
224 * State of TCP reply receive
225 */
226 __be32 tcp_fraghdr,
227 tcp_xid;
228
229 u32 tcp_offset,
230 tcp_reclen;
231
232 unsigned long tcp_copied,
233 tcp_flags;
234
235 /*
236 * Connection of transports
237 */
238 struct delayed_work connect_worker;
239 unsigned short port;
240
241 /*
242 * UDP socket buffer size parameters
243 */
244 size_t rcvsize,
245 sndsize;
246
247 /*
248 * Saved socket callback addresses
249 */
250 void (*old_data_ready)(struct sock *, int);
251 void (*old_state_change)(struct sock *);
252 void (*old_write_space)(struct sock *);
253};
254
255/*
256 * TCP receive state flags
257 */
258#define TCP_RCV_LAST_FRAG (1UL << 0)
259#define TCP_RCV_COPY_FRAGHDR (1UL << 1)
260#define TCP_RCV_COPY_XID (1UL << 2)
261#define TCP_RCV_COPY_DATA (1UL << 3)
262
128static void xs_format_peer_addresses(struct rpc_xprt *xprt) 263static void xs_format_peer_addresses(struct rpc_xprt *xprt)
129{ 264{
130 struct sockaddr_in *addr = (struct sockaddr_in *) &xprt->addr; 265 struct sockaddr_in *addr = (struct sockaddr_in *) &xprt->addr;
@@ -168,37 +303,52 @@ static void xs_free_peer_addresses(struct rpc_xprt *xprt)
168 303
169#define XS_SENDMSG_FLAGS (MSG_DONTWAIT | MSG_NOSIGNAL) 304#define XS_SENDMSG_FLAGS (MSG_DONTWAIT | MSG_NOSIGNAL)
170 305
171static inline int xs_send_head(struct socket *sock, struct sockaddr *addr, int addrlen, struct xdr_buf *xdr, unsigned int base, unsigned int len) 306static int xs_send_kvec(struct socket *sock, struct sockaddr *addr, int addrlen, struct kvec *vec, unsigned int base, int more)
172{ 307{
173 struct kvec iov = {
174 .iov_base = xdr->head[0].iov_base + base,
175 .iov_len = len - base,
176 };
177 struct msghdr msg = { 308 struct msghdr msg = {
178 .msg_name = addr, 309 .msg_name = addr,
179 .msg_namelen = addrlen, 310 .msg_namelen = addrlen,
180 .msg_flags = XS_SENDMSG_FLAGS, 311 .msg_flags = XS_SENDMSG_FLAGS | (more ? MSG_MORE : 0),
312 };
313 struct kvec iov = {
314 .iov_base = vec->iov_base + base,
315 .iov_len = vec->iov_len - base,
181 }; 316 };
182 317
183 if (xdr->len > len) 318 if (iov.iov_len != 0)
184 msg.msg_flags |= MSG_MORE;
185
186 if (likely(iov.iov_len))
187 return kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len); 319 return kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len);
188 return kernel_sendmsg(sock, &msg, NULL, 0, 0); 320 return kernel_sendmsg(sock, &msg, NULL, 0, 0);
189} 321}
190 322
191static int xs_send_tail(struct socket *sock, struct xdr_buf *xdr, unsigned int base, unsigned int len) 323static int xs_send_pagedata(struct socket *sock, struct xdr_buf *xdr, unsigned int base, int more)
192{ 324{
193 struct kvec iov = { 325 struct page **ppage;
194 .iov_base = xdr->tail[0].iov_base + base, 326 unsigned int remainder;
195 .iov_len = len - base, 327 int err, sent = 0;
196 }; 328
197 struct msghdr msg = { 329 remainder = xdr->page_len - base;
198 .msg_flags = XS_SENDMSG_FLAGS, 330 base += xdr->page_base;
199 }; 331 ppage = xdr->pages + (base >> PAGE_SHIFT);
332 base &= ~PAGE_MASK;
333 for(;;) {
334 unsigned int len = min_t(unsigned int, PAGE_SIZE - base, remainder);
335 int flags = XS_SENDMSG_FLAGS;
200 336
201 return kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len); 337 remainder -= len;
338 if (remainder != 0 || more)
339 flags |= MSG_MORE;
340 err = sock->ops->sendpage(sock, *ppage, base, len, flags);
341 if (remainder == 0 || err != len)
342 break;
343 sent += err;
344 ppage++;
345 base = 0;
346 }
347 if (sent == 0)
348 return err;
349 if (err > 0)
350 sent += err;
351 return sent;
202} 352}
203 353
204/** 354/**
@@ -210,76 +360,51 @@ static int xs_send_tail(struct socket *sock, struct xdr_buf *xdr, unsigned int b
210 * @base: starting position in the buffer 360 * @base: starting position in the buffer
211 * 361 *
212 */ 362 */
213static inline int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen, struct xdr_buf *xdr, unsigned int base) 363static int xs_sendpages(struct socket *sock, struct sockaddr *addr, int addrlen, struct xdr_buf *xdr, unsigned int base)
214{ 364{
215 struct page **ppage = xdr->pages; 365 unsigned int remainder = xdr->len - base;
216 unsigned int len, pglen = xdr->page_len; 366 int err, sent = 0;
217 int err, ret = 0;
218 367
219 if (unlikely(!sock)) 368 if (unlikely(!sock))
220 return -ENOTCONN; 369 return -ENOTCONN;
221 370
222 clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags); 371 clear_bit(SOCK_ASYNC_NOSPACE, &sock->flags);
372 if (base != 0) {
373 addr = NULL;
374 addrlen = 0;
375 }
223 376
224 len = xdr->head[0].iov_len; 377 if (base < xdr->head[0].iov_len || addr != NULL) {
225 if (base < len || (addr != NULL && base == 0)) { 378 unsigned int len = xdr->head[0].iov_len - base;
226 err = xs_send_head(sock, addr, addrlen, xdr, base, len); 379 remainder -= len;
227 if (ret == 0) 380 err = xs_send_kvec(sock, addr, addrlen, &xdr->head[0], base, remainder != 0);
228 ret = err; 381 if (remainder == 0 || err != len)
229 else if (err > 0)
230 ret += err;
231 if (err != (len - base))
232 goto out; 382 goto out;
383 sent += err;
233 base = 0; 384 base = 0;
234 } else 385 } else
235 base -= len; 386 base -= xdr->head[0].iov_len;
236 387
237 if (unlikely(pglen == 0)) 388 if (base < xdr->page_len) {
238 goto copy_tail; 389 unsigned int len = xdr->page_len - base;
239 if (unlikely(base >= pglen)) { 390 remainder -= len;
240 base -= pglen; 391 err = xs_send_pagedata(sock, xdr, base, remainder != 0);
241 goto copy_tail; 392 if (remainder == 0 || err != len)
242 }
243 if (base || xdr->page_base) {
244 pglen -= base;
245 base += xdr->page_base;
246 ppage += base >> PAGE_CACHE_SHIFT;
247 base &= ~PAGE_CACHE_MASK;
248 }
249
250 do {
251 int flags = XS_SENDMSG_FLAGS;
252
253 len = PAGE_CACHE_SIZE;
254 if (base)
255 len -= base;
256 if (pglen < len)
257 len = pglen;
258
259 if (pglen != len || xdr->tail[0].iov_len != 0)
260 flags |= MSG_MORE;
261
262 err = kernel_sendpage(sock, *ppage, base, len, flags);
263 if (ret == 0)
264 ret = err;
265 else if (err > 0)
266 ret += err;
267 if (err != len)
268 goto out; 393 goto out;
394 sent += err;
269 base = 0; 395 base = 0;
270 ppage++; 396 } else
271 } while ((pglen -= len) != 0); 397 base -= xdr->page_len;
272copy_tail: 398
273 len = xdr->tail[0].iov_len; 399 if (base >= xdr->tail[0].iov_len)
274 if (base < len) { 400 return sent;
275 err = xs_send_tail(sock, xdr, base, len); 401 err = xs_send_kvec(sock, NULL, 0, &xdr->tail[0], base, 0);
276 if (ret == 0)
277 ret = err;
278 else if (err > 0)
279 ret += err;
280 }
281out: 402out:
282 return ret; 403 if (sent == 0)
404 return err;
405 if (err > 0)
406 sent += err;
407 return sent;
283} 408}
284 409
285/** 410/**
@@ -291,19 +416,20 @@ static void xs_nospace(struct rpc_task *task)
291{ 416{
292 struct rpc_rqst *req = task->tk_rqstp; 417 struct rpc_rqst *req = task->tk_rqstp;
293 struct rpc_xprt *xprt = req->rq_xprt; 418 struct rpc_xprt *xprt = req->rq_xprt;
419 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
294 420
295 dprintk("RPC: %4d xmit incomplete (%u left of %u)\n", 421 dprintk("RPC: %4d xmit incomplete (%u left of %u)\n",
296 task->tk_pid, req->rq_slen - req->rq_bytes_sent, 422 task->tk_pid, req->rq_slen - req->rq_bytes_sent,
297 req->rq_slen); 423 req->rq_slen);
298 424
299 if (test_bit(SOCK_ASYNC_NOSPACE, &xprt->sock->flags)) { 425 if (test_bit(SOCK_ASYNC_NOSPACE, &transport->sock->flags)) {
300 /* Protect against races with write_space */ 426 /* Protect against races with write_space */
301 spin_lock_bh(&xprt->transport_lock); 427 spin_lock_bh(&xprt->transport_lock);
302 428
303 /* Don't race with disconnect */ 429 /* Don't race with disconnect */
304 if (!xprt_connected(xprt)) 430 if (!xprt_connected(xprt))
305 task->tk_status = -ENOTCONN; 431 task->tk_status = -ENOTCONN;
306 else if (test_bit(SOCK_NOSPACE, &xprt->sock->flags)) 432 else if (test_bit(SOCK_NOSPACE, &transport->sock->flags))
307 xprt_wait_for_buffer_space(task); 433 xprt_wait_for_buffer_space(task);
308 434
309 spin_unlock_bh(&xprt->transport_lock); 435 spin_unlock_bh(&xprt->transport_lock);
@@ -327,6 +453,7 @@ static int xs_udp_send_request(struct rpc_task *task)
327{ 453{
328 struct rpc_rqst *req = task->tk_rqstp; 454 struct rpc_rqst *req = task->tk_rqstp;
329 struct rpc_xprt *xprt = req->rq_xprt; 455 struct rpc_xprt *xprt = req->rq_xprt;
456 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
330 struct xdr_buf *xdr = &req->rq_snd_buf; 457 struct xdr_buf *xdr = &req->rq_snd_buf;
331 int status; 458 int status;
332 459
@@ -335,8 +462,10 @@ static int xs_udp_send_request(struct rpc_task *task)
335 req->rq_svec->iov_len); 462 req->rq_svec->iov_len);
336 463
337 req->rq_xtime = jiffies; 464 req->rq_xtime = jiffies;
338 status = xs_sendpages(xprt->sock, (struct sockaddr *) &xprt->addr, 465 status = xs_sendpages(transport->sock,
339 xprt->addrlen, xdr, req->rq_bytes_sent); 466 (struct sockaddr *) &xprt->addr,
467 xprt->addrlen, xdr,
468 req->rq_bytes_sent);
340 469
341 dprintk("RPC: xs_udp_send_request(%u) = %d\n", 470 dprintk("RPC: xs_udp_send_request(%u) = %d\n",
342 xdr->len - req->rq_bytes_sent, status); 471 xdr->len - req->rq_bytes_sent, status);
@@ -392,6 +521,7 @@ static int xs_tcp_send_request(struct rpc_task *task)
392{ 521{
393 struct rpc_rqst *req = task->tk_rqstp; 522 struct rpc_rqst *req = task->tk_rqstp;
394 struct rpc_xprt *xprt = req->rq_xprt; 523 struct rpc_xprt *xprt = req->rq_xprt;
524 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
395 struct xdr_buf *xdr = &req->rq_snd_buf; 525 struct xdr_buf *xdr = &req->rq_snd_buf;
396 int status, retry = 0; 526 int status, retry = 0;
397 527
@@ -406,8 +536,8 @@ static int xs_tcp_send_request(struct rpc_task *task)
406 * called sendmsg(). */ 536 * called sendmsg(). */
407 while (1) { 537 while (1) {
408 req->rq_xtime = jiffies; 538 req->rq_xtime = jiffies;
409 status = xs_sendpages(xprt->sock, NULL, 0, xdr, 539 status = xs_sendpages(transport->sock,
410 req->rq_bytes_sent); 540 NULL, 0, xdr, req->rq_bytes_sent);
411 541
412 dprintk("RPC: xs_tcp_send_request(%u) = %d\n", 542 dprintk("RPC: xs_tcp_send_request(%u) = %d\n",
413 xdr->len - req->rq_bytes_sent, status); 543 xdr->len - req->rq_bytes_sent, status);
@@ -485,8 +615,9 @@ out_release:
485 */ 615 */
486static void xs_close(struct rpc_xprt *xprt) 616static void xs_close(struct rpc_xprt *xprt)
487{ 617{
488 struct socket *sock = xprt->sock; 618 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
489 struct sock *sk = xprt->inet; 619 struct socket *sock = transport->sock;
620 struct sock *sk = transport->inet;
490 621
491 if (!sk) 622 if (!sk)
492 goto clear_close_wait; 623 goto clear_close_wait;
@@ -494,13 +625,13 @@ static void xs_close(struct rpc_xprt *xprt)
494 dprintk("RPC: xs_close xprt %p\n", xprt); 625 dprintk("RPC: xs_close xprt %p\n", xprt);
495 626
496 write_lock_bh(&sk->sk_callback_lock); 627 write_lock_bh(&sk->sk_callback_lock);
497 xprt->inet = NULL; 628 transport->inet = NULL;
498 xprt->sock = NULL; 629 transport->sock = NULL;
499 630
500 sk->sk_user_data = NULL; 631 sk->sk_user_data = NULL;
501 sk->sk_data_ready = xprt->old_data_ready; 632 sk->sk_data_ready = transport->old_data_ready;
502 sk->sk_state_change = xprt->old_state_change; 633 sk->sk_state_change = transport->old_state_change;
503 sk->sk_write_space = xprt->old_write_space; 634 sk->sk_write_space = transport->old_write_space;
504 write_unlock_bh(&sk->sk_callback_lock); 635 write_unlock_bh(&sk->sk_callback_lock);
505 636
506 sk->sk_no_check = 0; 637 sk->sk_no_check = 0;
@@ -519,15 +650,18 @@ clear_close_wait:
519 */ 650 */
520static void xs_destroy(struct rpc_xprt *xprt) 651static void xs_destroy(struct rpc_xprt *xprt)
521{ 652{
653 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
654
522 dprintk("RPC: xs_destroy xprt %p\n", xprt); 655 dprintk("RPC: xs_destroy xprt %p\n", xprt);
523 656
524 cancel_delayed_work(&xprt->connect_worker); 657 cancel_delayed_work(&transport->connect_worker);
525 flush_scheduled_work(); 658 flush_scheduled_work();
526 659
527 xprt_disconnect(xprt); 660 xprt_disconnect(xprt);
528 xs_close(xprt); 661 xs_close(xprt);
529 xs_free_peer_addresses(xprt); 662 xs_free_peer_addresses(xprt);
530 kfree(xprt->slot); 663 kfree(xprt->slot);
664 kfree(xprt);
531} 665}
532 666
533static inline struct rpc_xprt *xprt_from_sock(struct sock *sk) 667static inline struct rpc_xprt *xprt_from_sock(struct sock *sk)
@@ -603,91 +737,75 @@ static void xs_udp_data_ready(struct sock *sk, int len)
603 read_unlock(&sk->sk_callback_lock); 737 read_unlock(&sk->sk_callback_lock);
604} 738}
605 739
606static inline size_t xs_tcp_copy_data(skb_reader_t *desc, void *p, size_t len) 740static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, struct xdr_skb_reader *desc)
607{
608 if (len > desc->count)
609 len = desc->count;
610 if (skb_copy_bits(desc->skb, desc->offset, p, len)) {
611 dprintk("RPC: failed to copy %zu bytes from skb. %zu bytes remain\n",
612 len, desc->count);
613 return 0;
614 }
615 desc->offset += len;
616 desc->count -= len;
617 dprintk("RPC: copied %zu bytes from skb. %zu bytes remain\n",
618 len, desc->count);
619 return len;
620}
621
622static inline void xs_tcp_read_fraghdr(struct rpc_xprt *xprt, skb_reader_t *desc)
623{ 741{
742 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
624 size_t len, used; 743 size_t len, used;
625 char *p; 744 char *p;
626 745
627 p = ((char *) &xprt->tcp_recm) + xprt->tcp_offset; 746 p = ((char *) &transport->tcp_fraghdr) + transport->tcp_offset;
628 len = sizeof(xprt->tcp_recm) - xprt->tcp_offset; 747 len = sizeof(transport->tcp_fraghdr) - transport->tcp_offset;
629 used = xs_tcp_copy_data(desc, p, len); 748 used = xdr_skb_read_bits(desc, p, len);
630 xprt->tcp_offset += used; 749 transport->tcp_offset += used;
631 if (used != len) 750 if (used != len)
632 return; 751 return;
633 752
634 xprt->tcp_reclen = ntohl(xprt->tcp_recm); 753 transport->tcp_reclen = ntohl(transport->tcp_fraghdr);
635 if (xprt->tcp_reclen & RPC_LAST_STREAM_FRAGMENT) 754 if (transport->tcp_reclen & RPC_LAST_STREAM_FRAGMENT)
636 xprt->tcp_flags |= XPRT_LAST_FRAG; 755 transport->tcp_flags |= TCP_RCV_LAST_FRAG;
637 else 756 else
638 xprt->tcp_flags &= ~XPRT_LAST_FRAG; 757 transport->tcp_flags &= ~TCP_RCV_LAST_FRAG;
639 xprt->tcp_reclen &= RPC_FRAGMENT_SIZE_MASK; 758 transport->tcp_reclen &= RPC_FRAGMENT_SIZE_MASK;
640 759
641 xprt->tcp_flags &= ~XPRT_COPY_RECM; 760 transport->tcp_flags &= ~TCP_RCV_COPY_FRAGHDR;
642 xprt->tcp_offset = 0; 761 transport->tcp_offset = 0;
643 762
644 /* Sanity check of the record length */ 763 /* Sanity check of the record length */
645 if (unlikely(xprt->tcp_reclen < 4)) { 764 if (unlikely(transport->tcp_reclen < 4)) {
646 dprintk("RPC: invalid TCP record fragment length\n"); 765 dprintk("RPC: invalid TCP record fragment length\n");
647 xprt_disconnect(xprt); 766 xprt_disconnect(xprt);
648 return; 767 return;
649 } 768 }
650 dprintk("RPC: reading TCP record fragment of length %d\n", 769 dprintk("RPC: reading TCP record fragment of length %d\n",
651 xprt->tcp_reclen); 770 transport->tcp_reclen);
652} 771}
653 772
654static void xs_tcp_check_recm(struct rpc_xprt *xprt) 773static void xs_tcp_check_fraghdr(struct sock_xprt *transport)
655{ 774{
656 dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u, tcp_flags = %lx\n", 775 if (transport->tcp_offset == transport->tcp_reclen) {
657 xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen, xprt->tcp_flags); 776 transport->tcp_flags |= TCP_RCV_COPY_FRAGHDR;
658 if (xprt->tcp_offset == xprt->tcp_reclen) { 777 transport->tcp_offset = 0;
659 xprt->tcp_flags |= XPRT_COPY_RECM; 778 if (transport->tcp_flags & TCP_RCV_LAST_FRAG) {
660 xprt->tcp_offset = 0; 779 transport->tcp_flags &= ~TCP_RCV_COPY_DATA;
661 if (xprt->tcp_flags & XPRT_LAST_FRAG) { 780 transport->tcp_flags |= TCP_RCV_COPY_XID;
662 xprt->tcp_flags &= ~XPRT_COPY_DATA; 781 transport->tcp_copied = 0;
663 xprt->tcp_flags |= XPRT_COPY_XID;
664 xprt->tcp_copied = 0;
665 } 782 }
666 } 783 }
667} 784}
668 785
669static inline void xs_tcp_read_xid(struct rpc_xprt *xprt, skb_reader_t *desc) 786static inline void xs_tcp_read_xid(struct sock_xprt *transport, struct xdr_skb_reader *desc)
670{ 787{
671 size_t len, used; 788 size_t len, used;
672 char *p; 789 char *p;
673 790
674 len = sizeof(xprt->tcp_xid) - xprt->tcp_offset; 791 len = sizeof(transport->tcp_xid) - transport->tcp_offset;
675 dprintk("RPC: reading XID (%Zu bytes)\n", len); 792 dprintk("RPC: reading XID (%Zu bytes)\n", len);
676 p = ((char *) &xprt->tcp_xid) + xprt->tcp_offset; 793 p = ((char *) &transport->tcp_xid) + transport->tcp_offset;
677 used = xs_tcp_copy_data(desc, p, len); 794 used = xdr_skb_read_bits(desc, p, len);
678 xprt->tcp_offset += used; 795 transport->tcp_offset += used;
679 if (used != len) 796 if (used != len)
680 return; 797 return;
681 xprt->tcp_flags &= ~XPRT_COPY_XID; 798 transport->tcp_flags &= ~TCP_RCV_COPY_XID;
682 xprt->tcp_flags |= XPRT_COPY_DATA; 799 transport->tcp_flags |= TCP_RCV_COPY_DATA;
683 xprt->tcp_copied = 4; 800 transport->tcp_copied = 4;
684 dprintk("RPC: reading reply for XID %08x\n", 801 dprintk("RPC: reading reply for XID %08x\n",
685 ntohl(xprt->tcp_xid)); 802 ntohl(transport->tcp_xid));
686 xs_tcp_check_recm(xprt); 803 xs_tcp_check_fraghdr(transport);
687} 804}
688 805
689static inline void xs_tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc) 806static inline void xs_tcp_read_request(struct rpc_xprt *xprt, struct xdr_skb_reader *desc)
690{ 807{
808 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
691 struct rpc_rqst *req; 809 struct rpc_rqst *req;
692 struct xdr_buf *rcvbuf; 810 struct xdr_buf *rcvbuf;
693 size_t len; 811 size_t len;
@@ -695,116 +813,118 @@ static inline void xs_tcp_read_request(struct rpc_xprt *xprt, skb_reader_t *desc
695 813
696 /* Find and lock the request corresponding to this xid */ 814 /* Find and lock the request corresponding to this xid */
697 spin_lock(&xprt->transport_lock); 815 spin_lock(&xprt->transport_lock);
698 req = xprt_lookup_rqst(xprt, xprt->tcp_xid); 816 req = xprt_lookup_rqst(xprt, transport->tcp_xid);
699 if (!req) { 817 if (!req) {
700 xprt->tcp_flags &= ~XPRT_COPY_DATA; 818 transport->tcp_flags &= ~TCP_RCV_COPY_DATA;
701 dprintk("RPC: XID %08x request not found!\n", 819 dprintk("RPC: XID %08x request not found!\n",
702 ntohl(xprt->tcp_xid)); 820 ntohl(transport->tcp_xid));
703 spin_unlock(&xprt->transport_lock); 821 spin_unlock(&xprt->transport_lock);
704 return; 822 return;
705 } 823 }
706 824
707 rcvbuf = &req->rq_private_buf; 825 rcvbuf = &req->rq_private_buf;
708 len = desc->count; 826 len = desc->count;
709 if (len > xprt->tcp_reclen - xprt->tcp_offset) { 827 if (len > transport->tcp_reclen - transport->tcp_offset) {
710 skb_reader_t my_desc; 828 struct xdr_skb_reader my_desc;
711 829
712 len = xprt->tcp_reclen - xprt->tcp_offset; 830 len = transport->tcp_reclen - transport->tcp_offset;
713 memcpy(&my_desc, desc, sizeof(my_desc)); 831 memcpy(&my_desc, desc, sizeof(my_desc));
714 my_desc.count = len; 832 my_desc.count = len;
715 r = xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied, 833 r = xdr_partial_copy_from_skb(rcvbuf, transport->tcp_copied,
716 &my_desc, xs_tcp_copy_data); 834 &my_desc, xdr_skb_read_bits);
717 desc->count -= r; 835 desc->count -= r;
718 desc->offset += r; 836 desc->offset += r;
719 } else 837 } else
720 r = xdr_partial_copy_from_skb(rcvbuf, xprt->tcp_copied, 838 r = xdr_partial_copy_from_skb(rcvbuf, transport->tcp_copied,
721 desc, xs_tcp_copy_data); 839 desc, xdr_skb_read_bits);
722 840
723 if (r > 0) { 841 if (r > 0) {
724 xprt->tcp_copied += r; 842 transport->tcp_copied += r;
725 xprt->tcp_offset += r; 843 transport->tcp_offset += r;
726 } 844 }
727 if (r != len) { 845 if (r != len) {
728 /* Error when copying to the receive buffer, 846 /* Error when copying to the receive buffer,
729 * usually because we weren't able to allocate 847 * usually because we weren't able to allocate
730 * additional buffer pages. All we can do now 848 * additional buffer pages. All we can do now
731 * is turn off XPRT_COPY_DATA, so the request 849 * is turn off TCP_RCV_COPY_DATA, so the request
732 * will not receive any additional updates, 850 * will not receive any additional updates,
733 * and time out. 851 * and time out.
734 * Any remaining data from this record will 852 * Any remaining data from this record will
735 * be discarded. 853 * be discarded.
736 */ 854 */
737 xprt->tcp_flags &= ~XPRT_COPY_DATA; 855 transport->tcp_flags &= ~TCP_RCV_COPY_DATA;
738 dprintk("RPC: XID %08x truncated request\n", 856 dprintk("RPC: XID %08x truncated request\n",
739 ntohl(xprt->tcp_xid)); 857 ntohl(transport->tcp_xid));
740 dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n", 858 dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n",
741 xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen); 859 xprt, transport->tcp_copied, transport->tcp_offset,
860 transport->tcp_reclen);
742 goto out; 861 goto out;
743 } 862 }
744 863
745 dprintk("RPC: XID %08x read %Zd bytes\n", 864 dprintk("RPC: XID %08x read %Zd bytes\n",
746 ntohl(xprt->tcp_xid), r); 865 ntohl(transport->tcp_xid), r);
747 dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n", 866 dprintk("RPC: xprt = %p, tcp_copied = %lu, tcp_offset = %u, tcp_reclen = %u\n",
748 xprt, xprt->tcp_copied, xprt->tcp_offset, xprt->tcp_reclen); 867 xprt, transport->tcp_copied, transport->tcp_offset,
749 868 transport->tcp_reclen);
750 if (xprt->tcp_copied == req->rq_private_buf.buflen) 869
751 xprt->tcp_flags &= ~XPRT_COPY_DATA; 870 if (transport->tcp_copied == req->rq_private_buf.buflen)
752 else if (xprt->tcp_offset == xprt->tcp_reclen) { 871 transport->tcp_flags &= ~TCP_RCV_COPY_DATA;
753 if (xprt->tcp_flags & XPRT_LAST_FRAG) 872 else if (transport->tcp_offset == transport->tcp_reclen) {
754 xprt->tcp_flags &= ~XPRT_COPY_DATA; 873 if (transport->tcp_flags & TCP_RCV_LAST_FRAG)
874 transport->tcp_flags &= ~TCP_RCV_COPY_DATA;
755 } 875 }
756 876
757out: 877out:
758 if (!(xprt->tcp_flags & XPRT_COPY_DATA)) 878 if (!(transport->tcp_flags & TCP_RCV_COPY_DATA))
759 xprt_complete_rqst(req->rq_task, xprt->tcp_copied); 879 xprt_complete_rqst(req->rq_task, transport->tcp_copied);
760 spin_unlock(&xprt->transport_lock); 880 spin_unlock(&xprt->transport_lock);
761 xs_tcp_check_recm(xprt); 881 xs_tcp_check_fraghdr(transport);
762} 882}
763 883
764static inline void xs_tcp_read_discard(struct rpc_xprt *xprt, skb_reader_t *desc) 884static inline void xs_tcp_read_discard(struct sock_xprt *transport, struct xdr_skb_reader *desc)
765{ 885{
766 size_t len; 886 size_t len;
767 887
768 len = xprt->tcp_reclen - xprt->tcp_offset; 888 len = transport->tcp_reclen - transport->tcp_offset;
769 if (len > desc->count) 889 if (len > desc->count)
770 len = desc->count; 890 len = desc->count;
771 desc->count -= len; 891 desc->count -= len;
772 desc->offset += len; 892 desc->offset += len;
773 xprt->tcp_offset += len; 893 transport->tcp_offset += len;
774 dprintk("RPC: discarded %Zu bytes\n", len); 894 dprintk("RPC: discarded %Zu bytes\n", len);
775 xs_tcp_check_recm(xprt); 895 xs_tcp_check_fraghdr(transport);
776} 896}
777 897
778static int xs_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, unsigned int offset, size_t len) 898static int xs_tcp_data_recv(read_descriptor_t *rd_desc, struct sk_buff *skb, unsigned int offset, size_t len)
779{ 899{
780 struct rpc_xprt *xprt = rd_desc->arg.data; 900 struct rpc_xprt *xprt = rd_desc->arg.data;
781 skb_reader_t desc = { 901 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
902 struct xdr_skb_reader desc = {
782 .skb = skb, 903 .skb = skb,
783 .offset = offset, 904 .offset = offset,
784 .count = len, 905 .count = len,
785 .csum = 0
786 }; 906 };
787 907
788 dprintk("RPC: xs_tcp_data_recv started\n"); 908 dprintk("RPC: xs_tcp_data_recv started\n");
789 do { 909 do {
790 /* Read in a new fragment marker if necessary */ 910 /* Read in a new fragment marker if necessary */
791 /* Can we ever really expect to get completely empty fragments? */ 911 /* Can we ever really expect to get completely empty fragments? */
792 if (xprt->tcp_flags & XPRT_COPY_RECM) { 912 if (transport->tcp_flags & TCP_RCV_COPY_FRAGHDR) {
793 xs_tcp_read_fraghdr(xprt, &desc); 913 xs_tcp_read_fraghdr(xprt, &desc);
794 continue; 914 continue;
795 } 915 }
796 /* Read in the xid if necessary */ 916 /* Read in the xid if necessary */
797 if (xprt->tcp_flags & XPRT_COPY_XID) { 917 if (transport->tcp_flags & TCP_RCV_COPY_XID) {
798 xs_tcp_read_xid(xprt, &desc); 918 xs_tcp_read_xid(transport, &desc);
799 continue; 919 continue;
800 } 920 }
801 /* Read in the request data */ 921 /* Read in the request data */
802 if (xprt->tcp_flags & XPRT_COPY_DATA) { 922 if (transport->tcp_flags & TCP_RCV_COPY_DATA) {
803 xs_tcp_read_request(xprt, &desc); 923 xs_tcp_read_request(xprt, &desc);
804 continue; 924 continue;
805 } 925 }
806 /* Skip over any trailing bytes on short reads */ 926 /* Skip over any trailing bytes on short reads */
807 xs_tcp_read_discard(xprt, &desc); 927 xs_tcp_read_discard(transport, &desc);
808 } while (desc.count); 928 } while (desc.count);
809 dprintk("RPC: xs_tcp_data_recv done\n"); 929 dprintk("RPC: xs_tcp_data_recv done\n");
810 return len - desc.count; 930 return len - desc.count;
@@ -858,11 +978,16 @@ static void xs_tcp_state_change(struct sock *sk)
858 case TCP_ESTABLISHED: 978 case TCP_ESTABLISHED:
859 spin_lock_bh(&xprt->transport_lock); 979 spin_lock_bh(&xprt->transport_lock);
860 if (!xprt_test_and_set_connected(xprt)) { 980 if (!xprt_test_and_set_connected(xprt)) {
981 struct sock_xprt *transport = container_of(xprt,
982 struct sock_xprt, xprt);
983
861 /* Reset TCP record info */ 984 /* Reset TCP record info */
862 xprt->tcp_offset = 0; 985 transport->tcp_offset = 0;
863 xprt->tcp_reclen = 0; 986 transport->tcp_reclen = 0;
864 xprt->tcp_copied = 0; 987 transport->tcp_copied = 0;
865 xprt->tcp_flags = XPRT_COPY_RECM | XPRT_COPY_XID; 988 transport->tcp_flags =
989 TCP_RCV_COPY_FRAGHDR | TCP_RCV_COPY_XID;
990
866 xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; 991 xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;
867 xprt_wake_pending_tasks(xprt, 0); 992 xprt_wake_pending_tasks(xprt, 0);
868 } 993 }
@@ -951,15 +1076,16 @@ static void xs_tcp_write_space(struct sock *sk)
951 1076
952static void xs_udp_do_set_buffer_size(struct rpc_xprt *xprt) 1077static void xs_udp_do_set_buffer_size(struct rpc_xprt *xprt)
953{ 1078{
954 struct sock *sk = xprt->inet; 1079 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
1080 struct sock *sk = transport->inet;
955 1081
956 if (xprt->rcvsize) { 1082 if (transport->rcvsize) {
957 sk->sk_userlocks |= SOCK_RCVBUF_LOCK; 1083 sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
958 sk->sk_rcvbuf = xprt->rcvsize * xprt->max_reqs * 2; 1084 sk->sk_rcvbuf = transport->rcvsize * xprt->max_reqs * 2;
959 } 1085 }
960 if (xprt->sndsize) { 1086 if (transport->sndsize) {
961 sk->sk_userlocks |= SOCK_SNDBUF_LOCK; 1087 sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
962 sk->sk_sndbuf = xprt->sndsize * xprt->max_reqs * 2; 1088 sk->sk_sndbuf = transport->sndsize * xprt->max_reqs * 2;
963 sk->sk_write_space(sk); 1089 sk->sk_write_space(sk);
964 } 1090 }
965} 1091}
@@ -974,12 +1100,14 @@ static void xs_udp_do_set_buffer_size(struct rpc_xprt *xprt)
974 */ 1100 */
975static void xs_udp_set_buffer_size(struct rpc_xprt *xprt, size_t sndsize, size_t rcvsize) 1101static void xs_udp_set_buffer_size(struct rpc_xprt *xprt, size_t sndsize, size_t rcvsize)
976{ 1102{
977 xprt->sndsize = 0; 1103 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
1104
1105 transport->sndsize = 0;
978 if (sndsize) 1106 if (sndsize)
979 xprt->sndsize = sndsize + 1024; 1107 transport->sndsize = sndsize + 1024;
980 xprt->rcvsize = 0; 1108 transport->rcvsize = 0;
981 if (rcvsize) 1109 if (rcvsize)
982 xprt->rcvsize = rcvsize + 1024; 1110 transport->rcvsize = rcvsize + 1024;
983 1111
984 xs_udp_do_set_buffer_size(xprt); 1112 xs_udp_do_set_buffer_size(xprt);
985} 1113}
@@ -1003,19 +1131,6 @@ static unsigned short xs_get_random_port(void)
1003} 1131}
1004 1132
1005/** 1133/**
1006 * xs_print_peer_address - format an IPv4 address for printing
1007 * @xprt: generic transport
1008 * @format: flags field indicating which parts of the address to render
1009 */
1010static char *xs_print_peer_address(struct rpc_xprt *xprt, enum rpc_display_format_t format)
1011{
1012 if (xprt->address_strings[format] != NULL)
1013 return xprt->address_strings[format];
1014 else
1015 return "unprintable";
1016}
1017
1018/**
1019 * xs_set_port - reset the port number in the remote endpoint address 1134 * xs_set_port - reset the port number in the remote endpoint address
1020 * @xprt: generic transport 1135 * @xprt: generic transport
1021 * @port: new port number 1136 * @port: new port number
@@ -1030,20 +1145,20 @@ static void xs_set_port(struct rpc_xprt *xprt, unsigned short port)
1030 sap->sin_port = htons(port); 1145 sap->sin_port = htons(port);
1031} 1146}
1032 1147
1033static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock) 1148static int xs_bindresvport(struct sock_xprt *transport, struct socket *sock)
1034{ 1149{
1035 struct sockaddr_in myaddr = { 1150 struct sockaddr_in myaddr = {
1036 .sin_family = AF_INET, 1151 .sin_family = AF_INET,
1037 }; 1152 };
1038 int err; 1153 int err;
1039 unsigned short port = xprt->port; 1154 unsigned short port = transport->port;
1040 1155
1041 do { 1156 do {
1042 myaddr.sin_port = htons(port); 1157 myaddr.sin_port = htons(port);
1043 err = kernel_bind(sock, (struct sockaddr *) &myaddr, 1158 err = kernel_bind(sock, (struct sockaddr *) &myaddr,
1044 sizeof(myaddr)); 1159 sizeof(myaddr));
1045 if (err == 0) { 1160 if (err == 0) {
1046 xprt->port = port; 1161 transport->port = port;
1047 dprintk("RPC: xs_bindresvport bound to port %u\n", 1162 dprintk("RPC: xs_bindresvport bound to port %u\n",
1048 port); 1163 port);
1049 return 0; 1164 return 0;
@@ -1052,22 +1167,53 @@ static int xs_bindresvport(struct rpc_xprt *xprt, struct socket *sock)
1052 port = xprt_max_resvport; 1167 port = xprt_max_resvport;
1053 else 1168 else
1054 port--; 1169 port--;
1055 } while (err == -EADDRINUSE && port != xprt->port); 1170 } while (err == -EADDRINUSE && port != transport->port);
1056 1171
1057 dprintk("RPC: can't bind to reserved port (%d).\n", -err); 1172 dprintk("RPC: can't bind to reserved port (%d).\n", -err);
1058 return err; 1173 return err;
1059} 1174}
1060 1175
1176#ifdef CONFIG_DEBUG_LOCK_ALLOC
1177static struct lock_class_key xs_key[2];
1178static struct lock_class_key xs_slock_key[2];
1179
1180static inline void xs_reclassify_socket(struct socket *sock)
1181{
1182 struct sock *sk = sock->sk;
1183 BUG_ON(sk->sk_lock.owner != NULL);
1184 switch (sk->sk_family) {
1185 case AF_INET:
1186 sock_lock_init_class_and_name(sk, "slock-AF_INET-NFS",
1187 &xs_slock_key[0], "sk_lock-AF_INET-NFS", &xs_key[0]);
1188 break;
1189
1190 case AF_INET6:
1191 sock_lock_init_class_and_name(sk, "slock-AF_INET6-NFS",
1192 &xs_slock_key[1], "sk_lock-AF_INET6-NFS", &xs_key[1]);
1193 break;
1194
1195 default:
1196 BUG();
1197 }
1198}
1199#else
1200static inline void xs_reclassify_socket(struct socket *sock)
1201{
1202}
1203#endif
1204
1061/** 1205/**
1062 * xs_udp_connect_worker - set up a UDP socket 1206 * xs_udp_connect_worker - set up a UDP socket
1063 * @args: RPC transport to connect 1207 * @work: RPC transport to connect
1064 * 1208 *
1065 * Invoked by a work queue tasklet. 1209 * Invoked by a work queue tasklet.
1066 */ 1210 */
1067static void xs_udp_connect_worker(void *args) 1211static void xs_udp_connect_worker(struct work_struct *work)
1068{ 1212{
1069 struct rpc_xprt *xprt = (struct rpc_xprt *) args; 1213 struct sock_xprt *transport =
1070 struct socket *sock = xprt->sock; 1214 container_of(work, struct sock_xprt, connect_worker.work);
1215 struct rpc_xprt *xprt = &transport->xprt;
1216 struct socket *sock = transport->sock;
1071 int err, status = -EIO; 1217 int err, status = -EIO;
1072 1218
1073 if (xprt->shutdown || !xprt_bound(xprt)) 1219 if (xprt->shutdown || !xprt_bound(xprt))
@@ -1080,24 +1226,25 @@ static void xs_udp_connect_worker(void *args)
1080 dprintk("RPC: can't create UDP transport socket (%d).\n", -err); 1226 dprintk("RPC: can't create UDP transport socket (%d).\n", -err);
1081 goto out; 1227 goto out;
1082 } 1228 }
1229 xs_reclassify_socket(sock);
1083 1230
1084 if (xprt->resvport && xs_bindresvport(xprt, sock) < 0) { 1231 if (xprt->resvport && xs_bindresvport(transport, sock) < 0) {
1085 sock_release(sock); 1232 sock_release(sock);
1086 goto out; 1233 goto out;
1087 } 1234 }
1088 1235
1089 dprintk("RPC: worker connecting xprt %p to address: %s\n", 1236 dprintk("RPC: worker connecting xprt %p to address: %s\n",
1090 xprt, xs_print_peer_address(xprt, RPC_DISPLAY_ALL)); 1237 xprt, xprt->address_strings[RPC_DISPLAY_ALL]);
1091 1238
1092 if (!xprt->inet) { 1239 if (!transport->inet) {
1093 struct sock *sk = sock->sk; 1240 struct sock *sk = sock->sk;
1094 1241
1095 write_lock_bh(&sk->sk_callback_lock); 1242 write_lock_bh(&sk->sk_callback_lock);
1096 1243
1097 sk->sk_user_data = xprt; 1244 sk->sk_user_data = xprt;
1098 xprt->old_data_ready = sk->sk_data_ready; 1245 transport->old_data_ready = sk->sk_data_ready;
1099 xprt->old_state_change = sk->sk_state_change; 1246 transport->old_state_change = sk->sk_state_change;
1100 xprt->old_write_space = sk->sk_write_space; 1247 transport->old_write_space = sk->sk_write_space;
1101 sk->sk_data_ready = xs_udp_data_ready; 1248 sk->sk_data_ready = xs_udp_data_ready;
1102 sk->sk_write_space = xs_udp_write_space; 1249 sk->sk_write_space = xs_udp_write_space;
1103 sk->sk_no_check = UDP_CSUM_NORCV; 1250 sk->sk_no_check = UDP_CSUM_NORCV;
@@ -1106,8 +1253,8 @@ static void xs_udp_connect_worker(void *args)
1106 xprt_set_connected(xprt); 1253 xprt_set_connected(xprt);
1107 1254
1108 /* Reset to new socket */ 1255 /* Reset to new socket */
1109 xprt->sock = sock; 1256 transport->sock = sock;
1110 xprt->inet = sk; 1257 transport->inet = sk;
1111 1258
1112 write_unlock_bh(&sk->sk_callback_lock); 1259 write_unlock_bh(&sk->sk_callback_lock);
1113 } 1260 }
@@ -1125,7 +1272,7 @@ out:
1125static void xs_tcp_reuse_connection(struct rpc_xprt *xprt) 1272static void xs_tcp_reuse_connection(struct rpc_xprt *xprt)
1126{ 1273{
1127 int result; 1274 int result;
1128 struct socket *sock = xprt->sock; 1275 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
1129 struct sockaddr any; 1276 struct sockaddr any;
1130 1277
1131 dprintk("RPC: disconnecting xprt %p to reuse port\n", xprt); 1278 dprintk("RPC: disconnecting xprt %p to reuse port\n", xprt);
@@ -1136,7 +1283,7 @@ static void xs_tcp_reuse_connection(struct rpc_xprt *xprt)
1136 */ 1283 */
1137 memset(&any, 0, sizeof(any)); 1284 memset(&any, 0, sizeof(any));
1138 any.sa_family = AF_UNSPEC; 1285 any.sa_family = AF_UNSPEC;
1139 result = kernel_connect(sock, &any, sizeof(any), 0); 1286 result = kernel_connect(transport->sock, &any, sizeof(any), 0);
1140 if (result) 1287 if (result)
1141 dprintk("RPC: AF_UNSPEC connect return code %d\n", 1288 dprintk("RPC: AF_UNSPEC connect return code %d\n",
1142 result); 1289 result);
@@ -1144,27 +1291,30 @@ static void xs_tcp_reuse_connection(struct rpc_xprt *xprt)
1144 1291
1145/** 1292/**
1146 * xs_tcp_connect_worker - connect a TCP socket to a remote endpoint 1293 * xs_tcp_connect_worker - connect a TCP socket to a remote endpoint
1147 * @args: RPC transport to connect 1294 * @work: RPC transport to connect
1148 * 1295 *
1149 * Invoked by a work queue tasklet. 1296 * Invoked by a work queue tasklet.
1150 */ 1297 */
1151static void xs_tcp_connect_worker(void *args) 1298static void xs_tcp_connect_worker(struct work_struct *work)
1152{ 1299{
1153 struct rpc_xprt *xprt = (struct rpc_xprt *)args; 1300 struct sock_xprt *transport =
1154 struct socket *sock = xprt->sock; 1301 container_of(work, struct sock_xprt, connect_worker.work);
1302 struct rpc_xprt *xprt = &transport->xprt;
1303 struct socket *sock = transport->sock;
1155 int err, status = -EIO; 1304 int err, status = -EIO;
1156 1305
1157 if (xprt->shutdown || !xprt_bound(xprt)) 1306 if (xprt->shutdown || !xprt_bound(xprt))
1158 goto out; 1307 goto out;
1159 1308
1160 if (!xprt->sock) { 1309 if (!sock) {
1161 /* start from scratch */ 1310 /* start from scratch */
1162 if ((err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock)) < 0) { 1311 if ((err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock)) < 0) {
1163 dprintk("RPC: can't create TCP transport socket (%d).\n", -err); 1312 dprintk("RPC: can't create TCP transport socket (%d).\n", -err);
1164 goto out; 1313 goto out;
1165 } 1314 }
1315 xs_reclassify_socket(sock);
1166 1316
1167 if (xprt->resvport && xs_bindresvport(xprt, sock) < 0) { 1317 if (xprt->resvport && xs_bindresvport(transport, sock) < 0) {
1168 sock_release(sock); 1318 sock_release(sock);
1169 goto out; 1319 goto out;
1170 } 1320 }
@@ -1173,17 +1323,17 @@ static void xs_tcp_connect_worker(void *args)
1173 xs_tcp_reuse_connection(xprt); 1323 xs_tcp_reuse_connection(xprt);
1174 1324
1175 dprintk("RPC: worker connecting xprt %p to address: %s\n", 1325 dprintk("RPC: worker connecting xprt %p to address: %s\n",
1176 xprt, xs_print_peer_address(xprt, RPC_DISPLAY_ALL)); 1326 xprt, xprt->address_strings[RPC_DISPLAY_ALL]);
1177 1327
1178 if (!xprt->inet) { 1328 if (!transport->inet) {
1179 struct sock *sk = sock->sk; 1329 struct sock *sk = sock->sk;
1180 1330
1181 write_lock_bh(&sk->sk_callback_lock); 1331 write_lock_bh(&sk->sk_callback_lock);
1182 1332
1183 sk->sk_user_data = xprt; 1333 sk->sk_user_data = xprt;
1184 xprt->old_data_ready = sk->sk_data_ready; 1334 transport->old_data_ready = sk->sk_data_ready;
1185 xprt->old_state_change = sk->sk_state_change; 1335 transport->old_state_change = sk->sk_state_change;
1186 xprt->old_write_space = sk->sk_write_space; 1336 transport->old_write_space = sk->sk_write_space;
1187 sk->sk_data_ready = xs_tcp_data_ready; 1337 sk->sk_data_ready = xs_tcp_data_ready;
1188 sk->sk_state_change = xs_tcp_state_change; 1338 sk->sk_state_change = xs_tcp_state_change;
1189 sk->sk_write_space = xs_tcp_write_space; 1339 sk->sk_write_space = xs_tcp_write_space;
@@ -1198,8 +1348,8 @@ static void xs_tcp_connect_worker(void *args)
1198 xprt_clear_connected(xprt); 1348 xprt_clear_connected(xprt);
1199 1349
1200 /* Reset to new socket */ 1350 /* Reset to new socket */
1201 xprt->sock = sock; 1351 transport->sock = sock;
1202 xprt->inet = sk; 1352 transport->inet = sk;
1203 1353
1204 write_unlock_bh(&sk->sk_callback_lock); 1354 write_unlock_bh(&sk->sk_callback_lock);
1205 } 1355 }
@@ -1248,21 +1398,22 @@ out_clear:
1248static void xs_connect(struct rpc_task *task) 1398static void xs_connect(struct rpc_task *task)
1249{ 1399{
1250 struct rpc_xprt *xprt = task->tk_xprt; 1400 struct rpc_xprt *xprt = task->tk_xprt;
1401 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
1251 1402
1252 if (xprt_test_and_set_connecting(xprt)) 1403 if (xprt_test_and_set_connecting(xprt))
1253 return; 1404 return;
1254 1405
1255 if (xprt->sock != NULL) { 1406 if (transport->sock != NULL) {
1256 dprintk("RPC: xs_connect delayed xprt %p for %lu seconds\n", 1407 dprintk("RPC: xs_connect delayed xprt %p for %lu seconds\n",
1257 xprt, xprt->reestablish_timeout / HZ); 1408 xprt, xprt->reestablish_timeout / HZ);
1258 schedule_delayed_work(&xprt->connect_worker, 1409 schedule_delayed_work(&transport->connect_worker,
1259 xprt->reestablish_timeout); 1410 xprt->reestablish_timeout);
1260 xprt->reestablish_timeout <<= 1; 1411 xprt->reestablish_timeout <<= 1;
1261 if (xprt->reestablish_timeout > XS_TCP_MAX_REEST_TO) 1412 if (xprt->reestablish_timeout > XS_TCP_MAX_REEST_TO)
1262 xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO; 1413 xprt->reestablish_timeout = XS_TCP_MAX_REEST_TO;
1263 } else { 1414 } else {
1264 dprintk("RPC: xs_connect scheduled xprt %p\n", xprt); 1415 dprintk("RPC: xs_connect scheduled xprt %p\n", xprt);
1265 schedule_work(&xprt->connect_worker); 1416 schedule_delayed_work(&transport->connect_worker, 0);
1266 1417
1267 /* flush_scheduled_work can sleep... */ 1418 /* flush_scheduled_work can sleep... */
1268 if (!RPC_IS_ASYNC(task)) 1419 if (!RPC_IS_ASYNC(task))
@@ -1278,8 +1429,10 @@ static void xs_connect(struct rpc_task *task)
1278 */ 1429 */
1279static void xs_udp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq) 1430static void xs_udp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
1280{ 1431{
1432 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
1433
1281 seq_printf(seq, "\txprt:\tudp %u %lu %lu %lu %lu %Lu %Lu\n", 1434 seq_printf(seq, "\txprt:\tudp %u %lu %lu %lu %lu %Lu %Lu\n",
1282 xprt->port, 1435 transport->port,
1283 xprt->stat.bind_count, 1436 xprt->stat.bind_count,
1284 xprt->stat.sends, 1437 xprt->stat.sends,
1285 xprt->stat.recvs, 1438 xprt->stat.recvs,
@@ -1296,13 +1449,14 @@ static void xs_udp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
1296 */ 1449 */
1297static void xs_tcp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq) 1450static void xs_tcp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
1298{ 1451{
1452 struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
1299 long idle_time = 0; 1453 long idle_time = 0;
1300 1454
1301 if (xprt_connected(xprt)) 1455 if (xprt_connected(xprt))
1302 idle_time = (long)(jiffies - xprt->last_used) / HZ; 1456 idle_time = (long)(jiffies - xprt->last_used) / HZ;
1303 1457
1304 seq_printf(seq, "\txprt:\ttcp %u %lu %lu %lu %ld %lu %lu %lu %Lu %Lu\n", 1458 seq_printf(seq, "\txprt:\ttcp %u %lu %lu %lu %ld %lu %lu %lu %Lu %Lu\n",
1305 xprt->port, 1459 transport->port,
1306 xprt->stat.bind_count, 1460 xprt->stat.bind_count,
1307 xprt->stat.connect_count, 1461 xprt->stat.connect_count,
1308 xprt->stat.connect_time, 1462 xprt->stat.connect_time,
@@ -1316,7 +1470,6 @@ static void xs_tcp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq)
1316 1470
1317static struct rpc_xprt_ops xs_udp_ops = { 1471static struct rpc_xprt_ops xs_udp_ops = {
1318 .set_buffer_size = xs_udp_set_buffer_size, 1472 .set_buffer_size = xs_udp_set_buffer_size,
1319 .print_addr = xs_print_peer_address,
1320 .reserve_xprt = xprt_reserve_xprt_cong, 1473 .reserve_xprt = xprt_reserve_xprt_cong,
1321 .release_xprt = xprt_release_xprt_cong, 1474 .release_xprt = xprt_release_xprt_cong,
1322 .rpcbind = rpc_getport, 1475 .rpcbind = rpc_getport,
@@ -1334,7 +1487,6 @@ static struct rpc_xprt_ops xs_udp_ops = {
1334}; 1487};
1335 1488
1336static struct rpc_xprt_ops xs_tcp_ops = { 1489static struct rpc_xprt_ops xs_tcp_ops = {
1337 .print_addr = xs_print_peer_address,
1338 .reserve_xprt = xprt_reserve_xprt, 1490 .reserve_xprt = xprt_reserve_xprt,
1339 .release_xprt = xs_tcp_release_xprt, 1491 .release_xprt = xs_tcp_release_xprt,
1340 .rpcbind = rpc_getport, 1492 .rpcbind = rpc_getport,
@@ -1349,33 +1501,64 @@ static struct rpc_xprt_ops xs_tcp_ops = {
1349 .print_stats = xs_tcp_print_stats, 1501 .print_stats = xs_tcp_print_stats,
1350}; 1502};
1351 1503
1504static struct rpc_xprt *xs_setup_xprt(struct sockaddr *addr, size_t addrlen, unsigned int slot_table_size)
1505{
1506 struct rpc_xprt *xprt;
1507 struct sock_xprt *new;
1508
1509 if (addrlen > sizeof(xprt->addr)) {
1510 dprintk("RPC: xs_setup_xprt: address too large\n");
1511 return ERR_PTR(-EBADF);
1512 }
1513
1514 new = kzalloc(sizeof(*new), GFP_KERNEL);
1515 if (new == NULL) {
1516 dprintk("RPC: xs_setup_xprt: couldn't allocate rpc_xprt\n");
1517 return ERR_PTR(-ENOMEM);
1518 }
1519 xprt = &new->xprt;
1520
1521 xprt->max_reqs = slot_table_size;
1522 xprt->slot = kcalloc(xprt->max_reqs, sizeof(struct rpc_rqst), GFP_KERNEL);
1523 if (xprt->slot == NULL) {
1524 kfree(xprt);
1525 dprintk("RPC: xs_setup_xprt: couldn't allocate slot table\n");
1526 return ERR_PTR(-ENOMEM);
1527 }
1528
1529 memcpy(&xprt->addr, addr, addrlen);
1530 xprt->addrlen = addrlen;
1531 new->port = xs_get_random_port();
1532
1533 return xprt;
1534}
1535
1352/** 1536/**
1353 * xs_setup_udp - Set up transport to use a UDP socket 1537 * xs_setup_udp - Set up transport to use a UDP socket
1354 * @xprt: transport to set up 1538 * @addr: address of remote server
1539 * @addrlen: length of address in bytes
1355 * @to: timeout parameters 1540 * @to: timeout parameters
1356 * 1541 *
1357 */ 1542 */
1358int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to) 1543struct rpc_xprt *xs_setup_udp(struct sockaddr *addr, size_t addrlen, struct rpc_timeout *to)
1359{ 1544{
1360 size_t slot_table_size; 1545 struct rpc_xprt *xprt;
1361 struct sockaddr_in *addr = (struct sockaddr_in *) &xprt->addr; 1546 struct sock_xprt *transport;
1362 1547
1363 xprt->max_reqs = xprt_udp_slot_table_entries; 1548 xprt = xs_setup_xprt(addr, addrlen, xprt_udp_slot_table_entries);
1364 slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]); 1549 if (IS_ERR(xprt))
1365 xprt->slot = kzalloc(slot_table_size, GFP_KERNEL); 1550 return xprt;
1366 if (xprt->slot == NULL) 1551 transport = container_of(xprt, struct sock_xprt, xprt);
1367 return -ENOMEM;
1368 1552
1369 if (ntohs(addr->sin_port) != 0) 1553 if (ntohs(((struct sockaddr_in *)addr)->sin_port) != 0)
1370 xprt_set_bound(xprt); 1554 xprt_set_bound(xprt);
1371 xprt->port = xs_get_random_port();
1372 1555
1373 xprt->prot = IPPROTO_UDP; 1556 xprt->prot = IPPROTO_UDP;
1374 xprt->tsh_size = 0; 1557 xprt->tsh_size = 0;
1375 /* XXX: header size can vary due to auth type, IPv6, etc. */ 1558 /* XXX: header size can vary due to auth type, IPv6, etc. */
1376 xprt->max_payload = (1U << 16) - (MAX_HEADER << 3); 1559 xprt->max_payload = (1U << 16) - (MAX_HEADER << 3);
1377 1560
1378 INIT_WORK(&xprt->connect_worker, xs_udp_connect_worker, xprt); 1561 INIT_DELAYED_WORK(&transport->connect_worker, xs_udp_connect_worker);
1379 xprt->bind_timeout = XS_BIND_TO; 1562 xprt->bind_timeout = XS_BIND_TO;
1380 xprt->connect_timeout = XS_UDP_CONN_TO; 1563 xprt->connect_timeout = XS_UDP_CONN_TO;
1381 xprt->reestablish_timeout = XS_UDP_REEST_TO; 1564 xprt->reestablish_timeout = XS_UDP_REEST_TO;
@@ -1390,37 +1573,36 @@ int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to)
1390 1573
1391 xs_format_peer_addresses(xprt); 1574 xs_format_peer_addresses(xprt);
1392 dprintk("RPC: set up transport to address %s\n", 1575 dprintk("RPC: set up transport to address %s\n",
1393 xs_print_peer_address(xprt, RPC_DISPLAY_ALL)); 1576 xprt->address_strings[RPC_DISPLAY_ALL]);
1394 1577
1395 return 0; 1578 return xprt;
1396} 1579}
1397 1580
1398/** 1581/**
1399 * xs_setup_tcp - Set up transport to use a TCP socket 1582 * xs_setup_tcp - Set up transport to use a TCP socket
1400 * @xprt: transport to set up 1583 * @addr: address of remote server
1584 * @addrlen: length of address in bytes
1401 * @to: timeout parameters 1585 * @to: timeout parameters
1402 * 1586 *
1403 */ 1587 */
1404int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to) 1588struct rpc_xprt *xs_setup_tcp(struct sockaddr *addr, size_t addrlen, struct rpc_timeout *to)
1405{ 1589{
1406 size_t slot_table_size; 1590 struct rpc_xprt *xprt;
1407 struct sockaddr_in *addr = (struct sockaddr_in *) &xprt->addr; 1591 struct sock_xprt *transport;
1408 1592
1409 xprt->max_reqs = xprt_tcp_slot_table_entries; 1593 xprt = xs_setup_xprt(addr, addrlen, xprt_tcp_slot_table_entries);
1410 slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]); 1594 if (IS_ERR(xprt))
1411 xprt->slot = kzalloc(slot_table_size, GFP_KERNEL); 1595 return xprt;
1412 if (xprt->slot == NULL) 1596 transport = container_of(xprt, struct sock_xprt, xprt);
1413 return -ENOMEM;
1414 1597
1415 if (ntohs(addr->sin_port) != 0) 1598 if (ntohs(((struct sockaddr_in *)addr)->sin_port) != 0)
1416 xprt_set_bound(xprt); 1599 xprt_set_bound(xprt);
1417 xprt->port = xs_get_random_port();
1418 1600
1419 xprt->prot = IPPROTO_TCP; 1601 xprt->prot = IPPROTO_TCP;
1420 xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32); 1602 xprt->tsh_size = sizeof(rpc_fraghdr) / sizeof(u32);
1421 xprt->max_payload = RPC_MAX_FRAGMENT_SIZE; 1603 xprt->max_payload = RPC_MAX_FRAGMENT_SIZE;
1422 1604
1423 INIT_WORK(&xprt->connect_worker, xs_tcp_connect_worker, xprt); 1605 INIT_DELAYED_WORK(&transport->connect_worker, xs_tcp_connect_worker);
1424 xprt->bind_timeout = XS_BIND_TO; 1606 xprt->bind_timeout = XS_BIND_TO;
1425 xprt->connect_timeout = XS_TCP_CONN_TO; 1607 xprt->connect_timeout = XS_TCP_CONN_TO;
1426 xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO; 1608 xprt->reestablish_timeout = XS_TCP_INIT_REEST_TO;
@@ -1435,7 +1617,40 @@ int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to)
1435 1617
1436 xs_format_peer_addresses(xprt); 1618 xs_format_peer_addresses(xprt);
1437 dprintk("RPC: set up transport to address %s\n", 1619 dprintk("RPC: set up transport to address %s\n",
1438 xs_print_peer_address(xprt, RPC_DISPLAY_ALL)); 1620 xprt->address_strings[RPC_DISPLAY_ALL]);
1621
1622 return xprt;
1623}
1624
1625/**
1626 * init_socket_xprt - set up xprtsock's sysctls
1627 *
1628 */
1629int init_socket_xprt(void)
1630{
1631#ifdef RPC_DEBUG
1632 if (!sunrpc_table_header) {
1633 sunrpc_table_header = register_sysctl_table(sunrpc_table, 1);
1634#ifdef CONFIG_PROC_FS
1635 if (sunrpc_table[0].de)
1636 sunrpc_table[0].de->owner = THIS_MODULE;
1637#endif
1638 }
1639#endif
1439 1640
1440 return 0; 1641 return 0;
1441} 1642}
1643
1644/**
1645 * cleanup_socket_xprt - remove xprtsock's sysctls
1646 *
1647 */
1648void cleanup_socket_xprt(void)
1649{
1650#ifdef RPC_DEBUG
1651 if (sunrpc_table_header) {
1652 unregister_sysctl_table(sunrpc_table_header);
1653 sunrpc_table_header = NULL;
1654 }
1655#endif
1656}
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 1bb75703f3..730c5c47ed 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -774,8 +774,8 @@ int tipc_bclink_set_queue_limits(u32 limit)
774 774
775int tipc_bclink_init(void) 775int tipc_bclink_init(void)
776{ 776{
777 bcbearer = kmalloc(sizeof(*bcbearer), GFP_ATOMIC); 777 bcbearer = kzalloc(sizeof(*bcbearer), GFP_ATOMIC);
778 bclink = kmalloc(sizeof(*bclink), GFP_ATOMIC); 778 bclink = kzalloc(sizeof(*bclink), GFP_ATOMIC);
779 if (!bcbearer || !bclink) { 779 if (!bcbearer || !bclink) {
780 nomem: 780 nomem:
781 warn("Multicast link creation failed, no memory\n"); 781 warn("Multicast link creation failed, no memory\n");
@@ -786,14 +786,12 @@ int tipc_bclink_init(void)
786 return -ENOMEM; 786 return -ENOMEM;
787 } 787 }
788 788
789 memset(bcbearer, 0, sizeof(struct bcbearer));
790 INIT_LIST_HEAD(&bcbearer->bearer.cong_links); 789 INIT_LIST_HEAD(&bcbearer->bearer.cong_links);
791 bcbearer->bearer.media = &bcbearer->media; 790 bcbearer->bearer.media = &bcbearer->media;
792 bcbearer->media.send_msg = tipc_bcbearer_send; 791 bcbearer->media.send_msg = tipc_bcbearer_send;
793 sprintf(bcbearer->media.name, "tipc-multicast"); 792 sprintf(bcbearer->media.name, "tipc-multicast");
794 793
795 bcl = &bclink->link; 794 bcl = &bclink->link;
796 memset(bclink, 0, sizeof(struct bclink));
797 INIT_LIST_HEAD(&bcl->waiting_ports); 795 INIT_LIST_HEAD(&bcl->waiting_ports);
798 bcl->next_out_no = 1; 796 bcl->next_out_no = 1;
799 spin_lock_init(&bclink->node.lock); 797 spin_lock_init(&bclink->node.lock);
diff --git a/net/tipc/config.c b/net/tipc/config.c
index ed1351ed05..baf55c459c 100644
--- a/net/tipc/config.c
+++ b/net/tipc/config.c
@@ -107,7 +107,7 @@ int tipc_cfg_append_tlv(struct sk_buff *buf, int tlv_type,
107struct sk_buff *tipc_cfg_reply_unsigned_type(u16 tlv_type, u32 value) 107struct sk_buff *tipc_cfg_reply_unsigned_type(u16 tlv_type, u32 value)
108{ 108{
109 struct sk_buff *buf; 109 struct sk_buff *buf;
110 u32 value_net; 110 __be32 value_net;
111 111
112 buf = tipc_cfg_reply_alloc(TLV_SPACE(sizeof(value))); 112 buf = tipc_cfg_reply_alloc(TLV_SPACE(sizeof(value)));
113 if (buf) { 113 if (buf) {
@@ -208,7 +208,7 @@ static void cfg_cmd_event(struct tipc_cmd_msg *msg,
208 208
209 if (mng.link_subscriptions > 64) 209 if (mng.link_subscriptions > 64)
210 break; 210 break;
211 sub = (struct subscr_data *)kmalloc(sizeof(*sub), 211 sub = kmalloc(sizeof(*sub),
212 GFP_ATOMIC); 212 GFP_ATOMIC);
213 if (sub == NULL) { 213 if (sub == NULL) {
214 warn("Memory squeeze; dropped remote link subscription\n"); 214 warn("Memory squeeze; dropped remote link subscription\n");
@@ -284,8 +284,7 @@ static struct sk_buff *cfg_set_own_addr(void)
284 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR)) 284 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR))
285 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 285 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
286 286
287 addr = *(u32 *)TLV_DATA(req_tlv_area); 287 addr = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
288 addr = ntohl(addr);
289 if (addr == tipc_own_addr) 288 if (addr == tipc_own_addr)
290 return tipc_cfg_reply_none(); 289 return tipc_cfg_reply_none();
291 if (!tipc_addr_node_valid(addr)) 290 if (!tipc_addr_node_valid(addr))
@@ -319,8 +318,7 @@ static struct sk_buff *cfg_set_remote_mng(void)
319 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) 318 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
320 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 319 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
321 320
322 value = *(u32 *)TLV_DATA(req_tlv_area); 321 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
323 value = ntohl(value);
324 tipc_remote_management = (value != 0); 322 tipc_remote_management = (value != 0);
325 return tipc_cfg_reply_none(); 323 return tipc_cfg_reply_none();
326} 324}
@@ -332,8 +330,7 @@ static struct sk_buff *cfg_set_max_publications(void)
332 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) 330 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
333 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 331 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
334 332
335 value = *(u32 *)TLV_DATA(req_tlv_area); 333 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
336 value = ntohl(value);
337 if (value != delimit(value, 1, 65535)) 334 if (value != delimit(value, 1, 65535))
338 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE 335 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
339 " (max publications must be 1-65535)"); 336 " (max publications must be 1-65535)");
@@ -348,8 +345,7 @@ static struct sk_buff *cfg_set_max_subscriptions(void)
348 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) 345 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
349 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 346 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
350 347
351 value = *(u32 *)TLV_DATA(req_tlv_area); 348 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
352 value = ntohl(value);
353 if (value != delimit(value, 1, 65535)) 349 if (value != delimit(value, 1, 65535))
354 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE 350 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
355 " (max subscriptions must be 1-65535"); 351 " (max subscriptions must be 1-65535");
@@ -363,8 +359,7 @@ static struct sk_buff *cfg_set_max_ports(void)
363 359
364 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) 360 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
365 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 361 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
366 value = *(u32 *)TLV_DATA(req_tlv_area); 362 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
367 value = ntohl(value);
368 if (value == tipc_max_ports) 363 if (value == tipc_max_ports)
369 return tipc_cfg_reply_none(); 364 return tipc_cfg_reply_none();
370 if (value != delimit(value, 127, 65535)) 365 if (value != delimit(value, 127, 65535))
@@ -383,8 +378,7 @@ static struct sk_buff *cfg_set_max_zones(void)
383 378
384 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) 379 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
385 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 380 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
386 value = *(u32 *)TLV_DATA(req_tlv_area); 381 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
387 value = ntohl(value);
388 if (value == tipc_max_zones) 382 if (value == tipc_max_zones)
389 return tipc_cfg_reply_none(); 383 return tipc_cfg_reply_none();
390 if (value != delimit(value, 1, 255)) 384 if (value != delimit(value, 1, 255))
@@ -403,8 +397,7 @@ static struct sk_buff *cfg_set_max_clusters(void)
403 397
404 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) 398 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
405 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 399 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
406 value = *(u32 *)TLV_DATA(req_tlv_area); 400 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
407 value = ntohl(value);
408 if (value != delimit(value, 1, 1)) 401 if (value != delimit(value, 1, 1))
409 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE 402 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
410 " (max clusters fixed at 1)"); 403 " (max clusters fixed at 1)");
@@ -417,8 +410,7 @@ static struct sk_buff *cfg_set_max_nodes(void)
417 410
418 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) 411 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
419 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 412 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
420 value = *(u32 *)TLV_DATA(req_tlv_area); 413 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
421 value = ntohl(value);
422 if (value == tipc_max_nodes) 414 if (value == tipc_max_nodes)
423 return tipc_cfg_reply_none(); 415 return tipc_cfg_reply_none();
424 if (value != delimit(value, 8, 2047)) 416 if (value != delimit(value, 8, 2047))
@@ -437,8 +429,7 @@ static struct sk_buff *cfg_set_max_slaves(void)
437 429
438 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) 430 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
439 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 431 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
440 value = *(u32 *)TLV_DATA(req_tlv_area); 432 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
441 value = ntohl(value);
442 if (value != 0) 433 if (value != 0)
443 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED 434 return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED
444 " (max secondary nodes fixed at 0)"); 435 " (max secondary nodes fixed at 0)");
@@ -451,8 +442,7 @@ static struct sk_buff *cfg_set_netid(void)
451 442
452 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) 443 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
453 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 444 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
454 value = *(u32 *)TLV_DATA(req_tlv_area); 445 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
455 value = ntohl(value);
456 if (value == tipc_net_id) 446 if (value == tipc_net_id)
457 return tipc_cfg_reply_none(); 447 return tipc_cfg_reply_none();
458 if (value != delimit(value, 1, 9999)) 448 if (value != delimit(value, 1, 9999))
diff --git a/net/tipc/dbg.c b/net/tipc/dbg.c
index d8af4c2869..627f99b7af 100644
--- a/net/tipc/dbg.c
+++ b/net/tipc/dbg.c
@@ -393,8 +393,7 @@ struct sk_buff *tipc_log_resize(const void *req_tlv_area, int req_tlv_space)
393 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED)) 393 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_UNSIGNED))
394 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 394 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
395 395
396 value = *(u32 *)TLV_DATA(req_tlv_area); 396 value = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
397 value = ntohl(value);
398 if (value != delimit(value, 0, 32768)) 397 if (value != delimit(value, 0, 32768))
399 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE 398 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
400 " (log size must be 0-32768)"); 399 " (log size must be 0-32768)");
diff --git a/net/tipc/handler.c b/net/tipc/handler.c
index ae6ddf00a1..eb80778d6d 100644
--- a/net/tipc/handler.c
+++ b/net/tipc/handler.c
@@ -42,7 +42,7 @@ struct queue_item {
42 unsigned long data; 42 unsigned long data;
43}; 43};
44 44
45static kmem_cache_t *tipc_queue_item_cache; 45static struct kmem_cache *tipc_queue_item_cache;
46static struct list_head signal_queue_head; 46static struct list_head signal_queue_head;
47static DEFINE_SPINLOCK(qitem_lock); 47static DEFINE_SPINLOCK(qitem_lock);
48static int handler_enabled = 0; 48static int handler_enabled = 0;
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index 03bd659c43..7bf87cb26e 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -66,11 +66,11 @@
66 */ 66 */
67 67
68struct distr_item { 68struct distr_item {
69 u32 type; 69 __be32 type;
70 u32 lower; 70 __be32 lower;
71 u32 upper; 71 __be32 upper;
72 u32 ref; 72 __be32 ref;
73 u32 key; 73 __be32 key;
74}; 74};
75 75
76/** 76/**
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 886bda5e88..4111a31def 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -60,7 +60,7 @@ struct node *tipc_node_create(u32 addr)
60 struct node *n_ptr; 60 struct node *n_ptr;
61 struct node **curr_node; 61 struct node **curr_node;
62 62
63 n_ptr = kmalloc(sizeof(*n_ptr),GFP_ATOMIC); 63 n_ptr = kzalloc(sizeof(*n_ptr),GFP_ATOMIC);
64 if (!n_ptr) { 64 if (!n_ptr) {
65 warn("Node creation failed, no memory\n"); 65 warn("Node creation failed, no memory\n");
66 return NULL; 66 return NULL;
@@ -75,7 +75,6 @@ struct node *tipc_node_create(u32 addr)
75 return NULL; 75 return NULL;
76 } 76 }
77 77
78 memset(n_ptr, 0, sizeof(*n_ptr));
79 n_ptr->addr = addr; 78 n_ptr->addr = addr;
80 spin_lock_init(&n_ptr->lock); 79 spin_lock_init(&n_ptr->lock);
81 INIT_LIST_HEAD(&n_ptr->nsub); 80 INIT_LIST_HEAD(&n_ptr->nsub);
@@ -597,8 +596,7 @@ struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space)
597 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR)) 596 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR))
598 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 597 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
599 598
600 domain = *(u32 *)TLV_DATA(req_tlv_area); 599 domain = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
601 domain = ntohl(domain);
602 if (!tipc_addr_domain_valid(domain)) 600 if (!tipc_addr_domain_valid(domain))
603 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE 601 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
604 " (network address)"); 602 " (network address)");
@@ -642,8 +640,7 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
642 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR)) 640 if (!TLV_CHECK(req_tlv_area, req_tlv_space, TIPC_TLV_NET_ADDR))
643 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR); 641 return tipc_cfg_reply_error_string(TIPC_CFG_TLV_ERROR);
644 642
645 domain = *(u32 *)TLV_DATA(req_tlv_area); 643 domain = ntohl(*(__be32 *)TLV_DATA(req_tlv_area));
646 domain = ntohl(domain);
647 if (!tipc_addr_domain_valid(domain)) 644 if (!tipc_addr_domain_valid(domain))
648 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE 645 return tipc_cfg_reply_error_string(TIPC_CFG_INVALID_VALUE
649 " (network address)"); 646 " (network address)");
@@ -664,8 +661,7 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
664 661
665 /* Add TLV for broadcast link */ 662 /* Add TLV for broadcast link */
666 663
667 link_info.dest = tipc_own_addr & 0xfffff00; 664 link_info.dest = htonl(tipc_own_addr & 0xfffff00);
668 link_info.dest = htonl(link_info.dest);
669 link_info.up = htonl(1); 665 link_info.up = htonl(1);
670 sprintf(link_info.str, tipc_bclink_name); 666 sprintf(link_info.str, tipc_bclink_name);
671 tipc_cfg_append_tlv(buf, TIPC_TLV_LINK_INFO, &link_info, sizeof(link_info)); 667 tipc_cfg_append_tlv(buf, TIPC_TLV_LINK_INFO, &link_info, sizeof(link_info));
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
index 7a918f12a5..ddade7388a 100644
--- a/net/tipc/subscr.c
+++ b/net/tipc/subscr.c
@@ -350,7 +350,7 @@ static void subscr_subscribe(struct tipc_subscr *s,
350 350
351 /* Allocate subscription object */ 351 /* Allocate subscription object */
352 352
353 sub = kmalloc(sizeof(*sub), GFP_ATOMIC); 353 sub = kzalloc(sizeof(*sub), GFP_ATOMIC);
354 if (!sub) { 354 if (!sub) {
355 warn("Subscription rejected, no memory\n"); 355 warn("Subscription rejected, no memory\n");
356 subscr_terminate(subscriber); 356 subscr_terminate(subscriber);
@@ -359,7 +359,6 @@ static void subscr_subscribe(struct tipc_subscr *s,
359 359
360 /* Initialize subscription object */ 360 /* Initialize subscription object */
361 361
362 memset(sub, 0, sizeof(*sub));
363 sub->seq.type = htohl(s->seq.type, subscriber->swap); 362 sub->seq.type = htohl(s->seq.type, subscriber->swap);
364 sub->seq.lower = htohl(s->seq.lower, subscriber->swap); 363 sub->seq.lower = htohl(s->seq.lower, subscriber->swap);
365 sub->seq.upper = htohl(s->seq.upper, subscriber->swap); 364 sub->seq.upper = htohl(s->seq.upper, subscriber->swap);
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index b43a27828d..2f208c7f4d 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -151,8 +151,9 @@ static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb)
151 * each socket state is protected by separate rwlock. 151 * each socket state is protected by separate rwlock.
152 */ 152 */
153 153
154static inline unsigned unix_hash_fold(unsigned hash) 154static inline unsigned unix_hash_fold(__wsum n)
155{ 155{
156 unsigned hash = (__force unsigned)n;
156 hash ^= hash>>16; 157 hash ^= hash>>16;
157 hash ^= hash>>8; 158 hash ^= hash>>8;
158 return hash&(UNIX_HASH_SIZE-1); 159 return hash&(UNIX_HASH_SIZE-1);
diff --git a/net/unix/garbage.c b/net/unix/garbage.c
index 746c2f4a5f..f14ad6635f 100644
--- a/net/unix/garbage.c
+++ b/net/unix/garbage.c
@@ -96,7 +96,7 @@ atomic_t unix_tot_inflight = ATOMIC_INIT(0);
96static struct sock *unix_get_socket(struct file *filp) 96static struct sock *unix_get_socket(struct file *filp)
97{ 97{
98 struct sock *u_sock = NULL; 98 struct sock *u_sock = NULL;
99 struct inode *inode = filp->f_dentry->d_inode; 99 struct inode *inode = filp->f_path.dentry->d_inode;
100 100
101 /* 101 /*
102 * Socket ? 102 * Socket ?
diff --git a/net/wanrouter/af_wanpipe.c b/net/wanrouter/af_wanpipe.c
index 6f39faa158..c2059733e1 100644
--- a/net/wanrouter/af_wanpipe.c
+++ b/net/wanrouter/af_wanpipe.c
@@ -13,7 +13,7 @@
13* Due Credit: 13* Due Credit:
14* Wanpipe socket layer is based on Packet and 14* Wanpipe socket layer is based on Packet and
15* the X25 socket layers. The above sockets were 15* the X25 socket layers. The above sockets were
16* used for the specific use of Sangoma Technoloiges 16* used for the specific use of Sangoma Technologies
17* API programs. 17* API programs.
18* Packet socket Authors: Ross Biro, Fred N. van Kempen and 18* Packet socket Authors: Ross Biro, Fred N. van Kempen and
19* Alan Cox. 19* Alan Cox.
@@ -23,7 +23,7 @@
23* Apr 25, 2000 Nenad Corbic o Added the ability to send zero length packets. 23* Apr 25, 2000 Nenad Corbic o Added the ability to send zero length packets.
24* Mar 13, 2000 Nenad Corbic o Added a tx buffer check via ioctl call. 24* Mar 13, 2000 Nenad Corbic o Added a tx buffer check via ioctl call.
25* Mar 06, 2000 Nenad Corbic o Fixed the corrupt sock lcn problem. 25* Mar 06, 2000 Nenad Corbic o Fixed the corrupt sock lcn problem.
26* Server and client applicaton can run 26* Server and client application can run
27* simultaneously without conflicts. 27* simultaneously without conflicts.
28* Feb 29, 2000 Nenad Corbic o Added support for PVC protocols, such as 28* Feb 29, 2000 Nenad Corbic o Added support for PVC protocols, such as
29* CHDLC, Frame Relay and HDLC API. 29* CHDLC, Frame Relay and HDLC API.
diff --git a/net/wanrouter/wanmain.c b/net/wanrouter/wanmain.c
index 9479659277..769cdd62c1 100644
--- a/net/wanrouter/wanmain.c
+++ b/net/wanrouter/wanmain.c
@@ -3,7 +3,7 @@
3* 3*
4* This module is completely hardware-independent and provides 4* This module is completely hardware-independent and provides
5* the following common services for the WAN Link Drivers: 5* the following common services for the WAN Link Drivers:
6* o WAN device managenment (registering, unregistering) 6* o WAN device management (registering, unregistering)
7* o Network interface management 7* o Network interface management
8* o Physical connection management (dial-up, incoming calls) 8* o Physical connection management (dial-up, incoming calls)
9* o Logical connection management (switched virtual circuits) 9* o Logical connection management (switched virtual circuits)
@@ -62,63 +62,6 @@
62 62
63#define KMEM_SAFETYZONE 8 63#define KMEM_SAFETYZONE 8
64 64
65/***********FOR DEBUGGING PURPOSES*********************************************
66static void * dbg_kmalloc(unsigned int size, int prio, int line) {
67 int i = 0;
68 void * v = kmalloc(size+sizeof(unsigned int)+2*KMEM_SAFETYZONE*8,prio);
69 char * c1 = v;
70 c1 += sizeof(unsigned int);
71 *((unsigned int *)v) = size;
72
73 for (i = 0; i < KMEM_SAFETYZONE; i++) {
74 c1[0] = 'D'; c1[1] = 'E'; c1[2] = 'A'; c1[3] = 'D';
75 c1[4] = 'B'; c1[5] = 'E'; c1[6] = 'E'; c1[7] = 'F';
76 c1 += 8;
77 }
78 c1 += size;
79 for (i = 0; i < KMEM_SAFETYZONE; i++) {
80 c1[0] = 'M'; c1[1] = 'U'; c1[2] = 'N'; c1[3] = 'G';
81 c1[4] = 'W'; c1[5] = 'A'; c1[6] = 'L'; c1[7] = 'L';
82 c1 += 8;
83 }
84 v = ((char *)v) + sizeof(unsigned int) + KMEM_SAFETYZONE*8;
85 printk(KERN_INFO "line %d kmalloc(%d,%d) = %p\n",line,size,prio,v);
86 return v;
87}
88static void dbg_kfree(void * v, int line) {
89 unsigned int * sp = (unsigned int *)(((char *)v) - (sizeof(unsigned int) + KMEM_SAFETYZONE*8));
90 unsigned int size = *sp;
91 char * c1 = ((char *)v) - KMEM_SAFETYZONE*8;
92 int i = 0;
93 for (i = 0; i < KMEM_SAFETYZONE; i++) {
94 if ( c1[0] != 'D' || c1[1] != 'E' || c1[2] != 'A' || c1[3] != 'D'
95 || c1[4] != 'B' || c1[5] != 'E' || c1[6] != 'E' || c1[7] != 'F') {
96 printk(KERN_INFO "kmalloced block at %p has been corrupted (underrun)!\n",v);
97 printk(KERN_INFO " %4x: %2x %2x %2x %2x %2x %2x %2x %2x\n", i*8,
98 c1[0],c1[1],c1[2],c1[3],c1[4],c1[5],c1[6],c1[7] );
99 }
100 c1 += 8;
101 }
102 c1 += size;
103 for (i = 0; i < KMEM_SAFETYZONE; i++) {
104 if ( c1[0] != 'M' || c1[1] != 'U' || c1[2] != 'N' || c1[3] != 'G'
105 || c1[4] != 'W' || c1[5] != 'A' || c1[6] != 'L' || c1[7] != 'L'
106 ) {
107 printk(KERN_INFO "kmalloced block at %p has been corrupted (overrun):\n",v);
108 printk(KERN_INFO " %4x: %2x %2x %2x %2x %2x %2x %2x %2x\n", i*8,
109 c1[0],c1[1],c1[2],c1[3],c1[4],c1[5],c1[6],c1[7] );
110 }
111 c1 += 8;
112 }
113 printk(KERN_INFO "line %d kfree(%p)\n",line,v);
114 v = ((char *)v) - (sizeof(unsigned int) + KMEM_SAFETYZONE*8);
115 kfree(v);
116}
117
118#define kmalloc(x,y) dbg_kmalloc(x,y,__LINE__)
119#define kfree(x) dbg_kfree(x,__LINE__)
120*****************************************************************************/
121
122/* 65/*
123 * Function Prototypes 66 * Function Prototypes
124 */ 67 */
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 52a2726d32..b5c80b1899 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -484,8 +484,6 @@ out:
484 return sk; 484 return sk;
485} 485}
486 486
487void x25_init_timers(struct sock *sk);
488
489static int x25_create(struct socket *sock, int protocol) 487static int x25_create(struct socket *sock, int protocol)
490{ 488{
491 struct sock *sk; 489 struct sock *sk;
diff --git a/net/x25/x25_facilities.c b/net/x25/x25_facilities.c
index 9f42b9c9de..27f5cc7966 100644
--- a/net/x25/x25_facilities.c
+++ b/net/x25/x25_facilities.c
@@ -254,7 +254,7 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk,
254 * They want reverse charging, we won't accept it. 254 * They want reverse charging, we won't accept it.
255 */ 255 */
256 if ((theirs.reverse & 0x01 ) && (ours->reverse & 0x01)) { 256 if ((theirs.reverse & 0x01 ) && (ours->reverse & 0x01)) {
257 SOCK_DEBUG(sk, "X.25: rejecting reverse charging request"); 257 SOCK_DEBUG(sk, "X.25: rejecting reverse charging request\n");
258 return -1; 258 return -1;
259 } 259 }
260 260
@@ -262,29 +262,29 @@ int x25_negotiate_facilities(struct sk_buff *skb, struct sock *sk,
262 262
263 if (theirs.throughput) { 263 if (theirs.throughput) {
264 if (theirs.throughput < ours->throughput) { 264 if (theirs.throughput < ours->throughput) {
265 SOCK_DEBUG(sk, "X.25: throughput negotiated down"); 265 SOCK_DEBUG(sk, "X.25: throughput negotiated down\n");
266 new->throughput = theirs.throughput; 266 new->throughput = theirs.throughput;
267 } 267 }
268 } 268 }
269 269
270 if (theirs.pacsize_in && theirs.pacsize_out) { 270 if (theirs.pacsize_in && theirs.pacsize_out) {
271 if (theirs.pacsize_in < ours->pacsize_in) { 271 if (theirs.pacsize_in < ours->pacsize_in) {
272 SOCK_DEBUG(sk, "X.25: packet size inwards negotiated down"); 272 SOCK_DEBUG(sk, "X.25: packet size inwards negotiated down\n");
273 new->pacsize_in = theirs.pacsize_in; 273 new->pacsize_in = theirs.pacsize_in;
274 } 274 }
275 if (theirs.pacsize_out < ours->pacsize_out) { 275 if (theirs.pacsize_out < ours->pacsize_out) {
276 SOCK_DEBUG(sk, "X.25: packet size outwards negotiated down"); 276 SOCK_DEBUG(sk, "X.25: packet size outwards negotiated down\n");
277 new->pacsize_out = theirs.pacsize_out; 277 new->pacsize_out = theirs.pacsize_out;
278 } 278 }
279 } 279 }
280 280
281 if (theirs.winsize_in && theirs.winsize_out) { 281 if (theirs.winsize_in && theirs.winsize_out) {
282 if (theirs.winsize_in < ours->winsize_in) { 282 if (theirs.winsize_in < ours->winsize_in) {
283 SOCK_DEBUG(sk, "X.25: window size inwards negotiated down"); 283 SOCK_DEBUG(sk, "X.25: window size inwards negotiated down\n");
284 new->winsize_in = theirs.winsize_in; 284 new->winsize_in = theirs.winsize_in;
285 } 285 }
286 if (theirs.winsize_out < ours->winsize_out) { 286 if (theirs.winsize_out < ours->winsize_out) {
287 SOCK_DEBUG(sk, "X.25: window size outwards negotiated down"); 287 SOCK_DEBUG(sk, "X.25: window size outwards negotiated down\n");
288 new->winsize_out = theirs.winsize_out; 288 new->winsize_out = theirs.winsize_out;
289 } 289 }
290 } 290 }
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
index 5a0dbeb6bb..f1cf3402e7 100644
--- a/net/xfrm/xfrm_algo.c
+++ b/net/xfrm/xfrm_algo.c
@@ -119,6 +119,23 @@ static struct xfrm_algo_desc aalg_list[] = {
119 .sadb_alg_maxbits = 160 119 .sadb_alg_maxbits = 160
120 } 120 }
121}, 121},
122{
123 .name = "xcbc(aes)",
124
125 .uinfo = {
126 .auth = {
127 .icv_truncbits = 96,
128 .icv_fullbits = 128,
129 }
130 },
131
132 .desc = {
133 .sadb_alg_id = SADB_X_AALG_AES_XCBC_MAC,
134 .sadb_alg_ivlen = 0,
135 .sadb_alg_minbits = 128,
136 .sadb_alg_maxbits = 128
137 }
138},
122}; 139};
123 140
124static struct xfrm_algo_desc ealg_list[] = { 141static struct xfrm_algo_desc ealg_list[] = {
@@ -382,7 +399,8 @@ static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list,
382 if (!probe) 399 if (!probe)
383 break; 400 break;
384 401
385 status = crypto_has_alg(name, type, mask | CRYPTO_ALG_ASYNC); 402 status = crypto_has_alg(list[i].name, type,
403 mask | CRYPTO_ALG_ASYNC);
386 if (!status) 404 if (!status)
387 break; 405 break;
388 406
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index e8198a2c78..414f890703 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -12,7 +12,7 @@
12#include <net/ip.h> 12#include <net/ip.h>
13#include <net/xfrm.h> 13#include <net/xfrm.h>
14 14
15static kmem_cache_t *secpath_cachep __read_mostly; 15static struct kmem_cache *secpath_cachep __read_mostly;
16 16
17void __secpath_destroy(struct sec_path *sp) 17void __secpath_destroy(struct sec_path *sp)
18{ 18{
@@ -27,7 +27,7 @@ struct sec_path *secpath_dup(struct sec_path *src)
27{ 27{
28 struct sec_path *sp; 28 struct sec_path *sp;
29 29
30 sp = kmem_cache_alloc(secpath_cachep, SLAB_ATOMIC); 30 sp = kmem_cache_alloc(secpath_cachep, GFP_ATOMIC);
31 if (!sp) 31 if (!sp)
32 return NULL; 32 return NULL;
33 33
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 7736b23c3f..bebd40e5a6 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -25,6 +25,7 @@
25#include <linux/cache.h> 25#include <linux/cache.h>
26#include <net/xfrm.h> 26#include <net/xfrm.h>
27#include <net/ip.h> 27#include <net/ip.h>
28#include <linux/audit.h>
28 29
29#include "xfrm_hash.h" 30#include "xfrm_hash.h"
30 31
@@ -39,7 +40,7 @@ EXPORT_SYMBOL(xfrm_policy_count);
39static DEFINE_RWLOCK(xfrm_policy_afinfo_lock); 40static DEFINE_RWLOCK(xfrm_policy_afinfo_lock);
40static struct xfrm_policy_afinfo *xfrm_policy_afinfo[NPROTO]; 41static struct xfrm_policy_afinfo *xfrm_policy_afinfo[NPROTO];
41 42
42static kmem_cache_t *xfrm_dst_cache __read_mostly; 43static struct kmem_cache *xfrm_dst_cache __read_mostly;
43 44
44static struct work_struct xfrm_policy_gc_work; 45static struct work_struct xfrm_policy_gc_work;
45static HLIST_HEAD(xfrm_policy_gc_list); 46static HLIST_HEAD(xfrm_policy_gc_list);
@@ -50,6 +51,40 @@ static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo);
50static struct xfrm_policy_afinfo *xfrm_policy_lock_afinfo(unsigned int family); 51static struct xfrm_policy_afinfo *xfrm_policy_lock_afinfo(unsigned int family);
51static void xfrm_policy_unlock_afinfo(struct xfrm_policy_afinfo *afinfo); 52static void xfrm_policy_unlock_afinfo(struct xfrm_policy_afinfo *afinfo);
52 53
54static inline int
55__xfrm4_selector_match(struct xfrm_selector *sel, struct flowi *fl)
56{
57 return addr_match(&fl->fl4_dst, &sel->daddr, sel->prefixlen_d) &&
58 addr_match(&fl->fl4_src, &sel->saddr, sel->prefixlen_s) &&
59 !((xfrm_flowi_dport(fl) ^ sel->dport) & sel->dport_mask) &&
60 !((xfrm_flowi_sport(fl) ^ sel->sport) & sel->sport_mask) &&
61 (fl->proto == sel->proto || !sel->proto) &&
62 (fl->oif == sel->ifindex || !sel->ifindex);
63}
64
65static inline int
66__xfrm6_selector_match(struct xfrm_selector *sel, struct flowi *fl)
67{
68 return addr_match(&fl->fl6_dst, &sel->daddr, sel->prefixlen_d) &&
69 addr_match(&fl->fl6_src, &sel->saddr, sel->prefixlen_s) &&
70 !((xfrm_flowi_dport(fl) ^ sel->dport) & sel->dport_mask) &&
71 !((xfrm_flowi_sport(fl) ^ sel->sport) & sel->sport_mask) &&
72 (fl->proto == sel->proto || !sel->proto) &&
73 (fl->oif == sel->ifindex || !sel->ifindex);
74}
75
76int xfrm_selector_match(struct xfrm_selector *sel, struct flowi *fl,
77 unsigned short family)
78{
79 switch (family) {
80 case AF_INET:
81 return __xfrm4_selector_match(sel, fl);
82 case AF_INET6:
83 return __xfrm6_selector_match(sel, fl);
84 }
85 return 0;
86}
87
53int xfrm_register_type(struct xfrm_type *type, unsigned short family) 88int xfrm_register_type(struct xfrm_type *type, unsigned short family)
54{ 89{
55 struct xfrm_policy_afinfo *afinfo = xfrm_policy_lock_afinfo(family); 90 struct xfrm_policy_afinfo *afinfo = xfrm_policy_lock_afinfo(family);
@@ -358,7 +393,7 @@ static void xfrm_policy_gc_kill(struct xfrm_policy *policy)
358 xfrm_pol_put(policy); 393 xfrm_pol_put(policy);
359} 394}
360 395
361static void xfrm_policy_gc_task(void *data) 396static void xfrm_policy_gc_task(struct work_struct *work)
362{ 397{
363 struct xfrm_policy *policy; 398 struct xfrm_policy *policy;
364 struct hlist_node *entry, *tmp; 399 struct hlist_node *entry, *tmp;
@@ -546,7 +581,7 @@ static inline int xfrm_byidx_should_resize(int total)
546 581
547static DEFINE_MUTEX(hash_resize_mutex); 582static DEFINE_MUTEX(hash_resize_mutex);
548 583
549static void xfrm_hash_resize(void *__unused) 584static void xfrm_hash_resize(struct work_struct *__unused)
550{ 585{
551 int dir, total; 586 int dir, total;
552 587
@@ -563,7 +598,7 @@ static void xfrm_hash_resize(void *__unused)
563 mutex_unlock(&hash_resize_mutex); 598 mutex_unlock(&hash_resize_mutex);
564} 599}
565 600
566static DECLARE_WORK(xfrm_hash_work, xfrm_hash_resize, NULL); 601static DECLARE_WORK(xfrm_hash_work, xfrm_hash_resize);
567 602
568/* Generate new index... KAME seems to generate them ordered by cost 603/* Generate new index... KAME seems to generate them ordered by cost
569 * of an absolute inpredictability of ordering of rules. This will not pass. */ 604 * of an absolute inpredictability of ordering of rules. This will not pass. */
@@ -770,7 +805,7 @@ struct xfrm_policy *xfrm_policy_byid(u8 type, int dir, u32 id, int delete)
770} 805}
771EXPORT_SYMBOL(xfrm_policy_byid); 806EXPORT_SYMBOL(xfrm_policy_byid);
772 807
773void xfrm_policy_flush(u8 type) 808void xfrm_policy_flush(u8 type, struct xfrm_audit *audit_info)
774{ 809{
775 int dir; 810 int dir;
776 811
@@ -790,6 +825,9 @@ void xfrm_policy_flush(u8 type)
790 hlist_del(&pol->byidx); 825 hlist_del(&pol->byidx);
791 write_unlock_bh(&xfrm_policy_lock); 826 write_unlock_bh(&xfrm_policy_lock);
792 827
828 xfrm_audit_log(audit_info->loginuid, audit_info->secid,
829 AUDIT_MAC_IPSEC_DELSPD, 1, pol, NULL);
830
793 xfrm_policy_kill(pol); 831 xfrm_policy_kill(pol);
794 killed++; 832 killed++;
795 833
@@ -808,6 +846,11 @@ void xfrm_policy_flush(u8 type)
808 hlist_del(&pol->byidx); 846 hlist_del(&pol->byidx);
809 write_unlock_bh(&xfrm_policy_lock); 847 write_unlock_bh(&xfrm_policy_lock);
810 848
849 xfrm_audit_log(audit_info->loginuid,
850 audit_info->secid,
851 AUDIT_MAC_IPSEC_DELSPD, 1,
852 pol, NULL);
853
811 xfrm_policy_kill(pol); 854 xfrm_policy_kill(pol);
812 killed++; 855 killed++;
813 856
@@ -826,33 +869,12 @@ EXPORT_SYMBOL(xfrm_policy_flush);
826int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int, void*), 869int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int, void*),
827 void *data) 870 void *data)
828{ 871{
829 struct xfrm_policy *pol; 872 struct xfrm_policy *pol, *last = NULL;
830 struct hlist_node *entry; 873 struct hlist_node *entry;
831 int dir, count, error; 874 int dir, last_dir = 0, count, error;
832 875
833 read_lock_bh(&xfrm_policy_lock); 876 read_lock_bh(&xfrm_policy_lock);
834 count = 0; 877 count = 0;
835 for (dir = 0; dir < 2*XFRM_POLICY_MAX; dir++) {
836 struct hlist_head *table = xfrm_policy_bydst[dir].table;
837 int i;
838
839 hlist_for_each_entry(pol, entry,
840 &xfrm_policy_inexact[dir], bydst) {
841 if (pol->type == type)
842 count++;
843 }
844 for (i = xfrm_policy_bydst[dir].hmask; i >= 0; i--) {
845 hlist_for_each_entry(pol, entry, table + i, bydst) {
846 if (pol->type == type)
847 count++;
848 }
849 }
850 }
851
852 if (count == 0) {
853 error = -ENOENT;
854 goto out;
855 }
856 878
857 for (dir = 0; dir < 2*XFRM_POLICY_MAX; dir++) { 879 for (dir = 0; dir < 2*XFRM_POLICY_MAX; dir++) {
858 struct hlist_head *table = xfrm_policy_bydst[dir].table; 880 struct hlist_head *table = xfrm_policy_bydst[dir].table;
@@ -862,21 +884,37 @@ int xfrm_policy_walk(u8 type, int (*func)(struct xfrm_policy *, int, int, void*)
862 &xfrm_policy_inexact[dir], bydst) { 884 &xfrm_policy_inexact[dir], bydst) {
863 if (pol->type != type) 885 if (pol->type != type)
864 continue; 886 continue;
865 error = func(pol, dir % XFRM_POLICY_MAX, --count, data); 887 if (last) {
866 if (error) 888 error = func(last, last_dir % XFRM_POLICY_MAX,
867 goto out; 889 count, data);
890 if (error)
891 goto out;
892 }
893 last = pol;
894 last_dir = dir;
895 count++;
868 } 896 }
869 for (i = xfrm_policy_bydst[dir].hmask; i >= 0; i--) { 897 for (i = xfrm_policy_bydst[dir].hmask; i >= 0; i--) {
870 hlist_for_each_entry(pol, entry, table + i, bydst) { 898 hlist_for_each_entry(pol, entry, table + i, bydst) {
871 if (pol->type != type) 899 if (pol->type != type)
872 continue; 900 continue;
873 error = func(pol, dir % XFRM_POLICY_MAX, --count, data); 901 if (last) {
874 if (error) 902 error = func(last, last_dir % XFRM_POLICY_MAX,
875 goto out; 903 count, data);
904 if (error)
905 goto out;
906 }
907 last = pol;
908 last_dir = dir;
909 count++;
876 } 910 }
877 } 911 }
878 } 912 }
879 error = 0; 913 if (count == 0) {
914 error = -ENOENT;
915 goto out;
916 }
917 error = func(last, last_dir % XFRM_POLICY_MAX, 0, data);
880out: 918out:
881 read_unlock_bh(&xfrm_policy_lock); 919 read_unlock_bh(&xfrm_policy_lock);
882 return error; 920 return error;
@@ -1177,6 +1215,7 @@ xfrm_tmpl_resolve_one(struct xfrm_policy *policy, struct flowi *fl,
1177 if (tmpl->mode == XFRM_MODE_TUNNEL) { 1215 if (tmpl->mode == XFRM_MODE_TUNNEL) {
1178 remote = &tmpl->id.daddr; 1216 remote = &tmpl->id.daddr;
1179 local = &tmpl->saddr; 1217 local = &tmpl->saddr;
1218 family = tmpl->encap_family;
1180 if (xfrm_addr_any(local, family)) { 1219 if (xfrm_addr_any(local, family)) {
1181 error = xfrm_get_saddr(&tmp, remote, family); 1220 error = xfrm_get_saddr(&tmp, remote, family);
1182 if (error) 1221 if (error)
@@ -1894,7 +1933,8 @@ int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first,
1894 1933
1895 if (fl && !xfrm_selector_match(&dst->xfrm->sel, fl, family)) 1934 if (fl && !xfrm_selector_match(&dst->xfrm->sel, fl, family))
1896 return 0; 1935 return 0;
1897 if (fl && !security_xfrm_flow_state_match(fl, dst->xfrm, pol)) 1936 if (fl && pol &&
1937 !security_xfrm_state_pol_flow_match(dst->xfrm, pol, fl))
1898 return 0; 1938 return 0;
1899 if (dst->xfrm->km.state != XFRM_STATE_VALID) 1939 if (dst->xfrm->km.state != XFRM_STATE_VALID)
1900 return 0; 1940 return 0;
@@ -1946,6 +1986,117 @@ int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *first,
1946 1986
1947EXPORT_SYMBOL(xfrm_bundle_ok); 1987EXPORT_SYMBOL(xfrm_bundle_ok);
1948 1988
1989#ifdef CONFIG_AUDITSYSCALL
1990/* Audit addition and deletion of SAs and ipsec policy */
1991
1992void xfrm_audit_log(uid_t auid, u32 sid, int type, int result,
1993 struct xfrm_policy *xp, struct xfrm_state *x)
1994{
1995
1996 char *secctx;
1997 u32 secctx_len;
1998 struct xfrm_sec_ctx *sctx = NULL;
1999 struct audit_buffer *audit_buf;
2000 int family;
2001 extern int audit_enabled;
2002
2003 if (audit_enabled == 0)
2004 return;
2005
2006 audit_buf = audit_log_start(current->audit_context, GFP_ATOMIC, type);
2007 if (audit_buf == NULL)
2008 return;
2009
2010 switch(type) {
2011 case AUDIT_MAC_IPSEC_ADDSA:
2012 audit_log_format(audit_buf, "SAD add: auid=%u", auid);
2013 break;
2014 case AUDIT_MAC_IPSEC_DELSA:
2015 audit_log_format(audit_buf, "SAD delete: auid=%u", auid);
2016 break;
2017 case AUDIT_MAC_IPSEC_ADDSPD:
2018 audit_log_format(audit_buf, "SPD add: auid=%u", auid);
2019 break;
2020 case AUDIT_MAC_IPSEC_DELSPD:
2021 audit_log_format(audit_buf, "SPD delete: auid=%u", auid);
2022 break;
2023 default:
2024 return;
2025 }
2026
2027 if (sid != 0 &&
2028 security_secid_to_secctx(sid, &secctx, &secctx_len) == 0)
2029 audit_log_format(audit_buf, " subj=%s", secctx);
2030 else
2031 audit_log_task_context(audit_buf);
2032
2033 if (xp) {
2034 family = xp->selector.family;
2035 if (xp->security)
2036 sctx = xp->security;
2037 } else {
2038 family = x->props.family;
2039 if (x->security)
2040 sctx = x->security;
2041 }
2042
2043 if (sctx)
2044 audit_log_format(audit_buf,
2045 " sec_alg=%u sec_doi=%u sec_obj=%s",
2046 sctx->ctx_alg, sctx->ctx_doi, sctx->ctx_str);
2047
2048 switch(family) {
2049 case AF_INET:
2050 {
2051 struct in_addr saddr, daddr;
2052 if (xp) {
2053 saddr.s_addr = xp->selector.saddr.a4;
2054 daddr.s_addr = xp->selector.daddr.a4;
2055 } else {
2056 saddr.s_addr = x->props.saddr.a4;
2057 daddr.s_addr = x->id.daddr.a4;
2058 }
2059 audit_log_format(audit_buf,
2060 " src=%u.%u.%u.%u dst=%u.%u.%u.%u",
2061 NIPQUAD(saddr), NIPQUAD(daddr));
2062 }
2063 break;
2064 case AF_INET6:
2065 {
2066 struct in6_addr saddr6, daddr6;
2067 if (xp) {
2068 memcpy(&saddr6, xp->selector.saddr.a6,
2069 sizeof(struct in6_addr));
2070 memcpy(&daddr6, xp->selector.daddr.a6,
2071 sizeof(struct in6_addr));
2072 } else {
2073 memcpy(&saddr6, x->props.saddr.a6,
2074 sizeof(struct in6_addr));
2075 memcpy(&daddr6, x->id.daddr.a6,
2076 sizeof(struct in6_addr));
2077 }
2078 audit_log_format(audit_buf,
2079 " src=" NIP6_FMT "dst=" NIP6_FMT,
2080 NIP6(saddr6), NIP6(daddr6));
2081 }
2082 break;
2083 }
2084
2085 if (x)
2086 audit_log_format(audit_buf, " spi=%lu(0x%lx) protocol=%s",
2087 (unsigned long)ntohl(x->id.spi),
2088 (unsigned long)ntohl(x->id.spi),
2089 x->id.proto == IPPROTO_AH ? "AH" :
2090 (x->id.proto == IPPROTO_ESP ?
2091 "ESP" : "IPCOMP"));
2092
2093 audit_log_format(audit_buf, " res=%u", result);
2094 audit_log_end(audit_buf);
2095}
2096
2097EXPORT_SYMBOL(xfrm_audit_log);
2098#endif /* CONFIG_AUDITSYSCALL */
2099
1949int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo) 2100int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
1950{ 2101{
1951 int err = 0; 2102 int err = 0;
@@ -2080,7 +2231,7 @@ static void __init xfrm_policy_init(void)
2080 panic("XFRM: failed to allocate bydst hash\n"); 2231 panic("XFRM: failed to allocate bydst hash\n");
2081 } 2232 }
2082 2233
2083 INIT_WORK(&xfrm_policy_gc_work, xfrm_policy_gc_task, NULL); 2234 INIT_WORK(&xfrm_policy_gc_work, xfrm_policy_gc_task);
2084 register_netdevice_notifier(&xfrm_dev_notifier); 2235 register_netdevice_notifier(&xfrm_dev_notifier);
2085} 2236}
2086 2237
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 899de9ed22..fdb08d9f34 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -20,6 +20,7 @@
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/cache.h> 21#include <linux/cache.h>
22#include <asm/uaccess.h> 22#include <asm/uaccess.h>
23#include <linux/audit.h>
23 24
24#include "xfrm_hash.h" 25#include "xfrm_hash.h"
25 26
@@ -115,7 +116,7 @@ static unsigned long xfrm_hash_new_size(void)
115 116
116static DEFINE_MUTEX(hash_resize_mutex); 117static DEFINE_MUTEX(hash_resize_mutex);
117 118
118static void xfrm_hash_resize(void *__unused) 119static void xfrm_hash_resize(struct work_struct *__unused)
119{ 120{
120 struct hlist_head *ndst, *nsrc, *nspi, *odst, *osrc, *ospi; 121 struct hlist_head *ndst, *nsrc, *nspi, *odst, *osrc, *ospi;
121 unsigned long nsize, osize; 122 unsigned long nsize, osize;
@@ -168,7 +169,7 @@ out_unlock:
168 mutex_unlock(&hash_resize_mutex); 169 mutex_unlock(&hash_resize_mutex);
169} 170}
170 171
171static DECLARE_WORK(xfrm_hash_work, xfrm_hash_resize, NULL); 172static DECLARE_WORK(xfrm_hash_work, xfrm_hash_resize);
172 173
173DECLARE_WAIT_QUEUE_HEAD(km_waitq); 174DECLARE_WAIT_QUEUE_HEAD(km_waitq);
174EXPORT_SYMBOL(km_waitq); 175EXPORT_SYMBOL(km_waitq);
@@ -207,7 +208,7 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x)
207 kfree(x); 208 kfree(x);
208} 209}
209 210
210static void xfrm_state_gc_task(void *data) 211static void xfrm_state_gc_task(struct work_struct *data)
211{ 212{
212 struct xfrm_state *x; 213 struct xfrm_state *x;
213 struct hlist_node *entry, *tmp; 214 struct hlist_node *entry, *tmp;
@@ -238,6 +239,7 @@ static void xfrm_timer_handler(unsigned long data)
238 unsigned long now = (unsigned long)xtime.tv_sec; 239 unsigned long now = (unsigned long)xtime.tv_sec;
239 long next = LONG_MAX; 240 long next = LONG_MAX;
240 int warn = 0; 241 int warn = 0;
242 int err = 0;
241 243
242 spin_lock(&x->lock); 244 spin_lock(&x->lock);
243 if (x->km.state == XFRM_STATE_DEAD) 245 if (x->km.state == XFRM_STATE_DEAD)
@@ -295,9 +297,14 @@ expired:
295 next = 2; 297 next = 2;
296 goto resched; 298 goto resched;
297 } 299 }
298 if (!__xfrm_state_delete(x) && x->id.spi) 300
301 err = __xfrm_state_delete(x);
302 if (!err && x->id.spi)
299 km_state_expired(x, 1, 0); 303 km_state_expired(x, 1, 0);
300 304
305 xfrm_audit_log(audit_get_loginuid(current->audit_context), 0,
306 AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x);
307
301out: 308out:
302 spin_unlock(&x->lock); 309 spin_unlock(&x->lock);
303} 310}
@@ -384,9 +391,10 @@ int xfrm_state_delete(struct xfrm_state *x)
384} 391}
385EXPORT_SYMBOL(xfrm_state_delete); 392EXPORT_SYMBOL(xfrm_state_delete);
386 393
387void xfrm_state_flush(u8 proto) 394void xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info)
388{ 395{
389 int i; 396 int i;
397 int err = 0;
390 398
391 spin_lock_bh(&xfrm_state_lock); 399 spin_lock_bh(&xfrm_state_lock);
392 for (i = 0; i <= xfrm_state_hmask; i++) { 400 for (i = 0; i <= xfrm_state_hmask; i++) {
@@ -399,7 +407,11 @@ restart:
399 xfrm_state_hold(x); 407 xfrm_state_hold(x);
400 spin_unlock_bh(&xfrm_state_lock); 408 spin_unlock_bh(&xfrm_state_lock);
401 409
402 xfrm_state_delete(x); 410 err = xfrm_state_delete(x);
411 xfrm_audit_log(audit_info->loginuid,
412 audit_info->secid,
413 AUDIT_MAC_IPSEC_DELSA,
414 err ? 0 : 1, NULL, x);
403 xfrm_state_put(x); 415 xfrm_state_put(x);
404 416
405 spin_lock_bh(&xfrm_state_lock); 417 spin_lock_bh(&xfrm_state_lock);
@@ -1099,7 +1111,7 @@ int xfrm_state_walk(u8 proto, int (*func)(struct xfrm_state *, int, void*),
1099 void *data) 1111 void *data)
1100{ 1112{
1101 int i; 1113 int i;
1102 struct xfrm_state *x; 1114 struct xfrm_state *x, *last = NULL;
1103 struct hlist_node *entry; 1115 struct hlist_node *entry;
1104 int count = 0; 1116 int count = 0;
1105 int err = 0; 1117 int err = 0;
@@ -1107,24 +1119,22 @@ int xfrm_state_walk(u8 proto, int (*func)(struct xfrm_state *, int, void*),
1107 spin_lock_bh(&xfrm_state_lock); 1119 spin_lock_bh(&xfrm_state_lock);
1108 for (i = 0; i <= xfrm_state_hmask; i++) { 1120 for (i = 0; i <= xfrm_state_hmask; i++) {
1109 hlist_for_each_entry(x, entry, xfrm_state_bydst+i, bydst) { 1121 hlist_for_each_entry(x, entry, xfrm_state_bydst+i, bydst) {
1110 if (xfrm_id_proto_match(x->id.proto, proto)) 1122 if (!xfrm_id_proto_match(x->id.proto, proto))
1111 count++; 1123 continue;
1124 if (last) {
1125 err = func(last, count, data);
1126 if (err)
1127 goto out;
1128 }
1129 last = x;
1130 count++;
1112 } 1131 }
1113 } 1132 }
1114 if (count == 0) { 1133 if (count == 0) {
1115 err = -ENOENT; 1134 err = -ENOENT;
1116 goto out; 1135 goto out;
1117 } 1136 }
1118 1137 err = func(last, 0, data);
1119 for (i = 0; i <= xfrm_state_hmask; i++) {
1120 hlist_for_each_entry(x, entry, xfrm_state_bydst+i, bydst) {
1121 if (!xfrm_id_proto_match(x->id.proto, proto))
1122 continue;
1123 err = func(x, --count, data);
1124 if (err)
1125 goto out;
1126 }
1127 }
1128out: 1138out:
1129 spin_unlock_bh(&xfrm_state_lock); 1139 spin_unlock_bh(&xfrm_state_lock);
1130 return err; 1140 return err;
@@ -1304,7 +1314,7 @@ int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol)
1304} 1314}
1305EXPORT_SYMBOL(km_query); 1315EXPORT_SYMBOL(km_query);
1306 1316
1307int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport) 1317int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport)
1308{ 1318{
1309 int err = -EINVAL; 1319 int err = -EINVAL;
1310 struct xfrm_mgr *km; 1320 struct xfrm_mgr *km;
@@ -1568,6 +1578,6 @@ void __init xfrm_state_init(void)
1568 panic("XFRM: Cannot allocate bydst/bysrc/byspi hashes."); 1578 panic("XFRM: Cannot allocate bydst/bysrc/byspi hashes.");
1569 xfrm_state_hmask = ((sz / sizeof(struct hlist_head)) - 1); 1579 xfrm_state_hmask = ((sz / sizeof(struct hlist_head)) - 1);
1570 1580
1571 INIT_WORK(&xfrm_state_gc_work, xfrm_state_gc_task, NULL); 1581 INIT_WORK(&xfrm_state_gc_work, xfrm_state_gc_task);
1572} 1582}
1573 1583
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 2ee14f8a19..82f36d396f 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -31,6 +31,7 @@
31#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 31#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
32#include <linux/in6.h> 32#include <linux/in6.h>
33#endif 33#endif
34#include <linux/audit.h>
34 35
35static int verify_one_alg(struct rtattr **xfrma, enum xfrm_attr_type_t type) 36static int verify_one_alg(struct rtattr **xfrma, enum xfrm_attr_type_t type)
36{ 37{
@@ -244,11 +245,10 @@ static int attach_one_algo(struct xfrm_algo **algpp, u8 *props,
244 *props = algo->desc.sadb_alg_id; 245 *props = algo->desc.sadb_alg_id;
245 246
246 len = sizeof(*ualg) + (ualg->alg_key_len + 7U) / 8; 247 len = sizeof(*ualg) + (ualg->alg_key_len + 7U) / 8;
247 p = kmalloc(len, GFP_KERNEL); 248 p = kmemdup(ualg, len, GFP_KERNEL);
248 if (!p) 249 if (!p)
249 return -ENOMEM; 250 return -ENOMEM;
250 251
251 memcpy(p, ualg, len);
252 strcpy(p->alg_name, algo->name); 252 strcpy(p->alg_name, algo->name);
253 *algpp = p; 253 *algpp = p;
254 return 0; 254 return 0;
@@ -263,11 +263,10 @@ static int attach_encap_tmpl(struct xfrm_encap_tmpl **encapp, struct rtattr *u_a
263 return 0; 263 return 0;
264 264
265 uencap = RTA_DATA(rta); 265 uencap = RTA_DATA(rta);
266 p = kmalloc(sizeof(*p), GFP_KERNEL); 266 p = kmemdup(uencap, sizeof(*p), GFP_KERNEL);
267 if (!p) 267 if (!p)
268 return -ENOMEM; 268 return -ENOMEM;
269 269
270 memcpy(p, uencap, sizeof(*p));
271 *encapp = p; 270 *encapp = p;
272 return 0; 271 return 0;
273} 272}
@@ -305,11 +304,10 @@ static int attach_one_addr(xfrm_address_t **addrpp, struct rtattr *u_arg)
305 return 0; 304 return 0;
306 305
307 uaddrp = RTA_DATA(rta); 306 uaddrp = RTA_DATA(rta);
308 p = kmalloc(sizeof(*p), GFP_KERNEL); 307 p = kmemdup(uaddrp, sizeof(*p), GFP_KERNEL);
309 if (!p) 308 if (!p)
310 return -ENOMEM; 309 return -ENOMEM;
311 310
312 memcpy(p, uaddrp, sizeof(*p));
313 *addrpp = p; 311 *addrpp = p;
314 return 0; 312 return 0;
315} 313}
@@ -436,18 +434,19 @@ error_no_put:
436 return NULL; 434 return NULL;
437} 435}
438 436
439static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) 437static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
438 struct rtattr **xfrma)
440{ 439{
441 struct xfrm_usersa_info *p = NLMSG_DATA(nlh); 440 struct xfrm_usersa_info *p = NLMSG_DATA(nlh);
442 struct xfrm_state *x; 441 struct xfrm_state *x;
443 int err; 442 int err;
444 struct km_event c; 443 struct km_event c;
445 444
446 err = verify_newsa_info(p, (struct rtattr **)xfrma); 445 err = verify_newsa_info(p, xfrma);
447 if (err) 446 if (err)
448 return err; 447 return err;
449 448
450 x = xfrm_state_construct(p, (struct rtattr **)xfrma, &err); 449 x = xfrm_state_construct(p, xfrma, &err);
451 if (!x) 450 if (!x)
452 return err; 451 return err;
453 452
@@ -457,6 +456,9 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
457 else 456 else
458 err = xfrm_state_update(x); 457 err = xfrm_state_update(x);
459 458
459 xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
460 AUDIT_MAC_IPSEC_ADDSA, err ? 0 : 1, NULL, x);
461
460 if (err < 0) { 462 if (err < 0) {
461 x->km.state = XFRM_STATE_DEAD; 463 x->km.state = XFRM_STATE_DEAD;
462 __xfrm_state_put(x); 464 __xfrm_state_put(x);
@@ -506,14 +508,15 @@ static struct xfrm_state *xfrm_user_state_lookup(struct xfrm_usersa_id *p,
506 return x; 508 return x;
507} 509}
508 510
509static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) 511static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
512 struct rtattr **xfrma)
510{ 513{
511 struct xfrm_state *x; 514 struct xfrm_state *x;
512 int err = -ESRCH; 515 int err = -ESRCH;
513 struct km_event c; 516 struct km_event c;
514 struct xfrm_usersa_id *p = NLMSG_DATA(nlh); 517 struct xfrm_usersa_id *p = NLMSG_DATA(nlh);
515 518
516 x = xfrm_user_state_lookup(p, (struct rtattr **)xfrma, &err); 519 x = xfrm_user_state_lookup(p, xfrma, &err);
517 if (x == NULL) 520 if (x == NULL)
518 return err; 521 return err;
519 522
@@ -526,6 +529,10 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
526 } 529 }
527 530
528 err = xfrm_state_delete(x); 531 err = xfrm_state_delete(x);
532
533 xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
534 AUDIT_MAC_IPSEC_DELSA, err ? 0 : 1, NULL, x);
535
529 if (err < 0) 536 if (err < 0)
530 goto out; 537 goto out;
531 538
@@ -653,7 +660,6 @@ static struct sk_buff *xfrm_state_netlink(struct sk_buff *in_skb,
653 if (!skb) 660 if (!skb)
654 return ERR_PTR(-ENOMEM); 661 return ERR_PTR(-ENOMEM);
655 662
656 NETLINK_CB(skb).dst_pid = NETLINK_CB(in_skb).pid;
657 info.in_skb = in_skb; 663 info.in_skb = in_skb;
658 info.out_skb = skb; 664 info.out_skb = skb;
659 info.nlmsg_seq = seq; 665 info.nlmsg_seq = seq;
@@ -668,14 +674,15 @@ static struct sk_buff *xfrm_state_netlink(struct sk_buff *in_skb,
668 return skb; 674 return skb;
669} 675}
670 676
671static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) 677static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
678 struct rtattr **xfrma)
672{ 679{
673 struct xfrm_usersa_id *p = NLMSG_DATA(nlh); 680 struct xfrm_usersa_id *p = NLMSG_DATA(nlh);
674 struct xfrm_state *x; 681 struct xfrm_state *x;
675 struct sk_buff *resp_skb; 682 struct sk_buff *resp_skb;
676 int err = -ESRCH; 683 int err = -ESRCH;
677 684
678 x = xfrm_user_state_lookup(p, (struct rtattr **)xfrma, &err); 685 x = xfrm_user_state_lookup(p, xfrma, &err);
679 if (x == NULL) 686 if (x == NULL)
680 goto out_noput; 687 goto out_noput;
681 688
@@ -714,7 +721,8 @@ static int verify_userspi_info(struct xfrm_userspi_info *p)
714 return 0; 721 return 0;
715} 722}
716 723
717static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) 724static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
725 struct rtattr **xfrma)
718{ 726{
719 struct xfrm_state *x; 727 struct xfrm_state *x;
720 struct xfrm_userspi_info *p; 728 struct xfrm_userspi_info *p;
@@ -773,7 +781,7 @@ out_noput:
773 return err; 781 return err;
774} 782}
775 783
776static int verify_policy_dir(__u8 dir) 784static int verify_policy_dir(u8 dir)
777{ 785{
778 switch (dir) { 786 switch (dir) {
779 case XFRM_POLICY_IN: 787 case XFRM_POLICY_IN:
@@ -788,7 +796,7 @@ static int verify_policy_dir(__u8 dir)
788 return 0; 796 return 0;
789} 797}
790 798
791static int verify_policy_type(__u8 type) 799static int verify_policy_type(u8 type)
792{ 800{
793 switch (type) { 801 switch (type) {
794 case XFRM_POLICY_TYPE_MAIN: 802 case XFRM_POLICY_TYPE_MAIN:
@@ -875,22 +883,57 @@ static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut,
875 t->aalgos = ut->aalgos; 883 t->aalgos = ut->aalgos;
876 t->ealgos = ut->ealgos; 884 t->ealgos = ut->ealgos;
877 t->calgos = ut->calgos; 885 t->calgos = ut->calgos;
886 t->encap_family = ut->family;
878 } 887 }
879} 888}
880 889
890static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family)
891{
892 int i;
893
894 if (nr > XFRM_MAX_DEPTH)
895 return -EINVAL;
896
897 for (i = 0; i < nr; i++) {
898 /* We never validated the ut->family value, so many
899 * applications simply leave it at zero. The check was
900 * never made and ut->family was ignored because all
901 * templates could be assumed to have the same family as
902 * the policy itself. Now that we will have ipv4-in-ipv6
903 * and ipv6-in-ipv4 tunnels, this is no longer true.
904 */
905 if (!ut[i].family)
906 ut[i].family = family;
907
908 switch (ut[i].family) {
909 case AF_INET:
910 break;
911#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
912 case AF_INET6:
913 break;
914#endif
915 default:
916 return -EINVAL;
917 };
918 }
919
920 return 0;
921}
922
881static int copy_from_user_tmpl(struct xfrm_policy *pol, struct rtattr **xfrma) 923static int copy_from_user_tmpl(struct xfrm_policy *pol, struct rtattr **xfrma)
882{ 924{
883 struct rtattr *rt = xfrma[XFRMA_TMPL-1]; 925 struct rtattr *rt = xfrma[XFRMA_TMPL-1];
884 struct xfrm_user_tmpl *utmpl;
885 int nr;
886 926
887 if (!rt) { 927 if (!rt) {
888 pol->xfrm_nr = 0; 928 pol->xfrm_nr = 0;
889 } else { 929 } else {
890 nr = (rt->rta_len - sizeof(*rt)) / sizeof(*utmpl); 930 struct xfrm_user_tmpl *utmpl = RTA_DATA(rt);
931 int nr = (rt->rta_len - sizeof(*rt)) / sizeof(*utmpl);
932 int err;
891 933
892 if (nr > XFRM_MAX_DEPTH) 934 err = validate_tmpl(nr, utmpl, pol->family);
893 return -EINVAL; 935 if (err)
936 return err;
894 937
895 copy_templates(pol, RTA_DATA(rt), nr); 938 copy_templates(pol, RTA_DATA(rt), nr);
896 } 939 }
@@ -901,7 +944,7 @@ static int copy_from_user_policy_type(u8 *tp, struct rtattr **xfrma)
901{ 944{
902 struct rtattr *rt = xfrma[XFRMA_POLICY_TYPE-1]; 945 struct rtattr *rt = xfrma[XFRMA_POLICY_TYPE-1];
903 struct xfrm_userpolicy_type *upt; 946 struct xfrm_userpolicy_type *upt;
904 __u8 type = XFRM_POLICY_TYPE_MAIN; 947 u8 type = XFRM_POLICY_TYPE_MAIN;
905 int err; 948 int err;
906 949
907 if (rt) { 950 if (rt) {
@@ -974,7 +1017,8 @@ static struct xfrm_policy *xfrm_policy_construct(struct xfrm_userpolicy_info *p,
974 return NULL; 1017 return NULL;
975} 1018}
976 1019
977static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) 1020static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
1021 struct rtattr **xfrma)
978{ 1022{
979 struct xfrm_userpolicy_info *p = NLMSG_DATA(nlh); 1023 struct xfrm_userpolicy_info *p = NLMSG_DATA(nlh);
980 struct xfrm_policy *xp; 1024 struct xfrm_policy *xp;
@@ -985,11 +1029,11 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr
985 err = verify_newpolicy_info(p); 1029 err = verify_newpolicy_info(p);
986 if (err) 1030 if (err)
987 return err; 1031 return err;
988 err = verify_sec_ctx_len((struct rtattr **)xfrma); 1032 err = verify_sec_ctx_len(xfrma);
989 if (err) 1033 if (err)
990 return err; 1034 return err;
991 1035
992 xp = xfrm_policy_construct(p, (struct rtattr **)xfrma, &err); 1036 xp = xfrm_policy_construct(p, xfrma, &err);
993 if (!xp) 1037 if (!xp)
994 return err; 1038 return err;
995 1039
@@ -999,6 +1043,9 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr
999 * a type XFRM_MSG_UPDPOLICY - JHS */ 1043 * a type XFRM_MSG_UPDPOLICY - JHS */
1000 excl = nlh->nlmsg_type == XFRM_MSG_NEWPOLICY; 1044 excl = nlh->nlmsg_type == XFRM_MSG_NEWPOLICY;
1001 err = xfrm_policy_insert(p->dir, xp, excl); 1045 err = xfrm_policy_insert(p->dir, xp, excl);
1046 xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
1047 AUDIT_MAC_IPSEC_DELSPD, err ? 0 : 1, xp, NULL);
1048
1002 if (err) { 1049 if (err) {
1003 security_xfrm_policy_free(xp); 1050 security_xfrm_policy_free(xp);
1004 kfree(xp); 1051 kfree(xp);
@@ -1028,7 +1075,7 @@ static int copy_to_user_tmpl(struct xfrm_policy *xp, struct sk_buff *skb)
1028 struct xfrm_tmpl *kp = &xp->xfrm_vec[i]; 1075 struct xfrm_tmpl *kp = &xp->xfrm_vec[i];
1029 1076
1030 memcpy(&up->id, &kp->id, sizeof(up->id)); 1077 memcpy(&up->id, &kp->id, sizeof(up->id));
1031 up->family = xp->family; 1078 up->family = kp->encap_family;
1032 memcpy(&up->saddr, &kp->saddr, sizeof(up->saddr)); 1079 memcpy(&up->saddr, &kp->saddr, sizeof(up->saddr));
1033 up->reqid = kp->reqid; 1080 up->reqid = kp->reqid;
1034 up->mode = kp->mode; 1081 up->mode = kp->mode;
@@ -1083,12 +1130,12 @@ static inline int copy_to_user_sec_ctx(struct xfrm_policy *xp, struct sk_buff *s
1083} 1130}
1084 1131
1085#ifdef CONFIG_XFRM_SUB_POLICY 1132#ifdef CONFIG_XFRM_SUB_POLICY
1086static int copy_to_user_policy_type(struct xfrm_policy *xp, struct sk_buff *skb) 1133static int copy_to_user_policy_type(u8 type, struct sk_buff *skb)
1087{ 1134{
1088 struct xfrm_userpolicy_type upt; 1135 struct xfrm_userpolicy_type upt;
1089 1136
1090 memset(&upt, 0, sizeof(upt)); 1137 memset(&upt, 0, sizeof(upt));
1091 upt.type = xp->type; 1138 upt.type = type;
1092 1139
1093 RTA_PUT(skb, XFRMA_POLICY_TYPE, sizeof(upt), &upt); 1140 RTA_PUT(skb, XFRMA_POLICY_TYPE, sizeof(upt), &upt);
1094 1141
@@ -1099,7 +1146,7 @@ rtattr_failure:
1099} 1146}
1100 1147
1101#else 1148#else
1102static inline int copy_to_user_policy_type(struct xfrm_policy *xp, struct sk_buff *skb) 1149static inline int copy_to_user_policy_type(u8 type, struct sk_buff *skb)
1103{ 1150{
1104 return 0; 1151 return 0;
1105} 1152}
@@ -1128,7 +1175,7 @@ static int dump_one_policy(struct xfrm_policy *xp, int dir, int count, void *ptr
1128 goto nlmsg_failure; 1175 goto nlmsg_failure;
1129 if (copy_to_user_sec_ctx(xp, skb)) 1176 if (copy_to_user_sec_ctx(xp, skb))
1130 goto nlmsg_failure; 1177 goto nlmsg_failure;
1131 if (copy_to_user_policy_type(xp, skb) < 0) 1178 if (copy_to_user_policy_type(xp->type, skb) < 0)
1132 goto nlmsg_failure; 1179 goto nlmsg_failure;
1133 1180
1134 nlh->nlmsg_len = skb->tail - b; 1181 nlh->nlmsg_len = skb->tail - b;
@@ -1171,7 +1218,6 @@ static struct sk_buff *xfrm_policy_netlink(struct sk_buff *in_skb,
1171 if (!skb) 1218 if (!skb)
1172 return ERR_PTR(-ENOMEM); 1219 return ERR_PTR(-ENOMEM);
1173 1220
1174 NETLINK_CB(skb).dst_pid = NETLINK_CB(in_skb).pid;
1175 info.in_skb = in_skb; 1221 info.in_skb = in_skb;
1176 info.out_skb = skb; 1222 info.out_skb = skb;
1177 info.nlmsg_seq = seq; 1223 info.nlmsg_seq = seq;
@@ -1186,11 +1232,12 @@ static struct sk_buff *xfrm_policy_netlink(struct sk_buff *in_skb,
1186 return skb; 1232 return skb;
1187} 1233}
1188 1234
1189static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) 1235static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
1236 struct rtattr **xfrma)
1190{ 1237{
1191 struct xfrm_policy *xp; 1238 struct xfrm_policy *xp;
1192 struct xfrm_userpolicy_id *p; 1239 struct xfrm_userpolicy_id *p;
1193 __u8 type = XFRM_POLICY_TYPE_MAIN; 1240 u8 type = XFRM_POLICY_TYPE_MAIN;
1194 int err; 1241 int err;
1195 struct km_event c; 1242 struct km_event c;
1196 int delete; 1243 int delete;
@@ -1198,7 +1245,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr
1198 p = NLMSG_DATA(nlh); 1245 p = NLMSG_DATA(nlh);
1199 delete = nlh->nlmsg_type == XFRM_MSG_DELPOLICY; 1246 delete = nlh->nlmsg_type == XFRM_MSG_DELPOLICY;
1200 1247
1201 err = copy_from_user_policy_type(&type, (struct rtattr **)xfrma); 1248 err = copy_from_user_policy_type(&type, xfrma);
1202 if (err) 1249 if (err)
1203 return err; 1250 return err;
1204 1251
@@ -1209,11 +1256,10 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr
1209 if (p->index) 1256 if (p->index)
1210 xp = xfrm_policy_byid(type, p->dir, p->index, delete); 1257 xp = xfrm_policy_byid(type, p->dir, p->index, delete);
1211 else { 1258 else {
1212 struct rtattr **rtattrs = (struct rtattr **)xfrma; 1259 struct rtattr *rt = xfrma[XFRMA_SEC_CTX-1];
1213 struct rtattr *rt = rtattrs[XFRMA_SEC_CTX-1];
1214 struct xfrm_policy tmp; 1260 struct xfrm_policy tmp;
1215 1261
1216 err = verify_sec_ctx_len(rtattrs); 1262 err = verify_sec_ctx_len(xfrma);
1217 if (err) 1263 if (err)
1218 return err; 1264 return err;
1219 1265
@@ -1227,6 +1273,10 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr
1227 xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security, delete); 1273 xp = xfrm_policy_bysel_ctx(type, p->dir, &p->sel, tmp.security, delete);
1228 security_xfrm_policy_free(&tmp); 1274 security_xfrm_policy_free(&tmp);
1229 } 1275 }
1276 if (delete)
1277 xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
1278 AUDIT_MAC_IPSEC_DELSPD, (xp) ? 1 : 0, xp, NULL);
1279
1230 if (xp == NULL) 1280 if (xp == NULL)
1231 return -ENOENT; 1281 return -ENOENT;
1232 1282
@@ -1257,12 +1307,16 @@ out:
1257 return err; 1307 return err;
1258} 1308}
1259 1309
1260static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) 1310static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
1311 struct rtattr **xfrma)
1261{ 1312{
1262 struct km_event c; 1313 struct km_event c;
1263 struct xfrm_usersa_flush *p = NLMSG_DATA(nlh); 1314 struct xfrm_usersa_flush *p = NLMSG_DATA(nlh);
1315 struct xfrm_audit audit_info;
1264 1316
1265 xfrm_state_flush(p->proto); 1317 audit_info.loginuid = NETLINK_CB(skb).loginuid;
1318 audit_info.secid = NETLINK_CB(skb).sid;
1319 xfrm_state_flush(p->proto, &audit_info);
1266 c.data.proto = p->proto; 1320 c.data.proto = p->proto;
1267 c.event = nlh->nlmsg_type; 1321 c.event = nlh->nlmsg_type;
1268 c.seq = nlh->nlmsg_seq; 1322 c.seq = nlh->nlmsg_seq;
@@ -1284,10 +1338,12 @@ static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, struct km_eve
1284 id = NLMSG_DATA(nlh); 1338 id = NLMSG_DATA(nlh);
1285 nlh->nlmsg_flags = 0; 1339 nlh->nlmsg_flags = 0;
1286 1340
1287 id->sa_id.daddr = x->id.daddr; 1341 memcpy(&id->sa_id.daddr, &x->id.daddr,sizeof(x->id.daddr));
1288 id->sa_id.spi = x->id.spi; 1342 id->sa_id.spi = x->id.spi;
1289 id->sa_id.family = x->props.family; 1343 id->sa_id.family = x->props.family;
1290 id->sa_id.proto = x->id.proto; 1344 id->sa_id.proto = x->id.proto;
1345 memcpy(&id->saddr, &x->props.saddr,sizeof(x->props.saddr));
1346 id->reqid = x->props.reqid;
1291 id->flags = c->data.aevent; 1347 id->flags = c->data.aevent;
1292 1348
1293 RTA_PUT(skb, XFRMA_REPLAY_VAL, sizeof(x->replay), &x->replay); 1349 RTA_PUT(skb, XFRMA_REPLAY_VAL, sizeof(x->replay), &x->replay);
@@ -1317,7 +1373,8 @@ nlmsg_failure:
1317 return -1; 1373 return -1;
1318} 1374}
1319 1375
1320static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) 1376static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
1377 struct rtattr **xfrma)
1321{ 1378{
1322 struct xfrm_state *x; 1379 struct xfrm_state *x;
1323 struct sk_buff *r_skb; 1380 struct sk_buff *r_skb;
@@ -1365,7 +1422,8 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
1365 return err; 1422 return err;
1366} 1423}
1367 1424
1368static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) 1425static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
1426 struct rtattr **xfrma)
1369{ 1427{
1370 struct xfrm_state *x; 1428 struct xfrm_state *x;
1371 struct km_event c; 1429 struct km_event c;
@@ -1389,7 +1447,7 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
1389 goto out; 1447 goto out;
1390 1448
1391 spin_lock_bh(&x->lock); 1449 spin_lock_bh(&x->lock);
1392 err = xfrm_update_ae_params(x,(struct rtattr **)xfrma); 1450 err = xfrm_update_ae_params(x, xfrma);
1393 spin_unlock_bh(&x->lock); 1451 spin_unlock_bh(&x->lock);
1394 if (err < 0) 1452 if (err < 0)
1395 goto out; 1453 goto out;
@@ -1405,17 +1463,21 @@ out:
1405 return err; 1463 return err;
1406} 1464}
1407 1465
1408static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) 1466static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
1467 struct rtattr **xfrma)
1409{ 1468{
1410 struct km_event c; 1469 struct km_event c;
1411 __u8 type = XFRM_POLICY_TYPE_MAIN; 1470 u8 type = XFRM_POLICY_TYPE_MAIN;
1412 int err; 1471 int err;
1472 struct xfrm_audit audit_info;
1413 1473
1414 err = copy_from_user_policy_type(&type, (struct rtattr **)xfrma); 1474 err = copy_from_user_policy_type(&type, xfrma);
1415 if (err) 1475 if (err)
1416 return err; 1476 return err;
1417 1477
1418 xfrm_policy_flush(type); 1478 audit_info.loginuid = NETLINK_CB(skb).loginuid;
1479 audit_info.secid = NETLINK_CB(skb).sid;
1480 xfrm_policy_flush(type, &audit_info);
1419 c.data.type = type; 1481 c.data.type = type;
1420 c.event = nlh->nlmsg_type; 1482 c.event = nlh->nlmsg_type;
1421 c.seq = nlh->nlmsg_seq; 1483 c.seq = nlh->nlmsg_seq;
@@ -1424,26 +1486,26 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **x
1424 return 0; 1486 return 0;
1425} 1487}
1426 1488
1427static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) 1489static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
1490 struct rtattr **xfrma)
1428{ 1491{
1429 struct xfrm_policy *xp; 1492 struct xfrm_policy *xp;
1430 struct xfrm_user_polexpire *up = NLMSG_DATA(nlh); 1493 struct xfrm_user_polexpire *up = NLMSG_DATA(nlh);
1431 struct xfrm_userpolicy_info *p = &up->pol; 1494 struct xfrm_userpolicy_info *p = &up->pol;
1432 __u8 type = XFRM_POLICY_TYPE_MAIN; 1495 u8 type = XFRM_POLICY_TYPE_MAIN;
1433 int err = -ENOENT; 1496 int err = -ENOENT;
1434 1497
1435 err = copy_from_user_policy_type(&type, (struct rtattr **)xfrma); 1498 err = copy_from_user_policy_type(&type, xfrma);
1436 if (err) 1499 if (err)
1437 return err; 1500 return err;
1438 1501
1439 if (p->index) 1502 if (p->index)
1440 xp = xfrm_policy_byid(type, p->dir, p->index, 0); 1503 xp = xfrm_policy_byid(type, p->dir, p->index, 0);
1441 else { 1504 else {
1442 struct rtattr **rtattrs = (struct rtattr **)xfrma; 1505 struct rtattr *rt = xfrma[XFRMA_SEC_CTX-1];
1443 struct rtattr *rt = rtattrs[XFRMA_SEC_CTX-1];
1444 struct xfrm_policy tmp; 1506 struct xfrm_policy tmp;
1445 1507
1446 err = verify_sec_ctx_len(rtattrs); 1508 err = verify_sec_ctx_len(xfrma);
1447 if (err) 1509 if (err)
1448 return err; 1510 return err;
1449 1511
@@ -1470,6 +1532,9 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, void *
1470 err = 0; 1532 err = 0;
1471 if (up->hard) { 1533 if (up->hard) {
1472 xfrm_policy_delete(xp, p->dir); 1534 xfrm_policy_delete(xp, p->dir);
1535 xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
1536 AUDIT_MAC_IPSEC_DELSPD, 1, xp, NULL);
1537
1473 } else { 1538 } else {
1474 // reset the timers here? 1539 // reset the timers here?
1475 printk("Dont know what to do with soft policy expire\n"); 1540 printk("Dont know what to do with soft policy expire\n");
@@ -1481,7 +1546,8 @@ out:
1481 return err; 1546 return err;
1482} 1547}
1483 1548
1484static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) 1549static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
1550 struct rtattr **xfrma)
1485{ 1551{
1486 struct xfrm_state *x; 1552 struct xfrm_state *x;
1487 int err; 1553 int err;
@@ -1501,15 +1567,19 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh, void **
1501 goto out; 1567 goto out;
1502 km_state_expired(x, ue->hard, current->pid); 1568 km_state_expired(x, ue->hard, current->pid);
1503 1569
1504 if (ue->hard) 1570 if (ue->hard) {
1505 __xfrm_state_delete(x); 1571 __xfrm_state_delete(x);
1572 xfrm_audit_log(NETLINK_CB(skb).loginuid, NETLINK_CB(skb).sid,
1573 AUDIT_MAC_IPSEC_DELSA, 1, NULL, x);
1574 }
1506out: 1575out:
1507 spin_unlock_bh(&x->lock); 1576 spin_unlock_bh(&x->lock);
1508 xfrm_state_put(x); 1577 xfrm_state_put(x);
1509 return err; 1578 return err;
1510} 1579}
1511 1580
1512static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) 1581static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,
1582 struct rtattr **xfrma)
1513{ 1583{
1514 struct xfrm_policy *xp; 1584 struct xfrm_policy *xp;
1515 struct xfrm_user_tmpl *ut; 1585 struct xfrm_user_tmpl *ut;
@@ -1531,7 +1601,8 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, void **xf
1531 } 1601 }
1532 1602
1533 /* build an XP */ 1603 /* build an XP */
1534 xp = xfrm_policy_construct(&ua->policy, (struct rtattr **) xfrma, &err); if (!xp) { 1604 xp = xfrm_policy_construct(&ua->policy, (struct rtattr **) xfrma, &err);
1605 if (!xp) {
1535 kfree(x); 1606 kfree(x);
1536 return err; 1607 return err;
1537 } 1608 }
@@ -1587,7 +1658,7 @@ static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = {
1587#undef XMSGSIZE 1658#undef XMSGSIZE
1588 1659
1589static struct xfrm_link { 1660static struct xfrm_link {
1590 int (*doit)(struct sk_buff *, struct nlmsghdr *, void **); 1661 int (*doit)(struct sk_buff *, struct nlmsghdr *, struct rtattr **);
1591 int (*dump)(struct sk_buff *, struct netlink_callback *); 1662 int (*dump)(struct sk_buff *, struct netlink_callback *);
1592} xfrm_dispatch[XFRM_NR_MSGTYPES] = { 1663} xfrm_dispatch[XFRM_NR_MSGTYPES] = {
1593 [XFRM_MSG_NEWSA - XFRM_MSG_BASE] = { .doit = xfrm_add_sa }, 1664 [XFRM_MSG_NEWSA - XFRM_MSG_BASE] = { .doit = xfrm_add_sa },
@@ -1675,7 +1746,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *err
1675 1746
1676 if (link->doit == NULL) 1747 if (link->doit == NULL)
1677 goto err_einval; 1748 goto err_einval;
1678 *errp = link->doit(skb, nlh, (void **) &xfrma); 1749 *errp = link->doit(skb, nlh, xfrma);
1679 1750
1680 return *errp; 1751 return *errp;
1681 1752
@@ -1908,7 +1979,7 @@ static int build_acquire(struct sk_buff *skb, struct xfrm_state *x,
1908 goto nlmsg_failure; 1979 goto nlmsg_failure;
1909 if (copy_to_user_state_sec_ctx(x, skb)) 1980 if (copy_to_user_state_sec_ctx(x, skb))
1910 goto nlmsg_failure; 1981 goto nlmsg_failure;
1911 if (copy_to_user_policy_type(xp, skb) < 0) 1982 if (copy_to_user_policy_type(xp->type, skb) < 0)
1912 goto nlmsg_failure; 1983 goto nlmsg_failure;
1913 1984
1914 nlh->nlmsg_len = skb->tail - b; 1985 nlh->nlmsg_len = skb->tail - b;
@@ -1980,7 +2051,7 @@ static struct xfrm_policy *xfrm_compile_policy(struct sock *sk, int opt,
1980 return NULL; 2051 return NULL;
1981 2052
1982 nr = ((len - sizeof(*p)) / sizeof(*ut)); 2053 nr = ((len - sizeof(*p)) / sizeof(*ut));
1983 if (nr > XFRM_MAX_DEPTH) 2054 if (validate_tmpl(nr, ut, p->sel.family))
1984 return NULL; 2055 return NULL;
1985 2056
1986 if (p->dir > XFRM_POLICY_OUT) 2057 if (p->dir > XFRM_POLICY_OUT)
@@ -2018,7 +2089,7 @@ static int build_polexpire(struct sk_buff *skb, struct xfrm_policy *xp,
2018 goto nlmsg_failure; 2089 goto nlmsg_failure;
2019 if (copy_to_user_sec_ctx(xp, skb)) 2090 if (copy_to_user_sec_ctx(xp, skb))
2020 goto nlmsg_failure; 2091 goto nlmsg_failure;
2021 if (copy_to_user_policy_type(xp, skb) < 0) 2092 if (copy_to_user_policy_type(xp->type, skb) < 0)
2022 goto nlmsg_failure; 2093 goto nlmsg_failure;
2023 upe->hard = !!hard; 2094 upe->hard = !!hard;
2024 2095
@@ -2097,7 +2168,7 @@ static int xfrm_notify_policy(struct xfrm_policy *xp, int dir, struct km_event *
2097 copy_to_user_policy(xp, p, dir); 2168 copy_to_user_policy(xp, p, dir);
2098 if (copy_to_user_tmpl(xp, skb) < 0) 2169 if (copy_to_user_tmpl(xp, skb) < 0)
2099 goto nlmsg_failure; 2170 goto nlmsg_failure;
2100 if (copy_to_user_policy_type(xp, skb) < 0) 2171 if (copy_to_user_policy_type(xp->type, skb) < 0)
2101 goto nlmsg_failure; 2172 goto nlmsg_failure;
2102 2173
2103 nlh->nlmsg_len = skb->tail - b; 2174 nlh->nlmsg_len = skb->tail - b;
@@ -2118,7 +2189,6 @@ static int xfrm_notify_policy_flush(struct km_event *c)
2118 unsigned char *b; 2189 unsigned char *b;
2119 int len = 0; 2190 int len = 0;
2120#ifdef CONFIG_XFRM_SUB_POLICY 2191#ifdef CONFIG_XFRM_SUB_POLICY
2121 struct xfrm_userpolicy_type upt;
2122 len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type)); 2192 len += RTA_SPACE(sizeof(struct xfrm_userpolicy_type));
2123#endif 2193#endif
2124 len += NLMSG_LENGTH(0); 2194 len += NLMSG_LENGTH(0);
@@ -2131,12 +2201,8 @@ static int xfrm_notify_policy_flush(struct km_event *c)
2131 2201
2132 nlh = NLMSG_PUT(skb, c->pid, c->seq, XFRM_MSG_FLUSHPOLICY, 0); 2202 nlh = NLMSG_PUT(skb, c->pid, c->seq, XFRM_MSG_FLUSHPOLICY, 0);
2133 nlh->nlmsg_flags = 0; 2203 nlh->nlmsg_flags = 0;
2134 2204 if (copy_to_user_policy_type(c->data.type, skb) < 0)
2135#ifdef CONFIG_XFRM_SUB_POLICY 2205 goto nlmsg_failure;
2136 memset(&upt, 0, sizeof(upt));
2137 upt.type = c->data.type;
2138 RTA_PUT(skb, XFRMA_POLICY_TYPE, sizeof(upt), &upt);
2139#endif
2140 2206
2141 nlh->nlmsg_len = skb->tail - b; 2207 nlh->nlmsg_len = skb->tail - b;
2142 2208
@@ -2144,9 +2210,6 @@ static int xfrm_notify_policy_flush(struct km_event *c)
2144 return netlink_broadcast(xfrm_nl, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC); 2210 return netlink_broadcast(xfrm_nl, skb, 0, XFRMNLGRP_POLICY, GFP_ATOMIC);
2145 2211
2146nlmsg_failure: 2212nlmsg_failure:
2147#ifdef CONFIG_XFRM_SUB_POLICY
2148rtattr_failure:
2149#endif
2150 kfree_skb(skb); 2213 kfree_skb(skb);
2151 return -1; 2214 return -1;
2152} 2215}