pkt-loop-filter: Handle old type of net->net_cookie

The type of the net->net_cookie field member was changed in kernel 5.12
with commit 3d368ab87cf6 ("net: initialize net->net_cookie at netns setup").
Older versions of the kernel devices net->net_cookie as an atomic64_t
instead of a u64. This causes CO-RE reading of the field to fail due to the
type mismatch. Handle this by adding CO-RE checks for the old type as well
and using the CO-RE facility to check for the right type at load time.

Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
This commit is contained in:
Toke Høiland-Jørgensen
2022-07-08 13:57:54 +02:00
parent 9dd20f3325
commit 0306ff7cca
3 changed files with 26 additions and 2 deletions
+21
View File
@@ -27,6 +27,14 @@ struct net {
__u64 net_cookie;
} __attribute__((preserve_access_index));
typedef struct {
__s64 counter;
} atomic64_t;
struct net___old {
atomic64_t net_cookie;
} __attribute__((preserve_access_index));
struct net_device {
int ifindex;
struct {
@@ -38,4 +46,17 @@ struct netdev_notifier_info {
struct net_device *dev;
} __attribute__((preserve_access_index));
static inline __u64 read_net_cookie(struct net *net)
{
if (bpf_core_field_exists(net->net_cookie)) {
return BPF_CORE_READ(net, net_cookie);
} else {
struct net___old *n_old = (void *)net;
atomic64_t cookie_old;
cookie_old = BPF_CORE_READ(n_old, net_cookie);
return cookie_old.counter;
}
}
#endif
+2 -1
View File
@@ -15,8 +15,9 @@ SEC("kprobe/bond_select_active_slave")
int BPF_KPROBE(handle_select_slave, struct bonding *bond)
{
struct net_device *dev = BPF_PROBE_READ(bond, dev);
struct net *net = BPF_CORE_READ(dev, nd_net.net);
int ifindex = BPF_CORE_READ(dev, ifindex);
__u64 cookie = BPF_CORE_READ(dev, nd_net.net, net_cookie);
__u64 cookie = read_net_cookie(net);
if (cookie == netns_cookie && ifindex == bond_ifindex) {
struct net_device *active_dev = BPF_PROBE_READ(bond, curr_active_slave, dev);
+3 -1
View File
@@ -156,8 +156,10 @@ SEC("kprobe/bond_change_active_slave")
int BPF_KPROBE(handle_change_slave, struct bonding *bond, struct slave *new_active)
{
struct net_device *dev = BPF_PROBE_READ(bond, dev);
struct net *net = BPF_CORE_READ(dev, nd_net.net);
int ifindex = BPF_CORE_READ(dev, ifindex);
__u64 cookie = BPF_CORE_READ(dev, nd_net.net, net_cookie);
__u64 cookie = read_net_cookie(net);
if (cookie == netns_cookie && ifindex == bond_ifindex && new_active) {
struct net_device *new_dev;