Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!

Bug 195479

Summary: use ethtool in /etc/conf.d/net
Product: Gentoo Linux Reporter: Patrick Huber <phuber>
Component: [OLD] baselayoutAssignee: OpenRC Team <openrc>
Status: RESOLVED FIXED    
Severity: enhancement CC: holger, kfm, mehmet, radek, ryan.mchugh, virtuousfox
Priority: High    
Version: unspecified   
Hardware: All   
OS: Linux   
Whiteboard: openrc:oldnet:ethtool
Package list:
Runtime testing required: ---

Description Patrick Huber 2007-10-11 08:49:21 UTC
Hi

We have some scenario where the autosensing doesn't pickup the currect duplex setting so i hacked this into my /etc/conf.d/net so we can set duplex there.

I tried to follow the existing concepts in the file.

Might be useful for other and I'd be delighted to see this in the default baselayout package...

here you go:

#eth0_speed="100"
eth0_duplex="full"

#preup() {
#}

#predown() {
#}

postup() {

        speed="${IFVAR}_speed"
        speed=( "${!speed}" )

        duplex="${IFVAR}_duplex"
        duplex=( "${!duplex}" )

        # if speed or duplex are set, autonegotiation must be turned off
        if [ -n "${speed}${duplex}" ]; then

                einfo "Setting Auto-Negotiation to off"
                ethtool -s ${IFVAR} autoneg off
                eend $?

                if [ -n "${speed}" ]; then
                        einfo "Setting Speed to ${speed}"
                        ethtool -s ${IFVAR} speed ${speed}
                        eend $?
                fi

                if [ -n "${duplex}" ]; then
                        einfo "Setting Duplex to ${duplex}"
                        ethtool -s ${IFVAR} duplex ${duplex}
                        eend $?
                fi
        fi

}

postdown() {

        # assume autoneg on is the default so switch back on if-down
        einfo "Setting Auto-Negotiation to on"
        ethtool -s ${IFVAR} autoneg on
        eend $?

}

#failup() {
#}

#faildown() {
#}


Reproducible: Always

Actual Results:  
duplex autoneg doesn't work

Expected Results:  
duplex autoneg works

use the snipped above in your /etc/conf.d/net to set a fixed duplex value.
Comment 1 toon 2009-02-14 17:10:10 UTC
Nice, I needed this, thanks!
While I was testing your code I discovered that it didn't set all options all of the time.
I assumed that this could be caused by calling ethtool several times  in succession quickly,
so I changed your script to combine all options in one call to ethtool.
Please find it below.

Oh, and I changed the variable names from ${IFVAR}_speed into speed_${IFVAR} etc.

Regards,
Toon.

preup() {
        speed="speed_${IFVAR}"
        speed=( "${!speed}" )

        duplex="duplex_${IFVAR}"
        duplex=( "${!duplex}" )

        # if speed or duplex are set, autonegotiation must be turned off
        if [ -n "${speed}${duplex}" ]; then

                ethtool_cmds="autoneg off"
                if [ -n "${speed}" ]; then
                        ethtool_cmds="${ethtool_cmds} speed ${speed}"
                fi
                if [ -n "${duplex}" ]; then
                        ethtool_cmds="${ethtool_cmds} duplex ${duplex}"
                fi
                einfo "Running ethtool ${IFVAR} ${ethtool_cmds}"
                ethtool -s ${IFVAR} ${ethtool_cmds}
                eend $?
        fi
        return 0
}
Comment 2 Sergey Kondakov 2009-05-27 17:48:07 UTC
here is the same thing but with fancy filtration of substituted options to ethtool and it also ethernet-only.
i will try to hack some more and maybe will write entire ethtool.sh for openrc

preup() {
	# function to check validity of user settings
	check_option() {
		local choice="$1"
		local match_time=0
		for i in ${available_choices}; do
			[ ${i} = "${choice}" ] && match_time=$[match_time+1]
		done

		if [ $match_time -eq 1 ]; then
			return 0
		elif [ $match_time -eq 0 ]; then
			return 1
		else
			ewarn "really strange: several choices match in one option"
			return 2
		fi
	}

	### let's have some special parameters for...
	## Ethernet
	# currently this provide autoneg_ethX, speed_ethX, duplex_ethX and wol_ethX options
	case "${IFVAR}" in
        eth? ) 	einfo "Ethernet interface ${IFVAR} detected. doing special configuration..."

		# maping interface variables to script variables
		autoneg="autoneg_${IFVAR}"
		speed="speed_${IFVAR}"
		duplex="duplex_${IFVAR}"
		wol="wol_${IFVAR}"

		# actual assigning
		autoneg=( "${!autoneg}" )
		speed=( "${!speed}" )
		duplex=( "${!speed}" )
		wol=( "${!wol}" )

        	# if speed or duplex are set, autonegotiation must be turned off
        	if [ -n "${speed}${duplex}" ]; then
                	ethtool_cmds="autoneg off"
			else
			if [ -n "${autoneg}" ]; then
				available_choices="on off"
				check_option ${autoneg} && \
					ethtool_cmds="autoneg ${autoneg}" || \
					ewarn "autoneg_${IFVAR} seems incorrectly set; correct would be: ${available_choices}"
			fi
		fi

                if [ -n "${speed}" ]; then
			available_choices="10 100 1000 2500"
			check_option ${speed} && \
                       		ethtool_cmds="${ethtool_cmds} speed ${speed}" || \
				ewarn "speed_${IFVAR} seems incorrectly set; correct would be: ${available_choices}"
                fi

                if [ -n "${duplex}" ]; then
			available_choices="half full"
			check_option ${duplex} && \
                       		ethtool_cmds="${ethtool_cmds} duplex ${duplex}" || \
				ewarn "duplex_${IFVAR} seems incorrectly set; correct would be: ${available_choices}"
                fi

		if [ -n "${wol}" ]; then
			available_choices="p u m b a g s d"
			check_option ${wol} && \
				ethtool_cmds="${ethtool_cmds} wol ${wol}" || \
				ewarn "wol_${IFVAR} seems incorrectly set; correct would be: ${available_choices}"
		fi

                einfo "Running ethtool -s ${IFVAR} ${ethtool_cmds}"
                ethtool -s ${IFVAR} ${ethtool_cmds}
                eend $?;;
	esac

        return 0
}

postdown() {
	case "${IFVAR}" in
	eth? )	# assume autoneg on is the default so switch back on if-down
        	einfo "Setting Auto-Negotiation to on"
        	ethtool -s ${IFVAR} autoneg on
        	eend $?;;
	esac

	return 0
}
Comment 3 Ryan 2009-12-15 18:04:37 UTC
modified a bit more: 
1)duplex in last example was loading val from speed :(
2)configured to only run if ethtool is available
3)does nothing if no args are passed (thus leaving alone) 
4)my system did not like changing ethtool settings while interface was down, not sure if it needs to be preup or postup for default but for me it needed to be postup and predown

updated script:

#preup() {
#}

postup() {
        # function to check validity of user settings
        ethtool=`which ethtool 2>/dev/null`
        check_option() {
                local choice="$1"
                local match_time=0
                for i in ${available_choices}; do
                        [ ${i} = "${choice}" ] && match_time=$[match_time+1]
                done

                if [ $match_time -eq 1 ]; then
                        return 0
                elif [ $match_time -eq 0 ]; then
                        return 1
                else
                        ewarn "really strange: several choices match in one option"
                        return 2
                fi
        }

        ### let's have some special parameters for...
        ## Ethernet
        # currently this provide autoneg_ethX, speed_ethX, duplex_ethX and wol_ethX options
        case "${IFVAR}" in
        eth? )
                if [ -n "${ethtool}" ]; then
                        einfo "Ethernet interface ${IFVAR} detected. doing special configuration..."


                        # maping interface variables to script variables
                        autoneg="autoneg_${IFVAR}"
                        speed="speed_${IFVAR}"
                        duplex="duplex_${IFVAR}"
                        wol="wol_${IFVAR}"
                        # actual assigning
                        autoneg=( "${!autoneg}" )
                        speed=( "${!speed}" )
                        duplex=( "${!duplex}" )
                        wol=( "${!wol}" )

                        # if speed or duplex are set, autonegotiation must be turned off
                        if [ -n "${speed}${duplex}" ]; then
                                ethtool_cmds="autoneg off"
                                else
                                if [ -n "${autoneg}" ]; then
                                        available_choices="on off"
                                        check_option ${autoneg} && \
                                                ethtool_cmds="autoneg ${autoneg}" || \
                                                ewarn "autoneg_${IFVAR} seems incorrectly set; correct would be: ${available_choices}"
                                fi
                        fi

                        if [ -n "${speed}" ]; then
                                available_choices="10 100 1000 2500"
                                check_option ${speed} && \
                                        ethtool_cmds="${ethtool_cmds} speed ${speed}" || \
                                        ewarn "speed_${IFVAR} seems incorrectly set; correct would be: ${available_choices}"
                        fi

                        if [ -n "${duplex}" ]; then
                                available_choices="half full"
                                check_option ${duplex} && \
                                        ethtool_cmds="${ethtool_cmds} duplex ${duplex}" || \
                                        ewarn "duplex_${IFVAR} seems incorrectly set; correct would be: ${available_choices}"
                        fi

                        if [ -n "${wol}" ]; then
                                available_choices="p u m b a g s d"
                                check_option ${wol} && \
                                        ethtool_cmds="${ethtool_cmds} wol ${wol}" || \
                                        ewarn "wol_${IFVAR} seems incorrectly set; correct would be: ${available_choices}"
                        fi

                        if [ -n "${ethtool_cmds}" ]; then
                                einfo "Running ${ethtool} -s ${IFVAR} ${ethtool_cmds}"
                                ethtool -s ${IFVAR} ${ethtool_cmds}
                                eend $?
                        fi
                fi
                ;;
        esac

        return 0
}

predown() {
        ethtool=`which ethtool 2>/dev/null`
        case "${IFVAR}" in
        eth? )  # assume autoneg on is the default so switch back on if-down
                if [ -n "${ethtool}" ]; then
                 einfo "Setting Auto-Negotiation to on"
                        ${ethtool} -s ${IFVAR} autoneg on
                        eend $?
                fi
                ;;
        esac

        return 0
}

#postdown() {
#}

Comment 4 Robin Johnson archtester Gentoo Infrastructure gentoo-dev Security 2010-08-04 19:45:52 UTC
I assume you are using this with BL2 right?

I don't mind your implementation, but I'm not sure adding variables like that is going to be scalable.

How about:
ethtool_ethX="speed 10 duplex full port fibre autoneg off wol p"
ethtool_pause_ethX='autoneg off rx on tx on'
ethtool_coalesce_ethX='...'
ethtool_ring_ethX='...'
ethtool_offload_ethX='...'
ethtool_nfc_ethX='...'

That would cover ALL of the ethtool modes and settings, without introducing enough variables for all of them. Also, some of the variables would have to be disambiguated in your version, eg offload_tx and pause_tx.
Comment 5 Robin Johnson archtester Gentoo Infrastructure gentoo-dev Security 2010-12-12 07:12:44 UTC
Ok, I'm going to merge this with my proposal variant.
Comment 6 Robin Johnson archtester Gentoo Infrastructure gentoo-dev Security 2011-02-22 03:00:05 UTC
Implemented in OpenRC git now, commit dfd42d1.