staticint ife_validate_metatype(struct tcf_meta_ops *ops, void *val, int len)
{ int ret = 0; /* XXX: unfortunately cant use nla_policy at this point *becausealengthof0isvalidinthecaseof *"allow"."use"semanticsdoenforceforproper *lengthandicouldveusenla_policybutitmakesithard *touseitjustforthat..
*/ if (ops->validate) return ops->validate(val, len);
if (ops->metatype == NLA_U32)
ret = ife_validate_meta_u32(val, len); elseif (ops->metatype == NLA_U16)
ret = ife_validate_meta_u16(val, len);
return ret;
}
#ifdef CONFIG_MODULES staticconstchar *ife_meta_id2name(u32 metaid)
{ switch (metaid) { case IFE_META_SKBMARK: return"skbmark"; case IFE_META_PRIO: return"skbprio"; case IFE_META_TCINDEX: return"tcindex"; default: return"unknown";
}
} #endif
/* called when adding new meta information
*/ staticint load_metaops_and_vet(u32 metaid, void *val, int len, bool rtnl_held)
{ struct tcf_meta_ops *ops = find_ife_oplist(metaid); int ret = 0;
if (!ops) {
ret = -ENOENT; #ifdef CONFIG_MODULES if (rtnl_held)
rtnl_unlock();
request_module("ife-meta-%s", ife_meta_id2name(metaid)); if (rtnl_held)
rtnl_lock();
ops = find_ife_oplist(metaid); #endif
}
if (ops) {
ret = 0; if (len)
ret = ife_validate_metatype(ops, val, len);
module_put(ops->owner);
}
return ret;
}
/* called when adding new meta information
*/ staticint __add_metainfo(conststruct tcf_meta_ops *ops, struct tcf_ife_info *ife, u32 metaid, void *metaval, int len, bool atomic, bool exists)
{ struct tcf_meta_info *mi = NULL; int ret = 0;
mi = kzalloc(sizeof(*mi), atomic ? GFP_ATOMIC : GFP_KERNEL); if (!mi) return -ENOMEM;
mi->metaid = metaid;
mi->ops = ops; if (len > 0) {
ret = ops->alloc(mi, metaval, atomic ? GFP_ATOMIC : GFP_KERNEL); if (ret != 0) {
kfree(mi); return ret;
}
}
if (exists)
spin_lock_bh(&ife->tcf_lock);
list_add_tail(&mi->metalist, &ife->metalist); if (exists)
spin_unlock_bh(&ife->tcf_lock);
if (!try_module_get(ops->owner)) return -ENOENT;
ret = __add_metainfo(ops, ife, metaid, NULL, 0, true, exists); if (ret)
module_put(ops->owner); return ret;
}
staticint add_metainfo(struct tcf_ife_info *ife, u32 metaid, void *metaval, int len, bool exists)
{ conststruct tcf_meta_ops *ops = find_ife_oplist(metaid); int ret;
if (!ops) return -ENOENT;
ret = __add_metainfo(ops, ife, metaid, metaval, len, false, exists); if (ret) /*put back what find_ife_oplist took */
module_put(ops->owner); return ret;
}
staticint use_all_metadata(struct tcf_ife_info *ife, bool exists)
{ struct tcf_meta_ops *o; int rc = 0; int installed = 0;
/* IFE_DECODE is 0 and indicates the opposite of IFE_ENCODE because *theycannotrunasthesametime.Checkonallothervalueswhich *arenotsupportedrightnow.
*/ if (parm->flags & ~IFE_ENCODE) return -EINVAL;
p = kzalloc(sizeof(*p), GFP_KERNEL); if (!p) return -ENOMEM;
/* XXX: use hash to speed up */
list_for_each_entry(e, &ife->metalist, metalist) { if (metaid == e->metaid) { if (e->ops) { /* We check for decode presence already */ return e->ops->decode(skb, mdata, mlen);
}
}
}
/*XXX: check if we can do this at install time instead of current *senddatapath
**/ staticint ife_get_sz(struct sk_buff *skb, struct tcf_ife_info *ife)
{ struct tcf_meta_info *e, *n; int tot_run_sz = 0, run_sz = 0;
list_for_each_entry_safe(e, n, &ife->metalist, metalist) { if (e->ops->check_presence) {
run_sz = e->ops->check_presence(skb, e);
tot_run_sz += run_sz;
}
}
if (!metalen) { /* no metadata to send */ /* abuse overlimits to count when we allow packet *withnometadata
*/
qstats_overlimit_inc(this_cpu_ptr(ife->common.cpu_qstats)); return action;
} /* could be stupid policy setup or mtu config
* so lets be conservative.. */ if ((action == TC_ACT_SHOT) || exceed_mtu) {
qstats_drop_inc(this_cpu_ptr(ife->common.cpu_qstats)); return TC_ACT_SHOT;
}
if (skb_at_tc_ingress(skb))
skb_push(skb, skb->dev->hard_header_len);
ife_meta = ife_encode(skb, metalen);
spin_lock(&ife->tcf_lock);
/* XXX: we dont have a clever way of telling encode to *notrepeatsomeofthecomputationsthataredoneby *ops->presence_check...
*/
list_for_each_entry(e, &ife->metalist, metalist) { if (e->ops->encode) {
err = e->ops->encode(skb, (void *)(ife_meta + skboff),
e);
} if (err < 0) { /* too corrupt to keep around if overwritten */
spin_unlock(&ife->tcf_lock);
qstats_drop_inc(this_cpu_ptr(ife->common.cpu_qstats)); return TC_ACT_SHOT;
}
skboff += err;
}
spin_unlock(&ife->tcf_lock);
oethh = (struct ethhdr *)skb->data;
if (!is_zero_ether_addr(p->eth_src))
ether_addr_copy(oethh->h_source, p->eth_src); if (!is_zero_ether_addr(p->eth_dst))
ether_addr_copy(oethh->h_dest, p->eth_dst);
oethh->h_proto = htons(p->eth_type);
if (skb_at_tc_ingress(skb))
skb_pull(skb, skb->dev->hard_header_len);
MODULE_AUTHOR("Jamal Hadi Salim(2015)");
MODULE_DESCRIPTION("Inter-FE LFB action");
MODULE_LICENSE("GPL");
Messung V0.5 in Prozent
¤ 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.0.12Bemerkung:
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-09-28)
¤
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.