aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/lisp/lisp-cp/lisp_types.h
blob: 21bd72178d7eb50ac544a346d2c1ea31cf085c25 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
/*
 * Copyright (c) 2016 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef VNET_LISP_GPE_LISP_TYPES_H_
#define VNET_LISP_GPE_LISP_TYPES_H_

#include <vnet/ip/ip.h>
#include <lisp/lisp-cp/lisp_cp_messages.h>

#define SHA1_AUTH_DATA_LEN                  20
#define SHA256_AUTH_DATA_LEN                32

typedef enum
{
  HMAC_NO_KEY = 0,
  HMAC_SHA_1_96,
  HMAC_SHA_256_128
} lisp_key_type_t;

uword unformat_hmac_key_id (unformat_input_t * input, va_list * args);
u8 *format_hmac_key_id (u8 * s, va_list * args);

typedef enum
{
  /* NOTE: ip addresses are left out on purpose. Use max masked ip-prefixes
   * instead */
  GID_ADDR_IP_PREFIX,
  GID_ADDR_LCAF,
  GID_ADDR_MAC,
  GID_ADDR_SRC_DST,
  GID_ADDR_NSH,
  GID_ADDR_ARP,
  GID_ADDR_NDP,
  GID_ADDR_NO_ADDRESS,
  GID_ADDR_TYPES
} gid_address_type_t;

typedef enum
{
  /* make sure that values corresponds with RFC */
  LCAF_NULL_BODY = 0,
  LCAF_AFI_LIST_TYPE,
  LCAF_INSTANCE_ID,
  LCAF_SOURCE_DEST = 12,
  LCAF_NSH = 17,
  LCAF_TYPES
} lcaf_type_t;

typedef enum fid_addr_type_t_
{
  FID_ADDR_IP_PREF,
  FID_ADDR_MAC,
  FID_ADDR_NSH
} __attribute__ ((packed)) fid_addr_type_t;

/* flat address type */
typedef struct
{
  union
  {
    ip_prefix_t ippref;
    u8 mac[6];
    u32 nsh;
  };
  fid_addr_type_t type;
} fid_address_t;

typedef fid_address_t dp_address_t;

#define fid_addr_ippref(_a) (_a)->ippref
#define fid_addr_prefix_length(_a) ip_prefix_len(&fid_addr_ippref(_a))
#define fid_addr_ip_version(_a) ip_prefix_version(&fid_addr_ippref(_a))
#define fid_addr_mac(_a) (_a)->mac
#define fid_addr_nsh(_a) (_a)->nsh
#define fid_addr_type(_a) (_a)->type
u8 *format_fid_address (u8 * s, va_list * args);

typedef struct
{
  fid_address_t src;
  fid_address_t dst;
} source_dest_t;

#define sd_dst(_a) (_a)->dst
#define sd_src(_a) (_a)->src
#define sd_src_ippref(_a) fid_addr_ippref(&sd_src(_a))
#define sd_dst_ippref(_a) fid_addr_ippref(&sd_dst(_a))
#define sd_src_mac(_a) fid_addr_mac(&sd_src(_a))
#define sd_dst_mac(_a) fid_addr_mac(&sd_dst(_a))
#define sd_src_type(_a) fid_addr_type(&sd_src(_a))
#define sd_dst_type(_a) fid_addr_type(&sd_dst(_a))

typedef struct
{
  u8 vni_mask_len;
  u32 vni;
  struct _gid_address_t *gid_addr;
} vni_t;

#define vni_vni(_a) (_a)->vni
#define vni_mask_len(_a) (_a)->vni_mask_len
#define vni_gid(_a) (_a)->gid_addr

typedef struct
{
  u32 spi;
  u8 si;
} nsh_t;

#define nsh_spi(_a) (_a)->spi
#define nsh_si(_a) (_a)->si

typedef struct
{
  ip_address_t addr;
  u32 bd;
} lcaf_arp_ndp_t;

#define lcaf_arp_ndp_ip(_a) (_a)->addr
#define lcaf_arp_ndp_ip_ver(_a) ip_addr_version(&lcaf_arp_ndp_ip(_a))
#define lcaf_arp_ndp_ip4(_a) ip_addr_v4(&lcaf_arp_ndp_ip(_a))
#define lcaf_arp_ndp_ip6(_a) ip_addr_v6(&lcaf_arp_ndp_ip(_a))
#define lcaf_arp_ndp_bd(_a) (_a)->bd

typedef struct
{
  /* the union needs to be at the beginning! */
  union
  {
    source_dest_t sd;
    lcaf_arp_ndp_t arp_ndp;
    vni_t uni;
  };
  u8 type;
} lcaf_t;

#define lcaf_type(_a) (_a)->type
#define lcaf_vni(_a) vni_vni(& (_a)->uni)
#define lcaf_vni_len(_a) vni_mask_len(& (_a)->uni)

/* might want to expand this in the future :) */
typedef struct _gid_address_t
{
  union
  {
    ip_prefix_t ippref;
    lcaf_t lcaf;
    u8 mac[6];
    source_dest_t sd;
    lcaf_arp_ndp_t arp_ndp;
    nsh_t nsh;
  };
  u8 type;
  u32 vni;
  u8 vni_mask;
} gid_address_t;

u16 ip4_address_size_to_put ();
u16 ip6_address_size_to_put ();
u32 ip4_address_put (u8 * b, ip4_address_t * a);
u32 ip6_address_put (u8 * b, ip6_address_t * a);

u16 ip_address_size_to_write (ip_address_t * a);
u16 ip_address_iana_afi (ip_address_t * a);
u8 ip_address_max_len (u8 ver);
u32 ip_address_put (u8 * b, ip_address_t * a);

/* LISP AFI codes  */
typedef enum
{
  LISP_AFI_NO_ADDR,
  LISP_AFI_IP,
  LISP_AFI_IP6,
  LISP_AFI_LCAF = 16387,
  LISP_AFI_MAC = 16389
} lisp_afi_e;

u8 *format_gid_address (u8 * s, va_list * args);
uword unformat_gid_address (unformat_input_t * input, va_list * args);
int gid_address_cmp (gid_address_t * a1, gid_address_t * a2);
void gid_address_free (gid_address_t * a);

u16 gid_address_size_to_put (gid_address_t * a);
u16 gid_address_put (u8 * b, gid_address_t * gid);
u8 gid_address_len (gid_address_t * a);
void *gid_address_cast (gid_address_t * gid, gid_address_type_t type);
void gid_address_copy (gid_address_t * dst, gid_address_t * src);
u32 gid_address_parse (u8 * offset, gid_address_t * a);
void gid_address_ip_set (gid_address_t * dst, void *src, u8 version);

#define gid_address_type(_a) (_a)->type
#define gid_address_ippref(_a) (_a)->ippref
#define gid_address_ippref_len(_a) (_a)->ippref.len
#define gid_address_ip(_a) ip_prefix_addr(&gid_address_ippref(_a))
#define gid_address_ip_version(_a) ip_addr_version(&gid_address_ip(_a))
#define gid_address_lcaf(_a) (_a)->lcaf
#define gid_address_mac(_a) (_a)->mac
#define gid_address_nsh(_a) (_a)->nsh
#define gid_address_nsh_spi(_a) nsh_spi(&gid_address_nsh(_a))
#define gid_address_nsh_si(_a) nsh_si(&gid_address_nsh(_a))
#define gid_address_vni(_a) (_a)->vni
#define gid_address_vni_mask(_a) (_a)->vni_mask
#define gid_address_sd_dst_ippref(_a) sd_dst_ippref(&(_a)->sd)
#define gid_address_sd_src_ippref(_a) sd_src_ippref(&(_a)->sd)
#define gid_address_sd_dst_mac(_a) sd_dst_mac(&(_a)->sd)
#define gid_address_sd_src_mac(_a) sd_src_mac(&(_a)->sd)
#define gid_address_sd(_a) (_a)->sd
#define gid_address_sd_src(_a) sd_src(&gid_address_sd(_a))
#define gid_address_sd_dst(_a) sd_dst(&gid_address_sd(_a))
#define gid_address_sd_src_type(_a) sd_src_type(&gid_address_sd(_a))
#define gid_address_sd_dst_type(_a) sd_dst_type(&gid_address_sd(_a))
#define gid_address_arp_ndp(_a) (_a)->arp_ndp
#define gid_address_arp_ndp_bd(_a) lcaf_arp_ndp_bd(&gid_address_arp_ndp(_a))
#define gid_address_arp_ndp_ip(_a) lcaf_arp_ndp_ip(&gid_address_arp_ndp(_a))
#define gid_address_arp_ip4(_a) lcaf_arp_ndp_ip4(&gid_address_arp_ndp(_a))
#define gid_address_ndp_ip6(_a) lcaf_arp_ndp_ip6(&gid_address_arp_ndp(_a))
#define gid_address_ndp_bd gid_address_arp_ndp_bd
#define gid_address_arp_bd gid_address_arp_ndp_bd

/* 'sub'address functions */
#define foreach_gid_address_type_fcns  \
  _(no_addr)                      \
  _(ip_prefix)                    \
  _(lcaf)                         \
  _(mac)                          \
  _(nsh)                          \
  _(sd)

#define _(_n)                                 \
u16    _n ## _size_to_write (void * pref);    \
u16    _n ## _write (u8 * p, void * pref);    \
u8     _n ## _length (void *a);               \
void * _n ## _cast (gid_address_t * a);       \
void   _n ## _copy (void * dst , void * src);

foreach_gid_address_type_fcns
#undef _

always_inline u64
mac_to_u64 (u8 * m)
{
  return (*(u32 *) m) | ((u64) (*(u16 *) (m + 4)) << 32);
}

typedef struct
{
  /* mark locator as local as opposed to remote */
  u8 local;
  u8 state;
  union
  {
    u32 sw_if_index;
    gid_address_t address;
  };
  u8 priority;
  u8 weight;
  u8 mpriority;
  u8 mweight;
  u8 probed;
} locator_t;

u32 locator_parse (void *ptr, locator_t * loc);
void locator_copy (locator_t * dst, locator_t * src);
u32 locator_cmp (locator_t * l1, locator_t * l2);
void locator_free (locator_t * l);

typedef struct
{
  /* locator-set name */
  u8 *name;

  /* vector of locator indices */
  u32 *locator_indices;
  u8 local;
} locator_set_t;

typedef struct
{
  gid_address_t eid;

  /* index of local locator set */
  union
  {
    u32 locator_set_index;
    locator_t *locators;	/* used for map register message */
  };

  u32 ttl;
  u8 action;

  u8 authoritative:1;
  u8 local:1;
  /* valid only for remote mappings */
  u8 is_static:1;
  u8 pitr_set:1;
  u8 nsh_set:1;
  u8 almost_expired:1;
  u8 delete_after_expiration:1;
  u8 rsvd:1;

  u8 *key;
  lisp_key_type_t key_id;
  u8 timer_set;
  u32 timer_handle;
  counter_t packets;
} mapping_t;

uword
unformat_negative_mapping_action (unformat_input_t * input, va_list * args);
u8 *format_negative_mapping_action (u8 *, va_list * args);

typedef struct locator_pair
{
  /* local and remote locators (underlay attachment points) */
  ip_address_t lcl_loc;
  ip_address_t rmt_loc;

  u8 priority;
  u8 weight;
} locator_pair_t;

void
build_src_dst (gid_address_t * sd, gid_address_t * src, gid_address_t * dst);

void gid_address_from_ip (gid_address_t * g, ip_address_t * ip);
void gid_to_dp_address (gid_address_t * g, dp_address_t * d);

#endif /* VNET_LISP_GPE_LISP_TYPES_H_ */

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */