]> git.ipfire.org Git - thirdparty/bird.git/blame - lib/flowspec.h
Renamed my past self in commit authorship and mentioned that in the contributing...
[thirdparty/bird.git] / lib / flowspec.h
CommitLineData
77234bbb
OZ
1/*
2 * BIRD Library -- Flow specification (RFC 5575)
3 *
4 * (c) 2016 CZ.NIC z.s.p.o.
5 *
6 * Can be freely distributed and used under the terms of the GNU GPL.
7 */
8
9#ifndef _BIRD_FLOWSPEC_H_
10#define _BIRD_FLOWSPEC_H_
11
12#include "nest/bird.h"
13#include "lib/buffer.h"
14#include "lib/net.h"
15
16
734e9fb8 17/* Flow component operators */
d114959e 18#define FLOW_OP_FALSE 0x00 /* 0b000 */
734e9fb8
OZ
19#define FLOW_OP_EQ 0x01 /* 0b001 */
20#define FLOW_OP_GT 0x02 /* 0b010 */
21#define FLOW_OP_GEQ 0x03 /* 0b011 */
22#define FLOW_OP_LT 0x04 /* 0b100 */
23#define FLOW_OP_LEQ 0x05 /* 0b101 */
24#define FLOW_OP_NEQ 0x06 /* 0b110 */
d114959e 25#define FLOW_OP_TRUE 0x07 /* 0b111 */
734e9fb8
OZ
26
27#define FLOW_OP_OR 0x00
28#define FLOW_OP_AND 0x40
29
30
77234bbb
OZ
31/* Types of components in flowspec */
32enum flow_type {
33 FLOW_TYPE_DST_PREFIX = 1,
34 FLOW_TYPE_SRC_PREFIX = 2,
35 FLOW_TYPE_IP_PROTOCOL = 3,
36 FLOW_TYPE_NEXT_HEADER = 3, /* IPv6 */
37 FLOW_TYPE_PORT = 4,
38 FLOW_TYPE_DST_PORT = 5,
39 FLOW_TYPE_SRC_PORT = 6,
40 FLOW_TYPE_ICMP_TYPE = 7,
41 FLOW_TYPE_ICMP_CODE = 8,
42 FLOW_TYPE_TCP_FLAGS = 9,
43 FLOW_TYPE_PACKET_LENGTH = 10,
44 FLOW_TYPE_DSCP = 11, /* DiffServ Code Point */
45 FLOW_TYPE_FRAGMENT = 12,
46 FLOW_TYPE_LABEL = 13, /* IPv6 */
47 FLOW_TYPE_MAX
48};
49
50const char *flow_type_str(enum flow_type type, int ipv6);
51
52
53/*
54 * Length
55 */
56
57uint flow_write_length(byte *data, u16 len);
58
ac3ad139
OZ
59static inline u16 flow_hdr_length(const byte *data)
60{ return ((*data & 0xf0) == 0xf0) ? 2 : 1; }
61
77234bbb
OZ
62static inline u16 flow_read_length(const byte *data)
63{ return ((*data & 0xf0) == 0xf0) ? get_u16(data) & 0x0fff : *data; }
64
65static inline u16 flow4_get_length(const net_addr_flow4 *f)
66{ return f->length - sizeof(net_addr_flow4); }
67
68static inline u16 flow6_get_length(const net_addr_flow6 *f)
69{ return f->length - sizeof(net_addr_flow6); }
70
71static inline void flow4_set_length(net_addr_flow4 *f, u16 len)
72{ f->length = sizeof(net_addr_flow4) + flow_write_length(f->data, len) + len; }
73
74static inline void flow6_set_length(net_addr_flow6 *f, u16 len)
75{ f->length = sizeof(net_addr_flow6) + flow_write_length(f->data, len) + len; }
76
77
78/*
79 * Iterators
80 */
81
82const byte *flow4_first_part(const net_addr_flow4 *f);
83const byte *flow6_first_part(const net_addr_flow6 *f);
84const byte *flow4_next_part(const byte *pos, const byte *end);
85const byte *flow6_next_part(const byte *pos, const byte *end);
ff2ca10c
OZ
86const byte *flow4_get_part(const net_addr_flow4 *f, uint type);
87const byte *flow6_get_part(const net_addr_flow6 *f, uint type);
77234bbb
OZ
88
89
0f882002
OZ
90/*
91 * Flowspec accessors
92 */
93
94ip4_addr flow_read_ip4_part(const byte *part);
95ip6_addr flow_read_ip6_part(const byte *part);
ff2ca10c 96static inline int flow_read_pxlen(const byte *part) { return part[1]; }
0f882002
OZ
97
98
77234bbb
OZ
99/*
100 * Flowspec Builder
101 */
102
103/* A data structure for keep a state of flow builder */
104struct flow_builder {
a32a7b58 105 BUFFER_(byte) data;
77234bbb
OZ
106 enum flow_type this_type;
107 enum flow_type last_type;
108 u16 last_op_offset; /* Position of last operator in data.data */
109 int ipv6;
110 struct {
111 u16 offset; /* Beginning of a component */
112 u16 length; /* Length of a component */
113 } parts[FLOW_TYPE_MAX]; /* Indexing all components */
114};
115
116struct flow_builder *flow_builder_init(pool *pool);
117void flow_builder_clear(struct flow_builder *fb);
118void flow_builder_set_type(struct flow_builder *fb, enum flow_type p);
119int flow_builder4_add_pfx(struct flow_builder *fb, const net_addr_ip4 *n4);
120int flow_builder6_add_pfx(struct flow_builder *fb, const net_addr_ip6 *n6, u32 offset);
121int flow_builder_add_op_val(struct flow_builder *fb, byte op, u32 value);
122int flow_builder_add_val_mask(struct flow_builder *fb, byte op, u32 value, u32 mask);
123net_addr_flow4 *flow_builder4_finalize(struct flow_builder *fb, linpool *lpool);
124net_addr_flow6 *flow_builder6_finalize(struct flow_builder *fb, linpool *lpool);
125
126
127/*
128 * Validation
129 */
130
131/* Results of validation Flow specification */
132enum flow_validated_state {
133 FLOW_ST_UNKNOWN_COMPONENT,
134 FLOW_ST_VALID,
135 FLOW_ST_NOT_COMPLETE,
136 FLOW_ST_EXCEED_MAX_PREFIX_LENGTH,
137 FLOW_ST_EXCEED_MAX_PREFIX_OFFSET,
138 FLOW_ST_EXCEED_MAX_VALUE_LENGTH,
139 FLOW_ST_BAD_TYPE_ORDER,
140 FLOW_ST_AND_BIT_SHOULD_BE_UNSET,
141 FLOW_ST_ZERO_BIT_SHOULD_BE_UNSED,
142 FLOW_ST_DEST_PREFIX_REQUIRED,
5ca4bd5d 143 FLOW_ST_INVALID_TCP_FLAGS,
77234bbb
OZ
144 FLOW_ST_CANNOT_USE_DONT_FRAGMENT
145};
146
147const char *flow_validated_state_str(enum flow_validated_state code);
148enum flow_validated_state flow4_validate(const byte *nlri, uint len);
149enum flow_validated_state flow6_validate(const byte *nlri, uint len);
150void flow_check_cf_value_length(struct flow_builder *fb, u32 expr);
151void flow_check_cf_bmk_values(struct flow_builder *fb, u8 neg, u32 val, u32 mask);
152void flow4_validate_cf(net_addr_flow4 *f);
153void flow6_validate_cf(net_addr_flow6 *f);
154
155
156/*
157 * Net Formatting
158 */
159
eeba61cc
OZ
160uint flow4_net_format(char *buf, uint blen, const net_addr_flow4 *f);
161uint flow6_net_format(char *buf, uint blen, const net_addr_flow6 *f);
77234bbb
OZ
162
163#endif /* _BIRD_FLOWSPEC_H_ */