{"id":82,"date":"2011-02-12T08:14:47","date_gmt":"2011-02-12T06:14:47","guid":{"rendered":"http:\/\/www.melen.org\/u\/jan\/wp\/?p=82"},"modified":"2011-02-12T08:16:30","modified_gmt":"2011-02-12T06:16:30","slug":"creating-virtual-ethernet-interfaces-using-ng_eiface-and-ng_bridge","status":"publish","type":"post","link":"https:\/\/www.melen.org\/u\/jan\/wp\/?p=82","title":{"rendered":"Creating virtual ethernet interfaces using ng_eiface and ng_bridge"},"content":{"rendered":"<p>With generic ethernet interface netgraph node it is possible to create new interfaces that are accessible with ifconfig(8) and with ethernet bridging netgraph node type it is possible to bridge between different ethernet node types. By combining these two types it is possible to create multiple interfaces with different ethernet (MAC) address on a same physical interface. Here is sample script that is modified from the netgraph ether.bridge example script that comes with standard FreeBSD distribution: <\/p>\n<pre>\r\n#!\/bin\/sh\r\n#\r\n# Author: Jan Melen-jan(at)melen.org\r\n#\r\n# This script sets up an Ethernet bridging network across multiple\r\n# ng_eiface(4) using the ng_bridge(4) and ng_ether(4) netgraph\r\n# node types.\r\n#\r\n\r\nBRIDGE_NAME=\"bnet0\"\r\n\r\nVIRTUAL_IFACES=\"ngeth0 ngeth1 ngeth2\"\r\nLOCAL_IFACE=\"bge0\"\r\n\r\n# Routine to verify node's existence.\r\nvether_verify() {\r\n\tngctl info ${BRIDGE_NAME}: &gt;\/dev\/null 2&gt;&amp;1\r\n\tif [ $? -ne 0 ]; then\r\n\t\techo \"${BRIDGE_NAME}: bridge network not found\"\r\n\t\texit 1\r\n\tfi\r\n}\r\n\r\n# Start\/restart routine.\r\nvether_start() {\r\n\r\n\t# Load netgraph KLD's as necessary.\r\n\tfor KLD in ng_ether ng_bridge; do\r\n\t\tif ! kldstat -v | grep -qw ${KLD}; then\r\n\t\t\techo -n \"Loading ${KLD}.ko... \"\r\n\t\t\tkldload ${KLD} || exit 1\r\n\t\t\techo \"done\"\r\n\t\tfi\r\n\tdone\r\n\r\n\t# Reset all interfaces.\r\n\tvether_stop\r\n\r\n\t# Verify all interfaces exist.\r\n\tLINKNUM=2\r\n   ETHERADDR=`ifconfig ${LOCAL_IFACE} ether | grep \"ether\" | cut -b 8-22`\r\n\tfor ETHER in ${VIRTUAL_IFACES}; do\r\n\t\tif ! ngctl info ${ETHER}: &gt;\/dev\/null 2&gt;&amp;1; then\r\n           ngctl mkpeer . eiface hook ether\r\n\t\tfi\r\n       ifconfig ${ETHER} ether ${ETHERADDR}${LINKNUM}\r\n\t\tifconfig ${ETHER} up || exit 1\r\n\t\tLINKNUM=`expr ${LINKNUM} + 1`\r\n\tdone\r\n\r\n\t# Create new ng_bridge(4) node, attached to the first interface.\r\n\tngctl mkpeer ${LOCAL_IFACE}: bridge lower link0 || exit 1\r\n\tngctl name ${LOCAL_IFACE}:lower ${BRIDGE_NAME} || exit 1\r\n   ngctl connect ${LOCAL_IFACE}: ${BRIDGE_NAME}: upper link1 || exit 1\r\n\r\n\tLINKNUM=2\r\n\t# Attach other interfaces as well.\r\n\tfor ETHER in ${VIRTUAL_IFACES}; do\r\n\t\tif [ ${LINKNUM} != 0 ]; then\r\n\t\t\tngctl connect ${ETHER}: ${BRIDGE_NAME}: \\\r\n\t\t\t    ether link${LINKNUM} || exit 1\r\n\t\tfi\r\n\t\tLINKNUM=`expr ${LINKNUM} + 1`\r\n\tdone\r\n\r\n\t# Set all interfaces in promiscuous mode and don't overwrite src addr.\r\n\tfor ETHER in ${LOCAL_IFACE}; do\r\n\t\tngctl msg ${ETHER}: setpromisc 1\r\n\t\tngctl msg ${ETHER}: setautosrc 0\r\n\tdone\r\n}\r\n\r\n# Stop routine.\r\nvether_stop() {\r\n\tngctl kill ${BRIDGE_NAME}: &gt;\/dev\/null 2&gt;&amp;1\r\n\tfor ETHER in ${VIRTUAL_IFACES} ${LOCAL_IFACE}; do\r\n\t\tngctl kill ${ETHER}: &gt;\/dev\/null 2&gt;&amp;1\r\n\tdone\r\n}\r\n\r\n# Main entry point.\r\ncase $1 in\r\n\tstart)\r\n\t\tvether_start\r\n\t\t;;\r\n\tstop)\r\n\t\tvether_verify\r\n\t\tvether_stop\r\n\t\t;;\r\n\t*)\r\n\t\techo \"usage: $0 [ start | stop ]\"\r\n\t\texit 1\r\nesac\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>With generic ethernet interface netgraph node it is possible to create new interfaces that are accessible with ifconfig(8) and with ethernet bridging netgraph node type it is possible to bridge between different ethernet node types. By combining these two types it is possible to create multiple interfaces with different ethernet (MAC) address on a same [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[2],"tags":[],"_links":{"self":[{"href":"https:\/\/www.melen.org\/u\/jan\/wp\/index.php?rest_route=\/wp\/v2\/posts\/82"}],"collection":[{"href":"https:\/\/www.melen.org\/u\/jan\/wp\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.melen.org\/u\/jan\/wp\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.melen.org\/u\/jan\/wp\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.melen.org\/u\/jan\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=82"}],"version-history":[{"count":3,"href":"https:\/\/www.melen.org\/u\/jan\/wp\/index.php?rest_route=\/wp\/v2\/posts\/82\/revisions"}],"predecessor-version":[{"id":85,"href":"https:\/\/www.melen.org\/u\/jan\/wp\/index.php?rest_route=\/wp\/v2\/posts\/82\/revisions\/85"}],"wp:attachment":[{"href":"https:\/\/www.melen.org\/u\/jan\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=82"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.melen.org\/u\/jan\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=82"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.melen.org\/u\/jan\/wp\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=82"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}