]> git.proxmox.com Git - mirror_qemu.git/blobdiff - net/filter-buffer.c
vdpa: Add SetSteeringEBPF method for NetClientState
[mirror_qemu.git] / net / filter-buffer.c
index 2353d5bc756614137aa536013afbc159c41c82d2..283dc9cbe6b6e0a9d7ba9a9158296545ff629aed 100644 (file)
@@ -9,25 +9,24 @@
 #include "qemu/osdep.h"
 #include "net/filter.h"
 #include "net/queue.h"
-#include "qemu-common.h"
+#include "qapi/error.h"
 #include "qemu/timer.h"
 #include "qemu/iov.h"
+#include "qapi/qapi-builtin-visit.h"
 #include "qapi/qmp/qerror.h"
-#include "qapi-visit.h"
 #include "qom/object.h"
 
 #define TYPE_FILTER_BUFFER "filter-buffer"
 
-#define FILTER_BUFFER(obj) \
-    OBJECT_CHECK(FilterBufferState, (obj), TYPE_FILTER_BUFFER)
+OBJECT_DECLARE_SIMPLE_TYPE(FilterBufferState, FILTER_BUFFER)
 
-typedef struct FilterBufferState {
+struct FilterBufferState {
     NetFilterState parent_obj;
 
     NetQueue *incoming_queue;
     uint32_t interval;
     QEMUTimer release_timer;
-} FilterBufferState;
+};
 
 static void filter_buffer_flush(NetFilterState *nf)
 {
@@ -74,7 +73,7 @@ static ssize_t filter_buffer_receive_iov(NetFilterState *nf,
      * the filter can still accept packets until its internal queue is full.
      * For example:
      *   For some reason, receiver could not receive more packets
-     * (.can_receive() returns zero). Without a filter, at most one packet
+     * (.can_receive() returns false). Without a filter, at most one packet
      * will be queued in incoming queue and sender's poll will be disabled
      * unit its sent_cb() was called. With a filter, it will keep receiving
      * the packets without caring about the receiver. This is suboptimal.
@@ -100,6 +99,19 @@ static void filter_buffer_cleanup(NetFilterState *nf)
     }
 }
 
+static void filter_buffer_setup_timer(NetFilterState *nf)
+{
+    FilterBufferState *s = FILTER_BUFFER(nf);
+
+    if (s->interval) {
+        timer_init_us(&s->release_timer, QEMU_CLOCK_VIRTUAL,
+                      filter_buffer_release_timer, nf);
+        /* Timer armed to fire in s->interval microseconds. */
+        timer_mod(&s->release_timer,
+                  qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) + s->interval);
+    }
+}
+
 static void filter_buffer_setup(NetFilterState *nf, Error **errp)
 {
     FilterBufferState *s = FILTER_BUFFER(nf);
@@ -115,67 +127,69 @@ static void filter_buffer_setup(NetFilterState *nf, Error **errp)
     }
 
     s->incoming_queue = qemu_new_net_queue(qemu_netfilter_pass_to_next, nf);
-    if (s->interval) {
-        timer_init_us(&s->release_timer, QEMU_CLOCK_VIRTUAL,
-                      filter_buffer_release_timer, nf);
-        /* Timer armed to fire in s->interval microseconds. */
-        timer_mod(&s->release_timer,
-                  qemu_clock_get_us(QEMU_CLOCK_VIRTUAL) + s->interval);
-    }
+    filter_buffer_setup_timer(nf);
 }
 
-static void filter_buffer_class_init(ObjectClass *oc, void *data)
+static void filter_buffer_status_changed(NetFilterState *nf, Error **errp)
 {
-    NetFilterClass *nfc = NETFILTER_CLASS(oc);
+    FilterBufferState *s = FILTER_BUFFER(nf);
 
-    nfc->setup = filter_buffer_setup;
-    nfc->cleanup = filter_buffer_cleanup;
-    nfc->receive_iov = filter_buffer_receive_iov;
+    if (!nf->on) {
+        if (s->interval) {
+            timer_del(&s->release_timer);
+        }
+        filter_buffer_flush(nf);
+    } else {
+        filter_buffer_setup_timer(nf);
+    }
 }
 
-static void filter_buffer_get_interval(Object *obj, Visitor *v, void *opaque,
-                                       const char *name, Error **errp)
+static void filter_buffer_get_interval(Object *obj, Visitor *v,
+                                       const char *name, void *opaque,
+                                       Error **errp)
 {
     FilterBufferState *s = FILTER_BUFFER(obj);
     uint32_t value = s->interval;
 
-    visit_type_uint32(v, &value, name, errp);
+    visit_type_uint32(v, name, &value, errp);
 }
 
-static void filter_buffer_set_interval(Object *obj, Visitor *v, void *opaque,
-                                       const char *name, Error **errp)
+static void filter_buffer_set_interval(Object *obj, Visitor *v,
+                                       const char *name, void *opaque,
+                                       Error **errp)
 {
     FilterBufferState *s = FILTER_BUFFER(obj);
-    Error *local_err = NULL;
     uint32_t value;
 
-    visit_type_uint32(v, &value, name, &local_err);
-    if (local_err) {
-        goto out;
+    if (!visit_type_uint32(v, name, &value, errp)) {
+        return;
     }
     if (!value) {
-        error_setg(&local_err, "Property '%s.%s' requires a positive value",
+        error_setg(errp, "Property '%s.%s' requires a positive value",
                    object_get_typename(obj), name);
-        goto out;
+        return;
     }
     s->interval = value;
-
-out:
-    error_propagate(errp, local_err);
 }
 
-static void filter_buffer_init(Object *obj)
+static void filter_buffer_class_init(ObjectClass *oc, void *data)
 {
-    object_property_add(obj, "interval", "int",
-                        filter_buffer_get_interval,
-                        filter_buffer_set_interval, NULL, NULL, NULL);
+    NetFilterClass *nfc = NETFILTER_CLASS(oc);
+
+    object_class_property_add(oc, "interval", "uint32",
+                              filter_buffer_get_interval,
+                              filter_buffer_set_interval, NULL, NULL);
+
+    nfc->setup = filter_buffer_setup;
+    nfc->cleanup = filter_buffer_cleanup;
+    nfc->receive_iov = filter_buffer_receive_iov;
+    nfc->status_changed = filter_buffer_status_changed;
 }
 
 static const TypeInfo filter_buffer_info = {
     .name = TYPE_FILTER_BUFFER,
     .parent = TYPE_NETFILTER,
     .class_init = filter_buffer_class_init,
-    .instance_init = filter_buffer_init,
     .instance_size = sizeof(FilterBufferState),
 };