aboutsummaryrefslogtreecommitdiffstats
path: root/examples/cmd
diff options
context:
space:
mode:
authorOndrej Fabry <ofabry@cisco.com>2019-02-08 01:16:32 +0100
committerOndrej Fabry <ofabry@cisco.com>2019-02-08 01:16:32 +0100
commitfa21c9d726ebb807895a8571af9a16dab5cd8d6e (patch)
tree4597d483f90e374e89f3923324b531a56217a0f9 /examples/cmd
parent8ba70a7b13950593aab9863246f830eda450f06b (diff)
Generator improvements and cleanup
- generator now supports include-comments flag (as opt-in) - minor code cleanup in binapi-generator - remove obsolete unit tests - flatten examples from examples/cmd folder - introduce constant for checking compatibility in future versions Change-Id: I3545f2ba4b869a3b51d6d0de7e742f3f1e1be392 Signed-off-by: Ondrej Fabry <ofabry@cisco.com>
Diffstat (limited to 'examples/cmd')
-rw-r--r--examples/cmd/perf-bench/perf-bench.go126
-rw-r--r--examples/cmd/simple-client/simple_client.go271
-rw-r--r--examples/cmd/stats-api/README.md68
-rw-r--r--examples/cmd/stats-api/stats_api.go140
-rw-r--r--examples/cmd/union-example/union_example.go103
5 files changed, 0 insertions, 708 deletions
diff --git a/examples/cmd/perf-bench/perf-bench.go b/examples/cmd/perf-bench/perf-bench.go
deleted file mode 100644
index 664f046..0000000
--- a/examples/cmd/perf-bench/perf-bench.go
+++ /dev/null
@@ -1,126 +0,0 @@
-// Copyright (c) 2017 Cisco and/or its affiliates.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at:
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// Binary simple-client is an example VPP management application that exercises the
-// govpp API on real-world use-cases.
-package main
-
-import (
- "flag"
- "fmt"
- "log"
- "time"
-
- "github.com/pkg/profile"
- "github.com/sirupsen/logrus"
-
- "git.fd.io/govpp.git"
- "git.fd.io/govpp.git/api"
- "git.fd.io/govpp.git/core"
- "git.fd.io/govpp.git/examples/bin_api/vpe"
-)
-
-const (
- defaultSyncRequestCount = 1000
- defaultAsyncRequestCount = 10000
-)
-
-func main() {
- // parse optional flags
- var sync, prof bool
- var cnt int
- flag.BoolVar(&sync, "sync", false, "run synchronous perf test")
- flag.IntVar(&cnt, "count", 0, "count of requests to be sent to VPP")
- flag.BoolVar(&prof, "prof", false, "generate profile data")
- flag.Parse()
-
- if cnt == 0 {
- // no specific count defined - use defaults
- if sync {
- cnt = defaultSyncRequestCount
- } else {
- cnt = defaultAsyncRequestCount
- }
- }
-
- if prof {
- defer profile.Start().Stop()
- }
-
- // log only errors
- core.SetLogger(&logrus.Logger{Level: logrus.ErrorLevel})
-
- // connect to VPP
- conn, err := govpp.Connect("")
- if err != nil {
- log.Fatalln("Error:", err)
- }
- defer conn.Disconnect()
-
- // create an API channel
- ch, err := conn.NewAPIChannelBuffered(cnt, cnt)
- if err != nil {
- log.Fatalln("Error:", err)
- }
- defer ch.Close()
-
- // run the test & measure the time
- start := time.Now()
-
- if sync {
- // run synchronous test
- syncTest(ch, cnt)
- } else {
- // run asynchronous test
- asyncTest(ch, cnt)
- }
-
- elapsed := time.Since(start)
- fmt.Println("Test took:", elapsed)
- fmt.Printf("Requests per second: %.0f\n", float64(cnt)/elapsed.Seconds())
-}
-
-func syncTest(ch api.Channel, cnt int) {
- fmt.Printf("Running synchronous perf test with %d requests...\n", cnt)
-
- for i := 0; i < cnt; i++ {
- req := &vpe.ControlPing{}
- reply := &vpe.ControlPingReply{}
-
- if err := ch.SendRequest(req).ReceiveReply(reply); err != nil {
- log.Fatalln("Error in reply:", err)
- }
- }
-}
-
-func asyncTest(ch api.Channel, cnt int) {
- fmt.Printf("Running asynchronous perf test with %d requests...\n", cnt)
-
- ctxChan := make(chan api.RequestCtx, cnt)
-
- go func() {
- for i := 0; i < cnt; i++ {
- ctxChan <- ch.SendRequest(&vpe.ControlPing{})
- }
- close(ctxChan)
- fmt.Printf("Sending asynchronous requests finished\n")
- }()
-
- for ctx := range ctxChan {
- reply := &vpe.ControlPingReply{}
- if err := ctx.ReceiveReply(reply); err != nil {
- log.Fatalln("Error in reply:", err)
- }
- }
-}
diff --git a/examples/cmd/simple-client/simple_client.go b/examples/cmd/simple-client/simple_client.go
deleted file mode 100644
index 08d4da6..0000000
--- a/examples/cmd/simple-client/simple_client.go
+++ /dev/null
@@ -1,271 +0,0 @@
-// Copyright (c) 2017 Cisco and/or its affiliates.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at:
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// simple-client is an example VPP management application that exercises the
-// govpp API on real-world use-cases.
-package main
-
-import (
- "fmt"
- "log"
- "net"
- "os"
- "strings"
-
- "git.fd.io/govpp.git"
- "git.fd.io/govpp.git/api"
- "git.fd.io/govpp.git/examples/bin_api/acl"
- "git.fd.io/govpp.git/examples/bin_api/interfaces"
- "git.fd.io/govpp.git/examples/bin_api/ip"
-)
-
-func main() {
- fmt.Println("Starting simple VPP client...")
-
- // connect to VPP
- conn, err := govpp.Connect("")
- if err != nil {
- log.Fatalln("ERROR:", err)
- }
- defer conn.Disconnect()
-
- // create an API channel that will be used in the examples
- ch, err := conn.NewAPIChannel()
- if err != nil {
- log.Fatalln("ERROR:", err)
- }
- defer ch.Close()
-
- // individual examples
- aclVersion(ch)
- aclConfig(ch)
- aclDump(ch)
-
- interfaceDump(ch)
- ipAddressDump(ch)
-
- setIpUnnumbered(ch)
- ipUnnumberedDump(ch)
-
- interfaceNotifications(ch)
-}
-
-// aclVersion is the simplest API example - one empty request message and one reply message.
-func aclVersion(ch api.Channel) {
- fmt.Println("ACL getting version")
-
- req := &acl.ACLPluginGetVersion{}
- reply := &acl.ACLPluginGetVersionReply{}
-
- if err := ch.SendRequest(req).ReceiveReply(reply); err != nil {
- fmt.Println("ERROR:", err)
- } else {
- fmt.Printf("ACL version reply: %+v\n", reply)
- }
-}
-
-// aclConfig is another simple API example - in this case, the request contains structured data.
-func aclConfig(ch api.Channel) {
- fmt.Println("ACL adding replace")
-
- req := &acl.ACLAddReplace{
- ACLIndex: ^uint32(0),
- Tag: []byte("access list 1"),
- R: []acl.ACLRule{
- {
- IsPermit: 1,
- SrcIPAddr: net.ParseIP("10.0.0.0").To4(),
- SrcIPPrefixLen: 8,
- DstIPAddr: net.ParseIP("192.168.1.0").To4(),
- DstIPPrefixLen: 24,
- Proto: 6,
- },
- {
- IsPermit: 1,
- SrcIPAddr: net.ParseIP("8.8.8.8").To4(),
- SrcIPPrefixLen: 32,
- DstIPAddr: net.ParseIP("172.16.0.0").To4(),
- DstIPPrefixLen: 16,
- Proto: 6,
- },
- },
- }
- reply := &acl.ACLAddReplaceReply{}
-
- if err := ch.SendRequest(req).ReceiveReply(reply); err != nil {
- fmt.Println("ERROR:", err)
- return
- }
- if reply.Retval != 0 {
- fmt.Println("Retval:", reply.Retval)
- return
- }
-
- fmt.Printf("ACL add replace reply: %+v\n", reply)
-
-}
-
-// aclDump shows an example where SendRequest and ReceiveReply are not chained together.
-func aclDump(ch api.Channel) {
- fmt.Println("Dumping ACL")
-
- req := &acl.ACLDump{}
- reply := &acl.ACLDetails{}
-
- reqCtx := ch.SendRequest(req)
-
- if err := reqCtx.ReceiveReply(reply); err != nil {
- fmt.Println("ERROR:", err)
- } else {
- fmt.Printf("ACL details: %+v\n", reply)
- }
-}
-
-// interfaceDump shows an example of multipart request (multiple replies are expected).
-func interfaceDump(ch api.Channel) {
- fmt.Println("Dumping interfaces")
-
- reqCtx := ch.SendMultiRequest(&interfaces.SwInterfaceDump{})
-
- for {
- msg := &interfaces.SwInterfaceDetails{}
- stop, err := reqCtx.ReceiveReply(msg)
- if stop {
- break
- }
- if err != nil {
- fmt.Println("ERROR:", err)
- }
- ifaceName := strings.TrimFunc(string(msg.InterfaceName), func(r rune) bool {
- return r == 0x00
- })
- fmt.Printf("Interface %q: %+v\n", ifaceName, msg)
- }
-}
-
-func ipAddressDump(ch api.Channel) {
- fmt.Println("Dumping IP addresses")
-
- req := &ip.IPAddressDump{
- SwIfIndex: 1, //^uint32(0),
- }
- reqCtx := ch.SendMultiRequest(req)
-
- for {
- msg := &ip.IPAddressDetails{}
- stop, err := reqCtx.ReceiveReply(msg)
- if stop {
- break
- }
- if err != nil {
- fmt.Println("ERROR:", err)
- }
- fmt.Printf("ip address details: %d %+v\n", msg.SwIfIndex, msg)
- }
-}
-
-// aclDump shows an example where SendRequest and ReceiveReply are not chained together.
-func setIpUnnumbered(ch api.Channel) {
- req := &interfaces.SwInterfaceSetUnnumbered{
- SwIfIndex: 1,
- UnnumberedSwIfIndex: 2,
- IsAdd: 1,
- }
- reply := &interfaces.SwInterfaceSetUnnumberedReply{}
-
- if err := ch.SendRequest(req).ReceiveReply(reply); err != nil {
- fmt.Println("ERROR:", err)
- } else {
- fmt.Printf("%+v\n", reply)
- }
-}
-
-func ipUnnumberedDump(ch api.Channel) {
- fmt.Println("Dumping IP unnumbered")
-
- reqCtx := ch.SendMultiRequest(&ip.IPUnnumberedDump{
- SwIfIndex: ^uint32(0),
- })
-
- for {
- msg := &ip.IPUnnumberedDetails{}
- stop, err := reqCtx.ReceiveReply(msg)
- if stop {
- break
- }
- if err != nil {
- fmt.Println("ERROR:", err)
- }
- fmt.Printf("IP unnumbered details: %+v\n", msg)
- }
-}
-
-// interfaceNotifications shows the usage of notification API. Note that for notifications,
-// you are supposed to create your own Go channel with your preferred buffer size. If the channel's
-// buffer is full, the notifications will not be delivered into it.
-func interfaceNotifications(ch api.Channel) {
- fmt.Println("Subscribing to notificaiton events")
-
- notifChan := make(chan api.Message, 100)
-
- // subscribe for specific notification message
- sub, err := ch.SubscribeNotification(notifChan, &interfaces.SwInterfaceEvent{})
- if err != nil {
- panic(err)
- }
-
- // enable interface events in VPP
- err = ch.SendRequest(&interfaces.WantInterfaceEvents{
- PID: uint32(os.Getpid()),
- EnableDisable: 1,
- }).ReceiveReply(&interfaces.WantInterfaceEventsReply{})
- if err != nil {
- panic(err)
- }
-
- // generate some events in VPP
- err = ch.SendRequest(&interfaces.SwInterfaceSetFlags{
- SwIfIndex: 0,
- AdminUpDown: 0,
- }).ReceiveReply(&interfaces.SwInterfaceSetFlagsReply{})
- if err != nil {
- panic(err)
- }
- err = ch.SendRequest(&interfaces.SwInterfaceSetFlags{
- SwIfIndex: 0,
- AdminUpDown: 1,
- }).ReceiveReply(&interfaces.SwInterfaceSetFlagsReply{})
- if err != nil {
- panic(err)
- }
-
- // receive one notification
- notif := (<-notifChan).(*interfaces.SwInterfaceEvent)
- fmt.Printf("incoming event: %+v\n", notif)
-
- // disable interface events in VPP
- err = ch.SendRequest(&interfaces.WantInterfaceEvents{
- PID: uint32(os.Getpid()),
- EnableDisable: 0,
- }).ReceiveReply(&interfaces.WantInterfaceEventsReply{})
- if err != nil {
- panic(err)
- }
-
- // unsubscribe from delivery of the notifications
- err = sub.Unsubscribe()
- if err != nil {
- panic(err)
- }
-}
diff --git a/examples/cmd/stats-api/README.md b/examples/cmd/stats-api/README.md
deleted file mode 100644
index 44a1663..0000000
--- a/examples/cmd/stats-api/README.md
+++ /dev/null
@@ -1,68 +0,0 @@
-# Stats API Example
-
-This example demonstrates how to retrieve statistics from VPP using [the new Stats API](https://github.com/FDio/vpp/blob/master/src/vpp/stats/stats.md).
-
-## Requirements
-
-The following requirements are required to run this example:
-
-- install **VPP 18.10+**
-- enable stats in VPP:
-
- ```sh
- statseg {
- default
- }
- ```
- > The [default socket](https://wiki.fd.io/view/VPP/Command-line_Arguments#.22statseg.22_parameters) is located at `/run/vpp/stats.sock`.
-- run the VPP, ideally with some traffic
-
-## Running example
-
-First build the example: `go build git.fd.io/govpp.git/examples/cmd/stats-api`.
-
-Use commands `ls` and `dump` to list and dump statistics. Optionally, patterns can be used to filter the results.
-
-### List stats matching patterns `/sys/` and `/if/`
-```
-$ ./stats-api ls /sys/ /if/
-Listing stats.. /sys/ /if/
- - /sys/vector_rate
- - /sys/input_rate
- - /sys/last_update
- - /sys/last_stats_clear
- - /sys/heartbeat
- - /sys/node/clocks
- - /sys/node/vectors
- - /sys/node/calls
- - /sys/node/suspends
- - /if/drops
- - /if/punt
- - /if/ip4
- - /if/ip6
- - /if/rx-no-buf
- - /if/rx-miss
- - /if/rx-error
- - /if/tx-error
- - /if/rx
- - /if/rx-unicast
- - /if/rx-multicast
- - /if/rx-broadcast
- - /if/tx
- - /if/tx-unicast-miss
- - /if/tx-multicast
- - /if/tx-broadcast
-Listed 25 stats
-```
-
-### Dump all stats with their types and values
-```
-$ ./stats-api dump
-Dumping stats..
- - /sys/last_update ScalarIndex 10408
- - /sys/heartbeat ScalarIndex 1041
- - /err/ip4-icmp-error/unknown type ErrorIndex 5
- - /net/route/to CombinedCounterVector [[{Packets:0 Bytes:0} {Packets:0 Bytes:0} {Packets:0 Bytes:0} {Packets:0 Bytes:0} {Packets:0 Bytes:0} {Packets:0 Bytes:0} {Packets:0 Bytes:0} {Packets:0 Bytes:0} {Packets:0 Bytes:0} {Packets:0 Bytes:0} {Packets:0 Bytes:0} {Packets:0 Bytes:0} {Packets:0 Bytes:0} {Packets:5 Bytes:420}]]
- - /if/drops SimpleCounterVector [[0 5 5]]
-Dumped 5 (2798) stats
-```
diff --git a/examples/cmd/stats-api/stats_api.go b/examples/cmd/stats-api/stats_api.go
deleted file mode 100644
index 6fd46d2..0000000
--- a/examples/cmd/stats-api/stats_api.go
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright (c) 2018 Cisco and/or its affiliates.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at:
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package main
-
-import (
- "flag"
- "fmt"
- "log"
- "os"
- "strings"
-
- "git.fd.io/govpp.git/adapter"
- "git.fd.io/govpp.git/adapter/vppapiclient"
-)
-
-// ------------------------------------------------------------------
-// Example - Stats API
-// ------------------------------------------------------------------
-// The example stats_api demonstrates how to retrieve stats
-// from the VPP using the new stats API.
-// ------------------------------------------------------------------
-
-var (
- statsSocket = flag.String("socket", vppapiclient.DefaultStatSocket, "VPP stats segment socket")
- dumpAll = flag.Bool("all", false, "Dump all stats including ones with zero values")
-)
-
-func init() {
- flag.Usage = func() {
- fmt.Fprintf(os.Stderr, "%s: usage [ls|dump] <patterns>...\n", os.Args[0])
- flag.PrintDefaults()
- os.Exit(1)
- }
-}
-
-func main() {
- flag.Parse()
-
- cmd := flag.Arg(0)
-
- switch cmd {
- case "", "ls", "dump":
- default:
- flag.Usage()
- }
-
- var patterns []string
- if flag.NArg() > 0 {
- patterns = flag.Args()[1:]
- }
-
- client := vppapiclient.NewStatClient(*statsSocket)
-
- fmt.Printf("Connecting to stats socket: %s\n", *statsSocket)
-
- if err := client.Connect(); err != nil {
- log.Fatalln("Connecting failed:", err)
- }
- defer client.Disconnect()
-
- switch cmd {
- case "dump":
- dumpStats(client, patterns, !*dumpAll)
- default:
- listStats(client, patterns)
- }
-}
-
-func listStats(client adapter.StatsAPI, patterns []string) {
- fmt.Printf("Listing stats.. %s\n", strings.Join(patterns, " "))
-
- list, err := client.ListStats(patterns...)
- if err != nil {
- log.Fatalln("listing stats failed:", err)
- }
-
- for _, stat := range list {
- fmt.Printf(" - %v\n", stat)
- }
-
- fmt.Printf("Listed %d stats\n", len(list))
-}
-
-func dumpStats(client adapter.StatsAPI, patterns []string, skipZeros bool) {
- fmt.Printf("Dumping stats.. %s\n", strings.Join(patterns, " "))
-
- stats, err := client.DumpStats(patterns...)
- if err != nil {
- log.Fatalln("dumping stats failed:", err)
- }
-
- n := 0
- for _, stat := range stats {
- if isZero(stat.Data) && skipZeros {
- continue
- }
- fmt.Printf(" - %-25s %25v %+v\n", stat.Name, stat.Type, stat.Data)
- n++
- }
-
- fmt.Printf("Dumped %d (%d) stats\n", n, len(stats))
-}
-
-func isZero(stat adapter.Stat) bool {
- switch s := stat.(type) {
- case adapter.ScalarStat:
- return s == 0
- case adapter.ErrorStat:
- return s == 0
- case adapter.SimpleCounterStat:
- for _, ss := range s {
- for _, sss := range ss {
- if sss != 0 {
- return false
- }
- }
- }
- case adapter.CombinedCounterStat:
- for _, ss := range s {
- for _, sss := range ss {
- if sss.Bytes != 0 || sss.Packets != 0 {
- return false
- }
- }
- }
- }
- return true
-}
diff --git a/examples/cmd/union-example/union_example.go b/examples/cmd/union-example/union_example.go
deleted file mode 100644
index d4563c6..0000000
--- a/examples/cmd/union-example/union_example.go
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright (c) 2018 Cisco and/or its affiliates.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at:
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-// union-example is an example to show how to use unions in VPP binary API.
-package main
-
-import (
- "bytes"
- "fmt"
- "log"
- "net"
-
- "git.fd.io/govpp.git/examples/bin_api/ip"
- "github.com/lunixbochs/struc"
-)
-
-func main() {
- encodingExample()
- usageExample()
-}
-
-func encodingExample() {
- // create union with IPv4 address
- var unionIP4 ip.AddressUnion
- unionIP4.SetIP4(ip.IP4Address{192, 168, 1, 10})
-
- // use it in the Address type
- addr := &ip.Address{
- Af: ip.ADDRESS_IP4,
- Un: ip.AddressUnionIP4(ip.IP4Address{192, 168, 1, 10}),
- }
- log.Printf("encoding union IPv4: %v", addr.Un.GetIP4())
-
- // encode the address with union
- data := encode(addr)
- // decode the address with union
- addr2 := decode(data)
-
- log.Printf("decoded union IPv4: %v", addr2.Un.GetIP4())
-}
-
-func encode(addr *ip.Address) []byte {
- log.Printf("encoding address: %#v", addr)
- buf := new(bytes.Buffer)
- if err := struc.Pack(buf, addr); err != nil {
- panic(err)
- }
- return buf.Bytes()
-}
-
-func decode(data []byte) *ip.Address {
- addr := new(ip.Address)
- buf := bytes.NewReader(data)
- if err := struc.Unpack(buf, addr); err != nil {
- panic(err)
- }
- log.Printf("decoded address: %#v", addr)
- return addr
-}
-
-func usageExample() {
- var convAddr = func(ip string) {
- addr, err := ipToAddress(ip)
- if err != nil {
- log.Printf("converting ip %q failed: %v", ip, err)
- }
- fmt.Printf("% 0X\n", addr)
- }
-
- convAddr("10.10.10.10")
- convAddr("::1")
- convAddr("")
-}
-
-func ipToAddress(ipstr string) (addr ip.Address, err error) {
- netIP := net.ParseIP(ipstr)
- if netIP == nil {
- return ip.Address{}, fmt.Errorf("invalid IP: %q", ipstr)
- }
- if ip4 := netIP.To4(); ip4 == nil {
- addr.Af = ip.ADDRESS_IP6
- var ip6addr ip.IP6Address
- copy(ip6addr[:], netIP.To16())
- addr.Un.SetIP6(ip6addr)
- } else {
- addr.Af = ip.ADDRESS_IP4
- var ip4addr ip.IP4Address
- copy(ip4addr[:], ip4)
- addr.Un.SetIP4(ip4addr)
- }
- return
-}