On Wed, Nov 4, 2020 at 4:49 AM Jason Wang <jasow...@redhat.com> wrote:
> > On 2020/11/3 上午2:51, Andrew Melnychenko wrote: > > From: Andrew <and...@daynix.com> > > > > For now, that method supported only by Linux TAP. > > Linux TAP uses TUNSETSTEERINGEBPF ioctl. > > TUNSETSTEERINGBPF was added 3 years ago. > > Qemu checks if it was defined before using. > > > > Signed-off-by: Andrew Melnychenko <and...@daynix.com> > > --- > > include/net/net.h | 2 ++ > > net/tap-bsd.c | 5 +++++ > > net/tap-linux.c | 19 +++++++++++++++++++ > > net/tap-solaris.c | 5 +++++ > > net/tap-stub.c | 5 +++++ > > net/tap.c | 9 +++++++++ > > net/tap_int.h | 1 + > > 7 files changed, 46 insertions(+) > > > > diff --git a/include/net/net.h b/include/net/net.h > > index 897b2d7595..d8a41fb010 100644 > > --- a/include/net/net.h > > +++ b/include/net/net.h > > @@ -60,6 +60,7 @@ typedef int (SetVnetBE)(NetClientState *, bool); > > typedef struct SocketReadState SocketReadState; > > typedef void (SocketReadStateFinalize)(SocketReadState *rs); > > typedef void (NetAnnounce)(NetClientState *); > > +typedef bool (SetSteeringEBPF)(NetClientState *, int); > > > > typedef struct NetClientInfo { > > NetClientDriver type; > > @@ -81,6 +82,7 @@ typedef struct NetClientInfo { > > SetVnetLE *set_vnet_le; > > SetVnetBE *set_vnet_be; > > NetAnnounce *announce; > > + SetSteeringEBPF *set_steering_ebpf; > > } NetClientInfo; > > > > struct NetClientState { > > diff --git a/net/tap-bsd.c b/net/tap-bsd.c > > index 77aaf674b1..4f64f31e98 100644 > > --- a/net/tap-bsd.c > > +++ b/net/tap-bsd.c > > @@ -259,3 +259,8 @@ int tap_fd_get_ifname(int fd, char *ifname) > > { > > return -1; > > } > > + > > +int tap_fd_set_steering_ebpf(int fd, int prog_fd) > > +{ > > + return -1; > > +} > > diff --git a/net/tap-linux.c b/net/tap-linux.c > > index b0635e9e32..196373019f 100644 > > --- a/net/tap-linux.c > > +++ b/net/tap-linux.c > > @@ -31,6 +31,7 @@ > > > > #include <net/if.h> > > #include <sys/ioctl.h> > > +#include <linux/if_tun.h> /* TUNSETSTEERINGEBPF */ > > > > #include "qapi/error.h" > > #include "qemu/error-report.h" > > @@ -316,3 +317,21 @@ int tap_fd_get_ifname(int fd, char *ifname) > > pstrcpy(ifname, sizeof(ifr.ifr_name), ifr.ifr_name); > > return 0; > > } > > + > > +int tap_fd_set_steering_ebpf(int fd, int prog_fd) > > +{ > > +#ifdef TUNSETSTEERINGEBPF > > > I'm not sure how much this can help. > > But looking at tap-linux.h, I wonder do we need to pull TUN/TAP uapi > headers. > > Thanks > Agree, we just need to add this define to tap-linux.h > > > > + if (ioctl(fd, TUNSETSTEERINGEBPF, (void *) &prog_fd) != 0) { > > + error_report("Issue while setting TUNSETSTEERINGEBPF:" > > + " %s with fd: %d, prog_fd: %d", > > + strerror(errno), fd, prog_fd); > > + > > + return -1; > > + } > > + > > + return 0; > > +#else > > + error_report("TUNSETSTEERINGEBPF is not supported"); > > + return -1; > > +#endif > > +} > > diff --git a/net/tap-solaris.c b/net/tap-solaris.c > > index 0475a58207..d85224242b 100644 > > --- a/net/tap-solaris.c > > +++ b/net/tap-solaris.c > > @@ -255,3 +255,8 @@ int tap_fd_get_ifname(int fd, char *ifname) > > { > > return -1; > > } > > + > > +int tap_fd_set_steering_ebpf(int fd, int prog_fd) > > +{ > > + return -1; > > +} > > diff --git a/net/tap-stub.c b/net/tap-stub.c > > index de525a2e69..a0fa25804b 100644 > > --- a/net/tap-stub.c > > +++ b/net/tap-stub.c > > @@ -85,3 +85,8 @@ int tap_fd_get_ifname(int fd, char *ifname) > > { > > return -1; > > } > > + > > +int tap_fd_set_steering_ebpf(int fd, int prog_fd) > > +{ > > + return -1; > > +} > > diff --git a/net/tap.c b/net/tap.c > > index c46ff66184..81f50017bd 100644 > > --- a/net/tap.c > > +++ b/net/tap.c > > @@ -337,6 +337,14 @@ static void tap_poll(NetClientState *nc, bool > enable) > > tap_write_poll(s, enable); > > } > > > > +static bool tap_set_steering_ebpf(NetClientState *nc, int prog_fd) > > +{ > > + TAPState *s = DO_UPCAST(TAPState, nc, nc); > > + assert(nc->info->type == NET_CLIENT_DRIVER_TAP); > > + > > + return tap_fd_set_steering_ebpf(s->fd, prog_fd) == 0; > > +} > > + > > int tap_get_fd(NetClientState *nc) > > { > > TAPState *s = DO_UPCAST(TAPState, nc, nc); > > @@ -362,6 +370,7 @@ static NetClientInfo net_tap_info = { > > .set_vnet_hdr_len = tap_set_vnet_hdr_len, > > .set_vnet_le = tap_set_vnet_le, > > .set_vnet_be = tap_set_vnet_be, > > + .set_steering_ebpf = tap_set_steering_ebpf, > > }; > > > > static TAPState *net_tap_fd_init(NetClientState *peer, > > diff --git a/net/tap_int.h b/net/tap_int.h > > index 225a49ea48..547f8a5a28 100644 > > --- a/net/tap_int.h > > +++ b/net/tap_int.h > > @@ -44,5 +44,6 @@ int tap_fd_set_vnet_be(int fd, int vnet_is_be); > > int tap_fd_enable(int fd); > > int tap_fd_disable(int fd); > > int tap_fd_get_ifname(int fd, char *ifname); > > +int tap_fd_set_steering_ebpf(int fd, int prog_fd); > > > > #endif /* NET_TAP_INT_H */ > >