xref: /freebsd/libexec/rc/rc.d/routing (revision 30659d1d)
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="${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
340	for file in $( rcorder ${skip} /etc/rc.d/* ${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