github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/controller/pkg/aclprovider/ipsetprovider.go (about) 1 // +build linux darwin 2 3 package provider 4 5 import ( 6 "fmt" 7 "os/exec" 8 "strings" 9 10 "github.com/aporeto-inc/go-ipset/ipset" 11 "go.uber.org/zap" 12 ) 13 14 // IpsetProvider returns a fabric for Ipset. 15 type IpsetProvider interface { 16 NewIpset(name string, ipsetType string, p *ipset.Params) (Ipset, error) 17 GetIpset(name string) Ipset 18 DestroyAll(prefix string) error 19 ListIPSets() ([]string, error) 20 } 21 22 // Ipset is an abstraction of all the methods an implementation of userspace 23 // ipsets need to provide. 24 type Ipset interface { 25 Add(entry string, timeout int) error 26 AddOption(entry string, option string, timeout int) error 27 Del(entry string) error 28 Destroy() error 29 Flush() error 30 Test(entry string) (bool, error) 31 } 32 33 type goIpsetProvider struct{} 34 35 func ipsetCreateBitmapPort(setname string) error { 36 //Bitmap type is not supported by the ipset library 37 path, _ := exec.LookPath("ipset") 38 out, err := exec.Command(path, "create", setname, "bitmap:port", "range", "0-65535", "timeout", "0").CombinedOutput() 39 if err != nil { 40 if strings.Contains(string(out), "set with the same name already exists") { 41 zap.L().Warn("Set already exists - cleaning up", zap.String("set name", setname)) 42 // Clean up the existing set 43 if _, cerr := exec.Command(path, "-F", setname).CombinedOutput(); cerr != nil { 44 return fmt.Errorf("Failed to clean up existing ipset: %s", err) 45 } 46 return nil 47 } 48 zap.L().Error("Unable to create set", zap.String("set name", setname), zap.String("ipset-output", string(out))) 49 } 50 return err 51 } 52 53 // NewIpset returns an IpsetProvider interface based on the go-ipset 54 // external package. 55 func (i *goIpsetProvider) NewIpset(name string, ipsetType string, p *ipset.Params) (Ipset, error) { 56 // Check if hashtype is a type of hash 57 if strings.HasPrefix(ipsetType, "hash:") { 58 return ipset.New(name, ipsetType, p) 59 } 60 61 if err := ipsetCreateBitmapPort(name); err != nil { 62 return nil, err 63 } 64 65 return &ipset.IPSet{Name: name}, nil 66 } 67 68 // GetIpset gets the ipset object from the name. 69 func (i *goIpsetProvider) GetIpset(name string) Ipset { 70 return &ipset.IPSet{ 71 Name: name, 72 } 73 } 74 75 // DestroyAll destroys all the ipsets - it will fail if there are existing references 76 func (i *goIpsetProvider) DestroyAll(prefix string) error { 77 78 return ipset.DestroyAll() 79 } 80 81 func (i *goIpsetProvider) ListIPSets() ([]string, error) { 82 83 path, err := exec.LookPath("ipset") 84 if err != nil { 85 return nil, fmt.Errorf("ipset command not found: %s", err) 86 } 87 88 out, err := exec.Command(path, "-L", "-name").CombinedOutput() 89 if err != nil { 90 return nil, fmt.Errorf("unable to list ipsets:%s", err) 91 } 92 93 return strings.Split(string(out), "\n"), nil 94 } 95 96 // NewGoIPsetProvider Return a Go IPSet Provider 97 func NewGoIPsetProvider() IpsetProvider { 98 return &goIpsetProvider{} 99 }