Line data Source code
1 : /*
2 : * BGP pbr
3 : * Copyright (C) 6WIND
4 : *
5 : * FRR is free software; you can redistribute it and/or modify it
6 : * under the terms of the GNU General Public License as published by the
7 : * Free Software Foundation; either version 2, or (at your option) any
8 : * later version.
9 : *
10 : * FRR is distributed in the hope that it will be useful, but
11 : * WITHOUT ANY WARRANTY; without even the implied warranty of
12 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 : * General Public License for more details.
14 : *
15 : * You should have received a copy of the GNU General Public License along
16 : * with this program; see the file COPYING; if not, write to the Free Software
17 : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 : */
19 : #ifndef __BGP_PBR_H__
20 : #define __BGP_PBR_H__
21 :
22 : #include "nexthop.h"
23 : #include "zclient.h"
24 :
25 : /* flowspec case: 0 to 3 actions maximum:
26 : * 1 redirect
27 : * 1 set dscp
28 : * 1 set traffic rate
29 : */
30 : #define ACTIONS_MAX_NUM 4
31 : enum bgp_pbr_action_enum {
32 : ACTION_TRAFFICRATE = 1,
33 : ACTION_TRAFFIC_ACTION = 2,
34 : ACTION_REDIRECT = 3,
35 : ACTION_MARKING = 4,
36 : ACTION_REDIRECT_IP = 5
37 : };
38 :
39 : #define TRAFFIC_ACTION_SAMPLE (1 << 0)
40 : #define TRAFFIC_ACTION_TERMINATE (1 << 1)
41 : #define TRAFFIC_ACTION_DISTRIBUTE (1 << 2)
42 :
43 : #define OPERATOR_COMPARE_LESS_THAN (1<<1)
44 : #define OPERATOR_COMPARE_GREATER_THAN (1<<2)
45 : #define OPERATOR_COMPARE_EQUAL_TO (1<<3)
46 : #define OPERATOR_COMPARE_EXACT_MATCH (1<<4)
47 :
48 : #define OPERATOR_UNARY_OR (1<<1)
49 : #define OPERATOR_UNARY_AND (1<<2)
50 :
51 : /* struct used to store values [0;65535]
52 : * this can be used for port number of protocol
53 : */
54 : #define BGP_PBR_MATCH_VAL_MAX 5
55 :
56 : struct bgp_pbr_match_val {
57 : uint16_t value;
58 : uint8_t compare_operator;
59 : uint8_t unary_operator;
60 : };
61 :
62 : #define FRAGMENT_DONT 1
63 : #define FRAGMENT_IS 2
64 : #define FRAGMENT_FIRST 4
65 : #define FRAGMENT_LAST 8
66 :
67 : struct bgp_pbr_entry_action {
68 : /* used to store enum bgp_pbr_action_enum enumerate */
69 : uint8_t action;
70 : union {
71 : union {
72 : uint8_t rate_info[4]; /* IEEE.754.1985 */
73 : float rate;
74 : } r __attribute__((aligned(8)));
75 : struct _pbr_action {
76 : uint8_t do_sample;
77 : uint8_t filter;
78 : } za;
79 : vrf_id_t redirect_vrf;
80 : struct _pbr_redirect_ip {
81 : struct in_addr redirect_ip_v4;
82 : struct in6_addr redirect_ip_v6;
83 : uint8_t duplicate;
84 : } zr;
85 : uint8_t marking_dscp;
86 : } u __attribute__((aligned(8)));
87 : };
88 :
89 : /* BGP Policy Route structure */
90 : struct bgp_pbr_entry_main {
91 : #define BGP_PBR_UNDEFINED 0
92 : #define BGP_PBR_IPSET 1
93 : #define BGP_PBR_IPRULE 2
94 : uint8_t type;
95 :
96 : /*
97 : * This is an enum but we are going to treat it as a uint8_t
98 : * for purpose of encoding/decoding
99 : */
100 : afi_t afi;
101 : safi_t safi;
102 :
103 : #define PREFIX_SRC_PRESENT (1 << 0)
104 : #define PREFIX_DST_PRESENT (1 << 1)
105 : uint8_t match_bitmask_iprule;
106 : uint8_t match_bitmask;
107 :
108 : uint8_t match_src_port_num;
109 : uint8_t match_dst_port_num;
110 : uint8_t match_port_num;
111 : uint8_t match_protocol_num;
112 : uint8_t match_icmp_type_num;
113 : uint8_t match_icmp_code_num;
114 : uint8_t match_packet_length_num;
115 : uint8_t match_dscp_num;
116 : uint8_t match_tcpflags_num;
117 : uint8_t match_fragment_num;
118 : uint8_t match_flowlabel_num;
119 :
120 : struct prefix src_prefix;
121 : struct prefix dst_prefix;
122 : uint8_t src_prefix_offset;
123 : uint8_t dst_prefix_offset;
124 :
125 : #define PROTOCOL_UDP 17
126 : #define PROTOCOL_TCP 6
127 : #define PROTOCOL_ICMP 1
128 : #define PROTOCOL_ICMPV6 58
129 : struct bgp_pbr_match_val protocol[BGP_PBR_MATCH_VAL_MAX];
130 : struct bgp_pbr_match_val src_port[BGP_PBR_MATCH_VAL_MAX];
131 : struct bgp_pbr_match_val dst_port[BGP_PBR_MATCH_VAL_MAX];
132 : struct bgp_pbr_match_val port[BGP_PBR_MATCH_VAL_MAX];
133 : struct bgp_pbr_match_val icmp_type[BGP_PBR_MATCH_VAL_MAX];
134 : struct bgp_pbr_match_val icmp_code[BGP_PBR_MATCH_VAL_MAX];
135 : struct bgp_pbr_match_val packet_length[BGP_PBR_MATCH_VAL_MAX];
136 : struct bgp_pbr_match_val dscp[BGP_PBR_MATCH_VAL_MAX];
137 : struct bgp_pbr_match_val flow_label[BGP_PBR_MATCH_VAL_MAX];
138 :
139 : struct bgp_pbr_match_val tcpflags[BGP_PBR_MATCH_VAL_MAX];
140 : struct bgp_pbr_match_val fragment[BGP_PBR_MATCH_VAL_MAX];
141 :
142 : uint16_t action_num;
143 : struct bgp_pbr_entry_action actions[ACTIONS_MAX_NUM];
144 :
145 : vrf_id_t vrf_id;
146 : };
147 :
148 : struct bgp_pbr_interface {
149 : RB_ENTRY(bgp_pbr_interface) id_entry;
150 : char name[INTERFACE_NAMSIZ];
151 : };
152 :
153 : RB_HEAD(bgp_pbr_interface_head, bgp_pbr_interface);
154 24 : RB_PROTOTYPE(bgp_pbr_interface_head, bgp_pbr_interface, id_entry,
155 : bgp_pbr_interface_compare);
156 :
157 : extern int bgp_pbr_interface_compare(const struct bgp_pbr_interface *a,
158 : const struct bgp_pbr_interface *b);
159 :
160 : struct bgp_pbr_config {
161 : struct bgp_pbr_interface_head ifaces_by_name_ipv4;
162 : bool pbr_interface_any_ipv4;
163 : struct bgp_pbr_interface_head ifaces_by_name_ipv6;
164 : bool pbr_interface_any_ipv6;
165 : };
166 :
167 : extern struct bgp_pbr_config *bgp_pbr_cfg;
168 :
169 : struct bgp_pbr_rule {
170 : uint32_t flags;
171 : struct prefix src;
172 : struct prefix dst;
173 : struct bgp_pbr_action *action;
174 : vrf_id_t vrf_id;
175 : uint32_t unique;
176 : uint32_t priority;
177 : bool installed;
178 : bool install_in_progress;
179 : void *path;
180 : };
181 :
182 : struct bgp_pbr_match {
183 : char ipset_name[ZEBRA_IPSET_NAME_SIZE];
184 :
185 : /* mapped on enum ipset_type
186 : */
187 : uint32_t type;
188 :
189 : uint32_t flags;
190 : uint8_t family;
191 :
192 : uint16_t pkt_len_min;
193 : uint16_t pkt_len_max;
194 : uint16_t tcp_flags;
195 : uint16_t tcp_mask_flags;
196 : uint8_t dscp_value;
197 : uint8_t fragment;
198 : uint8_t protocol;
199 : uint16_t flow_label;
200 :
201 : vrf_id_t vrf_id;
202 :
203 : /* unique identifier for ipset create transaction
204 : */
205 : uint32_t unique;
206 :
207 : /* unique identifier for iptable add transaction
208 : */
209 : uint32_t unique2;
210 :
211 : bool installed;
212 : bool install_in_progress;
213 :
214 : bool installed_in_iptable;
215 : bool install_iptable_in_progress;
216 :
217 : struct hash *entry_hash;
218 :
219 : struct bgp_pbr_action *action;
220 :
221 : };
222 :
223 : struct bgp_pbr_match_entry {
224 : struct bgp_pbr_match *backpointer;
225 :
226 : uint32_t unique;
227 :
228 : struct prefix src;
229 : struct prefix dst;
230 :
231 : uint16_t src_port_min;
232 : uint16_t src_port_max;
233 : uint16_t dst_port_min;
234 : uint16_t dst_port_max;
235 : uint8_t proto;
236 :
237 : void *path;
238 :
239 : bool installed;
240 : bool install_in_progress;
241 : };
242 :
243 : struct bgp_pbr_action {
244 :
245 : /*
246 : * The Unique identifier of this specific pbrms
247 : */
248 : uint32_t unique;
249 :
250 : uint32_t fwmark;
251 :
252 : uint32_t table_id;
253 :
254 : float rate;
255 :
256 : /*
257 : * nexthop information, or drop information
258 : * contains src vrf_id and nh contains dest vrf_id
259 : */
260 : vrf_id_t vrf_id;
261 : struct nexthop nh;
262 :
263 : bool installed;
264 : bool install_in_progress;
265 : uint32_t refcnt;
266 : struct bgp *bgp;
267 : afi_t afi;
268 : };
269 :
270 : extern struct bgp_pbr_rule *bgp_pbr_rule_lookup(vrf_id_t vrf_id,
271 : uint32_t unique);
272 :
273 : extern struct bgp_pbr_action *bgp_pbr_action_rule_lookup(vrf_id_t vrf_id,
274 : uint32_t unique);
275 :
276 : extern struct bgp_pbr_match *bgp_pbr_match_ipset_lookup(vrf_id_t vrf_id,
277 : uint32_t unique);
278 :
279 : extern struct bgp_pbr_match_entry *bgp_pbr_match_ipset_entry_lookup(
280 : vrf_id_t vrf_id, char *name,
281 : uint32_t unique);
282 : extern struct bgp_pbr_match *bgp_pbr_match_iptable_lookup(vrf_id_t vrf_id,
283 : uint32_t unique);
284 :
285 : extern void bgp_pbr_cleanup(struct bgp *bgp);
286 : extern void bgp_pbr_init(struct bgp *bgp);
287 :
288 : extern uint32_t bgp_pbr_rule_hash_key(const void *arg);
289 : extern bool bgp_pbr_rule_hash_equal(const void *arg1,
290 : const void *arg2);
291 : extern uint32_t bgp_pbr_action_hash_key(const void *arg);
292 : extern bool bgp_pbr_action_hash_equal(const void *arg1,
293 : const void *arg2);
294 : extern uint32_t bgp_pbr_match_entry_hash_key(const void *arg);
295 : extern bool bgp_pbr_match_entry_hash_equal(const void *arg1,
296 : const void *arg2);
297 : extern uint32_t bgp_pbr_match_hash_key(const void *arg);
298 : extern bool bgp_pbr_match_hash_equal(const void *arg1,
299 : const void *arg2);
300 :
301 : void bgp_pbr_print_policy_route(struct bgp_pbr_entry_main *api);
302 :
303 : struct bgp_path_info;
304 : extern void bgp_pbr_update_entry(struct bgp *bgp, const struct prefix *p,
305 : struct bgp_path_info *new_select, afi_t afi,
306 : safi_t safi, bool nlri_update);
307 :
308 : /* bgp pbr utilities */
309 : extern struct bgp_pbr_interface *pbr_interface_lookup(const char *name);
310 : extern void bgp_pbr_reset(struct bgp *bgp, afi_t afi);
311 : extern struct bgp_pbr_interface *bgp_pbr_interface_lookup(const char *name,
312 : struct bgp_pbr_interface_head *head);
313 :
314 : extern int bgp_pbr_build_and_validate_entry(const struct prefix *p,
315 : struct bgp_path_info *path,
316 : struct bgp_pbr_entry_main *api);
317 : #endif /* __BGP_PBR_H__ */
|