]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
authorDavid S. Miller <davem@davemloft.net>
Tue, 15 Jul 2008 03:40:34 +0000 (20:40 -0700)
committerDavid S. Miller <davem@davemloft.net>
Tue, 15 Jul 2008 03:40:34 +0000 (20:40 -0700)
33 files changed:
Documentation/networking/ip-sysctl.txt
drivers/net/arm/ixp4xx_eth.c
drivers/net/tun.c
drivers/net/wireless/libertas/scan.c
drivers/net/wireless/rt2x00/rt2400pci.c
drivers/net/wireless/rt2x00/rt2500pci.c
drivers/net/wireless/rt2x00/rt2500usb.c
drivers/net/wireless/rt2x00/rt61pci.c
drivers/net/wireless/rt2x00/rt73usb.c
drivers/net/wireless/zd1211rw/zd_mac.c
include/linux/dccp.h
include/linux/pkt_cls.h
include/linux/xfrm.h
include/net/netfilter/nf_conntrack.h
net/dccp/ccids/ccid3.c
net/dccp/ccids/lib/loss_interval.c
net/dccp/ccids/lib/packet_history.c
net/dccp/ccids/lib/packet_history.h
net/dccp/dccp.h
net/dccp/options.c
net/ipv4/fib_trie.c
net/ipv4/netfilter/nf_nat_snmp_basic.c
net/ipv4/tcp_probe.c
net/ipv6/exthdrs.c
net/mac80211/rc80211_pid.h
net/mac80211/rc80211_pid_algo.c
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_conntrack_proto_tcp.c
net/netlabel/netlabel_cipso_v4.c
net/netlabel/netlabel_mgmt.c
net/netlabel/netlabel_unlabeled.c
net/sched/cls_flow.c
net/xfrm/xfrm_user.c

index a40feaee62ec084a0b4938ad5e97b27dfdee516c..d84932650fd3e926cc11d5fa0bcaee6cc8a8cd33 100644 (file)
@@ -148,9 +148,9 @@ tcp_available_congestion_control - STRING
        but not loaded.
 
 tcp_base_mss - INTEGER
-       The initial value of search_low to be used by Packetization Layer
-       Path MTU Discovery (MTU probing).  If MTU probing is enabled,
-       this is the inital MSS used by the connection.
+       The initial value of search_low to be used by the packetization layer
+       Path MTU discovery (MTU probing).  If MTU probing is enabled,
+       this is the initial MSS used by the connection.
 
 tcp_congestion_control - STRING
        Set the congestion control algorithm to be used for new
@@ -185,10 +185,9 @@ tcp_frto - INTEGER
        timeouts.  It is particularly beneficial in wireless environments
        where packet loss is typically due to random radio interference
        rather than intermediate router congestion.  F-RTO is sender-side
-       only modification.  Therefore it does not require any support from
-       the peer, but in a typical case, however, where wireless link is
-       the local access link and most of the data flows downlink, the
-       faraway servers should have F-RTO enabled to take advantage of it.
+       only modification. Therefore it does not require any support from
+       the peer.
+
        If set to 1, basic version is enabled.  2 enables SACK enhanced
        F-RTO if flow uses SACK.  The basic version can be used also when
        SACK is in use though scenario(s) with it exists where F-RTO
@@ -276,7 +275,7 @@ tcp_mem - vector of 3 INTEGERs: min, pressure, max
        memory.
 
 tcp_moderate_rcvbuf - BOOLEAN
-       If set, TCP performs receive buffer autotuning, attempting to
+       If set, TCP performs receive buffer auto-tuning, attempting to
        automatically size the buffer (no greater than tcp_rmem[2]) to
        match the size required by the path for full throughput.  Enabled by
        default.
@@ -336,7 +335,7 @@ tcp_rmem - vector of 3 INTEGERs: min, default, max
        pressure.
        Default: 8K
 
-       default: default size of receive buffer used by TCP sockets.
+       default: initial size of receive buffer used by TCP sockets.
        This value overrides net.core.rmem_default used by other protocols.
        Default: 87380 bytes. This value results in window of 65535 with
        default setting of tcp_adv_win_scale and tcp_app_win:0 and a bit
@@ -344,8 +343,10 @@ tcp_rmem - vector of 3 INTEGERs: min, default, max
 
        max: maximal size of receive buffer allowed for automatically
        selected receiver buffers for TCP socket. This value does not override
-       net.core.rmem_max, "static" selection via SO_RCVBUF does not use this.
-       Default: 87380*2 bytes.
+       net.core.rmem_max.  Calling setsockopt() with SO_RCVBUF disables
+       automatic tuning of that socket's receive buffer size, in which
+       case this value is ignored.
+       Default: between 87380B and 4MB, depending on RAM size.
 
 tcp_sack - BOOLEAN
        Enable select acknowledgments (SACKS).
@@ -358,7 +359,7 @@ tcp_slow_start_after_idle - BOOLEAN
        Default: 1
 
 tcp_stdurg - BOOLEAN
-       Use the Host requirements interpretation of the TCP urg pointer field.
+       Use the Host requirements interpretation of the TCP urgent pointer field.
        Most hosts use the older BSD interpretation, so if you turn this on
        Linux might not communicate correctly with them.
        Default: FALSE
@@ -371,12 +372,12 @@ tcp_synack_retries - INTEGER
 tcp_syncookies - BOOLEAN
        Only valid when the kernel was compiled with CONFIG_SYNCOOKIES
        Send out syncookies when the syn backlog queue of a socket
-       overflows. This is to prevent against the common 'syn flood attack'
+       overflows. This is to prevent against the common 'SYN flood attack'
        Default: FALSE
 
        Note, that syncookies is fallback facility.
        It MUST NOT be used to help highly loaded servers to stand
-       against legal connection rate. If you see synflood warnings
+       against legal connection rate. If you see SYN flood warnings
        in your logs, but investigation shows that they occur
        because of overload with legal connections, you should tune
        another parameters until this warning disappear.
@@ -386,7 +387,7 @@ tcp_syncookies - BOOLEAN
        to use TCP extensions, can result in serious degradation
        of some services (f.e. SMTP relaying), visible not by you,
        but your clients and relays, contacting you. While you see
-       synflood warnings in logs not being really flooded, your server
+       SYN flood warnings in logs not being really flooded, your server
        is seriously misconfigured.
 
 tcp_syn_retries - INTEGER
@@ -419,19 +420,21 @@ tcp_window_scaling - BOOLEAN
        Enable window scaling as defined in RFC1323.
 
 tcp_wmem - vector of 3 INTEGERs: min, default, max
-       min: Amount of memory reserved for send buffers for TCP socket.
+       min: Amount of memory reserved for send buffers for TCP sockets.
        Each TCP socket has rights to use it due to fact of its birth.
        Default: 4K
 
-       default: Amount of memory allowed for send buffers for TCP socket
-       by default. This value overrides net.core.wmem_default used
-       by other protocols, it is usually lower than net.core.wmem_default.
+       default: initial size of send buffer used by TCP sockets.  This
+       value overrides net.core.wmem_default used by other protocols.
+       It is usually lower than net.core.wmem_default.
        Default: 16K
 
-       max: Maximal amount of memory allowed for automatically selected
-       send buffers for TCP socket. This value does not override
-       net.core.wmem_max, "static" selection via SO_SNDBUF does not use this.
-       Default: 128K
+       max: Maximal amount of memory allowed for automatically tuned
+       send buffers for TCP sockets. This value does not override
+       net.core.wmem_max.  Calling setsockopt() with SO_SNDBUF disables
+       automatic tuning of that socket's send buffer size, in which case
+       this value is ignored.
+       Default: between 64K and 4MB, depending on RAM size.
 
 tcp_workaround_signed_windows - BOOLEAN
        If set, assume no receipt of a window scaling option means the
@@ -1073,24 +1076,193 @@ bridge-nf-filter-pppoe-tagged - BOOLEAN
        Default: 1
 
 
-UNDOCUMENTED:
+proc/sys/net/sctp/* Variables:
+
+addip_enable - BOOLEAN
+       Enable or disable extension of  Dynamic Address Reconfiguration
+       (ADD-IP) functionality specified in RFC5061.  This extension provides
+       the ability to dynamically add and remove new addresses for the SCTP
+       associations.
+
+       1: Enable extension.
+
+       0: Disable extension.
+
+       Default: 0
+
+addip_noauth_enable - BOOLEAN
+       Dynamic Address Reconfiguration (ADD-IP) requires the use of
+       authentication to protect the operations of adding or removing new
+       addresses.  This requirement is mandated so that unauthorized hosts
+       would not be able to hijack associations.  However, older
+       implementations may not have implemented this requirement while
+       allowing the ADD-IP extension.  For reasons of interoperability,
+       we provide this variable to control the enforcement of the
+       authentication requirement.
+
+       1: Allow ADD-IP extension to be used without authentication.  This
+          should only be set in a closed environment for interoperability
+          with older implementations.
+
+       0: Enforce the authentication requirement
+
+       Default: 0
+
+auth_enable - BOOLEAN
+       Enable or disable Authenticated Chunks extension.  This extension
+       provides the ability to send and receive authenticated chunks and is
+       required for secure operation of Dynamic Address Reconfiguration
+       (ADD-IP) extension.
+
+       1: Enable this extension.
+       0: Disable this extension.
+
+       Default: 0
+
+prsctp_enable - BOOLEAN
+       Enable or disable the Partial Reliability extension (RFC3758) which
+       is used to notify peers that a given DATA should no longer be expected.
+
+       1: Enable extension
+       0: Disable
+
+       Default: 1
+
+max_burst - INTEGER
+       The limit of the number of new packets that can be initially sent.  It
+       controls how bursty the generated traffic can be.
+
+       Default: 4
+
+association_max_retrans - INTEGER
+       Set the maximum number for retransmissions that an association can
+       attempt deciding that the remote end is unreachable.  If this value
+       is exceeded, the association is terminated.
+
+       Default: 10
+
+max_init_retransmits - INTEGER
+       The maximum number of retransmissions of INIT and COOKIE-ECHO chunks
+       that an association will attempt before declaring the destination
+       unreachable and terminating.
+
+       Default: 8
+
+path_max_retrans - INTEGER
+       The maximum number of retransmissions that will be attempted on a given
+       path.  Once this threshold is exceeded, the path is considered
+       unreachable, and new traffic will use a different path when the
+       association is multihomed.
+
+       Default: 5
+
+rto_initial - INTEGER
+       The initial round trip timeout value in milliseconds that will be used
+       in calculating round trip times.  This is the initial time interval
+       for retransmissions.
+
+       Default: 3000
 
-dev_weight FIXME
-discovery_slots FIXME
-discovery_timeout FIXME
-fast_poll_increase FIXME
-ip6_queue_maxlen FIXME
-lap_keepalive_time FIXME
-lo_cong FIXME
-max_baud_rate FIXME
-max_dgram_qlen FIXME
-max_noreply_time FIXME
-max_tx_data_size FIXME
-max_tx_window FIXME
-min_tx_turn_time FIXME
-mod_cong FIXME
-no_cong FIXME
-no_cong_thresh FIXME
-slot_timeout FIXME
-warn_noreply_time FIXME
+rto_max - INTEGER
+       The maximum value (in milliseconds) of the round trip timeout.  This
+       is the largest time interval that can elapse between retransmissions.
+
+       Default: 60000
+
+rto_min - INTEGER
+       The minimum value (in milliseconds) of the round trip timeout.  This
+       is the smallest time interval the can elapse between retransmissions.
+
+       Default: 1000
+
+hb_interval - INTEGER
+       The interval (in milliseconds) between HEARTBEAT chunks.  These chunks
+       are sent at the specified interval on idle paths to probe the state of
+       a given path between 2 associations.
+
+       Default: 30000
+
+sack_timeout - INTEGER
+       The amount of time (in milliseconds) that the implementation will wait
+       to send a SACK.
+
+       Default: 200
+
+valid_cookie_life - INTEGER
+       The default lifetime of the SCTP cookie (in milliseconds).  The cookie
+       is used during association establishment.
+
+       Default: 60000
+
+cookie_preserve_enable - BOOLEAN
+       Enable or disable the ability to extend the lifetime of the SCTP cookie
+       that is used during the establishment phase of SCTP association
+
+       1: Enable cookie lifetime extension.
+       0: Disable
+
+       Default: 1
+
+rcvbuf_policy - INTEGER
+       Determines if the receive buffer is attributed to the socket or to
+       association.   SCTP supports the capability to create multiple
+       associations on a single socket.  When using this capability, it is
+       possible that a single stalled association that's buffering a lot
+       of data may block other associations from delivering their data by
+       consuming all of the receive buffer space.  To work around this,
+       the rcvbuf_policy could be set to attribute the receiver buffer space
+       to each association instead of the socket.  This prevents the described
+       blocking.
+
+       1: rcvbuf space is per association
+       0: recbuf space is per socket
+
+       Default: 0
+
+sndbuf_policy - INTEGER
+       Similar to rcvbuf_policy above, this applies to send buffer space.
+
+       1: Send buffer is tracked per association
+       0: Send buffer is tracked per socket.
+
+       Default: 0
+
+sctp_mem - vector of 3 INTEGERs: min, pressure, max
+       Number of pages allowed for queueing by all SCTP sockets.
+
+       min: Below this number of pages SCTP is not bothered about its
+       memory appetite. When amount of memory allocated by SCTP exceeds
+       this number, SCTP starts to moderate memory usage.
+
+       pressure: This value was introduced to follow format of tcp_mem.
+
+       max: Number of pages allowed for queueing by all SCTP sockets.
+
+       Default is calculated at boot time from amount of available memory.
+
+sctp_rmem - vector of 3 INTEGERs: min, default, max
+       See tcp_rmem for a description.
+
+sctp_wmem  - vector of 3 INTEGERs: min, default, max
+       See tcp_wmem for a description.
+
+UNDOCUMENTED:
 
+/proc/sys/net/core/*
+       dev_weight FIXME
+
+/proc/sys/net/unix/*
+       max_dgram_qlen FIXME
+
+/proc/sys/net/irda/*
+       fast_poll_increase FIXME
+       warn_noreply_time FIXME
+       discovery_slots FIXME
+       slot_timeout FIXME
+       max_baud_rate FIXME
+       discovery_timeout FIXME
+       lap_keepalive_time FIXME
+       max_noreply_time FIXME
+       max_tx_data_size FIXME
+       max_tx_window FIXME
+       min_tx_turn_time FIXME
index c617b64c288e4d1a883a2e845610f64418c057aa..9b777d9433cd8b87b7c8479ef52c0d893f1ee117 100644 (file)
@@ -522,7 +522,6 @@ static int eth_poll(struct napi_struct *napi, int budget)
 #endif
 
                if ((n = queue_get_desc(rxq, port, 0)) < 0) {
-                       received = 0; /* No packet received */
 #if DEBUG_RX
                        printk(KERN_DEBUG "%s: eth_poll netif_rx_complete\n",
                               dev->name);
@@ -543,7 +542,7 @@ static int eth_poll(struct napi_struct *napi, int budget)
                        printk(KERN_DEBUG "%s: eth_poll all done\n",
                               dev->name);
 #endif
-                       return 0; /* all work done */
+                       return received; /* all work done */
                }
 
                desc = rx_desc_ptr(port, n);
index aa4ee4439f048e864d559764c5f57316d1b6a7b3..2693f883ecda78d112fe181ddc39da8e17edfd42 100644 (file)
@@ -690,6 +690,12 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
        tun->attached = 1;
        get_net(dev_net(tun->dev));
 
+       /* Make sure persistent devices do not get stuck in
+        * xoff state.
+        */
+       if (netif_running(tun->dev))
+               netif_wake_queue(tun->dev);
+
        strcpy(ifr->ifr_name, tun->dev->name);
        return 0;
 
index 343ed38f772d6a30d4f38526d381c34f7b6eae22..4b274562f965df9565003550e95a15c044e5e1ab 100644 (file)
@@ -567,11 +567,11 @@ static int lbs_process_bss(struct bss_descriptor *bss,
        pos += 8;
 
        /* beacon interval is 2 bytes long */
-       bss->beaconperiod = le16_to_cpup((void *) pos);
+       bss->beaconperiod = get_unaligned_le16(pos);
        pos += 2;
 
        /* capability information is 2 bytes long */
-       bss->capability = le16_to_cpup((void *) pos);
+       bss->capability = get_unaligned_le16(pos);
        lbs_deb_scan("process_bss: capabilities 0x%04x\n", bss->capability);
        pos += 2;
 
index 027580bfa7c3c4c4ce1b868f04c1cdb281d16668..4c0538d6099bb2503646d091e4a9e9a1d3417095 100644 (file)
@@ -733,6 +733,17 @@ static int rt2400pci_init_registers(struct rt2x00_dev *rt2x00dev)
                           (rt2x00dev->rx->data_size / 128));
        rt2x00pci_register_write(rt2x00dev, CSR9, reg);
 
+       rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
+       rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 0);
+       rt2x00_set_field32(&reg, CSR14_TSF_SYNC, 0);
+       rt2x00_set_field32(&reg, CSR14_TBCN, 0);
+       rt2x00_set_field32(&reg, CSR14_TCFP, 0);
+       rt2x00_set_field32(&reg, CSR14_TATIMW, 0);
+       rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
+       rt2x00_set_field32(&reg, CSR14_CFP_COUNT_PRELOAD, 0);
+       rt2x00_set_field32(&reg, CSR14_TBCM_PRELOAD, 0);
+       rt2x00pci_register_write(rt2x00dev, CSR14, reg);
+
        rt2x00pci_register_write(rt2x00dev, CNT3, 0x3f080000);
 
        rt2x00pci_register_read(rt2x00dev, ARCSR0, &reg);
index 50f9e8f6cd682e06c32c270209465ef17c425be0..aa6dfb811c7181bf861b04b7e35c062820581831 100644 (file)
@@ -831,6 +831,17 @@ static int rt2500pci_init_registers(struct rt2x00_dev *rt2x00dev)
        rt2x00_set_field32(&reg, CSR11_CW_SELECT, 0);
        rt2x00pci_register_write(rt2x00dev, CSR11, reg);
 
+       rt2x00pci_register_read(rt2x00dev, CSR14, &reg);
+       rt2x00_set_field32(&reg, CSR14_TSF_COUNT, 0);
+       rt2x00_set_field32(&reg, CSR14_TSF_SYNC, 0);
+       rt2x00_set_field32(&reg, CSR14_TBCN, 0);
+       rt2x00_set_field32(&reg, CSR14_TCFP, 0);
+       rt2x00_set_field32(&reg, CSR14_TATIMW, 0);
+       rt2x00_set_field32(&reg, CSR14_BEACON_GEN, 0);
+       rt2x00_set_field32(&reg, CSR14_CFP_COUNT_PRELOAD, 0);
+       rt2x00_set_field32(&reg, CSR14_TBCM_PRELOAD, 0);
+       rt2x00pci_register_write(rt2x00dev, CSR14, reg);
+
        rt2x00pci_register_write(rt2x00dev, CNT3, 0);
 
        rt2x00pci_register_read(rt2x00dev, TXCSR8, &reg);
index 1423fd0bdbb3d08ba30ae501b567befb8b3477aa..3558cb210747a1b6ba6f8cde0962f925747e9eab 100644 (file)
@@ -812,6 +812,13 @@ static int rt2500usb_init_registers(struct rt2x00_dev *rt2x00dev)
        rt2x00_set_field16(&reg, TXRX_CSR8_BBP_ID1_VALID, 0);
        rt2500usb_register_write(rt2x00dev, TXRX_CSR8, reg);
 
+       rt2500usb_register_read(rt2x00dev, TXRX_CSR19, &reg);
+       rt2x00_set_field16(&reg, TXRX_CSR19_TSF_COUNT, 0);
+       rt2x00_set_field16(&reg, TXRX_CSR19_TSF_SYNC, 0);
+       rt2x00_set_field16(&reg, TXRX_CSR19_TBCN, 0);
+       rt2x00_set_field16(&reg, TXRX_CSR19_BEACON_GEN, 0);
+       rt2500usb_register_write(rt2x00dev, TXRX_CSR19, reg);
+
        rt2500usb_register_write(rt2x00dev, TXRX_CSR21, 0xe78f);
        rt2500usb_register_write(rt2x00dev, MAC_CSR9, 0xff1d);
 
index 80c4445e62861edcb2f42eb756ac305f53bdc2fb..70ef7bf434ab44dee46e031999a19e1f7041e311 100644 (file)
@@ -1198,6 +1198,15 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev)
        rt2x00_set_field32(&reg, TXRX_CSR8_ACK_CTS_54MBS, 42);
        rt2x00pci_register_write(rt2x00dev, TXRX_CSR8, reg);
 
+       rt2x00pci_register_read(rt2x00dev, TXRX_CSR9, &reg);
+       rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_INTERVAL, 0);
+       rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 0);
+       rt2x00_set_field32(&reg, TXRX_CSR9_TSF_SYNC, 0);
+       rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 0);
+       rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
+       rt2x00_set_field32(&reg, TXRX_CSR9_TIMESTAMP_COMPENSATE, 0);
+       rt2x00pci_register_write(rt2x00dev, TXRX_CSR9, reg);
+
        rt2x00pci_register_write(rt2x00dev, TXRX_CSR15, 0x0000000f);
 
        rt2x00pci_register_write(rt2x00dev, MAC_CSR6, 0x00000fff);
index 6f89b4c75e1fc1d0a480c0c038f19d5220cfddde..34c6ff27afc4d5dbc0bcd8a009f3aeab331eb237 100644 (file)
@@ -1016,6 +1016,15 @@ static int rt73usb_init_registers(struct rt2x00_dev *rt2x00dev)
        rt2x00_set_field32(&reg, TXRX_CSR8_ACK_CTS_54MBS, 42);
        rt73usb_register_write(rt2x00dev, TXRX_CSR8, reg);
 
+       rt73usb_register_read(rt2x00dev, TXRX_CSR9, &reg);
+       rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_INTERVAL, 0);
+       rt2x00_set_field32(&reg, TXRX_CSR9_TSF_TICKING, 0);
+       rt2x00_set_field32(&reg, TXRX_CSR9_TSF_SYNC, 0);
+       rt2x00_set_field32(&reg, TXRX_CSR9_TBTT_ENABLE, 0);
+       rt2x00_set_field32(&reg, TXRX_CSR9_BEACON_GEN, 0);
+       rt2x00_set_field32(&reg, TXRX_CSR9_TIMESTAMP_COMPENSATE, 0);
+       rt73usb_register_write(rt2x00dev, TXRX_CSR9, reg);
+
        rt73usb_register_write(rt2x00dev, TXRX_CSR15, 0x0000000f);
 
        rt73usb_register_read(rt2x00dev, MAC_CSR6, &reg);
index 68e2749b2ce85688be5087f518ea993d5eb6cc1e..fcc532bb6a7efe0a13482458ff9572c854ca37aa 100644 (file)
@@ -707,6 +707,7 @@ static void zd_op_remove_interface(struct ieee80211_hw *hw,
 {
        struct zd_mac *mac = zd_hw_mac(hw);
        mac->type = IEEE80211_IF_TYPE_INVALID;
+       zd_set_beacon_interval(&mac->chip, 0);
        zd_write_mac_addr(&mac->chip, NULL);
 }
 
index aa0737019e37da6e759ea95e026088cbbfc6518d..6080449fbec942b7a1340c4a0c131f1957b33e81 100644 (file)
@@ -364,8 +364,6 @@ static inline unsigned int dccp_hdr_len(const struct sk_buff *skb)
 /* FIXME: for now we're default to 1 but it should really be 0 */
 #define DCCPF_INITIAL_SEND_NDP_COUNT           1
 
-#define DCCP_NDP_LIMIT 0xFFFFFF
-
 /**
   * struct dccp_minisock - Minimal DCCP connection representation
   *
@@ -437,7 +435,7 @@ extern int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
                              struct sk_buff *skb);
 
 struct dccp_options_received {
-       u32     dccpor_ndp; /* only 24 bits */
+       u64     dccpor_ndp:48;
        u32     dccpor_timestamp;
        u32     dccpor_timestamp_echo;
        u32     dccpor_elapsed_time;
@@ -533,7 +531,7 @@ struct dccp_sock {
        __u16                           dccps_r_ack_ratio;
        __u16                           dccps_pcslen;
        __u16                           dccps_pcrlen;
-       unsigned long                   dccps_ndp_count;
+       __u64                           dccps_ndp_count:48;
        unsigned long                   dccps_rate_last;
        struct dccp_minisock            dccps_minisock;
        struct dccp_ackvec              *dccps_hc_rx_ackvec;
index 99efbed81fa2ed1b72a3594b4be1a3b3ada4e1b7..7cf7824df77814b327b1fb4abbd263273bd55bf4 100644 (file)
@@ -374,6 +374,7 @@ enum
        TCA_FLOW_ACT,
        TCA_FLOW_POLICE,
        TCA_FLOW_EMATCHES,
+       TCA_FLOW_PERTURB,
        __TCA_FLOW_MAX
 };
 
index 2ca6bae88721920215a649bc437393733452aae9..fb0c215a3051a0e697d305c98067f39c25a2c790 100644 (file)
@@ -339,6 +339,7 @@ struct xfrm_usersa_info {
 #define XFRM_STATE_NOPMTUDISC  4
 #define XFRM_STATE_WILDRECV    8
 #define XFRM_STATE_ICMP                16
+#define XFRM_STATE_AF_UNSPEC   32
 };
 
 struct xfrm_usersa_id {
index d5d76ec7abb0f3339fc3f65d7218142eeb2bf95e..8f5b75734dd03693752d998c222670c826fbdd00 100644 (file)
@@ -223,23 +223,23 @@ static inline void nf_ct_refresh(struct nf_conn *ct,
        __nf_ct_refresh_acct(ct, 0, skb, extra_jiffies, 0);
 }
 
-extern void __nf_ct_kill_acct(struct nf_conn *ct,
-                               enum ip_conntrack_info ctinfo,
-                               const struct sk_buff *skb,
-                               int do_acct);
+extern bool __nf_ct_kill_acct(struct nf_conn *ct,
+                             enum ip_conntrack_info ctinfo,
+                             const struct sk_buff *skb,
+                             int do_acct);
 
 /* kill conntrack and do accounting */
-static inline void nf_ct_kill_acct(struct nf_conn *ct,
-                               enum ip_conntrack_info ctinfo,
-                               const struct sk_buff *skb)
+static inline bool nf_ct_kill_acct(struct nf_conn *ct,
+                                  enum ip_conntrack_info ctinfo,
+                                  const struct sk_buff *skb)
 {
-       __nf_ct_kill_acct(ct, ctinfo, skb, 1);
+       return __nf_ct_kill_acct(ct, ctinfo, skb, 1);
 }
 
 /* kill conntrack without accounting */
-static inline void nf_ct_kill(struct nf_conn *ct)
+static inline bool nf_ct_kill(struct nf_conn *ct)
 {
-       __nf_ct_kill_acct(ct, 0, NULL, 0);
+       return __nf_ct_kill_acct(ct, 0, NULL, 0);
 }
 
 /* These are for NAT.  Icky. */
index a1929f33d7030a2ac91fe51c99b16a104070eeb7..f6756e0c9e6989a8884493464a61bcd621c7880d 100644 (file)
@@ -794,7 +794,7 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
 {
        struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
        enum ccid3_fback_type do_feedback = CCID3_FBACK_NONE;
-       const u32 ndp = dccp_sk(sk)->dccps_options_received.dccpor_ndp;
+       const u64 ndp = dccp_sk(sk)->dccps_options_received.dccpor_ndp;
        const bool is_data_packet = dccp_data_packet(skb);
 
        if (unlikely(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)) {
@@ -825,18 +825,16 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
        }
 
        /*
-        * Handle pending losses and otherwise check for new loss
+        * Perform loss detection and handle pending losses
         */
-       if (tfrc_rx_hist_loss_pending(&hcrx->ccid3hcrx_hist) &&
-           tfrc_rx_handle_loss(&hcrx->ccid3hcrx_hist,
-                               &hcrx->ccid3hcrx_li_hist,
-                               skb, ndp, ccid3_first_li, sk) ) {
+       if (tfrc_rx_handle_loss(&hcrx->ccid3hcrx_hist, &hcrx->ccid3hcrx_li_hist,
+                               skb, ndp, ccid3_first_li, sk)) {
                do_feedback = CCID3_FBACK_PARAM_CHANGE;
                goto done_receiving;
        }
 
-       if (tfrc_rx_hist_new_loss_indicated(&hcrx->ccid3hcrx_hist, skb, ndp))
-               goto update_records;
+       if (tfrc_rx_hist_loss_pending(&hcrx->ccid3hcrx_hist))
+               return; /* done receiving */
 
        /*
         * Handle data packets: RTT sampling and monitoring p
index 849e181e698fa84d0a7c3e1665cc8e459f5567ac..bcd6ac415bb9a5073fd8255e4990ae4e5ad5aac4 100644 (file)
@@ -90,14 +90,14 @@ u8 tfrc_lh_update_i_mean(struct tfrc_loss_hist *lh, struct sk_buff *skb)
 {
        struct tfrc_loss_interval *cur = tfrc_lh_peek(lh);
        u32 old_i_mean = lh->i_mean;
-       s64 length;
+       s64 len;
 
        if (cur == NULL)                        /* not initialised */
                return 0;
 
-       length = dccp_delta_seqno(cur->li_seqno, DCCP_SKB_CB(skb)->dccpd_seq);
+       len = dccp_delta_seqno(cur->li_seqno, DCCP_SKB_CB(skb)->dccpd_seq) + 1;
 
-       if (length - cur->li_length <= 0)       /* duplicate or reordered */
+       if (len - (s64)cur->li_length <= 0)     /* duplicate or reordered */
                return 0;
 
        if (SUB16(dccp_hdr(skb)->dccph_ccval, cur->li_ccval) > 4)
@@ -114,7 +114,7 @@ u8 tfrc_lh_update_i_mean(struct tfrc_loss_hist *lh, struct sk_buff *skb)
        if (tfrc_lh_length(lh) == 1)            /* due to RFC 3448, 6.3.1 */
                return 0;
 
-       cur->li_length = length;
+       cur->li_length = len;
        tfrc_lh_calc_i_mean(lh);
 
        return (lh->i_mean < old_i_mean);
@@ -159,7 +159,7 @@ int tfrc_lh_interval_add(struct tfrc_loss_hist *lh, struct tfrc_rx_hist *rh,
        else {
                cur->li_length = dccp_delta_seqno(cur->li_seqno, new->li_seqno);
                new->li_length = dccp_delta_seqno(new->li_seqno,
-                                 tfrc_rx_hist_last_rcv(rh)->tfrchrx_seqno);
+                                 tfrc_rx_hist_last_rcv(rh)->tfrchrx_seqno) + 1;
                if (lh->counter > (2*LIH_SIZE))
                        lh->counter -= LIH_SIZE;
 
index 20af1a69342789f96abc6454b9a93187624de027..6cc108afdc3be594ddb6231b9fc4664de4a8c8da 100644 (file)
@@ -153,7 +153,7 @@ void tfrc_rx_packet_history_exit(void)
 
 static inline void tfrc_rx_hist_entry_from_skb(struct tfrc_rx_hist_entry *entry,
                                               const struct sk_buff *skb,
-                                              const u32 ndp)
+                                              const u64 ndp)
 {
        const struct dccp_hdr *dh = dccp_hdr(skb);
 
@@ -166,7 +166,7 @@ static inline void tfrc_rx_hist_entry_from_skb(struct tfrc_rx_hist_entry *entry,
 
 void tfrc_rx_hist_add_packet(struct tfrc_rx_hist *h,
                             const struct sk_buff *skb,
-                            const u32 ndp)
+                            const u64 ndp)
 {
        struct tfrc_rx_hist_entry *entry = tfrc_rx_hist_last_rcv(h);
 
@@ -206,31 +206,39 @@ static void tfrc_rx_hist_swap(struct tfrc_rx_hist *h, const u8 a, const u8 b)
  *
  * In the descriptions, `Si' refers to the sequence number of entry number i,
  * whose NDP count is `Ni' (lower case is used for variables).
- * Note: All __after_loss functions expect that a test against duplicates has
- *       been performed already: the seqno of the skb must not be less than the
- *       seqno of loss_prev; and it must not equal that of any valid hist_entry.
+ * Note: All __xxx_loss functions expect that a test against duplicates has been
+ *       performed already: the seqno of the skb must not be less than the seqno
+ *       of loss_prev; and it must not equal that of any valid history entry.
  */
+static void __do_track_loss(struct tfrc_rx_hist *h, struct sk_buff *skb, u64 n1)
+{
+       u64 s0 = tfrc_rx_hist_loss_prev(h)->tfrchrx_seqno,
+           s1 = DCCP_SKB_CB(skb)->dccpd_seq;
+
+       if (!dccp_loss_free(s0, s1, n1)) {      /* gap between S0 and S1 */
+               h->loss_count = 1;
+               tfrc_rx_hist_entry_from_skb(tfrc_rx_hist_entry(h, 1), skb, n1);
+       }
+}
+
 static void __one_after_loss(struct tfrc_rx_hist *h, struct sk_buff *skb, u32 n2)
 {
        u64 s0 = tfrc_rx_hist_loss_prev(h)->tfrchrx_seqno,
            s1 = tfrc_rx_hist_entry(h, 1)->tfrchrx_seqno,
            s2 = DCCP_SKB_CB(skb)->dccpd_seq;
-       int n1 = tfrc_rx_hist_entry(h, 1)->tfrchrx_ndp,
-          d12 = dccp_delta_seqno(s1, s2), d2;
 
-       if (d12 > 0) {                  /* S1  <  S2 */
+       if (likely(dccp_delta_seqno(s1, s2) > 0)) {     /* S1  <  S2 */
                h->loss_count = 2;
                tfrc_rx_hist_entry_from_skb(tfrc_rx_hist_entry(h, 2), skb, n2);
                return;
        }
 
        /* S0  <  S2  <  S1 */
-       d2 = dccp_delta_seqno(s0, s2);
 
-       if (d2 == 1 || n2 >= d2) {      /* S2 is direct successor of S0 */
-               int d21 = -d12;
+       if (dccp_loss_free(s0, s2, n2)) {
+               u64 n1 = tfrc_rx_hist_entry(h, 1)->tfrchrx_ndp;
 
-               if (d21 == 1 || n1 >= d21) {
+               if (dccp_loss_free(s2, s1, n1)) {
                        /* hole is filled: S0, S2, and S1 are consecutive */
                        h->loss_count = 0;
                        h->loss_start = tfrc_rx_hist_index(h, 1);
@@ -238,9 +246,9 @@ static void __one_after_loss(struct tfrc_rx_hist *h, struct sk_buff *skb, u32 n2
                        /* gap between S2 and S1: just update loss_prev */
                        tfrc_rx_hist_entry_from_skb(tfrc_rx_hist_loss_prev(h), skb, n2);
 
-       } else {                        /* hole between S0 and S2 */
+       } else {        /* gap between S0 and S2 */
                /*
-                * Reorder history to insert S2 between S0 and s1
+                * Reorder history to insert S2 between S0 and S1
                 */
                tfrc_rx_hist_swap(h, 0, 3);
                h->loss_start = tfrc_rx_hist_index(h, 3);
@@ -256,22 +264,18 @@ static int __two_after_loss(struct tfrc_rx_hist *h, struct sk_buff *skb, u32 n3)
            s1 = tfrc_rx_hist_entry(h, 1)->tfrchrx_seqno,
            s2 = tfrc_rx_hist_entry(h, 2)->tfrchrx_seqno,
            s3 = DCCP_SKB_CB(skb)->dccpd_seq;
-       int n1 = tfrc_rx_hist_entry(h, 1)->tfrchrx_ndp,
-          d23 = dccp_delta_seqno(s2, s3), d13, d3, d31;
 
-       if (d23 > 0) {                  /* S2  <  S3 */
+       if (likely(dccp_delta_seqno(s2, s3) > 0)) {     /* S2  <  S3 */
                h->loss_count = 3;
                tfrc_rx_hist_entry_from_skb(tfrc_rx_hist_entry(h, 3), skb, n3);
                return 1;
        }
 
        /* S3  <  S2 */
-       d13 = dccp_delta_seqno(s1, s3);
 
-       if (d13 > 0) {
+       if (dccp_delta_seqno(s1, s3) > 0) {             /* S1  <  S3  <  S2 */
                /*
-                * The sequence number order is S1, S3, S2
-                * Reorder history to insert entry between S1 and S2
+                * Reorder history to insert S3 between S1 and S2
                 */
                tfrc_rx_hist_swap(h, 2, 3);
                tfrc_rx_hist_entry_from_skb(tfrc_rx_hist_entry(h, 2), skb, n3);
@@ -280,17 +284,15 @@ static int __two_after_loss(struct tfrc_rx_hist *h, struct sk_buff *skb, u32 n3)
        }
 
        /* S0  <  S3  <  S1 */
-       d31 = -d13;
-       d3  = dccp_delta_seqno(s0, s3);
 
-       if (d3 == 1 || n3 >= d3) {      /* S3 is a successor of S0 */
+       if (dccp_loss_free(s0, s3, n3)) {
+               u64 n1 = tfrc_rx_hist_entry(h, 1)->tfrchrx_ndp;
 
-               if (d31 == 1 || n1 >= d31) {
+               if (dccp_loss_free(s3, s1, n1)) {
                        /* hole between S0 and S1 filled by S3 */
-                       int  d2 = dccp_delta_seqno(s1, s2),
-                            n2 = tfrc_rx_hist_entry(h, 2)->tfrchrx_ndp;
+                       u64 n2 = tfrc_rx_hist_entry(h, 2)->tfrchrx_ndp;
 
-                       if (d2 == 1 || n2 >= d2) {
+                       if (dccp_loss_free(s1, s2, n2)) {
                                /* entire hole filled by S0, S3, S1, S2 */
                                h->loss_start = tfrc_rx_hist_index(h, 2);
                                h->loss_count = 0;
@@ -307,8 +309,8 @@ static int __two_after_loss(struct tfrc_rx_hist *h, struct sk_buff *skb, u32 n3)
        }
 
        /*
-        * The remaining case: S3 is not a successor of S0.
-        * Sequence order is S0, S3, S1, S2; reorder to insert between S0 and S1
+        * The remaining case:  S0  <  S3  <  S1  <  S2;  gap between S0 and S3
+        * Reorder history to insert S3 between S0 and S1.
         */
        tfrc_rx_hist_swap(h, 0, 3);
        h->loss_start = tfrc_rx_hist_index(h, 3);
@@ -318,33 +320,25 @@ static int __two_after_loss(struct tfrc_rx_hist *h, struct sk_buff *skb, u32 n3)
        return 1;
 }
 
-/* return the signed modulo-2^48 sequence number distance from entry e1 to e2 */
-static s64 tfrc_rx_hist_delta_seqno(struct tfrc_rx_hist *h, u8 e1, u8 e2)
-{
-       DCCP_BUG_ON(e1 > h->loss_count || e2 > h->loss_count);
-
-       return dccp_delta_seqno(tfrc_rx_hist_entry(h, e1)->tfrchrx_seqno,
-                               tfrc_rx_hist_entry(h, e2)->tfrchrx_seqno);
-}
-
 /* recycle RX history records to continue loss detection if necessary */
 static void __three_after_loss(struct tfrc_rx_hist *h)
 {
        /*
-        * The distance between S0 and S1 is always greater than 1 and the NDP
-        * count of S1 is smaller than this distance. Otherwise there would
-        * have been no loss. Hence it is only necessary to see whether there
-        * are further missing data packets between S1/S2 and S2/S3.
+        * At this stage we know already that there is a gap between S0 and S1
+        * (since S0 was the highest sequence number received before detecting
+        * the loss). To recycle the loss record, it is thus only necessary to
+        * check for other possible gaps between S1/S2 and between S2/S3.
         */
-       int d2 = tfrc_rx_hist_delta_seqno(h, 1, 2),
-           d3 = tfrc_rx_hist_delta_seqno(h, 2, 3),
-           n2 = tfrc_rx_hist_entry(h, 2)->tfrchrx_ndp,
+       u64 s1 = tfrc_rx_hist_entry(h, 1)->tfrchrx_seqno,
+           s2 = tfrc_rx_hist_entry(h, 2)->tfrchrx_seqno,
+           s3 = tfrc_rx_hist_entry(h, 3)->tfrchrx_seqno;
+       u64 n2 = tfrc_rx_hist_entry(h, 2)->tfrchrx_ndp,
            n3 = tfrc_rx_hist_entry(h, 3)->tfrchrx_ndp;
 
-       if (d2 == 1 || n2 >= d2) {      /* S2 is successor to S1 */
+       if (dccp_loss_free(s1, s2, n2)) {
 
-               if (d3 == 1 || n3 >= d3) {
-                       /* S3 is successor of S2: entire hole is filled */
+               if (dccp_loss_free(s2, s3, n3)) {
+                       /* no gap between S2 and S3: entire hole is filled */
                        h->loss_start = tfrc_rx_hist_index(h, 3);
                        h->loss_count = 0;
                } else {
@@ -353,7 +347,7 @@ static void __three_after_loss(struct tfrc_rx_hist *h)
                        h->loss_count = 1;
                }
 
-       } else {                        /* gap between S1 and S2 */
+       } else {        /* gap between S1 and S2 */
                h->loss_start = tfrc_rx_hist_index(h, 1);
                h->loss_count = 2;
        }
@@ -370,15 +364,20 @@ static void __three_after_loss(struct tfrc_rx_hist *h)
  *  Chooses action according to pending loss, updates LI database when a new
  *  loss was detected, and does required post-processing. Returns 1 when caller
  *  should send feedback, 0 otherwise.
+ *  Since it also takes care of reordering during loss detection and updates the
+ *  records accordingly, the caller should not perform any more RX history
+ *  operations when loss_count is greater than 0 after calling this function.
  */
 int tfrc_rx_handle_loss(struct tfrc_rx_hist *h,
                        struct tfrc_loss_hist *lh,
-                       struct sk_buff *skb, u32 ndp,
+                       struct sk_buff *skb, const u64 ndp,
                        u32 (*calc_first_li)(struct sock *), struct sock *sk)
 {
        int is_new_loss = 0;
 
-       if (h->loss_count == 1) {
+       if (h->loss_count == 0) {
+               __do_track_loss(h, skb, ndp);
+       } else if (h->loss_count == 1) {
                __one_after_loss(h, skb, ndp);
        } else if (h->loss_count != 2) {
                DCCP_BUG("invalid loss_count %d", h->loss_count);
index c7eeda49cb20aae104fe3026d871e269a75bc848..461cc91cce88aecee60a32c8ab496de770192ad5 100644 (file)
@@ -64,7 +64,7 @@ struct tfrc_rx_hist_entry {
        u64              tfrchrx_seqno:48,
                         tfrchrx_ccval:4,
                         tfrchrx_type:4;
-       u32              tfrchrx_ndp; /* In fact it is from 8 to 24 bits */
+       u64              tfrchrx_ndp:48;
        ktime_t          tfrchrx_tstamp;
 };
 
@@ -118,41 +118,21 @@ static inline struct tfrc_rx_hist_entry *
        return h->ring[h->loss_start];
 }
 
-/* initialise loss detection and disable RTT sampling */
-static inline void tfrc_rx_hist_loss_indicated(struct tfrc_rx_hist *h)
-{
-       h->loss_count = 1;
-}
-
 /* indicate whether previously a packet was detected missing */
-static inline int tfrc_rx_hist_loss_pending(const struct tfrc_rx_hist *h)
-{
-       return h->loss_count;
-}
-
-/* any data packets missing between last reception and skb ? */
-static inline int tfrc_rx_hist_new_loss_indicated(struct tfrc_rx_hist *h,
-                                                 const struct sk_buff *skb,
-                                                 u32 ndp)
+static inline bool tfrc_rx_hist_loss_pending(const struct tfrc_rx_hist *h)
 {
-       int delta = dccp_delta_seqno(tfrc_rx_hist_last_rcv(h)->tfrchrx_seqno,
-                                    DCCP_SKB_CB(skb)->dccpd_seq);
-
-       if (delta > 1 && ndp < delta)
-               tfrc_rx_hist_loss_indicated(h);
-
-       return tfrc_rx_hist_loss_pending(h);
+       return h->loss_count > 0;
 }
 
 extern void tfrc_rx_hist_add_packet(struct tfrc_rx_hist *h,
-                                   const struct sk_buff *skb, const u32 ndp);
+                                   const struct sk_buff *skb, const u64 ndp);
 
 extern int tfrc_rx_hist_duplicate(struct tfrc_rx_hist *h, struct sk_buff *skb);
 
 struct tfrc_loss_hist;
 extern int  tfrc_rx_handle_loss(struct tfrc_rx_hist *h,
                                struct tfrc_loss_hist *lh,
-                               struct sk_buff *skb, u32 ndp,
+                               struct sk_buff *skb, const u64 ndp,
                                u32 (*first_li)(struct sock *sk),
                                struct sock *sk);
 extern u32 tfrc_rx_hist_sample_rtt(struct tfrc_rx_hist *h,
index 1b2cea244e12ec21818d17f522950830a630eafa..32617e0576cb04e240d654f13c2cbecb64d9230a 100644 (file)
@@ -153,6 +153,21 @@ static inline u64 max48(const u64 seq1, const u64 seq2)
        return after48(seq1, seq2) ? seq1 : seq2;
 }
 
+/**
+ * dccp_loss_free  -  Evaluates condition for data loss from RFC 4340, 7.7.1
+ * @s1:         start sequence number
+ * @s2:  end sequence number
+ * @ndp: NDP count on packet with sequence number @s2
+ * Returns true if the sequence range s1...s2 has no data loss.
+ */
+static inline bool dccp_loss_free(const u64 s1, const u64 s2, const u64 ndp)
+{
+       s64 delta = dccp_delta_seqno(s1, s2);
+
+       BUG_TRAP(delta >= 0);
+       return (u64)delta <= ndp + 1;
+}
+
 enum {
        DCCP_MIB_NUM = 0,
        DCCP_MIB_ACTIVEOPENS,                   /* ActiveOpens */
index 43bc24e761d0e707fca63a4404e061c270a071bc..dc7c158a2f4b81f49e1ab604cb8819912d82fd36 100644 (file)
@@ -124,12 +124,12 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
                                mandatory = 1;
                        break;
                case DCCPO_NDP_COUNT:
-                       if (len > 3)
+                       if (len > 6)
                                goto out_invalid_option;
 
                        opt_recv->dccpor_ndp = dccp_decode_value_var(value, len);
-                       dccp_pr_debug("%s rx opt: NDP count=%d\n", dccp_role(sk),
-                                     opt_recv->dccpor_ndp);
+                       dccp_pr_debug("%s opt: NDP count=%llu\n", dccp_role(sk),
+                                     (unsigned long long)opt_recv->dccpor_ndp);
                        break;
                case DCCPO_CHANGE_L:
                        /* fall through */
@@ -307,9 +307,11 @@ static void dccp_encode_value_var(const u32 value, unsigned char *to,
                *to++ = (value & 0xFF);
 }
 
-static inline int dccp_ndp_len(const int ndp)
+static inline u8 dccp_ndp_len(const u64 ndp)
 {
-       return likely(ndp <= 0xFF) ? 1 : ndp <= 0xFFFF ? 2 : 3;
+       if (likely(ndp <= 0xFF))
+               return 1;
+       return likely(ndp <= USHORT_MAX) ? 2 : (ndp <= UINT_MAX ? 4 : 6);
 }
 
 int dccp_insert_option(struct sock *sk, struct sk_buff *skb,
@@ -336,7 +338,7 @@ EXPORT_SYMBOL_GPL(dccp_insert_option);
 static int dccp_insert_option_ndp(struct sock *sk, struct sk_buff *skb)
 {
        struct dccp_sock *dp = dccp_sk(sk);
-       int ndp = dp->dccps_ndp_count;
+       u64 ndp = dp->dccps_ndp_count;
 
        if (dccp_non_data_packet(skb))
                ++dp->dccps_ndp_count;
index d16ae4623be64cbae61f97f0e28edbf7d2ca59b4..f155a66d6ebfe40916b3cc89216c8d4622ec0c2a 100644 (file)
@@ -1357,17 +1357,17 @@ static int check_leaf(struct trie *t, struct leaf *l,
                        t->stats.semantic_match_miss++;
 #endif
                if (err <= 0)
-                       return plen;
+                       return err;
        }
 
-       return -1;
+       return 1;
 }
 
 static int fn_trie_lookup(struct fib_table *tb, const struct flowi *flp,
                          struct fib_result *res)
 {
        struct trie *t = (struct trie *) tb->tb_data;
-       int plen, ret = 0;
+       int ret;
        struct node *n;
        struct tnode *pn;
        int pos, bits;
@@ -1391,10 +1391,7 @@ static int fn_trie_lookup(struct fib_table *tb, const struct flowi *flp,
 
        /* Just a leaf? */
        if (IS_LEAF(n)) {
-               plen = check_leaf(t, (struct leaf *)n, key, flp, res);
-               if (plen < 0)
-                       goto failed;
-               ret = 0;
+               ret = check_leaf(t, (struct leaf *)n, key, flp, res);
                goto found;
        }
 
@@ -1419,11 +1416,9 @@ static int fn_trie_lookup(struct fib_table *tb, const struct flowi *flp,
                }
 
                if (IS_LEAF(n)) {
-                       plen = check_leaf(t, (struct leaf *)n, key, flp, res);
-                       if (plen < 0)
+                       ret = check_leaf(t, (struct leaf *)n, key, flp, res);
+                       if (ret > 0)
                                goto backtrace;
-
-                       ret = 0;
                        goto found;
                }
 
index 7750c97fde7bb6bdc6ae05061b2528d3d3e31310..ffeaffc3fffe6c31c78e858b9a1fa61fe71ba03e 100644 (file)
@@ -439,8 +439,8 @@ static unsigned char asn1_oid_decode(struct asn1_ctx *ctx,
                                     unsigned int *len)
 {
        unsigned long subid;
-       unsigned int  size;
        unsigned long *optr;
+       size_t size;
 
        size = eoc - ctx->pointer + 1;
 
index 5ff0ce6e9d39d25538f5c98dff986231fbaebcc9..7ddc30f0744ff13afe250c37f000fe46d144efcc 100644 (file)
@@ -224,7 +224,7 @@ static __init int tcpprobe_init(void)
        if (bufsize < 0)
                return -EINVAL;
 
-       tcp_probe.log = kcalloc(sizeof(struct tcp_log), bufsize, GFP_KERNEL);
+       tcp_probe.log = kcalloc(bufsize, sizeof(struct tcp_log), GFP_KERNEL);
        if (!tcp_probe.log)
                goto err0;
 
index 602ea826f0a59665c1b15b00088062be2b1623c1..9f1084b4c0e80d592fb475f968333cd48c05206c 100644 (file)
@@ -443,7 +443,7 @@ looped_back:
                        kfree_skb(skb);
                        return -1;
                }
-               if (!ipv6_chk_home_addr(&init_net, addr)) {
+               if (!ipv6_chk_home_addr(dev_net(skb->dst->dev), addr)) {
                        IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
                                         IPSTATS_MIB_INADDRERRORS);
                        kfree_skb(skb);
index 2078803d3581dfdb6c4268e03f482bf0792d3c1c..0a9135b974b5d11817f60534338d272dd249aef1 100644 (file)
@@ -141,7 +141,6 @@ struct rc_pid_events_file_info {
  *     rate behaviour values (lower means we should trust more what we learnt
  *     about behaviour of rates, higher means we should trust more the natural
  *     ordering of rates)
- * @fast_start: if Y, push high rates right after initialization
  */
 struct rc_pid_debugfs_entries {
        struct dentry *dir;
@@ -154,7 +153,6 @@ struct rc_pid_debugfs_entries {
        struct dentry *sharpen_factor;
        struct dentry *sharpen_duration;
        struct dentry *norm_offset;
-       struct dentry *fast_start;
 };
 
 void rate_control_pid_event_tx_status(struct rc_pid_event_buffer *buf,
@@ -267,9 +265,6 @@ struct rc_pid_info {
        /* Normalization offset. */
        unsigned int norm_offset;
 
-       /* Fast starst parameter. */
-       unsigned int fast_start;
-
        /* Rates information. */
        struct rc_pid_rateinfo *rinfo;
 
index ca636295e6289e13fc7479bb6800de862e3ab6b1..a914ba73ccf56a3d828fa88a851dc44eebfd8fdb 100644 (file)
@@ -398,13 +398,25 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local)
                return NULL;
        }
 
+       pinfo->target = RC_PID_TARGET_PF;
+       pinfo->sampling_period = RC_PID_INTERVAL;
+       pinfo->coeff_p = RC_PID_COEFF_P;
+       pinfo->coeff_i = RC_PID_COEFF_I;
+       pinfo->coeff_d = RC_PID_COEFF_D;
+       pinfo->smoothing_shift = RC_PID_SMOOTHING_SHIFT;
+       pinfo->sharpen_factor = RC_PID_SHARPENING_FACTOR;
+       pinfo->sharpen_duration = RC_PID_SHARPENING_DURATION;
+       pinfo->norm_offset = RC_PID_NORM_OFFSET;
+       pinfo->rinfo = rinfo;
+       pinfo->oldrate = 0;
+
        /* Sort the rates. This is optimized for the most common case (i.e.
         * almost-sorted CCK+OFDM rates). Kind of bubble-sort with reversed
         * mapping too. */
        for (i = 0; i < sband->n_bitrates; i++) {
                rinfo[i].index = i;
                rinfo[i].rev_index = i;
-               if (pinfo->fast_start)
+               if (RC_PID_FAST_START)
                        rinfo[i].diff = 0;
                else
                        rinfo[i].diff = i * pinfo->norm_offset;
@@ -425,19 +437,6 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local)
                        break;
        }
 
-       pinfo->target = RC_PID_TARGET_PF;
-       pinfo->sampling_period = RC_PID_INTERVAL;
-       pinfo->coeff_p = RC_PID_COEFF_P;
-       pinfo->coeff_i = RC_PID_COEFF_I;
-       pinfo->coeff_d = RC_PID_COEFF_D;
-       pinfo->smoothing_shift = RC_PID_SMOOTHING_SHIFT;
-       pinfo->sharpen_factor = RC_PID_SHARPENING_FACTOR;
-       pinfo->sharpen_duration = RC_PID_SHARPENING_DURATION;
-       pinfo->norm_offset = RC_PID_NORM_OFFSET;
-       pinfo->fast_start = RC_PID_FAST_START;
-       pinfo->rinfo = rinfo;
-       pinfo->oldrate = 0;
-
 #ifdef CONFIG_MAC80211_DEBUGFS
        de = &pinfo->dentries;
        de->dir = debugfs_create_dir("rc80211_pid",
@@ -465,9 +464,6 @@ static void *rate_control_pid_alloc(struct ieee80211_local *local)
        de->norm_offset = debugfs_create_u32("norm_offset",
                                             S_IRUSR | S_IWUSR, de->dir,
                                             &pinfo->norm_offset);
-       de->fast_start = debugfs_create_bool("fast_start",
-                                            S_IRUSR | S_IWUSR, de->dir,
-                                            &pinfo->fast_start);
 #endif
 
        return pinfo;
@@ -479,7 +475,6 @@ static void rate_control_pid_free(void *priv)
 #ifdef CONFIG_MAC80211_DEBUGFS
        struct rc_pid_debugfs_entries *de = &pinfo->dentries;
 
-       debugfs_remove(de->fast_start);
        debugfs_remove(de->norm_offset);
        debugfs_remove(de->sharpen_duration);
        debugfs_remove(de->sharpen_factor);
index 212a0888408d01c9d11fd5894083ca5ad882e21a..28d03e64200b60284d196bfba395ea90d2316f7f 100644 (file)
@@ -848,10 +848,10 @@ acct:
 }
 EXPORT_SYMBOL_GPL(__nf_ct_refresh_acct);
 
-void __nf_ct_kill_acct(struct nf_conn *ct,
-               enum ip_conntrack_info ctinfo,
-               const struct sk_buff *skb,
-               int do_acct)
+bool __nf_ct_kill_acct(struct nf_conn *ct,
+                      enum ip_conntrack_info ctinfo,
+                      const struct sk_buff *skb,
+                      int do_acct)
 {
 #ifdef CONFIG_NF_CT_ACCT
        if (do_acct) {
@@ -862,8 +862,11 @@ void __nf_ct_kill_acct(struct nf_conn *ct,
                spin_unlock_bh(&nf_conntrack_lock);
        }
 #endif
-       if (del_timer(&ct->timeout))
+       if (del_timer(&ct->timeout)) {
                ct->timeout.function((unsigned long)ct);
+               return true;
+       }
+       return false;
 }
 EXPORT_SYMBOL_GPL(__nf_ct_kill_acct);
 
index 740acd6bc7d955328b22eb08273646727dcfec0d..420a10d8eb1ec7fdc449cc4304afcbe00f4b9e98 100644 (file)
@@ -844,8 +844,14 @@ static int tcp_packet(struct nf_conn *ct,
                        /* Attempt to reopen a closed/aborted connection.
                         * Delete this connection and look up again. */
                        write_unlock_bh(&tcp_lock);
-                       nf_ct_kill(ct);
-                       return -NF_REPEAT;
+
+                       /* Only repeat if we can actually remove the timer.
+                        * Destruction may already be in progress in process
+                        * context and we must give it a chance to terminate.
+                        */
+                       if (nf_ct_kill(ct))
+                               return -NF_REPEAT;
+                       return -NF_DROP;
                }
                /* Fall through */
        case TCP_CONNTRACK_IGNORE:
index fdc14a0d21af8fce47ced5d63fc8af46453851a5..9080c61b71a5633a7b4b49199db9b83a4c26559e 100644 (file)
@@ -584,12 +584,7 @@ list_start:
        rcu_read_unlock();
 
        genlmsg_end(ans_skb, data);
-
-       ret_val = genlmsg_reply(ans_skb, info);
-       if (ret_val != 0)
-               goto list_failure;
-
-       return 0;
+       return genlmsg_reply(ans_skb, info);
 
 list_retry:
        /* XXX - this limit is a guesstimate */
index 22c19126780899b464b70f3f4e545b29f1e51f65..44be5d5261f4670005f44276f5fb5a257fe97538 100644 (file)
@@ -386,11 +386,7 @@ static int netlbl_mgmt_listdef(struct sk_buff *skb, struct genl_info *info)
        rcu_read_unlock();
 
        genlmsg_end(ans_skb, data);
-
-       ret_val = genlmsg_reply(ans_skb, info);
-       if (ret_val != 0)
-               goto listdef_failure;
-       return 0;
+       return genlmsg_reply(ans_skb, info);
 
 listdef_failure_lock:
        rcu_read_unlock();
@@ -501,11 +497,7 @@ static int netlbl_mgmt_version(struct sk_buff *skb, struct genl_info *info)
                goto version_failure;
 
        genlmsg_end(ans_skb, data);
-
-       ret_val = genlmsg_reply(ans_skb, info);
-       if (ret_val != 0)
-               goto version_failure;
-       return 0;
+       return genlmsg_reply(ans_skb, info);
 
 version_failure:
        kfree_skb(ans_skb);
index 52b2611a6eb6625f8d1d329bea03d03e7ad460ac..56f80872924e88e5b007b004db93572382c94cd1 100644 (file)
@@ -1107,11 +1107,7 @@ static int netlbl_unlabel_list(struct sk_buff *skb, struct genl_info *info)
                goto list_failure;
 
        genlmsg_end(ans_skb, data);
-
-       ret_val = genlmsg_reply(ans_skb, info);
-       if (ret_val != 0)
-               goto list_failure;
-       return 0;
+       return genlmsg_reply(ans_skb, info);
 
 list_failure:
        kfree_skb(ans_skb);
index 971b867e0484fd8d50ec0d60e56109e8f54b02f4..8f63a1a94014ff35a6c15e83dc89382ccf3d9767 100644 (file)
@@ -36,6 +36,8 @@ struct flow_filter {
        struct list_head        list;
        struct tcf_exts         exts;
        struct tcf_ematch_tree  ematches;
+       struct timer_list       perturb_timer;
+       u32                     perturb_period;
        u32                     handle;
 
        u32                     nkeys;
@@ -47,11 +49,9 @@ struct flow_filter {
        u32                     addend;
        u32                     divisor;
        u32                     baseclass;
+       u32                     hashrnd;
 };
 
-static u32 flow_hashrnd __read_mostly;
-static int flow_hashrnd_initted __read_mostly;
-
 static const struct tcf_ext_map flow_ext_map = {
        .action = TCA_FLOW_ACT,
        .police = TCA_FLOW_POLICE,
@@ -348,7 +348,7 @@ static int flow_classify(struct sk_buff *skb, struct tcf_proto *tp,
                }
 
                if (f->mode == FLOW_MODE_HASH)
-                       classid = jhash2(keys, f->nkeys, flow_hashrnd);
+                       classid = jhash2(keys, f->nkeys, f->hashrnd);
                else {
                        classid = keys[0];
                        classid = (classid & f->mask) ^ f->xor;
@@ -369,6 +369,15 @@ static int flow_classify(struct sk_buff *skb, struct tcf_proto *tp,
        return -1;
 }
 
+static void flow_perturbation(unsigned long arg)
+{
+       struct flow_filter *f = (struct flow_filter *)arg;
+
+       get_random_bytes(&f->hashrnd, 4);
+       if (f->perturb_period)
+               mod_timer(&f->perturb_timer, jiffies + f->perturb_period);
+}
+
 static const struct nla_policy flow_policy[TCA_FLOW_MAX + 1] = {
        [TCA_FLOW_KEYS]         = { .type = NLA_U32 },
        [TCA_FLOW_MODE]         = { .type = NLA_U32 },
@@ -381,6 +390,7 @@ static const struct nla_policy flow_policy[TCA_FLOW_MAX + 1] = {
        [TCA_FLOW_ACT]          = { .type = NLA_NESTED },
        [TCA_FLOW_POLICE]       = { .type = NLA_NESTED },
        [TCA_FLOW_EMATCHES]     = { .type = NLA_NESTED },
+       [TCA_FLOW_PERTURB]      = { .type = NLA_U32 },
 };
 
 static int flow_change(struct tcf_proto *tp, unsigned long base,
@@ -394,6 +404,7 @@ static int flow_change(struct tcf_proto *tp, unsigned long base,
        struct tcf_exts e;
        struct tcf_ematch_tree t;
        unsigned int nkeys = 0;
+       unsigned int perturb_period = 0;
        u32 baseclass = 0;
        u32 keymask = 0;
        u32 mode;
@@ -442,6 +453,14 @@ static int flow_change(struct tcf_proto *tp, unsigned long base,
                        mode = nla_get_u32(tb[TCA_FLOW_MODE]);
                if (mode != FLOW_MODE_HASH && nkeys > 1)
                        goto err2;
+
+               if (mode == FLOW_MODE_HASH)
+                       perturb_period = f->perturb_period;
+               if (tb[TCA_FLOW_PERTURB]) {
+                       if (mode != FLOW_MODE_HASH)
+                               goto err2;
+                       perturb_period = nla_get_u32(tb[TCA_FLOW_PERTURB]) * HZ;
+               }
        } else {
                err = -EINVAL;
                if (!handle)
@@ -455,6 +474,12 @@ static int flow_change(struct tcf_proto *tp, unsigned long base,
                if (mode != FLOW_MODE_HASH && nkeys > 1)
                        goto err2;
 
+               if (tb[TCA_FLOW_PERTURB]) {
+                       if (mode != FLOW_MODE_HASH)
+                               goto err2;
+                       perturb_period = nla_get_u32(tb[TCA_FLOW_PERTURB]) * HZ;
+               }
+
                if (TC_H_MAJ(baseclass) == 0)
                        baseclass = TC_H_MAKE(tp->q->handle, baseclass);
                if (TC_H_MIN(baseclass) == 0)
@@ -467,6 +492,11 @@ static int flow_change(struct tcf_proto *tp, unsigned long base,
 
                f->handle = handle;
                f->mask   = ~0U;
+
+               get_random_bytes(&f->hashrnd, 4);
+               f->perturb_timer.function = flow_perturbation;
+               f->perturb_timer.data = (unsigned long)f;
+               init_timer_deferrable(&f->perturb_timer);
        }
 
        tcf_exts_change(tp, &f->exts, &e);
@@ -495,6 +525,11 @@ static int flow_change(struct tcf_proto *tp, unsigned long base,
        if (baseclass)
                f->baseclass = baseclass;
 
+       f->perturb_period = perturb_period;
+       del_timer(&f->perturb_timer);
+       if (perturb_period)
+               mod_timer(&f->perturb_timer, jiffies + perturb_period);
+
        if (*arg == 0)
                list_add_tail(&f->list, &head->filters);
 
@@ -512,6 +547,7 @@ err1:
 
 static void flow_destroy_filter(struct tcf_proto *tp, struct flow_filter *f)
 {
+       del_timer_sync(&f->perturb_timer);
        tcf_exts_destroy(tp, &f->exts);
        tcf_em_tree_destroy(tp, &f->ematches);
        kfree(f);
@@ -532,11 +568,6 @@ static int flow_init(struct tcf_proto *tp)
 {
        struct flow_head *head;
 
-       if (!flow_hashrnd_initted) {
-               get_random_bytes(&flow_hashrnd, 4);
-               flow_hashrnd_initted = 1;
-       }
-
        head = kzalloc(sizeof(*head), GFP_KERNEL);
        if (head == NULL)
                return -ENOBUFS;
@@ -605,6 +636,9 @@ static int flow_dump(struct tcf_proto *tp, unsigned long fh,
        if (f->baseclass)
                NLA_PUT_U32(skb, TCA_FLOW_BASECLASS, f->baseclass);
 
+       if (f->perturb_period)
+               NLA_PUT_U32(skb, TCA_FLOW_PERTURB, f->perturb_period / HZ);
+
        if (tcf_exts_dump(skb, &f->exts, &flow_ext_map) < 0)
                goto nla_put_failure;
 #ifdef CONFIG_NET_EMATCH
index b976d9ed10e45a3a2e410a6b873f9128a18f6021..04c41504f84c44b8b84d8be9b6cc602d568d3ce1 100644 (file)
@@ -277,9 +277,8 @@ static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info *
        memcpy(&x->props.saddr, &p->saddr, sizeof(x->props.saddr));
        x->props.flags = p->flags;
 
-       if (!x->sel.family)
+       if (!x->sel.family && !(p->flags & XFRM_STATE_AF_UNSPEC))
                x->sel.family = p->family;
-
 }
 
 /*