This breaks up creating compat ports so we can reuse some of the code to create ports with rtnetlink.
Co-authored-by: Thadeu Lima de Souza Cascardo <casca...@redhat.com> Signed-off-by: Thadeu Lima de Souza Cascardo <casca...@redhat.com> Signed-off-by: Eric Garver <e...@erig.me> Acked-by: Joe Stringer <j...@ovn.org> --- lib/dpif-netlink.c | 138 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 79 insertions(+), 59 deletions(-) diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c index 319808f909f9..4c4106c9b33f 100644 --- a/lib/dpif-netlink.c +++ b/lib/dpif-netlink.c @@ -785,10 +785,8 @@ get_vport_type(const struct dpif_netlink_vport *vport) } static enum ovs_vport_type -netdev_to_ovs_vport_type(const struct netdev *netdev) +netdev_to_ovs_vport_type(const char *type) { - const char *type = netdev_get_type(netdev); - if (!strcmp(type, "tap") || !strcmp(type, "system")) { return OVS_VPORT_TYPE_NETDEV; } else if (!strcmp(type, "internal")) { @@ -809,19 +807,14 @@ netdev_to_ovs_vport_type(const struct netdev *netdev) } static int -dpif_netlink_port_add__(struct dpif_netlink *dpif, struct netdev *netdev, +dpif_netlink_port_add__(struct dpif_netlink *dpif, const char *name, + enum ovs_vport_type type, + struct ofpbuf *options, odp_port_t *port_nop) OVS_REQ_WRLOCK(dpif->upcall_lock) { - const struct netdev_tunnel_config *tnl_cfg; - char namebuf[NETDEV_VPORT_NAME_BUFSIZE]; - const char *name = netdev_vport_get_dpif_port(netdev, - namebuf, sizeof namebuf); - const char *type = netdev_get_type(netdev); struct dpif_netlink_vport request, reply; struct ofpbuf *buf; - uint64_t options_stub[64 / 8]; - struct ofpbuf options; struct nl_sock **socksp = NULL; uint32_t *upcall_pids; int error = 0; @@ -836,17 +829,81 @@ dpif_netlink_port_add__(struct dpif_netlink *dpif, struct netdev *netdev, dpif_netlink_vport_init(&request); request.cmd = OVS_VPORT_CMD_NEW; request.dp_ifindex = dpif->dp_ifindex; - request.type = netdev_to_ovs_vport_type(netdev); - if (request.type == OVS_VPORT_TYPE_UNSPEC) { + request.type = type; + request.name = name; + + request.port_no = *port_nop; + upcall_pids = vport_socksp_to_pids(socksp, dpif->n_handlers); + request.n_upcall_pids = socksp ? dpif->n_handlers : 1; + request.upcall_pids = upcall_pids; + + if (options) { + request.options = options->data; + request.options_len = options->size; + } + + error = dpif_netlink_vport_transact(&request, &reply, &buf); + if (!error) { + *port_nop = reply.port_no; + } else { + if (error == EBUSY && *port_nop != ODPP_NONE) { + VLOG_INFO("%s: requested port %"PRIu32" is in use", + dpif_name(&dpif->dpif), *port_nop); + } + + vport_del_socksp(dpif, socksp); + goto exit; + } + + if (socksp) { + error = vport_add_channels(dpif, *port_nop, socksp); + if (error) { + VLOG_INFO("%s: could not add channel for port %s", + dpif_name(&dpif->dpif), name); + + /* Delete the port. */ + dpif_netlink_vport_init(&request); + request.cmd = OVS_VPORT_CMD_DEL; + request.dp_ifindex = dpif->dp_ifindex; + request.port_no = *port_nop; + dpif_netlink_vport_transact(&request, NULL, NULL); + vport_del_socksp(dpif, socksp); + goto exit; + } + } + free(socksp); + +exit: + ofpbuf_delete(buf); + free(upcall_pids); + + return error; +} + +static int +dpif_netlink_port_add_compat(struct dpif_netlink *dpif, struct netdev *netdev, + odp_port_t *port_nop) + OVS_REQ_WRLOCK(dpif->upcall_lock) +{ + const struct netdev_tunnel_config *tnl_cfg; + char namebuf[NETDEV_VPORT_NAME_BUFSIZE]; + const char *type = netdev_get_type(netdev); + uint64_t options_stub[64 / 8]; + enum ovs_vport_type ovs_type; + struct ofpbuf options; + const char *name; + + name = netdev_vport_get_dpif_port(netdev, namebuf, sizeof namebuf); + + ovs_type = netdev_to_ovs_vport_type(netdev_get_type(netdev)); + if (ovs_type == OVS_VPORT_TYPE_UNSPEC) { VLOG_WARN_RL(&error_rl, "%s: cannot create port `%s' because it has " "unsupported type `%s'", dpif_name(&dpif->dpif), name, type); - vport_del_socksp(dpif, socksp); return EINVAL; } - request.name = name; - if (request.type == OVS_VPORT_TYPE_NETDEV) { + if (ovs_type == OVS_VPORT_TYPE_NETDEV) { #ifdef _WIN32 /* XXX : Map appropiate Windows handle */ #else @@ -855,10 +912,9 @@ dpif_netlink_port_add__(struct dpif_netlink *dpif, struct netdev *netdev, } #ifdef _WIN32 - if (request.type == OVS_VPORT_TYPE_INTERNAL) { + if (ovs_type == OVS_VPORT_TYPE_INTERNAL) { if (!create_wmi_port(name)){ VLOG_ERR("Could not create wmi internal port with name:%s", name); - vport_del_socksp(dpif, socksp); return EINVAL; }; } @@ -883,52 +939,16 @@ dpif_netlink_port_add__(struct dpif_netlink *dpif, struct netdev *netdev, } nl_msg_end_nested(&options, ext_ofs); } - request.options = options.data; - request.options_len = options.size; - } - - request.port_no = *port_nop; - upcall_pids = vport_socksp_to_pids(socksp, dpif->n_handlers); - request.n_upcall_pids = socksp ? dpif->n_handlers : 1; - request.upcall_pids = upcall_pids; - - error = dpif_netlink_vport_transact(&request, &reply, &buf); - if (!error) { - *port_nop = reply.port_no; + return dpif_netlink_port_add__(dpif, name, ovs_type, &options, + port_nop); } else { - if (error == EBUSY && *port_nop != ODPP_NONE) { - VLOG_INFO("%s: requested port %"PRIu32" is in use", - dpif_name(&dpif->dpif), *port_nop); - } - - vport_del_socksp(dpif, socksp); - goto exit; + return dpif_netlink_port_add__(dpif, name, ovs_type, NULL, port_nop); } - if (socksp) { - error = vport_add_channels(dpif, *port_nop, socksp); - if (error) { - VLOG_INFO("%s: could not add channel for port %s", - dpif_name(&dpif->dpif), name); +} - /* Delete the port. */ - dpif_netlink_vport_init(&request); - request.cmd = OVS_VPORT_CMD_DEL; - request.dp_ifindex = dpif->dp_ifindex; - request.port_no = *port_nop; - dpif_netlink_vport_transact(&request, NULL, NULL); - vport_del_socksp(dpif, socksp); - goto exit; - } - } - free(socksp); -exit: - ofpbuf_delete(buf); - free(upcall_pids); - return error; -} static int dpif_netlink_port_add(struct dpif *dpif_, struct netdev *netdev, @@ -938,7 +958,7 @@ dpif_netlink_port_add(struct dpif *dpif_, struct netdev *netdev, int error; fat_rwlock_wrlock(&dpif->upcall_lock); - error = dpif_netlink_port_add__(dpif, netdev, port_nop); + error = dpif_netlink_port_add_compat(dpif, netdev, port_nop); fat_rwlock_unlock(&dpif->upcall_lock); return error; -- 2.12.0 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev