diff options
| author | Roland Dreier <roland@topspin.com> | 2003-01-06 09:06:34 -0800 |
|---|---|---|
| committer | David S. Miller <davem@kernel.bkbits.net> | 2003-01-06 09:06:34 -0800 |
| commit | 4f85bc95dedb42855fe6ea88ec0353497997f964 (patch) | |
| tree | e085c810ee0cea03102c67d5d6c4724a42635fa2 | |
| parent | ae4d98378f651581ece95d133fd65a811e5bb8d5 (diff) | |
[NET]: Increase MAX_ADDR_LEN.
- Add ARPHRD_INFINIBAND
- Increase MAX_ADDR_LEN to 32 from 8
- Add suitable length protection to SIOCGIFHWADDR and friends.
- Add RTM_SETLINK for portably setting larger hw addrs.
| -rw-r--r-- | include/linux/if_arp.h | 1 | ||||
| -rw-r--r-- | include/linux/netdevice.h | 2 | ||||
| -rw-r--r-- | include/linux/rtnetlink.h | 1 | ||||
| -rw-r--r-- | net/core/dev.c | 4 | ||||
| -rw-r--r-- | net/core/rtnetlink.c | 66 |
5 files changed, 46 insertions, 28 deletions
diff --git a/include/linux/if_arp.h b/include/linux/if_arp.h index dd936fe6180e..77906e130efd 100644 --- a/include/linux/if_arp.h +++ b/include/linux/if_arp.h @@ -40,6 +40,7 @@ #define ARPHRD_METRICOM 23 /* Metricom STRIP (new IANA id) */ #define ARPHRD_IEEE1394 24 /* IEEE 1394 IPv4 - RFC 2734 */ #define ARPHRD_EUI64 27 /* EUI-64 */ +#define ARPHRD_INFINIBAND 32 /* InfiniBand */ /* Dummy types for non ARP hardware */ #define ARPHRD_SLIP 256 diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 513b89ca7836..b3026b172369 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -65,7 +65,7 @@ struct vlan_group; #endif -#define MAX_ADDR_LEN 8 /* Largest hardware address length */ +#define MAX_ADDR_LEN 32 /* Largest hardware address length */ /* * Compute the worst case header length according to the protocols diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index 57296f48dc02..40ceec333586 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -17,6 +17,7 @@ #define RTM_NEWLINK (RTM_BASE+0) #define RTM_DELLINK (RTM_BASE+1) #define RTM_GETLINK (RTM_BASE+2) +#define RTM_SETLINK (RTM_BASE+3) #define RTM_NEWADDR (RTM_BASE+4) #define RTM_DELADDR (RTM_BASE+5) diff --git a/net/core/dev.c b/net/core/dev.c index 72f606980694..3246a37067c5 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2131,7 +2131,7 @@ static int dev_ifsioc(struct ifreq *ifr, unsigned int cmd) case SIOCGIFHWADDR: memcpy(ifr->ifr_hwaddr.sa_data, dev->dev_addr, - MAX_ADDR_LEN); + min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len)); ifr->ifr_hwaddr.sa_family = dev->type; return 0; @@ -2152,7 +2152,7 @@ static int dev_ifsioc(struct ifreq *ifr, unsigned int cmd) if (ifr->ifr_hwaddr.sa_family != dev->type) return -EINVAL; memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data, - MAX_ADDR_LEN); + min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len)); notifier_call_chain(&netdev_chain, NETDEV_CHANGEADDR, dev); return 0; diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 1702d8aa0ad0..e324ae6f75f3 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -220,6 +220,40 @@ int rtnetlink_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) return skb->len; } +static int do_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) +{ + struct ifinfomsg *ifm = NLMSG_DATA(nlh); + struct rtattr **ida = arg; + struct net_device *dev; + int err; + + dev = dev_get_by_index(ifm->ifi_index); + if (!dev) + return -ENODEV; + + err = -EINVAL; + + if (ida[IFLA_ADDRESS - 1]) { + if (ida[IFLA_ADDRESS - 1]->rta_len != RTA_LENGTH(dev->addr_len)) + goto out; + memcpy(dev->dev_addr, RTA_DATA(ida[IFLA_ADDRESS - 1]), + dev->addr_len); + } + + if (ida[IFLA_BROADCAST - 1]) { + if (ida[IFLA_BROADCAST - 1]->rta_len != RTA_LENGTH(dev->addr_len)) + goto out; + memcpy(dev->broadcast, RTA_DATA(ida[IFLA_BROADCAST - 1]), + dev->addr_len); + } + + err = 0; + +out: + dev_put(dev); + return err; +} + int rtnetlink_dump_all(struct sk_buff *skb, struct netlink_callback *cb) { int idx; @@ -457,33 +491,15 @@ static void rtnetlink_rcv(struct sock *sk, int len) static struct rtnetlink_link link_rtnetlink_table[RTM_MAX-RTM_BASE+1] = { - { NULL, NULL, }, - { NULL, NULL, }, - { NULL, rtnetlink_dump_ifinfo, }, - { NULL, NULL, }, - - { NULL, NULL, }, - { NULL, NULL, }, - { NULL, rtnetlink_dump_all, }, - { NULL, NULL, }, - - { NULL, NULL, }, - { NULL, NULL, }, - { NULL, rtnetlink_dump_all, }, - { NULL, NULL, }, - - { neigh_add, NULL, }, - { neigh_delete, NULL, }, - { NULL, neigh_dump_info, }, - { NULL, NULL, }, - - { NULL, NULL, }, - { NULL, NULL, }, - { NULL, NULL, }, - { NULL, NULL, }, + [RTM_GETLINK - RTM_BASE] = { .dumpit = rtnetlink_dump_ifinfo }, + [RTM_SETLINK - RTM_BASE] = { .doit = do_setlink }, + [RTM_GETADDR - RTM_BASE] = { .dumpit = rtnetlink_dump_all }, + [RTM_GETROUTE - RTM_BASE] = { .dumpit = rtnetlink_dump_all }, + [RTM_NEWNEIGH - RTM_BASE] = { .doit = neigh_add }, + [RTM_DELNEIGH - RTM_BASE] = { .doit = neigh_delete }, + [RTM_GETNEIGH - RTM_BASE] = { .dumpit = neigh_dump_info } }; - static int rtnetlink_event(struct notifier_block *this, unsigned long event, void *ptr) { struct net_device *dev = ptr; |
