On Wed, Nov 19, 2025 at 01:15:20PM -0600, Daniel Jurgens wrote:
> Add support for IP_USER type rules from ethtool.
> 
> Example:
> $ ethtool -U ens9 flow-type ip4 src-ip 192.168.51.101 action -1
> Added rule with ID 1
> 
> The example rule will drop packets with the source IP specified.
> 
> Signed-off-by: Daniel Jurgens <[email protected]>
> Reviewed-by: Parav Pandit <[email protected]>
> Reviewed-by: Shahar Shitrit <[email protected]>
> Reviewed-by: Xuan Zhuo <[email protected]>
> ---
> v4:
>     - Fixed bug in protocol check of parse_ip4
>     - (u8 *) to (void *) casting.
>     - Alignment issues.
> 
> v12
>     - refactor calculate_flow_sizes to remove goto. MST
>     - refactor build_and_insert to remove goto validate. MST
>     - Move parse_ip4 l3_mask check to TCP/UDP patch. MST
>     - Check saddr/daddr mask before copying in parse_ip4. MST
>     - Remove tos check in setup_ip_key_mask.

So if user attempts to set a filter by tos now, what blocks it?
because parse_ip4 seems to ignore it ...

>     - check l4_4_bytes mask is 0 in setup_ip_key_mask. MST
>     - changed return of setup_ip_key_mask to -EINVAL.
>     - BUG_ON if key overflows u8 size in calculate_flow_sizes. MST
> ---
> ---
>  drivers/net/virtio_net.c | 119 +++++++++++++++++++++++++++++++++++++--
>  1 file changed, 113 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
> index 5e49cd78904f..b0b9972fe624 100644
> --- a/drivers/net/virtio_net.c
> +++ b/drivers/net/virtio_net.c
> @@ -5894,6 +5894,34 @@ static bool validate_eth_mask(const struct virtnet_ff 
> *ff,
>       return true;
>  }
>  
> +static bool validate_ip4_mask(const struct virtnet_ff *ff,
> +                           const struct virtio_net_ff_selector *sel,
> +                           const struct virtio_net_ff_selector *sel_cap)
> +{
> +     bool partial_mask = !!(sel_cap->flags & 
> VIRTIO_NET_FF_MASK_F_PARTIAL_MASK);
> +     struct iphdr *cap, *mask;
> +
> +     cap = (struct iphdr *)&sel_cap->mask;
> +     mask = (struct iphdr *)&sel->mask;
> +
> +     if (mask->saddr &&
> +         !check_mask_vs_cap(&mask->saddr, &cap->saddr,
> +                            sizeof(__be32), partial_mask))
> +             return false;
> +
> +     if (mask->daddr &&
> +         !check_mask_vs_cap(&mask->daddr, &cap->daddr,
> +                            sizeof(__be32), partial_mask))
> +             return false;
> +
> +     if (mask->protocol &&
> +         !check_mask_vs_cap(&mask->protocol, &cap->protocol,
> +                            sizeof(u8), partial_mask))
> +             return false;
> +
> +     return true;
> +}
> +
>  static bool validate_mask(const struct virtnet_ff *ff,
>                         const struct virtio_net_ff_selector *sel)
>  {
> @@ -5905,11 +5933,36 @@ static bool validate_mask(const struct virtnet_ff *ff,
>       switch (sel->type) {
>       case VIRTIO_NET_FF_MASK_TYPE_ETH:
>               return validate_eth_mask(ff, sel, sel_cap);
> +
> +     case VIRTIO_NET_FF_MASK_TYPE_IPV4:
> +             return validate_ip4_mask(ff, sel, sel_cap);
>       }
>  
>       return false;
>  }
>  
> +static void parse_ip4(struct iphdr *mask, struct iphdr *key,
> +                   const struct ethtool_rx_flow_spec *fs)
> +{
> +     const struct ethtool_usrip4_spec *l3_mask = &fs->m_u.usr_ip4_spec;
> +     const struct ethtool_usrip4_spec *l3_val  = &fs->h_u.usr_ip4_spec;
> +
> +     if (mask->saddr) {
> +             mask->saddr = l3_mask->ip4src;
> +             key->saddr = l3_val->ip4src;
> +     }

So if mast->saddr is already set you over-write it?

But what sets it? Don't you really mean l3_mask->ip4src maybe?



> +
> +     if (mask->daddr) {
> +             mask->daddr = l3_mask->ip4dst;
> +             key->daddr = l3_val->ip4dst;
> +     }
> +}


Same question.




Reply via email to