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 }