diff options
Diffstat (limited to 'usr/src')
| -rw-r--r-- | usr/src/cmd/cmd-inet/usr.lib/in.mpathd/mpd_main.c | 151 | ||||
| -rw-r--r-- | usr/src/cmd/cmd-inet/usr.lib/in.mpathd/mpd_tables.c | 33 | ||||
| -rw-r--r-- | usr/src/cmd/cmd-inet/usr.lib/in.mpathd/mpd_tables.h | 11 |
3 files changed, 82 insertions, 113 deletions
diff --git a/usr/src/cmd/cmd-inet/usr.lib/in.mpathd/mpd_main.c b/usr/src/cmd/cmd-inet/usr.lib/in.mpathd/mpd_main.c index 4af1cb99b9..e7157dc630 100644 --- a/usr/src/cmd/cmd-inet/usr.lib/in.mpathd/mpd_main.c +++ b/usr/src/cmd/cmd-inet/usr.lib/in.mpathd/mpd_main.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -549,21 +548,6 @@ check_addr_unique(int af, char *name) } /* - * The pii_probe_logint used for probing, must satisfy the following properties - * with respect to its li_flags. - * IFF_NOFAILOVER - must be set (except in singleton group case) - * IFF_UP - must be set - * IFF_NOXMIT - must be clear - * IFF_NOLOCAL - must be clear - * IFF_DEPRECATED - preferably set (for IPv4) - */ -#define BEST_FLAG_SET (IFF_NOFAILOVER | IFF_UP | IFF_DEPRECATED) -#define CLEAR_FLAG_SET (IFF_NOXMIT | IFF_NOLOCAL) -#define TEST_CLEAR_FLAG_SET CLEAR_FLAG_SET -#define TEST_MINIMAL_FLAG_SET (IFF_UP | CLEAR_FLAG_SET) -#define TEST_BEST_FLAG_SET (BEST_FLAG_SET | CLEAR_FLAG_SET) - -/* * Stop probing an interface. Called when an interface is offlined. * The probe socket is closed on each interface instance, and the * interface state set to PI_OFFLINE. @@ -590,13 +574,36 @@ stop_probing(struct phyint *pi) phyint_chstate(pi, PI_OFFLINE); } +enum { BAD_TESTFLAGS, OK_TESTFLAGS, BEST_TESTFLAGS }; + +/* + * Rate the provided test flags. By definition, IFF_NOFAILOVER must be set. + * IFF_UP must also be set so that the associated address can be used as a + * source address. Further, we must be able to exchange packets with local + * destinations, so IFF_NOXMIT and IFF_NOLOCAL must be clear. For historical + * reasons, we have a proclivity for IFF_DEPRECATED IPv4 test addresses. + */ +static int +rate_testflags(uint64_t flags) +{ + if ((flags & (IFF_NOFAILOVER | IFF_UP)) != (IFF_NOFAILOVER | IFF_UP)) + return (BAD_TESTFLAGS); + + if ((flags & (IFF_NOXMIT | IFF_NOLOCAL)) != 0) + return (BAD_TESTFLAGS); + + if ((flags & (IFF_IPV6 | IFF_DEPRECATED)) == IFF_DEPRECATED) + return (BEST_TESTFLAGS); + + if ((flags & (IFF_IPV6 | IFF_DEPRECATED)) == IFF_IPV6) + return (BEST_TESTFLAGS); + + return (OK_TESTFLAGS); +} + /* - * Do the test address selection for each phyint instance. Pick an - * IFF_NOFAILOVER address as test address. For singleton case, - * if user didn't configure an IFF_NOFAILOVER address, we will pick a - * normal address as test address. For (multiple adapter) groups, - * user is required to configure IFF_NOFAILOVER test address. Call - * phyint_inst_sockinit() to complete the initializations. + * Attempt to select a test address for each phyint instance. + * Call phyint_inst_sockinit() to complete the initializations. */ static void select_test_ifs(void) @@ -604,10 +611,11 @@ select_test_ifs(void) struct phyint *pi; struct phyint_instance *pii; struct phyint_instance *next_pii; - struct logint *li; - struct logint *test_logint; - boolean_t target_scan_reqd = _B_FALSE; - struct target *tg; + struct logint *li; + struct logint *probe_logint; + boolean_t target_scan_reqd = _B_FALSE; + struct target *tg; + int rating; if (debug & D_PHYINT) logdebug("select_test_ifs\n"); @@ -617,6 +625,8 @@ select_test_ifs(void) */ for (pii = phyint_instances; pii != NULL; pii = next_pii) { next_pii = pii->pii_next; + probe_logint = NULL; + /* * An interface that is offline, should not be probed. * Offline interfaces should always in PI_OFFLINE state, @@ -634,24 +644,14 @@ select_test_ifs(void) continue; } - test_logint = pii->pii_probe_logint; - - if (test_logint != NULL) { - if ((test_logint->li_flags & TEST_BEST_FLAG_SET) - == BEST_FLAG_SET) - continue; - + li = pii->pii_probe_logint; + if (li != NULL) { /* - * If user configures IFF_NOXMIT or IFF_NOLOCAL - * flags on test addresses after in.mpathd has - * has started, the daemon aborts. In future - * this can be better handling, i.e. instead - * of abort the daemon, a more appropriate - * action may be issuing a warning and choose - * a different test address. + * We've already got a test address; only proceed + * if it's suboptimal. */ - assert((test_logint->li_flags & TEST_CLEAR_FLAG_SET) - == 0); + if (rate_testflags(li->li_flags) == BEST_TESTFLAGS) + continue; } /* @@ -668,51 +668,31 @@ select_test_ifs(void) !IN6_IS_ADDR_LINKLOCAL(&li->li_addr)) continue; - if ((li->li_flags & TEST_MINIMAL_FLAG_SET) == IFF_UP) { - /* - * Now we have a testaddress, that satisfies - * the minimal properties. - */ - if ((li->li_flags & TEST_BEST_FLAG_SET) - == BEST_FLAG_SET) { - /* - * This is the best possible address. - * So break, and continue to the - * next phyint - */ - test_logint = li; - break; - } - if ((test_logint == NULL) || - (!(test_logint->li_flags & - IFF_NOFAILOVER) && - (li->li_flags & IFF_NOFAILOVER))) - /* - * This is a possible candidate, - * unless we find a better one. - */ - test_logint = li; - } + /* + * Rate the testflags. If we've found an optimal + * match, then break out; otherwise, record the most + * recent OK one. + */ + rating = rate_testflags(li->li_flags); + if (rating == BAD_TESTFLAGS) + continue; + + probe_logint = li; + if (rating == BEST_TESTFLAGS) + break; } /* - * If we've gone from a singleton group to a multiple adapter - * group, and we haven't found an IFF_NOFAILOVER test address - * by now, the old test address is no longer valid. If we are - * not dealing with a singleton group, and the above test - * address selection loop has selected a non IFF_NOFAILOVER - * address as a candidate, we will correct that here. + * If the probe logint has changed, ditch the old one. */ - if ((test_logint != NULL) && - !SINGLETON_GROUP(pii->pii_phyint) && - !(test_logint->li_flags & IFF_NOFAILOVER)) { - test_logint = NULL; + if (pii->pii_probe_logint != NULL && + pii->pii_probe_logint != probe_logint) { if (pii->pii_probe_sock != -1) close_probe_socket(pii, _B_TRUE); pii->pii_probe_logint = NULL; } - if (test_logint == NULL) { + if (probe_logint == NULL) { /* * We don't have a test address. Don't print an * error message immediately. check_config() will @@ -728,7 +708,7 @@ select_test_ifs(void) reset_crtt_all(pii->pii_phyint); } continue; - } else if (test_logint == pii->pii_probe_logint) { + } else if (probe_logint == pii->pii_probe_logint) { /* * If we didn't find any new test addr, go to the * next phyint. @@ -741,7 +721,7 @@ select_test_ifs(void) * or is being assigned a testaddr for the 1st time. * Need to initialize the phyint socket */ - pii->pii_probe_logint = test_logint; + pii->pii_probe_logint = probe_logint; if (!phyint_inst_sockinit(pii)) { if (debug & D_PHYINT) { logdebug("select_test_ifs: " @@ -780,7 +760,7 @@ select_test_ifs(void) assert(pii->pii_targets == NULL); assert(pii->pii_target_next == NULL); assert(pii->pii_ntargets == 0); - target_create(pii, test_logint->li_dstaddr, + target_create(pii, probe_logint->li_dstaddr, _B_TRUE); } @@ -921,9 +901,6 @@ check_config(void) * been configured, notify the administrator, but continue on since we * can still perform load spreading, along with "link up/down" based * failure detection. - * - * Note: In the singleton group case, when user didn't configure - * a test address, the probe address is picked by this daemon. */ for (pi = phyints; pi != NULL; pi = pi->pi_next) { if (pi->pi_flags & IFF_OFFLINE) diff --git a/usr/src/cmd/cmd-inet/usr.lib/in.mpathd/mpd_tables.c b/usr/src/cmd/cmd-inet/usr.lib/in.mpathd/mpd_tables.c index 244566efb7..6459f5cdc1 100644 --- a/usr/src/cmd/cmd-inet/usr.lib/in.mpathd/mpd_tables.c +++ b/usr/src/cmd/cmd-inet/usr.lib/in.mpathd/mpd_tables.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -610,10 +609,10 @@ retry: } /* - * Bind the pii_probe_sock to the chosen IFF_NOFAILOVER address in - * pii_probe_logint. This socket will be used for sending and receiving - * ICMP/ICMPv6 probes to targets. Do the common part in this function, and - * complete the initializations by calling the protocol specific functions + * Bind pii_probe_sock to the address associated with pii_probe_logint. + * This socket will be used for sending and receiving ICMP/ICMPv6 probes to + * targets. Do the common part in this function, and complete the + * initializations by calling the protocol specific functions * phyint_inst_v{4,6}_sockinit() respectively. * * Return values: _B_TRUE/_B_FALSE for success or failure respectively. @@ -631,8 +630,7 @@ phyint_inst_sockinit(struct phyint_instance *pii) assert(pii->pii_probe_logint != NULL); assert(pii->pii_probe_logint->li_flags & IFF_UP); - assert(SINGLETON_GROUP(pii->pii_phyint) || - (pii->pii_probe_logint->li_flags & IFF_NOFAILOVER)); + assert(pii->pii_probe_logint->li_flags & IFF_NOFAILOVER); assert(pii->pii_af == AF_INET || pii->pii_af == AF_INET6); /* @@ -1117,8 +1115,7 @@ phyint_inst_delete(struct phyint_instance *pii) logint_delete(pii->pii_logint); /* - * Close the IFF_NOFAILOVER socket used to send probes to targets - * from this phyint. + * Close the socket used to send probes to targets from this phyint. */ if (pii->pii_probe_sock != -1) close_probe_socket(pii, _B_TRUE); @@ -1518,8 +1515,8 @@ logint_delete(struct logint *li) li->li_prev = NULL; /* - * If this logint corresponds to the IFF_NOFAILOVER testaddress of - * this phyint, then close the associated socket, if it exists + * If this logint is also being used for probing, then close the + * associated socket, if it exists. */ if (pii->pii_probe_logint == li) { if (pii->pii_probe_sock != -1) @@ -1878,10 +1875,10 @@ target_create(struct phyint_instance *pii, struct in6_addr addr, target_insert(pii, tg); /* - * Change to running state, if this phyint instance is capable of - * sending and receiving probes. i.e if we know of at least 1 target, - * and this phyint instance socket is bound to the IFF_NOFAILOVER - * address. More details in phyint state diagram in probe.c. + * Change state to PI_RUNNING if this phyint instance is capable of + * sending and receiving probes -- that is, if we know of at least 1 + * target, and this phyint instance is probe-capable. For more + * details, see the phyint state diagram in mpd_probe.c. */ pi = pii->pii_phyint; if (pi->pi_state == PI_NOTARGETS && PROBE_CAPABLE(pii)) { diff --git a/usr/src/cmd/cmd-inet/usr.lib/in.mpathd/mpd_tables.h b/usr/src/cmd/cmd-inet/usr.lib/in.mpathd/mpd_tables.h index f466c9f9a2..5d79347a3f 100644 --- a/usr/src/cmd/cmd-inet/usr.lib/in.mpathd/mpd_tables.h +++ b/usr/src/cmd/cmd-inet/usr.lib/in.mpathd/mpd_tables.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -146,10 +145,6 @@ extern "C" { FLAGS_TO_LINK_STATE(pi) ? 1 : 0) #define INIT_LINK_STATE(pi) ((pi)->pi_link_state = 1) -#define SINGLETON_GROUP(pi) ((pi) != NULL && \ - (pi)->pi_group->pg_name[0] != '\0' && \ - (pi)->pi_group->pg_phyint == (pi) && (pi)->pi_pgnext == NULL) - /* * Phyint group states; see below for the phyint group definition. */ |
