当前位置: 首页 > news >正文

【博客633】linux vxlan设备工作原理

linux vxlan设备工作原理

vxlan处理包的原理:以k8s cni flannel组件创建的vxlan设备为例

1、k8s cni组件创建flannel设备flannel.1,且这个设备为vxlan类型的设备

root@10.10.10.12:/home/ubuntu#  ethtool -i flannel.1
driver: vxlan
version: 0.1
firmware-version:
expansion-rom-version:
bus-info:
supports-statistics: no
supports-test: no
supports-eeprom-access: no
supports-register-dump: no
supports-priv-flags: no

2、vxlan设备创建的时候是有绑带其vtep通信的设备,比如:eth0

root@10.10.10.12:/home/ubuntu# ip -d link show flannel.1
6: flannel.1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN mode DEFAULT group defaultlink/ether 7e:b8:27:c7:4b:76 brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 68 maxmtu 65535vxlan id 1 local 10.10.10.12 dev eth0 srcport 0 0 dstport 8472 nolearning ttl auto ageing 300 udpcsum noudp6zerocsumtx noudp6zerocsumrx addrgenmode eui64 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535

3、flannel的agent会维护fdb表,查看flannel.1设备的fdb表

root@10-234-68-12:/home/ubuntu# bridge fdb show dev flannel.1
3e:5f:25:8e:e0:cd dst 10.10.10.12 self permanent
16:1d:36:f4:ab:26 dst 10.10.10.13 self permanent
a6:a0:56:1f:aa:4c dst 10.10.10.14 self permanent
76:50:cc:8d:7a:67 dst 10.10.10.15 self permanent

4、每个vxlan设备创建的时候会绑定一个udp socket,此时会有udp的vxlan端口的在监听,从而接收udp隧道包进行处理

# vxaln监听着8472的vxlan默认udp端口:
ubuntu@10.10.10.12:~$ netstat -uanv
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
udp        0      0 0.0.0.0:53851           0.0.0.0:*                          
udp        0      0 127.0.0.53:53           0.0.0.0:*                          
udp        0      0 0.0.0.0:111             0.0.0.0:*                          
udp        0      0 0.0.0.0:2049            0.0.0.0:*                          
udp        0      0 0.0.0.0:37543           0.0.0.0:*                          
udp        0      0 0.0.0.0:37554           0.0.0.0:*                          
udp        0      0 0.0.0.0:39762           0.0.0.0:*                          
udp        0      0 0.0.0.0:8472            0.0.0.0:*                          
udp6       0      0 :::52508                :::*                               
udp6       0      0 :::54535                :::*                               
udp6       0      0 :::59285                :::*                               
udp6       0      0 :::111                  :::*                               
udp6       0      0 :::2049                 :::*                               
udp6       0      0 :::40104                :::* 

细节剖析

1、vxlan模块回调函数在哪里设置:在vxlan 模块初始化中做:vxlan_init_module

1、register_pernet_device内部执行init函数rc = register_pernet_device(&vxlan_net_ops);
static struct pernet_operations vxlan_net_ops = {.init = vxlan_init_net,.exit = vxlan_exit_net,.id   = &vxlan_net_id,.size = sizeof(struct vxlan_net),
};2、设置收包的vxlan回调函数/* Disable multicast loopback */
inet_sk(sk)->mc_loop = 0;/* Mark socket as an encapsulation socket. */
udp_sk(sk)->encap_type = 1;
udp_sk(sk)->encap_rcv = vxlan_udp_encap_recv;

2、包如何来到vxlan的回调处理函数

已经知道vxlan是 MAC IN UDP中的封装,因此,在解封装之前,一切按照原有流程走

2-1、从网卡收到包来到协议栈开始:__netif_receive_skb_core**

/*type,二层封装内的协议,IP为 0x0800*/
type = skb->protocol;
/*获取协议注册的入口函数,ip为 ip_rcv,声明的变量为 ip_packet_type*/
list_for_each_entry_rcu(ptype,&ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) {if (ptype->type == type &&(ptype->dev == null_or_dev || ptype->dev == skb->dev ||ptype->dev == orig_dev)) {if (pt_prev)ret = deliver_skb(skb, pt_prev, orig_dev);pt_prev = ptype;}
}

2-2、ip_rcv

此函数只是对报文进行可靠性验证,最后到 钩子函数 ‘NF_HOOK’。
钩子函数中就是配置的netfilter,通过验证就会直接进入函数 ‘ip_rcv_finish’。

2-3、ip_rcv_finish

/*sysctl_ip_early_demux 是二进制值,该值用于对发往本地数据包的优化。
当前仅对建立连接的套接字起作用。*/
if (sysctl_ip_early_demux && !skb_dst(skb) && skb->sk == NULL) {const struct net_protocol *ipprot;int protocol = iph->protocol;ipprot = rcu_dereference(inet_protos[protocol]);if (ipprot && ipprot->early_demux) {ipprot->early_demux(skb);/* must reload iph, skb->head might have changed */iph = ip_hdr(skb);}}
/*这一部分时查找路由,判断是local in还是 forwarding。本次分析按照 local in分析*/
if (!skb_dst(skb)) {int err = ip_route_input_noref(skb, iph->daddr, iph->saddr,iph->tos, skb->dev);if (unlikely(err)) {if (err == -EXDEV)NET_INC_STATS_BH(dev_net(skb->dev),LINUX_MIB_IPRPFILTER);goto drop;}}
……/*按照local in分析,则此处相当于调用 ip_local_deliver(可深入 查找路由函数,里面有函数指针赋值)*/return dst_input(skb);

2-4、ip_local_deliver

钩子函数检测,不深入,直接到最后。

2-5、ip_local_deliver_finish

ipprot = rcu_dereference(inet_protos[protocol]);
……ret = ipprot->handler(skb);
……			
到了传输层注册的入口函数。UDP入口函数为 ‘udp_rcv’。

2-6、__udp4_lib_rcv

/*根据源目端口号及IP查找 插口*/
sk = __udp4_lib_lookup_skb(skb, uh->source, uh->dest, udptable);
……/*进入udp队列收包流程*/int ret = udp_queue_rcv_skb(sk, skb);
……

2-7、udp_queue_rcv_skb

/*插口如果是封装类型,vxlan等,则进入封装处理入口,下面开始分析vxlan部分代码*/
encap_rcv = ACCESS_ONCE(up->encap_rcv);
if (skb->len > sizeof(struct udphdr) && encap_rcv != NULL) {int ret;ret = encap_rcv(sk, skb);if (ret <= 0) {UDP_INC_STATS_BH(sock_net(sk),UDP_MIB_INDATAGRAMS,is_udplite);return -ret;}
}

3、vxlan的udp并不会上送到udp socket监听的进程,与传统用户态监听udp socket不同

vxlan的udp并不会上送到udp socket监听的进程,因为没有这个进程,vxlan设备是为udp socket注册了回调,让协议栈调这个回调来处理这个包,而不是上送到用户进程。这个回调函数进行包的拆解后把原包再经过协议栈,然后上送用户态进程

UDP有两条处理路径:

  • 1、放到sk的接收队列,通知等待进程
  • 2、调用udp_sock的encap_rcv函数,类似vxlan的实现,可以直接在内核中进行处理

如果udp_sock定义了encap_rcv函数,将会把报文交给该函数处理,而不是传统的保存到sock队列,唤醒进程收包。

总结:linux对vxlan包的处理过程

  • 创建vxlan设备的时候会创建udp socket来向内核注册对udp包的处理,这个udp socket还绑定了vxlan处理的回调函数
  • 当udp包来了,内核发现有相应的udp socket在监听,就将包给这个udp socket指定的回调来处理,如果有设置回调的话,vxlan的udp socker设置的vxlan包回调处理函数就会在这里调用,
    从而有机会处理vxlan udp隧道包。
  • 包到了之后通过udp socket指定的vxlan回调处理函数进行包的拆解然后才是把里面的原包上送协议栈,从而送到用户态进程
  • vxlan的收包和发包是从另外的设备那里拿和发到那个设备的,这个设备在创建vxlan设备的时候,用dev参数指定的
  • vxlan设备创建的时候没有指定remote端vetp的信息就会去查转发表,此时就可以通过自己的agent来维护转发表,从而实现自己的大三层网络拓扑

相关文章:

【博客633】linux vxlan设备工作原理

linux vxlan设备工作原理 vxlan处理包的原理&#xff1a;以k8s cni flannel组件创建的vxlan设备为例 1、k8s cni组件创建flannel设备flannel.1&#xff0c;且这个设备为vxlan类型的设备 root10.10.10.12:/home/ubuntu# ethtool -i flannel.1 driver: vxlan version: 0.1 fi…...

3.12学习周报

文章目录前言文献阅读摘要简介方法介绍讨论结论相关性分析总结前言 本周阅读文献《Streamflow and rainfall forecasting by two long short-term memory-based models》&#xff0c;文献主要提出两种基于长短时记忆网络的混合模型用于对水流量和降雨量进行预测。小波-LSTM&am…...

电力电子中逐波限流控制以及dsp实现

逐波限流是指在电力系统运行中&#xff0c;对电力设备进行电流保护的一种措施。它的实现方式是通过对电力系统的电流进行逐波监测和控制&#xff0c;每一波电流都可以独立地进行限制&#xff0c;从而保护电力系统设备不受过载损坏或短路故障的影响。 逐波限流的作用是提高电力…...

【数据结构】 顺序表

文章目录1 线性表2 顺序表2.1 概念及结构2.2 接口实现2.3 数组相关面试题2.4 顺序表的问题与思考1 线性表 线性表&#xff08;linear list&#xff09;是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表&#xff1a;顺序…...

Elasticsearch 集群规划- 单台机器核心数计算公式

在做集群规划的时候&#xff0c;到底需要给集群的每个节点多少个核心数&#xff1f;这个问题一直困扰了我很久。最近一段时间做千亿数据&#xff0c;PB存储量集群规划的时候&#xff0c;突然想明白了这件事&#xff0c;大致可以用一个公式来计算&#xff01;我觉得这是一个非常…...

Tesla都使用什么编程语言?

作者 | 初光 出品 | 车端 备注 | 转载请阅读文中版权声明 知圈 | 进“汽车电子与AutoSAR开发”群&#xff0c;请加微“cloud2sunshine” 总目录链接>> AutoSAR入门和实战系列总目录 带着对更美好未来的愿景&#xff0c;特斯拉不仅成为有史以来最有价值的汽车公司&…...

1143. 最长公共子序列——【Leetcode每日刷题】

1143. 最长公共子序列 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串在不改变字符的相对顺序的情况下删除某些…...

【并发基础】线程的通知与等待:obj.wait()、obj.notify()、obj.notifyAll()详解

目录 〇、先总结一下这三个方法带来的Java线程状态变化 一、obj.wait() 1.1 作用 1.2 使用前需要持有线程共享对象的锁 1.3 使用技巧 二、obj.notify(All)() 1.1 notify() 方法 1.1.1 调用notify()或notifyAll()不会释放线程的锁 1.2 notifyAll() 方法 1.3 使用技巧 三、使用实…...

css黏性定位-实现商城的分类滚动的标题吸附

传统的黏性定位是使用js通过计算高度来实现的&#xff0c;当元素滚动到一定位置时吸附在当前位置。下面我们通过css来实现黏性定位功能。 黏性定位 黏性定位目前主流的浏览器已经全部支持&#xff0c;顾名思义&#xff0c;黏性定位具有吸附的效果&#xff0c;其实它是positio…...

@Component和@bean注解在容器中创建实例区别

Component和Bean的区别 在Spring Boot中&#xff0c;Component注解和Bean注解都可以用于创建bean。它们的主要区别在于它们的作用范围和创建方式。 Component注解是一种通用的注解&#xff0c;可以用于标注任何类。被标注的类将被Spring容器自动扫描并创建为一个bean。这个bea…...

不写注释就是垃圾

最近Linux6.2出来了增加了很多新的东西&#xff0c;有看点的是&#xff0c;Linux确实要可以在Apple M1上面运行了&#xff0c;这应该是一个很大的新闻&#xff0c;如果有这么稳定的硬件支持&#xff0c;那对于Linux来说相当于又打下了一大片的江山。其中关于Linux6.2的特性罗列…...

深信服一面

1.C变量存储在哪里&#xff0c;生命周期是怎样的 2.静态成员变量和成员函数的特性&#xff0c;在哪里用过吗 3.new和delete是什么&#xff0c;和malloc和free对比有啥优势 4.new能不能重载&#xff0c;重载new有什么用 5.多态是怎么实现的&#xff0c;有什么优势和目的 6.…...

【C语言】深度理解指针(中)

前言✈上回说到&#xff0c;我们学习了一些与指针相关的数据类型&#xff0c;如指针数组&#xff0c;数组指针&#xff0c;函数指针等等&#xff0c;我们还学习了转移表的基本概念&#xff0c;学会了如何利用转移表来实现一个简易计算器。详情请点击传送门&#xff1a;【C语言】…...

步进电机运动八大算法

引导一种模块化(Module)设计思想&#xff0c;将传统步进电机的控制器(controller)、驱动器(Driver)、运动算法(Arithmetic)三合一。 对比国内外步进电机驱动原理和已有工作&#xff0c;结合各种硬件特性&#xff0c;改进或实现了可实际移植并用于步进电机控制八大算法。本产品…...

如果你持续大量的教坏ChatGPT,它确实会变坏

你输出的很多数据是经过人工标注吗&#xff0c;以确保可以正常对外展示出来&#xff0c;而不是有性别歧视、种族歧视或者其它意识形态为多数人所不认同的内容产生&#xff1f; 作为AI语言模型&#xff0c;我并不直接处理或输出任何数据&#xff0c;我的任务是通过对输入的自然语…...

opencv学习(二)图像阈值和平滑处理

图像阈值ret, dst cv2.threshold(src, thresh, maxval, type)src&#xff1a; 输入图&#xff0c;只能输入单通道图像&#xff0c;通常来说为灰度图dst&#xff1a; 输出图thresh&#xff1a; 阈值maxval&#xff1a; 当像素值超过了阈值&#xff08;或者小于阈值&#xff0c;…...

【含源码】用python做游戏有多简单好玩

有很多同学问我还有其他什么小游戏吗&#xff0c;游戏是怎么做的&#xff0c;难不难。我就用两篇文章来介绍一下&#xff0c;如何使用Python做游戏。 兔子与灌 俄罗斯方块 休闲五子棋 走迷宫 推箱子 消消乐 超多小游戏玩转不停↓ 更多小游戏可以评论区讨论哦&#xff0c;喜欢…...

C++常用函数

std::sort std::sort 函数用于对数组或容器进行排序&#xff0c;可以按照默认的升序排序或指定比较函数进行排序。 语法如下&#xff1a; template <class RandomAccessIterator> void sort(RandomAccessIterator first, RandomAccessIterator last);template <clas…...

Android Framework基础到深入篇

Android Framework基础到深入篇 KernelSU Android上基于内核的Root方案 Android系统源码下载/编译篇...

【Go进阶训练营】聊一下go的gc原理

背景 正好周末时间&#xff0c;就打算梳理以下自己对go gc的理解。跳出语言层面来说&#xff0c;gc分为两种&#xff0c;一种是手动创建&#xff0c;手动销毁。另一种就是由自动分配自动销毁&#xff0c;前者就是c,c的代表&#xff0c;后者就是java&#xff0c;go。 而整个流程…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…...

测试markdown--肇兴

day1&#xff1a; 1、去程&#xff1a;7:04 --11:32高铁 高铁右转上售票大厅2楼&#xff0c;穿过候车厅下一楼&#xff0c;上大巴车 &#xffe5;10/人 **2、到达&#xff1a;**12点多到达寨子&#xff0c;买门票&#xff0c;美团/抖音&#xff1a;&#xffe5;78人 3、中饭&a…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合

在汽车智能化的汹涌浪潮中&#xff0c;车辆不再仅仅是传统的交通工具&#xff0c;而是逐步演变为高度智能的移动终端。这一转变的核心支撑&#xff0c;来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒&#xff08;T-Box&#xff09;方案&#xff1a;NXP S32K146 与…...