feat: only load part of programs for bind to wan only

This commit is contained in:
mzz2017 2023-02-01 15:16:25 +08:00
parent a784b16367
commit 8908765ca1
4 changed files with 36 additions and 11 deletions

View File

@ -64,7 +64,8 @@ func Run() (err error) {
}
// New ControlPlane.
onlyBindLanInterface := len(param.Global.WanInterface) == 0
bindLan := len(param.Global.LanInterface) != 0
bindWan := len(param.Global.WanInterface) != 0
t, err := control.NewControlPlane(
log,
nodeList,
@ -73,7 +74,8 @@ func Run() (err error) {
param.Global.DnsUpstream,
param.Global.CheckUrl,
param.Global.CheckInterval,
onlyBindLanInterface,
bindLan,
bindWan,
)
if err != nil {
return err

View File

@ -96,4 +96,5 @@ const (
IpVersion_X IpVersion = 3
)
var BasicFeatureVersion = internal.Version{5, 2, 0}
var FtraceFeatureVersion = internal.Version{5, 5, 0}

View File

@ -98,12 +98,28 @@ func BatchUpdate(m *ebpf.Map, keys interface{}, values interface{}, opts *ebpf.B
type bpfObjectsLan struct {
// NOTICE: Consider to update me if any program added.
//bpfPrograms
TproxyEgress *ebpf.Program `ebpf:"tproxy_egress"`
TproxyIngress *ebpf.Program `ebpf:"tproxy_ingress"`
bpfMaps
}
type bpfObjectsWan struct {
// NOTICE: Consider to update me if any program added.
//bpfPrograms
Inet6Bind *ebpf.Program `ebpf:"inet6_bind"`
InetAutobind *ebpf.Program `ebpf:"inet_autobind"`
InetBind *ebpf.Program `ebpf:"inet_bind"`
InetRelease *ebpf.Program `ebpf:"inet_release"`
InetSendPrepare *ebpf.Program `ebpf:"inet_send_prepare"`
TcpConnect *ebpf.Program `ebpf:"tcp_connect"`
TproxyWanEgress *ebpf.Program `ebpf:"tproxy_wan_egress"`
TproxyWanIngress *ebpf.Program `ebpf:"tproxy_wan_ingress"`
bpfMaps
}
func AssignBpfObjects(to *bpfObjects, from interface{}) {
vTo := reflect.Indirect(reflect.ValueOf(to))
vFrom := reflect.Indirect(reflect.ValueOf(from))

View File

@ -65,12 +65,21 @@ func NewControlPlane(
dnsUpstream string,
checkUrl string,
checkInterval time.Duration,
onlyBindLanInterface bool,
bindLan bool,
bindWan bool,
) (c *ControlPlane, err error) {
kernelVersion, e := internal.KernelVersion()
if e != nil {
return nil, fmt.Errorf("failed to get kernel version: %w", e)
}
if kernelVersion.Less(consts.BasicFeatureVersion) {
return nil, fmt.Errorf("your kernel version %v does not satisfy basic requirement; expect >=%v", c.kernelVersion.String(), consts.BasicFeatureVersion.String())
}
if bindWan && kernelVersion.Less(consts.FtraceFeatureVersion) {
// Not support ftrace (fentry/fexit).
// PID bypass needs it.
return nil, fmt.Errorf("your kernel version %v does not support bind to WAN; expect >=%v; remove wan_interface in config file and try again", c.kernelVersion.String(), consts.FtraceFeatureVersion.String())
}
// Allow the current process to lock memory for eBPF resources.
if err = rlimit.RemoveMemlock(); err != nil {
@ -87,10 +96,13 @@ func NewControlPlane(
LogLevel: ebpf.LogLevelStats,
}
}
var obj interface{} = &bpf
if kernelVersion.Less(consts.FtraceFeatureVersion) || onlyBindLanInterface {
var obj interface{} = &bpf // Bind both LAN and WAN.
if bindLan && !bindWan {
// Trick. Replace the beams with rotten timbers.
obj = &bpfObjectsLan{}
} else if !bindLan && bindWan {
// Trick. Replace the beams with rotten timbers.
obj = &bpfObjectsWan{}
}
retryLoadBpf:
if err = loadBpfObjects(obj, &ebpf.CollectionOptions{
@ -388,12 +400,6 @@ func (c *ControlPlane) BindLan(ifname string) error {
}
func (c *ControlPlane) BindWan(ifname string) error {
if c.kernelVersion.Less(consts.FtraceFeatureVersion) {
// Not support ftrace (fentry/fexit).
// PID bypass needs it.
return fmt.Errorf("your kernel version %v does not support bind to WAN; expect >=%v; remove wan_interface in config file and try again", c.kernelVersion.String(), consts.FtraceFeatureVersion.String())
}
link, err := netlink.LinkByName(ifname)
if err != nil {
return err