From c4da7ab60ca11bc8d2cf683a68fa56483da01243 Mon Sep 17 00:00:00 2001 From: Jeff Shaw Date: Thu, 4 Aug 2016 16:51:37 -0400 Subject: [router] Handle initial tap link state. When an interface is tapped, the tap inherits the link state of the underlying device. Also, the hw vector was being resized in the time between getting the interface and when the hw_address was referenced, leading to a segmentation fault. Resolve the issue by saving the mac address contents on the stack before passing to other functions. Change-Id: I4b5b31e438159a83ddfea808882503775b1fcd1a Signed-off-by: Jeff Shaw --- router/router/router.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) (limited to 'router') 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"); -- cgit 1.2.3-korg