@@ -255,6 +255,89 @@ nfnl_cthelper_create(const struct nlattr * const tb[],
255255 return ret ;
256256}
257257
258+ static int
259+ nfnl_cthelper_update_policy_one (const struct nf_conntrack_expect_policy * policy ,
260+ struct nf_conntrack_expect_policy * new_policy ,
261+ const struct nlattr * attr )
262+ {
263+ struct nlattr * tb [NFCTH_POLICY_MAX + 1 ];
264+ int err ;
265+
266+ err = nla_parse_nested (tb , NFCTH_POLICY_MAX , attr ,
267+ nfnl_cthelper_expect_pol );
268+ if (err < 0 )
269+ return err ;
270+
271+ if (!tb [NFCTH_POLICY_NAME ] ||
272+ !tb [NFCTH_POLICY_EXPECT_MAX ] ||
273+ !tb [NFCTH_POLICY_EXPECT_TIMEOUT ])
274+ return - EINVAL ;
275+
276+ if (nla_strcmp (tb [NFCTH_POLICY_NAME ], policy -> name ))
277+ return - EBUSY ;
278+
279+ new_policy -> max_expected =
280+ ntohl (nla_get_be32 (tb [NFCTH_POLICY_EXPECT_MAX ]));
281+ new_policy -> timeout =
282+ ntohl (nla_get_be32 (tb [NFCTH_POLICY_EXPECT_TIMEOUT ]));
283+
284+ return 0 ;
285+ }
286+
287+ static int nfnl_cthelper_update_policy_all (struct nlattr * tb [],
288+ struct nf_conntrack_helper * helper )
289+ {
290+ struct nf_conntrack_expect_policy new_policy [helper -> expect_class_max + 1 ];
291+ struct nf_conntrack_expect_policy * policy ;
292+ int i , err ;
293+
294+ /* Check first that all policy attributes are well-formed, so we don't
295+ * leave things in inconsistent state on errors.
296+ */
297+ for (i = 0 ; i < helper -> expect_class_max + 1 ; i ++ ) {
298+
299+ if (!tb [NFCTH_POLICY_SET + i ])
300+ return - EINVAL ;
301+
302+ err = nfnl_cthelper_update_policy_one (& helper -> expect_policy [i ],
303+ & new_policy [i ],
304+ tb [NFCTH_POLICY_SET + i ]);
305+ if (err < 0 )
306+ return err ;
307+ }
308+ /* Now we can safely update them. */
309+ for (i = 0 ; i < helper -> expect_class_max + 1 ; i ++ ) {
310+ policy = (struct nf_conntrack_expect_policy * )
311+ & helper -> expect_policy [i ];
312+ policy -> max_expected = new_policy -> max_expected ;
313+ policy -> timeout = new_policy -> timeout ;
314+ }
315+
316+ return 0 ;
317+ }
318+
319+ static int nfnl_cthelper_update_policy (struct nf_conntrack_helper * helper ,
320+ const struct nlattr * attr )
321+ {
322+ struct nlattr * tb [NFCTH_POLICY_SET_MAX + 1 ];
323+ unsigned int class_max ;
324+ int err ;
325+
326+ err = nla_parse_nested (tb , NFCTH_POLICY_SET_MAX , attr ,
327+ nfnl_cthelper_expect_policy_set );
328+ if (err < 0 )
329+ return err ;
330+
331+ if (!tb [NFCTH_POLICY_SET_NUM ])
332+ return - EINVAL ;
333+
334+ class_max = ntohl (nla_get_be32 (tb [NFCTH_POLICY_SET_NUM ]));
335+ if (helper -> expect_class_max + 1 != class_max )
336+ return - EBUSY ;
337+
338+ return nfnl_cthelper_update_policy_all (tb , helper );
339+ }
340+
258341static int
259342nfnl_cthelper_update (const struct nlattr * const tb [],
260343 struct nf_conntrack_helper * helper )
@@ -265,8 +348,7 @@ nfnl_cthelper_update(const struct nlattr * const tb[],
265348 return - EBUSY ;
266349
267350 if (tb [NFCTH_POLICY ]) {
268- ret = nfnl_cthelper_parse_expect_policy (helper ,
269- tb [NFCTH_POLICY ]);
351+ ret = nfnl_cthelper_update_policy (helper , tb [NFCTH_POLICY ]);
270352 if (ret < 0 )
271353 return ret ;
272354 }
0 commit comments