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
SDN-1569: Add support for multiple destinations in redirect mode #34
SDN-1569: Add support for multiple destinations in redirect mode #34
Conversation
Presently if more than one destination is specified through the "destinations" array in the NAD, we only pick the first destination and ignore the rest. This patch adds support for multiple destinations. Also in OCP 3.11 we used to support multiple destination specification in 3 formats: 1)["ip-address/mask"] 2)["port protocol ip-address/mask"] 3)["port protocol ip-address/mask remote-port"] in multiple lines. We do the same for feature parity.
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.
Overall LGTM, It'd be cool to have unit tests for this. As the PR for the unit testing support is also on WIP let's create a follow-up patch for that.
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: danielmellado, tssurya The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
@@ -270,6 +271,79 @@ func macvlanCmdDel(args *skel.CmdArgs) error { | |||
return err | |||
} | |||
|
|||
// validatePortRange validates the destination port value provided in the NAD. |
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.
As this (and the following) are "util" functions, it's good practice to have them after the function that consumes them (in this case macVlanCmdAdd), so the reader finds the "important" stuff first
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.
Will move this in the next iteration when adding unit tests.
dest, _, err := net.ParseCIDR(destination[0]) | ||
if err != nil { | ||
logging.Errorf("Unable to parse destination IP address %v: %v", dest, err) | ||
return fmt.Errorf("Unable to parse destination IP address %v: %v", dest, 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.
you can use errors.Wrapf here
} else if len(destination) == 3 || len(destination) == 4 { | ||
// should be <localport protocol IPaddress/mask> format | ||
|
||
if err := validatePortRange(destination[0]); err != nil { |
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 wonder if this plus the check on the protocol could be compacted in a single "validateDestionation" function, making this a bit more readable
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.
ideally, I'd prefer to create a new file validation.go
in the future where we can move the validation stuff.
continue | ||
} | ||
|
||
ipt.Append("nat", "PREROUTING", "-i", "eth0", "-p", destination[1], "--dport", destination[0], "-j", "DNAT", "--to-destination", dest.String()) |
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.
if the remoteport is specified, do we still add this rule?
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.
if the remoteport is specified, then we continue to the next item in the loop on L334 and don't add this rule.
return fmt.Errorf("Unable to parse destination IP address %v: %v", dest.String(), err) | ||
} | ||
|
||
if len(destination) == 4 && validatePortRange(destination[3]) == nil { |
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.
this nested if is a bit tricky to read, maybe splitting the one above (to the cost of duplicating some code) would make it more straightforward?
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, I didn't want to duplicate code...
/retest Please review the full test history for this PR and help us cut down flakes. |
Presently if more than one destination is specified through the
destinations
array in the NAD, we only pick the first destinationand ignore the rest. This patch adds support for multiple
destinations.
Also in OCP 3.11 we used to support multiple destination specification
in 3 formats:
in multiple lines. We do the same for feature parity.
Note that the
allowedDestinations
field in CRD (same as thedestinations
field in the NAD) is just an array of strings, so right now we only support redirect mode. IN future if http/dns modes are supported, we can add further checks for dns aliases/hostnames that could get provided.Note to reviewers: Unit tests can be added in future when the unit test module gets merged.
Sample Test done:
NAD:
Router:
IPTables output: