Re: [RFC RTNETLINK 04/09]: Link creation API

2007-06-06 Thread Patrick McHardy
Stephen Hemminger wrote:
 On Wed, 06 Jun 2007 01:17:11 +0200
 Patrick McHardy [EMAIL PROTECTED] wrote:
 
If you want I'll extend existing bridge netlink to use these.


Are you talking about brige-port information or bridge device
configuration? So far the API is not suitable for anything that
currently uses IFLA_PROTINFO because the sender is not the driver
which created the device and doesn't use AF_UNSPEC. For bridge
device configuration it would certainly be nice to have, but I'm
not sure yet how to handle enslave operations. So far my favourite
idea is to add enslave/release operations to rtnl_link_ops and call
them when IFLA_MASTER is set (so the netlink message would look like
this: ifindex: eth0 master: br0 nlmsg_type: RTM_NETLINK). But I
haven't really thought this through yet.
 
 
 Was thinking AF_BRIDGE (we have it already so use it), and both
 add/remove bridge, and enslave/unslave device.


I think we should use two seperate families for bridge devices
and bridge ports. I'll think about the enslave operation some
more and try to add it next week.
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC RTNETLINK 04/09]: Link creation API

2007-06-06 Thread Eric W. Biederman

 +static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 +{
 + struct rtnl_link_ops *ops;
 + struct net_device *dev;
 + struct ifinfomsg *ifm;
 + char name[MODULE_NAME_LEN];
 + char ifname[IFNAMSIZ];
 + struct nlattr *tb[IFLA_MAX+1];
 + struct nlattr *linkinfo[IFLA_INFO_MAX+1];
 + int err;
 +
 + err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
 + if (err  0)
 + return err;
 +
 + if (tb[IFLA_IFNAME])
 + nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
 + else
 + ifname[0] = '\0';
 +
 + ifm = nlmsg_data(nlh);
 + if (ifm-ifi_index  0)
 + dev = __dev_get_by_index(ifm-ifi_index);
 + else if (ifname[0])
 + dev = __dev_get_by_name(ifname);
 + else
 + dev = NULL;
 +
 + if (tb[IFLA_LINKINFO]) {
 + err = nla_parse_nested(linkinfo, IFLA_INFO_MAX,
 +tb[IFLA_LINKINFO], ifla_info_policy);
 + if (err  0)
 + return err;
 + } else
 + memset(linkinfo, 0, sizeof(linkinfo));
 +
 + if (linkinfo[IFLA_INFO_NAME]) {
 + nla_strlcpy(name, linkinfo[IFLA_INFO_NAME], sizeof(name));
 + ops = rtnl_link_ops_get(name);

Ugh.  Shouldn't we have the request_module logic here?
Otherwise it looks like we can skip the validate method and 
have other weird interactions.


 + } else {
 + name[0] = '\0';
 + ops = NULL;
 + }
 +
 + if (1) {
 + struct nlattr *attr[ops ? ops-maxtype + 1 : 0], **data = NULL;
 +
 + if (ops) {
 + if (ops-maxtype  linkinfo[IFLA_INFO_DATA]) {
 + err = nla_parse_nested(attr, ops-maxtype,
 + linkinfo[IFLA_INFO_DATA],
 +ops-policy);
 + if (err  0)
 + return err;
 + data = attr;
 + }
 + if (ops-validate) {
 + err = ops-validate(tb, data);
 + if (err  0)
 + return err;
 + }
 + }
 +
 + if (dev) {
 + int modified = 0;
 +
 + if (nlh-nlmsg_flags  NLM_F_EXCL)
 + return -EEXIST;
 + if (nlh-nlmsg_flags  NLM_F_REPLACE)
 + return -EOPNOTSUPP;
 +
 + if (linkinfo[IFLA_INFO_DATA]) {
 + if (!ops || ops != dev-rtnl_link_ops ||
 + !ops-changelink)
 + return -EOPNOTSUPP;
 +
 + err = ops-changelink(dev, tb, data);
 + if (err  0)
 + return err;
 + modified = 1;
 + }
 +
 + return do_setlink(dev, ifm, tb, ifname, modified);
 + }
 +
 + if (!(nlh-nlmsg_flags  NLM_F_CREATE))
 + return -ENODEV;
 +
 + if (ifm-ifi_index)
 + return -EINVAL;
 + if (tb[IFLA_ADDRESS] || tb[IFLA_BROADCAST] || tb[IFLA_MAP])
 + return -EOPNOTSUPP;
 +
 +#ifdef CONFIG_KMOD
 + if (!ops  name[0]) {
 + /* race condition: device may be created while rtnl is
 +  * unlocked, final register_netdevice will catch it.
 +  */
 + __rtnl_unlock();
 + request_module(rtnl-link-%s, name);
 + rtnl_lock();
 + ops = rtnl_link_ops_get(name);
 + }
 +#endif
 + if (!ops)
 + return -EOPNOTSUPP;

 +
 + if (!ifname[0])
 + snprintf(ifname, IFNAMSIZ, %s%%d, ops-name);
 + dev = alloc_netdev(ops-priv_size, ifname, ops-setup);
 + if (!dev)
 + return -ENOMEM;
 +
 + if (strchr(dev-name, '%')) {
 + err = dev_alloc_name(dev, dev-name);
 + if (err  0)
 + goto err_free;
 + }
 + dev-rtnl_link_ops = ops;
 +
 + if (tb[IFLA_MTU])
 + dev-mtu = nla_get_u32(tb[IFLA_MTU]);
 + if (tb[IFLA_TXQLEN])
 + dev-tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]);
 + if (tb[IFLA_WEIGHT])
 + dev-weight = nla_get_u32(tb[IFLA_WEIGHT]);
 + if (tb[IFLA_OPERSTATE])
 + set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]));
 + if (tb[IFLA_LINKMODE])
 + dev-link_mode = nla_get_u8(tb[IFLA_LINKMODE]);
 +
 +

Re: [RFC RTNETLINK 04/09]: Link creation API

2007-06-06 Thread Patrick McHardy
Eric W. Biederman wrote:
+ if (linkinfo[IFLA_INFO_NAME]) {
+ nla_strlcpy(name, linkinfo[IFLA_INFO_NAME], sizeof(name));
+ ops = rtnl_link_ops_get(name);
 
 
 Ugh.  Shouldn't we have the request_module logic here?
 Otherwise it looks like we can skip the validate method and 
 have other weird interactions.


Good catch. The easiest solution seems be to simply replay the
request after successful module load, which also avoids the
device lookup race.

Something like this (untested).

diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 8d2f817..f2868b0 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -930,6 +930,7 @@ static int rtnl_newlink(struct sk_buff *skb, struct 
nlmsghdr *nlh, void *arg)
struct nlattr *linkinfo[IFLA_INFO_MAX+1];
int err;
 
+replay:
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
if (err  0)
return err;
@@ -1012,19 +1013,19 @@ static int rtnl_newlink(struct sk_buff *skb, struct 
nlmsghdr *nlh, void *arg)
if (tb[IFLA_ADDRESS] || tb[IFLA_BROADCAST] || tb[IFLA_MAP])
return -EOPNOTSUPP;
 
+   if (!ops) {
 #ifdef CONFIG_KMOD
-   if (!ops  kind[0]) {
-   /* race condition: device may be created while rtnl is
-* unlocked, final register_netdevice will catch it.
-*/
-   __rtnl_unlock();
-   request_module(rtnl-link-%s, kind);
-   rtnl_lock();
-   ops = rtnl_link_ops_get(kind);
-   }
+   if (kind[0]) {
+   __rtnl_unlock();
+   request_module(rtnl-link-%s, kind);
+   rtnl_lock();
+   ops = rtnl_link_ops_get(kind);
+   if (ops)
+   goto replay;
+   }
 #endif
-   if (!ops)
return -EOPNOTSUPP;
+   }
 
if (!ifname[0])
snprintf(ifname, IFNAMSIZ, %s%%d, ops-kind);


Re: [RFC RTNETLINK 04/09]: Link creation API

2007-06-06 Thread Eric W. Biederman
Patrick McHardy [EMAIL PROTECTED] writes:

 Eric W. Biederman wrote:
+if (linkinfo[IFLA_INFO_NAME]) {
+nla_strlcpy(name, linkinfo[IFLA_INFO_NAME], sizeof(name));
+ops = rtnl_link_ops_get(name);
 
 
 Ugh.  Shouldn't we have the request_module logic here?
 Otherwise it looks like we can skip the validate method and 
 have other weird interactions.


 Good catch. The easiest solution seems be to simply replay the
 request after successful module load, which also avoids the
 device lookup race.

Looks reasonable to me.   There might be a variable or two that
we need to make certain is initialized but at a quick glance it
looks ok.

Eric


 Something like this (untested).

 diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
 index 8d2f817..f2868b0 100644
 --- a/net/core/rtnetlink.c
 +++ b/net/core/rtnetlink.c
 @@ -930,6 +930,7 @@ static int rtnl_newlink(struct sk_buff *skb, struct 
 nlmsghdr
 *nlh, void *arg)
   struct nlattr *linkinfo[IFLA_INFO_MAX+1];
   int err;
  
 +replay:
   err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
   if (err  0)
   return err;
 @@ -1012,19 +1013,19 @@ static int rtnl_newlink(struct sk_buff *skb, struct
 nlmsghdr *nlh, void *arg)
   if (tb[IFLA_ADDRESS] || tb[IFLA_BROADCAST] || tb[IFLA_MAP])
   return -EOPNOTSUPP;
  
 + if (!ops) {
  #ifdef CONFIG_KMOD
 - if (!ops  kind[0]) {
 - /* race condition: device may be created while rtnl is
 -  * unlocked, final register_netdevice will catch it.
 -  */
 - __rtnl_unlock();
 - request_module(rtnl-link-%s, kind);
 - rtnl_lock();
 - ops = rtnl_link_ops_get(kind);
 - }
 + if (kind[0]) {
 + __rtnl_unlock();
 + request_module(rtnl-link-%s, kind);
 + rtnl_lock();
 + ops = rtnl_link_ops_get(kind);
 + if (ops)
 + goto replay;
 + }
  #endif
 - if (!ops)
   return -EOPNOTSUPP;
 + }
  
   if (!ifname[0])
   snprintf(ifname, IFNAMSIZ, %s%%d, ops-kind);
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC RTNETLINK 04/09]: Link creation API

2007-06-05 Thread David Miller
From: Patrick McHardy [EMAIL PROTECTED]
Date: Tue,  5 Jun 2007 16:12:57 +0200 (MEST)

 [RTNETLINK]: Link creation API
 
 Add rtnetlink API for creating, changing and deleting software devices.
 
 Signed-off-by: Patrick McHardy [EMAIL PROTECTED]

Looks mostly fine, perhaps you can make even more use of 'const'
for instances of struct rtnl_link_ops * at least as function
arguments deeper in the implementation.
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC RTNETLINK 04/09]: Link creation API

2007-06-05 Thread Patrick McHardy
David Miller wrote:
 From: Patrick McHardy [EMAIL PROTECTED]
 Date: Tue,  5 Jun 2007 16:12:57 +0200 (MEST)
 
[RTNETLINK]: Link creation API

Add rtnetlink API for creating, changing and deleting software devices.

Signed-off-by: Patrick McHardy [EMAIL PROTECTED]
 
 
 Looks mostly fine, perhaps you can make even more use of 'const'
 for instances of struct rtnl_link_ops * at least as function
 arguments deeper in the implementation.


Good suggestion. I initially had rtnl_link_ops const everywhere
(since the lookup was by family I stored it in an array and didn't
need the list_head), then changed it to a list and removed all
consts. I'll add them back where possible.

-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC RTNETLINK 04/09]: Link creation API

2007-06-05 Thread Stephen Hemminger
On Tue,  5 Jun 2007 16:12:57 +0200 (MEST)
Patrick McHardy [EMAIL PROTECTED] wrote:

 [RTNETLINK]: Link creation API
 
 Add rtnetlink API for creating, changing and deleting software devices.
 
 Signed-off-by: Patrick McHardy [EMAIL PROTECTED]
 

If you want I'll extend existing bridge netlink to use these.

-- 
Stephen Hemminger [EMAIL PROTECTED]
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC RTNETLINK 04/09]: Link creation API

2007-06-05 Thread Patrick McHardy
Stephen Hemminger wrote:
 On Tue,  5 Jun 2007 16:12:57 +0200 (MEST)
 Patrick McHardy [EMAIL PROTECTED] wrote:
 
 
[RTNETLINK]: Link creation API

Add rtnetlink API for creating, changing and deleting software devices.

Signed-off-by: Patrick McHardy [EMAIL PROTECTED]

 
 If you want I'll extend existing bridge netlink to use these.


Are you talking about brige-port information or bridge device
configuration? So far the API is not suitable for anything that
currently uses IFLA_PROTINFO because the sender is not the driver
which created the device and doesn't use AF_UNSPEC. For bridge
device configuration it would certainly be nice to have, but I'm
not sure yet how to handle enslave operations. So far my favourite
idea is to add enslave/release operations to rtnl_link_ops and call
them when IFLA_MASTER is set (so the netlink message would look like
this: ifindex: eth0 master: br0 nlmsg_type: RTM_NETLINK). But I
haven't really thought this through yet.

I would also like to add support for handling secondary device state
like bridge port state and others that currently use IFLA_PROTINFO
(a lot of the code is very similar to the generic code), but all ideas
so far turned out not to work very well.

I'm leaving for a short vacation until Sunday tommorrow, so replies
may be delayed :)
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC RTNETLINK 04/09]: Link creation API

2007-06-05 Thread Stephen Hemminger
On Wed, 06 Jun 2007 01:17:11 +0200
Patrick McHardy [EMAIL PROTECTED] wrote:

 Stephen Hemminger wrote:
  On Tue,  5 Jun 2007 16:12:57 +0200 (MEST)
  Patrick McHardy [EMAIL PROTECTED] wrote:
  
  
 [RTNETLINK]: Link creation API
 
 Add rtnetlink API for creating, changing and deleting software devices.
 
 Signed-off-by: Patrick McHardy [EMAIL PROTECTED]
 
  
  If you want I'll extend existing bridge netlink to use these.
 
 
 Are you talking about brige-port information or bridge device
 configuration? So far the API is not suitable for anything that
 currently uses IFLA_PROTINFO because the sender is not the driver
 which created the device and doesn't use AF_UNSPEC. For bridge
 device configuration it would certainly be nice to have, but I'm
 not sure yet how to handle enslave operations. So far my favourite
 idea is to add enslave/release operations to rtnl_link_ops and call
 them when IFLA_MASTER is set (so the netlink message would look like
 this: ifindex: eth0 master: br0 nlmsg_type: RTM_NETLINK). But I
 haven't really thought this through yet.

Was thinking AF_BRIDGE (we have it already so use it), and both
add/remove bridge, and enslave/unslave device.


 I would also like to add support for handling secondary device state
 like bridge port state and others that currently use IFLA_PROTINFO
 (a lot of the code is very similar to the generic code), but all ideas
 so far turned out not to work very well.
 
 I'm leaving for a short vacation until Sunday tommorrow, so replies
 may be delayed :)


-- 
Stephen Hemminger [EMAIL PROTECTED]
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html