From ccb7b913d54fafdf08b36ac7eb36e462b1ecc9eb Mon Sep 17 00:00:00 2001 From: Ondrej Fabry Date: Mon, 9 Sep 2019 09:56:59 +0200 Subject: Fix compatibility with latest master (20.01-rc0) - fixed generator for new string types - update simple client example - regenerate examples binapi for VPP 19.08 Change-Id: If4fe78c130d95641f35f75cd0262b35b032acaf8 Signed-off-by: Ondrej Fabry --- examples/simple-client/simple_client.go | 226 +++++++++++++++----------------- 1 file changed, 106 insertions(+), 120 deletions(-) (limited to 'examples/simple-client') diff --git a/examples/simple-client/simple_client.go b/examples/simple-client/simple_client.go index c857768..3a24e6a 100644 --- a/examples/simple-client/simple_client.go +++ b/examples/simple-client/simple_client.go @@ -20,7 +20,6 @@ import ( "flag" "fmt" "log" - "net" "os" "strings" @@ -28,9 +27,9 @@ import ( "git.fd.io/govpp.git/adapter/socketclient" "git.fd.io/govpp.git/api" "git.fd.io/govpp.git/core" - "git.fd.io/govpp.git/examples/binapi/acl" "git.fd.io/govpp.git/examples/binapi/interfaces" "git.fd.io/govpp.git/examples/binapi/ip" + "git.fd.io/govpp.git/examples/binapi/vpe" ) var ( @@ -42,13 +41,14 @@ func main() { fmt.Println("Starting simple client example") - // connect to VPP + // connect to VPP asynchronously conn, conev, err := govpp.AsyncConnect(*sockAddr, core.DefaultMaxReconnectAttempts, core.DefaultReconnectInterval) if err != nil { log.Fatalln("ERROR:", err) } defer conn.Disconnect() + // wait for Connected event select { case e := <-conev: if e.State != core.Connected { @@ -63,85 +63,64 @@ func main() { } defer ch.Close() - // individual examples - aclVersion(ch) - aclConfig(ch) - aclDump(ch) + vppVersion(ch) + createLoopback(ch) + createLoopback(ch) interfaceDump(ch) - ipAddressDump(ch) - setIpUnnumbered(ch) - ipUnnumberedDump(ch) + addIPAddress(ch) + ipAddressDump(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) + if len(Errors) > 0 { + fmt.Printf("finished with %d errors\n", len(Errors)) + os.Exit(1) } else { - fmt.Printf("ACL version reply: %+v\n", reply) + fmt.Println("finished successfully") } } -// 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{} +var Errors []error + +func logError(err error, msg string) { + fmt.Printf("ERROR: %s: %v\n", msg, err) + Errors = append(Errors, err) +} + +// vppVersion is the simplest API example - it retrieves VPP version. +func vppVersion(ch api.Channel) { + fmt.Println("Retrieving version") + + req := &vpe.ShowVersion{} + reply := &vpe.ShowVersionReply{} if err := ch.SendRequest(req).ReceiveReply(reply); err != nil { - fmt.Println("ERROR:", err) + logError(err, "retrieving version") return } + fmt.Printf("reply: %+v\n", reply) - fmt.Printf("ACL add replace reply: %+v\n", reply) - + fmt.Printf("VPP version: %q\n", cleanString(reply.Version)) + fmt.Println("ok") } -// 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{} +// createLoopback sends request to create loopback interface. +func createLoopback(ch api.Channel) { + fmt.Println("Creating loopback interface") - reqCtx := ch.SendRequest(req) + req := &interfaces.CreateLoopback{} + reply := &interfaces.CreateLoopbackReply{} - if err := reqCtx.ReceiveReply(reply); err != nil { - fmt.Println("ERROR:", err) - } else { - fmt.Printf("ACL details: %+v\n", reply) + if err := ch.SendRequest(req).ReceiveReply(reply); err != nil { + logError(err, "creating loopback interface") + return } + fmt.Printf("reply: %+v\n", reply) + + fmt.Printf("loopback interface index: %v\n", reply.SwIfIndex) + fmt.Println("OK") } // interfaceDump shows an example of multipart request (multiple replies are expected). @@ -149,81 +128,74 @@ 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) + logError(err, "dumping interfaces") return } - 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) - return - } - fmt.Printf("ip address details: %d %+v\n", msg.SwIfIndex, msg) + fmt.Printf(" - interface: %+v\n", msg) } + + fmt.Println("OK") } -// 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, +// addIPAddress sends request to add IP address to interface. +func addIPAddress(ch api.Channel) { + fmt.Println("Adding IP address to interface") + + req := &interfaces.SwInterfaceAddDelAddress{ + SwIfIndex: 1, + IsAdd: 1, + Address: []byte{10, 10, 0, 1}, + AddressLength: 24, + /* below for 20.01-rc0 + IsAdd: true, + Prefix: interfaces.Prefix{ + Address: interfaces.Address{ + Af: interfaces.ADDRESS_IP4, + Un: interfaces.AddressUnionIP4(interfaces.IP4Address{10, 10, 0, 1}), + }, + Len: 24, + },*/ } - reply := &interfaces.SwInterfaceSetUnnumberedReply{} + reply := &interfaces.SwInterfaceAddDelAddressReply{} if err := ch.SendRequest(req).ReceiveReply(reply); err != nil { - fmt.Println("ERROR:", err) - } else { - fmt.Printf("%+v\n", reply) + logError(err, "adding IP address to interface") + return } + fmt.Printf("reply: %+v\n", reply) + + fmt.Println("OK") } -func ipUnnumberedDump(ch api.Channel) { - fmt.Println("Dumping IP unnumbered") +func ipAddressDump(ch api.Channel) { + fmt.Println("Dumping IP addresses") - reqCtx := ch.SendMultiRequest(&ip.IPUnnumberedDump{ - SwIfIndex: ^uint32(0), - }) + req := &ip.IPAddressDump{ + SwIfIndex: 1, + } + reqCtx := ch.SendMultiRequest(req) for { - msg := &ip.IPUnnumberedDetails{} + msg := &ip.IPAddressDetails{} stop, err := reqCtx.ReceiveReply(msg) - if stop { - break - } if err != nil { - fmt.Println("ERROR:", err) + logError(err, "dumping IP addresses") return } - fmt.Printf("IP unnumbered details: %+v\n", msg) + if stop { + break + } + fmt.Printf(" - ip address: %+v\n", msg) } + + fmt.Println("OK") } // interfaceNotifications shows the usage of notification API. Note that for notifications, @@ -237,7 +209,8 @@ func interfaceNotifications(ch api.Channel) { // subscribe for specific notification message sub, err := ch.SubscribeNotification(notifChan, &interfaces.SwInterfaceEvent{}) if err != nil { - panic(err) + logError(err, "subscribing to interface events") + return } // enable interface events in VPP @@ -246,23 +219,28 @@ func interfaceNotifications(ch api.Channel) { EnableDisable: 1, }).ReceiveReply(&interfaces.WantInterfaceEventsReply{}) if err != nil { - panic(err) + logError(err, "enabling interface events") + return } // generate some events in VPP err = ch.SendRequest(&interfaces.SwInterfaceSetFlags{ - SwIfIndex: 0, - AdminUpDown: 0, + SwIfIndex: 1, }).ReceiveReply(&interfaces.SwInterfaceSetFlagsReply{}) if err != nil { - panic(err) + logError(err, "setting interface flags") + return } err = ch.SendRequest(&interfaces.SwInterfaceSetFlags{ - SwIfIndex: 0, + SwIfIndex: 1, AdminUpDown: 1, + /* below for 20.01-rc0 + AdminUpDown: true, + Flags: interfaces.IF_STATUS_API_FLAG_ADMIN_UP,*/ }).ReceiveReply(&interfaces.SwInterfaceSetFlagsReply{}) if err != nil { - panic(err) + logError(err, "setting interface flags") + return } // receive one notification @@ -275,12 +253,20 @@ func interfaceNotifications(ch api.Channel) { EnableDisable: 0, }).ReceiveReply(&interfaces.WantInterfaceEventsReply{}) if err != nil { - panic(err) + logError(err, "setting interface flags") + return } // unsubscribe from delivery of the notifications err = sub.Unsubscribe() if err != nil { - panic(err) + logError(err, "unsubscribing from interface events") + return } + + fmt.Println() +} + +func cleanString(str string) string { + return strings.Split(str, "\x00")[0] } -- cgit 1.2.3-korg