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