diff options
67 files changed, 843 insertions, 898 deletions
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index 07884fd6f92c..fad5a18b104e 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig @@ -1445,6 +1445,12 @@ source "net/Kconfig" source "net/ax25/Kconfig" +source "net/irda/Kconfig" + +source "drivers/isdn/Kconfig" + +source "drivers/telephony/Kconfig" + # This one must be before the filesystem configs. -DaveM menu "Unix 98 PTY support" diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index aa300085849e..95df732b2f7d 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig @@ -444,6 +444,7 @@ CONFIG_IPV6=m CONFIG_IPV6_PRIVACY=y CONFIG_INET6_AH=m CONFIG_INET6_ESP=m +CONFIG_INET6_IPCOMP=m # # IPv6: Netfilter Configuration @@ -742,6 +743,104 @@ CONFIG_ROSE=m # CONFIG_YAM is not set # +# IrDA (infrared) support +# +CONFIG_IRDA=m + +# +# IrDA protocols +# +CONFIG_IRLAN=m +CONFIG_IRNET=m +CONFIG_IRCOMM=m +CONFIG_IRDA_ULTRA=y + +# +# IrDA options +# +CONFIG_IRDA_CACHE_LAST_LSAP=y +CONFIG_IRDA_FAST_RR=y +# CONFIG_IRDA_DEBUG is not set + +# +# Infrared-port device drivers +# + +# +# SIR device drivers +# +# CONFIG_IRTTY_SIR is not set + +# +# Dongle support +# +# CONFIG_DONGLE is not set + +# +# Old SIR device drivers +# +# CONFIG_IRTTY_OLD is not set +# CONFIG_IRPORT_SIR is not set + +# +# Old Serial dongle support +# +# CONFIG_DONGLE_OLD is not set + +# +# FIR device drivers +# +# CONFIG_USB_IRDA is not set +# CONFIG_NSC_FIR is not set +# CONFIG_WINBOND_FIR is not set +# CONFIG_TOSHIBA_OLD is not set +# CONFIG_TOSHIBA_FIR is not set +# CONFIG_SMC_IRCC_FIR is not set +# CONFIG_ALI_FIR is not set +# CONFIG_VLSI_FIR is not set + +# +# ISDN subsystem +# +CONFIG_ISDN_BOOL=y + +# +# Old ISDN4Linux +# +# CONFIG_ISDN is not set + +# +# CAPI subsystem +# +CONFIG_ISDN_CAPI=m +CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y +CONFIG_ISDN_CAPI_MIDDLEWARE=y +CONFIG_ISDN_CAPI_CAPI20=m +CONFIG_ISDN_CAPI_CAPIFS_BOOL=y +CONFIG_ISDN_CAPI_CAPIFS=m + +# +# CAPI hardware drivers +# + +# +# Active AVM cards +# +# CONFIG_CAPI_AVM is not set + +# +# Active Eicon DIVA Server cards +# +# CONFIG_CAPI_EICON is not set + +# +# Telephony Support +# +CONFIG_PHONE=m +CONFIG_PHONE_IXJ=m +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# # Unix 98 PTY support # CONFIG_UNIX98_PTYS=y diff --git a/drivers/net/setup.c b/drivers/net/setup.c index 65694a8a2ff1..02d387fa4679 100644 --- a/drivers/net/setup.c +++ b/drivers/net/setup.c @@ -17,8 +17,6 @@ extern int sdla_setup(void); extern int sdla_c_setup(void); extern int lmc_setup(void); -extern int madgemc_probe(void); - /* * Devices in this list must do new style probing. That is they must * allocate their own device objects and do their own bus scans. @@ -50,14 +48,6 @@ static struct net_probe pci_probes[] __initdata = { #if defined(CONFIG_LANMEDIA) {lmc_setup, 0}, #endif - -/* - * Token Ring Drivers - */ -#ifdef CONFIG_MADGEMC - {madgemc_probe, 0}, -#endif - {NULL, 0}, }; diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c index 43d2ea0a9473..f5f450bc46df 100644 --- a/drivers/net/tokenring/madgemc.c +++ b/drivers/net/tokenring/madgemc.c @@ -63,7 +63,6 @@ struct madgemc_card { static struct madgemc_card *madgemc_card_list; -int madgemc_probe(void); static int madgemc_open(struct net_device *dev); static int madgemc_close(struct net_device *dev); static int madgemc_chipset_init(struct net_device *dev); @@ -152,7 +151,7 @@ static void madgemc_sifwritew(struct net_device *dev, unsigned short val, unsign -int __init madgemc_probe(void) +static int __init madgemc_probe(void) { static int versionprinted; struct net_device *dev; @@ -773,19 +772,7 @@ static int madgemc_mcaproc(char *buf, int slot, void *d) return len; } -#ifdef MODULE - -int init_module(void) -{ - /* Probe for cards. */ - if (madgemc_probe()) { - printk(KERN_NOTICE "madgemc.c: No cards found.\n"); - } - /* lock_tms380_module(); */ - return (0); -} - -void cleanup_module(void) +static void __exit madgemc_exit(void) { struct net_device *dev; struct madgemc_card *this_card; @@ -801,9 +788,10 @@ void cleanup_module(void) madgemc_card_list = this_card->next; kfree(this_card); } - /* unlock_tms380_module(); */ } -#endif /* MODULE */ + +module_init(madgemc_probe); +module_exit(madgemc_exit); MODULE_LICENSE("GPL"); diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 503c72da8c47..da2eaeb18118 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -213,24 +213,6 @@ extern void tasklet_kill(struct tasklet_struct *t); extern void tasklet_init(struct tasklet_struct *t, void (*func)(unsigned long), unsigned long data); -#ifdef CONFIG_SMP - -#define SMP_TIMER_NAME(name) name##__thr - -#define SMP_TIMER_DEFINE(name, task) \ -DECLARE_TASKLET(task, name##__thr, 0); \ -static void name (unsigned long dummy) \ -{ \ - tasklet_schedule(&(task)); \ -} - -#else /* CONFIG_SMP */ - -#define SMP_TIMER_NAME(name) name -#define SMP_TIMER_DEFINE(name, task) - -#endif /* CONFIG_SMP */ - /* * Autoprobing for irqs: * diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 7106c2eaf67e..e445c167c919 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -441,9 +441,6 @@ struct net_device struct divert_blk *divert; #endif /* CONFIG_NET_DIVERT */ - /* generic device structure used in constructing class */ - struct device *dev; - /* class/net/name entry */ struct class_device class_dev; @@ -455,7 +452,7 @@ struct net_device /* Set the sysfs physical device reference for the network logical device * if set prior to registration will cause a symlink during initialization. */ -#define SET_NETDEV_DEV(net, pdev) ((net)->dev = (pdev)) +#define SET_NETDEV_DEV(net, pdev) ((net)->class_dev.dev = (pdev)) struct packet_type diff --git a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h index 1dc2e0d5ce5e..44daac8cde2a 100644 --- a/include/linux/netfilter_ipv4/ip_conntrack.h +++ b/include/linux/netfilter_ipv4/ip_conntrack.h @@ -7,6 +7,7 @@ #include <linux/config.h> #include <linux/netfilter_ipv4/ip_conntrack_tuple.h> #include <linux/bitops.h> +#include <linux/compiler.h> #include <asm/atomic.h> enum ip_conntrack_info @@ -266,5 +267,16 @@ static inline int is_confirmed(struct ip_conntrack *ct) } extern unsigned int ip_conntrack_htable_size; + +/* eg. PROVIDES_CONNTRACK(ftp); */ +#define PROVIDES_CONNTRACK(name) \ + int needs_ip_conntrack_##name; \ + EXPORT_SYMBOL(needs_ip_conntrack_##name) + +/*. eg. NEEDS_CONNTRACK(ftp); */ +#define NEEDS_CONNTRACK(name) \ + extern int needs_ip_conntrack_##name; \ + static int *need_ip_conntrack_##name __attribute_used__ = &needs_ip_conntrack_##name + #endif /* __KERNEL__ */ #endif /* _IP_CONNTRACK_H */ diff --git a/include/linux/netfilter_ipv4/ip_nat_helper.h b/include/linux/netfilter_ipv4/ip_nat_helper.h index 633a9c37170d..185a24a6a047 100644 --- a/include/linux/netfilter_ipv4/ip_nat_helper.h +++ b/include/linux/netfilter_ipv4/ip_nat_helper.h @@ -3,14 +3,13 @@ /* NAT protocol helper routines. */ #include <linux/netfilter_ipv4/ip_conntrack.h> +#include <linux/module.h> struct sk_buff; /* Flags */ /* NAT helper must be called on every packet (for TCP) */ #define IP_NAT_HELPER_F_ALWAYS 0x01 -/* Standalone NAT helper, without a conntrack part */ -#define IP_NAT_HELPER_F_STANDALONE 0x02 struct ip_nat_helper { diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 30de192de7a9..d1df1ff56ed8 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -108,7 +108,6 @@ struct netlink_skb_parms extern int netlink_attach(int unit, int (*function)(int,struct sk_buff *skb)); extern void netlink_detach(int unit); extern int netlink_post(int unit, struct sk_buff *skb); -extern int init_netlink(void); extern struct sock *netlink_kernel_create(int unit, void (*input)(struct sock *sk, int len)); extern void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err); extern int netlink_unicast(struct sock *ssk, struct sk_buff *skb, __u32 pid, int nonblock); diff --git a/include/linux/xfrm.h b/include/linux/xfrm.h index 46144681c5a7..37b5ac010c7b 100644 --- a/include/linux/xfrm.h +++ b/include/linux/xfrm.h @@ -104,19 +104,21 @@ enum /* Netlink configuration messages. */ #define XFRM_MSG_BASE 0x10 -#define XFRM_MSG_NEWSA (RTM_BASE + 0) -#define XFRM_MSG_DELSA (RTM_BASE + 1) -#define XFRM_MSG_GETSA (RTM_BASE + 2) +#define XFRM_MSG_NEWSA (XFRM_MSG_BASE + 0) +#define XFRM_MSG_DELSA (XFRM_MSG_BASE + 1) +#define XFRM_MSG_GETSA (XFRM_MSG_BASE + 2) -#define XFRM_MSG_NEWPOLICY (RTM_BASE + 3) -#define XFRM_MSG_DELPOLICY (RTM_BASE + 4) -#define XFRM_MSG_GETPOLICY (RTM_BASE + 5) +#define XFRM_MSG_NEWPOLICY (XFRM_MSG_BASE + 3) +#define XFRM_MSG_DELPOLICY (XFRM_MSG_BASE + 4) +#define XFRM_MSG_GETPOLICY (XFRM_MSG_BASE + 5) -#define XFRM_MSG_ALLOCSPI (RTM_BASE + 6) -#define XFRM_MSG_ACQUIRE (RTM_BASE + 7) -#define XFRM_MSG_EXPIRE (RTM_BASE + 8) +#define XFRM_MSG_ALLOCSPI (XFRM_MSG_BASE + 6) +#define XFRM_MSG_ACQUIRE (XFRM_MSG_BASE + 7) +#define XFRM_MSG_EXPIRE (XFRM_MSG_BASE + 8) -#define XFRM_MSG_MAX (XFRM_MSG_EXPIRE+1) +#define XFRM_MSG_UPDPOLICY (XFRM_MSG_BASE + 9) + +#define XFRM_MSG_MAX (XFRM_MSG_UPDPOLICY+1) struct xfrm_user_tmpl { struct xfrm_id id; diff --git a/include/net/neighbour.h b/include/net/neighbour.h index bfcc2fa802bd..1307be7bf187 100644 --- a/include/net/neighbour.h +++ b/include/net/neighbour.h @@ -165,7 +165,6 @@ struct neigh_table unsigned long last_rand; struct neigh_parms *parms_list; kmem_cache_t *kmem_cachep; - struct tasklet_struct gc_task; struct neigh_statistics stats; struct neighbour *hash_buckets[NEIGH_HASHMASK+1]; struct pneigh_entry *phash_buckets[PNEIGH_HASHMASK+1]; diff --git a/include/net/tcp.h b/include/net/tcp.h index ee1ef9aa5c7e..158ee68198b4 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -35,6 +35,7 @@ #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) #include <linux/ipv6.h> #endif +#include <linux/seq_file.h> /* This is for all connections with a full identity, no wildcards. * New scheme, half the table is for TIME_WAIT, the other half is @@ -362,10 +363,6 @@ static __inline__ int tcp_sk_listen_hashfn(struct sock *sk) #define MAX_TCP_KEEPCNT 127 #define MAX_TCP_SYNCNT 127 -/* TIME_WAIT reaping mechanism. */ -#define TCP_TWKILL_SLOTS 8 /* Please keep this a power of 2. */ -#define TCP_TWKILL_PERIOD (TCP_TIMEWAIT_LEN/TCP_TWKILL_SLOTS) - #define TCP_SYNQ_INTERVAL (HZ/5) /* Period of SYNACK timer */ #define TCP_SYNQ_HSIZE 512 /* Size of SYNACK hash table */ @@ -1893,4 +1890,31 @@ static inline void tcp_mib_init(void) TCP_ADD_STATS_USER(TcpMaxConn, -1); } +/* /proc */ +enum tcp_seq_states { + TCP_SEQ_STATE_LISTENING, + TCP_SEQ_STATE_OPENREQ, + TCP_SEQ_STATE_ESTABLISHED, + TCP_SEQ_STATE_TIME_WAIT, +}; + +struct tcp_seq_afinfo { + struct module *owner; + char *name; + sa_family_t family; + int (*seq_show) (struct seq_file *m, void *v); + struct file_operations *seq_fops; +}; + +struct tcp_iter_state { + sa_family_t family; + enum tcp_seq_states state; + struct sock *syn_wait_sk; + int bucket, sbucket, num, uid; + struct seq_operations seq_ops; +}; + +extern int tcp_proc_register(struct tcp_seq_afinfo *afinfo); +extern void tcp_proc_unregister(struct tcp_seq_afinfo *afinfo); + #endif /* _TCP_H */ diff --git a/include/net/udp.h b/include/net/udp.h index 4684cba23be2..766330ad75b0 100644 --- a/include/net/udp.h +++ b/include/net/udp.h @@ -26,6 +26,7 @@ #include <linux/ip.h> #include <net/sock.h> #include <net/snmp.h> +#include <linux/seq_file.h> #define UDP_HTABLE_SIZE 128 @@ -77,4 +78,21 @@ DECLARE_SNMP_STAT(struct udp_mib, udp_statistics); #define UDP_INC_STATS_BH(field) SNMP_INC_STATS_BH(udp_statistics, field) #define UDP_INC_STATS_USER(field) SNMP_INC_STATS_USER(udp_statistics, field) +/* /proc */ +struct udp_seq_afinfo { + struct module *owner; + char *name; + sa_family_t family; + int (*seq_show) (struct seq_file *m, void *v); + struct file_operations *seq_fops; +}; + +struct udp_iter_state { + sa_family_t family; + int bucket; + struct seq_operations seq_ops; +}; + +extern int udp_proc_register(struct udp_seq_afinfo *afinfo); +extern void udp_proc_unregister(struct udp_seq_afinfo *afinfo); #endif /* _UDP_H */ diff --git a/kernel/compat.c b/kernel/compat.c index e0998f98b72b..0dcf84ac1a7d 100644 --- a/kernel/compat.c +++ b/kernel/compat.c @@ -214,7 +214,7 @@ asmlinkage long compat_sys_sigprocmask(int how, compat_old_sigset_t *set, #ifdef CONFIG_FUTEX asmlinkage long compat_sys_futex(u32 *uaddr, int op, int val, - struct compat_timespec *utime) + struct compat_timespec *utime, u32 *uaddr2) { struct timespec t; unsigned long timeout = MAX_SCHEDULE_TIMEOUT; @@ -226,9 +226,10 @@ asmlinkage long compat_sys_futex(u32 *uaddr, int op, int val, timeout = timespec_to_jiffies(&t) + 1; } if (op == FUTEX_REQUEUE) - val2 = (int) utime; + val2 = (int) (long) utime; - return do_futex((unsigned long)uaddr, op, val, timeout, uaddr2, val2); + return do_futex((unsigned long)uaddr, op, val, timeout, + (unsigned long)uaddr2, val2); } #endif diff --git a/kernel/futex.c b/kernel/futex.c index 5cd746c3c86c..36500829d9be 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -537,7 +537,7 @@ asmlinkage long sys_futex(u32 __user *uaddr, int op, int val, * requeue parameter in 'utime' if op == FUTEX_REQUEUE. */ if (op == FUTEX_REQUEUE) - val2 = (int) utime; + val2 = (int) (long) utime; return do_futex((unsigned long)uaddr, op, val, timeout, (unsigned long)uaddr2, val2); diff --git a/net/atm/mpoa_proc.c b/net/atm/mpoa_proc.c index 40600fc86a7c..9b6d873a7be9 100644 --- a/net/atm/mpoa_proc.c +++ b/net/atm/mpoa_proc.c @@ -223,7 +223,7 @@ static int parse_qos(const char *buff, int len) int value[5]; memset(&qos, 0, sizeof(struct atm_qos)); - strncpy(cmd, buff, 3); + strlcpy(cmd, buff, sizeof(cmd)); if( strncmp(cmd,"add", 3) && strncmp(cmd,"del", 3)) return 0; /* not add or del */ diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index e1cf71538c28..7db037622dd8 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -743,9 +743,8 @@ static int ax25_getsockopt(struct socket *sock, int level, int optname, ax25_dev = ax25->ax25_dev; if (ax25_dev != NULL && ax25_dev->dev != NULL) { - strncpy(devname, ax25_dev->dev->name, IFNAMSIZ); - length = min_t(unsigned int, strlen(ax25_dev->dev->name)+1, maxlen); - devname[length-1] = '\0'; + strlcpy(devname, ax25_dev->dev->name, sizeof(devname)); + length = strlen(devname) + 1; } else { *devname = '\0'; length = 1; diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c index 2a1003c8df60..2b6184e2814e 100644 --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c @@ -34,7 +34,7 @@ static inline int should_deliver(const struct net_bridge_port *p, int br_dev_queue_push_xmit(struct sk_buff *skb) { #ifdef CONFIG_NETFILTER - /* FIXME: skb bas not been linearized: is this valid?? --RR */ + /* ip_refrag calls ip_fragment, which doesn't copy the MAC header. */ if (skb->nf_bridge) memcpy(skb->data - 16, skb->nf_bridge->hh, 16); #endif diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index b98773255b90..99b1944c9f3a 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -84,7 +84,7 @@ static struct net_bridge *new_nb(const char *name) memset(br, 0, sizeof(*br)); dev = &br->dev; - strncpy(dev->name, name, IFNAMSIZ); + strlcpy(dev->name, name, sizeof(dev->name)); dev->priv = br; dev->priv_flags = IFF_EBRIDGE; ether_setup(dev); diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c index 12c073e51b79..c21cec286875 100644 --- a/net/bridge/br_netfilter.c +++ b/net/bridge/br_netfilter.c @@ -468,8 +468,7 @@ static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb, struct sk_buff *skb = *pskb; struct nf_bridge_info *nf_bridge = (*pskb)->nf_bridge; - /* FIXME: skb as not been linearized. Is this still true? --RR */ - /* Be very paranoid. */ + /* Be very paranoid. Must be a device driver bug. */ if (skb->mac.raw < skb->head || skb->mac.raw + ETH_HLEN > skb->data) { printk(KERN_CRIT "br_netfilter: Argh!! br_nf_post_routing: " "bad mac.raw pointer."); diff --git a/net/bridge/netfilter/ebt_arp.c b/net/bridge/netfilter/ebt_arp.c index 106d13d3ded8..d63d7206bbcb 100644 --- a/net/bridge/netfilter/ebt_arp.c +++ b/net/bridge/netfilter/ebt_arp.c @@ -19,89 +19,72 @@ static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in const struct net_device *out, const void *data, unsigned int datalen) { struct ebt_arp_info *info = (struct ebt_arp_info *)data; + struct arphdr arph; + if (skb_copy_bits(skb, 0, &arph, sizeof(arph))) + return EBT_NOMATCH; if (info->bitmask & EBT_ARP_OPCODE && FWINV(info->opcode != - ((*skb).nh.arph)->ar_op, EBT_ARP_OPCODE)) + arph.ar_op, EBT_ARP_OPCODE)) return EBT_NOMATCH; if (info->bitmask & EBT_ARP_HTYPE && FWINV(info->htype != - ((*skb).nh.arph)->ar_hrd, EBT_ARP_HTYPE)) + arph.ar_hrd, EBT_ARP_HTYPE)) return EBT_NOMATCH; if (info->bitmask & EBT_ARP_PTYPE && FWINV(info->ptype != - ((*skb).nh.arph)->ar_pro, EBT_ARP_PTYPE)) + arph.ar_pro, EBT_ARP_PTYPE)) return EBT_NOMATCH; - if (info->bitmask & (EBT_ARP_SRC_IP | EBT_ARP_DST_IP)) - { - uint32_t arp_len = sizeof(struct arphdr) + - (2 * (((*skb).nh.arph)->ar_hln)) + - (2 * (((*skb).nh.arph)->ar_pln)); - uint32_t dst; - uint32_t src; + if (info->bitmask & (EBT_ARP_SRC_IP | EBT_ARP_DST_IP)) { + uint32_t addr; - /* Make sure the packet is long enough */ - if ((((*skb).nh.raw) + arp_len) > (*skb).tail) - return EBT_NOMATCH; /* IPv4 addresses are always 4 bytes */ - if (((*skb).nh.arph)->ar_pln != sizeof(uint32_t)) + if (arph.ar_pln != sizeof(uint32_t)) return EBT_NOMATCH; - if (info->bitmask & EBT_ARP_SRC_IP) { - memcpy(&src, ((*skb).nh.raw) + sizeof(struct arphdr) + - ((*skb).nh.arph)->ar_hln, sizeof(uint32_t)); - if (FWINV(info->saddr != (src & info->smsk), + if (skb_copy_bits(skb, sizeof(struct arphdr) + + arph.ar_hln, &addr, sizeof(addr))) + return EBT_NOMATCH; + if (FWINV(info->saddr != (addr & info->smsk), EBT_ARP_SRC_IP)) return EBT_NOMATCH; } if (info->bitmask & EBT_ARP_DST_IP) { - memcpy(&dst, ((*skb).nh.raw)+sizeof(struct arphdr) + - (2*(((*skb).nh.arph)->ar_hln)) + - (((*skb).nh.arph)->ar_pln), sizeof(uint32_t)); - if (FWINV(info->daddr != (dst & info->dmsk), + if (skb_copy_bits(skb, sizeof(struct arphdr) + + 2*arph.ar_hln + sizeof(uint32_t), &addr, + sizeof(addr))) + return EBT_NOMATCH; + if (FWINV(info->daddr != (addr & info->dmsk), EBT_ARP_DST_IP)) return EBT_NOMATCH; } } - if (info->bitmask & (EBT_ARP_SRC_MAC | EBT_ARP_DST_MAC)) - { - uint32_t arp_len = sizeof(struct arphdr) + - (2 * (((*skb).nh.arph)->ar_hln)) + - (2 * (((*skb).nh.arph)->ar_pln)); - unsigned char dst[ETH_ALEN]; - unsigned char src[ETH_ALEN]; + if (info->bitmask & (EBT_ARP_SRC_MAC | EBT_ARP_DST_MAC)) { + unsigned char mac[ETH_ALEN]; + uint8_t verdict, i; - /* Make sure the packet is long enough */ - if ((((*skb).nh.raw) + arp_len) > (*skb).tail) - return EBT_NOMATCH; /* MAC addresses are 6 bytes */ - if (((*skb).nh.arph)->ar_hln != ETH_ALEN) + if (arph.ar_hln != ETH_ALEN) return EBT_NOMATCH; if (info->bitmask & EBT_ARP_SRC_MAC) { - uint8_t verdict, i; - - memcpy(&src, ((*skb).nh.raw) + - sizeof(struct arphdr), - ETH_ALEN); + if (skb_copy_bits(skb, sizeof(struct arphdr), &mac, + ETH_ALEN)) + return EBT_NOMATCH; verdict = 0; for (i = 0; i < 6; i++) - verdict |= (src[i] ^ info->smaddr[i]) & + verdict |= (mac[i] ^ info->smaddr[i]) & info->smmsk[i]; if (FWINV(verdict != 0, EBT_ARP_SRC_MAC)) return EBT_NOMATCH; } if (info->bitmask & EBT_ARP_DST_MAC) { - uint8_t verdict, i; - - memcpy(&dst, ((*skb).nh.raw) + - sizeof(struct arphdr) + - (((*skb).nh.arph)->ar_hln) + - (((*skb).nh.arph)->ar_pln), - ETH_ALEN); + if (skb_copy_bits(skb, sizeof(struct arphdr) + + arph.ar_hln + arph.ar_pln, &mac, ETH_ALEN)) + return EBT_NOMATCH; verdict = 0; for (i = 0; i < 6; i++) - verdict |= (dst[i] ^ info->dmaddr[i]) & + verdict |= (mac[i] ^ info->dmaddr[i]) & info->dmmsk[i]; if (FWINV(verdict != 0, EBT_ARP_DST_MAC)) return EBT_NOMATCH; diff --git a/net/bridge/netfilter/ebt_ip.c b/net/bridge/netfilter/ebt_ip.c index e61899bfebe4..7ef0662f81c6 100644 --- a/net/bridge/netfilter/ebt_ip.c +++ b/net/bridge/netfilter/ebt_ip.c @@ -23,53 +23,50 @@ struct tcpudphdr { uint16_t dst; }; -union h_u { - unsigned char *raw; - struct tcpudphdr *tuh; -}; - static int ebt_filter_ip(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const void *data, unsigned int datalen) { struct ebt_ip_info *info = (struct ebt_ip_info *)data; + union {struct iphdr iph; struct tcpudphdr ports;} u; + if (skb_copy_bits(skb, 0, &u.iph, sizeof(u.iph))) + return EBT_NOMATCH; if (info->bitmask & EBT_IP_TOS && - FWINV(info->tos != ((*skb).nh.iph)->tos, EBT_IP_TOS)) + FWINV(info->tos != u.iph.tos, EBT_IP_TOS)) return EBT_NOMATCH; - if (info->bitmask & EBT_IP_PROTO) { - if (FWINV(info->protocol != ((*skb).nh.iph)->protocol, - EBT_IP_PROTO)) - return EBT_NOMATCH; - if ( info->protocol == IPPROTO_TCP || - info->protocol == IPPROTO_UDP ) - { - union h_u h; - h.raw = skb->data + skb->nh.iph->ihl*4; - if (info->bitmask & EBT_IP_DPORT) { - uint16_t port = ntohs(h.tuh->dst); - if (FWINV(port < info->dport[0] || - port > info->dport[1], - EBT_IP_DPORT)) - return EBT_NOMATCH; - } - if (info->bitmask & EBT_IP_SPORT) { - uint16_t port = ntohs(h.tuh->src); - if (FWINV(port < info->sport[0] || - port > info->sport[1], - EBT_IP_SPORT)) - return EBT_NOMATCH; - } - } - } if (info->bitmask & EBT_IP_SOURCE && - FWINV((((*skb).nh.iph)->saddr & info->smsk) != + FWINV((u.iph.saddr & info->smsk) != info->saddr, EBT_IP_SOURCE)) return EBT_NOMATCH; if ((info->bitmask & EBT_IP_DEST) && - FWINV((((*skb).nh.iph)->daddr & info->dmsk) != + FWINV((u.iph.daddr & info->dmsk) != info->daddr, EBT_IP_DEST)) return EBT_NOMATCH; + if (info->bitmask & EBT_IP_PROTO) { + if (FWINV(info->protocol != u.iph.protocol, EBT_IP_PROTO)) + return EBT_NOMATCH; + if (!(info->bitmask & EBT_IP_DPORT) && + !(info->bitmask & EBT_IP_SPORT)) + return EBT_MATCH; + if (skb_copy_bits(skb, u.iph.ihl*4, &u.ports, + sizeof(u.ports))) + return EBT_NOMATCH; + if (info->bitmask & EBT_IP_DPORT) { + u.ports.dst = ntohs(u.ports.dst); + if (FWINV(u.ports.dst < info->dport[0] || + u.ports.dst > info->dport[1], + EBT_IP_DPORT)) + return EBT_NOMATCH; + } + if (info->bitmask & EBT_IP_SPORT) { + u.ports.src = ntohs(u.ports.src); + if (FWINV(u.ports.src < info->sport[0] || + u.ports.src > info->sport[1], + EBT_IP_SPORT)) + return EBT_NOMATCH; + } + } return EBT_MATCH; } @@ -86,7 +83,7 @@ static int ebt_ip_check(const char *tablename, unsigned int hookmask, if (info->bitmask & ~EBT_IP_MASK || info->invflags & ~EBT_IP_MASK) return -EINVAL; if (info->bitmask & (EBT_IP_DPORT | EBT_IP_SPORT)) { - if (info->bitmask & EBT_IPROTO) + if (info->invflags & EBT_IP_PROTO) return -EINVAL; if (info->protocol != IPPROTO_TCP && info->protocol != IPPROTO_UDP) diff --git a/net/bridge/netfilter/ebt_log.c b/net/bridge/netfilter/ebt_log.c index cdb84495cf4e..e7a3ef4afe5a 100644 --- a/net/bridge/netfilter/ebt_log.c +++ b/net/bridge/netfilter/ebt_log.c @@ -32,48 +32,105 @@ static int ebt_log_check(const char *tablename, unsigned int hookmask, return 0; } +struct tcpudphdr +{ + uint16_t src; + uint16_t dst; +}; + +struct arppayload +{ + unsigned char mac_src[ETH_ALEN]; + unsigned char ip_src[4]; + unsigned char mac_dst[ETH_ALEN]; + unsigned char ip_dst[4]; +}; + +static void print_MAC(unsigned char *p) +{ + int i; + + for (i = 0; i < ETH_ALEN; i++, p++) + printk("%02x%c", *p, i == ETH_ALEN - 1 ? ' ':':'); +} + +#define myNIPQUAD(a) a[0], a[1], a[2], a[3] static void ebt_log(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const void *data, unsigned int datalen) { struct ebt_log_info *info = (struct ebt_log_info *)data; char level_string[4] = "< >"; - level_string[1] = '0' + info->loglevel; + union {struct iphdr iph; struct tcpudphdr ports; + struct arphdr arph; struct arppayload arpp;} u; + level_string[1] = '0' + info->loglevel; spin_lock_bh(&ebt_log_lock); printk(level_string); printk("%s IN=%s OUT=%s ", info->prefix, in ? in->name : "", out ? out->name : ""); - if (skb->dev->hard_header_len) { - int i; - unsigned char *p = (skb->mac.ethernet)->h_source; - - printk("MAC source = "); - for (i = 0; i < ETH_ALEN; i++,p++) - printk("%02x%c", *p, i == ETH_ALEN - 1 ? ' ':':'); - printk("MAC dest = "); - p = (skb->mac.ethernet)->h_dest; - for (i = 0; i < ETH_ALEN; i++,p++) - printk("%02x%c", *p, i == ETH_ALEN - 1 ? ' ':':'); - } + printk("MAC source = "); + print_MAC((skb->mac.ethernet)->h_source); + printk("MAC dest = "); + print_MAC((skb->mac.ethernet)->h_dest); + printk("proto = 0x%04x", ntohs(((*skb).mac.ethernet)->h_proto)); if ((info->bitmask & EBT_LOG_IP) && skb->mac.ethernet->h_proto == htons(ETH_P_IP)){ - struct iphdr *iph = skb->nh.iph; + if (skb_copy_bits(skb, 0, &u.iph, sizeof(u.iph))) { + printk(" INCOMPLETE IP header"); + goto out; + } printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u,", - NIPQUAD(iph->saddr), NIPQUAD(iph->daddr)); - printk(" IP tos=0x%02X, IP proto=%d", iph->tos, iph->protocol); + NIPQUAD(u.iph.saddr), NIPQUAD(u.iph.daddr)); + printk(" IP tos=0x%02X, IP proto=%d", u.iph.tos, + u.iph.protocol); + if (u.iph.protocol == IPPROTO_TCP || + u.iph.protocol == IPPROTO_UDP) { + if (skb_copy_bits(skb, u.iph.ihl*4, &u.ports, + sizeof(u.ports))) { + printk(" INCOMPLETE TCP/UDP header"); + goto out; + } + printk(" SPT=%u DPT=%u", ntohs(u.ports.src), + ntohs(u.ports.dst)); + } + goto out; } if ((info->bitmask & EBT_LOG_ARP) && ((skb->mac.ethernet->h_proto == __constant_htons(ETH_P_ARP)) || (skb->mac.ethernet->h_proto == __constant_htons(ETH_P_RARP)))) { - struct arphdr * arph = skb->nh.arph; + if (skb_copy_bits(skb, 0, &u.arph, sizeof(u.arph))) { + printk(" INCOMPLETE ARP header"); + goto out; + } printk(" ARP HTYPE=%d, PTYPE=0x%04x, OPCODE=%d", - ntohs(arph->ar_hrd), ntohs(arph->ar_pro), - ntohs(arph->ar_op)); + ntohs(u.arph.ar_hrd), ntohs(u.arph.ar_pro), + ntohs(u.arph.ar_op)); + + /* If it's for Ethernet and the lengths are OK, + * then log the ARP payload */ + if (u.arph.ar_hrd == __constant_htons(1) && + u.arph.ar_hln == ETH_ALEN && + u.arph.ar_pln == sizeof(uint32_t)) { + if (skb_copy_bits(skb, sizeof(u.arph), &u.arpp, + sizeof(u.arpp))) { + printk(" INCOMPLETE ARP payload"); + goto out; + } + printk(" ARP MAC SRC="); + print_MAC(u.arpp.mac_src); + printk(" ARP IP SRC=%u.%u.%u.%u", + myNIPQUAD(u.arpp.ip_src)); + printk(" ARP MAC DST="); + print_MAC(u.arpp.mac_dst); + printk(" ARP IP DST=%u.%u.%u.%u", + myNIPQUAD(u.arpp.ip_dst)); + } } +out: printk("\n"); spin_unlock_bh(&ebt_log_lock); } diff --git a/net/bridge/netfilter/ebt_vlan.c b/net/bridge/netfilter/ebt_vlan.c index 143ab11fab1e..54120a771d3e 100644 --- a/net/bridge/netfilter/ebt_vlan.c +++ b/net/bridge/netfilter/ebt_vlan.c @@ -2,17 +2,17 @@ * Description: EBTables 802.1Q match extension kernelspace module. * Authors: Nick Fedchik <nick@fedchik.org.ua> * Bart De Schuymer <bdschuym@pandora.be> - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA @@ -39,92 +39,53 @@ MODULE_LICENSE("GPL"); #define INV_FLAG(_inv_flag_) (info->invflags & _inv_flag_) ? "!" : "" #define GET_BITMASK(_BIT_MASK_) info->bitmask & _BIT_MASK_ #define SET_BITMASK(_BIT_MASK_) info->bitmask |= _BIT_MASK_ -#define EXIT_ON_MISMATCH(_MATCH_,_MASK_) if (!((info->_MATCH_ == _MATCH_)^!!(info->invflags & _MASK_))) return 1; +#define EXIT_ON_MISMATCH(_MATCH_,_MASK_) {if (!((info->_MATCH_ == _MATCH_)^!!(info->invflags & _MASK_))) return EBT_NOMATCH;} -/* - * Function description: ebt_filter_vlan() is main engine for - * checking passed 802.1Q frame according to - * the passed extension parameters (in the *data buffer) - * ebt_filter_vlan() is called after successful check the rule params - * by ebt_check_vlan() function. - * Parameters: - * const struct sk_buff *skb - pointer to passed ethernet frame buffer - * const void *data - pointer to passed extension parameters - * unsigned int datalen - length of passed *data buffer - * const struct net_device *in - - * const struct net_device *out - - * const struct ebt_counter *c - - * Returned values: - * 0 - ok (all rule params matched) - * 1 - miss (rule params not acceptable to the parsed frame) - */ static int ebt_filter_vlan(const struct sk_buff *skb, const struct net_device *in, const struct net_device *out, const void *data, unsigned int datalen) { - struct ebt_vlan_info *info = (struct ebt_vlan_info *) data; /* userspace data */ - struct vlan_ethhdr *frame = (struct vlan_ethhdr *) skb->mac.raw; /* Passed tagged frame */ + struct ebt_vlan_info *info = (struct ebt_vlan_info *) data; + struct vlan_ethhdr frame; unsigned short TCI; /* Whole TCI, given from parsed frame */ unsigned short id; /* VLAN ID, given from frame TCI */ unsigned char prio; /* user_priority, given from frame TCI */ - unsigned short encap; /* VLAN encapsulated Type/Length field, given from orig frame */ + /* VLAN encapsulated Type/Length field, given from orig frame */ + unsigned short encap; - /* - * Tag Control Information (TCI) consists of the following elements: - * - User_priority. The user_priority field is three bits in length, - * interpreted as a binary number. - * - Canonical Format Indicator (CFI). The Canonical Format Indicator + if (skb_copy_bits(skb, 0, &frame, sizeof(frame))) + return EBT_NOMATCH; + + /* Tag Control Information (TCI) consists of the following elements: + * - User_priority. The user_priority field is three bits in length, + * interpreted as a binary number. + * - Canonical Format Indicator (CFI). The Canonical Format Indicator * (CFI) is a single bit flag value. Currently ignored. - * - VLAN Identifier (VID). The VID is encoded as - * an unsigned binary number. - */ - TCI = ntohs(frame->h_vlan_TCI); + * - VLAN Identifier (VID). The VID is encoded as + * an unsigned binary number. */ + TCI = ntohs(frame.h_vlan_TCI); id = TCI & VLAN_VID_MASK; prio = (TCI >> 13) & 0x7; - encap = frame->h_vlan_encapsulated_proto; + encap = frame.h_vlan_encapsulated_proto; - /* - * Checking VLAN Identifier (VID) - */ - if (GET_BITMASK(EBT_VLAN_ID)) { /* Is VLAN ID parsed? */ + /* Checking VLAN Identifier (VID) */ + if (GET_BITMASK(EBT_VLAN_ID)) EXIT_ON_MISMATCH(id, EBT_VLAN_ID); - } - /* - * Checking user_priority - */ - if (GET_BITMASK(EBT_VLAN_PRIO)) { /* Is VLAN user_priority parsed? */ + + /* Checking user_priority */ + if (GET_BITMASK(EBT_VLAN_PRIO)) EXIT_ON_MISMATCH(prio, EBT_VLAN_PRIO); - } - /* - * Checking Encapsulated Proto (Length/Type) field - */ - if (GET_BITMASK(EBT_VLAN_ENCAP)) { /* Is VLAN Encap parsed? */ + + /* Checking Encapsulated Proto (Length/Type) field */ + if (GET_BITMASK(EBT_VLAN_ENCAP)) EXIT_ON_MISMATCH(encap, EBT_VLAN_ENCAP); - } - /* - * All possible extension parameters was parsed. - * If rule never returned by missmatch, then all ok. - */ - return 0; + + return EBT_MATCH; } -/* - * Function description: ebt_vlan_check() is called when userspace - * delivers the table entry to the kernel, - * and to check that userspace doesn't give a bad table. - * Parameters: - * const char *tablename - table name string - * unsigned int hooknr - hook number - * const struct ebt_entry *e - ebtables entry basic set - * const void *data - pointer to passed extension parameters - * unsigned int datalen - length of passed *data buffer - * Returned values: - * 0 - ok (all delivered rule params are correct) - * 1 - miss (rule params is out of range, invalid, incompatible, etc.) - */ static int ebt_check_vlan(const char *tablename, unsigned int hooknr, @@ -132,9 +93,7 @@ ebt_check_vlan(const char *tablename, { struct ebt_vlan_info *info = (struct ebt_vlan_info *) data; - /* - * Parameters buffer overflow check - */ + /* Parameters buffer overflow check */ if (datalen != sizeof(struct ebt_vlan_info)) { DEBUG_MSG ("passed size %d is not eq to ebt_vlan_info (%Zd)\n", @@ -142,9 +101,7 @@ ebt_check_vlan(const char *tablename, return -EINVAL; } - /* - * Is it 802.1Q frame checked? - */ + /* Is it 802.1Q frame checked? */ if (e->ethproto != __constant_htons(ETH_P_8021Q)) { DEBUG_MSG ("passed entry proto %2.4X is not 802.1Q (8100)\n", @@ -152,67 +109,54 @@ ebt_check_vlan(const char *tablename, return -EINVAL; } - /* - * Check for bitmask range - * True if even one bit is out of mask - */ + /* Check for bitmask range + * True if even one bit is out of mask */ if (info->bitmask & ~EBT_VLAN_MASK) { DEBUG_MSG("bitmask %2X is out of mask (%2X)\n", info->bitmask, EBT_VLAN_MASK); return -EINVAL; } - /* - * Check for inversion flags range - */ + /* Check for inversion flags range */ if (info->invflags & ~EBT_VLAN_MASK) { DEBUG_MSG("inversion flags %2X is out of mask (%2X)\n", info->invflags, EBT_VLAN_MASK); return -EINVAL; } - /* - * Reserved VLAN ID (VID) values + /* Reserved VLAN ID (VID) values * ----------------------------- * 0 - The null VLAN ID. * 1 - The default Port VID (PVID) * 0x0FFF - Reserved for implementation use. - * if_vlan.h: VLAN_GROUP_ARRAY_LEN 4096. - */ - if (GET_BITMASK(EBT_VLAN_ID)) { /* when vlan-id param was spec-ed */ - if (!!info->id) { /* if id!=0 => check vid range */ + * if_vlan.h: VLAN_GROUP_ARRAY_LEN 4096. */ + if (GET_BITMASK(EBT_VLAN_ID)) { + if (!!info->id) { /* if id!=0 => check vid range */ if (info->id > VLAN_GROUP_ARRAY_LEN) { DEBUG_MSG ("id %d is out of range (1-4096)\n", info->id); return -EINVAL; } - /* - * Note: This is valid VLAN-tagged frame point. + /* Note: This is valid VLAN-tagged frame point. * Any value of user_priority are acceptable, * but should be ignored according to 802.1Q Std. - * So we just drop the prio flag. - */ + * So we just drop the prio flag. */ info->bitmask &= ~EBT_VLAN_PRIO; } - /* - * Else, id=0 (null VLAN ID) => user_priority range (any?) - */ + /* Else, id=0 (null VLAN ID) => user_priority range (any?) */ } if (GET_BITMASK(EBT_VLAN_PRIO)) { if ((unsigned char) info->prio > 7) { - DEBUG_MSG - ("prio %d is out of range (0-7)\n", + DEBUG_MSG("prio %d is out of range (0-7)\n", info->prio); return -EINVAL; } } - /* - * Check for encapsulated proto range - it is possible to be + /* Check for encapsulated proto range - it is possible to be * any value for u_short range. - * if_ether.h: ETH_ZLEN 60 - Min. octets in frame sans FCS - */ + * if_ether.h: ETH_ZLEN 60 - Min. octets in frame sans FCS */ if (GET_BITMASK(EBT_VLAN_ENCAP)) { if ((unsigned short) ntohs(info->encap) < ETH_ZLEN) { DEBUG_MSG @@ -232,9 +176,6 @@ static struct ebt_match filter_vlan = { .me = THIS_MODULE, }; -/* - * Module initialization function. - */ static int __init init(void) { DEBUG_MSG("ebtables 802.1Q extension module v" @@ -243,9 +184,6 @@ static int __init init(void) return ebt_register_match(&filter_vlan); } -/* - * Module "finalization" function - */ static void __exit fini(void) { ebt_unregister_match(&filter_vlan); diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 3ca261d14126..7f32804f201a 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c @@ -175,10 +175,6 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff **pskb, char *base; struct ebt_table_info *private = table->private; - /* FIXME: Push down to extensions --RR */ - if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0) - return NF_DROP; - read_lock_bh(&table->lock); cb_base = COUNTER_BASE(private->counters, private->nentries, smp_processor_id()); diff --git a/net/core/dev.c b/net/core/dev.c index 4a6c784220ef..90db1c394ede 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2754,6 +2754,8 @@ void netdev_run_todo(void) dev->next = NULL; + netdev_unregister_sysfs(dev); + netdev_wait_allrefs(dev); BUG_ON(atomic_read(&dev->refcnt)); @@ -2842,8 +2844,6 @@ int unregister_netdevice(struct net_device *dev) free_divert_blk(dev); - netdev_unregister_sysfs(dev); - spin_lock(&unregister_todo_lock); dev->next = unregister_todo; unregister_todo = dev; diff --git a/net/core/neighbour.c b/net/core/neighbour.c index b2a88e18554e..257460cb0749 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c @@ -540,7 +540,7 @@ static void neigh_sync(struct neighbour *n) } } -static void SMP_TIMER_NAME(neigh_periodic_timer)(unsigned long arg) +static void neigh_periodic_timer(unsigned long arg) { struct neigh_table *tbl = (struct neigh_table *)arg; unsigned long now = jiffies; @@ -605,15 +605,6 @@ next_elt: write_unlock(&tbl->lock); } -#ifdef CONFIG_SMP -static void neigh_periodic_timer(unsigned long arg) -{ - struct neigh_table *tbl = (struct neigh_table *)arg; - - tasklet_schedule(&tbl->gc_task); -} -#endif - static __inline__ int neigh_max_probes(struct neighbour *n) { struct neigh_parms *p = n->parms; @@ -1147,10 +1138,6 @@ void neigh_table_init(struct neigh_table *tbl) 15) & ~15, 0, SLAB_HWCACHE_ALIGN, NULL, NULL); -#ifdef CONFIG_SMP - tasklet_init(&tbl->gc_task, SMP_TIMER_NAME(neigh_periodic_timer), - (unsigned long)tbl); -#endif tbl->lock = RW_LOCK_UNLOCKED; init_timer(&tbl->gc_timer); tbl->gc_timer.data = (unsigned long)tbl; @@ -1178,7 +1165,6 @@ int neigh_table_clear(struct neigh_table *tbl) /* It is not clean... Fix it to unload IPv6 module safely */ del_timer_sync(&tbl->gc_timer); - tasklet_kill(&tbl->gc_task); del_timer_sync(&tbl->proxy_timer); pneigh_queue_purge(&tbl->proxy_queue); neigh_ifdown(tbl, NULL); diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index e4f69ff53bf6..e0da193e98fb 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -291,9 +291,7 @@ int netdev_register_sysfs(struct net_device *net) struct class_device_attribute *attr; int ret; - memset(class_dev, 0, sizeof(struct class_device)); class_dev->class = &net_class; - class_dev->dev = net->dev; class_dev->class_data = net; snprintf(class_dev->class_id, BUS_ID_SIZE, net->name); diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c index 4e166c24c4c7..cbaa260873ec 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c @@ -155,7 +155,7 @@ static inline void dnrt_drop(struct dn_route *rt) call_rcu(&rt->u.dst.rcu_head, (void (*)(void *))dst_free, &rt->u.dst); } -static void SMP_TIMER_NAME(dn_dst_check_expire)(unsigned long dummy) +static void dn_dst_check_expire(unsigned long dummy) { int i; struct dn_route *rt, **rtp; @@ -185,8 +185,6 @@ static void SMP_TIMER_NAME(dn_dst_check_expire)(unsigned long dummy) mod_timer(&dn_route_timer, now + decnet_dst_gc_interval * HZ); } -SMP_TIMER_DEFINE(dn_dst_check_expire, dn_dst_task); - static int dn_dst_gc(void) { struct dn_route *rt, **rtp; @@ -319,7 +317,7 @@ static int dn_insert_route(struct dn_route *rt, unsigned hash, struct dn_route * return 0; } -void SMP_TIMER_NAME(dn_run_flush)(unsigned long dummy) +void dn_run_flush(unsigned long dummy) { int i; struct dn_route *rt, *next; @@ -341,8 +339,6 @@ nothing_to_declare: } } -SMP_TIMER_DEFINE(dn_run_flush, dn_flush_task); - static spinlock_t dn_rt_flush_lock = SPIN_LOCK_UNLOCKED; void dn_rt_cache_flush(int delay) diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index d8eececee504..f96acad1857c 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1237,10 +1237,10 @@ extern void fib_proc_exit(void); extern int ip_misc_proc_init(void); extern int raw_proc_init(void); extern void raw_proc_exit(void); -extern int tcp_proc_init(void); -extern void tcp_proc_exit(void); -extern int udp_proc_init(void); -extern void udp_proc_exit(void); +extern int tcp4_proc_init(void); +extern void tcp4_proc_exit(void); +extern int udp4_proc_init(void); +extern void udp4_proc_exit(void); int __init ipv4_proc_init(void) { @@ -1248,9 +1248,9 @@ int __init ipv4_proc_init(void) if (raw_proc_init()) goto out_raw; - if (tcp_proc_init()) + if (tcp4_proc_init()) goto out_tcp; - if (udp_proc_init()) + if (udp4_proc_init()) goto out_udp; if (fib_proc_init()) goto out_fib; @@ -1261,9 +1261,9 @@ out: out_misc: fib_proc_exit(); out_fib: - udp_proc_exit(); + udp4_proc_exit(); out_udp: - tcp_proc_exit(); + tcp4_proc_exit(); out_tcp: raw_proc_exit(); out_raw: diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 3dddae90bbdc..f9959c4e932f 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -949,7 +949,7 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev) r->arp_flags = arp_state_to_flags(neigh); read_unlock_bh(&neigh->lock); r->arp_ha.sa_family = dev->type; - strncpy(r->arp_dev, dev->name, sizeof(r->arp_dev)); + strlcpy(r->arp_dev, dev->name, sizeof(r->arp_dev)); neigh_release(neigh); err = 0; } diff --git a/net/ipv4/fib_hash.c b/net/ipv4/fib_hash.c index 94cf6e7fdb11..d13ff6bf3885 100644 --- a/net/ipv4/fib_hash.c +++ b/net/ipv4/fib_hash.c @@ -151,17 +151,6 @@ static rwlock_t fib_hash_lock = RW_LOCK_UNLOCKED; #define FZ_MAX_DIVISOR ((PAGE_SIZE<<MAX_ORDER) / sizeof(struct fib_node *)) -static unsigned long size_to_order(unsigned long size) -{ - unsigned long order; - - for (order = 0; order < MAX_ORDER; order++) { - if ((PAGE_SIZE << order) >= size) - break; - } - return order; -} - static struct fib_node **fz_hash_alloc(int divisor) { unsigned long size = divisor * sizeof(struct fib_node *); @@ -170,7 +159,7 @@ static struct fib_node **fz_hash_alloc(int divisor) return kmalloc(size, GFP_KERNEL); } else { return (struct fib_node **) - __get_free_pages(GFP_KERNEL, size_to_order(size)); + __get_free_pages(GFP_KERNEL, get_order(size)); } } @@ -201,7 +190,7 @@ static void fz_hash_free(struct fib_node **hash, int divisor) kfree(hash); else free_pages((unsigned long) hash, - size_to_order(divisor * sizeof(struct fib_node *))); + get_order(divisor * sizeof(struct fib_node *))); } static void fn_rehash_zone(struct fn_zone *fz) diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 0f9bce09b3b5..9958e71d47d5 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c @@ -120,68 +120,68 @@ DEFINE_SNMP_STAT(struct icmp_mib, icmp_statistics); struct icmp_err icmp_err_convert[] = { { - .errno =ENETUNREACH, /* ICMP_NET_UNREACH */ - .fatal =0, + .errno = ENETUNREACH, /* ICMP_NET_UNREACH */ + .fatal = 0, }, { - .errno =EHOSTUNREACH, /* ICMP_HOST_UNREACH */ - .fatal =0, + .errno = EHOSTUNREACH, /* ICMP_HOST_UNREACH */ + .fatal = 0, }, { - .errno =ENOPROTOOPT /* ICMP_PROT_UNREACH */, - .fatal =1, + .errno = ENOPROTOOPT /* ICMP_PROT_UNREACH */, + .fatal = 1, }, { - .errno =ECONNREFUSED, /* ICMP_PORT_UNREACH */ - .fatal =1, + .errno = ECONNREFUSED, /* ICMP_PORT_UNREACH */ + .fatal = 1, }, { - .errno =EMSGSIZE, /* ICMP_FRAG_NEEDED */ - .fatal =0, + .errno = EMSGSIZE, /* ICMP_FRAG_NEEDED */ + .fatal = 0, }, { - .errno =EOPNOTSUPP, /* ICMP_SR_FAILED */ - .fatal =0, + .errno = EOPNOTSUPP, /* ICMP_SR_FAILED */ + .fatal = 0, }, { - .errno =ENETUNREACH, /* ICMP_NET_UNKNOWN */ - .fatal =1, + .errno = ENETUNREACH, /* ICMP_NET_UNKNOWN */ + .fatal = 1, }, { - .errno =EHOSTDOWN, /* ICMP_HOST_UNKNOWN */ - .fatal =1, + .errno = EHOSTDOWN, /* ICMP_HOST_UNKNOWN */ + .fatal = 1, }, { - .errno =ENONET, /* ICMP_HOST_ISOLATED */ - .fatal =1, + .errno = ENONET, /* ICMP_HOST_ISOLATED */ + .fatal = 1, }, { - .errno =ENETUNREACH, /* ICMP_NET_ANO */ - .fatal =1, + .errno = ENETUNREACH, /* ICMP_NET_ANO */ + .fatal = 1, }, { - .errno =EHOSTUNREACH, /* ICMP_HOST_ANO */ - .fatal =1, + .errno = EHOSTUNREACH, /* ICMP_HOST_ANO */ + .fatal = 1, }, { - .errno =ENETUNREACH, /* ICMP_NET_UNR_TOS */ - .fatal =0, + .errno = ENETUNREACH, /* ICMP_NET_UNR_TOS */ + .fatal = 0, }, { - .errno =EHOSTUNREACH, /* ICMP_HOST_UNR_TOS */ - .fatal =0, + .errno = EHOSTUNREACH, /* ICMP_HOST_UNR_TOS */ + .fatal = 0, }, { - .errno =EHOSTUNREACH, /* ICMP_PKT_FILTERED */ - .fatal =1, + .errno = EHOSTUNREACH, /* ICMP_PKT_FILTERED */ + .fatal = 1, }, { - .errno =EHOSTUNREACH, /* ICMP_PREC_VIOLATION */ - .fatal =1, + .errno = EHOSTUNREACH, /* ICMP_PREC_VIOLATION */ + .fatal = 1, }, { - .errno =EHOSTUNREACH, /* ICMP_PREC_CUTOFF */ - .fatal =1, + .errno = EHOSTUNREACH, /* ICMP_PREC_CUTOFF */ + .fatal = 1, }, }; @@ -320,8 +320,8 @@ static void icmp_out_count(int type) * Checksum each fragment, and on the first include the headers and final * checksum. */ -int -icmp_glue_bits(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb) +int icmp_glue_bits(void *from, char *to, int offset, int len, int odd, + struct sk_buff *skb) { struct icmp_bxm *icmp_param = (struct icmp_bxm *)from; unsigned int csum; @@ -334,8 +334,8 @@ icmp_glue_bits(void *from, char *to, int offset, int len, int odd, struct sk_buf return 0; } -static void -icmp_push_reply(struct icmp_bxm *icmp_param, struct ipcm_cookie *ipc, struct rtable *rt) +static void icmp_push_reply(struct icmp_bxm *icmp_param, + struct ipcm_cookie *ipc, struct rtable *rt) { struct sk_buff *skb; @@ -353,8 +353,8 @@ icmp_push_reply(struct icmp_bxm *icmp_param, struct ipcm_cookie *ipc, struct rta csum = csum_add(csum, skb1->csum); } csum = csum_partial_copy_nocheck((void *)&icmp_param->data, - (char*)icmph, icmp_param->head_len, - csum); + (char *)icmph, + icmp_param->head_len, csum); icmph->checksum = csum_fold(csum); skb->ip_summed = CHECKSUM_NONE; ip_push_pending_frames(icmp_socket->sk); @@ -728,20 +728,16 @@ static void icmp_redirect(struct sk_buff *skb) ip = iph->daddr; switch (skb->h.icmph->code & 7) { - case ICMP_REDIR_NET: - case ICMP_REDIR_NETTOS: - /* - * As per RFC recommendations now handle it as - * a host redirect. - */ - case ICMP_REDIR_HOST: - case ICMP_REDIR_HOSTTOS: - ip_rt_redirect(skb->nh.iph->saddr, - ip, skb->h.icmph->un.gateway, - iph->saddr, iph->tos, skb->dev); - break; - default: - break; + case ICMP_REDIR_NET: + case ICMP_REDIR_NETTOS: + /* + * As per RFC recommendations now handle it as a host redirect. + */ + case ICMP_REDIR_HOST: + case ICMP_REDIR_HOSTTOS: + ip_rt_redirect(skb->nh.iph->saddr, ip, skb->h.icmph->un.gateway, + iph->saddr, iph->tos, skb->dev); + break; } out: return; @@ -966,7 +962,7 @@ int icmp_rcv(struct sk_buff *skb) } ICMP_INC_STATS_BH_FIELD(icmp_pointers[icmph->type].input_off); - (icmp_pointers[icmph->type].handler)(skb); + icmp_pointers[icmph->type].handler(skb); drop: kfree_skb(skb); @@ -980,8 +976,7 @@ error: * This table is the definition of how we handle ICMP. */ static struct icmp_control icmp_pointers[NR_ICMP_TYPES + 1] = { - /* ECHO REPLY (0) */ - [0] = { + [ICMP_ECHOREPLY] = { .output_off = offsetof(struct icmp_mib, IcmpOutEchoReps), .input_off = offsetof(struct icmp_mib, IcmpInEchoReps), .handler = icmp_discard, @@ -998,22 +993,19 @@ static struct icmp_control icmp_pointers[NR_ICMP_TYPES + 1] = { .handler = icmp_discard, .error = 1, }, - /* DEST UNREACH (3) */ - [3] = { + [ICMP_DEST_UNREACH] = { .output_off = offsetof(struct icmp_mib, IcmpOutDestUnreachs), .input_off = offsetof(struct icmp_mib, IcmpInDestUnreachs), .handler = icmp_unreach, .error = 1, }, - /* SOURCE QUENCH (4) */ - [4] = { + [ICMP_SOURCE_QUENCH] = { .output_off = offsetof(struct icmp_mib, IcmpOutSrcQuenchs), .input_off = offsetof(struct icmp_mib, IcmpInSrcQuenchs), - icmp_unreach, + .handler = icmp_unreach, .error = 1, }, - /* REDIRECT (5) */ - [5] = { + [ICMP_REDIRECT] = { .output_off = offsetof(struct icmp_mib, IcmpOutRedirects), .input_off = offsetof(struct icmp_mib, IcmpInRedirects), .handler = icmp_redirect, @@ -1031,12 +1023,10 @@ static struct icmp_control icmp_pointers[NR_ICMP_TYPES + 1] = { .handler = icmp_discard, .error = 1, }, - /* ECHO (8) */ - [8] = { + [ICMP_ECHO] = { .output_off = offsetof(struct icmp_mib, IcmpOutEchos), .input_off = offsetof(struct icmp_mib, IcmpInEchos), .handler = icmp_echo, - .error = 0, }, [9] = { .output_off = offsetof(struct icmp_mib, dummy), @@ -1050,56 +1040,48 @@ static struct icmp_control icmp_pointers[NR_ICMP_TYPES + 1] = { .handler = icmp_discard, .error = 1, }, - /* TIME EXCEEDED (11) */ - [11] = { + [ICMP_TIME_EXCEEDED] = { .output_off = offsetof(struct icmp_mib, IcmpOutTimeExcds), .input_off = offsetof(struct icmp_mib,IcmpInTimeExcds), .handler = icmp_unreach, .error = 1, }, - /* PARAMETER PROBLEM (12) */ - [12] = { + [ICMP_PARAMETERPROB] = { .output_off = offsetof(struct icmp_mib, IcmpOutParmProbs), .input_off = offsetof(struct icmp_mib, IcmpInParmProbs), .handler = icmp_unreach, .error = 1, }, - /* TIMESTAMP (13) */ - [13] = { + [ICMP_TIMESTAMP] = { .output_off = offsetof(struct icmp_mib, IcmpOutTimestamps), .input_off = offsetof(struct icmp_mib, IcmpInTimestamps), .handler = icmp_timestamp, }, - /* TIMESTAMP REPLY (14) */ - [14] = { + [ICMP_TIMESTAMPREPLY] = { .output_off = offsetof(struct icmp_mib, IcmpOutTimestampReps), .input_off = offsetof(struct icmp_mib, IcmpInTimestampReps), .handler = icmp_discard, }, - /* INFO (15) */ - [15] = { + [ICMP_INFO_REQUEST] = { .output_off = offsetof(struct icmp_mib, dummy), .input_off = offsetof(struct icmp_mib, dummy), .handler = icmp_discard, }, - /* INFO REPLY (16) */ - [16] = { + [ICMP_INFO_REPLY] = { .output_off = offsetof(struct icmp_mib, dummy), .input_off = offsetof(struct icmp_mib, dummy), .handler = icmp_discard, }, - /* ADDR MASK (17) */ - [17] = { + [ICMP_ADDRESS] = { .output_off = offsetof(struct icmp_mib, IcmpOutAddrMasks), .input_off = offsetof(struct icmp_mib, IcmpInAddrMasks), .handler = icmp_address, }, - /* ADDR MASK REPLY (18) */ - [18] = { + [ICMP_ADDRESSREPLY] = { .output_off = offsetof(struct icmp_mib, IcmpOutAddrMaskReps), .input_off = offsetof(struct icmp_mib, IcmpInAddrMaskReps), .handler = icmp_address_reply, - } + }, }; void __init icmp_init(struct net_proto_family *ops) diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index 237eddf48d44..706b6e8a7bcb 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c @@ -1363,16 +1363,15 @@ static int __init ip_auto_config_setup(char *addrs) case 4: if ((dp = strchr(ip, '.'))) { *dp++ = '\0'; - strncpy(system_utsname.domainname, dp, __NEW_UTS_LEN); - system_utsname.domainname[__NEW_UTS_LEN] = '\0'; + strlcpy(system_utsname.domainname, dp, + sizeof(system_utsname.domainname)); } - strncpy(system_utsname.nodename, ip, __NEW_UTS_LEN); - system_utsname.nodename[__NEW_UTS_LEN] = '\0'; + strlcpy(system_utsname.nodename, ip, + sizeof(system_utsname.nodename)); ic_host_name_set = 1; break; case 5: - strncpy(user_dev_name, ip, IFNAMSIZ); - user_dev_name[IFNAMSIZ-1] = '\0'; + strlcpy(user_dev_name, ip, sizeof(user_dev_name)); break; case 6: ic_proto_name(ip); diff --git a/net/ipv4/netfilter/ip_conntrack_amanda.c b/net/ipv4/netfilter/ip_conntrack_amanda.c index 4ab6a5fa6ca9..9c30e71d56f6 100644 --- a/net/ipv4/netfilter/ip_conntrack_amanda.c +++ b/net/ipv4/netfilter/ip_conntrack_amanda.c @@ -207,6 +207,7 @@ static int __init init(void) return 0; } +PROVIDES_CONNTRACK(amanda); EXPORT_SYMBOL(ip_amanda_lock); module_init(init); diff --git a/net/ipv4/netfilter/ip_conntrack_ftp.c b/net/ipv4/netfilter/ip_conntrack_ftp.c index 9a0fca610442..2109464dd0bf 100644 --- a/net/ipv4/netfilter/ip_conntrack_ftp.c +++ b/net/ipv4/netfilter/ip_conntrack_ftp.c @@ -437,6 +437,7 @@ static int __init init(void) return 0; } +PROVIDES_CONNTRACK(ftp); EXPORT_SYMBOL(ip_ftp_lock); MODULE_LICENSE("GPL"); diff --git a/net/ipv4/netfilter/ip_conntrack_irc.c b/net/ipv4/netfilter/ip_conntrack_irc.c index f75422bdfbbf..6f4ea9db1217 100644 --- a/net/ipv4/netfilter/ip_conntrack_irc.c +++ b/net/ipv4/netfilter/ip_conntrack_irc.c @@ -289,6 +289,7 @@ static void fini(void) } } +PROVIDES_CONNTRACK(irc); EXPORT_SYMBOL(ip_irc_lock); module_init(init); diff --git a/net/ipv4/netfilter/ip_conntrack_tftp.c b/net/ipv4/netfilter/ip_conntrack_tftp.c index 2bd9c4b1dea3..8a7e1711d14f 100644 --- a/net/ipv4/netfilter/ip_conntrack_tftp.c +++ b/net/ipv4/netfilter/ip_conntrack_tftp.c @@ -130,5 +130,7 @@ static int __init init(void) return(0); } +PROVIDES_CONNTRACK(tftp); + module_init(init); module_exit(fini); diff --git a/net/ipv4/netfilter/ip_nat_amanda.c b/net/ipv4/netfilter/ip_nat_amanda.c index d3e9ccb80641..4cc24ad19c5d 100644 --- a/net/ipv4/netfilter/ip_nat_amanda.c +++ b/net/ipv4/netfilter/ip_nat_amanda.c @@ -221,6 +221,6 @@ static int __init init(void) return ret; } - +NEEDS_CONNTRACK(amanda); module_init(init); module_exit(fini); diff --git a/net/ipv4/netfilter/ip_nat_ftp.c b/net/ipv4/netfilter/ip_nat_ftp.c index d232a72f8f00..b14459eb71a5 100644 --- a/net/ipv4/netfilter/ip_nat_ftp.c +++ b/net/ipv4/netfilter/ip_nat_ftp.c @@ -341,6 +341,8 @@ static int __init init(void) return ret; } +NEEDS_CONNTRACK(ftp); + module_init(init); module_exit(fini); MODULE_LICENSE("GPL"); diff --git a/net/ipv4/netfilter/ip_nat_helper.c b/net/ipv4/netfilter/ip_nat_helper.c index 173294f34473..bea707e946e3 100644 --- a/net/ipv4/netfilter/ip_nat_helper.c +++ b/net/ipv4/netfilter/ip_nat_helper.c @@ -404,44 +404,6 @@ int ip_nat_helper_register(struct ip_nat_helper *me) { int ret = 0; - if (me->me && !(me->flags & IP_NAT_HELPER_F_STANDALONE)) { - struct ip_conntrack_helper *ct_helper; - - if ((ct_helper = ip_ct_find_helper(&me->tuple))) { - if (!try_module_get(ct_helper->me)) - return -EBUSY; - } else { - /* We are a NAT helper for protocol X. If we need - * respective conntrack helper for protoccol X, compute - * conntrack helper name and try to load module */ - char name[MODULE_NAME_LEN]; - const char *tmp = module_name(me->me); - - if (strlen(tmp) + 6 > MODULE_NAME_LEN) { - printk("%s: unable to " - "compute conntrack helper name " - "from %s\n", __FUNCTION__, tmp); - return -EBUSY; - } - tmp += 6; - sprintf(name, "ip_conntrack%s", tmp); -#ifdef CONFIG_KMOD - if (!request_module("ip_conntrack%s", tmp) - && (ct_helper = ip_ct_find_helper(&me->tuple))) { - if (!try_module_get(ct_helper->me)) - return -EBUSY; - } else { - printk("unable to load module %s\n", name); - return -EBUSY; - } -#else - printk("unable to load module %s automatically " - "because kernel was compiled without kernel " - "module loader support\n", name); - return -EBUSY; -#endif - } - } WRITE_LOCK(&ip_nat_lock); if (LIST_FIND(&helpers, helper_cmp, struct ip_nat_helper *,&me->tuple)) ret = -EBUSY; @@ -484,19 +446,4 @@ void ip_nat_helper_unregister(struct ip_nat_helper *me) which is just a long-winded way of making things worse. --RR */ ip_ct_selective_cleanup(kill_helper, me); - - /* If we are no standalone NAT helper, we need to decrement usage count - * on our conntrack helper */ - if (me->me && !(me->flags & IP_NAT_HELPER_F_STANDALONE)) { - struct ip_conntrack_helper *ct_helper; - - if ((ct_helper = ip_ct_find_helper(&me->tuple))) - module_put(ct_helper->me); -#ifdef CONFIG_MODULES - else - printk("%s: unable to decrement usage count" - " of conntrack helper %s\n", - __FUNCTION__, me->me->name); -#endif - } } diff --git a/net/ipv4/netfilter/ip_nat_irc.c b/net/ipv4/netfilter/ip_nat_irc.c index 50d0ec8d82f0..666a661f4932 100644 --- a/net/ipv4/netfilter/ip_nat_irc.c +++ b/net/ipv4/netfilter/ip_nat_irc.c @@ -279,6 +279,7 @@ static int __init init(void) return ret; } +NEEDS_CONNTRACK(irc); module_init(init); module_exit(fini); diff --git a/net/ipv4/netfilter/ip_nat_snmp_basic.c b/net/ipv4/netfilter/ip_nat_snmp_basic.c index 5e99951afa67..d5587b0863fb 100644 --- a/net/ipv4/netfilter/ip_nat_snmp_basic.c +++ b/net/ipv4/netfilter/ip_nat_snmp_basic.c @@ -1306,7 +1306,7 @@ static unsigned int nat_help(struct ip_conntrack *ct, static struct ip_nat_helper snmp = { { NULL, NULL }, "snmp", - IP_NAT_HELPER_F_STANDALONE, + 0, THIS_MODULE, { { 0, { __constant_htons(SNMP_PORT) } }, { 0, { 0 }, IPPROTO_UDP } }, @@ -1317,7 +1317,7 @@ static struct ip_nat_helper snmp = { static struct ip_nat_helper snmp_trap = { { NULL, NULL }, "snmp_trap", - IP_NAT_HELPER_F_STANDALONE, + 0, THIS_MODULE, { { 0, { __constant_htons(SNMP_TRAP_PORT) } }, { 0, { 0 }, IPPROTO_UDP } }, diff --git a/net/ipv4/route.c b/net/ipv4/route.c index db069664483c..bc01b55fb9aa 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -455,7 +455,7 @@ out: return ret; } /* This runs via a timer and thus is always in BH context. */ -static void SMP_TIMER_NAME(rt_check_expire)(unsigned long dummy) +static void rt_check_expire(unsigned long dummy) { static int rover; int i = rover, t; @@ -498,12 +498,10 @@ static void SMP_TIMER_NAME(rt_check_expire)(unsigned long dummy) mod_timer(&rt_periodic_timer, now + ip_rt_gc_interval); } -SMP_TIMER_DEFINE(rt_check_expire, rt_gc_task); - /* This can run from both BH and non-BH contexts, the latter * in the case of a forced flush event. */ -static void SMP_TIMER_NAME(rt_run_flush)(unsigned long dummy) +static void rt_run_flush(unsigned long dummy) { int i; struct rtable *rth, *next; @@ -526,8 +524,6 @@ static void SMP_TIMER_NAME(rt_run_flush)(unsigned long dummy) } } -SMP_TIMER_DEFINE(rt_run_flush, rt_cache_flush_task); - static spinlock_t rt_flush_lock = SPIN_LOCK_UNLOCKED; void rt_cache_flush(int delay) @@ -559,7 +555,7 @@ void rt_cache_flush(int delay) if (delay <= 0) { spin_unlock_bh(&rt_flush_lock); - SMP_TIMER_NAME(rt_run_flush)(0); + rt_run_flush(0); return; } diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 2ad587593075..544a181ff550 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -2129,19 +2129,6 @@ static int tcp_v4_destroy_sock(struct sock *sk) #ifdef CONFIG_PROC_FS /* Proc filesystem TCP sock list dumping. */ -enum tcp_seq_states { - TCP_SEQ_STATE_LISTENING, - TCP_SEQ_STATE_OPENREQ, - TCP_SEQ_STATE_ESTABLISHED, - TCP_SEQ_STATE_TIME_WAIT, -}; - -struct tcp_iter_state { - enum tcp_seq_states state; - struct sock *syn_wait_sk; - int bucket, sbucket, num, uid; -}; - static void *listening_get_first(struct seq_file *seq) { struct tcp_iter_state* st = seq->private; @@ -2155,7 +2142,7 @@ static void *listening_get_first(struct seq_file *seq) if (!sk) continue; ++st->num; - if (TCP_INET_FAMILY(sk->family)) { + if (sk->family == st->family) { rc = sk; goto out; } @@ -2169,7 +2156,7 @@ static void *listening_get_first(struct seq_file *seq) ++st->sbucket) { for (req = tp->listen_opt->syn_table[st->sbucket]; req; req = req->dl_next, ++st->num) { - if (!TCP_INET_FAMILY(req->class->family)) + if (req->class->family != st->family) continue; rc = req; goto out; @@ -2197,7 +2184,7 @@ static void *listening_get_next(struct seq_file *seq, void *cur) while (1) { while (req) { ++st->num; - if (TCP_INET_FAMILY(req->class->family)) { + if (req->class->family == st->family) { cur = req; goto out; } @@ -2215,7 +2202,7 @@ get_req: sk = sk->next; get_sk: while (sk) { - if (TCP_INET_FAMILY(sk->family)) { + if (sk->family == st->family) { cur = sk; goto out; } @@ -2262,7 +2249,7 @@ static void *established_get_first(struct seq_file *seq) read_lock(&tcp_ehash[st->bucket].lock); for (sk = tcp_ehash[st->bucket].chain; sk; sk = sk->next, ++st->num) { - if (!TCP_INET_FAMILY(sk->family)) + if (sk->family != st->family) continue; rc = sk; goto out; @@ -2271,7 +2258,7 @@ static void *established_get_first(struct seq_file *seq) for (tw = (struct tcp_tw_bucket *) tcp_ehash[st->bucket + tcp_ehash_size].chain; tw; tw = (struct tcp_tw_bucket *)tw->next, ++st->num) { - if (!TCP_INET_FAMILY(tw->family)) + if (tw->family != st->family) continue; rc = tw; goto out; @@ -2293,7 +2280,7 @@ static void *established_get_next(struct seq_file *seq, void *cur) tw = cur; tw = (struct tcp_tw_bucket *)tw->next; get_tw: - while (tw && !TCP_INET_FAMILY(tw->family)) { + while (tw && tw->family != st->family) { ++st->num; tw = (struct tcp_tw_bucket *)tw->next; } @@ -2313,7 +2300,7 @@ get_tw: } else sk = sk->next; - while (sk && !TCP_INET_FAMILY(sk->family)) { + while (sk && sk->family != st->family) { ++st->num; sk = sk->next; } @@ -2417,8 +2404,66 @@ static void tcp_seq_stop(struct seq_file *seq, void *v) } } -static void get_openreq(struct sock *sk, struct open_request *req, - char *tmpbuf, int i, int uid) +static int tcp_seq_open(struct inode *inode, struct file *file) +{ + struct tcp_seq_afinfo *afinfo = PDE(inode)->data; + struct seq_file *seq; + int rc = -ENOMEM; + struct tcp_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL); + + if (!s) + goto out; + memset(s, 0, sizeof(*s)); + s->family = afinfo->family; + s->seq_ops.start = tcp_seq_start; + s->seq_ops.next = tcp_seq_next; + s->seq_ops.show = afinfo->seq_show; + s->seq_ops.stop = tcp_seq_stop; + + rc = seq_open(file, &s->seq_ops); + if (rc) + goto out_kfree; + seq = file->private_data; + seq->private = s; +out: + return rc; +out_kfree: + kfree(s); + goto out; +} + +int tcp_proc_register(struct tcp_seq_afinfo *afinfo) +{ + int rc = 0; + struct proc_dir_entry *p; + + if (!afinfo) + return -EINVAL; + afinfo->seq_fops->owner = afinfo->owner; + afinfo->seq_fops->open = tcp_seq_open; + afinfo->seq_fops->read = seq_read; + afinfo->seq_fops->llseek = seq_lseek; + afinfo->seq_fops->release = seq_release_private; + + p = create_proc_entry(afinfo->name, S_IRUGO, proc_net); + if (p) { + p->data = afinfo; + p->proc_fops = afinfo->seq_fops; + } else + rc = -ENOMEM; + return rc; +} + +void tcp_proc_unregister(struct tcp_seq_afinfo *afinfo) +{ + if (!afinfo) + return; + remove_proc_entry(afinfo->name, proc_net); + memset(afinfo->seq_fops, 0, sizeof(*afinfo->seq_fops)); +} + +static void get_openreq4(struct sock *sk, struct open_request *req, + char *tmpbuf, int i, int uid) { int ttd = req->expires - jiffies; @@ -2441,7 +2486,7 @@ static void get_openreq(struct sock *sk, struct open_request *req, req); } -static void get_tcp_sock(struct sock *sp, char *tmpbuf, int i) +static void get_tcp4_sock(struct sock *sp, char *tmpbuf, int i) { int timer_active; unsigned long timer_expires; @@ -2481,7 +2526,7 @@ static void get_tcp_sock(struct sock *sp, char *tmpbuf, int i) tp->snd_ssthresh >= 0xFFFF ? -1 : tp->snd_ssthresh); } -static void get_timewait_sock(struct tcp_tw_bucket *tw, char *tmpbuf, int i) +static void get_timewait4_sock(struct tcp_tw_bucket *tw, char *tmpbuf, int i) { unsigned int dest, src; __u16 destp, srcp; @@ -2504,7 +2549,7 @@ static void get_timewait_sock(struct tcp_tw_bucket *tw, char *tmpbuf, int i) #define TMPSZ 150 -static int tcp_seq_show(struct seq_file *seq, void *v) +static int tcp4_seq_show(struct seq_file *seq, void *v) { struct tcp_iter_state* st; char tmpbuf[TMPSZ + 1]; @@ -2521,13 +2566,13 @@ static int tcp_seq_show(struct seq_file *seq, void *v) switch (st->state) { case TCP_SEQ_STATE_LISTENING: case TCP_SEQ_STATE_ESTABLISHED: - get_tcp_sock(v, tmpbuf, st->num); + get_tcp4_sock(v, tmpbuf, st->num); break; case TCP_SEQ_STATE_OPENREQ: - get_openreq(st->syn_wait_sk, v, tmpbuf, st->num, st->uid); + get_openreq4(st->syn_wait_sk, v, tmpbuf, st->num, st->uid); break; case TCP_SEQ_STATE_TIME_WAIT: - get_timewait_sock(v, tmpbuf, st->num); + get_timewait4_sock(v, tmpbuf, st->num); break; } seq_printf(seq, "%-*s\n", TMPSZ - 1, tmpbuf); @@ -2535,57 +2580,23 @@ out: return 0; } -static struct seq_operations tcp_seq_ops = { - .start = tcp_seq_start, - .next = tcp_seq_next, - .stop = tcp_seq_stop, - .show = tcp_seq_show, -}; - -static int tcp_seq_open(struct inode *inode, struct file *file) -{ - struct seq_file *seq; - int rc = -ENOMEM; - struct tcp_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL); - - if (!s) - goto out; - rc = seq_open(file, &tcp_seq_ops); - if (rc) - goto out_kfree; - seq = file->private_data; - seq->private = s; - memset(s, 0, sizeof(*s)); -out: - return rc; -out_kfree: - kfree(s); - goto out; -} - -static struct file_operations tcp_seq_fops = { - .owner = THIS_MODULE, - .open = tcp_seq_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release_private, +static struct file_operations tcp4_seq_fops; +static struct tcp_seq_afinfo tcp4_seq_afinfo = { + .owner = THIS_MODULE, + .name = "tcp", + .family = AF_INET, + .seq_show = tcp4_seq_show, + .seq_fops = &tcp4_seq_fops, }; -int __init tcp_proc_init(void) +int __init tcp4_proc_init(void) { - int rc = 0; - struct proc_dir_entry *p = create_proc_entry("tcp", S_IRUGO, proc_net); - - if (p) - p->proc_fops = &tcp_seq_fops; - else - rc = -ENOMEM; - return rc; + return tcp_proc_register(&tcp4_seq_afinfo); } -void __init tcp_proc_exit(void) +void tcp4_proc_exit(void) { - remove_proc_entry("tcp", proc_net); + tcp_proc_unregister(&tcp4_seq_afinfo); } #endif /* CONFIG_PROC_FS */ diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index baf4d171ae62..c55c96c04f00 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -418,11 +418,15 @@ static int tcp_tw_death_row_slot = 0; static void tcp_twkill(unsigned long); +/* TIME_WAIT reaping mechanism. */ +#define TCP_TWKILL_SLOTS 8 /* Please keep this a power of 2. */ +#define TCP_TWKILL_PERIOD (TCP_TIMEWAIT_LEN/TCP_TWKILL_SLOTS) + static struct tcp_tw_bucket *tcp_tw_death_row[TCP_TWKILL_SLOTS]; static spinlock_t tw_death_lock = SPIN_LOCK_UNLOCKED; static struct timer_list tcp_tw_timer = TIMER_INITIALIZER(tcp_twkill, 0, 0); -static void SMP_TIMER_NAME(tcp_twkill)(unsigned long dummy) +static void tcp_twkill(unsigned long dummy) { struct tcp_tw_bucket *tw; int killed = 0; @@ -462,8 +466,6 @@ out: spin_unlock(&tw_death_lock); } -SMP_TIMER_DEFINE(tcp_twkill, tcp_twkill_task); - /* These are always called from BH context. See callers in * tcp_input.c to verify this. */ @@ -575,7 +577,7 @@ void tcp_tw_schedule(struct tcp_tw_bucket *tw, int timeo) spin_unlock(&tw_death_lock); } -void SMP_TIMER_NAME(tcp_twcal_tick)(unsigned long dummy) +void tcp_twcal_tick(unsigned long dummy) { int n, slot; unsigned long j; @@ -626,9 +628,6 @@ out: spin_unlock(&tw_death_lock); } -SMP_TIMER_DEFINE(tcp_twcal_tick, tcp_twcal_tasklet); - - /* This is not only more efficient than what we used to do, it eliminates * a lot of code duplication between IPv4/IPv6 SYN recv processing. -DaveM * diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 635b438058f5..6a5b119c42db 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1349,10 +1349,6 @@ struct proto udp_prot = { /* ------------------------------------------------------------------------ */ #ifdef CONFIG_PROC_FS -struct udp_iter_state { - int bucket; -}; - static __inline__ struct sock *udp_get_bucket(struct seq_file *seq, loff_t *pos) { int i; @@ -1362,7 +1358,7 @@ static __inline__ struct sock *udp_get_bucket(struct seq_file *seq, loff_t *pos) for (; state->bucket < UDP_HTABLE_SIZE; ++state->bucket) for (i = 0, sk = udp_hash[state->bucket]; sk; ++i, sk = sk->next) { - if (sk->family != PF_INET) + if (sk->family != state->family) continue; if (l--) continue; @@ -1389,15 +1385,16 @@ static void *udp_seq_next(struct seq_file *seq, void *v, loff_t *pos) goto out; } + state = seq->private; + sk = v; sk = sk->next; for (; sk; sk = sk->next) { - if (sk->family == AF_INET) + if (sk->family == state->family) goto out; } - state = seq->private; if (++state->bucket >= UDP_HTABLE_SIZE) goto out; @@ -1413,7 +1410,68 @@ static void udp_seq_stop(struct seq_file *seq, void *v) read_unlock(&udp_hash_lock); } -static void udp_format_sock(struct sock *sp, char *tmpbuf, int bucket) +static int udp_seq_open(struct inode *inode, struct file *file) +{ + struct udp_seq_afinfo *afinfo = PDE(inode)->data; + struct seq_file *seq; + int rc = -ENOMEM; + struct udp_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL); + + if (!s) + goto out; + memset(s, 0, sizeof(*s)); + s->family = afinfo->family; + s->seq_ops.start = udp_seq_start; + s->seq_ops.next = udp_seq_next; + s->seq_ops.show = afinfo->seq_show; + s->seq_ops.stop = udp_seq_stop; + + rc = seq_open(file, &s->seq_ops); + if (rc) + goto out_kfree; + + seq = file->private_data; + seq->private = s; +out: + return rc; +out_kfree: + kfree(s); + goto out; +} + +/* ------------------------------------------------------------------------ */ +int udp_proc_register(struct udp_seq_afinfo *afinfo) +{ + struct proc_dir_entry *p; + int rc = 0; + + if (!afinfo) + return -EINVAL; + afinfo->seq_fops->owner = afinfo->owner; + afinfo->seq_fops->open = udp_seq_open; + afinfo->seq_fops->read = seq_read; + afinfo->seq_fops->llseek = seq_lseek; + afinfo->seq_fops->release = seq_release_private; + + p = create_proc_entry(afinfo->name, S_IRUGO, proc_net); + if (p) { + p->data = afinfo; + p->proc_fops = afinfo->seq_fops; + } else + rc = -ENOMEM; + return rc; +} + +void udp_proc_unregister(struct udp_seq_afinfo *afinfo) +{ + if (!afinfo) + return; + remove_proc_entry(afinfo->name, proc_net); + memset(afinfo->seq_fops, 0, sizeof(*afinfo->seq_fops)); +} + +/* ------------------------------------------------------------------------ */ +static void udp4_format_sock(struct sock *sp, char *tmpbuf, int bucket) { struct inet_opt *inet = inet_sk(sp); unsigned int dest = inet->daddr; @@ -1429,7 +1487,7 @@ static void udp_format_sock(struct sock *sp, char *tmpbuf, int bucket) atomic_read(&sp->refcnt), sp); } -static int udp_seq_show(struct seq_file *seq, void *v) +static int udp4_seq_show(struct seq_file *seq, void *v) { if (v == (void *)1) seq_printf(seq, "%-127s\n", @@ -1440,68 +1498,29 @@ static int udp_seq_show(struct seq_file *seq, void *v) char tmpbuf[129]; struct udp_iter_state *state = seq->private; - udp_format_sock(v, tmpbuf, state->bucket); + udp4_format_sock(v, tmpbuf, state->bucket); seq_printf(seq, "%-127s\n", tmpbuf); } return 0; } -/* ------------------------------------------------------------------------ */ - -static struct seq_operations udp_seq_ops = { - .start = udp_seq_start, - .next = udp_seq_next, - .stop = udp_seq_stop, - .show = udp_seq_show, -}; - -static int udp_seq_open(struct inode *inode, struct file *file) -{ - struct seq_file *seq; - int rc = -ENOMEM; - struct udp_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL); - - if (!s) - goto out; - - rc = seq_open(file, &udp_seq_ops); - if (rc) - goto out_kfree; - seq = file->private_data; - seq->private = s; - memset(s, 0, sizeof(*s)); -out: - return rc; -out_kfree: - kfree(s); - goto out; -} - -static struct file_operations udp_seq_fops = { +/* ------------------------------------------------------------------------ */ +static struct file_operations udp4_seq_fops; +static struct udp_seq_afinfo udp4_seq_afinfo = { .owner = THIS_MODULE, - .open = udp_seq_open, - .read = seq_read, - .llseek = seq_lseek, - .release = seq_release_private, + .name = "udp", + .family = AF_INET, + .seq_show = udp4_seq_show, + .seq_fops = &udp4_seq_fops, }; -/* ------------------------------------------------------------------------ */ - -int __init udp_proc_init(void) +int __init udp4_proc_init(void) { - struct proc_dir_entry *p; - int rc = 0; - - p = create_proc_entry("udp", S_IRUGO, proc_net); - if (p) - p->proc_fops = &udp_seq_fops; - else - rc = -ENOMEM; - return rc; + return udp_proc_register(&udp4_seq_afinfo); } -void __init udp_proc_exit(void) +void udp4_proc_exit(void) { - remove_proc_entry("udp", proc_net); + udp_proc_unregister(&udp4_seq_afinfo); } #endif /* CONFIG_PROC_FS */ diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 25821a76d765..c77815599497 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -77,8 +77,11 @@ MODULE_LICENSE("GPL"); extern int raw6_proc_init(void); extern int raw6_proc_exit(void); -extern int tcp6_get_info(char *, char **, off_t, int); -extern int udp6_get_info(char *, char **, off_t, int); +extern int tcp6_proc_init(void); +extern void tcp6_proc_exit(void); + +extern int udp6_proc_init(void); +extern void udp6_proc_exit(void); extern int ipv6_misc_proc_init(void); extern int ipv6_misc_proc_exit(void); @@ -787,9 +790,9 @@ static int __init inet6_init(void) err = -ENOMEM; if (raw6_proc_init()) goto proc_raw6_fail; - if (!proc_net_create("tcp6", 0, tcp6_get_info)) + if (tcp6_proc_init()) goto proc_tcp6_fail; - if (!proc_net_create("udp6", 0, udp6_get_info)) + if (udp6_proc_init()) goto proc_udp6_fail; if (ipv6_misc_proc_init()) goto proc_misc6_fail; @@ -820,9 +823,9 @@ static int __init inet6_init(void) proc_anycast6_fail: ipv6_misc_proc_exit(); proc_misc6_fail: - proc_net_remove("udp6"); + udp6_proc_exit(); proc_udp6_fail: - proc_net_remove("tcp6"); + tcp6_proc_exit(); proc_tcp6_fail: raw6_proc_exit(); proc_raw6_fail: diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index d2920063972c..ebcbc30701c5 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -17,6 +17,7 @@ * YOSHIFUJI Hideaki @USAGI and: Support IPV6_V6ONLY socket option, which * Alexey Kuznetsov allow both IPv4 and IPv6 sockets to bind * a single port at the same time. + * YOSHIFUJI Hideaki @USAGI: convert /proc/net/tcp6 to seq_file. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -55,6 +56,9 @@ #include <asm/uaccess.h> +#include <linux/proc_fs.h> +#include <linux/seq_file.h> + static void tcp_v6_send_reset(struct sk_buff *skb); static void tcp_v6_or_send_ack(struct sk_buff *skb, struct open_request *req); static void tcp_v6_send_check(struct sock *sk, struct tcphdr *th, int len, @@ -1934,7 +1938,8 @@ static int tcp_v6_destroy_sock(struct sock *sk) } /* Proc filesystem TCPv6 sock list dumping. */ -static void get_openreq6(struct sock *sk, struct open_request *req, char *tmpbuf, int i, int uid) +static void get_openreq6(struct seq_file *seq, + struct sock *sk, struct open_request *req, int i, int uid) { struct in6_addr *dest, *src; int ttd = req->expires - jiffies; @@ -1944,28 +1949,28 @@ static void get_openreq6(struct sock *sk, struct open_request *req, char *tmpbuf src = &req->af.v6_req.loc_addr; dest = &req->af.v6_req.rmt_addr; - sprintf(tmpbuf, - "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " - "%02X %08X:%08X %02X:%08X %08X %5d %8d %d %d %p", - i, - src->s6_addr32[0], src->s6_addr32[1], - src->s6_addr32[2], src->s6_addr32[3], - ntohs(inet_sk(sk)->sport), - dest->s6_addr32[0], dest->s6_addr32[1], - dest->s6_addr32[2], dest->s6_addr32[3], - ntohs(req->rmt_port), - TCP_SYN_RECV, - 0,0, /* could print option size, but that is af dependent. */ - 1, /* timers active (only the expire timer) */ - ttd, - req->retrans, - uid, - 0, /* non standard timer */ - 0, /* open_requests have no inode */ - 0, req); + seq_printf(seq, + "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " + "%02X %08X:%08X %02X:%08X %08X %5d %8d %d %d %p\n", + i, + src->s6_addr32[0], src->s6_addr32[1], + src->s6_addr32[2], src->s6_addr32[3], + ntohs(inet_sk(sk)->sport), + dest->s6_addr32[0], dest->s6_addr32[1], + dest->s6_addr32[2], dest->s6_addr32[3], + ntohs(req->rmt_port), + TCP_SYN_RECV, + 0,0, /* could print option size, but that is af dependent. */ + 1, /* timers active (only the expire timer) */ + ttd, + req->retrans, + uid, + 0, /* non standard timer */ + 0, /* open_requests have no inode */ + 0, req); } -static void get_tcp6_sock(struct sock *sp, char *tmpbuf, int i) +static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i) { struct in6_addr *dest, *src; __u16 destp, srcp; @@ -1993,28 +1998,29 @@ static void get_tcp6_sock(struct sock *sp, char *tmpbuf, int i) timer_expires = jiffies; } - sprintf(tmpbuf, - "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " - "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %u %u %u %u %d", - i, - src->s6_addr32[0], src->s6_addr32[1], - src->s6_addr32[2], src->s6_addr32[3], srcp, - dest->s6_addr32[0], dest->s6_addr32[1], - dest->s6_addr32[2], dest->s6_addr32[3], destp, - sp->state, - tp->write_seq-tp->snd_una, tp->rcv_nxt-tp->copied_seq, - timer_active, timer_expires-jiffies, - tp->retransmits, - sock_i_uid(sp), - tp->probes_out, - sock_i_ino(sp), - atomic_read(&sp->refcnt), sp, - tp->rto, tp->ack.ato, (tp->ack.quick<<1)|tp->ack.pingpong, - tp->snd_cwnd, tp->snd_ssthresh>=0xFFFF?-1:tp->snd_ssthresh - ); + seq_printf(seq, + "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " + "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %u %u %u %u %d\n", + i, + src->s6_addr32[0], src->s6_addr32[1], + src->s6_addr32[2], src->s6_addr32[3], srcp, + dest->s6_addr32[0], dest->s6_addr32[1], + dest->s6_addr32[2], dest->s6_addr32[3], destp, + sp->state, + tp->write_seq-tp->snd_una, tp->rcv_nxt-tp->copied_seq, + timer_active, timer_expires-jiffies, + tp->retransmits, + sock_i_uid(sp), + tp->probes_out, + sock_i_ino(sp), + atomic_read(&sp->refcnt), sp, + tp->rto, tp->ack.ato, (tp->ack.quick<<1)|tp->ack.pingpong, + tp->snd_cwnd, tp->snd_ssthresh>=0xFFFF?-1:tp->snd_ssthresh + ); } -static void get_timewait6_sock(struct tcp_tw_bucket *tw, char *tmpbuf, int i) +static void get_timewait6_sock(struct seq_file *seq, + struct tcp_tw_bucket *tw, int i) { struct in6_addr *dest, *src; __u16 destp, srcp; @@ -2028,144 +2034,67 @@ static void get_timewait6_sock(struct tcp_tw_bucket *tw, char *tmpbuf, int i) destp = ntohs(tw->dport); srcp = ntohs(tw->sport); - sprintf(tmpbuf, - "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " - "%02X %08X:%08X %02X:%08X %08X %5d %8d %d %d %p", - i, - src->s6_addr32[0], src->s6_addr32[1], - src->s6_addr32[2], src->s6_addr32[3], srcp, - dest->s6_addr32[0], dest->s6_addr32[1], - dest->s6_addr32[2], dest->s6_addr32[3], destp, - tw->substate, 0, 0, - 3, ttd, 0, 0, 0, 0, - atomic_read(&tw->refcnt), tw); + seq_printf(seq, + "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " + "%02X %08X:%08X %02X:%08X %08X %5d %8d %d %d %p\n", + i, + src->s6_addr32[0], src->s6_addr32[1], + src->s6_addr32[2], src->s6_addr32[3], srcp, + dest->s6_addr32[0], dest->s6_addr32[1], + dest->s6_addr32[2], dest->s6_addr32[3], destp, + tw->substate, 0, 0, + 3, ttd, 0, 0, 0, 0, + atomic_read(&tw->refcnt), tw); } -#define LINE_LEN 190 -#define LINE_FMT "%-190s\n" - -int tcp6_get_info(char *buffer, char **start, off_t offset, int length) +static int tcp6_seq_show(struct seq_file *seq, void *v) { - int len = 0, num = 0, i; - off_t begin, pos = 0; - char tmpbuf[LINE_LEN+2]; - - if (offset < LINE_LEN+1) - len += sprintf(buffer, LINE_FMT, - " sl " /* 6 */ - "local_address " /* 38 */ - "remote_address " /* 38 */ - "st tx_queue rx_queue tr tm->when retrnsmt" /* 41 */ - " uid timeout inode"); /* 21 */ - /*----*/ - /*144 */ - - pos = LINE_LEN+1; - - /* First, walk listening socket table. */ - tcp_listen_lock(); - for(i = 0; i < TCP_LHTABLE_SIZE; i++) { - struct sock *sk = tcp_listening_hash[i]; - struct tcp_listen_opt *lopt; - int k; - - for (sk = tcp_listening_hash[i]; sk; sk = sk->next, num++) { - struct open_request *req; - int uid; - struct tcp_opt *tp = tcp_sk(sk); - - if (sk->family != PF_INET6) - continue; - pos += LINE_LEN+1; - if (pos >= offset) { - get_tcp6_sock(sk, tmpbuf, num); - len += sprintf(buffer+len, LINE_FMT, tmpbuf); - if (pos >= offset + length) { - tcp_listen_unlock(); - goto out_no_bh; - } - } - - uid = sock_i_uid(sk); - read_lock_bh(&tp->syn_wait_lock); - lopt = tp->listen_opt; - if (lopt && lopt->qlen != 0) { - for (k=0; k<TCP_SYNQ_HSIZE; k++) { - for (req = lopt->syn_table[k]; req; req = req->dl_next, num++) { - if (req->class->family != PF_INET6) - continue; - pos += LINE_LEN+1; - if (pos <= offset) - continue; - get_openreq6(sk, req, tmpbuf, num, uid); - len += sprintf(buffer+len, LINE_FMT, tmpbuf); - if (pos >= offset + length) { - read_unlock_bh(&tp->syn_wait_lock); - tcp_listen_unlock(); - goto out_no_bh; - } - } - } - } - read_unlock_bh(&tp->syn_wait_lock); + struct tcp_iter_state *st; + + if (v == (void *)1) { + seq_printf(seq, + " sl " + "local_address " + "remote_address " + "st tx_queue rx_queue tr tm->when retrnsmt" + " uid timeout inode\n"); + goto out; + } + st = seq->private; - /* Completed requests are in normal socket hash table */ - } + switch (st->state) { + case TCP_SEQ_STATE_LISTENING: + case TCP_SEQ_STATE_ESTABLISHED: + get_tcp6_sock(seq, v, st->num); + break; + case TCP_SEQ_STATE_OPENREQ: + get_openreq6(seq, st->syn_wait_sk, v, st->num, st->uid); + break; + case TCP_SEQ_STATE_TIME_WAIT: + get_timewait6_sock(seq, v, st->num); + break; } - tcp_listen_unlock(); +out: + return 0; +} - local_bh_disable(); +static struct file_operations tcp6_seq_fops; +static struct tcp_seq_afinfo tcp6_seq_afinfo = { + .owner = THIS_MODULE, + .name = "tcp6", + .family = AF_INET6, + .seq_show = tcp6_seq_show, + .seq_fops = &tcp6_seq_fops, +}; - /* Next, walk established hash chain. */ - for (i = 0; i < tcp_ehash_size; i++) { - struct tcp_ehash_bucket *head = &tcp_ehash[i]; - struct sock *sk; - struct tcp_tw_bucket *tw; - - read_lock(&head->lock); - for(sk = head->chain; sk; sk = sk->next, num++) { - if (sk->family != PF_INET6) - continue; - pos += LINE_LEN+1; - if (pos <= offset) - continue; - get_tcp6_sock(sk, tmpbuf, num); - len += sprintf(buffer+len, LINE_FMT, tmpbuf); - if (pos >= offset + length) { - read_unlock(&head->lock); - goto out; - } - } - for (tw = (struct tcp_tw_bucket *)tcp_ehash[i+tcp_ehash_size].chain; - tw != NULL; - tw = (struct tcp_tw_bucket *)tw->next, num++) { - if (tw->family != PF_INET6) - continue; - pos += LINE_LEN+1; - if (pos <= offset) - continue; - get_timewait6_sock(tw, tmpbuf, num); - len += sprintf(buffer+len, LINE_FMT, tmpbuf); - if (pos >= offset + length) { - read_unlock(&head->lock); - goto out; - } - } - read_unlock(&head->lock); - } +int __init tcp6_proc_init(void) +{ + return tcp_proc_register(&tcp6_seq_afinfo); +} -out: - local_bh_enable(); -out_no_bh: - - begin = len - (pos - offset); - *start = buffer + begin; - len -= begin; - if (len > length) - len = length; - if (len < 0) - len = 0; - return len; +void tcp6_proc_exit(void) +{ + tcp_proc_unregister(&tcp6_seq_afinfo); } struct proto tcpv6_prot = { diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index fc3dd9c50b1e..4166095e1ce7 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -15,6 +15,7 @@ * Alexey Kuznetsov allow both IPv4 and IPv6 sockets to bind * a single port at the same time. * Kazunori MIYAZAWA @USAGI: change process style to use ip6_append_data + * YOSHIFUJI Hideaki @USAGI: convert /proc/net/udp6 to seq_file. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -53,6 +54,9 @@ #include <net/checksum.h> #include <net/xfrm.h> +#include <linux/proc_fs.h> +#include <linux/seq_file.h> + DEFINE_SNMP_STAT(struct udp_mib, udp_stats_in6); /* XXX This is identical to tcp_ipv6.c:ipv6_rcv_saddr_equal, put @@ -1116,10 +1120,10 @@ static struct inet6_protocol udpv6_protocol = { .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, }; -#define LINE_LEN 190 -#define LINE_FMT "%-190s\n" +/* ------------------------------------------------------------------------ */ +#ifdef CONFIG_PROC_FS -static void get_udp6_sock(struct sock *sp, char *tmpbuf, int i) +static void udp6_sock_seq_show(struct seq_file *seq, struct sock *sp, int bucket) { struct inet_opt *inet = inet_sk(sp); struct ipv6_pinfo *np = inet6_sk(sp); @@ -1130,66 +1134,56 @@ static void get_udp6_sock(struct sock *sp, char *tmpbuf, int i) src = &np->rcv_saddr; destp = ntohs(inet->dport); srcp = ntohs(inet->sport); - sprintf(tmpbuf, - "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " - "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p", - i, - src->s6_addr32[0], src->s6_addr32[1], - src->s6_addr32[2], src->s6_addr32[3], srcp, - dest->s6_addr32[0], dest->s6_addr32[1], - dest->s6_addr32[2], dest->s6_addr32[3], destp, - sp->state, - atomic_read(&sp->wmem_alloc), atomic_read(&sp->rmem_alloc), - 0, 0L, 0, - sock_i_uid(sp), 0, - sock_i_ino(sp), - atomic_read(&sp->refcnt), sp); + seq_printf(seq, + "%4d: %08X%08X%08X%08X:%04X %08X%08X%08X%08X:%04X " + "%02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p\n", + bucket, + src->s6_addr32[0], src->s6_addr32[1], + src->s6_addr32[2], src->s6_addr32[3], srcp, + dest->s6_addr32[0], dest->s6_addr32[1], + dest->s6_addr32[2], dest->s6_addr32[3], destp, + sp->state, + atomic_read(&sp->wmem_alloc), atomic_read(&sp->rmem_alloc), + 0, 0L, 0, + sock_i_uid(sp), 0, + sock_i_ino(sp), + atomic_read(&sp->refcnt), sp); } -int udp6_get_info(char *buffer, char **start, off_t offset, int length) +static int udp6_seq_show(struct seq_file *seq, void *v) { - int len = 0, num = 0, i; - off_t pos = 0; - off_t begin; - char tmpbuf[LINE_LEN+2]; - - if (offset < LINE_LEN+1) - len += sprintf(buffer, LINE_FMT, - " sl " /* 6 */ - "local_address " /* 38 */ - "remote_address " /* 38 */ - "st tx_queue rx_queue tr tm->when retrnsmt" /* 41 */ - " uid timeout inode"); /* 21 */ - /*----*/ - /*144 */ - pos = LINE_LEN+1; - read_lock(&udp_hash_lock); - for (i = 0; i < UDP_HTABLE_SIZE; i++) { - struct sock *sk; + if (v == (void *)1) + seq_printf(seq, + " sl " + "local_address " + "remote_address " + "st tx_queue rx_queue tr tm->when retrnsmt" + " uid timeout inode\n"); + else + udp6_sock_seq_show(seq, v, ((struct udp_iter_state *)seq->private)->bucket); + return 0; +} - for (sk = udp_hash[i]; sk; sk = sk->next, num++) { - if (sk->family != PF_INET6) - continue; - pos += LINE_LEN+1; - if (pos <= offset) - continue; - get_udp6_sock(sk, tmpbuf, i); - len += sprintf(buffer+len, LINE_FMT, tmpbuf); - if(len >= length) - goto out; - } - } -out: - read_unlock(&udp_hash_lock); - begin = len - (pos - offset); - *start = buffer + begin; - len -= begin; - if(len > length) - len = length; - if (len < 0) - len = 0; - return len; +static struct file_operations udp6_seq_fops; +static struct udp_seq_afinfo udp6_seq_afinfo = { + .owner = THIS_MODULE, + .name = "udp6", + .family = AF_INET6, + .seq_show = udp6_seq_show, + .seq_fops = &udp6_seq_fops, +}; + +int __init udp6_proc_init(void) +{ + return udp_proc_register(&udp6_seq_afinfo); +} + +void udp6_proc_exit(void) { + udp_proc_unregister(&udp6_seq_afinfo); } +#endif /* CONFIG_PROC_FS */ + +/* ------------------------------------------------------------------------ */ struct proto udpv6_prot = { .name = "UDP", diff --git a/net/irda/ircomm/ircomm_lmp.c b/net/irda/ircomm/ircomm_lmp.c index af27a51d08c5..a773b35c66cb 100644 --- a/net/irda/ircomm/ircomm_lmp.c +++ b/net/irda/ircomm/ircomm_lmp.c @@ -60,7 +60,7 @@ int ircomm_open_lsap(struct ircomm_cb *self) notify.connect_indication = ircomm_lmp_connect_indication; notify.disconnect_indication = ircomm_lmp_disconnect_indication; notify.instance = self; - strncpy(notify.name, "IrCOMM", NOTIFY_MAX_NAME); + strlcpy(notify.name, "IrCOMM", sizeof(notify.name)); self->lsap = irlmp_open_lsap(LSAP_ANY, ¬ify, 0); if (!self->lsap) { diff --git a/net/irda/ircomm/ircomm_ttp.c b/net/irda/ircomm/ircomm_ttp.c index c3b946e40fe6..fc453c3ad55e 100644 --- a/net/irda/ircomm/ircomm_ttp.c +++ b/net/irda/ircomm/ircomm_ttp.c @@ -60,7 +60,7 @@ int ircomm_open_tsap(struct ircomm_cb *self) notify.flow_indication = ircomm_ttp_flow_indication; notify.disconnect_indication = ircomm_ttp_disconnect_indication; notify.instance = self; - strncpy(notify.name, "IrCOMM", NOTIFY_MAX_NAME); + strlcpy(notify.name, "IrCOMM", sizeof(notify.name)); self->tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT, ¬ify); diff --git a/net/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c index 19a25ea6c3b9..35d77efe0632 100644 --- a/net/irda/ircomm/ircomm_tty.c +++ b/net/irda/ircomm/ircomm_tty.c @@ -205,7 +205,7 @@ static int ircomm_tty_startup(struct ircomm_tty_cb *self) notify.disconnect_indication = ircomm_tty_disconnect_indication; notify.connect_confirm = ircomm_tty_connect_confirm; notify.connect_indication = ircomm_tty_connect_indication; - strncpy(notify.name, "ircomm_tty", NOTIFY_MAX_NAME); + strlcpy(notify.name, "ircomm_tty", sizeof(notify.name)); notify.instance = self; if (!self->ircomm) { diff --git a/net/irda/irda_device.c b/net/irda/irda_device.c index c368b7fc72fc..743abb29c164 100644 --- a/net/irda/irda_device.c +++ b/net/irda/irda_device.c @@ -532,6 +532,7 @@ int irda_device_set_mode(struct net_device* dev, int mode) return ret; } +#ifdef CONFIG_ISA /* * Function setup_dma (idev, buffer, count, mode) * @@ -553,3 +554,4 @@ void setup_dma(int channel, char *buffer, int count, int mode) release_dma_lock(flags); } +#endif diff --git a/net/irda/irlan/irlan_client.c b/net/irda/irlan/irlan_client.c index f2bd3ec639d4..e142dbb0172e 100644 --- a/net/irda/irlan/irlan_client.c +++ b/net/irda/irlan/irlan_client.c @@ -268,7 +268,7 @@ void irlan_client_open_ctrl_tsap(struct irlan_cb *self) notify.connect_confirm = irlan_client_ctrl_connect_confirm; notify.disconnect_indication = irlan_client_ctrl_disconnect_indication; notify.instance = self; - strncpy(notify.name, "IrLAN ctrl (c)", NOTIFY_MAX_NAME); + strlcpy(notify.name, "IrLAN ctrl (c)", sizeof(notify.name)); tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT, ¬ify); if (!tsap) { diff --git a/net/irda/irlan/irlan_common.c b/net/irda/irlan/irlan_common.c index 69236887ac55..9f9338017a04 100644 --- a/net/irda/irlan/irlan_common.c +++ b/net/irda/irlan/irlan_common.c @@ -465,7 +465,7 @@ void irlan_open_data_tsap(struct irlan_cb *self) /*notify.flow_indication = irlan_eth_flow_indication;*/ notify.disconnect_indication = irlan_disconnect_indication; notify.instance = self; - strncpy(notify.name, "IrLAN data", NOTIFY_MAX_NAME); + strlcpy(notify.name, "IrLAN data", sizeof(notify.name)); tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT, ¬ify); if (!tsap) { diff --git a/net/irda/irlan/irlan_provider.c b/net/irda/irlan/irlan_provider.c index af9c50e4bd14..c7f26728cef9 100644 --- a/net/irda/irlan/irlan_provider.c +++ b/net/irda/irlan/irlan_provider.c @@ -396,7 +396,7 @@ int irlan_provider_open_ctrl_tsap(struct irlan_cb *self) notify.connect_indication = irlan_provider_connect_indication; notify.disconnect_indication = irlan_provider_disconnect_indication; notify.instance = self; - strncpy(notify.name, "IrLAN ctrl (p)", 16); + strlcpy(notify.name, "IrLAN ctrl (p)", sizeof(notify.name)); tsap = irttp_open_tsap(LSAP_ANY, 1, ¬ify); if (!tsap) { diff --git a/net/irda/irlap.c b/net/irda/irlap.c index 627278c5fef9..33b099d004da 100644 --- a/net/irda/irlap.c +++ b/net/irda/irlap.c @@ -122,8 +122,7 @@ struct irlap_cb *irlap_open(struct net_device *dev, struct qos_info *qos, self->qos_dev = qos; /* Copy hardware name */ if(hw_name != NULL) { - strncpy(self->hw_name, hw_name, 2*IFNAMSIZ); - self->hw_name[2*IFNAMSIZ] = '\0'; + strlcpy(self->hw_name, hw_name, sizeof(self->hw_name)); } else { self->hw_name[0] = '\0'; } diff --git a/net/irda/irnet/irnet_irda.c b/net/irda/irnet/irnet_irda.c index 83966549d07f..45dc5b03c168 100644 --- a/net/irda/irnet/irnet_irda.c +++ b/net/irda/irnet/irnet_irda.c @@ -114,7 +114,7 @@ irnet_open_tsap(irnet_socket * self) notify.flow_indication = irnet_flow_indication; notify.status_indication = irnet_status_indication; notify.instance = self; - strncpy(notify.name, IRNET_NOTIFY_NAME, NOTIFY_MAX_NAME); + strlcpy(notify.name, IRNET_NOTIFY_NAME, sizeof(notify.name)); /* Open an IrTTP instance */ self->tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT, @@ -692,7 +692,7 @@ irnet_daddr_to_dname(irnet_socket * self) if(discoveries[i].daddr == self->daddr) { /* Yes !!! Get it.. */ - strncpy(self->rname, discoveries[i].info, NICKNAME_MAX_LEN); + strlcpy(self->rname, discoveries[i].info, sizeof(self->rname)); self->rname[NICKNAME_MAX_LEN + 1] = '\0'; DEBUG(IRDA_SERV_INFO, "Device 0x%08x is in fact ``%s''.\n", self->daddr, self->rname); diff --git a/net/irda/irqueue.c b/net/irda/irqueue.c index a5e5b73e35a3..9f2e1d829b3b 100644 --- a/net/irda/irqueue.c +++ b/net/irda/irqueue.c @@ -594,7 +594,7 @@ void hashbin_insert(hashbin_t* hashbin, irda_queue_t* entry, long hashv, char* n */ entry->q_hash = hashv; if ( name ) - strncpy( entry->q_name, name, 32); + strlcpy( entry->q_name, name, sizeof(entry->q_name)); /* * Insert new entry first diff --git a/net/irda/irsyms.c b/net/irda/irsyms.c index ec7363528e14..70baa3fbef5f 100644 --- a/net/irda/irsyms.c +++ b/net/irda/irsyms.c @@ -167,7 +167,9 @@ EXPORT_SYMBOL(async_unwrap_char); EXPORT_SYMBOL(irda_calc_crc16); EXPORT_SYMBOL(irda_crc16_table); EXPORT_SYMBOL(irda_start_timer); +#ifdef CONFIG_ISA EXPORT_SYMBOL(setup_dma); +#endif EXPORT_SYMBOL(infrared_mode); #ifdef CONFIG_IRTTY @@ -248,7 +250,7 @@ void irda_notify_init(notify_t *notify) notify->flow_indication = NULL; notify->status_indication = NULL; notify->instance = NULL; - strncpy(notify->name, "Unknown", NOTIFY_MAX_NAME); + strlcpy(notify->name, "Unknown", sizeof(notify->name)); } /* diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 166e23a5d3fb..0474f80ea9be 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -1070,9 +1070,6 @@ static int __init netlink_proto_init(void) #endif /* The netlink device handler may be needed early. */ rtnetlink_init(); -#ifdef CONFIG_NETLINK_DEV - init_netlink(); -#endif return 0; } diff --git a/net/netlink/netlink_dev.c b/net/netlink/netlink_dev.c index c38bdcb138d0..813e6431d83a 100644 --- a/net/netlink/netlink_dev.c +++ b/net/netlink/netlink_dev.c @@ -220,7 +220,7 @@ static struct { }, }; -int __init init_netlink(void) +static int __init init_netlink(void) { int i; @@ -245,17 +245,7 @@ int __init init_netlink(void) return 0; } -#ifdef MODULE - -MODULE_LICENSE("GPL"); - -int init_module(void) -{ - printk(KERN_INFO "Network Kernel/User communications module 0.04\n"); - return init_netlink(); -} - -void cleanup_module(void) +static void __exit cleanup_netlink(void) { int i; @@ -267,4 +257,6 @@ void cleanup_module(void) unregister_chrdev(NETLINK_MAJOR, "netlink"); } -#endif +MODULE_LICENSE("GPL"); +module_init(init_netlink); +module_exit(cleanup_netlink); diff --git a/net/netsyms.c b/net/netsyms.c index e5599bd13c8a..c153585701e3 100644 --- a/net/netsyms.c +++ b/net/netsyms.c @@ -281,6 +281,14 @@ EXPORT_SYMBOL(devinet_ioctl); EXPORT_SYMBOL(register_inetaddr_notifier); EXPORT_SYMBOL(unregister_inetaddr_notifier); +/* proc */ +#ifdef CONFIG_PROC_FS +EXPORT_SYMBOL(udp_proc_register); +EXPORT_SYMBOL(udp_proc_unregister); +EXPORT_SYMBOL(tcp_proc_register); +EXPORT_SYMBOL(tcp_proc_unregister); +#endif + /* needed for ip_gre -cw */ EXPORT_SYMBOL(ip_statistics); diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index a83a22015c04..80b256e14de9 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -255,7 +255,7 @@ static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev, struct */ spkt->spkt_family = dev->type; - strncpy(spkt->spkt_device, dev->name, sizeof(spkt->spkt_device)); + strlcpy(spkt->spkt_device, dev->name, sizeof(spkt->spkt_device)); spkt->spkt_protocol = skb->protocol; /* @@ -878,8 +878,7 @@ static int packet_bind_spkt(struct socket *sock, struct sockaddr *uaddr, int add if(addr_len!=sizeof(struct sockaddr)) return -EINVAL; - strncpy(name,uaddr->sa_data,14); - name[14]=0; + strlcpy(name,uaddr->sa_data,sizeof(name)); dev = dev_get_by_name(name); if (dev) { @@ -1096,7 +1095,7 @@ static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr, uaddr->sa_family = AF_PACKET; dev = dev_get_by_index(pkt_sk(sk)->ifindex); if (dev) { - strncpy(uaddr->sa_data, dev->name, 15); + strlcpy(uaddr->sa_data, dev->name, 15); dev_put(dev); } else memset(uaddr->sa_data, 0, 14); diff --git a/net/wanrouter/af_wanpipe.c b/net/wanrouter/af_wanpipe.c index 3b179a0f65d1..9dd12c56a964 100644 --- a/net/wanrouter/af_wanpipe.c +++ b/net/wanrouter/af_wanpipe.c @@ -1408,8 +1408,7 @@ static int wanpipe_bind(struct socket *sock, struct sockaddr *uaddr, int addr_le /* Bind a socket to a interface name * This is used by PVC mostly */ - strncpy(name,sll->sll_device,14); - name[14]=0; + strlcpy(name,sll->sll_device,sizeof(name)); dev = dev_get_by_name(name); if (dev == NULL){ printk(KERN_INFO "wansock: Failed to get Dev from name: %s,\n", diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 291b51b616e8..cecce180ea97 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -634,6 +634,7 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr struct xfrm_userpolicy_info *p = NLMSG_DATA(nlh); struct xfrm_policy *xp; int err; + int excl; err = verify_newpolicy_info(p); if (err) @@ -643,7 +644,8 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr if (!xp) return err; - err = xfrm_policy_insert(p->dir, xp, 1); + excl = nlh->nlmsg_type == XFRM_MSG_NEWPOLICY; + err = xfrm_policy_insert(p->dir, xp, excl); if (err) { kfree(xp); return err; @@ -803,6 +805,7 @@ static const int xfrm_msg_min[(XFRM_MSG_MAX + 1 - XFRM_MSG_BASE)] = { NLMSG_LENGTH(sizeof(struct xfrm_userspi_info)), /* ALLOC SPI */ NLMSG_LENGTH(sizeof(struct xfrm_user_acquire)), /* ACQUIRE */ NLMSG_LENGTH(sizeof(struct xfrm_user_expire)), /* EXPIRE */ + NLMSG_LENGTH(sizeof(struct xfrm_userpolicy_info)),/* UPD POLICY */ }; static struct xfrm_link { @@ -822,6 +825,9 @@ static struct xfrm_link { .dump = xfrm_dump_policy, }, { .doit = xfrm_alloc_userspi }, + {}, + {}, + { .doit = xfrm_add_policy }, }; static int xfrm_done(struct netlink_callback *cb) |
