LCOV - code coverage report
Current view: top level - vnet/ethernet - mac_address.h (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 39 46 84.8 %
Date: 2023-07-05 22:20:52 Functions: 11 13 84.6 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2018 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             : #ifndef __MAC_ADDRESS_H__
      17             : #define __MAC_ADDRESS_H__
      18             : 
      19             : #include <vlib/vlib.h>
      20             : 
      21             : typedef struct mac_address_t_
      22             : {
      23             :   union
      24             :   {
      25             :     u8 bytes[6];
      26             :     struct
      27             :     {
      28             :       u32 first_4;
      29             :       u16 last_2;
      30             :     } __clib_packed u;
      31             :   };
      32             : } mac_address_t;
      33             : 
      34             : STATIC_ASSERT ((sizeof (mac_address_t) == 6),
      35             :                "MAC address must represent the on wire format");
      36             : 
      37             : extern const mac_address_t ZERO_MAC_ADDRESS;
      38             : 
      39             : always_inline u64
      40           4 : ethernet_mac_address_u64 (const u8 * a)
      41             : {
      42           4 :   return (((u64) a[0] << (u64) (5 * 8))
      43           4 :           | ((u64) a[1] << (u64) (4 * 8))
      44           4 :           | ((u64) a[2] << (u64) (3 * 8))
      45           4 :           | ((u64) a[3] << (u64) (2 * 8))
      46           4 :           | ((u64) a[4] << (u64) (1 * 8)) | ((u64) a[5] << (u64) (0 * 8)));
      47             : }
      48             : 
      49             : always_inline void
      50           4 : ethernet_mac_address_from_u64 (u64 u, u8 * a)
      51             : {
      52             :   i8 ii;
      53             : 
      54          28 :   for (ii = 5; ii >= 0; ii--)
      55             :     {
      56          24 :       a[ii] = u & 0xFF;
      57          24 :       u = u >> 8;
      58             :     }
      59           4 : }
      60             : 
      61             : static inline int
      62             : ethernet_mac_address_is_multicast_u64 (u64 a)
      63             : {
      64             :   return (a & (1ULL << (5 * 8))) != 0;
      65             : }
      66             : 
      67             : static inline int
      68         252 : ethernet_mac_address_is_zero (const u8 * mac)
      69             : {
      70         252 :   return ((*((u32 *) mac) == 0) && (*((u16 *) (mac + 4)) == 0));
      71             : }
      72             : 
      73             : static inline void
      74         504 : ethernet_mac_address_generate (u8 * mac)
      75             : {
      76         504 :   u32 rnd = clib_cpu_time_now ();
      77         504 :   rnd = random_u32 (&rnd);
      78             : 
      79         504 :   memcpy (mac + 2, &rnd, sizeof (rnd));
      80         504 :   mac[0] = 2;
      81         504 :   mac[1] = 0xfe;
      82         504 : }
      83             : 
      84             : static inline int
      85      271373 : ethernet_mac_address_equal (const u8 * a, const u8 * b)
      86             : {
      87      520995 :   return ((*((u32 *) a) == (*((u32 *) b))) &&
      88      249622 :           (*((u16 *) (a + 4)) == (*((u16 *) (b + 4)))));
      89             : }
      90             : 
      91             : static_always_inline void
      92       68968 : mac_address_from_bytes (mac_address_t * mac, const u8 * bytes)
      93             : {
      94             :   /* zero out the last 2 bytes, then copy over only 6 */
      95       68968 :   clib_memcpy_fast (mac->bytes, bytes, 6);
      96       68968 : }
      97             : 
      98             : static_always_inline void
      99             : mac_address_to_bytes (const mac_address_t * mac, u8 * bytes)
     100             : {
     101             :   /* zero out the last 2 bytes, then copy over only 6 */
     102             :   clib_memcpy_fast (bytes, mac->bytes, 6);
     103             : }
     104             : 
     105             : static_always_inline int
     106           8 : mac_address_is_zero (const mac_address_t * mac)
     107             : {
     108           8 :   return (0 == mac->u.first_4 && 0 == mac->u.last_2);
     109             : }
     110             : 
     111             : static_always_inline u64
     112          85 : mac_address_as_u64 (const mac_address_t * mac)
     113             : {
     114          85 :   volatile u64 as_u64 = 0;
     115             : 
     116          85 :   clib_memcpy ((void *) &as_u64, mac->bytes, 6);
     117             : 
     118          85 :   return as_u64;
     119             : }
     120             : 
     121             : static_always_inline void
     122           0 : mac_address_from_u64 (mac_address_t * mac, u64 u)
     123             : {
     124           0 :   clib_memcpy (mac->bytes, &u, 6);
     125           0 : }
     126             : 
     127             : static_always_inline void
     128        9258 : mac_address_copy (mac_address_t * dst, const mac_address_t * src)
     129             : {
     130        9258 :   mac_address_from_bytes (dst, src->bytes);
     131        9258 : }
     132             : 
     133             : static_always_inline int
     134       20299 : mac_address_cmp (const mac_address_t * a, const mac_address_t * b)
     135             : {
     136       20299 :   return (memcmp (a->bytes, b->bytes, 6));
     137             : }
     138             : 
     139             : static_always_inline int
     140           8 : mac_address_equal (const mac_address_t * a, const mac_address_t * b)
     141             : {
     142           8 :   return (a->u.last_2 == b->u.last_2 && a->u.first_4 == b->u.first_4);
     143             : }
     144             : 
     145             : static_always_inline void
     146           0 : mac_address_set_zero (mac_address_t * mac)
     147             : {
     148           0 :   mac->u.first_4 = 0;
     149           0 :   mac->u.last_2 = 0;
     150           0 : }
     151             : 
     152             : static_always_inline int
     153             : mac_address_n_bits_set (const mac_address_t * a)
     154             : {
     155             :   return (count_set_bits (mac_address_as_u64 (a)));
     156             : }
     157             : 
     158             : extern void mac_address_increment (mac_address_t * mac);
     159             : extern uword unformat_mac_address_t (unformat_input_t * input,
     160             :                                      va_list * args);
     161             : extern u8 *format_mac_address_t (u8 * s, va_list * args);
     162             : 
     163             : #endif
     164             : 
     165             : /*
     166             :  * fd.io coding-style-patch-verification: ON
     167             :  *
     168             :  * Local Variables:
     169             :  * eval: (c-set-style "gnu")
     170             :  * End:
     171             :  */

Generated by: LCOV version 1.14