Git Commit: 37763099533158d94670df8cc6882e782b0eb3be
Author: Eelco Chaudron <[email protected]>
Subject: dpif-offload: Add inline flow APIs for userspace datapaths.

This patch introduces new APIs in dpif-offload to allow userspace
datapaths to directly manage flows in the offloaded datapath,
providing efficient fast-path operations.

> diff --git a/lib/dp-packet.h b/lib/dp-packet.h
> index 285d0e43f..df441c6aa 100644
> --- a/lib/dp-packet.h
> +++ b/lib/dp-packet.h
> @@ -48,6 +48,7 @@ enum OVS_PACKED_ENUM dp_packet_source {
>  };
>  
>  #define DP_PACKET_CONTEXT_SIZE 64
> +#define INVALID_FLOW_MARK 0

Should this define be moved to dpif-offload.h where it's actually used?
The constant appears to be specific to flow marking rather than general
packet handling.

> diff --git a/lib/dpif-offload.c b/lib/dpif-offload.c
> index 0cff74a5d..a9ccadce9 100644
> --- a/lib/dpif-offload.c
> +++ b/lib/dpif-offload.c

[ ... ]

> @@ -1186,19 +1186,14 @@ dpif_offload_offload_get_netdev_by_port_id(struct 
> dpif_offload *offload,
>      return offload->class->get_netdev(offload, port_no);
>  }
>  
> -struct netdev *
> -dpif_offload_get_netdev_by_port_id(struct dpif *dpif,
> -                                   struct dpif_offload **offload,
> -                                   odp_port_t port_no)
> +static struct netdev *
> +dpif_offload_get_netdev_by_port_id_(struct dp_offload *dp_offload,
> +                                    struct dpif_offload **offload,
> +                                    odp_port_t port_no)
>  {
> -    struct dp_offload *dp_offload = dpif_offload_get_dp_offload(dpif);
>      struct dpif_offload *tmp_offload;
>      struct netdev *netdev = NULL;
>  
> -    if (!dp_offload || !dpif_offload_is_offload_enabled()) {
> -        return NULL;
> -    }
> -
>      LIST_FOR_EACH (tmp_offload, dpif_list_node,
>                     &dp_offload->offload_providers) {
>          netdev = tmp_offload->class->get_netdev(tmp_offload, port_no);

Does the removal of the dp_offload null check create a potential crash
in dpif_offload_get_netdev_by_port_id_? The LIST_FOR_EACH macro will
dereference dp_offload->offload_providers without checking if dp_offload
is null.

> +int
> +dpif_offload_datapath_flow_put(const char *dpif_name,
> +                               struct dpif_offload_flow_put *put,
> +                               uint32_t *flow_mark)
> +{
> +    struct dpif_offload *offload;
> +    struct dp_offload *dp_offload;
> +    struct netdev *netdev;
> +
> +    ovs_mutex_lock(&dpif_offload_mutex);
> +    /* XXX: Implement a faster solution than the current dpif_name lookup. */
> +    dp_offload = shash_find_data(&dpif_offload_providers, dpif_name);
> +    ovs_mutex_unlock(&dpif_offload_mutex);
> +
> +    if (OVS_UNLIKELY(!dp_offload)) {
> +        if (flow_mark) {
> +            *flow_mark = INVALID_FLOW_MARK;
> +        }
> +        return 0;
> +    }
> +
> +    netdev = dpif_offload_get_netdev_by_port_id_(dp_offload, &offload,
> +                                                 put->in_port);

Will dpif_offload_get_netdev_by_port_id_ crash if dp_offload is null?
The function no longer checks for null dp_offload internally.

> +
> +    if (OVS_LIKELY(netdev && offload->class->netdev_flow_put)) {
> +        return offload->class->netdev_flow_put(offload, netdev, put,
> +                                               flow_mark);
> +    }

Can 'offload' be null here if netdev is found but offload is not set by
dpif_offload_get_netdev_by_port_id_? This could cause a dereference of
null offload->class.

> +int
> +dpif_offload_datapath_flow_del(const char *dpif_name,
> +                               struct dpif_offload_flow_del *del,
> +                               uint32_t *flow_mark)
> +{
> +    struct dpif_offload *offload;
> +    struct dp_offload *dp_offload;
> +    struct netdev *netdev;
> +
> +    ovs_mutex_lock(&dpif_offload_mutex);
> +    /* XXX: Implement a faster solution than the current dpif_name lookup. */
> +    dp_offload = shash_find_data(&dpif_offload_providers, dpif_name);
> +    ovs_mutex_unlock(&dpif_offload_mutex);

Should there be a null check on dpif_name parameter before calling
shash_find_data? The function could crash if dpif_name is null.

> +bool
> +dpif_offload_datapath_flow_stats(const char *dpif_name, odp_port_t in_port,
> +                                 const ovs_u128 *ufid,
> +                                 struct dpif_flow_stats *stats,
> +                                 struct dpif_flow_attrs *attrs)
> +{

Are there null checks needed for the ufid, stats, or attrs parameters
before they're passed to the provider implementation? These pointers
could be dereferenced in the provider code.

> diff --git a/lib/dpif-offload.h b/lib/dpif-offload.h
> index 0de077919..b7d437c94 100644
> --- a/lib/dpif-offload.h
> +++ b/lib/dpif-offload.h

[ ... ]

> +static inline void dpif_offload_datapath_flow_op_continue(
> +    struct dpif_offload_flow_cb_data *cb, struct dpif_flow_stats *stats,
> +    uint32_t flow_mark, int error)
> +{
> +    if (cb && cb->callback) {
> +        cb->callback(cb->callback_aux_dp, cb->callback_aux_flow,
> +                      stats, flow_mark, error);
> +    }
> +}

Does this function need to check if stats is null before passing it to
the callback? The callback might dereference stats without checking.
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to