diff options
| author | Alexey Kuznetsov <kuznet@mops.inr.ac.ru> | 2002-10-15 05:01:33 -0700 |
|---|---|---|
| committer | David S. Miller <davem@nuts.ninka.net> | 2002-10-15 05:01:33 -0700 |
| commit | a64cda042232d4a02f771e65e304c0f064e92655 (patch) | |
| tree | 881af2edc98d5c3906be1dd73eb1664c3f817920 /include | |
| parent | 08e3418bc1a6ff0c8cd9481a39e3ef080a31e908 (diff) | |
[NET]: Prepare for zerocopy NFS and IPSEC.
- Import va10-hwchecksum-2.5.36.patch
- Import va11-udpsendfile-2.5.36.patch
- Implement new encapsulation friendly ipv4 output path.
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/ip.h | 16 | ||||
| -rw-r--r-- | include/linux/skbuff.h | 9 | ||||
| -rw-r--r-- | include/linux/tcp.h | 2 | ||||
| -rw-r--r-- | include/linux/udp.h | 31 | ||||
| -rw-r--r-- | include/net/dst.h | 56 | ||||
| -rw-r--r-- | include/net/ip.h | 16 | ||||
| -rw-r--r-- | include/net/sock.h | 2 | ||||
| -rw-r--r-- | include/net/tcp.h | 2 | ||||
| -rw-r--r-- | include/net/udp.h | 2 |
9 files changed, 125 insertions, 11 deletions
diff --git a/include/linux/ip.h b/include/linux/ip.h index 3ba8e804b0d8..e612f5be9cab 100644 --- a/include/linux/ip.h +++ b/include/linux/ip.h @@ -137,8 +137,24 @@ struct inet_opt { int mc_index; /* Multicast device index */ __u32 mc_addr; struct ip_mc_socklist *mc_list; /* Group array */ + struct page *sndmsg_page; /* Cached page for sendmsg */ + u32 sndmsg_off; /* Cached offset for sendmsg */ + /* + * Following members are used to retain the infomation to build + * an ip header on each ip fragmentation while the socket is corked. + */ + struct { + unsigned int flags; + unsigned int fragsize; + struct ip_options *opt; + struct rtable *rt; + int length; /* Total length of all frames */ + u32 addr; + } cork; }; +#define IPCORK_OPT 1 /* ip-options has been held in ipcork.opt */ + struct ipv6_pinfo; /* WARNING: don't change the layout of the members in inet_sock! */ diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 9b6e6ad08e2a..26467b154cdd 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -765,6 +765,15 @@ static inline int skb_headlen(const struct sk_buff *skb) return skb->len - skb->data_len; } +static inline int skb_pagelen(const struct sk_buff *skb) +{ + int i, len = 0; + + for (i = (int)skb_shinfo(skb)->nr_frags - 1; i >= 0; i--) + len += skb_shinfo(skb)->frags[i].size; + return len + skb_headlen(skb); +} + #define SKB_PAGE_ASSERT(skb) do { if (skb_shinfo(skb)->nr_frags) \ BUG(); } while (0) #define SKB_FRAG_ASSERT(skb) do { if (skb_shinfo(skb)->frag_list) \ diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 91b66d7ab004..3e43be408a06 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -285,8 +285,6 @@ struct tcp_opt { struct tcp_func *af_specific; /* Operations which are AF_INET{4,6} specific */ struct sk_buff *send_head; /* Front of stuff to transmit */ - struct page *sndmsg_page; /* Cached page for sendmsg */ - u32 sndmsg_off; /* Cached offset for sendmsg */ __u32 rcv_wnd; /* Current receiver window */ __u32 rcv_wup; /* rcv_nxt on last window update sent */ diff --git a/include/linux/udp.h b/include/linux/udp.h index ab75a1e815db..5bdb970a1b69 100644 --- a/include/linux/udp.h +++ b/include/linux/udp.h @@ -17,6 +17,9 @@ #ifndef _LINUX_UDP_H #define _LINUX_UDP_H +#include <asm/byteorder.h> +#include <net/sock.h> +#include <linux/ip.h> struct udphdr { __u16 source; @@ -25,5 +28,33 @@ struct udphdr { __u16 check; }; +/* UDP socket options */ +#define UDP_CORK 1 /* Never send partially complete segments */ + +struct udp_opt { + int pending; /* Any pending frames ? */ + unsigned int corkflag; /* Cork is required */ + /* + * Following members retains the infomation to create a UDP header + * when the socket is uncorked. + */ + u32 saddr; /* source address */ + u32 daddr; /* destination address */ + __u16 sport; /* source port */ + __u16 dport; /* destination port */ + __u16 len; /* total length of pending frames */ +}; + +/* WARNING: don't change the layout of the members in udp_sock! */ +struct udp_sock { + struct sock sk; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + struct ipv6_pinfo *pinet6; +#endif + struct inet_opt inet; + struct udp_opt udp; +}; + +#define udp_sk(__sk) (&((struct udp_sock *)__sk)->udp) #endif /* _LINUX_UDP_H */ diff --git a/include/net/dst.h b/include/net/dst.h index d81eb07bbd5b..c27a2e6f497c 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -29,6 +29,7 @@ struct dst_entry struct dst_entry *next; atomic_t __refcnt; /* client references */ int __use; + struct dst_entry *child; struct net_device *dev; int obsolete; int flags; @@ -36,6 +37,8 @@ struct dst_entry unsigned long lastuse; unsigned long expires; + unsigned header_len; /* more space at head required */ + unsigned mxlock; unsigned pmtu; unsigned window; @@ -108,18 +111,30 @@ void dst_release(struct dst_entry * dst) atomic_dec(&dst->__refcnt); } +/* Children define the path of the packet through the + * Linux networking. Thus, destinations are stackable. + */ + +static inline struct dst_entry *dst_pop(struct dst_entry *dst) +{ + struct dst_entry *child = dst_clone(dst->child); + + dst_release(dst); + return child; +} + extern void * dst_alloc(struct dst_ops * ops); extern void __dst_free(struct dst_entry * dst); -extern void dst_destroy(struct dst_entry * dst); +extern struct dst_entry *dst_destroy(struct dst_entry * dst); -static inline -void dst_free(struct dst_entry * dst) +static inline void dst_free(struct dst_entry * dst) { if (dst->obsolete > 1) return; if (!atomic_read(&dst->__refcnt)) { - dst_destroy(dst); - return; + dst = dst_destroy(dst); + if (!dst) + return; } __dst_free(dst); } @@ -155,6 +170,37 @@ static inline void dst_set_expires(struct dst_entry *dst, int timeout) dst->expires = expires; } +/* Output packet to network from transport. */ +static inline int dst_output(struct sk_buff *skb) +{ + int err; + + for (;;) { + err = skb->dst->output(skb); + + if (likely(err == 0)) + return err; + if (unlikely(err != NET_XMIT_BYPASS)) + return err; + } +} + +/* Input packet from network to transport. */ +static inline int dst_input(struct sk_buff *skb) +{ + int err; + + for (;;) { + err = skb->dst->input(skb); + + if (likely(err == 0)) + return err; + /* Oh, Jamal... Seems, I will not forgive you this mess. :-) */ + if (unlikely(err != NET_XMIT_BYPASS)) + return err; + } +} + extern void dst_init(void); #endif diff --git a/include/net/ip.h b/include/net/ip.h index 64f3ca87c050..36de9ce94756 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -102,12 +102,26 @@ extern int ip_build_xmit(struct sock *sk, int getfrag (const void *, char *, unsigned int, - unsigned int), + unsigned int, + struct sk_buff *), const void *frag, unsigned length, struct ipcm_cookie *ipc, struct rtable *rt, int flags); +extern int ip_append_data(struct sock *sk, + int getfrag(void *from, char *to, int offset, int len, + int odd, struct sk_buff *skb), + void *from, int len, int protolen, + struct ipcm_cookie *ipc, + struct rtable *rt, + unsigned int flags); +extern int generic_getfrag(void *from, char *to, int offset, int len, int odd, struct sk_buff *skb); +extern ssize_t ip_append_page(struct sock *sk, struct page *page, + int offset, size_t size, int flags); +extern int ip_push_pending_frames(struct sock *sk); +extern void ip_flush_pending_frames(struct sock *sk); + /* * Map a multicast IP onto multicast MAC for type Token Ring. diff --git a/include/net/sock.h b/include/net/sock.h index d3706f8ee02c..7240f39e7cf9 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -249,6 +249,8 @@ struct proto { struct msghdr *msg, int len, int noblock, int flags, int *addr_len); + int (*sendpage)(struct sock *sk, struct page *page, + int offset, size_t size, int flags); int (*bind)(struct sock *sk, struct sockaddr *uaddr, int addr_len); diff --git a/include/net/tcp.h b/include/net/tcp.h index 5b84f5563144..6683b8379936 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -1851,7 +1851,7 @@ static inline void tcp_v4_setup_caps(struct sock *sk, struct dst_entry *dst) { sk->route_caps = dst->dev->features; if (sk->route_caps & NETIF_F_TSO) { - if (sk->no_largesend) + if (sk->no_largesend || dst->header_len) sk->route_caps &= ~NETIF_F_TSO; } } diff --git a/include/net/udp.h b/include/net/udp.h index 7e46b4fb8c0b..63a24bdd3b06 100644 --- a/include/net/udp.h +++ b/include/net/udp.h @@ -76,6 +76,4 @@ extern struct udp_mib udp_statistics[NR_CPUS*2]; #define UDP_INC_STATS_BH(field) SNMP_INC_STATS_BH(udp_statistics, field) #define UDP_INC_STATS_USER(field) SNMP_INC_STATS_USER(udp_statistics, field) -#define udp_sock inet_sock - #endif /* _UDP_H */ |
