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:
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 #include <lisp/lisp-cp/lisp_msg_serdes.h>
17 #include <lisp/lisp-cp/packets.h>
18 #include <vppinfra/time.h>
20 void *lisp_msg_put_gid (vlib_buffer_t * b, gid_address_t * gid);
23 lisp_msg_put_locators (vlib_buffer_t * b, locator_t * locators)
27 vec_foreach (loc, locators)
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);
43 lisp_msg_put_mapping_record (vlib_buffer_t * b, mapping_t * record)
45 mapping_record_hdr_t *p =
46 vlib_buffer_put_uninit (b, sizeof (mapping_record_hdr_t));
47 gid_address_t *eid = &record->eid;
49 clib_memset (p, 0, sizeof (*p));
50 MAP_REC_EID_PLEN (p) = gid_address_len (eid);
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);
55 lisp_msg_put_gid (b, eid);
56 lisp_msg_put_locators (b, record->locators);
60 lisp_msg_put_mreg_records (vlib_buffer_t * b, mapping_t * records)
63 for (i = 0; i < vec_len (records); i++)
64 lisp_msg_put_mapping_record (b, &records[i]);
68 lisp_msg_put_gid (vlib_buffer_t * b, gid_address_t * gid)
73 /* insert only src-eid-afi field set to 0 */
74 p = vlib_buffer_put_uninit (b, sizeof (u16));
79 p = vlib_buffer_put_uninit (b, gid_address_size_to_put (gid));
80 gid_address_put (p, gid);
86 lisp_msg_put_itr_rlocs (lisp_cp_main_t * lcm, vlib_buffer_t * b,
87 gid_address_t * rlocs, u8 * locs_put)
92 bp = vlib_buffer_get_current (b);
93 for (i = 0; i < vec_len (rlocs); i++)
95 lisp_msg_put_gid (b, &rlocs[i]);
99 *locs_put = count - 1;
104 lisp_msg_put_eid_rec (vlib_buffer_t * b, gid_address_t * eid)
106 eid_record_hdr_t *h = vlib_buffer_put_uninit (b, sizeof (*h));
108 clib_memset (h, 0, sizeof (*h));
109 EID_REC_MLEN (h) = gid_address_len (eid);
110 lisp_msg_put_gid (b, eid);
115 nonce_build (u32 seed)
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);
128 /* OR in a caller provided seed to the low-order 32-bits. */
131 /* Return 64-bit nonce. */
133 nonce = (nonce << 32) | nonce_lower;
138 lisp_msg_put_map_reply (vlib_buffer_t * b, mapping_t * records, u64 nonce,
141 map_reply_hdr_t *h = vlib_buffer_put_uninit (b, sizeof (h[0]));
143 clib_memset (h, 0, sizeof (h[0]));
144 MREP_TYPE (h) = LISP_MAP_REPLY;
145 MREP_NONCE (h) = nonce;
146 MREP_REC_COUNT (h) = 1;
147 MREP_RLOC_PROBE (h) = probe_bit;
149 lisp_msg_put_mreg_records (b, records);
154 lisp_msg_put_map_register (vlib_buffer_t * b, mapping_t * records,
155 u8 want_map_notify, u16 auth_data_len, u64 * nonce,
160 /* Basic header init */
161 map_register_hdr_t *h = vlib_buffer_put_uninit (b, sizeof (h[0]));
163 clib_memset (h, 0, sizeof (h[0]));
164 MREG_TYPE (h) = LISP_MAP_REGISTER;
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);
169 auth_data = vlib_buffer_put_uninit (b, auth_data_len);
170 clib_memset (auth_data, 0, auth_data_len);
172 /* Put map register records */
173 lisp_msg_put_mreg_records (b, records);
175 nonce[0] = MREG_NONCE (h);
176 msg_len[0] = vlib_buffer_get_tail (b) - (u8 *) h;
181 lisp_msg_put_mreq (lisp_cp_main_t * lcm, vlib_buffer_t * b,
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)
188 /* Basic header init */
189 map_request_hdr_t *h = vlib_buffer_put_uninit (b, sizeof (h[0]));
191 clib_memset (h, 0, sizeof (h[0]));
192 MREQ_TYPE (h) = LISP_MAP_REQUEST;
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;
197 /* We're adding one eid record */
198 increment_record_count (h);
200 /* Fill source eid */
201 lisp_msg_put_gid (b, seid);
204 lisp_msg_put_itr_rlocs (lcm, b, rlocs, &loc_count);
205 MREQ_ITR_RLOC_COUNT (h) = loc_count;
208 lisp_msg_put_eid_rec (b, deid);
210 nonce[0] = MREQ_NONCE (h);
215 lisp_msg_push_ecm (vlib_main_t * vm, vlib_buffer_t * b, int lp, int rp,
216 gid_address_t * la, gid_address_t * ra)
219 ip_address_t _src_ip, *src_ip = &_src_ip, _dst_ip, *dst_ip = &_dst_ip;
220 if (gid_address_type (la) != GID_ADDR_IP_PREFIX)
223 clib_memset (src_ip, 0, sizeof (src_ip[0]));
224 clib_memset (dst_ip, 0, sizeof (dst_ip[0]));
228 src_ip = &gid_address_ip (la);
229 dst_ip = &gid_address_ip (ra);
232 /* Push inner ip and udp */
233 pkt_push_udp_and_ip (vm, b, lp, rp, src_ip, dst_ip, 0);
235 /* Push lisp ecm hdr */
236 h = pkt_push_ecm_hdr (b);
242 msg_type_to_hdr_len (lisp_msg_type_e type)
246 case LISP_MAP_REQUEST:
247 return (sizeof (map_request_hdr_t));
249 return (sizeof (map_reply_hdr_t));
256 lisp_msg_pull_hdr (vlib_buffer_t * b, lisp_msg_type_e type)
258 return vlib_buffer_pull (b, msg_type_to_hdr_len (type));
262 lisp_msg_parse_addr (vlib_buffer_t * b, gid_address_t * eid)
265 clib_memset (eid, 0, sizeof (*eid));
266 len = gid_address_parse (vlib_buffer_get_current (b), eid);
267 if ((len != ~0) && vlib_buffer_pull (b, len))
278 lisp_msg_parse_eid_rec (vlib_buffer_t * b, gid_address_t * eid)
280 eid_record_hdr_t *h = vlib_buffer_get_current (b);
282 clib_memset (eid, 0, sizeof (*eid));
283 len = gid_address_parse (EID_REC_ADDR (h), eid);
287 gid_address_ippref_len (eid) = EID_REC_MLEN (h);
288 if (!vlib_buffer_pull (b, len + sizeof (eid_record_hdr_t)))
293 return len + sizeof (eid_record_hdr_t);
297 lisp_msg_parse_itr_rlocs (vlib_buffer_t * b, gid_address_t ** rlocs,
301 u32 i, len = 0, tlen = 0;
303 //MREQ_ITR_RLOC_COUNT(mreq_hdr) + 1
304 for (i = 0; i < rloc_count; i++)
306 len = lisp_msg_parse_addr (b, &tloc);
309 vec_add1 (*rlocs, tloc);
316 lisp_msg_parse_loc (vlib_buffer_t * b, locator_t * loc)
320 len = locator_parse (vlib_buffer_get_current (b), loc);
324 if (!vlib_buffer_has_space (b, sizeof (len)))
326 vlib_buffer_pull (b, len);
332 lisp_msg_parse_mapping_record (vlib_buffer_t * b, gid_address_t * eid,
333 locator_t ** locs, locator_t * probed_)
335 void *h = 0, *loc_hdr = 0;
336 locator_t loc, *probed = 0;
337 int i = 0, len = 0, llen = 0;
339 h = vlib_buffer_get_current (b);
340 if (!vlib_buffer_has_space (b, sizeof (mapping_record_hdr_t)))
343 vlib_buffer_pull (b, sizeof (mapping_record_hdr_t));
345 clib_memset (eid, 0, sizeof (*eid));
346 len = gid_address_parse (vlib_buffer_get_current (b), eid);
350 if (!vlib_buffer_has_space (b, sizeof (len)))
353 vlib_buffer_pull (b, len);
354 if (GID_ADDR_IP_PREFIX == gid_address_type (eid))
355 gid_address_ippref_len (eid) = MAP_REC_EID_PLEN (h);
357 for (i = 0; i < MAP_REC_LOC_COUNT (h); i++)
359 loc_hdr = vlib_buffer_get_current (b);
361 llen = lisp_msg_parse_loc (b, &loc);
364 vec_add1 (*locs, loc);
367 if (LOC_PROBED (loc_hdr))
371 ("Multiple locators probed! Probing only the first!");
377 if (probed_ != 0 && probed)
380 return len + sizeof (map_reply_hdr_t);
384 * fd.io coding-style-patch-verification: ON
387 * eval: (c-set-style "gnu")