go.ligato.io/vpp-agent/v3@v3.5.0/examples/tutorials/07_vpp-connection/main.go (about)

     1  //  Copyright (c) 2019 Cisco and/or its affiliates.
     2  //
     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:
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     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.
    14  
    15  package main
    16  
    17  import (
    18  	"log"
    19  	"time"
    20  
    21  	"go.fd.io/govpp/api"
    22  	"go.fd.io/govpp/binapi/ethernet_types"
    23  	interfaces "go.fd.io/govpp/binapi/interface"
    24  	"go.ligato.io/cn-infra/v2/agent"
    25  
    26  	"go.ligato.io/vpp-agent/v3/plugins/govppmux"
    27  )
    28  
    29  func main() {
    30  	// Create an instance of our plugin.
    31  	p := new(HelloWorld)
    32  	p.GoVPPMux = &govppmux.DefaultPlugin
    33  
    34  	// Create new agent with our plugin instance.
    35  	a := agent.NewAgent(agent.AllPlugins(p))
    36  
    37  	// Run starts the agent with plugins, wait until shutdown
    38  	// and then stops the agent and its plugins.
    39  	if err := a.Start(); err != nil {
    40  		log.Fatalln(err)
    41  	}
    42  
    43  	p.syncVppCall()
    44  	p.asyncVppCall()
    45  	p.multiRequestCall()
    46  
    47  	if err := a.Stop(); err != nil {
    48  		log.Fatalln(err)
    49  	}
    50  }
    51  
    52  // HelloWorld represents our plugin.
    53  type HelloWorld struct {
    54  	vppChan api.Channel
    55  
    56  	GoVPPMux govppmux.API
    57  }
    58  
    59  // String is used to identify the plugin by giving it name.
    60  func (p *HelloWorld) String() string {
    61  	return "HelloWorld"
    62  }
    63  
    64  // Init is executed on agent initialization.
    65  func (p *HelloWorld) Init() (err error) {
    66  	log.Println("Hello World!")
    67  
    68  	if p.vppChan, err = p.GoVPPMux.NewAPIChannel(); err != nil {
    69  		panic(err)
    70  	}
    71  
    72  	return nil
    73  }
    74  
    75  func (p *HelloWorld) syncVppCall() {
    76  	// prepare request
    77  	mac, err := ethernet_types.ParseMacAddress("00:00:00:00:00:01")
    78  	if err != nil {
    79  		log.Panicf("ParseMacAddress failed: %v", err)
    80  	}
    81  	request := &interfaces.CreateLoopback{
    82  		MacAddress: mac,
    83  	}
    84  	// prepare reply
    85  	reply := &interfaces.CreateLoopbackReply{}
    86  	// send request and obtain reply
    87  	err = p.vppChan.SendRequest(request).ReceiveReply(reply)
    88  	if err != nil {
    89  		panic(err)
    90  	}
    91  	// check return value
    92  	if reply.Retval != 0 {
    93  		log.Panicf("Sync call loopback create returned %d", reply.Retval)
    94  	}
    95  
    96  	log.Printf("Sync call created loopback with index %d", reply.SwIfIndex)
    97  }
    98  
    99  func (p *HelloWorld) asyncVppCall() {
   100  	// prepare requests
   101  	mac1, err := ethernet_types.ParseMacAddress("00:00:00:00:00:02")
   102  	if err != nil {
   103  		log.Panicf("ParseMacAddress failed: %v", err)
   104  	}
   105  	mac2, err := ethernet_types.ParseMacAddress("00:00:00:00:00:03")
   106  	if err != nil {
   107  		log.Panicf("ParseMacAddress failed: %v", err)
   108  	}
   109  	request1 := &interfaces.CreateLoopback{
   110  		MacAddress: mac1,
   111  	}
   112  	request2 := &interfaces.CreateLoopback{
   113  		MacAddress: mac2,
   114  	}
   115  
   116  	// obtain contexts
   117  	reqCtx1 := p.vppChan.SendRequest(request1)
   118  	reqCtx2 := p.vppChan.SendRequest(request2)
   119  
   120  	// wait a bit
   121  	time.Sleep(2 * time.Second)
   122  
   123  	// prepare replies
   124  	reply1 := &interfaces.CreateLoopbackReply{}
   125  	reply2 := &interfaces.CreateLoopbackReply{}
   126  
   127  	// receive replies
   128  	if err := reqCtx1.ReceiveReply(reply1); err != nil {
   129  		panic(err)
   130  	}
   131  	if err := reqCtx2.ReceiveReply(reply2); err != nil {
   132  		panic(err)
   133  	}
   134  
   135  	log.Printf("Async call created loopbacks with indexes %d and %d",
   136  		reply1.SwIfIndex, reply2.SwIfIndex)
   137  }
   138  
   139  func (p *HelloWorld) multiRequestCall() {
   140  	// prepare request
   141  	request := &interfaces.SwInterfaceDump{}
   142  	multiReqCtx := p.vppChan.SendMultiRequest(request)
   143  
   144  	// read replies in the loop
   145  	for {
   146  		reply := &interfaces.SwInterfaceDetails{}
   147  		last, err := multiReqCtx.ReceiveReply(reply)
   148  		if err != nil {
   149  			panic(err)
   150  		}
   151  		if last {
   152  			break
   153  		}
   154  		log.Printf("received VPP interface with index %d", reply.SwIfIndex)
   155  	}
   156  }
   157  
   158  // Close is executed on agent shutdown.
   159  func (p *HelloWorld) Close() error {
   160  	p.vppChan.Close()
   161  	log.Println("Goodbye World!")
   162  	return nil
   163  }