diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c index 74ead97d87..ed7655de86 100644 --- a/audio/alsaaudio.c +++ b/audio/alsaaudio.c @@ -266,31 +266,19 @@ static int alsa_poll_helper (snd_pcm_t *handle, struct pollhlp *hlp, int mask) for (i = 0; i < count; ++i) { if (pfds[i].events & POLLIN) { - err = qemu_set_fd_handler (pfds[i].fd, alsa_poll_handler, - NULL, hlp); + qemu_set_fd_handler (pfds[i].fd, alsa_poll_handler, NULL, hlp); } if (pfds[i].events & POLLOUT) { if (conf.verbose) { dolog ("POLLOUT %d %d\n", i, pfds[i].fd); } - err = qemu_set_fd_handler (pfds[i].fd, NULL, - alsa_poll_handler, hlp); + qemu_set_fd_handler (pfds[i].fd, NULL, alsa_poll_handler, hlp); } if (conf.verbose) { dolog ("Set handler events=%#x index=%d fd=%d err=%d\n", pfds[i].events, i, pfds[i].fd, err); } - if (err) { - dolog ("Failed to set handler events=%#x index=%d fd=%d err=%d\n", - pfds[i].events, i, pfds[i].fd, err); - - while (i--) { - qemu_set_fd_handler (pfds[i].fd, NULL, NULL, NULL); - } - g_free (pfds); - return -1; - } } hlp->pfds = pfds; hlp->count = count; diff --git a/audio/ossaudio.c b/audio/ossaudio.c index 4db2ca65bf..b9c6b30ca1 100644 --- a/audio/ossaudio.c +++ b/audio/ossaudio.c @@ -138,18 +138,18 @@ static void oss_helper_poll_in (void *opaque) audio_run ("oss_poll_in"); } -static int oss_poll_out (HWVoiceOut *hw) +static void oss_poll_out (HWVoiceOut *hw) { OSSVoiceOut *oss = (OSSVoiceOut *) hw; - return qemu_set_fd_handler (oss->fd, NULL, oss_helper_poll_out, NULL); + qemu_set_fd_handler (oss->fd, NULL, oss_helper_poll_out, NULL); } -static int oss_poll_in (HWVoiceIn *hw) +static void oss_poll_in (HWVoiceIn *hw) { OSSVoiceIn *oss = (OSSVoiceIn *) hw; - return qemu_set_fd_handler (oss->fd, oss_helper_poll_in, NULL, NULL); + qemu_set_fd_handler (oss->fd, oss_helper_poll_in, NULL, NULL); } static int oss_write (SWVoiceOut *sw, void *buf, int len) @@ -634,7 +634,8 @@ static int oss_ctl_out (HWVoiceOut *hw, int cmd, ...) va_end (ap); ldebug ("enabling voice\n"); - if (poll_mode && oss_poll_out (hw)) { + if (poll_mode) { + oss_poll_out (hw); poll_mode = 0; } hw->poll_mode = poll_mode; @@ -828,7 +829,8 @@ static int oss_ctl_in (HWVoiceIn *hw, int cmd, ...) poll_mode = va_arg (ap, int); va_end (ap); - if (poll_mode && oss_poll_in (hw)) { + if (poll_mode) { + oss_poll_in (hw); poll_mode = 0; } hw->poll_mode = poll_mode; diff --git a/blockdev-nbd.c b/blockdev-nbd.c index 85cda4cfa7..0d9df47ce4 100644 --- a/blockdev-nbd.c +++ b/blockdev-nbd.c @@ -43,7 +43,7 @@ void qmp_nbd_server_start(SocketAddress *addr, Error **errp) server_fd = socket_listen(addr, errp); if (server_fd != -1) { - qemu_set_fd_handler2(server_fd, NULL, nbd_accept, NULL, NULL); + qemu_set_fd_handler(server_fd, nbd_accept, NULL, NULL); } } @@ -129,7 +129,7 @@ void qmp_nbd_server_stop(Error **errp) } if (server_fd != -1) { - qemu_set_fd_handler2(server_fd, NULL, NULL, NULL, NULL); + qemu_set_fd_handler(server_fd, NULL, NULL, NULL); close(server_fd); server_fd = -1; } diff --git a/docs/specs/rocker.txt b/docs/specs/rocker.txt index 1e7e1e1859..0af5c61585 100644 --- a/docs/specs/rocker.txt +++ b/docs/specs/rocker.txt @@ -420,6 +420,7 @@ Other properties for front-panel ports are available via DMA CMD descriptors: LEARNING 1 MAC address learning on port 1 = enabled 0 = disabled + PHYS_NAME Physical port name (string) Set PORT_SETTINGS descriptor: diff --git a/hmp-commands.hx b/hmp-commands.hx index 3d7dfccf7c..d3b7932ff6 100644 --- a/hmp-commands.hx +++ b/hmp-commands.hx @@ -1798,6 +1798,30 @@ STEXI show available trace events and their state ETEXI +STEXI +@item rocker @var{name} +@findex rocker +Show Rocker(s) +ETEXI + +STEXI +@item rocker_ports @var{name} +@findex rocker_ports +Show Rocker ports +ETEXI + +STEXI +@item rocker_of_dpa_flows @var{name} [@var{tbl_id}] +@findex rocker_of_dpa_flows +Show Rocker OF-DPA flow tables +ETEXI + +STEXI +@item rocker_of_dpa_groups @var{name} [@var{type}] +@findex rocker_of_dpa_groups +Show Rocker OF-DPA groups +ETEXI + STEXI @end table ETEXI diff --git a/hmp.c b/hmp.c index 514f22fbfa..1e7cac02ac 100644 --- a/hmp.c +++ b/hmp.c @@ -15,6 +15,7 @@ #include "hmp.h" #include "net/net.h" +#include "net/eth.h" #include "sysemu/char.h" #include "sysemu/block-backend.h" #include "qemu/option.h" @@ -1999,3 +2000,305 @@ void hmp_qom_set(Monitor *mon, const QDict *qdict) } hmp_handle_error(mon, &err); } + +void hmp_rocker(Monitor *mon, const QDict *qdict) +{ + const char *name = qdict_get_str(qdict, "name"); + RockerSwitch *rocker; + Error *errp = NULL; + + rocker = qmp_query_rocker(name, &errp); + if (errp != NULL) { + hmp_handle_error(mon, &errp); + return; + } + + monitor_printf(mon, "name: %s\n", rocker->name); + monitor_printf(mon, "id: 0x%" PRIx64 "\n", rocker->id); + monitor_printf(mon, "ports: %d\n", rocker->ports); + + qapi_free_RockerSwitch(rocker); +} + +void hmp_rocker_ports(Monitor *mon, const QDict *qdict) +{ + RockerPortList *list, *port; + const char *name = qdict_get_str(qdict, "name"); + Error *errp = NULL; + + list = qmp_query_rocker_ports(name, &errp); + if (errp != NULL) { + hmp_handle_error(mon, &errp); + return; + } + + monitor_printf(mon, " ena/ speed/ auto\n"); + monitor_printf(mon, " port link duplex neg?\n"); + + for (port = list; port; port = port->next) { + monitor_printf(mon, "%10s %-4s %-3s %2s %-3s\n", + port->value->name, + port->value->enabled ? port->value->link_up ? + "up" : "down" : "!ena", + port->value->speed == 10000 ? "10G" : "??", + port->value->duplex ? "FD" : "HD", + port->value->autoneg ? "Yes" : "No"); + } + + qapi_free_RockerPortList(list); +} + +void hmp_rocker_of_dpa_flows(Monitor *mon, const QDict *qdict) +{ + RockerOfDpaFlowList *list, *info; + const char *name = qdict_get_str(qdict, "name"); + uint32_t tbl_id = qdict_get_try_int(qdict, "tbl_id", -1); + Error *errp = NULL; + + list = qmp_query_rocker_of_dpa_flows(name, tbl_id != -1, tbl_id, &errp); + if (errp != NULL) { + hmp_handle_error(mon, &errp); + return; + } + + monitor_printf(mon, "prio tbl hits key(mask) --> actions\n"); + + for (info = list; info; info = info->next) { + RockerOfDpaFlow *flow = info->value; + RockerOfDpaFlowKey *key = flow->key; + RockerOfDpaFlowMask *mask = flow->mask; + RockerOfDpaFlowAction *action = flow->action; + + if (flow->hits) { + monitor_printf(mon, "%-4d %-3d %-4" PRIu64, + key->priority, key->tbl_id, flow->hits); + } else { + monitor_printf(mon, "%-4d %-3d ", + key->priority, key->tbl_id); + } + + if (key->has_in_pport) { + monitor_printf(mon, " pport %d", key->in_pport); + if (mask->has_in_pport) { + monitor_printf(mon, "(0x%x)", mask->in_pport); + } + } + + if (key->has_vlan_id) { + monitor_printf(mon, " vlan %d", + key->vlan_id & VLAN_VID_MASK); + if (mask->has_vlan_id) { + monitor_printf(mon, "(0x%x)", mask->vlan_id); + } + } + + if (key->has_tunnel_id) { + monitor_printf(mon, " tunnel %d", key->tunnel_id); + if (mask->has_tunnel_id) { + monitor_printf(mon, "(0x%x)", mask->tunnel_id); + } + } + + if (key->has_eth_type) { + switch (key->eth_type) { + case 0x0806: + monitor_printf(mon, " ARP"); + break; + case 0x0800: + monitor_printf(mon, " IP"); + break; + case 0x86dd: + monitor_printf(mon, " IPv6"); + break; + case 0x8809: + monitor_printf(mon, " LACP"); + break; + case 0x88cc: + monitor_printf(mon, " LLDP"); + break; + default: + monitor_printf(mon, " eth type 0x%04x", key->eth_type); + break; + } + } + + if (key->has_eth_src) { + if ((strcmp(key->eth_src, "01:00:00:00:00:00") == 0) && + (mask->has_eth_src) && + (strcmp(mask->eth_src, "01:00:00:00:00:00") == 0)) { + monitor_printf(mon, " src "); + } else if ((strcmp(key->eth_src, "00:00:00:00:00:00") == 0) && + (mask->has_eth_src) && + (strcmp(mask->eth_src, "01:00:00:00:00:00") == 0)) { + monitor_printf(mon, " src "); + } else { + monitor_printf(mon, " src %s", key->eth_src); + if (mask->has_eth_src) { + monitor_printf(mon, "(%s)", mask->eth_src); + } + } + } + + if (key->has_eth_dst) { + if ((strcmp(key->eth_dst, "01:00:00:00:00:00") == 0) && + (mask->has_eth_dst) && + (strcmp(mask->eth_dst, "01:00:00:00:00:00") == 0)) { + monitor_printf(mon, " dst "); + } else if ((strcmp(key->eth_dst, "00:00:00:00:00:00") == 0) && + (mask->has_eth_dst) && + (strcmp(mask->eth_dst, "01:00:00:00:00:00") == 0)) { + monitor_printf(mon, " dst "); + } else { + monitor_printf(mon, " dst %s", key->eth_dst); + if (mask->has_eth_dst) { + monitor_printf(mon, "(%s)", mask->eth_dst); + } + } + } + + if (key->has_ip_proto) { + monitor_printf(mon, " proto %d", key->ip_proto); + if (mask->has_ip_proto) { + monitor_printf(mon, "(0x%x)", mask->ip_proto); + } + } + + if (key->has_ip_tos) { + monitor_printf(mon, " TOS %d", key->ip_tos); + if (mask->has_ip_tos) { + monitor_printf(mon, "(0x%x)", mask->ip_tos); + } + } + + if (key->has_ip_dst) { + monitor_printf(mon, " dst %s", key->ip_dst); + } + + if (action->has_goto_tbl || action->has_group_id || + action->has_new_vlan_id) { + monitor_printf(mon, " -->"); + } + + if (action->has_new_vlan_id) { + monitor_printf(mon, " apply new vlan %d", + ntohs(action->new_vlan_id)); + } + + if (action->has_group_id) { + monitor_printf(mon, " write group 0x%08x", action->group_id); + } + + if (action->has_goto_tbl) { + monitor_printf(mon, " goto tbl %d", action->goto_tbl); + } + + monitor_printf(mon, "\n"); + } + + qapi_free_RockerOfDpaFlowList(list); +} + +void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict) +{ + RockerOfDpaGroupList *list, *g; + const char *name = qdict_get_str(qdict, "name"); + uint8_t type = qdict_get_try_int(qdict, "type", 9); + Error *errp = NULL; + bool set = false; + + list = qmp_query_rocker_of_dpa_groups(name, type != 9, type, &errp); + if (errp != NULL) { + hmp_handle_error(mon, &errp); + return; + } + + monitor_printf(mon, "id (decode) --> buckets\n"); + + for (g = list; g; g = g->next) { + RockerOfDpaGroup *group = g->value; + + monitor_printf(mon, "0x%08x", group->id); + + monitor_printf(mon, " (type %s", group->type == 0 ? "L2 interface" : + group->type == 1 ? "L2 rewrite" : + group->type == 2 ? "L3 unicast" : + group->type == 3 ? "L2 multicast" : + group->type == 4 ? "L2 flood" : + group->type == 5 ? "L3 interface" : + group->type == 6 ? "L3 multicast" : + group->type == 7 ? "L3 ECMP" : + group->type == 8 ? "L2 overlay" : + "unknown"); + + if (group->has_vlan_id) { + monitor_printf(mon, " vlan %d", group->vlan_id); + } + + if (group->has_pport) { + monitor_printf(mon, " pport %d", group->pport); + } + + if (group->has_index) { + monitor_printf(mon, " index %d", group->index); + } + + monitor_printf(mon, ") -->"); + + if (group->has_set_vlan_id && group->set_vlan_id) { + set = true; + monitor_printf(mon, " set vlan %d", + group->set_vlan_id & VLAN_VID_MASK); + } + + if (group->has_set_eth_src) { + if (!set) { + set = true; + monitor_printf(mon, " set"); + } + monitor_printf(mon, " src %s", group->set_eth_src); + } + + if (group->has_set_eth_dst) { + if (!set) { + set = true; + monitor_printf(mon, " set"); + } + monitor_printf(mon, " dst %s", group->set_eth_dst); + } + + set = false; + + if (group->has_ttl_check && group->ttl_check) { + monitor_printf(mon, " check TTL"); + } + + if (group->has_group_id && group->group_id) { + monitor_printf(mon, " group id 0x%08x", group->group_id); + } + + if (group->has_pop_vlan && group->pop_vlan) { + monitor_printf(mon, " pop vlan"); + } + + if (group->has_out_pport) { + monitor_printf(mon, " out pport %d", group->out_pport); + } + + if (group->has_group_ids) { + struct uint32List *id; + + monitor_printf(mon, " groups ["); + for (id = group->group_ids; id; id = id->next) { + monitor_printf(mon, "0x%08x", id->value); + if (id->next) { + monitor_printf(mon, ","); + } + } + monitor_printf(mon, "]"); + } + + monitor_printf(mon, "\n"); + } + + qapi_free_RockerOfDpaGroupList(list); +} diff --git a/hmp.h b/hmp.h index a70ac4fd0f..0cf4f2a3d1 100644 --- a/hmp.h +++ b/hmp.h @@ -124,5 +124,9 @@ void host_net_remove_completion(ReadLineState *rs, int nb_args, const char *str); void delvm_completion(ReadLineState *rs, int nb_args, const char *str); void loadvm_completion(ReadLineState *rs, int nb_args, const char *str); +void hmp_rocker(Monitor *mon, const QDict *qdict); +void hmp_rocker_ports(Monitor *mon, const QDict *qdict); +void hmp_rocker_of_dpa_flows(Monitor *mon, const QDict *qdict); +void hmp_rocker_of_dpa_groups(Monitor *mon, const QDict *qdict); #endif diff --git a/hw/net/Makefile.objs b/hw/net/Makefile.objs index 7b91c4e51d..98801739ef 100644 --- a/hw/net/Makefile.objs +++ b/hw/net/Makefile.objs @@ -39,3 +39,4 @@ obj-$(CONFIG_ETSEC) += fsl_etsec/etsec.o fsl_etsec/registers.o \ common-obj-$(CONFIG_ROCKER) += rocker/rocker.o rocker/rocker_fp.o \ rocker/rocker_desc.o rocker/rocker_world.o \ rocker/rocker_of_dpa.o +obj-$(call lnot,$(CONFIG_ROCKER)) += rocker/qmp-norocker.o diff --git a/hw/net/rocker/qmp-norocker.c b/hw/net/rocker/qmp-norocker.c new file mode 100644 index 0000000000..f253747361 --- /dev/null +++ b/hw/net/rocker/qmp-norocker.c @@ -0,0 +1,50 @@ +/* + * QMP Target options - Commands handled based on a target config + * versus a host config + * + * Copyright (c) 2015 David Ahern + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "qemu-common.h" +#include "qmp-commands.h" +#include "qapi/qmp/qerror.h" + +RockerSwitch *qmp_query_rocker(const char *name, Error **errp) +{ + error_set(errp, QERR_FEATURE_DISABLED, "rocker"); + return NULL; +}; + +RockerPortList *qmp_query_rocker_ports(const char *name, Error **errp) +{ + error_set(errp, QERR_FEATURE_DISABLED, "rocker"); + return NULL; +}; + +RockerOfDpaFlowList *qmp_query_rocker_of_dpa_flows(const char *name, + bool has_tbl_id, + uint32_t tbl_id, + Error **errp) +{ + error_set(errp, QERR_FEATURE_DISABLED, "rocker"); + return NULL; +}; + +RockerOfDpaGroupList *qmp_query_rocker_of_dpa_groups(const char *name, + bool has_type, + uint8_t type, + Error **errp) +{ + error_set(errp, QERR_FEATURE_DISABLED, "rocker"); + return NULL; +}; diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c index 55b6c46157..4d25842509 100644 --- a/hw/net/rocker/rocker.c +++ b/hw/net/rocker/rocker.c @@ -94,6 +94,51 @@ World *rocker_get_world(Rocker *r, enum rocker_world_type type) return NULL; } +RockerSwitch *qmp_query_rocker(const char *name, Error **errp) +{ + RockerSwitch *rocker = g_malloc0(sizeof(*rocker)); + Rocker *r; + + r = rocker_find(name); + if (!r) { + error_set(errp, ERROR_CLASS_GENERIC_ERROR, + "rocker %s not found", name); + return NULL; + } + + rocker->name = g_strdup(r->name); + rocker->id = r->switch_id; + rocker->ports = r->fp_ports; + + return rocker; +} + +RockerPortList *qmp_query_rocker_ports(const char *name, Error **errp) +{ + RockerPortList *list = NULL; + Rocker *r; + int i; + + r = rocker_find(name); + if (!r) { + error_set(errp, ERROR_CLASS_GENERIC_ERROR, + "rocker %s not found", name); + return NULL; + } + + for (i = r->fp_ports - 1; i >= 0; i--) { + RockerPortList *info = g_malloc0(sizeof(*info)); + info->value = g_malloc0(sizeof(*info->value)); + struct fp_port *port = r->fp_port[i]; + + fp_port_get_info(port, info); + info->next = list; + list = info; + } + + return list; +} + uint32_t rocker_fp_ports(Rocker *r) { return r->fp_ports; @@ -238,6 +283,7 @@ static int cmd_get_port_settings(Rocker *r, uint8_t duplex; uint8_t autoneg; uint8_t learning; + char *phys_name; MACAddr macaddr; enum rocker_world_type mode; size_t tlv_size; @@ -265,6 +311,7 @@ static int cmd_get_port_settings(Rocker *r, fp_port_get_macaddr(fp_port, &macaddr); mode = world_type(fp_port_get_world(fp_port)); learning = fp_port_get_learning(fp_port); + phys_name = fp_port_get_name(fp_port); tlv_size = rocker_tlv_total_size(0) + /* nest */ rocker_tlv_total_size(sizeof(uint32_t)) + /* pport */ @@ -273,7 +320,8 @@ static int cmd_get_port_settings(Rocker *r, rocker_tlv_total_size(sizeof(uint8_t)) + /* autoneg */ rocker_tlv_total_size(sizeof(macaddr.a)) + /* macaddr */ rocker_tlv_total_size(sizeof(uint8_t)) + /* mode */ - rocker_tlv_total_size(sizeof(uint8_t)); /* learning */ + rocker_tlv_total_size(sizeof(uint8_t)) + /* learning */ + rocker_tlv_total_size(strlen(phys_name)); if (tlv_size > desc_buf_size(info)) { return -ROCKER_EMSGSIZE; @@ -290,6 +338,8 @@ static int cmd_get_port_settings(Rocker *r, rocker_tlv_put_u8(buf, &pos, ROCKER_TLV_CMD_PORT_SETTINGS_MODE, mode); rocker_tlv_put_u8(buf, &pos, ROCKER_TLV_CMD_PORT_SETTINGS_LEARNING, learning); + rocker_tlv_put(buf, &pos, ROCKER_TLV_CMD_PORT_SETTINGS_PHYS_NAME, + strlen(phys_name), phys_name); rocker_tlv_nest_end(buf, &pos, nest); return desc_set_buf(info, tlv_size); @@ -1277,6 +1327,22 @@ static int pci_rocker_init(PCIDevice *dev) goto err_duplicate; } + /* Rocker name is passed in port name requests to OS with the intention + * that the name is used in interface names. Limit the length of the + * rocker name to avoid naming problems in the OS. Also, adding the + * port number as p# and unganged breakout b#, where # is at most 2 + * digits, so leave room for it too (-1 for string terminator, -3 for + * p# and -3 for b#) + */ +#define ROCKER_IFNAMSIZ 16 +#define MAX_ROCKER_NAME_LEN (ROCKER_IFNAMSIZ - 1 - 3 - 3) + if (strlen(r->name) > MAX_ROCKER_NAME_LEN) { + fprintf(stderr, + "rocker: name too long; please shorten to at most %d chars\n", + MAX_ROCKER_NAME_LEN); + return -EINVAL; + } + if (memcmp(&r->fp_start_macaddr, &zero, sizeof(zero)) == 0) { memcpy(&r->fp_start_macaddr, &dflt, sizeof(dflt)); r->fp_start_macaddr.a[4] += (sw_index++); diff --git a/hw/net/rocker/rocker_fp.c b/hw/net/rocker/rocker_fp.c index 2f1e3b348a..d8d934c396 100644 --- a/hw/net/rocker/rocker_fp.c +++ b/hw/net/rocker/rocker_fp.c @@ -41,11 +41,26 @@ struct fp_port { NICConf conf; }; +char *fp_port_get_name(FpPort *port) +{ + return port->name; +} + bool fp_port_get_link_up(FpPort *port) { return !qemu_get_queue(port->nic)->link_down; } +void fp_port_get_info(FpPort *port, RockerPortList *info) +{ + info->value->name = g_strdup(port->name); + info->value->enabled = port->enabled; + info->value->link_up = fp_port_get_link_up(port); + info->value->speed = port->speed; + info->value->duplex = port->duplex; + info->value->autoneg = port->autoneg; +} + void fp_port_get_macaddr(FpPort *port, MACAddr *macaddr) { memcpy(macaddr->a, port->conf.macaddr.a, sizeof(macaddr->a)); @@ -173,8 +188,19 @@ bool fp_port_enabled(FpPort *port) return port->enabled; } +static void fp_port_set_link(FpPort *port, bool up) +{ + NetClientState *nc = qemu_get_queue(port->nic); + + if (up == nc->link_down) { + nc->link_down = !up; + nc->info->link_status_changed(nc); + } +} + void fp_port_enable(FpPort *port) { + fp_port_set_link(port, true); port->enabled = true; DPRINTF("port %d enabled\n", port->index); } @@ -182,6 +208,7 @@ void fp_port_enable(FpPort *port) void fp_port_disable(FpPort *port) { port->enabled = false; + fp_port_set_link(port, false); DPRINTF("port %d disabled\n", port->index); } @@ -201,7 +228,7 @@ FpPort *fp_port_alloc(Rocker *r, char *sw_name, /* front-panel switch port names are 1-based */ - port->name = g_strdup_printf("%s.%d", sw_name, port->pport); + port->name = g_strdup_printf("%sp%d", sw_name, port->pport); memcpy(port->conf.macaddr.a, start_mac, sizeof(port->conf.macaddr.a)); port->conf.macaddr.a[5] += index; diff --git a/hw/net/rocker/rocker_fp.h b/hw/net/rocker/rocker_fp.h index a5f28f120d..ab80fd833c 100644 --- a/hw/net/rocker/rocker_fp.h +++ b/hw/net/rocker/rocker_fp.h @@ -26,7 +26,9 @@ typedef struct fp_port FpPort; int fp_port_eg(FpPort *port, const struct iovec *iov, int iovcnt); +char *fp_port_get_name(FpPort *port); bool fp_port_get_link_up(FpPort *port); +void fp_port_get_info(FpPort *port, RockerPortList *info); void fp_port_get_macaddr(FpPort *port, MACAddr *macaddr); void fp_port_set_macaddr(FpPort *port, MACAddr *macaddr); uint8_t fp_port_get_learning(FpPort *port); diff --git a/hw/net/rocker/rocker_hw.h b/hw/net/rocker/rocker_hw.h index c9c85a75bd..fe639badd4 100644 --- a/hw/net/rocker/rocker_hw.h +++ b/hw/net/rocker/rocker_hw.h @@ -179,6 +179,7 @@ enum { ROCKER_TLV_CMD_PORT_SETTINGS_MACADDR, /* binary */ ROCKER_TLV_CMD_PORT_SETTINGS_MODE, /* u8 */ ROCKER_TLV_CMD_PORT_SETTINGS_LEARNING, /* u8 */ + ROCKER_TLV_CMD_PORT_SETTINGS_PHYS_NAME, /* binary */ __ROCKER_TLV_CMD_PORT_SETTINGS_MAX, ROCKER_TLV_CMD_PORT_SETTINGS_MAX = __ROCKER_TLV_CMD_PORT_SETTINGS_MAX - 1, diff --git a/hw/net/rocker/rocker_of_dpa.c b/hw/net/rocker/rocker_of_dpa.c index 1bcb7af5ef..b25a17d6d7 100644 --- a/hw/net/rocker/rocker_of_dpa.c +++ b/hw/net/rocker/rocker_of_dpa.c @@ -2302,6 +2302,318 @@ static void of_dpa_uninit(World *world) g_hash_table_destroy(of_dpa->flow_tbl); } +struct of_dpa_flow_fill_context { + RockerOfDpaFlowList *list; + uint32_t tbl_id; +}; + +static void of_dpa_flow_fill(void *cookie, void *value, void *user_data) +{ + struct of_dpa_flow *flow = value; + struct of_dpa_flow_key *key = &flow->key; + struct of_dpa_flow_key *mask = &flow->mask; + struct of_dpa_flow_fill_context *flow_context = user_data; + RockerOfDpaFlowList *new; + RockerOfDpaFlow *nflow; + RockerOfDpaFlowKey *nkey; + RockerOfDpaFlowMask *nmask; + RockerOfDpaFlowAction *naction; + + if (flow_context->tbl_id != -1 && + flow_context->tbl_id != key->tbl_id) { + return; + } + + new = g_malloc0(sizeof(*new)); + nflow = new->value = g_malloc0(sizeof(*nflow)); + nkey = nflow->key = g_malloc0(sizeof(*nkey)); + nmask = nflow->mask = g_malloc0(sizeof(*nmask)); + naction = nflow->action = g_malloc0(sizeof(*naction)); + + nflow->cookie = flow->cookie; + nflow->hits = flow->stats.hits; + nkey->priority = flow->priority; + nkey->tbl_id = key->tbl_id; + + if (key->in_pport || mask->in_pport) { + nkey->has_in_pport = true; + nkey->in_pport = key->in_pport; + } + + if (nkey->has_in_pport && mask->in_pport != 0xffffffff) { + nmask->has_in_pport = true; + nmask->in_pport = mask->in_pport; + } + + if (key->eth.vlan_id || mask->eth.vlan_id) { + nkey->has_vlan_id = true; + nkey->vlan_id = ntohs(key->eth.vlan_id); + } + + if (nkey->has_vlan_id && mask->eth.vlan_id != 0xffff) { + nmask->has_vlan_id = true; + nmask->vlan_id = ntohs(mask->eth.vlan_id); + } + + if (key->tunnel_id || mask->tunnel_id) { + nkey->has_tunnel_id = true; + nkey->tunnel_id = key->tunnel_id; + } + + if (nkey->has_tunnel_id && mask->tunnel_id != 0xffffffff) { + nmask->has_tunnel_id = true; + nmask->tunnel_id = mask->tunnel_id; + } + + if (memcmp(key->eth.src.a, zero_mac.a, ETH_ALEN) || + memcmp(mask->eth.src.a, zero_mac.a, ETH_ALEN)) { + nkey->has_eth_src = true; + nkey->eth_src = qemu_mac_strdup_printf(key->eth.src.a); + } + + if (nkey->has_eth_src && memcmp(mask->eth.src.a, ff_mac.a, ETH_ALEN)) { + nmask->has_eth_src = true; + nmask->eth_src = qemu_mac_strdup_printf(mask->eth.src.a); + } + + if (memcmp(key->eth.dst.a, zero_mac.a, ETH_ALEN) || + memcmp(mask->eth.dst.a, zero_mac.a, ETH_ALEN)) { + nkey->has_eth_dst = true; + nkey->eth_dst = qemu_mac_strdup_printf(key->eth.dst.a); + } + + if (nkey->has_eth_dst && memcmp(mask->eth.dst.a, ff_mac.a, ETH_ALEN)) { + nmask->has_eth_dst = true; + nmask->eth_dst = qemu_mac_strdup_printf(mask->eth.dst.a); + } + + if (key->eth.type) { + + nkey->has_eth_type = true; + nkey->eth_type = ntohs(key->eth.type); + + switch (ntohs(key->eth.type)) { + case 0x0800: + case 0x86dd: + if (key->ip.proto || mask->ip.proto) { + nkey->has_ip_proto = true; + nkey->ip_proto = key->ip.proto; + } + if (nkey->has_ip_proto && mask->ip.proto != 0xff) { + nmask->has_ip_proto = true; + nmask->ip_proto = mask->ip.proto; + } + if (key->ip.tos || mask->ip.tos) { + nkey->has_ip_tos = true; + nkey->ip_tos = key->ip.tos; + } + if (nkey->has_ip_tos && mask->ip.tos != 0xff) { + nmask->has_ip_tos = true; + nmask->ip_tos = mask->ip.tos; + } + break; + } + + switch (ntohs(key->eth.type)) { + case 0x0800: + if (key->ipv4.addr.dst || mask->ipv4.addr.dst) { + char *dst = inet_ntoa(*(struct in_addr *)&key->ipv4.addr.dst); + int dst_len = of_dpa_mask2prefix(mask->ipv4.addr.dst); + nkey->has_ip_dst = true; + nkey->ip_dst = g_strdup_printf("%s/%d", dst, dst_len); + } + break; + } + } + + if (flow->action.goto_tbl) { + naction->has_goto_tbl = true; + naction->goto_tbl = flow->action.goto_tbl; + } + + if (flow->action.write.group_id) { + naction->has_group_id = true; + naction->group_id = flow->action.write.group_id; + } + + if (flow->action.apply.new_vlan_id) { + naction->has_new_vlan_id = true; + naction->new_vlan_id = flow->action.apply.new_vlan_id; + } + + new->next = flow_context->list; + flow_context->list = new; +} + +RockerOfDpaFlowList *qmp_query_rocker_of_dpa_flows(const char *name, + bool has_tbl_id, + uint32_t tbl_id, + Error **errp) +{ + struct rocker *r; + struct world *w; + struct of_dpa *of_dpa; + struct of_dpa_flow_fill_context fill_context = { + .list = NULL, + .tbl_id = tbl_id, + }; + + r = rocker_find(name); + if (!r) { + error_set(errp, ERROR_CLASS_GENERIC_ERROR, + "rocker %s not found", name); + return NULL; + } + + w = rocker_get_world(r, ROCKER_WORLD_TYPE_OF_DPA); + if (!w) { + error_set(errp, ERROR_CLASS_GENERIC_ERROR, + "rocker %s doesn't have OF-DPA world", name); + return NULL; + } + + of_dpa = world_private(w); + + g_hash_table_foreach(of_dpa->flow_tbl, of_dpa_flow_fill, &fill_context); + + return fill_context.list; +} + +struct of_dpa_group_fill_context { + RockerOfDpaGroupList *list; + uint8_t type; +}; + +static void of_dpa_group_fill(void *key, void *value, void *user_data) +{ + struct of_dpa_group *group = value; + struct of_dpa_group_fill_context *flow_context = user_data; + RockerOfDpaGroupList *new; + RockerOfDpaGroup *ngroup; + struct uint32List *id; + int i; + + if (flow_context->type != 9 && + flow_context->type != ROCKER_GROUP_TYPE_GET(group->id)) { + return; + } + + new = g_malloc0(sizeof(*new)); + ngroup = new->value = g_malloc0(sizeof(*ngroup)); + + ngroup->id = group->id; + + ngroup->type = ROCKER_GROUP_TYPE_GET(group->id); + + switch (ngroup->type) { + case ROCKER_OF_DPA_GROUP_TYPE_L2_INTERFACE: + ngroup->has_vlan_id = true; + ngroup->vlan_id = ROCKER_GROUP_VLAN_GET(group->id); + ngroup->has_pport = true; + ngroup->pport = ROCKER_GROUP_PORT_GET(group->id); + ngroup->has_out_pport = true; + ngroup->out_pport = group->l2_interface.out_pport; + ngroup->has_pop_vlan = true; + ngroup->pop_vlan = group->l2_interface.pop_vlan; + break; + case ROCKER_OF_DPA_GROUP_TYPE_L2_REWRITE: + ngroup->has_index = true; + ngroup->index = ROCKER_GROUP_INDEX_LONG_GET(group->id); + ngroup->has_group_id = true; + ngroup->group_id = group->l2_rewrite.group_id; + if (group->l2_rewrite.vlan_id) { + ngroup->has_set_vlan_id = true; + ngroup->set_vlan_id = ntohs(group->l2_rewrite.vlan_id); + } + break; + if (memcmp(group->l2_rewrite.src_mac.a, zero_mac.a, ETH_ALEN)) { + ngroup->has_set_eth_src = true; + ngroup->set_eth_src = + qemu_mac_strdup_printf(group->l2_rewrite.src_mac.a); + } + if (memcmp(group->l2_rewrite.dst_mac.a, zero_mac.a, ETH_ALEN)) { + ngroup->has_set_eth_dst = true; + ngroup->set_eth_dst = + qemu_mac_strdup_printf(group->l2_rewrite.dst_mac.a); + } + case ROCKER_OF_DPA_GROUP_TYPE_L2_FLOOD: + case ROCKER_OF_DPA_GROUP_TYPE_L2_MCAST: + ngroup->has_vlan_id = true; + ngroup->vlan_id = ROCKER_GROUP_VLAN_GET(group->id); + ngroup->has_index = true; + ngroup->index = ROCKER_GROUP_INDEX_GET(group->id); + for (i = 0; i < group->l2_flood.group_count; i++) { + ngroup->has_group_ids = true; + id = g_malloc0(sizeof(*id)); + id->value = group->l2_flood.group_ids[i]; + id->next = ngroup->group_ids; + ngroup->group_ids = id; + } + break; + case ROCKER_OF_DPA_GROUP_TYPE_L3_UCAST: + ngroup->has_index = true; + ngroup->index = ROCKER_GROUP_INDEX_LONG_GET(group->id); + ngroup->has_group_id = true; + ngroup->group_id = group->l3_unicast.group_id; + if (group->l3_unicast.vlan_id) { + ngroup->has_set_vlan_id = true; + ngroup->set_vlan_id = ntohs(group->l3_unicast.vlan_id); + } + if (memcmp(group->l3_unicast.src_mac.a, zero_mac.a, ETH_ALEN)) { + ngroup->has_set_eth_src = true; + ngroup->set_eth_src = + qemu_mac_strdup_printf(group->l3_unicast.src_mac.a); + } + if (memcmp(group->l3_unicast.dst_mac.a, zero_mac.a, ETH_ALEN)) { + ngroup->has_set_eth_dst = true; + ngroup->set_eth_dst = + qemu_mac_strdup_printf(group->l3_unicast.dst_mac.a); + } + if (group->l3_unicast.ttl_check) { + ngroup->has_ttl_check = true; + ngroup->ttl_check = group->l3_unicast.ttl_check; + } + break; + } + + new->next = flow_context->list; + flow_context->list = new; +} + +RockerOfDpaGroupList *qmp_query_rocker_of_dpa_groups(const char *name, + bool has_type, + uint8_t type, + Error **errp) +{ + struct rocker *r; + struct world *w; + struct of_dpa *of_dpa; + struct of_dpa_group_fill_context fill_context = { + .list = NULL, + .type = type, + }; + + r = rocker_find(name); + if (!r) { + error_set(errp, ERROR_CLASS_GENERIC_ERROR, + "rocker %s not found", name); + return NULL; + } + + w = rocker_get_world(r, ROCKER_WORLD_TYPE_OF_DPA); + if (!w) { + error_set(errp, ERROR_CLASS_GENERIC_ERROR, + "rocker %s doesn't have OF-DPA world", name); + return NULL; + } + + of_dpa = world_private(w); + + g_hash_table_foreach(of_dpa->group_tbl, of_dpa_group_fill, &fill_context); + + return fill_context.list; +} + static WorldOps of_dpa_ops = { .init = of_dpa_init, .uninit = of_dpa_uninit, diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c index b2cb22b99d..2510e2e4ff 100644 --- a/hw/xen/xen_backend.c +++ b/hw/xen/xen_backend.c @@ -714,9 +714,7 @@ int xen_be_init(void) return -1; } - if (qemu_set_fd_handler(xs_fileno(xenstore), xenstore_update, NULL, NULL) < 0) { - goto err; - } + qemu_set_fd_handler(xs_fileno(xenstore), xenstore_update, NULL, NULL); if (xen_xc == XC_HANDLER_INITIAL_VALUE) { /* Check if xen_init() have been called */ diff --git a/include/block/aio.h b/include/block/aio.h index d2bb423de1..b46103ece7 100644 --- a/include/block/aio.h +++ b/include/block/aio.h @@ -241,7 +241,7 @@ bool aio_dispatch(AioContext *ctx); bool aio_poll(AioContext *ctx, bool blocking); /* Register a file descriptor and associated callbacks. Behaves very similarly - * to qemu_set_fd_handler2. Unlike qemu_set_fd_handler2, these callbacks will + * to qemu_set_fd_handler. Unlike qemu_set_fd_handler, these callbacks will * be invoked when using aio_poll(). * * Code that invokes AIO completion functions should rely on this function diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h index 62c68c0f32..0f4a0fd4b2 100644 --- a/include/qemu/main-loop.h +++ b/include/qemu/main-loop.h @@ -96,8 +96,7 @@ AioContext *qemu_get_aio_context(void); * that the main loop waits for. * * Calling qemu_notify_event is rarely necessary, because main loop - * services (bottom halves and timers) call it themselves. One notable - * exception occurs when using qemu_set_fd_handler2 (see below). + * services (bottom halves and timers) call it themselves. */ void qemu_notify_event(void); @@ -171,52 +170,6 @@ void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque); typedef void IOReadHandler(void *opaque, const uint8_t *buf, int size); typedef int IOCanReadHandler(void *opaque); -/** - * qemu_set_fd_handler2: Register a file descriptor with the main loop - * - * This function tells the main loop to wake up whenever one of the - * following conditions is true: - * - * 1) if @fd_write is not %NULL, when the file descriptor is writable; - * - * 2) if @fd_read is not %NULL, when the file descriptor is readable. - * - * @fd_read_poll can be used to disable the @fd_read callback temporarily. - * This is useful to avoid calling qemu_set_fd_handler2 every time the - * client becomes interested in reading (or dually, stops being interested). - * A typical example is when @fd is a listening socket and you want to bound - * the number of active clients. Remember to call qemu_notify_event whenever - * the condition may change from %false to %true. - * - * The callbacks that are set up by qemu_set_fd_handler2 are level-triggered. - * If @fd_read does not read from @fd, or @fd_write does not write to @fd - * until its buffers are full, they will be called again on the next - * iteration. - * - * @fd: The file descriptor to be observed. Under Windows it must be - * a #SOCKET. - * - * @fd_read_poll: A function that returns 1 if the @fd_read callback - * should be fired. If the function returns 0, the main loop will not - * end its iteration even if @fd becomes readable. - * - * @fd_read: A level-triggered callback that is fired if @fd is readable - * at the beginning of a main loop iteration, or if it becomes readable - * during one. - * - * @fd_write: A level-triggered callback that is fired when @fd is writable - * at the beginning of a main loop iteration, or if it becomes writable - * during one. - * - * @opaque: A pointer-sized value that is passed to @fd_read_poll, - * @fd_read and @fd_write. - */ -int qemu_set_fd_handler2(int fd, - IOCanReadHandler *fd_read_poll, - IOHandler *fd_read, - IOHandler *fd_write, - void *opaque); - /** * qemu_set_fd_handler: Register a file descriptor with the main loop * @@ -245,10 +198,10 @@ int qemu_set_fd_handler2(int fd, * * @opaque: A pointer-sized value that is passed to @fd_read and @fd_write. */ -int qemu_set_fd_handler(int fd, - IOHandler *fd_read, - IOHandler *fd_write, - void *opaque); +void qemu_set_fd_handler(int fd, + IOHandler *fd_read, + IOHandler *fd_write, + void *opaque); #ifdef CONFIG_POSIX /** diff --git a/iohandler.c b/iohandler.c index cca614f087..826f713e9f 100644 --- a/iohandler.c +++ b/iohandler.c @@ -33,7 +33,6 @@ #endif typedef struct IOHandlerRecord { - IOCanReadHandler *fd_read_poll; IOHandler *fd_read; IOHandler *fd_write; void *opaque; @@ -46,11 +45,7 @@ typedef struct IOHandlerRecord { static QLIST_HEAD(, IOHandlerRecord) io_handlers = QLIST_HEAD_INITIALIZER(io_handlers); - -/* XXX: fd_read_poll should be suppressed, but an API change is - necessary in the character devices to suppress fd_can_read(). */ -int qemu_set_fd_handler2(int fd, - IOCanReadHandler *fd_read_poll, +void qemu_set_fd_handler(int fd, IOHandler *fd_read, IOHandler *fd_write, void *opaque) @@ -75,7 +70,6 @@ int qemu_set_fd_handler2(int fd, QLIST_INSERT_HEAD(&io_handlers, ioh, next); found: ioh->fd = fd; - ioh->fd_read_poll = fd_read_poll; ioh->fd_read = fd_read; ioh->fd_write = fd_write; ioh->opaque = opaque; @@ -83,15 +77,6 @@ int qemu_set_fd_handler2(int fd, ioh->deleted = 0; qemu_notify_event(); } - return 0; -} - -int qemu_set_fd_handler(int fd, - IOHandler *fd_read, - IOHandler *fd_write, - void *opaque) -{ - return qemu_set_fd_handler2(fd, NULL, fd_read, fd_write, opaque); } void qemu_iohandler_fill(GArray *pollfds) @@ -103,9 +88,7 @@ void qemu_iohandler_fill(GArray *pollfds) if (ioh->deleted) continue; - if (ioh->fd_read && - (!ioh->fd_read_poll || - ioh->fd_read_poll(ioh->opaque) != 0)) { + if (ioh->fd_read) { events |= G_IO_IN | G_IO_HUP | G_IO_ERR; } if (ioh->fd_write) { diff --git a/main-loop.c b/main-loop.c index 981bcb5f8e..82875a4dfd 100644 --- a/main-loop.c +++ b/main-loop.c @@ -100,8 +100,7 @@ static int qemu_signal_init(void) fcntl_setfl(sigfd, O_NONBLOCK); - qemu_set_fd_handler2(sigfd, NULL, sigfd_handler, NULL, - (void *)(intptr_t)sigfd); + qemu_set_fd_handler(sigfd, sigfd_handler, NULL, (void *)(intptr_t)sigfd); return 0; } diff --git a/migration/exec.c b/migration/exec.c index 479024752f..8406d2bbde 100644 --- a/migration/exec.c +++ b/migration/exec.c @@ -49,7 +49,7 @@ static void exec_accept_incoming_migration(void *opaque) { QEMUFile *f = opaque; - qemu_set_fd_handler2(qemu_get_fd(f), NULL, NULL, NULL, NULL); + qemu_set_fd_handler(qemu_get_fd(f), NULL, NULL, NULL); process_incoming_migration(f); } @@ -64,6 +64,6 @@ void exec_start_incoming_migration(const char *command, Error **errp) return; } - qemu_set_fd_handler2(qemu_get_fd(f), NULL, - exec_accept_incoming_migration, NULL, f); + qemu_set_fd_handler(qemu_get_fd(f), exec_accept_incoming_migration, NULL, + f); } diff --git a/migration/fd.c b/migration/fd.c index 129da9910b..3e4bed0e06 100644 --- a/migration/fd.c +++ b/migration/fd.c @@ -62,7 +62,7 @@ static void fd_accept_incoming_migration(void *opaque) { QEMUFile *f = opaque; - qemu_set_fd_handler2(qemu_get_fd(f), NULL, NULL, NULL, NULL); + qemu_set_fd_handler(qemu_get_fd(f), NULL, NULL, NULL); process_incoming_migration(f); } @@ -84,5 +84,5 @@ void fd_start_incoming_migration(const char *infd, Error **errp) return; } - qemu_set_fd_handler2(fd, NULL, fd_accept_incoming_migration, NULL, f); + qemu_set_fd_handler(fd, fd_accept_incoming_migration, NULL, f); } diff --git a/migration/rdma.c b/migration/rdma.c index 48b3e64b34..cf5de7e2ae 100644 --- a/migration/rdma.c +++ b/migration/rdma.c @@ -2840,7 +2840,7 @@ static int qemu_rdma_accept(RDMAContext *rdma) } } - qemu_set_fd_handler2(rdma->channel->fd, NULL, NULL, NULL, NULL); + qemu_set_fd_handler(rdma->channel->fd, NULL, NULL, NULL); ret = rdma_accept(rdma->cm_id, &conn_param); if (ret) { @@ -3337,9 +3337,8 @@ void rdma_start_incoming_migration(const char *host_port, Error **errp) trace_rdma_start_incoming_migration_after_rdma_listen(); - qemu_set_fd_handler2(rdma->channel->fd, NULL, - rdma_accept_incoming_migration, NULL, - (void *)(intptr_t) rdma); + qemu_set_fd_handler(rdma->channel->fd, rdma_accept_incoming_migration, + NULL, (void *)(intptr_t)rdma); return; err: error_propagate(errp, local_err); diff --git a/migration/tcp.c b/migration/tcp.c index 91c9cf381e..ae891728ef 100644 --- a/migration/tcp.c +++ b/migration/tcp.c @@ -65,7 +65,7 @@ static void tcp_accept_incoming_migration(void *opaque) c = qemu_accept(s, (struct sockaddr *)&addr, &addrlen); err = socket_error(); } while (c < 0 && err == EINTR); - qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL); + qemu_set_fd_handler(s, NULL, NULL, NULL); closesocket(s); DPRINTF("accepted migration\n"); @@ -98,6 +98,6 @@ void tcp_start_incoming_migration(const char *host_port, Error **errp) return; } - qemu_set_fd_handler2(s, NULL, tcp_accept_incoming_migration, NULL, - (void *)(intptr_t)s); + qemu_set_fd_handler(s, tcp_accept_incoming_migration, NULL, + (void *)(intptr_t)s); } diff --git a/migration/unix.c b/migration/unix.c index 1cdadfbc83..b591813eb9 100644 --- a/migration/unix.c +++ b/migration/unix.c @@ -65,7 +65,7 @@ static void unix_accept_incoming_migration(void *opaque) c = qemu_accept(s, (struct sockaddr *)&addr, &addrlen); err = errno; } while (c < 0 && err == EINTR); - qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL); + qemu_set_fd_handler(s, NULL, NULL, NULL); close(s); DPRINTF("accepted migration\n"); @@ -98,6 +98,6 @@ void unix_start_incoming_migration(const char *path, Error **errp) return; } - qemu_set_fd_handler2(s, NULL, unix_accept_incoming_migration, NULL, - (void *)(intptr_t)s); + qemu_set_fd_handler(s, unix_accept_incoming_migration, NULL, + (void *)(intptr_t)s); } diff --git a/monitor.c b/monitor.c index 9afee7b946..6a4642493a 100644 --- a/monitor.c +++ b/monitor.c @@ -2862,6 +2862,34 @@ static mon_cmd_t info_cmds[] = { .help = "show memory devices", .mhandler.cmd = hmp_info_memory_devices, }, + { + .name = "rocker", + .args_type = "name:s", + .params = "name", + .help = "Show rocker switch", + .mhandler.cmd = hmp_rocker, + }, + { + .name = "rocker-ports", + .args_type = "name:s", + .params = "name", + .help = "Show rocker ports", + .mhandler.cmd = hmp_rocker_ports, + }, + { + .name = "rocker-of-dpa-flows", + .args_type = "name:s,tbl_id:i?", + .params = "name [tbl_id]", + .help = "Show rocker OF-DPA flow tables", + .mhandler.cmd = hmp_rocker_of_dpa_flows, + }, + { + .name = "rocker-of-dpa-groups", + .args_type = "name:s,type:i?", + .params = "name [type]", + .help = "Show rocker OF-DPA groups", + .mhandler.cmd = hmp_rocker_of_dpa_groups, + }, { .name = NULL, }, diff --git a/net/l2tpv3.c b/net/l2tpv3.c index ed395dc126..356dae2b72 100644 --- a/net/l2tpv3.c +++ b/net/l2tpv3.c @@ -133,17 +133,15 @@ typedef struct NetL2TPV3State { } NetL2TPV3State; -static int l2tpv3_can_send(void *opaque); static void net_l2tpv3_send(void *opaque); static void l2tpv3_writable(void *opaque); static void l2tpv3_update_fd_handler(NetL2TPV3State *s) { - qemu_set_fd_handler2(s->fd, - s->read_poll ? l2tpv3_can_send : NULL, - s->read_poll ? net_l2tpv3_send : NULL, - s->write_poll ? l2tpv3_writable : NULL, - s); + qemu_set_fd_handler(s->fd, + s->read_poll ? net_l2tpv3_send : NULL, + s->write_poll ? l2tpv3_writable : NULL, + s); } static void l2tpv3_read_poll(NetL2TPV3State *s, bool enable) @@ -169,13 +167,6 @@ static void l2tpv3_writable(void *opaque) qemu_flush_queued_packets(&s->nc); } -static int l2tpv3_can_send(void *opaque) -{ - NetL2TPV3State *s = opaque; - - return qemu_can_send_packet(&s->nc); -} - static void l2tpv3_send_completed(NetClientState *nc, ssize_t len) { NetL2TPV3State *s = DO_UPCAST(NetL2TPV3State, nc, nc); diff --git a/net/netmap.c b/net/netmap.c index 69300eb1ae..508b82947d 100644 --- a/net/netmap.c +++ b/net/netmap.c @@ -132,26 +132,16 @@ error: return -1; } -/* Tell the event-loop if the netmap backend can send packets - to the frontend. */ -static int netmap_can_send(void *opaque) -{ - NetmapState *s = opaque; - - return qemu_can_send_packet(&s->nc); -} - static void netmap_send(void *opaque); static void netmap_writable(void *opaque); /* Set the event-loop handlers for the netmap backend. */ static void netmap_update_fd_handler(NetmapState *s) { - qemu_set_fd_handler2(s->me.fd, - s->read_poll ? netmap_can_send : NULL, - s->read_poll ? netmap_send : NULL, - s->write_poll ? netmap_writable : NULL, - s); + qemu_set_fd_handler(s->me.fd, + s->read_poll ? netmap_send : NULL, + s->write_poll ? netmap_writable : NULL, + s); } /* Update the read handler. */ @@ -317,7 +307,7 @@ static void netmap_send(void *opaque) /* Keep sending while there are available packets into the netmap RX ring and the forwarding path towards the peer is open. */ - while (!nm_ring_empty(ring) && qemu_can_send_packet(&s->nc)) { + while (!nm_ring_empty(ring)) { uint32_t i; uint32_t idx; bool morefrag; diff --git a/net/socket.c b/net/socket.c index 5a19aa1881..c752696cbb 100644 --- a/net/socket.c +++ b/net/socket.c @@ -51,21 +51,12 @@ typedef struct NetSocketState { static void net_socket_accept(void *opaque); static void net_socket_writable(void *opaque); -/* Only read packets from socket when peer can receive them */ -static int net_socket_can_send(void *opaque) -{ - NetSocketState *s = opaque; - - return qemu_can_send_packet(&s->nc); -} - static void net_socket_update_fd_handler(NetSocketState *s) { - qemu_set_fd_handler2(s->fd, - s->read_poll ? net_socket_can_send : NULL, - s->read_poll ? s->send_fn : NULL, - s->write_poll ? net_socket_writable : NULL, - s); + qemu_set_fd_handler(s->fd, + s->read_poll ? s->send_fn : NULL, + s->write_poll ? net_socket_writable : NULL, + s); } static void net_socket_read_poll(NetSocketState *s, bool enable) @@ -142,6 +133,15 @@ static ssize_t net_socket_receive_dgram(NetClientState *nc, const uint8_t *buf, return ret; } +static void net_socket_send_completed(NetClientState *nc, ssize_t len) +{ + NetSocketState *s = DO_UPCAST(NetSocketState, nc, nc); + + if (!s->read_poll) { + net_socket_read_poll(s, true); + } +} + static void net_socket_send(void *opaque) { NetSocketState *s = opaque; @@ -211,9 +211,13 @@ static void net_socket_send(void *opaque) buf += l; size -= l; if (s->index >= s->packet_len) { - qemu_send_packet(&s->nc, s->buf, s->packet_len); s->index = 0; s->state = 0; + if (qemu_send_packet_async(&s->nc, s->buf, size, + net_socket_send_completed) == 0) { + net_socket_read_poll(s, false); + break; + } } break; } @@ -234,7 +238,10 @@ static void net_socket_send_dgram(void *opaque) net_socket_write_poll(s, false); return; } - qemu_send_packet(&s->nc, s->buf, size); + if (qemu_send_packet_async(&s->nc, s->buf, size, + net_socket_send_completed) == 0) { + net_socket_read_poll(s, false); + } } static int net_socket_mcast_create(struct sockaddr_in *mcastaddr, struct in_addr *localaddr) diff --git a/net/tap.c b/net/tap.c index d1ca314dcf..aa8b3f5c8c 100644 --- a/net/tap.c +++ b/net/tap.c @@ -62,17 +62,15 @@ typedef struct TAPState { static void launch_script(const char *setup_script, const char *ifname, int fd, Error **errp); -static int tap_can_send(void *opaque); static void tap_send(void *opaque); static void tap_writable(void *opaque); static void tap_update_fd_handler(TAPState *s) { - qemu_set_fd_handler2(s->fd, - s->read_poll && s->enabled ? tap_can_send : NULL, - s->read_poll && s->enabled ? tap_send : NULL, - s->write_poll && s->enabled ? tap_writable : NULL, - s); + qemu_set_fd_handler(s->fd, + s->read_poll && s->enabled ? tap_send : NULL, + s->write_poll && s->enabled ? tap_writable : NULL, + s); } static void tap_read_poll(TAPState *s, bool enable) @@ -166,13 +164,6 @@ static ssize_t tap_receive(NetClientState *nc, const uint8_t *buf, size_t size) return tap_write_packet(s, iov, 1); } -static int tap_can_send(void *opaque) -{ - TAPState *s = opaque; - - return qemu_can_send_packet(&s->nc); -} - #ifndef __sun__ ssize_t tap_read_packet(int tapfd, uint8_t *buf, int maxlen) { @@ -192,7 +183,7 @@ static void tap_send(void *opaque) int size; int packets = 0; - while (qemu_can_send_packet(&s->nc)) { + while (true) { uint8_t *buf = s->buf; size = tap_read_packet(s->fd, s->buf, sizeof(s->buf)); diff --git a/qapi-schema.json b/qapi-schema.json index 6e17a5c36c..bcc604b813 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -3788,3 +3788,6 @@ # Since: 2.1 ## { 'command': 'rtc-reset-reinjection' } + +# Rocker ethernet network switch +{ 'include': 'qapi/rocker.json' } diff --git a/qapi/rocker.json b/qapi/rocker.json new file mode 100644 index 0000000000..2fe7fdfa66 --- /dev/null +++ b/qapi/rocker.json @@ -0,0 +1,286 @@ +## +# @Rocker: +# +# Rocker switch information. +# +# @name: switch name +# +# @id: switch ID +# +# @ports: number of front-panel ports +# +# Since: 2.4 +## +{ 'struct': 'RockerSwitch', + 'data': { 'name': 'str', 'id': 'uint64', 'ports': 'uint32' } } + +## +# @query-rocker: +# +# Return rocker switch information. +# +# Returns: @Rocker information +# +# Since: 2.4 +## +{ 'command': 'query-rocker', + 'data': { 'name': 'str' }, + 'returns': 'RockerSwitch' } + +## +# @RockerPortDuplex: +# +# An eumeration of port duplex states. +# +# @half: half duplex +# +# @full: full duplex +# +# Since: 2.4 +## +{ 'enum': 'RockerPortDuplex', 'data': [ 'half', 'full' ] } + +## +# @RockerPortAutoneg: +# +# An eumeration of port autoneg states. +# +# @off: autoneg is off +# +# @on: autoneg is on +# +# Since: 2.4 +## +{ 'enum': 'RockerPortAutoneg', 'data': [ 'off', 'on' ] } + +## +# @RockerPort: +# +# Rocker switch port information. +# +# @name: port name +# +# @enabled: port is enabled for I/O +# +# @link-up: physical link is UP on port +# +# @speed: port link speed in Mbps +# +# @duplex: port link duplex +# +# @autoneg: port link autoneg +# +# Since: 2.4 +## +{ 'struct': 'RockerPort', + 'data': { 'name': 'str', 'enabled': 'bool', 'link-up': 'bool', + 'speed': 'uint32', 'duplex': 'RockerPortDuplex', + 'autoneg': 'RockerPortAutoneg' } } + +## +# @query-rocker-ports: +# +# Return rocker switch information. +# +# Returns: @Rocker information +# +# Since: 2.4 +## +{ 'command': 'query-rocker-ports', + 'data': { 'name': 'str' }, + 'returns': ['RockerPort'] } + +## +# @RockerOfDpaFlowKey: +# +# Rocker switch OF-DPA flow key +# +# @priority: key priority, 0 being lowest priority +# +# @tbl-id: flow table ID +# +# @in-pport: #optional physical input port +# +# @tunnel-id: #optional tunnel ID +# +# @vlan-id: #optional VLAN ID +# +# @eth-type: #optional Ethernet header type +# +# @eth-src: #optional Ethernet header source MAC address +# +# @eth-dst: #optional Ethernet header destination MAC address +# +# @ip-proto: #optional IP Header protocol field +# +# @ip-tos: #optional IP header TOS field +# +# @ip-dst: #optional IP header destination address +# +# Note: fields are marked #optional to indicate that they may or may not +# appear in the flow key depending if they're relevant to the flow key. +# +# Since: 2.4 +## +{ 'struct': 'RockerOfDpaFlowKey', + 'data' : { 'priority': 'uint32', 'tbl-id': 'uint32', '*in-pport': 'uint32', + '*tunnel-id': 'uint32', '*vlan-id': 'uint16', + '*eth-type': 'uint16', '*eth-src': 'str', '*eth-dst': 'str', + '*ip-proto': 'uint8', '*ip-tos': 'uint8', '*ip-dst': 'str' } } + +## +# @RockerOfDpaFlowMask: +# +# Rocker switch OF-DPA flow mask +# +# @in-pport: #optional physical input port +# +# @tunnel-id: #optional tunnel ID +# +# @vlan-id: #optional VLAN ID +# +# @eth-src: #optional Ethernet header source MAC address +# +# @eth-dst: #optional Ethernet header destination MAC address +# +# @ip-proto: #optional IP Header protocol field +# +# @ip-tos: #optional IP header TOS field +# +# Note: fields are marked #optional to indicate that they may or may not +# appear in the flow mask depending if they're relevant to the flow mask. +# +# Since: 2.4 +## +{ 'struct': 'RockerOfDpaFlowMask', + 'data' : { '*in-pport': 'uint32', '*tunnel-id': 'uint32', + '*vlan-id': 'uint16', '*eth-src': 'str', '*eth-dst': 'str', + '*ip-proto': 'uint8', '*ip-tos': 'uint8' } } + +## +# @RockerOfDpaFlowAction: +# +# Rocker switch OF-DPA flow action +# +# @goto-tbl: #optional next table ID +# +# @group-id: #optional group ID +# +# @tunnel-lport: #optional tunnel logical port ID +# +# @vlan-id: #optional VLAN ID +# +# @new-vlan-id: #optional new VLAN ID +# +# @out-pport: #optional physical output port +# +# Note: fields are marked #optional to indicate that they may or may not +# appear in the flow action depending if they're relevant to the flow action. +# +# Since: 2.4 +## +{ 'struct': 'RockerOfDpaFlowAction', + 'data' : { '*goto-tbl': 'uint32', '*group-id': 'uint32', + '*tunnel-lport': 'uint32', '*vlan-id': 'uint16', + '*new-vlan-id': 'uint16', '*out-pport': 'uint32' } } + +## +# @RockerOfDpaFlow: +# +# Rocker switch OF-DPA flow +# +# @cookie: flow unique cookie ID +# +# @hits: count of matches (hits) on flow +# +# @key: flow key +# +# @mask: flow mask +# +# @action: flow action +# +# Since: 2.4 +## +{ 'struct': 'RockerOfDpaFlow', + 'data': { 'cookie': 'uint64', 'hits': 'uint64', 'key': 'RockerOfDpaFlowKey', + 'mask': 'RockerOfDpaFlowMask', 'action': 'RockerOfDpaFlowAction' } } + +## +# @query-rocker-of-dpa-flows: +# +# Return rocker OF-DPA flow information. +# +# @name: switch name +# +# @tbl-id: #optional flow table ID. If tbl-id is not specified, returns +# flow information for all tables. +# +# Returns: @Rocker OF-DPA flow information +# +# Since: 2.4 +## +{ 'command': 'query-rocker-of-dpa-flows', + 'data': { 'name': 'str', '*tbl-id': 'uint32' }, + 'returns': ['RockerOfDpaFlow'] } + +## +# @RockerOfDpaGroup: +# +# Rocker switch OF-DPA group +# +# @id: group unique ID +# +# @type: group type +# +# @vlan-id: #optional VLAN ID +# +# @pport: #optional physical port number +# +# @index: #optional group index, unique with group type +# +# @out-pport: #optional output physical port number +# +# @group-id: #optional next group ID +# +# @set-vlan-id: #optional VLAN ID to set +# +# @pop-vlan: #optional pop VLAN headr from packet +# +# @group-ids: #optional list of next group IDs +# +# @set-eth-src: #optional set source MAC address in Ethernet header +# +# @set-eth-dst: #optional set destination MAC address in Ethernet header +# +# @ttl-check: #optional perform TTL check +# +# Note: fields are marked #optional to indicate that they may or may not +# appear in the group depending if they're relevant to the group type. +# +# Since: 2.4 +## +{ 'struct': 'RockerOfDpaGroup', + 'data': { 'id': 'uint32', 'type': 'uint8', '*vlan-id': 'uint16', + '*pport': 'uint32', '*index': 'uint32', '*out-pport': 'uint32', + '*group-id': 'uint32', '*set-vlan-id': 'uint16', + '*pop-vlan': 'uint8', '*group-ids': ['uint32'], + '*set-eth-src': 'str', '*set-eth-dst': 'str', + '*ttl-check': 'uint8' } } + +## +# @query-rocker-of-dpa-groups: +# +# Return rocker OF-DPA group information. +# +# @name: switch name +# +# @type: #optional group type. If type is not specified, returns +# group information for all group types. +# +# Returns: @Rocker OF-DPA group information +# +# Since: 2.4 +## +{ 'command': 'query-rocker-of-dpa-groups', + 'data': { 'name': 'str', '*type': 'uint8' }, + 'returns': ['RockerOfDpaGroup'] } diff --git a/qmp-commands.hx b/qmp-commands.hx index 867a21fab6..c97d0d7667 100644 --- a/qmp-commands.hx +++ b/qmp-commands.hx @@ -4165,3 +4165,106 @@ Example: <- { "return": {} } EQMP + + { + .name = "query-rocker", + .args_type = "name:s", + .mhandler.cmd_new = qmp_marshal_input_query_rocker, + }, + +SQMP +Show rocker switch +------------------ + +Arguments: + +- "name": switch name + +Example: + +-> { "execute": "query-rocker", "arguments": { "name": "sw1" } } +<- { "return": {"name": "sw1", "ports": 2, "id": 1327446905938}} + +EQMP + + { + .name = "query-rocker-ports", + .args_type = "name:s", + .mhandler.cmd_new = qmp_marshal_input_query_rocker_ports, + }, + +SQMP +Show rocker switch ports +------------------------ + +Arguments: + +- "name": switch name + +Example: + +-> { "execute": "query-rocker-ports", "arguments": { "name": "sw1" } } +<- { "return": [ {"duplex": "full", "enabled": true, "name": "sw1.1", + "autoneg": "off", "link-up": true, "speed": 10000}, + {"duplex": "full", "enabled": true, "name": "sw1.2", + "autoneg": "off", "link-up": true, "speed": 10000} + ]} + +EQMP + + { + .name = "query-rocker-of-dpa-flows", + .args_type = "name:s,tbl-id:i?", + .mhandler.cmd_new = qmp_marshal_input_query_rocker_of_dpa_flows, + }, + +SQMP +Show rocker switch OF-DPA flow tables +------------------------------------- + +Arguments: + +- "name": switch name +- "tbl-id": (optional) flow table ID + +Example: + +-> { "execute": "query-rocker-of-dpa-flows", "arguments": { "name": "sw1" } } +<- { "return": [ {"key": {"in-pport": 0, "priority": 1, "tbl-id": 0}, + "hits": 138, + "cookie": 0, + "action": {"goto-tbl": 10}, + "mask": {"in-pport": 4294901760} + }, + {...more...}, + ]} + +EQMP + + { + .name = "query-rocker-of-dpa-groups", + .args_type = "name:s,type:i?", + .mhandler.cmd_new = qmp_marshal_input_query_rocker_of_dpa_groups, + }, + +SQMP +Show rocker OF-DPA group tables +------------------------------- + +Arguments: + +- "name": switch name +- "type": (optional) group type + +Example: + +-> { "execute": "query-rocker-of-dpa-groups", "arguments": { "name": "sw1" } } +<- { "return": [ {"type": 0, "out-pport": 2, "pport": 2, "vlan-id": 3841, + "pop-vlan": 1, "id": 251723778}, + {"type": 0, "out-pport": 0, "pport": 0, "vlan-id": 3841, + "pop-vlan": 1, "id": 251723776}, + {"type": 0, "out-pport": 1, "pport": 1, "vlan-id": 3840, + "pop-vlan": 1, "id": 251658241}, + {"type": 0, "out-pport": 0, "pport": 0, "vlan-id": 3840, + "pop-vlan": 1, "id": 251658240} + ]} diff --git a/stubs/set-fd-handler.c b/stubs/set-fd-handler.c index fc874d33fe..a8481bc3c1 100644 --- a/stubs/set-fd-handler.c +++ b/stubs/set-fd-handler.c @@ -1,8 +1,7 @@ #include "qemu-common.h" #include "qemu/main-loop.h" -int qemu_set_fd_handler2(int fd, - IOCanReadHandler *fd_read_poll, +void qemu_set_fd_handler(int fd, IOHandler *fd_read, IOHandler *fd_write, void *opaque) diff --git a/tests/rocker/bridge b/tests/rocker/bridge index 7a03f9a227..46abc6f4f6 100755 --- a/tests/rocker/bridge +++ b/tests/rocker/bridge @@ -9,8 +9,8 @@ while ! simp ssh tut h2 --cmd "ping -c 1 localhost >/dev/null"; do sleep 1; done # configure a 2-port bridge simp ssh tut sw1 --cmd "sudo /sbin/ip link add name br0 type bridge" -simp ssh tut sw1 --cmd "sudo /sbin/ip link set dev swp1 master br0" -simp ssh tut sw1 --cmd "sudo /sbin/ip link set dev swp2 master br0" +simp ssh tut sw1 --cmd "sudo /sbin/ip link set dev sw1p1 master br0" +simp ssh tut sw1 --cmd "sudo /sbin/ip link set dev sw1p2 master br0" # turn off vlan default_pvid on br0 @@ -18,28 +18,23 @@ simp ssh tut sw1 --cmd "echo 0 | sudo dd of=/sys/class/net/br0/bridge/default_pv # turn off learning and flooding in SW -simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev swp1 learning off" -simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev swp2 learning off" +simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev sw1p1 learning off" +simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev sw1p2 learning off" -simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev swp1 flood off" -simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev swp2 flood off" - -# turn on learning in HW - -simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev swp1 learning on self" -simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev swp2 learning on self" +simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev sw1p1 flood off" +simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev sw1p2 flood off" # bring up bridge and ports simp ssh tut sw1 --cmd "sudo ifconfig br0 up" -simp ssh tut sw1 --cmd "sudo ifconfig swp1 up" -simp ssh tut sw1 --cmd "sudo ifconfig swp2 up" +simp ssh tut sw1 --cmd "sudo ifconfig sw1p1 up" +simp ssh tut sw1 --cmd "sudo ifconfig sw1p2 up" simp ssh tut sw1 --cmd "sudo ifconfig br0 11.0.0.3/24" # config IP on hosts -simp ssh tut h1 --cmd "sudo ifconfig swp1 11.0.0.1/24" -simp ssh tut h2 --cmd "sudo ifconfig swp1 11.0.0.2/24" +simp ssh tut h1 --cmd "sudo ifconfig sw1p1 11.0.0.1/24" +simp ssh tut h2 --cmd "sudo ifconfig sw1p1 11.0.0.2/24" # test... diff --git a/tests/rocker/bridge-stp b/tests/rocker/bridge-stp index 4a111a17d3..008568ad8a 100755 --- a/tests/rocker/bridge-stp +++ b/tests/rocker/bridge-stp @@ -10,8 +10,8 @@ while ! simp ssh tut h2 --cmd "ping -c 1 localhost >/dev/null"; do sleep 1; done simp ssh tut sw1 --cmd "sudo /sbin/ip link add name br0 type bridge" simp ssh tut sw1 --cmd "sudo brctl stp br0 on" -simp ssh tut sw1 --cmd "sudo /sbin/ip link set dev swp1 master br0" -simp ssh tut sw1 --cmd "sudo /sbin/ip link set dev swp2 master br0" +simp ssh tut sw1 --cmd "sudo /sbin/ip link set dev sw1p1 master br0" +simp ssh tut sw1 --cmd "sudo /sbin/ip link set dev sw1p2 master br0" # turn off vlan default_pvid on br0 @@ -19,27 +19,22 @@ simp ssh tut sw1 --cmd "echo 0 | sudo dd of=/sys/class/net/br0/bridge/default_pv # turn off learning and flooding in SW -simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev swp1 learning off" -simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev swp2 learning off" +simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev sw1p1 learning off" +simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev sw1p2 learning off" -simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev swp1 flood off" -simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev swp2 flood off" - -# turn on learning in HW - -simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev swp1 learning on self" -simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev swp2 learning on self" +simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev sw1p1 flood off" +simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev sw1p2 flood off" # config IP on hosts -simp ssh tut h1 --cmd "sudo ifconfig swp1 11.0.0.1/24" -simp ssh tut h2 --cmd "sudo ifconfig swp1 11.0.0.2/24" +simp ssh tut h1 --cmd "sudo ifconfig sw1p1 11.0.0.1/24" +simp ssh tut h2 --cmd "sudo ifconfig sw1p1 11.0.0.2/24" # bring up bridge and ports simp ssh tut sw1 --cmd "sudo ifconfig br0 up" -simp ssh tut sw1 --cmd "sudo ifconfig swp1 up" -simp ssh tut sw1 --cmd "sudo ifconfig swp2 up" +simp ssh tut sw1 --cmd "sudo ifconfig sw1p1 up" +simp ssh tut sw1 --cmd "sudo ifconfig sw1p2 up" # test... diff --git a/tests/rocker/bridge-vlan b/tests/rocker/bridge-vlan index 9fa3431f66..ef9e5f53bb 100755 --- a/tests/rocker/bridge-vlan +++ b/tests/rocker/bridge-vlan @@ -9,8 +9,8 @@ while ! simp ssh tut h2 --cmd "ping -c 1 localhost >/dev/null"; do sleep 1; done # configure a 2-port bridge simp ssh tut sw1 --cmd "sudo /sbin/ip link add name br0 type bridge" -simp ssh tut sw1 --cmd "sudo /sbin/ip link set dev swp1 master br0" -simp ssh tut sw1 --cmd "sudo /sbin/ip link set dev swp2 master br0" +simp ssh tut sw1 --cmd "sudo /sbin/ip link set dev sw1p1 master br0" +simp ssh tut sw1 --cmd "sudo /sbin/ip link set dev sw1p2 master br0" # turn off vlan default_pvid on br0 # turn on vlan filtering on br0 @@ -20,37 +20,32 @@ simp ssh tut sw1 --cmd "echo 1 | sudo dd of=/sys/class/net/br0/bridge/vlan_filte # add both ports to VLAN 57 -simp ssh tut sw1 --cmd "sudo /sbin/bridge vlan add vid 57 dev swp1 master" -simp ssh tut sw1 --cmd "sudo /sbin/bridge vlan add vid 57 dev swp2 master" +simp ssh tut sw1 --cmd "sudo /sbin/bridge vlan add vid 57 dev sw1p1 master self" +simp ssh tut sw1 --cmd "sudo /sbin/bridge vlan add vid 57 dev sw1p2 master self" # turn off learning and flooding in SW -simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev swp1 learning off" -simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev swp2 learning off" +simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev sw1p1 learning off" +simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev sw1p2 learning off" -simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev swp1 flood off" -simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev swp2 flood off" - -# turn on learning in HW - -simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev swp1 learning on self" -simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev swp2 learning on self" +simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev sw1p1 flood off" +simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev sw1p2 flood off" # bring up bridge and ports simp ssh tut sw1 --cmd "sudo ifconfig br0 up" -simp ssh tut sw1 --cmd "sudo ifconfig swp1 up" -simp ssh tut sw1 --cmd "sudo ifconfig swp2 up" +simp ssh tut sw1 --cmd "sudo ifconfig sw1p1 up" +simp ssh tut sw1 --cmd "sudo ifconfig sw1p2 up" # config IP on host VLANs -simp ssh tut h1 --cmd "sudo vconfig add swp1 57 >/dev/null 2>&1" -simp ssh tut h1 --cmd "sudo ifconfig swp1 up" -simp ssh tut h1 --cmd "sudo ifconfig swp1.57 11.0.0.1/24" +simp ssh tut h1 --cmd "sudo vconfig add sw1p1 57 >/dev/null 2>&1" +simp ssh tut h1 --cmd "sudo ifconfig sw1p1 up" +simp ssh tut h1 --cmd "sudo ifconfig sw1p1.57 11.0.0.1/24" -simp ssh tut h2 --cmd "sudo vconfig add swp1 57 >/dev/null 2>&1" -simp ssh tut h2 --cmd "sudo ifconfig swp1 up" -simp ssh tut h2 --cmd "sudo ifconfig swp1.57 11.0.0.2/24" +simp ssh tut h2 --cmd "sudo vconfig add sw1p1 57 >/dev/null 2>&1" +simp ssh tut h2 --cmd "sudo ifconfig sw1p1 up" +simp ssh tut h2 --cmd "sudo ifconfig sw1p1.57 11.0.0.2/24" # test... diff --git a/tests/rocker/bridge-vlan-stp b/tests/rocker/bridge-vlan-stp index 77ab67efe2..c660312bc6 100755 --- a/tests/rocker/bridge-vlan-stp +++ b/tests/rocker/bridge-vlan-stp @@ -10,8 +10,8 @@ while ! simp ssh tut h2 --cmd "ping -c 1 localhost >/dev/null"; do sleep 1; done simp ssh tut sw1 --cmd "sudo /sbin/ip link add name br0 type bridge" simp ssh tut sw1 --cmd "sudo brctl stp br0 on" -simp ssh tut sw1 --cmd "sudo /sbin/ip link set dev swp1 master br0" -simp ssh tut sw1 --cmd "sudo /sbin/ip link set dev swp2 master br0" +simp ssh tut sw1 --cmd "sudo /sbin/ip link set dev sw1p1 master br0" +simp ssh tut sw1 --cmd "sudo /sbin/ip link set dev sw1p2 master br0" # turn off vlan default_pvid on br0 # turn on vlan filtering on br0 @@ -21,37 +21,32 @@ simp ssh tut sw1 --cmd "echo 1 | sudo dd of=/sys/class/net/br0/bridge/vlan_filte # add both ports to VLAN 57 -simp ssh tut sw1 --cmd "sudo /sbin/bridge vlan add vid 57 dev swp1 master" -simp ssh tut sw1 --cmd "sudo /sbin/bridge vlan add vid 57 dev swp2 master" +simp ssh tut sw1 --cmd "sudo /sbin/bridge vlan add vid 57 dev sw1p1 master self" +simp ssh tut sw1 --cmd "sudo /sbin/bridge vlan add vid 57 dev sw1p2 master self" # turn off learning and flooding in SW -simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev swp1 learning off" -simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev swp2 learning off" +simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev sw1p1 learning off" +simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev sw1p2 learning off" -simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev swp1 flood off" -simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev swp2 flood off" - -# turn on learning in HW - -simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev swp1 learning on self" -simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev swp2 learning on self" +simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev sw1p1 flood off" +simp ssh tut sw1 --cmd "sudo /sbin/bridge link set dev sw1p2 flood off" # config IP on host VLANs -simp ssh tut h1 --cmd "sudo vconfig add swp1 57 >/dev/null 2>&1" -simp ssh tut h1 --cmd "sudo ifconfig swp1 up" -simp ssh tut h1 --cmd "sudo ifconfig swp1.57 11.0.0.1/24" +simp ssh tut h1 --cmd "sudo vconfig add sw1p1 57 >/dev/null 2>&1" +simp ssh tut h1 --cmd "sudo ifconfig sw1p1 up" +simp ssh tut h1 --cmd "sudo ifconfig sw1p1.57 11.0.0.1/24" -simp ssh tut h2 --cmd "sudo vconfig add swp1 57 >/dev/null 2>&1" -simp ssh tut h2 --cmd "sudo ifconfig swp1 up" -simp ssh tut h2 --cmd "sudo ifconfig swp1.57 11.0.0.2/24" +simp ssh tut h2 --cmd "sudo vconfig add sw1p1 57 >/dev/null 2>&1" +simp ssh tut h2 --cmd "sudo ifconfig sw1p1 up" +simp ssh tut h2 --cmd "sudo ifconfig sw1p1.57 11.0.0.2/24" # bring up bridge and ports simp ssh tut sw1 --cmd "sudo ifconfig br0 up" -simp ssh tut sw1 --cmd "sudo ifconfig swp1 up" -simp ssh tut sw1 --cmd "sudo ifconfig swp2 up" +simp ssh tut sw1 --cmd "sudo ifconfig sw1p1 up" +simp ssh tut sw1 --cmd "sudo ifconfig sw1p2 up" # test... diff --git a/tests/rocker/port b/tests/rocker/port index 3437f7d7fe..5f2c248046 100755 --- a/tests/rocker/port +++ b/tests/rocker/port @@ -7,13 +7,13 @@ while ! simp ssh tut h2 --cmd "ping -c 1 localhost >/dev/null"; do sleep 1; done # bring up DUT ports -simp ssh tut sw1 --cmd "sudo ifconfig swp1 11.0.0.1/24" -simp ssh tut sw1 --cmd "sudo ifconfig swp2 12.0.0.1/24" +simp ssh tut sw1 --cmd "sudo ifconfig sw1p1 11.0.0.1/24" +simp ssh tut sw1 --cmd "sudo ifconfig sw1p2 12.0.0.1/24" # config IP on hosts -simp ssh tut h1 --cmd "sudo ifconfig swp1 11.0.0.2/24" -simp ssh tut h2 --cmd "sudo ifconfig swp1 12.0.0.2/24" +simp ssh tut h1 --cmd "sudo ifconfig sw1p1 11.0.0.2/24" +simp ssh tut h2 --cmd "sudo ifconfig sw1p1 12.0.0.2/24" # test... diff --git a/ui/vnc-auth-sasl.c b/ui/vnc-auth-sasl.c index 2ddd2591f9..62a5fc4bf1 100644 --- a/ui/vnc-auth-sasl.c +++ b/ui/vnc-auth-sasl.c @@ -86,7 +86,7 @@ long vnc_client_write_sasl(VncState *vs) * SASL encoded output */ if (vs->output.offset == 0) { - qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs); + qemu_set_fd_handler(vs->csock, vnc_client_read, NULL, vs); } return ret; diff --git a/ui/vnc-auth-vencrypt.c b/ui/vnc-auth-vencrypt.c index 03ea48a69c..8fc965b4ad 100644 --- a/ui/vnc-auth-vencrypt.c +++ b/ui/vnc-auth-vencrypt.c @@ -94,7 +94,7 @@ static int vnc_start_vencrypt_handshake(VncState *vs) } VNC_DEBUG("Handshake done, switching to TLS data mode\n"); - qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs); + qemu_set_fd_handler(vs->csock, vnc_client_read, vnc_client_write, vs); start_auth_vencrypt_subauth(vs); diff --git a/ui/vnc-ws.c b/ui/vnc-ws.c index 38a1b8b646..8c18268054 100644 --- a/ui/vnc-ws.c +++ b/ui/vnc-ws.c @@ -56,7 +56,7 @@ static int vncws_start_tls_handshake(VncState *vs) } VNC_DEBUG("Handshake done, switching to TLS data mode\n"); - qemu_set_fd_handler2(vs->csock, NULL, vncws_handshake_read, NULL, vs); + qemu_set_fd_handler(vs->csock, vncws_handshake_read, NULL, vs); return 0; } @@ -98,7 +98,7 @@ void vncws_handshake_read(void *opaque) handshake_end = (uint8_t *)g_strstr_len((char *)vs->ws_input.buffer, vs->ws_input.offset, WS_HANDSHAKE_END); if (handshake_end) { - qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs); + qemu_set_fd_handler(vs->csock, vnc_client_read, NULL, vs); vncws_process_handshake(vs, vs->ws_input.buffer, vs->ws_input.offset); buffer_advance(&vs->ws_input, handshake_end - vs->ws_input.buffer + strlen(WS_HANDSHAKE_END)); @@ -176,7 +176,7 @@ long vnc_client_write_ws(VncState *vs) buffer_advance(&vs->ws_output, ret); if (vs->ws_output.offset == 0) { - qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs); + qemu_set_fd_handler(vs->csock, vnc_client_read, NULL, vs); } return ret; diff --git a/ui/vnc.c b/ui/vnc.c index 0c6b5e3553..69b605c709 100644 --- a/ui/vnc.c +++ b/ui/vnc.c @@ -1213,7 +1213,7 @@ static void vnc_disconnect_start(VncState *vs) if (vs->csock == -1) return; vnc_set_share_mode(vs, VNC_SHARE_MODE_DISCONNECTED); - qemu_set_fd_handler2(vs->csock, NULL, NULL, NULL, NULL); + qemu_set_fd_handler(vs->csock, NULL, NULL, NULL); closesocket(vs->csock); vs->csock = -1; } @@ -1387,7 +1387,7 @@ static long vnc_client_write_plain(VncState *vs) buffer_advance(&vs->output, ret); if (vs->output.offset == 0) { - qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs); + qemu_set_fd_handler(vs->csock, vnc_client_read, NULL, vs); } return ret; @@ -1434,7 +1434,7 @@ void vnc_client_write(void *opaque) ) { vnc_client_write_locked(opaque); } else if (vs->csock != -1) { - qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs); + qemu_set_fd_handler(vs->csock, vnc_client_read, NULL, vs); } vnc_unlock_output(vs); } @@ -1581,7 +1581,7 @@ void vnc_write(VncState *vs, const void *data, size_t len) buffer_reserve(&vs->output, len); if (vs->csock != -1 && buffer_empty(&vs->output)) { - qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs); + qemu_set_fd_handler(vs->csock, vnc_client_read, vnc_client_write, vs); } buffer_append(&vs->output, data, len); @@ -3022,18 +3022,16 @@ static void vnc_connect(VncDisplay *vd, int csock, vs->websocket = 1; #ifdef CONFIG_VNC_TLS if (vd->ws_tls) { - qemu_set_fd_handler2(vs->csock, NULL, vncws_tls_handshake_io, - NULL, vs); + qemu_set_fd_handler(vs->csock, vncws_tls_handshake_io, NULL, vs); } else #endif /* CONFIG_VNC_TLS */ { - qemu_set_fd_handler2(vs->csock, NULL, vncws_handshake_read, - NULL, vs); + qemu_set_fd_handler(vs->csock, vncws_handshake_read, NULL, vs); } } else #endif /* CONFIG_VNC_WS */ { - qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, NULL, vs); + qemu_set_fd_handler(vs->csock, vnc_client_read, NULL, vs); } vnc_client_cache_addr(vs); @@ -3182,14 +3180,14 @@ static void vnc_display_close(VncDisplay *vs) vs->enabled = false; vs->is_unix = false; if (vs->lsock != -1) { - qemu_set_fd_handler2(vs->lsock, NULL, NULL, NULL, NULL); + qemu_set_fd_handler(vs->lsock, NULL, NULL, NULL); close(vs->lsock); vs->lsock = -1; } #ifdef CONFIG_VNC_WS vs->ws_enabled = false; if (vs->lwebsock != -1) { - qemu_set_fd_handler2(vs->lwebsock, NULL, NULL, NULL, NULL); + qemu_set_fd_handler(vs->lwebsock, NULL, NULL, NULL); close(vs->lwebsock); vs->lwebsock = -1; } @@ -3707,12 +3705,11 @@ void vnc_display_open(const char *id, Error **errp) #endif /* CONFIG_VNC_WS */ } vs->enabled = true; - qemu_set_fd_handler2(vs->lsock, NULL, - vnc_listen_regular_read, NULL, vs); + qemu_set_fd_handler(vs->lsock, vnc_listen_regular_read, NULL, vs); #ifdef CONFIG_VNC_WS if (vs->ws_enabled) { - qemu_set_fd_handler2(vs->lwebsock, NULL, - vnc_listen_websocket_read, NULL, vs); + qemu_set_fd_handler(vs->lwebsock, vnc_listen_websocket_read, + NULL, vs); } #endif /* CONFIG_VNC_WS */ } diff --git a/util/event_notifier-posix.c b/util/event_notifier-posix.c index 8442c6e63c..ed4ca2b01e 100644 --- a/util/event_notifier-posix.c +++ b/util/event_notifier-posix.c @@ -85,7 +85,8 @@ int event_notifier_get_fd(EventNotifier *e) int event_notifier_set_handler(EventNotifier *e, EventNotifierHandler *handler) { - return qemu_set_fd_handler(e->rfd, (IOHandler *)handler, NULL, e); + qemu_set_fd_handler(e->rfd, (IOHandler *)handler, NULL, e); + return 0; } int event_notifier_set(EventNotifier *e) diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c index f9ad34e40c..4026314435 100644 --- a/util/qemu-sockets.c +++ b/util/qemu-sockets.c @@ -244,7 +244,7 @@ static void wait_for_connect(void *opaque) bool in_progress; Error *err = NULL; - qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL); + qemu_set_fd_handler(s->fd, NULL, NULL, NULL); do { rc = qemu_getsockopt(s->fd, SOL_SOCKET, SO_ERROR, &val, &valsize); @@ -316,8 +316,7 @@ static int inet_connect_addr(struct addrinfo *addr, bool *in_progress, if (connect_state != NULL && QEMU_SOCKET_RC_INPROGRESS(rc)) { connect_state->fd = sock; - qemu_set_fd_handler2(sock, NULL, NULL, wait_for_connect, - connect_state); + qemu_set_fd_handler(sock, NULL, wait_for_connect, connect_state); *in_progress = true; } else if (rc < 0) { error_setg_errno(errp, errno, "Failed to connect socket"); @@ -796,8 +795,7 @@ int unix_connect_opts(QemuOpts *opts, Error **errp, if (connect_state != NULL && QEMU_SOCKET_RC_INPROGRESS(rc)) { connect_state->fd = sock; - qemu_set_fd_handler2(sock, NULL, NULL, wait_for_connect, - connect_state); + qemu_set_fd_handler(sock, NULL, wait_for_connect, connect_state); return sock; } else if (rc >= 0) { /* non blocking socket immediate success, call callback */