layer.h 3.52 KB
Newer Older
1
/*  Copyright (C) 2017 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#pragma once

#include "libknot/packet/pkt.h"
20
#include "libknot/mm_ctx.h"
21
#include "knot/nameserver/tsig_ctx.h"
22

23 24 25 26 27
/*!
 * \brief Layer processing states.
 *
 * Each state represents the state machine transition,
 * and determines readiness for the next action.
28
 */
29
typedef enum {
30 31 32
	KNOT_STATE_NOOP = 0,   //!< Invalid.
	KNOT_STATE_CONSUME,    //!< Consume data.
	KNOT_STATE_PRODUCE,    //!< Produce data.
33
	KNOT_STATE_RESET,      //!< Restart processing.
34 35
	KNOT_STATE_DONE,       //!< Finished.
	KNOT_STATE_FAIL        //!< Error.
36
} knot_layer_state_t;
37

38 39
typedef struct knot_layer_api knot_layer_api_t;

40
/*! \brief Packet processing context. */
41 42
typedef struct {
	const knot_layer_api_t *api;  //!< Layer API.
43
	knot_mm_t *mm;                //!< Processing memory context.
44
	knot_layer_state_t state;     //!< Processing state.
45
	void *data;                   //!< Module specific.
46
	tsig_ctx_t *tsig;             //!< TODO: remove
47
	unsigned flags;               //!< Custom flags.
48
} knot_layer_t;
49 50

/*! \brief Packet processing module API. */
51
struct knot_layer_api {
52
	int (*begin)(knot_layer_t *ctx, void *params);
53 54
	int (*reset)(knot_layer_t *ctx);
	int (*finish)(knot_layer_t *ctx);
55 56
	int (*consume)(knot_layer_t *ctx, knot_pkt_t *pkt);
	int (*produce)(knot_layer_t *ctx, knot_pkt_t *pkt);
57
};
58

59 60 61 62 63 64 65
/*! \brief Helper for conditional layer call. */
#define LAYER_CALL(layer, func, ...) \
	assert(layer->api); \
	if (layer->api->func) { \
		layer->state = layer->api->func(layer, ##__VA_ARGS__); \
	}

66 67 68
/*!
 * \brief Initialize packet processing context.
 *
69
 * \param ctx Layer context.
70
 * \param mm  Memory context.
71
 * \param api Layer API.
72
 */
73 74 75 76 77 78 79 80 81
inline static void knot_layer_init(knot_layer_t *ctx, knot_mm_t *mm,
                                   const knot_layer_api_t *api)
{
	memset(ctx, 0, sizeof(*ctx));

	ctx->mm = mm;
	ctx->api = api;
	ctx->state = KNOT_STATE_NOOP;
}
82 83 84 85 86

/*!
 * \brief Prepare packet processing.
 *
 * \param ctx Layer context.
87
 * \param params Initialization params.
88
 */
89 90 91 92
inline static void knot_layer_begin(knot_layer_t *ctx, void *params)
{
	LAYER_CALL(ctx, begin, params);
}
93 94 95

/*!
 * \brief Reset current packet processing context.
96 97
 *
 * \param ctx Layer context.
98
 */
99 100 101 102
inline static void knot_layer_reset(knot_layer_t *ctx)
{
	LAYER_CALL(ctx, reset);
}
103 104 105 106

/*!
 * \brief Finish and close packet processing context.
 *
107
 * \param ctx Layer context.
108
 */
109 110 111 112
inline static void knot_layer_finish(knot_layer_t *ctx)
{
	LAYER_CALL(ctx, finish);
}
113 114 115 116 117 118 119

/*!
 * \brief Add more data to layer processing.
 *
 * \param ctx Layer context.
 * \param pkt Data packet.
 */
120 121 122 123
inline static void knot_layer_consume(knot_layer_t *ctx, knot_pkt_t *pkt)
{
	LAYER_CALL(ctx, consume, pkt);
}
124 125 126 127 128 129 130

/*!
 * \brief Generate output from layer.
 *
 * \param ctx Layer context.
 * \param pkt Data packet.
 */
131 132 133 134
inline static void knot_layer_produce(knot_layer_t *ctx, knot_pkt_t *pkt)
{
	LAYER_CALL(ctx, produce, pkt);
}