From 3955d351f91c91fb9d85e23ff1c0315db1455027 Mon Sep 17 00:00:00 2001 From: Kathryn Baldauf Date: Tue, 27 Jun 2023 14:57:47 -0700 Subject: [PATCH] Add support for nodenetsvc v0 and readme to test network agent Signed-off-by: Kathryn Baldauf --- internal/tools/networkagent/README.md | 23 ++++++ internal/tools/networkagent/defs.go | 6 +- internal/tools/networkagent/main.go | 27 ++++--- .../tools/networkagent/v0_service_wrapper.go | 72 +++++++++++++++++++ 4 files changed, 119 insertions(+), 9 deletions(-) create mode 100644 internal/tools/networkagent/README.md create mode 100644 internal/tools/networkagent/v0_service_wrapper.go diff --git a/internal/tools/networkagent/README.md b/internal/tools/networkagent/README.md new file mode 100644 index 0000000000..db4dd06cf2 --- /dev/null +++ b/internal/tools/networkagent/README.md @@ -0,0 +1,23 @@ +# Using the test network agent + +## Create a network agent configuration file +- Create a file named `nodenetsvc.conf` with the following contents: + ``` + { + "ttrpc": "\\\\.\\pipe\\ncproxy-ttrpc", + "grpc": "127.0.0.1:6669", + "node_net_svc_addr": "127.0.0.1:6668", + "timeout": 10, + "networking_settings": { + "hns_settings": { + "switch_name": "name-of-your-switch" + } + } + } + ``` + See definitions [here](https://github.com/microsoft/hcsshim/blob/main/internal/tools/networkagent/defs.go) for further customizing this configuration. + +## Run the network agent +``` +networkagent.exe --config .\nodenetsvc.conf +``` diff --git a/internal/tools/networkagent/defs.go b/internal/tools/networkagent/defs.go index 4a339b07d6..a5e31d40ca 100644 --- a/internal/tools/networkagent/defs.go +++ b/internal/tools/networkagent/defs.go @@ -9,6 +9,7 @@ import ( "github.com/pkg/errors" ncproxygrpc "github.com/Microsoft/hcsshim/pkg/ncproxy/ncproxygrpc/v1" + nodenetsvcV0 "github.com/Microsoft/hcsshim/pkg/ncproxy/nodenetsvc/v0" nodenetsvc "github.com/Microsoft/hcsshim/pkg/ncproxy/nodenetsvc/v1" ) @@ -22,7 +23,10 @@ type service struct { containerToNetwork map[string][]string } -var _ nodenetsvc.NodeNetworkServiceServer = &service{} +type v0ServiceWrapper struct { + s *service + nodenetsvcV0.UnimplementedNodeNetworkServiceServer +} type hnsSettings struct { SwitchName string `json:"switch_name,omitempty"` diff --git a/internal/tools/networkagent/main.go b/internal/tools/networkagent/main.go index ba31fe6dc8..582ddfdf91 100644 --- a/internal/tools/networkagent/main.go +++ b/internal/tools/networkagent/main.go @@ -22,6 +22,7 @@ import ( "github.com/Microsoft/hcsshim/hcn" "github.com/Microsoft/hcsshim/internal/log" ncproxygrpc "github.com/Microsoft/hcsshim/pkg/ncproxy/ncproxygrpc/v1" + nodenetsvcV0 "github.com/Microsoft/hcsshim/pkg/ncproxy/nodenetsvc/v0" nodenetsvc "github.com/Microsoft/hcsshim/pkg/ncproxy/nodenetsvc/v1" ) @@ -76,12 +77,17 @@ func generateIPs(prefixLength string) (string, string, string) { func (s *service) configureHCNNetworkingHelper(ctx context.Context, req *nodenetsvc.ConfigureContainerNetworkingRequest) (_ *nodenetsvc.ConfigureContainerNetworkingResponse, err error) { prefixIP, gatewayIP, midIP := generateIPs(strconv.Itoa(int(prefixLength))) + + mode := ncproxygrpc.HostComputeNetworkSettings_NAT + if s.conf.NetworkingSettings.HNSSettings.IOVSettings != nil { + mode = ncproxygrpc.HostComputeNetworkSettings_Transparent + } addNetworkReq := &ncproxygrpc.CreateNetworkRequest{ Network: &ncproxygrpc.Network{ Settings: &ncproxygrpc.Network_HcnNetwork{ HcnNetwork: &ncproxygrpc.HostComputeNetworkSettings{ Name: req.ContainerID + "_network_hcn", - Mode: ncproxygrpc.HostComputeNetworkSettings_Transparent, + Mode: mode, SwitchName: s.conf.NetworkingSettings.HNSSettings.SwitchName, IpamType: ncproxygrpc.HostComputeNetworkSettings_Static, SubnetIpaddressPrefix: []string{prefixIP}, @@ -107,6 +113,11 @@ func (s *service) configureHCNNetworkingHelper(ctx context.Context, req *nodenet return nil, err } + policies := &ncproxygrpc.HcnEndpointPolicies{} + if s.conf.NetworkingSettings.HNSSettings.IOVSettings != nil { + policies.IovPolicySettings = s.conf.NetworkingSettings.HNSSettings.IOVSettings + } + name := req.ContainerID + "_endpoint_hcn" endpointCreateReq := &ncproxygrpc.CreateEndpointRequest{ EndpointSettings: &ncproxygrpc.EndpointSettings{ @@ -117,9 +128,7 @@ func (s *service) configureHCNNetworkingHelper(ctx context.Context, req *nodenet Ipaddress: midIP, IpaddressPrefixlength: prefixLength, NetworkName: network.Name, - Policies: &ncproxygrpc.HcnEndpointPolicies{ - IovPolicySettings: s.conf.NetworkingSettings.HNSSettings.IOVSettings, - }, + Policies: policies, }, }, }, @@ -298,14 +307,14 @@ func (s *service) ConfigureContainerNetworking(ctx context.Context, req *nodenet if req.RequestType == nodenetsvc.RequestType_Setup { interfaces := []*nodenetsvc.ContainerNetworkInterface{} - if s.conf.NetworkingSettings.HNSSettings != nil { + if s.conf.NetworkingSettings != nil && s.conf.NetworkingSettings.HNSSettings != nil { result, err := s.configureHCNNetworkingHelper(ctx, req) if err != nil { return nil, err } interfaces = append(interfaces, result.Interfaces...) } - if s.conf.NetworkingSettings.NCProxyNetworkingSettings != nil { + if s.conf.NetworkingSettings != nil && s.conf.NetworkingSettings.NCProxyNetworkingSettings != nil { result, err := s.configureNCProxyNetworkingHelper(ctx, req) if err != nil { return nil, err @@ -437,8 +446,6 @@ func (s *service) ConfigureNetworking(ctx context.Context, req *nodenetsvc.Confi return s.teardownHelper(ctx, req, containerNamespaceID) } -// GetHostLocalIpAddress is defined in the nodenetworksvc proto which is owned by the azure vnetagent team -// //nolint:stylecheck func (s *service) GetHostLocalIpAddress(ctx context.Context, req *nodenetsvc.GetHostLocalIpAddressRequest) (*nodenetsvc.GetHostLocalIpAddressResponse, error) { return &nodenetsvc.GetHostLocalIpAddressResponse{IpAddr: ""}, nil @@ -486,8 +493,12 @@ func main() { endpointToNicID: make(map[string]string), containerToNetwork: make(map[string][]string), } + v0Service := &v0ServiceWrapper{ + s: service, + } server := grpc.NewServer() nodenetsvc.RegisterNodeNetworkServiceServer(server, service) + nodenetsvcV0.RegisterNodeNetworkServiceServer(server, v0Service) grpcListener, err := net.Listen("tcp", conf.NodeNetSvcAddr) if err != nil { diff --git a/internal/tools/networkagent/v0_service_wrapper.go b/internal/tools/networkagent/v0_service_wrapper.go new file mode 100644 index 0000000000..2ebc521ca1 --- /dev/null +++ b/internal/tools/networkagent/v0_service_wrapper.go @@ -0,0 +1,72 @@ +//go:build windows + +package main + +import ( + "context" + + "github.com/Microsoft/hcsshim/internal/log" + nodenetsvcV0 "github.com/Microsoft/hcsshim/pkg/ncproxy/nodenetsvc/v0" + nodenetsvc "github.com/Microsoft/hcsshim/pkg/ncproxy/nodenetsvc/v1" +) + +func (s *v0ServiceWrapper) ConfigureContainerNetworking(ctx context.Context, req *nodenetsvcV0.ConfigureContainerNetworkingRequest) (_ *nodenetsvcV0.ConfigureContainerNetworkingResponse, err error) { + v1Req := &nodenetsvc.ConfigureContainerNetworkingRequest{ + RequestType: nodenetsvc.RequestType(req.RequestType), + ContainerID: req.ContainerID, + NetworkNamespaceID: req.NetworkNamespaceID, + } + v1Resp, err := s.s.ConfigureContainerNetworking(ctx, v1Req) + if err != nil { + return nil, err + } + + v0Interfaces := make([]*nodenetsvcV0.ContainerNetworkInterface, len(v1Resp.Interfaces)) + for i, v1Interface := range v1Resp.Interfaces { + v0Interface := &nodenetsvcV0.ContainerNetworkInterface{ + Name: v1Interface.Name, + MacAddress: v1Interface.MacAddress, + NetworkNamespaceID: v1Interface.NetworkNamespaceID, + } + + if v1Interface.Ipaddresses != nil { + ipAddrs := make([]*nodenetsvcV0.ContainerIPAddress, len(v1Interface.Ipaddresses)) + for i, v1IP := range v1Interface.Ipaddresses { + v0IP := &nodenetsvcV0.ContainerIPAddress{ + Version: v1IP.Version, + Ip: v1IP.Ip, + PrefixLength: v1IP.PrefixLength, + DefaultGateway: v1IP.DefaultGateway, + } + ipAddrs[i] = v0IP + } + v0Interface.Ipaddresses = ipAddrs + } + v0Interfaces[i] = v0Interface + } + return &nodenetsvcV0.ConfigureContainerNetworkingResponse{ + Interfaces: v0Interfaces, + }, nil +} + +func (s *v0ServiceWrapper) ConfigureNetworking(ctx context.Context, req *nodenetsvcV0.ConfigureNetworkingRequest) (*nodenetsvcV0.ConfigureNetworkingResponse, error) { + log.G(ctx).WithField("req", req).Info("ConfigureNetworking request") + v1Req := &nodenetsvc.ConfigureNetworkingRequest{ + ContainerID: req.ContainerID, + RequestType: nodenetsvc.RequestType(req.RequestType), + } + _, err := s.s.ConfigureNetworking(ctx, v1Req) + if err != nil { + return nil, err + } + return &nodenetsvcV0.ConfigureNetworkingResponse{}, nil +} + +//nolint:stylecheck +func (s *v0ServiceWrapper) GetHostLocalIpAddress(ctx context.Context, req *nodenetsvcV0.GetHostLocalIpAddressRequest) (*nodenetsvcV0.GetHostLocalIpAddressResponse, error) { + return &nodenetsvcV0.GetHostLocalIpAddressResponse{IpAddr: ""}, nil +} + +func (s *v0ServiceWrapper) PingNodeNetworkService(ctx context.Context, req *nodenetsvcV0.PingNodeNetworkServiceRequest) (*nodenetsvcV0.PingNodeNetworkServiceResponse, error) { + return &nodenetsvcV0.PingNodeNetworkServiceResponse{}, nil +}