On 3/22/23 00:41, Ilya Maximets wrote: > On 3/15/23 07:07, Nobuhiro MIKI wrote: >> This patch adds ODP actions for SRv6 and its tests. >> >> Signed-off-by: Nobuhiro MIKI <nm...@yahoo-corp.jp> >> --- >> lib/odp-util.c | 56 +++++++++++++++++++++++++++++++++++ >> python/ovs/flow/odp.py | 8 +++++ >> python/ovs/tests/test_odp.py | 16 ++++++++++ >> tests/odp.at | 1 + >> tests/tunnel-push-pop-ipv6.at | 23 ++++++++++++++ >> 5 files changed, 104 insertions(+) >> >> diff --git a/lib/odp-util.c b/lib/odp-util.c >> index dbd4554d0626..75f4d5242183 100644 >> --- a/lib/odp-util.c >> +++ b/lib/odp-util.c >> @@ -714,6 +714,24 @@ format_odp_tnl_push_header(struct ds *ds, struct >> ovs_action_push_tnl *data) >> ds_put_char(ds, ')'); >> } >> >> + ds_put_char(ds, ')'); >> + } else if (data->tnl_type == OVS_VPORT_TYPE_SRV6) { >> + const struct srv6_base_hdr *srh; >> + struct in6_addr *segs; >> + int nr_segs; >> + int i; >> + >> + srh = (const struct srv6_base_hdr *) l4; >> + segs = ALIGNED_CAST(struct in6_addr *, srh + 1); >> + nr_segs = srh->last_entry + 1; >> + >> + ds_put_format(ds, "srv6("); >> + ds_put_format(ds, "segments_left=%d", srh->rt_hdr.segments_left); >> + ds_put_format(ds, ",segs="); >> + for (i = 0; i < nr_segs; i++) { >> + ds_put_format(ds, i > 0 ? "," : ""); >> + ipv6_format_addr(&segs[nr_segs - i - 1], ds); >> + } >> ds_put_char(ds, ')'); >> } else if (data->tnl_type == OVS_VPORT_TYPE_GRE || >> data->tnl_type == OVS_VPORT_TYPE_IP6GRE) { >> @@ -1534,6 +1552,7 @@ ovs_parse_tnl_push(const char *s, struct >> ovs_action_push_tnl *data) >> uint8_t hwid, dir; >> uint32_t teid; >> uint8_t gtpu_flags, gtpu_msgtype; >> + uint8_t segments_left; >> >> if (!ovs_scan_len(s, &n, "tnl_push(tnl_port(%"SCNi32"),", >> &data->tnl_port)) { >> return -EINVAL; >> @@ -1775,6 +1794,43 @@ ovs_parse_tnl_push(const char *s, struct >> ovs_action_push_tnl *data) >> tnl_type = OVS_VPORT_TYPE_GTPU; >> header_len = sizeof *eth + ip_len + >> sizeof *udp + sizeof *gtph; >> + } else if (ovs_scan_len(s, &n, "srv6(segments_left=%"SCNu8, >> + &segments_left)) { >> + struct srv6_base_hdr *srh = (struct srv6_base_hdr *) (ip6 + 1); >> + uint8_t n_segs = segments_left + 1; >> + char seg_s[IPV6_SCAN_LEN + 1]; >> + struct in6_addr *segs; >> + struct in6_addr seg; >> + >> + ip6->ip6_nxt = IPPROTO_ROUTING; >> + >> + srh->rt_hdr.type = IPV6_SRCRT_TYPE_4; >> + srh->rt_hdr.segments_left = segments_left; >> + srh->rt_hdr.hdrlen = 2 * n_segs; >> + srh->last_entry = n_segs - 1; >> + >> + tnl_type = OVS_VPORT_TYPE_SRV6; >> + header_len = sizeof *eth + ip_len + >> + sizeof *srh + 8 * srh->rt_hdr.hdrlen; >> + >> + /* Parse segment list */ >> + if (!ovs_scan_len(s, &n, ",segs="IPV6_SCAN_FMT, seg_s) >> + || inet_pton(AF_INET6, seg_s, &seg) != 1) { >> + return -EINVAL; >> + } >> + >> + segs = ALIGNED_CAST(struct in6_addr *, srh + 1); >> + segs += n_segs - 1; >> + memcpy(segs--, &seg, sizeof(struct in6_addr)); >> + >> + while (ovs_scan_len(s, &n, ","IPV6_SCAN_FMT, seg_s) >> + && inet_pton(AF_INET6, seg_s, &seg) == 1) { >> + memcpy(segs--, &seg, sizeof(struct in_addr)); > > We will overwrite the header here if segments_left + 1 is less > than total number of specified segments. E.g. in the following > case: srv6(segments_left=0,segs=2001:cafe::92,2001:cafe::93). > > One solution for this may be to create an SRV6_MAX_SEGS + 1 sized > array and parse values there. Once all the values parsed, > copy them into an actual header. If more than SRV6_MAX_SEGS > values found, then fail the parsing. > > What do you think? > > Also, the sizeof seems incorrect here. It should be in6, not in. > It also should be just 'sizeof *segs' to avoid any potential > problems of this kind. > > Would be good to add a test to tests/odp.at for many segments > parsing while segments_left is small. > > And it's probably possible to avoid some code duplication here. > E.g. (didn't test): > > if (strncmp(s, ",segs=", 6)) { > return -EINVAL; > } > s += 6;
We need to check &s[n] and advance n, of course. :/ > while (ovs_scan_len(s, &n, IPV6_SCAN_FMT, seg_s) > && inet_pton(AF_INET6, seg_s, &seg) == 1) { > > ... > > if (s[n] == ',') { > s++; n++ here. > } > } > > Best regards, Ilya Maximets. _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev