Skip to content

Commit

Permalink
Update client examples (#151)
Browse files Browse the repository at this point in the history
* Update client examples

This change updates GoVPP client examples. Added missing types of calls, remove unused code, minimize logging and make them overall more consistent.

Signed-off-by: Ondrej Fabry <[email protected]>

* Ignore NO_CHANGE retval value

Signed-off-by: Ondrej Fabry <[email protected]>

---------

Signed-off-by: Ondrej Fabry <[email protected]>
  • Loading branch information
ondrej-fabry authored Jul 28, 2023
1 parent e935059 commit e760f0f
Show file tree
Hide file tree
Showing 4 changed files with 306 additions and 303 deletions.
145 changes: 131 additions & 14 deletions examples/rpc-service/rpc_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,16 @@ import (
"fmt"
"io"
"log"
"strings"
"net"
"os"
"sync"

"go.fd.io/govpp"
"go.fd.io/govpp/adapter/socketclient"
"go.fd.io/govpp/api"
interfaces "go.fd.io/govpp/binapi/interface"
"go.fd.io/govpp/binapi/interface_types"
"go.fd.io/govpp/binapi/ip_types"
"go.fd.io/govpp/binapi/vpe"
)

Expand All @@ -47,40 +51,153 @@ func main() {
}
defer conn.Disconnect()

showVersion(conn)
interfaceDump(conn)
getVppInfo(conn)
idx := createLoopback(conn)
listInterfaces(conn)
addIPAddress(conn, idx)
watchInterfaceEvents(conn, idx)
}

// showVersion shows an example of simple request with services.
func showVersion(conn api.Connection) {
func getVppInfo(conn api.Connection) {
c := vpe.NewServiceClient(conn)

version, err := c.ShowVersion(context.Background(), &vpe.ShowVersion{})
if err != nil {
log.Fatalln("ERROR: ShowVersion failed:", err)
log.Fatalln("ERROR: getting VPP version failed:", err)
}
fmt.Printf("VPP Version: %v\n", version.Version)

fmt.Printf("Version: %v\n", version.Version)
systime, err := c.ShowVpeSystemTime(context.Background(), &vpe.ShowVpeSystemTime{})
if err != nil {
log.Fatalln("ERROR: getting system time failed:", err)
}
fmt.Printf("System Time: %v\n", systime.VpeSystemTime)
}

// interfaceDump shows an example of multi request with services.
func interfaceDump(conn api.Connection) {
func createLoopback(conn api.Connection) interface_types.InterfaceIndex {
c := interfaces.NewServiceClient(conn)

stream, err := c.SwInterfaceDump(context.Background(), &interfaces.SwInterfaceDump{})
reply, err := c.CreateLoopback(context.Background(), &interfaces.CreateLoopback{})
if err != nil {
log.Fatalln("ERROR: DumpSwInterface failed:", err)
log.Fatalln("ERROR: creating loopback failed:", err)
}
fmt.Printf("Loopback interface created: %v\n", reply.SwIfIndex)

return reply.SwIfIndex
}

func listInterfaces(conn api.Connection) {
c := interfaces.NewServiceClient(conn)

fmt.Println("Dumping interfaces")
stream, err := c.SwInterfaceDump(context.Background(), &interfaces.SwInterfaceDump{
SwIfIndex: ^interface_types.InterfaceIndex(0),
})
if err != nil {
log.Fatalln("ERROR: listing interfaces failed:", err)
}
for {
iface, err := stream.Recv()
if err == io.EOF {
break
}
if err != nil {
log.Fatalln("ERROR: DumpSwInterface failed:", err)
log.Fatalln("ERROR: receiving interface list failed:", err)
}
fmt.Printf("- interface: %s (index: %v)\n", iface.InterfaceName, iface.SwIfIndex)
}
}

func addIPAddress(conn api.Connection, ifIdx interface_types.InterfaceIndex) {
c := interfaces.NewServiceClient(conn)

addr := ip_types.NewAddress(net.IPv4(10, 10, 0, byte(ifIdx)))

_, err := c.SwInterfaceAddDelAddress(context.Background(), &interfaces.SwInterfaceAddDelAddress{
SwIfIndex: ifIdx,
IsAdd: true,
Prefix: ip_types.AddressWithPrefix{Address: addr, Len: 32},
})
if err != nil {
log.Fatalln("ERROR: adding IP address failed:", err)
}

fmt.Printf("IP address %v added\n", addr)
}

func watchInterfaceEvents(conn api.Connection, index interface_types.InterfaceIndex) {
c := interfaces.NewServiceClient(conn)

// start watcher for specific event message
watcher, err := conn.WatchEvent(context.Background(), (*interfaces.SwInterfaceEvent)(nil))
if err != nil {
log.Fatalln("ERROR: watching interface events failed:", err)
}

// enable interface events in VPP
_, err = c.WantInterfaceEvents(context.Background(), &interfaces.WantInterfaceEvents{
PID: uint32(os.Getpid()),
EnableDisable: 1,
})
if err != nil {
log.Fatalln("ERROR: enabling interface events failed:", err)
}

fmt.Printf("watching interface events for index %d\n", index)

var wg sync.WaitGroup

// receive notifications
wg.Add(1)
go func() {
defer wg.Done()
for notif := range watcher.Events() {
e := notif.(*interfaces.SwInterfaceEvent)
fmt.Printf("incoming interface event: %+v\n", e)
}
fmt.Printf("- interface: %s\n", strings.Trim(iface.InterfaceName, "\x00"))
fmt.Println("watcher done")
}()

// generate some events in VPP
setInterfaceStatus(conn, index, true)
setInterfaceStatus(conn, index, false)

// disable interface events in VPP
_, err = c.WantInterfaceEvents(context.Background(), &interfaces.WantInterfaceEvents{
PID: uint32(os.Getpid()),
EnableDisable: 0,
})
if err != nil {
log.Fatalln("ERROR: disabling interface events failed:", err)
}

// close watcher to stop receiving notifications
watcher.Close()

// generate ignored events in VPP
setInterfaceStatus(conn, index, true)

wg.Wait()
}

func setInterfaceStatus(conn api.Connection, ifIdx interface_types.InterfaceIndex, up bool) {
c := interfaces.NewServiceClient(conn)

var flags interface_types.IfStatusFlags
if up {
flags = interface_types.IF_STATUS_API_FLAG_ADMIN_UP
} else {
flags = 0
}
_, err := c.SwInterfaceSetFlags(context.Background(), &interfaces.SwInterfaceSetFlags{
SwIfIndex: ifIdx,
Flags: flags,
})
if err != nil {
log.Fatalln("ERROR: setting interface flags failed:", err)
}
if up {
fmt.Printf("interface status set to UP")
} else {
fmt.Printf("interface status set to DOWN")
}
}
Loading

0 comments on commit e760f0f

Please sign in to comment.