go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/l3plugin/vppcalls/vpp2101/teib_vppcalls.go (about)

     1  package vpp2101
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"net"
     7  
     8  	"go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2101/interface_types"
     9  	"go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2101/ip_types"
    10  	"go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2101/teib"
    11  	l3 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l3"
    12  )
    13  
    14  // VppAddTeibEntry adds a new TEIB entry.
    15  func (h *TeibHandler) VppAddTeibEntry(ctx context.Context, entry *l3.TeibEntry) error {
    16  	return h.vppAddDelTeibEntry(entry, false)
    17  }
    18  
    19  // VppDelTeibEntry removes an existing TEIB entry.
    20  func (h *TeibHandler) VppDelTeibEntry(ctx context.Context, entry *l3.TeibEntry) error {
    21  	return h.vppAddDelTeibEntry(entry, true)
    22  }
    23  
    24  func (h *TeibHandler) vppAddDelTeibEntry(entry *l3.TeibEntry, delete bool) error {
    25  	peer, err := ipToAddress(entry.PeerAddr)
    26  	if err != nil {
    27  		return err
    28  	}
    29  	nh, err := ipToAddress(entry.NextHopAddr)
    30  	if err != nil {
    31  		return err
    32  	}
    33  
    34  	meta, found := h.ifIndexes.LookupByName(entry.Interface)
    35  	if !found {
    36  		return fmt.Errorf("interface %s not found", entry.Interface)
    37  	}
    38  
    39  	req := &teib.TeibEntryAddDel{
    40  		Entry: teib.TeibEntry{
    41  			SwIfIndex: interface_types.InterfaceIndex(meta.SwIfIndex),
    42  			Peer:      peer,
    43  			Nh:        nh,
    44  			NhTableID: entry.VrfId,
    45  		},
    46  	}
    47  	if !delete {
    48  		req.IsAdd = 1
    49  	}
    50  
    51  	reply := &teib.TeibEntryAddDelReply{}
    52  	return h.callsChannel.SendRequest(req).ReceiveReply(reply)
    53  }
    54  
    55  // DumpTeib dumps TEIB entries from VPP and fills them into the provided TEIB entry map.
    56  func (h *TeibHandler) DumpTeib() (entries []*l3.TeibEntry, err error) {
    57  	reqCtx := h.callsChannel.SendMultiRequest(&teib.TeibDump{})
    58  	for {
    59  		teibDetails := &teib.TeibDetails{}
    60  		stop, err := reqCtx.ReceiveReply(teibDetails)
    61  		if stop {
    62  			break
    63  		}
    64  		if err != nil {
    65  			return nil, err
    66  		}
    67  		entry := &l3.TeibEntry{
    68  			PeerAddr:    ipAddrToStr(teibDetails.Entry.Peer),
    69  			NextHopAddr: ipAddrToStr(teibDetails.Entry.Nh),
    70  			VrfId:       teibDetails.Entry.NhTableID,
    71  		}
    72  		if ifName, _, exists := h.ifIndexes.LookupBySwIfIndex(uint32(teibDetails.Entry.SwIfIndex)); !exists {
    73  			h.log.Warnf("TEIB dump: interface name for index %d not found", teibDetails.Entry.SwIfIndex)
    74  		} else {
    75  			entry.Interface = ifName
    76  		}
    77  		entries = append(entries, entry)
    78  	}
    79  	return
    80  }
    81  
    82  func ipAddrToStr(addr ip_types.Address) string {
    83  	if addr.Af == ip_types.ADDRESS_IP6 {
    84  		ip6Addr := addr.Un.GetIP6()
    85  		return net.IP(ip6Addr[:]).To16().String()
    86  	} else {
    87  		ip4Addr := addr.Un.GetIP4()
    88  		return net.IP(ip4Addr[:4]).To4().String()
    89  	}
    90  }