FD.io VPP  v19.01.2-3-gf61a1a8
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  lisp_msg_put_gid (b, &loc->address);
38  }
39 }
40 
41 static void
43 {
46  gid_address_t *eid = &record->eid;
47 
48  clib_memset (p, 0, sizeof (*p));
50  MAP_REC_TTL (p) = clib_host_to_net_u32 (MAP_REGISTER_DEFAULT_TTL);
51  MAP_REC_AUTH (p) = record->authoritative ? 1 : 0;
52  MAP_REC_LOC_COUNT (p) = vec_len (record->locators);
53 
54  lisp_msg_put_gid (b, eid);
55  lisp_msg_put_locators (b, record->locators);
56 }
57 
58 static void
60 {
61  u32 i;
62  for (i = 0; i < vec_len (records); i++)
63  lisp_msg_put_mapping_record (b, &records[i]);
64 }
65 
66 void *
68 {
69  u8 *p = 0;
70  if (!gid)
71  {
72  /* insert only src-eid-afi field set to 0 */
73  p = vlib_buffer_put_uninit (b, sizeof (u16));
74  *(u16 *) p = 0;
75  }
76  else
77  {
79  gid_address_put (p, gid);
80  }
81  return p;
82 }
83 
84 static void *
86  gid_address_t * rlocs, u8 * locs_put)
87 {
88  u8 *bp, count = 0;
89  u32 i;
90 
91  bp = vlib_buffer_get_current (b);
92  for (i = 0; i < vec_len (rlocs); i++)
93  {
94  lisp_msg_put_gid (b, &rlocs[i]);
95  count++;
96  }
97 
98  *locs_put = count - 1;
99  return bp;
100 }
101 
102 void *
104 {
105  eid_record_hdr_t *h = vlib_buffer_put_uninit (b, sizeof (*h));
106 
107  clib_memset (h, 0, sizeof (*h));
108  EID_REC_MLEN (h) = gid_address_len (eid);
109  lisp_msg_put_gid (b, eid);
110  return h;
111 }
112 
113 u64
115 {
116  u64 nonce;
117  u32 nonce_lower;
118  u32 nonce_upper;
119  struct timespec ts;
120 
121  /* Put nanosecond clock in lower 32-bits and put an XOR of the nanosecond
122  * clock with the second clock in the upper 32-bits. */
123  syscall (SYS_clock_gettime, CLOCK_REALTIME, &ts);
124  nonce_lower = ts.tv_nsec;
125  nonce_upper = ts.tv_sec ^ clib_host_to_net_u32 (nonce_lower);
126 
127  /* OR in a caller provided seed to the low-order 32-bits. */
128  nonce_lower |= seed;
129 
130  /* Return 64-bit nonce. */
131  nonce = nonce_upper;
132  nonce = (nonce << 32) | nonce_lower;
133  return nonce;
134 }
135 
136 void *
138  u8 probe_bit)
139 {
140  map_reply_hdr_t *h = vlib_buffer_put_uninit (b, sizeof (h[0]));
141 
142  clib_memset (h, 0, sizeof (h[0]));
144  MREP_NONCE (h) = nonce;
145  MREP_REC_COUNT (h) = 1;
146  MREP_RLOC_PROBE (h) = probe_bit;
147 
148  lisp_msg_put_mreg_records (b, records);
149  return h;
150 }
151 
152 void *
154  u8 want_map_notify, u16 auth_data_len, u64 * nonce,
155  u32 * msg_len)
156 {
157  u8 *auth_data = 0;
158 
159  /* Basic header init */
160  map_register_hdr_t *h = vlib_buffer_put_uninit (b, sizeof (h[0]));
161 
162  clib_memset (h, 0, sizeof (h[0]));
164  MREG_NONCE (h) = nonce_build (0);
165  MREG_WANT_MAP_NOTIFY (h) = want_map_notify ? 1 : 0;
166  MREG_REC_COUNT (h) = vec_len (records);
167 
168  auth_data = vlib_buffer_put_uninit (b, auth_data_len);
169  clib_memset (auth_data, 0, auth_data_len);
170 
171  /* Put map register records */
172  lisp_msg_put_mreg_records (b, records);
173 
174  nonce[0] = MREG_NONCE (h);
175  msg_len[0] = vlib_buffer_get_tail (b) - (u8 *) h;
176  return h;
177 }
178 
179 void *
181  gid_address_t * seid, gid_address_t * deid,
182  gid_address_t * rlocs, u8 is_smr_invoked,
183  u8 rloc_probe_set, u64 * nonce)
184 {
185  u8 loc_count = 0;
186 
187  /* Basic header init */
188  map_request_hdr_t *h = vlib_buffer_put_uninit (b, sizeof (h[0]));
189 
190  clib_memset (h, 0, sizeof (h[0]));
192  MREQ_NONCE (h) = nonce_build (0);
193  MREQ_SMR_INVOKED (h) = is_smr_invoked ? 1 : 0;
194  MREQ_RLOC_PROBE (h) = rloc_probe_set ? 1 : 0;
195 
196  /* We're adding one eid record */
198 
199  /* Fill source eid */
200  lisp_msg_put_gid (b, seid);
201 
202  /* Put itr rlocs */
203  lisp_msg_put_itr_rlocs (lcm, b, rlocs, &loc_count);
204  MREQ_ITR_RLOC_COUNT (h) = loc_count;
205 
206  /* Put eid record */
207  lisp_msg_put_eid_rec (b, deid);
208 
209  nonce[0] = MREQ_NONCE (h);
210  return h;
211 }
212 
213 void *
215  gid_address_t * la, gid_address_t * ra)
216 {
217  ecm_hdr_t *h;
218  ip_address_t _src_ip, *src_ip = &_src_ip, _dst_ip, *dst_ip = &_dst_ip;
220  {
221  /* empty ip4 */
222  clib_memset (src_ip, 0, sizeof (src_ip[0]));
223  clib_memset (dst_ip, 0, sizeof (dst_ip[0]));
224  }
225  else
226  {
227  src_ip = &gid_address_ip (la);
228  dst_ip = &gid_address_ip (ra);
229  }
230 
231  /* Push inner ip and udp */
232  pkt_push_udp_and_ip (vm, b, lp, rp, src_ip, dst_ip, 0);
233 
234  /* Push lisp ecm hdr */
235  h = pkt_push_ecm_hdr (b);
236 
237  return h;
238 }
239 
240 static u32
242 {
243  switch (type)
244  {
245  case LISP_MAP_REQUEST:
246  return (sizeof (map_request_hdr_t));
247  case LISP_MAP_REPLY:
248  return (sizeof (map_reply_hdr_t));
249  default:
250  return (0);
251  }
252 }
253 
254 void *
256 {
257  return vlib_buffer_pull (b, msg_type_to_hdr_len (type));
258 }
259 
260 u32
262 {
263  u32 len;
264  clib_memset (eid, 0, sizeof (*eid));
266  if (len != ~0)
267  vlib_buffer_pull (b, len);
268  return len;
269 }
270 
271 u32
273 {
275  u32 len;
276  clib_memset (eid, 0, sizeof (*eid));
277  len = gid_address_parse (EID_REC_ADDR (h), eid);
278  if (len == ~0)
279  return len;
280 
282  vlib_buffer_pull (b, len + sizeof (eid_record_hdr_t));
283 
284  return len + sizeof (eid_record_hdr_t);
285 }
286 
287 u32
289  u8 rloc_count)
290 {
291  gid_address_t tloc;
292  u32 i, len = 0, tlen = 0;
293 
294  //MREQ_ITR_RLOC_COUNT(mreq_hdr) + 1
295  for (i = 0; i < rloc_count; i++)
296  {
297  len = lisp_msg_parse_addr (b, &tloc);
298  if (len == ~0)
299  return len;
300  vec_add1 (*rlocs, tloc);
301  tlen += len;
302  }
303  return tlen;
304 }
305 
306 u32
308 {
309  int len;
310 
311  len = locator_parse (vlib_buffer_get_current (b), loc);
312  if (len == ~0)
313  return ~0;
314 
315  if (!vlib_buffer_has_space (b, sizeof (len)))
316  return ~0;
317  vlib_buffer_pull (b, len);
318 
319  return len;
320 }
321 
322 u32
324  locator_t ** locs, locator_t * probed_)
325 {
326  void *h = 0, *loc_hdr = 0;
327  locator_t loc, *probed = 0;
328  int i = 0, len = 0, llen = 0;
329 
330  h = vlib_buffer_get_current (b);
331  if (!vlib_buffer_has_space (b, sizeof (mapping_record_hdr_t)))
332  return ~0;
333 
335 
336  clib_memset (eid, 0, sizeof (*eid));
338  if (len == ~0)
339  return len;
340 
341  if (!vlib_buffer_has_space (b, sizeof (len)))
342  return ~0;
343 
344  vlib_buffer_pull (b, len);
347 
348  for (i = 0; i < MAP_REC_LOC_COUNT (h); i++)
349  {
350  loc_hdr = vlib_buffer_get_current (b);
351 
352  llen = lisp_msg_parse_loc (b, &loc);
353  if (llen == ~0)
354  return llen;
355  vec_add1 (*locs, loc);
356  len += llen;
357 
358  if (LOC_PROBED (loc_hdr))
359  {
360  if (probed != 0)
362  ("Multiple locators probed! Probing only the first!");
363  else
364  probed = &loc;
365  }
366  }
367  /* XXX */
368  if (probed_ != 0 && probed)
369  *probed_ = *probed;
370 
371  return len + sizeof (map_reply_hdr_t);
372 }
373 
374 /*
375  * fd.io coding-style-patch-verification: ON
376  *
377  * Local Variables:
378  * eval: (c-set-style "gnu")
379  * End:
380  */
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:295
boost::asio::ip::address ip_address_t
Definition: api_types.hpp:24
#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:525
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 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:214
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:301
#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:250
#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)
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:348
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:306
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_)