static QTAILQ_HEAD(, VLANState) vlans;
static QTAILQ_HEAD(, VLANClientState) non_vlan_clients;
+int default_net = 1;
+
/***********************************************************/
/* network device redirectors */
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);
}
}
- if (vc->cleanup) {
- vc->cleanup(vc);
+ if (vc->info->cleanup) {
+ vc->info->cleanup(vc);
}
qemu_free(vc->name);
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;
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;
}
/* 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;
}
}
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) {
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) {
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)
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);
}
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);
}
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 &&
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)
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
return -1;
}
+ default_net = 0;
return 0;
}