Skip to content

Commit 48a9983

Browse files
q2venPaolo Abeni
authored andcommitted
selftest: af_unix: Check EPOLLPRI after every send()/recv() in msg_oob.c
When OOB data is in recvq, we can detect it with epoll by checking EPOLLPRI. This patch add checks for EPOLLPRI after every send() and recv() in all test cases. Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
1 parent d02689e commit 48a9983

1 file changed

Lines changed: 147 additions & 0 deletions

File tree

tools/testing/selftests/net/af_unix/msg_oob.c

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <unistd.h>
77

88
#include <netinet/in.h>
9+
#include <sys/epoll.h>
910
#include <sys/ioctl.h>
1011
#include <sys/signalfd.h>
1112
#include <sys/socket.h>
@@ -22,6 +23,9 @@ FIXTURE(msg_oob)
2223
* 3: TCP receiver
2324
*/
2425
int signal_fd;
26+
int epoll_fd[2]; /* 0: AF_UNIX receiver
27+
* 1: TCP receiver
28+
*/
2529
bool tcp_compliant;
2630
};
2731

@@ -109,6 +113,25 @@ static void setup_sigurg(struct __test_metadata *_metadata,
109113
ASSERT_EQ(ret, -1);
110114
}
111115

116+
static void setup_epollpri(struct __test_metadata *_metadata,
117+
FIXTURE_DATA(msg_oob) *self)
118+
{
119+
struct epoll_event event = {
120+
.events = EPOLLPRI,
121+
};
122+
int i;
123+
124+
for (i = 0; i < 2; i++) {
125+
int ret;
126+
127+
self->epoll_fd[i] = epoll_create1(0);
128+
ASSERT_GE(self->epoll_fd[i], 0);
129+
130+
ret = epoll_ctl(self->epoll_fd[i], EPOLL_CTL_ADD, self->fd[i * 2 + 1], &event);
131+
ASSERT_EQ(ret, 0);
132+
}
133+
}
134+
112135
static void close_sockets(FIXTURE_DATA(msg_oob) *self)
113136
{
114137
int i;
@@ -123,6 +146,7 @@ FIXTURE_SETUP(msg_oob)
123146
create_tcp_socketpair(_metadata, self);
124147

125148
setup_sigurg(_metadata, self);
149+
setup_epollpri(_metadata, self);
126150

127151
self->tcp_compliant = true;
128152
}
@@ -132,6 +156,29 @@ FIXTURE_TEARDOWN(msg_oob)
132156
close_sockets(self);
133157
}
134158

159+
static void __epollpair(struct __test_metadata *_metadata,
160+
FIXTURE_DATA(msg_oob) *self,
161+
bool oob_remaining)
162+
{
163+
struct epoll_event event[2] = {};
164+
int i, ret[2];
165+
166+
for (i = 0; i < 2; i++)
167+
ret[i] = epoll_wait(self->epoll_fd[i], &event[i], 1, 0);
168+
169+
ASSERT_EQ(ret[0], oob_remaining);
170+
171+
if (self->tcp_compliant)
172+
ASSERT_EQ(ret[0], ret[1]);
173+
174+
if (oob_remaining) {
175+
ASSERT_EQ(event[0].events, EPOLLPRI);
176+
177+
if (self->tcp_compliant)
178+
ASSERT_EQ(event[0].events, event[1].events);
179+
}
180+
}
181+
135182
static void __sendpair(struct __test_metadata *_metadata,
136183
FIXTURE_DATA(msg_oob) *self,
137184
const void *buf, size_t len, int flags)
@@ -254,6 +301,9 @@ static void __setinlinepair(struct __test_metadata *_metadata,
254301
expected_buf, expected_len, buf_len, flags); \
255302
} while (0)
256303

304+
#define epollpair(oob_remaining) \
305+
__epollpair(_metadata, self, oob_remaining)
306+
257307
#define setinlinepair() \
258308
__setinlinepair(_metadata, self)
259309

@@ -265,182 +315,279 @@ static void __setinlinepair(struct __test_metadata *_metadata,
265315
TEST_F(msg_oob, non_oob)
266316
{
267317
sendpair("x", 1, 0);
318+
epollpair(false);
268319

269320
recvpair("", -EINVAL, 1, MSG_OOB);
321+
epollpair(false);
270322
}
271323

272324
TEST_F(msg_oob, oob)
273325
{
274326
sendpair("x", 1, MSG_OOB);
327+
epollpair(true);
275328

276329
recvpair("x", 1, 1, MSG_OOB);
330+
epollpair(false);
277331
}
278332

279333
TEST_F(msg_oob, oob_drop)
280334
{
281335
sendpair("x", 1, MSG_OOB);
336+
epollpair(true);
282337

283338
recvpair("", -EAGAIN, 1, 0); /* Drop OOB. */
339+
epollpair(false);
340+
284341
recvpair("", -EINVAL, 1, MSG_OOB);
342+
epollpair(false);
285343
}
286344

287345
TEST_F(msg_oob, oob_ahead)
288346
{
289347
sendpair("hello", 5, MSG_OOB);
348+
epollpair(true);
290349

291350
recvpair("o", 1, 1, MSG_OOB);
351+
epollpair(false);
352+
292353
recvpair("hell", 4, 4, 0);
354+
epollpair(false);
293355
}
294356

295357
TEST_F(msg_oob, oob_break)
296358
{
297359
sendpair("hello", 5, MSG_OOB);
360+
epollpair(true);
298361

299362
recvpair("hell", 4, 5, 0); /* Break at OOB even with enough buffer. */
363+
epollpair(true);
364+
300365
recvpair("o", 1, 1, MSG_OOB);
366+
epollpair(false);
301367
}
302368

303369
TEST_F(msg_oob, oob_ahead_break)
304370
{
305371
sendpair("hello", 5, MSG_OOB);
372+
epollpair(true);
373+
306374
sendpair("world", 5, 0);
375+
epollpair(true);
307376

308377
recvpair("o", 1, 1, MSG_OOB);
378+
epollpair(false);
379+
309380
recvpair("hell", 4, 9, 0); /* Break at OOB even after it's recv()ed. */
381+
epollpair(false);
382+
310383
recvpair("world", 5, 5, 0);
384+
epollpair(false);
311385
}
312386

313387
TEST_F(msg_oob, oob_break_drop)
314388
{
315389
sendpair("hello", 5, MSG_OOB);
390+
epollpair(true);
391+
316392
sendpair("world", 5, 0);
393+
epollpair(true);
317394

318395
recvpair("hell", 4, 10, 0); /* Break at OOB even with enough buffer. */
396+
epollpair(true);
397+
319398
recvpair("world", 5, 10, 0); /* Drop OOB and recv() the next skb. */
399+
epollpair(false);
400+
320401
recvpair("", -EINVAL, 1, MSG_OOB);
402+
epollpair(false);
321403
}
322404

323405
TEST_F(msg_oob, ex_oob_break)
324406
{
325407
sendpair("hello", 5, MSG_OOB);
408+
epollpair(true);
409+
326410
sendpair("wor", 3, MSG_OOB);
411+
epollpair(true);
412+
327413
sendpair("ld", 2, 0);
414+
epollpair(true);
328415

329416
recvpair("hellowo", 7, 10, 0); /* Break at OOB but not at ex-OOB. */
417+
epollpair(true);
418+
330419
recvpair("r", 1, 1, MSG_OOB);
420+
epollpair(false);
421+
331422
recvpair("ld", 2, 2, 0);
423+
epollpair(false);
332424
}
333425

334426
TEST_F(msg_oob, ex_oob_drop)
335427
{
336428
sendpair("x", 1, MSG_OOB);
429+
epollpair(true);
430+
337431
sendpair("y", 1, MSG_OOB); /* TCP drops "x" at this moment. */
432+
epollpair(true);
338433

339434
tcp_incompliant {
340435
recvpair("x", 1, 1, 0); /* TCP drops "y" by passing through it. */
436+
epollpair(true);
437+
341438
recvpair("y", 1, 1, MSG_OOB); /* TCP returns -EINVAL. */
439+
epollpair(false);
342440
}
343441
}
344442

345443
TEST_F(msg_oob, ex_oob_drop_2)
346444
{
347445
sendpair("x", 1, MSG_OOB);
446+
epollpair(true);
447+
348448
sendpair("y", 1, MSG_OOB); /* TCP drops "x" at this moment. */
449+
epollpair(true);
349450

350451
recvpair("y", 1, 1, MSG_OOB);
452+
epollpair(false);
351453

352454
tcp_incompliant {
353455
recvpair("x", 1, 1, 0); /* TCP returns -EAGAIN. */
456+
epollpair(false);
354457
}
355458
}
356459

357460
TEST_F(msg_oob, ex_oob_ahead_break)
358461
{
359462
sendpair("hello", 5, MSG_OOB);
463+
epollpair(true);
464+
360465
sendpair("wor", 3, MSG_OOB);
466+
epollpair(true);
361467

362468
recvpair("r", 1, 1, MSG_OOB);
469+
epollpair(false);
363470

364471
sendpair("ld", 2, MSG_OOB);
472+
epollpair(true);
365473

366474
tcp_incompliant {
367475
recvpair("hellowol", 8, 10, 0); /* TCP recv()s "helloworl", why "r" ?? */
368476
}
369477

478+
epollpair(true);
479+
370480
recvpair("d", 1, 1, MSG_OOB);
481+
epollpair(false);
371482
}
372483

373484
TEST_F(msg_oob, inline_oob)
374485
{
375486
setinlinepair();
376487

377488
sendpair("x", 1, MSG_OOB);
489+
epollpair(true);
378490

379491
recvpair("", -EINVAL, 1, MSG_OOB);
492+
epollpair(true);
493+
380494
recvpair("x", 1, 1, 0);
495+
epollpair(false);
381496
}
382497

383498
TEST_F(msg_oob, inline_oob_break)
384499
{
385500
setinlinepair();
386501

387502
sendpair("hello", 5, MSG_OOB);
503+
epollpair(true);
388504

389505
recvpair("", -EINVAL, 1, MSG_OOB);
506+
epollpair(true);
507+
390508
recvpair("hell", 4, 5, 0); /* Break at OOB but not at ex-OOB. */
509+
epollpair(true);
510+
391511
recvpair("o", 1, 1, 0);
512+
epollpair(false);
392513
}
393514

394515
TEST_F(msg_oob, inline_oob_ahead_break)
395516
{
396517
sendpair("hello", 5, MSG_OOB);
518+
epollpair(true);
519+
397520
sendpair("world", 5, 0);
521+
epollpair(true);
398522

399523
recvpair("o", 1, 1, MSG_OOB);
524+
epollpair(false);
400525

401526
setinlinepair();
402527

403528
recvpair("hell", 4, 9, 0); /* Break at OOB even with enough buffer. */
529+
epollpair(false);
404530

405531
tcp_incompliant {
406532
recvpair("world", 5, 6, 0); /* TCP recv()s "oworld", ... "o" ??? */
407533
}
534+
535+
epollpair(false);
408536
}
409537

410538
TEST_F(msg_oob, inline_ex_oob_break)
411539
{
412540
sendpair("hello", 5, MSG_OOB);
541+
epollpair(true);
542+
413543
sendpair("wor", 3, MSG_OOB);
544+
epollpair(true);
545+
414546
sendpair("ld", 2, 0);
547+
epollpair(true);
415548

416549
setinlinepair();
417550

418551
recvpair("hellowo", 7, 10, 0); /* Break at OOB but not at ex-OOB. */
552+
epollpair(true);
553+
419554
recvpair("rld", 3, 3, 0);
555+
epollpair(false);
420556
}
421557

422558
TEST_F(msg_oob, inline_ex_oob_no_drop)
423559
{
424560
sendpair("x", 1, MSG_OOB);
561+
epollpair(true);
425562

426563
setinlinepair();
427564

428565
sendpair("y", 1, MSG_OOB); /* TCP does NOT drops "x" at this moment. */
566+
epollpair(true);
429567

430568
recvpair("x", 1, 1, 0);
569+
epollpair(true);
570+
431571
recvpair("y", 1, 1, 0);
572+
epollpair(false);
432573
}
433574

434575
TEST_F(msg_oob, inline_ex_oob_drop)
435576
{
436577
sendpair("x", 1, MSG_OOB);
578+
epollpair(true);
579+
437580
sendpair("y", 1, MSG_OOB); /* TCP drops "x" at this moment. */
581+
epollpair(true);
438582

439583
setinlinepair();
440584

441585
tcp_incompliant {
442586
recvpair("x", 1, 1, 0); /* TCP recv()s "y". */
587+
epollpair(true);
588+
443589
recvpair("y", 1, 1, 0); /* TCP returns -EAGAIN. */
590+
epollpair(false);
444591
}
445592
}
446593

0 commit comments

Comments
 (0)