Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net: add a common function to compute features for upper devices

Some high level software drivers need to compute features from lower
devices. But each has their own implementations and may lost some
feature compute. Let's use one common function to compute features
for kinds of these devices.

The new helper uses the current bond implementation as the reference
one, as the latter already handles all the relevant aspects: netdev
features, TSO limits and dst retention.

Suggested-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Link: https://patch.msgid.link/20251017034155.61990-2-liuhangbin@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Hangbin Liu and committed by
Jakub Kicinski
28098def 0364ca33

+107
+18
include/linux/netdev_features.h
··· 255 255 NETIF_F_GSO_UDP_TUNNEL | \ 256 256 NETIF_F_GSO_UDP_TUNNEL_CSUM) 257 257 258 + /* virtual device features */ 259 + #define MASTER_UPPER_DEV_VLAN_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \ 260 + NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE | \ 261 + NETIF_F_GSO_ENCAP_ALL | \ 262 + NETIF_F_HIGHDMA | NETIF_F_LRO) 263 + 264 + #define MASTER_UPPER_DEV_ENC_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \ 265 + NETIF_F_RXCSUM | NETIF_F_GSO_SOFTWARE | \ 266 + NETIF_F_GSO_PARTIAL) 267 + 268 + #define MASTER_UPPER_DEV_MPLS_FEATURES (NETIF_F_HW_CSUM | NETIF_F_SG | \ 269 + NETIF_F_GSO_SOFTWARE) 270 + 271 + #define MASTER_UPPER_DEV_XFRM_FEATURES (NETIF_F_HW_ESP | NETIF_F_HW_ESP_TX_CSUM | \ 272 + NETIF_F_GSO_ESP) 273 + 274 + #define MASTER_UPPER_DEV_GSO_PARTIAL_FEATURES (NETIF_F_GSO_ESP) 275 + 258 276 static inline netdev_features_t netdev_base_features(netdev_features_t features) 259 277 { 260 278 features &= ~NETIF_F_ONE_FOR_ALL;
+1
include/linux/netdevice.h
··· 5304 5304 int __netdev_update_features(struct net_device *dev); 5305 5305 void netdev_update_features(struct net_device *dev); 5306 5306 void netdev_change_features(struct net_device *dev); 5307 + void netdev_compute_master_upper_features(struct net_device *dev, bool update_header); 5307 5308 5308 5309 void netif_stacked_transfer_operstate(const struct net_device *rootdev, 5309 5310 struct net_device *dev);
+88
net/core/dev.c
··· 12693 12693 } 12694 12694 EXPORT_SYMBOL(netdev_increment_features); 12695 12695 12696 + /** 12697 + * netdev_compute_master_upper_features - compute feature from lowers 12698 + * @dev: the upper device 12699 + * @update_header: whether to update upper device's header_len/headroom/tailroom 12700 + * 12701 + * Recompute the upper device's feature based on all lower devices. 12702 + */ 12703 + void netdev_compute_master_upper_features(struct net_device *dev, bool update_header) 12704 + { 12705 + unsigned int dst_release_flag = IFF_XMIT_DST_RELEASE | IFF_XMIT_DST_RELEASE_PERM; 12706 + netdev_features_t gso_partial_features = MASTER_UPPER_DEV_GSO_PARTIAL_FEATURES; 12707 + netdev_features_t xfrm_features = MASTER_UPPER_DEV_XFRM_FEATURES; 12708 + netdev_features_t mpls_features = MASTER_UPPER_DEV_MPLS_FEATURES; 12709 + netdev_features_t vlan_features = MASTER_UPPER_DEV_VLAN_FEATURES; 12710 + netdev_features_t enc_features = MASTER_UPPER_DEV_ENC_FEATURES; 12711 + unsigned short max_header_len = ETH_HLEN; 12712 + unsigned int tso_max_size = TSO_MAX_SIZE; 12713 + unsigned short max_headroom = 0; 12714 + unsigned short max_tailroom = 0; 12715 + u16 tso_max_segs = TSO_MAX_SEGS; 12716 + struct net_device *lower_dev; 12717 + struct list_head *iter; 12718 + 12719 + mpls_features = netdev_base_features(mpls_features); 12720 + vlan_features = netdev_base_features(vlan_features); 12721 + enc_features = netdev_base_features(enc_features); 12722 + 12723 + netdev_for_each_lower_dev(dev, lower_dev, iter) { 12724 + gso_partial_features = netdev_increment_features(gso_partial_features, 12725 + lower_dev->gso_partial_features, 12726 + MASTER_UPPER_DEV_GSO_PARTIAL_FEATURES); 12727 + 12728 + vlan_features = netdev_increment_features(vlan_features, 12729 + lower_dev->vlan_features, 12730 + MASTER_UPPER_DEV_VLAN_FEATURES); 12731 + 12732 + enc_features = netdev_increment_features(enc_features, 12733 + lower_dev->hw_enc_features, 12734 + MASTER_UPPER_DEV_ENC_FEATURES); 12735 + 12736 + if (IS_ENABLED(CONFIG_XFRM_OFFLOAD)) 12737 + xfrm_features = netdev_increment_features(xfrm_features, 12738 + lower_dev->hw_enc_features, 12739 + MASTER_UPPER_DEV_XFRM_FEATURES); 12740 + 12741 + mpls_features = netdev_increment_features(mpls_features, 12742 + lower_dev->mpls_features, 12743 + MASTER_UPPER_DEV_MPLS_FEATURES); 12744 + 12745 + dst_release_flag &= lower_dev->priv_flags; 12746 + 12747 + if (update_header) { 12748 + max_header_len = max(max_header_len, lower_dev->hard_header_len); 12749 + max_headroom = max(max_headroom, lower_dev->needed_headroom); 12750 + max_tailroom = max(max_tailroom, lower_dev->needed_tailroom); 12751 + } 12752 + 12753 + tso_max_size = min(tso_max_size, lower_dev->tso_max_size); 12754 + tso_max_segs = min(tso_max_segs, lower_dev->tso_max_segs); 12755 + } 12756 + 12757 + dev->gso_partial_features = gso_partial_features; 12758 + dev->vlan_features = vlan_features; 12759 + dev->hw_enc_features = enc_features | NETIF_F_GSO_ENCAP_ALL | 12760 + NETIF_F_HW_VLAN_CTAG_TX | 12761 + NETIF_F_HW_VLAN_STAG_TX; 12762 + if (IS_ENABLED(CONFIG_XFRM_OFFLOAD)) 12763 + dev->hw_enc_features |= xfrm_features; 12764 + dev->mpls_features = mpls_features; 12765 + 12766 + dev->priv_flags &= ~IFF_XMIT_DST_RELEASE; 12767 + if ((dev->priv_flags & IFF_XMIT_DST_RELEASE_PERM) && 12768 + dst_release_flag == (IFF_XMIT_DST_RELEASE | IFF_XMIT_DST_RELEASE_PERM)) 12769 + dev->priv_flags |= IFF_XMIT_DST_RELEASE; 12770 + 12771 + if (update_header) { 12772 + dev->hard_header_len = max_header_len; 12773 + dev->needed_headroom = max_headroom; 12774 + dev->needed_tailroom = max_tailroom; 12775 + } 12776 + 12777 + netif_set_tso_max_segs(dev, tso_max_segs); 12778 + netif_set_tso_max_size(dev, tso_max_size); 12779 + 12780 + netdev_change_features(dev); 12781 + } 12782 + EXPORT_SYMBOL(netdev_compute_master_upper_features); 12783 + 12696 12784 static struct hlist_head * __net_init netdev_create_hash(void) 12697 12785 { 12698 12786 int i;