From a50a14c5577e82866b05f325e359c86ba7145730 Mon Sep 17 00:00:00 2001 From: Mohsin Kazmi Date: Wed, 25 Apr 2018 15:58:05 +0200 Subject: itf: Fix admin up down for AF_PACKET and vhost-user Change-Id: I84327197d59c72d0d046dd2cb4071bf74af6fc28 Signed-off-by: Mohsin Kazmi --- src/vnet/devices/af_packet/af_packet.c | 45 +++++++++++++++++++++++++++++++--- src/vnet/devices/virtio/vhost-user.c | 10 +++----- src/vnet/interface.c | 7 ++++-- 3 files changed, 50 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/vnet/devices/af_packet/af_packet.c b/src/vnet/devices/af_packet/af_packet.c index 46bb42a4f47..500460126a8 100644 --- a/src/vnet/devices/af_packet/af_packet.c +++ b/src/vnet/devices/af_packet/af_packet.c @@ -19,6 +19,8 @@ #include #include +#include +#include #include #include #include @@ -212,9 +214,10 @@ af_packet_create_if (vlib_main_t * vm, u8 * host_if_name, u8 * hw_addr_set, u32 * sw_if_index) { af_packet_main_t *apm = &af_packet_main; - int ret, fd = -1; + int ret, fd = -1, fd2 = -1; struct tpacket_req *rx_req = 0; struct tpacket_req *tx_req = 0; + struct ifreq ifr; u8 *ring = 0; af_packet_if_t *apif = 0; u8 hw_addr[6]; @@ -248,14 +251,46 @@ af_packet_create_if (vlib_main_t * vm, u8 * host_if_name, u8 * hw_addr_set, tx_req->tp_block_nr = AF_PACKET_TX_BLOCK_NR; tx_req->tp_frame_nr = AF_PACKET_TX_FRAME_NR; - host_if_index = if_nametoindex ((const char *) host_if_name); + /* + * make sure host side of interface is 'UP' before binding AF_PACKET + * socket on it. + */ + if ((fd2 = socket (AF_UNIX, SOCK_DGRAM, 0)) < 0) + { + DBG_SOCK ("Failed to create socket"); + ret = VNET_API_ERROR_SYSCALL_ERROR_1; + goto error; + } - if (!host_if_index) + clib_memcpy (ifr.ifr_name, (const char *) host_if_name, + vec_len (host_if_name)); + if ((ret = ioctl (fd2, SIOCGIFINDEX, &ifr)) < 0) { - DBG_SOCK ("Wrong host interface name"); + clib_unix_warning ("af_packet_create error: %d", ret); + close (fd2); return VNET_API_ERROR_INVALID_INTERFACE; } + host_if_index = ifr.ifr_ifindex; + if ((ret = ioctl (fd2, SIOCGIFFLAGS, &ifr)) < 0) + { + clib_unix_warning ("af_packet_create error: %d", ret); + goto error; + } + + if (!(ifr.ifr_flags & IFF_UP)) + { + ifr.ifr_flags |= IFF_UP; + if ((ret = ioctl (fd2, SIOCSIFFLAGS, &ifr)) < 0) + { + clib_unix_warning ("af_packet_create error: %d", ret); + goto error; + } + } + + if (fd2 > -1) + close (fd2); + ret = create_packet_v2_sock (host_if_index, rx_req, tx_req, &fd, &ring); if (ret != 0) @@ -347,6 +382,8 @@ af_packet_create_if (vlib_main_t * vm, u8 * host_if_name, u8 * hw_addr_set, return 0; error: + if (fd2 > -1) + close (fd2); vec_free (host_if_name_dup); vec_free (rx_req); vec_free (tx_req); diff --git a/src/vnet/devices/virtio/vhost-user.c b/src/vnet/devices/virtio/vhost-user.c index 7e10a60f5fb..4e745d662fb 100644 --- a/src/vnet/devices/virtio/vhost-user.c +++ b/src/vnet/devices/virtio/vhost-user.c @@ -2548,16 +2548,14 @@ vhost_user_interface_admin_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags) { vnet_hw_interface_t *hif = vnet_get_hw_interface (vnm, hw_if_index); - uword is_up = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) != 0; vhost_user_main_t *vum = &vhost_user_main; vhost_user_intf_t *vui = pool_elt_at_index (vum->vhost_user_interfaces, hif->dev_instance); + u32 hw_flags = 0; + vui->admin_up = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) != 0; + hw_flags = vui->admin_up ? VNET_HW_INTERFACE_FLAG_LINK_UP : 0; - vui->admin_up = is_up; - - if (is_up && vui->is_up) - vnet_hw_interface_set_flags (vnm, vui->hw_if_index, - VNET_HW_INTERFACE_FLAG_LINK_UP); + vnet_hw_interface_set_flags (vnm, vui->hw_if_index, hw_flags); return /* no error */ 0; } diff --git a/src/vnet/interface.c b/src/vnet/interface.c index 36793f1177e..d85d864839e 100644 --- a/src/vnet/interface.c +++ b/src/vnet/interface.c @@ -485,10 +485,13 @@ vnet_sw_interface_set_flags_helper (vnet_main_t * vnm, u32 sw_if_index, error = call_elf_section_interface_callbacks (vnm, sw_if_index, flags, vnm->sw_interface_admin_up_down_functions); - si->flags = old_flags; if (error) - goto done; + { + /* restore flags on error */ + si->flags = old_flags; + goto done; + } if (si->type == VNET_SW_INTERFACE_TYPE_HARDWARE) { -- cgit 1.2.3-korg