linux snat mac 桥,关于SNAT在bridge中不生效的问题
本周在协助验证一套虚拟网络的方案,该方案包含一个bridge,向上对接容器的veth,并接管真实NIC作为tx口,方案中需要在bridge中做SNAT,具体hook点位于POST_ROUTING,命令如下:iptables -t nat -A POSTROUTING -d 192.168.0.0/24 -j SNAT --to-source 192.168.0.5
为了验证该方案,我创建了一对veth,其中一端划分到独立的netns中,命令如下:ip link add br-veth type veth peer name veth
ip link set br-veth up
ip link set veth up
brctl addif br0 br-veth
ip netns add test-zone
ip link set veth netns test-zone
ip netns exec test-zone ip addr add 192.168.0.100/24 dev veth
为了避免方案过于复杂,规避gw带来的影响,这里假设对端和本端在同一子网,在test-zone中ping对端,我发现对端抓包看到的源IP并未变为192.168.0.5,换句话说SNAT未生效。
在veth的tx方向,这里仅需做二层转发即可,阅读bridge的源码可以发现如下路径(kernel 3.10/4.9无显著区别):br_forward -> BR_FORWARD -> br_nf_forward -> BR_POST_FORWARD -> br_nf_post_routing -> INET_POST_ROUTING
然而挂载POST_ROUTING的SNAT竟然未生效,真的令人匪夷所思。一番google之后,发现需要enable一个标志:echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables
纵观bridge实现,该sysctl的值最终设置到了变量nf_call_iptables,而该变量仅在br_nf_pre_routing中使用。显然,这是不符合预期的。
惯性思维使然,总认为既然有代表特性是否开启的变量,那么在代码相关的分支处一定会用到该变量,而bridge的实现则正好不是这样。
可以看到,只有开启了nf_call_iptables,才会进入网络层的netfilter hook点:static unsigned int br_nf_pre_routing(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state)
{
struct nf_bridge_info *nf_bridge;
struct net_bridge_port *p;
struct net_bridge *br;
__u32 len = nf_bridge_encap_header_len(skb);
if (unlikely(!pskb_may_pull(skb, len)))
return NF_DROP;
p = br_port_get_rcu(state->in);
if (p == NULL)
return NF_DROP;
br = p->br;
...
if (!brnf_call_iptables && !br->nf_call_iptables)
return NF_ACCEPT;
...
nf_bridge_put(skb->nf_bridge);
if (!nf_bridge_alloc(skb)) // 注意这里!
return NF_DROP;
...
NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING, state->net, state->sk, skb,
skb->dev, NULL, br_nf_pre_routing_finish);
return NF_STOLEN;
}
很容易忽略标着注释的那一行,而恰是那一行,直接决定了是否进入NF_INET_FORWARD和NF_INET_POST_ROUTING的HOOK点。static unsigned int br_nf_forward_ip(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state)
{
struct nf_bridge_info *nf_bridge;
struct net_device *parent;
u_int8_t pf;
if (!skb->nf_bridge) // 看这里!
return NF_ACCEPT;
...
NF_HOOK(pf, NF_INET_FORWARD, state->net, NULL, skb,
brnf_get_logical_dev(skb, state->in),
parent, br_nf_forward_finish);
return NF_STOLEN;
}static unsigned int br_nf_post_routing(void *priv,
struct sk_buff *skb,
const struct nf_hook_state *state)
{
struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
struct net_device *realoutdev = bridge_parent(skb->dev);
u_int8_t pf;
if (!nf_bridge || !nf_bridge->physoutdev) // 看这里!
return NF_ACCEPT;
...
NF_HOOK(pf, NF_INET_POST_ROUTING, state->net, state->sk, skb,
NULL, realoutdev,
br_nf_dev_queue_xmit);
return NF_STOLEN;
}
参加工作后,见识了很多相当“野”的解决方案,一言不合就得改kernel,为了避免遇到问题时一脸懵逼,平时还是要多花时间熟悉内部实现!
linux snat mac 桥,关于SNAT在bridge中不生效的问题相关推荐
- Python编程软件的安装与使用——Windows、Linux和Mac
Python版本:3.6.2 操作系统:Windows 作者:SmallWZQ 最近,有读者透露:Python软件如何安装?为什么自己安装的软件会有各种"奇怪"的问题?据此,本 ...
- Linux 修改mac 地址方法记录
Linux 修改MAC 记录: sudo ifconfig eth0 hw ether 70B3D5106F90 转载于:https://www.cnblogs.com/chenfulin5/p/67 ...
- 将服务端移植到Linux和MAC OS
文章目录 1 将服务端移植到Linux和MAC OS 1.1 概述 1.2 服务端代码实现 1 将服务端移植到Linux和MAC OS 1.1 概述 这里我们将服务端移植到Linux和MAC OS,差 ...
- 将客户端移植到Linux和MAC OS
文章目录 1 将客户端移植到Linux和MAC OS 1.1 概述 1.2 客户端移植代码 1 将客户端移植到Linux和MAC OS 1.1 概述 我们这里把将客户端移植到Linux和MAC OS, ...
- 【Python】扫盲帖:关于在Windows、Linux和Mac上安装设置Python的问题
来源|Analytics Vidhya 概述 在Linux.Mac或Windows机器上安装Python时遇到的问题 一步一步安装Python及流行的数据科学工具 1 介绍 在你的机器上安装Pytho ...
- [C] 跨平台使用Intrinsic函数范例1——使用SSE、AVX指令集 处理 单精度浮点数组求和(支持vc、gcc,兼容Windows、Linux、Mac)...
作者:zyl910. 本文面对对SSE等SIMD指令集有一定基础的读者,以单精度浮点数组求和为例演示了如何跨平台使用SSE.AVX指令集.因使用了stdint.zintrin.ccpuid这三个模块, ...
- 在Linux以及Mac OS X启用F#
随着.NET Core的推进,如今我们在Linux和Mac OS X平台上也可以和原先Windows平台之下一样运行F#程序.Microsoft的F#项目经理David Stephens先生在Buil ...
- 在Linux和Mac OS X系统上运行.NET
.NET Core运行时已经看到了实现真正的跨平台的美好前景,它最终出现在Linux和Mac OS X平台上.在上周举办的Microsoft Build大会上,来自微软的项目经理Habib Heyda ...
- java怎么安装_Windows、Linux、Mac下安装JDK
前言 在知乎上看到很多童鞋在学Java的时候,因为安装jdk时没有正确的配置,会遇到很多问题.所以决定今天写一下jdk在Windows.Mac.Linux下都怎么安装. 下载JDK "巧妇难 ...
最新文章
- jquery删除数组中的某个元素下标越界_Java数据结构和算法(二)—数组
- java spring配置类_spring 配置 Java配置类装配bean
- ValueError: No JSON object could be decoded
- 很好的关于机器学习入门讲解(深入浅出)
- mysql导出成execl
- 如何做好信息化和数字化建设,看这一篇就够了--童亚斋
- Pentaho BIServer 5.0.1 CE 免登录设置
- python遍历文件夹下的所有文件
- LightOJ 1071 Baker Vai(记忆化搜索)
- 利用多线程爬点dianying回家慢慢看【python爬虫入门进阶】(05)
- Vue图表(v-charts, e-charts)入门安装使用
- Unity 生成随机房间、洞穴(2D、3D地图)总结
- 2022最新SpringBoot2.X仿B站项目part1笔记
- 【20220629】【信号处理】(平稳随机信号)自相关函数性质的证明过程
- 线性变换和矩阵的详细解释
- 如何批量给照片加水印?详细图文教程
- 如何在线编辑你的各种文档?
- 武汉理工计算机研究生就业去向统计,21考研择校:武汉理工大学就业率和薪酬情况统计!...
- 分布式事务解决方案 - SpringCloud Alibaba Seata
- ps转手绘课程嘴巴绘制+之前回顾--day05学习笔记
热门文章
- 技术点:weekMap和Map的区别
- k8s创建用户账号——User Account
- UiBot Excel筛选
- 服务器虚拟打印机为什么经常打打不,打印机虚拟论文,关于制作PDF打印服务器相关参考文献资料-免费论文范文...
- 数字集成电路物理设计学习总结——布图规划和布局
- 1dp 等于多少PX
- 2016年美国数学建模比赛(MCM/ICM) E题环境科学 Are we heading towards a thirsty planet? 人工精准翻译。...
- 帝国cms忘记网站后台登录网址怎么找回?
- 在旧时的桃花里,喊疼
- 多样性强化学习:不光要赢,还要赢得精彩 | 清华吴翼