Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 9 Mar 2017 06:01:24 +0000 (UTC)
From:      Mariusz Zaborski <oshogbo@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r314948 - in head: lib/libstand sys/boot/i386/libi386
Message-ID:  <201703090601.v2961OJx077853@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: oshogbo
Date: Thu Mar  9 06:01:24 2017
New Revision: 314948
URL: https://svnweb.freebsd.org/changeset/base/314948

Log:
  Try to extract the RFC1048 data from PXE. If we get enough info we can skip
  the bootp(). It removes unnecessary DHCP request from pxeloader.
  
  Submitted by:	kczekirda
  Sponsored by:	Oktawave
  Initiated by:	Matthew Dillon
  Reviewed by:	smh, gnn, bapt, oshogbo
  MFC after:	3 weeks
  Differential Revision:	https://reviews.freebsd.org/D9847

Modified:
  head/lib/libstand/bootp.c
  head/lib/libstand/bootp.h
  head/sys/boot/i386/libi386/pxe.c

Modified: head/lib/libstand/bootp.c
==============================================================================
--- head/lib/libstand/bootp.c	Thu Mar  9 05:30:05 2017	(r314947)
+++ head/lib/libstand/bootp.c	Thu Mar  9 06:01:24 2017	(r314948)
@@ -344,6 +344,17 @@ bad:
 	return (-1);
 }
 
+int
+dhcp_try_rfc1048(u_char *cp, u_int len)
+{
+
+	expected_dhcpmsgtype = DHCPACK;
+	if (bcmp(vm_rfc1048, cp, sizeof(vm_rfc1048)) == 0) {
+		return (vend_rfc1048(cp, len));
+	}
+	return (-1);
+}
+
 static int
 vend_rfc1048(cp, len)
 	u_char *cp;

Modified: head/lib/libstand/bootp.h
==============================================================================
--- head/lib/libstand/bootp.h	Thu Mar  9 05:30:05 2017	(r314947)
+++ head/lib/libstand/bootp.h	Thu Mar  9 06:01:24 2017	(r314948)
@@ -22,6 +22,8 @@
  * $FreeBSD$
  */
 
+#ifndef _BOOTP_H_
+#define _BOOTP_H_
 
 struct bootp {
 	unsigned char	bp_op;		/* packet opcode type */
@@ -145,3 +147,7 @@ struct cmu_vend {
 
 /* v_flags values */
 #define VF_SMASK	1	/* Subnet mask field contains valid data */
+
+int	dhcp_try_rfc1048(u_char *cp, u_int len);
+
+#endif /* _BOOTP_H_ */

Modified: head/sys/boot/i386/libi386/pxe.c
==============================================================================
--- head/sys/boot/i386/libi386/pxe.c	Thu Mar  9 05:30:05 2017	(r314947)
+++ head/sys/boot/i386/libi386/pxe.c	Thu Mar  9 06:01:24 2017	(r314948)
@@ -101,6 +101,7 @@ extern void			__bangpxeentry(void);
 extern u_int16_t		__pxenvseg;
 extern u_int16_t		__pxenvoff;
 extern void			__pxenventry(void);
+extern struct in_addr		servip;
 
 struct netif_dif pxe_ifs[] = {
 /*	dif_unit        dif_nsel        dif_stats       dif_private     */
@@ -276,17 +277,38 @@ pxe_open(struct open_file *f, ...)
 			}
 			if (pxe_debug)
 				printf("pxe_open: netif_open() succeeded\n");
+
+			if (socktodesc(pxe_sock) == NULL) {
+				printf("pxe_open: bad socket %d\n", pxe_sock);
+				return (ENXIO);
+			}
+
 		}
 		if (rootip.s_addr == 0) {
 			/*
-			 * Do a bootp/dhcp request to find out where our
+			 * Try to extract the RFC1048 data from PXE.
+			 * If fail do a bootp/dhcp request to find out where our
 			 * NFS/TFTP server is. Even if we dont get back
 			 * the proper information, fall back to the server
 			 * which brought us to life and a default rootpath.
 			 */
-			bootp(pxe_sock, BOOTP_PXE);
+
+			if (dhcp_try_rfc1048(bootplayer.vendor.d, BOOTP_DHCPVEND) < 0) {
+				if (pxe_debug)
+					printf("pxe_open: no RFC1048 data in PXE Cache\n");
+				bootp(pxe_sock, BOOTP_PXE);
+			} else if (pxe_debug) {
+				printf("pxe_open: loaded RFC1048 data from PXE Cache\n");
+			}
+
 			if (rootip.s_addr == 0)
 				rootip.s_addr = bootplayer.sip;
+			if (gateip.s_addr == 0)
+				gateip.s_addr = bootplayer.gip;
+			if (myip.s_addr == 0)
+				myip.s_addr = bootplayer.yip;
+			if (servip.s_addr == 0)
+				servip = rootip;
 
 			netproto = NET_NFS;
 			if (tftpip.s_addr != 0) {
@@ -323,6 +345,9 @@ pxe_open(struct open_file *f, ...)
 			printf("pxe_open: server addr: %s\n", inet_ntoa(rootip));
 			printf("pxe_open: server path: %s\n", rootpath);
 			printf("pxe_open: gateway ip:  %s\n", inet_ntoa(gateip));
+			printf("pxe_open: my ip:       %s\n", inet_ntoa(myip));
+			printf("pxe_open: netmask:     %s\n", intoa(netmask));
+			printf("pxe_open: servip:      %s\n", inet_ntoa(servip));
 
 			if (netproto == NET_TFTP) {
 				setenv("boot.tftproot.server", inet_ntoa(rootip), 1);



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