@@ -55,6 +55,7 @@ struct NetFilterState {
char *netdev_id;
NetClientState *netdev;
NetFilterDirection direction;
+ bool enabled;
QTAILQ_ENTRY(NetFilterState) next;
};
@@ -17,6 +17,11 @@
#include "qom/object_interfaces.h"
#include "qemu/iov.h"
+static inline bool qemu_need_skip_netfilter(NetFilterState *nf)
+{
+ return nf->enabled ? false : true;
+}
+
ssize_t qemu_netfilter_receive(NetFilterState *nf,
NetFilterDirection direction,
NetClientState *sender,
@@ -25,6 +30,10 @@ ssize_t qemu_netfilter_receive(NetFilterState *nf,
int iovcnt,
NetPacketSent *sent_cb)
{
+ /* Don't go through the filter if it is disabled */
+ if (qemu_need_skip_netfilter(nf)) {
+ return 0;
+ }
if (nf->direction == direction ||
nf->direction == NET_FILTER_DIRECTION_ALL) {
return NETFILTER_GET_CLASS(OBJECT(nf))->receive_iov(
@@ -134,8 +143,41 @@ static void netfilter_set_direction(Object *obj, int direction, Error **errp)
nf->direction = direction;
}
+static char *netfilter_get_status(Object *obj, Error **errp)
+{
+ NetFilterState *nf = NETFILTER(obj);
+
+ if (nf->enabled) {
+ return g_strdup("enable");
+ } else {
+ return g_strdup("disable");
+ }
+}
+
+static void netfilter_set_status(Object *obj, const char *str, Error **errp)
+{
+ NetFilterState *nf = NETFILTER(obj);
+
+ if (!strcmp(str, "enable")) {
+ nf->enabled = true;
+ } else if (!strcmp(str, "disable")) {
+ nf->enabled = false;
+ } else {
+ error_setg(errp, "Invalid value for netfilter status, "
+ "should be 'enable' or 'disable'");
+ }
+}
+
static void netfilter_init(Object *obj)
{
+ NetFilterState *nf = NETFILTER(obj);
+
+ /*
+ * If not configured with 'status' property, the default status
+ * for netfilter will be enabled.
+ */
+ nf->enabled = true;
+
object_property_add_str(obj, "netdev",
netfilter_get_netdev_id, netfilter_set_netdev_id,
NULL);
@@ -143,6 +185,9 @@ static void netfilter_init(Object *obj)
NetFilterDirection_lookup,
netfilter_get_direction, netfilter_set_direction,
NULL);
+ object_property_add_str(obj, "status",
+ netfilter_get_status, netfilter_set_status,
+ NULL);
}
static void netfilter_complete(UserCreatable *uc, Error **errp)
With this property, users can control if this filter is 'enable' or 'disable'. The default behavior for filter is enabled. We will skip the disabled filter when delivering packets in net layer. Signed-off-by: zhanghailiang <zhang.zhanghailiang@huawei.com> --- v2: - Squash previous patch 3 into this patch (Jason's suggestion) --- include/net/filter.h | 1 + net/filter.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+)