Skip to content

Commit 7c79cff

Browse files
Stanislav Fomichevkuba-moo
authored andcommitted
net: sched: wrap doit/dumpit methods
In preparation for grabbing netdev instance lock around qdisc operations, introduce tc_xxx wrappers that lookup netdev and call respective __tc_xxx helper to do the actual work. No functional changes. Cc: Cong Wang <[email protected]> Cc: Jiri Pirko <[email protected]> Cc: Saeed Mahameed <[email protected]> Reviewed-by: Jamal Hadi Salim <[email protected]> Signed-off-by: Stanislav Fomichev <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent c4f0f30 commit 7c79cff

File tree

1 file changed

+123
-68
lines changed

1 file changed

+123
-68
lines changed

net/sched/sch_api.c

Lines changed: 123 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1505,27 +1505,18 @@ const struct nla_policy rtm_tca_policy[TCA_MAX + 1] = {
15051505
* Delete/get qdisc.
15061506
*/
15071507

1508-
static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
1509-
struct netlink_ext_ack *extack)
1508+
static int __tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
1509+
struct netlink_ext_ack *extack,
1510+
struct net_device *dev,
1511+
struct nlattr *tca[TCA_MAX + 1],
1512+
struct tcmsg *tcm)
15101513
{
15111514
struct net *net = sock_net(skb->sk);
1512-
struct tcmsg *tcm = nlmsg_data(n);
1513-
struct nlattr *tca[TCA_MAX + 1];
1514-
struct net_device *dev;
1515-
u32 clid;
15161515
struct Qdisc *q = NULL;
15171516
struct Qdisc *p = NULL;
1517+
u32 clid;
15181518
int err;
15191519

1520-
err = nlmsg_parse_deprecated(n, sizeof(*tcm), tca, TCA_MAX,
1521-
rtm_tca_policy, extack);
1522-
if (err < 0)
1523-
return err;
1524-
1525-
dev = __dev_get_by_index(net, tcm->tcm_ifindex);
1526-
if (!dev)
1527-
return -ENODEV;
1528-
15291520
clid = tcm->tcm_parent;
15301521
if (clid) {
15311522
if (clid != TC_H_ROOT) {
@@ -1582,6 +1573,27 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
15821573
return 0;
15831574
}
15841575

1576+
static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
1577+
struct netlink_ext_ack *extack)
1578+
{
1579+
struct net *net = sock_net(skb->sk);
1580+
struct tcmsg *tcm = nlmsg_data(n);
1581+
struct nlattr *tca[TCA_MAX + 1];
1582+
struct net_device *dev;
1583+
int err;
1584+
1585+
err = nlmsg_parse_deprecated(n, sizeof(*tcm), tca, TCA_MAX,
1586+
rtm_tca_policy, extack);
1587+
if (err < 0)
1588+
return err;
1589+
1590+
dev = __dev_get_by_index(net, tcm->tcm_ifindex);
1591+
if (!dev)
1592+
return -ENODEV;
1593+
1594+
return __tc_get_qdisc(skb, n, extack, dev, tca, tcm);
1595+
}
1596+
15851597
static bool req_create_or_replace(struct nlmsghdr *n)
15861598
{
15871599
return (n->nlmsg_flags & NLM_F_CREATE &&
@@ -1601,35 +1613,19 @@ static bool req_change(struct nlmsghdr *n)
16011613
!(n->nlmsg_flags & NLM_F_EXCL));
16021614
}
16031615

1604-
/*
1605-
* Create/change qdisc.
1606-
*/
1607-
static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
1608-
struct netlink_ext_ack *extack)
1616+
static int __tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
1617+
struct netlink_ext_ack *extack,
1618+
struct net_device *dev,
1619+
struct nlattr *tca[TCA_MAX + 1],
1620+
struct tcmsg *tcm,
1621+
bool *replay)
16091622
{
1610-
struct net *net = sock_net(skb->sk);
1611-
struct tcmsg *tcm;
1612-
struct nlattr *tca[TCA_MAX + 1];
1613-
struct net_device *dev;
1623+
struct Qdisc *q = NULL;
1624+
struct Qdisc *p = NULL;
16141625
u32 clid;
1615-
struct Qdisc *q, *p;
16161626
int err;
16171627

1618-
replay:
1619-
/* Reinit, just in case something touches this. */
1620-
err = nlmsg_parse_deprecated(n, sizeof(*tcm), tca, TCA_MAX,
1621-
rtm_tca_policy, extack);
1622-
if (err < 0)
1623-
return err;
1624-
1625-
tcm = nlmsg_data(n);
16261628
clid = tcm->tcm_parent;
1627-
q = p = NULL;
1628-
1629-
dev = __dev_get_by_index(net, tcm->tcm_ifindex);
1630-
if (!dev)
1631-
return -ENODEV;
1632-
16331629

16341630
if (clid) {
16351631
if (clid != TC_H_ROOT) {
@@ -1755,7 +1751,7 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
17551751
}
17561752
err = qdisc_change(q, tca, extack);
17571753
if (err == 0)
1758-
qdisc_notify(net, skb, n, clid, NULL, q, extack);
1754+
qdisc_notify(sock_net(skb->sk), skb, n, clid, NULL, q, extack);
17591755
return err;
17601756

17611757
create_n_graft:
@@ -1788,8 +1784,10 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
17881784
tca, &err, extack);
17891785
}
17901786
if (q == NULL) {
1791-
if (err == -EAGAIN)
1792-
goto replay;
1787+
if (err == -EAGAIN) {
1788+
*replay = true;
1789+
return 0;
1790+
}
17931791
return err;
17941792
}
17951793

@@ -1804,6 +1802,39 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
18041802
return 0;
18051803
}
18061804

1805+
/*
1806+
* Create/change qdisc.
1807+
*/
1808+
static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
1809+
struct netlink_ext_ack *extack)
1810+
{
1811+
struct net *net = sock_net(skb->sk);
1812+
struct nlattr *tca[TCA_MAX + 1];
1813+
struct net_device *dev;
1814+
struct tcmsg *tcm;
1815+
bool replay;
1816+
int err;
1817+
1818+
replay:
1819+
/* Reinit, just in case something touches this. */
1820+
err = nlmsg_parse_deprecated(n, sizeof(*tcm), tca, TCA_MAX,
1821+
rtm_tca_policy, extack);
1822+
if (err < 0)
1823+
return err;
1824+
1825+
tcm = nlmsg_data(n);
1826+
dev = __dev_get_by_index(net, tcm->tcm_ifindex);
1827+
if (!dev)
1828+
return -ENODEV;
1829+
1830+
replay = false;
1831+
err = __tc_modify_qdisc(skb, n, extack, dev, tca, tcm, &replay);
1832+
if (replay)
1833+
goto replay;
1834+
1835+
return err;
1836+
}
1837+
18071838
static int tc_dump_qdisc_root(struct Qdisc *root, struct sk_buff *skb,
18081839
struct netlink_callback *cb,
18091840
int *q_idx_p, int s_q_idx, bool recur,
@@ -2135,31 +2166,22 @@ static void tc_bind_tclass(struct Qdisc *q, u32 portid, u32 clid,
21352166

21362167
#endif
21372168

2138-
static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n,
2139-
struct netlink_ext_ack *extack)
2169+
static int __tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n,
2170+
struct netlink_ext_ack *extack,
2171+
struct net_device *dev,
2172+
struct nlattr *tca[TCA_MAX + 1],
2173+
struct tcmsg *tcm)
21402174
{
21412175
struct net *net = sock_net(skb->sk);
2142-
struct tcmsg *tcm = nlmsg_data(n);
2143-
struct nlattr *tca[TCA_MAX + 1];
2144-
struct net_device *dev;
2145-
struct Qdisc *q = NULL;
21462176
const struct Qdisc_class_ops *cops;
2177+
struct Qdisc *q = NULL;
21472178
unsigned long cl = 0;
21482179
unsigned long new_cl;
21492180
u32 portid;
21502181
u32 clid;
21512182
u32 qid;
21522183
int err;
21532184

2154-
err = nlmsg_parse_deprecated(n, sizeof(*tcm), tca, TCA_MAX,
2155-
rtm_tca_policy, extack);
2156-
if (err < 0)
2157-
return err;
2158-
2159-
dev = __dev_get_by_index(net, tcm->tcm_ifindex);
2160-
if (!dev)
2161-
return -ENODEV;
2162-
21632185
/*
21642186
parent == TC_H_UNSPEC - unspecified parent.
21652187
parent == TC_H_ROOT - class is root, which has no parent.
@@ -2268,6 +2290,27 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n,
22682290
return err;
22692291
}
22702292

2293+
static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n,
2294+
struct netlink_ext_ack *extack)
2295+
{
2296+
struct net *net = sock_net(skb->sk);
2297+
struct tcmsg *tcm = nlmsg_data(n);
2298+
struct nlattr *tca[TCA_MAX + 1];
2299+
struct net_device *dev;
2300+
int err;
2301+
2302+
err = nlmsg_parse_deprecated(n, sizeof(*tcm), tca, TCA_MAX,
2303+
rtm_tca_policy, extack);
2304+
if (err < 0)
2305+
return err;
2306+
2307+
dev = __dev_get_by_index(net, tcm->tcm_ifindex);
2308+
if (!dev)
2309+
return -ENODEV;
2310+
2311+
return __tc_ctl_tclass(skb, n, extack, dev, tca, tcm);
2312+
}
2313+
22712314
struct qdisc_dump_args {
22722315
struct qdisc_walker w;
22732316
struct sk_buff *skb;
@@ -2344,20 +2387,12 @@ static int tc_dump_tclass_root(struct Qdisc *root, struct sk_buff *skb,
23442387
return 0;
23452388
}
23462389

2347-
static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
2390+
static int __tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb,
2391+
struct tcmsg *tcm, struct net_device *dev)
23482392
{
2349-
struct tcmsg *tcm = nlmsg_data(cb->nlh);
2350-
struct net *net = sock_net(skb->sk);
23512393
struct netdev_queue *dev_queue;
2352-
struct net_device *dev;
23532394
int t, s_t;
23542395

2355-
if (nlmsg_len(cb->nlh) < sizeof(*tcm))
2356-
return 0;
2357-
dev = dev_get_by_index(net, tcm->tcm_ifindex);
2358-
if (!dev)
2359-
return 0;
2360-
23612396
s_t = cb->args[0];
23622397
t = 0;
23632398

@@ -2374,10 +2409,30 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
23742409
done:
23752410
cb->args[0] = t;
23762411

2377-
dev_put(dev);
23782412
return skb->len;
23792413
}
23802414

2415+
static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
2416+
{
2417+
struct tcmsg *tcm = nlmsg_data(cb->nlh);
2418+
struct net *net = sock_net(skb->sk);
2419+
struct net_device *dev;
2420+
int err;
2421+
2422+
if (nlmsg_len(cb->nlh) < sizeof(*tcm))
2423+
return 0;
2424+
2425+
dev = dev_get_by_index(net, tcm->tcm_ifindex);
2426+
if (!dev)
2427+
return 0;
2428+
2429+
err = __tc_dump_tclass(skb, cb, tcm, dev);
2430+
2431+
dev_put(dev);
2432+
2433+
return err;
2434+
}
2435+
23812436
#ifdef CONFIG_PROC_FS
23822437
static int psched_show(struct seq_file *seq, void *v)
23832438
{

0 commit comments

Comments
 (0)