go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/l3plugin/vppcalls/vpp2106/l3xc_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 "io" 20 "net" 21 22 "github.com/pkg/errors" 23 24 "go.ligato.io/vpp-agent/v3/plugins/vpp" 25 "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2106/fib_types" 26 "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2106/interface_types" 27 "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2106/ip_types" 28 "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2106/l3xc" 29 "go.ligato.io/vpp-agent/v3/plugins/vpp/l3plugin/vppcalls" 30 ) 31 32 func (h *L3XCHandler) DumpAllL3XC(ctx context.Context) ([]vppcalls.L3XC, error) { 33 return h.DumpL3XC(ctx, ^uint32(0)) 34 } 35 36 func (h *L3XCHandler) DumpL3XC(ctx context.Context, index uint32) ([]vppcalls.L3XC, error) { 37 if h.l3xc == nil { 38 // no-op when disabled 39 return nil, nil 40 } 41 42 dump, err := h.l3xc.L3xcDump(ctx, &l3xc.L3xcDump{ 43 SwIfIndex: interface_types.InterfaceIndex(index), 44 }) 45 if err != nil { 46 return nil, err 47 } 48 l3xcs := make([]vppcalls.L3XC, 0) 49 for { 50 recv, err := dump.Recv() 51 if err == io.EOF { 52 break 53 } else if err != nil { 54 return nil, err 55 } 56 paths := make([]vppcalls.Path, len(recv.L3xc.Paths)) 57 for i, p := range recv.L3xc.Paths { 58 var nextHop net.IP 59 if p.Proto == fib_types.FIB_API_PATH_NH_PROTO_IP6 { 60 ip6Addr := p.Nh.Address.GetIP6() 61 nextHop = net.IP(ip6Addr[:]).To16() 62 } else { 63 ip4Addr := p.Nh.Address.GetIP4() 64 nextHop = net.IP(ip4Addr[:4]).To4() 65 } 66 paths[i] = vppcalls.Path{ 67 SwIfIndex: p.SwIfIndex, 68 Weight: p.Weight, 69 Preference: p.Preference, 70 NextHop: nextHop, 71 } 72 } 73 l3xcs = append(l3xcs, vppcalls.L3XC{ 74 SwIfIndex: uint32(recv.L3xc.SwIfIndex), 75 IsIPv6: recv.L3xc.IsIP6, 76 Paths: paths, 77 }) 78 } 79 return l3xcs, nil 80 } 81 82 func (h *L3XCHandler) UpdateL3XC(ctx context.Context, xc *vppcalls.L3XC) error { 83 if h.l3xc == nil { 84 return errors.Wrap(vpp.ErrPluginDisabled, "l3xc") 85 } 86 87 paths := make([]fib_types.FibPath, len(xc.Paths)) 88 for i, p := range xc.Paths { 89 fibPath := fib_types.FibPath{ 90 SwIfIndex: p.SwIfIndex, 91 Weight: p.Weight, 92 Preference: p.Preference, 93 Type: fib_types.FIB_API_PATH_TYPE_NORMAL, 94 } 95 fibPath.Nh, fibPath.Proto = getL3XCFibPathNhAndProto(p.NextHop) 96 paths[i] = fibPath 97 } 98 _, err := h.l3xc.L3xcUpdate(ctx, &l3xc.L3xcUpdate{ 99 L3xc: l3xc.L3xc{ 100 SwIfIndex: interface_types.InterfaceIndex(xc.SwIfIndex), 101 IsIP6: xc.IsIPv6, 102 Paths: paths, 103 }, 104 }) 105 if err != nil { 106 return err 107 } 108 return nil 109 } 110 111 func (h *L3XCHandler) DeleteL3XC(ctx context.Context, index uint32, ipv6 bool) error { 112 if h.l3xc == nil { 113 return errors.Wrap(vpp.ErrPluginDisabled, "l3xc") 114 } 115 116 _, err := h.l3xc.L3xcDel(ctx, &l3xc.L3xcDel{ 117 SwIfIndex: interface_types.InterfaceIndex(index), 118 IsIP6: ipv6, 119 }) 120 if err != nil { 121 return err 122 } 123 return nil 124 } 125 126 func getL3XCFibPathNhAndProto(netIP net.IP) (nh fib_types.FibPathNh, proto fib_types.FibPathNhProto) { 127 var addrUnion ip_types.AddressUnion 128 if netIP.To4() == nil { 129 proto = fib_types.FIB_API_PATH_NH_PROTO_IP6 130 var ip6addr ip_types.IP6Address 131 copy(ip6addr[:], netIP.To16()) 132 addrUnion.SetIP6(ip6addr) 133 } else { 134 proto = fib_types.FIB_API_PATH_NH_PROTO_IP4 135 var ip4addr ip_types.IP4Address 136 copy(ip4addr[:], netIP.To4()) 137 addrUnion.SetIP4(ip4addr) 138 } 139 return fib_types.FibPathNh{ 140 Address: addrUnion, 141 ViaLabel: NextHopViaLabelUnset, 142 ClassifyTableIndex: ClassifyTableIndexUnset, 143 }, proto 144 }