diff options
Diffstat (limited to 'net')
127 files changed, 1172 insertions, 526 deletions
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 934e221c1d07..9d40a071d038 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 fc63526d8695..f41f02656ff4 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 2252c2085dac..52cfd0c3ea71 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); |
diff --git a/net/atm/clip.c b/net/atm/clip.c index 4bc8c67ecb14..852394072fa1 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 22b963d06a10..14ff9fe39989 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 ba48daa68c1f..215c9fad7cdf 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 be3afdefec58..0d020de8d233 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 8c100c9dae28..d4f5dff7c955 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 e0dfbc151dd7..68def3b7fb49 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 1bacca4cb676..2cdf0070419f 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
| @@ -388,7 +388,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) | |||
| 388 | br_ifinfo_notify(RTM_NEWLINK, p); | 388 | br_ifinfo_notify(RTM_NEWLINK, p); |
| 389 | 389 | ||
| 390 | if (changed_addr) | 390 | if (changed_addr) |
| 391 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); | 391 | call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev); |
| 392 | 392 | ||
| 393 | dev_set_mtu(br->dev, br_min_mtu(br)); | 393 | dev_set_mtu(br->dev, br_min_mtu(br)); |
| 394 | 394 | ||
| @@ -417,6 +417,7 @@ put_back: | |||
| 417 | int br_del_if(struct net_bridge *br, struct net_device *dev) | 417 | int br_del_if(struct net_bridge *br, struct net_device *dev) |
| 418 | { | 418 | { |
| 419 | struct net_bridge_port *p; | 419 | struct net_bridge_port *p; |
| 420 | bool changed_addr; | ||
| 420 | 421 | ||
| 421 | p = br_port_get_rtnl(dev); | 422 | p = br_port_get_rtnl(dev); |
| 422 | if (!p || p->br != br) | 423 | if (!p || p->br != br) |
| @@ -425,9 +426,12 @@ int br_del_if(struct net_bridge *br, struct net_device *dev) | |||
| 425 | del_nbp(p); | 426 | del_nbp(p); |
| 426 | 427 | ||
| 427 | spin_lock_bh(&br->lock); | 428 | spin_lock_bh(&br->lock); |
| 428 | br_stp_recalculate_bridge_id(br); | 429 | changed_addr = br_stp_recalculate_bridge_id(br); |
| 429 | spin_unlock_bh(&br->lock); | 430 | spin_unlock_bh(&br->lock); |
| 430 | 431 | ||
| 432 | if (changed_addr) | ||
| 433 | call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev); | ||
| 434 | |||
| 431 | netdev_update_features(br->dev); | 435 | netdev_update_features(br->dev); |
| 432 | 436 | ||
| 433 | return 0; | 437 | return 0; |
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 6814083a92f4..5b1ed1ba9aa7 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 6545ee9591d1..a76b62135558 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 54578f274d85..78cc364997d9 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 642ef47a867e..05ed9bc7e426 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 bb4383e84de9..ad0a3f7cf6cc 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 289646ec9b7b..e16aade51ae0 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 6f615b8192f4..10eda3cd1d71 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 3e965140051e..58de2a0f9975 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 26377e96fa1c..bf2a333ca7c7 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 2b5ca1a0054d..5864cc491369 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 78b55f49de7c..c340e2e0765b 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 7330c2757c0c..ce310eee708d 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 8a04dd22cf77..0d357b1c4e57 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 9444c5cb4137..17d67b579beb 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 990703b8863b..bf32c33cad3b 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 a7b342131869..357bd4ee4baa 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 f76079cd750c..e35a6fbb8110 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 4c1ef026d695..811b53fb330e 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 000000000000..45329d7c9dd9 --- /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 2beda824636e..27002dffe7ed 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 8c36adfd1919..332639b56f4d 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 8dc4348774a5..b74f76117dcf 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 2bd8e53d7774..9e885f180b60 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 0dc3fe61085b..7f0eb087dc11 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 cd0354e9bdb3..a9a62f225a6b 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 09825711d58a..67f691bd4acf 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 5cffb63f481a..27997d35ebd3 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 2b3c23c287cd..2c2a98e402e7 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 37b3c188d8b3..bc19bd06dd00 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 9dbe10875fbd..dbfc21de3479 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 f1d27f6c9351..283c0a26e03f 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 3c0369a3a663..984ec656b03b 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 e38213817d0a..86f13c67ea85 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 ccaaa851ab42..8c6563361ab5 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 ab0c9efd1efa..8905e92f896a 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 aae2bd8cd924..58e879157976 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 2e97e3ec1eb7..929b27bdeb79 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 3e61faf23a9a..f52d41ea0690 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 08526786dc39..61714bd52925 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 33137307d52a..075212e41b83 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 92bb9434b338..3bc5c8f7c71b 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 955b8e65b69e..1c12b8ec849d 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 a06c53c14d84..f012ebd87b43 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 16560336eb72..9ef1831746ef 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 b53197233709..73f1a00a96af 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 54a4678955bf..320d91d20ad7 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 32e5339db0c8..4c882cf4e8a1 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 36c2842a86b2..0bc98886c383 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/route.c b/net/ipv6/route.c index e8987da06667..9e69eb0ec6dd 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/syncookies.c b/net/ipv6/syncookies.c index 89d5bf806222..ac838965ff34 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 78aa53492b3e..d1fb63f4aeb7 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 f2b713847b45..075a3808aa40 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> |
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index ed8a2335442f..ad4ac2601a56 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 a8193f52c13c..d2726a74597d 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 39a21d0c61c4..f42cd0915966 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 ebadb9ac9a7e..fd1aaf2a4a6c 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 bfc36e904764..3d1b091d9b2e 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 b2d6bba44054..1425380983f7 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 4470f6e8b845..f47b00dc7afd 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 dda0d1ab34f3..400c09bea639 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 cd5fb40d3fd4..556e7e6ddf0a 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 739bee13e813..5150c6d11b57 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 2b18053070c1..3460108810d5 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 c99237cd4b98..d6470c7fd6ce 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 f87e993e713b..6326d3439861 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 08a45ac3d6f8..6f09eca01112 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 b83870bf60fa..3db78b696c5c 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 cc79e697cdb2..f49d00a4c7fd 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 5bfb80cba634..ddeb1b998383 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 edf8583280c9..380b9a7462b6 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 be43fd805bd0..2b771dc708a3 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 5b466cd1272f..84d0fd47636a 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 2e7ccbb43ddb..2d8158acf6fa 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 49132bddd73e..00bd475eab4b 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 ea750e9df65f..d2732fc952e2 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 c0519139679e..96b749dacc34 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 2b9644e19de0..fdbc1d2c7352 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 bae5756b1626..6bf878335d94 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 af7f3355103e..d24d774bfd62 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 de0d8e4cbfb6..7d8083cde34f 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 0261dda3f2d2..bfcc0f7024c5 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 1b83e0009d8d..9c24de10a657 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 4f251b19fbcc..bfa555869775 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 0a25838bcf45..5a9f31ce5799 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 8efd061a0ae9..e6e823656f9d 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 0bc8dc3f9e3c..700af49022a0 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 a3fd75ac3fa5..9fae63f10298 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 f4fc4c9ad567..81969785e279 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 d8acdebe3c7c..b82d63e77b03 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/sch_prio.c b/net/sched/sch_prio.c index 2a318f2dc3e5..b5d56a22b1d2 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 4536ee64383e..4f5510e2bd6f 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 02dc82db3d23..24a77400b65e 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 b2198e65d8bb..ffd243d09188 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 9d2fca5ad14a..8209a0411bca 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 c3b75333b821..8c67890de427 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 e3c36a274412..ca8cad8251c7 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 cf06af3b63c6..91eaa26e4c42 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 1dd1a6890007..0b2eb388cbda 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 c50818f0473b..c5347d29cfb7 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 4814e246a874..d12ffa545811 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 2b90292e9505..6a69a1131fb7 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 ab86b7927f84..bd31208bbb61 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 c8e10216c113..ce136323da8b 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 af04f779ce9f..767d494de7a2 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 f008c14ad34c..277ebd4bf095 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 ce5eb68a9664..f4385e45a5fc 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 0867070bb5ca..b446e100286f 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 cae761a8536c..08c5d5a128fc 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 72abb7358933..d7f97ef26590 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 d234a98a460a..2761af36d141 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 880dbe2e6f94..645437cfc464 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 a570ff9214ec..8672e028022f 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 6a82c898f831..e83e7fee3bc0 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 1ad0f39fe091..02751dbc5a97 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 1c4672e35144..2936cb809152 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 4d7b83fbc32f..be75a3a0424e 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 58064d9e565d..791ab2e77f3f 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 | }; |
