1 #ifndef _NFT_BRIDGE_H_
2 #define _NFT_BRIDGE_H_
3
4 #include <netinet/in.h>
5 //#include <linux/netfilter_bridge/ebtables.h>
6 #include <linux/netfilter/x_tables.h>
7 #include <linux/netfilter/nf_tables.h>
8 #include <net/ethernet.h>
9 #include <libiptc/libxtc.h>
10
11 /* We use replace->flags, so we can't use the following values:
12 * 0x01 == OPT_COMMAND, 0x02 == OPT_TABLE, 0x100 == OPT_ZERO */
13 #define LIST_N 0x04
14 #define LIST_C 0x08
15 #define LIST_X 0x10
16 #define LIST_MAC2 0x20
17
18 extern unsigned char eb_mac_type_unicast[ETH_ALEN];
19 extern unsigned char eb_msk_type_unicast[ETH_ALEN];
20 extern unsigned char eb_mac_type_multicast[ETH_ALEN];
21 extern unsigned char eb_msk_type_multicast[ETH_ALEN];
22 extern unsigned char eb_mac_type_broadcast[ETH_ALEN];
23 extern unsigned char eb_msk_type_broadcast[ETH_ALEN];
24 extern unsigned char eb_mac_type_bridge_group[ETH_ALEN];
25 extern unsigned char eb_msk_type_bridge_group[ETH_ALEN];
26
27 int ebt_get_mac_and_mask(const char *from, unsigned char *to, unsigned char *mask);
28
29 /* From: include/linux/netfilter_bridge/ebtables.h
30 *
31 * Adapted for the need of the ebtables-compat.
32 */
33
34 #define EBT_TABLE_MAXNAMELEN 32
35 #define EBT_FUNCTION_MAXNAMELEN EBT_TABLE_MAXNAMELEN
36
37 /* verdicts >0 are "branches" */
38 #define EBT_ACCEPT -1
39 #define EBT_DROP -2
40 #define EBT_CONTINUE -3
41 #define EBT_RETURN -4
42 #define NUM_STANDARD_TARGETS 4
43
44 #define EBT_ENTRY_OR_ENTRIES 0x01
45 /* these are the normal masks */
46 #define EBT_NOPROTO 0x02
47 #define EBT_802_3 0x04
48 #define EBT_SOURCEMAC 0x08
49 #define EBT_DESTMAC 0x10
50 #define EBT_F_MASK (EBT_NOPROTO | EBT_802_3 | EBT_SOURCEMAC | EBT_DESTMAC \
51 | EBT_ENTRY_OR_ENTRIES)
52
53 #define EBT_IPROTO 0x01
54 #define EBT_IIN 0x02
55 #define EBT_IOUT 0x04
56 #define EBT_ISOURCE 0x8
57 #define EBT_IDEST 0x10
58 #define EBT_ILOGICALIN 0x20
59 #define EBT_ILOGICALOUT 0x40
60 #define EBT_INV_MASK (EBT_IPROTO | EBT_IIN | EBT_IOUT | EBT_ILOGICALIN \
61 | EBT_ILOGICALOUT | EBT_ISOURCE | EBT_IDEST)
62
63 /* ebtables target modules store the verdict inside an int. We can
64 * reclaim a part of this int for backwards compatible extensions.
65 * The 4 lsb are more than enough to store the verdict.
66 */
67 #define EBT_VERDICT_BITS 0x0000000F
68
69 struct nftnl_rule;
70 struct iptables_command_state;
71
72 static const char *ebt_standard_targets[NUM_STANDARD_TARGETS] = {
73 "ACCEPT",
74 "DROP",
75 "CONTINUE",
76 "RETURN",
77 };
78
nft_ebt_standard_target(unsigned int num)79 static inline const char *nft_ebt_standard_target(unsigned int num)
80 {
81 if (num >= NUM_STANDARD_TARGETS)
82 return NULL;
83
84 return ebt_standard_targets[num];
85 }
86
ebt_fill_target(const char * str,unsigned int * verdict)87 static inline int ebt_fill_target(const char *str, unsigned int *verdict)
88 {
89 int i, ret = 0;
90
91 for (i = 0; i < NUM_STANDARD_TARGETS; i++) {
92 if (!strcmp(str, nft_ebt_standard_target(i))) {
93 *verdict = -i - 1;
94 break;
95 }
96 }
97
98 if (i == NUM_STANDARD_TARGETS)
99 ret = 1;
100
101 return ret;
102 }
103
ebt_target_name(unsigned int verdict)104 static inline const char *ebt_target_name(unsigned int verdict)
105 {
106 return nft_ebt_standard_target(-verdict - 1);
107 }
108
109 #define EBT_CHECK_OPTION(flags, mask) ({ \
110 if (*flags & mask) \
111 xtables_error(PARAMETER_PROBLEM, \
112 "Multiple use of same " \
113 "option not allowed"); \
114 *flags |= mask; \
115 }) \
116
117 void ebt_cs_clean(struct iptables_command_state *cs);
118 void ebt_load_match_extensions(void);
119 void ebt_add_match(struct xtables_match *m,
120 struct iptables_command_state *cs);
121 void ebt_add_watcher(struct xtables_target *watcher,
122 struct iptables_command_state *cs);
123 int ebt_command_default(struct iptables_command_state *cs);
124
125 struct nft_among_pair {
126 struct ether_addr ether;
127 struct in_addr in __attribute__((aligned (4)));
128 };
129
130 struct nft_among_data {
131 struct {
132 size_t cnt;
133 bool inv;
134 bool ip;
135 } src, dst;
136 /* first source, then dest pairs */
137 struct nft_among_pair pairs[0];
138 };
139
140 /* initialize fields, return offset into pairs array to write pairs to */
141 static inline size_t
nft_among_prepare_data(struct nft_among_data * data,bool dst,size_t cnt,bool inv,bool ip)142 nft_among_prepare_data(struct nft_among_data *data, bool dst,
143 size_t cnt, bool inv, bool ip)
144 {
145 size_t poff;
146
147 if (dst) {
148 data->dst.cnt = cnt;
149 data->dst.inv = inv;
150 data->dst.ip = ip;
151 poff = data->src.cnt;
152 } else {
153 data->src.cnt = cnt;
154 data->src.inv = inv;
155 data->src.ip = ip;
156 poff = 0;
157 memmove(data->pairs + cnt, data->pairs,
158 data->dst.cnt * sizeof(*data->pairs));
159 }
160 return poff;
161 }
162
163 static inline void
nft_among_insert_pair(struct nft_among_pair * pairs,size_t * pcount,const struct nft_among_pair * new)164 nft_among_insert_pair(struct nft_among_pair *pairs,
165 size_t *pcount, const struct nft_among_pair *new)
166 {
167 int i;
168
169 /* nftables automatically sorts set elements from smallest to largest,
170 * insert sorted so extension comparison works */
171
172 for (i = 0; i < *pcount; i++) {
173 if (memcmp(new, &pairs[i], sizeof(*new)) < 0)
174 break;
175 }
176 memmove(&pairs[i + 1], &pairs[i], sizeof(*pairs) * (*pcount - i));
177 memcpy(&pairs[i], new, sizeof(*new));
178 (*pcount)++;
179 }
180
181 #endif
182