diff options
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/dev.c | 25 | ||||
-rw-r--r-- | net/core/devlink.c | 148 | ||||
-rw-r--r-- | net/core/ethtool.c | 17 | ||||
-rw-r--r-- | net/core/filter.c | 12 | ||||
-rw-r--r-- | net/core/lwt_bpf.c | 2 | ||||
-rw-r--r-- | net/core/lwtunnel.c | 16 | ||||
-rw-r--r-- | net/core/skbuff.c | 4 | ||||
-rw-r--r-- | net/core/sock.c | 34 |
8 files changed, 129 insertions, 129 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index ecbe419e05ab..2b67f2aa59dd 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -3421,7 +3421,7 @@ static void qdisc_pkt_len_init(struct sk_buff *skb) /* To get more precise estimation of bytes sent on wire, * we add to pkt_len the headers size of all segments */ - if (shinfo->gso_size) { + if (shinfo->gso_size && skb_transport_header_was_set(skb)) { unsigned int hdr_len; u16 gso_segs = shinfo->gso_segs; @@ -7954,6 +7954,25 @@ int dev_change_proto_down(struct net_device *dev, bool proto_down) } EXPORT_SYMBOL(dev_change_proto_down); +/** + * dev_change_proto_down_generic - generic implementation for + * ndo_change_proto_down that sets carrier according to + * proto_down. + * + * @dev: device + * @proto_down: new value + */ +int dev_change_proto_down_generic(struct net_device *dev, bool proto_down) +{ + if (proto_down) + netif_carrier_off(dev); + else + netif_carrier_on(dev); + dev->proto_down = proto_down; + return 0; +} +EXPORT_SYMBOL(dev_change_proto_down_generic); + u32 __dev_xdp_query(struct net_device *dev, bpf_op_t bpf_op, enum bpf_netdev_command cmd) { @@ -8215,7 +8234,7 @@ static netdev_features_t netdev_sync_upper_features(struct net_device *lower, netdev_features_t feature; int feature_bit; - for_each_netdev_feature(&upper_disables, feature_bit) { + for_each_netdev_feature(upper_disables, feature_bit) { feature = __NETIF_F_BIT(feature_bit); if (!(upper->wanted_features & feature) && (features & feature)) { @@ -8235,7 +8254,7 @@ static void netdev_sync_lower_features(struct net_device *upper, netdev_features_t feature; int feature_bit; - for_each_netdev_feature(&upper_disables, feature_bit) { + for_each_netdev_feature(upper_disables, feature_bit) { feature = __NETIF_F_BIT(feature_bit); if (!(features & feature) && (lower->features & feature)) { netdev_dbg(upper, "Disabling feature %pNF on lower dev %s.\n", diff --git a/net/core/devlink.c b/net/core/devlink.c index 04d98550c78c..6515fbec0dcd 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c @@ -723,7 +723,7 @@ static int devlink_port_type_set(struct devlink *devlink, { int err; - if (devlink->ops && devlink->ops->port_type_set) { + if (devlink->ops->port_type_set) { if (port_type == DEVLINK_PORT_TYPE_NOTSET) return -EINVAL; if (port_type == devlink_port->type) @@ -760,7 +760,7 @@ static int devlink_port_split(struct devlink *devlink, u32 port_index, u32 count, struct netlink_ext_ack *extack) { - if (devlink->ops && devlink->ops->port_split) + if (devlink->ops->port_split) return devlink->ops->port_split(devlink, port_index, count, extack); return -EOPNOTSUPP; @@ -786,7 +786,7 @@ static int devlink_port_unsplit(struct devlink *devlink, u32 port_index, struct netlink_ext_ack *extack) { - if (devlink->ops && devlink->ops->port_unsplit) + if (devlink->ops->port_unsplit) return devlink->ops->port_unsplit(devlink, port_index, extack); return -EOPNOTSUPP; } @@ -961,7 +961,7 @@ static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb, if (err) return err; - if (!devlink->ops || !devlink->ops->sb_pool_get) + if (!devlink->ops->sb_pool_get) return -EOPNOTSUPP; msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); @@ -1017,7 +1017,7 @@ static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg, mutex_lock(&devlink_mutex); list_for_each_entry(devlink, &devlink_list, list) { if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) || - !devlink->ops || !devlink->ops->sb_pool_get) + !devlink->ops->sb_pool_get) continue; mutex_lock(&devlink->lock); list_for_each_entry(devlink_sb, &devlink->sb_list, list) { @@ -1046,7 +1046,7 @@ static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index, { const struct devlink_ops *ops = devlink->ops; - if (ops && ops->sb_pool_set) + if (ops->sb_pool_set) return ops->sb_pool_set(devlink, sb_index, pool_index, size, threshold_type); return -EOPNOTSUPP; @@ -1151,7 +1151,7 @@ static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb, if (err) return err; - if (!devlink->ops || !devlink->ops->sb_port_pool_get) + if (!devlink->ops->sb_port_pool_get) return -EOPNOTSUPP; msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); @@ -1213,7 +1213,7 @@ static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg, mutex_lock(&devlink_mutex); list_for_each_entry(devlink, &devlink_list, list) { if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) || - !devlink->ops || !devlink->ops->sb_port_pool_get) + !devlink->ops->sb_port_pool_get) continue; mutex_lock(&devlink->lock); list_for_each_entry(devlink_sb, &devlink->sb_list, list) { @@ -1242,7 +1242,7 @@ static int devlink_sb_port_pool_set(struct devlink_port *devlink_port, { const struct devlink_ops *ops = devlink_port->devlink->ops; - if (ops && ops->sb_port_pool_set) + if (ops->sb_port_pool_set) return ops->sb_port_pool_set(devlink_port, sb_index, pool_index, threshold); return -EOPNOTSUPP; @@ -1355,7 +1355,7 @@ static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb, if (err) return err; - if (!devlink->ops || !devlink->ops->sb_tc_pool_bind_get) + if (!devlink->ops->sb_tc_pool_bind_get) return -EOPNOTSUPP; msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); @@ -1439,7 +1439,7 @@ devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff *msg, mutex_lock(&devlink_mutex); list_for_each_entry(devlink, &devlink_list, list) { if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) || - !devlink->ops || !devlink->ops->sb_tc_pool_bind_get) + !devlink->ops->sb_tc_pool_bind_get) continue; mutex_lock(&devlink->lock); @@ -1471,7 +1471,7 @@ static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port, { const struct devlink_ops *ops = devlink_port->devlink->ops; - if (ops && ops->sb_tc_pool_bind_set) + if (ops->sb_tc_pool_bind_set) return ops->sb_tc_pool_bind_set(devlink_port, sb_index, tc_index, pool_type, pool_index, threshold); @@ -1519,7 +1519,7 @@ static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb, struct devlink_sb *devlink_sb = info->user_ptr[1]; const struct devlink_ops *ops = devlink->ops; - if (ops && ops->sb_occ_snapshot) + if (ops->sb_occ_snapshot) return ops->sb_occ_snapshot(devlink, devlink_sb->index); return -EOPNOTSUPP; } @@ -1531,7 +1531,7 @@ static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb, struct devlink_sb *devlink_sb = info->user_ptr[1]; const struct devlink_ops *ops = devlink->ops; - if (ops && ops->sb_occ_max_clear) + if (ops->sb_occ_max_clear) return ops->sb_occ_max_clear(devlink, devlink_sb->index); return -EOPNOTSUPP; } @@ -1594,13 +1594,9 @@ static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff *skb, struct genl_info *info) { struct devlink *devlink = info->user_ptr[0]; - const struct devlink_ops *ops = devlink->ops; struct sk_buff *msg; int err; - if (!ops) - return -EOPNOTSUPP; - msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) return -ENOMEM; @@ -1625,9 +1621,6 @@ static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff *skb, int err = 0; u16 mode; - if (!ops) - return -EOPNOTSUPP; - if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) { if (!ops->eswitch_mode_set) return -EOPNOTSUPP; @@ -3869,7 +3862,7 @@ static int devlink_nl_cmd_info_get_doit(struct sk_buff *skb, struct sk_buff *msg; int err; - if (!devlink->ops || !devlink->ops->info_get) + if (!devlink->ops->info_get) return -EOPNOTSUPP; msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); @@ -4650,17 +4643,19 @@ devlink_nl_health_reporter_fill(struct sk_buff *msg, if (nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_STATE, reporter->health_state)) goto reporter_nest_cancel; - if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_ERR, + if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT, reporter->error_count, DEVLINK_ATTR_PAD)) goto reporter_nest_cancel; - if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER, + if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT, reporter->recovery_count, DEVLINK_ATTR_PAD)) goto reporter_nest_cancel; - if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD, + if (reporter->ops->recover && + nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD, reporter->graceful_period, DEVLINK_ATTR_PAD)) goto reporter_nest_cancel; - if (nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER, + if (reporter->ops->recover && + nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER, reporter->auto_recover)) goto reporter_nest_cancel; if (reporter->dump_fmsg && @@ -5230,6 +5225,9 @@ struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size) { struct devlink *devlink; + if (WARN_ON(!ops)) + return NULL; + devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL); if (!devlink) return NULL; @@ -5251,6 +5249,7 @@ EXPORT_SYMBOL_GPL(devlink_alloc); * devlink_register - Register devlink instance * * @devlink: devlink + * @dev: parent device */ int devlink_register(struct devlink *devlink, struct device *dev) { @@ -5301,7 +5300,7 @@ EXPORT_SYMBOL_GPL(devlink_free); * * @devlink: devlink * @devlink_port: devlink port - * @port_index + * @port_index: driver-specific numerical identifier of the port * * Register devlink port with provided port index. User can use * any indexing, even hw-related one. devlink_port structure @@ -5631,13 +5630,10 @@ EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister); * * @devlink: devlink * @resource_name: resource's name - * @top_hierarchy: top hierarchy - * @reload_required: reload is required for new configuration to - * apply * @resource_size: resource's size * @resource_id: resource's id - * @parent_reosurce_id: resource's parent id - * @size params: size parameters + * @parent_resource_id: resource's parent id + * @size_params: size parameters */ int devlink_resource_register(struct devlink *devlink, const char *resource_name, @@ -6089,7 +6085,7 @@ __devlink_param_driverinit_value_set(struct devlink *devlink, int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id, union devlink_param_value *init_val) { - if (!devlink->ops || !devlink->ops->reload) + if (!devlink->ops->reload) return -EOPNOTSUPP; return __devlink_param_driverinit_value_get(&devlink->param_list, @@ -6136,7 +6132,7 @@ int devlink_port_param_driverinit_value_get(struct devlink_port *devlink_port, { struct devlink *devlink = devlink_port->devlink; - if (!devlink->ops || !devlink->ops->reload) + if (!devlink->ops->reload) return -EOPNOTSUPP; return __devlink_param_driverinit_value_get(&devlink_port->param_list, @@ -6334,7 +6330,7 @@ EXPORT_SYMBOL_GPL(devlink_region_shapshot_id_get); * Multiple snapshots can be created on a region. * The @snapshot_id should be obtained using the getter function. * - * @devlink_region: devlink region of the snapshot + * @region: devlink region of the snapshot * @data_len: size of snapshot data * @data: snapshot data * @snapshot_id: snapshot id to be created @@ -6395,9 +6391,6 @@ static void __devlink_compat_running_version(struct devlink *devlink, struct sk_buff *msg; int rem, err; - if (!devlink->ops->info_get) - return; - msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); if (!msg) return; @@ -6429,71 +6422,54 @@ free_msg: void devlink_compat_running_version(struct net_device *dev, char *buf, size_t len) { - struct devlink_port *devlink_port; struct devlink *devlink; + dev_hold(dev); + rtnl_unlock(); + mutex_lock(&devlink_mutex); - list_for_each_entry(devlink, &devlink_list, list) { - mutex_lock(&devlink->lock); - list_for_each_entry(devlink_port, &devlink->port_list, list) { - if (devlink_port->type == DEVLINK_PORT_TYPE_ETH && - devlink_port->type_dev == dev) { - __devlink_compat_running_version(devlink, - buf, len); - mutex_unlock(&devlink->lock); - goto out; - } - } - mutex_unlock(&devlink->lock); - } -out: + devlink = netdev_to_devlink(dev); + if (!devlink || !devlink->ops->info_get) + goto unlock_list; + + mutex_lock(&devlink->lock); + __devlink_compat_running_version(devlink, buf, len); + mutex_unlock(&devlink->lock); +unlock_list: mutex_unlock(&devlink_mutex); + + rtnl_lock(); + dev_put(dev); } int devlink_compat_flash_update(struct net_device *dev, const char *file_name) { - struct devlink_port *devlink_port; struct devlink *devlink; + int ret = -EOPNOTSUPP; - mutex_lock(&devlink_mutex); - list_for_each_entry(devlink, &devlink_list, list) { - mutex_lock(&devlink->lock); - list_for_each_entry(devlink_port, &devlink->port_list, list) { - int ret = -EOPNOTSUPP; + dev_hold(dev); + rtnl_unlock(); - if (devlink_port->type != DEVLINK_PORT_TYPE_ETH || - devlink_port->type_dev != dev) - continue; + mutex_lock(&devlink_mutex); + devlink = netdev_to_devlink(dev); + if (!devlink || !devlink->ops->flash_update) + goto unlock_list; - mutex_unlock(&devlink_mutex); - if (devlink->ops->flash_update) - ret = devlink->ops->flash_update(devlink, - file_name, - NULL, NULL); - mutex_unlock(&devlink->lock); - return ret; - } - mutex_unlock(&devlink->lock); - } + mutex_lock(&devlink->lock); + ret = devlink->ops->flash_update(devlink, file_name, NULL, NULL); + mutex_unlock(&devlink->lock); +unlock_list: mutex_unlock(&devlink_mutex); - return -EOPNOTSUPP; -} + rtnl_lock(); + dev_put(dev); -static int __init devlink_module_init(void) -{ - return genl_register_family(&devlink_nl_family); + return ret; } -static void __exit devlink_module_exit(void) +static int __init devlink_init(void) { - genl_unregister_family(&devlink_nl_family); + return genl_register_family(&devlink_nl_family); } -module_init(devlink_module_init); -module_exit(devlink_module_exit); - -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>"); -MODULE_DESCRIPTION("Network physical device Netlink interface"); -MODULE_ALIAS_GENL_FAMILY(DEVLINK_GENL_NAME); +subsys_initcall(devlink_init); diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 1320e8dce559..d4918ffddda8 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -805,11 +805,9 @@ static noinline_for_stack int ethtool_get_drvinfo(struct net_device *dev, if (ops->get_eeprom_len) info.eedump_len = ops->get_eeprom_len(dev); - rtnl_unlock(); if (!info.fw_version[0]) devlink_compat_running_version(dev, info.fw_version, sizeof(info.fw_version)); - rtnl_lock(); if (copy_to_user(useraddr, &info, sizeof(info))) return -EFAULT; @@ -1719,7 +1717,7 @@ static noinline_for_stack int ethtool_set_channels(struct net_device *dev, static int ethtool_get_pauseparam(struct net_device *dev, void __user *useraddr) { - struct ethtool_pauseparam pauseparam = { ETHTOOL_GPAUSEPARAM }; + struct ethtool_pauseparam pauseparam = { .cmd = ETHTOOL_GPAUSEPARAM }; if (!dev->ethtool_ops->get_pauseparam) return -EOPNOTSUPP; @@ -2040,15 +2038,8 @@ static noinline_for_stack int ethtool_flash_device(struct net_device *dev, return -EFAULT; efl.data[ETHTOOL_FLASH_MAX_FILENAME - 1] = 0; - if (!dev->ethtool_ops->flash_device) { - int ret; - - rtnl_unlock(); - ret = devlink_compat_flash_update(dev, efl.data); - rtnl_lock(); - - return ret; - } + if (!dev->ethtool_ops->flash_device) + return devlink_compat_flash_update(dev, efl.data); return dev->ethtool_ops->flash_device(dev, &efl); } @@ -2512,7 +2503,7 @@ static int set_phy_tunable(struct net_device *dev, void __user *useraddr) static int ethtool_get_fecparam(struct net_device *dev, void __user *useraddr) { - struct ethtool_fecparam fecparam = { ETHTOOL_GFECPARAM }; + struct ethtool_fecparam fecparam = { .cmd = ETHTOOL_GFECPARAM }; int rc; if (!dev->ethtool_ops->get_fecparam) diff --git a/net/core/filter.c b/net/core/filter.c index 558ca72f2254..5ceba98069d4 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -2804,8 +2804,7 @@ static int bpf_skb_proto_4_to_6(struct sk_buff *skb) u32 off = skb_mac_header_len(skb); int ret; - /* SCTP uses GSO_BY_FRAGS, thus cannot adjust it. */ - if (skb_is_gso(skb) && unlikely(skb_is_gso_sctp(skb))) + if (!skb_is_gso_tcp(skb)) return -ENOTSUPP; ret = skb_cow(skb, len_diff); @@ -2846,8 +2845,7 @@ static int bpf_skb_proto_6_to_4(struct sk_buff *skb) u32 off = skb_mac_header_len(skb); int ret; - /* SCTP uses GSO_BY_FRAGS, thus cannot adjust it. */ - if (skb_is_gso(skb) && unlikely(skb_is_gso_sctp(skb))) + if (!skb_is_gso_tcp(skb)) return -ENOTSUPP; ret = skb_unclone(skb, GFP_ATOMIC); @@ -2972,8 +2970,7 @@ static int bpf_skb_net_grow(struct sk_buff *skb, u32 len_diff) u32 off = skb_mac_header_len(skb) + bpf_skb_net_base_len(skb); int ret; - /* SCTP uses GSO_BY_FRAGS, thus cannot adjust it. */ - if (skb_is_gso(skb) && unlikely(skb_is_gso_sctp(skb))) + if (!skb_is_gso_tcp(skb)) return -ENOTSUPP; ret = skb_cow(skb, len_diff); @@ -3002,8 +2999,7 @@ static int bpf_skb_net_shrink(struct sk_buff *skb, u32 len_diff) u32 off = skb_mac_header_len(skb) + bpf_skb_net_base_len(skb); int ret; - /* SCTP uses GSO_BY_FRAGS, thus cannot adjust it. */ - if (skb_is_gso(skb) && unlikely(skb_is_gso_sctp(skb))) + if (!skb_is_gso_tcp(skb)) return -ENOTSUPP; ret = skb_unclone(skb, GFP_ATOMIC); diff --git a/net/core/lwt_bpf.c b/net/core/lwt_bpf.c index a5c8c79d468a..cf2f8897ca19 100644 --- a/net/core/lwt_bpf.c +++ b/net/core/lwt_bpf.c @@ -260,7 +260,7 @@ static int bpf_lwt_xmit_reroute(struct sk_buff *skb) err = dst_output(dev_net(skb_dst(skb)->dev), skb->sk, skb); if (unlikely(err)) - goto err; + return err; /* ip[6]_finish_output2 understand LWTUNNEL_XMIT_DONE */ return LWTUNNEL_XMIT_DONE; diff --git a/net/core/lwtunnel.c b/net/core/lwtunnel.c index 0b171756453c..19b557bd294b 100644 --- a/net/core/lwtunnel.c +++ b/net/core/lwtunnel.c @@ -122,18 +122,18 @@ int lwtunnel_build_state(u16 encap_type, ret = -EOPNOTSUPP; rcu_read_lock(); ops = rcu_dereference(lwtun_encaps[encap_type]); - if (likely(ops && ops->build_state && try_module_get(ops->owner))) { + if (likely(ops && ops->build_state && try_module_get(ops->owner))) found = true; + rcu_read_unlock(); + + if (found) { ret = ops->build_state(encap, family, cfg, lws, extack); if (ret) module_put(ops->owner); - } - rcu_read_unlock(); - - /* don't rely on -EOPNOTSUPP to detect match as build_state - * handlers could return it - */ - if (!found) { + } else { + /* don't rely on -EOPNOTSUPP to detect match as build_state + * handlers could return it + */ NL_SET_ERR_MSG_ATTR(extack, encap, "LWT encapsulation type not supported"); } diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 26d848484912..2415d9cb9b89 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -356,6 +356,8 @@ static void *__netdev_alloc_frag(unsigned int fragsz, gfp_t gfp_mask) */ void *netdev_alloc_frag(unsigned int fragsz) { + fragsz = SKB_DATA_ALIGN(fragsz); + return __netdev_alloc_frag(fragsz, GFP_ATOMIC); } EXPORT_SYMBOL(netdev_alloc_frag); @@ -369,6 +371,8 @@ static void *__napi_alloc_frag(unsigned int fragsz, gfp_t gfp_mask) void *napi_alloc_frag(unsigned int fragsz) { + fragsz = SKB_DATA_ALIGN(fragsz); + return __napi_alloc_frag(fragsz, GFP_ATOMIC); } EXPORT_SYMBOL(napi_alloc_frag); diff --git a/net/core/sock.c b/net/core/sock.c index f4b8b78535f8..782343bb925b 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -1108,15 +1108,23 @@ set_rcvbuf: #endif case SO_MAX_PACING_RATE: - if (val != ~0U) + { + unsigned long ulval = (val == ~0U) ? ~0UL : val; + + if (sizeof(ulval) != sizeof(val) && + optlen >= sizeof(ulval) && + get_user(ulval, (unsigned long __user *)optval)) { + ret = -EFAULT; + break; + } + if (ulval != ~0UL) cmpxchg(&sk->sk_pacing_status, SK_PACING_NONE, SK_PACING_NEEDED); - sk->sk_max_pacing_rate = (val == ~0U) ? ~0UL : val; - sk->sk_pacing_rate = min(sk->sk_pacing_rate, - sk->sk_max_pacing_rate); + sk->sk_max_pacing_rate = ulval; + sk->sk_pacing_rate = min(sk->sk_pacing_rate, ulval); break; - + } case SO_INCOMING_CPU: sk->sk_incoming_cpu = val; break; @@ -1211,6 +1219,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname, union { int val; u64 val64; + unsigned long ulval; struct linger ling; struct old_timeval32 tm32; struct __kernel_old_timeval tm; @@ -1456,8 +1465,13 @@ int sock_getsockopt(struct socket *sock, int level, int optname, #endif case SO_MAX_PACING_RATE: - /* 32bit version */ - v.val = min_t(unsigned long, sk->sk_max_pacing_rate, ~0U); + if (sizeof(v.ulval) != sizeof(v.val) && len >= sizeof(v.ulval)) { + lv = sizeof(v.ulval); + v.ulval = sk->sk_max_pacing_rate; + } else { + /* 32bit version */ + v.val = min_t(unsigned long, sk->sk_max_pacing_rate, ~0U); + } break; case SO_INCOMING_CPU: @@ -1865,7 +1879,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority) */ sk_refcnt_debug_inc(newsk); sk_set_socket(newsk, NULL); - newsk->sk_wq = NULL; + RCU_INIT_POINTER(newsk->sk_wq, NULL); if (newsk->sk_prot->sockets_allocated) sk_sockets_allocated_inc(newsk); @@ -2828,11 +2842,11 @@ void sock_init_data(struct socket *sock, struct sock *sk) if (sock) { sk->sk_type = sock->type; - sk->sk_wq = sock->wq; + RCU_INIT_POINTER(sk->sk_wq, sock->wq); sock->sk = sk; sk->sk_uid = SOCK_INODE(sock)->i_uid; } else { - sk->sk_wq = NULL; + RCU_INIT_POINTER(sk->sk_wq, NULL); sk->sk_uid = make_kuid(sock_net(sk)->user_ns, 0); } |