aboutsummaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/filter.c21
-rw-r--r--net/net.c20
2 files changed, 34 insertions, 7 deletions
diff --git a/net/filter.c b/net/filter.c
index 5d90f83429..17a83982b9 100644
--- a/net/filter.c
+++ b/net/filter.c
@@ -34,6 +34,22 @@ ssize_t qemu_netfilter_receive(NetFilterState *nf,
return 0;
}
+static NetFilterState *netfilter_next(NetFilterState *nf,
+ NetFilterDirection dir)
+{
+ NetFilterState *next;
+
+ if (dir == NET_FILTER_DIRECTION_TX) {
+ /* forward walk through filters */
+ next = QTAILQ_NEXT(nf, next);
+ } else {
+ /* reverse order */
+ next = QTAILQ_PREV(nf, NetFilterHead, next);
+ }
+
+ return next;
+}
+
ssize_t qemu_netfilter_pass_to_next(NetClientState *sender,
unsigned flags,
const struct iovec *iov,
@@ -43,7 +59,7 @@ ssize_t qemu_netfilter_pass_to_next(NetClientState *sender,
int ret = 0;
int direction;
NetFilterState *nf = opaque;
- NetFilterState *next = QTAILQ_NEXT(nf, next);
+ NetFilterState *next = NULL;
if (!sender || !sender->peer) {
/* no receiver, or sender been deleted, no need to pass it further */
@@ -61,6 +77,7 @@ ssize_t qemu_netfilter_pass_to_next(NetClientState *sender,
direction = nf->direction;
}
+ next = netfilter_next(nf, direction);
while (next) {
/*
* if qemu_netfilter_pass_to_next been called, means that
@@ -73,7 +90,7 @@ ssize_t qemu_netfilter_pass_to_next(NetClientState *sender,
if (ret) {
return ret;
}
- next = QTAILQ_NEXT(next, next);
+ next = netfilter_next(next, direction);
}
/*
diff --git a/net/net.c b/net/net.c
index 87dd3568dc..c929c41a10 100644
--- a/net/net.c
+++ b/net/net.c
@@ -580,11 +580,21 @@ static ssize_t filter_receive_iov(NetClientState *nc,
ssize_t ret = 0;
NetFilterState *nf = NULL;
- QTAILQ_FOREACH(nf, &nc->filters, next) {
- ret = qemu_netfilter_receive(nf, direction, sender, flags, iov,
- iovcnt, sent_cb);
- if (ret) {
- return ret;
+ if (direction == NET_FILTER_DIRECTION_TX) {
+ QTAILQ_FOREACH(nf, &nc->filters, next) {
+ ret = qemu_netfilter_receive(nf, direction, sender, flags, iov,
+ iovcnt, sent_cb);
+ if (ret) {
+ return ret;
+ }
+ }
+ } else {
+ QTAILQ_FOREACH_REVERSE(nf, &nc->filters, NetFilterHead, next) {
+ ret = qemu_netfilter_receive(nf, direction, sender, flags, iov,
+ iovcnt, sent_cb);
+ if (ret) {
+ return ret;
+ }
}
}