Commit 4f85bc95 authored by Roland Dreier's avatar Roland Dreier Committed by David S. Miller

[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.
parent ae4d9837
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#define ARPHRD_METRICOM 23 /* Metricom STRIP (new IANA id) */ #define ARPHRD_METRICOM 23 /* Metricom STRIP (new IANA id) */
#define ARPHRD_IEEE1394 24 /* IEEE 1394 IPv4 - RFC 2734 */ #define ARPHRD_IEEE1394 24 /* IEEE 1394 IPv4 - RFC 2734 */
#define ARPHRD_EUI64 27 /* EUI-64 */ #define ARPHRD_EUI64 27 /* EUI-64 */
#define ARPHRD_INFINIBAND 32 /* InfiniBand */
/* Dummy types for non ARP hardware */ /* Dummy types for non ARP hardware */
#define ARPHRD_SLIP 256 #define ARPHRD_SLIP 256
......
...@@ -65,7 +65,7 @@ struct vlan_group; ...@@ -65,7 +65,7 @@ struct vlan_group;
#endif #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 * Compute the worst case header length according to the protocols
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#define RTM_NEWLINK (RTM_BASE+0) #define RTM_NEWLINK (RTM_BASE+0)
#define RTM_DELLINK (RTM_BASE+1) #define RTM_DELLINK (RTM_BASE+1)
#define RTM_GETLINK (RTM_BASE+2) #define RTM_GETLINK (RTM_BASE+2)
#define RTM_SETLINK (RTM_BASE+3)
#define RTM_NEWADDR (RTM_BASE+4) #define RTM_NEWADDR (RTM_BASE+4)
#define RTM_DELADDR (RTM_BASE+5) #define RTM_DELADDR (RTM_BASE+5)
......
...@@ -2131,7 +2131,7 @@ static int dev_ifsioc(struct ifreq *ifr, unsigned int cmd) ...@@ -2131,7 +2131,7 @@ static int dev_ifsioc(struct ifreq *ifr, unsigned int cmd)
case SIOCGIFHWADDR: case SIOCGIFHWADDR:
memcpy(ifr->ifr_hwaddr.sa_data, dev->dev_addr, 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; ifr->ifr_hwaddr.sa_family = dev->type;
return 0; return 0;
...@@ -2152,7 +2152,7 @@ static int dev_ifsioc(struct ifreq *ifr, unsigned int cmd) ...@@ -2152,7 +2152,7 @@ static int dev_ifsioc(struct ifreq *ifr, unsigned int cmd)
if (ifr->ifr_hwaddr.sa_family != dev->type) if (ifr->ifr_hwaddr.sa_family != dev->type)
return -EINVAL; return -EINVAL;
memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data, 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, notifier_call_chain(&netdev_chain,
NETDEV_CHANGEADDR, dev); NETDEV_CHANGEADDR, dev);
return 0; return 0;
......
...@@ -220,6 +220,40 @@ int rtnetlink_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -220,6 +220,40 @@ int rtnetlink_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
return skb->len; 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 rtnetlink_dump_all(struct sk_buff *skb, struct netlink_callback *cb)
{ {
int idx; int idx;
...@@ -457,33 +491,15 @@ static void rtnetlink_rcv(struct sock *sk, int len) ...@@ -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] = static struct rtnetlink_link link_rtnetlink_table[RTM_MAX-RTM_BASE+1] =
{ {
{ NULL, NULL, }, [RTM_GETLINK - RTM_BASE] = { .dumpit = rtnetlink_dump_ifinfo },
{ NULL, NULL, }, [RTM_SETLINK - RTM_BASE] = { .doit = do_setlink },
{ NULL, rtnetlink_dump_ifinfo, }, [RTM_GETADDR - RTM_BASE] = { .dumpit = rtnetlink_dump_all },
{ NULL, NULL, }, [RTM_GETROUTE - RTM_BASE] = { .dumpit = rtnetlink_dump_all },
[RTM_NEWNEIGH - RTM_BASE] = { .doit = neigh_add },
{ NULL, NULL, }, [RTM_DELNEIGH - RTM_BASE] = { .doit = neigh_delete },
{ NULL, NULL, }, [RTM_GETNEIGH - RTM_BASE] = { .dumpit = neigh_dump_info }
{ 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, },
}; };
static int rtnetlink_event(struct notifier_block *this, unsigned long event, void *ptr) static int rtnetlink_event(struct notifier_block *this, unsigned long event, void *ptr)
{ {
struct net_device *dev = ptr; struct net_device *dev = ptr;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment