V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  wacke  ›  全部回复第 2 页 / 共 3 页
回复总数  60
1  2  3  
2023-02-22 07:56:00 +08:00
回复了 phpfpm 创建的主题 宽带症候群 华为 MA5671A 如何设置多拨?
作为打包这个棒子固件的人告诉你,目前想让棒子本身将多个用户侧 vlan 转换到同一个 isp 侧 vlan 是实现不了的。。。除非另外再使用交换机,进行 vlan 转换或改写。。。
@qakito 已尝试删除 endpoint->src_if4 = skb->skb_iif ,重新编译 openwrt 后,测试无效。。。从最小跃点数的 wan 连入工作正常,其他就无法握手了。。。
@qakito
首先非常感谢你的回复,作为一个差不多将编程知识都还给老师的小白,要弄懂 kernel 协议栈,实在有点困难。。。。

1.我要实现的目标是 wireguard 作为服务端在 openwrt 里实现多 pppoe 的情况下,客户端可以任意连接一个 pppoe 实现接入。
2.目前在 openwrt+mwan3 的情况下,fwmark 标记入口数据包无效,手动指定 fwmark 则仅能实现 wireguard 固定选择多个 pppoe 中的一个作为默认路由。
3.从我 github 的 issue 以及 openwrt 论坛的部分讨论帖子来看,这个问题不仅仅是 openwrt+mwan3 特有的,邮件列表里也有很多提交给 wireguard 官方案例,但 wireguard 官方都是没有下文。。。。基于此(主要是补丁肯定很 low ),我也不可能将我的修改提交给 wireguard 。
4.稍晚点我尝试注释 endpoint->src_if4 = skb->skb_iif 这句试试吧。
@qakito
没有关系,这个补丁,至少在我自己的环境下,实现了我的需求。。。
@qakito

更新了下补丁,粗略测试,貌似没啥问题。。。

```
diff -uNr linux-5.15.12_orig/drivers/net/wireguard/socket.c linux-5.15.12_wg/drivers/net/wireguard/socket.c
--- linux-5.15.12_orig/drivers/net/wireguard/socket.c 2021-12-29 19:29:03.000000000 +0800
+++ linux-5.15.12_wg/drivers/net/wireguard/socket.c 2022-06-01 08:18:00.990080098 +0800
@@ -17,6 +17,12 @@
#include <net/udp_tunnel.h>
#include <net/ipv6.h>

+u32 dst_addr;
+u32 src_addr;
+
+int receive = 0;
+int send = 0;
+
static int send4(struct wg_device *wg, struct sk_buff *skb,
struct endpoint *endpoint, u8 ds, struct dst_cache *cache)
{
@@ -37,6 +43,13 @@

rcu_read_lock_bh();
sock = rcu_dereference_bh(wg->sock4);
+
+ if ((receive) && (!send) || (send) && (!receive)) {
+ src_addr = dst_addr;
+ }
+ else {
+ src_addr = 0;
+ }

if (unlikely(!sock)) {
ret = -ENONET;
@@ -52,9 +65,11 @@
security_sk_classify_flow(sock, flowi4_to_flowi_common(&fl));
if (unlikely(!inet_confirm_addr(sock_net(sock), NULL, 0,
fl.saddr, RT_SCOPE_HOST))) {
- endpoint->src4.s_addr = 0;
+ endpoint->src4.s_addr = src_addr;
endpoint->src_if4 = 0;
- fl.saddr = 0;
+ fl.saddr = src_addr;
+ send = 1;
+ receive = 0;
if (cache)
dst_cache_reset(cache);
}
@@ -62,9 +77,11 @@
if (unlikely(endpoint->src_if4 && ((IS_ERR(rt) &&
PTR_ERR(rt) == -EINVAL) || (!IS_ERR(rt) &&
rt->dst.dev->ifindex != endpoint->src_if4)))) {
- endpoint->src4.s_addr = 0;
+ endpoint->src4.s_addr = src_addr;
endpoint->src_if4 = 0;
- fl.saddr = 0;
+ fl.saddr = src_addr;
+ send = 1;
+ receive = 0;
if (cache)
dst_cache_reset(cache);
if (!IS_ERR(rt))
@@ -77,8 +94,12 @@
wg->dev->name, &endpoint->addr, ret);
goto err;
}
- if (cache)
+ if (cache) {
+ if (receive) {
+ fl.saddr = src_addr;
+ }
dst_cache_set_ip4(cache, &rt->dst, fl.saddr);
+ }
}

skb->ignore_df = 1;
@@ -315,6 +336,11 @@
static int wg_receive(struct sock *sk, struct sk_buff *skb)
{
struct wg_device *wg;
+ struct iphdr *ip_header = (struct iphdr *)skb_network_header(skb);
+
+ dst_addr = ip_header->daddr;
+ receive = 1;
+ send = 0;

if (unlikely(!sk))
goto err;

```
@qakito
>顺便说一句,用全局变量绝对不可行,根本无法重入
OK ,我尝试把 static 去掉试试。。。
>还有 endpoint->src_if4 是 netdevice 的 ifindex ,不是 src_addr
这个改回原来的 “endpoint->src_if4 = 0;” 吗?

目前来说,我自己从公司的电脑及手机同时分别连接路由的两个 wan ,没发现有啥异常。。。
@qakito 相当一部分的 NAT/防火墙,确实会因为回程地址变了,会丢弃数据包,导致无法握手。。。但其实根源还是 wireguard 本身, 收到数据包后,主动去重置源地址及传入的 ip mark 。。。
@geekvcn 好吧。你这回了等于没回。。。
@geekvcn 那么求解,该如何配置,才能实现 wireguard 作为 server 时,client 从任一 wan 口连入时,wireguard 的握手包从连入的 wan 口出去?针对 wireguard 的监听端口做策略路由吗?
@lcdtyph 这个 patch ,我自己也改了好多个版本了,既要保证传入连接的 ip 被正确应用,还要保证当已保存的 ip 失效时,wireguard 能重置这个失效的 ip ,另外还得保证配合 mwan3 的对于 wireguard 对端的策略路由正常工作,头疼。。。
此前我尝试使用 `inet_confirm_addr(sock_net(sock), NULL, 0, &src_addr, RT_SCOPE_LINL)` 这个函数,貌似没起作用。。。最后发出来的补丁,是我 debug 了 n 次之后貌似没问题的版本。。。
@lcdtyph 所以才求大神帮忙完善啊,我自己测试,至少 2 个 peer 同时连接我路由的 pppoe-wan2 ,是正常的。。。
@yanqiyu 还有一个情况就是,从我理解的 wireguard 源码来看,是 wireguard 自己重置了 ip mark 以及传入连接的目标 ip 的。。。
@yanqiyu 我是个小白。。。没有丰富的路由相关的理论知识,更没有内核协议栈及内核编程的知识背景。。。。只能从实际应用出发,尝试解决相关的问题。。。想要让上游接受,我差太远了。。。。另外就是想等待上游解决,估计还是自己实现来得靠谱。。。这个问题已经等了 5 年以上了。。。
@lcdtyph 我这里测试是可以的。。。
@TempTXT 可能吧。。。wireguard 团队超级固执。。。这个问题,早在 2016 年的样子,就有人提出过了。。。。
@TempTXT
https://github.com/openwrt/packages/issues/9538#issuecomment-983330533
https://github.com/openwrt/packages/issues/9538#issuecomment-1003715531
这个是我此前根据 mwan3 的策略路由搞的 wireguard 源 ip 策略路由,确实可行,但是效能太低了。。。
@TempTXT github 的 issue 差不多是 3 年前的事情了,mwan3 的维护人员,以及其他一些大神,都进行过一些尝试,基本确认这是 wireguard 本身的问题。。。。直到好几个月之前,我尝试过针对目的端口的策略路由,可行,但是过于繁琐且效能太低。。。在 wireguard 团队拒绝修复的情况下, 直接修改 wireguard 源码实现源进源出效能可靠些。
@neoblackcap 我主要是使用 openwrt+mwan3 ,eBPF 太高大上,玩不来。。。
@FabricPath 然而,wireguard 也不保存传入连接的 ip mark ,而是每次都重置。。。。这个在 github 的 issue 里也是测试过的,无效。。。
@lqs 不是的,其他 udp tunnel ,应该是有源进源出的设计的或者说可以 bind 到某个 interface 以使用策略路由,但 wireguard 设计成无法 bind 到 interface ,并且每次都直接从 kernel 获取路由。。。
1  2  3  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   947 人在线   最高记录 6543   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 16ms · UTC 20:22 · PVG 04:22 · LAX 13:22 · JFK 16:22
Developed with CodeLauncher
♥ Do have faith in what you're doing.