Date: Fri, 25 May 2001 20:06:02 +0200 (SAT) From: John Hay <jhay@icomtek.csir.co.za> To: gunther@aurora.regenstrief.org (Gunther Schadow) Cc: freebsd-net@FreeBSD.ORG Subject: Re: NetWare / IPX routing facts and a question Message-ID: <200105251806.f4PI62P92317@zibbi.icomtek.csir.co.za> In-Reply-To: <3B0D9BE4.80CB1E35@aurora.regenstrief.org> from Gunther Schadow at "May 24, 2001 11:40:20 pm"
next in thread | previous in thread | raw e-mail | index | archive | help
> > > TAKE: Now the problem. IPX acts very strangely. Oftentimes I > can connect to the main IPX network and sometimes Novell servers > aren't seen. They appear in the server list (nlist, or SAP stuff) > but as soon as you try connecting to them they sometimes can't be > connected. We have a large campus network with thousands of Novell > servers. All of them are supposed to use 802.2 and almost all of > them do. Certainly the servers I'm interested in use the right > frame type. The systems that talk though the FreeBSD router are > DOS, Novell, and Windows machines. We run a Revelation data base > over IPX and it sometimes will do fine and sometimes fail to start. > I am sure there is something completely stupid going on. > Here is a patch that I'm running. The problem is that on a large network the SAP table can grow very large and take a long time to be transmitted. (Only 7 SAP entries fit into a packet and you need to space them 50ms apart.) The current code will do it in one go, but during that time it will not read any received packets so the input buffers can overflow. The patch will check for received packets between each SAP broadcast and process them. The other thing that this patch does is to add the ability to filter certain SAP types. You can specify them on the commandline with the -f option. So you can do something like this: IPXrouted -s -f 0x640 -f 0x64e John -- John Hay -- John.Hay@icomtek.csir.co.za diff -u IPXrouted.org/defs.h IPXrouted/defs.h --- IPXrouted.org/defs.h Tue Aug 31 08:32:48 1999 +++ IPXrouted/defs.h Tue Aug 22 12:16:43 2000 @@ -104,4 +104,4 @@ void toall(void (*f)(struct sockaddr *, int, struct interface *, int), struct rt_entry *, int); void rip_input(struct sockaddr *, int); - +void check_packets(void); diff -u IPXrouted.org/main.c IPXrouted/main.c --- IPXrouted.org/main.c Tue Aug 31 08:32:48 1999 +++ IPXrouted/main.c Tue Aug 22 21:13:09 2000 @@ -152,8 +152,28 @@ argv++, argc--; continue; } + if (strcmp(*argv, "-f") == 0) { + if(no_sap_filters == SAPFILTERS) { + fprintf(stderr, "Too many SAP filters.\n"); + exit(1); + } + argv++, argc--; + if(argc == 0) { + fprintf(stderr, "Missing SAP service number " + "after -f\n"); + exit(1); + } + sap_filter[no_sap_filters] = strtoul(*argv, NULL, 0); + fprintf(stderr, "SAP filter %d, 0x%04X\n", + no_sap_filters + 1, sap_filter[no_sap_filters]); + sap_filter[no_sap_filters] = + htons(sap_filter[no_sap_filters]); + no_sap_filters++; + argv++, argc--; + continue; + } fprintf(stderr, - "usage: ipxrouted [ -s ] [ -q ] [ -t ] [ -g ] [ -l ] [ -N ]\n"); + "usage: ipxrouted [ -s ] [ -q ] [ -t ] [ -g ] [ -l ] [ -N -f <SAP> ]\n"); exit(1); } @@ -266,6 +286,51 @@ if (ttime > (lastbcast + TIMER_RATE + (TIMER_RATE * 2 / 3))) { dobcast = 1; syslog(LOG_ERR, "Missed alarm"); + } + } +} + +void +check_packets(void) +{ + int nfds, rval; + fd_set fdvar; + struct timeval to; + + nfds = ripsock; + if(dosap && (sapsock > nfds)) + nfds = sapsock; + nfds++; + + for(;;) { + to.tv_sec = 0; + to.tv_usec = 0; + + FD_ZERO(&fdvar); + if (dosap) { + FD_SET(sapsock, &fdvar); + } + FD_SET(ripsock, &fdvar); + + rval = select(nfds, &fdvar, NULL, NULL, &to); + + if(rval == 0) + return; + + if(rval == -1) { + if(errno == EINTR) + return; + perror("during select"); + exit(1); + } + + if(FD_ISSET(ripsock, &fdvar)) + process(ripsock, RIP_PKT); + + if(dosap && FD_ISSET(sapsock, &fdvar)) { + if(ftrace) + fprintf(ftrace, "YESYES got one\n"); + process(sapsock, SAP_PKT); } } } diff -u IPXrouted.org/sap.h IPXrouted/sap.h --- IPXrouted.org/sap.h Tue Aug 31 08:32:48 1999 +++ IPXrouted/sap.h Tue Aug 22 19:44:34 2000 @@ -82,6 +82,10 @@ extern struct sap_packet *sap_msg; +#define SAPFILTERS 10 +extern int no_sap_filters; +extern u_short sap_filter[SAPFILTERS]; + void sapinit(void); void sap_input(struct sockaddr *from, int size); void sapsndmsg(struct sockaddr *dst, int flags, struct interface *ifp, diff -u IPXrouted.org/sap_input.c IPXrouted/sap_input.c --- IPXrouted.org/sap_input.c Tue Aug 31 08:32:48 1999 +++ IPXrouted/sap_input.c Tue Aug 22 20:25:06 2000 @@ -38,6 +38,9 @@ int dognreply = 1; +int no_sap_filters; +u_short sap_filter[SAPFILTERS]; + /* * Process a newly received packet. */ @@ -144,6 +147,16 @@ */ if (ntohs(n->hops) > HOPCNT_INFINITY) continue; + if(no_sap_filters) { + int x; + + for(x = 0; x < no_sap_filters; x++) + if(sap_filter[x] == n->ServType) + break; + if(x < no_sap_filters) + continue; + } + sap = sap_lookup(n->ServType, n->ServName); if (sap == 0) { if (ntohs(n->hops) == HOPCNT_INFINITY) diff -u IPXrouted.org/sap_output.c IPXrouted/sap_output.c --- IPXrouted.org/sap_output.c Tue Aug 31 08:32:48 1999 +++ IPXrouted/sap_output.c Tue Aug 22 12:16:43 2000 @@ -121,7 +121,6 @@ struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) dst; af_output_t *output = afswitch[dst->sa_family].af_output; int size, metric; - int delay = 0; if (sipx->sipx_port == 0) sipx->sipx_port = htons(IPXPORT_SAP); @@ -136,11 +135,9 @@ (*output)(sapsock, flags, dst, size); TRACE_SAP_OUTPUT(ifp, dst, size); n = sap_msg->sap; - delay++; - if(delay == 2) { - usleep(50000); - delay = 0; - } + usleep(50000); + /* Check and process packets received. */ + check_packets(); } if (changesonly && !(sap->state & RTS_CHANGED)) To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-net" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200105251806.f4PI62P92317>