|
@@ -20,12 +20,17 @@ const (
|
|
)
|
|
)
|
|
|
|
|
|
// createIPVlan Create the ipvlan slave specifying the source name
|
|
// createIPVlan Create the ipvlan slave specifying the source name
|
|
-func createIPVlan(containerIfName, parent, ipvlanMode string) (string, error) {
|
|
|
|
- // Set the ipvlan mode. Default is bridge mode
|
|
|
|
|
|
+func createIPVlan(containerIfName, parent, ipvlanMode, ipvlanFlag string) (string, error) {
|
|
|
|
+ // Set the ipvlan mode and flag. Default is L2 bridge
|
|
mode, err := setIPVlanMode(ipvlanMode)
|
|
mode, err := setIPVlanMode(ipvlanMode)
|
|
if err != nil {
|
|
if err != nil {
|
|
return "", fmt.Errorf("Unsupported %s ipvlan mode: %v", ipvlanMode, err)
|
|
return "", fmt.Errorf("Unsupported %s ipvlan mode: %v", ipvlanMode, err)
|
|
}
|
|
}
|
|
|
|
+ // Set the ipvlan flag. Default is bridge
|
|
|
|
+ flag, err := setIPVlanFlag(ipvlanFlag)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return "", fmt.Errorf("Unsupported %s ipvlan flag: %v", ipvlanFlag, err)
|
|
|
|
+ }
|
|
// verify the Docker host interface acting as the macvlan parent iface exists
|
|
// verify the Docker host interface acting as the macvlan parent iface exists
|
|
if !parentExists(parent) {
|
|
if !parentExists(parent) {
|
|
return "", fmt.Errorf("the requested parent interface %s was not found on the Docker host", parent)
|
|
return "", fmt.Errorf("the requested parent interface %s was not found on the Docker host", parent)
|
|
@@ -42,6 +47,7 @@ func createIPVlan(containerIfName, parent, ipvlanMode string) (string, error) {
|
|
ParentIndex: parentLink.Attrs().Index,
|
|
ParentIndex: parentLink.Attrs().Index,
|
|
},
|
|
},
|
|
Mode: mode,
|
|
Mode: mode,
|
|
|
|
+ Flag: flag,
|
|
}
|
|
}
|
|
if err := ns.NlHandle().LinkAdd(ipvlan); err != nil {
|
|
if err := ns.NlHandle().LinkAdd(ipvlan); err != nil {
|
|
// If a user creates a macvlan and ipvlan on same parent, only one slave iface can be active at a time.
|
|
// If a user creates a macvlan and ipvlan on same parent, only one slave iface can be active at a time.
|
|
@@ -51,18 +57,34 @@ func createIPVlan(containerIfName, parent, ipvlanMode string) (string, error) {
|
|
return ipvlan.Attrs().Name, nil
|
|
return ipvlan.Attrs().Name, nil
|
|
}
|
|
}
|
|
|
|
|
|
-// setIPVlanMode setter for one of the two ipvlan port types
|
|
|
|
|
|
+// setIPVlanMode setter for one of the three ipvlan port types
|
|
func setIPVlanMode(mode string) (netlink.IPVlanMode, error) {
|
|
func setIPVlanMode(mode string) (netlink.IPVlanMode, error) {
|
|
switch mode {
|
|
switch mode {
|
|
case modeL2:
|
|
case modeL2:
|
|
return netlink.IPVLAN_MODE_L2, nil
|
|
return netlink.IPVLAN_MODE_L2, nil
|
|
case modeL3:
|
|
case modeL3:
|
|
return netlink.IPVLAN_MODE_L3, nil
|
|
return netlink.IPVLAN_MODE_L3, nil
|
|
|
|
+ case modeL3S:
|
|
|
|
+ return netlink.IPVLAN_MODE_L3S, nil
|
|
default:
|
|
default:
|
|
return 0, fmt.Errorf("Unknown ipvlan mode: %s", mode)
|
|
return 0, fmt.Errorf("Unknown ipvlan mode: %s", mode)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// setIPVlanFlag setter for one of the three ipvlan port flags
|
|
|
|
+func setIPVlanFlag(flag string) (netlink.IPVlanFlag, error) {
|
|
|
|
+ switch flag {
|
|
|
|
+ case flagBridge:
|
|
|
|
+ return netlink.IPVLAN_FLAG_BRIDGE, nil
|
|
|
|
+ case flagPrivate:
|
|
|
|
+ return netlink.IPVLAN_FLAG_PRIVATE, nil
|
|
|
|
+ case flagVepa:
|
|
|
|
+ return netlink.IPVLAN_FLAG_VEPA, nil
|
|
|
|
+ default:
|
|
|
|
+ return 0, fmt.Errorf("unknown ipvlan flag: %s", flag)
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
// parentExists check if the specified interface exists in the default namespace
|
|
// parentExists check if the specified interface exists in the default namespace
|
|
func parentExists(ifaceStr string) bool {
|
|
func parentExists(ifaceStr string) bool {
|
|
_, err := ns.NlHandle().LinkByName(ifaceStr)
|
|
_, err := ns.NlHandle().LinkByName(ifaceStr)
|