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

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