github.com/zhyoulun/cilium@v1.6.12/pkg/netns/netns.go (about) 1 // Copyright 2019 Authors of Cilium 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package netns 16 17 import ( 18 "fmt" 19 "io/ioutil" 20 "os/exec" 21 "path/filepath" 22 "strings" 23 24 "github.com/containernetworking/plugins/pkg/ns" 25 "github.com/vishvananda/netlink" 26 ) 27 28 // RemoveIfFromNetNSIfExists removes the given interface from the given 29 // network namespace. 30 // 31 // If the interface does not exist, no error will be returned. 32 func RemoveIfFromNetNSIfExists(netNS ns.NetNS, ifName string) error { 33 return netNS.Do(func(_ ns.NetNS) error { 34 l, err := netlink.LinkByName(ifName) 35 if err != nil { 36 if strings.Contains(err.Error(), "Link not found") { 37 return nil 38 } 39 return err 40 } 41 return netlink.LinkDel(l) 42 }) 43 } 44 45 // RemoveIfFromNetNSWithNameIfBothExist removes the given interface from 46 // the given network namespace identified by its name. 47 // 48 // If either the interface or the namespace do not exist, no error will 49 // be returned. 50 func RemoveIfFromNetNSWithNameIfBothExist(netNSName, ifName string) error { 51 netNS, err := ns.GetNS(netNSPath(netNSName)) 52 if err != nil { 53 if _, ok := err.(ns.NSPathNotExistErr); ok { 54 return nil 55 } 56 return err 57 } 58 return RemoveIfFromNetNSIfExists(netNS, ifName) 59 } 60 61 // ReplaceNetNSWithName creates a network namespace with the given name. 62 // If such netns already exists from a previous run, it will be removed 63 // and then re-created to avoid any previous state of the netns. 64 // 65 // FIXME: replace "ip-netns" invocations with native Go code 66 func ReplaceNetNSWithName(netNSName string) (ns.NetNS, error) { 67 path := netNSPath(netNSName) 68 69 if err := ns.IsNSorErr(path); err == nil { 70 if err := exec.Command("ip", "netns", "del", netNSName).Run(); err != nil { 71 return nil, fmt.Errorf("Unable to delete named netns %s: %s", netNSName, err) 72 } 73 } 74 75 if err := exec.Command("ip", "netns", "add", netNSName).Run(); err != nil { 76 return nil, fmt.Errorf("Unable to create named netns %s: %s", netNSName, err) 77 } 78 79 ns, err := ns.GetNS(path) 80 if err != nil { 81 return nil, fmt.Errorf("Unable to open netns %s: %s", path, err) 82 } 83 84 return ns, nil 85 } 86 87 // RemoveNetNSWithName removes the given named network namespace. 88 // 89 // FIXME: replace "ip-netns" invocations with native Go code 90 func RemoveNetNSWithName(netNSName string) error { 91 if out, err := exec.Command("ip", "netns", "del", netNSName).CombinedOutput(); err != nil { 92 return fmt.Errorf("Unable to delete named netns %s: %s %s", netNSName, out, err) 93 } 94 95 return nil 96 } 97 98 // ListNamedNetNSWithPrefix returns list of named network namespaces which name 99 // starts with the given prefix. 100 func ListNamedNetNSWithPrefix(prefix string) ([]string, error) { 101 entries, err := ioutil.ReadDir(netNSRootDir()) 102 if err != nil { 103 return nil, err 104 } 105 106 ns := make([]string, 0) 107 for _, e := range entries { 108 if !e.IsDir() && strings.HasPrefix(e.Name(), prefix) { 109 ns = append(ns, e.Name()) 110 } 111 } 112 113 return ns, nil 114 } 115 116 func netNSPath(name string) string { 117 return filepath.Join(netNSRootDir(), name) 118 } 119 120 func netNSRootDir() string { 121 return filepath.Join("/", "var", "run", "netns") 122 }