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 }