cvs commit: src/sbin/ipfw ipfw2.c src/sys/netgraph ng_ipfw.cng_ipfw.h src/sys/netinet ip_fw.h ip_fw2.c ip_fw_pfil.c

Andre Oppermann oppermann at networx.ch
Thu Feb 10 15:07:14 GMT 2005


Gleb Smirnoff wrote:
> 
>   Andre,
> 
> On Thu, Feb 10, 2005 at 03:18:32PM +0100, Andre Oppermann wrote:
> A> > Andre, all other edge netgraph nodes does not queue packet for ISR.
> A> > "Edge node" stands for a node which is an interface between netgraph and
> A> > other networking subsystem. It has been proved in practice, that it is not
> A> > needed. And in theory, there is no way ro recurse. You say, that you can
> A> > describe a normal setup which leads to recursion. I can't. So pls describe it.
> A>
> A> There is a major difference to the other edge nodes.  When ng_ipfw is
> A> being entered the pfil lock is still held we are in the middle of
> A> ip_input/ouput() processing.  For example I can quite readily imagine
> A> someone ng-diverting all SMTP TCP sessions into some kind tunneling
> A> encapsulation, perhaps through ng_ppp->ng_l2tp which causes the packet
> A> so re-enter ip_input() again.  Then it may be that I have another
> A> ng-diversion either intentionally or accidentially causing my stack
> A> to grow until it explodes.  In addition the pfil read lock is held
> A> all the time and even recursed on.  Given a certain traffic level it
> A> may load to deadlock or prevent any pfil hooks changes for a long time.
> A> This is dangerous territory and netgraph is not bound in depth or path
> A> a packet may take.
> A> ng_ipfw is special in this regard compared to other netgraph edges
> A> precisely because it gets called from the middle of ip_input/output().
> A> And because of that you have to do some special treatment.  I wouldn't
> A> complain if there were a guarnatee that packets going out via ng_ipfw
> A> absolutely come back through it again, but there isn't.  You can set
> A> it up as one-way thing.
> 
> You haven't gave an example of normal setup, bringing recursion. Neither
> ng_ppp nor ng_l2tp can reinject packet to IP stack. Looking for recursion,
> you should look only at edge nodes. ng_ppp and ng_l2tp are protocol implementing
> nodes, not edge ones. Probably you meant that packet diverted via ng_ipfw
> traverses ng_ppp|ng_l2tp and comes on ng_iface node, which implements system
> interface. I will doubtfully count this setup as "normal", but anyway there is
> no recursion. ng_iface, as a well designed edge node, queues packets for ISR.

Ok, I was looking for such a clear explanation.  I'm not an netgraph expert
at all and need you to tell me what happens in there to get the full picture.
Thanks for this writeup.  So far I was assuming the worst case.

Are you sure ng_iface does not and never will do direct dispatch?

> Possible recursion, you are speaking about should be solved in other direction.
> Every edge node should queue packets, when they exit netgraph. And they all do.
> If you find one that does not, we will fix it not ng_ipfw.

How does the return path for ng_ipfw do it before it sends the packet back
to ip_input/output()?  And different question: If netgraph doesn't queue
the packet why can't you just pick it up again and let it continue directly
from ip_ipfw_pfil?  E.g. why does it have to reinject the packet?

> A> > A> The other thing is the passing back of errors from netgraph.  Only
> A> > A> certain kinds of errors should be reported back and others converted
> A> > A> to some default error.  It is very confusing for an application
> A> > A> developer to get a very (from his POV) non-sensical error message
> A> > A> like ENOTCONN when writing on a socket.  He doesn't have knowledge
> A> > A> of the ipfw/netgraph stuff that happens in the kernel and it makes
> A> > A> debugging extremely confusing.  In the he blames FreeBSDs socket
> A> > A> implementation whereas it was only some error in setting up the
> A> > A> netgraph by the administrator.
> A> >
> A> > I have already replied this in net@ list. OK, I'll ask again: Do you want
> A> > ng_ipfw_rcvdata() to end with "return (0)"?
> A>
> A> No.  I want it to pass EACCES, ENOMEM/ENOBUFS and everything else as
> A> ENXIO (including if hook not connected).  In a previous email I said
> A> ESRCH was ok, but it really doesn't make sense and is pretty confusing
> A> to an application writer.  ENXIO is much better and not to be confused
> A> with possible programming errors from application side.
> 
> I have asked you in mail: "Do you want this ugly construction at and of
> ng_ipfw_input()?"
> 
>         NG_SEND_DATA_ONLY(error, hook, m);
> 
>         if (error == EACCES || error == ENOMEM || error == ENOBUFS)
>                 return (error);
>         else
>                 return (0);
> 
> Do you want it?

No, I want this:

	NG_SEND_DATA_ONLY(error, hook, m);
 
	if (error == EACCES || error == ENOMEM || error == ENOBUFS)
		return (error);
	else if (error != 0)
		return (ENXIO);
	else
		return (0);

or alternatively:

	switch (error) {
		case 0:
			return (0);
			break;	/* Not reached. */

		case EACCES:
		case ENOMEM:
		case ENOBUFS:
			return (error);
			break;	/* Not reached. */

		default:
			return (ENXIO);
			break;	/* Not reached. */
	}


> Ok, let's treat question about substituting ESRCH with ENXIO separately. I can
> accept it, just to meet your wishes. Please, ask Ruslan for review, since he
> showed interest to this node particularly, and uses netgraph in general.

-- 
Andre


More information about the cvs-src mailing list