diff options
Diffstat (limited to 'net')
131 files changed, 1197 insertions, 538 deletions
diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index 5f27f8e3025..f1f2f7bb666 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c | |||
@@ -167,6 +167,8 @@ struct sk_buff *vlan_untag(struct sk_buff *skb) | |||
167 | if (unlikely(!skb)) | 167 | if (unlikely(!skb)) |
168 | goto err_free; | 168 | goto err_free; |
169 | 169 | ||
170 | skb_reset_network_header(skb); | ||
171 | skb_reset_transport_header(skb); | ||
170 | return skb; | 172 | return skb; |
171 | 173 | ||
172 | err_free: | 174 | err_free: |
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 934e221c1d0..9d40a071d03 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
@@ -695,7 +695,7 @@ void vlan_setup(struct net_device *dev) | |||
695 | ether_setup(dev); | 695 | ether_setup(dev); |
696 | 696 | ||
697 | dev->priv_flags |= IFF_802_1Q_VLAN; | 697 | dev->priv_flags |= IFF_802_1Q_VLAN; |
698 | dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; | 698 | dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING); |
699 | dev->tx_queue_len = 0; | 699 | dev->tx_queue_len = 0; |
700 | 700 | ||
701 | dev->netdev_ops = &vlan_netdev_ops; | 701 | dev->netdev_ops = &vlan_netdev_ops; |
diff --git a/net/atm/atm_misc.c b/net/atm/atm_misc.c index fc63526d869..f41f02656ff 100644 --- a/net/atm/atm_misc.c +++ b/net/atm/atm_misc.c | |||
@@ -9,7 +9,7 @@ | |||
9 | #include <linux/sonet.h> | 9 | #include <linux/sonet.h> |
10 | #include <linux/bitops.h> | 10 | #include <linux/bitops.h> |
11 | #include <linux/errno.h> | 11 | #include <linux/errno.h> |
12 | #include <asm/atomic.h> | 12 | #include <linux/atomic.h> |
13 | 13 | ||
14 | int atm_charge(struct atm_vcc *vcc, int truesize) | 14 | int atm_charge(struct atm_vcc *vcc, int truesize) |
15 | { | 15 | { |
diff --git a/net/atm/br2684.c b/net/atm/br2684.c index 2252c2085da..d07223c834a 100644 --- a/net/atm/br2684.c +++ b/net/atm/br2684.c | |||
@@ -242,8 +242,6 @@ static int br2684_xmit_vcc(struct sk_buff *skb, struct net_device *dev, | |||
242 | if (brdev->payload == p_bridged) { | 242 | if (brdev->payload == p_bridged) { |
243 | skb_push(skb, 2); | 243 | skb_push(skb, 2); |
244 | memset(skb->data, 0, 2); | 244 | memset(skb->data, 0, 2); |
245 | } else { /* p_routed */ | ||
246 | skb_pull(skb, ETH_HLEN); | ||
247 | } | 245 | } |
248 | } | 246 | } |
249 | skb_debug(skb); | 247 | skb_debug(skb); |
@@ -560,12 +558,13 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg) | |||
560 | spin_unlock_irqrestore(&rq->lock, flags); | 558 | spin_unlock_irqrestore(&rq->lock, flags); |
561 | 559 | ||
562 | skb_queue_walk_safe(&queue, skb, tmp) { | 560 | skb_queue_walk_safe(&queue, skb, tmp) { |
563 | struct net_device *dev = skb->dev; | 561 | struct net_device *dev; |
562 | |||
563 | br2684_push(atmvcc, skb); | ||
564 | dev = skb->dev; | ||
564 | 565 | ||
565 | dev->stats.rx_bytes -= skb->len; | 566 | dev->stats.rx_bytes -= skb->len; |
566 | dev->stats.rx_packets--; | 567 | dev->stats.rx_packets--; |
567 | |||
568 | br2684_push(atmvcc, skb); | ||
569 | } | 568 | } |
570 | 569 | ||
571 | /* initialize netdev carrier state */ | 570 | /* initialize netdev carrier state */ |
diff --git a/net/atm/clip.c b/net/atm/clip.c index 4bc8c67ecb1..852394072fa 100644 --- a/net/atm/clip.c +++ b/net/atm/clip.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include <linux/uaccess.h> | 37 | #include <linux/uaccess.h> |
38 | #include <asm/byteorder.h> /* for htons etc. */ | 38 | #include <asm/byteorder.h> /* for htons etc. */ |
39 | #include <asm/system.h> /* save/restore_flags */ | 39 | #include <asm/system.h> /* save/restore_flags */ |
40 | #include <asm/atomic.h> | 40 | #include <linux/atomic.h> |
41 | 41 | ||
42 | #include "common.h" | 42 | #include "common.h" |
43 | #include "resources.h" | 43 | #include "resources.h" |
diff --git a/net/atm/common.c b/net/atm/common.c index 22b963d06a1..14ff9fe3998 100644 --- a/net/atm/common.c +++ b/net/atm/common.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #include <linux/uaccess.h> | 23 | #include <linux/uaccess.h> |
24 | #include <linux/poll.h> | 24 | #include <linux/poll.h> |
25 | 25 | ||
26 | #include <asm/atomic.h> | 26 | #include <linux/atomic.h> |
27 | 27 | ||
28 | #include "resources.h" /* atm_find_dev */ | 28 | #include "resources.h" /* atm_find_dev */ |
29 | #include "common.h" /* prototypes */ | 29 | #include "common.h" /* prototypes */ |
diff --git a/net/atm/lec.c b/net/atm/lec.c index ba48daa68c1..215c9fad7cd 100644 --- a/net/atm/lec.c +++ b/net/atm/lec.c | |||
@@ -1335,7 +1335,7 @@ static void lane2_associate_ind(struct net_device *dev, const u8 *mac_addr, | |||
1335 | #include <linux/types.h> | 1335 | #include <linux/types.h> |
1336 | #include <linux/timer.h> | 1336 | #include <linux/timer.h> |
1337 | #include <linux/param.h> | 1337 | #include <linux/param.h> |
1338 | #include <asm/atomic.h> | 1338 | #include <linux/atomic.h> |
1339 | #include <linux/inetdevice.h> | 1339 | #include <linux/inetdevice.h> |
1340 | #include <net/route.h> | 1340 | #include <net/route.h> |
1341 | 1341 | ||
diff --git a/net/atm/proc.c b/net/atm/proc.c index be3afdefec5..0d020de8d23 100644 --- a/net/atm/proc.c +++ b/net/atm/proc.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include <net/atmclip.h> | 27 | #include <net/atmclip.h> |
28 | #include <linux/uaccess.h> | 28 | #include <linux/uaccess.h> |
29 | #include <linux/param.h> /* for HZ */ | 29 | #include <linux/param.h> /* for HZ */ |
30 | #include <asm/atomic.h> | 30 | #include <linux/atomic.h> |
31 | #include "resources.h" | 31 | #include "resources.h" |
32 | #include "common.h" /* atm_proc_init prototype */ | 32 | #include "common.h" /* atm_proc_init prototype */ |
33 | #include "signaling.h" /* to get sigd - ugly too */ | 33 | #include "signaling.h" /* to get sigd - ugly too */ |
diff --git a/net/bluetooth/bnep/netdev.c b/net/bluetooth/bnep/netdev.c index 8c100c9dae2..d4f5dff7c95 100644 --- a/net/bluetooth/bnep/netdev.c +++ b/net/bluetooth/bnep/netdev.c | |||
@@ -231,6 +231,7 @@ void bnep_net_setup(struct net_device *dev) | |||
231 | dev->addr_len = ETH_ALEN; | 231 | dev->addr_len = ETH_ALEN; |
232 | 232 | ||
233 | ether_setup(dev); | 233 | ether_setup(dev); |
234 | dev->priv_flags &= ~IFF_TX_SKB_SHARING; | ||
234 | dev->netdev_ops = &bnep_netdev_ops; | 235 | dev->netdev_ops = &bnep_netdev_ops; |
235 | 236 | ||
236 | dev->watchdog_timeo = HZ * 2; | 237 | dev->watchdog_timeo = HZ * 2; |
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index e0dfbc151dd..68def3b7fb4 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c | |||
@@ -21,7 +21,7 @@ | |||
21 | #include <linux/jhash.h> | 21 | #include <linux/jhash.h> |
22 | #include <linux/random.h> | 22 | #include <linux/random.h> |
23 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
24 | #include <asm/atomic.h> | 24 | #include <linux/atomic.h> |
25 | #include <asm/unaligned.h> | 25 | #include <asm/unaligned.h> |
26 | #include "br_private.h" | 26 | #include "br_private.h" |
27 | 27 | ||
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 1bacca4cb67..e73815456ad 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
@@ -231,6 +231,7 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br, | |||
231 | int br_add_bridge(struct net *net, const char *name) | 231 | int br_add_bridge(struct net *net, const char *name) |
232 | { | 232 | { |
233 | struct net_device *dev; | 233 | struct net_device *dev; |
234 | int res; | ||
234 | 235 | ||
235 | dev = alloc_netdev(sizeof(struct net_bridge), name, | 236 | dev = alloc_netdev(sizeof(struct net_bridge), name, |
236 | br_dev_setup); | 237 | br_dev_setup); |
@@ -240,7 +241,10 @@ int br_add_bridge(struct net *net, const char *name) | |||
240 | 241 | ||
241 | dev_net_set(dev, net); | 242 | dev_net_set(dev, net); |
242 | 243 | ||
243 | return register_netdev(dev); | 244 | res = register_netdev(dev); |
245 | if (res) | ||
246 | free_netdev(dev); | ||
247 | return res; | ||
244 | } | 248 | } |
245 | 249 | ||
246 | int br_del_bridge(struct net *net, const char *name) | 250 | int br_del_bridge(struct net *net, const char *name) |
@@ -388,7 +392,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) | |||
388 | br_ifinfo_notify(RTM_NEWLINK, p); | 392 | br_ifinfo_notify(RTM_NEWLINK, p); |
389 | 393 | ||
390 | if (changed_addr) | 394 | if (changed_addr) |
391 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); | 395 | call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev); |
392 | 396 | ||
393 | dev_set_mtu(br->dev, br_min_mtu(br)); | 397 | dev_set_mtu(br->dev, br_min_mtu(br)); |
394 | 398 | ||
@@ -417,6 +421,7 @@ put_back: | |||
417 | int br_del_if(struct net_bridge *br, struct net_device *dev) | 421 | int br_del_if(struct net_bridge *br, struct net_device *dev) |
418 | { | 422 | { |
419 | struct net_bridge_port *p; | 423 | struct net_bridge_port *p; |
424 | bool changed_addr; | ||
420 | 425 | ||
421 | p = br_port_get_rtnl(dev); | 426 | p = br_port_get_rtnl(dev); |
422 | if (!p || p->br != br) | 427 | if (!p || p->br != br) |
@@ -425,9 +430,12 @@ int br_del_if(struct net_bridge *br, struct net_device *dev) | |||
425 | del_nbp(p); | 430 | del_nbp(p); |
426 | 431 | ||
427 | spin_lock_bh(&br->lock); | 432 | spin_lock_bh(&br->lock); |
428 | br_stp_recalculate_bridge_id(br); | 433 | changed_addr = br_stp_recalculate_bridge_id(br); |
429 | spin_unlock_bh(&br->lock); | 434 | spin_unlock_bh(&br->lock); |
430 | 435 | ||
436 | if (changed_addr) | ||
437 | call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev); | ||
438 | |||
431 | netdev_update_features(br->dev); | 439 | netdev_update_features(br->dev); |
432 | 440 | ||
433 | return 0; | 441 | return 0; |
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 6814083a92f..5b1ed1ba9aa 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c | |||
@@ -188,6 +188,8 @@ static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
188 | 188 | ||
189 | p->state = new_state; | 189 | p->state = new_state; |
190 | br_log_state(p); | 190 | br_log_state(p); |
191 | br_ifinfo_notify(RTM_NEWLINK, p); | ||
192 | |||
191 | return 0; | 193 | return 0; |
192 | } | 194 | } |
193 | 195 | ||
diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c index 6545ee9591d..a76b6213555 100644 --- a/net/bridge/br_notify.c +++ b/net/bridge/br_notify.c | |||
@@ -34,6 +34,7 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v | |||
34 | struct net_device *dev = ptr; | 34 | struct net_device *dev = ptr; |
35 | struct net_bridge_port *p; | 35 | struct net_bridge_port *p; |
36 | struct net_bridge *br; | 36 | struct net_bridge *br; |
37 | bool changed_addr; | ||
37 | int err; | 38 | int err; |
38 | 39 | ||
39 | /* register of bridge completed, add sysfs entries */ | 40 | /* register of bridge completed, add sysfs entries */ |
@@ -57,8 +58,12 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v | |||
57 | case NETDEV_CHANGEADDR: | 58 | case NETDEV_CHANGEADDR: |
58 | spin_lock_bh(&br->lock); | 59 | spin_lock_bh(&br->lock); |
59 | br_fdb_changeaddr(p, dev->dev_addr); | 60 | br_fdb_changeaddr(p, dev->dev_addr); |
60 | br_stp_recalculate_bridge_id(br); | 61 | changed_addr = br_stp_recalculate_bridge_id(br); |
61 | spin_unlock_bh(&br->lock); | 62 | spin_unlock_bh(&br->lock); |
63 | |||
64 | if (changed_addr) | ||
65 | call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev); | ||
66 | |||
62 | break; | 67 | break; |
63 | 68 | ||
64 | case NETDEV_CHANGE: | 69 | case NETDEV_CHANGE: |
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 54578f274d8..78cc364997d 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
@@ -124,6 +124,7 @@ struct net_bridge_port | |||
124 | bridge_id designated_bridge; | 124 | bridge_id designated_bridge; |
125 | u32 path_cost; | 125 | u32 path_cost; |
126 | u32 designated_cost; | 126 | u32 designated_cost; |
127 | unsigned long designated_age; | ||
127 | 128 | ||
128 | struct timer_list forward_delay_timer; | 129 | struct timer_list forward_delay_timer; |
129 | struct timer_list hold_timer; | 130 | struct timer_list hold_timer; |
diff --git a/net/bridge/br_private_stp.h b/net/bridge/br_private_stp.h index 642ef47a867..05ed9bc7e42 100644 --- a/net/bridge/br_private_stp.h +++ b/net/bridge/br_private_stp.h | |||
@@ -56,7 +56,8 @@ extern void br_become_root_bridge(struct net_bridge *br); | |||
56 | extern void br_config_bpdu_generation(struct net_bridge *); | 56 | extern void br_config_bpdu_generation(struct net_bridge *); |
57 | extern void br_configuration_update(struct net_bridge *); | 57 | extern void br_configuration_update(struct net_bridge *); |
58 | extern void br_port_state_selection(struct net_bridge *); | 58 | extern void br_port_state_selection(struct net_bridge *); |
59 | extern void br_received_config_bpdu(struct net_bridge_port *p, struct br_config_bpdu *bpdu); | 59 | extern void br_received_config_bpdu(struct net_bridge_port *p, |
60 | const struct br_config_bpdu *bpdu); | ||
60 | extern void br_received_tcn_bpdu(struct net_bridge_port *p); | 61 | extern void br_received_tcn_bpdu(struct net_bridge_port *p); |
61 | extern void br_transmit_config(struct net_bridge_port *p); | 62 | extern void br_transmit_config(struct net_bridge_port *p); |
62 | extern void br_transmit_tcn(struct net_bridge *br); | 63 | extern void br_transmit_tcn(struct net_bridge *br); |
diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c index bb4383e84de..ad0a3f7cf6c 100644 --- a/net/bridge/br_stp.c +++ b/net/bridge/br_stp.c | |||
@@ -109,7 +109,6 @@ static void br_root_selection(struct net_bridge *br) | |||
109 | list_for_each_entry(p, &br->port_list, list) { | 109 | list_for_each_entry(p, &br->port_list, list) { |
110 | if (br_should_become_root_port(p, root_port)) | 110 | if (br_should_become_root_port(p, root_port)) |
111 | root_port = p->port_no; | 111 | root_port = p->port_no; |
112 | |||
113 | } | 112 | } |
114 | 113 | ||
115 | br->root_port = root_port; | 114 | br->root_port = root_port; |
@@ -145,7 +144,6 @@ void br_transmit_config(struct net_bridge_port *p) | |||
145 | struct br_config_bpdu bpdu; | 144 | struct br_config_bpdu bpdu; |
146 | struct net_bridge *br; | 145 | struct net_bridge *br; |
147 | 146 | ||
148 | |||
149 | if (timer_pending(&p->hold_timer)) { | 147 | if (timer_pending(&p->hold_timer)) { |
150 | p->config_pending = 1; | 148 | p->config_pending = 1; |
151 | return; | 149 | return; |
@@ -164,8 +162,7 @@ void br_transmit_config(struct net_bridge_port *p) | |||
164 | else { | 162 | else { |
165 | struct net_bridge_port *root | 163 | struct net_bridge_port *root |
166 | = br_get_port(br, br->root_port); | 164 | = br_get_port(br, br->root_port); |
167 | bpdu.message_age = br->max_age | 165 | bpdu.message_age = (jiffies - root->designated_age) |
168 | - (root->message_age_timer.expires - jiffies) | ||
169 | + MESSAGE_AGE_INCR; | 166 | + MESSAGE_AGE_INCR; |
170 | } | 167 | } |
171 | bpdu.max_age = br->max_age; | 168 | bpdu.max_age = br->max_age; |
@@ -182,20 +179,21 @@ void br_transmit_config(struct net_bridge_port *p) | |||
182 | } | 179 | } |
183 | 180 | ||
184 | /* called under bridge lock */ | 181 | /* called under bridge lock */ |
185 | static inline void br_record_config_information(struct net_bridge_port *p, | 182 | static void br_record_config_information(struct net_bridge_port *p, |
186 | const struct br_config_bpdu *bpdu) | 183 | const struct br_config_bpdu *bpdu) |
187 | { | 184 | { |
188 | p->designated_root = bpdu->root; | 185 | p->designated_root = bpdu->root; |
189 | p->designated_cost = bpdu->root_path_cost; | 186 | p->designated_cost = bpdu->root_path_cost; |
190 | p->designated_bridge = bpdu->bridge_id; | 187 | p->designated_bridge = bpdu->bridge_id; |
191 | p->designated_port = bpdu->port_id; | 188 | p->designated_port = bpdu->port_id; |
189 | p->designated_age = jiffies + bpdu->message_age; | ||
192 | 190 | ||
193 | mod_timer(&p->message_age_timer, jiffies | 191 | mod_timer(&p->message_age_timer, jiffies |
194 | + (p->br->max_age - bpdu->message_age)); | 192 | + (p->br->max_age - bpdu->message_age)); |
195 | } | 193 | } |
196 | 194 | ||
197 | /* called under bridge lock */ | 195 | /* called under bridge lock */ |
198 | static inline void br_record_config_timeout_values(struct net_bridge *br, | 196 | static void br_record_config_timeout_values(struct net_bridge *br, |
199 | const struct br_config_bpdu *bpdu) | 197 | const struct br_config_bpdu *bpdu) |
200 | { | 198 | { |
201 | br->max_age = bpdu->max_age; | 199 | br->max_age = bpdu->max_age; |
@@ -254,7 +252,8 @@ static void br_designated_port_selection(struct net_bridge *br) | |||
254 | } | 252 | } |
255 | 253 | ||
256 | /* called under bridge lock */ | 254 | /* called under bridge lock */ |
257 | static int br_supersedes_port_info(struct net_bridge_port *p, struct br_config_bpdu *bpdu) | 255 | static int br_supersedes_port_info(const struct net_bridge_port *p, |
256 | const struct br_config_bpdu *bpdu) | ||
258 | { | 257 | { |
259 | int t; | 258 | int t; |
260 | 259 | ||
@@ -285,7 +284,7 @@ static int br_supersedes_port_info(struct net_bridge_port *p, struct br_config_b | |||
285 | } | 284 | } |
286 | 285 | ||
287 | /* called under bridge lock */ | 286 | /* called under bridge lock */ |
288 | static inline void br_topology_change_acknowledged(struct net_bridge *br) | 287 | static void br_topology_change_acknowledged(struct net_bridge *br) |
289 | { | 288 | { |
290 | br->topology_change_detected = 0; | 289 | br->topology_change_detected = 0; |
291 | del_timer(&br->tcn_timer); | 290 | del_timer(&br->tcn_timer); |
@@ -327,7 +326,7 @@ void br_config_bpdu_generation(struct net_bridge *br) | |||
327 | } | 326 | } |
328 | 327 | ||
329 | /* called under bridge lock */ | 328 | /* called under bridge lock */ |
330 | static inline void br_reply(struct net_bridge_port *p) | 329 | static void br_reply(struct net_bridge_port *p) |
331 | { | 330 | { |
332 | br_transmit_config(p); | 331 | br_transmit_config(p); |
333 | } | 332 | } |
@@ -363,6 +362,8 @@ static void br_make_blocking(struct net_bridge_port *p) | |||
363 | 362 | ||
364 | p->state = BR_STATE_BLOCKING; | 363 | p->state = BR_STATE_BLOCKING; |
365 | br_log_state(p); | 364 | br_log_state(p); |
365 | br_ifinfo_notify(RTM_NEWLINK, p); | ||
366 | |||
366 | del_timer(&p->forward_delay_timer); | 367 | del_timer(&p->forward_delay_timer); |
367 | } | 368 | } |
368 | } | 369 | } |
@@ -379,15 +380,14 @@ static void br_make_forwarding(struct net_bridge_port *p) | |||
379 | p->state = BR_STATE_FORWARDING; | 380 | p->state = BR_STATE_FORWARDING; |
380 | br_topology_change_detection(br); | 381 | br_topology_change_detection(br); |
381 | del_timer(&p->forward_delay_timer); | 382 | del_timer(&p->forward_delay_timer); |
382 | } | 383 | } else if (br->stp_enabled == BR_KERNEL_STP) |
383 | else if (br->stp_enabled == BR_KERNEL_STP) | ||
384 | p->state = BR_STATE_LISTENING; | 384 | p->state = BR_STATE_LISTENING; |
385 | else | 385 | else |
386 | p->state = BR_STATE_LEARNING; | 386 | p->state = BR_STATE_LEARNING; |
387 | 387 | ||
388 | br_multicast_enable_port(p); | 388 | br_multicast_enable_port(p); |
389 | |||
390 | br_log_state(p); | 389 | br_log_state(p); |
390 | br_ifinfo_notify(RTM_NEWLINK, p); | ||
391 | 391 | ||
392 | if (br->forward_delay != 0) | 392 | if (br->forward_delay != 0) |
393 | mod_timer(&p->forward_delay_timer, jiffies + br->forward_delay); | 393 | mod_timer(&p->forward_delay_timer, jiffies + br->forward_delay); |
@@ -431,14 +431,15 @@ void br_port_state_selection(struct net_bridge *br) | |||
431 | } | 431 | } |
432 | 432 | ||
433 | /* called under bridge lock */ | 433 | /* called under bridge lock */ |
434 | static inline void br_topology_change_acknowledge(struct net_bridge_port *p) | 434 | static void br_topology_change_acknowledge(struct net_bridge_port *p) |
435 | { | 435 | { |
436 | p->topology_change_ack = 1; | 436 | p->topology_change_ack = 1; |
437 | br_transmit_config(p); | 437 | br_transmit_config(p); |
438 | } | 438 | } |
439 | 439 | ||
440 | /* called under bridge lock */ | 440 | /* called under bridge lock */ |
441 | void br_received_config_bpdu(struct net_bridge_port *p, struct br_config_bpdu *bpdu) | 441 | void br_received_config_bpdu(struct net_bridge_port *p, |
442 | const struct br_config_bpdu *bpdu) | ||
442 | { | 443 | { |
443 | struct net_bridge *br; | 444 | struct net_bridge *br; |
444 | int was_root; | 445 | int was_root; |
diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c index 289646ec9b7..e16aade51ae 100644 --- a/net/bridge/br_stp_bpdu.c +++ b/net/bridge/br_stp_bpdu.c | |||
@@ -210,10 +210,19 @@ void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb, | |||
210 | bpdu.hello_time = br_get_ticks(buf+28); | 210 | bpdu.hello_time = br_get_ticks(buf+28); |
211 | bpdu.forward_delay = br_get_ticks(buf+30); | 211 | bpdu.forward_delay = br_get_ticks(buf+30); |
212 | 212 | ||
213 | br_received_config_bpdu(p, &bpdu); | 213 | if (bpdu.message_age > bpdu.max_age) { |
214 | } | 214 | if (net_ratelimit()) |
215 | br_notice(p->br, | ||
216 | "port %u config from %pM" | ||
217 | " (message_age %ul > max_age %ul)\n", | ||
218 | p->port_no, | ||
219 | eth_hdr(skb)->h_source, | ||
220 | bpdu.message_age, bpdu.max_age); | ||
221 | goto out; | ||
222 | } | ||
215 | 223 | ||
216 | else if (buf[0] == BPDU_TYPE_TCN) { | 224 | br_received_config_bpdu(p, &bpdu); |
225 | } else if (buf[0] == BPDU_TYPE_TCN) { | ||
217 | br_received_tcn_bpdu(p); | 226 | br_received_tcn_bpdu(p); |
218 | } | 227 | } |
219 | out: | 228 | out: |
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c index 6f615b8192f..10eda3cd1d7 100644 --- a/net/bridge/br_stp_if.c +++ b/net/bridge/br_stp_if.c | |||
@@ -88,6 +88,7 @@ void br_stp_enable_port(struct net_bridge_port *p) | |||
88 | br_init_port(p); | 88 | br_init_port(p); |
89 | br_port_state_selection(p->br); | 89 | br_port_state_selection(p->br); |
90 | br_log_state(p); | 90 | br_log_state(p); |
91 | br_ifinfo_notify(RTM_NEWLINK, p); | ||
91 | } | 92 | } |
92 | 93 | ||
93 | /* called under bridge lock */ | 94 | /* called under bridge lock */ |
@@ -104,6 +105,8 @@ void br_stp_disable_port(struct net_bridge_port *p) | |||
104 | p->topology_change_ack = 0; | 105 | p->topology_change_ack = 0; |
105 | p->config_pending = 0; | 106 | p->config_pending = 0; |
106 | 107 | ||
108 | br_ifinfo_notify(RTM_NEWLINK, p); | ||
109 | |||
107 | del_timer(&p->message_age_timer); | 110 | del_timer(&p->message_age_timer); |
108 | del_timer(&p->forward_delay_timer); | 111 | del_timer(&p->forward_delay_timer); |
109 | del_timer(&p->hold_timer); | 112 | del_timer(&p->hold_timer); |
diff --git a/net/bridge/br_stp_timer.c b/net/bridge/br_stp_timer.c index 3e965140051..58de2a0f997 100644 --- a/net/bridge/br_stp_timer.c +++ b/net/bridge/br_stp_timer.c | |||
@@ -97,6 +97,7 @@ static void br_forward_delay_timer_expired(unsigned long arg) | |||
97 | netif_carrier_on(br->dev); | 97 | netif_carrier_on(br->dev); |
98 | } | 98 | } |
99 | br_log_state(p); | 99 | br_log_state(p); |
100 | br_ifinfo_notify(RTM_NEWLINK, p); | ||
100 | spin_unlock(&br->lock); | 101 | spin_unlock(&br->lock); |
101 | } | 102 | } |
102 | 103 | ||
diff --git a/net/bridge/netfilter/ebt_ulog.c b/net/bridge/netfilter/ebt_ulog.c index 26377e96fa1..bf2a333ca7c 100644 --- a/net/bridge/netfilter/ebt_ulog.c +++ b/net/bridge/netfilter/ebt_ulog.c | |||
@@ -216,7 +216,6 @@ unlock: | |||
216 | nlmsg_failure: | 216 | nlmsg_failure: |
217 | pr_debug("error during NLMSG_PUT. This should " | 217 | pr_debug("error during NLMSG_PUT. This should " |
218 | "not happen, please report to author.\n"); | 218 | "not happen, please report to author.\n"); |
219 | goto unlock; | ||
220 | alloc_failure: | 219 | alloc_failure: |
221 | goto unlock; | 220 | goto unlock; |
222 | } | 221 | } |
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 2b5ca1a0054..5864cc49136 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c | |||
@@ -1198,7 +1198,8 @@ ebt_register_table(struct net *net, const struct ebt_table *input_table) | |||
1198 | 1198 | ||
1199 | if (table->check && table->check(newinfo, table->valid_hooks)) { | 1199 | if (table->check && table->check(newinfo, table->valid_hooks)) { |
1200 | BUGPRINT("The table doesn't like its own initial data, lol\n"); | 1200 | BUGPRINT("The table doesn't like its own initial data, lol\n"); |
1201 | return ERR_PTR(-EINVAL); | 1201 | ret = -EINVAL; |
1202 | goto free_chainstack; | ||
1202 | } | 1203 | } |
1203 | 1204 | ||
1204 | table->private = newinfo; | 1205 | table->private = newinfo; |
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 78b55f49de7..c340e2e0765 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c | |||
@@ -486,13 +486,10 @@ static void prepare_write_message(struct ceph_connection *con) | |||
486 | m = list_first_entry(&con->out_queue, | 486 | m = list_first_entry(&con->out_queue, |
487 | struct ceph_msg, list_head); | 487 | struct ceph_msg, list_head); |
488 | con->out_msg = m; | 488 | con->out_msg = m; |
489 | if (test_bit(LOSSYTX, &con->state)) { | 489 | |
490 | list_del_init(&m->list_head); | 490 | /* put message on sent list */ |
491 | } else { | 491 | ceph_msg_get(m); |
492 | /* put message on sent list */ | 492 | list_move_tail(&m->list_head, &con->out_sent); |
493 | ceph_msg_get(m); | ||
494 | list_move_tail(&m->list_head, &con->out_sent); | ||
495 | } | ||
496 | 493 | ||
497 | /* | 494 | /* |
498 | * only assign outgoing seq # if we haven't sent this message | 495 | * only assign outgoing seq # if we haven't sent this message |
@@ -1399,6 +1396,7 @@ static void process_ack(struct ceph_connection *con) | |||
1399 | break; | 1396 | break; |
1400 | dout("got ack for seq %llu type %d at %p\n", seq, | 1397 | dout("got ack for seq %llu type %d at %p\n", seq, |
1401 | le16_to_cpu(m->hdr.type), m); | 1398 | le16_to_cpu(m->hdr.type), m); |
1399 | m->ack_stamp = jiffies; | ||
1402 | ceph_msg_remove(m); | 1400 | ceph_msg_remove(m); |
1403 | } | 1401 | } |
1404 | prepare_read_tag(con); | 1402 | prepare_read_tag(con); |
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 7330c2757c0..ce310eee708 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c | |||
@@ -1085,9 +1085,15 @@ static void handle_timeout(struct work_struct *work) | |||
1085 | req = list_entry(osdc->req_lru.next, struct ceph_osd_request, | 1085 | req = list_entry(osdc->req_lru.next, struct ceph_osd_request, |
1086 | r_req_lru_item); | 1086 | r_req_lru_item); |
1087 | 1087 | ||
1088 | /* hasn't been long enough since we sent it? */ | ||
1088 | if (time_before(jiffies, req->r_stamp + timeout)) | 1089 | if (time_before(jiffies, req->r_stamp + timeout)) |
1089 | break; | 1090 | break; |
1090 | 1091 | ||
1092 | /* hasn't been long enough since it was acked? */ | ||
1093 | if (req->r_request->ack_stamp == 0 || | ||
1094 | time_before(jiffies, req->r_request->ack_stamp + timeout)) | ||
1095 | break; | ||
1096 | |||
1091 | BUG_ON(req == last_req && req->r_stamp == last_stamp); | 1097 | BUG_ON(req == last_req && req->r_stamp == last_stamp); |
1092 | last_req = req; | 1098 | last_req = req; |
1093 | last_stamp = req->r_stamp; | 1099 | last_stamp = req->r_stamp; |
diff --git a/net/core/Makefile b/net/core/Makefile index 8a04dd22cf7..0d357b1c4e5 100644 --- a/net/core/Makefile +++ b/net/core/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \ | 5 | obj-y := sock.o request_sock.o skbuff.o iovec.o datagram.o stream.o scm.o \ |
6 | gen_stats.o gen_estimator.o net_namespace.o | 6 | gen_stats.o gen_estimator.o net_namespace.o secure_seq.o |
7 | 7 | ||
8 | obj-$(CONFIG_SYSCTL) += sysctl_net_core.o | 8 | obj-$(CONFIG_SYSCTL) += sysctl_net_core.o |
9 | 9 | ||
diff --git a/net/core/dev.c b/net/core/dev.c index 9444c5cb413..17d67b579be 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -4497,10 +4497,10 @@ void __dev_set_rx_mode(struct net_device *dev) | |||
4497 | */ | 4497 | */ |
4498 | if (!netdev_uc_empty(dev) && !dev->uc_promisc) { | 4498 | if (!netdev_uc_empty(dev) && !dev->uc_promisc) { |
4499 | __dev_set_promiscuity(dev, 1); | 4499 | __dev_set_promiscuity(dev, 1); |
4500 | dev->uc_promisc = 1; | 4500 | dev->uc_promisc = true; |
4501 | } else if (netdev_uc_empty(dev) && dev->uc_promisc) { | 4501 | } else if (netdev_uc_empty(dev) && dev->uc_promisc) { |
4502 | __dev_set_promiscuity(dev, -1); | 4502 | __dev_set_promiscuity(dev, -1); |
4503 | dev->uc_promisc = 0; | 4503 | dev->uc_promisc = false; |
4504 | } | 4504 | } |
4505 | 4505 | ||
4506 | if (ops->ndo_set_multicast_list) | 4506 | if (ops->ndo_set_multicast_list) |
diff --git a/net/core/flow.c b/net/core/flow.c index 990703b8863..bf32c33cad3 100644 --- a/net/core/flow.c +++ b/net/core/flow.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <linux/cpumask.h> | 22 | #include <linux/cpumask.h> |
23 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
24 | #include <net/flow.h> | 24 | #include <net/flow.h> |
25 | #include <asm/atomic.h> | 25 | #include <linux/atomic.h> |
26 | #include <linux/security.h> | 26 | #include <linux/security.h> |
27 | 27 | ||
28 | struct flow_cache_entry { | 28 | struct flow_cache_entry { |
diff --git a/net/core/link_watch.c b/net/core/link_watch.c index a7b34213186..357bd4ee4ba 100644 --- a/net/core/link_watch.c +++ b/net/core/link_watch.c | |||
@@ -126,7 +126,7 @@ static void linkwatch_schedule_work(int urgent) | |||
126 | return; | 126 | return; |
127 | 127 | ||
128 | /* It's already running which is good enough. */ | 128 | /* It's already running which is good enough. */ |
129 | if (!cancel_delayed_work(&linkwatch_work)) | 129 | if (!__cancel_delayed_work(&linkwatch_work)) |
130 | return; | 130 | return; |
131 | 131 | ||
132 | /* Otherwise we reschedule it again for immediate execution. */ | 132 | /* Otherwise we reschedule it again for immediate execution. */ |
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index f76079cd750..e35a6fbb811 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
@@ -1070,7 +1070,9 @@ static ssize_t pktgen_if_write(struct file *file, | |||
1070 | len = num_arg(&user_buffer[i], 10, &value); | 1070 | len = num_arg(&user_buffer[i], 10, &value); |
1071 | if (len < 0) | 1071 | if (len < 0) |
1072 | return len; | 1072 | return len; |
1073 | 1073 | if ((value > 0) && | |
1074 | (!(pkt_dev->odev->priv_flags & IFF_TX_SKB_SHARING))) | ||
1075 | return -ENOTSUPP; | ||
1074 | i += len; | 1076 | i += len; |
1075 | pkt_dev->clone_skb = value; | 1077 | pkt_dev->clone_skb = value; |
1076 | 1078 | ||
@@ -3555,7 +3557,6 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) | |||
3555 | pkt_dev->min_pkt_size = ETH_ZLEN; | 3557 | pkt_dev->min_pkt_size = ETH_ZLEN; |
3556 | pkt_dev->max_pkt_size = ETH_ZLEN; | 3558 | pkt_dev->max_pkt_size = ETH_ZLEN; |
3557 | pkt_dev->nfrags = 0; | 3559 | pkt_dev->nfrags = 0; |
3558 | pkt_dev->clone_skb = pg_clone_skb_d; | ||
3559 | pkt_dev->delay = pg_delay_d; | 3560 | pkt_dev->delay = pg_delay_d; |
3560 | pkt_dev->count = pg_count_d; | 3561 | pkt_dev->count = pg_count_d; |
3561 | pkt_dev->sofar = 0; | 3562 | pkt_dev->sofar = 0; |
@@ -3563,7 +3564,6 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) | |||
3563 | pkt_dev->udp_src_max = 9; | 3564 | pkt_dev->udp_src_max = 9; |
3564 | pkt_dev->udp_dst_min = 9; | 3565 | pkt_dev->udp_dst_min = 9; |
3565 | pkt_dev->udp_dst_max = 9; | 3566 | pkt_dev->udp_dst_max = 9; |
3566 | |||
3567 | pkt_dev->vlan_p = 0; | 3567 | pkt_dev->vlan_p = 0; |
3568 | pkt_dev->vlan_cfi = 0; | 3568 | pkt_dev->vlan_cfi = 0; |
3569 | pkt_dev->vlan_id = 0xffff; | 3569 | pkt_dev->vlan_id = 0xffff; |
@@ -3575,6 +3575,8 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) | |||
3575 | err = pktgen_setup_dev(pkt_dev, ifname); | 3575 | err = pktgen_setup_dev(pkt_dev, ifname); |
3576 | if (err) | 3576 | if (err) |
3577 | goto out1; | 3577 | goto out1; |
3578 | if (pkt_dev->odev->priv_flags & IFF_TX_SKB_SHARING) | ||
3579 | pkt_dev->clone_skb = pg_clone_skb_d; | ||
3578 | 3580 | ||
3579 | pkt_dev->entry = proc_create_data(ifname, 0600, pg_proc_dir, | 3581 | pkt_dev->entry = proc_create_data(ifname, 0600, pg_proc_dir, |
3580 | &pktgen_if_fops, pkt_dev); | 3582 | &pktgen_if_fops, pkt_dev); |
diff --git a/net/core/scm.c b/net/core/scm.c index 4c1ef026d69..811b53fb330 100644 --- a/net/core/scm.c +++ b/net/core/scm.c | |||
@@ -192,7 +192,7 @@ int __scm_send(struct socket *sock, struct msghdr *msg, struct scm_cookie *p) | |||
192 | goto error; | 192 | goto error; |
193 | 193 | ||
194 | cred->uid = cred->euid = p->creds.uid; | 194 | cred->uid = cred->euid = p->creds.uid; |
195 | cred->gid = cred->egid = p->creds.uid; | 195 | cred->gid = cred->egid = p->creds.gid; |
196 | put_cred(p->cred); | 196 | put_cred(p->cred); |
197 | p->cred = cred; | 197 | p->cred = cred; |
198 | } | 198 | } |
diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c new file mode 100644 index 00000000000..45329d7c9dd --- /dev/null +++ b/net/core/secure_seq.c | |||
@@ -0,0 +1,184 @@ | |||
1 | #include <linux/kernel.h> | ||
2 | #include <linux/init.h> | ||
3 | #include <linux/cryptohash.h> | ||
4 | #include <linux/module.h> | ||
5 | #include <linux/cache.h> | ||
6 | #include <linux/random.h> | ||
7 | #include <linux/hrtimer.h> | ||
8 | #include <linux/ktime.h> | ||
9 | #include <linux/string.h> | ||
10 | |||
11 | #include <net/secure_seq.h> | ||
12 | |||
13 | static u32 net_secret[MD5_MESSAGE_BYTES / 4] ____cacheline_aligned; | ||
14 | |||
15 | static int __init net_secret_init(void) | ||
16 | { | ||
17 | get_random_bytes(net_secret, sizeof(net_secret)); | ||
18 | return 0; | ||
19 | } | ||
20 | late_initcall(net_secret_init); | ||
21 | |||
22 | static u32 seq_scale(u32 seq) | ||
23 | { | ||
24 | /* | ||
25 | * As close as possible to RFC 793, which | ||
26 | * suggests using a 250 kHz clock. | ||
27 | * Further reading shows this assumes 2 Mb/s networks. | ||
28 | * For 10 Mb/s Ethernet, a 1 MHz clock is appropriate. | ||
29 | * For 10 Gb/s Ethernet, a 1 GHz clock should be ok, but | ||
30 | * we also need to limit the resolution so that the u32 seq | ||
31 | * overlaps less than one time per MSL (2 minutes). | ||
32 | * Choosing a clock of 64 ns period is OK. (period of 274 s) | ||
33 | */ | ||
34 | return seq + (ktime_to_ns(ktime_get_real()) >> 6); | ||
35 | } | ||
36 | |||
37 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
38 | __u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr, | ||
39 | __be16 sport, __be16 dport) | ||
40 | { | ||
41 | u32 secret[MD5_MESSAGE_BYTES / 4]; | ||
42 | u32 hash[MD5_DIGEST_WORDS]; | ||
43 | u32 i; | ||
44 | |||
45 | memcpy(hash, saddr, 16); | ||
46 | for (i = 0; i < 4; i++) | ||
47 | secret[i] = net_secret[i] + daddr[i]; | ||
48 | secret[4] = net_secret[4] + | ||
49 | (((__force u16)sport << 16) + (__force u16)dport); | ||
50 | for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++) | ||
51 | secret[i] = net_secret[i]; | ||
52 | |||
53 | md5_transform(hash, secret); | ||
54 | |||
55 | return seq_scale(hash[0]); | ||
56 | } | ||
57 | EXPORT_SYMBOL(secure_tcpv6_sequence_number); | ||
58 | |||
59 | u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr, | ||
60 | __be16 dport) | ||
61 | { | ||
62 | u32 secret[MD5_MESSAGE_BYTES / 4]; | ||
63 | u32 hash[MD5_DIGEST_WORDS]; | ||
64 | u32 i; | ||
65 | |||
66 | memcpy(hash, saddr, 16); | ||
67 | for (i = 0; i < 4; i++) | ||
68 | secret[i] = net_secret[i] + (__force u32) daddr[i]; | ||
69 | secret[4] = net_secret[4] + (__force u32)dport; | ||
70 | for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++) | ||
71 | secret[i] = net_secret[i]; | ||
72 | |||
73 | md5_transform(hash, secret); | ||
74 | |||
75 | return hash[0]; | ||
76 | } | ||
77 | #endif | ||
78 | |||
79 | #ifdef CONFIG_INET | ||
80 | __u32 secure_ip_id(__be32 daddr) | ||
81 | { | ||
82 | u32 hash[MD5_DIGEST_WORDS]; | ||
83 | |||
84 | hash[0] = (__force __u32) daddr; | ||
85 | hash[1] = net_secret[13]; | ||
86 | hash[2] = net_secret[14]; | ||
87 | hash[3] = net_secret[15]; | ||
88 | |||
89 | md5_transform(hash, net_secret); | ||
90 | |||
91 | return hash[0]; | ||
92 | } | ||
93 | |||
94 | __u32 secure_ipv6_id(const __be32 daddr[4]) | ||
95 | { | ||
96 | __u32 hash[4]; | ||
97 | |||
98 | memcpy(hash, daddr, 16); | ||
99 | md5_transform(hash, net_secret); | ||
100 | |||
101 | return hash[0]; | ||
102 | } | ||
103 | |||
104 | __u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr, | ||
105 | __be16 sport, __be16 dport) | ||
106 | { | ||
107 | u32 hash[MD5_DIGEST_WORDS]; | ||
108 | |||
109 | hash[0] = (__force u32)saddr; | ||
110 | hash[1] = (__force u32)daddr; | ||
111 | hash[2] = ((__force u16)sport << 16) + (__force u16)dport; | ||
112 | hash[3] = net_secret[15]; | ||
113 | |||
114 | md5_transform(hash, net_secret); | ||
115 | |||
116 | return seq_scale(hash[0]); | ||
117 | } | ||
118 | |||
119 | u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport) | ||
120 | { | ||
121 | u32 hash[MD5_DIGEST_WORDS]; | ||
122 | |||
123 | hash[0] = (__force u32)saddr; | ||
124 | hash[1] = (__force u32)daddr; | ||
125 | hash[2] = (__force u32)dport ^ net_secret[14]; | ||
126 | hash[3] = net_secret[15]; | ||
127 | |||
128 | md5_transform(hash, net_secret); | ||
129 | |||
130 | return hash[0]; | ||
131 | } | ||
132 | EXPORT_SYMBOL_GPL(secure_ipv4_port_ephemeral); | ||
133 | #endif | ||
134 | |||
135 | #if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE) | ||
136 | u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr, | ||
137 | __be16 sport, __be16 dport) | ||
138 | { | ||
139 | u32 hash[MD5_DIGEST_WORDS]; | ||
140 | u64 seq; | ||
141 | |||
142 | hash[0] = (__force u32)saddr; | ||
143 | hash[1] = (__force u32)daddr; | ||
144 | hash[2] = ((__force u16)sport << 16) + (__force u16)dport; | ||
145 | hash[3] = net_secret[15]; | ||
146 | |||
147 | md5_transform(hash, net_secret); | ||
148 | |||
149 | seq = hash[0] | (((u64)hash[1]) << 32); | ||
150 | seq += ktime_to_ns(ktime_get_real()); | ||
151 | seq &= (1ull << 48) - 1; | ||
152 | |||
153 | return seq; | ||
154 | } | ||
155 | EXPORT_SYMBOL(secure_dccp_sequence_number); | ||
156 | |||
157 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
158 | u64 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr, | ||
159 | __be16 sport, __be16 dport) | ||
160 | { | ||
161 | u32 secret[MD5_MESSAGE_BYTES / 4]; | ||
162 | u32 hash[MD5_DIGEST_WORDS]; | ||
163 | u64 seq; | ||
164 | u32 i; | ||
165 | |||
166 | memcpy(hash, saddr, 16); | ||
167 | for (i = 0; i < 4; i++) | ||
168 | secret[i] = net_secret[i] + daddr[i]; | ||
169 | secret[4] = net_secret[4] + | ||
170 | (((__force u16)sport << 16) + (__force u16)dport); | ||
171 | for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++) | ||
172 | secret[i] = net_secret[i]; | ||
173 | |||
174 | md5_transform(hash, secret); | ||
175 | |||
176 | seq = hash[0] | (((u64)hash[1]) << 32); | ||
177 | seq += ktime_to_ns(ktime_get_real()); | ||
178 | seq &= (1ull << 48) - 1; | ||
179 | |||
180 | return seq; | ||
181 | } | ||
182 | EXPORT_SYMBOL(secure_dccpv6_sequence_number); | ||
183 | #endif | ||
184 | #endif | ||
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 2beda824636..27002dffe7e 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -1369,8 +1369,21 @@ pull_pages: | |||
1369 | } | 1369 | } |
1370 | EXPORT_SYMBOL(__pskb_pull_tail); | 1370 | EXPORT_SYMBOL(__pskb_pull_tail); |
1371 | 1371 | ||
1372 | /* Copy some data bits from skb to kernel buffer. */ | 1372 | /** |
1373 | 1373 | * skb_copy_bits - copy bits from skb to kernel buffer | |
1374 | * @skb: source skb | ||
1375 | * @offset: offset in source | ||
1376 | * @to: destination buffer | ||
1377 | * @len: number of bytes to copy | ||
1378 | * | ||
1379 | * Copy the specified number of bytes from the source skb to the | ||
1380 | * destination buffer. | ||
1381 | * | ||
1382 | * CAUTION ! : | ||
1383 | * If its prototype is ever changed, | ||
1384 | * check arch/{*}/net/{*}.S files, | ||
1385 | * since it is called from BPF assembly code. | ||
1386 | */ | ||
1374 | int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) | 1387 | int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len) |
1375 | { | 1388 | { |
1376 | int start = skb_headlen(skb); | 1389 | int start = skb_headlen(skb); |
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 8c36adfd191..332639b56f4 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <net/timewait_sock.h> | 26 | #include <net/timewait_sock.h> |
27 | #include <net/tcp_states.h> | 27 | #include <net/tcp_states.h> |
28 | #include <net/xfrm.h> | 28 | #include <net/xfrm.h> |
29 | #include <net/secure_seq.h> | ||
29 | 30 | ||
30 | #include "ackvec.h" | 31 | #include "ackvec.h" |
31 | #include "ccid.h" | 32 | #include "ccid.h" |
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index 8dc4348774a..b74f76117dc 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <net/transp_v6.h> | 29 | #include <net/transp_v6.h> |
30 | #include <net/ip6_checksum.h> | 30 | #include <net/ip6_checksum.h> |
31 | #include <net/xfrm.h> | 31 | #include <net/xfrm.h> |
32 | #include <net/secure_seq.h> | ||
32 | 33 | ||
33 | #include "dccp.h" | 34 | #include "dccp.h" |
34 | #include "ipv6.h" | 35 | #include "ipv6.h" |
@@ -69,13 +70,7 @@ static inline void dccp_v6_send_check(struct sock *sk, struct sk_buff *skb) | |||
69 | dh->dccph_checksum = dccp_v6_csum_finish(skb, &np->saddr, &np->daddr); | 70 | dh->dccph_checksum = dccp_v6_csum_finish(skb, &np->saddr, &np->daddr); |
70 | } | 71 | } |
71 | 72 | ||
72 | static inline __u32 secure_dccpv6_sequence_number(__be32 *saddr, __be32 *daddr, | 73 | static inline __u64 dccp_v6_init_sequence(struct sk_buff *skb) |
73 | __be16 sport, __be16 dport ) | ||
74 | { | ||
75 | return secure_tcpv6_sequence_number(saddr, daddr, sport, dport); | ||
76 | } | ||
77 | |||
78 | static inline __u32 dccp_v6_init_sequence(struct sk_buff *skb) | ||
79 | { | 74 | { |
80 | return secure_dccpv6_sequence_number(ipv6_hdr(skb)->daddr.s6_addr32, | 75 | return secure_dccpv6_sequence_number(ipv6_hdr(skb)->daddr.s6_addr32, |
81 | ipv6_hdr(skb)->saddr.s6_addr32, | 76 | ipv6_hdr(skb)->saddr.s6_addr32, |
diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c index 2bd8e53d777..9e885f180b6 100644 --- a/net/decnet/dn_fib.c +++ b/net/decnet/dn_fib.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <linux/netdevice.h> | 30 | #include <linux/netdevice.h> |
31 | #include <linux/timer.h> | 31 | #include <linux/timer.h> |
32 | #include <linux/spinlock.h> | 32 | #include <linux/spinlock.h> |
33 | #include <asm/atomic.h> | 33 | #include <linux/atomic.h> |
34 | #include <asm/uaccess.h> | 34 | #include <asm/uaccess.h> |
35 | #include <net/neighbour.h> | 35 | #include <net/neighbour.h> |
36 | #include <net/dst.h> | 36 | #include <net/dst.h> |
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c index 0dc3fe61085..7f0eb087dc1 100644 --- a/net/decnet/dn_neigh.c +++ b/net/decnet/dn_neigh.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #include <linux/seq_file.h> | 38 | #include <linux/seq_file.h> |
39 | #include <linux/rcupdate.h> | 39 | #include <linux/rcupdate.h> |
40 | #include <linux/jhash.h> | 40 | #include <linux/jhash.h> |
41 | #include <asm/atomic.h> | 41 | #include <linux/atomic.h> |
42 | #include <net/net_namespace.h> | 42 | #include <net/net_namespace.h> |
43 | #include <net/neighbour.h> | 43 | #include <net/neighbour.h> |
44 | #include <net/dst.h> | 44 | #include <net/dst.h> |
diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c index cd0354e9bdb..a9a62f225a6 100644 --- a/net/decnet/dn_table.c +++ b/net/decnet/dn_table.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <linux/netdevice.h> | 25 | #include <linux/netdevice.h> |
26 | #include <linux/timer.h> | 26 | #include <linux/timer.h> |
27 | #include <linux/spinlock.h> | 27 | #include <linux/spinlock.h> |
28 | #include <asm/atomic.h> | 28 | #include <linux/atomic.h> |
29 | #include <asm/uaccess.h> | 29 | #include <asm/uaccess.h> |
30 | #include <linux/route.h> /* RTF_xxx */ | 30 | #include <linux/route.h> /* RTF_xxx */ |
31 | #include <net/neighbour.h> | 31 | #include <net/neighbour.h> |
diff --git a/net/decnet/dn_timer.c b/net/decnet/dn_timer.c index 09825711d58..67f691bd4ac 100644 --- a/net/decnet/dn_timer.c +++ b/net/decnet/dn_timer.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include <linux/timer.h> | 22 | #include <linux/timer.h> |
23 | #include <linux/spinlock.h> | 23 | #include <linux/spinlock.h> |
24 | #include <net/sock.h> | 24 | #include <net/sock.h> |
25 | #include <asm/atomic.h> | 25 | #include <linux/atomic.h> |
26 | #include <net/flow.h> | 26 | #include <net/flow.h> |
27 | #include <net/dn.h> | 27 | #include <net/dn.h> |
28 | 28 | ||
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index 5cffb63f481..27997d35ebd 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c | |||
@@ -231,6 +231,7 @@ EXPORT_SYMBOL(eth_header_parse); | |||
231 | * eth_header_cache - fill cache entry from neighbour | 231 | * eth_header_cache - fill cache entry from neighbour |
232 | * @neigh: source neighbour | 232 | * @neigh: source neighbour |
233 | * @hh: destination cache entry | 233 | * @hh: destination cache entry |
234 | * @type: Ethernet type field | ||
234 | * Create an Ethernet header template from the neighbour. | 235 | * Create an Ethernet header template from the neighbour. |
235 | */ | 236 | */ |
236 | int eth_header_cache(const struct neighbour *neigh, struct hh_cache *hh, __be16 type) | 237 | int eth_header_cache(const struct neighbour *neigh, struct hh_cache *hh, __be16 type) |
@@ -339,6 +340,7 @@ void ether_setup(struct net_device *dev) | |||
339 | dev->addr_len = ETH_ALEN; | 340 | dev->addr_len = ETH_ALEN; |
340 | dev->tx_queue_len = 1000; /* Ethernet wants good queues */ | 341 | dev->tx_queue_len = 1000; /* Ethernet wants good queues */ |
341 | dev->flags = IFF_BROADCAST|IFF_MULTICAST; | 342 | dev->flags = IFF_BROADCAST|IFF_MULTICAST; |
343 | dev->priv_flags = IFF_TX_SKB_SHARING; | ||
342 | 344 | ||
343 | memset(dev->broadcast, 0xFF, ETH_ALEN); | 345 | memset(dev->broadcast, 0xFF, ETH_ALEN); |
344 | 346 | ||
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index 2b3c23c287c..2c2a98e402e 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c | |||
@@ -50,7 +50,7 @@ | |||
50 | #include <net/tcp.h> | 50 | #include <net/tcp.h> |
51 | #include <net/netlabel.h> | 51 | #include <net/netlabel.h> |
52 | #include <net/cipso_ipv4.h> | 52 | #include <net/cipso_ipv4.h> |
53 | #include <asm/atomic.h> | 53 | #include <linux/atomic.h> |
54 | #include <asm/bug.h> | 54 | #include <asm/bug.h> |
55 | #include <asm/unaligned.h> | 55 | #include <asm/unaligned.h> |
56 | 56 | ||
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 37b3c188d8b..bc19bd06dd0 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -1134,15 +1134,15 @@ static void inetdev_send_gratuitous_arp(struct net_device *dev, | |||
1134 | struct in_device *in_dev) | 1134 | struct in_device *in_dev) |
1135 | 1135 | ||
1136 | { | 1136 | { |
1137 | struct in_ifaddr *ifa = in_dev->ifa_list; | 1137 | struct in_ifaddr *ifa; |
1138 | |||
1139 | if (!ifa) | ||
1140 | return; | ||
1141 | 1138 | ||
1142 | arp_send(ARPOP_REQUEST, ETH_P_ARP, | 1139 | for (ifa = in_dev->ifa_list; ifa; |
1143 | ifa->ifa_local, dev, | 1140 | ifa = ifa->ifa_next) { |
1144 | ifa->ifa_local, NULL, | 1141 | arp_send(ARPOP_REQUEST, ETH_P_ARP, |
1145 | dev->dev_addr, NULL); | 1142 | ifa->ifa_local, dev, |
1143 | ifa->ifa_local, NULL, | ||
1144 | dev->dev_addr, NULL); | ||
1145 | } | ||
1146 | } | 1146 | } |
1147 | 1147 | ||
1148 | /* Called only under RTNL semaphore */ | 1148 | /* Called only under RTNL semaphore */ |
diff --git a/net/ipv4/gre.c b/net/ipv4/gre.c index 9dbe10875fb..dbfc21de347 100644 --- a/net/ipv4/gre.c +++ b/net/ipv4/gre.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/kmod.h> | 15 | #include <linux/kmod.h> |
16 | #include <linux/skbuff.h> | 16 | #include <linux/skbuff.h> |
17 | #include <linux/in.h> | 17 | #include <linux/in.h> |
18 | #include <linux/ip.h> | ||
18 | #include <linux/netdevice.h> | 19 | #include <linux/netdevice.h> |
19 | #include <linux/spinlock.h> | 20 | #include <linux/spinlock.h> |
20 | #include <net/protocol.h> | 21 | #include <net/protocol.h> |
@@ -96,27 +97,17 @@ drop: | |||
96 | static void gre_err(struct sk_buff *skb, u32 info) | 97 | static void gre_err(struct sk_buff *skb, u32 info) |
97 | { | 98 | { |
98 | const struct gre_protocol *proto; | 99 | const struct gre_protocol *proto; |
99 | u8 ver; | 100 | const struct iphdr *iph = (const struct iphdr *)skb->data; |
100 | 101 | u8 ver = skb->data[(iph->ihl<<2) + 1]&0x7f; | |
101 | if (!pskb_may_pull(skb, 12)) | ||
102 | goto drop; | ||
103 | 102 | ||
104 | ver = skb->data[1]&0x7f; | ||
105 | if (ver >= GREPROTO_MAX) | 103 | if (ver >= GREPROTO_MAX) |
106 | goto drop; | 104 | return; |
107 | 105 | ||
108 | rcu_read_lock(); | 106 | rcu_read_lock(); |
109 | proto = rcu_dereference(gre_proto[ver]); | 107 | proto = rcu_dereference(gre_proto[ver]); |
110 | if (!proto || !proto->err_handler) | 108 | if (proto && proto->err_handler) |
111 | goto drop_unlock; | 109 | proto->err_handler(skb, info); |
112 | proto->err_handler(skb, info); | ||
113 | rcu_read_unlock(); | ||
114 | return; | ||
115 | |||
116 | drop_unlock: | ||
117 | rcu_read_unlock(); | 110 | rcu_read_unlock(); |
118 | drop: | ||
119 | kfree_skb(skb); | ||
120 | } | 111 | } |
121 | 112 | ||
122 | static const struct net_protocol net_gre_protocol = { | 113 | static const struct net_protocol net_gre_protocol = { |
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index f1d27f6c935..283c0a26e03 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
@@ -1718,7 +1718,7 @@ static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode, | |||
1718 | 1718 | ||
1719 | pmc->sfcount[sfmode]--; | 1719 | pmc->sfcount[sfmode]--; |
1720 | for (j=0; j<i; j++) | 1720 | for (j=0; j<i; j++) |
1721 | (void) ip_mc_del1_src(pmc, sfmode, &psfsrc[i]); | 1721 | (void) ip_mc_del1_src(pmc, sfmode, &psfsrc[j]); |
1722 | } else if (isexclude != (pmc->sfcount[MCAST_EXCLUDE] != 0)) { | 1722 | } else if (isexclude != (pmc->sfcount[MCAST_EXCLUDE] != 0)) { |
1723 | #ifdef CONFIG_IP_MULTICAST | 1723 | #ifdef CONFIG_IP_MULTICAST |
1724 | struct ip_sf_list *psf; | 1724 | struct ip_sf_list *psf; |
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c index 3c0369a3a66..984ec656b03 100644 --- a/net/ipv4/inet_hashtables.c +++ b/net/ipv4/inet_hashtables.c | |||
@@ -21,6 +21,7 @@ | |||
21 | 21 | ||
22 | #include <net/inet_connection_sock.h> | 22 | #include <net/inet_connection_sock.h> |
23 | #include <net/inet_hashtables.h> | 23 | #include <net/inet_hashtables.h> |
24 | #include <net/secure_seq.h> | ||
24 | #include <net/ip.h> | 25 | #include <net/ip.h> |
25 | 26 | ||
26 | /* | 27 | /* |
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index e38213817d0..86f13c67ea8 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/net.h> | 19 | #include <linux/net.h> |
20 | #include <net/ip.h> | 20 | #include <net/ip.h> |
21 | #include <net/inetpeer.h> | 21 | #include <net/inetpeer.h> |
22 | #include <net/secure_seq.h> | ||
22 | 23 | ||
23 | /* | 24 | /* |
24 | * Theory of operations. | 25 | * Theory of operations. |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index ccaaa851ab4..8c6563361ab 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -122,6 +122,7 @@ static int ip_dev_loopback_xmit(struct sk_buff *newskb) | |||
122 | newskb->pkt_type = PACKET_LOOPBACK; | 122 | newskb->pkt_type = PACKET_LOOPBACK; |
123 | newskb->ip_summed = CHECKSUM_UNNECESSARY; | 123 | newskb->ip_summed = CHECKSUM_UNNECESSARY; |
124 | WARN_ON(!skb_dst(newskb)); | 124 | WARN_ON(!skb_dst(newskb)); |
125 | skb_dst_force(newskb); | ||
125 | netif_rx_ni(newskb); | 126 | netif_rx_ni(newskb); |
126 | return 0; | 127 | return 0; |
127 | } | 128 | } |
@@ -204,9 +205,15 @@ static inline int ip_finish_output2(struct sk_buff *skb) | |||
204 | skb = skb2; | 205 | skb = skb2; |
205 | } | 206 | } |
206 | 207 | ||
208 | rcu_read_lock(); | ||
207 | neigh = dst_get_neighbour(dst); | 209 | neigh = dst_get_neighbour(dst); |
208 | if (neigh) | 210 | if (neigh) { |
209 | return neigh_output(neigh, skb); | 211 | int res = neigh_output(neigh, skb); |
212 | |||
213 | rcu_read_unlock(); | ||
214 | return res; | ||
215 | } | ||
216 | rcu_read_unlock(); | ||
210 | 217 | ||
211 | if (net_ratelimit()) | 218 | if (net_ratelimit()) |
212 | printk(KERN_DEBUG "ip_finish_output2: No header cache and no neighbour!\n"); | 219 | printk(KERN_DEBUG "ip_finish_output2: No header cache and no neighbour!\n"); |
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index ab0c9efd1ef..8905e92f896 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c | |||
@@ -1067,7 +1067,7 @@ EXPORT_SYMBOL(compat_ip_setsockopt); | |||
1067 | */ | 1067 | */ |
1068 | 1068 | ||
1069 | static int do_ip_getsockopt(struct sock *sk, int level, int optname, | 1069 | static int do_ip_getsockopt(struct sock *sk, int level, int optname, |
1070 | char __user *optval, int __user *optlen) | 1070 | char __user *optval, int __user *optlen, unsigned flags) |
1071 | { | 1071 | { |
1072 | struct inet_sock *inet = inet_sk(sk); | 1072 | struct inet_sock *inet = inet_sk(sk); |
1073 | int val; | 1073 | int val; |
@@ -1240,7 +1240,7 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname, | |||
1240 | 1240 | ||
1241 | msg.msg_control = optval; | 1241 | msg.msg_control = optval; |
1242 | msg.msg_controllen = len; | 1242 | msg.msg_controllen = len; |
1243 | msg.msg_flags = 0; | 1243 | msg.msg_flags = flags; |
1244 | 1244 | ||
1245 | if (inet->cmsg_flags & IP_CMSG_PKTINFO) { | 1245 | if (inet->cmsg_flags & IP_CMSG_PKTINFO) { |
1246 | struct in_pktinfo info; | 1246 | struct in_pktinfo info; |
@@ -1294,7 +1294,7 @@ int ip_getsockopt(struct sock *sk, int level, | |||
1294 | { | 1294 | { |
1295 | int err; | 1295 | int err; |
1296 | 1296 | ||
1297 | err = do_ip_getsockopt(sk, level, optname, optval, optlen); | 1297 | err = do_ip_getsockopt(sk, level, optname, optval, optlen, 0); |
1298 | #ifdef CONFIG_NETFILTER | 1298 | #ifdef CONFIG_NETFILTER |
1299 | /* we need to exclude all possible ENOPROTOOPTs except default case */ | 1299 | /* we need to exclude all possible ENOPROTOOPTs except default case */ |
1300 | if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS && | 1300 | if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS && |
@@ -1327,7 +1327,8 @@ int compat_ip_getsockopt(struct sock *sk, int level, int optname, | |||
1327 | return compat_mc_getsockopt(sk, level, optname, optval, optlen, | 1327 | return compat_mc_getsockopt(sk, level, optname, optval, optlen, |
1328 | ip_getsockopt); | 1328 | ip_getsockopt); |
1329 | 1329 | ||
1330 | err = do_ip_getsockopt(sk, level, optname, optval, optlen); | 1330 | err = do_ip_getsockopt(sk, level, optname, optval, optlen, |
1331 | MSG_CMSG_COMPAT); | ||
1331 | 1332 | ||
1332 | #ifdef CONFIG_NETFILTER | 1333 | #ifdef CONFIG_NETFILTER |
1333 | /* we need to exclude all possible ENOPROTOOPTs except default case */ | 1334 | /* we need to exclude all possible ENOPROTOOPTs except default case */ |
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index aae2bd8cd92..58e87915797 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -1796,7 +1796,7 @@ static struct mr_table *ipmr_rt_fib_lookup(struct net *net, struct sk_buff *skb) | |||
1796 | struct flowi4 fl4 = { | 1796 | struct flowi4 fl4 = { |
1797 | .daddr = iph->daddr, | 1797 | .daddr = iph->daddr, |
1798 | .saddr = iph->saddr, | 1798 | .saddr = iph->saddr, |
1799 | .flowi4_tos = iph->tos, | 1799 | .flowi4_tos = RT_TOS(iph->tos), |
1800 | .flowi4_oif = rt->rt_oif, | 1800 | .flowi4_oif = rt->rt_oif, |
1801 | .flowi4_iif = rt->rt_iif, | 1801 | .flowi4_iif = rt->rt_iif, |
1802 | .flowi4_mark = rt->rt_mark, | 1802 | .flowi4_mark = rt->rt_mark, |
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c index 2e97e3ec1eb..929b27bdeb7 100644 --- a/net/ipv4/netfilter.c +++ b/net/ipv4/netfilter.c | |||
@@ -18,17 +18,15 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) | |||
18 | struct rtable *rt; | 18 | struct rtable *rt; |
19 | struct flowi4 fl4 = {}; | 19 | struct flowi4 fl4 = {}; |
20 | __be32 saddr = iph->saddr; | 20 | __be32 saddr = iph->saddr; |
21 | __u8 flags = 0; | 21 | __u8 flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0; |
22 | unsigned int hh_len; | 22 | unsigned int hh_len; |
23 | 23 | ||
24 | if (!skb->sk && addr_type != RTN_LOCAL) { | 24 | if (addr_type == RTN_UNSPEC) |
25 | if (addr_type == RTN_UNSPEC) | 25 | addr_type = inet_addr_type(net, saddr); |
26 | addr_type = inet_addr_type(net, saddr); | 26 | if (addr_type == RTN_LOCAL || addr_type == RTN_UNICAST) |
27 | if (addr_type == RTN_LOCAL || addr_type == RTN_UNICAST) | 27 | flags |= FLOWI_FLAG_ANYSRC; |
28 | flags |= FLOWI_FLAG_ANYSRC; | 28 | else |
29 | else | 29 | saddr = 0; |
30 | saddr = 0; | ||
31 | } | ||
32 | 30 | ||
33 | /* some non-standard hacks like ipt_REJECT.c:send_reset() can cause | 31 | /* some non-standard hacks like ipt_REJECT.c:send_reset() can cause |
34 | * packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook. | 32 | * packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook. |
@@ -38,7 +36,7 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type) | |||
38 | fl4.flowi4_tos = RT_TOS(iph->tos); | 36 | fl4.flowi4_tos = RT_TOS(iph->tos); |
39 | fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; | 37 | fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; |
40 | fl4.flowi4_mark = skb->mark; | 38 | fl4.flowi4_mark = skb->mark; |
41 | fl4.flowi4_flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : flags; | 39 | fl4.flowi4_flags = flags; |
42 | rt = ip_route_output_key(net, &fl4); | 40 | rt = ip_route_output_key(net, &fl4); |
43 | if (IS_ERR(rt)) | 41 | if (IS_ERR(rt)) |
44 | return -1; | 42 | return -1; |
diff --git a/net/ipv4/netfilter/nf_nat_proto_common.c b/net/ipv4/netfilter/nf_nat_proto_common.c index 3e61faf23a9..f52d41ea069 100644 --- a/net/ipv4/netfilter/nf_nat_proto_common.c +++ b/net/ipv4/netfilter/nf_nat_proto_common.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/ip.h> | 12 | #include <linux/ip.h> |
13 | 13 | ||
14 | #include <linux/netfilter.h> | 14 | #include <linux/netfilter.h> |
15 | #include <net/secure_seq.h> | ||
15 | #include <net/netfilter/nf_nat.h> | 16 | #include <net/netfilter/nf_nat.h> |
16 | #include <net/netfilter/nf_nat_core.h> | 17 | #include <net/netfilter/nf_nat_core.h> |
17 | #include <net/netfilter/nf_nat_rule.h> | 18 | #include <net/netfilter/nf_nat_rule.h> |
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 08526786dc3..61714bd5292 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
@@ -38,7 +38,7 @@ | |||
38 | */ | 38 | */ |
39 | 39 | ||
40 | #include <linux/types.h> | 40 | #include <linux/types.h> |
41 | #include <asm/atomic.h> | 41 | #include <linux/atomic.h> |
42 | #include <asm/byteorder.h> | 42 | #include <asm/byteorder.h> |
43 | #include <asm/current.h> | 43 | #include <asm/current.h> |
44 | #include <asm/uaccess.h> | 44 | #include <asm/uaccess.h> |
@@ -563,7 +563,8 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
563 | flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos, | 563 | flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos, |
564 | RT_SCOPE_UNIVERSE, | 564 | RT_SCOPE_UNIVERSE, |
565 | inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol, | 565 | inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol, |
566 | FLOWI_FLAG_CAN_SLEEP, daddr, saddr, 0, 0); | 566 | inet_sk_flowi_flags(sk) | FLOWI_FLAG_CAN_SLEEP, |
567 | daddr, saddr, 0, 0); | ||
567 | 568 | ||
568 | if (!inet->hdrincl) { | 569 | if (!inet->hdrincl) { |
569 | err = raw_probe_proto_opt(&fl4, msg); | 570 | err = raw_probe_proto_opt(&fl4, msg); |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 33137307d52..075212e41b8 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -109,6 +109,7 @@ | |||
109 | #include <linux/sysctl.h> | 109 | #include <linux/sysctl.h> |
110 | #endif | 110 | #endif |
111 | #include <net/atmclip.h> | 111 | #include <net/atmclip.h> |
112 | #include <net/secure_seq.h> | ||
112 | 113 | ||
113 | #define RT_FL_TOS(oldflp4) \ | 114 | #define RT_FL_TOS(oldflp4) \ |
114 | ((u32)(oldflp4->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK))) | 115 | ((u32)(oldflp4->flowi4_tos & (IPTOS_RT_MASK | RTO_ONLINK))) |
@@ -721,7 +722,7 @@ static inline bool compare_hash_inputs(const struct rtable *rt1, | |||
721 | { | 722 | { |
722 | return ((((__force u32)rt1->rt_key_dst ^ (__force u32)rt2->rt_key_dst) | | 723 | return ((((__force u32)rt1->rt_key_dst ^ (__force u32)rt2->rt_key_dst) | |
723 | ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) | | 724 | ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) | |
724 | (rt1->rt_iif ^ rt2->rt_iif)) == 0); | 725 | (rt1->rt_route_iif ^ rt2->rt_route_iif)) == 0); |
725 | } | 726 | } |
726 | 727 | ||
727 | static inline int compare_keys(struct rtable *rt1, struct rtable *rt2) | 728 | static inline int compare_keys(struct rtable *rt1, struct rtable *rt2) |
@@ -730,8 +731,8 @@ static inline int compare_keys(struct rtable *rt1, struct rtable *rt2) | |||
730 | ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) | | 731 | ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) | |
731 | (rt1->rt_mark ^ rt2->rt_mark) | | 732 | (rt1->rt_mark ^ rt2->rt_mark) | |
732 | (rt1->rt_key_tos ^ rt2->rt_key_tos) | | 733 | (rt1->rt_key_tos ^ rt2->rt_key_tos) | |
733 | (rt1->rt_oif ^ rt2->rt_oif) | | 734 | (rt1->rt_route_iif ^ rt2->rt_route_iif) | |
734 | (rt1->rt_iif ^ rt2->rt_iif)) == 0; | 735 | (rt1->rt_oif ^ rt2->rt_oif)) == 0; |
735 | } | 736 | } |
736 | 737 | ||
737 | static inline int compare_netns(struct rtable *rt1, struct rtable *rt2) | 738 | static inline int compare_netns(struct rtable *rt1, struct rtable *rt2) |
@@ -1628,16 +1629,18 @@ static int check_peer_redir(struct dst_entry *dst, struct inet_peer *peer) | |||
1628 | { | 1629 | { |
1629 | struct rtable *rt = (struct rtable *) dst; | 1630 | struct rtable *rt = (struct rtable *) dst; |
1630 | __be32 orig_gw = rt->rt_gateway; | 1631 | __be32 orig_gw = rt->rt_gateway; |
1631 | struct neighbour *n; | 1632 | struct neighbour *n, *old_n; |
1632 | 1633 | ||
1633 | dst_confirm(&rt->dst); | 1634 | dst_confirm(&rt->dst); |
1634 | 1635 | ||
1635 | neigh_release(dst_get_neighbour(&rt->dst)); | ||
1636 | dst_set_neighbour(&rt->dst, NULL); | ||
1637 | |||
1638 | rt->rt_gateway = peer->redirect_learned.a4; | 1636 | rt->rt_gateway = peer->redirect_learned.a4; |
1639 | rt_bind_neighbour(rt); | 1637 | |
1640 | n = dst_get_neighbour(&rt->dst); | 1638 | n = ipv4_neigh_lookup(&rt->dst, &rt->rt_gateway); |
1639 | if (IS_ERR(n)) | ||
1640 | return PTR_ERR(n); | ||
1641 | old_n = xchg(&rt->dst._neighbour, n); | ||
1642 | if (old_n) | ||
1643 | neigh_release(old_n); | ||
1641 | if (!n || !(n->nud_state & NUD_VALID)) { | 1644 | if (!n || !(n->nud_state & NUD_VALID)) { |
1642 | if (n) | 1645 | if (n) |
1643 | neigh_event_send(n, NULL); | 1646 | neigh_event_send(n, NULL); |
@@ -1740,7 +1743,7 @@ void ip_rt_get_source(u8 *addr, struct sk_buff *skb, struct rtable *rt) | |||
1740 | memset(&fl4, 0, sizeof(fl4)); | 1743 | memset(&fl4, 0, sizeof(fl4)); |
1741 | fl4.daddr = iph->daddr; | 1744 | fl4.daddr = iph->daddr; |
1742 | fl4.saddr = iph->saddr; | 1745 | fl4.saddr = iph->saddr; |
1743 | fl4.flowi4_tos = iph->tos; | 1746 | fl4.flowi4_tos = RT_TOS(iph->tos); |
1744 | fl4.flowi4_oif = rt->dst.dev->ifindex; | 1747 | fl4.flowi4_oif = rt->dst.dev->ifindex; |
1745 | fl4.flowi4_iif = skb->dev->ifindex; | 1748 | fl4.flowi4_iif = skb->dev->ifindex; |
1746 | fl4.flowi4_mark = skb->mark; | 1749 | fl4.flowi4_mark = skb->mark; |
@@ -2317,8 +2320,7 @@ int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
2317 | rth = rcu_dereference(rth->dst.rt_next)) { | 2320 | rth = rcu_dereference(rth->dst.rt_next)) { |
2318 | if ((((__force u32)rth->rt_key_dst ^ (__force u32)daddr) | | 2321 | if ((((__force u32)rth->rt_key_dst ^ (__force u32)daddr) | |
2319 | ((__force u32)rth->rt_key_src ^ (__force u32)saddr) | | 2322 | ((__force u32)rth->rt_key_src ^ (__force u32)saddr) | |
2320 | (rth->rt_iif ^ iif) | | 2323 | (rth->rt_route_iif ^ iif) | |
2321 | rth->rt_oif | | ||
2322 | (rth->rt_key_tos ^ tos)) == 0 && | 2324 | (rth->rt_key_tos ^ tos)) == 0 && |
2323 | rth->rt_mark == skb->mark && | 2325 | rth->rt_mark == skb->mark && |
2324 | net_eq(dev_net(rth->dst.dev), net) && | 2326 | net_eq(dev_net(rth->dst.dev), net) && |
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index 92bb9434b33..3bc5c8f7c71 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c | |||
@@ -276,7 +276,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, | |||
276 | int mss; | 276 | int mss; |
277 | struct rtable *rt; | 277 | struct rtable *rt; |
278 | __u8 rcv_wscale; | 278 | __u8 rcv_wscale; |
279 | bool ecn_ok; | 279 | bool ecn_ok = false; |
280 | 280 | ||
281 | if (!sysctl_tcp_syncookies || !th->ack || th->rst) | 281 | if (!sysctl_tcp_syncookies || !th->ack || th->rst) |
282 | goto out; | 282 | goto out; |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 955b8e65b69..1c12b8ec849 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -72,6 +72,7 @@ | |||
72 | #include <net/timewait_sock.h> | 72 | #include <net/timewait_sock.h> |
73 | #include <net/xfrm.h> | 73 | #include <net/xfrm.h> |
74 | #include <net/netdma.h> | 74 | #include <net/netdma.h> |
75 | #include <net/secure_seq.h> | ||
75 | 76 | ||
76 | #include <linux/inet.h> | 77 | #include <linux/inet.h> |
77 | #include <linux/ipv6.h> | 78 | #include <linux/ipv6.h> |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index a06c53c14d8..f012ebd87b4 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -656,7 +656,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, | |||
656 | * layer address of our nexhop router | 656 | * layer address of our nexhop router |
657 | */ | 657 | */ |
658 | 658 | ||
659 | if (dst_get_neighbour(&rt->dst) == NULL) | 659 | if (dst_get_neighbour_raw(&rt->dst) == NULL) |
660 | ifa->flags &= ~IFA_F_OPTIMISTIC; | 660 | ifa->flags &= ~IFA_F_OPTIMISTIC; |
661 | 661 | ||
662 | ifa->idev = idev; | 662 | ifa->idev = idev; |
@@ -1481,6 +1481,8 @@ static void addrconf_join_anycast(struct inet6_ifaddr *ifp) | |||
1481 | static void addrconf_leave_anycast(struct inet6_ifaddr *ifp) | 1481 | static void addrconf_leave_anycast(struct inet6_ifaddr *ifp) |
1482 | { | 1482 | { |
1483 | struct in6_addr addr; | 1483 | struct in6_addr addr; |
1484 | if (ifp->prefix_len == 127) /* RFC 6164 */ | ||
1485 | return; | ||
1484 | ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); | 1486 | ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len); |
1485 | if (ipv6_addr_any(&addr)) | 1487 | if (ipv6_addr_any(&addr)) |
1486 | return; | 1488 | return; |
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 16560336eb7..9ef1831746e 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
@@ -33,6 +33,11 @@ | |||
33 | #include <linux/errqueue.h> | 33 | #include <linux/errqueue.h> |
34 | #include <asm/uaccess.h> | 34 | #include <asm/uaccess.h> |
35 | 35 | ||
36 | static inline int ipv6_mapped_addr_any(const struct in6_addr *a) | ||
37 | { | ||
38 | return (ipv6_addr_v4mapped(a) && (a->s6_addr32[3] == 0)); | ||
39 | } | ||
40 | |||
36 | int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | 41 | int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) |
37 | { | 42 | { |
38 | struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; | 43 | struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr; |
@@ -102,10 +107,12 @@ ipv4_connected: | |||
102 | 107 | ||
103 | ipv6_addr_set_v4mapped(inet->inet_daddr, &np->daddr); | 108 | ipv6_addr_set_v4mapped(inet->inet_daddr, &np->daddr); |
104 | 109 | ||
105 | if (ipv6_addr_any(&np->saddr)) | 110 | if (ipv6_addr_any(&np->saddr) || |
111 | ipv6_mapped_addr_any(&np->saddr)) | ||
106 | ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr); | 112 | ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr); |
107 | 113 | ||
108 | if (ipv6_addr_any(&np->rcv_saddr)) { | 114 | if (ipv6_addr_any(&np->rcv_saddr) || |
115 | ipv6_mapped_addr_any(&np->rcv_saddr)) { | ||
109 | ipv6_addr_set_v4mapped(inet->inet_rcv_saddr, | 116 | ipv6_addr_set_v4mapped(inet->inet_rcv_saddr, |
110 | &np->rcv_saddr); | 117 | &np->rcv_saddr); |
111 | if (sk->sk_prot->rehash) | 118 | if (sk->sk_prot->rehash) |
diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c index b5319723370..73f1a00a96a 100644 --- a/net/ipv6/inet6_hashtables.c +++ b/net/ipv6/inet6_hashtables.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <net/inet_connection_sock.h> | 20 | #include <net/inet_connection_sock.h> |
21 | #include <net/inet_hashtables.h> | 21 | #include <net/inet_hashtables.h> |
22 | #include <net/inet6_hashtables.h> | 22 | #include <net/inet6_hashtables.h> |
23 | #include <net/secure_seq.h> | ||
23 | #include <net/ip.h> | 24 | #include <net/ip.h> |
24 | 25 | ||
25 | int __inet6_hash(struct sock *sk, struct inet_timewait_sock *tw) | 26 | int __inet6_hash(struct sock *sk, struct inet_timewait_sock *tw) |
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 54a4678955b..320d91d20ad 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
@@ -1455,7 +1455,7 @@ static int fib6_age(struct rt6_info *rt, void *arg) | |||
1455 | RT6_TRACE("aging clone %p\n", rt); | 1455 | RT6_TRACE("aging clone %p\n", rt); |
1456 | return -1; | 1456 | return -1; |
1457 | } else if ((rt->rt6i_flags & RTF_GATEWAY) && | 1457 | } else if ((rt->rt6i_flags & RTF_GATEWAY) && |
1458 | (!(dst_get_neighbour(&rt->dst)->flags & NTF_ROUTER))) { | 1458 | (!(dst_get_neighbour_raw(&rt->dst)->flags & NTF_ROUTER))) { |
1459 | RT6_TRACE("purging route %p via non-router but gateway\n", | 1459 | RT6_TRACE("purging route %p via non-router but gateway\n", |
1460 | rt); | 1460 | rt); |
1461 | return -1; | 1461 | return -1; |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 32e5339db0c..4c882cf4e8a 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -135,10 +135,15 @@ static int ip6_finish_output2(struct sk_buff *skb) | |||
135 | skb->len); | 135 | skb->len); |
136 | } | 136 | } |
137 | 137 | ||
138 | rcu_read_lock(); | ||
138 | neigh = dst_get_neighbour(dst); | 139 | neigh = dst_get_neighbour(dst); |
139 | if (neigh) | 140 | if (neigh) { |
140 | return neigh_output(neigh, skb); | 141 | int res = neigh_output(neigh, skb); |
141 | 142 | ||
143 | rcu_read_unlock(); | ||
144 | return res; | ||
145 | } | ||
146 | rcu_read_unlock(); | ||
142 | IP6_INC_STATS_BH(dev_net(dst->dev), | 147 | IP6_INC_STATS_BH(dev_net(dst->dev), |
143 | ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); | 148 | ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES); |
144 | kfree_skb(skb); | 149 | kfree_skb(skb); |
@@ -975,12 +980,14 @@ static int ip6_dst_lookup_tail(struct sock *sk, | |||
975 | * dst entry and replace it instead with the | 980 | * dst entry and replace it instead with the |
976 | * dst entry of the nexthop router | 981 | * dst entry of the nexthop router |
977 | */ | 982 | */ |
983 | rcu_read_lock(); | ||
978 | n = dst_get_neighbour(*dst); | 984 | n = dst_get_neighbour(*dst); |
979 | if (n && !(n->nud_state & NUD_VALID)) { | 985 | if (n && !(n->nud_state & NUD_VALID)) { |
980 | struct inet6_ifaddr *ifp; | 986 | struct inet6_ifaddr *ifp; |
981 | struct flowi6 fl_gw6; | 987 | struct flowi6 fl_gw6; |
982 | int redirect; | 988 | int redirect; |
983 | 989 | ||
990 | rcu_read_unlock(); | ||
984 | ifp = ipv6_get_ifaddr(net, &fl6->saddr, | 991 | ifp = ipv6_get_ifaddr(net, &fl6->saddr, |
985 | (*dst)->dev, 1); | 992 | (*dst)->dev, 1); |
986 | 993 | ||
@@ -1000,6 +1007,8 @@ static int ip6_dst_lookup_tail(struct sock *sk, | |||
1000 | if ((err = (*dst)->error)) | 1007 | if ((err = (*dst)->error)) |
1001 | goto out_err_release; | 1008 | goto out_err_release; |
1002 | } | 1009 | } |
1010 | } else { | ||
1011 | rcu_read_unlock(); | ||
1003 | } | 1012 | } |
1004 | #endif | 1013 | #endif |
1005 | 1014 | ||
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 36c2842a86b..0bc98886c38 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -40,7 +40,7 @@ | |||
40 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
41 | 41 | ||
42 | #include <asm/uaccess.h> | 42 | #include <asm/uaccess.h> |
43 | #include <asm/atomic.h> | 43 | #include <linux/atomic.h> |
44 | 44 | ||
45 | #include <net/icmp.h> | 45 | #include <net/icmp.h> |
46 | #include <net/ip.h> | 46 | #include <net/ip.h> |
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 9cb191ecaba..147ede38ab4 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
@@ -913,7 +913,7 @@ static int ipv6_getsockopt_sticky(struct sock *sk, struct ipv6_txoptions *opt, | |||
913 | } | 913 | } |
914 | 914 | ||
915 | static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | 915 | static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, |
916 | char __user *optval, int __user *optlen) | 916 | char __user *optval, int __user *optlen, unsigned flags) |
917 | { | 917 | { |
918 | struct ipv6_pinfo *np = inet6_sk(sk); | 918 | struct ipv6_pinfo *np = inet6_sk(sk); |
919 | int len; | 919 | int len; |
@@ -962,7 +962,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
962 | 962 | ||
963 | msg.msg_control = optval; | 963 | msg.msg_control = optval; |
964 | msg.msg_controllen = len; | 964 | msg.msg_controllen = len; |
965 | msg.msg_flags = 0; | 965 | msg.msg_flags = flags; |
966 | 966 | ||
967 | lock_sock(sk); | 967 | lock_sock(sk); |
968 | skb = np->pktoptions; | 968 | skb = np->pktoptions; |
@@ -1222,7 +1222,7 @@ int ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
1222 | if(level != SOL_IPV6) | 1222 | if(level != SOL_IPV6) |
1223 | return -ENOPROTOOPT; | 1223 | return -ENOPROTOOPT; |
1224 | 1224 | ||
1225 | err = do_ipv6_getsockopt(sk, level, optname, optval, optlen); | 1225 | err = do_ipv6_getsockopt(sk, level, optname, optval, optlen, 0); |
1226 | #ifdef CONFIG_NETFILTER | 1226 | #ifdef CONFIG_NETFILTER |
1227 | /* we need to exclude all possible ENOPROTOOPTs except default case */ | 1227 | /* we need to exclude all possible ENOPROTOOPTs except default case */ |
1228 | if (err == -ENOPROTOOPT && optname != IPV6_2292PKTOPTIONS) { | 1228 | if (err == -ENOPROTOOPT && optname != IPV6_2292PKTOPTIONS) { |
@@ -1264,7 +1264,8 @@ int compat_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
1264 | return compat_mc_getsockopt(sk, level, optname, optval, optlen, | 1264 | return compat_mc_getsockopt(sk, level, optname, optval, optlen, |
1265 | ipv6_getsockopt); | 1265 | ipv6_getsockopt); |
1266 | 1266 | ||
1267 | err = do_ipv6_getsockopt(sk, level, optname, optval, optlen); | 1267 | err = do_ipv6_getsockopt(sk, level, optname, optval, optlen, |
1268 | MSG_CMSG_COMPAT); | ||
1268 | #ifdef CONFIG_NETFILTER | 1269 | #ifdef CONFIG_NETFILTER |
1269 | /* we need to exclude all possible ENOPROTOOPTs except default case */ | 1270 | /* we need to exclude all possible ENOPROTOOPTs except default case */ |
1270 | if (err == -ENOPROTOOPT && optname != IPV6_2292PKTOPTIONS) { | 1271 | if (err == -ENOPROTOOPT && optname != IPV6_2292PKTOPTIONS) { |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index e8987da0666..9e69eb0ec6d 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -364,7 +364,7 @@ out: | |||
364 | #ifdef CONFIG_IPV6_ROUTER_PREF | 364 | #ifdef CONFIG_IPV6_ROUTER_PREF |
365 | static void rt6_probe(struct rt6_info *rt) | 365 | static void rt6_probe(struct rt6_info *rt) |
366 | { | 366 | { |
367 | struct neighbour *neigh = rt ? dst_get_neighbour(&rt->dst) : NULL; | 367 | struct neighbour *neigh; |
368 | /* | 368 | /* |
369 | * Okay, this does not seem to be appropriate | 369 | * Okay, this does not seem to be appropriate |
370 | * for now, however, we need to check if it | 370 | * for now, however, we need to check if it |
@@ -373,8 +373,10 @@ static void rt6_probe(struct rt6_info *rt) | |||
373 | * Router Reachability Probe MUST be rate-limited | 373 | * Router Reachability Probe MUST be rate-limited |
374 | * to no more than one per minute. | 374 | * to no more than one per minute. |
375 | */ | 375 | */ |
376 | rcu_read_lock(); | ||
377 | neigh = rt ? dst_get_neighbour(&rt->dst) : NULL; | ||
376 | if (!neigh || (neigh->nud_state & NUD_VALID)) | 378 | if (!neigh || (neigh->nud_state & NUD_VALID)) |
377 | return; | 379 | goto out; |
378 | read_lock_bh(&neigh->lock); | 380 | read_lock_bh(&neigh->lock); |
379 | if (!(neigh->nud_state & NUD_VALID) && | 381 | if (!(neigh->nud_state & NUD_VALID) && |
380 | time_after(jiffies, neigh->updated + rt->rt6i_idev->cnf.rtr_probe_interval)) { | 382 | time_after(jiffies, neigh->updated + rt->rt6i_idev->cnf.rtr_probe_interval)) { |
@@ -387,8 +389,11 @@ static void rt6_probe(struct rt6_info *rt) | |||
387 | target = (struct in6_addr *)&neigh->primary_key; | 389 | target = (struct in6_addr *)&neigh->primary_key; |
388 | addrconf_addr_solict_mult(target, &mcaddr); | 390 | addrconf_addr_solict_mult(target, &mcaddr); |
389 | ndisc_send_ns(rt->rt6i_dev, NULL, target, &mcaddr, NULL); | 391 | ndisc_send_ns(rt->rt6i_dev, NULL, target, &mcaddr, NULL); |
390 | } else | 392 | } else { |
391 | read_unlock_bh(&neigh->lock); | 393 | read_unlock_bh(&neigh->lock); |
394 | } | ||
395 | out: | ||
396 | rcu_read_unlock(); | ||
392 | } | 397 | } |
393 | #else | 398 | #else |
394 | static inline void rt6_probe(struct rt6_info *rt) | 399 | static inline void rt6_probe(struct rt6_info *rt) |
@@ -412,8 +417,11 @@ static inline int rt6_check_dev(struct rt6_info *rt, int oif) | |||
412 | 417 | ||
413 | static inline int rt6_check_neigh(struct rt6_info *rt) | 418 | static inline int rt6_check_neigh(struct rt6_info *rt) |
414 | { | 419 | { |
415 | struct neighbour *neigh = dst_get_neighbour(&rt->dst); | 420 | struct neighbour *neigh; |
416 | int m; | 421 | int m; |
422 | |||
423 | rcu_read_lock(); | ||
424 | neigh = dst_get_neighbour(&rt->dst); | ||
417 | if (rt->rt6i_flags & RTF_NONEXTHOP || | 425 | if (rt->rt6i_flags & RTF_NONEXTHOP || |
418 | !(rt->rt6i_flags & RTF_GATEWAY)) | 426 | !(rt->rt6i_flags & RTF_GATEWAY)) |
419 | m = 1; | 427 | m = 1; |
@@ -430,6 +438,7 @@ static inline int rt6_check_neigh(struct rt6_info *rt) | |||
430 | read_unlock_bh(&neigh->lock); | 438 | read_unlock_bh(&neigh->lock); |
431 | } else | 439 | } else |
432 | m = 0; | 440 | m = 0; |
441 | rcu_read_unlock(); | ||
433 | return m; | 442 | return m; |
434 | } | 443 | } |
435 | 444 | ||
@@ -769,7 +778,7 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, | |||
769 | rt->rt6i_dst.plen = 128; | 778 | rt->rt6i_dst.plen = 128; |
770 | rt->rt6i_flags |= RTF_CACHE; | 779 | rt->rt6i_flags |= RTF_CACHE; |
771 | rt->dst.flags |= DST_HOST; | 780 | rt->dst.flags |= DST_HOST; |
772 | dst_set_neighbour(&rt->dst, neigh_clone(dst_get_neighbour(&ort->dst))); | 781 | dst_set_neighbour(&rt->dst, neigh_clone(dst_get_neighbour_raw(&ort->dst))); |
773 | } | 782 | } |
774 | return rt; | 783 | return rt; |
775 | } | 784 | } |
@@ -803,7 +812,7 @@ restart: | |||
803 | dst_hold(&rt->dst); | 812 | dst_hold(&rt->dst); |
804 | read_unlock_bh(&table->tb6_lock); | 813 | read_unlock_bh(&table->tb6_lock); |
805 | 814 | ||
806 | if (!dst_get_neighbour(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP)) | 815 | if (!dst_get_neighbour_raw(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP)) |
807 | nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr); | 816 | nrt = rt6_alloc_cow(rt, &fl6->daddr, &fl6->saddr); |
808 | else if (!(rt->dst.flags & DST_HOST)) | 817 | else if (!(rt->dst.flags & DST_HOST)) |
809 | nrt = rt6_alloc_clone(rt, &fl6->daddr); | 818 | nrt = rt6_alloc_clone(rt, &fl6->daddr); |
@@ -1587,7 +1596,7 @@ void rt6_redirect(const struct in6_addr *dest, const struct in6_addr *src, | |||
1587 | dst_confirm(&rt->dst); | 1596 | dst_confirm(&rt->dst); |
1588 | 1597 | ||
1589 | /* Duplicate redirect: silently ignore. */ | 1598 | /* Duplicate redirect: silently ignore. */ |
1590 | if (neigh == dst_get_neighbour(&rt->dst)) | 1599 | if (neigh == dst_get_neighbour_raw(&rt->dst)) |
1591 | goto out; | 1600 | goto out; |
1592 | 1601 | ||
1593 | nrt = ip6_rt_copy(rt, dest); | 1602 | nrt = ip6_rt_copy(rt, dest); |
@@ -1682,7 +1691,7 @@ again: | |||
1682 | 1. It is connected route. Action: COW | 1691 | 1. It is connected route. Action: COW |
1683 | 2. It is gatewayed route or NONEXTHOP route. Action: clone it. | 1692 | 2. It is gatewayed route or NONEXTHOP route. Action: clone it. |
1684 | */ | 1693 | */ |
1685 | if (!dst_get_neighbour(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP)) | 1694 | if (!dst_get_neighbour_raw(&rt->dst) && !(rt->rt6i_flags & RTF_NONEXTHOP)) |
1686 | nrt = rt6_alloc_cow(rt, daddr, saddr); | 1695 | nrt = rt6_alloc_cow(rt, daddr, saddr); |
1687 | else | 1696 | else |
1688 | nrt = rt6_alloc_clone(rt, daddr); | 1697 | nrt = rt6_alloc_clone(rt, daddr); |
@@ -2326,6 +2335,7 @@ static int rt6_fill_node(struct net *net, | |||
2326 | struct nlmsghdr *nlh; | 2335 | struct nlmsghdr *nlh; |
2327 | long expires; | 2336 | long expires; |
2328 | u32 table; | 2337 | u32 table; |
2338 | struct neighbour *n; | ||
2329 | 2339 | ||
2330 | if (prefix) { /* user wants prefix routes only */ | 2340 | if (prefix) { /* user wants prefix routes only */ |
2331 | if (!(rt->rt6i_flags & RTF_PREFIX_RT)) { | 2341 | if (!(rt->rt6i_flags & RTF_PREFIX_RT)) { |
@@ -2414,8 +2424,11 @@ static int rt6_fill_node(struct net *net, | |||
2414 | if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0) | 2424 | if (rtnetlink_put_metrics(skb, dst_metrics_ptr(&rt->dst)) < 0) |
2415 | goto nla_put_failure; | 2425 | goto nla_put_failure; |
2416 | 2426 | ||
2417 | if (dst_get_neighbour(&rt->dst)) | 2427 | rcu_read_lock(); |
2418 | NLA_PUT(skb, RTA_GATEWAY, 16, &dst_get_neighbour(&rt->dst)->primary_key); | 2428 | n = dst_get_neighbour(&rt->dst); |
2429 | if (n) | ||
2430 | NLA_PUT(skb, RTA_GATEWAY, 16, &n->primary_key); | ||
2431 | rcu_read_unlock(); | ||
2419 | 2432 | ||
2420 | if (rt->dst.dev) | 2433 | if (rt->dst.dev) |
2421 | NLA_PUT_U32(skb, RTA_OIF, rt->rt6i_dev->ifindex); | 2434 | NLA_PUT_U32(skb, RTA_OIF, rt->rt6i_dev->ifindex); |
@@ -2608,12 +2621,14 @@ static int rt6_info_route(struct rt6_info *rt, void *p_arg) | |||
2608 | #else | 2621 | #else |
2609 | seq_puts(m, "00000000000000000000000000000000 00 "); | 2622 | seq_puts(m, "00000000000000000000000000000000 00 "); |
2610 | #endif | 2623 | #endif |
2624 | rcu_read_lock(); | ||
2611 | n = dst_get_neighbour(&rt->dst); | 2625 | n = dst_get_neighbour(&rt->dst); |
2612 | if (n) { | 2626 | if (n) { |
2613 | seq_printf(m, "%pi6", n->primary_key); | 2627 | seq_printf(m, "%pi6", n->primary_key); |
2614 | } else { | 2628 | } else { |
2615 | seq_puts(m, "00000000000000000000000000000000"); | 2629 | seq_puts(m, "00000000000000000000000000000000"); |
2616 | } | 2630 | } |
2631 | rcu_read_unlock(); | ||
2617 | seq_printf(m, " %08x %08x %08x %08x %8s\n", | 2632 | seq_printf(m, " %08x %08x %08x %08x %8s\n", |
2618 | rt->rt6i_metric, atomic_read(&rt->dst.__refcnt), | 2633 | rt->rt6i_metric, atomic_read(&rt->dst.__refcnt), |
2619 | rt->dst.__use, rt->rt6i_flags, | 2634 | rt->dst.__use, rt->rt6i_flags, |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 07bf1085458..00b15ac7a70 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -672,6 +672,9 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, | |||
672 | if (skb->protocol != htons(ETH_P_IPV6)) | 672 | if (skb->protocol != htons(ETH_P_IPV6)) |
673 | goto tx_error; | 673 | goto tx_error; |
674 | 674 | ||
675 | if (tos == 1) | ||
676 | tos = ipv6_get_dsfield(iph6); | ||
677 | |||
675 | /* ISATAP (RFC4214) - must come before 6to4 */ | 678 | /* ISATAP (RFC4214) - must come before 6to4 */ |
676 | if (dev->priv_flags & IFF_ISATAP) { | 679 | if (dev->priv_flags & IFF_ISATAP) { |
677 | struct neighbour *neigh = NULL; | 680 | struct neighbour *neigh = NULL; |
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index 89d5bf80622..ac838965ff3 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c | |||
@@ -165,7 +165,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb) | |||
165 | int mss; | 165 | int mss; |
166 | struct dst_entry *dst; | 166 | struct dst_entry *dst; |
167 | __u8 rcv_wscale; | 167 | __u8 rcv_wscale; |
168 | bool ecn_ok; | 168 | bool ecn_ok = false; |
169 | 169 | ||
170 | if (!sysctl_tcp_syncookies || !th->ack || th->rst) | 170 | if (!sysctl_tcp_syncookies || !th->ack || th->rst) |
171 | goto out; | 171 | goto out; |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 78aa53492b3..d1fb63f4aeb 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -61,6 +61,7 @@ | |||
61 | #include <net/timewait_sock.h> | 61 | #include <net/timewait_sock.h> |
62 | #include <net/netdma.h> | 62 | #include <net/netdma.h> |
63 | #include <net/inet_common.h> | 63 | #include <net/inet_common.h> |
64 | #include <net/secure_seq.h> | ||
64 | 65 | ||
65 | #include <asm/uaccess.h> | 66 | #include <asm/uaccess.h> |
66 | 67 | ||
diff --git a/net/iucv/iucv.c b/net/iucv/iucv.c index 7f9124914b1..075a3808aa4 100644 --- a/net/iucv/iucv.c +++ b/net/iucv/iucv.c | |||
@@ -51,7 +51,7 @@ | |||
51 | #include <linux/cpu.h> | 51 | #include <linux/cpu.h> |
52 | #include <linux/reboot.h> | 52 | #include <linux/reboot.h> |
53 | #include <net/iucv/iucv.h> | 53 | #include <net/iucv/iucv.h> |
54 | #include <asm/atomic.h> | 54 | #include <linux/atomic.h> |
55 | #include <asm/ebcdic.h> | 55 | #include <asm/ebcdic.h> |
56 | #include <asm/io.h> | 56 | #include <asm/io.h> |
57 | #include <asm/irq.h> | 57 | #include <asm/irq.h> |
@@ -1988,12 +1988,13 @@ static int __init iucv_init(void) | |||
1988 | rc = -EPROTONOSUPPORT; | 1988 | rc = -EPROTONOSUPPORT; |
1989 | goto out; | 1989 | goto out; |
1990 | } | 1990 | } |
1991 | ctl_set_bit(0, 1); | ||
1991 | rc = iucv_query_maxconn(); | 1992 | rc = iucv_query_maxconn(); |
1992 | if (rc) | 1993 | if (rc) |
1993 | goto out; | 1994 | goto out_ctl; |
1994 | rc = register_external_interrupt(0x4000, iucv_external_interrupt); | 1995 | rc = register_external_interrupt(0x4000, iucv_external_interrupt); |
1995 | if (rc) | 1996 | if (rc) |
1996 | goto out; | 1997 | goto out_ctl; |
1997 | iucv_root = root_device_register("iucv"); | 1998 | iucv_root = root_device_register("iucv"); |
1998 | if (IS_ERR(iucv_root)) { | 1999 | if (IS_ERR(iucv_root)) { |
1999 | rc = PTR_ERR(iucv_root); | 2000 | rc = PTR_ERR(iucv_root); |
@@ -2055,6 +2056,8 @@ out_free: | |||
2055 | root_device_unregister(iucv_root); | 2056 | root_device_unregister(iucv_root); |
2056 | out_int: | 2057 | out_int: |
2057 | unregister_external_interrupt(0x4000, iucv_external_interrupt); | 2058 | unregister_external_interrupt(0x4000, iucv_external_interrupt); |
2059 | out_ctl: | ||
2060 | ctl_clear_bit(0, 1); | ||
2058 | out: | 2061 | out: |
2059 | return rc; | 2062 | return rc; |
2060 | } | 2063 | } |
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index ed8a2335442..ad4ac2601a5 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c | |||
@@ -55,7 +55,7 @@ | |||
55 | #include <net/protocol.h> | 55 | #include <net/protocol.h> |
56 | 56 | ||
57 | #include <asm/byteorder.h> | 57 | #include <asm/byteorder.h> |
58 | #include <asm/atomic.h> | 58 | #include <linux/atomic.h> |
59 | 59 | ||
60 | #include "l2tp_core.h" | 60 | #include "l2tp_core.h" |
61 | 61 | ||
diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index a8193f52c13..d2726a74597 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c | |||
@@ -103,7 +103,7 @@ static struct net_device_ops l2tp_eth_netdev_ops = { | |||
103 | static void l2tp_eth_dev_setup(struct net_device *dev) | 103 | static void l2tp_eth_dev_setup(struct net_device *dev) |
104 | { | 104 | { |
105 | ether_setup(dev); | 105 | ether_setup(dev); |
106 | 106 | dev->priv_flags &= ~IFF_TX_SKB_SHARING; | |
107 | dev->netdev_ops = &l2tp_eth_netdev_ops; | 107 | dev->netdev_ops = &l2tp_eth_netdev_ops; |
108 | dev->destructor = free_netdev; | 108 | dev->destructor = free_netdev; |
109 | } | 109 | } |
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index 39a21d0c61c..f42cd091596 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c | |||
@@ -97,7 +97,7 @@ | |||
97 | #include <net/xfrm.h> | 97 | #include <net/xfrm.h> |
98 | 98 | ||
99 | #include <asm/byteorder.h> | 99 | #include <asm/byteorder.h> |
100 | #include <asm/atomic.h> | 100 | #include <linux/atomic.h> |
101 | 101 | ||
102 | #include "l2tp_core.h" | 102 | #include "l2tp_core.h" |
103 | 103 | ||
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index ebadb9ac9a7..fd1aaf2a4a6 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
@@ -104,14 +104,22 @@ void ieee80211_stop_rx_ba_session(struct ieee80211_vif *vif, u16 ba_rx_bitmap, | |||
104 | const u8 *addr) | 104 | const u8 *addr) |
105 | { | 105 | { |
106 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | 106 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
107 | struct sta_info *sta = sta_info_get(sdata, addr); | 107 | struct sta_info *sta; |
108 | int i; | 108 | int i; |
109 | 109 | ||
110 | rcu_read_lock(); | ||
111 | sta = sta_info_get(sdata, addr); | ||
112 | if (!sta) { | ||
113 | rcu_read_unlock(); | ||
114 | return; | ||
115 | } | ||
116 | |||
110 | for (i = 0; i < STA_TID_NUM; i++) | 117 | for (i = 0; i < STA_TID_NUM; i++) |
111 | if (ba_rx_bitmap & BIT(i)) | 118 | if (ba_rx_bitmap & BIT(i)) |
112 | set_bit(i, sta->ampdu_mlme.tid_rx_stop_requested); | 119 | set_bit(i, sta->ampdu_mlme.tid_rx_stop_requested); |
113 | 120 | ||
114 | ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work); | 121 | ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work); |
122 | rcu_read_unlock(); | ||
115 | } | 123 | } |
116 | EXPORT_SYMBOL(ieee80211_stop_rx_ba_session); | 124 | EXPORT_SYMBOL(ieee80211_stop_rx_ba_session); |
117 | 125 | ||
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index bfc36e90476..3d1b091d9b2 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1255,6 +1255,10 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy, | |||
1255 | */ | 1255 | */ |
1256 | p.uapsd = false; | 1256 | p.uapsd = false; |
1257 | 1257 | ||
1258 | if (params->queue >= local->hw.queues) | ||
1259 | return -EINVAL; | ||
1260 | |||
1261 | local->tx_conf[params->queue] = p; | ||
1258 | if (drv_conf_tx(local, params->queue, &p)) { | 1262 | if (drv_conf_tx(local, params->queue, &p)) { |
1259 | wiphy_debug(local->hw.wiphy, | 1263 | wiphy_debug(local->hw.wiphy, |
1260 | "failed to set TX queue parameters for queue %d\n", | 1264 | "failed to set TX queue parameters for queue %d\n", |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index b2d6bba4405..1425380983f 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -130,6 +130,37 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local, | |||
130 | trace_drv_return_void(local); | 130 | trace_drv_return_void(local); |
131 | } | 131 | } |
132 | 132 | ||
133 | static inline int drv_tx_sync(struct ieee80211_local *local, | ||
134 | struct ieee80211_sub_if_data *sdata, | ||
135 | const u8 *bssid, | ||
136 | enum ieee80211_tx_sync_type type) | ||
137 | { | ||
138 | int ret = 0; | ||
139 | |||
140 | might_sleep(); | ||
141 | |||
142 | trace_drv_tx_sync(local, sdata, bssid, type); | ||
143 | if (local->ops->tx_sync) | ||
144 | ret = local->ops->tx_sync(&local->hw, &sdata->vif, | ||
145 | bssid, type); | ||
146 | trace_drv_return_int(local, ret); | ||
147 | return ret; | ||
148 | } | ||
149 | |||
150 | static inline void drv_finish_tx_sync(struct ieee80211_local *local, | ||
151 | struct ieee80211_sub_if_data *sdata, | ||
152 | const u8 *bssid, | ||
153 | enum ieee80211_tx_sync_type type) | ||
154 | { | ||
155 | might_sleep(); | ||
156 | |||
157 | trace_drv_finish_tx_sync(local, sdata, bssid, type); | ||
158 | if (local->ops->finish_tx_sync) | ||
159 | local->ops->finish_tx_sync(&local->hw, &sdata->vif, | ||
160 | bssid, type); | ||
161 | trace_drv_return_void(local); | ||
162 | } | ||
163 | |||
133 | static inline u64 drv_prepare_multicast(struct ieee80211_local *local, | 164 | static inline u64 drv_prepare_multicast(struct ieee80211_local *local, |
134 | struct netdev_hw_addr_list *mc_list) | 165 | struct netdev_hw_addr_list *mc_list) |
135 | { | 166 | { |
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h index 4470f6e8b84..f47b00dc7af 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/driver-trace.h | |||
@@ -319,6 +319,49 @@ TRACE_EVENT(drv_bss_info_changed, | |||
319 | ) | 319 | ) |
320 | ); | 320 | ); |
321 | 321 | ||
322 | DECLARE_EVENT_CLASS(tx_sync_evt, | ||
323 | TP_PROTO(struct ieee80211_local *local, | ||
324 | struct ieee80211_sub_if_data *sdata, | ||
325 | const u8 *bssid, | ||
326 | enum ieee80211_tx_sync_type type), | ||
327 | TP_ARGS(local, sdata, bssid, type), | ||
328 | |||
329 | TP_STRUCT__entry( | ||
330 | LOCAL_ENTRY | ||
331 | VIF_ENTRY | ||
332 | __array(char, bssid, ETH_ALEN) | ||
333 | __field(u32, sync_type) | ||
334 | ), | ||
335 | |||
336 | TP_fast_assign( | ||
337 | LOCAL_ASSIGN; | ||
338 | VIF_ASSIGN; | ||
339 | memcpy(__entry->bssid, bssid, ETH_ALEN); | ||
340 | __entry->sync_type = type; | ||
341 | ), | ||
342 | |||
343 | TP_printk( | ||
344 | LOCAL_PR_FMT VIF_PR_FMT " bssid:%pM type:%d", | ||
345 | LOCAL_PR_ARG, VIF_PR_ARG, __entry->bssid, __entry->sync_type | ||
346 | ) | ||
347 | ); | ||
348 | |||
349 | DEFINE_EVENT(tx_sync_evt, drv_tx_sync, | ||
350 | TP_PROTO(struct ieee80211_local *local, | ||
351 | struct ieee80211_sub_if_data *sdata, | ||
352 | const u8 *bssid, | ||
353 | enum ieee80211_tx_sync_type type), | ||
354 | TP_ARGS(local, sdata, bssid, type) | ||
355 | ); | ||
356 | |||
357 | DEFINE_EVENT(tx_sync_evt, drv_finish_tx_sync, | ||
358 | TP_PROTO(struct ieee80211_local *local, | ||
359 | struct ieee80211_sub_if_data *sdata, | ||
360 | const u8 *bssid, | ||
361 | enum ieee80211_tx_sync_type type), | ||
362 | TP_ARGS(local, sdata, bssid, type) | ||
363 | ); | ||
364 | |||
322 | TRACE_EVENT(drv_prepare_multicast, | 365 | TRACE_EVENT(drv_prepare_multicast, |
323 | TP_PROTO(struct ieee80211_local *local, int mc_count), | 366 | TP_PROTO(struct ieee80211_local *local, int mc_count), |
324 | 367 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index dda0d1ab34f..400c09bea63 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -323,6 +323,7 @@ struct ieee80211_work { | |||
323 | u8 key[WLAN_KEY_LEN_WEP104]; | 323 | u8 key[WLAN_KEY_LEN_WEP104]; |
324 | u8 key_len, key_idx; | 324 | u8 key_len, key_idx; |
325 | bool privacy; | 325 | bool privacy; |
326 | bool synced; | ||
326 | } probe_auth; | 327 | } probe_auth; |
327 | struct { | 328 | struct { |
328 | struct cfg80211_bss *bss; | 329 | struct cfg80211_bss *bss; |
@@ -336,6 +337,7 @@ struct ieee80211_work { | |||
336 | u8 ssid_len; | 337 | u8 ssid_len; |
337 | u8 supp_rates_len; | 338 | u8 supp_rates_len; |
338 | bool wmm_used, use_11n, uapsd_used; | 339 | bool wmm_used, use_11n, uapsd_used; |
340 | bool synced; | ||
339 | } assoc; | 341 | } assoc; |
340 | struct { | 342 | struct { |
341 | u32 duration; | 343 | u32 duration; |
@@ -746,6 +748,7 @@ struct ieee80211_local { | |||
746 | struct workqueue_struct *workqueue; | 748 | struct workqueue_struct *workqueue; |
747 | 749 | ||
748 | unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES]; | 750 | unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES]; |
751 | struct ieee80211_tx_queue_params tx_conf[IEEE80211_MAX_QUEUES]; | ||
749 | /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */ | 752 | /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */ |
750 | spinlock_t queue_stop_reason_lock; | 753 | spinlock_t queue_stop_reason_lock; |
751 | 754 | ||
@@ -1376,14 +1379,14 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | |||
1376 | enum ieee80211_band band, u32 rate_mask, | 1379 | enum ieee80211_band band, u32 rate_mask, |
1377 | u8 channel); | 1380 | u8 channel); |
1378 | struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, | 1381 | struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, |
1379 | u8 *dst, | 1382 | u8 *dst, u32 ratemask, |
1380 | const u8 *ssid, size_t ssid_len, | 1383 | const u8 *ssid, size_t ssid_len, |
1381 | const u8 *ie, size_t ie_len, | 1384 | const u8 *ie, size_t ie_len, |
1382 | bool directed); | 1385 | bool directed); |
1383 | void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | 1386 | void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, |
1384 | const u8 *ssid, size_t ssid_len, | 1387 | const u8 *ssid, size_t ssid_len, |
1385 | const u8 *ie, size_t ie_len, | 1388 | const u8 *ie, size_t ie_len, |
1386 | bool directed); | 1389 | u32 ratemask, bool directed); |
1387 | 1390 | ||
1388 | void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, | 1391 | void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, |
1389 | const size_t supp_rates_len, | 1392 | const size_t supp_rates_len, |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index cd5fb40d3fd..556e7e6ddf0 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -698,6 +698,7 @@ static const struct net_device_ops ieee80211_monitorif_ops = { | |||
698 | static void ieee80211_if_setup(struct net_device *dev) | 698 | static void ieee80211_if_setup(struct net_device *dev) |
699 | { | 699 | { |
700 | ether_setup(dev); | 700 | ether_setup(dev); |
701 | dev->priv_flags &= ~IFF_TX_SKB_SHARING; | ||
701 | dev->netdev_ops = &ieee80211_dataif_ops; | 702 | dev->netdev_ops = &ieee80211_dataif_ops; |
702 | dev->destructor = free_netdev; | 703 | dev->destructor = free_netdev; |
703 | } | 704 | } |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 739bee13e81..5150c6d11b5 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -278,7 +278,7 @@ static void __ieee80211_key_replace(struct ieee80211_sub_if_data *sdata, | |||
278 | bool defunikey, defmultikey, defmgmtkey; | 278 | bool defunikey, defmultikey, defmgmtkey; |
279 | 279 | ||
280 | if (new) | 280 | if (new) |
281 | list_add(&new->list, &sdata->key_list); | 281 | list_add_tail(&new->list, &sdata->key_list); |
282 | 282 | ||
283 | if (sta && pairwise) { | 283 | if (sta && pairwise) { |
284 | rcu_assign_pointer(sta->ptk, new); | 284 | rcu_assign_pointer(sta->ptk, new); |
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 2b18053070c..3460108810d 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
@@ -57,29 +57,29 @@ static inline u32 u16_field_get(u8 *preq_elem, int offset, bool ae) | |||
57 | #define PREQ_IE_TTL(x) (*(x + 2)) | 57 | #define PREQ_IE_TTL(x) (*(x + 2)) |
58 | #define PREQ_IE_PREQ_ID(x) u32_field_get(x, 3, 0) | 58 | #define PREQ_IE_PREQ_ID(x) u32_field_get(x, 3, 0) |
59 | #define PREQ_IE_ORIG_ADDR(x) (x + 7) | 59 | #define PREQ_IE_ORIG_ADDR(x) (x + 7) |
60 | #define PREQ_IE_ORIG_SN(x) u32_field_get(x, 13, 0); | 60 | #define PREQ_IE_ORIG_SN(x) u32_field_get(x, 13, 0) |
61 | #define PREQ_IE_LIFETIME(x) u32_field_get(x, 17, AE_F_SET(x)); | 61 | #define PREQ_IE_LIFETIME(x) u32_field_get(x, 17, AE_F_SET(x)) |
62 | #define PREQ_IE_METRIC(x) u32_field_get(x, 21, AE_F_SET(x)); | 62 | #define PREQ_IE_METRIC(x) u32_field_get(x, 21, AE_F_SET(x)) |
63 | #define PREQ_IE_TARGET_F(x) (*(AE_F_SET(x) ? x + 32 : x + 26)) | 63 | #define PREQ_IE_TARGET_F(x) (*(AE_F_SET(x) ? x + 32 : x + 26)) |
64 | #define PREQ_IE_TARGET_ADDR(x) (AE_F_SET(x) ? x + 33 : x + 27) | 64 | #define PREQ_IE_TARGET_ADDR(x) (AE_F_SET(x) ? x + 33 : x + 27) |
65 | #define PREQ_IE_TARGET_SN(x) u32_field_get(x, 33, AE_F_SET(x)); | 65 | #define PREQ_IE_TARGET_SN(x) u32_field_get(x, 33, AE_F_SET(x)) |
66 | 66 | ||
67 | 67 | ||
68 | #define PREP_IE_FLAGS(x) PREQ_IE_FLAGS(x) | 68 | #define PREP_IE_FLAGS(x) PREQ_IE_FLAGS(x) |
69 | #define PREP_IE_HOPCOUNT(x) PREQ_IE_HOPCOUNT(x) | 69 | #define PREP_IE_HOPCOUNT(x) PREQ_IE_HOPCOUNT(x) |
70 | #define PREP_IE_TTL(x) PREQ_IE_TTL(x) | 70 | #define PREP_IE_TTL(x) PREQ_IE_TTL(x) |
71 | #define PREP_IE_ORIG_ADDR(x) (x + 3) | 71 | #define PREP_IE_ORIG_ADDR(x) (x + 3) |
72 | #define PREP_IE_ORIG_SN(x) u32_field_get(x, 9, 0); | 72 | #define PREP_IE_ORIG_SN(x) u32_field_get(x, 9, 0) |
73 | #define PREP_IE_LIFETIME(x) u32_field_get(x, 13, AE_F_SET(x)); | 73 | #define PREP_IE_LIFETIME(x) u32_field_get(x, 13, AE_F_SET(x)) |
74 | #define PREP_IE_METRIC(x) u32_field_get(x, 17, AE_F_SET(x)); | 74 | #define PREP_IE_METRIC(x) u32_field_get(x, 17, AE_F_SET(x)) |
75 | #define PREP_IE_TARGET_ADDR(x) (AE_F_SET(x) ? x + 27 : x + 21) | 75 | #define PREP_IE_TARGET_ADDR(x) (AE_F_SET(x) ? x + 27 : x + 21) |
76 | #define PREP_IE_TARGET_SN(x) u32_field_get(x, 27, AE_F_SET(x)); | 76 | #define PREP_IE_TARGET_SN(x) u32_field_get(x, 27, AE_F_SET(x)) |
77 | 77 | ||
78 | #define PERR_IE_TTL(x) (*(x)) | 78 | #define PERR_IE_TTL(x) (*(x)) |
79 | #define PERR_IE_TARGET_FLAGS(x) (*(x + 2)) | 79 | #define PERR_IE_TARGET_FLAGS(x) (*(x + 2)) |
80 | #define PERR_IE_TARGET_ADDR(x) (x + 3) | 80 | #define PERR_IE_TARGET_ADDR(x) (x + 3) |
81 | #define PERR_IE_TARGET_SN(x) u32_field_get(x, 9, 0); | 81 | #define PERR_IE_TARGET_SN(x) u32_field_get(x, 9, 0) |
82 | #define PERR_IE_TARGET_RCODE(x) u16_field_get(x, 13, 0); | 82 | #define PERR_IE_TARGET_RCODE(x) u16_field_get(x, 13, 0) |
83 | 83 | ||
84 | #define MSEC_TO_TU(x) (x*1000/1024) | 84 | #define MSEC_TO_TU(x) (x*1000/1024) |
85 | #define SN_GT(x, y) ((long) (y) - (long) (x) < 0) | 85 | #define SN_GT(x, y) ((long) (y) - (long) (x) < 0) |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index c99237cd4b9..d6470c7fd6c 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -917,6 +917,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, | |||
917 | params.aifs, params.cw_min, params.cw_max, | 917 | params.aifs, params.cw_min, params.cw_max, |
918 | params.txop, params.uapsd); | 918 | params.txop, params.uapsd); |
919 | #endif | 919 | #endif |
920 | local->tx_conf[queue] = params; | ||
920 | if (drv_conf_tx(local, queue, ¶ms)) | 921 | if (drv_conf_tx(local, queue, ¶ms)) |
921 | wiphy_debug(local->hw.wiphy, | 922 | wiphy_debug(local->hw.wiphy, |
922 | "failed to set TX queue parameters for queue %d\n", | 923 | "failed to set TX queue parameters for queue %d\n", |
@@ -1219,7 +1220,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) | |||
1219 | } else { | 1220 | } else { |
1220 | ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); | 1221 | ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); |
1221 | ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0, | 1222 | ieee80211_send_probe_req(sdata, dst, ssid + 2, ssid[1], NULL, 0, |
1222 | true); | 1223 | (u32) -1, true); |
1223 | } | 1224 | } |
1224 | 1225 | ||
1225 | ifmgd->probe_send_count++; | 1226 | ifmgd->probe_send_count++; |
@@ -1304,7 +1305,8 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw, | |||
1304 | 1305 | ||
1305 | ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); | 1306 | ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); |
1306 | skb = ieee80211_build_probe_req(sdata, ifmgd->associated->bssid, | 1307 | skb = ieee80211_build_probe_req(sdata, ifmgd->associated->bssid, |
1307 | ssid + 2, ssid[1], NULL, 0, true); | 1308 | (u32) -1, ssid + 2, ssid[1], |
1309 | NULL, 0, true); | ||
1308 | 1310 | ||
1309 | return skb; | 1311 | return skb; |
1310 | } | 1312 | } |
@@ -2333,14 +2335,16 @@ static enum work_done_result | |||
2333 | ieee80211_probe_auth_done(struct ieee80211_work *wk, | 2335 | ieee80211_probe_auth_done(struct ieee80211_work *wk, |
2334 | struct sk_buff *skb) | 2336 | struct sk_buff *skb) |
2335 | { | 2337 | { |
2338 | struct ieee80211_local *local = wk->sdata->local; | ||
2339 | |||
2336 | if (!skb) { | 2340 | if (!skb) { |
2337 | cfg80211_send_auth_timeout(wk->sdata->dev, wk->filter_ta); | 2341 | cfg80211_send_auth_timeout(wk->sdata->dev, wk->filter_ta); |
2338 | return WORK_DONE_DESTROY; | 2342 | goto destroy; |
2339 | } | 2343 | } |
2340 | 2344 | ||
2341 | if (wk->type == IEEE80211_WORK_AUTH) { | 2345 | if (wk->type == IEEE80211_WORK_AUTH) { |
2342 | cfg80211_send_rx_auth(wk->sdata->dev, skb->data, skb->len); | 2346 | cfg80211_send_rx_auth(wk->sdata->dev, skb->data, skb->len); |
2343 | return WORK_DONE_DESTROY; | 2347 | goto destroy; |
2344 | } | 2348 | } |
2345 | 2349 | ||
2346 | mutex_lock(&wk->sdata->u.mgd.mtx); | 2350 | mutex_lock(&wk->sdata->u.mgd.mtx); |
@@ -2350,6 +2354,12 @@ ieee80211_probe_auth_done(struct ieee80211_work *wk, | |||
2350 | wk->type = IEEE80211_WORK_AUTH; | 2354 | wk->type = IEEE80211_WORK_AUTH; |
2351 | wk->probe_auth.tries = 0; | 2355 | wk->probe_auth.tries = 0; |
2352 | return WORK_DONE_REQUEUE; | 2356 | return WORK_DONE_REQUEUE; |
2357 | destroy: | ||
2358 | if (wk->probe_auth.synced) | ||
2359 | drv_finish_tx_sync(local, wk->sdata, wk->filter_ta, | ||
2360 | IEEE80211_TX_SYNC_AUTH); | ||
2361 | |||
2362 | return WORK_DONE_DESTROY; | ||
2353 | } | 2363 | } |
2354 | 2364 | ||
2355 | int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | 2365 | int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, |
@@ -2422,6 +2432,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
2422 | static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk, | 2432 | static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk, |
2423 | struct sk_buff *skb) | 2433 | struct sk_buff *skb) |
2424 | { | 2434 | { |
2435 | struct ieee80211_local *local = wk->sdata->local; | ||
2425 | struct ieee80211_mgmt *mgmt; | 2436 | struct ieee80211_mgmt *mgmt; |
2426 | struct ieee80211_rx_status *rx_status; | 2437 | struct ieee80211_rx_status *rx_status; |
2427 | struct ieee802_11_elems elems; | 2438 | struct ieee802_11_elems elems; |
@@ -2429,7 +2440,7 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk, | |||
2429 | 2440 | ||
2430 | if (!skb) { | 2441 | if (!skb) { |
2431 | cfg80211_send_assoc_timeout(wk->sdata->dev, wk->filter_ta); | 2442 | cfg80211_send_assoc_timeout(wk->sdata->dev, wk->filter_ta); |
2432 | return WORK_DONE_DESTROY; | 2443 | goto destroy; |
2433 | } | 2444 | } |
2434 | 2445 | ||
2435 | if (wk->type == IEEE80211_WORK_ASSOC_BEACON_WAIT) { | 2446 | if (wk->type == IEEE80211_WORK_ASSOC_BEACON_WAIT) { |
@@ -2449,6 +2460,10 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk, | |||
2449 | status = le16_to_cpu(mgmt->u.assoc_resp.status_code); | 2460 | status = le16_to_cpu(mgmt->u.assoc_resp.status_code); |
2450 | 2461 | ||
2451 | if (status == WLAN_STATUS_SUCCESS) { | 2462 | if (status == WLAN_STATUS_SUCCESS) { |
2463 | if (wk->assoc.synced) | ||
2464 | drv_finish_tx_sync(local, wk->sdata, wk->filter_ta, | ||
2465 | IEEE80211_TX_SYNC_ASSOC); | ||
2466 | |||
2452 | mutex_lock(&wk->sdata->u.mgd.mtx); | 2467 | mutex_lock(&wk->sdata->u.mgd.mtx); |
2453 | if (!ieee80211_assoc_success(wk, mgmt, skb->len)) { | 2468 | if (!ieee80211_assoc_success(wk, mgmt, skb->len)) { |
2454 | mutex_unlock(&wk->sdata->u.mgd.mtx); | 2469 | mutex_unlock(&wk->sdata->u.mgd.mtx); |
@@ -2462,6 +2477,11 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk, | |||
2462 | } | 2477 | } |
2463 | 2478 | ||
2464 | cfg80211_send_rx_assoc(wk->sdata->dev, skb->data, skb->len); | 2479 | cfg80211_send_rx_assoc(wk->sdata->dev, skb->data, skb->len); |
2480 | destroy: | ||
2481 | if (wk->assoc.synced) | ||
2482 | drv_finish_tx_sync(local, wk->sdata, wk->filter_ta, | ||
2483 | IEEE80211_TX_SYNC_ASSOC); | ||
2484 | |||
2465 | return WORK_DONE_DESTROY; | 2485 | return WORK_DONE_DESTROY; |
2466 | } | 2486 | } |
2467 | 2487 | ||
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index f87e993e713..6326d343986 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c | |||
@@ -34,6 +34,9 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
34 | struct ieee80211_sub_if_data *sdata; | 34 | struct ieee80211_sub_if_data *sdata; |
35 | struct sta_info *sta; | 35 | struct sta_info *sta; |
36 | 36 | ||
37 | if (!local->open_count) | ||
38 | goto suspend; | ||
39 | |||
37 | ieee80211_scan_cancel(local); | 40 | ieee80211_scan_cancel(local); |
38 | 41 | ||
39 | if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { | 42 | if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 08a45ac3d6f..6f09eca0111 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -228,7 +228,6 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) | |||
228 | static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) | 228 | static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) |
229 | { | 229 | { |
230 | struct cfg80211_scan_request *req = local->scan_req; | 230 | struct cfg80211_scan_request *req = local->scan_req; |
231 | struct ieee80211_sub_if_data *sdata = local->scan_sdata; | ||
232 | enum ieee80211_band band; | 231 | enum ieee80211_band band; |
233 | int i, ielen, n_chans; | 232 | int i, ielen, n_chans; |
234 | 233 | ||
@@ -253,7 +252,7 @@ static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) | |||
253 | 252 | ||
254 | ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie, | 253 | ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie, |
255 | req->ie, req->ie_len, band, | 254 | req->ie, req->ie_len, band, |
256 | sdata->rc_rateidx_mask[band], 0); | 255 | req->rates[band], 0); |
257 | local->hw_scan_req->ie_len = ielen; | 256 | local->hw_scan_req->ie_len = ielen; |
258 | 257 | ||
259 | return true; | 258 | return true; |
@@ -653,6 +652,7 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local, | |||
653 | { | 652 | { |
654 | int i; | 653 | int i; |
655 | struct ieee80211_sub_if_data *sdata = local->scan_sdata; | 654 | struct ieee80211_sub_if_data *sdata = local->scan_sdata; |
655 | enum ieee80211_band band = local->hw.conf.channel->band; | ||
656 | 656 | ||
657 | for (i = 0; i < local->scan_req->n_ssids; i++) | 657 | for (i = 0; i < local->scan_req->n_ssids; i++) |
658 | ieee80211_send_probe_req( | 658 | ieee80211_send_probe_req( |
@@ -660,7 +660,7 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local, | |||
660 | local->scan_req->ssids[i].ssid, | 660 | local->scan_req->ssids[i].ssid, |
661 | local->scan_req->ssids[i].ssid_len, | 661 | local->scan_req->ssids[i].ssid_len, |
662 | local->scan_req->ie, local->scan_req->ie_len, | 662 | local->scan_req->ie, local->scan_req->ie_len, |
663 | false); | 663 | local->scan_req->rates[band], false); |
664 | 664 | ||
665 | /* | 665 | /* |
666 | * After sending probe requests, wait for probe responses | 666 | * After sending probe requests, wait for probe responses |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index b83870bf60f..3db78b696c5 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -97,7 +97,6 @@ struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata, | |||
97 | struct sta_info *sta; | 97 | struct sta_info *sta; |
98 | 98 | ||
99 | sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)], | 99 | sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)], |
100 | rcu_read_lock_held() || | ||
101 | lockdep_is_held(&local->sta_lock) || | 100 | lockdep_is_held(&local->sta_lock) || |
102 | lockdep_is_held(&local->sta_mtx)); | 101 | lockdep_is_held(&local->sta_mtx)); |
103 | while (sta) { | 102 | while (sta) { |
@@ -105,7 +104,6 @@ struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata, | |||
105 | memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) | 104 | memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) |
106 | break; | 105 | break; |
107 | sta = rcu_dereference_check(sta->hnext, | 106 | sta = rcu_dereference_check(sta->hnext, |
108 | rcu_read_lock_held() || | ||
109 | lockdep_is_held(&local->sta_lock) || | 107 | lockdep_is_held(&local->sta_lock) || |
110 | lockdep_is_held(&local->sta_mtx)); | 108 | lockdep_is_held(&local->sta_mtx)); |
111 | } | 109 | } |
@@ -123,7 +121,6 @@ struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata, | |||
123 | struct sta_info *sta; | 121 | struct sta_info *sta; |
124 | 122 | ||
125 | sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)], | 123 | sta = rcu_dereference_check(local->sta_hash[STA_HASH(addr)], |
126 | rcu_read_lock_held() || | ||
127 | lockdep_is_held(&local->sta_lock) || | 124 | lockdep_is_held(&local->sta_lock) || |
128 | lockdep_is_held(&local->sta_mtx)); | 125 | lockdep_is_held(&local->sta_mtx)); |
129 | while (sta) { | 126 | while (sta) { |
@@ -132,7 +129,6 @@ struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata, | |||
132 | memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) | 129 | memcmp(sta->sta.addr, addr, ETH_ALEN) == 0) |
133 | break; | 130 | break; |
134 | sta = rcu_dereference_check(sta->hnext, | 131 | sta = rcu_dereference_check(sta->hnext, |
135 | rcu_read_lock_held() || | ||
136 | lockdep_is_held(&local->sta_lock) || | 132 | lockdep_is_held(&local->sta_lock) || |
137 | lockdep_is_held(&local->sta_mtx)); | 133 | lockdep_is_held(&local->sta_mtx)); |
138 | } | 134 | } |
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c index cc79e697cdb..f49d00a4c7f 100644 --- a/net/mac80211/tkip.c +++ b/net/mac80211/tkip.c | |||
@@ -185,6 +185,17 @@ void ieee80211_get_tkip_p1k_iv(struct ieee80211_key_conf *keyconf, | |||
185 | } | 185 | } |
186 | EXPORT_SYMBOL(ieee80211_get_tkip_p1k_iv); | 186 | EXPORT_SYMBOL(ieee80211_get_tkip_p1k_iv); |
187 | 187 | ||
188 | void ieee80211_get_tkip_rx_p1k(struct ieee80211_key_conf *keyconf, | ||
189 | const u8 *ta, u32 iv32, u16 *p1k) | ||
190 | { | ||
191 | const u8 *tk = &keyconf->key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; | ||
192 | struct tkip_ctx ctx; | ||
193 | |||
194 | tkip_mixing_phase1(tk, &ctx, ta, iv32); | ||
195 | memcpy(p1k, ctx.p1k, sizeof(ctx.p1k)); | ||
196 | } | ||
197 | EXPORT_SYMBOL(ieee80211_get_tkip_rx_p1k); | ||
198 | |||
188 | void ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf, | 199 | void ieee80211_get_tkip_p2k(struct ieee80211_key_conf *keyconf, |
189 | struct sk_buff *skb, u8 *p2k) | 200 | struct sk_buff *skb, u8 *p2k) |
190 | { | 201 | { |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 5bfb80cba63..ddeb1b99838 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -799,6 +799,7 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata) | |||
799 | 799 | ||
800 | qparam.uapsd = false; | 800 | qparam.uapsd = false; |
801 | 801 | ||
802 | local->tx_conf[queue] = qparam; | ||
802 | drv_conf_tx(local, queue, &qparam); | 803 | drv_conf_tx(local, queue, &qparam); |
803 | } | 804 | } |
804 | 805 | ||
@@ -1016,7 +1017,7 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | |||
1016 | } | 1017 | } |
1017 | 1018 | ||
1018 | struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, | 1019 | struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, |
1019 | u8 *dst, | 1020 | u8 *dst, u32 ratemask, |
1020 | const u8 *ssid, size_t ssid_len, | 1021 | const u8 *ssid, size_t ssid_len, |
1021 | const u8 *ie, size_t ie_len, | 1022 | const u8 *ie, size_t ie_len, |
1022 | bool directed) | 1023 | bool directed) |
@@ -1049,9 +1050,7 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, | |||
1049 | 1050 | ||
1050 | buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len, | 1051 | buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len, |
1051 | local->hw.conf.channel->band, | 1052 | local->hw.conf.channel->band, |
1052 | sdata->rc_rateidx_mask | 1053 | ratemask, chan); |
1053 | [local->hw.conf.channel->band], | ||
1054 | chan); | ||
1055 | 1054 | ||
1056 | skb = ieee80211_probereq_get(&local->hw, &sdata->vif, | 1055 | skb = ieee80211_probereq_get(&local->hw, &sdata->vif, |
1057 | ssid, ssid_len, | 1056 | ssid, ssid_len, |
@@ -1072,12 +1071,12 @@ struct sk_buff *ieee80211_build_probe_req(struct ieee80211_sub_if_data *sdata, | |||
1072 | void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | 1071 | void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, |
1073 | const u8 *ssid, size_t ssid_len, | 1072 | const u8 *ssid, size_t ssid_len, |
1074 | const u8 *ie, size_t ie_len, | 1073 | const u8 *ie, size_t ie_len, |
1075 | bool directed) | 1074 | u32 ratemask, bool directed) |
1076 | { | 1075 | { |
1077 | struct sk_buff *skb; | 1076 | struct sk_buff *skb; |
1078 | 1077 | ||
1079 | skb = ieee80211_build_probe_req(sdata, dst, ssid, ssid_len, ie, ie_len, | 1078 | skb = ieee80211_build_probe_req(sdata, dst, ratemask, ssid, ssid_len, |
1080 | directed); | 1079 | ie, ie_len, directed); |
1081 | if (skb) | 1080 | if (skb) |
1082 | ieee80211_tx_skb(sdata, skb); | 1081 | ieee80211_tx_skb(sdata, skb); |
1083 | } | 1082 | } |
@@ -1134,7 +1133,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1134 | struct ieee80211_hw *hw = &local->hw; | 1133 | struct ieee80211_hw *hw = &local->hw; |
1135 | struct ieee80211_sub_if_data *sdata; | 1134 | struct ieee80211_sub_if_data *sdata; |
1136 | struct sta_info *sta; | 1135 | struct sta_info *sta; |
1137 | int res; | 1136 | int res, i; |
1138 | 1137 | ||
1139 | #ifdef CONFIG_PM | 1138 | #ifdef CONFIG_PM |
1140 | if (local->suspended) | 1139 | if (local->suspended) |
@@ -1157,27 +1156,37 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1157 | } | 1156 | } |
1158 | #endif | 1157 | #endif |
1159 | 1158 | ||
1160 | /* restart hardware */ | 1159 | /* setup fragmentation threshold */ |
1161 | if (local->open_count) { | 1160 | drv_set_frag_threshold(local, hw->wiphy->frag_threshold); |
1162 | /* | 1161 | |
1163 | * Upon resume hardware can sometimes be goofy due to | 1162 | /* setup RTS threshold */ |
1164 | * various platform / driver / bus issues, so restarting | 1163 | drv_set_rts_threshold(local, hw->wiphy->rts_threshold); |
1165 | * the device may at times not work immediately. Propagate | 1164 | |
1166 | * the error. | 1165 | /* reset coverage class */ |
1167 | */ | 1166 | drv_set_coverage_class(local, hw->wiphy->coverage_class); |
1168 | res = drv_start(local); | 1167 | |
1169 | if (res) { | 1168 | /* everything else happens only if HW was up & running */ |
1170 | WARN(local->suspended, "Hardware became unavailable " | 1169 | if (!local->open_count) |
1171 | "upon resume. This could be a software issue " | 1170 | goto wake_up; |
1172 | "prior to suspend or a hardware issue.\n"); | ||
1173 | return res; | ||
1174 | } | ||
1175 | 1171 | ||
1176 | ieee80211_led_radio(local, true); | 1172 | /* |
1177 | ieee80211_mod_tpt_led_trig(local, | 1173 | * Upon resume hardware can sometimes be goofy due to |
1178 | IEEE80211_TPT_LEDTRIG_FL_RADIO, 0); | 1174 | * various platform / driver / bus issues, so restarting |
1175 | * the device may at times not work immediately. Propagate | ||
1176 | * the error. | ||
1177 | */ | ||
1178 | res = drv_start(local); | ||
1179 | if (res) { | ||
1180 | WARN(local->suspended, "Hardware became unavailable " | ||
1181 | "upon resume. This could be a software issue " | ||
1182 | "prior to suspend or a hardware issue.\n"); | ||
1183 | return res; | ||
1179 | } | 1184 | } |
1180 | 1185 | ||
1186 | ieee80211_led_radio(local, true); | ||
1187 | ieee80211_mod_tpt_led_trig(local, | ||
1188 | IEEE80211_TPT_LEDTRIG_FL_RADIO, 0); | ||
1189 | |||
1181 | /* add interfaces */ | 1190 | /* add interfaces */ |
1182 | list_for_each_entry(sdata, &local->interfaces, list) { | 1191 | list_for_each_entry(sdata, &local->interfaces, list) { |
1183 | if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && | 1192 | if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && |
@@ -1201,11 +1210,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1201 | } | 1210 | } |
1202 | mutex_unlock(&local->sta_mtx); | 1211 | mutex_unlock(&local->sta_mtx); |
1203 | 1212 | ||
1204 | /* setup fragmentation threshold */ | 1213 | /* reconfigure tx conf */ |
1205 | drv_set_frag_threshold(local, hw->wiphy->frag_threshold); | 1214 | for (i = 0; i < hw->queues; i++) |
1206 | 1215 | drv_conf_tx(local, i, &local->tx_conf[i]); | |
1207 | /* setup RTS threshold */ | ||
1208 | drv_set_rts_threshold(local, hw->wiphy->rts_threshold); | ||
1209 | 1216 | ||
1210 | /* reconfigure hardware */ | 1217 | /* reconfigure hardware */ |
1211 | ieee80211_hw_config(local, ~0); | 1218 | ieee80211_hw_config(local, ~0); |
@@ -1287,9 +1294,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1287 | if (ieee80211_sdata_running(sdata)) | 1294 | if (ieee80211_sdata_running(sdata)) |
1288 | ieee80211_enable_keys(sdata); | 1295 | ieee80211_enable_keys(sdata); |
1289 | 1296 | ||
1290 | #ifdef CONFIG_PM | ||
1291 | wake_up: | 1297 | wake_up: |
1292 | #endif | ||
1293 | ieee80211_wake_queues_by_reason(hw, | 1298 | ieee80211_wake_queues_by_reason(hw, |
1294 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); | 1299 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); |
1295 | 1300 | ||
diff --git a/net/mac80211/work.c b/net/mac80211/work.c index edf8583280c..380b9a7462b 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #include "ieee80211_i.h" | 26 | #include "ieee80211_i.h" |
27 | #include "rate.h" | 27 | #include "rate.h" |
28 | #include "driver-ops.h" | ||
28 | 29 | ||
29 | #define IEEE80211_AUTH_TIMEOUT (HZ / 5) | 30 | #define IEEE80211_AUTH_TIMEOUT (HZ / 5) |
30 | #define IEEE80211_AUTH_MAX_TRIES 3 | 31 | #define IEEE80211_AUTH_MAX_TRIES 3 |
@@ -427,6 +428,14 @@ ieee80211_direct_probe(struct ieee80211_work *wk) | |||
427 | struct ieee80211_sub_if_data *sdata = wk->sdata; | 428 | struct ieee80211_sub_if_data *sdata = wk->sdata; |
428 | struct ieee80211_local *local = sdata->local; | 429 | struct ieee80211_local *local = sdata->local; |
429 | 430 | ||
431 | if (!wk->probe_auth.synced) { | ||
432 | int ret = drv_tx_sync(local, sdata, wk->filter_ta, | ||
433 | IEEE80211_TX_SYNC_AUTH); | ||
434 | if (ret) | ||
435 | return WORK_ACT_TIMEOUT; | ||
436 | } | ||
437 | wk->probe_auth.synced = true; | ||
438 | |||
430 | wk->probe_auth.tries++; | 439 | wk->probe_auth.tries++; |
431 | if (wk->probe_auth.tries > IEEE80211_AUTH_MAX_TRIES) { | 440 | if (wk->probe_auth.tries > IEEE80211_AUTH_MAX_TRIES) { |
432 | printk(KERN_DEBUG "%s: direct probe to %pM timed out\n", | 441 | printk(KERN_DEBUG "%s: direct probe to %pM timed out\n", |
@@ -450,7 +459,8 @@ ieee80211_direct_probe(struct ieee80211_work *wk) | |||
450 | * will not answer to direct packet in unassociated state. | 459 | * will not answer to direct packet in unassociated state. |
451 | */ | 460 | */ |
452 | ieee80211_send_probe_req(sdata, NULL, wk->probe_auth.ssid, | 461 | ieee80211_send_probe_req(sdata, NULL, wk->probe_auth.ssid, |
453 | wk->probe_auth.ssid_len, NULL, 0, true); | 462 | wk->probe_auth.ssid_len, NULL, 0, |
463 | (u32) -1, true); | ||
454 | 464 | ||
455 | wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; | 465 | wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; |
456 | run_again(local, wk->timeout); | 466 | run_again(local, wk->timeout); |
@@ -465,6 +475,14 @@ ieee80211_authenticate(struct ieee80211_work *wk) | |||
465 | struct ieee80211_sub_if_data *sdata = wk->sdata; | 475 | struct ieee80211_sub_if_data *sdata = wk->sdata; |
466 | struct ieee80211_local *local = sdata->local; | 476 | struct ieee80211_local *local = sdata->local; |
467 | 477 | ||
478 | if (!wk->probe_auth.synced) { | ||
479 | int ret = drv_tx_sync(local, sdata, wk->filter_ta, | ||
480 | IEEE80211_TX_SYNC_AUTH); | ||
481 | if (ret) | ||
482 | return WORK_ACT_TIMEOUT; | ||
483 | } | ||
484 | wk->probe_auth.synced = true; | ||
485 | |||
468 | wk->probe_auth.tries++; | 486 | wk->probe_auth.tries++; |
469 | if (wk->probe_auth.tries > IEEE80211_AUTH_MAX_TRIES) { | 487 | if (wk->probe_auth.tries > IEEE80211_AUTH_MAX_TRIES) { |
470 | printk(KERN_DEBUG "%s: authentication with %pM" | 488 | printk(KERN_DEBUG "%s: authentication with %pM" |
@@ -498,6 +516,14 @@ ieee80211_associate(struct ieee80211_work *wk) | |||
498 | struct ieee80211_sub_if_data *sdata = wk->sdata; | 516 | struct ieee80211_sub_if_data *sdata = wk->sdata; |
499 | struct ieee80211_local *local = sdata->local; | 517 | struct ieee80211_local *local = sdata->local; |
500 | 518 | ||
519 | if (!wk->assoc.synced) { | ||
520 | int ret = drv_tx_sync(local, sdata, wk->filter_ta, | ||
521 | IEEE80211_TX_SYNC_ASSOC); | ||
522 | if (ret) | ||
523 | return WORK_ACT_TIMEOUT; | ||
524 | } | ||
525 | wk->assoc.synced = true; | ||
526 | |||
501 | wk->assoc.tries++; | 527 | wk->assoc.tries++; |
502 | if (wk->assoc.tries > IEEE80211_ASSOC_MAX_TRIES) { | 528 | if (wk->assoc.tries > IEEE80211_ASSOC_MAX_TRIES) { |
503 | printk(KERN_DEBUG "%s: association with %pM" | 529 | printk(KERN_DEBUG "%s: association with %pM" |
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index be43fd805bd..2b771dc708a 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c | |||
@@ -3771,6 +3771,7 @@ err_sock: | |||
3771 | void ip_vs_control_cleanup(void) | 3771 | void ip_vs_control_cleanup(void) |
3772 | { | 3772 | { |
3773 | EnterFunction(2); | 3773 | EnterFunction(2); |
3774 | unregister_netdevice_notifier(&ip_vs_dst_notifier); | ||
3774 | ip_vs_genl_unregister(); | 3775 | ip_vs_genl_unregister(); |
3775 | nf_unregister_sockopt(&ip_vs_sockopts); | 3776 | nf_unregister_sockopt(&ip_vs_sockopts); |
3776 | LeaveFunction(2); | 3777 | LeaveFunction(2); |
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c index 5b466cd1272..84d0fd47636 100644 --- a/net/netfilter/nf_queue.c +++ b/net/netfilter/nf_queue.c | |||
@@ -312,6 +312,7 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict) | |||
312 | } | 312 | } |
313 | break; | 313 | break; |
314 | case NF_STOLEN: | 314 | case NF_STOLEN: |
315 | break; | ||
315 | default: | 316 | default: |
316 | kfree_skb(skb); | 317 | kfree_skb(skb); |
317 | } | 318 | } |
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index 2e7ccbb43dd..2d8158acf6f 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c | |||
@@ -33,7 +33,7 @@ | |||
33 | #include <net/netfilter/nf_log.h> | 33 | #include <net/netfilter/nf_log.h> |
34 | #include <net/netfilter/nfnetlink_log.h> | 34 | #include <net/netfilter/nfnetlink_log.h> |
35 | 35 | ||
36 | #include <asm/atomic.h> | 36 | #include <linux/atomic.h> |
37 | 37 | ||
38 | #ifdef CONFIG_BRIDGE_NETFILTER | 38 | #ifdef CONFIG_BRIDGE_NETFILTER |
39 | #include "../bridge/br_private.h" | 39 | #include "../bridge/br_private.h" |
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index 49132bddd73..00bd475eab4 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <net/sock.h> | 31 | #include <net/sock.h> |
32 | #include <net/netfilter/nf_queue.h> | 32 | #include <net/netfilter/nf_queue.h> |
33 | 33 | ||
34 | #include <asm/atomic.h> | 34 | #include <linux/atomic.h> |
35 | 35 | ||
36 | #ifdef CONFIG_BRIDGE_NETFILTER | 36 | #ifdef CONFIG_BRIDGE_NETFILTER |
37 | #include "../bridge/br_private.h" | 37 | #include "../bridge/br_private.h" |
diff --git a/net/netlabel/Makefile b/net/netlabel/Makefile index ea750e9df65..d2732fc952e 100644 --- a/net/netlabel/Makefile +++ b/net/netlabel/Makefile | |||
@@ -1,8 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Makefile for the NetLabel subsystem. | 2 | # Makefile for the NetLabel subsystem. |
3 | # | 3 | # |
4 | # Feb 9, 2006, Paul Moore <paul.moore@hp.com> | ||
5 | # | ||
6 | 4 | ||
7 | # base objects | 5 | # base objects |
8 | obj-y := netlabel_user.o netlabel_kapi.o | 6 | obj-y := netlabel_user.o netlabel_kapi.o |
diff --git a/net/netlabel/netlabel_addrlist.c b/net/netlabel/netlabel_addrlist.c index c0519139679..96b749dacc3 100644 --- a/net/netlabel/netlabel_addrlist.c +++ b/net/netlabel/netlabel_addrlist.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * system manages static and dynamic label mappings for network protocols such | 6 | * system manages static and dynamic label mappings for network protocols such |
7 | * as CIPSO and RIPSO. | 7 | * as CIPSO and RIPSO. |
8 | * | 8 | * |
9 | * Author: Paul Moore <paul.moore@hp.com> | 9 | * Author: Paul Moore <paul@paul-moore.com> |
10 | * | 10 | * |
11 | */ | 11 | */ |
12 | 12 | ||
diff --git a/net/netlabel/netlabel_addrlist.h b/net/netlabel/netlabel_addrlist.h index 2b9644e19de..fdbc1d2c735 100644 --- a/net/netlabel/netlabel_addrlist.h +++ b/net/netlabel/netlabel_addrlist.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * system manages static and dynamic label mappings for network protocols such | 6 | * system manages static and dynamic label mappings for network protocols such |
7 | * as CIPSO and RIPSO. | 7 | * as CIPSO and RIPSO. |
8 | * | 8 | * |
9 | * Author: Paul Moore <paul.moore@hp.com> | 9 | * Author: Paul Moore <paul@paul-moore.com> |
10 | * | 10 | * |
11 | */ | 11 | */ |
12 | 12 | ||
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c index bae5756b162..6bf878335d9 100644 --- a/net/netlabel/netlabel_cipso_v4.c +++ b/net/netlabel/netlabel_cipso_v4.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * NetLabel system manages static and dynamic label mappings for network | 5 | * NetLabel system manages static and dynamic label mappings for network |
6 | * protocols such as CIPSO and RIPSO. | 6 | * protocols such as CIPSO and RIPSO. |
7 | * | 7 | * |
8 | * Author: Paul Moore <paul.moore@hp.com> | 8 | * Author: Paul Moore <paul@paul-moore.com> |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | 11 | ||
@@ -39,7 +39,7 @@ | |||
39 | #include <net/genetlink.h> | 39 | #include <net/genetlink.h> |
40 | #include <net/netlabel.h> | 40 | #include <net/netlabel.h> |
41 | #include <net/cipso_ipv4.h> | 41 | #include <net/cipso_ipv4.h> |
42 | #include <asm/atomic.h> | 42 | #include <linux/atomic.h> |
43 | 43 | ||
44 | #include "netlabel_user.h" | 44 | #include "netlabel_user.h" |
45 | #include "netlabel_cipso_v4.h" | 45 | #include "netlabel_cipso_v4.h" |
diff --git a/net/netlabel/netlabel_cipso_v4.h b/net/netlabel/netlabel_cipso_v4.h index af7f3355103..d24d774bfd6 100644 --- a/net/netlabel/netlabel_cipso_v4.h +++ b/net/netlabel/netlabel_cipso_v4.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * NetLabel system manages static and dynamic label mappings for network | 5 | * NetLabel system manages static and dynamic label mappings for network |
6 | * protocols such as CIPSO and RIPSO. | 6 | * protocols such as CIPSO and RIPSO. |
7 | * | 7 | * |
8 | * Author: Paul Moore <paul.moore@hp.com> | 8 | * Author: Paul Moore <paul@paul-moore.com> |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | 11 | ||
diff --git a/net/netlabel/netlabel_domainhash.c b/net/netlabel/netlabel_domainhash.c index de0d8e4cbfb..7d8083cde34 100644 --- a/net/netlabel/netlabel_domainhash.c +++ b/net/netlabel/netlabel_domainhash.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * system manages static and dynamic label mappings for network protocols such | 6 | * system manages static and dynamic label mappings for network protocols such |
7 | * as CIPSO and RIPSO. | 7 | * as CIPSO and RIPSO. |
8 | * | 8 | * |
9 | * Author: Paul Moore <paul.moore@hp.com> | 9 | * Author: Paul Moore <paul@paul-moore.com> |
10 | * | 10 | * |
11 | */ | 11 | */ |
12 | 12 | ||
@@ -55,8 +55,7 @@ struct netlbl_domhsh_tbl { | |||
55 | * should be okay */ | 55 | * should be okay */ |
56 | static DEFINE_SPINLOCK(netlbl_domhsh_lock); | 56 | static DEFINE_SPINLOCK(netlbl_domhsh_lock); |
57 | #define netlbl_domhsh_rcu_deref(p) \ | 57 | #define netlbl_domhsh_rcu_deref(p) \ |
58 | rcu_dereference_check(p, rcu_read_lock_held() || \ | 58 | rcu_dereference_check(p, lockdep_is_held(&netlbl_domhsh_lock)) |
59 | lockdep_is_held(&netlbl_domhsh_lock)) | ||
60 | static struct netlbl_domhsh_tbl *netlbl_domhsh = NULL; | 59 | static struct netlbl_domhsh_tbl *netlbl_domhsh = NULL; |
61 | static struct netlbl_dom_map *netlbl_domhsh_def = NULL; | 60 | static struct netlbl_dom_map *netlbl_domhsh_def = NULL; |
62 | 61 | ||
diff --git a/net/netlabel/netlabel_domainhash.h b/net/netlabel/netlabel_domainhash.h index 0261dda3f2d..bfcc0f7024c 100644 --- a/net/netlabel/netlabel_domainhash.h +++ b/net/netlabel/netlabel_domainhash.h | |||
@@ -6,7 +6,7 @@ | |||
6 | * system manages static and dynamic label mappings for network protocols such | 6 | * system manages static and dynamic label mappings for network protocols such |
7 | * as CIPSO and RIPSO. | 7 | * as CIPSO and RIPSO. |
8 | * | 8 | * |
9 | * Author: Paul Moore <paul.moore@hp.com> | 9 | * Author: Paul Moore <paul@paul-moore.com> |
10 | * | 10 | * |
11 | */ | 11 | */ |
12 | 12 | ||
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c index 1b83e0009d8..9c24de10a65 100644 --- a/net/netlabel/netlabel_kapi.c +++ b/net/netlabel/netlabel_kapi.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * system manages static and dynamic label mappings for network protocols such | 5 | * system manages static and dynamic label mappings for network protocols such |
6 | * as CIPSO and RIPSO. | 6 | * as CIPSO and RIPSO. |
7 | * | 7 | * |
8 | * Author: Paul Moore <paul.moore@hp.com> | 8 | * Author: Paul Moore <paul@paul-moore.com> |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | 11 | ||
@@ -39,7 +39,7 @@ | |||
39 | #include <net/netlabel.h> | 39 | #include <net/netlabel.h> |
40 | #include <net/cipso_ipv4.h> | 40 | #include <net/cipso_ipv4.h> |
41 | #include <asm/bug.h> | 41 | #include <asm/bug.h> |
42 | #include <asm/atomic.h> | 42 | #include <linux/atomic.h> |
43 | 43 | ||
44 | #include "netlabel_domainhash.h" | 44 | #include "netlabel_domainhash.h" |
45 | #include "netlabel_unlabeled.h" | 45 | #include "netlabel_unlabeled.h" |
@@ -341,11 +341,11 @@ int netlbl_cfg_cipsov4_map_add(u32 doi, | |||
341 | 341 | ||
342 | entry = kzalloc(sizeof(*entry), GFP_ATOMIC); | 342 | entry = kzalloc(sizeof(*entry), GFP_ATOMIC); |
343 | if (entry == NULL) | 343 | if (entry == NULL) |
344 | return -ENOMEM; | 344 | goto out_entry; |
345 | if (domain != NULL) { | 345 | if (domain != NULL) { |
346 | entry->domain = kstrdup(domain, GFP_ATOMIC); | 346 | entry->domain = kstrdup(domain, GFP_ATOMIC); |
347 | if (entry->domain == NULL) | 347 | if (entry->domain == NULL) |
348 | goto cfg_cipsov4_map_add_failure; | 348 | goto out_domain; |
349 | } | 349 | } |
350 | 350 | ||
351 | if (addr == NULL && mask == NULL) { | 351 | if (addr == NULL && mask == NULL) { |
@@ -354,13 +354,13 @@ int netlbl_cfg_cipsov4_map_add(u32 doi, | |||
354 | } else if (addr != NULL && mask != NULL) { | 354 | } else if (addr != NULL && mask != NULL) { |
355 | addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC); | 355 | addrmap = kzalloc(sizeof(*addrmap), GFP_ATOMIC); |
356 | if (addrmap == NULL) | 356 | if (addrmap == NULL) |
357 | goto cfg_cipsov4_map_add_failure; | 357 | goto out_addrmap; |
358 | INIT_LIST_HEAD(&addrmap->list4); | 358 | INIT_LIST_HEAD(&addrmap->list4); |
359 | INIT_LIST_HEAD(&addrmap->list6); | 359 | INIT_LIST_HEAD(&addrmap->list6); |
360 | 360 | ||
361 | addrinfo = kzalloc(sizeof(*addrinfo), GFP_ATOMIC); | 361 | addrinfo = kzalloc(sizeof(*addrinfo), GFP_ATOMIC); |
362 | if (addrinfo == NULL) | 362 | if (addrinfo == NULL) |
363 | goto cfg_cipsov4_map_add_failure; | 363 | goto out_addrinfo; |
364 | addrinfo->type_def.cipsov4 = doi_def; | 364 | addrinfo->type_def.cipsov4 = doi_def; |
365 | addrinfo->type = NETLBL_NLTYPE_CIPSOV4; | 365 | addrinfo->type = NETLBL_NLTYPE_CIPSOV4; |
366 | addrinfo->list.addr = addr->s_addr & mask->s_addr; | 366 | addrinfo->list.addr = addr->s_addr & mask->s_addr; |
@@ -374,7 +374,7 @@ int netlbl_cfg_cipsov4_map_add(u32 doi, | |||
374 | entry->type = NETLBL_NLTYPE_ADDRSELECT; | 374 | entry->type = NETLBL_NLTYPE_ADDRSELECT; |
375 | } else { | 375 | } else { |
376 | ret_val = -EINVAL; | 376 | ret_val = -EINVAL; |
377 | goto cfg_cipsov4_map_add_failure; | 377 | goto out_addrmap; |
378 | } | 378 | } |
379 | 379 | ||
380 | ret_val = netlbl_domhsh_add(entry, audit_info); | 380 | ret_val = netlbl_domhsh_add(entry, audit_info); |
@@ -384,11 +384,15 @@ int netlbl_cfg_cipsov4_map_add(u32 doi, | |||
384 | return 0; | 384 | return 0; |
385 | 385 | ||
386 | cfg_cipsov4_map_add_failure: | 386 | cfg_cipsov4_map_add_failure: |
387 | cipso_v4_doi_putdef(doi_def); | 387 | kfree(addrinfo); |
388 | out_addrinfo: | ||
389 | kfree(addrmap); | ||
390 | out_addrmap: | ||
388 | kfree(entry->domain); | 391 | kfree(entry->domain); |
392 | out_domain: | ||
389 | kfree(entry); | 393 | kfree(entry); |
390 | kfree(addrmap); | 394 | out_entry: |
391 | kfree(addrinfo); | 395 | cipso_v4_doi_putdef(doi_def); |
392 | return ret_val; | 396 | return ret_val; |
393 | } | 397 | } |
394 | 398 | ||
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c index 4f251b19fbc..bfa55586977 100644 --- a/net/netlabel/netlabel_mgmt.c +++ b/net/netlabel/netlabel_mgmt.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * NetLabel system manages static and dynamic label mappings for network | 5 | * NetLabel system manages static and dynamic label mappings for network |
6 | * protocols such as CIPSO and RIPSO. | 6 | * protocols such as CIPSO and RIPSO. |
7 | * | 7 | * |
8 | * Author: Paul Moore <paul.moore@hp.com> | 8 | * Author: Paul Moore <paul@paul-moore.com> |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | 11 | ||
@@ -42,7 +42,7 @@ | |||
42 | #include <net/ipv6.h> | 42 | #include <net/ipv6.h> |
43 | #include <net/netlabel.h> | 43 | #include <net/netlabel.h> |
44 | #include <net/cipso_ipv4.h> | 44 | #include <net/cipso_ipv4.h> |
45 | #include <asm/atomic.h> | 45 | #include <linux/atomic.h> |
46 | 46 | ||
47 | #include "netlabel_domainhash.h" | 47 | #include "netlabel_domainhash.h" |
48 | #include "netlabel_user.h" | 48 | #include "netlabel_user.h" |
diff --git a/net/netlabel/netlabel_mgmt.h b/net/netlabel/netlabel_mgmt.h index 0a25838bcf4..5a9f31ce579 100644 --- a/net/netlabel/netlabel_mgmt.h +++ b/net/netlabel/netlabel_mgmt.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * NetLabel system manages static and dynamic label mappings for network | 5 | * NetLabel system manages static and dynamic label mappings for network |
6 | * protocols such as CIPSO and RIPSO. | 6 | * protocols such as CIPSO and RIPSO. |
7 | * | 7 | * |
8 | * Author: Paul Moore <paul.moore@hp.com> | 8 | * Author: Paul Moore <paul@paul-moore.com> |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | 11 | ||
@@ -32,7 +32,7 @@ | |||
32 | #define _NETLABEL_MGMT_H | 32 | #define _NETLABEL_MGMT_H |
33 | 33 | ||
34 | #include <net/netlabel.h> | 34 | #include <net/netlabel.h> |
35 | #include <asm/atomic.h> | 35 | #include <linux/atomic.h> |
36 | 36 | ||
37 | /* | 37 | /* |
38 | * The following NetLabel payloads are supported by the management interface. | 38 | * The following NetLabel payloads are supported by the management interface. |
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c index 8efd061a0ae..e6e823656f9 100644 --- a/net/netlabel/netlabel_unlabeled.c +++ b/net/netlabel/netlabel_unlabeled.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * NetLabel system. The NetLabel system manages static and dynamic label | 5 | * NetLabel system. The NetLabel system manages static and dynamic label |
6 | * mappings for network protocols such as CIPSO and RIPSO. | 6 | * mappings for network protocols such as CIPSO and RIPSO. |
7 | * | 7 | * |
8 | * Author: Paul Moore <paul.moore@hp.com> | 8 | * Author: Paul Moore <paul@paul-moore.com> |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | 11 | ||
@@ -52,7 +52,7 @@ | |||
52 | #include <net/net_namespace.h> | 52 | #include <net/net_namespace.h> |
53 | #include <net/netlabel.h> | 53 | #include <net/netlabel.h> |
54 | #include <asm/bug.h> | 54 | #include <asm/bug.h> |
55 | #include <asm/atomic.h> | 55 | #include <linux/atomic.h> |
56 | 56 | ||
57 | #include "netlabel_user.h" | 57 | #include "netlabel_user.h" |
58 | #include "netlabel_addrlist.h" | 58 | #include "netlabel_addrlist.h" |
@@ -116,8 +116,7 @@ struct netlbl_unlhsh_walk_arg { | |||
116 | * hash table should be okay */ | 116 | * hash table should be okay */ |
117 | static DEFINE_SPINLOCK(netlbl_unlhsh_lock); | 117 | static DEFINE_SPINLOCK(netlbl_unlhsh_lock); |
118 | #define netlbl_unlhsh_rcu_deref(p) \ | 118 | #define netlbl_unlhsh_rcu_deref(p) \ |
119 | rcu_dereference_check(p, rcu_read_lock_held() || \ | 119 | rcu_dereference_check(p, lockdep_is_held(&netlbl_unlhsh_lock)) |
120 | lockdep_is_held(&netlbl_unlhsh_lock)) | ||
121 | static struct netlbl_unlhsh_tbl *netlbl_unlhsh = NULL; | 120 | static struct netlbl_unlhsh_tbl *netlbl_unlhsh = NULL; |
122 | static struct netlbl_unlhsh_iface *netlbl_unlhsh_def = NULL; | 121 | static struct netlbl_unlhsh_iface *netlbl_unlhsh_def = NULL; |
123 | 122 | ||
diff --git a/net/netlabel/netlabel_unlabeled.h b/net/netlabel/netlabel_unlabeled.h index 0bc8dc3f9e3..700af49022a 100644 --- a/net/netlabel/netlabel_unlabeled.h +++ b/net/netlabel/netlabel_unlabeled.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * NetLabel system. The NetLabel system manages static and dynamic label | 5 | * NetLabel system. The NetLabel system manages static and dynamic label |
6 | * mappings for network protocols such as CIPSO and RIPSO. | 6 | * mappings for network protocols such as CIPSO and RIPSO. |
7 | * | 7 | * |
8 | * Author: Paul Moore <paul.moore@hp.com> | 8 | * Author: Paul Moore <paul@paul-moore.com> |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | 11 | ||
diff --git a/net/netlabel/netlabel_user.c b/net/netlabel/netlabel_user.c index a3fd75ac3fa..9fae63f1029 100644 --- a/net/netlabel/netlabel_user.c +++ b/net/netlabel/netlabel_user.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * NetLabel system manages static and dynamic label mappings for network | 5 | * NetLabel system manages static and dynamic label mappings for network |
6 | * protocols such as CIPSO and RIPSO. | 6 | * protocols such as CIPSO and RIPSO. |
7 | * | 7 | * |
8 | * Author: Paul Moore <paul.moore@hp.com> | 8 | * Author: Paul Moore <paul@paul-moore.com> |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | 11 | ||
diff --git a/net/netlabel/netlabel_user.h b/net/netlabel/netlabel_user.h index f4fc4c9ad56..81969785e27 100644 --- a/net/netlabel/netlabel_user.h +++ b/net/netlabel/netlabel_user.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * NetLabel system manages static and dynamic label mappings for network | 5 | * NetLabel system manages static and dynamic label mappings for network |
6 | * protocols such as CIPSO and RIPSO. | 6 | * protocols such as CIPSO and RIPSO. |
7 | * | 7 | * |
8 | * Author: Paul Moore <paul.moore@hp.com> | 8 | * Author: Paul Moore <paul@paul-moore.com> |
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | 11 | ||
diff --git a/net/rds/page.c b/net/rds/page.c index d8acdebe3c7..b82d63e77b0 100644 --- a/net/rds/page.c +++ b/net/rds/page.c | |||
@@ -32,6 +32,7 @@ | |||
32 | */ | 32 | */ |
33 | #include <linux/highmem.h> | 33 | #include <linux/highmem.h> |
34 | #include <linux/gfp.h> | 34 | #include <linux/gfp.h> |
35 | #include <linux/cpu.h> | ||
35 | 36 | ||
36 | #include "rds.h" | 37 | #include "rds.h" |
37 | 38 | ||
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 102fc212cd6..e051398fdf6 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c | |||
@@ -196,8 +196,7 @@ static int tcf_mirred(struct sk_buff *skb, const struct tc_action *a, | |||
196 | 196 | ||
197 | skb2->skb_iif = skb->dev->ifindex; | 197 | skb2->skb_iif = skb->dev->ifindex; |
198 | skb2->dev = dev; | 198 | skb2->dev = dev; |
199 | dev_queue_xmit(skb2); | 199 | err = dev_queue_xmit(skb2); |
200 | err = 0; | ||
201 | 200 | ||
202 | out: | 201 | out: |
203 | if (err) { | 202 | if (err) { |
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c index 2a318f2dc3e..b5d56a22b1d 100644 --- a/net/sched/sch_prio.c +++ b/net/sched/sch_prio.c | |||
@@ -112,7 +112,7 @@ static struct sk_buff *prio_dequeue(struct Qdisc *sch) | |||
112 | 112 | ||
113 | for (prio = 0; prio < q->bands; prio++) { | 113 | for (prio = 0; prio < q->bands; prio++) { |
114 | struct Qdisc *qdisc = q->queues[prio]; | 114 | struct Qdisc *qdisc = q->queues[prio]; |
115 | struct sk_buff *skb = qdisc->dequeue(qdisc); | 115 | struct sk_buff *skb = qdisc_dequeue_peeked(qdisc); |
116 | if (skb) { | 116 | if (skb) { |
117 | qdisc_bstats_update(sch, skb); | 117 | qdisc_bstats_update(sch, skb); |
118 | sch->q.qlen--; | 118 | sch->q.qlen--; |
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 4536ee64383..4f5510e2bd6 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c | |||
@@ -410,7 +410,12 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
410 | /* Return Congestion Notification only if we dropped a packet | 410 | /* Return Congestion Notification only if we dropped a packet |
411 | * from this flow. | 411 | * from this flow. |
412 | */ | 412 | */ |
413 | return (qlen != slot->qlen) ? NET_XMIT_CN : NET_XMIT_SUCCESS; | 413 | if (qlen != slot->qlen) |
414 | return NET_XMIT_CN; | ||
415 | |||
416 | /* As we dropped a packet, better let upper stack know this */ | ||
417 | qdisc_tree_decrease_qlen(sch, 1); | ||
418 | return NET_XMIT_SUCCESS; | ||
414 | } | 419 | } |
415 | 420 | ||
416 | static struct sk_buff * | 421 | static struct sk_buff * |
diff --git a/net/socket.c b/net/socket.c index 02dc82db3d2..24a77400b65 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -467,7 +467,7 @@ static struct socket *sock_alloc(void) | |||
467 | struct inode *inode; | 467 | struct inode *inode; |
468 | struct socket *sock; | 468 | struct socket *sock; |
469 | 469 | ||
470 | inode = new_inode(sock_mnt->mnt_sb); | 470 | inode = new_inode_pseudo(sock_mnt->mnt_sb); |
471 | if (!inode) | 471 | if (!inode) |
472 | return NULL; | 472 | return NULL; |
473 | 473 | ||
@@ -580,7 +580,7 @@ int sock_sendmsg(struct socket *sock, struct msghdr *msg, size_t size) | |||
580 | } | 580 | } |
581 | EXPORT_SYMBOL(sock_sendmsg); | 581 | EXPORT_SYMBOL(sock_sendmsg); |
582 | 582 | ||
583 | int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg, size_t size) | 583 | static int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg, size_t size) |
584 | { | 584 | { |
585 | struct kiocb iocb; | 585 | struct kiocb iocb; |
586 | struct sock_iocb siocb; | 586 | struct sock_iocb siocb; |
@@ -1871,8 +1871,14 @@ SYSCALL_DEFINE2(shutdown, int, fd, int, how) | |||
1871 | #define COMPAT_NAMELEN(msg) COMPAT_MSG(msg, msg_namelen) | 1871 | #define COMPAT_NAMELEN(msg) COMPAT_MSG(msg, msg_namelen) |
1872 | #define COMPAT_FLAGS(msg) COMPAT_MSG(msg, msg_flags) | 1872 | #define COMPAT_FLAGS(msg) COMPAT_MSG(msg, msg_flags) |
1873 | 1873 | ||
1874 | struct used_address { | ||
1875 | struct sockaddr_storage name; | ||
1876 | unsigned int name_len; | ||
1877 | }; | ||
1878 | |||
1874 | static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, | 1879 | static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, |
1875 | struct msghdr *msg_sys, unsigned flags, int nosec) | 1880 | struct msghdr *msg_sys, unsigned flags, |
1881 | struct used_address *used_address) | ||
1876 | { | 1882 | { |
1877 | struct compat_msghdr __user *msg_compat = | 1883 | struct compat_msghdr __user *msg_compat = |
1878 | (struct compat_msghdr __user *)msg; | 1884 | (struct compat_msghdr __user *)msg; |
@@ -1953,8 +1959,28 @@ static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, | |||
1953 | 1959 | ||
1954 | if (sock->file->f_flags & O_NONBLOCK) | 1960 | if (sock->file->f_flags & O_NONBLOCK) |
1955 | msg_sys->msg_flags |= MSG_DONTWAIT; | 1961 | msg_sys->msg_flags |= MSG_DONTWAIT; |
1956 | err = (nosec ? sock_sendmsg_nosec : sock_sendmsg)(sock, msg_sys, | 1962 | /* |
1957 | total_len); | 1963 | * If this is sendmmsg() and current destination address is same as |
1964 | * previously succeeded address, omit asking LSM's decision. | ||
1965 | * used_address->name_len is initialized to UINT_MAX so that the first | ||
1966 | * destination address never matches. | ||
1967 | */ | ||
1968 | if (used_address && used_address->name_len == msg_sys->msg_namelen && | ||
1969 | !memcmp(&used_address->name, msg->msg_name, | ||
1970 | used_address->name_len)) { | ||
1971 | err = sock_sendmsg_nosec(sock, msg_sys, total_len); | ||
1972 | goto out_freectl; | ||
1973 | } | ||
1974 | err = sock_sendmsg(sock, msg_sys, total_len); | ||
1975 | /* | ||
1976 | * If this is sendmmsg() and sending to current destination address was | ||
1977 | * successful, remember it. | ||
1978 | */ | ||
1979 | if (used_address && err >= 0) { | ||
1980 | used_address->name_len = msg_sys->msg_namelen; | ||
1981 | memcpy(&used_address->name, msg->msg_name, | ||
1982 | used_address->name_len); | ||
1983 | } | ||
1958 | 1984 | ||
1959 | out_freectl: | 1985 | out_freectl: |
1960 | if (ctl_buf != ctl) | 1986 | if (ctl_buf != ctl) |
@@ -1979,7 +2005,7 @@ SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags) | |||
1979 | if (!sock) | 2005 | if (!sock) |
1980 | goto out; | 2006 | goto out; |
1981 | 2007 | ||
1982 | err = __sys_sendmsg(sock, msg, &msg_sys, flags, 0); | 2008 | err = __sys_sendmsg(sock, msg, &msg_sys, flags, NULL); |
1983 | 2009 | ||
1984 | fput_light(sock->file, fput_needed); | 2010 | fput_light(sock->file, fput_needed); |
1985 | out: | 2011 | out: |
@@ -1998,6 +2024,10 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, | |||
1998 | struct mmsghdr __user *entry; | 2024 | struct mmsghdr __user *entry; |
1999 | struct compat_mmsghdr __user *compat_entry; | 2025 | struct compat_mmsghdr __user *compat_entry; |
2000 | struct msghdr msg_sys; | 2026 | struct msghdr msg_sys; |
2027 | struct used_address used_address; | ||
2028 | |||
2029 | if (vlen > UIO_MAXIOV) | ||
2030 | vlen = UIO_MAXIOV; | ||
2001 | 2031 | ||
2002 | datagrams = 0; | 2032 | datagrams = 0; |
2003 | 2033 | ||
@@ -2005,27 +2035,22 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, | |||
2005 | if (!sock) | 2035 | if (!sock) |
2006 | return err; | 2036 | return err; |
2007 | 2037 | ||
2008 | err = sock_error(sock->sk); | 2038 | used_address.name_len = UINT_MAX; |
2009 | if (err) | ||
2010 | goto out_put; | ||
2011 | |||
2012 | entry = mmsg; | 2039 | entry = mmsg; |
2013 | compat_entry = (struct compat_mmsghdr __user *)mmsg; | 2040 | compat_entry = (struct compat_mmsghdr __user *)mmsg; |
2041 | err = 0; | ||
2014 | 2042 | ||
2015 | while (datagrams < vlen) { | 2043 | while (datagrams < vlen) { |
2016 | /* | ||
2017 | * No need to ask LSM for more than the first datagram. | ||
2018 | */ | ||
2019 | if (MSG_CMSG_COMPAT & flags) { | 2044 | if (MSG_CMSG_COMPAT & flags) { |
2020 | err = __sys_sendmsg(sock, (struct msghdr __user *)compat_entry, | 2045 | err = __sys_sendmsg(sock, (struct msghdr __user *)compat_entry, |
2021 | &msg_sys, flags, datagrams); | 2046 | &msg_sys, flags, &used_address); |
2022 | if (err < 0) | 2047 | if (err < 0) |
2023 | break; | 2048 | break; |
2024 | err = __put_user(err, &compat_entry->msg_len); | 2049 | err = __put_user(err, &compat_entry->msg_len); |
2025 | ++compat_entry; | 2050 | ++compat_entry; |
2026 | } else { | 2051 | } else { |
2027 | err = __sys_sendmsg(sock, (struct msghdr __user *)entry, | 2052 | err = __sys_sendmsg(sock, (struct msghdr __user *)entry, |
2028 | &msg_sys, flags, datagrams); | 2053 | &msg_sys, flags, &used_address); |
2029 | if (err < 0) | 2054 | if (err < 0) |
2030 | break; | 2055 | break; |
2031 | err = put_user(err, &entry->msg_len); | 2056 | err = put_user(err, &entry->msg_len); |
@@ -2037,29 +2062,11 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, | |||
2037 | ++datagrams; | 2062 | ++datagrams; |
2038 | } | 2063 | } |
2039 | 2064 | ||
2040 | out_put: | ||
2041 | fput_light(sock->file, fput_needed); | 2065 | fput_light(sock->file, fput_needed); |
2042 | 2066 | ||
2043 | if (err == 0) | 2067 | /* We only return an error if no datagrams were able to be sent */ |
2044 | return datagrams; | 2068 | if (datagrams != 0) |
2045 | |||
2046 | if (datagrams != 0) { | ||
2047 | /* | ||
2048 | * We may send less entries than requested (vlen) if the | ||
2049 | * sock is non blocking... | ||
2050 | */ | ||
2051 | if (err != -EAGAIN) { | ||
2052 | /* | ||
2053 | * ... or if sendmsg returns an error after we | ||
2054 | * send some datagrams, where we record the | ||
2055 | * error to return on the next call or if the | ||
2056 | * app asks about it using getsockopt(SO_ERROR). | ||
2057 | */ | ||
2058 | sock->sk->sk_err = -err; | ||
2059 | } | ||
2060 | |||
2061 | return datagrams; | 2069 | return datagrams; |
2062 | } | ||
2063 | 2070 | ||
2064 | return err; | 2071 | return err; |
2065 | } | 2072 | } |
diff --git a/net/sunrpc/Kconfig b/net/sunrpc/Kconfig index b2198e65d8b..ffd243d0918 100644 --- a/net/sunrpc/Kconfig +++ b/net/sunrpc/Kconfig | |||
@@ -4,6 +4,10 @@ config SUNRPC | |||
4 | config SUNRPC_GSS | 4 | config SUNRPC_GSS |
5 | tristate | 5 | tristate |
6 | 6 | ||
7 | config SUNRPC_BACKCHANNEL | ||
8 | bool | ||
9 | depends on SUNRPC | ||
10 | |||
7 | config SUNRPC_XPRT_RDMA | 11 | config SUNRPC_XPRT_RDMA |
8 | tristate | 12 | tristate |
9 | depends on SUNRPC && INFINIBAND && INFINIBAND_ADDR_TRANS && EXPERIMENTAL | 13 | depends on SUNRPC && INFINIBAND && INFINIBAND_ADDR_TRANS && EXPERIMENTAL |
diff --git a/net/sunrpc/Makefile b/net/sunrpc/Makefile index 9d2fca5ad14..8209a0411bc 100644 --- a/net/sunrpc/Makefile +++ b/net/sunrpc/Makefile | |||
@@ -13,6 +13,6 @@ sunrpc-y := clnt.o xprt.o socklib.o xprtsock.o sched.o \ | |||
13 | addr.o rpcb_clnt.o timer.o xdr.o \ | 13 | addr.o rpcb_clnt.o timer.o xdr.o \ |
14 | sunrpc_syms.o cache.o rpc_pipe.o \ | 14 | sunrpc_syms.o cache.o rpc_pipe.o \ |
15 | svc_xprt.o | 15 | svc_xprt.o |
16 | sunrpc-$(CONFIG_NFS_V4_1) += backchannel_rqst.o bc_svc.o | 16 | sunrpc-$(CONFIG_SUNRPC_BACKCHANNEL) += backchannel_rqst.o bc_svc.o |
17 | sunrpc-$(CONFIG_PROC_FS) += stats.o | 17 | sunrpc-$(CONFIG_PROC_FS) += stats.o |
18 | sunrpc-$(CONFIG_SYSCTL) += sysctl.o | 18 | sunrpc-$(CONFIG_SYSCTL) += sysctl.o |
diff --git a/net/sunrpc/auth_gss/gss_krb5_mech.c b/net/sunrpc/auth_gss/gss_krb5_mech.c index c3b75333b82..8c67890de42 100644 --- a/net/sunrpc/auth_gss/gss_krb5_mech.c +++ b/net/sunrpc/auth_gss/gss_krb5_mech.c | |||
@@ -744,6 +744,13 @@ static struct pf_desc gss_kerberos_pfs[] = { | |||
744 | }, | 744 | }, |
745 | }; | 745 | }; |
746 | 746 | ||
747 | MODULE_ALIAS("rpc-auth-gss-krb5"); | ||
748 | MODULE_ALIAS("rpc-auth-gss-krb5i"); | ||
749 | MODULE_ALIAS("rpc-auth-gss-krb5p"); | ||
750 | MODULE_ALIAS("rpc-auth-gss-390003"); | ||
751 | MODULE_ALIAS("rpc-auth-gss-390004"); | ||
752 | MODULE_ALIAS("rpc-auth-gss-390005"); | ||
753 | |||
747 | static struct gss_api_mech gss_kerberos_mech = { | 754 | static struct gss_api_mech gss_kerberos_mech = { |
748 | .gm_name = "krb5", | 755 | .gm_name = "krb5", |
749 | .gm_owner = THIS_MODULE, | 756 | .gm_owner = THIS_MODULE, |
diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c index e3c36a27441..ca8cad8251c 100644 --- a/net/sunrpc/auth_gss/gss_mech_switch.c +++ b/net/sunrpc/auth_gss/gss_mech_switch.c | |||
@@ -141,7 +141,7 @@ gss_mech_get(struct gss_api_mech *gm) | |||
141 | EXPORT_SYMBOL_GPL(gss_mech_get); | 141 | EXPORT_SYMBOL_GPL(gss_mech_get); |
142 | 142 | ||
143 | struct gss_api_mech * | 143 | struct gss_api_mech * |
144 | gss_mech_get_by_name(const char *name) | 144 | _gss_mech_get_by_name(const char *name) |
145 | { | 145 | { |
146 | struct gss_api_mech *pos, *gm = NULL; | 146 | struct gss_api_mech *pos, *gm = NULL; |
147 | 147 | ||
@@ -158,6 +158,17 @@ gss_mech_get_by_name(const char *name) | |||
158 | 158 | ||
159 | } | 159 | } |
160 | 160 | ||
161 | struct gss_api_mech * gss_mech_get_by_name(const char *name) | ||
162 | { | ||
163 | struct gss_api_mech *gm = NULL; | ||
164 | |||
165 | gm = _gss_mech_get_by_name(name); | ||
166 | if (!gm) { | ||
167 | request_module("rpc-auth-gss-%s", name); | ||
168 | gm = _gss_mech_get_by_name(name); | ||
169 | } | ||
170 | return gm; | ||
171 | } | ||
161 | EXPORT_SYMBOL_GPL(gss_mech_get_by_name); | 172 | EXPORT_SYMBOL_GPL(gss_mech_get_by_name); |
162 | 173 | ||
163 | struct gss_api_mech * | 174 | struct gss_api_mech * |
@@ -194,10 +205,9 @@ mech_supports_pseudoflavor(struct gss_api_mech *gm, u32 pseudoflavor) | |||
194 | return 0; | 205 | return 0; |
195 | } | 206 | } |
196 | 207 | ||
197 | struct gss_api_mech * | 208 | struct gss_api_mech *_gss_mech_get_by_pseudoflavor(u32 pseudoflavor) |
198 | gss_mech_get_by_pseudoflavor(u32 pseudoflavor) | ||
199 | { | 209 | { |
200 | struct gss_api_mech *pos, *gm = NULL; | 210 | struct gss_api_mech *gm = NULL, *pos; |
201 | 211 | ||
202 | spin_lock(®istered_mechs_lock); | 212 | spin_lock(®istered_mechs_lock); |
203 | list_for_each_entry(pos, ®istered_mechs, gm_list) { | 213 | list_for_each_entry(pos, ®istered_mechs, gm_list) { |
@@ -213,6 +223,20 @@ gss_mech_get_by_pseudoflavor(u32 pseudoflavor) | |||
213 | return gm; | 223 | return gm; |
214 | } | 224 | } |
215 | 225 | ||
226 | struct gss_api_mech * | ||
227 | gss_mech_get_by_pseudoflavor(u32 pseudoflavor) | ||
228 | { | ||
229 | struct gss_api_mech *gm; | ||
230 | |||
231 | gm = _gss_mech_get_by_pseudoflavor(pseudoflavor); | ||
232 | |||
233 | if (!gm) { | ||
234 | request_module("rpc-auth-gss-%u", pseudoflavor); | ||
235 | gm = _gss_mech_get_by_pseudoflavor(pseudoflavor); | ||
236 | } | ||
237 | return gm; | ||
238 | } | ||
239 | |||
216 | EXPORT_SYMBOL_GPL(gss_mech_get_by_pseudoflavor); | 240 | EXPORT_SYMBOL_GPL(gss_mech_get_by_pseudoflavor); |
217 | 241 | ||
218 | int gss_mech_list_pseudoflavors(rpc_authflavor_t *array_ptr) | 242 | int gss_mech_list_pseudoflavors(rpc_authflavor_t *array_ptr) |
diff --git a/net/sunrpc/backchannel_rqst.c b/net/sunrpc/backchannel_rqst.c index cf06af3b63c..91eaa26e4c4 100644 --- a/net/sunrpc/backchannel_rqst.c +++ b/net/sunrpc/backchannel_rqst.c | |||
@@ -29,8 +29,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
29 | #define RPCDBG_FACILITY RPCDBG_TRANS | 29 | #define RPCDBG_FACILITY RPCDBG_TRANS |
30 | #endif | 30 | #endif |
31 | 31 | ||
32 | #if defined(CONFIG_NFS_V4_1) | ||
33 | |||
34 | /* | 32 | /* |
35 | * Helper routines that track the number of preallocation elements | 33 | * Helper routines that track the number of preallocation elements |
36 | * on the transport. | 34 | * on the transport. |
@@ -174,7 +172,7 @@ out_free: | |||
174 | dprintk("RPC: setup backchannel transport failed\n"); | 172 | dprintk("RPC: setup backchannel transport failed\n"); |
175 | return -1; | 173 | return -1; |
176 | } | 174 | } |
177 | EXPORT_SYMBOL(xprt_setup_backchannel); | 175 | EXPORT_SYMBOL_GPL(xprt_setup_backchannel); |
178 | 176 | ||
179 | /* | 177 | /* |
180 | * Destroys the backchannel preallocated structures. | 178 | * Destroys the backchannel preallocated structures. |
@@ -204,7 +202,7 @@ void xprt_destroy_backchannel(struct rpc_xprt *xprt, unsigned int max_reqs) | |||
204 | dprintk("RPC: backchannel list empty= %s\n", | 202 | dprintk("RPC: backchannel list empty= %s\n", |
205 | list_empty(&xprt->bc_pa_list) ? "true" : "false"); | 203 | list_empty(&xprt->bc_pa_list) ? "true" : "false"); |
206 | } | 204 | } |
207 | EXPORT_SYMBOL(xprt_destroy_backchannel); | 205 | EXPORT_SYMBOL_GPL(xprt_destroy_backchannel); |
208 | 206 | ||
209 | /* | 207 | /* |
210 | * One or more rpc_rqst structure have been preallocated during the | 208 | * One or more rpc_rqst structure have been preallocated during the |
@@ -279,4 +277,3 @@ void xprt_free_bc_request(struct rpc_rqst *req) | |||
279 | spin_unlock_bh(&xprt->bc_pa_lock); | 277 | spin_unlock_bh(&xprt->bc_pa_lock); |
280 | } | 278 | } |
281 | 279 | ||
282 | #endif /* CONFIG_NFS_V4_1 */ | ||
diff --git a/net/sunrpc/bc_svc.c b/net/sunrpc/bc_svc.c index 1dd1a689000..0b2eb388cbd 100644 --- a/net/sunrpc/bc_svc.c +++ b/net/sunrpc/bc_svc.c | |||
@@ -27,8 +27,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |||
27 | * reply over an existing open connection previously established by the client. | 27 | * reply over an existing open connection previously established by the client. |
28 | */ | 28 | */ |
29 | 29 | ||
30 | #if defined(CONFIG_NFS_V4_1) | ||
31 | |||
32 | #include <linux/module.h> | 30 | #include <linux/module.h> |
33 | 31 | ||
34 | #include <linux/sunrpc/xprt.h> | 32 | #include <linux/sunrpc/xprt.h> |
@@ -63,4 +61,3 @@ int bc_send(struct rpc_rqst *req) | |||
63 | return ret; | 61 | return ret; |
64 | } | 62 | } |
65 | 63 | ||
66 | #endif /* CONFIG_NFS_V4_1 */ | ||
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index c50818f0473..c5347d29cfb 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -64,9 +64,9 @@ static void call_decode(struct rpc_task *task); | |||
64 | static void call_bind(struct rpc_task *task); | 64 | static void call_bind(struct rpc_task *task); |
65 | static void call_bind_status(struct rpc_task *task); | 65 | static void call_bind_status(struct rpc_task *task); |
66 | static void call_transmit(struct rpc_task *task); | 66 | static void call_transmit(struct rpc_task *task); |
67 | #if defined(CONFIG_NFS_V4_1) | 67 | #if defined(CONFIG_SUNRPC_BACKCHANNEL) |
68 | static void call_bc_transmit(struct rpc_task *task); | 68 | static void call_bc_transmit(struct rpc_task *task); |
69 | #endif /* CONFIG_NFS_V4_1 */ | 69 | #endif /* CONFIG_SUNRPC_BACKCHANNEL */ |
70 | static void call_status(struct rpc_task *task); | 70 | static void call_status(struct rpc_task *task); |
71 | static void call_transmit_status(struct rpc_task *task); | 71 | static void call_transmit_status(struct rpc_task *task); |
72 | static void call_refresh(struct rpc_task *task); | 72 | static void call_refresh(struct rpc_task *task); |
@@ -715,7 +715,7 @@ rpc_call_async(struct rpc_clnt *clnt, const struct rpc_message *msg, int flags, | |||
715 | } | 715 | } |
716 | EXPORT_SYMBOL_GPL(rpc_call_async); | 716 | EXPORT_SYMBOL_GPL(rpc_call_async); |
717 | 717 | ||
718 | #if defined(CONFIG_NFS_V4_1) | 718 | #if defined(CONFIG_SUNRPC_BACKCHANNEL) |
719 | /** | 719 | /** |
720 | * rpc_run_bc_task - Allocate a new RPC task for backchannel use, then run | 720 | * rpc_run_bc_task - Allocate a new RPC task for backchannel use, then run |
721 | * rpc_execute against it | 721 | * rpc_execute against it |
@@ -758,7 +758,7 @@ out: | |||
758 | dprintk("RPC: rpc_run_bc_task: task= %p\n", task); | 758 | dprintk("RPC: rpc_run_bc_task: task= %p\n", task); |
759 | return task; | 759 | return task; |
760 | } | 760 | } |
761 | #endif /* CONFIG_NFS_V4_1 */ | 761 | #endif /* CONFIG_SUNRPC_BACKCHANNEL */ |
762 | 762 | ||
763 | void | 763 | void |
764 | rpc_call_start(struct rpc_task *task) | 764 | rpc_call_start(struct rpc_task *task) |
@@ -1361,7 +1361,7 @@ call_transmit_status(struct rpc_task *task) | |||
1361 | } | 1361 | } |
1362 | } | 1362 | } |
1363 | 1363 | ||
1364 | #if defined(CONFIG_NFS_V4_1) | 1364 | #if defined(CONFIG_SUNRPC_BACKCHANNEL) |
1365 | /* | 1365 | /* |
1366 | * 5b. Send the backchannel RPC reply. On error, drop the reply. In | 1366 | * 5b. Send the backchannel RPC reply. On error, drop the reply. In |
1367 | * addition, disconnect on connectivity errors. | 1367 | * addition, disconnect on connectivity errors. |
@@ -1425,7 +1425,7 @@ call_bc_transmit(struct rpc_task *task) | |||
1425 | } | 1425 | } |
1426 | rpc_wake_up_queued_task(&req->rq_xprt->pending, task); | 1426 | rpc_wake_up_queued_task(&req->rq_xprt->pending, task); |
1427 | } | 1427 | } |
1428 | #endif /* CONFIG_NFS_V4_1 */ | 1428 | #endif /* CONFIG_SUNRPC_BACKCHANNEL */ |
1429 | 1429 | ||
1430 | /* | 1430 | /* |
1431 | * 6. Sort out the RPC call status | 1431 | * 6. Sort out the RPC call status |
@@ -1550,8 +1550,7 @@ call_decode(struct rpc_task *task) | |||
1550 | kxdrdproc_t decode = task->tk_msg.rpc_proc->p_decode; | 1550 | kxdrdproc_t decode = task->tk_msg.rpc_proc->p_decode; |
1551 | __be32 *p; | 1551 | __be32 *p; |
1552 | 1552 | ||
1553 | dprintk("RPC: %5u call_decode (status %d)\n", | 1553 | dprint_status(task); |
1554 | task->tk_pid, task->tk_status); | ||
1555 | 1554 | ||
1556 | if (task->tk_flags & RPC_CALL_MAJORSEEN) { | 1555 | if (task->tk_flags & RPC_CALL_MAJORSEEN) { |
1557 | if (clnt->cl_chatty) | 1556 | if (clnt->cl_chatty) |
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 4814e246a87..d12ffa54581 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c | |||
@@ -97,14 +97,16 @@ __rpc_add_timer(struct rpc_wait_queue *queue, struct rpc_task *task) | |||
97 | /* | 97 | /* |
98 | * Add new request to a priority queue. | 98 | * Add new request to a priority queue. |
99 | */ | 99 | */ |
100 | static void __rpc_add_wait_queue_priority(struct rpc_wait_queue *queue, struct rpc_task *task) | 100 | static void __rpc_add_wait_queue_priority(struct rpc_wait_queue *queue, |
101 | struct rpc_task *task, | ||
102 | unsigned char queue_priority) | ||
101 | { | 103 | { |
102 | struct list_head *q; | 104 | struct list_head *q; |
103 | struct rpc_task *t; | 105 | struct rpc_task *t; |
104 | 106 | ||
105 | INIT_LIST_HEAD(&task->u.tk_wait.links); | 107 | INIT_LIST_HEAD(&task->u.tk_wait.links); |
106 | q = &queue->tasks[task->tk_priority]; | 108 | q = &queue->tasks[queue_priority]; |
107 | if (unlikely(task->tk_priority > queue->maxpriority)) | 109 | if (unlikely(queue_priority > queue->maxpriority)) |
108 | q = &queue->tasks[queue->maxpriority]; | 110 | q = &queue->tasks[queue->maxpriority]; |
109 | list_for_each_entry(t, q, u.tk_wait.list) { | 111 | list_for_each_entry(t, q, u.tk_wait.list) { |
110 | if (t->tk_owner == task->tk_owner) { | 112 | if (t->tk_owner == task->tk_owner) { |
@@ -123,12 +125,14 @@ static void __rpc_add_wait_queue_priority(struct rpc_wait_queue *queue, struct r | |||
123 | * improve overall performance. | 125 | * improve overall performance. |
124 | * Everyone else gets appended to the queue to ensure proper FIFO behavior. | 126 | * Everyone else gets appended to the queue to ensure proper FIFO behavior. |
125 | */ | 127 | */ |
126 | static void __rpc_add_wait_queue(struct rpc_wait_queue *queue, struct rpc_task *task) | 128 | static void __rpc_add_wait_queue(struct rpc_wait_queue *queue, |
129 | struct rpc_task *task, | ||
130 | unsigned char queue_priority) | ||
127 | { | 131 | { |
128 | BUG_ON (RPC_IS_QUEUED(task)); | 132 | BUG_ON (RPC_IS_QUEUED(task)); |
129 | 133 | ||
130 | if (RPC_IS_PRIORITY(queue)) | 134 | if (RPC_IS_PRIORITY(queue)) |
131 | __rpc_add_wait_queue_priority(queue, task); | 135 | __rpc_add_wait_queue_priority(queue, task, queue_priority); |
132 | else if (RPC_IS_SWAPPER(task)) | 136 | else if (RPC_IS_SWAPPER(task)) |
133 | list_add(&task->u.tk_wait.list, &queue->tasks[0]); | 137 | list_add(&task->u.tk_wait.list, &queue->tasks[0]); |
134 | else | 138 | else |
@@ -311,13 +315,15 @@ static void rpc_make_runnable(struct rpc_task *task) | |||
311 | * NB: An RPC task will only receive interrupt-driven events as long | 315 | * NB: An RPC task will only receive interrupt-driven events as long |
312 | * as it's on a wait queue. | 316 | * as it's on a wait queue. |
313 | */ | 317 | */ |
314 | static void __rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task, | 318 | static void __rpc_sleep_on_priority(struct rpc_wait_queue *q, |
315 | rpc_action action) | 319 | struct rpc_task *task, |
320 | rpc_action action, | ||
321 | unsigned char queue_priority) | ||
316 | { | 322 | { |
317 | dprintk("RPC: %5u sleep_on(queue \"%s\" time %lu)\n", | 323 | dprintk("RPC: %5u sleep_on(queue \"%s\" time %lu)\n", |
318 | task->tk_pid, rpc_qname(q), jiffies); | 324 | task->tk_pid, rpc_qname(q), jiffies); |
319 | 325 | ||
320 | __rpc_add_wait_queue(q, task); | 326 | __rpc_add_wait_queue(q, task, queue_priority); |
321 | 327 | ||
322 | BUG_ON(task->tk_callback != NULL); | 328 | BUG_ON(task->tk_callback != NULL); |
323 | task->tk_callback = action; | 329 | task->tk_callback = action; |
@@ -334,11 +340,25 @@ void rpc_sleep_on(struct rpc_wait_queue *q, struct rpc_task *task, | |||
334 | * Protect the queue operations. | 340 | * Protect the queue operations. |
335 | */ | 341 | */ |
336 | spin_lock_bh(&q->lock); | 342 | spin_lock_bh(&q->lock); |
337 | __rpc_sleep_on(q, task, action); | 343 | __rpc_sleep_on_priority(q, task, action, task->tk_priority); |
338 | spin_unlock_bh(&q->lock); | 344 | spin_unlock_bh(&q->lock); |
339 | } | 345 | } |
340 | EXPORT_SYMBOL_GPL(rpc_sleep_on); | 346 | EXPORT_SYMBOL_GPL(rpc_sleep_on); |
341 | 347 | ||
348 | void rpc_sleep_on_priority(struct rpc_wait_queue *q, struct rpc_task *task, | ||
349 | rpc_action action, int priority) | ||
350 | { | ||
351 | /* We shouldn't ever put an inactive task to sleep */ | ||
352 | BUG_ON(!RPC_IS_ACTIVATED(task)); | ||
353 | |||
354 | /* | ||
355 | * Protect the queue operations. | ||
356 | */ | ||
357 | spin_lock_bh(&q->lock); | ||
358 | __rpc_sleep_on_priority(q, task, action, priority - RPC_PRIORITY_LOW); | ||
359 | spin_unlock_bh(&q->lock); | ||
360 | } | ||
361 | |||
342 | /** | 362 | /** |
343 | * __rpc_do_wake_up_task - wake up a single rpc_task | 363 | * __rpc_do_wake_up_task - wake up a single rpc_task |
344 | * @queue: wait queue | 364 | * @queue: wait queue |
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index 2b90292e950..6a69a1131fb 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c | |||
@@ -1252,7 +1252,7 @@ svc_process(struct svc_rqst *rqstp) | |||
1252 | } | 1252 | } |
1253 | } | 1253 | } |
1254 | 1254 | ||
1255 | #if defined(CONFIG_NFS_V4_1) | 1255 | #if defined(CONFIG_SUNRPC_BACKCHANNEL) |
1256 | /* | 1256 | /* |
1257 | * Process a backchannel RPC request that arrived over an existing | 1257 | * Process a backchannel RPC request that arrived over an existing |
1258 | * outbound connection | 1258 | * outbound connection |
@@ -1300,8 +1300,8 @@ bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req, | |||
1300 | return 0; | 1300 | return 0; |
1301 | } | 1301 | } |
1302 | } | 1302 | } |
1303 | EXPORT_SYMBOL(bc_svc_process); | 1303 | EXPORT_SYMBOL_GPL(bc_svc_process); |
1304 | #endif /* CONFIG_NFS_V4_1 */ | 1304 | #endif /* CONFIG_SUNRPC_BACKCHANNEL */ |
1305 | 1305 | ||
1306 | /* | 1306 | /* |
1307 | * Return (transport-specific) limit on the rpc payload. | 1307 | * Return (transport-specific) limit on the rpc payload. |
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index ab86b7927f8..bd31208bbb6 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c | |||
@@ -902,12 +902,13 @@ void svc_delete_xprt(struct svc_xprt *xprt) | |||
902 | if (!test_and_set_bit(XPT_DETACHED, &xprt->xpt_flags)) | 902 | if (!test_and_set_bit(XPT_DETACHED, &xprt->xpt_flags)) |
903 | list_del_init(&xprt->xpt_list); | 903 | list_del_init(&xprt->xpt_list); |
904 | /* | 904 | /* |
905 | * We used to delete the transport from whichever list | 905 | * The only time we're called while xpt_ready is still on a list |
906 | * it's sk_xprt.xpt_ready node was on, but we don't actually | 906 | * is while the list itself is about to be destroyed (in |
907 | * need to. This is because the only time we're called | 907 | * svc_destroy). BUT svc_xprt_enqueue could still be attempting |
908 | * while still attached to a queue, the queue itself | 908 | * to add new entries to the sp_sockets list, so we can't leave |
909 | * is about to be destroyed (in svc_destroy). | 909 | * a freed xprt on it. |
910 | */ | 910 | */ |
911 | list_del_init(&xprt->xpt_ready); | ||
911 | if (test_bit(XPT_TEMP, &xprt->xpt_flags)) | 912 | if (test_bit(XPT_TEMP, &xprt->xpt_flags)) |
912 | serv->sv_tmpcnt--; | 913 | serv->sv_tmpcnt--; |
913 | spin_unlock_bh(&serv->sv_lock); | 914 | spin_unlock_bh(&serv->sv_lock); |
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index c8e10216c11..ce136323da8 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c | |||
@@ -30,12 +30,10 @@ | |||
30 | 30 | ||
31 | struct unix_domain { | 31 | struct unix_domain { |
32 | struct auth_domain h; | 32 | struct auth_domain h; |
33 | #ifdef CONFIG_NFSD_DEPRECATED | ||
34 | int addr_changes; | ||
35 | #endif /* CONFIG_NFSD_DEPRECATED */ | ||
36 | /* other stuff later */ | 33 | /* other stuff later */ |
37 | }; | 34 | }; |
38 | 35 | ||
36 | extern struct auth_ops svcauth_null; | ||
39 | extern struct auth_ops svcauth_unix; | 37 | extern struct auth_ops svcauth_unix; |
40 | 38 | ||
41 | static void svcauth_unix_domain_release(struct auth_domain *dom) | 39 | static void svcauth_unix_domain_release(struct auth_domain *dom) |
@@ -74,9 +72,6 @@ struct auth_domain *unix_domain_find(char *name) | |||
74 | return NULL; | 72 | return NULL; |
75 | } | 73 | } |
76 | new->h.flavour = &svcauth_unix; | 74 | new->h.flavour = &svcauth_unix; |
77 | #ifdef CONFIG_NFSD_DEPRECATED | ||
78 | new->addr_changes = 0; | ||
79 | #endif /* CONFIG_NFSD_DEPRECATED */ | ||
80 | rv = auth_domain_lookup(name, &new->h); | 75 | rv = auth_domain_lookup(name, &new->h); |
81 | } | 76 | } |
82 | } | 77 | } |
@@ -95,9 +90,6 @@ struct ip_map { | |||
95 | char m_class[8]; /* e.g. "nfsd" */ | 90 | char m_class[8]; /* e.g. "nfsd" */ |
96 | struct in6_addr m_addr; | 91 | struct in6_addr m_addr; |
97 | struct unix_domain *m_client; | 92 | struct unix_domain *m_client; |
98 | #ifdef CONFIG_NFSD_DEPRECATED | ||
99 | int m_add_change; | ||
100 | #endif /* CONFIG_NFSD_DEPRECATED */ | ||
101 | }; | 93 | }; |
102 | 94 | ||
103 | static void ip_map_put(struct kref *kref) | 95 | static void ip_map_put(struct kref *kref) |
@@ -151,9 +143,6 @@ static void update(struct cache_head *cnew, struct cache_head *citem) | |||
151 | 143 | ||
152 | kref_get(&item->m_client->h.ref); | 144 | kref_get(&item->m_client->h.ref); |
153 | new->m_client = item->m_client; | 145 | new->m_client = item->m_client; |
154 | #ifdef CONFIG_NFSD_DEPRECATED | ||
155 | new->m_add_change = item->m_add_change; | ||
156 | #endif /* CONFIG_NFSD_DEPRECATED */ | ||
157 | } | 146 | } |
158 | static struct cache_head *ip_map_alloc(void) | 147 | static struct cache_head *ip_map_alloc(void) |
159 | { | 148 | { |
@@ -338,16 +327,6 @@ static int __ip_map_update(struct cache_detail *cd, struct ip_map *ipm, | |||
338 | ip.h.flags = 0; | 327 | ip.h.flags = 0; |
339 | if (!udom) | 328 | if (!udom) |
340 | set_bit(CACHE_NEGATIVE, &ip.h.flags); | 329 | set_bit(CACHE_NEGATIVE, &ip.h.flags); |
341 | #ifdef CONFIG_NFSD_DEPRECATED | ||
342 | else { | ||
343 | ip.m_add_change = udom->addr_changes; | ||
344 | /* if this is from the legacy set_client system call, | ||
345 | * we need m_add_change to be one higher | ||
346 | */ | ||
347 | if (expiry == NEVER) | ||
348 | ip.m_add_change++; | ||
349 | } | ||
350 | #endif /* CONFIG_NFSD_DEPRECATED */ | ||
351 | ip.h.expiry_time = expiry; | 330 | ip.h.expiry_time = expiry; |
352 | ch = sunrpc_cache_update(cd, &ip.h, &ipm->h, | 331 | ch = sunrpc_cache_update(cd, &ip.h, &ipm->h, |
353 | hash_str(ipm->m_class, IP_HASHBITS) ^ | 332 | hash_str(ipm->m_class, IP_HASHBITS) ^ |
@@ -367,62 +346,6 @@ static inline int ip_map_update(struct net *net, struct ip_map *ipm, | |||
367 | return __ip_map_update(sn->ip_map_cache, ipm, udom, expiry); | 346 | return __ip_map_update(sn->ip_map_cache, ipm, udom, expiry); |
368 | } | 347 | } |
369 | 348 | ||
370 | #ifdef CONFIG_NFSD_DEPRECATED | ||
371 | int auth_unix_add_addr(struct net *net, struct in6_addr *addr, struct auth_domain *dom) | ||
372 | { | ||
373 | struct unix_domain *udom; | ||
374 | struct ip_map *ipmp; | ||
375 | |||
376 | if (dom->flavour != &svcauth_unix) | ||
377 | return -EINVAL; | ||
378 | udom = container_of(dom, struct unix_domain, h); | ||
379 | ipmp = ip_map_lookup(net, "nfsd", addr); | ||
380 | |||
381 | if (ipmp) | ||
382 | return ip_map_update(net, ipmp, udom, NEVER); | ||
383 | else | ||
384 | return -ENOMEM; | ||
385 | } | ||
386 | EXPORT_SYMBOL_GPL(auth_unix_add_addr); | ||
387 | |||
388 | int auth_unix_forget_old(struct auth_domain *dom) | ||
389 | { | ||
390 | struct unix_domain *udom; | ||
391 | |||
392 | if (dom->flavour != &svcauth_unix) | ||
393 | return -EINVAL; | ||
394 | udom = container_of(dom, struct unix_domain, h); | ||
395 | udom->addr_changes++; | ||
396 | return 0; | ||
397 | } | ||
398 | EXPORT_SYMBOL_GPL(auth_unix_forget_old); | ||
399 | |||
400 | struct auth_domain *auth_unix_lookup(struct net *net, struct in6_addr *addr) | ||
401 | { | ||
402 | struct ip_map *ipm; | ||
403 | struct auth_domain *rv; | ||
404 | struct sunrpc_net *sn; | ||
405 | |||
406 | sn = net_generic(net, sunrpc_net_id); | ||
407 | ipm = ip_map_lookup(net, "nfsd", addr); | ||
408 | |||
409 | if (!ipm) | ||
410 | return NULL; | ||
411 | if (cache_check(sn->ip_map_cache, &ipm->h, NULL)) | ||
412 | return NULL; | ||
413 | |||
414 | if ((ipm->m_client->addr_changes - ipm->m_add_change) >0) { | ||
415 | sunrpc_invalidate(&ipm->h, sn->ip_map_cache); | ||
416 | rv = NULL; | ||
417 | } else { | ||
418 | rv = &ipm->m_client->h; | ||
419 | kref_get(&rv->ref); | ||
420 | } | ||
421 | cache_put(&ipm->h, sn->ip_map_cache); | ||
422 | return rv; | ||
423 | } | ||
424 | EXPORT_SYMBOL_GPL(auth_unix_lookup); | ||
425 | #endif /* CONFIG_NFSD_DEPRECATED */ | ||
426 | 349 | ||
427 | void svcauth_unix_purge(void) | 350 | void svcauth_unix_purge(void) |
428 | { | 351 | { |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index af04f779ce9..767d494de7a 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
@@ -51,6 +51,8 @@ | |||
51 | #include <linux/sunrpc/stats.h> | 51 | #include <linux/sunrpc/stats.h> |
52 | #include <linux/sunrpc/xprt.h> | 52 | #include <linux/sunrpc/xprt.h> |
53 | 53 | ||
54 | #include "sunrpc.h" | ||
55 | |||
54 | #define RPCDBG_FACILITY RPCDBG_SVCXPRT | 56 | #define RPCDBG_FACILITY RPCDBG_SVCXPRT |
55 | 57 | ||
56 | 58 | ||
@@ -66,12 +68,12 @@ static void svc_sock_free(struct svc_xprt *); | |||
66 | static struct svc_xprt *svc_create_socket(struct svc_serv *, int, | 68 | static struct svc_xprt *svc_create_socket(struct svc_serv *, int, |
67 | struct net *, struct sockaddr *, | 69 | struct net *, struct sockaddr *, |
68 | int, int); | 70 | int, int); |
69 | #if defined(CONFIG_NFS_V4_1) | 71 | #if defined(CONFIG_SUNRPC_BACKCHANNEL) |
70 | static struct svc_xprt *svc_bc_create_socket(struct svc_serv *, int, | 72 | static struct svc_xprt *svc_bc_create_socket(struct svc_serv *, int, |
71 | struct net *, struct sockaddr *, | 73 | struct net *, struct sockaddr *, |
72 | int, int); | 74 | int, int); |
73 | static void svc_bc_sock_free(struct svc_xprt *xprt); | 75 | static void svc_bc_sock_free(struct svc_xprt *xprt); |
74 | #endif /* CONFIG_NFS_V4_1 */ | 76 | #endif /* CONFIG_SUNRPC_BACKCHANNEL */ |
75 | 77 | ||
76 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 78 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
77 | static struct lock_class_key svc_key[2]; | 79 | static struct lock_class_key svc_key[2]; |
@@ -1241,7 +1243,7 @@ static struct svc_xprt *svc_tcp_create(struct svc_serv *serv, | |||
1241 | return svc_create_socket(serv, IPPROTO_TCP, net, sa, salen, flags); | 1243 | return svc_create_socket(serv, IPPROTO_TCP, net, sa, salen, flags); |
1242 | } | 1244 | } |
1243 | 1245 | ||
1244 | #if defined(CONFIG_NFS_V4_1) | 1246 | #if defined(CONFIG_SUNRPC_BACKCHANNEL) |
1245 | static struct svc_xprt *svc_bc_create_socket(struct svc_serv *, int, | 1247 | static struct svc_xprt *svc_bc_create_socket(struct svc_serv *, int, |
1246 | struct net *, struct sockaddr *, | 1248 | struct net *, struct sockaddr *, |
1247 | int, int); | 1249 | int, int); |
@@ -1282,7 +1284,7 @@ static void svc_cleanup_bc_xprt_sock(void) | |||
1282 | { | 1284 | { |
1283 | svc_unreg_xprt_class(&svc_tcp_bc_class); | 1285 | svc_unreg_xprt_class(&svc_tcp_bc_class); |
1284 | } | 1286 | } |
1285 | #else /* CONFIG_NFS_V4_1 */ | 1287 | #else /* CONFIG_SUNRPC_BACKCHANNEL */ |
1286 | static void svc_init_bc_xprt_sock(void) | 1288 | static void svc_init_bc_xprt_sock(void) |
1287 | { | 1289 | { |
1288 | } | 1290 | } |
@@ -1290,7 +1292,7 @@ static void svc_init_bc_xprt_sock(void) | |||
1290 | static void svc_cleanup_bc_xprt_sock(void) | 1292 | static void svc_cleanup_bc_xprt_sock(void) |
1291 | { | 1293 | { |
1292 | } | 1294 | } |
1293 | #endif /* CONFIG_NFS_V4_1 */ | 1295 | #endif /* CONFIG_SUNRPC_BACKCHANNEL */ |
1294 | 1296 | ||
1295 | static struct svc_xprt_ops svc_tcp_ops = { | 1297 | static struct svc_xprt_ops svc_tcp_ops = { |
1296 | .xpo_create = svc_tcp_create, | 1298 | .xpo_create = svc_tcp_create, |
@@ -1621,7 +1623,7 @@ static void svc_sock_free(struct svc_xprt *xprt) | |||
1621 | kfree(svsk); | 1623 | kfree(svsk); |
1622 | } | 1624 | } |
1623 | 1625 | ||
1624 | #if defined(CONFIG_NFS_V4_1) | 1626 | #if defined(CONFIG_SUNRPC_BACKCHANNEL) |
1625 | /* | 1627 | /* |
1626 | * Create a back channel svc_xprt which shares the fore channel socket. | 1628 | * Create a back channel svc_xprt which shares the fore channel socket. |
1627 | */ | 1629 | */ |
@@ -1660,4 +1662,4 @@ static void svc_bc_sock_free(struct svc_xprt *xprt) | |||
1660 | if (xprt) | 1662 | if (xprt) |
1661 | kfree(container_of(xprt, struct svc_sock, sk_xprt)); | 1663 | kfree(container_of(xprt, struct svc_sock, sk_xprt)); |
1662 | } | 1664 | } |
1663 | #endif /* CONFIG_NFS_V4_1 */ | 1665 | #endif /* CONFIG_SUNRPC_BACKCHANNEL */ |
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index f008c14ad34..277ebd4bf09 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c | |||
@@ -126,7 +126,7 @@ xdr_terminate_string(struct xdr_buf *buf, const u32 len) | |||
126 | kaddr[buf->page_base + len] = '\0'; | 126 | kaddr[buf->page_base + len] = '\0'; |
127 | kunmap_atomic(kaddr, KM_USER0); | 127 | kunmap_atomic(kaddr, KM_USER0); |
128 | } | 128 | } |
129 | EXPORT_SYMBOL(xdr_terminate_string); | 129 | EXPORT_SYMBOL_GPL(xdr_terminate_string); |
130 | 130 | ||
131 | void | 131 | void |
132 | xdr_encode_pages(struct xdr_buf *xdr, struct page **pages, unsigned int base, | 132 | xdr_encode_pages(struct xdr_buf *xdr, struct page **pages, unsigned int base, |
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index ce5eb68a966..f4385e45a5f 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
@@ -62,6 +62,7 @@ | |||
62 | /* | 62 | /* |
63 | * Local functions | 63 | * Local functions |
64 | */ | 64 | */ |
65 | static void xprt_init(struct rpc_xprt *xprt, struct net *net); | ||
65 | static void xprt_request_init(struct rpc_task *, struct rpc_xprt *); | 66 | static void xprt_request_init(struct rpc_task *, struct rpc_xprt *); |
66 | static void xprt_connect_status(struct rpc_task *task); | 67 | static void xprt_connect_status(struct rpc_task *task); |
67 | static int __xprt_get_cong(struct rpc_xprt *, struct rpc_task *); | 68 | static int __xprt_get_cong(struct rpc_xprt *, struct rpc_task *); |
@@ -186,15 +187,16 @@ EXPORT_SYMBOL_GPL(xprt_load_transport); | |||
186 | /** | 187 | /** |
187 | * xprt_reserve_xprt - serialize write access to transports | 188 | * xprt_reserve_xprt - serialize write access to transports |
188 | * @task: task that is requesting access to the transport | 189 | * @task: task that is requesting access to the transport |
190 | * @xprt: pointer to the target transport | ||
189 | * | 191 | * |
190 | * This prevents mixing the payload of separate requests, and prevents | 192 | * This prevents mixing the payload of separate requests, and prevents |
191 | * transport connects from colliding with writes. No congestion control | 193 | * transport connects from colliding with writes. No congestion control |
192 | * is provided. | 194 | * is provided. |
193 | */ | 195 | */ |
194 | int xprt_reserve_xprt(struct rpc_task *task) | 196 | int xprt_reserve_xprt(struct rpc_xprt *xprt, struct rpc_task *task) |
195 | { | 197 | { |
196 | struct rpc_rqst *req = task->tk_rqstp; | 198 | struct rpc_rqst *req = task->tk_rqstp; |
197 | struct rpc_xprt *xprt = req->rq_xprt; | 199 | int priority; |
198 | 200 | ||
199 | if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) { | 201 | if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) { |
200 | if (task == xprt->snd_task) | 202 | if (task == xprt->snd_task) |
@@ -202,8 +204,10 @@ int xprt_reserve_xprt(struct rpc_task *task) | |||
202 | goto out_sleep; | 204 | goto out_sleep; |
203 | } | 205 | } |
204 | xprt->snd_task = task; | 206 | xprt->snd_task = task; |
205 | req->rq_bytes_sent = 0; | 207 | if (req != NULL) { |
206 | req->rq_ntrans++; | 208 | req->rq_bytes_sent = 0; |
209 | req->rq_ntrans++; | ||
210 | } | ||
207 | 211 | ||
208 | return 1; | 212 | return 1; |
209 | 213 | ||
@@ -212,10 +216,13 @@ out_sleep: | |||
212 | task->tk_pid, xprt); | 216 | task->tk_pid, xprt); |
213 | task->tk_timeout = 0; | 217 | task->tk_timeout = 0; |
214 | task->tk_status = -EAGAIN; | 218 | task->tk_status = -EAGAIN; |
215 | if (req->rq_ntrans) | 219 | if (req == NULL) |
216 | rpc_sleep_on(&xprt->resend, task, NULL); | 220 | priority = RPC_PRIORITY_LOW; |
221 | else if (!req->rq_ntrans) | ||
222 | priority = RPC_PRIORITY_NORMAL; | ||
217 | else | 223 | else |
218 | rpc_sleep_on(&xprt->sending, task, NULL); | 224 | priority = RPC_PRIORITY_HIGH; |
225 | rpc_sleep_on_priority(&xprt->sending, task, NULL, priority); | ||
219 | return 0; | 226 | return 0; |
220 | } | 227 | } |
221 | EXPORT_SYMBOL_GPL(xprt_reserve_xprt); | 228 | EXPORT_SYMBOL_GPL(xprt_reserve_xprt); |
@@ -239,22 +246,24 @@ static void xprt_clear_locked(struct rpc_xprt *xprt) | |||
239 | * integrated into the decision of whether a request is allowed to be | 246 | * integrated into the decision of whether a request is allowed to be |
240 | * woken up and given access to the transport. | 247 | * woken up and given access to the transport. |
241 | */ | 248 | */ |
242 | int xprt_reserve_xprt_cong(struct rpc_task *task) | 249 | int xprt_reserve_xprt_cong(struct rpc_xprt *xprt, struct rpc_task *task) |
243 | { | 250 | { |
244 | struct rpc_xprt *xprt = task->tk_xprt; | ||
245 | struct rpc_rqst *req = task->tk_rqstp; | 251 | struct rpc_rqst *req = task->tk_rqstp; |
252 | int priority; | ||
246 | 253 | ||
247 | if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) { | 254 | if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) { |
248 | if (task == xprt->snd_task) | 255 | if (task == xprt->snd_task) |
249 | return 1; | 256 | return 1; |
250 | goto out_sleep; | 257 | goto out_sleep; |
251 | } | 258 | } |
259 | if (req == NULL) { | ||
260 | xprt->snd_task = task; | ||
261 | return 1; | ||
262 | } | ||
252 | if (__xprt_get_cong(xprt, task)) { | 263 | if (__xprt_get_cong(xprt, task)) { |
253 | xprt->snd_task = task; | 264 | xprt->snd_task = task; |
254 | if (req) { | 265 | req->rq_bytes_sent = 0; |
255 | req->rq_bytes_sent = 0; | 266 | req->rq_ntrans++; |
256 | req->rq_ntrans++; | ||
257 | } | ||
258 | return 1; | 267 | return 1; |
259 | } | 268 | } |
260 | xprt_clear_locked(xprt); | 269 | xprt_clear_locked(xprt); |
@@ -262,10 +271,13 @@ out_sleep: | |||
262 | dprintk("RPC: %5u failed to lock transport %p\n", task->tk_pid, xprt); | 271 | dprintk("RPC: %5u failed to lock transport %p\n", task->tk_pid, xprt); |
263 | task->tk_timeout = 0; | 272 | task->tk_timeout = 0; |
264 | task->tk_status = -EAGAIN; | 273 | task->tk_status = -EAGAIN; |
265 | if (req && req->rq_ntrans) | 274 | if (req == NULL) |
266 | rpc_sleep_on(&xprt->resend, task, NULL); | 275 | priority = RPC_PRIORITY_LOW; |
276 | else if (!req->rq_ntrans) | ||
277 | priority = RPC_PRIORITY_NORMAL; | ||
267 | else | 278 | else |
268 | rpc_sleep_on(&xprt->sending, task, NULL); | 279 | priority = RPC_PRIORITY_HIGH; |
280 | rpc_sleep_on_priority(&xprt->sending, task, NULL, priority); | ||
269 | return 0; | 281 | return 0; |
270 | } | 282 | } |
271 | EXPORT_SYMBOL_GPL(xprt_reserve_xprt_cong); | 283 | EXPORT_SYMBOL_GPL(xprt_reserve_xprt_cong); |
@@ -275,7 +287,7 @@ static inline int xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task) | |||
275 | int retval; | 287 | int retval; |
276 | 288 | ||
277 | spin_lock_bh(&xprt->transport_lock); | 289 | spin_lock_bh(&xprt->transport_lock); |
278 | retval = xprt->ops->reserve_xprt(task); | 290 | retval = xprt->ops->reserve_xprt(xprt, task); |
279 | spin_unlock_bh(&xprt->transport_lock); | 291 | spin_unlock_bh(&xprt->transport_lock); |
280 | return retval; | 292 | return retval; |
281 | } | 293 | } |
@@ -288,12 +300,9 @@ static void __xprt_lock_write_next(struct rpc_xprt *xprt) | |||
288 | if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) | 300 | if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) |
289 | return; | 301 | return; |
290 | 302 | ||
291 | task = rpc_wake_up_next(&xprt->resend); | 303 | task = rpc_wake_up_next(&xprt->sending); |
292 | if (!task) { | 304 | if (task == NULL) |
293 | task = rpc_wake_up_next(&xprt->sending); | 305 | goto out_unlock; |
294 | if (!task) | ||
295 | goto out_unlock; | ||
296 | } | ||
297 | 306 | ||
298 | req = task->tk_rqstp; | 307 | req = task->tk_rqstp; |
299 | xprt->snd_task = task; | 308 | xprt->snd_task = task; |
@@ -310,24 +319,25 @@ out_unlock: | |||
310 | static void __xprt_lock_write_next_cong(struct rpc_xprt *xprt) | 319 | static void __xprt_lock_write_next_cong(struct rpc_xprt *xprt) |
311 | { | 320 | { |
312 | struct rpc_task *task; | 321 | struct rpc_task *task; |
322 | struct rpc_rqst *req; | ||
313 | 323 | ||
314 | if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) | 324 | if (test_and_set_bit(XPRT_LOCKED, &xprt->state)) |
315 | return; | 325 | return; |
316 | if (RPCXPRT_CONGESTED(xprt)) | 326 | if (RPCXPRT_CONGESTED(xprt)) |
317 | goto out_unlock; | 327 | goto out_unlock; |
318 | task = rpc_wake_up_next(&xprt->resend); | 328 | task = rpc_wake_up_next(&xprt->sending); |
319 | if (!task) { | 329 | if (task == NULL) |
320 | task = rpc_wake_up_next(&xprt->sending); | 330 | goto out_unlock; |
321 | if (!task) | 331 | |
322 | goto out_unlock; | 332 | req = task->tk_rqstp; |
333 | if (req == NULL) { | ||
334 | xprt->snd_task = task; | ||
335 | return; | ||
323 | } | 336 | } |
324 | if (__xprt_get_cong(xprt, task)) { | 337 | if (__xprt_get_cong(xprt, task)) { |
325 | struct rpc_rqst *req = task->tk_rqstp; | ||
326 | xprt->snd_task = task; | 338 | xprt->snd_task = task; |
327 | if (req) { | 339 | req->rq_bytes_sent = 0; |
328 | req->rq_bytes_sent = 0; | 340 | req->rq_ntrans++; |
329 | req->rq_ntrans++; | ||
330 | } | ||
331 | return; | 341 | return; |
332 | } | 342 | } |
333 | out_unlock: | 343 | out_unlock: |
@@ -852,7 +862,7 @@ int xprt_prepare_transmit(struct rpc_task *task) | |||
852 | err = req->rq_reply_bytes_recvd; | 862 | err = req->rq_reply_bytes_recvd; |
853 | goto out_unlock; | 863 | goto out_unlock; |
854 | } | 864 | } |
855 | if (!xprt->ops->reserve_xprt(task)) | 865 | if (!xprt->ops->reserve_xprt(xprt, task)) |
856 | err = -EAGAIN; | 866 | err = -EAGAIN; |
857 | out_unlock: | 867 | out_unlock: |
858 | spin_unlock_bh(&xprt->transport_lock); | 868 | spin_unlock_bh(&xprt->transport_lock); |
@@ -928,28 +938,66 @@ void xprt_transmit(struct rpc_task *task) | |||
928 | spin_unlock_bh(&xprt->transport_lock); | 938 | spin_unlock_bh(&xprt->transport_lock); |
929 | } | 939 | } |
930 | 940 | ||
941 | static struct rpc_rqst *xprt_dynamic_alloc_slot(struct rpc_xprt *xprt, gfp_t gfp_flags) | ||
942 | { | ||
943 | struct rpc_rqst *req = ERR_PTR(-EAGAIN); | ||
944 | |||
945 | if (!atomic_add_unless(&xprt->num_reqs, 1, xprt->max_reqs)) | ||
946 | goto out; | ||
947 | req = kzalloc(sizeof(struct rpc_rqst), gfp_flags); | ||
948 | if (req != NULL) | ||
949 | goto out; | ||
950 | atomic_dec(&xprt->num_reqs); | ||
951 | req = ERR_PTR(-ENOMEM); | ||
952 | out: | ||
953 | return req; | ||
954 | } | ||
955 | |||
956 | static bool xprt_dynamic_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req) | ||
957 | { | ||
958 | if (atomic_add_unless(&xprt->num_reqs, -1, xprt->min_reqs)) { | ||
959 | kfree(req); | ||
960 | return true; | ||
961 | } | ||
962 | return false; | ||
963 | } | ||
964 | |||
931 | static void xprt_alloc_slot(struct rpc_task *task) | 965 | static void xprt_alloc_slot(struct rpc_task *task) |
932 | { | 966 | { |
933 | struct rpc_xprt *xprt = task->tk_xprt; | 967 | struct rpc_xprt *xprt = task->tk_xprt; |
968 | struct rpc_rqst *req; | ||
934 | 969 | ||
935 | task->tk_status = 0; | ||
936 | if (task->tk_rqstp) | ||
937 | return; | ||
938 | if (!list_empty(&xprt->free)) { | 970 | if (!list_empty(&xprt->free)) { |
939 | struct rpc_rqst *req = list_entry(xprt->free.next, struct rpc_rqst, rq_list); | 971 | req = list_entry(xprt->free.next, struct rpc_rqst, rq_list); |
940 | list_del_init(&req->rq_list); | 972 | list_del(&req->rq_list); |
941 | task->tk_rqstp = req; | 973 | goto out_init_req; |
942 | xprt_request_init(task, xprt); | 974 | } |
943 | return; | 975 | req = xprt_dynamic_alloc_slot(xprt, GFP_NOWAIT); |
976 | if (!IS_ERR(req)) | ||
977 | goto out_init_req; | ||
978 | switch (PTR_ERR(req)) { | ||
979 | case -ENOMEM: | ||
980 | rpc_delay(task, HZ >> 2); | ||
981 | dprintk("RPC: dynamic allocation of request slot " | ||
982 | "failed! Retrying\n"); | ||
983 | break; | ||
984 | case -EAGAIN: | ||
985 | rpc_sleep_on(&xprt->backlog, task, NULL); | ||
986 | dprintk("RPC: waiting for request slot\n"); | ||
944 | } | 987 | } |
945 | dprintk("RPC: waiting for request slot\n"); | ||
946 | task->tk_status = -EAGAIN; | 988 | task->tk_status = -EAGAIN; |
947 | task->tk_timeout = 0; | 989 | return; |
948 | rpc_sleep_on(&xprt->backlog, task, NULL); | 990 | out_init_req: |
991 | task->tk_status = 0; | ||
992 | task->tk_rqstp = req; | ||
993 | xprt_request_init(task, xprt); | ||
949 | } | 994 | } |
950 | 995 | ||
951 | static void xprt_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req) | 996 | static void xprt_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req) |
952 | { | 997 | { |
998 | if (xprt_dynamic_free_slot(xprt, req)) | ||
999 | return; | ||
1000 | |||
953 | memset(req, 0, sizeof(*req)); /* mark unused */ | 1001 | memset(req, 0, sizeof(*req)); /* mark unused */ |
954 | 1002 | ||
955 | spin_lock(&xprt->reserve_lock); | 1003 | spin_lock(&xprt->reserve_lock); |
@@ -958,25 +1006,49 @@ static void xprt_free_slot(struct rpc_xprt *xprt, struct rpc_rqst *req) | |||
958 | spin_unlock(&xprt->reserve_lock); | 1006 | spin_unlock(&xprt->reserve_lock); |
959 | } | 1007 | } |
960 | 1008 | ||
961 | struct rpc_xprt *xprt_alloc(struct net *net, int size, int max_req) | 1009 | static void xprt_free_all_slots(struct rpc_xprt *xprt) |
1010 | { | ||
1011 | struct rpc_rqst *req; | ||
1012 | while (!list_empty(&xprt->free)) { | ||
1013 | req = list_first_entry(&xprt->free, struct rpc_rqst, rq_list); | ||
1014 | list_del(&req->rq_list); | ||
1015 | kfree(req); | ||
1016 | } | ||
1017 | } | ||
1018 | |||
1019 | struct rpc_xprt *xprt_alloc(struct net *net, size_t size, | ||
1020 | unsigned int num_prealloc, | ||
1021 | unsigned int max_alloc) | ||
962 | { | 1022 | { |
963 | struct rpc_xprt *xprt; | 1023 | struct rpc_xprt *xprt; |
1024 | struct rpc_rqst *req; | ||
1025 | int i; | ||
964 | 1026 | ||
965 | xprt = kzalloc(size, GFP_KERNEL); | 1027 | xprt = kzalloc(size, GFP_KERNEL); |
966 | if (xprt == NULL) | 1028 | if (xprt == NULL) |
967 | goto out; | 1029 | goto out; |
968 | atomic_set(&xprt->count, 1); | ||
969 | 1030 | ||
970 | xprt->max_reqs = max_req; | 1031 | xprt_init(xprt, net); |
971 | xprt->slot = kcalloc(max_req, sizeof(struct rpc_rqst), GFP_KERNEL); | 1032 | |
972 | if (xprt->slot == NULL) | 1033 | for (i = 0; i < num_prealloc; i++) { |
1034 | req = kzalloc(sizeof(struct rpc_rqst), GFP_KERNEL); | ||
1035 | if (!req) | ||
1036 | break; | ||
1037 | list_add(&req->rq_list, &xprt->free); | ||
1038 | } | ||
1039 | if (i < num_prealloc) | ||
973 | goto out_free; | 1040 | goto out_free; |
1041 | if (max_alloc > num_prealloc) | ||
1042 | xprt->max_reqs = max_alloc; | ||
1043 | else | ||
1044 | xprt->max_reqs = num_prealloc; | ||
1045 | xprt->min_reqs = num_prealloc; | ||
1046 | atomic_set(&xprt->num_reqs, num_prealloc); | ||
974 | 1047 | ||
975 | xprt->xprt_net = get_net(net); | ||
976 | return xprt; | 1048 | return xprt; |
977 | 1049 | ||
978 | out_free: | 1050 | out_free: |
979 | kfree(xprt); | 1051 | xprt_free(xprt); |
980 | out: | 1052 | out: |
981 | return NULL; | 1053 | return NULL; |
982 | } | 1054 | } |
@@ -985,7 +1057,7 @@ EXPORT_SYMBOL_GPL(xprt_alloc); | |||
985 | void xprt_free(struct rpc_xprt *xprt) | 1057 | void xprt_free(struct rpc_xprt *xprt) |
986 | { | 1058 | { |
987 | put_net(xprt->xprt_net); | 1059 | put_net(xprt->xprt_net); |
988 | kfree(xprt->slot); | 1060 | xprt_free_all_slots(xprt); |
989 | kfree(xprt); | 1061 | kfree(xprt); |
990 | } | 1062 | } |
991 | EXPORT_SYMBOL_GPL(xprt_free); | 1063 | EXPORT_SYMBOL_GPL(xprt_free); |
@@ -1001,10 +1073,24 @@ void xprt_reserve(struct rpc_task *task) | |||
1001 | { | 1073 | { |
1002 | struct rpc_xprt *xprt = task->tk_xprt; | 1074 | struct rpc_xprt *xprt = task->tk_xprt; |
1003 | 1075 | ||
1004 | task->tk_status = -EIO; | 1076 | task->tk_status = 0; |
1077 | if (task->tk_rqstp != NULL) | ||
1078 | return; | ||
1079 | |||
1080 | /* Note: grabbing the xprt_lock_write() here is not strictly needed, | ||
1081 | * but ensures that we throttle new slot allocation if the transport | ||
1082 | * is congested (e.g. if reconnecting or if we're out of socket | ||
1083 | * write buffer space). | ||
1084 | */ | ||
1085 | task->tk_timeout = 0; | ||
1086 | task->tk_status = -EAGAIN; | ||
1087 | if (!xprt_lock_write(xprt, task)) | ||
1088 | return; | ||
1089 | |||
1005 | spin_lock(&xprt->reserve_lock); | 1090 | spin_lock(&xprt->reserve_lock); |
1006 | xprt_alloc_slot(task); | 1091 | xprt_alloc_slot(task); |
1007 | spin_unlock(&xprt->reserve_lock); | 1092 | spin_unlock(&xprt->reserve_lock); |
1093 | xprt_release_write(xprt, task); | ||
1008 | } | 1094 | } |
1009 | 1095 | ||
1010 | static inline __be32 xprt_alloc_xid(struct rpc_xprt *xprt) | 1096 | static inline __be32 xprt_alloc_xid(struct rpc_xprt *xprt) |
@@ -1021,6 +1107,7 @@ static void xprt_request_init(struct rpc_task *task, struct rpc_xprt *xprt) | |||
1021 | { | 1107 | { |
1022 | struct rpc_rqst *req = task->tk_rqstp; | 1108 | struct rpc_rqst *req = task->tk_rqstp; |
1023 | 1109 | ||
1110 | INIT_LIST_HEAD(&req->rq_list); | ||
1024 | req->rq_timeout = task->tk_client->cl_timeout->to_initval; | 1111 | req->rq_timeout = task->tk_client->cl_timeout->to_initval; |
1025 | req->rq_task = task; | 1112 | req->rq_task = task; |
1026 | req->rq_xprt = xprt; | 1113 | req->rq_xprt = xprt; |
@@ -1073,6 +1160,34 @@ void xprt_release(struct rpc_task *task) | |||
1073 | xprt_free_bc_request(req); | 1160 | xprt_free_bc_request(req); |
1074 | } | 1161 | } |
1075 | 1162 | ||
1163 | static void xprt_init(struct rpc_xprt *xprt, struct net *net) | ||
1164 | { | ||
1165 | atomic_set(&xprt->count, 1); | ||
1166 | |||
1167 | spin_lock_init(&xprt->transport_lock); | ||
1168 | spin_lock_init(&xprt->reserve_lock); | ||
1169 | |||
1170 | INIT_LIST_HEAD(&xprt->free); | ||
1171 | INIT_LIST_HEAD(&xprt->recv); | ||
1172 | #if defined(CONFIG_SUNRPC_BACKCHANNEL) | ||
1173 | spin_lock_init(&xprt->bc_pa_lock); | ||
1174 | INIT_LIST_HEAD(&xprt->bc_pa_list); | ||
1175 | #endif /* CONFIG_SUNRPC_BACKCHANNEL */ | ||
1176 | |||
1177 | xprt->last_used = jiffies; | ||
1178 | xprt->cwnd = RPC_INITCWND; | ||
1179 | xprt->bind_index = 0; | ||
1180 | |||
1181 | rpc_init_wait_queue(&xprt->binding, "xprt_binding"); | ||
1182 | rpc_init_wait_queue(&xprt->pending, "xprt_pending"); | ||
1183 | rpc_init_priority_wait_queue(&xprt->sending, "xprt_sending"); | ||
1184 | rpc_init_priority_wait_queue(&xprt->backlog, "xprt_backlog"); | ||
1185 | |||
1186 | xprt_init_xid(xprt); | ||
1187 | |||
1188 | xprt->xprt_net = get_net(net); | ||
1189 | } | ||
1190 | |||
1076 | /** | 1191 | /** |
1077 | * xprt_create_transport - create an RPC transport | 1192 | * xprt_create_transport - create an RPC transport |
1078 | * @args: rpc transport creation arguments | 1193 | * @args: rpc transport creation arguments |
@@ -1081,7 +1196,6 @@ void xprt_release(struct rpc_task *task) | |||
1081 | struct rpc_xprt *xprt_create_transport(struct xprt_create *args) | 1196 | struct rpc_xprt *xprt_create_transport(struct xprt_create *args) |
1082 | { | 1197 | { |
1083 | struct rpc_xprt *xprt; | 1198 | struct rpc_xprt *xprt; |
1084 | struct rpc_rqst *req; | ||
1085 | struct xprt_class *t; | 1199 | struct xprt_class *t; |
1086 | 1200 | ||
1087 | spin_lock(&xprt_list_lock); | 1201 | spin_lock(&xprt_list_lock); |
@@ -1100,46 +1214,17 @@ found: | |||
1100 | if (IS_ERR(xprt)) { | 1214 | if (IS_ERR(xprt)) { |
1101 | dprintk("RPC: xprt_create_transport: failed, %ld\n", | 1215 | dprintk("RPC: xprt_create_transport: failed, %ld\n", |
1102 | -PTR_ERR(xprt)); | 1216 | -PTR_ERR(xprt)); |
1103 | return xprt; | 1217 | goto out; |
1104 | } | 1218 | } |
1105 | if (test_and_set_bit(XPRT_INITIALIZED, &xprt->state)) | ||
1106 | /* ->setup returned a pre-initialized xprt: */ | ||
1107 | return xprt; | ||
1108 | |||
1109 | spin_lock_init(&xprt->transport_lock); | ||
1110 | spin_lock_init(&xprt->reserve_lock); | ||
1111 | |||
1112 | INIT_LIST_HEAD(&xprt->free); | ||
1113 | INIT_LIST_HEAD(&xprt->recv); | ||
1114 | #if defined(CONFIG_NFS_V4_1) | ||
1115 | spin_lock_init(&xprt->bc_pa_lock); | ||
1116 | INIT_LIST_HEAD(&xprt->bc_pa_list); | ||
1117 | #endif /* CONFIG_NFS_V4_1 */ | ||
1118 | |||
1119 | INIT_WORK(&xprt->task_cleanup, xprt_autoclose); | 1219 | INIT_WORK(&xprt->task_cleanup, xprt_autoclose); |
1120 | if (xprt_has_timer(xprt)) | 1220 | if (xprt_has_timer(xprt)) |
1121 | setup_timer(&xprt->timer, xprt_init_autodisconnect, | 1221 | setup_timer(&xprt->timer, xprt_init_autodisconnect, |
1122 | (unsigned long)xprt); | 1222 | (unsigned long)xprt); |
1123 | else | 1223 | else |
1124 | init_timer(&xprt->timer); | 1224 | init_timer(&xprt->timer); |
1125 | xprt->last_used = jiffies; | ||
1126 | xprt->cwnd = RPC_INITCWND; | ||
1127 | xprt->bind_index = 0; | ||
1128 | |||
1129 | rpc_init_wait_queue(&xprt->binding, "xprt_binding"); | ||
1130 | rpc_init_wait_queue(&xprt->pending, "xprt_pending"); | ||
1131 | rpc_init_wait_queue(&xprt->sending, "xprt_sending"); | ||
1132 | rpc_init_wait_queue(&xprt->resend, "xprt_resend"); | ||
1133 | rpc_init_priority_wait_queue(&xprt->backlog, "xprt_backlog"); | ||
1134 | |||
1135 | /* initialize free list */ | ||
1136 | for (req = &xprt->slot[xprt->max_reqs-1]; req >= &xprt->slot[0]; req--) | ||
1137 | list_add(&req->rq_list, &xprt->free); | ||
1138 | |||
1139 | xprt_init_xid(xprt); | ||
1140 | |||
1141 | dprintk("RPC: created transport %p with %u slots\n", xprt, | 1225 | dprintk("RPC: created transport %p with %u slots\n", xprt, |
1142 | xprt->max_reqs); | 1226 | xprt->max_reqs); |
1227 | out: | ||
1143 | return xprt; | 1228 | return xprt; |
1144 | } | 1229 | } |
1145 | 1230 | ||
@@ -1157,7 +1242,6 @@ static void xprt_destroy(struct rpc_xprt *xprt) | |||
1157 | rpc_destroy_wait_queue(&xprt->binding); | 1242 | rpc_destroy_wait_queue(&xprt->binding); |
1158 | rpc_destroy_wait_queue(&xprt->pending); | 1243 | rpc_destroy_wait_queue(&xprt->pending); |
1159 | rpc_destroy_wait_queue(&xprt->sending); | 1244 | rpc_destroy_wait_queue(&xprt->sending); |
1160 | rpc_destroy_wait_queue(&xprt->resend); | ||
1161 | rpc_destroy_wait_queue(&xprt->backlog); | 1245 | rpc_destroy_wait_queue(&xprt->backlog); |
1162 | cancel_work_sync(&xprt->task_cleanup); | 1246 | cancel_work_sync(&xprt->task_cleanup); |
1163 | /* | 1247 | /* |
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c index 0867070bb5c..b446e100286 100644 --- a/net/sunrpc/xprtrdma/transport.c +++ b/net/sunrpc/xprtrdma/transport.c | |||
@@ -283,6 +283,7 @@ xprt_setup_rdma(struct xprt_create *args) | |||
283 | } | 283 | } |
284 | 284 | ||
285 | xprt = xprt_alloc(args->net, sizeof(struct rpcrdma_xprt), | 285 | xprt = xprt_alloc(args->net, sizeof(struct rpcrdma_xprt), |
286 | xprt_rdma_slot_table_entries, | ||
286 | xprt_rdma_slot_table_entries); | 287 | xprt_rdma_slot_table_entries); |
287 | if (xprt == NULL) { | 288 | if (xprt == NULL) { |
288 | dprintk("RPC: %s: couldn't allocate rpcrdma_xprt\n", | 289 | dprintk("RPC: %s: couldn't allocate rpcrdma_xprt\n", |
@@ -452,9 +453,8 @@ xprt_rdma_connect(struct rpc_task *task) | |||
452 | } | 453 | } |
453 | 454 | ||
454 | static int | 455 | static int |
455 | xprt_rdma_reserve_xprt(struct rpc_task *task) | 456 | xprt_rdma_reserve_xprt(struct rpc_xprt *xprt, struct rpc_task *task) |
456 | { | 457 | { |
457 | struct rpc_xprt *xprt = task->tk_xprt; | ||
458 | struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt); | 458 | struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt); |
459 | int credits = atomic_read(&r_xprt->rx_buf.rb_credits); | 459 | int credits = atomic_read(&r_xprt->rx_buf.rb_credits); |
460 | 460 | ||
@@ -466,7 +466,7 @@ xprt_rdma_reserve_xprt(struct rpc_task *task) | |||
466 | BUG_ON(r_xprt->rx_buf.rb_cwndscale <= 0); | 466 | BUG_ON(r_xprt->rx_buf.rb_cwndscale <= 0); |
467 | } | 467 | } |
468 | xprt->cwnd = credits * r_xprt->rx_buf.rb_cwndscale; | 468 | xprt->cwnd = credits * r_xprt->rx_buf.rb_cwndscale; |
469 | return xprt_reserve_xprt_cong(task); | 469 | return xprt_reserve_xprt_cong(xprt, task); |
470 | } | 470 | } |
471 | 471 | ||
472 | /* | 472 | /* |
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h index cae761a8536..08c5d5a128f 100644 --- a/net/sunrpc/xprtrdma/xprt_rdma.h +++ b/net/sunrpc/xprtrdma/xprt_rdma.h | |||
@@ -42,7 +42,7 @@ | |||
42 | 42 | ||
43 | #include <linux/wait.h> /* wait_queue_head_t, etc */ | 43 | #include <linux/wait.h> /* wait_queue_head_t, etc */ |
44 | #include <linux/spinlock.h> /* spinlock_t, etc */ | 44 | #include <linux/spinlock.h> /* spinlock_t, etc */ |
45 | #include <asm/atomic.h> /* atomic_t, etc */ | 45 | #include <linux/atomic.h> /* atomic_t, etc */ |
46 | 46 | ||
47 | #include <rdma/rdma_cm.h> /* RDMA connection api */ | 47 | #include <rdma/rdma_cm.h> /* RDMA connection api */ |
48 | #include <rdma/ib_verbs.h> /* RDMA verbs api */ | 48 | #include <rdma/ib_verbs.h> /* RDMA verbs api */ |
@@ -109,7 +109,7 @@ struct rpcrdma_ep { | |||
109 | */ | 109 | */ |
110 | 110 | ||
111 | /* temporary static scatter/gather max */ | 111 | /* temporary static scatter/gather max */ |
112 | #define RPCRDMA_MAX_DATA_SEGS (8) /* max scatter/gather */ | 112 | #define RPCRDMA_MAX_DATA_SEGS (64) /* max scatter/gather */ |
113 | #define RPCRDMA_MAX_SEGS (RPCRDMA_MAX_DATA_SEGS + 2) /* head+tail = 2 */ | 113 | #define RPCRDMA_MAX_SEGS (RPCRDMA_MAX_DATA_SEGS + 2) /* head+tail = 2 */ |
114 | #define MAX_RPCRDMAHDR (\ | 114 | #define MAX_RPCRDMAHDR (\ |
115 | /* max supported RPC/RDMA header */ \ | 115 | /* max supported RPC/RDMA header */ \ |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 72abb735893..d7f97ef2659 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include <linux/sunrpc/svcsock.h> | 37 | #include <linux/sunrpc/svcsock.h> |
38 | #include <linux/sunrpc/xprtsock.h> | 38 | #include <linux/sunrpc/xprtsock.h> |
39 | #include <linux/file.h> | 39 | #include <linux/file.h> |
40 | #ifdef CONFIG_NFS_V4_1 | 40 | #ifdef CONFIG_SUNRPC_BACKCHANNEL |
41 | #include <linux/sunrpc/bc_xprt.h> | 41 | #include <linux/sunrpc/bc_xprt.h> |
42 | #endif | 42 | #endif |
43 | 43 | ||
@@ -54,7 +54,8 @@ static void xs_close(struct rpc_xprt *xprt); | |||
54 | * xprtsock tunables | 54 | * xprtsock tunables |
55 | */ | 55 | */ |
56 | unsigned int xprt_udp_slot_table_entries = RPC_DEF_SLOT_TABLE; | 56 | unsigned int xprt_udp_slot_table_entries = RPC_DEF_SLOT_TABLE; |
57 | unsigned int xprt_tcp_slot_table_entries = RPC_DEF_SLOT_TABLE; | 57 | unsigned int xprt_tcp_slot_table_entries = RPC_MIN_SLOT_TABLE; |
58 | unsigned int xprt_max_tcp_slot_table_entries = RPC_MAX_SLOT_TABLE; | ||
58 | 59 | ||
59 | unsigned int xprt_min_resvport = RPC_DEF_MIN_RESVPORT; | 60 | unsigned int xprt_min_resvport = RPC_DEF_MIN_RESVPORT; |
60 | unsigned int xprt_max_resvport = RPC_DEF_MAX_RESVPORT; | 61 | unsigned int xprt_max_resvport = RPC_DEF_MAX_RESVPORT; |
@@ -75,6 +76,7 @@ static unsigned int xs_tcp_fin_timeout __read_mostly = XS_TCP_LINGER_TO; | |||
75 | 76 | ||
76 | static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE; | 77 | static unsigned int min_slot_table_size = RPC_MIN_SLOT_TABLE; |
77 | static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE; | 78 | static unsigned int max_slot_table_size = RPC_MAX_SLOT_TABLE; |
79 | static unsigned int max_tcp_slot_table_limit = RPC_MAX_SLOT_TABLE_LIMIT; | ||
78 | static unsigned int xprt_min_resvport_limit = RPC_MIN_RESVPORT; | 80 | static unsigned int xprt_min_resvport_limit = RPC_MIN_RESVPORT; |
79 | static unsigned int xprt_max_resvport_limit = RPC_MAX_RESVPORT; | 81 | static unsigned int xprt_max_resvport_limit = RPC_MAX_RESVPORT; |
80 | 82 | ||
@@ -104,6 +106,15 @@ static ctl_table xs_tunables_table[] = { | |||
104 | .extra2 = &max_slot_table_size | 106 | .extra2 = &max_slot_table_size |
105 | }, | 107 | }, |
106 | { | 108 | { |
109 | .procname = "tcp_max_slot_table_entries", | ||
110 | .data = &xprt_max_tcp_slot_table_entries, | ||
111 | .maxlen = sizeof(unsigned int), | ||
112 | .mode = 0644, | ||
113 | .proc_handler = proc_dointvec_minmax, | ||
114 | .extra1 = &min_slot_table_size, | ||
115 | .extra2 = &max_tcp_slot_table_limit | ||
116 | }, | ||
117 | { | ||
107 | .procname = "min_resvport", | 118 | .procname = "min_resvport", |
108 | .data = &xprt_min_resvport, | 119 | .data = &xprt_min_resvport, |
109 | .maxlen = sizeof(unsigned int), | 120 | .maxlen = sizeof(unsigned int), |
@@ -755,6 +766,8 @@ static void xs_tcp_release_xprt(struct rpc_xprt *xprt, struct rpc_task *task) | |||
755 | if (task == NULL) | 766 | if (task == NULL) |
756 | goto out_release; | 767 | goto out_release; |
757 | req = task->tk_rqstp; | 768 | req = task->tk_rqstp; |
769 | if (req == NULL) | ||
770 | goto out_release; | ||
758 | if (req->rq_bytes_sent == 0) | 771 | if (req->rq_bytes_sent == 0) |
759 | goto out_release; | 772 | goto out_release; |
760 | if (req->rq_bytes_sent == req->rq_snd_buf.len) | 773 | if (req->rq_bytes_sent == req->rq_snd_buf.len) |
@@ -1236,7 +1249,7 @@ static inline int xs_tcp_read_reply(struct rpc_xprt *xprt, | |||
1236 | return 0; | 1249 | return 0; |
1237 | } | 1250 | } |
1238 | 1251 | ||
1239 | #if defined(CONFIG_NFS_V4_1) | 1252 | #if defined(CONFIG_SUNRPC_BACKCHANNEL) |
1240 | /* | 1253 | /* |
1241 | * Obtains an rpc_rqst previously allocated and invokes the common | 1254 | * Obtains an rpc_rqst previously allocated and invokes the common |
1242 | * tcp read code to read the data. The result is placed in the callback | 1255 | * tcp read code to read the data. The result is placed in the callback |
@@ -1299,7 +1312,7 @@ static inline int _xs_tcp_read_data(struct rpc_xprt *xprt, | |||
1299 | { | 1312 | { |
1300 | return xs_tcp_read_reply(xprt, desc); | 1313 | return xs_tcp_read_reply(xprt, desc); |
1301 | } | 1314 | } |
1302 | #endif /* CONFIG_NFS_V4_1 */ | 1315 | #endif /* CONFIG_SUNRPC_BACKCHANNEL */ |
1303 | 1316 | ||
1304 | /* | 1317 | /* |
1305 | * Read data off the transport. This can be either an RPC_CALL or an | 1318 | * Read data off the transport. This can be either an RPC_CALL or an |
@@ -2489,7 +2502,8 @@ static int xs_init_anyaddr(const int family, struct sockaddr *sap) | |||
2489 | } | 2502 | } |
2490 | 2503 | ||
2491 | static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args, | 2504 | static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args, |
2492 | unsigned int slot_table_size) | 2505 | unsigned int slot_table_size, |
2506 | unsigned int max_slot_table_size) | ||
2493 | { | 2507 | { |
2494 | struct rpc_xprt *xprt; | 2508 | struct rpc_xprt *xprt; |
2495 | struct sock_xprt *new; | 2509 | struct sock_xprt *new; |
@@ -2499,7 +2513,8 @@ static struct rpc_xprt *xs_setup_xprt(struct xprt_create *args, | |||
2499 | return ERR_PTR(-EBADF); | 2513 | return ERR_PTR(-EBADF); |
2500 | } | 2514 | } |
2501 | 2515 | ||
2502 | xprt = xprt_alloc(args->net, sizeof(*new), slot_table_size); | 2516 | xprt = xprt_alloc(args->net, sizeof(*new), slot_table_size, |
2517 | max_slot_table_size); | ||
2503 | if (xprt == NULL) { | 2518 | if (xprt == NULL) { |
2504 | dprintk("RPC: xs_setup_xprt: couldn't allocate " | 2519 | dprintk("RPC: xs_setup_xprt: couldn't allocate " |
2505 | "rpc_xprt\n"); | 2520 | "rpc_xprt\n"); |
@@ -2541,7 +2556,8 @@ static struct rpc_xprt *xs_setup_local(struct xprt_create *args) | |||
2541 | struct rpc_xprt *xprt; | 2556 | struct rpc_xprt *xprt; |
2542 | struct rpc_xprt *ret; | 2557 | struct rpc_xprt *ret; |
2543 | 2558 | ||
2544 | xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries); | 2559 | xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries, |
2560 | xprt_max_tcp_slot_table_entries); | ||
2545 | if (IS_ERR(xprt)) | 2561 | if (IS_ERR(xprt)) |
2546 | return xprt; | 2562 | return xprt; |
2547 | transport = container_of(xprt, struct sock_xprt, xprt); | 2563 | transport = container_of(xprt, struct sock_xprt, xprt); |
@@ -2605,7 +2621,8 @@ static struct rpc_xprt *xs_setup_udp(struct xprt_create *args) | |||
2605 | struct sock_xprt *transport; | 2621 | struct sock_xprt *transport; |
2606 | struct rpc_xprt *ret; | 2622 | struct rpc_xprt *ret; |
2607 | 2623 | ||
2608 | xprt = xs_setup_xprt(args, xprt_udp_slot_table_entries); | 2624 | xprt = xs_setup_xprt(args, xprt_udp_slot_table_entries, |
2625 | xprt_udp_slot_table_entries); | ||
2609 | if (IS_ERR(xprt)) | 2626 | if (IS_ERR(xprt)) |
2610 | return xprt; | 2627 | return xprt; |
2611 | transport = container_of(xprt, struct sock_xprt, xprt); | 2628 | transport = container_of(xprt, struct sock_xprt, xprt); |
@@ -2681,7 +2698,8 @@ static struct rpc_xprt *xs_setup_tcp(struct xprt_create *args) | |||
2681 | struct sock_xprt *transport; | 2698 | struct sock_xprt *transport; |
2682 | struct rpc_xprt *ret; | 2699 | struct rpc_xprt *ret; |
2683 | 2700 | ||
2684 | xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries); | 2701 | xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries, |
2702 | xprt_max_tcp_slot_table_entries); | ||
2685 | if (IS_ERR(xprt)) | 2703 | if (IS_ERR(xprt)) |
2686 | return xprt; | 2704 | return xprt; |
2687 | transport = container_of(xprt, struct sock_xprt, xprt); | 2705 | transport = container_of(xprt, struct sock_xprt, xprt); |
@@ -2760,7 +2778,8 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args) | |||
2760 | */ | 2778 | */ |
2761 | return args->bc_xprt->xpt_bc_xprt; | 2779 | return args->bc_xprt->xpt_bc_xprt; |
2762 | } | 2780 | } |
2763 | xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries); | 2781 | xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries, |
2782 | xprt_tcp_slot_table_entries); | ||
2764 | if (IS_ERR(xprt)) | 2783 | if (IS_ERR(xprt)) |
2765 | return xprt; | 2784 | return xprt; |
2766 | transport = container_of(xprt, struct sock_xprt, xprt); | 2785 | transport = container_of(xprt, struct sock_xprt, xprt); |
@@ -2947,8 +2966,26 @@ static struct kernel_param_ops param_ops_slot_table_size = { | |||
2947 | #define param_check_slot_table_size(name, p) \ | 2966 | #define param_check_slot_table_size(name, p) \ |
2948 | __param_check(name, p, unsigned int); | 2967 | __param_check(name, p, unsigned int); |
2949 | 2968 | ||
2969 | static int param_set_max_slot_table_size(const char *val, | ||
2970 | const struct kernel_param *kp) | ||
2971 | { | ||
2972 | return param_set_uint_minmax(val, kp, | ||
2973 | RPC_MIN_SLOT_TABLE, | ||
2974 | RPC_MAX_SLOT_TABLE_LIMIT); | ||
2975 | } | ||
2976 | |||
2977 | static struct kernel_param_ops param_ops_max_slot_table_size = { | ||
2978 | .set = param_set_max_slot_table_size, | ||
2979 | .get = param_get_uint, | ||
2980 | }; | ||
2981 | |||
2982 | #define param_check_max_slot_table_size(name, p) \ | ||
2983 | __param_check(name, p, unsigned int); | ||
2984 | |||
2950 | module_param_named(tcp_slot_table_entries, xprt_tcp_slot_table_entries, | 2985 | module_param_named(tcp_slot_table_entries, xprt_tcp_slot_table_entries, |
2951 | slot_table_size, 0644); | 2986 | slot_table_size, 0644); |
2987 | module_param_named(tcp_max_slot_table_entries, xprt_max_tcp_slot_table_entries, | ||
2988 | max_slot_table_size, 0644); | ||
2952 | module_param_named(udp_slot_table_entries, xprt_udp_slot_table_entries, | 2989 | module_param_named(udp_slot_table_entries, xprt_udp_slot_table_entries, |
2953 | slot_table_size, 0644); | 2990 | slot_table_size, 0644); |
2954 | 2991 | ||
diff --git a/net/tipc/core.h b/net/tipc/core.h index d234a98a460..2761af36d14 100644 --- a/net/tipc/core.h +++ b/net/tipc/core.h | |||
@@ -47,7 +47,7 @@ | |||
47 | #include <linux/string.h> | 47 | #include <linux/string.h> |
48 | #include <asm/uaccess.h> | 48 | #include <asm/uaccess.h> |
49 | #include <linux/interrupt.h> | 49 | #include <linux/interrupt.h> |
50 | #include <asm/atomic.h> | 50 | #include <linux/atomic.h> |
51 | #include <asm/hardirq.h> | 51 | #include <asm/hardirq.h> |
52 | #include <linux/netdevice.h> | 52 | #include <linux/netdevice.h> |
53 | #include <linux/in.h> | 53 | #include <linux/in.h> |
diff --git a/net/wireless/core.c b/net/wireless/core.c index 880dbe2e6f9..645437cfc46 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -488,6 +488,10 @@ int wiphy_register(struct wiphy *wiphy) | |||
488 | int i; | 488 | int i; |
489 | u16 ifmodes = wiphy->interface_modes; | 489 | u16 ifmodes = wiphy->interface_modes; |
490 | 490 | ||
491 | if (WARN_ON((wiphy->wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) && | ||
492 | !(wiphy->wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY))) | ||
493 | return -EINVAL; | ||
494 | |||
491 | if (WARN_ON(wiphy->addresses && !wiphy->n_addresses)) | 495 | if (WARN_ON(wiphy->addresses && !wiphy->n_addresses)) |
492 | return -EINVAL; | 496 | return -EINVAL; |
493 | 497 | ||
@@ -918,7 +922,8 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, | |||
918 | * Configure power management to the driver here so that its | 922 | * Configure power management to the driver here so that its |
919 | * correctly set also after interface type changes etc. | 923 | * correctly set also after interface type changes etc. |
920 | */ | 924 | */ |
921 | if (wdev->iftype == NL80211_IFTYPE_STATION && | 925 | if ((wdev->iftype == NL80211_IFTYPE_STATION || |
926 | wdev->iftype == NL80211_IFTYPE_P2P_CLIENT) && | ||
922 | rdev->ops->set_power_mgmt) | 927 | rdev->ops->set_power_mgmt) |
923 | if (rdev->ops->set_power_mgmt(wdev->wiphy, dev, | 928 | if (rdev->ops->set_power_mgmt(wdev->wiphy, dev, |
924 | wdev->ps, | 929 | wdev->ps, |
diff --git a/net/wireless/core.h b/net/wireless/core.h index a570ff9214e..8672e028022 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -447,6 +447,10 @@ int cfg80211_set_freq(struct cfg80211_registered_device *rdev, | |||
447 | 447 | ||
448 | u16 cfg80211_calculate_bitrate(struct rate_info *rate); | 448 | u16 cfg80211_calculate_bitrate(struct rate_info *rate); |
449 | 449 | ||
450 | int ieee80211_get_ratemask(struct ieee80211_supported_band *sband, | ||
451 | const u8 *rates, unsigned int n_rates, | ||
452 | u32 *mask); | ||
453 | |||
450 | int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, | 454 | int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev, |
451 | u32 beacon_int); | 455 | u32 beacon_int); |
452 | 456 | ||
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 6a82c898f83..e83e7fee3bc 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -177,6 +177,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = { | |||
177 | [NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 }, | 177 | [NL80211_ATTR_STA_PLINK_STATE] = { .type = NLA_U8 }, |
178 | [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 }, | 178 | [NL80211_ATTR_SCHED_SCAN_INTERVAL] = { .type = NLA_U32 }, |
179 | [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED }, | 179 | [NL80211_ATTR_REKEY_DATA] = { .type = NLA_NESTED }, |
180 | [NL80211_ATTR_SCAN_SUPP_RATES] = { .type = NLA_NESTED }, | ||
180 | }; | 181 | }; |
181 | 182 | ||
182 | /* policy for the key attributes */ | 183 | /* policy for the key attributes */ |
@@ -205,6 +206,10 @@ nl80211_wowlan_policy[NUM_NL80211_WOWLAN_TRIG] = { | |||
205 | [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG }, | 206 | [NL80211_WOWLAN_TRIG_DISCONNECT] = { .type = NLA_FLAG }, |
206 | [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG }, | 207 | [NL80211_WOWLAN_TRIG_MAGIC_PKT] = { .type = NLA_FLAG }, |
207 | [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED }, | 208 | [NL80211_WOWLAN_TRIG_PKT_PATTERN] = { .type = NLA_NESTED }, |
209 | [NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE] = { .type = NLA_FLAG }, | ||
210 | [NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST] = { .type = NLA_FLAG }, | ||
211 | [NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE] = { .type = NLA_FLAG }, | ||
212 | [NL80211_WOWLAN_TRIG_RFKILL_RELEASE] = { .type = NLA_FLAG }, | ||
208 | }; | 213 | }; |
209 | 214 | ||
210 | /* policy for GTK rekey offload attributes */ | 215 | /* policy for GTK rekey offload attributes */ |
@@ -692,8 +697,12 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, | |||
692 | dev->wiphy.coverage_class); | 697 | dev->wiphy.coverage_class); |
693 | NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS, | 698 | NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS, |
694 | dev->wiphy.max_scan_ssids); | 699 | dev->wiphy.max_scan_ssids); |
700 | NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS, | ||
701 | dev->wiphy.max_sched_scan_ssids); | ||
695 | NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN, | 702 | NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCAN_IE_LEN, |
696 | dev->wiphy.max_scan_ie_len); | 703 | dev->wiphy.max_scan_ie_len); |
704 | NLA_PUT_U16(msg, NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN, | ||
705 | dev->wiphy.max_sched_scan_ie_len); | ||
697 | 706 | ||
698 | if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) | 707 | if (dev->wiphy.flags & WIPHY_FLAG_IBSS_RSN) |
699 | NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN); | 708 | NLA_PUT_FLAG(msg, NL80211_ATTR_SUPPORT_IBSS_RSN); |
@@ -929,6 +938,16 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, | |||
929 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT); | 938 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT); |
930 | if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_MAGIC_PKT) | 939 | if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_MAGIC_PKT) |
931 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT); | 940 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT); |
941 | if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_SUPPORTS_GTK_REKEY) | ||
942 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED); | ||
943 | if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) | ||
944 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE); | ||
945 | if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ) | ||
946 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST); | ||
947 | if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_4WAY_HANDSHAKE) | ||
948 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE); | ||
949 | if (dev->wiphy.wowlan.flags & WIPHY_WOWLAN_RFKILL_RELEASE) | ||
950 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE); | ||
932 | if (dev->wiphy.wowlan.n_patterns) { | 951 | if (dev->wiphy.wowlan.n_patterns) { |
933 | struct nl80211_wowlan_pattern_support pat = { | 952 | struct nl80211_wowlan_pattern_support pat = { |
934 | .max_patterns = dev->wiphy.wowlan.n_patterns, | 953 | .max_patterns = dev->wiphy.wowlan.n_patterns, |
@@ -3306,7 +3325,6 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) | |||
3306 | struct nlattr *attr; | 3325 | struct nlattr *attr; |
3307 | struct wiphy *wiphy; | 3326 | struct wiphy *wiphy; |
3308 | int err, tmp, n_ssids = 0, n_channels, i; | 3327 | int err, tmp, n_ssids = 0, n_channels, i; |
3309 | enum ieee80211_band band; | ||
3310 | size_t ie_len; | 3328 | size_t ie_len; |
3311 | 3329 | ||
3312 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) | 3330 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) |
@@ -3326,6 +3344,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) | |||
3326 | if (!n_channels) | 3344 | if (!n_channels) |
3327 | return -EINVAL; | 3345 | return -EINVAL; |
3328 | } else { | 3346 | } else { |
3347 | enum ieee80211_band band; | ||
3329 | n_channels = 0; | 3348 | n_channels = 0; |
3330 | 3349 | ||
3331 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) | 3350 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) |
@@ -3386,6 +3405,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) | |||
3386 | i++; | 3405 | i++; |
3387 | } | 3406 | } |
3388 | } else { | 3407 | } else { |
3408 | enum ieee80211_band band; | ||
3409 | |||
3389 | /* all channels */ | 3410 | /* all channels */ |
3390 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 3411 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
3391 | int j; | 3412 | int j; |
@@ -3432,6 +3453,30 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) | |||
3432 | request->ie_len); | 3453 | request->ie_len); |
3433 | } | 3454 | } |
3434 | 3455 | ||
3456 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) | ||
3457 | if (wiphy->bands[i]) | ||
3458 | request->rates[i] = | ||
3459 | (1 << wiphy->bands[i]->n_bitrates) - 1; | ||
3460 | |||
3461 | if (info->attrs[NL80211_ATTR_SCAN_SUPP_RATES]) { | ||
3462 | nla_for_each_nested(attr, | ||
3463 | info->attrs[NL80211_ATTR_SCAN_SUPP_RATES], | ||
3464 | tmp) { | ||
3465 | enum ieee80211_band band = nla_type(attr); | ||
3466 | |||
3467 | if (band < 0 || band >= IEEE80211_NUM_BANDS) { | ||
3468 | err = -EINVAL; | ||
3469 | goto out_free; | ||
3470 | } | ||
3471 | err = ieee80211_get_ratemask(wiphy->bands[band], | ||
3472 | nla_data(attr), | ||
3473 | nla_len(attr), | ||
3474 | &request->rates[band]); | ||
3475 | if (err) | ||
3476 | goto out_free; | ||
3477 | } | ||
3478 | } | ||
3479 | |||
3435 | request->dev = dev; | 3480 | request->dev = dev; |
3436 | request->wiphy = &rdev->wiphy; | 3481 | request->wiphy = &rdev->wiphy; |
3437 | 3482 | ||
@@ -3497,7 +3542,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, | |||
3497 | tmp) | 3542 | tmp) |
3498 | n_ssids++; | 3543 | n_ssids++; |
3499 | 3544 | ||
3500 | if (n_ssids > wiphy->max_scan_ssids) | 3545 | if (n_ssids > wiphy->max_sched_scan_ssids) |
3501 | return -EINVAL; | 3546 | return -EINVAL; |
3502 | 3547 | ||
3503 | if (info->attrs[NL80211_ATTR_IE]) | 3548 | if (info->attrs[NL80211_ATTR_IE]) |
@@ -3505,7 +3550,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, | |||
3505 | else | 3550 | else |
3506 | ie_len = 0; | 3551 | ie_len = 0; |
3507 | 3552 | ||
3508 | if (ie_len > wiphy->max_scan_ie_len) | 3553 | if (ie_len > wiphy->max_sched_scan_ie_len) |
3509 | return -EINVAL; | 3554 | return -EINVAL; |
3510 | 3555 | ||
3511 | mutex_lock(&rdev->sched_scan_mtx); | 3556 | mutex_lock(&rdev->sched_scan_mtx); |
@@ -4318,25 +4363,12 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info) | |||
4318 | nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); | 4363 | nla_len(info->attrs[NL80211_ATTR_BSS_BASIC_RATES]); |
4319 | struct ieee80211_supported_band *sband = | 4364 | struct ieee80211_supported_band *sband = |
4320 | wiphy->bands[ibss.channel->band]; | 4365 | wiphy->bands[ibss.channel->band]; |
4321 | int i, j; | 4366 | int err; |
4322 | 4367 | ||
4323 | if (n_rates == 0) | 4368 | err = ieee80211_get_ratemask(sband, rates, n_rates, |
4324 | return -EINVAL; | 4369 | &ibss.basic_rates); |
4325 | 4370 | if (err) | |
4326 | for (i = 0; i < n_rates; i++) { | 4371 | return err; |
4327 | int rate = (rates[i] & 0x7f) * 5; | ||
4328 | bool found = false; | ||
4329 | |||
4330 | for (j = 0; j < sband->n_bitrates; j++) { | ||
4331 | if (sband->bitrates[j].bitrate == rate) { | ||
4332 | found = true; | ||
4333 | ibss.basic_rates |= BIT(j); | ||
4334 | break; | ||
4335 | } | ||
4336 | } | ||
4337 | if (!found) | ||
4338 | return -EINVAL; | ||
4339 | } | ||
4340 | } | 4372 | } |
4341 | 4373 | ||
4342 | if (info->attrs[NL80211_ATTR_MCAST_RATE] && | 4374 | if (info->attrs[NL80211_ATTR_MCAST_RATE] && |
@@ -5272,6 +5304,14 @@ static int nl80211_get_wowlan(struct sk_buff *skb, struct genl_info *info) | |||
5272 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT); | 5304 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_DISCONNECT); |
5273 | if (rdev->wowlan->magic_pkt) | 5305 | if (rdev->wowlan->magic_pkt) |
5274 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT); | 5306 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_MAGIC_PKT); |
5307 | if (rdev->wowlan->gtk_rekey_failure) | ||
5308 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE); | ||
5309 | if (rdev->wowlan->eap_identity_req) | ||
5310 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST); | ||
5311 | if (rdev->wowlan->four_way_handshake) | ||
5312 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE); | ||
5313 | if (rdev->wowlan->rfkill_release) | ||
5314 | NLA_PUT_FLAG(msg, NL80211_WOWLAN_TRIG_RFKILL_RELEASE); | ||
5275 | if (rdev->wowlan->n_patterns) { | 5315 | if (rdev->wowlan->n_patterns) { |
5276 | struct nlattr *nl_pats, *nl_pat; | 5316 | struct nlattr *nl_pats, *nl_pat; |
5277 | int i, pat_len; | 5317 | int i, pat_len; |
@@ -5348,6 +5388,33 @@ static int nl80211_set_wowlan(struct sk_buff *skb, struct genl_info *info) | |||
5348 | new_triggers.magic_pkt = true; | 5388 | new_triggers.magic_pkt = true; |
5349 | } | 5389 | } |
5350 | 5390 | ||
5391 | if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_SUPPORTED]) | ||
5392 | return -EINVAL; | ||
5393 | |||
5394 | if (tb[NL80211_WOWLAN_TRIG_GTK_REKEY_FAILURE]) { | ||
5395 | if (!(wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE)) | ||
5396 | return -EINVAL; | ||
5397 | new_triggers.gtk_rekey_failure = true; | ||
5398 | } | ||
5399 | |||
5400 | if (tb[NL80211_WOWLAN_TRIG_EAP_IDENT_REQUEST]) { | ||
5401 | if (!(wowlan->flags & WIPHY_WOWLAN_EAP_IDENTITY_REQ)) | ||
5402 | return -EINVAL; | ||
5403 | new_triggers.eap_identity_req = true; | ||
5404 | } | ||
5405 | |||
5406 | if (tb[NL80211_WOWLAN_TRIG_4WAY_HANDSHAKE]) { | ||
5407 | if (!(wowlan->flags & WIPHY_WOWLAN_4WAY_HANDSHAKE)) | ||
5408 | return -EINVAL; | ||
5409 | new_triggers.four_way_handshake = true; | ||
5410 | } | ||
5411 | |||
5412 | if (tb[NL80211_WOWLAN_TRIG_RFKILL_RELEASE]) { | ||
5413 | if (!(wowlan->flags & WIPHY_WOWLAN_RFKILL_RELEASE)) | ||
5414 | return -EINVAL; | ||
5415 | new_triggers.rfkill_release = true; | ||
5416 | } | ||
5417 | |||
5351 | if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) { | 5418 | if (tb[NL80211_WOWLAN_TRIG_PKT_PATTERN]) { |
5352 | struct nlattr *pat; | 5419 | struct nlattr *pat; |
5353 | int n_patterns = 0; | 5420 | int n_patterns = 0; |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 1ad0f39fe09..02751dbc5a9 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -903,7 +903,7 @@ static bool ignore_reg_update(struct wiphy *wiphy, | |||
903 | initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE && | 903 | initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE && |
904 | !is_world_regdom(last_request->alpha2)) { | 904 | !is_world_regdom(last_request->alpha2)) { |
905 | REG_DBG_PRINT("Ignoring regulatory request %s " | 905 | REG_DBG_PRINT("Ignoring regulatory request %s " |
906 | "since the driver requires its own regulaotry " | 906 | "since the driver requires its own regulatory " |
907 | "domain to be set first", | 907 | "domain to be set first", |
908 | reg_initiator_name(initiator)); | 908 | reg_initiator_name(initiator)); |
909 | return true; | 909 | return true; |
@@ -1125,12 +1125,13 @@ void wiphy_update_regulatory(struct wiphy *wiphy, | |||
1125 | enum ieee80211_band band; | 1125 | enum ieee80211_band band; |
1126 | 1126 | ||
1127 | if (ignore_reg_update(wiphy, initiator)) | 1127 | if (ignore_reg_update(wiphy, initiator)) |
1128 | goto out; | 1128 | return; |
1129 | |||
1129 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 1130 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
1130 | if (wiphy->bands[band]) | 1131 | if (wiphy->bands[band]) |
1131 | handle_band(wiphy, band, initiator); | 1132 | handle_band(wiphy, band, initiator); |
1132 | } | 1133 | } |
1133 | out: | 1134 | |
1134 | reg_process_beacons(wiphy); | 1135 | reg_process_beacons(wiphy); |
1135 | reg_process_ht_flags(wiphy); | 1136 | reg_process_ht_flags(wiphy); |
1136 | if (wiphy->reg_notifier) | 1137 | if (wiphy->reg_notifier) |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 1c4672e3514..2936cb80915 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -862,6 +862,10 @@ int cfg80211_wext_siwscan(struct net_device *dev, | |||
862 | creq->n_ssids = 0; | 862 | creq->n_ssids = 0; |
863 | } | 863 | } |
864 | 864 | ||
865 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) | ||
866 | if (wiphy->bands[i]) | ||
867 | creq->rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1; | ||
868 | |||
865 | rdev->scan_req = creq; | 869 | rdev->scan_req = creq; |
866 | err = rdev->ops->scan(wiphy, dev, creq); | 870 | err = rdev->ops->scan(wiphy, dev, creq); |
867 | if (err) { | 871 | if (err) { |
diff --git a/net/wireless/util.c b/net/wireless/util.c index 4d7b83fbc32..be75a3a0424 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -1006,3 +1006,41 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev, | |||
1006 | 1006 | ||
1007 | return -EBUSY; | 1007 | return -EBUSY; |
1008 | } | 1008 | } |
1009 | |||
1010 | int ieee80211_get_ratemask(struct ieee80211_supported_band *sband, | ||
1011 | const u8 *rates, unsigned int n_rates, | ||
1012 | u32 *mask) | ||
1013 | { | ||
1014 | int i, j; | ||
1015 | |||
1016 | if (!sband) | ||
1017 | return -EINVAL; | ||
1018 | |||
1019 | if (n_rates == 0 || n_rates > NL80211_MAX_SUPP_RATES) | ||
1020 | return -EINVAL; | ||
1021 | |||
1022 | *mask = 0; | ||
1023 | |||
1024 | for (i = 0; i < n_rates; i++) { | ||
1025 | int rate = (rates[i] & 0x7f) * 5; | ||
1026 | bool found = false; | ||
1027 | |||
1028 | for (j = 0; j < sband->n_bitrates; j++) { | ||
1029 | if (sband->bitrates[j].bitrate == rate) { | ||
1030 | found = true; | ||
1031 | *mask |= BIT(j); | ||
1032 | break; | ||
1033 | } | ||
1034 | } | ||
1035 | if (!found) | ||
1036 | return -EINVAL; | ||
1037 | } | ||
1038 | |||
1039 | /* | ||
1040 | * mask must have at least one bit set here since we | ||
1041 | * didn't accept a 0-length rates array nor allowed | ||
1042 | * entries in the array that didn't exist | ||
1043 | */ | ||
1044 | |||
1045 | return 0; | ||
1046 | } | ||
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c index 58064d9e565..791ab2e77f3 100644 --- a/net/xfrm/xfrm_algo.c +++ b/net/xfrm/xfrm_algo.c | |||
@@ -462,8 +462,8 @@ static struct xfrm_algo_desc ealg_list[] = { | |||
462 | .desc = { | 462 | .desc = { |
463 | .sadb_alg_id = SADB_X_EALG_AESCTR, | 463 | .sadb_alg_id = SADB_X_EALG_AESCTR, |
464 | .sadb_alg_ivlen = 8, | 464 | .sadb_alg_ivlen = 8, |
465 | .sadb_alg_minbits = 128, | 465 | .sadb_alg_minbits = 160, |
466 | .sadb_alg_maxbits = 256 | 466 | .sadb_alg_maxbits = 288 |
467 | } | 467 | } |
468 | }, | 468 | }, |
469 | }; | 469 | }; |