OpenStack-Neutron-VPNaaS-代码

时间:2023-03-09 05:25:09
OpenStack-Neutron-VPNaaS-代码

目前juno只支持ipsec的vpn  但是其实稍微修改代码pptp/openvpn/gre也都是可以支持的,下面看看vpn服务的代码流程:

默认我们创建好了ide策略、ipsec策略和vpn服务,因为这几个都是直接在数据库中添加记录,不实际做其他事情

OpenStack-Neutron-VPNaaS-代码

下面看看创建一个连接的代码
路径: neutron/services/vpn/plugin.py

类:VPNPluginDb

方法:create_ipsec_site_connection

这个方法会首先创建数据库的ipsec_site_connection记录

def create_ipsec_site_connection(self, context, ipsec_site_connection):
ipsec_site_connection = super(
VPNDriverPlugin, self).create_ipsec_site_connection(
context, ipsec_site_connection)# 1.创建数据库记录
driver = self._get_driver_for_ipsec_site_connection(
context, ipsec_site_connection) # 2.获取driver,在配置文件配置的,这里是ipsec
driver.create_ipsec_site_connection(context, ipsec_site_connection) #3.调用vpn_service类中的方法开始底层的操作
return ipsec_site_connection

 1.

路径:neutron/db/vpn/vpn_db.py

类:VPNPluginDb

方法:create_ipsec_site_connection

这个方法里面会根据ipsec_site_connection来获取vpn服务的id,ike策略id,ipsec策略id
从而得到数据中对应的vpn服务,ide策略,ipsec策略的数据记录,最后创建ipsec_site_connection数据库记录

3.

路径: neutron/services/vpn/service_drivers/ipsec.py

类:VPNPluginDb

方法:create_ipsec_site_connection

调用rpc方法vpnservice_updated

def create_ipsec_site_connection(self, context, ipsec_site_connection):
vpnservice = self.service_plugin._get_vpnservice(
context, ipsec_site_connection['vpnservice_id'])
self.agent_rpc.vpnservice_updated(context, vpnservice['router_id'])

路径: neutron/services/vpn/device_drivers/ipsec.py

类:IPsecDriver

方法:vpnservice_updated,该方法调用sync方法

def sync(self, context, routers):
vpnservices = self.agent_rpc.get_vpn_services_on_host(
context, self.host)#获取数据库中有关vpn的记录列表
router_ids = [vpnservice['router_id'] for vpnservice in vpnservices]
# Ensure the ipsec process is enabled
for vpnservice in vpnservices:
process = self.ensure_process(vpnservice['router_id'],
vpnservice=vpnservice) #创建openswan进程,初始化文件和目录,数据库字段过滤等等
self._update_nat(vpnservice, self.agent.add_nat_rule) #在路由空间中创建nat规则
process.update() #启动openswan进程 # Delete any IPSec processes that are
# associated with routers, but are not running the VPN service.
for router in routers:
#We are using router id as process_id
process_id = router['id']
if process_id not in router_ids:
process = self.ensure_process(process_id)
self.destroy_router(process_id) # Delete any IPSec processes running
# VPN that do not have an associated router.
process_ids = [process_id
for process_id in self.processes
if process_id not in router_ids]
for process_id in process_ids:
self.destroy_router(process_id)
self.report_status(context)

  

启动openswan进程
def update(self):
"""Update Status based on vpnservice configuration."""
if self.vpnservice and not self.vpnservice['admin_state_up']:
self.disable()
else:
self.enable() if plugin_utils.in_pending_status(self.vpnservice['status']):
self.updated_pending_status = True self.vpnservice['status'] = self.status
for ipsec_site_conn in self.vpnservice['ipsec_site_connections']:
if plugin_utils.in_pending_status(ipsec_site_conn['status']):
conn_id = ipsec_site_conn['id']
conn_status = self.connection_status.get(conn_id)
if not conn_status:
continue
conn_status['updated_pending_status'] = True
ipsec_site_conn['status'] = conn_status['status']

enable中调用start方法

def start(self):
"""Start the process. Note: if there is not namespace yet,
just do nothing, and wait next event.
"""
if not self.namespace:
return
virtual_private = self._virtual_privates()
self.clear_pid() #这里需要清空对应目录中的pid文件,不然会报错 #start pluto IKE keying daemon
  #启动IKE守护进程
self._execute([self.binary,
'pluto',
'--ctlbase', self.pid_path,
'--ipsecdir', self.ipsecd_dir,
#'--use-netkey',
'--uniqueids',
'--nat_traversal',
'--secretsfile', self.secrets_file,
'--virtual_private', virtual_private
])
#add connections
for ipsec_site_conn in self.vpnservice['ipsec_site_connections']:
nexthop = self._get_nexthop(ipsec_site_conn['peer_address'])
self._execute([self.binary,
'addconn',
'--ctlbase', '%s.ctl' % self.pid_path,
# '--defaultroutenexthop', nexthop,
'--config', self.config_file,
ipsec_site_conn['id']
])
#TODO(nati) fix this when openswan is fixed
#Due to openswan bug, this command always exit with 3
#start whack ipsec keying daemon
self._execute([self.binary,
'whack',
'--ctlbase', self.pid_path,
'--listen',
], check_exit_code=False) for ipsec_site_conn in self.vpnservice['ipsec_site_connections']:
if not ipsec_site_conn['initiator'] == 'start':
continue #initiate ipsec connection
self._execute([self.binary,
'whack',
'--ctlbase', self.pid_path,
'--name', ipsec_site_conn['id'],
'--asynchronous',
'--initiate'
])