LCOV - code coverage report
Current view: top level - plugins/lisp/lisp-cp - lisp_msg_serdes.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 0 180 0.0 %
Date: 2023-07-05 22:20:52 Functions: 0 18 0.0 %

          Line data    Source code
       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             : 
      16             : #include <lisp/lisp-cp/lisp_msg_serdes.h>
      17             : #include <lisp/lisp-cp/packets.h>
      18             : #include <vppinfra/time.h>
      19             : 
      20             : void *lisp_msg_put_gid (vlib_buffer_t * b, gid_address_t * gid);
      21             : 
      22             : static void
      23           0 : lisp_msg_put_locators (vlib_buffer_t * b, locator_t * locators)
      24             : {
      25             :   locator_t *loc;
      26             : 
      27           0 :   vec_foreach (loc, locators)
      28             :   {
      29           0 :     u8 *p = vlib_buffer_put_uninit (b, sizeof (locator_hdr_t));
      30           0 :     clib_memset (p, 0, sizeof (locator_hdr_t));
      31           0 :     LOC_PRIORITY (p) = loc->priority;
      32           0 :     LOC_MPRIORITY (p) = loc->mpriority;
      33           0 :     LOC_WEIGHT (p) = loc->weight;
      34           0 :     LOC_MWEIGHT (p) = loc->mweight;
      35           0 :     LOC_LOCAL (p) = loc->local;
      36           0 :     LOC_PROBED (p) = loc->probed ? 1 : 0;
      37           0 :     LOC_REACHABLE (p) = loc->state ? 1 : 0;
      38           0 :     lisp_msg_put_gid (b, &loc->address);
      39             :   }
      40           0 : }
      41             : 
      42             : static void
      43           0 : lisp_msg_put_mapping_record (vlib_buffer_t * b, mapping_t * record)
      44             : {
      45             :   mapping_record_hdr_t *p =
      46           0 :     vlib_buffer_put_uninit (b, sizeof (mapping_record_hdr_t));
      47           0 :   gid_address_t *eid = &record->eid;
      48             : 
      49           0 :   clib_memset (p, 0, sizeof (*p));
      50           0 :   MAP_REC_EID_PLEN (p) = gid_address_len (eid);
      51           0 :   MAP_REC_TTL (p) = clib_host_to_net_u32 (MAP_REGISTER_DEFAULT_TTL);
      52           0 :   MAP_REC_AUTH (p) = record->authoritative ? 1 : 0;
      53           0 :   MAP_REC_LOC_COUNT (p) = vec_len (record->locators);
      54             : 
      55           0 :   lisp_msg_put_gid (b, eid);
      56           0 :   lisp_msg_put_locators (b, record->locators);
      57           0 : }
      58             : 
      59             : static void
      60           0 : lisp_msg_put_mreg_records (vlib_buffer_t * b, mapping_t * records)
      61             : {
      62             :   u32 i;
      63           0 :   for (i = 0; i < vec_len (records); i++)
      64           0 :     lisp_msg_put_mapping_record (b, &records[i]);
      65           0 : }
      66             : 
      67             : void *
      68           0 : lisp_msg_put_gid (vlib_buffer_t * b, gid_address_t * gid)
      69             : {
      70           0 :   u8 *p = 0;
      71           0 :   if (!gid)
      72             :     {
      73             :       /* insert only src-eid-afi field set to 0 */
      74           0 :       p = vlib_buffer_put_uninit (b, sizeof (u16));
      75           0 :       *(u16 *) p = 0;
      76             :     }
      77             :   else
      78             :     {
      79           0 :       p = vlib_buffer_put_uninit (b, gid_address_size_to_put (gid));
      80           0 :       gid_address_put (p, gid);
      81             :     }
      82           0 :   return p;
      83             : }
      84             : 
      85             : static void *
      86           0 : lisp_msg_put_itr_rlocs (lisp_cp_main_t * lcm, vlib_buffer_t * b,
      87             :                         gid_address_t * rlocs, u8 * locs_put)
      88             : {
      89           0 :   u8 *bp, count = 0;
      90             :   u32 i;
      91             : 
      92           0 :   bp = vlib_buffer_get_current (b);
      93           0 :   for (i = 0; i < vec_len (rlocs); i++)
      94             :     {
      95           0 :       lisp_msg_put_gid (b, &rlocs[i]);
      96           0 :       count++;
      97             :     }
      98             : 
      99           0 :   *locs_put = count - 1;
     100           0 :   return bp;
     101             : }
     102             : 
     103             : void *
     104           0 : lisp_msg_put_eid_rec (vlib_buffer_t * b, gid_address_t * eid)
     105             : {
     106           0 :   eid_record_hdr_t *h = vlib_buffer_put_uninit (b, sizeof (*h));
     107             : 
     108           0 :   clib_memset (h, 0, sizeof (*h));
     109           0 :   EID_REC_MLEN (h) = gid_address_len (eid);
     110           0 :   lisp_msg_put_gid (b, eid);
     111           0 :   return h;
     112             : }
     113             : 
     114             : u64
     115           0 : nonce_build (u32 seed)
     116             : {
     117             :   u64 nonce;
     118             :   u32 nonce_lower;
     119             :   u32 nonce_upper;
     120             :   struct timespec ts;
     121             : 
     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           0 :   syscall (SYS_clock_gettime, CLOCK_REALTIME, &ts);
     125           0 :   nonce_lower = ts.tv_nsec;
     126           0 :   nonce_upper = ts.tv_sec ^ clib_host_to_net_u32 (nonce_lower);
     127             : 
     128             :   /* OR in a caller provided seed to the low-order 32-bits. */
     129           0 :   nonce_lower |= seed;
     130             : 
     131             :   /* Return 64-bit nonce. */
     132           0 :   nonce = nonce_upper;
     133           0 :   nonce = (nonce << 32) | nonce_lower;
     134           0 :   return nonce;
     135             : }
     136             : 
     137             : void *
     138           0 : lisp_msg_put_map_reply (vlib_buffer_t * b, mapping_t * records, u64 nonce,
     139             :                         u8 probe_bit)
     140             : {
     141           0 :   map_reply_hdr_t *h = vlib_buffer_put_uninit (b, sizeof (h[0]));
     142             : 
     143           0 :   clib_memset (h, 0, sizeof (h[0]));
     144           0 :   MREP_TYPE (h) = LISP_MAP_REPLY;
     145           0 :   MREP_NONCE (h) = nonce;
     146           0 :   MREP_REC_COUNT (h) = 1;
     147           0 :   MREP_RLOC_PROBE (h) = probe_bit;
     148             : 
     149           0 :   lisp_msg_put_mreg_records (b, records);
     150           0 :   return h;
     151             : }
     152             : 
     153             : void *
     154           0 : lisp_msg_put_map_register (vlib_buffer_t * b, mapping_t * records,
     155             :                            u8 want_map_notify, u16 auth_data_len, u64 * nonce,
     156             :                            u32 * msg_len)
     157             : {
     158           0 :   u8 *auth_data = 0;
     159             : 
     160             :   /* Basic header init */
     161           0 :   map_register_hdr_t *h = vlib_buffer_put_uninit (b, sizeof (h[0]));
     162             : 
     163           0 :   clib_memset (h, 0, sizeof (h[0]));
     164           0 :   MREG_TYPE (h) = LISP_MAP_REGISTER;
     165           0 :   MREG_NONCE (h) = nonce_build (0);
     166           0 :   MREG_WANT_MAP_NOTIFY (h) = want_map_notify ? 1 : 0;
     167           0 :   MREG_REC_COUNT (h) = vec_len (records);
     168             : 
     169           0 :   auth_data = vlib_buffer_put_uninit (b, auth_data_len);
     170           0 :   clib_memset (auth_data, 0, auth_data_len);
     171             : 
     172             :   /* Put map register records */
     173           0 :   lisp_msg_put_mreg_records (b, records);
     174             : 
     175           0 :   nonce[0] = MREG_NONCE (h);
     176           0 :   msg_len[0] = vlib_buffer_get_tail (b) - (u8 *) h;
     177           0 :   return h;
     178             : }
     179             : 
     180             : void *
     181           0 : 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)
     185             : {
     186           0 :   u8 loc_count = 0;
     187             : 
     188             :   /* Basic header init */
     189           0 :   map_request_hdr_t *h = vlib_buffer_put_uninit (b, sizeof (h[0]));
     190             : 
     191           0 :   clib_memset (h, 0, sizeof (h[0]));
     192           0 :   MREQ_TYPE (h) = LISP_MAP_REQUEST;
     193           0 :   MREQ_NONCE (h) = nonce_build (0);
     194           0 :   MREQ_SMR_INVOKED (h) = is_smr_invoked ? 1 : 0;
     195           0 :   MREQ_RLOC_PROBE (h) = rloc_probe_set ? 1 : 0;
     196             : 
     197             :   /* We're adding one eid record */
     198           0 :   increment_record_count (h);
     199             : 
     200             :   /* Fill source eid */
     201           0 :   lisp_msg_put_gid (b, seid);
     202             : 
     203             :   /* Put itr rlocs */
     204           0 :   lisp_msg_put_itr_rlocs (lcm, b, rlocs, &loc_count);
     205           0 :   MREQ_ITR_RLOC_COUNT (h) = loc_count;
     206             : 
     207             :   /* Put eid record */
     208           0 :   lisp_msg_put_eid_rec (b, deid);
     209             : 
     210           0 :   nonce[0] = MREQ_NONCE (h);
     211           0 :   return h;
     212             : }
     213             : 
     214             : void *
     215           0 : 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)
     217             : {
     218             :   ecm_hdr_t *h;
     219           0 :   ip_address_t _src_ip, *src_ip = &_src_ip, _dst_ip, *dst_ip = &_dst_ip;
     220           0 :   if (gid_address_type (la) != GID_ADDR_IP_PREFIX)
     221             :     {
     222             :       /* empty ip4 */
     223           0 :       clib_memset (src_ip, 0, sizeof (src_ip[0]));
     224           0 :       clib_memset (dst_ip, 0, sizeof (dst_ip[0]));
     225             :     }
     226             :   else
     227             :     {
     228           0 :       src_ip = &gid_address_ip (la);
     229           0 :       dst_ip = &gid_address_ip (ra);
     230             :     }
     231             : 
     232             :   /* Push inner ip and udp */
     233           0 :   pkt_push_udp_and_ip (vm, b, lp, rp, src_ip, dst_ip, 0);
     234             : 
     235             :   /* Push lisp ecm hdr */
     236           0 :   h = pkt_push_ecm_hdr (b);
     237             : 
     238           0 :   return h;
     239             : }
     240             : 
     241             : static u32
     242           0 : msg_type_to_hdr_len (lisp_msg_type_e type)
     243             : {
     244           0 :   switch (type)
     245             :     {
     246           0 :     case LISP_MAP_REQUEST:
     247           0 :       return (sizeof (map_request_hdr_t));
     248           0 :     case LISP_MAP_REPLY:
     249           0 :       return (sizeof (map_reply_hdr_t));
     250           0 :     default:
     251           0 :       return (0);
     252             :     }
     253             : }
     254             : 
     255             : void *
     256           0 : lisp_msg_pull_hdr (vlib_buffer_t * b, lisp_msg_type_e type)
     257             : {
     258           0 :   return vlib_buffer_pull (b, msg_type_to_hdr_len (type));
     259             : }
     260             : 
     261             : u32
     262           0 : lisp_msg_parse_addr (vlib_buffer_t * b, gid_address_t * eid)
     263             : {
     264             :   u32 len;
     265           0 :   clib_memset (eid, 0, sizeof (*eid));
     266           0 :   len = gid_address_parse (vlib_buffer_get_current (b), eid);
     267           0 :   if ((len != ~0) && vlib_buffer_pull (b, len))
     268             :     {
     269           0 :       return len;
     270             :     }
     271             :   else
     272             :     {
     273           0 :       return ~0;
     274             :     }
     275             : }
     276             : 
     277             : u32
     278           0 : lisp_msg_parse_eid_rec (vlib_buffer_t * b, gid_address_t * eid)
     279             : {
     280           0 :   eid_record_hdr_t *h = vlib_buffer_get_current (b);
     281             :   u32 len;
     282           0 :   clib_memset (eid, 0, sizeof (*eid));
     283           0 :   len = gid_address_parse (EID_REC_ADDR (h), eid);
     284           0 :   if (len == ~0)
     285           0 :     return len;
     286             : 
     287           0 :   gid_address_ippref_len (eid) = EID_REC_MLEN (h);
     288           0 :   if (!vlib_buffer_pull (b, len + sizeof (eid_record_hdr_t)))
     289             :     {
     290           0 :       return ~0;
     291             :     }
     292             : 
     293           0 :   return len + sizeof (eid_record_hdr_t);
     294             : }
     295             : 
     296             : u32
     297           0 : lisp_msg_parse_itr_rlocs (vlib_buffer_t * b, gid_address_t ** rlocs,
     298             :                           u8 rloc_count)
     299             : {
     300             :   gid_address_t tloc;
     301           0 :   u32 i, len = 0, tlen = 0;
     302             : 
     303             :   //MREQ_ITR_RLOC_COUNT(mreq_hdr) + 1
     304           0 :   for (i = 0; i < rloc_count; i++)
     305             :     {
     306           0 :       len = lisp_msg_parse_addr (b, &tloc);
     307           0 :       if (len == ~0)
     308           0 :         return len;
     309           0 :       vec_add1 (*rlocs, tloc);
     310           0 :       tlen += len;
     311             :     }
     312           0 :   return tlen;
     313             : }
     314             : 
     315             : u32
     316           0 : lisp_msg_parse_loc (vlib_buffer_t * b, locator_t * loc)
     317             : {
     318             :   int len;
     319             : 
     320           0 :   len = locator_parse (vlib_buffer_get_current (b), loc);
     321           0 :   if (len == ~0)
     322           0 :     return ~0;
     323             : 
     324           0 :   if (!vlib_buffer_has_space (b, sizeof (len)))
     325           0 :     return ~0;
     326           0 :   vlib_buffer_pull (b, len);
     327             : 
     328           0 :   return len;
     329             : }
     330             : 
     331             : u32
     332           0 : lisp_msg_parse_mapping_record (vlib_buffer_t * b, gid_address_t * eid,
     333             :                                locator_t ** locs, locator_t * probed_)
     334             : {
     335           0 :   void *h = 0, *loc_hdr = 0;
     336           0 :   locator_t loc, *probed = 0;
     337           0 :   int i = 0, len = 0, llen = 0;
     338             : 
     339           0 :   h = vlib_buffer_get_current (b);
     340           0 :   if (!vlib_buffer_has_space (b, sizeof (mapping_record_hdr_t)))
     341           0 :     return ~0;
     342             : 
     343           0 :   vlib_buffer_pull (b, sizeof (mapping_record_hdr_t));
     344             : 
     345           0 :   clib_memset (eid, 0, sizeof (*eid));
     346           0 :   len = gid_address_parse (vlib_buffer_get_current (b), eid);
     347           0 :   if (len == ~0)
     348           0 :     return len;
     349             : 
     350           0 :   if (!vlib_buffer_has_space (b, sizeof (len)))
     351           0 :     return ~0;
     352             : 
     353           0 :   vlib_buffer_pull (b, len);
     354           0 :   if (GID_ADDR_IP_PREFIX == gid_address_type (eid))
     355           0 :     gid_address_ippref_len (eid) = MAP_REC_EID_PLEN (h);
     356             : 
     357           0 :   for (i = 0; i < MAP_REC_LOC_COUNT (h); i++)
     358             :     {
     359           0 :       loc_hdr = vlib_buffer_get_current (b);
     360             : 
     361           0 :       llen = lisp_msg_parse_loc (b, &loc);
     362           0 :       if (llen == ~0)
     363           0 :         return llen;
     364           0 :       vec_add1 (*locs, loc);
     365           0 :       len += llen;
     366             : 
     367           0 :       if (LOC_PROBED (loc_hdr))
     368             :         {
     369           0 :           if (probed != 0)
     370           0 :             clib_warning
     371             :               ("Multiple locators probed! Probing only the first!");
     372             :           else
     373           0 :             probed = &loc;
     374             :         }
     375             :     }
     376             :   /* XXX */
     377           0 :   if (probed_ != 0 && probed)
     378           0 :     *probed_ = *probed;
     379             : 
     380           0 :   return len + sizeof (map_reply_hdr_t);
     381             : }
     382             : 
     383             : /*
     384             :  * fd.io coding-style-patch-verification: ON
     385             :  *
     386             :  * Local Variables:
     387             :  * eval: (c-set-style "gnu")
     388             :  * End:
     389             :  */

Generated by: LCOV version 1.14