1#ifndef __BPF_SCM__
2#define __BPF_SCM__
3
4#include <sys/types.h>
5#include <sys/socket.h>
6#include <sys/un.h>
7
8#include "utils.h"
9#include "bpf_elf.h"
10
11#define BPF_SCM_AUX_VER		1
12#define BPF_SCM_MAX_FDS		ELF_MAX_MAPS
13#define BPF_SCM_MSG_SIZE	1024
14
15struct bpf_elf_st {
16	dev_t st_dev;
17	ino_t st_ino;
18};
19
20struct bpf_map_aux {
21	unsigned short uds_ver;
22	unsigned short num_ent;
23	char obj_name[64];
24	struct bpf_elf_st obj_st;
25	struct bpf_elf_map ent[BPF_SCM_MAX_FDS];
26};
27
28struct bpf_map_set_msg {
29	struct msghdr hdr;
30	struct iovec iov;
31	char msg_buf[BPF_SCM_MSG_SIZE];
32	struct bpf_map_aux aux;
33};
34
35static inline int *bpf_map_set_init(struct bpf_map_set_msg *msg,
36				    struct sockaddr_un *addr,
37				    unsigned int addr_len)
38{
39	const unsigned int cmsg_ctl_len = sizeof(int) * BPF_SCM_MAX_FDS;
40	struct cmsghdr *cmsg;
41
42	msg->iov.iov_base = &msg->aux;
43	msg->iov.iov_len = sizeof(msg->aux);
44
45	msg->hdr.msg_iov = &msg->iov;
46	msg->hdr.msg_iovlen = 1;
47
48	msg->hdr.msg_name = (struct sockaddr *)addr;
49	msg->hdr.msg_namelen = addr_len;
50
51	BUILD_BUG_ON(sizeof(msg->msg_buf) < cmsg_ctl_len);
52	msg->hdr.msg_control = &msg->msg_buf;
53	msg->hdr.msg_controllen	= cmsg_ctl_len;
54
55	cmsg = CMSG_FIRSTHDR(&msg->hdr);
56	cmsg->cmsg_len = msg->hdr.msg_controllen;
57	cmsg->cmsg_level = SOL_SOCKET;
58	cmsg->cmsg_type	= SCM_RIGHTS;
59
60	return (int *)CMSG_DATA(cmsg);
61}
62
63static inline void bpf_map_set_init_single(struct bpf_map_set_msg *msg,
64					   int num)
65{
66	struct cmsghdr *cmsg;
67
68	msg->hdr.msg_controllen = CMSG_LEN(sizeof(int) * num);
69	msg->iov.iov_len = offsetof(struct bpf_map_aux, ent) +
70			   sizeof(struct bpf_elf_map) * num;
71
72	cmsg = CMSG_FIRSTHDR(&msg->hdr);
73	cmsg->cmsg_len = msg->hdr.msg_controllen;
74}
75
76#endif /* __BPF_SCM__ */
77