if (err) {
bpf_log(log, "no write support to %s at off %d\n",
btf_name_by_offset(reg->btf, t->name_off), off); return -EACCES;
}
if (off + size > end) {
bpf_log(log, "write access at off %d with size %d beyond the member of %s ended at %zu\n",
off, size, btf_name_by_offset(reg->btf, t->name_off), end); return -EACCES;
}
/* r1 = stack[ctx_stack_off]; // r1 will be "u64 *ctx" *r1=r1[0];// r1 will be "struct Qdisc *sch" *r0=bpf_qdisc_reset_destroy_epilogue(r1); *BPF_EXIT;
*/
*insn++ = BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_FP, ctx_stack_off);
*insn++ = BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0);
*insn++ = BPF_CALL_KFUNC(0, bpf_qdisc_reset_destroy_epilogue_ids[0]);
*insn++ = BPF_EXIT_INSN();
return insn - insn_buf;
}
__bpf_kfunc_start_defs();
/* bpf_skb_get_hash - Get the flow hash of an skb. *@skb:Theskbtogettheflowhashfrom.
*/
__bpf_kfunc u32 bpf_skb_get_hash(struct sk_buff *skb)
{ return skb_get_hash(skb);
}
/* bpf_kfree_skb - Release an skb's reference and drop it immediately. *@skb:Theskbwhosereferencetobereleasedanddropped.
*/
__bpf_kfunc void bpf_kfree_skb(struct sk_buff *skb)
{
kfree_skb(skb);
}
/* bpf_qdisc_skb_drop - Drop an skb by adding it to a deferred free list. *@skb:Theskbwhosereferencetobereleasedanddropped. *@to_free_list:Thelistofskbstobedropped.
*/
__bpf_kfunc void bpf_qdisc_skb_drop(struct sk_buff *skb, struct bpf_sk_buff_ptr *to_free_list)
{
__qdisc_drop(skb, (struct sk_buff **)to_free_list);
}
/* bpf_qdisc_watchdog_schedule - Schedule a qdisc to a later time using a timer. *@sch:Theqdisctobescheduled. *@expire:Theexpirytimeofthetimer. *@delta_ns:Theslackrangeofthetimer.
*/
__bpf_kfunc void bpf_qdisc_watchdog_schedule(struct Qdisc *sch, u64 expire, u64 delta_ns)
{ struct bpf_sched_data *q = qdisc_priv(sch);
/* bpf_qdisc_init_prologue - Hidden kfunc called in prologue of .init. */
__bpf_kfunc int bpf_qdisc_init_prologue(struct Qdisc *sch, struct netlink_ext_ack *extack)
{ struct bpf_sched_data *q = qdisc_priv(sch); struct net_device *dev = qdisc_dev(sch); struct Qdisc *p;
qdisc_watchdog_init(&q->watchdog, sch);
if (sch->parent != TC_H_ROOT) { /* If qdisc_lookup() returns NULL, it means .init is called by *qdisc_create_dflt()inmq/mqprio_initandtheparentqdisc *hasnotbeenaddedtoqdisc_hashyet.
*/
p = qdisc_lookup(dev, TC_H_MAJ(sch->parent)); if (p && !(p->flags & TCQ_F_MQROOT)) {
NL_SET_ERR_MSG(extack, "BPF qdisc only supported on root or mq"); return -EINVAL;
}
}
return0;
}
/* bpf_qdisc_reset_destroy_epilogue - Hidden kfunc called in epilogue of .reset *and.destroy
*/
__bpf_kfunc void bpf_qdisc_reset_destroy_epilogue(struct Qdisc *sch)
{ struct bpf_sched_data *q = qdisc_priv(sch);
ret = register_btf_kfunc_id_set(BPF_PROG_TYPE_STRUCT_OPS, &bpf_qdisc_kfunc_set);
ret = ret ?: register_btf_id_dtor_kfuncs(skb_kfunc_dtors,
ARRAY_SIZE(skb_kfunc_dtors),
THIS_MODULE);
ret = ret ?: register_bpf_struct_ops(&bpf_Qdisc_ops, Qdisc_ops);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.