On 08/04/2015 04:30 PM, Yang Hongyang wrote:
> add an API qemu_netfilter_pass_to_next_iov() to pass the packet
> to next filter, and a wrapper qemu_netfilter_pass_to_next().
>
> Signed-off-by: Yang Hongyang <[email protected]>
> ---
> include/net/filter.h | 12 ++++++++++++
> net/filter.c | 43 +++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 55 insertions(+)
>
> diff --git a/include/net/filter.h b/include/net/filter.h
> index c146be2..867d5aa 100644
> --- a/include/net/filter.h
> +++ b/include/net/filter.h
> @@ -54,4 +54,16 @@ void qemu_del_net_filter(NetFilterState *nf);
> void netfilter_add(QemuOpts *opts, Error **errp);
> void qmp_netfilter_add(QDict *qdict, QObject **ret, Error **errp);
>
> +/* pass the packet to the next filter */
> +void qemu_netfilter_pass_to_next_iov(NetFilterState *nf,
> + NetClientState *sender,
> + unsigned flags,
> + const struct iovec *iov,
> + int iovcnt);
> +void qemu_netfilter_pass_to_next(NetFilterState *nf,
> + NetClientState *sender,
> + unsigned flags,
> + const uint8_t *data,
> + size_t size);
sender, flags, data and size were all could be inferred from packet. How
about just have a packet parameter?
> +
> #endif /* QEMU_NET_FILTER_H */
> diff --git a/net/filter.c b/net/filter.c
> index 24ec4e1..166b851 100644
> --- a/net/filter.c
> +++ b/net/filter.c
> @@ -14,9 +14,11 @@
> #include "qapi/dealloc-visitor.h"
> #include "qemu/config-file.h"
> #include "qmp-commands.h"
> +#include "qemu/iov.h"
>
> #include "net/filter.h"
> #include "net/net.h"
> +#include "net/queue.h"
>
> static QTAILQ_HEAD(, NetFilterState) net_filters;
>
> @@ -130,6 +132,47 @@ void qmp_netfilter_del(const char *id, Error **errp)
> qemu_opts_del(opts);
> }
>
> +void qemu_netfilter_pass_to_next_iov(NetFilterState *nf,
> + NetClientState *sender,
> + unsigned flags,
> + const struct iovec *iov,
> + int iovcnt)
> +{
> + int ret = 0;
> + ssize_t size = iov_size(iov, iovcnt);
> + NetFilterState *next = QTAILQ_NEXT(nf, next);
> +
> + while (next) {
> + if (next->chain == nf->chain || next->chain == NET_FILTER_ALL) {
> + ret = next->info->receive_iov(next, sender, flags, iov, iovcnt);
> + if (ret == size) {
> + return;
> + }
> + }
> + next = QTAILQ_NEXT(next, next);
> + }
> +
> + /* we have gone through all filters, pass it to receiver */
> + if (sender && sender->peer) {
> + qemu_net_queue_send_iov(sender->peer->incoming_queue, sender, flags,
> + iov, iovcnt, NULL);
> + }
> +}
> +
> +void qemu_netfilter_pass_to_next(NetFilterState *nf,
> + NetClientState *sender,
> + unsigned flags,
> + const uint8_t *data,
> + size_t size)
> +{
> + struct iovec iov = {
> + .iov_base = (void *)data,
> + .iov_len = size
> + };
> +
> + return qemu_netfilter_pass_to_next_iov(nf, sender, flags, &iov, 1);
> +}
> +
> typedef int (NetFilterInit)(const NetFilterOptions *opts,
> const char *name, int chain,
> NetClientState *netdev, Error **errp);