diff --git a/pkg/networkservice/common/mechanisms/kernel/client.go b/pkg/networkservice/common/mechanisms/kernel/client.go index 60aac1093..e3f092503 100644 --- a/pkg/networkservice/common/mechanisms/kernel/client.go +++ b/pkg/networkservice/common/mechanisms/kernel/client.go @@ -36,7 +36,7 @@ import ( type kernelMechanismClient struct { interfaceName string - interfaceNameGenerator func() (string, error) + interfaceNameGenerator func(ns string) (string, error) } // NewClient - returns client that sets kernel preferred mechanism @@ -70,7 +70,7 @@ func (k *kernelMechanismClient) manageMechanismPreferences(request *networkservi var updated = false for _, m := range request.GetRequestMechanismPreferences() { if mechanism := kernelmech.ToMechanism(m); mechanism != nil { - if err := k.updateMechanism(mechanism); err != nil { + if err := k.updateMechanism(request.GetConnection().GetNetworkService(), mechanism); err != nil { return err } mechanism.SetNetNSURL(netNSURL) @@ -83,7 +83,7 @@ func (k *kernelMechanismClient) manageMechanismPreferences(request *networkservi } mechanism := kernelmech.ToMechanism(kernelmech.New(netNSURL)) - if err := k.updateMechanism(mechanism); err != nil { + if err := k.updateMechanism(request.GetConnection().GetNetworkService(), mechanism); err != nil { return err } @@ -91,12 +91,12 @@ func (k *kernelMechanismClient) manageMechanismPreferences(request *networkservi return nil } -func (k *kernelMechanismClient) updateMechanism(mechanism *kernelmech.Mechanism) error { +func (k *kernelMechanismClient) updateMechanism(ns string, mechanism *kernelmech.Mechanism) error { if mechanism.GetInterfaceName() == "" { if k.interfaceName != "" { mechanism.SetInterfaceName(k.interfaceName) } else { - ifname, err := k.interfaceNameGenerator() + ifname, err := k.interfaceNameGenerator(ns) if err != nil { return errors.Wrap(err, "Failed to generate kernel interface name") } diff --git a/pkg/networkservice/common/mechanisms/kernel/client_test.go b/pkg/networkservice/common/mechanisms/kernel/client_test.go index b008599dd..dc7144355 100644 --- a/pkg/networkservice/common/mechanisms/kernel/client_test.go +++ b/pkg/networkservice/common/mechanisms/kernel/client_test.go @@ -81,7 +81,7 @@ func TestKernelMechanismClient_ShouldSetValidNetNSURL(t *testing.T) { func TestKernelMechanismClient_ShouldSetRandomInteraceName(t *testing.T) { c := kernel.NewClient() - req := &networkservice.NetworkServiceRequest{} + req := &networkservice.NetworkServiceRequest{Connection: &networkservice.Connection{NetworkService: "nsm"}} _, err := c.Request(context.Background(), req) require.NoError(t, err) @@ -91,12 +91,12 @@ func TestKernelMechanismClient_ShouldSetRandomInteraceName(t *testing.T) { require.Len(t, ifname, kernelmech.LinuxIfMaxLength) require.True(t, strings.HasPrefix(ifname, "nsm")) for i := 0; i < kernelmech.LinuxIfMaxLength; i++ { - require.Contains(t, nanoid.DefaultAlphabet, string(ifname[i])) + require.Contains(t, nanoid.DefaultAlphabet+"-", string(ifname[i])) } } func TestKernelMechanismClient_FailedToGenerateRandomName(t *testing.T) { - c := kernel.NewClient(kernel.WithInterfaceNameGenerator(func() (string, error) { + c := kernel.NewClient(kernel.WithInterfaceNameGenerator(func(_ string) (string, error) { return "", errors.New("failed to generate bytes") })) req := &networkservice.NetworkServiceRequest{} diff --git a/pkg/networkservice/common/mechanisms/kernel/option.go b/pkg/networkservice/common/mechanisms/kernel/option.go index d36e318a0..f927ec11f 100644 --- a/pkg/networkservice/common/mechanisms/kernel/option.go +++ b/pkg/networkservice/common/mechanisms/kernel/option.go @@ -20,7 +20,7 @@ package kernel type options struct { interfaceName string - interfaceNameGenerator func() (string, error) + interfaceNameGenerator func(ns string) (string, error) } // Option is an option pattern for kernelMechanismClient/Server @@ -34,7 +34,7 @@ func WithInterfaceName(interfaceName string) Option { } // WithInterfaceNameGenerator sets a generator for generating random interface names -func WithInterfaceNameGenerator(generator func() (string, error)) Option { +func WithInterfaceNameGenerator(generator func(ns string) (string, error)) Option { return func(o *options) { o.interfaceNameGenerator = generator } diff --git a/pkg/networkservice/common/mechanisms/kernel/server.go b/pkg/networkservice/common/mechanisms/kernel/server.go index 4f66c9584..b57343c18 100644 --- a/pkg/networkservice/common/mechanisms/kernel/server.go +++ b/pkg/networkservice/common/mechanisms/kernel/server.go @@ -34,7 +34,7 @@ import ( type kernelMechanismServer struct { interfaceName string - interfaceNameGenerator func() (string, error) + interfaceNameGenerator func(string) (string, error) } // NewServer - creates a NetworkServiceServer that requests a kernel interface and populates the netns inode @@ -58,7 +58,7 @@ func (m *kernelMechanismServer) Request(ctx context.Context, request *networkser if m.interfaceName != "" { mechanism.SetInterfaceName(m.interfaceName) } else { - ifname, err := m.interfaceNameGenerator() + ifname, err := m.interfaceNameGenerator(request.GetConnection().GetNetworkService()) if err != nil { return nil, errors.Wrap(err, "Failed to generate kernel interface name") } diff --git a/pkg/networkservice/common/mechanisms/kernel/server_test.go b/pkg/networkservice/common/mechanisms/kernel/server_test.go index 90ddb7c3a..b7cc5bc2a 100644 --- a/pkg/networkservice/common/mechanisms/kernel/server_test.go +++ b/pkg/networkservice/common/mechanisms/kernel/server_test.go @@ -80,7 +80,8 @@ func TestKernelMechanismServer_ShouldSetRandomInteraceName(t *testing.T) { s := kernel.NewServer() req := &networkservice.NetworkServiceRequest{ Connection: &networkservice.Connection{ - Mechanism: kernelmech.New(""), + Mechanism: kernelmech.New(""), + NetworkService: "nsm-dfs422343tsdf543", }, } @@ -91,7 +92,7 @@ func TestKernelMechanismServer_ShouldSetRandomInteraceName(t *testing.T) { require.Len(t, ifname, kernelmech.LinuxIfMaxLength) require.True(t, strings.HasPrefix(ifname, "nsm")) for i := 0; i < kernelmech.LinuxIfMaxLength; i++ { - require.Contains(t, nanoid.DefaultAlphabet, string(ifname[i])) + require.Contains(t, nanoid.DefaultAlphabet+"-", string(ifname[i])) } // Refresh @@ -102,7 +103,7 @@ func TestKernelMechanismServer_ShouldSetRandomInteraceName(t *testing.T) { } func TestKernelMechanismServer_FailedToGenerateRandomName(t *testing.T) { - s := kernel.NewServer(kernel.WithInterfaceNameGenerator(func() (string, error) { + s := kernel.NewServer(kernel.WithInterfaceNameGenerator(func(_ string) (string, error) { return "", errors.New("failed to generate bytes") })) req := &networkservice.NetworkServiceRequest{ diff --git a/pkg/tools/nanoid/generator.go b/pkg/tools/nanoid/generator.go index 4e6f43e6d..e02fd23ff 100644 --- a/pkg/tools/nanoid/generator.go +++ b/pkg/tools/nanoid/generator.go @@ -26,7 +26,7 @@ import ( const ( // DefaultAlphabet is the default alphabet for the generator which can be used to generate kernel interface names - DefaultAlphabet = "!\"#$&'()*+,-.012456789;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~" + DefaultAlphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" ) type generatorOpts struct { diff --git a/pkg/tools/nanoid/utils.go b/pkg/tools/nanoid/utils.go index c685b29c2..4783f362e 100644 --- a/pkg/tools/nanoid/utils.go +++ b/pkg/tools/nanoid/utils.go @@ -22,19 +22,17 @@ import ( kernelmech "github.com/networkservicemesh/api/pkg/api/networkservice/mechanisms/kernel" ) -const ( - ifPrefix = "nsm" -) - // GenerateLinuxInterfaceName - returns a random interface name with "nsm" prefix // to achieve a 1% chance of name collision, you need to generate approximately 68 billon names -func GenerateLinuxInterfaceName() (string, error) { - ifIDLen := kernelmech.LinuxIfMaxLength - len(ifPrefix) +func GenerateLinuxInterfaceName(ns string) (string, error) { + maxServiceName := kernelmech.LinuxIfMaxLength - 5 + if len(ns) > maxServiceName { + ns = ns[:maxServiceName] + } + ifIDLen := kernelmech.LinuxIfMaxLength - len(ns) - 1 id, err := GenerateString(ifIDLen) if err != nil { return "", err } - name := fmt.Sprintf("%s%s", ifPrefix, id) - - return name, nil + return fmt.Sprintf("%v-%v", ns, id), nil }