首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >learning:vpp hash Infrastructure (2)

learning:vpp hash Infrastructure (2)

作者头像
dpdk-vpp源码解读
发布于 2023-09-05 09:56:34
发布于 2023-09-05 09:56:34
55900
代码可运行
举报
文章被收录于专栏:DPDK VPP源码分析DPDK VPP源码分析
运行总次数:0
代码可运行

前面讲了vpp 软件Packet Flow Hash基础架构,其中在hash算法中有一个对称hash算法(handoff-eth-sym 1 Ethernet/IPv4/IPv6/MPLS headers Symmetric),对称hash算法的作用是将同一条流的两个方向的报文hash到一个cpu核心来处理。在软件逻辑中存在基于CPU核的L34会话业务及DPVS软件(dpvs中一般是使用网卡FDIR功能实现)中都有对称hash的应用,以提升网络处理性能。

在上家单位实现过基于vpp实现tcp,sctp报文的去重,保序、分片重组功能,以提供应用层完整的业务报文。就是利用网卡对称RSS实现网络性能优化,以减少vpp handoff功能的使用(一般会存在10%左右的性能开销)。可以参考以前文章:dpdk X710 symmetric RSS Vpp使用dpdk RSS功能部分报文不生效问题

下面以代码展开说明vpp 软件中对称hash处理逻辑。

1、普通IPv4报文,分别以Sip + Dip + protocol 做异或运算。

2、普通IPv6报文,分别以Sip + Dip + protocol 做异或运算。

3、mpls报文,最多支持五层mpls 嵌套,解析内层报文如果是ipv4或ipv6 ,以Sip + Dip + protocol 做异或运算,否则以内层mpls 标签数值做hash。

4、vlan或dot1ad报文,解析内层报文如果是ipv4或ipv6 ,以Sip + Dip + protocol 做异或运算,否则以 ethernet type做hash。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    static inline u64
eth_get_sym_key (ethernet_header_t * h0)
{
    u64 hash_key;
    /*1、普通ipv4报文以sip + dip + protocl 计算hash key*/
    if (PREDICT_TRUE (h0->type) == clib_host_to_net_u16 (ETHERNET_TYPE_IP4))
    {
        ip4_header_t *ip = (ip4_header_t *) (h0 + 1);
        hash_key =(u64) (ip->src_address.as_u32 ^
                 ip->dst_address.as_u32 ^ ip->protocol);
    }
   /*2、普通ipv6报文以sip + dip + protocl 计算hash key*/
    else if (h0->type == clib_host_to_net_u16 (ETHERNET_TYPE_IP6))
    {
        ip6_header_t *ip = (ip6_header_t *) (h0 + 1);
        hash_key = (u64) (ip->src_address.as_u64[0] ^
            ip->src_address.as_u64[1] ^
            ip->dst_address.as_u64[0] ^
            ip->dst_address.as_u64[1] ^ ip->protocol);
    }
    /*3、普通mpls报文计算hash key*/
    else if (h0->type == clib_host_to_net_u16 (ETHERNET_TYPE_MPLS))
    {
        hash_key = mpls_get_key ((mpls_unicast_header_t *) (h0 + 1));
    }
    /*4、vlan或dot1ad报文计算hash key*/
    else if (PREDICT_FALSE((h0->type == clib_host_to_net_u16 (ETHERNET_TYPE_VLAN))
         || (h0->type == clib_host_to_net_u16 (ETHERNET_TYPE_DOT1AD)))) 
    {
        ethernet_vlan_header_t *outer = (ethernet_vlan_header_t *) (h0 + 1);
        outer = (outer->type == clib_host_to_net_u16 (ETHERNET_TYPE_VLAN)) ?outer + 1 : outer;
        if (PREDICT_TRUE (outer->type) ==
                clib_host_to_net_u16 (ETHERNET_TYPE_IP4))
        {
             ip4_header_t *ip = (ip4_header_t *) (outer + 1);
             hash_key = (u64) (ip->src_address.as_u32 ^
                         ip->dst_address.as_u32 ^ ip->protocol);
        }
        else if (outer->type == clib_host_to_net_u16 (ETHERNET_TYPE_IP6))
        {
            ip6_header_t *ip = (ip6_header_t *) (outer + 1);
            hash_key = (u64) (ip->src_address.as_u64[0] ^ 
                ip->src_address.as_u64[1] ^
                ip->dst_address.as_u64[0] ^
                ip->dst_address.as_u64[1] ^ ip->protocol);
        }
        else if (outer->type == clib_host_to_net_u16 (ETHERNET_TYPE_MPLS))
        {
             hash_key = mpls_get_key ((mpls_unicast_header_t *) (outer + 1));
        }
        else
        {
             hash_key = outer->type;
        }
    }
    else
    {
        hash_key = 0;
    }

    return hash_key;
}

通过分析代码,软件对称hash因子实现还是比较简单,不能做到hash均匀,vpp只是简单实现了此算法。vpp中flow hash使用的地方还是相当多的,也曾经因hash遇到过很多问题。

在vpp 19.01版本中ipsec使用vpp自带的ikev2协商,遇到过因硬件RSS算法(默认是L34层做hash key)导致协商失败的问题。大致原因是因为ikev2在协商过程中创建了以cpu核资源,通过spi查询到ipsec sa资源。在网卡开启多队列之后,ikev2第一阶段,端口号500,rss hash到worker1上,ikev2 第二阶段,因存在nat 端口号4500,rss hash 到worker2上面,导致查询不到sa资源,协商失败。解决方案也比较简单,就是修改网卡硬件rss key因子,以L3层为key做hash。

在vxlan报文封装过程中,计算外层UDP报文src port端口号,就是以内层报文来做hash key计算得到端口号。因资源池存在防火墙会话,内层报文数据量太大,导致防火墙会话满而丢包的问题。通过优化hash算法解决此问题。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
static inline u32
vnet_l2_compute_flow_hash (vlib_buffer_t * b)
{
  ethernet_header_t *eh = vlib_buffer_get_current (b);
  u8 *l3h = (u8 *) eh + vnet_buffer (b)->l2.l2_len;
  u16 ethertype = clib_net_to_host_u16 (*(u16 *) (l3h - 2));
  /*1、ipv4 报文 以报文五元组做hash key*/
  if (ethertype == ETHERNET_TYPE_IP4)
    return ip4_compute_flow_hash ((ip4_header_t *) l3h, IP_FLOW_HASH_DEFAULT);
/*2、ipv6 报文 以报文五元组 + flowtable 做hash key*/
  else if (ethertype == ETHERNET_TYPE_IP6)
    return ip6_compute_flow_hash ((ip6_header_t *) l3h, IP_FLOW_HASH_DEFAULT);
  else
    {/*2、二层报文 以报文smac + dmac + ethernet type 做hash key*/
      u32 a, b, c;
      u32 *ap = (u32 *) & eh->dst_address[2];
      u32 *bp = (u32 *) & eh->src_address[2];
      a = *ap;
      b = *bp;
      c = ethertype;
      hash_v3_mix32 (a, b, c);
      hash_v3_finalize32 (a, b, c);
      return c;
    }
}

/** Default: 5-tuple + flowlabel without the "reverse" bit 
* 以Sip+Dip+Sport + Dport + proctcol + flowlabel (ipv6报文 flowlable)*/
#define IP_FLOW_HASH_DEFAULT (0x9F)

另外在ip转发模块中,存在ECMP(Equal-Cost Multi-Path Routing等价多路径路由)中,也存在软件hash 选择的问题。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/** Default: 5-tuple + flowlabel without the "reverse" bit */
#define IP_FLOW_HASH_DEFAULT (0x9F)

#define foreach_flow_hash_bit_v1                                              \
  _ (src, IP_FLOW_HASH_SRC_ADDR)                                              \
  _ (dst, IP_FLOW_HASH_DST_ADDR)                                              \
  _ (sport, IP_FLOW_HASH_SRC_PORT)                                            \
  _ (dport, IP_FLOW_HASH_DST_PORT)                                            \
  _ (proto, IP_FLOW_HASH_PROTO)                                               \
  _ (reverse, IP_FLOW_HASH_REVERSE_SRC_DST)                                   \
  _ (symmetric, IP_FLOW_HASH_SYMMETRIC)

#define foreach_flow_hash_bit                                                 \
  _ (src, 0, IP_FLOW_HASH_SRC_ADDR)                                           \
  _ (dst, 1, IP_FLOW_HASH_DST_ADDR)                                           \
  _ (sport, 2, IP_FLOW_HASH_SRC_PORT)                                         \
  _ (dport, 3, IP_FLOW_HASH_DST_PORT)                                         \
  _ (proto, 4, IP_FLOW_HASH_PROTO)                                            \
  _ (reverse, 5, IP_FLOW_HASH_REVERSE_SRC_DST)                                \
  _ (symmetric, 6, IP_FLOW_HASH_SYMMETRIC)                                    \
  _ (flowlabel, 7, IP_FLOW_HASH_FL)                                           \
  _ (gtpv1teid, 8, IP_FLOW_HASH_GTPV1_TEID)

可以通过set ip flow-hash 来设置hash key选择因子,此设置是基于vrf的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
set ip flow-hash table <table-id> [src] [dst] [sport] [dport] [proto] [reverse] [gtpv1teid]

至此我们了解了vpp中软件Packet Flow Hash的使用,以及遇到问题的一些解决思路。如果遇到类似的问题,欢迎留言讨论学习。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-08-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DPDK VPP源码分析 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
聊一聊VPP常用的定位手段(2)
前段时间有人在微信群询问通过vlib_frame_t地址,如果获取到报文vlib_buffer_t结构信息。本文以ping回应报文处理流程中节点ip4_icmp_input为例简单分析一下:
dpdk-vpp源码解读
2023/01/04
1.6K0
learning:vpp hash Infrastructure
现代物理网卡为了提高网络并行处理性能,使用Packet Flow Hash 用于不同的目的,比如RSS(Receive Side Scaling)、RPS(Receive Packet Steering)、RFS(Receive Flow Steering)、ARFS(Accelerated Receive Flow Steering)以及接口bonding等等。网卡也可以提供包流哈希值作为元数据,它可以被应用程序使用,而不需要重新计算包流哈希值。
dpdk-vpp源码解读
2023/09/05
4280
learning:vpp hash Infrastructure
learning:vet/classify(1)
前面公众号文章learning:vet/policer介绍了policer的基本结构及基于接口in方向的policer限速的配置及使用。文章结尾讲到classify-policer 基于流的policer限速功能实现,本文就介绍一下classify的基本原理及相关命令行。
dpdk-vpp源码解读
2023/03/07
8420
learning:vet/classify(1)
vppinfra--字节序转换、bitops、cacheline、jmp机制
vpp提供的字节序相关的api都定义在src\vppinfra\byte_order.h文件中,支持u16、i16、u32、i32、u64、i64字节序的转换。 下面是定义当前系统是大端还是小端的宏定义
dpdk-vpp源码解读
2023/03/07
8600
vppinfra--字节序转换、bitops、cacheline、jmp机制
Vpp --node节点调度总结
Vpp的功能逻辑被划分为多个featuce arc(比如ipv4、IPv6、l2、MPLS等),每个feature arc是由一定顺序的node组成,每个node完成一个功能。本文主要是来介绍一下node的类型及调度模式。
dpdk-vpp源码解读
2023/03/07
2.4K0
Vpp --node节点调度总结
基于vpp搭建ipsec环境
最近忙于工作任务,一直没有时间来更新文章,今天周末正好没有太重要的事情,就自己在家使用vmware 虚拟机搭建了一下基于vpp的ipsec的环境,来学习一下ipsec的流程。
dpdk-vpp源码解读
2023/03/07
4.5K0
基于vpp搭建ipsec环境
vpp cli简单介绍
vpp提供了一套非常方便的cli引擎,无论是用户还是开发人员的角度,在代码调试、构造产品的可维护性方面、及配置下发等等都有使用。 要添加一个新命令,需要注册它的名称、帮助字符串及处理函数。 通过下面的测试代码来说明一下:
dpdk-vpp源码解读
2023/03/07
9360
vpp cli简单介绍
learning:vpp/classify(2)
作用如下图所示从table内存池上申请table内存,在main_heap上申请桶占用空间,从系统内存映射classify session中匹配规则表配置空间。这里操作和bihash一致。
dpdk-vpp源码解读
2023/01/04
2K0
learning:vpp/classify(2)
learning:vpp-sswan 实现ipsec策略模式 (2)
上一节完成了vpp-sswan基本环境的安装部署,接下来搭建环境来验证ike协商及转发功能,下图是基本环境配置组网情况:
dpdk-vpp源码解读
2023/12/04
1.2K4
learning:vpp-sswan 实现ipsec策略模式 (2)
learning:vet/policer
vpp自带的qos policer模块提供了限速及remark dscp功能。最开始policer需要和classify模块一起使用才能生效。在最近master分支合入了基于接口入方向配置policer功能,并且支持policer资源与绑定worker线程,利用handoff功能而避免多核模式下policer资源加锁(handoff 实现和加锁方式对性能影响没有详细数据)。
dpdk-vpp源码解读
2023/03/07
1.3K0
learning:vet/policer
learning:vpp bond
前几天有人在微信群里询问bond相关的一些问题,在上家公司使用过bond功能,但当时是基于vpp 16.9版本。最近看了一下21.10版本的发现差异很大,bond node节点跳转方式完全不同了。本文基于21.10搭建环境,通过cli来配置和验证bond功能。
dpdk-vpp源码解读
2023/01/04
1.9K1
learning:vpp bond
Learning VPP: OSPF routing protocol
前面文章:learning:vppsb router插件编译 介绍了vppsb router插件在Centos7内核版本3.10上的基于vpp 21.06版本的编译,并将修改后代码放在github上《链接https://github.com/jin13417/vppsb/tree/vpp_21.06》。本文主要参考博文《Learning VPP: OSPF routing protocol》学习使用vppsb的router插件搭建ospf学习环境。
dpdk-vpp源码解读
2023/03/07
2.7K1
Learning VPP: OSPF routing protocol
learning:vrrp vmac config
最近在测试vrrp功能的时候发现一个问题,就是主备同时在线的时候,在ping虚拟网关的时候,会出现下面的问题:
dpdk-vpp源码解读
2023/01/04
8220
learning:vrrp vmac config
OpenvSwitch代码分析 - fastpath数据结构
本文以openvswitch 2.5.0源码,主要介绍用户态openvswitch代码相关分析,分析其设计的原因和精彩之处。
yateszhou
2019/12/06
1.6K0
Learning VPP: VXLAN tunnel
VXLAN(Virtual eXtensible Local Area Network,虚拟扩展局域网),是由IETF定义的NVO3(Network Virtualization over Layer 3)标准技术之一,是对传统VLAN协议的一种扩展。VXLAN的特点是将L2的以太帧封装到UDP报文(即L2 over L4)中,并在L3网络中传输.
dpdk-vpp源码解读
2023/03/07
2.1K0
Learning VPP: VXLAN tunnel
learning vpp:span
镜像是指将经过指定端口(源端口或者镜像端口)的报文复制一份到另一个指定端口(目的端口或者观察端口)。
dpdk-vpp源码解读
2023/01/04
3.2K0
learning vpp:span
learning vpp:内存管理和 DPDK API
本译文源自PANTHEON.tech公司技术博客文章《VPP 105: Memory Management & DPDK APIs》,在我们深入运用VPP的过程中,不免对其中涉及的各类技术与库——它们的实践应用、优势特性及对应API——产生诸多疑问。这篇针对性的文章恰好为我们详尽答疑,扫清困惑。很适合入门vpp的同学学习。如需查阅原文,欢迎直接点击文末阅读原文。
dpdk-vpp源码解读
2024/04/15
9140
learning vpp:内存管理和 DPDK API
vppinfra----mpcap介绍
mpcap 是利用mmap 文件映射的方式把抓包文件映射进程的虚拟地址空间。从而减少了write函数一次内存拷贝到页缓存的过程,从而提高效率。
dpdk-vpp源码解读
2023/03/07
3040
vppinfra----mpcap介绍
learning:vpp dns plugins
域名系统(英文:Domain Name System,缩写:DNS)是互联网的一项服务。它作为将域名和IP地址相互映射的一个分布式数据库,能够使人更方便地访问互联网。DNS使用UDP端口53。当前,对于每一级域名长度的限制是63个字符,域名总长度则不能超过253个字符。 DNS 不仅方便了人们访问不同的互联网服务,更为很多应用提供了,动态服务发现和全局负载均衡(Global Server Load Balance,GSLB)的机制。这样,DNS 就可以选择离用户最近的 IP 来提供服务。即使后端服务的 IP 地址发生变化,用户依然可以用相同域名来访问。 VPP dns plugins一个缓存DNS域名解析器,适合优化域名解析性能,并覆盖LD_PRELOAD库中的gethostbyname()。目前支持以下特性: 1、缓存上游ipv4 DNS服务器的A、AAAA记录; 2、响应ipv4和ipv6的名称解析请求; 3、支持最大64K的cache并发项;--目前缺省是1000条目。 4、支持CNAME间接访问; 5、静态缓存条目创建,适合于重定向特定的名称; 6、轮询上游域名查找; 7、性能/规模适合SOHO设备或其他轻型应用程序。 本文主要介绍vpp dns 插件模块,DNS相关基础知识详细介绍请参阅参考资料中文章。下面就重点介绍dns测试环境搭建与配置。
dpdk-vpp源码解读
2023/01/04
1.2K1
learning:vpp dns plugins
learning vpp: svs基于源地址的路由选择的插件
单纯的SVS功能有下面2个好处:增强路由灵活性:SVS 允许路由器根据数据包的源 IP 地址来选择不同的 VRF(Virtual Routing and Forwarding)实例进行路由查找。这意味着网络可以更加灵活地处理不同的流量类型,特别是在多租户环境中,每个租户可能有自己的 VRF 实例。提高安全性:通过 SVS,网络管理员可以根据数据包的源地址来控制哪些流量可以访问特定的网络资源。这种基于源地址的路由选择有助于防止未经授权的访问,并增加了网络的整体安全性。
dpdk-vpp源码解读
2024/11/23
2170
learning vpp: svs基于源地址的路由选择的插件
相关推荐
聊一聊VPP常用的定位手段(2)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档