VPP-197: LISP Source/Dest control plane support
[vpp.git] / vnet / vnet / lisp-cp / lisp_cp_messages.h
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #ifndef VNET_LISP_GPE_LISP_CP_MESSAGES_H_
17 #define VNET_LISP_GPE_LISP_CP_MESSAGES_H_
18
19 #include <vnet/vnet.h>
20
21 #define MAX_IP_PKT_LEN 4096
22 #define MAX_IP_HDR_LEN 40  /* without options or IPv6 hdr extensions */
23 #define UDP_HDR_LEN 8
24 #define LISP_DATA_HDR_LEN 8
25 #define LISP_ECM_HDR_LEN 4
26 #define MAX_LISP_MSG_ENCAP_LEN  2*(MAX_IP_HDR_LEN + UDP_HDR_LEN)+ LISP_ECM_HDR_LEN
27 #define MAX_LISP_PKT_ENCAP_LEN  MAX_IP_HDR_LEN + UDP_HDR_LEN + LISP_DATA_HDR_LEN
28
29 #define LISP_CONTROL_PORT 4342
30
31 /*
32  * EID RECORD FIELD
33  */
34
35 /*
36  *      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
37  *    / |   Reserved    | EID mask-len  |        EID-prefix-AFI         |
38  *  Rec +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
39  *    \ |                       EID-prefix  ...                         |
40  *      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
41  */
42
43
44 typedef struct _eid_prefix_record_hdr {
45     u8 reserved;
46     u8 eid_prefix_length;
47 } __attribute__ ((__packed__)) eid_record_hdr_t;
48
49 void eid_rec_hdr_init(eid_record_hdr_t *ptr);
50
51 #define EID_REC_CAST(h_) ((eid_record_hdr_t *)(h_))
52 #define EID_REC_MLEN(h_) EID_REC_CAST((h_))->eid_prefix_length
53 #define EID_REC_ADDR(h) (u8 *)(h) + sizeof(eid_record_hdr_t)
54
55 /* LISP Types */
56 typedef enum
57 {
58   NOT_LISP_MSG,
59   LISP_MAP_REQUEST = 1,
60   LISP_MAP_REPLY,
61   LISP_MAP_REGISTER,
62   LISP_MAP_NOTIFY,
63   LISP_INFO_NAT = 7,
64   LISP_ENCAP_CONTROL_TYPE = 8,
65   LISP_MSG_TYPES
66 } lisp_msg_type_e;
67
68 /*
69  * ENCAPSULATED CONTROL MESSAGE
70  */
71
72 /*
73  *     0                   1                   2                   3
74  *     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
75  *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
76  *   / |                       IPv4 or IPv6 Header                     |
77  * OH  |                      (uses RLOC addresses)                    |
78  *   \ |                                                               |
79  *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
80  *   / |       Source Port = xxxx      |       Dest Port = 4342        |
81  * UDP +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
82  *   \ |           UDP Length          |        UDP Checksum           |
83  *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
84  * LH  |Type=8 |S|                  Reserved                           |
85  *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
86  *   / |                       IPv4 or IPv6 Header                     |
87  * IH  |                  (uses RLOC or EID addresses)                 |
88  *   \ |                                                               |
89  *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
90  *   / |       Source Port = xxxx      |       Dest Port = yyyy        |
91  * UDP +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
92  *   \ |           UDP Length          |        UDP Checksum           |
93  *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
94  * LCM |                      LISP Control Message                     |
95  *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
96  */
97
98
99 /*
100  * Encapsulated control message header. This is followed by the IP
101  * header of the encapsulated LISP control message.
102  *
103  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
104  *    |Type=8 |S|                 Reserved                            |
105  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
106  */
107
108 typedef struct
109 {
110 #if CLIB_ARCH_IS_LITTLE_ENDIAN
111   u8 reserved:3;
112   u8 s_bit:1;
113   u8 type:4;
114 #else
115   u8 type:4;
116   u8 s_bit:1;
117   u8 reserved:3;
118 #endif
119   u8 reserved2[3];
120 } ecm_hdr_t;
121
122 char *ecm_hdr_to_char(ecm_hdr_t *h);
123
124 #define ECM_TYPE(h_) ((ecm_hdr_t *)(h_))->type
125
126 /*
127  * MAP-REQUEST MESSAGE
128  */
129
130 /*
131  * Map-Request Message Format
132  *
133  *       0                   1                   2                   3
134  *       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
135  *      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
136  *      |Type=1 |A|M|P|S|p|s|    Reserved     |   IRC   | Record Count  |
137  *      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
138  *      |                         Nonce . . .                           |
139  *      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
140  *      |                         . . . Nonce                           |
141  *      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
142  *      |         Source-EID-AFI        |   Source EID Address  ...     |
143  *      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
144  *      |         ITR-RLOC-AFI 1        |    ITR-RLOC Address 1  ...    |
145  *      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
146  *      |                              ...                              |
147  *      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
148  *      |         ITR-RLOC-AFI n        |    ITR-RLOC Address n  ...    |
149  *      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
150  *    / |   Reserved    | EID mask-len  |        EID-prefix-AFI         |
151  *  Rec +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
152  *    \ |                       EID-prefix  ...                         |
153  *      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
154  *      |                   Map-Reply Record  ...                       |
155  *      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
156  *      |                     Mapping Protocol Data                     |
157  *      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
158  */
159
160
161 /*
162  * Fixed size portion of the map request. Variable size source EID
163  * address, originating ITR RLOC AFIs and addresses and then map
164  * request records follow.
165  */
166 typedef struct
167 {
168 #if CLIB_ARCH_IS_LITTLE_ENDIAN
169     u8 solicit_map_request:1;
170     u8 rloc_probe:1;
171     u8 map_data_present:1;
172     u8 authoritative:1;
173     u8 type:4;
174 #else
175     u8 type:4;
176     u8 authoritative:1;
177     u8 map_data_present:1;
178     u8 rloc_probe:1;
179     u8 solicit_map_request:1;
180 #endif
181 #if CLIB_ARCH_IS_LITTLE_ENDIAN
182     u8 reserved1:6;
183     u8 smr_invoked:1;
184     u8 pitr:1;
185 #else
186     u8 pitr:1;
187     u8 smr_invoked:1;
188     u8 reserved1:6;
189 #endif
190 #if CLIB_ARCH_IS_LITTLE_ENDIAN
191     u8 additional_itr_rloc_count:5;
192     u8 reserved2:3;
193 #else
194     u8 reserved2:3;
195     u8 additional_itr_rloc_count:5;
196 #endif
197     u8 record_count;
198     u64 nonce;
199 }__attribute__ ((__packed__)) map_request_hdr_t;
200
201 void map_request_hdr_init(void *ptr);
202 char *map_request_hdr_to_char(map_request_hdr_t *h);
203
204 #define MREQ_TYPE(h_) (h_)->type
205 #define MREQ_HDR_CAST(h_) ((map_request_hdr_t *)(h_))
206 #define MREQ_REC_COUNT(h_) (MREQ_HDR_CAST(h_))->record_count
207 #define MREQ_RLOC_PROBE(h_) (MREQ_HDR_CAST(h_))->rloc_probe
208 #define MREQ_ITR_RLOC_COUNT(h_) (MREQ_HDR_CAST(h_))->additional_itr_rloc_count
209 #define MREQ_NONCE(h_) (MREQ_HDR_CAST(h_))->nonce
210 #define MREQ_SMR(h_) (MREQ_HDR_CAST(h_))->solicit_map_request
211 #define MREQ_SMR_INVOKED(h_) (MREQ_HDR_CAST(h_))->smr_invoked
212
213 /*
214  * MAP-REPLY MESSAGE
215  */
216
217  /*
218   * Map-Reply Message Format
219   *
220   *       0                   1                   2                   3
221   *       0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
222   *      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
223   *      |Type=2 |P|E|S|         Reserved                | Record Count  |
224   *      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
225   *      |                         Nonce . . .                           |
226   *      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
227   *      |                         . . . Nonce                           |
228   *  +-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
229   *  |   |                          Record  TTL                          |
230   *  |   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
231   *  R   | Locator Count | EID mask-len  | ACT |A|      Reserved         |
232   *  e   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
233   *  c   | Rsvd  |  Map-Version Number   |            EID-AFI            |
234   *  o   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
235   *  r   |                          EID-prefix                           |
236   *  d   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
237   *  |  /|    Priority   |    Weight     |  M Priority   |   M Weight    |
238   *  | L +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
239   *  | o |        Unused Flags     |L|p|R|           Loc-AFI             |
240   *  | c +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
241   *  |  \|                            Locator                            |
242   *  +-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
243   *      |                     Mapping Protocol Data                     |
244   *      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
245   */
246
247  /*
248   * Fixed size portion of the map reply.
249   */
250 typedef struct
251 {
252 #if CLIB_ARCH_IS_LITTLE_ENDIAN
253     u8 reserved1:1;
254     u8 security:1;
255     u8 echo_nonce:1;
256     u8 rloc_probe:1;
257     u8 type:4;
258 #else
259     u8 type:4;
260     u8 rloc_probe:1;
261     u8 echo_nonce:1;
262     u8 security:1;
263     u8 reserved1:1;
264 #endif
265     u8 reserved2;
266     u8 reserved3;
267     u8 record_count;
268     u64 nonce;
269 } __attribute__ ((__packed__)) map_reply_hdr_t;
270
271  void map_reply_hdr_init(void *ptr);
272  char *map_reply_hdr_to_char(map_reply_hdr_t *h);
273
274 #define MREP_HDR_CAST(h_) ((map_reply_hdr_t *)(h_))
275 #define MREP_REC_COUNT(h_) MREP_HDR_CAST(h_)->record_count
276 #define MREP_RLOC_PROBE(h_) MREP_HDR_CAST(h_)->rloc_probe
277 #define MREP_NONCE(h_) MREP_HDR_CAST(h_)->nonce
278
279
280 always_inline lisp_msg_type_e
281 lisp_msg_type (void * b)
282 {
283   ecm_hdr_t * hdr = b;
284   if (!hdr)
285     {
286       return (NOT_LISP_MSG);
287     }
288   return (hdr->type);
289 }
290
291 always_inline void
292 increment_record_count (void * b)
293 {
294   switch (lisp_msg_type (b))
295     {
296     case LISP_MAP_REQUEST:
297       MREQ_REC_COUNT(b) += 1;
298       break;
299     case LISP_MAP_REPLY:
300       MREP_REC_COUNT(b) += 1;
301       break;
302     default:
303       return;
304     }
305 }
306
307
308 /*
309  * LOCATOR FIELD
310  *
311  *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
312  *    /|    Priority   |    Weight     |  M Priority   |   M Weight    |
313  *   L +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
314  *   o |        Unused Flags     |L|p|R|           Loc-AFI             |
315  *   c +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
316  *    \|                            Locator                            |
317  *     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
318  *
319  * Fixed portion of the mapping record locator. Variable length
320  * locator address follows.
321  */
322 typedef struct _locator_hdr {
323     u8 priority;
324     u8 weight;
325     u8 mpriority;
326     u8 mweight;
327     u8 unused1;
328 #ifdef CLIB_ARCH_IS_LITTLE_ENDIAN
329     u8 reachable:1;
330     u8 probed:1;
331     u8 local:1;
332     u8 unused2:5;
333 #else
334     u8 unused2:5;
335     u8 local:1;
336     u8 probed:1;
337     u8 reachable:1;
338 #endif
339 } __attribute__ ((__packed__)) locator_hdr_t;
340
341 #define LOC_CAST(h_) ((locator_hdr_t *)(h_))
342 #define LOC_PROBED(h_) LOC_CAST(h_)->probed
343 #define LOC_PRIORITY(h_) LOC_CAST(h_)->priority
344 #define LOC_WEIGHT(h_) LOC_CAST(h_)->weight
345 #define LOC_MPRIORITY(h_) LOC_CAST(h_)->mpriority
346 #define LOC_MWEIGHT(h_) LOC_CAST(h_)->mweight
347 #define LOC_REACHABLE(h_) LOC_CAST(h_)->reachable
348 #define LOC_LOCAL(h_) LOC_CAST(h_)->local
349 #define LOC_ADDR(h_) ((u8 *)(h_)  + sizeof(locator_hdr_t))
350
351 /*
352  * MAPPING RECORD
353  *
354  * Mapping record used in all LISP control messages.
355  *
356  *  +--->  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
357  *  |      |                          Record  TTL                          |
358  *  |      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
359  *  R      | Locator Count | EID mask-len  | ACT |A|       Reserved        |
360  *  e      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
361  *  c      | Rsvd  |  Map-Version Number   |            EID-AFI            |
362  *  o      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
363  *  r      |                          EID-prefix                           |
364  *  d      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
365  *  |     /|    Priority   |    Weight     |  M Priority   |   M Weight    |
366  *  |    / +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
367  *  |  Loc |         Unused Flags    |L|p|R|           Loc-AFI             |
368  *  |    \ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
369  *  |     \|                             Locator                           |
370  *  +--->  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
371  */
372
373 /*
374  * Fixed portion of the mapping record. EID prefix address and
375  * locators follow.
376  */
377
378 typedef struct _mapping_record_hdr_t
379 {
380   u32 ttl;
381   u8 locator_count;
382   u8 eid_prefix_length;
383 #ifdef CLIB_ARCH_IS_LITTLE_ENDIAN
384   u8 reserved1:4;
385   u8 authoritative:1;
386   u8 action:3;
387 #else
388   u8 action :3;
389   u8 authoritative :1;
390   u8 reserved1 :4;
391 #endif
392   u8 reserved2;
393 #ifdef CLIB_ARCH_IS_LITTLE_ENDIAN
394   u8 version_hi:4;
395   u8 reserved3:4;
396 #else
397   u8 reserved3 :4;
398   u8 version_hi :4;
399 #endif
400   u8 version_low;
401 }__attribute__ ((__packed__)) mapping_record_hdr_t;
402
403 void mapping_record_init_hdr(mapping_record_hdr_t *h);
404
405 #define MAP_REC_EID_PLEN(h) ((mapping_record_hdr_t *)(h))->eid_prefix_length
406 #define MAP_REC_LOC_COUNT(h) ((mapping_record_hdr_t *)(h))->locator_count
407 #define MAP_REC_ACTION(h) ((mapping_record_hdr_t *)(h))->action
408 #define MAP_REC_AUTH(h) ((mapping_record_hdr_t *)(h))->authoritative
409 #define MAP_REC_TTL(h) ((mapping_record_hdr_t *)(h))->ttl
410 #define MAP_REC_EID(h) (u8 *)(h)+sizeof(mapping_record_hdr_t)
411 #define MAP_REC_VERSION(h) (h)->version_hi << 8 | (h)->version_low
412
413 typedef enum
414 {
415   LISP_NO_ACTION,
416   LISP_FORWARD_NATIVE,
417   LISP_SEND_MAP_REQUEST,
418   LISP_DROP
419 } lisp_action_e;
420
421 typedef enum lisp_authoritative
422 {
423   A_NO_AUTHORITATIVE = 0,
424   A_AUTHORITATIVE
425 } lisp_authoritative_e;
426
427 /*
428  * LISP Canonical Address Format Encodings
429  *
430  *   0                   1                   2                   3
431  *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
432  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
433  *  |           AFI = 16387         |     Rsvd1     |     Flags     |
434  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
435  *  |    Type       |     Rsvd2     |            Length             |
436  *  +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
437  */
438
439 typedef struct _lcaf_hdr_t
440 {
441   u8 reserved1;
442   u8 flags;
443   u8 type;
444   u8 reserved2;
445   u16 len;
446 } __attribute__ ((__packed__)) lcaf_hdr_t;
447
448 #define LCAF_TYPE(h) ((lcaf_hdr_t *)(h))->type
449 #define LCAF_LENGTH(h) ((lcaf_hdr_t *)(h))->len
450 #define LCAF_RES2(h) ((lcaf_hdr_t *)(h))->reserved2
451 #define LCAF_FLAGS(h) ((lcaf_hdr_t *)(h))->flags
452 #define LCAF_PAYLOAD(h) (u8 *)(h)+sizeof(lcaf_hdr_t)
453
454 /*
455  * Source/Dest Key Canonical Address Format:
456  *
457  *   0                   1                   2                   3
458  *   0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
459  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
460  *   |            Reserved           |   Source-ML   |    Dest-ML    |
461  *   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
462  */
463 typedef struct _lcaf_src_dst_hdr_t
464 {
465   u16 reserved;
466   u8 src_mask_len;
467   u8 dst_mask_len;
468 } __attribute__ ((__packed__)) lcaf_src_dst_hdr_t;
469
470 #define LCAF_SD_SRC_ML(_h) (_h)->src_mask_len
471 #define LCAF_SD_DST_ML(_h) (_h)->dst_mask_len
472
473 #endif /* VNET_LISP_GPE_LISP_CP_MESSAGES_H_ */