mirror of
https://github.com/openvswitch/ovs
synced 2025-08-30 13:58:14 +00:00
bridge: Prohibit "default" and "all" bridge name.
Under Linux, when users create bridge named "default" or "all", although ovs-vsctl fails but vswitchd in the background will keep retrying it, causing the systemd-udev to reach 100% cpu utilization. The patch prevents any attempt to create or open a netdev named "default" or "all" because these two names are reserved on Linux due to /proc/sys/net/ipv4/conf/ always contains directories by these names. The reason for high CPU utilization is due to frequent calls into kernel's register_netdevice function, which will invoke several kernel elements who has registered on the netdevice notifier chain. And due to creation failed, OVS wakes up and re-recreate the device, which ends up as a high CPU loop. VMWare-BZ: #1842388 Signed-off-by: William Tu <u9012063@gmail.com> Signed-off-by: Ben Pfaff <blp@ovn.org> Acked-by: Greg Rose <gvrose8192@gmail.com>
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Nicira, Inc.
|
* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017 Nicira, Inc.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -773,10 +773,28 @@ netdev_linux_alloc(void)
|
|||||||
return &netdev->up;
|
return &netdev->up;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static int
|
||||||
netdev_linux_common_construct(struct netdev_linux *netdev)
|
netdev_linux_common_construct(struct netdev *netdev_)
|
||||||
{
|
{
|
||||||
|
/* Prevent any attempt to create (or open) a network device named "default"
|
||||||
|
* or "all". These device names are effectively reserved on Linux because
|
||||||
|
* /proc/sys/net/ipv4/conf/ always contains directories by these names. By
|
||||||
|
* itself this wouldn't call for any special treatment, but in practice if
|
||||||
|
* a program tries to create devices with these names, it causes the kernel
|
||||||
|
* to fire a "new device" notification event even though creation failed,
|
||||||
|
* and in turn that causes OVS to wake up and try to create them again,
|
||||||
|
* which ends up as a 100% CPU loop. */
|
||||||
|
struct netdev_linux *netdev = netdev_linux_cast(netdev_);
|
||||||
|
const char *name = netdev_->name;
|
||||||
|
if (!strcmp(name, "default") || !strcmp(name, "all")) {
|
||||||
|
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
|
||||||
|
VLOG_WARN_RL(&rl, "%s: Linux forbids network device with this name",
|
||||||
|
name);
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
ovs_mutex_init(&netdev->mutex);
|
ovs_mutex_init(&netdev->mutex);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Creates system and internal devices. */
|
/* Creates system and internal devices. */
|
||||||
@@ -784,9 +802,10 @@ static int
|
|||||||
netdev_linux_construct(struct netdev *netdev_)
|
netdev_linux_construct(struct netdev *netdev_)
|
||||||
{
|
{
|
||||||
struct netdev_linux *netdev = netdev_linux_cast(netdev_);
|
struct netdev_linux *netdev = netdev_linux_cast(netdev_);
|
||||||
int error;
|
int error = netdev_linux_common_construct(netdev_);
|
||||||
|
if (error) {
|
||||||
netdev_linux_common_construct(netdev);
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
error = get_flags(&netdev->up, &netdev->ifi_flags);
|
error = get_flags(&netdev->up, &netdev->ifi_flags);
|
||||||
if (error == ENODEV) {
|
if (error == ENODEV) {
|
||||||
@@ -817,9 +836,11 @@ netdev_linux_construct_tap(struct netdev *netdev_)
|
|||||||
static const char tap_dev[] = "/dev/net/tun";
|
static const char tap_dev[] = "/dev/net/tun";
|
||||||
const char *name = netdev_->name;
|
const char *name = netdev_->name;
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
int error;
|
|
||||||
|
|
||||||
netdev_linux_common_construct(netdev);
|
int error = netdev_linux_common_construct(netdev_);
|
||||||
|
if (error) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
/* Open tap device. */
|
/* Open tap device. */
|
||||||
netdev->tap_fd = open(tap_dev, O_RDWR);
|
netdev->tap_fd = open(tap_dev, O_RDWR);
|
||||||
|
Reference in New Issue
Block a user