Dingo: FreeBSD Network Cleanup and Consolidation Project



A Small Presentation

Dingo project is a collection of work that needs to be done to clean up and advance the network stack. The overriding goal is to remove duplicated functionality while also adding new features that will make FreeBSD easier to use both for the network engineer and experimenter and for the first time user.

You'll find the complete description on the project's webpage.

Where I'm involved

One day, I thought : "Gregory, it's time to wake up, and began to code". I thought that Dingo would be a good point to start, after looking at this page and at this page.

So I had a look at Dingo's page, and decide to begin with the "take M_PROMISC from NetBSD"... It was already done, just to be ported, I was pretty sure I could handle it. An interesting fact was that there was a lot to do, and the names sounded easy. (Well, I'm meaning there that it's always less hard to begin a project whom title you understand than to begin a project where you don't understand a f0ckin' word)

Let's begin with technique !

When everything began at NetBSD

At the beginning, there is a problem (If not, why would we do something ?)

Manuel Bouyer, from netbsd (and also from LIP6, in Paris), wrote to tech-net (20030319) :

"there is currently a problem with promiscous mode and vlan(4) interfaces. When a vlan interface is put in promiscous ode, the underlying interface is as well. But the packets for others hosts never get delivered to the vlan interface, because they are filtered too early in ether_input(). The main problem is that this breaks bridges on top of vlans."

He then suggested to solution :

  1. deliver the packet to vlans devices before the (ifp->if_flags & IFF_PROMISC) check. The bad effect is that we'll have to do this check again in vlan_input, and we'll test etype one more time.
  2. add a new M_PROMISC mbuf flag, and set it in the (ifp->if_flags & IFF_PROMISC) check in ether_input instead of dropping the packet if it's not for us. We'll drop it later if approriate, either in vlan_input() or in the others switch (etype) cases. This may also allow to fix the XXX comment before (ifp->if_flags & IFF_PROMISC) in ether_input() (I didn't look at this yet).

He finally chose the second solution, and committed 6 days later :

Make promiscous mode work on vlans: introduce a new link-layer m_flag M_PROMISC. In ether_input(), flag packets comming from an interface in promiscous mode which are not for us M_PROMISC instead of droping them. Drop M_PROMISC packets which are not passed to vlan_input(). M_PROMISC packets passed to vlan_input() will be looped back to ether_input() the M_PROMISC flag will be handled appropriately. Clear M_PROMISC before giving the packet to bridge, as bridge has its own checks for local MAC addresses. This also makes bridges on vlan working.

Let's learn how to network on freebsd

I came thru a great page (=> link)

The request for FreeBSD

Bruce M Simpson wrote :

NetBSD has a flag called M_PROMISC. Why is this relevant? Well, one thing I've noticed is that if you're running regular unicast forwarding on a box, and then put one of the interfaces into PROMISC mode, the danger is that the box will then begin trying to forward the datagrams it's just forwarded. We'd need a way to differentiate between traffic addressed to us and not addressed to us by MAC address when forwarding.

This time, it was a problem with multicast routing between multiple VLANs on FreeBSD.

Where my TODO list evolves...

I posted a question on freebsd-net@ :

What is the difference between if (m->m_flags & M_VLANTAG) and if (ether_type == ETHERTYPE_VLAN) ?

I got 2 answers, from Jon Simola and Gleb Smirnoff. Basically, they told me that I was right to assume that there were barely any difference

In fact, it depends on if the driver is able to recognize VLAN frames. If yes, mbuf has M_VLANTAG set on it, and mbuf contains the untagged frame. If the driver is not able to handle VLAN frames, we need to look into frame and look for the tag. Well, I should have guessed that it was an hardware-related issue...

I also discussed IFF_PROMISC and IFF_PPROMISC with gnn@. Seems the first point of my TODO is not a real problem. I still think it would be a good idea to rename IFF_PPROMISC in IFF_USERPROMISC. More on this in a few days.

So, after thinking and reading a lot, I got a patch : M_PROMISC.diff

My TODO