1 // Copyright (c) 2017 Cisco and/or its affiliates.
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at:
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 // Binary stats-client is an example VPP management application that exercises the
16 // govpp API for interface counters together with asynchronous connection to VPP.
19 // Generates Go bindings for all VPP APIs located in the json directory.
20 //go:generate binapi-generator --input-dir=../../bin_api --output-dir=../../bin_api
28 "git.fd.io/govpp.git/api"
29 "git.fd.io/govpp.git/core"
30 "git.fd.io/govpp.git/examples/bin_api/interfaces"
31 "git.fd.io/govpp.git/examples/bin_api/stats"
35 fmt.Println("Starting stats VPP client...")
37 // async connect to VPP
38 conn, statCh, err := govpp.AsyncConnect()
40 fmt.Println("Error:", err)
43 defer conn.Disconnect()
45 // create an API channel that will be used in the examples
46 ch, err := conn.NewAPIChannel()
48 fmt.Println("Error:", err)
53 // create channel for Interrupt signal
54 sigChan := make(chan os.Signal, 1)
55 signal.Notify(sigChan, os.Interrupt)
57 var simpleCountersSubs *api.NotifSubscription
58 var combinedCountersSubs *api.NotifSubscription
59 var notifChan chan api.Message
61 // loop until Interrupt signal is received
66 case connEvent := <-statCh:
67 // VPP connection state change
68 switch connEvent.State {
70 fmt.Println("VPP connected.")
71 if simpleCountersSubs == nil {
72 simpleCountersSubs, combinedCountersSubs, notifChan = subscribeNotifications(ch)
76 case core.Disconnected:
77 fmt.Println("VPP disconnected.")
80 case msg := <-notifChan:
81 switch notif := msg.(type) {
82 case *interfaces.VnetInterfaceSimpleCounters:
83 // simple counter notification received
84 processSimpleCounters(notif)
85 case *interfaces.VnetInterfaceCombinedCounters:
86 // combined counter notification received
87 processCombinedCounters(notif)
89 fmt.Println("Ignoring unknown VPP notification")
94 fmt.Println("Interrupt received, exiting.")
99 ch.UnsubscribeNotification(simpleCountersSubs)
100 ch.UnsubscribeNotification(combinedCountersSubs)
103 // subscribeNotifications subscribes for interface counters notifications.
104 func subscribeNotifications(ch *api.Channel) (*api.NotifSubscription, *api.NotifSubscription, chan api.Message) {
106 notifChan := make(chan api.Message, 100)
107 simpleCountersSubs, _ := ch.SubscribeNotification(notifChan, interfaces.NewVnetInterfaceSimpleCounters)
108 combinedCountersSubs, _ := ch.SubscribeNotification(notifChan, interfaces.NewVnetInterfaceCombinedCounters)
110 return simpleCountersSubs, combinedCountersSubs, notifChan
113 // requestStatistics requests interface counters notifications from VPP.
114 func requestStatistics(ch *api.Channel) {
115 ch.SendRequest(&stats.WantStats{
116 Pid: uint32(os.Getpid()),
118 }).ReceiveReply(&stats.WantStatsReply{})
121 // processSimpleCounters processes simple counters received from VPP.
122 func processSimpleCounters(counters *interfaces.VnetInterfaceSimpleCounters) {
123 fmt.Printf("%+v\n", counters)
125 counterNames := []string{"Drop", "Punt", "IPv4", "IPv6", "RxNoBuf", "RxMiss", "RxError", "TxError", "MPLS"}
127 for i := uint32(0); i < counters.Count; i++ {
128 fmt.Printf("Interface '%d': %s = %d\n",
129 counters.FirstSwIfIndex+i, counterNames[counters.VnetCounterType], counters.Data[i])
133 // processCombinedCounters processes combined counters received from VPP.
134 func processCombinedCounters(counters *interfaces.VnetInterfaceCombinedCounters) {
135 fmt.Printf("%+v\n", counters)
137 counterNames := []string{"Rx", "Tx"}
139 for i := uint32(0); i < counters.Count; i++ {
140 fmt.Printf("Interface '%d': %s packets = %d, %s bytes = %d\n",
141 counters.FirstSwIfIndex+i, counterNames[counters.VnetCounterType], counters.Data[i].Packets,
142 counterNames[counters.VnetCounterType], counters.Data[i].Bytes)