rtnl: expose carrier value with possibility to set it
authorJiri Pirko <jiri@resnulli.us>
Thu, 27 Dec 2012 23:49:39 +0000 (23:49 +0000)
committerDavid S. Miller <davem@davemloft.net>
Fri, 28 Dec 2012 23:24:18 +0000 (15:24 -0800)
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Acked-by: Flavio Leitner <fbl@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Documentation/networking/operstates.txt
include/uapi/linux/if_link.h
net/core/rtnetlink.c

index 1a77a3c..9769457 100644 (file)
@@ -88,6 +88,10 @@ set this flag. On netif_carrier_off(), the scheduler stops sending
 packets. The name 'carrier' and the inversion are historical, think of
 it as lower layer.
 
+Note that for certain kind of soft-devices, which are not managing any
+real hardware, there is possible to set this bit from userpsace.
+One should use TVL IFLA_CARRIER to do so.
+
 netif_carrier_ok() can be used to query that bit.
 
 __LINK_STATE_DORMANT, maps to IFF_DORMANT:
index 60f3b6b..c4edfe1 100644 (file)
@@ -142,6 +142,7 @@ enum {
 #define IFLA_PROMISCUITY IFLA_PROMISCUITY
        IFLA_NUM_TX_QUEUES,
        IFLA_NUM_RX_QUEUES,
+       IFLA_CARRIER,
        __IFLA_MAX
 };
 
index 1868625..2ef7a56 100644 (file)
@@ -780,6 +780,7 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev,
               + nla_total_size(4) /* IFLA_MTU */
               + nla_total_size(4) /* IFLA_LINK */
               + nla_total_size(4) /* IFLA_MASTER */
+              + nla_total_size(1) /* IFLA_CARRIER */
               + nla_total_size(4) /* IFLA_PROMISCUITY */
               + nla_total_size(4) /* IFLA_NUM_TX_QUEUES */
               + nla_total_size(4) /* IFLA_NUM_RX_QUEUES */
@@ -909,6 +910,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
             nla_put_u32(skb, IFLA_LINK, dev->iflink)) ||
            (dev->master &&
             nla_put_u32(skb, IFLA_MASTER, dev->master->ifindex)) ||
+           nla_put_u8(skb, IFLA_CARRIER, netif_carrier_ok(dev)) ||
            (dev->qdisc &&
             nla_put_string(skb, IFLA_QDISC, dev->qdisc->ops->id)) ||
            (dev->ifalias &&
@@ -1108,6 +1110,7 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = {
        [IFLA_MTU]              = { .type = NLA_U32 },
        [IFLA_LINK]             = { .type = NLA_U32 },
        [IFLA_MASTER]           = { .type = NLA_U32 },
+       [IFLA_CARRIER]          = { .type = NLA_U8 },
        [IFLA_TXQLEN]           = { .type = NLA_U32 },
        [IFLA_WEIGHT]           = { .type = NLA_U32 },
        [IFLA_OPERSTATE]        = { .type = NLA_U8 },
@@ -1438,6 +1441,13 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
                modified = 1;
        }
 
+       if (tb[IFLA_CARRIER]) {
+               err = dev_change_carrier(dev, nla_get_u8(tb[IFLA_CARRIER]));
+               if (err)
+                       goto errout;
+               modified = 1;
+       }
+
        if (tb[IFLA_TXQLEN])
                dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]);