@@ -189,6 +189,9 @@ set_match_v1(const struct sk_buff *skb, struct xt_action_param *par)
189189 ADT_OPT (opt , par -> family , info -> match_set .dim ,
190190 info -> match_set .flags , 0 , UINT_MAX );
191191
192+ if (opt .flags & IPSET_RETURN_NOMATCH )
193+ opt .cmdflags |= IPSET_FLAG_RETURN_NOMATCH ;
194+
192195 return match_set (info -> match_set .index , skb , par , & opt ,
193196 info -> match_set .flags & IPSET_INV_MATCH );
194197}
@@ -317,6 +320,52 @@ set_target_v2(struct sk_buff *skb, const struct xt_action_param *par)
317320#define set_target_v2_checkentry set_target_v1_checkentry
318321#define set_target_v2_destroy set_target_v1_destroy
319322
323+ /* Revision 3 match */
324+
325+ static bool
326+ match_counter (u64 counter , const struct ip_set_counter_match * info )
327+ {
328+ switch (info -> op ) {
329+ case IPSET_COUNTER_NONE :
330+ return true;
331+ case IPSET_COUNTER_EQ :
332+ return counter == info -> value ;
333+ case IPSET_COUNTER_NE :
334+ return counter != info -> value ;
335+ case IPSET_COUNTER_LT :
336+ return counter < info -> value ;
337+ case IPSET_COUNTER_GT :
338+ return counter > info -> value ;
339+ }
340+ return false;
341+ }
342+
343+ static bool
344+ set_match_v3 (const struct sk_buff * skb , struct xt_action_param * par )
345+ {
346+ const struct xt_set_info_match_v3 * info = par -> matchinfo ;
347+ ADT_OPT (opt , par -> family , info -> match_set .dim ,
348+ info -> match_set .flags , info -> flags , UINT_MAX );
349+ int ret ;
350+
351+ if (info -> packets .op != IPSET_COUNTER_NONE ||
352+ info -> bytes .op != IPSET_COUNTER_NONE )
353+ opt .cmdflags |= IPSET_FLAG_MATCH_COUNTERS ;
354+
355+ ret = match_set (info -> match_set .index , skb , par , & opt ,
356+ info -> match_set .flags & IPSET_INV_MATCH );
357+
358+ if (!(ret && opt .cmdflags & IPSET_FLAG_MATCH_COUNTERS ))
359+ return ret ;
360+
361+ if (!match_counter (opt .ext .packets , & info -> packets ))
362+ return 0 ;
363+ return match_counter (opt .ext .bytes , & info -> bytes );
364+ }
365+
366+ #define set_match_v3_checkentry set_match_v1_checkentry
367+ #define set_match_v3_destroy set_match_v1_destroy
368+
320369static struct xt_match set_matches [] __read_mostly = {
321370 {
322371 .name = "set" ,
@@ -369,6 +418,27 @@ static struct xt_match set_matches[] __read_mostly = {
369418 .destroy = set_match_v1_destroy ,
370419 .me = THIS_MODULE
371420 },
421+ /* counters support: update, match */
422+ {
423+ .name = "set" ,
424+ .family = NFPROTO_IPV4 ,
425+ .revision = 3 ,
426+ .match = set_match_v3 ,
427+ .matchsize = sizeof (struct xt_set_info_match_v3 ),
428+ .checkentry = set_match_v3_checkentry ,
429+ .destroy = set_match_v3_destroy ,
430+ .me = THIS_MODULE
431+ },
432+ {
433+ .name = "set" ,
434+ .family = NFPROTO_IPV6 ,
435+ .revision = 3 ,
436+ .match = set_match_v3 ,
437+ .matchsize = sizeof (struct xt_set_info_match_v3 ),
438+ .checkentry = set_match_v3_checkentry ,
439+ .destroy = set_match_v3_destroy ,
440+ .me = THIS_MODULE
441+ },
372442};
373443
374444static struct xt_target set_targets [] __read_mostly = {
0 commit comments