github.com/FlowerWrong/netstack@v0.0.0-20191009141956-e5848263af28/tcpip/stack/nic.go (about)

     1  // Copyright 2018 The gVisor Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package stack
    16  
    17  import (
    18  	"strings"
    19  	"sync"
    20  	"sync/atomic"
    21  
    22  	"github.com/FlowerWrong/netstack/ilist"
    23  	"github.com/FlowerWrong/netstack/tcpip"
    24  	"github.com/FlowerWrong/netstack/tcpip/buffer"
    25  	"github.com/FlowerWrong/netstack/tcpip/header"
    26  )
    27  
    28  // NIC represents a "network interface card" to which the networking stack is
    29  // attached.
    30  type NIC struct {
    31  	stack    *Stack
    32  	id       tcpip.NICID
    33  	name     string
    34  	linkEP   LinkEndpoint
    35  	loopback bool
    36  
    37  	mu            sync.RWMutex
    38  	spoofing      bool
    39  	promiscuous   bool
    40  	primary       map[tcpip.NetworkProtocolNumber]*ilist.List
    41  	endpoints     map[NetworkEndpointID]*referencedNetworkEndpoint
    42  	addressRanges []tcpip.Subnet
    43  	mcastJoins    map[NetworkEndpointID]int32
    44  
    45  	stats NICStats
    46  }
    47  
    48  // NICStats includes transmitted and received stats.
    49  type NICStats struct {
    50  	Tx DirectionStats
    51  	Rx DirectionStats
    52  }
    53  
    54  // DirectionStats includes packet and byte counts.
    55  type DirectionStats struct {
    56  	Packets *tcpip.StatCounter
    57  	Bytes   *tcpip.StatCounter
    58  }
    59  
    60  // PrimaryEndpointBehavior is an enumeration of an endpoint's primacy behavior.
    61  type PrimaryEndpointBehavior int
    62  
    63  const (
    64  	// CanBePrimaryEndpoint indicates the endpoint can be used as a primary
    65  	// endpoint for new connections with no local address. This is the
    66  	// default when calling NIC.AddAddress.
    67  	CanBePrimaryEndpoint PrimaryEndpointBehavior = iota
    68  
    69  	// FirstPrimaryEndpoint indicates the endpoint should be the first
    70  	// primary endpoint considered. If there are multiple endpoints with
    71  	// this behavior, the most recently-added one will be first.
    72  	FirstPrimaryEndpoint
    73  
    74  	// NeverPrimaryEndpoint indicates the endpoint should never be a
    75  	// primary endpoint.
    76  	NeverPrimaryEndpoint
    77  )
    78  
    79  func newNIC(stack *Stack, id tcpip.NICID, name string, ep LinkEndpoint, loopback bool) *NIC {
    80  	return &NIC{
    81  		stack:      stack,
    82  		id:         id,
    83  		name:       name,
    84  		linkEP:     ep,
    85  		loopback:   loopback,
    86  		primary:    make(map[tcpip.NetworkProtocolNumber]*ilist.List),
    87  		endpoints:  make(map[NetworkEndpointID]*referencedNetworkEndpoint),
    88  		mcastJoins: make(map[NetworkEndpointID]int32),
    89  		stats: NICStats{
    90  			Tx: DirectionStats{
    91  				Packets: &tcpip.StatCounter{},
    92  				Bytes:   &tcpip.StatCounter{},
    93  			},
    94  			Rx: DirectionStats{
    95  				Packets: &tcpip.StatCounter{},
    96  				Bytes:   &tcpip.StatCounter{},
    97  			},
    98  		},
    99  	}
   100  }
   101  
   102  // enable enables the NIC. enable will attach the link to its LinkEndpoint and
   103  // join the IPv6 All-Nodes Multicast address (ff02::1).
   104  func (n *NIC) enable() *tcpip.Error {
   105  	n.attachLinkEndpoint()
   106  
   107  	// Create an endpoint to receive broadcast packets on this interface.
   108  	if _, ok := n.stack.networkProtocols[header.IPv4ProtocolNumber]; ok {
   109  		if err := n.AddAddress(tcpip.ProtocolAddress{
   110  			Protocol:          header.IPv4ProtocolNumber,
   111  			AddressWithPrefix: tcpip.AddressWithPrefix{header.IPv4Broadcast, 8 * header.IPv4AddressSize},
   112  		}, NeverPrimaryEndpoint); err != nil {
   113  			return err
   114  		}
   115  	}
   116  
   117  	// Join the IPv6 All-Nodes Multicast group if the stack is configured to
   118  	// use IPv6. This is required to ensure that this node properly receives
   119  	// and responds to the various NDP messages that are destined to the
   120  	// all-nodes multicast address. An example is the Neighbor Advertisement
   121  	// when we perform Duplicate Address Detection, or Router Advertisement
   122  	// when we do Router Discovery. See RFC 4862, section 5.4.2 and RFC 4861
   123  	// section 4.2 for more information.
   124  	if _, ok := n.stack.networkProtocols[header.IPv6ProtocolNumber]; ok {
   125  		return n.joinGroup(header.IPv6ProtocolNumber, header.IPv6AllNodesMulticastAddress)
   126  	}
   127  
   128  	return nil
   129  }
   130  
   131  // attachLinkEndpoint attaches the NIC to the endpoint, which will enable it
   132  // to start delivering packets.
   133  func (n *NIC) attachLinkEndpoint() {
   134  	n.linkEP.Attach(n)
   135  }
   136  
   137  // setPromiscuousMode enables or disables promiscuous mode.
   138  func (n *NIC) setPromiscuousMode(enable bool) {
   139  	n.mu.Lock()
   140  	n.promiscuous = enable
   141  	n.mu.Unlock()
   142  }
   143  
   144  func (n *NIC) isPromiscuousMode() bool {
   145  	n.mu.RLock()
   146  	rv := n.promiscuous
   147  	n.mu.RUnlock()
   148  	return rv
   149  }
   150  
   151  // setSpoofing enables or disables address spoofing.
   152  func (n *NIC) setSpoofing(enable bool) {
   153  	n.mu.Lock()
   154  	n.spoofing = enable
   155  	n.mu.Unlock()
   156  }
   157  
   158  // primaryEndpoint returns the primary endpoint of n for the given network
   159  // protocol.
   160  func (n *NIC) primaryEndpoint(protocol tcpip.NetworkProtocolNumber) *referencedNetworkEndpoint {
   161  	n.mu.RLock()
   162  	defer n.mu.RUnlock()
   163  
   164  	list := n.primary[protocol]
   165  	if list == nil {
   166  		return nil
   167  	}
   168  
   169  	for e := list.Front(); e != nil; e = e.Next() {
   170  		r := e.(*referencedNetworkEndpoint)
   171  		// TODO(crawshaw): allow broadcast address when SO_BROADCAST is set.
   172  		switch r.ep.ID().LocalAddress {
   173  		case header.IPv4Broadcast, header.IPv4Any:
   174  			continue
   175  		}
   176  		if r.isValidForOutgoing() && r.tryIncRef() {
   177  			return r
   178  		}
   179  	}
   180  
   181  	return nil
   182  }
   183  
   184  func (n *NIC) getRef(protocol tcpip.NetworkProtocolNumber, dst tcpip.Address) *referencedNetworkEndpoint {
   185  	return n.getRefOrCreateTemp(protocol, dst, CanBePrimaryEndpoint, n.promiscuous)
   186  }
   187  
   188  // findEndpoint finds the endpoint, if any, with the given address.
   189  func (n *NIC) findEndpoint(protocol tcpip.NetworkProtocolNumber, address tcpip.Address, peb PrimaryEndpointBehavior) *referencedNetworkEndpoint {
   190  	return n.getRefOrCreateTemp(protocol, address, peb, n.spoofing)
   191  }
   192  
   193  // getRefEpOrCreateTemp returns the referenced network endpoint for the given
   194  // protocol and address. If none exists a temporary one may be created if
   195  // we are in promiscuous mode or spoofing.
   196  func (n *NIC) getRefOrCreateTemp(protocol tcpip.NetworkProtocolNumber, address tcpip.Address, peb PrimaryEndpointBehavior, spoofingOrPromiscuous bool) *referencedNetworkEndpoint {
   197  	id := NetworkEndpointID{address}
   198  
   199  	n.mu.RLock()
   200  
   201  	if ref, ok := n.endpoints[id]; ok {
   202  		// An endpoint with this id exists, check if it can be used and return it.
   203  		switch ref.getKind() {
   204  		case permanentExpired:
   205  			if !spoofingOrPromiscuous {
   206  				n.mu.RUnlock()
   207  				return nil
   208  			}
   209  			fallthrough
   210  		case temporary, permanent:
   211  			if ref.tryIncRef() {
   212  				n.mu.RUnlock()
   213  				return ref
   214  			}
   215  		}
   216  	}
   217  
   218  	// A usable reference was not found, create a temporary one if requested by
   219  	// the caller or if the address is found in the NIC's subnets.
   220  	createTempEP := spoofingOrPromiscuous
   221  	if !createTempEP {
   222  		for _, sn := range n.addressRanges {
   223  			// Skip the subnet address.
   224  			if address == sn.ID() {
   225  				continue
   226  			}
   227  			// For now just skip the broadcast address, until we support it.
   228  			// FIXME(b/137608825): Add support for sending/receiving directed
   229  			// (subnet) broadcast.
   230  			if address == sn.Broadcast() {
   231  				continue
   232  			}
   233  			if sn.Contains(address) {
   234  				createTempEP = true
   235  				break
   236  			}
   237  		}
   238  	}
   239  
   240  	n.mu.RUnlock()
   241  
   242  	if !createTempEP {
   243  		return nil
   244  	}
   245  
   246  	// Try again with the lock in exclusive mode. If we still can't get the
   247  	// endpoint, create a new "temporary" endpoint. It will only exist while
   248  	// there's a route through it.
   249  	n.mu.Lock()
   250  	if ref, ok := n.endpoints[id]; ok {
   251  		// No need to check the type as we are ok with expired endpoints at this
   252  		// point.
   253  		if ref.tryIncRef() {
   254  			n.mu.Unlock()
   255  			return ref
   256  		}
   257  		// tryIncRef failing means the endpoint is scheduled to be removed once the
   258  		// lock is released. Remove it here so we can create a new (temporary) one.
   259  		// The removal logic waiting for the lock handles this case.
   260  		n.removeEndpointLocked(ref)
   261  	}
   262  
   263  	// Add a new temporary endpoint.
   264  	netProto, ok := n.stack.networkProtocols[protocol]
   265  	if !ok {
   266  		n.mu.Unlock()
   267  		return nil
   268  	}
   269  	ref, _ := n.addAddressLocked(tcpip.ProtocolAddress{
   270  		Protocol: protocol,
   271  		AddressWithPrefix: tcpip.AddressWithPrefix{
   272  			Address:   address,
   273  			PrefixLen: netProto.DefaultPrefixLen(),
   274  		},
   275  	}, peb, temporary)
   276  
   277  	n.mu.Unlock()
   278  	return ref
   279  }
   280  
   281  func (n *NIC) addPermanentAddressLocked(protocolAddress tcpip.ProtocolAddress, peb PrimaryEndpointBehavior) (*referencedNetworkEndpoint, *tcpip.Error) {
   282  	id := NetworkEndpointID{protocolAddress.AddressWithPrefix.Address}
   283  	if ref, ok := n.endpoints[id]; ok {
   284  		switch ref.getKind() {
   285  		case permanent:
   286  			// The NIC already have a permanent endpoint with that address.
   287  			return nil, tcpip.ErrDuplicateAddress
   288  		case permanentExpired, temporary:
   289  			// Promote the endpoint to become permanent.
   290  			if ref.tryIncRef() {
   291  				ref.setKind(permanent)
   292  				return ref, nil
   293  			}
   294  			// tryIncRef failing means the endpoint is scheduled to be removed once
   295  			// the lock is released. Remove it here so we can create a new
   296  			// (permanent) one. The removal logic waiting for the lock handles this
   297  			// case.
   298  			n.removeEndpointLocked(ref)
   299  		}
   300  	}
   301  	return n.addAddressLocked(protocolAddress, peb, permanent)
   302  }
   303  
   304  func (n *NIC) addAddressLocked(protocolAddress tcpip.ProtocolAddress, peb PrimaryEndpointBehavior, kind networkEndpointKind) (*referencedNetworkEndpoint, *tcpip.Error) {
   305  	// TODO(b/141022673): Validate IP address before adding them.
   306  
   307  	// Sanity check.
   308  	id := NetworkEndpointID{protocolAddress.AddressWithPrefix.Address}
   309  	if _, ok := n.endpoints[id]; ok {
   310  		// Endpoint already exists.
   311  		return nil, tcpip.ErrDuplicateAddress
   312  	}
   313  
   314  	netProto, ok := n.stack.networkProtocols[protocolAddress.Protocol]
   315  	if !ok {
   316  		return nil, tcpip.ErrUnknownProtocol
   317  	}
   318  
   319  	// Create the new network endpoint.
   320  	ep, err := netProto.NewEndpoint(n.id, protocolAddress.AddressWithPrefix, n.stack, n, n.linkEP)
   321  	if err != nil {
   322  		return nil, err
   323  	}
   324  	ref := &referencedNetworkEndpoint{
   325  		refs:     1,
   326  		ep:       ep,
   327  		nic:      n,
   328  		protocol: protocolAddress.Protocol,
   329  		kind:     kind,
   330  	}
   331  
   332  	// Set up cache if link address resolution exists for this protocol.
   333  	if n.linkEP.Capabilities()&CapabilityResolutionRequired != 0 {
   334  		if _, ok := n.stack.linkAddrResolvers[protocolAddress.Protocol]; ok {
   335  			ref.linkCache = n.stack
   336  		}
   337  	}
   338  
   339  	// If we are adding an IPv6 unicast address, join the solicited-node
   340  	// multicast address.
   341  	if protocolAddress.Protocol == header.IPv6ProtocolNumber && header.IsV6UnicastAddress(protocolAddress.AddressWithPrefix.Address) {
   342  		snmc := header.SolicitedNodeAddr(protocolAddress.AddressWithPrefix.Address)
   343  		if err := n.joinGroupLocked(protocolAddress.Protocol, snmc); err != nil {
   344  			return nil, err
   345  		}
   346  	}
   347  
   348  	n.endpoints[id] = ref
   349  
   350  	l, ok := n.primary[protocolAddress.Protocol]
   351  	if !ok {
   352  		l = &ilist.List{}
   353  		n.primary[protocolAddress.Protocol] = l
   354  	}
   355  
   356  	switch peb {
   357  	case CanBePrimaryEndpoint:
   358  		l.PushBack(ref)
   359  	case FirstPrimaryEndpoint:
   360  		l.PushFront(ref)
   361  	}
   362  
   363  	return ref, nil
   364  }
   365  
   366  // AddAddress adds a new address to n, so that it starts accepting packets
   367  // targeted at the given address (and network protocol).
   368  func (n *NIC) AddAddress(protocolAddress tcpip.ProtocolAddress, peb PrimaryEndpointBehavior) *tcpip.Error {
   369  	// Add the endpoint.
   370  	n.mu.Lock()
   371  	_, err := n.addPermanentAddressLocked(protocolAddress, peb)
   372  	n.mu.Unlock()
   373  
   374  	return err
   375  }
   376  
   377  // AllAddresses returns all addresses (primary and non-primary) associated with
   378  // this NIC.
   379  func (n *NIC) AllAddresses() []tcpip.ProtocolAddress {
   380  	n.mu.RLock()
   381  	defer n.mu.RUnlock()
   382  
   383  	addrs := make([]tcpip.ProtocolAddress, 0, len(n.endpoints))
   384  	for nid, ref := range n.endpoints {
   385  		// Don't include expired or temporary endpoints to avoid confusion and
   386  		// prevent the caller from using those.
   387  		switch ref.getKind() {
   388  		case permanentExpired, temporary:
   389  			continue
   390  		}
   391  		addrs = append(addrs, tcpip.ProtocolAddress{
   392  			Protocol: ref.protocol,
   393  			AddressWithPrefix: tcpip.AddressWithPrefix{
   394  				Address:   nid.LocalAddress,
   395  				PrefixLen: ref.ep.PrefixLen(),
   396  			},
   397  		})
   398  	}
   399  	return addrs
   400  }
   401  
   402  // PrimaryAddresses returns the primary addresses associated with this NIC.
   403  func (n *NIC) PrimaryAddresses() []tcpip.ProtocolAddress {
   404  	n.mu.RLock()
   405  	defer n.mu.RUnlock()
   406  
   407  	var addrs []tcpip.ProtocolAddress
   408  	for proto, list := range n.primary {
   409  		for e := list.Front(); e != nil; e = e.Next() {
   410  			ref := e.(*referencedNetworkEndpoint)
   411  			// Don't include expired or tempory endpoints to avoid confusion and
   412  			// prevent the caller from using those.
   413  			switch ref.getKind() {
   414  			case permanentExpired, temporary:
   415  				continue
   416  			}
   417  
   418  			addrs = append(addrs, tcpip.ProtocolAddress{
   419  				Protocol: proto,
   420  				AddressWithPrefix: tcpip.AddressWithPrefix{
   421  					Address:   ref.ep.ID().LocalAddress,
   422  					PrefixLen: ref.ep.PrefixLen(),
   423  				},
   424  			})
   425  		}
   426  	}
   427  	return addrs
   428  }
   429  
   430  // AddAddressRange adds a range of addresses to n, so that it starts accepting
   431  // packets targeted at the given addresses and network protocol. The range is
   432  // given by a subnet address, and all addresses contained in the subnet are
   433  // used except for the subnet address itself and the subnet's broadcast
   434  // address.
   435  func (n *NIC) AddAddressRange(protocol tcpip.NetworkProtocolNumber, subnet tcpip.Subnet) {
   436  	n.mu.Lock()
   437  	n.addressRanges = append(n.addressRanges, subnet)
   438  	n.mu.Unlock()
   439  }
   440  
   441  // RemoveAddressRange removes the given address range from n.
   442  func (n *NIC) RemoveAddressRange(subnet tcpip.Subnet) {
   443  	n.mu.Lock()
   444  
   445  	// Use the same underlying array.
   446  	tmp := n.addressRanges[:0]
   447  	for _, sub := range n.addressRanges {
   448  		if sub != subnet {
   449  			tmp = append(tmp, sub)
   450  		}
   451  	}
   452  	n.addressRanges = tmp
   453  
   454  	n.mu.Unlock()
   455  }
   456  
   457  // Subnets returns the Subnets associated with this NIC.
   458  func (n *NIC) AddressRanges() []tcpip.Subnet {
   459  	n.mu.RLock()
   460  	defer n.mu.RUnlock()
   461  	sns := make([]tcpip.Subnet, 0, len(n.addressRanges)+len(n.endpoints))
   462  	for nid := range n.endpoints {
   463  		sn, err := tcpip.NewSubnet(nid.LocalAddress, tcpip.AddressMask(strings.Repeat("\xff", len(nid.LocalAddress))))
   464  		if err != nil {
   465  			// This should never happen as the mask has been carefully crafted to
   466  			// match the address.
   467  			panic("Invalid endpoint subnet: " + err.Error())
   468  		}
   469  		sns = append(sns, sn)
   470  	}
   471  	return append(sns, n.addressRanges...)
   472  }
   473  
   474  func (n *NIC) removeEndpointLocked(r *referencedNetworkEndpoint) {
   475  	id := *r.ep.ID()
   476  
   477  	// Nothing to do if the reference has already been replaced with a different
   478  	// one. This happens in the case where 1) this endpoint's ref count hit zero
   479  	// and was waiting (on the lock) to be removed and 2) the same address was
   480  	// re-added in the meantime by removing this endpoint from the list and
   481  	// adding a new one.
   482  	if n.endpoints[id] != r {
   483  		return
   484  	}
   485  
   486  	if r.getKind() == permanent {
   487  		panic("Reference count dropped to zero before being removed")
   488  	}
   489  
   490  	delete(n.endpoints, id)
   491  	wasInList := r.Next() != nil || r.Prev() != nil || r == n.primary[r.protocol].Front()
   492  	if wasInList {
   493  		n.primary[r.protocol].Remove(r)
   494  	}
   495  
   496  	r.ep.Close()
   497  }
   498  
   499  func (n *NIC) removeEndpoint(r *referencedNetworkEndpoint) {
   500  	n.mu.Lock()
   501  	n.removeEndpointLocked(r)
   502  	n.mu.Unlock()
   503  }
   504  
   505  func (n *NIC) removePermanentAddressLocked(addr tcpip.Address) *tcpip.Error {
   506  	r, ok := n.endpoints[NetworkEndpointID{addr}]
   507  	if !ok || r.getKind() != permanent {
   508  		return tcpip.ErrBadLocalAddress
   509  	}
   510  
   511  	r.setKind(permanentExpired)
   512  	if !r.decRefLocked() {
   513  		// The endpoint still has references to it.
   514  		return nil
   515  	}
   516  
   517  	// At this point the endpoint is deleted.
   518  
   519  	// If we are removing an IPv6 unicast address, leave the solicited-node
   520  	// multicast address.
   521  	if r.protocol == header.IPv6ProtocolNumber && header.IsV6UnicastAddress(addr) {
   522  		snmc := header.SolicitedNodeAddr(addr)
   523  		if err := n.leaveGroupLocked(snmc); err != nil {
   524  			return err
   525  		}
   526  	}
   527  
   528  	return nil
   529  }
   530  
   531  // RemoveAddress removes an address from n.
   532  func (n *NIC) RemoveAddress(addr tcpip.Address) *tcpip.Error {
   533  	n.mu.Lock()
   534  	defer n.mu.Unlock()
   535  	return n.removePermanentAddressLocked(addr)
   536  }
   537  
   538  // joinGroup adds a new endpoint for the given multicast address, if none
   539  // exists yet. Otherwise it just increments its count.
   540  func (n *NIC) joinGroup(protocol tcpip.NetworkProtocolNumber, addr tcpip.Address) *tcpip.Error {
   541  	n.mu.Lock()
   542  	defer n.mu.Unlock()
   543  
   544  	return n.joinGroupLocked(protocol, addr)
   545  }
   546  
   547  // joinGroupLocked adds a new endpoint for the given multicast address, if none
   548  // exists yet. Otherwise it just increments its count. n MUST be locked before
   549  // joinGroupLocked is called.
   550  func (n *NIC) joinGroupLocked(protocol tcpip.NetworkProtocolNumber, addr tcpip.Address) *tcpip.Error {
   551  	id := NetworkEndpointID{addr}
   552  	joins := n.mcastJoins[id]
   553  	if joins == 0 {
   554  		netProto, ok := n.stack.networkProtocols[protocol]
   555  		if !ok {
   556  			return tcpip.ErrUnknownProtocol
   557  		}
   558  		if _, err := n.addPermanentAddressLocked(tcpip.ProtocolAddress{
   559  			Protocol: protocol,
   560  			AddressWithPrefix: tcpip.AddressWithPrefix{
   561  				Address:   addr,
   562  				PrefixLen: netProto.DefaultPrefixLen(),
   563  			},
   564  		}, NeverPrimaryEndpoint); err != nil {
   565  			return err
   566  		}
   567  	}
   568  	n.mcastJoins[id] = joins + 1
   569  	return nil
   570  }
   571  
   572  // leaveGroup decrements the count for the given multicast address, and when it
   573  // reaches zero removes the endpoint for this address.
   574  func (n *NIC) leaveGroup(addr tcpip.Address) *tcpip.Error {
   575  	n.mu.Lock()
   576  	defer n.mu.Unlock()
   577  
   578  	return n.leaveGroupLocked(addr)
   579  }
   580  
   581  // leaveGroupLocked decrements the count for the given multicast address, and
   582  // when it reaches zero removes the endpoint for this address. n MUST be locked
   583  // before leaveGroupLocked is called.
   584  func (n *NIC) leaveGroupLocked(addr tcpip.Address) *tcpip.Error {
   585  	id := NetworkEndpointID{addr}
   586  	joins := n.mcastJoins[id]
   587  	switch joins {
   588  	case 0:
   589  		// There are no joins with this address on this NIC.
   590  		return tcpip.ErrBadLocalAddress
   591  	case 1:
   592  		// This is the last one, clean up.
   593  		if err := n.removePermanentAddressLocked(addr); err != nil {
   594  			return err
   595  		}
   596  	}
   597  	n.mcastJoins[id] = joins - 1
   598  	return nil
   599  }
   600  
   601  func handlePacket(protocol tcpip.NetworkProtocolNumber, dst, src tcpip.Address, localLinkAddr, remotelinkAddr tcpip.LinkAddress, ref *referencedNetworkEndpoint, vv buffer.VectorisedView) {
   602  	r := makeRoute(protocol, dst, src, localLinkAddr, ref, false /* handleLocal */, false /* multicastLoop */)
   603  	r.RemoteLinkAddress = remotelinkAddr
   604  	ref.ep.HandlePacket(&r, vv)
   605  	ref.decRef()
   606  }
   607  
   608  // DeliverNetworkPacket finds the appropriate network protocol endpoint and
   609  // hands the packet over for further processing. This function is called when
   610  // the NIC receives a packet from the physical interface.
   611  // Note that the ownership of the slice backing vv is retained by the caller.
   612  // This rule applies only to the slice itself, not to the items of the slice;
   613  // the ownership of the items is not retained by the caller.
   614  func (n *NIC) DeliverNetworkPacket(linkEP LinkEndpoint, remote, _ tcpip.LinkAddress, protocol tcpip.NetworkProtocolNumber, vv buffer.VectorisedView) {
   615  	n.stats.Rx.Packets.Increment()
   616  	n.stats.Rx.Bytes.IncrementBy(uint64(vv.Size()))
   617  
   618  	netProto, ok := n.stack.networkProtocols[protocol]
   619  	if !ok {
   620  		n.stack.stats.UnknownProtocolRcvdPackets.Increment()
   621  		return
   622  	}
   623  
   624  	if netProto.Number() == header.IPv4ProtocolNumber || netProto.Number() == header.IPv6ProtocolNumber {
   625  		n.stack.stats.IP.PacketsReceived.Increment()
   626  	}
   627  
   628  	if len(vv.First()) < netProto.MinimumPacketSize() {
   629  		n.stack.stats.MalformedRcvdPackets.Increment()
   630  		return
   631  	}
   632  
   633  	src, dst := netProto.ParseAddresses(vv.First())
   634  
   635  	n.stack.AddLinkAddress(n.id, src, remote)
   636  
   637  	if ref := n.getRef(protocol, dst); ref != nil {
   638  		handlePacket(protocol, dst, src, linkEP.LinkAddress(), remote, ref, vv)
   639  		return
   640  	}
   641  
   642  	// This NIC doesn't care about the packet. Find a NIC that cares about the
   643  	// packet and forward it to the NIC.
   644  	//
   645  	// TODO: Should we be forwarding the packet even if promiscuous?
   646  	if n.stack.Forwarding() {
   647  		r, err := n.stack.FindRoute(0, "", dst, protocol, false /* multicastLoop */)
   648  		if err != nil {
   649  			n.stack.stats.IP.InvalidAddressesReceived.Increment()
   650  			return
   651  		}
   652  		defer r.Release()
   653  
   654  		r.LocalLinkAddress = n.linkEP.LinkAddress()
   655  		r.RemoteLinkAddress = remote
   656  
   657  		// Found a NIC.
   658  		n := r.ref.nic
   659  		n.mu.RLock()
   660  		ref, ok := n.endpoints[NetworkEndpointID{dst}]
   661  		ok = ok && ref.isValidForOutgoing() && ref.tryIncRef()
   662  		n.mu.RUnlock()
   663  		if ok {
   664  			r.RemoteAddress = src
   665  			// TODO(b/123449044): Update the source NIC as well.
   666  			ref.ep.HandlePacket(&r, vv)
   667  			ref.decRef()
   668  		} else {
   669  			// n doesn't have a destination endpoint.
   670  			// Send the packet out of n.
   671  			hdr := buffer.NewPrependableFromView(vv.First())
   672  			vv.RemoveFirst()
   673  
   674  			// TODO(b/128629022): use route.WritePacket.
   675  			if err := n.linkEP.WritePacket(&r, nil /* gso */, hdr, vv, protocol); err != nil {
   676  				r.Stats().IP.OutgoingPacketErrors.Increment()
   677  			} else {
   678  				n.stats.Tx.Packets.Increment()
   679  				n.stats.Tx.Bytes.IncrementBy(uint64(hdr.UsedLength() + vv.Size()))
   680  			}
   681  		}
   682  		return
   683  	}
   684  
   685  	n.stack.stats.IP.InvalidAddressesReceived.Increment()
   686  }
   687  
   688  // DeliverTransportPacket delivers the packets to the appropriate transport
   689  // protocol endpoint.
   690  func (n *NIC) DeliverTransportPacket(r *Route, protocol tcpip.TransportProtocolNumber, netHeader buffer.View, vv buffer.VectorisedView) {
   691  	state, ok := n.stack.transportProtocols[protocol]
   692  	if !ok {
   693  		n.stack.stats.UnknownProtocolRcvdPackets.Increment()
   694  		return
   695  	}
   696  
   697  	transProto := state.proto
   698  
   699  	// Raw socket packets are delivered based solely on the transport
   700  	// protocol number. We do not inspect the payload to ensure it's
   701  	// validly formed.
   702  	n.stack.demux.deliverRawPacket(r, protocol, netHeader, vv)
   703  
   704  	if len(vv.First()) < transProto.MinimumPacketSize() {
   705  		n.stack.stats.MalformedRcvdPackets.Increment()
   706  		return
   707  	}
   708  
   709  	srcPort, dstPort, err := transProto.ParsePorts(vv.First())
   710  	if err != nil {
   711  		n.stack.stats.MalformedRcvdPackets.Increment()
   712  		return
   713  	}
   714  
   715  	id := TransportEndpointID{dstPort, r.LocalAddress, srcPort, r.RemoteAddress}
   716  	if n.stack.demux.deliverPacket(r, protocol, netHeader, vv, id) {
   717  		return
   718  	}
   719  
   720  	// Try to deliver to per-stack default handler.
   721  	if state.defaultHandler != nil {
   722  		if state.defaultHandler(r, id, netHeader, vv) {
   723  			return
   724  		}
   725  	}
   726  
   727  	// We could not find an appropriate destination for this packet, so
   728  	// deliver it to the global handler.
   729  	if !transProto.HandleUnknownDestinationPacket(r, id, netHeader, vv) {
   730  		n.stack.stats.MalformedRcvdPackets.Increment()
   731  	}
   732  }
   733  
   734  // DeliverTransportControlPacket delivers control packets to the appropriate
   735  // transport protocol endpoint.
   736  func (n *NIC) DeliverTransportControlPacket(local, remote tcpip.Address, net tcpip.NetworkProtocolNumber, trans tcpip.TransportProtocolNumber, typ ControlType, extra uint32, vv buffer.VectorisedView) {
   737  	state, ok := n.stack.transportProtocols[trans]
   738  	if !ok {
   739  		return
   740  	}
   741  
   742  	transProto := state.proto
   743  
   744  	// ICMPv4 only guarantees that 8 bytes of the transport protocol will
   745  	// be present in the payload. We know that the ports are within the
   746  	// first 8 bytes for all known transport protocols.
   747  	if len(vv.First()) < 8 {
   748  		return
   749  	}
   750  
   751  	srcPort, dstPort, err := transProto.ParsePorts(vv.First())
   752  	if err != nil {
   753  		return
   754  	}
   755  
   756  	id := TransportEndpointID{srcPort, local, dstPort, remote}
   757  	if n.stack.demux.deliverControlPacket(n, net, trans, typ, extra, vv, id) {
   758  		return
   759  	}
   760  }
   761  
   762  // ID returns the identifier of n.
   763  func (n *NIC) ID() tcpip.NICID {
   764  	return n.id
   765  }
   766  
   767  // Stack returns the instance of the Stack that owns this NIC.
   768  func (n *NIC) Stack() *Stack {
   769  	return n.stack
   770  }
   771  
   772  type networkEndpointKind int32
   773  
   774  const (
   775  	// A permanent endpoint is created by adding a permanent address (vs. a
   776  	// temporary one) to the NIC. Its reference count is biased by 1 to avoid
   777  	// removal when no route holds a reference to it. It is removed by explicitly
   778  	// removing the permanent address from the NIC.
   779  	permanent networkEndpointKind = iota
   780  
   781  	// An expired permanent endoint is a permanent endoint that had its address
   782  	// removed from the NIC, and it is waiting to be removed once no more routes
   783  	// hold a reference to it. This is achieved by decreasing its reference count
   784  	// by 1. If its address is re-added before the endpoint is removed, its type
   785  	// changes back to permanent and its reference count increases by 1 again.
   786  	permanentExpired
   787  
   788  	// A temporary endpoint is created for spoofing outgoing packets, or when in
   789  	// promiscuous mode and accepting incoming packets that don't match any
   790  	// permanent endpoint. Its reference count is not biased by 1 and the
   791  	// endpoint is removed immediately when no more route holds a reference to
   792  	// it. A temporary endpoint can be promoted to permanent if its address
   793  	// is added permanently.
   794  	temporary
   795  )
   796  
   797  type referencedNetworkEndpoint struct {
   798  	ilist.Entry
   799  	ep       NetworkEndpoint
   800  	nic      *NIC
   801  	protocol tcpip.NetworkProtocolNumber
   802  
   803  	// linkCache is set if link address resolution is enabled for this
   804  	// protocol. Set to nil otherwise.
   805  	linkCache LinkAddressCache
   806  
   807  	// refs is counting references held for this endpoint. When refs hits zero it
   808  	// triggers the automatic removal of the endpoint from the NIC.
   809  	refs int32
   810  
   811  	// networkEndpointKind must only be accessed using {get,set}Kind().
   812  	kind networkEndpointKind
   813  }
   814  
   815  func (r *referencedNetworkEndpoint) getKind() networkEndpointKind {
   816  	return networkEndpointKind(atomic.LoadInt32((*int32)(&r.kind)))
   817  }
   818  
   819  func (r *referencedNetworkEndpoint) setKind(kind networkEndpointKind) {
   820  	atomic.StoreInt32((*int32)(&r.kind), int32(kind))
   821  }
   822  
   823  // isValidForOutgoing returns true if the endpoint can be used to send out a
   824  // packet. It requires the endpoint to not be marked expired (i.e., its address
   825  // has been removed), or the NIC to be in spoofing mode.
   826  func (r *referencedNetworkEndpoint) isValidForOutgoing() bool {
   827  	return r.getKind() != permanentExpired || r.nic.spoofing
   828  }
   829  
   830  // isValidForIncoming returns true if the endpoint can accept an incoming
   831  // packet. It requires the endpoint to not be marked expired (i.e., its address
   832  // has been removed), or the NIC to be in promiscuous mode.
   833  func (r *referencedNetworkEndpoint) isValidForIncoming() bool {
   834  	return r.getKind() != permanentExpired || r.nic.promiscuous
   835  }
   836  
   837  // decRef decrements the ref count and cleans up the endpoint once it reaches
   838  // zero.
   839  func (r *referencedNetworkEndpoint) decRef() {
   840  	if atomic.AddInt32(&r.refs, -1) == 0 {
   841  		r.nic.removeEndpoint(r)
   842  	}
   843  }
   844  
   845  // decRefLocked is the same as decRef but assumes that the NIC.mu mutex is
   846  // locked. Returns true if the endpoint was removed.
   847  func (r *referencedNetworkEndpoint) decRefLocked() bool {
   848  	if atomic.AddInt32(&r.refs, -1) == 0 {
   849  		r.nic.removeEndpointLocked(r)
   850  		return true
   851  	}
   852  
   853  	return false
   854  }
   855  
   856  // incRef increments the ref count. It must only be called when the caller is
   857  // known to be holding a reference to the endpoint, otherwise tryIncRef should
   858  // be used.
   859  func (r *referencedNetworkEndpoint) incRef() {
   860  	atomic.AddInt32(&r.refs, 1)
   861  }
   862  
   863  // tryIncRef attempts to increment the ref count from n to n+1, but only if n is
   864  // not zero. That is, it will increment the count if the endpoint is still
   865  // alive, and do nothing if it has already been clean up.
   866  func (r *referencedNetworkEndpoint) tryIncRef() bool {
   867  	for {
   868  		v := atomic.LoadInt32(&r.refs)
   869  		if v == 0 {
   870  			return false
   871  		}
   872  
   873  		if atomic.CompareAndSwapInt32(&r.refs, v, v+1) {
   874  			return true
   875  		}
   876  	}
   877  }
   878  
   879  // stack returns the Stack instance that owns the underlying endpoint.
   880  func (r *referencedNetworkEndpoint) stack() *Stack {
   881  	return r.nic.stack
   882  }