Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@home.transmeta.com>2002-10-06 19:43:41 -0700
committerLinus Torvalds <torvalds@home.transmeta.com>2002-10-06 19:43:41 -0700
commit38b4e74829cc1b7a0870848f9c0900a843f6b9fc (patch)
tree78f5de39afdc8214e46835bee111eb6c44bbcb86
parente7f900845581666f38aedca7505b3f43aa69139e (diff)
parentd3150cd7f059bab3ae3bc809ec6327b9c0110b9d (diff)
Merge master.kernel.org:/home/davem/BK/net-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
-rw-r--r--include/linux/atalk.h14
-rw-r--r--include/linux/netdevice.h1
-rw-r--r--include/linux/sctp.h17
-rw-r--r--include/net/ipx.h21
-rw-r--r--include/net/llc_main.h3
-rw-r--r--include/net/llc_proc.h18
-rw-r--r--include/net/sctp/sctp.h8
-rw-r--r--include/net/sctp/sm.h11
-rw-r--r--include/net/sctp/structs.h14
-rw-r--r--include/net/x25.h11
-rw-r--r--net/8021q/vlan.c2
-rw-r--r--net/8021q/vlan_dev.c1
-rw-r--r--net/appletalk/Makefile2
-rw-r--r--net/appletalk/aarp.c22
-rw-r--r--net/appletalk/atalk_proc.c319
-rw-r--r--net/appletalk/ddp.c244
-rw-r--r--net/appletalk/sysctl_net_atalk.c7
-rw-r--r--net/bridge/br.c12
-rw-r--r--net/bridge/br_if.c15
-rw-r--r--net/bridge/br_stp.c17
-rw-r--r--net/core/dev.c22
-rw-r--r--net/ipv4/devinet.c18
-rw-r--r--net/ipv4/igmp.c2
-rw-r--r--net/ipv4/ip_gre.c34
-rw-r--r--net/ipv4/ip_output.c18
-rw-r--r--net/ipv4/ipconfig.c24
-rw-r--r--net/ipv4/ipip.c14
-rw-r--r--net/ipv4/ipmr.c4
-rw-r--r--net/ipv4/netfilter/ip_nat_core.c2
-rw-r--r--net/ipv4/netfilter/ip_nat_snmp_basic.c4
-rw-r--r--net/ipv4/netfilter/ip_nat_standalone.c4
-rw-r--r--net/ipv4/route.c8
-rw-r--r--net/ipv4/tcp_diag.c2
-rw-r--r--net/ipv4/tcp_input.c8
-rw-r--r--net/ipv4/tcp_ipv4.c4
-rw-r--r--net/ipv4/tcp_minisocks.c4
-rw-r--r--net/ipv6/addrconf.c36
-rw-r--r--net/ipv6/datagram.c4
-rw-r--r--net/ipv6/icmp.c38
-rw-r--r--net/ipv6/ip6_fib.c2
-rw-r--r--net/ipv6/ip6_output.c6
-rw-r--r--net/ipv6/netfilter/ip6_queue.c10
-rw-r--r--net/ipv6/netfilter/ip6t_LOG.c2
-rw-r--r--net/ipv6/reassembly.c4
-rw-r--r--net/ipv6/sit.c10
-rw-r--r--net/ipv6/udp.c4
-rw-r--r--net/ipx/ChangeLog101
-rw-r--r--net/ipx/Makefile2
-rw-r--r--net/ipx/af_ipx.c294
-rw-r--r--net/ipx/ipx_proc.c388
-rw-r--r--net/llc/Makefile2
-rw-r--r--net/llc/af_llc.c105
-rw-r--r--net/llc/llc_if.c2
-rw-r--r--net/llc/llc_mac.c3
-rw-r--r--net/llc/llc_main.c106
-rw-r--r--net/llc/llc_proc.c287
-rw-r--r--net/netsyms.c1
-rw-r--r--net/sched/sch_htb.c34
-rw-r--r--net/sctp/debug.c2
-rw-r--r--net/sctp/outqueue.c9
-rw-r--r--net/sctp/sm_make_chunk.c219
-rw-r--r--net/sctp/sm_sideeffect.c18
-rw-r--r--net/sctp/sm_statefuns.c418
-rw-r--r--net/sctp/socket.c155
-rw-r--r--net/wanrouter/wanproc.c26
-rw-r--r--net/x25/Makefile2
-rw-r--r--net/x25/af_x25.c146
-rw-r--r--net/x25/x25_proc.c252
-rw-r--r--net/x25/x25_route.c65
69 files changed, 2396 insertions, 1288 deletions
diff --git a/include/linux/atalk.h b/include/linux/atalk.h
index e26dc1db8a41..477169eb5b28 100644
--- a/include/linux/atalk.h
+++ b/include/linux/atalk.h
@@ -198,5 +198,19 @@ extern void aarp_cleanup_module(void);
#define at_sk(__sk) ((struct atalk_sock *)(__sk)->protinfo)
+extern struct sock *atalk_sockets;
+extern spinlock_t atalk_sockets_lock;
+
+extern struct atalk_route *atalk_routes;
+extern rwlock_t atalk_routes_lock;
+
+extern struct atalk_iface *atalk_interfaces;
+extern spinlock_t atalk_interfaces_lock;
+
+extern struct atalk_route atrtr_default;
+
+extern int atalk_proc_init(void);
+extern void atalk_proc_exit(void);
+
#endif /* __KERNEL__ */
#endif /* __LINUX_ATALK_H__ */
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 93b4d5f1e64d..f2c8daf526aa 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -587,7 +587,6 @@ static inline void dev_kfree_skb_any(struct sk_buff *skb)
dev_kfree_skb(skb);
}
-extern void net_call_rx_atomic(void (*fn)(void));
#define HAVE_NETIF_RX 1
extern int netif_rx(struct sk_buff *skb);
#define HAVE_NETIF_RECEIVE_SKB 1
diff --git a/include/linux/sctp.h b/include/linux/sctp.h
index 77502f62b660..1d54c9488601 100644
--- a/include/linux/sctp.h
+++ b/include/linux/sctp.h
@@ -155,15 +155,15 @@ typedef struct sctp_paramhdr {
typedef enum {
/* RFC 2960 Section 3.3.5 */
- SCTP_PARAM_HEATBEAT_INFO = __constant_htons(1),
+ SCTP_PARAM_HEARTBEAT_INFO = __constant_htons(1),
/* RFC 2960 Section 3.3.2.1 */
- SCTP_PARAM_IPV4_ADDRESS = __constant_htons(5),
- SCTP_PARAM_IPV6_ADDRESS = __constant_htons(6),
- SCTP_PARAM_STATE_COOKIE = __constant_htons(7),
- SCTP_PARAM_UNRECOGNIZED_PARAMETERS = __constant_htons(8),
- SCTP_PARAM_COOKIE_PRESERVATIVE = __constant_htons(9),
- SCTP_PARAM_HOST_NAME_ADDRESS = __constant_htons(11),
- SCTP_PARAM_SUPPORTED_ADDRESS_TYPES = __constant_htons(12),
+ SCTP_PARAM_IPV4_ADDRESS = __constant_htons(5),
+ SCTP_PARAM_IPV6_ADDRESS = __constant_htons(6),
+ SCTP_PARAM_STATE_COOKIE = __constant_htons(7),
+ SCTP_PARAM_UNRECOGNIZED_PARAMETERS = __constant_htons(8),
+ SCTP_PARAM_COOKIE_PRESERVATIVE = __constant_htons(9),
+ SCTP_PARAM_HOST_NAME_ADDRESS = __constant_htons(11),
+ SCTP_PARAM_SUPPORTED_ADDRESS_TYPES = __constant_htons(12),
SCTP_PARAM_ECN_CAPABLE = __constant_htons(0x8000),
/* Add-IP Extension. Section 3.2 */
@@ -190,6 +190,7 @@ typedef enum {
SCTP_PARAM_ACTION_SKIP_ERR = __constant_htons(0xc000),
} sctp_param_action_t;
+enum { SCTP_PARAM_ACTION_MASK = __constant_htons(0xc000), };
/* RFC 2960 Section 3.3.1 Payload Data (DATA) (0) */
diff --git a/include/net/ipx.h b/include/net/ipx.h
index 1f59db84c1a1..c3b1e4698438 100644
--- a/include/net/ipx.h
+++ b/include/net/ipx.h
@@ -1,3 +1,5 @@
+#ifndef _NET_INET_IPX_H_
+#define _NET_INET_IPX_H_
/*
* The following information is in its entirety obtained from:
*
@@ -7,9 +9,6 @@
* Which is available from ftp.novell.com
*/
-#ifndef _NET_INET_IPX_H_
-#define _NET_INET_IPX_H_
-
#include <linux/netdevice.h>
#include <net/datalink.h>
#include <linux/ipx.h>
@@ -25,8 +24,7 @@ struct ipx_address {
#define IPX_MAX_PPROP_HOPS 8
-struct ipxhdr
-{
+struct ipxhdr {
__u16 ipx_checksum __attribute__ ((packed));
#define IPX_NO_CHECKSUM 0xFFFF
__u16 ipx_pktsize __attribute__ ((packed));
@@ -110,4 +108,17 @@ struct ipx_opt {
#define IPX_MIN_EPHEMERAL_SOCKET 0x4000
#define IPX_MAX_EPHEMERAL_SOCKET 0x7fff
+extern struct ipx_route *ipx_routes;
+extern rwlock_t ipx_routes_lock;
+
+extern struct ipx_interface *ipx_interfaces;
+extern spinlock_t ipx_interfaces_lock;
+
+extern struct ipx_interface *ipx_primary_net;
+
+extern int ipx_proc_init(void);
+extern void ipx_proc_exit(void);
+
+extern const char *ipx_frame_name(unsigned short);
+extern const char *ipx_device_name(struct ipx_interface *intrfc);
#endif /* def _NET_INET_IPX_H_ */
diff --git a/include/net/llc_main.h b/include/net/llc_main.h
index 434e86044dec..0e0d39742a2e 100644
--- a/include/net/llc_main.h
+++ b/include/net/llc_main.h
@@ -57,10 +57,11 @@ extern struct llc_sap *llc_sap_alloc(void);
extern void llc_sap_save(struct llc_sap *sap);
extern void llc_free_sap(struct llc_sap *sap);
extern struct llc_sap *llc_sap_find(u8 lsap);
-extern struct llc_station *llc_station_get(void);
extern void llc_station_state_process(struct llc_station *station,
struct sk_buff *skb);
extern void llc_station_send_pdu(struct llc_station *station,
struct sk_buff *skb);
extern struct sk_buff *llc_alloc_frame(void);
+
+extern struct llc_station llc_main_station;
#endif /* LLC_MAIN_H */
diff --git a/include/net/llc_proc.h b/include/net/llc_proc.h
new file mode 100644
index 000000000000..c6e7306aa8c3
--- /dev/null
+++ b/include/net/llc_proc.h
@@ -0,0 +1,18 @@
+#ifndef LLC_PROC_H
+#define LLC_PROC_H
+/*
+ * Copyright (c) 1997 by Procom Technology, Inc.
+ * 2002 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+
+extern int llc_proc_init(void);
+extern void llc_proc_exit(void);
+
+#endif /* LLC_PROC_H */
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index d45cdd15f939..56de3338ade2 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -103,6 +103,14 @@
#define SCTP_PROTOSW_FLAG INET_PROTOSW_PERMANENT
#endif
+
+/* Certain internal static functions need to be exported when
+ * compiled into the test frame.
+ */
+#ifndef SCTP_STATIC
+#define SCTP_STATIC static
+#endif
+
/*
* Function declarations.
*/
diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h
index 5cb4858fac34..9459322a411b 100644
--- a/include/net/sctp/sm.h
+++ b/include/net/sctp/sm.h
@@ -215,7 +215,8 @@ sctp_chunk_t *sctp_make_init(const sctp_association_t *,
int priority);
sctp_chunk_t *sctp_make_init_ack(const sctp_association_t *,
const sctp_chunk_t *,
- const int priority);
+ const int priority,
+ const int unkparam_len);
sctp_chunk_t *sctp_make_cookie_echo(const sctp_association_t *,
const sctp_chunk_t *);
sctp_chunk_t *sctp_make_cookie_ack(const sctp_association_t *,
@@ -304,6 +305,14 @@ void sctp_generate_t3_rtx_event(unsigned long peer);
void sctp_generate_heartbeat_event(unsigned long peer);
sctp_sackhdr_t *sctp_sm_pull_sack(sctp_chunk_t *);
+sctp_packet_t *sctp_abort_pkt_new(const sctp_endpoint_t *ep,
+ const sctp_association_t *asoc,
+ sctp_chunk_t *chunk,
+ const void *payload,
+ size_t paylen);
+sctp_packet_t *sctp_ootb_pkt_new(const sctp_association_t *asoc,
+ const sctp_chunk_t *chunk);
+void sctp_ootb_pkt_free(sctp_packet_t *packet);
sctp_cookie_param_t *
sctp_pack_cookie(const sctp_endpoint_t *, const sctp_association_t *,
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index a405d9b517d8..d1748a73e6b0 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1044,6 +1044,20 @@ sctp_association_t *sctp_endpoint_lookup_assoc(const sctp_endpoint_t *ep,
sctp_endpoint_t *sctp_endpoint_is_match(sctp_endpoint_t *,
const sockaddr_storage_t *);
+int sctp_verify_init(const sctp_association_t *asoc,
+ sctp_cid_t cid,
+ sctp_init_chunk_t *peer_init,
+ sctp_chunk_t *chunk,
+ sctp_chunk_t **err_chunk);
+int sctp_verify_param(const sctp_association_t *asoc,
+ sctpParam_t param,
+ sctp_cid_t cid,
+ sctp_chunk_t *chunk,
+ sctp_chunk_t **err_chunk);
+int sctp_process_unk_param(const sctp_association_t *asoc,
+ sctpParam_t param,
+ sctp_chunk_t *chunk,
+ sctp_chunk_t **err_chunk);
void sctp_process_init(sctp_association_t *asoc, sctp_cid_t cid,
const sockaddr_storage_t *peer_addr,
sctp_init_chunk_t *peer_init, int priority);
diff --git a/include/net/x25.h b/include/net/x25.h
index a043f5e093c8..98fb713f3121 100644
--- a/include/net/x25.h
+++ b/include/net/x25.h
@@ -220,9 +220,8 @@ extern void x25_enquiry_response(struct sock *);
/* x25_route.c */
extern struct x25_route *x25_get_route(struct x25_address *addr);
extern struct net_device *x25_dev_get(char *);
-extern void x25_route_device_down(struct net_device *);
+extern void x25_route_device_down(struct net_device *dev);
extern int x25_route_ioctl(unsigned int, void *);
-extern int x25_routes_get_info(char *, char **, off_t, int);
extern void x25_route_free(void);
static __inline__ void x25_route_hold(struct x25_route *rt)
@@ -263,4 +262,12 @@ struct x25_skb_cb {
unsigned flags;
};
#define X25_SKB_CB(s) ((struct x25_skb_cb *) ((s)->cb))
+
+extern struct sock *x25_list;
+extern rwlock_t x25_list_lock;
+extern struct list_head x25_route_list;
+extern rwlock_t x25_route_list_lock;
+
+extern int x25_proc_init(void);
+extern void x25_proc_exit(void);
#endif
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 6f21903b0932..6bc8857d5393 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -207,7 +207,7 @@ static int unregister_vlan_dev(struct net_device *real_dev,
#endif
/* sanity check */
- if ((vlan_id >= VLAN_VID_MASK) || (vlan_id <= 0))
+ if (vlan_id >= VLAN_VID_MASK)
return -EINVAL;
spin_lock_bh(&vlan_group_lock);
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index eb2d1960a828..18d80e849412 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -573,6 +573,7 @@ int vlan_dev_set_egress_priority(char *dev_name, __u32 skb_prio, short vlan_prio
dev_put(dev);
return 0;
}
+ mp = mp->next;
}
/* Create a new mapping then. */
diff --git a/net/appletalk/Makefile b/net/appletalk/Makefile
index 14c4e7c55e0a..0f8309f9d5a6 100644
--- a/net/appletalk/Makefile
+++ b/net/appletalk/Makefile
@@ -6,7 +6,7 @@ export-objs = ddp.o
obj-$(CONFIG_ATALK) += appletalk.o
-appletalk-y := aarp.o ddp.o
+appletalk-y := aarp.o ddp.o atalk_proc.o
appletalk-$(CONFIG_SYSCTL) += sysctl_net_atalk.o
appletalk-objs := $(appletalk-y)
diff --git a/net/appletalk/aarp.c b/net/appletalk/aarp.c
index c86f71734d9c..ee2303344c7a 100644
--- a/net/appletalk/aarp.c
+++ b/net/appletalk/aarp.c
@@ -30,34 +30,13 @@
*/
#include <linux/config.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/inet.h>
-#include <linux/notifier.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
#include <linux/if_arp.h>
-#include <linux/skbuff.h>
-#include <linux/spinlock.h>
#include <net/sock.h>
#include <net/datalink.h>
#include <net/psnap.h>
#include <linux/atalk.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
-#include <linux/module.h>
int sysctl_aarp_expiry_time = AARP_EXPIRY_TIME;
int sysctl_aarp_tick_time = AARP_TICK_TIME;
@@ -995,4 +974,3 @@ void aarp_unregister_proc_fs(void)
proc_net_remove("aarp");
}
#endif
-MODULE_LICENSE("GPL");
diff --git a/net/appletalk/atalk_proc.c b/net/appletalk/atalk_proc.c
new file mode 100644
index 000000000000..7a990eff3066
--- /dev/null
+++ b/net/appletalk/atalk_proc.c
@@ -0,0 +1,319 @@
+/*
+ * atalk_proc.c - proc support for Appletalk
+ *
+ * Copyright(c) Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * 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, version 2.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <net/sock.h>
+#include <linux/atalk.h>
+
+#ifdef CONFIG_PROC_FS
+static __inline__ struct atalk_iface *atalk_get_interface_idx(loff_t pos)
+{
+ struct atalk_iface *i;
+
+ for (i = atalk_interfaces; pos && i; i = i->next)
+ --pos;
+
+ return i;
+}
+
+static void *atalk_seq_interface_start(struct seq_file *seq, loff_t *pos)
+{
+ loff_t l = *pos;
+
+ spin_lock_bh(&atalk_interfaces_lock);
+ return l ? atalk_get_interface_idx(--l) : (void *)1;
+}
+
+static void *atalk_seq_interface_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ struct atalk_iface *i;
+
+ ++*pos;
+ if (v == (void *)1) {
+ i = NULL;
+ if (atalk_interfaces)
+ i = atalk_interfaces;
+ goto out;
+ }
+ i = v;
+ i = i->next;
+out:
+ return i;
+}
+
+static void atalk_seq_interface_stop(struct seq_file *seq, void *v)
+{
+ spin_unlock_bh(&atalk_interfaces_lock);
+}
+
+static int atalk_seq_interface_show(struct seq_file *seq, void *v)
+{
+ struct atalk_iface *iface;
+
+ if (v == (void *)1) {
+ seq_puts(seq, "Interface Address Networks "
+ "Status\n");
+ goto out;
+ }
+
+ iface = v;
+ seq_printf(seq, "%-16s %04X:%02X %04X-%04X %d\n",
+ iface->dev->name, ntohs(iface->address.s_net),
+ iface->address.s_node, ntohs(iface->nets.nr_firstnet),
+ ntohs(iface->nets.nr_lastnet), iface->status);
+out:
+ return 0;
+}
+
+static __inline__ struct atalk_route *atalk_get_route_idx(loff_t pos)
+{
+ struct atalk_route *r;
+
+ for (r = atalk_routes; pos && r; r = r->next)
+ --pos;
+
+ return r;
+}
+
+static void *atalk_seq_route_start(struct seq_file *seq, loff_t *pos)
+{
+ loff_t l = *pos;
+
+ read_lock_bh(&atalk_routes_lock);
+ return l ? atalk_get_route_idx(--l) : (void *)1;
+}
+
+static void *atalk_seq_route_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ struct atalk_route *r;
+
+ ++*pos;
+ if (v == (void *)1) {
+ r = NULL;
+ if (atalk_routes)
+ r = atalk_routes;
+ goto out;
+ }
+ r = v;
+ r = r->next;
+out:
+ return r;
+}
+
+static void atalk_seq_route_stop(struct seq_file *seq, void *v)
+{
+ read_unlock_bh(&atalk_routes_lock);
+}
+
+static int atalk_seq_route_show(struct seq_file *seq, void *v)
+{
+ struct atalk_route *rt;
+
+ if (v == (void *)1) {
+ seq_puts(seq, "Target Router Flags Dev\n");
+ goto out;
+ }
+
+ if (atrtr_default.dev) {
+ rt = &atrtr_default;
+ seq_printf(seq, "Default %04X:%02X %-4d %s\n",
+ ntohs(rt->gateway.s_net), rt->gateway.s_node,
+ rt->flags, rt->dev->name);
+ }
+
+ rt = v;
+ seq_printf(seq, "%04X:%02X %04X:%02X %-4d %s\n",
+ ntohs(rt->target.s_net), rt->target.s_node,
+ ntohs(rt->gateway.s_net), rt->gateway.s_node,
+ rt->flags, rt->dev->name);
+out:
+ return 0;
+}
+
+static __inline__ struct sock *atalk_get_socket_idx(loff_t pos)
+{
+ struct sock *s;
+
+ for (s = atalk_sockets; pos && s; s = s->next)
+ --pos;
+
+ return s;
+}
+
+static void *atalk_seq_socket_start(struct seq_file *seq, loff_t *pos)
+{
+ loff_t l = *pos;
+
+ spin_lock_bh(&atalk_sockets_lock);
+ return l ? atalk_get_socket_idx(--l) : (void *)1;
+}
+
+static void *atalk_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ struct sock *i;
+
+ ++*pos;
+ if (v == (void *)1) {
+ i = NULL;
+ if (atalk_sockets)
+ i = atalk_sockets;
+ goto out;
+ }
+ i = v;
+ i = i->next;
+out:
+ return i;
+}
+
+static void atalk_seq_socket_stop(struct seq_file *seq, void *v)
+{
+ spin_unlock_bh(&atalk_sockets_lock);
+}
+
+static int atalk_seq_socket_show(struct seq_file *seq, void *v)
+{
+ struct sock *s;
+ struct atalk_sock *at;
+
+ if (v == (void *)1) {
+ seq_printf(seq, "Type Local_addr Remote_addr Tx_queue "
+ "Rx_queue St UID\n");
+ goto out;
+ }
+
+ s = v;
+ at = at_sk(s);
+
+ seq_printf(seq, "%02X %04X:%02X:%02X %04X:%02X:%02X %08X:%08X "
+ "%02X %d\n",
+ s->type, ntohs(at->src_net), at->src_node, at->src_port,
+ ntohs(at->dest_net), at->dest_node, at->dest_port,
+ atomic_read(&s->wmem_alloc), atomic_read(&s->rmem_alloc),
+ s->state, SOCK_INODE(s->socket)->i_uid);
+out:
+ return 0;
+}
+
+struct seq_operations atalk_seq_interface_ops = {
+ .start = atalk_seq_interface_start,
+ .next = atalk_seq_interface_next,
+ .stop = atalk_seq_interface_stop,
+ .show = atalk_seq_interface_show,
+};
+
+struct seq_operations atalk_seq_route_ops = {
+ .start = atalk_seq_route_start,
+ .next = atalk_seq_route_next,
+ .stop = atalk_seq_route_stop,
+ .show = atalk_seq_route_show,
+};
+
+struct seq_operations atalk_seq_socket_ops = {
+ .start = atalk_seq_socket_start,
+ .next = atalk_seq_socket_next,
+ .stop = atalk_seq_socket_stop,
+ .show = atalk_seq_socket_show,
+};
+
+static int atalk_seq_interface_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &atalk_seq_interface_ops);
+}
+
+static int atalk_seq_route_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &atalk_seq_route_ops);
+}
+
+static int atalk_seq_socket_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &atalk_seq_socket_ops);
+}
+
+static struct file_operations atalk_seq_interface_fops = {
+ .open = atalk_seq_interface_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static struct file_operations atalk_seq_route_fops = {
+ .open = atalk_seq_route_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static struct file_operations atalk_seq_socket_fops = {
+ .open = atalk_seq_socket_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static struct proc_dir_entry *atalk_proc_dir;
+
+int __init atalk_proc_init(void)
+{
+ struct proc_dir_entry *p;
+ int rc = -ENOMEM;
+
+ atalk_proc_dir = proc_mkdir("atalk", proc_net);
+ if (!atalk_proc_dir)
+ goto out;
+
+ p = create_proc_entry("interface", S_IRUGO, atalk_proc_dir);
+ if (!p)
+ goto out_interface;
+ p->proc_fops = &atalk_seq_interface_fops;
+
+ p = create_proc_entry("route", S_IRUGO, atalk_proc_dir);
+ if (!p)
+ goto out_route;
+ p->proc_fops = &atalk_seq_route_fops;
+
+ p = create_proc_entry("socket", S_IRUGO, atalk_proc_dir);
+ if (!p)
+ goto out_socket;
+ p->proc_fops = &atalk_seq_socket_fops;
+
+ rc = 0;
+out:
+ return rc;
+out_socket:
+ remove_proc_entry("route", atalk_proc_dir);
+out_route:
+ remove_proc_entry("interface", atalk_proc_dir);
+out_interface:
+ remove_proc_entry("atalk", proc_net);
+ goto out;
+}
+
+void __exit atalk_proc_exit(void)
+{
+ remove_proc_entry("interface", atalk_proc_dir);
+ remove_proc_entry("route", atalk_proc_dir);
+ remove_proc_entry("socket", atalk_proc_dir);
+ remove_proc_entry("atalk", proc_net);
+}
+
+#else /* CONFIG_PROC_FS */
+int __init atalk_proc_init(void)
+{
+ return 0;
+}
+
+void __exit atalk_proc_exit(void)
+{
+}
+#endif /* CONFIG_PROC_FS */
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 3a3eae32fa43..5b1dc1368548 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -40,6 +40,8 @@
* result.
* Arnaldo C. de Melo : Cleanup, in preparation for
* shared skb support 8)
+ * Arnaldo C. de Melo : Move proc stuff to atalk_proc.c,
+ * use seq_file
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -50,41 +52,14 @@
#include <linux/config.h>
#include <linux/module.h>
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <linux/in.h>
#include <linux/tcp.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/if_ether.h>
-#include <linux/notifier.h>
-#include <linux/netdevice.h>
-#include <linux/inetdevice.h>
-#include <linux/route.h>
-#include <linux/inet.h>
-#include <linux/etherdevice.h>
#include <linux/if_arp.h>
-#include <linux/skbuff.h>
-#include <linux/spinlock.h>
#include <linux/termios.h> /* For TIOCOUTQ/INQ */
#include <net/datalink.h>
-#include <net/p8022.h>
#include <net/psnap.h>
#include <net/sock.h>
-#include <linux/ip.h>
#include <net/route.h>
#include <linux/atalk.h>
-#include <linux/proc_fs.h>
-#include <linux/stat.h>
-#include <linux/init.h>
#ifdef CONFIG_PROC_FS
extern void aarp_register_proc_fs(void);
@@ -112,8 +87,8 @@ static struct proto_ops atalk_dgram_ops;
* *
\**************************************************************************/
-static struct sock *atalk_sockets;
-static spinlock_t atalk_sockets_lock = SPIN_LOCK_UNLOCKED;
+struct sock *atalk_sockets;
+spinlock_t atalk_sockets_lock = SPIN_LOCK_UNLOCKED;
extern inline void atalk_insert_socket(struct sock *sk)
{
@@ -244,53 +219,6 @@ extern inline void atalk_destroy_socket(struct sock *sk)
}
}
-/* Called from proc fs */
-static int atalk_get_info(char *buffer, char **start, off_t offset, int length)
-{
- off_t pos = 0;
- off_t begin = 0;
- int len = sprintf(buffer, "Type local_addr remote_addr tx_queue "
- "rx_queue st uid\n");
- struct sock *s;
- /* Output the AppleTalk data for the /proc filesystem */
-
- spin_lock_bh(&atalk_sockets_lock);
- for (s = atalk_sockets; s; s = s->next) {
- struct atalk_sock *at = at_sk(s);
-
- len += sprintf(buffer + len, "%02X ", s->type);
- len += sprintf(buffer + len, "%04X:%02X:%02X ",
- ntohs(at->src_net), at->src_node, at->src_port);
- len += sprintf(buffer + len, "%04X:%02X:%02X ",
- ntohs(at->dest_net), at->dest_node,
- at->dest_port);
- len += sprintf(buffer + len, "%08X:%08X ",
- atomic_read(&s->wmem_alloc),
- atomic_read(&s->rmem_alloc));
- len += sprintf(buffer + len, "%02X %d\n", s->state,
- SOCK_INODE(s->socket)->i_uid);
-
- /* Are we still dumping unwanted data then discard the record */
- pos = begin + len;
-
- if (pos < offset) {
- len = 0; /* Keep dumping into the buffer start */
- begin = pos;
- }
- if (pos > offset + length) /* We have dumped enough */
- break;
- }
- spin_unlock_bh(&atalk_sockets_lock);
-
- /* The data in question runs from begin to begin + len */
- *start = buffer + offset - begin; /* Start of wanted data */
- len -= offset - begin; /* Remove unwanted header data from length */
- if (len > length)
- len = length; /* Remove unwanted tail data from length */
-
- return len;
-}
-
/**************************************************************************\
* *
* Routing tables for the AppleTalk socket layer. *
@@ -298,14 +226,14 @@ static int atalk_get_info(char *buffer, char **start, off_t offset, int length)
\**************************************************************************/
/* Anti-deadlock ordering is router_lock --> iface_lock -DaveM */
-static struct atalk_route *atalk_router_list;
-static rwlock_t atalk_router_lock = RW_LOCK_UNLOCKED;
+struct atalk_route *atalk_routes;
+rwlock_t atalk_routes_lock = RW_LOCK_UNLOCKED;
-static struct atalk_iface *atalk_iface_list;
-static spinlock_t atalk_iface_lock = SPIN_LOCK_UNLOCKED;
+struct atalk_iface *atalk_interfaces;
+spinlock_t atalk_interfaces_lock = SPIN_LOCK_UNLOCKED;
/* For probing devices or in a routerless network */
-static struct atalk_route atrtr_default;
+struct atalk_route atrtr_default;
/* AppleTalk interface control */
/*
@@ -314,10 +242,10 @@ static struct atalk_route atrtr_default;
*/
static void atif_drop_device(struct net_device *dev)
{
- struct atalk_iface **iface = &atalk_iface_list;
+ struct atalk_iface **iface = &atalk_interfaces;
struct atalk_iface *tmp;
- spin_lock_bh(&atalk_iface_lock);
+ spin_lock_bh(&atalk_interfaces_lock);
while ((tmp = *iface) != NULL) {
if (tmp->dev == dev) {
*iface = tmp->next;
@@ -327,7 +255,7 @@ static void atif_drop_device(struct net_device *dev)
} else
iface = &tmp->next;
}
- spin_unlock_bh(&atalk_iface_lock);
+ spin_unlock_bh(&atalk_interfaces_lock);
}
static struct atalk_iface *atif_add_device(struct net_device *dev,
@@ -346,10 +274,10 @@ static struct atalk_iface *atif_add_device(struct net_device *dev,
iface->address = *sa;
iface->status = 0;
- spin_lock_bh(&atalk_iface_lock);
- iface->next = atalk_iface_list;
- atalk_iface_list = iface;
- spin_unlock_bh(&atalk_iface_lock);
+ spin_lock_bh(&atalk_interfaces_lock);
+ iface->next = atalk_interfaces;
+ atalk_interfaces = iface;
+ spin_unlock_bh(&atalk_interfaces_lock);
out:
return iface;
out_mem:
@@ -466,8 +394,8 @@ static struct atalk_addr *atalk_find_primary(void)
* Return a point-to-point interface only if
* there is no non-ptp interface available.
*/
- spin_lock_bh(&atalk_iface_lock);
- for (iface = atalk_iface_list; iface; iface = iface->next) {
+ spin_lock_bh(&atalk_interfaces_lock);
+ for (iface = atalk_interfaces; iface; iface = iface->next) {
if (!fiface && !(iface->dev->flags & IFF_LOOPBACK))
fiface = iface;
if (!(iface->dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) {
@@ -478,12 +406,12 @@ static struct atalk_addr *atalk_find_primary(void)
if (fiface)
retval = &fiface->address;
- else if (atalk_iface_list)
- retval = &atalk_iface_list->address;
+ else if (atalk_interfaces)
+ retval = &atalk_interfaces->address;
else
retval = NULL;
out:
- spin_unlock_bh(&atalk_iface_lock);
+ spin_unlock_bh(&atalk_interfaces_lock);
return retval;
}
@@ -514,8 +442,8 @@ static struct atalk_iface *atalk_find_interface(int net, int node)
{
struct atalk_iface *iface;
- spin_lock_bh(&atalk_iface_lock);
- for (iface = atalk_iface_list; iface; iface = iface->next) {
+ spin_lock_bh(&atalk_interfaces_lock);
+ for (iface = atalk_interfaces; iface; iface = iface->next) {
if ((node == ATADDR_BCAST ||
node == ATADDR_ANYNODE ||
iface->address.s_node == node) &&
@@ -529,7 +457,7 @@ static struct atalk_iface *atalk_find_interface(int net, int node)
ntohs(net) <= ntohs(iface->nets.nr_lastnet))
break;
}
- spin_unlock_bh(&atalk_iface_lock);
+ spin_unlock_bh(&atalk_interfaces_lock);
return iface;
}
@@ -549,8 +477,8 @@ static struct atalk_route *atrtr_find(struct atalk_addr *target)
struct atalk_route *net_route = NULL;
struct atalk_route *r;
- read_lock_bh(&atalk_router_lock);
- for (r = atalk_router_list; r; r = r->next) {
+ read_lock_bh(&atalk_routes_lock);
+ for (r = atalk_routes; r; r = r->next) {
if (!(r->flags & RTF_UP))
continue;
@@ -582,7 +510,7 @@ static struct atalk_route *atrtr_find(struct atalk_addr *target)
else /* No route can be found */
r = NULL;
out:
- read_unlock_bh(&atalk_router_lock);
+ read_unlock_bh(&atalk_routes_lock);
return r;
}
@@ -630,8 +558,8 @@ static int atrtr_create(struct rtentry *r, struct net_device *devhint)
goto out;
/* Now walk the routing table and make our decisions */
- write_lock_bh(&atalk_router_lock);
- for (rt = atalk_router_list; rt; rt = rt->next) {
+ write_lock_bh(&atalk_routes_lock);
+ for (rt = atalk_routes; rt; rt = rt->next) {
if (r->rt_flags != rt->flags)
continue;
@@ -646,8 +574,8 @@ static int atrtr_create(struct rtentry *r, struct net_device *devhint)
if (!devhint) {
riface = NULL;
- spin_lock_bh(&atalk_iface_lock);
- for (iface = atalk_iface_list; iface; iface = iface->next) {
+ spin_lock_bh(&atalk_interfaces_lock);
+ for (iface = atalk_interfaces; iface; iface = iface->next) {
if (!riface &&
ntohs(ga->sat_addr.s_net) >=
ntohs(iface->nets.nr_firstnet) &&
@@ -659,7 +587,7 @@ static int atrtr_create(struct rtentry *r, struct net_device *devhint)
ga->sat_addr.s_node == iface->address.s_node)
riface = iface;
}
- spin_unlock_bh(&atalk_iface_lock);
+ spin_unlock_bh(&atalk_interfaces_lock);
retval = -ENETUNREACH;
if (!riface)
@@ -675,8 +603,8 @@ static int atrtr_create(struct rtentry *r, struct net_device *devhint)
if (!rt)
goto out;
- rt->next = atalk_router_list;
- atalk_router_list = rt;
+ rt->next = atalk_routes;
+ atalk_routes = rt;
}
/* Fill in the routing entry */
@@ -687,7 +615,7 @@ static int atrtr_create(struct rtentry *r, struct net_device *devhint)
retval = 0;
out_unlock:
- write_unlock_bh(&atalk_router_lock);
+ write_unlock_bh(&atalk_routes_lock);
out:
return retval;
}
@@ -695,11 +623,11 @@ out:
/* Delete a route. Find it and discard it */
static int atrtr_delete(struct atalk_addr * addr)
{
- struct atalk_route **r = &atalk_router_list;
+ struct atalk_route **r = &atalk_routes;
int retval = 0;
struct atalk_route *tmp;
- write_lock_bh(&atalk_router_lock);
+ write_lock_bh(&atalk_routes_lock);
while ((tmp = *r) != NULL) {
if (tmp->target.s_net == addr->s_net &&
(!(tmp->flags&RTF_GATEWAY) ||
@@ -712,7 +640,7 @@ static int atrtr_delete(struct atalk_addr * addr)
}
retval = -ENOENT;
out:
- write_unlock_bh(&atalk_router_lock);
+ write_unlock_bh(&atalk_routes_lock);
return retval;
}
@@ -722,10 +650,10 @@ out:
*/
void atrtr_device_down(struct net_device *dev)
{
- struct atalk_route **r = &atalk_router_list;
+ struct atalk_route **r = &atalk_routes;
struct atalk_route *tmp;
- write_lock_bh(&atalk_router_lock);
+ write_lock_bh(&atalk_routes_lock);
while ((tmp = *r) != NULL) {
if (tmp->dev == dev) {
*r = tmp->next;
@@ -733,7 +661,7 @@ void atrtr_device_down(struct net_device *dev)
} else
r = &tmp->next;
}
- write_unlock_bh(&atalk_router_lock);
+ write_unlock_bh(&atalk_routes_lock);
if (atrtr_default.dev == dev)
atrtr_set_default(NULL);
@@ -1013,81 +941,6 @@ static int atrtr_ioctl(unsigned int cmd, void *arg)
return -EINVAL;
}
-/* Called from proc fs - just make it print the ifaces neatly */
-static int atalk_if_get_info(char *buffer, char **start, off_t offset,
- int length)
-{
- off_t pos = 0;
- off_t begin = 0;
- struct atalk_iface *iface;
- int len = sprintf(buffer, "Interface Address "
- "Networks Status\n");
-
- spin_lock_bh(&atalk_iface_lock);
- for (iface = atalk_iface_list; iface; iface = iface->next) {
- len += sprintf(buffer + len, "%-16s %04X:%02X %04X-%04X %d\n",
- iface->dev->name, ntohs(iface->address.s_net),
- iface->address.s_node,
- ntohs(iface->nets.nr_firstnet),
- ntohs(iface->nets.nr_lastnet), iface->status);
- pos = begin + len;
- if (pos < offset) {
- len = 0;
- begin = pos;
- }
- if (pos > offset + length)
- break;
- }
- spin_unlock_bh(&atalk_iface_lock);
-
- *start = buffer + (offset - begin);
- len -= (offset - begin);
- if (len > length)
- len = length;
- return len;
-}
-
-/* Called from proc fs - just make it print the routes neatly */
-static int atalk_rt_get_info(char *buffer, char **start, off_t offset,
- int length)
-{
- off_t pos = 0;
- off_t begin = 0;
- int len = sprintf(buffer, "Target Router Flags Dev\n");
- struct atalk_route *rt;
-
- if (atrtr_default.dev) {
- rt = &atrtr_default;
- len += sprintf(buffer + len,
- "Default %04X:%02X %-4d %s\n",
- ntohs(rt->gateway.s_net), rt->gateway.s_node,
- rt->flags, rt->dev->name);
- }
-
- read_lock_bh(&atalk_router_lock);
- for (rt = atalk_router_list; rt; rt = rt->next) {
- len += sprintf(buffer + len,
- "%04X:%02X %04X:%02X %-4d %s\n",
- ntohs(rt->target.s_net), rt->target.s_node,
- ntohs(rt->gateway.s_net), rt->gateway.s_node,
- rt->flags, rt->dev->name);
- pos = begin + len;
- if (pos < offset) {
- len = 0;
- begin = pos;
- }
- if (pos > offset + length)
- break;
- }
- read_unlock_bh(&atalk_router_lock);
-
- *start = buffer + (offset - begin);
- len -= (offset - begin);
- if (len > length)
- len = length;
- return len;
-}
-
/**************************************************************************\
* *
* Handling for system calls applied via the various interfaces to an *
@@ -1991,17 +1844,14 @@ static int __init atalk_init(void)
register_netdevice_notifier(&ddp_notifier);
aarp_proto_init();
-
- proc_net_create("appletalk", 0, atalk_get_info);
- proc_net_create("atalk_route", 0, atalk_rt_get_info);
- proc_net_create("atalk_iface", 0, atalk_if_get_info);
+ atalk_proc_init();
#ifdef CONFIG_PROC_FS
aarp_register_proc_fs();
#endif /* CONFIG_PROC_FS */
#ifdef CONFIG_SYSCTL
atalk_register_sysctl();
#endif /* CONFIG_SYSCTL */
- printk(KERN_INFO "NET4: AppleTalk 0.18a for Linux NET4.0\n");
+ printk(KERN_INFO "NET4: AppleTalk 0.20 for Linux NET4.0\n");
return 0;
}
module_init(atalk_init);
@@ -2024,9 +1874,7 @@ static void __exit atalk_exit(void)
#ifdef CONFIG_SYSCTL
atalk_unregister_sysctl();
#endif /* CONFIG_SYSCTL */
- proc_net_remove("appletalk");
- proc_net_remove("atalk_route");
- proc_net_remove("atalk_iface");
+ atalk_proc_exit();
#ifdef CONFIG_PROC_FS
aarp_unregister_proc_fs();
#endif /* CONFIG_PROC_FS */
@@ -2039,3 +1887,7 @@ static void __exit atalk_exit(void)
}
module_exit(atalk_exit);
#endif /* MODULE */
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Alan Cox <Alan.Cox@linux.org>");
+MODULE_DESCRIPTION("AppleTalk 0.20 for Linux NET4.0\n");
diff --git a/net/appletalk/sysctl_net_atalk.c b/net/appletalk/sysctl_net_atalk.c
index 663df18c826a..ea6a990c77d8 100644
--- a/net/appletalk/sysctl_net_atalk.c
+++ b/net/appletalk/sysctl_net_atalk.c
@@ -7,7 +7,6 @@
*/
#include <linux/config.h>
-#include <linux/mm.h>
#include <linux/sysctl.h>
extern int sysctl_aarp_expiry_time;
@@ -16,7 +15,7 @@ extern int sysctl_aarp_retransmit_limit;
extern int sysctl_aarp_resolve_time;
#ifdef CONFIG_SYSCTL
-static ctl_table atalk_table[] = {
+static struct ctl_table atalk_table[] = {
{
.ctl_name = NET_ATALK_AARP_EXPIRY_TIME,
.procname = "aarp-expiry-time",
@@ -52,7 +51,7 @@ static ctl_table atalk_table[] = {
{ 0 },
};
-static ctl_table atalk_dir_table[] = {
+static struct ctl_table atalk_dir_table[] = {
{
.ctl_name = NET_ATALK,
.procname = "appletalk",
@@ -62,7 +61,7 @@ static ctl_table atalk_dir_table[] = {
{ 0 },
};
-static ctl_table atalk_root_table[] = {
+static struct ctl_table atalk_root_table[] = {
{
.ctl_name = CTL_NET,
.procname = "net",
diff --git a/net/bridge/br.c b/net/bridge/br.c
index c4a03bd392b0..2af745df791f 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -21,6 +21,7 @@
#include <linux/etherdevice.h>
#include <linux/init.h>
#include <linux/if_bridge.h>
+#include <linux/brlock.h>
#include <asm/uaccess.h>
#include "br_private.h"
@@ -55,11 +56,6 @@ static int __init br_init(void)
return 0;
}
-static void __br_clear_frame_hook(void)
-{
- br_handle_frame_hook = NULL;
-}
-
static void __br_clear_ioctl_hook(void)
{
br_ioctl_hook = NULL;
@@ -69,7 +65,11 @@ static void __exit br_deinit(void)
{
unregister_netdevice_notifier(&br_device_notifier);
br_call_ioctl_atomic(__br_clear_ioctl_hook);
- net_call_rx_atomic(__br_clear_frame_hook);
+
+ br_write_lock_bh(BR_NETPROTO_LOCK);
+ br_handle_frame_hook = NULL;
+ br_write_unlock_bh(BR_NETPROTO_LOCK);
+
#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
br_fdb_get_hook = NULL;
br_fdb_put_hook = NULL;
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index ea1a238bc790..e3c38e52a741 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -18,6 +18,7 @@
#include <linux/if_bridge.h>
#include <linux/inetdevice.h>
#include <linux/rtnetlink.h>
+#include <linux/brlock.h>
#include <asm/uaccess.h>
#include "br_private.h"
@@ -37,7 +38,7 @@ static int br_initial_port_cost(struct net_device *dev)
return 100;
}
-/* called under bridge lock */
+/* called under BR_NETPROTO_LOCK and bridge lock */
static int __br_del_if(struct net_bridge *br, struct net_device *dev)
{
struct net_bridge_port *p;
@@ -86,10 +87,12 @@ static struct net_bridge **__find_br(char *name)
static void del_ifs(struct net_bridge *br)
{
- write_lock_bh(&br->lock);
+ br_write_lock_bh(BR_NETPROTO_LOCK);
+ write_lock(&br->lock);
while (br->port_list != NULL)
__br_del_if(br, br->port_list->dev);
- write_unlock_bh(&br->lock);
+ write_unlock(&br->lock);
+ br_write_unlock_bh(BR_NETPROTO_LOCK);
}
static struct net_bridge *new_nb(char *name)
@@ -252,10 +255,12 @@ int br_del_if(struct net_bridge *br, struct net_device *dev)
{
int retval;
- write_lock_bh(&br->lock);
+ br_write_lock_bh(BR_NETPROTO_LOCK);
+ write_lock(&br->lock);
retval = __br_del_if(br, dev);
br_stp_recalculate_bridge_id(br);
- write_unlock_bh(&br->lock);
+ write_unlock(&br->lock);
+ br_write_unlock_bh(BR_NETPROTO_LOCK);
return retval;
}
diff --git a/net/bridge/br_stp.c b/net/bridge/br_stp.c
index 8625038e1558..1fde8eb0156f 100644
--- a/net/bridge/br_stp.c
+++ b/net/bridge/br_stp.c
@@ -369,10 +369,19 @@ static void br_make_blocking(struct net_bridge_port *p)
static void br_make_forwarding(struct net_bridge_port *p)
{
if (p->state == BR_STATE_BLOCKING) {
- printk(KERN_INFO "%s: port %i(%s) entering %s state\n",
- p->br->dev.name, p->port_no, p->dev->name, "listening");
-
- p->state = BR_STATE_LISTENING;
+ if (p->br->stp_enabled) {
+ printk(KERN_INFO "%s: port %i(%s) entering %s state\n",
+ p->br->dev.name, p->port_no, p->dev->name,
+ "listening");
+
+ p->state = BR_STATE_LISTENING;
+ } else {
+ printk(KERN_INFO "%s: port %i(%s) entering %s state\n",
+ p->br->dev.name, p->port_no, p->dev->name,
+ "learning");
+
+ p->state = BR_STATE_LEARNING;
+ }
br_timer_set(&p->forward_delay_timer, jiffies);
}
}
diff --git a/net/core/dev.c b/net/core/dev.c
index 8ed6cb8b6457..cb92c7dd4bb1 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -904,8 +904,8 @@ void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev)
if (skb2->nh.raw < skb2->data ||
skb2->nh.raw > skb2->tail) {
if (net_ratelimit())
- printk(KERN_DEBUG "protocol %04x is "
- "buggy, dev %s\n",
+ printk(KERN_CRIT "protocol %04x is "
+ "buggy, dev %s\n",
skb2->protocol, dev->name);
skb2->nh.raw = skb2->data;
}
@@ -1062,14 +1062,14 @@ int dev_queue_xmit(struct sk_buff *skb)
dev->xmit_lock_owner = -1;
spin_unlock_bh(&dev->xmit_lock);
if (net_ratelimit())
- printk(KERN_DEBUG "Virtual device %s asks to "
+ printk(KERN_CRIT "Virtual device %s asks to "
"queue packet!\n", dev->name);
goto out_enetdown;
} else {
/* Recursion is detected! It is possible,
* unfortunately */
if (net_ratelimit())
- printk(KERN_DEBUG "Dead loop on virtual device "
+ printk(KERN_CRIT "Dead loop on virtual device "
"%s, fix it urgently!\n", dev->name);
}
}
@@ -1374,20 +1374,6 @@ static void net_tx_action(struct softirq_action *h)
}
}
-/**
- * net_call_rx_atomic
- * @fn: function to call
- *
- * Make a function call that is atomic with respect to the protocol
- * layers.
- */
-void net_call_rx_atomic(void (*fn)(void))
-{
- br_write_lock_bh(BR_NETPROTO_LOCK);
- fn();
- br_write_unlock_bh(BR_NETPROTO_LOCK);
-}
-
#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE)
int (*br_handle_frame_hook)(struct sk_buff *skb) = NULL;
#endif
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 306b15efaa9f..8ae7efe2427c 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -984,16 +984,16 @@ static void rtmsg_ifa(int event, struct in_ifaddr* ifa)
}
static struct rtnetlink_link inet_rtnetlink_table[RTM_MAX - RTM_BASE + 1] = {
- [4] = { doit: inet_rtm_newaddr, },
- [5] = { doit: inet_rtm_deladdr, },
- [6] = { dumpit: inet_dump_ifaddr, },
- [8] = { doit: inet_rtm_newroute, },
- [9] = { doit: inet_rtm_delroute, },
- [10] = { doit: inet_rtm_getroute, dumpit: inet_dump_fib, },
+ [4] = { .doit = inet_rtm_newaddr, },
+ [5] = { .doit = inet_rtm_deladdr, },
+ [6] = { .dumpit = inet_dump_ifaddr, },
+ [8] = { .doit = inet_rtm_newroute, },
+ [9] = { .doit = inet_rtm_delroute, },
+ [10] = { .doit = inet_rtm_getroute, .dumpit = inet_dump_fib, },
#ifdef CONFIG_IP_MULTIPLE_TABLES
- [16] = { doit: inet_rtm_newrule, },
- [17] = { doit: inet_rtm_delrule, },
- [18] = { dumpit: inet_dump_rules, },
+ [16] = { .doit = inet_rtm_newrule, },
+ [17] = { .doit = inet_rtm_delrule, },
+ [18] = { .dumpit = inet_dump_rules, },
#endif
};
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 2b60971dc356..c887839e79ea 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -229,7 +229,7 @@ static int igmp_send_report(struct net_device *dev, u32 group, int type)
iph->version = 4;
iph->ihl = (sizeof(struct iphdr)+4)>>2;
iph->tos = 0;
- iph->frag_off = __constant_htons(IP_DF);
+ iph->frag_off = htons(IP_DF);
iph->ttl = 1;
iph->daddr = dst;
iph->saddr = rt->rt_src;
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 48d1064ffabe..547fbfed7673 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -126,7 +126,7 @@ static struct net_device ipgre_fb_tunnel_dev = {
static struct ip_tunnel ipgre_fb_tunnel = {
.dev = &ipgre_fb_tunnel_dev,
- .parms ={ name: "gre0" }
+ .parms ={ .name = "gre0" }
};
/* Tunnel hash table */
@@ -414,7 +414,7 @@ out:
struct sk_buff *skb2;
struct rtable *rt;
- if (p[1] != __constant_htons(ETH_P_IP))
+ if (p[1] != htons(ETH_P_IP))
return;
flags = p[0];
@@ -537,10 +537,10 @@ out:
static inline void ipgre_ecn_decapsulate(struct iphdr *iph, struct sk_buff *skb)
{
if (INET_ECN_is_ce(iph->tos)) {
- if (skb->protocol == __constant_htons(ETH_P_IP)) {
+ if (skb->protocol == htons(ETH_P_IP)) {
if (INET_ECN_is_not_ce(skb->nh.iph->tos))
IP_ECN_set_ce(skb->nh.iph);
- } else if (skb->protocol == __constant_htons(ETH_P_IPV6)) {
+ } else if (skb->protocol == htons(ETH_P_IPV6)) {
if (INET_ECN_is_not_ce(ip6_get_dsfield(skb->nh.ipv6h)))
IP6_ECN_set_ce(skb->nh.ipv6h);
}
@@ -551,9 +551,9 @@ static inline u8
ipgre_ecn_encapsulate(u8 tos, struct iphdr *old_iph, struct sk_buff *skb)
{
u8 inner = 0;
- if (skb->protocol == __constant_htons(ETH_P_IP))
+ if (skb->protocol == htons(ETH_P_IP))
inner = old_iph->tos;
- else if (skb->protocol == __constant_htons(ETH_P_IPV6))
+ else if (skb->protocol == htons(ETH_P_IPV6))
inner = ip6_get_dsfield((struct ipv6hdr*)old_iph);
return INET_ECN_encapsulate(tos, inner);
}
@@ -710,13 +710,13 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
goto tx_error;
}
- if (skb->protocol == __constant_htons(ETH_P_IP)) {
+ if (skb->protocol == htons(ETH_P_IP)) {
rt = (struct rtable*)skb->dst;
if ((dst = rt->rt_gateway) == 0)
goto tx_error_icmp;
}
#ifdef CONFIG_IPV6
- else if (skb->protocol == __constant_htons(ETH_P_IPV6)) {
+ else if (skb->protocol == htons(ETH_P_IPV6)) {
struct in6_addr *addr6;
int addr_type;
struct neighbour *neigh = skb->dst->neighbour;
@@ -744,7 +744,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
tos = tiph->tos;
if (tos&1) {
- if (skb->protocol == __constant_htons(ETH_P_IP))
+ if (skb->protocol == htons(ETH_P_IP))
tos = old_iph->tos;
tos &= ~1;
}
@@ -767,13 +767,13 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
else
mtu = skb->dst ? skb->dst->pmtu : dev->mtu;
- if (skb->protocol == __constant_htons(ETH_P_IP)) {
+ if (skb->protocol == htons(ETH_P_IP)) {
if (skb->dst && mtu < skb->dst->pmtu && mtu >= 68)
skb->dst->pmtu = mtu;
- df |= (old_iph->frag_off&__constant_htons(IP_DF));
+ df |= (old_iph->frag_off&htons(IP_DF));
- if ((old_iph->frag_off&__constant_htons(IP_DF)) &&
+ if ((old_iph->frag_off&htons(IP_DF)) &&
mtu < ntohs(old_iph->tot_len)) {
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
ip_rt_put(rt);
@@ -781,7 +781,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
}
}
#ifdef CONFIG_IPV6
- else if (skb->protocol == __constant_htons(ETH_P_IPV6)) {
+ else if (skb->protocol == htons(ETH_P_IPV6)) {
struct rt6_info *rt6 = (struct rt6_info*)skb->dst;
if (rt6 && mtu < rt6->u.dst.pmtu && mtu >= IPV6_MIN_MTU) {
@@ -847,10 +847,10 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
iph->saddr = rt->rt_src;
if ((iph->ttl = tiph->ttl) == 0) {
- if (skb->protocol == __constant_htons(ETH_P_IP))
+ if (skb->protocol == htons(ETH_P_IP))
iph->ttl = old_iph->ttl;
#ifdef CONFIG_IPV6
- else if (skb->protocol == __constant_htons(ETH_P_IPV6))
+ else if (skb->protocol == htons(ETH_P_IPV6))
iph->ttl = ((struct ipv6hdr*)old_iph)->hop_limit;
#endif
else
@@ -938,11 +938,11 @@ ipgre_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
err = -EINVAL;
if (p.iph.version != 4 || p.iph.protocol != IPPROTO_GRE ||
- p.iph.ihl != 5 || (p.iph.frag_off&__constant_htons(~IP_DF)) ||
+ p.iph.ihl != 5 || (p.iph.frag_off&htons(~IP_DF)) ||
((p.i_flags|p.o_flags)&(GRE_VERSION|GRE_ROUTING)))
goto done;
if (p.iph.ttl)
- p.iph.frag_off |= __constant_htons(IP_DF);
+ p.iph.frag_off |= htons(IP_DF);
if (!(p.i_flags&GRE_KEY))
p.i_key = 0;
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 9bff742881be..082c29da4047 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -136,7 +136,7 @@ int ip_build_and_send_pkt(struct sk_buff *skb, struct sock *sk,
iph->ihl = 5;
iph->tos = inet->tos;
if (ip_dont_fragment(sk, &rt->u.dst))
- iph->frag_off = __constant_htons(IP_DF);
+ iph->frag_off = htons(IP_DF);
else
iph->frag_off = 0;
iph->ttl = inet->ttl;
@@ -187,7 +187,7 @@ __inline__ int ip_finish_output(struct sk_buff *skb)
struct net_device *dev = skb->dst->dev;
skb->dev = dev;
- skb->protocol = __constant_htons(ETH_P_IP);
+ skb->protocol = htons(ETH_P_IP);
return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev,
ip_finish_output2);
@@ -209,7 +209,7 @@ int ip_mc_output(struct sk_buff *skb)
#endif
skb->dev = dev;
- skb->protocol = __constant_htons(ETH_P_IP);
+ skb->protocol = htons(ETH_P_IP);
/*
* Multicasts are looped back for other local users
@@ -394,7 +394,7 @@ packet_routed:
*((__u16 *)iph) = htons((4 << 12) | (5 << 8) | (inet->tos & 0xff));
iph->tot_len = htons(skb->len);
if (ip_dont_fragment(sk, &rt->u.dst))
- iph->frag_off = __constant_htons(IP_DF);
+ iph->frag_off = htons(IP_DF);
else
iph->frag_off = 0;
iph->ttl = inet->ttl;
@@ -463,7 +463,7 @@ static int ip_build_xmit_slow(struct sock *sk,
mtu = rt->u.dst.pmtu;
if (ip_dont_fragment(sk, &rt->u.dst))
- df = __constant_htons(IP_DF);
+ df = htons(IP_DF);
length -= sizeof(struct iphdr);
@@ -594,7 +594,7 @@ static int ip_build_xmit_slow(struct sock *sk,
/*
* Any further fragments will have MF set.
*/
- mf = __constant_htons(IP_MF);
+ mf = htons(IP_MF);
}
if (rt->rt_type == RTN_MULTICAST)
iph->ttl = inet->mc_ttl;
@@ -693,7 +693,7 @@ int ip_build_xmit(struct sock *sk,
*/
df = 0;
if (ip_dont_fragment(sk, &rt->u.dst))
- df = __constant_htons(IP_DF);
+ df = htons(IP_DF);
/*
* Fast path for unfragmented frames without options.
@@ -797,7 +797,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
*/
offset = (ntohs(iph->frag_off) & IP_OFFSET) << 3;
- not_last_frag = iph->frag_off & __constant_htons(IP_MF);
+ not_last_frag = iph->frag_off & htons(IP_MF);
/*
* Keep copying data until we run out.
@@ -882,7 +882,7 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
* last fragment then keep MF on each bit
*/
if (left > 0 || not_last_frag)
- iph->frag_off |= __constant_htons(IP_MF);
+ iph->frag_off |= htons(IP_MF);
ptr += len;
offset += len;
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c
index 5c752e18b533..28272abbb6d9 100644
--- a/net/ipv4/ipconfig.c
+++ b/net/ipv4/ipconfig.c
@@ -362,11 +362,11 @@ static int __init ic_defaults(void)
if (ic_netmask == INADDR_NONE) {
if (IN_CLASSA(ntohl(ic_myaddr)))
- ic_netmask = __constant_htonl(IN_CLASSA_NET);
+ ic_netmask = htonl(IN_CLASSA_NET);
else if (IN_CLASSB(ntohl(ic_myaddr)))
- ic_netmask = __constant_htonl(IN_CLASSB_NET);
+ ic_netmask = htonl(IN_CLASSB_NET);
else if (IN_CLASSC(ntohl(ic_myaddr)))
- ic_netmask = __constant_htonl(IN_CLASSC_NET);
+ ic_netmask = htonl(IN_CLASSC_NET);
else {
printk(KERN_ERR "IP-Config: Unable to guess netmask for address %u.%u.%u.%u\n",
NIPQUAD(ic_myaddr));
@@ -432,11 +432,11 @@ ic_rarp_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt
goto drop;
/* If it's not a RARP reply, delete it. */
- if (rarp->ar_op != __constant_htons(ARPOP_RREPLY))
+ if (rarp->ar_op != htons(ARPOP_RREPLY))
goto drop;
/* If it's not Ethernet, delete it. */
- if (rarp->ar_pro != __constant_htons(ETH_P_IP))
+ if (rarp->ar_pro != htons(ETH_P_IP))
goto drop;
/* Extract variable-width fields */
@@ -672,15 +672,15 @@ static void __init ic_bootp_send_if(struct ic_device *d, unsigned long jiffies_d
h->version = 4;
h->ihl = 5;
h->tot_len = htons(sizeof(struct bootp_pkt));
- h->frag_off = __constant_htons(IP_DF);
+ h->frag_off = htons(IP_DF);
h->ttl = 64;
h->protocol = IPPROTO_UDP;
h->daddr = INADDR_BROADCAST;
h->check = ip_fast_csum((unsigned char *) h, h->ihl);
/* Construct UDP header */
- b->udph.source = __constant_htons(68);
- b->udph.dest = __constant_htons(67);
+ b->udph.source = htons(68);
+ b->udph.dest = htons(67);
b->udph.len = htons(sizeof(struct bootp_pkt) - sizeof(struct iphdr));
/* UDP checksum not calculated -- explicitly allowed in BOOTP RFC */
@@ -711,7 +711,7 @@ static void __init ic_bootp_send_if(struct ic_device *d, unsigned long jiffies_d
/* Chain packet down the line... */
skb->dev = dev;
- skb->protocol = __constant_htons(ETH_P_IP);
+ skb->protocol = htons(ETH_P_IP);
if ((dev->hard_header &&
dev->hard_header(skb, dev, ntohs(skb->protocol), dev->broadcast, dev->dev_addr, skb->len) < 0) ||
dev_queue_xmit(skb) < 0)
@@ -819,13 +819,13 @@ static int __init ic_bootp_recv(struct sk_buff *skb, struct net_device *dev, str
ip_fast_csum((char *) h, h->ihl) != 0 ||
skb->len < ntohs(h->tot_len) ||
h->protocol != IPPROTO_UDP ||
- b->udph.source != __constant_htons(67) ||
- b->udph.dest != __constant_htons(68) ||
+ b->udph.source != htons(67) ||
+ b->udph.dest != htons(68) ||
ntohs(h->tot_len) < ntohs(b->udph.len) + sizeof(struct iphdr))
goto drop;
/* Fragments are not supported */
- if (h->frag_off & __constant_htons(IP_OFFSET | IP_MF)) {
+ if (h->frag_off & htons(IP_OFFSET | IP_MF)) {
printk(KERN_ERR "DHCP/BOOTP: Ignoring fragmented reply.\n");
goto drop;
}
diff --git a/net/ipv4/ipip.c b/net/ipv4/ipip.c
index a8fa8e86e673..5f7437e6efbd 100644
--- a/net/ipv4/ipip.c
+++ b/net/ipv4/ipip.c
@@ -129,7 +129,7 @@ static struct net_device ipip_fb_tunnel_dev = {
static struct ip_tunnel ipip_fb_tunnel = {
.dev = &ipip_fb_tunnel_dev,
- .parms ={ name: "tunl0", }
+ .parms ={ .name = "tunl0", }
};
static struct ip_tunnel *tunnels_r_l[HASH_SIZE];
@@ -483,7 +483,7 @@ int ipip_rcv(struct sk_buff *skb)
skb->mac.raw = skb->nh.raw;
skb->nh.raw = skb->data;
memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
- skb->protocol = __constant_htons(ETH_P_IP);
+ skb->protocol = htons(ETH_P_IP);
skb->pkt_type = PACKET_HOST;
read_lock(&ipip_lock);
@@ -544,7 +544,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
goto tx_error;
}
- if (skb->protocol != __constant_htons(ETH_P_IP))
+ if (skb->protocol != htons(ETH_P_IP))
goto tx_error;
if (tos&1)
@@ -585,9 +585,9 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
if (skb->dst && mtu < skb->dst->pmtu)
skb->dst->pmtu = mtu;
- df |= (old_iph->frag_off&__constant_htons(IP_DF));
+ df |= (old_iph->frag_off&htons(IP_DF));
- if ((old_iph->frag_off&__constant_htons(IP_DF)) && mtu < ntohs(old_iph->tot_len)) {
+ if ((old_iph->frag_off&htons(IP_DF)) && mtu < ntohs(old_iph->tot_len)) {
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu));
ip_rt_put(rt);
goto tx_error;
@@ -703,10 +703,10 @@ ipip_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
err = -EINVAL;
if (p.iph.version != 4 || p.iph.protocol != IPPROTO_IPIP ||
- p.iph.ihl != 5 || (p.iph.frag_off&__constant_htons(~IP_DF)))
+ p.iph.ihl != 5 || (p.iph.frag_off&htons(~IP_DF)))
goto done;
if (p.iph.ttl)
- p.iph.frag_off |= __constant_htons(IP_DF);
+ p.iph.frag_off |= htons(IP_DF);
t = ipip_tunnel_locate(&p, cmd == SIOCADDTUNNEL);
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 62d2693b133b..50b8550accae 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -1434,7 +1434,7 @@ int pim_rcv_v1(struct sk_buff * skb)
skb->nh.iph = (struct iphdr *)skb->data;
skb->dev = reg_dev;
memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
- skb->protocol = __constant_htons(ETH_P_IP);
+ skb->protocol = htons(ETH_P_IP);
skb->ip_summed = 0;
skb->pkt_type = PACKET_HOST;
dst_release(skb->dst);
@@ -1501,7 +1501,7 @@ int pim_rcv(struct sk_buff * skb)
skb->nh.iph = (struct iphdr *)skb->data;
skb->dev = reg_dev;
memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
- skb->protocol = __constant_htons(ETH_P_IP);
+ skb->protocol = htons(ETH_P_IP);
skb->ip_summed = 0;
skb->pkt_type = PACKET_HOST;
dst_release(skb->dst);
diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c
index 8f7dee29fae3..5c72c54e02b2 100644
--- a/net/ipv4/netfilter/ip_nat_core.c
+++ b/net/ipv4/netfilter/ip_nat_core.c
@@ -804,7 +804,7 @@ do_bindings(struct ip_conntrack *ct,
/* Always defragged for helpers */
IP_NF_ASSERT(!((*pskb)->nh.iph->frag_off
- & __constant_htons(IP_MF|IP_OFFSET)));
+ & htons(IP_MF|IP_OFFSET)));
/* Have to grab read lock before sibling_list traversal */
READ_LOCK(&ip_conntrack_lock);
diff --git a/net/ipv4/netfilter/ip_nat_snmp_basic.c b/net/ipv4/netfilter/ip_nat_snmp_basic.c
index a2dbe5aba949..1ded416880e8 100644
--- a/net/ipv4/netfilter/ip_nat_snmp_basic.c
+++ b/net/ipv4/netfilter/ip_nat_snmp_basic.c
@@ -1260,9 +1260,9 @@ static unsigned int nat_help(struct ip_conntrack *ct,
* on post routing (SNAT).
*/
if (!((dir == IP_CT_DIR_REPLY && hooknum == NF_IP_PRE_ROUTING &&
- udph->source == __constant_ntohs(SNMP_PORT)) ||
+ udph->source == ntohs(SNMP_PORT)) ||
(dir == IP_CT_DIR_ORIGINAL && hooknum == NF_IP_POST_ROUTING &&
- udph->dest == __constant_ntohs(SNMP_TRAP_PORT)))) {
+ udph->dest == ntohs(SNMP_TRAP_PORT)))) {
spin_unlock_bh(&snmp_lock);
return NF_ACCEPT;
}
diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c
index f30fa72b0f45..8eb33381126f 100644
--- a/net/ipv4/netfilter/ip_nat_standalone.c
+++ b/net/ipv4/netfilter/ip_nat_standalone.c
@@ -75,7 +75,7 @@ ip_nat_fn(unsigned int hooknum,
/* We never see fragments: conntrack defrags on pre-routing
and local-out, and ip_nat_out protects post-routing. */
IP_NF_ASSERT(!((*pskb)->nh.iph->frag_off
- & __constant_htons(IP_MF|IP_OFFSET)));
+ & htons(IP_MF|IP_OFFSET)));
(*pskb)->nfcache |= NFC_UNKNOWN;
@@ -186,7 +186,7 @@ ip_nat_out(unsigned int hooknum,
I'm starting to have nightmares about fragments. */
- if ((*pskb)->nh.iph->frag_off & __constant_htons(IP_MF|IP_OFFSET)) {
+ if ((*pskb)->nh.iph->frag_off & htons(IP_MF|IP_OFFSET)) {
*pskb = ip_ct_gather_frags(*pskb);
if (!*pskb)
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index f3efb03d8896..692053a355e2 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1244,7 +1244,7 @@ static int ip_route_input_mc(struct sk_buff *skb, u32 daddr, u32 saddr,
return -EINVAL;
if (MULTICAST(saddr) || BADCLASS(saddr) || LOOPBACK(saddr) ||
- skb->protocol != __constant_htons(ETH_P_IP))
+ skb->protocol != htons(ETH_P_IP))
goto e_inval;
if (ZERONET(saddr)) {
@@ -1455,7 +1455,7 @@ int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr,
inet_addr_onlink(out_dev, saddr, FIB_RES_GW(res))))
flags |= RTCF_DOREDIRECT;
- if (skb->protocol != __constant_htons(ETH_P_IP)) {
+ if (skb->protocol != htons(ETH_P_IP)) {
/* Not IP (i.e. ARP). Do not create route, if it is
* invalid for proxy arp. DNAT routes are always valid.
*/
@@ -1520,7 +1520,7 @@ done:
out: return err;
brd_input:
- if (skb->protocol != __constant_htons(ETH_P_IP))
+ if (skb->protocol != htons(ETH_P_IP))
goto e_inval;
if (ZERONET(saddr))
@@ -2154,7 +2154,7 @@ int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
err = -ENODEV;
if (!dev)
goto out;
- skb->protocol = __constant_htons(ETH_P_IP);
+ skb->protocol = htons(ETH_P_IP);
skb->dev = dev;
local_bh_disable();
err = ip_route_input(skb, dst, src, rtm->rtm_tos, dev);
diff --git a/net/ipv4/tcp_diag.c b/net/ipv4/tcp_diag.c
index ed963291a7cf..505f7574b4f4 100644
--- a/net/ipv4/tcp_diag.c
+++ b/net/ipv4/tcp_diag.c
@@ -360,7 +360,7 @@ int tcpdiag_bc_run(char *bc, int len, struct sock *sk)
break;
if (sk->family == AF_INET6 && cond->family == AF_INET) {
if (addr[0] == 0 && addr[1] == 0 &&
- addr[2] == __constant_htonl(0xffff) &&
+ addr[2] == htonl(0xffff) &&
bitstring_match(addr+3, cond->addr, cond->prefix_len))
break;
}
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index 8c1d316db7b5..3f58b7ce0a54 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2103,8 +2103,8 @@ static __inline__ int tcp_fast_parse_options(struct sk_buff *skb, struct tcphdr
} else if (tp->tstamp_ok &&
th->doff == (sizeof(struct tcphdr)>>2)+(TCPOLEN_TSTAMP_ALIGNED>>2)) {
__u32 *ptr = (__u32 *)(th + 1);
- if (*ptr == __constant_ntohl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16)
- | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) {
+ if (*ptr == ntohl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16)
+ | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) {
tp->saw_tstamp = 1;
++ptr;
tp->rcv_tsval = ntohl(*ptr);
@@ -3275,8 +3275,8 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb,
__u32 *ptr = (__u32 *)(th + 1);
/* No? Slow path! */
- if (*ptr != __constant_ntohl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16)
- | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP))
+ if (*ptr != ntohl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16)
+ | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP))
goto slow_path;
tp->saw_tstamp = 1;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 1bf245763a61..994ed2410d1a 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -81,8 +81,8 @@ void tcp_v4_send_check(struct sock *sk, struct tcphdr *th, int len,
struct tcp_hashinfo __cacheline_aligned tcp_hashinfo = {
.__tcp_lhash_lock = RW_LOCK_UNLOCKED,
.__tcp_lhash_users = ATOMIC_INIT(0),
- __tcp_lhash_wait:
- __WAIT_QUEUE_HEAD_INITIALIZER(tcp_hashinfo.__tcp_lhash_wait),
+ .__tcp_lhash_wait
+ = __WAIT_QUEUE_HEAD_INITIALIZER(tcp_hashinfo.__tcp_lhash_wait),
.__tcp_portalloc_lock = SPIN_LOCK_UNLOCKED
};
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index 5371c054796e..a582e9cb80c8 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -428,7 +428,7 @@ static void tcp_twkill(unsigned long);
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 = { function: tcp_twkill };
+static struct timer_list tcp_tw_timer = { .function = tcp_twkill };
static void SMP_TIMER_NAME(tcp_twkill)(unsigned long dummy)
{
@@ -495,7 +495,7 @@ void tcp_tw_deschedule(struct tcp_tw_bucket *tw)
static int tcp_twcal_hand = -1;
static int tcp_twcal_jiffie;
static void tcp_twcal_tick(unsigned long);
-static struct timer_list tcp_twcal_timer = {function: tcp_twcal_tick};
+static struct timer_list tcp_twcal_timer = {.function = tcp_twcal_tick};
static struct tcp_tw_bucket *tcp_twcal_row[TCP_TW_RECYCLE_SLOTS];
void tcp_tw_schedule(struct tcp_tw_bucket *tw, int timeo)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index d7c18b8efaf5..e78730a04290 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -94,7 +94,7 @@ rwlock_t addrconf_lock = RW_LOCK_UNLOCKED;
static void addrconf_verify(unsigned long);
-static struct timer_list addr_chk_timer = { function: addrconf_verify };
+static struct timer_list addr_chk_timer = { .function = addrconf_verify };
static spinlock_t addrconf_verify_lock = SPIN_LOCK_UNLOCKED;
static int addrconf_ifdown(struct net_device *dev, int how);
@@ -144,47 +144,47 @@ int ipv6_addr_type(struct in6_addr *addr)
/* Consider all addresses with the first three bits different of
000 and 111 as unicasts.
*/
- if ((st & __constant_htonl(0xE0000000)) != __constant_htonl(0x00000000) &&
- (st & __constant_htonl(0xE0000000)) != __constant_htonl(0xE0000000))
+ if ((st & htonl(0xE0000000)) != htonl(0x00000000) &&
+ (st & htonl(0xE0000000)) != htonl(0xE0000000))
return IPV6_ADDR_UNICAST;
- if ((st & __constant_htonl(0xFF000000)) == __constant_htonl(0xFF000000)) {
+ if ((st & htonl(0xFF000000)) == htonl(0xFF000000)) {
int type = IPV6_ADDR_MULTICAST;
- switch((st & __constant_htonl(0x00FF0000))) {
- case __constant_htonl(0x00010000):
+ switch((st & htonl(0x00FF0000))) {
+ case htonl(0x00010000):
type |= IPV6_ADDR_LOOPBACK;
break;
- case __constant_htonl(0x00020000):
+ case htonl(0x00020000):
type |= IPV6_ADDR_LINKLOCAL;
break;
- case __constant_htonl(0x00050000):
+ case htonl(0x00050000):
type |= IPV6_ADDR_SITELOCAL;
break;
};
return type;
}
- if ((st & __constant_htonl(0xFFC00000)) == __constant_htonl(0xFE800000))
+ if ((st & htonl(0xFFC00000)) == htonl(0xFE800000))
return (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_UNICAST);
- if ((st & __constant_htonl(0xFFC00000)) == __constant_htonl(0xFEC00000))
+ if ((st & htonl(0xFFC00000)) == htonl(0xFEC00000))
return (IPV6_ADDR_SITELOCAL | IPV6_ADDR_UNICAST);
if ((addr->s6_addr32[0] | addr->s6_addr32[1]) == 0) {
if (addr->s6_addr32[2] == 0) {
- if (addr->in6_u.u6_addr32[3] == 0)
+ if (addr->s6_addr32[3] == 0)
return IPV6_ADDR_ANY;
- if (addr->s6_addr32[3] == __constant_htonl(0x00000001))
+ if (addr->s6_addr32[3] == htonl(0x00000001))
return (IPV6_ADDR_LOOPBACK | IPV6_ADDR_UNICAST);
return (IPV6_ADDR_COMPATv4 | IPV6_ADDR_UNICAST);
}
- if (addr->s6_addr32[2] == __constant_htonl(0x0000ffff))
+ if (addr->s6_addr32[2] == htonl(0x0000ffff))
return IPV6_ADDR_MAPPED;
}
@@ -755,7 +755,7 @@ static void addrconf_add_mroute(struct net_device *dev)
memset(&rtmsg, 0, sizeof(rtmsg));
ipv6_addr_set(&rtmsg.rtmsg_dst,
- __constant_htonl(0xFF000000), 0, 0, 0);
+ htonl(0xFF000000), 0, 0, 0);
rtmsg.rtmsg_dst_len = 8;
rtmsg.rtmsg_metric = IP6_RT_PRIO_ADDRCONF;
rtmsg.rtmsg_ifindex = dev->ifindex;
@@ -785,7 +785,7 @@ static void addrconf_add_lroute(struct net_device *dev)
{
struct in6_addr addr;
- ipv6_addr_set(&addr, __constant_htonl(0xFE800000), 0, 0, 0);
+ ipv6_addr_set(&addr, htonl(0xFE800000), 0, 0, 0);
addrconf_prefix_route(&addr, 10, dev, 0, RTF_ADDRCONF);
}
@@ -1123,7 +1123,7 @@ static void sit_add_v4_addrs(struct inet6_dev *idev)
memcpy(&addr.s6_addr32[3], idev->dev->dev_addr, 4);
if (idev->dev->flags&IFF_POINTOPOINT) {
- addr.s6_addr32[0] = __constant_htonl(0xfe800000);
+ addr.s6_addr32[0] = htonl(0xfe800000);
scope = IFA_LINK;
} else {
scope = IPV6_ADDR_COMPATv4;
@@ -1237,9 +1237,7 @@ static void addrconf_dev_config(struct net_device *dev)
return;
memset(&addr, 0, sizeof(struct in6_addr));
-
- addr.s6_addr[0] = 0xFE;
- addr.s6_addr[1] = 0x80;
+ addr.s6_addr32[0] = htonl(0xFE800000);
if (ipv6_generate_eui64(addr.s6_addr + 8, dev) == 0)
addrconf_add_linklocal(idev, &addr);
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 612aff241d93..d16af3e623cd 100644
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -150,7 +150,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
}
} else {
ipv6_addr_set(&sin->sin6_addr, 0, 0,
- __constant_htonl(0xffff),
+ htonl(0xffff),
*(u32*)(skb->nh.raw + serr->addr_offset));
}
}
@@ -173,7 +173,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
struct inet_opt *inet = inet_sk(sk);
ipv6_addr_set(&sin->sin6_addr, 0, 0,
- __constant_htonl(0xffff),
+ htonl(0xffff),
skb->nh.iph->saddr);
if (inet->cmsg_flags)
ip_cmsg_recv(msg, skb);
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 4cb9df365f07..d3819b14b010 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -198,7 +198,7 @@ static int is_ineligible(struct sk_buff *skb)
u8 type;
if (skb_copy_bits(skb, ptr+offsetof(struct icmp6hdr, icmp6_type),
&type, 1)
- || !(type & 0x80))
+ || !(type & ICMPV6_INFOMSG_MASK))
return 1;
}
return 0;
@@ -216,7 +216,7 @@ static inline int icmpv6_xrlim_allow(struct sock *sk, int type,
int res = 0;
/* Informational messages are not limited. */
- if (type & 0x80)
+ if (type & ICMPV6_INFOMSG_MASK)
return 1;
/* Do not limit pmtu discovery, it would break it. */
@@ -519,22 +519,22 @@ static int icmpv6_rcv(struct sk_buff *skb)
skb_checksum(skb, 0, skb->len, 0))) {
if (net_ratelimit())
printk(KERN_DEBUG "ICMPv6 checksum failed [%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x > %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x]\n",
- ntohs(saddr->in6_u.u6_addr16[0]),
- ntohs(saddr->in6_u.u6_addr16[1]),
- ntohs(saddr->in6_u.u6_addr16[2]),
- ntohs(saddr->in6_u.u6_addr16[3]),
- ntohs(saddr->in6_u.u6_addr16[4]),
- ntohs(saddr->in6_u.u6_addr16[5]),
- ntohs(saddr->in6_u.u6_addr16[6]),
- ntohs(saddr->in6_u.u6_addr16[7]),
- ntohs(daddr->in6_u.u6_addr16[0]),
- ntohs(daddr->in6_u.u6_addr16[1]),
- ntohs(daddr->in6_u.u6_addr16[2]),
- ntohs(daddr->in6_u.u6_addr16[3]),
- ntohs(daddr->in6_u.u6_addr16[4]),
- ntohs(daddr->in6_u.u6_addr16[5]),
- ntohs(daddr->in6_u.u6_addr16[6]),
- ntohs(daddr->in6_u.u6_addr16[7]));
+ ntohs(saddr->s6_addr16[0]),
+ ntohs(saddr->s6_addr16[1]),
+ ntohs(saddr->s6_addr16[2]),
+ ntohs(saddr->s6_addr16[3]),
+ ntohs(saddr->s6_addr16[4]),
+ ntohs(saddr->s6_addr16[5]),
+ ntohs(saddr->s6_addr16[6]),
+ ntohs(saddr->s6_addr16[7]),
+ ntohs(daddr->s6_addr16[0]),
+ ntohs(daddr->s6_addr16[1]),
+ ntohs(daddr->s6_addr16[2]),
+ ntohs(daddr->s6_addr16[3]),
+ ntohs(daddr->s6_addr16[4]),
+ ntohs(daddr->s6_addr16[5]),
+ ntohs(daddr->s6_addr16[6]),
+ ntohs(daddr->s6_addr16[7]));
goto discard_it;
}
}
@@ -613,7 +613,7 @@ static int icmpv6_rcv(struct sk_buff *skb)
printk(KERN_DEBUG "icmpv6: msg of unkown type\n");
/* informational */
- if (type & 0x80)
+ if (type & ICMPV6_INFOMSG_MASK)
break;
/*
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 12f3addba338..5c9d8b0e6f04 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -93,7 +93,7 @@ static struct fib6_node * fib6_repair_tree(struct fib6_node *fn);
static __u32 rt_sernum = 0;
-static struct timer_list ip6_fib_timer = { function: fib6_run_gc };
+static struct timer_list ip6_fib_timer = { .function = fib6_run_gc };
static struct fib6_walker_t fib6_walker_list = {
&fib6_walker_list, &fib6_walker_list,
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index d164350c781a..4da20babb480 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -102,7 +102,7 @@ int ip6_output(struct sk_buff *skb)
struct dst_entry *dst = skb->dst;
struct net_device *dev = dst->dev;
- skb->protocol = __constant_htons(ETH_P_IPV6);
+ skb->protocol = htons(ETH_P_IPV6);
skb->dev = dev;
if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr)) {
@@ -223,7 +223,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
* Fill in the IPv6 header
*/
- *(u32*)hdr = __constant_htonl(0x60000000) | fl->fl6_flowlabel;
+ *(u32*)hdr = htonl(0x60000000) | fl->fl6_flowlabel;
hlimit = -1;
if (np)
hlimit = np->hop_limit;
@@ -264,7 +264,7 @@ int ip6_nd_hdr(struct sock *sk, struct sk_buff *skb, struct net_device *dev,
struct ipv6hdr *hdr;
int totlen;
- skb->protocol = __constant_htons(ETH_P_IPV6);
+ skb->protocol = htons(ETH_P_IPV6);
skb->dev = dev;
totlen = len + sizeof(struct ipv6hdr);
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index f08e496d9e3f..5e02b47050e9 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -408,14 +408,8 @@ ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct ipq_queue_entry *e)
*/
if (e->info->hook == NF_IP_LOCAL_OUT) {
struct ipv6hdr *iph = e->skb->nh.ipv6h;
- if (!( iph->daddr.in6_u.u6_addr32[0] == e->rt_info.daddr.in6_u.u6_addr32[0]
- && iph->daddr.in6_u.u6_addr32[1] == e->rt_info.daddr.in6_u.u6_addr32[1]
- && iph->daddr.in6_u.u6_addr32[2] == e->rt_info.daddr.in6_u.u6_addr32[2]
- && iph->daddr.in6_u.u6_addr32[3] == e->rt_info.daddr.in6_u.u6_addr32[3]
- && iph->saddr.in6_u.u6_addr32[0] == e->rt_info.saddr.in6_u.u6_addr32[0]
- && iph->saddr.in6_u.u6_addr32[1] == e->rt_info.saddr.in6_u.u6_addr32[1]
- && iph->saddr.in6_u.u6_addr32[2] == e->rt_info.saddr.in6_u.u6_addr32[2]
- && iph->saddr.in6_u.u6_addr32[3] == e->rt_info.saddr.in6_u.u6_addr32[3]))
+ if (ipv6_addr_cmp(&iph->daddr, &e->rt_info.daddr) ||
+ ipv6_addr_cmp(&iph->saddr, &e->rt_info.saddr))
return route6_me_harder(e->skb);
}
return 0;
diff --git a/net/ipv6/netfilter/ip6t_LOG.c b/net/ipv6/netfilter/ip6t_LOG.c
index 74a69222289c..f3f0092c6d8f 100644
--- a/net/ipv6/netfilter/ip6t_LOG.c
+++ b/net/ipv6/netfilter/ip6t_LOG.c
@@ -112,7 +112,7 @@ static void dump_packet(const struct ip6t_log_info *info,
printk("FRAG:%u ", ntohs(fhdr->frag_off) & 0xFFF8);
/* Max length: 11 "INCOMPLETE " */
- if (fhdr->frag_off & __constant_htons(0x0001))
+ if (fhdr->frag_off & htons(0x0001))
printk("INCOMPLETE ");
printk("ID:%08x ", fhdr->identification);
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index c8dc8cd000a1..f934219697f2 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -372,7 +372,7 @@ static void ip6_frag_queue(struct frag_queue *fq, struct sk_buff *skb,
csum_partial(skb->nh.raw, (u8*)(fhdr+1)-skb->nh.raw, 0));
/* Is this the final fragment? */
- if (!(fhdr->frag_off & __constant_htons(0x0001))) {
+ if (!(fhdr->frag_off & htons(0x0001))) {
/* If we already have some bits beyond end
* or have different end, the segment is corrupted.
*/
@@ -648,7 +648,7 @@ int ipv6_reassembly(struct sk_buff **skbp, int nhoff)
hdr = skb->nh.ipv6h;
fhdr = (struct frag_hdr *)skb->h.raw;
- if (!(fhdr->frag_off & __constant_htons(0xFFF9))) {
+ if (!(fhdr->frag_off & htons(0xFFF9))) {
/* It is not a fragmented frame */
skb->h.raw += sizeof(struct frag_hdr);
IP6_INC_STATS_BH(Ip6ReasmOKs);
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index 223c8dbbac95..35fe20015cd8 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -396,7 +396,7 @@ static int ipip6_rcv(struct sk_buff *skb)
skb->mac.raw = skb->nh.raw;
skb->nh.raw = skb->data;
memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options));
- skb->protocol = __constant_htons(ETH_P_IPV6);
+ skb->protocol = htons(ETH_P_IPV6);
skb->pkt_type = PACKET_HOST;
tunnel->stat.rx_packets++;
tunnel->stat.rx_bytes += skb->len;
@@ -470,7 +470,7 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
goto tx_error;
}
- if (skb->protocol != __constant_htons(ETH_P_IPV6))
+ if (skb->protocol != htons(ETH_P_IPV6))
goto tx_error;
if (!dst)
@@ -588,7 +588,7 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
iph->version = 4;
iph->ihl = sizeof(struct iphdr)>>2;
if (mtu > IPV6_MIN_MTU)
- iph->frag_off = __constant_htons(IP_DF);
+ iph->frag_off = htons(IP_DF);
else
iph->frag_off = 0;
@@ -659,10 +659,10 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd)
err = -EINVAL;
if (p.iph.version != 4 || p.iph.protocol != IPPROTO_IPV6 ||
- p.iph.ihl != 5 || (p.iph.frag_off&__constant_htons(~IP_DF)))
+ p.iph.ihl != 5 || (p.iph.frag_off&htons(~IP_DF)))
goto done;
if (p.iph.ttl)
- p.iph.frag_off |= __constant_htons(IP_DF);
+ p.iph.frag_off |= htons(IP_DF);
t = ipip6_tunnel_locate(&p, cmd == SIOCADDTUNNEL);
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 62d100f563bd..0738339a40e2 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -424,11 +424,11 @@ static int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, int len,
sin6->sin6_flowinfo = 0;
sin6->sin6_scope_id = 0;
- if (skb->protocol == __constant_htons(ETH_P_IP)) {
+ if (skb->protocol == htons(ETH_P_IP)) {
struct inet_opt *inet = inet_sk(sk);
ipv6_addr_set(&sin6->sin6_addr, 0, 0,
- __constant_htonl(0xffff), skb->nh.iph->saddr);
+ htonl(0xffff), skb->nh.iph->saddr);
if (inet->cmsg_flags)
ip_cmsg_recv(msg, skb);
} else {
diff --git a/net/ipx/ChangeLog b/net/ipx/ChangeLog
new file mode 100644
index 000000000000..3b29763751a3
--- /dev/null
+++ b/net/ipx/ChangeLog
@@ -0,0 +1,101 @@
+ Revision 0.21: Uses the new generic socket option code.
+
+ Revision 0.22: Gcc clean ups and drop out device registration. Use the
+ new multi-protocol edition of hard_header
+
+ Revision 0.23: IPX /proc by Mark Evans. Adding a route will
+ will overwrite any existing route to the same network.
+
+ Revision 0.24: Supports new /proc with no 4K limit
+
+ Revision 0.25: Add ephemeral sockets, passive local network
+ identification, support for local net 0 and
+ multiple datalinks <Greg Page>
+
+ Revision 0.26: Device drop kills IPX routes via it. (needed for module)
+
+ Revision 0.27: Autobind <Mark Evans>
+
+ Revision 0.28: Small fix for multiple local networks <Thomas Winder>
+
+ Revision 0.29: Assorted major errors removed <Mark Evans>
+ Small correction to promisc mode error fix <Alan Cox>
+ Asynchronous I/O support. Changed to use notifiers
+ and the newer packet_type stuff. Assorted major
+ fixes <Alejandro Liu>
+
+ Revision 0.30: Moved to net/ipx/... <Alan Cox>
+ Don't set address length on recvfrom that errors.
+ Incorrect verify_area.
+
+ Revision 0.31: New sk_buffs. This still needs a lot of
+ testing. <Alan Cox>
+
+ Revision 0.32: Using sock_alloc_send_skb, firewall hooks. <Alan Cox>
+ Supports sendmsg/recvmsg
+
+ Revision 0.33: Internal network support, routing changes, uses a
+ protocol private area for ipx data.
+
+ Revision 0.34: Module support. <Jim Freeman>
+
+ Revision 0.35: Checksum support. <Neil Turton>, hooked in by <Alan Cox>
+ Handles WIN95 discovery packets <Volker Lendecke>
+
+ Revision 0.36: Internal bump up for 2.1
+
+ Revision 0.37: Began adding POSIXisms.
+
+ Revision 0.38: Asynchronous socket stuff made current.
+
+ Revision 0.39: SPX interfaces
+
+ Revision 0.40: Tiny SIOCGSTAMP fix (chris@cybernet.co.nz)
+
+ Revision 0.41: 802.2TR removed (p.norton@computer.org)
+ Fixed connecting to primary net,
+ Automatic binding on send & receive,
+ Martijn van Oosterhout <kleptogimp@geocities.com>
+
+ Revision 042: Multithreading - use spinlocks and refcounting to
+ protect some structures: ipx_interface sock list, list
+ of ipx interfaces, etc.
+ Bugfixes - do refcounting on net_devices, check function
+ results, etc. Thanks to davem and freitag for
+ suggestions and guidance.
+ Arnaldo Carvalho de Melo <acme@conectiva.com.br>,
+ November, 2000
+
+ Revision 043: Shared SKBs, don't mangle packets, some cleanups
+ Arnaldo Carvalho de Melo <acme@conectiva.com.br>,
+ December, 2000
+
+ Revision 044: Call ipxitf_hold on NETDEV_UP - acme
+
+ Revision 045: fix PPROP routing bug - acme
+
+ Revision 046: Further fixes to PPROP, ipxitf_create_internal was
+ doing an unneeded MOD_INC_USE_COUNT, implement
+ sysctl for ipx_pprop_broacasting, fix the ipx sysctl
+ handling, making it dynamic, some cleanups, thanks to
+ Petr Vandrovec for review and good suggestions. (acme)
+
+ Revision 047: Cleanups, CodingStyle changes, move the ncp connection
+ hack out of line - acme
+
+ Revision 048: Use sk->protinfo to store the pointer to IPX private
+ area, remove af_ipx from sk->protinfo and move ipx_opt
+ to include/net/ipx.h, use IPX_SK like DecNET, etc - acme
+
+ Revision 049: SPX support dropped, see comment in ipx_create - acme
+
+ Revision 050: Use seq_file for proc stuff, moving it to ipx_proc.c - acme
+
+Other fixes:
+
+ Protect the module by a MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT pair. Also, now
+ usage count is managed this way:
+ -Count one if the auto_interface mode is on
+ -Count one per configured interface
+
+ Jacques Gelinas (jacques@solucorp.qc.ca)
diff --git a/net/ipx/Makefile b/net/ipx/Makefile
index 0c40039074f3..e17fffc815d8 100644
--- a/net/ipx/Makefile
+++ b/net/ipx/Makefile
@@ -4,7 +4,7 @@
obj-$(CONFIG_IPX) += ipx.o
-ipx-y := af_ipx.o
+ipx-y := af_ipx.o ipx_proc.o
ipx-$(CONFIG_SYSCTL) += sysctl_net_ipx.o
ipx-objs := $(ipx-y)
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
index a0dedb215d95..0951077705e9 100644
--- a/net/ipx/af_ipx.c
+++ b/net/ipx/af_ipx.c
@@ -15,81 +15,17 @@
* liability nor provide warranty for any of this software. This material
* is provided as is and at no charge.
*
- * Revision 0.21: Uses the new generic socket option code.
- * Revision 0.22: Gcc clean ups and drop out device registration. Use the
- * new multi-protocol edition of hard_header
- * Revision 0.23: IPX /proc by Mark Evans. Adding a route will
- * will overwrite any existing route to the same network.
- * Revision 0.24: Supports new /proc with no 4K limit
- * Revision 0.25: Add ephemeral sockets, passive local network
- * identification, support for local net 0 and
- * multiple datalinks <Greg Page>
- * Revision 0.26: Device drop kills IPX routes via it. (needed for module)
- * Revision 0.27: Autobind <Mark Evans>
- * Revision 0.28: Small fix for multiple local networks <Thomas Winder>
- * Revision 0.29: Assorted major errors removed <Mark Evans>
- * Small correction to promisc mode error fix <Alan Cox>
- * Asynchronous I/O support. Changed to use notifiers
- * and the newer packet_type stuff. Assorted major
- * fixes <Alejandro Liu>
- * Revision 0.30: Moved to net/ipx/... <Alan Cox>
- * Don't set address length on recvfrom that errors.
- * Incorrect verify_area.
- * Revision 0.31: New sk_buffs. This still needs a lot of
- * testing. <Alan Cox>
- * Revision 0.32: Using sock_alloc_send_skb, firewall hooks. <Alan Cox>
- * Supports sendmsg/recvmsg
- * Revision 0.33: Internal network support, routing changes, uses a
- * protocol private area for ipx data.
- * Revision 0.34: Module support. <Jim Freeman>
- * Revision 0.35: Checksum support. <Neil Turton>, hooked in by <Alan Cox>
- * Handles WIN95 discovery packets <Volker Lendecke>
- * Revision 0.36: Internal bump up for 2.1
- * Revision 0.37: Began adding POSIXisms.
- * Revision 0.38: Asynchronous socket stuff made current.
- * Revision 0.39: SPX interfaces
- * Revision 0.40: Tiny SIOCGSTAMP fix (chris@cybernet.co.nz)
- * Revision 0.41: 802.2TR removed (p.norton@computer.org)
- * Fixed connecting to primary net,
- * Automatic binding on send & receive,
- * Martijn van Oosterhout <kleptogimp@geocities.com>
- * Revision 042: Multithreading - use spinlocks and refcounting to
- * protect some structures: ipx_interface sock list, list
- * of ipx interfaces, etc.
- * Bugfixes - do refcounting on net_devices, check function
- * results, etc. Thanks to davem and freitag for
- * suggestions and guidance.
- * Arnaldo Carvalho de Melo <acme@conectiva.com.br>,
- * November, 2000
- * Revision 043: Shared SKBs, don't mangle packets, some cleanups
- * Arnaldo Carvalho de Melo <acme@conectiva.com.br>,
- * December, 2000
- * Revision 044: Call ipxitf_hold on NETDEV_UP (acme)
- * Revision 045: fix PPROP routing bug (acme)
- * Revision 046: Further fixes to PPROP, ipxitf_create_internal was
- * doing an unneeded MOD_INC_USE_COUNT, implement
- * sysctl for ipx_pprop_broacasting, fix the ipx sysctl
- * handling, making it dynamic, some cleanups, thanks to
- * Petr Vandrovec for review and good suggestions. (acme)
- * Revision 047: Cleanups, CodingStyle changes, move the ncp connection
- * hack out of line (acme)
- * Revision 048: Use sk->protinfo to store the pointer to IPX private
- * area, remove af_ipx from sk->protinfo and move ipx_opt
- * to include/net/ipx.h, use IPX_SK like DecNET, etc
- * Revision 049: SPX support dropped, see comment in ipx_create
- *
- * Protect the module by a MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT
- * pair. Also, now usage count is managed this way
- * -Count one if the auto_interface mode is on
- * -Count one per configured interface
- *
- * Jacques Gelinas (jacques@solucorp.qc.ca)
- *
+ * Portions Copyright (c) 2000-2002 Conectiva, Inc. <acme@conectiva.com.br>
+ * Neither Arnaldo Carvalho de Melo nor Conectiva, Inc. admit liability nor
+ * provide warranty for any of this software. This material is provided
+ * "AS-IS" and at no charge.
*
* Portions Copyright (c) 1995 Caldera, Inc. <greg@caldera.com>
* Neither Greg Page nor Caldera, Inc. admit liability nor provide
* warranty for any of this software. This material is provided
* "AS-IS" and at no charge.
+ *
+ * See net/ipx/ChangeLog.
*/
#include <linux/config.h>
@@ -145,13 +81,13 @@ static struct datalink_proto *pSNAP_datalink;
static struct proto_ops ipx_dgram_ops;
-static struct ipx_route *ipx_routes;
-static rwlock_t ipx_routes_lock = RW_LOCK_UNLOCKED;
+struct ipx_route *ipx_routes;
+rwlock_t ipx_routes_lock = RW_LOCK_UNLOCKED;
-static struct ipx_interface *ipx_interfaces;
-static spinlock_t ipx_interfaces_lock = SPIN_LOCK_UNLOCKED;
+struct ipx_interface *ipx_interfaces;
+spinlock_t ipx_interfaces_lock = SPIN_LOCK_UNLOCKED;
-static struct ipx_interface *ipx_primary_net;
+struct ipx_interface *ipx_primary_net;
static struct ipx_interface *ipx_internal_net;
#undef IPX_REFCNT_DEBUG
@@ -791,8 +727,6 @@ static int ipxitf_add_local_route(struct ipx_interface *intrfc)
return ipxrtr_add_route(intrfc->if_netnum, intrfc, NULL);
}
-static const char *ipx_frame_name(unsigned short);
-static const char *ipx_device_name(struct ipx_interface *);
static void ipxitf_discover_netnum(struct ipx_interface *intrfc,
struct sk_buff *skb);
static int ipxitf_pprop(struct ipx_interface *intrfc, struct sk_buff *skb);
@@ -1656,7 +1590,7 @@ static int ipxrtr_ioctl(unsigned int cmd, void *arg)
out: return ret;
}
-static const char *ipx_frame_name(unsigned short frame)
+const char *ipx_frame_name(unsigned short frame)
{
char* ret = "None";
@@ -1671,189 +1605,12 @@ static const char *ipx_frame_name(unsigned short frame)
return ret;
}
-static const char *ipx_device_name(struct ipx_interface *intrfc)
+const char *ipx_device_name(struct ipx_interface *intrfc)
{
return intrfc->if_internal ? "Internal" :
intrfc->if_dev ? intrfc->if_dev->name : "Unknown";
}
-/* Called from proc fs */
-static int ipx_interface_get_info(char *buffer, char **start, off_t offset,
- int length)
-{
- struct ipx_interface *i;
- off_t begin = 0, pos = 0;
- int len = 0;
-
- /* Theory.. Keep printing in the same place until we pass offset */
-
- len += sprintf(buffer, "%-11s%-15s%-9s%-11s%s", "Network",
- "Node_Address", "Primary", "Device", "Frame_Type");
-#ifdef IPX_REFCNT_DEBUG
- len += sprintf(buffer + len, " refcnt");
-#endif
- strcat(buffer + len++, "\n");
- spin_lock_bh(&ipx_interfaces_lock);
- for (i = ipx_interfaces; i; i = i->if_next) {
- len += sprintf(buffer + len, "%08lX ",
- (long unsigned int) ntohl(i->if_netnum));
- len += sprintf(buffer + len, "%02X%02X%02X%02X%02X%02X ",
- i->if_node[0], i->if_node[1], i->if_node[2],
- i->if_node[3], i->if_node[4], i->if_node[5]);
- len += sprintf(buffer + len, "%-9s", i == ipx_primary_net ?
- "Yes" : "No");
- len += sprintf(buffer + len, "%-11s", ipx_device_name(i));
- len += sprintf(buffer + len, "%-9s",
- ipx_frame_name(i->if_dlink_type));
-#ifdef IPX_REFCNT_DEBUG
- len += sprintf(buffer + len, "%6d", atomic_read(&i->refcnt));
-#endif
- strcat(buffer + len++, "\n");
- /* Are we still dumping unwanted data then discard the record */
- pos = begin + len;
-
- if (pos < offset) {
- len = 0; /* Keep dumping into the buffer start */
- begin = pos;
- }
- if (pos > offset + length) /* We have dumped enough */
- break;
- }
- spin_unlock_bh(&ipx_interfaces_lock);
-
- /* The data in question runs from begin to begin+len */
- *start = buffer + (offset - begin); /* Start of wanted data */
- len -= (offset - begin); /* Remove unwanted header data from length */
- if (len > length)
- len = length; /* Remove unwanted tail data from length */
-
- return len;
-}
-
-static int ipx_get_info(char *buffer, char **start, off_t offset, int length)
-{
- struct sock *s;
- struct ipx_interface *i;
- off_t begin = 0, pos = 0;
- int len = 0;
-
- /* Theory.. Keep printing in the same place until we pass offset */
-
-#ifdef CONFIG_IPX_INTERN
- len += sprintf(buffer, "%-28s%-28s%-10s%-10s%-7s%s\n", "Local_Address",
-#else
- len += sprintf(buffer, "%-15s%-28s%-10s%-10s%-7s%s\n", "Local_Address",
-#endif /* CONFIG_IPX_INTERN */
- "Remote_Address", "Tx_Queue", "Rx_Queue",
- "State", "Uid");
-
- spin_lock_bh(&ipx_interfaces_lock);
- for (i = ipx_interfaces; i; i = i->if_next) {
- ipxitf_hold(i);
- spin_lock_bh(&i->if_sklist_lock);
- for (s = i->if_sklist; s; s = s->next) {
- struct ipx_opt *ipxs = ipx_sk(s);
-#ifdef CONFIG_IPX_INTERN
- len += sprintf(buffer + len,
- "%08lX:%02X%02X%02X%02X%02X%02X:%04X ",
- (unsigned long)htonl(ipxs->intrfc->if_netnum),
- ipxs->node[0], ipxs->node[1],
- ipxs->node[2], ipxs->node[3],
- ipxs->node[4], ipxs->node[5],
- htons(ipxs->port));
-#else
- len += sprintf(buffer + len, "%08lX:%04X ",
- (unsigned long) htonl(i->if_netnum),
- htons(ipxs->port));
-#endif /* CONFIG_IPX_INTERN */
- if (s->state != TCP_ESTABLISHED)
- len += sprintf(buffer + len, "%-28s",
- "Not_Connected");
- else {
- len += sprintf(buffer + len,
- "%08lX:%02X%02X%02X%02X%02X%02X:%04X ",
- (unsigned long)htonl(ipxs->dest_addr.net),
- ipxs->dest_addr.node[0],
- ipxs->dest_addr.node[1],
- ipxs->dest_addr.node[2],
- ipxs->dest_addr.node[3],
- ipxs->dest_addr.node[4],
- ipxs->dest_addr.node[5],
- htons(ipxs->dest_addr.sock));
- }
-
- len += sprintf(buffer + len, "%08X %08X ",
- atomic_read(&s->wmem_alloc),
- atomic_read(&s->rmem_alloc));
- len += sprintf(buffer + len, "%02X %03d\n",
- s->state, SOCK_INODE(s->socket)->i_uid);
-
- pos = begin + len;
- if (pos < offset) {
- len = 0;
- begin = pos;
- }
-
- if (pos > offset + length) /* We have dumped enough */
- break;
- }
- spin_unlock_bh(&i->if_sklist_lock);
- ipxitf_put(i);
- }
- spin_unlock_bh(&ipx_interfaces_lock);
-
- /* The data in question runs from begin to begin+len */
- *start = buffer + offset - begin;
- len -= (offset - begin);
- if (len > length)
- len = length;
-
- return len;
-}
-
-static int ipx_rt_get_info(char *buffer, char **start, off_t offset, int length)
-{
- struct ipx_route *rt;
- off_t begin = 0, pos = 0;
- int len = 0;
-
- len += sprintf(buffer, "%-11s%-13s%s\n",
- "Network", "Router_Net", "Router_Node");
- read_lock_bh(&ipx_routes_lock);
- for (rt = ipx_routes; rt; rt = rt->ir_next) {
- len += sprintf(buffer + len, "%08lX ",
- (long unsigned int) ntohl(rt->ir_net));
- if (rt->ir_routed) {
- len += sprintf(buffer + len,
- "%08lX %02X%02X%02X%02X%02X%02X\n",
- (long unsigned int) ntohl(rt->ir_intrfc->if_netnum),
- rt->ir_router_node[0], rt->ir_router_node[1],
- rt->ir_router_node[2], rt->ir_router_node[3],
- rt->ir_router_node[4], rt->ir_router_node[5]);
- } else {
- len += sprintf(buffer + len, "%-13s%s\n",
- "Directly", "Connected");
- }
-
- pos = begin + len;
- if (pos < offset) {
- len = 0;
- begin = pos;
- }
-
- if (pos > offset + length)
- break;
- }
- read_unlock_bh(&ipx_routes_lock);
-
- *start = buffer + (offset - begin);
- len -= (offset - begin);
- if (len > length)
- len = length;
-
- return len;
-}
-
/* Handling for system calls applied via the various interfaces to an IPX
* socket object. */
@@ -2516,9 +2273,9 @@ extern void destroy_8023_client(struct datalink_proto *);
static unsigned char ipx_8022_type = 0xE0;
static unsigned char ipx_snap_id[5] = { 0x0, 0x0, 0x0, 0x81, 0x37 };
static char ipx_banner[] __initdata =
- KERN_INFO "NET4: Linux IPX 0.49 for NET4.0\n"
+ KERN_INFO "NET4: Linux IPX 0.50 for NET4.0\n"
KERN_INFO "IPX Portions Copyright (c) 1995 Caldera, Inc.\n" \
- KERN_INFO "IPX Portions Copyright (c) 2000, 2001 Conectiva, Inc.\n";
+ KERN_INFO "IPX Portions Copyright (c) 2000-2002 Conectiva, Inc.\n";
static char ipx_EII_err_msg[] __initdata =
KERN_CRIT "IPX: Unable to register with Ethernet II\n";
static char ipx_8023_err_msg[] __initdata =
@@ -2554,11 +2311,7 @@ static int __init ipx_init(void)
register_netdevice_notifier(&ipx_dev_notifier);
ipx_register_sysctl();
-#ifdef CONFIG_PROC_FS
- proc_net_create("ipx", 0, ipx_get_info);
- proc_net_create("ipx_interface", 0, ipx_interface_get_info);
- proc_net_create("ipx_route", 0, ipx_rt_get_info);
-#endif
+ ipx_proc_init();
printk(ipx_banner);
return 0;
}
@@ -2580,14 +2333,13 @@ module_init(ipx_init);
static void __exit ipx_proto_finito(void)
{
- /* no need to worry about having anything on the ipx_interfaces
- * list, when a interface is created we increment the module
- * usage count, so the module will only be unloaded when there
- * are no more interfaces */
-
- proc_net_remove("ipx_route");
- proc_net_remove("ipx_interface");
- proc_net_remove("ipx");
+ /*
+ * No need to worry about having anything on the ipx_interfaces list,
+ * when a interface is created we increment the module usage count, so
+ * the module will only be unloaded when there are no more interfaces
+ */
+
+ ipx_proc_exit();
ipx_unregister_sysctl();
unregister_netdevice_notifier(&ipx_dev_notifier);
diff --git a/net/ipx/ipx_proc.c b/net/ipx/ipx_proc.c
new file mode 100644
index 000000000000..c96b7b382d0e
--- /dev/null
+++ b/net/ipx/ipx_proc.c
@@ -0,0 +1,388 @@
+/*
+ * IPX proc routines
+ *
+ * Copyright(C) Arnaldo Carvalho de Melo <acme@conectiva.com.br>, 2002
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/spinlock.h>
+#include <linux/seq_file.h>
+#include <linux/tcp.h>
+#include <net/ipx.h>
+
+#ifdef CONFIG_PROC_FS
+static __inline__ struct ipx_interface *ipx_get_interface_idx(loff_t pos)
+{
+ struct ipx_interface *i;
+
+ for (i = ipx_interfaces; pos && i; i = i->if_next)
+ --pos;
+
+ return i;
+}
+
+static void *ipx_seq_interface_start(struct seq_file *seq, loff_t *pos)
+{
+ loff_t l = *pos;
+
+ spin_lock_bh(&ipx_interfaces_lock);
+ return l ? ipx_get_interface_idx(--l) : (void *)1;
+}
+
+static void *ipx_seq_interface_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ struct ipx_interface *i;
+
+ ++*pos;
+ if (v == (void *)1) {
+ i = NULL;
+ if (ipx_interfaces)
+ i = ipx_interfaces;
+ goto out;
+ }
+ i = v;
+ i = i->if_next;
+out:
+ return i;
+}
+
+static void ipx_seq_interface_stop(struct seq_file *seq, void *v)
+{
+ spin_unlock_bh(&ipx_interfaces_lock);
+}
+
+static int ipx_seq_interface_show(struct seq_file *seq, void *v)
+{
+ struct ipx_interface *i;
+
+ if (v == (void *)1) {
+ seq_puts(seq, "Network Node_Address Primary Device "
+ "Frame_Type");
+#ifdef IPX_REFCNT_DEBUG
+ seq_puts(seq, " refcnt");
+#endif
+ seq_puts(seq, "\n");
+ goto out;
+ }
+
+ i = v;
+ seq_printf(seq, "%08lX ", (unsigned long int)ntohl(i->if_netnum));
+ seq_printf(seq, "%02X%02X%02X%02X%02X%02X ",
+ i->if_node[0], i->if_node[1], i->if_node[2],
+ i->if_node[3], i->if_node[4], i->if_node[5]);
+ seq_printf(seq, "%-9s", i == ipx_primary_net ? "Yes" : "No");
+ seq_printf(seq, "%-11s", ipx_device_name(i));
+ seq_printf(seq, "%-9s", ipx_frame_name(i->if_dlink_type));
+#ifdef IPX_REFCNT_DEBUG
+ seq_printf(seq, "%6d", atomic_read(&i->refcnt));
+#endif
+ seq_puts(seq, "\n");
+out:
+ return 0;
+}
+
+static __inline__ struct ipx_route *ipx_get_route_idx(loff_t pos)
+{
+ struct ipx_route *r;
+
+ for (r = ipx_routes; pos && r; r = r->ir_next)
+ --pos;
+
+ return r;
+}
+
+static void *ipx_seq_route_start(struct seq_file *seq, loff_t *pos)
+{
+ loff_t l = *pos;
+ read_lock_bh(&ipx_routes_lock);
+ return l ? ipx_get_route_idx(--l) : (void *)1;
+}
+
+static void *ipx_seq_route_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ struct ipx_route *r;
+
+ ++*pos;
+ if (v == (void *)1) {
+ r = NULL;
+ if (ipx_routes)
+ r = ipx_routes;
+ goto out;
+ }
+ r = v;
+ r = r->ir_next;
+out:
+ return r;
+}
+
+static void ipx_seq_route_stop(struct seq_file *seq, void *v)
+{
+ read_unlock_bh(&ipx_routes_lock);
+}
+
+static int ipx_seq_route_show(struct seq_file *seq, void *v)
+{
+ struct ipx_route *rt;
+
+ if (v == (void *)1) {
+ seq_puts(seq, "Network Router_Net Router_Node\n");
+ goto out;
+ }
+ rt = v;
+ seq_printf(seq, "%08lX ", (unsigned long int)ntohl(rt->ir_net));
+ if (rt->ir_routed)
+ seq_printf(seq, "%08lX %02X%02X%02X%02X%02X%02X\n",
+ (long unsigned int)ntohl(rt->ir_intrfc->if_netnum),
+ rt->ir_router_node[0], rt->ir_router_node[1],
+ rt->ir_router_node[2], rt->ir_router_node[3],
+ rt->ir_router_node[4], rt->ir_router_node[5]);
+ else
+ seq_puts(seq, "Directly Connected\n");
+out:
+ return 0;
+}
+
+static __inline__ struct sock *ipx_get_socket_idx(loff_t pos)
+{
+ struct sock *s = NULL;
+ struct ipx_interface *i;
+
+ for (i = ipx_interfaces; pos && i; i = i->if_next) {
+ spin_lock_bh(&i->if_sklist_lock);
+ for (s = i->if_sklist; pos && s; s = s->next)
+ --pos;
+ if (!pos) {
+ if (!s)
+ spin_unlock_bh(&i->if_sklist_lock);
+ break;
+ }
+ spin_unlock_bh(&i->if_sklist_lock);
+ }
+
+ return s;
+}
+
+static void *ipx_seq_socket_start(struct seq_file *seq, loff_t *pos)
+{
+ loff_t l = *pos;
+
+ spin_lock_bh(&ipx_interfaces_lock);
+ return l ? ipx_get_socket_idx(--l) : (void *)1;
+}
+
+static void *ipx_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ struct sock* sk;
+ struct ipx_interface *i;
+ struct ipx_opt *ipxs;
+
+ ++*pos;
+ if (v == (void *)1) {
+ sk = NULL;
+ if (!ipx_interfaces)
+ goto out;
+ sk = ipx_interfaces->if_sklist;
+ if (sk)
+ spin_lock_bh(&ipx_interfaces->if_sklist_lock);
+ goto out;
+ }
+ sk = v;
+ if (sk->next) {
+ sk = sk->next;
+ goto out;
+ }
+ ipxs = ipx_sk(sk);
+ i = ipxs->intrfc;
+ spin_unlock_bh(&i->if_sklist_lock);
+ sk = NULL;
+ for (;;) {
+ if (!i->if_next)
+ break;
+ i = i->if_next;
+ spin_lock_bh(&i->if_sklist_lock);
+ if (i->if_sklist) {
+ sk = i->if_sklist;
+ break;
+ }
+ spin_unlock_bh(&i->if_sklist_lock);
+ }
+out:
+ return sk;
+}
+
+static int ipx_seq_socket_show(struct seq_file *seq, void *v)
+{
+ struct sock *s;
+ struct ipx_opt *ipxs;
+
+ if (v == (void *)1) {
+#ifdef CONFIG_IPX_INTERN
+ seq_puts(seq, "Local_Address "
+ "Remote_Address Tx_Queue "
+ "Rx_Queue State Uid\n");
+#else
+ seq_puts(seq, "Local_Address Remote_Address "
+ "Tx_Queue Rx_Queue State Uid\n");
+#endif
+ goto out;
+ }
+
+ s = v;
+ ipxs = ipx_sk(s);
+#ifdef CONFIG_IPX_INTERN
+ seq_printf(seq, "%08lX:%02X%02X%02X%02X%02X%02X:%04X ",
+ (unsigned long)htonl(ipxs->intrfc->if_netnum),
+ ipxs->node[0], ipxs->node[1], ipxs->node[2], ipxs->node[3],
+ ipxs->node[4], ipxs->node[5], htons(ipxs->port));
+#else
+ seq_printf(seq, "%08lX:%04X ", (unsigned long) htonl(ipxs->intrfc->if_netnum),
+ htons(ipxs->port));
+#endif /* CONFIG_IPX_INTERN */
+ if (s->state != TCP_ESTABLISHED)
+ seq_printf(seq, "%-28s", "Not_Connected");
+ else {
+ seq_printf(seq, "%08lX:%02X%02X%02X%02X%02X%02X:%04X ",
+ (unsigned long)htonl(ipxs->dest_addr.net),
+ ipxs->dest_addr.node[0], ipxs->dest_addr.node[1],
+ ipxs->dest_addr.node[2], ipxs->dest_addr.node[3],
+ ipxs->dest_addr.node[4], ipxs->dest_addr.node[5],
+ htons(ipxs->dest_addr.sock));
+ }
+
+ seq_printf(seq, "%08X %08X %02X %03d\n",
+ atomic_read(&s->wmem_alloc), atomic_read(&s->rmem_alloc),
+ s->state, SOCK_INODE(s->socket)->i_uid);
+out:
+ return 0;
+}
+
+struct seq_operations ipx_seq_interface_ops = {
+ .start = ipx_seq_interface_start,
+ .next = ipx_seq_interface_next,
+ .stop = ipx_seq_interface_stop,
+ .show = ipx_seq_interface_show,
+};
+
+struct seq_operations ipx_seq_route_ops = {
+ .start = ipx_seq_route_start,
+ .next = ipx_seq_route_next,
+ .stop = ipx_seq_route_stop,
+ .show = ipx_seq_route_show,
+};
+
+struct seq_operations ipx_seq_socket_ops = {
+ .start = ipx_seq_socket_start,
+ .next = ipx_seq_socket_next,
+ .stop = ipx_seq_interface_stop,
+ .show = ipx_seq_socket_show,
+};
+
+static int ipx_seq_route_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &ipx_seq_route_ops);
+}
+
+static int ipx_seq_interface_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &ipx_seq_interface_ops);
+}
+
+static int ipx_seq_socket_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &ipx_seq_socket_ops);
+}
+
+static struct file_operations ipx_seq_interface_fops = {
+ .open = ipx_seq_interface_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static struct file_operations ipx_seq_route_fops = {
+ .open = ipx_seq_route_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static struct file_operations ipx_seq_socket_fops = {
+ .open = ipx_seq_socket_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static int ipx_proc_perms(struct inode* inode, int op)
+{
+ return 0;
+}
+
+static struct inode_operations ipx_seq_inode = {
+ .permission = ipx_proc_perms,
+};
+
+static struct proc_dir_entry *ipx_proc_dir;
+
+int __init ipx_proc_init(void)
+{
+ struct proc_dir_entry *p;
+ int rc = -ENOMEM;
+
+ ipx_proc_dir = proc_mkdir("ipx", proc_net);
+
+ if (!ipx_proc_dir)
+ goto out;
+ p = create_proc_entry("interface", 0, ipx_proc_dir);
+ if (!p)
+ goto out_interface;
+
+ p->proc_fops = &ipx_seq_interface_fops;
+ p->proc_iops = &ipx_seq_inode;
+ p = create_proc_entry("route", 0, ipx_proc_dir);
+ if (!p)
+ goto out_route;
+
+ p->proc_fops = &ipx_seq_route_fops;
+ p->proc_iops = &ipx_seq_inode;
+ p = create_proc_entry("socket", 0, ipx_proc_dir);
+ if (!p)
+ goto out_socket;
+
+ p->proc_fops = &ipx_seq_socket_fops;
+ p->proc_iops = &ipx_seq_inode;
+
+ rc = 0;
+out:
+ return rc;
+out_socket:
+ remove_proc_entry("route", ipx_proc_dir);
+out_route:
+ remove_proc_entry("interface", ipx_proc_dir);
+out_interface:
+ remove_proc_entry("ipx", proc_net);
+ goto out;
+}
+
+void __exit ipx_proc_exit(void)
+{
+ remove_proc_entry("interface", ipx_proc_dir);
+ remove_proc_entry("route", ipx_proc_dir);
+ remove_proc_entry("socket", ipx_proc_dir);
+ remove_proc_entry("ipx", proc_net);
+}
+
+#else /* CONFIG_PROC_FS */
+
+int __init ipx_proc_init(void)
+{
+ return 0;
+}
+
+void __exit ipx_proc_exit(void)
+{
+}
+
+#endif /* CONFIG_PROC_FS */
diff --git a/net/llc/Makefile b/net/llc/Makefile
index 05ae5f67518d..5c9a53fe6988 100644
--- a/net/llc/Makefile
+++ b/net/llc/Makefile
@@ -16,7 +16,7 @@ obj-$(CONFIG_LLC) += llc.o
llc-y := llc_if.o llc_c_ev.o llc_c_ac.o llc_mac.o llc_sap.o llc_s_st.o \
llc_main.o llc_s_ac.o llc_conn.o llc_c_st.o llc_stat.o llc_actn.o \
- llc_s_ev.o llc_evnt.o llc_pdu.o
+ llc_s_ev.o llc_evnt.o llc_pdu.o llc_proc.o
llc-$(CONFIG_LLC_UI) += af_llc.o
llc-objs := $(llc-y)
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index 2144915eee5b..97b99a5575b2 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -22,27 +22,12 @@
*/
#include <linux/config.h>
#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/sockios.h>
-#include <asm/uaccess.h>
-#include <asm/ioctls.h>
-#include <linux/proc_fs.h>
-#include <linux/in.h>
#include <linux/tcp.h>
-#include <linux/netdevice.h>
-#include <linux/inetdevice.h>
-#include <linux/errno.h>
-#include <net/sock.h>
-#include <net/llc_if.h>
#include <net/llc_sap.h>
#include <net/llc_pdu.h>
#include <net/llc_conn.h>
#include <net/llc_mac.h>
#include <net/llc_main.h>
-#include <linux/llc.h>
-#include <linux/if_arp.h>
#include <linux/rtnetlink.h>
#include <linux/init.h>
@@ -1027,94 +1012,6 @@ out:
return rc;
}
-#ifdef CONFIG_PROC_FS
-#define MAC_FORMATTED_SIZE 17
-static void llc_ui_format_mac(char *bf, unsigned char *mac)
-{
- sprintf(bf, "%02X:%02X:%02X:%02X:%02X:%02X",
- mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
-}
-
-/**
- * llc_ui_get_info - return info to procfs
- * @buffer: where to put the formatted output
- * @start: starting from
- * @offset: offset into buffer.
- * @length: size of the buffer
- *
- * Get the output of the local llc ui socket list to the caller.
- * Returns the length of data wrote to buffer.
- */
-static int llc_ui_get_info(char *buffer, char **start, off_t offset, int length)
-{
- off_t pos = 0;
- off_t begin = 0;
- struct llc_sap *sap;
- struct sock *sk;
- struct list_head *sap_entry;
- struct llc_station *station = llc_station_get();
- int len = sprintf(buffer, "SKt Mc local_mac_sap "
- "remote_mac_sap tx_queue rx_queue st uid "
- "link\n");
-
- /* Output the LLC socket data for the /proc filesystem */
- read_lock_bh(&station->sap_list.lock);
- list_for_each(sap_entry, &station->sap_list.list) {
- sap = list_entry(sap_entry, struct llc_sap, node);
-
- read_lock_bh(&sap->sk_list.lock);
- for (sk = sap->sk_list.list; sk; sk = sk->next) {
- struct llc_opt *llc = llc_sk(sk);
-
- len += sprintf(buffer + len, "%2X %2X ", sk->type,
- !llc_mac_null(llc->addr.sllc_mmac));
- if (llc->dev && llc_mac_null(llc->addr.sllc_mmac))
- llc_ui_format_mac(buffer + len,
- llc->dev->dev_addr);
- else {
- if (!llc_mac_null(llc->addr.sllc_mmac))
- llc_ui_format_mac(buffer + len,
- llc->addr.sllc_mmac);
- else
- sprintf(buffer + len,
- "00:00:00:00:00:00");
- }
- len += MAC_FORMATTED_SIZE;
- len += sprintf(buffer + len, "@%02X ", sap->laddr.lsap);
- llc_ui_format_mac(buffer + len, llc->addr.sllc_dmac);
- len += MAC_FORMATTED_SIZE;
- len += sprintf(buffer + len,
- "@%02X %8d %8d %2d %3d ",
- llc->addr.sllc_dsap,
- atomic_read(&sk->wmem_alloc),
- atomic_read(&sk->rmem_alloc),
- sk->state,
- sk->socket ?
- SOCK_INODE(sk->socket)->i_uid : -1);
- len += sprintf(buffer + len, "%4d\n", llc->link);
- /* Are we still dumping unwanted data then discard the record */
- pos = begin + len;
-
- if (pos < offset) {
- len = 0; /* Keep dumping into the buffer start */
- begin = pos;
- }
- if (pos > offset + length) /* We have dumped enough */
- break;
- }
- read_unlock_bh(&sap->sk_list.lock);
- }
- read_unlock_bh(&station->sap_list.lock);
-
- /* The data in question runs from begin to begin + len */
- *start = buffer + offset - begin; /* Start of wanted data */
- len -= offset - begin; /* Remove unwanted header data from length */
- if (len > length)
- len = length; /* Remove unwanted tail data from length */
- return len;
-}
-#endif /* CONFIG_PROC_FS */
-
static struct net_proto_family llc_ui_family_ops = {
.family = PF_LLC,
.create = llc_ui_create,
@@ -1147,13 +1044,11 @@ int __init llc_ui_init(void)
{
llc_ui_sap_last_autoport = LLC_SAP_DYN_START;
sock_register(&llc_ui_family_ops);
- proc_net_create("llc", 0, llc_ui_get_info);
printk(llc_ui_banner);
return 0;
}
void __exit llc_ui_exit(void)
{
- proc_net_remove("llc");
sock_unregister(PF_LLC);
}
diff --git a/net/llc/llc_if.c b/net/llc/llc_if.c
index 1f1d241732a6..ffc0771f69e4 100644
--- a/net/llc/llc_if.c
+++ b/net/llc/llc_if.c
@@ -56,7 +56,7 @@ struct llc_sap *llc_sap_open(u8 lsap, int (*func)(struct sk_buff *skb,
/* allocated a SAP; initialize it and clear out its memory pool */
sap->laddr.lsap = lsap;
sap->rcv_func = func;
- sap->station = llc_station_get();
+ sap->station = &llc_main_station;
/* initialized SAP; add it to list of SAPs this station manages */
llc_sap_save(sap);
out:
diff --git a/net/llc/llc_mac.c b/net/llc/llc_mac.c
index ae97f73a607b..3f53410df740 100644
--- a/net/llc/llc_mac.c
+++ b/net/llc/llc_mac.c
@@ -197,12 +197,11 @@ static void fix_up_incoming_skb(struct sk_buff *skb)
*/
static void llc_station_rcv(struct sk_buff *skb)
{
- struct llc_station *station = llc_station_get();
struct llc_station_state_ev *ev = llc_station_ev(skb);
ev->type = LLC_STATION_EV_TYPE_PDU;
ev->reason = 0;
- llc_station_state_process(station, skb);
+ llc_station_state_process(&llc_main_station, skb);
}
diff --git a/net/llc/llc_main.c b/net/llc/llc_main.c
index f7b54e15882d..ae9477ecd8f1 100644
--- a/net/llc/llc_main.c
+++ b/net/llc/llc_main.c
@@ -3,7 +3,7 @@
* and connections of the LLC.
*
* Copyright (c) 1997 by Procom Technology, Inc.
- * 2001 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ * 2001, 2002 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
*
* This program can be redistributed or modified under the terms of the
* GNU General Public License as published by the Free Software Foundation.
@@ -12,14 +12,9 @@
*
* See the GNU General Public License for more details.
*/
-#include <linux/kernel.h>
-#include <linux/netdevice.h>
-#include <net/sock.h>
-#include <linux/sched.h>
+#include <linux/config.h>
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/proc_fs.h>
-#include <net/llc_if.h>
#include <net/llc_sap.h>
#include <net/llc_conn.h>
#include <net/llc_main.h>
@@ -33,7 +28,7 @@
#include <net/llc_s_ev.h>
#include <net/llc_s_st.h>
#include <net/llc_mac.h>
-#include <linux/llc.h>
+#include <net/llc_proc.h>
/* static function prototypes */
static void llc_station_service_events(struct llc_station *station);
@@ -50,7 +45,7 @@ static struct llc_station_state_trans *
struct sk_buff *skb);
static int llc_rtn_all_conns(struct llc_sap *sap);
-static struct llc_station llc_main_station; /* only one of its kind */
+struct llc_station llc_main_station; /* only one of its kind */
#undef LLC_REFCNT_DEBUG
#ifdef LLC_REFCNT_DEBUG
@@ -340,16 +335,6 @@ static int llc_rtn_all_conns(struct llc_sap *sap)
}
/**
- * llc_station_get - get addr of global station.
- *
- * Returns address of a place to copy the global station to it.
- */
-struct llc_station *llc_station_get(void)
-{
- return &llc_main_station;
-}
-
-/**
* llc_station_state_process: queue event and try to process queue.
* @station: Address of the station
* @skb: Address of the event
@@ -537,80 +522,6 @@ struct sk_buff *llc_alloc_frame(void)
return skb;
}
-static char *llc_conn_state_names[] = {
- [LLC_CONN_STATE_ADM] = "adm",
- [LLC_CONN_STATE_SETUP] = "setup",
- [LLC_CONN_STATE_NORMAL] = "normal",
- [LLC_CONN_STATE_BUSY] = "busy",
- [LLC_CONN_STATE_REJ] = "rej",
- [LLC_CONN_STATE_AWAIT] = "await",
- [LLC_CONN_STATE_AWAIT_BUSY] = "await_busy",
- [LLC_CONN_STATE_AWAIT_REJ] = "await_rej",
- [LLC_CONN_STATE_D_CONN] = "d_conn",
- [LLC_CONN_STATE_RESET] = "reset",
- [LLC_CONN_STATE_ERROR] = "error",
- [LLC_CONN_STATE_TEMP] = "temp",
-};
-
-static int llc_proc_get_info(char *bf, char **start, off_t offset, int length)
-{
- struct list_head *sap_entry;
- struct sock *sk;
- off_t begin = 0, pos = 0;
- int len = 0;
-
- read_lock_bh(&llc_main_station.sap_list.lock);
- list_for_each(sap_entry, &llc_main_station.sap_list.list) {
- struct llc_sap *sap = list_entry(sap_entry, struct llc_sap,
- node);
-
- len += sprintf(bf + len, "lsap=%02X\n", sap->laddr.lsap);
- read_lock_bh(&sap->sk_list.lock);
- if (!sap->sk_list.list) {
- len += sprintf(bf + len, "no connections\n");
- goto unlock;
- }
- len += sprintf(bf + len, "connection list:\n"
- "dsap state retr txw rxw "
- "pf ff sf df rs cs "
- "tack tpfc trs tbs blog busr\n");
- for (sk = sap->sk_list.list; sk; sk = sk->next) {
- struct llc_opt *llc = llc_sk(sk);
-
- len += sprintf(bf + len, " %02X %-10s %3d %3d %3d "
- "%2d %2d %2d "
- "%2d %2d %2d "
- "%4d %4d %3d %3d %4d %4d\n",
- llc->daddr.lsap,
- llc_conn_state_names[llc->state],
- llc->retry_count, llc->k, llc->rw,
- llc->p_flag, llc->f_flag, llc->s_flag,
- llc->data_flag, llc->remote_busy_flag,
- llc->cause_flag,
- timer_pending(&llc->ack_timer.timer),
- timer_pending(&llc->pf_cycle_timer.timer),
- timer_pending(&llc->rej_sent_timer.timer),
- timer_pending(&llc->busy_state_timer.timer),
- !!sk->backlog.tail, sk->lock.users);
- }
-unlock:
- read_unlock_bh(&sap->sk_list.lock);
- pos = begin + len;
- if (pos < offset) {
- len = 0; /* Keep dumping into the buffer start */
- begin = pos;
- }
- if (pos > offset + length) /* We have dumped enough */
- break;
- }
- read_unlock_bh(&llc_main_station.sap_list.lock);
-
- /* The data in question runs from begin to begin + len */
- *start = bf + (offset - begin); /* Start of wanted data */
- len -= (offset - begin); /* Remove unwanted header data from length */
- return len;
-}
-
static struct packet_type llc_packet_type = {
.type = __constant_htons(ETH_P_802_2),
.func = llc_rcv,
@@ -644,9 +555,11 @@ static int __init llc_init(void)
llc_main_station.ack_timer.data = (unsigned long)&llc_main_station;
llc_main_station.ack_timer.function = llc_station_ack_tmr_cb;
+ if (llc_proc_init())
+ goto err;
skb = alloc_skb(0, GFP_ATOMIC);
if (!skb)
- goto err;
+ goto err_skb;
llc_build_offset_table();
ev = llc_station_ev(skb);
memset(ev, 0, sizeof(*ev));
@@ -661,12 +574,13 @@ static int __init llc_init(void)
ev->type = LLC_STATION_EV_TYPE_SIMPLE;
ev->prim_type = LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK;
rc = llc_station_next_state(&llc_main_station, skb);
- proc_net_create("802.2", 0, llc_proc_get_info);
llc_ui_init();
dev_add_pack(&llc_packet_type);
dev_add_pack(&llc_tr_packet_type);
out:
return rc;
+err_skb:
+ llc_proc_exit();
err:
printk(llc_error_msg);
rc = 1;
@@ -676,9 +590,9 @@ err:
static void __exit llc_exit(void)
{
llc_ui_exit();
+ llc_proc_exit();
dev_remove_pack(&llc_packet_type);
dev_remove_pack(&llc_tr_packet_type);
- proc_net_remove("802.2");
}
module_init(llc_init);
diff --git a/net/llc/llc_proc.c b/net/llc/llc_proc.c
new file mode 100644
index 000000000000..d4f1f73f2245
--- /dev/null
+++ b/net/llc/llc_proc.c
@@ -0,0 +1,287 @@
+/*
+ * proc_llc.c - proc interface for LLC
+ *
+ * Copyright (c) 2001 by Jay Schulist <jschlst@samba.org>
+ * 2002 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ *
+ * This program can be redistributed or modified under the terms of the
+ * GNU General Public License as published by the Free Software Foundation.
+ * This program is distributed without any warranty or implied warranty
+ * of merchantability or fitness for a particular purpose.
+ *
+ * See the GNU General Public License for more details.
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/proc_fs.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/seq_file.h>
+#include <net/sock.h>
+#include <net/llc_c_ac.h>
+#include <net/llc_c_ev.h>
+#include <net/llc_c_st.h>
+#include <net/llc_conn.h>
+#include <net/llc_mac.h>
+#include <net/llc_main.h>
+#include <net/llc_sap.h>
+
+#ifdef CONFIG_PROC_FS
+static void llc_ui_format_mac(struct seq_file *seq, unsigned char *mac)
+{
+ seq_printf(seq, "%02X:%02X:%02X:%02X:%02X:%02X",
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+}
+
+static __inline__ struct sock *llc_get_sk_idx(loff_t pos)
+{
+ struct list_head *sap_entry;
+ struct llc_sap *sap;
+ struct sock *sk = NULL;
+
+ list_for_each(sap_entry, &llc_main_station.sap_list.list) {
+ sap = list_entry(sap_entry, struct llc_sap, node);
+
+ read_lock_bh(&sap->sk_list.lock);
+ for (sk = sap->sk_list.list; pos && sk; sk = sk->next)
+ --pos;
+ if (!pos) {
+ if (!sk)
+ read_unlock_bh(&sap->sk_list.lock);
+ break;
+ }
+ read_unlock_bh(&sap->sk_list.lock);
+ }
+ return sk;
+}
+
+static void *llc_seq_start(struct seq_file *seq, loff_t *pos)
+{
+ loff_t l = *pos;
+
+ read_lock_bh(&llc_main_station.sap_list.lock);
+ return l ? llc_get_sk_idx(--l) : (void *)1;
+}
+
+static void *llc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ struct sock* sk;
+ struct llc_opt *llc;
+ struct llc_sap *sap;
+
+ ++*pos;
+ if (v == (void *)1) {
+ if (list_empty(&llc_main_station.sap_list.list)) {
+ sk = NULL;
+ goto out;
+ }
+ sap = list_entry(llc_main_station.sap_list.list.next,
+ struct llc_sap, node);
+
+ read_lock_bh(&sap->sk_list.lock);
+ sk = sap->sk_list.list;
+ goto out;
+ }
+ sk = v;
+ if (sk->next) {
+ sk = sk->next;
+ goto out;
+ }
+ llc = llc_sk(sk);
+ sap = llc->sap;
+ read_unlock_bh(&sap->sk_list.lock);
+ sk = NULL;
+ for (;;) {
+ if (sap->node.next == &llc_main_station.sap_list.list)
+ break;
+ sap = list_entry(sap->node.next, struct llc_sap, node);
+ read_lock_bh(&sap->sk_list.lock);
+ if (sap->sk_list.list) {
+ sk = sap->sk_list.list;
+ break;
+ }
+ read_unlock_bh(&sap->sk_list.lock);
+ }
+out:
+ return sk;
+}
+
+static void llc_seq_stop(struct seq_file *seq, void *v)
+{
+ read_unlock_bh(&llc_main_station.sap_list.lock);
+}
+
+static int llc_seq_socket_show(struct seq_file *seq, void *v)
+{
+ struct sock* sk;
+ struct llc_opt *llc;
+
+ if (v == (void *)1) {
+ seq_puts(seq, "SKt Mc local_mac_sap remote_mac_sap "
+ " tx_queue rx_queue st uid link\n");
+ goto out;
+ }
+ sk = v;
+ llc = llc_sk(sk);
+
+ seq_printf(seq, "%2X %2X ", sk->type,
+ !llc_mac_null(llc->addr.sllc_mmac));
+
+ if (llc->dev && llc_mac_null(llc->addr.sllc_mmac))
+ llc_ui_format_mac(seq, llc->dev->dev_addr);
+ else if (!llc_mac_null(llc->addr.sllc_mmac))
+ llc_ui_format_mac(seq, llc->addr.sllc_mmac);
+ else
+ seq_printf(seq, "00:00:00:00:00:00");
+ seq_printf(seq, "@%02X ", llc->sap->laddr.lsap);
+ llc_ui_format_mac(seq, llc->addr.sllc_dmac);
+ seq_printf(seq, "@%02X %8d %8d %2d %3d %4d\n", llc->addr.sllc_dsap,
+ atomic_read(&sk->wmem_alloc), atomic_read(&sk->rmem_alloc),
+ sk->state, sk->socket ? SOCK_INODE(sk->socket)->i_uid : -1,
+ llc->link);
+out:
+ return 0;
+}
+
+static char *llc_conn_state_names[] = {
+ [LLC_CONN_STATE_ADM] = "adm",
+ [LLC_CONN_STATE_SETUP] = "setup",
+ [LLC_CONN_STATE_NORMAL] = "normal",
+ [LLC_CONN_STATE_BUSY] = "busy",
+ [LLC_CONN_STATE_REJ] = "rej",
+ [LLC_CONN_STATE_AWAIT] = "await",
+ [LLC_CONN_STATE_AWAIT_BUSY] = "await_busy",
+ [LLC_CONN_STATE_AWAIT_REJ] = "await_rej",
+ [LLC_CONN_STATE_D_CONN] = "d_conn",
+ [LLC_CONN_STATE_RESET] = "reset",
+ [LLC_CONN_STATE_ERROR] = "error",
+ [LLC_CONN_STATE_TEMP] = "temp",
+};
+
+static int llc_seq_core_show(struct seq_file *seq, void *v)
+{
+ struct sock* sk;
+ struct llc_opt *llc;
+
+ if (v == (void *)1) {
+ seq_puts(seq, "Connection list:\n"
+ "dsap state retr txw rxw pf ff sf df rs cs "
+ "tack tpfc trs tbs blog busr\n");
+ goto out;
+ }
+ sk = v;
+ llc = llc_sk(sk);
+
+ seq_printf(seq, " %02X %-10s %3d %3d %3d %2d %2d %2d %2d %2d %2d "
+ "%4d %4d %3d %3d %4d %4d\n",
+ llc->daddr.lsap, llc_conn_state_names[llc->state],
+ llc->retry_count, llc->k, llc->rw, llc->p_flag, llc->f_flag,
+ llc->s_flag, llc->data_flag, llc->remote_busy_flag,
+ llc->cause_flag, timer_pending(&llc->ack_timer.timer),
+ timer_pending(&llc->pf_cycle_timer.timer),
+ timer_pending(&llc->rej_sent_timer.timer),
+ timer_pending(&llc->busy_state_timer.timer),
+ !!sk->backlog.tail, sk->lock.users);
+out:
+ return 0;
+}
+
+struct seq_operations llc_seq_socket_ops = {
+ .start = llc_seq_start,
+ .next = llc_seq_next,
+ .stop = llc_seq_stop,
+ .show = llc_seq_socket_show,
+};
+
+struct seq_operations llc_seq_core_ops = {
+ .start = llc_seq_start,
+ .next = llc_seq_next,
+ .stop = llc_seq_stop,
+ .show = llc_seq_core_show,
+};
+
+static int llc_seq_socket_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &llc_seq_socket_ops);
+}
+
+static int llc_seq_core_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &llc_seq_core_ops);
+}
+
+static int llc_proc_perms(struct inode* inode, int op)
+{
+ return 0;
+}
+
+static struct file_operations llc_seq_socket_fops = {
+ .open = llc_seq_socket_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static struct file_operations llc_seq_core_fops = {
+ .open = llc_seq_core_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static struct inode_operations llc_seq_inode = {
+ .permission = llc_proc_perms,
+};
+
+static struct proc_dir_entry *llc_proc_dir;
+
+int __init llc_proc_init(void)
+{
+ int rc = -ENOMEM;
+ struct proc_dir_entry *p;
+
+ llc_proc_dir = proc_mkdir("llc", proc_net);
+ if (!llc_proc_dir)
+ goto out;
+
+ p = create_proc_entry("socket", 0, llc_proc_dir);
+ if (!p)
+ goto out_socket;
+
+ p->proc_fops = &llc_seq_socket_fops;
+ p->proc_iops = &llc_seq_inode;
+
+ p = create_proc_entry("core", 0, llc_proc_dir);
+ if (!p)
+ goto out_core;
+
+ p->proc_fops = &llc_seq_core_fops;
+ p->proc_iops = &llc_seq_inode;
+
+ rc = 0;
+out:
+ return rc;
+out_core:
+ remove_proc_entry("socket", llc_proc_dir);
+out_socket:
+ remove_proc_entry("llc", proc_net);
+ goto out;
+}
+
+void __exit llc_proc_exit(void)
+{
+ remove_proc_entry("socket", llc_proc_dir);
+ remove_proc_entry("core", llc_proc_dir);
+ remove_proc_entry("llc", proc_net);
+}
+#else /* CONFIG_PROC_FS */
+int __init llc_proc_init(void)
+{
+ return 0;
+}
+
+void __exit llc_proc_exit(void)
+{
+}
+#endif /* CONFIG_PROC_FS */
diff --git a/net/netsyms.c b/net/netsyms.c
index 463f6749b027..1a77dc66baa6 100644
--- a/net/netsyms.c
+++ b/net/netsyms.c
@@ -587,7 +587,6 @@ EXPORT_SYMBOL(ip_route_me_harder);
EXPORT_SYMBOL(register_gifconf);
-EXPORT_SYMBOL(net_call_rx_atomic);
EXPORT_SYMBOL(softnet_data);
#if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO)
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index fbf86ac9a2d2..f4bbf7a2596a 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -15,9 +15,11 @@
* helped a lot to locate nasty class stall bug
* Andi Kleen, Jamal Hadi, Bert Hubert
* code review and helpful comments on shaping
+ * Tomasz Wrona, <tw@eter.tym.pl>
+ * created test case so that I was able to fix nasty bug
* and many others. thanks.
*
- * $Id: sch_htb.c,v 1.13 2002/05/25 09:04:50 devik Exp $
+ * $Id: sch_htb.c,v 1.14 2002/09/28 12:55:22 devik Exp devik $
*/
#include <linux/config.h>
#include <linux/module.h>
@@ -69,7 +71,7 @@
#define HTB_HYSTERESIS 1/* whether to use mode hysteresis for speedup */
#define HTB_QLOCK(S) spin_lock_bh(&(S)->dev->queue_lock)
#define HTB_QUNLOCK(S) spin_unlock_bh(&(S)->dev->queue_lock)
-#define HTB_VER 0x30006 /* major must be matched with number suplied by TC as version */
+#define HTB_VER 0x30007 /* major must be matched with number suplied by TC as version */
#if HTB_VER >> 16 != TC_HTB_PROTOVER
#error "Mismatched sch_htb.c and pkt_sch.h"
@@ -1496,19 +1498,23 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
#endif
} else sch_tree_lock(sch);
- cl->un.leaf.quantum = rtab->rate.rate / q->rate2quantum;
- if (!hopt->quantum && cl->un.leaf.quantum < 1000) {
- printk(KERN_WARNING "HTB: quantum of class %X is small. Consider r2q change.", cl->classid);
- cl->un.leaf.quantum = 1000;
- }
- if (!hopt->quantum && cl->un.leaf.quantum > 200000) {
- printk(KERN_WARNING "HTB: quantum of class %X is big. Consider r2q change.", cl->classid);
- cl->un.leaf.quantum = 200000;
+ /* it used to be a nasty bug here, we have to check that node
+ is really leaf before changing cl->un.leaf ! */
+ if (!cl->level) {
+ cl->un.leaf.quantum = rtab->rate.rate / q->rate2quantum;
+ if (!hopt->quantum && cl->un.leaf.quantum < 1000) {
+ printk(KERN_WARNING "HTB: quantum of class %X is small. Consider r2q change.", cl->classid);
+ cl->un.leaf.quantum = 1000;
+ }
+ if (!hopt->quantum && cl->un.leaf.quantum > 200000) {
+ printk(KERN_WARNING "HTB: quantum of class %X is big. Consider r2q change.", cl->classid);
+ cl->un.leaf.quantum = 200000;
+ }
+ if (hopt->quantum)
+ cl->un.leaf.quantum = hopt->quantum;
+ if ((cl->un.leaf.prio = hopt->prio) >= TC_HTB_NUMPRIO)
+ cl->un.leaf.prio = TC_HTB_NUMPRIO - 1;
}
- if (hopt->quantum)
- cl->un.leaf.quantum = hopt->quantum;
- if ((cl->un.leaf.prio = hopt->prio) >= TC_HTB_NUMPRIO)
- cl->un.leaf.prio = TC_HTB_NUMPRIO - 1;
cl->buffer = hopt->buffer;
cl->cbuffer = hopt->cbuffer;
diff --git a/net/sctp/debug.c b/net/sctp/debug.c
index 18f68d7b1dc5..bca2c110aa7e 100644
--- a/net/sctp/debug.c
+++ b/net/sctp/debug.c
@@ -97,7 +97,7 @@ const char *sctp_cname(const sctp_subtype_t cid)
/* These are printable form of variable-length parameters. */
const char *sctp_param_tbl[SCTP_PARAM_ECN_CAPABLE + 1] = {
"",
- "PARAM_HEATBEAT_INFO",
+ "PARAM_HEARTBEAT_INFO",
"",
"",
"",
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c
index cba2bd621984..94ebe7f08b53 100644
--- a/net/sctp/outqueue.c
+++ b/net/sctp/outqueue.c
@@ -104,7 +104,7 @@ void sctp_outqueue_init(sctp_association_t *asoc, sctp_outqueue_t *q)
void sctp_outqueue_teardown(sctp_outqueue_t *q)
{
sctp_transport_t *transport;
- struct list_head *lchunk, *pos;
+ struct list_head *lchunk, *pos, *temp;
sctp_chunk_t *chunk;
/* Throw away unacknowledged chunks. */
@@ -117,6 +117,13 @@ void sctp_outqueue_teardown(sctp_outqueue_t *q)
}
}
+ /* Throw away chunks that have been gap ACKed. */
+ list_for_each_safe(lchunk, temp, &q->sacked) {
+ list_del(lchunk);
+ chunk = list_entry(lchunk, sctp_chunk_t, transmitted_list);
+ sctp_free_chunk(chunk);
+ }
+
/* Throw away any leftover chunks. */
while ((chunk = (sctp_chunk_t *) skb_dequeue(&q->out)))
sctp_free_chunk(chunk);
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index d798822e9730..74c795b964f5 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -223,7 +223,7 @@ nodata:
sctp_chunk_t *sctp_make_init_ack(const sctp_association_t *asoc,
const sctp_chunk_t *chunk,
- int priority)
+ int priority, int unkparam_len)
{
sctp_inithdr_t initack;
sctp_chunk_t *retval;
@@ -278,7 +278,10 @@ sctp_chunk_t *sctp_make_init_ack(const sctp_association_t *asoc,
if (!cookie)
goto nomem_cookie;
- chunksize = sizeof(initack) + addrs_len + cookie_len;
+ /* Calculate the total size of allocation, include the reserved
+ * space for reporting unknown parameters if it is specified.
+ */
+ chunksize = sizeof(initack) + addrs_len + cookie_len + unkparam_len;
/* Tell peer that we'll do ECN only if peer advertised such cap. */
if (asoc->peer.ecn_capable)
@@ -883,25 +886,27 @@ nodata:
return retval;
}
-/* Create an Operation Error chunk. */
-sctp_chunk_t *sctp_make_op_error(const sctp_association_t *asoc,
- const sctp_chunk_t *chunk,
- __u16 cause_code, const void *payload,
- size_t paylen)
+/* Create an Operation Error chunk with the specified space reserved.
+ * This routine can be used for containing multiple causes in the chunk.
+ */
+sctp_chunk_t *sctp_make_op_error_space(const sctp_association_t *asoc,
+ const sctp_chunk_t *chunk,
+ size_t size)
{
- sctp_chunk_t *retval = sctp_make_chunk(asoc, SCTP_CID_ERROR, 0,
- sizeof(sctp_errhdr_t) + paylen);
+ sctp_chunk_t *retval;
+ retval = sctp_make_chunk(asoc, SCTP_CID_ERROR, 0,
+ sizeof(sctp_errhdr_t) + size);
if (!retval)
goto nodata;
- sctp_init_cause(retval, cause_code, payload, paylen);
- /* RFC 2960 6.4 Multi-homed SCTP Endpoints
+ /* RFC 2960 6.4 Multi-homed SCTP Endpoints
*
* An endpoint SHOULD transmit reply chunks (e.g., SACK,
- * HEARTBEAT ACK, * etc.) to the same destination transport
- * address from which it * received the DATA or control chunk
+ * HEARTBEAT ACK, etc.) to the same destination transport
+ * address from which it received the DATA or control chunk
* to which it is replying.
+ *
*/
if (chunk)
retval->transport = chunk->transport;
@@ -910,6 +915,23 @@ nodata:
return retval;
}
+/* Create an Operation Error chunk. */
+sctp_chunk_t *sctp_make_op_error(const sctp_association_t *asoc,
+ const sctp_chunk_t *chunk,
+ __u16 cause_code, const void *payload,
+ size_t paylen)
+{
+ sctp_chunk_t *retval = sctp_make_op_error_space(asoc, chunk, paylen);
+
+ if (!retval)
+ goto nodata;
+
+ sctp_init_cause(retval, cause_code, payload, paylen);
+
+nodata:
+ return retval;
+}
+
/********************************************************************
* 2nd Level Abstractions
********************************************************************/
@@ -1405,6 +1427,162 @@ malformed:
* 3rd Level Abstractions
********************************************************************/
+/* Verify the INIT packet before we process it. */
+int sctp_verify_init(const sctp_association_t *asoc,
+ sctp_cid_t cid,
+ sctp_init_chunk_t *peer_init,
+ sctp_chunk_t *chunk,
+ sctp_chunk_t **err_chk_p)
+{
+ sctpParam_t param;
+ uint8_t *end;
+
+ /* FIXME - Verify the fixed fields of the INIT chunk. Also, verify
+ * the mandatory parameters somewhere here and generate either the
+ * "Missing mandatory parameter" error or the "Invalid mandatory
+ * parameter" error. */
+
+ /* Find unrecognized parameters. */
+
+ end = ((uint8_t *)peer_init + ntohs(peer_init->chunk_hdr.length));
+
+ for (param.v = peer_init->init_hdr.params;
+ param.v < end;
+ param.v += WORD_ROUND(ntohs(param.p->length))) {
+
+ if (!sctp_verify_param(asoc, param, cid, chunk, err_chk_p))
+ return 0;
+
+ } /* for (loop through all parameters) */
+
+ return 1;
+}
+
+
+/* Find unrecognized parameters in the chunk.
+ * Return values:
+ * 0 - discard the chunk
+ * 1 - continue with the chunk
+ */
+int sctp_verify_param(const sctp_association_t *asoc,
+ sctpParam_t param,
+ sctp_cid_t cid,
+ sctp_chunk_t *chunk,
+ sctp_chunk_t **err_chk_p)
+{
+ int retval = 1;
+
+ /* FIXME - This routine is not looking at each parameter per the
+ * chunk type, i.e., unrecognized parameters should be further
+ * identified based on the chunk id.
+ */
+
+ switch (param.p->type) {
+ case SCTP_PARAM_IPV4_ADDRESS:
+ case SCTP_PARAM_IPV6_ADDRESS:
+ case SCTP_PARAM_COOKIE_PRESERVATIVE:
+ /* FIXME - If we don't support the host name parameter, we should
+ * generate an error for this - Unresolvable address.
+ */
+ case SCTP_PARAM_HOST_NAME_ADDRESS:
+ case SCTP_PARAM_SUPPORTED_ADDRESS_TYPES:
+ case SCTP_PARAM_STATE_COOKIE:
+ case SCTP_PARAM_HEARTBEAT_INFO:
+ case SCTP_PARAM_UNRECOGNIZED_PARAMETERS:
+ case SCTP_PARAM_ECN_CAPABLE:
+ break;
+ default:
+ SCTP_DEBUG_PRINTK("Unrecognized param: %d for chunk %d.\n",
+ ntohs(param.p->type), cid);
+ return sctp_process_unk_param(asoc, param, chunk, err_chk_p);
+
+ break;
+ }
+ return retval;
+}
+
+/* RFC 3.2.1 & the Implementers Guide 2.2.
+ *
+ * The Parameter Types are encoded such that the
+ * highest-order two bits specify the action that must be
+ * taken if the processing endpoint does not recognize the
+ * Parameter Type.
+ *
+ * 00 - Stop processing this SCTP chunk and discard it,
+ * do not process any further chunks within it.
+ *
+ * 01 - Stop processing this SCTP chunk and discard it,
+ * do not process any further chunks within it, and report
+ * the unrecognized parameter in an 'Unrecognized
+ * Parameter Type' (in either an ERROR or in the INIT ACK).
+ *
+ * 10 - Skip this parameter and continue processing.
+ *
+ * 11 - Skip this parameter and continue processing but
+ * report the unrecognized parameter in an
+ * 'Unrecognized Parameter Type' (in either an ERROR or in
+ * the INIT ACK).
+ *
+ * Return value:
+ * 0 - discard the chunk
+ * 1 - continue with the chunk
+ */
+int sctp_process_unk_param(const sctp_association_t *asoc,
+ sctpParam_t param,
+ sctp_chunk_t *chunk,
+ sctp_chunk_t **err_chk_p)
+{
+ int retval = 1;
+
+ switch (param.p->type & SCTP_PARAM_ACTION_MASK) {
+ case SCTP_PARAM_ACTION_DISCARD:
+ retval = 0;
+ break;
+ case SCTP_PARAM_ACTION_DISCARD_ERR:
+ retval = 0;
+ /* Make an ERROR chunk, preparing enough room for
+ * returning multiple unknown parameters.
+ */
+ if (NULL == *err_chk_p)
+ *err_chk_p = sctp_make_op_error_space(asoc, chunk,
+ ntohs(chunk->chunk_hdr->length));
+
+ if (*err_chk_p)
+ sctp_init_cause(*err_chk_p, SCTP_ERROR_UNKNOWN_PARAM,
+ (const void *)param.p,
+ WORD_ROUND(ntohs(param.p->length)));
+
+ break;
+ case SCTP_PARAM_ACTION_SKIP:
+ break;
+ case SCTP_PARAM_ACTION_SKIP_ERR:
+ /* Make an ERROR chunk, preparing enough room for
+ * returning multiple unknown parameters.
+ */
+ if (NULL == *err_chk_p)
+ *err_chk_p = sctp_make_op_error_space(asoc, chunk,
+ ntohs(chunk->chunk_hdr->length));
+
+ if (*err_chk_p) {
+ sctp_init_cause(*err_chk_p, SCTP_ERROR_UNKNOWN_PARAM,
+ (const void *)param.p,
+ WORD_ROUND(ntohs(param.p->length)));
+ } else {
+ /* If there is no memory for generating the ERROR
+ * report as specified, an ABORT will be triggered
+ * to the peer and the association won't be established.
+ */
+ retval = 0;
+ }
+
+ break;
+ default:
+ break;
+ }
+
+ return retval;
+}
+
/* Unpack the parameters in an INIT packet.
* FIXME: There is no return status to allow callers to do
* error handling.
@@ -1609,9 +1787,9 @@ int sctp_process_param(sctp_association_t *asoc, sctpParam_t param,
asoc->peer.cookie = param.cookie->body;
break;
- case SCTP_PARAM_HEATBEAT_INFO:
+ case SCTP_PARAM_HEARTBEAT_INFO:
SCTP_DEBUG_PRINTK("unimplemented "
- "SCTP_PARAM_HEATBEAT_INFO\n");
+ "SCTP_PARAM_HEARTBEAT_INFO\n");
break;
case SCTP_PARAM_UNRECOGNIZED_PARAMETERS:
@@ -1624,14 +1802,13 @@ int sctp_process_param(sctp_association_t *asoc, sctpParam_t param,
break;
default:
+ /* Any unrecognized parameters should have been caught
+ * and handled by sctp_verify_param() which should be
+ * called prior to this routine. Simply log the error
+ * here.
+ */
SCTP_DEBUG_PRINTK("Ignoring param: %d for association %p.\n",
ntohs(param.p->type), asoc);
- /* FIXME: The entire parameter processing really needs
- * redesigned. For now, always return success as doing
- * otherwise craters the system.
- */
- retval = 1;
-
break;
};
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 457e669aa17b..f6c217fb68a6 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -327,7 +327,8 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
case SCTP_CMD_GEN_INIT_ACK:
/* Generate an INIT ACK chunk. */
- new_obj = sctp_make_init_ack(asoc, chunk, GFP_ATOMIC);
+ new_obj = sctp_make_init_ack(asoc, chunk, GFP_ATOMIC,
+ 0);
if (!new_obj)
goto nomem;
@@ -344,10 +345,20 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
case SCTP_CMD_GEN_COOKIE_ECHO:
/* Generate a COOKIE ECHO chunk. */
new_obj = sctp_make_cookie_echo(asoc, chunk);
- if (!new_obj)
+ if (!new_obj) {
+ if (command->obj.ptr)
+ sctp_free_chunk(command->obj.ptr);
goto nomem;
+ }
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
SCTP_CHUNK(new_obj));
+
+ /* If there is an ERROR chunk to be sent along with
+ * the COOKIE_ECHO, send it, too.
+ */
+ if (command->obj.ptr)
+ sctp_add_cmd_sf(commands, SCTP_CMD_REPLY,
+ SCTP_CHUNK(command->obj.ptr));
break;
case SCTP_CMD_GEN_SHUTDOWN:
@@ -397,8 +408,7 @@ int sctp_cmd_interpreter(sctp_event_t event_type, sctp_subtype_t subtype,
/* Send a full packet to our peer. */
packet = command->obj.ptr;
sctp_packet_transmit(packet);
- sctp_transport_free(packet->transport);
- sctp_packet_free(packet);
+ sctp_ootb_pkt_free(packet);
break;
case SCTP_CMD_RETRAN:
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index 6226b68336e9..dd5d1ab51120 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -194,6 +194,10 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const sctp_endpoint_t *ep,
sctp_chunk_t *chunk = arg;
sctp_chunk_t *repl;
sctp_association_t *new_asoc;
+ sctp_chunk_t *err_chunk;
+ sctp_packet_t *packet;
+ sctp_unrecognized_param_t *unk_param;
+ int len;
/* If the packet is an OOTB packet which is temporarily on the
* control endpoint, responding with an ABORT.
@@ -208,6 +212,36 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const sctp_endpoint_t *ep,
if (!chunk->singleton)
return SCTP_DISPOSITION_VIOLATION;
+ /* Verify the INIT chunk before processing it. */
+ err_chunk = NULL;
+ if (!sctp_verify_init(asoc, chunk->chunk_hdr->type,
+ (sctp_init_chunk_t *)chunk->chunk_hdr, chunk,
+ &err_chunk)) {
+ /* This chunk contains fatal error. It is to be discarded.
+ * Send an ABORT, with causes if there is any.
+ */
+ if (err_chunk) {
+ packet = sctp_abort_pkt_new(ep, asoc, arg,
+ (__u8 *)(err_chunk->chunk_hdr) +
+ sizeof(sctp_chunkhdr_t),
+ ntohs(err_chunk->chunk_hdr->length) -
+ sizeof(sctp_chunkhdr_t));
+
+ sctp_free_chunk(err_chunk);
+
+ if (packet) {
+ sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
+ SCTP_PACKET(packet));
+ return SCTP_DISPOSITION_CONSUME;
+ } else {
+ return SCTP_DISPOSITION_NOMEM;
+ }
+ } else {
+ return sctp_sf_tabort_8_4_8(ep, asoc, type, arg,
+ commands);
+ }
+ }
+
/* Grab the INIT header. */
chunk->subh.init_hdr = (sctp_inithdr_t *)chunk->skb->data;
@@ -230,10 +264,41 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const sctp_endpoint_t *ep,
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));
/* B) "Z" shall respond immediately with an INIT ACK chunk. */
- repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC);
+
+ /* If there are errors need to be reported for unknown parameters,
+ * make sure to reserve enough room in the INIT ACK for them.
+ */
+ len = 0;
+ if (err_chunk)
+ len = ntohs(err_chunk->chunk_hdr->length) -
+ sizeof(sctp_chunkhdr_t);
+
+ repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len);
if (!repl)
goto nomem_ack;
+ /* If there are errors need to be reported for unknown parameters,
+ * include them in the outgoing INIT ACK as "Unrecognized parameter"
+ * parameter.
+ */
+ if (err_chunk) {
+ /* Get the "Unrecognized parameter" parameter(s) out of the
+ * ERROR chunk generated by sctp_verify_init(). Since the
+ * error cause code for "unknown parameter" and the
+ * "Unrecognized parameter" type is the same, we can
+ * construct the parameters in INIT ACK by copying the
+ * ERROR causes over.
+ */
+ unk_param = (sctp_unrecognized_param_t *)
+ ((__u8 *)(err_chunk->chunk_hdr) +
+ sizeof(sctp_chunkhdr_t));
+ /* Replace the cause code with the "Unrecognized parameter"
+ * parameter type.
+ */
+ sctp_addto_chunk(repl, len, unk_param);
+ sctp_free_chunk(err_chunk);
+ }
+
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
/*
@@ -248,6 +313,9 @@ sctp_disposition_t sctp_sf_do_5_1B_init(const sctp_endpoint_t *ep,
nomem_ack:
sctp_association_free(new_asoc);
+ if (err_chunk)
+ sctp_free_chunk(err_chunk);
+
nomem:
return SCTP_DISPOSITION_NOMEM;
}
@@ -289,6 +357,10 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const sctp_endpoint_t *ep,
sctp_chunk_t *chunk = arg;
sctp_init_chunk_t *initchunk;
__u32 init_tag;
+ sctp_chunk_t *err_chunk;
+ sctp_packet_t *packet;
+ sctp_disposition_t ret;
+
/* 6.10 Bundling
* An endpoint MUST NOT bundle INIT, INIT ACK or
@@ -319,6 +391,49 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const sctp_endpoint_t *ep,
return SCTP_DISPOSITION_DELETE_TCB;
}
+ /* Verify the INIT chunk before processing it. */
+ err_chunk = NULL;
+ if (!sctp_verify_init(asoc, chunk->chunk_hdr->type,
+ (sctp_init_chunk_t *)chunk->chunk_hdr, chunk,
+ &err_chunk)) {
+ /* This chunk contains fatal error. It is to be discarded.
+ * Send an ABORT, with causes if there is any.
+ */
+ if (err_chunk) {
+ packet = sctp_abort_pkt_new(ep, asoc, arg,
+ (__u8 *)(err_chunk->chunk_hdr) +
+ sizeof(sctp_chunkhdr_t),
+ ntohs(err_chunk->chunk_hdr->length) -
+ sizeof(sctp_chunkhdr_t));
+
+ sctp_free_chunk(err_chunk);
+
+ if (packet) {
+ sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
+ SCTP_PACKET(packet));
+ sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
+ SCTP_STATE(SCTP_STATE_CLOSED));
+ sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB,
+ SCTP_NULL());
+ return SCTP_DISPOSITION_CONSUME;
+ } else {
+ sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
+ SCTP_STATE(SCTP_STATE_CLOSED));
+ sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB,
+ SCTP_NULL());
+ return SCTP_DISPOSITION_NOMEM;
+ }
+ } else {
+ ret = sctp_sf_tabort_8_4_8(ep, asoc, type, arg,
+ commands);
+ sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE,
+ SCTP_STATE(SCTP_STATE_CLOSED));
+ sctp_add_cmd_sf(commands, SCTP_CMD_DELETE_TCB,
+ SCTP_NULL());
+ return ret;
+ }
+ }
+
/* Tag the variable length paramters. Note that we never
* convert the parameters in an INIT chunk.
*/
@@ -345,7 +460,12 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(const sctp_endpoint_t *ep,
/* 5.1 C) "A" shall then send the State Cookie received in the
* INIT ACK chunk in a COOKIE ECHO chunk, ...
*/
- sctp_add_cmd_sf(commands, SCTP_CMD_GEN_COOKIE_ECHO, SCTP_NULL());
+ /* If there is any errors to report, send the ERROR chunk generated
+ * for unknown parameters as well.
+ */
+ sctp_add_cmd_sf(commands, SCTP_CMD_GEN_COOKIE_ECHO,
+ SCTP_CHUNK(err_chunk));
+
return SCTP_DISPOSITION_CONSUME;
nomem:
@@ -579,7 +699,7 @@ sctp_disposition_t sctp_sf_sendbeat_8_3(const sctp_endpoint_t *ep,
* HEARTBEAT is sent (see Section 8.3).
*/
- hbinfo.param_hdr.type = SCTP_PARAM_HEATBEAT_INFO;
+ hbinfo.param_hdr.type = SCTP_PARAM_HEARTBEAT_INFO;
hbinfo.param_hdr.length = htons(sizeof(sctp_sender_hb_info_t));
hbinfo.daddr = transport->ipaddr;
hbinfo.sent_at = jiffies;
@@ -852,6 +972,11 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
sctp_chunk_t *chunk = arg;
sctp_chunk_t *repl;
sctp_association_t *new_asoc;
+ sctp_chunk_t *err_chunk;
+ sctp_packet_t *packet;
+ sctp_unrecognized_param_t *unk_param;
+ int len;
+
/* 6.10 Bundling
* An endpoint MUST NOT bundle INIT, INIT ACK or
@@ -866,6 +991,36 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
/* Tag the variable length parameters. */
chunk->param_hdr.v = skb_pull(chunk->skb, sizeof(sctp_inithdr_t));
+ /* Verify the INIT chunk before processing it. */
+ err_chunk = NULL;
+ if (!sctp_verify_init(asoc, chunk->chunk_hdr->type,
+ (sctp_init_chunk_t *)chunk->chunk_hdr, chunk,
+ &err_chunk)) {
+ /* This chunk contains fatal error. It is to be discarded.
+ * Send an ABORT, with causes if there is any.
+ */
+ if (err_chunk) {
+ packet = sctp_abort_pkt_new(ep, asoc, arg,
+ (__u8 *)(err_chunk->chunk_hdr) +
+ sizeof(sctp_chunkhdr_t),
+ ntohs(err_chunk->chunk_hdr->length) -
+ sizeof(sctp_chunkhdr_t));
+
+ sctp_free_chunk(err_chunk);
+
+ if (packet) {
+ sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
+ SCTP_PACKET(packet));
+ return SCTP_DISPOSITION_CONSUME;
+ } else {
+ return SCTP_DISPOSITION_NOMEM;
+ }
+ } else {
+ return sctp_sf_tabort_8_4_8(ep, asoc, type, arg,
+ commands);
+ }
+ }
+
/*
* Other parameters for the endpoint SHOULD be copied from the
* existing parameters of the association (e.g. number of
@@ -887,10 +1042,41 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
sctp_tietags_populate(new_asoc, asoc);
/* B) "Z" shall respond immediately with an INIT ACK chunk. */
- repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC);
+
+ /* If there are errors need to be reported for unknown parameters,
+ * make sure to reserve enough room in the INIT ACK for them.
+ */
+ len = 0;
+ if (err_chunk) {
+ len = ntohs(err_chunk->chunk_hdr->length) -
+ sizeof(sctp_chunkhdr_t);
+ }
+ repl = sctp_make_init_ack(new_asoc, chunk, GFP_ATOMIC, len);
if (!repl)
goto nomem;
+ /* If there are errors need to be reported for unknown parameters,
+ * include them in the outgoing INIT ACK as "Unrecognized parameter"
+ * parameter.
+ */
+ if (err_chunk) {
+ /* Get the "Unrecognized parameter" parameter(s) out of the
+ * ERROR chunk generated by sctp_verify_init(). Since the
+ * error cause code for "unknown parameter" and the
+ * "Unrecognized parameter" type is the same, we can
+ * construct the parameters in INIT ACK by copying the
+ * ERROR causes over.
+ */
+ unk_param = (sctp_unrecognized_param_t *)
+ ((__u8 *)(err_chunk->chunk_hdr) +
+ sizeof(sctp_chunkhdr_t));
+ /* Replace the cause code with the "Unrecognized parameter"
+ * parameter type.
+ */
+ sctp_addto_chunk(repl, len, unk_param);
+ sctp_free_chunk(err_chunk);
+ }
+
sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(new_asoc));
sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl));
@@ -903,6 +1089,9 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
return SCTP_DISPOSITION_CONSUME;
nomem:
+ if (err_chunk)
+ sctp_free_chunk(err_chunk);
+
return SCTP_DISPOSITION_NOMEM;
}
@@ -1948,17 +2137,16 @@ sctp_disposition_t sctp_sf_eat_data_6_2(const sctp_endpoint_t *ep,
/* This is a new TSN. */
- /* If we don't have any room in our receive window, discard.
- * Actually, allow a little bit of overflow (up to a MTU of
- * of overflow).
+ /* Discard if there is no room in the receive window.
+ * Actually, allow a little bit of overflow (up to a MTU).
*/
datalen = ntohs(chunk->chunk_hdr->length);
datalen -= sizeof(sctp_data_chunk_t);
- if (!asoc->rwnd || (datalen > asoc->frag_point)) {
+ if (asoc->rwnd_over || (datalen > asoc->rwnd + asoc->frag_point)) {
SCTP_DEBUG_PRINTK("Discarding tsn: %u datalen: %Zd, "
"rwnd: %d\n", tsn, datalen, asoc->rwnd);
- goto discard_noforce;
+ goto discard_force;
}
/*
@@ -2330,59 +2518,32 @@ sctp_disposition_t sctp_sf_tabort_8_4_8(const sctp_endpoint_t *ep,
sctp_cmd_seq_t *commands)
{
sctp_packet_t *packet = NULL;
- sctp_transport_t *transport = NULL;
sctp_chunk_t *chunk = arg;
sctp_chunk_t *abort;
- __u16 sport;
- __u16 dport;
- __u32 vtag;
-
- /* Grub in chunk and endpoint for kewl bitz. */
- sport = ntohs(chunk->sctp_hdr->dest);
- dport = ntohs(chunk->sctp_hdr->source);
- /* -- Make sure the ABORT packet's V-tag is the same as the
- * inbound packet if no association exists, otherwise use
- * the peer's vtag.
- */
- if (asoc)
- vtag = asoc->peer.i.init_tag;
- else
- vtag = ntohl(chunk->sctp_hdr->vtag);
- /* Make a transport for the bucket, Eliza... */
- transport = sctp_transport_new(sctp_source(chunk), GFP_ATOMIC);
- if (!transport)
- goto nomem;
+ packet = sctp_ootb_pkt_new(asoc, chunk);
- /* Make a packet for the ABORT to go into. */
- packet = t_new(sctp_packet_t, GFP_ATOMIC);
- if (!packet)
- goto nomem_packet;
-
- packet = sctp_packet_init(packet, transport, sport, dport);
- packet = sctp_packet_config(packet, vtag, 0, NULL);
+ if (packet) {
+ /* Make an ABORT. The T bit will be set if the asoc
+ * is NULL.
+ */
+ abort = sctp_make_abort(asoc, chunk, 0);
+ if (!abort) {
+ sctp_ootb_pkt_free(packet);
+ return SCTP_DISPOSITION_NOMEM;
+ }
- /* Make an ABORT.
- * This will set the T bit since we have no association.
- */
- abort = sctp_make_abort(NULL, chunk, 0);
- if (!abort)
- goto nomem_chunk;
+ /* Set the skb to the belonging sock for accounting. */
+ abort->skb->sk = ep->base.sk;
- /* Set the skb to the belonging sock for accounting. */
- abort->skb->sk = ep->base.sk;
+ sctp_packet_append_chunk(packet, abort);
- sctp_packet_append_chunk(packet, abort);
- sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT, SCTP_PACKET(packet));
- return SCTP_DISPOSITION_DISCARD;
+ sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
+ SCTP_PACKET(packet));
-nomem_chunk:
- sctp_packet_free(packet);
-
-nomem_packet:
- sctp_transport_free(transport);
+ return SCTP_DISPOSITION_CONSUME;
+ }
-nomem:
return SCTP_DISPOSITION_NOMEM;
}
@@ -2560,60 +2721,35 @@ sctp_disposition_t sctp_sf_shut_8_4_5(const sctp_endpoint_t *ep,
sctp_cmd_seq_t *commands)
{
sctp_packet_t *packet = NULL;
- sctp_transport_t *transport = NULL;
sctp_chunk_t *chunk = arg;
sctp_chunk_t *shut;
- __u16 sport;
- __u16 dport;
- __u32 vtag;
- /* Grub in chunk and endpoint for kewl bitz. */
- sport = ntohs(chunk->sctp_hdr->dest);
- dport = ntohs(chunk->sctp_hdr->source);
-
- /* Make sure the ABORT packet's V-tag is the same as the
- * inbound packet if no association exists, otherwise use
- * the peer's vtag.
- */
- vtag = ntohl(chunk->sctp_hdr->vtag);
-
- /* Make a transport for the bucket, Eliza... */
- transport = sctp_transport_new(sctp_source(chunk), GFP_ATOMIC);
- if (!transport)
- goto nomem;
-
- /* Make a packet for the ABORT to go into. */
- packet = t_new(sctp_packet_t, GFP_ATOMIC);
- if (!packet)
- goto nomem_packet;
-
- packet = sctp_packet_init(packet, transport, sport, dport);
- packet = sctp_packet_config(packet, vtag, 0, NULL);
-
- /* Make an ABORT.
- * This will set the T bit since we have no association.
- */
- shut = sctp_make_shutdown_complete(NULL, chunk);
- if (!shut)
- goto nomem_chunk;
+ packet = sctp_ootb_pkt_new(asoc, chunk);
- /* Set the skb to the belonging sock for accounting. */
- shut->skb->sk = ep->base.sk;
+ if (packet) {
+ /* Make an SHUTDOWN_COMPLETE.
+ * The T bit will be set if the asoc is NULL.
+ */
+ shut = sctp_make_shutdown_complete(asoc, chunk);
+ if (!shut) {
+ sctp_ootb_pkt_free(packet);
+ return SCTP_DISPOSITION_NOMEM;
+ }
- sctp_packet_append_chunk(packet, shut);
- sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT, SCTP_PACKET(packet));
+ /* Set the skb to the belonging sock for accounting. */
+ shut->skb->sk = ep->base.sk;
- return SCTP_DISPOSITION_CONSUME;
+ sctp_packet_append_chunk(packet, shut);
-nomem_chunk:
- sctp_packet_free(packet);
+ sctp_add_cmd_sf(commands, SCTP_CMD_SEND_PKT,
+ SCTP_PACKET(packet));
-nomem_packet:
- sctp_transport_free(transport);
+ return SCTP_DISPOSITION_CONSUME;
+ }
-nomem:
return SCTP_DISPOSITION_NOMEM;
}
+
/*
* Process an unknown chunk.
*
@@ -3949,3 +4085,93 @@ sctp_sackhdr_t *sctp_sm_pull_sack(sctp_chunk_t *chunk)
skb_pull(chunk->skb, (num_blocks + num_dup_tsns) * sizeof(__u32));
return sack;
}
+
+/* Create an ABORT packet to be sent as a response, with the specified
+ * error causes.
+ */
+sctp_packet_t *sctp_abort_pkt_new(const sctp_endpoint_t *ep,
+ const sctp_association_t *asoc,
+ sctp_chunk_t *chunk,
+ const void *payload,
+ size_t paylen)
+{
+ sctp_packet_t *packet;
+ sctp_chunk_t *abort;
+
+ packet = sctp_ootb_pkt_new(asoc, chunk);
+
+ if (packet) {
+ /* Make an ABORT.
+ * The T bit will be set if the asoc is NULL.
+ */
+ abort = sctp_make_abort(asoc, chunk, paylen);
+ if (!abort) {
+ sctp_ootb_pkt_free(packet);
+ return NULL;
+ }
+ /* Add specified error causes, i.e., payload, to the
+ * end of the chunk.
+ */
+ sctp_addto_chunk(abort, paylen, payload);
+
+ /* Set the skb to the belonging sock for accounting. */
+ abort->skb->sk = ep->base.sk;
+
+ sctp_packet_append_chunk(packet, abort);
+
+ }
+
+ return packet;
+}
+
+/* Allocate a packet for responding in the OOTB conditions. */
+sctp_packet_t *sctp_ootb_pkt_new(const sctp_association_t *asoc,
+ const sctp_chunk_t *chunk)
+{
+ sctp_packet_t *packet;
+ sctp_transport_t *transport;
+ __u16 sport;
+ __u16 dport;
+ __u32 vtag;
+
+ /* Get the source and destination port from the inbound packet. */
+ sport = ntohs(chunk->sctp_hdr->dest);
+ dport = ntohs(chunk->sctp_hdr->source);
+
+ /* The V-tag is going to be the same as the inbound packet if no
+ * association exists, otherwise, use the peer's vtag.
+ */
+ if (asoc) {
+ vtag = asoc->peer.i.init_tag;
+ } else {
+ vtag = ntohl(chunk->sctp_hdr->vtag);
+ }
+
+ /* Make a transport for the bucket, Eliza... */
+ transport = sctp_transport_new(sctp_source(chunk), GFP_ATOMIC);
+
+ if (!transport)
+ goto nomem;
+
+ /* Allocate a new packet for sending the response. */
+ packet = t_new(sctp_packet_t, GFP_ATOMIC);
+ if (!packet)
+ goto nomem_packet;
+
+ packet = sctp_packet_init(packet, transport, sport, dport);
+ packet = sctp_packet_config(packet, vtag, 0, NULL);
+
+ return packet;
+
+nomem_packet:
+ sctp_transport_free(transport);
+nomem:
+ return NULL;
+}
+
+/* Free the packet allocated earlier for responding in the OOTB condition. */
+void sctp_ootb_pkt_free(sctp_packet_t *packet)
+{
+ sctp_transport_free(packet->transport);
+ sctp_packet_free(packet);
+}
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 65bb90e1a419..36e91aa641e6 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -4,41 +4,41 @@
* Copyright (c) 2001-2002 Intel Corp.
* Copyright (c) 2001-2002 Nokia, Inc.
* Copyright (c) 2001 La Monte H.P. Yarroll
- *
+ *
* This file is part of the SCTP kernel reference Implementation
- *
+ *
* These functions interface with the sockets layer to implement the
* SCTP Extensions for the Sockets API.
- *
+ *
* Note that the descriptions from the specification are USER level
* functions--this file is the functions which populate the struct proto
* for SCTP which is the BOTTOM of the sockets interface.
- *
- * The SCTP reference implementation is free software;
- * you can redistribute it and/or modify it under the terms of
+ *
+ * The SCTP reference implementation 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, or (at your option)
* any later version.
- *
- * The SCTP reference implementation is distributed in the hope that it
+ *
+ * The SCTP reference implementation 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 GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
+ * Boston, MA 02111-1307, USA.
+ *
* Please send any bug reports or fixes you make to the
* email address(es):
* lksctp developers <lksctp-developers@lists.sourceforge.net>
- *
+ *
* Or submit a bug report through the following website:
* http://www.sf.net/projects/lksctp
*
- * Written or modified by:
+ * Written or modified by:
* La Monte H.P. Yarroll <piggy@acm.org>
* Narasimha Budihal <narsi@refcode.org>
* Karl Knutson <karl@athena.chicago.il.us>
@@ -47,7 +47,7 @@
* Daisy Chang <daisyc@us.ibm.com>
* Sridhar Samudrala <samudrala@us.ibm.com>
* Inaky Perez-Gonzalez <inaky.gonzalez@intel.com>
- *
+ *
* Any bugs reported given to us we will try to fix... any fixes shared will
* be incorporated into the next SCTP release.
*/
@@ -67,14 +67,18 @@
#include <net/icmp.h>
#include <net/route.h>
#include <net/ipv6.h>
-#include <net/inet_common.h>
+#include <net/inet_common.h>
#include <linux/socket.h> /* for sa_family_t */
#include <net/sock.h>
-#include <net/sctp/sctp.h>
+#include <net/sctp/sctp.h>
+
+/* WARNING: Please do not remove the SCTP_STATIC attribute to
+ * any of the functions below as they are used to export functions
+ * used by a project regression testsuite.
+ */
/* Forward declarations for internal helper functions. */
-static void __sctp_write_space(sctp_association_t *asoc);
static int sctp_writeable(struct sock *sk);
static inline int sctp_wspace(sctp_association_t *asoc);
static inline void sctp_set_owner_w(sctp_chunk_t *chunk);
@@ -92,8 +96,7 @@ static int sctp_bindx_add(struct sock *, struct sockaddr_storage *, int);
static int sctp_bindx_rem(struct sock *, struct sockaddr_storage *, int);
static int sctp_do_bind(struct sock *, sockaddr_storage_t *, int);
static int sctp_autobind(struct sock *sk);
-static sctp_bind_bucket_t *sctp_bucket_create(sctp_bind_hashbucket_t *head,
- unsigned short snum);
+
/* API 3.1.2 bind() - UDP Style Syntax
* The syntax of bind() is,
@@ -132,7 +135,8 @@ int sctp_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
static long sctp_get_port_local(struct sock *, unsigned short);
/* Bind a local address either to an endpoint or to an association. */
-static int sctp_do_bind(struct sock *sk, sockaddr_storage_t *newaddr, int addr_len)
+SCTP_STATIC int sctp_do_bind(struct sock *sk, sockaddr_storage_t *newaddr,
+ int addr_len)
{
sctp_opt_t *sp = sctp_sk(sk);
sctp_endpoint_t *ep = sp->ep;
@@ -151,7 +155,7 @@ static int sctp_do_bind(struct sock *sk, sockaddr_storage_t *newaddr, int addr_l
if (PF_INET == sk->family) {
if (sa_family != AF_INET)
return -EINVAL;
- }
+ }
/* Make a local copy of the new address. */
tmpaddr = *newaddr;
@@ -317,7 +321,7 @@ static int sctp_do_bind(struct sock *sk, sockaddr_storage_t *newaddr, int addr_l
* sctp_bindx() for a lock-protected call.
*/
-static int __sctp_bindx(struct sock *sk, struct sockaddr_storage *addrs,
+static int __sctp_bindx(struct sock *sk, struct sockaddr_storage *addrs,
int addrcnt, int flags)
{
int retval = 0;
@@ -603,9 +607,9 @@ err_bindx_rem:
*
* Returns 0 if ok, <0 errno code on error.
*/
-static int sctp_setsockopt_bindx(struct sock* sk,
- struct sockaddr_storage *addrs,
- int addrssize, int op)
+SCTP_STATIC int sctp_setsockopt_bindx(struct sock* sk,
+ struct sockaddr_storage *addrs,
+ int addrssize, int op)
{
struct sockaddr_storage *kaddrs;
int err;
@@ -659,7 +663,7 @@ static int sctp_setsockopt_bindx(struct sock* sk,
* If sd in the close() call is a branched-off socket representing only
* one association, the shutdown is performed on that association only.
*/
-static void sctp_close(struct sock *sk, long timeout)
+SCTP_STATIC void sctp_close(struct sock *sk, long timeout)
{
sctp_endpoint_t *ep;
sctp_association_t *asoc;
@@ -727,9 +731,9 @@ static void sctp_close(struct sock *sk, long timeout)
/* BUG: We do not implement timeouts. */
/* BUG: We do not implement the equivalent of wait_for_tcp_memory(). */
-static int sctp_msghdr_parse(const struct msghdr *, sctp_cmsgs_t *);
+SCTP_STATIC int sctp_msghdr_parse(const struct msghdr *, sctp_cmsgs_t *);
-static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size)
+SCTP_STATIC int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size)
{
sctp_opt_t *sp;
sctp_endpoint_t *ep;
@@ -931,7 +935,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, int size)
= sinit->sinit_max_attempts;
}
if (sinit->sinit_max_init_timeo) {
- asoc->max_init_timeo
+ asoc->max_init_timeo
= sinit->sinit_max_init_timeo * HZ;
}
}
@@ -1094,8 +1098,8 @@ do_interrupted:
*/
static struct sk_buff *sctp_skb_recv_datagram(struct sock *, int, int, int *);
-static int sctp_recvmsg(struct sock *sk, struct msghdr *msg, int len,
- int noblock, int flags, int *addr_len)
+SCTP_STATIC int sctp_recvmsg(struct sock *sk, struct msghdr *msg, int len,
+ int noblock, int flags, int *addr_len)
{
sctp_ulpevent_t *event = NULL;
sctp_opt_t *sp = sctp_sk(sk);
@@ -1170,7 +1174,7 @@ out:
return err;
}
-static inline int sctp_setsockopt_disable_fragments(struct sock *sk,
+static inline int sctp_setsockopt_disable_fragments(struct sock *sk,
char *optval, int optlen)
{
int val;
@@ -1186,7 +1190,7 @@ static inline int sctp_setsockopt_disable_fragments(struct sock *sk,
return 0;
}
-static inline int sctp_setsockopt_set_events(struct sock *sk, char *optval,
+static inline int sctp_setsockopt_set_events(struct sock *sk, char *optval,
int optlen)
{
if (optlen != sizeof(struct sctp_event_subscribe))
@@ -1196,7 +1200,7 @@ static inline int sctp_setsockopt_set_events(struct sock *sk, char *optval,
return 0;
}
-static inline int sctp_setsockopt_autoclose(struct sock *sk, char *optval,
+static inline int sctp_setsockopt_autoclose(struct sock *sk, char *optval,
int optlen)
{
sctp_opt_t *sp = sctp_sk(sk);
@@ -1229,7 +1233,7 @@ static inline int sctp_setsockopt_autoclose(struct sock *sk, char *optval,
* optval - the buffer to store the value of the option.
* optlen - the size of the buffer.
*/
-static int sctp_setsockopt(struct sock *sk, int level, int optname,
+SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname,
char *optval, int optlen)
{
int retval = 0;
@@ -1313,19 +1317,20 @@ out_nounlock:
}
/* FIXME: Write comments. */
-static int sctp_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
+SCTP_STATIC int sctp_connect(struct sock *sk, struct sockaddr *uaddr,
+ int addr_len)
{
return -EOPNOTSUPP; /* STUB */
}
/* FIXME: Write comments. */
-static int sctp_disconnect(struct sock *sk, int flags)
+SCTP_STATIC int sctp_disconnect(struct sock *sk, int flags)
{
return -EOPNOTSUPP; /* STUB */
}
/* FIXME: Write comments. */
-static struct sock *sctp_accept(struct sock *sk, int flags, int *err)
+SCTP_STATIC struct sock *sctp_accept(struct sock *sk, int flags, int *err)
{
int error = -EOPNOTSUPP;
@@ -1334,7 +1339,7 @@ static struct sock *sctp_accept(struct sock *sk, int flags, int *err)
}
/* FIXME: Write Comments. */
-static int sctp_ioctl(struct sock *sk, int cmd, unsigned long arg)
+SCTP_STATIC int sctp_ioctl(struct sock *sk, int cmd, unsigned long arg)
{
return -EOPNOTSUPP; /* STUB */
}
@@ -1343,7 +1348,7 @@ static int sctp_ioctl(struct sock *sk, int cmd, unsigned long arg)
* initialized the SCTP-specific portion of the sock.
* The sock structure should already be zero-filled memory.
*/
-static int sctp_init_sock(struct sock *sk)
+SCTP_STATIC int sctp_init_sock(struct sock *sk)
{
sctp_endpoint_t *ep;
sctp_protocol_t *proto;
@@ -1428,7 +1433,7 @@ static int sctp_init_sock(struct sock *sk)
}
/* Cleanup any SCTP per socket resources. */
-static int sctp_destroy_sock(struct sock *sk)
+SCTP_STATIC int sctp_destroy_sock(struct sock *sk)
{
sctp_endpoint_t *ep;
@@ -1442,7 +1447,7 @@ static int sctp_destroy_sock(struct sock *sk)
}
/* FIXME: Comments needed. */
-static void sctp_shutdown(struct sock *sk, int how)
+SCTP_STATIC void sctp_shutdown(struct sock *sk, int how)
{
/* UDP-style sockets do not support shutdown. */
/* STUB */
@@ -1563,7 +1568,7 @@ static inline int sctp_getsockopt_autoclose(struct sock *sk, int len, char *optv
}
/* Helper routine to branch off an association to a new socket. */
-static int sctp_do_peeloff(sctp_association_t *assoc, struct socket **newsock)
+SCTP_STATIC int sctp_do_peeloff(sctp_association_t *assoc, struct socket **newsock)
{
struct sock *oldsk = assoc->base.sk;
struct sock *newsk;
@@ -1652,8 +1657,8 @@ static inline int sctp_getsockopt_peeloff(struct sock *sk, int len, char *optval
return 0;
}
-static int sctp_getsockopt(struct sock *sk, int level, int optname,
- char *optval, int *optlen)
+SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
+ char *optval, int *optlen)
{
int retval = 0;
sctp_protocol_t *proto = sctp_get_protocol();
@@ -1734,6 +1739,8 @@ static void sctp_unhash(struct sock *sk)
* link to the socket (struct sock) that uses it, the port number and
* a fastreuse flag (FIXME: NPI ipg).
*/
+static sctp_bind_bucket_t *sctp_bucket_create(sctp_bind_hashbucket_t *head,
+ unsigned short snum);
static long sctp_get_port_local(struct sock *sk, unsigned short snum)
{
sctp_bind_hashbucket_t *head; /* hash list */
@@ -1927,7 +1934,7 @@ static int sctp_get_port(struct sock *sk, unsigned short snum)
* An application uses listen() to mark a socket as being able to
* accept new associations.
*/
-static int sctp_seqpacket_listen(struct sock *sk, int backlog)
+SCTP_STATIC int sctp_seqpacket_listen(struct sock *sk, int backlog)
{
sctp_opt_t *sp = sctp_sk(sk);
sctp_endpoint_t *ep = sp->ep;
@@ -2184,7 +2191,8 @@ static int sctp_autobind(struct sock *sk)
* msg_control
* points here
*/
-static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs)
+SCTP_STATIC int sctp_msghdr_parse(const struct msghdr *msg,
+ sctp_cmsgs_t *cmsgs)
{
struct cmsghdr *cmsg;
@@ -2500,6 +2508,31 @@ static inline void sctp_set_owner_w(sctp_chunk_t *chunk)
sk->wmem_queued += SCTP_DATA_SNDSIZE(chunk);
}
+/* If sndbuf has changed, wake up per association sndbuf waiters. */
+static void __sctp_write_space(sctp_association_t *asoc)
+{
+ struct sock *sk = asoc->base.sk;
+ struct socket *sock = sk->socket;
+
+ if ((sctp_wspace(asoc) > 0) && sock) {
+ if (waitqueue_active(&asoc->wait))
+ wake_up_interruptible(&asoc->wait);
+
+ if (sctp_writeable(sk)) {
+ if (sk->sleep && waitqueue_active(sk->sleep))
+ wake_up_interruptible(sk->sleep);
+
+ /* Note that we try to include the Async I/O support
+ * here by modeling from the current TCP/UDP code.
+ * We have not tested with it yet.
+ */
+ if (sock->fasync_list &&
+ !(sk->shutdown & SEND_SHUTDOWN))
+ sock_wake_async(sock, 2, POLL_OUT);
+ }
+ }
+}
+
/* Do accounting for the sndbuf space.
* Decrement the used sndbuf space of the corresponding association by the
* data size which was just transmitted(freed).
@@ -2522,7 +2555,8 @@ static void sctp_wfree(struct sk_buff *skb)
}
/* Helper function to wait for space in the sndbuf. */
-static int sctp_wait_for_sndbuf(sctp_association_t *asoc, long *timeo_p, int msg_len)
+static int sctp_wait_for_sndbuf(sctp_association_t *asoc, long *timeo_p,
+ int msg_len)
{
struct sock *sk = asoc->base.sk;
int err = 0;
@@ -2581,31 +2615,6 @@ do_nonblock:
goto out;
}
-/* If sndbuf has changed, wake up per association sndbuf waiters. */
-static void __sctp_write_space(sctp_association_t *asoc)
-{
- struct sock *sk = asoc->base.sk;
- struct socket *sock = sk->socket;
-
- if ((sctp_wspace(asoc) > 0) && sock) {
- if (waitqueue_active(&asoc->wait))
- wake_up_interruptible(&asoc->wait);
-
- if (sctp_writeable(sk)) {
- if (sk->sleep && waitqueue_active(sk->sleep))
- wake_up_interruptible(sk->sleep);
-
- /* Note that we try to include the Async I/O support
- * here by modeling from the current TCP/UDP code.
- * We have not tested with it yet.
- */
- if (sock->fasync_list &&
- !(sk->shutdown & SEND_SHUTDOWN))
- sock_wake_async(sock, 2, POLL_OUT);
- }
- }
-}
-
/* If socket sndbuf has changed, wake up all per association waiters. */
void sctp_write_space(struct sock *sk)
{
diff --git a/net/wanrouter/wanproc.c b/net/wanrouter/wanproc.c
index b3ba10e04e66..aae0e01ad266 100644
--- a/net/wanrouter/wanproc.c
+++ b/net/wanrouter/wanproc.c
@@ -61,9 +61,6 @@ typedef struct wan_stat_entry
#ifdef CONFIG_PROC_FS
-/* Proc filesystem interface */
-static int router_proc_perms(struct inode *, int);
-
/* Miscellaneous */
/*
@@ -79,11 +76,6 @@ static int router_proc_perms(struct inode *, int);
* Generic /proc/net/router/<file> file and inode operations
*/
-static struct inode_operations router_inode =
-{
- .permission = router_proc_perms,
-};
-
/*
* /proc/net/router
*/
@@ -99,15 +91,6 @@ static struct proc_dir_entry *proc_router;
/****** Proc filesystem entry points ****************************************/
/*
- * Verify access rights.
- */
-
-static int router_proc_perms (struct inode* inode, int op)
-{
- return 0;
-}
-
-/*
* Iterator
*/
static void *r_start(struct seq_file *m, loff_t *pos)
@@ -320,16 +303,14 @@ int __init wanrouter_proc_init (void)
if (!proc_router)
goto fail;
- p = create_proc_entry("config",0,proc_router);
+ p = create_proc_entry("config", S_IRUGO, proc_router);
if (!p)
goto fail_config;
p->proc_fops = &config_fops;
- p->proc_iops = &router_inode;
- p = create_proc_entry("status",0,proc_router);
+ p = create_proc_entry("status", S_IRUGO, proc_router);
if (!p)
goto fail_stat;
p->proc_fops = &status_fops;
- p->proc_iops = &router_inode;
return 0;
fail_stat:
remove_proc_entry("config", proc_router);
@@ -359,11 +340,10 @@ int wanrouter_proc_add (wan_device_t* wandev)
if (wandev->magic != ROUTER_MAGIC)
return -EINVAL;
- wandev->dent = create_proc_entry(wandev->name, 0, proc_router);
+ wandev->dent = create_proc_entry(wandev->name, S_IRUGO, proc_router);
if (!wandev->dent)
return -ENOMEM;
wandev->dent->proc_fops = &wandev_fops;
- wandev->dent->proc_iops = &router_inode;
wandev->dent->data = wandev;
return 0;
}
diff --git a/net/x25/Makefile b/net/x25/Makefile
index 7656831c6c69..eb24260baafc 100644
--- a/net/x25/Makefile
+++ b/net/x25/Makefile
@@ -6,7 +6,7 @@ obj-$(CONFIG_X25) += x25.o
x25-y := af_x25.o x25_dev.o x25_facilities.o x25_in.o \
x25_link.o x25_out.o x25_route.o x25_subr.o \
- x25_timer.o
+ x25_timer.o x25_proc.o
x25-$(CONFIG_SYSCTL) += sysctl_net_x25.o
x25-objs := $(x25-y)
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c
index 97ac8aa10235..89c6026256c9 100644
--- a/net/x25/af_x25.c
+++ b/net/x25/af_x25.c
@@ -27,6 +27,8 @@
* 2000-10-02 Henner Eisen Made x25_kick() single threaded per socket.
* 2000-10-27 Henner Eisen MSG_DONTWAIT for fragment allocation.
* 2000-11-14 Henner Eisen Closing datalink from NETDEV_GOING_DOWN
+ * 2002-10-06 Arnaldo C. Melo Get rid of cli/sti, move proc stuff to
+ * x25_proc.c, using seq_file
*/
#include <linux/config.h>
@@ -55,7 +57,6 @@
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/notifier.h>
-#include <linux/proc_fs.h>
#include <linux/init.h>
#include <net/x25.h>
@@ -65,8 +66,8 @@ int sysctl_x25_reset_request_timeout = X25_DEFAULT_T22;
int sysctl_x25_clear_request_timeout = X25_DEFAULT_T23;
int sysctl_x25_ack_holdback_timeout = X25_DEFAULT_T2;
-static struct sock *x25_list;
-static rwlock_t x25_list_lock = RW_LOCK_UNLOCKED;
+struct sock *x25_list;
+rwlock_t x25_list_lock = RW_LOCK_UNLOCKED;
static struct proto_ops x25_proto_ops;
@@ -246,8 +247,10 @@ static struct sock *x25_find_listener(struct x25_address *addr)
read_lock_bh(&x25_list_lock);
for (s = x25_list; s; s = s->next)
- if ((!strcmp(addr->x25_addr, x25_sk(s)->source_addr.x25_addr) ||
- !strcmp(addr->x25_addr, null_x25_address.x25_addr)) &&
+ if ((!strcmp(addr->x25_addr,
+ x25_sk(s)->source_addr.x25_addr) ||
+ !strcmp(addr->x25_addr,
+ null_x25_address.x25_addr)) &&
s->state == TCP_LISTEN)
break;
@@ -318,12 +321,13 @@ static void x25_destroy_timer(unsigned long data)
}
/*
- * This is called from user mode and the timers. Thus it protects itself against
- * interrupt users but doesn't worry about being called during work.
- * Once it is removed from the queue no interrupt or bottom half will
- * touch it and we are (fairly 8-) ) safe.
+ * This is called from user mode and the timers. Thus it protects itself
+ * against interrupt users but doesn't worry about being called during
+ * work. Once it is removed from the queue no interrupt or bottom half
+ * will touch it and we are (fairly 8-) ) safe.
+ * Not static as it's used by the timer
*/
-void x25_destroy_socket(struct sock *sk) /* Not static as it's used by the timer */
+void x25_destroy_socket(struct sock *sk)
{
struct sk_buff *skb;
@@ -337,7 +341,10 @@ void x25_destroy_socket(struct sock *sk) /* Not static as it's used by the timer
while ((skb = skb_dequeue(&sk->receive_queue)) != NULL) {
if (skb->sk != sk) { /* A pending connection */
- skb->sk->dead = 1; /* Queue the unaccepted socket for death */
+ /*
+ * Queue the unaccepted socket for death
+ */
+ skb->sk->dead = 1;
x25_start_heartbeat(skb->sk);
x25_sk(skb->sk)->state = X25_STATE_0;
}
@@ -631,7 +638,8 @@ static int x25_wait_for_connection_establishment(struct sock *sk)
return rc;
}
-static int x25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags)
+static int x25_connect(struct socket *sock, struct sockaddr *uaddr,
+ int addr_len, int flags)
{
struct sock *sk = sock->sk;
struct x25_opt *x25 = x25_sk(sk);
@@ -642,7 +650,7 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len
lock_sock(sk);
if (sk->state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) {
sock->state = SS_CONNECTED;
- goto out; /* Connect completed during a ERESTARTSYS event */
+ goto out; /* Connect completed during a ERESTARTSYS event */
}
rc = -ECONNREFUSED;
@@ -679,7 +687,7 @@ static int x25_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len
goto out_put_neigh;
rc = -EINVAL;
- if (sk->zapped) /* Must bind first - autobinding does not work */
+ if (sk->zapped) /* Must bind first - autobinding does not work */
goto out_put_neigh;
if (!strcmp(x25->source_addr.x25_addr, null_x25_address.x25_addr))
@@ -785,7 +793,8 @@ out:
return rc;
}
-static int x25_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer)
+static int x25_getname(struct socket *sock, struct sockaddr *uaddr,
+ int *uaddr_len, int peer)
{
struct sockaddr_x25 *sx25 = (struct sockaddr_x25 *)uaddr;
struct sock *sk = sock->sk;
@@ -804,7 +813,8 @@ static int x25_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_l
return 0;
}
-int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb, unsigned int lci)
+int x25_rx_call_request(struct sk_buff *skb, struct x25_neigh *nb,
+ unsigned int lci)
{
struct sock *sk;
struct sock *make;
@@ -906,7 +916,8 @@ out_clear_request:
goto out;
}
-static int x25_sendmsg(struct socket *sock, struct msghdr *msg, int len, struct scm_cookie *scm)
+static int x25_sendmsg(struct socket *sock, struct msghdr *msg, int len,
+ struct scm_cookie *scm)
{
struct sock *sk = sock->sk;
struct x25_opt *x25 = x25_sk(sk);
@@ -1118,7 +1129,8 @@ static int x25_recvmsg(struct socket *sock, struct msghdr *msg, int size,
msg->msg_flags |= MSG_OOB;
} else {
/* Now we can treat all alike */
- skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, flags & MSG_DONTWAIT, &rc);
+ skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
+ flags & MSG_DONTWAIT, &rc);
if (!skb)
goto out;
@@ -1236,14 +1248,16 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
break;
case SIOCX25GFACILITIES: {
struct x25_facilities fac = x25->facilities;
- rc = copy_to_user((void *)arg, &fac, sizeof(fac)) ? -EFAULT : 0;
+ rc = copy_to_user((void *)arg, &fac,
+ sizeof(fac)) ? -EFAULT : 0;
break;
}
case SIOCX25SFACILITIES: {
struct x25_facilities facilities;
rc = -EFAULT;
- if (copy_from_user(&facilities, (void *)arg, sizeof(facilities)))
+ if (copy_from_user(&facilities, (void *)arg,
+ sizeof(facilities)))
break;
rc = -EINVAL;
if (sk->state != TCP_LISTEN && sk->state != TCP_CLOSE)
@@ -1269,7 +1283,8 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
case SIOCX25GCALLUSERDATA: {
struct x25_calluserdata cud = x25->calluserdata;
- rc = copy_to_user((void *)arg, &cud, sizeof(cud)) ? -EFAULT : 0;
+ rc = copy_to_user((void *)arg, &cud,
+ sizeof(cud)) ? -EFAULT : 0;
break;
}
@@ -1277,7 +1292,8 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
struct x25_calluserdata calluserdata;
rc = -EFAULT;
- if (copy_from_user(&calluserdata, (void *)arg, sizeof(calluserdata)))
+ if (copy_from_user(&calluserdata, (void *)arg,
+ sizeof(calluserdata)))
break;
rc = -EINVAL;
if (calluserdata.cudlength > X25_MAX_CUD_LEN)
@@ -1290,7 +1306,8 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
case SIOCX25GCAUSEDIAG: {
struct x25_causediag causediag;
causediag = x25->causediag;
- rc = copy_to_user((void *)arg, &causediag, sizeof(causediag)) ? -EFAULT : 0;
+ rc = copy_to_user((void *)arg, &causediag,
+ sizeof(causediag)) ? -EFAULT : 0;
break;
}
@@ -1302,70 +1319,6 @@ static int x25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
return rc;
}
-static int x25_get_info(char *buffer, char **start, off_t offset, int length)
-{
- struct sock *s;
- struct net_device *dev;
- const char *devname;
- off_t pos = 0;
- off_t begin = 0;
- int len = sprintf(buffer, "dest_addr src_addr dev lci st vs vr "
- "va t t2 t21 t22 t23 Snd-Q Rcv-Q inode\n");
-
- read_lock_bh(&x25_list_lock);
-
- for (s = x25_list; s; s = s->next) {
- struct x25_opt *x25 = x25_sk(s);
-
- if (!x25->neighbour || (dev = x25->neighbour->dev) == NULL)
- devname = "???";
- else
- devname = x25->neighbour->dev->name;
-
- len += sprintf(buffer + len, "%-10s %-10s %-5s %3.3X %d %d "
- "%d %d %3lu %3lu %3lu %3lu %3lu "
- "%5d %5d %ld\n",
- !x25->dest_addr.x25_addr[0] ? "*" :
- x25->dest_addr.x25_addr,
- !x25->source_addr.x25_addr[0] ? "*" :
- x25->source_addr.x25_addr,
- devname,
- x25->lci & 0x0FFF,
- x25->state,
- x25->vs,
- x25->vr,
- x25->va,
- x25_display_timer(s) / HZ,
- x25->t2 / HZ,
- x25->t21 / HZ,
- x25->t22 / HZ,
- x25->t23 / HZ,
- atomic_read(&s->wmem_alloc),
- atomic_read(&s->rmem_alloc),
- s->socket ? SOCK_INODE(s->socket)->i_ino : 0L);
-
- pos = begin + len;
-
- if (pos < offset) {
- len = 0;
- begin = pos;
- }
-
- if (pos > offset + length)
- break;
- }
-
- read_unlock_bh(&x25_list_lock);
-
- *start = buffer + (offset - begin);
- len -= (offset - begin);
-
- if (len > length)
- len = length;
-
- return len;
-}
-
struct net_proto_family x25_family_ops = {
.family = AF_X25,
.create = x25_create,
@@ -1395,7 +1348,6 @@ static struct proto_ops SOCKOPS_WRAPPED(x25_proto_ops) = {
#include <linux/smp_lock.h>
SOCKOPS_WRAP(x25_proto, AF_X25);
-
static struct packet_type x25_packet_type = {
.type = __constant_htons(ETH_P_X25),
.func = x25_lapb_receive_frame,
@@ -1435,9 +1387,7 @@ static int __init x25_init(void)
x25_register_sysctl();
#endif
- proc_net_create("x25", 0, x25_get_info);
- proc_net_create("x25_routes", 0, x25_routes_get_info);
-
+ x25_proc_init();
#ifdef MODULE
/*
* Register any pre existing devices.
@@ -1457,18 +1407,9 @@ static int __init x25_init(void)
}
module_init(x25_init);
-
-
-MODULE_AUTHOR("Jonathan Naylor <g4klx@g4klx.demon.co.uk>");
-MODULE_DESCRIPTION("The X.25 Packet Layer network layer protocol");
-MODULE_LICENSE("GPL");
-
static void __exit x25_exit(void)
{
-
- proc_net_remove("x25");
- proc_net_remove("x25_routes");
-
+ x25_proc_exit();
x25_link_free();
x25_route_free();
@@ -1484,3 +1425,6 @@ static void __exit x25_exit(void)
}
module_exit(x25_exit);
+MODULE_AUTHOR("Jonathan Naylor <g4klx@g4klx.demon.co.uk>");
+MODULE_DESCRIPTION("The X.25 Packet Layer network layer protocol");
+MODULE_LICENSE("GPL");
diff --git a/net/x25/x25_proc.c b/net/x25/x25_proc.c
new file mode 100644
index 000000000000..a8961fa0a341
--- /dev/null
+++ b/net/x25/x25_proc.c
@@ -0,0 +1,252 @@
+/*
+ * X.25 Packet Layer release 002
+ *
+ * This is ALPHA test software. This code may break your machine,
+ * randomly fail to work with new releases, misbehave and/or generally
+ * screw up. It might even work.
+ *
+ * This code REQUIRES 2.4 with seq_file support
+ *
+ * This module:
+ * This module 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.
+ *
+ * History
+ * 2002/10/06 Arnaldo Carvalho de Melo seq_file support
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <net/sock.h>
+#include <net/x25.h>
+
+#ifdef CONFIG_PROC_FS
+static __inline__ struct x25_route *x25_get_route_idx(loff_t pos)
+{
+ struct list_head *route_entry;
+ struct x25_route *rt = NULL;
+
+ list_for_each(route_entry, &x25_route_list) {
+ rt = list_entry(route_entry, struct x25_route, node);
+ if (--pos)
+ break;
+ }
+
+ return rt;
+}
+
+static void *x25_seq_route_start(struct seq_file *seq, loff_t *pos)
+{
+ loff_t l = *pos;
+
+ read_lock_bh(&x25_route_list_lock);
+ return l ? x25_get_route_idx(--l) : (void *)1;
+}
+
+static void *x25_seq_route_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ struct x25_route *rt;
+
+ ++*pos;
+ if (v == (void *)1) {
+ rt = NULL;
+ if (!list_empty(&x25_route_list))
+ rt = list_entry(x25_route_list.next,
+ struct x25_route, node);
+ goto out;
+ }
+ rt = v;
+ if (rt->node.next != &x25_route_list)
+ rt = list_entry(rt->node.next, struct x25_route, node);
+ else
+ rt = NULL;
+out:
+ return rt;
+}
+
+static void x25_seq_route_stop(struct seq_file *seq, void *v)
+{
+ read_unlock_bh(&x25_route_list_lock);
+}
+
+static int x25_seq_route_show(struct seq_file *seq, void *v)
+{
+ struct x25_route *rt;
+
+ if (v == (void *)1) {
+ seq_puts(seq, "Address Digits Device\n");
+ goto out;
+ }
+
+ rt = v;
+ seq_printf(seq, "%-15s %-6d %-5s\n",
+ rt->address.x25_addr, rt->sigdigits,
+ rt->dev ? rt->dev->name : "???");
+out:
+ return 0;
+}
+
+static __inline__ struct sock *x25_get_socket_idx(loff_t pos)
+{
+ struct sock *s;
+
+ for (s = x25_list; pos && s; s = s->next)
+ --pos;
+
+ return s;
+}
+
+static void *x25_seq_socket_start(struct seq_file *seq, loff_t *pos)
+{
+ loff_t l = *pos;
+
+ read_lock_bh(&x25_list_lock);
+ return l ? x25_get_socket_idx(--l) : (void *)1;
+}
+
+static void *x25_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos)
+{
+ struct sock *s;
+
+ ++*pos;
+ if (v == (void *)1) {
+ s = NULL;
+ if (x25_list)
+ s = x25_list;
+ goto out;
+ }
+ s = v;
+ s = s->next;
+out:
+ return s;
+}
+
+static void x25_seq_socket_stop(struct seq_file *seq, void *v)
+{
+ read_unlock_bh(&x25_list_lock);
+}
+
+static int x25_seq_socket_show(struct seq_file *seq, void *v)
+{
+ struct sock *s;
+ struct x25_opt *x25;
+ struct net_device *dev;
+ const char *devname;
+
+ if (v == (void *)1) {
+ seq_printf(seq, "dest_addr src_addr dev lci st vs vr "
+ "va t t2 t21 t22 t23 Snd-Q Rcv-Q inode\n");
+ goto out;
+ }
+
+ s = v;
+ x25 = x25_sk(s);
+
+ if (!x25->neighbour || (dev = x25->neighbour->dev) == NULL)
+ devname = "???";
+ else
+ devname = x25->neighbour->dev->name;
+
+ seq_printf(seq, "%-10s %-10s %-5s %3.3X %d %d %d %d %3lu %3lu "
+ "%3lu %3lu %3lu %5d %5d %ld\n",
+ !x25->dest_addr.x25_addr[0] ? "*" : x25->dest_addr.x25_addr,
+ !x25->source_addr.x25_addr[0] ? "*" : x25->source_addr.x25_addr,
+ devname, x25->lci & 0x0FFF, x25->state, x25->vs, x25->vr,
+ x25->va, x25_display_timer(s) / HZ, x25->t2 / HZ,
+ x25->t21 / HZ, x25->t22 / HZ, x25->t23 / HZ,
+ atomic_read(&s->wmem_alloc), atomic_read(&s->rmem_alloc),
+ s->socket ? SOCK_INODE(s->socket)->i_ino : 0L);
+out:
+ return 0;
+}
+
+struct seq_operations x25_seq_route_ops = {
+ .start = x25_seq_route_start,
+ .next = x25_seq_route_next,
+ .stop = x25_seq_route_stop,
+ .show = x25_seq_route_show,
+};
+
+struct seq_operations x25_seq_socket_ops = {
+ .start = x25_seq_socket_start,
+ .next = x25_seq_socket_next,
+ .stop = x25_seq_socket_stop,
+ .show = x25_seq_socket_show,
+};
+
+static int x25_seq_socket_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &x25_seq_socket_ops);
+}
+
+static int x25_seq_route_open(struct inode *inode, struct file *file)
+{
+ return seq_open(file, &x25_seq_route_ops);
+}
+
+static struct file_operations x25_seq_socket_fops = {
+ .open = x25_seq_socket_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static struct file_operations x25_seq_route_fops = {
+ .open = x25_seq_route_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static struct proc_dir_entry *x25_proc_dir;
+
+int __init x25_proc_init(void)
+{
+ struct proc_dir_entry *p;
+ int rc = -ENOMEM;
+
+ x25_proc_dir = proc_mkdir("x25", proc_net);
+ if (!x25_proc_dir)
+ goto out;
+
+ p = create_proc_entry("route", S_IRUGO, x25_proc_dir);
+ if (!p)
+ goto out_route;
+ p->proc_fops = &x25_seq_route_fops;
+
+ p = create_proc_entry("socket", S_IRUGO, x25_proc_dir);
+ if (!p)
+ goto out_socket;
+ p->proc_fops = &x25_seq_socket_fops;
+ rc = 0;
+out:
+ return rc;
+out_socket:
+ remove_proc_entry("route", x25_proc_dir);
+out_route:
+ remove_proc_entry("x25", proc_net);
+ goto out;
+}
+
+void __exit x25_proc_exit(void)
+{
+ remove_proc_entry("route", x25_proc_dir);
+ remove_proc_entry("socket", x25_proc_dir);
+ remove_proc_entry("x25", proc_net);
+}
+
+#else /* CONFIG_PROC_FS */
+
+int __init x25_proc_init(void)
+{
+ return 0;
+}
+
+void __exit x25_proc_exit(void)
+{
+}
+#endif /* CONFIG_PROC_FS */
diff --git a/net/x25/x25_route.c b/net/x25/x25_route.c
index 0513197a7f8b..07ae9d9e204a 100644
--- a/net/x25/x25_route.c
+++ b/net/x25/x25_route.c
@@ -18,34 +18,12 @@
*/
#include <linux/config.h>
-#include <linux/errno.h>
-#include <linux/types.h>
-#include <linux/socket.h>
-#include <linux/in.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/timer.h>
-#include <linux/string.h>
-#include <linux/sockios.h>
-#include <linux/net.h>
-#include <linux/inet.h>
-#include <linux/netdevice.h>
-#include <net/arp.h>
#include <linux/if_arp.h>
-#include <linux/skbuff.h>
-#include <net/sock.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <linux/fcntl.h>
-#include <linux/termios.h> /* For TIOCINQ/OUTQ */
-#include <linux/mm.h>
-#include <linux/interrupt.h>
-#include <linux/notifier.h>
#include <linux/init.h>
#include <net/x25.h>
-static struct list_head x25_route_list = LIST_HEAD_INIT(x25_route_list);
-static rwlock_t x25_route_list_lock = RW_LOCK_UNLOCKED;
+struct list_head x25_route_list = LIST_HEAD_INIT(x25_route_list);
+rwlock_t x25_route_list_lock = RW_LOCK_UNLOCKED;
/*
* Add a new route.
@@ -226,45 +204,6 @@ out:
return rc;
}
-int x25_routes_get_info(char *buffer, char **start, off_t offset, int length)
-{
- struct x25_route *rt;
- struct list_head *entry;
- off_t pos = 0;
- off_t begin = 0;
- int len = sprintf(buffer, "address digits device\n");
-
- read_lock_bh(&x25_route_list_lock);
-
- list_for_each(entry, &x25_route_list) {
- rt = list_entry(entry, struct x25_route, node);
- len += sprintf(buffer + len, "%-15s %-6d %-5s\n",
- rt->address.x25_addr,
- rt->sigdigits,
- rt->dev ? rt->dev->name : "???");
-
- pos = begin + len;
-
- if (pos < offset) {
- len = 0;
- begin = pos;
- }
-
- if (pos > offset + length)
- break;
- }
-
- read_unlock_bh(&x25_route_list_lock);
-
- *start = buffer + (offset - begin);
- len -= (offset - begin);
-
- if (len > length)
- len = length;
-
- return len;
-}
-
/*
* Release all memory associated with X.25 routing structures.
*/