]> git.neil.brown.name Git - history.git/commitdiff
[NET]: Increase MAX_ADDR_LEN.
authorRoland Dreier <roland@topspin.com>
Mon, 6 Jan 2003 17:06:34 +0000 (09:06 -0800)
committerDavid S. Miller <davem@kernel.bkbits.net>
Mon, 6 Jan 2003 17:06:34 +0000 (09:06 -0800)
- 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.

include/linux/if_arp.h
include/linux/netdevice.h
include/linux/rtnetlink.h
net/core/dev.c
net/core/rtnetlink.c

index dd936fe6180ea6c541800345f45eeb9891bd3df6..77906e130efdac3288127e99a675bc64048fef74 100644 (file)
@@ -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
index 513b89ca78365c1674ae16630eabaaa004d0a0fc..b3026b172369baa75ea1071a4e417f095fd7aa0f 100644 (file)
@@ -65,7 +65,7 @@ struct vlan_group;
 
 #endif
 
-#define MAX_ADDR_LEN                 /* Largest hardware address length */
+#define MAX_ADDR_LEN   32              /* Largest hardware address length */
 
 /*
  *     Compute the worst case header length according to the protocols
index 57296f48dc0293d71340b617478a3052cbfe4514..40ceec3335863f3cd91df1b94e73fbf6806679c9 100644 (file)
@@ -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)
index 72f606980694eacdc80fd4984a7c8fce52316df8..3246a37067c52e561626471741a86ab21429adf8 100644 (file)
@@ -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;
index 1702d8aa0ad07821dbdd15ebc20e76a0d1d246a1..e324ae6f75f33e3ceafa3de2387a6b19e4fe597e 100644 (file)
@@ -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;