Skip to content

Commit 64268c8

Browse files
kevinGCgvisor-bot
authored andcommitted
netstack: make tcpip.Address an opaque type
The important change here is in tcpip/tcpip.go, where tcpip.Address is defined. The rest is updating uses of tcpip.Address. This is preparation for netip.Addr or []byte based addresses, which should save us a bunch of allocations. Currently, we allocate every time we want to, say, get a tcpip.Address from a header. This is because the header is a byte slice, but Address is a string. Strings are immutable, so Go allocates and copies. PiperOrigin-RevId: 532284732
1 parent 83f4f48 commit 64268c8

File tree

110 files changed

+1400
-1122
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

110 files changed

+1400
-1122
lines changed

pkg/sentry/socket/hostinet/netlink.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -284,21 +284,21 @@ func doNetlinkInterfaceRequest(typ, flags uint16, idx uint32, addr inet.Interfac
284284
Flags: addr.Flags,
285285
}
286286
// Local address.
287-
localAddr := tcpip.Address(addr.Addr)
287+
localAddr := tcpip.AddrFromSlice(addr.Addr)
288288
if addr.Family == linux.AF_INET {
289289
localAddr = localAddr.To4()
290290
}
291291
rtLocal := linux.RtAttr{
292-
Len: linux.SizeOfRtAttr + uint16(len(localAddr)),
292+
Len: linux.SizeOfRtAttr + uint16(localAddr.Len()),
293293
Type: linux.IFA_LOCAL,
294294
}
295-
localAddrBs := primitive.ByteSlice(localAddr)
295+
localAddrBs := primitive.ByteSlice(localAddr.AsSlice())
296296
// Peer is always the local address for us.
297297
rtPeer := linux.RtAttr{
298-
Len: linux.SizeOfRtAttr + uint16(len(localAddr)),
298+
Len: linux.SizeOfRtAttr + uint16(localAddr.Len()),
299299
Type: linux.IFA_ADDRESS,
300300
}
301-
peerAddrBs := primitive.ByteSlice(localAddr)
301+
peerAddrBs := primitive.ByteSlice(localAddr.AsSlice())
302302

303303
msgs := []marshal.Marshallable{
304304
&hdr,

pkg/sentry/socket/netfilter/ipv4.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ import (
2828
// emptyIPv4Filter is for comparison with a rule's filters to determine whether
2929
// it is also empty. It is immutable.
3030
var emptyIPv4Filter = stack.IPHeaderFilter{
31-
Dst: "\x00\x00\x00\x00",
32-
DstMask: "\x00\x00\x00\x00",
33-
Src: "\x00\x00\x00\x00",
34-
SrcMask: "\x00\x00\x00\x00",
31+
Dst: tcpip.AddrFrom4([4]byte{0x00, 0x00, 0x00, 0x00}),
32+
DstMask: tcpip.AddrFrom4([4]byte{0x00, 0x00, 0x00, 0x00}),
33+
Src: tcpip.AddrFrom4([4]byte{0x00, 0x00, 0x00, 0x00}),
34+
SrcMask: tcpip.AddrFrom4([4]byte{0x00, 0x00, 0x00, 0x00}),
3535
}
3636

3737
// convertNetstackToBinary4 converts the iptables as stored in netstack to the
@@ -75,10 +75,10 @@ func getEntries4(table stack.Table, tablename linux.TableName) (linux.KernelIPTG
7575
TargetOffset: linux.SizeOfIPTEntry,
7676
},
7777
}
78-
copy(entry.Entry.IP.Dst[:], rule.Filter.Dst)
79-
copy(entry.Entry.IP.DstMask[:], rule.Filter.DstMask)
80-
copy(entry.Entry.IP.Src[:], rule.Filter.Src)
81-
copy(entry.Entry.IP.SrcMask[:], rule.Filter.SrcMask)
78+
copy(entry.Entry.IP.Dst[:], rule.Filter.Dst.AsSlice())
79+
copy(entry.Entry.IP.DstMask[:], rule.Filter.DstMask.AsSlice())
80+
copy(entry.Entry.IP.Src[:], rule.Filter.Src.AsSlice())
81+
copy(entry.Entry.IP.SrcMask[:], rule.Filter.SrcMask.AsSlice())
8282
copy(entry.Entry.IP.OutputInterface[:], rule.Filter.OutputInterface)
8383
copy(entry.Entry.IP.OutputInterfaceMask[:], rule.Filter.OutputInterfaceMask)
8484
copy(entry.Entry.IP.InputInterface[:], rule.Filter.InputInterface)
@@ -218,11 +218,11 @@ func filterFromIPTIP(iptip linux.IPTIP) (stack.IPHeaderFilter, error) {
218218
Protocol: tcpip.TransportProtocolNumber(iptip.Protocol),
219219
// A Protocol value of 0 indicates all protocols match.
220220
CheckProtocol: iptip.Protocol != 0,
221-
Dst: tcpip.Address(iptip.Dst[:]),
222-
DstMask: tcpip.Address(iptip.DstMask[:]),
221+
Dst: tcpip.AddrFrom4(iptip.Dst),
222+
DstMask: tcpip.AddrFrom4(iptip.DstMask),
223223
DstInvert: iptip.InverseFlags&linux.IPT_INV_DSTIP != 0,
224-
Src: tcpip.Address(iptip.Src[:]),
225-
SrcMask: tcpip.Address(iptip.SrcMask[:]),
224+
Src: tcpip.AddrFrom4(iptip.Src),
225+
SrcMask: tcpip.AddrFrom4(iptip.SrcMask),
226226
SrcInvert: iptip.InverseFlags&linux.IPT_INV_SRCIP != 0,
227227
InputInterface: string(trimNullBytes(iptip.InputInterface[:])),
228228
InputInterfaceMask: string(trimNullBytes(iptip.InputInterfaceMask[:])),

pkg/sentry/socket/netfilter/ipv6.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ import (
2828
// emptyIPv6Filter is for comparison with a rule's filters to determine whether
2929
// it is also empty. It is immutable.
3030
var emptyIPv6Filter = stack.IPHeaderFilter{
31-
Dst: "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
32-
DstMask: "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
33-
Src: "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
34-
SrcMask: "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
31+
Dst: tcpip.AddrFrom16([16]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
32+
DstMask: tcpip.AddrFrom16([16]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
33+
Src: tcpip.AddrFrom16([16]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
34+
SrcMask: tcpip.AddrFrom16([16]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}),
3535
}
3636

3737
// convertNetstackToBinary6 converts the ip6tables as stored in netstack to the
@@ -75,10 +75,10 @@ func getEntries6(table stack.Table, tablename linux.TableName) (linux.KernelIP6T
7575
TargetOffset: linux.SizeOfIP6TEntry,
7676
},
7777
}
78-
copy(entry.Entry.IPv6.Dst[:], rule.Filter.Dst)
79-
copy(entry.Entry.IPv6.DstMask[:], rule.Filter.DstMask)
80-
copy(entry.Entry.IPv6.Src[:], rule.Filter.Src)
81-
copy(entry.Entry.IPv6.SrcMask[:], rule.Filter.SrcMask)
78+
copy(entry.Entry.IPv6.Dst[:], rule.Filter.Dst.AsSlice())
79+
copy(entry.Entry.IPv6.DstMask[:], rule.Filter.DstMask.AsSlice())
80+
copy(entry.Entry.IPv6.Src[:], rule.Filter.Src.AsSlice())
81+
copy(entry.Entry.IPv6.SrcMask[:], rule.Filter.SrcMask.AsSlice())
8282
copy(entry.Entry.IPv6.OutputInterface[:], rule.Filter.OutputInterface)
8383
copy(entry.Entry.IPv6.OutputInterfaceMask[:], rule.Filter.OutputInterfaceMask)
8484
copy(entry.Entry.IPv6.InputInterface[:], rule.Filter.InputInterface)
@@ -221,11 +221,11 @@ func filterFromIP6TIP(iptip linux.IP6TIP) (stack.IPHeaderFilter, error) {
221221
Protocol: tcpip.TransportProtocolNumber(iptip.Protocol),
222222
// In ip6tables a flag controls whether to check the protocol.
223223
CheckProtocol: iptip.Flags&linux.IP6T_F_PROTO != 0,
224-
Dst: tcpip.Address(iptip.Dst[:]),
225-
DstMask: tcpip.Address(iptip.DstMask[:]),
224+
Dst: tcpip.AddrFrom16(iptip.Dst),
225+
DstMask: tcpip.AddrFrom16(iptip.DstMask),
226226
DstInvert: iptip.InverseFlags&linux.IP6T_INV_DSTIP != 0,
227-
Src: tcpip.Address(iptip.Src[:]),
228-
SrcMask: tcpip.Address(iptip.SrcMask[:]),
227+
Src: tcpip.AddrFrom16(iptip.Src),
228+
SrcMask: tcpip.AddrFrom16(iptip.SrcMask),
229229
SrcInvert: iptip.InverseFlags&linux.IP6T_INV_SRCIP != 0,
230230
InputInterface: string(trimNullBytes(iptip.InputInterface[:])),
231231
InputInterfaceMask: string(trimNullBytes(iptip.InputInterfaceMask[:])),

pkg/sentry/socket/netfilter/targets.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ func (*redirectTargetMaker) unmarshal(buf []byte, filter stack.IPHeaderFilter) (
346346
return nil, syserr.ErrInvalidArgument
347347
}
348348

349-
target.addr = tcpip.Address(nfRange.RangeIPV4.MinIP[:])
349+
target.addr = tcpip.AddrFrom4(nfRange.RangeIPV4.MinIP)
350350
target.Port = ntohs(nfRange.RangeIPV4.MinPort)
351351

352352
return &target, nil
@@ -382,8 +382,8 @@ func (*nfNATTargetMaker) marshal(target target) []byte {
382382
},
383383
}
384384
copy(nt.Target.Name[:], RedirectTargetName)
385-
copy(nt.Range.MinAddr[:], rt.addr)
386-
copy(nt.Range.MaxAddr[:], rt.addr)
385+
copy(nt.Range.MinAddr[:], rt.addr.AsSlice())
386+
copy(nt.Range.MaxAddr[:], rt.addr.AsSlice())
387387

388388
nt.Range.MinProto = htons(rt.Port)
389389
nt.Range.MaxProto = nt.Range.MinProto
@@ -426,7 +426,7 @@ func (*nfNATTargetMaker) unmarshal(buf []byte, filter stack.IPHeaderFilter) (tar
426426
NetworkProtocol: filter.NetworkProtocol(),
427427
Port: ntohs(natRange.MinProto),
428428
},
429-
addr: tcpip.Address(natRange.MinAddr[:]),
429+
addr: tcpip.AddrFrom16(natRange.MinAddr),
430430
}
431431

432432
return &target, nil
@@ -457,8 +457,8 @@ func (*snatTargetMakerV4) marshal(target target) []byte {
457457
xt.NfRange.RangeIPV4.Flags |= linux.NF_NAT_RANGE_MAP_IPS | linux.NF_NAT_RANGE_PROTO_SPECIFIED
458458
xt.NfRange.RangeIPV4.MinPort = htons(st.Port)
459459
xt.NfRange.RangeIPV4.MaxPort = xt.NfRange.RangeIPV4.MinPort
460-
copy(xt.NfRange.RangeIPV4.MinIP[:], st.Addr)
461-
copy(xt.NfRange.RangeIPV4.MaxIP[:], st.Addr)
460+
copy(xt.NfRange.RangeIPV4.MinIP[:], st.Addr.AsSlice())
461+
copy(xt.NfRange.RangeIPV4.MaxIP[:], st.Addr.AsSlice())
462462
return marshal.Marshal(&xt)
463463
}
464464

@@ -504,7 +504,7 @@ func (*snatTargetMakerV4) unmarshal(buf []byte, filter stack.IPHeaderFilter) (ta
504504
return nil, syserr.ErrInvalidArgument
505505
}
506506

507-
target.Addr = tcpip.Address(nfRange.RangeIPV4.MinIP[:])
507+
target.Addr = tcpip.AddrFrom4(nfRange.RangeIPV4.MinIP)
508508
target.Port = ntohs(nfRange.RangeIPV4.MinPort)
509509

510510
return &target, nil
@@ -533,8 +533,8 @@ func (*snatTargetMakerV6) marshal(target target) []byte {
533533
},
534534
}
535535
copy(nt.Target.Name[:], SNATTargetName)
536-
copy(nt.Range.MinAddr[:], st.Addr)
537-
copy(nt.Range.MaxAddr[:], st.Addr)
536+
copy(nt.Range.MinAddr[:], st.Addr.AsSlice())
537+
copy(nt.Range.MaxAddr[:], st.Addr.AsSlice())
538538
nt.Range.MinProto = htons(st.Port)
539539
nt.Range.MaxProto = nt.Range.MinProto
540540

@@ -574,7 +574,7 @@ func (*snatTargetMakerV6) unmarshal(buf []byte, filter stack.IPHeaderFilter) (ta
574574
target := snatTarget{
575575
SNATTarget: stack.SNATTarget{
576576
NetworkProtocol: filter.NetworkProtocol(),
577-
Addr: tcpip.Address(natRange.MinAddr[:]),
577+
Addr: tcpip.AddrFrom16(natRange.MinAddr),
578578
Port: ntohs(natRange.MinProto),
579579
},
580580
}

pkg/sentry/socket/netstack/netstack.go

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -666,8 +666,8 @@ func (s *sock) checkFamily(family uint16, exact bool) bool {
666666
//
667667
// TODO(gvisor.dev/issue/1556): remove this function.
668668
func (s *sock) mapFamily(addr tcpip.FullAddress, family uint16) tcpip.FullAddress {
669-
if len(addr.Addr) == 0 && s.family == linux.AF_INET6 && family == linux.AF_INET {
670-
addr.Addr = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00"
669+
if addr.Addr.BitLen() == 0 && s.family == linux.AF_INET6 && family == linux.AF_INET {
670+
addr.Addr = tcpip.AddrFrom16([16]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00})
671671
}
672672
return addr
673673
}
@@ -748,8 +748,11 @@ func (s *sock) Bind(_ *kernel.Task, sockaddr []byte) *syserr.Error {
748748
a.UnmarshalBytes(sockaddr)
749749

750750
addr = tcpip.FullAddress{
751-
NIC: tcpip.NICID(a.InterfaceIndex),
752-
Addr: tcpip.Address(a.HardwareAddr[:header.EthernetAddressSize]),
751+
NIC: tcpip.NICID(a.InterfaceIndex),
752+
Addr: tcpip.AddrFrom16Slice(append(
753+
a.HardwareAddr[:header.EthernetAddressSize],
754+
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}...,
755+
)),
753756
Port: socket.Ntohs(a.Protocol),
754757
}
755758
} else {
@@ -2181,7 +2184,7 @@ func setSockOptIPv6(t *kernel.Task, s socket.Socket, ep commonEndpoint, name int
21812184

21822185
return syserr.TranslateNetstackError(ep.SetSockOpt(&tcpip.AddMembershipOption{
21832186
NIC: tcpip.NICID(req.InterfaceIndex),
2184-
MulticastAddr: tcpip.Address(req.MulticastAddr[:]),
2187+
MulticastAddr: tcpip.AddrFrom16(req.MulticastAddr),
21852188
}))
21862189

21872190
case linux.IPV6_DROP_MEMBERSHIP:
@@ -2192,7 +2195,7 @@ func setSockOptIPv6(t *kernel.Task, s socket.Socket, ep commonEndpoint, name int
21922195

21932196
return syserr.TranslateNetstackError(ep.SetSockOpt(&tcpip.RemoveMembershipOption{
21942197
NIC: tcpip.NICID(req.InterfaceIndex),
2195-
MulticastAddr: tcpip.Address(req.MulticastAddr[:]),
2198+
MulticastAddr: tcpip.AddrFrom16(req.MulticastAddr),
21962199
}))
21972200

21982201
case linux.IPV6_IPSEC_POLICY,
@@ -2399,8 +2402,8 @@ func setSockOptIP(t *kernel.Task, s socket.Socket, ep commonEndpoint, name int,
23992402
NIC: tcpip.NICID(req.InterfaceIndex),
24002403
// TODO(igudger): Change AddMembership to use the standard
24012404
// any address representation.
2402-
InterfaceAddr: tcpip.Address(req.InterfaceAddr[:]),
2403-
MulticastAddr: tcpip.Address(req.MulticastAddr[:]),
2405+
InterfaceAddr: tcpip.AddrFrom4(req.InterfaceAddr),
2406+
MulticastAddr: tcpip.AddrFrom4(req.MulticastAddr),
24042407
}))
24052408

24062409
case linux.IP_DROP_MEMBERSHIP:
@@ -2413,8 +2416,8 @@ func setSockOptIP(t *kernel.Task, s socket.Socket, ep commonEndpoint, name int,
24132416
NIC: tcpip.NICID(req.InterfaceIndex),
24142417
// TODO(igudger): Change DropMembership to use the standard
24152418
// any address representation.
2416-
InterfaceAddr: tcpip.Address(req.InterfaceAddr[:]),
2417-
MulticastAddr: tcpip.Address(req.MulticastAddr[:]),
2419+
InterfaceAddr: tcpip.AddrFrom4(req.InterfaceAddr),
2420+
MulticastAddr: tcpip.AddrFrom4(req.MulticastAddr),
24182421
}))
24192422

24202423
case linux.IP_MULTICAST_IF:

pkg/sentry/socket/netstack/stack.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ func (s *Stack) InterfaceAddrs() map[int32][]inet.InterfaceAddr {
120120
addrs = append(addrs, inet.InterfaceAddr{
121121
Family: family,
122122
PrefixLen: uint8(a.AddressWithPrefix.PrefixLen),
123-
Addr: []byte(a.AddressWithPrefix.Address),
123+
Addr: a.AddressWithPrefix.Address.AsSlice(),
124124
// TODO(b/68878065): Other fields.
125125
})
126126
}
@@ -145,7 +145,7 @@ func convertAddr(addr inet.InterfaceAddr) (tcpip.ProtocolAddress, error) {
145145
return protocolAddress, linuxerr.EINVAL
146146
}
147147
protocol = ipv4.ProtocolNumber
148-
address = tcpip.Address(addr.Addr)
148+
address = tcpip.AddrFrom4Slice(addr.Addr)
149149
case linux.AF_INET6:
150150
if len(addr.Addr) != header.IPv6AddressSize {
151151
return protocolAddress, linuxerr.EINVAL
@@ -154,7 +154,7 @@ func convertAddr(addr inet.InterfaceAddr) (tcpip.ProtocolAddress, error) {
154154
return protocolAddress, linuxerr.EINVAL
155155
}
156156
protocol = ipv6.ProtocolNumber
157-
address = tcpip.Address(addr.Addr)
157+
address = tcpip.AddrFrom16Slice(addr.Addr)
158158
default:
159159
return protocolAddress, linuxerr.ENOTSUP
160160
}
@@ -185,7 +185,7 @@ func (s *Stack) AddInterfaceAddr(idx int32, addr inet.InterfaceAddr) error {
185185
// Add route for local network if it doesn't exist already.
186186
localRoute := tcpip.Route{
187187
Destination: protocolAddress.AddressWithPrefix.Subnet(),
188-
Gateway: "", // No gateway for local network.
188+
Gateway: tcpip.Address{}, // No gateway for local network.
189189
NIC: nicID,
190190
}
191191

@@ -217,7 +217,7 @@ func (s *Stack) RemoveInterfaceAddr(idx int32, addr inet.InterfaceAddr) error {
217217
// Remove the corresponding local network route if it exists.
218218
localRoute := tcpip.Route{
219219
Destination: protocolAddress.AddressWithPrefix.Subnet(),
220-
Gateway: "", // No gateway for local network.
220+
Gateway: tcpip.Address{}, // No gateway for local network.
221221
NIC: nicID,
222222
}
223223
s.Stack.RemoveRoutes(func(rt tcpip.Route) bool {
@@ -430,10 +430,10 @@ func (s *Stack) RouteTable() []inet.Route {
430430

431431
for _, rt := range s.Stack.GetRouteTable() {
432432
var family uint8
433-
switch len(rt.Destination.ID()) {
434-
case header.IPv4AddressSize:
433+
switch rt.Destination.ID().BitLen() {
434+
case header.IPv4AddressSizeBits:
435435
family = linux.AF_INET
436-
case header.IPv6AddressSize:
436+
case header.IPv6AddressSizeBits:
437437
family = linux.AF_INET6
438438
default:
439439
log.Warningf("Unknown network protocol in route %+v", rt)
@@ -453,9 +453,9 @@ func (s *Stack) RouteTable() []inet.Route {
453453
Scope: linux.RT_SCOPE_LINK,
454454
Type: linux.RTN_UNICAST,
455455

456-
DstAddr: []byte(rt.Destination.ID()),
456+
DstAddr: rt.Destination.ID().AsSlice(),
457457
OutputInterface: int32(rt.NIC),
458-
GatewayAddr: []byte(rt.Gateway),
458+
GatewayAddr: rt.Gateway.AsSlice(),
459459
})
460460
}
461461

0 commit comments

Comments
 (0)