1 /* 2 * Test functionality of BPF filters for SO_REUSEPORT. The tests below will use 3 * a BPF program (both classic and extended) to read the first word from an 4 * incoming packet (expected to be in network byte-order), calculate a modulus 5 * of that number, and then dispatch the packet to the Nth socket using the 6 * result. These tests are run for each supported address family and protocol. 7 * Additionally, a few edge cases in the implementation are tested. 8 */ 9 10 #include <errno.h> 11 #include <error.h> 12 #include <fcntl.h> 13 #include <linux/bpf.h> 14 #include <linux/filter.h> 15 #include <linux/unistd.h> 16 #include <netinet/in.h> 17 #include <netinet/tcp.h> 18 #include <stdio.h> 19 #include <stdlib.h> 20 #include <string.h> 21 #include <sys/epoll.h> 22 #include <sys/types.h> 23 #include <sys/socket.h> 24 #include <unistd.h> 25 26 #ifndef ARRAY_SIZE 27 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) 28 #endif 29 30 struct test_params { 31 int recv_family; 32 int send_family; 33 int protocol; 34 size_t recv_socks; 35 uint16_t recv_port; 36 uint16_t send_port_min; 37 }; 38 39 static size_t sockaddr_size(void) 40 { 41 return sizeof(struct sockaddr_storage); 42 } 43 44 static struct sockaddr *new_any_sockaddr(int family, uint16_t port) 45 { 46 struct sockaddr_storage *addr; 47 struct sockaddr_in *addr4; 48 struct sockaddr_in6 *addr6; 49 50 addr = malloc(sizeof(struct sockaddr_storage)); 51 memset(addr, 0, sizeof(struct sockaddr_storage)); 52 53 switch (family) { 54 case AF_INET: 55 addr4 = (struct sockaddr_in *)addr; 56 addr4->sin_family = AF_INET; 57 addr4->sin_addr.s_addr = htonl(INADDR_ANY); 58 addr4->sin_port = htons(port); 59 break; 60 case AF_INET6: 61 addr6 = (struct sockaddr_in6 *)addr; 62 addr6->sin6_family = AF_INET6; 63 addr6->sin6_addr = in6addr_any; 64 addr6->sin6_port = htons(port); 65 break; 66 default: 67 error(1, 0, "Unsupported family %d", family); 68 } 69 return (struct sockaddr *)addr; 70 } 71 72 static struct sockaddr *new_loopback_sockaddr(int family, uint16_t port) 73 { 74 struct sockaddr *addr = new_any_sockaddr(family, port); 75 struct sockaddr_in *addr4; 76 struct sockaddr_in6 *addr6; 77 78 switch (family) { 79 case AF_INET: 80 addr4 = (struct sockaddr_in *)addr; 81 addr4->sin_addr.s_addr = htonl(INADDR_LOOPBACK); 82 break; 83 case AF_INET6: 84 addr6 = (struct sockaddr_in6 *)addr; 85 addr6->sin6_addr = in6addr_loopback; 86 break; 87 default: 88 error(1, 0, "Unsupported family %d", family); 89 } 90 return addr; 91 } 92 93 static void attach_ebpf(int fd, uint16_t mod) 94 { 95 static char bpf_log_buf[65536]; 96 static const char bpf_license[] = "GPL"; 97 98 int bpf_fd; 99 const struct bpf_insn prog[] = { 100 /* BPF_MOV64_REG(BPF_REG_6, BPF_REG_1) */ 101 { BPF_ALU64 | BPF_MOV | BPF_X, BPF_REG_6, BPF_REG_1, 0, 0 }, 102 /* BPF_LD_ABS(BPF_W, 0) R0 = (uint32_t)skb[0] */ 103 { BPF_LD | BPF_ABS | BPF_W, 0, 0, 0, 0 }, 104 /* BPF_ALU64_IMM(BPF_MOD, BPF_REG_0, mod) */ 105 { BPF_ALU64 | BPF_MOD | BPF_K, BPF_REG_0, 0, 0, mod }, 106 /* BPF_EXIT_INSN() */ 107 { BPF_JMP | BPF_EXIT, 0, 0, 0, 0 } 108 }; 109 union bpf_attr attr; 110 111 memset(&attr, 0, sizeof(attr)); 112 attr.prog_type = BPF_PROG_TYPE_SOCKET_FILTER; 113 attr.insn_cnt = ARRAY_SIZE(prog); 114 attr.insns = (unsigned long) &prog; 115 attr.license = (unsigned long) &bpf_license; 116 attr.log_buf = (unsigned long) &bpf_log_buf; 117 attr.log_size = sizeof(bpf_log_buf); 118 attr.log_level = 1; 119 attr.kern_version = 0; 120 121 bpf_fd = syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr)); 122 if (bpf_fd < 0) 123 error(1, errno, "ebpf error. log:\n%s\n", bpf_log_buf); 124 125 if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_REUSEPORT_EBPF, &bpf_fd, 126 sizeof(bpf_fd))) 127 error(1, errno, "failed to set SO_ATTACH_REUSEPORT_EBPF"); 128 129 close(bpf_fd); 130 } 131 132 static void attach_cbpf(int fd, uint16_t mod) 133 { 134 struct sock_filter code[] = { 135 /* A = (uint32_t)skb[0] */ 136 { BPF_LD | BPF_W | BPF_ABS, 0, 0, 0 }, 137 /* A = A % mod */ 138 { BPF_ALU | BPF_MOD, 0, 0, mod }, 139 /* return A */ 140 { BPF_RET | BPF_A, 0, 0, 0 }, 141 }; 142 struct sock_fprog p = { 143 .len = ARRAY_SIZE(code), 144 .filter = code, 145 }; 146 147 if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, &p, sizeof(p))) 148 error(1, errno, "failed to set SO_ATTACH_REUSEPORT_CBPF"); 149 } 150 151 static void build_recv_group(const struct test_params p, int fd[], uint16_t mod, 152 void (*attach_bpf)(int, uint16_t)) 153 { 154 struct sockaddr * const addr = 155 new_any_sockaddr(p.recv_family, p.recv_port); 156 int i, opt; 157 158 for (i = 0; i < p.recv_socks; ++i) { 159 fd[i] = socket(p.recv_family, p.protocol, 0); 160 if (fd[i] < 0) 161 error(1, errno, "failed to create recv %d", i); 162 163 opt = 1; 164 if (setsockopt(fd[i], SOL_SOCKET, SO_REUSEPORT, &opt, 165 sizeof(opt))) 166 error(1, errno, "failed to set SO_REUSEPORT on %d", i); 167 168 if (i == 0) 169 attach_bpf(fd[i], mod); 170 171 if (bind(fd[i], addr, sockaddr_size())) 172 error(1, errno, "failed to bind recv socket %d", i); 173 174 if (p.protocol == SOCK_STREAM) { 175 opt = 4; 176 if (setsockopt(fd[i], SOL_TCP, TCP_FASTOPEN, &opt, 177 sizeof(opt))) 178 error(1, errno, 179 "failed to set TCP_FASTOPEN on %d", i); 180 if (listen(fd[i], p.recv_socks * 10)) 181 error(1, errno, "failed to listen on socket"); 182 } 183 } 184 free(addr); 185 } 186 187 static void send_from(struct test_params p, uint16_t sport, char *buf, 188 size_t len) 189 { 190 struct sockaddr * const saddr = new_any_sockaddr(p.send_family, sport); 191 struct sockaddr * const daddr = 192 new_loopback_sockaddr(p.send_family, p.recv_port); 193 const int fd = socket(p.send_family, p.protocol, 0); 194 195 if (fd < 0) 196 error(1, errno, "failed to create send socket"); 197 198 if (bind(fd, saddr, sockaddr_size())) 199 error(1, errno, "failed to bind send socket"); 200 201 if (sendto(fd, buf, len, MSG_FASTOPEN, daddr, sockaddr_size()) < 0) 202 error(1, errno, "failed to send message"); 203 204 close(fd); 205 free(saddr); 206 free(daddr); 207 } 208 209 static void test_recv_order(const struct test_params p, int fd[], int mod) 210 { 211 char recv_buf[8], send_buf[8]; 212 struct msghdr msg; 213 struct iovec recv_io = { recv_buf, 8 }; 214 struct epoll_event ev; 215 int epfd, conn, i, sport, expected; 216 uint32_t data, ndata; 217 218 epfd = epoll_create(1); 219 if (epfd < 0) 220 error(1, errno, "failed to create epoll"); 221 for (i = 0; i < p.recv_socks; ++i) { 222 ev.events = EPOLLIN; 223 ev.data.fd = fd[i]; 224 if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd[i], &ev)) 225 error(1, errno, "failed to register sock %d epoll", i); 226 } 227 228 memset(&msg, 0, sizeof(msg)); 229 msg.msg_iov = &recv_io; 230 msg.msg_iovlen = 1; 231 232 for (data = 0; data < p.recv_socks * 2; ++data) { 233 sport = p.send_port_min + data; 234 ndata = htonl(data); 235 memcpy(send_buf, &ndata, sizeof(ndata)); 236 send_from(p, sport, send_buf, sizeof(ndata)); 237 238 i = epoll_wait(epfd, &ev, 1, -1); 239 if (i < 0) 240 error(1, errno, "epoll wait failed"); 241 242 if (p.protocol == SOCK_STREAM) { 243 conn = accept(ev.data.fd, NULL, NULL); 244 if (conn < 0) 245 error(1, errno, "error accepting"); 246 i = recvmsg(conn, &msg, 0); 247 close(conn); 248 } else { 249 i = recvmsg(ev.data.fd, &msg, 0); 250 } 251 if (i < 0) 252 error(1, errno, "recvmsg error"); 253 if (i != sizeof(ndata)) 254 error(1, 0, "expected size %zd got %d", 255 sizeof(ndata), i); 256 257 for (i = 0; i < p.recv_socks; ++i) 258 if (ev.data.fd == fd[i]) 259 break; 260 memcpy(&ndata, recv_buf, sizeof(ndata)); 261 fprintf(stderr, "Socket %d: %d\n", i, ntohl(ndata)); 262 263 expected = (sport % mod); 264 if (i != expected) 265 error(1, 0, "expected socket %d", expected); 266 } 267 } 268 269 static void test_reuseport_ebpf(struct test_params p) 270 { 271 int i, fd[p.recv_socks]; 272 273 fprintf(stderr, "Testing EBPF mod %zd...\n", p.recv_socks); 274 build_recv_group(p, fd, p.recv_socks, attach_ebpf); 275 test_recv_order(p, fd, p.recv_socks); 276 277 p.send_port_min += p.recv_socks * 2; 278 fprintf(stderr, "Reprograming, testing mod %zd...\n", p.recv_socks / 2); 279 attach_ebpf(fd[0], p.recv_socks / 2); 280 test_recv_order(p, fd, p.recv_socks / 2); 281 282 for (i = 0; i < p.recv_socks; ++i) 283 close(fd[i]); 284 } 285 286 static void test_reuseport_cbpf(struct test_params p) 287 { 288 int i, fd[p.recv_socks]; 289 290 fprintf(stderr, "Testing CBPF mod %zd...\n", p.recv_socks); 291 build_recv_group(p, fd, p.recv_socks, attach_cbpf); 292 test_recv_order(p, fd, p.recv_socks); 293 294 p.send_port_min += p.recv_socks * 2; 295 fprintf(stderr, "Reprograming, testing mod %zd...\n", p.recv_socks / 2); 296 attach_cbpf(fd[0], p.recv_socks / 2); 297 test_recv_order(p, fd, p.recv_socks / 2); 298 299 for (i = 0; i < p.recv_socks; ++i) 300 close(fd[i]); 301 } 302 303 static void test_extra_filter(const struct test_params p) 304 { 305 struct sockaddr * const addr = 306 new_any_sockaddr(p.recv_family, p.recv_port); 307 int fd1, fd2, opt; 308 309 fprintf(stderr, "Testing too many filters...\n"); 310 fd1 = socket(p.recv_family, p.protocol, 0); 311 if (fd1 < 0) 312 error(1, errno, "failed to create socket 1"); 313 fd2 = socket(p.recv_family, p.protocol, 0); 314 if (fd2 < 0) 315 error(1, errno, "failed to create socket 2"); 316 317 opt = 1; 318 if (setsockopt(fd1, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt))) 319 error(1, errno, "failed to set SO_REUSEPORT on socket 1"); 320 if (setsockopt(fd2, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt))) 321 error(1, errno, "failed to set SO_REUSEPORT on socket 2"); 322 323 attach_ebpf(fd1, 10); 324 attach_ebpf(fd2, 10); 325 326 if (bind(fd1, addr, sockaddr_size())) 327 error(1, errno, "failed to bind recv socket 1"); 328 329 if (!bind(fd2, addr, sockaddr_size()) && errno != EADDRINUSE) 330 error(1, errno, "bind socket 2 should fail with EADDRINUSE"); 331 332 free(addr); 333 } 334 335 static void test_filter_no_reuseport(const struct test_params p) 336 { 337 struct sockaddr * const addr = 338 new_any_sockaddr(p.recv_family, p.recv_port); 339 const char bpf_license[] = "GPL"; 340 struct bpf_insn ecode[] = { 341 { BPF_ALU64 | BPF_MOV | BPF_K, BPF_REG_0, 0, 0, 10 }, 342 { BPF_JMP | BPF_EXIT, 0, 0, 0, 0 } 343 }; 344 struct sock_filter ccode[] = {{ BPF_RET | BPF_A, 0, 0, 0 }}; 345 union bpf_attr eprog; 346 struct sock_fprog cprog; 347 int fd, bpf_fd; 348 349 fprintf(stderr, "Testing filters on non-SO_REUSEPORT socket...\n"); 350 351 memset(&eprog, 0, sizeof(eprog)); 352 eprog.prog_type = BPF_PROG_TYPE_SOCKET_FILTER; 353 eprog.insn_cnt = ARRAY_SIZE(ecode); 354 eprog.insns = (unsigned long) &ecode; 355 eprog.license = (unsigned long) &bpf_license; 356 eprog.kern_version = 0; 357 358 memset(&cprog, 0, sizeof(cprog)); 359 cprog.len = ARRAY_SIZE(ccode); 360 cprog.filter = ccode; 361 362 363 bpf_fd = syscall(__NR_bpf, BPF_PROG_LOAD, &eprog, sizeof(eprog)); 364 if (bpf_fd < 0) 365 error(1, errno, "ebpf error"); 366 fd = socket(p.recv_family, p.protocol, 0); 367 if (fd < 0) 368 error(1, errno, "failed to create socket 1"); 369 370 if (bind(fd, addr, sockaddr_size())) 371 error(1, errno, "failed to bind recv socket 1"); 372 373 errno = 0; 374 if (!setsockopt(fd, SOL_SOCKET, SO_ATTACH_REUSEPORT_EBPF, &bpf_fd, 375 sizeof(bpf_fd)) || errno != EINVAL) 376 error(1, errno, "setsockopt should have returned EINVAL"); 377 378 errno = 0; 379 if (!setsockopt(fd, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, &cprog, 380 sizeof(cprog)) || errno != EINVAL) 381 error(1, errno, "setsockopt should have returned EINVAL"); 382 383 free(addr); 384 } 385 386 static void test_filter_without_bind(void) 387 { 388 int fd1, fd2, opt = 1; 389 390 fprintf(stderr, "Testing filter add without bind...\n"); 391 fd1 = socket(AF_INET, SOCK_DGRAM, 0); 392 if (fd1 < 0) 393 error(1, errno, "failed to create socket 1"); 394 fd2 = socket(AF_INET, SOCK_DGRAM, 0); 395 if (fd2 < 0) 396 error(1, errno, "failed to create socket 2"); 397 if (setsockopt(fd1, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt))) 398 error(1, errno, "failed to set SO_REUSEPORT on socket 1"); 399 if (setsockopt(fd2, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt))) 400 error(1, errno, "failed to set SO_REUSEPORT on socket 2"); 401 402 attach_ebpf(fd1, 10); 403 attach_cbpf(fd2, 10); 404 405 close(fd1); 406 close(fd2); 407 } 408 409 void enable_fastopen(void) 410 { 411 int fd = open("/proc/sys/net/ipv4/tcp_fastopen", 0); 412 int rw_mask = 3; /* bit 1: client side; bit-2 server side */ 413 int val, size; 414 char buf[16]; 415 416 if (fd < 0) 417 error(1, errno, "Unable to open tcp_fastopen sysctl"); 418 if (read(fd, buf, sizeof(buf)) <= 0) 419 error(1, errno, "Unable to read tcp_fastopen sysctl"); 420 val = atoi(buf); 421 close(fd); 422 423 if ((val & rw_mask) != rw_mask) { 424 fd = open("/proc/sys/net/ipv4/tcp_fastopen", O_RDWR); 425 if (fd < 0) 426 error(1, errno, 427 "Unable to open tcp_fastopen sysctl for writing"); 428 val |= rw_mask; 429 size = snprintf(buf, 16, "%d", val); 430 if (write(fd, buf, size) <= 0) 431 error(1, errno, "Unable to write tcp_fastopen sysctl"); 432 close(fd); 433 } 434 } 435 436 int main(void) 437 { 438 fprintf(stderr, "---- IPv4 UDP ----\n"); 439 /* NOTE: UDP socket lookups traverse a different code path when there 440 * are > 10 sockets in a group. Run the bpf test through both paths. 441 */ 442 test_reuseport_ebpf((struct test_params) { 443 .recv_family = AF_INET, 444 .send_family = AF_INET, 445 .protocol = SOCK_DGRAM, 446 .recv_socks = 10, 447 .recv_port = 8000, 448 .send_port_min = 9000}); 449 test_reuseport_ebpf((struct test_params) { 450 .recv_family = AF_INET, 451 .send_family = AF_INET, 452 .protocol = SOCK_DGRAM, 453 .recv_socks = 20, 454 .recv_port = 8000, 455 .send_port_min = 9000}); 456 test_reuseport_cbpf((struct test_params) { 457 .recv_family = AF_INET, 458 .send_family = AF_INET, 459 .protocol = SOCK_DGRAM, 460 .recv_socks = 10, 461 .recv_port = 8001, 462 .send_port_min = 9020}); 463 test_reuseport_cbpf((struct test_params) { 464 .recv_family = AF_INET, 465 .send_family = AF_INET, 466 .protocol = SOCK_DGRAM, 467 .recv_socks = 20, 468 .recv_port = 8001, 469 .send_port_min = 9020}); 470 test_extra_filter((struct test_params) { 471 .recv_family = AF_INET, 472 .protocol = SOCK_DGRAM, 473 .recv_port = 8002}); 474 test_filter_no_reuseport((struct test_params) { 475 .recv_family = AF_INET, 476 .protocol = SOCK_DGRAM, 477 .recv_port = 8008}); 478 479 fprintf(stderr, "---- IPv6 UDP ----\n"); 480 test_reuseport_ebpf((struct test_params) { 481 .recv_family = AF_INET6, 482 .send_family = AF_INET6, 483 .protocol = SOCK_DGRAM, 484 .recv_socks = 10, 485 .recv_port = 8003, 486 .send_port_min = 9040}); 487 test_reuseport_ebpf((struct test_params) { 488 .recv_family = AF_INET6, 489 .send_family = AF_INET6, 490 .protocol = SOCK_DGRAM, 491 .recv_socks = 20, 492 .recv_port = 8003, 493 .send_port_min = 9040}); 494 test_reuseport_cbpf((struct test_params) { 495 .recv_family = AF_INET6, 496 .send_family = AF_INET6, 497 .protocol = SOCK_DGRAM, 498 .recv_socks = 10, 499 .recv_port = 8004, 500 .send_port_min = 9060}); 501 test_reuseport_cbpf((struct test_params) { 502 .recv_family = AF_INET6, 503 .send_family = AF_INET6, 504 .protocol = SOCK_DGRAM, 505 .recv_socks = 20, 506 .recv_port = 8004, 507 .send_port_min = 9060}); 508 test_extra_filter((struct test_params) { 509 .recv_family = AF_INET6, 510 .protocol = SOCK_DGRAM, 511 .recv_port = 8005}); 512 test_filter_no_reuseport((struct test_params) { 513 .recv_family = AF_INET6, 514 .protocol = SOCK_DGRAM, 515 .recv_port = 8009}); 516 517 fprintf(stderr, "---- IPv6 UDP w/ mapped IPv4 ----\n"); 518 test_reuseport_ebpf((struct test_params) { 519 .recv_family = AF_INET6, 520 .send_family = AF_INET, 521 .protocol = SOCK_DGRAM, 522 .recv_socks = 20, 523 .recv_port = 8006, 524 .send_port_min = 9080}); 525 test_reuseport_ebpf((struct test_params) { 526 .recv_family = AF_INET6, 527 .send_family = AF_INET, 528 .protocol = SOCK_DGRAM, 529 .recv_socks = 10, 530 .recv_port = 8006, 531 .send_port_min = 9080}); 532 test_reuseport_cbpf((struct test_params) { 533 .recv_family = AF_INET6, 534 .send_family = AF_INET, 535 .protocol = SOCK_DGRAM, 536 .recv_socks = 10, 537 .recv_port = 8007, 538 .send_port_min = 9100}); 539 test_reuseport_cbpf((struct test_params) { 540 .recv_family = AF_INET6, 541 .send_family = AF_INET, 542 .protocol = SOCK_DGRAM, 543 .recv_socks = 20, 544 .recv_port = 8007, 545 .send_port_min = 9100}); 546 547 /* TCP fastopen is required for the TCP tests */ 548 enable_fastopen(); 549 fprintf(stderr, "---- IPv4 TCP ----\n"); 550 test_reuseport_ebpf((struct test_params) { 551 .recv_family = AF_INET, 552 .send_family = AF_INET, 553 .protocol = SOCK_STREAM, 554 .recv_socks = 10, 555 .recv_port = 8008, 556 .send_port_min = 9120}); 557 test_reuseport_cbpf((struct test_params) { 558 .recv_family = AF_INET, 559 .send_family = AF_INET, 560 .protocol = SOCK_STREAM, 561 .recv_socks = 10, 562 .recv_port = 8009, 563 .send_port_min = 9160}); 564 test_extra_filter((struct test_params) { 565 .recv_family = AF_INET, 566 .protocol = SOCK_STREAM, 567 .recv_port = 8010}); 568 test_filter_no_reuseport((struct test_params) { 569 .recv_family = AF_INET, 570 .protocol = SOCK_STREAM, 571 .recv_port = 8011}); 572 573 fprintf(stderr, "---- IPv6 TCP ----\n"); 574 test_reuseport_ebpf((struct test_params) { 575 .recv_family = AF_INET6, 576 .send_family = AF_INET6, 577 .protocol = SOCK_STREAM, 578 .recv_socks = 10, 579 .recv_port = 8012, 580 .send_port_min = 9200}); 581 test_reuseport_cbpf((struct test_params) { 582 .recv_family = AF_INET6, 583 .send_family = AF_INET6, 584 .protocol = SOCK_STREAM, 585 .recv_socks = 10, 586 .recv_port = 8013, 587 .send_port_min = 9240}); 588 test_extra_filter((struct test_params) { 589 .recv_family = AF_INET6, 590 .protocol = SOCK_STREAM, 591 .recv_port = 8014}); 592 test_filter_no_reuseport((struct test_params) { 593 .recv_family = AF_INET6, 594 .protocol = SOCK_STREAM, 595 .recv_port = 8015}); 596 597 fprintf(stderr, "---- IPv6 TCP w/ mapped IPv4 ----\n"); 598 test_reuseport_ebpf((struct test_params) { 599 .recv_family = AF_INET6, 600 .send_family = AF_INET, 601 .protocol = SOCK_STREAM, 602 .recv_socks = 10, 603 .recv_port = 8016, 604 .send_port_min = 9320}); 605 test_reuseport_cbpf((struct test_params) { 606 .recv_family = AF_INET6, 607 .send_family = AF_INET, 608 .protocol = SOCK_STREAM, 609 .recv_socks = 10, 610 .recv_port = 8017, 611 .send_port_min = 9360}); 612 613 test_filter_without_bind(); 614 615 fprintf(stderr, "SUCCESS\n"); 616 return 0; 617 } 618