counters.go 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. package firewall
  2. import (
  3. "fmt"
  4. "os/exec"
  5. "strings"
  6. )
  7. func (m *FirewallManager) ResetRuleCounters(kind, id string) error {
  8. m.mu.Lock()
  9. defer m.mu.Unlock()
  10. found := false
  11. switch kind {
  12. case "filter":
  13. for _, r := range m.filterRules {
  14. found = found || r.ID == id
  15. }
  16. case "nat":
  17. for _, r := range m.natRules {
  18. found = found || r.ID == id
  19. }
  20. case "mangle":
  21. for _, r := range m.mangleRules {
  22. found = found || r.ID == id
  23. }
  24. default:
  25. return fmt.Errorf("unknown rule kind")
  26. }
  27. if !found {
  28. return fmt.Errorf("rule not found")
  29. }
  30. for _, binary := range []string{"iptables", "ip6tables"} {
  31. out, err := exec.Command(binary + "-save").Output()
  32. if err != nil {
  33. return err
  34. }
  35. table := ""
  36. numbers := map[string]int{}
  37. for _, line := range strings.Split(string(out), "\n") {
  38. if strings.HasPrefix(line, "*") {
  39. table = line[1:]
  40. numbers = map[string]int{}
  41. }
  42. if !strings.HasPrefix(line, "-A ") {
  43. continue
  44. }
  45. fields := strings.Fields(line)
  46. chain := fields[1]
  47. numbers[chain]++
  48. if table != kind && !(kind == "filter" && table == "filter") {
  49. continue
  50. }
  51. if !strings.HasPrefix(chain, "DT_") {
  52. continue
  53. }
  54. if strings.Contains(line, "--comment "+quote("id:"+id)) || strings.Contains(line, "--comment "+quote("id:"+id+":log")) {
  55. if out, err := exec.Command(binary, "-t", table, "-Z", chain, fmt.Sprint(numbers[chain])).CombinedOutput(); err != nil {
  56. return fmt.Errorf("reset counter: %s: %w", out, err)
  57. }
  58. }
  59. }
  60. }
  61. return nil
  62. }