go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/ifplugin/vppcalls/vpp2202/vmxnet3_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 vpp2202 16 17 import ( 18 "fmt" 19 20 "github.com/pkg/errors" 21 22 "go.ligato.io/vpp-agent/v3/plugins/vpp" 23 "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2202/interface_types" 24 vpp_vmxnet3 "go.ligato.io/vpp-agent/v3/plugins/vpp/binapi/vpp2202/vmxnet3" 25 "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/vppcalls" 26 ifs "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces" 27 ) 28 29 func (h *InterfaceVppHandler) AddVmxNet3(ifName string, vmxNet3 *ifs.VmxNet3Link) (swIdx uint32, err error) { 30 if h.vmxnet3 == nil { 31 return 0, errors.WithMessage(vpp.ErrPluginDisabled, "wmxnet") 32 } 33 34 var pci uint32 35 pci, err = derivePCI(ifName) 36 if err != nil { 37 return 0, err 38 } 39 40 req := &vpp_vmxnet3.Vmxnet3Create{ 41 PciAddr: pci, 42 } 43 // Optional arguments 44 if vmxNet3 != nil { 45 req.EnableElog = int32(boolToUint(vmxNet3.EnableElog)) 46 req.RxqSize = uint16(vmxNet3.RxqSize) 47 req.TxqSize = uint16(vmxNet3.TxqSize) 48 } 49 50 reply := &vpp_vmxnet3.Vmxnet3CreateReply{} 51 if err = h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { 52 return 0, errors.Errorf(err.Error()) 53 } 54 55 return uint32(reply.SwIfIndex), h.SetInterfaceTag(ifName, uint32(reply.SwIfIndex)) 56 } 57 58 func (h *InterfaceVppHandler) DeleteVmxNet3(ifName string, ifIdx uint32) error { 59 if h.vmxnet3 == nil { 60 return errors.WithMessage(vpp.ErrPluginDisabled, "wmxnet") 61 } 62 63 req := &vpp_vmxnet3.Vmxnet3Delete{ 64 SwIfIndex: interface_types.InterfaceIndex(ifIdx), 65 } 66 reply := &vpp_vmxnet3.Vmxnet3DeleteReply{} 67 if err := h.callsChannel.SendRequest(req).ReceiveReply(reply); err != nil { 68 return errors.Errorf(err.Error()) 69 } 70 71 return h.RemoveInterfaceTag(ifName, ifIdx) 72 } 73 74 func derivePCI(ifName string) (uint32, error) { 75 var function, slot, bus, domain, pci uint32 76 77 numLen, err := fmt.Sscanf(ifName, "vmxnet3-%x/%x/%x/%x", &domain, &bus, &slot, &function) 78 if err != nil { 79 err = errors.Errorf("cannot parse PCI address from the vmxnet3 interface name %s: %v", ifName, err) 80 return 0, err 81 } 82 if numLen != 4 { 83 err = errors.Errorf("cannot parse PCI address from the interface name %s: expected 4 address elements, received %d", 84 ifName, numLen) 85 return 0, err 86 } 87 88 pci |= function << 29 89 pci |= slot << 24 90 pci |= bus << 16 91 pci |= domain 92 93 return pci, nil 94 } 95 96 // dumpVmxNet3Details dumps VmxNet3 interface details from VPP and fills them into the provided interface map. 97 func (h *InterfaceVppHandler) dumpVmxNet3Details(interfaces map[uint32]*vppcalls.InterfaceDetails) error { 98 if h.vmxnet3 == nil { 99 // no-op when disabled 100 return nil 101 } 102 103 reqCtx := h.callsChannel.SendMultiRequest(&vpp_vmxnet3.Vmxnet3Dump{}) 104 for { 105 vmxnet3Details := &vpp_vmxnet3.Vmxnet3Details{} 106 stop, err := reqCtx.ReceiveReply(vmxnet3Details) 107 if stop { 108 break // Break from the loop. 109 } 110 if err != nil { 111 return fmt.Errorf("failed to dump VmxNet3 tunnel interface details: %v", err) 112 } 113 _, ifIdxExists := interfaces[uint32(vmxnet3Details.SwIfIndex)] 114 if !ifIdxExists { 115 continue 116 } 117 interfaces[uint32(vmxnet3Details.SwIfIndex)].Interface.Link = &ifs.Interface_VmxNet3{ 118 VmxNet3: &ifs.VmxNet3Link{ 119 RxqSize: uint32(vmxnet3Details.RxCount), 120 TxqSize: uint32(vmxnet3Details.TxCount), 121 }, 122 } 123 interfaces[uint32(vmxnet3Details.SwIfIndex)].Interface.Type = ifs.Interface_VMXNET3_INTERFACE 124 interfaces[uint32(vmxnet3Details.SwIfIndex)].Meta.Pci = vmxnet3Details.PciAddr 125 } 126 return nil 127 }