From dcf80215004a918535bf7d8de9c8bff2f4587b7f Mon Sep 17 00:00:00 2001 From: mzz2017 <2017@duck.com> Date: Sat, 4 Feb 2023 18:27:13 +0800 Subject: [PATCH] docs/fix: README; fix BatchUpdate version requirement --- README.md | 7 ++-- component/control/bpf_utils.go | 66 ++++++++++++++++++++-------------- 2 files changed, 44 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 80de8df..1886ddc 100644 --- a/README.md +++ b/README.md @@ -51,8 +51,9 @@ Note that if you bind dae to WAN only, dae only provide network service for loca 1. Check dns upstream and source loop (whether upstream is also a client of us) and remind the user to add sip rule. 1. Domain routing performance optimization. -1. Handle the case that nodes do not support UDP. -1. Handle the case that nodes do not support IPv6. -1. L4Checksum problem. +1. Handle the case that nodes do not support UDP by adding `filter: l4proto_out(tcp, udp)`, and filter out those nodes support both TCP and UDP. Thus we can use routing to handle it. +1. Handle the case that nodes do not support IPv6 by adding `filter: ipversion_out(4, 6)`, and filter out those nodes support both IPv4 and IPv6. Thus we can use routing to handle it. +1. L4Checksum problem. Maybe it is hard to solve. 1. MACv2 extension extraction. +1. Log to userspace. 1. ... diff --git a/component/control/bpf_utils.go b/component/control/bpf_utils.go index 3b4bff1..b646b47 100644 --- a/component/control/bpf_utils.go +++ b/component/control/bpf_utils.go @@ -71,43 +71,57 @@ func cidrToBpfLpmKey(prefix netip.Prefix) _bpfLpmKey { var ( CheckBatchUpdateFeatureOnce sync.Once SimulateBatchUpdate bool + SimulateBatchUpdateLpmTrie bool ) func BatchUpdate(m *ebpf.Map, keys interface{}, values interface{}, opts *ebpf.BatchOptions) (n int, err error) { CheckBatchUpdateFeatureOnce.Do(func() { version, e := internal.KernelVersion() - if e != nil || version.Less(consts.UserspaceBatchUpdateFeatureVersion) { + if e != nil { + SimulateBatchUpdate = true + SimulateBatchUpdateLpmTrie = true + return + } + if version.Less(consts.UserspaceBatchUpdateFeatureVersion) { SimulateBatchUpdate = true } - if m.Type() == ebpf.LPMTrie && version.Less(consts.UserspaceBatchUpdateLpmTrieFeatureVersion) { - SimulateBatchUpdate = true + if version.Less(consts.UserspaceBatchUpdateLpmTrieFeatureVersion) { + SimulateBatchUpdateLpmTrie = true } }) - if !SimulateBatchUpdate { - return m.BatchUpdate(keys, values, opts) - } else { - vKeys := reflect.ValueOf(keys) - if vKeys.Kind() != reflect.Slice { - return 0, fmt.Errorf("keys must be slice") - } - vVals := reflect.ValueOf(values) - if vVals.Kind() != reflect.Slice { - return 0, fmt.Errorf("values must be slice") - } - length := vKeys.Len() - if vVals.Len() != length { - return 0, fmt.Errorf("keys and values must have same length") - } - for i := 0; i < length; i++ { - vKey := vKeys.Index(i) - vVal := vVals.Index(i) - if err = m.Update(vKey.Interface(), vVal.Interface(), ebpf.MapUpdateFlags(opts.ElemFlags)); err != nil { - return i, err - } - } - return vKeys.Len(), nil + simulate := SimulateBatchUpdate + if m.Type() == ebpf.LPMTrie { + simulate = SimulateBatchUpdateLpmTrie } + + if !simulate { + // Genuine BatchUpdate + return m.BatchUpdate(keys, values, opts) + } + + // Simulate + vKeys := reflect.ValueOf(keys) + if vKeys.Kind() != reflect.Slice { + return 0, fmt.Errorf("keys must be slice") + } + vVals := reflect.ValueOf(values) + if vVals.Kind() != reflect.Slice { + return 0, fmt.Errorf("values must be slice") + } + length := vKeys.Len() + if vVals.Len() != length { + return 0, fmt.Errorf("keys and values must have same length") + } + + for i := 0; i < length; i++ { + vKey := vKeys.Index(i) + vVal := vVals.Index(i) + if err = m.Update(vKey.Interface(), vVal.Interface(), ebpf.MapUpdateFlags(opts.ElemFlags)); err != nil { + return i, err + } + } + return vKeys.Len(), nil } func AssignBpfObjects(to *bpfObjects, from interface{}) {