Files
elmprodvpn/selective-vpn-api/app/traffic_mode_iface.go

158 lines
4.5 KiB
Go

package app
import (
"encoding/json"
"fmt"
"os"
trafficmodepkg "selective-vpn-api/app/trafficmode"
"strings"
)
func ensureRoutesTableEntry() {
data, _ := os.ReadFile("/etc/iproute2/rt_tables")
want := fmt.Sprintf("%s %s", routesTableNum(), routesTableName())
if strings.Contains(string(data), "\n"+want) || strings.HasPrefix(string(data), want) {
return
}
f, err := os.OpenFile("/etc/iproute2/rt_tables", os.O_APPEND|os.O_WRONLY, 0o644)
if err != nil {
return
}
defer f.Close()
_, _ = fmt.Fprintf(f, "%s\n", want)
}
func ifaceExists(iface string) bool {
return trafficmodepkg.IfaceExists(iface, runCommand)
}
func statusIfaceFromFile() string {
data, err := os.ReadFile(statusFilePath)
if err != nil {
return ""
}
var st Status
if json.Unmarshal(data, &st) != nil {
return ""
}
return strings.TrimSpace(st.Iface)
}
func listUpIfaces() []string {
return trafficmodepkg.ListUpIfaces(runCommand)
}
func listSelectableIfaces(preferred string) []string {
return trafficmodepkg.ListSelectableIfaces(listUpIfaces(), preferred)
}
func isVPNLikeIface(iface string) bool {
return trafficmodepkg.IsVPNLikeIface(iface)
}
func resolveTrafficIface(preferred string) (string, string) {
return trafficmodepkg.ResolveTrafficIface(preferred, ifaceExists, statusIfaceFromFile, listUpIfaces)
}
type autoLocalRoute = trafficmodepkg.AutoLocalRoute
func parseRouteDevice(fields []string) string {
return trafficmodepkg.ParseRouteDevice(fields)
}
func isContainerIface(iface string) bool {
return trafficmodepkg.IsContainerIface(iface)
}
func routeLineIsLinkDown(line string) bool {
return trafficmodepkg.RouteLineIsLinkDown(line)
}
func isAutoBypassDestination(dst string) bool {
return trafficmodepkg.IsAutoBypassDestination(dst)
}
func detectAutoLocalBypassRoutes(vpnIface string) []autoLocalRoute {
vpnIface = strings.TrimSpace(vpnIface)
out, _, code, _ := runCommand("ip", "-4", "route", "show", "table", "main")
if code != 0 {
return nil
}
return trafficmodepkg.ParseAutoBypassRoutes(out, vpnIface, isVPNLikeIface)
}
func applyAutoLocalBypass(vpnIface string) {
for _, rt := range detectAutoLocalBypassRoutes(vpnIface) {
_, _, _, _ = runCommand(
"ip", "-4", "route", "replace",
rt.Dst, "dev", rt.Dev, "table", routesTableName(),
)
}
}
func ingressBypassConfig() trafficmodepkg.IngressBypassConfig {
return trafficmodepkg.IngressBypassConfig{
TableName: routesTableName(),
PreroutingChain: trafficIngressPreroutingChain,
OutputChain: trafficIngressOutputChain,
MarkIngress: MARK_INGRESS,
CaptureComment: trafficIngressCaptureComment,
RestoreComment: trafficIngressRestoreComment,
}
}
func ensureIngressReplyBypassChains() {
trafficmodepkg.EnsureIngressReplyBypassChains(ingressBypassConfig(), runCommandTimeout)
}
func flushIngressReplyBypassChains() error {
return trafficmodepkg.FlushIngressReplyBypassChains(ingressBypassConfig(), runCommandTimeout)
}
func enableIngressReplyBypass(vpnIface string) error {
return trafficmodepkg.EnableIngressReplyBypass(ingressBypassConfig(), strings.TrimSpace(vpnIface), runCommandTimeout)
}
func disableIngressReplyBypass() error {
return trafficmodepkg.DisableIngressReplyBypass(ingressBypassConfig(), runCommandTimeout)
}
func ingressReplyNftActive() bool {
return trafficmodepkg.IngressReplyNftActive(ingressBypassConfig(), runCommandTimeout)
}
func prefStr(v int) string {
return trafficmodepkg.PrefStr(v)
}
func trafficModeRulesConfig() trafficmodepkg.RulesConfig {
return trafficmodepkg.RulesConfig{
RoutesTableName: routesTableName(),
Mark: MARK,
MarkIngress: MARK_INGRESS,
PrefSelective: trafficRulePrefSelective,
PrefFull: trafficRulePrefFull,
PrefMarkIngressReply: trafficRulePrefMarkIngressReply,
ModeFull: string(TrafficModeFullTunnel),
ModeSelective: string(TrafficModeSelective),
ModeDirect: string(TrafficModeDirect),
}
}
func trafficModeOverrideConfig() trafficmodepkg.OverrideConfig {
return trafficmodepkg.OverrideConfig{
RoutesTableName: routesTableName(),
RulePerKindLimit: trafficRulePerKindLimit,
PrefManagedMin: trafficRulePrefManagedMin,
PrefManagedMax: trafficRulePrefManagedMax,
PrefDirectSubnetBase: trafficRulePrefDirectSubnetStart,
PrefDirectUIDBase: trafficRulePrefDirectUIDStart,
PrefVPNSubnetBase: trafficRulePrefVPNSubnetStart,
PrefVPNUIDBase: trafficRulePrefVPNUIDStart,
}
}
func removeTrafficRulesForTable() {
trafficmodepkg.RemoveRulesForTable(trafficModeOverrideConfig(), runCommand)
}