Commit 84e14fe3 authored by Maciej Żenczykowski's avatar Maciej Żenczykowski Committed by David S. Miller

net-ipv6: add support for sockopt(SOL_IPV6, IPV6_FREEBIND)

So far we've been relying on sockopt(SOL_IP, IP_FREEBIND) being usable
even on IPv6 sockets.

However, it turns out it is perfectly reasonable to want to set freebind
on an AF_INET6 SOCK_RAW socket - but there is no way to set any SOL_IP
socket option on such a socket (they're all blindly errored out).

One use case for this is to allow spoofing src ip on a raw socket
via sendmsg cmsg.

Tested:
  built, and booted
  # python
  >>> import socket
  >>> SOL_IP = socket.SOL_IP
  >>> SOL_IPV6 = socket.IPPROTO_IPV6
  >>> IP_FREEBIND = 15
  >>> IPV6_FREEBIND = 78
  >>> s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, 0)
  >>> s.getsockopt(SOL_IP, IP_FREEBIND)
  0
  >>> s.getsockopt(SOL_IPV6, IPV6_FREEBIND)
  0
  >>> s.setsockopt(SOL_IPV6, IPV6_FREEBIND, 1)
  >>> s.getsockopt(SOL_IP, IP_FREEBIND)
  1
  >>> s.getsockopt(SOL_IPV6, IPV6_FREEBIND)
  1
Signed-off-by: default avatarMaciej Żenczykowski <maze@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1f372c7b
...@@ -284,6 +284,7 @@ struct in6_flowlabel_req { ...@@ -284,6 +284,7 @@ struct in6_flowlabel_req {
#define IPV6_TRANSPARENT 75 #define IPV6_TRANSPARENT 75
#define IPV6_UNICAST_IF 76 #define IPV6_UNICAST_IF 76
#define IPV6_RECVFRAGSIZE 77 #define IPV6_RECVFRAGSIZE 77
#define IPV6_FREEBIND 78
/* /*
* Multicast Routing: * Multicast Routing:
......
...@@ -377,6 +377,14 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, ...@@ -377,6 +377,14 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
retv = 0; retv = 0;
break; break;
case IPV6_FREEBIND:
if (optlen < sizeof(int))
goto e_inval;
/* we also don't have a separate freebind bit for IPV6 */
inet_sk(sk)->freebind = valbool;
retv = 0;
break;
case IPV6_RECVORIGDSTADDR: case IPV6_RECVORIGDSTADDR:
if (optlen < sizeof(int)) if (optlen < sizeof(int))
goto e_inval; goto e_inval;
...@@ -1214,6 +1222,10 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, ...@@ -1214,6 +1222,10 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname,
val = inet_sk(sk)->transparent; val = inet_sk(sk)->transparent;
break; break;
case IPV6_FREEBIND:
val = inet_sk(sk)->freebind;
break;
case IPV6_RECVORIGDSTADDR: case IPV6_RECVORIGDSTADDR:
val = np->rxopt.bits.rxorigdstaddr; val = np->rxopt.bits.rxorigdstaddr;
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment