Newer
Older
# script to assembly ppsi.conf based on dot-config configuration
#
# Parameters:
# -j generate JSON format of ppsi.conf
# -o file Overwrite the default output file name
# -i file Overwrite the default input dot-config file
# -p file Overwrite the default input psi-pre file
#
PRE_FILE="/wr/etc/ppsi-pre.conf"
OUTPUT_FILE="/etc/ppsi.conf"
DOTCONFIG_FILE="/wr/etc/dot-config"
log_output=/dev/kmsg
unset JSON_FORMAT
#decode script parameters
while getopts jo:i:p: option
do
case "${option}" in
"j") JSON_FORMAT=1;;
"o") OUTPUT_FILE=${OPTARG};;
"i") DOTCONFIG_FILE=${OPTARG};;
"p") PRE_FILE=$OPTARG;;
esac
done
if [ -f "$DOTCONFIG_FILE" ]; then
. "$DOTCONFIG_FILE"
else
# if dot-config not available remove ppsi's config
rm $OUTPUT_FILE
exit 1
fi
script_name="$0"
#
# This function retreive the fiber delay coefficient from
# the CONFIG_FIBER${1}_PARAMS parameter
# Parameter :
# $1 = fiber index
# Return the fiber delay coefficient
function get_fiber_delay_coeff() {
local dc=0
local fb=$1
if [ -n "$fb" ]; then # check if fiber parameter exists
if [[ "$fb" =~ ^-?[0-9]+$ ]]; then # check if fiber parameter is an integer
printf -v fb "%02d" $fb
local fiber_param=$(eval "echo \$CONFIG_FIBER${fb}_PARAMS")
if [ -n "$fiber_param" ]; then # check if the fiber exists
IFS='=' read -a fpa <<< "$fiber_param"
dc=${fpa[1]}
else
echo "$script_name: Unknown fiber=\"$fb\" in CONFIG_PORT"$i_port"_FIBER" | tee $log_output
echo "$script_name: Invalid parameter fiber=\"$fb\" in CONFIG_PORT"$i_port"_FIBER" | tee $log_output
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
fi
fi
echo "$dc"
}
#
# Decode ppsi.conf 'pre' file. It is used to define or override global keys.
# Expected file format :
# - must define key/value pairs separated with a space character : 'key value'
# - empty line are allowed
# - a comment start at the beginning of the line with the character '#'
# Parameter: $1 file_to_open
#
function decode_pre_file(){
filename="$1"
# read globals entries
while IFS='' read -r line ; do
if [[ -n "$line" ]] && [[ ${line:0:1} != "#" ]] ; then
IFS=' ' read var1 var2 <<< $line
if [[ -n $var1 ]] && [[ -n $var2 ]] ; then
globals[$var1]=$var2
fi
fi
done < "$filename"
}
#
# Generate the ppsi.conf file using the default text format:
# - define key/value pairs separated with a space character : 'key value'
# - empty line are allowed
# - a comment start at the beginning of the line with the character '#'
# - port instances are separated by a empty line
#
# Parameter : $1 output_file_name
# $2 pre_file_name
function gen_ppsi_conf() {
# Read destination - stdout if not defined
output=${1:-/dev/stdout}
echo "# Autogenerated file, please don't edit." >$output
echo "# This file will be overwritten at next boot." >>$output
echo -e "\n# Globals\n" >>$output
# globals
for key in ${globals_indexes}; do
prefix=""
if [[ $key = *"${globals_not_yet_supported}"* ]] ; then
prefix="# Parameter not yet supported // "
fi
value=${globals[$key]}
if [ -n "$value" ]; then
echo "${prefix}$key $value" >>$output
fi
done
echo -e "\n\n# Port instances\n" >>$output
local size
# Physical ports
for i_port in {01..18}; do # scan all the physical ports
port_vn="port${i_port}"
# PPSI instances
for j_inst in {01..02}; do # scan all the ppsi instances for a given port
inst_vn="${port_vn}inst${j_inst}"
eval array=\( \${${inst_vn}[@]} \)
size=${#array[@]}
if [ "${size}" == "0" ] ; then
continue
fi
hpKeys="port proto iface profile"
for k in $hpKeys; do
v="$port_vn[$k]";[[ -n "${!v}" ]] && echo "$k ${!v}" >>$output
v="$inst_vn[$k]";[[ -n "${!v}" ]] && echo "$k ${!v}" >>$output
done
# print remaining keys
for k in $port_ppsi_keys ; do
[[ "$hpKeys" != *"$k"* ]] && (v="$port_vn[$k]";[[ -n "${!v}" ]] && echo "$k ${!v}" >>$output)
done
for k in $inst_ppsi_keys ; do
[[ "$hpKeys" != *"$k"* ]] && (v="$inst_vn[$k]";[[ -n "${!v}" ]] && echo "$k ${!v}" >>$output)
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
done
echo -n -e "\n\n" >>$output
done
done
}
#
# Generate the ppsi.conf file using a JSON format:
# {
# "globals": {
# "clock-class" : 187,
# ...
# },
# "ports" : [
# {
# "iface" : "wri1",
# ...
# "instances" : [
# {
# "name" : "wri1-i1",
# ...
# },
# { ... }
# ]
# },
# { ... }
# ]
# }
#
# Parameter : $1 output_file_name
# $2 pre_file_name
function gen_ppsi_conf_json() {
# Read destination - stdout if not defined
output=${1:-/dev/stdout}
# start globals
echo -e "{\n \"globals\": {\n" >$output
# globals
unset comma_g
for key in ${globals_indexes}; do
if [[ $key = *"${globals_not_yet_supported}"* ]] ; then
continue
fi
value=${globals[$key]}
if [ -n "$value" ]; then
[[ -n "${comma_g}" ]] && echo "," >>$output
echo -e -n " \"$key\": \"$value\"" >>$output
comma_g=1
fi
done
# end globals
echo -e -n "\n }" >>$output
# start ports
echo -e ",\n \"ports\": [" >>$output
local size
# Physical ports
for i_port in {01..18}; do # scan all the physical ports
port_vn="port${i_port}"
# start port
if [ $i_port == "01" ] ; then
echo -e " {" >>$output
else
echo -e ",\n {" >>$output
fi
hpKeys="iface"
for k in $hpKeys; do
v="$port_vn[$k]";[[ -n "${!v}" ]] && echo -e " \"$k\": \"${!v}\"," >>$output
done
# print remaining keys
for k in $port_ppsi_keys; do
[[ "$hpKeys" != *"$k"* ]] && (v="$port_vn[$k]"; [[ -n "${!v}" ]] && echo -e " \"$k\": \"${!v}\"," >>$output)
done
# start instances
echo -e " \"instances\": [" >>$output
# PPSI instances
for j_inst in {01..02}; do # scan all the ppsi instances for a given port
inst_vn="${port_vn}inst${j_inst}"
eval array=\( \${${inst_vn}[@]} \)
size=${#array[@]}
if [ "${size}" == "0" ] ; then
continue
fi
# start instance /instances
if [ $j_inst == "01" ] ; then
# start instances
echo -e " {" >>$output
else
echo -e ",\n {" >>$output
fi
hpKeys="port proto iface profile"
for k in $hpKeys; do
v="$inst_vn[$k]";[[ -n "${!v}" ]] && echo -e " \"$k\": \"${!v}\"," >>$output
done
# print remaining keys
for k in $inst_ppsi_keys ; do
[[ "$hpKeys" != *"$k"* ]] && (v="$inst_vn[$k]";[[ -n "${!v}" ]] && echo -e " \"$k\": \"${!v}\"," >>$output)
done
# end instance
echo -e -n "\n }" >>$output
done
# end instances
echo -e "\n ]" >>$output
# end port
echo -e -n " }" >>$output
done
# end ports
echo -e "\n ]" >>$output
# end main block
echo "}" >>$output
}
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
function disable_L1sync() {
local inst=$1
local lv
for k in l1SyncEnabled l1SyncTxCoherencyIsRequired l1SyncRxCoherencyIsRequired \
l1SyncCongruencyIsRequired logL1SyncInterval l1SyncReceiptTimeout l1SyncOptParamsEnabled; do
lv="$inst[$k]"; unset ${lv}
done
}
function set_profile_for_PTP() {
local inst=$1
local lv
disable_L1sync $inst
}
function set_profile_for_WR() {
local inst=$1
local lv
disable_L1sync $inst
}
function set_profile_for_HA() {
local inst=$1
local lv
# L1SYNC mandatory values
for k in l1SyncEnabled l1SyncTxCoherencyIsRequired l1SyncRxCoherencyIsRequired l1SyncCongruencyIsRequired ; do
lv="$inst[$k]"; eval ${lv}="y"
done
lv="$inst[l1SyncOptParamsEnabled]"; eval ${lv}="n"
# Free parameters
test ! ${inst_vn[logL1SyncInterval]+_} && (lv="$inst_vn[logL1SyncInterval]"; eval ${lv}="0") # Set default value
test ! ${inst_vn[l1SyncReceiptTimeout]+_} && (lv="$inst_vn[l1SyncReceiptTimeout]"; eval ${lv}="3") # Set default value
# Force asymmetry correction
lv="$inst[asymmetryCorrectionEnable]"; eval ${lv}="y"
function set_instance_profile() {
local inst=$1
local lv="$inst[profile]"
local value=${!lv}
if [ "${value}" == "wr" ]; then
eval ${lv}="wr"
set_profile_for_WR $inst
elif [ "${value}" == "ha" ]; then
eval ${lv}="ha"
elif [ "${value}" == "custom" ]; then
eval ${lv}="custom"
elif [ "${value}" == "none" ] || [ "${value}" == "ptp" ]; then
# do nothing
eval ${lv}="ptp"
set_profile_for_PTP $inst
elif [ -n "$p" ]; then
echo "$script_name: Invalid parameter profile=\"$p\" in ${inst}" | tee $log_output
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
eval ${lv}="ha"
else
# default
eval ${lv}="ha"
fi
value=${!lv}
if [ "${value}" == "ha" ]; then
set_profile_for_HA $inst
fi
}
function build_port_ppsi_keys() {
local s=""
for i in "${!port_dotc_ppsi_key_mapping[@]}"
do
value=`echo ${port_dotc_ppsi_key_mapping[$i]} | head -n1 | cut -d " " -f1`;
[[ "$s" != *"$value"* ]] && s="$s $value"
done
echo `echo $s | xargs -n1 | sort -u | xargs`
}
function build_inst_ppsi_keys() {
local s=""
for i in "${!inst_dotc_ppsi_key_mapping[@]}"
do
value=`echo ${inst_dotc_ppsi_key_mapping[$i]} | head -n1 | cut -d " " -f1`;
[[ "$s" != *"$value"* ]] && s="$s $value"
done
echo `echo $s | xargs -n1 | sort -u | xargs`
}
globals_indexes='clock-class clock-accuracy clock-allan-variance domain-number priority1 priority2 time-source externalPortConfigurationEnabled slaveOnly ptpPpsThresholdMs ptpFallbackPpsGen gmDelayToGenPpsSec forcePpsGen'
globals_not_yet_supported='time-source'
# PHYSICAL PORT PARAMETERS
declare -A port_dotc_ppsi_key_mapping='(\
[FIBER]="delayCoefficient" \
[IFACE]="iface" \
[CONSTANT_ASYMMETRY]="constantAsymmetry" \
)'
port_dotc_keys="${!port_dotc_ppsi_key_mapping[@]}"
port_ppsi_keys=$(build_port_ppsi_keys)
# PPSI INSTANCE PARAMETERS
declare -A inst_dotc_ppsi_key_mapping='(\
[PROTOCOL_RAW]="proto raw" [PROTOCOL_UDP_IPV4]="proto udp" \
[MECHANISM_E2E]="mechanism e2e" [MECHANISM_P2P]="mechanism p2p" \
[PROFILE_PTP]="profile ptp" [PROFILE_WR]="profile wr" [PROFILE_HA]="profile ha" [PROFILE_CUSTOM]="profile custom" \
[DESIRADE_STATE_MASTER]="desiredState master" [DESIRADE_STATE_SLAVE]="desiredState slave" [DESIRADE_STATE_PASSIVE]="desiredState passive" \
[ANNOUNCE_INTERVAL]="logAnnounceInterval" [ANNOUNCE_RECEIPT_TIMEOUT]="announceReceiptTimeout" \
[MIN_DELAY_REQ_INTERVAL]="logMinDelayReqInterval" [MIN_PDELAY_REQ_INTERVAL]="logMinPDelayReqInterval" \
[ASYMMETRY_CORRECTION_ENABLE]="asymmetryCorrectionEnable" \
[BMODE_MASTER_ONLY]="masterOnly" \
[EGRESS_LATENCY]="egressLatency" [INGRESS_LATENCY]="ingressLatency" \
[L1SYNC_ENABLED]="l1SyncEnabled" [L1SYNC_INTERVAL]="logL1SyncInterval" \
[L1SYNC_RECEIPT_TIMEOUT]="l1SyncReceiptTimeout" \
[L1SYNC_OPT_PARAMS_ENABLED]="l1SyncOptParamsEnabled" [L1SYNC_OPT_PARAMS_TS_CORRECTED_TX_ENABLED]="l1SyncTimestampsCorrectedTxEnabled" \
[L1SYNC_TX_COHERENCY_IS_REQUIRED]="l1SyncTxCoherencyIsRequired" \
[L1SYNC_RX_COHERENCY_IS_REQUIRED]="l1SyncRxCoherencyIsRequired" [L1SYNC_CONGRUENCY_IS_REQUIRED]="l1SyncCongruencyIsRequired" \
[_VLAN]="vlan" \
)'
inst_dotc_keys="${!inst_dotc_ppsi_key_mapping[@]}"
inst_ppsi_keys=$(build_inst_ppsi_keys)
declare -A globals
# Read specific configuration : Still use the old format - to discuss
[[ "$PRE_FILE" != "" ]] && [[ -f $PRE_FILE ]] && decode_pre_file "$PRE_FILE"
# Use default value of clock class if not overwritten or empty string
if [ -v CONFIG_PTP_OPT_OVERWRITE_CLOCK_CLASS ] && [ -n "$CONFIG_PTP_OPT_CLOCK_CLASS" ]; then
globals[clock-class]="$CONFIG_PTP_OPT_CLOCK_CLASS"
else
if [ "$CONFIG_TIME_GM" = "y" ]; then
fi
if [ "$CONFIG_TIME_FM" = "y" ]; then
fi
if [ "$CONFIG_TIME_BC" = "y" ]; then
fi
if [ -n "$CONFIG_PTP_OPT_CLOCK_ACCURACY" ]; then
globals[clock-accuracy]="$CONFIG_PTP_OPT_CLOCK_ACCURACY"
fi
if [ -n "$CONFIG_PTP_OPT_CLOCK_ALLAN_VARIANCE" ]; then
globals[clock-allan-variance]="$CONFIG_PTP_OPT_CLOCK_ALLAN_VARIANCE"
fi
if [ -n "$CONFIG_PTP_OPT_DOMAIN_NUMBER" ]; then
globals[domain-number]="$CONFIG_PTP_OPT_DOMAIN_NUMBER"
fi
if [ -n "$CONFIG_PTP_OPT_ANNOUNCE_INTERVAL" ]; then
globals[announce-interval]="$CONFIG_PTP_OPT_ANNOUNCE_INTERVAL"
fi
if [ -n "$CONFIG_PTP_OPT_SYNC_INTERVAL" ]; then
globals[sync-interval]="$CONFIG_PTP_OPT_SYNC_INTERVAL"
fi
if [ -n "$CONFIG_PTP_OPT_PRIORITY1" ]; then
globals[priority1]="$CONFIG_PTP_OPT_PRIORITY1"
fi
if [ -n "$CONFIG_PTP_OPT_PRIORITY2" ]; then
globals[priority2]="$CONFIG_PTP_OPT_PRIORITY2"
if [ -v CONFIG_PTP_OPT_OVERWRITE_TIME_SOURCE ] && [ -n "$CONFIG_PTP_OPT_TIME_SOURCE" ]; then
globals[time-source]="$CONFIG_PTP_OPT_TIME_SOURCE"
else
if [ "$CONFIG_TIME_GM" = "y" ]; then
globals[time-source]=16 # ATOMIC_CLOCK
fi
if [ "$CONFIG_TIME_FM" = "y" ]; then
globals[time-source]=160 # INTERNAL_OSCILLATOR
fi
if [ "$CONFIG_TIME_BC" = "y" ]; then
globals[time-source]=160 # INTERNAL_OSCILLATOR
fi
if [ -n "$CONFIG_PTP_OPT_EXT_PORT_CONFIG_ENABLED" ]; then
globals[externalPortConfigurationEnabled]="$CONFIG_PTP_OPT_EXT_PORT_CONFIG_ENABLED"
else
globals[externalPortConfigurationEnabled]="n"
fi
if [ -n "$CONFIG_PTP_SLAVE_ONLY" ] && [ "${globals[externalPortConfigurationEnabled]}" = "n" ]; then
globals[slaveOnly]="$CONFIG_PTP_SLAVE_ONLY"
else
globals[slaveOnly]="n"
if [ -n "$CONFIG_PPSGEN_PTP_THRESHOLD_MS" ]; then
globals[ptpPpsThresholdMs]="$CONFIG_PPSGEN_PTP_THRESHOLD_MS"
fi
if [ -n "$CONFIG_PPSGEN_PTP_FALLBACK" ]; then
globals[ptpFallbackPpsGen]="$CONFIG_PPSGEN_PTP_FALLBACK"
fi
if [ -n "$CONFIG_PPSGEN_GM_DELAY_TO_GEN_PPS_SEC" ]; then
globals[gmDelayToGenPpsSec]="$CONFIG_PPSGEN_GM_DELAY_TO_GEN_PPS_SEC"
fi
if [ -n "$CONFIG_PPSGEN_FORCE" ]; then
globals[forcePpsGen]="$CONFIG_PPSGEN_FORCE"
fi
for i_port in {01..18}; do # scan all the physical ports
port_vn="port${i_port}"
declare -A $port_vn
#remove leading zero from i_port (params has numbers with leading zero,
#interface names are without leading zero)
i_port_int=$(expr $i_port + 0)
for p in $port_dotc_keys; do
k="${port_key}_$p"
plc="${port_dotc_ppsi_key_mapping[$p]}"
if [ -n "${!k}" ] && [ "$plc" != "" ]; then
v="$port_vn[${plc}]";
if [ "$p" == "FIBER" ] ; then
# Special treatment for FIBER : Retreive the delay coefficient from the DB
fiber_num="${!k}"
eval ${v}=$(get_fiber_delay_coeff $fiber_num)
else
eval ${v}="${!k}"
fi
fi
done
for j_inst in {01..02}; do # scan all the ppsi instances for a given port
#remove leading zero from i_port (params has numbers with leading zero,
#interface names are without leading zero)
j_inst_int=$(expr $j_inst + 0)
inst_count="CONFIG_PORT${i_port}_INSTANCE_COUNT_`expr ${j_inst_int} - 1`"
inst_count_value=$(eval "echo \$${inst_count}")
if [ -n "${inst_count_value}" ]; then
break # number of defined instances reached
fi
inst_vn="${port_vn}inst${j_inst}"
declare -A $inst_vn
inst_key="CONFIG_PORT${i_port}_INST${j_inst}"
for p in $inst_dotc_keys; do
plc="${inst_dotc_ppsi_key_mapping[$p]}"
if [ -n "${!k}" ] && [ "$plc" != "" ]; then
# Check if the string contains 2 elements separated by a space
OIFS=${IFS}; IFS=' ' read -a tokens <<< "${plc}"; IFS=${OIFS}
plc=${tokens[0]};
v="$inst_vn[${plc}]"
if [ "${#tokens[@]}" -gt "1" ] ; then
eval ${v}="${tokens[1]}";
else
eval ${v}="${!k}"
fi
Adam Wujek
committed
fi
v="$inst_vn[proto]"
if [ ! -n "${!v}" ]; then
eval ${v}="raw" # proto not defined. Set it to raw by default
fi
# set the profile
set_instance_profile $inst_vn
v="$inst_vn[profile]"; p_profile=${!v}
# define instance name
v="$port_vn[iface]"; p_iface=${!v}
v="$inst_vn[proto]"; p_proto=${!v}
v="$inst_vn[port]"; eval ${v}="${p_iface}-${j_inst_int}-${p_profile:0:2}-${p_proto}"
# if extPortConfiguration enabled, get the desired state
if [ "$CONFIG_PTP_OPT_EXT_PORT_CONFIG_ENABLED" == 'y' ] ; then
v="$inst_vn[desiredState]";
if [ -z "{!v}" ] ; then
eval ${v}="passive" # default value
fi
v="$inst_vn[masteronly]"; unset ${v} # remove master only
fi
# add vlans
if [ "$CONFIG_VLANS_ENABLE" = "y" ]; then
unset ppsi_vlans;
unset port_mode_access;
unset port_mode_trunk;
unset port_mode_unqualified;
unset port_mode_disabled;
# check port mode
port_mode_access=$(eval "echo \$CONFIG_VLANS_PORT"$i_port"_MODE_ACCESS")
port_mode_trunk=$(eval "echo \$CONFIG_VLANS_PORT"$i_port"_MODE_TRUNK")
port_mode_unqualified=$(eval "echo \$CONFIG_VLANS_PORT"$i_port"_MODE_UNQUALIFIED")
port_mode_disabled=$(eval "echo \$CONFIG_VLANS_PORT"$i_port"_MODE_DISABLED")
# check port mode
if [ "$port_mode_access" = "y" ]; then
ppsi_vlans=$(eval "echo \$CONFIG_VLANS_PORT"$i_port"_VID")
# use "&> /dev/null" to avoid error when $ppsi_vlans
# is not a number
if [ "$ppsi_vlans" -ge 0 ] &> /dev/null \
&& [ "$ppsi_vlans" -le 4094 ] &> /dev/null; then
v="$inst_vn[vlan]"; eval ${v}="$ppsi_vlans"
else
echo "$script_name: Wrong value \"$ppsi_vlans\" in CONFIG_VLANS_PORT"$i_port"_VID" | tee $log_output
continue;
fi
fi
if [ "$port_mode_trunk" = "y" ] \
|| [ "$port_mode_disabled" = "y" ] \
|| [ "$port_mode_unqualified" = "y" ]; then
ppsi_vlans=$(eval "echo \$CONFIG_VLANS_PORT"$i_port"_VID")
if [ -n "$ppsi_vlans" ]; then
mod_vlans=${ppsi_vlans//;/,}
v="$inst_vn[vlan]"; eval ${v}="$mod_vlans"
fi
done # scan all the ppsi instances in a port
done # scan all the physical ports
if [ -v JSON_FORMAT ] ; then
gen_ppsi_conf_json ${OUTPUT_FILE} ${PRE_FILE}
else
gen_ppsi_conf ${OUTPUT_FILE} ${PRE_FILE}
fi