All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jason Wang <jasowang@redhat.com>
To: peter.maydell@linaro.org, qemu-devel@nongnu.org
Cc: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>,
	Li Zhijian <lizhijian@cn.fujitsu.com>,
	Wen Congyang <wency@cn.fujitsu.com>,
	Jason Wang <jasowang@redhat.com>
Subject: [Qemu-devel] [PULL 20/20] net/net: Add SocketReadState for reuse codes
Date: Mon, 23 May 2016 10:14:02 +0800	[thread overview]
Message-ID: <1463969642-5908-21-git-send-email-jasowang@redhat.com> (raw)
In-Reply-To: <1463969642-5908-1-git-send-email-jasowang@redhat.com>

From: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>

This function is from net/socket.c, move it to net.c and net.h.
Add SocketReadState to make others reuse net_fill_rstate().
suggestion from jason.

v4:
 - move 'rs->finalize = finalize' to rs_init()

v3:
 - remove SocketReadState init callback
 - put finalize callback to net_fill_rstate()

v2:
 - rename ReadState to SocketReadState
 - add SocketReadState init and finalize callback

v1:
 - init patch

Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
---
 include/net/net.h   | 13 +++++++++
 net/filter-mirror.c | 66 +++++++++++----------------------------------
 net/net.c           | 70 ++++++++++++++++++++++++++++++++++++++++++++++++
 net/socket.c        | 77 +++++++++++++++--------------------------------------
 4 files changed, 121 insertions(+), 105 deletions(-)

diff --git a/include/net/net.h b/include/net/net.h
index 422bc3e..a69e382 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -62,6 +62,8 @@ typedef void (SetOffload)(NetClientState *, int, int, int, int, int);
 typedef void (SetVnetHdrLen)(NetClientState *, int);
 typedef int (SetVnetLE)(NetClientState *, bool);
 typedef int (SetVnetBE)(NetClientState *, bool);
+typedef struct SocketReadState SocketReadState;
+typedef void (SocketReadStateFinalize)(SocketReadState *rs);
 
 typedef struct NetClientInfo {
     NetClientOptionsKind type;
@@ -107,6 +109,15 @@ typedef struct NICState {
     bool peer_deleted;
 } NICState;
 
+struct SocketReadState {
+    int state; /* 0 = getting length, 1 = getting data */
+    uint32_t index;
+    uint32_t packet_len;
+    uint8_t buf[NET_BUFSIZE];
+    SocketReadStateFinalize *finalize;
+};
+
+int net_fill_rstate(SocketReadState *rs, const uint8_t *buf, int size);
 char *qemu_mac_strdup_printf(const uint8_t *macaddr);
 NetClientState *qemu_find_netdev(const char *id);
 int qemu_find_net_clients_except(const char *id, NetClientState **ncs,
@@ -165,6 +176,8 @@ ssize_t qemu_deliver_packet_iov(NetClientState *sender,
 
 void print_net_client(Monitor *mon, NetClientState *nc);
 void hmp_info_network(Monitor *mon, const QDict *qdict);
+void net_socket_rs_init(SocketReadState *rs,
+                        SocketReadStateFinalize *finalize);
 
 /* NIC info */
 
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
index c0c4dc6..35df374 100644
--- a/net/filter-mirror.c
+++ b/net/filter-mirror.c
@@ -40,10 +40,7 @@ typedef struct MirrorState {
     char *outdev;
     CharDriverState *chr_in;
     CharDriverState *chr_out;
-    int state; /* 0 = getting length, 1 = getting data */
-    unsigned int index;
-    unsigned int packet_len;
-    uint8_t buf[REDIRECTOR_MAX_LEN];
+    SocketReadState rs;
 } MirrorState;
 
 static int filter_mirror_send(CharDriverState *chr_out,
@@ -108,51 +105,12 @@ static void redirector_chr_read(void *opaque, const uint8_t *buf, int size)
 {
     NetFilterState *nf = opaque;
     MirrorState *s = FILTER_REDIRECTOR(nf);
-    unsigned int l;
-
-    while (size > 0) {
-        /* reassemble a packet from the network */
-        switch (s->state) { /* 0 = getting length, 1 = getting data */
-        case 0:
-            l = 4 - s->index;
-            if (l > size) {
-                l = size;
-            }
-            memcpy(s->buf + s->index, buf, l);
-            buf += l;
-            size -= l;
-            s->index += l;
-            if (s->index == 4) {
-                /* got length */
-                s->packet_len = ntohl(*(uint32_t *)s->buf);
-                s->index = 0;
-                s->state = 1;
-            }
-            break;
-        case 1:
-            l = s->packet_len - s->index;
-            if (l > size) {
-                l = size;
-            }
-            if (s->index + l <= sizeof(s->buf)) {
-                memcpy(s->buf + s->index, buf, l);
-            } else {
-                error_report("serious error: oversized packet received.");
-                s->index = s->state = 0;
-                qemu_chr_add_handlers(s->chr_in, NULL, NULL, NULL, NULL);
-                return;
-            }
-
-            s->index += l;
-            buf += l;
-            size -= l;
-            if (s->index >= s->packet_len) {
-                s->index = 0;
-                s->state = 0;
-                redirector_to_filter(nf, s->buf, s->packet_len);
-            }
-            break;
-        }
+    int ret;
+
+    ret = net_fill_rstate(&s->rs, buf, size);
+
+    if (ret == -1) {
+        qemu_chr_add_handlers(s->chr_in, NULL, NULL, NULL, NULL);
     }
 }
 
@@ -258,6 +216,14 @@ static void filter_mirror_setup(NetFilterState *nf, Error **errp)
     }
 }
 
+static void redirector_rs_finalize(SocketReadState *rs)
+{
+    MirrorState *s = container_of(rs, MirrorState, rs);
+    NetFilterState *nf = NETFILTER(s);
+
+    redirector_to_filter(nf, rs->buf, rs->packet_len);
+}
+
 static void filter_redirector_setup(NetFilterState *nf, Error **errp)
 {
     MirrorState *s = FILTER_REDIRECTOR(nf);
@@ -274,7 +240,7 @@ static void filter_redirector_setup(NetFilterState *nf, Error **errp)
         }
     }
 
-    s->state = s->index = 0;
+    net_socket_rs_init(&s->rs, redirector_rs_finalize);
 
     if (s->indev) {
         s->chr_in = qemu_chr_find(s->indev);
diff --git a/net/net.c b/net/net.c
index 1680b68..5f3e5a9 100644
--- a/net/net.c
+++ b/net/net.c
@@ -1550,3 +1550,73 @@ QemuOptsList qemu_net_opts = {
         { /* end of list */ }
     },
 };
+
+void net_socket_rs_init(SocketReadState *rs,
+                        SocketReadStateFinalize *finalize)
+{
+    rs->state = 0;
+    rs->index = 0;
+    rs->packet_len = 0;
+    memset(rs->buf, 0, sizeof(rs->buf));
+    rs->finalize = finalize;
+}
+
+/*
+ * Returns
+ * 0: SocketReadState is not ready
+ * 1: SocketReadState is ready
+ * otherwise error occurs
+ */
+int net_fill_rstate(SocketReadState *rs, const uint8_t *buf, int size)
+{
+    unsigned int l;
+
+    while (size > 0) {
+        /* reassemble a packet from the network */
+        switch (rs->state) { /* 0 = getting length, 1 = getting data */
+        case 0:
+            l = 4 - rs->index;
+            if (l > size) {
+                l = size;
+            }
+            memcpy(rs->buf + rs->index, buf, l);
+            buf += l;
+            size -= l;
+            rs->index += l;
+            if (rs->index == 4) {
+                /* got length */
+                rs->packet_len = ntohl(*(uint32_t *)rs->buf);
+                rs->index = 0;
+                rs->state = 1;
+            }
+            break;
+        case 1:
+            l = rs->packet_len - rs->index;
+            if (l > size) {
+                l = size;
+            }
+            if (rs->index + l <= sizeof(rs->buf)) {
+                memcpy(rs->buf + rs->index, buf, l);
+            } else {
+                fprintf(stderr, "serious error: oversized packet received,"
+                    "connection terminated.\n");
+                rs->index = rs->state = 0;
+                return -1;
+            }
+
+            rs->index += l;
+            buf += l;
+            size -= l;
+            if (rs->index >= rs->packet_len) {
+                rs->index = 0;
+                rs->state = 0;
+                if (rs->finalize) {
+                    rs->finalize(rs);
+                }
+                return 1;
+            }
+            break;
+        }
+    }
+    return 0;
+}
diff --git a/net/socket.c b/net/socket.c
index 9fa2cd8..333fb9e 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -38,11 +38,8 @@ typedef struct NetSocketState {
     NetClientState nc;
     int listen_fd;
     int fd;
-    int state; /* 0 = getting length, 1 = getting data */
-    unsigned int index;
-    unsigned int packet_len;
+    SocketReadState rs;
     unsigned int send_index;      /* number of bytes sent (only SOCK_STREAM) */
-    uint8_t buf[NET_BUFSIZE];
     struct sockaddr_in dgram_dst; /* contains inet host and port destination iff connectionless (SOCK_DGRAM) */
     IOHandler *send_fn;           /* differs between SOCK_STREAM/SOCK_DGRAM */
     bool read_poll;               /* waiting to receive data? */
@@ -143,11 +140,22 @@ static void net_socket_send_completed(NetClientState *nc, ssize_t len)
     }
 }
 
+static void net_socket_rs_finalize(SocketReadState *rs)
+{
+    NetSocketState *s = container_of(rs, NetSocketState, rs);
+
+    if (qemu_send_packet_async(&s->nc, rs->buf,
+                               rs->packet_len,
+                               net_socket_send_completed) == 0) {
+        net_socket_read_poll(s, false);
+    }
+}
+
 static void net_socket_send(void *opaque)
 {
     NetSocketState *s = opaque;
     int size;
-    unsigned l;
+    int ret;
     uint8_t buf1[NET_BUFSIZE];
     const uint8_t *buf;
 
@@ -166,61 +174,18 @@ static void net_socket_send(void *opaque)
         closesocket(s->fd);
 
         s->fd = -1;
-        s->state = 0;
-        s->index = 0;
-        s->packet_len = 0;
+        net_socket_rs_init(&s->rs, net_socket_rs_finalize);
         s->nc.link_down = true;
-        memset(s->buf, 0, sizeof(s->buf));
         memset(s->nc.info_str, 0, sizeof(s->nc.info_str));
 
         return;
     }
     buf = buf1;
-    while (size > 0) {
-        /* reassemble a packet from the network */
-        switch(s->state) {
-        case 0:
-            l = 4 - s->index;
-            if (l > size)
-                l = size;
-            memcpy(s->buf + s->index, buf, l);
-            buf += l;
-            size -= l;
-            s->index += l;
-            if (s->index == 4) {
-                /* got length */
-                s->packet_len = ntohl(*(uint32_t *)s->buf);
-                s->index = 0;
-                s->state = 1;
-            }
-            break;
-        case 1:
-            l = s->packet_len - s->index;
-            if (l > size)
-                l = size;
-            if (s->index + l <= sizeof(s->buf)) {
-                memcpy(s->buf + s->index, buf, l);
-            } else {
-                fprintf(stderr, "serious error: oversized packet received,"
-                    "connection terminated.\n");
-                s->state = 0;
-                goto eoc;
-            }
 
-            s->index += l;
-            buf += l;
-            size -= l;
-            if (s->index >= s->packet_len) {
-                s->index = 0;
-                s->state = 0;
-                if (qemu_send_packet_async(&s->nc, s->buf, s->packet_len,
-                                           net_socket_send_completed) == 0) {
-                    net_socket_read_poll(s, false);
-                    break;
-                }
-            }
-            break;
-        }
+    ret = net_fill_rstate(&s->rs, buf, size);
+
+    if (ret == -1) {
+        goto eoc;
     }
 }
 
@@ -229,7 +194,7 @@ static void net_socket_send_dgram(void *opaque)
     NetSocketState *s = opaque;
     int size;
 
-    size = qemu_recv(s->fd, s->buf, sizeof(s->buf), 0);
+    size = qemu_recv(s->fd, s->rs.buf, sizeof(s->rs.buf), 0);
     if (size < 0)
         return;
     if (size == 0) {
@@ -238,7 +203,7 @@ static void net_socket_send_dgram(void *opaque)
         net_socket_write_poll(s, false);
         return;
     }
-    if (qemu_send_packet_async(&s->nc, s->buf, size,
+    if (qemu_send_packet_async(&s->nc, s->rs.buf, size,
                                net_socket_send_completed) == 0) {
         net_socket_read_poll(s, false);
     }
@@ -401,6 +366,7 @@ static NetSocketState *net_socket_fd_init_dgram(NetClientState *peer,
     s->fd = fd;
     s->listen_fd = -1;
     s->send_fn = net_socket_send_dgram;
+    net_socket_rs_init(&s->rs, net_socket_rs_finalize);
     net_socket_read_poll(s, true);
 
     /* mcast: save bound address as dst */
@@ -451,6 +417,7 @@ static NetSocketState *net_socket_fd_init_stream(NetClientState *peer,
 
     s->fd = fd;
     s->listen_fd = -1;
+    net_socket_rs_init(&s->rs, net_socket_rs_finalize);
 
     /* Disable Nagle algorithm on TCP sockets to reduce latency */
     socket_set_nodelay(fd);
-- 
2.7.4

  parent reply	other threads:[~2016-05-23  2:15 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-23  2:13 [Qemu-devel] [PULL 00/20] Net patches Jason Wang
2016-05-23  2:13 ` [Qemu-devel] [PULL 01/20] net/tap: Allocating Large sized arrays to heap Jason Wang
2016-05-23  2:13 ` [Qemu-devel] [PULL 02/20] net: mipsnet: check packet length against buffer Jason Wang
2016-05-23  2:13 ` [Qemu-devel] [PULL 03/20] msix: make msix_clr_pending() visible for clients Jason Wang
2016-05-23  2:13 ` [Qemu-devel] [PULL 04/20] pci: Introduce define for PM capability version 1.1 Jason Wang
2016-05-23  2:13 ` [Qemu-devel] [PULL 05/20] pcie: Add support for PCIe CAP v1 Jason Wang
2016-05-23  2:13 ` [Qemu-devel] [PULL 06/20] pcie: Introduce function for DSN capability creation Jason Wang
2016-05-23  2:13 ` [Qemu-devel] [PULL 07/20] vmxnet3: Use generic function for DSN capability definition Jason Wang
2016-05-23  2:13 ` [Qemu-devel] [PULL 08/20] net: Introduce Toeplitz hash calculator Jason Wang
2016-05-23  2:13 ` [Qemu-devel] [PULL 09/20] net: Add macros for MAC address tracing Jason Wang
2016-05-23  2:13 ` [Qemu-devel] [PULL 10/20] vmxnet3: Use common MAC address tracing macros Jason Wang
2016-05-23  2:13 ` [Qemu-devel] [PULL 11/20] net_pkt: Name vmxnet3 packet abstractions more generic Jason Wang
2016-05-23  2:13 ` [Qemu-devel] [PULL 12/20] rtl8139: Move more TCP definitions to common header Jason Wang
2016-05-23  2:13 ` [Qemu-devel] [PULL 13/20] net_pkt: Extend packet abstraction as required by e1000e functionality Jason Wang
2016-05-23  2:13 ` [Qemu-devel] [PULL 14/20] vmxnet3: Use pci_dma_* API instead of cpu_physical_memory_* Jason Wang
2016-05-23  2:13 ` [Qemu-devel] [PULL 15/20] e1000_regs: Add definitions for Intel 82574-specific bits Jason Wang
2016-05-23  2:13 ` [Qemu-devel] [PULL 16/20] e1000: Move out code that will be reused in e1000e Jason Wang
2016-05-23  2:13 ` [Qemu-devel] [PULL 17/20] net: Introduce e1000e device emulation Jason Wang
2016-05-23  2:14 ` [Qemu-devel] [PULL 18/20] e1000e: Introduce qtest for e1000e device Jason Wang
2016-05-23  2:14 ` [Qemu-devel] [PULL 19/20] net: vl: Move default_net to vl.c Jason Wang
2016-05-23  2:14 ` Jason Wang [this message]
2016-05-23 11:09 ` [Qemu-devel] [PULL 00/20] Net patches Peter Maydell
2016-05-24  5:33   ` Jason Wang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1463969642-5908-21-git-send-email-jasowang@redhat.com \
    --to=jasowang@redhat.com \
    --cc=lizhijian@cn.fujitsu.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=wency@cn.fujitsu.com \
    --cc=zhangchen.fnst@cn.fujitsu.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.