Skip to content

Commit f701077

Browse files
yonghong-songAlexei Starovoitov
authored andcommitted
tools/bpf: move bpf/lib netlink related functions into a new file
There are no functionality change for this patch. In the subsequent patches, more netlink related library functions will be added and a separate file is better than cluttering bpf.c. Signed-off-by: Yonghong Song <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 52b7b78 commit f701077

File tree

3 files changed

+166
-130
lines changed

3 files changed

+166
-130
lines changed

tools/lib/bpf/Build

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
libbpf-y := libbpf.o bpf.o nlattr.o btf.o libbpf_errno.o
1+
libbpf-y := libbpf.o bpf.o nlattr.o btf.o libbpf_errno.o netlink.o

tools/lib/bpf/bpf.c

Lines changed: 0 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,8 @@
2828
#include <linux/bpf.h>
2929
#include "bpf.h"
3030
#include "libbpf.h"
31-
#include "nlattr.h"
32-
#include <linux/rtnetlink.h>
33-
#include <linux/if_link.h>
34-
#include <sys/socket.h>
3531
#include <errno.h>
3632

37-
#ifndef SOL_NETLINK
38-
#define SOL_NETLINK 270
39-
#endif
40-
4133
/*
4234
* When building perf, unistd.h is overridden. __NR_bpf is
4335
* required to be defined explicitly.
@@ -499,127 +491,6 @@ int bpf_raw_tracepoint_open(const char *name, int prog_fd)
499491
return sys_bpf(BPF_RAW_TRACEPOINT_OPEN, &attr, sizeof(attr));
500492
}
501493

502-
int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags)
503-
{
504-
struct sockaddr_nl sa;
505-
int sock, seq = 0, len, ret = -1;
506-
char buf[4096];
507-
struct nlattr *nla, *nla_xdp;
508-
struct {
509-
struct nlmsghdr nh;
510-
struct ifinfomsg ifinfo;
511-
char attrbuf[64];
512-
} req;
513-
struct nlmsghdr *nh;
514-
struct nlmsgerr *err;
515-
socklen_t addrlen;
516-
int one = 1;
517-
518-
memset(&sa, 0, sizeof(sa));
519-
sa.nl_family = AF_NETLINK;
520-
521-
sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
522-
if (sock < 0) {
523-
return -errno;
524-
}
525-
526-
if (setsockopt(sock, SOL_NETLINK, NETLINK_EXT_ACK,
527-
&one, sizeof(one)) < 0) {
528-
fprintf(stderr, "Netlink error reporting not supported\n");
529-
}
530-
531-
if (bind(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
532-
ret = -errno;
533-
goto cleanup;
534-
}
535-
536-
addrlen = sizeof(sa);
537-
if (getsockname(sock, (struct sockaddr *)&sa, &addrlen) < 0) {
538-
ret = -errno;
539-
goto cleanup;
540-
}
541-
542-
if (addrlen != sizeof(sa)) {
543-
ret = -LIBBPF_ERRNO__INTERNAL;
544-
goto cleanup;
545-
}
546-
547-
memset(&req, 0, sizeof(req));
548-
req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
549-
req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
550-
req.nh.nlmsg_type = RTM_SETLINK;
551-
req.nh.nlmsg_pid = 0;
552-
req.nh.nlmsg_seq = ++seq;
553-
req.ifinfo.ifi_family = AF_UNSPEC;
554-
req.ifinfo.ifi_index = ifindex;
555-
556-
/* started nested attribute for XDP */
557-
nla = (struct nlattr *)(((char *)&req)
558-
+ NLMSG_ALIGN(req.nh.nlmsg_len));
559-
nla->nla_type = NLA_F_NESTED | IFLA_XDP;
560-
nla->nla_len = NLA_HDRLEN;
561-
562-
/* add XDP fd */
563-
nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
564-
nla_xdp->nla_type = IFLA_XDP_FD;
565-
nla_xdp->nla_len = NLA_HDRLEN + sizeof(int);
566-
memcpy((char *)nla_xdp + NLA_HDRLEN, &fd, sizeof(fd));
567-
nla->nla_len += nla_xdp->nla_len;
568-
569-
/* if user passed in any flags, add those too */
570-
if (flags) {
571-
nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
572-
nla_xdp->nla_type = IFLA_XDP_FLAGS;
573-
nla_xdp->nla_len = NLA_HDRLEN + sizeof(flags);
574-
memcpy((char *)nla_xdp + NLA_HDRLEN, &flags, sizeof(flags));
575-
nla->nla_len += nla_xdp->nla_len;
576-
}
577-
578-
req.nh.nlmsg_len += NLA_ALIGN(nla->nla_len);
579-
580-
if (send(sock, &req, req.nh.nlmsg_len, 0) < 0) {
581-
ret = -errno;
582-
goto cleanup;
583-
}
584-
585-
len = recv(sock, buf, sizeof(buf), 0);
586-
if (len < 0) {
587-
ret = -errno;
588-
goto cleanup;
589-
}
590-
591-
for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len);
592-
nh = NLMSG_NEXT(nh, len)) {
593-
if (nh->nlmsg_pid != sa.nl_pid) {
594-
ret = -LIBBPF_ERRNO__WRNGPID;
595-
goto cleanup;
596-
}
597-
if (nh->nlmsg_seq != seq) {
598-
ret = -LIBBPF_ERRNO__INVSEQ;
599-
goto cleanup;
600-
}
601-
switch (nh->nlmsg_type) {
602-
case NLMSG_ERROR:
603-
err = (struct nlmsgerr *)NLMSG_DATA(nh);
604-
if (!err->error)
605-
continue;
606-
ret = err->error;
607-
nla_dump_errormsg(nh);
608-
goto cleanup;
609-
case NLMSG_DONE:
610-
break;
611-
default:
612-
break;
613-
}
614-
}
615-
616-
ret = 0;
617-
618-
cleanup:
619-
close(sock);
620-
return ret;
621-
}
622-
623494
int bpf_load_btf(void *btf, __u32 btf_size, char *log_buf, __u32 log_buf_size,
624495
bool do_log)
625496
{

tools/lib/bpf/netlink.c

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
// SPDX-License-Identifier: LGPL-2.1
2+
/* Copyright (c) 2018 Facebook */
3+
4+
#include <stdlib.h>
5+
#include <memory.h>
6+
#include <unistd.h>
7+
#include <linux/bpf.h>
8+
#include <linux/rtnetlink.h>
9+
#include <sys/socket.h>
10+
#include <errno.h>
11+
#include <time.h>
12+
13+
#include "bpf.h"
14+
#include "libbpf.h"
15+
#include "nlattr.h"
16+
17+
#ifndef SOL_NETLINK
18+
#define SOL_NETLINK 270
19+
#endif
20+
21+
static int bpf_netlink_open(__u32 *nl_pid)
22+
{
23+
struct sockaddr_nl sa;
24+
socklen_t addrlen;
25+
int one = 1, ret;
26+
int sock;
27+
28+
memset(&sa, 0, sizeof(sa));
29+
sa.nl_family = AF_NETLINK;
30+
31+
sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
32+
if (sock < 0)
33+
return -errno;
34+
35+
if (setsockopt(sock, SOL_NETLINK, NETLINK_EXT_ACK,
36+
&one, sizeof(one)) < 0) {
37+
fprintf(stderr, "Netlink error reporting not supported\n");
38+
}
39+
40+
if (bind(sock, (struct sockaddr *)&sa, sizeof(sa)) < 0) {
41+
ret = -errno;
42+
goto cleanup;
43+
}
44+
45+
addrlen = sizeof(sa);
46+
if (getsockname(sock, (struct sockaddr *)&sa, &addrlen) < 0) {
47+
ret = -errno;
48+
goto cleanup;
49+
}
50+
51+
if (addrlen != sizeof(sa)) {
52+
ret = -LIBBPF_ERRNO__INTERNAL;
53+
goto cleanup;
54+
}
55+
56+
*nl_pid = sa.nl_pid;
57+
return sock;
58+
59+
cleanup:
60+
close(sock);
61+
return ret;
62+
}
63+
64+
static int bpf_netlink_recv(int sock, __u32 nl_pid, int seq)
65+
{
66+
struct nlmsgerr *err;
67+
struct nlmsghdr *nh;
68+
char buf[4096];
69+
int len, ret;
70+
71+
while (1) {
72+
len = recv(sock, buf, sizeof(buf), 0);
73+
if (len < 0) {
74+
ret = -errno;
75+
goto done;
76+
}
77+
78+
for (nh = (struct nlmsghdr *)buf; NLMSG_OK(nh, len);
79+
nh = NLMSG_NEXT(nh, len)) {
80+
if (nh->nlmsg_pid != nl_pid) {
81+
ret = -LIBBPF_ERRNO__WRNGPID;
82+
goto done;
83+
}
84+
if (nh->nlmsg_seq != seq) {
85+
ret = -LIBBPF_ERRNO__INVSEQ;
86+
goto done;
87+
}
88+
switch (nh->nlmsg_type) {
89+
case NLMSG_ERROR:
90+
err = (struct nlmsgerr *)NLMSG_DATA(nh);
91+
if (!err->error)
92+
continue;
93+
ret = err->error;
94+
nla_dump_errormsg(nh);
95+
goto done;
96+
case NLMSG_DONE:
97+
return 0;
98+
default:
99+
break;
100+
}
101+
}
102+
}
103+
ret = 0;
104+
done:
105+
return ret;
106+
}
107+
108+
int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags)
109+
{
110+
int sock, seq = 0, ret;
111+
struct nlattr *nla, *nla_xdp;
112+
struct {
113+
struct nlmsghdr nh;
114+
struct ifinfomsg ifinfo;
115+
char attrbuf[64];
116+
} req;
117+
__u32 nl_pid;
118+
119+
sock = bpf_netlink_open(&nl_pid);
120+
if (sock < 0)
121+
return sock;
122+
123+
memset(&req, 0, sizeof(req));
124+
req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
125+
req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
126+
req.nh.nlmsg_type = RTM_SETLINK;
127+
req.nh.nlmsg_pid = 0;
128+
req.nh.nlmsg_seq = ++seq;
129+
req.ifinfo.ifi_family = AF_UNSPEC;
130+
req.ifinfo.ifi_index = ifindex;
131+
132+
/* started nested attribute for XDP */
133+
nla = (struct nlattr *)(((char *)&req)
134+
+ NLMSG_ALIGN(req.nh.nlmsg_len));
135+
nla->nla_type = NLA_F_NESTED | IFLA_XDP;
136+
nla->nla_len = NLA_HDRLEN;
137+
138+
/* add XDP fd */
139+
nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
140+
nla_xdp->nla_type = IFLA_XDP_FD;
141+
nla_xdp->nla_len = NLA_HDRLEN + sizeof(int);
142+
memcpy((char *)nla_xdp + NLA_HDRLEN, &fd, sizeof(fd));
143+
nla->nla_len += nla_xdp->nla_len;
144+
145+
/* if user passed in any flags, add those too */
146+
if (flags) {
147+
nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
148+
nla_xdp->nla_type = IFLA_XDP_FLAGS;
149+
nla_xdp->nla_len = NLA_HDRLEN + sizeof(flags);
150+
memcpy((char *)nla_xdp + NLA_HDRLEN, &flags, sizeof(flags));
151+
nla->nla_len += nla_xdp->nla_len;
152+
}
153+
154+
req.nh.nlmsg_len += NLA_ALIGN(nla->nla_len);
155+
156+
if (send(sock, &req, req.nh.nlmsg_len, 0) < 0) {
157+
ret = -errno;
158+
goto cleanup;
159+
}
160+
ret = bpf_netlink_recv(sock, nl_pid, seq);
161+
162+
cleanup:
163+
close(sock);
164+
return ret;
165+
}

0 commit comments

Comments
 (0)