[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <a4532ca7-fee8-486a-9c5f-6fccb6de7b40@oracle.com>
Date: Sat, 30 Aug 2025 00:09:11 +0530
From: ALOK TIWARI <alok.a.tiwari@...cle.com>
To: Daniel Jurgens <danielj@...dia.com>, netdev@...r.kernel.org,
mst@...hat.com, jasowang@...hat.com, alex.williamson@...hat.com,
virtualization@...ts.linux.dev, pabeni@...hat.com
Cc: parav@...dia.com, shshitrit@...dia.com, yohadt@...dia.com
Subject: Re: [PATCH net-next 06/11] virtio_net: Implement layer 2 ethtool flow
rules
> +static void calculate_flow_sizes(struct ethtool_rx_flow_spec *fs,
> + size_t *key_size, size_t *classifier_size,
> + int *num_hdrs)
> +{
> + *num_hdrs = 1;
> + *key_size = sizeof(struct ethhdr);
> + /*
> + * The classifier size is the size of the classifier header, a selector
> + * header for each type of header in the match critea, and each header
typo critea -> criteria
> + * providing the mask for matching against.
> + */
> + *classifier_size = *key_size +
> + sizeof(struct virtio_net_resource_obj_ff_classifier) +
> + sizeof(struct virtio_net_ff_selector) * (*num_hdrs);
> +}
> +
> +static void setup_eth_hdr_key_mask(struct virtio_net_ff_selector *selector,
> + u8 *key,
> + const struct ethtool_rx_flow_spec *fs)
> +{
> + struct ethhdr *eth_m = (struct ethhdr *)&selector->mask;
> + struct ethhdr *eth_k = (struct ethhdr *)key;
> +
> + selector->type = VIRTIO_NET_FF_MASK_TYPE_ETH;
> + selector->length = sizeof(struct ethhdr);
> +
> + memcpy(eth_m, &fs->m_u.ether_spec, sizeof(*eth_m));
> + memcpy(eth_k, &fs->h_u.ether_spec, sizeof(*eth_k));
> +}
> +
> +static int
> +validate_classifier_selectors(struct virtnet_ff *ff,
> + struct virtio_net_resource_obj_ff_classifier *classifier,
> + int num_hdrs)
> +{
> + struct virtio_net_ff_selector *selector = classifier->selectors;
> +
> + for (int i = 0; i < num_hdrs; i++) {
> + if (!validate_mask(ff, selector))
> + return -EINVAL;
> +
> + selector = (struct virtio_net_ff_selector *)(((u8 *)selector) +
> + sizeof(*selector) + selector->length);
> + }
> +
> + return 0;
> +}
> +
> +static int build_and_insert(struct virtnet_ff *ff,
> + struct virtnet_ethtool_rule *eth_rule)
> +{
> + struct virtio_net_resource_obj_ff_classifier *classifier;
> + struct ethtool_rx_flow_spec *fs = ð_rule->flow_spec;
> + struct virtio_net_ff_selector *selector;
> + struct virtnet_classifier *c;
> + size_t classifier_size;
> + size_t key_size;
> + int num_hdrs;
> + u8 *key;
> + int err;
> +
> + calculate_flow_sizes(fs, &key_size, &classifier_size, &num_hdrs);
> +
> + key = kzalloc(key_size, GFP_KERNEL);
> + if (!key)
> + return -ENOMEM;
> +
> + /*
> + * virio_net_ff_obj_ff_classifier is already included in the
virio_net_ff_obj_ff_classifier -> virtio_net_ff_obj_ff_classifier
> + * classifier_size.
> + */
> + c = kzalloc(classifier_size +
> + sizeof(struct virtnet_classifier) -
> + sizeof(struct virtio_net_resource_obj_ff_classifier),
> + GFP_KERNEL);
> + if (!c)
> + return -ENOMEM;
kfree(key) before returning -ENOMEM
> +
> + c->size = classifier_size;
> + classifier = &c->classifier;
> + classifier->count = num_hdrs;
> + selector = &classifier->selectors[0];
> +
> + setup_eth_hdr_key_mask(selector, key, fs);
> +
> + err = validate_classifier_selectors(ff, classifier, num_hdrs);
> + if (err)
> + goto err_key;
> +
> + err = setup_classifier(ff, c);
> + if (err)
> + goto err_classifier;
> +
> + err = insert_rule(ff, eth_rule, c->id, key, key_size);
> + if (err) {
> + destroy_classifier(ff, c->id);
> + goto err_key;
> + }
> +
> + return 0;
> +
> +err_classifier:
> + kfree(c);
> +err_key:
> + kfree(key);
> +
> + return err;
> +}
> +
Thanks,
Alok
Powered by blists - more mailing lists