github.com/aristanetworks/goarista@v0.0.0-20240514173732-cca2755bbd44/netns/nslistener_linux.go (about)

     1  // Copyright (c) 2019 Arista Networks, Inc.
     2  // Use of this source code is governed by the Apache License 2.0
     3  // that can be found in the COPYING file.
     4  
     5  package netns
     6  
     7  import (
     8  	"errors"
     9  	"net"
    10  	"os"
    11  
    12  	"github.com/aristanetworks/goarista/dscp"
    13  	"github.com/aristanetworks/goarista/logger"
    14  )
    15  
    16  var hasMount = func(mountPoint string, logger logger.Logger) bool {
    17  	fd, err := os.Open("/proc/mounts")
    18  	if err != nil {
    19  		logger.Fatal("can't open /proc/mounts")
    20  	}
    21  	defer fd.Close()
    22  
    23  	return hasMountInProcMounts(fd, mountPoint)
    24  }
    25  
    26  func getNsDir() (string, error) {
    27  	fd, err := os.Open("/proc/mounts")
    28  	if err != nil {
    29  		return "", errors.New("can't open /proc/mounts")
    30  	}
    31  	defer fd.Close()
    32  
    33  	return getNsDirFromProcMounts(fd)
    34  }
    35  
    36  // NewNSListener creates a new net.Listener bound to a network namespace. The listening socket will
    37  // be bound to the specified local address and will have the specified tos.
    38  func NewNSListener(nsName string, addr *net.TCPAddr, tos byte, logger logger.Logger) (net.Listener,
    39  	error) {
    40  	return NewNSListenerWithCustomListener(nsName, addr, logger,
    41  		func() (net.Listener, error) {
    42  			return dscp.ListenTCPWithTOSLogger(addr, tos, logger)
    43  		})
    44  }
    45  
    46  // NewNSListenerWithCustomListener creates a new net.Listener bound to a network namespace. The
    47  // listener is created using listenerCreator. listenerCreator should create a listener that
    48  // binds to addr. listenerCreator may be called multiple times if the vrf is deleted and recreated.
    49  func NewNSListenerWithCustomListener(nsName string, addr *net.TCPAddr, logger logger.Logger,
    50  	listenerCreator ListenerCreator) (net.Listener, error) {
    51  	// The default namespace doesn't get recreated and avoid the watcher helps with environments
    52  	// that aren't setup for multiple namespaces (eg inside containers)
    53  	if nsName == "" || nsName == "default" {
    54  		return makeListener(nsName, listenerCreator)
    55  	}
    56  	nsDir, err := getNsDir()
    57  	if err != nil {
    58  		return nil, err
    59  	}
    60  	return newNSListenerWithDir(nsDir, nsName, addr, logger, listenerCreator)
    61  }