10 "git.fd.io/govpp.git/api"
11 "github.com/edwarnicke/exechelper"
12 "github.com/edwarnicke/govpp/binapi/af_packet"
13 "github.com/edwarnicke/govpp/binapi/ethernet_types"
14 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"
23 workDir, _ = os.Getwd()
26 type ConfFn func(context.Context, api.Connection) error
31 func configureProxyTcp(ifName0, ipAddr0, ifName1, ipAddr1 string) ConfFn {
32 return func(ctx context.Context,
33 vppConn api.Connection) error {
35 _, err := configureAfPacket(ctx, vppConn, ifName0, ipAddr0)
37 fmt.Printf("failed to create af packet: %v", err)
40 _, err = configureAfPacket(ctx, vppConn, ifName1, ipAddr1)
42 fmt.Printf("failed to create af packet: %v", err)
49 func (a *Actions) RunHttpCliSrv(args []string) *ActionResult {
50 cmd := fmt.Sprintf("http cli server")
51 return ApiCliInband(workDir, cmd)
54 func (a *Actions) RunHttpCliCln(args []string) *ActionResult {
55 cmd := fmt.Sprintf("http cli client uri http://10.10.10.1/80 query %s", getArgs())
57 return ApiCliInband(workDir, cmd)
60 func (a *Actions) ConfigureVppProxy(args []string) *ActionResult {
61 ctx, cancel := newVppContext()
64 con, vppErrCh := vpphelper.StartAndDialContext(ctx,
65 vpphelper.WithVppConfig(configTemplate),
66 vpphelper.WithRootDir(workDir))
67 exitOnErrCh(ctx, cancel, vppErrCh)
69 confFn := configureProxyTcp("vpp0", "10.0.0.2/24", "vpp1", "10.0.1.2/24")
70 err := confFn(ctx, con)
72 return NewActionResult(err, ActionResultWithDesc("configuration failed"))
74 writeSyncFile(OkResult())
79 func (a *Actions) ConfigureEnvoyProxy(args []string) *ActionResult {
84 Append("use-app-socket-api").
85 Append("evt_qs_memfd_seg").
86 Append("event-queue-length 100000").Close()
87 ctx, cancel := newVppContext()
90 con, vppErrCh := vpphelper.StartAndDialContext(ctx,
91 vpphelper.WithVppConfig(configTemplate+startup.ToString()),
92 vpphelper.WithRootDir(workDir))
93 exitOnErrCh(ctx, cancel, vppErrCh)
95 confFn := configureProxyTcp("vpp0", "10.0.0.2/24", "vpp1", "10.0.1.2/24")
96 err := confFn(ctx, con)
98 return NewActionResult(err, ActionResultWithDesc("configuration failed"))
100 err0 := exechelper.Run("chmod 777 -R " + workDir)
102 return NewActionResult(err, ActionResultWithDesc("setting permissions failed"))
104 writeSyncFile(OkResult())
109 func getArgs() string {
111 for i := 2; i < len(os.Args); i++ {
112 s = s + " " + os.Args[i]
117 func ApiCliInband(root, cmd string) *ActionResult {
118 ctx, _ := newVppContext()
119 con := vpphelper.DialContext(ctx, filepath.Join(root, "/var/run/vpp/api.sock"))
120 cliInband := vlib.CliInband{Cmd: cmd}
121 cliInbandReply, err := vlib.NewServiceClient(con).CliInband(ctx, &cliInband)
122 return NewActionResult(err, ActionResultWithStdout(cliInbandReply.Reply))
125 func (a *Actions) RunEchoClient(args []string) *ActionResult {
126 outBuff := bytes.NewBuffer([]byte{})
127 errBuff := bytes.NewBuffer([]byte{})
129 cmd := fmt.Sprintf("vpp_echo client socket-name %s/var/run/app_ns_sockets/2 use-app-socket-api uri %s://10.10.10.1/12344", workDir, args[2])
130 err := exechelper.Run(cmd,
131 exechelper.WithStdout(outBuff), exechelper.WithStderr(errBuff),
132 exechelper.WithStdout(os.Stdout), exechelper.WithStderr(os.Stderr))
134 return NewActionResult(err, ActionResultWithStdout(string(outBuff.String())),
135 ActionResultWithStderr(string(errBuff.String())))
138 func (a *Actions) RunEchoServer(args []string) *ActionResult {
139 cmd := fmt.Sprintf("vpp_echo server TX=RX socket-name %s/var/run/app_ns_sockets/1 use-app-socket-api uri %s://10.10.10.1/12344", workDir, args[2])
140 errCh := exechelper.Start(cmd)
143 writeSyncFile(NewActionResult(err, ActionResultWithDesc("echo_server: ")))
146 writeSyncFile(OkResult())
150 func (a *Actions) RunEchoSrvInternal(args []string) *ActionResult {
151 cmd := fmt.Sprintf("test echo server %s uri tcp://10.10.10.1/1234", getArgs())
152 return ApiCliInband(workDir, cmd)
155 func (a *Actions) RunEchoClnInternal(args []string) *ActionResult {
156 cmd := fmt.Sprintf("test echo client %s uri tcp://10.10.10.1/1234", getArgs())
157 return ApiCliInband(workDir, cmd)
160 func (a *Actions) RunVclEchoServer(args []string) *ActionResult {
161 f, err := os.Create("vcl_1.conf")
163 return NewActionResult(err, ActionResultWithStderr(("create vcl config: ")))
165 socketPath := fmt.Sprintf("%s/var/run/app_ns_sockets/1", workDir)
166 fmt.Fprintf(f, vclTemplate, socketPath, "1")
169 os.Setenv("VCL_CONFIG", "./vcl_1.conf")
170 cmd := fmt.Sprintf("vcl_test_server -p %s 12346", args[2])
171 errCh := exechelper.Start(cmd)
174 writeSyncFile(NewActionResult(err, ActionResultWithDesc("vcl_test_server: ")))
177 writeSyncFile(OkResult())
181 func (a *Actions) RunVclEchoClient(args []string) *ActionResult {
182 outBuff := bytes.NewBuffer([]byte{})
183 errBuff := bytes.NewBuffer([]byte{})
185 f, err := os.Create("vcl_2.conf")
187 return NewActionResult(err, ActionResultWithStderr(("create vcl config: ")))
189 socketPath := fmt.Sprintf("%s/var/run/app_ns_sockets/2", workDir)
190 fmt.Fprintf(f, vclTemplate, socketPath, "2")
193 os.Setenv("VCL_CONFIG", "./vcl_2.conf")
194 cmd := fmt.Sprintf("vcl_test_client -U -p %s 10.10.10.1 12346", args[2])
195 err = exechelper.Run(cmd,
196 exechelper.WithStdout(outBuff), exechelper.WithStderr(errBuff),
197 exechelper.WithStdout(os.Stdout), exechelper.WithStderr(os.Stderr))
199 return NewActionResult(err, ActionResultWithStdout(string(outBuff.String())),
200 ActionResultWithStderr(string(errBuff.String())))
203 func configure2vethsTopo(ifName, interfaceAddress, namespaceId string, secret uint64, optionalHardwareAddress ...string) ConfFn {
204 return func(ctx context.Context,
205 vppConn api.Connection) error {
207 var swIfIndex interface_types.InterfaceIndex
209 if optionalHardwareAddress == nil {
210 swIfIndex, err = configureAfPacket(ctx, vppConn, ifName, interfaceAddress)
212 swIfIndex, err = configureAfPacket(ctx, vppConn, ifName, interfaceAddress, optionalHardwareAddress[0])
215 fmt.Printf("failed to create af packet: %v", err)
217 _, er := session.NewServiceClient(vppConn).AppNamespaceAddDelV2(ctx, &session.AppNamespaceAddDelV2{
219 SwIfIndex: swIfIndex,
220 NamespaceID: namespaceId,
223 fmt.Printf("add app namespace: %v", err)
227 _, er1 := session.NewServiceClient(vppConn).SessionEnableDisable(ctx, &session.SessionEnableDisable{
231 fmt.Printf("session enable %v", err)
238 func (a *Actions) Configure2Veths(args []string) *ActionResult {
241 NewStanza("session").
243 Append("use-app-socket-api").Close()
245 ctx, cancel := newVppContext()
248 vppConfig, err := deserializeVppConfig(args[2])
250 return NewActionResult(err, ActionResultWithDesc("deserializing configuration failed"))
253 con, vppErrCh := vpphelper.StartAndDialContext(ctx,
254 vpphelper.WithVppConfig(vppConfig.getTemplate()+startup.ToString()),
255 vpphelper.WithRootDir(workDir))
256 exitOnErrCh(ctx, cancel, vppErrCh)
258 var fn func(context.Context, api.Connection) error
259 switch vppConfig.Variant {
261 fn = configure2vethsTopo("vppsrv", "10.10.10.1/24", "1", 1)
262 case "srv-with-preset-hw-addr":
263 fn = configure2vethsTopo("vppsrv", "10.10.10.1/24", "1", 1, "00:00:5e:00:53:01")
267 fn = configure2vethsTopo("vppcln", "10.10.10.2/24", "2", 2)
271 return NewActionResult(err, ActionResultWithDesc("configuration failed"))
273 writeSyncFile(OkResult())
278 func configureAfPacket(ctx context.Context, vppCon api.Connection,
279 name, interfaceAddress string, optionalHardwareAddress ...string) (interface_types.InterfaceIndex, error) {
281 ifaceClient := interfaces.NewServiceClient(vppCon)
282 afPacketCreate := af_packet.AfPacketCreateV2{
283 UseRandomHwAddr: true,
287 if len(optionalHardwareAddress) > 0 {
288 afPacketCreate.HwAddr, err = ethernet_types.ParseMacAddress(optionalHardwareAddress[0])
290 fmt.Printf("failed to parse mac address: %v", err)
293 afPacketCreate.UseRandomHwAddr = false
295 afPacketCreateRsp, err := af_packet.NewServiceClient(vppCon).AfPacketCreateV2(ctx, &afPacketCreate)
297 fmt.Printf("failed to create af packet: %v", err)
300 _, err = ifaceClient.SwInterfaceSetFlags(ctx, &interfaces.SwInterfaceSetFlags{
301 SwIfIndex: afPacketCreateRsp.SwIfIndex,
302 Flags: interface_types.IF_STATUS_API_FLAG_ADMIN_UP,
305 fmt.Printf("set interface state up failed: %v\n", err)
308 ipPrefix, err := ip_types.ParseAddressWithPrefix(interfaceAddress)
310 fmt.Printf("parse ip address %v\n", err)
313 ipAddress := &interfaces.SwInterfaceAddDelAddress{
315 SwIfIndex: afPacketCreateRsp.SwIfIndex,
318 _, errx := ifaceClient.SwInterfaceAddDelAddress(ctx, ipAddress)
320 fmt.Printf("add ip address %v\n", err)
323 return afPacketCreateRsp.SwIfIndex, nil
326 func (a *Actions) ConfigureHttpTps(args []string) *ActionResult {
327 ctx, cancel := newVppContext()
329 con, vppErrCh := vpphelper.StartAndDialContext(ctx,
330 vpphelper.WithVppConfig(configTemplate))
331 exitOnErrCh(ctx, cancel, vppErrCh)
333 confFn := configureProxyTcp("vpp0", "10.0.0.2/24", "vpp1", "10.0.1.2/24")
334 err := confFn(ctx, con)
336 return NewActionResult(err, ActionResultWithDesc("configuration failed"))
339 _, err = session.NewServiceClient(con).SessionEnableDisable(ctx, &session.SessionEnableDisable{
343 return NewActionResult(err, ActionResultWithDesc("configuration failed"))
345 Vppcli("", "http tps uri tcp://0.0.0.0/8080")
346 writeSyncFile(OkResult())