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.
25 "git.fd.io/govpp.git/api"
26 "git.fd.io/govpp.git/core"
27 "git.fd.io/govpp.git/examples/bin_api/stats"
31 fmt.Println("Starting stats VPP client...")
33 // async connect to VPP
34 conn, statCh, err := govpp.AsyncConnect("")
36 fmt.Println("Error:", err)
39 defer conn.Disconnect()
41 // create an API channel that will be used in the examples
42 ch, err := conn.NewAPIChannel()
44 fmt.Println("Error:", err)
47 defer fmt.Println("calling close")
50 // create channel for Interrupt signal
51 sigChan := make(chan os.Signal, 1)
52 signal.Notify(sigChan, os.Interrupt)
54 var simpleCountersSubs *api.NotifSubscription
55 var combinedCountersSubs *api.NotifSubscription
56 var notifChan chan api.Message
58 // loop until Interrupt signal is received
63 case connEvent := <-statCh:
64 // VPP connection state change
65 switch connEvent.State {
67 fmt.Println("VPP connected.")
68 if simpleCountersSubs == nil {
69 simpleCountersSubs, combinedCountersSubs, notifChan = subscribeNotifications(ch)
73 case core.Disconnected:
74 fmt.Println("VPP disconnected.")
77 case msg := <-notifChan:
78 switch notif := msg.(type) {
79 case *stats.VnetInterfaceSimpleCounters:
80 // simple counter notification received
81 processSimpleCounters(notif)
82 case *stats.VnetInterfaceCombinedCounters:
83 // combined counter notification received
84 processCombinedCounters(notif)
86 fmt.Println("Ignoring unknown VPP notification")
91 fmt.Println("Interrupt received, exiting.")
96 ch.UnsubscribeNotification(simpleCountersSubs)
97 ch.UnsubscribeNotification(combinedCountersSubs)
100 // subscribeNotifications subscribes for interface counters notifications.
101 func subscribeNotifications(ch api.Channel) (*api.NotifSubscription, *api.NotifSubscription, chan api.Message) {
102 notifChan := make(chan api.Message, 100)
104 simpleCountersSubs, err := ch.SubscribeNotification(notifChan, stats.NewVnetInterfaceSimpleCounters)
108 combinedCountersSubs, err := ch.SubscribeNotification(notifChan, stats.NewVnetInterfaceCombinedCounters)
113 return simpleCountersSubs, combinedCountersSubs, notifChan
116 // requestStatistics requests interface counters notifications from VPP.
117 func requestStatistics(ch api.Channel) {
118 if err := ch.SendRequest(&stats.WantStats{
119 PID: uint32(os.Getpid()),
121 }).ReceiveReply(&stats.WantStatsReply{}); err != nil {
126 // processSimpleCounters processes simple counters received from VPP.
127 func processSimpleCounters(counters *stats.VnetInterfaceSimpleCounters) {
128 fmt.Printf("SimpleCounters: %+v\n", counters)
130 counterNames := []string{
134 "RxError", "TxError",
138 for i := uint32(0); i < counters.Count; i++ {
139 fmt.Printf("Interface '%d': %s = %d\n",
140 counters.FirstSwIfIndex+i, counterNames[counters.VnetCounterType], counters.Data[i])
144 // processCombinedCounters processes combined counters received from VPP.
145 func processCombinedCounters(counters *stats.VnetInterfaceCombinedCounters) {
146 fmt.Printf("CombinedCounters: %+v\n", counters)
148 counterNames := []string{"Rx", "Tx"}
150 for i := uint32(0); i < counters.Count; i++ {
151 if len(counterNames) <= int(counters.VnetCounterType) {
154 fmt.Printf("Interface '%d': %s packets = %d, %s bytes = %d\n",
155 counters.FirstSwIfIndex+i,
156 counterNames[counters.VnetCounterType], counters.Data[i].Packets,
157 counterNames[counters.VnetCounterType], counters.Data[i].Bytes)