From: Christopher Faulet Date: Mon, 26 Oct 2026 09:41:57 +0000 (+0100) Subject: MINOR: filters: Set the class flags on filter class registration X-Git-Tag: v3.5-dev10~40 X-Git-Url: https://git.kaiwu.me/$%7BGITURL%7D$%7Bcid%7D?a=commitdiff_plain;h=23591a429e671eef4c1da802a2d78c899b2722fa;p=haproxy.git MINOR: filters: Set the class flags on filter class registration The classes registered with filter_register_class() or filter_register_class_full() could not set their flags, in particular FLT_CLS_FL_MULTI: the flags passed to flt_init_class() were always 0, so a class of an external module was always limited to a single instance per proxy, even with an id. filter_register_class() and filter_register_class_full() now take a 'flags' argument, passed to flt_init_class() as for the internal classes. The class flags are the FLT_CLS_FL_* flags, only FLT_CLS_FL_MULTI for now, set when several instances of the class are allowed in the same proxy. The filters documentation is updated accordingly, in the class registration section and in the filter instance mode conversion guide. The example in the comment of filter_init_classes() is updated too. --- diff --git a/doc/internals/api/filters.txt b/doc/internals/api/filters.txt index a4aed16f0..7c384f8e6 100644 --- a/doc/internals/api/filters.txt +++ b/doc/internals/api/filters.txt @@ -536,7 +536,9 @@ The filter class is described by the following structure : now, only FLT_CLS_FL_MULTI may be set when several instances of the class are allowed in the same proxy. In this case, an id is mandatory for each instance. Otherwise a second instance of the class in the same proxy is - rejected, even with a different id. + rejected, even with a different id. The flags are set by the 'flags' + argument of filter_register_class() when the class is registered, they + cannot be set directly in the structure. * 'filter_class.parse' is the callback parsing a filter instance (see section 3.2.1). It may be NULL, but in this case the class cannot be used @@ -555,7 +557,8 @@ it supports, relative to an already placed class, with filter_place_class() : static int my_filter_register_class(void) { - if (filter_register_class(&flt_my_filter_cls, "my-filter", my_filter_parse_instance) < 0) + if (filter_register_class(&flt_my_filter_cls, "my-filter", FLT_CLS_FL_MULTI, + my_filter_parse_instance) < 0) return -1; /* Evaluate the filter before cache-store globally, before SPOE on the @@ -589,7 +592,8 @@ and FLT_SIDE_RES, and may be called once per side : filter_register_class_full() is a helper for the common case where the class is placed at the same position relative to the same class, on the global side and -on both channel sides. +on both channel sides. It takes the same class flags as +filter_register_class(). A class placed on neither the request nor the response side is rejected at startup because it would be useless. The placements define the default @@ -1760,6 +1764,7 @@ are left untouched. /* Evaluate the filter before SPOE on the request path and after the * Lua filters on the response path. */ if (filter_register_class(&flt_my_filter_cls, "my-filter", + FLT_CLS_FL_MULTI, my_filter_parse_instance) < 0) return -1; if (filter_place_class(&flt_my_filter_cls, FLT_SIDE_REQ, @@ -1809,12 +1814,12 @@ enabled by another directive, or is referenced by other directives. filter. If dynamically allocated, 'fconf->id' must be freed by 'flt_ops.deinit', as HAProxy never frees or duplicates it. - * Allow several instances of the class. Set FLT_CLS_FL_MULTI in the class - flags to allow several instances of the class in the same proxy, each - one with an id. Without this flag, a second instance of the class in the - same proxy is rejected, even with a different id. With the flag, an id - is mandatory for each instance. Use flt_find_instance() to find an - instance by class and id. + * Allow several instances of the class. Pass FLT_CLS_FL_MULTI in the flags + argument of filter_register_class() to allow several instances of the + class in the same proxy, each one with an id. Without this flag, a second + instance of the class in the same proxy is rejected, even with a different + id. With the flag, an id is mandatory for each instance. Use + flt_find_instance() to find an instance by class and id. * Declare an implicit instance when the filter is enabled by another directive. If the filter can be enabled by another directive, for diff --git a/include/haproxy/filters.h b/include/haproxy/filters.h index 2ca8a5111..8aaf1f206 100644 --- a/include/haproxy/filters.h +++ b/include/haproxy/filters.h @@ -355,11 +355,13 @@ int flt_parse_instance_legacy(struct proxy *px, struct filter_instance *inst, ch void *private); int filter_register_class(struct filter_class *cls, const char *name, + unsigned int flags, int (*parse)(char **args, struct proxy *px, struct filter_instance *inst, char **err)); int filter_place_class(struct filter_class *cls, unsigned int side, const char *ref_name, enum flt_pos pos); int filter_register_class_full(struct filter_class *cls, const char *name, + unsigned int flags, int (*parse)(char **args, struct proxy *px, struct filter_instance *inst, char **err), const char *ref_name, enum flt_pos pos); diff --git a/src/filters.c b/src/filters.c index 0ef8c625e..f07039252 100644 --- a/src/filters.c +++ b/src/filters.c @@ -3755,16 +3755,18 @@ int flt_parse_instance_legacy(struct proxy *px, struct filter_instance *inst, ch /* Registers a new filter class, with the parsing function used to * finalize the filter instances of this class (may be NULL if the class does - * not support the "filter-config" directive). The class is initialized and - * added to the global registry of the known classes, and appended at the end - * of the global order. It is not usable on any channel side until placed with - * filter_place_class(). Must be called after filter_init_classes(), which - * runs at the prepare stage: a class registered from the register stage on - * is added in time for "haproxy -vv" to list it, a class registered later - * is reported by the CLI alone. + * not support the "filter-config" directive). The class is initialized with + * the class flags (FLT_CLS_FL_*) and added to the global registry of + * the known classes, and appended at the end of the global order. It is not + * usable on any channel side until placed with filter_place_class(). Must be + * called after filter_init_classes(), which runs at the prepare stage: a + * class registered from the register stage on is added in time for + * "haproxy -vv" to list it, a class registered later is reported by the CLI + * alone. * Returns 0 on success, -1 on error (too early call, duplicate name). */ int filter_register_class(struct filter_class *cls, const char *name, + unsigned int flags, int (*parse)(char **args, struct proxy *px, struct filter_instance *inst, char **err)) { @@ -3785,13 +3787,14 @@ int filter_register_class(struct filter_class *cls, const char *name, goto out; } - flt_init_class(cls, name, 0, parse); + flt_init_class(cls, name, flags, parse); LIST_APPEND(&filter_classes, &cls->list); LIST_APPEND(&global_filter_classes, &cls->global.list); ret = 0; out: return ret; } + /* Places in the order of (FLT_SIDE_GLOBAL, FLT_SIDE_REQ or * FLT_SIDE_RES), before or after the reference class . The class is * appended in the reference class' .before or .after constraint list of that @@ -3880,18 +3883,19 @@ static void flt_unplace_class(struct filter_class *cls) } } -/* Registers a new filter class named and places it on the global side - * and on both channel sides, before or after the reference class . - * Convenience function for the common symmetric case, equivalent to - * filter_register_class() followed by filter_place_class() on - * FLT_SIDE_GLOBAL, FLT_SIDE_REQ and FLT_SIDE_RES. +/* Registers a new filter class named with the class flags + * (FLT_CLS_FL_*) and places it on the global side and on both channel sides, + * before or after the reference class . Convenience function for + * the common symmetric case, equivalent to filter_register_class() followed + * by filter_place_class() on FLT_SIDE_GLOBAL, FLT_SIDE_REQ and FLT_SIDE_RES. * Returns 0 on success, -1 on error. */ int filter_register_class_full(struct filter_class *cls, const char *name, + unsigned int flags, int (*parse)(char **args, struct proxy *px, struct filter_instance *inst, char **err), const char *ref_name, enum flt_pos pos) { - if (filter_register_class(cls, name, parse) < 0) + if (filter_register_class(cls, name, flags, parse) < 0) goto err; if (filter_place_class(cls, FLT_SIDE_GLOBAL, ref_name, pos) < 0) goto cleanup_on_err; @@ -3924,7 +3928,7 @@ int filter_register_class_full(struct filter_class *cls, const char *name, * * static int myfilter_register_class(void) * { - * if (filter_register_class(&flt_myfilter_cls, "myfilter", myfilter_parse_def) < 0) + * if (filter_register_class(&flt_myfilter_cls, "myfilter", FLT_CLS_FL_MULTI, myfilter_parse_def) < 0) * return -1; * * // before spoe on request, after lua on response, before cache-store