1
2
3
4 package main
5
6 import (
7 "flag"
8 "fmt"
9 "log"
10 "net"
11 "os"
12 "sort"
13
14 "github.com/vishvananda/netlink"
15 )
16
17 type command struct {
18 Function func([]string)
19 Description string
20 ArgCount int
21 }
22
23 var (
24 commands = map[string]command{
25 "protocol": {cmdProtocol, "prints the protocol version", 0},
26 "create": {cmdCreate, "creates a new ipset", 2},
27 "destroy": {cmdDestroy, "creates a new ipset", 1},
28 "list": {cmdList, "list specific ipset", 1},
29 "listall": {cmdListAll, "list all ipsets", 0},
30 "add": {cmdAddDel(netlink.IpsetAdd), "add entry", 2},
31 "del": {cmdAddDel(netlink.IpsetDel), "delete entry", 2},
32 "test": {cmdTest, "test whether an entry is in a set or not", 2},
33 }
34
35 timeoutVal *uint32
36 timeout = flag.Int("timeout", -1, "timeout, negative means omit the argument")
37 comment = flag.String("comment", "", "comment")
38 withComments = flag.Bool("with-comments", false, "create set with comment support")
39 withCounters = flag.Bool("with-counters", false, "create set with counters support")
40 withSkbinfo = flag.Bool("with-skbinfo", false, "create set with skbinfo support")
41 replace = flag.Bool("replace", false, "replace existing set/entry")
42 )
43
44 func main() {
45 flag.Parse()
46 args := flag.Args()
47
48 if len(args) < 1 {
49 printUsage()
50 os.Exit(1)
51 }
52
53 if *timeout >= 0 {
54 v := uint32(*timeout)
55 timeoutVal = &v
56 }
57
58 log.SetFlags(log.Lshortfile)
59
60 cmdName := args[0]
61 args = args[1:]
62
63 cmd, exist := commands[cmdName]
64 if !exist {
65 fmt.Printf("Unknown command '%s'\n\n", cmdName)
66 printUsage()
67 os.Exit(1)
68 }
69
70 if cmd.ArgCount != len(args) {
71 fmt.Printf("Invalid number of arguments. expected=%d given=%d\n", cmd.ArgCount, len(args))
72 os.Exit(1)
73 }
74
75 cmd.Function(args)
76 }
77
78 func printUsage() {
79 fmt.Printf("Usage: %s COMMAND [args] [-flags]\n\n", os.Args[0])
80 names := make([]string, 0, len(commands))
81 for name := range commands {
82 names = append(names, name)
83 }
84 sort.Strings(names)
85 fmt.Println("Available commands:")
86 for _, name := range names {
87 fmt.Printf(" %-15v %s\n", name, commands[name].Description)
88 }
89 fmt.Println("\nAvailable flags:")
90 flag.PrintDefaults()
91 }
92
93 func cmdProtocol(_ []string) {
94 protocol, minProto, err := netlink.IpsetProtocol()
95 check(err)
96 log.Println("Protocol:", protocol, "min:", minProto)
97 }
98
99 func cmdCreate(args []string) {
100 err := netlink.IpsetCreate(args[0], args[1], netlink.IpsetCreateOptions{
101 Replace: *replace,
102 Timeout: timeoutVal,
103 Comments: *withComments,
104 Counters: *withCounters,
105 Skbinfo: *withSkbinfo,
106 })
107 check(err)
108 }
109
110 func cmdDestroy(args []string) {
111 check(netlink.IpsetDestroy(args[0]))
112 }
113
114 func cmdList(args []string) {
115 result, err := netlink.IpsetList(args[0])
116 check(err)
117 log.Printf("%+v", result)
118 }
119
120 func cmdListAll(args []string) {
121 result, err := netlink.IpsetListAll()
122 check(err)
123 for _, ipset := range result {
124 log.Printf("%+v", ipset)
125 }
126 }
127
128 func cmdAddDel(f func(string, *netlink.IPSetEntry) error) func([]string) {
129 return func(args []string) {
130 setName := args[0]
131 element := args[1]
132
133 mac, _ := net.ParseMAC(element)
134 entry := netlink.IPSetEntry{
135 Timeout: timeoutVal,
136 MAC: mac,
137 Comment: *comment,
138 Replace: *replace,
139 }
140
141 check(f(setName, &entry))
142 }
143 }
144
145 func cmdTest(args []string) {
146 setName := args[0]
147 element := args[1]
148 ip := net.ParseIP(element)
149 entry := &netlink.IPSetEntry{
150 Timeout: timeoutVal,
151 IP: ip,
152 Comment: *comment,
153 Replace: *replace,
154 }
155 exist, err := netlink.IpsetTest(setName, entry)
156 check(err)
157 log.Printf("existence: %t\n", exist)
158 }
159
160
161 func check(err error) {
162 if err != nil {
163 panic(err)
164 }
165 }
166
View as plain text