Skip to content

Commit

Permalink
Use network service for generating iface name on nse side (networkser…
Browse files Browse the repository at this point in the history
…vicemesh#1644)

* use network service for generating iface name on nse side

Signed-off-by: denis-tingaikin <denis.tingajkin@xored.com>

* update alphabet

Signed-off-by: denis-tingaikin <denis.tingajkin@xored.com>

* fix tests

Signed-off-by: denis-tingaikin <denis.tingajkin@xored.com>

---------

Signed-off-by: denis-tingaikin <denis.tingajkin@xored.com>
  • Loading branch information
denis-tingaikin authored and NikitaSkrynnik committed Jul 24, 2024
1 parent 9648c4a commit 16b5ab1
Show file tree
Hide file tree
Showing 7 changed files with 24 additions and 25 deletions.
10 changes: 5 additions & 5 deletions pkg/networkservice/common/mechanisms/kernel/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -83,20 +83,20 @@ 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
}

request.MechanismPreferences = append(request.GetMechanismPreferences(), mechanism.Mechanism)
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")
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/networkservice/common/mechanisms/kernel/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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{}
Expand Down
4 changes: 2 additions & 2 deletions pkg/networkservice/common/mechanisms/kernel/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/networkservice/common/mechanisms/kernel/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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")
}
Expand Down
7 changes: 4 additions & 3 deletions pkg/networkservice/common/mechanisms/kernel/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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",
},
}

Expand All @@ -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
Expand All @@ -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{
Expand Down
2 changes: 1 addition & 1 deletion pkg/tools/nanoid/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
16 changes: 7 additions & 9 deletions pkg/tools/nanoid/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

0 comments on commit 16b5ab1

Please sign in to comment.