aa82f49c4c024cba1618c3478e320d5eea44b33a
[vpp.git] / extras / hs-test / actions.go
1 package main
2
3 import (
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"
13         interfaces "github.com/edwarnicke/govpp/binapi/interface"
14         "github.com/edwarnicke/govpp/binapi/interface_types"
15         ip_types "github.com/edwarnicke/govpp/binapi/ip_types"
16         "github.com/edwarnicke/govpp/binapi/session"
17         "github.com/edwarnicke/govpp/binapi/vlib"
18         "github.com/edwarnicke/vpphelper"
19 )
20
21 func RegisterActions() {
22         cfgTable = make(map[string]func([]string) *ActionResult)
23         reg("echo-srv-internal", Configure2Veths)
24         reg("echo-cln-internal", Configure2Veths)
25         reg("echo-client", RunEchoClient)
26         reg("echo-server", RunEchoServer)
27         reg("vpp-proxy", ConfigureVppProxy)
28         reg("vpp-envoy", ConfigureEnvoyProxy)
29         reg("http-tps", ConfigureHttpTps)
30         reg("2veths", Configure2Veths)
31 }
32
33 func configureProxyTcp(ifName0, ipAddr0, ifName1, ipAddr1 string) ConfFn {
34         return func(ctx context.Context,
35                 vppConn api.Connection) error {
36
37                 _, err := configureAfPacket(ctx, vppConn, ifName0, ipAddr0)
38                 if err != nil {
39                         fmt.Printf("failed to create af packet: %v", err)
40                         return err
41                 }
42                 _, err = configureAfPacket(ctx, vppConn, ifName1, ipAddr1)
43                 if err != nil {
44                         fmt.Printf("failed to create af packet: %v", err)
45                         return err
46                 }
47                 return nil
48         }
49 }
50
51 func ConfigureVppProxy(args []string) *ActionResult {
52         ctx, cancel := newVppContext()
53         defer cancel()
54
55         con, vppErrCh := vpphelper.StartAndDialContext(ctx, vpphelper.WithVppConfig(configTemplate))
56         exitOnErrCh(ctx, cancel, vppErrCh)
57
58         confFn := configureProxyTcp("vpp0", "10.0.0.2/24", "vpp1", "10.0.1.2/24")
59         err := confFn(ctx, con)
60         if err != nil {
61                 return NewActionResult(err, ActionResultWithDesc("configuration failed"))
62         }
63         writeSyncFile(OkResult())
64         <-ctx.Done()
65         return nil
66 }
67
68 func ConfigureEnvoyProxy(args []string) *ActionResult {
69         var startup Stanza
70         startup.
71                 NewStanza("session").
72                 Append("enable").
73                 Append("use-app-socket-api").
74                 Append("evt_qs_memfd_seg").
75                 Append("event-queue-length 100000").Close()
76         ctx, cancel := newVppContext()
77         defer cancel()
78
79         con, vppErrCh := vpphelper.StartAndDialContext(ctx,
80                 vpphelper.WithVppConfig(configTemplate+startup.ToString()),
81                 vpphelper.WithRootDir("/tmp/vpp-envoy"))
82         exitOnErrCh(ctx, cancel, vppErrCh)
83
84         confFn := configureProxyTcp("vpp0", "10.0.0.2/24", "vpp1", "10.0.1.2/24")
85         err := confFn(ctx, con)
86         if err != nil {
87                 return NewActionResult(err, ActionResultWithDesc("configuration failed"))
88         }
89         err0 := exechelper.Run("chmod 777 -R /tmp/vpp-envoy")
90         if err0 != nil {
91                 return NewActionResult(err, ActionResultWithDesc("setting permissions failed"))
92         }
93         writeSyncFile(OkResult())
94         <-ctx.Done()
95         return nil
96 }
97
98 func getArgs() string {
99         s := ""
100         for i := 2; i < len(os.Args); i++ {
101                 s = s + " " + os.Args[i]
102         }
103         return s
104 }
105
106 func ApiCliInband(root, cmd string) *ActionResult {
107         ctx, _ := newVppContext()
108         con := vpphelper.DialContext(ctx, filepath.Join(root, "/var/run/vpp/api.sock"))
109         cliInband := vlib.CliInband{Cmd: cmd}
110         cliInbandReply, err := vlib.NewServiceClient(con).CliInband(ctx, &cliInband)
111         return NewActionResult(err, ActionResultWithStdout(cliInbandReply.Reply))
112 }
113
114 func RunEchoClient(args []string) *ActionResult {
115         outBuff := bytes.NewBuffer([]byte{})
116         errBuff := bytes.NewBuffer([]byte{})
117
118         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])
119         err := exechelper.Run(cmd,
120                 exechelper.WithStdout(outBuff), exechelper.WithStderr(errBuff),
121                 exechelper.WithStdout(os.Stdout), exechelper.WithStderr(os.Stderr))
122
123         return NewActionResult(err, ActionResultWithStdout(string(outBuff.String())),
124                 ActionResultWithStderr(string(errBuff.String())))
125 }
126
127 func RunEchoServer(args []string) *ActionResult {
128         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])
129         errCh := exechelper.Start(cmd)
130         select {
131         case err := <-errCh:
132                 writeSyncFile(NewActionResult(err, ActionResultWithDesc("echo_server: ")))
133         default:
134         }
135         writeSyncFile(OkResult())
136         return nil
137 }
138
139 func RunEchoSrvInternal() *ActionResult {
140         cmd := fmt.Sprintf("test echo server %s uri tcp://10.10.10.1/1234", getArgs())
141         return ApiCliInband("/tmp/2veths", cmd)
142 }
143
144 func RunEchoClnInternal() *ActionResult {
145         cmd := fmt.Sprintf("test echo client %s uri tcp://10.10.10.1/1234", getArgs())
146         return ApiCliInband("/tmp/2veths", cmd)
147 }
148 func configure2vethsTopo(ifName, interfaceAddress, namespaceId string, secret uint64) ConfFn {
149         return func(ctx context.Context,
150                 vppConn api.Connection) error {
151
152                 swIfIndex, err := configureAfPacket(ctx, vppConn, ifName, interfaceAddress)
153                 if err != nil {
154                         fmt.Printf("failed to create af packet: %v", err)
155                 }
156                 _, er := session.NewServiceClient(vppConn).AppNamespaceAddDelV2(ctx, &session.AppNamespaceAddDelV2{
157                         Secret:      secret,
158                         SwIfIndex:   swIfIndex,
159                         NamespaceID: namespaceId,
160                 })
161                 if er != nil {
162                         fmt.Printf("add app namespace: %v", err)
163                         return err
164                 }
165
166                 _, er1 := session.NewServiceClient(vppConn).SessionEnableDisable(ctx, &session.SessionEnableDisable{
167                         IsEnable: true,
168                 })
169                 if er1 != nil {
170                         fmt.Printf("session enable %v", err)
171                         return err
172                 }
173                 return nil
174         }
175 }
176
177 func Configure2Veths(args []string) *ActionResult {
178         var startup Stanza
179         startup.
180                 NewStanza("session").
181                 Append("enable").
182                 Append("use-app-socket-api").Close()
183
184         ctx, cancel := newVppContext()
185         defer cancel()
186         con, vppErrCh := vpphelper.StartAndDialContext(ctx,
187                 vpphelper.WithVppConfig(configTemplate+startup.ToString()),
188                 vpphelper.WithRootDir(fmt.Sprintf("/tmp/%s", args[1])))
189         exitOnErrCh(ctx, cancel, vppErrCh)
190
191         var fn func(context.Context, api.Connection) error
192         if args[2] == "srv" {
193                 fn = configure2vethsTopo("vppsrv", "10.10.10.1/24", "1", 1)
194         } else {
195                 fn = configure2vethsTopo("vppcln", "10.10.10.2/24", "2", 2)
196         }
197         err := fn(ctx, con)
198         if err != nil {
199                 return NewActionResult(err, ActionResultWithDesc("configuration failed"))
200         }
201         writeSyncFile(OkResult())
202         <-ctx.Done()
203         return nil
204 }
205
206 func configureAfPacket(ctx context.Context, vppCon api.Connection,
207         name, interfaceAddress string) (interface_types.InterfaceIndex, error) {
208         ifaceClient := interfaces.NewServiceClient(vppCon)
209         afPacketCreate := &af_packet.AfPacketCreateV2{
210                 UseRandomHwAddr: true,
211                 HostIfName:      name,
212                 NumRxQueues:     1,
213         }
214         afPacketCreateRsp, err := af_packet.NewServiceClient(vppCon).AfPacketCreateV2(ctx, afPacketCreate)
215         if err != nil {
216                 fmt.Printf("failed to create af packet: %v", err)
217                 return 0, err
218         }
219         _, err = ifaceClient.SwInterfaceSetFlags(ctx, &interfaces.SwInterfaceSetFlags{
220                 SwIfIndex: afPacketCreateRsp.SwIfIndex,
221                 Flags:     interface_types.IF_STATUS_API_FLAG_ADMIN_UP,
222         })
223         if err != nil {
224                 fmt.Printf("set interface state up failed: %v\n", err)
225                 return 0, err
226         }
227         ipPrefix, err := ip_types.ParseAddressWithPrefix(interfaceAddress)
228         if err != nil {
229                 fmt.Printf("parse ip address %v\n", err)
230                 return 0, err
231         }
232         ipAddress := &interfaces.SwInterfaceAddDelAddress{
233                 IsAdd:     true,
234                 SwIfIndex: afPacketCreateRsp.SwIfIndex,
235                 Prefix:    ipPrefix,
236         }
237         _, errx := ifaceClient.SwInterfaceAddDelAddress(ctx, ipAddress)
238         if errx != nil {
239                 fmt.Printf("add ip address %v\n", err)
240                 return 0, err
241         }
242         return afPacketCreateRsp.SwIfIndex, nil
243 }
244
245 func ConfigureHttpTps(args []string) *ActionResult {
246         ctx, cancel := newVppContext()
247         defer cancel()
248         con, vppErrCh := vpphelper.StartAndDialContext(ctx,
249                 vpphelper.WithVppConfig(configTemplate))
250         exitOnErrCh(ctx, cancel, vppErrCh)
251
252         confFn := configureProxyTcp("vpp0", "10.0.0.2/24", "vpp1", "10.0.1.2/24")
253         err := confFn(ctx, con)
254         if err != nil {
255                 return NewActionResult(err, ActionResultWithDesc("configuration failed"))
256         }
257
258         _, err = session.NewServiceClient(con).SessionEnableDisable(ctx, &session.SessionEnableDisable{
259                 IsEnable: true,
260         })
261         if err != nil {
262                 return NewActionResult(err, ActionResultWithDesc("configuration failed"))
263         }
264         Vppcli("", "http tps uri tcp://0.0.0.0/8080")
265         writeSyncFile(OkResult())
266         <-ctx.Done()
267         return nil
268 }