This repository has been archived by the owner on May 12, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 374
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #811 from amshinde/network_refactor
Refactor network.go
- Loading branch information
Showing
18 changed files
with
1,368 additions
and
1,239 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
// Copyright (c) 2018 Intel Corporation | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
package virtcontainers | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/containernetworking/plugins/pkg/ns" | ||
) | ||
|
||
// BridgedMacvlanEndpoint represents a macvlan endpoint that is bridged to the VM | ||
type BridgedMacvlanEndpoint struct { | ||
NetPair NetworkInterfacePair | ||
EndpointProperties NetworkInfo | ||
EndpointType EndpointType | ||
PCIAddr string | ||
} | ||
|
||
func createBridgedMacvlanNetworkEndpoint(idx int, ifName string, interworkingModel NetInterworkingModel) (*BridgedMacvlanEndpoint, error) { | ||
if idx < 0 { | ||
return &BridgedMacvlanEndpoint{}, fmt.Errorf("invalid network endpoint index: %d", idx) | ||
} | ||
|
||
netPair, err := createNetworkInterfacePair(idx, ifName, interworkingModel) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
endpoint := &BridgedMacvlanEndpoint{ | ||
NetPair: netPair, | ||
EndpointType: BridgedMacvlanEndpointType, | ||
} | ||
if ifName != "" { | ||
endpoint.NetPair.VirtIface.Name = ifName | ||
} | ||
|
||
return endpoint, nil | ||
} | ||
|
||
// Properties returns properties of the interface. | ||
func (endpoint *BridgedMacvlanEndpoint) Properties() NetworkInfo { | ||
return endpoint.EndpointProperties | ||
} | ||
|
||
// Name returns name of the veth interface in the network pair. | ||
func (endpoint *BridgedMacvlanEndpoint) Name() string { | ||
return endpoint.NetPair.VirtIface.Name | ||
} | ||
|
||
// HardwareAddr returns the mac address that is assigned to the tap interface | ||
// in th network pair. | ||
func (endpoint *BridgedMacvlanEndpoint) HardwareAddr() string { | ||
return endpoint.NetPair.TAPIface.HardAddr | ||
} | ||
|
||
// Type identifies the endpoint as a virtual endpoint. | ||
func (endpoint *BridgedMacvlanEndpoint) Type() EndpointType { | ||
return endpoint.EndpointType | ||
} | ||
|
||
// SetProperties sets the properties for the endpoint. | ||
func (endpoint *BridgedMacvlanEndpoint) SetProperties(properties NetworkInfo) { | ||
endpoint.EndpointProperties = properties | ||
} | ||
|
||
// PciAddr returns the PCI address of the endpoint. | ||
func (endpoint *BridgedMacvlanEndpoint) PciAddr() string { | ||
return endpoint.PCIAddr | ||
} | ||
|
||
// NetworkPair returns the network pair of the endpoint. | ||
func (endpoint *BridgedMacvlanEndpoint) NetworkPair() *NetworkInterfacePair { | ||
return &endpoint.NetPair | ||
} | ||
|
||
// Attach for virtual endpoint bridges the network pair and adds the | ||
// tap interface of the network pair to the hypervisor. | ||
func (endpoint *BridgedMacvlanEndpoint) Attach(h hypervisor) error { | ||
if err := xconnectVMNetwork(endpoint, true, h.hypervisorConfig().NumVCPUs, h.hypervisorConfig().DisableVhostNet); err != nil { | ||
networkLogger().WithError(err).Error("Error bridging virtual ep") | ||
return err | ||
} | ||
|
||
return h.addDevice(endpoint, netDev) | ||
} | ||
|
||
// Detach for the virtual endpoint tears down the tap and bridge | ||
// created for the veth interface. | ||
func (endpoint *BridgedMacvlanEndpoint) Detach(netNsCreated bool, netNsPath string) error { | ||
// The network namespace would have been deleted at this point | ||
// if it has not been created by virtcontainers. | ||
if !netNsCreated { | ||
return nil | ||
} | ||
|
||
return doNetNS(netNsPath, func(_ ns.NetNS) error { | ||
return xconnectVMNetwork(endpoint, false, 0, false) | ||
}) | ||
} | ||
|
||
// HotAttach for physical endpoint not supported yet | ||
func (endpoint *BridgedMacvlanEndpoint) HotAttach(h hypervisor) error { | ||
return fmt.Errorf("BridgedMacvlanEndpoint does not support Hot attach") | ||
} | ||
|
||
// HotDetach for physical endpoint not supported yet | ||
func (endpoint *BridgedMacvlanEndpoint) HotDetach(h hypervisor, netNsCreated bool, netNsPath string) error { | ||
return fmt.Errorf("BridgedMacvlanEndpoint does not support Hot detach") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// Copyright (c) 2018 Intel Corporation | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
package virtcontainers | ||
|
||
import ( | ||
"net" | ||
"reflect" | ||
"testing" | ||
) | ||
|
||
func TestCreateBridgedMacvlanEndpoint(t *testing.T) { | ||
macAddr := net.HardwareAddr{0x02, 0x00, 0xCA, 0xFE, 0x00, 0x04} | ||
|
||
expected := &BridgedMacvlanEndpoint{ | ||
NetPair: NetworkInterfacePair{ | ||
ID: "uniqueTestID-4", | ||
Name: "br4_kata", | ||
VirtIface: NetworkInterface{ | ||
Name: "eth4", | ||
HardAddr: macAddr.String(), | ||
}, | ||
TAPIface: NetworkInterface{ | ||
Name: "tap4_kata", | ||
}, | ||
NetInterworkingModel: DefaultNetInterworkingModel, | ||
}, | ||
EndpointType: BridgedMacvlanEndpointType, | ||
} | ||
|
||
result, err := createBridgedMacvlanNetworkEndpoint(4, "", DefaultNetInterworkingModel) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
// the resulting ID will be random - so let's overwrite to test the rest of the flow | ||
result.NetPair.ID = "uniqueTestID-4" | ||
|
||
// the resulting mac address will be random - so lets overwrite it | ||
result.NetPair.VirtIface.HardAddr = macAddr.String() | ||
|
||
if reflect.DeepEqual(result, expected) == false { | ||
t.Fatalf("\nGot: %+v, \n\nExpected: %+v", result, expected) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
// Copyright (c) 2018 Intel Corporation | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
package virtcontainers | ||
|
||
import ( | ||
"fmt" | ||
) | ||
|
||
// Endpoint represents a physical or virtual network interface. | ||
type Endpoint interface { | ||
Properties() NetworkInfo | ||
Name() string | ||
HardwareAddr() string | ||
Type() EndpointType | ||
PciAddr() string | ||
NetworkPair() *NetworkInterfacePair | ||
|
||
SetProperties(NetworkInfo) | ||
Attach(hypervisor) error | ||
Detach(netNsCreated bool, netNsPath string) error | ||
HotAttach(h hypervisor) error | ||
HotDetach(h hypervisor, netNsCreated bool, netNsPath string) error | ||
} | ||
|
||
// EndpointType identifies the type of the network endpoint. | ||
type EndpointType string | ||
|
||
const ( | ||
// PhysicalEndpointType is the physical network interface. | ||
PhysicalEndpointType EndpointType = "physical" | ||
|
||
// VethEndpointType is the virtual network interface. | ||
VethEndpointType EndpointType = "virtual" | ||
|
||
// VhostUserEndpointType is the vhostuser network interface. | ||
VhostUserEndpointType EndpointType = "vhost-user" | ||
|
||
// BridgedMacvlanEndpointType is macvlan network interface. | ||
BridgedMacvlanEndpointType EndpointType = "macvlan" | ||
|
||
// MacvtapEndpointType is macvtap network interface. | ||
MacvtapEndpointType EndpointType = "macvtap" | ||
) | ||
|
||
// Set sets an endpoint type based on the input string. | ||
func (endpointType *EndpointType) Set(value string) error { | ||
switch value { | ||
case "physical": | ||
*endpointType = PhysicalEndpointType | ||
return nil | ||
case "virtual": | ||
*endpointType = VethEndpointType | ||
return nil | ||
case "vhost-user": | ||
*endpointType = VhostUserEndpointType | ||
return nil | ||
case "macvlan": | ||
*endpointType = BridgedMacvlanEndpointType | ||
return nil | ||
case "macvtap": | ||
*endpointType = MacvtapEndpointType | ||
return nil | ||
default: | ||
return fmt.Errorf("Unknown endpoint type %s", value) | ||
} | ||
} | ||
|
||
// String converts an endpoint type to a string. | ||
func (endpointType *EndpointType) String() string { | ||
switch *endpointType { | ||
case PhysicalEndpointType: | ||
return string(PhysicalEndpointType) | ||
case VethEndpointType: | ||
return string(VethEndpointType) | ||
case VhostUserEndpointType: | ||
return string(VhostUserEndpointType) | ||
case BridgedMacvlanEndpointType: | ||
return string(BridgedMacvlanEndpointType) | ||
case MacvtapEndpointType: | ||
return string(MacvtapEndpointType) | ||
default: | ||
return "" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
// Copyright (c) 2018 Intel Corporation | ||
// | ||
// SPDX-License-Identifier: Apache-2.0 | ||
// | ||
|
||
package virtcontainers | ||
|
||
import "testing" | ||
|
||
func testEndpointTypeSet(t *testing.T, value string, expected EndpointType) { | ||
//var netModel NetworkModel | ||
var endpointType EndpointType | ||
|
||
err := endpointType.Set(value) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
if endpointType != expected { | ||
t.Fatal() | ||
} | ||
} | ||
|
||
func TestPhysicalEndpointTypeSet(t *testing.T) { | ||
testEndpointTypeSet(t, "physical", PhysicalEndpointType) | ||
} | ||
|
||
func TestVethEndpointTypeSet(t *testing.T) { | ||
testEndpointTypeSet(t, "virtual", VethEndpointType) | ||
} | ||
|
||
func TestVhostUserEndpointTypeSet(t *testing.T) { | ||
testEndpointTypeSet(t, "vhost-user", VhostUserEndpointType) | ||
} | ||
|
||
func TestBridgedMacvlanEndpointTypeSet(t *testing.T) { | ||
testEndpointTypeSet(t, "macvlan", BridgedMacvlanEndpointType) | ||
} | ||
|
||
func TestMacvtapEndpointTypeSet(t *testing.T) { | ||
testEndpointTypeSet(t, "macvtap", MacvtapEndpointType) | ||
} | ||
|
||
func TestEndpointTypeSetFailure(t *testing.T) { | ||
var endpointType EndpointType | ||
|
||
err := endpointType.Set("wrong-value") | ||
if err == nil { | ||
t.Fatal(err) | ||
} | ||
} | ||
|
||
func testEndpointTypeString(t *testing.T, endpointType *EndpointType, expected string) { | ||
result := endpointType.String() | ||
|
||
if result != expected { | ||
t.Fatal() | ||
} | ||
} | ||
|
||
func TestPhysicalEndpointTypeString(t *testing.T) { | ||
endpointType := PhysicalEndpointType | ||
testEndpointTypeString(t, &endpointType, string(PhysicalEndpointType)) | ||
} | ||
|
||
func TestVethEndpointTypeString(t *testing.T) { | ||
endpointType := VethEndpointType | ||
testEndpointTypeString(t, &endpointType, string(VethEndpointType)) | ||
} | ||
|
||
func TestVhostUserEndpointTypeString(t *testing.T) { | ||
endpointType := VhostUserEndpointType | ||
testEndpointTypeString(t, &endpointType, string(VhostUserEndpointType)) | ||
} | ||
|
||
func TestBridgedMacvlanEndpointTypeString(t *testing.T) { | ||
endpointType := BridgedMacvlanEndpointType | ||
testEndpointTypeString(t, &endpointType, string(BridgedMacvlanEndpointType)) | ||
} | ||
|
||
func TestMacvtapEndpointTypeString(t *testing.T) { | ||
endpointType := MacvtapEndpointType | ||
testEndpointTypeString(t, &endpointType, string(MacvtapEndpointType)) | ||
} | ||
|
||
func TestIncorrectEndpointTypeString(t *testing.T) { | ||
var endpointType EndpointType | ||
testEndpointTypeString(t, &endpointType, "") | ||
} |
Oops, something went wrong.