48 print "failed to determine if IPv6 forwarding is enabled or not" |
50 print "failed to determine if IPv6 forwarding is enabled or not" |
49 return smf_include.SMF_EXIT_ERR_FATAL |
51 return smf_include.SMF_EXIT_ERR_FATAL |
50 v6fwding = "on" in output |
52 v6fwding = "on" in output |
51 |
53 |
52 if not any((v4fwding, v6fwding)): |
54 if not any((v4fwding, v6fwding)): |
53 print "System-wide IPv4 or IPv6 (or both) forwarding must be enabled " \ |
55 print "System-wide IPv4 or IPv6 (or both) forwarding must be " \ |
54 "before enabling %s" % os.getenv("SMF_FMRI") |
56 "enabled before enabling neutron-l3-agent" |
55 return smf_include.SMF_EXIT_ERR_CONFIG |
57 return smf_include.SMF_EXIT_ERR_CONFIG |
56 |
58 |
57 cmd = "/usr/lib/neutron/neutron-l3-agent --config-file %s " \ |
59 cmd = "/usr/lib/neutron/neutron-l3-agent --config-file %s " \ |
58 "--config-file %s" % tuple(sys.argv[2:4]) |
60 "--config-file %s" % tuple(sys.argv[2:4]) |
59 smf_include.smf_subprocess(cmd) |
61 smf_include.smf_subprocess(cmd) |
60 |
62 |
|
63 |
|
64 def stop(): |
|
65 try: |
|
66 # first kill the SMF contract |
|
67 check_call(["/usr/bin/pkill", "-c", sys.argv[2]]) |
|
68 except CalledProcessError as err: |
|
69 print "failed to kill the SMF contract: %s" % (err) |
|
70 return smf_include.SMF_EXIT_ERR_FATAL |
|
71 # remove VNICs associated with L3 agent |
|
72 cmd = ["/usr/sbin/ipadm", "show-if", "-p", "-o", "ifname"] |
|
73 p = Popen(cmd, stdout=PIPE, stderr=PIPE) |
|
74 output, error = p.communicate() |
|
75 if p.returncode != 0: |
|
76 print "failed to retrieve IP interface names" |
|
77 return smf_include.SMF_EXIT_ERR_CONFIG |
|
78 |
|
79 ifnames = output.splitlines() |
|
80 # L3 agent datalinks are always 15 characters in length. They start |
|
81 # with either 'l3i' or 'l3e', end with '_0', and in between they are |
|
82 # hexadecimal digits. |
|
83 prog = re.compile('l3[ie][0-9A-Fa-f\_]{10}_0') |
|
84 for ifname in ifnames: |
|
85 if not prog.search(ifname): |
|
86 continue |
|
87 try: |
|
88 # first remove the IP |
|
89 check_call(["/usr/bin/pfexec", "/usr/sbin/ipadm", "delete-ip", |
|
90 ifname]) |
|
91 # next remove the VNIC |
|
92 check_call(["/usr/bin/pfexec", "/usr/sbin/dladm", "delete-vnic", |
|
93 ifname]) |
|
94 except CalledProcessError as err: |
|
95 print "failed to remove datalinks used by L3 agent: %s" % (err) |
|
96 return smf_include.SMF_EXIT_ERR_FATAL |
|
97 |
|
98 # remove IP Filter rules added by neutron-l3-agent |
|
99 cmd = ["/usr/bin/pfexec", "/usr/sbin/ipfstat", "-io"] |
|
100 p = Popen(cmd, stdout=PIPE, stderr=PIPE) |
|
101 output, error = p.communicate() |
|
102 if p.returncode != 0: |
|
103 print "failed to retrieve IP Filter rules" |
|
104 return smf_include.SMF_EXIT_ERR_FATAL |
|
105 |
|
106 ipfilters = output.splitlines() |
|
107 # L3 agent IP Filter rules are of the form |
|
108 # block in quick on l3i64cbb496_a_0 from ... to pool/15417332 |
|
109 prog = re.compile('on l3i[0-9A-Fa-f\_]{10}_0') |
|
110 ippool_names = [] |
|
111 for ipf in ipfilters: |
|
112 if not prog.search(ipf): |
|
113 continue |
|
114 # capture the IP pool name |
|
115 ippool_names.append(ipf.split('pool/')[1]) |
|
116 |
|
117 try: |
|
118 # remove the IP Filter rule |
|
119 p = Popen(["echo", ipf], stdout=PIPE) |
|
120 check_call(["/usr/bin/pfexec", "/usr/sbin/ipf", "-r", "-f", "-"], |
|
121 stdin=p.stdout) |
|
122 except CalledProcessError as err: |
|
123 print "failed to remove IP Filter rule %s: %s" % (ipf, err) |
|
124 return smf_include.SMF_EXIT_ERR_FATAL |
|
125 |
|
126 # remove IP Pools added by neutron-l3-agent |
|
127 for ippool_name in ippool_names: |
|
128 try: |
|
129 check_call(["/usr/bin/pfexec", "/usr/sbin/ippool", "-R", |
|
130 "-m", ippool_name, "-t", "tree"]) |
|
131 except CalledProcessError as err: |
|
132 print "failed to remove IP Pool %s: %s" % (ippool_name, err) |
|
133 return smf_include.SMF_EXIT_ERR_FATAL |
|
134 |
|
135 # remove IP NAT rules added by neutron-l3-agent |
|
136 cmd = ["/usr/bin/pfexec", "/usr/sbin/ipnat", "-lR"] |
|
137 p = Popen(cmd, stdout=PIPE, stderr=PIPE) |
|
138 output, error = p.communicate() |
|
139 if p.returncode != 0: |
|
140 print "failed to retrieve IP NAT rules" |
|
141 return smf_include.SMF_EXIT_ERR_FATAL |
|
142 |
|
143 ipnat_rules = output.splitlines() |
|
144 # L3 agent IP NAT rules are of the form |
|
145 # bimap l3e64ccc496_a_0 192.168.1.3/32 -> 172.16.10.3/32 |
|
146 prog = re.compile('l3e[0-9A-Fa-f\_]{10}_0') |
|
147 for ipnat_rule in ipnat_rules: |
|
148 if not prog.search(ipnat_rule): |
|
149 continue |
|
150 # remove the IP NAT rule |
|
151 try: |
|
152 p = Popen(["echo", ipnat_rule], stdout=PIPE) |
|
153 check_call(["/usr/bin/pfexec", "/usr/sbin/ipnat", "-r", "-f", "-"], |
|
154 stdin=p.stdout) |
|
155 except CalledProcessError as err: |
|
156 print "failed to remove IP NAT rule %s: %s" % (ipnat_rule, err) |
|
157 return smf_include.SMF_EXIT_ERR_FATAL |
|
158 |
|
159 return smf_include.SMF_EXIT_OK |
|
160 |
61 if __name__ == "__main__": |
161 if __name__ == "__main__": |
62 os.putenv("LC_ALL", "C") |
162 os.putenv("LC_ALL", "C") |
63 smf_include.smf_main() |
163 smf_include.smf_main() |