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  }