Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(config): wildcard lan interface name support #729

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

woshikedayaa
Copy link
Contributor

Background

#724

Checklist

Full Changelogs

实现了 #724 的请求,现在支持了对于 lan_interfaces的匹配支持。

匹配规则支持 + 匹配一个字符,* 匹配多个字符。

代码变化

主要变动的是匹配部分,首先入口变成了 bindLanWildcard

global.LanInterface = common.Deduplicate(global.LanInterface)
for _, ifname := range global.LanInterface {
	if err = core.bindLanWildcard(ifname, global.AutoConfigKernelParameter); err != nil {
		return nil, fmt.Errorf("bindLan: %v: %w", ifname, err)
	}
}
  

内部实现是,首先根据匹配的 pattern 来匹配。如果不是 pattern 就只绑定单独的if。

func (c *controlPlaneCore) bindLanWildcard(ifname string, autoConfigKernelParameter bool) error {
	if !netutils.IsInterfaceNameIsWildcard(ifname) {
		return c.bindLan(ifname, autoConfigKernelParameter, false)
	}

	// bind to current existed matched-interfaces
	matcher, err := netutils.NewInterfaceMather(ifname)
	if err != nil {
		return err
	}
	interfaces, err := net.Interfaces()
        // ......
	for _, iface := range interfaces {
        // ......
	}
	// listen new link creation
	if e := c.addNewLinkBindLanCb(ifname, autoConfigKernelParameter, true); e != nil {
		return fmt.Errorf("%w: %v", err, e)
	}
	return nil
}

addNewLinkBindLanCb方法添加了一个 keep bool 参数来决定是否需要持续监听。

另外就是 bindLan 方法的变化。因为全局已经有一个 通过监听匹配表达式的监听回调,所以用一个参数表面如果监听删除的网卡是来自 wildcard 就不添加新的监听了。

func (c *controlPlaneCore) bindLan(ifname string, autoConfigKernelParameter bool, isFromWildcard bool) error {
	if !isFromWildcard && netutils.IsInterfaceNameIsWildcard(ifname) {
		return c.bindLanWildcard(ifname, autoConfigKernelParameter)
	}

	if autoConfigKernelParameter {
		SetSendRedirects(ifname, "0")
		SetForwarding(ifname, "1")
	}
	if err := c._bindLan(ifname); err != nil {

		var notFoundErr netlink.LinkNotFoundError
		if !errors.As(err, &notFoundErr) {
			return err
		}
		if isFromWildcard {
			return err
		}
		// Not found error.
		// Listen for `NEWLINK` to bind.
		c.log.Warnf("Link '%v' is not found. Bind LAN program to it once it is created.", ifname)
		if e := c.addNewLinkBindLanCb(ifname, autoConfigKernelParameter, false); e != nil {
			return fmt.Errorf("%w: %v", err, e)
		}
		return nil
	}

	// Listen for `DELLINK` and add `NEWLINK` callback to re-bind.
	if err := c.addLinkCb(ifname, unix.RTM_DELLINK, func(realIfname string) {
		c.log.Warnf("Link deletion of '%v' is detected. Bind LAN program to it once it is re-created.", realIfname)
		// The interface retrieved through wildcard will be handled by the global wildcard callback.
		// no need to monitor it here
		if isFromWildcard {
			return
		}
		if e := c.addNewLinkBindLanCb(realIfname, autoConfigKernelParameter, false); e != nil {
			c.log.Errorf("Failed to add callback for re-bind LAN program to '%v': %v", ifname, e)
		}
	}, false); err != nil {
		return fmt.Errorf("failed to add re-bind callback: %w", err)
	}
	return nil
}

最后,文档将在合并后添加。谢谢各位开发者的耐心查看代码。

另外还有个小问题,个人未修复(不知道咋修)。具体表现为,在一个被泛型匹配到的网卡被删除后,会报错
[Jan 04 16:49:01] ERROR addQdisc: Link not found

往提出修改意见修复(小bug 不影响使用)。

Issue Reference

#724

Test Result

在我的电脑工作正常。

帖一个测试脚本

#!/bin/bash
# Define interface name
IFACE="br-test"

# Check if running as root
if [ "$EUID" -ne 0 ]; then
    echo "Please run as root (use sudo)"
    exit 1
fi

# Create a dummy interface
ip link add ${IFACE} type dummy
if [ $? -eq 0 ]; then
    echo "Created virtual interface: ${IFACE}"
    # Bring the interface up
    ip link set ${IFACE} up
    echo "Interface ${IFACE} is up"
else
    echo "Failed to create interface"
    exit 1
fi

# Wait for user input
echo "Interface is ready. Type 'ok' to delete it:"
while true; do
    read input
    if [ "$input" = "ok" ]; then
        break
    else
        echo "Type 'ok' to delete the interface:"
    fi
done

# Delete the interface
ip link delete ${IFACE}
echo "Interface ${IFACE} has been deleted"

@jschwinger233
Copy link
Member

golang 使用 tab 作为缩进,请用 go fmt 格式化代码。

@woshikedayaa
Copy link
Contributor Author

woshikedayaa commented Jan 7, 2025

已经重新 commit , cmd/internal 文件大面积爆红是因为上次提交的时候没有 format

顺便修了个 typo


另外,在群内讨论到后面可能需要单独修改 Callback的逻辑,以便于在 route 阶段匹配 lan 口名称。此PR 需要建议来修改可能。
@LostAttractor

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants