diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1997-06-17 13:20:30 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1997-06-17 13:20:30 +0000 |
commit | 7acb77a6e7bddd4c4c5aa975bbf976927c013798 (patch) | |
tree | 4139829ec6edb85f73774bb95cdec376758bfc73 /net | |
parent | 64d58d4c8cd6a89ee218301ec0dc0ebfec91a4db (diff) |
Merge with 2.1.43.
Diffstat (limited to 'net')
34 files changed, 351 insertions, 148 deletions
diff --git a/net/Config.in b/net/Config.in index 97441ad6c..4cd3619c3 100644 --- a/net/Config.in +++ b/net/Config.in @@ -42,6 +42,10 @@ if [ "$CONFIG_AX25" != "n" ]; then dep_tristate 'Amateur Radio X.25 PLP (Rose)' CONFIG_ROSE $CONFIG_AX25 fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then +# tristate 'DECnet Support (NOT YET FUNCTIONAL)' CONFIG_DECNET +# if [ "$CONFIG_DECNET" != "n" ]; then +# source net/decnet/Config.in +# fi tristate 'CCITT X.25 Packet Layer (EXPERIMENTAL)' CONFIG_X25 tristate 'LAPB Data Link Driver (EXPERIMENTAL)' CONFIG_LAPB bool 'Bridging (EXPERIMENTAL)' CONFIG_BRIDGE diff --git a/net/Makefile b/net/Makefile index 9c45939cb..09924ff89 100644 --- a/net/Makefile +++ b/net/Makefile @@ -105,6 +105,14 @@ else endif endif +ifeq ($(CONFIG_DECNET),y) +SUB_DIRS += decnet +else + ifeq ($(CONFIG_DECNET),m) + MOD_SUB_DIRS += decnet + endif +endif + # We must attach netsyms.o to socket.o, as otherwise there is nothing # to pull the object file from the archive. diff --git a/net/README b/net/README index 09327483c..a88ccfc5a 100644 --- a/net/README +++ b/net/README @@ -8,6 +8,7 @@ Code Section Bug Report Contact appletalk alan@lxorguk.ukuu.org.uk and netatalk@umich.edu ax25 jsn@cs.nott.ac.uk core alan@lxorguk.ukuu.org.uk +decnet SteveW@ACM.org ethernet alan@lxorguk.ukuu.org.uk ipv4 davem@caip.rutgers.edu,Eric.Schenk@dna.lth.se ipv6 davem@caip.rutgers.edu,Eric.Schenk@dna.lth.se diff --git a/net/appletalk/aarp.c b/net/appletalk/aarp.c index 9ad9b8e93..f8a510e62 100644 --- a/net/appletalk/aarp.c +++ b/net/appletalk/aarp.c @@ -49,6 +49,12 @@ #include <linux/atalk.h> #include <linux/init.h> + +int sysctl_aarp_expiry_time = AARP_EXPIRY_TIME; +int sysctl_aarp_tick_time = AARP_TICK_TIME; +int sysctl_aarp_retransmit_limit = AARP_RETRANSMIT_LIMIT; +int sysctl_aarp_resolve_time = AARP_RESOLVE_TIME; + /* * Lists of aarp entries */ @@ -309,7 +315,7 @@ static void aarp_kick(struct aarp_entry **n) { /* Expired - if this will be the 11th transmit, we delete instead */ - if((*n)->xmit_count>=AARP_RETRANSMIT_LIMIT) + if((*n)->xmit_count>=sysctl_aarp_retransmit_limit) { t= *n; *n=(*n)->next; @@ -359,9 +365,9 @@ static void aarp_expire_timeout(unsigned long unused) } del_timer(&aarp_timer); if(unresolved_count==0) - aarp_timer.expires=jiffies+AARP_EXPIRY_TIME; + aarp_timer.expires=jiffies+sysctl_aarp_expiry_time; else - aarp_timer.expires=jiffies+AARP_TICK_TIME; + aarp_timer.expires=jiffies+sysctl_aarp_tick_time; add_timer(&aarp_timer); } @@ -475,6 +481,21 @@ int aarp_send_ddp(struct device *dev,struct sk_buff *skb, struct at_addr *sa, vo dev_queue_xmit(skb); return 1; } + + /* + * On a PPP link we neither compress nor aarp. + */ + if(dev->type==ARPHRD_PPP) + { + skb->protocol = htons(ETH_P_PPPTALK); + if(skb->sk==NULL) + skb->priority = SOPRI_NORMAL; + else + skb->priority = skb->sk->priority; + skb->dev = dev; + dev_queue_xmit(skb); + return 1; + } /* * Non ELAP we cannot do. @@ -514,7 +535,7 @@ int aarp_send_ddp(struct device *dev,struct sk_buff *skb, struct at_addr *sa, vo * Return 1 and fill in the address */ - a->expires_at=jiffies+AARP_EXPIRY_TIME*10; + a->expires_at=jiffies+sysctl_aarp_expiry_time*10; ddp_dl->datalink_header(ddp_dl, skb, a->hwaddr); if(skb->sk==NULL) skb->priority = SOPRI_NORMAL; @@ -561,7 +582,7 @@ int aarp_send_ddp(struct device *dev,struct sk_buff *skb, struct at_addr *sa, vo */ skb_queue_tail(&a->packet_queue, skb); - a->expires_at=jiffies+AARP_RESOLVE_TIME; + a->expires_at=jiffies+sysctl_aarp_resolve_time; a->dev=dev; a->next=unresolved[hash]; a->target_addr= *sa; @@ -584,7 +605,7 @@ int aarp_send_ddp(struct device *dev,struct sk_buff *skb, struct at_addr *sa, vo if(unresolved_count==1) { del_timer(&aarp_timer); - aarp_timer.expires=jiffies+AARP_TICK_TIME; + aarp_timer.expires=jiffies+sysctl_aarp_tick_time; add_timer(&aarp_timer); } @@ -623,7 +644,7 @@ static void aarp_resolved(struct aarp_entry **list, struct aarp_entry *a, int ha while((skb=skb_dequeue(&a->packet_queue))!=NULL) { - a->expires_at=jiffies+AARP_EXPIRY_TIME*10; + a->expires_at=jiffies+sysctl_aarp_expiry_time*10; ddp_dl->datalink_header(ddp_dl,skb,a->hwaddr); if(skb->sk==NULL) skb->priority = SOPRI_NORMAL; @@ -751,7 +772,7 @@ static int aarp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type if(unresolved_count==0) { del_timer(&aarp_timer); - aarp_timer.expires=jiffies+AARP_EXPIRY_TIME; + aarp_timer.expires=jiffies+sysctl_aarp_expiry_time; add_timer(&aarp_timer); } break; @@ -804,7 +825,7 @@ __initfunc(void aarp_proto_init(void)) init_timer(&aarp_timer); aarp_timer.function=aarp_expire_timeout; aarp_timer.data=0; - aarp_timer.expires=jiffies+AARP_EXPIRY_TIME; + aarp_timer.expires=jiffies+sysctl_aarp_expiry_time; add_timer(&aarp_timer); register_netdevice_notifier(&aarp_notifier); } diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 4dbcc0a9c..de05f7047 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c @@ -79,6 +79,11 @@ #define DPRINT(x) #endif +#ifdef CONFIG_SYSCTL +extern inline void atalk_register_sysctl(void); +extern inline void atalk_unregister_sysctl(void); +#endif + struct datalink_proto *ddp_dl, *aarp_dl; static struct proto_ops atalk_dgram_ops; @@ -262,7 +267,6 @@ static void atif_drop_device(struct device *dev) else iface = &tmp->next; } - MOD_DEC_USE_COUNT; } static struct atalk_iface *atif_add_device(struct device *dev, struct at_addr *sa) @@ -281,7 +285,6 @@ static struct atalk_iface *atif_add_device(struct device *dev, struct at_addr *s iface->next=atalk_iface_list; atalk_iface_list=iface; restore_flags(flags); - MOD_INC_USE_COUNT; return iface; } @@ -399,9 +402,21 @@ struct at_addr *atalk_find_dev_addr(struct device *dev) static struct at_addr *atalk_find_primary(void) { struct atalk_iface *iface; + struct atalk_iface *fiface; + /* + * Return a point-to-point interface only if + * there is no non-ptp interface available. + */ + fiface=NULL; for(iface=atalk_iface_list;iface!=NULL;iface=iface->next) - if(!(iface->dev->flags&IFF_LOOPBACK)) + { + if(!fiface && !(iface->dev->flags&IFF_LOOPBACK)) + fiface=iface; + if(!(iface->dev->flags&(IFF_LOOPBACK|IFF_POINTOPOINT))) return &iface->address; + } + if (fiface) + return &fiface->address; if ( atalk_iface_list != NULL ) return &atalk_iface_list->address; else @@ -779,6 +794,16 @@ int atif_ioctl(int cmd, void *arg) ((struct sockaddr_at *)(&atreq.ifr_addr))->sat_addr.s_net=atif->address.s_net; ((struct sockaddr_at *)(&atreq.ifr_addr))->sat_addr.s_node=ATADDR_BCAST; break; + case SIOCATALKDIFADDR: + if(!suser()) + return -EPERM; + if(sa->sat_family!=AF_APPLETALK) + return -EINVAL; + if(atif==NULL) + return -EADDRNOTAVAIL; + atrtr_device_down(atif->dev); + atif_drop_device(atif->dev); + break; } err = copy_to_user(arg,&atreq,sizeof(atreq)); @@ -951,7 +976,8 @@ static int atalk_create(struct socket *sock, int protocol) MOD_INC_USE_COUNT; sock_init_data(sock,sk); - + + sk->destruct=NULL; /* Checksums on by default */ sk->mtu=DDP_MAXSZ; sk->zapped=1; @@ -1928,6 +1954,7 @@ static int atalk_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg) case SIOCGIFADDR: case SIOCSIFADDR: case SIOCGIFBRDADDR: + case SIOCATALKDIFADDR: return atif_ioctl(cmd,(void *)arg); /* * Physical layer ioctl calls @@ -2056,6 +2083,10 @@ __initfunc(void atalk_proto_init(struct net_proto *pro)) proc_net_register(&proc_atalk_iface); #endif +#ifdef CONFIG_SYSCTL + atalk_register_sysctl(); +#endif + #ifdef CONFIG_IPDDP register_netdev(&dev_ipddp); #endif /* CONFIG_IPDDP */ @@ -2098,6 +2129,7 @@ extern inline void free_interface_list(void) while (list != NULL) { tmp = list->next; + list->dev->atalk_ptr = NULL; kfree_s(list, sizeof(struct atalk_iface)); list = tmp; } @@ -2112,6 +2144,10 @@ void cleanup_module(void) aarp_cleanup_module(); +#ifdef CONFIG_SYSCTL + atalk_unregister_sysctl(); +#endif + #ifdef CONFIG_PROC_FS proc_net_unregister(PROC_NET_ATALK); proc_net_unregister(PROC_NET_AT_ROUTE); diff --git a/net/appletalk/sysctl_net_atalk.c b/net/appletalk/sysctl_net_atalk.c index 307278992..6d5159ddc 100644 --- a/net/appletalk/sysctl_net_atalk.c +++ b/net/appletalk/sysctl_net_atalk.c @@ -3,11 +3,55 @@ * * Begun April 1, 1996, Mike Shaver. * Added /proc/sys/net/atalk directory entry (empty =) ). [MS] + * Dynamic registration, added aarp entries. (5/30/97 Chris Horn) */ #include <linux/mm.h> #include <linux/sysctl.h> -ctl_table atalk_table[] = { +extern int sysctl_aarp_expiry_time; +extern int sysctl_aarp_tick_time; +extern int sysctl_aarp_retransmit_limit; +extern int sysctl_aarp_resolve_time; + + +static ctl_table atalk_table[] = { + {NET_ATALK_AARP_EXPIRY_TIME, "aarp-expiry-time", + &sysctl_aarp_expiry_time, sizeof(int), 0644, NULL, &proc_dointvec_jiffies}, + {NET_ATALK_AARP_TICK_TIME, "aarp-tick-time", + &sysctl_aarp_tick_time, sizeof(int), 0644, NULL, &proc_dointvec_jiffies}, + {NET_ATALK_AARP_RETRANSMIT_LIMIT, "aarp-retransmit-limit", + &sysctl_aarp_retransmit_limit, sizeof(int), 0644, NULL, &proc_dointvec}, + {NET_ATALK_AARP_RESOLVE_TIME, "aarp-resolve-time", + &sysctl_aarp_resolve_time, sizeof(int), 0644, NULL, &proc_dointvec_jiffies}, + {0} +}; + +static ctl_table atalk_dir_table[] = { + {NET_ATALK, "appletalk", NULL, 0, 0555, atalk_table}, {0} }; + +static ctl_table atalk_root_table[] = { + {CTL_NET, "net", NULL, 0, 0555, atalk_dir_table}, + {0} +}; + +static struct ctl_table_header *atalk_table_header; + +inline void atalk_register_sysctl(void) +{ + atalk_table_header = register_sysctl_table(atalk_root_table, 1); +} + +inline void atalk_unregister_sysctl(void) +{ + unregister_sysctl_table(atalk_table_header); +} + + + + + + + diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index fe5d4dca6..37b679600 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -148,6 +148,11 @@ void ax25_free_cb(ax25_cb *ax25) MOD_DEC_USE_COUNT; } +static void ax25_free_sock(struct sock *sk) +{ + ax25_free_cb(sk->protinfo.ax25); +} + /* * Socket removal during an interrupt is now safe. */ @@ -428,7 +433,6 @@ void ax25_destroy_socket(ax25_cb *ax25) /* Not static as it's used by the timer add_timer(&ax25->timer); } else { sk_free(ax25->sk); - ax25_free_cb(ax25); } } else { ax25_free_cb(ax25); @@ -858,7 +862,8 @@ int ax25_create(struct socket *sock, int protocol) } sock_init_data(sock, sk); - + + sk->destruct = ax25_free_sock; sock->ops = &ax25_proto_ops; sk->protocol = protocol; sk->mtu = AX25_MTU; /* 256 */ @@ -894,7 +899,8 @@ struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev) } sock_init_data(NULL, sk); - + + sk->destruct = ax25_free_sock; sk->type = osk->type; sk->socket = osk->socket; sk->priority = osk->priority; @@ -926,7 +932,6 @@ struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev) if (osk->protinfo.ax25->digipeat != NULL) { if ((ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) { sk_free(sk); - ax25_free_cb(ax25); return NULL; } @@ -1182,8 +1187,8 @@ static int ax25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le #ifdef CONFIG_AX25_DAMA_SLAVE case AX25_PROTO_DAMA_SLAVE: - ax25->modulus = AX25_MODULUS; - ax25->window = ax25->ax25_dev->values[AX25_VALUES_WINDOW]; + sk->protinfo.ax25->modulus = AX25_MODULUS; + sk->protinfo.ax25->window = sk->protinfo.ax25->ax25_dev->values[AX25_VALUES_WINDOW]; if (sk->protinfo.ax25->ax25_dev->dama.slave) ax25_ds_establish_data_link(sk->protinfo.ax25); else diff --git a/net/core/dev.c b/net/core/dev.c index 07a5c1706..2b593cbb1 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1485,7 +1485,6 @@ int dev_ioctl(unsigned int cmd, void *arg) case SIOCGIFMTU: case SIOCGIFMEM: case SIOCGIFHWADDR: - case SIOCSIFHWADDR: case SIOCGIFSLAVE: case SIOCGIFMAP: case SIOGIFINDEX: @@ -1499,6 +1498,7 @@ int dev_ioctl(unsigned int cmd, void *arg) case SIOCSIFMETRIC: case SIOCSIFMTU: case SIOCSIFMEM: + case SIOCSIFHWADDR: case SIOCSIFMAP: case SIOCSIFSLAVE: case SIOCADDMULTI: diff --git a/net/core/sock.c b/net/core/sock.c index f28ea828e..37f73485c 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -71,6 +71,8 @@ * Alan Cox : Generic socket allocation to make hooks * easier (suggested by Craig Metz). * Michael Pall : SO_ERROR returns positive errno again + * Steve Whitehouse: Added default destructor to free + * protocol private data. * * To Fix: * @@ -124,6 +126,8 @@ __u32 sysctl_rmem_max = SK_RMEM_MAX; __u32 sysctl_wmem_default = SK_WMEM_MAX; __u32 sysctl_rmem_default = SK_RMEM_MAX; +int sysctl_core_destroy_delay = SOCK_DESTROY_TIME; + /* * This is meant for all protocols to use and covers goings on * at the socket level. Everything here is generic. @@ -465,6 +469,9 @@ struct sock *sk_alloc(int priority) void sk_free(struct sock *sk) { + if (sk->destruct) + sk->destruct(sk); + kmem_cache_free(sk_cachep, sk); } @@ -787,7 +794,7 @@ void sklist_destroy_socket(struct sock **list,struct sock *sk) * Someone is using our buffers still.. defer */ init_timer(&sk->timer); - sk->timer.expires=jiffies+10*HZ; + sk->timer.expires=jiffies+sysctl_core_destroy_delay; sk->timer.function=sklist_destroy_timer; sk->timer.data = (unsigned long)sk; add_timer(&sk->timer); @@ -874,6 +881,12 @@ void sock_def_callback3(struct sock *sk) } } +void sock_def_destruct(struct sock *sk) +{ + if (sk->protinfo.destruct_hook) + kfree(sk->protinfo.destruct_hook); +} + void sock_init_data(struct socket *sock, struct sock *sk) { skb_queue_head_init(&sk->receive_queue); @@ -901,6 +914,7 @@ void sock_init_data(struct socket *sock, struct sock *sk) sk->data_ready = sock_def_callback2; sk->write_space = sock_def_callback3; sk->error_report = sock_def_callback1; + sk->destruct = sock_def_destruct; sk->peercred.pid = 0; sk->peercred.uid = -1; diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c index fd770becd..c912e8b2e 100644 --- a/net/core/sysctl_net_core.c +++ b/net/core/sysctl_net_core.c @@ -13,6 +13,8 @@ extern __u32 sysctl_rmem_max; extern __u32 sysctl_wmem_default; extern __u32 sysctl_rmem_default; +extern int sysctl_core_destroy_delay; + ctl_table core_table[] = { {NET_CORE_WMEM_MAX, "wmem_max", &sysctl_wmem_max, sizeof(int), 0644, NULL, @@ -26,5 +28,8 @@ ctl_table core_table[] = { {NET_CORE_RMEM_DEFAULT, "rmem_default", &sysctl_rmem_default, sizeof(int), 0644, NULL, &proc_dointvec}, + {NET_CORE_DESTROY_DELAY, "destroy_delay", + &sysctl_core_destroy_delay, sizeof(int), 0644, NULL, + &proc_dointvec_jiffies}, { 0 } }; diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index a3a126529..eb47c3dfe 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -114,6 +114,7 @@ #define min(a,b) ((a)<(b)?(a):(b)) +extern int sysctl_core_destroy_delay; extern struct proto packet_prot; extern int raw_get_info(char *, char **, off_t, int, int); extern int snmp_get_info(char *, char **, off_t, int, int); @@ -190,7 +191,7 @@ static __inline__ void kill_sk_later(struct sock *sk) sk->destroy = 1; sk->ack_backlog = 0; release_sock(sk); - net_reset_timer(sk, TIME_DESTROY, SOCK_DESTROY_TIME); + net_reset_timer(sk, TIME_DESTROY, sysctl_core_destroy_delay); } void destroy_sock(struct sock *sk) @@ -366,7 +367,8 @@ static int inet_create(struct socket *sock, int protocol) } sock_init_data(sock,sk); - + sk->destruct = NULL; + sk->zapped=0; #ifdef CONFIG_TCP_NAGLE_OFF sk->nonagle = 1; diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index da0685340..c12417c52 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -81,7 +81,7 @@ static unsigned long ip_get_mask(unsigned long addr) * This checks bitmasks for the ioctl calls for devices. */ -static inline int bad_mask(unsigned long mask, unsigned long addr) +static inline int bad_mask(__u32 mask, __u32 addr) { if (addr & (mask = ~mask)) return 1; diff --git a/net/ipv4/fib.c b/net/ipv4/fib.c index 7daab2e61..6dc90b0ab 100644 --- a/net/ipv4/fib.c +++ b/net/ipv4/fib.c @@ -1896,8 +1896,8 @@ static void ip_rt_add_broadcasts(struct device *dev, u32 brd, u32 mask) void ip_rt_change_broadcast(struct device *dev, u32 new_brd) { fib_lock(); - printk(KERN_DEBUG "%s changes brd %08lX -> %08X\n", - dev->name, dev->pa_brdaddr, new_brd); + printk(KERN_DEBUG "%s changes brd %08X -> %08X\n", + dev->name, (u32)dev->pa_brdaddr, new_brd); if (!ZERONET(dev->pa_addr) && dev->flags&IFF_BROADCAST) { fib_magic(RTMSG_DELROUTE, RTF_IFBRD, dev->pa_brdaddr, ~0, dev); rtmsg_dev(RTMSG_DELDEVICE, dev, NULL); @@ -1911,8 +1911,8 @@ void ip_rt_change_dstaddr(struct device *dev, u32 dstaddr) { fib_lock(); if (!ZERONET(dev->pa_addr) && (dev->flags&IFF_POINTOPOINT) && dev->type != ARPHRD_TUNNEL) { - printk(KERN_DEBUG "%s changes dst %08lX -> %08X\n", - dev->name, dev->pa_dstaddr, dstaddr); + printk(KERN_DEBUG "%s changes dst %08X -> %08X\n", + dev->name, (u32)dev->pa_dstaddr, dstaddr); fib_magic(RTMSG_DELROUTE, RTF_IFPREFIX, dev->pa_dstaddr, ~0, dev); rtmsg_dev(RTMSG_DELDEVICE, dev, NULL); rtmsg_dev(RTMSG_NEWDEVICE, dev, NULL); @@ -1927,8 +1927,8 @@ void ip_rt_change_netmask(struct device *dev, u32 mask) u32 net; fib_lock(); - printk(KERN_DEBUG "%s changes netmask %08lX -> %08X\n", - dev->name, dev->pa_mask, mask); + printk(KERN_DEBUG "%s changes netmask %08X -> %08X\n", + dev->name, (u32)dev->pa_mask, mask); if (ZERONET(dev->pa_addr)) { fib_unlock(); return; @@ -1961,9 +1961,9 @@ int ip_rt_event(int event, struct device *dev) return NOTIFY_DONE; } if (event == NETDEV_CHANGE) { - printk(KERN_DEBUG "%s(%s) changes state fl=%08x pa=%08lX/%08lX brd=%08lX dst=%08lX\n", - dev->name, current->comm, dev->flags, dev->pa_addr, dev->pa_mask, - dev->pa_brdaddr, dev->pa_dstaddr); + printk(KERN_DEBUG "%s(%s) changes state fl=%08x pa=%08X/%08X brd=%08X dst=%08X\n", + dev->name, current->comm, dev->flags, (u32)dev->pa_addr, (u32)dev->pa_mask, + (u32)dev->pa_brdaddr, (u32)dev->pa_dstaddr); if (!(dev->flags&IFF_BROADCAST)) fib_magic(RTMSG_DELROUTE, RTF_IFBRD, dev->pa_brdaddr, ~0, dev); if (!(dev->flags&IFF_POINTOPOINT)) @@ -1985,9 +1985,9 @@ int ip_rt_event(int event, struct device *dev) } if (event == NETDEV_UP) - printk(KERN_DEBUG "%s UP fl=%08x pa=%08lX/%08lX brd=%08lX dst=%08lX\n", - dev->name, dev->flags, dev->pa_addr, - dev->pa_mask, dev->pa_brdaddr, dev->pa_dstaddr); + printk(KERN_DEBUG "%s UP fl=%08x pa=%08X/%08X brd=%08X dst=%08X\n", + dev->name, dev->flags, (u32)dev->pa_addr, + (u32)dev->pa_mask, (u32)dev->pa_brdaddr, (u32)dev->pa_dstaddr); rtmsg_dev(RTMSG_NEWDEVICE, dev, NULL); diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index 2aaef74de..fbc5403fc 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c @@ -88,6 +88,9 @@ #include <linux/igmp.h> #include <net/checksum.h> +int sysctl_igmp_max_host_report_delay = IGMP_MAX_HOST_REPORT_DELAY; +int sysctl_igmp_timer_scale = IGMP_TIMER_SCALE; +int sysctl_igmp_age_threshold = IGMP_AGE_THRESHOLD; /* * If time expired, change the router type to IGMP_NEW_ROUTER. @@ -133,7 +136,7 @@ static struct ip_router_info *igmp_get_mrouter_info(struct device *dev) return NULL; i->dev = dev; i->type = IGMP_NEW_ROUTER; - i->time = IGMP_AGE_THRESHOLD; + i->time = sysctl_igmp_age_threshold; i->next = ip_router_info_head; ip_router_info_head = i; @@ -229,7 +232,7 @@ static void igmp_start_timer(struct ip_mc_list *im,unsigned char max_resp_time) int tv; if(im->tm_running) return; - tv=random()%(max_resp_time*HZ/IGMP_TIMER_SCALE); /* Pick a number any number 8) */ + tv=random()%(max_resp_time*HZ/sysctl_igmp_timer_scale); /* Pick a number any number 8) */ im->timer.expires=jiffies+tv; im->tm_running=1; add_timer(&im->timer); @@ -363,7 +366,7 @@ static void igmp_heard_query(struct device *dev, unsigned char max_resp_time, if (group && group != im->multiaddr) continue; if(im->tm_running) { - if(im->timer.expires>jiffies+max_resp_time*HZ/IGMP_TIMER_SCALE) { + if(im->timer.expires>jiffies+max_resp_time*HZ/sysctl_igmp_timer_scale) { igmp_stop_timer(im); igmp_start_timer(im,max_resp_time); } @@ -372,9 +375,9 @@ static void igmp_heard_query(struct device *dev, unsigned char max_resp_time, } } else { mrouter_type=IGMP_OLD_ROUTER; - max_resp_time=IGMP_MAX_HOST_REPORT_DELAY*IGMP_TIMER_SCALE; + max_resp_time=sysctl_igmp_max_host_report_delay*sysctl_igmp_timer_scale; - if(igmp_set_mrouter_info(dev,mrouter_type,IGMP_AGE_THRESHOLD)==NULL) + if(igmp_set_mrouter_info(dev,mrouter_type,sysctl_igmp_age_threshold)==NULL) return; /* diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 290f871a1..e4fe370fd 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c @@ -5,7 +5,7 @@ * * The IP fragmentation functionality. * - * Version: $Id: ip_fragment.c,v 1.22 1997/05/17 05:21:56 freitag Exp $ + * Version: $Id: ip_fragment.c,v 1.23 1997/05/31 12:36:35 freitag Exp $ * * Authors: Fred N. van Kempen <waltje@uWalt.NL.Mugnet.ORG> * Alan Cox <Alan.Cox@linux.org> @@ -41,6 +41,8 @@ int sysctl_ipfrag_high_thresh = 256*1024; int sysctl_ipfrag_low_thresh = 192*1024; +int sysctl_ipfrag_time = IP_FRAG_TIME; + /* Describe an IP fragment. */ struct ipfrag { int offset; /* offset of fragment in IP datagram */ @@ -251,7 +253,7 @@ static struct ipq *ip_create(struct sk_buff *skb, struct iphdr *iph) qp->dev = skb->dev; /* Start a timer for this entry. */ - qp->timer.expires = jiffies + IP_FRAG_TIME; /* about 30 seconds */ + qp->timer.expires = jiffies + sysctl_ipfrag_time; /* about 30 seconds */ qp->timer.data = (unsigned long) qp; /* pointer to queue */ qp->timer.function = ip_expire; /* expire function */ add_timer(&qp->timer); @@ -417,7 +419,7 @@ struct sk_buff *ip_defrag(struct sk_buff *skb) memcpy(qp->iph, iph, ihl+8); } del_timer(&qp->timer); - qp->timer.expires = jiffies + IP_FRAG_TIME; /* about 30 seconds */ + qp->timer.expires = jiffies + sysctl_ipfrag_time; /* about 30 seconds */ qp->timer.data = (unsigned long) qp; /* pointer to queue */ qp->timer.function = ip_expire; /* expire function */ add_timer(&qp->timer); diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 1a38c5275..20246148a 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -1031,7 +1031,7 @@ int ipmr_mfc_info(char *buffer, char **start, off_t offset, int length, int dumm } if(pos>offset+length) { - sti(); + end_bh_atomic(); goto done; } mfc=mfc->next; diff --git a/net/ipv4/packet.c b/net/ipv4/packet.c index b98b58f35..f69449e76 100644 --- a/net/ipv4/packet.c +++ b/net/ipv4/packet.c @@ -160,7 +160,7 @@ static int packet_sendmsg(struct sock *sk, struct msghdr *msg, int len) if(len>dev->mtu+dev->hard_header_len) return -EMSGSIZE; - skb = sock_wmalloc(sk, len, 0, GFP_KERNEL); + skb = sock_wmalloc(sk, len+dev->hard_header_len, 0, GFP_KERNEL); /* * If the write buffer is full, then tough. At this level the user gets to @@ -177,6 +177,11 @@ static int packet_sendmsg(struct sock *sk, struct msghdr *msg, int len) * Fill it in */ + /* FIXME: Save some space for broken drivers that write a + * hard header at transmission time by themselves. PPP is the + * notable one here. This should really be fixed at the driver level. + */ + skb_reserve(skb,dev->hard_header_len); err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len); skb->arp = 1; /* No ARP needs doing on this (complete) frame */ skb->protocol = proto; diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c index 18a8d2bf8..6d7ba591f 100644 --- a/net/ipv4/sysctl_net_ipv4.c +++ b/net/ipv4/sysctl_net_ipv4.c @@ -34,10 +34,17 @@ extern int sysctl_arp_timeout; extern int sysctl_arp_check_interval; extern int sysctl_arp_confirm_interval; extern int sysctl_arp_confirm_timeout; +extern int sysctl_arp_max_pings; /* From ip_fragment.c */ extern int sysctl_ipfrag_low_thresh; extern int sysctl_ipfrag_high_thresh; +extern int sysctl_ipfrag_time; + +/* From igmp.c */ +extern int sysctl_igmp_max_host_report_delay; +extern int sysctl_igmp_timer_scale; +extern int sysctl_igmp_age_threshold; extern int sysctl_tcp_cong_avoidance; extern int sysctl_tcp_hoe_retransmits; @@ -45,7 +52,16 @@ extern int sysctl_tcp_sack; extern int sysctl_tcp_tsack; extern int sysctl_tcp_timestamps; extern int sysctl_tcp_window_scaling; -extern int sysctl_syn_retries; +extern int sysctl_tcp_keepalive_time; +extern int sysctl_tcp_keepalive_probes; +extern int sysctl_tcp_max_ka_probes; +extern int sysctl_tcp_retries1; +extern int sysctl_tcp_retries2; +extern int sysctl_tcp_max_delay_acks; +extern int sysctl_tcp_fin_timeout; +extern int sysctl_tcp_syncookies; +extern int sysctl_tcp_always_syncookie; +extern int sysctl_tcp_syn_retries; extern int tcp_sysctl_congavoid(ctl_table *ctl, int write, struct file * filp, void *buffer, size_t *lenp); @@ -82,6 +98,8 @@ ctl_table ipv4_table[] = { &sysctl_arp_dead_res_time, sizeof(int), 0644, NULL, &proc_dointvec}, {NET_IPV4_ARP_MAX_TRIES, "arp_max_tries", &sysctl_arp_max_tries, sizeof(int), 0644, NULL, &proc_dointvec}, + {NET_IPV4_ARP_MAX_PINGS, "arp_max_pings", + &sysctl_arp_max_pings, sizeof(int), 0644, NULL, &proc_dointvec}, {NET_IPV4_ARP_TIMEOUT, "arp_timeout", &sysctl_arp_timeout, sizeof(int), 0644, NULL, &proc_dointvec}, {NET_IPV4_ARP_CHECK_INTERVAL, "arp_check_interval", @@ -149,12 +167,46 @@ ctl_table ipv4_table[] = { {NET_IPV4_RFC1620_REDIRECTS, "ip_rfc1620_redirects", &ipv4_config.rfc1620_redirects, sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_TCP_SYN_RETRIES, "tcp_syn_retries", - &sysctl_syn_retries, sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_IPFRAG_HIGH_THRESH, "ipfrag_high_thresh", - &sysctl_ipfrag_high_thresh, sizeof(int), 0644, NULL, &proc_dointvec}, - {NET_IPFRAG_LOW_THRESH, "ipfrag_low_thresh", - &sysctl_ipfrag_low_thresh, sizeof(int), 0644, NULL, &proc_dointvec}, + {NET_IPV4_TCP_SYN_RETRIES, "tcp_syn_retries", + &sysctl_tcp_syn_retries, sizeof(int), 0644, NULL, &proc_dointvec}, + {NET_IPV4_IPFRAG_HIGH_THRESH, "ipfrag_high_thresh", + &sysctl_ipfrag_high_thresh, sizeof(int), 0644, NULL, &proc_dointvec}, + {NET_IPV4_IPFRAG_LOW_THRESH, "ipfrag_low_thresh", + &sysctl_ipfrag_low_thresh, sizeof(int), 0644, NULL, &proc_dointvec}, + {NET_IPV4_IPFRAG_TIME, "ipfrag_time", + &sysctl_ipfrag_time, sizeof(int), 0644, NULL, &proc_dointvec_jiffies}, + {NET_IPV4_TCP_MAX_KA_PROBES, "tcp_max_ka_probes", + &sysctl_tcp_max_ka_probes, sizeof(int), 0644, NULL, &proc_dointvec}, + {NET_IPV4_TCP_KEEPALIVE_TIME, "tcp_keepalive_time", + &sysctl_tcp_keepalive_time, sizeof(int), 0644, NULL, + &proc_dointvec_jiffies}, + {NET_IPV4_TCP_KEEPALIVE_PROBES, "tcp_keepalive_probes", + &sysctl_tcp_keepalive_probes, sizeof(int), 0644, NULL, + &proc_dointvec}, + {NET_IPV4_TCP_RETRIES1, "tcp_retries1", + &sysctl_tcp_retries1, sizeof(int), 0644, NULL, &proc_dointvec}, + {NET_IPV4_TCP_RETRIES2, "tcp_retries2", + &sysctl_tcp_retries2, sizeof(int), 0644, NULL, &proc_dointvec}, + {NET_IPV4_TCP_MAX_DELAY_ACKS, "tcp_max_delay_acks", + &sysctl_tcp_max_delay_acks, sizeof(int), 0644, NULL, &proc_dointvec}, + {NET_IPV4_TCP_FIN_TIMEOUT, "tcp_fin_timeout", + &sysctl_tcp_fin_timeout, sizeof(int), 0644, NULL, + &proc_dointvec_jiffies}, + {NET_IPV4_IGMP_MAX_HOST_REPORT_DELAY, "igmp_max_host_report_delay", + &sysctl_igmp_max_host_report_delay, sizeof(int), 0644, NULL, + &proc_dointvec}, + {NET_IPV4_IGMP_TIMER_SCALE, "igmp_timer_scale", + &sysctl_igmp_timer_scale, sizeof(int), 0644, NULL, &proc_dointvec}, +#if 0 + /* This one shouldn't be exposed to the user (too implementation + specific): */ + {NET_IPV4_IGMP_AGE_THRESHOLD, "igmp_age_threshold", + &sysctl_igmp_age_threshold, sizeof(int), 0644, NULL, &proc_dointvec}, +#endif + {NET_TCP_SYNCOOKIES, "tcp_syncookies", + &sysctl_tcp_syncookies, sizeof(int), 0644, NULL, &proc_dointvec}, + {NET_TCP_ALWAYS_SYNCOOKIE, "tcp_always_syncookie", + &sysctl_tcp_always_syncookie, sizeof(int), 0644, NULL, &proc_dointvec}, {0} }; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 000813b94..b43a972cc 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp.c,v 1.65 1997/05/06 09:31:43 davem Exp $ + * Version: $Id: tcp.c,v 1.66 1997/05/31 12:36:39 freitag Exp $ * * Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> @@ -431,6 +431,8 @@ #include <asm/uaccess.h> +int sysctl_tcp_fin_timeout = TCP_FIN_TIMEOUT; + unsigned long seq_offset; struct tcp_mib tcp_statistics; @@ -1385,7 +1387,7 @@ static int tcp_close_state(struct sock *sk, int dead) if(timer_active) add_timer(&sk->timer); else - tcp_reset_msl_timer(sk, TIME_CLOSE, TCP_FIN_TIMEOUT); + tcp_reset_msl_timer(sk, TIME_CLOSE, sysctl_tcp_fin_timeout); } return send_fin; @@ -1499,7 +1501,7 @@ void tcp_close(struct sock *sk, unsigned long timeout) if(timer_active) add_timer(&sk->timer); else - tcp_reset_msl_timer(sk, TIME_CLOSE, TCP_FIN_TIMEOUT); + tcp_reset_msl_timer(sk, TIME_CLOSE, sysctl_tcp_fin_timeout); } sk->dead = 1; diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 3ab1dee42..604bd1c84 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c @@ -5,7 +5,7 @@ * * Implementation of the Transmission Control Protocol(TCP). * - * Version: $Id: tcp_input.c,v 1.51 1997/04/27 19:24:40 schenk Exp $ + * Version: $Id: tcp_input.c,v 1.52 1997/05/31 12:36:42 freitag Exp $ * * Authors: Ross Biro, <bir7@leland.Stanford.Edu> * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> @@ -56,13 +56,15 @@ static void tcp_cong_avoid_vanj(struct sock *sk, u32 seq, u32 ack, static void tcp_cong_avoid_vegas(struct sock *sk, u32 seq, u32 ack, u32 seq_rtt); -int sysctl_tcp_cong_avoidance = 0; -int sysctl_tcp_hoe_retransmits = 0; -int sysctl_tcp_sack = 0; -int sysctl_tcp_tsack = 0; -int sysctl_tcp_timestamps = 0; -int sysctl_tcp_window_scaling = 0; - +int sysctl_tcp_cong_avoidance; +int sysctl_tcp_hoe_retransmits; +int sysctl_tcp_sack; +int sysctl_tcp_tsack; +int sysctl_tcp_timestamps; +int sysctl_tcp_window_scaling; +int sysctl_tcp_syncookies; +int sysctl_tcp_always_syncookie; +int sysctl_tcp_max_delay_acks = MAX_DELAY_ACK; static tcp_sys_cong_ctl_t tcp_sys_cong_ctl_f = &tcp_cong_avoid_vanj; @@ -1080,7 +1082,7 @@ queue_and_out: /* A retransmit, 2nd most common case. Force an imediate ack. */ SOCK_DEBUG(sk, "retransmit received: seq %X\n", skb->seq); - tp->delayed_acks = MAX_DELAY_ACK; + tp->delayed_acks = sysctl_tcp_max_delay_acks; kfree_skb(skb, FREE_READ); return; } @@ -1094,7 +1096,7 @@ queue_and_out: } /* Ok. This is an out_of_order segment, force an ack. */ - tp->delayed_acks = MAX_DELAY_ACK; + tp->delayed_acks = sysctl_tcp_max_delay_acks; /* Disable header predition. */ tp->pred_flags = 0; @@ -1218,7 +1220,7 @@ static __inline__ void tcp_ack_snd_check(struct sock *sk) return; } - if (tp->delayed_acks >= MAX_DELAY_ACK || tcp_raise_window(sk)) + if (tp->delayed_acks >= sysctl_tcp_max_delay_acks || tcp_raise_window(sk)) tcp_send_ack(sk); else tcp_send_delayed_ack(sk, HZ/2); diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index ce6c60feb..b4810e784 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c @@ -22,7 +22,11 @@ #include <net/tcp.h> -int sysctl_syn_retries = TCP_SYN_RETRIES; +int sysctl_tcp_syn_retries = TCP_SYN_RETRIES; +int sysctl_tcp_keepalive_time = TCP_KEEPALIVE_TIME; +int sysctl_tcp_keepalive_probes = TCP_KEEPALIVE_PROBES; +int sysctl_tcp_retries1 = TCP_RETR1; +int sysctl_tcp_retries2 = TCP_RETR2; static void tcp_sltimer_handler(unsigned long); static void tcp_syn_recv_timer(unsigned long); @@ -172,7 +176,7 @@ static int tcp_write_timeout(struct sock *sk) /* Eric, what the heck is this doing?!?! */ tp->retransmits && !(tp->retransmits & 7)) || - (sk->state != TCP_ESTABLISHED && tp->retransmits > TCP_RETR1)) { + (sk->state != TCP_ESTABLISHED && tp->retransmits > sysctl_tcp_retries1)) { /* Attempt to recover if arp has changed (unlikely!) or * a route has shifted (not supported prior to 1.3). */ @@ -180,7 +184,7 @@ static int tcp_write_timeout(struct sock *sk) } /* Have we tried to SYN too many times (repent repent 8)) */ - if(tp->retransmits > sysctl_syn_retries && sk->state==TCP_SYN_SENT) { + if(tp->retransmits > sysctl_tcp_syn_retries && sk->state==TCP_SYN_SENT) { if(sk->err_soft) sk->err=sk->err_soft; else @@ -198,7 +202,7 @@ static int tcp_write_timeout(struct sock *sk) } /* Has it gone just too far? */ - if (tp->retransmits > TCP_RETR2) { + if (tp->retransmits > sysctl_tcp_retries2) { if(sk->err_soft) sk->err = sk->err_soft; else @@ -251,7 +255,7 @@ void tcp_probe_timer(unsigned long data) { * FIXME: We ought not to do it, Solaris 2.5 actually has fixing * this behaviour in Solaris down as a bug fix. [AC] */ - if (tp->probes_out > TCP_RETR2) { + if (tp->probes_out > sysctl_tcp_retries2) { if(sk->err_soft) sk->err = sk->err_soft; else @@ -281,8 +285,8 @@ static __inline__ int tcp_keepopen_proc(struct sock *sk) struct tcp_opt *tp = &sk->tp_pinfo.af_tcp; __u32 elapsed = jiffies - tp->rcv_tstamp; - if (elapsed >= TCP_KEEPALIVE_TIME) { - if (tp->probes_out > TCP_KEEPALIVE_PROBES) { + if (elapsed >= sysctl_tcp_keepalive_time) { + if (tp->probes_out > sysctl_tcp_keepalive_probes) { if(sk->err_soft) sk->err = sk->err_soft; else @@ -316,6 +320,8 @@ static __inline__ int tcp_keepopen_proc(struct sock *sk) */ #define MAX_KA_PROBES 5 +int sysctl_tcp_max_ka_probes = MAX_KA_PROBES; + /* Keepopen's are only valid for "established" TCP's, nicely our listener * hash gets rid of most of the useless testing, so we run through a couple * of the established hash chains each clock tick. -DaveM @@ -341,7 +347,7 @@ static void tcp_keepalive(unsigned long data) while(sk) { if(sk->keepopen) { count += tcp_keepopen_proc(sk); - if(count == MAX_KA_PROBES) + if(count == sysctl_tcp_max_ka_probes) goto out; } sk = sk->next; @@ -455,7 +461,7 @@ static void tcp_syn_recv_timer(unsigned long data) break; tcp_synq_unlink(tp, conn); - if (conn->retrans >= TCP_RETR1) { + if (conn->retrans >= sysctl_tcp_retries1) { #ifdef TCP_DEBUG printk(KERN_DEBUG "syn_recv: " "too many retransmits\n"); diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 1de20e358..3d23b6e86 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -7,7 +7,7 @@ * * Adapted from linux/net/ipv4/af_inet.c * - * $Id: af_inet6.c,v 1.18 1997/05/07 09:40:12 davem Exp $ + * $Id: af_inet6.c,v 1.19 1997/06/02 14:40:40 alan Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -105,6 +105,7 @@ static int inet6_create(struct socket *sock, int protocol) sock_init_data(sock, sk); + sk->destruct = NULL; sk->zapped = 0; sk->family = AF_INET6; sk->protocol = protocol; diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 3c61f7b50..4bf0207d9 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -5,7 +5,7 @@ * Authors: * Pedro Roque <roque@di.fc.ul.pt> * - * $Id: tcp_ipv6.c,v 1.31 1997/04/29 21:51:23 davem Exp $ + * $Id: tcp_ipv6.c,v 1.32 1997/06/04 08:28:58 davem Exp $ * * Based on: * linux/net/ipv4/tcp.c @@ -643,7 +643,6 @@ static void tcp_v6_send_synack(struct sock *sk, struct open_request *req) skb->end_seq = skb->seq + 1; th->seq = ntohl(skb->seq); th->ack_seq = htonl(req->rcv_isn + 1); - th->doff = sizeof(*th)/4 + 1; /* Don't offer more than they did. * This way we don't have to memorize who said what. @@ -669,8 +668,9 @@ static void tcp_v6_send_synack(struct sock *sk, struct open_request *req) th->window = htons(req->rcv_wnd); tmp = tcp_syn_build_options(skb, req->mss, req->sack_ok, req->tstamp_ok, - req->snd_wscale,req->rcv_wscale); - th->doff = sizeof(*th)/4 + (tmp>>2); + req->wscale_ok,req->rcv_wscale); + skb->csum = 0; + th->doff = (sizeof(*th) + tmp)>>2; th->check = tcp_v6_check(th, sizeof(*th) + tmp, &req->af.v6_req.loc_addr, &req->af.v6_req.rmt_addr, csum_partial((char *)th, sizeof(*th)+tmp, skb->csum)); diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index cfb47bb42..de3588e41 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c @@ -751,7 +751,7 @@ static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb) } #ifdef CONFIG_IPX_PPROP_ROUTING - if( ipx->ipx_type == IPX_TYPE_PPROP && ipx->ipx_tctrl < 8 ) + if( ipx->ipx_type == IPX_TYPE_PPROP && ipx->ipx_tctrl < 8 && skb->pkt_type == PACKET_HOST ) { int i; ipx_interface *ifcs; @@ -759,35 +759,10 @@ static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb) long *l; char *c; - if(skb->pkt_type!=PACKET_HOST) - { - kfree_skb(skb, FREE_READ); - return 0; - } - -#ifdef DEBUG_IPX_PPROP_ROUTING - printk(KERN_INFO "IPX: PPROP packet received\n" - " Src: %8x:%02x:%02x:%02x:%02x:%02x:%02x:%d/%d\n", - htonl(ipx->ipx_source.net), - ipx->ipx_source.node[0], ipx->ipx_source.node[1], - ipx->ipx_source.node[2], ipx->ipx_source.node[3], - ipx->ipx_source.node[4], ipx->ipx_source.node[5], - htons(ipx->ipx_source.sock), - htons(ipx->ipx_dest.sock) - ); -#endif - c = (char *) skb->data; c += sizeof( struct ipxhdr ); - l = (long *) c; -#ifdef DEBUG_IPX_PPROP_ROUTING - printk( "IPX: Routing PPROP from net num %08x\n", (unsigned int) htonl(intrfc->if_netnum) ); - for( i = 0 ; i < ipx->ipx_tctrl ; i++ ) - printk( "IPX: Routing PPROP seen net num %08x\n", (unsigned int) htonl(*l++) ); - l = (long *) c; -#endif i = 0; /* * Dump packet if too many hops or already seen this net @@ -812,25 +787,13 @@ static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb) if( i - 1 == ipx->ipx_tctrl ) { ipx->ipx_dest.net = ifcs->if_netnum; -#ifdef DEBUG_IPX_PPROP_ROUTING - printk( "IPX: Forward PPROP onto net num %08x\n", (unsigned int) htonl(ifcs->if_netnum) ); -#endif - skb2 = skb_clone(skb, GFP_ATOMIC); - - /* - * See if we are allowed to firewall forward - */ - if (call_fw_firewall(PF_IPX, skb2->dev, ipx, NULL, &skb)!=FW_ACCEPT) + /* See if we are allowed to firewall forward */ + if (call_fw_firewall(PF_IPX, skb->dev, ipx, NULL, &skb)==FW_ACCEPT) { - kfree_skb(skb, FREE_READ); - return 0; - } + skb2 = skb_clone(skb, GFP_ATOMIC); ipxrtr_route_skb(skb2); } -#ifdef DEBUG_IPX_PPROP_ROUTING - else - printk( "IPX: Ignoring PPROP for net num %08x\n", (unsigned int) htonl(ifcs->if_netnum) ); -#endif + } } /* * Reset network number in packet @@ -1793,6 +1756,7 @@ static int ipx_create(struct socket *sock, int protocol) return(-ESOCKTNOSUPPORT); } sock_init_data(sock,sk); + sk->destruct=NULL; sk->mtu=IPX_MTU; sk->no_check = 1; /* Checksum off by default */ MOD_INC_USE_COUNT; diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index a6af49f15..22e1afbee 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c @@ -86,8 +86,6 @@ static struct proto_ops nr_proto_ops; static void nr_free_sock(struct sock *sk) { - kfree(sk->protinfo.nr); - sk_free(sk); MOD_DEC_USE_COUNT; diff --git a/net/netsyms.c b/net/netsyms.c index 9f13cabca..525f08689 100644 --- a/net/netsyms.c +++ b/net/netsyms.c @@ -326,6 +326,17 @@ EXPORT_SYMBOL(tty_register_ldisc); EXPORT_SYMBOL(kill_fasync); EXPORT_SYMBOL(ip_rcv); EXPORT_SYMBOL(arp_rcv); + +#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE) +#include<linux/if_ltalk.h> +EXPORT_SYMBOL(ltalk_setup); +#endif + +#ifdef CONFIG_DLCI_MODULE +extern int (*dlci_ioctl_hook)(unsigned int, void *); +EXPORT_SYMBOL(dlci_ioctl_hook); +#endif + #endif /* CONFIG_NET */ #ifdef CONFIG_NETLINK diff --git a/net/protocols.c b/net/protocols.c index 24e67cde1..a0bb0a6b8 100644 --- a/net/protocols.c +++ b/net/protocols.c @@ -47,6 +47,10 @@ extern void inet6_proto_init(struct net_proto *pro); #endif #endif +#if defined(CONFIG_DECNET) +#include <net/decnet_call.h> +#endif + #if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE) #define NEED_802 #include <net/atalkcall.h> @@ -107,9 +111,11 @@ struct net_proto protocols[] = { { "Rose", rose_proto_init }, /* Amateur Radio X.25 PLP */ #endif #endif - +#ifdef CONFIG_DECNET + { "DECnet", decnet_proto_init }, /* DECnet */ +#endif #ifdef CONFIG_INET - { "INET", inet_proto_init }, /* TCP/IP */ + { "INET", inet_proto_init }, /* TCP/IP */ #ifdef CONFIG_IPV6 { "INET6", inet6_proto_init}, /* IPv6 */ #endif diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index bd0ecd843..9896de9cb 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c @@ -136,8 +136,6 @@ int rosecmpm(rose_address *addr1, rose_address *addr2, unsigned short mask) static void rose_free_sock(struct sock *sk) { - kfree(sk->protinfo.rose); - sk_free(sk); MOD_DEC_USE_COUNT; diff --git a/net/socket.c b/net/socket.c index 482255255..2587083bc 100644 --- a/net/socket.c +++ b/net/socket.c @@ -212,7 +212,7 @@ static int get_fd(struct inode *inode) file->f_flags = O_RDWR; file->f_inode = inode; if (inode) - inode->i_count++; + atomic_inc(&inode->i_count); file->f_pos = 0; } return fd; @@ -797,6 +797,7 @@ asmlinkage int sys_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_ad int len; lock_kernel(); +restart: if ((sock = sockfd_lookup(fd, &err))!=NULL) { if (!(newsock = sock_alloc())) @@ -834,7 +835,13 @@ asmlinkage int sys_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_ad if (upeer_sockaddr) { - newsock->ops->getname(newsock, (struct sockaddr *)address, &len, 1); + /* Handle the race where the accept works and we + then getname after it has closed again */ + if(newsock->ops->getname(newsock, (struct sockaddr *)address, &len, 1)<0) + { + sys_close(err); + goto restart; + } move_addr_to_user(address,len, upeer_sockaddr, upeer_addrlen); } out: diff --git a/net/sysctl_net.c b/net/sysctl_net.c index eb23ea698..1acd01749 100644 --- a/net/sysctl_net.c +++ b/net/sysctl_net.c @@ -24,10 +24,6 @@ extern ctl_table ipv4_table[]; extern ctl_table ipx_table[]; #endif -#ifdef CONFIG_ATALK -extern ctl_table atalk_table[]; -#endif - extern ctl_table core_table[], unix_table[]; #ifdef CONFIG_NET @@ -59,9 +55,6 @@ ctl_table net_table[] = { #ifdef CONFIG_IPX {NET_IPX, "ipx", NULL, 0, 0555, ipx_table}, #endif -#ifdef CONFIG_ATALK - {NET_ATALK, "appletalk", NULL, 0, 0555, atalk_table}, -#endif #ifdef CONFIG_BRIDGE {NET_BRIDGE, "bridge", NULL, 0, 0555, bridge_table}, #endif diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 80d91481e..1dfdf1832 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -87,6 +87,8 @@ #define min(a,b) (((a)<(b))?(a):(b)) +int sysctl_unix_delete_delay = HZ; +int sysctl_unix_destroy_delay = 10*HZ; unix_socket *unix_socket_table[UNIX_HASH_SIZE+1]; @@ -138,6 +140,12 @@ extern __inline__ void unix_release_addr(struct unix_address *addr) } } +static void unix_destruct_addr(struct sock *sk) +{ + struct unix_address *addr = sk->protinfo.af_unix.addr; + + unix_release_addr(addr); +} /* * Check unix socket name: @@ -231,7 +239,6 @@ static void unix_destroy_timer(unsigned long data) unix_socket *sk=(unix_socket *)data; if(!unix_locked(sk) && atomic_read(&sk->wmem_alloc) == 0) { - unix_release_addr(sk->protinfo.af_unix.addr); sk_free(sk); return; } @@ -240,7 +247,7 @@ static void unix_destroy_timer(unsigned long data) * Retry; */ - sk->timer.expires=jiffies+10*HZ; /* No real hurry try it every 10 seconds or so */ + sk->timer.expires=jiffies+sysctl_unix_destroy_delay; /* No real hurry try it every 10 seconds or so */ add_timer(&sk->timer); } @@ -248,7 +255,7 @@ static void unix_destroy_timer(unsigned long data) static void unix_delayed_delete(unix_socket *sk) { sk->timer.data=(unsigned long)sk; - sk->timer.expires=jiffies+HZ; /* Normally 1 second after will clean up. After that we try every 10 */ + sk->timer.expires=jiffies+sysctl_unix_delete_delay; /* Normally 1 second after will clean up. After that we try every 10 */ sk->timer.function=unix_destroy_timer; add_timer(&sk->timer); } @@ -284,7 +291,6 @@ static void unix_destroy_socket(unix_socket *sk) if(!unix_unlock(sk) && atomic_read(&sk->wmem_alloc) == 0) { - unix_release_addr(sk->protinfo.af_unix.addr); sk_free(sk); } else @@ -346,7 +352,8 @@ static int unix_create(struct socket *sock, int protocol) return -ENOMEM; sock_init_data(sock,sk); - + + sk->destruct = unix_destruct_addr; sk->protinfo.af_unix.family=AF_UNIX; sk->protinfo.af_unix.inode=NULL; sk->sock_readers=1; /* Us */ @@ -792,7 +799,7 @@ static int unix_accept(struct socket *sock, struct socket *newsock, int flags) } if (sk->protinfo.af_unix.inode) { - sk->protinfo.af_unix.inode->i_count++; + atomic_inc(&sk->protinfo.af_unix.inode->i_count); newsk->protinfo.af_unix.inode=sk->protinfo.af_unix.inode; } diff --git a/net/unix/sysctl_net_unix.c b/net/unix/sysctl_net_unix.c index 5af2df443..18ce57684 100644 --- a/net/unix/sysctl_net_unix.c +++ b/net/unix/sysctl_net_unix.c @@ -14,6 +14,15 @@ #include <linux/mm.h> #include <linux/sysctl.h> +extern int sysctl_unix_destroy_delay; +extern int sysctl_unix_delete_delay; + ctl_table unix_table[] = { + {NET_UNIX_DESTROY_DELAY, "destroy_delay", + &sysctl_unix_destroy_delay, sizeof(int), 0644, NULL, + &proc_dointvec_jiffies}, + {NET_UNIX_DELETE_DELAY, "delete_delay", + &sysctl_unix_delete_delay, sizeof(int), 0644, NULL, + &proc_dointvec_jiffies}, {0} }; diff --git a/net/wanrouter/wanproc.c b/net/wanrouter/wanproc.c index de207d319..04a49d803 100644 --- a/net/wanrouter/wanproc.c +++ b/net/wanrouter/wanproc.c @@ -121,7 +121,6 @@ static struct inode_operations router_inode = NULL, /* mknod */ NULL, /* rename */ NULL, /* readlink */ - NULL, /* follow_link */ NULL, /* readpage */ NULL, /* writepage */ NULL, /* bmap */ @@ -160,7 +159,6 @@ static struct inode_operations wandev_inode = NULL, /* mknod */ NULL, /* rename */ NULL, /* readlink */ - NULL, /* follow_link */ NULL, /* readpage */ NULL, /* writepage */ NULL, /* bmap */ diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index c7cb33613..a77380648 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c @@ -341,7 +341,6 @@ void x25_destroy_socket(struct sock *sk) /* Not static as it's used by the timer sk->timer.data = (unsigned long)sk; add_timer(&sk->timer); } else { - kfree(sk->protinfo.x25); sk_free(sk); MOD_DEC_USE_COUNT; } |