go.ligato.io/vpp-agent/v3@v3.5.0/plugins/linux/ifplugin/linuxcalls/netlink_api.go (about) 1 // Copyright (c) 2018 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 linuxcalls 16 17 import ( 18 "net" 19 20 "github.com/vishvananda/netlink" 21 "github.com/vishvananda/netns" 22 "go.ligato.io/cn-infra/v2/logging" 23 24 "go.ligato.io/vpp-agent/v3/plugins/linux/ifplugin/ifaceidx" 25 "go.ligato.io/vpp-agent/v3/plugins/linux/nsplugin" 26 interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/linux/interfaces" 27 namespaces "go.ligato.io/vpp-agent/v3/proto/ligato/linux/namespace" 28 ) 29 30 // InterfaceDetails is an object combining linux interface data based on proto 31 // model with additional metadata 32 type InterfaceDetails struct { 33 Interface *interfaces.Interface `json:"interface"` 34 Meta *InterfaceMeta `json:"interface_meta"` 35 } 36 37 // InterfaceStatistics are represented here since 38 // there is currently no model 39 type InterfaceStatistics struct { 40 Name string `json:"interface_name"` 41 Type interfaces.Interface_Type `json:"interface_type"` 42 LinuxIfIndex int `json:"linux_if_index"` 43 44 // stats data 45 RxPackets uint64 `json:"rx_packets"` 46 TxPackets uint64 `json:"tx_packets"` 47 RxBytes uint64 `json:"rx_bytes"` 48 TxBytes uint64 `json:"tx_bytes"` 49 RxErrors uint64 `json:"rx_errors"` 50 TxErrors uint64 `json:"tx_errors"` 51 RxDropped uint64 `json:"rx_dropped"` 52 TxDropped uint64 `json:"tx_dropped"` 53 } 54 55 // InterfaceMeta represents linux interface metadata 56 type InterfaceMeta struct { 57 LinuxIfIndex int `json:"linux_if_index"` 58 ParentIndex int `json:"parent_index"` 59 MasterIndex int `json:"master_index"` 60 OperState uint8 `json:"oper_state"` 61 Flags uint32 `json:"flags"` 62 Encapsulation string `json:"encapsulation"` 63 NumRxQueues int `json:"num_rx_queue"` 64 NumTxQueues int `json:"num_tx_queue"` 65 TxQueueLen int `json:"tx_queue_len"` 66 } 67 68 // NetlinkAPI interface covers all methods inside linux calls package 69 // needed to manage linux interfaces. 70 type NetlinkAPI interface { 71 NetlinkAPIRead 72 73 // AddVethInterfacePair configures two connected VETH interfaces 74 AddVethInterfacePair(ifName, peerIfName string) error 75 // AddDummyInterface configures dummy interface (effectively additional loopback). 76 AddDummyInterface(ifName string) error 77 // AddVRFDevice configures new VRF network device. 78 AddVRFDevice(vrfDevName string, routingTable uint32) error 79 // PutInterfaceIntoVRF assigns Linux interface into a given VRF. 80 PutInterfaceIntoVRF(ifName, vrfDevName string) error 81 // RemoveInterfaceFromVRF un-assigns Linux interface from a given VRF. 82 RemoveInterfaceFromVRF(ifName, vrfDevName string) error 83 // DeleteInterface removes the given interface. 84 DeleteInterface(ifName string) error 85 // SetInterfaceUp sets interface state to 'up' 86 SetInterfaceUp(ifName string) error 87 // SetInterfaceDown sets interface state to 'down' 88 SetInterfaceDown(ifName string) error 89 // AddInterfaceIP adds new IP address 90 AddInterfaceIP(ifName string, addr *net.IPNet) error 91 // DelInterfaceIP removes IP address from linux interface 92 DelInterfaceIP(ifName string, addr *net.IPNet) error 93 // SetInterfaceMac sets MAC address 94 SetInterfaceMac(ifName string, macAddress string) error 95 // SetInterfaceMTU set maximum transmission unit for interface 96 SetInterfaceMTU(ifName string, mtu int) error 97 // RenameInterface changes interface host name 98 RenameInterface(ifName string, newName string) error 99 // SetInterfaceAlias sets the alias of the given interface. 100 // Equivalent to: `ip link set dev $ifName alias $alias` 101 SetInterfaceAlias(ifName, alias string) error 102 // SetLinkNamespace puts link into a network namespace. 103 SetLinkNamespace(link netlink.Link, ns netns.NsHandle) error 104 // SetChecksumOffloading enables/disables Rx/Tx checksum offloading 105 // for the given interface. 106 SetChecksumOffloading(ifName string, rxOn, txOn bool) error 107 } 108 109 // NetlinkAPIRead interface covers read methods inside linux calls package 110 // needed to manage linux interfaces. 111 type NetlinkAPIRead interface { 112 // GetLinkByName calls netlink API to get Link type from interface name 113 GetLinkByName(ifName string) (netlink.Link, error) 114 // GetLinkByIndex calls netlink API to get Link type from interface index 115 GetLinkByIndex(ifIdx int) (netlink.Link, error) 116 // GetLinkList return all links from namespace 117 GetLinkList() ([]netlink.Link, error) 118 // LinkSubscribe takes a channel to which notifications will be sent 119 // when links change. Close the 'done' chan to stop subscription. 120 LinkSubscribe(ch chan<- netlink.LinkUpdate, done <-chan struct{}) error 121 // AddrSubscribe takes a channel to which notifications will be sent 122 // when addresses change. Close the 'done' chan to stop subscription. 123 AddrSubscribe(ch chan<- netlink.AddrUpdate, done <-chan struct{}) error 124 // GetAddressList reads all IP addresses 125 GetAddressList(ifName string) ([]netlink.Addr, error) 126 // InterfaceExists verifies interface existence 127 InterfaceExists(ifName string) (bool, error) 128 // IsInterfaceUp checks if the interface is UP. 129 IsInterfaceUp(ifName string) (bool, error) 130 // GetInterfaceType returns linux interface type 131 GetInterfaceType(ifName string) (string, error) 132 // GetChecksumOffloading returns the state of Rx/Tx checksum offloading 133 // for the given interface. 134 GetChecksumOffloading(ifName string) (rxOn, txOn bool, err error) 135 // DumpInterfaces uses local cache to gather information about linux 136 // namespaces and retrieves interfaces from them. 137 DumpInterfaces() ([]*InterfaceDetails, error) 138 // DumpInterfacesFromNamespaces retrieves all linux interfaces based 139 // on provided namespace context. 140 DumpInterfacesFromNamespaces(nsList []*namespaces.NetNamespace) ([]*InterfaceDetails, error) 141 // DumpInterfaceStats uses local cache to gather information about linux 142 // namespaces and retrieves stats for interfaces in that namespace them. 143 DumpInterfaceStats() ([]*InterfaceStatistics, error) 144 // DumpInterfaceStatsFromNamespaces retrieves all linux interface stats based 145 // on provided namespace context. 146 DumpInterfaceStatsFromNamespaces(nsList []*namespaces.NetNamespace) ([]*InterfaceStatistics, error) 147 } 148 149 // NetLinkHandler is accessor for Netlink methods. 150 type NetLinkHandler struct { 151 *netlink.Handle 152 nsHandle netns.NsHandle 153 154 nsPlugin nsplugin.API 155 ifIndexes ifaceidx.LinuxIfMetadataIndex 156 157 agentPrefix string 158 159 // parallelization of the Retrieve operation 160 goRoutineCount int 161 log logging.Logger 162 } 163 164 // NewNetLinkHandler creates new instance of Netlink handler. 165 func NewNetLinkHandler( 166 nsPlugin nsplugin.API, 167 ifIndexes ifaceidx.LinuxIfMetadataIndex, 168 agentPrefix string, 169 goRoutineCount int, 170 log logging.Logger, 171 ) *NetLinkHandler { 172 return &NetLinkHandler{ 173 Handle: new(netlink.Handle), 174 nsHandle: netns.None(), 175 nsPlugin: nsPlugin, 176 ifIndexes: ifIndexes, 177 agentPrefix: agentPrefix, 178 goRoutineCount: goRoutineCount, 179 log: log, 180 } 181 } 182 183 func NewNetLinkHandlerNs(ns netns.NsHandle, log logging.Logger) *NetLinkHandler { 184 handle, err := netlink.NewHandleAt(ns) 185 if err != nil { 186 log.Errorf("netlink.NewHandleAt(NS %v): %v", ns, err) 187 } 188 return &NetLinkHandler{ 189 Handle: handle, 190 nsHandle: ns, 191 log: log, 192 } 193 }