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
|
/*
* 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 <vnet/lisp-cp/lisp_cp_messages.h>
typedef enum
{
IP4,
IP6
} ip_address_type_t;
typedef CLIB_PACKED(struct ip_address
{
union
{
ip4_address_t v4;
ip6_address_t v6;
} ip;
u8 version;
}) ip_address_t;
#define ip_addr_addr(_a) (_a)->ip
#define ip_addr_v4(_a) (_a)->ip.v4
#define ip_addr_v6(_a) (_a)->ip.v6
#define ip_addr_version(_a) (_a)->version
int ip_address_cmp (ip_address_t * ip1, ip_address_t * ip2);
void ip_address_copy (ip_address_t * dst , ip_address_t * src);
void ip_address_copy_addr (void * dst , ip_address_t * src);
void ip_address_set(ip_address_t * dst, void * src, u8 version);
typedef CLIB_PACKED(struct ip_prefix
{
ip_address_t addr;
u8 len;
}) ip_prefix_t;
#define ip_prefix_addr(_a) (_a)->addr
#define ip_prefix_version(_a) ip_addr_version(&ip_prefix_addr(_a))
#define ip_prefix_len(_a) (_a)->len
#define ip_prefix_v4(_a) ip_addr_v4(&ip_prefix_addr(_a))
#define ip_prefix_v6(_a) ip_addr_v6(&ip_prefix_addr(_a))
void ip_prefix_normalize(ip_prefix_t * a);
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_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_TYPES
} lcaf_type_t;
struct _gid_address_t;
typedef struct
{
u8 src_len;
u8 dst_len;
struct _gid_address_t *src;
struct _gid_address_t *dst;
} source_dest_t;
#define SD_CAST (source_dest_t *)
#define sd_dst_gid(_a) (SD_CAST _a)->dst
#define sd_src_gid(_a) (SD_CAST _a)->src
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
{
/* the union needs to be at the beginning! */
union
{
source_dest_t sd;
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];
};
u8 type;
u32 vni;
u8 vni_mask;
} gid_address_t;
u8 * format_ip_address (u8 * s, va_list * args);
uword unformat_ip_address (unformat_input_t * input, va_list * args);
u8 * format_ip_prefix (u8 * s, va_list * args);
uword unformat_ip_prefix (unformat_input_t * input, va_list * args);
u8 * format_mac_address (u8 * s, va_list * args);
uword unformat_mac_address (unformat_input_t * input, va_list * args);
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_MAC = 6,
LISP_AFI_LCAF = 16387
} 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);
#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_vni(_a) (_a)->vni
#define gid_address_vni_mask(_a) (_a)->vni_mask
#define gid_address_sd_dest_pref(_a) \
gid_address_ippref(sd_dst_gid(_a))
#define gid_address_sd_source_pref(_a) \
gid_address_ippref(sd_src_gid(_a))
/* 'sub'address functions */
#define foreach_gid_address_type_fcns \
_(ip_prefix) \
_(lcaf) \
_(mac)
#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 _
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;
} 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 */
u32 locator_set_index;
u32 ttl;
u8 action;
u8 authoritative;
u8 local;
} mapping_t;
uword
unformat_negative_mapping_action (unformat_input_t * input, va_list * args);
#endif /* VNET_LISP_GPE_LISP_TYPES_H_ */
|