@@ -94,6 +94,33 @@ struct netdev_flow_api {
* takes ownership of a packet if errno != EOPNOTSUPP. */
int (*hw_miss_packet_recover)(struct netdev *, struct dp_packet *);
+ /* Offloads or modifies the offloaded meter in HW with the given 'meter_id'
+ * and the configuration in 'config'. On failure, a non-zero error code is
+ * returned.
+ *
+ * The meter id specified through 'config->meter_id' is ignored. */
+ int (*meter_set)(ofproto_meter_id meter_id,
+ struct ofputil_meter_config *config);
+
+ /* Queries HW for meter stats with the given 'meter_id'. Store the stats
+ * of dropped packets to band 0. On failure, a non-zero error code is
+ * returned.
+ *
+ * Note that the 'stats' structure is already initialized, and only the
+ * available statistics should be incremented, not replaced. Those fields
+ * are packet_in_count, byte_in_count and band[]->byte_count and
+ * band[]->packet_count. */
+ int (*meter_get)(ofproto_meter_id meter_id,
+ struct ofputil_meter_stats *stats);
+
+ /* Removes meter 'meter_id' from HW. Store the stats of dropped packets to
+ * band 0. On failure, a non-zero error code is returned.
+ *
+ * 'stats' may be passed in as NULL if no stats are needed, See the above
+ * function for additional details on the 'stats' usage. */
+ int (*meter_del)(ofproto_meter_id meter_id,
+ struct ofputil_meter_stats *stats);
+
/* Initializies the netdev flow api.
* Return 0 if successful, otherwise returns a positive errno value. */
int (*init_flow_api)(struct netdev *);
@@ -58,6 +58,7 @@
VLOG_DEFINE_THIS_MODULE(netdev_offload);
+static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
static bool netdev_flow_api_enabled = false;
#define DEFAULT_OFFLOAD_THREAD_NB 1
@@ -195,6 +196,64 @@ netdev_assign_flow_api(struct netdev *netdev)
return -1;
}
+void
+meter_offload_set(ofproto_meter_id meter_id,
+ struct ofputil_meter_config *config)
+{
+ struct netdev_registered_flow_api *rfa;
+
+ CMAP_FOR_EACH (rfa, cmap_node, &netdev_flow_apis) {
+ if (rfa->flow_api->meter_set) {
+ int ret = rfa->flow_api->meter_set(meter_id, config);
+ if (ret) {
+ VLOG_DBG_RL(&rl, "Failed setting meter %u for flow api %s, "
+ "error %d", meter_id.uint32, rfa->flow_api->type,
+ ret);
+ }
+ }
+ }
+ /* Offload APIs could fail, for example, because the offload is not
+ * supported. This is fine, as the offload API should take care of this. */
+}
+
+int
+meter_offload_get(ofproto_meter_id meter_id, struct ofputil_meter_stats *stats)
+{
+ struct netdev_registered_flow_api *rfa;
+
+ CMAP_FOR_EACH (rfa, cmap_node, &netdev_flow_apis) {
+ if (rfa->flow_api->meter_get) {
+ int ret = rfa->flow_api->meter_get(meter_id, stats);
+ if (ret) {
+ VLOG_DBG_RL(&rl, "Failed getting meter %u for flow api %s, "
+ "error %d", meter_id.uint32, rfa->flow_api->type,
+ ret);
+ }
+ }
+ }
+
+ return 0;
+}
+
+int
+meter_offload_del(ofproto_meter_id meter_id, struct ofputil_meter_stats *stats)
+{
+ struct netdev_registered_flow_api *rfa;
+
+ CMAP_FOR_EACH (rfa, cmap_node, &netdev_flow_apis) {
+ if (rfa->flow_api->meter_del) {
+ int ret = rfa->flow_api->meter_del(meter_id, stats);
+ if (ret) {
+ VLOG_DBG_RL(&rl, "Failed deleting meter %u for flow api %s, "
+ "error %d", meter_id.uint32, rfa->flow_api->type,
+ ret);
+ }
+ }
+ }
+
+ return 0;
+}
+
int
netdev_flow_flush(struct netdev *netdev)
{
@@ -22,6 +22,7 @@
#include "openvswitch/types.h"
#include "ovs-rcu.h"
#include "ovs-thread.h"
+#include "openvswitch/ofp-meter.h"
#include "packets.h"
#include "flow.h"
@@ -158,6 +159,10 @@ int netdev_ports_flow_get(const char *dpif_type, struct match *match,
int netdev_ports_get_n_flows(const char *dpif_type,
odp_port_t port_no, uint64_t *n_flows);
+void meter_offload_set(ofproto_meter_id, struct ofputil_meter_config *);
+int meter_offload_get(ofproto_meter_id, struct ofputil_meter_stats *);
+int meter_offload_del(ofproto_meter_id, struct ofputil_meter_stats *);
+
#ifdef __cplusplus
}
#endif
Add API to offload meter to HW, and the corresponding functions to call the meter callbacks from all the registered flow API providers. The interfaces are like those related to meter in dpif_class, in order to pass necessary info to HW. Signed-off-by: Jianbo Liu <jianbol@nvidia.com> --- lib/netdev-offload-provider.h | 27 ++++++++++++++++ lib/netdev-offload.c | 59 +++++++++++++++++++++++++++++++++++ lib/netdev-offload.h | 5 +++ 3 files changed, 91 insertions(+)