summaryrefslogtreecommitdiff
path: root/scripts/vyatta-conntrack-ignore.pl
blob: 701c8b875ecb2cc13baa11e5348a036ac225aecd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/usr/bin/perl

use lib "/opt/vyatta/share/perl5";
use warnings;
use strict;

use Vyatta::Config;
use Vyatta::Conntrack::RuleCT;
use Vyatta::Conntrack::RuleIgnore;
use Vyatta::IpTables::AddressFilter;
use Vyatta::Conntrack::ConntrackUtil;
use Getopt::Long;
use Vyatta::Zone;
use Sys::Syslog qw(:standard :macros);

#for future use when v6 ignore s need to be set
my %cmd_hash = ( 'ipv4'        => 'iptables',
		 'ipv6'   => 'ip6tables');
# Enable printing debug output to stdout.
my $debug_flag = 0;

# Enable sending debug output to syslog.
my $syslog_flag = 0;
my $nfct = "sudo /usr/sbin/nfct";
my ($create, $delete, $update);
my $CTERROR = "Conntrack ignore  error:";
GetOptions("create=s"        => \$create,
           "delete=s"        => \$delete,
           "update=s"        => \$update,
);

update_config();

openlog("vyatta-conntrack", "pid", "local0");

sub remove_ignore_policy {
    my ($rule_string) = @_;
    my $iptables_cmd1 = "iptables -D VYATTA_CT_IGNORE -t raw $rule_string -j NOTRACK";
    my $iptables_cmd2 = "iptables -D VYATTA_CT_IGNORE -t raw $rule_string -j RETURN";
    run_cmd($iptables_cmd2);
    if ($? >> 8) {
     print "$CTERROR failed to run $iptables_cmd2\n";    
      #dont exit, try to clean as much. 
    }
    run_cmd($iptables_cmd1);
    if ($? >> 8) {
      print "$CTERROR failed to run $iptables_cmd1\n";    
    }
}

sub apply_ignore_policy {
   my ($rule_string, $rule, $num_rules) = @_;
   # insert at num_rules + 1 as there are so many rules already. 
   my $iptables_cmd1 = "iptables -I VYATTA_CT_IGNORE $num_rules -t raw $rule_string -j NOTRACK";
   $num_rules +=1;
   my $iptables_cmd2 = "iptables -I VYATTA_CT_IGNORE $num_rules -t raw $rule_string -j RETURN";
   run_cmd($iptables_cmd1);
    if ($? >> 8) {
     print "$CTERROR failed to run $iptables_cmd1\n";    
     exit 1; 
   }
   run_cmd($iptables_cmd2);
    if ($? >> 8) {
     print "$CTERROR failed to run $iptables_cmd2\n";    
     exit 1; 
   }
}

sub handle_rule_creation {
  my ($rule, $num_rules) = @_;
  my $node = new Vyatta::Conntrack::RuleIgnore;
  my ($rule_string);

  do_interface_check($rule);
  $node->setup("system conntrack ignore rule $rule");
  $rule_string = $node->rule();
  apply_ignore_policy($rule_string, $rule, $num_rules);
}

# mandate only one interface configuration per rule
sub do_interface_check {
  my ($rule) = @_;
  my $config = new Vyatta::Config;
  my $intf_nos = $config->listNodes("system conntrack ignore rule $rule inbound-interface");
  if (($intf_nos > 1)) {
    Vyatta::Config::outputError(["Conntrack"], "Conntrack config error: configure at most one inbound interface in rule $rule");
    exit 1;
  }
}

sub handle_rule_modification {
  my ($rule, $num_rules) = @_;
  do_interface_check($rule);
  handle_rule_deletion($rule);
  handle_rule_creation($rule, $num_rules);
}

sub handle_rule_deletion {
  my ($rule) = @_;
  my $node = new Vyatta::Conntrack::RuleIgnore;
  my ($rule_string);
  $node->setupOrig("system conntrack ignore rule $rule");
  $rule_string = $node->rule();
  remove_ignore_policy($rule_string);
}

sub numerically { $a <=> $b; }

sub update_config {
  my $config = new Vyatta::Config;
  my %rules = (); #hash of ignore config rules  
  my $iptables_cmd = $cmd_hash{'ipv4'};

  $config->setLevel("system conntrack ignore rule");
  %rules = $config->listNodeStatus();

  my $iptablesrule = 1;
  foreach my $rule (sort numerically keys %rules) { 
    if ("$rules{$rule}" eq 'static') {
      $iptablesrule+=2;
    } elsif ("$rules{$rule}" eq 'added') {      
        handle_rule_creation($rule, $iptablesrule);
        $iptablesrule+=2;
    } elsif ("$rules{$rule}" eq 'changed') {
        handle_rule_modification($rule, $iptablesrule);
        $iptablesrule+=2;
    } elsif ("$rules{$rule}" eq 'deleted') {
        handle_rule_deletion($rule);
    }  
  }
}