From nobody@FreeBSD.org  Sun Jul 23 21:49:31 2006
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 038EE16A4DD
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 23 Jul 2006 21:49:31 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [216.136.204.117])
	by mx1.FreeBSD.org (Postfix) with ESMTP id BCEA043D55
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 23 Jul 2006 21:49:30 +0000 (GMT)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.13.1/8.13.1) with ESMTP id k6NLnSe5061475
	for <freebsd-gnats-submit@FreeBSD.org>; Sun, 23 Jul 2006 21:49:28 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.13.1/8.13.1/Submit) id k6NLnSIS061468;
	Sun, 23 Jul 2006 21:49:28 GMT
	(envelope-from nobody)
Message-Id: <200607232149.k6NLnSIS061468@www.freebsd.org>
Date: Sun, 23 Jul 2006 21:49:28 GMT
From: Rauf Kuliyev <rauf@kuliyev.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: [PATCH] natd+kqueue
X-Send-Pr-Version: www-2.3

>Number:         100765
>Category:       bin
>Synopsis:       [patch] natd(8): add support for kqueue in natd
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          update
>Submitter-Id:   current-users
>Arrival-Date:   Sun Jul 23 21:50:16 GMT 2006
>Closed-Date:    Fri Jun 15 09:57:33 GMT 2007
>Last-Modified:  Fri Jun 15 09:57:33 GMT 2007
>Originator:     Rauf Kuliyev
>Release:        FreeBSD 6.1-RELEASE-p3
>Organization:
>Environment:
FreeBSD laptop.kuliyev.com 6.1-RELEASE-p3 FreeBSD 6.1-RELEASE-p3 #0: Mon Jul 10 11:56:26 AZST 2006     root@laptop.kuliyev.com:/usr/obj/usr/src/sys/C1110  i386

>Description:
Support for KQUEUE in natd:

--- natd.c.orig	Mon May  2 15:13:38 2005
+++ natd.c	Mon Jul 24 02:38:51 2006
@@ -46,6 +46,8 @@
 #include <unistd.h>
 
 #include "natd.h"
+#include <sys/event.h>
+
 
 struct instance {
 	const char		*name;
@@ -74,6 +76,9 @@
 struct instance *mip;
 int ninstance = 1;
 
+int kq;	
+struct kevent kev;
+
 /* 
  * Default values for input and output
  * divert socket ports.
@@ -151,7 +156,6 @@
 int main (int argc, char** argv)
 {
 	struct sockaddr_in	addr;
-	fd_set			readMask;
 	int			fdMax;
 /* 
  * Initialize packet aliasing software.
@@ -358,6 +362,9 @@
 		if (mip->aliasAddr.s_addr != INADDR_NONE)
 			LibAliasSetAddress (mla, mip->aliasAddr);
 	}
+		if( (kq = kqueue() ) == -1) {
+			Quit ("Kqueue failed.");
+		}
 
 	while (running) {
 		mip = LIST_FIRST(&root);	/* XXX: simon */
@@ -370,64 +377,72 @@
 			DoAliasing (mip->divertInOut, DONT_KNOW);
 			continue;
 		}
-/* 
- * Build read mask from socket descriptors to select.
- */
-		FD_ZERO (&readMask);
 /*
  * Check if new packets are available.
  */
 		LIST_FOREACH(mip, &root, list) {
-			if (mip->divertIn != -1)
-				FD_SET (mip->divertIn, &readMask);
+			if (mip->divertIn != -1) {
+				EV_SET(&kev, mip->divertIn, EVFILT_READ, EV_ADD, 0, 0, NULL);
+				if( (kevent(kq, &kev, 1, NULL, 0, NULL)) == -1) 
+					Quit("Kevent registration error: divertIn");
+			}
 
-			if (mip->divertOut != -1)
-				FD_SET (mip->divertOut, &readMask);
+			if (mip->divertOut != -1) {
+				EV_SET(&kev, mip->divertOut, EVFILT_READ, EV_ADD, 0, 0, NULL);
+				if( (kevent(kq, &kev, 1, NULL, 0, NULL)) == -1)
+					Quit("Kevent registration error: divertOut");
+			}
+
+			if (mip->divertInOut != -1) {
+				EV_SET(&kev, mip->divertInOut, EVFILT_READ, EV_ADD, 0, 0, NULL);
+				if( (kevent(kq, &kev, 1, NULL, 0, NULL)) == -1)
+					Quit("Kevent registration error: divertInOut");
+			}
 
-			if (mip->divertInOut != -1)
-				FD_SET (mip->divertInOut, &readMask);
 		}
 /*
  * Routing info is processed always.
  */
-		if (routeSock != -1)
-			FD_SET (routeSock, &readMask);
-
-		if (divertGlobal != -1)
-			FD_SET (divertGlobal, &readMask);
+		if (routeSock != -1) {
+			EV_SET(&kev, routeSock, EVFILT_READ, EV_ADD, 0, 0, NULL);
+			if( (kevent(kq, &kev, 1, NULL, 0, NULL)) == -1)
+				Quit("Kevent registration error: routeSock");
+		}
 
-		if (select (fdMax + 1,
-			    &readMask,
-			    NULL,
-			    NULL,
-			    NULL) == -1) {
+		if (divertGlobal != -1) {
+			EV_SET(&kev, divertGlobal, EVFILT_READ, EV_ADD, 0, 0, NULL);
+			if( (kevent(kq, &kev, 1, NULL, 0, NULL)) == -1)
+				Quit("Kevent registration error: divertGlobal");
+		}
 
-			if (errno == EINTR)
-				continue;
 
+		if (kevent(kq, NULL, 0, &kev, 1, NULL) == -1) {
 			Quit ("Select failed.");
 		}
 
+
+
 		if (divertGlobal != -1)
-			if (FD_ISSET (divertGlobal, &readMask))
+			if (kev.ident == divertGlobal) 
 				DoGlobal (divertGlobal);
+
 		LIST_FOREACH(mip, &root, list) {
 			mla = mip->la;
 			if (mip->divertIn != -1)
-				if (FD_ISSET (mip->divertIn, &readMask))
+				if (kev.ident == mip->divertIn)
 					DoAliasing (mip->divertIn, INPUT);
 
 			if (mip->divertOut != -1)
-				if (FD_ISSET (mip->divertOut, &readMask))
+				if (kev.ident == mip->divertOut)
 					DoAliasing (mip->divertOut, OUTPUT);
 
 			if (mip->divertInOut != -1) 
-				if (FD_ISSET (mip->divertInOut, &readMask))
+				if (kev.ident == mip->divertInOut)
 					DoAliasing (mip->divertInOut, DONT_KNOW);
 
 		}
 		if (routeSock != -1)
-			if (FD_ISSET (routeSock, &readMask))
+			if (kev.ident == routeSock)
 				HandleRoutingInfo (routeSock);
 	}
 
>How-To-Repeat:
cd /usr/src/sbin/natd/ && patch < /path/to/natd.patch && make clean all install clean

>Fix:

>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->feedback 
State-Changed-By: jmg 
State-Changed-When: Sun Sep 24 07:00:02 UTC 2006 
State-Changed-Why:  
This patch isn't complete...  You hsould to move the code that sets up the 
events once outside the while (running) loop...  You also might want to 
use udata to simplify the processing of events... 

http://www.freebsd.org/cgi/query-pr.cgi?pr=100765 
State-Changed-From-To: feedback->closed 
State-Changed-By: linimon 
State-Changed-When: Fri Jun 15 09:56:14 UTC 2007 
State-Changed-Why:  
Feedback timeout (> 6 months).  Note to submitter: if you are still 
interested in adding this functionality, please submit a followup and 
we can reopen it. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=100765 
>Unformatted:
