Message ID | 14A83280-2A2D-4DCC-BD75-5DB6B43883EB@irisa.fr |
---|---|
State | New |
Headers | show |
On Tue, 2009-11-24 at 22:27 +0100, Pierre Riteau wrote: > On 24 nov. 2009, at 12:22, Mark McLoughlin wrote: > > > On Tue, 2009-11-24 at 12:17 +0100, Pierre Riteau wrote: > >> Isn't there a way to detect whether the kernel supports the > >> TUNSETOFFLOAD ioctl at all? > > > > The kernel will set errno to EINVAL if TUNSETOFFLOAD isn't supported, so > > we could just ignore that case: > > > > if (ioctl(fd, TUNSETOFFLOAD, offload) != 0) { > > offload &= ~TUN_F_UFO; > > if (ioctl(fd, TUNSETOFFLOAD, offload) != 0 && errno != EINVAL) { > > fprintf(stderr, "TUNSETOFFLOAD ioctl() failed: %s\n", > > strerror(errno)); > > } > > } > > > > The only concern is that we'll also miss out on an error message if > > EINVAL is set for another reason. Currently, the only other reason if we > > pass a offload flag not supported by the kernel, but that should never > > happen. > > > > Feel free to send a patch with that change and I'll ack it .... > > Couldn't we probe the kernel with a 0 offload value to check if it supports TUNSETOFFLOAD? > I tried the following and it works on my 2.6.26 Debian kernel. > What do you think? I will send a proper patch if you agree. > > diff --git a/net/tap-linux.c b/net/tap-linux.c > index 0f621a2..e038e1a 100644 > --- a/net/tap-linux.c > +++ b/net/tap-linux.c > @@ -129,6 +129,11 @@ void tap_fd_set_offload(int fd, int csum, int tso4, > { > unsigned int offload = 0; > > + /* Check if our kernel supports TUNSETOFFLOAD */ > + if (ioctl(fd, TUNSETOFFLOAD, 0) != 0 && errno == EINVAL) { > + return; > + } > + It's not ideal because a) it's another syscall and b) you're briefly disabling any flags that may have been set previously ... but in our case, neither is a real concern and it's a nice, simple solution. So, sounds good to me :) Cheers, Mark.
diff --git a/net/tap-linux.c b/net/tap-linux.c index 0f621a2..e038e1a 100644 --- a/net/tap-linux.c +++ b/net/tap-linux.c @@ -129,6 +129,11 @@ void tap_fd_set_offload(int fd, int csum, int tso4, { unsigned int offload = 0; + /* Check if our kernel supports TUNSETOFFLOAD */ + if (ioctl(fd, TUNSETOFFLOAD, 0) != 0 && errno == EINVAL) { + return; + } + if (csum) { offload |= TUN_F_CSUM; if (tso4)