github.com/Heebron/moby@v0.0.0-20221111184709-6eab4f55faf7/libnetwork/ns/init_linux.go (about) 1 package ns 2 3 import ( 4 "fmt" 5 "os/exec" 6 "strings" 7 "sync" 8 "syscall" 9 "time" 10 11 "github.com/sirupsen/logrus" 12 "github.com/vishvananda/netlink" 13 "github.com/vishvananda/netns" 14 ) 15 16 var ( 17 initNs netns.NsHandle 18 initNl *netlink.Handle 19 initOnce sync.Once 20 // NetlinkSocketsTimeout represents the default timeout duration for the sockets 21 NetlinkSocketsTimeout = 3 * time.Second 22 ) 23 24 // Init initializes a new network namespace 25 func Init() { 26 var err error 27 initNs, err = netns.Get() 28 if err != nil { 29 logrus.Errorf("could not get initial namespace: %v", err) 30 } 31 initNl, err = netlink.NewHandle(getSupportedNlFamilies()...) 32 if err != nil { 33 logrus.Errorf("could not create netlink handle on initial namespace: %v", err) 34 } 35 err = initNl.SetSocketTimeout(NetlinkSocketsTimeout) 36 if err != nil { 37 logrus.Warnf("Failed to set the timeout on the default netlink handle sockets: %v", err) 38 } 39 } 40 41 // ParseHandlerInt transforms the namespace handler into an integer 42 func ParseHandlerInt() int { 43 return int(getHandler()) 44 } 45 46 // GetHandler returns the namespace handler 47 func getHandler() netns.NsHandle { 48 initOnce.Do(Init) 49 return initNs 50 } 51 52 // NlHandle returns the netlink handler 53 func NlHandle() *netlink.Handle { 54 initOnce.Do(Init) 55 return initNl 56 } 57 58 func getSupportedNlFamilies() []int { 59 fams := []int{syscall.NETLINK_ROUTE} 60 // NETLINK_XFRM test 61 if err := checkXfrmSocket(); err != nil { 62 logrus.Warnf("Could not load necessary modules for IPSEC rules: %v", err) 63 } else { 64 fams = append(fams, syscall.NETLINK_XFRM) 65 } 66 // NETLINK_NETFILTER test 67 if err := loadNfConntrackModules(); err != nil { 68 if checkNfSocket() != nil { 69 logrus.Warnf("Could not load necessary modules for Conntrack: %v", err) 70 } else { 71 fams = append(fams, syscall.NETLINK_NETFILTER) 72 } 73 } else { 74 fams = append(fams, syscall.NETLINK_NETFILTER) 75 } 76 77 return fams 78 } 79 80 // API check on required xfrm modules (xfrm_user, xfrm_algo) 81 func checkXfrmSocket() error { 82 fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_XFRM) 83 if err != nil { 84 return err 85 } 86 syscall.Close(fd) 87 return nil 88 } 89 90 func loadNfConntrackModules() error { 91 if out, err := exec.Command("modprobe", "-va", "nf_conntrack").CombinedOutput(); err != nil { 92 return fmt.Errorf("Running modprobe nf_conntrack failed with message: `%s`, error: %v", strings.TrimSpace(string(out)), err) 93 } 94 if out, err := exec.Command("modprobe", "-va", "nf_conntrack_netlink").CombinedOutput(); err != nil { 95 return fmt.Errorf("Running modprobe nf_conntrack_netlink failed with message: `%s`, error: %v", strings.TrimSpace(string(out)), err) 96 } 97 return nil 98 } 99 100 // API check on required nf_conntrack* modules (nf_conntrack, nf_conntrack_netlink) 101 func checkNfSocket() error { 102 fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_NETFILTER) 103 if err != nil { 104 return err 105 } 106 syscall.Close(fd) 107 return nil 108 }