linux: Support IPPROTO_RAW socket option translation

Handle Linux IPPROTO_RAW socket options in the Linuxulator for both
getsockopt(2) and setsockopt(2). Detect the socket family and remap
the level to IPPROTO_IPV6 for AF_INET6, reusing the existing option
translators.

This fixes IPV6_CHECKSUM for IPv6 raw sockets, which Linux programs
set at level IPPROTO_RAW rather than IPPROTO_IPV6.

Signed-off-by:	Ricardo Branco <rbranco@suse.de>
PR:		294434
Reviewed by:	pouria
Pull-Request:	https://github.com/freebsd/freebsd-src/pull/2138
This commit is contained in:
Ricardo Branco
2026-04-12 16:08:38 +02:00
committed by Pouria Mousavizadeh Tehrani
parent 64e2715f5d
commit caaa7a07fe
+41
View File
@@ -30,6 +30,7 @@
#include <sys/param.h>
#include <sys/capsicum.h>
#include <sys/domain.h>
#include <sys/filedesc.h>
#include <sys/limits.h>
#include <sys/malloc.h>
@@ -2190,6 +2191,26 @@ linux_setsockopt(struct thread *td, struct linux_setsockopt_args *args)
}
break;
#ifdef INET6
case IPPROTO_RAW: {
struct file *fp;
struct socket *so;
int family;
error = getsock(td, args->s, &cap_setsockopt_rights, &fp);
if (error != 0)
return (error);
so = fp->f_data;
family = so->so_proto->pr_domain->dom_family;
fdrop(fp, td);
name = -1;
if (family == AF_INET6) {
name = linux_to_bsd_ip6_sockopt(args->optname);
if (name >= 0)
level = IPPROTO_IPV6;
}
break;
}
case IPPROTO_ICMPV6: {
struct icmp6_filter f;
int i;
@@ -2473,6 +2494,26 @@ linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args)
}
break;
#ifdef INET6
case IPPROTO_RAW: {
struct file *fp;
struct socket *so;
int family;
error = getsock(td, args->s, &cap_getsockopt_rights, &fp);
if (error != 0)
return (error);
so = fp->f_data;
family = so->so_proto->pr_domain->dom_family;
fdrop(fp, td);
name = -1;
if (family == AF_INET6) {
name = linux_to_bsd_ip6_sockopt(args->optname);
if (name >= 0)
level = IPPROTO_IPV6;
}
break;
}
case IPPROTO_ICMPV6: {
struct icmp6_filter f;
int i;