diff options
Diffstat (limited to 'net/core/xdp.c')
| -rw-r--r-- | net/core/xdp.c | 48 | 
1 files changed, 38 insertions, 10 deletions
diff --git a/net/core/xdp.c b/net/core/xdp.c index 8c92fc553317..fb85aca81961 100644 --- a/net/core/xdp.c +++ b/net/core/xdp.c @@ -720,7 +720,10 @@ __diag_ignore_all("-Wmissing-prototypes",   * @ctx: XDP context pointer.   * @timestamp: Return value pointer.   * - * Returns 0 on success or ``-errno`` on error. + * Return: + * * Returns 0 on success or ``-errno`` on error. + * * ``-EOPNOTSUPP`` : means device driver does not implement kfunc + * * ``-ENODATA``    : means no RX-timestamp available for this frame   */  __bpf_kfunc int bpf_xdp_metadata_rx_timestamp(const struct xdp_md *ctx, u64 *timestamp)  { @@ -731,10 +734,21 @@ __bpf_kfunc int bpf_xdp_metadata_rx_timestamp(const struct xdp_md *ctx, u64 *tim   * bpf_xdp_metadata_rx_hash - Read XDP frame RX hash.   * @ctx: XDP context pointer.   * @hash: Return value pointer. + * @rss_type: Return value pointer for RSS type.   * - * Returns 0 on success or ``-errno`` on error. + * The RSS hash type (@rss_type) specifies what portion of packet headers NIC + * hardware used when calculating RSS hash value.  The RSS type can be decoded + * via &enum xdp_rss_hash_type either matching on individual L3/L4 bits + * ``XDP_RSS_L*`` or by combined traditional *RSS Hashing Types* + * ``XDP_RSS_TYPE_L*``. + * + * Return: + * * Returns 0 on success or ``-errno`` on error. + * * ``-EOPNOTSUPP`` : means device driver doesn't implement kfunc + * * ``-ENODATA``    : means no RX-hash available for this frame   */ -__bpf_kfunc int bpf_xdp_metadata_rx_hash(const struct xdp_md *ctx, u32 *hash) +__bpf_kfunc int bpf_xdp_metadata_rx_hash(const struct xdp_md *ctx, u32 *hash, +					 enum xdp_rss_hash_type *rss_type)  {  	return -EOPNOTSUPP;  } @@ -774,20 +788,34 @@ static int __init xdp_metadata_init(void)  }  late_initcall(xdp_metadata_init); +void xdp_set_features_flag(struct net_device *dev, xdp_features_t val) +{ +	val &= NETDEV_XDP_ACT_MASK; +	if (dev->xdp_features == val) +		return; + +	dev->xdp_features = val; + +	if (dev->reg_state == NETREG_REGISTERED) +		call_netdevice_notifiers(NETDEV_XDP_FEAT_CHANGE, dev); +} +EXPORT_SYMBOL_GPL(xdp_set_features_flag); +  void xdp_features_set_redirect_target(struct net_device *dev, bool support_sg)  { -	dev->xdp_features |= NETDEV_XDP_ACT_NDO_XMIT; -	if (support_sg) -		dev->xdp_features |= NETDEV_XDP_ACT_NDO_XMIT_SG; +	xdp_features_t val = (dev->xdp_features | NETDEV_XDP_ACT_NDO_XMIT); -	call_netdevice_notifiers(NETDEV_XDP_FEAT_CHANGE, dev); +	if (support_sg) +		val |= NETDEV_XDP_ACT_NDO_XMIT_SG; +	xdp_set_features_flag(dev, val);  }  EXPORT_SYMBOL_GPL(xdp_features_set_redirect_target);  void xdp_features_clear_redirect_target(struct net_device *dev)  { -	dev->xdp_features &= ~(NETDEV_XDP_ACT_NDO_XMIT | -			       NETDEV_XDP_ACT_NDO_XMIT_SG); -	call_netdevice_notifiers(NETDEV_XDP_FEAT_CHANGE, dev); +	xdp_features_t val = dev->xdp_features; + +	val &= ~(NETDEV_XDP_ACT_NDO_XMIT | NETDEV_XDP_ACT_NDO_XMIT_SG); +	xdp_set_features_flag(dev, val);  }  EXPORT_SYMBOL_GPL(xdp_features_clear_redirect_target);  |