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 <yan...@cn.fujitsu.com> > --- > 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);