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 <vnet/lisp-cp/lisp_msg_serdes.h>
17 #include <vnet/lisp-cp/packets.h>
18 #include <vppinfra/time.h>
21 lisp_msg_put_gid (vlib_buffer_t * b, gid_address_t * gid)
23 u8 *p = vlib_buffer_put_uninit (b, gid_address_size_to_put (gid));
24 gid_address_put (p, gid);
29 lisp_msg_put_itr_rlocs (lisp_cp_main_t * lcm, vlib_buffer_t * b,
30 gid_address_t * rlocs, u8 * locs_put)
35 bp = vlib_buffer_get_current (b);
36 for (i = 0; i < vec_len (rlocs); i++)
38 lisp_msg_put_gid (b, &rlocs[i]);
42 *locs_put = count - 1;
47 lisp_msg_put_eid_rec (vlib_buffer_t * b, gid_address_t * eid)
49 eid_record_hdr_t *h = vlib_buffer_put_uninit (b, sizeof (*h));
51 memset (h, 0, sizeof (*h));
52 EID_REC_MLEN (h) = gid_address_len (eid);
53 lisp_msg_put_gid (b, eid);
58 nonce_build (u32 seed)
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);
71 /* OR in a caller provided seed to the low-order 32-bits. */
74 /* Return 64-bit nonce. */
76 nonce = (nonce << 32) | nonce_lower;
81 lisp_msg_put_mreq (lisp_cp_main_t * lcm, vlib_buffer_t * b,
82 gid_address_t * seid, gid_address_t * deid,
83 gid_address_t * rlocs, u8 is_smr_invoked, u64 * nonce)
87 /* Basic header init */
88 map_request_hdr_t *h = vlib_buffer_put_uninit (b, sizeof (h[0]));
90 memset (h, 0, sizeof (h[0]));
91 MREQ_TYPE (h) = LISP_MAP_REQUEST;
92 MREQ_NONCE (h) = nonce_build (0);
93 MREQ_SMR_INVOKED (h) = is_smr_invoked ? 1 : 0;
95 /* We're adding one eid record */
96 increment_record_count (h);
99 lisp_msg_put_gid (b, seid);
102 lisp_msg_put_itr_rlocs (lcm, b, rlocs, &loc_count);
103 MREQ_ITR_RLOC_COUNT (h) = loc_count;
106 lisp_msg_put_eid_rec (b, deid);
108 nonce[0] = MREQ_NONCE (h);
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)
117 ip_address_t _src_ip, *src_ip = &_src_ip, _dst_ip, *dst_ip = &_dst_ip;
118 if (gid_address_type (la) != GID_ADDR_IP_PREFIX)
121 memset (src_ip, 0, sizeof (src_ip[0]));
122 memset (dst_ip, 0, sizeof (dst_ip[0]));
126 src_ip = &gid_address_ip (la);
127 dst_ip = &gid_address_ip (ra);
130 /* Push inner ip and udp */
131 pkt_push_udp_and_ip (vm, b, lp, rp, src_ip, dst_ip);
133 /* Push lisp ecm hdr */
134 h = pkt_push_ecm_hdr (b);
140 msg_type_to_hdr_len (lisp_msg_type_e type)
144 case LISP_MAP_REQUEST:
145 return (sizeof (map_request_hdr_t));
147 return (sizeof (map_reply_hdr_t));
154 lisp_msg_pull_hdr (vlib_buffer_t * b, lisp_msg_type_e type)
156 return vlib_buffer_pull (b, msg_type_to_hdr_len (type));
160 lisp_msg_parse_addr (vlib_buffer_t * b, gid_address_t * eid)
163 memset (eid, 0, sizeof (*eid));
164 len = gid_address_parse (vlib_buffer_get_current (b), eid);
166 vlib_buffer_pull (b, len);
171 lisp_msg_parse_eid_rec (vlib_buffer_t * b, gid_address_t * eid)
173 eid_record_hdr_t *h = vlib_buffer_get_current (b);
175 memset (eid, 0, sizeof (*eid));
176 len = gid_address_parse (EID_REC_ADDR (h), eid);
180 gid_address_ippref_len (eid) = EID_REC_MLEN (h);
181 vlib_buffer_pull (b, len + sizeof (eid_record_hdr_t));
183 return len + sizeof (eid_record_hdr_t);
187 lisp_msg_parse_itr_rlocs (vlib_buffer_t * b, gid_address_t ** rlocs,
191 u32 i, len = 0, tlen = 0;
193 //MREQ_ITR_RLOC_COUNT(mreq_hdr) + 1
194 for (i = 0; i < rloc_count; i++)
196 len = lisp_msg_parse_addr (b, &tloc);
199 vec_add1 (*rlocs, tloc);
206 lisp_msg_parse_loc (vlib_buffer_t * b, locator_t * loc)
210 len = locator_parse (vlib_buffer_get_current (b), loc);
214 vlib_buffer_pull (b, len);
220 lisp_msg_parse_mapping_record (vlib_buffer_t * b, gid_address_t * eid,
221 locator_t ** locs, locator_t * probed_)
223 void *h = 0, *loc_hdr = 0;
224 locator_t loc, *probed = 0;
225 int i = 0, len = 0, llen = 0;
227 h = vlib_buffer_get_current (b);
228 vlib_buffer_pull (b, sizeof (mapping_record_hdr_t));
230 memset (eid, 0, sizeof (*eid));
231 len = gid_address_parse (vlib_buffer_get_current (b), eid);
235 vlib_buffer_pull (b, len);
236 if (GID_ADDR_IP_PREFIX == gid_address_type (eid))
237 gid_address_ippref_len (eid) = MAP_REC_EID_PLEN (h);
239 for (i = 0; i < MAP_REC_LOC_COUNT (h); i++)
241 loc_hdr = vlib_buffer_get_current (b);
243 llen = lisp_msg_parse_loc (b, &loc);
246 vec_add1 (*locs, loc);
249 if (LOC_PROBED (loc_hdr))
253 ("Multiple locators probed! Probing only the first!");
259 if (probed_ != 0 && probed)
262 return len + sizeof (map_reply_hdr_t);
266 * fd.io coding-style-patch-verification: ON
269 * eval: (c-set-style "gnu")