mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
Add support for a subnet prefix length on interface network addresses
This allows the user code to add a network address with a subnet prefix length. The prefix length value is stored in the network endpoint and provided back to the user in the ProtocolAddress type. PiperOrigin-RevId: 259807693
This commit is contained in:
@@ -75,8 +75,8 @@ func (s *Stack) InterfaceAddrs() map[int32][]inet.InterfaceAddr {
|
||||
|
||||
addrs = append(addrs, inet.InterfaceAddr{
|
||||
Family: family,
|
||||
PrefixLen: uint8(len(a.Address) * 8),
|
||||
Addr: []byte(a.Address),
|
||||
PrefixLen: uint8(a.AddressWithPrefix.PrefixLen),
|
||||
Addr: []byte(a.AddressWithPrefix.Address),
|
||||
// TODO(b/68878065): Other fields.
|
||||
})
|
||||
}
|
||||
|
||||
@@ -46,7 +46,6 @@ const (
|
||||
// endpoint implements stack.NetworkEndpoint.
|
||||
type endpoint struct {
|
||||
nicid tcpip.NICID
|
||||
addr tcpip.Address
|
||||
linkEP stack.LinkEndpoint
|
||||
linkAddrCache stack.LinkAddressCache
|
||||
}
|
||||
@@ -73,6 +72,10 @@ func (e *endpoint) ID() *stack.NetworkEndpointID {
|
||||
return &stack.NetworkEndpointID{ProtocolAddress}
|
||||
}
|
||||
|
||||
func (e *endpoint) PrefixLen() int {
|
||||
return 0
|
||||
}
|
||||
|
||||
func (e *endpoint) MaxHeaderLength() uint16 {
|
||||
return e.linkEP.MaxHeaderLength() + header.ARPSize
|
||||
}
|
||||
@@ -122,19 +125,19 @@ type protocol struct {
|
||||
|
||||
func (p *protocol) Number() tcpip.NetworkProtocolNumber { return ProtocolNumber }
|
||||
func (p *protocol) MinimumPacketSize() int { return header.ARPSize }
|
||||
func (p *protocol) DefaultPrefixLen() int { return 0 }
|
||||
|
||||
func (*protocol) ParseAddresses(v buffer.View) (src, dst tcpip.Address) {
|
||||
h := header.ARP(v)
|
||||
return tcpip.Address(h.ProtocolAddressSender()), ProtocolAddress
|
||||
}
|
||||
|
||||
func (p *protocol) NewEndpoint(nicid tcpip.NICID, addr tcpip.Address, linkAddrCache stack.LinkAddressCache, dispatcher stack.TransportDispatcher, sender stack.LinkEndpoint) (stack.NetworkEndpoint, *tcpip.Error) {
|
||||
if addr != ProtocolAddress {
|
||||
func (p *protocol) NewEndpoint(nicid tcpip.NICID, addrWithPrefix tcpip.AddressWithPrefix, linkAddrCache stack.LinkAddressCache, dispatcher stack.TransportDispatcher, sender stack.LinkEndpoint) (stack.NetworkEndpoint, *tcpip.Error) {
|
||||
if addrWithPrefix.Address != ProtocolAddress {
|
||||
return nil, tcpip.ErrBadLocalAddress
|
||||
}
|
||||
return &endpoint{
|
||||
nicid: nicid,
|
||||
addr: addr,
|
||||
linkEP: sender,
|
||||
linkAddrCache: linkAddrCache,
|
||||
}, nil
|
||||
|
||||
@@ -29,16 +29,18 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
localIpv4Addr = "\x0a\x00\x00\x01"
|
||||
remoteIpv4Addr = "\x0a\x00\x00\x02"
|
||||
ipv4SubnetAddr = "\x0a\x00\x00\x00"
|
||||
ipv4SubnetMask = "\xff\xff\xff\x00"
|
||||
ipv4Gateway = "\x0a\x00\x00\x03"
|
||||
localIpv6Addr = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"
|
||||
remoteIpv6Addr = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"
|
||||
ipv6SubnetAddr = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
ipv6SubnetMask = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00"
|
||||
ipv6Gateway = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03"
|
||||
localIpv4Addr = "\x0a\x00\x00\x01"
|
||||
localIpv4PrefixLen = 24
|
||||
remoteIpv4Addr = "\x0a\x00\x00\x02"
|
||||
ipv4SubnetAddr = "\x0a\x00\x00\x00"
|
||||
ipv4SubnetMask = "\xff\xff\xff\x00"
|
||||
ipv4Gateway = "\x0a\x00\x00\x03"
|
||||
localIpv6Addr = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"
|
||||
localIpv6PrefixLen = 120
|
||||
remoteIpv6Addr = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"
|
||||
ipv6SubnetAddr = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||
ipv6SubnetMask = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x00"
|
||||
ipv6Gateway = "\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03"
|
||||
)
|
||||
|
||||
// testObject implements two interfaces: LinkEndpoint and TransportDispatcher.
|
||||
@@ -197,7 +199,7 @@ func buildIPv6Route(local, remote tcpip.Address) (stack.Route, *tcpip.Error) {
|
||||
func TestIPv4Send(t *testing.T) {
|
||||
o := testObject{t: t, v4: true}
|
||||
proto := ipv4.NewProtocol()
|
||||
ep, err := proto.NewEndpoint(1, localIpv4Addr, nil, nil, &o)
|
||||
ep, err := proto.NewEndpoint(1, tcpip.AddressWithPrefix{localIpv4Addr, localIpv4PrefixLen}, nil, nil, &o)
|
||||
if err != nil {
|
||||
t.Fatalf("NewEndpoint failed: %v", err)
|
||||
}
|
||||
@@ -229,7 +231,7 @@ func TestIPv4Send(t *testing.T) {
|
||||
func TestIPv4Receive(t *testing.T) {
|
||||
o := testObject{t: t, v4: true}
|
||||
proto := ipv4.NewProtocol()
|
||||
ep, err := proto.NewEndpoint(1, localIpv4Addr, nil, &o, nil)
|
||||
ep, err := proto.NewEndpoint(1, tcpip.AddressWithPrefix{localIpv4Addr, localIpv4PrefixLen}, nil, &o, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("NewEndpoint failed: %v", err)
|
||||
}
|
||||
@@ -295,7 +297,7 @@ func TestIPv4ReceiveControl(t *testing.T) {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
o := testObject{t: t}
|
||||
proto := ipv4.NewProtocol()
|
||||
ep, err := proto.NewEndpoint(1, localIpv4Addr, nil, &o, nil)
|
||||
ep, err := proto.NewEndpoint(1, tcpip.AddressWithPrefix{localIpv4Addr, localIpv4PrefixLen}, nil, &o, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("NewEndpoint failed: %v", err)
|
||||
}
|
||||
@@ -359,7 +361,7 @@ func TestIPv4ReceiveControl(t *testing.T) {
|
||||
func TestIPv4FragmentationReceive(t *testing.T) {
|
||||
o := testObject{t: t, v4: true}
|
||||
proto := ipv4.NewProtocol()
|
||||
ep, err := proto.NewEndpoint(1, localIpv4Addr, nil, &o, nil)
|
||||
ep, err := proto.NewEndpoint(1, tcpip.AddressWithPrefix{localIpv4Addr, localIpv4PrefixLen}, nil, &o, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("NewEndpoint failed: %v", err)
|
||||
}
|
||||
@@ -426,7 +428,7 @@ func TestIPv4FragmentationReceive(t *testing.T) {
|
||||
func TestIPv6Send(t *testing.T) {
|
||||
o := testObject{t: t}
|
||||
proto := ipv6.NewProtocol()
|
||||
ep, err := proto.NewEndpoint(1, localIpv6Addr, nil, nil, &o)
|
||||
ep, err := proto.NewEndpoint(1, tcpip.AddressWithPrefix{localIpv6Addr, localIpv6PrefixLen}, nil, nil, &o)
|
||||
if err != nil {
|
||||
t.Fatalf("NewEndpoint failed: %v", err)
|
||||
}
|
||||
@@ -458,7 +460,7 @@ func TestIPv6Send(t *testing.T) {
|
||||
func TestIPv6Receive(t *testing.T) {
|
||||
o := testObject{t: t}
|
||||
proto := ipv6.NewProtocol()
|
||||
ep, err := proto.NewEndpoint(1, localIpv6Addr, nil, &o, nil)
|
||||
ep, err := proto.NewEndpoint(1, tcpip.AddressWithPrefix{localIpv6Addr, localIpv6PrefixLen}, nil, &o, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("NewEndpoint failed: %v", err)
|
||||
}
|
||||
@@ -532,7 +534,7 @@ func TestIPv6ReceiveControl(t *testing.T) {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
o := testObject{t: t}
|
||||
proto := ipv6.NewProtocol()
|
||||
ep, err := proto.NewEndpoint(1, localIpv6Addr, nil, &o, nil)
|
||||
ep, err := proto.NewEndpoint(1, tcpip.AddressWithPrefix{localIpv6Addr, localIpv6PrefixLen}, nil, &o, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("NewEndpoint failed: %v", err)
|
||||
}
|
||||
|
||||
@@ -49,16 +49,18 @@ const (
|
||||
type endpoint struct {
|
||||
nicid tcpip.NICID
|
||||
id stack.NetworkEndpointID
|
||||
prefixLen int
|
||||
linkEP stack.LinkEndpoint
|
||||
dispatcher stack.TransportDispatcher
|
||||
fragmentation *fragmentation.Fragmentation
|
||||
}
|
||||
|
||||
// NewEndpoint creates a new ipv4 endpoint.
|
||||
func (p *protocol) NewEndpoint(nicid tcpip.NICID, addr tcpip.Address, linkAddrCache stack.LinkAddressCache, dispatcher stack.TransportDispatcher, linkEP stack.LinkEndpoint) (stack.NetworkEndpoint, *tcpip.Error) {
|
||||
func (p *protocol) NewEndpoint(nicid tcpip.NICID, addrWithPrefix tcpip.AddressWithPrefix, linkAddrCache stack.LinkAddressCache, dispatcher stack.TransportDispatcher, linkEP stack.LinkEndpoint) (stack.NetworkEndpoint, *tcpip.Error) {
|
||||
e := &endpoint{
|
||||
nicid: nicid,
|
||||
id: stack.NetworkEndpointID{LocalAddress: addr},
|
||||
id: stack.NetworkEndpointID{LocalAddress: addrWithPrefix.Address},
|
||||
prefixLen: addrWithPrefix.PrefixLen,
|
||||
linkEP: linkEP,
|
||||
dispatcher: dispatcher,
|
||||
fragmentation: fragmentation.NewFragmentation(fragmentation.HighFragThreshold, fragmentation.LowFragThreshold, fragmentation.DefaultReassembleTimeout),
|
||||
@@ -93,6 +95,11 @@ func (e *endpoint) ID() *stack.NetworkEndpointID {
|
||||
return &e.id
|
||||
}
|
||||
|
||||
// PrefixLen returns the ipv4 endpoint subnet prefix length in bits.
|
||||
func (e *endpoint) PrefixLen() int {
|
||||
return e.prefixLen
|
||||
}
|
||||
|
||||
// MaxHeaderLength returns the maximum length needed by ipv4 headers (and
|
||||
// underlying protocols).
|
||||
func (e *endpoint) MaxHeaderLength() uint16 {
|
||||
@@ -338,6 +345,11 @@ func (p *protocol) MinimumPacketSize() int {
|
||||
return header.IPv4MinimumSize
|
||||
}
|
||||
|
||||
// DefaultPrefixLen returns the IPv4 default prefix length.
|
||||
func (p *protocol) DefaultPrefixLen() int {
|
||||
return header.IPv4AddressSize * 8
|
||||
}
|
||||
|
||||
// ParseAddresses implements NetworkProtocol.ParseAddresses.
|
||||
func (*protocol) ParseAddresses(v buffer.View) (src, dst tcpip.Address) {
|
||||
h := header.IPv4(v)
|
||||
|
||||
@@ -99,7 +99,11 @@ func TestICMPCounts(t *testing.T) {
|
||||
}},
|
||||
)
|
||||
|
||||
ep, err := s.NetworkProtocolInstance(ProtocolNumber).NewEndpoint(0, lladdr1, &stubLinkAddressCache{}, &stubDispatcher{}, nil)
|
||||
netProto := s.NetworkProtocolInstance(ProtocolNumber)
|
||||
if netProto == nil {
|
||||
t.Fatalf("cannot find protocol instance for network protocol %d", ProtocolNumber)
|
||||
}
|
||||
ep, err := netProto.NewEndpoint(0, tcpip.AddressWithPrefix{lladdr1, netProto.DefaultPrefixLen()}, &stubLinkAddressCache{}, &stubDispatcher{}, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("NewEndpoint(_) = _, %s, want = _, nil", err)
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ const (
|
||||
type endpoint struct {
|
||||
nicid tcpip.NICID
|
||||
id stack.NetworkEndpointID
|
||||
prefixLen int
|
||||
linkEP stack.LinkEndpoint
|
||||
linkAddrCache stack.LinkAddressCache
|
||||
dispatcher stack.TransportDispatcher
|
||||
@@ -72,6 +73,11 @@ func (e *endpoint) ID() *stack.NetworkEndpointID {
|
||||
return &e.id
|
||||
}
|
||||
|
||||
// PrefixLen returns the ipv6 endpoint subnet prefix length in bits.
|
||||
func (e *endpoint) PrefixLen() int {
|
||||
return e.prefixLen
|
||||
}
|
||||
|
||||
// Capabilities implements stack.NetworkEndpoint.Capabilities.
|
||||
func (e *endpoint) Capabilities() stack.LinkEndpointCapabilities {
|
||||
return e.linkEP.Capabilities()
|
||||
@@ -172,6 +178,11 @@ func (p *protocol) MinimumPacketSize() int {
|
||||
return header.IPv6MinimumSize
|
||||
}
|
||||
|
||||
// DefaultPrefixLen returns the IPv6 default prefix length.
|
||||
func (p *protocol) DefaultPrefixLen() int {
|
||||
return header.IPv6AddressSize * 8
|
||||
}
|
||||
|
||||
// ParseAddresses implements NetworkProtocol.ParseAddresses.
|
||||
func (*protocol) ParseAddresses(v buffer.View) (src, dst tcpip.Address) {
|
||||
h := header.IPv6(v)
|
||||
@@ -179,10 +190,11 @@ func (*protocol) ParseAddresses(v buffer.View) (src, dst tcpip.Address) {
|
||||
}
|
||||
|
||||
// NewEndpoint creates a new ipv6 endpoint.
|
||||
func (p *protocol) NewEndpoint(nicid tcpip.NICID, addr tcpip.Address, linkAddrCache stack.LinkAddressCache, dispatcher stack.TransportDispatcher, linkEP stack.LinkEndpoint) (stack.NetworkEndpoint, *tcpip.Error) {
|
||||
func (p *protocol) NewEndpoint(nicid tcpip.NICID, addrWithPrefix tcpip.AddressWithPrefix, linkAddrCache stack.LinkAddressCache, dispatcher stack.TransportDispatcher, linkEP stack.LinkEndpoint) (stack.NetworkEndpoint, *tcpip.Error) {
|
||||
return &endpoint{
|
||||
nicid: nicid,
|
||||
id: stack.NetworkEndpointID{LocalAddress: addr},
|
||||
id: stack.NetworkEndpointID{LocalAddress: addrWithPrefix.Address},
|
||||
prefixLen: addrWithPrefix.PrefixLen,
|
||||
linkEP: linkEP,
|
||||
linkAddrCache: linkAddrCache,
|
||||
dispatcher: dispatcher,
|
||||
|
||||
+36
-30
@@ -129,7 +129,7 @@ func (n *NIC) setSpoofing(enable bool) {
|
||||
n.mu.Unlock()
|
||||
}
|
||||
|
||||
func (n *NIC) getMainNICAddress(protocol tcpip.NetworkProtocolNumber) (tcpip.Address, tcpip.Subnet, *tcpip.Error) {
|
||||
func (n *NIC) getMainNICAddress(protocol tcpip.NetworkProtocolNumber) (tcpip.AddressWithPrefix, *tcpip.Error) {
|
||||
n.mu.RLock()
|
||||
defer n.mu.RUnlock()
|
||||
|
||||
@@ -148,21 +148,16 @@ func (n *NIC) getMainNICAddress(protocol tcpip.NetworkProtocolNumber) (tcpip.Add
|
||||
}
|
||||
|
||||
if r == nil {
|
||||
return "", tcpip.Subnet{}, tcpip.ErrNoLinkAddress
|
||||
return tcpip.AddressWithPrefix{}, tcpip.ErrNoLinkAddress
|
||||
}
|
||||
|
||||
address := r.ep.ID().LocalAddress
|
||||
addressWithPrefix := tcpip.AddressWithPrefix{
|
||||
Address: r.ep.ID().LocalAddress,
|
||||
PrefixLen: r.ep.PrefixLen(),
|
||||
}
|
||||
r.decRef()
|
||||
|
||||
// Find the least-constrained matching subnet for the address, if one
|
||||
// exists, and return it.
|
||||
var subnet tcpip.Subnet
|
||||
for _, s := range n.subnets {
|
||||
if s.Contains(address) && !subnet.Contains(s.ID()) {
|
||||
subnet = s
|
||||
}
|
||||
}
|
||||
return address, subnet, nil
|
||||
return addressWithPrefix, nil
|
||||
}
|
||||
|
||||
// primaryEndpoint returns the primary endpoint of n for the given network
|
||||
@@ -213,23 +208,26 @@ func (n *NIC) findEndpoint(protocol tcpip.NetworkProtocolNumber, address tcpip.A
|
||||
n.mu.Lock()
|
||||
ref = n.endpoints[id]
|
||||
if ref == nil || !ref.tryIncRef() {
|
||||
ref, _ = n.addAddressLocked(protocol, address, peb, true)
|
||||
if ref != nil {
|
||||
ref.holdsInsertRef = false
|
||||
if netProto, ok := n.stack.networkProtocols[protocol]; ok {
|
||||
addrWithPrefix := tcpip.AddressWithPrefix{address, netProto.DefaultPrefixLen()}
|
||||
ref, _ = n.addAddressLocked(protocol, addrWithPrefix, peb, true)
|
||||
if ref != nil {
|
||||
ref.holdsInsertRef = false
|
||||
}
|
||||
}
|
||||
}
|
||||
n.mu.Unlock()
|
||||
return ref
|
||||
}
|
||||
|
||||
func (n *NIC) addAddressLocked(protocol tcpip.NetworkProtocolNumber, addr tcpip.Address, peb PrimaryEndpointBehavior, replace bool) (*referencedNetworkEndpoint, *tcpip.Error) {
|
||||
func (n *NIC) addAddressLocked(protocol tcpip.NetworkProtocolNumber, addrWithPrefix tcpip.AddressWithPrefix, peb PrimaryEndpointBehavior, replace bool) (*referencedNetworkEndpoint, *tcpip.Error) {
|
||||
netProto, ok := n.stack.networkProtocols[protocol]
|
||||
if !ok {
|
||||
return nil, tcpip.ErrUnknownProtocol
|
||||
}
|
||||
|
||||
// Create the new network endpoint.
|
||||
ep, err := netProto.NewEndpoint(n.id, addr, n.stack, n, n.linkEP)
|
||||
ep, err := netProto.NewEndpoint(n.id, addrWithPrefix, n.stack, n, n.linkEP)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -278,16 +276,10 @@ func (n *NIC) addAddressLocked(protocol tcpip.NetworkProtocolNumber, addr tcpip.
|
||||
|
||||
// AddAddress adds a new address to n, so that it starts accepting packets
|
||||
// targeted at the given address (and network protocol).
|
||||
func (n *NIC) AddAddress(protocol tcpip.NetworkProtocolNumber, addr tcpip.Address) *tcpip.Error {
|
||||
return n.AddAddressWithOptions(protocol, addr, CanBePrimaryEndpoint)
|
||||
}
|
||||
|
||||
// AddAddressWithOptions is the same as AddAddress, but allows you to specify
|
||||
// whether the new endpoint can be primary or not.
|
||||
func (n *NIC) AddAddressWithOptions(protocol tcpip.NetworkProtocolNumber, addr tcpip.Address, peb PrimaryEndpointBehavior) *tcpip.Error {
|
||||
func (n *NIC) AddAddress(protocol tcpip.NetworkProtocolNumber, addrWithPrefix tcpip.AddressWithPrefix, peb PrimaryEndpointBehavior) *tcpip.Error {
|
||||
// Add the endpoint.
|
||||
n.mu.Lock()
|
||||
_, err := n.addAddressLocked(protocol, addr, peb, false)
|
||||
_, err := n.addAddressLocked(protocol, addrWithPrefix, peb, false)
|
||||
n.mu.Unlock()
|
||||
|
||||
return err
|
||||
@@ -298,10 +290,13 @@ func (n *NIC) Addresses() []tcpip.ProtocolAddress {
|
||||
n.mu.RLock()
|
||||
defer n.mu.RUnlock()
|
||||
addrs := make([]tcpip.ProtocolAddress, 0, len(n.endpoints))
|
||||
for nid, ep := range n.endpoints {
|
||||
for nid, ref := range n.endpoints {
|
||||
addrs = append(addrs, tcpip.ProtocolAddress{
|
||||
Protocol: ep.protocol,
|
||||
Address: nid.LocalAddress,
|
||||
Protocol: ref.protocol,
|
||||
AddressWithPrefix: tcpip.AddressWithPrefix{
|
||||
Address: nid.LocalAddress,
|
||||
PrefixLen: ref.ep.PrefixLen(),
|
||||
},
|
||||
})
|
||||
}
|
||||
return addrs
|
||||
@@ -415,7 +410,12 @@ func (n *NIC) joinGroup(protocol tcpip.NetworkProtocolNumber, addr tcpip.Address
|
||||
id := NetworkEndpointID{addr}
|
||||
joins := n.mcastJoins[id]
|
||||
if joins == 0 {
|
||||
if _, err := n.addAddressLocked(protocol, addr, NeverPrimaryEndpoint, false); err != nil {
|
||||
netProto, ok := n.stack.networkProtocols[protocol]
|
||||
if !ok {
|
||||
return tcpip.ErrUnknownProtocol
|
||||
}
|
||||
addrWithPrefix := tcpip.AddressWithPrefix{addr, netProto.DefaultPrefixLen()}
|
||||
if _, err := n.addAddressLocked(protocol, addrWithPrefix, NeverPrimaryEndpoint, false); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -572,7 +572,13 @@ func (n *NIC) getRef(protocol tcpip.NetworkProtocolNumber, dst tcpip.Address) *r
|
||||
n.mu.Unlock()
|
||||
return ref
|
||||
}
|
||||
ref, err := n.addAddressLocked(protocol, dst, CanBePrimaryEndpoint, true)
|
||||
netProto, ok := n.stack.networkProtocols[protocol]
|
||||
if !ok {
|
||||
n.mu.Unlock()
|
||||
return nil
|
||||
}
|
||||
addrWithPrefix := tcpip.AddressWithPrefix{dst, netProto.DefaultPrefixLen()}
|
||||
ref, err := n.addAddressLocked(protocol, addrWithPrefix, CanBePrimaryEndpoint, true)
|
||||
n.mu.Unlock()
|
||||
if err == nil {
|
||||
ref.holdsInsertRef = false
|
||||
|
||||
@@ -181,6 +181,9 @@ type NetworkEndpoint interface {
|
||||
// ID returns the network protocol endpoint ID.
|
||||
ID() *NetworkEndpointID
|
||||
|
||||
// PrefixLen returns the network endpoint's subnet prefix length in bits.
|
||||
PrefixLen() int
|
||||
|
||||
// NICID returns the id of the NIC this endpoint belongs to.
|
||||
NICID() tcpip.NICID
|
||||
|
||||
@@ -203,12 +206,15 @@ type NetworkProtocol interface {
|
||||
// than this targeted at this protocol.
|
||||
MinimumPacketSize() int
|
||||
|
||||
// DefaultPrefixLen returns the protocol's default prefix length.
|
||||
DefaultPrefixLen() int
|
||||
|
||||
// ParsePorts returns the source and destination addresses stored in a
|
||||
// packet of this protocol.
|
||||
ParseAddresses(v buffer.View) (src, dst tcpip.Address)
|
||||
|
||||
// NewEndpoint creates a new endpoint of this protocol.
|
||||
NewEndpoint(nicid tcpip.NICID, addr tcpip.Address, linkAddrCache LinkAddressCache, dispatcher TransportDispatcher, sender LinkEndpoint) (NetworkEndpoint, *tcpip.Error)
|
||||
NewEndpoint(nicid tcpip.NICID, addrWithPrefix tcpip.AddressWithPrefix, linkAddrCache LinkAddressCache, dispatcher TransportDispatcher, sender LinkEndpoint) (NetworkEndpoint, *tcpip.Error)
|
||||
|
||||
// SetOption allows enabling/disabling protocol specific features.
|
||||
// SetOption returns an error if the option is not supported or the
|
||||
|
||||
@@ -751,9 +751,26 @@ func (s *Stack) AddAddress(id tcpip.NICID, protocol tcpip.NetworkProtocolNumber,
|
||||
return s.AddAddressWithOptions(id, protocol, addr, CanBePrimaryEndpoint)
|
||||
}
|
||||
|
||||
// AddAddressWithPrefix adds a new network-layer address/prefixLen to the
|
||||
// specified NIC.
|
||||
func (s *Stack) AddAddressWithPrefix(id tcpip.NICID, protocol tcpip.NetworkProtocolNumber, addrWithPrefix tcpip.AddressWithPrefix) *tcpip.Error {
|
||||
return s.AddAddressWithPrefixAndOptions(id, protocol, addrWithPrefix, CanBePrimaryEndpoint)
|
||||
}
|
||||
|
||||
// AddAddressWithOptions is the same as AddAddress, but allows you to specify
|
||||
// whether the new endpoint can be primary or not.
|
||||
func (s *Stack) AddAddressWithOptions(id tcpip.NICID, protocol tcpip.NetworkProtocolNumber, addr tcpip.Address, peb PrimaryEndpointBehavior) *tcpip.Error {
|
||||
netProto, ok := s.networkProtocols[protocol]
|
||||
if !ok {
|
||||
return tcpip.ErrUnknownProtocol
|
||||
}
|
||||
addrWithPrefix := tcpip.AddressWithPrefix{addr, netProto.DefaultPrefixLen()}
|
||||
return s.AddAddressWithPrefixAndOptions(id, protocol, addrWithPrefix, peb)
|
||||
}
|
||||
|
||||
// AddAddressWithPrefixAndOptions is the same as AddAddressWithPrefixLen,
|
||||
// but allows you to specify whether the new endpoint can be primary or not.
|
||||
func (s *Stack) AddAddressWithPrefixAndOptions(id tcpip.NICID, protocol tcpip.NetworkProtocolNumber, addrWithPrefix tcpip.AddressWithPrefix, peb PrimaryEndpointBehavior) *tcpip.Error {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
|
||||
@@ -762,7 +779,7 @@ func (s *Stack) AddAddressWithOptions(id tcpip.NICID, protocol tcpip.NetworkProt
|
||||
return tcpip.ErrUnknownNICID
|
||||
}
|
||||
|
||||
return nic.AddAddressWithOptions(protocol, addr, peb)
|
||||
return nic.AddAddress(protocol, addrWithPrefix, peb)
|
||||
}
|
||||
|
||||
// AddSubnet adds a subnet range to the specified NIC.
|
||||
@@ -821,7 +838,7 @@ func (s *Stack) RemoveAddress(id tcpip.NICID, addr tcpip.Address) *tcpip.Error {
|
||||
// contains it) for the given NIC and protocol. Returns an arbitrary endpoint's
|
||||
// address if no primary addresses exist. Returns an error if the NIC doesn't
|
||||
// exist or has no endpoints.
|
||||
func (s *Stack) GetMainNICAddress(id tcpip.NICID, protocol tcpip.NetworkProtocolNumber) (tcpip.Address, tcpip.Subnet, *tcpip.Error) {
|
||||
func (s *Stack) GetMainNICAddress(id tcpip.NICID, protocol tcpip.NetworkProtocolNumber) (tcpip.AddressWithPrefix, *tcpip.Error) {
|
||||
s.mu.RLock()
|
||||
defer s.mu.RUnlock()
|
||||
|
||||
@@ -829,7 +846,7 @@ func (s *Stack) GetMainNICAddress(id tcpip.NICID, protocol tcpip.NetworkProtocol
|
||||
return nic.getMainNICAddress(protocol)
|
||||
}
|
||||
|
||||
return "", tcpip.Subnet{}, tcpip.ErrUnknownNICID
|
||||
return tcpip.AddressWithPrefix{}, tcpip.ErrUnknownNICID
|
||||
}
|
||||
|
||||
func (s *Stack) getRefEP(nic *NIC, localAddr tcpip.Address, netProto tcpip.NetworkProtocolNumber) (ref *referencedNetworkEndpoint) {
|
||||
|
||||
+259
-125
File diff suppressed because it is too large
Load Diff
+11
-2
@@ -1059,14 +1059,23 @@ func ParseMACAddress(s string) (LinkAddress, error) {
|
||||
return LinkAddress(addr), nil
|
||||
}
|
||||
|
||||
// AddressWithPrefix is an address with its subnet prefix length.
|
||||
type AddressWithPrefix struct {
|
||||
// Address is a network address.
|
||||
Address Address
|
||||
|
||||
// PrefixLen is the subnet prefix length.
|
||||
PrefixLen int
|
||||
}
|
||||
|
||||
// ProtocolAddress is an address and the network protocol it is associated
|
||||
// with.
|
||||
type ProtocolAddress struct {
|
||||
// Protocol is the protocol of the address.
|
||||
Protocol NetworkProtocolNumber
|
||||
|
||||
// Address is a network address.
|
||||
Address Address
|
||||
// AddressWithPrefix is a network address with its subnet prefix length.
|
||||
AddressWithPrefix AddressWithPrefix
|
||||
}
|
||||
|
||||
// danglingEndpointsMu protects access to danglingEndpoints.
|
||||
|
||||
@@ -967,14 +967,14 @@ func TestTTL(t *testing.T) {
|
||||
multicast = false
|
||||
switch variant {
|
||||
case "v4", "mapped":
|
||||
ep, err := ipv4.NewProtocol().NewEndpoint(0, "", nil, nil, nil)
|
||||
ep, err := ipv4.NewProtocol().NewEndpoint(0, tcpip.AddressWithPrefix{}, nil, nil, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
wantTTL = ep.DefaultTTL()
|
||||
ep.Close()
|
||||
case "v6":
|
||||
ep, err := ipv6.NewProtocol().NewEndpoint(0, "", nil, nil, nil)
|
||||
ep, err := ipv6.NewProtocol().NewEndpoint(0, tcpip.AddressWithPrefix{}, nil, nil, nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user