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