github.com/zhuohuang-hust/src-cbuild@v0.0.0-20230105071821-c7aab3e7c840/mergeCode/libnetwork/ns/init_linux.go (about) 1 package ns 2 3 import ( 4 "fmt" 5 "os" 6 "os/exec" 7 "strings" 8 "sync" 9 "syscall" 10 11 log "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 ) 21 22 // Init initializes a new network namespace 23 func Init() { 24 var err error 25 initNs, err = netns.Get() 26 if err != nil { 27 log.Errorf("could not get initial namespace: %v", err) 28 } 29 initNl, err = netlink.NewHandle(getSupportedNlFamilies()...) 30 if err != nil { 31 log.Errorf("could not create netlink handle on initial namespace: %v", err) 32 } 33 } 34 35 // SetNamespace sets the initial namespace handler 36 func SetNamespace() error { 37 initOnce.Do(Init) 38 if err := netns.Set(initNs); err != nil { 39 linkInfo, linkErr := getLink() 40 if linkErr != nil { 41 linkInfo = linkErr.Error() 42 } 43 return fmt.Errorf("failed to set to initial namespace, %v, initns fd %d: %v", linkInfo, initNs, err) 44 } 45 return nil 46 } 47 48 // ParseHandlerInt transforms the namespace handler into an integer 49 func ParseHandlerInt() int { 50 return int(getHandler()) 51 } 52 53 // GetHandler returns the namespace handler 54 func getHandler() netns.NsHandle { 55 initOnce.Do(Init) 56 return initNs 57 } 58 59 func getLink() (string, error) { 60 return os.Readlink(fmt.Sprintf("/proc/%d/task/%d/ns/net", os.Getpid(), syscall.Gettid())) 61 } 62 63 // NlHandle returns the netlink handler 64 func NlHandle() *netlink.Handle { 65 initOnce.Do(Init) 66 return initNl 67 } 68 69 func getSupportedNlFamilies() []int { 70 fams := []int{syscall.NETLINK_ROUTE} 71 if err := loadXfrmModules(); err != nil { 72 if checkXfrmSocket() != nil { 73 log.Warnf("Could not load necessary modules for IPSEC rules: %v", err) 74 return fams 75 } 76 } 77 return append(fams, syscall.NETLINK_XFRM) 78 } 79 80 func loadXfrmModules() error { 81 if out, err := exec.Command("modprobe", "-va", "xfrm_user").CombinedOutput(); err != nil { 82 return fmt.Errorf("Running modprobe xfrm_user failed with message: `%s`, error: %v", strings.TrimSpace(string(out)), err) 83 } 84 if out, err := exec.Command("modprobe", "-va", "xfrm_algo").CombinedOutput(); err != nil { 85 return fmt.Errorf("Running modprobe xfrm_algo failed with message: `%s`, error: %v", strings.TrimSpace(string(out)), err) 86 } 87 return nil 88 } 89 90 // API check on required xfrm modules (xfrm_user, xfrm_algo) 91 func checkXfrmSocket() error { 92 fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, syscall.NETLINK_XFRM) 93 if err != nil { 94 return err 95 } 96 syscall.Close(fd) 97 return nil 98 }