-
Notifications
You must be signed in to change notification settings - Fork 791
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
bridge: Add mac field to specify container iface mac #636
Conversation
@squeed I have added the support for CNI_ARGS, Args and RunningConfig parameters. Can you please approve the CI run? |
I believe that this would fix #450 as well. |
This looks pretty good. @s1061123 would you mind giving this a quick review? |
Personal nit pick - can this be a single commit? |
/lgtm |
The idea was to make it easy for reviewers to go over it in stages. The changes are independent, stand by themselves and give a nicer "story" in the history (the details in the tests may look messy when looked as one change). |
@@ -233,6 +233,37 @@ var _ = Describe("Link", func() { | |||
}) | |||
}) | |||
|
|||
It("successfully creates a veth pair with an explicit mac", func() { | |||
const mac = "02:00:00:00:01:23" |
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.
plugins/main/bridge/bridge.go
Outdated
} `json:"args,omitempty"` | ||
RuntimeConfig struct { | ||
Mac string `json:"mac,omitempty"` | ||
} `json:"runtimeConfig,omit"` |
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.
nit: omit --> omitempty
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.
Thanks! Done.
plugins/main/bridge/bridge.go
Outdated
@@ -55,6 +55,24 @@ type NetConf struct { | |||
HairpinMode bool `json:"hairpinMode"` | |||
PromiscMode bool `json:"promiscMode"` | |||
Vlan int `json:"vlan"` | |||
Mac string `json:"mac,omitempty"` |
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.
Mac
field here is internal, it should be ignored when marshalling
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 do you think it is internal?
All existing plugins here (macvlan, tuning) allow setting the mac through the network configuration and not only though the runtime parameters.
At the moment, this looks like a consistent behavior to have the parameters as a subset of the configuration.
Are you suggesting not to expose this parameter at the network configuration level?
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.
@EdDev this is the netconf for the overall Bridge, not the container interface. A 'mac' field here would be the MAC of the bridge itself, not the container veth. It shouldn't be here because per-container options are not specified int he top-level plugin config struct. That's what the runtime args and CNI_ARGS are for.
The difference with macvlan and tuning is they do not have a "parent" interface like the bridge plugin does, so the MAC specified in the config there can only apply to the container interface.
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.
@dcbw for the purpose of original requirement, I can take it out of the netconf. However, it seems to me that by doing so will break an existing convention where the runtime parameters are (always?) a subset of the netconf.
But again, I have no need for it and it is indeed odd to have this mac
field defined at the network level.
If there no other opinions on this, I will take it out.
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.
Done
d1bcb40
to
089b7d3
Compare
change: Responding to review. |
As far as I looked the diff, the 'mac' field could be provided through following ways:
So if user fills different MAC address in those fields, which MAC will wins? |
I think the order is suppose to be part of the convention. There is an explicit statement where @squeed , am I correct here? Is there another specification where this is defined? Do you think it is worth updating the convention document to clarify this? |
In convention.md, it seems not to be mentioned clearly (explicitly) yet, I guess. @squeed Do you have any plan to mention the priority among Args/CNI_ARGS/RuntimeConfig in spec? |
Controlling the mac address of the interface (veth peer) in the container is useful for functionalities that depend on the mac address. Examples range from dynamic IP allocations based on an identifier (the mac) and up to firewall rules (e.g. no-mac-spoofing). Enforcing a mac address at an early stage and not through a chained plugin assures the configuration does not have wrong intermediate configuration. This is especially critical when a dynamic IP may be provided already in this period. But it also has implications for future abilities that may land on the bridge plugin, e.g. supporting no-mac-spoofing. The field name used (`mac`) fits with other plugins which control the mac address of the container interface. The mac address may be specified through the following methods: - CNI_ARGS - Args - RuntimeConfig [1] The list is ordered by priority, from lowest to higher. The higher priority method overrides any previous settings. (e.g. if the mac is specified in RuntimeConfig, it will override any specifications of the mac mentioned in CNI_ARGS or Args) [1] To use RuntimeConfig, the network configuration should include the `capabilities` field with `mac` specified (`"capabilities": {"mac": true}`). Signed-off-by: Edward Haas <[email protected]>
089b7d3
to
a3cde17
Compare
Change: Answered review requests
|
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.
thank you Eddi. Really Nice!
I am not so familiar with this subject, but (as I asked also in the inline comments) are all macs acceptable for a veth at this stage, or there are limitations ? what happens if the mac being set breaks the limitation?
For example I think that the bridges mac should be the smallest of all macs of the veths that are connected to this bridge. Do we care about this kind of limitation at this stage, and is there something should be done to enforce it ?
} | ||
|
||
// MacEnvArgs represents CNI_ARGS | ||
type MacEnvArgs struct { |
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.
Shouldn't the name be something more abstract, because it might contain more kinds of args in the future?
I mean, maybe it is better to drop Mac
from the name?
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.
No, this is the type boilerplate to automatically parse CNI_ARGS "MAC=FOO" strings.
@@ -1967,6 +2010,66 @@ var _ = Describe("bridge Operations", func() { | |||
}) | |||
} | |||
|
|||
It(fmt.Sprintf("[%s] uses an explicit MAC addresses for the container iface (from CNI_ARGS)", ver), func() { |
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.
are all macs acceptable for a veth? if no perhaps it is also worth to add a test that shows what suppose to happen if someone sets a "wrong" mac?
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.
Yeah, they are all "valid" here. The kernel will validate and fail the request if the MAC is wrong in some way (all zeros or 1s) and we shouldn't bother trying to reproduce the validation the kernel does I think.
This looks really good, thanks! I think this is ready to go. A second set of eyes would help, but the testcases are nice. By the way, I don't care about argument preference. If you try and specify mac two different ways, then you deserve what happens to you :-) |
/lgtm |
@EdDev now that this has merged, can you file a PR on https://github.com/containernetworking/cni.dev/ that updates the bridge documentation (https://github.com/containernetworking/cni.dev/blob/main/content/plugins/current/main/bridge.md) |
On it first thing tomorrow morning. |
Ref: containernetworking/plugins#636 Signed-off-by: Edward Haas <[email protected]>
Done |
Controlling the mac address of the interface (veth peer) in the
container is useful for functionalities that depend on the mac address.
Examples range from dynamic IP allocations based on an identifier (the
mac) and up to firewall rules (e.g. no-mac-spoofing).
Enforcing a mac address at an early stage and not through a chained
plugin assures the configuration does not have wrong intermediate
configuration. This is especially critical when a dynamic IP may be
provided already in this period.
But it also has implications for future abilities that may land on the
bridge plugin, e.g. supporting no-mac-spoofing.
The field name used (
mac
) fits with other plugins which control themac address of the container interface.
The mac address may be specified through the following methods:
The list is ordered by priority, from lowest to higher. The higher
priority method overrides any previous settings.
(e.g. if the mac is specified in RuntimeConfig, it will override any
specifications of the mac mentioned in CNI_ARGS or Args)
[1] To use RuntimeConfig, the network configuration should include the
capabilities
field withmac
specified ("capabilities": {"mac": true}
).