Re: distributed bridging [script]

From: Julian Elischer (julian_at_elischer.org)
Date: 10/28/05

  • Next message: Craig Boston: "Re: 6.0-RC1 IPv6 losing local subnet route"
    Date: Fri, 28 Oct 2005 13:04:19 -0700
    To: Julian Elischer <julian@elischer.org>
    
    
    

    Julian Elischer wrote:

    > spoggle wrote:
    >
    >> Greetings,
    >>
    >> I'm trying to create a configuration that would bridge interfaces on
    >> different hosts. Each host would have at least two interfaces, one
    >> would be the inter-host connection, the remaining would be the bridged
    >> interfaces, so that a packet appearing on host a's bridged interface
    >> would also appear on host b, c, etc. bridged interfaces and vice
    >> versa.
    >>
    >> My equipment to try this is on order, so it's still somewhat of a
    >> brain exercise.
    >>
    >> I would like to use if_bridge (for it's STP) and I was thinking of
    >> bridging the local interfaces and then using netgraph (eiface?)
    >> connected to some other plumbing like l2tp to connect the remote
    >> bridges together.
    >>
    >> Does this sound feasible? Anyone have any other suggestions on how to
    >> pull this off?
    >>
    >> I've also considered hacking if_bridge to allow the configuration of
    >> remote bridges as pseudo ports, but not sure I'll have time.
    >>
    >>
    >
    > on machine A you have:
    > NIC A 1.1.1.1
    > NIC B 10.0.0.1
    > on machine B you have:
    >
    > NIC A 2.2.2.2
    > NIC B 10.0.0.2
    >
    >
    > On each machine use a modification of
    > /usr/share/examples/netgraph/ether.bridge
    >
    > so that one link of each bridge is set to an ng_ksocket instead of a
    > real interface.
    > then send messages to each or the sockets to connect to each other
    > with UDP.
    >
    > how to do this is in /usr/share/examples/netgraph/udp.tunnel
    >
    > by combining the two you should create a tunnel between the two
    > bridges which
    > should result in a single bridged network.
    >
    >
    > that should be about all you need.

    here's a completely untested script.
    swap the addresses on each end of the bridge (and probably remove one of
    the
    bridged ethernet ports ans you probably only have one internal NIC on
    each machine (remove ed0))

    >
    >
    >
    >
    >
    >
    >> spoggle
    >> _______________________________________________
    >> freebsd-net@freebsd.org mailing list
    >> http://lists.freebsd.org/mailman/listinfo/freebsd-net
    >> To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org"
    >>
    >>
    > _______________________________________________
    > freebsd-net@freebsd.org mailing list
    > http://lists.freebsd.org/mailman/listinfo/freebsd-net
    > To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org"

    
    

    #!/bin/sh
    # $FreeBSD: src/share/examples/netgraph/ether.bridge,v 1.1.2.2 2001/07/19 05:45:03 dd Exp $

    # 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.

    # This script sets up a virtual point-to-point WAN link between
    # two subnets, using UDP packets as the ``WAN connection.''
    # The two subnets might be non-routable addresses behind a
    # firewall.
    #

    # Here define the local and remote inside networks as well
    # as the local and remote outside IP addresses and UDP port
    # number that will be used for the tunnel.
    #
    #BRIDGE_IFACES="ed0 fxp0 fxp1 tunnel1"
    BRIDGE_IFACES="fxp0 tunnel1"
    LOCAL_IFACE="fxp0"
    LOC_INTERIOR_IP=192.168.1.1
    LOC_EXTERIOR_IP=1.1.1.1
    REM_INTERIOR_IP=192.168.2.1
    REM_EXTERIOR_IP=2.2.2.2
    REM_INSIDE_NET=192.168.2.0
    UDP_TUNNEL_PORT=4028

    ####################################################################
    #### 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 ng_ksocket; 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
                    case $ETHER in
                    tunnel*)
                            # nothing to do (I think)
                            ;;
                    *)
                            if ngctl info ${ETHER}: >/dev/null 2>&1; then
                                    ifconfig ${ETHER} up || exit 1
                            else
                                    echo "Error: interface ${ETHER} does not exist"
                                    exit 1
                            fi
                            ;;
                    esac
            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
                    case $ETHER in
                    tunnel*)
                            # Attach a UDP socket to the ``inet''
                            # hook of the interface node
                            # using the ng_ksocket(8) node type.
                            #
                            ngctl mkpeer ${BRIDGE_NAME}: ksocket \
                                    link${LINKNUM} inet/dgram/udp

                            # Bind the UDP socket to the local external
                            # IP address and port
                            ngctl msg ng0:inet bind \
                                    inet/${LOC_EXTERIOR_IP}:${UDP_TUNNEL_PORT}

                            # Connect the UDP socket to the peer's
                            # external IP address and port
                            ngctl msg ng0:inet connect \
                                    inet/${REM_EXTERIOR_IP}:${UDP_TUNNEL_PORT}

                            ;;
                    *)
                            if [ ${LINKNUM} != 0 ]; then
                                    ngctl connect ${ETHER}: ${BRIDGE_NAME}: \
                                        lower link${LINKNUM} || exit 1
                            fi
                            ;;
                    esac
                    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
                    case $ETHER in
                    tunnel*)
                            # nothing to do (I think)
                            ;;
                    *)
                            ngctl msg ${ETHER}: setpromisc 1 || exit 1
                            ngctl msg ${ETHER}: setautosrc 0 || exit 1
                    ;;
                    esac
            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 ${LOCAL_IFACE}:"
                    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

    
    

    _______________________________________________
    freebsd-net@freebsd.org mailing list
    http://lists.freebsd.org/mailman/listinfo/freebsd-net
    To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org"


  • Next message: Craig Boston: "Re: 6.0-RC1 IPv6 losing local subnet route"

    Relevant Pages

    • IPS-Builder
      ... I' d like to share with all, this script made by me based on root0 ... You need 3 network interfaces (One for management and two for the bridge) ... -This have a management interface. ...
      (Focus-IDS)
    • Re: bridge with access on both interfaces
      ... >>'inside' and 'outside' IPs separately on each bridge interface, ... Some tcpdumps on both in and outside interfaces suggest an ARP ... > If you want to use IP while bridging, ... and net4801 is that the 3 ethernet controllers now share one interrupt. ...
      (freebsd-net)
    • [BUG][debian-2.6.20-1-686] bridging + vlans + "vconfig rem" == stuck kernel
      ... I've managed to fairly reliably trigger a deadlock in some portion of the linux networking code on my Debian test box. ... I'm pretty sure that it's a race condition of some sort as it doesn't trigger if I ifdown the interfaces one by one, but if I run "ifdown -a" then it triggers halfway through reliably. ... Just for a bit of background on why this is so complex: When I get this networking problem sorted out I'm going to set up heartbeat and a dummy "world1" interface with a shared MAC which is added to the "world" bridge when the current system is the DHCP-client master. ...
      (Linux-Kernel)
    • Re: IPS-Builder
      ... I' d like to share with all, this script made by me based on root0 ... You need 3 network interfaces (One for management and two for the bridge) ... -This have a management interface. ...
      (Focus-IDS)
    • Re: bridge issues with pf rules on OpenBSD/Sparc
      ... > assigned so that clients on the bridged interfaces can access the ... > time, regardless of bridge state. ... > rule pass in on le0 tag t_lan ... > rule pass in on le2 tag t_wap ...
      (comp.unix.bsd.openbsd.misc)