Skip to content

Commit 187bbb6

Browse files
IurmanJPaolo Abeni
authored andcommitted
selftests: ioam: refactoring to align with the fix
ioam6_parser uses a packet socket. After the fix to prevent writing to cloned skb's, the receiver does not see its IOAM data anymore, which makes input/forward ioam-selftests to fail. As a workaround, ioam6_parser now uses an IPv6 raw socket and leverages ancillary data to get hop-by-hop options. As a consequence, the hook is "after" the IOAM data insertion by the receiver and all tests are working again. Signed-off-by: Justin Iurman <[email protected]> Signed-off-by: Paolo Abeni <[email protected]>
1 parent f198d93 commit 187bbb6

File tree

2 files changed

+66
-67
lines changed

2 files changed

+66
-67
lines changed

tools/testing/selftests/net/ioam6.sh

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -367,14 +367,12 @@ run_test()
367367
local desc=$2
368368
local node_src=$3
369369
local node_dst=$4
370-
local ip6_src=$5
371-
local ip6_dst=$6
372-
local if_dst=$7
373-
local trace_type=$8
374-
local ioam_ns=$9
375-
376-
ip netns exec $node_dst ./ioam6_parser $if_dst $name $ip6_src $ip6_dst \
377-
$trace_type $ioam_ns &
370+
local ip6_dst=$5
371+
local trace_type=$6
372+
local ioam_ns=$7
373+
local type=$8
374+
375+
ip netns exec $node_dst ./ioam6_parser $name $trace_type $ioam_ns $type &
378376
local spid=$!
379377
sleep 0.1
380378

@@ -489,7 +487,7 @@ out_undef_ns()
489487
trace prealloc type 0x800000 ns 0 size 4 dev veth0
490488

491489
run_test ${FUNCNAME[0]} "${desc} ($1 mode)" $ioam_node_alpha $ioam_node_beta \
492-
db01::2 db01::1 veth0 0x800000 0
490+
db01::1 0x800000 0 $1
493491

494492
[ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 down
495493
}
@@ -509,7 +507,7 @@ out_no_room()
509507
trace prealloc type 0xc00000 ns 123 size 4 dev veth0
510508

511509
run_test ${FUNCNAME[0]} "${desc} ($1 mode)" $ioam_node_alpha $ioam_node_beta \
512-
db01::2 db01::1 veth0 0xc00000 123
510+
db01::1 0xc00000 123 $1
513511

514512
[ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 down
515513
}
@@ -543,14 +541,14 @@ out_bits()
543541
if [ $cmd_res != 0 ]
544542
then
545543
npassed=$((npassed+1))
546-
log_test_passed "$descr"
544+
log_test_passed "$descr ($1 mode)"
547545
else
548546
nfailed=$((nfailed+1))
549-
log_test_failed "$descr"
547+
log_test_failed "$descr ($1 mode)"
550548
fi
551549
else
552550
run_test "out_bit$i" "$descr ($1 mode)" $ioam_node_alpha \
553-
$ioam_node_beta db01::2 db01::1 veth0 ${bit2type[$i]} 123
551+
$ioam_node_beta db01::1 ${bit2type[$i]} 123 $1
554552
fi
555553
done
556554

@@ -574,7 +572,7 @@ out_full_supp_trace()
574572
trace prealloc type 0xfff002 ns 123 size 100 dev veth0
575573

576574
run_test ${FUNCNAME[0]} "${desc} ($1 mode)" $ioam_node_alpha $ioam_node_beta \
577-
db01::2 db01::1 veth0 0xfff002 123
575+
db01::1 0xfff002 123 $1
578576

579577
[ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 down
580578
}
@@ -604,7 +602,7 @@ in_undef_ns()
604602
trace prealloc type 0x800000 ns 0 size 4 dev veth0
605603

606604
run_test ${FUNCNAME[0]} "${desc} ($1 mode)" $ioam_node_alpha $ioam_node_beta \
607-
db01::2 db01::1 veth0 0x800000 0
605+
db01::1 0x800000 0 $1
608606

609607
[ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 down
610608
}
@@ -624,7 +622,7 @@ in_no_room()
624622
trace prealloc type 0xc00000 ns 123 size 4 dev veth0
625623

626624
run_test ${FUNCNAME[0]} "${desc} ($1 mode)" $ioam_node_alpha $ioam_node_beta \
627-
db01::2 db01::1 veth0 0xc00000 123
625+
db01::1 0xc00000 123 $1
628626

629627
[ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 down
630628
}
@@ -651,7 +649,7 @@ in_bits()
651649
dev veth0
652650

653651
run_test "in_bit$i" "${desc/<n>/$i} ($1 mode)" $ioam_node_alpha \
654-
$ioam_node_beta db01::2 db01::1 veth0 ${bit2type[$i]} 123
652+
$ioam_node_beta db01::1 ${bit2type[$i]} 123 $1
655653
done
656654

657655
[ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 down
@@ -679,7 +677,7 @@ in_oflag()
679677
trace prealloc type 0xc00000 ns 123 size 4 dev veth0
680678

681679
run_test ${FUNCNAME[0]} "${desc} ($1 mode)" $ioam_node_alpha $ioam_node_beta \
682-
db01::2 db01::1 veth0 0xc00000 123
680+
db01::1 0xc00000 123 $1
683681

684682
[ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 down
685683

@@ -703,7 +701,7 @@ in_full_supp_trace()
703701
trace prealloc type 0xfff002 ns 123 size 80 dev veth0
704702

705703
run_test ${FUNCNAME[0]} "${desc} ($1 mode)" $ioam_node_alpha $ioam_node_beta \
706-
db01::2 db01::1 veth0 0xfff002 123
704+
db01::1 0xfff002 123 $1
707705

708706
[ "$1" = "encap" ] && ip -netns $ioam_node_beta link set ip6tnl0 down
709707
}
@@ -731,7 +729,7 @@ fwd_full_supp_trace()
731729
trace prealloc type 0xfff002 ns 123 size 244 via db01::1 dev veth0
732730

733731
run_test ${FUNCNAME[0]} "${desc} ($1 mode)" $ioam_node_alpha $ioam_node_gamma \
734-
db01::2 db02::2 veth0 0xfff002 123
732+
db02::2 0xfff002 123 $1
735733

736734
[ "$1" = "encap" ] && ip -netns $ioam_node_gamma link set ip6tnl0 down
737735
}

tools/testing/selftests/net/ioam6_parser.c

Lines changed: 48 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
#include <errno.h>
99
#include <limits.h>
1010
#include <linux/const.h>
11-
#include <linux/if_ether.h>
1211
#include <linux/ioam6.h>
1312
#include <linux/ipv6.h>
1413
#include <stdlib.h>
@@ -512,14 +511,6 @@ static int str2id(const char *tname)
512511
return -1;
513512
}
514513

515-
static int ipv6_addr_equal(const struct in6_addr *a1, const struct in6_addr *a2)
516-
{
517-
return ((a1->s6_addr32[0] ^ a2->s6_addr32[0]) |
518-
(a1->s6_addr32[1] ^ a2->s6_addr32[1]) |
519-
(a1->s6_addr32[2] ^ a2->s6_addr32[2]) |
520-
(a1->s6_addr32[3] ^ a2->s6_addr32[3])) == 0;
521-
}
522-
523514
static int get_u32(__u32 *val, const char *arg, int base)
524515
{
525516
unsigned long res;
@@ -603,70 +594,80 @@ static int (*func[__TEST_MAX])(int, struct ioam6_trace_hdr *, __u32, __u16) = {
603594

604595
int main(int argc, char **argv)
605596
{
606-
int fd, size, hoplen, tid, ret = 1;
607-
struct in6_addr src, dst;
597+
int fd, size, hoplen, tid, ret = 1, on = 1;
608598
struct ioam6_hdr *opt;
609-
struct ipv6hdr *ip6h;
610-
__u8 buffer[400], *p;
611-
__u16 ioam_ns;
599+
struct cmsghdr *cmsg;
600+
struct msghdr msg;
601+
struct iovec iov;
602+
__u8 buffer[512];
612603
__u32 tr_type;
604+
__u16 ioam_ns;
605+
__u8 *ptr;
613606

614-
if (argc != 7)
607+
if (argc != 5)
615608
goto out;
616609

617-
tid = str2id(argv[2]);
610+
tid = str2id(argv[1]);
618611
if (tid < 0 || !func[tid])
619612
goto out;
620613

621-
if (inet_pton(AF_INET6, argv[3], &src) != 1 ||
622-
inet_pton(AF_INET6, argv[4], &dst) != 1)
614+
if (get_u32(&tr_type, argv[2], 16) ||
615+
get_u16(&ioam_ns, argv[3], 0))
623616
goto out;
624617

625-
if (get_u32(&tr_type, argv[5], 16) ||
626-
get_u16(&ioam_ns, argv[6], 0))
618+
fd = socket(PF_INET6, SOCK_RAW,
619+
!strcmp(argv[4], "encap") ? IPPROTO_IPV6 : IPPROTO_ICMPV6);
620+
if (fd < 0)
627621
goto out;
628622

629-
fd = socket(AF_PACKET, SOCK_DGRAM, __cpu_to_be16(ETH_P_IPV6));
630-
if (!fd)
631-
goto out;
623+
setsockopt(fd, IPPROTO_IPV6, IPV6_RECVHOPOPTS, &on, sizeof(on));
632624

633-
if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE,
634-
argv[1], strlen(argv[1])))
625+
iov.iov_len = 1;
626+
iov.iov_base = malloc(CMSG_SPACE(sizeof(buffer)));
627+
if (!iov.iov_base)
635628
goto close;
636-
637629
recv:
638-
size = recv(fd, buffer, sizeof(buffer), 0);
630+
memset(&msg, 0, sizeof(msg));
631+
msg.msg_iov = &iov;
632+
msg.msg_iovlen = 1;
633+
msg.msg_control = buffer;
634+
msg.msg_controllen = CMSG_SPACE(sizeof(buffer));
635+
636+
size = recvmsg(fd, &msg, 0);
639637
if (size <= 0)
640638
goto close;
641639

642-
ip6h = (struct ipv6hdr *)buffer;
640+
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
641+
if (cmsg->cmsg_level != IPPROTO_IPV6 ||
642+
cmsg->cmsg_type != IPV6_HOPOPTS ||
643+
cmsg->cmsg_len < sizeof(struct ipv6_hopopt_hdr))
644+
continue;
643645

644-
if (!ipv6_addr_equal(&ip6h->saddr, &src) ||
645-
!ipv6_addr_equal(&ip6h->daddr, &dst))
646-
goto recv;
646+
ptr = (__u8 *)CMSG_DATA(cmsg);
647647

648-
if (ip6h->nexthdr != IPPROTO_HOPOPTS)
649-
goto close;
648+
hoplen = (ptr[1] + 1) << 3;
649+
ptr += sizeof(struct ipv6_hopopt_hdr);
650650

651-
p = buffer + sizeof(*ip6h);
652-
hoplen = (p[1] + 1) << 3;
653-
p += sizeof(struct ipv6_hopopt_hdr);
651+
while (hoplen > 0) {
652+
opt = (struct ioam6_hdr *)ptr;
654653

655-
while (hoplen > 0) {
656-
opt = (struct ioam6_hdr *)p;
654+
if (opt->opt_type == IPV6_TLV_IOAM &&
655+
opt->type == IOAM6_TYPE_PREALLOC) {
656+
ptr += sizeof(*opt);
657+
ret = func[tid](tid,
658+
(struct ioam6_trace_hdr *)ptr,
659+
tr_type, ioam_ns);
660+
goto close;
661+
}
657662

658-
if (opt->opt_type == IPV6_TLV_IOAM &&
659-
opt->type == IOAM6_TYPE_PREALLOC) {
660-
p += sizeof(*opt);
661-
ret = func[tid](tid, (struct ioam6_trace_hdr *)p,
662-
tr_type, ioam_ns);
663-
break;
663+
ptr += opt->opt_len + 2;
664+
hoplen -= opt->opt_len + 2;
664665
}
665-
666-
p += opt->opt_len + 2;
667-
hoplen -= opt->opt_len + 2;
668666
}
667+
668+
goto recv;
669669
close:
670+
free(iov.iov_base);
670671
close(fd);
671672
out:
672673
return ret;

0 commit comments

Comments
 (0)