@@ -2173,53 +2173,6 @@ static bool fl_needs_tc_skb_ext(const struct fl_flow_key *mask)
2173
2173
return mask -> meta .l2_miss ;
2174
2174
}
2175
2175
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
-
2223
2176
static int fl_ht_insert_unique (struct cls_fl_filter * fnew ,
2224
2177
struct cls_fl_filter * fold ,
2225
2178
bool * in_ht )
@@ -2251,6 +2204,7 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
2251
2204
struct cls_fl_head * head = fl_head_dereference (tp );
2252
2205
bool rtnl_held = !(flags & TCA_ACT_FLAGS_NO_RTNL );
2253
2206
struct cls_fl_filter * fold = * arg ;
2207
+ bool bound_to_filter = false;
2254
2208
struct cls_fl_filter * fnew ;
2255
2209
struct fl_flow_mask * mask ;
2256
2210
struct nlattr * * tb ;
@@ -2335,15 +2289,46 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
2335
2289
if (err < 0 )
2336
2290
goto errout_idr ;
2337
2291
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 )
2342
2296
goto errout_idr ;
2343
2297
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
+
2344
2329
err = fl_check_assign_mask (head , fnew , fold , mask );
2345
2330
if (err )
2346
- goto errout_idr ;
2331
+ goto unbind_filter ;
2347
2332
2348
2333
err = fl_ht_insert_unique (fnew , fold , & in_ht );
2349
2334
if (err )
@@ -2434,6 +2419,16 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
2434
2419
fnew -> mask -> filter_ht_params );
2435
2420
errout_mask :
2436
2421
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
+
2437
2432
errout_idr :
2438
2433
if (!fold )
2439
2434
idr_remove (& head -> handle_idr , fnew -> handle );
0 commit comments