xref: /freebsd/libexec/rc/rc.d/routing (revision 9f23cbd6cae82fd77edfad7173432fa8dccd0a95)
1#!/bin/sh
2#
3# Configure routing and miscellaneous network tunables
4#
5# $FreeBSD$
6#
7
8# PROVIDE: routing
9# REQUIRE: netif ppp stf
10# KEYWORD: nojailvnet
11
12. /etc/rc.subr
13. /etc/network.subr
14
15name="routing"
16desc="Routing setup"
17start_cmd="routing_start doall"
18stop_cmd="routing_stop"
19extra_commands="options static"
20static_cmd="routing_start static"
21options_cmd="routing_start options"
22
23ROUTE_CMD="/sbin/route"
24
25routing_start()
26{
27	local _cmd _af _if _a _ret
28	_cmd=$1
29	_af=$2
30	_if=$3
31	_ret=0
32
33	case $_if in
34	""|[Aa][Ll][Ll]|[Aa][Nn][Yy])	_if="" ;;
35	esac
36
37	case $_af in
38	""|[Aa][Ll][Ll]|[Aa][Nn][Yy])
39		for _a in inet inet6; do
40			afexists $_a || continue
41			setroutes $_cmd $_a $_if || _ret=1
42		done
43	;;
44	*)
45		if afexists $_af; then
46			setroutes $_cmd $_af $_if || _ret=1
47		else
48			err 1 "Unsupported address family: $_af."
49		fi
50	;;
51	esac
52
53	return $_ret
54}
55
56routing_stop()
57{
58	local _af _if _a
59	_af=$1
60	_if=$2
61
62	case $_if in
63	""|[Aa][Ll][Ll]|[Aa][Nn][Yy])	_if="" ;;
64	esac
65
66	case $_af in
67	""|[Aa][Ll][Ll]|[Aa][Nn][Yy])
68		for _a in inet inet6; do
69			afexists $_a || continue
70			eval static_${_a} delete $_if
71			# When $_if is specified, do not flush routes.
72			if ! [ -n "$_if" ]; then
73				eval routing_stop_${_a}
74			fi
75		done
76	;;
77	*)
78		if afexists $_af; then
79			eval static_${_af} delete $_if
80			# When $_if is specified, do not flush routes.
81			if ! [ -n "$_if" ]; then
82				eval routing_stop_${_af}
83			fi
84		else
85			err 1 "Unsupported address family: $_af."
86		fi
87	;;
88	esac
89}
90
91setroutes()
92{
93	local _ret
94	_ret=0
95	case $1 in
96	static)
97		static_$2 add $3
98		_ret=$?
99		;;
100	options)
101		options_$2
102		;;
103	doall)
104		static_$2 add $3
105		_ret=$?
106		options_$2
107		;;
108	esac
109	return $_ret
110}
111
112routing_stop_inet()
113{
114	${ROUTE_CMD} -n flush -inet
115}
116
117routing_stop_inet6()
118{
119	local i
120
121	${ROUTE_CMD} -n flush -inet6
122	for i in `list_net_interfaces`; do
123		if ipv6if $i; then
124			ifconfig $i inet6 -defaultif
125		fi
126	done
127}
128
129get_fibmod()
130{
131	local _fibs
132
133	_fibs=$((`${SYSCTL_N} net.fibs` - 1))
134	if [ ${_fibs} -gt 0 ]; then
135		echo "-fib 0-${_fibs}"
136	else
137		echo
138	fi
139}
140
141static_inet()
142{
143	local _action _if _skip _fibmod _fibs
144	_action=$1
145	_if=$2
146
147	_fibmod=`get_fibmod`
148	_fibs=$((`${SYSCTL_N} net.fibs` - 1))
149
150	# Provide loopback route in all routing tables.  This has to come
151	# first so that any following routes can be added.
152	static_routes="_loopback ${static_routes}"
153	route__loopback="-inet 127.0.0.1 -iface lo0 ${_fibmod}"
154
155	# Add default route.
156	case ${defaultrouter} in
157	[Nn][Oo] | '')
158		;;
159	*)
160		static_routes="${static_routes} _default"
161		route__default="default ${defaultrouter}"
162		;;
163	esac
164
165	# Add default routes for fibs
166	if [ ${_fibs} -gt 0 ]; then
167		for _fibnum in `jot ${_fibs}` ; do
168			eval _fib_gw=\${defaultrouter_fib${_fibnum}}
169			case ${_fib_gw} in
170			[Nn][Oo] | '')
171				;;
172			*)
173				static_routes="${static_routes} _default_fib${_fibnum}"
174				eval route__default_fib${_fibnum}="'default ${_fib_gw} -fib ${_fibnum}'"
175				;;
176			esac
177		done
178	fi
179
180
181	# Install configured routes.
182	if [ -n "${static_routes}" ]; then
183		for i in ${static_routes}; do
184			_skip=0
185			if [ -n "$_if" ]; then
186				case $i in
187				*:$_if)	;;
188				*)	_skip=1 ;;
189				esac
190			fi
191			if [ $_skip = 0 ]; then
192				route_args=`get_if_var ${i%:*} route_IF`
193				if [ -n "$route_args" ]; then
194					${ROUTE_CMD} ${_action} ${route_args}
195				else
196					warn "route_${i%:*} not found."
197				fi
198			fi
199		done
200	fi
201}
202
203static_inet6()
204{
205	local _action _if _skip fibmod _fibs
206	_action=$1
207	_if=$2
208
209	fibmod=`get_fibmod`
210	_fibs=$((`${SYSCTL_N} net.fibs` - 1))
211
212	# Add pre-defined static routes first.
213	ipv6_static_routes="_v4mapped _v4compat ${ipv6_static_routes}"
214	ipv6_static_routes="_lla _llma ${ipv6_static_routes}"
215	ipv6_static_routes="_loopback ${ipv6_static_routes}"
216
217	# disallow "internal" addresses to appear on the wire
218	ipv6_route__v4mapped="::ffff:0.0.0.0 -prefixlen 96 ::1 -reject ${fibmod}"
219	ipv6_route__v4compat="::0.0.0.0 -prefixlen 96 ::1 -reject ${fibmod}"
220
221	# Create a loopback route in every fib
222	ipv6_route__loopback="::1 -prefixlen 128 -iface lo0 ${fibmod}"
223
224	# Disallow link-local unicast packets without outgoing scope
225	# identifiers.  However, if you set "ipv6_default_interface",
226	# for the host case, you will allow to omit the identifiers.
227	# Under this configuration, the packets will go to the default
228	# interface.
229	ipv6_route__lla="fe80:: -prefixlen 10 ::1 -reject ${fibmod}"
230	ipv6_route__llma="ff02:: -prefixlen 16 ::1 -reject ${fibmod}"
231
232	# Add default route.
233	case ${ipv6_defaultrouter} in
234	[Nn][Oo] | '')
235		;;
236	*)
237		ipv6_static_routes="${ipv6_static_routes} _default"
238		ipv6_route__default="default ${ipv6_defaultrouter}"
239		;;
240	esac
241
242	# Add default routes for fibs
243	if [ ${_fibs} -gt 0 ]; then
244		for _fibnum in `jot ${_fibs}` ; do
245			eval _fib_gw=\${ipv6_defaultrouter_fib${_fibnum}}
246			case ${_fib_gw} in
247			[Nn][Oo] | '')
248				;;
249			*)
250				ipv6_static_routes="${ipv6_static_routes} _default_fib${_fibnum}"
251				eval ipv6_route__default_fib${_fibnum}="'default ${_fib_gw} -fib ${_fibnum}'"
252				;;
253			esac
254		done
255	fi
256
257
258	# Install configured routes.
259	if [ -n "${ipv6_static_routes}" ]; then
260		for i in ${ipv6_static_routes}; do
261			_skip=0
262			if [ -n "$_if" ]; then
263				case $i in
264				*:$_if)	;;
265				*)	_skip=1 ;;
266				esac
267			fi
268			if [ $_skip = 0 ]; then
269				ipv6_route_args=`get_if_var ${i%:*} ipv6_route_IF`
270				if [ -n "$ipv6_route_args" ]; then
271					${ROUTE_CMD} ${_action} \
272						-inet6 ${ipv6_route_args}
273				else
274					warn "route_${i%:*} not found"
275				fi
276			fi
277		done
278	fi
279
280	# Install the "default interface" to kernel, which will be used
281	# as the default route when there's no router.
282
283	# Disable installing the default interface when we act
284	# as router to avoid conflict between the default
285	# router list and the manual configured default route.
286	if checkyesno ipv6_gateway_enable; then
287		return
288	fi
289
290	case "${ipv6_default_interface}" in
291	[Nn][Oo] | [Nn][Oo][Nn][Ee])
292		return
293		;;
294	[Aa][Uu][Tt][Oo] | "")
295		for i in ${ipv6_network_interfaces}; do
296			case $i in
297			[Nn][Oo][Nn][Ee])
298				return
299				;;
300			lo0)
301				continue
302				;;
303			esac
304			laddr=`network6_getladdr $i exclude_tentative`
305			case ${laddr} in
306			'')
307				;;
308			*)
309				ipv6_default_interface=$i
310				break
311				;;
312			esac
313		done
314		;;
315	esac
316
317	ifconfig ${ipv6_default_interface} inet6 defaultif
318	${SYSCTL} net.inet6.ip6.use_defaultzone=1 > /dev/null
319}
320
321ropts_init()
322{
323	if [ -z "${_ropts_initdone}" ]; then
324		echo -n "Additional $1 routing options:"
325		_ropts_initdone=yes
326	fi
327}
328
329_check_dynamicrouting()
330{
331	local skip file name rcvar
332
333	# copied from /etc/rc
334	skip="-s nostart"
335	if [ `/sbin/sysctl -n security.jail.jailed` -eq 1 ]; then
336		skip="$skip -s nojail"
337	fi
338	[ -n "$local_startup" ] && find_local_scripts_new
339	[ -n "$system_rc" ] && find_system_scripts
340
341	for file in $( rcorder ${skip} ${system_rc} ${local_rc} 2>/dev/null |
342		       xargs grep -lE '^# PROVIDE:.*\<dynamicrouting\>' ); do
343		(set -- enabled; . $file) && return 0;
344	done
345
346	return 1
347}
348
349options_inet()
350{
351	local _icmp_drop_redirect
352
353	_ropts_initdone=
354	if checkyesno icmp_bmcastecho; then
355		ropts_init inet
356		echo -n ' broadcast ping responses=YES'
357		${SYSCTL} net.inet.icmp.bmcastecho=1 > /dev/null
358	else
359		${SYSCTL} net.inet.icmp.bmcastecho=0 > /dev/null
360	fi
361
362	_icmp_drop_redirect="${icmp_drop_redirect}"
363	case "${_icmp_drop_redirect}" in
364	[Aa][Uu][Tt][Oo] | "")
365		if _check_dynamicrouting; then
366			_icmp_drop_redirect="yes"
367		else
368			_icmp_drop_redirect="no"
369		fi
370		;;
371	esac
372	if checkyesno _icmp_drop_redirect; then
373		ropts_init inet
374		echo -n ' ignore ICMP redirect=YES'
375		${SYSCTL} net.inet.icmp.drop_redirect=1 > /dev/null
376	else
377		${SYSCTL} net.inet.icmp.drop_redirect=0 > /dev/null
378	fi
379
380	if checkyesno icmp_log_redirect; then
381		ropts_init inet
382		echo -n ' log ICMP redirect=YES'
383		${SYSCTL} net.inet.icmp.log_redirect=1 > /dev/null
384	else
385		${SYSCTL} net.inet.icmp.log_redirect=0 > /dev/null
386	fi
387
388	if checkyesno gateway_enable; then
389		ropts_init inet
390		echo -n ' gateway=YES'
391		${SYSCTL} net.inet.ip.forwarding=1 > /dev/null
392	else
393		${SYSCTL} net.inet.ip.forwarding=0 > /dev/null
394	fi
395
396	if checkyesno forward_sourceroute; then
397		ropts_init inet
398		echo -n ' do source routing=YES'
399		${SYSCTL} net.inet.ip.sourceroute=1 > /dev/null
400	else
401		${SYSCTL} net.inet.ip.sourceroute=0 > /dev/null
402	fi
403
404	if checkyesno accept_sourceroute; then
405		ropts_init inet
406		echo -n ' accept source routing=YES'
407		${SYSCTL} net.inet.ip.accept_sourceroute=1 > /dev/null
408	else
409		${SYSCTL} net.inet.ip.accept_sourceroute=0 > /dev/null
410	fi
411
412	if checkyesno arpproxy_all; then
413		ropts_init inet
414		echo -n ' ARP proxyall=YES'
415		${SYSCTL} net.link.ether.inet.proxyall=1 > /dev/null
416	else
417		${SYSCTL} net.link.ether.inet.proxyall=0 > /dev/null
418	fi
419
420	[ -n "${_ropts_initdone}" ] && echo '.'
421}
422
423options_inet6()
424{
425	_ropts_initdone=
426
427	if checkyesno ipv6_gateway_enable; then
428		ropts_init inet6
429		echo -n ' gateway=YES'
430		${SYSCTL} net.inet6.ip6.forwarding=1 > /dev/null
431	else
432		${SYSCTL} net.inet6.ip6.forwarding=0 > /dev/null
433	fi
434
435	[ -n "${_ropts_initdone}" ] && echo '.'
436}
437
438load_rc_config $name
439run_rc_command "$@"
440