mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
xdp: clean up the XDP flag situation
A single flag now controls XDP. More modes will be added as we test XDP, and we don't want to proliferate confusing flags. PiperOrigin-RevId: 595502921
This commit is contained in:
committed by
gVisor bot
parent
9ea77eb8bc
commit
0bb4cfdc4b
+74
-11
@@ -282,17 +282,8 @@ type Config struct {
|
||||
// Use pools to manage buffer memory instead of heap.
|
||||
BufferPooling bool `flag:"buffer-pooling"`
|
||||
|
||||
// AFXDP defines whether to use an AF_XDP socket to receive packets
|
||||
// (rather than AF_PACKET). Enabling it disables RX checksum offload.
|
||||
AFXDP bool `flag:"EXPERIMENTAL-afxdp"`
|
||||
|
||||
// AFXDPRedirectHost is the name of a network interface. runsc will
|
||||
// scrape the address, routes, and neighbors of that interface, and
|
||||
// send packets via an AF_XDP socket on that interface.
|
||||
//
|
||||
// Requires use of `xdp_loader redirect` to setup the XDP program and
|
||||
// eBPF map that runsc hooks into.
|
||||
AFXDPRedirectHost string `flag:"EXPERIMENTAL-xdp-redirect-host"`
|
||||
// XDP controls Whether and how to use XDP.
|
||||
XDP XDP `flag:"EXPERIMENTAL-xdp"`
|
||||
|
||||
// AFXDPUseNeedWakeup determines whether XDP_USE_NEED_WAKEUP is set
|
||||
// when using AF_XDP sockets.
|
||||
@@ -924,3 +915,75 @@ func (o *Overlay2) SubMountOverlayMedium() OverlayMedium {
|
||||
}
|
||||
return o.medium
|
||||
}
|
||||
|
||||
// XDP holds configuration for whether and how to use XDP.
|
||||
type XDP struct {
|
||||
Mode XDPMode
|
||||
IfaceName string
|
||||
}
|
||||
|
||||
// XDPMode specifies a particular use of XDP.
|
||||
type XDPMode int
|
||||
|
||||
const (
|
||||
// XDPModeOff doesn't use XDP.
|
||||
XDPModeOff XDPMode = iota
|
||||
|
||||
// XDPModeNS uses an AF_XDP socket to read from the VETH device inside
|
||||
// the container's network namespace.
|
||||
XDPModeNS
|
||||
|
||||
// XDPModeRedirect uses an AF_XDP socket on the host NIC to bypass the
|
||||
// Linux network stack.
|
||||
XDPModeRedirect
|
||||
)
|
||||
|
||||
const (
|
||||
xdpModeStrOff = "off"
|
||||
xdpModeStrNS = "ns"
|
||||
xdpModeStrRedirect = "redirect"
|
||||
)
|
||||
|
||||
var xdpConfig XDP
|
||||
|
||||
// Get implements flag.Getter.
|
||||
func (xd *XDP) Get() any {
|
||||
return *xd
|
||||
}
|
||||
|
||||
// String implements flag.Getter.
|
||||
func (xd *XDP) String() string {
|
||||
switch xd.Mode {
|
||||
case XDPModeOff:
|
||||
return xdpModeStrOff
|
||||
case XDPModeNS:
|
||||
return xdpModeStrNS
|
||||
case XDPModeRedirect:
|
||||
return fmt.Sprintf("%s:%s", xdpModeStrRedirect, xd.IfaceName)
|
||||
default:
|
||||
panic(fmt.Sprintf("unknown mode %d", xd.Mode))
|
||||
}
|
||||
}
|
||||
|
||||
// Set implements flag.Getter.
|
||||
func (xd *XDP) Set(input string) error {
|
||||
parts := strings.Split(input, ":")
|
||||
if len(parts) > 2 {
|
||||
return fmt.Errorf("invalid --xdp value: %q", input)
|
||||
}
|
||||
|
||||
switch {
|
||||
case input == xdpModeStrOff:
|
||||
xd.Mode = XDPModeOff
|
||||
xd.IfaceName = ""
|
||||
case input == xdpModeStrNS:
|
||||
xd.Mode = XDPModeNS
|
||||
xd.IfaceName = ""
|
||||
case len(parts) == 2 && parts[0] == xdpModeStrRedirect && parts[1] != "":
|
||||
xd.Mode = XDPModeRedirect
|
||||
xd.IfaceName = parts[1]
|
||||
default:
|
||||
return fmt.Errorf("invalid --xdp value: %q", input)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -120,9 +120,8 @@ func RegisterFlags(flagSet *flag.FlagSet) {
|
||||
flagSet.Var(queueingDisciplinePtr(QDiscFIFO), "qdisc", "specifies which queueing discipline to apply by default to the non loopback nics used by the sandbox.")
|
||||
flagSet.Int("num-network-channels", 1, "number of underlying channels(FDs) to use for network link endpoints.")
|
||||
flagSet.Bool("buffer-pooling", true, "enable allocation of buffers from a shared pool instead of the heap.")
|
||||
flagSet.Bool("EXPERIMENTAL-afxdp", false, "EXPERIMENTAL. Use an AF_XDP socket to receive packets.")
|
||||
flagSet.String("EXPERIMENTAL-xdp-redirect-host", "", "EXPERIMENTAL. Use an AF_XDP socket attached to <interface name>. Use the IP of that interface.")
|
||||
flagSet.Bool("EXPERIMENTAL-xdp-need-wakeup", true, "EXPERIMENTAL. Use XDP_USE_NEED_WAKEUP with XDP sockets.")
|
||||
flagSet.Var(&xdpConfig, "EXPERIMENTAL-xdp", `whether and how to use XDP. Can be one of: "off" (default), "ns", or "redirect:<device name>"`)
|
||||
flagSet.Bool("EXPERIMENTAL-xdp-need-wakeup", true, "EXPERIMENTAL. Use XDP_USE_NEED_WAKEUP with XDP sockets.") // TODO(b/240191988): Figure out whether this helps and remove it as a flag.
|
||||
flagSet.Bool("reproduce-nat", false, "Scrape the host netns NAT table and reproduce it in the sandbox.")
|
||||
flagSet.Bool("reproduce-nftables", false, "Attempt to scrape and reproduce nftable rules inside the sandbox. Overrides reproduce-nat when true.")
|
||||
|
||||
|
||||
@@ -120,11 +120,16 @@ func isRootNS() (bool, error) {
|
||||
// net namespace with the given path, creates them in the sandbox, and removes
|
||||
// them from the host.
|
||||
func createInterfacesAndRoutesFromNS(conn *urpc.Client, nsPath string, conf *config.Config) error {
|
||||
if conf.AFXDPRedirectHost != "" {
|
||||
switch conf.XDP.Mode {
|
||||
case config.XDPModeOff:
|
||||
case config.XDPModeNS:
|
||||
case config.XDPModeRedirect:
|
||||
if err := createRedirectInterfacesAndRoutes(conn, conf); err != nil {
|
||||
return fmt.Errorf("failed to create XDP redirect interface: %w", err)
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("unknown XDP mode: %v", conf.XDP.Mode)
|
||||
}
|
||||
|
||||
// Join the network namespace that we will be copying.
|
||||
@@ -250,7 +255,7 @@ func createInterfacesAndRoutesFromNS(conn *urpc.Client, nsPath string, conf *con
|
||||
}
|
||||
}
|
||||
|
||||
if conf.AFXDP {
|
||||
if conf.XDP.Mode == config.XDPModeNS {
|
||||
xdpSockFDs, err := createSocketXDP(iface)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create XDP socket: %v", err)
|
||||
|
||||
@@ -157,7 +157,7 @@ func prepareRedirectInterfaceArgs(conf *config.Config) (boot.CreateLinksAndRoute
|
||||
continue
|
||||
}
|
||||
|
||||
if iface.Name != conf.AFXDPRedirectHost {
|
||||
if iface.Name != conf.XDP.IfaceName {
|
||||
log.Infof("Skipping interface %q", iface.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user