aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@vyatta.com>2008-09-23 00:28:11 -0400
committerDavid S. Miller <davem@davemloft.net>2008-09-23 00:28:11 -0400
commit0b815a1a6d43ab498674b8430c8c35ab08487a16 (patch)
tree18ea2e50f36c1d38127c535f619e80209bfc4e07 /net/core
parent83bfba5fca16d040bb78a24148da844db3de6a76 (diff)
net: network device name ifalias support
This patch add support for keeping an additional character alias associated with an network interface. This is useful for maintaining the SNMP ifAlias value which is a user defined value. Routers use this to hold information like which circuit or line it is connected to. It is just an arbitrary text label on the network device. There are two exposed interfaces with this patch, the value can be read/written either via netlink or sysfs. This could be maintained just by the snmp daemon, but it is more generally useful for other management tools, and the kernel is good place to act as an agreed upon interface to store it. Signed-off-by: Stephen Hemminger <shemminger@vyatta.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/dev.c23
-rw-r--r--net/core/net-sysfs.c36
-rw-r--r--net/core/rtnetlink.c13
3 files changed, 72 insertions, 0 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index fdfc4b6a6448..e91390533999 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -954,6 +954,29 @@ rollback:
954} 954}
955 955
956/** 956/**
957 * dev_set_alias - change ifalias of a device
958 * @dev: device
959 * @alias: name up to IFALIASZ
960 *
961 * Set ifalias for a device,
962 */
963int dev_set_alias(struct net_device *dev, const char *alias, size_t len)
964{
965 ASSERT_RTNL();
966
967 if (len >= IFALIASZ)
968 return -EINVAL;
969
970 dev->ifalias = krealloc(dev->ifalias, len+1, GFP_KERNEL);
971 if (!dev->ifalias)
972 return -ENOMEM;
973
974 strlcpy(dev->ifalias, alias, len+1);
975 return len;
976}
977
978
979/**
957 * netdev_features_change - device changes features 980 * netdev_features_change - device changes features
958 * @dev: device to cause notification 981 * @dev: device to cause notification
959 * 982 *
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index c1f4e0d428c0..92d6b9467314 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -209,9 +209,44 @@ static ssize_t store_tx_queue_len(struct device *dev,
209 return netdev_store(dev, attr, buf, len, change_tx_queue_len); 209 return netdev_store(dev, attr, buf, len, change_tx_queue_len);
210} 210}
211 211
212static ssize_t store_ifalias(struct device *dev, struct device_attribute *attr,
213 const char *buf, size_t len)
214{
215 struct net_device *netdev = to_net_dev(dev);
216 size_t count = len;
217 ssize_t ret;
218
219 if (!capable(CAP_NET_ADMIN))
220 return -EPERM;
221
222 /* ignore trailing newline */
223 if (len > 0 && buf[len - 1] == '\n')
224 --count;
225
226 rtnl_lock();
227 ret = dev_set_alias(netdev, buf, count);
228 rtnl_unlock();
229
230 return ret < 0 ? ret : len;
231}
232
233static ssize_t show_ifalias(struct device *dev,
234 struct device_attribute *attr, char *buf)
235{
236 const struct net_device *netdev = to_net_dev(dev);
237 ssize_t ret = 0;
238
239 rtnl_lock();
240 if (netdev->ifalias)
241 ret = sprintf(buf, "%s\n", netdev->ifalias);
242 rtnl_unlock();
243 return ret;
244}
245
212static struct device_attribute net_class_attributes[] = { 246static struct device_attribute net_class_attributes[] = {
213 __ATTR(addr_len, S_IRUGO, show_addr_len, NULL), 247 __ATTR(addr_len, S_IRUGO, show_addr_len, NULL),
214 __ATTR(dev_id, S_IRUGO, show_dev_id, NULL), 248 __ATTR(dev_id, S_IRUGO, show_dev_id, NULL),
249 __ATTR(ifalias, S_IRUGO | S_IWUSR, show_ifalias, store_ifalias),
215 __ATTR(iflink, S_IRUGO, show_iflink, NULL), 250 __ATTR(iflink, S_IRUGO, show_iflink, NULL),
216 __ATTR(ifindex, S_IRUGO, show_ifindex, NULL), 251 __ATTR(ifindex, S_IRUGO, show_ifindex, NULL),
217 __ATTR(features, S_IRUGO, show_features, NULL), 252 __ATTR(features, S_IRUGO, show_features, NULL),
@@ -418,6 +453,7 @@ static void netdev_release(struct device *d)
418 453
419 BUG_ON(dev->reg_state != NETREG_RELEASED); 454 BUG_ON(dev->reg_state != NETREG_RELEASED);
420 455
456 kfree(dev->ifalias);
421 kfree((char *)dev - dev->padded); 457 kfree((char *)dev - dev->padded);
422} 458}
423 459
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 71edb8b36341..8862498fd4a6 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -586,6 +586,7 @@ static inline size_t if_nlmsg_size(const struct net_device *dev)
586{ 586{
587 return NLMSG_ALIGN(sizeof(struct ifinfomsg)) 587 return NLMSG_ALIGN(sizeof(struct ifinfomsg))
588 + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */ 588 + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
589 + nla_total_size(IFALIASZ) /* IFLA_IFALIAS */
589 + nla_total_size(IFNAMSIZ) /* IFLA_QDISC */ 590 + nla_total_size(IFNAMSIZ) /* IFLA_QDISC */
590 + nla_total_size(sizeof(struct rtnl_link_ifmap)) 591 + nla_total_size(sizeof(struct rtnl_link_ifmap))
591 + nla_total_size(sizeof(struct rtnl_link_stats)) 592 + nla_total_size(sizeof(struct rtnl_link_stats))
@@ -640,6 +641,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
640 if (txq->qdisc_sleeping) 641 if (txq->qdisc_sleeping)
641 NLA_PUT_STRING(skb, IFLA_QDISC, txq->qdisc_sleeping->ops->id); 642 NLA_PUT_STRING(skb, IFLA_QDISC, txq->qdisc_sleeping->ops->id);
642 643
644 if (dev->ifalias)
645 NLA_PUT_STRING(skb, IFLA_IFALIAS, dev->ifalias);
646
643 if (1) { 647 if (1) {
644 struct rtnl_link_ifmap map = { 648 struct rtnl_link_ifmap map = {
645 .mem_start = dev->mem_start, 649 .mem_start = dev->mem_start,
@@ -713,6 +717,7 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = {
713 [IFLA_LINKMODE] = { .type = NLA_U8 }, 717 [IFLA_LINKMODE] = { .type = NLA_U8 },
714 [IFLA_LINKINFO] = { .type = NLA_NESTED }, 718 [IFLA_LINKINFO] = { .type = NLA_NESTED },
715 [IFLA_NET_NS_PID] = { .type = NLA_U32 }, 719 [IFLA_NET_NS_PID] = { .type = NLA_U32 },
720 [IFLA_IFALIAS] = { .type = NLA_STRING, .len = IFALIASZ-1 },
716}; 721};
717 722
718static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = { 723static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
@@ -853,6 +858,14 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
853 modified = 1; 858 modified = 1;
854 } 859 }
855 860
861 if (tb[IFLA_IFALIAS]) {
862 err = dev_set_alias(dev, nla_data(tb[IFLA_IFALIAS]),
863 nla_len(tb[IFLA_IFALIAS]));
864 if (err < 0)
865 goto errout;
866 modified = 1;
867 }
868
856 if (tb[IFLA_BROADCAST]) { 869 if (tb[IFLA_BROADCAST]) {
857 nla_memcpy(dev->broadcast, tb[IFLA_BROADCAST], dev->addr_len); 870 nla_memcpy(dev->broadcast, tb[IFLA_BROADCAST], dev->addr_len);
858 send_addr_notify = 1; 871 send_addr_notify = 1;