From 892d6187fc9fff86524adef180726b7139211c3e Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Mon, 12 Jan 2004 23:04:43 -0800 Subject: [COMPAT]: Mark SIOCSIFNAME as compatible ioctl. --- include/linux/compat_ioctl.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/compat_ioctl.h b/include/linux/compat_ioctl.h index d87c417544bc..2a72386d5303 100644 --- a/include/linux/compat_ioctl.h +++ b/include/linux/compat_ioctl.h @@ -260,6 +260,7 @@ COMPATIBLE_IOCTL(SIOCATMARK) COMPATIBLE_IOCTL(SIOCSIFLINK) COMPATIBLE_IOCTL(SIOCSIFENCAP) COMPATIBLE_IOCTL(SIOCGIFENCAP) +COMPATIBLE_IOCTL(SIOCSIFNAME) COMPATIBLE_IOCTL(SIOCSIFBR) COMPATIBLE_IOCTL(SIOCGIFBR) COMPATIBLE_IOCTL(SIOCSARP) -- cgit v1.2.3 From 7aeea3693303e63c8196f17c81bb1e974b911390 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 12 Jan 2004 23:46:26 -0800 Subject: [COMPAT]: Support wireless ioctls, with help from Clint Adams. --- fs/compat_ioctl.c | 57 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/compat_ioctl.h | 31 ++++++++++++++++++++++++ 2 files changed, 88 insertions(+) (limited to 'include/linux') diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index bfd4938a1627..534e87dadded 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c @@ -65,6 +65,7 @@ #include #include #include +#include #include /* siocdevprivate_ioctl */ #include @@ -2970,6 +2971,48 @@ static int do_i2c_smbus_ioctl(unsigned int fd, unsigned int cmd, unsigned long a return sys_ioctl(fd, cmd, (unsigned long)tdata); } +struct compat_iw_point { + compat_caddr_t pointer; + __u16 length; + __u16 flags; +}; + +static int do_wireless_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg) +{ + struct iwreq *iwr, *iwr_u; + struct iw_point *iwp; + struct compat_iw_point *iwp_u; + compat_caddr_t pointer; + __u16 length, flags; + + iwr_u = (struct iwreq *) compat_ptr(arg); + iwp_u = (struct compat_iw_point *) &iwr_u->u.data; + iwr = compat_alloc_user_space(sizeof(*iwr)); + if (iwr == NULL) + return -ENOMEM; + + iwp = &iwr->u.data; + + if (verify_area(VERIFY_WRITE, iwr, sizeof(*iwr))) + return -EFAULT; + + if (__copy_in_user(&iwr->ifr_ifrn.ifrn_name[0], + &iwr_u->ifr_ifrn.ifrn_name[0], + sizeof(iwr->ifr_ifrn.ifrn_name))) + return -EFAULT; + + if (__get_user(pointer, &iwp_u->pointer) || + __get_user(length, &iwp_u->length) || + __get_user(flags, &iwp_u->flags)) + return -EFAULT; + + if (__put_user(compat_ptr(pointer), &iwp->pointer) || + __put_user(length, &iwp->length) || + __put_user(flags, &iwp->flags)) + return -EFAULT; + + return sys_ioctl(fd, cmd, (unsigned long) iwr); +} #undef CODE #endif @@ -3133,6 +3176,20 @@ HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal) HANDLE_IOCTL(I2C_FUNCS, w_long) HANDLE_IOCTL(I2C_RDWR, do_i2c_rdwr_ioctl) HANDLE_IOCTL(I2C_SMBUS, do_i2c_smbus_ioctl) +/* wireless */ +HANDLE_IOCTL(SIOCGIWRANGE, do_wireless_ioctl) +HANDLE_IOCTL(SIOCSIWSPY, do_wireless_ioctl) +HANDLE_IOCTL(SIOCGIWSPY, do_wireless_ioctl) +HANDLE_IOCTL(SIOCSIWTHRSPY, do_wireless_ioctl) +HANDLE_IOCTL(SIOCGIWTHRSPY, do_wireless_ioctl) +HANDLE_IOCTL(SIOCGIWAPLIST, do_wireless_ioctl) +HANDLE_IOCTL(SIOCGIWSCAN, do_wireless_ioctl) +HANDLE_IOCTL(SIOCSIWESSID, do_wireless_ioctl) +HANDLE_IOCTL(SIOCGIWESSID, do_wireless_ioctl) +HANDLE_IOCTL(SIOCSIWNICKN, do_wireless_ioctl) +HANDLE_IOCTL(SIOCGIWNICKN, do_wireless_ioctl) +HANDLE_IOCTL(SIOCSIWENCODE, do_wireless_ioctl) +HANDLE_IOCTL(SIOCGIWENCODE, do_wireless_ioctl) #undef DECLARES #endif diff --git a/include/linux/compat_ioctl.h b/include/linux/compat_ioctl.h index 2a72386d5303..37c5a35ff237 100644 --- a/include/linux/compat_ioctl.h +++ b/include/linux/compat_ioctl.h @@ -686,3 +686,34 @@ COMPATIBLE_IOCTL(I2C_TENBIT) COMPATIBLE_IOCTL(I2C_PEC) COMPATIBLE_IOCTL(I2C_RETRIES) COMPATIBLE_IOCTL(I2C_TIMEOUT) +/* wireless */ +COMPATIBLE_IOCTL(SIOCSIWCOMMIT) +COMPATIBLE_IOCTL(SIOCGIWNAME) +COMPATIBLE_IOCTL(SIOCSIWNWID) +COMPATIBLE_IOCTL(SIOCGIWNWID) +COMPATIBLE_IOCTL(SIOCSIWFREQ) +COMPATIBLE_IOCTL(SIOCGIWFREQ) +COMPATIBLE_IOCTL(SIOCSIWMODE) +COMPATIBLE_IOCTL(SIOCGIWMODE) +COMPATIBLE_IOCTL(SIOCSIWSENS) +COMPATIBLE_IOCTL(SIOCGIWSENS) +COMPATIBLE_IOCTL(SIOCSIWRANGE) +COMPATIBLE_IOCTL(SIOCSIWPRIV) +COMPATIBLE_IOCTL(SIOCGIWPRIV) +COMPATIBLE_IOCTL(SIOCSIWSTATS) +COMPATIBLE_IOCTL(SIOCGIWSTATS) +COMPATIBLE_IOCTL(SIOCSIWAP) +COMPATIBLE_IOCTL(SIOCGIWAP) +COMPATIBLE_IOCTL(SIOCSIWSCAN) +COMPATIBLE_IOCTL(SIOCSIWRATE) +COMPATIBLE_IOCTL(SIOCGIWRATE) +COMPATIBLE_IOCTL(SIOCSIWRTS) +COMPATIBLE_IOCTL(SIOCGIWRTS) +COMPATIBLE_IOCTL(SIOCSIWFRAG) +COMPATIBLE_IOCTL(SIOCGIWFRAG) +COMPATIBLE_IOCTL(SIOCSIWTXPOW) +COMPATIBLE_IOCTL(SIOCGIWTXPOW) +COMPATIBLE_IOCTL(SIOCSIWRETRY) +COMPATIBLE_IOCTL(SIOCGIWRETRY) +COMPATIBLE_IOCTL(SIOCSIWPOWER) +COMPATIBLE_IOCTL(SIOCGIWPOWER) -- cgit v1.2.3 From 3c1ea2a57f835a46d08b20d72b2c3c8bc4e9c2a0 Mon Sep 17 00:00:00 2001 From: Shirley Ma Date: Wed, 14 Jan 2004 08:58:20 -0800 Subject: [IPV6]: Implement MIB:ipv6InterfaceTable --- include/linux/rtnetlink.h | 12 ++++++++- include/net/if_inet6.h | 1 + include/net/ndisc.h | 11 +++++++++ include/net/neighbour.h | 10 ++++++-- net/core/neighbour.c | 7 +++++- net/ipv4/arp.c | 2 +- net/ipv4/devinet.c | 4 +-- net/ipv6/addrconf.c | 62 ++++++++++++++++++++++++++++++++++++++++------- net/ipv6/ndisc.c | 22 ++++++++++++++++- 9 files changed, 114 insertions(+), 17 deletions(-) (limited to 'include/linux') diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index 4a26f207b5d7..db1966e24462 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -558,9 +558,18 @@ enum IFLA_INET6_CONF, /* sysctl parameters */ IFLA_INET6_STATS, /* statistics */ IFLA_INET6_MCAST, /* MC things. What of them? */ + IFLA_INET6_CACHEINFO, /* time values and max reasm size */ }; -#define IFLA_INET6_MAX IFLA_INET6_MCAST +struct ifla_cacheinfo +{ + __u32 max_reasm_len; + __u32 tstamp; /* ipv6InterfaceTable updated timestamp */ + __u32 reachable_time; + __u32 retrans_time; +}; + +#define IFLA_INET6_MAX IFLA_INET6_CACHEINFO /***************************************************************** * Traffic control messages. @@ -611,6 +620,7 @@ enum #define RTMGRP_IPV6_IFADDR 0x100 #define RTMGRP_IPV6_MROUTE 0x200 #define RTMGRP_IPV6_ROUTE 0x400 +#define RTMGRP_IPV6_IFINFO 0x800 #define RTMGRP_DECnet_IFADDR 0x1000 #define RTMGRP_DECnet_ROUTE 0x4000 diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h index 6dd6ebda5e6f..4ef8526494d2 100644 --- a/include/net/if_inet6.h +++ b/include/net/if_inet6.h @@ -183,6 +183,7 @@ struct inet6_dev struct inet6_dev *next; struct ipv6_devconf cnf; struct ipv6_devstat stats; + unsigned long tstamp; /* ipv6InterfaceTable update timestamp */ }; extern struct ipv6_devconf ipv6_devconf; diff --git a/include/net/ndisc.h b/include/net/ndisc.h index d364fc636912..95684d3363c1 100644 --- a/include/net/ndisc.h +++ b/include/net/ndisc.h @@ -98,6 +98,17 @@ extern int igmp6_event_report(struct sk_buff *skb); extern void igmp6_cleanup(void); +#ifdef CONFIG_SYSCTL +extern int ndisc_ifinfo_sysctl_change(ctl_table *ctl, + int write, + struct file * filp, + void __user *buffer, + size_t *lenp); +#endif + +extern void inet6_ifinfo_notify(int event, + struct inet6_dev *idev); + static inline struct neighbour * ndisc_get_neigh(struct net_device *dev, struct in6_addr *addr) { diff --git a/include/net/neighbour.h b/include/net/neighbour.h index 24bee28fd7fb..e016389694a8 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h @@ -47,6 +47,9 @@ #include #include +#ifdef CONFIG_SYSCTL +#include +#endif #define NUD_IN_TIMER (NUD_INCOMPLETE|NUD_DELAY|NUD_PROBE) #define NUD_VALID (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE|NUD_PROBE|NUD_STALE|NUD_DELAY) @@ -206,8 +209,11 @@ extern int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg); extern int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg); extern void neigh_app_ns(struct neighbour *n); -extern int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p, - int p_id, int pdev_id, char *p_name); +extern int neigh_sysctl_register(struct net_device *dev, + struct neigh_parms *p, + int p_id, int pdev_id, + char *p_name, + proc_handler *proc_handler); extern void neigh_sysctl_unregister(struct neigh_parms *p); /* diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 4b194b6be05a..c1b4a4496309 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -1629,7 +1629,8 @@ struct neigh_sysctl_table { }; int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p, - int p_id, int pdev_id, char *p_name) + int p_id, int pdev_id, char *p_name, + proc_handler *handler) { struct neigh_sysctl_table *t = kmalloc(sizeof(*t), GFP_KERNEL); const char *dev_name_source = NULL; @@ -1643,6 +1644,10 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p, t->neigh_vars[1].data = &p->ucast_probes; t->neigh_vars[2].data = &p->app_probes; t->neigh_vars[3].data = &p->retrans_time; + if (handler) { + t->neigh_vars[3].proc_handler = handler; + t->neigh_vars[3].extra1 = dev; + } t->neigh_vars[4].data = &p->base_reachable_time; t->neigh_vars[5].data = &p->delay_probe_time; t->neigh_vars[6].data = &p->gc_staletime; diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index dc026cfacd3d..5c03f63502bc 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -1122,7 +1122,7 @@ void __init arp_init(void) arp_proc_init(); #ifdef CONFIG_SYSCTL neigh_sysctl_register(NULL, &arp_tbl.parms, NET_IPV4, - NET_IPV4_NEIGH, "ipv4"); + NET_IPV4_NEIGH, "ipv4", NULL); #endif register_netdevice_notifier(&arp_netdev_notifier); } diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index fe58fb5b59da..4bdfd7319ae6 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -155,7 +155,7 @@ struct in_device *inetdev_init(struct net_device *dev) dev_hold(dev); #ifdef CONFIG_SYSCTL neigh_sysctl_register(dev, in_dev->arp_parms, NET_IPV4, - NET_IPV4_NEIGH, "ipv4"); + NET_IPV4_NEIGH, "ipv4", NULL); #endif write_lock_bh(&inetdev_lock); dev->ip_ptr = in_dev; @@ -910,7 +910,7 @@ static int inetdev_event(struct notifier_block *this, unsigned long event, devinet_sysctl_unregister(&in_dev->cnf); neigh_sysctl_unregister(in_dev->arp_parms); neigh_sysctl_register(dev, in_dev->arp_parms, NET_IPV4, - NET_IPV4_NEIGH, "ipv4"); + NET_IPV4_NEIGH, "ipv4", NULL); devinet_sysctl_register(in_dev, &in_dev->cnf); #endif break; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index b614c23b0e14..237a4c933680 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -373,9 +373,10 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev) write_unlock_bh(&addrconf_lock); ipv6_mc_init_dev(ndev); - + ndev->tstamp = jiffies; #ifdef CONFIG_SYSCTL - neigh_sysctl_register(dev, ndev->nd_parms, NET_IPV6, NET_IPV6_NEIGH, "ipv6"); + neigh_sysctl_register(dev, ndev->nd_parms, NET_IPV6, + NET_IPV6_NEIGH, "ipv6", &ndisc_ifinfo_sysctl_change); addrconf_sysctl_register(ndev, &ndev->cnf); #endif } @@ -1890,6 +1891,8 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, rt6_mtu_change(dev, dev->mtu); idev->cnf.mtu6 = dev->mtu; } + idev->tstamp = jiffies; + inet6_ifinfo_notify(RTM_NEWLINK, idev); /* If the changed mtu during down is lower than IPV6_MIN_MTU stop IPv6 on this interface. */ @@ -1921,7 +1924,7 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event, if (idev) { addrconf_sysctl_unregister(&idev->cnf); neigh_sysctl_unregister(idev->nd_parms); - neigh_sysctl_register(dev, idev->nd_parms, NET_IPV6, NET_IPV6_NEIGH, "ipv6"); + neigh_sysctl_register(dev, idev->nd_parms, NET_IPV6, NET_IPV6_NEIGH, "ipv6", &ndisc_ifinfo_sysctl_change); addrconf_sysctl_register(idev, &idev->cnf); } #endif @@ -2031,6 +2034,10 @@ static int addrconf_ifdown(struct net_device *dev, int how) else ipv6_mc_down(idev); + /* Step 5: netlink notification of this interface */ + idev->tstamp = jiffies; + inet6_ifinfo_notify(RTM_NEWLINK, idev); + /* Shot the device (if unregistered) */ if (how == 1) { @@ -2732,17 +2739,19 @@ static void inline ipv6_store_devconf(struct ipv6_devconf *cnf, #endif } -static int inet6_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, - struct inet6_dev *idev, - int type, u32 pid, u32 seq) +static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, + u32 pid, u32 seq, int event) { + struct net_device *dev = idev->dev; __s32 *array = NULL; struct ifinfomsg *r; struct nlmsghdr *nlh; unsigned char *b = skb->tail; struct rtattr *subattr; + __u32 mtu = dev->mtu; + struct ifla_cacheinfo ci; - nlh = NLMSG_PUT(skb, pid, seq, type, sizeof(*r)); + nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*r)); if (pid) nlh->nlmsg_flags |= NLM_F_MULTI; r = NLMSG_DATA(nlh); r->ifi_family = AF_INET6; @@ -2757,6 +2766,13 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, RTA_PUT(skb, IFLA_IFNAME, strlen(dev->name)+1, dev->name); + if (dev->addr_len) + RTA_PUT(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr); + + RTA_PUT(skb, IFLA_MTU, sizeof(mtu), &mtu); + if (dev->ifindex != dev->iflink) + RTA_PUT(skb, IFLA_LINK, sizeof(int), &dev->iflink); + subattr = (struct rtattr*)skb->tail; RTA_PUT(skb, IFLA_PROTINFO, 0, NULL); @@ -2764,6 +2780,14 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, /* return the device flags */ RTA_PUT(skb, IFLA_INET6_FLAGS, sizeof(__u32), &idev->if_flags); + /* return interface cacheinfo */ + ci.max_reasm_len = IPV6_MAXPLEN; + ci.tstamp = (__u32)(TIME_DELTA(idev->tstamp, INITIAL_JIFFIES) / HZ * 100 + + TIME_DELTA(idev->tstamp, INITIAL_JIFFIES) % HZ * 100 / HZ); + ci.reachable_time = idev->nd_parms->reachable_time; + ci.retrans_time = idev->nd_parms->retrans_time; + RTA_PUT(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci); + /* return the device sysctl params */ if ((array = kmalloc(DEVCONF_MAX * sizeof(*array), GFP_ATOMIC)) == NULL) goto rtattr_failure; @@ -2798,8 +2822,8 @@ static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) continue; if ((idev = in6_dev_get(dev)) == NULL) continue; - err = inet6_fill_ifinfo(skb, dev, idev, RTM_NEWLINK, - NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq); + err = inet6_fill_ifinfo(skb, idev, NETLINK_CB(cb->skb).pid, + cb->nlh->nlmsg_seq, RTM_NEWLINK); in6_dev_put(idev); if (err <= 0) break; @@ -2810,6 +2834,26 @@ static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) return skb->len; } +void inet6_ifinfo_notify(int event, struct inet6_dev *idev) +{ + struct sk_buff *skb; + /* 128 bytes ?? */ + int size = NLMSG_SPACE(sizeof(struct ifinfomsg)+128); + + skb = alloc_skb(size, GFP_ATOMIC); + if (!skb) { + netlink_set_err(rtnl, 0, RTMGRP_IPV6_IFINFO, ENOBUFS); + return; + } + if (inet6_fill_ifinfo(skb, idev, 0, 0, event) < 0) { + kfree_skb(skb); + netlink_set_err(rtnl, 0, RTMGRP_IPV6_IFINFO, EINVAL); + return; + } + NETLINK_CB(skb).dst_groups = RTMGRP_IPV6_IFINFO; + netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV6_IFINFO, GFP_ATOMIC); +} + static struct rtnetlink_link inet6_rtnetlink_table[RTM_MAX - RTM_BASE + 1] = { [RTM_GETLINK - RTM_BASE] = { .dumpit = inet6_dump_ifinfo, }, [RTM_NEWADDR - RTM_BASE] = { .doit = inet6_rtm_newaddr, }, diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index f2e7c8bb7fe9..f725744e6d48 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -1115,6 +1115,8 @@ static void ndisc_router_discovery(struct sk_buff *skb) if (rtime < HZ/10) rtime = HZ/10; in6_dev->nd_parms->retrans_time = rtime; + in6_dev->tstamp = jiffies; + inet6_ifinfo_notify(RTM_NEWLINK, in6_dev); } rtime = ntohl(ra_msg->reachable_time); @@ -1128,6 +1130,8 @@ static void ndisc_router_discovery(struct sk_buff *skb) in6_dev->nd_parms->base_reachable_time = rtime; in6_dev->nd_parms->gc_staletime = 3 * rtime; in6_dev->nd_parms->reachable_time = neigh_rand_reach_time(rtime); + in6_dev->tstamp = jiffies; + inet6_ifinfo_notify(RTM_NEWLINK, in6_dev); } } } @@ -1492,6 +1496,21 @@ struct notifier_block ndisc_netdev_notifier = { .notifier_call = ndisc_netdev_event, }; +#ifdef CONFIG_SYSCTL +int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write, struct file * filp, void __user *buffer, size_t *lenp) +{ + struct net_device *dev = ctl->extra1; + struct inet6_dev *idev; + + if (write && dev && (idev = in6_dev_get(dev)) != NULL) { + idev->tstamp = jiffies; + inet6_ifinfo_notify(RTM_NEWLINK, idev); + in6_dev_put(idev); + } + return proc_dointvec(ctl, write, filp, buffer, lenp); +} +#endif + int __init ndisc_init(struct net_proto_family *ops) { struct ipv6_pinfo *np; @@ -1522,7 +1541,8 @@ int __init ndisc_init(struct net_proto_family *ops) neigh_table_init(&nd_tbl); #ifdef CONFIG_SYSCTL - neigh_sysctl_register(NULL, &nd_tbl.parms, NET_IPV6, NET_IPV6_NEIGH, "ipv6"); + neigh_sysctl_register(NULL, &nd_tbl.parms, NET_IPV6, NET_IPV6_NEIGH, + "ipv6", &ndisc_ifinfo_sysctl_change); #endif register_netdevice_notifier(&ndisc_netdev_notifier); -- cgit v1.2.3 From 60872d54d963eefeb302ebeae15204e4be229c2b Mon Sep 17 00:00:00 2001 From: Shirley Ma Date: Wed, 14 Jan 2004 09:01:45 -0800 Subject: [IPV6]: Add notification for MIB:ipv6Prefix events. --- include/linux/rtnetlink.h | 35 +++++++++++++++++++++++++- include/net/if_inet6.h | 4 +++ net/ipv6/addrconf.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index db1966e24462..6cfd6f2f4a98 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -44,7 +44,10 @@ #define RTM_DELTFILTER (RTM_BASE+29) #define RTM_GETTFILTER (RTM_BASE+30) -#define RTM_MAX (RTM_BASE+31) +#define RTM_NEWPREFIX (RTM_BASE+36) +#define RTM_GETPREFIX (RTM_BASE+38) + +#define RTM_MAX (RTM_BASE+39) /* Generic structure for encapsulation of optional route information. @@ -459,6 +462,34 @@ struct ifinfomsg unsigned ifi_change; /* IFF_* change mask */ }; +/******************************************************************** + * prefix information + ****/ + +struct prefixmsg +{ + unsigned char prefix_family; + int prefix_ifindex; + unsigned char prefix_type; + unsigned char prefix_len; + unsigned char prefix_flags; +}; + +enum +{ + PREFIX_UNSPEC, + PREFIX_ADDRESS, + PREFIX_CACHEINFO, +}; + +#define PREFIX_MAX PREFIX_CACHEINFO + +struct prefix_cacheinfo +{ + __u32 preferred_time; + __u32 valid_time; +}; + /* The struct should be in sync with struct net_device_stats */ struct rtnl_link_stats { @@ -625,6 +656,8 @@ enum #define RTMGRP_DECnet_IFADDR 0x1000 #define RTMGRP_DECnet_ROUTE 0x4000 +#define RTMGRP_IPV6_PREFIX 0x20000 + /* End of information exported to user level */ #ifdef __KERNEL__ diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h index 4ef8526494d2..48280b138cb9 100644 --- a/include/net/if_inet6.h +++ b/include/net/if_inet6.h @@ -25,6 +25,10 @@ #define IF_RA_RCVD 0x20 #define IF_RS_SENT 0x10 +/* prefix flags */ +#define IF_PREFIX_ONLINK 0x01 +#define IF_PREFIX_AUTOCONF 0x02 + #ifdef __KERNEL__ struct inet6_ifaddr diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 237a4c933680..6f1dc6fba0a4 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -138,6 +138,8 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp); static void addrconf_rs_timer(unsigned long data); static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa); +static void inet6_prefix_notify(int event, struct inet6_dev *idev, + struct prefix_info *pinfo); static int ipv6_chk_same_addr(const struct in6_addr *addr, struct net_device *dev); static struct notifier_block *inet6addr_chain; @@ -1492,6 +1494,7 @@ ok: addrconf_verify(0); } } + inet6_prefix_notify(RTM_NEWPREFIX, in6_dev, pinfo); in6_dev_put(in6_dev); } @@ -2854,6 +2857,66 @@ void inet6_ifinfo_notify(int event, struct inet6_dev *idev) netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV6_IFINFO, GFP_ATOMIC); } +static int inet6_fill_prefix(struct sk_buff *skb, struct inet6_dev *idev, + struct prefix_info *pinfo, u32 pid, u32 seq, int event) +{ + struct prefixmsg *pmsg; + struct nlmsghdr *nlh; + unsigned char *b = skb->tail; + struct prefix_cacheinfo ci; + + nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*pmsg)); + + if (pid) + nlh->nlmsg_flags |= NLM_F_MULTI; + + pmsg = NLMSG_DATA(nlh); + pmsg->prefix_family = AF_INET6; + pmsg->prefix_ifindex = idev->dev->ifindex; + pmsg->prefix_len = pinfo->prefix_len; + pmsg->prefix_type = pinfo->type; + + pmsg->prefix_flags = 0; + if (pinfo->onlink) + pmsg->prefix_flags |= IF_PREFIX_ONLINK; + if (pinfo->autoconf) + pmsg->prefix_flags |= IF_PREFIX_AUTOCONF; + + RTA_PUT(skb, PREFIX_ADDRESS, sizeof(pinfo->prefix), &pinfo->prefix); + + ci.preferred_time = ntohl(pinfo->prefered); + ci.valid_time = ntohl(pinfo->valid); + RTA_PUT(skb, PREFIX_CACHEINFO, sizeof(ci), &ci); + + nlh->nlmsg_len = skb->tail - b; + return skb->len; + +nlmsg_failure: +rtattr_failure: + skb_trim(skb, b - skb->data); + return -1; +} + +static void inet6_prefix_notify(int event, struct inet6_dev *idev, + struct prefix_info *pinfo) +{ + struct sk_buff *skb; + int size = NLMSG_SPACE(sizeof(struct prefixmsg)+128); + + skb = alloc_skb(size, GFP_ATOMIC); + if (!skb) { + netlink_set_err(rtnl, 0, RTMGRP_IPV6_PREFIX, ENOBUFS); + return; + } + if (inet6_fill_prefix(skb, idev, pinfo, 0, 0, event) < 0) { + kfree_skb(skb); + netlink_set_err(rtnl, 0, RTMGRP_IPV6_PREFIX, EINVAL); + return; + } + NETLINK_CB(skb).dst_groups = RTMGRP_IPV6_PREFIX; + netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV6_PREFIX, GFP_ATOMIC); +} + static struct rtnetlink_link inet6_rtnetlink_table[RTM_MAX - RTM_BASE + 1] = { [RTM_GETLINK - RTM_BASE] = { .dumpit = inet6_dump_ifinfo, }, [RTM_NEWADDR - RTM_BASE] = { .doit = inet6_rtm_newaddr, }, -- cgit v1.2.3 From c21c7b412096f85b650241a189f79bb10f1a48bd Mon Sep 17 00:00:00 2001 From: Hideaki Yoshifuji Date: Wed, 14 Jan 2004 22:15:23 -0800 Subject: [IPV6]: Allow per-device max addresses configurable via sysctl. --- Documentation/networking/ip-sysctl.txt | 7 +++++++ include/linux/ipv6.h | 2 ++ include/linux/sysctl.h | 3 ++- include/net/addrconf.h | 2 ++ net/ipv6/addrconf.c | 23 +++++++++++++++++++---- 5 files changed, 32 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 030a5b67313a..f2b360b5ef0e 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt @@ -667,6 +667,13 @@ regen_max_retry - INTEGER valid temporary addresses. Default: 5 +max_addresses - INTEGER + Number of maximum addresses per interface. 0 disables limitation. + It is recommended not set too large value (or 0) because it would + be too easy way to crash kernel to allow to create too much of + autoconfigured addresses. + Default: 16 + icmp/*: ratelimit - INTEGER Limit the maximal rates for sending ICMPv6 packets. diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 7f5a5c4280f7..e073162776fa 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -143,6 +143,7 @@ struct ipv6_devconf { __s32 regen_max_retry; __s32 max_desync_factor; #endif + __s32 max_addresses; void *sysctl; }; @@ -165,6 +166,7 @@ enum { DEVCONF_REGEN_MAX_RETRY, DEVCONF_MAX_DESYNC_FACTOR, #endif + DEVCONF_MAX_ADDRESSES, DEVCONF_MAX }; diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index c94fb1d1862a..de7b8b5bc523 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -418,7 +418,8 @@ enum { NET_IPV6_TEMP_VALID_LFT=12, NET_IPV6_TEMP_PREFERED_LFT=13, NET_IPV6_REGEN_MAX_RETRY=14, - NET_IPV6_MAX_DESYNC_FACTOR=15 + NET_IPV6_MAX_DESYNC_FACTOR=15, + NET_IPV6_MAX_ADDRESSES=16 }; /* /proc/sys/net/ipv6/icmp */ diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 54fd7773f5b1..92cbb7794cac 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -15,6 +15,8 @@ #define ADDR_CHECK_FREQUENCY (120*HZ) +#define IPV6_MAX_ADDRESSES 16 + struct prefix_info { __u8 type; __u8 length; diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 6f1dc6fba0a4..d20f6647bc70 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -81,8 +81,6 @@ #include #include -#define IPV6_MAX_ADDRESSES 16 - /* Set to 3 to get tracing... */ #define ACONF_DEBUG 2 @@ -162,6 +160,7 @@ struct ipv6_devconf ipv6_devconf = { .regen_max_retry = REGEN_MAX_RETRY, .max_desync_factor = MAX_DESYNC_FACTOR, #endif + .max_addresses = IPV6_MAX_ADDRESSES, }; static struct ipv6_devconf ipv6_devconf_dflt = { @@ -182,6 +181,7 @@ static struct ipv6_devconf ipv6_devconf_dflt = { .regen_max_retry = REGEN_MAX_RETRY, .max_desync_factor = MAX_DESYNC_FACTOR, #endif + .max_addresses = IPV6_MAX_ADDRESSES, }; /* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */ @@ -633,6 +633,7 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i unsigned long tmp_prefered_lft, tmp_valid_lft; int tmp_plen; int ret = 0; + int max_addresses; if (ift) { spin_lock_bh(&ift->lock); @@ -688,9 +689,11 @@ retry: ifp->prefered_lft, idev->cnf.temp_prefered_lft - desync_factor / HZ); tmp_plen = ifp->prefix_len; + max_addresses = idev->cnf.max_addresses; write_unlock(&idev->lock); spin_unlock_bh(&ifp->lock); - ift = ipv6_count_addresses(idev) < IPV6_MAX_ADDRESSES ? + ift = !max_addresses || + ipv6_count_addresses(idev) < max_addresses ? ipv6_add_addr(idev, &addr, tmp_plen, ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, IFA_F_TEMPORARY) : 0; if (!ift || IS_ERR(ift)) { @@ -1393,10 +1396,13 @@ ok: ifp = ipv6_get_ifaddr(&addr, dev); if (ifp == NULL && valid_lft) { + int max_addresses = in6_dev->cnf.max_addresses; + /* Do not allow to create too much of autoconfigured * addresses; this would be too easy way to crash kernel. */ - if (ipv6_count_addresses(in6_dev) < IPV6_MAX_ADDRESSES) + if (!max_addresses || + ipv6_count_addresses(in6_dev) < max_addresses) ifp = ipv6_add_addr(in6_dev, &addr, pinfo->prefix_len, addr_type&IPV6_ADDR_SCOPE_MASK, 0); @@ -2740,6 +2746,7 @@ static void inline ipv6_store_devconf(struct ipv6_devconf *cnf, array[DEVCONF_REGEN_MAX_RETRY] = cnf->regen_max_retry; array[DEVCONF_MAX_DESYNC_FACTOR] = cnf->max_desync_factor; #endif + array[DEVCONF_MAX_ADDRESSES] = cnf->max_addresses; } static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, @@ -3165,6 +3172,14 @@ static struct addrconf_sysctl_table .proc_handler = &proc_dointvec, }, #endif + { + .ctl_name = NET_IPV6_MAX_ADDRESSES, + .procname = "max_addresses", + .data = &ipv6_devconf.max_addresses, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, }, .addrconf_dev = { { -- cgit v1.2.3 From 60cb2439cf78ac5fa4d37c94361538d9865a5898 Mon Sep 17 00:00:00 2001 From: Hideaki Yoshifuji Date: Wed, 14 Jan 2004 22:15:45 -0800 Subject: [IPV6]: Do not change DEVCONF_xxx indexed based upon kernel config. --- include/linux/ipv6.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index e073162776fa..ab97fc520921 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -159,13 +159,11 @@ enum { DEVCONF_RTR_SOLICITS, DEVCONF_RTR_SOLICIT_INTERVAL, DEVCONF_RTR_SOLICIT_DELAY, -#ifdef CONFIG_IPV6_PRIVACY DEVCONF_USE_TEMPADDR, DEVCONF_TEMP_VALID_LFT, DEVCONF_TEMP_PREFERED_LFT, DEVCONF_REGEN_MAX_RETRY, DEVCONF_MAX_DESYNC_FACTOR, -#endif DEVCONF_MAX_ADDRESSES, DEVCONF_MAX }; -- cgit v1.2.3 From c272dd4672c7b0d2b20f84acb965f1b61694a601 Mon Sep 17 00:00:00 2001 From: Shirley Ma Date: Wed, 14 Jan 2004 23:10:22 -0800 Subject: [IPV6]: Add MIB:ipv6RouterAdvert netlink notification. --- include/linux/rtnetlink.h | 36 ++++++++++++++++++++++++++++++ include/net/ndisc.h | 4 ++++ net/ipv6/addrconf.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++ net/ipv6/ndisc.c | 1 + 4 files changed, 97 insertions(+) (limited to 'include/linux') diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index 6cfd6f2f4a98..eb051105d72f 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -44,6 +44,8 @@ #define RTM_DELTFILTER (RTM_BASE+29) #define RTM_GETTFILTER (RTM_BASE+30) +#define RTM_NEWRA (RTM_BASE+32) + #define RTM_NEWPREFIX (RTM_BASE+36) #define RTM_GETPREFIX (RTM_BASE+38) @@ -443,6 +445,38 @@ struct rtgenmsg unsigned char rtgen_family; }; +/***************************************************************** + * Route Advertisement specific messages. + * ******/ + +/* struct iframsg + * passes router advertisement specific information + */ + +struct iframsg +{ + unsigned char ifra_family; + unsigned ifra_flags; + int ifra_index; +}; + +enum +{ + IFRA_UNSPEC, + IFRA_LMTU, + IFRA_CACHEINFO +}; + +/* max_adver_interval, min_adver_interval should be gotten from user level */ +struct ifra_cacheinfo { + __u32 hop_limit; + __u32 lifetime; + __u32 reachable_time; + __u32 retrans_time; +}; + +#define IFRA_MAX IFRA_CACHEINFO + /***************************************************************** * Link layer specific messages. ****/ @@ -658,6 +692,8 @@ enum #define RTMGRP_IPV6_PREFIX 0x20000 +#define RTMGRP_IPV6_IFRA 0x10000 + /* End of information exported to user level */ #ifdef __KERNEL__ diff --git a/include/net/ndisc.h b/include/net/ndisc.h index 95684d3363c1..499eeb8d5337 100644 --- a/include/net/ndisc.h +++ b/include/net/ndisc.h @@ -109,6 +109,10 @@ extern int ndisc_ifinfo_sysctl_change(ctl_table *ctl, extern void inet6_ifinfo_notify(int event, struct inet6_dev *idev); +extern void inet6_ifra_notify(int event, + struct inet6_dev *idev, + struct ra_msg *ra_msg); + static inline struct neighbour * ndisc_get_neigh(struct net_device *dev, struct in6_addr *addr) { diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index d20f6647bc70..346dc88be972 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2924,6 +2924,62 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev, netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV6_PREFIX, GFP_ATOMIC); } +static int inet6_fill_ifra(struct sk_buff *skb, struct inet6_dev *idev, + struct ra_msg *ra_msg, u32 pid, u32 seq, int event) +{ + struct iframsg *ifra; + struct nlmsghdr *nlh; + unsigned char *b = skb->tail; + __u32 mtu = idev->dev->mtu; + struct ifra_cacheinfo ci; + + nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifra)); + + if (pid) + nlh->nlmsg_flags |= NLM_F_MULTI; + + ifra = NLMSG_DATA(nlh); + ifra->ifra_family = AF_INET6; + ifra->ifra_index = idev->dev->ifindex; + ifra->ifra_flags = idev->if_flags; + + RTA_PUT(skb, IFRA_LMTU, sizeof(mtu), &mtu); + + ci.hop_limit = ra_msg->icmph.icmp6_hop_limit; + ci.lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime); + ci.reachable_time = ntohl(ra_msg->reachable_time); + ci.retrans_time = ntohl(ra_msg->retrans_timer); + RTA_PUT(skb, IFRA_CACHEINFO, sizeof(ci), &ci); + + nlh->nlmsg_len = skb->tail - b; + return skb->len; + +nlmsg_failure: +rtattr_failure: + skb_trim(skb, b - skb->data); + return -1; +} + +void inet6_ifra_notify(int event, struct inet6_dev *idev, + struct ra_msg *ra_msg) +{ + struct sk_buff *skb; + int size = NLMSG_SPACE(sizeof(struct iframsg)+128); + + skb = alloc_skb(size, GFP_ATOMIC); + if (!skb) { + netlink_set_err(rtnl, 0, RTMGRP_IPV6_IFRA, ENOBUFS); + return; + } + if (inet6_fill_ifra(skb, idev, ra_msg, 0, 0, event) < 0) { + kfree_skb(skb); + netlink_set_err(rtnl, 0, RTMGRP_IPV6_IFRA, EINVAL); + return; + } + NETLINK_CB(skb).dst_groups = RTMGRP_IPV6_IFRA; + netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV6_IFRA, GFP_ATOMIC); +} + static struct rtnetlink_link inet6_rtnetlink_table[RTM_MAX - RTM_BASE + 1] = { [RTM_GETLINK - RTM_BASE] = { .dumpit = inet6_dump_ifinfo, }, [RTM_NEWADDR - RTM_BASE] = { .doit = inet6_rtm_newaddr, }, diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index f725744e6d48..08bd069732bf 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -1194,6 +1194,7 @@ static void ndisc_router_discovery(struct sk_buff *skb) out: if (rt) dst_release(&rt->u.dst); + inet6_ifra_notify(RTM_NEWRA, in6_dev, ra_msg); in6_dev_put(in6_dev); } -- cgit v1.2.3 From 3f2a0d1df938bd3507a665dedbf5a9b1701124eb Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 15 Jan 2004 04:47:18 -0800 Subject: [PATCH] fix pdeath_signal SMP locking Obviously almost noone uses the pdeath_signal feature, since this has gone unnoticed for quite some time. This patch calls the function that does the right locking for the context of this call (inside exit_notify). The names of the signal.c entrypoints are a little confusing. --- include/linux/signal.h | 1 + kernel/exit.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/signal.h b/include/linux/signal.h index e051eb0b17db..0e95116b878a 100644 --- a/include/linux/signal.h +++ b/include/linux/signal.h @@ -207,6 +207,7 @@ static inline void init_sigpending(struct sigpending *sig) INIT_LIST_HEAD(&sig->list); } +extern int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p); extern long do_sigpending(void __user *, unsigned long); extern int sigprocmask(int, sigset_t *, sigset_t *); diff --git a/kernel/exit.c b/kernel/exit.c index 749da057424a..34956331ad0f 100644 --- a/kernel/exit.c +++ b/kernel/exit.c @@ -529,7 +529,8 @@ static inline void reparent_thread(task_t *p, task_t *father, int traced) p->self_exec_id++; if (p->pdeath_signal) - send_group_sig_info(p->pdeath_signal, 0, p); + /* We already hold the tasklist_lock here. */ + group_send_sig_info(p->pdeath_signal, (void *) 0, p); /* Move the child from its dying parent to the new one. */ if (unlikely(traced)) { -- cgit v1.2.3 From d9189b24bd2bbb9237589ef530f34c96913b985d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Thu, 15 Jan 2004 10:10:09 -0800 Subject: Cset exclude: mashirle@us.ibm.com|ChangeSet|20040115231022|51079 --- include/linux/rtnetlink.h | 36 ------------------------------ include/net/ndisc.h | 4 ---- net/ipv6/addrconf.c | 56 ----------------------------------------------- net/ipv6/ndisc.c | 1 - 4 files changed, 97 deletions(-) (limited to 'include/linux') diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index eb051105d72f..6cfd6f2f4a98 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -44,8 +44,6 @@ #define RTM_DELTFILTER (RTM_BASE+29) #define RTM_GETTFILTER (RTM_BASE+30) -#define RTM_NEWRA (RTM_BASE+32) - #define RTM_NEWPREFIX (RTM_BASE+36) #define RTM_GETPREFIX (RTM_BASE+38) @@ -445,38 +443,6 @@ struct rtgenmsg unsigned char rtgen_family; }; -/***************************************************************** - * Route Advertisement specific messages. - * ******/ - -/* struct iframsg - * passes router advertisement specific information - */ - -struct iframsg -{ - unsigned char ifra_family; - unsigned ifra_flags; - int ifra_index; -}; - -enum -{ - IFRA_UNSPEC, - IFRA_LMTU, - IFRA_CACHEINFO -}; - -/* max_adver_interval, min_adver_interval should be gotten from user level */ -struct ifra_cacheinfo { - __u32 hop_limit; - __u32 lifetime; - __u32 reachable_time; - __u32 retrans_time; -}; - -#define IFRA_MAX IFRA_CACHEINFO - /***************************************************************** * Link layer specific messages. ****/ @@ -692,8 +658,6 @@ enum #define RTMGRP_IPV6_PREFIX 0x20000 -#define RTMGRP_IPV6_IFRA 0x10000 - /* End of information exported to user level */ #ifdef __KERNEL__ diff --git a/include/net/ndisc.h b/include/net/ndisc.h index 499eeb8d5337..95684d3363c1 100644 --- a/include/net/ndisc.h +++ b/include/net/ndisc.h @@ -109,10 +109,6 @@ extern int ndisc_ifinfo_sysctl_change(ctl_table *ctl, extern void inet6_ifinfo_notify(int event, struct inet6_dev *idev); -extern void inet6_ifra_notify(int event, - struct inet6_dev *idev, - struct ra_msg *ra_msg); - static inline struct neighbour * ndisc_get_neigh(struct net_device *dev, struct in6_addr *addr) { diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 346dc88be972..d20f6647bc70 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -2924,62 +2924,6 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev, netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV6_PREFIX, GFP_ATOMIC); } -static int inet6_fill_ifra(struct sk_buff *skb, struct inet6_dev *idev, - struct ra_msg *ra_msg, u32 pid, u32 seq, int event) -{ - struct iframsg *ifra; - struct nlmsghdr *nlh; - unsigned char *b = skb->tail; - __u32 mtu = idev->dev->mtu; - struct ifra_cacheinfo ci; - - nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*ifra)); - - if (pid) - nlh->nlmsg_flags |= NLM_F_MULTI; - - ifra = NLMSG_DATA(nlh); - ifra->ifra_family = AF_INET6; - ifra->ifra_index = idev->dev->ifindex; - ifra->ifra_flags = idev->if_flags; - - RTA_PUT(skb, IFRA_LMTU, sizeof(mtu), &mtu); - - ci.hop_limit = ra_msg->icmph.icmp6_hop_limit; - ci.lifetime = ntohs(ra_msg->icmph.icmp6_rt_lifetime); - ci.reachable_time = ntohl(ra_msg->reachable_time); - ci.retrans_time = ntohl(ra_msg->retrans_timer); - RTA_PUT(skb, IFRA_CACHEINFO, sizeof(ci), &ci); - - nlh->nlmsg_len = skb->tail - b; - return skb->len; - -nlmsg_failure: -rtattr_failure: - skb_trim(skb, b - skb->data); - return -1; -} - -void inet6_ifra_notify(int event, struct inet6_dev *idev, - struct ra_msg *ra_msg) -{ - struct sk_buff *skb; - int size = NLMSG_SPACE(sizeof(struct iframsg)+128); - - skb = alloc_skb(size, GFP_ATOMIC); - if (!skb) { - netlink_set_err(rtnl, 0, RTMGRP_IPV6_IFRA, ENOBUFS); - return; - } - if (inet6_fill_ifra(skb, idev, ra_msg, 0, 0, event) < 0) { - kfree_skb(skb); - netlink_set_err(rtnl, 0, RTMGRP_IPV6_IFRA, EINVAL); - return; - } - NETLINK_CB(skb).dst_groups = RTMGRP_IPV6_IFRA; - netlink_broadcast(rtnl, skb, 0, RTMGRP_IPV6_IFRA, GFP_ATOMIC); -} - static struct rtnetlink_link inet6_rtnetlink_table[RTM_MAX - RTM_BASE + 1] = { [RTM_GETLINK - RTM_BASE] = { .dumpit = inet6_dump_ifinfo, }, [RTM_NEWADDR - RTM_BASE] = { .doit = inet6_rtm_newaddr, }, diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 08bd069732bf..f725744e6d48 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c @@ -1194,7 +1194,6 @@ static void ndisc_router_discovery(struct sk_buff *skb) out: if (rt) dst_release(&rt->u.dst); - inet6_ifra_notify(RTM_NEWRA, in6_dev, ra_msg); in6_dev_put(in6_dev); } -- cgit v1.2.3