diff options
author | djm@openbsd.org <djm@openbsd.org> | 2015-10-07 02:54:06 +0200 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2015-10-07 19:01:04 +0200 |
commit | 2905d6f99c837bb699b6ebc61711b19acd030709 (patch) | |
tree | 0a0f2531b0bbc0fd649daab9f52fcc5a37ccab71 /misc.c | |
parent | unbreak merge botch (diff) | |
download | openssh-2905d6f99c837bb699b6ebc61711b19acd030709.tar.xz openssh-2905d6f99c837bb699b6ebc61711b19acd030709.zip |
upstream commit
don't try to change tun device flags if they are already
what we need; makes it possible to use tun/tap networking as non- root user
if device permissions and interface flags are pre-established; based on patch
by Ossi Herrala
Upstream-ID: 89099ac4634cd477b066865acf54cb230780fd21
Diffstat (limited to 'misc.c')
-rw-r--r-- | misc.c | 55 |
1 files changed, 33 insertions, 22 deletions
@@ -1,4 +1,4 @@ -/* $OpenBSD: misc.c,v 1.97 2015/04/24 01:36:00 deraadt Exp $ */ +/* $OpenBSD: misc.c,v 1.98 2015/10/07 00:54:06 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2005,2006 Damien Miller. All rights reserved. @@ -666,49 +666,60 @@ tun_open(int tun, int mode) } } else { debug("%s: invalid tunnel %u", __func__, tun); - return (-1); + return -1; } if (fd < 0) { - debug("%s: %s open failed: %s", __func__, name, strerror(errno)); - return (-1); + debug("%s: %s open: %s", __func__, name, strerror(errno)); + return -1; } debug("%s: %s mode %d fd %d", __func__, name, mode, fd); /* Set the tunnel device operation mode */ snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "tun%d", tun); - if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) + if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) { + error("%s: socket: %s", __func__, strerror(errno)); goto failed; + } - if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) + if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) { + debug("%s: get interface %s flags: %s", __func__, + ifr.ifr_name, strerror(errno)); goto failed; + } - /* Set interface mode */ - ifr.ifr_flags &= ~IFF_UP; - if (mode == SSH_TUNMODE_ETHERNET) - ifr.ifr_flags |= IFF_LINK0; - else - ifr.ifr_flags &= ~IFF_LINK0; - if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) - goto failed; + /* Set interface mode if not already in correct mode */ + if ((mode == SSH_TUNMODE_ETHERNET && !(ifr.ifr_flags & IFF_LINK0)) || + (mode != SSH_TUNMODE_ETHERNET && (ifr.ifr_flags & IFF_LINK0))) { + ifr.ifr_flags &= ~IFF_UP; + ifr.ifr_flags ^= IFF_LINK0; + if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) { + debug("%s: reset interface %s flags: %s", __func__, + ifr.ifr_name, strerror(errno)); + goto failed; + } + } - /* Bring interface up */ - ifr.ifr_flags |= IFF_UP; - if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) - goto failed; + /* Bring interface up if it is not already */ + if (!(ifr.ifr_flags & IFF_UP)) { + ifr.ifr_flags |= IFF_UP; + if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) { + debug("%s: activate interface %s: %s", __func__, + ifr.ifr_name, strerror(errno)); + goto failed; + } + } close(sock); - return (fd); + return fd; failed: if (fd >= 0) close(fd); if (sock >= 0) close(sock); - debug("%s: failed to set %s mode %d: %s", __func__, name, - mode, strerror(errno)); - return (-1); + return -1; #else error("Tunnel interfaces are not supported on this platform"); return (-1); |