aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/networking/ip-sysctl.txt256
-rw-r--r--drivers/net/arm/ixp4xx_eth.c3
-rw-r--r--drivers/net/tun.c6
-rw-r--r--drivers/net/wireless/libertas/scan.c4
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c11
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c11
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c7
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c9
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c9
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c1
-rw-r--r--include/linux/dccp.h6
-rw-r--r--include/linux/pkt_cls.h1
-rw-r--r--include/linux/xfrm.h1
-rw-r--r--include/net/netfilter/nf_conntrack.h20
-rw-r--r--net/dccp/ccids/ccid3.c14
-rw-r--r--net/dccp/ccids/lib/loss_interval.c10
-rw-r--r--net/dccp/ccids/lib/packet_history.c103
-rw-r--r--net/dccp/ccids/lib/packet_history.h30
-rw-r--r--net/dccp/dccp.h15
-rw-r--r--net/dccp/options.c14
-rw-r--r--net/ipv4/fib_trie.c17
-rw-r--r--net/ipv4/netfilter/nf_nat_snmp_basic.c2
-rw-r--r--net/ipv4/tcp_probe.c2
-rw-r--r--net/ipv6/exthdrs.c2
-rw-r--r--net/mac80211/rc80211_pid.h5
-rw-r--r--net/mac80211/rc80211_pid_algo.c31
-rw-r--r--net/netfilter/nf_conntrack_core.c13
-rw-r--r--net/netfilter/nf_conntrack_proto_tcp.c10
-rw-r--r--net/netlabel/netlabel_cipso_v4.c7
-rw-r--r--net/netlabel/netlabel_mgmt.c12
-rw-r--r--net/netlabel/netlabel_unlabeled.c6
-rw-r--r--net/sched/cls_flow.c52
-rw-r--r--net/xfrm/xfrm_user.c3
33 files changed, 461 insertions, 232 deletions
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index a40feaee62e..d84932650fd 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -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
diff --git a/drivers/net/arm/ixp4xx_eth.c b/drivers/net/arm/ixp4xx_eth.c
index c617b64c288..9b777d9433c 100644
--- a/drivers/net/arm/ixp4xx_eth.c
+++ b/drivers/net/arm/ixp4xx_eth.c
@@ -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);
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index aa4ee4439f0..2693f883ecd 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -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;
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
index 343ed38f772..4b274562f96 100644
--- a/drivers/net/wireless/libertas/scan.c
+++ b/drivers/net/wireless/libertas/scan.c
@@ -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;
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index 027580bfa7c..4c0538d6099 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -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);
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index 50f9e8f6cd6..aa6dfb811c7 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -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);
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 1423fd0bdbb..3558cb21074 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -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);
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 80c4445e628..70ef7bf434a 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -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);
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 6f89b4c75e1..34c6ff27afc 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -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);
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 68e2749b2ce..fcc532bb6a7 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -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);
}
diff --git a/include/linux/dccp.h b/include/linux/dccp.h
index aa0737019e3..6080449fbec 100644
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -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;
diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h
index 99efbed81fa..7cf7824df77 100644
--- a/include/linux/pkt_cls.h
+++ b/include/linux/pkt_cls.h
@@ -374,6 +374,7 @@ enum
TCA_FLOW_ACT,
TCA_FLOW_POLICE,
TCA_FLOW_EMATCHES,
+ TCA_FLOW_PERTURB,
__TCA_FLOW_MAX
};
diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h
index 2ca6bae8872..fb0c215a305 100644
--- a/include/linux/xfrm.h
+++ b/include/linux/xfrm.h
@@ -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 {
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index d5d76ec7abb..8f5b75734dd 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -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. */
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index a1929f33d70..f6756e0c9e6 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -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
diff --git a/net/dccp/ccids/lib/loss_interval.c b/net/dccp/ccids/lib/loss_interval.c
index 849e181e698..bcd6ac415bb 100644
--- a/net/dccp/ccids/lib/loss_interval.c
+++ b/net/dccp/ccids/lib/loss_interval.c
@@ -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;
diff --git a/net/dccp/ccids/lib/packet_history.c b/net/dccp/ccids/lib/packet_history.c
index 20af1a69342..6cc108afdc3 100644
--- a/net/dccp/ccids/lib/packet_history.c
+++ b/net/dccp/ccids/lib/packet_history.c
@@ -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);
diff --git a/net/dccp/ccids/lib/packet_history.h b/net/dccp/ccids/lib/packet_history.h
index c7eeda49cb2..461cc91cce8 100644
--- a/net/dccp/ccids/lib/packet_history.h
+++ b/net/dccp/ccids/lib/packet_history.h
@@ -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,
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index 1b2cea244e1..32617e0576c 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -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 */
diff --git a/net/dccp/options.c b/net/dccp/options.c
index 43bc24e761d..dc7c158a2f4 100644
--- a/net/dccp/options.c
+++ b/net/dccp/options.c
@@ -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;
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index d16ae4623be..f155a66d6eb 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -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;
}
diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c
index 7750c97fde7..ffeaffc3fff 100644
--- a/net/ipv4/netfilter/nf_nat_snmp_basic.c
+++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c
@@ -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;
diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c
index 5ff0ce6e9d3..7ddc30f0744 100644
--- a/net/ipv4/tcp_probe.c
+++ b/net/ipv4/tcp_probe.c
@@ -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;
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 602ea826f0a..9f1084b4c0e 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -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);
diff --git a/net/mac80211/rc80211_pid.h b/net/mac80211/rc80211_pid.h
index 2078803d358..0a9135b974b 100644
--- a/net/mac80211/rc80211_pid.h
+++ b/net/mac80211/rc80211_pid.h
@@ -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;
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c
index ca636295e62..a914ba73ccf 100644
--- a/net/mac80211/rc80211_pid_algo.c
+++ b/net/mac80211/rc80211_pid_algo.c
@@ -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);
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 212a0888408..28d03e64200 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -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);
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c
index 740acd6bc7d..420a10d8eb1 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -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:
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c
index fdc14a0d21a..9080c61b71a 100644
--- a/net/netlabel/netlabel_cipso_v4.c
+++ b/net/netlabel/netlabel_cipso_v4.c
@@ -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 */
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
index 22c19126780..44be5d5261f 100644
--- a/net/netlabel/netlabel_mgmt.c
+++ b/net/netlabel/netlabel_mgmt.c
@@ -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);
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index 52b2611a6eb..56f80872924 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -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);
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
index 971b867e048..8f63a1a9401 100644
--- a/net/sched/cls_flow.c
+++ b/net/sched/cls_flow.c
@@ -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
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index b976d9ed10e..04c41504f84 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -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;
-
}
/*