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 <nm...@yahoo-corp.jp> > > > > 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 d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev