virtcontainers: kata_agent: Move out a generic function

The specific agent implementation kata_agent was defining a very
useful generic function that is now moved to the global file
network.go.

Fixes #629

Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2018-08-16 15:21:24 -07:00
parent 3f458187a4
commit f0e09c887a
4 changed files with 158 additions and 185 deletions

View File

@ -381,95 +381,6 @@ func (k *kataAgent) exec(sandbox *Sandbox, c Container, cmd Cmd) (*Process, erro
k.state.URL, cmd, []ns.NSType{}, enterNSList)
}
func (k *kataAgent) generateInterfacesAndRoutes(networkNS NetworkNamespace) ([]*grpc.Interface, []*grpc.Route, error) {
span, _ := k.trace("generateInterfacesAndRoutes")
defer span.Finish()
if networkNS.NetNsPath == "" {
return nil, nil, nil
}
var routes []*grpc.Route
var ifaces []*grpc.Interface
for _, endpoint := range networkNS.Endpoints {
var ipAddresses []*grpc.IPAddress
for _, addr := range endpoint.Properties().Addrs {
// Skip IPv6 because not supported
if addr.IP.To4() == nil {
// Skip IPv6 because not supported
k.Logger().WithFields(logrus.Fields{
"unsupported-address-type": "ipv6",
"address": addr,
}).Warn("unsupported address")
continue
}
// Skip localhost interface
if addr.IP.IsLoopback() {
continue
}
netMask, _ := addr.Mask.Size()
ipAddress := grpc.IPAddress{
Family: grpc.IPFamily_v4,
Address: addr.IP.String(),
Mask: fmt.Sprintf("%d", netMask),
}
ipAddresses = append(ipAddresses, &ipAddress)
}
ifc := grpc.Interface{
IPAddresses: ipAddresses,
Device: endpoint.Name(),
Name: endpoint.Name(),
Mtu: uint64(endpoint.Properties().Iface.MTU),
HwAddr: endpoint.HardwareAddr(),
}
ifaces = append(ifaces, &ifc)
for _, route := range endpoint.Properties().Routes {
var r grpc.Route
if route.Dst != nil {
r.Dest = route.Dst.String()
if route.Dst.IP.To4() == nil {
// Skip IPv6 because not supported
k.Logger().WithFields(logrus.Fields{
"unsupported-route-type": "ipv6",
"destination": r.Dest,
}).Warn("unsupported route")
continue
}
}
if route.Gw != nil {
gateway := route.Gw.String()
if route.Gw.To4() == nil {
// Skip IPv6 because is is not supported
k.Logger().WithFields(logrus.Fields{
"unsupported-route-type": "ipv6",
"gateway": gateway,
}).Warn("unsupported route")
continue
}
r.Gateway = gateway
}
if route.Src != nil {
r.Source = route.Src.String()
}
r.Device = endpoint.Name()
r.Scope = uint32(route.Scope)
routes = append(routes, &r)
}
}
return ifaces, routes, nil
}
func (k *kataAgent) updateInterface(ifc *grpc.Interface) (*grpc.Interface, error) {
// send update interface request
ifcReq := &grpc.UpdateInterfaceRequest{
@ -623,7 +534,7 @@ func (k *kataAgent) startSandbox(sandbox *Sandbox) error {
//
// Setup network interfaces and routes
//
interfaces, routes, err := k.generateInterfacesAndRoutes(sandbox.networkNS)
interfaces, routes, err := generateInterfacesAndRoutes(sandbox.networkNS)
if err != nil {
return err
}

View File

@ -20,7 +20,6 @@ import (
gpb "github.com/gogo/protobuf/types"
specs "github.com/opencontainers/runtime-spec/specs-go"
"github.com/stretchr/testify/assert"
"github.com/vishvananda/netlink"
"golang.org/x/net/context"
"google.golang.org/grpc"
@ -339,100 +338,6 @@ func TestKataAgentSendReq(t *testing.T) {
assert.Nil(err)
}
func TestGenerateInterfacesAndRoutes(t *testing.T) {
impl := &gRPCProxy{}
proxy := mock.ProxyGRPCMock{
GRPCImplementer: impl,
GRPCRegister: gRPCRegister,
}
sockDir, err := testGenerateKataProxySockDir()
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(sockDir)
testKataProxyURL := fmt.Sprintf(testKataProxyURLTempl, sockDir)
if err := proxy.Start(testKataProxyURL); err != nil {
t.Fatal(err)
}
defer proxy.Stop()
k := &kataAgent{
state: KataAgentState{
URL: testKataProxyURL,
},
}
//
//Create a couple of addresses
//
address1 := &net.IPNet{IP: net.IPv4(172, 17, 0, 2), Mask: net.CIDRMask(16, 32)}
address2 := &net.IPNet{IP: net.IPv4(182, 17, 0, 2), Mask: net.CIDRMask(16, 32)}
addrs := []netlink.Addr{
{IPNet: address1, Label: "phyaddr1"},
{IPNet: address2, Label: "phyaddr2"},
}
// Create a couple of routes:
dst2 := &net.IPNet{IP: net.IPv4(172, 17, 0, 0), Mask: net.CIDRMask(16, 32)}
src2 := net.IPv4(172, 17, 0, 2)
gw2 := net.IPv4(172, 17, 0, 1)
routes := []netlink.Route{
{LinkIndex: 329, Dst: nil, Src: nil, Gw: net.IPv4(172, 17, 0, 1), Scope: netlink.Scope(254)},
{LinkIndex: 329, Dst: dst2, Src: src2, Gw: gw2},
}
networkInfo := NetworkInfo{
Iface: NetlinkIface{
LinkAttrs: netlink.LinkAttrs{MTU: 1500},
Type: "",
},
Addrs: addrs,
Routes: routes,
}
ep0 := &PhysicalEndpoint{
IfaceName: "eth0",
HardAddr: net.HardwareAddr{0x02, 0x00, 0xca, 0xfe, 0x00, 0x04}.String(),
EndpointProperties: networkInfo,
}
endpoints := []Endpoint{ep0}
nns := NetworkNamespace{NetNsPath: "foobar", NetNsCreated: true, Endpoints: endpoints}
resInterfaces, resRoutes, err := k.generateInterfacesAndRoutes(nns)
//
// Build expected results:
//
expectedAddresses := []*pb.IPAddress{
{Family: 0, Address: "172.17.0.2", Mask: "16"},
{Family: 0, Address: "182.17.0.2", Mask: "16"},
}
expectedInterfaces := []*pb.Interface{
{Device: "eth0", Name: "eth0", IPAddresses: expectedAddresses, Mtu: 1500, HwAddr: "02:00:ca:fe:00:04"},
}
expectedRoutes := []*pb.Route{
{Dest: "", Gateway: "172.17.0.1", Device: "eth0", Source: "", Scope: uint32(254)},
{Dest: "172.17.0.0/16", Gateway: "172.17.0.1", Device: "eth0", Source: "172.17.0.2"},
}
assert.Nil(t, err, "unexpected failure when calling generateKataInterfacesAndRoutes")
assert.True(t, reflect.DeepEqual(resInterfaces, expectedInterfaces),
"Interfaces returned didn't match: got %+v, expecting %+v", resInterfaces, expectedInterfaces)
assert.True(t, reflect.DeepEqual(resRoutes, expectedRoutes),
"Routes returned didn't match: got %+v, expecting %+v", resRoutes, expectedRoutes)
}
func TestHandleEphemeralStorage(t *testing.T) {
k := kataAgent{}
var ociMounts []specs.Mount

View File

@ -27,6 +27,7 @@ import (
"github.com/vishvananda/netns"
"golang.org/x/sys/unix"
"github.com/kata-containers/agent/protocols/grpc"
"github.com/kata-containers/runtime/virtcontainers/device/config"
"github.com/kata-containers/runtime/virtcontainers/device/drivers"
"github.com/kata-containers/runtime/virtcontainers/pkg/uuid"
@ -1340,6 +1341,93 @@ func createVirtualNetworkEndpoint(idx int, ifName string, interworkingModel NetI
return endpoint, nil
}
func generateInterfacesAndRoutes(networkNS NetworkNamespace) ([]*grpc.Interface, []*grpc.Route, error) {
if networkNS.NetNsPath == "" {
return nil, nil, nil
}
var routes []*grpc.Route
var ifaces []*grpc.Interface
for _, endpoint := range networkNS.Endpoints {
var ipAddresses []*grpc.IPAddress
for _, addr := range endpoint.Properties().Addrs {
// Skip IPv6 because not supported
if addr.IP.To4() == nil {
// Skip IPv6 because not supported
networkLogger().WithFields(logrus.Fields{
"unsupported-address-type": "ipv6",
"address": addr,
}).Warn("unsupported address")
continue
}
// Skip localhost interface
if addr.IP.IsLoopback() {
continue
}
netMask, _ := addr.Mask.Size()
ipAddress := grpc.IPAddress{
Family: grpc.IPFamily_v4,
Address: addr.IP.String(),
Mask: fmt.Sprintf("%d", netMask),
}
ipAddresses = append(ipAddresses, &ipAddress)
}
ifc := grpc.Interface{
IPAddresses: ipAddresses,
Device: endpoint.Name(),
Name: endpoint.Name(),
Mtu: uint64(endpoint.Properties().Iface.MTU),
HwAddr: endpoint.HardwareAddr(),
}
ifaces = append(ifaces, &ifc)
for _, route := range endpoint.Properties().Routes {
var r grpc.Route
if route.Dst != nil {
r.Dest = route.Dst.String()
if route.Dst.IP.To4() == nil {
// Skip IPv6 because not supported
networkLogger().WithFields(logrus.Fields{
"unsupported-route-type": "ipv6",
"destination": r.Dest,
}).Warn("unsupported route")
continue
}
}
if route.Gw != nil {
gateway := route.Gw.String()
if route.Gw.To4() == nil {
// Skip IPv6 because is is not supported
networkLogger().WithFields(logrus.Fields{
"unsupported-route-type": "ipv6",
"gateway": gateway,
}).Warn("unsupported route")
continue
}
r.Gateway = gateway
}
if route.Src != nil {
r.Source = route.Src.String()
}
r.Device = endpoint.Name()
r.Scope = uint32(route.Scope)
routes = append(routes, &r)
}
}
return ifaces, routes, nil
}
func networkInfoFromLink(handle *netlink.Handle, link netlink.Link) (NetworkInfo, error) {
addrs, err := handle.AddrList(link, netlink.FAMILY_ALL)
if err != nil {

View File

@ -16,6 +16,7 @@ import (
"testing"
"github.com/containernetworking/plugins/pkg/ns"
"github.com/kata-containers/agent/protocols/grpc"
"github.com/stretchr/testify/assert"
"github.com/vishvananda/netlink"
"github.com/vishvananda/netns"
@ -614,3 +615,71 @@ func TestHostNetworkingRequested(t *testing.T) {
syscall.Unmount(tmpFile, 0)
}
func TestGenerateInterfacesAndRoutes(t *testing.T) {
//
//Create a couple of addresses
//
address1 := &net.IPNet{IP: net.IPv4(172, 17, 0, 2), Mask: net.CIDRMask(16, 32)}
address2 := &net.IPNet{IP: net.IPv4(182, 17, 0, 2), Mask: net.CIDRMask(16, 32)}
addrs := []netlink.Addr{
{IPNet: address1, Label: "phyaddr1"},
{IPNet: address2, Label: "phyaddr2"},
}
// Create a couple of routes:
dst2 := &net.IPNet{IP: net.IPv4(172, 17, 0, 0), Mask: net.CIDRMask(16, 32)}
src2 := net.IPv4(172, 17, 0, 2)
gw2 := net.IPv4(172, 17, 0, 1)
routes := []netlink.Route{
{LinkIndex: 329, Dst: nil, Src: nil, Gw: net.IPv4(172, 17, 0, 1), Scope: netlink.Scope(254)},
{LinkIndex: 329, Dst: dst2, Src: src2, Gw: gw2},
}
networkInfo := NetworkInfo{
Iface: NetlinkIface{
LinkAttrs: netlink.LinkAttrs{MTU: 1500},
Type: "",
},
Addrs: addrs,
Routes: routes,
}
ep0 := &PhysicalEndpoint{
IfaceName: "eth0",
HardAddr: net.HardwareAddr{0x02, 0x00, 0xca, 0xfe, 0x00, 0x04}.String(),
EndpointProperties: networkInfo,
}
endpoints := []Endpoint{ep0}
nns := NetworkNamespace{NetNsPath: "foobar", NetNsCreated: true, Endpoints: endpoints}
resInterfaces, resRoutes, err := generateInterfacesAndRoutes(nns)
//
// Build expected results:
//
expectedAddresses := []*grpc.IPAddress{
{Family: 0, Address: "172.17.0.2", Mask: "16"},
{Family: 0, Address: "182.17.0.2", Mask: "16"},
}
expectedInterfaces := []*grpc.Interface{
{Device: "eth0", Name: "eth0", IPAddresses: expectedAddresses, Mtu: 1500, HwAddr: "02:00:ca:fe:00:04"},
}
expectedRoutes := []*grpc.Route{
{Dest: "", Gateway: "172.17.0.1", Device: "eth0", Source: "", Scope: uint32(254)},
{Dest: "172.17.0.0/16", Gateway: "172.17.0.1", Device: "eth0", Source: "172.17.0.2"},
}
assert.Nil(t, err, "unexpected failure when calling generateKataInterfacesAndRoutes")
assert.True(t, reflect.DeepEqual(resInterfaces, expectedInterfaces),
"Interfaces returned didn't match: got %+v, expecting %+v", resInterfaces, expectedInterfaces)
assert.True(t, reflect.DeepEqual(resRoutes, expectedRoutes),
"Routes returned didn't match: got %+v, expecting %+v", resRoutes, expectedRoutes)
}