package trafficappmarks import ( "fmt" "os" "path/filepath" "strings" "syscall" ) func ResolveCgroupV2PathForNft(input string, cgroupRootPath string) (rel string, level int, inodeID uint64, abs string, err error) { raw := strings.TrimSpace(input) if raw == "" { return "", 0, 0, "", fmt.Errorf("empty cgroup") } rel = NormalizeCgroupRelOnly(raw) if rel == "" { return "", 0, 0, raw, fmt.Errorf("invalid cgroup path: %s", raw) } inodeID, err = CgroupDirInode(cgroupRootPath, rel) if err != nil { return "", 0, 0, raw, err } level = strings.Count(rel, "/") + 1 abs = "/" + rel return rel, level, inodeID, abs, nil } func NormalizeCgroupRelOnly(raw string) string { rel := strings.TrimSpace(raw) rel = strings.TrimPrefix(rel, "/") rel = filepath.Clean(rel) if rel == "." || rel == "" { return "" } if strings.HasPrefix(rel, "..") || strings.Contains(rel, "../") { return "" } return rel } func CgroupDirInode(cgroupRootPath, rel string) (uint64, error) { full := filepath.Join(cgroupRootPath, strings.TrimPrefix(rel, "/")) fi, err := os.Stat(full) if err != nil || fi == nil || !fi.IsDir() { return 0, fmt.Errorf("cgroup not found: %s", "/"+strings.TrimPrefix(rel, "/")) } st, ok := fi.Sys().(*syscall.Stat_t) if !ok || st == nil { return 0, fmt.Errorf("cannot stat cgroup: %s", "/"+strings.TrimPrefix(rel, "/")) } if st.Ino == 0 { return 0, fmt.Errorf("invalid cgroup inode id: %s", "/"+strings.TrimPrefix(rel, "/")) } return st.Ino, nil }