summaryrefslogtreecommitdiffstats
path: root/include/net
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1998-09-19 19:15:08 +0000
committerRalf Baechle <ralf@linux-mips.org>1998-09-19 19:15:08 +0000
commit03ba4131783cc9e872f8bb26a03f15bc11f27564 (patch)
tree88db8dba75ae06ba3bad08e42c5e52efc162535c /include/net
parent257730f99381dd26e10b832fce4c94cae7ac1176 (diff)
- Merge with Linux 2.1.121.
- Bugfixes.
Diffstat (limited to 'include/net')
-rw-r--r--include/net/dst.h1
-rw-r--r--include/net/flow.h4
-rw-r--r--include/net/ip6_fib.h58
-rw-r--r--include/net/ip6_route.h41
-rw-r--r--include/net/ip_fib.h2
-rw-r--r--include/net/ipv6.h121
-rw-r--r--include/net/ndisc.h7
-rw-r--r--include/net/pkt_sched.h10
-rw-r--r--include/net/protocol.h16
-rw-r--r--include/net/rawv6.h16
-rw-r--r--include/net/route.h12
-rw-r--r--include/net/snmp.h47
-rw-r--r--include/net/sock.h93
-rw-r--r--include/net/tcp.h67
-rw-r--r--include/net/transp_v6.h4
15 files changed, 277 insertions, 222 deletions
diff --git a/include/net/dst.h b/include/net/dst.h
index a73a2d045..50b3373dd 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -35,7 +35,6 @@ struct dst_entry
atomic_t use; /* client references */
struct device *dev;
int obsolete;
- __u32 priority;
unsigned long lastuse;
unsigned mxlock;
unsigned window;
diff --git a/include/net/flow.h b/include/net/flow.h
index 7759e506c..45d232fb9 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -21,6 +21,10 @@ struct flowi {
struct in6_addr * saddr;
} ip6_u;
} nl_u;
+#define fl6_dst nl_u.ip6_u.daddr
+#define fl6_src nl_u.ip6_u.saddr
+#define fl4_dst nl_u.ip4_u.daddr
+#define fl4_src nl_u.ip4_u.saddr
int oif;
diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
index 5bd90dde7..905876d00 100644
--- a/include/net/ip6_fib.h
+++ b/include/net/ip6_fib.h
@@ -23,7 +23,8 @@
struct rt6_info;
-struct fib6_node {
+struct fib6_node
+{
struct fib6_node *parent;
struct fib6_node *left;
struct fib6_node *right;
@@ -43,12 +44,14 @@ struct fib6_node {
*
*/
-struct rt6key {
+struct rt6key
+{
struct in6_addr addr;
int plen;
};
-struct rt6_info {
+struct rt6_info
+{
union {
struct dst_entry dst;
struct rt6_info *next;
@@ -56,21 +59,16 @@ struct rt6_info {
#define rt6i_dev u.dst.dev
#define rt6i_nexthop u.dst.neighbour
-#define rt6i_use u.dst.use
-#define rt6i_ref u.dst.refcnt
-
-#define rt6i_tstamp u.dst.lastuse
struct fib6_node *rt6i_node;
struct in6_addr rt6i_gateway;
- int rt6i_keylen;
-
u32 rt6i_flags;
u32 rt6i_metric;
u8 rt6i_hoplimit;
unsigned long rt6i_expires;
+ atomic_t rt6i_ref;
union {
struct flow_rule *rt6iu_flowr;
@@ -84,6 +82,33 @@ struct rt6_info {
struct rt6key rt6i_src;
};
+struct fib6_walker_t
+{
+ struct fib6_walker_t *prev, *next;
+ struct fib6_node *root, *node;
+ struct rt6_info *leaf;
+ unsigned char state;
+ unsigned char prune;
+ int (*func)(struct fib6_walker_t *);
+ void *args;
+};
+
+extern struct fib6_walker_t fib6_walker_list;
+
+extern __inline__ void fib6_walker_link(struct fib6_walker_t *w)
+{
+ w->next = fib6_walker_list.next;
+ w->prev = &fib6_walker_list;
+ w->next->prev = w;
+ w->prev->next = w;
+}
+
+extern __inline__ void fib6_walker_unlink(struct fib6_walker_t *w)
+{
+ w->next->prev = w->prev;
+ w->prev->next = w->next;
+ w->prev = w->next = w;
+}
struct rt6_statistics {
__u32 fib_nodes;
@@ -97,8 +122,6 @@ struct rt6_statistics {
#define RTN_ROOT 0x0002 /* tree root node */
#define RTN_RTINFO 0x0004 /* node with valid routing info */
-#define RTN_TAG 0x0100
-
/*
* priority levels (or metrics)
*
@@ -128,11 +151,16 @@ extern struct fib6_node *fib6_lookup(struct fib6_node *root,
struct in6_addr *daddr,
struct in6_addr *saddr);
-#define RT6_FILTER_RTNODES 1
+struct fib6_node *fib6_locate(struct fib6_node *root,
+ struct in6_addr *daddr, int dst_len,
+ struct in6_addr *saddr, int src_len);
+
+extern void fib6_clean_tree(struct fib6_node *root,
+ int (*func)(struct rt6_info *, void *arg),
+ int prune, void *arg);
-extern void fib6_walk_tree(struct fib6_node *root,
- f_pnode func, void *arg,
- int filter);
+extern int fib6_walk(struct fib6_walker_t *w);
+extern int fib6_walk_continue(struct fib6_walker_t *w);
extern int fib6_add(struct fib6_node *root,
struct rt6_info *rt);
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index 8ca62a7ed..9311cc34e 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -12,23 +12,6 @@
#include <net/flow.h>
#include <net/ip6_fib.h>
-/*
- * Structure for assync processing of operations on the routing
- * table
- */
-
-struct rt6_req {
- int operation;
- struct rt6_info *ptr;
-
- struct rt6_req *next;
- struct rt6_req *prev;
-
-#define RT_OPER_ADD 1
-#define RT_OPER_DEL 2
-};
-
-
struct pol_chain {
int type;
int priority;
@@ -53,8 +36,7 @@ extern void ip6_route_cleanup(void);
extern int ipv6_route_ioctl(unsigned int cmd, void *arg);
-extern struct rt6_info * ip6_route_add(struct in6_rtmsg *rtmsg,
- int *err);
+extern int ip6_route_add(struct in6_rtmsg *rtmsg);
extern int ip6_del_rt(struct rt6_info *);
extern int ip6_rt_addr_add(struct in6_addr *addr,
@@ -85,15 +67,15 @@ extern struct rt6_info * rt6_add_dflt_router(struct in6_addr *gwaddr,
extern void rt6_purge_dflt_routers(int lst_resort);
-extern struct rt6_info * rt6_redirect(struct in6_addr *dest,
+extern void rt6_redirect(struct in6_addr *dest,
struct in6_addr *saddr,
- struct in6_addr *target,
- struct device *dev,
+ struct neighbour *neigh,
int on_link);
-extern void rt6_pmtu_discovery(struct in6_addr *addr,
+extern void rt6_pmtu_discovery(struct in6_addr *daddr,
+ struct in6_addr *saddr,
struct device *dev,
- int pmtu);
+ u32 pmtu);
struct nlmsghdr;
struct netlink_callback;
@@ -103,22 +85,25 @@ extern int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *a
extern int inet6_rtm_getroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg);
extern void rt6_ifdown(struct device *dev);
+extern void rt6_mtu_change(struct device *dev, unsigned mtu);
/*
* Store a destination cache entry in a socket
* For UDP/RAW sockets this is done on udp_connect.
*/
-extern __inline__ void ip6_dst_store(struct sock *sk, struct dst_entry *dst)
+extern __inline__ void ip6_dst_store(struct sock *sk, struct dst_entry *dst,
+ struct in6_addr *daddr)
{
struct ipv6_pinfo *np;
struct rt6_info *rt;
-
+
np = &sk->net_pinfo.af_inet6;
dst_release(xchg(&sk->dst_cache,dst));
-
+
rt = (struct rt6_info *) dst;
-
+
+ np->daddr_cache = daddr;
np->dst_cookie = rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0;
}
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index f96fa618c..b79e4d0fb 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -212,7 +212,7 @@ extern int fib_semantic_match(int type, struct fib_info *,
extern struct fib_info *fib_create_info(const struct rtmsg *r, struct kern_rta *rta,
const struct nlmsghdr *, int *err);
extern int fib_nh_match(struct rtmsg *r, struct nlmsghdr *, struct kern_rta *rta, struct fib_info *fi);
-extern int fib_dump_info(struct sk_buff *skb, pid_t pid, u32 seq, int event,
+extern int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
u8 tb_id, u8 type, u8 scope, void *dst, int dst_len, u8 tos,
struct fib_info *fi);
extern int fib_sync_down(u32 local, struct device *dev, int force);
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index acf37b357..03f30b644 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -4,7 +4,7 @@
* Authors:
* Pedro Roque <roque@di.fc.ul.pt>
*
- * $Id: ipv6.h,v 1.12 1998/07/15 05:05:02 davem Exp $
+ * $Id: ipv6.h,v 1.13 1998/08/26 12:02:11 davem Exp $
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -86,53 +86,44 @@ struct frag_hdr {
#include <net/sock.h>
-extern struct ipv6_mib ipv6_statistics;
+extern struct ipv6_mib ipv6_statistics;
+extern struct icmpv6_mib icmpv6_statistics;
+extern struct udp_mib udp_stats_in6;
-struct ipv6_frag {
- __u16 offset;
- __u16 len;
- struct sk_buff *skb;
-
- struct frag_hdr *fhdr;
-
- struct ipv6_frag *next;
+struct ip6_ra_chain
+{
+ struct ip6_ra_chain *next;
+ struct sock *sk;
+ int sel;
+ void (*destructor)(struct sock *);
};
+extern struct ip6_ra_chain *ip6_ra_chain;
+
/*
- * Equivalent of ipv4 struct ipq
+ This structure is prepared by protocol, when parsing
+ ancillary data and passed to IPv6.
*/
-struct frag_queue {
+struct ipv6_txoptions
+{
+ /* Length of this structure */
+ int tot_len;
- struct frag_queue *next;
- struct frag_queue *prev;
+ /* length of extension headers */
- __u32 id; /* fragment id */
- struct in6_addr saddr;
- struct in6_addr daddr;
- struct timer_list timer; /* expire timer */
- struct ipv6_frag *fragments;
- struct device *dev;
- __u8 last_in; /* has last segment arrived? */
- __u8 nexthdr;
- __u8 *nhptr;
-};
+ __u16 opt_flen; /* after fragment hdr */
+ __u16 opt_nflen; /* before fragment hdr */
-struct ipv6_tlvtype
-{
- u8 type;
- u8 len;
-};
+ struct ipv6_opt_hdr *hopopt;
+ struct ipv6_opt_hdr *dst0opt;
+ struct ipv6_rt_hdr *srcrt; /* Routing Header */
+ struct ipv6_opt_hdr *auth;
+ struct ipv6_opt_hdr *dst1opt;
-struct ip6_ra_chain
-{
- struct ip6_ra_chain *next;
- struct sock *sk;
- int sel;
- void (*destructor)(struct sock *);
+ /* Option buffer, as read by IPV6_PKTOPTIONS, starts here. */
};
-extern struct ip6_ra_chain *ip6_ra_chain;
extern int ip6_ra_control(struct sock *sk, int sel,
void (*destructor)(struct sock *));
@@ -140,18 +131,13 @@ extern int ip6_ra_control(struct sock *sk, int sel,
extern int ip6_call_ra_chain(struct sk_buff *skb, int sel);
-extern int ip6_dstopt_unknown(struct sk_buff *skb,
- struct ipv6_tlvtype *hdr);
+extern u8 * ipv6_reassembly(struct sk_buff **skb, u8 *nhptr);
-extern int ipv6_routing_header(struct sk_buff **skb,
- struct device *dev,
- __u8 *nhptr,
- struct ipv6_options *opt);
+extern u8 * ipv6_parse_hopopts(struct sk_buff *skb, u8 *nhptr);
-extern int ipv6_reassembly(struct sk_buff **skb,
- struct device *dev,
- __u8 *nhptr,
- struct ipv6_options *opt);
+extern u8 * ipv6_parse_exthdrs(struct sk_buff **skb, u8 *nhptr);
+
+extern struct ipv6_txoptions * ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt);
#define IPV6_FRAG_TIMEOUT (60*HZ) /* 60 seconds */
@@ -226,7 +212,7 @@ extern int ipv6_rcv(struct sk_buff *skb,
extern int ip6_xmit(struct sock *sk,
struct sk_buff *skb,
struct flowi *fl,
- struct ipv6_options *opt);
+ struct ipv6_txoptions *opt);
extern int ip6_nd_hdr(struct sock *sk,
struct sk_buff *skb,
@@ -240,7 +226,7 @@ extern int ip6_build_xmit(struct sock *sk,
const void *data,
struct flowi *fl,
unsigned length,
- struct ipv6_options *opt,
+ struct ipv6_txoptions *opt,
int hlimit, int flags);
/*
@@ -256,28 +242,27 @@ extern int ip6_mc_input(struct sk_buff *skb);
* Extension header (options) processing
*/
-extern int ipv6opt_bld_rthdr(struct sk_buff *skb,
- struct ipv6_options *opt,
- struct in6_addr *addr,
- int proto);
-
-extern int ipv6opt_srcrt_co(struct sockaddr_in6 *sin6,
- int len,
- struct ipv6_options *opt);
-
-extern int ipv6opt_srcrt_cl(struct sockaddr_in6 *sin6,
- int num_addrs,
- struct ipv6_options *opt);
-
-extern int ipv6opt_srt_tosin(struct ipv6_options *opt,
- struct sockaddr_in6 *sin6,
- int len);
-
-extern void ipv6opt_free(struct ipv6_options *opt);
-
-extern struct ipv6_opt_hdr * ipv6_skip_exthdr(struct ipv6_opt_hdr *hdr,
+extern u8 * ipv6_build_nfrag_opts(struct sk_buff *skb,
+ u8 *prev_hdr,
+ struct ipv6_txoptions *opt,
+ struct in6_addr *daddr,
+ u32 jumbolen);
+extern u8 * ipv6_build_frag_opts(struct sk_buff *skb,
+ u8 *prev_hdr,
+ struct ipv6_txoptions *opt);
+extern void ipv6_push_nfrag_opts(struct sk_buff *skb,
+ struct ipv6_txoptions *opt,
+ u8 *proto,
+ struct in6_addr **daddr_p);
+extern void ipv6_push_frag_opts(struct sk_buff *skb,
+ struct ipv6_txoptions *opt,
+ u8 *proto);
+
+extern u8 * ipv6_skip_exthdr(struct ipv6_opt_hdr *hdr,
u8 *nexthdrp, int len);
+extern struct ipv6_txoptions * ipv6_invert_rthdr(struct sock *sk,
+ struct ipv6_rt_hdr *hdr);
/*
diff --git a/include/net/ndisc.h b/include/net/ndisc.h
index 8ca371336..7a51f367a 100644
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -60,12 +60,7 @@ extern int ndisc_init(struct net_proto_family *ops);
extern void ndisc_cleanup(void);
-extern int ndisc_rcv(struct sk_buff *skb,
- struct device *dev,
- struct in6_addr *saddr,
- struct in6_addr *daddr,
- struct ipv6_options *opt,
- unsigned short len);
+extern int ndisc_rcv(struct sk_buff *skb, unsigned long len);
extern void ndisc_send_ns(struct device *dev,
struct neighbour *neigh,
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index de7c7691a..142f7b3c7 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -147,12 +147,12 @@ extern psched_time_t psched_time_base;
#if PSCHED_CLOCK_SOURCE == PSCHED_JIFFIES
-#define PSCHED_WATCHER
+#define PSCHED_WATCHER unsigned long
-extern unsigned long psched_time_mark;
+extern PSCHED_WATCHER psched_time_mark;
#if HZ == 100
-#define PSCHED_JSCALE 7
+#define PSCHED_JSCALE 13
#elif HZ == 1024
#define PSCHED_JSCALE 10
#else
@@ -179,9 +179,9 @@ extern int psched_clock_scale;
#elif defined (__alpha__)
-#define PSCHED_WATCHER
+#define PSCHED_WATCHER u32
-extern u32 psched_time_mark;
+extern PSCHED_WATCHER psched_time_mark;
#define PSCHED_GET_TIME(stamp) \
({ u32 __res; \
diff --git a/include/net/protocol.h b/include/net/protocol.h
index 63d562a98..f6e947b1f 100644
--- a/include/net/protocol.h
+++ b/include/net/protocol.h
@@ -48,17 +48,13 @@ struct inet_protocol
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
struct inet6_protocol
{
- int (*handler)(struct sk_buff *skb, struct device *dev,
- struct in6_addr *saddr,
- struct in6_addr *daddr,
- struct ipv6_options *opt,
- unsigned short len,
- int redo, struct inet6_protocol *protocol);
+ int (*handler)(struct sk_buff *skb,
+ unsigned long len);
- void (*err_handler)(struct sk_buff *skb, int type, int code, unsigned char *buff,
- __u32 info, struct in6_addr *saddr,
- struct in6_addr *daddr,
- struct inet6_protocol *protocol);
+ void (*err_handler)(struct sk_buff *skb, struct ipv6hdr *hdr,
+ struct inet6_skb_parm *opt,
+ int type, int code, unsigned char *buff,
+ __u32 info);
struct inet6_protocol *next;
unsigned char protocol;
unsigned char copy:1;
diff --git a/include/net/rawv6.h b/include/net/rawv6.h
index 36373719f..d54572d1f 100644
--- a/include/net/rawv6.h
+++ b/include/net/rawv6.h
@@ -10,19 +10,17 @@ extern struct sock *raw_v6_htable[RAWV6_HTABLE_SIZE];
extern struct sock *raw_v6_lookup(struct sock *sk, unsigned short num,
struct in6_addr *loc_addr, struct in6_addr *rmt_addr);
-extern int rawv6_rcv(struct sk_buff *skb,
- struct device *dev,
- struct in6_addr *saddr,
- struct in6_addr *daddr,
- struct ipv6_options *opt,
- unsigned short len);
+extern int rawv6_rcv(struct sock *sk,
+ struct sk_buff *skb,
+ unsigned long len);
extern void rawv6_err(struct sock *sk,
+ struct sk_buff *skb,
+ struct ipv6hdr *hdr,
+ struct inet6_skb_parm *opt,
int type, int code,
- unsigned char *buff,
- struct in6_addr *saddr,
- struct in6_addr *daddr);
+ unsigned char *buff, u32 info);
#endif
diff --git a/include/net/route.h b/include/net/route.h
index 624fd233a..bd76d033b 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -27,6 +27,11 @@
#include <net/dst.h>
#include <linux/in_route.h>
#include <linux/rtnetlink.h>
+#include <linux/route.h>
+
+#ifndef __KERNEL__
+#warning This file is not supposed to be used outside of kernel.
+#endif
#define RT_HASH_DIVISOR 256
@@ -36,7 +41,6 @@
*/
#define RT_CACHE_BUBBLE_THRESHOLD (5*HZ)
-#include <linux/route.h>
#define RTO_ONLINK 0x01
#define RTO_TPROXY 0x80000000
@@ -87,7 +91,8 @@ struct rtable
#endif
};
-#ifdef __KERNEL__
+extern struct rtable *rt_hash_table[RT_HASH_DIVISOR];
+
extern void ip_rt_init(void);
extern void ip_rt_redirect(u32 old_gw, u32 dst, u32 new_gw,
u32 src, u8 tos, struct device *dev);
@@ -131,7 +136,4 @@ extern __inline__ int ip_route_connect(struct rtable **rp, u32 dst, u32 src, u32
return ip_route_output(rp, dst, src, tos, oif);
}
-#endif
-
-
#endif /* _ROUTE_H */
diff --git a/include/net/snmp.h b/include/net/snmp.h
index eeeeb6aa2..e38826d0b 100644
--- a/include/net/snmp.h
+++ b/include/net/snmp.h
@@ -52,11 +52,14 @@ struct ipv6_mib
{
unsigned long Ip6InReceives;
unsigned long Ip6InHdrErrors;
+ unsigned long Ip6InTooBigErrors;
+ unsigned long Ip6InNoRoutes;
unsigned long Ip6InAddrErrors;
- unsigned long Ip6ForwDatagrams;
unsigned long Ip6InUnknownProtos;
+ unsigned long Ip6InTruncatedPkts;
unsigned long Ip6InDiscards;
unsigned long Ip6InDelivers;
+ unsigned long Ip6OutForwDatagrams;
unsigned long Ip6OutRequests;
unsigned long Ip6OutDiscards;
unsigned long Ip6OutNoRoutes;
@@ -67,6 +70,8 @@ struct ipv6_mib
unsigned long Ip6FragOKs;
unsigned long Ip6FragFails;
unsigned long Ip6FragCreates;
+ unsigned long Ip6InMcastPkts;
+ unsigned long Ip6OutMcastPkts;
};
struct icmp_mib
@@ -98,6 +103,43 @@ struct icmp_mib
unsigned long IcmpOutAddrMasks;
unsigned long IcmpOutAddrMaskReps;
};
+
+struct icmpv6_mib
+{
+ unsigned long Icmp6InMsgs;
+ unsigned long Icmp6InErrors;
+
+ unsigned long Icmp6InDestUnreachs;
+ unsigned long Icmp6InPktTooBigs;
+ unsigned long Icmp6InTimeExcds;
+ unsigned long Icmp6InParmProblems;
+
+ unsigned long Icmp6InEchos;
+ unsigned long Icmp6InEchoReplies;
+ unsigned long Icmp6InGroupMembQueries;
+ unsigned long Icmp6InGroupMembResponses;
+ unsigned long Icmp6InGroupMembReductions;
+ unsigned long Icmp6InRouterSolicits;
+ unsigned long Icmp6InRouterAdvertisements;
+ unsigned long Icmp6InNeighborSolicits;
+ unsigned long Icmp6InNeighborAdvertisements;
+ unsigned long Icmp6InRedirects;
+
+ unsigned long Icmp6OutMsgs;
+
+ unsigned long Icmp6OutDestUnreachs;
+ unsigned long Icmp6OutPktTooBigs;
+ unsigned long Icmp6OutTimeExcds;
+ unsigned long Icmp6OutParmProblems;
+
+ unsigned long Icmp6OutEchoReplies;
+ unsigned long Icmp6OutRouterSolicits;
+ unsigned long Icmp6OutNeighborSolicits;
+ unsigned long Icmp6OutNeighborAdvertisements;
+ unsigned long Icmp6OutRedirects;
+ unsigned long Icmp6OutGroupMembResponses;
+ unsigned long Icmp6OutGroupMembReductions;
+};
struct tcp_mib
{
@@ -131,6 +173,9 @@ struct linux_mib
unsigned long SyncookiesRecv;
unsigned long SyncookiesFailed;
unsigned long EmbryonicRsts;
+ unsigned long PruneCalled;
+ unsigned long RcvPruned;
+ unsigned long OfoPruned;
};
#endif
diff --git a/include/net/sock.h b/include/net/sock.h
index ed05e12be..ad27511c2 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -87,6 +87,8 @@
#include <asm/atomic.h>
+#define MIN_WRITE_SPACE 2048
+
/* The AF_UNIX specific socket options */
struct unix_opt {
int family;
@@ -134,6 +136,7 @@ struct ipv6_pinfo {
struct in6_addr saddr;
struct in6_addr rcv_saddr;
struct in6_addr daddr;
+ struct in6_addr *daddr_cache;
__u32 flow_lbl;
int hop_limit;
@@ -141,21 +144,28 @@ struct ipv6_pinfo {
int mcast_oif;
__u8 priority;
-
- /* sockopt flags */
-
- __u8 recvsrcrt:1,
- rxinfo:1,
+ /* pktoption flags */
+ union {
+ struct {
+ __u8 srcrt:2,
+ rxinfo:1,
rxhlim:1,
hopopts:1,
dstopts:1,
- mc_loop:1,
- unused:2;
+ authhdr:1,
+ unused:1;
+ } bits;
+ __u8 all;
+ } rxopt;
+
+ /* sockopt flags */
+ __u8 mc_loop:1;
struct ipv6_mc_socklist *ipv6_mc_list;
__u32 dst_cookie;
- struct ipv6_options *opt;
+ struct ipv6_txoptions *opt;
+ struct sk_buff *pktoptions;
};
struct raw6_opt {
@@ -207,6 +217,10 @@ struct tcp_opt {
__u32 snd_wl2; /* Ack sequence for update */
__u32 snd_wnd; /* The window we expect to receive */
__u32 max_window;
+ __u32 pmtu_cookie; /* Last pmtu seen by socket */
+ __u16 mss_cache; /* Cached effective mss, not including SACKS */
+ __u16 mss_clamp; /* Maximal mss, negotiated at connection setup */
+ __u16 ext_header_len; /* Dave, do you allow mw to use this hole? 8) --ANK */
__u8 pending; /* pending events */
__u8 retransmits;
__u32 last_ack_sent; /* last ack we sent */
@@ -226,6 +240,7 @@ struct tcp_opt {
__u32 snd_ssthresh; /* Slow start size threshold */
__u8 dup_acks; /* Consequetive duplicate acks seen from other end */
__u8 delayed_acks;
+ __u16 user_mss; /* mss requested by user in ioctl */
/* Two commonly used timers in both sender and receiver paths. */
struct timer_list retransmit_timer; /* Resend (no ack) */
@@ -252,7 +267,6 @@ struct tcp_opt {
wscale_ok, /* Wscale seen on SYN packet */
sack_ok; /* SACK seen on SYN packet */
char saw_tstamp; /* Saw TIMESTAMP on last packet */
- __u16 in_mss; /* MSS option received from sender */
__u8 snd_wscale; /* Window scaling received from sender */
__u8 rcv_wscale; /* Window scaling to send to receiver */
__u32 rcv_tsval; /* Time stamp value */
@@ -270,6 +284,9 @@ struct tcp_opt {
__u32 urg_seq;
__u32 urg_data;
+ __u32 last_seg_size; /* Size of last incoming segment */
+ __u32 rcv_mss; /* MSS used for delayed ACK decisions */
+
struct open_request *syn_wait_queue;
struct open_request **syn_wait_last;
@@ -350,7 +367,7 @@ struct sock {
unsigned char reuse, /* SO_REUSEADDR setting */
nonagle; /* Disable Nagle algorithm? */
- int sock_readers; /* User count */
+ atomic_t sock_readers; /* User count */
int rcvbuf; /* Size of receive buffer in bytes */
struct wait_queue **sleep; /* Sock wait queue */
@@ -390,12 +407,6 @@ struct sock {
struct proto *prot;
- /* mss is min(mtu, max_window)
- * XXX Fix this, mtu only used in one TCP place and that is it -DaveM
- */
- unsigned short mtu; /* mss negotiated in the syn's */
- unsigned short mss; /* current eff. mss - can change */
- unsigned short user_mss; /* mss requested by user in ioctl */
unsigned short shutdown;
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
@@ -643,42 +654,20 @@ static inline void lock_sock(struct sock *sk)
#if 0
/* debugging code: the test isn't even 100% correct, but it can catch bugs */
/* Note that a double lock is ok in theory - it's just _usually_ a bug */
- if (sk->sock_readers) {
+ if (atomic_read(&sk->sock_readers)) {
__label__ here;
printk("double lock on socket at %p\n", &&here);
here:
}
#endif
-#ifdef __SMP__
- /*
- * This is a very broken bottom half synchronization mechanism.
- * You don't want to know..
- */
- { unsigned long flags;
- save_flags(flags);
- cli();
- sk->sock_readers++;
- restore_flags(flags);
- }
-#else
- sk->sock_readers++;
- barrier();
-#endif
+ atomic_inc(&sk->sock_readers);
+ synchronize_bh();
}
static inline void release_sock(struct sock *sk)
{
barrier();
-#if 0
-/* debugging code: remove me when ok */
- if (sk->sock_readers == 0) {
- __label__ here;
- sk->sock_readers = 1;
- printk("trying to unlock unlocked socket at %p\n", &&here);
-here:
- }
-#endif
- if ((sk->sock_readers = sk->sock_readers-1) == 0)
+ if (atomic_dec_and_test(&sk->sock_readers))
__release_sock(sk);
}
@@ -890,6 +879,26 @@ extern __inline__ int sock_error(struct sock *sk)
return -err;
}
+extern __inline__ unsigned long sock_wspace(struct sock *sk)
+{
+ int amt = 0;
+
+ if (!(sk->shutdown & SEND_SHUTDOWN)) {
+ amt = sk->sndbuf - atomic_read(&sk->wmem_alloc);
+ if (amt < 0)
+ amt = 0;
+ }
+ return amt;
+}
+
+/*
+ * Default write policy as shown to user space via poll/select/SIGIO
+ * Kernel internally doesn't use the MIN_WRITE_SPACE threshold.
+ */
+extern __inline__ int sock_writeable(struct sock *sk)
+{
+ return sock_wspace(sk) >= MIN_WRITE_SPACE;
+}
/*
* Declarations from timer.c
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 225d40ad0..3f305aa7e 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -78,6 +78,7 @@ struct tcp_bind_bucket {
unsigned short flags;
#define TCPB_FLAG_LOCKED 0x0001
#define TCPB_FLAG_FASTREUSE 0x0002
+#define TCPB_FLAG_GOODSOCKNUM 0x0004
struct tcp_bind_bucket *next;
struct sock *owners;
@@ -230,11 +231,8 @@ static __inline__ int tcp_sk_listen_hashfn(struct sock *sk)
return tcp_lhashfn(sk->num);
}
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
-#define NETHDR_SIZE sizeof(struct ipv6hdr)
-#else
-#define NETHDR_SIZE sizeof(struct iphdr) + 40
-#endif
+/* Note, that it is > than ipv6 header */
+#define NETHDR_SIZE (sizeof(struct iphdr) + 40)
/*
* 40 is maximal IP options size
@@ -257,7 +255,6 @@ static __inline__ int tcp_sk_listen_hashfn(struct sock *sk)
#define MIN_WINDOW 2048
#define MAX_ACK_BACKLOG 2
#define MAX_DELAY_ACK 2
-#define MIN_WRITE_SPACE 2048
#define TCP_WINDOW_DIFF 2048
/* urg_data states */
@@ -354,7 +351,7 @@ struct tcp_v4_open_req {
struct tcp_v6_open_req {
struct in6_addr loc_addr;
struct in6_addr rmt_addr;
- struct ipv6_options *opt;
+ struct sk_buff *pktopts;
int iif;
};
#endif
@@ -400,6 +397,13 @@ extern kmem_cache_t *tcp_openreq_cachep;
/*
* Pointers to address related TCP functions
* (i.e. things that depend on the address family)
+ *
+ * BUGGG_FUTURE: all the idea behind this struct is wrong.
+ * It mixes socket frontend with transport function.
+ * With port sharing between IPv6/v4 it gives the only advantage,
+ * only poor IPv6 needs to permanently recheck, that it
+ * is still IPv6 8)8) It must be cleaned up as soon as possible.
+ * --ANK (980802)
*/
struct tcp_func {
@@ -414,7 +418,7 @@ struct tcp_func {
int (*conn_request) (struct sock *sk,
struct sk_buff *skb,
- void *opt, __u32 isn);
+ __u32 isn);
struct sock * (*syn_recv_sock) (struct sock *sk,
struct sk_buff *skb,
@@ -424,6 +428,10 @@ struct tcp_func {
struct sock * (*get_sock) (struct sk_buff *skb,
struct tcphdr *th);
+ __u16 net_header_len;
+
+
+
int (*setsockopt) (struct sock *sk,
int level,
int optname,
@@ -490,22 +498,24 @@ extern int tcp_ioctl(struct sock *sk,
extern int tcp_rcv_state_process(struct sock *sk,
struct sk_buff *skb,
struct tcphdr *th,
- void *opt, __u16 len);
+ unsigned len);
extern int tcp_rcv_established(struct sock *sk,
struct sk_buff *skb,
struct tcphdr *th,
- __u16 len);
+ unsigned len);
extern int tcp_timewait_state_process(struct tcp_tw_bucket *tw,
struct sk_buff *skb,
struct tcphdr *th,
- void *opt, __u16 len);
+ unsigned len);
extern void tcp_close(struct sock *sk,
unsigned long timeout);
extern struct sock * tcp_accept(struct sock *sk, int flags);
extern unsigned int tcp_poll(struct file * file, struct socket *sock, struct poll_table_struct *wait);
+extern void tcp_write_space(struct sock *sk);
+
extern int tcp_getsockopt(struct sock *sk, int level,
int optname, char *optval,
int *optlen);
@@ -536,12 +546,11 @@ extern void tcp_v4_send_check(struct sock *sk,
extern int tcp_v4_conn_request(struct sock *sk,
struct sk_buff *skb,
- void *ptr, __u32 isn);
+ __u32 isn);
extern struct sock * tcp_create_openreq_child(struct sock *sk,
struct open_request *req,
- struct sk_buff *skb,
- int mss);
+ struct sk_buff *skb);
extern struct sock * tcp_v4_syn_recv_sock(struct sock *sk,
struct sk_buff *skb,
@@ -628,30 +637,25 @@ struct tcp_sl_timer {
extern struct tcp_sl_timer tcp_slt_array[TCP_SLT_MAX];
+extern int tcp_sync_mss(struct sock *sk, u32 pmtu);
+
/* Compute the current effective MSS, taking SACKs and IP options,
* and even PMTU discovery events into account.
*/
+
static __inline__ unsigned int tcp_current_mss(struct sock *sk)
{
struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
struct dst_entry *dst = sk->dst_cache;
- unsigned int mss_now = sk->mss;
+ int mss_now = tp->mss_cache;
- if(dst && (sk->mtu < dst->pmtu)) {
- unsigned int mss_distance = (sk->mtu - sk->mss);
-
- /* PMTU discovery event has occurred. */
- sk->mtu = dst->pmtu;
- mss_now = sk->mss = sk->mtu - mss_distance;
- }
+ if (dst && dst->pmtu != tp->pmtu_cookie)
+ mss_now = tcp_sync_mss(sk, dst->pmtu);
if(tp->sack_ok && tp->num_sacks)
mss_now -= (TCPOLEN_SACK_BASE_ALIGNED +
(tp->num_sacks * TCPOLEN_SACK_PERBLOCK));
- if(sk->opt)
- mss_now -= sk->opt->optlen;
-
- return mss_now;
+ return mss_now > 8 ? mss_now : 8;
}
/* Compute the actual receive window we are currently advertising.
@@ -715,7 +719,12 @@ extern __inline__ int tcp_raise_window(struct sock *sk)
* skbuff.h:skbuff->cb[xxx] size appropriately.
*/
struct tcp_skb_cb {
- struct inet_skb_parm header; /* For incoming frames */
+ union {
+ struct inet_skb_parm h4;
+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
+ struct inet6_skb_parm h6;
+#endif
+ } header; /* For incoming frames */
__u32 seq; /* Starting sequence number */
__u32 end_seq; /* SEQ + FIN + SYN + datalen */
unsigned long when; /* used to compute rtt's */
@@ -787,7 +796,7 @@ static __inline__ int tcp_snd_test(struct sock *sk, struct sk_buff *skb)
*
* Don't use the nagle rule for urgent data.
*/
- if (!sk->nonagle && skb->len < (sk->mss >> 1) && tp->packets_out &&
+ if (!sk->nonagle && skb->len < (tp->mss_cache >> 1) && tp->packets_out &&
!(TCP_SKB_CB(skb)->flags & TCPCB_FLAG_URG))
nagle_check = 0;
@@ -913,8 +922,6 @@ extern __inline__ void tcp_syn_build_options(__u32 *ptr, int mss, int ts, int sa
* SACKs don't matter, we never delay an ACK when we
* have any of those going out.
*/
- if(ts)
- mss += TCPOLEN_TSTAMP_ALIGNED;
*ptr++ = htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) | mss);
if (ts) {
if(sack)
diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h
index 45bdcc59d..b697d7c3c 100644
--- a/include/net/transp_v6.h
+++ b/include/net/transp_v6.h
@@ -28,7 +28,7 @@ extern int datagram_recv_ctl(struct sock *sk,
extern int datagram_send_ctl(struct msghdr *msg,
int *oif,
struct in6_addr **src_addr,
- struct ipv6_options *opt,
+ struct ipv6_txoptions *opt,
int *hlimit);
#define LOOPBACK4_IPV6 __constant_htonl(0x7f000006)
@@ -38,6 +38,8 @@ extern int datagram_send_ctl(struct msghdr *msg,
*/
extern struct tcp_func ipv4_specific;
+extern int inet6_destroy_sock(struct sock *sk);
+
#endif
#endif