using netlink instead exec in ip-helper
This commit is contained in:
parent
dd58154c07
commit
c335a7cce6
2
group.go
2
group.go
@ -16,7 +16,7 @@ import (
|
||||
type GroupOptions struct {
|
||||
Enabled bool
|
||||
FWMark uint32
|
||||
Table uint16
|
||||
Table int
|
||||
}
|
||||
|
||||
type Group struct {
|
||||
|
@ -1,16 +1,14 @@
|
||||
package ipHelper
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/vishvananda/netlink"
|
||||
"github.com/vishvananda/netlink/nl"
|
||||
)
|
||||
|
||||
var (
|
||||
@ -32,23 +30,13 @@ func ExecIp(args ...string) ([]byte, error) {
|
||||
func GetUsedFwMarks() ([]uint32, error) {
|
||||
markMap := make(map[uint32]struct{})
|
||||
|
||||
out, err := ExecIp("rule", "show")
|
||||
rules, err := netlink.RuleList(nl.FAMILY_ALL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error while getting rules: %w", err)
|
||||
}
|
||||
|
||||
re := regexp.MustCompile(`fwmark\s+0x([0-9a-fA-F]+)`)
|
||||
for _, line := range strings.Split(string(out), "\n") {
|
||||
match := re.FindStringSubmatch(line)
|
||||
if len(match) < 2 {
|
||||
continue
|
||||
}
|
||||
|
||||
hexStr := match[1]
|
||||
hexValue, err := strconv.ParseInt(hexStr, 16, 64)
|
||||
if err == nil {
|
||||
markMap[uint32(hexValue)] = struct{}{}
|
||||
}
|
||||
for _, rule := range rules {
|
||||
markMap[rule.Mark] = struct{}{}
|
||||
}
|
||||
|
||||
marks := make([]uint32, len(markMap))
|
||||
@ -77,102 +65,33 @@ func GetUnusedFwMark(startFrom uint32) (uint32, error) {
|
||||
return fwmark, nil
|
||||
}
|
||||
|
||||
func GetTableAliases() (map[string]uint16, error) {
|
||||
tables := map[string]uint16{
|
||||
"unspec": 0,
|
||||
"default": 253,
|
||||
"main": 254,
|
||||
"local": 255,
|
||||
}
|
||||
|
||||
file, err := os.Open("/opt/etc/iproute2/rt_tables")
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return tables, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if strings.HasPrefix(line, "#") || len(strings.TrimSpace(line)) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
parts := strings.Fields(line)
|
||||
if len(parts) >= 2 {
|
||||
tableID, err := strconv.Atoi(parts[0])
|
||||
if err == nil {
|
||||
tables[parts[1]] = uint16(tableID)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := scanner.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return tables, nil
|
||||
}
|
||||
|
||||
func GetUsedTables() ([]uint16, error) {
|
||||
tableMap := map[uint16]struct{}{
|
||||
func GetUsedTables() ([]int, error) {
|
||||
tableMap := map[int]struct{}{
|
||||
0: {},
|
||||
253: {},
|
||||
254: {},
|
||||
255: {},
|
||||
}
|
||||
|
||||
tableAliases, err := GetTableAliases()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error while getting table aliases: %w", err)
|
||||
}
|
||||
|
||||
out, err := ExecIp("route", "show", "table", "all")
|
||||
routes, err := netlink.RouteListFiltered(nl.FAMILY_ALL, &netlink.Route{}, netlink.RT_FILTER_TABLE)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error while getting routes: %w", err)
|
||||
}
|
||||
|
||||
for _, line := range strings.Split(string(out), "\n") {
|
||||
if strings.Contains(line, "table") {
|
||||
parts := strings.Fields(line)
|
||||
for i, part := range parts {
|
||||
if part == "table" && i+1 < len(parts) {
|
||||
tableNum, ok := tableAliases[parts[i+1]]
|
||||
if !ok {
|
||||
tableNumInt, _ := strconv.Atoi(parts[i+1])
|
||||
tableNum = uint16(tableNumInt)
|
||||
}
|
||||
tableMap[tableNum] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, route := range routes {
|
||||
tableMap[route.Table] = struct{}{}
|
||||
}
|
||||
|
||||
out, err = ExecIp("rule", "show")
|
||||
rules, err := netlink.RuleList(nl.FAMILY_ALL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error while getting rules: %w", err)
|
||||
}
|
||||
|
||||
for _, line := range strings.Split(string(out), "\n") {
|
||||
if strings.Contains(line, "lookup") {
|
||||
parts := strings.Fields(line)
|
||||
for i, part := range parts {
|
||||
if part == "lookup" && i+1 < len(parts) {
|
||||
tableNum, ok := tableAliases[parts[i+1]]
|
||||
if !ok {
|
||||
tableNumInt, _ := strconv.Atoi(parts[i+1])
|
||||
tableNum = uint16(tableNumInt)
|
||||
}
|
||||
tableMap[tableNum] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, rule := range rules {
|
||||
tableMap[rule.Table] = struct{}{}
|
||||
}
|
||||
|
||||
tables := make([]uint16, len(tableMap))
|
||||
tables := make([]int, len(tableMap))
|
||||
counter := 0
|
||||
for table, _ := range tableMap {
|
||||
tables[counter] = table
|
||||
@ -182,7 +101,7 @@ func GetUsedTables() ([]uint16, error) {
|
||||
return tables, nil
|
||||
}
|
||||
|
||||
func GetUnusedTable(startFrom uint16) (uint16, error) {
|
||||
func GetUnusedTable(startFrom int) (int, error) {
|
||||
usedTables, err := GetUsedTables()
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("error while getting used tables: %w", err)
|
||||
|
Loading…
x
Reference in New Issue
Block a user