Ethernet interfaces on bridge using netgraph

Hello,

I have some trouble while trying to implement 2 ethernet interfaces connected via a bridge using netgraph. I am using FreeBSD 10.1 release. What I want to do seems to be as simple as shown in the code section below, however I can't make sending/receiving broadcast messages.

Code:
---------------  ---------------
|  ngeth0     |  |  ngeth1     |
| (ng_eiface) |  | (ng_eiface) |
---------------  ---------------
        |               |
        |               |
--------------------------------
|          br0                 |
|        (ng_bridge)           |
--------------------------------

Network setup:
I followed as far as possible the example in /usr/share/examples/netgraph/ether.bridge, with the exceptions:
- I couldnt use hook lower while creating the bridge, and
- setting promiscuous mode/dont overwrite src address doesnt work
Code:
#create 2 eithernet interfaces
ngctl mkpeer . eiface hook ether
ngctl mkpeer . eiface hook ether
#create bridge and attach the first interface
//ngctl mkpeer ngeth0: bridge lower link0 (doesnt work hook lower not allowed: Protocol family not supported)
ngctl mkpeer ngeth0: bridge ether link0
//ngctl name ngeth0:lower br0 (doesnt work as above)
ngctl name ngeth0:ether br0
#attach the 2nd interface
ngctl connect ngeth1: br0: ether link1
#assign MAC
ifconfig ngeth0 ether 01:02:03:04:05:01
ifconfig ngeth1 ether 01:02:03:04:05:02

#trying to set up promiscous mode fails
ngctl msg ngeth0: setpromisc 1
ngctl: send msg: Function not implemented

#status according to ifconfig
ngeth0: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
   options=28<VLAN_MTU,JUMBO_MTU>
   ether 01:02:03:04:05:01
   nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
   media: Ethernet autoselect (1000baseT <full-duplex>)
   status: active
ngeth1: flags=8802<BROADCAST,SIMPLEX,MULTICAST> metric 0 mtu 1500
   options=28<VLAN_MTU,JUMBO_MTU>
   ether 01:02:03:04:05:02
   nd6 options=29<PERFORMNUD,IFDISABLED,AUTO_LINKLOCAL>
   media: Ethernet autoselect (1000baseT <full-duplex>)
   status: active

#status according to ngctl l
Name: br0  Type: bridge  ID: 00000033  Num hooks: 2
Name: ngctl1623  Type: socket  ID: 00000039  Num hooks: 0
Name: ngeth0  Type: eiface  ID: 0000002c  Num hooks: 1
Name: ngeth1  Type: eiface  ID: 0000002e  Num hooks: 1
Tests:
Code:
#produce DHCPDISCOVER messages using dhclient:
dhclient ngeth0
DHCPDISCOVER on ngeth0 to 255.255.255.255 port 67 interval 4
DHCPDISCOVER on ngeth0 to 255.255.255.255 port 67 interval 6
^C

#capture traffic on ngeth0
tcpdump -i ngeth0
tcpdump: WARNING: ngeth0: no IPv4 address assigned
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ngeth0, link-type EN10MB (Ethernet), capture size 65535 bytes
21:21:36.459845 IP 0.0.0.0.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 01:02:03:04:05:01 (oui Unknown), length 300
^C
1 packet captured
2 packets received by filter
0 packets dropped by kernel

#capture traffic at ngeth1 (nothing shows up)
tcpdump -i ngeth1
tcpdump: WARNING: ngeth1: no IPv4 address assigned
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ngeth1, link-type EN10MB (Ethernet), capture size 65535 bytes
^C
0 packets captured
0 packets received by filter
0 packets dropped by kernel
Observations/Questions:
Interestingly the message at interface ngeth0 only shows up when exiting tcpdump using ^C.
Moreover I noticed that after running dhclient on interface ngeth0 the interface has been "configured" with ip/netmask 0.0.0.0/8 and broadcast address 255.255.255.255

More questions:
Why I cannot use hook "lower" ? (And what is actually the difference to hook "ether")
Why no broadcast messages arrived on interface ngeth1 ?

Thanks everybody,
plichel
 
update:

Seems I that I don't really understand the example in /usr/share/examples/netgraph/ether.bridge. Main problem seems to be, that I haven't made use of my physical network interface. However it seems to be necessary to link lower and upper hooks with the bridge.

After some more experiments I have now a setup as follows:
Code:
ngctl mkpeer ${DEV}: bridge lower link0
ngctl name ${DEV}:lower br0
ngctl connect ${DEV}: br0: upper link1
ngctl mkpeer br0: eiface link2 ether
ngctl mkpeer br0: eiface link3 ether
... where ${DEV} is my real network interface (in my case re0).

Now when I let run dhclient as described in the first post I see dhcp discover messages on both the interfaces. But I have no explanation why I only see this kind of broadcasts when I have a blank MAC address on the client side:
Code:
#having blank address configured dhcp discover reaches ngeth0
ifconfig ngeth1 ether 00:00:00:00:00:00
dhclient ngeth1
DHCPDISCOVER on ngeth1 to 255.255.255.255 port 67 interval 5
DHCPDISCOVER on ngeth1 to 255.255.255.255 port 67 interval 6
^C

Output on ngeth0:
Code:
tcpdump -i ngeth0 port bootpc
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ngeth0, link-type EN10MB (Ethernet), capture size 65535 bytes
21:22:53.616116 IP 0.0.0.0.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 00:00:00:00:00:00 (oui Ethernet), length 300
21:22:58.679770 IP 0.0.0.0.bootpc > 255.255.255.255.bootps: BOOTP/DHCP, Request from 00:00:00:00:00:00 (oui Ethernet), length 300

But now:
Code:
#Nothing shows up when configure a 'real' address
ifconfig ngeth1 ether 01:02:04:08:10:01
dhclient ngeth1
DHCPDISCOVER on ngeth1 to 255.255.255.255 port 67 interval 5
DHCPDISCOVER on ngeth1 to 255.255.255.255 port 67 interval 6
^C
No packets arrive on ngeth0. Weird, isn't it ?
 
Old thread! But for what it's worth, your issue may or may not be related to the fact that the MAC you assigned is a broadcast mac (bit 0 in 1th octet is is 1: https://en.wikipedia.org/wiki/MAC_address)

I just got the following setup working:
re1 - real interface connected to ISP, dhclient gets one IP
ngeth0 - virtual eiface, dhclient gets a second IP
ngeth1 - virtual eiface, dhclient gets a third IP
br0 - netgraph bridge between these three interfaces (or rather 4, since re1 has upper and lower hook)

My setup, and my interpretation on what it does:

Code:
# Create new bridge, linking it to re1's lower hook (physical interface)
ngctl mkpeer re1: bridge lower link0
# Name the newly created bridge br0, initially referencing to it via re1:lower
ngctl name re1:lower br0
# Connect the upper hook on re1 (OS) to the bridge
ngctl connect re1: br0: upper link1
# Create two virtual ethernet interfaces, and conncet it to the bridge.
ngctl mkpeer br0: eiface link2 ether
ngctl mkpeer br0: eiface link3 ether
# Assign semi-valid MACs for the virtual interfaces
ifconfig ngeth0 ether 00:01:03:04:55:01
ifconfig ngeth1 ether 00:01:03:04:55:02
# Make re1 promisc and "do not auto set source address"?
ngctl msg re1: setpromisc 1
ngctl msg re1: setautosrc 0
# Get some IPs
dhclient re1
dhclient ngeth0
dhclient ngeth1

I haven't tested this any further than actually getting an IP though.. :)
 
Back
Top