* [patch net-next 1/2] team: add binary option type
@ 2012-04-04 22:16 Jiri Pirko
2012-04-04 22:16 ` [patch net-next 2/2] team: add loadbalance mode Jiri Pirko
2012-04-05 0:31 ` [patch net-next 1/2] team: add binary option type David Miller
0 siblings, 2 replies; 6+ messages in thread
From: Jiri Pirko @ 2012-04-04 22:16 UTC (permalink / raw)
To: netdev
Cc: davem, eric.dumazet, bhutchings, shemminger, raise.sail,
nuno.martins, matt
For transfering generic binary data (e.g. BPF code), introduce new
binary option type.
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
---
drivers/net/team/team.c | 30 ++++++++++++++++++++++++++----
include/linux/if_team.h | 8 ++++++++
2 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 0db6e66..ea96f82 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -1145,10 +1145,7 @@ team_nl_option_policy[TEAM_ATTR_OPTION_MAX + 1] = {
},
[TEAM_ATTR_OPTION_CHANGED] = { .type = NLA_FLAG },
[TEAM_ATTR_OPTION_TYPE] = { .type = NLA_U8 },
- [TEAM_ATTR_OPTION_DATA] = {
- .type = NLA_BINARY,
- .len = TEAM_STRING_MAX_LEN,
- },
+ [TEAM_ATTR_OPTION_DATA] = { .type = NLA_BINARY },
};
static int team_nl_cmd_noop(struct sk_buff *skb, struct genl_info *info)
@@ -1257,6 +1254,7 @@ static int team_nl_fill_options_get(struct sk_buff *skb,
list_for_each_entry(option, &team->option_list, list) {
struct nlattr *option_item;
long arg;
+ struct team_option_binary tbinary;
/* Include only changed options if fill all mode is not on */
if (!fillall && !option->changed)
@@ -1290,6 +1288,15 @@ static int team_nl_fill_options_get(struct sk_buff *skb,
(char *) arg))
goto nla_put_failure;
break;
+ case TEAM_OPTION_TYPE_BINARY:
+ if (nla_put_u8(skb, TEAM_ATTR_OPTION_TYPE, NLA_BINARY))
+ goto nla_put_failure;
+ arg = (long) &tbinary;
+ team_option_get(team, option, &arg);
+ if (nla_put(skb, TEAM_ATTR_OPTION_DATA,
+ tbinary.data_len, tbinary.data))
+ goto nla_put_failure;
+ break;
default:
BUG();
}
@@ -1374,6 +1381,9 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
case NLA_STRING:
opt_type = TEAM_OPTION_TYPE_STRING;
break;
+ case NLA_BINARY:
+ opt_type = TEAM_OPTION_TYPE_BINARY;
+ break;
default:
goto team_put;
}
@@ -1382,19 +1392,31 @@ static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
list_for_each_entry(option, &team->option_list, list) {
long arg;
struct nlattr *opt_data_attr;
+ struct team_option_binary tbinary;
+ int data_len;
if (option->type != opt_type ||
strcmp(option->name, opt_name))
continue;
opt_found = true;
opt_data_attr = mode_attrs[TEAM_ATTR_OPTION_DATA];
+ data_len = nla_len(opt_data_attr);
switch (opt_type) {
case TEAM_OPTION_TYPE_U32:
arg = nla_get_u32(opt_data_attr);
break;
case TEAM_OPTION_TYPE_STRING:
+ if (data_len > TEAM_STRING_MAX_LEN) {
+ err = -EINVAL;
+ goto team_put;
+ }
arg = (long) nla_data(opt_data_attr);
break;
+ case TEAM_OPTION_TYPE_BINARY:
+ tbinary.data_len = data_len;
+ tbinary.data = nla_data(opt_data_attr);
+ arg = (long) &tbinary;
+ break;
default:
BUG();
}
diff --git a/include/linux/if_team.h b/include/linux/if_team.h
index 58404b0..41163ac 100644
--- a/include/linux/if_team.h
+++ b/include/linux/if_team.h
@@ -68,6 +68,7 @@ struct team_mode_ops {
enum team_option_type {
TEAM_OPTION_TYPE_U32,
TEAM_OPTION_TYPE_STRING,
+ TEAM_OPTION_TYPE_BINARY,
};
struct team_option {
@@ -82,6 +83,13 @@ struct team_option {
bool removed;
};
+struct team_option_binary {
+ u32 data_len;
+ void *data;
+};
+
+#define team_optarg_tbinary(arg) (*((struct team_option_binary **) arg))
+
struct team_mode {
struct list_head list;
const char *kind;
--
1.7.9.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [patch net-next 2/2] team: add loadbalance mode
2012-04-04 22:16 [patch net-next 1/2] team: add binary option type Jiri Pirko
@ 2012-04-04 22:16 ` Jiri Pirko
2012-04-04 22:26 ` David Miller
2012-04-05 0:31 ` David Miller
2012-04-05 0:31 ` [patch net-next 1/2] team: add binary option type David Miller
1 sibling, 2 replies; 6+ messages in thread
From: Jiri Pirko @ 2012-04-04 22:16 UTC (permalink / raw)
To: netdev
Cc: davem, eric.dumazet, bhutchings, shemminger, raise.sail,
nuno.martins, matt
This patch introduces new team mode. It's TX port is selected by
user-set BPF hash function.
Signed-off-by: Jiri Pirko <jpirko@redhat.com>
---
drivers/net/team/Kconfig | 11 ++
drivers/net/team/Makefile | 1 +
drivers/net/team/team_mode_loadbalance.c | 188 ++++++++++++++++++++++++++++++
3 files changed, 200 insertions(+), 0 deletions(-)
create mode 100644 drivers/net/team/team_mode_loadbalance.c
diff --git a/drivers/net/team/Kconfig b/drivers/net/team/Kconfig
index 248a144..89024d5 100644
--- a/drivers/net/team/Kconfig
+++ b/drivers/net/team/Kconfig
@@ -40,4 +40,15 @@ config NET_TEAM_MODE_ACTIVEBACKUP
To compile this team mode as a module, choose M here: the module
will be called team_mode_activebackup.
+config NET_TEAM_MODE_LOADBALANCE
+ tristate "Load-balance mode support"
+ depends on NET_TEAM
+ ---help---
+ This mode provides load balancing functionality. Tx port selection
+ is done using BPF function set up from userspace (bpf_hash_func
+ option)
+
+ To compile this team mode as a module, choose M here: the module
+ will be called team_mode_loadbalance.
+
endif # NET_TEAM
diff --git a/drivers/net/team/Makefile b/drivers/net/team/Makefile
index 85f2028..fb9f4c1 100644
--- a/drivers/net/team/Makefile
+++ b/drivers/net/team/Makefile
@@ -5,3 +5,4 @@
obj-$(CONFIG_NET_TEAM) += team.o
obj-$(CONFIG_NET_TEAM_MODE_ROUNDROBIN) += team_mode_roundrobin.o
obj-$(CONFIG_NET_TEAM_MODE_ACTIVEBACKUP) += team_mode_activebackup.o
+obj-$(CONFIG_NET_TEAM_MODE_LOADBALANCE) += team_mode_loadbalance.o
diff --git a/drivers/net/team/team_mode_loadbalance.c b/drivers/net/team/team_mode_loadbalance.c
new file mode 100644
index 0000000..ed20f39
--- /dev/null
+++ b/drivers/net/team/team_mode_loadbalance.c
@@ -0,0 +1,188 @@
+/*
+ * drivers/net/team/team_mode_loadbalance.c - Load-balancing mode for team
+ * Copyright (c) 2012 Jiri Pirko <jpirko@redhat.com>
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/filter.h>
+#include <linux/if_team.h>
+
+struct lb_priv {
+ struct sk_filter __rcu *fp;
+ struct sock_fprog *orig_fprog;
+};
+
+static struct lb_priv *lb_priv(struct team *team)
+{
+ return (struct lb_priv *) &team->mode_priv;
+}
+
+static bool lb_transmit(struct team *team, struct sk_buff *skb)
+{
+ struct sk_filter *fp;
+ struct team_port *port;
+ unsigned int hash;
+ int port_index;
+
+ fp = rcu_dereference(lb_priv(team)->fp);
+ if (unlikely(!fp))
+ goto drop;
+ hash = SK_RUN_FILTER(fp, skb);
+ port_index = hash % team->port_count;
+ port = team_get_port_by_index_rcu(team, port_index);
+ if (unlikely(!port))
+ goto drop;
+ skb->dev = port->dev;
+ if (dev_queue_xmit(skb))
+ return false;
+ return true;
+
+drop:
+ dev_kfree_skb_any(skb);
+ return false;
+}
+
+static int lb_bpf_func_get(struct team *team, void *arg)
+{
+ struct team_option_binary *tbinary = team_optarg_tbinary(arg);
+
+ memset(tbinary, 0, sizeof(*tbinary));
+ if (!lb_priv(team)->orig_fprog)
+ return 0;
+
+ tbinary->data_len = lb_priv(team)->orig_fprog->len *
+ sizeof(struct sock_filter);
+ tbinary->data = lb_priv(team)->orig_fprog->filter;
+ return 0;
+}
+
+static int __fprog_create(struct sock_fprog **pfprog, u32 data_len,
+ void *data)
+{
+ struct sock_fprog *fprog;
+ struct sock_filter *filter = (struct sock_filter *) data;
+
+ if (data_len % sizeof(struct sock_filter))
+ return -EINVAL;
+ fprog = kmalloc(sizeof(struct sock_fprog), GFP_KERNEL);
+ if (!fprog)
+ return -ENOMEM;
+ fprog->filter = kmemdup(filter, data_len, GFP_KERNEL);
+ if (!fprog->filter) {
+ kfree(fprog);
+ return -ENOMEM;
+ }
+ fprog->len = data_len / sizeof(struct sock_filter);
+ *pfprog = fprog;
+ return 0;
+}
+
+static void __fprog_destroy(struct sock_fprog *fprog)
+{
+ kfree(fprog->filter);
+ kfree(fprog);
+}
+
+static int lb_bpf_func_set(struct team *team, void *arg)
+{
+ struct team_option_binary *tbinary = team_optarg_tbinary(arg);
+ struct sk_filter *fp = NULL;
+ struct sock_fprog *fprog = NULL;
+ int err;
+
+ if (tbinary->data_len) {
+ err = __fprog_create(&fprog, tbinary->data_len,
+ tbinary->data);
+ if (err)
+ return err;
+ err = sk_unattached_filter_create(&fp, fprog);
+ if (err) {
+ __fprog_destroy(fprog);
+ return err;
+ }
+ }
+
+ if (lb_priv(team)->orig_fprog) {
+ /* Clear old filter data */
+ __fprog_destroy(lb_priv(team)->orig_fprog);
+ sk_unattached_filter_destroy(lb_priv(team)->fp);
+ }
+
+ rcu_assign_pointer(lb_priv(team)->fp, fp);
+ lb_priv(team)->orig_fprog = fprog;
+ return 0;
+}
+
+static const struct team_option lb_options[] = {
+ {
+ .name = "bpf_hash_func",
+ .type = TEAM_OPTION_TYPE_BINARY,
+ .getter = lb_bpf_func_get,
+ .setter = lb_bpf_func_set,
+ },
+};
+
+int lb_init(struct team *team)
+{
+ return team_options_register(team, lb_options,
+ ARRAY_SIZE(lb_options));
+}
+
+void lb_exit(struct team *team)
+{
+ team_options_unregister(team, lb_options,
+ ARRAY_SIZE(lb_options));
+}
+
+static int lb_port_enter(struct team *team, struct team_port *port)
+{
+ return team_port_set_team_mac(port);
+}
+
+static void lb_port_change_mac(struct team *team, struct team_port *port)
+{
+ team_port_set_team_mac(port);
+}
+
+static const struct team_mode_ops lb_mode_ops = {
+ .init = lb_init,
+ .exit = lb_exit,
+ .transmit = lb_transmit,
+ .port_enter = lb_port_enter,
+ .port_change_mac = lb_port_change_mac,
+};
+
+static struct team_mode lb_mode = {
+ .kind = "loadbalance",
+ .owner = THIS_MODULE,
+ .priv_size = sizeof(struct lb_priv),
+ .ops = &lb_mode_ops,
+};
+
+static int __init lb_init_module(void)
+{
+ return team_mode_register(&lb_mode);
+}
+
+static void __exit lb_cleanup_module(void)
+{
+ team_mode_unregister(&lb_mode);
+}
+
+module_init(lb_init_module);
+module_exit(lb_cleanup_module);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Jiri Pirko <jpirko@redhat.com>");
+MODULE_DESCRIPTION("Load-balancing mode for team");
+MODULE_ALIAS("team-mode-loadbalance");
--
1.7.9.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [patch net-next 2/2] team: add loadbalance mode
2012-04-04 22:16 ` [patch net-next 2/2] team: add loadbalance mode Jiri Pirko
@ 2012-04-04 22:26 ` David Miller
2012-04-05 6:37 ` Jiri Pirko
2012-04-05 0:31 ` David Miller
1 sibling, 1 reply; 6+ messages in thread
From: David Miller @ 2012-04-04 22:26 UTC (permalink / raw)
To: jpirko
Cc: netdev, eric.dumazet, bhutchings, shemminger, raise.sail,
nuno.martins, matt
Hmmm, is the first patch stuck in a mail server queue somewhere?
I didn't see it.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [patch net-next 2/2] team: add loadbalance mode
2012-04-04 22:16 ` [patch net-next 2/2] team: add loadbalance mode Jiri Pirko
2012-04-04 22:26 ` David Miller
@ 2012-04-05 0:31 ` David Miller
1 sibling, 0 replies; 6+ messages in thread
From: David Miller @ 2012-04-05 0:31 UTC (permalink / raw)
To: jpirko
Cc: netdev, eric.dumazet, bhutchings, shemminger, raise.sail,
nuno.martins, matt
From: Jiri Pirko <jpirko@redhat.com>
Date: Thu, 5 Apr 2012 00:16:27 +0200
> This patch introduces new team mode. It's TX port is selected by
> user-set BPF hash function.
>
> Signed-off-by: Jiri Pirko <jpirko@redhat.com>
Applied, thanks Jiri.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [patch net-next 1/2] team: add binary option type
2012-04-04 22:16 [patch net-next 1/2] team: add binary option type Jiri Pirko
2012-04-04 22:16 ` [patch net-next 2/2] team: add loadbalance mode Jiri Pirko
@ 2012-04-05 0:31 ` David Miller
1 sibling, 0 replies; 6+ messages in thread
From: David Miller @ 2012-04-05 0:31 UTC (permalink / raw)
To: jpirko
Cc: netdev, eric.dumazet, bhutchings, shemminger, raise.sail,
nuno.martins, matt
From: Jiri Pirko <jpirko@redhat.com>
Date: Thu, 5 Apr 2012 00:16:26 +0200
> For transfering generic binary data (e.g. BPF code), introduce new
> binary option type.
>
> Signed-off-by: Jiri Pirko <jpirko@redhat.com>
Applied.
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2012-04-05 6:37 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-04-04 22:16 [patch net-next 1/2] team: add binary option type Jiri Pirko
2012-04-04 22:16 ` [patch net-next 2/2] team: add loadbalance mode Jiri Pirko
2012-04-04 22:26 ` David Miller
2012-04-05 6:37 ` Jiri Pirko
2012-04-05 0:31 ` David Miller
2012-04-05 0:31 ` [patch net-next 1/2] team: add binary option type David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).