Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 15 Sep 2000 17:18:48 -0700 (PDT)
From:      Archie Cobbs <archie@whistle.com>
To:        nsayer@kfu.com
Cc:        freebsd-emulation@freebsd.org
Subject:   Re: vmnet, bridging and netgraph
Message-ID:  <200009160018.RAA81024@bubba.whistle.com>
In-Reply-To: <39C2B501.58EC338E@sftw.com> "from Nick Sayer at Sep 15, 2000 04:47:13 pm"

next in thread | previous in thread | raw e-mail | index | archive | help
Nick Sayer writes:
> 2. The kernel spits out lots of these:
> 
> arp: 209.157.37.4 is on xl0 but got reply from 00:bd:5a:e6:4d:91 on
> vmnet1
> 
> This is because ARP checks the source of the packet and sees the wrong
> interface. When ng_bridge is sending packets to an upper hook, it should
> make the packet look like it was received on the interface belonging to
> the upper hook in question. Either that or the arp code has not yet been
> sufficiently disconnected from the interfaces to let the upper and lower
> hooks work the way ng_bridge wants them to. Archie? :-)

The ng_bridge(4) node treats all links as the same, whether they are
pointing "up" or "down", so it wouldn't know how to do that. I guess
it could contain logic to probe each peer to see if it's an ng_ether
node, and if so, remember it. That's probably worth looking in to..

> 4. I forgot the need to sent setpromisc 1 and setautosrc 0 messages when
> setting this whole thing up.

Yep..

> 5. I don't yet have a correct list of modules to load in vmware.sh to
> make this work. I have tried loading just netgraph.ko, but this fails
> the _first_ time I do all of the hookups, but not the second. Archie?
> :-)

You'd need ng_ether.ko and ng_bridge.ko, both of which depend on
netgraph.ko... ?

> 7. Those of you using ed interfaces may notice that there is a couple
> #ifdef BRIDGE sections in the driver. Not sure what for.

This is an optimization that I left in because Luigi asked for it.
It avoids doing painfully slow PIO reads of packets that are going to
be thrown away anyway.

FYI, I've written a little script for /usr/share/examples that
sets up bridging using netgraph. This is completely untested,
so any feedback is appreciated.

-Archie

___________________________________________________________________________
Archie Cobbs   *   Whistle Communications, Inc.  *   http://www.whistle.com

#!/bin/sh
# $FreeBSD$

# This script sets up an Ethernet bridging network across multiple
# Ethernet interfaces using the ng_bridge(4) and ng_ether(4) netgraph
# node types.
#
# To use this script:
#
# 0. Make your own copy of this example script
#
# 1. Give your bridging network a name by editing the definition of
#    ${BRIDGE_NAME} below. It must be a valid netgraph node name.
#
# 2. Edit the definitions of ${BRIDGE_IFACES} and ${LOCAL_IFACE}
#    as described below to define your bridging interfaces.
#
# 3. Run this script with "start" as the command line argument.
#
# 4. Examine bridging statistics by running this script with "stats"
#    as the command line argument.
#
# 5. Stop bridging by running this script with "stop" as the
#    command line argument.
#
# To run multiple independent bridging networks, create multiple
# copies of this script with different variable definitions.
# 

# Give each bridging network a unique name here

BRIDGE_NAME="bnet0"

# List the names of the interfaces that you want to bridge across
# here in ${BRIDGE_IFACES}. If you want to include the local host
# machine as well then set ${LOCAL_IFACE} as well (it may also be
# listed in ${BRIDGE_IFACES}). Of course, any ${LOCAL_IFACE} must
# be ifconfig(8)ured separately. If you don't want a ${LOCAL_IFACE}
# then leave it defined as the emtpy string.

BRIDGE_IFACES="ed0 fxp0 fxp1"
LOCAL_IFACE="fxp0"

####################################################################
#### Everything below this point should not need to be modified ####
####################################################################

# Routine to verify node's existence
bridge_verify() {
	ngctl info ${BRIDGE_NAME}: >/dev/null 2>&1
	if [ $? -ne 0 ]; then
		echo "${BRIDGE_NAME}: bridge network not found"
		exit 1
	fi
}

# Routine to get and display link stats
bridge_linkstats() {
	STATS=`ngctl msg ${BRIDGE_NAME}: getstats $1`
	if [ $? -ne 0 ]; then
		exit 1
	fi
	echo "${STATS}" | fmt 2 | awk '/=/ { fl=index($0, "="); \
	    printf "%20s = %s\n", substr($0, 0, fl - 1), substr($0, fl + 1); }'
}

# Start/restart routine
bridge_start() {

	# Load netgraph KLD's as necessary
	for KLD in ng_ether ng_bridge; do
		if kldstat -v | grep -qw ${KLD}; then
		else
			echo -n "Loading ${KLD}.ko... "
			kldload ${KLD} || exit 1
			echo "done"
		fi
	done

	# Reset all interfaces
	bridge_stop

	# Verify all interfaces exist
	for ETHER in ${BRIDGE_IFACES} ${LOCAL_IFACE}; do
		if ngctl info ${ETHER}: >/dev/null 2>&1; then
		else
			echo "Error: interface ${ETHER} does not exist"
			exit 1
		fi
		ifconfig ${ETHER} up || exit 1
	done

	# Create new ng_bridge(4) node, attached to the first interface
	FIRSTIF=`echo ${BRIDGE_IFACES} | awk '{ print $1 }'`
	ngctl mkpeer ${FIRSTIF}: bridge lower link0 || exit 1
	ngctl name ${FIRSTIF}:lower ${BRIDGE_NAME} || exit 1

	# Attach other interfaces as well
	LINKNUM=0
	for ETHER in ${BRIDGE_IFACES}; do
		if [ ${LINKNUM} != 0 ]; then
			ngctl connect ${ETHER}: ${BRIDGE_NAME}: \
			    lower link${LINKNUM} || exit 1
		fi
		LINKNUM=`expr ${LINKNUM} + 1`
	done

	# Hook up local interface, if any
	if [ "${LOCAL_IFACE}" != "" ]; then
		ngctl connect ${LOCAL_IFACE}: ${BRIDGE_NAME}: \
		    upper link${LINKNUM} || exit 1
	fi

	# Set all interfaces in promiscuous mode and don't overwrite src addr
	for ETHER in ${BRIDGE_IFACES}; do
		ngctl msg ${ETHER}: setpromisc 1 || exit 1
		ngctl msg ${ETHER}: setautosrc 0 || exit 1
	done
}

# Stop routine
bridge_stop() {
	ngctl kill ${BRIDGE_NAME}: >/dev/null 2>&1
	for ETHER in ${BRIDGE_IFACES} ${LOCAL_IFACE}; do
		ngctl kill ${ETHER}: >/dev/null 2>&1
	done
}

# Stats routine
bridge_stats() {

	# Make sure node exists
	bridge_verify

	echo ""
	echo "Statistics for bridging network ${BRIDGE_NAME}:"
	echo ""
	LINKNUM=0
	for ETHER in ${BRIDGE_IFACES}; do
		echo "Network interface ${ETHER}:"
		bridge_linkstats ${LINKNUM}
		LINKNUM=`expr ${LINKNUM} + 1`
	done
	if [ "${LOCAL_IFACE}" != "" ]; then
		echo "Local host interface ${ETHER}:"
		bridge_linkstats ${LINKNUM}
	fi
}

# Main entry point
case $1 in
	start)
		bridge_start
		;;
	stats)
		bridge_verify
		bridge_stats
		;;
	stop)
		bridge_verify
		bridge_stop
		;;
	*)
		echo "Usage: ether.bridge [ start | stop | stats ]"
		exit 1
esac



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-emulation" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200009160018.RAA81024>