@@ -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+
15851597static 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
17611757create_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+
18071838static 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+
22712314struct 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)
23742409done :
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
23822437static int psched_show (struct seq_file * seq , void * v )
23832438{
0 commit comments