staticint cxgb4_policer_validate(conststruct flow_action *action, conststruct flow_action_entry *act, struct netlink_ext_ack *extack)
{ if (act->police.exceed.act_id != FLOW_ACTION_DROP) {
NL_SET_ERR_MSG_MOD(extack, "Offload not supported when exceed action is not drop"); return -EOPNOTSUPP;
}
if (act->police.notexceed.act_id != FLOW_ACTION_PIPE &&
act->police.notexceed.act_id != FLOW_ACTION_ACCEPT) {
NL_SET_ERR_MSG_MOD(extack, "Offload not supported when conform action is not pipe or ok"); return -EOPNOTSUPP;
}
if (act->police.notexceed.act_id == FLOW_ACTION_ACCEPT &&
!flow_action_is_last_entry(action, act)) {
NL_SET_ERR_MSG_MOD(extack, "Offload not supported when conform action is ok, but action is not last"); return -EOPNOTSUPP;
}
if (act->police.peakrate_bytes_ps ||
act->police.avrate || act->police.overhead) {
NL_SET_ERR_MSG_MOD(extack, "Offload not supported when peakrate/avrate/overhead is configured"); return -EOPNOTSUPP;
}
if (act->police.rate_pkt_ps) {
NL_SET_ERR_MSG_MOD(extack, "QoS offload not support packets per second"); return -EOPNOTSUPP;
}
if (!flow_action_has_entries(actions)) {
NL_SET_ERR_MSG_MOD(extack, "Egress MATCHALL offload needs at least 1 policing action"); return -EINVAL;
} elseif (!flow_offload_has_one_action(actions)) {
NL_SET_ERR_MSG_MOD(extack, "Egress MATCHALL offload only supports 1 policing action"); return -EINVAL;
} elseif (pi->tc_block_shared) {
NL_SET_ERR_MSG_MOD(extack, "Egress MATCHALL offload not supported with shared blocks"); return -EINVAL;
}
ret = t4_get_link_params(pi, NULL, &speed, NULL); if (ret) {
NL_SET_ERR_MSG_MOD(extack, "Failed to get max speed supported by the link"); return -EINVAL;
}
/* Convert from Mbps to bps */
max_link_rate = (u64)speed * 1000 * 1000;
flow_action_for_each(i, entry, actions) { switch (entry->id) { case FLOW_ACTION_POLICE:
ret = cxgb4_policer_validate(actions, entry, extack); if (ret) return ret;
/* Convert bytes per second to bits per second */ if (entry->police.rate_bytes_ps * 8 > max_link_rate) {
NL_SET_ERR_MSG_MOD(extack, "Specified policing max rate is larger than underlying link speed"); return -ERANGE;
} break; default:
NL_SET_ERR_MSG_MOD(extack, "Only policing action supported with Egress MATCHALL offload"); return -EOPNOTSUPP;
}
}
for (i = 0; i < pi->nqsets; i++) {
memset(&qe, 0, sizeof(qe));
qe.queue = i;
e = cxgb4_sched_queue_lookup(dev, &qe); if (e && e->info.u.params.level != SCHED_CLASS_LEVEL_CH_RL) {
NL_SET_ERR_MSG_MOD(extack, "Some queues are already bound to different class"); return -EBUSY;
}
}
flow_action_for_each(i, entry, &cls->rule->action) if (entry->id == FLOW_ACTION_POLICE) break;
ret = cxgb4_policer_validate(&cls->rule->action, entry, extack); if (ret) return ret;
/* Convert from bytes per second to Kbps */
p.u.params.maxrate = div_u64(entry->police.rate_bytes_ps * 8, 1000);
p.u.params.channel = pi->tx_chan;
e = cxgb4_sched_class_alloc(dev, &p); if (!e) {
NL_SET_ERR_MSG_MOD(extack, "No free traffic class available for policing action"); return -ENOMEM;
}
ret = cxgb4_matchall_tc_bind_queues(dev, e->idx); if (ret) {
NL_SET_ERR_MSG_MOD(extack, "Could not bind queues to traffic class"); goto out_free;
}
/* Get a free filter entry TID, where we can insert this new * rule. Only insert rule if its prio doesn't conflict with * existing rules.
*/
fidx = cxgb4_get_free_ftid(dev, filter_type ? PF_INET6 : PF_INET, false, cls->common.prio); if (fidx < 0) {
NL_SET_ERR_MSG_MOD(extack, "No free LETCAM index available"); return -ENOMEM;
}
tc_port_matchall = &adap->tc_matchall->port_matchall[pi->port_id]; if (ingress) { /* All the filter types of this matchall rule save the * same cookie. So, checking for the first one is * enough.
*/ if (cls_matchall->cookie !=
tc_port_matchall->ingress.fs[0].tc_cookie) return -ENOENT;
return cxgb4_matchall_free_filter(dev);
}
if (cls_matchall->cookie != tc_port_matchall->egress.cookie) return -ENOENT;
tc_port_matchall = &adap->tc_matchall->port_matchall[pi->port_id]; if (tc_port_matchall->ingress.state == CXGB4_MATCHALL_STATE_DISABLED) return -ENOENT;
ingress = &tc_port_matchall->ingress; for (i = 0; i < CXGB4_FILTER_TYPE_MAX; i++) {
ret = cxgb4_get_filter_counters(dev, ingress->tid[i],
&tmp_packets, &tmp_bytes,
ingress->fs[i].hash); if (ret) return ret;
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.