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 locator_set_t * loc_set, u8 * locs_put)
32 ip_interface_address_t * ia = 0;
38 u8 * p, * bp, count = 0;
40 bp = vlib_buffer_get_current(b);
41 for (i = 0; i < vec_len(loc_set->locator_indices); i++)
43 loc_indexp = vec_elt_at_index(loc_set->locator_indices, i);
44 loc = pool_elt_at_index (lcm->locator_pool, loc_indexp[0]);
46 /* Add ipv4 locators first TODO sort them */
47 foreach_ip_interface_address (&lcm->im4->lookup_main, ia,
48 loc->sw_if_index, 1 /* unnumbered */,
50 l4 = ip_interface_address_get_address (&lcm->im4->lookup_main, ia);
51 p = vlib_buffer_put_uninit (b, ip4_address_size_to_put());
52 ip4_address_put (p, l4);
56 /* Add ipv6 locators */
57 foreach_ip_interface_address (&lcm->im6->lookup_main, ia,
58 loc->sw_if_index, 1 /* unnumbered */,
60 l6 = ip_interface_address_get_address (&lcm->im6->lookup_main, ia);
61 p = vlib_buffer_put_uninit (b, ip6_address_size_to_put());
62 ip6_address_put (p, l6);
71 lisp_msg_put_eid_rec (vlib_buffer_t * b, gid_address_t * eid)
73 eid_record_hdr_t * h = vlib_buffer_put_uninit (b, sizeof (*h));
75 memset(h, 0, sizeof (*h));
76 EID_REC_MLEN (h) = gid_address_len (eid);
77 lisp_msg_put_gid (b, eid);
82 nonce_build (u32 seed)
89 /* Put nanosecond clock in lower 32-bits and put an XOR of the nanosecond
90 * clock with the seond clock in the upper 32-bits. */
91 syscall (SYS_clock_gettime, CLOCK_REALTIME, &ts);
92 nonce_lower = ts.tv_nsec;
93 nonce_upper = ts.tv_sec ^ clib_host_to_net_u32(nonce_lower);
95 /* OR in a caller provided seed to the low-order 32-bits. */
98 /* Return 64-bit nonce. */
100 nonce = (nonce << 32) | nonce_lower;
105 lisp_msg_put_mreq (lisp_cp_main_t * lcm, vlib_buffer_t * b,
106 gid_address_t * seid, gid_address_t * deid,
107 locator_set_t * loc_set, u8 is_smr_invoked, u64 * nonce)
111 /* Basic header init */
112 map_request_hdr_t * h = vlib_buffer_put_uninit (b, sizeof(h[0]));
114 memset(h, 0, sizeof(h[0]));
115 MREQ_TYPE(h) = LISP_MAP_REQUEST;
116 MREQ_NONCE(h) = nonce_build(0);
117 MREQ_SMR_INVOKED(h) = is_smr_invoked ? 1 : 0;
119 /* We're adding one eid record */
120 increment_record_count (h);
122 /* Fill source eid */
123 lisp_msg_put_gid (b, seid);
126 lisp_msg_put_itr_rlocs(lcm, b, loc_set, &loc_count);
127 MREQ_ITR_RLOC_COUNT(h) = loc_count;
130 lisp_msg_put_eid_rec(b, deid);
132 nonce[0] = MREQ_NONCE(h);
137 lisp_msg_push_ecm (vlib_main_t * vm, vlib_buffer_t *b, int lp, int rp,
138 gid_address_t *la, gid_address_t *ra)
141 ASSERT(gid_address_type(la) == IP_PREFIX);
143 /* Push inner ip and udp */
144 pkt_push_udp_and_ip (vm, b, lp, rp, &gid_address_ip(la),
145 &gid_address_ip(ra));
147 /* Push lisp ecm hdr */
148 h = pkt_push_ecm_hdr (b);
154 msg_type_to_hdr_len (lisp_msg_type_e type)
158 case LISP_MAP_REQUEST:
159 return (sizeof(map_request_hdr_t));
161 return (sizeof(map_reply_hdr_t));
168 lisp_msg_pull_hdr (vlib_buffer_t * b, lisp_msg_type_e type)
170 return vlib_buffer_pull (b, msg_type_to_hdr_len (type));
174 lisp_msg_parse_addr (vlib_buffer_t * b, gid_address_t * eid)
176 u32 len = gid_address_parse (vlib_buffer_get_current (b), eid);
178 vlib_buffer_pull (b, len);
183 lisp_msg_parse_eid_rec (vlib_buffer_t * b, gid_address_t * eid)
185 eid_record_hdr_t * h = vlib_buffer_get_current (b);
186 u32 len = gid_address_parse (EID_REC_ADDR(h), eid);
190 gid_address_ippref_len(eid) = EID_REC_MLEN(h);
191 vlib_buffer_pull (b, len + sizeof(eid_record_hdr_t));
193 return len + sizeof(eid_record_hdr_t);
197 lisp_msg_parse_itr_rlocs (vlib_buffer_t * b, gid_address_t ** rlocs,
201 u32 i, len = 0, tlen = 0;
203 //MREQ_ITR_RLOC_COUNT(mreq_hdr) + 1
204 for (i = 0; i < rloc_count; i++)
206 len = lisp_msg_parse_addr (b, &tloc);
209 vec_add1(*rlocs, tloc);
216 lisp_msg_parse_loc (vlib_buffer_t * b, locator_t * loc)
220 len = locator_parse (vlib_buffer_get_current (b), loc);
224 vlib_buffer_pull (b, len);
230 lisp_msg_parse_mapping_record (vlib_buffer_t * b, gid_address_t * eid,
231 locator_t ** locs, locator_t * probed_)
233 void * h = 0, * loc_hdr = 0;
234 locator_t loc, * probed = 0;
235 int i = 0, len = 0, llen = 0;
237 h = vlib_buffer_get_current (b);
238 vlib_buffer_pull (b, sizeof(mapping_record_hdr_t));
240 len = gid_address_parse (vlib_buffer_get_current (b), eid);
244 vlib_buffer_pull (b, len);
245 gid_address_ippref_len(eid) = MAP_REC_EID_PLEN(h);
247 for (i = 0; i < MAP_REC_LOC_COUNT(h); i++)
249 loc_hdr = vlib_buffer_get_current (b);
251 llen = lisp_msg_parse_loc (b, &loc);
254 vec_add1(*locs, loc);
257 if (LOC_PROBED(loc_hdr))
260 clib_warning("Multiple locators probed! Probing only the first!");
266 if (probed_ != 0 && probed)
269 return len + sizeof(map_reply_hdr_t);