Christopher Faulet | 1f40b91 | 2017-02-17 09:32:19 +0100 | [diff] [blame] | 1 | /* |
| 2 | * include/types/spoe.h |
| 3 | * Macros, variables and structures for the SPOE filter. |
| 4 | * |
| 5 | * Copyright (C) 2017 HAProxy Technologies, Christopher Faulet <cfaulet@haproxy.com> |
| 6 | * |
| 7 | * This library is free software; you can redistribute it and/or |
| 8 | * modify it under the terms of the GNU Lesser General Public |
| 9 | * License as published by the Free Software Foundation, version 2.1 |
| 10 | * exclusively. |
| 11 | * |
| 12 | * This library is distributed in the hope that it will be useful, |
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 15 | * Lesser General Public License for more details. |
| 16 | * |
| 17 | * You should have received a copy of the GNU Lesser General Public |
| 18 | * License along with this library; if not, write to the Free Software |
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 20 | */ |
| 21 | |
| 22 | #ifndef _TYPES_SPOE_H |
| 23 | #define _TYPES_SPOE_H |
| 24 | |
| 25 | #include <common/buffer.h> |
| 26 | #include <common/mini-clist.h> |
| 27 | |
| 28 | #include <types/filters.h> |
| 29 | #include <types/freq_ctr.h> |
| 30 | #include <types/proxy.h> |
| 31 | #include <types/sample.h> |
| 32 | #include <types/stream.h> |
| 33 | #include <types/task.h> |
| 34 | |
Christopher Faulet | c718b82 | 2017-09-21 16:50:56 +0200 | [diff] [blame] | 35 | /* Type of list of messages */ |
| 36 | #define SPOE_MSGS_BY_EVENT 0x01 |
| 37 | #define SPOE_MSGS_BY_GROUP 0x02 |
| 38 | |
Christopher Faulet | 1f40b91 | 2017-02-17 09:32:19 +0100 | [diff] [blame] | 39 | /* Flags set on the SPOE agent */ |
| 40 | #define SPOE_FL_CONT_ON_ERR 0x00000001 /* Do not stop events processing when an error occurred */ |
Christopher Faulet | 305c607 | 2017-02-23 16:17:53 +0100 | [diff] [blame] | 41 | #define SPOE_FL_PIPELINING 0x00000002 /* Set when SPOE agent supports pipelining (set by default) */ |
| 42 | #define SPOE_FL_ASYNC 0x00000004 /* Set when SPOE agent supports async (set by default) */ |
Christopher Faulet | cecd852 | 2017-02-24 22:11:21 +0100 | [diff] [blame] | 43 | #define SPOE_FL_SND_FRAGMENTATION 0x00000008 /* Set when SPOE agent supports sending fragmented payload */ |
| 44 | #define SPOE_FL_RCV_FRAGMENTATION 0x00000010 /* Set when SPOE agent supports receiving fragmented payload */ |
Christopher Faulet | 1f40b91 | 2017-02-17 09:32:19 +0100 | [diff] [blame] | 45 | |
| 46 | /* Flags set on the SPOE context */ |
| 47 | #define SPOE_CTX_FL_CLI_CONNECTED 0x00000001 /* Set after that on-client-session event was processed */ |
| 48 | #define SPOE_CTX_FL_SRV_CONNECTED 0x00000002 /* Set after that on-server-session event was processed */ |
| 49 | #define SPOE_CTX_FL_REQ_PROCESS 0x00000004 /* Set when SPOE is processing the request */ |
| 50 | #define SPOE_CTX_FL_RSP_PROCESS 0x00000008 /* Set when SPOE is processing the response */ |
| 51 | #define SPOE_CTX_FL_FRAGMENTED 0x00000010 /* Set when a fragmented frame is processing */ |
| 52 | |
| 53 | #define SPOE_CTX_FL_PROCESS (SPOE_CTX_FL_REQ_PROCESS|SPOE_CTX_FL_RSP_PROCESS) |
| 54 | |
| 55 | /* Flags set on the SPOE applet */ |
| 56 | #define SPOE_APPCTX_FL_PIPELINING 0x00000001 /* Set if pipelining is supported */ |
| 57 | #define SPOE_APPCTX_FL_ASYNC 0x00000002 /* Set if asynchronus frames is supported */ |
| 58 | #define SPOE_APPCTX_FL_FRAGMENTATION 0x00000004 /* Set if fragmentation is supported */ |
| 59 | #define SPOE_APPCTX_FL_PERSIST 0x00000008 /* Set if the applet is persistent */ |
| 60 | |
| 61 | #define SPOE_APPCTX_ERR_NONE 0x00000000 /* no error yet, leave it to zero */ |
| 62 | #define SPOE_APPCTX_ERR_TOUT 0x00000001 /* SPOE applet timeout */ |
| 63 | |
| 64 | /* Flags set on the SPOE frame */ |
| 65 | #define SPOE_FRM_FL_FIN 0x00000001 |
| 66 | #define SPOE_FRM_FL_ABRT 0x00000002 |
| 67 | |
| 68 | /* All possible states for a SPOE context */ |
| 69 | enum spoe_ctx_state { |
| 70 | SPOE_CTX_ST_NONE = 0, |
| 71 | SPOE_CTX_ST_READY, |
| 72 | SPOE_CTX_ST_ENCODING_MSGS, |
| 73 | SPOE_CTX_ST_SENDING_MSGS, |
| 74 | SPOE_CTX_ST_WAITING_ACK, |
| 75 | SPOE_CTX_ST_DONE, |
| 76 | SPOE_CTX_ST_ERROR, |
| 77 | }; |
| 78 | |
| 79 | /* All possible states for a SPOE applet */ |
| 80 | enum spoe_appctx_state { |
| 81 | SPOE_APPCTX_ST_CONNECT = 0, |
| 82 | SPOE_APPCTX_ST_CONNECTING, |
| 83 | SPOE_APPCTX_ST_IDLE, |
| 84 | SPOE_APPCTX_ST_PROCESSING, |
| 85 | SPOE_APPCTX_ST_SENDING_FRAG_NOTIFY, |
| 86 | SPOE_APPCTX_ST_WAITING_SYNC_ACK, |
| 87 | SPOE_APPCTX_ST_DISCONNECT, |
| 88 | SPOE_APPCTX_ST_DISCONNECTING, |
| 89 | SPOE_APPCTX_ST_EXIT, |
| 90 | SPOE_APPCTX_ST_END, |
| 91 | }; |
| 92 | |
| 93 | /* All supported SPOE actions */ |
| 94 | enum spoe_action_type { |
| 95 | SPOE_ACT_T_SET_VAR = 1, |
| 96 | SPOE_ACT_T_UNSET_VAR, |
| 97 | SPOE_ACT_TYPES, |
| 98 | }; |
| 99 | |
| 100 | /* All supported SPOE events */ |
| 101 | enum spoe_event { |
| 102 | SPOE_EV_NONE = 0, |
| 103 | |
| 104 | /* Request events */ |
| 105 | SPOE_EV_ON_CLIENT_SESS = 1, |
| 106 | SPOE_EV_ON_TCP_REQ_FE, |
| 107 | SPOE_EV_ON_TCP_REQ_BE, |
| 108 | SPOE_EV_ON_HTTP_REQ_FE, |
| 109 | SPOE_EV_ON_HTTP_REQ_BE, |
| 110 | |
| 111 | /* Response events */ |
| 112 | SPOE_EV_ON_SERVER_SESS, |
| 113 | SPOE_EV_ON_TCP_RSP, |
| 114 | SPOE_EV_ON_HTTP_RSP, |
| 115 | |
| 116 | SPOE_EV_EVENTS |
| 117 | }; |
| 118 | |
| 119 | /* Errors triggered by streams */ |
| 120 | enum spoe_context_error { |
| 121 | SPOE_CTX_ERR_NONE = 0, |
| 122 | SPOE_CTX_ERR_TOUT, |
| 123 | SPOE_CTX_ERR_RES, |
| 124 | SPOE_CTX_ERR_TOO_BIG, |
| 125 | SPOE_CTX_ERR_FRAG_FRAME_ABRT, |
Christopher Faulet | 344c4ab | 2017-09-22 10:20:13 +0200 | [diff] [blame] | 126 | SPOE_CTX_ERR_INTERRUPT, |
Christopher Faulet | 1f40b91 | 2017-02-17 09:32:19 +0100 | [diff] [blame] | 127 | SPOE_CTX_ERR_UNKNOWN = 255, |
| 128 | SPOE_CTX_ERRS, |
| 129 | }; |
| 130 | |
| 131 | /* Errors triggerd by SPOE applet */ |
| 132 | enum spoe_frame_error { |
| 133 | SPOE_FRM_ERR_NONE = 0, |
| 134 | SPOE_FRM_ERR_IO, |
| 135 | SPOE_FRM_ERR_TOUT, |
| 136 | SPOE_FRM_ERR_TOO_BIG, |
| 137 | SPOE_FRM_ERR_INVALID, |
| 138 | SPOE_FRM_ERR_NO_VSN, |
| 139 | SPOE_FRM_ERR_NO_FRAME_SIZE, |
| 140 | SPOE_FRM_ERR_NO_CAP, |
| 141 | SPOE_FRM_ERR_BAD_VSN, |
| 142 | SPOE_FRM_ERR_BAD_FRAME_SIZE, |
| 143 | SPOE_FRM_ERR_FRAG_NOT_SUPPORTED, |
| 144 | SPOE_FRM_ERR_INTERLACED_FRAMES, |
| 145 | SPOE_FRM_ERR_FRAMEID_NOTFOUND, |
| 146 | SPOE_FRM_ERR_RES, |
| 147 | SPOE_FRM_ERR_UNKNOWN = 99, |
| 148 | SPOE_FRM_ERRS, |
| 149 | }; |
| 150 | |
| 151 | /* Scopes used for variables set by agents. It is a way to be agnotic to vars |
| 152 | * scope. */ |
| 153 | enum spoe_vars_scope { |
| 154 | SPOE_SCOPE_PROC = 0, /* <=> SCOPE_PROC */ |
| 155 | SPOE_SCOPE_SESS, /* <=> SCOPE_SESS */ |
| 156 | SPOE_SCOPE_TXN, /* <=> SCOPE_TXN */ |
| 157 | SPOE_SCOPE_REQ, /* <=> SCOPE_REQ */ |
| 158 | SPOE_SCOPE_RES, /* <=> SCOPE_RES */ |
| 159 | }; |
| 160 | |
| 161 | |
| 162 | /* Describe an argument that will be linked to a message. It is a sample fetch, |
| 163 | * with an optional name. */ |
| 164 | struct spoe_arg { |
| 165 | char *name; /* Name of the argument, may be NULL */ |
| 166 | unsigned int name_len; /* The name length, 0 if NULL */ |
| 167 | struct sample_expr *expr; /* Sample expression */ |
| 168 | struct list list; /* Used to chain SPOE args */ |
| 169 | }; |
| 170 | |
| 171 | /* Used during the config parsing only because, when a SPOE agent section is |
Christopher Faulet | 11610f3 | 2017-09-21 10:23:10 +0200 | [diff] [blame] | 172 | * parsed, messages/groups can be undefined. */ |
| 173 | struct spoe_placeholder { |
| 174 | char *id; /* SPOE placeholder id */ |
| 175 | struct list list; /* Use to chain SPOE placeholders */ |
Christopher Faulet | 1f40b91 | 2017-02-17 09:32:19 +0100 | [diff] [blame] | 176 | }; |
| 177 | |
| 178 | /* Describe a message that will be sent in a NOTIFY frame. A message has a name, |
| 179 | * an argument list (see above) and it is linked to a specific event. */ |
| 180 | struct spoe_message { |
Christopher Faulet | 11610f3 | 2017-09-21 10:23:10 +0200 | [diff] [blame] | 181 | char *id; /* SPOE message id */ |
| 182 | unsigned int id_len; /* The message id length */ |
| 183 | struct spoe_agent *agent; /* SPOE agent owning this SPOE message */ |
| 184 | struct spoe_group *group; /* SPOE group owning this SPOE message (can be NULL) */ |
Christopher Faulet | 1f40b91 | 2017-02-17 09:32:19 +0100 | [diff] [blame] | 185 | struct { |
Christopher Faulet | 11610f3 | 2017-09-21 10:23:10 +0200 | [diff] [blame] | 186 | char *file; /* file where the SPOE message appears */ |
| 187 | int line; /* line where the SPOE message appears */ |
Christopher Faulet | 1f40b91 | 2017-02-17 09:32:19 +0100 | [diff] [blame] | 188 | } conf; /* config information */ |
Christopher Faulet | 11610f3 | 2017-09-21 10:23:10 +0200 | [diff] [blame] | 189 | unsigned int nargs; /* # of arguments */ |
| 190 | struct list args; /* Arguments added when the SPOE messages is sent */ |
| 191 | struct list list; /* Used to chain SPOE messages */ |
| 192 | struct list by_evt; /* By event list */ |
| 193 | struct list by_grp; /* By group list */ |
Christopher Faulet | 1f40b91 | 2017-02-17 09:32:19 +0100 | [diff] [blame] | 194 | |
Christopher Faulet | 11610f3 | 2017-09-21 10:23:10 +0200 | [diff] [blame] | 195 | struct list acls; /* ACL declared on this message */ |
| 196 | struct acl_cond *cond; /* acl condition to meet */ |
| 197 | enum spoe_event event; /* SPOE_EV_* */ |
Christopher Faulet | 1f40b91 | 2017-02-17 09:32:19 +0100 | [diff] [blame] | 198 | }; |
| 199 | |
Christopher Faulet | 11610f3 | 2017-09-21 10:23:10 +0200 | [diff] [blame] | 200 | /* Describe a group of messages that will be sent in a NOTIFY frame. A group has |
| 201 | * a name and a list of messages. It can be used by HAProxy, outside events |
| 202 | * processing, mainly in (tcp|http) rules. */ |
| 203 | struct spoe_group { |
| 204 | char *id; /* SPOE group id */ |
| 205 | struct spoe_agent *agent; /* SPOE agent owning this SPOE group */ |
| 206 | struct { |
| 207 | char *file; /* file where the SPOE group appears */ |
| 208 | int line; /* line where the SPOE group appears */ |
| 209 | } conf; /* config information */ |
| 210 | |
| 211 | struct list phs; /* List of placeholders used during conf parsing */ |
| 212 | struct list messages; /* List of SPOE messages that will be sent by this |
| 213 | * group */ |
| 214 | |
| 215 | struct list list; /* Used to chain SPOE groups */ |
| 216 | }; |
| 217 | |
Christopher Faulet | 1f40b91 | 2017-02-17 09:32:19 +0100 | [diff] [blame] | 218 | /* Describe a SPOE agent. */ |
| 219 | struct spoe_agent { |
| 220 | char *id; /* SPOE agent id (name) */ |
| 221 | struct { |
| 222 | char *file; /* file where the SPOE agent appears */ |
| 223 | int line; /* line where the SPOE agent appears */ |
| 224 | } conf; /* config information */ |
| 225 | union { |
| 226 | struct proxy *be; /* Backend used by this agent */ |
| 227 | char *name; /* Backend name used during conf parsing */ |
| 228 | } b; |
| 229 | struct { |
| 230 | unsigned int hello; /* Max time to receive AGENT-HELLO frame (in SPOE applet) */ |
| 231 | unsigned int idle; /* Max Idle timeout (in SPOE applet) */ |
| 232 | unsigned int processing; /* Max time to process an event (in the main stream) */ |
| 233 | } timeout; |
| 234 | |
| 235 | /* Config info */ |
| 236 | char *engine_id; /* engine-id string */ |
| 237 | char *var_pfx; /* Prefix used for vars set by the agent */ |
| 238 | char *var_on_error; /* Variable to set when an error occurred, in the TXN scope */ |
| 239 | unsigned int flags; /* SPOE_FL_* */ |
| 240 | unsigned int cps_max; /* Maximum # of connections per second */ |
| 241 | unsigned int eps_max; /* Maximum # of errors per second */ |
| 242 | unsigned int max_frame_size; /* Maximum frame size for this agent, before any negotiation */ |
| 243 | unsigned int min_applets; /* Minimum # applets alive at a time */ |
| 244 | unsigned int max_fpa; /* Maximum # of frames handled per applet at once */ |
| 245 | |
Christopher Faulet | 11610f3 | 2017-09-21 10:23:10 +0200 | [diff] [blame] | 246 | struct list events[SPOE_EV_EVENTS]; /* List of SPOE messages that will be sent |
Christopher Faulet | 1f40b91 | 2017-02-17 09:32:19 +0100 | [diff] [blame] | 247 | * for each supported events */ |
| 248 | |
Christopher Faulet | 11610f3 | 2017-09-21 10:23:10 +0200 | [diff] [blame] | 249 | struct list groups; /* List of available SPOE groups */ |
| 250 | |
| 251 | struct list messages; /* list of all messages attached to this SPOE agent */ |
| 252 | |
Christopher Faulet | 1f40b91 | 2017-02-17 09:32:19 +0100 | [diff] [blame] | 253 | /* running info */ |
| 254 | unsigned int frame_size; /* current maximum frame size, only used to encode messages */ |
| 255 | unsigned int applets_act; /* # of applets alive at a time */ |
| 256 | unsigned int applets_idle; /* # of applets in the state SPOE_APPCTX_ST_IDLE */ |
| 257 | unsigned int sending_rate; /* the global sending rate */ |
| 258 | |
| 259 | struct freq_ctr conn_per_sec; /* connections per second */ |
| 260 | struct freq_ctr err_per_sec; /* connetion errors per second */ |
| 261 | |
| 262 | struct list applets; /* List of available SPOE applets */ |
| 263 | struct list sending_queue; /* Queue of streams waiting to send data */ |
| 264 | struct list waiting_queue; /* Queue of streams waiting for a ack, in async mode */ |
| 265 | |
| 266 | }; |
| 267 | |
| 268 | /* SPOE filter configuration */ |
| 269 | struct spoe_config { |
Christopher Faulet | 7ee8667 | 2017-09-19 11:08:28 +0200 | [diff] [blame] | 270 | char *id; /* The SPOE engine name. If undefined in HAProxy config, |
| 271 | * it will be set with the SPOE agent name */ |
Christopher Faulet | 1f40b91 | 2017-02-17 09:32:19 +0100 | [diff] [blame] | 272 | struct proxy *proxy; /* Proxy owning the filter */ |
| 273 | struct spoe_agent *agent; /* Agent used by this filter */ |
| 274 | struct proxy agent_fe; /* Agent frontend */ |
| 275 | }; |
| 276 | |
| 277 | /* SPOE context attached to a stream. It is the main structure that handles the |
| 278 | * processing offload */ |
| 279 | struct spoe_context { |
| 280 | struct filter *filter; /* The SPOE filter */ |
| 281 | struct stream *strm; /* The stream that should be offloaded */ |
| 282 | |
Christopher Faulet | 11610f3 | 2017-09-21 10:23:10 +0200 | [diff] [blame] | 283 | struct list *events; /* List of messages that will be sent during the stream processing */ |
Christopher Faulet | 76c09ef | 2017-09-21 11:03:52 +0200 | [diff] [blame] | 284 | struct list *groups; /* List of available SPOE group */ |
Christopher Faulet | 11610f3 | 2017-09-21 10:23:10 +0200 | [diff] [blame] | 285 | |
Christopher Faulet | 1f40b91 | 2017-02-17 09:32:19 +0100 | [diff] [blame] | 286 | struct buffer *buffer; /* Buffer used to store a encoded messages */ |
| 287 | struct buffer_wait buffer_wait; /* position in the list of ressources waiting for a buffer */ |
| 288 | struct list list; |
| 289 | |
| 290 | enum spoe_ctx_state state; /* SPOE_CTX_ST_* */ |
| 291 | unsigned int flags; /* SPOE_CTX_FL_* */ |
| 292 | unsigned int status_code; /* SPOE_CTX_ERR_* */ |
| 293 | |
| 294 | unsigned int stream_id; /* stream_id and frame_id are used */ |
| 295 | unsigned int frame_id; /* to map NOTIFY and ACK frames */ |
| 296 | unsigned int process_exp; /* expiration date to process an event */ |
| 297 | |
| 298 | struct { |
| 299 | struct spoe_appctx *spoe_appctx; /* SPOE appctx sending the fragmented frame */ |
| 300 | struct spoe_message *curmsg; /* SPOE message from which to resume encoding */ |
| 301 | struct spoe_arg *curarg; /* SPOE arg in <curmsg> from which to resume encoding */ |
| 302 | unsigned int curoff; /* offset in <curarg> from which to resume encoding */ |
| 303 | unsigned int flags; /* SPOE_FRM_FL_* */ |
| 304 | } frag_ctx; /* Info about fragmented frames, valid on if SPOE_CTX_FL_FRAGMENTED is set */ |
| 305 | }; |
| 306 | |
| 307 | /* SPOE context inside a appctx */ |
| 308 | struct spoe_appctx { |
| 309 | struct appctx *owner; /* the owner */ |
| 310 | struct task *task; /* task to handle applet timeouts */ |
| 311 | struct spoe_agent *agent; /* agent on which the applet is attached */ |
| 312 | |
| 313 | unsigned int version; /* the negotiated version */ |
| 314 | unsigned int max_frame_size; /* the negotiated max-frame-size value */ |
| 315 | unsigned int flags; /* SPOE_APPCTX_FL_* */ |
| 316 | |
| 317 | unsigned int status_code; /* SPOE_FRM_ERR_* */ |
| 318 | #if defined(DEBUG_SPOE) || defined(DEBUG_FULL) |
| 319 | char *reason; /* Error message, used for debugging only */ |
| 320 | int rlen; /* reason length */ |
| 321 | #endif |
| 322 | |
| 323 | struct buffer *buffer; /* Buffer used to store a encoded messages */ |
| 324 | struct buffer_wait buffer_wait; /* position in the list of ressources waiting for a buffer */ |
| 325 | struct list waiting_queue; /* list of streams waiting for a ACK frame, in sync and pipelining mode */ |
| 326 | struct list list; /* next spoe appctx for the same agent */ |
| 327 | |
| 328 | struct { |
| 329 | struct spoe_context *ctx; /* SPOE context owning the fragmented frame */ |
| 330 | unsigned int cursid; /* stream-id of the fragmented frame. used if the processing is aborted */ |
| 331 | unsigned int curfid; /* frame-id of the fragmented frame. used if the processing is aborted */ |
| 332 | } frag_ctx; /* Info about fragmented frames, unused for unfragmented frames */ |
| 333 | }; |
| 334 | |
| 335 | /* Frame Types sent by HAProxy and by agents */ |
| 336 | enum spoe_frame_type { |
Christopher Faulet | f032c3e | 2017-02-17 15:18:35 +0100 | [diff] [blame] | 337 | SPOE_FRM_T_UNSET = 0, |
| 338 | |
Christopher Faulet | 1f40b91 | 2017-02-17 09:32:19 +0100 | [diff] [blame] | 339 | /* Frames sent by HAProxy */ |
| 340 | SPOE_FRM_T_HAPROXY_HELLO = 1, |
| 341 | SPOE_FRM_T_HAPROXY_DISCON, |
| 342 | SPOE_FRM_T_HAPROXY_NOTIFY, |
| 343 | |
| 344 | /* Frames sent by the agents */ |
| 345 | SPOE_FRM_T_AGENT_HELLO = 101, |
| 346 | SPOE_FRM_T_AGENT_DISCON, |
| 347 | SPOE_FRM_T_AGENT_ACK |
| 348 | }; |
| 349 | |
| 350 | /* All supported data types */ |
| 351 | enum spoe_data_type { |
| 352 | SPOE_DATA_T_NULL = 0, |
| 353 | SPOE_DATA_T_BOOL, |
| 354 | SPOE_DATA_T_INT32, |
| 355 | SPOE_DATA_T_UINT32, |
| 356 | SPOE_DATA_T_INT64, |
| 357 | SPOE_DATA_T_UINT64, |
| 358 | SPOE_DATA_T_IPV4, |
| 359 | SPOE_DATA_T_IPV6, |
| 360 | SPOE_DATA_T_STR, |
| 361 | SPOE_DATA_T_BIN, |
| 362 | SPOE_DATA_TYPES |
| 363 | }; |
| 364 | |
| 365 | /* Masks to get data type or flags value */ |
| 366 | #define SPOE_DATA_T_MASK 0x0F |
| 367 | #define SPOE_DATA_FL_MASK 0xF0 |
| 368 | |
| 369 | /* Flags to set Boolean values */ |
| 370 | #define SPOE_DATA_FL_FALSE 0x00 |
| 371 | #define SPOE_DATA_FL_TRUE 0x10 |
| 372 | |
| 373 | |
| 374 | #endif /* _TYPES_SPOE_H */ |