ip6tables: (de)serialize ip6tables structs

More implementation+testing to follow.

#3549.

PiperOrigin-RevId: 328770160
This commit is contained in:
Kevin Krakauer
2020-08-27 10:53:49 -07:00
committed by gVisor bot
parent 140ffb6007
commit 01a35a2f19
10 changed files with 489 additions and 50 deletions
+68 -7
View File
@@ -997,7 +997,7 @@ func GetSockOpt(t *kernel.Task, s socket.SocketOps, ep commonEndpoint, family in
return getSockOptTCP(t, ep, name, outLen)
case linux.SOL_IPV6:
return getSockOptIPv6(t, ep, name, outLen)
return getSockOptIPv6(t, s, ep, name, outPtr, outLen)
case linux.SOL_IP:
return getSockOptIP(t, s, ep, name, outPtr, outLen, family)
@@ -1455,7 +1455,7 @@ func getSockOptTCP(t *kernel.Task, ep commonEndpoint, name, outLen int) (marshal
}
// getSockOptIPv6 implements GetSockOpt when level is SOL_IPV6.
func getSockOptIPv6(t *kernel.Task, ep commonEndpoint, name, outLen int) (marshal.Marshallable, *syserr.Error) {
func getSockOptIPv6(t *kernel.Task, s socket.SocketOps, ep commonEndpoint, name int, outPtr usermem.Addr, outLen int) (marshal.Marshallable, *syserr.Error) {
switch name {
case linux.IPV6_V6ONLY:
if outLen < sizeOfInt32 {
@@ -1508,10 +1508,50 @@ func getSockOptIPv6(t *kernel.Task, ep commonEndpoint, name, outLen int) (marsha
vP := primitive.Int32(boolToInt32(v))
return &vP, nil
case linux.SO_ORIGINAL_DST:
case linux.IP6T_ORIGINAL_DST:
// TODO(gvisor.dev/issue/170): ip6tables.
return nil, syserr.ErrInvalidArgument
case linux.IP6T_SO_GET_INFO:
if outLen < linux.SizeOfIPTGetinfo {
return nil, syserr.ErrInvalidArgument
}
// Only valid for raw IPv6 sockets.
if family, skType, _ := s.Type(); family != linux.AF_INET6 || skType != linux.SOCK_RAW {
return nil, syserr.ErrProtocolNotAvailable
}
stack := inet.StackFromContext(t)
if stack == nil {
return nil, syserr.ErrNoDevice
}
info, err := netfilter.GetInfo(t, stack.(*Stack).Stack, outPtr, true)
if err != nil {
return nil, err
}
return &info, nil
case linux.IP6T_SO_GET_ENTRIES:
// IPTGetEntries is reused for IPv6.
if outLen < linux.SizeOfIPTGetEntries {
return nil, syserr.ErrInvalidArgument
}
// Only valid for raw IPv6 sockets.
if family, skType, _ := s.Type(); family != linux.AF_INET6 || skType != linux.SOCK_RAW {
return nil, syserr.ErrProtocolNotAvailable
}
stack := inet.StackFromContext(t)
if stack == nil {
return nil, syserr.ErrNoDevice
}
entries, err := netfilter.GetEntries6(t, stack.(*Stack).Stack, outPtr, outLen)
if err != nil {
return nil, err
}
return &entries, nil
default:
emitUnimplementedEventIPv6(t, name)
}
@@ -1649,7 +1689,7 @@ func getSockOptIP(t *kernel.Task, s socket.SocketOps, ep commonEndpoint, name in
if stack == nil {
return nil, syserr.ErrNoDevice
}
info, err := netfilter.GetInfo(t, stack.(*Stack).Stack, outPtr)
info, err := netfilter.GetInfo(t, stack.(*Stack).Stack, outPtr, false)
if err != nil {
return nil, err
}
@@ -1722,7 +1762,7 @@ func SetSockOpt(t *kernel.Task, s socket.SocketOps, ep commonEndpoint, level int
return setSockOptTCP(t, ep, name, optVal)
case linux.SOL_IPV6:
return setSockOptIPv6(t, ep, name, optVal)
return setSockOptIPv6(t, s, ep, name, optVal)
case linux.SOL_IP:
return setSockOptIP(t, s, ep, name, optVal)
@@ -2027,7 +2067,7 @@ func setSockOptTCP(t *kernel.Task, ep commonEndpoint, name int, optVal []byte) *
}
// setSockOptIPv6 implements SetSockOpt when level is SOL_IPV6.
func setSockOptIPv6(t *kernel.Task, ep commonEndpoint, name int, optVal []byte) *syserr.Error {
func setSockOptIPv6(t *kernel.Task, s socket.SocketOps, ep commonEndpoint, name int, optVal []byte) *syserr.Error {
switch name {
case linux.IPV6_V6ONLY:
if len(optVal) < sizeOfInt32 {
@@ -2076,6 +2116,27 @@ func setSockOptIPv6(t *kernel.Task, ep commonEndpoint, name int, optVal []byte)
return syserr.TranslateNetstackError(ep.SetSockOptBool(tcpip.ReceiveTClassOption, v != 0))
case linux.IP6T_SO_SET_REPLACE:
if len(optVal) < linux.SizeOfIP6TReplace {
return syserr.ErrInvalidArgument
}
// Only valid for raw IPv6 sockets.
if family, skType, _ := s.Type(); family != linux.AF_INET6 || skType != linux.SOCK_RAW {
return syserr.ErrProtocolNotAvailable
}
stack := inet.StackFromContext(t)
if stack == nil {
return syserr.ErrNoDevice
}
// Stack must be a netstack stack.
return netfilter.SetEntries(stack.(*Stack).Stack, optVal, true)
case linux.IP6T_SO_SET_ADD_COUNTERS:
// TODO(gvisor.dev/issue/170): Counter support.
return nil
default:
emitUnimplementedEventIPv6(t, name)
}
@@ -2271,7 +2332,7 @@ func setSockOptIP(t *kernel.Task, s socket.SocketOps, ep commonEndpoint, name in
return syserr.ErrNoDevice
}
// Stack must be a netstack stack.
return netfilter.SetEntries(stack.(*Stack).Stack, optVal)
return netfilter.SetEntries(stack.(*Stack).Stack, optVal, false)
case linux.IPT_SO_SET_ADD_COUNTERS:
// TODO(gvisor.dev/issue/170): Counter support.