2 * BIRD Library -- Flow specification (RFC 5575)
4 * (c) 2016 CZ.NIC z.s.p.o.
6 * Can be freely distributed and used under the terms of the GNU GPL.
9 #ifndef _BIRD_FLOWSPEC_H_
10 #define _BIRD_FLOWSPEC_H_
12 #include "nest/bird.h"
13 #include "lib/buffer.h"
17 /* Flow component operators */
18 #define FLOW_OP_FALSE 0x00 /* 0b000 */
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 */
25 #define FLOW_OP_TRUE 0x07 /* 0b111 */
27 #define FLOW_OP_OR 0x00
28 #define FLOW_OP_AND 0x40
31 /* Types of components in flowspec */
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 */
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 */
50 const char *flow_type_str(enum flow_type type
, int ipv6
);
57 uint
flow_write_length(byte
*data
, u16 len
);
59 static inline u16
flow_hdr_length(const byte
*data
)
60 { return ((*data
& 0xf0) == 0xf0) ? 2 : 1; }
62 static inline u16
flow_read_length(const byte
*data
)
63 { return ((*data
& 0xf0) == 0xf0) ? get_u16(data
) & 0x0fff : *data
; }
65 static inline u16
flow4_get_length(const net_addr_flow4
*f
)
66 { return f
->length
- sizeof(net_addr_flow4
); }
68 static inline u16
flow6_get_length(const net_addr_flow6
*f
)
69 { return f
->length
- sizeof(net_addr_flow6
); }
71 static 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
; }
74 static 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
; }
82 const byte
*flow4_first_part(const net_addr_flow4
*f
);
83 const byte
*flow6_first_part(const net_addr_flow6
*f
);
84 const byte
*flow4_next_part(const byte
*pos
, const byte
*end
);
85 const byte
*flow6_next_part(const byte
*pos
, const byte
*end
);
86 const byte
*flow4_get_part(const net_addr_flow4
*f
, uint type
);
87 const byte
*flow6_get_part(const net_addr_flow6
*f
, uint type
);
94 ip4_addr
flow_read_ip4_part(const byte
*part
);
95 ip6_addr
flow_read_ip6_part(const byte
*part
);
96 static inline int flow_read_pxlen(const byte
*part
) { return part
[1]; }
103 /* A data structure for keep a state of flow builder */
104 struct flow_builder
{
106 enum flow_type this_type
;
107 enum flow_type last_type
;
108 u16 last_op_offset
; /* Position of last operator in data.data */
111 u16 offset
; /* Beginning of a component */
112 u16 length
; /* Length of a component */
113 } parts
[FLOW_TYPE_MAX
]; /* Indexing all components */
116 struct flow_builder
*flow_builder_init(pool
*pool
);
117 void flow_builder_clear(struct flow_builder
*fb
);
118 void flow_builder_set_type(struct flow_builder
*fb
, enum flow_type p
);
119 int flow_builder4_add_pfx(struct flow_builder
*fb
, const net_addr_ip4
*n4
);
120 int flow_builder6_add_pfx(struct flow_builder
*fb
, const net_addr_ip6
*n6
, u32 offset
);
121 int flow_builder_add_op_val(struct flow_builder
*fb
, byte op
, u32 value
);
122 int flow_builder_add_val_mask(struct flow_builder
*fb
, byte op
, u32 value
, u32 mask
);
123 net_addr_flow4
*flow_builder4_finalize(struct flow_builder
*fb
, linpool
*lpool
);
124 net_addr_flow6
*flow_builder6_finalize(struct flow_builder
*fb
, linpool
*lpool
);
131 /* Results of validation Flow specification */
132 enum flow_validated_state
{
133 FLOW_ST_UNKNOWN_COMPONENT
,
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
,
143 FLOW_ST_INVALID_TCP_FLAGS
,
144 FLOW_ST_CANNOT_USE_DONT_FRAGMENT
147 const char *flow_validated_state_str(enum flow_validated_state code
);
148 enum flow_validated_state
flow4_validate(const byte
*nlri
, uint len
);
149 enum flow_validated_state
flow6_validate(const byte
*nlri
, uint len
);
150 void flow_check_cf_value_length(struct flow_builder
*fb
, u32 expr
);
151 void flow_check_cf_bmk_values(struct flow_builder
*fb
, u8 neg
, u32 val
, u32 mask
);
152 void flow4_validate_cf(net_addr_flow4
*f
);
153 void flow6_validate_cf(net_addr_flow6
*f
);
160 uint
flow4_net_format(char *buf
, uint blen
, const net_addr_flow4
*f
);
161 uint
flow6_net_format(char *buf
, uint blen
, const net_addr_flow6
*f
);
163 #endif /* _BIRD_FLOWSPEC_H_ */