Skip to content

Commit

Permalink
teamd: introduce simple SR-IOV support
Browse files Browse the repository at this point in the history
Just warn user if he is teaming virt functions belonging under same
physical function.

Signed-off-by: Jiri Pirko <jiri@resnulli.us>
  • Loading branch information
jpirko committed May 24, 2013
1 parent 0652c68 commit 268932b
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 3 deletions.
5 changes: 3 additions & 2 deletions teamd/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ bin_PROGRAMS=teamd
teamd_SOURCES=teamd.c teamd_common.c teamd_json.c teamd_config.c teamd_state.c \
teamd_workq.c teamd_events.c teamd_per_port.c \
teamd_option_watch.c teamd_ifinfo_watch.c teamd_link_watch.c \
teamd_ctl.c teamd_dbus.c teamd_usock.c \
teamd_ctl.c teamd_dbus.c teamd_usock.c teamd_sriov.c \
teamd_bpf_chef.c teamd_hash_func.c teamd_balancer.c \
teamd_runner_basic_ones.c teamd_runner_activebackup.c \
teamd_runner_loadbalance.c teamd_runner_lacp.c
Expand All @@ -23,4 +23,5 @@ EXTRA_DIST = example_configs dbus redhat

noinst_HEADERS = teamd.h teamd_workq.h teamd_bpf_chef.h teamd_ctl.h \
teamd_json.h teamd_dbus.h teamd_usock.h teamd_dbus_common.h \
teamd_usock_common.h teamd_config.h teamd_state.h
teamd_usock_common.h teamd_config.h teamd_state.h \
teamd_sriov.h
13 changes: 12 additions & 1 deletion teamd/teamd.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include "teamd_state.h"
#include "teamd_usock.h"
#include "teamd_dbus.h"
#include "teamd_sriov.h"

static const struct teamd_runner *teamd_runner_list[] = {
&teamd_runner_broadcast,
Expand Down Expand Up @@ -1114,10 +1115,16 @@ static int teamd_init(struct teamd_context *ctx)
goto runner_fini;
}

err = teamd_sriov_init(ctx);
if (err) {
teamd_log_err("Failed to init SR-IOV support.");
goto state_basics_fini;
}

err = teamd_usock_init(ctx);
if (err) {
teamd_log_err("Failed to init unix domain socket.");
goto state_basics_fini;
goto sriov_fini;
}

err = teamd_dbus_init(ctx);
Expand Down Expand Up @@ -1148,6 +1155,8 @@ static int teamd_init(struct teamd_context *ctx)
teamd_dbus_fini(ctx);
usock_fini:
teamd_usock_fini(ctx);
sriov_fini:
teamd_sriov_fini(ctx);
state_basics_fini:
teamd_state_basics_fini(ctx);
runner_fini:
Expand Down Expand Up @@ -1183,6 +1192,8 @@ static void teamd_fini(struct teamd_context *ctx)
{
teamd_dbus_fini(ctx);
teamd_usock_fini(ctx);
teamd_sriov_fini(ctx);
teamd_state_basics_fini(ctx);
teamd_runner_fini(ctx);
teamd_link_watch_fini(ctx);
teamd_per_port_fini(ctx);
Expand Down
113 changes: 113 additions & 0 deletions teamd/teamd_sriov.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/*
* teamd_sriov.c - SR-IOV support for teamd
* Copyright (C) 2013 Jiri Pirko <jiri@resnulli.us>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#include "teamd.h"

struct pcie_addr {
uint16_t domain;
uint8_t bus;
uint8_t slot;
uint8_t function;
};

static int teamd_sriov_physfn_addr(struct pcie_addr *addr, const char *ifname)
{
char link[256];
char *path;
char *start;
int ret;

ret = asprintf(&path, "/sys/class/net/%s/device/physfn", ifname);
if (ret == -1)
return -ENOMEM;

ret = readlink(path, link, sizeof(link));
free(path);
if (ret == -1)
return -errno;

start = strrchr(link, '/');
if (!start)
return -EINVAL;
start++;
memset(addr, 0, sizeof(*addr));
ret = sscanf(start, "%04x:%02x:%02x.%x", (unsigned int *) &addr->domain,
(unsigned int *) &addr->bus,
(unsigned int *) &addr->slot,
(unsigned int *) &addr->function);
if (ret != 4)
return -EINVAL;
return 0;
}

static int teamd_sriov_event_watch_port_added(struct teamd_context *ctx,
struct teamd_port *tdport,
void *priv)
{
struct pcie_addr physfnaddr;
struct pcie_addr cur_physfnaddr;
struct teamd_port *cur_tdport;
int err;

err = teamd_sriov_physfn_addr(&physfnaddr, tdport->ifname);
if (err)
return 0;

teamd_for_each_tdport(cur_tdport, ctx) {
if (cur_tdport == tdport)
continue;
err = teamd_sriov_physfn_addr(&cur_physfnaddr,
cur_tdport->ifname);
if (err)
continue;
if (!memcmp(&physfnaddr, &cur_physfnaddr, sizeof(physfnaddr)))
teamd_log_warn("%s: port is virtual function of same physical function as port %s. Note that teaming virtual functions of the same physical function makes no sense.",
tdport->ifname, cur_tdport->ifname);
}
return 0;
}

static const struct teamd_event_watch_ops teamd_sriov_event_watch_ops = {
.port_added = teamd_sriov_event_watch_port_added,
};

int teamd_sriov_init(struct teamd_context *ctx)
{
int err;

err = teamd_event_watch_register(ctx, &teamd_sriov_event_watch_ops,
NULL);
if (err) {
teamd_log_err("Failed to register event watch.");
return err;
}
return 0;
}

void teamd_sriov_fini(struct teamd_context *ctx)
{
teamd_event_watch_unregister(ctx, &teamd_sriov_event_watch_ops,
NULL);
}
28 changes: 28 additions & 0 deletions teamd/teamd_sriov.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* teamd_sriov.h - SR-IOV support for teamd
* Copyright (C) 2013 Jiri Pirko <jiri@resnulli.us>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/

#ifndef _TEAMD_SRIOV_H_
#define _TEAMD_SRIOV_H_

#include <jansson.h>

int teamd_sriov_init(struct teamd_context *ctx);
void teamd_sriov_fini(struct teamd_context *ctx);

#endif /* _TEAMD_SRIOV_H_ */

0 comments on commit 268932b

Please sign in to comment.