aboutsummaryrefslogtreecommitdiffstats
path: root/brctl/brctl_cmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'brctl/brctl_cmd.c')
-rw-r--r--brctl/brctl_cmd.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/brctl/brctl_cmd.c b/brctl/brctl_cmd.c
index c93dd55..d37e99c 100644
--- a/brctl/brctl_cmd.c
+++ b/brctl/brctl_cmd.c
@@ -395,6 +395,42 @@ static int br_cmd_showmacs(int argc, char *const* argv)
return 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 const struct command commands[] = {
{ 1, "addbr", br_cmd_addbr, "<bridge>\t\tadd bridge" },
{ 1, "delbr", br_cmd_delbr, "<bridge>\t\tdelete bridge" },
@@ -402,6 +438,8 @@ static const struct command commands[] = {
"<bridge> <device>\tadd interface to bridge" },
{ 2, "delif", br_cmd_delif,
"<bridge> <device>\tdelete interface from bridge" },
+ { 3, "hairpin", br_cmd_hairpin,
+ "<bridge> <port> {on|off}\tturn hairpin on/off" },
{ 2, "setageing", br_cmd_setageing,
"<bridge> <time>\t\tset ageing time" },
{ 2, "setbridgeprio", br_cmd_setbridgeprio,