From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jiri Pirko Subject: Re: [patch net-next 0/4] net: allow to change carrier from userspace Date: Wed, 12 Dec 2012 19:10:17 +0100 Message-ID: <20121212181017.GB3060@minipsycho.orion> References: <1355309887-1081-1-git-send-email-jiri@resnulli.us> <20121212081500.24085752@nehalam.linuxnetplumber.net> <20121212170520.GA3060@minipsycho.orion> <20121212092700.7ef2607a@nehalam.linuxnetplumber.net> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Cc: netdev@vger.kernel.org, davem@davemloft.net, edumazet@google.com, bhutchings@solarflare.com, mirqus@gmail.com, greearb@candelatech.com, fbl@redhat.com To: Stephen Hemminger Return-path: Received: from mail-ee0-f46.google.com ([74.125.83.46]:51644 "EHLO mail-ee0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753531Ab2LLSKW (ORCPT ); Wed, 12 Dec 2012 13:10:22 -0500 Received: by mail-ee0-f46.google.com with SMTP id e53so682470eek.19 for ; Wed, 12 Dec 2012 10:10:20 -0800 (PST) Content-Disposition: inline In-Reply-To: <20121212092700.7ef2607a@nehalam.linuxnetplumber.net> Sender: netdev-owner@vger.kernel.org List-ID: Wed, Dec 12, 2012 at 06:27:00PM CET, shemminger@vyatta.com wrote: >On Wed, 12 Dec 2012 18:05:20 +0100 >Jiri Pirko wrote: > >> Wed, Dec 12, 2012 at 05:15:00PM CET, shemminger@vyatta.com wrote: >> >On Wed, 12 Dec 2012 11:58:03 +0100 >> >Jiri Pirko wrote: >> > >> >> This is basically a repost of my previous patchset: >> >> "[patch net-next-2.6 0/2] net: allow to change carrier via sysfs" from Aug 30 >> >> >> >> The way net-sysfs stores values changed and this patchset reflects it. >> >> Also, I exposed carrier via rtnetlink iface. >> >> >> >> So far, only dummy driver uses carrier change ndo. In very near future >> >> team driver will use that as well. >> >> >> >> Jiri Pirko (4): >> >> net: add change_carrier netdev op >> >> net: allow to change carrier via sysfs >> >> rtnl: expose carrier value with possibility to set it >> >> dummy: implement carrier change >> >> >> >> drivers/net/dummy.c | 10 ++++++++++ >> >> include/linux/netdevice.h | 7 +++++++ >> >> include/uapi/linux/if_link.h | 1 + >> >> net/core/dev.c | 19 +++++++++++++++++++ >> >> net/core/net-sysfs.c | 15 ++++++++++++++- >> >> net/core/rtnetlink.c | 10 ++++++++++ >> >> 6 files changed, 61 insertions(+), 1 deletion(-) >> >> >> > >> >I needed to do the same thing for a project we are working on and discovered >> >that there already is a working documented interface for doing that via >> >operstate mode. Therefore I can't recommend that the additional complexity >> >of a new API for this is required. >> >> I might be missing something, but I'm unable to find how operstate set >> can affect value returned by netif_carrier_ok() >> -- >> 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 > >Here is an example using dummy device using libmnl. It is also possible >with ip commands. > ># modprobe dummy ># ip li show dev dummy0 >12: dummy0: mtu 1500 qdisc noop state DOWN mode DEFAULT > link/ether ce:90:46:83:6e:f8 brd ff:ff:ff:ff:ff:ff ># ./dummy dummy0 init ># ip li show dev dummy0 >12: dummy0: mtu 1500 qdisc noop state DOWN mode DORMANT > link/ether ce:90:46:83:6e:f8 brd ff:ff:ff:ff:ff:ff ># ip li set dummy0 up ># ip li show dev dummy0 >12: dummy0: mtu 1500 qdisc noqueue state UNKNOWN mode DORMANT > link/ether ce:90:46:83:6e:f8 brd ff:ff:ff:ff:ff:ff ># ./dummy dummy0 down ># ip li show dev dummy0 >12: dummy0: mtu 1500 qdisc noqueue state DORMANT mode DORMANT if you mean this "NO-CARRIER" it has no direct relation with netif_carrier_ok(). > link/ether ce:90:46:83:6e:f8 brd ff:ff:ff:ff:ff:ff ># ./dummy dummy0 up ># ip li show dev dummy0 >12: dummy0: mtu 1500 qdisc noqueue state UP mode DORMANT > link/ether ce:90:46:83:6e:f8 brd ff:ff:ff:ff:ff:ff > > >/* Sample program to control link mode and link state */ >#include >#include >#include >#include >#include >#include >#include >#include >#include >#include > >#include >#include >#include > >static void panic(const char *str) >{ > perror(str); > exit(1); >} > >static void usage(const char *cmd) >{ > fprintf(stderr, "Usage: %s dummyX [up|down|init]\n", cmd); > exit(1); >} > >/* Send request and parse response */ >static void mnl_talk(struct mnl_socket *nl, struct nlmsghdr *nlh) >{ > unsigned portid = mnl_socket_get_portid(nl); > uint32_t seq = time(NULL); > char buf[MNL_SOCKET_BUFFER_SIZE]; > > nlh->nlmsg_flags |= NLM_F_ACK; > nlh->nlmsg_seq = seq; > > if (mnl_socket_sendto(nl, nlh, nlh->nlmsg_len) < 0) > panic("mnl_socket_sendto failed"); > > int ret = mnl_socket_recvfrom(nl, buf, sizeof(buf)); > if (ret < 0) > panic("mnl_socket_recvfrom"); > > if ( mnl_cb_run(buf, ret, seq, portid, NULL, NULL) < 0) > panic("mnl_cb_run"); >} > >static void linkstate(struct mnl_socket *nl, > const char *ifname, unsigned int state) >{ > char buf[MNL_SOCKET_BUFFER_SIZE]; > struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf); > nlh->nlmsg_type = RTM_NEWLINK; > nlh->nlmsg_flags = NLM_F_REQUEST; > > struct ifinfomsg *ifi; > ifi = mnl_nlmsg_put_extra_header(nlh, sizeof(struct ifinfomsg)); > ifi->ifi_family = AF_UNSPEC; > > mnl_attr_put_strz(nlh, IFLA_IFNAME, ifname); > mnl_attr_put_u8(nlh, IFLA_OPERSTATE, state); > > mnl_talk(nl, nlh); >} > >/* Set device link mode */ >static void init(struct mnl_socket *nl, const char *ifname) >{ > char buf[MNL_SOCKET_BUFFER_SIZE]; > struct nlmsghdr *nlh = mnl_nlmsg_put_header(buf); > nlh->nlmsg_type = RTM_NEWLINK; > nlh->nlmsg_flags = NLM_F_REQUEST; > > struct ifinfomsg *ifi; > ifi = mnl_nlmsg_put_extra_header(nlh, sizeof(struct ifinfomsg)); > ifi->ifi_family = AF_UNSPEC; > > mnl_attr_put_strz(nlh, IFLA_IFNAME, ifname); > mnl_attr_put_u8(nlh, IFLA_LINKMODE, IF_LINK_MODE_DORMANT); > mnl_talk(nl, nlh); >} > >int main(int argc, char **argv) >{ > if (argc != 3) > usage(argv[0]); > > struct mnl_socket *nl = mnl_socket_open(NETLINK_ROUTE); > if (!nl) > panic("mnl_socket_open"); > > if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) > panic("mnl_socket_bind"); > > > if (strcmp(argv[2], "init") == 0) > init(nl, argv[1]); > else if (strcmp(argv[2], "up") == 0) > linkstate(nl, argv[1], IF_OPER_UP); > else if (strcmp(argv[2], "down") == 0) > linkstate(nl, argv[1], IF_OPER_DORMANT); > else > usage(argv[0]); > > return 0; >} > >