aboutsummaryrefslogtreecommitdiffstats
path: root/router
diff options
context:
space:
mode:
authorJeff Shaw <jeffrey.b.shaw@intel.com>2016-08-04 16:51:37 -0400
committerJeff Shaw <jeffrey.b.shaw@intel.com>2016-08-12 16:58:05 -0400
commitc4da7ab60ca11bc8d2cf683a68fa56483da01243 (patch)
tree9469eb0ddb37e9e7de7df0fe6bc819054cd8856b /router
parentadff8bfb431798fc1d4e4571d53074dc3438d14f (diff)
[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 <jeffrey.b.shaw@intel.com>
Diffstat (limited to 'router')
-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");