Print this page
4360 Fix SMF methods and other scripts which rely on the system shell to use /sbin/sh
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/svc/shell/net_include.sh
+++ new/usr/src/cmd/svc/shell/net_include.sh
1 -#!/bin/sh
1 +#!/sbin/sh
2 2 #
3 3 # CDDL HEADER START
4 4 #
5 5 # The contents of this file are subject to the terms of the
6 6 # Common Development and Distribution License (the "License").
7 7 # You may not use this file except in compliance with the License.
8 8 #
9 9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 10 # or http://www.opensolaris.org/os/licensing.
11 11 # See the License for the specific language governing permissions
12 12 # and limitations under the License.
13 13 #
14 14 # When distributing Covered Code, include this CDDL HEADER in each
15 15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 16 # If applicable, add the following below this CDDL HEADER, with the
17 17 # fields enclosed by brackets "[]" replaced with your own identifying
18 18 # information: Portions Copyright [yyyy] [name of copyright owner]
19 19 #
20 20 # CDDL HEADER END
21 21 #
22 22 #
23 23 # Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 #
25 25 # Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T.
26 26 # All rights reserved.
27 27 #
28 28
29 29 NET_INADDR_ANY="0.0.0.0"
30 30 NET_IN6ADDR_ANY_INIT="::0"
31 31
32 32 # Print warnings to console
33 33 warn_failed_ifs() {
34 34 echo "Failed to $1 interface(s):$2" >/dev/msglog
35 35 }
36 36
37 37 #
38 38 # shcat file
39 39 # Simulates cat in sh so it doesn't need to be on the root filesystem.
40 40 #
41 41 shcat() {
42 42 while [ $# -ge 1 ]; do
43 43 while read i; do
44 44 echo "$i"
45 45 done < $1
46 46 shift
47 47 done
48 48 }
49 49
50 50 net_record_err()
51 51 {
52 52 message=$1
53 53 err=$2
54 54
55 55 echo "$message" | smf_console
56 56 if [ $err -ne 0 ]; then
57 57 echo "Error code = $err" | smf_console
58 58 fi
59 59 }
60 60
61 61 #
62 62 # inet_list list of IPv4 interfaces.
63 63 # inet6_list list of IPv6 interfaces.
64 64 # ipmp_list list of IPMP IPv4 interfaces.
65 65 # ipmp6_list list of IPMP IPv6 interfaces.
66 66 # inet_plumbed list of plumbed IPv4 interfaces.
67 67 # inet6_plumbed list of plumbed IPv6 interfaces.
68 68 # ipmp_created list of created IPMP IPv4 interfaces.
69 69 # ipmp6_created list of created IPMP IPv6 interfaces.
70 70 # inet_failed list of IPv4 interfaces that failed to plumb.
71 71 # inet6_failed list of IPv6 interfaces that failed to plumb.
72 72 # ipmp_failed list of IPMP IPv4 interfaces that failed to be created.
73 73 # ipmp6_failed list of IPMP IPv6 interfaces that failed to be created.
74 74 #
75 75 unset inet_list inet_plumbed inet_failed \
76 76 inet6_list inet6_plumbed inet6_failed \
77 77 ipmp_list ipmp_created ipmp_failed \
78 78 ipmp6_list ipmp6_created ipmp6_failed
79 79
80 80 #
81 81 # get_physical interface
82 82 #
83 83 # Return physical interface corresponding to the given interface.
84 84 #
85 85 get_physical()
86 86 {
87 87 ORIGIFS="$IFS"
88 88 IFS="${IFS}:"
89 89 set -- $1
90 90 IFS="$ORIGIFS"
91 91
92 92 echo $1
93 93 }
94 94
95 95 #
96 96 # get_logical interface
97 97 #
98 98 # Return logical interface number. Zero will be returned
99 99 # if there is no explicit logical number.
100 100 #
101 101 get_logical()
102 102 {
103 103 ORIGIFS="$IFS"
104 104 IFS="${IFS}:"
105 105 set -- $1
106 106 IFS="$ORIGIFS"
107 107
108 108 if [ -z "$2" ]; then
109 109 echo 0
110 110 else
111 111 echo $2
112 112 fi
113 113 }
114 114
115 115 #
116 116 # if_comp if1 if2
117 117 #
118 118 # Compare interfaces. Do the physical interface names and logical interface
119 119 # numbers match?
120 120 #
121 121 if_comp()
122 122 {
123 123 physical_comp $1 $2 && [ `get_logical $1` -eq `get_logical $2` ]
124 124 }
125 125
126 126 #
127 127 # physical_comp if1 if2
128 128 #
129 129 # Do the two interfaces share a physical interface?
130 130 #
131 131 physical_comp()
132 132 {
133 133 [ "`get_physical $1`" = "`get_physical $2`" ]
134 134 }
135 135
136 136 #
137 137 # in_list op item list
138 138 #
139 139 # Is "item" in the given list? Use "op" to do the test, applying it to
140 140 # "item" and each member of the list in turn until it returns success.
141 141 #
142 142 in_list()
143 143 {
144 144 op=$1
145 145 item=$2
146 146 shift 2
147 147
148 148 while [ $# -gt 0 ]; do
149 149 $op $item $1 && return 0
150 150 shift
151 151 done
152 152
153 153 return 1
154 154 }
155 155
156 156 #
157 157 # get_groupifname groupname
158 158 #
159 159 # Return the IPMP meta-interface name for the group, if it exists.
160 160 #
161 161 get_groupifname()
162 162 {
163 163 /sbin/ipmpstat -gP -o groupname,group | while IFS=: read name ifname; do
164 164 if [ "$name" = "$1" ]; then
165 165 echo "$ifname"
166 166 return
167 167 fi
168 168 done
169 169 }
170 170
171 171 #
172 172 # create_ipmp ifname groupname type
173 173 #
174 174 # Helper function for create_groupifname() that returns zero if it's able
175 175 # to create an IPMP interface of the specified type and place it in the
176 176 # specified group, or non-zero otherwise.
177 177 #
178 178 create_ipmp()
179 179 {
180 180 /sbin/ifconfig $1 >/dev/null 2>&1 && return 1
181 181 /sbin/ifconfig $1 inet6 >/dev/null 2>&1 && return 1
182 182 /sbin/ifconfig $1 $3 ipmp group $2 2>/dev/null
183 183 }
184 184
185 185 #
186 186 # create_groupifname groupname type
187 187 #
188 188 # Create an IPMP meta-interface name for the group. We only use this
189 189 # function if all of the interfaces in the group failed at boot and there
190 190 # were no /etc/hostname[6].<if> files for the IPMP meta-interface.
191 191 #
192 192 create_groupifname()
193 193 {
194 194 #
195 195 # This is a horrible way to count from 0 to 999, but in sh and
196 196 # without necessarily having /usr mounted, what else can we do?
197 197 #
198 198 for a in "" 1 2 3 4 5 6 7 8 9; do
199 199 for b in 0 1 2 3 4 5 6 7 8 9; do
200 200 for c in 0 1 2 3 4 5 6 7 8 9; do
201 201 # strip leading zeroes
202 202 [ "$a" = "" ] && [ "$b" = 0 ] && b=""
203 203 if create_ipmp ipmp$a$b$c $1 $2; then
204 204 echo ipmp$a$b$c
205 205 return
206 206 fi
207 207 done
208 208 done
209 209 done
210 210 }
211 211
212 212 #
213 213 # get_hostname_ipmpinfo interface type
214 214 #
215 215 # Return all requested IPMP keywords from hostname file for a given interface.
216 216 #
217 217 # Example:
218 218 # get_hostname_ipmpinfo hme0 inet keyword [ keyword ... ]
219 219 #
220 220 get_hostname_ipmpinfo()
221 221 {
222 222 case "$2" in
223 223 inet) file=/etc/hostname.$1
224 224 ;;
225 225 inet6) file=/etc/hostname6.$1
226 226 ;;
227 227 *)
228 228 return
229 229 ;;
230 230 esac
231 231
232 232 [ -r "$file" ] || return
233 233
234 234 type=$2
235 235 shift 2
236 236
237 237 #
238 238 # Read through the hostname file looking for the specified
239 239 # keywords. Since there may be several keywords that cancel
240 240 # each other out, the caller must post-process as appropriate.
241 241 #
242 242 while read line; do
243 243 [ -z "$line" ] && continue
244 244 /sbin/ifparse -s "$type" $line
245 245 done < "$file" | while read one two; do
246 246 for keyword in "$@"; do
247 247 [ "$one" = "$keyword" ] && echo "$one $two"
248 248 done
249 249 done
250 250 }
251 251
252 252 #
253 253 # get_group_for_type interface type list
254 254 #
255 255 # Look through the set of hostname files associated with the same physical
256 256 # interface as "interface", and determine which group they would configure.
257 257 # Only hostname files associated with the physical interface or logical
258 258 # interface zero are allowed to set the group.
259 259 #
260 260 get_group_for_type()
261 261 {
262 262 physical=`get_physical $1`
263 263 type=$2
264 264 group=""
265 265
266 266 #
267 267 # The last setting of the group is the one that counts, which is
268 268 # the reason for the second while loop.
269 269 #
270 270 shift 2
271 271 for ifname in "$@"; do
272 272 if if_comp "$physical" $ifname; then
273 273 get_hostname_ipmpinfo $ifname $type group
274 274 fi
275 275 done | while :; do
276 276 read keyword grname || {
277 277 echo "$group"
278 278 break
279 279 }
280 280 group="$grname"
281 281 done
282 282 }
283 283
284 284 #
285 285 # get_group interface
286 286 #
287 287 # If there is both an inet and inet6 version of an interface, the group
288 288 # could be set in either set of hostname files. Since inet6 is configured
289 289 # after inet, if there's a setting in both files, inet6 wins.
290 290 #
291 291 get_group()
292 292 {
293 293 group=`get_group_for_type $1 inet6 $inet6_list`
294 294 [ -z "$group" ] && group=`get_group_for_type $1 inet $inet_list`
295 295 echo $group
296 296 }
297 297
298 298 #
299 299 # Given the interface name and the address family (inet or inet6), determine
300 300 # whether this is a VRRP VNIC.
301 301 #
302 302 # This is used to determine whether to bring the interface up
303 303 #
304 304 not_vrrp_interface() {
305 305 macaddrtype=`/sbin/dladm show-vnic $1 -o MACADDRTYPE -p 2>/dev/null`
306 306
307 307 case "$macaddrtype" in
308 308 'vrrp'*''$2'') vrrp=1
309 309 ;;
310 310 *) vrrp=0
311 311 ;;
312 312 esac
313 313 return $vrrp
314 314 }
315 315
316 316 # doDHCPhostname interface
317 317 # Pass to this function the name of an interface. It will return
318 318 # true if one should enable the use of DHCP client-side host name
319 319 # requests on the interface, and false otherwise.
320 320 #
321 321 doDHCPhostname()
322 322 {
323 323 if [ -f /etc/dhcp.$1 ] && [ -f /etc/hostname.$1 ]; then
324 324 set -- `shcat /etc/hostname.$1`
325 325 [ $# -eq 2 -a "$1" = "inet" ]
326 326 return $?
327 327 fi
328 328 return 1
329 329 }
330 330
331 331 #
332 332 # inet_process_hostname processor [ args ]
333 333 #
334 334 # Process an inet hostname file. The contents of the file
335 335 # are taken from standard input. Each line is passed
336 336 # on the command line to the "processor" command.
337 337 # Command line arguments can be passed to the processor.
338 338 #
339 339 # Examples:
340 340 # inet_process_hostname /sbin/ifconfig hme0 < /etc/hostname.hme0
341 341 #
342 342 # inet_process_hostname /sbin/ifparse -f < /etc/hostname.hme0
343 343 #
344 344 # If there is only line in an hostname file we assume it contains
345 345 # the old style address which results in the interface being brought up
346 346 # and the netmask and broadcast address being set ($inet_oneline_epilogue).
347 347 #
348 348 # Note that if the interface is a VRRP interface, do not bring the address
349 349 # up ($inet_oneline_epilogue_no_up).
350 350 #
351 351 # If there are multiple lines we assume the file contains a list of
352 352 # commands to the processor with neither the implied bringing up of the
353 353 # interface nor the setting of the default netmask and broadcast address.
354 354 #
355 355 # Return non-zero if any command fails so that the caller may alert
356 356 # users to errors in the configuration.
357 357 #
358 358 inet_oneline_epilogue_no_up="netmask + broadcast +"
359 359 inet_oneline_epilogue="netmask + broadcast + up"
360 360
361 361 inet_process_hostname()
362 362 {
363 363 if doDHCPhostname $2; then
364 364 :
365 365 else
366 366 #
367 367 # Redirecting input from a file results in a sub-shell being
368 368 # used, hence this outer loop surrounding the "multiple_lines"
369 369 # and "ifcmds" variables.
370 370 #
371 371 while :; do
372 372 multiple_lines=false
373 373 ifcmds=""
374 374 retval=0
375 375
376 376 while read one rest; do
377 377 if [ -n "$ifcmds" ]; then
378 378 #
379 379 # This handles the first N-1
380 380 # lines of a N-line hostname file.
381 381 #
382 382 $* $ifcmds || retval=$?
383 383 multiple_lines=true
384 384 fi
385 385
386 386 #
387 387 # Strip out the "ipmp" keyword if it's the
388 388 # first token, since it's used to control
389 389 # interface creation, not configuration.
390 390 #
391 391 [ "$one" = ipmp ] && one=
392 392 ifcmds="$one $rest"
393 393 done
394 394
395 395 #
396 396 # If the hostname file is empty or consists of only
397 397 # blank lines, break out of the outer loop without
398 398 # configuring the newly plumbed interface.
399 399 #
400 400 [ -z "$ifcmds" ] && return $retval
401 401 if [ $multiple_lines = false ]; then
402 402 #
403 403 # The traditional one-line hostname file.
404 404 # Note that we only bring it up if the
405 405 # interface is not a VRRP VNIC.
406 406 #
407 407 if not_vrrp_interface $2 $3; then
408 408 estr="$inet_oneline_epilogue"
409 409 else
410 410 estr="$inet_oneline_epilogue_no_up"
411 411 fi
412 412 ifcmds="$ifcmds $estr"
413 413 fi
414 414
415 415 #
416 416 # This handles either the single-line case or
417 417 # the last line of the N-line case.
418 418 #
419 419 $* $ifcmds || return $?
420 420 return $retval
421 421 done
422 422 fi
423 423 }
424 424
425 425 #
426 426 # inet6_process_hostname processor [ args ]
427 427 #
428 428 # Process an inet6 hostname file. The contents of the file
429 429 # are taken from standard input. Each line is passed
430 430 # on the command line to the "processor" command.
431 431 # Command line arguments can be passed to the processor.
432 432 #
433 433 # Examples:
434 434 # inet6_process_hostname /sbin/ifconfig hme0 inet6 < /etc/hostname6.hme0
435 435 #
436 436 # inet6_process_hostname /sbin/ifparse -f inet6 < /etc/hostname6.hme0
437 437 #
438 438 # Return non-zero if any of the commands fail so that the caller may alert
439 439 # users to errors in the configuration.
440 440 #
441 441 inet6_process_hostname()
442 442 {
443 443 retval=0
444 444 while read one rest; do
445 445 #
446 446 # See comment in inet_process_hostname for details.
447 447 #
448 448 [ "$one" = ipmp ] && one=
449 449 ifcmds="$one $rest"
450 450
451 451 if [ -n "$ifcmds" ]; then
452 452 $* $ifcmds || retval=$?
453 453 fi
454 454 done
455 455 return $retval
456 456 }
457 457
458 458 #
459 459 # Process interfaces that failed to plumb. Find the IPMP meta-interface
460 460 # that should host the addresses. For IPv6, only static addresses defined
461 461 # in hostname6 files are moved, autoconfigured addresses are not moved.
462 462 #
463 463 # Example:
464 464 # move_addresses inet6
465 465 #
466 466 move_addresses()
467 467 {
468 468 type="$1"
469 469 eval "failed=\"\$${type}_failed\""
470 470 eval "list=\"\$${type}_list\""
471 471 process_func="${type}_process_hostname"
472 472 processed=""
473 473
474 474 if [ "$type" = inet ]; then
475 475 typedesc="IPv4"
476 476 zaddr="0.0.0.0"
477 477 hostpfx="/etc/hostname"
478 478 else
479 479 typedesc="IPv6"
480 480 zaddr="::"
481 481 hostpfx="/etc/hostname6"
482 482 fi
483 483
484 484 echo "Moving addresses from missing ${typedesc} interface(s):\c" \
485 485 >/dev/msglog
486 486
487 487 for ifname in $failed; do
488 488 in_list if_comp $ifname $processed && continue
489 489
490 490 group=`get_group $ifname`
491 491 if [ -z "$group" ]; then
492 492 in_list physical_comp $ifname $processed || {
493 493 echo " $ifname (not moved -- not" \
494 494 "in an IPMP group)\c" >/dev/msglog
495 495 processed="$processed $ifname"
496 496 }
497 497 continue
498 498 fi
499 499
500 500 #
501 501 # Lookup the IPMP meta-interface name. If one doesn't exist,
502 502 # create it.
503 503 #
504 504 grifname=`get_groupifname $group`
505 505 [ -z "$grifname" ] && grifname=`create_groupifname $group $type`
506 506
507 507 #
508 508 # The hostname files are processed twice. In the first
509 509 # pass, we are looking for all commands that apply to the
510 510 # non-additional interface address. These may be
511 511 # scattered over several files. We won't know whether the
512 512 # address represents a failover address or not until we've
513 513 # read all the files associated with the interface.
514 514 #
515 515 # In the first pass through the hostname files, all
516 516 # additional logical interface commands are removed. The
517 517 # remaining commands are concatenated together and passed
518 518 # to ifparse to determine whether the non-additional
519 519 # logical interface address is a failover address. If it
520 520 # as a failover address, the address may not be the first
521 521 # item on the line, so we can't just substitute "addif"
522 522 # for "set". We prepend an "addif $zaddr" command, and
523 523 # let the embedded "set" command set the address later.
524 524 #
525 525 /sbin/ifparse -f $type `
526 526 for item in $list; do
527 527 if_comp $ifname $item && $process_func \
528 528 /sbin/ifparse $type < $hostpfx.$item
529 529 done | while read three four; do
530 530 [ "$three" != addif ] && echo "$three $four \c"
531 531 done` | while read one two; do
532 532 [ -z "$one" ] && continue
533 533 [ "$one $two" = "$inet_oneline_epilogue" ] && \
534 534 continue
535 535 line="addif $zaddr $one $two"
536 536 /sbin/ifconfig $grifname $type $line >/dev/null
537 537 done
538 538
539 539 #
540 540 # In the second pass, look for the the "addif" commands
541 541 # that configure additional failover addresses. Addif
542 542 # commands are not valid in logical interface hostname
543 543 # files.
544 544 #
545 545 if [ "$ifname" = "`get_physical $ifname`" ]; then
546 546 $process_func /sbin/ifparse -f $type < $hostpfx.$ifname \
547 547 | while read one two; do
548 548 [ "$one" = addif ] && \
549 549 /sbin/ifconfig $grifname $type \
550 550 addif $two >/dev/null
551 551 done
552 552 fi
553 553
554 554 in_list physical_comp $ifname $processed || {
555 555 processed="$processed $ifname"
556 556 echo " $ifname (moved to $grifname)\c" > /dev/msglog
557 557 }
558 558 done
559 559 echo "." >/dev/msglog
560 560 }
561 561
562 562 #
563 563 # ipadm_from_gz_if ifname
564 564 #
565 565 # Return true if we are in a non-global zone and Layer-3 protection of
566 566 # IP addresses is being enforced on the interface by the global zone
567 567 #
568 568 ipadm_from_gz_if()
569 569 {
570 570 pif=`/sbin/ipadm show-if -o persistent -p $1 2>/dev/null | egrep '4|6'`
571 571 if smf_is_globalzone || ![[ $pif == *4* || $pif == *6* ]]; then
572 572 return 1
573 573 else
574 574 #
575 575 # In the non-global zone, plumb the interface to show current
576 576 # flags and check if Layer-3 protection has been enforced by
577 577 # the global zone. Note that this function may return
578 578 # with a plumbed interface. Ideally, we would not have to
579 579 # plumb the interface to check l3protect, but since we
580 580 # the `allowed-ips' datalink property cannot currently be
581 581 # examined in any other way from the non-global zone, we
582 582 # resort to plumbing the interface
583 583 #
584 584 /sbin/ifconfig $1 plumb > /dev/null 2>&1
585 585 l3protect=`/sbin/ipadm show-if -o current -p $1|grep -c 'Z'`
586 586 if [ $l3protect = 0 ]; then
587 587 return 1
588 588 else
589 589 return 0
590 590 fi
591 591 fi
592 592 }
593 593
594 594 #
595 595 # if_configure type class interface_list
596 596 #
597 597 # Configure all of the interfaces of type `type' (e.g., "inet6") in
598 598 # `interface_list' according to their /etc/hostname[6].* files. `class'
599 599 # describes the class of interface (e.g., "IPMP"), as a diagnostic aid.
600 600 # For inet6 interfaces, the interface is also brought up.
601 601 #
602 602 if_configure()
603 603 {
604 604 fail=
605 605 type=$1
606 606 class=$2
607 607 process_func=${type}_process_hostname
608 608 shift 2
609 609
610 610 if [ "$type" = inet ]; then
611 611 desc="IPv4"
612 612 hostpfx="/etc/hostname"
613 613 else
614 614 desc="IPv6"
615 615 hostpfx="/etc/hostname6"
616 616 fi
617 617 [ -n "$class" ] && desc="$class $desc"
618 618
619 619 echo "configuring $desc interfaces:\c"
620 620 while [ $# -gt 0 ]; do
621 621 $process_func /sbin/ifconfig $1 $type < $hostpfx.$1 >/dev/null
622 622 if [ $? != 0 ]; then
623 623 ipadm_from_gz_if $1
624 624 if [ $? != 0 ]; then
625 625 fail="$fail $1"
626 626 fi
627 627 elif [ "$type" = inet6 ]; then
628 628 #
629 629 # only bring the interface up if it is not a
630 630 # VRRP VNIC
631 631 #
632 632 if not_vrrp_interface $1 $type; then
633 633 /sbin/ifconfig $1 inet6 up || fail="$fail $1"
634 634 fi
635 635 fi
636 636 echo " $1\c"
637 637 shift
638 638 done
639 639 echo "."
640 640
641 641 [ -n "$fail" ] && warn_failed_ifs "configure $desc" "$fail"
642 642 }
643 643
644 644 #
645 645 # net_reconfigure is called from the network/physical service (by the
646 646 # net-physical and net-nwam method scripts) to perform tasks that only
647 647 # need to be done during a reconfigure boot. This needs to be
648 648 # isolated in a function since network/physical has two instances
649 649 # (default and nwam) that have distinct method scripts that each need
650 650 # to do these things.
651 651 #
652 652 net_reconfigure ()
653 653 {
654 654 #
655 655 # Is this a reconfigure boot? If not, then there's nothing
656 656 # for us to do.
657 657 #
658 658 reconfig=`svcprop -c -p system/reconfigure \
659 659 system/svc/restarter:default 2>/dev/null`
660 660 if [ $? -ne 0 -o "$reconfig" = false ]; then
661 661 return 0
662 662 fi
663 663
664 664 #
665 665 # Ensure that the datalink-management service is running since
666 666 # manifest-import has not yet run for a first boot after
667 667 # upgrade. We wouldn't need to do that if manifest-import ran
668 668 # earlier in boot, since there is an explicit dependency
669 669 # between datalink-management and network/physical.
670 670 #
671 671 svcadm enable -ts network/datalink-management:default
672 672
673 673 #
674 674 # There is a bug in SMF which causes the svcadm command above
675 675 # to exit prematurely (with an error code of 3) before having
676 676 # waited for the service to come online after having enabled
677 677 # it. Until that bug is fixed, we need to have the following
678 678 # loop to explicitly wait for the service to come online.
679 679 #
680 680 i=0
681 681 while [ $i -lt 30 ]; do
682 682 i=`expr $i + 1`
683 683 sleep 1
684 684 state=`svcprop -p restarter/state \
685 685 network/datalink-management:default 2>/dev/null`
686 686 if [ $? -ne 0 ]; then
687 687 continue
688 688 elif [ "$state" = "online" ]; then
689 689 break
690 690 fi
691 691 done
692 692 if [ "$state" != "online" ]; then
693 693 echo "The network/datalink-management service \c"
694 694 echo "did not come online."
695 695 return 1
696 696 fi
697 697
698 698 #
699 699 # Initialize the set of physical links, and validate and
700 700 # remove all the physical links which were removed during the
701 701 # system shutdown.
702 702 #
703 703 /sbin/dladm init-phys
704 704 return 0
705 705 }
706 706
707 707 #
708 708 # Check for use of the default "Port VLAN Identifier" (PVID) -- VLAN 1.
709 709 # If there is one for a given interface, then warn the user and force the
710 710 # PVID to zero (if it's not already set). We do this by generating a list
711 711 # of interfaces with VLAN 1 in use first, and then parsing out the
712 712 # corresponding base datalink entries to check for ones without a
713 713 # "default_tag" property.
714 714 #
715 715 update_pvid()
716 716 {
717 717 datalink=/etc/dladm/datalink.conf
718 718
719 719 (
720 720 # Find datalinks using VLAN 1 explicitly
721 721 # configured by dladm
722 722 /usr/bin/nawk '
723 723 /^#/ || NF < 2 { next }
724 724 { linkdata[$1]=$2; }
725 725 /;vid=int,1;/ {
726 726 sub(/.*;linkover=int,/, "", $2);
727 727 sub(/;.*/, "", $2);
728 728 link=linkdata[$2];
729 729 sub(/name=string,/, "", link);
730 730 sub(/;.*/, "", link);
731 731 print link;
732 732 }' $datalink
733 733 ) | ( /usr/bin/sort -u; echo END; cat $datalink ) | /usr/bin/nawk '
734 734 /^END$/ { state=1; }
735 735 state == 0 { usingpvid[++nusingpvid]=$1; next; }
736 736 /^#/ || NF < 2 { next; }
737 737 {
738 738 # If it is already present and has a tag set,
739 739 # then believe it.
740 740 if (!match($2, /;default_tag=/))
741 741 next;
742 742 sub(/name=string,/, "", $2);
743 743 sub(/;.*/, "", $2);
744 744 for (i = 1; i <= nusingpvid; i++) {
745 745 if (usingpvid[i] == $2)
746 746 usingpvid[i]="";
747 747 }
748 748 }
749 749 END {
750 750 for (i = 1; i <= nusingpvid; i++) {
751 751 if (usingpvid[i] != "") {
752 752 printf("Warning: default VLAN tag set to 0" \
753 753 " on %s\n", usingpvid[i]);
754 754 cmd=sprintf("dladm set-linkprop -p " \
755 755 "default_tag=0 %s\n", usingpvid[i]);
756 756 system(cmd);
757 757 }
758 758 }
759 759 }'
760 760 }
761 761
762 762 #
763 763 # service_exists fmri
764 764 #
765 765 # returns success (0) if the service exists, 1 otherwise.
766 766 #
767 767 service_exists()
768 768 {
769 769 /usr/sbin/svccfg -s $1 listpg > /dev/null 2>&1
770 770 if [ $? -eq 0 ]; then
771 771 return 0;
772 772 fi
773 773 return 1;
774 774 }
775 775
776 776 #
777 777 # service_is_enabled fmri
778 778 #
779 779 # returns success (0) if the service is enabled (permanently or
780 780 # temporarily), 1 otherwise.
781 781 #
782 782 service_is_enabled()
783 783 {
784 784 #
785 785 # The -c option must be specified to use the composed view
786 786 # because the general/enabled property takes immediate effect.
787 787 # See Example 2 in svcprop(1).
788 788 #
789 789 # Look at the general_ovr/enabled (if it is present) first to
790 790 # determine the temporarily enabled state.
791 791 #
792 792 tstate=`/usr/bin/svcprop -c -p general_ovr/enabled $1 2>/dev/null`
793 793 if [ $? -eq 0 ]; then
794 794 [ "$tstate" = "true" ] && return 0
795 795 return 1
796 796 fi
797 797
798 798 state=`/usr/bin/svcprop -c -p general/enabled $1 2>/dev/null`
799 799 [ "$state" = "true" ] && return 0
800 800 return 1
801 801 }
802 802
803 803 #
804 804 # is_valid_v4addr addr
805 805 #
806 806 # Returns 0 if a valid IPv4 address is given, 1 otherwise.
807 807 #
808 808 is_valid_v4addr()
809 809 {
810 810 echo $1 | /usr/xpg4/bin/awk 'NF != 1 { exit 1 } \
811 811 $1 !~ /^((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}\
812 812 (25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])$/ \
813 813 { exit 1 }'
814 814 return $?
815 815 }
816 816
817 817 #
818 818 # is_valid_v6addr addr
819 819 #
820 820 # Returns 0 if a valid IPv6 address is given, 1 otherwise.
821 821 #
822 822 is_valid_v6addr()
823 823 {
824 824 echo $1 | /usr/xpg4/bin/awk 'NF != 1 { exit 1 } \
825 825 # 1:2:3:4:5:6:7:8
826 826 $1 !~ /^([a-fA-F0-9]{1,4}:){7}[a-fA-F0-9]{1,4}$/ &&
827 827 # 1:2:3::6:7:8
828 828 $1 !~ /^([a-fA-F0-9]{1,4}:){0,6}:([a-fA-F0-9]{1,4}:){0,6}\
829 829 [a-fA-F0-9]{1,4}$/ &&
830 830 # 1:2:3::
831 831 $1 !~ /^([a-fA-F0-9]{1,4}:){0,7}:$/ &&
832 832 # ::7:8
833 833 $1 !~ /^:(:[a-fA-F0-9]{1,4}){0,6}:[a-fA-F0-9]{1,4}$/ &&
834 834 # ::f:1.2.3.4
835 835 $1 !~ /^:(:[a-fA-F0-9]{1,4}){0,5}:\
836 836 ((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}\
837 837 (25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])$/ &&
838 838 # a:b:c:d:e:f:1.2.3.4
839 839 $1 !~ /^([a-fA-F0-9]{1,4}:){6}\
840 840 ((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}\
841 841 (25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])$/ \
842 842 { exit 1 }'
843 843 return $?
844 844 }
845 845
846 846 #
847 847 # is_valid_addr addr
848 848 #
849 849 # Returns 0 if a valid IPv4 or IPv6 address is given, 1 otherwise.
850 850 #
851 851 is_valid_addr()
852 852 {
853 853 is_valid_v4addr $1 || is_valid_v6addr $1
854 854 }
855 855
856 856 #
857 857 # nwam_get_loc_prop location property
858 858 #
859 859 # echoes the value of the property for the given location
860 860 # return:
861 861 # 0 => property is set
862 862 # 1 => property is not set
863 863 #
864 864 nwam_get_loc_prop()
865 865 {
866 866 value=`/usr/sbin/nwamcfg "select loc $1; get -V $2" 2>/dev/null`
867 867 rtn=$?
868 868 echo $value
869 869 return $rtn
870 870 }
871 871
872 872 #
873 873 # nwam_get_loc_list_prop location property
874 874 #
875 875 # echoes a space-separated list of the property values for the given location
876 876 # return:
877 877 # 0 => property is set
878 878 # 1 => property is not set
879 879 #
880 880 nwam_get_loc_list_prop()
881 881 {
882 882 clist=`/usr/sbin/nwamcfg "select loc $1; get -V $2" 2>/dev/null`
883 883 rtn=$?
884 884 #
885 885 # nwamcfg gives us a comma-separated list;
886 886 # need to convert commas to spaces.
887 887 #
888 888 slist=`echo $clist | sed -e s/","/" "/g`
889 889 echo $slist
890 890 return $rtn
891 891 }
↓ open down ↓ |
880 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX