xref: /freebsd/tools/ifnet/convert_ifapi.sh (revision 3c4ba5f55438f7afd4f4b0b56f88f2bb505fd6a6)
1#!/bin/sh
2#
3# Copyright (c) 2014, 2019, 2020 Juniper Networks, Inc.
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9#
10# 1. Redistributions of source code must retain the above copyright
11#    notice, this list of conditions and the following disclaimer.
12# 2. Redistributions in binary form must reproduce the above copyright
13#    notice, this list of conditions and the following disclaimer in the
14#    documentation and/or other materials provided with the distribution.
15#
16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26#
27# $FreeBSD$
28#
29
30#
31# Convert a NIC driver to use the procdural API.
32# It doesn't take care of all the # cases yet,
33# but still does about 95% of work.
34#
35# Author: Sreekanth Rupavatharam
36#
37
38MAX_PASSES=100
39
40if [ $# -lt 1 ]
41then
42	echo " $0 <driver source (e.g., if_em.c)>";
43	exit 1;
44fi
45
46# XXX - This needs to change if the data structure uses different name
47__ifp__="ifp";
48
49file=$1
50
51rotateCursor() {
52	case $toggle in
53	1) c="\\" ;;
54	2) c="|" ;;
55	3) c="/" ;;
56	*) c="-" ;;
57	esac
58	toggle=$(((toggle + 1) % 4))
59	printf " %s \b\b\b" $c
60}
61
62# Handle the case where $__ifp__->if_blah = XX;
63handle_set() {
64	if echo $line | grep "$__ifp__->.* = " > /dev/null 2>&1
65	then
66		if echo $line | grep "\[$__ifp__->.* = " > /dev/null 2>&1; then
67			# Special case of array[ifp->member] = value
68			return 1
69		fi
70		word=`echo $line | awk -F "if_" ' { print $2 }' | awk -F" =" '{ print $1 }'`
71		value=`echo $line | awk -F "=" '{ print $2 }' | sed -e 's/;//g'`
72		new=`echo if_set$word"\($__ifp__,"$value");"`
73		new=`echo $new | sed -e 's/&/\\\&/'`
74		old=`echo $line|sed -e 's/^[ 	]*//'`
75		line=`echo $line| sed -e's/'$old'/'$new'/g'`
76		return 0
77	fi
78	return 1
79}
80
81handle_inc() {
82	if echo $line | grep "$__ifp__->.*++\|++$__ifp__->.*" > /dev/null 2>&1
83	then
84		word=`echo $line | awk -F"if_" '{ print $2 }'|awk -F"\+" '{ print $1}'`
85		value=' 1';
86		old=`echo $line|sed -e 's/^[ 	]*//'`
87		new=`echo if_inc$word"\($__ifp__,"$value");"`
88		new=`echo $new | sed -e 's/&/\\\&/'`
89		line=`echo $line| sed -e's/'$old'/'$new'/g'`
90		return 0;
91	fi
92	return 1;
93}
94
95handle_add() {
96	if echo $line | grep "$__ifp__->.*+= " > /dev/null 2>&1
97	then
98		word=`echo $line | awk -F"if_" '{ print $2 }'|awk '{ print $1}'`
99		value=`echo $line | awk -F"=" '{ print $2}' | sed -e 's/;//g'`
100		new=`echo if_inc$word"\($__ifp__,$value);"`
101		new=`echo $new | sed -e 's/&/\\\&/'`
102		old=`echo $line|sed -e 's/^[ 	]*//'`
103		line=`echo $line| sed -e's/'$old'/'$new'/g'`
104		return 0
105	fi
106	return 1;
107
108}
109
110handle_or() {
111	if echo $line | grep "$__ifp__->.*|= " > /dev/null 2>&1
112	then
113		word=`echo $line | awk -F"if_" '{ print $2 }'|awk '{ print $1}'`
114		value=`echo $line | awk -F"=" '{ print $2}' | sed -e 's/;//g'`
115		new=`echo if_set${word}bit"($__ifp__,$value, 0);"`
116		new=`echo $new | sed -e 's/&/\\\&/'`
117		#line=`echo $line|sed -e 's/&/\\&/'`
118		old=`echo $line|sed -e 's/^[ 	]*//'`
119		line=`echo $line| sed -e's/'$old'/'$new'/g'`
120		return 0;
121	fi
122	return 1;
123
124}
125
126handle_and() {
127	if echo $line |grep "$__ifp__->.*&= " > /dev/null 2>&1
128	then
129		word=`echo $line | awk -F"if_" '{ print $2 }'|awk '{ print $1}'`
130		value=`echo $line | awk -F"=" '{ print $2}' | sed -e 's/;//g'`
131		value=`echo $value | sed -e's/~//g'`
132		new=`echo if_set${word}bit"\($__ifp__, 0,$value);"`
133		new=`echo $new | sed -e 's/&/\\\&/'`
134		old=`echo $line|sed -e 's/^[ 	]*//'`
135		line=`echo $line| sed -e's/'$old'/'$new'/g'`
136		return 0;
137	fi
138	return 1;
139
140}
141
142handle_toggle() {
143	if echo $line | grep "\^=" > /dev/null 2>&1
144	then
145		line=`echo $line | sed -e 's/'"$__ifp__"'->if_\(.*\) ^=\(.*\);/if_toggle\1('"$__ifp__"',\2);/g'`
146		return 0;
147	fi
148	return 1
149
150}
151
152# XXX - this needs updating
153handle_misc() {
154	if echo $line | grep "$__ifp__->\(if_capabilities\|if_flags\|if_softc\|if_capenable\|if_hwassist\|if_mtu\|if_drv_flags\|if_index\|if_alloctype\|if_dname\|if_xname\|if_addr\|if_hw_tsomax\|if_hw_tsomaxsegcount\|if_hw_tsomaxsegsize\)" > /dev/null 2>&1
155	then
156		word=`echo $line |awk -F"$__ifp__->if_" '{ print $2 }' | \
157			sed -e's/[^a-zA-Z0-9_]/\@/'|awk -F"\@" '{ print $1}'`
158		old=`echo "$__ifp__->if_"${word}`
159		new=`echo "if_get"${word}"($__ifp__)"`
160		new=`echo $new | sed -e 's/&/\\\&/'`
161		line=`echo $line| sed -e's/'$old'/'$new'/g'`
162		return 0;
163	fi
164	return 1;
165
166}
167
168replace_str ()
169{
170	orig=$1
171	new=$2
172
173	if echo $line | grep "$orig" > /dev/null 2>&1
174	then
175		line=`echo $line | sed -e "s|$orig|$new|"`
176	else
177		return 1
178	fi
179}
180
181handle_special ()
182{
183	replace_str "(\*$__ifp__->if_input)" "if_input" || \
184	replace_str "IFQ_DRV_IS_EMPTY(&$__ifp__->if_snd)" \
185		"if_sendq_empty($__ifp__)" || \
186	replace_str "IFQ_DRV_PREPEND(&$__ifp__->if_snd" \
187		"if_sendq_prepend($__ifp__" || \
188	replace_str "IFQ_SET_READY(&$__ifp__->if_snd)" \
189		"if_setsendqready($__ifp__)" || \
190	replace_str "VLAN_CAPABILITIES($__ifp__)" \
191		"if_vlancap($__ifp__)" || \
192	replace_str "IFQ_SET_MAXLEN(&$__ifp__->if_snd," \
193		"if_setsendqlen($__ifp__," || \
194	replace_str "IFQ_DRV_DEQUEUE(&$__ifp__->if_snd, \(.*\))" \
195		"\1 = if_dequeue($__ifp__)"
196	replace_str "$__ifp__->if_vlantrunk != NULL" \
197		"if_vlantrunkinuse($__ifp__)"
198}
199
200handle_ifps() {
201	handle_set || handle_inc || handle_add || handle_or || handle_and || \
202	handle_toggle || handle_misc || handle_special
203}
204
205handle_renames ()
206{
207	replace_str "if_setinit(" "if_setinitfn(" || \
208	replace_str "if_setioctl(" "if_setioctlfn(" || \
209	replace_str "if_setqflush(" "if_setqflushfn(" || \
210	replace_str "if_settransmit(" "if_settransmitfn(" || \
211	replace_str "if_getdrv_flags(" "if_getdrvflags(" || \
212	replace_str "if_setdrv_flagsbit(" "if_setdrvflagbits(" || \
213	replace_str "if_setstart(" "if_setstartfn(" || \
214	replace_str "if_sethwassistbit(" "if_sethwassistbits(" || \
215	replace_str "ifmedia_init(" "ifmedia_init_drv("
216}
217
218check_ifp()
219{
220	case "$line" in
221	*"${__ifp__}->"*) return 0;; # Still an ifp to convert
222	esac
223	return 1
224}
225
226add_failed ()
227{
228	line="$line /* ${FAIL_PAT} */"
229	return 1
230}
231
232if [ -e $file.tmp ]
233then
234	rm $file.tmp
235fi
236IFS=
237echo -n "Conversion for $file started, please wait: "
238FAIL_PAT="XXX - IFAPI"
239count=0
240while read -r line
241do
242	rotateCursor
243
244	# There is an ifp, we need to process it
245	passes=0
246	while check_ifp
247	do
248		if handle_ifps
249		then
250			handle_renames
251		else
252			add_failed
253			break
254		fi
255		passes=$((passes + 1))
256		if [ $passes -ge $MAX_PASSES ]; then
257			add_failed
258			break
259		fi
260	done
261
262	# Replace the ifnet * with if_t
263	case "$line" in
264	*"struct ifnet"*)
265		line=`echo $line | sed -e 's/struct ifnet[ \t]*\*/if_t /g'` ;;
266	*"IF_LLADDR("*)
267		line=`echo $line | sed -e 's/IF_LLADDR(/if_getlladdr(/g'` ;;
268	esac
269	printf "%s\n" "$line" >> $file.tmp
270done < $1
271echo ""
272count=`grep $FAIL_PAT $file.tmp | wc -l`
273if [ $count -gt 0 ]
274then
275	echo "$count lines could not be converted to IFAPI"
276	echo "Look for /* $FAIL_PAT */ in the converted file"
277fi
278echo "original $file  has been moved to $file.orig"
279mv $file $file.orig
280mv $file.tmp $file
281