@@ -2173,53 +2173,6 @@ static bool fl_needs_tc_skb_ext(const struct fl_flow_key *mask)
21732173 return mask -> meta .l2_miss ;
21742174}
21752175
2176- static int fl_set_parms (struct net * net , struct tcf_proto * tp ,
2177- struct cls_fl_filter * f , struct fl_flow_mask * mask ,
2178- unsigned long base , struct nlattr * * tb ,
2179- struct nlattr * est ,
2180- struct fl_flow_tmplt * tmplt ,
2181- u32 flags , u32 fl_flags ,
2182- struct netlink_ext_ack * extack )
2183- {
2184- int err ;
2185-
2186- err = tcf_exts_validate_ex (net , tp , tb , est , & f -> exts , flags ,
2187- fl_flags , extack );
2188- if (err < 0 )
2189- return err ;
2190-
2191- if (tb [TCA_FLOWER_CLASSID ]) {
2192- f -> res .classid = nla_get_u32 (tb [TCA_FLOWER_CLASSID ]);
2193- if (flags & TCA_ACT_FLAGS_NO_RTNL )
2194- rtnl_lock ();
2195- tcf_bind_filter (tp , & f -> res , base );
2196- if (flags & TCA_ACT_FLAGS_NO_RTNL )
2197- rtnl_unlock ();
2198- }
2199-
2200- err = fl_set_key (net , tb , & f -> key , & mask -> key , extack );
2201- if (err )
2202- return err ;
2203-
2204- fl_mask_update_range (mask );
2205- fl_set_masked_key (& f -> mkey , & f -> key , mask );
2206-
2207- if (!fl_mask_fits_tmplt (tmplt , mask )) {
2208- NL_SET_ERR_MSG_MOD (extack , "Mask does not fit the template" );
2209- return - EINVAL ;
2210- }
2211-
2212- /* Enable tc skb extension if filter matches on data extracted from
2213- * this extension.
2214- */
2215- if (fl_needs_tc_skb_ext (& mask -> key )) {
2216- f -> needs_tc_skb_ext = 1 ;
2217- tc_skb_ext_tc_enable ();
2218- }
2219-
2220- return 0 ;
2221- }
2222-
22232176static int fl_ht_insert_unique (struct cls_fl_filter * fnew ,
22242177 struct cls_fl_filter * fold ,
22252178 bool * in_ht )
@@ -2251,6 +2204,7 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
22512204 struct cls_fl_head * head = fl_head_dereference (tp );
22522205 bool rtnl_held = !(flags & TCA_ACT_FLAGS_NO_RTNL );
22532206 struct cls_fl_filter * fold = * arg ;
2207+ bool bound_to_filter = false;
22542208 struct cls_fl_filter * fnew ;
22552209 struct fl_flow_mask * mask ;
22562210 struct nlattr * * tb ;
@@ -2335,15 +2289,46 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
23352289 if (err < 0 )
23362290 goto errout_idr ;
23372291
2338- err = fl_set_parms (net , tp , fnew , mask , base , tb , tca [TCA_RATE ],
2339- tp -> chain -> tmplt_priv , flags , fnew -> flags ,
2340- extack );
2341- if (err )
2292+ err = tcf_exts_validate_ex (net , tp , tb , tca [TCA_RATE ],
2293+ & fnew -> exts , flags , fnew -> flags ,
2294+ extack );
2295+ if (err < 0 )
23422296 goto errout_idr ;
23432297
2298+ if (tb [TCA_FLOWER_CLASSID ]) {
2299+ fnew -> res .classid = nla_get_u32 (tb [TCA_FLOWER_CLASSID ]);
2300+ if (flags & TCA_ACT_FLAGS_NO_RTNL )
2301+ rtnl_lock ();
2302+ tcf_bind_filter (tp , & fnew -> res , base );
2303+ if (flags & TCA_ACT_FLAGS_NO_RTNL )
2304+ rtnl_unlock ();
2305+ bound_to_filter = true;
2306+ }
2307+
2308+ err = fl_set_key (net , tb , & fnew -> key , & mask -> key , extack );
2309+ if (err )
2310+ goto unbind_filter ;
2311+
2312+ fl_mask_update_range (mask );
2313+ fl_set_masked_key (& fnew -> mkey , & fnew -> key , mask );
2314+
2315+ if (!fl_mask_fits_tmplt (tp -> chain -> tmplt_priv , mask )) {
2316+ NL_SET_ERR_MSG_MOD (extack , "Mask does not fit the template" );
2317+ err = - EINVAL ;
2318+ goto unbind_filter ;
2319+ }
2320+
2321+ /* Enable tc skb extension if filter matches on data extracted from
2322+ * this extension.
2323+ */
2324+ if (fl_needs_tc_skb_ext (& mask -> key )) {
2325+ fnew -> needs_tc_skb_ext = 1 ;
2326+ tc_skb_ext_tc_enable ();
2327+ }
2328+
23442329 err = fl_check_assign_mask (head , fnew , fold , mask );
23452330 if (err )
2346- goto errout_idr ;
2331+ goto unbind_filter ;
23472332
23482333 err = fl_ht_insert_unique (fnew , fold , & in_ht );
23492334 if (err )
@@ -2434,6 +2419,16 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
24342419 fnew -> mask -> filter_ht_params );
24352420errout_mask :
24362421 fl_mask_put (head , fnew -> mask );
2422+
2423+ unbind_filter :
2424+ if (bound_to_filter ) {
2425+ if (flags & TCA_ACT_FLAGS_NO_RTNL )
2426+ rtnl_lock ();
2427+ tcf_unbind_filter (tp , & fnew -> res );
2428+ if (flags & TCA_ACT_FLAGS_NO_RTNL )
2429+ rtnl_unlock ();
2430+ }
2431+
24372432errout_idr :
24382433 if (!fold )
24392434 idr_remove (& head -> handle_idr , fnew -> handle );
0 commit comments