-
Notifications
You must be signed in to change notification settings - Fork 294
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tap update for modern linux versions #64
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -240,11 +240,12 @@ bool ether_init(void) | |
|
||
// Determine Ethernet device type | ||
net_if_type = -1; | ||
if (strncmp(name, "tap", 3) == 0) | ||
net_if_type = NET_IF_ETHERTAP; | ||
#if ENABLE_TUNTAP | ||
else if (strcmp(name, "tun") == 0) | ||
if (strncmp(name, "tap", 3) == 0) | ||
net_if_type = NET_IF_TUNTAP; | ||
#else | ||
if (strncmp(name, "tap", 3) == 0) | ||
net_if_type = NET_IF_ETHERTAP; | ||
#endif | ||
#ifdef HAVE_SLIRP | ||
else if (strcmp(name, "slirp") == 0) | ||
|
@@ -291,12 +292,15 @@ bool ether_init(void) | |
// Open sheep_net or ethertap or TUN/TAP device | ||
char dev_name[16]; | ||
switch (net_if_type) { | ||
case NET_IF_ETHERTAP: | ||
sprintf(dev_name, "/dev/%s", name); | ||
break; | ||
#if ENABLE_TUNTAP | ||
case NET_IF_TUNTAP: | ||
strcpy(dev_name, "/dev/net/tun"); | ||
break; | ||
#else | ||
case NET_IF_ETHERTAP: | ||
sprintf(dev_name, "/dev/%s", name); | ||
break; | ||
#endif | ||
case NET_IF_SHEEPNET: | ||
strcpy(dev_name, "/dev/sheep_net"); | ||
break; | ||
|
@@ -314,14 +318,6 @@ bool ether_init(void) | |
// Open TUN/TAP interface | ||
if (net_if_type == NET_IF_TUNTAP) { | ||
struct ifreq ifr; | ||
memset(&ifr, 0, sizeof(ifr)); | ||
ifr.ifr_flags = IFF_TAP | IFF_NO_PI; | ||
strcpy(ifr.ifr_name, "tun%d"); | ||
if (ioctl(fd, TUNSETIFF, (void *) &ifr) != 0) { | ||
sprintf(str, GetString(STR_SHEEP_NET_ATTACH_WARN), strerror(errno)); | ||
WarningAlert(str); | ||
goto open_error; | ||
} | ||
|
||
// Get network config script file path | ||
net_if_script = PrefsFindString("etherconfig"); | ||
|
@@ -334,12 +330,20 @@ bool ether_init(void) | |
WarningAlert(str); | ||
goto open_error; | ||
} | ||
net_if_name = strdup(ifr.ifr_name); | ||
net_if_name = strdup(name); | ||
if (!execute_network_script("up")) { | ||
sprintf(str, GetString(STR_TUN_TAP_CONFIG_WARN), "script execute error"); | ||
WarningAlert(str); | ||
goto open_error; | ||
} | ||
memset(&ifr, 0, sizeof(ifr)); | ||
ifr.ifr_flags = IFF_TAP | IFF_NO_PI; | ||
strcpy(ifr.ifr_name, name); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What ensures that ifr_name is big enough to hold name? Please use strlcpy instead. |
||
if (ioctl(fd, TUNSETIFF, (void *) &ifr) != 0) { | ||
sprintf(str, GetString(STR_SHEEP_NET_ATTACH_WARN), strerror(errno)); | ||
WarningAlert(str); | ||
goto open_error; | ||
} | ||
D(bug("Connected to host network interface: %s\n", net_if_name)); | ||
} | ||
#endif | ||
|
@@ -431,14 +435,6 @@ void ether_exit(void) | |
// Stop reception threads | ||
stop_thread(); | ||
|
||
// Shut down TUN/TAP interface | ||
if (net_if_type == NET_IF_TUNTAP) | ||
execute_network_script("down"); | ||
|
||
// Free TUN/TAP device name | ||
if (net_if_name) | ||
free(net_if_name); | ||
|
||
// Close sheep_net device | ||
if (fd > 0) | ||
close(fd); | ||
|
@@ -453,6 +449,14 @@ void ether_exit(void) | |
if (slirp_output_fd > 0) | ||
close(slirp_output_fd); | ||
|
||
// Shut down TUN/TAP interface | ||
if (net_if_type == NET_IF_TUNTAP) | ||
execute_network_script("down"); | ||
|
||
// Free TUN/TAP device name | ||
if (net_if_name) | ||
free(net_if_name); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you're changing this, could you add a line that sets it to NULL? |
||
|
||
#if STATISTICS | ||
// Show statistics | ||
printf("%ld messages put on write queue\n", num_wput); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -815,7 +815,7 @@ int main(int argc, char **argv) | |
|
||
#if defined(ENABLE_XF86_DGA) && !defined(ENABLE_MON) | ||
// Fork out, so we can return from fullscreen mode when things get ugly | ||
XF86DGAForkApp(DefaultScreen(x_display)); | ||
//XF86DGAForkApp(DefaultScreen(x_display)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems unrelated to the TAP fixes and I don't think should be in this commit. |
||
#endif | ||
#endif | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happened to "tun"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, this is a bit of a wall of text, hopefully the headings help a little:
tun
is a confusing name since it's atap
deviceAs mentioned in the blog post @hfmanson linked to, and this more obviously canonical kernel.org source (which I'm quoting from):
As you can see in the code, it uses
ifr.ifr_flags = IFF_TAP
, so it's using atap
-type interface (thankfully, because I want to use AppleTalk over one of these interfaces!), but the code being deleted above requires you to setether tun
in your configuration to select this, which is confusing.This is why @hfmanson also says "tunconfig (which should be renamed tapconfig IMO) [...]".
Prior to this patch,
tap
is used to refer to ethertapI guess that the term
tun
is used to refer to this type of interface because it is a "TUN/TAP" interface (as per the kernel.org document linked above) and although the code is using thetap
type, the code also supportsethertap
interfaces by settingether tapN
, so the termtap
was already taken.However, it's quite confusing to use
tun
to refer to thesetap
devices. It makes it difficult to search the web for help with issues if you think you're using atun
device when you're using atap
device.This patch makes TUN/TAP and ethertap mutually exclusive at build time
As @hfmanson says, "when tuntap is detected in the configure script ethertap is no longer used and the user can enter tapN as ether device". In other words, this patch means that when you run
configure
, if your host supports both ethertap and TUN/TAP, then you'll only be able to use TUN/TAP. That meanstap
can be used to refer to the interface regardless of whether you're using ethertap or TUN/TAP.I think that makes sense - http://user-mode-linux.sourceforge.net/old/UserModeLinux-HOWTO-6.html indicates that ethertap is for users of the Linux kernel version 2.2, and TUN/TAP is for 2.4 and later. It also says "Ethertap is available on 2.4 and works fine. TUN/TAP is preferred to it because it has better performance and ethertap is officially considered obsolete in 2.4." CentOS 7's kernel (version 3.10, which is relatively old) seems to be built without ethertap support.
How to select TUN/TAP or ethertap in the future
The patch causes both ethertap and TUN/TAP to be selected by providing the name of an existing
tapN
interface.Since the handling of TUN/TAP is changed significantly by the patch - the
tunconfig
script is called to create and configure the interface before BasiliskII attaches to it, instead of the previous behaviour where thetunconfig
script was called to configure the interface after BasiliskII had created it, and therefore the script is significantly different - any users that previously usedtun
are going to have to do some work to move to the new scheme.I think that the code ought to still do something about users with
tun
in their configuration, though. With this patch, it looks to me like that configuration would cause the code to fall back to theNET_IF_SHEEPNET
case, and presumably the user would then get an error message saying that there's no interface calledtun
. It would be much nicer to give them an error message saying that they should read the updatedREADME
file. Also, there really needs to be an update to theREADME
file!Alternatives
In Bochs, you specify that you want to use a
tap
type of TUN/TAP interface by specifyingtuntap
(I guess it is implicit that it's using atap
type). You also need to provide the path/dev/net/tun
(which you can see BasiliskII hard-codes, which is probably fine). Then, if you have an existingtap
interface, you can append:tapN
to that path (probably the interface's name doesn't even need to start withtap
, as the kernel doesn't enforce that, but I haven't tested this), otherwise Bochs will create the interface for you, much like BasiliskII does without this patch.It would probably be nice to act like Bochs in terms of separating the "I want to use a
tap
-type interface" configuration and the "here is the name of the existingtap
-type interface I want to use" configuration rather than enforcing that the interface's name start withtap
.As for emulating Bochs's ability to optionally create the interface for you, the fact that this patch runs the
tunconfig
script before it attaches to the interface would make this tricky, since you'd want to run it after if you just created the interface. I think that the scheme used in this patch, where the script is run before attaching to the interface, is pretty unconventional for emulators, and that generally if you wanted BasiliskII to not create the interface itself usingcap_net_admin
, you would simply create the interface before starting BasiliskII, which one could of course do with a wrapper script. I would prefer to have something that worked more like Bochs and less like this patch in this regard, although I don't have strong feelings either way - I'm happy to just create the interface myself and then tell BasiliskII to run an empty script.