Thread (14 messages) 14 messages, 5 authors, 2018-12-17

Re: [PATCH bpf-next 1/2] libbpf: add support for using AF_XDP sockets

From: Daniel Borkmann <daniel@iogearbox.net>
Date: 2018-12-12 01:14:26

On 12/10/2018 04:34 PM, Magnus Karlsson wrote:
[...]
+int xsk_create_umem(void *umem_area, __u64 size, struct xsk_prod_ring *fq,
+		    struct xsk_cons_ring *cq,
+		    struct xsk_umem_config *usr_config)
+{
+	struct xdp_mmap_offsets off;
+	struct xsk_umem_info *umem;
+	struct xdp_umem_reg mr;
+	socklen_t optlen;
+	int err, fd;
+	void *map;
+
+	if (!umem_area)
+		return -EFAULT;
+	if (!size && !xsk_page_aligned(umem_area))
+		return -EINVAL;
+
+	fd = socket(AF_XDP, SOCK_RAW, 0);
+	if (fd < 0)
+		return -errno;
+
+	umem = calloc(1, sizeof(*umem));
+	if (!umem)
+		return -ENOMEM;
On error, we should also close fd and not 'leak' it into the app, similar
for other errors below. Same in xsk_create_xdp_socket(), etc.
+	xsk_hash_insert_umem(fd, umem);
+	xsk_set_umem_config(&umem->config, usr_config);
+
+	mr.addr = (uintptr_t)umem_area;
+	mr.len = size;
+	mr.chunk_size = umem->config.frame_size;
+	mr.headroom = umem->config.frame_headroom;
+
+	err = setsockopt(fd, SOL_XDP, XDP_UMEM_REG, &mr, sizeof(mr));
+	if (err)
+		return -errno;
+	err = setsockopt(fd, SOL_XDP, XDP_UMEM_FILL_RING,
+			 &umem->config.fq_size, sizeof(umem->config.fq_size));
+	if (err)
+		return -errno;
+	err = setsockopt(fd, SOL_XDP, XDP_UMEM_COMPLETION_RING,
+			 &umem->config.cq_size, sizeof(umem->config.cq_size));
+	if (err)
+		return -errno;
+
+	optlen = sizeof(off);
+	err = getsockopt(fd, SOL_XDP, XDP_MMAP_OFFSETS, &off, &optlen);
+	if (err)
+		return -errno;
+
+	map = xsk_mmap(NULL, off.fr.desc + umem->config.fq_size * sizeof(__u64),
+		       PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE,
+		       fd, XDP_UMEM_PGOFF_FILL_RING);
+	if (map == MAP_FAILED)
+		return -errno;
+
+	umem->fq = fq;
+	fq->mask = umem->config.fq_size - 1;
+	fq->size = umem->config.fq_size;
+	fq->producer = map + off.fr.producer;
+	fq->consumer = map + off.fr.consumer;
+	fq->ring = map + off.fr.desc;
+	fq->cached_cons = umem->config.fq_size;
+
+	map = xsk_mmap(NULL, off.cr.desc + umem->config.cq_size * sizeof(__u64),
+		    PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE,
+		    fd, XDP_UMEM_PGOFF_COMPLETION_RING);
+	if (map == MAP_FAILED)
+		return -errno;
Plus undoing prior mmaps.
+	umem->cq = cq;
+	cq->mask = umem->config.cq_size - 1;
+	cq->size = umem->config.cq_size;
+	cq->producer = map + off.cr.producer;
+	cq->consumer = map + off.cr.consumer;
+	cq->ring = map + off.cr.desc;
+
+	umem->umem_area = umem_area;
+	umem->fd = fd;
+
+	return fd;
+}
Thanks,
Daniel
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help