Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932519AbZFORef (ORCPT ); Mon, 15 Jun 2009 13:34:35 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1764257AbZFOReK (ORCPT ); Mon, 15 Jun 2009 13:34:10 -0400 Received: from g4t0016.houston.hp.com ([15.201.24.19]:23466 "EHLO g4t0016.houston.hp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1762355AbZFOReF convert rfc822-to-8bit (ORCPT ); Mon, 15 Jun 2009 13:34:05 -0400 From: "Fischer, Anna" To: "bridge@lists.linux-foundation.org" , "linux-kernel@vger.kernel.org" , "netdev@vger.kernel.org" , "virtualization@lists.linux-foundation.org" , "evb@yahoogroups.com" CC: "shemminger@linux-foundation.org" , "davem@davemloft.net" , "kaber@trash.net" , "adobriyan@gmail.com" , Arnd Bergmann , "Paul Congdon (UC Davis)" Date: Mon, 15 Jun 2009 17:33:55 +0000 Subject: [PATCH][RFC] bridge-utils: add basic VEPA support Thread-Topic: [PATCH][RFC] bridge-utils: add basic VEPA support Thread-Index: Acnt33VgGC0LrPrTS5GEr9IDsUDtuQ== Message-ID: <0199E0D51A61344794750DC57738F58E67D2DCECBD@GVW1118EXC.americas.hpqcorp.net> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: acceptlanguage: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 8BIT MIME-Version: 1.0 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 12426 Lines: 406 This patch adds basic Virtual Ethernet Port Aggregator (VEPA) capabilities to the Linux Ethernet bridging utilities. The patch provides functionality that depends on the Linux kernel patch 'net/bridge: add basic VEPA support'. This patch relies on the patch 'bridge-utils: fix sysfs path for setting bridge configuration parameters'. A Virtual Ethernet Port Aggregator (VEPA) is a capability within a physical end station that collaborates with an adjacent, external bridge to provide distributed bridging support between multiple virtual end stations and external networks. The VEPA collaborates by forwarding all station-originated frames to the adjacent bridge for frame processing and frame relay (including so-called 'hairpin' forwarding) and by steering and replicating frames received from the VEPA uplink to the appropriate destinations. A VEPA may be implemented in software or in conjunction with embedded hardware. In particular, the patch extends the Linux Ethernet bridge utilities to configure a bridge to act as (1) a VEPA, or as (2) a bridge supporting 'hairpin' forwarding. You can find additional information on VEPA here: http://tech.groups.yahoo.com/group/evb/ http://www.ieee802.org/1/files/public/docs2009/new-hudson-vepa_seminar-20090514d.pdf Signed-off-by: Paul Congdon Signed-off-by: Anna Fischer --- brctl/brctl_cmd.c | 108 ++++++++++++++++++++++++++++++++++++++++--- brctl/brctl_disp.c | 6 ++ libbridge/libbridge.h | 7 +++ libbridge/libbridge_devif.c | 90 ++++++++++++++++++++++++++++++++++- 4 files changed, 201 insertions(+), 10 deletions(-) diff --git a/brctl/brctl_cmd.c b/brctl/brctl_cmd.c index c93dd55..77eaf1e 100644 --- a/brctl/brctl_cmd.c +++ b/brctl/brctl_cmd.c @@ -280,17 +280,26 @@ static int br_cmd_setportprio(int argc, char *const* argv) return err != 0; } +static int br_parse_param(const char *param, int *res) +{ + if (!strcmp(param, "on") || !strcmp(param, "yes") + || !strcmp(param, "1")) + *res = 1; + else if (!strcmp(param, "off") || !strcmp(param, "no") + || !strcmp(param, "0")) + *res = 0; + else { + return EINVAL; + } + return 0; +} + static int br_cmd_stp(int argc, char *const* argv) { int stp, err; - if (!strcmp(argv[2], "on") || !strcmp(argv[2], "yes") - || !strcmp(argv[2], "1")) - stp = 1; - else if (!strcmp(argv[2], "off") || !strcmp(argv[2], "no") - || !strcmp(argv[2], "0")) - stp = 0; - else { + err = br_parse_param(argv[2], &stp); + if (err) { fprintf(stderr, "expect on/off for argument\n"); return 1; } @@ -316,6 +325,85 @@ static int br_cmd_showstp(int argc, char *const* argv) return 0; } +static int br_cmd_vepa(int argc, char *const* argv) +{ + int vepa, err; + + err = br_parse_param(argv[2], &vepa); + if (err) { + fprintf(stderr, "expect on/off for argument\n"); + return 1; + } + + err = br_set_vepa_mode(argv[1], vepa); + if (err) + fprintf(stderr, "set vepa mode failed: %s\n", + strerror(errno)); + return err != 0; +} + +static int br_cmd_vepauplink(int argc, char *const* argv) +{ + const char *brname = *++argv; + const char *ifname = *++argv; + int err; + + if (if_nametoindex(ifname) == 0) { + fprintf(stderr, "interface %s does not exist!\n", + ifname); + return 1; + } else if (if_nametoindex(brname) == 0) { + fprintf(stderr, "bridge %s does not exist!\n", + brname); + return 1; + } + + err = br_set_vepa_uplink(brname, ifname); + + if (err) { + fprintf(stderr, "cannot set %s as vepa uplink.\n%s has " + "to be valid port of bridge %s: %s\n", ifname, + ifname, brname, strerror(err)); + } + return err != 0; +} + +static int br_cmd_hairpin(int argc, char *const* argv) +{ + int hairpin, err; + const char *brname = *++argv; + const char *ifname = *++argv; + const char *hpmode = *++argv; + + if (!strcmp(hpmode, "on") || !strcmp(hpmode, "yes") + || !strcmp(hpmode, "1")) + hairpin = 1; + else if (!strcmp(hpmode, "off") || !strcmp(hpmode, "no") + || !strcmp(hpmode, "0")) + hairpin = 0; + else { + fprintf(stderr, "expect on/off for argument\n"); + return 1; + } + if (if_nametoindex(ifname) == 0) { + fprintf(stderr, "interface %s does not exist!\n", + ifname); + return 1; + } else if (if_nametoindex(brname) == 0) { + fprintf(stderr, "bridge %s does not exist!\n", + brname); + return 1; + } + + err = br_set_hairpin_mode(brname, ifname, hairpin); + + if (err) { + fprintf(stderr, "can't set %s to hairpin on bridge %s: %s\n", + ifname, brname, strerror(err)); + } + return err != 0; +} + static int show_bridge(const char *name, void *arg) { struct bridge_info info; @@ -402,6 +490,8 @@ static const struct command commands[] = { " \tadd interface to bridge" }, { 2, "delif", br_cmd_delif, " \tdelete interface from bridge" }, + { 3, "hairpin", br_cmd_hairpin, + " {on|off}\tturn hairpin on/off" }, { 2, "setageing", br_cmd_setageing, "