xref: /freebsd/libexec/rc/rc.d/routing (revision c6989859ae9388eeb46a24fe88f9b8d07101c710)
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
144	_action=$1
145	_if=$2
146
147	_fibmod=`get_fibmod`
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	# Install configured routes.
165	if [ -n "${static_routes}" ]; then
166		for i in ${static_routes}; do
167			_skip=0
168			if [ -n "$_if" ]; then
169				case $i in
170				*:$_if)	;;
171				*)	_skip=1 ;;
172				esac
173			fi
174			if [ $_skip = 0 ]; then
175				route_args=`get_if_var ${i%:*} route_IF`
176				if [ -n "$route_args" ]; then
177					${ROUTE_CMD} ${_action} ${route_args}
178				else
179					warn "route_${i%:*} not found."
180				fi
181			fi
182		done
183	fi
184}
185
186static_inet6()
187{
188	local _action _if _skip fibmod allfibs
189	_action=$1
190	_if=$2
191
192	fibmod=`get_fibmod`
193
194	# Add pre-defined static routes first.
195	ipv6_static_routes="_v4mapped _v4compat ${ipv6_static_routes}"
196	ipv6_static_routes="_lla _llma ${ipv6_static_routes}"
197	ipv6_static_routes="_loopback ${ipv6_static_routes}"
198
199	# disallow "internal" addresses to appear on the wire
200	ipv6_route__v4mapped="::ffff:0.0.0.0 -prefixlen 96 ::1 -reject ${fibmod}"
201	ipv6_route__v4compat="::0.0.0.0 -prefixlen 96 ::1 -reject ${fibmod}"
202
203	# Create a loopback route in every fib
204	ipv6_route__loopback="::1 -prefixlen 128 -iface lo0 ${fibmod}"
205
206	# Disallow link-local unicast packets without outgoing scope
207	# identifiers.  However, if you set "ipv6_default_interface",
208	# for the host case, you will allow to omit the identifiers.
209	# Under this configuration, the packets will go to the default
210	# interface.
211	ipv6_route__lla="fe80:: -prefixlen 10 ::1 -reject ${fibmod}"
212	ipv6_route__llma="ff02:: -prefixlen 16 ::1 -reject ${fibmod}"
213
214	# Add default route.
215	case ${ipv6_defaultrouter} in
216	[Nn][Oo] | '')
217		;;
218	*)
219		ipv6_static_routes="${ipv6_static_routes} _default"
220		ipv6_route__default="default ${ipv6_defaultrouter}"
221		;;
222	esac
223
224	# Install configured routes.
225	if [ -n "${ipv6_static_routes}" ]; then
226		for i in ${ipv6_static_routes}; do
227			_skip=0
228			if [ -n "$_if" ]; then
229				case $i in
230				*:$_if)	;;
231				*)	_skip=1 ;;
232				esac
233			fi
234			if [ $_skip = 0 ]; then
235				ipv6_route_args=`get_if_var ${i%:*} ipv6_route_IF`
236				if [ -n "$ipv6_route_args" ]; then
237					${ROUTE_CMD} ${_action} \
238						-inet6 ${ipv6_route_args}
239				else
240					warn "route_${i%:*} not found"
241				fi
242			fi
243		done
244	fi
245
246	# Install the "default interface" to kernel, which will be used
247	# as the default route when there's no router.
248
249	# Disable installing the default interface when we act
250	# as router to avoid conflict between the default
251	# router list and the manual configured default route.
252	if checkyesno ipv6_gateway_enable; then
253		return
254	fi
255
256	case "${ipv6_default_interface}" in
257	[Nn][Oo] | [Nn][Oo][Nn][Ee])
258		return
259		;;
260	[Aa][Uu][Tt][Oo] | "")
261		for i in ${ipv6_network_interfaces}; do
262			case $i in
263			[Nn][Oo][Nn][Ee])
264				return
265				;;
266			lo0)
267				continue
268				;;
269			esac
270			laddr=`network6_getladdr $i exclude_tentative`
271			case ${laddr} in
272			'')
273				;;
274			*)
275				ipv6_default_interface=$i
276				break
277				;;
278			esac
279		done
280		;;
281	esac
282
283	ifconfig ${ipv6_default_interface} inet6 defaultif
284	${SYSCTL} net.inet6.ip6.use_defaultzone=1 > /dev/null
285}
286
287ropts_init()
288{
289	if [ -z "${_ropts_initdone}" ]; then
290		echo -n "Additional $1 routing options:"
291		_ropts_initdone=yes
292	fi
293}
294
295_check_dynamicrouting()
296{
297	local skip file name rcvar
298
299	# copied from /etc/rc
300	skip="-s nostart"
301	if [ `/sbin/sysctl -n security.jail.jailed` -eq 1 ]; then
302		skip="$skip -s nojail"
303	fi
304	[ -n "$local_startup" ] && find_local_scripts_new
305
306	for file in $( rcorder ${skip} /etc/rc.d/* ${local_rc} 2>/dev/null |
307		       xargs grep -lE '^# PROVIDE:.*\<dynamicrouting\>' ); do
308		(set -- enabled; . $file) && return 0;
309	done
310
311	return 1
312}
313
314options_inet()
315{
316	local _icmp_drop_redirect
317
318	_ropts_initdone=
319	if checkyesno icmp_bmcastecho; then
320		ropts_init inet
321		echo -n ' broadcast ping responses=YES'
322		${SYSCTL} net.inet.icmp.bmcastecho=1 > /dev/null
323	else
324		${SYSCTL} net.inet.icmp.bmcastecho=0 > /dev/null
325	fi
326
327	_icmp_drop_redirect="${icmp_drop_redirect}"
328	case "${_icmp_drop_redirect}" in
329	[Aa][Uu][Tt][Oo] | "")
330		if _check_dynamicrouting; then
331			_icmp_drop_redirect="yes"
332		else
333			_icmp_drop_redirect="no"
334		fi
335		;;
336	esac
337	if checkyesno _icmp_drop_redirect; then
338		ropts_init inet
339		echo -n ' ignore ICMP redirect=YES'
340		${SYSCTL} net.inet.icmp.drop_redirect=1 > /dev/null
341	else
342		${SYSCTL} net.inet.icmp.drop_redirect=0 > /dev/null
343	fi
344
345	if checkyesno icmp_log_redirect; then
346		ropts_init inet
347		echo -n ' log ICMP redirect=YES'
348		${SYSCTL} net.inet.icmp.log_redirect=1 > /dev/null
349	else
350		${SYSCTL} net.inet.icmp.log_redirect=0 > /dev/null
351	fi
352
353	if checkyesno gateway_enable; then
354		ropts_init inet
355		echo -n ' gateway=YES'
356		${SYSCTL} net.inet.ip.forwarding=1 > /dev/null
357	else
358		${SYSCTL} net.inet.ip.forwarding=0 > /dev/null
359	fi
360
361	if checkyesno forward_sourceroute; then
362		ropts_init inet
363		echo -n ' do source routing=YES'
364		${SYSCTL} net.inet.ip.sourceroute=1 > /dev/null
365	else
366		${SYSCTL} net.inet.ip.sourceroute=0 > /dev/null
367	fi
368
369	if checkyesno accept_sourceroute; then
370		ropts_init inet
371		echo -n ' accept source routing=YES'
372		${SYSCTL} net.inet.ip.accept_sourceroute=1 > /dev/null
373	else
374		${SYSCTL} net.inet.ip.accept_sourceroute=0 > /dev/null
375	fi
376
377	if checkyesno arpproxy_all; then
378		ropts_init inet
379		echo -n ' ARP proxyall=YES'
380		${SYSCTL} net.link.ether.inet.proxyall=1 > /dev/null
381	else
382		${SYSCTL} net.link.ether.inet.proxyall=0 > /dev/null
383	fi
384
385	[ -n "${_ropts_initdone}" ] && echo '.'
386}
387
388options_inet6()
389{
390	_ropts_initdone=
391
392	if checkyesno ipv6_gateway_enable; then
393		ropts_init inet6
394		echo -n ' gateway=YES'
395		${SYSCTL} net.inet6.ip6.forwarding=1 > /dev/null
396	else
397		${SYSCTL} net.inet6.ip6.forwarding=0 > /dev/null
398	fi
399
400	[ -n "${_ropts_initdone}" ] && echo '.'
401}
402
403load_rc_config $name
404run_rc_command "$@"
405