diff --git a/include/types/filters.h b/include/types/filters.h index 62fcfb129..62b457de7 100644 --- a/include/types/filters.h +++ b/include/types/filters.h @@ -64,14 +64,32 @@ struct flt_kw_list { * number of errors encountered. * * + * - attach : Called after a filter instance creation, when it is + * attached to a stream. This happens when the stream + * is started for filters defined on the stream's + * frontend and when the backend is set for filters + * declared on the stream's backend. + * Returns a negative value if an error occurs, 0 if + * the filter must be ignored for the stream, any other + * value otherwise. * - stream_start : Called when a stream is started. This callback will - * only be called for filters defined on a proxy with - * the frontend capability. + * only be called for filters defined on the stream's + * frontend. + * Returns a negative value if an error occurs, any + * other value otherwise. + * - stream_set_backend : Called when a backend is set for a stream. This + * callbacks will be called for all filters attached + * to a stream (frontend and backend). * Returns a negative value if an error occurs, any * other value otherwise. * - stream_stop : Called when a stream is stopped. This callback will - * only be called for filters defined on a proxy with - * the frontend capability. + * only be called for filters defined on the stream's + * frontend. + * - detach : Called when a filter instance is detached from a + * stream, before its destruction. This happens when + * the stream is stopped for filters defined on the + * stream's frontend and when the analyze ends for + * filters defined on the stream's backend. * * * - channel_start_analyze: Called when a filter starts to analyze a channel. @@ -133,12 +151,14 @@ struct flt_ops { int (*init) (struct proxy *p, struct flt_conf *fconf); void (*deinit)(struct proxy *p, struct flt_conf *fconf); int (*check) (struct proxy *p, struct flt_conf *fconf); - /* * Stream callbacks */ - int (*stream_start) (struct stream *s, struct filter *f); - void (*stream_stop) (struct stream *s, struct filter *f); + int (*attach) (struct stream *s, struct filter *f); + int (*stream_start) (struct stream *s, struct filter *f); + int (*stream_set_backend)(struct stream *s, struct filter *f, struct proxy *be); + void (*stream_stop) (struct stream *s, struct filter *f); + void (*detach) (struct stream *s, struct filter *f); /* * Channel callbacks diff --git a/src/filters.c b/src/filters.c index 7f8fae43f..a1b36ba44 100644 --- a/src/filters.c +++ b/src/filters.c @@ -304,11 +304,21 @@ static int flt_stream_add_filter(struct stream *s, struct flt_conf *fconf, unsigned int flags) { struct filter *f = pool_alloc2(pool2_filter); + if (!f) /* not enough memory */ return -1; memset(f, 0, sizeof(*f)); f->config = fconf; f->flags |= flags; + + if (FLT_OPS(f)->attach) { + int ret = FLT_OPS(f)->attach(s, f); + if (ret <= 0) { + pool_free2(pool2_filter, f); + return ret; + } + } + LIST_ADDQ(&strm_flt(s)->filters, &f->list); strm_flt(s)->flags |= STRM_FLT_FL_HAS_FILTERS; return 0; @@ -345,6 +355,8 @@ flt_stream_release(struct stream *s, int only_backend) list_for_each_entry_safe(filter, back, &strm_flt(s)->filters, list) { if (!only_backend || (filter->flags & FLT_FL_IS_BACKEND_FILTER)) { + if (FLT_OPS(filter)->detach) + FLT_OPS(filter)->detach(s, filter); LIST_DEL(&filter->list); pool_free2(pool2_filter, filter); } @@ -387,21 +399,30 @@ flt_stream_stop(struct stream *s) /* * Called when a backend is set for a stream. If the frontend and the backend - * are the same, this function does nothing. Else it attaches all backend - * filters to the stream. Returns -1 if an error occurs, 0 otherwise. + * are not the same, this function attaches all backend filters to the + * stream. Returns -1 if an error occurs, 0 otherwise. */ int flt_set_stream_backend(struct stream *s, struct proxy *be) { struct flt_conf *fconf; + struct filter *filter; if (strm_fe(s) == be) - return 0; + goto end; list_for_each_entry(fconf, &be->filter_configs, list) { if (flt_stream_add_filter(s, fconf, FLT_FL_IS_BACKEND_FILTER) < 0) return -1; } + + end: + list_for_each_entry(filter, &strm_flt(s)->filters, list) { + if (FLT_OPS(filter)->stream_set_backend && + FLT_OPS(filter)->stream_set_backend(s, filter, be) < 0) + return -1; + } + return 0; } diff --git a/src/flt_trace.c b/src/flt_trace.c index a052ab59b..ce3bf5ccc 100644 --- a/src/flt_trace.c +++ b/src/flt_trace.c @@ -66,6 +66,12 @@ stream_pos(const struct stream *s) return (s->flags & SF_BE_ASSIGNED) ? "backend" : "frontend"; } +static const char * +filter_type(const struct filter *f) +{ + return (f->flags & FLT_FL_IS_BACKEND_FILTER) ? "backend" : "frontend"; +} + /*************************************************************************** * Hooks that manage the filter lifecycle (init/check/deinit) **************************************************************************/ @@ -111,6 +117,28 @@ trace_check(struct proxy *px, struct flt_conf *fconf) /************************************************************************** * Hooks to handle start/stop of streams *************************************************************************/ +/* Called when a filter instance is created and attach to a stream */ +static int +trace_attach(struct stream *s, struct filter *filter) +{ + struct trace_config *conf = FLT_CONF(filter); + + STRM_TRACE(conf, s, "%-25s: filter-type=%s", + __FUNCTION__, filter_type(filter)); + return 1; +} + +/* Called when a filter instance is detach from a stream, just before its + * destruction */ +static void +trace_detach(struct stream *s, struct filter *filter) +{ + struct trace_config *conf = FLT_CONF(filter); + + STRM_TRACE(conf, s, "%-25s: filter-type=%s", + __FUNCTION__, filter_type(filter)); +} + /* Called when a stream is created */ static int trace_stream_start(struct stream *s, struct filter *filter) @@ -122,6 +150,19 @@ trace_stream_start(struct stream *s, struct filter *filter) return 0; } + +/* Called when a backend is set for a stream */ +static int +trace_stream_set_backend(struct stream *s, struct filter *filter, + struct proxy *be) +{ + struct trace_config *conf = FLT_CONF(filter); + + STRM_TRACE(conf, s, "%-25s: backend=%s", + __FUNCTION__, be->id); + return 0; +} + /* Called when a stream is destroyed */ static void trace_stream_stop(struct stream *s, struct filter *filter) @@ -410,8 +451,11 @@ struct flt_ops trace_ops = { .check = trace_check, /* Handle start/stop of streams */ - .stream_start = trace_stream_start, - .stream_stop = trace_stream_stop, + .attach = trace_attach, + .detach = trace_detach, + .stream_start = trace_stream_start, + .stream_set_backend = trace_stream_set_backend, + .stream_stop = trace_stream_stop, /* Handle channels activity */ .channel_start_analyze = trace_chn_start_analyze,