github.com/kata-containers/runtime@v0.0.0-20210505125100-04f29832a923/virtcontainers/veth_endpoint.go (about)

     1  // Copyright (c) 2018 Intel Corporation
     2  //
     3  // SPDX-License-Identifier: Apache-2.0
     4  //
     5  
     6  package virtcontainers
     7  
     8  import (
     9  	"fmt"
    10  
    11  	"github.com/containernetworking/plugins/pkg/ns"
    12  	persistapi "github.com/kata-containers/runtime/virtcontainers/persist/api"
    13  	vcTypes "github.com/kata-containers/runtime/virtcontainers/pkg/types"
    14  )
    15  
    16  // VethEndpoint gathers a network pair and its properties.
    17  type VethEndpoint struct {
    18  	NetPair            NetworkInterfacePair
    19  	EndpointProperties NetworkInfo
    20  	EndpointType       EndpointType
    21  	PCIPath            vcTypes.PciPath
    22  }
    23  
    24  func createVethNetworkEndpoint(idx int, ifName string, interworkingModel NetInterworkingModel) (*VethEndpoint, error) {
    25  	if idx < 0 {
    26  		return &VethEndpoint{}, fmt.Errorf("invalid network endpoint index: %d", idx)
    27  	}
    28  
    29  	netPair, err := createNetworkInterfacePair(idx, ifName, interworkingModel)
    30  	if err != nil {
    31  		return nil, err
    32  	}
    33  
    34  	endpoint := &VethEndpoint{
    35  		// TODO This is too specific. We may need to create multiple
    36  		// end point types here and then decide how to connect them
    37  		// at the time of hypervisor attach and not here
    38  		NetPair:      netPair,
    39  		EndpointType: VethEndpointType,
    40  	}
    41  	if ifName != "" {
    42  		endpoint.NetPair.VirtIface.Name = ifName
    43  	}
    44  
    45  	return endpoint, nil
    46  }
    47  
    48  // Properties returns properties for the veth interface in the network pair.
    49  func (endpoint *VethEndpoint) Properties() NetworkInfo {
    50  	return endpoint.EndpointProperties
    51  }
    52  
    53  // Name returns name of the veth interface in the network pair.
    54  func (endpoint *VethEndpoint) Name() string {
    55  	return endpoint.NetPair.VirtIface.Name
    56  }
    57  
    58  // HardwareAddr returns the mac address that is assigned to the tap interface
    59  // in th network pair.
    60  func (endpoint *VethEndpoint) HardwareAddr() string {
    61  	return endpoint.NetPair.TAPIface.HardAddr
    62  }
    63  
    64  // Type identifies the endpoint as a veth endpoint.
    65  func (endpoint *VethEndpoint) Type() EndpointType {
    66  	return endpoint.EndpointType
    67  }
    68  
    69  // PciPath returns the PCI path of the endpoint.
    70  func (endpoint *VethEndpoint) PciPath() vcTypes.PciPath {
    71  	return endpoint.PCIPath
    72  }
    73  
    74  // SetPciPath sets the PCI path of the endpoint.
    75  func (endpoint *VethEndpoint) SetPciPath(pciPath vcTypes.PciPath) {
    76  	endpoint.PCIPath = pciPath
    77  }
    78  
    79  // NetworkPair returns the network pair of the endpoint.
    80  func (endpoint *VethEndpoint) NetworkPair() *NetworkInterfacePair {
    81  	return &endpoint.NetPair
    82  }
    83  
    84  // SetProperties sets the properties for the endpoint.
    85  func (endpoint *VethEndpoint) SetProperties(properties NetworkInfo) {
    86  	endpoint.EndpointProperties = properties
    87  }
    88  
    89  // Attach for veth endpoint bridges the network pair and adds the
    90  // tap interface of the network pair to the hypervisor.
    91  func (endpoint *VethEndpoint) Attach(s *Sandbox) error {
    92  	h := s.hypervisor
    93  	if err := xConnectVMNetwork(endpoint, h); err != nil {
    94  		networkLogger().WithError(err).Error("Error bridging virtual endpoint")
    95  		return err
    96  	}
    97  
    98  	return h.addDevice(endpoint, netDev)
    99  }
   100  
   101  // Detach for the veth endpoint tears down the tap and bridge
   102  // created for the veth interface.
   103  func (endpoint *VethEndpoint) Detach(netNsCreated bool, netNsPath string) error {
   104  	// The network namespace would have been deleted at this point
   105  	// if it has not been created by virtcontainers.
   106  	if !netNsCreated {
   107  		return nil
   108  	}
   109  
   110  	return doNetNS(netNsPath, func(_ ns.NetNS) error {
   111  		return xDisconnectVMNetwork(endpoint)
   112  	})
   113  }
   114  
   115  // HotAttach for the veth endpoint uses hot plug device
   116  func (endpoint *VethEndpoint) HotAttach(h hypervisor) error {
   117  	if err := xConnectVMNetwork(endpoint, h); err != nil {
   118  		networkLogger().WithError(err).Error("Error bridging virtual ep")
   119  		return err
   120  	}
   121  
   122  	if _, err := h.hotplugAddDevice(endpoint, netDev); err != nil {
   123  		networkLogger().WithError(err).Error("Error attach virtual ep")
   124  		return err
   125  	}
   126  	return nil
   127  }
   128  
   129  // HotDetach for the veth endpoint uses hot pull device
   130  func (endpoint *VethEndpoint) HotDetach(h hypervisor, netNsCreated bool, netNsPath string) error {
   131  	if !netNsCreated {
   132  		return nil
   133  	}
   134  
   135  	if err := doNetNS(netNsPath, func(_ ns.NetNS) error {
   136  		return xDisconnectVMNetwork(endpoint)
   137  	}); err != nil {
   138  		networkLogger().WithError(err).Warn("Error un-bridging virtual ep")
   139  	}
   140  
   141  	if _, err := h.hotplugRemoveDevice(endpoint, netDev); err != nil {
   142  		networkLogger().WithError(err).Error("Error detach virtual ep")
   143  		return err
   144  	}
   145  	return nil
   146  }
   147  
   148  func (endpoint *VethEndpoint) save() persistapi.NetworkEndpoint {
   149  	netpair := saveNetIfPair(&endpoint.NetPair)
   150  
   151  	return persistapi.NetworkEndpoint{
   152  		Type: string(endpoint.Type()),
   153  		Veth: &persistapi.VethEndpoint{
   154  			NetPair: *netpair,
   155  		},
   156  	}
   157  }
   158  
   159  func (endpoint *VethEndpoint) load(s persistapi.NetworkEndpoint) {
   160  	endpoint.EndpointType = VethEndpointType
   161  
   162  	if s.Veth != nil {
   163  		netpair := loadNetIfPair(&s.Veth.NetPair)
   164  		endpoint.NetPair = *netpair
   165  	}
   166  }