On Tue, Feb 21, 2023 at 06:33:32PM +0900, Nobuhiro MIKI wrote:
> On 2023/02/21 2:23, Simon Horman wrote:
> > On Tue, Feb 14, 2023 at 12:39:05PM +0900, Nobuhiro MIKI wrote:
> >> When adding a route with ovs/route/add command, the source address
> >> in "ovs_router_entry" structure is always the FIRST address that the
> >> interface has. See "ovs_router_get_netdev_source_address"
> >> function for more information.
> >>
> >> If an interface has multiple ipv4 and/or ipv6 addresses, there are use
> >> cases where the user wants to control the source address. This patch
> >> therefore addresses this issue by adding a src parameter.
> >>
> >> Note that same constraints also exist when caching routes from
> >> Kernel FIB with Netlink, but are not dealt with in this patch.
> >>
> >> Signed-off-by: Nobuhiro MIKI <[email protected]>
> >
> > aside: this patch was base64 encoded, which is slightly inconvenient
> > on my side (which is not important in itself). Curiously
> > the other patches in this series are not.
>
> There was a warning from git send-mail. Perhaps the modification of the man
> page might be the cause of some misjudgment. Sorry for the inconvenience.
Thanks. No need to spend any more time on the base64 question.
> >> diff --git a/lib/ovs-router.c b/lib/ovs-router.c
> >> index 5d0fbd503e9e..8f2587444034 100644
> >> --- a/lib/ovs-router.c
> >> +++ b/lib/ovs-router.c
> >> @@ -164,6 +164,47 @@ static void rt_init_match(struct match *match,
> >> uint32_t mark,
> >> match->flow.pkt_mark = mark;
> >> }
> >>
> >> +static int
> >
> > Maybe bool is a more appropriate return type for this function?
> > Likewise for ovs_router_get_netdev_source_address().
> > But perhaps that is a cleanup for another time.
>
> Yes, boolean is appropriate here. I'll fix it.
>
> > Also, there is a lot of comonality between verify_prefsrc()
> > and ovs_router_get_netdev_source_address(). I am curious to know
> > if you considered combining them, or otherwise sharing code between them?
>
> I am aware that many parts are common in those two functions.
>
> However, to my ability, the logic to search for a source address
> and the logic to verify one given source address do not merge well,
> so I have split them into two functions.
>
> It would probably be possible to put them together by dividing
> the cases according to whether the prefsrc is null or not, but
> it would complicate the logic in the loop.
Understood. There is a balance to be had between clean and
avoiding duplication.
...
> >> @@ -236,11 +278,21 @@ ovs_router_insert__(uint32_t mark, uint8_t priority,
> >> bool local,
> >> p->plen = plen;
> >> p->local = local;
> >> p->priority = priority;
> >> - err = ovs_router_get_netdev_source_address(ip6_dst, output_bridge,
> >> - &p->src_addr);
> >> - if (err && ipv6_addr_is_set(gw)) {
> >> - err = ovs_router_get_netdev_source_address(gw, output_bridge,
> >> +
> >> + if (ipv6_addr_is_set(ip6_src)) {
> >> + p->src_addr = *ip6_src;
> >> +
> >> + err = verify_prefsrc(ip6_dst, output_bridge, &p->src_addr);
> >> + if (err && ipv6_addr_is_set(gw)) {
> >> + err = verify_prefsrc(gw, output_bridge, &p->src_addr);
> >> + }
> >> + } else {
> >> + err = ovs_router_get_netdev_source_address(ip6_dst, output_bridge,
> >> &p->src_addr);
> >> + if (err && ipv6_addr_is_set(gw)) {
> >> + err = ovs_router_get_netdev_source_address(gw, output_bridge,
> >> + &p->src_addr);
> >> + }
> >> }
> >
> > This seems very repetitive. Combining verify_prefsrc() and
> > ovs_router_get_netdev_source_address() might simplify things.
> >
> > Another idea I had was to use a function pointer.
> >
> > *compile tested only*
> >
> >
> > int (*f)(const struct in6_addr *ip6_dst,
> > const char output_bridge[],
> > struct in6_addr *prefsrc);
> >
> > ...
> >
> >
> > if (ipv6_addr_is_set(ip6_src)) {
> > p->src_addr = *ip6_src;
> >
> > f = verify_prefsrc;
> > } else {
> > f = ovs_router_get_netdev_source_address;
> > }
> >
> > err = f(ip6_dst, output_bridge, &p->src_addr);
> > if (err && ipv6_addr_is_set(gw)) {
> > err = f(gw, output_bridge, &p->src_addr);
> > }
>
> Oh thanks. This is clean code using a function pointer,
> I'll try this idea if it's difficult to combine the two functions.
Thanks.
...
> >> } else if (scan_ipv6_route(argv[1], &ip6, &plen)) {
> >> - if (argc > 3) {
> >> - if (!ovs_scan(argv[3], "pkt_mark=%"SCNi32, &mark) &&
> >> - !ipv6_parse(argv[3], &gw6)) {
> >> - unixctl_command_reply_error(conn, "Invalid pkt_mark or
> >> IPv6 gateway");
> >> - return;
> >> - }
> >> - }
> >> + is_ipv6 = true;
> >> } else {
> >> unixctl_command_reply_error(conn, "Invalid parameters");
> >> return;
> >> }
> >> - if (argc > 4) {
> >> - if (!ovs_scan(argv[4], "pkt_mark=%"SCNi32, &mark)) {
> >> - unixctl_command_reply_error(conn, "Invalid pkt_mark");
> >> - return;
> >> +
> >> + /* Parse optional parameters. */
> >> + for (i = 3; i < argc; i++) {
> >> + if (ovs_scan(argv[i], "pkt_mark=%"SCNi32, &mark)) {
> >> + continue;
> >> }
> >> +
> >> + if (is_ipv6) {
> >> + if (ovs_scan(argv[i], "src="IPV6_SCAN_FMT, src6_s) &&
> >> + ipv6_parse(src6_s, &src6)) {
> >> + continue;
> >> + }
> >> + if (ipv6_parse(argv[i], &gw6)) {
> >> + continue;
> >> + }
> >> + } else {
> >> + if (ovs_scan(argv[i], "src="IP_SCAN_FMT, IP_SCAN_ARGS(&src)))
> >> {
> >> + continue;
> >> + }
> >> + if (ip_parse(argv[i], &gw)) {
> >> + continue;
> >> + }
> >> + }
> >
> > If I read this correctly then, before this patch gw (if present)
> > must come before pkt_mark (if present). A maximum of two arguments
> > are parsed for gw and pkt_mark. And pkt_mark, but not gw,
> > may occur twice (in which case gw is not parsed).
> >
> > But after this patch pkt_mark, gw and src may come in any order.
> > And each may occur any number of times.
>
> Yes, this behavior matches purpose of this patch.
>
> > Perhaps my analysis is wrong. But my question is, are there
> > any backwards compatibility issues here?
> >
> > Also, perhaps it would be best to refactor the parser, as a cleanup
> > patch, then add support for 'src'.
>
> After this patch, I think that optional parameters can be given more
> flexibly without breaking backwards compatibility.
>
> pkt_mark, gw and src are normally expected to be specified exactly once.
> However, as with other tools, if specified multiple times, the last
> specification is used.
>
> Also, pkt_mark, gw and src have separate prefix strings so they can be
> parsed in any order.
On reflection, yes I agree.
I don't think there are any backwards compatibility issues.
And this approach does seem nicer.
> I'll a cleanup patch before this patch.
Great, thanks.
...
> >> diff --git a/ofproto/ofproto-tnl-unixctl.man
> >> b/ofproto/ofproto-tnl-unixctl.man
> >> index 13a465119a90..3d8f8261f3c4 100644
> >> --- a/ofproto/ofproto-tnl-unixctl.man
> >> +++ b/ofproto/ofproto-tnl-unixctl.man
> >> @@ -1,8 +1,9 @@
> >> .SS "OPENVSWITCH TUNNELING COMMANDS"
> >> These commands query and modify OVS tunnel components.
> >> .
> >> -.IP "\fBovs/route/add ipv4_address/plen output_bridge [GW]\fR"
> >> -Adds ipv4_address/plen route to vswitchd routing table. output_bridge
> >> +.IP "\fBovs/route/add \fIip\fB/\fIplen\fB \fIoutput_bridge\fB \
> >> +[\fIgateway\fB] [pkt_mark=\fImark\fB] [src=\fIsrc_ip\fB]\fR"
> >> +Adds \fIip\fR/\fIplen\fR route to vswitchd routing table.
> >> \fIoutput_bridge\fR
> >> needs to be OVS bridge name. This command is useful if OVS cached
> >> routes does not look right.
> >> .
> >> @@ -10,8 +11,8 @@ routes does not look right.
> >> Print all routes in OVS routing table, This includes routes cached
> >> from system routing table and user configured routes.
> >> .
> >> -.IP "\fBovs/route/del ipv4_address/plen\fR"
> >> -Delete ipv4_address/plen route from OVS routing table.
> >> +.IP "\fBovs/route/del \fIip\fB/\fIplen\fR"
> >> +Delete \fIip\fR/\fIplen\fR route from OVS routing table.
> >> .
> >> .IP "\fBtnl/neigh/show\fR"
> >> .IP "\fBtnl/arp/show\fR"
> >
> > Is the reason for the s/ipv4_address/ip/ portion of the man page changes
> > because both IPv4 and IPv6 are supported?
> >
> > If so is that also the case before this patch?
> >
> > If so, perhaps that change should be in a separate patch.
>
> Both ipv4 and ipv6 were supported before this patch. So this fix is necessary,
> but out of scope, so it is removed from this patch series.
Thanks. IMHO it's find to make this change in this patch-set.
But I think a separate patch is warranted.
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev