components/openstack/neutron/files/neutron-l3-agent
branchs11-update
changeset 3178 77584387a894
parent 3077 3e8d5f02f4a0
child 1977 12e9c20eef5a
equal deleted inserted replaced
3175:1ff833d174d4 3178:77584387a894
    13 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
    13 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
    14 #    License for the specific language governing permissions and limitations
    14 #    License for the specific language governing permissions and limitations
    15 #    under the License.
    15 #    under the License.
    16 
    16 
    17 import os
    17 import os
       
    18 import re
    18 import sys
    19 import sys
    19 
    20 
       
    21 import netaddr
    20 import smf_include
    22 import smf_include
    21 
    23 
    22 from subprocess import Popen, PIPE
    24 from subprocess import CalledProcessError, Popen, PIPE, check_call
    23 
    25 
    24 
    26 
    25 def start():
    27 def start():
    26     # verify paths are valid
    28     # verify paths are valid
    27     for f in sys.argv[2:4]:
    29     for f in sys.argv[2:4]:
    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()