Skip to content

Commit bd5ca3e

Browse files
tohojoAlexei Starovoitov
authored andcommitted
libbpf: Add function to set link XDP fd while specifying old program
This adds a new function to set the XDP fd while specifying the FD of the program to replace, using the newly added IFLA_XDP_EXPECTED_FD netlink parameter. The new function uses the opts struct mechanism to be extendable in the future. Signed-off-by: Toke Høiland-Jørgensen <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent 50a3e67 commit bd5ca3e

File tree

3 files changed

+42
-1
lines changed

3 files changed

+42
-1
lines changed

tools/lib/bpf/libbpf.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,15 @@ struct xdp_link_info {
444444
__u8 attach_mode;
445445
};
446446

447+
struct bpf_xdp_set_link_opts {
448+
size_t sz;
449+
__u32 old_fd;
450+
};
451+
#define bpf_xdp_set_link_opts__last_field old_fd
452+
447453
LIBBPF_API int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags);
454+
LIBBPF_API int bpf_set_link_xdp_fd_opts(int ifindex, int fd, __u32 flags,
455+
const struct bpf_xdp_set_link_opts *opts);
448456
LIBBPF_API int bpf_get_link_xdp_id(int ifindex, __u32 *prog_id, __u32 flags);
449457
LIBBPF_API int bpf_get_link_xdp_info(int ifindex, struct xdp_link_info *info,
450458
size_t info_size, __u32 flags);

tools/lib/bpf/libbpf.map

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,4 +244,5 @@ LIBBPF_0.0.8 {
244244
bpf_link__pin_path;
245245
bpf_link__unpin;
246246
bpf_program__set_attach_target;
247+
bpf_set_link_xdp_fd_opts;
247248
} LIBBPF_0.0.7;

tools/lib/bpf/netlink.c

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ static int bpf_netlink_recv(int sock, __u32 nl_pid, int seq,
132132
return ret;
133133
}
134134

135-
int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags)
135+
static int __bpf_set_link_xdp_fd_replace(int ifindex, int fd, int old_fd,
136+
__u32 flags)
136137
{
137138
int sock, seq = 0, ret;
138139
struct nlattr *nla, *nla_xdp;
@@ -178,6 +179,14 @@ int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags)
178179
nla->nla_len += nla_xdp->nla_len;
179180
}
180181

182+
if (flags & XDP_FLAGS_REPLACE) {
183+
nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
184+
nla_xdp->nla_type = IFLA_XDP_EXPECTED_FD;
185+
nla_xdp->nla_len = NLA_HDRLEN + sizeof(old_fd);
186+
memcpy((char *)nla_xdp + NLA_HDRLEN, &old_fd, sizeof(old_fd));
187+
nla->nla_len += nla_xdp->nla_len;
188+
}
189+
181190
req.nh.nlmsg_len += NLA_ALIGN(nla->nla_len);
182191

183192
if (send(sock, &req, req.nh.nlmsg_len, 0) < 0) {
@@ -191,6 +200,29 @@ int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags)
191200
return ret;
192201
}
193202

203+
int bpf_set_link_xdp_fd_opts(int ifindex, int fd, __u32 flags,
204+
const struct bpf_xdp_set_link_opts *opts)
205+
{
206+
int old_fd = -1;
207+
208+
if (!OPTS_VALID(opts, bpf_xdp_set_link_opts))
209+
return -EINVAL;
210+
211+
if (OPTS_HAS(opts, old_fd)) {
212+
old_fd = OPTS_GET(opts, old_fd, -1);
213+
flags |= XDP_FLAGS_REPLACE;
214+
}
215+
216+
return __bpf_set_link_xdp_fd_replace(ifindex, fd,
217+
old_fd,
218+
flags);
219+
}
220+
221+
int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags)
222+
{
223+
return __bpf_set_link_xdp_fd_replace(ifindex, fd, 0, flags);
224+
}
225+
194226
static int __dump_link_nlmsg(struct nlmsghdr *nlh,
195227
libbpf_dump_nlmsg_t dump_link_nlmsg, void *cookie)
196228
{

0 commit comments

Comments
 (0)