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