FD.io VPP  v16.06
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 
20 void *
22 {
24  gid_address_put (p, gid);
25  return p;
26 }
27 
28 static void *
30  gid_address_t * rlocs, u8 * locs_put)
31 {
32  u8 * bp, count = 0;
33  u32 i;
34 
35  bp = vlib_buffer_get_current (b);
36  for (i = 0; i < vec_len (rlocs); i++)
37  {
38  lisp_msg_put_gid (b, &rlocs[i]);
39  count++;
40  }
41 
42  *locs_put = count-1;
43  return bp;
44 }
45 
46 void *
48 {
49  eid_record_hdr_t * h = vlib_buffer_put_uninit (b, sizeof (*h));
50 
51  memset(h, 0, sizeof (*h));
52  EID_REC_MLEN (h) = gid_address_len (eid);
53  lisp_msg_put_gid (b, eid);
54  return h;
55 }
56 
57 u64
59 {
60  u64 nonce;
61  u32 nonce_lower;
62  u32 nonce_upper;
63  struct timespec ts;
64 
65  /* Put nanosecond clock in lower 32-bits and put an XOR of the nanosecond
66  * clock with the seond clock in the upper 32-bits. */
67  syscall (SYS_clock_gettime, CLOCK_REALTIME, &ts);
68  nonce_lower = ts.tv_nsec;
69  nonce_upper = ts.tv_sec ^ clib_host_to_net_u32(nonce_lower);
70 
71  /* OR in a caller provided seed to the low-order 32-bits. */
72  nonce_lower |= seed;
73 
74  /* Return 64-bit nonce. */
75  nonce = nonce_upper;
76  nonce = (nonce << 32) | nonce_lower;
77  return nonce;
78 }
79 
80 void *
82  gid_address_t * seid, gid_address_t * deid,
83  gid_address_t * rlocs, u8 is_smr_invoked, u64 * nonce)
84 {
85  u8 loc_count = 0;
86 
87  /* Basic header init */
88  map_request_hdr_t * h = vlib_buffer_put_uninit (b, sizeof(h[0]));
89 
90  memset(h, 0, sizeof(h[0]));
92  MREQ_NONCE(h) = nonce_build(0);
93  MREQ_SMR_INVOKED(h) = is_smr_invoked ? 1 : 0;
94 
95  /* We're adding one eid record */
97 
98  /* Fill source eid */
99  lisp_msg_put_gid (b, seid);
100 
101  /* Put itr rlocs */
102  lisp_msg_put_itr_rlocs(lcm, b, rlocs, &loc_count);
103  MREQ_ITR_RLOC_COUNT(h) = loc_count;
104 
105  /* Put eid record */
106  lisp_msg_put_eid_rec(b, deid);
107 
108  nonce[0] = MREQ_NONCE(h);
109  return h;
110 }
111 
112 void *
113 lisp_msg_push_ecm (vlib_main_t * vm, vlib_buffer_t *b, int lp, int rp,
114  gid_address_t *la, gid_address_t *ra)
115 {
116  ecm_hdr_t *h;
118 
119  /* Push inner ip and udp */
120  pkt_push_udp_and_ip (vm, b, lp, rp, &gid_address_ip(la),
121  &gid_address_ip(ra));
122 
123  /* Push lisp ecm hdr */
124  h = pkt_push_ecm_hdr (b);
125 
126  return h;
127 }
128 
129 static u32
131 {
132  switch (type)
133  {
134  case LISP_MAP_REQUEST:
135  return (sizeof(map_request_hdr_t));
136  case LISP_MAP_REPLY:
137  return (sizeof(map_reply_hdr_t));
138  default:
139  return (0);
140  }
141 }
142 
143 void *
145 {
146  return vlib_buffer_pull (b, msg_type_to_hdr_len (type));
147 }
148 
149 u32
151 {
153  if (len != ~0)
154  vlib_buffer_pull (b, len);
155  return len;
156 }
157 
158 u32
160 {
162  u32 len = gid_address_parse (EID_REC_ADDR(h), eid);
163  if (len == ~0)
164  return len;
165 
167  vlib_buffer_pull (b, len + sizeof(eid_record_hdr_t));
168 
169  return len + sizeof(eid_record_hdr_t);
170 }
171 
172 u32
174  u8 rloc_count)
175 {
176  gid_address_t tloc;
177  u32 i, len = 0, tlen = 0;
178 
179  //MREQ_ITR_RLOC_COUNT(mreq_hdr) + 1
180  for (i = 0; i < rloc_count; i++)
181  {
182  len = lisp_msg_parse_addr (b, &tloc);
183  if (len == ~0)
184  return len;
185  vec_add1(*rlocs, tloc);
186  tlen += len;
187  }
188  return tlen;
189 }
190 
191 u32
193 {
194  int len;
195 
196  len = locator_parse (vlib_buffer_get_current (b), loc);
197  if (len == ~0)
198  return ~0;
199 
200  vlib_buffer_pull (b, len);
201 
202  return len;
203 }
204 
205 u32
207  locator_t ** locs, locator_t * probed_)
208 {
209  void * h = 0, * loc_hdr = 0;
210  locator_t loc, * probed = 0;
211  int i = 0, len = 0, llen = 0;
212 
213  h = vlib_buffer_get_current (b);
215 
217  if (len == ~0)
218  return len;
219 
220  vlib_buffer_pull (b, len);
222 
223  for (i = 0; i < MAP_REC_LOC_COUNT(h); i++)
224  {
225  loc_hdr = vlib_buffer_get_current (b);
226 
227  llen = lisp_msg_parse_loc (b, &loc);
228  if (llen == ~0)
229  return llen;
230  vec_add1(*locs, loc);
231  len += llen;
232 
233  if (LOC_PROBED(loc_hdr))
234  {
235  if (probed != 0)
236  clib_warning("Multiple locators probed! Probing only the first!");
237  else
238  probed = &loc;
239  }
240  }
241  /* XXX */
242  if (probed_ != 0 && probed)
243  *probed_ = *probed;
244 
245  return len + sizeof(map_reply_hdr_t);
246 }
#define MREQ_ITR_RLOC_COUNT(h_)
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:267
#define gid_address_type(_a)
Definition: lisp_types.h:161
bad routing header type(not 4)") sr_error (NO_MORE_SEGMENTS
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)
Definition: packets.c:222
#define MAP_REC_EID_PLEN(h)
#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:480
static u32 msg_type_to_hdr_len(lisp_msg_type_e type)
#define EID_REC_ADDR(h)
always_inline void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:184
always_inline void increment_record_count(void *b)
#define MREQ_NONCE(h_)
u32 locator_parse(void *b, locator_t *loc)
Definition: lisp_types.c:765
u16 gid_address_put(u8 *b, gid_address_t *gid)
Definition: lisp_types.c:636
u16 gid_address_size_to_put(gid_address_t *gid)
Definition: lisp_types.c:643
#define clib_warning(format, args...)
Definition: error.h:59
unsigned long u64
Definition: types.h:89
#define MREQ_TYPE(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, u64 *nonce)
u32 lisp_msg_parse_addr(vlib_buffer_t *b, gid_address_t *eid)
always_inline void * vlib_buffer_put_uninit(vlib_buffer_t *b, u8 size)
Definition: packets.h:39
u32 lisp_msg_parse_itr_rlocs(vlib_buffer_t *b, gid_address_t **rlocs, u8 rloc_count)
#define LOC_PROBED(h_)
u64 nonce_build(u32 seed)
#define gid_address_ippref_len(_a)
Definition: lisp_types.h:163
u32 lisp_msg_parse_mapping_record(vlib_buffer_t *b, gid_address_t *eid, locator_t **locs, locator_t *probed_)
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)
struct _mapping_record_hdr_t mapping_record_hdr_t
struct _gid_address_t gid_address_t
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
always_inline void * vlib_buffer_pull(vlib_buffer_t *b, u8 size)
Definition: packets.h:67
#define MAP_REC_LOC_COUNT(h)
#define gid_address_ip(_a)
Definition: lisp_types.h:164
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)
unsigned char u8
Definition: types.h:56
u8 gid_address_len(gid_address_t *a)
Definition: lisp_types.c:629
void * lisp_msg_pull_hdr(vlib_buffer_t *b, lisp_msg_type_e type)
u32 lisp_msg_parse_eid_rec(vlib_buffer_t *b, gid_address_t *eid)
u32 gid_address_parse(u8 *offset, gid_address_t *a)
Definition: lisp_types.c:664
static void * lisp_msg_put_itr_rlocs(lisp_cp_main_t *lcm, vlib_buffer_t *b, gid_address_t *rlocs, u8 *locs_put)
void * pkt_push_ecm_hdr(vlib_buffer_t *b)
Definition: packets.c:245
void * lisp_msg_put_gid(vlib_buffer_t *b, gid_address_t *gid)
lisp_msg_type_e
#define MREQ_SMR_INVOKED(h_)