Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 23 Jul 2006 21:49:28 GMT
From:      Rauf Kuliyev <rauf@kuliyev.com>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   bin/100765: [PATCH] natd+kqueue
Message-ID:  <200607232149.k6NLnSIS061468@www.freebsd.org>
Resent-Message-ID: <200607232150.k6NLoGkO039566@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         100765
>Category:       bin
>Synopsis:       [PATCH] natd+kqueue
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          update
>Submitter-Id:   current-users
>Arrival-Date:   Sun Jul 23 21:50:16 GMT 2006
>Closed-Date:
>Last-Modified:
>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:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200607232149.k6NLnSIS061468>