@@ -129,7 +129,8 @@ static inline u32 tcf_auto_prio(struct tcf_proto *tp)
129129}
130130
131131static struct tcf_proto * tcf_proto_create (const char * kind , u32 protocol ,
132- u32 prio , u32 parent , struct Qdisc * q )
132+ u32 prio , u32 parent , struct Qdisc * q ,
133+ struct tcf_block * block )
133134{
134135 struct tcf_proto * tp ;
135136 int err ;
@@ -165,6 +166,7 @@ static struct tcf_proto *tcf_proto_create(const char *kind, u32 protocol,
165166 tp -> prio = prio ;
166167 tp -> classid = parent ;
167168 tp -> q = q ;
169+ tp -> block = block ;
168170
169171 err = tp -> ops -> init (tp );
170172 if (err ) {
@@ -185,7 +187,7 @@ static void tcf_proto_destroy(struct tcf_proto *tp)
185187 kfree_rcu (tp , rcu );
186188}
187189
188- void tcf_destroy_chain (struct tcf_proto __rcu * * fl )
190+ static void tcf_destroy_chain (struct tcf_proto __rcu * * fl )
189191{
190192 struct tcf_proto * tp ;
191193
@@ -194,7 +196,28 @@ void tcf_destroy_chain(struct tcf_proto __rcu **fl)
194196 tcf_proto_destroy (tp );
195197 }
196198}
197- EXPORT_SYMBOL (tcf_destroy_chain );
199+
200+ int tcf_block_get (struct tcf_block * * p_block ,
201+ struct tcf_proto __rcu * * p_filter_chain )
202+ {
203+ struct tcf_block * block = kzalloc (sizeof (* block ), GFP_KERNEL );
204+
205+ if (!block )
206+ return - ENOMEM ;
207+ block -> p_filter_chain = p_filter_chain ;
208+ * p_block = block ;
209+ return 0 ;
210+ }
211+ EXPORT_SYMBOL (tcf_block_get );
212+
213+ void tcf_block_put (struct tcf_block * block )
214+ {
215+ if (!block )
216+ return ;
217+ tcf_destroy_chain (block -> p_filter_chain );
218+ kfree (block );
219+ }
220+ EXPORT_SYMBOL (tcf_block_put );
198221
199222/* Main classifier routine: scans classifier chain attached
200223 * to this qdisc, (optionally) tests for protocol and asks
@@ -260,6 +283,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
260283 struct Qdisc * q ;
261284 struct tcf_proto __rcu * * back ;
262285 struct tcf_proto __rcu * * chain ;
286+ struct tcf_block * block ;
263287 struct tcf_proto * next ;
264288 struct tcf_proto * tp ;
265289 const struct Qdisc_class_ops * cops ;
@@ -328,7 +352,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
328352 if (!cops )
329353 return - EINVAL ;
330354
331- if (cops -> tcf_chain == NULL )
355+ if (! cops -> tcf_block )
332356 return - EOPNOTSUPP ;
333357
334358 /* Do we search for filter, attached to class? */
@@ -339,11 +363,13 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
339363 }
340364
341365 /* And the last stroke */
342- chain = cops -> tcf_chain (q , cl );
343- if (chain == NULL ) {
366+ block = cops -> tcf_block (q , cl );
367+ if (! block ) {
344368 err = - EINVAL ;
345369 goto errout ;
346370 }
371+ chain = block -> p_filter_chain ;
372+
347373 if (n -> nlmsg_type == RTM_DELTFILTER && prio == 0 ) {
348374 tfilter_notify_chain (net , skb , n , chain , RTM_DELTFILTER );
349375 tcf_destroy_chain (chain );
@@ -387,7 +413,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n,
387413 nprio = TC_H_MAJ (tcf_auto_prio (rtnl_dereference (* back )));
388414
389415 tp = tcf_proto_create (nla_data (tca [TCA_KIND ]),
390- protocol , nprio , parent , q );
416+ protocol , nprio , parent , q , block );
391417 if (IS_ERR (tp )) {
392418 err = PTR_ERR (tp );
393419 goto errout ;
@@ -556,6 +582,7 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
556582 int s_t ;
557583 struct net_device * dev ;
558584 struct Qdisc * q ;
585+ struct tcf_block * block ;
559586 struct tcf_proto * tp , __rcu * * chain ;
560587 struct tcmsg * tcm = nlmsg_data (cb -> nlh );
561588 unsigned long cl = 0 ;
@@ -577,16 +604,17 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
577604 cops = q -> ops -> cl_ops ;
578605 if (!cops )
579606 goto errout ;
580- if (cops -> tcf_chain == NULL )
607+ if (! cops -> tcf_block )
581608 goto errout ;
582609 if (TC_H_MIN (tcm -> tcm_parent )) {
583610 cl = cops -> get (q , tcm -> tcm_parent );
584611 if (cl == 0 )
585612 goto errout ;
586613 }
587- chain = cops -> tcf_chain (q , cl );
588- if (chain == NULL )
614+ block = cops -> tcf_block (q , cl );
615+ if (! block )
589616 goto errout ;
617+ chain = block -> p_filter_chain ;
590618
591619 s_t = cb -> args [0 ];
592620
0 commit comments