Lines Matching refs:xdp
2 * xdp-server.c -- integration of AF_XDP into nsd
11 * Parts inspired by https://github.com/xdp-project/xdp-tutorial
34 #include <xdp/xsk.h>
35 #include <xdp/libxdp.h>
54 #include "xdp-server.h"
55 #include "xdp-util.h"
90 static int xsk_configure_socket(struct xdp_server *xdp,
113 static int load_xdp_program_and_map(struct xdp_server *xdp);
116 * Unload eBPF/XDP program
118 static void unload_xdp_program(struct xdp_server *xdp);
123 static int figure_ip_addresses(struct xdp_server *xdp);
128 static void add_ip_address(struct xdp_server *xdp,
134 static int dest_ip_allowed4(struct xdp_server *xdp, struct iphdr *ipv4);
139 static int dest_ip_allowed6(struct xdp_server *xdp, struct ipv6hdr *ipv6);
142 * Setup XDP sockets
144 static int xdp_sockets_init(struct xdp_server *xdp);
147 * Cleanup XDP sockets and memory
149 static void xdp_sockets_cleanup(struct xdp_server *xdp);
172 process_packet(struct xdp_server *xdp,
236 /* printf("xdp: trying to fill_addr INVALID UMEM FRAME"); */
245 static int load_xdp_program_and_map(struct xdp_server *xdp) {
254 if (xdp->bpf_bpffs_path)
255 opts.pin_root_path = xdp->bpf_bpffs_path;
257 /* for now our xdp program should contain just one program section */
259 xdp->bpf_prog = xdp_program__open_file(xdp->bpf_prog_filename, NULL, &opts);
263 err = (int) libxdp_get_error(xdp->bpf_prog);
266 log_msg(LOG_ERR, "xdp: could not open xdp program: %s\n", errmsg);
270 if (xdp->bpf_prog_should_load) {
273 /* This is done to allow unloading the XDP program we load without
277 err = xdp_program__attach(xdp->bpf_prog, (int) xdp->interface_index, attach_mode, 0);
278 /* err = xdp_program__attach_single(xdp->bpf_prog, xdp->interface_index, attach_mode); */
281 log_msg(LOG_ERR, "xdp: could not attach xdp program to interface '%s' : %s\n",
282 xdp->interface_name, errmsg);
286 xdp->bpf_prog_fd = xdp_program__fd(xdp->bpf_prog);
287 xdp->bpf_prog_id = xdp_program__id(xdp->bpf_prog);
290 map = bpf_object__find_map_by_name(xdp_program__bpf_obj(xdp->bpf_prog), "xsks_map");
293 log_msg(LOG_ERR, "xdp: no xsks map found in xdp program: %s\n", strerror(ret));
296 xdp->xsk_map_fd = ret;
297 xdp->xsk_map = map;
302 snprintf(map_path, PATH_MAX, "%s/%s", xdp->bpf_bpffs_path, "xsks_map");
306 log_msg(LOG_ERR, "xdp: could not retrieve xsks_map pin from %s: %s", map_path, strerror(errno));
310 map = bpf_object__find_map_by_name(xdp_program__bpf_obj(xdp->bpf_prog), "xsks_map");
312 log_msg(LOG_ERR, "xdp: could not re-use xsks_map: %s\n", strerror(errno));
316 xdp->xsk_map_fd = fd;
317 xdp->xsk_map = map;
344 xsk_configure_socket(struct xdp_server *xdp, struct xsk_socket_info *xsk_info,
357 if (xdp->force_copy) {
370 xdp->interface_name,
377 log_msg(LOG_ERR, "xdp: failed to create xsk_socket");
381 ret = xsk_socket__update_xskmap(xsk_info->xsk, xdp->xsk_map_fd);
383 log_msg(LOG_ERR, "xdp: failed to update xskmap");
400 "xdp: amount of reserved addr not as expected (is %d)", reserved);
426 static int xdp_sockets_init(struct xdp_server *xdp) {
427 size_t umems_len = sizeof(struct xsk_umem_info) * xdp->queue_count;
428 size_t xsks_len = sizeof(struct xsk_socket_info) * xdp->queue_count;
430 xdp->umems = (struct xsk_umem_info *) alloc_shared_mem(umems_len);
431 if (xdp->umems == MAP_FAILED) {
433 "xdp: failed to allocate shared memory for umem info: %s",
438 xdp->xsks = (struct xsk_socket_info *) alloc_shared_mem(xsks_len);
439 if (xdp->xsks == MAP_FAILED) {
441 "xdp: failed to allocate shared memory for xsk info: %s",
446 for (uint32_t q_idx = 0; q_idx < xdp->queue_count; ++q_idx) {
448 xdp->umems[q_idx].buffer = alloc_shared_mem(XDP_BUFFER_SIZE);
450 if (xsk_configure_umem(&xdp->umems[q_idx], XDP_BUFFER_SIZE)) {
451 log_msg(LOG_ERR, "xdp: cannot create umem: %s", strerror(errno));
455 if (xsk_configure_socket(xdp, &xdp->xsks[q_idx], &xdp->umems[q_idx],
458 "xdp: cannot create AF_XDP socket: %s",
467 for (uint32_t i = 0; i < xdp->queue_count; ++i)
468 xsk_umem__delete(xdp->umems[i].umem);
474 static void xdp_sockets_cleanup(struct xdp_server *xdp) {
475 for (uint32_t i = 0; i < xdp->queue_count; ++i) {
476 xsk_socket__delete(xdp->xsks[i].xsk);
477 xsk_umem__delete(xdp->umems[i].umem);
481 int xdp_server_init(struct xdp_server *xdp) {
485 xdp->interface_index = if_nametoindex(xdp->interface_name);
486 if (xdp->interface_index == 0) {
487 log_msg(LOG_ERR, "xdp: configured xdp-interface (%s) is unknown: %s",
488 xdp->interface_name, strerror(errno));
492 /* (optionally) load xdp program and (definitely) set xsks_map_fd */
493 if (load_xdp_program_and_map(xdp)) {
494 log_msg(LOG_ERR, "xdp: failed to load/pin xdp program/map");
502 log_msg(LOG_ERR, "xdp: cannot adjust rlimit (RLIMIT_MEMLOCK): \"%s\"\n",
507 if (xdp_sockets_init(xdp))
515 if (!xdp->ip_addresses)
516 figure_ip_addresses(xdp);
521 void xdp_server_cleanup(struct xdp_server *xdp) {
522 xdp_sockets_cleanup(xdp);
525 if (xdp->bpf_prog_should_load) {
526 if (xdp->xsk_map && bpf_map__is_pinned(xdp->xsk_map)) {
527 if (bpf_map__unpin(xdp->xsk_map, NULL)) {
528 /* We currently ship an XDP program that doesn't pin the map. So
530 * custom XDP program to load by NSD. Therefore they should know
533 log_msg(LOG_ERR, "xdp: failed to unpin bpf map during cleanup: \"%s\". "
536 strerror(errno), xdp->bpf_bpffs_path);
540 unload_xdp_program(xdp);
544 static void unload_xdp_program(struct xdp_server *xdp) {
546 .old_prog_fd = xdp->bpf_prog_fd);
548 log_msg(LOG_INFO, "xdp: detaching xdp program %u from %s\n",
549 xdp->bpf_prog_id, xdp->interface_name);
551 if (bpf_xdp_detach((int) xdp->interface_index, 0, &bpf_opts))
552 log_msg(LOG_ERR, "xdp: failed to detach xdp program: %s\n",
556 static int dest_ip_allowed6(struct xdp_server *xdp, struct ipv6hdr *ipv6) {
557 struct xdp_ip_address *ip = xdp->ip_addresses;
574 static int dest_ip_allowed4(struct xdp_server *xdp, struct iphdr *ipv4) {
575 struct xdp_ip_address *ip = xdp->ip_addresses;
591 add_ip_address(struct xdp_server *xdp, struct sockaddr_storage *addr) {
592 struct xdp_ip_address *ip = xdp->ip_addresses;
594 xdp->ip_addresses = region_alloc_zero(xdp->region,
596 ip = xdp->ip_addresses;
601 ip->next = region_alloc_zero(xdp->region,
609 static int figure_ip_addresses(struct xdp_server *xdp) {
615 log_msg(LOG_ERR, "xdp: couldn't determine local IP addresses. "
624 if (strcmp(ifa->ifa_name, xdp->interface_name))
634 add_ip_address(xdp, (struct sockaddr_storage *) ifa->ifa_addr);
739 process_packet(struct xdp_server *xdp, uint8_t *pkt,
741 /* log_msg(LOG_INFO, "xdp: received packet with len %d", *len); */
773 if (!dest_ip_allowed6(xdp, ipv6))
786 if (!dest_ip_allowed4(xdp, ipv4))
818 STATUP(xdp->nsd, qudp6);
827 STATUP(xdp->nsd, qudp);
835 dnslen = parse_dns(xdp->nsd, dnslen, query, query->remote_addr.ss_family);
858 log_msg(LOG_ERR, "xdp: we forgot to implement something... oops");
862 /* log_msg(LOG_INFO, "xdp: done with processing the packet"); */
868 void xdp_handle_recv_and_send(struct xdp_server *xdp) {
869 struct xsk_socket_info *xsk = &xdp->xsks[xdp->queue_index];
889 if ((ret = process_packet(xdp, pkt, &len, xdp->queries[i])) <= 0) {
903 query_reset(xdp->queries[i], UDP_MAX_MESSAGE_LEN, 0);
919 log_msg(LOG_ERR, "xdp: not enough TX frames available, dropping "
927 xdp->nsd->st->txerr += to_send;