summaryrefslogtreecommitdiffstats
path: root/src/vnet/devices/af_packet/af_packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/devices/af_packet/af_packet.c')
-rw-r--r--src/vnet/devices/af_packet/af_packet.c45
1 files changed, 41 insertions, 4 deletions
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 <linux/if_ether.h>
#include <linux/if_packet.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -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);