From 05952067bb67e3f627c969fd91c9fef29dc7b27e Mon Sep 17 00:00:00 2001 From: Hans Petter Selasky Date: Thu, 26 Nov 2020 16:36:50 +0000 Subject: [PATCH] Ensure consistent error messages from ifconfig(8). If multiple threads are invoking "ifconfig XXX create" a race may occur which can lead to two different error messages for the same error. a) ifconfig: SIOCIFCREATE2: File exists b) ifconfig: interface XXX already exists This patch ensures ifconfig prints the same error code for the same case. Reviewed by: imp@ and kib@ Differential Revision: https://reviews.freebsd.org/D27380 MFC after: 1 week Sponsored by: Mellanox Technologies // NVIDIA Networking --- sbin/ifconfig/ifclone.c | 3 +-- sbin/ifconfig/ifconfig.c | 13 +++++++++++++ sbin/ifconfig/ifconfig.h | 1 + sbin/ifconfig/ifieee80211.c | 3 +-- sbin/ifconfig/iflagg.c | 3 +-- sbin/ifconfig/ifvlan.c | 3 +-- sbin/ifconfig/ifvxlan.c | 3 +-- 7 files changed, 19 insertions(+), 10 deletions(-) diff --git a/sbin/ifconfig/ifclone.c b/sbin/ifconfig/ifclone.c index 58bc3b3103ee..268cc0a28180 100644 --- a/sbin/ifconfig/ifclone.c +++ b/sbin/ifconfig/ifclone.c @@ -151,8 +151,7 @@ ifclonecreate(int s, void *arg) } if (clone_cb == NULL) { /* NB: no parameters */ - if (ioctl(s, SIOCIFCREATE2, &ifr) < 0) - err(1, "SIOCIFCREATE2"); + ioctl_ifcreate(s, &ifr); } else { clone_cb(s, &ifr); } diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index e47d0000c7ab..e6e7908e18cd 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -198,6 +198,19 @@ usage(void) exit(1); } +void +ioctl_ifcreate(int s, struct ifreq *ifr) +{ + if (ioctl(s, SIOCIFCREATE2, ifr) < 0) { + switch (errno) { + case EEXIST: + errx(1, "interface %s already exists", ifr->ifr_name); + default: + err(1, "SIOCIFCREATE2"); + } + } +} + #define ORDERS_SIZE(x) sizeof(x) / sizeof(x[0]) static int diff --git a/sbin/ifconfig/ifconfig.h b/sbin/ifconfig/ifconfig.h index f91ee2fd23bb..67c25f5921d6 100644 --- a/sbin/ifconfig/ifconfig.h +++ b/sbin/ifconfig/ifconfig.h @@ -160,3 +160,4 @@ struct ifmediareq *ifmedia_getstate(int s); void print_vhid(const struct ifaddrs *, const char *); +void ioctl_ifcreate(int s, struct ifreq *); diff --git a/sbin/ifconfig/ifieee80211.c b/sbin/ifconfig/ifieee80211.c index d3f1c3e3aea6..bb406469829a 100644 --- a/sbin/ifconfig/ifieee80211.c +++ b/sbin/ifconfig/ifieee80211.c @@ -5758,8 +5758,7 @@ wlan_create(int s, struct ifreq *ifr) memcmp(params.icp_bssid, zerobssid, sizeof(zerobssid)) == 0) errx(1, "no bssid specified for WDS (use wlanbssid)"); ifr->ifr_data = (caddr_t) ¶ms; - if (ioctl(s, SIOCIFCREATE2, ifr) < 0) - err(1, "SIOCIFCREATE2"); + ioctl_ifcreate(s, ifr); /* XXX preserve original name for ifclonecreate(). */ strlcpy(orig_name, name, sizeof(orig_name)); diff --git a/sbin/ifconfig/iflagg.c b/sbin/ifconfig/iflagg.c index 86532aae3aef..5be8c67cd72a 100644 --- a/sbin/ifconfig/iflagg.c +++ b/sbin/ifconfig/iflagg.c @@ -324,8 +324,7 @@ static void lagg_create(int s, struct ifreq *ifr) { ifr->ifr_data = (caddr_t) ¶ms; - if (ioctl(s, SIOCIFCREATE2, ifr) < 0) - err(1, "SIOCIFCREATE2"); + ioctl_ifcreate(s, ifr); } static struct cmd lagg_cmds[] = { diff --git a/sbin/ifconfig/ifvlan.c b/sbin/ifconfig/ifvlan.c index bbf9d0324cde..f316b0404459 100644 --- a/sbin/ifconfig/ifvlan.c +++ b/sbin/ifconfig/ifvlan.c @@ -162,8 +162,7 @@ vlan_create(int s, struct ifreq *ifr) errx(1, "must specify a parent device for vlan create"); ifr->ifr_data = (caddr_t) ¶ms; } - if (ioctl(s, SIOCIFCREATE2, ifr) < 0) - err(1, "SIOCIFCREATE2"); + ioctl_ifcreate(s, ifr); } static void diff --git a/sbin/ifconfig/ifvxlan.c b/sbin/ifconfig/ifvxlan.c index e9ccc0f4fb2e..fda435343a16 100644 --- a/sbin/ifconfig/ifvxlan.c +++ b/sbin/ifconfig/ifvxlan.c @@ -191,8 +191,7 @@ vxlan_create(int s, struct ifreq *ifr) vxlan_check_params(); ifr->ifr_data = (caddr_t) ¶ms; - if (ioctl(s, SIOCIFCREATE2, ifr) < 0) - err(1, "SIOCIFCREATE2"); + ioctl_ifcreate(s, ifr); } static