-
Notifications
You must be signed in to change notification settings - Fork 793
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bridge: Add mac field to specify container iface mac #636
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -55,6 +55,25 @@ type NetConf struct { | |
HairpinMode bool `json:"hairpinMode"` | ||
PromiscMode bool `json:"promiscMode"` | ||
Vlan int `json:"vlan"` | ||
|
||
Args struct { | ||
Cni BridgeArgs `json:"cni,omitempty"` | ||
} `json:"args,omitempty"` | ||
RuntimeConfig struct { | ||
Mac string `json:"mac,omitempty"` | ||
} `json:"runtimeConfig,omitempty"` | ||
|
||
mac string | ||
} | ||
|
||
type BridgeArgs struct { | ||
Mac string `json:"mac,omitempty"` | ||
} | ||
|
||
// MacEnvArgs represents CNI_ARGS | ||
type MacEnvArgs struct { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't the name be something more abstract, because it might contain more kinds of args in the future? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, this is the type boilerplate to automatically parse CNI_ARGS "MAC=FOO" strings. |
||
types.CommonArgs | ||
MAC types.UnmarshallableString `json:"mac,omitempty"` | ||
} | ||
|
||
type gwInfo struct { | ||
|
@@ -70,7 +89,7 @@ func init() { | |
runtime.LockOSThread() | ||
} | ||
|
||
func loadNetConf(bytes []byte) (*NetConf, string, error) { | ||
func loadNetConf(bytes []byte, envArgs string) (*NetConf, string, error) { | ||
n := &NetConf{ | ||
BrName: defaultBrName, | ||
} | ||
|
@@ -80,6 +99,26 @@ func loadNetConf(bytes []byte) (*NetConf, string, error) { | |
if n.Vlan < 0 || n.Vlan > 4094 { | ||
return nil, "", fmt.Errorf("invalid VLAN ID %d (must be between 0 and 4094)", n.Vlan) | ||
} | ||
|
||
if envArgs != "" { | ||
e := MacEnvArgs{} | ||
if err := types.LoadArgs(envArgs, &e); err != nil { | ||
return nil, "", err | ||
} | ||
|
||
if e.MAC != "" { | ||
dcbw marked this conversation as resolved.
Show resolved
Hide resolved
|
||
n.mac = string(e.MAC) | ||
} | ||
} | ||
|
||
if mac := n.Args.Cni.Mac; mac != "" { | ||
n.mac = mac | ||
} | ||
|
||
if mac := n.RuntimeConfig.Mac; mac != "" { | ||
n.mac = mac | ||
} | ||
|
||
return n, n.CNIVersion, nil | ||
} | ||
|
||
|
@@ -273,7 +312,7 @@ func ensureVlanInterface(br *netlink.Bridge, vlanId int) (netlink.Link, error) { | |
return nil, fmt.Errorf("faild to find host namespace: %v", err) | ||
} | ||
|
||
_, brGatewayIface, err := setupVeth(hostNS, br, name, br.MTU, false, vlanId) | ||
_, brGatewayIface, err := setupVeth(hostNS, br, name, br.MTU, false, vlanId, "") | ||
if err != nil { | ||
return nil, fmt.Errorf("faild to create vlan gateway %q: %v", name, err) | ||
} | ||
|
@@ -287,13 +326,13 @@ func ensureVlanInterface(br *netlink.Bridge, vlanId int) (netlink.Link, error) { | |
return brGatewayVeth, nil | ||
} | ||
|
||
func setupVeth(netns ns.NetNS, br *netlink.Bridge, ifName string, mtu int, hairpinMode bool, vlanID int) (*current.Interface, *current.Interface, error) { | ||
func setupVeth(netns ns.NetNS, br *netlink.Bridge, ifName string, mtu int, hairpinMode bool, vlanID int, mac string) (*current.Interface, *current.Interface, error) { | ||
contIface := ¤t.Interface{} | ||
hostIface := ¤t.Interface{} | ||
|
||
err := netns.Do(func(hostNS ns.NetNS) error { | ||
// create the veth pair in the container and move host end into host netns | ||
hostVeth, containerVeth, err := ip.SetupVeth(ifName, mtu, hostNS) | ||
hostVeth, containerVeth, err := ip.SetupVeth(ifName, mtu, mac, hostNS) | ||
if err != nil { | ||
return err | ||
} | ||
|
@@ -380,7 +419,7 @@ func enableIPForward(family int) error { | |
func cmdAdd(args *skel.CmdArgs) error { | ||
var success bool = false | ||
|
||
n, cniVersion, err := loadNetConf(args.StdinData) | ||
n, cniVersion, err := loadNetConf(args.StdinData, args.Args) | ||
if err != nil { | ||
return err | ||
} | ||
|
@@ -406,7 +445,7 @@ func cmdAdd(args *skel.CmdArgs) error { | |
} | ||
defer netns.Close() | ||
|
||
hostInterface, containerInterface, err := setupVeth(netns, br, args.IfName, n.MTU, n.HairpinMode, n.Vlan) | ||
hostInterface, containerInterface, err := setupVeth(netns, br, args.IfName, n.MTU, n.HairpinMode, n.Vlan, n.mac) | ||
if err != nil { | ||
return err | ||
} | ||
|
@@ -585,7 +624,7 @@ func cmdAdd(args *skel.CmdArgs) error { | |
} | ||
|
||
func cmdDel(args *skel.CmdArgs) error { | ||
n, _, err := loadNetConf(args.StdinData) | ||
n, _, err := loadNetConf(args.StdinData, args.Args) | ||
if err != nil { | ||
return err | ||
} | ||
|
@@ -776,7 +815,7 @@ func validateCniContainerInterface(intf current.Interface) (cniBridgeIf, error) | |
|
||
func cmdCheck(args *skel.CmdArgs) error { | ||
|
||
n, _, err := loadNetConf(args.StdinData) | ||
n, _, err := loadNetConf(args.StdinData, args.Args) | ||
if err != nil { | ||
return err | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why this test case is separated into three steps? and I don't see the necessity of the third step
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I followed the format of the previous test.
I agree that the first two steps can be merged, they execute on the same netns so there is no reason to split them.
Perhaps the original reason for the split was to emphasize that the first step is the setup while the second is the assertion.
Anyway, I merged them.
The 3rd step is validating that the mac address specified is not assigned to the host side of the veth peer. It seemed a reasonable check to me.