From patchwork Fri May 18 15:45:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Huth X-Patchwork-Id: 916442 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40nXbF4wLZz9s29 for ; Sat, 19 May 2018 01:46:33 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 40nXbF3C6JzF2DQ for ; Sat, 19 May 2018 01:46:33 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=redhat.com X-Original-To: slof@lists.ozlabs.org Delivered-To: slof@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=redhat.com (client-ip=66.187.233.73; helo=mx1.redhat.com; envelope-from=thuth@redhat.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=redhat.com Received: from mx1.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 40nXZL4BzGzF2GM for ; Sat, 19 May 2018 01:45:46 +1000 (AEST) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 66AACBB40A; Fri, 18 May 2018 15:45:44 +0000 (UTC) Received: from thh440s.redhat.com (ovpn-116-82.ams2.redhat.com [10.36.116.82]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5AB9583B67; Fri, 18 May 2018 15:45:43 +0000 (UTC) From: Thomas Huth To: slof@lists.ozlabs.org Date: Fri, 18 May 2018 17:45:30 +0200 Message-Id: <1526658340-1992-2-git-send-email-thuth@redhat.com> In-Reply-To: <1526658340-1992-1-git-send-email-thuth@redhat.com> References: <1526658340-1992-1-git-send-email-thuth@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Fri, 18 May 2018 15:45:44 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Fri, 18 May 2018 15:45:44 +0000 (UTC) for IP:'10.11.54.5' DOMAIN:'int-mx05.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'thuth@redhat.com' RCPT:'' Subject: [SLOF] [PATCH v2 01/11] libnet: Get rid of unused huge_load and block_size parameters X-BeenThere: slof@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: "Patches for https://github.com/aik/SLOF" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Greg Kurz MIME-Version: 1.0 Errors-To: slof-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "SLOF" The blocksize is hard-coded to 1428 bytes in obp-tftp.fs, so instead of hardcoding this in the Forth code, we could also move this into tftp.c directly instead. A similar condition exists with the huge-tftp-load parameter. While this non-standard variable could still be changed in the obp-tftp package, it does not make much sense to set it to zero since you only lose the possibility to do huge TFTP loads with index wrap-around in that case. Signed-off-by: Thomas Huth Reviewed-by: Greg Kurz --- lib/libnet/libnet.code | 4 +--- lib/libnet/netapps.h | 3 +-- lib/libnet/netload.c | 11 ++++------- lib/libnet/tftp.c | 13 +++---------- lib/libnet/tftp.h | 2 +- slof/fs/packages/obp-tftp.fs | 3 --- 6 files changed, 10 insertions(+), 26 deletions(-) diff --git a/lib/libnet/libnet.code b/lib/libnet/libnet.code index 2746782..419419d 100644 --- a/lib/libnet/libnet.code +++ b/lib/libnet/libnet.code @@ -4,11 +4,9 @@ PRIM(NET_X2d_LOAD) int alen = TOS.n; POP; char *arg = TOS.a; POP; - int blocksize = TOS.n; POP; - int hugeload = TOS.n; POP; long maxlen = TOS.n; POP; void *loadaddr = TOS.a; - TOS.n = netload(loadaddr, maxlen, hugeload, blocksize, arg, alen); + TOS.n = netload(loadaddr, maxlen, arg, alen); MIRP PRIM(NET_X2d_PING) diff --git a/lib/libnet/netapps.h b/lib/libnet/netapps.h index 0e637e1..6e00466 100644 --- a/lib/libnet/netapps.h +++ b/lib/libnet/netapps.h @@ -18,8 +18,7 @@ struct filename_ip; -extern int netload(char *buffer, int len, int huge_load, int block_size, - char *args_fs, int alen); +extern int netload(char *buffer, int len, char *args_fs, int alen); extern int ping(char *args_fs, int alen); extern int dhcp(char *ret_buffer, struct filename_ip *fn_ip, unsigned int retries, int flags); diff --git a/lib/libnet/netload.c b/lib/libnet/netload.c index 5c37fe2..8dca654 100644 --- a/lib/libnet/netload.c +++ b/lib/libnet/netload.c @@ -405,13 +405,12 @@ static void seed_rng(uint8_t mac[]) } static int tftp_load(filename_ip_t *fnip, unsigned char *buffer, int len, - unsigned int retries, int32_t mode, - int32_t blksize, int ip_vers) + unsigned int retries, int ip_vers) { tftp_err_t tftp_err; int rc; - rc = tftp(fnip, buffer, len, retries, &tftp_err, mode, blksize, ip_vers); + rc = tftp(fnip, buffer, len, retries, &tftp_err, ip_vers); if (rc > 0) { printf(" TFTP: Received %s (%d KBytes)\n", fnip->filename, @@ -510,8 +509,7 @@ static void encode_response(char *pkt_buffer, size_t size, int ip_init) } } -int netload(char *buffer, int len, int huge_load, int block_size, - char *args_fs, int alen) +int netload(char *buffer, int len, char *args_fs, int alen) { int rc; filename_ip_t fn_ip; @@ -755,8 +753,7 @@ int netload(char *buffer, int len, int huge_load, int block_size, /* Do the TFTP load and print error message if necessary */ rc = tftp_load(&fn_ip, (unsigned char *)buffer, len, - obp_tftp_args.tftp_retries, huge_load, - block_size, ip_version); + obp_tftp_args.tftp_retries, ip_version); if (obp_tftp_args.ip_init == IP_INIT_DHCP) dhcp_send_release(fn_ip.fd); diff --git a/lib/libnet/tftp.c b/lib/libnet/tftp.c index 1656c27..5e7951f 100644 --- a/lib/libnet/tftp.c +++ b/lib/libnet/tftp.c @@ -497,19 +497,15 @@ void handle_tftp_dun(uint8_t err_code) * @param _len size of destination buffer * @param _retries max number of retries * @param _tftp_err contains info about TFTP-errors (e.g. lost packets) - * @param _mode NON ZERO - multicast, ZERO - unicast - * @param _blocksize blocksize for DATA-packets * @return ZERO - error condition occurs * NON ZERO - size of received file */ int tftp(filename_ip_t * _fn_ip, unsigned char *_buffer, int _len, - unsigned int _retries, tftp_err_t * _tftp_err, - int32_t _mode, int32_t _blocksize, int _ip_version) + unsigned int _retries, tftp_err_t * _tftp_err, int _ip_version) { retries = _retries; fn_ip = _fn_ip; len = _len; - huge_load = _mode; ip_version = _ip_version; tftp_errno = 0; tftp_err = _tftp_err; @@ -523,17 +519,14 @@ int tftp(filename_ip_t * _fn_ip, unsigned char *_buffer, int _len, port_number = -1; progress_first = -1; progress_last_bytes = 0; + huge_load = 1; /* Default blocksize must be 512 for TFTP servers * which do not support the RRQ blocksize option */ blocksize = 512; /* Preferred blocksize - used as option for the read request */ - if (_blocksize < 8) - _blocksize = 8; - else if (_blocksize > MAX_BLOCKSIZE) - _blocksize = MAX_BLOCKSIZE; - sprintf(blocksize_str, "%d", _blocksize); + sprintf(blocksize_str, "%d", MAX_BLOCKSIZE); printf(" Receiving data: "); print_progress(-1, 0); diff --git a/lib/libnet/tftp.h b/lib/libnet/tftp.h index e32e473..a09cf71 100644 --- a/lib/libnet/tftp.h +++ b/lib/libnet/tftp.h @@ -41,7 +41,7 @@ typedef struct { } tftp_err_t; int tftp(filename_ip_t *, unsigned char *, int, unsigned int, - tftp_err_t *, int32_t mode, int32_t blocksize, int ip_version); + tftp_err_t *, int ip_version); int32_t handle_tftp(int fd, uint8_t *, int32_t); void handle_tftp_dun(uint8_t err_code); diff --git a/slof/fs/packages/obp-tftp.fs b/slof/fs/packages/obp-tftp.fs index 17fb980..19c11e1 100644 --- a/slof/fs/packages/obp-tftp.fs +++ b/slof/fs/packages/obp-tftp.fs @@ -12,8 +12,6 @@ s" obp-tftp" device-name -VARIABLE huge-tftp-load 1 huge-tftp-load ! - : open ( -- okay? ) true ; @@ -28,7 +26,6 @@ VARIABLE huge-tftp-load 1 huge-tftp-load ! 60000000 ( addr maxlen ) - huge-tftp-load @ d# 1428 ( addr maxlen hugetftp blocksize ) \ Add OBP-TFTP Bootstring argument, e.g. "10.128.0.1,bootrom.bin,10.128.40.1" my-args net-load dup 0< IF drop 0 THEN From patchwork Fri May 18 15:45:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Huth X-Patchwork-Id: 916443 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40nXbK2szwz9s29 for ; Sat, 19 May 2018 01:46:37 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 40nXbK1ZXtzF2Gd for ; Sat, 19 May 2018 01:46:37 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=redhat.com X-Original-To: slof@lists.ozlabs.org Delivered-To: slof@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=redhat.com (client-ip=66.187.233.73; helo=mx1.redhat.com; envelope-from=thuth@redhat.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=redhat.com Received: from mx1.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 40nXZM6lDNzF2FM for ; Sat, 19 May 2018 01:45:47 +1000 (AEST) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D057781FE15D; Fri, 18 May 2018 15:45:45 +0000 (UTC) Received: from thh440s.redhat.com (ovpn-116-82.ams2.redhat.com [10.36.116.82]) by smtp.corp.redhat.com (Postfix) with ESMTP id C484D6B5B6; Fri, 18 May 2018 15:45:44 +0000 (UTC) From: Thomas Huth To: slof@lists.ozlabs.org Date: Fri, 18 May 2018 17:45:31 +0200 Message-Id: <1526658340-1992-3-git-send-email-thuth@redhat.com> In-Reply-To: <1526658340-1992-1-git-send-email-thuth@redhat.com> References: <1526658340-1992-1-git-send-email-thuth@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Fri, 18 May 2018 15:45:45 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Fri, 18 May 2018 15:45:45 +0000 (UTC) for IP:'10.11.54.5' DOMAIN:'int-mx05.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'thuth@redhat.com' RCPT:'' Subject: [SLOF] [PATCH v2 02/11] obp-tftp: Make sure to not overwrite paflof in memory X-BeenThere: slof@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: "Patches for https://github.com/aik/SLOF" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Greg Kurz MIME-Version: 1.0 Errors-To: slof-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "SLOF" The obp-tftp package is currently using an arbitrary large value as maximal load size. If the downloaded file is big enough, we can easily erase Paflof in memory this way. Let's make sure that this can not happen by limiting the size to the amount of memory below the Paflof binary (which is close to the end of the RAM) in case of board-qemu, or the amount of memory between the minimum RAM size and the load-base on board-js2x. Signed-off-by: Thomas Huth Reviewed-by: Greg Kurz --- slof/fs/packages/obp-tftp.fs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/slof/fs/packages/obp-tftp.fs b/slof/fs/packages/obp-tftp.fs index 19c11e1..7236624 100644 --- a/slof/fs/packages/obp-tftp.fs +++ b/slof/fs/packages/obp-tftp.fs @@ -24,7 +24,13 @@ s" obp-tftp" device-name my-parent ihandle>phandle node>path encode-string s" bootpath" set-chosen - 60000000 ( addr maxlen ) + \ Determine the maximum size that we can load: + dup paflof-start < IF + paflof-start + ELSE + MIN-RAM-SIZE + THEN ( addr endaddr ) + over - ( addr maxlen ) \ Add OBP-TFTP Bootstring argument, e.g. "10.128.0.1,bootrom.bin,10.128.40.1" my-args From patchwork Fri May 18 15:45:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Huth X-Patchwork-Id: 916444 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40nXbP0tsZz9s3M for ; Sat, 19 May 2018 01:46:41 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 40nXbN6lD0zF2DQ for ; Sat, 19 May 2018 01:46:40 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=redhat.com X-Original-To: slof@lists.ozlabs.org Delivered-To: slof@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=redhat.com (client-ip=66.187.233.73; helo=mx1.redhat.com; envelope-from=thuth@redhat.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=redhat.com Received: from mx1.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 40nXZP2Z8NzF2GV for ; Sat, 19 May 2018 01:45:49 +1000 (AEST) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 12C79BB40D; Fri, 18 May 2018 15:45:47 +0000 (UTC) Received: from thh440s.redhat.com (ovpn-116-82.ams2.redhat.com [10.36.116.82]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3AD3F6B5B6; Fri, 18 May 2018 15:45:46 +0000 (UTC) From: Thomas Huth To: slof@lists.ozlabs.org Date: Fri, 18 May 2018 17:45:32 +0200 Message-Id: <1526658340-1992-4-git-send-email-thuth@redhat.com> In-Reply-To: <1526658340-1992-1-git-send-email-thuth@redhat.com> References: <1526658340-1992-1-git-send-email-thuth@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Fri, 18 May 2018 15:45:47 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Fri, 18 May 2018 15:45:47 +0000 (UTC) for IP:'10.11.54.5' DOMAIN:'int-mx05.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'thuth@redhat.com' RCPT:'' Subject: [SLOF] [PATCH v2 03/11] libnet: Pass tftp_retries and ip_version via struct filename_ip X-BeenThere: slof@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: "Patches for https://github.com/aik/SLOF" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Greg Kurz MIME-Version: 1.0 Errors-To: slof-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "SLOF" When we will support loading of pxelinux.cfg files later, we have to call the tftp load function multiple times from different places. To avoid that we've also got to pass around the tftp_retries and ip_version information via function parameters to all spots, let's rather put them into struct filename_ip since we've got this struct filename_ip info available every- where already. While we're at it, also drop the __attribute__((packed)) from the struct. The struct is only used internally, without exchanging it with the outside world, so the attribute is certainly not necessary here. Reviewed-by: Greg Kurz Signed-off-by: Thomas Huth --- lib/libnet/netload.c | 11 ++++++----- lib/libnet/tftp.c | 6 +++--- lib/libnet/tftp.h | 10 +++++----- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/lib/libnet/netload.c b/lib/libnet/netload.c index 8dca654..407d173 100644 --- a/lib/libnet/netload.c +++ b/lib/libnet/netload.c @@ -404,13 +404,12 @@ static void seed_rng(uint8_t mac[]) srand(seed); } -static int tftp_load(filename_ip_t *fnip, unsigned char *buffer, int len, - unsigned int retries, int ip_vers) +static int tftp_load(filename_ip_t *fnip, void *buffer, int len) { tftp_err_t tftp_err; int rc; - rc = tftp(fnip, buffer, len, retries, &tftp_err, ip_vers); + rc = tftp(fnip, buffer, len, &tftp_err); if (rc > 0) { printf(" TFTP: Received %s (%d KBytes)\n", fnip->filename, @@ -737,6 +736,9 @@ int netload(char *buffer, int len, char *args_fs, int alen) fn_ip.filename[sizeof(fn_ip.filename)-1] = 0; } + fn_ip.ip_version = ip_version; + fn_ip.tftp_retries = obp_tftp_args.tftp_retries; + if (ip_version == 4) { printf(" Requesting file \"%s\" via TFTP from %d.%d.%d.%d\n", fn_ip.filename, @@ -752,8 +754,7 @@ int netload(char *buffer, int len, char *args_fs, int alen) } /* Do the TFTP load and print error message if necessary */ - rc = tftp_load(&fn_ip, (unsigned char *)buffer, len, - obp_tftp_args.tftp_retries, ip_version); + rc = tftp_load(&fn_ip, buffer, len); if (obp_tftp_args.ip_init == IP_INIT_DHCP) dhcp_send_release(fn_ip.fd); diff --git a/lib/libnet/tftp.c b/lib/libnet/tftp.c index 5e7951f..b7121fe 100644 --- a/lib/libnet/tftp.c +++ b/lib/libnet/tftp.c @@ -501,12 +501,12 @@ void handle_tftp_dun(uint8_t err_code) * NON ZERO - size of received file */ int tftp(filename_ip_t * _fn_ip, unsigned char *_buffer, int _len, - unsigned int _retries, tftp_err_t * _tftp_err, int _ip_version) + tftp_err_t * _tftp_err) { - retries = _retries; + retries = _fn_ip->tftp_retries; fn_ip = _fn_ip; len = _len; - ip_version = _ip_version; + ip_version = _fn_ip->ip_version; tftp_errno = 0; tftp_err = _tftp_err; tftp_err->bad_tftp_packets = 0; diff --git a/lib/libnet/tftp.h b/lib/libnet/tftp.h index a09cf71..c94c94d 100644 --- a/lib/libnet/tftp.h +++ b/lib/libnet/tftp.h @@ -29,8 +29,10 @@ struct filename_ip { ip6_addr_t server_ip6; ip6_addr_t dns_ip6; char filename[256]; - int fd; -} __attribute__ ((packed)); + int fd; + int ip_version; + int tftp_retries; +}; typedef struct filename_ip filename_ip_t; typedef struct { @@ -40,9 +42,7 @@ typedef struct { uint32_t blocks_received; } tftp_err_t; -int tftp(filename_ip_t *, unsigned char *, int, unsigned int, - tftp_err_t *, int ip_version); - +int tftp(filename_ip_t *fnip, unsigned char *buf, int len, tftp_err_t *err); int32_t handle_tftp(int fd, uint8_t *, int32_t); void handle_tftp_dun(uint8_t err_code); int parse_tftp_args(char buffer[], char *server_ip, char filename[], int fd, int len); From patchwork Fri May 18 15:45:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Huth X-Patchwork-Id: 916445 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40nXbS559lz9s3T for ; Sat, 19 May 2018 01:46:44 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 40nXbS3PJZzF2Ch for ; Sat, 19 May 2018 01:46:44 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=redhat.com X-Original-To: slof@lists.ozlabs.org Delivered-To: slof@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=redhat.com (client-ip=66.187.233.73; helo=mx1.redhat.com; envelope-from=thuth@redhat.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=redhat.com Received: from mx1.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 40nXZQ3x7xzF2GV for ; Sat, 19 May 2018 01:45:50 +1000 (AEST) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7D641BB413; Fri, 18 May 2018 15:45:48 +0000 (UTC) Received: from thh440s.redhat.com (ovpn-116-82.ams2.redhat.com [10.36.116.82]) by smtp.corp.redhat.com (Postfix) with ESMTP id 71E9683B67; Fri, 18 May 2018 15:45:47 +0000 (UTC) From: Thomas Huth To: slof@lists.ozlabs.org Date: Fri, 18 May 2018 17:45:33 +0200 Message-Id: <1526658340-1992-5-git-send-email-thuth@redhat.com> In-Reply-To: <1526658340-1992-1-git-send-email-thuth@redhat.com> References: <1526658340-1992-1-git-send-email-thuth@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Fri, 18 May 2018 15:45:48 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Fri, 18 May 2018 15:45:48 +0000 (UTC) for IP:'10.11.54.5' DOMAIN:'int-mx05.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'thuth@redhat.com' RCPT:'' Subject: [SLOF] [PATCH v2 04/11] libnet: Put code for determing TFTP error strings into a separate function X-BeenThere: slof@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: "Patches for https://github.com/aik/SLOF" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Greg Kurz MIME-Version: 1.0 Errors-To: slof-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "SLOF" This way we can easily re-use the rc --> string translation in later patches. Reviewed-by: Greg Kurz Signed-off-by: Thomas Huth --- lib/libnet/netload.c | 79 +++------------------------------------ lib/libnet/tftp.c | 103 +++++++++++++++++++++++++++++++++++++++++++++++++++ lib/libnet/tftp.h | 2 + 3 files changed, 111 insertions(+), 73 deletions(-) diff --git a/lib/libnet/netload.c b/lib/libnet/netload.c index 407d173..ba1008c 100644 --- a/lib/libnet/netload.c +++ b/lib/libnet/netload.c @@ -414,79 +414,12 @@ static int tftp_load(filename_ip_t *fnip, void *buffer, int len) if (rc > 0) { printf(" TFTP: Received %s (%d KBytes)\n", fnip->filename, rc / 1024); - } else if (rc == -1) { - netload_error(0x3003, "unknown TFTP error"); - return -103; - } else if (rc == -2) { - netload_error(0x3004, "TFTP buffer of %d bytes " - "is too small for %s", - len, fnip->filename); - return -104; - } else if (rc == -3) { - netload_error(0x3009, "file not found: %s", - fnip->filename); - return -108; - } else if (rc == -4) { - netload_error(0x3010, "TFTP access violation"); - return -109; - } else if (rc == -5) { - netload_error(0x3011, "illegal TFTP operation"); - return -110; - } else if (rc == -6) { - netload_error(0x3012, "unknown TFTP transfer ID"); - return -111; - } else if (rc == -7) { - netload_error(0x3013, "no such TFTP user"); - return -112; - } else if (rc == -8) { - netload_error(0x3017, "TFTP blocksize negotiation failed"); - return -116; - } else if (rc == -9) { - netload_error(0x3018, "file exceeds maximum TFTP transfer size"); - return -117; - } else if (rc <= -10 && rc >= -15) { - const char *icmp_err_str; - switch (rc) { - case -ICMP_NET_UNREACHABLE - 10: - icmp_err_str = "net unreachable"; - break; - case -ICMP_HOST_UNREACHABLE - 10: - icmp_err_str = "host unreachable"; - break; - case -ICMP_PROTOCOL_UNREACHABLE - 10: - icmp_err_str = "protocol unreachable"; - break; - case -ICMP_PORT_UNREACHABLE - 10: - icmp_err_str = "port unreachable"; - break; - case -ICMP_FRAGMENTATION_NEEDED - 10: - icmp_err_str = "fragmentation needed and DF set"; - break; - case -ICMP_SOURCE_ROUTE_FAILED - 10: - icmp_err_str = "source route failed"; - break; - default: - icmp_err_str = " UNKNOWN"; - break; - } - netload_error(0x3005, "ICMP ERROR \"%s\"", icmp_err_str); - return -105; - } else if (rc == -40) { - netload_error(0x3014, "TFTP error occurred after " - "%d bad packets received", - tftp_err.bad_tftp_packets); - return -113; - } else if (rc == -41) { - netload_error(0x3015, "TFTP error occurred after " - "missing %d responses", - tftp_err.no_packets); - return -114; - } else if (rc == -42) { - netload_error(0x3016, "TFTP error missing block %d, " - "expected block was %d", - tftp_err.blocks_missed, - tftp_err.blocks_received); - return -115; + } else { + int ecode; + const char *errstr = NULL; + rc = tftp_get_error_info(fnip, &tftp_err, rc, &errstr, &ecode); + if (errstr) + netload_error(ecode, errstr); } return rc; diff --git a/lib/libnet/tftp.c b/lib/libnet/tftp.c index b7121fe..ec8d631 100644 --- a/lib/libnet/tftp.c +++ b/lib/libnet/tftp.c @@ -690,3 +690,106 @@ int parse_tftp_args(char buffer[], char *server_ip, char filename[], int fd, return 0; } } + +int tftp_get_error_info(filename_ip_t *fnip, tftp_err_t *tftperr, int rc, + const char **errstr, int *ecode) +{ + static char estrbuf[80]; + int dummy; + + if (!ecode) + ecode = &dummy; + + if (rc == -1) { + *ecode = 0x3003; + *errstr = "unknown TFTP error"; + return -103; + } else if (rc == -2) { + *ecode = 0x3004; + sprintf(estrbuf, "TFTP buffer of %d bytes is too small for %s", + len, fnip->filename); + *errstr = estrbuf; + return -104; + } else if (rc == -3) { + *ecode = 0x3009; + sprintf(estrbuf, "file not found: %s", fnip->filename); + *errstr = estrbuf; + return -108; + } else if (rc == -4) { + *ecode = 0x3010; + *errstr = "TFTP access violation"; + return -109; + } else if (rc == -5) { + *ecode = 0x3011; + *errstr = "illegal TFTP operation"; + return -110; + } else if (rc == -6) { + *ecode = 0x3012; + *errstr = "unknown TFTP transfer ID"; + return -111; + } else if (rc == -7) { + *ecode = 0x3013; + *errstr = "no such TFTP user"; + return -112; + } else if (rc == -8) { + *ecode = 0x3017; + *errstr = "TFTP blocksize negotiation failed"; + return -116; + } else if (rc == -9) { + *ecode = 0x3018; + *errstr = "file exceeds maximum TFTP transfer size"; + return -117; + } else if (rc <= -10 && rc >= -15) { + const char *icmp_err_str; + switch (rc) { + case -ICMP_NET_UNREACHABLE - 10: + icmp_err_str = "net unreachable"; + break; + case -ICMP_HOST_UNREACHABLE - 10: + icmp_err_str = "host unreachable"; + break; + case -ICMP_PROTOCOL_UNREACHABLE - 10: + icmp_err_str = "protocol unreachable"; + break; + case -ICMP_PORT_UNREACHABLE - 10: + icmp_err_str = "port unreachable"; + break; + case -ICMP_FRAGMENTATION_NEEDED - 10: + icmp_err_str = "fragmentation needed and DF set"; + break; + case -ICMP_SOURCE_ROUTE_FAILED - 10: + icmp_err_str = "source route failed"; + break; + default: + icmp_err_str = "UNKNOWN"; + break; + } + *ecode = 0x3005; + sprintf(estrbuf, "ICMP ERROR \"%s\"", icmp_err_str); + *errstr = estrbuf; + return -105; + } else if (rc == -40) { + *ecode = 0x3014; + sprintf(estrbuf, + "TFTP error occurred after %d bad packets received", + tftp_err->bad_tftp_packets); + *errstr = estrbuf; + return -113; + } else if (rc == -41) { + *ecode = 0x3015; + sprintf(estrbuf, + "TFTP error occurred after missing %d responses", + tftp_err->no_packets); + *errstr = estrbuf; + return -114; + } else if (rc == -42) { + *ecode = 0x3016; + sprintf(estrbuf, + "TFTP error missing block %d, expected block was %d", + tftp_err->blocks_missed, tftp_err->blocks_received); + *errstr = estrbuf; + return -115; + } + + return rc; +} diff --git a/lib/libnet/tftp.h b/lib/libnet/tftp.h index c94c94d..da743d3 100644 --- a/lib/libnet/tftp.h +++ b/lib/libnet/tftp.h @@ -46,5 +46,7 @@ int tftp(filename_ip_t *fnip, unsigned char *buf, int len, tftp_err_t *err); int32_t handle_tftp(int fd, uint8_t *, int32_t); void handle_tftp_dun(uint8_t err_code); int parse_tftp_args(char buffer[], char *server_ip, char filename[], int fd, int len); +int tftp_get_error_info(filename_ip_t *fnip, tftp_err_t *tftperr, int rc, + const char **errstr, int *ecode); #endif From patchwork Fri May 18 15:45:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Huth X-Patchwork-Id: 916446 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40nXbY476cz9s3Z for ; Sat, 19 May 2018 01:46:49 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 40nXbY1p42zF2CJ for ; Sat, 19 May 2018 01:46:49 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=redhat.com X-Original-To: slof@lists.ozlabs.org Delivered-To: slof@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=redhat.com (client-ip=66.187.233.73; helo=mx1.redhat.com; envelope-from=thuth@redhat.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=redhat.com Received: from mx1.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 40nXZS1cbgzF2Fk for ; Sat, 19 May 2018 01:45:52 +1000 (AEST) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E7FCD81FE15F; Fri, 18 May 2018 15:45:49 +0000 (UTC) Received: from thh440s.redhat.com (ovpn-116-82.ams2.redhat.com [10.36.116.82]) by smtp.corp.redhat.com (Postfix) with ESMTP id DBF4B6B5B6; Fri, 18 May 2018 15:45:48 +0000 (UTC) From: Thomas Huth To: slof@lists.ozlabs.org Date: Fri, 18 May 2018 17:45:34 +0200 Message-Id: <1526658340-1992-6-git-send-email-thuth@redhat.com> In-Reply-To: <1526658340-1992-1-git-send-email-thuth@redhat.com> References: <1526658340-1992-1-git-send-email-thuth@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Fri, 18 May 2018 15:45:49 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Fri, 18 May 2018 15:45:49 +0000 (UTC) for IP:'10.11.54.5' DOMAIN:'int-mx05.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'thuth@redhat.com' RCPT:'' Subject: [SLOF] [PATCH v2 05/11] libc: Implement strrchr() X-BeenThere: slof@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: "Patches for https://github.com/aik/SLOF" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Greg Kurz MIME-Version: 1.0 Errors-To: slof-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "SLOF" This function will be used in one of the next patches to find the last slash in a file name string. Reviewed-by: Greg Kurz Signed-off-by: Thomas Huth --- lib/libc/string/Makefile.inc | 2 +- lib/libc/string/strrchr.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 lib/libc/string/strrchr.c diff --git a/lib/libc/string/Makefile.inc b/lib/libc/string/Makefile.inc index 7ccf3c4..0a77738 100644 --- a/lib/libc/string/Makefile.inc +++ b/lib/libc/string/Makefile.inc @@ -13,7 +13,7 @@ STRING_SRC_C = strcat.c strchr.c strcmp.c strcpy.c strlen.c strncmp.c \ strncpy.c strstr.c memset.c memcpy.c memmove.c memchr.c \ - memcmp.c strcasecmp.c strncasecmp.c strtok.c + memcmp.c strcasecmp.c strncasecmp.c strtok.c strrchr.c STRING_SRC_ASM = STRING_SRCS = $(STRING_SRC_C:%=$(STRINGCMNDIR)/%) $(STRING_SRC_ASM:%=$(STRINGCMNDIR)/%) STRING_OBJS = $(STRING_SRC_C:%.c=%.o) $(STRING_SRC_ASM:%.S=%.o) diff --git a/lib/libc/string/strrchr.c b/lib/libc/string/strrchr.c new file mode 100644 index 0000000..ccfaa9f --- /dev/null +++ b/lib/libc/string/strrchr.c @@ -0,0 +1,28 @@ +/****************************************************************************** + * libc strrchr() implementation + * + * This program and the accompanying materials are made available under + * the terms of the BSD License which accompanies this distribution, and + * is available at http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * Thomas Huth - initial implementation + *****************************************************************************/ + +#include + +char * +strrchr(const char *s, int c) +{ + char cb = c; + char *ptr = (char *)s + strlen(s) - 1; + + while (ptr >= s) { + if (*ptr == cb) { + return ptr; + } + --ptr; + } + + return NULL; +} From patchwork Fri May 18 15:45:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Huth X-Patchwork-Id: 916447 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40nXbd5qW7z9s3T for ; Sat, 19 May 2018 01:46:53 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 40nXbd4cbXzF2HZ for ; Sat, 19 May 2018 01:46:53 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=redhat.com X-Original-To: slof@lists.ozlabs.org Delivered-To: slof@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=redhat.com (client-ip=66.187.233.73; helo=mx1.redhat.com; envelope-from=thuth@redhat.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=redhat.com Received: from mx1.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 40nXZT6FM1zF2F2 for ; Sat, 19 May 2018 01:45:53 +1000 (AEST) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5E05779D36; Fri, 18 May 2018 15:45:51 +0000 (UTC) Received: from thh440s.redhat.com (ovpn-116-82.ams2.redhat.com [10.36.116.82]) by smtp.corp.redhat.com (Postfix) with ESMTP id 51C016B5B6; Fri, 18 May 2018 15:45:50 +0000 (UTC) From: Thomas Huth To: slof@lists.ozlabs.org Date: Fri, 18 May 2018 17:45:35 +0200 Message-Id: <1526658340-1992-7-git-send-email-thuth@redhat.com> In-Reply-To: <1526658340-1992-1-git-send-email-thuth@redhat.com> References: <1526658340-1992-1-git-send-email-thuth@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Fri, 18 May 2018 15:45:51 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Fri, 18 May 2018 15:45:51 +0000 (UTC) for IP:'10.11.54.5' DOMAIN:'int-mx05.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'thuth@redhat.com' RCPT:'' Subject: [SLOF] [PATCH v2 06/11] libnet: Add functions for downloading and parsing pxelinux.cfg files X-BeenThere: slof@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: "Patches for https://github.com/aik/SLOF" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Greg Kurz MIME-Version: 1.0 Errors-To: slof-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "SLOF" Booting a kernel via pxelinux.cfg files is common on x86 and also with ppc64 bootloaders like petitboot, so it would be nice to support this in SLOF, too. This patch adds functions for downloading and parsing such pxelinux.cfg files. See this URL for more details on pxelinux.cfg: https://www.syslinux.org/wiki/index.php?title=PXELINUX Signed-off-by: Thomas Huth --- lib/libnet/Makefile | 2 +- lib/libnet/pxelinux.c | 209 ++++++++++++++++++++++++++++++++++++++++++++++++++ lib/libnet/pxelinux.h | 33 ++++++++ 3 files changed, 243 insertions(+), 1 deletion(-) create mode 100644 lib/libnet/pxelinux.c create mode 100644 lib/libnet/pxelinux.h diff --git a/lib/libnet/Makefile b/lib/libnet/Makefile index dfefea9..a2a6570 100644 --- a/lib/libnet/Makefile +++ b/lib/libnet/Makefile @@ -19,7 +19,7 @@ include $(TOP)/make.rules CFLAGS += -I. -I.. -I../libc/include -I$(TOP)/include $(FLAG) SRCS = ethernet.c ipv4.c udp.c tcp.c dns.c bootp.c dhcp.c tftp.c \ - ipv6.c dhcpv6.c icmpv6.c ndp.c netload.c ping.c args.c + ipv6.c dhcpv6.c icmpv6.c ndp.c netload.c ping.c args.c pxelinux.c OBJS = $(SRCS:%.c=%.o) diff --git a/lib/libnet/pxelinux.c b/lib/libnet/pxelinux.c new file mode 100644 index 0000000..0c0b42e --- /dev/null +++ b/lib/libnet/pxelinux.c @@ -0,0 +1,209 @@ +/***************************************************************************** + * pxelinux.cfg-style config file support. + * + * See https://www.syslinux.org/wiki/index.php?title=PXELINUX for information + * about the pxelinux config file layout. + * + * Copyright 2018 Red Hat, Inc. + * + * This program and the accompanying materials are made available under the + * terms of the BSD License which accompanies this distribution, and is + * available at http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * Thomas Huth, Red Hat Inc. - initial implementation + *****************************************************************************/ + +#include +#include +#include "tftp.h" +#include "pxelinux.h" + +/** + * Call tftp() and report errors (excet "file-not-found" errors) + */ +static int pxelinux_tftp_load(filename_ip_t *fnip, void *buffer, int len) +{ + tftp_err_t tftp_err; + int rc; + + rc = tftp(fnip, buffer, len, &tftp_err); + + if (rc > 0) { + printf("\r TFTP: Received %s (%d bytes)\n", + fnip->filename, rc); + } else if (rc == -3) { + /* Ignore file-not-found (since we are probing the files) + * and simply erase the "Receiving data: 0 KBytes" string */ + printf("\r \r"); + } else { + const char *errstr = NULL; + rc = tftp_get_error_info(fnip, &tftp_err, rc, &errstr, NULL); + if (errstr) + printf("\r TFTP error: %s\n", errstr); + } + + return rc; +} + +/** + * Try to load a pxelinux.cfg file by probing the possible file names. + */ +static int pxelinux_load_cfg(filename_ip_t *fn_ip, uint8_t *mac, uint8_t *uuid, + char *cfgbuf, int cfgbufsize) +{ + int rc, idx; + char basedir[sizeof(fn_ip->filename) - 40]; + char *slash; + + cfgbuf[cfgbufsize - 1] = 0; /* Make sure it is NUL-terminated */ + + /* Did we get a usable base directory via DHCP? */ + slash = strrchr(fn_ip->filename, '/'); + if (slash && slash - fn_ip->filename < sizeof(basedir) - 1) { + slash[1] = 0; + strcpy(basedir, fn_ip->filename); + } else { + strcpy(basedir, "pxelinux.cfg/"); + } + + printf("Trying pxelinux.cfg files...\n"); + + /* Try to load config file with name based on the VM UUID */ + if (uuid) { + sprintf(fn_ip->filename, "%s%02x%02x%02x%02x-%02x%02x-" + "%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", basedir, + uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], + uuid[6], uuid[7], uuid[8], uuid[9], uuid[10], uuid[11], + uuid[12], uuid[13], uuid[14], uuid[15]); + rc = pxelinux_tftp_load(fn_ip, cfgbuf, cfgbufsize - 1); + if (rc > 0) { + return rc; + } + } + + /* Look for config file with MAC address in its name */ + sprintf(fn_ip->filename, "%s%02x-%02x-%02x-%02x-%02x-%02x", basedir, + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + rc = pxelinux_tftp_load(fn_ip, cfgbuf, cfgbufsize - 1); + if (rc > 0) { + return rc; + } + + /* Look for config file with IP address in its name */ + if (fn_ip->ip_version == 4) { + for (idx = 0; idx <= 7; idx++) { + sprintf(fn_ip->filename, "%s%02X%02X%02X%02X", basedir, + (fn_ip->own_ip >> 24) & 0xff, + (fn_ip->own_ip >> 16) & 0xff, + (fn_ip->own_ip >> 8) & 0xff, + fn_ip->own_ip & 0xff); + fn_ip->filename[strlen(fn_ip->filename) - idx] = 0; + rc = pxelinux_tftp_load(fn_ip, cfgbuf, cfgbufsize - 1); + if (rc > 0) { + return rc; + } + } + } + + /* Try "default" config file */ + sprintf(fn_ip->filename, "%sdefault", basedir); + rc = pxelinux_tftp_load(fn_ip, cfgbuf, cfgbufsize - 1); + + return rc; +} + +/** + * Parse a pxelinux-style configuration file. + * @param cfg Pointer to the buffer with contents of the config file + * @param cfgsize Size of the cfg buffer + * @param entries Pointer to array where the results should be put into + * @param max_entries Number of available slots in the entries array + * @param def_ent Used to return the index of the default entry + * @return Number of valid entries + */ +int pxelinux_parse_cfg(char *cfg, int cfgsize, struct lkia *entries, + int max_entries, int *def_ent) +{ + int num_entries = 0; + char *ptr = cfg, *nextptr, *eol, *arg; + char *defaultlabel = NULL; + + *def_ent = 0; + + while (ptr < cfg + cfgsize && num_entries < max_entries) { + eol = strchr(ptr, '\n'); + if (!eol) { + eol = cfg + cfgsize; + } + nextptr = eol + 1; + do { + *eol-- = '\0'; /* Remove spaces, tabs and returns */ + } while (eol >= ptr && + (*eol == '\r' || *eol == ' ' || *eol == '\t')); + while (*ptr == ' ' || *ptr == '\t') { + ptr++; + } + if (*ptr == 0 || *ptr == '#') { + goto nextline; /* Ignore comments and empty lines */ + } + arg = strchr(ptr, ' '); /* Search space between cmnd and arg */ + if (!arg) { + arg = strchr(ptr, '\t'); + } + if (!arg) { + printf("Failed to parse this line:\n %s\n", ptr); + goto nextline; + } + *arg++ = 0; + while (*arg == ' ' || *arg == '\t') { + arg++; + } + if (!strcasecmp("default", ptr)) { + defaultlabel = arg; + } else if (!strcasecmp("label", ptr)) { + entries[num_entries].label = arg; + if (defaultlabel && !strcmp(arg, defaultlabel)) { + *def_ent = num_entries; + } + num_entries++; + } else if (!strcasecmp("kernel", ptr) && num_entries > 0) { + entries[num_entries - 1].kernel = arg; + } else if (!strcasecmp("initrd", ptr) && num_entries > 0) { + entries[num_entries - 1].initrd = arg; + } else if (!strcasecmp("append", ptr) && num_entries > 0) { + entries[num_entries - 1].append = arg; + } else { + printf("Command '%s' is not supported.\n", ptr); + } +nextline: + ptr = nextptr; + } + + return num_entries; +} + +/** + * Try to load and parse a pxelinux-style configuration file. + * @param fn_ip must contain server and client IP information + * @param mac MAC address which should be used for probing + * @param uuid UUID which should be used for probing (can be NULL) + * @param cfgbuf Pointer to the buffer where config file should be loaded + * @param cfgsize Size of the cfgbuf buffer + * @param entries Pointer to array where the results should be put into + * @param max_entries Number of available slots in the entries array + * @param def_ent Used to return the index of the default entry + * @return Number of valid entries + */ +int pxelinux_load_parse_cfg(filename_ip_t *fn_ip, uint8_t *mac, uint8_t *uuid, + char *cfgbuf, int cfgsize, struct lkia *entries, + int max_entries, int *def_ent) +{ + int rc; + + rc = pxelinux_load_cfg(fn_ip, mac, uuid, cfgbuf, cfgsize); + if (rc < 0) + return rc; + + return pxelinux_parse_cfg(cfgbuf, rc, entries, max_entries, def_ent); +} diff --git a/lib/libnet/pxelinux.h b/lib/libnet/pxelinux.h new file mode 100644 index 0000000..9fd1b2f --- /dev/null +++ b/lib/libnet/pxelinux.h @@ -0,0 +1,33 @@ +/***************************************************************************** + * Definitions for pxelinux-style config file support + * + * Copyright 2018 Red Hat, Inc. + * + * This program and the accompanying materials + * are made available under the terms of the BSD License + * which accompanies this distribution, and is available at + * http://www.opensource.org/licenses/bsd-license.php + * + * Contributors: + * Thomas Huth, Red Hat Inc. - initial implementation + *****************************************************************************/ + +#ifndef LIBNET_PXELINUX_H +#define LIBNET_PXELINUX_H + +/* This structure holds the data from one pxelinux.cfg file entry */ +struct lkia { + const char *label; + const char *kernel; + const char *initrd; + const char *append; +}; + +int pxelinux_parse_cfg(char *cfg, int cfgsize, struct lkia *entries, + int max_entries, int *def_ent); +int pxelinux_load_parse_cfg(filename_ip_t *fn_ip, uint8_t *mac, uint8_t *uuid, + char *cfgbuf, int cfgsize, struct lkia *entries, + int max_entries, int *def_ent); + + +#endif From patchwork Fri May 18 15:45:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Huth X-Patchwork-Id: 916448 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40nXbk107Tz9s29 for ; Sat, 19 May 2018 01:46:58 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 40nXbj6P1szF2Hv for ; Sat, 19 May 2018 01:46:57 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=redhat.com X-Original-To: slof@lists.ozlabs.org Delivered-To: slof@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=redhat.com (client-ip=66.187.233.73; helo=mx1.redhat.com; envelope-from=thuth@redhat.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=redhat.com Received: from mx1.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 40nXZV63Z3zF2DT for ; Sat, 19 May 2018 01:45:54 +1000 (AEST) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C68CA81FE162; Fri, 18 May 2018 15:45:52 +0000 (UTC) Received: from thh440s.redhat.com (ovpn-116-82.ams2.redhat.com [10.36.116.82]) by smtp.corp.redhat.com (Postfix) with ESMTP id BB98A728F3; Fri, 18 May 2018 15:45:51 +0000 (UTC) From: Thomas Huth To: slof@lists.ozlabs.org Date: Fri, 18 May 2018 17:45:36 +0200 Message-Id: <1526658340-1992-8-git-send-email-thuth@redhat.com> In-Reply-To: <1526658340-1992-1-git-send-email-thuth@redhat.com> References: <1526658340-1992-1-git-send-email-thuth@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Fri, 18 May 2018 15:45:52 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Fri, 18 May 2018 15:45:52 +0000 (UTC) for IP:'10.11.54.5' DOMAIN:'int-mx05.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'thuth@redhat.com' RCPT:'' Subject: [SLOF] [PATCH v2 07/11] libnet: Wire up pxelinux.cfg network booting X-BeenThere: slof@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: "Patches for https://github.com/aik/SLOF" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Greg Kurz MIME-Version: 1.0 Errors-To: slof-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "SLOF" In case the normal network loading failed, try to load a pxelinux.cfg config file. If that succeeds, load the kernel and initrd with the information that could be found in this file. Signed-off-by: Thomas Huth --- include/helpers.h | 2 ++ lib/libnet/netload.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++ slof/helpers.c | 15 ++++++++++--- 3 files changed, 73 insertions(+), 3 deletions(-) diff --git a/include/helpers.h b/include/helpers.h index 04ee771..9dfe3ae 100644 --- a/include/helpers.h +++ b/include/helpers.h @@ -36,6 +36,8 @@ extern void SLOF_pci_config_write16(long offset, long value); extern void SLOF_pci_config_write8(long offset, long value); extern void *SLOF_translate_my_address(void *addr); extern int write_mm_log(char *data, unsigned int len, unsigned short type); +extern void SLOF_set_chosen_int(const char *s, long val); +extern void SLOF_set_chosen_bytes(const char *s, const char *addr, size_t size); extern void SLOF_encode_bootp_response(void *addr, size_t size); extern void SLOF_encode_dhcp_response(void *addr, size_t size); diff --git a/lib/libnet/netload.c b/lib/libnet/netload.c index ba1008c..2a2a7c5 100644 --- a/lib/libnet/netload.c +++ b/lib/libnet/netload.c @@ -26,6 +26,7 @@ #include #include "args.h" #include "netapps.h" +#include "pxelinux.h" #define IP_INIT_DEFAULT 5 #define IP_INIT_NONE 0 @@ -425,6 +426,60 @@ static int tftp_load(filename_ip_t *fnip, void *buffer, int len) return rc; } +#define CFG_BUF_SIZE 2048 +#define MAX_LKIA_ENTRIES 16 +static int net_pxelinux_cfg_load(filename_ip_t *fnip, char *loadbase, + int maxloadlen, uint8_t *mac) +{ + static char cfgbuf[CFG_BUF_SIZE]; + struct lkia entries[MAX_LKIA_ENTRIES]; + int def, num_entries, rc, ilen; + + num_entries = pxelinux_load_parse_cfg(fnip, mac, NULL, cfgbuf, + CFG_BUF_SIZE, entries, + MAX_LKIA_ENTRIES, &def); + if (num_entries <= 0) + return -1; + + /* Load kernel */ + strncpy(fnip->filename, entries[def].kernel, + sizeof(fnip->filename) - 1); + fnip->filename[sizeof(fnip->filename) - 1] = 0; + rc = tftp_load(fnip, loadbase, maxloadlen); + if (rc < 0) + return rc; + + /* Load ramdisk */ + if (entries[def].initrd) { + loadbase += rc; + maxloadlen -= rc; + if (maxloadlen <= 0) { + puts(" Not enough space for loading the initrd!"); + return -1; + } + strncpy(fnip->filename, entries[def].initrd, + sizeof(fnip->filename) - 1); + ilen = tftp_load(fnip, loadbase, maxloadlen); + if (ilen < 0) + return ilen; + /* The ELF loader will move the kernel to some spot in low mem + * later, thus move the initrd to the end of the RAM instead */ + memmove(loadbase + maxloadlen - ilen, loadbase, ilen); + /* Encode the initrd information in the device tree */ + SLOF_set_chosen_int("linux,initrd-start", + (long)loadbase + maxloadlen - ilen); + SLOF_set_chosen_int("linux,initrd-end", + (long)loadbase + maxloadlen); + } + + if (entries[def].append) { + SLOF_set_chosen_bytes("bootargs", entries[def].append, + strlen(entries[def].append) + 1); + } + + return rc; +} + static void encode_response(char *pkt_buffer, size_t size, int ip_init) { switch(ip_init) { @@ -689,6 +744,10 @@ int netload(char *buffer, int len, char *args_fs, int alen) /* Do the TFTP load and print error message if necessary */ rc = tftp_load(&fn_ip, buffer, len); + if (rc <= 0 && !obp_tftp_args.filename[0]) { + rc = net_pxelinux_cfg_load(&fn_ip, buffer, len, own_mac); + } + if (obp_tftp_args.ip_init == IP_INIT_DHCP) dhcp_send_release(fn_ip.fd); diff --git a/slof/helpers.c b/slof/helpers.c index a8d575c..bd0742e 100644 --- a/slof/helpers.c +++ b/slof/helpers.c @@ -181,7 +181,16 @@ int write_mm_log(char *data, unsigned int len, unsigned short type) return forth_eval_pop("write-mm-log"); } -static void SLOF_encode_response(void *addr, size_t size,char *s) +void SLOF_set_chosen_int(const char *s, long val) +{ + forth_push(val); + forth_eval("encode-int"); + forth_push((unsigned long)s); + forth_push(strlen(s)); + forth_eval("set-chosen"); +} + +void SLOF_set_chosen_bytes(const char *s, const char *addr, size_t size) { forth_push((unsigned long)addr); forth_push(size); @@ -193,10 +202,10 @@ static void SLOF_encode_response(void *addr, size_t size,char *s) void SLOF_encode_bootp_response(void *addr, size_t size) { - SLOF_encode_response(addr, size, "bootp-response"); + SLOF_set_chosen_bytes("bootp-response", addr, size); } void SLOF_encode_dhcp_response(void *addr, size_t size) { - SLOF_encode_response(addr, size, "dhcp-response"); + SLOF_set_chosen_bytes("dhcp-response", addr, size); } From patchwork Fri May 18 15:45:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Huth X-Patchwork-Id: 916449 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40nXbn5dDBz9s29 for ; Sat, 19 May 2018 01:47:01 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 40nXbn4RWFzF2J8 for ; Sat, 19 May 2018 01:47:01 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=redhat.com X-Original-To: slof@lists.ozlabs.org Delivered-To: slof@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=redhat.com (client-ip=66.187.233.73; helo=mx1.redhat.com; envelope-from=thuth@redhat.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=redhat.com Received: from mx1.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 40nXZX2KHFzF2Cj for ; Sat, 19 May 2018 01:45:56 +1000 (AEST) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3C7AF401EF14; Fri, 18 May 2018 15:45:54 +0000 (UTC) Received: from thh440s.redhat.com (ovpn-116-82.ams2.redhat.com [10.36.116.82]) by smtp.corp.redhat.com (Postfix) with ESMTP id 315C183B67; Fri, 18 May 2018 15:45:52 +0000 (UTC) From: Thomas Huth To: slof@lists.ozlabs.org Date: Fri, 18 May 2018 17:45:37 +0200 Message-Id: <1526658340-1992-9-git-send-email-thuth@redhat.com> In-Reply-To: <1526658340-1992-1-git-send-email-thuth@redhat.com> References: <1526658340-1992-1-git-send-email-thuth@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.5]); Fri, 18 May 2018 15:45:54 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.5]); Fri, 18 May 2018 15:45:54 +0000 (UTC) for IP:'10.11.54.5' DOMAIN:'int-mx05.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'thuth@redhat.com' RCPT:'' Subject: [SLOF] [PATCH v2 08/11] libc: Check for NULL pointers in free() X-BeenThere: slof@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: "Patches for https://github.com/aik/SLOF" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Greg Kurz MIME-Version: 1.0 Errors-To: slof-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "SLOF" POSIX says that the free() function should simply do nothing if a NULL pointer argument has been specified. So let's be a little bit more compliant in our libc and add a NULL pointer check here, too. Reviewed-by: Greg Kurz Signed-off-by: Thomas Huth --- lib/libc/stdlib/free.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/libc/stdlib/free.c b/lib/libc/stdlib/free.c index 9005450..d276585 100644 --- a/lib/libc/stdlib/free.c +++ b/lib/libc/stdlib/free.c @@ -19,8 +19,10 @@ free(void *ptr) { struct chunk *header; + if (!ptr) + return; + header = (struct chunk *) ptr; header--; header->inuse = 0; - } From patchwork Fri May 18 15:45:38 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Huth X-Patchwork-Id: 916450 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40nXbs1HCLz9s29 for ; Sat, 19 May 2018 01:47:05 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 40nXbr6mJCzF2F5 for ; Sat, 19 May 2018 01:47:04 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=redhat.com X-Original-To: slof@lists.ozlabs.org Delivered-To: slof@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=redhat.com (client-ip=66.187.233.73; helo=mx1.redhat.com; envelope-from=thuth@redhat.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=redhat.com Received: from mx1.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 40nXZY45PwzF2Cj for ; Sat, 19 May 2018 01:45:57 +1000 (AEST) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 82B54402290A; Fri, 18 May 2018 15:45:55 +0000 (UTC) Received: from thh440s.redhat.com (ovpn-116-82.ams2.redhat.com [10.36.116.82]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8704D728F3; Fri, 18 May 2018 15:45:54 +0000 (UTC) From: Thomas Huth To: slof@lists.ozlabs.org Date: Fri, 18 May 2018 17:45:38 +0200 Message-Id: <1526658340-1992-10-git-send-email-thuth@redhat.com> In-Reply-To: <1526658340-1992-1-git-send-email-thuth@redhat.com> References: <1526658340-1992-1-git-send-email-thuth@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Fri, 18 May 2018 15:45:55 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Fri, 18 May 2018 15:45:55 +0000 (UTC) for IP:'10.11.54.5' DOMAIN:'int-mx05.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'thuth@redhat.com' RCPT:'' Subject: [SLOF] [PATCH v2 09/11] libnet: Add support for DHCPv4 options 209 and 210 X-BeenThere: slof@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: "Patches for https://github.com/aik/SLOF" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Greg Kurz MIME-Version: 1.0 Errors-To: slof-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "SLOF" There are two dedicated DHCP options for loading PXELINUX config files, option 209 (config file name) and 210 (path prefix). We should support them, too, in case some users want to configure their boot flow this way. See RFC 5071 and the following URL for more details: https://www.syslinux.org/wiki/index.php?title=PXELINUX#DHCP_options Unlike most other strings in libnet, I've chosen to not use fixed-size arrays for these two strings, but to allocate the memory via malloc here. We always have to make sure not to overflow the stack in Paflof, so adding 2 * 256 byte arrays to struct filename_ip sounded just too dangerous to me. Signed-off-by: Thomas Huth --- lib/libnet/dhcp.c | 33 +++++++++++++++++++++++++++++++++ lib/libnet/netload.c | 7 ++++++- lib/libnet/ping.c | 14 +++++++++----- lib/libnet/pxelinux.c | 24 +++++++++++++++++++----- lib/libnet/tftp.h | 2 ++ 5 files changed, 69 insertions(+), 11 deletions(-) diff --git a/lib/libnet/dhcp.c b/lib/libnet/dhcp.c index d3e5170..85cd7c0 100644 --- a/lib/libnet/dhcp.c +++ b/lib/libnet/dhcp.c @@ -79,6 +79,8 @@ #define DHCP_TFTP_SERVER 66 #define DHCP_BOOTFILE 67 #define DHCP_CLIENT_ARCH 93 +#define DHCP_PXELINUX_CFGFILE 209 /* See RFC 5071 */ +#define DHCP_PXELINUX_PREFIX 210 #define DHCP_ENDOPT 0xFF #define DHCP_PADOPT 0x00 @@ -167,6 +169,8 @@ static uint32_t dhcp_siaddr_ip = 0; static char dhcp_filename[256]; static char dhcp_tftp_name[256]; static uint32_t dhcp_xid; +static char *pxelinux_cfgfile; +static char *pxelinux_prefix; static char * response_buffer; @@ -185,6 +189,8 @@ int32_t dhcpv4(char *ret_buffer, filename_ip_t *fn_ip) strcpy(dhcp_filename, ""); strcpy(dhcp_tftp_name, ""); + pxelinux_cfgfile = pxelinux_prefix = NULL; + response_buffer = ret_buffer; if (dhcp_attempt(fd) == 0) @@ -232,6 +238,10 @@ int32_t dhcpv4(char *ret_buffer, filename_ip_t *fn_ip) fn_ip -> server_ip = dhcp_tftp_ip; strcpy(fn_ip->filename, dhcp_filename); + fn_ip->pl_cfgfile = pxelinux_cfgfile; + fn_ip->pl_prefix = pxelinux_prefix; + pxelinux_cfgfile = pxelinux_prefix = NULL; + return 0; } @@ -456,6 +466,26 @@ static int32_t dhcp_decode_options(uint8_t opt_field[], uint32_t opt_len, offset += 4; break; + case DHCP_PXELINUX_CFGFILE: + pxelinux_cfgfile = malloc(opt_field[offset + 1] + 1); + if (pxelinux_cfgfile) { + memcpy(pxelinux_cfgfile, opt_field + offset + 2, + opt_field[offset + 1]); + pxelinux_cfgfile[opt_field[offset + 1]] = 0; + } + offset += 2 + opt_field[offset + 1]; + break; + + case DHCP_PXELINUX_PREFIX: + pxelinux_prefix = malloc(opt_field[offset + 1] + 1); + if (pxelinux_prefix) { + memcpy(pxelinux_prefix, opt_field + offset + 2, + opt_field[offset + 1]); + pxelinux_prefix[opt_field[offset + 1]] = 0; + } + offset += 2 + opt_field[offset + 1]; + break; + case DHCP_PADOPT : offset++; break; @@ -681,6 +711,9 @@ static void dhcp_send_request(int fd) opt.request_list[DHCP_ROUTER] = 1; opt.request_list[DHCP_TFTP_SERVER] = 1; opt.request_list[DHCP_BOOTFILE] = 1; + opt.request_list[DHCP_PXELINUX_CFGFILE] = 1; + opt.request_list[DHCP_PXELINUX_PREFIX] = 1; + opt.request_list[DHCP_CLIENT_ARCH] = USE_DHCPARCH; opt.flag[DHCP_CLIENT_ARCH] = USE_DHCPARCH; diff --git a/lib/libnet/netload.c b/lib/libnet/netload.c index 2a2a7c5..5af4e26 100644 --- a/lib/libnet/netload.c +++ b/lib/libnet/netload.c @@ -742,7 +742,10 @@ int netload(char *buffer, int len, char *args_fs, int alen) } /* Do the TFTP load and print error message if necessary */ - rc = tftp_load(&fn_ip, buffer, len); + rc = 0; + if (!fn_ip.pl_cfgfile && strlen(fn_ip.filename) > 0) { + rc = tftp_load(&fn_ip, buffer, len); + } if (rc <= 0 && !obp_tftp_args.filename[0]) { rc = net_pxelinux_cfg_load(&fn_ip, buffer, len, own_mac); @@ -758,5 +761,7 @@ int netload(char *buffer, int len, char *args_fs, int alen) } err_out: SLOF_free_mem(pkt_buffer, MAX_PKT_SIZE); + free(fn_ip.pl_cfgfile); + free(fn_ip.pl_prefix); return rc; } diff --git a/lib/libnet/ping.c b/lib/libnet/ping.c index edad5eb..051269f 100644 --- a/lib/libnet/ping.c +++ b/lib/libnet/ping.c @@ -115,6 +115,7 @@ int ping(char *args_fs, int alen) uint8_t own_mac[6]; uint32_t netmask; char args[256]; + int ret = -1; memset(&ping_args, 0, sizeof(struct ping_args)); @@ -164,8 +165,7 @@ int ping(char *args_fs, int alen) if (arp_failed == -1) { printf("\n DHCP: Could not get ip address\n"); - close(fn_ip.fd); - return -1; + goto free_out; } } else { @@ -210,12 +210,16 @@ int ping(char *args_fs, int alen) receive_ether(fd_device); if(pong_ipv4() == 0) { printf("success\n"); - close(fn_ip.fd); - return 0; + ret = 0; + goto free_out; } } printf("failed\n"); +free_out: + free(fn_ip.pl_cfgfile); + free(fn_ip.pl_prefix); close(fn_ip.fd); - return -1; + + return ret; } diff --git a/lib/libnet/pxelinux.c b/lib/libnet/pxelinux.c index 0c0b42e..6c03029 100644 --- a/lib/libnet/pxelinux.c +++ b/lib/libnet/pxelinux.c @@ -59,16 +59,30 @@ static int pxelinux_load_cfg(filename_ip_t *fn_ip, uint8_t *mac, uint8_t *uuid, cfgbuf[cfgbufsize - 1] = 0; /* Make sure it is NUL-terminated */ /* Did we get a usable base directory via DHCP? */ - slash = strrchr(fn_ip->filename, '/'); - if (slash && slash - fn_ip->filename < sizeof(basedir) - 1) { - slash[1] = 0; - strcpy(basedir, fn_ip->filename); + if (fn_ip->pl_prefix && strlen(fn_ip->pl_prefix) < sizeof(basedir)) { + strcpy(basedir, fn_ip->pl_prefix); } else { - strcpy(basedir, "pxelinux.cfg/"); + slash = strrchr(fn_ip->filename, '/'); + if (slash && slash - fn_ip->filename < sizeof(basedir) - 1) { + slash[1] = 0; + strcpy(basedir, fn_ip->filename); + } else { + strcpy(basedir, "pxelinux.cfg/"); + } } printf("Trying pxelinux.cfg files...\n"); + /* Try to load config file according to file name in DHCP option 209 */ + if (fn_ip->pl_cfgfile && strlen(fn_ip->pl_cfgfile) + + strlen(basedir) < sizeof(fn_ip->filename)) { + sprintf(fn_ip->filename, "%s%s", basedir, fn_ip->pl_cfgfile); + rc = pxelinux_tftp_load(fn_ip, cfgbuf, cfgbufsize - 1); + if (rc > 0) { + return rc; + } + } + /* Try to load config file with name based on the VM UUID */ if (uuid) { sprintf(fn_ip->filename, "%s%02x%02x%02x%02x-%02x%02x-" diff --git a/lib/libnet/tftp.h b/lib/libnet/tftp.h index da743d3..775700a 100644 --- a/lib/libnet/tftp.h +++ b/lib/libnet/tftp.h @@ -29,6 +29,8 @@ struct filename_ip { ip6_addr_t server_ip6; ip6_addr_t dns_ip6; char filename[256]; + char *pl_cfgfile; /* For PXELINUX DHCPv4 option 209. Must be free()ed */ + char *pl_prefix; /* For PXELINUX DHCPv4 option 210. Must be free()ed */ int fd; int ip_version; int tftp_retries; From patchwork Fri May 18 15:45:39 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Huth X-Patchwork-Id: 916451 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40nXbw6FlMz9s29 for ; Sat, 19 May 2018 01:47:08 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 40nXbw53DszF2F5 for ; Sat, 19 May 2018 01:47:08 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=redhat.com X-Original-To: slof@lists.ozlabs.org Delivered-To: slof@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=redhat.com (client-ip=66.187.233.73; helo=mx1.redhat.com; envelope-from=thuth@redhat.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=redhat.com Received: from mx1.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 40nXZb2WftzF2DQ for ; Sat, 19 May 2018 01:45:59 +1000 (AEST) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1B5C84023112; Fri, 18 May 2018 15:45:57 +0000 (UTC) Received: from thh440s.redhat.com (ovpn-116-82.ams2.redhat.com [10.36.116.82]) by smtp.corp.redhat.com (Postfix) with ESMTP id D3115728F3; Fri, 18 May 2018 15:45:55 +0000 (UTC) From: Thomas Huth To: slof@lists.ozlabs.org Date: Fri, 18 May 2018 17:45:39 +0200 Message-Id: <1526658340-1992-11-git-send-email-thuth@redhat.com> In-Reply-To: <1526658340-1992-1-git-send-email-thuth@redhat.com> References: <1526658340-1992-1-git-send-email-thuth@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Fri, 18 May 2018 15:45:57 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Fri, 18 May 2018 15:45:57 +0000 (UTC) for IP:'10.11.54.5' DOMAIN:'int-mx05.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'thuth@redhat.com' RCPT:'' Subject: [SLOF] [PATCH v2 10/11] slof: Add a helper function to get the contents of a property in C code X-BeenThere: slof@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: "Patches for https://github.com/aik/SLOF" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Greg Kurz MIME-Version: 1.0 Errors-To: slof-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "SLOF" We will need to retrieve the UUID of the VM in the libnet code, so we need a function to get the contents from a device tree property. Signed-off-by: Thomas Huth --- include/helpers.h | 2 ++ slof/helpers.c | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/include/helpers.h b/include/helpers.h index 9dfe3ae..5834bce 100644 --- a/include/helpers.h +++ b/include/helpers.h @@ -40,6 +40,8 @@ extern void SLOF_set_chosen_int(const char *s, long val); extern void SLOF_set_chosen_bytes(const char *s, const char *addr, size_t size); extern void SLOF_encode_bootp_response(void *addr, size_t size); extern void SLOF_encode_dhcp_response(void *addr, size_t size); +extern int SLOF_get_property(const char *node, const char *propname, + char **addr, int *len); #define offset_of(type, member) ((long) &((type *)0)->member) #define container_of(ptr, type, member) ({ \ diff --git a/slof/helpers.c b/slof/helpers.c index bd0742e..dfb0c13 100644 --- a/slof/helpers.c +++ b/slof/helpers.c @@ -209,3 +209,18 @@ void SLOF_encode_dhcp_response(void *addr, size_t size) { SLOF_set_chosen_bytes("dhcp-response", addr, size); } + +int SLOF_get_property(const char *node, const char *propname, + char **addr, int *len) +{ + forth_push((unsigned long)propname); + forth_push(strlen(propname)); + forth_push((unsigned long)node); + forth_push(strlen(node)); + forth_eval("find-node get-property"); + if (forth_pop()) + return -1; + *len = forth_pop(); + *addr = (char *)forth_pop(); + return 0; +} From patchwork Fri May 18 15:45:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Huth X-Patchwork-Id: 916452 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40nXc14Skfz9s29 for ; Sat, 19 May 2018 01:47:13 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 40nXc13DNxzF2JS for ; Sat, 19 May 2018 01:47:13 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=redhat.com X-Original-To: slof@lists.ozlabs.org Delivered-To: slof@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=redhat.com (client-ip=66.187.233.73; helo=mx1.redhat.com; envelope-from=thuth@redhat.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=redhat.com Received: from mx1.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 40nXZc71s1zF2Cy for ; Sat, 19 May 2018 01:46:00 +1000 (AEST) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8594B402333B; Fri, 18 May 2018 15:45:58 +0000 (UTC) Received: from thh440s.redhat.com (ovpn-116-82.ams2.redhat.com [10.36.116.82]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7B0A86B5B6; Fri, 18 May 2018 15:45:57 +0000 (UTC) From: Thomas Huth To: slof@lists.ozlabs.org Date: Fri, 18 May 2018 17:45:40 +0200 Message-Id: <1526658340-1992-12-git-send-email-thuth@redhat.com> In-Reply-To: <1526658340-1992-1-git-send-email-thuth@redhat.com> References: <1526658340-1992-1-git-send-email-thuth@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Fri, 18 May 2018 15:45:58 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Fri, 18 May 2018 15:45:58 +0000 (UTC) for IP:'10.11.54.5' DOMAIN:'int-mx05.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'thuth@redhat.com' RCPT:'' Subject: [SLOF] [PATCH v2 11/11] libnet: Support UUID-based pxelinux.cfg file names X-BeenThere: slof@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: "Patches for https://github.com/aik/SLOF" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Greg Kurz MIME-Version: 1.0 Errors-To: slof-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "SLOF" Retrieve the UUID from the device tree and pass it to the pxelinux.cfg function, so that we can look there for UUID-based file names, too. Signed-off-by: Thomas Huth --- lib/libnet/netload.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/lib/libnet/netload.c b/lib/libnet/netload.c index 5af4e26..5d69c3b 100644 --- a/lib/libnet/netload.c +++ b/lib/libnet/netload.c @@ -426,6 +426,42 @@ static int tftp_load(filename_ip_t *fnip, void *buffer, int len) return rc; } +static int get_uuid(uint8_t *uuid) +{ + char *addr; + int len; + char tmp[5]; + + if (SLOF_get_property("/", "system-id", &addr, &len)) + return 0; + + if (len < 36) { /* This should never happen... */ + puts("Warning: UUID property is too short"); + return 0; + } + + /* Parse property string */ + *(uint32_t *)&uuid[0] = strtoul(addr, &addr, 16); + if (*addr++ != '-') + return 0; + *(uint16_t *)&uuid[4] = strtoul(addr, &addr, 16); + if (*addr++ != '-') + return 0; + *(uint16_t *)&uuid[6] = strtoul(addr, &addr, 16); + if (*addr++ != '-') + return 0; + *(uint16_t *)&uuid[8] = strtoul(addr, &addr, 16); + if (*addr++ != '-') + return 0; + memcpy(tmp, addr, 4); + tmp[4] = 0; + *(uint16_t *)&uuid[10] = strtoul(tmp, NULL, 16); + addr += 4; + *(uint32_t *)&uuid[12] = strtoul(addr, NULL, 16); + + return 1; +} + #define CFG_BUF_SIZE 2048 #define MAX_LKIA_ENTRIES 16 static int net_pxelinux_cfg_load(filename_ip_t *fnip, char *loadbase, @@ -433,10 +469,13 @@ static int net_pxelinux_cfg_load(filename_ip_t *fnip, char *loadbase, { static char cfgbuf[CFG_BUF_SIZE]; struct lkia entries[MAX_LKIA_ENTRIES]; - int def, num_entries, rc, ilen; + int def, num_entries, rc, ilen, has_uuid; + uint8_t uuid[16]; + + has_uuid = get_uuid(uuid); - num_entries = pxelinux_load_parse_cfg(fnip, mac, NULL, cfgbuf, - CFG_BUF_SIZE, entries, + num_entries = pxelinux_load_parse_cfg(fnip, mac, has_uuid ? uuid : NULL, + cfgbuf, CFG_BUF_SIZE, entries, MAX_LKIA_ENTRIES, &def); if (num_entries <= 0) return -1;