mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
committed by
gVisor bot
parent
6fc9f0aefd
commit
b9aa62b9f9
+24
-11
@@ -80,7 +80,8 @@ type CreateLinksAndRoutesArgs struct {
|
||||
LoopbackLinks []LoopbackLink
|
||||
FDBasedLinks []FDBasedLink
|
||||
|
||||
DefaultGateway DefaultRoute
|
||||
Defaultv4Gateway DefaultRoute
|
||||
Defaultv6Gateway DefaultRoute
|
||||
}
|
||||
|
||||
// Empty returns true if route hasn't been set.
|
||||
@@ -122,10 +123,10 @@ func (n *Network) CreateLinksAndRoutes(args *CreateLinksAndRoutesArgs, _ *struct
|
||||
nicID++
|
||||
nicids[link.Name] = nicID
|
||||
|
||||
ep := loopback.New()
|
||||
linkEP := loopback.New()
|
||||
|
||||
log.Infof("Enabling loopback interface %q with id %d on addresses %+v", link.Name, nicID, link.Addresses)
|
||||
if err := n.createNICWithAddrs(nicID, link.Name, ep, link.Addresses, true /* loopback */); err != nil {
|
||||
if err := n.createNICWithAddrs(nicID, link.Name, linkEP, link.Addresses, true /* loopback */); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -157,7 +158,7 @@ func (n *Network) CreateLinksAndRoutes(args *CreateLinksAndRoutesArgs, _ *struct
|
||||
}
|
||||
|
||||
mac := tcpip.LinkAddress(link.LinkAddress)
|
||||
ep, err := fdbased.New(&fdbased.Options{
|
||||
linkEP, err := fdbased.New(&fdbased.Options{
|
||||
FDs: FDs,
|
||||
MTU: uint32(link.MTU),
|
||||
EthernetHeader: true,
|
||||
@@ -172,7 +173,7 @@ func (n *Network) CreateLinksAndRoutes(args *CreateLinksAndRoutesArgs, _ *struct
|
||||
}
|
||||
|
||||
log.Infof("Enabling interface %q with id %d on addresses %+v (%v) w/ %d channels", link.Name, nicID, link.Addresses, mac, link.NumChannels)
|
||||
if err := n.createNICWithAddrs(nicID, link.Name, ep, link.Addresses, false /* loopback */); err != nil {
|
||||
if err := n.createNICWithAddrs(nicID, link.Name, linkEP, link.Addresses, false /* loopback */); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -186,12 +187,24 @@ func (n *Network) CreateLinksAndRoutes(args *CreateLinksAndRoutesArgs, _ *struct
|
||||
}
|
||||
}
|
||||
|
||||
if !args.DefaultGateway.Route.Empty() {
|
||||
nicID, ok := nicids[args.DefaultGateway.Name]
|
||||
if !args.Defaultv4Gateway.Route.Empty() {
|
||||
nicID, ok := nicids[args.Defaultv4Gateway.Name]
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid interface name %q for default route", args.DefaultGateway.Name)
|
||||
return fmt.Errorf("invalid interface name %q for default route", args.Defaultv4Gateway.Name)
|
||||
}
|
||||
route, err := args.DefaultGateway.Route.toTcpipRoute(nicID)
|
||||
route, err := args.Defaultv4Gateway.Route.toTcpipRoute(nicID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
routes = append(routes, route)
|
||||
}
|
||||
|
||||
if !args.Defaultv6Gateway.Route.Empty() {
|
||||
nicID, ok := nicids[args.Defaultv6Gateway.Name]
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid interface name %q for default route", args.Defaultv6Gateway.Name)
|
||||
}
|
||||
route, err := args.Defaultv6Gateway.Route.toTcpipRoute(nicID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -208,11 +221,11 @@ func (n *Network) CreateLinksAndRoutes(args *CreateLinksAndRoutesArgs, _ *struct
|
||||
func (n *Network) createNICWithAddrs(id tcpip.NICID, name string, ep stack.LinkEndpoint, addrs []net.IP, loopback bool) error {
|
||||
if loopback {
|
||||
if err := n.Stack.CreateNamedLoopbackNIC(id, name, sniffer.New(ep)); err != nil {
|
||||
return fmt.Errorf("CreateNamedLoopbackNIC(%v, %v) failed: %v", id, name, err)
|
||||
return fmt.Errorf("CreateNamedLoopbackNIC(%v, %v, %v) failed: %v", id, name, ep, err)
|
||||
}
|
||||
} else {
|
||||
if err := n.Stack.CreateNamedNIC(id, name, sniffer.New(ep)); err != nil {
|
||||
return fmt.Errorf("CreateNamedNIC(%v, %v) failed: %v", id, name, err)
|
||||
return fmt.Errorf("CreateNamedNIC(%v, %v, %v) failed: %v", id, name, ep, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ go_library(
|
||||
"//pkg/log",
|
||||
"//pkg/sentry/control",
|
||||
"//pkg/sentry/platform",
|
||||
"//pkg/tcpip/header",
|
||||
"//pkg/tcpip/stack",
|
||||
"//pkg/urpc",
|
||||
"//runsc/boot",
|
||||
|
||||
+55
-40
@@ -28,6 +28,7 @@ import (
|
||||
"github.com/vishvananda/netlink"
|
||||
"golang.org/x/sys/unix"
|
||||
"gvisor.dev/gvisor/pkg/log"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/header"
|
||||
"gvisor.dev/gvisor/pkg/tcpip/stack"
|
||||
"gvisor.dev/gvisor/pkg/urpc"
|
||||
"gvisor.dev/gvisor/runsc/boot"
|
||||
@@ -183,36 +184,39 @@ func createInterfacesAndRoutesFromNS(conn *urpc.Client, nsPath string, hardwareG
|
||||
continue
|
||||
}
|
||||
|
||||
// Keep only IPv4 addresses.
|
||||
var ip4addrs []*net.IPNet
|
||||
var ipAddrs []*net.IPNet
|
||||
for _, ifaddr := range allAddrs {
|
||||
ipNet, ok := ifaddr.(*net.IPNet)
|
||||
if !ok {
|
||||
return fmt.Errorf("address is not IPNet: %+v", ifaddr)
|
||||
}
|
||||
if ipNet.IP.To4() == nil {
|
||||
log.Warningf("IPv6 is not supported, skipping: %v", ipNet)
|
||||
continue
|
||||
}
|
||||
ip4addrs = append(ip4addrs, ipNet)
|
||||
ipAddrs = append(ipAddrs, ipNet)
|
||||
}
|
||||
if len(ip4addrs) == 0 {
|
||||
log.Warningf("No IPv4 address found for interface %q, skipping", iface.Name)
|
||||
if len(ipAddrs) == 0 {
|
||||
log.Warningf("No usable IP addresses found for interface %q, skipping", iface.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
// Scrape the routes before removing the address, since that
|
||||
// will remove the routes as well.
|
||||
routes, def, err := routesForIface(iface)
|
||||
routes, defv4, defv6, err := routesForIface(iface)
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting routes for interface %q: %v", iface.Name, err)
|
||||
}
|
||||
if def != nil {
|
||||
if !args.DefaultGateway.Route.Empty() {
|
||||
return fmt.Errorf("more than one default route found, interface: %v, route: %v, default route: %+v", iface.Name, def, args.DefaultGateway)
|
||||
if defv4 != nil {
|
||||
if !args.Defaultv4Gateway.Route.Empty() {
|
||||
return fmt.Errorf("more than one default route found, interface: %v, route: %v, default route: %+v", iface.Name, defv4, args.Defaultv4Gateway)
|
||||
}
|
||||
args.DefaultGateway.Route = *def
|
||||
args.DefaultGateway.Name = iface.Name
|
||||
args.Defaultv4Gateway.Route = *defv4
|
||||
args.Defaultv4Gateway.Name = iface.Name
|
||||
}
|
||||
|
||||
if defv6 != nil {
|
||||
if !args.Defaultv6Gateway.Route.Empty() {
|
||||
return fmt.Errorf("more than one default route found, interface: %v, route: %v, default route: %+v", iface.Name, defv6, args.Defaultv6Gateway)
|
||||
}
|
||||
args.Defaultv6Gateway.Route = *defv6
|
||||
args.Defaultv6Gateway.Name = iface.Name
|
||||
}
|
||||
|
||||
link := boot.FDBasedLink{
|
||||
@@ -247,6 +251,7 @@ func createInterfacesAndRoutesFromNS(conn *urpc.Client, nsPath string, hardwareG
|
||||
}
|
||||
args.FilePayload.Files = append(args.FilePayload.Files, socketEntry.deviceFile)
|
||||
}
|
||||
|
||||
if link.GSOMaxSize == 0 && softwareGSO {
|
||||
// Hardware GSO is disabled. Let's enable software GSO.
|
||||
link.GSOMaxSize = stack.SoftwareGSOMaxSize
|
||||
@@ -255,7 +260,7 @@ func createInterfacesAndRoutesFromNS(conn *urpc.Client, nsPath string, hardwareG
|
||||
|
||||
// Collect the addresses for the interface, enable forwarding,
|
||||
// and remove them from the host.
|
||||
for _, addr := range ip4addrs {
|
||||
for _, addr := range ipAddrs {
|
||||
link.Addresses = append(link.Addresses, addr.IP)
|
||||
|
||||
// Steal IP address from NIC.
|
||||
@@ -351,46 +356,56 @@ func loopbackLinks(iface net.Interface, addrs []net.Addr) ([]boot.LoopbackLink,
|
||||
}
|
||||
|
||||
// routesForIface iterates over all routes for the given interface and converts
|
||||
// them to boot.Routes.
|
||||
func routesForIface(iface net.Interface) ([]boot.Route, *boot.Route, error) {
|
||||
// them to boot.Routes. It also returns the a default v4/v6 route if found.
|
||||
func routesForIface(iface net.Interface) ([]boot.Route, *boot.Route, *boot.Route, error) {
|
||||
link, err := netlink.LinkByIndex(iface.Index)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
rs, err := netlink.RouteList(link, netlink.FAMILY_ALL)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("getting routes from %q: %v", iface.Name, err)
|
||||
return nil, nil, nil, fmt.Errorf("getting routes from %q: %v", iface.Name, err)
|
||||
}
|
||||
|
||||
var def *boot.Route
|
||||
var defv4, defv6 *boot.Route
|
||||
var routes []boot.Route
|
||||
for _, r := range rs {
|
||||
// Is it a default route?
|
||||
if r.Dst == nil {
|
||||
if r.Gw == nil {
|
||||
return nil, nil, fmt.Errorf("default route with no gateway %q: %+v", iface.Name, r)
|
||||
}
|
||||
if r.Gw.To4() == nil {
|
||||
log.Warningf("IPv6 is not supported, skipping default route: %v", r)
|
||||
continue
|
||||
}
|
||||
if def != nil {
|
||||
return nil, nil, fmt.Errorf("more than one default route found %q, def: %+v, route: %+v", iface.Name, def, r)
|
||||
return nil, nil, nil, fmt.Errorf("default route with no gateway %q: %+v", iface.Name, r)
|
||||
}
|
||||
// Create a catch all route to the gateway.
|
||||
def = &boot.Route{
|
||||
Destination: net.IPNet{
|
||||
IP: net.IPv4zero,
|
||||
Mask: net.IPMask(net.IPv4zero),
|
||||
},
|
||||
Gateway: r.Gw,
|
||||
switch len(r.Gw) {
|
||||
case header.IPv4AddressSize:
|
||||
if defv4 != nil {
|
||||
return nil, nil, nil, fmt.Errorf("more than one default route found %q, def: %+v, route: %+v", iface.Name, defv4, r)
|
||||
}
|
||||
defv4 = &boot.Route{
|
||||
Destination: net.IPNet{
|
||||
IP: net.IPv4zero,
|
||||
Mask: net.IPMask(net.IPv4zero),
|
||||
},
|
||||
Gateway: r.Gw,
|
||||
}
|
||||
case header.IPv6AddressSize:
|
||||
if defv6 != nil {
|
||||
return nil, nil, nil, fmt.Errorf("more than one default route found %q, def: %+v, route: %+v", iface.Name, defv6, r)
|
||||
}
|
||||
|
||||
defv6 = &boot.Route{
|
||||
Destination: net.IPNet{
|
||||
IP: net.IPv6zero,
|
||||
Mask: net.IPMask(net.IPv6zero),
|
||||
},
|
||||
Gateway: r.Gw,
|
||||
}
|
||||
default:
|
||||
return nil, nil, nil, fmt.Errorf("unexpected address size for gateway: %+v for route: %+v", r.Gw, r)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if r.Dst.IP.To4() == nil {
|
||||
log.Warningf("IPv6 is not supported, skipping route: %v", r)
|
||||
continue
|
||||
}
|
||||
|
||||
dst := *r.Dst
|
||||
dst.IP = dst.IP.Mask(dst.Mask)
|
||||
routes = append(routes, boot.Route{
|
||||
@@ -398,7 +413,7 @@ func routesForIface(iface net.Interface) ([]boot.Route, *boot.Route, error) {
|
||||
Gateway: r.Gw,
|
||||
})
|
||||
}
|
||||
return routes, def, nil
|
||||
return routes, defv4, defv6, nil
|
||||
}
|
||||
|
||||
// removeAddress removes IP address from network device. It's equivalent to:
|
||||
|
||||
Reference in New Issue
Block a user