On 10/4/22 4:11 PM, Daniel Borkmann wrote:
@@ -191,7 +202,8 @@ static void __xtc_prog_detach_all(struct net_device *dev, bool ingress, u32 limi if (!prog) break; dev_xtc_entry_prio_del(entry, item->bpf_priority); - bpf_prog_put(prog); + if (!item->bpf_id) + bpf_prog_put(prog);
Should the link->dev be set to NULL somewhere?
if (ingress) net_dec_ingress_queue(); else @@ -244,6 +256,7 @@ __xtc_prog_query(const union bpf_attr *attr, union bpf_attr __user *uattr, if (!prog) break; info.prog_id = prog->aux->id; + info.link_id = item->bpf_id; info.prio = item->bpf_priority; if (copy_to_user(uinfo + i, &info, sizeof(info))) return -EFAULT; @@ -272,3 +285,90 @@ int xtc_prog_query(const union bpf_attr *attr, union bpf_attr __user *uattr) rtnl_unlock(); return ret; } +
[ ... ]
+static void xtc_link_release(struct bpf_link *l) +{ + struct bpf_tc_link *link = container_of(l, struct bpf_tc_link, link); + + rtnl_lock(); + if (link->dev) { + WARN_ON(__xtc_prog_detach(link->dev, + link->location == BPF_NET_INGRESS, + XTC_MAX_ENTRIES, l->id, link->priority)); + link->dev = NULL; + } + rtnl_unlock(); +}