* remove netdev_sk_get_lowest_dev() from net/core * move get_netdev_for_sock() from net/tls to net/core * update existing users in net/tls/tls_device.c get_netdev_for_sock() is a utility that is used to obtain the net_device structure from a connected socket. Later patches will use this for nvme-tcp DDP and DDP DDGST offloads. Suggested-by: Christoph Hellwig Signed-off-by: Ben Ben-Ishay Signed-off-by: Shai Malin Signed-off-by: Aurelien Aptel Reviewed-by: Sagi Grimberg --- include/linux/netdevice.h | 5 +++-- net/core/dev.c | 32 ++++++++++++++++++++------------ net/tls/tls_device.c | 31 +++++++++---------------------- 3 files changed, 32 insertions(+), 36 deletions(-) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index fe510ba65c7b..f6adc0b7d5b4 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -3400,8 +3400,9 @@ void free_netdev(struct net_device *dev); struct net_device *netdev_get_xmit_slave(struct net_device *dev, struct sk_buff *skb, bool all_slaves); -struct net_device *netdev_sk_get_lowest_dev(struct net_device *dev, - struct sock *sk); +struct net_device *get_netdev_for_sock(struct sock *sk, + netdevice_tracker *tracker, + gfp_t gfp); struct net_device *dev_get_by_index(struct net *net, int ifindex); struct net_device *__dev_get_by_index(struct net *net, int ifindex); struct net_device *netdev_get_by_index(struct net *net, int ifindex, diff --git a/net/core/dev.c b/net/core/dev.c index 7ee808eb068e..9dc206f3d1c1 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -9137,27 +9137,35 @@ static struct net_device *netdev_sk_get_lower_dev(struct net_device *dev, } /** - * netdev_sk_get_lowest_dev - Get the lowest device in chain given device and socket - * @dev: device + * get_netdev_for_sock - Get the lowest device in socket * @sk: the socket + * @tracker: tracking object for the acquired reference + * @gfp: allocation flags for the tracker * - * %NULL is returned if no lower device is found. + * Assumes that the socket is already connected. + * Returns the lower device or %NULL if no lower device is found. */ - -struct net_device *netdev_sk_get_lowest_dev(struct net_device *dev, - struct sock *sk) +struct net_device *get_netdev_for_sock(struct sock *sk, + netdevice_tracker *tracker, + gfp_t gfp) { - struct net_device *lower; + struct dst_entry *dst = sk_dst_get(sk); + struct net_device *dev, *lower; - lower = netdev_sk_get_lower_dev(dev, sk); - while (lower) { + if (unlikely(!dst)) + return NULL; + + dev = dst->dev; + while ((lower = netdev_sk_get_lower_dev(dev, sk))) dev = lower; - lower = netdev_sk_get_lower_dev(dev, sk); - } + if (is_vlan_dev(dev)) + dev = vlan_dev_real_dev(dev); + netdev_hold(dev, tracker, gfp); + dst_release(dst); return dev; } -EXPORT_SYMBOL(netdev_sk_get_lowest_dev); +EXPORT_SYMBOL_GPL(get_netdev_for_sock); static void netdev_adjacent_add_links(struct net_device *dev) { diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c index f672a62a9a52..150410ee2c6c 100644 --- a/net/tls/tls_device.c +++ b/net/tls/tls_device.c @@ -120,22 +120,6 @@ static void tls_device_queue_ctx_destruction(struct tls_context *ctx) tls_device_free_ctx(ctx); } -/* We assume that the socket is already connected */ -static struct net_device *get_netdev_for_sock(struct sock *sk) -{ - struct dst_entry *dst = sk_dst_get(sk); - struct net_device *netdev = NULL; - - if (likely(dst)) { - netdev = netdev_sk_get_lowest_dev(dst->dev, sk); - dev_hold(netdev); - } - - dst_release(dst); - - return netdev; -} - static void destroy_record(struct tls_record_info *record) { int i; @@ -1060,6 +1044,7 @@ int tls_set_device_offload(struct sock *sk) struct tls_offload_context_tx *offload_ctx; const struct tls_cipher_desc *cipher_desc; struct tls_crypto_info *crypto_info; + netdevice_tracker netdev_tracker; struct tls_prot_info *prot; struct net_device *netdev; struct tls_context *ctx; @@ -1072,7 +1057,7 @@ int tls_set_device_offload(struct sock *sk) if (ctx->priv_ctx_tx) return -EEXIST; - netdev = get_netdev_for_sock(sk); + netdev = get_netdev_for_sock(sk, &netdev_tracker, GFP_KERNEL); if (!netdev) { pr_err_ratelimited("%s: netdev not found\n", __func__); return -EINVAL; @@ -1166,7 +1151,7 @@ int tls_set_device_offload(struct sock *sk) * by the netdev's xmit function. */ smp_store_release(&sk->sk_validate_xmit_skb, tls_validate_xmit_skb); - dev_put(netdev); + netdev_put(netdev, &netdev_tracker); return 0; @@ -1180,7 +1165,7 @@ int tls_set_device_offload(struct sock *sk) free_marker_record: kfree(start_marker_record); release_netdev: - dev_put(netdev); + netdev_put(netdev, &netdev_tracker); return rc; } @@ -1188,13 +1173,15 @@ int tls_set_device_offload_rx(struct sock *sk, struct tls_context *ctx) { struct tls12_crypto_info_aes_gcm_128 *info; struct tls_offload_context_rx *context; + netdevice_tracker netdev_tracker; struct net_device *netdev; + int rc = 0; if (ctx->crypto_recv.info.version != TLS_1_2_VERSION) return -EOPNOTSUPP; - netdev = get_netdev_for_sock(sk); + netdev = get_netdev_for_sock(sk, &netdev_tracker, GFP_KERNEL); if (!netdev) { pr_err_ratelimited("%s: netdev not found\n", __func__); return -EINVAL; @@ -1243,7 +1230,7 @@ int tls_set_device_offload_rx(struct sock *sk, struct tls_context *ctx) tls_device_attach(ctx, sk, netdev); up_read(&device_offload_lock); - dev_put(netdev); + netdev_put(netdev, &netdev_tracker); return 0; @@ -1256,7 +1243,7 @@ int tls_set_device_offload_rx(struct sock *sk, struct tls_context *ctx) release_lock: up_read(&device_offload_lock); release_netdev: - dev_put(netdev); + netdev_put(netdev, &netdev_tracker); return rc; } -- 2.34.1