]> git.proxmox.com Git - qemu.git/blobdiff - net.c
LAN9118 improvements
[qemu.git] / net.c
diff --git a/net.c b/net.c
index cca008a91527db675aa9605e06fb6760ff1bf33e..6ef93e615c8db9d2de230fc1b988213d763ba4f7 100644 (file)
--- a/net.c
+++ b/net.c
@@ -39,6 +39,8 @@
 static QTAILQ_HEAD(, VLANState) vlans;
 static QTAILQ_HEAD(, VLANClientState) non_vlan_clients;
 
+int default_net = 1;
+
 /***********************************************************/
 /* network device redirectors */
 
@@ -229,19 +231,13 @@ VLANClientState *qemu_new_net_client(NetClientInfo *info,
 
     vc = qemu_mallocz(info->size);
 
-    vc->type = info->type;
+    vc->info = info;
     vc->model = qemu_strdup(model);
     if (name) {
         vc->name = qemu_strdup(name);
     } else {
         vc->name = assign_name(vc, model);
     }
-    vc->can_receive = info->can_receive;
-    vc->receive = info->receive;
-    vc->receive_raw = info->receive_raw;
-    vc->receive_iov = info->receive_iov;
-    vc->cleanup = info->cleanup;
-    vc->link_status_changed = info->link_status_changed;
 
     if (vlan) {
         assert(!peer);
@@ -283,37 +279,6 @@ NICState *qemu_new_nic(NetClientInfo *info,
     return nic;
 }
 
-VLANClientState *qemu_new_vlan_client(net_client_type type,
-                                      VLANState *vlan,
-                                      VLANClientState *peer,
-                                      const char *model,
-                                      const char *name,
-                                      NetCanReceive *can_receive,
-                                      NetReceive *receive,
-                                      NetReceive *receive_raw,
-                                      NetReceiveIOV *receive_iov,
-                                      NetCleanup *cleanup,
-                                      void *opaque)
-{
-    VLANClientState *ret;
-    NetClientInfo info;
-
-    info.type = type;
-    info.size = sizeof(VLANClientState);
-    info.can_receive = can_receive;
-    info.receive = receive;
-    info.receive_raw = receive_raw;
-    info.receive_iov = receive_iov;
-    info.cleanup = cleanup;
-    info.link_status_changed = NULL;
-
-    ret = qemu_new_net_client(&info, vlan, peer, model, name);
-
-    ret->opaque = opaque;
-
-    return ret;
-}
-
 void qemu_del_vlan_client(VLANClientState *vc)
 {
     if (vc->vlan) {
@@ -328,8 +293,8 @@ void qemu_del_vlan_client(VLANClientState *vc)
         }
     }
 
-    if (vc->cleanup) {
-        vc->cleanup(vc);
+    if (vc->info->cleanup) {
+        vc->info->cleanup(vc);
     }
 
     qemu_free(vc->name);
@@ -337,19 +302,6 @@ void qemu_del_vlan_client(VLANClientState *vc)
     qemu_free(vc);
 }
 
-VLANClientState *qemu_find_vlan_client(VLANState *vlan, void *opaque)
-{
-    VLANClientState *vc;
-
-    QTAILQ_FOREACH(vc, &vlan->clients, next) {
-        if (vc->opaque == opaque) {
-            return vc;
-        }
-    }
-
-    return NULL;
-}
-
 VLANClientState *
 qemu_find_vlan_client_by_name(Monitor *mon, int vlan_id,
                               const char *client_str)
@@ -376,6 +328,26 @@ qemu_find_vlan_client_by_name(Monitor *mon, int vlan_id,
     return vc;
 }
 
+void qemu_foreach_nic(qemu_nic_foreach func, void *opaque)
+{
+    VLANClientState *nc;
+    VLANState *vlan;
+
+    QTAILQ_FOREACH(nc, &non_vlan_clients, next) {
+        if (nc->info->type == NET_CLIENT_TYPE_NIC) {
+            func(DO_UPCAST(NICState, nc, nc), opaque);
+        }
+    }
+
+    QTAILQ_FOREACH(vlan, &vlans, next) {
+        QTAILQ_FOREACH(nc, &vlan->clients, next) {
+            if (nc->info->type == NET_CLIENT_TYPE_NIC) {
+                func(DO_UPCAST(NICState, nc, nc), opaque);
+            }
+        }
+    }
+}
+
 int qemu_can_send_packet(VLANClientState *sender)
 {
     VLANState *vlan = sender->vlan;
@@ -384,8 +356,8 @@ int qemu_can_send_packet(VLANClientState *sender)
     if (sender->peer) {
         if (sender->peer->receive_disabled) {
             return 0;
-        } else if (sender->peer->can_receive &&
-                   !sender->peer->can_receive(sender->peer)) {
+        } else if (sender->peer->info->can_receive &&
+                   !sender->peer->info->can_receive(sender->peer)) {
             return 0;
         } else {
             return 1;
@@ -402,7 +374,7 @@ int qemu_can_send_packet(VLANClientState *sender)
         }
 
         /* no can_receive() handler, they can always receive */
-        if (!vc->can_receive || vc->can_receive(vc)) {
+        if (!vc->info->can_receive || vc->info->can_receive(vc)) {
             return 1;
         }
     }
@@ -426,10 +398,10 @@ static ssize_t qemu_deliver_packet(VLANClientState *sender,
         return 0;
     }
 
-    if (flags & QEMU_NET_PACKET_FLAG_RAW && vc->receive_raw) {
-        ret = vc->receive_raw(vc, data, size);
+    if (flags & QEMU_NET_PACKET_FLAG_RAW && vc->info->receive_raw) {
+        ret = vc->info->receive_raw(vc, data, size);
     } else {
-        ret = vc->receive(vc, data, size);
+        ret = vc->info->receive(vc, data, size);
     }
 
     if (ret == 0) {
@@ -466,10 +438,10 @@ static ssize_t qemu_vlan_deliver_packet(VLANClientState *sender,
             continue;
         }
 
-        if (flags & QEMU_NET_PACKET_FLAG_RAW && vc->receive_raw) {
-            len = vc->receive_raw(vc, buf, size);
+        if (flags & QEMU_NET_PACKET_FLAG_RAW && vc->info->receive_raw) {
+            len = vc->info->receive_raw(vc, buf, size);
         } else {
-            len = vc->receive(vc, buf, size);
+            len = vc->info->receive(vc, buf, size);
         }
 
         if (len == 0) {
@@ -574,7 +546,7 @@ static ssize_t vc_sendv_compat(VLANClientState *vc, const struct iovec *iov,
         offset += len;
     }
 
-    return vc->receive(vc, buffer, offset);
+    return vc->info->receive(vc, buffer, offset);
 }
 
 static ssize_t calc_iov_length(const struct iovec *iov, int iovcnt)
@@ -599,8 +571,8 @@ static ssize_t qemu_deliver_packet_iov(VLANClientState *sender,
         return calc_iov_length(iov, iovcnt);
     }
 
-    if (vc->receive_iov) {
-        return vc->receive_iov(vc, iov, iovcnt);
+    if (vc->info->receive_iov) {
+        return vc->info->receive_iov(vc, iov, iovcnt);
     } else {
         return vc_sendv_compat(vc, iov, iovcnt);
     }
@@ -630,8 +602,8 @@ static ssize_t qemu_vlan_deliver_packet_iov(VLANClientState *sender,
 
         assert(!(flags & QEMU_NET_PACKET_FLAG_RAW));
 
-        if (vc->receive_iov) {
-            len = vc->receive_iov(vc, iov, iovcnt);
+        if (vc->info->receive_iov) {
+            len = vc->info->receive_iov(vc, iov, iovcnt);
         } else {
             len = vc_sendv_compat(vc, iov, iovcnt);
         }
@@ -1085,12 +1057,18 @@ int net_client_init(Monitor *mon, QemuOpts *opts, int is_netdev)
     int i;
 
     type = qemu_opt_get(opts, "type");
-    if (!type) {
-        qemu_error("No type specified for -net\n");
-        return -1;
-    }
 
-    if (is_netdev) {
+    if (!is_netdev) {
+        if (!type) {
+            qemu_error("No type specified for -net\n");
+            return -1;
+        }
+    } else {
+        if (!type) {
+            qemu_error("No type specified for -netdev\n");
+            return -1;
+        }
+
         if (strcmp(type, "tap") != 0 &&
 #ifdef CONFIG_SLIRP
             strcmp(type, "user") != 0 &&
@@ -1290,8 +1268,9 @@ done:
         monitor_printf(mon, "invalid link status '%s'; only 'up' or 'down' "
                        "valid\n", up_or_down);
 
-    if (vc->link_status_changed)
-        vc->link_status_changed(vc);
+    if (vc->info->link_status_changed) {
+        vc->info->link_status_changed(vc);
+    }
 }
 
 void net_cleanup(void)
@@ -1340,7 +1319,7 @@ static int net_init_netdev(QemuOpts *opts, void *dummy)
 
 int net_init_clients(void)
 {
-    if (QTAILQ_EMPTY(&qemu_net_opts.head)) {
+    if (default_net) {
         /* if no clients, we use a default config */
         qemu_opts_set(&qemu_net_opts, NULL, "type", "nic");
 #ifdef CONFIG_SLIRP
@@ -1376,5 +1355,6 @@ int net_client_parse(QemuOptsList *opts_list, const char *optarg)
         return -1;
     }
 
+    default_net = 0;
     return 0;
 }