--- anaconda.spec | 2 + isys/iface.h | 3 +- iw/netconfig_dialog.py | 4 +- loader/Makefile | 4 +- loader/ibft.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++ loader/ibft.h | 45 ++++++++++++++++++++ loader/net.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++- 7 files changed, 260 insertions(+), 7 deletions(-) create mode 100644 loader/ibft.c create mode 100644 loader/ibft.h diff --git a/anaconda.spec b/anaconda.spec index 010cbf4..fd00cf3 100644 --- a/anaconda.spec +++ b/anaconda.spec @@ -38,6 +38,7 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) %define dbusver 1.2.3 %define createrepover 0.4.7 %define yumutilsver 1.1.11-3 +%define iscsiver 6.2.0.870 BuildRequires: audit-libs-devel BuildRequires: booty @@ -75,6 +76,7 @@ BuildRequires: dbus-devel >= %{dbusver} %ifarch %livearches BuildRequires: desktop-file-utils %endif +BuildRequires: iscsi-initiator-utils-devel >= %{iscsiver} Requires: policycoreutils Requires: rpm-python >= %{rpmpythonver} diff --git a/isys/iface.h b/isys/iface.h index 5cd8614..e20c2b4 100644 --- a/isys/iface.h +++ b/isys/iface.h @@ -30,7 +30,7 @@ /* Enumerated types used in iface.c as well as loader's network code */ enum { IPUNUSED, IPV4, IPV6 }; -enum { IPV4_UNUSED_METHOD, IPV4_DHCP_METHOD, IPV4_MANUAL_METHOD }; +enum { IPV4_UNUSED_METHOD, IPV4_DHCP_METHOD, IPV4_MANUAL_METHOD, IPV4_IBFT_METHOD }; enum { IPV6_UNUSED_METHOD, IPV6_AUTO_METHOD, IPV6_DHCP_METHOD, IPV6_MANUAL_METHOD }; @@ -100,6 +100,7 @@ typedef struct _iface_t { uint64_t flags; int ipv4method; int ipv6method; + int isiBFT; } iface_t; /* Function prototypes */ diff --git a/iw/netconfig_dialog.py b/iw/netconfig_dialog.py index 4818171..c87da21 100644 --- a/iw/netconfig_dialog.py +++ b/iw/netconfig_dialog.py @@ -67,8 +67,8 @@ class NetworkConfigurator: val = combo.get_model().get_value(active, 1) netdev = self.network.available()[val] - bootproto = netdev.get('BOOTPROTO') - if not bootproto or bootproto == "dhcp": + bootproto = netdev.get("BOOTPROTO") + if not bootproto or bootproto == "dhcp" or bootproto == "ibft": self.xml.get_widget("dhcpCheckbutton").set_active(True) else: self.xml.get_widget("dhcpCheckbutton").set_active(False) diff --git a/loader/Makefile b/loader/Makefile index 6dc0412..def2bad 100644 --- a/loader/Makefile +++ b/loader/Makefile @@ -26,7 +26,7 @@ else TARGET=depend $(PROGS) endif -LIBS = -lnewt -lslang -lz -lpopt ../isys/libisys.a -lcheckisomd5 +LIBS = -lnewt -lslang -lz -lpopt ../isys/libisys.a -lcheckisomd5 -liscsi # devmapper LIBS += $(shell pkg-config --libs devmapper) @@ -57,7 +57,7 @@ METHOBJS = method.o cdinstall.o hdinstall.o nfsinstall.o urlinstall.o OBJS = copy.o log.o moduleinfo.o loadermisc.o modules.o windows.o \ lang.o kbd.o driverdisk.o selinux.o \ mediacheck.o kickstart.o driverselect.o \ - getparts.o dirbrowser.o fwloader.o \ + getparts.o dirbrowser.o fwloader.o ibft.o \ $(HWOBJS) $(METHOBJS) LOADEROBJS = loader.o loader-pcmcia.o NETOBJS = net.o urls.o ftp.o telnet.o telnetd.o diff --git a/loader/ibft.c b/loader/ibft.c new file mode 100644 index 0000000..b3a3827 --- /dev/null +++ b/loader/ibft.c @@ -0,0 +1,105 @@ +/* + File name: ibft.c + Date: 2008/09/02 + Author: Martin Sivak <msivak@xxxxxxxxxx> + + Copyright (C) 2008 Red Hat + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + in a file called COPYING along with this program; if not, write to + the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA + 02139, USA. +*/ + + +#include <stddef.h> +#include <stdio.h> +#include <string.h> + +#include <libiscsi.h> +#include "ibft.h" + +struct libiscsi_network_config ibft_context; +int ibft_ispresent = 0; +int ibft_initialized = 0; + +int ibft_init(void) +{ + int ret; + + memset(&ibft_context, 0, sizeof(ibft_context)); + + ret = libiscsi_get_firmware_network_config(&ibft_context); + + /* ret == 0 -> OK */ + ibft_ispresent = !ret; + ibft_initialized = 1; + + return ibft_initialized; +} + +/* Is iBFT available on this system */ +int ibft_present() +{ + if(!ibft_initialized) + ibft_init(); + + return ibft_ispresent; +} + +/* Is the iBFT network configured to use DHCP */ +int ibft_iface_dhcp() +{ + if(!ibft_initialized) + ibft_init(); + + if(!ibft_present()) + return -1; + + return ibft_context.dhcp; +} + +#define ibft_iface_charfunc(name, var) char* ibft_iface_##name()\ +{\ + if(!ibft_initialized)\ + ibft_init();\ +\ + if(!ibft_present())\ + return NULL;\ +\ + if(!strlen(ibft_context.var))\ + return NULL;\ +\ + return ibft_context.var;\ +} + + +/* Get the iBFT MAC address */ +ibft_iface_charfunc(mac, mac_address) + +/* Get the iBFT ip address */ +ibft_iface_charfunc(ip, ip_address) + +/* Get the iBFT subnet mask */ +ibft_iface_charfunc(mask, netmask) + +/* Get the iBFT gateway */ +ibft_iface_charfunc(gw, gateway) + +/* Get the iBFT iface name */ +ibft_iface_charfunc(iface, iface_name) + +/* Get the iBFT dns servers */ +ibft_iface_charfunc(dns1, primary_dns) +ibft_iface_charfunc(dns2, secondary_dns) + diff --git a/loader/ibft.h b/loader/ibft.h new file mode 100644 index 0000000..a922c91 --- /dev/null +++ b/loader/ibft.h @@ -0,0 +1,45 @@ +/* + File name: ibft.h + Date: 2008/09/02 + Author: Martin Sivak + + Copyright (C) 2008 Red Hat + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + in a file called COPYING along with this program; if not, write to + the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA + 02139, USA. +*/ + + +#ifndef __IBFT_H__ +#define __IBFT_H__ + + +int ibft_init(); +int ibft_present(); + +int ibft_iface_dhcp(); + +char* ibft_iface_mac(); +char* ibft_iface_ip(); +char* ibft_iface_mask(); +char* ibft_iface_gw(); +char* ibft_iface_iface(); +char* ibft_iface_dns1(); +char* ibft_iface_dns2(); + + +#endif + +/* end of ibft.h */ diff --git a/loader/net.c b/loader/net.c index 4d08d34..7ee0053 100644 --- a/loader/net.c +++ b/loader/net.c @@ -53,6 +53,7 @@ #include "method.h" #include "net.h" #include "windows.h" +#include "ibft.h" /* boot flags */ extern uint64_t flags; @@ -237,8 +238,26 @@ void setupIfaceStruct(iface_t * iface, struct loaderData_s * loaderData) { } if (loaderData->ipinfo_set && loaderData->ipv4 != NULL) { + /* this is iBFT configured device */ + if (!strncmp(loaderData->ip, "ibft", 4)) { + char *devmacaddr = nl_mac2str(loaderData->netDev); + iface->ipv4method = IPV4_IBFT_METHOD; + iface->isiBFT = 1; + + /* Problems with getting the info from iBFT or iBFT uses dhcp*/ + if(!devmacaddr || !ibft_present() || ibft_iface_dhcp()){ + iface->ipv4method = IPV4_DHCP_METHOD; + logMessage(INFO, "iBFT is not present or is configured to use DHCP"); + } + /* MAC address doesn't match */ + else if(strcasecmp(ibft_iface_mac(), devmacaddr)){ + iface->ipv4method = IPV4_DHCP_METHOD; + logMessage(INFO, "iBFT doesn't know what NIC to use - falling back to DHCP"); + } + if(devmacaddr) free(devmacaddr); + } /* this is how we specify dhcp */ - if (!strncmp(loaderData->ipv4, "dhcp", 4)) { + else if (!strncmp(loaderData->ipv4, "dhcp", 4)) { iface->dhcptimeout = loaderData->dhcpTimeout; iface->ipv4method = IPV4_DHCP_METHOD; } else if (inet_pton(AF_INET, loaderData->ipv4, &addr) >= 1) { @@ -289,6 +308,24 @@ void setupIfaceStruct(iface_t * iface, struct loaderData_s * loaderData) { } #endif + /* iBFT configured DNS */ + if(iface->ipv4method == IPV4_IBFT_METHOD){ + if(iface->numdns<MAXNS){ + if(ibft_iface_dns1() && inet_pton(AF_INET, ibft_iface_dns1(), &addr)>=1){ + iface->dns[iface->numdns] = strdup(ibft_iface_dns1()); + iface->numdns++; + logMessage(INFO, "adding iBFT dns server %s", ibft_iface_dns1()); + } + } + if(iface->numdns<MAXNS){ + if(ibft_iface_dns2() && inet_pton(AF_INET, ibft_iface_dns2(), &addr)>=1){ + iface->dns[iface->numdns] = strdup(ibft_iface_dns2()); + iface->numdns++; + logMessage(INFO, "adding iBFT dns server %s", ibft_iface_dns2()); + } + } + } + if (loaderData->dns) { char * buf; char ret[INET6_ADDRSTRLEN+1]; @@ -320,6 +357,8 @@ void setupIfaceStruct(iface_t * iface, struct loaderData_s * loaderData) { } } + + logMessage(INFO, "dnsservers is %s", loaderData->dns); } @@ -1221,7 +1260,15 @@ int writeEnabledNetInfo(iface_t *iface) { fprintf(fp, "ONBOOT=yes\n"); if (!FL_NOIPV4(flags)) { - if (iface->ipv4method == IPV4_DHCP_METHOD) { + if (iface->ipv4method == IPV4_IBFT_METHOD) { + /* When initrd and NM support iBFT, we should just write + * BOOTPROTO=ibft and let NM deal with it. Until than, + * just use static and do it ourselves. */ + fprintf(fp, "BOOTPROTO=static\n"); + if(ibft_iface_ip()) fprintf(fp, "IPADDR=%s\n", ibft_iface_ip()); + if(ibft_iface_mask()) fprintf(fp, "NETMASK=%s\n", ibft_iface_mask()); + if(ibft_iface_gw()) fprintf(fp, "GATEWAY=%s\n", ibft_iface_gw()); + else if (iface->ipv4method == IPV4_DHCP_METHOD) { fprintf(fp, "BOOTPROTO=dhcp\n"); } else if (iface->ipv4method == IPV4_MANUAL_METHOD) { fprintf(fp, "BOOTPROTO=static\n"); @@ -1580,6 +1627,7 @@ int chooseNetworkInterface(struct loaderData_s * loaderData) { char **deviceNames; char *ksMacAddr = NULL, *seconds = strdup("10"), *idstr = NULL; struct device **devs; + int lookForLink = 0; struct newtWinEntry entry[] = {{N_("Seconds:"), (char **) &seconds, 0}, {NULL, NULL, 0 }}; @@ -1669,8 +1717,60 @@ int chooseNetworkInterface(struct loaderData_s * loaderData) { return LOADER_NOOP; } + while((loaderData->netDev && (loaderData->netDev_set == 1)) && + !strcmp(loaderData->netDev, "ibft")){ + char *devmacaddr = NULL; + char *ibftmacaddr = ""; + + /* get MAC from the iBFT table */ + if(!(ibftmacaddr = ibft_iface_mac())){ /* iBFT not present or error */ + lookForLink = 0; + break; + } + + logMessage(INFO, "looking for iBFT configured device %s with link", ibftmacaddr); + lookForLink = 0; + + for (i = 0; devs[i]; i++) { + if (!devs[i]->device) + continue; + devmacaddr = nl_mac2str(devs[i]->device); + if(!strcasecmp(devmacaddr, ibftmacaddr)){ + logMessage(INFO, "%s has the right MAC (%s), checking for link", devmacaddr, devices[i]); + free(devmacaddr); + if(get_link_status(devices[i]) == 1){ + lookForLink = 0; + loaderData->netDev = devices[i]; + logMessage(INFO, "%s has link, using it", devices[i]); + + /* set the IP method to ibft if not requested differently */ + if(loaderData->ip==NULL){ + loaderData->ip = strdup("ibft"); + logMessage(INFO, "%s will be configured using iBFT values", devices[i]); + } + return LOADER_NOOP; + } + else{ + logMessage(INFO, "%s has no link, skipping it", devices[i]); + } + + break; + } + else{ + free(devmacaddr); + } + } + + break; + } + + if ((loaderData->netDev && (loaderData->netDev_set == 1)) && !strcmp(loaderData->netDev, "link")) { + lookForLink = 1; + } + + if(lookForLink){ logMessage(INFO, "looking for first netDev with link"); for (rc = 0; rc < 5; rc++) { for (i = 0; i < deviceNums; i++) { -- 1.5.4.3 _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list