aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--router/router/router.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/router/router/router.c b/router/router/router.c
index 5df86f0..ee23a3d 100644
--- a/router/router/router.c
+++ b/router/router/router.c
@@ -331,21 +331,56 @@ set_tap_hwaddr(vlib_main_t *m, char *name, u8 *hwaddr)
return rc;
}
+static int
+set_tap_link_state(vlib_main_t *m, char *name, u16 flags)
+{
+ int fd, rc;
+ struct ifreq ifr;
+
+ fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+ if (fd < 0)
+ return -1;
+
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, (char *)name, sizeof(ifr.ifr_name) - 1);
+
+ rc = ioctl(fd, SIOCGIFFLAGS, &ifr);
+ if (rc < 0)
+ goto out;
+
+ if (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP)
+ ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);
+ else
+ ifr.ifr_flags &= ~(IFF_UP | IFF_RUNNING);
+
+ rc = ioctl(fd, SIOCSIFFLAGS, &ifr) < 0 ? -1 : 0;
+out:
+ close(fd);
+ return rc;
+}
+
static clib_error_t *
do_tap_connect(vlib_main_t *m, char *name, u32 iface, u32 *tap)
{
vnet_hw_interface_t *hw = vnet_get_hw_interface(rm.vnet_main, iface);
+ vnet_sw_interface_t *sw = vnet_get_sw_interface(rm.vnet_main, iface);
+ u64 hw_address = 0;
*tap = ~0;
if (!hw)
return clib_error_return(0, "invalid interface");
+ else if (hw->hw_address)
+ memcpy(&hw_address, hw->hw_address, 6);
- if (vnet_tap_connect(m, (u8 *)name, hw->hw_address, tap))
+ if (vnet_tap_connect(m, (u8 *)name, (u8 *)&hw_address, tap))
return clib_error_return(0, "failed to connect tap");
- if (set_tap_hwaddr(m, name, hw->hw_address))
+ if (set_tap_hwaddr(m, name, (u8 *)&hw_address))
return clib_error_return(0, "failed to set tap hw address");
+ if (set_tap_link_state(m, name, sw->flags))
+ return clib_error_return(0, "failed to set tap link state");
+
if (set_int_l2_mode(m, rm.vnet_main, MODE_L2_XC, *tap, 0, 0, 0, iface))
return clib_error_return(0, "failed to xconnect to interface");