Blame utils/fwparam_ibft/fw_entry.c

Packit eace71
/*
Packit eace71
 * Copyright (C) IBM Corporation. 2007
Packit eace71
 * Author: Doug Maxey <dwm@austin.ibm.com>
Packit eace71
 * based on code written by "Prasanna Mumbai" <mumbai.prasanna@gmail.com>
Packit eace71
 *
Packit eace71
 * This program is free software: you can redistribute it and/or modify
Packit eace71
 * it under the terms of the GNU General Public License as published by
Packit eace71
 * the Free Software Foundation, either version 2 of the License, or
Packit eace71
 * (at your option) any later version.
Packit eace71
 *
Packit eace71
 * This program is distributed in the hope that it will be useful,
Packit eace71
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit eace71
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit eace71
 * GNU General Public License for more details.
Packit eace71
 *
Packit eace71
 * You should have received a copy of the GNU General Public License
Packit eace71
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
Packit eace71
 *
Packit eace71
 */
Packit eace71
#include <stddef.h>
Packit eace71
#include <stdio.h>
Packit eace71
#include <string.h>
Packit eace71
#include <stdlib.h>
Packit eace71
#include <unistd.h>
Packit eace71
#include <stddef.h>
Packit eace71
#include <errno.h>
Packit eace71
#include <sys/socket.h>
Packit eace71
#include <sys/ioctl.h>
Packit eace71
#include <netinet/in.h>
Packit eace71
#include <arpa/inet.h>
Packit eace71
#include <net/route.h>
Packit eace71
Packit eace71
#include "fw_context.h"
Packit eace71
#include "fwparam.h"
Packit eace71
#include "idbm_fields.h"
Packit eace71
#include "iscsi_net_util.h"
Packit eace71
#include "iscsi_err.h"
Packit eace71
#include "config.h"
Packit eace71
#include "iface.h"
Packit eace71
Packit eace71
/**
Packit eace71
 * fw_setup_nics - setup nics (ethXs) based on ibft net info
Packit eace71
 *
Packit eace71
 * If this is a offload card, this function does nothing. The
Packit eace71
 * net info is used by the iscsi iface settings for the iscsi
Packit eace71
 * function.
Packit eace71
 */
Packit eace71
int fw_setup_nics(void)
Packit eace71
{
Packit eace71
	struct boot_context *context;
Packit eace71
	struct list_head targets;
Packit eace71
	char *iface_prev = NULL, transport[16];
Packit eace71
	int needs_bringup = 0, ret = 0, err;
Packit eace71
Packit eace71
	INIT_LIST_HEAD(&targets;;
Packit eace71
Packit eace71
	ret = fw_get_targets(&targets;;
Packit eace71
	if (ret || list_empty(&targets)) {
Packit eace71
		printf("Could not setup fw entries.\n");
Packit eace71
		return ISCSI_ERR_NO_OBJS_FOUND;
Packit eace71
	}
Packit eace71
Packit eace71
	/*
Packit eace71
	 * For each target in iBFT bring up required NIC and use routing
Packit eace71
	 * to force iSCSI traffic through correct NIC
Packit eace71
	 */
Packit eace71
	list_for_each_entry(context, &targets, list) {
Packit eace71
		if (iface_prev == NULL || strcmp(context->iface, iface_prev)) {
Packit eace71
				/* Note: test above works because there is a
Packit eace71
				 * maximum of two targets in the iBFT
Packit eace71
				 */
Packit eace71
				iface_prev = context->iface;
Packit eace71
				needs_bringup = 1;
Packit eace71
		}
Packit eace71
		if (net_get_transport_name_from_netdev(context->iface, transport)) {
Packit eace71
			/* Setup software NIC, */
Packit eace71
			printf("Setting up software interface %s\n", context->iface);
Packit eace71
			err = net_setup_netdev(context->iface, context->ipaddr,
Packit eace71
								   context->mask, context->gateway,
Packit eace71
								   context->vlan,
Packit eace71
								   context->target_ipaddr, needs_bringup);
Packit eace71
			if (err) {
Packit eace71
				printf("Setting up software interface %s failed\n",
Packit eace71
						context->iface);
Packit eace71
				ret = err;
Packit eace71
			}
Packit eace71
		} else {
Packit eace71
			/* Setup offload NIC. */
Packit eace71
			struct iface_rec iface;
Packit eace71
Packit eace71
			memset(&iface, 0, sizeof(iface));
Packit eace71
			iface_setup_defaults(&iface);
Packit eace71
			printf("Setting up offload interface %s\n", context->iface);
Packit eace71
			if (!iface_setup_from_boot_context(&iface, context)) {
Packit eace71
					printf("Setting up offload interface %s failed\n",
Packit eace71
						   context->iface);
Packit eace71
Packit eace71
					ret = ISCSI_ERR;
Packit eace71
			}
Packit eace71
		}
Packit eace71
	}
Packit eace71
Packit eace71
	fw_free_targets(&targets;;
Packit eace71
	if (ret)
Packit eace71
		return ISCSI_ERR;
Packit eace71
	else
Packit eace71
		return 0;
Packit eace71
}
Packit eace71
Packit eace71
/**
Packit eace71
 * fw_get_entry - return boot context of portal used for boot
Packit eace71
 * @context: firmware info of portal
Packit eace71
 *
Packit eace71
 * Returns non-zero if no portal was used for boot.
Packit eace71
 *
Packit eace71
 * This function is not thread safe.
Packit eace71
 */
Packit eace71
int fw_get_entry(struct boot_context *context)
Packit eace71
{
Packit eace71
	int ret;
Packit eace71
Packit eace71
	ret = fwparam_ppc_boot_info(context);
Packit eace71
	if (ret)
Packit eace71
		ret = fwparam_sysfs_boot_info(context);
Packit eace71
	return ret;
Packit eace71
}
Packit eace71
Packit eace71
/**
Packit eace71
 * fw_get_targets - get a boot_context struct for each target
Packit eace71
 * @list: list to add entires on.
Packit eace71
 *
Packit eace71
 * Returns zero if entries were found that can be traversed with the
Packit eace71
 * list.h helpers, or non-zero if no entries are found.
Packit eace71
 *
Packit eace71
 * fw_free_targets should be called to free the list.
Packit eace71
 *
Packit eace71
 * This function is not thread safe.
Packit eace71
 */
Packit eace71
int fw_get_targets(struct list_head *list)
Packit eace71
{
Packit eace71
	int ret;
Packit eace71
Packit eace71
	ret = fwparam_ppc_get_targets(list);
Packit eace71
	if (ret)
Packit eace71
		ret = fwparam_sysfs_get_targets(list);
Packit eace71
	return ret;
Packit eace71
}
Packit eace71
Packit eace71
void fw_free_targets(struct list_head *list)
Packit eace71
{
Packit eace71
	struct boot_context *curr, *tmp;
Packit eace71
Packit eace71
	if (!list || list_empty(list))
Packit eace71
		return;
Packit eace71
Packit eace71
	list_for_each_entry_safe(curr, tmp, list, list) {
Packit eace71
		list_del(&curr->list);
Packit eace71
		free(curr);
Packit eace71
	}
Packit eace71
}
Packit eace71
Packit eace71
static void dump_initiator(struct boot_context *context)
Packit eace71
{
Packit eace71
	struct iface_rec iface;
Packit eace71
Packit eace71
	memset(&iface, 0, sizeof(iface));
Packit eace71
	iface_setup_defaults(&iface);
Packit eace71
	iface_setup_from_boot_context(&iface, context);
Packit eace71
Packit eace71
	if (strlen(context->initiatorname))
Packit eace71
		printf("%s = %s\n", IFACE_INAME, context->initiatorname);
Packit eace71
Packit eace71
	if (strlen(context->isid))
Packit eace71
		printf("%s = %s\n", IFACE_ISID, context->isid);
Packit eace71
Packit eace71
	printf("%s = %s\n", IFACE_TRANSPORTNAME, iface.transport_name);
Packit eace71
}
Packit eace71
Packit eace71
static void dump_target(struct boot_context *context)
Packit eace71
{
Packit eace71
	if (strlen(context->targetname))
Packit eace71
		printf("%s = %s\n", NODE_NAME, context->targetname);
Packit eace71
Packit eace71
	if (strlen(context->target_ipaddr))
Packit eace71
		printf(CONN_ADDR" = %s\n", 0, context->target_ipaddr);
Packit eace71
	printf(CONN_PORT" = %d\n", 0, context->target_port);
Packit eace71
Packit eace71
	if (strlen(context->chap_name))
Packit eace71
		printf("%s = %s\n", SESSION_USERNAME, context->chap_name);
Packit eace71
	if (strlen(context->chap_password))
Packit eace71
		printf("%s = %s\n", SESSION_PASSWORD, context->chap_password);
Packit eace71
	if (strlen(context->chap_name_in))
Packit eace71
		printf("%s = %s\n", SESSION_USERNAME_IN, context->chap_name_in);
Packit eace71
	if (strlen(context->chap_password_in))
Packit eace71
		printf("%s = %s\n", SESSION_PASSWORD_IN,
Packit eace71
		       context->chap_password_in);
Packit eace71
Packit eace71
	if (strlen(context->lun))
Packit eace71
		printf("%s = %s\n", NODE_BOOT_LUN, context->lun);
Packit eace71
}
Packit eace71
Packit eace71
static void dump_network(struct boot_context *context)
Packit eace71
{
Packit eace71
	/* Dump the 8 byte mac address (not iser support) */
Packit eace71
	if (strlen(context->mac))
Packit eace71
		printf("%s = %s\n", IFACE_HWADDR, context->mac);
Packit eace71
	/*
Packit eace71
	 * If the 'origin' field is 3 (IBFT_IP_PREFIX_ORIGIN_DHCP),
Packit eace71
	 * then DHCP is used.
Packit eace71
	 * Otherwise evaluate the 'dhcp' field, if this has a valid
Packit eace71
	 * address then DHCP was used (broadcom sends 0.0.0.0).
Packit eace71
	 */
Packit eace71
	if ((context->origin == IBFT_IP_PREFIX_ORIGIN_DHCP) ||
Packit eace71
	    (strlen(context->dhcp) && strcmp(context->dhcp, "0.0.0.0")))
Packit eace71
		printf("%s = DHCP\n", IFACE_BOOT_PROTO);
Packit eace71
	else
Packit eace71
		printf("%s = STATIC\n", IFACE_BOOT_PROTO);
Packit eace71
	if (strlen(context->ipaddr))
Packit eace71
		printf("%s = %s\n", IFACE_IPADDR, context->ipaddr);
Packit eace71
	if (context->prefix)
Packit eace71
		printf("%s = %d\n", IFACE_PREFIX_LEN, context->prefix);
Packit eace71
	if (strlen(context->mask))
Packit eace71
		printf("%s = %s\n", IFACE_SUBNET_MASK, context->mask);
Packit eace71
	if (strlen(context->gateway))
Packit eace71
		printf("%s = %s\n", IFACE_GATEWAY, context->gateway);
Packit eace71
	if (strlen(context->primary_dns))
Packit eace71
		printf("%s = %s\n", IFACE_PRIMARY_DNS, context->primary_dns);
Packit eace71
	if (strlen(context->secondary_dns))
Packit eace71
		printf("%s = %s\n", IFACE_SEC_DNS, context->secondary_dns);
Packit eace71
	if (strlen(context->vlan))
Packit eace71
		printf("%s = %s\n", IFACE_VLAN_ID, context->vlan);
Packit eace71
	if (strlen(context->iface))
Packit eace71
		printf("%s = %s\n", IFACE_NETNAME, context->iface);
Packit eace71
}
Packit eace71
Packit eace71
/**
Packit eace71
 * fw_print_entry - print boot context info of portal used for boot
Packit eace71
 * @context: firmware info of portal
Packit eace71
 *
Packit eace71
 * Does not print anything if no portal was used for boot.
Packit eace71
 *
Packit eace71
 * TODO: Merge this in with idbm.c helpers.
Packit eace71
 */
Packit eace71
void fw_print_entry(struct boot_context *context)
Packit eace71
{
Packit eace71
	printf("%s\n", ISCSI_BEGIN_REC);
Packit eace71
	dump_initiator(context);
Packit eace71
	dump_network(context);
Packit eace71
	dump_target(context);
Packit eace71
	printf("%s\n", ISCSI_END_REC);
Packit eace71
}