diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1998-09-19 19:15:08 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1998-09-19 19:15:08 +0000 |
commit | 03ba4131783cc9e872f8bb26a03f15bc11f27564 (patch) | |
tree | 88db8dba75ae06ba3bad08e42c5e52efc162535c /include/net | |
parent | 257730f99381dd26e10b832fce4c94cae7ac1176 (diff) |
- Merge with Linux 2.1.121.
- Bugfixes.
Diffstat (limited to 'include/net')
-rw-r--r-- | include/net/dst.h | 1 | ||||
-rw-r--r-- | include/net/flow.h | 4 | ||||
-rw-r--r-- | include/net/ip6_fib.h | 58 | ||||
-rw-r--r-- | include/net/ip6_route.h | 41 | ||||
-rw-r--r-- | include/net/ip_fib.h | 2 | ||||
-rw-r--r-- | include/net/ipv6.h | 121 | ||||
-rw-r--r-- | include/net/ndisc.h | 7 | ||||
-rw-r--r-- | include/net/pkt_sched.h | 10 | ||||
-rw-r--r-- | include/net/protocol.h | 16 | ||||
-rw-r--r-- | include/net/rawv6.h | 16 | ||||
-rw-r--r-- | include/net/route.h | 12 | ||||
-rw-r--r-- | include/net/snmp.h | 47 | ||||
-rw-r--r-- | include/net/sock.h | 93 | ||||
-rw-r--r-- | include/net/tcp.h | 67 | ||||
-rw-r--r-- | include/net/transp_v6.h | 4 |
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 |