diff --git a/RELNOTES b/RELNOTES index 46c28b35..8eeac4a4 100644 --- a/RELNOTES +++ b/RELNOTES @@ -82,6 +82,16 @@ work on other platforms. Please report any problems and suggested fixes to - Fixed a cosmetic bug where pretty-printing valid domain-search options would result in an erroneous error log message ('garbage in format string'). +- A bug in DLPI packet transmission (Solaris, HP/UX) that caused the server + to stop receiving packets is fixed. The same fix also means that the MAC + address will no longer appear 'bogus' on DLPI-based systems. + +- A bug in select handling was discovered where the results of one select() + call were discarded, causing the server to process the next select() call + and use more system calls than required. This has been repaired - the + sockets will be handled after the first return from select(), resulting in + fewer system calls. + Changes since 4.1.0b1 - A missing "else" in dhcrelay.c could have caused an interface not to diff --git a/common/dlpi.c b/common/dlpi.c index a2d5cb2d..56f6b3a9 100644 --- a/common/dlpi.c +++ b/common/dlpi.c @@ -204,7 +204,6 @@ int if_register_dlpi (info) log_fatal ("Can't open DLPI device for %s: %m", info -> name); } - /* * Submit a DL_INFO_REQ request, to find the dl_mac_type and * dl_provider_style @@ -292,8 +291,6 @@ int if_register_dlpi (info) } #endif - get_hw_addr(info->name, &info->hw_address); - return sock; } @@ -642,6 +639,7 @@ ssize_t receive_packet (interface, buf, len, from, hfrom) #endif if (length <= 0) { + log_error("receive_packet: %m"); return length; } @@ -665,8 +663,7 @@ ssize_t receive_packet (interface, buf, len, from, hfrom) memcpy ((char *) &hfrom -> hbuf [1], srcaddr, phys_len); } else { - memcpy ((char *) &hfrom -> hbuf [1], (char *) &srcaddr [phys_len], - phys_len); + memcpy((char *)&hfrom->hbuf[1], srcaddr + sap_len, phys_len); } } else if (hfrom) { @@ -694,9 +691,16 @@ ssize_t receive_packet (interface, buf, len, from, hfrom) offset = decode_udp_ip_header (interface, dbuf, bufix, from, length, &paylen); - /* If the IP or UDP checksum was bad, skip the packet... */ + /* + * If the IP or UDP checksum was bad, skip the packet... + * + * Note: this happens all the time when writing packets via the + * fallback socket. The packet received by streams does not have + * the IP or UDP checksums filled in, as those are calculated by + * the hardware. + */ if (offset < 0) { - return 0; + return 0; } bufix += offset; @@ -1147,22 +1151,32 @@ static int dlpiunitdataind (fd, daddr, daddrlen, ctl.maxlen = DLPI_MAXDLBUF; ctl.len = 0; ctl.buf = (char *)buf; - + data.maxlen = dlen; data.len = 0; data.buf = (char *)dbuf; - + result = getmsg (fd, &ctl, &data, &flags); - + + /* + * The getmsg() manpage says: + * + * "On successful completion, a non-negative value is returned." + * + * This suggests that if MOREDATA or MORECTL are set, we error? + * This seems to be safe as it never seems to happen. Still, + * set a log message, so we know if it ever starts happening. + */ if (result != 0) { + log_debug("dlpiunitdataind: %m"); return -1; } - + if (ctl.len < sizeof (dl_unitdata_ind_t) || dlp -> unitdata_ind.dl_primitive != DL_UNITDATA_IND) { return -1; } - + if (data.len <= 0) { return data.len; } @@ -1186,11 +1200,11 @@ static int dlpiunitdataind (fd, daddr, daddrlen, if (daddrlen) { *daddrlen = dlp -> unitdata_ind.dl_dest_addr_length; } - + if (grpaddr) { *grpaddr = dlp -> unitdata_ind.dl_group_address; } - + return data.len; } @@ -1320,7 +1334,7 @@ void maybe_setup_fallback () void get_hw_addr(const char *name, struct hardware *hw) { - int sock; + int sock, unit; long buf[DLPI_MAXDLBUF]; union DL_primitives *dlp; @@ -1360,6 +1374,20 @@ get_hw_addr(const char *name, struct hardware *hw) { (unsigned long)dlp->info_ack.dl_mac_type); } + if (dlp->info_ack.dl_provider_style == DL_STYLE2) { + /* + * Attach to the device. If this fails, the device + * does not exist. + */ + unit = dlpiunit((char *)name); + + if (dlpiattachreq(sock, unit) < 0 || + dlpiokack(sock, (char *)buf) < 0) { + log_fatal("Can't attach DLPI device for %s: %m", + name); + } + } + /* * Submit a DL_PHYS_ADDR_REQ request, to find * the hardware address. diff --git a/omapip/dispatch.c b/omapip/dispatch.c index dda8ce77..5b234dc5 100644 --- a/omapip/dispatch.c +++ b/omapip/dispatch.c @@ -359,7 +359,10 @@ isc_result_t omapi_one_dispatch (omapi_object_t *wo, /* We are dry now */ trigger_event(&rw_queue_empty); /* Wait for a packet or a timeout... XXX */ - count = select(max + 1, &rr, &ww, &xx, t ? &to : NULL); + r = rr; + w = ww; + x = xx; + count = select(max + 1, &r, &w, &x, t ? &to : NULL); } /* Get the current time... */