summaryrefslogtreecommitdiffhomepage
path: root/pkg/tcpip/stack
diff options
context:
space:
mode:
authorgVisor bot <gvisor-bot@google.com>2021-02-09 03:10:57 +0000
committergVisor bot <gvisor-bot@google.com>2021-02-09 03:10:57 +0000
commit5741b2ffd9a15af87775038d47667263bb871ca1 (patch)
tree1894624b3f564758077646888358d18c6e221db5 /pkg/tcpip/stack
parent619ca7375ad32627c6237433e4508e3c54f7450e (diff)
parent39251f31cb92d6c2b053416d04e195e290b106f2 (diff)
Merge release-20210201.0-58-g39251f31c (automated)
Diffstat (limited to 'pkg/tcpip/stack')
-rw-r--r--pkg/tcpip/stack/nic.go33
-rw-r--r--pkg/tcpip/stack/registration.go93
-rw-r--r--pkg/tcpip/stack/stack.go11
3 files changed, 127 insertions, 10 deletions
diff --git a/pkg/tcpip/stack/nic.go b/pkg/tcpip/stack/nic.go
index 00cfba35a..f66db16a7 100644
--- a/pkg/tcpip/stack/nic.go
+++ b/pkg/tcpip/stack/nic.go
@@ -55,8 +55,9 @@ type nic struct {
// The network endpoints themselves may be modified by calling the interface's
// methods, but the map reference and entries must be constant.
- networkEndpoints map[tcpip.NetworkProtocolNumber]NetworkEndpoint
- linkAddrResolvers map[tcpip.NetworkProtocolNumber]*linkResolver
+ networkEndpoints map[tcpip.NetworkProtocolNumber]NetworkEndpoint
+ linkAddrResolvers map[tcpip.NetworkProtocolNumber]*linkResolver
+ duplicateAddressDetectors map[tcpip.NetworkProtocolNumber]DuplicateAddressDetector
// enabled is set to 1 when the NIC is enabled and 0 when it is disabled.
//
@@ -145,13 +146,14 @@ func newNIC(stack *Stack, id tcpip.NICID, name string, ep LinkEndpoint, ctx NICC
nic := &nic{
LinkEndpoint: ep,
- stack: stack,
- id: id,
- name: name,
- context: ctx,
- stats: makeNICStats(),
- networkEndpoints: make(map[tcpip.NetworkProtocolNumber]NetworkEndpoint),
- linkAddrResolvers: make(map[tcpip.NetworkProtocolNumber]*linkResolver),
+ stack: stack,
+ id: id,
+ name: name,
+ context: ctx,
+ stats: makeNICStats(),
+ networkEndpoints: make(map[tcpip.NetworkProtocolNumber]NetworkEndpoint),
+ linkAddrResolvers: make(map[tcpip.NetworkProtocolNumber]*linkResolver),
+ duplicateAddressDetectors: make(map[tcpip.NetworkProtocolNumber]DuplicateAddressDetector),
}
nic.linkResQueue.init(nic)
nic.mu.packetEPs = make(map[tcpip.NetworkProtocolNumber]*packetEndpointList)
@@ -176,6 +178,10 @@ func newNIC(stack *Stack, id tcpip.NICID, name string, ep LinkEndpoint, ctx NICC
nic.linkAddrResolvers[r.LinkAddressProtocol()] = l
}
}
+
+ if d, ok := netEP.(DuplicateAddressDetector); ok {
+ nic.duplicateAddressDetectors[d.DuplicateAddressProtocol()] = d
+ }
}
nic.LinkEndpoint.Attach(nic)
@@ -991,3 +997,12 @@ func (n *nic) CheckLocalAddress(protocol tcpip.NetworkProtocolNumber, addr tcpip
return false
}
+
+func (n *nic) checkDuplicateAddress(protocol tcpip.NetworkProtocolNumber, addr tcpip.Address, h DADCompletionHandler) (DADCheckAddressDisposition, tcpip.Error) {
+ d, ok := n.duplicateAddressDetectors[protocol]
+ if !ok {
+ return 0, &tcpip.ErrNotSupported{}
+ }
+
+ return d.CheckDuplicateAddress(addr, h), nil
+}
diff --git a/pkg/tcpip/stack/registration.go b/pkg/tcpip/stack/registration.go
index 2bc1c4270..43e9e4beb 100644
--- a/pkg/tcpip/stack/registration.go
+++ b/pkg/tcpip/stack/registration.go
@@ -16,6 +16,7 @@ package stack
import (
"fmt"
+ "time"
"gvisor.dev/gvisor/pkg/tcpip"
"gvisor.dev/gvisor/pkg/tcpip/buffer"
@@ -851,7 +852,97 @@ type InjectableLinkEndpoint interface {
InjectOutbound(dest tcpip.Address, packet []byte) tcpip.Error
}
-// A LinkAddressResolver handles link address resolution for a network protocol.
+// DADResult is the result of a duplicate address detection process.
+type DADResult struct {
+ // Resolved is true when DAD completed without detecting a duplicate address
+ // on the link.
+ //
+ // Ignored when Err is non-nil.
+ Resolved bool
+
+ // Err is an error encountered while performing DAD.
+ Err tcpip.Error
+}
+
+// DADCompletionHandler is a handler for DAD completion.
+type DADCompletionHandler func(DADResult)
+
+// DADCheckAddressDisposition enumerates the possible return values from
+// DAD.CheckDuplicateAddress.
+type DADCheckAddressDisposition int
+
+const (
+ _ DADCheckAddressDisposition = iota
+
+ // DADDisabled indicates that DAD is disabled.
+ DADDisabled
+
+ // DADStarting indicates that DAD is starting for an address.
+ DADStarting
+
+ // DADAlreadyRunning indicates that DAD was already started for an address.
+ DADAlreadyRunning
+)
+
+const (
+ // defaultDupAddrDetectTransmits is the default number of NDP Neighbor
+ // Solicitation messages to send when doing Duplicate Address Detection
+ // for a tentative address.
+ //
+ // Default = 1 (from RFC 4862 section 5.1)
+ defaultDupAddrDetectTransmits = 1
+)
+
+// DADConfigurations holds configurations for duplicate address detection.
+type DADConfigurations struct {
+ // The number of Neighbor Solicitation messages to send when doing
+ // Duplicate Address Detection for a tentative address.
+ //
+ // Note, a value of zero effectively disables DAD.
+ DupAddrDetectTransmits uint8
+
+ // The amount of time to wait between sending Neighbor Solicitation
+ // messages.
+ //
+ // Must be greater than or equal to 1ms.
+ RetransmitTimer time.Duration
+}
+
+// DefaultDADConfigurations returns the default DAD configurations.
+func DefaultDADConfigurations() DADConfigurations {
+ return DADConfigurations{
+ DupAddrDetectTransmits: defaultDupAddrDetectTransmits,
+ RetransmitTimer: defaultRetransmitTimer,
+ }
+}
+
+// Validate modifies the configuration with valid values. If invalid values are
+// present in the configurations, the corresponding default values are used
+// instead.
+func (c *DADConfigurations) Validate() {
+ if c.RetransmitTimer < minimumRetransmitTimer {
+ c.RetransmitTimer = defaultRetransmitTimer
+ }
+}
+
+// DuplicateAddressDetector handles checking if an address is already assigned
+// to some neighboring node on the link.
+type DuplicateAddressDetector interface {
+ // CheckDuplicateAddress checks if an address is assigned to a neighbor.
+ //
+ // If DAD is already being performed for the address, the handler will be
+ // called with the result of the original DAD request.
+ CheckDuplicateAddress(tcpip.Address, DADCompletionHandler) DADCheckAddressDisposition
+
+ // SetDADConfiguations sets the configurations for DAD.
+ SetDADConfigurations(c DADConfigurations)
+
+ // DuplicateAddressProtocol returns the network protocol the receiver can
+ // perform duplicate address detection for.
+ DuplicateAddressProtocol() tcpip.NetworkProtocolNumber
+}
+
+// LinkAddressResolver handles link address resolution for a network protocol.
type LinkAddressResolver interface {
// LinkAddressRequest sends a request for the link address of the target
// address. The request is broadcasted on the local network if a remote link
diff --git a/pkg/tcpip/stack/stack.go b/pkg/tcpip/stack/stack.go
index 46c1817ea..674c9a1ff 100644
--- a/pkg/tcpip/stack/stack.go
+++ b/pkg/tcpip/stack/stack.go
@@ -1466,6 +1466,17 @@ func (s *Stack) CheckNetworkProtocol(protocol tcpip.NetworkProtocolNumber) bool
return ok
}
+// CheckDuplicateAddress performs duplicate address detection for the address on
+// the specified interface.
+func (s *Stack) CheckDuplicateAddress(nicID tcpip.NICID, protocol tcpip.NetworkProtocolNumber, addr tcpip.Address, h DADCompletionHandler) (DADCheckAddressDisposition, tcpip.Error) {
+ nic, ok := s.nics[nicID]
+ if !ok {
+ return 0, &tcpip.ErrUnknownNICID{}
+ }
+
+ return nic.checkDuplicateAddress(protocol, addr, h)
+}
+
// CheckLocalAddress determines if the given local address exists, and if it
// does, returns the id of the NIC it's bound to. Returns 0 if the address
// does not exist.