--- zzzz-none-000/linux-3.10.107/net/core/dev_ioctl.c 2017-06-27 09:49:32.000000000 +0000 +++ vr9-7490-729/linux-3.10.107/net/core/dev_ioctl.c 2021-11-10 11:53:56.000000000 +0000 @@ -326,6 +326,11 @@ cmd == SIOCSMIIREG || cmd == SIOCBRADDIF || cmd == SIOCBRDELIF || +#ifdef CONFIG_IFX_IGMP_SNOOPING + cmd == SIOCBRADDMGREC || + cmd == SIOCBRDELMGREC || + cmd == SIOCBRSETROUTERPORT || +#endif cmd == SIOCSHWTSTAMP || cmd == SIOCWANDEV) { err = -EOPNOTSUPP; @@ -354,6 +359,7 @@ void dev_load(struct net *net, const char *name) { +#ifdef CONFIG_NET_DEV_LOAD struct net_device *dev; int no_module; @@ -369,6 +375,7 @@ pr_warn("Loading kernel module for a network device with CAP_SYS_MODULE (deprecated). Use CAP_NET_ADMIN and alias netdev-%s instead.\n", name); } +#endif /*--- #ifdef CONFIG_NET_DEV_LOAD ---*/ } EXPORT_SYMBOL(dev_load); @@ -377,6 +384,38 @@ * 'doing' part of this is dev_ifsioc above. */ +void release_offload_lock(int in_offload_lock) +{ +#ifdef CONFIG_AVM_ENHANCED + if (in_offload_lock) + rtnl_offload_read_unlock(); +#endif +} + +int acquire_offload_lock(struct net *net, const char *name){ + int need_lock = 0; +#ifdef CONFIG_AVM_ENHANCED + struct net_device *dev; + + read_lock(&dev_base_lock); + dev = __dev_get_by_name(net, name); + need_lock = ( dev && (dev->priv_flags & IFF_AVM_WLAN_OFFLOAD_DEVICE)); + read_unlock(&dev_base_lock); + + if (need_lock){ + rtnl_offload_read_lock(); + /* + * now we have to wait for for wasp device to become completely functional + * queue_state: + * - dev->flags: IFF_MULTICAST, IFF_BROADCAST, IFF_UP + * - dev->state: __LINK_STATE_START, __LINK_STATE_PRESENT + */ + wait_for_link_to_offload_cpu(); + } +#endif + return need_lock; +} + /** * dev_ioctl - network device ioctl * @net: the applicable net namespace @@ -394,6 +433,7 @@ struct ifreq ifr; int ret; char *colon; + int in_offload_lock = 0; /* One special case: SIOCGIFCONF takes ifconf argument and requires shared lock, because it sleeps writing @@ -438,9 +478,11 @@ case SIOCGIFINDEX: case SIOCGIFTXQLEN: dev_load(net, ifr.ifr_name); + in_offload_lock = acquire_offload_lock(net, ifr.ifr_name); rcu_read_lock(); ret = dev_ifsioc_locked(net, &ifr, cmd); rcu_read_unlock(); + release_offload_lock(in_offload_lock); if (!ret) { if (colon) *colon = ':'; @@ -452,9 +494,11 @@ case SIOCETHTOOL: dev_load(net, ifr.ifr_name); + in_offload_lock = acquire_offload_lock(net, ifr.ifr_name); rtnl_lock(); ret = dev_ethtool(net, &ifr); rtnl_unlock(); + release_offload_lock(in_offload_lock); if (!ret) { if (colon) *colon = ':'; @@ -476,9 +520,11 @@ if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) return -EPERM; dev_load(net, ifr.ifr_name); + in_offload_lock = acquire_offload_lock(net, ifr.ifr_name); rtnl_lock(); ret = dev_ifsioc(net, &ifr, cmd); rtnl_unlock(); + release_offload_lock(in_offload_lock); if (!ret) { if (colon) *colon = ':'; @@ -527,9 +573,11 @@ case SIOCBONDSLAVEINFOQUERY: case SIOCBONDINFOQUERY: dev_load(net, ifr.ifr_name); + in_offload_lock = acquire_offload_lock(net, ifr.ifr_name); rtnl_lock(); ret = dev_ifsioc(net, &ifr, cmd); rtnl_unlock(); + release_offload_lock(in_offload_lock); return ret; case SIOCGIFMEM: @@ -549,17 +597,23 @@ (cmd >= SIOCDEVPRIVATE && cmd <= SIOCDEVPRIVATE + 15)) { dev_load(net, ifr.ifr_name); + in_offload_lock = acquire_offload_lock(net, ifr.ifr_name); rtnl_lock(); ret = dev_ifsioc(net, &ifr, cmd); rtnl_unlock(); + release_offload_lock(in_offload_lock); if (!ret && copy_to_user(arg, &ifr, sizeof(struct ifreq))) ret = -EFAULT; return ret; } /* Take care of Wireless Extensions */ - if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) - return wext_handle_ioctl(net, &ifr, cmd, arg); + if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST){ + in_offload_lock = acquire_offload_lock(net, ifr.ifr_name); + ret = wext_handle_ioctl(net, &ifr, cmd, arg); + release_offload_lock(in_offload_lock); + return ret; + } return -ENOTTY; } }