go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/l3plugin/vppcalls/vpp2106/teib_vppcalls.go (about) 1 // Copyright (c) 2021 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 vpp2106 16 17 import ( 18 "context" 19 "fmt" 20 "net" 21 22 "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2106/interface_types" 23 "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2106/ip_types" 24 "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2106/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 }