From patchwork Mon Oct 6 20:31:04 2008 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manoel X-Patchwork-Id: 22977 Return-Path: X-Original-To: yaboot-devel@ozlabs.org Delivered-To: yaboot-devel@ozlabs.org Received: from igw1.br.ibm.com (igw1.br.ibm.com [32.104.18.24]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 7FFDADDDEC for ; Tue, 7 Oct 2008 07:31:10 +1100 (EST) Received: from d24relay01.br.ibm.com (unknown [9.8.31.16]) by igw1.br.ibm.com (Postfix) with ESMTP id E5D3732C32C for ; Mon, 6 Oct 2008 16:59:14 -0300 (BRT) Received: from d24av01.br.ibm.com (d24av01.br.ibm.com [9.18.232.46]) by d24relay01.br.ibm.com (8.13.8/8.13.8/NCO v9.1) with ESMTP id m96KUttV2523176 for ; Mon, 6 Oct 2008 17:30:55 -0300 Received: from d24av01.br.ibm.com (loopback [127.0.0.1]) by d24av01.br.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id m96KV4WS024942 for ; Mon, 6 Oct 2008 17:31:04 -0300 Received: from [9.18.253.165] (manoel-laptop.br.ibm.com [9.18.253.165]) by d24av01.br.ibm.com (8.12.11.20060308/8.12.11) with ESMTP id m96KV4EH024921; Mon, 6 Oct 2008 17:31:04 -0300 Subject: Re: Power 6 netboot bug/testing From: Manoel To: yaboot-devel@ozlabs.org Date: Mon, 06 Oct 2008 17:31:04 -0300 Message-Id: <1223325064.6495.48.camel@manoel-laptop> Mime-Version: 1.0 X-Mailer: Evolution 2.22.3.1 X-BeenThere: yaboot-devel@ozlabs.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: Technical and development discussion regarding yaboot List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 06 Oct 2008 20:31:11 -0000 I have done a patch (file attached) to solve the bug described in: https://bugzilla.redhat.com/show_bug.cgi?id=458438. In recent OpenFirmware versions the property "bootpreply-packet" was replaced by the newer "bootp-response". It contains only the bootp packet, excluding the encapsulating UDP, IP, and link-layer headers and trailers that were in the earlier structure. This new Extension introduced some problems to DHCP environments, which does not correctly build the tftp request when a discrete file is specified. Due to this change on the packet sent, the yaboot fails to boot through network. This patch basically works by identifying the OpenFirmare version and constructing the buffer in the format necessary for it. It was tested in both older P5 and newer P6 machine OpenFirmware versions and was able to boot correctly. I'm assuming that Chandras' Patches has been applied into git HEAD, because I'm using some structures purposed by him. I'd like your opinions and suggestions regarding this patch. Best Regards, Manoel Abranches IBM Linux Technology Center Brasil [1] http://pastebin.zurich.ibm.com/mef77758 [2] http://pastebin.zurich.ibm.com/m7b7ba2b5 diff -Naurp yaboot/include/file.h yaboot.new//include/file.h --- yaboot/include/file.h 2008-10-02 10:03:07.000000000 -0300 +++ yaboot.new//include/file.h 2008-10-06 10:58:22.000000000 -0300 @@ -42,6 +42,7 @@ struct boot_fspec_t { char* siaddr; /* Server address */ char* file; /* File path */ char* ciaddr; /* Client address */ + char* yiaddr; /* Client address filled in by server*/ char* giaddr; /* Gateway address */ char* bootp_retries; /* Bootp retries */ char* tftp_retries; /* TFTP retries */ @@ -81,5 +82,6 @@ extern int parse_device_path(char *imagepath, char *defdevice, int defpart, char *deffile, struct boot_fspec_t *result); +int bootp_to_fspec(struct bootp_packet *,struct boot_fspec_t *); #endif diff -Naurp yaboot/second/file.c yaboot.new//second/file.c --- yaboot/second/file.c 2008-10-02 10:03:07.000000000 -0300 +++ yaboot.new//second/file.c 2008-10-06 16:16:18.000000000 -0300 @@ -61,6 +61,40 @@ scopy(char **dest, char **source) return ret; } +#define IPLEN 16 +/*Return ip in xxx.xxx.xxx.xxx string format*/ + +static char * ipv4_to_str( u32 ip) +{ + char * buf = malloc(IPLEN); + sprintf(buf,"%u.%u.%u.%u", + (ip & 0xff000000) >> 24, + (ip & 0x00ff0000) >> 16, + (ip & 0x0000ff00) >> 8, + (ip & 0x000000ff)); + return buf; +} + +/*Puts the IP information on boot_packet struct in boot_fspec_t struct + * return 1 in success and 0 on fail*/ +int bootp_to_fspec(struct bootp_packet *packet,struct boot_fspec_t *fspec){ + + if (packet == NULL || fspec == NULL) + return 0; + + fspec->siaddr=ipv4_to_str(packet->siaddr); + fspec->ciaddr=ipv4_to_str(packet->ciaddr); + fspec->giaddr=ipv4_to_str(packet->giaddr); + fspec->yiaddr=ipv4_to_str(packet->yiaddr); + DEBUG_F("siaddr = <%s>\n",fspec->siaddr); + DEBUG_F("ciaddr = <%s>\n",fspec->ciaddr); + DEBUG_F("giaddr = <%s>\n",fspec->giaddr); + DEBUG_F("yiaddr = <%s>\n",fspec->yiaddr); + + return 1; +} + + /* * Extract all the ipv4 arguments from the bootpath provided and fill result * Returns 1 on success, 0 on failure. diff -Naurp yaboot/second/fs_of.c yaboot.new//second/fs_of.c --- yaboot/second/fs_of.c 2008-10-02 10:03:07.000000000 -0300 +++ yaboot.new//second/fs_of.c 2008-10-06 12:26:43.000000000 -0300 @@ -46,7 +46,7 @@ #define LOAD_BUFFER_POS 0x00000000 #define LOAD_BUFFER_SIZE 0x01000000 - +extern int net_type; static int of_open(struct boot_file_t* file, struct partition_t* part, struct boot_fspec_t* fspec); static int of_read(struct boot_file_t* file, unsigned int size, void* buffer); @@ -137,38 +137,58 @@ of_net_open(struct boot_file_t* file, static char buffer[1024]; char *filename = NULL; char *p; - + struct bootp_packet *packet; DEBUG_ENTER; DEBUG_OPEN; +/*Newer IBM firmware needs the server ip, client ip and the desired file to be + * set in the buffer, thus broken previus Yaboot network boot. + * + * The format is :tftpserver,filename,client,gateway,bootp-retry,tftp-retry,netmask,tftp-blocksize + */ + + if (net_type){//Use new firmware network interface + packet = prom_get_netinfo(); + if(packet) + bootp_to_fspec(packet,fspec); + }else + strcpy(fspec->yiaddr,fspec->ciaddr); + if (fspec->file && strlen(fspec->file)) { filename = strdup(fspec->file); for (p = filename; *p; p++) if (*p == '/') *p = '\\'; } - + DEBUG_F("siaddr <%s>; filename <%s>; ciaddr <%s>; giaddr <%s>; ipv6 <%d>\n", fspec->siaddr, filename, fspec->ciaddr, fspec->giaddr, fspec->is_ipv6); - strncpy(buffer, fspec->dev, 768); - if (fspec->is_ipv6) - strcat(buffer, TOK_IPV6 ","); - strcat(buffer, fspec->siaddr); - strcat(buffer, ","); - if (fspec->is_ipv6 && (strstr(filename, "filename=") == NULL)) - strcat(buffer, "filename="); - strcat(buffer, filename); - strcat(buffer, ","); - strcat(buffer, fspec->ciaddr); - strcat(buffer, ","); - strcat(buffer, fspec->giaddr); - strcat(buffer, ","); - strcat(buffer, fspec->bootp_retries); - strcat(buffer, ","); - strcat(buffer, fspec->tftp_retries); - strcat(buffer, ","); - strcat(buffer, fspec->addl_params); - + if(net_type){ + strncpy(buffer, fspec->dev, 768); + if (fspec->is_ipv6) + strcat(buffer, TOK_IPV6 ","); + strcat(buffer, fspec->siaddr); + strcat(buffer, ","); + if (fspec->is_ipv6 && (strstr(filename, "filename=") == NULL)) + strcat(buffer, "filename="); + strcat(buffer, filename); + strcat(buffer, ","); + strcat(buffer, fspec->yiaddr); + strcat(buffer, ","); + strcat(buffer, fspec->giaddr); + strcat(buffer, ","); + strcat(buffer, fspec->bootp_retries); + strcat(buffer, ","); + strcat(buffer, fspec->tftp_retries); + strcat(buffer, ","); + strcat(buffer, fspec->addl_params); + } + else{ + + strncpy(buffer, fspec->dev, (int)strchr(fspec->dev,':')); + strcat(buffer, ","); + strcat(buffer, filename); + } DEBUG_F("Opening: \"%s\"\n", buffer); file->of_device = prom_open(buffer); diff -Naurp yaboot/second/yaboot.c yaboot.new//second/yaboot.c --- yaboot/second/yaboot.c 2008-10-02 10:03:07.000000000 -0300 +++ yaboot.new//second/yaboot.c 2008-10-06 10:40:19.000000000 -0300 @@ -121,7 +121,7 @@ char *password = NULL; struct boot_fspec_t boot; int _machine = _MACH_Pmac; int flat_vmlinux; - +int net_type = 0;//type of net interface #ifdef CONFIG_COLOR_TEXT /* Color values for text ui */ @@ -183,7 +183,7 @@ yaboot_start (unsigned long r3, unsigned void* malloc_base = NULL; unsigned long addr; prom_handle root; - + ihandle promnet; /* OF seems to do it, but I'm not very confident */ memset(&__bss_start, 0, &_end - &__bss_start); @@ -237,6 +237,11 @@ yaboot_start (unsigned long r3, unsigned !strncmp(model, "IBM", 3)) _machine = _MACH_chrp; } + + if (prom_getprop(root, "ibm,fw-net-compatibility",&promnet, sizeof(ihandle)) > 0) + net_type = 1; + + } DEBUG_F("Running on _machine = %d\n", _machine); @@ -469,7 +474,8 @@ static int load_my_config_file(struct bo char *cfgpath = (_machine == _MACH_chrp || _machine == _MACH_bplan) ? "/etc/" : ""; int flen; int minlen; - + char *macaddress; + packet = prom_get_netinfo(); if (!packet) return rc; @@ -483,10 +489,16 @@ static int load_my_config_file(struct bo fspec.file = malloc(packet->hlen * 3 + 2 + 6); if (!fspec.file) goto out; - - sprintf(fspec.file, "%s%02x-", cfgpath, packet->htype); - strcat(fspec.file, prom_get_mac(packet)); - + + if (net_type){ + macaddress = prom_get_mac(packet); + fspec.file = malloc(strlen(CONFIG_FILE_NAME) + strlen(macaddress) + 1 ); + sprintf(fspec.file,"%s-%s" ,CONFIG_FILE_NAME,macaddress);// bootp_to_fspec(packet,fspec); + } + else{ + sprintf(fspec.file, "%s%02x-", cfgpath, packet->htype); + strcat(fspec.file, prom_get_mac(packet)); + } rc = load_config_file(&fspec); if (rc) goto out;