* Re: [patch net-next v3 04/17] net: introduce generic switch devices support
From: Jamal Hadi Salim @ 2014-11-25 15:51 UTC (permalink / raw)
To: Jiri Pirko, netdev
Cc: davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse, pshelar,
azhou, ben, stephen, jeffrey.t.kirsher, vyasevic, xiyou.wangcong,
john.r.fastabend, edumazet, sfeldma, f.fainelli, roopa, linville,
jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a, buytenh,
aviadr, nbd, alexei.starovoitov, Neil.Jerram, ronye, simon.horman,
alexander.h.duyck, john.ronciak, mleitner, shrijeet, gospo, bcrl
In-Reply-To: <1416911328-10979-5-git-send-email-jiri@resnulli.us>
On 11/25/14 05:28, Jiri Pirko wrote:
> The goal of this is to provide a possibility to support various switch
> chips. Drivers should implement relevant ndos to do so. Now there is
> only one ndo defined:
> - for getting physical switch id is in place.
>
I am not sure switch id is the right term. I have a network processor
that *does not* do switching. I am not sure if "chip" or "ASIC" or
"offload_id" would be the right term. switch doesnt sound right.
cheers,
jamal
^ permalink raw reply
* Re: [patch net-next v3 03/17] net: rename netdev_phys_port_id to more generic name
From: Jamal Hadi Salim @ 2014-11-25 15:44 UTC (permalink / raw)
To: Jiri Pirko, netdev
Cc: davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse, pshelar,
azhou, ben, stephen, jeffrey.t.kirsher, vyasevic, xiyou.wangcong,
john.r.fastabend, edumazet, sfeldma, f.fainelli, roopa, linville,
jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a, buytenh,
aviadr, nbd, alexei.starovoitov, Neil.Jerram, ronye, simon.horman,
alexander.h.duyck, john.ronciak, mleitner, shrijeet, gospo, bcrl
In-Reply-To: <1416911328-10979-4-git-send-email-jiri@resnulli.us>
On 11/25/14 05:28, Jiri Pirko wrote:
> So this can be reused for identification of other "items" as well.
>
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
> Reviewed-by: Thomas Graf <tgraf@suug.ch>
> Acked-by: John Fastabend <john.r.fastabend@intel.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
cheers,
jamal
^ permalink raw reply
* Re: [patch net-next v3 02/17] net: make vid as a parameter for ndo_fdb_add/ndo_fdb_del
From: John Fastabend @ 2014-11-25 15:43 UTC (permalink / raw)
To: Jiri Pirko
Cc: Andy Gospodarek, netdev, davem, nhorman, andy, tgraf, dborkman,
ogerlitz, jesse, pshelar, azhou, ben, stephen, jeffrey.t.kirsher,
vyasevic, xiyou.wangcong, john.r.fastabend, edumazet, jhs,
sfeldma, f.fainelli, roopa, linville, jasowang, ebiederm,
nicolas.dichtel, ryazanov.s.a, buytenh, aviadr, nbd,
alexei.starovoitov, Neil.Jerram, ronye, simon.horman,
alexander.h.duyck, john.ronciak, mleitner, shrijeet
In-Reply-To: <20141125151811.GF1971@nanopsycho.orion>
On 11/25/2014 07:18 AM, Jiri Pirko wrote:
> Tue, Nov 25, 2014 at 04:13:12PM CET, gospo@cumulusnetworks.com wrote:
>> On Tue, Nov 25, 2014 at 11:28:33AM +0100, Jiri Pirko wrote:
>>> Do the work of parsing NDA_VLAN directly in rtnetlink code, pass simple
>>> u16 vid to drivers from there.
>>>
>>> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
>>
>> Structurally this looks fine, just a misspelling noted below.
>>
>> Acked-by: Andy Gospodarek <gospo@cumulusnetworks.com>
>>
If your going to spin this, should we return an error from
ndo_dflt_fdb_add() when we have a non-zero vid? The dflt
handler uses the dev_(mc|uc)_add_excl routines which will
not consume vids.
If you want to address this with a follow up patch I'm OK
with that. Go ahead and add my ack,
Acked-by: John Fastabend <john.r.fastabend@intel.com>
--
John Fastabend Intel Corporation
^ permalink raw reply
* Fw: [Bug 88871] New: SO_BINDTODEVICE set sock's sk_bound_dev_if ,but interface's index can chang where interface down and up
From: Stephen Hemminger @ 2014-11-25 15:43 UTC (permalink / raw)
To: netdev
This is not really a bug.
Begin forwarded message:
Date: Mon, 24 Nov 2014 22:50:49 -0800
From: "bugzilla-daemon@bugzilla.kernel.org" <bugzilla-daemon@bugzilla.kernel.org>
To: "stephen@networkplumber.org" <stephen@networkplumber.org>
Subject: [Bug 88871] New: SO_BINDTODEVICE set sock's sk_bound_dev_if ,but interface's index can chang where interface down and up
https://bugzilla.kernel.org/show_bug.cgi?id=88871
Bug ID: 88871
Summary: SO_BINDTODEVICE set sock's sk_bound_dev_if ,but
interface's index can chang where interface down and
up
Product: Networking
Version: 2.5
Kernel Version: 3.4
Hardware: All
OS: Linux
Tree: Mainline
Status: NEW
Severity: high
Priority: P1
Component: Other
Assignee: shemminger@linux-foundation.org
Reporter: 10142904@qq.com
Regression: No
call setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, iface_brlan, iface_len + 1),
the sock's sk_bound_dev_if be set to iface_brlan's index, when i pull out other
cab and plug in, the br-lan's index can changed, the tcp packet to the socket
be rest, because the orignal sk_bound_dev_if not match current br-lan's index
--
You are receiving this mail because:
You are the assignee for the bug.
^ permalink raw reply
* [PATCH net] tcp: fix possible NULL dereference in tcp_vX_send_reset()
From: Eric Dumazet @ 2014-11-25 15:40 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Daniel Borkmann, Jaša Bartelj
From: Eric Dumazet <edumazet@google.com>
After commit ca777eff51f7 ("tcp: remove dst refcount false sharing for
prequeue mode") we have to relax check against skb dst in
tcp_v[46]_send_reset() if prequeue dropped the dst.
If a socket is provided, a full lookup was done to find this socket,
so the dst test can be skipped.
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=88191
Reported-by: Jaša Bartelj <jasa.bartelj@gmail.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: Daniel Borkmann <dborkman@redhat.com>
Fixes: ca777eff51f7 ("tcp: remove dst refcount false sharing for prequeue mode")
---
net/ipv4/tcp_ipv4.c | 5 ++++-
net/ipv6/tcp_ipv6.c | 5 ++++-
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 9c7d7621466b..147be2024290 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -598,7 +598,10 @@ static void tcp_v4_send_reset(struct sock *sk, struct sk_buff *skb)
if (th->rst)
return;
- if (skb_rtable(skb)->rt_type != RTN_LOCAL)
+ /* If sk not NULL, it means we did a successful lookup and incoming
+ * route had to be correct. prequeue might have dropped our dst.
+ */
+ if (!sk && skb_rtable(skb)->rt_type != RTN_LOCAL)
return;
/* Swap the send and the receive. */
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index ace29b60813c..dc495ae2ead0 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -903,7 +903,10 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
if (th->rst)
return;
- if (!ipv6_unicast_destination(skb))
+ /* If sk not NULL, it means we did a successful lookup and incoming
+ * route had to be correct. prequeue might have dropped our dst.
+ */
+ if (!sk && !ipv6_unicast_destination(skb))
return;
#ifdef CONFIG_TCP_MD5SIG
^ permalink raw reply related
* Re: [patch net-next v3 02/17] net: make vid as a parameter for ndo_fdb_add/ndo_fdb_del
From: Jamal Hadi Salim @ 2014-11-25 15:38 UTC (permalink / raw)
To: Jiri Pirko, netdev
Cc: davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse, pshelar,
azhou, ben, stephen, jeffrey.t.kirsher, vyasevic, xiyou.wangcong,
john.r.fastabend, edumazet, sfeldma, f.fainelli, roopa, linville,
jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a, buytenh,
aviadr, nbd, alexei.starovoitov, Neil.Jerram, ronye, simon.horman,
alexander.h.duyck, john.ronciak, mleitner, shrijeet, gospo, bcrl
In-Reply-To: <1416911328-10979-3-git-send-email-jiri@resnulli.us>
On 11/25/14 05:28, Jiri Pirko wrote:
> Do the work of parsing NDA_VLAN directly in rtnetlink code, pass simple
> u16 vid to drivers from there.
>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
I know this maintains status quo of what is already in the kernel.
But we need to take care of policy (pass it from user space) which
dictates how to proceed on failure. Three possible options:
1) If something fails just continue with the rest of the transaction.
Return success if at least one thing succeeds.
2) If something fails stop transaction and return some partial success code
3) If something fails undo everything that has been done and return failure.
So two bits from somewhere would be useful to send from userspace->kernel
> +static int fbd_vid_parse(struct nlattr *vlan_attr, u16 *p_vid)
typo fbd_vid_parse -> fdb_vid_parse
cheers,
jamal
^ permalink raw reply
* Re: [PATCH] net: team: expose sysfs attributes for each team option
From: Jiri Pirko @ 2014-11-25 15:37 UTC (permalink / raw)
To: Hamad Kadmany; +Cc: netdev
In-Reply-To: <20141119124043.GC1926@nanopsycho.orion>
Wed, Nov 19, 2014 at 01:40:43PM CET, jiri@resnulli.us wrote:
>Wed, Nov 19, 2014 at 01:28:19PM CET, hkadmany@codeaurora.org wrote:
>>On Mon, November 17, 2014 1:02 pm, Jiri Pirko wrote:
>>>
>>> Nak.
>>>
>>> I don't like this patch. The plan for team was keep things simple and to
>>> have single userspace api using netlink, as that is the correct way to
>>> deal with things. Sysfs for this use-case is not. Please, use netlink api.
>>
>>Using team driver requires using libnl3. In Android based platforms, libnl3 is not supported, and libnl3 license poses constraints in Android's user-space.
>>
>>This is the reason for the this change, to have at least the team options exposed through sysfs.
>
>No, that is certainly not the reason. If libnl3 does not suit you, use a
>different lib. It is in my opinion unacceptaptable to work around
>certain licence issues by adding parallel sysfs api (not to mention that
>sysfs is totally unsuitable for that).
>
>You should use existing Netlink API. That's it.
Also, using Netlink API, you get all the events to your userspace
daemon. Sysfs is just not suitable for that.
>
>>
>>
>>>
>>>>
>>>>Signed-off-by: Hamad Kadmany <hkadmany@codeaurora.org>
>>>>---
>>>> drivers/net/team/team.c | 282 ++++++++++++++++++++++++++++++++++++++++++++++--
>>>> include/linux/if_team.h | 3 +
>>>> 2 files changed, 278 insertions(+), 7 deletions(-)
>>>>
>>>>diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
>>>>index 1222229..afd2f8f 100644
>>>>--- a/drivers/net/team/team.c
>>>>+++ b/drivers/net/team/team.c
>>>>@@ -110,8 +110,198 @@ struct team_option_inst { /* One for each option instance */
>>>> struct team_option_inst_info info;
>>>> bool changed;
>>>> bool removed;
>>>>+ bool dev_attr_file_exist;
>>>>+ struct device_attribute dev_attr; /* corresponding sysfs attribute */
>>>> };
>>>>
>>>>+static struct attribute *team_sysfs_attrs[] = {
>>>>+ NULL,
>>>>+};
>>>>+
>>>>+static struct attribute_group team_sysfs_attr_group = {
>>>>+ .attrs = team_sysfs_attrs,
>>>>+};
>>>>+
>>>>+/* Device attributes (sysfs) */
>>>>+
>>>>+static ssize_t show_attribute(struct device *dev,
>>>>+ struct device_attribute *attr,
>>>>+ char *buf)
>>>>+{
>>>>+ struct team *team = dev_get_drvdata(dev);
>>>>+ struct team_option_inst *opt_inst;
>>>>+ ssize_t ret;
>>>>+ struct team_option *option;
>>>>+ struct team_gsetter_ctx ctx;
>>>>+
>>>>+ if (mutex_lock_interruptible(&team->lock))
>>>>+ return -ERESTARTSYS;
>>>>+
>>>>+ opt_inst = container_of(attr, struct team_option_inst, dev_attr);
>>>>+ option = opt_inst->option;
>>>>+ if (!option->getter) {
>>>>+ ret = -EOPNOTSUPP;
>>>>+ netdev_err(team->dev,
>>>>+ "Option %s is write only\n", attr->attr.name);
>>>>+ goto exit;
>>>>+ }
>>>>+
>>>>+ ctx.info = &opt_inst->info;
>>>>+ /* let the option getter do its job */
>>>>+ ret = option->getter(team, &ctx);
>>>>+ if (ret)
>>>>+ goto exit;
>>>>+
>>>>+ /* translate option's output into sysfs output */
>>>>+ switch (option->type) {
>>>>+ case TEAM_OPTION_TYPE_U32:
>>>>+ ret = scnprintf(buf, PAGE_SIZE, "%u\n", ctx.data.u32_val);
>>>>+ break;
>>>>+ case TEAM_OPTION_TYPE_STRING:
>>>>+ ret = scnprintf(buf, PAGE_SIZE, "%s\n", ctx.data.str_val);
>>>>+ break;
>>>>+ case TEAM_OPTION_TYPE_BINARY:
>>>>+ if (ctx.data.bin_val.len > PAGE_SIZE) {
>>>>+ netdev_err(team->dev,
>>>>+ "Option output is too long (%d)\n",
>>>>+ ctx.data.bin_val.len);
>>>>+ break;
>>>>+ }
>>>>+
>>>>+ memcpy(buf, ctx.data.bin_val.ptr, ctx.data.bin_val.len);
>>>>+ ret = ctx.data.bin_val.len;
>>>>+ break;
>>>>+ case TEAM_OPTION_TYPE_BOOL:
>>>>+ ret = scnprintf(buf, PAGE_SIZE, "%d\n", ctx.data.bool_val);
>>>>+ break;
>>>>+ case TEAM_OPTION_TYPE_S32:
>>>>+ ret = scnprintf(buf, PAGE_SIZE, "%d\n", ctx.data.s32_val);
>>>>+ break;
>>>>+ default:
>>>>+ BUG();
>>>>+ }
>>>>+
>>>>+exit:
>>>>+ mutex_unlock(&team->lock);
>>>>+
>>>>+ return ret;
>>>>+}
>>>>+
>>>>+static int team_nl_send_event_options_get(struct team *team,
>>>>+ struct list_head *sel_opt_inst_list);
>>>>+
>>>>+static ssize_t set_attribute(struct device *dev,
>>>>+ struct device_attribute *attr,
>>>>+ const char *buf, size_t count)
>>>>+{
>>>>+ struct team_option_inst *opt_inst;
>>>>+ struct team *team = dev_get_drvdata(dev);
>>>>+ int err = 0;
>>>>+ struct team_option *option = NULL;
>>>>+ struct team_gsetter_ctx ctx;
>>>>+
>>>>+ LIST_HEAD(opt_inst_list);
>>>>+
>>>>+ if (mutex_lock_interruptible(&team->lock))
>>>>+ return -ERESTARTSYS;
>>>>+
>>>>+ opt_inst = container_of(attr, struct team_option_inst, dev_attr);
>>>>+ option = opt_inst->option;
>>>>+ if (!option->setter) {
>>>>+ netdev_err(team->dev,
>>>>+ "Option %s is read only\n", attr->attr.name);
>>>>+ err = -EOPNOTSUPP;
>>>>+ goto exit;
>>>>+ }
>>>>+
>>>>+ ctx.info = &opt_inst->info;
>>>>+
>>>>+ /* translate sysfs input into option's input */
>>>>+ switch (option->type) {
>>>>+ case TEAM_OPTION_TYPE_U32:
>>>>+ err = kstrtoint(buf, 0, &ctx.data.u32_val);
>>>>+ break;
>>>>+ case TEAM_OPTION_TYPE_STRING:
>>>>+ if (count > TEAM_STRING_MAX_LEN) {
>>>>+ netdev_err(team->dev,
>>>>+ "Input buffer too long (%zu)\n", count);
>>>>+ err = -EINVAL;
>>>>+ break;
>>>>+ }
>>>>+ ctx.data.str_val = buf;
>>>>+ break;
>>>>+ case TEAM_OPTION_TYPE_BINARY:
>>>>+ ctx.data.bin_val.len = count;
>>>>+ ctx.data.bin_val.ptr = buf;
>>>>+ break;
>>>>+ case TEAM_OPTION_TYPE_BOOL:
>>>>+ err = strtobool(buf, &ctx.data.bool_val);
>>>>+ break;
>>>>+ case TEAM_OPTION_TYPE_S32:
>>>>+ err = kstrtoint(buf, 0, &ctx.data.s32_val);
>>>>+ break;
>>>>+ default:
>>>>+ BUG();
>>>>+ }
>>>>+
>>>>+ if (err) {
>>>>+ netdev_err(team->dev, "Failed to translate input buffer\n");
>>>>+ goto exit;
>>>>+ }
>>>>+
>>>>+ /* let the option setter do its job */
>>>>+ err = option->setter(team, &ctx);
>>>>+ if (err)
>>>>+ goto exit;
>>>>+
>>>>+ /* propagate option changed event */
>>>>+ opt_inst->changed = true;
>>>>+ list_add(&opt_inst->tmp_list, &opt_inst_list);
>>>>+ err = team_nl_send_event_options_get(team, &opt_inst_list);
>>>>+ if (err == -ESRCH) /* no listeners, not a real error */
>>>>+ err = 0;
>>>>+
>>>>+exit:
>>>>+ mutex_unlock(&team->lock);
>>>>+
>>>>+ if (!err)
>>>>+ err = count;
>>>>+ return err;
>>>>+}
>>>>+
>>>>+/* create sysfs attribute for each option that is being registered */
>>>>+static int __team_option_add_sysfs_attr(struct team *team,
>>>>+ struct team_option_inst *opt_inst,
>>>>+ bool create_sysfs_file)
>>>>+{
>>>>+ int err = 0;
>>>>+ struct device_attribute *new_dev_attr = &opt_inst->dev_attr;
>>>>+
>>>>+ new_dev_attr->attr.name = opt_inst->option->name;
>>>>+ new_dev_attr->attr.mode = S_IRUGO | S_IWUSR;
>>>>+ new_dev_attr->show = show_attribute;
>>>>+ new_dev_attr->store = set_attribute;
>>>>+
>>>>+ if (create_sysfs_file) {
>>>>+ err = sysfs_create_file(&team->dev->dev.kobj,
>>>>+ &new_dev_attr->attr);
>>>>+ if (err)
>>>>+ netdev_err(team->dev,
>>>>+ "Failed to create sysfs attribute %s\n",
>>>>+ new_dev_attr->attr.name);
>>>>+ }
>>>>+
>>>>+ return err;
>>>>+}
>>>>+
>>>>+static void __team_option_del_sysfs_attr(struct team *team,
>>>>+ struct team_option_inst *opt_inst)
>>>>+{
>>>>+ if (opt_inst->dev_attr_file_exist)
>>>>+ sysfs_remove_file(&team->dev->dev.kobj,
>>>>+ &opt_inst->dev_attr.attr);
>>>>+}
>>>>+
>>>> static struct team_option *__team_find_option(struct team *team,
>>>> const char *opt_name)
>>>> {
>>>>@@ -124,8 +314,10 @@ static struct team_option *__team_find_option(struct team *team,
>>>> return NULL;
>>>> }
>>>>
>>>>-static void __team_option_inst_del(struct team_option_inst *opt_inst)
>>>>+static void __team_option_inst_del(struct team *team,
>>>>+ struct team_option_inst *opt_inst)
>>>> {
>>>>+ __team_option_del_sysfs_attr(team, opt_inst);
>>>> list_del(&opt_inst->list);
>>>> kfree(opt_inst);
>>>> }
>>>>@@ -137,7 +329,7 @@ static void __team_option_inst_del_option(struct team *team,
>>>>
>>>> list_for_each_entry_safe(opt_inst, tmp, &team->option_inst_list, list) {
>>>> if (opt_inst->option == option)
>>>>- __team_option_inst_del(opt_inst);
>>>>+ __team_option_inst_del(team, opt_inst);
>>>> }
>>>> }
>>>>
>>>>@@ -162,6 +354,7 @@ static int __team_option_inst_add(struct team *team, struct team_option *option,
>>>> opt_inst->info.array_index = i;
>>>> opt_inst->changed = true;
>>>> opt_inst->removed = false;
>>>>+ opt_inst->dev_attr_file_exist = false;
>>>> list_add_tail(&opt_inst->list, &team->option_inst_list);
>>>> if (option->init) {
>>>> err = option->init(team, &opt_inst->info);
>>>>@@ -170,6 +363,20 @@ static int __team_option_inst_add(struct team *team, struct team_option *option,
>>>> }
>>>>
>>>> }
>>>>+
>>>>+ /* add sysfs attribute. per-port and array options are skipped */
>>>>+ if (!option->per_port && !option->array_size) {
>>>>+ /* create the sysfs file only if our state allows it */
>>>>+ bool create_sysfs_file = device_is_registered(&team->dev->dev);
>>>>+
>>>>+ err = __team_option_add_sysfs_attr(team, opt_inst,
>>>>+ create_sysfs_file);
>>>>+ if (err)
>>>>+ return err;
>>>>+
>>>>+ opt_inst->dev_attr_file_exist = true;
>>>>+ }
>>>>+
>>>> return 0;
>>>> }
>>>>
>>>>@@ -218,7 +425,7 @@ static void __team_option_inst_del_port(struct team *team,
>>>> list_for_each_entry_safe(opt_inst, tmp, &team->option_inst_list, list) {
>>>> if (opt_inst->option->per_port &&
>>>> opt_inst->info.port == port)
>>>>- __team_option_inst_del(opt_inst);
>>>>+ __team_option_inst_del(team, opt_inst);
>>>> }
>>>> }
>>>>
>>>>@@ -337,6 +544,51 @@ static void __team_options_unregister(struct team *team,
>>>>
>>>> static void __team_options_change_check(struct team *team);
>>>>
>>>>+static void team_attr_grp_free(struct team *team)
>>>>+{
>>>>+ kfree(team->attr_grp.attrs);
>>>>+}
>>>>+
>>>>+/* allocate attribute group for creating sysfs for team's own options */
>>>>+static int team_attr_grp_alloc(struct team *team)
>>>>+{
>>>>+ struct attribute **attributes;
>>>>+ struct team_option_inst *opt_inst;
>>>>+ int num_attr = 0;
>>>>+ struct team_option *option;
>>>>+
>>>>+ list_for_each_entry(opt_inst, &team->option_inst_list, list) {
>>>>+ option = opt_inst->option;
>>>>+ /* per-port and array options currently not supported as
>>>>+ * sysfs attributes
>>>>+ */
>>>>+ if (option->per_port || option->array_size)
>>>>+ continue;
>>>>+
>>>>+ num_attr++;
>>>>+ }
>>>>+
>>>>+ /* +1 for having NULL as last item in the array */
>>>>+ attributes = kzalloc((num_attr + 1) * sizeof(*attributes), GFP_KERNEL);
>>>>+ if (!attributes)
>>>>+ return -ENOMEM;
>>>>+ team->attr_grp.attrs = attributes;
>>>>+
>>>>+ num_attr = 0;
>>>>+ list_for_each_entry(opt_inst, &team->option_inst_list, list) {
>>>>+ option = opt_inst->option;
>>>>+ /* per-port and array options currently not supported as
>>>>+ * sysfs attributes
>>>>+ */
>>>>+ if (option->per_port || option->array_size)
>>>>+ continue;
>>>>+
>>>>+ attributes[num_attr++] = &opt_inst->dev_attr.attr;
>>>>+ }
>>>>+
>>>>+ return 0;
>>>>+}
>>>>+
>>>> int team_options_register(struct team *team,
>>>> const struct team_option *option,
>>>> size_t option_count)
>>>>@@ -1380,15 +1632,28 @@ static int team_init(struct net_device *dev)
>>>>
>>>> INIT_LIST_HEAD(&team->option_list);
>>>> INIT_LIST_HEAD(&team->option_inst_list);
>>>>- err = team_options_register(team, team_options, ARRAY_SIZE(team_options));
>>>>+
>>>>+ err = team_options_register(team, team_options,
>>>>+ ARRAY_SIZE(team_options));
>>>> if (err)
>>>> goto err_options_register;
>>>> netif_carrier_off(dev);
>>>>
>>>> team_set_lockdep_class(dev);
>>>>
>>>>+ /* store team context, to be used by Device attributes getter/setter */
>>>>+ dev_set_drvdata(&dev->dev, team);
>>>>+
>>>>+ /* allocate and register sysfs attributes for team's own options */
>>>>+ err = team_attr_grp_alloc(team);
>>>>+ if (err)
>>>>+ goto err_grp_alloc;
>>>>+ dev->sysfs_groups[0] = &team->attr_grp;
>>>>+
>>>> return 0;
>>>>
>>>>+err_grp_alloc:
>>>>+ team_options_unregister(team, team_options, ARRAY_SIZE(team_options));
>>>> err_options_register:
>>>> team_queue_override_fini(team);
>>>> err_team_queue_override_init:
>>>>@@ -1407,9 +1672,15 @@ static void team_uninit(struct net_device *dev)
>>>> list_for_each_entry_safe(port, tmp, &team->port_list, list)
>>>> team_port_del(team, port->dev);
>>>>
>>>>+ sysfs_remove_group(&team->dev->dev.kobj, &team->attr_grp);
>>>>+ team_attr_grp_free(team);
>>>>+ /* set to dummy group to avoid double free by core */
>>>>+ dev->sysfs_groups[0] = &team_sysfs_attr_group;
>>>>+
>>>> __team_change_mode(team, NULL); /* cleanup */
>>>> __team_options_unregister(team, team_options, ARRAY_SIZE(team_options));
>>>> team_queue_override_fini(team);
>>>>+
>>>> mutex_unlock(&team->lock);
>>>> }
>>>>
>>>>@@ -2194,9 +2465,6 @@ static int team_nl_cmd_options_get(struct sk_buff *skb, struct genl_info *info)
>>>> return err;
>>>> }
>>>>
>>>>-static int team_nl_send_event_options_get(struct team *team,
>>>>- struct list_head *sel_opt_inst_list);
>>>>-
>>>> static int team_nl_cmd_options_set(struct sk_buff *skb, struct genl_info *info)
>>>> {
>>>> struct team *team;
>>>>diff --git a/include/linux/if_team.h b/include/linux/if_team.h
>>>>index 25b8b15..2e9fb2a 100644
>>>>--- a/include/linux/if_team.h
>>>>+++ b/include/linux/if_team.h
>>>>@@ -188,6 +188,9 @@ struct team {
>>>> struct list_head option_list;
>>>> struct list_head option_inst_list; /* list of option instances */
>>>>
>>>>+ /* attribute group for registering team's own options at init */
>>>>+ struct attribute_group attr_grp;
>>>>+
>>>> const struct team_mode *mode;
>>>> struct team_mode_ops ops;
>>>> bool user_carrier_enabled;
>>>>--
>>>>1.8.5.2
>>>>--
>>>>Qualcomm Israel, on behalf of Qualcomm Innovation Center, Inc.
>>>>The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
>>>>a Linux Foundation Collaborative Project
>>>>
>>>
>>
>>
^ permalink raw reply
* Re: [patch net-next v3 06/17] net-sysfs: expose physical switch id for particular device
From: Andy Gospodarek @ 2014-11-25 15:28 UTC (permalink / raw)
To: Jiri Pirko
Cc: netdev, davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse,
pshelar, azhou, ben, stephen, jeffrey.t.kirsher, vyasevic,
xiyou.wangcong, john.r.fastabend, edumazet, jhs, sfeldma,
f.fainelli, roopa, linville, jasowang, ebiederm, nicolas.dichtel,
ryazanov.s.a, buytenh, aviadr, nbd, alexei.starovoitov,
Neil.Jerram, ronye, simon.horman, alexander.h.duyck, john.ronciak,
mleitner, shrijeet, bcrl
In-Reply-To: <1416911328-10979-7-git-send-email-jiri@resnulli.us>
On Tue, Nov 25, 2014 at 11:28:37AM +0100, Jiri Pirko wrote:
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
> Reviewed-by: Thomas Graf <tgraf@suug.ch>
> Acked-by: John Fastabend <john.r.fastabend@intel.com>
Acked-by: Andy Gospodarek <gospo@cumulusnetworks.com>
> ---
> v2->v3:
> -changed "sw" string to "switch" to avoid confusion
> v1->v2:
> -no change
> ---
> net/core/net-sysfs.c | 24 ++++++++++++++++++++++++
> 1 file changed, 24 insertions(+)
>
> diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
> index 26c46f4..9993412 100644
> --- a/net/core/net-sysfs.c
> +++ b/net/core/net-sysfs.c
> @@ -12,6 +12,7 @@
> #include <linux/capability.h>
> #include <linux/kernel.h>
> #include <linux/netdevice.h>
> +#include <net/switchdev.h>
> #include <linux/if_arp.h>
> #include <linux/slab.h>
> #include <linux/nsproxy.h>
> @@ -416,6 +417,28 @@ static ssize_t phys_port_id_show(struct device *dev,
> }
> static DEVICE_ATTR_RO(phys_port_id);
>
> +static ssize_t phys_switch_id_show(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + struct net_device *netdev = to_net_dev(dev);
> + ssize_t ret = -EINVAL;
> +
> + if (!rtnl_trylock())
> + return restart_syscall();
> +
> + if (dev_isalive(netdev)) {
> + struct netdev_phys_item_id ppid;
> +
> + ret = netdev_switch_parent_id_get(netdev, &ppid);
> + if (!ret)
> + ret = sprintf(buf, "%*phN\n", ppid.id_len, ppid.id);
> + }
> + rtnl_unlock();
> +
> + return ret;
> +}
> +static DEVICE_ATTR_RO(phys_switch_id);
> +
> static struct attribute *net_class_attrs[] = {
> &dev_attr_netdev_group.attr,
> &dev_attr_type.attr,
> @@ -441,6 +464,7 @@ static struct attribute *net_class_attrs[] = {
> &dev_attr_tx_queue_len.attr,
> &dev_attr_gro_flush_timeout.attr,
> &dev_attr_phys_port_id.attr,
> + &dev_attr_phys_switch_id.attr,
> NULL,
> };
> ATTRIBUTE_GROUPS(net_class);
> --
> 1.9.3
>
^ permalink raw reply
* Re: [patch net-next v3 01/17] bridge: rename fdb_*_hw to fdb_*_hw_addr to avoid confusion
From: Jamal Hadi Salim @ 2014-11-25 15:26 UTC (permalink / raw)
To: Jiri Pirko, netdev
Cc: davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse, pshelar,
azhou, ben, stephen, jeffrey.t.kirsher, vyasevic, xiyou.wangcong,
john.r.fastabend, edumazet, sfeldma, f.fainelli, roopa, linville,
jasowang, ebiederm, nicolas.dichtel, ryazanov.s.a, buytenh,
aviadr, nbd, alexei.starovoitov, Neil.Jerram, ronye, simon.horman,
alexander.h.duyck, john.ronciak, mleitner, shrijeet, gospo, bcrl
In-Reply-To: <1416911328-10979-2-git-send-email-jiri@resnulli.us>
On 11/25/14 05:28, Jiri Pirko wrote:
> The current name might seem that this actually offloads the fdb entry to
> hw. So rename it to clearly present that this for hardware address
> addition/removal.
>
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
cheers,
jamal
^ permalink raw reply
* Re: [patch net-next v3 02/17] net: make vid as a parameter for ndo_fdb_add/ndo_fdb_del
From: Jiri Pirko @ 2014-11-25 15:18 UTC (permalink / raw)
To: Andy Gospodarek
Cc: netdev, davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse,
pshelar, azhou, ben, stephen, jeffrey.t.kirsher, vyasevic,
xiyou.wangcong, john.r.fastabend, edumazet, jhs, sfeldma,
f.fainelli, roopa, linville, jasowang, ebiederm, nicolas.dichtel,
ryazanov.s.a, buytenh, aviadr, nbd, alexei.starovoitov,
Neil.Jerram, ronye, simon.horman, alexander.h.duyck, john.ronciak,
mleitner, shrijeet, bcrl
In-Reply-To: <20141125151312.GC27416@gospo.rtplab.test>
Tue, Nov 25, 2014 at 04:13:12PM CET, gospo@cumulusnetworks.com wrote:
>On Tue, Nov 25, 2014 at 11:28:33AM +0100, Jiri Pirko wrote:
>> Do the work of parsing NDA_VLAN directly in rtnetlink code, pass simple
>> u16 vid to drivers from there.
>>
>> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
>
>Structurally this looks fine, just a misspelling noted below.
>
>Acked-by: Andy Gospodarek <gospo@cumulusnetworks.com>
>
>> ---
>> new in v3
>> ---
>> drivers/net/ethernet/intel/i40e/i40e_main.c | 2 +-
>> drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 4 +-
>> drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 9 +++--
>> drivers/net/macvlan.c | 4 +-
>> drivers/net/vxlan.c | 4 +-
>> include/linux/netdevice.h | 8 ++--
>> include/linux/rtnetlink.h | 6 ++-
>> net/bridge/br_fdb.c | 39 ++----------------
>> net/bridge/br_private.h | 4 +-
>> net/core/rtnetlink.c | 50 ++++++++++++++++++++----
>> 10 files changed, 70 insertions(+), 60 deletions(-)
>>
>[...]
>> diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
>> index a688268..f2a4b38 100644
>> --- a/net/core/rtnetlink.c
>> +++ b/net/core/rtnetlink.c
>> @@ -36,6 +36,7 @@
>> #include <linux/mutex.h>
>> #include <linux/if_addr.h>
>> #include <linux/if_bridge.h>
>> +#include <linux/if_vlan.h>
>> #include <linux/pci.h>
>> #include <linux/etherdevice.h>
>>
>> @@ -2312,7 +2313,7 @@ errout:
>> int ndo_dflt_fdb_add(struct ndmsg *ndm,
>> struct nlattr *tb[],
>> struct net_device *dev,
>> - const unsigned char *addr,
>> + const unsigned char *addr, u16 vid,
>> u16 flags)
>> {
>> int err = -EINVAL;
>> @@ -2338,6 +2339,28 @@ int ndo_dflt_fdb_add(struct ndmsg *ndm,
>> }
>> EXPORT_SYMBOL(ndo_dflt_fdb_add);
>>
>> +static int fbd_vid_parse(struct nlattr *vlan_attr, u16 *p_vid)
>I presume this is a misspelling?
Darn. Thanks. Will fix this.
>
>[...]
>> @@ -2370,6 +2394,10 @@ static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh)
>>
>> addr = nla_data(tb[NDA_LLADDR]);
>>
>> + err = fbd_vid_parse(tb[NDA_VLAN], &vid);
>Same here....
>
>> + if (err)
>> + return err;
>> +
>> err = -EOPNOTSUPP;
>>
>> /* Support fdb on master device the net/bridge default case */
>
>[...]
>> @@ -2465,6 +2496,10 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh)
>>
>> addr = nla_data(tb[NDA_LLADDR]);
>>
>> + err = fbd_vid_parse(tb[NDA_VLAN], &vid);
>...and here.
>
>> + if (err)
>> + return err;
>> +
>> err = -EOPNOTSUPP;
>>
>> /* Support fdb on master device the net/bridge default case */
>> @@ -2474,7 +2509,7 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh)
>> const struct net_device_ops *ops = br_dev->netdev_ops;
>>
>> if (ops->ndo_fdb_del)
>> - err = ops->ndo_fdb_del(ndm, tb, dev, addr);
>> + err = ops->ndo_fdb_del(ndm, tb, dev, addr, vid);
>>
>> if (err)
>> goto out;
>> @@ -2485,9 +2520,10 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh)
>> /* Embedded bridge, macvlan, and any other device support */
>> if (ndm->ndm_flags & NTF_SELF) {
>> if (dev->netdev_ops->ndo_fdb_del)
>> - err = dev->netdev_ops->ndo_fdb_del(ndm, tb, dev, addr);
>> + err = dev->netdev_ops->ndo_fdb_del(ndm, tb, dev, addr,
>> + vid);
>> else
>> - err = ndo_dflt_fdb_del(ndm, tb, dev, addr);
>> + err = ndo_dflt_fdb_del(ndm, tb, dev, addr, vid);
>>
>> if (!err) {
>> rtnl_fdb_notify(dev, addr, RTM_DELNEIGH);
>> --
>> 1.9.3
>>
^ permalink raw reply
* Re: [patch net-next v3 05/17] rtnl: expose physical switch id for particular device
From: Andy Gospodarek @ 2014-11-25 15:16 UTC (permalink / raw)
To: Jiri Pirko
Cc: netdev, davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse,
pshelar, azhou, ben, stephen, jeffrey.t.kirsher, vyasevic,
xiyou.wangcong, john.r.fastabend, edumazet, jhs, sfeldma,
f.fainelli, roopa, linville, jasowang, ebiederm, nicolas.dichtel,
ryazanov.s.a, buytenh, aviadr, nbd, alexei.starovoitov,
Neil.Jerram, ronye, simon.horman, alexander.h.duyck, john.ronciak,
mleitner, shrijeet, bcrl
In-Reply-To: <1416911328-10979-6-git-send-email-jiri@resnulli.us>
On Tue, Nov 25, 2014 at 11:28:36AM +0100, Jiri Pirko wrote:
> The netdevice represents a port in a switch, it will expose
> IFLA_PHYS_SWITCH_ID value via rtnl. Two netdevices with the same value
> belong to one physical switch.
>
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
> Reviewed-by: Thomas Graf <tgraf@suug.ch>
> Acked-by: John Fastabend <john.r.fastabend@intel.com>
Acked-by: Andy Gospodarek <gospo@cumulusnetworks.com>
> ---
> v2->v3:
> -changed "sw" string to "switch" to avoid confusion
> v1->v2:
> -no change
> ---
> include/uapi/linux/if_link.h | 1 +
> net/core/rtnetlink.c | 26 +++++++++++++++++++++++++-
> 2 files changed, 26 insertions(+), 1 deletion(-)
>
> diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
> index 7072d83..4163753 100644
> --- a/include/uapi/linux/if_link.h
> +++ b/include/uapi/linux/if_link.h
> @@ -145,6 +145,7 @@ enum {
> IFLA_CARRIER,
> IFLA_PHYS_PORT_ID,
> IFLA_CARRIER_CHANGES,
> + IFLA_PHYS_SWITCH_ID,
> __IFLA_MAX
> };
>
> diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
> index 0fb3a68..bd5e783 100644
> --- a/net/core/rtnetlink.c
> +++ b/net/core/rtnetlink.c
> @@ -44,6 +44,7 @@
>
> #include <linux/inet.h>
> #include <linux/netdevice.h>
> +#include <net/switchdev.h>
> #include <net/ip.h>
> #include <net/protocol.h>
> #include <net/arp.h>
> @@ -869,7 +870,8 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev,
> + rtnl_port_size(dev, ext_filter_mask) /* IFLA_VF_PORTS + IFLA_PORT_SELF */
> + rtnl_link_get_size(dev) /* IFLA_LINKINFO */
> + rtnl_link_get_af_size(dev) /* IFLA_AF_SPEC */
> - + nla_total_size(MAX_PHYS_ITEM_ID_LEN); /* IFLA_PHYS_PORT_ID */
> + + nla_total_size(MAX_PHYS_ITEM_ID_LEN) /* IFLA_PHYS_PORT_ID */
> + + nla_total_size(MAX_PHYS_ITEM_ID_LEN); /* IFLA_PHYS_SWITCH_ID */
> }
>
> static int rtnl_vf_ports_fill(struct sk_buff *skb, struct net_device *dev)
> @@ -968,6 +970,24 @@ static int rtnl_phys_port_id_fill(struct sk_buff *skb, struct net_device *dev)
> return 0;
> }
>
> +static int rtnl_phys_switch_id_fill(struct sk_buff *skb, struct net_device *dev)
> +{
> + int err;
> + struct netdev_phys_item_id psid;
> +
> + err = netdev_switch_parent_id_get(dev, &psid);
> + if (err) {
> + if (err == -EOPNOTSUPP)
> + return 0;
> + return err;
> + }
> +
> + if (nla_put(skb, IFLA_PHYS_SWITCH_ID, psid.id_len, psid.id))
> + return -EMSGSIZE;
> +
> + return 0;
> +}
> +
> static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
> int type, u32 pid, u32 seq, u32 change,
> unsigned int flags, u32 ext_filter_mask)
> @@ -1040,6 +1060,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
> if (rtnl_phys_port_id_fill(skb, dev))
> goto nla_put_failure;
>
> + if (rtnl_phys_switch_id_fill(skb, dev))
> + goto nla_put_failure;
> +
> attr = nla_reserve(skb, IFLA_STATS,
> sizeof(struct rtnl_link_stats));
> if (attr == NULL)
> @@ -1199,6 +1222,7 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
> [IFLA_NUM_RX_QUEUES] = { .type = NLA_U32 },
> [IFLA_PHYS_PORT_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN },
> [IFLA_CARRIER_CHANGES] = { .type = NLA_U32 }, /* ignored */
> + [IFLA_PHYS_SWITCH_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN },
> };
>
> static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
> --
> 1.9.3
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [patch net-next v3 03/17] net: rename netdev_phys_port_id to more generic name
From: Andy Gospodarek @ 2014-11-25 15:15 UTC (permalink / raw)
To: Jiri Pirko
Cc: netdev, davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse,
pshelar, azhou, ben, stephen, jeffrey.t.kirsher, vyasevic,
xiyou.wangcong, john.r.fastabend, edumazet, jhs, sfeldma,
f.fainelli, roopa, linville, jasowang, ebiederm, nicolas.dichtel,
ryazanov.s.a, buytenh, aviadr, nbd, alexei.starovoitov,
Neil.Jerram, ronye, simon.horman, alexander.h.duyck, john.ronciak,
mleitner, shrijeet, bcrl
In-Reply-To: <1416911328-10979-4-git-send-email-jiri@resnulli.us>
On Tue, Nov 25, 2014 at 11:28:34AM +0100, Jiri Pirko wrote:
> So this can be reused for identification of other "items" as well.
>
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
> Reviewed-by: Thomas Graf <tgraf@suug.ch>
> Acked-by: John Fastabend <john.r.fastabend@intel.com>
Still seems fine for v3. :-)
Acked-by: Andy Gospodarek <gospo@cumulusnetworks.com>
> ---
> v1->v2->v3:
> -no change
> ---
> drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 2 +-
> drivers/net/ethernet/intel/i40e/i40e_main.c | 2 +-
> drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 2 +-
> drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 2 +-
> include/linux/netdevice.h | 16 ++++++++--------
> net/core/dev.c | 2 +-
> net/core/net-sysfs.c | 2 +-
> net/core/rtnetlink.c | 6 +++---
> 8 files changed, 17 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
> index c4bd025..336ef3c 100644
> --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
> +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
> @@ -12537,7 +12537,7 @@ static int bnx2x_validate_addr(struct net_device *dev)
> }
>
> static int bnx2x_get_phys_port_id(struct net_device *netdev,
> - struct netdev_phys_port_id *ppid)
> + struct netdev_phys_item_id *ppid)
> {
> struct bnx2x *bp = netdev_priv(netdev);
>
> diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
> index 5ed5e40..9ae4270 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_main.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
> @@ -7511,7 +7511,7 @@ static void i40e_del_vxlan_port(struct net_device *netdev,
>
> #endif
> static int i40e_get_phys_port_id(struct net_device *netdev,
> - struct netdev_phys_port_id *ppid)
> + struct netdev_phys_item_id *ppid)
> {
> struct i40e_netdev_priv *np = netdev_priv(netdev);
> struct i40e_pf *pf = np->vsi->back;
> diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> index b7c9978..1597fb0 100644
> --- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> +++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
> @@ -2259,7 +2259,7 @@ static int mlx4_en_set_vf_link_state(struct net_device *dev, int vf, int link_st
>
> #define PORT_ID_BYTE_LEN 8
> static int mlx4_en_get_phys_port_id(struct net_device *dev,
> - struct netdev_phys_port_id *ppid)
> + struct netdev_phys_item_id *ppid)
> {
> struct mlx4_en_priv *priv = netdev_priv(dev);
> struct mlx4_dev *mdev = priv->mdev->dev;
> diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
> index 3227c80..1aa25b1 100644
> --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
> +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
> @@ -461,7 +461,7 @@ static void qlcnic_82xx_cancel_idc_work(struct qlcnic_adapter *adapter)
> }
>
> static int qlcnic_get_phys_port_id(struct net_device *netdev,
> - struct netdev_phys_port_id *ppid)
> + struct netdev_phys_item_id *ppid)
> {
> struct qlcnic_adapter *adapter = netdev_priv(netdev);
> struct qlcnic_hardware_context *ahw = adapter->ahw;
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index fab074e..5b491b3 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -754,13 +754,13 @@ struct netdev_fcoe_hbainfo {
> };
> #endif
>
> -#define MAX_PHYS_PORT_ID_LEN 32
> +#define MAX_PHYS_ITEM_ID_LEN 32
>
> -/* This structure holds a unique identifier to identify the
> - * physical port used by a netdevice.
> +/* This structure holds a unique identifier to identify some
> + * physical item (port for example) used by a netdevice.
> */
> -struct netdev_phys_port_id {
> - unsigned char id[MAX_PHYS_PORT_ID_LEN];
> +struct netdev_phys_item_id {
> + unsigned char id[MAX_PHYS_ITEM_ID_LEN];
> unsigned char id_len;
> };
>
> @@ -976,7 +976,7 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
> * USB_CDC_NOTIFY_NETWORK_CONNECTION) should NOT implement this function.
> *
> * int (*ndo_get_phys_port_id)(struct net_device *dev,
> - * struct netdev_phys_port_id *ppid);
> + * struct netdev_phys_item_id *ppid);
> * Called to get ID of physical port of this device. If driver does
> * not implement this, it is assumed that the hw is not able to have
> * multiple net devices on single physical port.
> @@ -1152,7 +1152,7 @@ struct net_device_ops {
> int (*ndo_change_carrier)(struct net_device *dev,
> bool new_carrier);
> int (*ndo_get_phys_port_id)(struct net_device *dev,
> - struct netdev_phys_port_id *ppid);
> + struct netdev_phys_item_id *ppid);
> void (*ndo_add_vxlan_port)(struct net_device *dev,
> sa_family_t sa_family,
> __be16 port);
> @@ -2866,7 +2866,7 @@ void dev_set_group(struct net_device *, int);
> int dev_set_mac_address(struct net_device *, struct sockaddr *);
> int dev_change_carrier(struct net_device *, bool new_carrier);
> int dev_get_phys_port_id(struct net_device *dev,
> - struct netdev_phys_port_id *ppid);
> + struct netdev_phys_item_id *ppid);
> struct sk_buff *validate_xmit_skb_list(struct sk_buff *skb, struct net_device *dev);
> struct sk_buff *dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
> struct netdev_queue *txq, int *ret);
> diff --git a/net/core/dev.c b/net/core/dev.c
> index ac48362..0814a56 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -5846,7 +5846,7 @@ EXPORT_SYMBOL(dev_change_carrier);
> * Get device physical port ID
> */
> int dev_get_phys_port_id(struct net_device *dev,
> - struct netdev_phys_port_id *ppid)
> + struct netdev_phys_item_id *ppid)
> {
> const struct net_device_ops *ops = dev->netdev_ops;
>
> diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
> index 1a24602..26c46f4 100644
> --- a/net/core/net-sysfs.c
> +++ b/net/core/net-sysfs.c
> @@ -404,7 +404,7 @@ static ssize_t phys_port_id_show(struct device *dev,
> return restart_syscall();
>
> if (dev_isalive(netdev)) {
> - struct netdev_phys_port_id ppid;
> + struct netdev_phys_item_id ppid;
>
> ret = dev_get_phys_port_id(netdev, &ppid);
> if (!ret)
> diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
> index f2a4b38..0fb3a68 100644
> --- a/net/core/rtnetlink.c
> +++ b/net/core/rtnetlink.c
> @@ -869,7 +869,7 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev,
> + rtnl_port_size(dev, ext_filter_mask) /* IFLA_VF_PORTS + IFLA_PORT_SELF */
> + rtnl_link_get_size(dev) /* IFLA_LINKINFO */
> + rtnl_link_get_af_size(dev) /* IFLA_AF_SPEC */
> - + nla_total_size(MAX_PHYS_PORT_ID_LEN); /* IFLA_PHYS_PORT_ID */
> + + nla_total_size(MAX_PHYS_ITEM_ID_LEN); /* IFLA_PHYS_PORT_ID */
> }
>
> static int rtnl_vf_ports_fill(struct sk_buff *skb, struct net_device *dev)
> @@ -953,7 +953,7 @@ static int rtnl_port_fill(struct sk_buff *skb, struct net_device *dev,
> static int rtnl_phys_port_id_fill(struct sk_buff *skb, struct net_device *dev)
> {
> int err;
> - struct netdev_phys_port_id ppid;
> + struct netdev_phys_item_id ppid;
>
> err = dev_get_phys_port_id(dev, &ppid);
> if (err) {
> @@ -1197,7 +1197,7 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
> [IFLA_PROMISCUITY] = { .type = NLA_U32 },
> [IFLA_NUM_TX_QUEUES] = { .type = NLA_U32 },
> [IFLA_NUM_RX_QUEUES] = { .type = NLA_U32 },
> - [IFLA_PHYS_PORT_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_PORT_ID_LEN },
> + [IFLA_PHYS_PORT_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN },
> [IFLA_CARRIER_CHANGES] = { .type = NLA_U32 }, /* ignored */
> };
>
> --
> 1.9.3
>
^ permalink raw reply
* Re: [patch net-next v3 02/17] net: make vid as a parameter for ndo_fdb_add/ndo_fdb_del
From: Andy Gospodarek @ 2014-11-25 15:13 UTC (permalink / raw)
To: Jiri Pirko
Cc: netdev, davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse,
pshelar, azhou, ben, stephen, jeffrey.t.kirsher, vyasevic,
xiyou.wangcong, john.r.fastabend, edumazet, jhs, sfeldma,
f.fainelli, roopa, linville, jasowang, ebiederm, nicolas.dichtel,
ryazanov.s.a, buytenh, aviadr, nbd, alexei.starovoitov,
Neil.Jerram, ronye, simon.horman, alexander.h.duyck, john.ronciak,
mleitner, shrijeet, bcrl
In-Reply-To: <1416911328-10979-3-git-send-email-jiri@resnulli.us>
On Tue, Nov 25, 2014 at 11:28:33AM +0100, Jiri Pirko wrote:
> Do the work of parsing NDA_VLAN directly in rtnetlink code, pass simple
> u16 vid to drivers from there.
>
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Structurally this looks fine, just a misspelling noted below.
Acked-by: Andy Gospodarek <gospo@cumulusnetworks.com>
> ---
> new in v3
> ---
> drivers/net/ethernet/intel/i40e/i40e_main.c | 2 +-
> drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 4 +-
> drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | 9 +++--
> drivers/net/macvlan.c | 4 +-
> drivers/net/vxlan.c | 4 +-
> include/linux/netdevice.h | 8 ++--
> include/linux/rtnetlink.h | 6 ++-
> net/bridge/br_fdb.c | 39 ++----------------
> net/bridge/br_private.h | 4 +-
> net/core/rtnetlink.c | 50 ++++++++++++++++++++----
> 10 files changed, 70 insertions(+), 60 deletions(-)
>
[...]
> diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
> index a688268..f2a4b38 100644
> --- a/net/core/rtnetlink.c
> +++ b/net/core/rtnetlink.c
> @@ -36,6 +36,7 @@
> #include <linux/mutex.h>
> #include <linux/if_addr.h>
> #include <linux/if_bridge.h>
> +#include <linux/if_vlan.h>
> #include <linux/pci.h>
> #include <linux/etherdevice.h>
>
> @@ -2312,7 +2313,7 @@ errout:
> int ndo_dflt_fdb_add(struct ndmsg *ndm,
> struct nlattr *tb[],
> struct net_device *dev,
> - const unsigned char *addr,
> + const unsigned char *addr, u16 vid,
> u16 flags)
> {
> int err = -EINVAL;
> @@ -2338,6 +2339,28 @@ int ndo_dflt_fdb_add(struct ndmsg *ndm,
> }
> EXPORT_SYMBOL(ndo_dflt_fdb_add);
>
> +static int fbd_vid_parse(struct nlattr *vlan_attr, u16 *p_vid)
I presume this is a misspelling?
[...]
> @@ -2370,6 +2394,10 @@ static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh)
>
> addr = nla_data(tb[NDA_LLADDR]);
>
> + err = fbd_vid_parse(tb[NDA_VLAN], &vid);
Same here....
> + if (err)
> + return err;
> +
> err = -EOPNOTSUPP;
>
> /* Support fdb on master device the net/bridge default case */
[...]
> @@ -2465,6 +2496,10 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh)
>
> addr = nla_data(tb[NDA_LLADDR]);
>
> + err = fbd_vid_parse(tb[NDA_VLAN], &vid);
...and here.
> + if (err)
> + return err;
> +
> err = -EOPNOTSUPP;
>
> /* Support fdb on master device the net/bridge default case */
> @@ -2474,7 +2509,7 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh)
> const struct net_device_ops *ops = br_dev->netdev_ops;
>
> if (ops->ndo_fdb_del)
> - err = ops->ndo_fdb_del(ndm, tb, dev, addr);
> + err = ops->ndo_fdb_del(ndm, tb, dev, addr, vid);
>
> if (err)
> goto out;
> @@ -2485,9 +2520,10 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh)
> /* Embedded bridge, macvlan, and any other device support */
> if (ndm->ndm_flags & NTF_SELF) {
> if (dev->netdev_ops->ndo_fdb_del)
> - err = dev->netdev_ops->ndo_fdb_del(ndm, tb, dev, addr);
> + err = dev->netdev_ops->ndo_fdb_del(ndm, tb, dev, addr,
> + vid);
> else
> - err = ndo_dflt_fdb_del(ndm, tb, dev, addr);
> + err = ndo_dflt_fdb_del(ndm, tb, dev, addr, vid);
>
> if (!err) {
> rtnl_fdb_notify(dev, addr, RTM_DELNEIGH);
> --
> 1.9.3
>
^ permalink raw reply
* [PATCH] net: netfilter: Fix undefined reference to nf_nat_redirect_* functions
From: Andreas Ruprecht @ 2014-11-25 15:07 UTC (permalink / raw)
To: Pablo Neira Ayuso
Cc: Patrick McHardy, Jozsef Kadlecsik, David S. Miller,
netfilter-devel, coreteam, netdev, linux-kernel, Andreas Ruprecht
In a configuration with CONFIG_NFT_NAT and
CONFIG_NETFILTER_XT_TARGET_REDIRECT enabled, undefined references to
nf_nat_redirect_ipv{4,6}() can occur, when the corresponding options
CONFIG_NF_NAT_REDIRECT_IPV4 or CONFIG_NF_NAT_REDIRECT_IPV6 are not
enabled.
net/built-in.o: In function `redirect_tg4':
xt_REDIRECT.c:(.text+0x6d001): undefined reference to `nf_nat_redirect_ipv4'
net/built-in.o: In function `redirect_tg6':
xt_REDIRECT.c:(.text+0x6d021): undefined reference to `nf_nat_redirect_ipv6'
This is because the file xt_REDIRECT.c is compiled when
CONFIG_NETFILTER_XT_TARGET_REDIRECT is enabled, which only depends
on CONFIG_NF_NAT. This option is invisible and can only be selected by
other Kconfig options. In this particular case, it is selected by
CONFIG_NFT_NAT.
This patch changes the dependency for CONFIG_NETFILTER_XT_TARGET_REDIRECT
to only make it visible if at least one of
{CONFIG_NF_NAT_REDIRECT_IPV4, CONFIG_NF_NAT_REDIRECT_IPV6} are enabled.
Additionally it is necessary to provide stubs for the
nf_nat_redirect_ipv{4,6} functions in case the header is included but
the corresponding Kconfig feature is not enabled.
Signed-off-by: Andreas Ruprecht <rupran@einserver.de>
---
include/net/netfilter/ipv4/nf_nat_redirect.h | 14 ++++++++++++++
include/net/netfilter/ipv6/nf_nat_redirect.h | 13 +++++++++++++
net/netfilter/Kconfig | 2 +-
3 files changed, 28 insertions(+), 1 deletion(-)
diff --git a/include/net/netfilter/ipv4/nf_nat_redirect.h b/include/net/netfilter/ipv4/nf_nat_redirect.h
index 19e1df3a0a4d..514c7f465d5f 100644
--- a/include/net/netfilter/ipv4/nf_nat_redirect.h
+++ b/include/net/netfilter/ipv4/nf_nat_redirect.h
@@ -1,9 +1,23 @@
#ifndef _NF_NAT_REDIRECT_IPV4_H_
#define _NF_NAT_REDIRECT_IPV4_H_
+#include <linux/netfilter.h>
+
+#ifdef CONFIG_NF_NAT_REDIRECT_IPV4
unsigned int
nf_nat_redirect_ipv4(struct sk_buff *skb,
const struct nf_nat_ipv4_multi_range_compat *mr,
unsigned int hooknum);
+#else /* CONFIG_NF_NAT_REDIRECT_IPv4 */
+
+unsigned int
+nf_nat_redirect_ipv4(struct sk_buff *skb,
+ const struct nf_nat_ipv4_multi_range_compat *mr,
+ unsigned int hooknum)
+{
+ return NF_ACCEPT;
+}
+#endif /* CONFIG_NF_NAT_REDIRECT_IPv4 */
+
#endif /* _NF_NAT_REDIRECT_IPV4_H_ */
diff --git a/include/net/netfilter/ipv6/nf_nat_redirect.h b/include/net/netfilter/ipv6/nf_nat_redirect.h
index 1ebdffc461cc..4db9351120ec 100644
--- a/include/net/netfilter/ipv6/nf_nat_redirect.h
+++ b/include/net/netfilter/ipv6/nf_nat_redirect.h
@@ -1,8 +1,21 @@
#ifndef _NF_NAT_REDIRECT_IPV6_H_
#define _NF_NAT_REDIRECT_IPV6_H_
+#include <linux/netfilter.h>
+
+#ifdef CONFIG_NF_NAT_REDIRECT_IPV6
unsigned int
nf_nat_redirect_ipv6(struct sk_buff *skb, const struct nf_nat_range *range,
unsigned int hooknum);
+#else /* CONFIG_NF_NAT_REDIRECT_IPV6 */
+
+unsigned int
+nf_nat_redirect_ipv6(struct sk_buff *skb, const struct nf_nat_range *range,
+ unsigned int hooknum)
+{
+ return NF_ACCEPT;
+}
+#endif /* CONFIG_NF_NAT_REDIRECT_IPV6 */
+
#endif /* _NF_NAT_REDIRECT_IPV6_H_ */
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index be8db270aa77..0972851cce03 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -844,7 +844,7 @@ config NETFILTER_XT_TARGET_RATEEST
config NETFILTER_XT_TARGET_REDIRECT
tristate "REDIRECT target support"
- depends on NF_NAT
+ depends on NF_NAT_IPV4 || NF_NAT_IPV6
select NF_NAT_REDIRECT_IPV4 if NF_NAT_IPV4
select NF_NAT_REDIRECT_IPV6 if NF_NAT_IPV6
---help---
--
1.9.1
^ permalink raw reply related
* Re: [patch net-next v3 01/17] bridge: rename fdb_*_hw to fdb_*_hw_addr to avoid confusion
From: Andy Gospodarek @ 2014-11-25 15:03 UTC (permalink / raw)
To: Jiri Pirko
Cc: netdev, davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse,
pshelar, azhou, ben, stephen, jeffrey.t.kirsher, vyasevic,
xiyou.wangcong, john.r.fastabend, edumazet, jhs, sfeldma,
f.fainelli, roopa, linville, jasowang, ebiederm, nicolas.dichtel,
ryazanov.s.a, buytenh, aviadr, nbd, alexei.starovoitov,
Neil.Jerram, ronye, simon.horman, alexander.h.duyck, john.ronciak,
mleitner, shrijeet, bcrl
In-Reply-To: <1416911328-10979-2-git-send-email-jiri@resnulli.us>
On Tue, Nov 25, 2014 at 11:28:32AM +0100, Jiri Pirko wrote:
> The current name might seem that this actually offloads the fdb entry to
> hw. So rename it to clearly present that this for hardware address
> addition/removal.
>
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Acked-by: Andy Gospodarek <gospo@cumulusnetworks.com>
> ---
> new in v2 as suggested by DaveM
> v2->v3:
> -moved the patch to the patchset head
> ---
> net/bridge/br_fdb.c | 14 +++++++-------
> 1 file changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
> index 6f6c95c..08ef4e7 100644
> --- a/net/bridge/br_fdb.c
> +++ b/net/bridge/br_fdb.c
> @@ -90,7 +90,7 @@ static void fdb_rcu_free(struct rcu_head *head)
> * are then updated with the new information.
> * Called under RTNL.
> */
> -static void fdb_add_hw(struct net_bridge *br, const unsigned char *addr)
> +static void fdb_add_hw_addr(struct net_bridge *br, const unsigned char *addr)
> {
> int err;
> struct net_bridge_port *p;
> @@ -118,7 +118,7 @@ undo:
> * the ports with needed information.
> * Called under RTNL.
> */
> -static void fdb_del_hw(struct net_bridge *br, const unsigned char *addr)
> +static void fdb_del_hw_addr(struct net_bridge *br, const unsigned char *addr)
> {
> struct net_bridge_port *p;
>
> @@ -133,7 +133,7 @@ static void fdb_del_hw(struct net_bridge *br, const unsigned char *addr)
> static void fdb_delete(struct net_bridge *br, struct net_bridge_fdb_entry *f)
> {
> if (f->is_static)
> - fdb_del_hw(br, f->addr.addr);
> + fdb_del_hw_addr(br, f->addr.addr);
>
> hlist_del_rcu(&f->hlist);
> fdb_notify(br, f, RTM_DELNEIGH);
> @@ -514,7 +514,7 @@ static int fdb_insert(struct net_bridge *br, struct net_bridge_port *source,
> return -ENOMEM;
>
> fdb->is_local = fdb->is_static = 1;
> - fdb_add_hw(br, addr);
> + fdb_add_hw_addr(br, addr);
> fdb_notify(br, fdb, RTM_NEWNEIGH);
> return 0;
> }
> @@ -754,19 +754,19 @@ static int fdb_add_entry(struct net_bridge_port *source, const __u8 *addr,
> fdb->is_local = 1;
> if (!fdb->is_static) {
> fdb->is_static = 1;
> - fdb_add_hw(br, addr);
> + fdb_add_hw_addr(br, addr);
> }
> } else if (state & NUD_NOARP) {
> fdb->is_local = 0;
> if (!fdb->is_static) {
> fdb->is_static = 1;
> - fdb_add_hw(br, addr);
> + fdb_add_hw_addr(br, addr);
> }
> } else {
> fdb->is_local = 0;
> if (fdb->is_static) {
> fdb->is_static = 0;
> - fdb_del_hw(br, addr);
> + fdb_del_hw_addr(br, addr);
> }
> }
>
> --
> 1.9.3
>
^ permalink raw reply
* Re: [patch net-next v3 04/17] net: introduce generic switch devices support
From: Andy Gospodarek @ 2014-11-25 15:02 UTC (permalink / raw)
To: Jiri Pirko
Cc: netdev, davem, nhorman, andy, tgraf, dborkman, ogerlitz, jesse,
pshelar, azhou, ben, stephen, jeffrey.t.kirsher, vyasevic,
xiyou.wangcong, john.r.fastabend, edumazet, jhs, sfeldma,
f.fainelli, roopa, linville, jasowang, ebiederm, nicolas.dichtel,
ryazanov.s.a, buytenh, aviadr, nbd, alexei.starovoitov,
Neil.Jerram, ronye, simon.horman, alexander.h.duyck, john.ronciak,
mleitner, shrijeet, bcrl
In-Reply-To: <1416911328-10979-5-git-send-email-jiri@resnulli.us>
On Tue, Nov 25, 2014 at 11:28:35AM +0100, Jiri Pirko wrote:
> The goal of this is to provide a possibility to support various switch
> chips. Drivers should implement relevant ndos to do so. Now there is
> only one ndo defined:
> - for getting physical switch id is in place.
>
> Note that user can use random port netdevice to access the switch.
>
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
> Reviewed-by: Thomas Graf <tgraf@suug.ch>
Looks good -- thanks for replacing 'sw' with 'switch'
Acked-by: Andy Gospodarek <gospo@cumulusnetworks.com>
> ---
> v2->v3:
> -fixed documentation typo pointed out by M. Braun
> -changed "sw" string to "switch" to avoid confusion
> v1->v2:
> -no change
> ---
> Documentation/networking/switchdev.txt | 59 ++++++++++++++++++++++++++++++++++
> MAINTAINERS | 7 ++++
> include/linux/netdevice.h | 10 ++++++
> include/net/switchdev.h | 30 +++++++++++++++++
> net/Kconfig | 1 +
> net/Makefile | 3 ++
> net/switchdev/Kconfig | 13 ++++++++
> net/switchdev/Makefile | 5 +++
> net/switchdev/switchdev.c | 33 +++++++++++++++++++
> 9 files changed, 161 insertions(+)
> create mode 100644 Documentation/networking/switchdev.txt
> create mode 100644 include/net/switchdev.h
> create mode 100644 net/switchdev/Kconfig
> create mode 100644 net/switchdev/Makefile
> create mode 100644 net/switchdev/switchdev.c
>
> diff --git a/Documentation/networking/switchdev.txt b/Documentation/networking/switchdev.txt
> new file mode 100644
> index 0000000..f981a92
> --- /dev/null
> +++ b/Documentation/networking/switchdev.txt
> @@ -0,0 +1,59 @@
> +Switch (and switch-ish) device drivers HOWTO
> +===========================
> +
> +Please note that the word "switch" is here used in very generic meaning.
> +This include devices supporting L2/L3 but also various flow offloading chips,
> +including switches embedded into SR-IOV NICs.
> +
> +Lets describe a topology a bit. Imagine the following example:
> +
> + +----------------------------+ +---------------+
> + | SOME switch chip | | CPU |
> + +----------------------------+ +---------------+
> + port1 port2 port3 port4 MNGMNT | PCI-E |
> + | | | | | +---------------+
> + PHY PHY | | | | NIC0 NIC1
> + | | | | | |
> + | | +- PCI-E -+ | |
> + | +------- MII -------+ |
> + +------------- MII ------------+
> +
> +In this example, there are two independent lines between the switch silicon
> +and CPU. NIC0 and NIC1 drivers are not aware of a switch presence. They are
> +separate from the switch driver. SOME switch chip is by managed by a driver
> +via PCI-E device MNGMNT. Note that MNGMNT device, NIC0 and NIC1 may be
> +connected to some other type of bus.
> +
> +Now, for the previous example show the representation in kernel:
> +
> + +----------------------------+ +---------------+
> + | SOME switch chip | | CPU |
> + +----------------------------+ +---------------+
> + sw0p0 sw0p1 sw0p2 sw0p3 MNGMNT | PCI-E |
> + | | | | | +---------------+
> + PHY PHY | | | | eth0 eth1
> + | | | | | |
> + | | +- PCI-E -+ | |
> + | +------- MII -------+ |
> + +------------- MII ------------+
> +
> +Lets call the example switch driver for SOME switch chip "SOMEswitch". This
> +driver takes care of PCI-E device MNGMNT. There is a netdevice instance sw0pX
> +created for each port of a switch. These netdevices are instances
> +of "SOMEswitch" driver. sw0pX netdevices serve as a "representation"
> +of the switch chip. eth0 and eth1 are instances of some other existing driver.
> +
> +The only difference of the switch-port netdevice from the ordinary netdevice
> +is that is implements couple more NDOs:
> +
> + ndo_switch_parent_id_get - This returns the same ID for two port netdevices
> + of the same physical switch chip. This is
> + mandatory to be implemented by all switch drivers
> + and serves the caller for recognition of a port
> + netdevice.
> + ndo_switch_parent_* - Functions that serve for a manipulation of the switch
> + chip itself (it can be though of as a "parent" of the
> + port, therefore the name). They are not port-specific.
> + Caller might use arbitrary port netdevice of the same
> + switch and it will make no difference.
> + ndo_switch_port_* - Functions that serve for a port-specific manipulation.
> diff --git a/MAINTAINERS b/MAINTAINERS
> index a545d68..05addb6 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -9058,6 +9058,13 @@ F: lib/swiotlb.c
> F: arch/*/kernel/pci-swiotlb.c
> F: include/linux/swiotlb.h
>
> +SWITCHDEV
> +M: Jiri Pirko <jiri@resnulli.us>
> +L: netdev@vger.kernel.org
> +S: Supported
> +F: net/switchdev/
> +F: include/net/switchdev.h
> +
> SYNOPSYS ARC ARCHITECTURE
> M: Vineet Gupta <vgupta@synopsys.com>
> S: Supported
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 5b491b3..ce096dc 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -1018,6 +1018,12 @@ typedef u16 (*select_queue_fallback_t)(struct net_device *dev,
> * performing GSO on a packet. The device returns true if it is
> * able to GSO the packet, false otherwise. If the return value is
> * false the stack will do software GSO.
> + *
> + * int (*ndo_switch_parent_id_get)(struct net_device *dev,
> + * struct netdev_phys_item_id *psid);
> + * Called to get an ID of the switch chip this port is part of.
> + * If driver implements this, it indicates that it represents a port
> + * of a switch chip.
> */
> struct net_device_ops {
> int (*ndo_init)(struct net_device *dev);
> @@ -1171,6 +1177,10 @@ struct net_device_ops {
> int (*ndo_get_lock_subclass)(struct net_device *dev);
> bool (*ndo_gso_check) (struct sk_buff *skb,
> struct net_device *dev);
> +#ifdef CONFIG_NET_SWITCHDEV
> + int (*ndo_switch_parent_id_get)(struct net_device *dev,
> + struct netdev_phys_item_id *psid);
> +#endif
> };
>
> /**
> diff --git a/include/net/switchdev.h b/include/net/switchdev.h
> new file mode 100644
> index 0000000..7a52360
> --- /dev/null
> +++ b/include/net/switchdev.h
> @@ -0,0 +1,30 @@
> +/*
> + * include/net/switchdev.h - Switch device API
> + * Copyright (c) 2014 Jiri Pirko <jiri@resnulli.us>
> + *
> + * 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.
> + */
> +#ifndef _LINUX_SWITCHDEV_H_
> +#define _LINUX_SWITCHDEV_H_
> +
> +#include <linux/netdevice.h>
> +
> +#ifdef CONFIG_NET_SWITCHDEV
> +
> +int netdev_switch_parent_id_get(struct net_device *dev,
> + struct netdev_phys_item_id *psid);
> +
> +#else
> +
> +static inline int netdev_switch_parent_id_get(struct net_device *dev,
> + struct netdev_phys_item_id *psid)
> +{
> + return -EOPNOTSUPP;
> +}
> +
> +#endif
> +
> +#endif /* _LINUX_SWITCHDEV_H_ */
> diff --git a/net/Kconfig b/net/Kconfig
> index 99815b5..ff9ffc1 100644
> --- a/net/Kconfig
> +++ b/net/Kconfig
> @@ -228,6 +228,7 @@ source "net/vmw_vsock/Kconfig"
> source "net/netlink/Kconfig"
> source "net/mpls/Kconfig"
> source "net/hsr/Kconfig"
> +source "net/switchdev/Kconfig"
>
> config RPS
> boolean
> diff --git a/net/Makefile b/net/Makefile
> index 7ed1970..95fc694 100644
> --- a/net/Makefile
> +++ b/net/Makefile
> @@ -73,3 +73,6 @@ obj-$(CONFIG_OPENVSWITCH) += openvswitch/
> obj-$(CONFIG_VSOCKETS) += vmw_vsock/
> obj-$(CONFIG_NET_MPLS_GSO) += mpls/
> obj-$(CONFIG_HSR) += hsr/
> +ifneq ($(CONFIG_NET_SWITCHDEV),)
> +obj-y += switchdev/
> +endif
> diff --git a/net/switchdev/Kconfig b/net/switchdev/Kconfig
> new file mode 100644
> index 0000000..1557545
> --- /dev/null
> +++ b/net/switchdev/Kconfig
> @@ -0,0 +1,13 @@
> +#
> +# Configuration for Switch device support
> +#
> +
> +config NET_SWITCHDEV
> + boolean "Switch (and switch-ish) device support (EXPERIMENTAL)"
> + depends on INET
> + ---help---
> + This module provides glue between core networking code and device
> + drivers in order to support hardware switch chips in very generic
> + meaning of the word "switch". This include devices supporting L2/L3 but
> + also various flow offloading chips, including switches embedded into
> + SR-IOV NICs.
> diff --git a/net/switchdev/Makefile b/net/switchdev/Makefile
> new file mode 100644
> index 0000000..5ed63ed
> --- /dev/null
> +++ b/net/switchdev/Makefile
> @@ -0,0 +1,5 @@
> +#
> +# Makefile for the Switch device API
> +#
> +
> +obj-$(CONFIG_NET_SWITCHDEV) += switchdev.o
> diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
> new file mode 100644
> index 0000000..66973de
> --- /dev/null
> +++ b/net/switchdev/switchdev.c
> @@ -0,0 +1,33 @@
> +/*
> + * net/switchdev/switchdev.c - Switch device API
> + * Copyright (c) 2014 Jiri Pirko <jiri@resnulli.us>
> + *
> + * 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/init.h>
> +#include <linux/netdevice.h>
> +#include <net/switchdev.h>
> +
> +/**
> + * netdev_switch_parent_id_get - Get ID of a switch
> + * @dev: port device
> + * @psid: switch ID
> + *
> + * Get ID of a switch this port is part of.
> + */
> +int netdev_switch_parent_id_get(struct net_device *dev,
> + struct netdev_phys_item_id *psid)
> +{
> + const struct net_device_ops *ops = dev->netdev_ops;
> +
> + if (!ops->ndo_switch_parent_id_get)
> + return -EOPNOTSUPP;
> + return ops->ndo_switch_parent_id_get(dev, psid);
> +}
> +EXPORT_SYMBOL(netdev_switch_parent_id_get);
> --
> 1.9.3
>
^ permalink raw reply
* Re: [PATCH net-next 3/3] sch_fq: segment too big GSO packets
From: Eric Dumazet @ 2014-11-25 14:53 UTC (permalink / raw)
To: Yang Yingliang; +Cc: netdev, davem
In-Reply-To: <1416921892-4756-4-git-send-email-yangyingliang@huawei.com>
On Tue, 2014-11-25 at 21:24 +0800, Yang Yingliang wrote:
> If a GSO packet cost more than 125ms to send, segment the
> packet and send individual segments.
>
> Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
> ---
> net/sched/sch_fq.c | 24 ++++++++++++++++++++++++
> 1 file changed, 24 insertions(+)
>
> diff --git a/net/sched/sch_fq.c b/net/sched/sch_fq.c
> index ec6eff8..0119340 100644
> --- a/net/sched/sch_fq.c
> +++ b/net/sched/sch_fq.c
> @@ -423,6 +423,30 @@ static int fq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
> return qdisc_drop(skb, sch);
> }
>
I am opposed to this patch serie.
FQ is used at 40Gb speeds at Google, we can not afford doing such copies
in FQ at all.
If you believe packets are too big at this point, then you should fix
the provider of such packets.
Sorry.
^ permalink raw reply
* Re: [PATCH 3/4] GMAC: dts: add gmac info for rk3288
From: Heiko Stübner @ 2014-11-25 14:39 UTC (permalink / raw)
To: Roger Chen
Cc: Sergei Shtylyov, peppe.cavallaro, netdev, linux-kernel,
linux-rockchip, kever.yang, mark.yao, eddie.cai
In-Reply-To: <547486EB.5080702@cogentembedded.com>
Am Dienstag, 25. November 2014, 16:40:59 schrieb Sergei Shtylyov:
> Hello.
>
> On 11/25/2014 12:08 PM, Roger Chen wrote:
> > add gmac info in rk3288.dtsi for GMAC driver
> >
> > Signed-off-by: Roger Chen <roger.chen@rock-chips.com>
> > ---
> >
> > arch/arm/boot/dts/rk3288.dtsi | 59
> > +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59
> > insertions(+)
> >
> > diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
> > index 0f50d5d..949675d 100644
> > --- a/arch/arm/boot/dts/rk3288.dtsi
> > +++ b/arch/arm/boot/dts/rk3288.dtsi
>
> [...]
>
> > @@ -490,6 +497,25 @@
> >
> > reg = <0xff740000 0x1000>;
> >
> > };
> >
> > + gmac: eth@ff290000 {
>
> Please name the node "ethernet@ff290000" to comply with the ePAPR
> standard.
> > + compatible = "rockchip,rk3288-gmac";
> > + reg = <0xff290000 0x10000>;
> > + interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>; /*irq=59*/
> > + interrupt-names = "macirq";
> > + rockchip,grf = <&grf>;
> > + clocks = <&cru SCLK_MAC>, <&cru SCLK_MAC_PLL>,
> > + <&cru SCLK_MAC_RX>, <&cru SCLK_MAC_TX>,
> > + <&cru SCLK_MACREF>, <&cru SCLK_MACREF_OUT>,
> > + <&cru ACLK_GMAC>, <&cru PCLK_GMAC>;
> > + clock-names = "stmmaceth", "clk_mac_pll",
> > + "mac_clk_rx", "mac_clk_tx",
> > + "clk_mac_ref", "clk_mac_refout",
> > + "aclk_mac", "pclk_mac";
> > + phy-mode = "rgmii";
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&rgmii_pin /*&rmii_pin*/>;
>
> Hm, pinctrl props in a .dtsi file? Those are usually board dependent.
yep, especially as there is a board-dependent selection needed of what to use
[rgmii or rmii] depending on the phy on the board.
>
> [...]
>
> > @@ -1040,5 +1066,38 @@
> >
> > rockchip,pins = <7 23 3 &pcfg_pull_none>;
> >
> > };
> >
> > };
> >
> > +
> > + gmac {
> > + rgmii_pin: rgmii-pins {
please add the "s" to the label - "rgmii_pins"
> > + rockchip,pins = <3 30 3 &pcfg_pull_none>,
> > + <3 31 3 &pcfg_pull_none>,
> > + <3 26 3 &pcfg_pull_none>,
> > + <3 27 3 &pcfg_pull_none>,
> > + <3 28 3 &pcfg_pull_none>,
> > + <3 29 3 &pcfg_pull_none>,
> > + <3 24 3 &pcfg_pull_none>,
> > + <3 25 3 &pcfg_pull_none>,
> > + <4 0 3 &pcfg_pull_none>,
> > + <4 5 3 &pcfg_pull_none>,
> > + <4 6 3 &pcfg_pull_none>,
> > + <4 9 3 &pcfg_pull_none>,
> > + <4 4 3 &pcfg_pull_none>,
> > + <4 1 3 &pcfg_pull_none>,
> > + <4 3 3 &pcfg_pull_none>;
> > + };
> > +
> > + rmii_pin: rmii-pins {
same here
> > + rockchip,pins = <3 30 3 &pcfg_pull_none>,
> > + <3 31 3 &pcfg_pull_none>,
> > + <3 28 3 &pcfg_pull_none>,
> > + <3 29 3 &pcfg_pull_none>,
> > + <4 0 3 &pcfg_pull_none>,
> > + <4 5 3 &pcfg_pull_none>,
> > + <4 4 3 &pcfg_pull_none>,
> > + <4 1 3 &pcfg_pull_none>,
> > + <4 2 3 &pcfg_pull_none>,
> > + <4 3 3 &pcfg_pull_none>;
> > + };
> > + };
>
> These are usually define in the board .dts file...
The pinctrl settings itself are soc-specific, i.e. the pins and their settings
to use to enable r{g}mii functionality are the same for all boards using this
soc, so the pinctrl definitions should stay here and not be redefined in each
and every board file.
Heiko
^ permalink raw reply
* Possible memory leak in function (r8712_setrttbl_cmd) not freeing pointer (ph2c) on error path
From: Ahmed Tamrawi @ 2014-11-25 14:24 UTC (permalink / raw)
To: netdev
Bug Report Filed: https://bugzilla.kernel.org/show_bug.cgi?id=88881
Linux Version [3.17-rc1]
Configuration: Default configuration for x86
In function (r8712_setrttbl_cmd) file (drivers/staging/rtl8712/rtl871x_cmd.c):
Function (r8712_setrttbl_cmd) allocates the variable (ph2c) at line
732 and passes it as a parameter to function (r8712_enqueue_cmd) at
line 743. Function (r8712_setrttbl_cmd) returns (_SUCCESS) result
regardless of the result of the called function (r8712_enqueue_cmd)
which may return (_FAIL) at line 176. This failure causing the
allocated object not to be queued and hence not freed later. Thus,
causing a possible memory leak not freeing the (ph2c) pointer upon
(_FAIL) return of function (r8712_enqueue_cmd).
Source code reference for function (r8712_setrttbl_cmd):
http://lxr.free-electrons.com/source/drivers/staging/rtl8712/rtl871x_cmd.c#L725
Source code reference for function (r8712_enqueue_cmd):
http://lxr.free-electrons.com/source/drivers/staging/rtl8712/rtl871x_cmd.c#L171
~Ahmed
^ permalink raw reply
* Re: [PATCH 1/2] sh_eth: Fix sleeping function called from invalid context
From: Sergei Shtylyov @ 2014-11-25 14:09 UTC (permalink / raw)
To: Geert Uytterhoeven, Yoshihiro Kaneko
Cc: netdev@vger.kernel.org, David S. Miller, Simon Horman,
Magnus Damm, Linux-sh list
In-Reply-To: <CAMuHMdWJYuXES4g1-=H6xo=gVePPSUkybUhL0VjuKk7asE6syg@mail.gmail.com>
Hello.
On 11/25/2014 4:35 PM, Geert Uytterhoeven wrote:
>> From: Mitsuhiro Kimura <mitsuhiro.kimura.kc@renesas.com>
>> Fix the bug as follows:
>> ----
>> [ 1238.161349] BUG: sleeping function called from invalid context at drivers/base/power/runtime.c:952
>> [ 1238.188279] in_atomic(): 1, irqs_disabled(): 0, pid: 1388, name: cat
>> [ 1238.207425] CPU: 0 PID: 1388 Comm: cat Not tainted 3.10.31-ltsi-00046-gefa0b46 #1087
>> [ 1238.230737] Backtrace:
>> [ 1238.238123] [<c0012e64>] (dump_backtrace+0x0/0x10c) from [<c0013000>] (show_stack+0x18/0x1c)
>> [ 1238.263499] r6:000003b8 r5:c06160c0 r4:c0669e00 r3:00404000
>> [ 1238.280583] [<c0012fe8>] (show_stack+0x0/0x1c) from [<c04515a4>] (dump_stack+0x20/0x28)
>> [ 1238.304631] [<c0451584>] (dump_stack+0x0/0x28) from [<c004970c>] (__might_sleep+0xf8/0x118)
>> [ 1238.329734] [<c0049614>] (__might_sleep+0x0/0x118) from [<c02465ac>] (__pm_runtime_resume+0x38/0x90)
>> [ 1238.357170] r7:d616f000 r6:c049c458 r5:00000004 r4:d6a17210
>> [ 1238.374251] [<c0246574>] (__pm_runtime_resume+0x0/0x90) from [<c029b1c4>] (sh_eth_get_stats+0x44/0x280)
>> [ 1238.402468] r7:d616f000 r6:c049c458 r5:d5c21000 r4:d5c21000
>> [ 1238.419552] [<c029b180>] (sh_eth_get_stats+0x0/0x280) from [<c03ae39c>] (dev_get_stats+0x54/0x88)
>> [ 1238.446204] r5:d5c21000 r4:d5ed7e08
>> [ 1238.456980] [<c03ae348>] (dev_get_stats+0x0/0x88) from [<c03c677c>] (netstat_show.isra.15+0x54/0x9c)
>> [ 1238.484413] r6:d5c21000 r5:d5c21238 r4:00000028 r3:00000001
>> [ 1238.501495] [<c03c6728>] (netstat_show.isra.15+0x0/0x9c) from [<c03c69b8>] (show_tx_errors+0x18/0x1c)
>> [ 1238.529196] r7:d5f945d8 r6:d5f945c0 r5:c049716c r4:c0650e7c
>> [ 1238.546279] [<c03c69a0>] (show_tx_errors+0x0/0x1c) from [<c023963c>] (dev_attr_show+0x24/0x50)
>> [ 1238.572157] [<c0239618>] (dev_attr_show+0x0/0x50) from [<c010c148>] (sysfs_read_file+0xb0/0x140)
>> [ 1238.598554] r5:c049716c r4:d5c21240
>> [ 1238.609326] [<c010c098>] (sysfs_read_file+0x0/0x140) from [<c00b9ee4>] (vfs_read+0xb0/0x13c)
>> [ 1238.634679] [<c00b9e34>] (vfs_read+0x0/0x13c) from [<c00ba0ac>] (SyS_read+0x44/0x74)
>> [ 1238.657944] r8:bef45bf0 r7:00000000 r6:d6ac0600 r5:00000000 r4:00000000
>> [ 1238.678172] [<c00ba068>] (SyS_read+0x0/0x74) from [<c000eec0>] (ret_fast_syscall+0x0/0x30)
>> ----
>> Signed-off-by: Mitsuhiro Kimura <mitsuhiro.kimura.kc@renesas.com>
>> Signed-off-by: Yoshihiro Kaneko <ykaneko0929@gmail.com>
>> ---
>> drivers/net/ethernet/renesas/sh_eth.c | 64 +++++++++++++++++++----------------
>> drivers/net/ethernet/renesas/sh_eth.h | 1 +
>> 2 files changed, 36 insertions(+), 29 deletions(-)
>> diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
>> index 60e9c2c..862a691 100644
>> --- a/drivers/net/ethernet/renesas/sh_eth.c
>> +++ b/drivers/net/ethernet/renesas/sh_eth.c
[...]
>> @@ -2131,6 +2133,36 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
>> return NETDEV_TX_OK;
>> }
>>
>> +static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev)
>> +{
>> + struct sh_eth_private *mdp = netdev_priv(ndev);
>> +
>> + if (sh_eth_is_rz_fast_ether(mdp))
>> + return &ndev->stats;
>> +
>> + if (!mdp->is_opened)
> Can't you use netif_running(ndev) instead?
The __LINK_STATE_START flag it tests gets set in __dev_open() before
calling the ndo_open() method. Looks like it would be somewhat unsafe to use it...
WBR, Sergei
^ permalink raw reply
* [PATCH v2 13/17] tipc_msg_build(): pass msghdr instead of its ->msg_iov
From: Al Viro @ 2014-11-25 14:02 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-kernel
In-Reply-To: <20141125024018.GH7996@ZenIV.linux.org.uk>
From: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
net/tipc/msg.c | 8 ++++----
net/tipc/msg.h | 2 +-
net/tipc/socket.c | 7 +++----
3 files changed, 8 insertions(+), 9 deletions(-)
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index ec18076..9155496 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -162,14 +162,14 @@ err:
/**
* tipc_msg_build - create buffer chain containing specified header and data
* @mhdr: Message header, to be prepended to data
- * @iov: User data
+ * @m: User message
* @offset: Posision in iov to start copying from
* @dsz: Total length of user data
* @pktmax: Max packet size that can be used
* @chain: Buffer or chain of buffers to be returned to caller
* Returns message data size or errno: -ENOMEM, -EFAULT
*/
-int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov,
+int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m,
int offset, int dsz, int pktmax , struct sk_buff **chain)
{
int mhsz = msg_hdr_sz(mhdr);
@@ -194,7 +194,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov,
skb_copy_to_linear_data(buf, mhdr, mhsz);
pktpos = buf->data + mhsz;
TIPC_SKB_CB(buf)->chain_sz = 1;
- if (!dsz || !memcpy_fromiovecend(pktpos, iov, offset, dsz))
+ if (!dsz || !memcpy_fromiovecend(pktpos, m->msg_iov, offset, dsz))
return dsz;
rc = -EFAULT;
goto error;
@@ -223,7 +223,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov,
if (drem < pktrem)
pktrem = drem;
- if (memcpy_fromiovecend(pktpos, iov, offset, pktrem)) {
+ if (memcpy_fromiovecend(pktpos, m->msg_iov, offset, pktrem)) {
rc = -EFAULT;
goto error;
}
diff --git a/net/tipc/msg.h b/net/tipc/msg.h
index 0ea7b69..d7d2ba2 100644
--- a/net/tipc/msg.h
+++ b/net/tipc/msg.h
@@ -743,7 +743,7 @@ bool tipc_msg_bundle(struct sk_buff *bbuf, struct sk_buff *buf, u32 mtu);
bool tipc_msg_make_bundle(struct sk_buff **buf, u32 mtu, u32 dnode);
-int tipc_msg_build(struct tipc_msg *mhdr, struct iovec const *iov,
+int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m,
int offset, int dsz, int mtu , struct sk_buff **chain);
struct sk_buff *tipc_msg_reassemble(struct sk_buff *chain);
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 2d4b2fa..b3415a7 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -727,7 +727,7 @@ static int tipc_sendmcast(struct socket *sock, struct tipc_name_seq *seq,
new_mtu:
mtu = tipc_bclink_get_mtu();
- rc = tipc_msg_build(mhdr, msg->msg_iov, 0, dsz, mtu, &buf);
+ rc = tipc_msg_build(mhdr, msg, 0, dsz, mtu, &buf);
if (unlikely(rc < 0))
return rc;
@@ -905,7 +905,6 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock,
struct sock *sk = sock->sk;
struct tipc_sock *tsk = tipc_sk(sk);
struct tipc_msg *mhdr = &tsk->phdr;
- struct iovec *iov = m->msg_iov;
u32 dnode, dport;
struct sk_buff *buf;
struct tipc_name_seq *seq = &dest->addr.nameseq;
@@ -982,7 +981,7 @@ static int tipc_sendmsg(struct kiocb *iocb, struct socket *sock,
new_mtu:
mtu = tipc_node_get_mtu(dnode, tsk->ref);
- rc = tipc_msg_build(mhdr, iov, 0, dsz, mtu, &buf);
+ rc = tipc_msg_build(mhdr, m, 0, dsz, mtu, &buf);
if (rc < 0)
goto exit;
@@ -1094,7 +1093,7 @@ static int tipc_send_stream(struct kiocb *iocb, struct socket *sock,
next:
mtu = tsk->max_pkt;
send = min_t(uint, dsz - sent, TIPC_MAX_USER_MSG_SIZE);
- rc = tipc_msg_build(mhdr, m->msg_iov, sent, send, mtu, &buf);
+ rc = tipc_msg_build(mhdr, m, sent, send, mtu, &buf);
if (unlikely(rc < 0))
goto exit;
do {
--
1.7.10.4
^ permalink raw reply related
* [PATCH v2 17/17] rds: switch rds_message_copy_from_user() to iov_iter
From: Al Viro @ 2014-11-25 14:02 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-kernel
In-Reply-To: <20141125024018.GH7996@ZenIV.linux.org.uk>
From: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
net/rds/message.c | 42 ++++++++++++------------------------------
net/rds/rds.h | 3 +--
net/rds/send.c | 4 +++-
3 files changed, 16 insertions(+), 33 deletions(-)
diff --git a/net/rds/message.c b/net/rds/message.c
index 7a546e0..ff22022 100644
--- a/net/rds/message.c
+++ b/net/rds/message.c
@@ -264,64 +264,46 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in
return rm;
}
-int rds_message_copy_from_user(struct rds_message *rm, struct iovec *first_iov,
- size_t total_len)
+int rds_message_copy_from_user(struct rds_message *rm, struct iov_iter *from)
{
unsigned long to_copy;
- unsigned long iov_off;
unsigned long sg_off;
- struct iovec *iov;
struct scatterlist *sg;
int ret = 0;
- rm->m_inc.i_hdr.h_len = cpu_to_be32(total_len);
+ rm->m_inc.i_hdr.h_len = cpu_to_be32(iov_iter_count(from));
/*
* now allocate and copy in the data payload.
*/
sg = rm->data.op_sg;
- iov = first_iov;
- iov_off = 0;
sg_off = 0; /* Dear gcc, sg->page will be null from kzalloc. */
- while (total_len) {
+ while (iov_iter_count(from)) {
if (!sg_page(sg)) {
- ret = rds_page_remainder_alloc(sg, total_len,
+ ret = rds_page_remainder_alloc(sg, iov_iter_count(from),
GFP_HIGHUSER);
if (ret)
- goto out;
+ return ret;
rm->data.op_nents++;
sg_off = 0;
}
- while (iov_off == iov->iov_len) {
- iov_off = 0;
- iov++;
- }
-
- to_copy = min(iov->iov_len - iov_off, sg->length - sg_off);
- to_copy = min_t(size_t, to_copy, total_len);
-
- rdsdebug("copying %lu bytes from user iov [%p, %zu] + %lu to "
- "sg [%p, %u, %u] + %lu\n",
- to_copy, iov->iov_base, iov->iov_len, iov_off,
- (void *)sg_page(sg), sg->offset, sg->length, sg_off);
+ to_copy = min_t(unsigned long, iov_iter_count(from),
+ sg->length - sg_off);
- ret = rds_page_copy_from_user(sg_page(sg), sg->offset + sg_off,
- iov->iov_base + iov_off,
- to_copy);
- if (ret)
- goto out;
+ rds_stats_add(s_copy_from_user, to_copy);
+ ret = copy_page_from_iter(sg_page(sg), sg->offset + sg_off,
+ to_copy, from);
+ if (ret != to_copy)
+ return -EFAULT;
- iov_off += to_copy;
- total_len -= to_copy;
sg_off += to_copy;
if (sg_off == sg->length)
sg++;
}
-out:
return ret;
}
diff --git a/net/rds/rds.h b/net/rds/rds.h
index b22dad9..c2a5eef 100644
--- a/net/rds/rds.h
+++ b/net/rds/rds.h
@@ -656,8 +656,7 @@ rds_conn_connecting(struct rds_connection *conn)
/* message.c */
struct rds_message *rds_message_alloc(unsigned int nents, gfp_t gfp);
struct scatterlist *rds_message_alloc_sgs(struct rds_message *rm, int nents);
-int rds_message_copy_from_user(struct rds_message *rm, struct iovec *first_iov,
- size_t total_len);
+int rds_message_copy_from_user(struct rds_message *rm, struct iov_iter *from);
struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned int total_len);
void rds_message_populate_header(struct rds_header *hdr, __be16 sport,
__be16 dport, u64 seq);
diff --git a/net/rds/send.c b/net/rds/send.c
index 0a64541..4de62ea 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -934,7 +934,9 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
int queued = 0, allocated_mr = 0;
int nonblock = msg->msg_flags & MSG_DONTWAIT;
long timeo = sock_sndtimeo(sk, nonblock);
+ struct iov_iter from;
+ iov_iter_init(&from, WRITE, msg->msg_iov, msg->msg_iovlen, payload_len);
/* Mirror Linux UDP mirror of BSD error message compatibility */
/* XXX: Perhaps MSG_MORE someday */
if (msg->msg_flags & ~(MSG_DONTWAIT | MSG_CMSG_COMPAT)) {
@@ -982,7 +984,7 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
ret = -ENOMEM;
goto out;
}
- ret = rds_message_copy_from_user(rm, msg->msg_iov, payload_len);
+ ret = rds_message_copy_from_user(rm, &from);
if (ret)
goto out;
}
--
1.7.10.4
^ permalink raw reply related
* [PATCH v2 16/17] rds: switch ->inc_copy_to_user() to passing iov_iter
From: Al Viro @ 2014-11-25 14:02 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-kernel
In-Reply-To: <20141125024018.GH7996@ZenIV.linux.org.uk>
From: Al Viro <viro@zeniv.linux.org.uk>
instances get considerably simpler from that...
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
net/rds/ib.h | 3 +--
net/rds/ib_recv.c | 37 +++++++++++--------------------------
net/rds/iw.h | 3 +--
net/rds/iw_recv.c | 37 +++++++++++--------------------------
net/rds/message.c | 35 ++++++++---------------------------
net/rds/rds.h | 6 ++----
net/rds/recv.c | 5 +++--
net/rds/tcp.h | 3 +--
net/rds/tcp_recv.c | 38 +++++++++-----------------------------
9 files changed, 47 insertions(+), 120 deletions(-)
diff --git a/net/rds/ib.h b/net/rds/ib.h
index 7280ab8..c36d713 100644
--- a/net/rds/ib.h
+++ b/net/rds/ib.h
@@ -316,8 +316,7 @@ int rds_ib_recv_alloc_caches(struct rds_ib_connection *ic);
void rds_ib_recv_free_caches(struct rds_ib_connection *ic);
void rds_ib_recv_refill(struct rds_connection *conn, int prefill);
void rds_ib_inc_free(struct rds_incoming *inc);
-int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov,
- size_t size);
+int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to);
void rds_ib_recv_cq_comp_handler(struct ib_cq *cq, void *context);
void rds_ib_recv_tasklet_fn(unsigned long data);
void rds_ib_recv_init_ring(struct rds_ib_connection *ic);
diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c
index d67de45..1b981a4 100644
--- a/net/rds/ib_recv.c
+++ b/net/rds/ib_recv.c
@@ -472,15 +472,12 @@ static struct list_head *rds_ib_recv_cache_get(struct rds_ib_refill_cache *cache
return head;
}
-int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov,
- size_t size)
+int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to)
{
struct rds_ib_incoming *ibinc;
struct rds_page_frag *frag;
- struct iovec *iov = first_iov;
unsigned long to_copy;
unsigned long frag_off = 0;
- unsigned long iov_off = 0;
int copied = 0;
int ret;
u32 len;
@@ -489,37 +486,25 @@ int rds_ib_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov,
frag = list_entry(ibinc->ii_frags.next, struct rds_page_frag, f_item);
len = be32_to_cpu(inc->i_hdr.h_len);
- while (copied < size && copied < len) {
+ while (iov_iter_count(to) && copied < len) {
if (frag_off == RDS_FRAG_SIZE) {
frag = list_entry(frag->f_item.next,
struct rds_page_frag, f_item);
frag_off = 0;
}
- while (iov_off == iov->iov_len) {
- iov_off = 0;
- iov++;
- }
-
- to_copy = min(iov->iov_len - iov_off, RDS_FRAG_SIZE - frag_off);
- to_copy = min_t(size_t, to_copy, size - copied);
+ to_copy = min_t(unsigned long, iov_iter_count(to),
+ RDS_FRAG_SIZE - frag_off);
to_copy = min_t(unsigned long, to_copy, len - copied);
- rdsdebug("%lu bytes to user [%p, %zu] + %lu from frag "
- "[%p, %u] + %lu\n",
- to_copy, iov->iov_base, iov->iov_len, iov_off,
- sg_page(&frag->f_sg), frag->f_sg.offset, frag_off);
-
/* XXX needs + offset for multiple recvs per page */
- ret = rds_page_copy_to_user(sg_page(&frag->f_sg),
- frag->f_sg.offset + frag_off,
- iov->iov_base + iov_off,
- to_copy);
- if (ret) {
- copied = ret;
- break;
- }
+ rds_stats_add(s_copy_to_user, to_copy);
+ ret = copy_page_to_iter(sg_page(&frag->f_sg),
+ frag->f_sg.offset + frag_off,
+ to_copy,
+ to);
+ if (ret != to_copy)
+ return -EFAULT;
- iov_off += to_copy;
frag_off += to_copy;
copied += to_copy;
}
diff --git a/net/rds/iw.h b/net/rds/iw.h
index 04ce3b1..cbe6674 100644
--- a/net/rds/iw.h
+++ b/net/rds/iw.h
@@ -325,8 +325,7 @@ int rds_iw_recv(struct rds_connection *conn);
int rds_iw_recv_refill(struct rds_connection *conn, gfp_t kptr_gfp,
gfp_t page_gfp, int prefill);
void rds_iw_inc_free(struct rds_incoming *inc);
-int rds_iw_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov,
- size_t size);
+int rds_iw_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to);
void rds_iw_recv_cq_comp_handler(struct ib_cq *cq, void *context);
void rds_iw_recv_tasklet_fn(unsigned long data);
void rds_iw_recv_init_ring(struct rds_iw_connection *ic);
diff --git a/net/rds/iw_recv.c b/net/rds/iw_recv.c
index aa8bf67..a66d179 100644
--- a/net/rds/iw_recv.c
+++ b/net/rds/iw_recv.c
@@ -303,15 +303,12 @@ void rds_iw_inc_free(struct rds_incoming *inc)
BUG_ON(atomic_read(&rds_iw_allocation) < 0);
}
-int rds_iw_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov,
- size_t size)
+int rds_iw_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to)
{
struct rds_iw_incoming *iwinc;
struct rds_page_frag *frag;
- struct iovec *iov = first_iov;
unsigned long to_copy;
unsigned long frag_off = 0;
- unsigned long iov_off = 0;
int copied = 0;
int ret;
u32 len;
@@ -320,37 +317,25 @@ int rds_iw_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov,
frag = list_entry(iwinc->ii_frags.next, struct rds_page_frag, f_item);
len = be32_to_cpu(inc->i_hdr.h_len);
- while (copied < size && copied < len) {
+ while (iov_iter_count(to) && copied < len) {
if (frag_off == RDS_FRAG_SIZE) {
frag = list_entry(frag->f_item.next,
struct rds_page_frag, f_item);
frag_off = 0;
}
- while (iov_off == iov->iov_len) {
- iov_off = 0;
- iov++;
- }
-
- to_copy = min(iov->iov_len - iov_off, RDS_FRAG_SIZE - frag_off);
- to_copy = min_t(size_t, to_copy, size - copied);
+ to_copy = min_t(unsigned long, iov_iter_count(to),
+ RDS_FRAG_SIZE - frag_off);
to_copy = min_t(unsigned long, to_copy, len - copied);
- rdsdebug("%lu bytes to user [%p, %zu] + %lu from frag "
- "[%p, %lu] + %lu\n",
- to_copy, iov->iov_base, iov->iov_len, iov_off,
- frag->f_page, frag->f_offset, frag_off);
-
/* XXX needs + offset for multiple recvs per page */
- ret = rds_page_copy_to_user(frag->f_page,
- frag->f_offset + frag_off,
- iov->iov_base + iov_off,
- to_copy);
- if (ret) {
- copied = ret;
- break;
- }
+ rds_stats_add(s_copy_to_user, to_copy);
+ ret = copy_page_to_iter(frag->f_page,
+ frag->f_offset + frag_off,
+ to_copy,
+ to);
+ if (ret != to_copy)
+ return -EFAULT;
- iov_off += to_copy;
frag_off += to_copy;
copied += to_copy;
}
diff --git a/net/rds/message.c b/net/rds/message.c
index aba232f..7a546e0 100644
--- a/net/rds/message.c
+++ b/net/rds/message.c
@@ -325,14 +325,11 @@ out:
return ret;
}
-int rds_message_inc_copy_to_user(struct rds_incoming *inc,
- struct iovec *first_iov, size_t size)
+int rds_message_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to)
{
struct rds_message *rm;
- struct iovec *iov;
struct scatterlist *sg;
unsigned long to_copy;
- unsigned long iov_off;
unsigned long vec_off;
int copied;
int ret;
@@ -341,36 +338,20 @@ int rds_message_inc_copy_to_user(struct rds_incoming *inc,
rm = container_of(inc, struct rds_message, m_inc);
len = be32_to_cpu(rm->m_inc.i_hdr.h_len);
- iov = first_iov;
- iov_off = 0;
sg = rm->data.op_sg;
vec_off = 0;
copied = 0;
- while (copied < size && copied < len) {
- while (iov_off == iov->iov_len) {
- iov_off = 0;
- iov++;
- }
-
- to_copy = min(iov->iov_len - iov_off, sg->length - vec_off);
- to_copy = min_t(size_t, to_copy, size - copied);
+ while (iov_iter_count(to) && copied < len) {
+ to_copy = min(iov_iter_count(to), sg->length - vec_off);
to_copy = min_t(unsigned long, to_copy, len - copied);
- rdsdebug("copying %lu bytes to user iov [%p, %zu] + %lu to "
- "sg [%p, %u, %u] + %lu\n",
- to_copy, iov->iov_base, iov->iov_len, iov_off,
- sg_page(sg), sg->offset, sg->length, vec_off);
-
- ret = rds_page_copy_to_user(sg_page(sg), sg->offset + vec_off,
- iov->iov_base + iov_off,
- to_copy);
- if (ret) {
- copied = ret;
- break;
- }
+ rds_stats_add(s_copy_to_user, to_copy);
+ ret = copy_page_to_iter(sg_page(sg), sg->offset + vec_off,
+ to_copy, to);
+ if (ret != to_copy)
+ return -EFAULT;
- iov_off += to_copy;
vec_off += to_copy;
copied += to_copy;
diff --git a/net/rds/rds.h b/net/rds/rds.h
index 48f8ffc..b22dad9 100644
--- a/net/rds/rds.h
+++ b/net/rds/rds.h
@@ -431,8 +431,7 @@ struct rds_transport {
int (*xmit_rdma)(struct rds_connection *conn, struct rm_rdma_op *op);
int (*xmit_atomic)(struct rds_connection *conn, struct rm_atomic_op *op);
int (*recv)(struct rds_connection *conn);
- int (*inc_copy_to_user)(struct rds_incoming *inc, struct iovec *iov,
- size_t size);
+ int (*inc_copy_to_user)(struct rds_incoming *inc, struct iov_iter *to);
void (*inc_free)(struct rds_incoming *inc);
int (*cm_handle_connect)(struct rdma_cm_id *cm_id,
@@ -667,8 +666,7 @@ int rds_message_add_extension(struct rds_header *hdr,
int rds_message_next_extension(struct rds_header *hdr,
unsigned int *pos, void *buf, unsigned int *buflen);
int rds_message_add_rdma_dest_extension(struct rds_header *hdr, u32 r_key, u32 offset);
-int rds_message_inc_copy_to_user(struct rds_incoming *inc,
- struct iovec *first_iov, size_t size);
+int rds_message_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to);
void rds_message_inc_free(struct rds_incoming *inc);
void rds_message_addref(struct rds_message *rm);
void rds_message_put(struct rds_message *rm);
diff --git a/net/rds/recv.c b/net/rds/recv.c
index bd82522..47d7b10 100644
--- a/net/rds/recv.c
+++ b/net/rds/recv.c
@@ -404,6 +404,7 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
int ret = 0, nonblock = msg_flags & MSG_DONTWAIT;
DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name);
struct rds_incoming *inc = NULL;
+ struct iov_iter to;
/* udp_recvmsg()->sock_recvtimeo() gets away without locking too.. */
timeo = sock_rcvtimeo(sk, nonblock);
@@ -449,8 +450,8 @@ int rds_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
rdsdebug("copying inc %p from %pI4:%u to user\n", inc,
&inc->i_conn->c_faddr,
ntohs(inc->i_hdr.h_sport));
- ret = inc->i_conn->c_trans->inc_copy_to_user(inc, msg->msg_iov,
- size);
+ iov_iter_init(&to, READ, msg->msg_iov, msg->msg_iovlen, size);
+ ret = inc->i_conn->c_trans->inc_copy_to_user(inc, &to);
if (ret < 0)
break;
diff --git a/net/rds/tcp.h b/net/rds/tcp.h
index 6563749..0dbdd37 100644
--- a/net/rds/tcp.h
+++ b/net/rds/tcp.h
@@ -69,8 +69,7 @@ void rds_tcp_recv_exit(void);
void rds_tcp_data_ready(struct sock *sk);
int rds_tcp_recv(struct rds_connection *conn);
void rds_tcp_inc_free(struct rds_incoming *inc);
-int rds_tcp_inc_copy_to_user(struct rds_incoming *inc, struct iovec *iov,
- size_t size);
+int rds_tcp_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to);
/* tcp_send.c */
void rds_tcp_xmit_prepare(struct rds_connection *conn);
diff --git a/net/rds/tcp_recv.c b/net/rds/tcp_recv.c
index 9ae6e0a..fbc5ef8 100644
--- a/net/rds/tcp_recv.c
+++ b/net/rds/tcp_recv.c
@@ -59,50 +59,30 @@ void rds_tcp_inc_free(struct rds_incoming *inc)
/*
* this is pretty lame, but, whatever.
*/
-int rds_tcp_inc_copy_to_user(struct rds_incoming *inc, struct iovec *first_iov,
- size_t size)
+int rds_tcp_inc_copy_to_user(struct rds_incoming *inc, struct iov_iter *to)
{
struct rds_tcp_incoming *tinc;
- struct iovec *iov, tmp;
struct sk_buff *skb;
- unsigned long to_copy, skb_off;
int ret = 0;
- if (size == 0)
+ if (!iov_iter_count(to))
goto out;
tinc = container_of(inc, struct rds_tcp_incoming, ti_inc);
- iov = first_iov;
- tmp = *iov;
skb_queue_walk(&tinc->ti_skb_list, skb) {
- skb_off = 0;
- while (skb_off < skb->len) {
- while (tmp.iov_len == 0) {
- iov++;
- tmp = *iov;
- }
-
- to_copy = min(tmp.iov_len, size);
+ unsigned long to_copy, skb_off;
+ for (skb_off = 0; skb_off < skb->len; skb_off += to_copy) {
+ to_copy = iov_iter_count(to);
to_copy = min(to_copy, skb->len - skb_off);
- rdsdebug("ret %d size %zu skb %p skb_off %lu "
- "skblen %d iov_base %p iov_len %zu cpy %lu\n",
- ret, size, skb, skb_off, skb->len,
- tmp.iov_base, tmp.iov_len, to_copy);
-
- /* modifies tmp as it copies */
- if (skb_copy_datagram_iovec(skb, skb_off, &tmp,
- to_copy)) {
- ret = -EFAULT;
- goto out;
- }
+ if (skb_copy_datagram_iter(skb, skb_off, to, to_copy))
+ return -EFAULT;
rds_stats_add(s_copy_to_user, to_copy);
- size -= to_copy;
ret += to_copy;
- skb_off += to_copy;
- if (size == 0)
+
+ if (!iov_iter_count(to))
goto out;
}
}
--
1.7.10.4
^ permalink raw reply related
* [PATCH v2 15/17] [atm] switch vcc_sendmsg() to copy_from_iter()
From: Al Viro @ 2014-11-25 14:02 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-kernel
In-Reply-To: <20141125024018.GH7996@ZenIV.linux.org.uk>
From: Al Viro <viro@zeniv.linux.org.uk>
... and make it handle multi-segment iovecs - deals with that
"fix this later" issue for free. A bit of shame, really - it
had been there since 2.3.15pre3 when the whole thing went into the
tree, practically a historical artefact by now...
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
net/atm/common.c | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/net/atm/common.c b/net/atm/common.c
index 9cd1cca..f591129 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -570,15 +570,16 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
}
int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
- size_t total_len)
+ size_t size)
{
struct sock *sk = sock->sk;
DEFINE_WAIT(wait);
struct atm_vcc *vcc;
struct sk_buff *skb;
int eff, error;
- const void __user *buff;
- int size;
+ struct iov_iter from;
+
+ iov_iter_init(&from, WRITE, m->msg_iov, m->msg_iovlen, size);
lock_sock(sk);
if (sock->state != SS_CONNECTED) {
@@ -589,12 +590,6 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
error = -EISCONN;
goto out;
}
- if (m->msg_iovlen != 1) {
- error = -ENOSYS; /* fix this later @@@ */
- goto out;
- }
- buff = m->msg_iov->iov_base;
- size = m->msg_iov->iov_len;
vcc = ATM_SD(sock);
if (test_bit(ATM_VF_RELEASED, &vcc->flags) ||
test_bit(ATM_VF_CLOSE, &vcc->flags) ||
@@ -607,7 +602,7 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
error = 0;
goto out;
}
- if (size < 0 || size > vcc->qos.txtp.max_sdu) {
+ if (size > vcc->qos.txtp.max_sdu) {
error = -EMSGSIZE;
goto out;
}
@@ -639,7 +634,7 @@ int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
goto out;
skb->dev = NULL; /* for paths shared with net_device interfaces */
ATM_SKB(skb)->atm_options = vcc->atm_options;
- if (copy_from_user(skb_put(skb, size), buff, size)) {
+ if (copy_from_iter(skb_put(skb, size), size, &from) != size) {
kfree_skb(skb);
error = -EFAULT;
goto out;
--
1.7.10.4
^ permalink raw reply related
* [PATCH v2 14/17] vmci_transport: switch ->enqeue_dgram, ->enqueue_stream and ->dequeue_stream to msghdr
From: Al Viro @ 2014-11-25 14:02 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-kernel
In-Reply-To: <20141125024018.GH7996@ZenIV.linux.org.uk>
From: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
include/net/af_vsock.h | 6 +++---
net/vmw_vsock/af_vsock.c | 6 +++---
net/vmw_vsock/vmci_transport.c | 14 +++++++-------
3 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h
index 4282778..0d87674 100644
--- a/include/net/af_vsock.h
+++ b/include/net/af_vsock.h
@@ -103,14 +103,14 @@ struct vsock_transport {
int (*dgram_dequeue)(struct kiocb *kiocb, struct vsock_sock *vsk,
struct msghdr *msg, size_t len, int flags);
int (*dgram_enqueue)(struct vsock_sock *, struct sockaddr_vm *,
- struct iovec *, size_t len);
+ struct msghdr *, size_t len);
bool (*dgram_allow)(u32 cid, u32 port);
/* STREAM. */
/* TODO: stream_bind() */
- ssize_t (*stream_dequeue)(struct vsock_sock *, struct iovec *,
+ ssize_t (*stream_dequeue)(struct vsock_sock *, struct msghdr *,
size_t len, int flags);
- ssize_t (*stream_enqueue)(struct vsock_sock *, struct iovec *,
+ ssize_t (*stream_enqueue)(struct vsock_sock *, struct msghdr *,
size_t len);
s64 (*stream_has_data)(struct vsock_sock *);
s64 (*stream_has_space)(struct vsock_sock *);
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 85d232b..1d0e39c 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -1013,7 +1013,7 @@ static int vsock_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock,
goto out;
}
- err = transport->dgram_enqueue(vsk, remote_addr, msg->msg_iov, len);
+ err = transport->dgram_enqueue(vsk, remote_addr, msg, len);
out:
release_sock(sk);
@@ -1617,7 +1617,7 @@ static int vsock_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
*/
written = transport->stream_enqueue(
- vsk, msg->msg_iov,
+ vsk, msg,
len - total_written);
if (written < 0) {
err = -ENOMEM;
@@ -1739,7 +1739,7 @@ vsock_stream_recvmsg(struct kiocb *kiocb,
break;
read = transport->stream_dequeue(
- vsk, msg->msg_iov,
+ vsk, msg,
len - copied, flags);
if (read < 0) {
err = -ENOMEM;
diff --git a/net/vmw_vsock/vmci_transport.c b/net/vmw_vsock/vmci_transport.c
index a57ddef..c1c0389 100644
--- a/net/vmw_vsock/vmci_transport.c
+++ b/net/vmw_vsock/vmci_transport.c
@@ -1697,7 +1697,7 @@ static int vmci_transport_dgram_bind(struct vsock_sock *vsk,
static int vmci_transport_dgram_enqueue(
struct vsock_sock *vsk,
struct sockaddr_vm *remote_addr,
- struct iovec *iov,
+ struct msghdr *msg,
size_t len)
{
int err;
@@ -1714,7 +1714,7 @@ static int vmci_transport_dgram_enqueue(
if (!dg)
return -ENOMEM;
- memcpy_fromiovec(VMCI_DG_PAYLOAD(dg), iov, len);
+ memcpy_from_msg(VMCI_DG_PAYLOAD(dg), msg, len);
dg->dst = vmci_make_handle(remote_addr->svm_cid,
remote_addr->svm_port);
@@ -1835,22 +1835,22 @@ static int vmci_transport_connect(struct vsock_sock *vsk)
static ssize_t vmci_transport_stream_dequeue(
struct vsock_sock *vsk,
- struct iovec *iov,
+ struct msghdr *msg,
size_t len,
int flags)
{
if (flags & MSG_PEEK)
- return vmci_qpair_peekv(vmci_trans(vsk)->qpair, iov, len, 0);
+ return vmci_qpair_peekv(vmci_trans(vsk)->qpair, msg->msg_iov, len, 0);
else
- return vmci_qpair_dequev(vmci_trans(vsk)->qpair, iov, len, 0);
+ return vmci_qpair_dequev(vmci_trans(vsk)->qpair, msg->msg_iov, len, 0);
}
static ssize_t vmci_transport_stream_enqueue(
struct vsock_sock *vsk,
- struct iovec *iov,
+ struct msghdr *msg,
size_t len)
{
- return vmci_qpair_enquev(vmci_trans(vsk)->qpair, iov, len, 0);
+ return vmci_qpair_enquev(vmci_trans(vsk)->qpair, msg->msg_iov, len, 0);
}
static s64 vmci_transport_stream_has_data(struct vsock_sock *vsk)
--
1.7.10.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox