summaryrefslogtreecommitdiffstats
path: root/tc/m_ematch.h
blob: c4443ee22942d38dad0ab72a943bbb895743f542 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __TC_EMATCH_H_
#define __TC_EMATCH_H_

#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

#include "utils.h"
#include "tc_util.h"

#define EMATCHKINDSIZ 16

struct bstr {
	char	*data;
	unsigned int	len;
	int		quoted;
	struct bstr	*next;
};

struct bstr *bstr_alloc(const char *text);

static inline struct bstr *bstr_new(char *data, unsigned int len)
{
	struct bstr *b = calloc(1, sizeof(*b));

	if (b == NULL)
		return NULL;

	b->data = data;
	b->len = len;

	return b;
}

static inline int bstrcmp(const struct bstr *b, const char *text)
{
	int len = strlen(text);
	int d = b->len - len;

	if (d == 0)
		return strncmp(b->data, text, len);

	return d;
}

static inline struct bstr *bstr_next(struct bstr *b)
{
	return b->next;
}

unsigned long bstrtoul(const struct bstr *b);

struct ematch {
	struct bstr	*args;
	int		index;
	int		inverted;
	int		relation;
	int		child_ref;
	struct ematch	*child;
	struct ematch	*next;
};

static inline struct ematch *new_ematch(struct bstr *args, int inverted)
{
	struct ematch *e = calloc(1, sizeof(*e));

	if (e == NULL)
		return NULL;

	e->args = args;
	e->inverted = inverted;

	return e;
}

void print_ematch_tree(const struct ematch *tree);

struct ematch_util {
	char			kind[EMATCHKINDSIZ];
	int			kind_num;
	int	(*parse_eopt)(struct nlmsghdr *, struct tcf_ematch_hdr *,
			      struct bstr *);
	int	(*parse_eopt_argv)(struct nlmsghdr *, struct tcf_ematch_hdr *,
				   int, char **);
	int	(*print_eopt)(FILE *, struct tcf_ematch_hdr *, void *, int);
	void	(*print_usage)(FILE *);
	struct ematch_util	*next;
};

static inline int parse_layer(const struct bstr *b)
{
	if (*((char *) b->data) == 'l')
		return TCF_LAYER_LINK;
	else if (*((char *) b->data) == 'n')
		return TCF_LAYER_NETWORK;
	else if (*((char *) b->data) == 't')
		return TCF_LAYER_TRANSPORT;
	else
		return INT_MAX;
}

__attribute__((format(printf, 5, 6)))
int em_parse_error(int err, struct bstr *args, struct bstr *carg,
		   struct ematch_util *, char *fmt, ...);
int print_ematch(FILE *, const struct rtattr *);
int parse_ematch(int *, char ***, int, struct nlmsghdr *);

#endif