# HOWTO: bridging made simple

## bjornrun

I extended the network script to handle my bridging needs. I wanted to bridge my ethernet interfaces and also have an IP address on the bridge so the host both could be transparent and accessable.

Just add this to /etc/conf.d/net (comment everything else out):

```

iface_br0="dhcp"

bridge_br0="eth0 eth1"

```

Make /etc/init.d/net.br0 (just taking net.eth0 and adding the missing pieces):

```

#!/sbin/runscript

# Copyright 1999-2003 Gentoo Technologies, Inc.

# Distributed under the terms of the GNU General Public License v2

# $Header: /home/cvsroot/gentoo-src/rc-scripts/init.d/net.eth0,v 1.34 2003/11/26 19:23:15 azarah Exp $

# Unoffically patched for bridge support 2004/03/20 bjornrun

#NB: Config is in /etc/conf.d/net

# For pcmcia users. note that pcmcia must be added to the same

# runlevel as the net.* script that needs it.

depend() {

   use hotplug pcmcia

}

checkconfig() {

   if [ -z "${iface_IFACE}" ]

   then

      eerror "Please make sure that /etc/conf.d/net has \$iface_$IFACE set"

      return 1

   fi

   if [ -n "${vlans}" -a \! -x /sbin/vconfig ]

   then

      eerror "For VLAN (802.1q) support, emerge net-misc/vconfig"

      return 1

   fi

}

setup_env() {

   # No reason to check these multiple times in the file

   iface="${1/\./_}"

   iface_IFACE="$(eval echo \$\{iface_${iface}\})"

   dhcpcd_IFACE="$(eval echo \$\{dhcpcd_${iface}\})"

   inet6_IFACE="$(eval echo \$\{inet6_${iface}\})"

   alias_IFACE="$(eval echo \$\{alias_${iface}\})"

   status_IFACE="$(ifconfig | gawk -v IFACE="${iface}" '$0 ~ /Link/ { if ($1 == IFACE) print "up" }')"

   vlans="$(eval echo \$\{iface_${IFACE}_vlans\})"

   bridged="$(eval echo \$\{bridge_${IFACE}\})"

}

iface_start() {

   local retval=0

   setup_env ${1}

   checkconfig || return 1

   local IFACE="${1}"

   ebegin "Bringing ${IFACE} up"

   if [ -n "${bridged}" ]

   then

      /sbin/brctl addbr ${IFACE} || {

         retval=$?

         eend ${retval} "Failed to create bridge ${IFACE}"

         return ${retval}

      }

      for brport in ${bridged}

      do

           /sbin/brctl addif "${IFACE}" "${brport}" || {

            retval=$?

            eend ${retval} "Failed to add ${brport} to bridge ${IFACE}"

            return ${retval}

         }

         ifconfig "${brport}" 0.0.0.0 promisc up || {

            retval=$?

            eend ${retval} "Failed to ifconfig bridge port ${brport}"

            return ${retval}

         }

      done

       ifconfig ${IFACE} promisc up || {

         retval=$?

         eend ${retval} "Failed to bring bridge ${IFACE} up"

         return ${retval}

      }

   fi      

   

   if [ "${iface_IFACE}" != "dhcp" ]

   then

      /sbin/ifconfig ${IFACE} ${iface_IFACE} >/dev/null || {

         retval=$?

         eend ${retval} "Failed to bring ${IFACE} up"

         return ${retval}

      }

      # ifconfig do not always return failure ..

      /sbin/ifconfig ${IFACE} &> /dev/null || {

         retval=$?

         eend ${retval} "Failed to bring ${IFACE} up"

         return ${retval}

      }

   else

      # Check that eth0 was not brough up by the kernel ...

      if [ "${status_IFACE}" != "up" ]

      then

         /sbin/dhcpcd ${dhcpcd_IFACE} ${IFACE} >/dev/null || {

            retval=$?

            eend ${retval} "Failed to bring ${IFACE} up"

            return ${retval}

         }

      fi

   fi

   eend 0

   if [ -n "${alias_IFACE}" ]

   then

      local x=""

      local num=0

      local aliasbcast=""

      local aliasnmask=""

      ebegin "  Adding aliases"

      for x in ${alias_IFACE}

      do

         aliasbcast="$(eval echo \$\{broadcast_${iface}\} \| awk \'\{ print \$$((num + 1)) \}\')"

         if [ -n "${aliasbcast}" ]

         then

            aliasbcast="broadcast ${aliasbcast}"

         fi

         aliasnmask="$(eval echo \$\{netmask_${iface}\} \| awk \'\{ print \$$((num + 1)) \}\')"

         if [ -n "${aliasnmask}" ]

         then

            aliasnmask="netmask ${aliasnmask}"

         fi

      

         ebegin "    ${IFACE}:${num}"

         /sbin/ifconfig ${IFACE}:${num} ${x} \

            ${aliasbcast} ${aliasnmask} >/dev/null

         num=$((num + 1))

         eend 0

      done

      save_options "alias" "${alias_IFACE}"

   fi

   if [ -n "${inet6_IFACE}" ]

   then

      local x=""

      ebegin "  Adding inet6 addresses"

      for x in ${inet6_IFACE}

      do

         ebegin "    ${IFACE} inet6 add ${x}"

         /sbin/ifconfig ${IFACE} inet6 add ${x} >/dev/null

         eend 0

      done

      save_options "inet6" "${inet6_IFACE}"

   fi

   

   if [ -n "${gateway}" ] && [ "${gateway%/*}" = "${IFACE}" ]

   then

      ebegin "  Setting default gateway"

      # First delete any existing routes if it was setup by kernel ..

      /sbin/route del default dev ${gateway%/*} &>/dev/null

      /sbin/route add default gw ${gateway#*/} dev ${gateway%/*} \

         netmask 0.0.0.0 metric 1 >/dev/null || {

         

         local error=$?

         ifconfig ${IFACE} down &>/dev/null

         eend ${error} "Failed to bring ${IFACE} up"

         stop

         return ${error}

      }

      eend 0

   fi

   # Enabling rp_filter causes wacky packets to be auto-dropped by

   # the kernel.  Note that we only do this if it is not set via

   # /etc/sysctl.conf ...

   if [ -e /proc/sys/net/ipv4/conf/${IFACE}/rp_filter ] && \

      [ -z "$(egrep '^[^#]*rp_filter' /etc/sysctl.conf 2>/dev/null)" ]

   then

      echo 1 > /proc/sys/net/ipv4/conf/${IFACE}/rp_filter

   fi

}

iface_stop() {

   local myalias="$(get_options alias)"

   local myinet6="$(get_options inet6)"

   setup_env ${1}

   local IFACE="${1}"

   ebegin "Bringing ${IFACE} down"

   # Also down the inet6 interfaces

   if [ -n "${myinet6}" ]

   then

      local x=""

      for x in ${myinet6}

      do

         /sbin/ifconfig ${IFACE} inet6 del ${x} >/dev/null

      done

   fi

   

   # Do some cleanup in case the amount of aliases change

   if [ -n "${myalias}" ]

   then

      local x=""

      local num=0

      for x in ${myalias}

      do

         /sbin/ifconfig ${IFACE}:${num} down >/dev/null

         num=$((num + 1))

      done

   fi

   if [ "${iface_IFACE}" = "dhcp" ]

   then

      local count=0

      while /sbin/dhcpcd -z ${IFACE} &>/dev/null && [ "${count}" -lt 9 ]

      do

         # Give dhcpcd time to properly shutdown

         sleep 1

         count=$((count + 1))

      done

      if [ "${count}" -ge 9 ]

      then

         eerror "Timed out trying to stop dhcpcd"

      fi

   else

      /sbin/ifconfig ${IFACE} down >/dev/null

   fi

   if [ -n "${bridged}" ]

   then

      for brport in ${bridged}

      do

           /sbin/brctl delif "${IFACE}" "${brport}" || {

            retval=$?

            eend ${retval} "Failed to del ${brport} to bridge ${IFACE}"

            return ${retval}

         }

         /sbin/ifconfig "${brport}" 0.0.0.0 down || {

            retval=$?

            eend ${retval} "Failed to ifconfig bridge port ${brport}"

            return ${retval}

         }

      done

      /sbin/ifconfig ${IFACE} down >/dev/null

      /sbin/brctl delbr ${IFACE} || {

         retval=$?

         eend ${retval} "Failed to delete bridge ${IFACE}"

         return ${retval}

      }

   fi      

   eend 0

}

start() {

   iface_start ${IFACE} || return 1

   for vlan in ${vlans}

   do

      /sbin/vconfig add ${IFACE} ${vlan} >/dev/null

      iface_start ${IFACE}.${vlan}

   done

}

stop () {

   setup_env ${IFACE}

   checkconfig || return 1

   for vlan in ${vlans}

   do

      iface_stop ${IFACE}.${vlan}

      /sbin/vconfig rem ${IFACE}.${vlan} >/dev/null

   done

   iface_stop ${IFACE}

}

# vim:ts=4

```

Remember getting brctl

```

emerge bridge-utils

```

This made bridging from very difficult on Linux to even simpler than OpenBSD for me. Probably there is ways to make it even better, please tell me.  I would like this patch be in the official Gentoo, saving the manual patching - perhaps added by a USE flag "bridge".

----------

## atom

afaik, a transparent bridge does not have an ip address.  :Smile: 

in any case, to make the bridge truly transparent and invisible, just change the following:

```
iface_br0="0.0.0.0"
```

----------

## pakman

Nice guide, I was just about to ask if iptables worked on transparent bridges then I saw this:

http://ebtables.sourceforge.net/

I'm thinking these bridges make a great security measure, now if you could run two of them with some kind of redundancy protocol such as carp or ucarp (www.ucarp.org) that could handle redundancy with just mac addresses then you have one sweet firewall setup.

----------

## atom

i just set my bridge up and put it between my cable modem and firewall/router which is running openbsd 3.4. i started reading about carp/pfsync today and i may go ahead and set it up once openbsd 3.5 comes out.

the bridge is for ipsec. i'm thinking a transparent bridge should be able to set up an ipsec transport, but i'm not positive. maybe i'll find out today.

----------

## pakman

A bridge can transport ipsec no worries as ipsec operates at the network layer, same layer as normal IP, and a bridge operates at the data-link layer beneath it. i.e. the bridge just transports ethernet packets which may be ip or ipsec.

----------

## atom

what i want is the bridge to generate the ipsec packets. so that when packets destined for the remote ipsec node pass through the bridge, they will be encapsulated in ipsec. pakman, is this what you mean?

----------

## pakman

 *atom wrote:*   

> what i want is the bridge to generate the ipsec packets. so that when packets destined for the remote ipsec node pass through the bridge, they will be encapsulated in ipsec. pakman, is this what you mean?

 

Ah no, I meant the bridge can carry IPSec packets. You can't have a bridge as an end-point for an IPSec connection as bridges work at different layer of the OSI model to IPSec.

Basically, IPSec requires an IP address to work and bridges don't have one. What you want is a VPN.

----------

## sorcerer25

iface_br0="dhcp"

so, i guess you working only with dhcp

WITHOUT dhcp:

 * Bringing br0 up...  [ ok ]

/sbin/rc: line 168:  : command not found

anyway, the bridge is up and working ... but ...

NO GATEWAY ... setting a gateway (gateway="br0/192.168.1.1") and the script will fail completly

same thing about aliases

i already use your script (and setting up what i need - gateway and aliases in an v. simple bash script)

but anyway ... can you fix it ?  ... plz  :Smile: 

PS cat /etc/gentoo-release 

Gentoo Base System version 1.4.3.13

----------

## pakman

sorceror your questions are answered in the above posts, iface_br0="0.0.0.0" for no IP.

As for the GATEWAY, bridges don't use gateways as they do not use IP. This is why you get an error. Either you want to set the GATEWAY on a different interface, one with an IP address (eth0 maybe), or you actually want a router not a bridge  :Smile: 

Nice explanation of bridges here:

http://www.cisco.com/univercd/cc/td/doc/cisintwk/ito_doc/bridging.htm

edit: ewp these bridges can do ip-layer filtering etc, thats what makes them so funky  :Smile: 

----------

## sorcerer25

man ... turn the power on ... i hate to use this tone but still

bridge is something i use for WHAT I WANT ... the fact that you can't see bridges otherwise than no ip, transparent firewall is your ONLY PERSONAL BUSINESS (besides this is linux, NOT cisco, last time i check cisco don't define all networking, and what they say is NOT the word of god)

come on ! bridges can be used be cause I NEED arp forwarding (no, not proxyarp), be cause i have 3 ethernet cards in my computer and bridging them is cheaper and quicker then buying, setting up and cascading an hub, bridging an tunnel,vpn,etc. with an netcard to make the other side see transparently that lan (all protocols will work directly not only TCP/IP) , etc. etc. etc.

bridge is just another net card ... or i'm wrong about that ?!?

----------

## pakman

Chill out mate, bridges have been around since before cisco, was just trying to help explain. You could try this to get the gateway working, edit line 151 and change:

```
/sbin/route add default gw ${gateway#*/} dev ${gateway%/*} \
```

to

```
/sbin/route add default gw ${gateway#*/} \
```

Last edited by pakman on Sun May 02, 2004 8:23 pm; edited 1 time in total

----------

## sorcerer25

sorry, i just hate ... holly fossils (cisco)  :Wink: 

and tank you  :Smile: 

----------

