Lines Matching +full:array +full:- +full:nest

1 // SPDX-License-Identifier: GPL-2.0-or-later
47 const struct tcf_chain *chain = rcu_dereference_bh(a->goto_chain);
49 res->goto_tp = rcu_dereference_bh(chain->filter_chain);
56 kfree(cookie->data);
67 call_rcu(&old->rcu, tcf_free_cookie_rcu);
74 int opcode = TC_ACT_EXT_OPCODE(action), ret = -EINVAL;
78 ret = action > TC_ACT_VALUE_MAX ? -EINVAL : 0;
89 ret = -EINVAL;
94 *newchain = tcf_chain_get_by_act(tp->chain->block, chain_index);
96 ret = -ENOMEM;
109 a->tcfa_action = action;
110 goto_chain = rcu_replace_pointer(a->goto_chain, goto_chain, 1);
122 struct tcf_chain *chain = rcu_dereference_protected(p->goto_chain, 1);
124 free_percpu(p->cpu_bstats);
125 free_percpu(p->cpu_bstats_hw);
126 free_percpu(p->cpu_qstats);
128 tcf_set_action_cookie(&p->user_cookie, NULL);
138 act->in_hw_count = hw_count;
144 act->in_hw_count += hw_count;
150 act->in_hw_count = act->in_hw_count > hw_count ?
151 act->in_hw_count - hw_count : 0;
187 fl_action->extack = extack;
188 fl_action->command = cmd;
189 fl_action->index = act->tcfa_index;
190 fl_action->cookie = (unsigned long)act;
192 if (act->ops->offload_act_setup) {
193 spin_lock_bh(&act->tcfa_lock);
194 err = act->ops->offload_act_setup(act, fl_action, NULL,
196 spin_unlock_bh(&act->tcfa_lock);
200 return -EOPNOTSUPP;
251 bool skip_sw = tc_act_skip_sw(action->tcfa_flags);
259 if (tc_act_skip_hw(action->tcfa_flags))
265 return -ENOMEM;
271 err = tc_setup_action(&fl_action->action, actions, 0, extack);
284 err = -EINVAL;
286 tc_cleanup_offload_action(&fl_action->action);
319 action->used_hw_stats = fl_act.stats.used_hw_stats;
320 action->used_hw_stats_valid = true;
322 return -EOPNOTSUPP;
348 if (!cb && action->in_hw_count != in_hw_count)
349 return -EINVAL;
366 if (p->ops->cleanup)
367 p->ops->cleanup(p);
369 gen_kill_estimator(&p->tcfa_rate_est);
375 struct tcf_idrinfo *idrinfo = p->idrinfo;
377 if (refcount_dec_and_mutex_lock(&p->tcfa_refcnt, &idrinfo->lock)) {
379 atomic_dec(&p->tcfa_bindcnt);
380 idr_remove(&idrinfo->action_idr, p->tcfa_index);
381 mutex_unlock(&idrinfo->lock);
388 atomic_dec(&p->tcfa_bindcnt);
410 if (!bind && strict && atomic_read(&p->tcfa_bindcnt) > 0)
411 return -EPERM;
422 const struct tc_action_ops *ops = a->ops;
427 module_put(ops->owner);
438 user_cookie = rcu_dereference(act->user_cookie);
441 cookie_len = nla_total_size(user_cookie->len);
472 if (act->ops->get_fill_size)
473 return act->ops->get_fill_size(act) + sz;
483 if (nla_put_string(skb, TCA_ACT_KIND, a->ops->kind))
487 if (from_act && nla_put_u32(skb, TCA_ACT_INDEX, a->tcfa_index))
491 cookie = rcu_dereference(a->user_cookie);
493 if (nla_put(skb, TCA_ACT_COOKIE, cookie->len, cookie->data)) {
504 return -1;
511 struct nlattr *nest;
512 int err = -EINVAL;
518 if (a->hw_stats != TCA_ACT_HW_STATS_ANY &&
520 a->hw_stats, TCA_ACT_HW_STATS_ANY))
523 if (a->used_hw_stats_valid &&
525 a->used_hw_stats, TCA_ACT_HW_STATS_ANY))
528 flags = a->tcfa_flags & TCA_ACT_FLAGS_USER_MASK;
534 if (nla_put_u32(skb, TCA_ACT_IN_HW_COUNT, a->in_hw_count))
537 nest = nla_nest_start_noflag(skb, TCA_ACT_OPTIONS);
538 if (nest == NULL)
542 nla_nest_end(skb, nest);
548 return -1;
554 int err = 0, index = -1, s_i = 0, n_i = 0;
555 u32 act_flags = cb->args[2];
556 unsigned long jiffy_since = cb->args[3];
557 struct nlattr *nest;
558 struct idr *idr = &idrinfo->action_idr;
563 mutex_lock(&idrinfo->lock);
565 s_i = cb->args[0];
576 (unsigned long)p->tcfa_tm.lastuse))
581 nest = nla_nest_start_noflag(skb, n_i);
582 if (!nest) {
583 index--;
590 index--;
591 nlmsg_trim(skb, nest);
594 nla_nest_end(skb, nest);
602 cb->args[0] = index + 1;
604 mutex_unlock(&idrinfo->lock);
607 cb->args[1] = n_i;
612 nla_nest_cancel(skb, nest);
618 if (atomic_read(&p->tcfa_bindcnt) > 0)
619 return -EPERM;
621 if (refcount_dec_and_test(&p->tcfa_refcnt)) {
622 idr_remove(&p->idrinfo->action_idr, p->tcfa_index);
634 struct nlattr *nest;
636 int ret = -EINVAL;
637 struct idr *idr = &idrinfo->action_idr;
642 nest = nla_nest_start_noflag(skb, 0);
643 if (nest == NULL)
645 if (nla_put_string(skb, TCA_ACT_KIND, ops->kind))
649 mutex_lock(&idrinfo->lock);
655 module_put(ops->owner);
660 mutex_unlock(&idrinfo->lock);
671 nla_nest_end(skb, nest);
675 nla_nest_cancel(skb, nest);
684 struct tcf_idrinfo *idrinfo = tn->idrinfo;
693 return -EINVAL;
700 struct tcf_idrinfo *idrinfo = tn->idrinfo;
703 mutex_lock(&idrinfo->lock);
704 p = idr_find(&idrinfo->action_idr, index);
708 refcount_inc(&p->tcfa_refcnt);
709 mutex_unlock(&idrinfo->lock);
724 struct tc_action_net *tn = net_generic(net, ops->net_id);
726 if (unlikely(ops->walk))
727 return ops->walk(net, skb, cb, type, ops, extack);
736 struct tc_action_net *tn = net_generic(net, ops->net_id);
738 if (unlikely(ops->lookup))
739 return ops->lookup(net, a, index);
749 mutex_lock(&idrinfo->lock);
750 p = idr_find(&idrinfo->action_idr, index);
752 mutex_unlock(&idrinfo->lock);
753 return -ENOENT;
756 if (!atomic_read(&p->tcfa_bindcnt)) {
757 if (refcount_dec_and_test(&p->tcfa_refcnt)) {
758 struct module *owner = p->ops->owner;
760 WARN_ON(p != idr_remove(&idrinfo->action_idr,
761 p->tcfa_index));
762 mutex_unlock(&idrinfo->lock);
770 ret = -EPERM;
773 mutex_unlock(&idrinfo->lock);
781 struct tc_action *p = kzalloc(ops->size, GFP_KERNEL);
782 struct tcf_idrinfo *idrinfo = tn->idrinfo;
783 int err = -ENOMEM;
786 return -ENOMEM;
787 refcount_set(&p->tcfa_refcnt, 1);
789 atomic_set(&p->tcfa_bindcnt, 1);
792 p->cpu_bstats = netdev_alloc_pcpu_stats(struct gnet_stats_basic_sync);
793 if (!p->cpu_bstats)
795 p->cpu_bstats_hw = netdev_alloc_pcpu_stats(struct gnet_stats_basic_sync);
796 if (!p->cpu_bstats_hw)
798 p->cpu_qstats = alloc_percpu(struct gnet_stats_queue);
799 if (!p->cpu_qstats)
802 gnet_stats_basic_sync_init(&p->tcfa_bstats);
803 gnet_stats_basic_sync_init(&p->tcfa_bstats_hw);
804 spin_lock_init(&p->tcfa_lock);
805 p->tcfa_index = index;
806 p->tcfa_tm.install = jiffies;
807 p->tcfa_tm.lastuse = jiffies;
808 p->tcfa_tm.firstuse = 0;
809 p->tcfa_flags = flags;
811 err = gen_new_estimator(&p->tcfa_bstats, p->cpu_bstats,
812 &p->tcfa_rate_est,
813 &p->tcfa_lock, false, est);
818 p->idrinfo = idrinfo;
819 __module_get(ops->owner);
820 p->ops = ops;
824 free_percpu(p->cpu_qstats);
826 free_percpu(p->cpu_bstats_hw);
828 free_percpu(p->cpu_bstats);
850 struct tcf_idrinfo *idrinfo = tn->idrinfo;
852 mutex_lock(&idrinfo->lock);
853 /* Remove ERR_PTR(-EBUSY) allocated by tcf_idr_check_alloc */
854 WARN_ON(!IS_ERR(idr_remove(&idrinfo->action_idr, index)));
855 mutex_unlock(&idrinfo->lock);
864 * May return -EAGAIN for binding actions in case of a parallel add/delete on
871 struct tcf_idrinfo *idrinfo = tn->idrinfo;
878 p = idr_find(&idrinfo->action_idr, *index);
885 return -EAGAIN;
895 if (!refcount_inc_not_zero(&p->tcfa_refcnt)) {
898 return -EAGAIN;
902 atomic_inc(&p->tcfa_bindcnt);
917 mutex_lock(&idrinfo->lock);
918 ret = idr_alloc_u32(&idrinfo->action_idr, ERR_PTR(-EBUSY), index, max,
920 mutex_unlock(&idrinfo->lock);
925 if (ret == -ENOSPC && *index == max)
926 ret = -EAGAIN;
935 struct idr *idr = &idrinfo->action_idr;
949 module_put(ops->owner);
955 idr_destroy(&idrinfo->action_idr);
980 if (id_ptr->id == id) {
981 ret = -EEXIST;
988 ret = -ENOMEM;
991 id_ptr->id = id;
993 list_add_tail(&id_ptr->list, &act_pernet_id_list);
1006 if (id_ptr->id == id) {
1007 list_del(&id_ptr->list);
1021 if (!act->act || !act->dump || !act->init)
1022 return -EINVAL;
1032 if (ops->id) {
1033 ret = tcf_pernet_add_id_list(*ops->id);
1040 if (act->id == a->id || (strcmp(act->kind, a->kind) == 0)) {
1041 ret = -EEXIST;
1045 list_add_tail(&act->head, &act_base);
1052 if (ops->id)
1053 tcf_pernet_del_id_list(*ops->id);
1064 int err = -ENOENT;
1069 list_del(&act->head);
1077 if (ops->id)
1078 tcf_pernet_del_id_list(*ops->id);
1092 if (strcmp(kind, a->kind) == 0) {
1093 if (try_module_get(a->owner))
1111 if (nla_strcmp(kind, a->kind) == 0) {
1112 if (try_module_get(a->owner))
1141 jmp_prgcnt -= 1;
1145 if (tc_act_skip_sw(a->tcfa_flags))
1152 if (--repeat_ttl != 0)
1164 jmp_ttl -= 1;
1171 if (unlikely(!rcu_access_pointer(a->goto_chain))) {
1195 ops = a->ops;
1198 module_put(ops->owner);
1216 const struct tc_action_ops *ops = a->ops;
1218 module_put(ops->owner);
1228 const struct tc_action_ops *ops = a->ops;
1234 module_put(ops->owner);
1241 return a->ops->dump(skb, a, bind, ref);
1248 int err = -EINVAL, i;
1249 struct nlattr *nest;
1252 nest = nla_nest_start_noflag(skb, i + 1);
1253 if (nest == NULL)
1259 nla_nest_end(skb, nest);
1265 err = -EINVAL;
1267 nla_nest_cancel(skb, nest);
1277 c->data = nla_memdup(tb[TCA_ACT_COOKIE], GFP_KERNEL);
1278 if (!c->data) {
1282 c->len = nla_len(tb[TCA_ACT_COOKIE]);
1324 idrinfo = a->idrinfo;
1325 mutex_lock(&idrinfo->lock);
1326 /* Replace ERR_PTR(-EBUSY) allocated by tcf_idr_check_alloc */
1327 idr_replace(&idrinfo->action_idr, a, a->tcfa_index);
1328 mutex_unlock(&idrinfo->lock);
1347 err = -EINVAL;
1360 return ERR_PTR(-EINVAL);
1381 * indicate this using -EAGAIN.
1384 module_put(a_o->owner);
1385 return ERR_PTR(-EAGAIN);
1389 return ERR_PTR(-ENOENT);
1418 err = -ENOMEM;
1426 err = -EINVAL;
1431 err = a_o->init(net, tb[TCA_ACT_OPTIONS], est, &a, tp,
1434 err = a_o->init(net, nla, est, &a, tp, userflags.value | flags,
1442 tcf_set_action_cookie(&a->user_cookie, user_cookie);
1445 a->hw_stats = hw_stats;
1451 kfree(user_cookie->data);
1483 * array of actions. So we parse one more than we can handle, and return
1491 return -EINVAL;
1502 ops[i - 1] = a_o;
1506 act = tcf_action_init_1(net, tp, tb[i], est, ops[i - 1],
1507 &init_res[i - 1], flags, extack);
1514 actions[i - 1] = act;
1519 if (tc_act_bind(act->tcfa_flags)) {
1527 if ((tc_act_skip_sw(act->tcfa_flags) && !skip_sw) ||
1528 (tc_act_skip_hw(act->tcfa_flags) && !skip_hw)) {
1531 err = -EINVAL;
1535 act->tcfa_flags |= TCA_ACT_FLAGS_SKIP_SW;
1537 act->tcfa_flags |= TCA_ACT_FLAGS_SKIP_HW;
1542 if (skip_sw != tc_act_skip_sw(act->tcfa_flags) ||
1543 skip_hw != tc_act_skip_hw(act->tcfa_flags)) {
1546 err = -EINVAL;
1551 if (tc_act_skip_sw(act->tcfa_flags) && err)
1562 err = i - 1;
1569 module_put(ops[i]->owner);
1576 if (a->cpu_bstats) {
1577 _bstats_update(this_cpu_ptr(a->cpu_bstats), bytes, packets);
1579 this_cpu_ptr(a->cpu_qstats)->drops += drops;
1582 _bstats_update(this_cpu_ptr(a->cpu_bstats_hw),
1587 _bstats_update(&a->tcfa_bstats, bytes, packets);
1588 atomic_add(drops, &a->tcfa_drops);
1590 _bstats_update(&a->tcfa_bstats_hw, bytes, packets);
1608 if (p->type == TCA_OLD_COMPAT)
1612 &p->tcfa_lock, &d,
1618 &p->tcfa_lock, &d, TCA_ACT_PAD);
1623 qstats.drops = atomic_read(&p->tcfa_drops);
1624 qstats.overlimits = atomic_read(&p->tcfa_overlimits);
1626 if (gnet_stats_copy_basic(&d, p->cpu_bstats,
1627 &p->tcfa_bstats, false) < 0 ||
1628 gnet_stats_copy_basic_hw(&d, p->cpu_bstats_hw,
1629 &p->tcfa_bstats_hw, false) < 0 ||
1630 gnet_stats_copy_rate_est(&d, &p->tcfa_rate_est) < 0 ||
1631 gnet_stats_copy_queue(&d, p->cpu_qstats,
1642 return -1;
1652 struct nlattr *nest;
1658 t->tca_family = AF_UNSPEC;
1659 t->tca__pad1 = 0;
1660 t->tca__pad2 = 0;
1662 if (extack && extack->_msg &&
1663 nla_put_string(skb, TCA_ROOT_EXT_WARN_MSG, extack->_msg))
1666 nest = nla_nest_start_noflag(skb, TCA_ACT_TAB);
1667 if (!nest)
1673 nla_nest_end(skb, nest);
1675 nlh->nlmsg_len = skb_tail_pointer(skb) - b;
1677 return skb->len;
1681 return -1;
1693 return -ENOBUFS;
1694 if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, 0, event,
1698 return -EINVAL;
1719 err = -EINVAL;
1727 err = -EINVAL;
1733 err = -ENOENT;
1739 module_put(ops->owner);
1743 module_put(ops->owner);
1757 struct nlattr *nest;
1761 int err = -ENOMEM;
1774 err = -EINVAL;
1782 nlh = nlmsg_put(skb, portid, n->nlmsg_seq, RTM_DELACTION,
1789 t->tca_family = AF_UNSPEC;
1790 t->tca__pad1 = 0;
1791 t->tca__pad2 = 0;
1793 nest = nla_nest_start_noflag(skb, TCA_ACT_TAB);
1794 if (!nest) {
1801 nla_nest_cancel(skb, nest);
1805 nla_nest_end(skb, nest);
1807 nlh->nlmsg_len = skb_tail_pointer(skb) - b;
1808 nlh->nlmsg_flags |= NLM_F_ROOT;
1809 module_put(ops->owner);
1811 n->nlmsg_flags & NLM_F_ECHO);
1818 module_put(ops->owner);
1830 const struct tc_action_ops *ops = a->ops;
1834 struct tcf_idrinfo *idrinfo = a->idrinfo;
1835 u32 act_index = a->tcfa_index;
1840 module_put(ops->owner);
1864 return ERR_PTR(-ENOBUFS);
1868 return ERR_PTR(-EINVAL);
1876 const struct tc_action_ops *ops = action->ops;
1890 module_put(ops->owner);
1914 return -EINVAL;
1921 act_id = id_ptr->id;
1925 idrinfo = tn->idrinfo;
1929 mutex_lock(&idrinfo->lock);
1930 idr = &idrinfo->action_idr;
1932 if (IS_ERR(p) || tc_act_bind(p->tcfa_flags))
1944 if (tc_act_skip_sw(p->tcfa_flags) &&
1948 mutex_unlock(&idrinfo->lock);
1966 return ERR_PTR(-ENOBUFS);
1968 if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, 0, RTM_DELACTION,
1972 return ERR_PTR(-EINVAL);
1985 if (!rtnl_notify_needed(net, n->nlmsg_flags, RTNLGRP_TC)) {
2003 n->nlmsg_flags & NLM_F_ECHO);
2021 if (event == RTM_DELACTION && n->nlmsg_flags & NLM_F_ROOT) {
2026 return -EINVAL;
2036 actions[i - 1] = act;
2063 return ERR_PTR(-ENOBUFS);
2065 if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, n->nlmsg_flags,
2069 return ERR_PTR(-EINVAL);
2081 if (!rtnl_notify_needed(net, n->nlmsg_flags, RTNLGRP_TC)) {
2091 n->nlmsg_flags & NLM_F_ECHO);
2106 if (ret != -EAGAIN)
2130 struct net *net = sock_net(skb->sk);
2136 if ((n->nlmsg_type != RTM_GETACTION) &&
2138 return -EPERM;
2147 return -EINVAL;
2150 /* n->nlmsg_flags & NLM_F_CREATE */
2151 switch (n->nlmsg_type) {
2159 if (n->nlmsg_flags & NLM_F_REPLACE)
2203 struct net *net = sock_net(skb->sk);
2206 struct nlattr *nest;
2209 struct tcamsg *t = (struct tcamsg *) nlmsg_data(cb->nlh);
2218 ret = nlmsg_parse_deprecated(cb->nlh, sizeof(struct tcamsg), tb,
2219 TCA_ROOT_MAX, tcaa_policy, cb->extack);
2233 cb->args[2] = 0;
2236 cb->args[2] = bf.value;
2243 nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
2244 cb->nlh->nlmsg_type, sizeof(*t), 0);
2249 jiffy_since = jiffies - msecs_to_jiffies(msecs_since);
2252 t->tca_family = AF_UNSPEC;
2253 t->tca__pad1 = 0;
2254 t->tca__pad2 = 0;
2255 cb->args[3] = jiffy_since;
2260 nest = nla_nest_start_noflag(skb, TCA_ACT_TAB);
2261 if (nest == NULL)
2269 nla_nest_end(skb, nest);
2270 ret = skb->len;
2271 act_count = cb->args[1];
2273 cb->args[1] = 0;
2277 nlh->nlmsg_len = skb_tail_pointer(skb) - b;
2278 if (NETLINK_CB(cb->skb).portid && ret)
2279 nlh->nlmsg_flags |= NLM_F_MULTI;
2280 module_put(a_o->owner);
2281 return skb->len;
2284 module_put(a_o->owner);
2286 return skb->len;