From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41691) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZlYIv-0006TE-0h for qemu-devel@nongnu.org; Mon, 12 Oct 2015 04:17:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZlYIu-0002mz-0E for qemu-devel@nongnu.org; Mon, 12 Oct 2015 04:17:56 -0400 Received: from mx1.redhat.com ([209.132.183.28]:37969) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZlYIt-0002mm-Pb for qemu-devel@nongnu.org; Mon, 12 Oct 2015 04:17:55 -0400 From: Jason Wang Date: Mon, 12 Oct 2015 16:17:12 +0800 Message-Id: <1444637836-12215-11-git-send-email-jasowang@redhat.com> In-Reply-To: <1444637836-12215-1-git-send-email-jasowang@redhat.com> References: <1444637836-12215-1-git-send-email-jasowang@redhat.com> Subject: [Qemu-devel] [PULL 10/14] netfilter: add an API to pass the packet to next filter List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org, peter.maydell@linaro.org Cc: Jason Wang , Yang Hongyang From: Yang Hongyang add an API qemu_netfilter_pass_to_next() to pass the packet to next filter. Signed-off-by: Yang Hongyang Reviewed-by: Thomas Huth Signed-off-by: Jason Wang --- include/net/filter.h | 7 +++++++ net/filter.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/include/net/filter.h b/include/net/filter.h index db035b6..5639976 100644 --- a/include/net/filter.h +++ b/include/net/filter.h @@ -66,4 +66,11 @@ ssize_t qemu_netfilter_receive(NetFilterState *nf, int iovcnt, NetPacketSent *sent_cb); +/* pass the packet to the next filter */ +ssize_t qemu_netfilter_pass_to_next(NetClientState *sender, + unsigned flags, + const struct iovec *iov, + int iovcnt, + void *opaque); + #endif /* QEMU_NET_FILTER_H */ diff --git a/net/filter.c b/net/filter.c index 147c57f..5d5022f 100644 --- a/net/filter.c +++ b/net/filter.c @@ -14,6 +14,7 @@ #include "net/net.h" #include "net/vhost_net.h" #include "qom/object_interfaces.h" +#include "qemu/iov.h" ssize_t qemu_netfilter_receive(NetFilterState *nf, NetFilterDirection direction, @@ -32,6 +33,63 @@ ssize_t qemu_netfilter_receive(NetFilterState *nf, return 0; } +ssize_t qemu_netfilter_pass_to_next(NetClientState *sender, + unsigned flags, + const struct iovec *iov, + int iovcnt, + void *opaque) +{ + int ret = 0; + int direction; + NetFilterState *nf = opaque; + NetFilterState *next = QTAILQ_NEXT(nf, next); + + if (!sender || !sender->peer) { + /* no receiver, or sender been deleted, no need to pass it further */ + goto out; + } + + if (nf->direction == NET_FILTER_DIRECTION_ALL) { + if (sender == nf->netdev) { + /* This packet is sent by netdev itself */ + direction = NET_FILTER_DIRECTION_TX; + } else { + direction = NET_FILTER_DIRECTION_RX; + } + } else { + direction = nf->direction; + } + + while (next) { + /* + * if qemu_netfilter_pass_to_next been called, means that + * the packet has been hold by filter and has already retured size + * to the sender, so sent_cb shouldn't be called later, just + * pass NULL to next. + */ + ret = qemu_netfilter_receive(next, direction, sender, flags, iov, + iovcnt, NULL); + if (ret) { + return ret; + } + next = QTAILQ_NEXT(next, next); + } + + /* + * We have gone through all filters, pass it to receiver. + * Do the valid check again incase sender or receiver been + * deleted while we go through filters. + */ + if (sender && sender->peer) { + qemu_net_queue_send_iov(sender->peer->incoming_queue, + sender, flags, iov, iovcnt, NULL); + } + +out: + /* no receiver, or sender been deleted */ + return iov_size(iov, iovcnt); +} + static char *netfilter_get_netdev_id(Object *obj, Error **errp) { NetFilterState *nf = NETFILTER(obj); -- 2.1.4