blob: 9885f87b87d36a7798ed7b63e4842d9602e726cc [file] [log] [blame]
Filip Tehlar229f5fc2022-08-09 14:44:47 +00001package main
2
3import (
4 "bytes"
5 "context"
6 "fmt"
7 "os"
8 "path/filepath"
9
10 "git.fd.io/govpp.git/api"
11 "github.com/edwarnicke/exechelper"
12 "github.com/edwarnicke/govpp/binapi/af_packet"
Maros Ondrejicka0db15752022-10-12 22:58:01 +020013 "github.com/edwarnicke/govpp/binapi/ethernet_types"
Filip Tehlar229f5fc2022-08-09 14:44:47 +000014 interfaces "github.com/edwarnicke/govpp/binapi/interface"
15 "github.com/edwarnicke/govpp/binapi/interface_types"
16 ip_types "github.com/edwarnicke/govpp/binapi/ip_types"
17 "github.com/edwarnicke/govpp/binapi/session"
18 "github.com/edwarnicke/govpp/binapi/vlib"
19 "github.com/edwarnicke/vpphelper"
20)
21
Filip Tehlar1a9dc752022-11-22 12:49:22 +010022type ConfFn func(context.Context, api.Connection) error
23
24type Actions struct {
Filip Tehlar229f5fc2022-08-09 14:44:47 +000025}
26
27func configureProxyTcp(ifName0, ipAddr0, ifName1, ipAddr1 string) ConfFn {
28 return func(ctx context.Context,
29 vppConn api.Connection) error {
30
31 _, err := configureAfPacket(ctx, vppConn, ifName0, ipAddr0)
32 if err != nil {
33 fmt.Printf("failed to create af packet: %v", err)
34 return err
35 }
36 _, err = configureAfPacket(ctx, vppConn, ifName1, ipAddr1)
37 if err != nil {
38 fmt.Printf("failed to create af packet: %v", err)
39 return err
40 }
41 return nil
42 }
43}
44
Filip Tehlar1a9dc752022-11-22 12:49:22 +010045func (a *Actions) RunHttpCliSrv(args []string) *ActionResult {
Filip Tehlarb15a0002022-11-10 12:34:17 +010046 cmd := fmt.Sprintf("http cli server")
Filip Tehlar1a9dc752022-11-22 12:49:22 +010047 return ApiCliInband("/tmp/Configure2Veths", cmd)
Filip Tehlarb15a0002022-11-10 12:34:17 +010048}
49
Filip Tehlar1a9dc752022-11-22 12:49:22 +010050func (a *Actions) RunHttpCliCln(args []string) *ActionResult {
Filip Tehlarb15a0002022-11-10 12:34:17 +010051 cmd := fmt.Sprintf("http cli client uri http://10.10.10.1/80 query %s", getArgs())
52 fmt.Println(cmd)
Filip Tehlar1a9dc752022-11-22 12:49:22 +010053 return ApiCliInband("/tmp/Configure2Veths", cmd)
Filip Tehlarb15a0002022-11-10 12:34:17 +010054}
55
Filip Tehlar1a9dc752022-11-22 12:49:22 +010056func (a *Actions) ConfigureVppProxy(args []string) *ActionResult {
Filip Tehlar229f5fc2022-08-09 14:44:47 +000057 ctx, cancel := newVppContext()
58 defer cancel()
59
60 con, vppErrCh := vpphelper.StartAndDialContext(ctx, vpphelper.WithVppConfig(configTemplate))
61 exitOnErrCh(ctx, cancel, vppErrCh)
62
63 confFn := configureProxyTcp("vpp0", "10.0.0.2/24", "vpp1", "10.0.1.2/24")
64 err := confFn(ctx, con)
65 if err != nil {
66 return NewActionResult(err, ActionResultWithDesc("configuration failed"))
67 }
68 writeSyncFile(OkResult())
69 <-ctx.Done()
70 return nil
71}
72
Filip Tehlar1a9dc752022-11-22 12:49:22 +010073func (a *Actions) ConfigureEnvoyProxy(args []string) *ActionResult {
Filip Tehlar229f5fc2022-08-09 14:44:47 +000074 var startup Stanza
75 startup.
76 NewStanza("session").
77 Append("enable").
78 Append("use-app-socket-api").
79 Append("evt_qs_memfd_seg").
80 Append("event-queue-length 100000").Close()
81 ctx, cancel := newVppContext()
82 defer cancel()
83
84 con, vppErrCh := vpphelper.StartAndDialContext(ctx,
85 vpphelper.WithVppConfig(configTemplate+startup.ToString()),
86 vpphelper.WithRootDir("/tmp/vpp-envoy"))
87 exitOnErrCh(ctx, cancel, vppErrCh)
88
89 confFn := configureProxyTcp("vpp0", "10.0.0.2/24", "vpp1", "10.0.1.2/24")
90 err := confFn(ctx, con)
91 if err != nil {
92 return NewActionResult(err, ActionResultWithDesc("configuration failed"))
93 }
94 err0 := exechelper.Run("chmod 777 -R /tmp/vpp-envoy")
95 if err0 != nil {
96 return NewActionResult(err, ActionResultWithDesc("setting permissions failed"))
97 }
98 writeSyncFile(OkResult())
99 <-ctx.Done()
100 return nil
101}
102
103func getArgs() string {
104 s := ""
105 for i := 2; i < len(os.Args); i++ {
106 s = s + " " + os.Args[i]
107 }
108 return s
109}
110
111func ApiCliInband(root, cmd string) *ActionResult {
112 ctx, _ := newVppContext()
113 con := vpphelper.DialContext(ctx, filepath.Join(root, "/var/run/vpp/api.sock"))
114 cliInband := vlib.CliInband{Cmd: cmd}
115 cliInbandReply, err := vlib.NewServiceClient(con).CliInband(ctx, &cliInband)
116 return NewActionResult(err, ActionResultWithStdout(cliInbandReply.Reply))
117}
118
Filip Tehlar1a9dc752022-11-22 12:49:22 +0100119func (a *Actions) RunEchoClient(args []string) *ActionResult {
Filip Tehlar229f5fc2022-08-09 14:44:47 +0000120 outBuff := bytes.NewBuffer([]byte{})
121 errBuff := bytes.NewBuffer([]byte{})
122
123 cmd := fmt.Sprintf("vpp_echo client socket-name /tmp/echo-cln/var/run/app_ns_sockets/2 use-app-socket-api uri %s://10.10.10.1/12344", args[2])
124 err := exechelper.Run(cmd,
125 exechelper.WithStdout(outBuff), exechelper.WithStderr(errBuff),
126 exechelper.WithStdout(os.Stdout), exechelper.WithStderr(os.Stderr))
127
128 return NewActionResult(err, ActionResultWithStdout(string(outBuff.String())),
129 ActionResultWithStderr(string(errBuff.String())))
130}
131
Filip Tehlar1a9dc752022-11-22 12:49:22 +0100132func (a *Actions) RunEchoServer(args []string) *ActionResult {
Filip Tehlar229f5fc2022-08-09 14:44:47 +0000133 cmd := fmt.Sprintf("vpp_echo server TX=RX socket-name /tmp/echo-srv/var/run/app_ns_sockets/1 use-app-socket-api uri %s://10.10.10.1/12344", args[2])
134 errCh := exechelper.Start(cmd)
135 select {
136 case err := <-errCh:
137 writeSyncFile(NewActionResult(err, ActionResultWithDesc("echo_server: ")))
138 default:
139 }
140 writeSyncFile(OkResult())
141 return nil
142}
143
Filip Tehlar1a9dc752022-11-22 12:49:22 +0100144func (a *Actions) RunEchoSrvInternal(args []string) *ActionResult {
Filip Tehlar229f5fc2022-08-09 14:44:47 +0000145 cmd := fmt.Sprintf("test echo server %s uri tcp://10.10.10.1/1234", getArgs())
Filip Tehlar1a9dc752022-11-22 12:49:22 +0100146 return ApiCliInband("/tmp/Configure2Veths", cmd)
Filip Tehlar229f5fc2022-08-09 14:44:47 +0000147}
148
Filip Tehlar1a9dc752022-11-22 12:49:22 +0100149func (a *Actions) RunEchoClnInternal(args []string) *ActionResult {
Filip Tehlar229f5fc2022-08-09 14:44:47 +0000150 cmd := fmt.Sprintf("test echo client %s uri tcp://10.10.10.1/1234", getArgs())
Filip Tehlar1a9dc752022-11-22 12:49:22 +0100151 return ApiCliInband("/tmp/Configure2Veths", cmd)
Filip Tehlar229f5fc2022-08-09 14:44:47 +0000152}
Maros Ondrejicka0db15752022-10-12 22:58:01 +0200153
Filip Tehlar1a9dc752022-11-22 12:49:22 +0100154func (a *Actions) RunVclEchoServer(args []string) *ActionResult {
Maros Ondrejicka0db15752022-10-12 22:58:01 +0200155 f, err := os.Create("vcl_1.conf")
156 if err != nil {
157 return NewActionResult(err, ActionResultWithStderr(("create vcl config: ")))
158 }
159 fmt.Fprintf(f, vclTemplate, "/tmp/echo-srv/var/run/app_ns_sockets/1", "1")
160 f.Close()
161
162 os.Setenv("VCL_CONFIG", "/vcl_1.conf")
163 cmd := fmt.Sprintf("vcl_test_server -p %s 12346", args[2])
164 errCh := exechelper.Start(cmd)
165 select {
166 case err := <-errCh:
167 writeSyncFile(NewActionResult(err, ActionResultWithDesc("vcl_test_server: ")))
168 default:
169 }
170 writeSyncFile(OkResult())
171 return nil
172}
173
Filip Tehlar1a9dc752022-11-22 12:49:22 +0100174func (a *Actions) RunVclEchoClient(args []string) *ActionResult {
Maros Ondrejicka0db15752022-10-12 22:58:01 +0200175 outBuff := bytes.NewBuffer([]byte{})
176 errBuff := bytes.NewBuffer([]byte{})
177
178 f, err := os.Create("vcl_2.conf")
179 if err != nil {
180 return NewActionResult(err, ActionResultWithStderr(("create vcl config: ")))
181 }
182 fmt.Fprintf(f, vclTemplate, "/tmp/echo-cln/var/run/app_ns_sockets/2", "2")
183 f.Close()
184
185 os.Setenv("VCL_CONFIG", "/vcl_2.conf")
186 cmd := fmt.Sprintf("vcl_test_client -U -p %s 10.10.10.1 12346", args[2])
187 err = exechelper.Run(cmd,
188 exechelper.WithStdout(outBuff), exechelper.WithStderr(errBuff),
189 exechelper.WithStdout(os.Stdout), exechelper.WithStderr(os.Stderr))
190
191 return NewActionResult(err, ActionResultWithStdout(string(outBuff.String())),
192 ActionResultWithStderr(string(errBuff.String())))
193}
194
195func configure2vethsTopo(ifName, interfaceAddress, namespaceId string, secret uint64, optionalHardwareAddress ...string) ConfFn {
Filip Tehlar229f5fc2022-08-09 14:44:47 +0000196 return func(ctx context.Context,
197 vppConn api.Connection) error {
198
Maros Ondrejicka0db15752022-10-12 22:58:01 +0200199 var swIfIndex interface_types.InterfaceIndex
200 var err error
201 if optionalHardwareAddress == nil {
202 swIfIndex, err = configureAfPacket(ctx, vppConn, ifName, interfaceAddress)
203 } else {
204 swIfIndex, err = configureAfPacket(ctx, vppConn, ifName, interfaceAddress, optionalHardwareAddress[0])
205 }
Filip Tehlar229f5fc2022-08-09 14:44:47 +0000206 if err != nil {
207 fmt.Printf("failed to create af packet: %v", err)
208 }
209 _, er := session.NewServiceClient(vppConn).AppNamespaceAddDelV2(ctx, &session.AppNamespaceAddDelV2{
210 Secret: secret,
211 SwIfIndex: swIfIndex,
212 NamespaceID: namespaceId,
213 })
214 if er != nil {
215 fmt.Printf("add app namespace: %v", err)
216 return err
217 }
218
219 _, er1 := session.NewServiceClient(vppConn).SessionEnableDisable(ctx, &session.SessionEnableDisable{
220 IsEnable: true,
221 })
222 if er1 != nil {
223 fmt.Printf("session enable %v", err)
224 return err
225 }
226 return nil
227 }
228}
229
Filip Tehlar1a9dc752022-11-22 12:49:22 +0100230func (a *Actions) Configure2Veths(args []string) *ActionResult {
Filip Tehlar229f5fc2022-08-09 14:44:47 +0000231 var startup Stanza
232 startup.
233 NewStanza("session").
234 Append("enable").
235 Append("use-app-socket-api").Close()
236
237 ctx, cancel := newVppContext()
238 defer cancel()
239 con, vppErrCh := vpphelper.StartAndDialContext(ctx,
240 vpphelper.WithVppConfig(configTemplate+startup.ToString()),
241 vpphelper.WithRootDir(fmt.Sprintf("/tmp/%s", args[1])))
242 exitOnErrCh(ctx, cancel, vppErrCh)
243
244 var fn func(context.Context, api.Connection) error
245 if args[2] == "srv" {
246 fn = configure2vethsTopo("vppsrv", "10.10.10.1/24", "1", 1)
Maros Ondrejicka0db15752022-10-12 22:58:01 +0200247 } else if args[2] == "srv-with-preset-hw-addr" {
248 fn = configure2vethsTopo("vppsrv", "10.10.10.1/24", "1", 1, "00:00:5e:00:53:01")
Filip Tehlar229f5fc2022-08-09 14:44:47 +0000249 } else {
250 fn = configure2vethsTopo("vppcln", "10.10.10.2/24", "2", 2)
251 }
252 err := fn(ctx, con)
253 if err != nil {
254 return NewActionResult(err, ActionResultWithDesc("configuration failed"))
255 }
256 writeSyncFile(OkResult())
257 <-ctx.Done()
258 return nil
259}
260
261func configureAfPacket(ctx context.Context, vppCon api.Connection,
Maros Ondrejicka0db15752022-10-12 22:58:01 +0200262 name, interfaceAddress string, optionalHardwareAddress ...string) (interface_types.InterfaceIndex, error) {
263 var err error
Filip Tehlar229f5fc2022-08-09 14:44:47 +0000264 ifaceClient := interfaces.NewServiceClient(vppCon)
Maros Ondrejicka0db15752022-10-12 22:58:01 +0200265 afPacketCreate := af_packet.AfPacketCreateV2{
Filip Tehlar229f5fc2022-08-09 14:44:47 +0000266 UseRandomHwAddr: true,
267 HostIfName: name,
268 NumRxQueues: 1,
269 }
Maros Ondrejicka0db15752022-10-12 22:58:01 +0200270 if len(optionalHardwareAddress) > 0 {
271 afPacketCreate.HwAddr, err = ethernet_types.ParseMacAddress(optionalHardwareAddress[0])
272 if err != nil {
273 fmt.Printf("failed to parse mac address: %v", err)
274 return 0, err
275 }
276 afPacketCreate.UseRandomHwAddr = false
277 }
278 afPacketCreateRsp, err := af_packet.NewServiceClient(vppCon).AfPacketCreateV2(ctx, &afPacketCreate)
Filip Tehlar229f5fc2022-08-09 14:44:47 +0000279 if err != nil {
280 fmt.Printf("failed to create af packet: %v", err)
281 return 0, err
282 }
283 _, err = ifaceClient.SwInterfaceSetFlags(ctx, &interfaces.SwInterfaceSetFlags{
284 SwIfIndex: afPacketCreateRsp.SwIfIndex,
285 Flags: interface_types.IF_STATUS_API_FLAG_ADMIN_UP,
286 })
287 if err != nil {
288 fmt.Printf("set interface state up failed: %v\n", err)
289 return 0, err
290 }
291 ipPrefix, err := ip_types.ParseAddressWithPrefix(interfaceAddress)
292 if err != nil {
293 fmt.Printf("parse ip address %v\n", err)
294 return 0, err
295 }
296 ipAddress := &interfaces.SwInterfaceAddDelAddress{
297 IsAdd: true,
298 SwIfIndex: afPacketCreateRsp.SwIfIndex,
299 Prefix: ipPrefix,
300 }
301 _, errx := ifaceClient.SwInterfaceAddDelAddress(ctx, ipAddress)
302 if errx != nil {
303 fmt.Printf("add ip address %v\n", err)
304 return 0, err
305 }
306 return afPacketCreateRsp.SwIfIndex, nil
307}
308
Filip Tehlar1a9dc752022-11-22 12:49:22 +0100309func (a *Actions) ConfigureHttpTps(args []string) *ActionResult {
Filip Tehlar229f5fc2022-08-09 14:44:47 +0000310 ctx, cancel := newVppContext()
311 defer cancel()
312 con, vppErrCh := vpphelper.StartAndDialContext(ctx,
313 vpphelper.WithVppConfig(configTemplate))
314 exitOnErrCh(ctx, cancel, vppErrCh)
315
316 confFn := configureProxyTcp("vpp0", "10.0.0.2/24", "vpp1", "10.0.1.2/24")
317 err := confFn(ctx, con)
318 if err != nil {
319 return NewActionResult(err, ActionResultWithDesc("configuration failed"))
320 }
321
322 _, err = session.NewServiceClient(con).SessionEnableDisable(ctx, &session.SessionEnableDisable{
323 IsEnable: true,
324 })
325 if err != nil {
326 return NewActionResult(err, ActionResultWithDesc("configuration failed"))
327 }
328 Vppcli("", "http tps uri tcp://0.0.0.0/8080")
329 writeSyncFile(OkResult())
330 <-ctx.Done()
331 return nil
332}