aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-04-18 20:53:46 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-18 20:53:46 -0400
commitebfc45ee7004088d610cd399d2dee6d95f87199b (patch)
tree7e3edfaeb7660d20eb187e9d2b1d6c9a9b3ceece /net
parent6e66d5dab5d530a368314eb631201a02aabb075d (diff)
parentb14878ccb7fac0242db82720b784ab62c467c0dc (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull more networking fixes from David Miller: 1) Fix mlx4_en_netpoll implementation, it needs to schedule a NAPI context, not synchronize it. From Chris Mason. 2) Ipv4 flow input interface should never be zero, it should be LOOPBACK_IFINDEX instead. From Cong Wang and Julian Anastasov. 3) Properly configure MAC to PHY connection in mvneta devices, from Thomas Petazzoni. 4) sys_recv should use SYSCALL_DEFINE. From Jan Glauber. 5) Tunnel driver ioctls do not use the correct namespace, fix from Nicolas Dichtel. 6) Fix memory leak on seccomp filter attach, from Kees Cook. 7) Fix lockdep warning for nested vlans, from Ding Tianhong. 8) Crashes can happen in SCTP due to how the auth_enable value is managed, fix from Vlad Yasevich. 9) Wireless fixes from John W Linville and co. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (45 commits) net: sctp: cache auth_enable per endpoint tg3: update rx_jumbo_pending ring param only when jumbo frames are enabled vlan: Fix lockdep warning when vlan dev handle notification seccomp: fix memory leak on filter attach isdn: icn: buffer overflow in icn_command() ip6_tunnel: use the right netns in ioctl handler sit: use the right netns in ioctl handler ip_tunnel: use the right netns in ioctl handler net: use SYSCALL_DEFINEx for sys_recv net: mdio-gpio: Add support for separate MDI and MDO gpio pins net: mdio-gpio: Add support for active low gpio pins net: mdio-gpio: Use devm_ functions where possible ipv4, route: pass 0 instead of LOOPBACK_IFINDEX to fib_validate_source() ipv4, fib: pass LOOPBACK_IFINDEX instead of 0 to flowi4_iif mlx4_en: don't use napi_synchronize inside mlx4_en_netpoll net: mvneta: properly configure the MAC <-> PHY connection in all situations net: phy: add minimal support for QSGMII PHY sfc:On MCDI timeout, issue an FLR (and mark MCDI to fail-fast) mwifiex: fix hung task on command timeout mwifiex: process event before command response ...
Diffstat (limited to 'net')
-rw-r--r--net/8021q/vlan_dev.c46
-rw-r--r--net/core/dev.c1
-rw-r--r--net/ipv4/fib_frontend.c2
-rw-r--r--net/ipv4/fib_semantics.c1
-rw-r--r--net/ipv4/ip_tunnel.c15
-rw-r--r--net/ipv4/ipmr.c2
-rw-r--r--net/ipv4/netfilter/ipt_rpfilter.c5
-rw-r--r--net/ipv4/route.c3
-rw-r--r--net/ipv6/ip6_tunnel.c8
-rw-r--r--net/ipv6/ip6mr.c2
-rw-r--r--net/ipv6/sit.c17
-rw-r--r--net/mac80211/chan.c11
-rw-r--r--net/mac80211/main.c4
-rw-r--r--net/mac80211/offchannel.c1
-rw-r--r--net/mac80211/status.c1
-rw-r--r--net/sctp/auth.c17
-rw-r--r--net/sctp/endpointola.c3
-rw-r--r--net/sctp/sm_make_chunk.c32
-rw-r--r--net/sctp/sm_statefuns.c6
-rw-r--r--net/sctp/socket.c54
-rw-r--r--net/sctp/sysctl.c36
-rw-r--r--net/socket.c4
22 files changed, 168 insertions, 103 deletions
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 6f142f03716d..733ec283ed1b 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -493,10 +493,48 @@ static void vlan_dev_change_rx_flags(struct net_device *dev, int change)
493 } 493 }
494} 494}
495 495
496static int vlan_calculate_locking_subclass(struct net_device *real_dev)
497{
498 int subclass = 0;
499
500 while (is_vlan_dev(real_dev)) {
501 subclass++;
502 real_dev = vlan_dev_priv(real_dev)->real_dev;
503 }
504
505 return subclass;
506}
507
508static void vlan_dev_mc_sync(struct net_device *to, struct net_device *from)
509{
510 int err = 0, subclass;
511
512 subclass = vlan_calculate_locking_subclass(to);
513
514 spin_lock_nested(&to->addr_list_lock, subclass);
515 err = __hw_addr_sync(&to->mc, &from->mc, to->addr_len);
516 if (!err)
517 __dev_set_rx_mode(to);
518 spin_unlock(&to->addr_list_lock);
519}
520
521static void vlan_dev_uc_sync(struct net_device *to, struct net_device *from)
522{
523 int err = 0, subclass;
524
525 subclass = vlan_calculate_locking_subclass(to);
526
527 spin_lock_nested(&to->addr_list_lock, subclass);
528 err = __hw_addr_sync(&to->uc, &from->uc, to->addr_len);
529 if (!err)
530 __dev_set_rx_mode(to);
531 spin_unlock(&to->addr_list_lock);
532}
533
496static void vlan_dev_set_rx_mode(struct net_device *vlan_dev) 534static void vlan_dev_set_rx_mode(struct net_device *vlan_dev)
497{ 535{
498 dev_mc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev); 536 vlan_dev_mc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev);
499 dev_uc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev); 537 vlan_dev_uc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev);
500} 538}
501 539
502/* 540/*
@@ -608,9 +646,7 @@ static int vlan_dev_init(struct net_device *dev)
608 646
609 SET_NETDEV_DEVTYPE(dev, &vlan_type); 647 SET_NETDEV_DEVTYPE(dev, &vlan_type);
610 648
611 if (is_vlan_dev(real_dev)) 649 subclass = vlan_calculate_locking_subclass(dev);
612 subclass = 1;
613
614 vlan_dev_set_lockdep_class(dev, subclass); 650 vlan_dev_set_lockdep_class(dev, subclass);
615 651
616 vlan_dev_priv(dev)->vlan_pcpu_stats = netdev_alloc_pcpu_stats(struct vlan_pcpu_stats); 652 vlan_dev_priv(dev)->vlan_pcpu_stats = netdev_alloc_pcpu_stats(struct vlan_pcpu_stats);
diff --git a/net/core/dev.c b/net/core/dev.c
index 5b3042e69f85..d2c8a06b3a98 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5238,6 +5238,7 @@ void __dev_set_rx_mode(struct net_device *dev)
5238 if (ops->ndo_set_rx_mode) 5238 if (ops->ndo_set_rx_mode)
5239 ops->ndo_set_rx_mode(dev); 5239 ops->ndo_set_rx_mode(dev);
5240} 5240}
5241EXPORT_SYMBOL(__dev_set_rx_mode);
5241 5242
5242void dev_set_rx_mode(struct net_device *dev) 5243void dev_set_rx_mode(struct net_device *dev)
5243{ 5244{
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 1a629f870274..255aa9946fe7 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -250,7 +250,7 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
250 bool dev_match; 250 bool dev_match;
251 251
252 fl4.flowi4_oif = 0; 252 fl4.flowi4_oif = 0;
253 fl4.flowi4_iif = oif; 253 fl4.flowi4_iif = oif ? : LOOPBACK_IFINDEX;
254 fl4.daddr = src; 254 fl4.daddr = src;
255 fl4.saddr = dst; 255 fl4.saddr = dst;
256 fl4.flowi4_tos = tos; 256 fl4.flowi4_tos = tos;
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index b53f0bf84dca..8a043f03c88e 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -631,6 +631,7 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi,
631 .daddr = nh->nh_gw, 631 .daddr = nh->nh_gw,
632 .flowi4_scope = cfg->fc_scope + 1, 632 .flowi4_scope = cfg->fc_scope + 1,
633 .flowi4_oif = nh->nh_oif, 633 .flowi4_oif = nh->nh_oif,
634 .flowi4_iif = LOOPBACK_IFINDEX,
634 }; 635 };
635 636
636 /* It is not necessary, but requires a bit of thinking */ 637 /* It is not necessary, but requires a bit of thinking */
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index 484d0ce27ef7..fa5b7519765f 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -722,19 +722,18 @@ static void ip_tunnel_update(struct ip_tunnel_net *itn,
722int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd) 722int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd)
723{ 723{
724 int err = 0; 724 int err = 0;
725 struct ip_tunnel *t; 725 struct ip_tunnel *t = netdev_priv(dev);
726 struct net *net = dev_net(dev); 726 struct net *net = t->net;
727 struct ip_tunnel *tunnel = netdev_priv(dev); 727 struct ip_tunnel_net *itn = net_generic(net, t->ip_tnl_net_id);
728 struct ip_tunnel_net *itn = net_generic(net, tunnel->ip_tnl_net_id);
729 728
730 BUG_ON(!itn->fb_tunnel_dev); 729 BUG_ON(!itn->fb_tunnel_dev);
731 switch (cmd) { 730 switch (cmd) {
732 case SIOCGETTUNNEL: 731 case SIOCGETTUNNEL:
733 t = NULL; 732 if (dev == itn->fb_tunnel_dev) {
734 if (dev == itn->fb_tunnel_dev)
735 t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type); 733 t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type);
736 if (t == NULL) 734 if (t == NULL)
737 t = netdev_priv(dev); 735 t = netdev_priv(dev);
736 }
738 memcpy(p, &t->parms, sizeof(*p)); 737 memcpy(p, &t->parms, sizeof(*p));
739 break; 738 break;
740 739
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 28863570dd60..d84dc8d4c916 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -455,7 +455,7 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb, struct net_device *dev)
455 struct mr_table *mrt; 455 struct mr_table *mrt;
456 struct flowi4 fl4 = { 456 struct flowi4 fl4 = {
457 .flowi4_oif = dev->ifindex, 457 .flowi4_oif = dev->ifindex,
458 .flowi4_iif = skb->skb_iif, 458 .flowi4_iif = skb->skb_iif ? : LOOPBACK_IFINDEX,
459 .flowi4_mark = skb->mark, 459 .flowi4_mark = skb->mark,
460 }; 460 };
461 int err; 461 int err;
diff --git a/net/ipv4/netfilter/ipt_rpfilter.c b/net/ipv4/netfilter/ipt_rpfilter.c
index c49dcd0284a0..4bfaedf9b34e 100644
--- a/net/ipv4/netfilter/ipt_rpfilter.c
+++ b/net/ipv4/netfilter/ipt_rpfilter.c
@@ -89,11 +89,8 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par)
89 if (ipv4_is_multicast(iph->daddr)) { 89 if (ipv4_is_multicast(iph->daddr)) {
90 if (ipv4_is_zeronet(iph->saddr)) 90 if (ipv4_is_zeronet(iph->saddr))
91 return ipv4_is_local_multicast(iph->daddr) ^ invert; 91 return ipv4_is_local_multicast(iph->daddr) ^ invert;
92 flow.flowi4_iif = 0;
93 } else {
94 flow.flowi4_iif = LOOPBACK_IFINDEX;
95 } 92 }
96 93 flow.flowi4_iif = LOOPBACK_IFINDEX;
97 flow.daddr = iph->saddr; 94 flow.daddr = iph->saddr;
98 flow.saddr = rpfilter_get_saddr(iph->daddr); 95 flow.saddr = rpfilter_get_saddr(iph->daddr);
99 flow.flowi4_oif = 0; 96 flow.flowi4_oif = 0;
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 1485aafcad59..db1e0da871f4 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1700,8 +1700,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
1700 1700
1701 if (res.type == RTN_LOCAL) { 1701 if (res.type == RTN_LOCAL) {
1702 err = fib_validate_source(skb, saddr, daddr, tos, 1702 err = fib_validate_source(skb, saddr, daddr, tos,
1703 LOOPBACK_IFINDEX, 1703 0, dev, in_dev, &itag);
1704 dev, in_dev, &itag);
1705 if (err < 0) 1704 if (err < 0)
1706 goto martian_source_keep_err; 1705 goto martian_source_keep_err;
1707 goto local_input; 1706 goto local_input;
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index e1df691d78be..b05b609f69d1 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1340,8 +1340,8 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1340 int err = 0; 1340 int err = 0;
1341 struct ip6_tnl_parm p; 1341 struct ip6_tnl_parm p;
1342 struct __ip6_tnl_parm p1; 1342 struct __ip6_tnl_parm p1;
1343 struct ip6_tnl *t = NULL; 1343 struct ip6_tnl *t = netdev_priv(dev);
1344 struct net *net = dev_net(dev); 1344 struct net *net = t->net;
1345 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id); 1345 struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);
1346 1346
1347 switch (cmd) { 1347 switch (cmd) {
@@ -1353,11 +1353,11 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1353 } 1353 }
1354 ip6_tnl_parm_from_user(&p1, &p); 1354 ip6_tnl_parm_from_user(&p1, &p);
1355 t = ip6_tnl_locate(net, &p1, 0); 1355 t = ip6_tnl_locate(net, &p1, 0);
1356 if (t == NULL)
1357 t = netdev_priv(dev);
1356 } else { 1358 } else {
1357 memset(&p, 0, sizeof(p)); 1359 memset(&p, 0, sizeof(p));
1358 } 1360 }
1359 if (t == NULL)
1360 t = netdev_priv(dev);
1361 ip6_tnl_parm_to_user(&p, &t->parms); 1361 ip6_tnl_parm_to_user(&p, &t->parms);
1362 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof (p))) { 1362 if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof (p))) {
1363 err = -EFAULT; 1363 err = -EFAULT;
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 8737400af0a0..8659067da28e 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -700,7 +700,7 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb,
700 struct mr6_table *mrt; 700 struct mr6_table *mrt;
701 struct flowi6 fl6 = { 701 struct flowi6 fl6 = {
702 .flowi6_oif = dev->ifindex, 702 .flowi6_oif = dev->ifindex,
703 .flowi6_iif = skb->skb_iif, 703 .flowi6_iif = skb->skb_iif ? : LOOPBACK_IFINDEX,
704 .flowi6_mark = skb->mark, 704 .flowi6_mark = skb->mark,
705 }; 705 };
706 int err; 706 int err;
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 8da8268d65f8..e5a453ca302e 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -1127,8 +1127,8 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
1127 int err = 0; 1127 int err = 0;
1128 struct ip_tunnel_parm p; 1128 struct ip_tunnel_parm p;
1129 struct ip_tunnel_prl prl; 1129 struct ip_tunnel_prl prl;
1130 struct ip_tunnel *t; 1130 struct ip_tunnel *t = netdev_priv(dev);
1131 struct net *net = dev_net(dev); 1131 struct net *net = t->net;
1132 struct sit_net *sitn = net_generic(net, sit_net_id); 1132 struct sit_net *sitn = net_generic(net, sit_net_id);
1133#ifdef CONFIG_IPV6_SIT_6RD 1133#ifdef CONFIG_IPV6_SIT_6RD
1134 struct ip_tunnel_6rd ip6rd; 1134 struct ip_tunnel_6rd ip6rd;
@@ -1139,16 +1139,15 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
1139#ifdef CONFIG_IPV6_SIT_6RD 1139#ifdef CONFIG_IPV6_SIT_6RD
1140 case SIOCGET6RD: 1140 case SIOCGET6RD:
1141#endif 1141#endif
1142 t = NULL;
1143 if (dev == sitn->fb_tunnel_dev) { 1142 if (dev == sitn->fb_tunnel_dev) {
1144 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) { 1143 if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) {
1145 err = -EFAULT; 1144 err = -EFAULT;
1146 break; 1145 break;
1147 } 1146 }
1148 t = ipip6_tunnel_locate(net, &p, 0); 1147 t = ipip6_tunnel_locate(net, &p, 0);
1148 if (t == NULL)
1149 t = netdev_priv(dev);
1149 } 1150 }
1150 if (t == NULL)
1151 t = netdev_priv(dev);
1152 1151
1153 err = -EFAULT; 1152 err = -EFAULT;
1154 if (cmd == SIOCGETTUNNEL) { 1153 if (cmd == SIOCGETTUNNEL) {
@@ -1244,9 +1243,6 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
1244 err = -EINVAL; 1243 err = -EINVAL;
1245 if (dev == sitn->fb_tunnel_dev) 1244 if (dev == sitn->fb_tunnel_dev)
1246 goto done; 1245 goto done;
1247 err = -ENOENT;
1248 if (!(t = netdev_priv(dev)))
1249 goto done;
1250 err = ipip6_tunnel_get_prl(t, ifr->ifr_ifru.ifru_data); 1246 err = ipip6_tunnel_get_prl(t, ifr->ifr_ifru.ifru_data);
1251 break; 1247 break;
1252 1248
@@ -1262,9 +1258,6 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
1262 err = -EFAULT; 1258 err = -EFAULT;
1263 if (copy_from_user(&prl, ifr->ifr_ifru.ifru_data, sizeof(prl))) 1259 if (copy_from_user(&prl, ifr->ifr_ifru.ifru_data, sizeof(prl)))
1264 goto done; 1260 goto done;
1265 err = -ENOENT;
1266 if (!(t = netdev_priv(dev)))
1267 goto done;
1268 1261
1269 switch (cmd) { 1262 switch (cmd) {
1270 case SIOCDELPRL: 1263 case SIOCDELPRL:
@@ -1292,8 +1285,6 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
1292 sizeof(ip6rd))) 1285 sizeof(ip6rd)))
1293 goto done; 1286 goto done;
1294 1287
1295 t = netdev_priv(dev);
1296
1297 if (cmd != SIOCDEL6RD) { 1288 if (cmd != SIOCDEL6RD) {
1298 err = ipip6_tunnel_update_6rd(t, &ip6rd); 1289 err = ipip6_tunnel_update_6rd(t, &ip6rd);
1299 if (err < 0) 1290 if (err < 0)
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index bd1fd8ea5105..75b5dd2c9267 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -249,7 +249,7 @@ ieee80211_new_chanctx(struct ieee80211_local *local,
249 249
250 if (!local->use_chanctx) { 250 if (!local->use_chanctx) {
251 local->_oper_chandef = *chandef; 251 local->_oper_chandef = *chandef;
252 ieee80211_hw_config(local, 0); 252 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
253 } else { 253 } else {
254 err = drv_add_chanctx(local, ctx); 254 err = drv_add_chanctx(local, ctx);
255 if (err) { 255 if (err) {
@@ -286,7 +286,7 @@ static void ieee80211_free_chanctx(struct ieee80211_local *local,
286 check_single_channel = true; 286 check_single_channel = true;
287 local->hw.conf.radar_enabled = false; 287 local->hw.conf.radar_enabled = false;
288 288
289 ieee80211_hw_config(local, 0); 289 ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL);
290 } else { 290 } else {
291 drv_remove_chanctx(local, ctx); 291 drv_remove_chanctx(local, ctx);
292 } 292 }
@@ -492,6 +492,13 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
492 rx_chains_static = max(rx_chains_static, needed_static); 492 rx_chains_static = max(rx_chains_static, needed_static);
493 rx_chains_dynamic = max(rx_chains_dynamic, needed_dynamic); 493 rx_chains_dynamic = max(rx_chains_dynamic, needed_dynamic);
494 } 494 }
495
496 /* Disable SMPS for the monitor interface */
497 sdata = rcu_dereference(local->monitor_sdata);
498 if (sdata &&
499 rcu_access_pointer(sdata->vif.chanctx_conf) == &chanctx->conf)
500 rx_chains_dynamic = rx_chains_static = local->rx_chains;
501
495 rcu_read_unlock(); 502 rcu_read_unlock();
496 503
497 if (!local->use_chanctx) { 504 if (!local->use_chanctx) {
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index b055f6a55c68..4c1bf61bc778 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -148,6 +148,8 @@ static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
148 list_for_each_entry_rcu(sdata, &local->interfaces, list) { 148 list_for_each_entry_rcu(sdata, &local->interfaces, list) {
149 if (!rcu_access_pointer(sdata->vif.chanctx_conf)) 149 if (!rcu_access_pointer(sdata->vif.chanctx_conf))
150 continue; 150 continue;
151 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
152 continue;
151 power = min(power, sdata->vif.bss_conf.txpower); 153 power = min(power, sdata->vif.bss_conf.txpower);
152 } 154 }
153 rcu_read_unlock(); 155 rcu_read_unlock();
@@ -199,7 +201,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
199{ 201{
200 struct ieee80211_local *local = sdata->local; 202 struct ieee80211_local *local = sdata->local;
201 203
202 if (!changed) 204 if (!changed || sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
203 return; 205 return;
204 206
205 drv_bss_info_changed(local, sdata, &sdata->vif.bss_conf, changed); 207 drv_bss_info_changed(local, sdata, &sdata->vif.bss_conf, changed);
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index 0c2a29484c07..6fb38558a5e6 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -355,6 +355,7 @@ void ieee80211_sw_roc_work(struct work_struct *work)
355 struct ieee80211_roc_work *dep; 355 struct ieee80211_roc_work *dep;
356 356
357 /* start this ROC */ 357 /* start this ROC */
358 ieee80211_offchannel_stop_vifs(local);
358 359
359 /* switch channel etc */ 360 /* switch channel etc */
360 ieee80211_recalc_idle(local); 361 ieee80211_recalc_idle(local);
diff --git a/net/mac80211/status.c b/net/mac80211/status.c
index e6e574a307c8..00ba90b02ab2 100644
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -618,6 +618,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
618 sta, true, acked); 618 sta, true, acked);
619 619
620 if ((local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) && 620 if ((local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) &&
621 (ieee80211_is_data(hdr->frame_control)) &&
621 (rates_idx != -1)) 622 (rates_idx != -1))
622 sta->last_tx_rate = info->status.rates[rates_idx]; 623 sta->last_tx_rate = info->status.rates[rates_idx];
623 624
diff --git a/net/sctp/auth.c b/net/sctp/auth.c
index 683c7d1b1306..0e8529113dc5 100644
--- a/net/sctp/auth.c
+++ b/net/sctp/auth.c
@@ -386,14 +386,13 @@ nomem:
386 */ 386 */
387int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp) 387int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp)
388{ 388{
389 struct net *net = sock_net(asoc->base.sk);
390 struct sctp_auth_bytes *secret; 389 struct sctp_auth_bytes *secret;
391 struct sctp_shared_key *ep_key; 390 struct sctp_shared_key *ep_key;
392 391
393 /* If we don't support AUTH, or peer is not capable 392 /* If we don't support AUTH, or peer is not capable
394 * we don't need to do anything. 393 * we don't need to do anything.
395 */ 394 */
396 if (!net->sctp.auth_enable || !asoc->peer.auth_capable) 395 if (!asoc->ep->auth_enable || !asoc->peer.auth_capable)
397 return 0; 396 return 0;
398 397
399 /* If the key_id is non-zero and we couldn't find an 398 /* If the key_id is non-zero and we couldn't find an
@@ -440,16 +439,16 @@ struct sctp_shared_key *sctp_auth_get_shkey(
440 */ 439 */
441int sctp_auth_init_hmacs(struct sctp_endpoint *ep, gfp_t gfp) 440int sctp_auth_init_hmacs(struct sctp_endpoint *ep, gfp_t gfp)
442{ 441{
443 struct net *net = sock_net(ep->base.sk);
444 struct crypto_hash *tfm = NULL; 442 struct crypto_hash *tfm = NULL;
445 __u16 id; 443 __u16 id;
446 444
447 /* if the transforms are already allocted, we are done */ 445 /* If AUTH extension is disabled, we are done */
448 if (!net->sctp.auth_enable) { 446 if (!ep->auth_enable) {
449 ep->auth_hmacs = NULL; 447 ep->auth_hmacs = NULL;
450 return 0; 448 return 0;
451 } 449 }
452 450
451 /* If the transforms are already allocated, we are done */
453 if (ep->auth_hmacs) 452 if (ep->auth_hmacs)
454 return 0; 453 return 0;
455 454
@@ -665,12 +664,10 @@ static int __sctp_auth_cid(sctp_cid_t chunk, struct sctp_chunks_param *param)
665/* Check if peer requested that this chunk is authenticated */ 664/* Check if peer requested that this chunk is authenticated */
666int sctp_auth_send_cid(sctp_cid_t chunk, const struct sctp_association *asoc) 665int sctp_auth_send_cid(sctp_cid_t chunk, const struct sctp_association *asoc)
667{ 666{
668 struct net *net;
669 if (!asoc) 667 if (!asoc)
670 return 0; 668 return 0;
671 669
672 net = sock_net(asoc->base.sk); 670 if (!asoc->ep->auth_enable || !asoc->peer.auth_capable)
673 if (!net->sctp.auth_enable || !asoc->peer.auth_capable)
674 return 0; 671 return 0;
675 672
676 return __sctp_auth_cid(chunk, asoc->peer.peer_chunks); 673 return __sctp_auth_cid(chunk, asoc->peer.peer_chunks);
@@ -679,12 +676,10 @@ int sctp_auth_send_cid(sctp_cid_t chunk, const struct sctp_association *asoc)
679/* Check if we requested that peer authenticate this chunk. */ 676/* Check if we requested that peer authenticate this chunk. */
680int sctp_auth_recv_cid(sctp_cid_t chunk, const struct sctp_association *asoc) 677int sctp_auth_recv_cid(sctp_cid_t chunk, const struct sctp_association *asoc)
681{ 678{
682 struct net *net;
683 if (!asoc) 679 if (!asoc)
684 return 0; 680 return 0;
685 681
686 net = sock_net(asoc->base.sk); 682 if (!asoc->ep->auth_enable)
687 if (!net->sctp.auth_enable)
688 return 0; 683 return 0;
689 684
690 return __sctp_auth_cid(chunk, 685 return __sctp_auth_cid(chunk,
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index 8e5fdea05216..3d9f429858dc 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -68,7 +68,8 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
68 if (!ep->digest) 68 if (!ep->digest)
69 return NULL; 69 return NULL;
70 70
71 if (net->sctp.auth_enable) { 71 ep->auth_enable = net->sctp.auth_enable;
72 if (ep->auth_enable) {
72 /* Allocate space for HMACS and CHUNKS authentication 73 /* Allocate space for HMACS and CHUNKS authentication
73 * variables. There are arrays that we encode directly 74 * variables. There are arrays that we encode directly
74 * into parameters to make the rest of the operations easier. 75 * into parameters to make the rest of the operations easier.
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 3a1767ef3201..fee5552ddf92 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -219,6 +219,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
219 gfp_t gfp, int vparam_len) 219 gfp_t gfp, int vparam_len)
220{ 220{
221 struct net *net = sock_net(asoc->base.sk); 221 struct net *net = sock_net(asoc->base.sk);
222 struct sctp_endpoint *ep = asoc->ep;
222 sctp_inithdr_t init; 223 sctp_inithdr_t init;
223 union sctp_params addrs; 224 union sctp_params addrs;
224 size_t chunksize; 225 size_t chunksize;
@@ -278,7 +279,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
278 chunksize += vparam_len; 279 chunksize += vparam_len;
279 280
280 /* Account for AUTH related parameters */ 281 /* Account for AUTH related parameters */
281 if (net->sctp.auth_enable) { 282 if (ep->auth_enable) {
282 /* Add random parameter length*/ 283 /* Add random parameter length*/
283 chunksize += sizeof(asoc->c.auth_random); 284 chunksize += sizeof(asoc->c.auth_random);
284 285
@@ -363,7 +364,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
363 } 364 }
364 365
365 /* Add SCTP-AUTH chunks to the parameter list */ 366 /* Add SCTP-AUTH chunks to the parameter list */
366 if (net->sctp.auth_enable) { 367 if (ep->auth_enable) {
367 sctp_addto_chunk(retval, sizeof(asoc->c.auth_random), 368 sctp_addto_chunk(retval, sizeof(asoc->c.auth_random),
368 asoc->c.auth_random); 369 asoc->c.auth_random);
369 if (auth_hmacs) 370 if (auth_hmacs)
@@ -2010,7 +2011,7 @@ static void sctp_process_ext_param(struct sctp_association *asoc,
2010 /* if the peer reports AUTH, assume that he 2011 /* if the peer reports AUTH, assume that he
2011 * supports AUTH. 2012 * supports AUTH.
2012 */ 2013 */
2013 if (net->sctp.auth_enable) 2014 if (asoc->ep->auth_enable)
2014 asoc->peer.auth_capable = 1; 2015 asoc->peer.auth_capable = 1;
2015 break; 2016 break;
2016 case SCTP_CID_ASCONF: 2017 case SCTP_CID_ASCONF:
@@ -2102,6 +2103,7 @@ static sctp_ierror_t sctp_process_unk_param(const struct sctp_association *asoc,
2102 * SCTP_IERROR_NO_ERROR - continue with the chunk 2103 * SCTP_IERROR_NO_ERROR - continue with the chunk
2103 */ 2104 */
2104static sctp_ierror_t sctp_verify_param(struct net *net, 2105static sctp_ierror_t sctp_verify_param(struct net *net,
2106 const struct sctp_endpoint *ep,
2105 const struct sctp_association *asoc, 2107 const struct sctp_association *asoc,
2106 union sctp_params param, 2108 union sctp_params param,
2107 sctp_cid_t cid, 2109 sctp_cid_t cid,
@@ -2152,7 +2154,7 @@ static sctp_ierror_t sctp_verify_param(struct net *net,
2152 goto fallthrough; 2154 goto fallthrough;
2153 2155
2154 case SCTP_PARAM_RANDOM: 2156 case SCTP_PARAM_RANDOM:
2155 if (!net->sctp.auth_enable) 2157 if (!ep->auth_enable)
2156 goto fallthrough; 2158 goto fallthrough;
2157 2159
2158 /* SCTP-AUTH: Secion 6.1 2160 /* SCTP-AUTH: Secion 6.1
@@ -2169,7 +2171,7 @@ static sctp_ierror_t sctp_verify_param(struct net *net,
2169 break; 2171 break;
2170 2172
2171 case SCTP_PARAM_CHUNKS: 2173 case SCTP_PARAM_CHUNKS:
2172 if (!net->sctp.auth_enable) 2174 if (!ep->auth_enable)
2173 goto fallthrough; 2175 goto fallthrough;
2174 2176
2175 /* SCTP-AUTH: Section 3.2 2177 /* SCTP-AUTH: Section 3.2
@@ -2185,7 +2187,7 @@ static sctp_ierror_t sctp_verify_param(struct net *net,
2185 break; 2187 break;
2186 2188
2187 case SCTP_PARAM_HMAC_ALGO: 2189 case SCTP_PARAM_HMAC_ALGO:
2188 if (!net->sctp.auth_enable) 2190 if (!ep->auth_enable)
2189 goto fallthrough; 2191 goto fallthrough;
2190 2192
2191 hmacs = (struct sctp_hmac_algo_param *)param.p; 2193 hmacs = (struct sctp_hmac_algo_param *)param.p;
@@ -2220,10 +2222,9 @@ fallthrough:
2220} 2222}
2221 2223
2222/* Verify the INIT packet before we process it. */ 2224/* Verify the INIT packet before we process it. */
2223int sctp_verify_init(struct net *net, const struct sctp_association *asoc, 2225int sctp_verify_init(struct net *net, const struct sctp_endpoint *ep,
2224 sctp_cid_t cid, 2226 const struct sctp_association *asoc, sctp_cid_t cid,
2225 sctp_init_chunk_t *peer_init, 2227 sctp_init_chunk_t *peer_init, struct sctp_chunk *chunk,
2226 struct sctp_chunk *chunk,
2227 struct sctp_chunk **errp) 2228 struct sctp_chunk **errp)
2228{ 2229{
2229 union sctp_params param; 2230 union sctp_params param;
@@ -2264,8 +2265,8 @@ int sctp_verify_init(struct net *net, const struct sctp_association *asoc,
2264 2265
2265 /* Verify all the variable length parameters */ 2266 /* Verify all the variable length parameters */
2266 sctp_walk_params(param, peer_init, init_hdr.params) { 2267 sctp_walk_params(param, peer_init, init_hdr.params) {
2267 2268 result = sctp_verify_param(net, ep, asoc, param, cid,
2268 result = sctp_verify_param(net, asoc, param, cid, chunk, errp); 2269 chunk, errp);
2269 switch (result) { 2270 switch (result) {
2270 case SCTP_IERROR_ABORT: 2271 case SCTP_IERROR_ABORT:
2271 case SCTP_IERROR_NOMEM: 2272 case SCTP_IERROR_NOMEM:
@@ -2497,6 +2498,7 @@ static int sctp_process_param(struct sctp_association *asoc,
2497 struct sctp_af *af; 2498 struct sctp_af *af;
2498 union sctp_addr_param *addr_param; 2499 union sctp_addr_param *addr_param;
2499 struct sctp_transport *t; 2500 struct sctp_transport *t;
2501 struct sctp_endpoint *ep = asoc->ep;
2500 2502
2501 /* We maintain all INIT parameters in network byte order all the 2503 /* We maintain all INIT parameters in network byte order all the
2502 * time. This allows us to not worry about whether the parameters 2504 * time. This allows us to not worry about whether the parameters
@@ -2636,7 +2638,7 @@ do_addr_param:
2636 goto fall_through; 2638 goto fall_through;
2637 2639
2638 case SCTP_PARAM_RANDOM: 2640 case SCTP_PARAM_RANDOM:
2639 if (!net->sctp.auth_enable) 2641 if (!ep->auth_enable)
2640 goto fall_through; 2642 goto fall_through;
2641 2643
2642 /* Save peer's random parameter */ 2644 /* Save peer's random parameter */
@@ -2649,7 +2651,7 @@ do_addr_param:
2649 break; 2651 break;
2650 2652
2651 case SCTP_PARAM_HMAC_ALGO: 2653 case SCTP_PARAM_HMAC_ALGO:
2652 if (!net->sctp.auth_enable) 2654 if (!ep->auth_enable)
2653 goto fall_through; 2655 goto fall_through;
2654 2656
2655 /* Save peer's HMAC list */ 2657 /* Save peer's HMAC list */
@@ -2665,7 +2667,7 @@ do_addr_param:
2665 break; 2667 break;
2666 2668
2667 case SCTP_PARAM_CHUNKS: 2669 case SCTP_PARAM_CHUNKS:
2668 if (!net->sctp.auth_enable) 2670 if (!ep->auth_enable)
2669 goto fall_through; 2671 goto fall_through;
2670 2672
2671 asoc->peer.peer_chunks = kmemdup(param.p, 2673 asoc->peer.peer_chunks = kmemdup(param.p,
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index ae9fbeba40b0..5170a1ff95a1 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -357,7 +357,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(struct net *net,
357 357
358 /* Verify the INIT chunk before processing it. */ 358 /* Verify the INIT chunk before processing it. */
359 err_chunk = NULL; 359 err_chunk = NULL;
360 if (!sctp_verify_init(net, asoc, chunk->chunk_hdr->type, 360 if (!sctp_verify_init(net, ep, asoc, chunk->chunk_hdr->type,
361 (sctp_init_chunk_t *)chunk->chunk_hdr, chunk, 361 (sctp_init_chunk_t *)chunk->chunk_hdr, chunk,
362 &err_chunk)) { 362 &err_chunk)) {
363 /* This chunk contains fatal error. It is to be discarded. 363 /* This chunk contains fatal error. It is to be discarded.
@@ -524,7 +524,7 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(struct net *net,
524 524
525 /* Verify the INIT chunk before processing it. */ 525 /* Verify the INIT chunk before processing it. */
526 err_chunk = NULL; 526 err_chunk = NULL;
527 if (!sctp_verify_init(net, asoc, chunk->chunk_hdr->type, 527 if (!sctp_verify_init(net, ep, asoc, chunk->chunk_hdr->type,
528 (sctp_init_chunk_t *)chunk->chunk_hdr, chunk, 528 (sctp_init_chunk_t *)chunk->chunk_hdr, chunk,
529 &err_chunk)) { 529 &err_chunk)) {
530 530
@@ -1430,7 +1430,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
1430 1430
1431 /* Verify the INIT chunk before processing it. */ 1431 /* Verify the INIT chunk before processing it. */
1432 err_chunk = NULL; 1432 err_chunk = NULL;
1433 if (!sctp_verify_init(net, asoc, chunk->chunk_hdr->type, 1433 if (!sctp_verify_init(net, ep, asoc, chunk->chunk_hdr->type,
1434 (sctp_init_chunk_t *)chunk->chunk_hdr, chunk, 1434 (sctp_init_chunk_t *)chunk->chunk_hdr, chunk,
1435 &err_chunk)) { 1435 &err_chunk)) {
1436 /* This chunk contains fatal error. It is to be discarded. 1436 /* This chunk contains fatal error. It is to be discarded.
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index ff20e2dbbbc7..fee06b99a4da 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -3321,10 +3321,10 @@ static int sctp_setsockopt_auth_chunk(struct sock *sk,
3321 char __user *optval, 3321 char __user *optval,
3322 unsigned int optlen) 3322 unsigned int optlen)
3323{ 3323{
3324 struct net *net = sock_net(sk); 3324 struct sctp_endpoint *ep = sctp_sk(sk)->ep;
3325 struct sctp_authchunk val; 3325 struct sctp_authchunk val;
3326 3326
3327 if (!net->sctp.auth_enable) 3327 if (!ep->auth_enable)
3328 return -EACCES; 3328 return -EACCES;
3329 3329
3330 if (optlen != sizeof(struct sctp_authchunk)) 3330 if (optlen != sizeof(struct sctp_authchunk))
@@ -3341,7 +3341,7 @@ static int sctp_setsockopt_auth_chunk(struct sock *sk,
3341 } 3341 }
3342 3342
3343 /* add this chunk id to the endpoint */ 3343 /* add this chunk id to the endpoint */
3344 return sctp_auth_ep_add_chunkid(sctp_sk(sk)->ep, val.sauth_chunk); 3344 return sctp_auth_ep_add_chunkid(ep, val.sauth_chunk);
3345} 3345}
3346 3346
3347/* 3347/*
@@ -3354,12 +3354,12 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk,
3354 char __user *optval, 3354 char __user *optval,
3355 unsigned int optlen) 3355 unsigned int optlen)
3356{ 3356{
3357 struct net *net = sock_net(sk); 3357 struct sctp_endpoint *ep = sctp_sk(sk)->ep;
3358 struct sctp_hmacalgo *hmacs; 3358 struct sctp_hmacalgo *hmacs;
3359 u32 idents; 3359 u32 idents;
3360 int err; 3360 int err;
3361 3361
3362 if (!net->sctp.auth_enable) 3362 if (!ep->auth_enable)
3363 return -EACCES; 3363 return -EACCES;
3364 3364
3365 if (optlen < sizeof(struct sctp_hmacalgo)) 3365 if (optlen < sizeof(struct sctp_hmacalgo))
@@ -3376,7 +3376,7 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk,
3376 goto out; 3376 goto out;
3377 } 3377 }
3378 3378
3379 err = sctp_auth_ep_set_hmacs(sctp_sk(sk)->ep, hmacs); 3379 err = sctp_auth_ep_set_hmacs(ep, hmacs);
3380out: 3380out:
3381 kfree(hmacs); 3381 kfree(hmacs);
3382 return err; 3382 return err;
@@ -3392,12 +3392,12 @@ static int sctp_setsockopt_auth_key(struct sock *sk,
3392 char __user *optval, 3392 char __user *optval,
3393 unsigned int optlen) 3393 unsigned int optlen)
3394{ 3394{
3395 struct net *net = sock_net(sk); 3395 struct sctp_endpoint *ep = sctp_sk(sk)->ep;
3396 struct sctp_authkey *authkey; 3396 struct sctp_authkey *authkey;
3397 struct sctp_association *asoc; 3397 struct sctp_association *asoc;
3398 int ret; 3398 int ret;
3399 3399
3400 if (!net->sctp.auth_enable) 3400 if (!ep->auth_enable)
3401 return -EACCES; 3401 return -EACCES;
3402 3402
3403 if (optlen <= sizeof(struct sctp_authkey)) 3403 if (optlen <= sizeof(struct sctp_authkey))
@@ -3418,7 +3418,7 @@ static int sctp_setsockopt_auth_key(struct sock *sk,
3418 goto out; 3418 goto out;
3419 } 3419 }
3420 3420
3421 ret = sctp_auth_set_key(sctp_sk(sk)->ep, asoc, authkey); 3421 ret = sctp_auth_set_key(ep, asoc, authkey);
3422out: 3422out:
3423 kzfree(authkey); 3423 kzfree(authkey);
3424 return ret; 3424 return ret;
@@ -3434,11 +3434,11 @@ static int sctp_setsockopt_active_key(struct sock *sk,
3434 char __user *optval, 3434 char __user *optval,
3435 unsigned int optlen) 3435 unsigned int optlen)
3436{ 3436{
3437 struct net *net = sock_net(sk); 3437 struct sctp_endpoint *ep = sctp_sk(sk)->ep;
3438 struct sctp_authkeyid val; 3438 struct sctp_authkeyid val;
3439 struct sctp_association *asoc; 3439 struct sctp_association *asoc;
3440 3440
3441 if (!net->sctp.auth_enable) 3441 if (!ep->auth_enable)
3442 return -EACCES; 3442 return -EACCES;
3443 3443
3444 if (optlen != sizeof(struct sctp_authkeyid)) 3444 if (optlen != sizeof(struct sctp_authkeyid))
@@ -3450,8 +3450,7 @@ static int sctp_setsockopt_active_key(struct sock *sk,
3450 if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP)) 3450 if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP))
3451 return -EINVAL; 3451 return -EINVAL;
3452 3452
3453 return sctp_auth_set_active_key(sctp_sk(sk)->ep, asoc, 3453 return sctp_auth_set_active_key(ep, asoc, val.scact_keynumber);
3454 val.scact_keynumber);
3455} 3454}
3456 3455
3457/* 3456/*
@@ -3463,11 +3462,11 @@ static int sctp_setsockopt_del_key(struct sock *sk,
3463 char __user *optval, 3462 char __user *optval,
3464 unsigned int optlen) 3463 unsigned int optlen)
3465{ 3464{
3466 struct net *net = sock_net(sk); 3465 struct sctp_endpoint *ep = sctp_sk(sk)->ep;
3467 struct sctp_authkeyid val; 3466 struct sctp_authkeyid val;
3468 struct sctp_association *asoc; 3467 struct sctp_association *asoc;
3469 3468
3470 if (!net->sctp.auth_enable) 3469 if (!ep->auth_enable)
3471 return -EACCES; 3470 return -EACCES;
3472 3471
3473 if (optlen != sizeof(struct sctp_authkeyid)) 3472 if (optlen != sizeof(struct sctp_authkeyid))
@@ -3479,8 +3478,7 @@ static int sctp_setsockopt_del_key(struct sock *sk,
3479 if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP)) 3478 if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP))
3480 return -EINVAL; 3479 return -EINVAL;
3481 3480
3482 return sctp_auth_del_key_id(sctp_sk(sk)->ep, asoc, 3481 return sctp_auth_del_key_id(ep, asoc, val.scact_keynumber);
3483 val.scact_keynumber);
3484 3482
3485} 3483}
3486 3484
@@ -5387,16 +5385,16 @@ static int sctp_getsockopt_maxburst(struct sock *sk, int len,
5387static int sctp_getsockopt_hmac_ident(struct sock *sk, int len, 5385static int sctp_getsockopt_hmac_ident(struct sock *sk, int len,
5388 char __user *optval, int __user *optlen) 5386 char __user *optval, int __user *optlen)
5389{ 5387{
5390 struct net *net = sock_net(sk); 5388 struct sctp_endpoint *ep = sctp_sk(sk)->ep;
5391 struct sctp_hmacalgo __user *p = (void __user *)optval; 5389 struct sctp_hmacalgo __user *p = (void __user *)optval;
5392 struct sctp_hmac_algo_param *hmacs; 5390 struct sctp_hmac_algo_param *hmacs;
5393 __u16 data_len = 0; 5391 __u16 data_len = 0;
5394 u32 num_idents; 5392 u32 num_idents;
5395 5393
5396 if (!net->sctp.auth_enable) 5394 if (!ep->auth_enable)
5397 return -EACCES; 5395 return -EACCES;
5398 5396
5399 hmacs = sctp_sk(sk)->ep->auth_hmacs_list; 5397 hmacs = ep->auth_hmacs_list;
5400 data_len = ntohs(hmacs->param_hdr.length) - sizeof(sctp_paramhdr_t); 5398 data_len = ntohs(hmacs->param_hdr.length) - sizeof(sctp_paramhdr_t);
5401 5399
5402 if (len < sizeof(struct sctp_hmacalgo) + data_len) 5400 if (len < sizeof(struct sctp_hmacalgo) + data_len)
@@ -5417,11 +5415,11 @@ static int sctp_getsockopt_hmac_ident(struct sock *sk, int len,
5417static int sctp_getsockopt_active_key(struct sock *sk, int len, 5415static int sctp_getsockopt_active_key(struct sock *sk, int len,
5418 char __user *optval, int __user *optlen) 5416 char __user *optval, int __user *optlen)
5419{ 5417{
5420 struct net *net = sock_net(sk); 5418 struct sctp_endpoint *ep = sctp_sk(sk)->ep;
5421 struct sctp_authkeyid val; 5419 struct sctp_authkeyid val;
5422 struct sctp_association *asoc; 5420 struct sctp_association *asoc;
5423 5421
5424 if (!net->sctp.auth_enable) 5422 if (!ep->auth_enable)
5425 return -EACCES; 5423 return -EACCES;
5426 5424
5427 if (len < sizeof(struct sctp_authkeyid)) 5425 if (len < sizeof(struct sctp_authkeyid))
@@ -5436,7 +5434,7 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len,
5436 if (asoc) 5434 if (asoc)
5437 val.scact_keynumber = asoc->active_key_id; 5435 val.scact_keynumber = asoc->active_key_id;
5438 else 5436 else
5439 val.scact_keynumber = sctp_sk(sk)->ep->active_key_id; 5437 val.scact_keynumber = ep->active_key_id;
5440 5438
5441 len = sizeof(struct sctp_authkeyid); 5439 len = sizeof(struct sctp_authkeyid);
5442 if (put_user(len, optlen)) 5440 if (put_user(len, optlen))
@@ -5450,7 +5448,7 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len,
5450static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, 5448static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len,
5451 char __user *optval, int __user *optlen) 5449 char __user *optval, int __user *optlen)
5452{ 5450{
5453 struct net *net = sock_net(sk); 5451 struct sctp_endpoint *ep = sctp_sk(sk)->ep;
5454 struct sctp_authchunks __user *p = (void __user *)optval; 5452 struct sctp_authchunks __user *p = (void __user *)optval;
5455 struct sctp_authchunks val; 5453 struct sctp_authchunks val;
5456 struct sctp_association *asoc; 5454 struct sctp_association *asoc;
@@ -5458,7 +5456,7 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len,
5458 u32 num_chunks = 0; 5456 u32 num_chunks = 0;
5459 char __user *to; 5457 char __user *to;
5460 5458
5461 if (!net->sctp.auth_enable) 5459 if (!ep->auth_enable)
5462 return -EACCES; 5460 return -EACCES;
5463 5461
5464 if (len < sizeof(struct sctp_authchunks)) 5462 if (len < sizeof(struct sctp_authchunks))
@@ -5495,7 +5493,7 @@ num:
5495static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, 5493static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len,
5496 char __user *optval, int __user *optlen) 5494 char __user *optval, int __user *optlen)
5497{ 5495{
5498 struct net *net = sock_net(sk); 5496 struct sctp_endpoint *ep = sctp_sk(sk)->ep;
5499 struct sctp_authchunks __user *p = (void __user *)optval; 5497 struct sctp_authchunks __user *p = (void __user *)optval;
5500 struct sctp_authchunks val; 5498 struct sctp_authchunks val;
5501 struct sctp_association *asoc; 5499 struct sctp_association *asoc;
@@ -5503,7 +5501,7 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len,
5503 u32 num_chunks = 0; 5501 u32 num_chunks = 0;
5504 char __user *to; 5502 char __user *to;
5505 5503
5506 if (!net->sctp.auth_enable) 5504 if (!ep->auth_enable)
5507 return -EACCES; 5505 return -EACCES;
5508 5506
5509 if (len < sizeof(struct sctp_authchunks)) 5507 if (len < sizeof(struct sctp_authchunks))
@@ -5520,7 +5518,7 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len,
5520 if (asoc) 5518 if (asoc)
5521 ch = (struct sctp_chunks_param *)asoc->c.auth_chunks; 5519 ch = (struct sctp_chunks_param *)asoc->c.auth_chunks;
5522 else 5520 else
5523 ch = sctp_sk(sk)->ep->auth_chunk_list; 5521 ch = ep->auth_chunk_list;
5524 5522
5525 if (!ch) 5523 if (!ch)
5526 goto num; 5524 goto num;
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
index 35c8923b5554..c82fdc1eab7c 100644
--- a/net/sctp/sysctl.c
+++ b/net/sctp/sysctl.c
@@ -64,6 +64,9 @@ static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
64static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write, 64static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
65 void __user *buffer, size_t *lenp, 65 void __user *buffer, size_t *lenp,
66 loff_t *ppos); 66 loff_t *ppos);
67static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
68 void __user *buffer, size_t *lenp,
69 loff_t *ppos);
67 70
68static struct ctl_table sctp_table[] = { 71static struct ctl_table sctp_table[] = {
69 { 72 {
@@ -266,7 +269,7 @@ static struct ctl_table sctp_net_table[] = {
266 .data = &init_net.sctp.auth_enable, 269 .data = &init_net.sctp.auth_enable,
267 .maxlen = sizeof(int), 270 .maxlen = sizeof(int),
268 .mode = 0644, 271 .mode = 0644,
269 .proc_handler = proc_dointvec, 272 .proc_handler = proc_sctp_do_auth,
270 }, 273 },
271 { 274 {
272 .procname = "addr_scope_policy", 275 .procname = "addr_scope_policy",
@@ -400,6 +403,37 @@ static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
400 return ret; 403 return ret;
401} 404}
402 405
406static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
407 void __user *buffer, size_t *lenp,
408 loff_t *ppos)
409{
410 struct net *net = current->nsproxy->net_ns;
411 struct ctl_table tbl;
412 int new_value, ret;
413
414 memset(&tbl, 0, sizeof(struct ctl_table));
415 tbl.maxlen = sizeof(unsigned int);
416
417 if (write)
418 tbl.data = &new_value;
419 else
420 tbl.data = &net->sctp.auth_enable;
421
422 ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
423
424 if (write) {
425 struct sock *sk = net->sctp.ctl_sock;
426
427 net->sctp.auth_enable = new_value;
428 /* Update the value in the control socket */
429 lock_sock(sk);
430 sctp_sk(sk)->ep->auth_enable = new_value;
431 release_sock(sk);
432 }
433
434 return ret;
435}
436
403int sctp_sysctl_net_register(struct net *net) 437int sctp_sysctl_net_register(struct net *net)
404{ 438{
405 struct ctl_table *table = sctp_net_table; 439 struct ctl_table *table = sctp_net_table;
diff --git a/net/socket.c b/net/socket.c
index 1b1e7e6a960f..abf56b2a14f9 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1880,8 +1880,8 @@ out:
1880 * Receive a datagram from a socket. 1880 * Receive a datagram from a socket.
1881 */ 1881 */
1882 1882
1883asmlinkage long sys_recv(int fd, void __user *ubuf, size_t size, 1883SYSCALL_DEFINE4(recv, int, fd, void __user *, ubuf, size_t, size,
1884 unsigned int flags) 1884 unsigned int, flags)
1885{ 1885{
1886 return sys_recvfrom(fd, ubuf, size, flags, NULL, NULL); 1886 return sys_recvfrom(fd, ubuf, size, flags, NULL, NULL);
1887} 1887}