Merge branch 'abdosi/master_201911_label_to_201911' into 201911.

Cherry pick changes from master into 201911
This commit is contained in:
Abhishek 2020-01-06 17:30:03 -08:00
commit 6045e34650
101 changed files with 4679 additions and 2161 deletions

3
.gitignore vendored
View File

@ -60,6 +60,9 @@ src/lldpd/*
!src/lldpd/patch/
src/lm-sensors/*
!src/lm-sensors/Makefile
src/monit/*
!src/monit/Makefile
!src/monit/patch/
src/mpdecimal/*
!src/mpdecimal/Makefile
src/python-click/*

View File

@ -240,7 +240,6 @@ sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y in
openssh-server \
python \
python-setuptools \
monit \
python-apt \
traceroute \
iputils-ping \
@ -348,10 +347,6 @@ EOF
sudo sed -i 's/^ListenAddress ::/#ListenAddress ::/' $FILESYSTEM_ROOT/etc/ssh/sshd_config
sudo sed -i 's/^#ListenAddress 0.0.0.0/ListenAddress 0.0.0.0/' $FILESYSTEM_ROOT/etc/ssh/sshd_config
## Config monit
sudo cp files/image_config/monit/monitrc $FILESYSTEM_ROOT/etc/monit/
sudo chmod 600 $FILESYSTEM_ROOT/etc/monit/monitrc
## Config sysctl
sudo mkdir -p $FILESYSTEM_ROOT/var/core
sudo augtool --autosave "

View File

@ -1 +1 @@
SAI_INIT_CONFIG_FILE=/etc/bcm/td3-as7326-48x25G+8x100G.config.bcm
SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-as7326-48x25G+8x100G.config.bcm

View File

@ -17,6 +17,7 @@ l2xmsg_mode=1
bcm_num_cos=8
bcm_stat_interval=2000000
cdma_timeout_usec=3000000
ifp_inports_support_enable=1
ipv6_lpm_128b_enable=0x1
l3_max_ecmp_mode=1
l3_alpm_enable=2
@ -24,11 +25,13 @@ lpm_scaling_enable=0
max_vp_lags=0
miim_intr_enable=0
module_64ports=1
port_flex_enable=1
schan_intr_enable=0
stable_size=0x5500000
tdma_timeout_usec=3000000
skip_L2_USER_ENTRY=0
bcm_tunnel_term_compatible_mode=1
l3_alpm_ipv6_128b_bkt_rsvd=1
dport_map_port_1=6
dport_map_port_2=2

Binary file not shown.

View File

@ -0,0 +1,6 @@
#led auto off
#led stop
m0 load 0 0x0 /usr/share/sonic/platform/linkscan_led_fw.bin
m0 load 0 0x3800 /usr/share/sonic/platform/custom_led.bin
led auto on
led start

View File

@ -1,12 +1,37 @@
#!/bin/bash
declare -r SYSLOG_LOGGER="/usr/bin/logger"
declare -r SYSLOG_IDENTIFIER="platform_wait"
declare -r SYSLOG_ERROR="error"
declare -r SYSLOG_NOTICE="notice"
declare -r SYSLOG_INFO="info"
declare -r HW_MGMT_CONFIG="/var/run/hw-management/config"
declare -r MODULE_COUNTER="${HW_MGMT_CONFIG}/module_counter"
declare -r SFP_COUNTER="${HW_MGMT_CONFIG}/sfp_counter"
declare -r EXIT_SUCCESS="0"
declare -r EXIT_TIMEOUT="1"
declare -r QSFP_PATH="/var/run/hw-management/qsfp"
function log_error() {
eval "${SYSLOG_LOGGER} -t ${SYSLOG_IDENTIFIER} -p ${SYSLOG_ERROR} $@"
}
function WaitForQsfpReady() {
local -r _QSFP_PATH="${1}"
function log_notice() {
eval "${SYSLOG_LOGGER} -t ${SYSLOG_IDENTIFIER} -p ${SYSLOG_NOTICE} $@"
}
function log_info() {
eval "${SYSLOG_LOGGER} -t ${SYSLOG_IDENTIFIER} -p ${SYSLOG_INFO} $@"
}
function wait_for_sfp() {
local -r _NUM_MATCH="^[0-9]+$"
local -r _NUM_ZERO="0"
local _MODULE_CNT="0"
local _SFP_CNT="0"
local -i _WDOG_CNT="1"
local -ir _WDOG_MAX="300"
@ -14,11 +39,14 @@ function WaitForQsfpReady() {
local -r _TIMEOUT="1s"
while [[ "${_WDOG_CNT}" -le "${_WDOG_MAX}" ]]; do
for _QSFP in ${_QSFP_PATH}/qsfp*; do
if [[ -e "${_QSFP}" ]]; then
_MODULE_CNT="$(cat ${MODULE_COUNTER} 2>&1)"
_SFP_CNT="$(cat ${SFP_COUNTER} 2>&1)"
if [[ "${_MODULE_CNT}" =~ ${_NUM_MATCH} && "${_SFP_CNT}" =~ ${_NUM_MATCH} ]]; then
if [[ "${_SFP_CNT}" -gt "${_NUM_ZERO}" && "${_MODULE_CNT}" -eq "${_SFP_CNT}" ]]; then
return "${EXIT_SUCCESS}"
fi
done
fi
let "_WDOG_CNT++"
sleep "${_TIMEOUT}"
@ -27,14 +55,15 @@ function WaitForQsfpReady() {
return "${EXIT_TIMEOUT}"
}
echo "Wait for QSFP I2C interface is ready"
log_info "Wait for SFP interfaces to be ready"
WaitForQsfpReady "${QSFP_PATH}"
wait_for_sfp
EXIT_CODE="$?"
if [[ "${EXIT_CODE}" != "${EXIT_SUCCESS}" ]]; then
echo "QSFP I2C interface is not ready: timeout"
log_error "SFP interfaces are not ready: timeout"
exit "${EXIT_CODE}"
fi
echo "QSFP I2C interface is ready: mlxsw_minimal has finished initialization"
log_info "SFP interfaces are ready"
exit "${EXIT_SUCCESS}"

View File

@ -48,7 +48,13 @@ RUN apt-get update && \
vim-tiny \
# Install dependencies of supervisor
python-pkg-resources \
python-meld3
python-meld3 \
# dependencies of redis-tools
libatomic1 \
libjemalloc1 \
liblua5.1-0 \
lua-bitop \
lua-cjson
{% if CONFIGURED_ARCH == "armhf" %}
# ip and ifconfig utility missing in docker for armhf

View File

@ -16,12 +16,6 @@ if [ $(supervisorctl status | grep -c "^isc-dhcp-relay:") -gt 0 ]; then
# lifetime of the process.
/usr/bin/wait_for_intf.sh
# Allow a bit more time for interfaces to settle before starting the
# relay agent processes.
# FIXME: Remove/decrease this once we determine how to prevent future race
# conditions here.
sleep 180
# Start all DHCP relay agent(s)
supervisorctl start isc-dhcp-relay:*
fi

View File

@ -120,29 +120,23 @@ class Directory(object):
self.data = defaultdict(dict)
self.notify = defaultdict(lambda: defaultdict(list))
def path_exist(self, slot, path):
def path_traverse(self, slot, path):
if slot not in self.data:
return False
return False, None
elif path == '':
return True
return True, self.data[slot]
d = self.data[slot]
for p in path.split("/"):
if p not in d:
return False
return False, None
d = d[p]
return True
return True, d
def path_exist(self, slot, path):
return self.path_traverse(slot, path)[0]
def get_path(self, slot, path):
if slot not in self.data:
return None
elif path == '':
return self.data[slot]
d = self.data[slot]
for p in path.split("/"):
if p not in d:
return None
d = d[p]
return d
return self.path_traverse(slot, path)[1]
def put(self, slot, key, value):
self.data[slot][key] = value
@ -289,6 +283,8 @@ class BGPPeerMgr(Manager):
}
def set_handler(self, key, data):
key = self.normalize_key(key)
vrf, nbr = key.split('|', 1)
if key not in self.peers:
cmd = None
neigmeta = self.directory.get_slot("neigmeta")
@ -298,14 +294,14 @@ class BGPPeerMgr(Manager):
cmd = self.templates["add"].render(
DEVICE_METADATA=self.directory.get_slot("meta"),
DEVICE_NEIGHBOR_METADATA=neigmeta,
neighbor_addr=key,
neighbor_addr=nbr,
bgp_session=data
)
except:
syslog.syslog(syslog.LOG_ERR, 'Peer {}. Error in rendering the template for "SET" command {}'.format(key, data))
return True
if cmd is not None:
rc = self.apply_op(cmd)
rc = self.apply_op(cmd, vrf)
if rc:
self.peers.add(key)
syslog.syslog(syslog.LOG_INFO, 'Peer {} added with attributes {}'.format(key, data))
@ -316,13 +312,13 @@ class BGPPeerMgr(Manager):
# commands for the peers only
if "admin_status" in data:
if data['admin_status'] == 'up':
rc = self.apply_op(self.templates["no shutdown"].render(neighbor_addr=key))
rc = self.apply_op(self.templates["no shutdown"].render(neighbor_addr=nbr), vrf)
if rc:
syslog.syslog(syslog.LOG_INFO, 'Peer {} admin state is set to "up"'.format(key))
else:
syslog.syslog(syslog.LOG_ERR, "Peer {} admin state wasn't set to 'up'.".format(key))
elif data['admin_status'] == 'down':
rc = self.apply_op(self.templates["shutdown"].render(neighbor_addr=key))
rc = self.apply_op(self.templates["shutdown"].render(neighbor_addr=nbr), vrf)
if rc:
syslog.syslog(syslog.LOG_INFO, 'Peer {} admin state is set to "down"'.format(key))
else:
@ -334,23 +330,28 @@ class BGPPeerMgr(Manager):
return True
def del_handler(self, key):
key = self.normalize_key(key)
vrf, nbr = key.split('|', 1)
if key not in self.peers:
syslog.syslog(syslog.LOG_WARNING, 'Peer {} has not been found'.format(key))
return
cmd = self.templates["delete"].render(neighbor_addr=key)
rc = self.apply_op(cmd)
cmd = self.templates["delete"].render(neighbor_addr=nbr)
rc = self.apply_op(cmd, vrf)
if rc:
syslog.syslog(syslog.LOG_INFO, 'Peer {} has been removed'.format(key))
self.peers.remove(key)
else:
syslog.syslog(syslog.LOG_ERR, "Peer {} hasn't been removed".format(key))
def apply_op(self, cmd):
def apply_op(self, cmd, vrf):
bgp_asn = self.directory.get_slot("meta")["localhost"]["bgp_asn"]
fd, tmp_filename = tempfile.mkstemp(dir='/tmp')
os.close(fd)
with open(tmp_filename, 'w') as fp:
fp.write('router bgp %s\n' % bgp_asn)
if vrf == 'default':
fp.write('router bgp %s\n' % bgp_asn)
else:
fp.write('router bgp %s vrf %s\n' % (bgp_asn, vrf))
fp.write("%s\n" % cmd)
command = ["vtysh", "-f", tmp_filename]
@ -358,14 +359,31 @@ class BGPPeerMgr(Manager):
os.remove(tmp_filename)
return rc == 0
@staticmethod
def normalize_key(key):
if '|' not in key:
return 'default|' + key
else:
return key
@staticmethod
def load_peers():
peers = set()
command = ["vtysh", "-c", "show bgp neighbors json"]
vrfs = []
command = ["vtysh", "-c", "show bgp vrfs json"]
rc, out, err = run_command(command)
if rc == 0:
js_bgp = json.loads(out)
peers = set(js_bgp.keys())
js_vrf = json.loads(out)
vrfs = js_vrf['vrfs'].keys()
peers = set()
for vrf in vrfs:
command = ["vtysh", "-c", 'show bgp vrf {} neighbors json'.format(vrf)]
rc, out, err = run_command(command)
if rc == 0:
js_bgp = json.loads(out)
for nbr in js_bgp.keys():
peers.add((vrf, nbr))
return peers

View File

@ -18,13 +18,6 @@ RUN apt-get update && \
iproute2 \
ndisc6 \
tcpdump \
# Install redis-tools dependencies
# TODO: implicitly install dependencies
libatomic1 \
libjemalloc1 \
liblua5.1-0 \
lua-bitop \
lua-cjson \
libelf1 \
libmnl0 \
bridge-utils

View File

@ -11,14 +11,7 @@ RUN apt-get update && \
apt-get install -f -y \
libdbus-1-3 \
libdaemon0 \
libjansson4 \
# Install redis-tools dependencies
# TODO: implicitly install dependencies
libatomic1 \
libjemalloc1 \
liblua5.1-0 \
lua-bitop \
lua-cjson
libjansson4
{% if docker_sonic_telemetry_debs.strip() -%}
# Copy locally-built Debian package dependencies

View File

@ -12,14 +12,7 @@ RUN apt-get update && \
libdbus-1-3 \
libdaemon0 \
libjansson4 \
libpython2.7 \
# Install redis-tools dependencies
# TODO: implicitly install dependencies
libatomic1 \
libjemalloc1 \
liblua5.1-0 \
lua-bitop \
lua-cjson
libpython2.7
{% if docker_teamd_debs.strip() -%}
# Copy locally-built Debian package dependencies

View File

@ -149,6 +149,11 @@ function postStartAction()
sonic-cfggen -j /etc/sonic/config_db.json --write-to-db
fi
if [[ "$BOOT_TYPE" == "fast" ]]; then
# set the key to expire in 3 minutes
redis-cli -n 6 SET "FAST_REBOOT|system" "1" "EX" "180"
fi
redis-cli -n 4 SET "CONFIG_DB_INITIALIZED" "1"
fi

View File

@ -1,6 +1,6 @@
[Unit]
Description=sFlow container
Requires=swss.service
Requisite=swss.service
After=swss.service syncd.service
Before=ntp-config.service
StartLimitIntervalSec=1200

View File

@ -4,6 +4,7 @@ Requires=updategraph.service
Requisite=swss.service
After=updategraph.service swss.service syncd.service
Before=ntp-config.service
Conflicts=snmp.timer
StartLimitIntervalSec=1200
StartLimitBurst=3
@ -14,5 +15,3 @@ ExecStop=/usr/bin/{{docker_container_name}}.sh stop
Restart=always
RestartSec=30
[Install]
WantedBy=multi-user.target swss.service

View File

@ -1,9 +1,11 @@
[Unit]
Description=Delays snmp container until SONiC has started
Conflicts=snmp.service
[Timer]
OnUnitActiveSec=0 sec
OnBootSec=3min 30 sec
Unit=snmp.service
[Install]
WantedBy=timers.target
WantedBy=timers.target swss.service

View File

@ -36,6 +36,8 @@ FILESYSTEM_ROOT_USR="$FILESYSTEM_ROOT/usr"
FILESYSTEM_ROOT_USR_SHARE="$FILESYSTEM_ROOT_USR/share"
FILESYSTEM_ROOT_USR_SHARE_SONIC="$FILESYSTEM_ROOT_USR_SHARE/sonic"
FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES="$FILESYSTEM_ROOT_USR_SHARE_SONIC/templates"
FILESYSTEM_ROOT_ETC="$FILESYSTEM_ROOT/etc"
FILESYSTEM_ROOT_ETC_SONIC="$FILESYSTEM_ROOT_ETC/sonic"
GENERATED_SERVICE_FILE="$FILESYSTEM_ROOT/etc/sonic/generated_services.conf"
@ -164,6 +166,14 @@ sudo sed -i -e '/^passwd/s/ tacplus//' $FILESYSTEM_ROOT/etc/nsswitch.conf
sudo DEBIAN_FRONTEND=noninteractive dpkg --root=$FILESYSTEM_ROOT -i $debs_path/kdump-tools_*.deb || \
sudo LANG=C DEBIAN_FRONTEND=noninteractive DEBCONF_NONINTERACTIVE_SEEN=truechroot $FILESYSTEM_ROOT apt-get -q --no-install-suggests --no-install-recommends --force-no install
# Install custom-built monit package and SONiC configuration files
sudo dpkg --root=$FILESYSTEM_ROOT -i $debs_path/monit_*.deb || \
sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install -f
sudo cp $IMAGE_CONFIGS/monit/monitrc $FILESYSTEM_ROOT/etc/monit/
sudo chmod 600 $FILESYSTEM_ROOT/etc/monit/monitrc
sudo cp $IMAGE_CONFIGS/monit/conf.d/* $FILESYSTEM_ROOT/etc/monit/conf.d/
sudo chmod 600 $FILESYSTEM_ROOT/etc/monit/conf.d/*
# Copy crontabs
sudo cp -f $IMAGE_CONFIGS/cron.d/* $FILESYSTEM_ROOT/etc/cron.d/
@ -207,6 +217,16 @@ echo "hostcfgd.service" | sudo tee -a $GENERATED_SERVICE_FILE
sudo cp $IMAGE_CONFIGS/hostcfgd/hostcfgd $FILESYSTEM_ROOT/usr/bin/
sudo cp $IMAGE_CONFIGS/hostcfgd/*.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/
# copy core file uploader files
sudo cp $IMAGE_CONFIGS/corefile_uploader/core_uploader.service $FILESYSTEM_ROOT/etc/systemd/system/
sudo LANG=C chroot $FILESYSTEM_ROOT systemctl disable core_uploader.service
sudo cp $IMAGE_CONFIGS/corefile_uploader/core_uploader.py $FILESYSTEM_ROOT/usr/bin/
sudo cp $IMAGE_CONFIGS/corefile_uploader/core_analyzer.rc.json $FILESYSTEM_ROOT_ETC_SONIC/
sudo chmod og-rw $FILESYSTEM_ROOT_ETC_SONIC/core_analyzer.rc.json
sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install azure-storage
sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install watchdog
sudo https_proxy=$https_proxy LANG=C chroot $FILESYSTEM_ROOT pip install futures
# Copy the buffer configuration template
sudo cp $BUILD_TEMPLATES/buffers_config.j2 $FILESYSTEM_ROOT_USR_SHARE_SONIC_TEMPLATES/
@ -329,7 +349,7 @@ EOF
## Bind docker path
if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then
sudo mkdir -p $FILESYSTEM_ROOT/dockerfs
sudo mount --bind dockerfs $FILESYSTEM_ROOT/dockerfs
sudo mount --bind dockerfs $FILESYSTEM_ROOT/dockerfs
fi
{% if installer_images.strip() -%}
@ -346,7 +366,7 @@ sudo LANG=C chroot $FILESYSTEM_ROOT docker $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS ta
{% endif %}
{% endfor %}
if [[ $CONFIGURED_ARCH == armhf || $CONFIGURED_ARCH == arm64 ]]; then
sudo umount $FILESYSTEM_ROOT/dockerfs
sudo umount $FILESYSTEM_ROOT/dockerfs
sudo rm -fr $FILESYSTEM_ROOT/dockerfs
sudo kill -9 `sudo $SONIC_NATIVE_DOCKERD_FOR_DOCKERFS_PID` || true
else
@ -374,6 +394,10 @@ sudo LANG=C cp $SCRIPTS_DIR/syncd.sh $FILESYSTEM_ROOT/usr/local/bin/syncd.sh
# It implements delayed start of services
sudo cp $BUILD_TEMPLATES/snmp.timer $FILESYSTEM_ROOT/etc/systemd/system/
sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable snmp.timer
{% if enable_system_telemetry == 'y' %}
sudo cp $BUILD_TEMPLATES/telemetry.timer $FILESYSTEM_ROOT/etc/systemd/system/
sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable telemetry.timer
{% endif %}
sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get purge -y python-dev
sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get clean -y

View File

@ -14,5 +14,3 @@ ExecStop=/usr/bin/{{docker_container_name}}.sh stop
Restart=always
RestartSec=30
[Install]
WantedBy=multi-user.target

View File

@ -0,0 +1,9 @@
[Unit]
Description=Delays telemetry container until SONiC has started
[Timer]
OnBootSec=3min 30 sec
Unit=telemetry.service
[Install]
WantedBy=timers.target

View File

@ -194,13 +194,14 @@ class ControlPlaneAclManager(object):
continue
# If we haven't determined the IP version for this ACL table yet,
# try to do it now. We determine heuristically based on whether the
# src IP is an IPv4 or IPv6 address.
if not table_ip_version and "SRC_IP" in rule_props and rule_props["SRC_IP"]:
ip_addr = ipaddress.IPAddress(rule_props["SRC_IP"].split("/")[0])
if isinstance(ip_addr, ipaddress.IPv6Address):
# try to do it now. We attempt to determine heuristically based on
# whether the src or dst IP of this rule is an IPv4 or IPv6 address.
if not table_ip_version:
if (("SRC_IPV6" in rule_props and rule_props["SRC_IPV6"]) or
("DST_IPV6" in rule_props and rule_props["DST_IPV6"])):
table_ip_version = 6
elif isinstance(ip_addr, ipaddress.IPv4Address):
elif (("SRC_IP" in rule_props and rule_props["SRC_IP"]) or
("DST_IP" in rule_props and rule_props["DST_IP"])):
table_ip_version = 4
# If we were unable to determine whether this ACL table contains

View File

@ -0,0 +1,17 @@
{
"local_work": {
"core_upload": "/tmp/core_upload/"
},
"azure_sonic_core_storage": {
"account_name": "corefilecollection",
"account_key": "",
"share_name": "corefiles-root"
},
"metadata_files_in_archive": {
"version": "/etc/sonic/sonic_version.yml",
"core_info": "core_info.json"
},
"env": {
"https_proxy": ""
}
}

View File

@ -0,0 +1,285 @@
#!/usr/bin/env python
import os
import time
import tarfile
import socket
import yaml
import json
import syslog
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
from azure.storage.file import FileService
global CORE_FILE_PATH, RC_FILE
global hostname, sonicversion, asicname, acctname, acctkey, sharename, cwd
global INIT_CWD
global log_level
global this_file
this_file = os.path.basename(__file__)
global cfg
cfg = ""
CORE_FILE_PATH = "/var/core/"
RC_FILE = "/etc/sonic/core_analyzer.rc.json"
INIT_CWD = "/tmp"
hostname = ""
sonicversion = ""
asicname = ""
acctname = ""
acctkey = ""
sharename = ""
cwd = []
HOURS_4 = (4 * 60 * 60)
PAUSE_ON_FAIL = (60 * 60)
WAIT_FILE_WRITE1 = (10 * 60)
WAIT_FILE_WRITE2= (5 * 60)
POLL_SLEEP = (60 * 60)
MAX_RETRIES = 5
UPLOAD_PREFIX = "UPLOADED_"
log_level = syslog.LOG_DEBUG
def log_msg(lvl, fname, m):
if (lvl <= log_level):
syslog.syslog(lvl, "{}: {}".format(fname, m))
if log_level == syslog.LOG_DEBUG:
print("{}: {}".format(fname, m))
def log_err(m):
log_msg(syslog.LOG_ERR, this_file, m)
def log_info(m):
log_msg(syslog.LOG_INFO, this_file, m)
def log_warn(m):
log_msg(syslog.LOG_WARNING, this_file, m)
def log_debug(m):
log_msg(syslog.LOG_DEBUG, this_file, m)
def make_new_dir(p):
os.system("rm -rf " + p)
os.system("mkdir -p " + p)
def parse_a_json(data, prefix, val):
for i in data:
if type(data[i]) == dict:
parse_a_json(data[i], prefix + (i,), val)
else:
val[prefix + (i,)] = data[i]
class config:
parsed_data = {}
cfg_data = {}
def __init__(self):
while not os.path.exists(RC_FILE):
# Wait here until service restart
log_err("Unable to retrieve Azure storage credentials")
time.sleep (HOURS_4)
with open(RC_FILE, 'r') as f:
self.parsed_data = json.load(f)
parse_a_json(self.parsed_data, (), self.cfg_data)
def get_data(self, k):
return self.cfg_data[k] if self.cfg_data.has_key(k) else ""
def get_dict(self):
return self.parsed_data
def get_core_info(self, corepath, devicename):
info = {}
info["corefname"] = os.path.basename(corepath)
info["tstamp"] = str(os.stat(corepath).st_ctime)
info["devicename"] = devicename
lpath = self.get_data(("metadata_files_in_archive", "core_info"))
f = open(lpath, "w+")
f.write(json.dumps(info, indent=4))
f.close()
return lpath
class Watcher:
def __init__(self):
self.observer = Observer()
def run(self):
event_handler = Handler()
self.observer.schedule(event_handler, CORE_FILE_PATH)
self.observer.start()
try:
while True:
time.sleep(POLL_SLEEP)
except:
self.observer.stop()
log_err("Error in watcher")
self.observer.join()
def set_env(lst):
for k in lst:
if lst[k]:
os.environ[k] = lst[k]
log_debug("set env {} = {}".format(k, lst[k]))
class Handler(FileSystemEventHandler):
@staticmethod
def init():
global hostname, sonicversion, asicname, acctname, acctkey, sharename
global cwd, cfg
cfg = config()
set_env(cfg.get_dict()["env"])
hostname = socket.gethostname()
if not hostname:
raise Exception("Failed to read hostname")
acctname = cfg.get_data(("azure_sonic_core_storage", "account_name"))
acctkey = cfg.get_data(("azure_sonic_core_storage", "account_key"))
sharename = cfg.get_data(("azure_sonic_core_storage", "share_name"))
if not acctname or not acctkey or not sharename:
while True:
# Wait here until service restart
log_err("Unable to retrieve Azure storage credentials")
time.sleep (HOURS_4)
with open("/etc/sonic/sonic_version.yml", 'r') as stream:
l = yaml.safe_load(stream)
sonicversion = l['build_version']
asicname = l['asic_type']
if not sonicversion:
raise Exception("Failed to read build_version from /etc/sonic/sonic_version.yml")
if not asicname:
raise Exception("Failed to read asic_type from /etc/sonic/sonic_version.yml")
cwd = cfg.get_data(("local_work", "core_upload")).split("/")
if not len(cwd) > 2:
raise Exception("Invalid path for core_upload. Expect a min of two elements in path")
os.chdir(INIT_CWD)
@staticmethod
def on_any_event(event):
if event.is_directory:
return None
elif event.event_type == 'created':
# Take any action here when a file is first created.
log_debug("Received create event - " + event.src_path)
Handler.wait_for_file_write_complete(event.src_path)
Handler.handle_file(event.src_path)
@staticmethod
def wait_for_file_write_complete(path):
mtime = 0
# Sleep for ample time enough for file dump to complete.
time.sleep(WAIT_FILE_WRITE1)
# Give another chance & poll until mtime stabilizes
while mtime != os.stat(path).st_mtime:
mtime = os.stat(path).st_mtime
time.sleep(10)
# A safety pause for double confirmation
time.sleep(WAIT_FILE_WRITE2)
if mtime != os.stat(path).st_mtime:
raise Exception("Dump file creation is too slow: " + path)
# Give up as something is terribly wrong with this file.
log_debug("File write complete - " + path)
@staticmethod
def handle_file(path):
lpath = "/".join(cwd)
make_new_dir(lpath)
os.chdir(lpath)
# Create a new archive with core & more.
metafiles = cfg.get_dict()["metadata_files_in_archive"]
fname = os.path.basename(path)
tarf_name = fname + ".tar.gz"
cfg.get_core_info(path, hostname)
tar = tarfile.open(tarf_name, "w:gz")
for e in metafiles:
tar.add(metafiles[e])
tar.add(path)
tar.close()
log_debug("Tar file for upload created: " + tarf_name)
Handler.upload_file(tarf_name, tarf_name, path)
log_debug("File uploaded - " + path)
os.chdir(INIT_CWD)
@staticmethod
def upload_file(fname, fpath, coref):
daemonname = fname.split(".")[0]
i = 0
fail_msg = ""
while True:
try:
svc = FileService(account_name=acctname, account_key=acctkey)
l = [sonicversion, asicname, daemonname, hostname]
e = []
while len(e) != len(l):
e.append(l[len(e)])
svc.create_directory(sharename, "/".join(e))
log_debug("Remote dir created: " + "/".join(e))
svc.create_file_from_path(sharename, "/".join(l), fname, fpath)
log_debug("Remote file created: name{} path{}".format(fname, fpath))
newcoref = os.path.dirname(coref) + "/" + UPLOAD_PREFIX + os.path.basename(coref)
os.rename(coref, newcoref)
break
except Exception as ex:
log_err("core uploader failed: Failed during upload (" + coref + ") err: ("+ str(ex) +") retry:" + str(i))
if not os.path.exists(fpath):
break
i += 1
time.sleep(PAUSE_ON_FAIL)
@staticmethod
def scan():
for e in os.listdir(CORE_FILE_PATH):
fl = CORE_FILE_PATH + e
if os.path.isfile(fl) and not e.startswith(UPLOAD_PREFIX):
Handler.handle_file(fl)
if __name__ == '__main__':
try:
Handler.init()
w = Watcher()
Handler.scan()
w.run()
except Exception as e:
log_err("core uploader failed: " + str(e) + " Exiting ...")

View File

@ -0,0 +1,13 @@
[Unit]
Description=Host core file uploader daemon
Requires=syslog.service
After=syslog.service
[Service]
Type=simple
ExecStart=/usr/bin/core_uploader.py
StandardOutput=null
Restart=on-failure
[Install]
WantedBy=multi-user.target

View File

@ -176,6 +176,11 @@ class AaaCfg(object):
if modify_conf:
self.modify_conf_file()
def modify_single_file(self, filename, operations=None):
if operations:
cmd = "sed -e {0} {1} > {1}.new; mv -f {1} {1}.old; mv -f {1}.new {1}".format(' -e '.join(operations), filename)
os.system(cmd)
def modify_conf_file(self):
auth = self.auth_default.copy()
auth.update(self.auth)
@ -201,19 +206,19 @@ class AaaCfg(object):
# Modify common-auth include file in /etc/pam.d/login and sshd
if os.path.isfile(PAM_AUTH_CONF):
os.system("sed -i -e '/^@include/s/common-auth$/common-auth-sonic/' /etc/pam.d/sshd")
os.system("sed -i -e '/^@include/s/common-auth$/common-auth-sonic/' /etc/pam.d/login")
self.modify_single_file('/etc/pam.d/sshd', [ "'/^@include/s/common-auth$/common-auth-sonic/'" ])
self.modify_single_file('/etc/pam.d/login', [ "'/^@include/s/common-auth$/common-auth-sonic/'" ])
else:
os.system("sed -i -e '/^@include/s/common-auth-sonic$/common-auth/' /etc/pam.d/sshd")
os.system("sed -i -e '/^@include/s/common-auth-sonic$/common-auth/' /etc/pam.d/login")
self.modify_single_file('/etc/pam.d/sshd', [ "'/^@include/s/common-auth-sonic$/common-auth/'" ])
self.modify_single_file('/etc/pam.d/login', [ "'/^@include/s/common-auth-sonic$/common-auth/'" ])
# Add tacplus in nsswitch.conf if TACACS+ enable
if 'tacacs+' in auth['login']:
if os.path.isfile(NSS_CONF):
os.system("sed -i -e '/tacplus/b' -e '/^passwd/s/compat/tacplus &/' /etc/nsswitch.conf")
self.modify_single_file(NSS_CONF, [ "'/tacplus/b'", "'/^passwd/s/compat/tacplus &/'"])
else:
if os.path.isfile(NSS_CONF):
os.system("sed -i -e '/^passwd/s/tacplus //' /etc/nsswitch.conf")
self.modify_single_file(NSS_CONF, [ "'/^passwd/s/tacplus //'" ])
# Set tacacs+ server in nss-tacplus conf
template_file = os.path.abspath(NSS_TACPLUS_CONF_TEMPLATE)

View File

@ -0,0 +1,22 @@
###############################################################################
## Monit configuration for SONiC host OS
##
## This includes system-level monitoring as well as processes which
## run in the host OS (i.e., not inside a Docker container)
###############################################################################
check filesystem root-overlay with path /
if space usage > 90% for 5 times within 10 cycles then alert
check filesystem var-log with path /var/log
if space usage > 90% for 5 times within 10 cycles then alert
check system $HOST
if memory usage > 90% for 5 times within 10 cycles then alert
if cpu usage (user) > 90% for 5 times within 10 cycles then alert
if cpu usage (system) > 90% for 5 times within 10 cycles then alert
check process rsyslog with pidfile /var/run/rsyslogd.pid
start program = "/bin/systemctl start rsyslog.service"
stop program = "/bin/systemctl stop rsyslog.service"
if totalmem > 800 MB for 5 times within 10 cycles then restart

View File

@ -24,8 +24,7 @@
## Set syslog logging. If you want to log to a standalone log file instead,
## specify the full path to the log file
#
# set logfile /var/log/monit.log
set logfile syslog
set logfile syslog
#
#
## Set the location of the Monit lock file which stores the process id of the
@ -153,8 +152,8 @@ set logfile syslog
## commands to a running Monit daemon. See the Monit Wiki if you want to
## enable SSL for the HTTP interface.
#
set httpd unixsocket /var/run/monit.sock and
allow localhost # allow localhost to connect to the server and
set httpd unixsocket /var/run/monit.sock and
allow localhost # allow localhost to connect to the server
#
###############################################################################
## Services
@ -294,15 +293,3 @@ set httpd unixsocket /var/run/monit.sock and
include /etc/monit/conf.d/*
include /etc/monit/conf-enabled/*
#
check filesystem root-overlay with path /
if space usage > 90% for 5 times within 10 cycles then alert
check filesystem var-log with path /var/log
if space usage > 90% for 5 times within 10 cycles then alert
check system $HOST
if memory usage > 90% for 5 times within 10 cycles then alert
if cpu usage (user) > 90% for 5 times within 10 cycles then alert
if cpu usage (system) > 90% for 5 times within 10 cycles then alert
check process rsyslog with pidfile /var/run/rsyslogd.pid
start program = "/bin/systemctl start rsyslog.service"
stop program = "/bin/systemctl stop rsyslog.service"
if totalmem > 800 MB for 5 times within 10 cycles then restart

View File

@ -11,6 +11,7 @@ try:
import pwd
import sys
import syslog
import re
except ImportError as err:
raise ImportError("%s - required module not found" % str(err))
@ -22,6 +23,16 @@ REBOOT_CAUSE_DIR = "/host/reboot-cause/"
REBOOT_CAUSE_FILE = REBOOT_CAUSE_DIR + "reboot-cause.txt"
PREVIOUS_REBOOT_CAUSE_FILE = REBOOT_CAUSE_DIR + "previous-reboot-cause.txt"
FIRST_BOOT_PLATFORM_FILE = "/tmp/notify_firstboot_to_platform"
REBOOT_TYPE_KEXEC_FILE = "/proc/cmdline"
# The following SONIC_BOOT_TYPEs come from the warm/fast reboot script which is in sonic-utilities
# Because the system can be rebooted from some old versions, we have to take all possible BOOT options into consideration.
# On 201803, 201807 we have
# BOOT_OPTIONS="$(echo $KERNEL_OPTIONS | sed -e 's/\s*linux\s*/BOOT_IMAGE=/') fast-reboot"
# On 201811 and later we have
# BOOT_OPTIONS="$(echo $KERNEL_OPTIONS | sed -e 's/\s*linux\s*/BOOT_IMAGE=/') SONIC_BOOT_TYPE=${BOOT_TYPE_ARG}" where BOOT_TYPE_ARG can be warm, fastfast or fast
# To extract the commom part of them, we should have the following PATTERN
REBOOT_TYPE_KEXEC_PATTERN_WARM = ".*SONIC_BOOT_TYPE=(warm|fastfast).*"
REBOOT_TYPE_KEXEC_PATTERN_FAST = ".*SONIC_BOOT_TYPE=(fast|fast-reboot).*"
UNKNOWN_REBOOT_CAUSE = "Unknown"
@ -47,7 +58,32 @@ def log_error(msg):
# ============================= Functions =============================
def parse_warmfast_reboot_from_proc_cmdline():
if os.path.isfile(REBOOT_TYPE_KEXEC_FILE):
with open(REBOOT_TYPE_KEXEC_FILE, "r") as cause_file:
cause_file_kexec = cause_file.readline()
m = re.match(REBOOT_TYPE_KEXEC_PATTERN_WARM, cause_file_kexec)
if m and m.group(1):
return 'warm-reboot'
m = re.match(REBOOT_TYPE_KEXEC_PATTERN_FAST, cause_file_kexec)
if m and m.group(1):
return 'fast-reboot'
return None
def find_software_reboot_cause():
software_reboot_cause = UNKNOWN_REBOOT_CAUSE
if os.path.isfile(REBOOT_CAUSE_FILE):
with open(REBOOT_CAUSE_FILE, "r") as cause_file:
software_reboot_cause = cause_file.readline().rstrip('\n')
if os.path.isfile(FIRST_BOOT_PLATFORM_FILE):
os.remove(FIRST_BOOT_PLATFORM_FILE)
return software_reboot_cause
def main():
log_info("Starting up...")
@ -73,51 +109,48 @@ def main():
try:
import sonic_platform
# Check if the previous reboot was caused by hardware
platform = sonic_platform.platform.Platform()
chassis = platform.get_chassis()
hardware_reboot_cause, optional_details = chassis.get_reboot_cause()
if hardware_reboot_cause == chassis.REBOOT_CAUSE_NON_HARDWARE:
# The reboot was not caused by hardware. If there is a REBOOT_CAUSE_FILE, it will
# contain any software-related reboot info. We will use it as the previous cause.
# 1. Check if the previous reboot was warm/fast reboot by testing whether there is "fast|fastfast|warm" in /proc/cmdline
# If yes, the content of /hosts/reboot-cause/reboot-cause.txt will be treated as the reboot cause
proc_cmdline_reboot_cause = parse_warmfast_reboot_from_proc_cmdline()
if proc_cmdline_reboot_cause:
log_info("/proc/cmdline indicates reboot type: {}".format(proc_cmdline_reboot_cause))
if os.path.isfile(REBOOT_CAUSE_FILE):
cause_file = open(REBOOT_CAUSE_FILE, "r")
previous_reboot_cause = cause_file.readline().rstrip('\n')
cause_file.close()
# If it is FirstTime Boot and previous_reboot_cause is unknown
# and hardware_reboot cause is non_hardware then
# Update the reboot cause as required
if os.path.isfile(FIRST_BOOT_PLATFORM_FILE):
if (previous_reboot_cause == UNKNOWN_REBOOT_CAUSE):
previous_reboot_cause = UNKNOWN_REBOOT_CAUSE
os.remove(FIRST_BOOT_PLATFORM_FILE)
elif hardware_reboot_cause == chassis.REBOOT_CAUSE_HARDWARE_OTHER:
previous_reboot_cause = "{} ({})".format(hardware_reboot_cause, optional_details)
with open(REBOOT_CAUSE_FILE, "r") as cause_file:
proc_cmdline_reboot_cause = cause_file.readline().rstrip('\n')
else:
# /proc/cmdline says it's a warm/fast reboot but /host/reboot-cause.txt doesn't exist.
# This could happen when upgrading from a version doesn't support reboot cause.
log_info("Reboot cause file {} doesn't exist".format(REBOOT_CAUSE_DIR))
if proc_cmdline_reboot_cause is not None:
previous_reboot_cause = proc_cmdline_reboot_cause
else:
previous_reboot_cause = hardware_reboot_cause
# 2. Check if the previous reboot was caused by hardware
# If yes, the hardware reboot cause will be treated as the reboot cause
platform = sonic_platform.platform.Platform()
chassis = platform.get_chassis()
hardware_reboot_cause, optional_details = chassis.get_reboot_cause()
if hardware_reboot_cause == chassis.REBOOT_CAUSE_NON_HARDWARE:
# The reboot was not caused by hardware. If there is a REBOOT_CAUSE_FILE, it will
# contain any software-related reboot info. We will use it as the previous cause.
previous_reboot_cause = find_software_reboot_cause()
elif hardware_reboot_cause == chassis.REBOOT_CAUSE_HARDWARE_OTHER:
previous_reboot_cause = "{} ({})".format(hardware_reboot_cause, optional_details)
else:
previous_reboot_cause = hardware_reboot_cause
except ImportError as err:
log_warning("sonic_platform package not installed. Unable to detect hardware reboot causes.")
# If there is a REBOOT_CAUSE_FILE, it will contain any software-related
# reboot info. We will use it as the previous cause.
if os.path.isfile(REBOOT_CAUSE_FILE):
cause_file = open(REBOOT_CAUSE_FILE, "r")
previous_reboot_cause = cause_file.readline().rstrip('\n')
cause_file.close()
previous_reboot_cause = find_software_reboot_cause()
# If it is FirstTime Boot and previous_reboot_cause is unknown
# Update the reboot cause as required
if os.path.isfile(FIRST_BOOT_PLATFORM_FILE):
if (previous_reboot_cause == UNKNOWN_REBOOT_CAUSE):
previous_reboot_cause = UNKNOWN_REBOOT_CAUSE
os.remove(FIRST_BOOT_PLATFORM_FILE)
# Write the previous reboot cause to PREVIOUS_REBOOT_CAUSE_FILE
prev_cause_file = open(PREVIOUS_REBOOT_CAUSE_FILE, "w")
prev_cause_file.write(previous_reboot_cause)
prev_cause_file.close()
with open(PREVIOUS_REBOOT_CAUSE_FILE, "w") as prev_cause_file:
prev_cause_file.write(previous_reboot_cause)
# Also log the previous reboot cause to the syslog
log_info("Previous reboot cause: {}".format(previous_reboot_cause))
@ -127,9 +160,8 @@ def main():
os.remove(REBOOT_CAUSE_FILE)
# Write a new default reboot cause file for the next reboot
cause_file = open(REBOOT_CAUSE_FILE, "w")
cause_file.write(UNKNOWN_REBOOT_CAUSE)
cause_file.close()
with open(REBOOT_CAUSE_FILE, "w") as cause_file:
cause_file.write(UNKNOWN_REBOOT_CAUSE)
if __name__ == "__main__":

View File

@ -85,9 +85,7 @@ start_peer_and_dependent_services() {
if [[ x"$WARM_BOOT" != x"true" ]]; then
/bin/systemctl start ${PEER}
for dep in ${DEPENDENT}; do
# Here we call `systemctl restart` on each dependent service instead of `systemctl start` to
# ensure the services actually get stopped and started in case they were not previously stopped.
/bin/systemctl restart ${dep}
/bin/systemctl start ${dep}
done
fi
}
@ -163,6 +161,13 @@ stop() {
/usr/bin/${SERVICE}.sh stop
debug "Stopped ${SERVICE} service..."
# Flush FAST_REBOOT table when swss needs to stop. The only
# time when this would take effect is when fast-reboot
# encountered error, e.g. syncd crashed. And swss needs to
# be restarted.
debug "Clearing FAST_REBOOT flag..."
clean_up_tables 6 "'FAST_REBOOT*'"
# Unlock has to happen before reaching out to peer service
unlock_service_state_change

View File

@ -64,7 +64,12 @@ function getBootType()
TYPE='fastfast'
;;
*SONIC_BOOT_TYPE=fast*|*fast-reboot*)
TYPE=$(awk '{ if ($1 <= 180) print "fast"; else print "cold" }' /proc/uptime)
# check that the key exists
if [[ $(redis-cli -n 6 GET "FAST_REBOOT|system") == "1" ]]; then
TYPE='fast'
else
TYPE='cold'
fi
;;
*)
TYPE='cold'
@ -106,7 +111,6 @@ start() {
/bin/systemctl stop pmon
debug "pmon is active while syncd starting, stop it first"
fi
/usr/bin/hw-management.sh chipdown
fi
if [[ x"$BOOT_TYPE" == x"fast" ]]; then

View File

@ -1,3 +1,4 @@
{% from "dockers/dockerfile-macros.j2" import install_debian_packages %}
FROM docker-config-engine-stretch
ARG docker_container_name
@ -14,10 +15,8 @@ debs/{{ deb }}{{' '}}
{%- endfor -%}
debs/
RUN dpkg -i \
{% for deb in docker_syncd_brcm_debs.split(' ') -%}
debs/{{ deb }}{{' '}}
{%- endfor %}
# Install locally-built Debian packages and implicitly install their dependencies
{{ install_debian_packages(docker_syncd_brcm_debs.split(' ')) }}
## TODO: add kmod into Depends
RUN apt-get install -yf kmod

View File

@ -1,7 +1,7 @@
# Broadcom SAI modules
KVERSION = 4.9.0-9-2-amd64
BRCM_OPENNSL_KERNEL_VERSION = 3.4.1.11-1
BRCM_OPENNSL_KERNEL_VERSION = 3.7.3.3-1
BRCM_OPENNSL_KERNEL = opennsl-modules_$(BRCM_OPENNSL_KERNEL_VERSION)_amd64.deb
$(BRCM_OPENNSL_KERNEL)_SRC_PATH = $(PLATFORM_PATH)/saibcm-modules

View File

@ -1,9 +1,9 @@
BRCM_SAI = libsaibcm_3.5.3.1m-25_amd64.deb
$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.5/libsaibcm_3.5.3.1m-26_amd64.deb?sv=2015-04-05&sr=b&sig=zo83IKnlT7goymXwynW8%2Fx6rR2eIh0AiIS%2BSrSMUhRE%3D&se=2033-07-21T18%3A50%3A27Z&sp=r"
BRCM_SAI = libsaibcm_3.7.3.3_amd64.deb
$(BRCM_SAI)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm_3.7.3.3_amd64.deb?sv=2015-04-05&sr=b&sig=Y66VSRUEl4PDf5kHRo%2FS3DBBE9tONSyCzNJvi8IP9n8%3D&se=2033-08-25T01%3A22%3A08Z&sp=r"
BRCM_SAI_DEV = libsaibcm-dev_3.5.3.1m-25_amd64.deb
BRCM_SAI_DEV = libsaibcm-dev_3.7.3.3_amd64.deb
$(eval $(call add_derived_package,$(BRCM_SAI),$(BRCM_SAI_DEV)))
$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.5/libsaibcm-dev_3.5.3.1m-26_amd64.deb?sv=2015-04-05&sr=b&sig=tQmkCIy2mnb9rH7B9oXFUZDwijMGXWnVtta2CNTMbFM%3D&se=2033-07-21T18%3A50%3A47Z&sp=r"
$(BRCM_SAI_DEV)_URL = "https://sonicstorage.blob.core.windows.net/packages/bcmsai/3.7/libsaibcm-dev_3.7.3.3_amd64.deb?sv=2015-04-05&sr=b&sig=6%2BWzgFL845H9lKE0COsN53P4MO4UWfSo0z%2FmUMFbYVk%3D&se=2033-08-25T01%3A21%3A50Z&sp=r"
SONIC_ONLINE_DEBS += $(BRCM_SAI)
$(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI)
$(BRCM_SAI_DEV)_DEPENDS += $(BRCM_SAI)

View File

@ -1,3 +1,24 @@
opennsl (3.7.3.3-1) unstable; urgency=medium
* Port Broadcom SAI 3.7.3.3
* Cherry-pick change from master branch, 3.7.3.3-1
-- Judy Joseph <jujoseph@microsoft.com> Fri, 2 Dec 2019 15:32:47 +0000
opennsl (3.7.3.2-1) unstable; urgency=medium
* Port Broadcom SAI 3.7.3.2
* Cherry-pick change from master branch, 3.7.3.2-1
-- Judy Joseph <jujoseph@microsoft.com> Fri, 12 Nov 2019 15:22:47 +0000
opennsl (3.7.3.1-1) unstable; urgency=medium
* Port Broadcom SAI 3.7.3.1
* Cherry-pick change from master branch, 3.7.3.1-1
-- Judy Joseph <jujoseph@microsoft.com> Fri, 19 Sep 2019 13:11:47 +0000
opennsl (3.4.1.11-1) unstable; urgency=medium
* Port Broadcom SAI 3.4.1.11

View File

@ -32,14 +32,38 @@ function create_devices()
# level logs
function load_kernel_modules()
{
modprobe linux-kernel-bde dmasize=32M maxpayload=128 debug=4 dma_debug=1
. /host/machine.conf
if [ -n "$aboot_platform" ]; then
platform=$aboot_platform
elif [ -n "$onie_platform" ]; then
platform=$onie_platform
else
platform="unknown"
fi
# Set the default configuration for dmasize and usemsi parameters
dmasize=32M
usemsi=0
# Source the platform env file
env_file="/usr/share/sonic/device/$platform/platform_env.conf"
source $env_file
modprobe linux-kernel-bde dmasize=$dmasize maxpayload=128 debug=4 dma_debug=1 usemsi=$usemsi
modprobe linux-user-bde
# Using insmod with absolute path for psample to make sure bcm psample is loaded.
# There is a different psample.ko module getting created at net/psample/psample.ko
insmod /lib/modules/$(uname -r)/extra/psample.ko
modprobe linux-bcm-knet use_rx_skb=1 rx_buffer_size=9238 debug=0x5020
modprobe linux-knet-cb
}
function remove_kernel_modules()
{
rmmod psample.ko
rmmod linux-knet-cb
rmmod linux-bcm-knet
rmmod linux-user-bde

View File

@ -2,4 +2,5 @@ systems/linux/user/x86-smp_generic_64-2_6/linux-bcm-knet.ko lib/modules/4.9.0-9-
systems/linux/user/x86-smp_generic_64-2_6/linux-kernel-bde.ko lib/modules/4.9.0-9-2-amd64/extra
systems/linux/user/x86-smp_generic_64-2_6/linux-user-bde.ko lib/modules/4.9.0-9-2-amd64/extra
systems/linux/user/x86-smp_generic_64-2_6/linux-knet-cb.ko lib/modules/4.9.0-9-2-amd64/extra
systems/linux/user/x86-smp_generic_64-2_6/psample.ko lib/modules/4.9.0-9-2-amd64/extra
systemd/opennsl-modules.service lib/systemd/system

View File

@ -60,7 +60,7 @@ kdist_config: prep-deb-files
kdist_clean: clean
dh_testdir
dh_clean
SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 KERNDIR=/usr/src/linux-headers-4.9.0-9-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-9-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean
SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-9-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-9-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean
# rm -f driver/*.o driver/*.ko
#
### end KERNEL SETUP
@ -78,7 +78,7 @@ build-arch-stamp:
dh_testdir
# Add here command to compile/build the package.
SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 KERNDIR=/usr/src/linux-headers-4.9.0-9-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-9-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6
SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-9-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-9-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6
touch $@
@ -103,7 +103,7 @@ clean:
rm -f build-arch-stamp build-indep-stamp configure-stamp
# Add here commands to clean up after the build process.
SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 KERNDIR=/usr/src/linux-headers-4.9.0-9-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-9-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean
SDK=$(realpath .) LINUX_UAPI_SPLIT=1 DEBIAN_LINUX_HEADER=1 BUILD_KNET_CB=1 BUILD_PSAMPLE=1 KERNDIR=/usr/src/linux-headers-4.9.0-9-2-amd64 KERNEL_SRC=/usr/src/linux-headers-4.9.0-9-2-amd64 $(MAKE) -C systems/linux/user/x86-smp_generic_64-2_6 clean
dh_clean

View File

@ -148,14 +148,6 @@ typedef struct ibde_s {
*/
int (*get_cmic_ver)(int d, uint32 *ver);
/*
* Probe available devices.
* Return value :
* 0: success to probe available devices
* -1: error happens during probe
*/
int (*probe)(void);
/*
* I2C operations on the Device, assuming it is connected by I2C to the CPU.
*/

View File

@ -121,6 +121,13 @@ typedef struct kcom_msg_hdr_s {
#define KCOM_NETIF_NAME_MAX 16
/*
* Max size of Sand System Headers
* For DNX, Module Header(20B) + PTCH(2B) + ITMH(5B)
* For DPP, PTCH(2B) + ITMH(4B)
*/
#define KCOM_NETIF_SYSTEM_HEADERS_SIZE_MAX 27
typedef struct kcom_netif_s {
uint16 id;
uint8 type;
@ -133,6 +140,8 @@ typedef struct kcom_netif_s {
uint8 macaddr[6];
uint8 ptch[2];
uint8 itmh[4];
uint8 system_headers[KCOM_NETIF_SYSTEM_HEADERS_SIZE_MAX];
uint8 system_headers_size;
char name[KCOM_NETIF_NAME_MAX];
} kcom_netif_t;
@ -216,6 +225,13 @@ typedef struct kcom_filter_s {
uint8 b[KCOM_FILTER_BYTES_MAX];
uint32 w[KCOM_FILTER_WORDS_MAX];
} mask;
/** Information to parse Dune system headers */
uint32 ftmh_lb_key_ext_size;
uint32 ftmh_stacking_ext_size;
uint32 pph_base_size;
uint32 pph_lif_ext_size[8];
uint8 udh_enable;
uint32 udh_length_type[4];
} kcom_filter_t;
/*
@ -470,8 +486,7 @@ typedef struct kcom_msg_filter_destroy_s {
* Get list of currently defined packet filters.
*/
#ifndef KCOM_FILTER_MAX
/* SAI_FIXUP - Increased the filters to 1024 from 128 */
#define KCOM_FILTER_MAX 1024
#define KCOM_FILTER_MAX 128
#endif
typedef struct kcom_msg_filter_list_s {

View File

@ -14,7 +14,7 @@
* version 2 (GPLv2) along with this source code.
*/
/*
* Copyright: (c) 2018 Broadcom.
* Copyright: (c) 2019 Broadcom.
* All Rights Reserved.
*/
@ -835,31 +835,6 @@
#define BCM56746_A0_REV_ID 1
#define BCM56746_A1_REV_ID 2
#define BCM88230_DEVICE_ID 0x0230
#define BCM88230_A0_REV_ID 1
#define BCM88230_B0_REV_ID 0x11
#define BCM88230_C0_REV_ID 0x21
#define BCM88231_DEVICE_ID 0x0231
#define BCM88231_A0_REV_ID 1
#define BCM88231_B0_REV_ID 0x11
#define BCM88231_C0_REV_ID 0x21
#define BCM88235_DEVICE_ID 0x0235
#define BCM88235_A0_REV_ID 1
#define BCM88235_B0_REV_ID 0x11
#define BCM88235_C0_REV_ID 0x21
#define BCM88236_DEVICE_ID 0x0236
#define BCM88236_A0_REV_ID 1
#define BCM88236_B0_REV_ID 0x11
#define BCM88236_C0_REV_ID 0x21
#define BCM88239_DEVICE_ID 0x0239
#define BCM88239_A0_REV_ID 1
#define BCM88239_B0_REV_ID 0x11
#define BCM88239_C0_REV_ID 0x21
#define BCM56613_DEVICE_ID 0xb613
#define BCM56613_A0_REV_ID 1
#define BCM56613_B0_REV_ID 0x11
#define BCM56613_C0_REV_ID 0x21
#define BCM88732_DEVICE_ID 0x0732
#define BCM88732_A0_REV_ID 1
#define BCM88732_A1_REV_ID 2
@ -1243,10 +1218,13 @@
#define BCM56981_A0_REV_ID 1
#define BCM56982_DEVICE_ID 0xb982
#define BCM56982_A0_REV_ID 1
#define BCM56982_B0_REV_ID 0x11
#define BCM56983_DEVICE_ID 0xb983
#define BCM56983_A0_REV_ID 1
#define BCM56983_B0_REV_ID 0x11
#define BCM56984_DEVICE_ID 0xb984
#define BCM56984_A0_REV_ID 1
#define BCM56984_B0_REV_ID 0x11
#define BCM56968_DEVICE_ID 0xb968
#define BCM56968_A0_REV_ID 1
@ -1428,33 +1406,43 @@
#define BCM56370_DEVICE_ID 0xb370
#define BCM56370_A0_REV_ID 1
#define BCM56370_A1_REV_ID 0x02
#define BCM56371_DEVICE_ID 0xb371
#define BCM56371_A0_REV_ID 1
#define BCM56371_A1_REV_ID 0x02
#define BCM56372_DEVICE_ID 0xb372
#define BCM56372_A0_REV_ID 1
#define BCM56372_A1_REV_ID 0x02
#define BCM56374_DEVICE_ID 0xb374
#define BCM56374_A0_REV_ID 1
#define BCM56374_A1_REV_ID 0x02
#define BCM56375_DEVICE_ID 0xb375
#define BCM56375_A0_REV_ID 1
#define BCM56375_A1_REV_ID 0x02
#define BCM56376_DEVICE_ID 0xb376
#define BCM56376_A0_REV_ID 1
#define BCM56376_A1_REV_ID 0x02
#define BCM56377_DEVICE_ID 0xb377
#define BCM56377_A0_REV_ID 1
#define BCM56377_A1_REV_ID 0x02
#define BCM56577_DEVICE_ID 0xb577
#define BCM56577_A0_REV_ID 1
#define BCM56577_A1_REV_ID 0x02
#define BCM56578_DEVICE_ID 0xb578
#define BCM56578_A0_REV_ID 1
#define BCM56578_A1_REV_ID 0x02
#define BCM56579_DEVICE_ID 0xb579
#define BCM56579_A0_REV_ID 1
#define BCM56579_A1_REV_ID 0x02
#define BCM56770_DEVICE_ID 0xb770
#define BCM56770_A0_REV_ID 1
@ -1488,247 +1476,6 @@
#define BROADCOM_PHYID_HIGH 0x0040
#define BCM5338_PHYID_LOW 0x62b0
#define BCM5338_A0_REV_ID 0
#define BCM5338_A1_REV_ID 1
#define BCM5338_B0_REV_ID 3
#define BCM5324_PHYID_LOW 0xbc20
#define BCM5324_PHYID_HIGH 0x143
#define BCM5324_A1_PHYID_HIGH 0x153
#define BCM5324_DEVICE_ID 0xbc20
#define BCM5324_A0_REV_ID 0
#define BCM5324_A1_REV_ID 1
#define BCM5324_A2_REV_ID 2
#define BCM5380_PHYID_LOW 0x6250
#define BCM5380_A0_REV_ID 0
#define BCM5388_PHYID_LOW 0x6288
#define BCM5388_A0_REV_ID 0
#define BCM5396_PHYID_LOW 0xbd70
#define BCM5396_PHYID_HIGH 0x143
#define BCM5396_DEVICE_ID 0x96
#define BCM5396_A0_REV_ID 0
#define BCM5389_PHYID_LOW 0xbd70
#define BCM5389_PHYID_HIGH 0x143
#define BCM5389_DEVICE_ID 0x89
#define BCM5389_A0_REV_ID 0
#define BCM5389_A1_DEVICE_ID 0x86
#define BCM5389_A1_REV_ID 1
#define BCM5398_PHYID_LOW 0xbcd0
#define BCM5398_PHYID_HIGH 0x0143
#define BCM5398_DEVICE_ID 0x98
#define BCM5398_A0_REV_ID 0
#define BCM5325_PHYID_LOW 0xbc30
#define BCM5325_PHYID_HIGH 0x143
#define BCM5325_DEVICE_ID 0xbc30
#define BCM5325_A0_REV_ID 0
#define BCM5325_A1_REV_ID 1
#define BCM5348_PHYID_LOW 0xbe40
#define BCM5348_PHYID_HIGH 0x0143
#define BCM5348_DEVICE_ID 0x48
#define BCM5348_A0_REV_ID 0
#define BCM5348_A1_REV_ID 1
#define BCM5397_PHYID_LOW 0xbcd0
#define BCM5397_PHYID_HIGH 0x0143
#define BCM5397_DEVICE_ID 0x97
#define BCM5397_A0_REV_ID 0
#define BCM5347_PHYID_LOW 0xbe40
#define BCM5347_PHYID_HIGH 0x0143
#define BCM5347_DEVICE_ID 0x47
#define BCM5347_A0_REV_ID 0
#define BCM5395_PHYID_LOW 0xbcf0
#define BCM5395_PHYID_HIGH 0x0143
#define BCM5395_DEVICE_ID 0xbcf0
#define BCM5395_A0_REV_ID 0
#define BCM53242_PHYID_LOW 0xbf10
#define BCM53242_PHYID_HIGH 0x0143
#define BCM53242_DEVICE_ID 0xbf10
#define BCM53242_A0_REV_ID 0
#define BCM53242_B0_REV_ID 4
#define BCM53242_B1_REV_ID 5
#define BCM53262_PHYID_LOW 0xbf20
#define BCM53262_PHYID_HIGH 0x0143
#define BCM53262_DEVICE_ID 0xbf20
#define BCM53262_A0_REV_ID 0
#define BCM53262_B0_REV_ID 4
#define BCM53262_B1_REV_ID 5
#define BCM53115_PHYID_LOW 0xbf80
#define BCM53115_PHYID_HIGH 0x0143
#define BCM53115_DEVICE_ID 0xbf80
#define BCM53115_A0_REV_ID 0
#define BCM53115_A1_REV_ID 1
#define BCM53115_B0_REV_ID 2
#define BCM53115_B1_REV_ID 3
#define BCM53115_C0_REV_ID 8
#define BCM53118_PHYID_LOW 0xbfe0
#define BCM53118_PHYID_HIGH 0x0143
#define BCM53118_DEVICE_ID 0xbfe0
#define BCM53118_A0_REV_ID 0
#define BCM53118_B0_REV_ID 4
#define BCM53118_B1_REV_ID 5
#define BCM53280_PHYID_LOW 0x5e90
#define BCM53280_PHYID_HIGH 0x0362
#define BCM53280_DEVICE_ID (0x4 | BCM53280_PHYID_LOW)
#define BCM53280_A0_REV_ID 0
#define BCM53280_B0_REV_ID 0x4
#define BCM53280_B1_REV_ID 0x5
#define BCM53280_B2_REV_ID 0x6
#define BCM53286_DEVICE_ID (0x4 | BCM53280_PHYID_LOW)
#define BCM53288_DEVICE_ID (0xc | BCM53280_PHYID_LOW)
#define BCM53284_DEVICE_ID (0x7 | BCM53280_PHYID_LOW)
#define BCM53283_DEVICE_ID (0x6 | BCM53280_PHYID_LOW)
#define BCM53282_DEVICE_ID (0x5 | BCM53280_PHYID_LOW)
#define BCM53101_PHYID_LOW 0x5ed0
#define BCM53101_PHYID_HIGH 0x0362
#define BCM53101_DEVICE_ID 0x5ed0
#define BCM53101_A0_REV_ID 0
#define BCM53101_B0_REV_ID 4
#define BCM53125_PHYID_LOW 0x5f20
#define BCM53125_PHYID_HIGH 0x0362
#define BCM53125_DEVICE_ID 0x5f20
#define BCM53125_A0_REV_ID 0
#define BCM53125_B0_REV_ID 0x4
#define BCM53125_MODEL_ID 0x53125
#define BCM53134_PHYID_LOW 0x5350
#define BCM53134_PHYID_HIGH 0xAE02
#define BCM53134_DEVICE_ID 0x5350
#define BCM53134_A0_REV_ID 0x0
#define BCM53134_B0_REV_ID 0x1
#define BCM53134_B1_REV_ID 0x2
#define BCM53134_A0_MODEL_ID 0x5035
#define BCM53134_B0_MODEL_ID 0x5075
#define BCM53128_PHYID_LOW 0x5e10
#define BCM53128_PHYID_HIGH 0x0362
#define BCM53128_DEVICE_ID 0x5e10
#define BCM53128_A0_REV_ID 0
#define BCM53128_B0_REV_ID 0x4
#define BCM53128_MODEL_ID 0x53128
#define BCM53600_PHYID_LOW 0x5f40
#define BCM53600_PHYID_HIGH 0x0362
#define BCM53600_DEVICE_ID (0x3 | BCM53600_PHYID_LOW)
#define BCM53600_A0_REV_ID 0
#define BCM53602_DEVICE_ID (0x1 | BCM53600_PHYID_LOW)
#define BCM53603_DEVICE_ID (0x2 | BCM53600_PHYID_LOW)
#define BCM53604_DEVICE_ID (0x3 | BCM53600_PHYID_LOW)
#define BCM53606_DEVICE_ID (0x7 | BCM53600_PHYID_LOW)
#define BCM89500_PHYID_LOW 0x5d30
#define BCM89500_PHYID_HIGH 0x0362
#define BCM89500_DEVICE_ID 0x9500
#define BCM89501_DEVICE_ID 0x9501
#define BCM89200_DEVICE_ID 0x9200
#define BCM89500_A0_REV_ID 0
#define BCM89500_B0_REV_ID 0x4
#define BCM89500_MODEL_ID 0x89500
#define BCM53010_PHYID_LOW 0x8760
#define BCM53010_PHYID_HIGH 0x600d
#define BCM53010_DEVICE_ID 0x3010
#define BCM53011_DEVICE_ID 0x3011
#define BCM53012_DEVICE_ID 0x3012
#define BCM53010_A0_REV_ID 0
#define BCM53010_A2_REV_ID 0x2
#define BCM53010_MODEL_ID 0x53010
#define BCM53018_PHYID_LOW 0x87c0
#define BCM53018_PHYID_HIGH 0x600d
#define BCM53017_DEVICE_ID 0x3016
#define BCM53018_DEVICE_ID 0x3018
#define BCM53019_DEVICE_ID 0x3019
#define BCM53018_A0_REV_ID 0
#define BCM53018_MODEL_ID 0x53016
#define BCM53020_PHYID_LOW 0x87f0
#define BCM53020_PHYID_HIGH 0x600d
#define BCM53020_DEVICE_ID 0x8022
#define BCM53022_DEVICE_ID 0x8022
#define BCM53023_DEVICE_ID 0x8023
#define BCM53025_DEVICE_ID 0x8025
#define BCM58625_DEVICE_ID 0x8625
#define BCM58622_DEVICE_ID 0x8622
#define BCM58623_DEVICE_ID 0x8623
#define BCM58525_DEVICE_ID 0x8525
#define BCM58522_DEVICE_ID 0x8522
#define BCM53020_A0_REV_ID 0
#define BCM53020_MODEL_ID 0x3025
#define BCM4713_DEVICE_ID 0x4713
#define BCM4713_A0_REV_ID 0
#define BCM4713_A9_REV_ID 9
#define BCM53000_GMAC_DEVICE_ID 0x4715
#define BCM53000_A0_REV_ID 0
#define BCM53010_GMAC_DEVICE_ID 0x4715
#define BCM53000PCIE_DEVICE_ID 0x5300
#define SANDBURST_VENDOR_ID 0x17ba
#define BME3200_DEVICE_ID 0x0280
#define BME3200_A0_REV_ID 0x0000
#define BME3200_B0_REV_ID 0x0001
#define BM9600_DEVICE_ID 0x0480
#define BM9600_A0_REV_ID 0x0000
#define BM9600_B0_REV_ID 0x0010
#define QE2000_DEVICE_ID 0x0300
#define QE2000_A1_REV_ID 0x0001
#define QE2000_A2_REV_ID 0x0002
#define QE2000_A3_REV_ID 0x0003
#define QE2000_A4_REV_ID 0x0004
#define BCM88020_DEVICE_ID 0x0380
#define BCM88020_A0_REV_ID 0x0000
#define BCM88020_A1_REV_ID 0x0001
#define BCM88020_A2_REV_ID 0x0002
#define BCM88025_DEVICE_ID 0x0580
#define BCM88025_A0_REV_ID 0x0000
#define BCM88030_DEVICE_ID 0x0038
#define BCM88030_A0_REV_ID 0x0001
#define BCM88030_A1_REV_ID 0x0002
#define BCM88030_B0_REV_ID 0x0011
#define BCM88030_B1_REV_ID 0x0012
#define BCM88034_DEVICE_ID 0x0034
#define BCM88034_A0_REV_ID (BCM88030_A0_REV_ID)
#define BCM88034_A1_REV_ID (BCM88030_A1_REV_ID)
#define BCM88034_B0_REV_ID (BCM88030_B0_REV_ID)
#define BCM88034_B1_REV_ID (BCM88030_B1_REV_ID)
#define BCM88039_DEVICE_ID 0x0039
#define BCM88039_A0_REV_ID (BCM88030_A0_REV_ID)
#define BCM88039_A1_REV_ID (BCM88030_A1_REV_ID)
#define BCM88039_B0_REV_ID (BCM88030_B0_REV_ID)
#define BCM88039_B1_REV_ID (BCM88030_B1_REV_ID)
#define BCM88130_DEVICE_ID 0x0480
#define BCM88130_A0_REV_ID 0x0000
#define BCM88130_A1_REV_ID 0x0001
#define BCM88130_B0_REV_ID 0x0010
#define PLX_VENDOR_ID 0x10b5
#define PLX9656_DEVICE_ID 0x9656
#define PLX9656_REV_ID 0x0000
#define PLX9056_DEVICE_ID 0x9056
#define PLX9056_REV_ID 0x0000
#define TK371X_DEVICE_ID 0x8600
#define TK371X_A0_REV_ID 0x0
#define GEDI_DEVICE_ID 0xa100
#define GEDI_REV_ID 0x0001
#define ARAD_DEVICE_ID 0x8650
@ -1778,6 +1525,7 @@
#define DNXC_A0_REV_ID 0x0001
#define DNXC_A1_REV_ID 0x0002
#define DNXC_B0_REV_ID 0x0011
#define DNXC_B1_REV_ID 0x0012
#define BCM88790_DEVICE_ID 0x8790
#define BCM88790_A0_REV_ID DNXC_A0_REV_ID
#define BCM88790_B0_REV_ID DNXC_B0_REV_ID
@ -1933,9 +1681,34 @@
#define BCM88381_A0_REV_ID JERICHO_PLUS_A0_REV_ID
#define JERICHO_2_DEVICE_ID 0x8690
#define JERICHO_2_A0_REV_ID 0x0001
#define JERICHO_2_A0_REV_ID DNXC_A0_REV_ID
#define JERICHO_2_B0_REV_ID DNXC_B0_REV_ID
#define JERICHO_2_B1_REV_ID DNXC_B1_REV_ID
#define BCM88690_DEVICE_ID JERICHO_2_DEVICE_ID
#define BCM88690_A0_REV_ID JERICHO_2_A0_REV_ID
#define BCM88690_B0_REV_ID JERICHO_2_B0_REV_ID
#define BCM88690_B1_REV_ID JERICHO_2_B1_REV_ID
#define BCM88691_DEVICE_ID 0x8691
#define BCM88692_DEVICE_ID 0x8692
#define BCM88693_DEVICE_ID 0x8693
#define BCM88694_DEVICE_ID 0x8694
#define BCM88695_DEVICE_ID 0x8695
#define BCM88696_DEVICE_ID 0x8696
#define BCM88697_DEVICE_ID 0x8697
#define BCM88698_DEVICE_ID 0x8698
#define BCM88699_DEVICE_ID 0x8699
#define BCM8869A_DEVICE_ID 0x869A
#define BCM8869B_DEVICE_ID 0x869B
#define BCM8869C_DEVICE_ID 0x869C
#define BCM8869D_DEVICE_ID 0x869D
#define BCM8869E_DEVICE_ID 0x869E
#define BCM8869F_DEVICE_ID 0x869F
#define BCM_JR2_DEVID_MASK 0xFFF0
#define J2C_DEVICE_ID 0x8800
#define J2C_A0_REV_ID DNXC_A0_REV_ID
#define BCM88800_DEVICE_ID J2C_DEVICE_ID
#define BCM88800_A0_REV_ID J2C_A0_REV_ID
#define QAX_DEVICE_ID 0x8470
#define QAX_A0_REV_ID 0x0001
@ -1964,6 +1737,7 @@
#define BCM88270_A1_REV_ID QUX_A1_REV_ID
#define BCM88272_DEVICE_ID 0x8272
#define BCM88273_DEVICE_ID 0x8273
#define BCM88274_DEVICE_ID 0x8274
#define BCM88278_DEVICE_ID 0x8278
#define BCM88279_DEVICE_ID 0x8279
@ -2045,5 +1819,8 @@
#define ACP_PCI_VENDOR_ID 0x10ee
#define ACP_PCI_DEVICE_ID 0x7011
#define ACP_PCI_REV_ID 0x0001
#define PLX9056_DEVICE_ID 0x9056
#endif

View File

@ -54,12 +54,7 @@ endif
-include ${SDK}/make/Make.local
ifdef ALL_CHIPS
ROBO_CHIPS = 1
ESW_CHIPS = 1
else
ifndef ROBO_CHIPS
ESW_CHIPS = 1
endif
endif # ALL_CHIPS
#
@ -166,7 +161,7 @@ CFLAGS += ${INCFLAGS}
CXXFLAGS += ${INCFLAGS}
CPPFLAGS += ${INCFLAGS}
CFLAGS += -DSAI_FIXUP -DBCM_PORT_DEFAULT_DISABLE -DBCM_VLAN_NO_DEFAULT_ETHER -DBCM_VLAN_NO_DEFAULT_CPU -DBCM_WARM_BOOT_SUPPORT -DSAL_CONFIG_FILE_DISABLE -DSAL_THREAD_NAME_PRINT_DISABLE -UKCOM_FILTER_MAX -DKCOM_FILTER_MAX=256 -DALPM_ENABLE -DOPENNSL_PHY_ROUTINES -DTH2_CPU_POOL_SETUP -DINCLUDE_L3 -DSAI_ONLY -DPRINT_TO_SYSLOG -D_SHR_PBMP_WIDTH=256 -DINCLUDE_DIAG_SHELL -DSTATIC=static -DLOG_TEST -DLOG_SAI -D_GNU_SOURCE
CFLAGS += -DSAI_FIXUP -UKCOM_FILTER_MAX -DKCOM_FILTER_MAX=1024
#
# Debug #ifdef control

View File

@ -74,12 +74,6 @@ modname_flags = $(if $(filter 1,$(words $(modname))),\
KFLAG_INCLD = $(TOOLCHAIN_BIN_DIR)/../lib/gcc/$(TARGET_ARCHITECTURE)/4.6.4/include
ifdef BROADCOM_SVK
ifdef BCM_BME3200_B0
PLX_PCI2LBUS=1
endif
ifdef BCM_BM9600_B0
PLX_PCI2LBUS=1
endif
ifeq ($PLX_PCI2LBUS, 1)
CFLAGS += -DBCM_PLX9656_LOCAL_BUS -DBDE_LINUX_NON_INTERRUPTIBLE
endif

View File

@ -224,12 +224,6 @@ endif
endif
ifdef BROADCOM_SVK
ifdef BCM_BME3200_B0
PLX_PCI2LBUS=1
endif
ifdef BCM_BM9600_B0
PLX_PCI2LBUS=1
endif
ifeq ($PLX_PCI2LBUS, 1)
CFLAGS += -DBCM_PLX9656_LOCAL_BUS -DBDE_LINUX_NON_INTERRUPTIBLE
endif

View File

@ -27,11 +27,11 @@ endif
# TARGET_ARCHITECTURE Compiler for target architecture
# KERNDIR Kernel directory for iPROC-CMICd devices
ifeq (BE,$(ENDIAN_MODE))
TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/iproc-be/XLDK
TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk50-be/XLDK32
TARGET_ARCHITECTURE:=armeb-broadcom-linux-uclibcgnueabi
KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux
else
TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/iproc/XLDK
TOOLCHAIN_BASE_DIR ?= /projects/ntsw-tools/linux/iproc_ldks/xldk50/XLDK32
TARGET_ARCHITECTURE:= arm-broadcom-linux-uclibcgnueabi
KERNDIR ?= $(TOOLCHAIN_BASE_DIR)/kernel/linux
endif
@ -60,6 +60,8 @@ CFGFLAGS += -DSYS_BE_PIO=0 -DSYS_BE_PACKET=0 -DSYS_BE_OTHER=0
ENDIAN = LE_HOST=1
endif
CFLAGS += -fno-aggressive-loop-optimizations
CFGFLAGS += -D$(ENDIAN) -DIPROC_CMICD
CFGFLAGS += -DBCM_PLATFORM_STRING=\"IPROC_CMICD\"
@ -80,7 +82,7 @@ basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))"
modname_flags = $(if $(filter 1,$(words $(modname))),\
-D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))")
KFLAG_INCLD ?= $(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/lib/gcc/$(TARGET_ARCHITECTURE)/4.9.3/include
KFLAG_INCLD ?= $(TOOLCHAIN_BASE_DIR)/buildroot/host/usr/lib/gcc/$(TARGET_ARCHITECTURE)/4.9.4/include
ifeq (,$(KFLAGS))
KFLAGS := -D__LINUX_ARM_ARCH__=7 -D__KERNEL__ -nostdinc -isystem $(KFLAG_INCLD) -I$(LINUX_INCLUDE) -include $(LINUX_INCLUDE)/generated/autoconf.h -I$(KERNDIR)/arch/arm/include -I$(KERNDIR)/arch/arm/include/generated -I$(KERNDIR)/arch/arm/mach-iproc/include -Wall -Wstrict-prototypes -Wno-trigraphs -Os -fno-strict-aliasing -fno-common -marm -mabi=aapcs-linux -fno-pic -pipe -msoft-float -ffreestanding -march=armv7-a -mfpu=vfp -mfloat-abi=softfp -fomit-frame-pointer -g -fno-stack-protector -Wdeclaration-after-statement -Wno-pointer-sign -mlong-calls

View File

@ -71,7 +71,7 @@ $(KMODULE):
rm -f *.o *.ko .*.cmd
rm -fr .tmp_versions
ln -s $(LIBDIR)/$(MODULE) $(PRE_COMPILED_OBJ)_shipped
echo "suppress warning" > .$(PRE_COMPILED_OBJ).cmd
if [ ! -f $(KERNBLDDIR)/NO_SUPRESS ]; then echo "# suppress warning" > .$(PRE_COMPILED_OBJ).cmd; fi
$(MAKE) -C $(KERNBLDDIR) CROSS_COMPILE=$(CROSS_COMPILE) M=$(PWD) modules
if [ ! -f Module.symvers ]; then echo "old kernel (pre-2.6.17)" > Module.symvers; fi
cp -f $(KMODULE) $(LIBDIR)

View File

@ -22,7 +22,7 @@ ENDIAN = LE_HOST=1
CFGFLAGS += -D$(ENDIAN)
CFGFLAGS += -DBCM_PLATFORM_STRING=\"X86\"
ifeq (,$(findstring -DSAL_BDE_DMA_MEM_DEFAULT,$(CFGFLAGS)))
CFGFLAGS += -DSAL_BDE_DMA_MEM_DEFAULT=32
CFGFLAGS += -DSAL_BDE_DMA_MEM_DEFAULT=16
endif
# Extra variables.

View File

@ -48,4 +48,4 @@ AUTOCONF = $(KERNDIR)/include/linux/autoconf.h
endif
# gcc system include path
SYSINC = $(shell gcc -print-search-dirs | grep install | cut -c 10-)include
SYSINC = $(shell $(CC) -print-search-dirs | grep install | cut -c 10-)include

View File

@ -43,4 +43,3 @@ KFLAGS += -I$(KERNDIR_COMMON)/include -I$(KERNDIR_COMMON)/include/uapi -I$(KERND
endif
include ${SDK}/make/Makefile.linux-x86-common-2_6

View File

@ -222,7 +222,7 @@ extern int lkbde_dev_instid_set(int d, uint32 instid);
extern int lkbde_irq_mask_set(int d, uint32 addr, uint32 mask, uint32 fmask);
extern int lkbde_irq_mask_get(int d, uint32 *mask, uint32 *fmask);
#if (defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT))
#ifdef BCM_SAND_SUPPORT
extern int lkbde_cpu_write(int d, uint32 addr, uint32 *buf);
extern int lkbde_cpu_read(int d, uint32 addr, uint32 *buf);
extern int lkbde_cpu_pci_register(int d);
@ -241,15 +241,12 @@ extern int lkbde_cpu_pci_register(int d);
*/
#define LKBDE_IPROC_REG 0x4000
#if defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT)
#ifdef BCM_SAND_SUPPORT
#include <linux/version.h>
#if defined(__DUNE_LINUX_BCM_CPU_PCIE__) && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
#ifndef _SIMPLE_MEMORY_ALLOCATION_
#define _SIMPLE_MEMORY_ALLOCATION_ 1
#endif
#ifndef USE_LINUX_BDE_MMAP
#define USE_LINUX_BDE_MMAP 1
#endif
#endif
#endif
@ -271,13 +268,9 @@ extern int lkbde_cpu_pci_register(int d);
#define _SIMPLE_MEMORY_ALLOCATION_ 9 /* compile in the allocation method, but do not use it by default */
#endif
/* By default we use our private mmap only if /dev/mem mmap has restrictions */
/* By default we use our private mmap for DMA pool */
#ifndef USE_LINUX_BDE_MMAP
#ifdef CONFIG_STRICT_DEVMEM
#define USE_LINUX_BDE_MMAP 1
#else
#define USE_LINUX_BDE_MMAP 0
#endif
#endif
#endif /* __KERNEL__ */

View File

@ -58,7 +58,7 @@
#define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1))
#endif
extern void _dma_init(int robo_switch, int dev_index);
extern void _dma_init(int dev_index);
extern int _dma_cleanup(void);
extern void _dma_pprint(void);
extern uint32_t *_salloc(int d, int size, const char *name);
@ -68,7 +68,7 @@ extern int _sflush(int d, void *ptr, int length);
extern sal_paddr_t _l2p(int d, void *vaddr);
extern void *_p2l(int d, sal_paddr_t paddr);
extern int _dma_pool_allocated(void);
extern int _dma_range_valid(unsigned long phys_addr, unsigned long size);
extern int _dma_mmap(struct file *filp, struct vm_area_struct *vma);
#endif /* __KERNEL__ */

View File

@ -33,33 +33,11 @@ LIBS = $(LIBDIR)/libkern.a
BDE = linux-kernel-bde.o
ifdef ROBO_CHIPS
CFLAGS += -I$(ET_ROBO) -I${SDK}/include/shared/et
ET_ROBO = ${SDK}/systems/drv/et
endif
# need to add vpath sources
VPATH = ../shared $(ET_ROBO)
VPATH = ../shared
# Add the srcs to be found by vpath
LSRCS += mpool.c
ifdef ROBO_CHIPS
platformsplt = $(subst -, , ${platform}) # change hyphens to spaces
platformbase = $(word 1,${platformsplt})
ifeq ($(platformbase), keystone)
LSRCS += etc_robo_spi.c aiutils.c
else
ifeq ($(platformbase), keystone_le)
LSRCS += etc_robo_spi.c aiutils.c
else
ifeq ($(platformbase), iproc)
LSRCS += robo_srab.c robo_spi.c aiutils.c
endif
endif
endif # platformbase
endif # ROBO_CHIPS
# Add shared BDE sources
VPATH += ../../shared

View File

@ -85,10 +85,25 @@
#if _SIMPLE_MEMORY_ALLOCATION_ == 1
#define ALLOC_METHOD_DEFAULT ALLOC_TYPE_API
#if defined(__arm__)
#define USE_DMA_MMAP_COHERENT
#define _PGPROT_NONCACHED(x) x = pgprot_noncached((x))
#elif defined(__aarch64__ )
#define USE_DMA_MMAP_COHERENT
#define _PGPROT_NONCACHED(x) x = pgprot_writecombine((x))
#endif
#else
#define ALLOC_METHOD_DEFAULT ALLOC_TYPE_CHUNK
#endif
#ifndef _PGPROT_NONCACHED
#ifdef REMAP_DMA_NONCACHED
#define _PGPROT_NONCACHED(x) x = pgprot_noncached((x))
#else
#define _PGPROT_NONCACHED(x)
#endif
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
#include <linux/slab.h>
#define virt_to_bus virt_to_phys
@ -101,6 +116,12 @@
#define VIRT_TO_PAGE(p) virt_to_page((p))
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27))
#define DMA_MAPPING_ERROR(d, p) dma_mapping_error((d),(p))
#else
#define DMA_MAPPING_ERROR(d, p) dma_mapping_error((p))
#endif
#ifndef KMALLOC_MAX_SIZE
#define KMALLOC_MAX_SIZE (1UL << (MAX_ORDER - 1 + PAGE_SHIFT))
#endif
@ -170,7 +191,6 @@ MODULE_PARM_DESC(himemaddr,
#else
#define DMA_MEM_DEFAULT (8 * ONE_MB)
#endif
#define DMA_MEM_DEFAULT_ROBO (4 * ONE_MB)
/* We try to assemble a contiguous segment from chunks of this size */
#define DMA_BLOCK_SIZE (512 * ONE_KB)
@ -203,6 +223,7 @@ static unsigned long _himemaddr = 0;
static int _use_dma_mapping = 0;
static LIST_HEAD(_dma_seg);
#define DMA_DEV_INDEX 0 /* Device index to allocate memory pool */
#define DMA_DEV(n) lkbde_get_dma_dev(n)
#define BDE_NUM_DEVICES(t) lkbde_get_num_devices(t)
@ -545,7 +566,7 @@ _pgcleanup(void)
case ALLOC_TYPE_API:
if (_dma_vbase) {
if (dma_debug >= 1) gprintk("freeing v=%p p=0x%lx size=0x%lx\n", _dma_vbase,(unsigned long) _dma_pbase, (unsigned long)_dma_mem_size);
dma_free_coherent(DMA_DEV(0), _dma_mem_size, _dma_vbase, _dma_pbase);
dma_free_coherent(DMA_DEV(DMA_DEV_INDEX), _dma_mem_size, _dma_vbase, _dma_pbase);
}
break;
#endif /* _SIMPLE_MEMORY_ALLOCATION_ */
@ -554,7 +575,7 @@ _pgcleanup(void)
struct list_head *pos, *tmp;
int i, ndevices;
if (_use_dma_mapping) {
ndevices = BDE_NUM_DEVICES(BDE_ALL_DEVICES);
ndevices = BDE_NUM_DEVICES(BDE_SWITCH_DEVICES);
for (i = 0; i < ndevices && DMA_DEV(i); i ++) {
dma_unmap_single(DMA_DEV(i), (dma_addr_t)_dma_pbase, _dma_mem_size, DMA_BIDIRECTIONAL);
}
@ -591,7 +612,6 @@ static void
_alloc_mpool(size_t size)
{
unsigned long pbase = 0;
#if defined(__arm__) && !defined(CONFIG_HIGHMEM)
if (_use_himem) {
gprintk("DMA in high memory requires CONFIG_HIGHMEM on ARM CPUs.\n");
@ -614,6 +634,9 @@ _alloc_mpool(size_t size)
_dma_vbase = IOREMAP(_dma_pbase, size);
} else {
/* Get DMA memory from kernel */
if (dma_debug >= 1) {
gprintk("Allocating DMA memory using method dmaalloc=%d\n", dmaalloc);
}
switch (dmaalloc) {
#if _SIMPLE_MEMORY_ALLOCATION_
case ALLOC_TYPE_API: {
@ -624,8 +647,9 @@ _alloc_mpool(size_t size)
/* get a memory allocation from the kernel */
{
dma_addr_t dma_handle;
if (!(_dma_vbase = dma_alloc_coherent(DMA_DEV(0), alloc_size, &dma_handle, GFP_KERNEL)) || !dma_handle) {
gprintk("failed to allocate the memory pool of size 0x%lx\n", (unsigned long)alloc_size);
if (!(_dma_vbase = dma_alloc_coherent(DMA_DEV(DMA_DEV_INDEX),
alloc_size, &dma_handle, GFP_KERNEL)) || !dma_handle) {
gprintk("Failed to allocate coherent memory pool of size 0x%lx\n", (unsigned long)alloc_size);
return;
}
_cpu_pbase = pbase = dma_handle;
@ -643,14 +667,14 @@ _alloc_mpool(size_t size)
case ALLOC_TYPE_CHUNK:
_dma_vbase = _pgalloc(size);
if (!_dma_vbase) {
gprintk("failed to allocate the memory pool of size 0x%lx\n", (unsigned long)size);
gprintk("Failed to allocate memory pool of size 0x%lx\n", (unsigned long)size);
return;
}
_cpu_pbase = virt_to_bus(_dma_vbase);
/* Use dma_map_single to obtain DMA bus address or IOVA if iommu is present. */
if (DMA_DEV(0)) {
pbase = dma_map_single(DMA_DEV(0), _dma_vbase, size, DMA_BIDIRECTIONAL);
if (dma_mapping_error(DMA_DEV(0), pbase)) {
if (DMA_DEV(DMA_DEV_INDEX)) {
pbase = dma_map_single(DMA_DEV(DMA_DEV_INDEX), _dma_vbase, size, DMA_BIDIRECTIONAL);
if (DMA_MAPPING_ERROR(DMA_DEV(DMA_DEV_INDEX), pbase)) {
gprintk("Failed to map memory at %p\n", _dma_vbase);
_pgcleanup();
_dma_vbase = NULL;
@ -659,7 +683,6 @@ _alloc_mpool(size_t size)
}
_use_dma_mapping = 1;
} else {
/* Device has not been probed. */
pbase = _cpu_pbase;
}
break;
@ -719,15 +742,21 @@ _dma_cleanup(void)
return 0;
}
void _dma_init(int robo_switch, int dev_index)
void _dma_init(int dev_index)
{
unsigned long pbase;
if (dev_index > 0) {
if ((_use_dma_mapping == 1) && DMA_DEV(dev_index) && _dma_vbase) {
if (dev_index > DMA_DEV_INDEX) {
if (_use_dma_mapping && DMA_DEV(dev_index) && _dma_vbase) {
pbase = dma_map_single(DMA_DEV(dev_index), _dma_vbase, _dma_mem_size, DMA_BIDIRECTIONAL);
if (dma_mapping_error(DMA_DEV(dev_index), pbase)) {
if (DMA_MAPPING_ERROR(DMA_DEV(dev_index), pbase)) {
gprintk("Failed to map memory for device %d at %p\n", dev_index, _dma_vbase);
return;
}
if (pbase != (unsigned long)_dma_pbase) {
/* Bus address/IOVA must be identical for all devices. */
gprintk("Device %d has different pbase: %lx (should be %lx)\n",
dev_index, pbase, (unsigned long)_dma_pbase);
}
}
return;
@ -745,10 +774,6 @@ void _dma_init(int robo_switch, int dev_index)
gprintk("dmasize must be a power of 2 (1M, 2M, 4M, 8M etc.)\n");
_dma_mem_size = 0;
}
} else {
if(robo_switch){
_dma_mem_size = DMA_MEM_DEFAULT_ROBO;
}
}
if (himem) {
@ -775,42 +800,54 @@ void _dma_init(int robo_switch, int dev_index)
_alloc_mpool(_dma_mem_size);
if (_dma_vbase == NULL) {
gprintk("no DMA memory available\n");
}
else {
} else {
mpool_init();
_dma_pool = mpool_create(_dma_vbase, _dma_mem_size);
}
}
}
#if USE_LINUX_BDE_MMAP
/*
* Function: _dma_range_valid
* Some kernels are configured to prevent mapping of kernel RAM memory
* into user space via the /dev/mem device.
*
* Purpose:
* Check if DMA address range is valid.
* Parameters:
* phys_addr - start physical address
* size - range size
* Returns:
* 0 : not valid
* 1 : valid
* The function below provides a backdoor to mapping the DMA pool to
* user space via the BDE device file.
*/
int
_dma_range_valid(unsigned long phys_addr, unsigned long size)
int _dma_mmap(struct file *filp, struct vm_area_struct *vma)
{
unsigned long pool_start = _cpu_pbase;
unsigned long pool_end = pool_start + _dma_mem_size;
unsigned long phys_addr = vma->vm_pgoff << PAGE_SHIFT;
unsigned long size = vma->vm_end - vma->vm_start;
if (phys_addr < pool_start || (phys_addr + size) > pool_end) {
if (phys_addr < (unsigned long )_cpu_pbase ||
(phys_addr + size) > ((unsigned long )_cpu_pbase + _dma_mem_size)) {
gprintk("range 0x%lx-0x%lx outside DMA pool 0x%lx-0x%lx\n",
phys_addr, phys_addr + size, pool_start, pool_end);
return 0;
phys_addr, phys_addr + size, (unsigned long )_cpu_pbase,
(unsigned long )_cpu_pbase + _dma_mem_size);
return -EINVAL;
}
#ifdef USE_DMA_MMAP_COHERENT
if (dmaalloc == ALLOC_TYPE_API) {
vma->vm_pgoff = 0;
return dma_mmap_coherent(DMA_DEV(DMA_DEV_INDEX), vma, (void *)_dma_vbase, phys_addr, size);
}
return 1;
}
#endif
_PGPROT_NONCACHED(vma->vm_page_prot);
if (remap_pfn_range(vma,
vma->vm_start,
vma->vm_pgoff,
size,
vma->vm_page_prot)) {
gprintk("Failed to mmap phys range 0x%lx-0x%lx to 0x%lx-0x%lx\n",
phys_addr, phys_addr + size, vma->vm_start,vma->vm_end);
return -EAGAIN;
}
return 0;
}
/*
* Function: _dma_pool_allocated
*

View File

@ -70,12 +70,31 @@ static sal_sem_t _mpool_lock;
#endif
#endif
#define MPOOL_BUF_SIZE 1024
#define MPOOL_BUF_ALLOC_COUNT_MAX 16
typedef struct mpool_mem_s {
unsigned char *address;
int size;
struct mpool_mem_s *prev;
struct mpool_mem_s *next;
} mpool_mem_t;
static int _buf_alloc_count;
static mpool_mem_t *mpool_buf[MPOOL_BUF_ALLOC_COUNT_MAX];
static mpool_mem_t *free_list;
#define ALLOC_INIT_MPOOL_BUF(ptr) \
ptr = MALLOC((sizeof(mpool_mem_t) * MPOOL_BUF_SIZE)); \
if (ptr) { \
int i; \
for (i = 0; i < MPOOL_BUF_SIZE - 1; i++) { \
ptr[i].next = &ptr[i+1]; \
} \
ptr[MPOOL_BUF_SIZE - 1].next = NULL; \
free_list = &ptr[0]; \
}
/*
* Function: mpool_init
*
@ -116,6 +135,10 @@ mpool_alloc(mpool_handle_t pool, int size)
MPOOL_LOCK();
if (size < BCM_CACHE_LINE_BYTES) {
size = BCM_CACHE_LINE_BYTES;
}
mod = size & (BCM_CACHE_LINE_BYTES - 1);
if (mod != 0 ) {
size += (BCM_CACHE_LINE_BYTES - mod);
@ -131,21 +154,37 @@ mpool_alloc(mpool_handle_t pool, int size)
MPOOL_UNLOCK();
return NULL;
}
newptr = MALLOC(sizeof(mpool_mem_t));
if (!newptr) {
MPOOL_UNLOCK();
return NULL;
if (!free_list) {
if (_buf_alloc_count == MPOOL_BUF_ALLOC_COUNT_MAX) {
MPOOL_UNLOCK();
return NULL;
}
ALLOC_INIT_MPOOL_BUF(mpool_buf[_buf_alloc_count]);
if (mpool_buf[_buf_alloc_count] == NULL) {
MPOOL_UNLOCK();
return NULL;
}
_buf_alloc_count++;
}
newptr = free_list;
free_list = free_list->next;
newptr->address = ptr->address + ptr->size;
newptr->size = size;
newptr->next = ptr->next;
newptr->prev = ptr;
ptr->next->prev = newptr;
ptr->next = newptr;
#ifdef TRACK_DMA_USAGE
_dma_mem_used += size;
#endif
MPOOL_UNLOCK();
MPOOL_UNLOCK();
return newptr->address;
}
@ -165,25 +204,29 @@ void
mpool_free(mpool_handle_t pool, void *addr)
{
unsigned char *address = (unsigned char *)addr;
mpool_mem_t *ptr = pool, *prev = NULL;
mpool_mem_t *head = pool, *ptr = NULL;
MPOOL_LOCK();
while (ptr && ptr->next) {
if (ptr->next->address == address) {
if (!(head && head->prev)) {
MPOOL_UNLOCK();
return;
}
ptr = head->prev->prev;
while (ptr && (ptr != head)) {
if (ptr->address == address) {
#ifdef TRACK_DMA_USAGE
_dma_mem_used -= ptr->next->size;
_dma_mem_used -= ptr->size;
#endif
ptr->prev->next = ptr->next;
ptr->next->prev = ptr->prev;
ptr->next = free_list;
free_list = ptr;
break;
}
ptr = ptr->next;
}
if (ptr && ptr->next) {
prev = ptr;
ptr = ptr->next;
prev->next = ptr->next;
FREE(ptr);
ptr = ptr->prev;
}
MPOOL_UNLOCK();
@ -208,34 +251,45 @@ mpool_create(void *base_ptr, int size)
{
mpool_mem_t *head, *tail;
int mod = (int)(((unsigned long)base_ptr) & (BCM_CACHE_LINE_BYTES - 1));
int i;
MPOOL_LOCK();
for (i = 0; i < MPOOL_BUF_ALLOC_COUNT_MAX; i++) {
mpool_buf[i] = NULL;
}
_buf_alloc_count = 0;
ALLOC_INIT_MPOOL_BUF(mpool_buf[_buf_alloc_count]);
if (mpool_buf[_buf_alloc_count] == NULL) {
MPOOL_UNLOCK();
return NULL;
}
_buf_alloc_count++;
if (mod) {
base_ptr = (char*)base_ptr + (BCM_CACHE_LINE_BYTES - mod);
size -= (BCM_CACHE_LINE_BYTES - mod);
}
size &= ~(BCM_CACHE_LINE_BYTES - 1);
head = (mpool_mem_t *)MALLOC(sizeof(mpool_mem_t));
if (head == NULL) {
return NULL;
}
tail = (mpool_mem_t *)MALLOC(sizeof(mpool_mem_t));
if (tail == NULL) {
FREE(head);
return NULL;
}
head = free_list;
free_list = free_list->next;
tail = free_list;
free_list = free_list->next;
head->size = tail->size = 0;
head->address = base_ptr;
tail->address = head->address + size;
head->prev = tail;
head->next = tail;
tail->prev = head;
tail->next = NULL;
MPOOL_UNLOCK();
return head;
}
@ -252,13 +306,20 @@ mpool_create(void *base_ptr, int size)
int
mpool_destroy(mpool_handle_t pool)
{
mpool_mem_t *ptr, *next;
int i;
MPOOL_LOCK();
for (ptr = pool; ptr; ptr = next) {
next = ptr->next;
FREE(ptr);
if ((mpool_mem_t *)pool != mpool_buf[0]) {
MPOOL_UNLOCK();
return 0;
}
for (i = 0; i < MPOOL_BUF_ALLOC_COUNT_MAX; i++) {
if (mpool_buf[i]) {
FREE(mpool_buf[i]);
mpool_buf[i] = NULL;
}
}
MPOOL_UNLOCK();
@ -285,7 +346,7 @@ mpool_usage(mpool_handle_t pool)
MPOOL_LOCK();
for (ptr = pool; ptr; ptr = ptr->next) {
usage += ptr->size;
usage += ptr->size;
}
MPOOL_UNLOCK();

View File

@ -33,9 +33,6 @@
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,12,0)
#include <linux/uaccess.h>
#endif
#ifdef KEYSTONE
#include <shared/et/bcmdevs.h>
#endif
MODULE_AUTHOR("Broadcom Corporation");
@ -676,124 +673,10 @@ _bcm88750_interrupt(bde_ctrl_t *ctrl)
#endif
}
static void
_qe2k_interrupt(bde_ctrl_t *ctrl)
{
bde_inst_resource_t *res;
res = &_bde_inst_resource[ctrl->inst];
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x20/sizeof(uint32));
atomic_set(&res->intr, 1);
#ifdef BDE_LINUX_NON_INTERRUPTIBLE
wake_up(&res->intr_wq);
#else
wake_up_interruptible(&res->intr_wq);
#endif
}
static void
_fe2k_interrupt(bde_ctrl_t *ctrl)
{
bde_inst_resource_t *res;
res = &_bde_inst_resource[ctrl->inst];
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x18/sizeof(uint32)); /* PC_INTERRUPT_MASK */
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x24/sizeof(uint32)); /* PC_ERROR0_MASK */
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x2c/sizeof(uint32)); /* PC_ERROR1_MASK */
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x34/sizeof(uint32)); /* PC_UNIT_MASK */
atomic_set(&res->intr, 1);
#ifdef BDE_LINUX_NON_INTERRUPTIBLE
wake_up(&res->intr_wq);
#else
wake_up_interruptible(&res->intr_wq);
#endif
}
static void
_fe2kxt_interrupt(bde_ctrl_t *ctrl)
{
bde_inst_resource_t *res;
res = &_bde_inst_resource[ctrl->inst];
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x2c/sizeof(uint32)); /* PC_INTERRUPT_MASK */
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x38/sizeof(uint32)); /* PC_ERROR0_MASK */
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x40/sizeof(uint32)); /* PC_ERROR1_MASK */
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x50/sizeof(uint32)); /* PC_UNIT_MASK */
atomic_set(&res->intr, 1);
#ifdef BDE_LINUX_NON_INTERRUPTIBLE
wake_up(&res->intr_wq);
#else
wake_up_interruptible(&res->intr_wq);
#endif
}
static void
_bme3200_interrupt(bde_ctrl_t *ctrl)
{
bde_inst_resource_t *res;
res = &_bde_inst_resource[ctrl->inst];
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x54/sizeof(uint32)); /* PI_PT_ERROR0 */
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x5c/sizeof(uint32)); /* PI_PT_ERROR1 */
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x64/sizeof(uint32)); /* PI_PT_ERROR2 */
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x6c/sizeof(uint32)); /* PI_PT_ERROR3 */
atomic_set(&res->intr, 1);
#ifdef BDE_LINUX_NON_INTERRUPTIBLE
wake_up(&res->intr_wq);
#else
wake_up_interruptible(&res->intr_wq);
#endif
}
static void
_bm9600_interrupt(bde_ctrl_t *ctrl)
{
bde_inst_resource_t *res;
res = &_bde_inst_resource[ctrl->inst];
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x5c/sizeof(uint32)); /* PI_INTERRUPT_MASK */
SSOC_WRITEL(0xffffffff, ctrl->ba + 0xc/sizeof(uint32)); /* PI_UNIT_INTERRUPT0_MASK */
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x14/sizeof(uint32)); /* PI_UNIT_INTERRUPT1_MASK */
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x1c/sizeof(uint32)); /* PI_UNIT_INTERRUPT2_MASK */
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x24/sizeof(uint32)); /* PI_UNIT_INTERRUPT3_MASK */
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x2c/sizeof(uint32)); /* PI_UNIT_INTERRUPT4_MASK */
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x34/sizeof(uint32)); /* PI_UNIT_INTERRUPT5_MASK */
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x3c/sizeof(uint32)); /* PI_UNIT_INTERRUPT6_MASK */
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x44/sizeof(uint32)); /* PI_UNIT_INTERRUPT7_MASK */
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x4c/sizeof(uint32)); /* PI_UNIT_INTERRUPT8_MASK */
SSOC_WRITEL(0xffffffff, ctrl->ba + 0x54/sizeof(uint32)); /* PI_UNIT_INTERRUPT9_MASK */
atomic_set(&res->intr, 1);
#ifdef BDE_LINUX_NON_INTERRUPTIBLE
wake_up(&res->intr_wq);
#else
wake_up_interruptible(&res->intr_wq);
#endif
}
/* The actual interrupt handler of ethernet devices */
static void
_ether_interrupt(bde_ctrl_t *ctrl)
{
#ifdef KEYSTONE
/*
* Since the two GMAC cores are sharing the same IRQ.
* Add the checking to handle the interrupt events.
*/
if ((ctrl->devid == BCM53000_GMAC_ID)) {
if ((readl(ctrl->ba + 0x020/4) & readl(ctrl->ba + 0x024/4)) == 0) {
return;
}
}
#endif
SSOC_WRITEL(0, ctrl->ba + 0x024/4);
atomic_set(&_ether_interrupt_has_taken_place, 1);
@ -813,11 +696,6 @@ static struct _intr_mode_s {
{ (isr_f)_cmicm_interrupt, "CMICm" },
{ (isr_f)_cmicd_interrupt, "CMICd" },
{ (isr_f)_cmicd_cmc0_interrupt, "CMICd CMC0" },
{ (isr_f)_qe2k_interrupt, "QE2K" },
{ (isr_f)_fe2k_interrupt, "FE2K" },
{ (isr_f)_fe2kxt_interrupt, "FE2KXT" },
{ (isr_f)_bme3200_interrupt, "BME3200" },
{ (isr_f)_bm9600_interrupt, "BM9600" },
{ (isr_f)_bcm88750_interrupt, "BCM88750" },
{ (isr_f)_cmicx_interrupt, "CMICx" },
{ NULL, NULL }
@ -845,7 +723,7 @@ _devices_init(int d)
uint32 ver;
uint16 device_id_mask = 0xFFF0;
uint16 device_id;
int state = 0;
uint32 state = 0;
(void)lkbde_dev_state_get(d, &state);
if (state == BDE_DEV_STATE_REMOVED) {
@ -864,21 +742,6 @@ _devices_init(int d)
}
if (ctrl->dev_type & BDE_SWITCH_DEV_TYPE) {
switch (user_bde->get_dev(d)->device) {
case QE2000_DEVICE_ID:
ctrl->isr = (isr_f)_qe2k_interrupt;
break;
case BCM88020_DEVICE_ID:
ctrl->isr = (isr_f)_fe2k_interrupt;
break;
case BCM88025_DEVICE_ID:
ctrl->isr = (isr_f)_fe2kxt_interrupt;
break;
case BME3200_DEVICE_ID:
ctrl->isr = (isr_f)_bme3200_interrupt;
break;
case BM9600_DEVICE_ID:
ctrl->isr = (isr_f)_bm9600_interrupt;
break;
case BCM88750_DEVICE_ID:
case BCM88753_DEVICE_ID:
case BCM88754_DEVICE_ID:
@ -920,7 +783,7 @@ _devices_init(int d)
case BCM88380_DEVICE_ID:
case BCM88381_DEVICE_ID:
case BCM88680_DEVICE_ID:
case BCM88690_DEVICE_ID:
case BCM88800_DEVICE_ID:
case BCM88770_DEVICE_ID:
case BCM88773_DEVICE_ID:
case BCM88774_DEVICE_ID:
@ -938,6 +801,7 @@ _devices_init(int d)
case BCM88270_DEVICE_ID:
case BCM88272_DEVICE_ID:
case BCM88273_DEVICE_ID:
case BCM88274_DEVICE_ID:
case BCM88278_DEVICE_ID:
case BCM88279_DEVICE_ID:
case BCM8206_DEVICE_ID:
@ -1002,7 +866,15 @@ _devices_init(int d)
}
break;
}
/* All Ramon devices from 0x8790 to 0x879F */
#ifdef BCM_DNX_SUPPORT
/*All Jericho 2 devices from 0x8690 to 0x869F*/
if (SOC_IS_JERICHO_2_TYPE(user_bde->get_dev(d)->device)) {
ctrl->isr = (isr_f)_cmicx_interrupt;
}
#endif
/*All Ramon devices from 0x8790 to 0x879F*/
if ((user_bde->get_dev(d)->device & BCM88790_DEVICE_ID) == BCM88790_DEVICE_ID) {
ctrl->isr = (isr_f)_cmicx_interrupt;
}
@ -1456,30 +1328,9 @@ _ioctl(unsigned int cmd, unsigned long arg)
}
break;
case LUBDE_USLEEP:
sal_usleep(io.d0);
break;
case LUBDE_UDELAY:
sal_udelay(io.d0);
break;
case LUBDE_SEM_OP:
switch (io.d0) {
case LUBDE_SEM_OP_CREATE:
io.p0 = (bde_kernel_addr_t)sal_sem_create("", io.d1, io.d2);
break;
case LUBDE_SEM_OP_DESTROY:
sal_sem_destroy((sal_sem_t)io.p0);
break;
case LUBDE_SEM_OP_TAKE:
io.rc = sal_sem_take((sal_sem_t)io.p0, io.d2);
break;
case LUBDE_SEM_OP_GIVE:
io.rc = sal_sem_give((sal_sem_t)io.p0);
break;
default:
io.rc = LUBDE_FAIL;
break;
}
break;
return -EINVAL;
case LUBDE_WRITE_IRQ_MASK:
io.rc = lkbde_irq_mask_set(io.dev, io.d0, io.d1, 0);
break;
@ -1499,7 +1350,7 @@ _ioctl(unsigned int cmd, unsigned long arg)
case LUBDE_WRITE_REG_16BIT_BUS:
io.rc = user_bde->write(io.dev, io.d0, io.d1);
break;
#if (defined(BCM_PETRA_SUPPORT) || defined(BCM_DFE_SUPPORT))
#ifdef BCM_SAND_SUPPORT
case LUBDE_CPU_WRITE_REG:
{
if (lkbde_cpu_write(io.dev, io.d0, (uint32*)io.dx.buf) == -1) {

View File

@ -30,6 +30,8 @@
#define BAR0_PAXB_CONFIG_IND_ADDR 0x2120
#define BAR0_PAXB_CONFIG_IND_DATA 0x2124
#define PAXB_0_CMICD_TO_PCIE_INTR_EN 0x2380
#define BAR0_PAXB_IMAP0_0 (0x2c00)
#define BAR0_PAXB_IMAP0_1 (0x2c04)
#define BAR0_PAXB_IMAP0_2 (0x2c08)
@ -287,7 +289,8 @@ shbde_iproc_paxb_init(shbde_hal_t *shbde, void *iproc_regs,
iproc32_write(shbde, reg, data | 0x1);
}
}
/* Configure MSIX interrupt page, only need for iproc ver == 0x10 */
/* Configure MSIX interrupt page, only need for iproc ver == 0x10 */
if ((icfg->use_msi == 2) && (icfg->iproc_ver == 0x10)) {
unsigned int mask = (0x1 << PAXB_0_FUNC0_IMAP1_3_ADDR_SHIFT) - 1;
reg = ROFFS(iproc_regs, PAXB_0_FUNC0_IMAP1_3);
@ -296,6 +299,17 @@ shbde_iproc_paxb_init(shbde_hal_t *shbde, void *iproc_regs,
data |= 0x410 << PAXB_0_FUNC0_IMAP1_3_ADDR_SHIFT;
iproc32_write(shbde, reg, data);
}
/* Disable INTx interrupt if MSI/MSIX is selected */
reg = ROFFS(iproc_regs, PAXB_0_CMICD_TO_PCIE_INTR_EN);
data = iproc32_read(shbde, reg);
if (icfg->use_msi) {
data &= ~0x1;
} else {
data |= 0x1;
}
iproc32_write(shbde, reg, data);
return pci_num;
}

View File

@ -39,14 +39,17 @@ typedef struct {
* Call-back interfaces for other Linux kernel drivers.
*/
#include <linux/skbuff.h>
#include <linux/netdevice.h>
#include <kcom.h>
typedef struct {
uint32 netif_user_data;
uint32 filter_user_data;
uint16 dcb_type;
int port;
} knet_skb_cb_t;
#define KNET_SKB_CB(__skb) ((knet_skb_cb_t *)&((__skb)->cb[0]))
#define KNET_SKB_CB(_skb) ((knet_skb_cb_t *)_skb->cb)
typedef struct sk_buff *
(*knet_skb_cb_f)(struct sk_buff *skb, int dev_no, void *meta);
@ -55,6 +58,21 @@ typedef int
(*knet_filter_cb_f)(uint8_t *pkt, int size, int dev_no, void *meta,
int chan, kcom_filter_t *filter);
typedef int
(*knet_hw_tstamp_enable_cb_f)(int dev_no, int port);
typedef int
(*knet_hw_tstamp_tx_time_get_cb_f)(int dev_no, int port, uint8_t *pkt, uint64_t *ts);
typedef int
(*knet_hw_tstamp_tx_meta_get_cb_f)(int dev_no, struct sk_buff *skb, uint32_t **md);
typedef int
(*knet_hw_tstamp_ptp_clock_index_cb_f)(int dev_no);
typedef int
(*knet_hw_tstamp_rx_time_upscale_cb_f)(int dev_no, uint64_t *ts);
extern int
bkn_rx_skb_cb_register(knet_skb_cb_f rx_cb);
@ -73,6 +91,68 @@ bkn_filter_cb_register(knet_filter_cb_f filter_cb);
extern int
bkn_filter_cb_unregister(knet_filter_cb_f filter_cb);
#endif
extern int
bkn_hw_tstamp_enable_cb_register(knet_hw_tstamp_enable_cb_f hw_tstamp_enable_cb);
extern int
bkn_hw_tstamp_enable_cb_unregister(knet_hw_tstamp_enable_cb_f hw_tstamp_enable_cb);
extern int
bkn_hw_tstamp_disable_cb_register(knet_hw_tstamp_enable_cb_f hw_tstamp_disable_cb);
extern int
bkn_hw_tstamp_disable_cb_unregister(knet_hw_tstamp_enable_cb_f hw_tstamp_disable_cb);
extern int
bkn_hw_tstamp_tx_time_get_cb_register(knet_hw_tstamp_tx_time_get_cb_f hw_tstamp_tx_time_get_cb);
extern int
bkn_hw_tstamp_tx_time_get_cb_unregister(knet_hw_tstamp_tx_time_get_cb_f hw_tstamp_tx_time_get_cb);
extern int
bkn_hw_tstamp_tx_meta_get_cb_register(knet_hw_tstamp_tx_meta_get_cb_f hw_tstamp_tx_meta_get_cb);
extern int
bkn_hw_tstamp_tx_meta_get_cb_unregister(knet_hw_tstamp_tx_meta_get_cb_f hw_tstamp_tx_meta_get_cb);
extern int
bkn_hw_tstamp_ptp_clock_index_cb_register(knet_hw_tstamp_ptp_clock_index_cb_f hw_tstamp_ptp_clock_index_cb);
extern int
bkn_hw_tstamp_ptp_clock_index_cb_unregister(knet_hw_tstamp_ptp_clock_index_cb_f hw_tstamp_ptp_clock_index_cb);
extern int
bkn_hw_tstamp_rx_time_upscale_cb_register(knet_hw_tstamp_rx_time_upscale_cb_f hw_tstamp_rx_time_upscale_cb);
extern int
bkn_hw_tstamp_rx_time_upscale_cb_unregister(knet_hw_tstamp_rx_time_upscale_cb_f hw_tstamp_rx_time_upscale_cb);
typedef struct {
uint8 cmic_type;
uint8 dcb_type;
uint8 dcb_size;
uint8 pkt_hdr_size;
uint32 cdma_channels;
} knet_hw_info_t;
extern int
bkn_hw_info_get(int unit, knet_hw_info_t *hw_info);
typedef int
(*knet_netif_cb_f)(int unit, kcom_netif_t *netif, struct net_device *dev);
extern int
bkn_netif_create_cb_register(knet_netif_cb_f netif_cb);
extern int
bkn_netif_create_cb_unregister(knet_netif_cb_f netif_cb);
extern int
bkn_netif_destroy_cb_register(knet_netif_cb_f netif_cb);
extern int
bkn_netif_destroy_cb_unregister(knet_netif_cb_f netif_cb);
#endif /* __KERNEL__ */
#endif /* __LINUX_BCM_KNET_H__ */

View File

@ -0,0 +1,24 @@
#ifndef __NET_PSAMPLE_H
#define __NET_PSAMPLE_H
#include <gmodule.h>
#include <uapi/linux/psample.h>
#include <linux/module.h>
#include <linux/list.h>
struct psample_group {
struct list_head list;
struct net *net;
u32 group_num;
u32 refcount;
u32 seq;
};
extern struct psample_group *psample_group_get(struct net *net, u32 group_num);
extern void psample_group_put(struct psample_group *group);
extern void psample_sample_packet(struct psample_group *group, struct sk_buff *skb,
u32 trunc_size, int in_ifindex, int out_ifindex,
u32 sample_rate);
#endif /* __NET_PSAMPLE_H */

View File

@ -0,0 +1,35 @@
#ifndef __UAPI_PSAMPLE_H
#define __UAPI_PSAMPLE_H
enum {
/* sampled packet metadata */
PSAMPLE_ATTR_IIFINDEX,
PSAMPLE_ATTR_OIFINDEX,
PSAMPLE_ATTR_ORIGSIZE,
PSAMPLE_ATTR_SAMPLE_GROUP,
PSAMPLE_ATTR_GROUP_SEQ,
PSAMPLE_ATTR_SAMPLE_RATE,
PSAMPLE_ATTR_DATA,
/* commands attributes */
PSAMPLE_ATTR_GROUP_REFCOUNT,
__PSAMPLE_ATTR_MAX
};
enum psample_command {
PSAMPLE_CMD_SAMPLE,
PSAMPLE_CMD_GET_GROUP,
PSAMPLE_CMD_NEW_GROUP,
PSAMPLE_CMD_DEL_GROUP,
};
/* Can be overridden at runtime by module option */
#define PSAMPLE_ATTR_MAX (__PSAMPLE_ATTR_MAX - 1)
#define PSAMPLE_NL_MCGRP_CONFIG_NAME "config"
#define PSAMPLE_NL_MCGRP_SAMPLE_NAME "packets"
#define PSAMPLE_GENL_NAME "psample"
#define PSAMPLE_GENL_VERSION 1
#endif

View File

@ -36,7 +36,9 @@ KMODULE = $(LIBDIR)/$(THIS_MOD_NAME).ko
build: $(MODULE) $(KMODULE)
endif
KBUILD_EXTRA_SYMBOLS := ${BLDDIR}/../bcm-knet/kernel_module/Module.symvers
ifeq ($(BUILD_PSAMPLE),1)
KBUILD_EXTRA_SYMBOLS += ${BLDDIR}/../psample/kernel_module/Module.symvers
endif
# BCM Network Device

View File

@ -1,5 +1,5 @@
/*
* Copyright 2017 Broadcom
* Copyright 2017-2019 Broadcom
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2, as
@ -45,17 +45,20 @@
#include <bcm-knet.h>
#include <linux/if_vlan.h>
/* Enable sflow sampling using psample */
#ifdef PSAMPLE_SUPPORT
#include "psample-cb.h"
#endif
MODULE_AUTHOR("Broadcom Corporation");
MODULE_DESCRIPTION("Broadcom Linux KNET Call-Back Driver");
MODULE_LICENSE("GPL");
static int debug;
int debug;
LKM_MOD_PARAM(debug, "i", int, 0);
MODULE_PARM_DESC(debug,
"Debug level (default 0)");
/* Module Information */
#define MODULE_MAJOR 121
#define MODULE_NAME "linux-knet-cb"
@ -63,8 +66,10 @@ MODULE_PARM_DESC(debug,
/* set KNET_CB_DEBUG for debug info */
#define KNET_CB_DEBUG
#define FILTER_TAG_STRIP 0
#define FILTER_TAG_KEEP 1
/* These below need to match incoming enum values */
#define FILTER_TAG_STRIP 0
#define FILTER_TAG_KEEP 1
#define FILTER_TAG_ORIGINAL 2
/* Maintain tag strip statistics */
struct strip_stats_s {
@ -105,7 +110,7 @@ strip_vlan_tag(struct sk_buff *skb)
*
* DCB type 14: word 12, bits 10.11
* DCB type 19, 20, 21, 22, 30: word 12, bits 10..11
* DCB type 23, 29: word 13, bits 0..1
* DCB type 23, 29: word 13, bits 0..1
* DCB type 31, 34, 37: word 13, bits 0..1
* DCB type 26, 32, 33, 35: word 13, bits 0..1
*
@ -150,7 +155,7 @@ get_tag_status(int dcb_type, void *meta)
{
/* untested */
/* TH3 only parses outer tag. */
const int tag_map[4] = { 0, 2, -1, -1 };
const int tag_map[4] = { 0, 2, -1, -1 };
tag_status = tag_map[(dcb[9] >> 13) & 0x3];
}
break;
@ -162,7 +167,7 @@ get_tag_status(int dcb_type, void *meta)
if (debug & 0x1) {
gprintk("%s; DCB Type: %d; tag status: %d\n", __func__, dcb_type, tag_status);
}
#endif
#endif
return tag_status;
}
@ -183,12 +188,12 @@ strip_tag_rx_cb(struct sk_buff *skb, int dev_no, void *meta)
if (debug & 0x1) {
gprintk("%s Enter; netif Flags: %08X filter_flags %08X \n",
__func__, netif_flags, filter_flags);
}
}
#endif
/* KNET implements this already */
if (filter_flags == FILTER_TAG_KEEP)
{
{
strip_stats.skipped++;
return skb;
}
@ -217,8 +222,17 @@ strip_tag_rx_cb(struct sk_buff *skb, int dev_no, void *meta)
return skb;
}
if (filter_flags == FILTER_TAG_ORIGINAL)
{
/* If untagged or single inner, strip the extra tag that knet
keep tag will add. */
if (tag_status < 2)
{
strip_tag = 1;
}
}
strip_stats.checked++;
if (strip_tag) {
#ifdef KNET_CB_DEBUG
if (debug & 0x1) {
@ -235,7 +249,6 @@ strip_tag_rx_cb(struct sk_buff *skb, int dev_no, void *meta)
}
}
#endif
return skb;
}
@ -250,16 +263,50 @@ strip_tag_tx_cb(struct sk_buff *skb, int dev_no, void *meta)
/* Filter callback not used */
static int
strip_tag_filter_cb(uint8_t * pkt, int size, int dev_no, void *meta,
int chan, kcom_filter_t *kf)
int chan, kcom_filter_t *kf)
{
/* Pass through for now */
return 0;
}
static int
knet_filter_cb(uint8_t * pkt, int size, int dev_no, void *meta,
int chan, kcom_filter_t *kf)
{
/* check for filter callback handler */
#ifdef PSAMPLE_SUPPORT
if (strncmp(kf->desc, PSAMPLE_CB_NAME, KCOM_FILTER_DESC_MAX) == 0) {
return psample_filter_cb (pkt, size, dev_no, meta, chan, kf);
}
#endif
return strip_tag_filter_cb (pkt, size, dev_no, meta, chan, kf);
}
static int
knet_netif_create_cb(int unit, kcom_netif_t *netif, struct net_device *dev)
{
int retv = 0;
#ifdef PSAMPLE_SUPPORT
retv = psample_netif_create_cb(unit, netif, dev);
#endif
return retv;
}
static int
knet_netif_destroy_cb(int unit, kcom_netif_t *netif, struct net_device *dev)
{
int retv = 0;
#ifdef PSAMPLE_SUPPORT
retv = psample_netif_destroy_cb(unit, netif, dev);
#endif
return retv;
}
/*
* Get statistics.
* % cat /proc/linux-knet-cb
*/
static int
_pprint(void)
{
@ -275,19 +322,40 @@ static int
_cleanup(void)
{
bkn_rx_skb_cb_unregister(strip_tag_rx_cb);
bkn_tx_skb_cb_unregister(strip_tag_tx_cb);
bkn_filter_cb_unregister(strip_tag_filter_cb);
/* strip_tag_tx_cb is currently a no-op, so no need to unregister */
if (0)
{
bkn_tx_skb_cb_unregister(strip_tag_tx_cb);
}
bkn_filter_cb_unregister(knet_filter_cb);
bkn_netif_create_cb_unregister(knet_netif_create_cb);
bkn_netif_destroy_cb_unregister(knet_netif_destroy_cb);
#ifdef PSAMPLE_SUPPORT
psample_cleanup();
#endif
return 0;
}
static int
_init(void)
{
bkn_rx_skb_cb_register(strip_tag_rx_cb);
bkn_tx_skb_cb_register(strip_tag_tx_cb);
bkn_filter_cb_register(strip_tag_filter_cb);
bkn_rx_skb_cb_register(strip_tag_rx_cb);
/* strip_tag_tx_cb is currently a no-op, so no need to register */
if (0)
{
bkn_tx_skb_cb_register(strip_tag_tx_cb);
}
#ifdef PSAMPLE_SUPPORT
psample_init();
#endif
bkn_filter_cb_register(knet_filter_cb);
bkn_netif_create_cb_register(knet_netif_create_cb);
bkn_netif_destroy_cb_register(knet_netif_destroy_cb);
return 0;
}

View File

@ -0,0 +1,875 @@
/*
* Copyright 2017-2019 Broadcom
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2, as
* published by the Free Software Foundation (the "GPL").
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License version 2 (GPLv2) for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 (GPLv2) along with this source code.
*/
/*
* $Id: psample_cb.c $
* $Copyright: (c) 2019 Broadcom Corp.
* All Rights Reserved.$
*/
/*
* Driver for call-back functions for Linux KNET driver.
*
* This code is used to integrate packet sampling KNET callback to
* the psample infra for sending sampled pkts to userspace sflow
* applications such as Host Sflow (https://github.com/sflow/host-sflow)
* using genetlink interfaces.
*
* The module can be built from the standard Linux user mode target
* directories using the following command (assuming bash), e.g.
*
* cd $SDK/systems/linux/user/<target>
* make BUILD_KNET_CB=1
*
*/
#include <gmodule.h> /* Must be included first */
#include <kcom.h>
#include <bcm-knet.h>
#include <linux/if_vlan.h>
#include <linux/skbuff.h>
#include <linux/sched.h>
#include <linux/netdevice.h>
#include <net/net_namespace.h>
#include <net/psample.h>
#include "psample-cb.h"
#define PSAMPLE_CB_DBG
#ifdef PSAMPLE_CB_DBG
extern int debug;
#define PSAMPLE_CB_DBG_PRINT(...) \
if (debug & 0x1) { \
gprintk(__VA_ARGS__); \
}
#else
#define PSAMPLE_CB_DBG_PRINT(...)
#endif
/* HIGIG2 header fields */
#define SOC_HIGIG_SOP (0xfb)
#define SOC_HIGIG_START(x) ((x[0] >> 24) & 0xff)
#define SOC_HIGIG_DSTPORT(x) ((x[1] >> 11) & 0x1f)
#define SOC_HIGIG_SRCPORT(x) ((x[1] >> 16) & 0x1f)
#define SOC_HIGIG2_SOP (0xfb) //0xfc - TODO: how can we differentiate between Higig and higig2?
#define SOC_HIGIG2_START(x) ((x[0] >> 24) & 0xff)
#define SOC_HIGIG2_DSTPORT(x) ((x[0] >> 0) & 0xff)
#define SOC_HIGIG2_SRCPORT(x) ((x[1] >> 16) & 0xff)
#define SOC_DCB32_HG_OFFSET (6)
#define FCS_SZ 4
#define PSAMPLE_NLA_PADDING 4
#define PSAMPLE_RATE_DFLT 1
#define PSAMPLE_SIZE_DFLT 128
static int psample_size = PSAMPLE_SIZE_DFLT;
LKM_MOD_PARAM(psample_size, "i", int, 0);
MODULE_PARM_DESC(psample_size,
"psample pkt size (default 128 bytes)");
/* driver proc entry root */
static struct proc_dir_entry *psample_proc_root = NULL;
/* psample general info */
typedef struct {
struct list_head netif_list;
knet_hw_info_t hw;
struct net *netns;
spinlock_t lock;
} psample_info_t;
static psample_info_t g_psample_info = {{0}};
/* Maintain sampled pkt statistics */
typedef struct psample_stats_s {
unsigned long pkts_f_psample_cb;
unsigned long pkts_f_psample_mod;
unsigned long pkts_f_handled;
unsigned long pkts_f_pass_through;
unsigned long pkts_d_no_group;
unsigned long pkts_d_sampling_disabled;
unsigned long pkts_d_no_skb;
unsigned long pkts_d_not_ready;
unsigned long pkts_d_metadata;
unsigned long pkts_d_meta_srcport;
unsigned long pkts_d_meta_dstport;
unsigned long pkts_d_invalid_size;
} psample_stats_t;
static psample_stats_t g_psample_stats = {0};
typedef struct psample_meta_s {
int trunc_size;
int src_ifindex;
int dst_ifindex;
int sample_rate;
} psample_meta_t;
static psample_netif_t*
psample_netif_lookup_by_port(int unit, int port)
{
struct list_head *list;
psample_netif_t *psample_netif = NULL;
unsigned long flags;
/* look for port from list of available net_devices */
spin_lock_irqsave(&g_psample_info.lock, flags);
list_for_each(list, &g_psample_info.netif_list) {
psample_netif = (psample_netif_t*)list;
if (psample_netif->port == port) {
spin_unlock_irqrestore(&g_psample_info.lock, flags);
return psample_netif;
}
}
spin_unlock_irqrestore(&g_psample_info.lock, flags);
return (NULL);
}
static int
psample_info_get (int unit, psample_info_t *psample_info)
{
int rv = 0;
if (!psample_info) {
gprintk("%s: psample_info is NULL\n", __func__);
return (-1);
}
/* get hw info */
rv = bkn_hw_info_get(unit, &psample_info->hw);
if (rv < 0) {
gprintk("%s: failed to get hw info\n", __func__);
return (-1);
}
PSAMPLE_CB_DBG_PRINT("%s: DCB type %d\n",
__func__, psample_info->hw.dcb_type);
return (0);
}
static int
psample_meta_srcport_get(uint8_t *pkt, void *pkt_meta)
{
int srcport = 0;
uint32_t *metadata = (uint32_t*)pkt_meta;
switch(g_psample_info.hw.dcb_type) {
case 36: /* TD3 */
case 38: /* TH3 */
break;
case 32: /* TH1/TH2 */
case 26: /* TD2 */
case 23: /* HX4 */
metadata += SOC_DCB32_HG_OFFSET;
break;
default:
break;
}
if (SOC_HIGIG2_START(metadata) == SOC_HIGIG2_SOP)
{
srcport = SOC_HIGIG2_SRCPORT(metadata);
}
else if (SOC_HIGIG_START(metadata) == SOC_HIGIG_SOP)
{
srcport = SOC_HIGIG_SRCPORT(metadata);
}
else
{
PSAMPLE_CB_DBG_PRINT("%s: Could not detect metadata sop type: 0x%02x (w[0]: 0x%04x)\n", __func__,
SOC_HIGIG_START(metadata), metadata[0]);
return -1;
}
return srcport;
}
static int
psample_meta_dstport_get(uint8_t *pkt, void *pkt_meta)
{
int dstport = 0;
uint32_t *metadata = (uint32_t*)pkt_meta;
switch(g_psample_info.hw.dcb_type) {
case 36: /* TD3 */
case 38: /* TH3 */
break;
case 32: /* TH1/TH2 */
case 26: /* TD2 */
case 23: /* HX4 */
metadata += SOC_DCB32_HG_OFFSET;
break;
default:
break;
}
if (SOC_HIGIG2_START(metadata) == SOC_HIGIG2_SOP)
{
dstport = SOC_HIGIG2_DSTPORT(metadata);
}
else if (SOC_HIGIG_START(metadata) == SOC_HIGIG_SOP)
{
dstport = SOC_HIGIG_DSTPORT(metadata);
}
else
{
PSAMPLE_CB_DBG_PRINT("%s: Could not detect metadata sop type: 0x%02x (w[0]: 0x%04x)\n", __func__,
SOC_HIGIG_START(metadata), metadata[0]);
return (-1);
}
return dstport;
}
static int
psample_meta_sample_reason(uint8_t *pkt, void *pkt_meta)
{
uint32_t *metadata = (uint32_t*)pkt_meta;
uint32_t reason = 0;
uint32_t reason_hi = 0;
uint32_t sample_rx_reason_mask = 0;
/* Sample Pkt reason code (bcmRxReasonSampleSource) */
switch(g_psample_info.hw.dcb_type) {
case 36: /* TD3 */
case 38: /* TH3 */
reason_hi = *(metadata + 4);
reason = *(metadata + 5);
sample_rx_reason_mask = (1 << 3);
break;
case 32: /* TH1/TH2 */
case 26: /* TD2 */
case 23: /* HX4 */
default:
reason_hi = *(metadata + 2);
reason = *(metadata + 3);
sample_rx_reason_mask = (1 << 5);
break;
}
PSAMPLE_CB_DBG_PRINT("%s: DCB%d sample_rx_reason_mask: 0x%08x, reason: 0x%08x, reason_hi: 0x%08x\n",
__func__, g_psample_info.hw.dcb_type, sample_rx_reason_mask, reason, reason_hi);
/* Check if only sample reason code is set.
* If only sample reason code, then consume pkt.
* If other reason codes exist, then pkt should be
* passed through to Linux network stack.
*/
if ((reason & ~sample_rx_reason_mask) || reason_hi) {
return 0; /* multiple reasons set, pass through */
}
/* only sample rx reason set, consume pkt */
return (1);
}
static int
psample_meta_get(int unit, uint8_t *pkt, void *pkt_meta, psample_meta_t *sflow_meta)
{
int srcport, dstport;
int src_ifindex = 0;
int dst_ifindex = 0;
int sample_rate = PSAMPLE_RATE_DFLT;
int sample_size = PSAMPLE_SIZE_DFLT;
psample_netif_t *psample_netif = NULL;
#ifdef PSAMPLE_CB_DBG
if (debug & 0x1) {
int i=0;
uint8_t *meta = (uint8_t*)pkt_meta;
PSAMPLE_CB_DBG_PRINT("%s: psample pkt metadata\n", __func__);
for (i=0; i<64; i+=16) {
PSAMPLE_CB_DBG_PRINT("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
meta[i+0], meta[i+1], meta[i+2], meta[i+3], meta[i+4], meta[i+5], meta[i+6], meta[i+7],
meta[i+8], meta[i+9], meta[i+10], meta[i+11], meta[i+12], meta[i+13], meta[i+14], meta[i+15]);
}
}
#endif
/* parse pkt metadata for src and dst ports */
srcport = psample_meta_srcport_get(pkt, pkt_meta);
dstport = psample_meta_dstport_get(pkt, pkt_meta);
if ((srcport == -1) || (dstport == -1)) {
gprintk("%s: invalid srcport %d or dstport %d\n", __func__, srcport, dstport);
return (-1);
}
/* find src port netif (no need to lookup CPU port) */
if (srcport != 0) {
if ((psample_netif = psample_netif_lookup_by_port(unit, srcport))) {
src_ifindex = psample_netif->dev->ifindex;
sample_rate = psample_netif->sample_rate;
sample_size = psample_netif->sample_size;
} else {
g_psample_stats.pkts_d_meta_srcport++;
PSAMPLE_CB_DBG_PRINT("%s: could not find srcport(%d)\n", __func__, srcport);
}
}
/* find dst port netif (no need to lookup CPU port) */
if (dstport != 0) {
if ((psample_netif = psample_netif_lookup_by_port(unit, dstport))) {
dst_ifindex = psample_netif->dev->ifindex;
} else {
g_psample_stats.pkts_d_meta_dstport++;
PSAMPLE_CB_DBG_PRINT("%s: could not find dstport(%d)\n", __func__, dstport);
}
}
PSAMPLE_CB_DBG_PRINT("%s: srcport %d, dstport %d, src_ifindex %d, dst_ifindex %d, trunc_size %d, sample_rate %d\n",
__func__, srcport, dstport, src_ifindex, dst_ifindex, sample_size, sample_rate);
sflow_meta->src_ifindex = src_ifindex;
sflow_meta->dst_ifindex = dst_ifindex;
sflow_meta->trunc_size = sample_size;
sflow_meta->sample_rate = sample_rate;
return (0);
}
int
psample_filter_cb(uint8_t * pkt, int size, int dev_no, void *pkt_meta,
int chan, kcom_filter_t *kf)
{
struct psample_group *group;
psample_meta_t meta;
struct sk_buff skb;
int rv = 0;
static int info_get = 0;
if (!info_get) {
rv = psample_info_get (dev_no, &g_psample_info);
if (rv < 0) {
gprintk("%s: failed to get psample info\n", __func__);
goto PSAMPLE_FILTER_CB_PKT_HANDLED;
}
info_get = 1;
}
PSAMPLE_CB_DBG_PRINT("%s: pkt size %d, kf->dest_id %d, kf->cb_user_data %d\n",
__func__, size, kf->dest_id, kf->cb_user_data);
g_psample_stats.pkts_f_psample_cb++;
/* get psample group info. psample genetlink group ID passed in kf->dest_id */
group = psample_group_get(g_psample_info.netns, kf->dest_id);
if (!group) {
gprintk("%s: Could not find psample genetlink group %d\n", __func__, kf->cb_user_data);
g_psample_stats.pkts_d_no_group++;
goto PSAMPLE_FILTER_CB_PKT_HANDLED;
}
/* get psample metadata */
rv = psample_meta_get(dev_no, pkt, pkt_meta, &meta);
if (rv < 0) {
gprintk("%s: Could not parse pkt metadata\n", __func__);
g_psample_stats.pkts_d_metadata++;
goto PSAMPLE_FILTER_CB_PKT_HANDLED;
}
/* Adjust original pkt size to remove 4B FCS */
if (size < FCS_SZ) {
g_psample_stats.pkts_d_invalid_size++;
goto PSAMPLE_FILTER_CB_PKT_HANDLED;
} else {
size -= FCS_SZ;
}
/* Account for padding in libnl used by psample */
if (meta.trunc_size >= size) {
meta.trunc_size = size - PSAMPLE_NLA_PADDING;
}
PSAMPLE_CB_DBG_PRINT("%s: group 0x%x, trunc_size %d, src_ifdx %d, dst_ifdx %d, sample_rate %d\n",
__func__, group->group_num, meta.trunc_size, meta.src_ifindex, meta.dst_ifindex, meta.sample_rate);
/* drop if configured sample rate is 0 */
if (meta.sample_rate > 0) {
/* setup skb to point to pkt */
memset(&skb, 0, sizeof(struct sk_buff));
skb.len = size;
skb.data = pkt;
psample_sample_packet(group,
&skb,
meta.trunc_size,
meta.src_ifindex,
meta.dst_ifindex,
meta.sample_rate);
g_psample_stats.pkts_f_psample_mod++;
} else {
g_psample_stats.pkts_d_sampling_disabled++;
}
PSAMPLE_FILTER_CB_PKT_HANDLED:
/* if sample reason only, consume pkt. else pass through */
rv = psample_meta_sample_reason(pkt, pkt_meta);
if (rv) {
g_psample_stats.pkts_f_handled++;
} else {
g_psample_stats.pkts_f_pass_through++;
}
return rv;
}
int
psample_netif_create_cb(int unit, kcom_netif_t *netif, struct net_device *dev)
{
int found;
struct list_head *list;
psample_netif_t *psample_netif, *lpsample_netif;
unsigned long flags;
if ((psample_netif = kmalloc(sizeof(psample_netif_t), GFP_KERNEL)) == NULL) {
gprintk("%s: failed to alloc psample mem for netif '%s'\n",
__func__, dev->name);
return (-1);
}
spin_lock_irqsave(&g_psample_info.lock, flags);
psample_netif->dev = dev;
psample_netif->id = netif->id;
psample_netif->port = netif->port;
psample_netif->vlan = netif->vlan;
psample_netif->qnum = netif->qnum;
psample_netif->sample_rate = PSAMPLE_RATE_DFLT;
psample_netif->sample_size = PSAMPLE_SIZE_DFLT;
/* insert netif sorted by ID similar to bkn_knet_netif_create() */
found = 0;
list_for_each(list, &g_psample_info.netif_list) {
lpsample_netif = (psample_netif_t*)list;
if (netif->id < lpsample_netif->id) {
found = 1;
break;
}
}
if (found) {
/* Replace previously removed interface */
list_add_tail(&psample_netif->list, &lpsample_netif->list);
} else {
/* No holes - add to end of list */
list_add_tail(&psample_netif->list, &g_psample_info.netif_list);
}
spin_unlock_irqrestore(&g_psample_info.lock, flags);
PSAMPLE_CB_DBG_PRINT("%s: added psample netif '%s'\n", __func__, dev->name);
return (0);
}
int
psample_netif_destroy_cb(int unit, kcom_netif_t *netif, struct net_device *dev)
{
int found;
struct list_head *list;
psample_netif_t *psample_netif;
unsigned long flags;
if (!netif || !dev) {
gprintk("%s: netif or net_device is NULL\n", __func__);
return (-1);
}
spin_lock_irqsave(&g_psample_info.lock, flags);
list_for_each(list, &g_psample_info.netif_list) {
psample_netif = (psample_netif_t*)list;
if (netif->id == psample_netif->id) {
found = 1;
list_del(&psample_netif->list);
PSAMPLE_CB_DBG_PRINT("%s: removing psample netif '%s'\n", __func__, dev->name);
kfree(psample_netif);
break;
}
}
spin_unlock_irqrestore(&g_psample_info.lock, flags);
if (!found) {
gprintk("%s: netif ID %d not found!\n", __func__, netif->id);
return (-1);
}
return (0);
}
/*
* psample rate Proc Read Entry
*/
static int
psample_proc_rate_show(struct seq_file *m, void *v)
{
struct list_head *list;
psample_netif_t *psample_netif;
unsigned long flags;
spin_lock_irqsave(&g_psample_info.lock, flags);
list_for_each(list, &g_psample_info.netif_list) {
psample_netif = (psample_netif_t*)list;
seq_printf(m, " %-14s %d\n", psample_netif->dev->name, psample_netif->sample_rate);
}
spin_unlock_irqrestore(&g_psample_info.lock, flags);
return 0;
}
static int
psample_proc_rate_open(struct inode * inode, struct file * file)
{
return single_open(file, psample_proc_rate_show, NULL);
}
/*
* psample rate Proc Write Entry
*
* Syntax:
* <netif>=<pkt sample rate>
*
* Where <netif> is a virtual network interface name.
*
* Examples:
* eth4=1000
*/
static ssize_t
psample_proc_rate_write(struct file *file, const char *buf,
size_t count, loff_t *loff)
{
int found;
struct list_head *list;
psample_netif_t *psample_netif;
char sample_str[40], *ptr, *newline;
unsigned long flags;
if (count > sizeof(sample_str)) {
count = sizeof(sample_str) - 1;
sample_str[count] = '\0';
}
if (copy_from_user(sample_str, buf, count)) {
return -EFAULT;
}
sample_str[count] = 0;
newline = strchr(sample_str, '\n');
if (newline) {
/* Chop off the trailing newline */
*newline = '\0';
}
if ((ptr = strchr(sample_str, '=')) == NULL &&
(ptr = strchr(sample_str, ':')) == NULL) {
gprintk("Error: Pkt sample rate syntax not recognized: '%s'\n", sample_str);
return count;
}
*ptr++ = 0;
spin_lock_irqsave(&g_psample_info.lock, flags);
found = 0;
list_for_each(list, &g_psample_info.netif_list) {
psample_netif = (psample_netif_t*)list;
if (strcmp(psample_netif->dev->name, sample_str) == 0) {
psample_netif->sample_rate = simple_strtol(ptr, NULL, 10);
// TODO MLI@BRCM - check valid sample rate
found = 1;
break;
}
}
spin_unlock_irqrestore(&g_psample_info.lock, flags);
if (!found) {
gprintk("Warning: Failed setting psample rate on unknown network interface: '%s'\n", sample_str);
}
return count;
}
struct file_operations psample_proc_rate_file_ops = {
owner: THIS_MODULE,
open: psample_proc_rate_open,
read: seq_read,
llseek: seq_lseek,
write: psample_proc_rate_write,
release: single_release,
};
/*
* psample size Proc Read Entry
*/
static int
psample_proc_size_show(struct seq_file *m, void *v)
{
struct list_head *list;
psample_netif_t *psample_netif;
unsigned long flags;
spin_lock_irqsave(&g_psample_info.lock, flags);
list_for_each(list, &g_psample_info.netif_list) {
psample_netif = (psample_netif_t*)list;
seq_printf(m, " %-14s %d\n", psample_netif->dev->name, psample_netif->sample_size);
}
spin_unlock_irqrestore(&g_psample_info.lock, flags);
return 0;
}
static int
psample_proc_size_open(struct inode * inode, struct file * file)
{
return single_open(file, psample_proc_size_show, NULL);
}
/*
* psample size Proc Write Entry
*
* Syntax:
* <netif>=<pkt sample size in bytes>
*
* Where <netif> is a virtual network interface name.
*
* Examples:
* eth4=128
*/
static ssize_t
psample_proc_size_write(struct file *file, const char *buf,
size_t count, loff_t *loff)
{
int found;
struct list_head *list;
psample_netif_t *psample_netif;
char sample_str[40], *ptr, *newline;
unsigned long flags;
if (count > sizeof(sample_str)) {
count = sizeof(sample_str) - 1;
sample_str[count] = '\0';
}
if (copy_from_user(sample_str, buf, count)) {
return -EFAULT;
}
sample_str[count] = 0;
newline = strchr(sample_str, '\n');
if (newline) {
/* Chop off the trailing newline */
*newline = '\0';
}
if ((ptr = strchr(sample_str, '=')) == NULL &&
(ptr = strchr(sample_str, ':')) == NULL) {
gprintk("Error: Pkt sample size syntax not recognized: '%s'\n", sample_str);
return count;
}
*ptr++ = 0;
spin_lock_irqsave(&g_psample_info.lock, flags);
found = 0;
list_for_each(list, &g_psample_info.netif_list) {
psample_netif = (psample_netif_t*)list;
if (strcmp(psample_netif->dev->name, sample_str) == 0) {
psample_netif->sample_size = simple_strtol(ptr, NULL, 10);
// TODO MLI@BRCM - check valid sample size
found = 1;
break;
}
}
spin_unlock_irqrestore(&g_psample_info.lock, flags);
if (!found) {
gprintk("Warning: Failed setting psample size on unknown network interface: '%s'\n", sample_str);
}
return count;
}
struct file_operations psample_proc_size_file_ops = {
owner: THIS_MODULE,
open: psample_proc_size_open,
read: seq_read,
llseek: seq_lseek,
write: psample_proc_size_write,
release: single_release,
};
/*
* psample debug Proc Read Entry
*/
static int
psample_proc_debug_show(struct seq_file *m, void *v)
{
seq_printf(m, "BCM KNET %s Callback Config\n", PSAMPLE_CB_NAME);
seq_printf(m, " debug: 0x%x\n", debug);
seq_printf(m, " cmic_type: %d\n", g_psample_info.hw.cmic_type);
seq_printf(m, " dcb_type: %d\n", g_psample_info.hw.dcb_type);
seq_printf(m, " dcb_size: %d\n", g_psample_info.hw.dcb_size);
seq_printf(m, " pkt_hdr_size: %d\n", g_psample_info.hw.pkt_hdr_size);
seq_printf(m, " cdma_channels: %d\n", g_psample_info.hw.cdma_channels);
return 0;
}
static int
psample_proc_debug_open(struct inode * inode, struct file * file)
{
return single_open(file, psample_proc_debug_show, NULL);
}
/*
* psample debug Proc Write Entry
*
* Syntax:
* debug=<mask>
*
* Where <mask> corresponds to the debug module parameter.
*
* Examples:
* debug=0x1
*/
static ssize_t
psample_proc_debug_write(struct file *file, const char *buf,
size_t count, loff_t *loff)
{
char debug_str[40];
char *ptr;
if (count > sizeof(debug_str)) {
count = sizeof(debug_str) - 1;
debug_str[count] = '\0';
}
if (copy_from_user(debug_str, buf, count)) {
return -EFAULT;
}
if ((ptr = strstr(debug_str, "debug=")) != NULL) {
ptr += 6;
debug = simple_strtol(ptr, NULL, 0);
} else {
gprintk("Warning: unknown configuration setting\n");
}
return count;
}
struct file_operations psample_proc_debug_file_ops = {
owner: THIS_MODULE,
open: psample_proc_debug_open,
read: seq_read,
llseek: seq_lseek,
write: psample_proc_debug_write,
release: single_release,
};
static int
psample_proc_stats_show(struct seq_file *m, void *v)
{
seq_printf(m, "BCM KNET %s Callback Stats\n", PSAMPLE_CB_NAME);
seq_printf(m, " DCB type %d\n", g_psample_info.hw.dcb_type);
seq_printf(m, " pkts filter psample cb %10lu\n", g_psample_stats.pkts_f_psample_cb);
seq_printf(m, " pkts sent to psample module %10lu\n", g_psample_stats.pkts_f_psample_mod);
seq_printf(m, " pkts handled by psample %10lu\n", g_psample_stats.pkts_f_handled);
seq_printf(m, " pkts pass through %10lu\n", g_psample_stats.pkts_f_pass_through);
seq_printf(m, " pkts drop no psample group %10lu\n", g_psample_stats.pkts_d_no_group);
seq_printf(m, " pkts drop sampling disabled %10lu\n", g_psample_stats.pkts_d_sampling_disabled);
seq_printf(m, " pkts drop no skb %10lu\n", g_psample_stats.pkts_d_no_skb);
seq_printf(m, " pkts drop psample not ready %10lu\n", g_psample_stats.pkts_d_not_ready);
seq_printf(m, " pkts drop metadata parse error %10lu\n", g_psample_stats.pkts_d_metadata);
seq_printf(m, " pkts with invalid src port %10lu\n", g_psample_stats.pkts_d_meta_srcport);
seq_printf(m, " pkts with invalid dst port %10lu\n", g_psample_stats.pkts_d_meta_dstport);
seq_printf(m, " pkts with invalid orig pkt sz %10lu\n", g_psample_stats.pkts_d_invalid_size);
return 0;
}
static int
psample_proc_stats_open(struct inode * inode, struct file * file)
{
return single_open(file, psample_proc_stats_show, NULL);
}
struct file_operations psample_proc_stats_file_ops = {
owner: THIS_MODULE,
open: psample_proc_stats_open,
read: seq_read,
llseek: seq_lseek,
write: NULL,
release: single_release,
};
int psample_cleanup(void)
{
remove_proc_entry("stats", psample_proc_root);
remove_proc_entry("rate", psample_proc_root);
remove_proc_entry("size", psample_proc_root);
remove_proc_entry("debug", psample_proc_root);
return 0;
}
int psample_init(void)
{
#define PROCFS_MAX_PATH 1024
char psample_procfs_path[PROCFS_MAX_PATH];
struct proc_dir_entry *entry;
/* create procfs for psample */
snprintf(psample_procfs_path, PROCFS_MAX_PATH, "bcm/knet-cb");
proc_mkdir(psample_procfs_path, NULL);
snprintf(psample_procfs_path, PROCFS_MAX_PATH, "%s/%s", psample_procfs_path, PSAMPLE_CB_NAME);
psample_proc_root = proc_mkdir(psample_procfs_path, NULL);
/* create procfs for psample stats */
PROC_CREATE(entry, "stats", 0666, psample_proc_root, &psample_proc_stats_file_ops);
if (entry == NULL) {
gprintk("%s: Unable to create procfs entry '/procfs/%s/stats'\n", __func__, psample_procfs_path);
return -1;
}
/* create procfs for setting sample rates */
PROC_CREATE(entry, "rate", 0666, psample_proc_root, &psample_proc_rate_file_ops);
if (entry == NULL) {
gprintk("%s: Unable to create procfs entry '/procfs/%s/rate'\n", __func__, psample_procfs_path);
return -1;
}
/* create procfs for setting sample size */
PROC_CREATE(entry, "size", 0666, psample_proc_root, &psample_proc_size_file_ops);
if (entry == NULL) {
gprintk("%s: Unable to create procfs entry '/procfs/%s/size'\n", __func__, psample_procfs_path);
return -1;
}
/* create procfs for debug log */
PROC_CREATE(entry, "debug", 0666, psample_proc_root, &psample_proc_debug_file_ops);
if (entry == NULL) {
gprintk("%s: Unable to create procfs entry '/procfs/%s/debug'\n", __func__, psample_procfs_path);
return -1;
}
/* clear data structs */
memset(&g_psample_stats, 0, sizeof(psample_stats_t));
memset(&g_psample_info, 0, sizeof(psample_info_t));
/* setup psample_info struct */
INIT_LIST_HEAD(&g_psample_info.netif_list);
spin_lock_init(&g_psample_info.lock);
/* get net namespace */
g_psample_info.netns = get_net_ns_by_pid(current->pid);
if (!g_psample_info.netns) {
gprintk("%s: Could not get network namespace for pid %d\n", __func__, current->pid);
return (-1);
}
PSAMPLE_CB_DBG_PRINT("%s: current->pid %d, netns 0x%p, sample_size %d\n", __func__,
current->pid, g_psample_info.netns, psample_size);
return 0;
}

View File

@ -0,0 +1,58 @@
/*
* Copyright 2017 Broadcom
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2, as
* published by the Free Software Foundation (the "GPL").
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License version 2 (GPLv2) for more details.
*
* You should have received a copy of the GNU General Public License
* version 2 (GPLv2) along with this source code.
*/
/*
* $Id: psample_cb.h $
* $Copyright: (c) 2019 Broadcom Corp.
* All Rights Reserved.$
*/
#ifndef __PSAMPLE_CB_H__
#define __PSAMPLE_CB_H__
#include <gmodule.h>
#include <kcom.h>
#include <linux/netdevice.h>
#define PSAMPLE_CB_NAME "psample"
extern int
psample_init(void);
extern int
psample_cleanup(void);
extern int
psample_filter_cb(uint8_t * pkt, int size, int dev_no, void *pkt_meta,
int chan, kcom_filter_t *kf);
/* psample data per interface */
typedef struct {
struct list_head list;
struct net_device *dev;
uint16 id;
uint8 port;
uint16 vlan;
uint16 qnum;
uint32 sample_rate;
uint32 sample_size;
} psample_netif_t;
extern int
psample_netif_create_cb(int unit, kcom_netif_t *netif, struct net_device *dev);
extern int
psample_netif_destroy_cb(int unit, kcom_netif_t *netif, struct net_device *dev);
#endif /* __PSAMPLE_CB_H__ */

View File

@ -0,0 +1,64 @@
#
# Copyright 2017 Broadcom
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License, version 2, as
# published by the Free Software Foundation (the "GPL").
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License version 2 (GPLv2) for more details.
#
# You should have received a copy of the GNU General Public License
# version 2 (GPLv2) along with this source code.
#
# -*- Makefile -*-
# $Id: Makefile,v 1.3 Broadcom SDK $
# $Copyright: (c) 2005 Broadcom Corp.
# All Rights Reserved.$
#
LOCALDIR = systems/linux/kernel/modules/psample
include ${SDK}/make/Make.config
LIBS = $(LIBDIR)/libkern.a
ifeq ($(kernel_version),2_4)
MODULE = $(LIBDIR)/psample.o
else
KERNEL_MODULE_DIR = kernel_module
THIS_MOD_NAME := psample
MODULE = $(LIBDIR)/$(THIS_MOD_NAME).o
KMODULE = $(LIBDIR)/$(THIS_MOD_NAME).ko
build: $(MODULE) $(KMODULE)
endif
KBUILD_EXTRA_SYMBOLS := ${BLDDIR}/../bcm-knet/kernel_module/Module.symvers
# BCM Network Device
$(MODULE): $(BLDDIR)/.tree $(BOBJS) $(LIBS)
$(LD) $(MODULE_LDFLAGS) -r -d $(BOBJS) $(LIBS) -o $@
ifneq ($(kernel_version),2_4)
$(KMODULE): $(MODULE)
rm -fr $(BLDDIR)/$(KERNEL_MODULE_DIR)
mkdir $(BLDDIR)/$(KERNEL_MODULE_DIR)
cp ${SDK}/make/Makefile.linux-kmodule $(BLDDIR)/$(KERNEL_MODULE_DIR)/Makefile
cat ${KBUILD_EXTRA_SYMBOLS} > $(BLDDIR)/$(KERNEL_MODULE_DIR)/Module.symvers
MOD_NAME=$(THIS_MOD_NAME) $(MAKE) -C $(BLDDIR)/$(KERNEL_MODULE_DIR) $(THIS_MOD_NAME).ko
endif
# Make.depend is before clean:: so that Make.depend's clean:: runs first.
include ${SDK}/make/Make.depend
clean::
$(RM) $(BLDDIR)/version.c $(BLDDIR)/version.o
$(RM) $(BOBJS) $(MODULE)
ifneq ($(kernel_version),2_4)
.PHONY: build
endif

View File

@ -0,0 +1,302 @@
/*
* net/psample/psample.c - Netlink channel for packet sampling
* Copyright (c) 2017 Yotam Gigi <yotamg@mellanox.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <gmodule.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/module.h>
#include <net/net_namespace.h>
#include <net/sock.h>
#include <net/netlink.h>
#include <net/genetlink.h>
#include <net/psample.h>
#include <linux/spinlock.h>
#define PSAMPLE_MAX_PACKET_SIZE 0xffff
static LIST_HEAD(psample_groups_list);
static DEFINE_SPINLOCK(psample_groups_lock);
/* multicast groups */
enum psample_nl_multicast_groups {
PSAMPLE_NL_MCGRP_CONFIG,
PSAMPLE_NL_MCGRP_SAMPLE,
};
static const struct genl_multicast_group psample_nl_mcgrps[] = {
[PSAMPLE_NL_MCGRP_CONFIG] = { .name = PSAMPLE_NL_MCGRP_CONFIG_NAME },
[PSAMPLE_NL_MCGRP_SAMPLE] = { .name = PSAMPLE_NL_MCGRP_SAMPLE_NAME },
};
static struct genl_family psample_nl_family __ro_after_init;
static int psample_group_nl_fill(struct sk_buff *msg,
struct psample_group *group,
enum psample_command cmd, u32 portid, u32 seq,
int flags)
{
void *hdr;
int ret;
hdr = genlmsg_put(msg, portid, seq, &psample_nl_family, flags, cmd);
if (!hdr)
return -EMSGSIZE;
ret = nla_put_u32(msg, PSAMPLE_ATTR_SAMPLE_GROUP, group->group_num);
if (ret < 0)
goto error;
ret = nla_put_u32(msg, PSAMPLE_ATTR_GROUP_REFCOUNT, group->refcount);
if (ret < 0)
goto error;
ret = nla_put_u32(msg, PSAMPLE_ATTR_GROUP_SEQ, group->seq);
if (ret < 0)
goto error;
genlmsg_end(msg, hdr);
return 0;
error:
genlmsg_cancel(msg, hdr);
return -EMSGSIZE;
}
static int psample_nl_cmd_get_group_dumpit(struct sk_buff *msg,
struct netlink_callback *cb)
{
struct psample_group *group;
int start = cb->args[0];
int idx = 0;
int err;
spin_lock(&psample_groups_lock);
list_for_each_entry(group, &psample_groups_list, list) {
if (!net_eq(group->net, sock_net(msg->sk)))
continue;
if (idx < start) {
idx++;
continue;
}
err = psample_group_nl_fill(msg, group, PSAMPLE_CMD_NEW_GROUP,
NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq, NLM_F_MULTI);
if (err)
break;
idx++;
}
spin_unlock(&psample_groups_lock);
cb->args[0] = idx;
return msg->len;
}
static const struct genl_ops psample_nl_ops[] = {
{
.cmd = PSAMPLE_CMD_GET_GROUP,
.dumpit = psample_nl_cmd_get_group_dumpit,
/* can be retrieved by unprivileged users */
}
};
static struct genl_family psample_nl_family __ro_after_init = {
.name = PSAMPLE_GENL_NAME,
.version = PSAMPLE_GENL_VERSION,
.maxattr = PSAMPLE_ATTR_MAX,
.netnsok = true,
.module = THIS_MODULE,
.mcgrps = psample_nl_mcgrps,
.ops = psample_nl_ops,
.n_ops = ARRAY_SIZE(psample_nl_ops),
.n_mcgrps = ARRAY_SIZE(psample_nl_mcgrps),
};
static void psample_group_notify(struct psample_group *group,
enum psample_command cmd)
{
struct sk_buff *msg;
int err;
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_ATOMIC);
if (!msg)
return;
err = psample_group_nl_fill(msg, group, cmd, 0, 0, NLM_F_MULTI);
if (!err)
genlmsg_multicast_netns(&psample_nl_family, group->net, msg, 0,
PSAMPLE_NL_MCGRP_CONFIG, GFP_ATOMIC);
else
nlmsg_free(msg);
}
static struct psample_group *psample_group_create(struct net *net,
u32 group_num)
{
struct psample_group *group;
group = kzalloc(sizeof(*group), GFP_ATOMIC);
if (!group)
return NULL;
group->net = net;
group->group_num = group_num;
list_add_tail(&group->list, &psample_groups_list);
psample_group_notify(group, PSAMPLE_CMD_NEW_GROUP);
return group;
}
static void psample_group_destroy(struct psample_group *group)
{
psample_group_notify(group, PSAMPLE_CMD_DEL_GROUP);
list_del(&group->list);
kfree(group);
}
static struct psample_group *
psample_group_lookup(struct net *net, u32 group_num)
{
struct psample_group *group;
list_for_each_entry(group, &psample_groups_list, list)
if ((group->group_num == group_num) && (group->net == net))
return group;
return NULL;
}
struct psample_group *psample_group_get(struct net *net, u32 group_num)
{
struct psample_group *group;
spin_lock(&psample_groups_lock);
group = psample_group_lookup(net, group_num);
if (!group) {
group = psample_group_create(net, group_num);
if (!group)
goto out;
}
group->refcount++;
out:
spin_unlock(&psample_groups_lock);
return group;
}
EXPORT_SYMBOL_GPL(psample_group_get);
void psample_group_put(struct psample_group *group)
{
spin_lock(&psample_groups_lock);
if (--group->refcount == 0)
psample_group_destroy(group);
spin_unlock(&psample_groups_lock);
}
EXPORT_SYMBOL_GPL(psample_group_put);
void psample_sample_packet(struct psample_group *group, struct sk_buff *skb,
u32 trunc_size, int in_ifindex, int out_ifindex,
u32 sample_rate)
{
struct sk_buff *nl_skb;
int data_len;
int meta_len;
void *data;
int ret;
meta_len = (in_ifindex ? nla_total_size(sizeof(u16)) : 0) +
(out_ifindex ? nla_total_size(sizeof(u16)) : 0) +
nla_total_size(sizeof(u32)) + /* sample_rate */
nla_total_size(sizeof(u32)) + /* orig_size */
nla_total_size(sizeof(u32)) + /* group_num */
nla_total_size(sizeof(u32)); /* seq */
data_len = min(skb->len, trunc_size);
if (meta_len + nla_total_size(data_len) > PSAMPLE_MAX_PACKET_SIZE)
data_len = PSAMPLE_MAX_PACKET_SIZE - meta_len - NLA_HDRLEN
- NLA_ALIGNTO;
nl_skb = genlmsg_new(meta_len + data_len, GFP_ATOMIC);
if (unlikely(!nl_skb))
return;
data = genlmsg_put(nl_skb, 0, 0, &psample_nl_family, 0,
PSAMPLE_CMD_SAMPLE);
if (unlikely(!data))
goto error;
if (in_ifindex) {
ret = nla_put_u16(nl_skb, PSAMPLE_ATTR_IIFINDEX, in_ifindex);
if (unlikely(ret < 0))
goto error;
}
if (out_ifindex) {
ret = nla_put_u16(nl_skb, PSAMPLE_ATTR_OIFINDEX, out_ifindex);
if (unlikely(ret < 0))
goto error;
}
ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_SAMPLE_RATE, sample_rate);
if (unlikely(ret < 0))
goto error;
ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_ORIGSIZE, skb->len);
if (unlikely(ret < 0))
goto error;
ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_SAMPLE_GROUP, group->group_num);
if (unlikely(ret < 0))
goto error;
ret = nla_put_u32(nl_skb, PSAMPLE_ATTR_GROUP_SEQ, group->seq++);
if (unlikely(ret < 0))
goto error;
if (data_len) {
int nla_len = nla_total_size(data_len);
struct nlattr *nla;
nla = (struct nlattr *)skb_put(nl_skb, nla_len);
nla->nla_type = PSAMPLE_ATTR_DATA;
nla->nla_len = nla_attr_size(data_len);
if (skb_copy_bits(skb, 0, nla_data(nla), data_len))
goto error;
}
genlmsg_end(nl_skb, data);
genlmsg_multicast_netns(&psample_nl_family, group->net, nl_skb, 0,
PSAMPLE_NL_MCGRP_SAMPLE, GFP_ATOMIC);
return;
error:
pr_err_ratelimited("Could not create psample log message\n");
nlmsg_free(nl_skb);
}
EXPORT_SYMBOL_GPL(psample_sample_packet);
static int __init psample_module_init(void)
{
return genl_register_family(&psample_nl_family);
}
static void __exit psample_module_exit(void)
{
genl_unregister_family(&psample_nl_family);
}
module_init(psample_module_init);
module_exit(psample_module_exit);
MODULE_AUTHOR("Yotam Gigi <yotamg@mellanox.com>");
MODULE_DESCRIPTION("netlink channel for packet sampling");
MODULE_LICENSE("GPL v2");

View File

@ -91,6 +91,9 @@ KNET_CB := $(DEST_DIR)/$(KNET_CB_LOCAL)
BCM_KNET_LOCAL :=linux-bcm-knet.$(KOBJ)
BCM_KNET=$(DEST_DIR)/$(BCM_KNET_LOCAL)
PSAMPLE_LOCAL := psample.$(KOBJ)
PSAMPLE := $(DEST_DIR)/$(PSAMPLE_LOCAL)
ifeq (,$(findstring DELIVER,$(MAKECMDGOALS)))
.DEFAULT_GOAL := all
all_targets := kernel_modules $(KERNEL_BDE) $(USER_BDE)
@ -126,6 +129,15 @@ all_targets +=$(LOCAL_TARGETS)
endif
endif
ifdef BUILD_PSAMPLE
all_targets += $(PSAMPLE)
ADD_TO_CFLAGS += -DPSAMPLE_SUPPORT
ifeq ($(NO_LOCAL_TARGETS),)
LOCAL_TARGETS +=$(patsubst %,../$(platform)/%,$(PSAMPLE_LOCAL))
all_targets +=$(LOCAL_TARGETS)
endif
endif
ADD_TO_CFLAGS += -I$(SDK)/systems/linux/kernel/modules/include
COND_KNET_LIBS = libuser.$(libext)
endif
@ -159,6 +171,10 @@ kernel_modules:
ifeq ($(BUILD_KNET),1)
$(MAKE) -j1 -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \
subdirs="shared bcm-knet" override-target=linux-$(platform) CFLAGS="$(CFLAGS)"
ifdef BUILD_PSAMPLE
$(MAKE) -j1 -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \
subdirs="psample" override-target=linux-$(platform) CFLAGS="$(CFLAGS)"
endif
ifdef BUILD_KNET_CB
$(MAKE) -j1 -C $(SDK)/systems/linux/kernel/modules kernel_version=$(kernel_version) \
subdirs="knet-cb" override-target=linux-$(platform) CFLAGS="$(CFLAGS)"
@ -178,6 +194,10 @@ $(BCM_KNET): $(KERN_BLDROOT)/linux-bcm-knet.$(KOBJ)
$(KNET_CB): $(KERN_BLDROOT)/linux-knet-cb.$(KOBJ)
$(OBJCOPY) --strip-debug $< $@
$(PSAMPLE): $(KERN_BLDROOT)/psample.$(KOBJ)
$(OBJCOPY) --strip-debug $< $@
ifeq ($(NO_LOCAL_TARGETS),)
$(foreach targ,$(LOCAL_TARGETS),$(eval $(call LOCAL_TARGET_DEF,$(targ))))
endif
@ -194,6 +214,7 @@ clean::
$(RM) $(KERN_BLDROOT)/linux-user-bde.$(KOBJ)
$(RM) $(KERN_BLDROOT)/linux-bcm-knet.$(KOBJ)
$(RM) $(KERN_BLDROOT)/linux-knet-cb.$(KOBJ)
$(RM) $(KERN_BLDROOT)/psample.$(KOBJ)
$(RM) $(LOCAL_TARGETS)
distclean:: clean

View File

@ -44,7 +44,7 @@ endif
export SDK
override kernel_version=4_4
override kernel_version=4_14
platform=iproc
IPROC_BUILD=1

View File

@ -11,12 +11,12 @@ else
FW_FROM_URL = n
endif
MLNX_SPC_FW_VERSION = 13.2000.2602
MLNX_SPC_FW_VERSION = 13.2000.2696
MLNX_SPC_FW_FILE = fw-SPC-rel-$(subst .,_,$(MLNX_SPC_FW_VERSION))-EVB.mfa
$(MLNX_SPC_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH)
$(MLNX_SPC_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC_FW_FILE)
MLNX_SPC2_FW_VERSION = 29.2000.2602
MLNX_SPC2_FW_VERSION = 29.2000.2696
MLNX_SPC2_FW_FILE = fw-SPC2-rel-$(subst .,_,$(MLNX_SPC2_FW_VERSION))-EVB.mfa
$(MLNX_SPC2_FW_FILE)_PATH = $(MLNX_FW_BASE_PATH)
$(MLNX_SPC2_FW_FILE)_URL = $(MLNX_FW_BASE_URL)/$(MLNX_SPC2_FW_FILE)

View File

@ -1,6 +1,6 @@
# Mellanox HW Management
MLNX_HW_MANAGEMENT_VERSION = 7.0000.2303
MLNX_HW_MANAGEMENT_VERSION = 7.0000.2308
export MLNX_HW_MANAGEMENT_VERSION

@ -1 +1 @@
Subproject commit 7c26a8f6a520b06663992afe874bc56b1fcd9311
Subproject commit 28d83cdb3565d3b0352cc718fe82a14cacd1d4a5

View File

@ -136,6 +136,26 @@ SFP_CHANNL_MON_WIDTH = 6
SFP_CHANNL_STATUS_OFFSET = 110
SFP_CHANNL_STATUS_WIDTH = 1
# identifier value of xSFP module which is in the first byte of the EEPROM
# if the identifier value falls into SFP_TYPE_CODE_LIST the module is treated as a SFP module and parsed according to 8472
# for QSFP_TYPE_CODE_LIST the module is treated as a QSFP module and parsed according to 8436/8636
# Originally the type (SFP/QSFP) of each module is determined according to the SKU dictionary
# where the type of each FP port is defined. The content of EEPROM is parsed according to its type.
# However, sometimes the SFP module can be fit in an adapter and then pluged into a QSFP port.
# In this case the EEPROM content is in format of SFP but parsed as QSFP, causing failure.
# To resolve that issue the type field of the xSFP module is also fetched so that we can know exectly what type the
# module is. Currently only the following types are recognized as SFP/QSFP module.
# Meanwhile, if the a module's identifier value can't be recognized, it will be parsed according to the SKU dictionary.
# This is because in the future it's possible that some new identifier value which is not regonized but backward compatible
# with the current format and by doing so it can be parsed as much as possible.
SFP_TYPE_CODE_LIST = [
'03' # SFP/SFP+/SFP28
]
QSFP_TYPE_CODE_LIST = [
'0d', # QSFP+ or later
'11' # QSFP28 or later
]
qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)',
'Length OM2(m)', 'Length OM1(m)',
'Length Cable Assembly(m)')
@ -206,7 +226,7 @@ class SFP(SfpBase):
self.index = sfp_index + 1
self.sfp_eeprom_path = "qsfp{}".format(self.index)
self.sfp_status_path = "qsfp{}_status".format(self.index)
self.sfp_type = sfp_type
self._detect_sfp_type(sfp_type)
self.dom_tx_disable_supported = False
self._dom_capability_detect()
self.sdk_handle = None
@ -293,6 +313,26 @@ class SFP(SfpBase):
return eeprom_raw
def _detect_sfp_type(self, sfp_type):
eeprom_raw = []
eeprom_raw = self._read_eeprom_specific_bytes(XCVR_TYPE_OFFSET, XCVR_TYPE_WIDTH)
if eeprom_raw:
if eeprom_raw[0] in SFP_TYPE_CODE_LIST:
self.sfp_type = SFP_TYPE
elif eeprom_raw[0] in QSFP_TYPE_CODE_LIST:
self.sfp_type = QSFP_TYPE
else:
# we don't regonize this identifier value, treat the xSFP module as the default type
self.sfp_type = sfp_type
logger.log_info("Identifier value of {} module {} is {} which isn't regonized and will be treated as default type ({})".format(
sfp_type, self.index, eeprom_raw[0], sfp_type
))
else:
# eeprom_raw being None indicates the module is not present.
# in this case we treat it as the default type according to the SKU
self.sfp_type = sfp_type
def _dom_capability_detect(self):
if not self.get_presence():
self.dom_supported = False
@ -303,7 +343,7 @@ class SFP(SfpBase):
self.calibration = 0
return
if self.sfp_type == "QSFP":
if self.sfp_type == QSFP_TYPE:
self.calibration = 1
sfpi_obj = sff8436InterfaceId()
if sfpi_obj is None:
@ -348,7 +388,7 @@ class SFP(SfpBase):
self.dom_tx_power_supported = False
self.calibration = 0
self.qsfp_page3_available = False
elif self.sfp_type == "SFP":
elif self.sfp_type == SFP_TYPE:
sfpi_obj = sff8472InterfaceId()
if sfpi_obj is None:
return None

@ -1 +1 @@
Subproject commit 925116eb63a5a9012dcc22a7a0682ada6e976380
Subproject commit d878245e364ce8d5edd08bbd7120c44c92362235

View File

@ -19,7 +19,6 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% :
fi
# build
patch -p1 < ../sx_kernel_makefile_sonic_build.patch
debuild -e KVERSION=$(KVERSION) -e KSRC_EXT=/lib/modules/$(KVERSION)/source/ -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS)

@ -1 +1 @@
Subproject commit 87f7a7911275285abc63c24ba39aa4af4c4b4678
Subproject commit c08b5bb3810fe7da2811622aa7003ac9cc95344b

View File

@ -1,18 +0,0 @@
diff --git a/makefile b/makefile
index f23f0ac..a16b2ce 100644
--- a/makefile
+++ b/makefile
@@ -93,10 +93,10 @@ V ?= 1
ifneq ($(findstring 3.10,$(KVERSION))$(findstring 3.13,$(KVERSION))$(findstring 3.14,$(KVERSION))$(findstring 3.16,$(KVERSION)),)
MLNX_LINUX_AUTOCONF_FILE = include/generated/autoconf.h
-MLNX_LINUX_EXTRA_INCLUDE_FILES = -include include/linux/kconfig.h
+MLNX_LINUX_EXTRA_INCLUDE_FILES = -include $(KSRC_EXT)/include/linux/kconfig.h
MLNX_LINUX_EXTRA_INCLUDE_FOLDERS = \
- -Iarch/$$(SRCARCH)/include/uapi \
- -Iinclude/uapi \
+ -I$(KSRC_EXT)/arch/$$(SRCARCH)/include/uapi \
+ -I$(KSRC_EXT)/include/uapi \
-Iarch/$$(SRCARCH)/include/generated/uapi \
-Iarch/$$(SRCARCH)/include/generated \
-Iinclude/generated/uapi

View File

@ -1,5 +1,5 @@
MLNX_SDK_BASE_PATH = $(PLATFORM_PATH)/sdk-src/sx-kernel/Switch-SDK-drivers/bin/
MLNX_SDK_VERSION = 4.3.2602
MLNX_SDK_VERSION = 4.3.2904
MLNX_SDK_ISSU_VERSION = 101
MLNX_SDK_DEB_VERSION = $(subst _,.,$(MLNX_SDK_VERSION))

View File

@ -2,7 +2,7 @@
DOCKER_BASE_STRETCH = docker-base-stretch.gz
$(DOCKER_BASE_STRETCH)_PATH = $(DOCKERS_PATH)/docker-base-stretch
$(DOCKER_BASE_STRETCH)_DEPENDS += $(SUPERVISOR)
$(DOCKER_BASE_STRETCH)_DEPENDS += $(SUPERVISOR) $(REDIS_TOOLS)
$(DOCKER_BASE_STRETCH)_DEPENDS += $(SOCAT)
GDB = gdb

14
rules/monit.mk Normal file
View File

@ -0,0 +1,14 @@
# monit package
MONIT_VERSION = 5.20.0-6
export MONIT_VERSION
MONIT = monit_$(MONIT_VERSION)_$(CONFIGURED_ARCH).deb
$(MONIT)_SRC_PATH = $(SRC_PATH)/monit
SONIC_MAKE_DEBS += $(MONIT)
SONIC_STRETCH_DEBS += $(MONIT)
MONIT_DBG = monit-dbgsym_$(MONIT_VERSION)_$(CONFIGURED_ARCH).deb
$(eval $(call add_derived_package,$(MONIT),$(MONIT_DBG)))

View File

@ -616,7 +616,8 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \
$(IFUPDOWN2) \
$(KDUMP_TOOLS) \
$(LIBPAM_TACPLUS) \
$(LIBNSS_TACPLUS)) \
$(LIBNSS_TACPLUS) \
$(MONIT)) \
$$(addprefix $(TARGET_PATH)/,$$($$*_DOCKERS)) \
$$(addprefix $(FILES_PATH)/,$$($$*_FILES)) \
$(addprefix $(STRETCH_FILES_PATH)/, $(if $(filter $(CONFIGURED_ARCH),amd64), $(IXGBE_DRIVER))) \
@ -639,6 +640,7 @@ $(addprefix $(TARGET_PATH)/, $(SONIC_INSTALLERS)) : $(TARGET_PATH)/% : \
export sonic_asic_platform="$(patsubst %-$(CONFIGURED_ARCH),%,$(CONFIGURED_PLATFORM))"
export enable_organization_extensions="$(ENABLE_ORGANIZATION_EXTENSIONS)"
export enable_dhcp_graph_service="$(ENABLE_DHCP_GRAPH_SERVICE)"
export enable_system_telemetry="$(ENABLE_SYSTEM_TELEMETRY)"
export shutdown_bgp_on_start="$(SHUTDOWN_BGP_ON_START)"
export enable_pfcwd_on_start="$(ENABLE_PFCWD_ON_START)"
export installer_debs="$(addprefix $(STRETCH_DEBS_PATH)/,$($*_INSTALLS))"

View File

@ -291,7 +291,9 @@ RUN apt-get update && apt-get install -y \
automake1.11 \
libselinux1-dev \
# For kdump-tools
liblzo2-dev
liblzo2-dev \
# For SAI3.7
libprotobuf-dev
# For smartmontools 6.6-1
RUN apt-get -t stretch-backports install -y debhelper

View File

@ -0,0 +1,32 @@
From 06850e9beb2c50b5cc23fc94168acd9ae58d8ef8 Mon Sep 17 00:00:00 2001
From: Joe LeVeque <jolevequ@microsoft.com>
Date: Fri, 6 Dec 2019 05:53:09 +0000
Subject: [PATCH] Don't skip down interfaces when discovering interfaces in
relay mode
When discovering interfaces in relay mode, don't skip interfaces just
because they're down. If we fail to discover the interfaces because they
are down when the relay starts, but then are brought up at a later point
in time, the relay will discard any packets received on them because it
didn't discover the interface(s) when it started up.
---
common/discover.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/common/discover.c b/common/discover.c
index 8d5b958..5efff49 100644
--- a/common/discover.c
+++ b/common/discover.c
@@ -1016,7 +1016,8 @@ discover_interfaces(int state) {
info.flags & IFF_LOOPBACK ||
info.flags & IFF_POINTOPOINT) && !tmp) ||
(!(info.flags & IFF_UP) &&
- state != DISCOVER_UNCONFIGURED))
+ state != DISCOVER_UNCONFIGURED &&
+ state != DISCOVER_RELAY))
continue;
/* If there isn't already an interface by this name,
--
2.17.1

View File

@ -10,3 +10,4 @@
0009-CVE-2018-5733.patch
0010-CVE-2018-5732.patch
0008-interface-name-maxlen-crash.patch
0012-Don-t-skip-down-interfaces-when-discovering-interfac.patch

View File

@ -0,0 +1,169 @@
From 46aa45d0fa3e8879ecdca1c156cb2d91194c45e9 Mon Sep 17 00:00:00 2001
From: Pavel Shirshov <pavelsh@microsoft.com>
Date: Thu, 12 Dec 2019 13:47:17 -0800
Subject: [PATCH 1/1] lldpctl: put a lock around some commands to avoid race
conditions
---
src/client/client.h | 3 +++
src/client/commands.c | 58 ++++++++++++++++++++++++++++++++++++++++---
src/client/conf.c | 4 +--
3 files changed, 60 insertions(+), 5 deletions(-)
diff --git a/src/client/client.h b/src/client/client.h
index e3ee352..6c3e30d 100644
--- a/src/client/client.h
+++ b/src/client/client.h
@@ -62,6 +62,8 @@ extern void add_history ();
#endif
#undef NEWLINE
+extern const char *ctlname;
+
/* commands.c */
#define NEWLINE "<CR>"
struct cmd_node;
@@ -76,6 +78,7 @@ struct cmd_node *commands_new(
struct cmd_env*, void *),
void *);
struct cmd_node* commands_privileged(struct cmd_node *);
+struct cmd_node* commands_lock(struct cmd_node *);
struct cmd_node* commands_hidden(struct cmd_node *);
void commands_free(struct cmd_node *);
const char *cmdenv_arg(struct cmd_env*);
diff --git a/src/client/commands.c b/src/client/commands.c
index beedbf1..58df4a7 100644
--- a/src/client/commands.c
+++ b/src/client/commands.c
@@ -18,6 +18,9 @@
#include "client.h"
#include <string.h>
#include <sys/queue.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
/**
* An element of the environment (a key and a value).
@@ -68,6 +71,7 @@ struct cmd_node {
const char *token; /**< Token to enter this cnode */
const char *doc; /**< Documentation string */
int privileged; /**< Privileged command? */
+ int lock; /**< Lock required for execution? */
int hidden; /**< Hidden command? */
/**
@@ -113,6 +117,21 @@ commands_privileged(struct cmd_node *node)
return node;
}
+/**
+ * Make a node accessible only with a lock.
+ *
+ * @param node node to use lock to execute
+ * @return the modified node
+ *
+ * The node is modified. It is returned to ease chaining.
+ */
+struct cmd_node*
+commands_lock(struct cmd_node *node)
+{
+ if (node) node->lock = 1;
+ return node;
+}
+
/**
* Hide a node from help or completion.
*
@@ -344,6 +363,7 @@ _commands_execute(struct lldpctl_conn_t *conn, struct writer *w,
int n, rc = 0, completion = (word != NULL);
int help = 0; /* Are we asking for help? */
int complete = 0; /* Are we asking for possible completions? */
+ int needlock = 0; /* Do we need a lock? */
struct cmd_env env = {
.elements = TAILQ_HEAD_INITIALIZER(env.elements),
.stack = TAILQ_HEAD_INITIALIZER(env.stack),
@@ -351,6 +371,7 @@ _commands_execute(struct lldpctl_conn_t *conn, struct writer *w,
.argv = argv,
.argp = 0
};
+ static int lockfd = -1;
cmdenv_push(&env, root);
if (!completion)
for (n = 0; n < argc; n++)
@@ -388,6 +409,7 @@ _commands_execute(struct lldpctl_conn_t *conn, struct writer *w,
!strcmp(candidate->token, token)) {
/* Exact match */
best = candidate;
+ needlock = needlock || candidate->lock;
break;
}
if (!best) best = candidate;
@@ -406,6 +428,7 @@ _commands_execute(struct lldpctl_conn_t *conn, struct writer *w,
if (!candidate->token &&
CAN_EXECUTE(candidate)) {
best = candidate;
+ needlock = needlock || candidate->lock;
break;
}
}
@@ -421,9 +444,38 @@ _commands_execute(struct lldpctl_conn_t *conn, struct writer *w,
/* Push and execute */
cmdenv_push(&env, best);
- if (best->execute && best->execute(conn, w, &env, best->arg) != 1) {
- rc = -1;
- goto end;
+ if (best->execute) {
+ struct sockaddr_un su;
+ if (needlock) {
+ if (lockfd == -1) {
+ log_debug("lldpctl", "reopen %s for locking", ctlname);
+ if ((lockfd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) {
+ log_warn("lldpctl", "cannot open for lock %s", ctlname);
+ rc = -1;
+ goto end;
+ }
+ su.sun_family = AF_UNIX;
+ strlcpy(su.sun_path, ctlname, sizeof(su.sun_path));
+ if (connect(lockfd, (struct sockaddr *)&su, sizeof(struct sockaddr_un)) == -1) {
+ log_warn("lldpctl", "cannot connect to socket %s", ctlname);
+ rc = -1;
+ close(lockfd); lockfd = -1;
+ goto end;
+ }
+ }
+ if (lockf(lockfd, F_LOCK, 0) == -1) {
+ log_warn("lldpctl", "cannot get lock on %s", ctlname);
+ rc = -1;
+ close(lockfd); lockfd = -1;
+ goto end;
+ }
+ }
+ rc = best->execute(conn, w, &env, best->arg) != 1 ? -1 : rc;
+ if (needlock && lockf(lockfd, F_ULOCK, 0) == -1) {
+ log_warn("lldpctl", "cannot unlock %s", ctlname);
+ close(lockfd); lockfd = -1;
+ }
+ if (rc == -1) goto end;
}
env.argp++;
}
diff --git a/src/client/conf.c b/src/client/conf.c
index 1a14981..ba5743f 100644
--- a/src/client/conf.c
+++ b/src/client/conf.c
@@ -37,8 +37,8 @@ register_commands_configure(struct cmd_node *root)
"unconfigure",
"Unconfigure system settings",
NULL, NULL, NULL);
- commands_privileged(configure);
- commands_privileged(unconfigure);
+ commands_privileged(commands_lock(configure));
+ commands_privileged(commands_lock(unconfigure));
cmd_restrict_ports(configure);
cmd_restrict_ports(unconfigure);
--
2.17.1.windows.2

View File

@ -0,0 +1,27 @@
From b8e66b52f40103fd3abea77031c4634742c31860 Mon Sep 17 00:00:00 2001
From: Pavel Shirshov <pavelsh@microsoft.com>
Date: Thu, 12 Dec 2019 12:47:42 -0800
Subject: [PATCH 1/1] Read all notifications in lldpctl_recv
---
src/lib/connection.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/lib/connection.c b/src/lib/connection.c
index 591d9e9..88bbc99 100644
--- a/src/lib/connection.c
+++ b/src/lib/connection.c
@@ -253,8 +253,8 @@ lldpctl_recv(lldpctl_conn_t *conn, const uint8_t *data, size_t length)
memcpy(conn->input_buffer + conn->input_buffer_len, data, length);
conn->input_buffer_len += length;
- /* Is it a notification? */
- check_for_notification(conn);
+ /* Read all notifications */
+ while(!check_for_notification(conn));
RESET_ERROR(conn);
--
2.17.1.windows.2

View File

@ -0,0 +1,24 @@
From 833653dffb9be40110142af2a7cb4076a0dd24f5 Mon Sep 17 00:00:00 2001
From: Pavel Shirshov <pavelsh@microsoft.com>
Date: Thu, 12 Dec 2019 12:48:47 -0800
Subject: [PATCH 1/1] lib: fix memory leak
---
src/lib/connection.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/lib/connection.c b/src/lib/connection.c
index 88bbc99..aa88dad 100644
--- a/src/lib/connection.c
+++ b/src/lib/connection.c
@@ -114,6 +114,7 @@ lldpctl_new_name(const char *ctlname, lldpctl_send_callback send, lldpctl_recv_c
}
if (!send && !recv) {
if ((data = malloc(sizeof(struct lldpctl_conn_sync_t))) == NULL) {
+ free(conn->ctlname);
free(conn);
return NULL;
}
--
2.17.1.windows.2

View File

@ -0,0 +1,85 @@
From f6086575e63b5e089814ca116aa637d7588bfcd3 Mon Sep 17 00:00:00 2001
From: Pavel Shirshov <pavelsh@microsoft.com>
Date: Thu, 12 Dec 2019 13:52:42 -0800
Subject: [PATCH 1/1] lib: fix memory leak when handling I/O.
---
src/lib/atom.c | 11 ++++++-----
src/lib/atom.h | 9 ++++-----
src/lib/atoms/port.c | 2 +-
3 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/src/lib/atom.c b/src/lib/atom.c
index 955f434..f81d3bb 100644
--- a/src/lib/atom.c
+++ b/src/lib/atom.c
@@ -322,10 +322,12 @@ _lldpctl_do_something(lldpctl_conn_t *conn,
return SET_ERROR(conn, LLDPCTL_ERR_SERIALIZATION);
conn->state = state_send;
if (state_data)
- conn->state_data = strdup(state_data);
+ strlcpy(conn->state_data, state_data, sizeof(conn->state_data));
+ else
+ conn->state_data[0] = 0;
}
if (conn->state == state_send &&
- (state_data == NULL || !strcmp(conn->state_data, state_data))) {
+ (state_data == NULL || !strncmp(conn->state_data, state_data, sizeof(conn->state_data)))) {
/* We need to send the currently built message */
rc = lldpctl_send(conn);
if (rc < 0)
@@ -333,7 +335,7 @@ _lldpctl_do_something(lldpctl_conn_t *conn,
conn->state = state_recv;
}
if (conn->state == state_recv &&
- (state_data == NULL || !strcmp(conn->state_data, state_data))) {
+ (state_data == NULL || !strncmp(conn->state_data, state_data, sizeof(conn->state_data)))) {
/* We need to receive the answer */
while ((rc = ctl_msg_recv_unserialized(&conn->input_buffer,
&conn->input_buffer_len,
@@ -347,8 +349,7 @@ _lldpctl_do_something(lldpctl_conn_t *conn,
return SET_ERROR(conn, LLDPCTL_ERR_SERIALIZATION);
/* rc == 0 */
conn->state = CONN_STATE_IDLE;
- free(conn->state_data);
- conn->state_data = NULL;
+ conn->state_data[0] = 0;
return 0;
} else
return SET_ERROR(conn, LLDPCTL_ERR_INVALID_STATE);
diff --git a/src/lib/atom.h b/src/lib/atom.h
index 265c0a7..ab7037d 100644
--- a/src/lib/atom.h
+++ b/src/lib/atom.h
@@ -55,11 +55,10 @@ struct lldpctl_conn_t {
#define CONN_STATE_GET_DEFAULT_PORT_SEND 14
#define CONN_STATE_GET_DEFAULT_PORT_RECV 15
int state; /* Current state */
- char *state_data; /* Data attached to the state. It is used to
- * check that we are using the same data as a
- * previous call until the state machine goes to
- * CONN_STATE_IDLE. */
-
+ /* Data attached to the state. It is used to check that we are using the
+ * same data as a previous call until the state machine goes to
+ * CONN_STATE_IDLE. */
+ char state_data[IFNAMSIZ + 64];
/* Error handling */
lldpctl_error_t error; /* Last error */
diff --git a/src/lib/atoms/port.c b/src/lib/atoms/port.c
index 545155c..d902188 100644
--- a/src/lib/atoms/port.c
+++ b/src/lib/atoms/port.c
@@ -329,7 +329,7 @@ _lldpctl_atom_set_atom_port(lldpctl_atom_t *atom, lldpctl_key_t key, lldpctl_ato
struct lldpd_hardware *hardware = p->hardware;
struct lldpd_port_set set = {};
int rc;
- char *canary;
+ char *canary = NULL;
#ifdef ENABLE_DOT3
struct _lldpctl_atom_dot3_power_t *dpow;
--
2.17.1.windows.2

View File

@ -2,3 +2,7 @@
0001-return-error-when-port-does-not-exist.patch
0002-Let-linux-kernel-to-find-appropriate-nl_pid-automa.patch
0003-update-tx-interval-immediately.patch
0004-lldpctl-put-a-lock-around-some-commands-to-avoid-rac.patch
0005-Read-all-notifications-in-lldpctl_recv.patch
0006-lib-fix-memory-leak.patch
0007-lib-fix-memory-leak-when-handling-I-O.patch

33
src/monit/Makefile Normal file
View File

@ -0,0 +1,33 @@
.ONESHELL:
SHELL = /bin/bash
.SHELLFLAGS += -e
MAIN_TARGET = monit_$(MONIT_VERSION)_$(CONFIGURED_ARCH).deb
DERIVED_TARGETS = monit-dbgsym_$(MONIT_VERSION)_$(CONFIGURED_ARCH).deb
$(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% :
# Remove any stale files
rm -rf ./monit
# Clone monit repo
git clone https://salsa.debian.org/sk-guest/monit.git
pushd ./monit
# Reset HEAD to the commit of the proper tag
# NOTE: Using "git checkout <tag_name>" here detaches our HEAD,
# which stg doesn't like, so we use this method instead
# NOTE: For some reason, tags in the Debian monit repo are prefixed with "1%"
git reset --hard debian/1\%$(MONIT_VERSION)
# Apply patches
stg init
stg import -s ../patch/series
# Build source and Debian packages
dpkg-buildpackage -rfakeroot -b -us -uc -j$(SONIC_CONFIG_MAKE_JOBS)
popd
# Move the newly-built .deb packages to the destination directory
mv $(DERIVED_TARGETS) $* $(DEST)/
$(addprefix $(DEST)/, $(DERIVED_TARGETS)): $(DEST)/% : $(DEST)/$(MAIN_TARGET)

View File

@ -0,0 +1,70 @@
From c392362c9c1d57256b7e8ab7c77926824677fd73 Mon Sep 17 00:00:00 2001
From: Joe LeVeque <jolevequ@microsoft.com>
Date: Tue, 19 Nov 2019 01:51:13 +0000
Subject: [PATCH] [used_system_memory_sysdep] Use 'MemAvailable' value if
available
---
src/process/sysdep_LINUX.c | 35 +++++++++++++++++++++++------------
1 file changed, 23 insertions(+), 12 deletions(-)
diff --git a/src/process/sysdep_LINUX.c b/src/process/sysdep_LINUX.c
index 0d18f85..221e785 100644
--- a/src/process/sysdep_LINUX.c
+++ b/src/process/sysdep_LINUX.c
@@ -335,6 +335,7 @@ int getloadavg_sysdep(double *loadv, int nelem) {
boolean_t used_system_memory_sysdep(SystemInfo_T *si) {
char *ptr;
char buf[2048];
+ unsigned long mem_available = 0UL;
unsigned long mem_free = 0UL;
unsigned long buffers = 0UL;
unsigned long cached = 0UL;
@@ -343,22 +344,32 @@ boolean_t used_system_memory_sysdep(SystemInfo_T *si) {
unsigned long swap_free = 0UL;
if (! file_readProc(buf, sizeof(buf), "meminfo", -1, NULL)) {
- LogError("system statistic error -- cannot get real memory free amount\n");
+ LogError("system statistic error -- cannot read /proc/meminfo\n");
goto error;
}
- /* Memory */
- if (! (ptr = strstr(buf, "MemFree:")) || sscanf(ptr + 8, "%ld", &mem_free) != 1) {
- LogError("system statistic error -- cannot get real memory free amount\n");
- goto error;
+ /*
+ * Memory
+ *
+ * First, check if the "MemAvailable" value is available on this system. If it is, we will
+ * use it. Otherwise we will attempt to calculate the amount of available memory ourself.
+ */
+ if ((ptr = strstr(buf, "MemAvailable:")) && sscanf(ptr + 13, "%ld", &mem_available) == 1) {
+ si->total_mem = systeminfo.mem_max - (uint64_t)mem_available * 1024;
+ } else {
+ DEBUG("'MemAvailable' value not available on this system. Attempting to calculate available memory manually...\n");
+ if (! (ptr = strstr(buf, "MemFree:")) || sscanf(ptr + 8, "%ld", &mem_free) != 1) {
+ LogError("system statistic error -- cannot get real memory free amount\n");
+ goto error;
+ }
+ if (! (ptr = strstr(buf, "Buffers:")) || sscanf(ptr + 8, "%ld", &buffers) != 1)
+ DEBUG("system statistic error -- cannot get real memory buffers amount\n");
+ if (! (ptr = strstr(buf, "Cached:")) || sscanf(ptr + 7, "%ld", &cached) != 1)
+ DEBUG("system statistic error -- cannot get real memory cache amount\n");
+ if (! (ptr = strstr(buf, "SReclaimable:")) || sscanf(ptr + 13, "%ld", &slabreclaimable) != 1)
+ DEBUG("system statistic error -- cannot get slab reclaimable memory amount\n");
+ si->total_mem = systeminfo.mem_max - (uint64_t)(mem_free + buffers + cached + slabreclaimable) * 1024;
}
- if (! (ptr = strstr(buf, "Buffers:")) || sscanf(ptr + 8, "%ld", &buffers) != 1)
- DEBUG("system statistic error -- cannot get real memory buffers amount\n");
- if (! (ptr = strstr(buf, "Cached:")) || sscanf(ptr + 7, "%ld", &cached) != 1)
- DEBUG("system statistic error -- cannot get real memory cache amount\n");
- if (! (ptr = strstr(buf, "SReclaimable:")) || sscanf(ptr + 13, "%ld", &slabreclaimable) != 1)
- DEBUG("system statistic error -- cannot get slab reclaimable memory amount\n");
- si->total_mem = systeminfo.mem_max - (uint64_t)(mem_free + buffers + cached + slabreclaimable) * 1024;
/* Swap */
if (! (ptr = strstr(buf, "SwapTotal:")) || sscanf(ptr + 10, "%ld", &swap_total) != 1) {
--
2.17.1

2
src/monit/patch/series Normal file
View File

@ -0,0 +1,2 @@
# This series applies on GIT commit dc9bc1c949125140d967edfc598dfad47eedc552
0001-used_system_memory_sysdep-Use-MemAvailable-value-if-.patch

@ -1 +1 @@
Subproject commit feb42b05eb912ea64f0b4ce17f4bc890929eb57e
Subproject commit d5bc436a6179ec5ba985f66e96d2fb7864f0002d

@ -1 +1 @@
Subproject commit d22f0a0e64f30e9e26064824fb11f27b2d636850
Subproject commit 6ddd012d9ab362254bd6a54372ee0ab679a7130e

@ -1 +1 @@
Subproject commit a34ba131f618a8df6beec1f548aa08f9cedc48db
Subproject commit e97f2ab26c6cfc8e620cceddf94fe47646afe64c

@ -1 +1 @@
Subproject commit 4cee38534919e34f407363ac3ab5f31b4d09be6d
Subproject commit dd21b345d71dae02c6309c8faca911b1e25bc7b7

@ -1 +1 @@
Subproject commit 904a350107793d44be7167500fcec9087ca3243b
Subproject commit 0fa66a0210c081a1e6f3778f1ea59f1853a94e04

@ -1 +1 @@
Subproject commit 533749062f638f74ebc09c4bd0a5162b2c575564
Subproject commit 792800607c0a987097d430d9f7fa9dce34361cfd

@ -1 +1 @@
Subproject commit c3b8fe10b1568022fa025ef4be9cb063bfe49df4
Subproject commit 7b9661b2aea0d9c3c770c421ca9963e2d742197f

@ -1 +1 @@
Subproject commit a4a1e108afb3e75717e204da49a975681d964e8c
Subproject commit 8d6844984b6f02d389eb5f8d92e14f3e12e3f19c

Some files were not shown because too many files have changed in this diff Show More