summary refs log tree commit diff
path: root/Completion/Solaris/Command/_ipadm
blob: 34d1eacbae80c2000e4f96d09726d16d659c35d3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
#compdef ipadm
# Synced with the S11U1 build 19 man page

_ipadm_ifs() {
	local -a extra

	zparseopts -D -E -a extra /+:

	compadd "$@" - $(ipadm show-if -p -o ifname) $extra[2,-1]
}

_ipadm_enabled_ifs() {
	# Interfaces not marked "disabled"
	compadd "$@" - "${(@)${(@)${(f)$(ipadm show-if -p -o state,ifname)}:#disabled:*}#*:}"
}

_ipadm_disabled_ifs() {
	compadd "$@" - "${(@)${(@)${(f)$(ipadm show-if -p -o state,ifname)}#disabled:*}:#*:*}"
}

_ipadm_vnis() {
	compadd "$@" - "${(@)${(@)${(f)$(ipadm show-if -p -o class,ifname)}#vni:*}:#*:*}"
}

_ipadm_ipmps() {
	compadd "$@" - "${(@)${(@)${(f)$(ipadm show-if -p -o class,ifname)}#ipmp:*}:#*:*}"
}

_ipadm_get_possible_values() {
	local -a proto poss
	local cmd

	cmd=${${(M)words:#set-*}/set/show}
	if [[ $cmd == "show-prop" ]]; then
		# You have to specify a protocol for show-prop if you specify a
		# property, so we loop through them all.
		poss=()
		for proto in ipv4 ipv6 icmp tcp udp sctp; do
			poss=( $poss ${(u)=$(ipadm $cmd -c -p ${IPREFIX%=} -o possible $proto 2> /dev/null)//,/ } )
		done
		poss=( ${(u)poss:#\?} )
	else
		proto=${=opt_args[-m]:+-m $opt_args[-m]}
		poss=( ${(u)=$(ipadm $cmd -c -p ${IPREFIX%=} $proto -o possible)//,/ } )
	fi
	if [[ $poss[1] == [0-9]##-[0-9]## ]]; then
		if (( $#poss > 1 )); then
			_message -e "number in ranges ${(j:, :)poss}"
		else
			_message -e "number in range $poss"
		fi
	elif [[ -z $poss[1] ]]; then
		_message -e "value"
	else
		compadd "$@" - $poss
	fi
}

_ipadm_addrobjs() {
	compadd "$@" - $(ipadm show-addr -p -o addrobj)
}

_ipadm_addrobjs_or_ifs() {
	compadd "$@" - $(ipadm show-addr -p -o addrobj) \
		$(ipadm show-if -p -o ifname)
}

_ipadm_protos() {
	compadd "$@" - $(ipadm show-prop -c -o proto)
}

_ipadm() {
	local context state line expl
	local -A opt_args
	local -a subcmds
	local -a if_properties if_propproperties if_properties2
	local -a addr_properties addr_propproperties
	local -a addrobj_properties
	local -a proto_ipv4_properties proto_ipv6_properties proto_tcp_properties
	local -a proto_udp_properties proto_sctp_properties proto_icmp_properties
	local -a proto_all_properties proto_propproperties

	subcmds=(
		"help"
		{"show","disable","enable"}"-if"
		{"create","delete"}"-ip"
		{"create","delete"}"-vni"
		{"create","delete","add","remove"}"-ipmp"
		{"set","reset","show"}"-ifprop"
		{"create","delete","show","up","down","refresh","disable","enable"}"-addr"
		{"set","reset","show"}"-addrprop"
		{"set","reset","show"}"-prop"
	)

	if_properties=( "ifname" "class" "state" "active" "current" "persistent" "over" )

	if_propproperties=( "ifname" "property" "proto" "perm" "current" "persistent" "default" "possible" )

	if_properties2=(
		"arp:value:_ipadm_get_possible_values"
		"forwarding:value:_ipadm_get_possible_values"
		"metric:value:_ipadm_get_possible_values"
		"mtu:value:_ipadm_get_possible_values"
		"nud:value:_ipadm_get_possible_values"
		"usesrc:value:_ipadm_ifs -/ none"
		"exchange_routes:value:_ipadm_get_possible_values"
		"group:value:_ipadm_get_possible_values"
		"standby:value:_ipadm_get_possible_values"
	)

	addr_properties=(
		"broadcast:value:_ipadm_get_possible_values"
		"deprecated:value:_ipadm_get_possible_values"
		"prefixlen:value:_ipadm_get_possible_values"
		"private:value:_ipadm_get_possible_values"
		"reqhost:value:_ipadm_get_possible_values"
		"transmit:value:_ipadm_get_possible_values"
		"zone:value:_zones -t c"
	)

	addr_propproperties=( "addrobj" "property" "perm" "current" "persistent" "default" "possible" )

	addrobj_properties=(
		"addrobj" "type" "state" "current" "persistent" "addr"
		"cid-type" "cid-value" "begin" "expire" "renew"
	)

	proto_ipv4_properties=( "hostmodel" "ttl" "forwarding" )
	proto_ipv6_properties=( "hostmodel" "hoplimit" "forwarding" )
	proto_tcp_properties=( "cong_default" "cong_enabled" "ecn" "extra_priv_ports" "max_buf" "recv_buf"
		"send_buf" "sack" "smallest_anon_port" "largest_anon_port" "smallest_nonpriv_port" )
	proto_udp_properties=( "extra_priv_ports" "max_buf" "recv_buf" "send_buf" "smallest_anon_port"
		"largest_anon_port" "smallest_nonpriv_port" )
	proto_sctp_properties=( "cong_default" "cong_enabled" "extra_priv_ports" "max_buf" "recv_buf"
		"send_buf" "smallest_anon_port" "largest_anon_port" "smallest_nonpriv_port" )
	proto_icmp_properties=( "max_buf" "recv_buf" "send_buf" )
	proto_all_properties=( $proto_ipv4_properties $proto_ipv6_properties $proto_tcp_properties
		$proto_udp_properties $proto_sctp_properties $proto_icmp_properties )
	proto_all_properties=( $^proto_all_properties:value:_ipadm_get_possible_values )

	proto_propproperties=( "proto" "property" "perm" "current" "persistent" "default" "possible" )

	if [[ $service == "ipadm" ]]; then
		_arguments -C -A "-*" \
			'-\?[Help]' \
			'*::command:->subcmd' && return 0

		if (( CURRENT == 1 )); then
			_wanted commands expl "ipadm subcommand" compadd -a subcmds
			return
		fi
		service="$words[1]"
		curcontext="${curcontext%:*}=$service:"
	fi

	case $service in
	("help")
		_arguments ':subcommand:($subcmds)'
		;;

	("create-ip")
		_arguments -A "-*" \
			'(-t --temporary)'{-t,--temporary}'[Interface should be temporary]' \
			':interface name:'
		;;

	("delete-ip")
		_arguments -A "-*" \
			':interface name:_ipadm_ifs'
		;;

	("create-vni")
		_arguments -A "-*" \
			'(-t --temporary)'{-t,--temporary}'[Interface should be temporary]' \
			':VNI name:'
		;;

	("delete-vni")
		_arguments -A "-*" \
			':VNI name:_ipadm_vnis'
		;;

	("create-ipmp")
		_arguments -A "-*" \
			'(-t --temporary)'{-t,--temporary}'[Interface should be temporary]' \
			'(-i --interface)'{-i,--interface}'[List of underlying interfaces]:interface name:_values -s , "interface" $(ipadm show-if -p -o ifname)' \
			':IPMP interface name:'
		;;

	("delete-ipmp")
		_arguments -A "-*" \
			'(-f --force)'{-f,--force}'[First remove all underlying interfaces from group]' \
			':IPMP interface name:_ipadm_ipmps'
		;;

	("add-ipmp")
		_arguments -A "-*" \
			'(-t --temporary)'{-t,--temporary}'[Interface should be temporary]' \
			'(-i --interface)'{-i,--interface}'[List of underlying interfaces]:interface name:_values -s , "interface" $(ipadm show-if -p -o ifname)' \
			':IPMP interface name:_ipadm_ipmps'
		;;

	("remove-ipmp")
		_arguments -A "-*" \
			'(-t --temporary)'{-t,--temporary}'[Interface should be temporary]' \
			'(-i --interface)'{-i,--interface}'[List of underlying interfaces]:interface name:_values -s , "interface" $(ipadm show-if -p -o ifname)' \
			':IPMP interface name:_ipadm_ipmps'
		;;

	("show-if")
		_arguments -A "-*" \
			'(-p --parseable)'{-p,--parseable}'[Parseable output]' \
			'(-o --output)'{-o,--output}'[Properties to display]:property:_values -s , "property" $if_properties' \
			':interface name:_ipadm_ifs'
		;;

	("disable-if")
		_arguments -A "-*" \
			'(-t --temporary)'{-t,--temporary}'[Change should be temporary]' \
			':interface name:_ipadm_enabled_ifs'
		;;

	("enable-if")
		_arguments -A "-*" \
			'(-t --temporary)'{-t,--temporary}'[Change should be temporary]' \
			':interface name:_ipadm_disabled_ifs'
		;;

	("set-ifprop")
		_arguments -A "-*" \
			'(-t --temporary)'{-t,--temporary}'[Change should be temporary]' \
			'(-m --module)'{-m,--module}'[Protocol]:protocol:(ipv4 ipv6)' \
			'(-p --prop)'{-p,--prop}'[Property to set]:property:_values -s , "property" $if_properties2' \
			':interface name:_ipadm_ifs'
		;;

	("reset-ifprop")
		_arguments -A "-*" \
			'(-t --temporary)'{-t,--temporary}'[Change should be temporary]' \
			'(-m --module)'{-m,--module}'[Protocol]:protocol:(ipv4 ipv6)' \
			'(-p --prop)'{-p,--prop}'[Property to reset]:property:($if_properties2)' \
			':interface name:_ipadm_ifs'
		;;

	("show-ifprop")
		_arguments -A "-*" \
			'(-c --parseable)'{-c,--parseable}'[Parseable output]' \
			'(-m --module)'{-m,--module}'[Protocol]:protocol:(ipv4 ipv6)' \
			'(-o --output)'{-o,--output}'[Property properties to display]:property:_values -s , "property" $if_propproperties' \
			'(-p --prop)'{-p,--prop}'[Interface properties to display]:property:_values -s , "property" ${if_properties2%%\:*}' \
			':interface name:_ipadm_ifs'
		;;

	("create-addr")
		# This causes all options and arguments following -T to be
		# stuck into $opt_args[-T].  It feels hacky, but it seems
		# to do the trick.
		# XXX When -T is static, it's not necessary.
		_arguments -C -A "-*" \
			'(-t --temporary)'{-t,--temporary}'[Address should be temporary]' \
			'-T[Address type]:*::address type:->newaddr'

		if [[ $state == "newaddr" ]]; then

			case ${opt_args[-T]#-T:} in
			("static:"*)
				local -a addrthingsv4
				addrthingsv4=( "local:address: " "remote:address: ")
				_arguments -A "-*" \
				'(-d --down)'{-d,--down}'[Address should be marked down]' \
				'(-a --address)'{-a,--address}'[Address specification]:address:_values -s , "address" $addrthingsv4' \
				':address object name:_ipadm_addrobjs_or_ifs'
				;;

			("dhcp:"*)
				_arguments -A "-*" \
				'(-w --wait)'{-w,--wait}'[Seconds to wait for completion]:number or "forever":{if [[ -prefix [0-9]## ]]; then _message -e "number of seconds"; else _wanted forever expl "number or \"forever\"" compadd forever; fi}' \
				'-h[Request a specific hostname]:hostname:' \
				':address object name:_ipadm_addrobjs_or_ifs'
				;;

			("addrconf:"*)
				local -a addrthingsv6 statefulness
				addrthingsv6=( "local:interface id: " "remote:interface id: ")
				statefulness=( "stateful:statefulness:(yes no)" "stateless:statelessness:(yes no)" )
				_arguments -A "-*" \
				'(-i --interface-id)'{-i,--interface-id}'[Interface ID]:address:_values -s , "interface id" $addrthingsv6' \
				'(-p --prop)'{-p,--prop}'[Statefulness configuration]:statefulness configuration:_values -s , "statefulness" $statefulness' \
				':address object name:_ipadm_addrobjs_or_ifs'
				;;
			(*)
				_wanted commands expl "address type" compadd static dhcp addrconf
				;;
			esac
		fi

		;;

	("delete-addr")
		_arguments -A "-*" \
			'(-r --release)'{-r,--release}'[Release DHCP-acquired address]' \
			':address object name:_ipadm_addrobjs'
		;;

	("show-addr")
		_arguments -A "-*" \
			'(-d --dhcp -p --parseable)'{-d,--dhcp}'[Display DHCP status fields]' \
			'(-p --parseable -d --dhcp)'{-p,--parseable}'[Parseable output]' \
			'(-o --output)'{-o,--output}'[Properties to display]:property:_values -s , "property" $addrobj_properties' \
			':address object name:_ipadm_addrobjs_or_ifs'
		;;

	({"up","down","disable","enable"}"-addr")
		_arguments -A "-*" \
			'(-t --temporary)'{-t,--temporary}'[Change should be temporary]' \
			':address object name:_ipadm_addrobjs'
		;;

	("refresh-addr")
		_arguments -A "-*" \
			'(-i --inform)'{-i,--inform}'[Retrieve DHCP parameters]' \
			':address object name:_ipadm_addrobjs'
		;;

	("set-addrprop")
		_arguments -A "-*" \
			'(-t --temporary)'{-t,--temporary}'[Change should be temporary]' \
			'(-p --prop)'{-p,--prop}'[Property to set]:property:_values -s , "property" $addr_properties' \
			':address object name:_ipadm_addrobjs'
		;;

	("reset-addrprop")
		_arguments -A "-*" \
			'(-t --temporary)'{-t,--temporary}'[Change should be temporary]' \
			'(-p --prop)'{-p,--prop}'[Property to reset]:property:(${addr_properties%%\:*})' \
			':address object name:_ipadm_addrobjs'
		;;

	("show-addrprop")
		_arguments -A "-*" \
			'(-c --parseable)'{-c,--parseable}'[Parseable output]' \
			'(-o --output)'{-o,--output}'[Property properties to display]:property:_values -s , "property" $addr_propproperties' \
			'(-p --prop)'{-p,--prop}'[Address object properties to display]:property:_values -s , "property" ${addr_properties%%\:*}' \
			':address object name:_ipadm_addrobjs_or_ifs'
		;;

	("set-prop")
		_arguments -A "-*" \
			'(-t --temporary)'{-t,--temporary}'[Change should be temporary]' \
			'(-p --prop)'{-p,--prop}'[Property to set]:property:_values -s , "property" $proto_all_properties' \
			':protocol name:_ipadm_protos'
		;;

	("reset-prop")
		_arguments -A "-*" \
			'(-t --temporary)'{-t,--temporary}'[Change should be temporary]' \
			'(-p --prop)'{-p,--prop}'[Property to reset]:property:(${proto_all_properties%%\:*})' \
			':protocol name:_ipadm_protos'
		;;

	("show-prop")
		_arguments -A "-*" \
			'(-c --parseable)'{-c,--parseable}'[Parseable output]' \
			'(-o --output)'{-o,--output}'[Property properties to display]:property:_values -s , "property" $proto_propproperties' \
			'(-p --prop)'{-p,--prop}'[Protocol properties to display]:property:_values -s , "property" ${proto_all_properties%%\:*}' \
			':protocol name:_ipadm_protos'
		;;

	(*)
		_message "unknown ipadm subcommand: $service"
		;;
	esac
}

_ipadm "$@"