Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-UPF
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
1
Issues
1
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
OpenXG
OpenXG-UPF
Commits
444bd85d
Commit
444bd85d
authored
Feb 03, 2021
by
吴洲洋
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
update gtpu export ip and gtpu entry ip
parent
f89a03ef
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
789 additions
and
55 deletions
+789
-55
etc/config_system.sh
etc/config_system.sh
+5
-5
etc/n4_config.yaml
etc/n4_config.yaml
+1
-1
etc/startup_debug.conf
etc/startup_debug.conf
+3
-3
etc/supervisor-configure.yaml
etc/supervisor-configure.yaml
+0
-32
etc/template/config_system.template
etc/template/config_system.template
+2
-2
etc/upf.yaml
etc/upf.yaml
+11
-10
plugin/replace/replace
plugin/replace/replace
+0
-0
scripts/dpdk-devbind.py
scripts/dpdk-devbind.py
+741
-0
scripts/run_upf.sh
scripts/run_upf.sh
+26
-2
No files found.
etc/config_system.sh
View file @
444bd85d
set
interface state GigabitEthernet2/
2
/0 up
set
interface ip address GigabitEthernet2/
2/0 192.168.1
0.10/24
set
interface state GigabitEthernet2/
4
/0 up
set
interface ip address GigabitEthernet2/
4/0 192.168.3
0.10/24
set
interface state GigabitEthernet2/
3
/0 up
set
interface ip address GigabitEthernet2/
3/0 192.168.3
0.10/24
ip route add 0.0.0.0/0 via GigabitEthernet2/
3
/0
set
interface state GigabitEthernet2/
5
/0 up
set
interface ip address GigabitEthernet2/
5/0 192.168.5
0.10/24
ip route add 0.0.0.0/0 via GigabitEthernet2/
5
/0
...
...
etc/n4_config.yaml
View file @
444bd85d
gnb
:
192.168.10.10
smf
:
192.168.2.58
upf
:
192.168.2.
209
upf
:
192.168.2.
123
logSize
:
100
etc/startup_debug.conf
View file @
444bd85d
...
...
@@ -31,7 +31,7 @@ cpu {
## Set logical CPU core where main thread runs, if main core is not set
## VPP will use core 1 if available
main
-
core
3
main
-
core
14
## Set logical CPU core(s) where worker threads are running
#corelist-workers 2-3
...
...
@@ -97,8 +97,8 @@ dpdk {
#82576 1G
dev
0000
:
02
:
0
2
.
0
dev
0000
:
02
:
0
3
.
0
dev
0000
:
02
:
0
4
.
0
dev
0000
:
02
:
0
5
.
0
## Whitelist specific interface by specifying PCI address and in
## addition specify custom parameters for this interface
...
...
etc/supervisor-configure.yaml
deleted
100644 → 0
View file @
f89a03ef
gnb
:
username
:
root
password
:
123456
remoteHost
:
192.168.2.128
inter
:
eno1
smf
:
username
:
root
password
:
123456
remoteHost
:
192.168.2.63
inter
:
ens33
udm
:
username
:
root
password
:
123456
remoteHost
:
192.168.2.63
amf
:
username
:
root
password
:
123456
remoteHost
:
192.168.2.63
inter
:
ens33
upf
:
username
:
root
password
:
remoteHost
:
192.168.2.133
vppinter
:
enp5s0
n4inter
:
enp14s0
vppEntry
:
TenGigabitEthernet2/0/0
vppExport
:
TenGigabitEthernet2/0/1
gateway
:
ens4f1
vppWatch
:
/opt/5gc/support-system/watch/upf_watch
tcpdump
:
true
reboot
:
true
runScript
:
/opt/5gc/support-system/test_start_5g.sh
etc/template/config_system.template
View file @
444bd85d
set interface state @gtpu_entry@ up
set interface ip address @gtpu_entry@
192.168.10.10
/24
set interface ip address @gtpu_entry@
@gtpu_entry_ip@
/24
set interface state @gtpu_export@ up
set interface ip address @gtpu_export@
192.168.30.10
/24
set interface ip address @gtpu_export@
@gtpu_export_ip@
/24
ip route add 0.0.0.0/0 via @gtpu_export@
...
...
etc/upf.yaml
View file @
444bd85d
vpp
:
system
:
gtpu_entry
:
GigabitEthernet2/2/0
gtpu_export
:
GigabitEthernet2/3/0
gtpu_entry
:
GigabitEthernet2/4/0
gtpu_export
:
GigabitEthernet2/5/0
gtpu_entry_ip
:
192.168.30.10
gtpu_export_ip
:
192.168.50.10
ip_link
:
ueip
:
192.169.0.0
ueIPPrefix
:
24
snatInter
:
ens33
snatIP
:
192.168.2.209
vppHost
:
ens36
vppHostIP
:
192.168.30.10
gtpu_entry
:
ens34
gtpu_export
:
ens35
snatInter
:
ens32
snatIP
:
192.168.2.123
vppHost
:
ens38
gtpu_entry
:
ens36
gtpu_export
:
ens37
startup
:
pci_addr_id_entry
:
02:0
2
.0
pci_addr_id_export
:
02:0
3
.0
pci_addr_id_entry
:
02:0
4
.0
pci_addr_id_export
:
02:0
5
.0
vpp_plugins_path
:
/usr/lib/x86_64-linux-gnu/vpp_plugins
drive
:
e1000
n4
:
...
...
plugin/replace/replace
View file @
444bd85d
No preview for this file type
scripts/dpdk-devbind.py
0 → 100755
View file @
444bd85d
#! /usr/bin/env python
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2010-2014 Intel Corporation
#
from
__future__
import
print_function
import
sys
import
os
import
getopt
import
subprocess
from
os.path
import
exists
,
abspath
,
dirname
,
basename
# The PCI base class for all devices
network_class
=
{
'Class'
:
'02'
,
'Vendor'
:
None
,
'Device'
:
None
,
'SVendor'
:
None
,
'SDevice'
:
None
}
acceleration_class
=
{
'Class'
:
'12'
,
'Vendor'
:
None
,
'Device'
:
None
,
'SVendor'
:
None
,
'SDevice'
:
None
}
ifpga_class
=
{
'Class'
:
'12'
,
'Vendor'
:
'8086'
,
'Device'
:
'0b30'
,
'SVendor'
:
None
,
'SDevice'
:
None
}
encryption_class
=
{
'Class'
:
'10'
,
'Vendor'
:
None
,
'Device'
:
None
,
'SVendor'
:
None
,
'SDevice'
:
None
}
intel_processor_class
=
{
'Class'
:
'0b'
,
'Vendor'
:
'8086'
,
'Device'
:
None
,
'SVendor'
:
None
,
'SDevice'
:
None
}
cavium_sso
=
{
'Class'
:
'08'
,
'Vendor'
:
'177d'
,
'Device'
:
'a04b,a04d'
,
'SVendor'
:
None
,
'SDevice'
:
None
}
cavium_fpa
=
{
'Class'
:
'08'
,
'Vendor'
:
'177d'
,
'Device'
:
'a053'
,
'SVendor'
:
None
,
'SDevice'
:
None
}
cavium_pkx
=
{
'Class'
:
'08'
,
'Vendor'
:
'177d'
,
'Device'
:
'a0dd,a049'
,
'SVendor'
:
None
,
'SDevice'
:
None
}
cavium_tim
=
{
'Class'
:
'08'
,
'Vendor'
:
'177d'
,
'Device'
:
'a051'
,
'SVendor'
:
None
,
'SDevice'
:
None
}
cavium_zip
=
{
'Class'
:
'12'
,
'Vendor'
:
'177d'
,
'Device'
:
'a037'
,
'SVendor'
:
None
,
'SDevice'
:
None
}
avp_vnic
=
{
'Class'
:
'05'
,
'Vendor'
:
'1af4'
,
'Device'
:
'1110'
,
'SVendor'
:
None
,
'SDevice'
:
None
}
octeontx2_sso
=
{
'Class'
:
'08'
,
'Vendor'
:
'177d'
,
'Device'
:
'a0f9,a0fa'
,
'SVendor'
:
None
,
'SDevice'
:
None
}
octeontx2_npa
=
{
'Class'
:
'08'
,
'Vendor'
:
'177d'
,
'Device'
:
'a0fb,a0fc'
,
'SVendor'
:
None
,
'SDevice'
:
None
}
octeontx2_dma
=
{
'Class'
:
'08'
,
'Vendor'
:
'177d'
,
'Device'
:
'a081'
,
'SVendor'
:
None
,
'SDevice'
:
None
}
intel_ioat_bdw
=
{
'Class'
:
'08'
,
'Vendor'
:
'8086'
,
'Device'
:
'6f20,6f21,6f22,6f23,6f24,6f25,6f26,6f27,6f2e,6f2f'
,
'SVendor'
:
None
,
'SDevice'
:
None
}
intel_ioat_skx
=
{
'Class'
:
'08'
,
'Vendor'
:
'8086'
,
'Device'
:
'2021'
,
'SVendor'
:
None
,
'SDevice'
:
None
}
intel_ntb_skx
=
{
'Class'
:
'06'
,
'Vendor'
:
'8086'
,
'Device'
:
'201c'
,
'SVendor'
:
None
,
'SDevice'
:
None
}
network_devices
=
[
network_class
,
cavium_pkx
,
avp_vnic
,
ifpga_class
]
baseband_devices
=
[
acceleration_class
]
crypto_devices
=
[
encryption_class
,
intel_processor_class
]
eventdev_devices
=
[
cavium_sso
,
cavium_tim
,
octeontx2_sso
]
mempool_devices
=
[
cavium_fpa
,
octeontx2_npa
]
compress_devices
=
[
cavium_zip
]
misc_devices
=
[
intel_ioat_bdw
,
intel_ioat_skx
,
intel_ntb_skx
,
octeontx2_dma
]
# global dict ethernet devices present. Dictionary indexed by PCI address.
# Each device within this is itself a dictionary of device properties
devices
=
{}
# list of supported DPDK drivers
dpdk_drivers
=
[
"igb_uio"
,
"vfio-pci"
,
"uio_pci_generic"
]
# list of currently loaded kernel modules
loaded_modules
=
None
# command-line arg flags
b_flag
=
None
status_flag
=
False
force_flag
=
False
args
=
[]
def
usage
():
'''Print usage information for the program'''
argv0
=
basename
(
sys
.
argv
[
0
])
print
(
"""
Usage:
------
%(argv0)s [options] DEVICE1 DEVICE2 ....
where DEVICE1, DEVICE2 etc, are specified via PCI "domain:bus:slot.func" syntax
or "bus:slot.func" syntax. For devices bound to Linux kernel drivers, they may
also be referred to by Linux interface name e.g. eth0, eth1, em0, em1, etc.
Options:
--help, --usage:
Display usage information and quit
-s, --status:
Print the current status of all known network, crypto, event
and mempool devices.
For each device, it displays the PCI domain, bus, slot and function,
along with a text description of the device. Depending upon whether the
device is being used by a kernel driver, the igb_uio driver, or no
driver, other relevant information will be displayed:
* the Linux interface name e.g. if=eth0
* the driver being used e.g. drv=igb_uio
* any suitable drivers not currently using that device
e.g. unused=igb_uio
NOTE: if this flag is passed along with a bind/unbind option, the
status display will always occur after the other operations have taken
place.
--status-dev:
Print the status of given device group. Supported device groups are:
"net", "baseband", "crypto", "event", "mempool" and "compress"
-b driver, --bind=driver:
Select the driver to use or
\"
none
\"
to unbind the device
-u, --unbind:
Unbind a device (Equivalent to
\"
-b none
\"
)
--force:
By default, network devices which are used by Linux - as indicated by
having routes in the routing table - cannot be modified. Using the
--force flag overrides this behavior, allowing active links to be
forcibly unbound.
WARNING: This can lead to loss of network connection and should be used
with caution.
Examples:
---------
To display current device status:
%(argv0)s --status
To display current network device status:
%(argv0)s --status-dev net
To bind eth1 from the current driver and move to use igb_uio
%(argv0)s --bind=igb_uio eth1
To unbind 0000:01:00.0 from using any driver
%(argv0)s -u 0000:01:00.0
To bind 0000:02:00.0 and 0000:02:00.1 to the ixgbe kernel driver
%(argv0)s -b ixgbe 02:00.0 02:00.1
"""
%
locals
())
# replace items from local variables
# This is roughly compatible with check_output function in subprocess module
# which is only available in python 2.7.
def
check_output
(
args
,
stderr
=
None
):
'''Run a command and capture its output'''
return
subprocess
.
Popen
(
args
,
stdout
=
subprocess
.
PIPE
,
stderr
=
stderr
).
communicate
()[
0
]
# check if a specific kernel module is loaded
def
module_is_loaded
(
module
):
global
loaded_modules
if
loaded_modules
:
return
module
in
loaded_modules
# Get list of sysfs modules (both built-in and dynamically loaded)
sysfs_path
=
'/sys/module/'
# Get the list of directories in sysfs_path
sysfs_mods
=
[
m
for
m
in
os
.
listdir
(
sysfs_path
)
if
os
.
path
.
isdir
(
os
.
path
.
join
(
sysfs_path
,
m
))]
# special case for vfio_pci (module is named vfio-pci,
# but its .ko is named vfio_pci)
sysfs_mods
=
[
a
if
a
!=
'vfio_pci'
else
'vfio-pci'
for
a
in
sysfs_mods
]
loaded_modules
=
sysfs_mods
return
module
in
sysfs_mods
def
check_modules
():
'''Checks that igb_uio is loaded'''
global
dpdk_drivers
# list of supported modules
mods
=
[{
"Name"
:
driver
,
"Found"
:
False
}
for
driver
in
dpdk_drivers
]
# first check if module is loaded
for
mod
in
mods
:
if
module_is_loaded
(
mod
[
"Name"
]):
mod
[
"Found"
]
=
True
# check if we have at least one loaded module
if
True
not
in
[
mod
[
"Found"
]
for
mod
in
mods
]
and
b_flag
is
not
None
:
print
(
"Warning: no supported DPDK kernel modules are loaded"
,
file
=
sys
.
stderr
)
# change DPDK driver list to only contain drivers that are loaded
dpdk_drivers
=
[
mod
[
"Name"
]
for
mod
in
mods
if
mod
[
"Found"
]]
def
has_driver
(
dev_id
):
'''return true if a device is assigned to a driver. False otherwise'''
return
"Driver_str"
in
devices
[
dev_id
]
def
get_pci_device_details
(
dev_id
,
probe_lspci
):
'''This function gets additional details for a PCI device'''
device
=
{}
if
probe_lspci
:
extra_info
=
check_output
([
"lspci"
,
"-vmmks"
,
dev_id
]).
splitlines
()
# parse lspci details
for
line
in
extra_info
:
if
len
(
line
)
==
0
:
continue
name
,
value
=
line
.
decode
().
split
(
"
\t
"
,
1
)
name
=
name
.
strip
(
":"
)
+
"_str"
device
[
name
]
=
value
# check for a unix interface name
device
[
"Interface"
]
=
""
for
base
,
dirs
,
_
in
os
.
walk
(
"/sys/bus/pci/devices/%s/"
%
dev_id
):
if
"net"
in
dirs
:
device
[
"Interface"
]
=
\
","
.
join
(
os
.
listdir
(
os
.
path
.
join
(
base
,
"net"
)))
break
# check if a port is used for ssh connection
device
[
"Ssh_if"
]
=
False
device
[
"Active"
]
=
""
return
device
def
clear_data
():
'''This function clears any old data'''
global
devices
devices
=
{}
def
get_device_details
(
devices_type
):
'''This function populates the "devices" dictionary. The keys used are
the pci addresses (domain:bus:slot.func). The values are themselves
dictionaries - one for each NIC.'''
global
devices
global
dpdk_drivers
# first loop through and read details for all devices
# request machine readable format, with numeric IDs and String
dev
=
{}
dev_lines
=
check_output
([
"lspci"
,
"-Dvmmnnk"
]).
splitlines
()
for
dev_line
in
dev_lines
:
if
len
(
dev_line
)
==
0
:
if
device_type_match
(
dev
,
devices_type
):
# Replace "Driver" with "Driver_str" to have consistency of
# of dictionary key names
if
"Driver"
in
dev
.
keys
():
dev
[
"Driver_str"
]
=
dev
.
pop
(
"Driver"
)
if
"Module"
in
dev
.
keys
():
dev
[
"Module_str"
]
=
dev
.
pop
(
"Module"
)
# use dict to make copy of dev
devices
[
dev
[
"Slot"
]]
=
dict
(
dev
)
# Clear previous device's data
dev
=
{}
else
:
name
,
value
=
dev_line
.
decode
().
split
(
"
\t
"
,
1
)
value_list
=
value
.
rsplit
(
' '
,
1
)
if
len
(
value_list
)
>
1
:
# String stored in <name>_str
dev
[
name
.
rstrip
(
":"
)
+
'_str'
]
=
value_list
[
0
]
# Numeric IDs
dev
[
name
.
rstrip
(
":"
)]
=
value_list
[
len
(
value_list
)
-
1
]
\
.
rstrip
(
"]"
).
lstrip
(
"["
)
if
devices_type
==
network_devices
:
# check what is the interface if any for an ssh connection if
# any to this host, so we can mark it later.
ssh_if
=
[]
route
=
check_output
([
"ip"
,
"-o"
,
"route"
])
# filter out all lines for 169.254 routes
route
=
"
\n
"
.
join
(
filter
(
lambda
ln
:
not
ln
.
startswith
(
"169.254"
),
route
.
decode
().
splitlines
()))
rt_info
=
route
.
split
()
for
i
in
range
(
len
(
rt_info
)
-
1
):
if
rt_info
[
i
]
==
"dev"
:
ssh_if
.
append
(
rt_info
[
i
+
1
])
# based on the basic info, get extended text details
for
d
in
devices
.
keys
():
if
not
device_type_match
(
devices
[
d
],
devices_type
):
continue
# get additional info and add it to existing data
devices
[
d
]
=
devices
[
d
].
copy
()
# No need to probe lspci
devices
[
d
].
update
(
get_pci_device_details
(
d
,
False
).
items
())
if
devices_type
==
network_devices
:
for
_if
in
ssh_if
:
if
_if
in
devices
[
d
][
"Interface"
].
split
(
","
):
devices
[
d
][
"Ssh_if"
]
=
True
devices
[
d
][
"Active"
]
=
"*Active*"
break
# add igb_uio to list of supporting modules if needed
if
"Module_str"
in
devices
[
d
]:
for
driver
in
dpdk_drivers
:
if
driver
not
in
devices
[
d
][
"Module_str"
]:
devices
[
d
][
"Module_str"
]
=
\
devices
[
d
][
"Module_str"
]
+
",%s"
%
driver
else
:
devices
[
d
][
"Module_str"
]
=
","
.
join
(
dpdk_drivers
)
# make sure the driver and module strings do not have any duplicates
if
has_driver
(
d
):
modules
=
devices
[
d
][
"Module_str"
].
split
(
","
)
if
devices
[
d
][
"Driver_str"
]
in
modules
:
modules
.
remove
(
devices
[
d
][
"Driver_str"
])
devices
[
d
][
"Module_str"
]
=
","
.
join
(
modules
)
def
device_type_match
(
dev
,
devices_type
):
for
i
in
range
(
len
(
devices_type
)):
param_count
=
len
(
[
x
for
x
in
devices_type
[
i
].
values
()
if
x
is
not
None
])
match_count
=
0
if
dev
[
"Class"
][
0
:
2
]
==
devices_type
[
i
][
"Class"
]:
match_count
=
match_count
+
1
for
key
in
devices_type
[
i
].
keys
():
if
key
!=
'Class'
and
devices_type
[
i
][
key
]:
value_list
=
devices_type
[
i
][
key
].
split
(
','
)
for
value
in
value_list
:
if
value
.
strip
(
' '
)
==
dev
[
key
]:
match_count
=
match_count
+
1
# count must be the number of non None parameters to match
if
match_count
==
param_count
:
return
True
return
False
def
dev_id_from_dev_name
(
dev_name
):
'''Take a device "name" - a string passed in by user to identify a NIC
device, and determine the device id - i.e. the domain:bus:slot.func - for
it, which can then be used to index into the devices array'''
# check if it's already a suitable index
if
dev_name
in
devices
:
return
dev_name
# check if it's an index just missing the domain part
elif
"0000:"
+
dev_name
in
devices
:
return
"0000:"
+
dev_name
else
:
# check if it's an interface name, e.g. eth1
for
d
in
devices
.
keys
():
if
dev_name
in
devices
[
d
][
"Interface"
].
split
(
","
):
return
devices
[
d
][
"Slot"
]
# if nothing else matches - error
raise
ValueError
(
"Unknown device: %s. "
"Please specify device in
\"
bus:slot.func
\"
format"
%
dev_name
)
def
unbind_one
(
dev_id
,
force
):
'''Unbind the device identified by "dev_id" from its current driver'''
dev
=
devices
[
dev_id
]
if
not
has_driver
(
dev_id
):
print
(
"Notice: %s %s %s is not currently managed by any driver"
%
(
dev
[
"Slot"
],
dev
[
"Device_str"
],
dev
[
"Interface"
]),
file
=
sys
.
stderr
)
return
# prevent us disconnecting ourselves
if
dev
[
"Ssh_if"
]
and
not
force
:
print
(
"Warning: routing table indicates that interface %s is active. "
"Skipping unbind"
%
dev_id
,
file
=
sys
.
stderr
)
return
# write to /sys to unbind
filename
=
"/sys/bus/pci/drivers/%s/unbind"
%
dev
[
"Driver_str"
]
try
:
f
=
open
(
filename
,
"a"
)
except
:
sys
.
exit
(
"Error: unbind failed for %s - Cannot open %s"
%
(
dev_id
,
filename
))
f
.
write
(
dev_id
)
f
.
close
()
def
bind_one
(
dev_id
,
driver
,
force
):
'''Bind the device given by "dev_id" to the driver "driver". If the device
is already bound to a different driver, it will be unbound first'''
dev
=
devices
[
dev_id
]
saved_driver
=
None
# used to rollback any unbind in case of failure
# prevent disconnection of our ssh session
if
dev
[
"Ssh_if"
]
and
not
force
:
print
(
"Warning: routing table indicates that interface %s is active. "
"Not modifying"
%
dev_id
,
file
=
sys
.
stderr
)
return
# unbind any existing drivers we don't want
if
has_driver
(
dev_id
):
if
dev
[
"Driver_str"
]
==
driver
:
print
(
"Notice: %s already bound to driver %s, skipping"
%
(
dev_id
,
driver
),
file
=
sys
.
stderr
)
return
else
:
saved_driver
=
dev
[
"Driver_str"
]
unbind_one
(
dev_id
,
force
)
dev
[
"Driver_str"
]
=
""
# clear driver string
# For kernels >= 3.15 driver_override can be used to specify the driver
# for a device rather than relying on the driver to provide a positive
# match of the device. The existing process of looking up
# the vendor and device ID, adding them to the driver new_id,
# will erroneously bind other devices too which has the additional burden
# of unbinding those devices
if
driver
in
dpdk_drivers
:
filename
=
"/sys/bus/pci/devices/%s/driver_override"
%
dev_id
if
os
.
path
.
exists
(
filename
):
try
:
f
=
open
(
filename
,
"w"
)
except
:
print
(
"Error: bind failed for %s - Cannot open %s"
%
(
dev_id
,
filename
),
file
=
sys
.
stderr
)
return
try
:
f
.
write
(
"%s"
%
driver
)
f
.
close
()
except
:
print
(
"Error: bind failed for %s - Cannot write driver %s to "
"PCI ID "
%
(
dev_id
,
driver
),
file
=
sys
.
stderr
)
return
# For kernels < 3.15 use new_id to add PCI id's to the driver
else
:
filename
=
"/sys/bus/pci/drivers/%s/new_id"
%
driver
try
:
f
=
open
(
filename
,
"w"
)
except
:
print
(
"Error: bind failed for %s - Cannot open %s"
%
(
dev_id
,
filename
),
file
=
sys
.
stderr
)
return
try
:
# Convert Device and Vendor Id to int to write to new_id
f
.
write
(
"%04x %04x"
%
(
int
(
dev
[
"Vendor"
],
16
),
int
(
dev
[
"Device"
],
16
)))
f
.
close
()
except
:
print
(
"Error: bind failed for %s - Cannot write new PCI ID to "
"driver %s"
%
(
dev_id
,
driver
),
file
=
sys
.
stderr
)
return
# do the bind by writing to /sys
filename
=
"/sys/bus/pci/drivers/%s/bind"
%
driver
try
:
f
=
open
(
filename
,
"a"
)
except
:
print
(
"Error: bind failed for %s - Cannot open %s"
%
(
dev_id
,
filename
),
file
=
sys
.
stderr
)
if
saved_driver
is
not
None
:
# restore any previous driver
bind_one
(
dev_id
,
saved_driver
,
force
)
return
try
:
f
.
write
(
dev_id
)
f
.
close
()
except
:
# for some reason, closing dev_id after adding a new PCI ID to new_id
# results in IOError. however, if the device was successfully bound,
# we don't care for any errors and can safely ignore IOError
tmp
=
get_pci_device_details
(
dev_id
,
True
)
if
"Driver_str"
in
tmp
and
tmp
[
"Driver_str"
]
==
driver
:
return
print
(
"Error: bind failed for %s - Cannot bind to driver %s"
%
(
dev_id
,
driver
),
file
=
sys
.
stderr
)
if
saved_driver
is
not
None
:
# restore any previous driver
bind_one
(
dev_id
,
saved_driver
,
force
)
return
# For kernels > 3.15 driver_override is used to bind a device to a driver.
# Before unbinding it, overwrite driver_override with empty string so that
# the device can be bound to any other driver
filename
=
"/sys/bus/pci/devices/%s/driver_override"
%
dev_id
if
os
.
path
.
exists
(
filename
):
try
:
f
=
open
(
filename
,
"w"
)
except
:
sys
.
exit
(
"Error: unbind failed for %s - Cannot open %s"
%
(
dev_id
,
filename
))
try
:
f
.
write
(
"
\00
"
)
f
.
close
()
except
:
sys
.
exit
(
"Error: unbind failed for %s - Cannot open %s"
%
(
dev_id
,
filename
))
def
unbind_all
(
dev_list
,
force
=
False
):
"""Unbind method, takes a list of device locations"""
if
dev_list
[
0
]
==
"dpdk"
:
for
d
in
devices
.
keys
():
if
"Driver_str"
in
devices
[
d
]:
if
devices
[
d
][
"Driver_str"
]
in
dpdk_drivers
:
unbind_one
(
devices
[
d
][
"Slot"
],
force
)
return
try
:
dev_list
=
map
(
dev_id_from_dev_name
,
dev_list
)
except
ValueError
as
ex
:
print
(
ex
)
sys
.
exit
(
1
)
for
d
in
dev_list
:
unbind_one
(
d
,
force
)
def
bind_all
(
dev_list
,
driver
,
force
=
False
):
"""Bind method, takes a list of device locations"""
global
devices
# a common user error is to forget to specify the driver the devices need to
# be bound to. check if the driver is a valid device, and if it is, show
# a meaningful error.
try
:
dev_id_from_dev_name
(
driver
)
# if we've made it this far, this means that the "driver" was a valid
# device string, so it's probably not a valid driver name.
sys
.
exit
(
"Error: Driver '%s' does not look like a valid driver. "
\
"Did you forget to specify the driver to bind devices to?"
%
driver
)
except
ValueError
:
# driver generated error - it's not a valid device ID, so all is well
pass
# check if we're attempting to bind to a driver that isn't loaded
if
not
module_is_loaded
(
driver
):
sys
.
exit
(
"Error: Driver '%s' is not loaded."
%
driver
)
try
:
dev_list
=
map
(
dev_id_from_dev_name
,
dev_list
)
except
ValueError
as
ex
:
sys
.
exit
(
ex
)
for
d
in
dev_list
:
bind_one
(
d
,
driver
,
force
)
# For kernels < 3.15 when binding devices to a generic driver
# (i.e. one that doesn't have a PCI ID table) using new_id, some devices
# that are not bound to any other driver could be bound even if no one has
# asked them to. hence, we check the list of drivers again, and see if
# some of the previously-unbound devices were erroneously bound.
if
not
os
.
path
.
exists
(
"/sys/bus/pci/devices/%s/driver_override"
%
d
):
for
d
in
devices
.
keys
():
# skip devices that were already bound or that we know should be bound
if
"Driver_str"
in
devices
[
d
]
or
d
in
dev_list
:
continue
# update information about this device
devices
[
d
]
=
dict
(
devices
[
d
].
items
()
+
get_pci_device_details
(
d
,
True
).
items
())
# check if updated information indicates that the device was bound
if
"Driver_str"
in
devices
[
d
]:
unbind_one
(
d
,
force
)
def
display_devices
(
title
,
dev_list
,
extra_params
=
None
):
'''Displays to the user the details of a list of devices given in
"dev_list". The "extra_params" parameter, if given, should contain a string
with %()s fields in it for replacement by the named fields in each
device's dictionary.'''
strings
=
[]
# this holds the strings to print. We sort before printing
print
(
"
\n
%s"
%
title
)
print
(
"="
*
len
(
title
))
if
len
(
dev_list
)
==
0
:
strings
.
append
(
"<none>"
)
else
:
for
dev
in
dev_list
:
if
extra_params
is
not
None
:
strings
.
append
(
"%s '%s %s' %s"
%
(
dev
[
"Slot"
],
dev
[
"Device_str"
],
dev
[
"Device"
],
extra_params
%
dev
))
else
:
strings
.
append
(
"%s '%s'"
%
(
dev
[
"Slot"
],
dev
[
"Device_str"
]))
# sort before printing, so that the entries appear in PCI order
strings
.
sort
()
print
(
"
\n
"
.
join
(
strings
))
# print one per line
def
show_device_status
(
devices_type
,
device_name
):
global
dpdk_drivers
kernel_drv
=
[]
dpdk_drv
=
[]
no_drv
=
[]
# split our list of network devices into the three categories above
for
d
in
devices
.
keys
():
if
device_type_match
(
devices
[
d
],
devices_type
):
if
not
has_driver
(
d
):
no_drv
.
append
(
devices
[
d
])
continue
if
devices
[
d
][
"Driver_str"
]
in
dpdk_drivers
:
dpdk_drv
.
append
(
devices
[
d
])
else
:
kernel_drv
.
append
(
devices
[
d
])
n_devs
=
len
(
dpdk_drv
)
+
len
(
kernel_drv
)
+
len
(
no_drv
)
# don't bother displaying anything if there are no devices
if
n_devs
==
0
:
msg
=
"No '%s' devices detected"
%
device_name
print
(
""
)
print
(
msg
)
print
(
""
.
join
(
'='
*
len
(
msg
)))
return
# print each category separately, so we can clearly see what's used by DPDK
if
len
(
dpdk_drv
)
!=
0
:
display_devices
(
"%s devices using DPDK-compatible driver"
%
device_name
,
dpdk_drv
,
"drv=%(Driver_str)s unused=%(Module_str)s"
)
if
len
(
kernel_drv
)
!=
0
:
display_devices
(
"%s devices using kernel driver"
%
device_name
,
kernel_drv
,
"if=%(Interface)s drv=%(Driver_str)s "
"unused=%(Module_str)s %(Active)s"
)
if
len
(
no_drv
)
!=
0
:
display_devices
(
"Other %s devices"
%
device_name
,
no_drv
,
"unused=%(Module_str)s"
)
def
show_status
():
'''Function called when the script is passed the "--status" option.
Displays to the user what devices are bound to the igb_uio driver, the
kernel driver or to no driver'''
if
status_dev
==
"net"
or
status_dev
==
"all"
:
show_device_status
(
network_devices
,
"Network"
)
if
status_dev
==
"baseband"
or
status_dev
==
"all"
:
show_device_status
(
baseband_devices
,
"Baseband"
)
if
status_dev
==
"crypto"
or
status_dev
==
"all"
:
show_device_status
(
crypto_devices
,
"Crypto"
)
if
status_dev
==
"event"
or
status_dev
==
"all"
:
show_device_status
(
eventdev_devices
,
"Eventdev"
)
if
status_dev
==
"mempool"
or
status_dev
==
"all"
:
show_device_status
(
mempool_devices
,
"Mempool"
)
if
status_dev
==
"compress"
or
status_dev
==
"all"
:
show_device_status
(
compress_devices
,
"Compress"
)
if
status_dev
==
"misc"
or
status_dev
==
"all"
:
show_device_status
(
misc_devices
,
"Misc (rawdev)"
)
def
parse_args
():
'''Parses the command-line arguments given by the user and takes the
appropriate action for each'''
global
b_flag
global
status_flag
global
status_dev
global
force_flag
global
args
if
len
(
sys
.
argv
)
<=
1
:
usage
()
sys
.
exit
(
0
)
try
:
opts
,
args
=
getopt
.
getopt
(
sys
.
argv
[
1
:],
"b:us"
,
[
"help"
,
"usage"
,
"status"
,
"status-dev="
,
"force"
,
"bind="
,
"unbind"
,
])
except
getopt
.
GetoptError
as
error
:
print
(
str
(
error
))
print
(
"Run '%s --usage' for further information"
%
sys
.
argv
[
0
])
sys
.
exit
(
1
)
for
opt
,
arg
in
opts
:
if
opt
==
"--help"
or
opt
==
"--usage"
:
usage
()
sys
.
exit
(
0
)
if
opt
==
"--status-dev"
:
status_flag
=
True
status_dev
=
arg
if
opt
==
"--status"
or
opt
==
"-s"
:
status_flag
=
True
status_dev
=
"all"
if
opt
==
"--force"
:
force_flag
=
True
if
opt
==
"-b"
or
opt
==
"-u"
or
opt
==
"--bind"
or
opt
==
"--unbind"
:
if
b_flag
is
not
None
:
sys
.
exit
(
"Error: binding and unbinding are mutually exclusive"
)
if
opt
==
"-u"
or
opt
==
"--unbind"
:
b_flag
=
"none"
else
:
b_flag
=
arg
def
do_arg_actions
():
'''do the actual action requested by the user'''
global
b_flag
global
status_flag
global
force_flag
global
args
if
b_flag
is
None
and
not
status_flag
:
print
(
"Error: No action specified for devices. "
"Please give a -b or -u option"
,
file
=
sys
.
stderr
)
usage
()
sys
.
exit
(
1
)
if
b_flag
is
not
None
and
len
(
args
)
==
0
:
print
(
"Error: No devices specified."
,
file
=
sys
.
stderr
)
usage
()
sys
.
exit
(
1
)
if
b_flag
==
"none"
or
b_flag
==
"None"
:
unbind_all
(
args
,
force_flag
)
elif
b_flag
is
not
None
:
bind_all
(
args
,
b_flag
,
force_flag
)
if
status_flag
:
if
b_flag
is
not
None
:
clear_data
()
# refresh if we have changed anything
get_device_details
(
network_devices
)
get_device_details
(
baseband_devices
)
get_device_details
(
crypto_devices
)
get_device_details
(
eventdev_devices
)
get_device_details
(
mempool_devices
)
get_device_details
(
compress_devices
)
get_device_details
(
misc_devices
)
show_status
()
def
main
():
'''program main function'''
# check if lspci is installed, suppress any output
with
open
(
os
.
devnull
,
'w'
)
as
devnull
:
ret
=
subprocess
.
call
([
'which'
,
'lspci'
],
stdout
=
devnull
,
stderr
=
devnull
)
if
ret
!=
0
:
sys
.
exit
(
"'lspci' not found - please install 'pciutils'"
)
parse_args
()
check_modules
()
clear_data
()
get_device_details
(
network_devices
)
get_device_details
(
baseband_devices
)
get_device_details
(
crypto_devices
)
get_device_details
(
eventdev_devices
)
get_device_details
(
mempool_devices
)
get_device_details
(
compress_devices
)
get_device_details
(
misc_devices
)
do_arg_actions
()
if
__name__
==
"__main__"
:
main
()
scripts/run_upf.sh
View file @
444bd85d
...
...
@@ -32,6 +32,9 @@ DPDK_ENTRY=""
TUNNELPATH
=
"/opt/5gc/upf/n4-beta"
DPDK_ENTRY_PCI
=
""
DPDK_EXPORT_PCI
=
""
DRIVE
=
""
function
init_configure
(){
yaml
=
"
$1
"
# vpp
...
...
@@ -46,7 +49,7 @@ function init_configure(){
UEIP
=
$(
$current
/yq r
$yaml
vpp.ip_link.ueip
)
PREFIX
=
$(
$current
/yq r
$yaml
vpp.ip_link.ueIPPrefix
)
INTER
=
$(
$current
/yq r
$yaml
vpp.ip_link.vppHost
)
VPPEXPORT
=
$(
$current
/yq r
$yaml
vpp.
ip_link.vppHostIP
)
VPPEXPORT
=
$(
$current
/yq r
$yaml
vpp.
system.gtpu_export_ip
)
MAC
=
$(
ifconfig
$INTER
|grep ether|awk
'{print $2}'
)
# nat
UE_IP
=
$(
$current
/yq r
$yaml
vpp.ip_link.ueip
)
...
...
@@ -57,6 +60,9 @@ function init_configure(){
DPDK_EXPORT
=
$(
$current
/yq r
$yaml
vpp.ip_link.gtpu_export
)
DPDK_ENTRY
=
$(
$current
/yq r
$yaml
vpp.ip_link.gtpu_entry
)
DPDK_ENTRY_PCI
=
$(
$current
/yq r
$yaml
vpp.startup.pci_addr_id_entry
)
DPDK_EXPORT_PCI
=
$(
$current
/yq r
$yaml
vpp.startup.pci_addr_id_export
)
DRIVE
=
$(
$current
/yq r
$yaml
vpp.startup.drive
)
}
function
start_vpp
()
{
...
...
@@ -199,6 +205,23 @@ function install_depence(){
cp
$base
/plugin/replace/replace
$current
>
/dev/null 2>&1
}
function
unbind
(){
python3
$current
/dpdk-devbind.py
-u
0000:
$DPDK_EXPORT_PCI
;
python3
$current
/dpdk-devbind.py
-u
0000:
$DPDK_EXPORT_PCI
;
python3
$current
/dpdk-devbind.py
-b
$DRIVE
$DPDK_EXPORT_PCI
sleep
1
python3
$current
/dpdk-devbind.py
-b
$DRIVE
$DPDK_EXPORT_PCI
sleep
1
ifconfig
$DPDK_EXPORT
down
;
sleep
1
ifconfig
$DPDK_ENTRY
down
;
sleep
1
}
function
main
()
{
install_depence
...
...
@@ -221,6 +244,7 @@ function main() {
close_vpp
close_n4
close_arp
# unbind
shift
;;
esac
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment