VPP代码阅读中文注解--byte_order.h

处理字节序相关的头文件。比如IP地址  192.168.10.20 这个IP地址。

在X86 CPU中处理时,长这样: 0x140aa8c0

在网络上传输时,长这样:0xc0a80a14

由于网络传输是按照低地址代表most significant byte的语义。这个与x86 这类的CPU刚好相反。

所以软件中需要做相应的处理,实际上就是在内存中做字节交换。

 

#include <vppinfra/clib.h>

#if (__BYTE_ORDER__)==( __ORDER_LITTLE_ENDIAN__)
#define CLIB_ARCH_IS_BIG_ENDIAN (0)
#define CLIB_ARCH_IS_LITTLE_ENDIAN (1)
#else
/* Default is big endian. */
#define CLIB_ARCH_IS_BIG_ENDIAN (1)
#define CLIB_ARCH_IS_LITTLE_ENDIAN (0)
#endif

/* Big/little endian. */
#define clib_arch_is_big_endian    CLIB_ARCH_IS_BIG_ENDIAN
#define clib_arch_is_little_endian CLIB_ARCH_IS_LITTLE_ENDIAN

当前CPU是大端结尾还是小端结尾,简称大端CPU,小端CPU。由编译选项决定。

如果编译的时候编译选项指定错误,则会出问题。

 

always_inline u16
clib_byte_swap_u16 (u16 x)
{
#if defined (__aarch64__)
  if (!__builtin_constant_p (x))
    {
    __asm__ ("rev16 %w0, %w0":"+r" (x));
      return x;
    }
#endif
  return (x >> 8) | (x << 8);
}

always_inline i16
clib_byte_swap_i16 (i16 x)
{
  return clib_byte_swap_u16 (x);
}

交换16位数的2个字节的内容。

always_inline u32
clib_byte_swap_u32 (u32 x)
{
#if defined (i386) || defined (__x86_64__)
  if (!__builtin_constant_p (x))
    {
      asm volatile ("bswap %0":"=r" (x):"0" (x));
      return x;
    }
#elif defined (__aarch64__)
  if (!__builtin_constant_p (x))
    {
    __asm__ ("rev %w0, %w0":"+r" (x));
      return x;
    }
#endif
  return ((x << 24) | ((x & 0xff00) << 8) | ((x >> 8) & 0xff00) | (x >> 24));
}

always_inline i32
clib_byte_swap_i32 (i32 x)
{
  return clib_byte_swap_u32 (x);
}

交换32位数的4个字节的内容。依次对调。

always_inline u64
clib_byte_swap_u64 (u64 x)
{
#if defined (__x86_64__)
  if (!__builtin_constant_p (x))
    {
      asm volatile ("bswapq %0":"=r" (x):"0" (x));
      return x;
    }
#elif defined (__aarch64__)
  if (!__builtin_constant_p (x))
    {
    __asm__ ("rev %0, %0":"+r" (x));
      return x;
    }
#endif
#define _(x,n,i) \
  ((((x) >> (8*(i))) & 0xff) << (8*((n)-(i)-1)))
  return (_(x, 8, 0) | _(x, 8, 1)
	  | _(x, 8, 2) | _(x, 8, 3)
	  | _(x, 8, 4) | _(x, 8, 5) | _(x, 8, 6) | _(x, 8, 7));
#undef _
}

always_inline i64
clib_byte_swap_i64 (i64 x)
{
  return clib_byte_swap_u64 (x);
}

交换64位数的8个字节。

/* HOST -> SEX */						\
always_inline type						\
clib_host_to_##sex##_##type (type x)				\
{								\
  if (! clib_arch_is_##sex##_endian)				\
    x = clib_byte_swap_##type (x);				\
  return x;							\
}								\
								\
always_inline type						\
clib_host_to_##sex##_mem_##type (type * x)			\
{								\
  type v = x[0];						\
  return clib_host_to_##sex##_##type (v);			\
}								\
								\
always_inline type						\
clib_host_to_##sex##_unaligned_mem_##type (type * x)		\
{								\
  type v = clib_mem_unaligned (x, type);			\
  return clib_host_to_##sex##_##type (v);			\
}								\

CPU字节序转换成网络字节序。

 

/* SEX -> HOST */						\
always_inline type						\
clib_##sex##_to_host_##type (type x)				\
{ return clib_host_to_##sex##_##type (x); }			\
								\
always_inline type						\
clib_##sex##_to_host_mem_##type (type * x)			\
{ return clib_host_to_##sex##_mem_##type (x); }			\
								\
always_inline type						\
clib_##sex##_to_host_unaligned_mem_##type (type * x)		\
{ return clib_host_to_##sex##_unaligned_mem_##type (x); }

网络字节序转主机字节序

#ifndef __cplusplus
_(little, u16)
_(little, u32)
_(little, u64)
_(little, i16)
_(little, i32)
_(little, i64)
_(big, u16) _(big, u32) _(big, u64) _(big, i16) _(big, i32) _(big, i64)
#endif
#undef _

2种CPU结构下,各种长度的字节序转换宏封装。

/* Network "net" alias for "big". */
#define _(type)						\
always_inline type					\
clib_net_to_host_##type (type x)			\
{ return clib_big_to_host_##type (x); }			\
							\
always_inline type					\
clib_net_to_host_mem_##type (type * x)			\
{ return clib_big_to_host_mem_##type (x); }		\
							\
always_inline type					\
clib_net_to_host_unaligned_mem_##type (type * x)	\
{ return clib_big_to_host_unaligned_mem_##type (x); }	\
							\
always_inline type					\
clib_host_to_net_##type (type x)			\
{ return clib_host_to_big_##type (x); }			\
							\
always_inline type					\
clib_host_to_net_mem_##type (type * x)			\
{ return clib_host_to_big_mem_##type (x); }		\
							\
always_inline type					\
clib_host_to_net_unaligned_mem_##type (type * x)	\
{ return clib_host_to_big_unaligned_mem_##type (x); }
#ifndef __cplusplus
  _(u16);
_(i16);
_(u32);
_(i32);
_(u64);
_(i64);
#endif

#undef _

宏封装

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值