FD.io VPP  v19.04.2-12-g66b1689
Vector Packet Processing
lisp_msg_serdes.c
Go to the documentation of this file.
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 
17 #include <vnet/lisp-cp/packets.h>
18 #include <vppinfra/time.h>
19 
21 
22 static void
24 {
25  locator_t *loc;
26 
27  vec_foreach (loc, locators)
28  {
29  u8 *p = vlib_buffer_put_uninit (b, sizeof (locator_hdr_t));
30  clib_memset (p, 0, sizeof (locator_hdr_t));
31  LOC_PRIORITY (p) = loc->priority;
32  LOC_MPRIORITY (p) = loc->mpriority;
33  LOC_WEIGHT (p) = loc->weight;
34  LOC_MWEIGHT (p) = loc->mweight;
35  LOC_LOCAL (p) = loc->local;
36  LOC_PROBED (p) = loc->probed ? 1 : 0;
37  LOC_REACHABLE (p) = loc->state ? 1 : 0;
38  lisp_msg_put_gid (b, &loc->address);
39  }
40 }
41 
42 static void
44 {
47  gid_address_t *eid = &record->eid;
48 
49  clib_memset (p, 0, sizeof (*p));
51  MAP_REC_TTL (p) = clib_host_to_net_u32 (MAP_REGISTER_DEFAULT_TTL);
52  MAP_REC_AUTH (p) = record->authoritative ? 1 : 0;
53  MAP_REC_LOC_COUNT (p) = vec_len (record->locators);
54 
55  lisp_msg_put_gid (b, eid);
56  lisp_msg_put_locators (b, record->locators);
57 }
58 
59 static void
61 {
62  u32 i;
63  for (i = 0; i < vec_len (records); i++)
64  lisp_msg_put_mapping_record (b, &records[i]);
65 }
66 
67 void *
69 {
70  u8 *p = 0;
71  if (!gid)
72  {
73  /* insert only src-eid-afi field set to 0 */
74  p = vlib_buffer_put_uninit (b, sizeof (u16));
75  *(u16 *) p = 0;
76  }
77  else
78  {
80  gid_address_put (p, gid);
81  }
82  return p;
83 }
84 
85 static void *
87  gid_address_t * rlocs, u8 * locs_put)
88 {
89  u8 *bp, count = 0;
90  u32 i;
91 
92  bp = vlib_buffer_get_current (b);
93  for (i = 0; i < vec_len (rlocs); i++)
94  {
95  lisp_msg_put_gid (b, &rlocs[i]);
96  count++;
97  }
98 
99  *locs_put = count - 1;
100  return bp;
101 }
102 
103 void *
105 {
106  eid_record_hdr_t *h = vlib_buffer_put_uninit (b, sizeof (*h));
107 
108  clib_memset (h, 0, sizeof (*h));
109  EID_REC_MLEN (h) = gid_address_len (eid);
110  lisp_msg_put_gid (b, eid);
111  return h;
112 }
113 
114 u64
116 {
117  u64 nonce;
118  u32 nonce_lower;
119  u32 nonce_upper;
120  struct timespec ts;
121 
122  /* Put nanosecond clock in lower 32-bits and put an XOR of the nanosecond
123  * clock with the second clock in the upper 32-bits. */
124  syscall (SYS_clock_gettime, CLOCK_REALTIME, &ts);
125  nonce_lower = ts.tv_nsec;
126  nonce_upper = ts.tv_sec ^ clib_host_to_net_u32 (nonce_lower);
127 
128  /* OR in a caller provided seed to the low-order 32-bits. */
129  nonce_lower |= seed;
130 
131  /* Return 64-bit nonce. */
132  nonce = nonce_upper;
133  nonce = (nonce << 32) | nonce_lower;
134  return nonce;
135 }
136 
137 void *
139  u8 probe_bit)
140 {
141  map_reply_hdr_t *h = vlib_buffer_put_uninit (b, sizeof (h[0]));
142 
143  clib_memset (h, 0, sizeof (h[0]));
145  MREP_NONCE (h) = nonce;
146  MREP_REC_COUNT (h) = 1;
147  MREP_RLOC_PROBE (h) = probe_bit;
148 
149  lisp_msg_put_mreg_records (b, records);
150  return h;
151 }
152 
153 void *
155  u8 want_map_notify, u16 auth_data_len, u64 * nonce,
156  u32 * msg_len)
157 {
158  u8 *auth_data = 0;
159 
160  /* Basic header init */
161  map_register_hdr_t *h = vlib_buffer_put_uninit (b, sizeof (h[0]));
162 
163  clib_memset (h, 0, sizeof (h[0]));
165  MREG_NONCE (h) = nonce_build (0);
166  MREG_WANT_MAP_NOTIFY (h) = want_map_notify ? 1 : 0;
167  MREG_REC_COUNT (h) = vec_len (records);
168 
169  auth_data = vlib_buffer_put_uninit (b, auth_data_len);
170  clib_memset (auth_data, 0, auth_data_len);
171 
172  /* Put map register records */
173  lisp_msg_put_mreg_records (b, records);
174 
175  nonce[0] = MREG_NONCE (h);
176  msg_len[0] = vlib_buffer_get_tail (b) - (u8 *) h;
177  return h;
178 }
179 
180 void *
182  gid_address_t * seid, gid_address_t * deid,
183  gid_address_t * rlocs, u8 is_smr_invoked,
184  u8 rloc_probe_set, u64 * nonce)
185 {
186  u8 loc_count = 0;
187 
188  /* Basic header init */
189  map_request_hdr_t *h = vlib_buffer_put_uninit (b, sizeof (h[0]));
190 
191  clib_memset (h, 0, sizeof (h[0]));
193  MREQ_NONCE (h) = nonce_build (0);
194  MREQ_SMR_INVOKED (h) = is_smr_invoked ? 1 : 0;
195  MREQ_RLOC_PROBE (h) = rloc_probe_set ? 1 : 0;
196 
197  /* We're adding one eid record */
199 
200  /* Fill source eid */
201  lisp_msg_put_gid (b, seid);
202 
203  /* Put itr rlocs */
204  lisp_msg_put_itr_rlocs (lcm, b, rlocs, &loc_count);
205  MREQ_ITR_RLOC_COUNT (h) = loc_count;
206 
207  /* Put eid record */
208  lisp_msg_put_eid_rec (b, deid);
209 
210  nonce[0] = MREQ_NONCE (h);
211  return h;
212 }
213 
214 void *
216  gid_address_t * la, gid_address_t * ra)
217 {
218  ecm_hdr_t *h;
219  ip_address_t _src_ip, *src_ip = &_src_ip, _dst_ip, *dst_ip = &_dst_ip;
221  {
222  /* empty ip4 */
223  clib_memset (src_ip, 0, sizeof (src_ip[0]));
224  clib_memset (dst_ip, 0, sizeof (dst_ip[0]));
225  }
226  else
227  {
228  src_ip = &gid_address_ip (la);
229  dst_ip = &gid_address_ip (ra);
230  }
231 
232  /* Push inner ip and udp */
233  pkt_push_udp_and_ip (vm, b, lp, rp, src_ip, dst_ip, 0);
234 
235  /* Push lisp ecm hdr */
236  h = pkt_push_ecm_hdr (b);
237 
238  return h;
239 }
240 
241 static u32
243 {
244  switch (type)
245  {
246  case LISP_MAP_REQUEST:
247  return (sizeof (map_request_hdr_t));
248  case LISP_MAP_REPLY:
249  return (sizeof (map_reply_hdr_t));
250  default:
251  return (0);
252  }
253 }
254 
255 void *
257 {
258  return vlib_buffer_pull (b, msg_type_to_hdr_len (type));
259 }
260 
261 u32
263 {
264  u32 len;
265  clib_memset (eid, 0, sizeof (*eid));
267  if (len != ~0)
268  vlib_buffer_pull (b, len);
269  return len;
270 }
271 
272 u32
274 {
276  u32 len;
277  clib_memset (eid, 0, sizeof (*eid));
278  len = gid_address_parse (EID_REC_ADDR (h), eid);
279  if (len == ~0)
280  return len;
281 
283  vlib_buffer_pull (b, len + sizeof (eid_record_hdr_t));
284 
285  return len + sizeof (eid_record_hdr_t);
286 }
287 
288 u32
290  u8 rloc_count)
291 {
292  gid_address_t tloc;
293  u32 i, len = 0, tlen = 0;
294 
295  //MREQ_ITR_RLOC_COUNT(mreq_hdr) + 1
296  for (i = 0; i < rloc_count; i++)
297  {
298  len = lisp_msg_parse_addr (b, &tloc);
299  if (len == ~0)
300  return len;
301  vec_add1 (*rlocs, tloc);
302  tlen += len;
303  }
304  return tlen;
305 }
306 
307 u32
309 {
310  int len;
311 
312  len = locator_parse (vlib_buffer_get_current (b), loc);
313  if (len == ~0)
314  return ~0;
315 
316  if (!vlib_buffer_has_space (b, sizeof (len)))
317  return ~0;
318  vlib_buffer_pull (b, len);
319 
320  return len;
321 }
322 
323 u32
325  locator_t ** locs, locator_t * probed_)
326 {
327  void *h = 0, *loc_hdr = 0;
328  locator_t loc, *probed = 0;
329  int i = 0, len = 0, llen = 0;
330 
331  h = vlib_buffer_get_current (b);
332  if (!vlib_buffer_has_space (b, sizeof (mapping_record_hdr_t)))
333  return ~0;
334 
336 
337  clib_memset (eid, 0, sizeof (*eid));
339  if (len == ~0)
340  return len;
341 
342  if (!vlib_buffer_has_space (b, sizeof (len)))
343  return ~0;
344 
345  vlib_buffer_pull (b, len);
348 
349  for (i = 0; i < MAP_REC_LOC_COUNT (h); i++)
350  {
351  loc_hdr = vlib_buffer_get_current (b);
352 
353  llen = lisp_msg_parse_loc (b, &loc);
354  if (llen == ~0)
355  return llen;
356  vec_add1 (*locs, loc);
357  len += llen;
358 
359  if (LOC_PROBED (loc_hdr))
360  {
361  if (probed != 0)
363  ("Multiple locators probed! Probing only the first!");
364  else
365  probed = &loc;
366  }
367  }
368  /* XXX */
369  if (probed_ != 0 && probed)
370  *probed_ = *probed;
371 
372  return len + sizeof (map_reply_hdr_t);
373 }
374 
375 /*
376  * fd.io coding-style-patch-verification: ON
377  *
378  * Local Variables:
379  * eval: (c-set-style "gnu")
380  * End:
381  */
struct _mapping_record_hdr_t mapping_record_hdr_t
#define MREQ_ITR_RLOC_COUNT(h_)
void * lisp_msg_put_mreq(lisp_cp_main_t *lcm, vlib_buffer_t *b, gid_address_t *seid, gid_address_t *deid, gid_address_t *rlocs, u8 is_smr_invoked, u8 rloc_probe_set, u64 *nonce)
void * lisp_msg_put_map_register(vlib_buffer_t *b, mapping_t *records, u8 want_map_notify, u16 auth_data_len, u64 *nonce, u32 *msg_len)
#define MREP_REC_COUNT(h_)
static u8 * vlib_buffer_get_tail(vlib_buffer_t *b)
Get pointer to the end of buffer&#39;s data.
Definition: buffer.h:310
boost::asio::ip::address ip_address_t
Definition: api_types.hpp:25
#define gid_address_type(_a)
Definition: lisp_types.h:259
#define MAP_REC_TTL(h)
#define MREP_TYPE(h_)
static void increment_record_count(void *b)
unsigned long u64
Definition: types.h:89
#define LOC_LOCAL(h_)
#define MAP_REC_EID_PLEN(h)
static void lisp_msg_put_mapping_record(vlib_buffer_t *b, mapping_t *record)
#define EID_REC_MLEN(h_)
struct _eid_prefix_record_hdr eid_record_hdr_t
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:522
void * lisp_msg_put_gid(vlib_buffer_t *b, gid_address_t *gid)
int i
u8 mpriority
Definition: lisp_types.h:327
clib_memset(h->entries, 0, sizeof(h->entries[0])*entries)
static u32 msg_type_to_hdr_len(lisp_msg_type_e type)
#define EID_REC_ADDR(h)
unsigned char u8
Definition: types.h:56
#define LOC_REACHABLE(h_)
#define MREQ_NONCE(h_)
u32 locator_parse(void *b, locator_t *loc)
Definition: lisp_types.c:1668
#define LOC_MWEIGHT(h_)
u16 gid_address_put(u8 *b, gid_address_t *gid)
Definition: lisp_types.c:1448
u16 gid_address_size_to_put(gid_address_t *gid)
Definition: lisp_types.c:1464
static void lisp_msg_put_mreg_records(vlib_buffer_t *b, mapping_t *records)
unsigned int u32
Definition: types.h:88
#define MREQ_TYPE(h_)
#define MREQ_RLOC_PROBE(h_)
#define LOC_PRIORITY(h_)
#define MREG_REC_COUNT(h_)
#define MAP_REC_AUTH(h)
unsigned short u16
Definition: types.h:57
u32 lisp_msg_parse_addr(vlib_buffer_t *b, gid_address_t *eid)
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:229
u8 authoritative
Definition: lisp_types.h:361
#define MREG_NONCE(h_)
void * pkt_push_udp_and_ip(vlib_main_t *vm, vlib_buffer_t *b, u16 sp, u16 dp, ip_address_t *sip, ip_address_t *dip, u8 csum_offload)
Definition: packets.c:171
u8 len
Definition: ip_types.api:49
#define MREG_TYPE(h_)
u32 lisp_msg_parse_itr_rlocs(vlib_buffer_t *b, gid_address_t **rlocs, u8 rloc_count)
vlib_main_t * vm
Definition: buffer.c:312
#define LOC_PROBED(h_)
u64 nonce_build(u32 seed)
#define gid_address_ippref_len(_a)
Definition: lisp_types.h:261
u32 lisp_msg_parse_mapping_record(vlib_buffer_t *b, gid_address_t *eid, locator_t **locs, locator_t *probed_)
#define clib_warning(format, args...)
Definition: error.h:59
void * lisp_msg_put_eid_rec(vlib_buffer_t *b, gid_address_t *eid)
void * lisp_msg_push_ecm(vlib_main_t *vm, vlib_buffer_t *b, int lp, int rp, gid_address_t *la, gid_address_t *ra)
void * lisp_msg_put_map_reply(vlib_buffer_t *b, mapping_t *records, u64 nonce, u8 probe_bit)
struct _gid_address_t gid_address_t
#define MAP_REC_LOC_COUNT(h)
struct _locator_hdr locator_hdr_t
size_t count
Definition: vapi.c:47
vl_api_address_t src_ip
Definition: udp.api:43
#define gid_address_ip(_a)
Definition: lisp_types.h:262
static u8 vlib_buffer_has_space(vlib_buffer_t *b, word l)
Check if there is enough space in buffer to advance.
Definition: buffer.h:265
#define LOC_WEIGHT(h_)
u32 lisp_msg_parse_loc(vlib_buffer_t *b, locator_t *loc)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
VLIB buffer representation.
Definition: buffer.h:102
u8 gid_address_len(gid_address_t *a)
Definition: lisp_types.c:1434
void * lisp_msg_pull_hdr(vlib_buffer_t *b, lisp_msg_type_e type)
#define LOC_MPRIORITY(h_)
gid_address_t eid
Definition: lisp_types.h:349
gid_address_t address
Definition: lisp_types.h:323
vl_api_address_t dst_ip
Definition: udp.api:44
u32 lisp_msg_parse_eid_rec(vlib_buffer_t *b, gid_address_t *eid)
#define vec_foreach(var, vec)
Vector iterator.
static void * vlib_buffer_pull(vlib_buffer_t *b, u8 size)
Retrieve bytes from buffer head.
Definition: buffer.h:363
u32 gid_address_parse(u8 *offset, gid_address_t *a)
Definition: lisp_types.c:1499
static void * vlib_buffer_put_uninit(vlib_buffer_t *b, u16 size)
Append uninitialized data to buffer.
Definition: buffer.h:321
static void * lisp_msg_put_itr_rlocs(lisp_cp_main_t *lcm, vlib_buffer_t *b, gid_address_t *rlocs, u8 *locs_put)
#define MREP_NONCE(h_)
void * pkt_push_ecm_hdr(vlib_buffer_t *b)
Definition: packets.c:206
static void lisp_msg_put_locators(vlib_buffer_t *b, locator_t *locators)
#define MREP_RLOC_PROBE(h_)
#define MAP_REGISTER_DEFAULT_TTL
Definition: control.h:45
lisp_msg_type_e
#define MREQ_SMR_INVOKED(h_)
locator_t * locators
Definition: lisp_types.h:355
#define MREG_WANT_MAP_NOTIFY(h_)