On Thu, Aug 20, 2026 at 7:57 PM Timothy Redaelli via dev <
[email protected]> wrote:

> The 'filter' column of the Mirror table was parsed with
> parse_ofp_exact_flow(), which requires every field that is mentioned to
> be given as an exact value.  Specifications like "ip,nw_src=10.0.0.0/24"
> were therefore rejected, even though the matching side already stores the
> filter as a miniflow plus minimask and unions that mask into the
> megaflow, so partially masked fields work end to end.
>
> Add parse_ofp_flow_match(), which parses a flow specification into a
> 'struct match' using ofp_parse_field(), so each value may carry a mask.
> Use it for the mirror filter.  parse_ofp_exact_flow() is left alone, as
> its other callers do want exact values.
>
> Reported-at: https://github.com/openvswitch/ovs-issues/issues/349
> Reported-at: https://redhat.atlassian.net/browse/FDP-2conntrack: Handle
> FTP buffer overflow during NAT ALG rewrite. 474
> <https://redhat.atlassian.net/browse/FDP-2474>
> Signed-off-by: Timothy Redaelli <[email protected]>
> ---
>  NEWS                           |  3 ++
>  include/openvswitch/ofp-flow.h |  4 +++
>  lib/ofp-flow.c                 | 55 ++++++++++++++++++++++++++++++++++
>  ofproto/ofproto-dpif-mirror.c  | 11 ++++---
>  tests/ofproto-dpif.at          | 43 ++++++++++++++++++++++++++
>  vswitchd/vswitch.xml           |  8 +++--
>  6 files changed, 115 insertions(+), 9 deletions(-)
>
> diff --git a/NEWS b/NEWS
> index de1a030ad..33ab0585b 100644
> --- a/NEWS
> +++ b/NEWS
> @@ -1,5 +1,8 @@
>  Post-v4.0.0
>  --------------------
> +   - ovs-vswitchd:
> +     * Mirror filters now accept masked fields, e.g. "ip,nw_src=
> 10.0.0.0/24"
> +       in the "filter" column of the Mirror table.
>
>
>  v4.0.0 - 17 Aug 2026
> diff --git a/include/openvswitch/ofp-flow.h
> b/include/openvswitch/ofp-flow.h
> index f2223d90b..6c4310b75 100644
> --- a/include/openvswitch/ofp-flow.h
> +++ b/include/openvswitch/ofp-flow.h
> @@ -155,6 +155,10 @@ char *parse_ofp_exact_flow(struct flow *flow, struct
> flow_wildcards *wc,
>                             const struct tun_table *tun_table, const char
> *s,
>                             const struct ofputil_port_map *port_map);
>
> +char *parse_ofp_flow_match(struct match *match,
> +                           const struct tun_table *tun_table, const char
> *s,
> +                           const struct ofputil_port_map *port_map);
> +
>  /* Flow stats or aggregate stats request, independent of protocol. */
>  struct ofputil_flow_stats_request {
>      bool aggregate;             /* Aggregate results? */
> diff --git a/lib/ofp-flow.c b/lib/ofp-flow.c
> index 3bc744f78..26d10012f 100644
> --- a/lib/ofp-flow.c
> +++ b/lib/ofp-flow.c
> @@ -2016,3 +2016,58 @@ exit:
>      }
>      return error;
>  }
> +
> +/* Parses a specification of a flow from 's' into 'match'.  's' must take
> the
> + * form FIELD=VALUE[,FIELD=VALUE]... where each FIELD is the name of an
> + * mf_field.  Unlike parse_ofp_exact_flow(), each VALUE may include a mask
> + * (e.g. "nw_src=10.0.0.0/24"), so a field can be partially wildcarded.
> + * Fields must be specified in a natural order for satisfying
> prerequisites.
> + * If the map 'port_map' is specified, converts port names into port
> numbers.
> + *
> + * Returns NULL on success, otherwise a malloc()'d string that explains
> the
> + * problem. */
> +char *
> +parse_ofp_flow_match(struct match *match, const struct tun_table
> *tun_table,
> +                     const char *s, const struct ofputil_port_map
> *port_map)
> +{
> +    enum ofputil_protocol usable_protocols = OFPUTIL_P_ANY;
> +    char *pos, *key, *value_s;
> +    char *error = NULL;
> +    char *copy;
> +
> +    match_init_catchall(match);
> +    match->flow.tunnel.metadata.tab = tun_table;
> +
> +    pos = copy = xstrdup(s);
> +    while (ofputil_parse_key_value(&pos, &key, &value_s)) {
> +        const struct ofp_protocol *p;
> +        if (ofp_parse_protocol(key, &p)) {
> +            match_set_dl_type(match, htons(p->dl_type));
> +            if (p->nw_proto) {
> +                match_set_nw_proto(match, p->nw_proto);
> +            }
> +            match_set_default_packet_type(match);
> +        } else {
> +            const struct mf_field *mf = mf_from_name(key);
> +
> +            if (!mf) {
> +                error = xasprintf("%s: unknown field %s", s, key);
> +                goto exit;
> +            }
>

This appears to remove the prerequisit and duplicate value checks which had
been in place before, intended?


Thanks,
M
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to