diff options
author | David Howells <dhowells@redhat.com> | 2006-12-05 17:37:56 +0300 |
---|---|---|
committer | David Howells <dhowells@warthog.cambridge.redhat.com> | 2006-12-05 17:37:56 +0300 |
commit | 4c1ac1b49122b805adfa4efc620592f68dccf5db (patch) | |
tree | 87557f4bc2fd4fe65b7570489c2f610c45c0adcd /include/net | |
parent | c4028958b6ecad064b1a6303a6a5906d4fe48d73 (diff) | |
parent | d916faace3efc0bf19fe9a615a1ab8fa1a24cd93 (diff) | |
download | linux-4c1ac1b49122b805adfa4efc620592f68dccf5db.tar.xz |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts:
drivers/infiniband/core/iwcm.c
drivers/net/chelsio/cxgb2.c
drivers/net/wireless/bcm43xx/bcm43xx_main.c
drivers/net/wireless/prism54/islpci_eth.c
drivers/usb/core/hub.h
drivers/usb/input/hid-core.c
net/core/netpoll.c
Fix up merge failures with Linus's head and fix new compilation failures.
Signed-Off-By: David Howells <dhowells@redhat.com>
Diffstat (limited to 'include/net')
65 files changed, 1442 insertions, 473 deletions
diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 44f1b673f916..88df8fc814e4 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -35,9 +35,9 @@ struct prefix_info { #else #error "Please fix <asm/byteorder.h>" #endif - __u32 valid; - __u32 prefered; - __u32 reserved2; + __be32 valid; + __be32 prefered; + __be32 reserved2; struct in6_addr prefix; }; @@ -183,7 +183,7 @@ static __inline__ u8 ipv6_addr_hash(const struct in6_addr *addr) * This will include the IEEE address token on links that support it. */ - word = addr->s6_addr32[2] ^ addr->s6_addr32[3]; + word = (__force u32)(addr->s6_addr32[2] ^ addr->s6_addr32[3]); word ^= (word >> 16); word ^= (word >> 8); diff --git a/include/net/arp.h b/include/net/arp.h index 6a3d9a7d302b..f02664568600 100644 --- a/include/net/arp.h +++ b/include/net/arp.h @@ -16,7 +16,7 @@ extern void arp_send(int type, int ptype, __be32 dest_ip, struct net_device *dev, __be32 src_ip, unsigned char *dest_hw, unsigned char *src_hw, unsigned char *th); extern int arp_bind_neighbour(struct dst_entry *dst); -extern int arp_mc_map(u32 addr, u8 *haddr, struct net_device *dev, int dir); +extern int arp_mc_map(__be32 addr, u8 *haddr, struct net_device *dev, int dir); extern void arp_ifdown(struct net_device *dev); extern struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip, diff --git a/include/net/atmclip.h b/include/net/atmclip.h index 90fcc98e676f..b5a51a7bb364 100644 --- a/include/net/atmclip.h +++ b/include/net/atmclip.h @@ -36,7 +36,7 @@ struct clip_vcc { struct atmarp_entry { - u32 ip; /* IP address */ + __be32 ip; /* IP address */ struct clip_vcc *vccs; /* active VCCs; NULL if resolution is pending */ unsigned long expires; /* entry expiration time */ diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h index 89d743cfdfdf..3c563f02907c 100644 --- a/include/net/bluetooth/rfcomm.h +++ b/include/net/bluetooth/rfcomm.h @@ -124,7 +124,7 @@ struct rfcomm_pn { u8 flow_ctrl; u8 priority; u8 ack_timer; - u16 mtu; + __le16 mtu; u8 max_retrans; u8 credits; } __attribute__ ((packed)); @@ -136,7 +136,7 @@ struct rfcomm_rpn { u8 flow_ctrl; u8 xon_char; u8 xoff_char; - u16 param_mask; + __le16 param_mask; } __attribute__ ((packed)); struct rfcomm_rls { diff --git a/include/net/checksum.h b/include/net/checksum.h index e3ea7cc2c728..124246172a88 100644 --- a/include/net/checksum.h +++ b/include/net/checksum.h @@ -27,8 +27,8 @@ #ifndef _HAVE_ARCH_COPY_AND_CSUM_FROM_USER static inline -unsigned int csum_and_copy_from_user (const unsigned char __user *src, unsigned char *dst, - int len, int sum, int *err_ptr) +__wsum csum_and_copy_from_user (const void __user *src, void *dst, + int len, __wsum sum, int *err_ptr) { if (access_ok(VERIFY_READ, src, len)) return csum_partial_copy_from_user(src, dst, len, sum, err_ptr); @@ -41,8 +41,8 @@ unsigned int csum_and_copy_from_user (const unsigned char __user *src, unsigned #endif #ifndef HAVE_CSUM_COPY_USER -static __inline__ unsigned int csum_and_copy_to_user -(const unsigned char *src, unsigned char __user *dst, int len, unsigned int sum, int *err_ptr) +static __inline__ __wsum csum_and_copy_to_user +(const void *src, void __user *dst, int len, __wsum sum, int *err_ptr) { sum = csum_partial(src, len, sum); @@ -53,35 +53,44 @@ static __inline__ unsigned int csum_and_copy_to_user if (len) *err_ptr = -EFAULT; - return -1; /* invalid checksum */ + return (__force __wsum)-1; /* invalid checksum */ } #endif -static inline unsigned int csum_add(unsigned int csum, unsigned int addend) +static inline __wsum csum_add(__wsum csum, __wsum addend) { - csum += addend; - return csum + (csum < addend); + u32 res = (__force u32)csum; + res += (__force u32)addend; + return (__force __wsum)(res + (res < (__force u32)addend)); } -static inline unsigned int csum_sub(unsigned int csum, unsigned int addend) +static inline __wsum csum_sub(__wsum csum, __wsum addend) { return csum_add(csum, ~addend); } -static inline unsigned int -csum_block_add(unsigned int csum, unsigned int csum2, int offset) +static inline __wsum +csum_block_add(__wsum csum, __wsum csum2, int offset) { + u32 sum = (__force u32)csum2; if (offset&1) - csum2 = ((csum2&0xFF00FF)<<8)+((csum2>>8)&0xFF00FF); - return csum_add(csum, csum2); + sum = ((sum&0xFF00FF)<<8)+((sum>>8)&0xFF00FF); + return csum_add(csum, (__force __wsum)sum); } -static inline unsigned int -csum_block_sub(unsigned int csum, unsigned int csum2, int offset) +static inline __wsum +csum_block_sub(__wsum csum, __wsum csum2, int offset) { + u32 sum = (__force u32)csum2; if (offset&1) - csum2 = ((csum2&0xFF00FF)<<8)+((csum2>>8)&0xFF00FF); - return csum_sub(csum, csum2); + sum = ((sum&0xFF00FF)<<8)+((sum>>8)&0xFF00FF); + return csum_sub(csum, (__force __wsum)sum); } +static inline __wsum csum_unfold(__sum16 n) +{ + return (__force __wsum)n; +} + +#define CSUM_MANGLED_0 ((__force __sum16)0xffff) #endif diff --git a/include/net/cipso_ipv4.h b/include/net/cipso_ipv4.h index 718b4d9c891f..4c9522c5178f 100644 --- a/include/net/cipso_ipv4.h +++ b/include/net/cipso_ipv4.h @@ -58,10 +58,10 @@ #define CIPSO_V4_MAP_PASS 2 /* limits */ -#define CIPSO_V4_MAX_REM_LVLS 256 +#define CIPSO_V4_MAX_REM_LVLS 255 #define CIPSO_V4_INV_LVL 0x80000000 #define CIPSO_V4_MAX_LOC_LVLS (CIPSO_V4_INV_LVL - 1) -#define CIPSO_V4_MAX_REM_CATS 65536 +#define CIPSO_V4_MAX_REM_CATS 65534 #define CIPSO_V4_INV_CAT 0x80000000 #define CIPSO_V4_MAX_LOC_CATS (CIPSO_V4_INV_CAT - 1) diff --git a/include/net/dsfield.h b/include/net/dsfield.h index a79c9e075f7f..eb65bf2e2502 100644 --- a/include/net/dsfield.h +++ b/include/net/dsfield.h @@ -20,14 +20,14 @@ static inline __u8 ipv4_get_dsfield(struct iphdr *iph) static inline __u8 ipv6_get_dsfield(struct ipv6hdr *ipv6h) { - return ntohs(*(__u16 *) ipv6h) >> 4; + return ntohs(*(__be16 *) ipv6h) >> 4; } static inline void ipv4_change_dsfield(struct iphdr *iph,__u8 mask, __u8 value) { - __u32 check = ntohs(iph->check); + __u32 check = ntohs((__force __be16)iph->check); __u8 dsfield; dsfield = (iph->tos & mask) | value; @@ -35,7 +35,7 @@ static inline void ipv4_change_dsfield(struct iphdr *iph,__u8 mask, if ((check+1) >> 16) check = (check+1) & 0xffff; check -= dsfield; check += check >> 16; /* adjust carry */ - iph->check = htons(check); + iph->check = (__force __sum16)htons(check); iph->tos = dsfield; } @@ -45,9 +45,9 @@ static inline void ipv6_change_dsfield(struct ipv6hdr *ipv6h,__u8 mask, { __u16 tmp; - tmp = ntohs(*(__u16 *) ipv6h); + tmp = ntohs(*(__be16 *) ipv6h); tmp = (tmp & ((mask << 4) | 0xf00f)) | (value << 4); - *(__u16 *) ipv6h = htons(tmp); + *(__be16 *) ipv6h = htons(tmp); } diff --git a/include/net/fib_rules.h b/include/net/fib_rules.h index 8e2f473d3e82..bc3c26494c3d 100644 --- a/include/net/fib_rules.h +++ b/include/net/fib_rules.h @@ -13,6 +13,8 @@ struct fib_rule atomic_t refcnt; int ifindex; char ifname[IFNAMSIZ]; + u32 mark; + u32 mark_mask; u32 pref; u32 flags; u32 table; @@ -50,6 +52,7 @@ struct fib_rules_ops struct nlmsghdr *, struct fib_rule_hdr *); u32 (*default_pref)(void); + size_t (*nlmsg_payload)(struct fib_rule *); int nlgroup; struct nla_policy *policy; @@ -57,6 +60,13 @@ struct fib_rules_ops struct module *owner; }; +#define FRA_GENERIC_POLICY \ + [FRA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ - 1 }, \ + [FRA_PRIORITY] = { .type = NLA_U32 }, \ + [FRA_FWMARK] = { .type = NLA_U32 }, \ + [FRA_FWMASK] = { .type = NLA_U32 }, \ + [FRA_TABLE] = { .type = NLA_U32 } + static inline void fib_rule_get(struct fib_rule *rule) { atomic_inc(&rule->refcnt); diff --git a/include/net/flow.h b/include/net/flow.h index 5cda27cd9deb..ce4b10d8b412 100644 --- a/include/net/flow.h +++ b/include/net/flow.h @@ -13,12 +13,12 @@ struct flowi { int oif; int iif; + __u32 mark; union { struct { __be32 daddr; __be32 saddr; - __u32 fwmark; __u8 tos; __u8 scope; } ip4_u; @@ -26,28 +26,23 @@ struct flowi { struct { struct in6_addr daddr; struct in6_addr saddr; - __u32 fwmark; - __u32 flowlabel; + __be32 flowlabel; } ip6_u; struct { __le16 daddr; __le16 saddr; - __u32 fwmark; __u8 scope; } dn_u; } nl_u; #define fld_dst nl_u.dn_u.daddr #define fld_src nl_u.dn_u.saddr -#define fld_fwmark nl_u.dn_u.fwmark #define fld_scope nl_u.dn_u.scope #define fl6_dst nl_u.ip6_u.daddr #define fl6_src nl_u.ip6_u.saddr -#define fl6_fwmark nl_u.ip6_u.fwmark #define fl6_flowlabel nl_u.ip6_u.flowlabel #define fl4_dst nl_u.ip4_u.daddr #define fl4_src nl_u.ip4_u.saddr -#define fl4_fwmark nl_u.ip4_u.fwmark #define fl4_tos nl_u.ip4_u.tos #define fl4_scope nl_u.ip4_u.scope diff --git a/include/net/genetlink.h b/include/net/genetlink.h index b619314218a6..adff4c898d50 100644 --- a/include/net/genetlink.h +++ b/include/net/genetlink.h @@ -53,6 +53,7 @@ struct genl_info * @policy: attribute validation policy * @doit: standard command callback * @dumpit: callback for dumpers + * @done: completion callback for dumps * @ops_list: operations list */ struct genl_ops @@ -64,6 +65,7 @@ struct genl_ops struct genl_info *info); int (*dumpit)(struct sk_buff *skb, struct netlink_callback *cb); + int (*done)(struct netlink_callback *cb); struct list_head ops_list; }; @@ -79,34 +81,51 @@ extern struct sock *genl_sock; * @skb: socket buffer holding the message * @pid: netlink pid the message is addressed to * @seq: sequence number (usually the one of the sender) - * @type: netlink message type - * @hdrlen: length of the user specific header + * @family: generic netlink family * @flags netlink message flags * @cmd: generic netlink command - * @version: version * * Returns pointer to user specific header */ static inline void *genlmsg_put(struct sk_buff *skb, u32 pid, u32 seq, - int type, int hdrlen, int flags, - u8 cmd, u8 version) + struct genl_family *family, int flags, u8 cmd) { struct nlmsghdr *nlh; struct genlmsghdr *hdr; - nlh = nlmsg_put(skb, pid, seq, type, GENL_HDRLEN + hdrlen, flags); + nlh = nlmsg_put(skb, pid, seq, family->id, GENL_HDRLEN + + family->hdrsize, flags); if (nlh == NULL) return NULL; hdr = nlmsg_data(nlh); hdr->cmd = cmd; - hdr->version = version; + hdr->version = family->version; hdr->reserved = 0; return (char *) hdr + GENL_HDRLEN; } /** + * genlmsg_put_reply - Add generic netlink header to a reply message + * @skb: socket buffer holding the message + * @info: receiver info + * @family: generic netlink family + * @flags: netlink message flags + * @cmd: generic netlink command + * + * Returns pointer to user specific header + */ +static inline void *genlmsg_put_reply(struct sk_buff *skb, + struct genl_info *info, + struct genl_family *family, + int flags, u8 cmd) +{ + return genlmsg_put(skb, info->snd_pid, info->snd_seq, family, + flags, cmd); +} + +/** * genlmsg_end - Finalize a generic netlink message * @skb: socket buffer the message is stored in * @hdr: user specific header @@ -150,6 +169,16 @@ static inline int genlmsg_unicast(struct sk_buff *skb, u32 pid) } /** + * genlmsg_reply - reply to a request + * @skb: netlink message to be sent back + * @info: receiver information + */ +static inline int genlmsg_reply(struct sk_buff *skb, struct genl_info *info) +{ + return genlmsg_unicast(skb, info->snd_pid); +} + +/** * gennlmsg_data - head of message payload * @gnlh: genetlink messsage header */ @@ -187,4 +216,15 @@ static inline int genlmsg_total_size(int payload) return NLMSG_ALIGN(genlmsg_msg_size(payload)); } +/** + * genlmsg_new - Allocate a new generic netlink message + * @payload: size of the message payload + * @flags: the type of memory to allocate. + */ +static inline struct sk_buff *genlmsg_new(size_t payload, gfp_t flags) +{ + return nlmsg_new(genlmsg_total_size(payload), flags); +} + + #endif /* __NET_GENERIC_NETLINK_H */ diff --git a/include/net/ieee80211.h b/include/net/ieee80211.h index b174ebb277a9..e6af381e206d 100644 --- a/include/net/ieee80211.h +++ b/include/net/ieee80211.h @@ -1037,6 +1037,10 @@ struct ieee80211_device { /* host performs multicast decryption */ int host_mc_decrypt; + /* host should strip IV and ICV from protected frames */ + /* meaningful only when hardware decryption is being used */ + int host_strip_iv_icv; + int host_open_frag; int host_build_iv; int ieee802_1x; /* is IEEE 802.1X used */ @@ -1076,6 +1080,8 @@ struct ieee80211_device { int perfect_rssi; int worst_rssi; + u16 prev_seq_ctl; /* used to drop duplicate frames */ + /* Callback functions */ void (*set_security) (struct net_device * dev, struct ieee80211_security * sec); diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h index 34489c13c119..3ec7d07346d6 100644 --- a/include/net/if_inet6.h +++ b/include/net/if_inet6.h @@ -152,6 +152,7 @@ struct ifacaddr6 struct ipv6_devstat { struct proc_dir_entry *proc_dir_entry; + DEFINE_SNMP_STAT(struct ipstats_mib, ipv6); DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6); }; diff --git a/include/net/inet6_connection_sock.h b/include/net/inet6_connection_sock.h index b33b438bffcc..16aa96a6a53b 100644 --- a/include/net/inet6_connection_sock.h +++ b/include/net/inet6_connection_sock.h @@ -27,7 +27,7 @@ extern int inet6_csk_bind_conflict(const struct sock *sk, extern struct request_sock *inet6_csk_search_req(const struct sock *sk, struct request_sock ***prevp, - const __u16 rport, + const __be16 rport, const struct in6_addr *raddr, const struct in6_addr *laddr, const int iif); @@ -38,5 +38,5 @@ extern void inet6_csk_reqsk_queue_hash_add(struct sock *sk, extern void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr); -extern int inet6_csk_xmit(struct sk_buff *skb, int ipfragok); +extern int inet6_csk_xmit(struct sk_buff *skb, struct sock *sk, int ipfragok); #endif /* _INET6_CONNECTION_SOCK_H */ diff --git a/include/net/inet6_hashtables.h b/include/net/inet6_hashtables.h index bc6a71dce984..c28e424f53d9 100644 --- a/include/net/inet6_hashtables.h +++ b/include/net/inet6_hashtables.h @@ -26,11 +26,11 @@ struct inet_hashinfo; /* I have no idea if this is a good hash for v6 or not. -DaveM */ static inline unsigned int inet6_ehashfn(const struct in6_addr *laddr, const u16 lport, - const struct in6_addr *faddr, const u16 fport) + const struct in6_addr *faddr, const __be16 fport) { - unsigned int hashent = (lport ^ fport); + unsigned int hashent = (lport ^ (__force u16)fport); - hashent ^= (laddr->s6_addr32[3] ^ faddr->s6_addr32[3]); + hashent ^= (__force u32)(laddr->s6_addr32[3] ^ faddr->s6_addr32[3]); hashent ^= hashent >> 16; hashent ^= hashent >> 8; return hashent; @@ -43,7 +43,7 @@ static inline int inet6_sk_ehashfn(const struct sock *sk) const struct in6_addr *laddr = &np->rcv_saddr; const struct in6_addr *faddr = &np->daddr; const __u16 lport = inet->num; - const __u16 fport = inet->dport; + const __be16 fport = inet->dport; return inet6_ehashfn(laddr, lport, faddr, fport); } @@ -57,7 +57,7 @@ extern void __inet6_hash(struct inet_hashinfo *hashinfo, struct sock *sk); */ extern struct sock *__inet6_lookup_established(struct inet_hashinfo *hashinfo, const struct in6_addr *saddr, - const u16 sport, + const __be16 sport, const struct in6_addr *daddr, const u16 hnum, const int dif); @@ -69,7 +69,7 @@ extern struct sock *inet6_lookup_listener(struct inet_hashinfo *hashinfo, static inline struct sock *__inet6_lookup(struct inet_hashinfo *hashinfo, const struct in6_addr *saddr, - const u16 sport, + const __be16 sport, const struct in6_addr *daddr, const u16 hnum, const int dif) @@ -83,8 +83,8 @@ static inline struct sock *__inet6_lookup(struct inet_hashinfo *hashinfo, } extern struct sock *inet6_lookup(struct inet_hashinfo *hashinfo, - const struct in6_addr *saddr, const u16 sport, - const struct in6_addr *daddr, const u16 dport, + const struct in6_addr *saddr, const __be16 sport, + const struct in6_addr *daddr, const __be16 dport, const int dif); #endif /* defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) */ #endif /* _INET6_HASHTABLES_H */ diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index 0bcf9f237e1f..cccea051e922 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h @@ -36,7 +36,8 @@ struct tcp_congestion_ops; * (i.e. things that depend on the address family) */ struct inet_connection_sock_af_ops { - int (*queue_xmit)(struct sk_buff *skb, int ipfragok); + int (*queue_xmit)(struct sk_buff *skb, struct sock *sk, + int ipfragok); void (*send_check)(struct sock *sk, int len, struct sk_buff *skb); int (*rebuild_header)(struct sock *sk); @@ -45,7 +46,8 @@ struct inet_connection_sock_af_ops { struct request_sock *req, struct dst_entry *dst); int (*remember_stamp)(struct sock *sk); - __u16 net_header_len; + u16 net_header_len; + u16 sockaddr_len; int (*setsockopt)(struct sock *sk, int level, int optname, char __user *optval, int optlen); int (*getsockopt)(struct sock *sk, int level, int optname, @@ -57,7 +59,6 @@ struct inet_connection_sock_af_ops { int level, int optname, char __user *optval, int __user *optlen); void (*addr2sockaddr)(struct sock *sk, struct sockaddr *); - int sockaddr_len; }; /** inet_connection_sock - INET connection oriented sock diff --git a/include/net/inet_ecn.h b/include/net/inet_ecn.h index 7849844a4911..10117c8503e8 100644 --- a/include/net/inet_ecn.h +++ b/include/net/inet_ecn.h @@ -53,7 +53,7 @@ static inline __u8 INET_ECN_encapsulate(__u8 outer, __u8 inner) static inline int IP_ECN_set_ce(struct iphdr *iph) { - u32 check = iph->check; + u32 check = (__force u32)iph->check; u32 ecn = (iph->tos + 1) & INET_ECN_MASK; /* @@ -71,9 +71,9 @@ static inline int IP_ECN_set_ce(struct iphdr *iph) * INET_ECN_ECT_1 => check += htons(0xFFFD) * INET_ECN_ECT_0 => check += htons(0xFFFE) */ - check += htons(0xFFFB) + htons(ecn); + check += (__force u16)htons(0xFFFB) + (__force u16)htons(ecn); - iph->check = check + (check>=0xFFFF); + iph->check = (__force __sum16)(check + (check>=0xFFFF)); iph->tos |= INET_ECN_CE; return 1; } @@ -95,13 +95,13 @@ static inline int IP6_ECN_set_ce(struct ipv6hdr *iph) { if (INET_ECN_is_not_ect(ipv6_get_dsfield(iph))) return 0; - *(u32*)iph |= htonl(INET_ECN_CE << 20); + *(__be32*)iph |= htonl(INET_ECN_CE << 20); return 1; } static inline void IP6_ECN_clear(struct ipv6hdr *iph) { - *(u32*)iph &= ~htonl(INET_ECN_MASK << 20); + *(__be32*)iph &= ~htonl(INET_ECN_MASK << 20); } static inline void ipv6_copy_dscp(struct ipv6hdr *outer, struct ipv6hdr *inner) diff --git a/include/net/ip.h b/include/net/ip.h index b6d95e553401..83cb9ac5554e 100644 --- a/include/net/ip.h +++ b/include/net/ip.h @@ -97,7 +97,7 @@ extern int ip_mc_output(struct sk_buff *skb); extern int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)); extern int ip_do_nat(struct sk_buff *skb); extern void ip_send_check(struct iphdr *ip); -extern int ip_queue_xmit(struct sk_buff *skb, int ipfragok); +extern int ip_queue_xmit(struct sk_buff *skb, struct sock *sk, int ipfragok); extern void ip_init(void); extern int ip_append_data(struct sock *sk, int getfrag(void *from, char *to, int offset, int len, @@ -123,7 +123,7 @@ extern int ip4_datagram_connect(struct sock *sk, * multicast packets. */ -static inline void ip_tr_mc_map(u32 addr, char *buf) +static inline void ip_tr_mc_map(__be32 addr, char *buf) { buf[0]=0xC0; buf[1]=0x00; @@ -135,7 +135,7 @@ static inline void ip_tr_mc_map(u32 addr, char *buf) struct ip_reply_arg { struct kvec iov[1]; - u32 csum; + __wsum csum; int csumoffset; /* u16 offset of csum in iov[0].iov_base */ /* -1 if not needed */ }; @@ -192,9 +192,9 @@ extern void ipfrag_init(void); static inline int ip_decrease_ttl(struct iphdr *iph) { - u32 check = iph->check; - check += htons(0x0100); - iph->check = check + (check>=0xFFFF); + u32 check = (__force u32)iph->check; + check += (__force u32)htons(0x0100); + iph->check = (__force __sum16)(check + (check>=0xFFFF)); return --iph->ttl; } @@ -238,9 +238,9 @@ static inline void ip_select_ident_more(struct iphdr *iph, struct dst_entry *dst * Map a multicast IP onto multicast MAC for type ethernet. */ -static inline void ip_eth_mc_map(u32 addr, char *buf) +static inline void ip_eth_mc_map(__be32 naddr, char *buf) { - addr=ntohl(addr); + __u32 addr=ntohl(naddr); buf[0]=0x01; buf[1]=0x00; buf[2]=0x5e; @@ -256,13 +256,14 @@ static inline void ip_eth_mc_map(u32 addr, char *buf) * Leave P_Key as 0 to be filled in by driver. */ -static inline void ip_ib_mc_map(u32 addr, char *buf) +static inline void ip_ib_mc_map(__be32 naddr, char *buf) { + __u32 addr; buf[0] = 0; /* Reserved */ buf[1] = 0xff; /* Multicast QPN */ buf[2] = 0xff; buf[3] = 0xff; - addr = ntohl(addr); + addr = ntohl(naddr); buf[4] = 0xff; buf[5] = 0x12; /* link local scope */ buf[6] = 0x40; /* IPv4 signature */ diff --git a/include/net/ip6_checksum.h b/include/net/ip6_checksum.h index 3dfc885bdf25..68e2b32cf1d6 100644 --- a/include/net/ip6_checksum.h +++ b/include/net/ip6_checksum.h @@ -34,60 +34,60 @@ #ifndef _HAVE_ARCH_IPV6_CSUM -static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr, - struct in6_addr *daddr, - __u16 len, - unsigned short proto, - unsigned int csum) +static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, + const struct in6_addr *daddr, + __u32 len, unsigned short proto, + __wsum csum) { int carry; __u32 ulen; __u32 uproto; + __u32 sum = (__force u32)csum; - csum += saddr->s6_addr32[0]; - carry = (csum < saddr->s6_addr32[0]); - csum += carry; + sum += (__force u32)saddr->s6_addr32[0]; + carry = (sum < (__force u32)saddr->s6_addr32[0]); + sum += carry; - csum += saddr->s6_addr32[1]; - carry = (csum < saddr->s6_addr32[1]); - csum += carry; + sum += (__force u32)saddr->s6_addr32[1]; + carry = (sum < (__force u32)saddr->s6_addr32[1]); + sum += carry; - csum += saddr->s6_addr32[2]; - carry = (csum < saddr->s6_addr32[2]); - csum += carry; + sum += (__force u32)saddr->s6_addr32[2]; + carry = (sum < (__force u32)saddr->s6_addr32[2]); + sum += carry; - csum += saddr->s6_addr32[3]; - carry = (csum < saddr->s6_addr32[3]); - csum += carry; + sum += (__force u32)saddr->s6_addr32[3]; + carry = (sum < (__force u32)saddr->s6_addr32[3]); + sum += carry; - csum += daddr->s6_addr32[0]; - carry = (csum < daddr->s6_addr32[0]); - csum += carry; + sum += (__force u32)daddr->s6_addr32[0]; + carry = (sum < (__force u32)daddr->s6_addr32[0]); + sum += carry; - csum += daddr->s6_addr32[1]; - carry = (csum < daddr->s6_addr32[1]); - csum += carry; + sum += (__force u32)daddr->s6_addr32[1]; + carry = (sum < (__force u32)daddr->s6_addr32[1]); + sum += carry; - csum += daddr->s6_addr32[2]; - carry = (csum < daddr->s6_addr32[2]); - csum += carry; + sum += (__force u32)daddr->s6_addr32[2]; + carry = (sum < (__force u32)daddr->s6_addr32[2]); + sum += carry; - csum += daddr->s6_addr32[3]; - carry = (csum < daddr->s6_addr32[3]); - csum += carry; + sum += (__force u32)daddr->s6_addr32[3]; + carry = (sum < (__force u32)daddr->s6_addr32[3]); + sum += carry; - ulen = htonl((__u32) len); - csum += ulen; - carry = (csum < ulen); - csum += carry; + ulen = (__force u32)htonl((__u32) len); + sum += ulen; + carry = (sum < ulen); + sum += carry; - uproto = htonl(proto); - csum += uproto; - carry = (csum < uproto); - csum += carry; + uproto = (__force u32)htonl(proto); + sum += uproto; + carry = (sum < uproto); + sum += carry; - return csum_fold(csum); + return csum_fold((__force __wsum)csum); } #endif diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h index e4438de3bd6b..f9cde44f93b4 100644 --- a/include/net/ip6_fib.h +++ b/include/net/ip6_fib.h @@ -107,6 +107,11 @@ struct rt6_info u8 rt6i_protocol; }; +static inline struct inet6_dev *ip6_dst_idev(struct dst_entry *dst) +{ + return ((struct rt6_info *)dst)->rt6i_idev; +} + struct fib6_walker_t { struct fib6_walker_t *prev, *next; diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index c14b70ed4c57..4e927ebd1cb3 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h @@ -20,7 +20,7 @@ struct route_info { route_pref:2, reserved_h:3; #endif - __u32 lifetime; + __be32 lifetime; __u8 prefix[0]; /* 0,8 or 16 */ }; diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index 949b932d2f08..36c635ca1aa6 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h @@ -115,7 +115,7 @@ struct fib_result { struct fib_result_nl { __be32 fl_addr; /* To be looked up*/ - u32 fl_fwmark; + u32 fl_mark; unsigned char fl_tos; unsigned char fl_scope; unsigned char tb_id_in; diff --git a/include/net/ip_mp_alg.h b/include/net/ip_mp_alg.h index beffdd66ad74..25b56571e54b 100644 --- a/include/net/ip_mp_alg.h +++ b/include/net/ip_mp_alg.h @@ -88,9 +88,7 @@ static inline int multipath_comparekeys(const struct flowi *flp1, return flp1->fl4_dst == flp2->fl4_dst && flp1->fl4_src == flp2->fl4_src && flp1->oif == flp2->oif && -#ifdef CONFIG_IP_ROUTE_FWMARK - flp1->fl4_fwmark == flp2->fl4_fwmark && -#endif + flp1->mark == flp2->mark && !((flp1->fl4_tos ^ flp2->fl4_tos) & (IPTOS_RT_MASK | RTO_ONLINK)); } diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 903108e583f8..672564e5a81d 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -988,14 +988,20 @@ extern int ip_vs_make_skb_writable(struct sk_buff **pskb, int len); extern void ip_vs_nat_icmp(struct sk_buff *skb, struct ip_vs_protocol *pp, struct ip_vs_conn *cp, int dir); -extern u16 ip_vs_checksum_complete(struct sk_buff *skb, int offset); +extern __sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset); -static inline u16 ip_vs_check_diff(u32 old, u32 new, u16 oldsum) +static inline __wsum ip_vs_check_diff4(__be32 old, __be32 new, __wsum oldsum) { - u32 diff[2] = { old, new }; + __be32 diff[2] = { ~old, new }; - return csum_fold(csum_partial((char *) diff, sizeof(diff), - oldsum ^ 0xFFFF)); + return csum_partial((char *) diff, sizeof(diff), oldsum); +} + +static inline __wsum ip_vs_check_diff2(__be16 old, __be16 new, __wsum oldsum) +{ + __be16 diff[2] = { ~old, new }; + + return csum_partial((char *) diff, sizeof(diff), oldsum); } #endif /* __KERNEL__ */ diff --git a/include/net/ipconfig.h b/include/net/ipconfig.h index 2a1fe996fbc6..3924d7d2cb11 100644 --- a/include/net/ipconfig.h +++ b/include/net/ipconfig.h @@ -11,12 +11,12 @@ extern int ic_proto_enabled; /* Protocols enabled (see IC_xxx) */ extern int ic_set_manually; /* IPconfig parameters set manually */ -extern u32 ic_myaddr; /* My IP address */ -extern u32 ic_gateway; /* Gateway IP address */ +extern __be32 ic_myaddr; /* My IP address */ +extern __be32 ic_gateway; /* Gateway IP address */ -extern u32 ic_servaddr; /* Boot server IP address */ +extern __be32 ic_servaddr; /* Boot server IP address */ -extern u32 root_server_addr; /* Address of NFS server */ +extern __be32 root_server_addr; /* Address of NFS server */ extern u8 root_server_path[]; /* Path to mount as root */ diff --git a/include/net/ipip.h b/include/net/ipip.h index f490c3cbe377..7cdc914322f0 100644 --- a/include/net/ipip.h +++ b/include/net/ipip.h @@ -35,7 +35,7 @@ struct ip_tunnel ip_send_check(iph); \ \ err = NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, skb, NULL, rt->u.dst.dev, dst_output);\ - if (err == NET_XMIT_SUCCESS || err == NET_XMIT_CN) { \ + if (net_xmit_eval(err) == 0) { \ stats->tx_bytes += pkt_len; \ stats->tx_packets++; \ } else { \ @@ -44,8 +44,4 @@ struct ip_tunnel } \ } while (0) - -extern int sit_init(void); -extern void sit_cleanup(void); - #endif diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 8223c4410b4b..00328b71a08c 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h @@ -95,10 +95,10 @@ */ struct frag_hdr { - unsigned char nexthdr; - unsigned char reserved; - unsigned short frag_off; - __u32 identification; + __u8 nexthdr; + __u8 reserved; + __be16 frag_off; + __be32 identification; }; #define IP6_MF 0x0001 @@ -113,9 +113,24 @@ extern int sysctl_mld_max_msf; /* MIBs */ DECLARE_SNMP_STAT(struct ipstats_mib, ipv6_statistics); -#define IP6_INC_STATS(field) SNMP_INC_STATS(ipv6_statistics, field) -#define IP6_INC_STATS_BH(field) SNMP_INC_STATS_BH(ipv6_statistics, field) -#define IP6_INC_STATS_USER(field) SNMP_INC_STATS_USER(ipv6_statistics, field) +#define IP6_INC_STATS(idev,field) ({ \ + struct inet6_dev *_idev = (idev); \ + if (likely(_idev != NULL)) \ + SNMP_INC_STATS(_idev->stats.ipv6, field); \ + SNMP_INC_STATS(ipv6_statistics, field); \ +}) +#define IP6_INC_STATS_BH(idev,field) ({ \ + struct inet6_dev *_idev = (idev); \ + if (likely(_idev != NULL)) \ + SNMP_INC_STATS_BH(_idev->stats.ipv6, field); \ + SNMP_INC_STATS_BH(ipv6_statistics, field); \ +}) +#define IP6_INC_STATS_USER(idev,field) ({ \ + struct inet6_dev *_idev = (idev); \ + if (likely(_idev != NULL)) \ + SNMP_INC_STATS_USER(_idev->stats.ipv6, field); \ + SNMP_INC_STATS_USER(ipv6_statistics, field); \ +}) DECLARE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics); #define ICMP6_INC_STATS(idev, field) ({ \ struct inet6_dev *_idev = (idev); \ @@ -143,9 +158,13 @@ DECLARE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics); SNMP_INC_STATS_OFFSET_BH(icmpv6_statistics, field, _offset); \ }) DECLARE_SNMP_STAT(struct udp_mib, udp_stats_in6); -#define UDP6_INC_STATS(field) SNMP_INC_STATS(udp_stats_in6, field) -#define UDP6_INC_STATS_BH(field) SNMP_INC_STATS_BH(udp_stats_in6, field) -#define UDP6_INC_STATS_USER(field) SNMP_INC_STATS_USER(udp_stats_in6, field) +DECLARE_SNMP_STAT(struct udp_mib, udplite_stats_in6); +#define UDP6_INC_STATS_BH(field, is_udplite) do { \ + if (is_udplite) SNMP_INC_STATS_BH(udplite_stats_in6, field); \ + else SNMP_INC_STATS_BH(udp_stats_in6, field); } while(0) +#define UDP6_INC_STATS_USER(field, is_udplite) do { \ + if (is_udplite) SNMP_INC_STATS_USER(udplite_stats_in6, field); \ + else SNMP_INC_STATS_USER(udp_stats_in6, field); } while(0) int snmp6_register_dev(struct inet6_dev *idev); int snmp6_unregister_dev(struct inet6_dev *idev); @@ -191,7 +210,7 @@ struct ipv6_txoptions struct ip6_flowlabel { struct ip6_flowlabel *next; - u32 label; + __be32 label; struct in6_addr dst; struct ipv6_txoptions *opt; atomic_t users; @@ -211,7 +230,7 @@ struct ipv6_fl_socklist struct ip6_flowlabel *fl; }; -extern struct ip6_flowlabel *fl6_sock_lookup(struct sock *sk, u32 label); +extern struct ip6_flowlabel *fl6_sock_lookup(struct sock *sk, __be32 label); extern struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions * opt_space, struct ip6_flowlabel * fl, struct ipv6_txoptions * fopt); @@ -375,22 +394,15 @@ static inline int ipv6_addr_any(const struct in6_addr *a) */ static inline int __ipv6_addr_diff(const void *token1, const void *token2, int addrlen) { - const __u32 *a1 = token1, *a2 = token2; + const __be32 *a1 = token1, *a2 = token2; int i; addrlen >>= 2; for (i = 0; i < addrlen; i++) { - __u32 xb = a1[i] ^ a2[i]; - if (xb) { - int j = 31; - - xb = ntohl(xb); - while ((xb & (1 << j)) == 0) - j--; - - return (i * 32 + 31 - j); - } + __be32 xb = a1[i] ^ a2[i]; + if (xb) + return i * 32 + 32 - fls(ntohl(xb)); } /* @@ -544,7 +556,7 @@ extern int ip6_datagram_connect(struct sock *sk, struct sockaddr *addr, int addr_len); extern int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len); -extern void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, u16 port, +extern void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err, __be16 port, u32 info, u8 *payload); extern void ipv6_local_error(struct sock *sk, int err, struct flowi *fl, u32 info); @@ -589,6 +601,8 @@ extern int tcp6_proc_init(void); extern void tcp6_proc_exit(void); extern int udp6_proc_init(void); extern void udp6_proc_exit(void); +extern int udplite6_proc_init(void); +extern void udplite6_proc_exit(void); extern int ipv6_misc_proc_init(void); extern void ipv6_misc_proc_exit(void); diff --git a/include/net/irda/irlap_frame.h b/include/net/irda/irlap_frame.h index 9dd54a5002b2..641f88e848bd 100644 --- a/include/net/irda/irlap_frame.h +++ b/include/net/irda/irlap_frame.h @@ -91,8 +91,8 @@ struct xid_frame { __u8 caddr; /* Connection address */ __u8 control; __u8 ident; /* Should always be XID_FORMAT */ - __u32 saddr; /* Source device address */ - __u32 daddr; /* Destination device address */ + __le32 saddr; /* Source device address */ + __le32 daddr; /* Destination device address */ __u8 flags; /* Discovery flags */ __u8 slotnr; __u8 version; @@ -101,15 +101,15 @@ struct xid_frame { struct test_frame { __u8 caddr; /* Connection address */ __u8 control; - __u32 saddr; /* Source device address */ - __u32 daddr; /* Destination device address */ + __le32 saddr; /* Source device address */ + __le32 daddr; /* Destination device address */ } IRDA_PACK; struct ua_frame { __u8 caddr; __u8 control; - __u32 saddr; /* Source device address */ - __u32 daddr; /* Dest device address */ + __le32 saddr; /* Source device address */ + __le32 daddr; /* Dest device address */ } IRDA_PACK; struct dm_frame { @@ -135,8 +135,8 @@ struct i_frame { struct snrm_frame { __u8 caddr; __u8 control; - __u32 saddr; - __u32 daddr; + __le32 saddr; + __le32 daddr; __u8 ncaddr; } IRDA_PACK; diff --git a/include/net/llc_pdu.h b/include/net/llc_pdu.h index 8f6306581fa7..aa33a477c3fb 100644 --- a/include/net/llc_pdu.h +++ b/include/net/llc_pdu.h @@ -252,9 +252,9 @@ static inline void llc_pdu_header_init(struct sk_buff *skb, u8 type, */ static inline void llc_pdu_decode_sa(struct sk_buff *skb, u8 *sa) { - if (skb->protocol == ntohs(ETH_P_802_2)) + if (skb->protocol == htons(ETH_P_802_2)) memcpy(sa, eth_hdr(skb)->h_source, ETH_ALEN); - else if (skb->protocol == ntohs(ETH_P_TR_802_2)) { + else if (skb->protocol == htons(ETH_P_TR_802_2)) { memcpy(sa, tr_hdr(skb)->saddr, ETH_ALEN); *sa &= 0x7F; } @@ -269,9 +269,9 @@ static inline void llc_pdu_decode_sa(struct sk_buff *skb, u8 *sa) */ static inline void llc_pdu_decode_da(struct sk_buff *skb, u8 *da) { - if (skb->protocol == ntohs(ETH_P_802_2)) + if (skb->protocol == htons(ETH_P_802_2)) memcpy(da, eth_hdr(skb)->h_dest, ETH_ALEN); - else if (skb->protocol == ntohs(ETH_P_TR_802_2)) + else if (skb->protocol == htons(ETH_P_TR_802_2)) memcpy(da, tr_hdr(skb)->daddr, ETH_ALEN); } @@ -345,7 +345,7 @@ static inline void llc_pdu_init_as_test_rsp(struct sk_buff *skb, pdu->ctrl_1 = LLC_PDU_TYPE_U; pdu->ctrl_1 |= LLC_1_PDU_CMD_TEST; pdu->ctrl_1 |= LLC_U_PF_BIT_MASK; - if (ev_skb->protocol == ntohs(ETH_P_802_2)) { + if (ev_skb->protocol == htons(ETH_P_802_2)) { struct llc_pdu_un *ev_pdu = llc_pdu_un_hdr(ev_skb); int dsize; diff --git a/include/net/ndisc.h b/include/net/ndisc.h index d3915dabe6de..475b10c575b3 100644 --- a/include/net/ndisc.h +++ b/include/net/ndisc.h @@ -66,8 +66,8 @@ struct rs_msg { struct ra_msg { struct icmp6hdr icmph; - __u32 reachable_time; - __u32 retrans_timer; + __be32 reachable_time; + __be32 retrans_timer; }; struct nd_opt_hdr { diff --git a/include/net/netfilter/ipv4/nf_conntrack_ipv4.h b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h index 91684436af8e..1401ccc051c4 100644 --- a/include/net/netfilter/ipv4/nf_conntrack_ipv4.h +++ b/include/net/netfilter/ipv4/nf_conntrack_ipv4.h @@ -9,32 +9,35 @@ #ifndef _NF_CONNTRACK_IPV4_H #define _NF_CONNTRACK_IPV4_H -#ifdef CONFIG_IP_NF_NAT_NEEDED -#include <linux/netfilter_ipv4/ip_nat.h> +#ifdef CONFIG_NF_NAT_NEEDED +#include <net/netfilter/nf_nat.h> +#include <linux/netfilter/nf_conntrack_pptp.h> /* per conntrack: nat application helper private data */ -union ip_conntrack_nat_help { +union nf_conntrack_nat_help { /* insert nat helper private data here */ + struct nf_nat_pptp nat_pptp_info; }; -struct nf_conntrack_ipv4_nat { - struct ip_nat_info info; - union ip_conntrack_nat_help help; +struct nf_conn_nat { + struct nf_nat_info info; + union nf_conntrack_nat_help help; #if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \ defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE) int masq_index; #endif }; -#endif /* CONFIG_IP_NF_NAT_NEEDED */ - -struct nf_conntrack_ipv4 { -#ifdef CONFIG_IP_NF_NAT_NEEDED - struct nf_conntrack_ipv4_nat *nat; -#endif -}; +#endif /* CONFIG_NF_NAT_NEEDED */ /* Returns new sk_buff, or NULL */ struct sk_buff * nf_ct_ipv4_ct_gather_frags(struct sk_buff *skb); +extern struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4; +extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4; +extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp; + +extern int nf_conntrack_ipv4_compat_init(void); +extern void nf_conntrack_ipv4_compat_fini(void); + #endif /*_NF_CONNTRACK_IPV4_H*/ diff --git a/include/net/netfilter/ipv6/nf_conntrack_ipv6.h b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h new file mode 100644 index 000000000000..b4b6049e01fa --- /dev/null +++ b/include/net/netfilter/ipv6/nf_conntrack_ipv6.h @@ -0,0 +1,25 @@ +#ifndef _NF_CONNTRACK_IPV6_H +#define _NF_CONNTRACK_IPV6_H + +extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6; + +extern struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6; +extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6; +extern struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6; + +extern int nf_ct_ipv6_skip_exthdr(struct sk_buff *skb, int start, + u8 *nexthdrp, int len); + +extern int nf_ct_frag6_init(void); +extern void nf_ct_frag6_cleanup(void); +extern struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb); +extern void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb, + struct net_device *in, + struct net_device *out, + int (*okfn)(struct sk_buff *)); + +extern unsigned int nf_ct_frag6_timeout; +extern unsigned int nf_ct_frag6_low_thresh; +extern unsigned int nf_ct_frag6_high_thresh; + +#endif /* _NF_CONNTRACK_IPV6_H*/ diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h index 1fbd8193d5f1..032b36a0e378 100644 --- a/include/net/netfilter/nf_conntrack.h +++ b/include/net/netfilter/nf_conntrack.h @@ -21,6 +21,7 @@ #include <linux/netfilter/nf_conntrack_tcp.h> #include <linux/netfilter/nf_conntrack_sctp.h> +#include <linux/netfilter/nf_conntrack_proto_gre.h> #include <net/netfilter/ipv4/nf_conntrack_icmp.h> #include <net/netfilter/ipv6/nf_conntrack_icmpv6.h> @@ -33,6 +34,7 @@ union nf_conntrack_proto { struct ip_ct_tcp tcp; struct ip_ct_icmp icmp; struct nf_ct_icmpv6 icmpv6; + struct nf_ct_gre gre; }; union nf_conntrack_expect_proto { @@ -41,11 +43,15 @@ union nf_conntrack_expect_proto { /* Add protocol helper include file here */ #include <linux/netfilter/nf_conntrack_ftp.h> +#include <linux/netfilter/nf_conntrack_pptp.h> +#include <linux/netfilter/nf_conntrack_h323.h> /* per conntrack: application helper private data */ union nf_conntrack_help { /* insert conntrack helper private data (master) here */ - struct ip_ct_ftp_master ct_ftp_info; + struct nf_ct_ftp_master ct_ftp_info; + struct nf_ct_pptp_master ct_pptp_info; + struct nf_ct_h323_master ct_h323_info; }; #include <linux/types.h> @@ -79,6 +85,8 @@ struct nf_conn_help { #include <net/netfilter/ipv4/nf_conntrack_ipv4.h> +#include <net/netfilter/ipv6/nf_conntrack_ipv6.h> + struct nf_conn { /* Usage count in here is 1 for hash table/destruct timer, 1 per skb, @@ -124,44 +132,6 @@ struct nf_conn char data[0]; }; -struct nf_conntrack_expect -{ - /* Internal linked list (global expectation list) */ - struct list_head list; - - /* We expect this tuple, with the following mask */ - struct nf_conntrack_tuple tuple, mask; - - /* Function to call after setup and insertion */ - void (*expectfn)(struct nf_conn *new, - struct nf_conntrack_expect *this); - - /* The conntrack of the master connection */ - struct nf_conn *master; - - /* Timer function; deletes the expectation. */ - struct timer_list timeout; - - /* Usage count. */ - atomic_t use; - - /* Unique ID */ - unsigned int id; - - /* Flags */ - unsigned int flags; - -#ifdef CONFIG_NF_NAT_NEEDED - /* This is the original per-proto part, used to map the - * expected connection the way the recipient expects. */ - union nf_conntrack_manip_proto saved_proto; - /* Direction relative to the master connection. */ - enum ip_conntrack_dir dir; -#endif -}; - -#define NF_CT_EXPECT_PERMANENT 0x1 - static inline struct nf_conn * nf_ct_tuplehash_to_ctrack(const struct nf_conntrack_tuple_hash *hash) { @@ -208,16 +178,6 @@ __nf_conntrack_find(const struct nf_conntrack_tuple *tuple, extern void nf_conntrack_hash_insert(struct nf_conn *ct); -extern struct nf_conntrack_expect * -__nf_conntrack_expect_find(const struct nf_conntrack_tuple *tuple); - -extern struct nf_conntrack_expect * -nf_conntrack_expect_find(const struct nf_conntrack_tuple *tuple); - -extern void nf_ct_unlink_expect(struct nf_conntrack_expect *exp); - -extern void nf_ct_remove_expectations(struct nf_conn *ct); - extern void nf_conntrack_flush(void); extern struct nf_conntrack_helper * @@ -289,89 +249,12 @@ static inline int nf_ct_is_dying(struct nf_conn *ct) extern unsigned int nf_conntrack_htable_size; extern int nf_conntrack_checksum; +extern atomic_t nf_conntrack_count; +extern int nf_conntrack_max; +DECLARE_PER_CPU(struct ip_conntrack_stat, nf_conntrack_stat); #define NF_CT_STAT_INC(count) (__get_cpu_var(nf_conntrack_stat).count++) -#ifdef CONFIG_NF_CONNTRACK_EVENTS -#include <linux/notifier.h> -#include <linux/interrupt.h> - -struct nf_conntrack_ecache { - struct nf_conn *ct; - unsigned int events; -}; -DECLARE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache); - -#define CONNTRACK_ECACHE(x) (__get_cpu_var(nf_conntrack_ecache).x) - -extern struct atomic_notifier_head nf_conntrack_chain; -extern struct atomic_notifier_head nf_conntrack_expect_chain; - -static inline int nf_conntrack_register_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_register(&nf_conntrack_chain, nb); -} - -static inline int nf_conntrack_unregister_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_unregister(&nf_conntrack_chain, nb); -} - -static inline int -nf_conntrack_expect_register_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_register(&nf_conntrack_expect_chain, nb); -} - -static inline int -nf_conntrack_expect_unregister_notifier(struct notifier_block *nb) -{ - return atomic_notifier_chain_unregister(&nf_conntrack_expect_chain, - nb); -} - -extern void nf_ct_deliver_cached_events(const struct nf_conn *ct); -extern void __nf_ct_event_cache_init(struct nf_conn *ct); - -static inline void -nf_conntrack_event_cache(enum ip_conntrack_events event, - const struct sk_buff *skb) -{ - struct nf_conn *ct = (struct nf_conn *)skb->nfct; - struct nf_conntrack_ecache *ecache; - - local_bh_disable(); - ecache = &__get_cpu_var(nf_conntrack_ecache); - if (ct != ecache->ct) - __nf_ct_event_cache_init(ct); - ecache->events |= event; - local_bh_enable(); -} - -static inline void nf_conntrack_event(enum ip_conntrack_events event, - struct nf_conn *ct) -{ - if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) - atomic_notifier_call_chain(&nf_conntrack_chain, event, ct); -} - -static inline void -nf_conntrack_expect_event(enum ip_conntrack_expect_events event, - struct nf_conntrack_expect *exp) -{ - atomic_notifier_call_chain(&nf_conntrack_expect_chain, event, exp); -} -#else /* CONFIG_NF_CONNTRACK_EVENTS */ -static inline void nf_conntrack_event_cache(enum ip_conntrack_events event, - const struct sk_buff *skb) {} -static inline void nf_conntrack_event(enum ip_conntrack_events event, - struct nf_conn *ct) {} -static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct) {} -static inline void -nf_conntrack_expect_event(enum ip_conntrack_expect_events event, - struct nf_conntrack_expect *exp) {} -#endif /* CONFIG_NF_CONNTRACK_EVENTS */ - /* no helper, no nat */ #define NF_CT_F_BASIC 0 /* for helper */ @@ -387,17 +270,45 @@ nf_conntrack_unregister_cache(u_int32_t features); /* valid combinations: * basic: nf_conn, nf_conn .. nf_conn_help - * nat: nf_conn .. nf_conn_nat, nf_conn .. nf_conn_nat, nf_conn help + * nat: nf_conn .. nf_conn_nat, nf_conn .. nf_conn_nat .. nf_conn help */ +#ifdef CONFIG_NF_NAT_NEEDED +static inline struct nf_conn_nat *nfct_nat(const struct nf_conn *ct) +{ + unsigned int offset = sizeof(struct nf_conn); + + if (!(ct->features & NF_CT_F_NAT)) + return NULL; + + offset = ALIGN(offset, __alignof__(struct nf_conn_nat)); + return (struct nf_conn_nat *) ((void *)ct + offset); +} + static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct) { unsigned int offset = sizeof(struct nf_conn); if (!(ct->features & NF_CT_F_HELP)) return NULL; + if (ct->features & NF_CT_F_NAT) { + offset = ALIGN(offset, __alignof__(struct nf_conn_nat)); + offset += sizeof(struct nf_conn_nat); + } + offset = ALIGN(offset, __alignof__(struct nf_conn_help)); return (struct nf_conn_help *) ((void *)ct + offset); } +#else /* No NAT */ +static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct) +{ + unsigned int offset = sizeof(struct nf_conn); + + if (!(ct->features & NF_CT_F_HELP)) + return NULL; + offset = ALIGN(offset, __alignof__(struct nf_conn_help)); + return (struct nf_conn_help *) ((void *)ct + offset); +} +#endif /* CONFIG_NF_NAT_NEEDED */ #endif /* __KERNEL__ */ #endif /* _NF_CONNTRACK_H */ diff --git a/include/net/netfilter/nf_conntrack_core.h b/include/net/netfilter/nf_conntrack_core.h index da254525a4ce..7fdc72c01356 100644 --- a/include/net/netfilter/nf_conntrack_core.h +++ b/include/net/netfilter/nf_conntrack_core.h @@ -13,6 +13,9 @@ #define _NF_CONNTRACK_CORE_H #include <linux/netfilter.h> +#include <net/netfilter/nf_conntrack_l3proto.h> +#include <net/netfilter/nf_conntrack_l4proto.h> +#include <net/netfilter/nf_conntrack_ecache.h> /* This header is used to share core functionality between the standalone connection tracking module, and the compatibility layer's use @@ -29,7 +32,7 @@ extern struct nf_conntrack_l3proto *nf_ct_find_l3proto(u_int16_t pf); /* Like above, but you already have conntrack read lock. */ extern struct nf_conntrack_l3proto *__nf_ct_find_l3proto(u_int16_t l3proto); -struct nf_conntrack_protocol; +struct nf_conntrack_l4proto; extern int nf_ct_get_tuple(const struct sk_buff *skb, @@ -39,13 +42,13 @@ nf_ct_get_tuple(const struct sk_buff *skb, u_int8_t protonum, struct nf_conntrack_tuple *tuple, const struct nf_conntrack_l3proto *l3proto, - const struct nf_conntrack_protocol *protocol); + const struct nf_conntrack_l4proto *l4proto); extern int nf_ct_invert_tuple(struct nf_conntrack_tuple *inverse, const struct nf_conntrack_tuple *orig, const struct nf_conntrack_l3proto *l3proto, - const struct nf_conntrack_protocol *protocol); + const struct nf_conntrack_l4proto *l4proto); /* Find a connection corresponding to a tuple. */ extern struct nf_conntrack_tuple_hash * @@ -70,7 +73,14 @@ static inline int nf_conntrack_confirm(struct sk_buff **pskb) extern void __nf_conntrack_attach(struct sk_buff *nskb, struct sk_buff *skb); +int +print_tuple(struct seq_file *s, const struct nf_conntrack_tuple *tuple, + struct nf_conntrack_l3proto *l3proto, + struct nf_conntrack_l4proto *proto); + extern struct list_head *nf_conntrack_hash; extern struct list_head nf_conntrack_expect_list; extern rwlock_t nf_conntrack_lock ; +extern struct list_head unconfirmed; + #endif /* _NF_CONNTRACK_CORE_H */ diff --git a/include/net/netfilter/nf_conntrack_ecache.h b/include/net/netfilter/nf_conntrack_ecache.h new file mode 100644 index 000000000000..b62a8a9ec9d8 --- /dev/null +++ b/include/net/netfilter/nf_conntrack_ecache.h @@ -0,0 +1,95 @@ +/* + * connection tracking event cache. + */ + +#ifndef _NF_CONNTRACK_ECACHE_H +#define _NF_CONNTRACK_ECACHE_H +#include <net/netfilter/nf_conntrack.h> + +#include <linux/notifier.h> +#include <linux/interrupt.h> +#include <net/netfilter/nf_conntrack_expect.h> + +#ifdef CONFIG_NF_CONNTRACK_EVENTS +struct nf_conntrack_ecache { + struct nf_conn *ct; + unsigned int events; +}; +DECLARE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache); + +#define CONNTRACK_ECACHE(x) (__get_cpu_var(nf_conntrack_ecache).x) + +extern struct atomic_notifier_head nf_conntrack_chain; +extern struct atomic_notifier_head nf_conntrack_expect_chain; + +static inline int nf_conntrack_register_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&nf_conntrack_chain, nb); +} + +static inline int nf_conntrack_unregister_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&nf_conntrack_chain, nb); +} + +static inline int +nf_conntrack_expect_register_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&nf_conntrack_expect_chain, nb); +} + +static inline int +nf_conntrack_expect_unregister_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&nf_conntrack_expect_chain, + nb); +} + +extern void nf_ct_deliver_cached_events(const struct nf_conn *ct); +extern void __nf_ct_event_cache_init(struct nf_conn *ct); +extern void nf_ct_event_cache_flush(void); + +static inline void +nf_conntrack_event_cache(enum ip_conntrack_events event, + const struct sk_buff *skb) +{ + struct nf_conn *ct = (struct nf_conn *)skb->nfct; + struct nf_conntrack_ecache *ecache; + + local_bh_disable(); + ecache = &__get_cpu_var(nf_conntrack_ecache); + if (ct != ecache->ct) + __nf_ct_event_cache_init(ct); + ecache->events |= event; + local_bh_enable(); +} + +static inline void nf_conntrack_event(enum ip_conntrack_events event, + struct nf_conn *ct) +{ + if (nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct)) + atomic_notifier_call_chain(&nf_conntrack_chain, event, ct); +} + +static inline void +nf_conntrack_expect_event(enum ip_conntrack_expect_events event, + struct nf_conntrack_expect *exp) +{ + atomic_notifier_call_chain(&nf_conntrack_expect_chain, event, exp); +} + +#else /* CONFIG_NF_CONNTRACK_EVENTS */ + +static inline void nf_conntrack_event_cache(enum ip_conntrack_events event, + const struct sk_buff *skb) {} +static inline void nf_conntrack_event(enum ip_conntrack_events event, + struct nf_conn *ct) {} +static inline void nf_ct_deliver_cached_events(const struct nf_conn *ct) {} +static inline void +nf_conntrack_expect_event(enum ip_conntrack_expect_events event, + struct nf_conntrack_expect *exp) {} +static inline void nf_ct_event_cache_flush(void) {} +#endif /* CONFIG_NF_CONNTRACK_EVENTS */ + +#endif /*_NF_CONNTRACK_ECACHE_H*/ + diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h new file mode 100644 index 000000000000..cef3136e22a3 --- /dev/null +++ b/include/net/netfilter/nf_conntrack_expect.h @@ -0,0 +1,80 @@ +/* + * connection tracking expectations. + */ + +#ifndef _NF_CONNTRACK_EXPECT_H +#define _NF_CONNTRACK_EXPECT_H +#include <net/netfilter/nf_conntrack.h> + +extern struct list_head nf_conntrack_expect_list; +extern kmem_cache_t *nf_conntrack_expect_cachep; +extern struct file_operations exp_file_ops; + +struct nf_conntrack_expect +{ + /* Internal linked list (global expectation list) */ + struct list_head list; + + /* We expect this tuple, with the following mask */ + struct nf_conntrack_tuple tuple, mask; + + /* Function to call after setup and insertion */ + void (*expectfn)(struct nf_conn *new, + struct nf_conntrack_expect *this); + + /* Helper to assign to new connection */ + struct nf_conntrack_helper *helper; + + /* The conntrack of the master connection */ + struct nf_conn *master; + + /* Timer function; deletes the expectation. */ + struct timer_list timeout; + + /* Usage count. */ + atomic_t use; + + /* Unique ID */ + unsigned int id; + + /* Flags */ + unsigned int flags; + +#ifdef CONFIG_NF_NAT_NEEDED + __be32 saved_ip; + /* This is the original per-proto part, used to map the + * expected connection the way the recipient expects. */ + union nf_conntrack_man_proto saved_proto; + /* Direction relative to the master connection. */ + enum ip_conntrack_dir dir; +#endif +}; + +#define NF_CT_EXPECT_PERMANENT 0x1 + + +struct nf_conntrack_expect * +__nf_conntrack_expect_find(const struct nf_conntrack_tuple *tuple); + +struct nf_conntrack_expect * +nf_conntrack_expect_find_get(const struct nf_conntrack_tuple *tuple); + +struct nf_conntrack_expect * +find_expectation(const struct nf_conntrack_tuple *tuple); + +void nf_ct_unlink_expect(struct nf_conntrack_expect *exp); +void nf_ct_remove_expectations(struct nf_conn *ct); +void nf_conntrack_unexpect_related(struct nf_conntrack_expect *exp); + +/* Allocate space for an expectation: this is mandatory before calling + nf_conntrack_expect_related. You will have to call put afterwards. */ +struct nf_conntrack_expect *nf_conntrack_expect_alloc(struct nf_conn *me); +void nf_conntrack_expect_init(struct nf_conntrack_expect *, int, + union nf_conntrack_address *, + union nf_conntrack_address *, + u_int8_t, __be16 *, __be16 *); +void nf_conntrack_expect_put(struct nf_conntrack_expect *exp); +int nf_conntrack_expect_related(struct nf_conntrack_expect *expect); + +#endif /*_NF_CONNTRACK_EXPECT_H*/ + diff --git a/include/net/netfilter/nf_conntrack_helper.h b/include/net/netfilter/nf_conntrack_helper.h index 86ec8174ad02..8c72ac9f0ab8 100644 --- a/include/net/netfilter/nf_conntrack_helper.h +++ b/include/net/netfilter/nf_conntrack_helper.h @@ -34,20 +34,22 @@ struct nf_conntrack_helper struct nf_conn *ct, enum ip_conntrack_info conntrackinfo); + void (*destroy)(struct nf_conn *ct); + int (*to_nfattr)(struct sk_buff *skb, const struct nf_conn *ct); }; -extern int nf_conntrack_helper_register(struct nf_conntrack_helper *); -extern void nf_conntrack_helper_unregister(struct nf_conntrack_helper *); +extern struct nf_conntrack_helper * +__nf_ct_helper_find(const struct nf_conntrack_tuple *tuple); -/* Allocate space for an expectation: this is mandatory before calling - nf_conntrack_expect_related. You will have to call put afterwards. */ -extern struct nf_conntrack_expect * -nf_conntrack_expect_alloc(struct nf_conn *master); -extern void nf_conntrack_expect_put(struct nf_conntrack_expect *exp); +extern struct nf_conntrack_helper * +nf_ct_helper_find_get( const struct nf_conntrack_tuple *tuple); -/* Add an expected connection: can have more than one per connection */ -extern int nf_conntrack_expect_related(struct nf_conntrack_expect *exp); -extern void nf_conntrack_unexpect_related(struct nf_conntrack_expect *exp); +extern struct nf_conntrack_helper * +__nf_conntrack_helper_find_byname(const char *name); + +extern void nf_ct_helper_put(struct nf_conntrack_helper *helper); +extern int nf_conntrack_helper_register(struct nf_conntrack_helper *); +extern void nf_conntrack_helper_unregister(struct nf_conntrack_helper *); #endif /*_NF_CONNTRACK_HELPER_H*/ diff --git a/include/net/netfilter/nf_conntrack_l3proto.h b/include/net/netfilter/nf_conntrack_l3proto.h index dac43b15a5b0..664ddcffe00d 100644 --- a/include/net/netfilter/nf_conntrack_l3proto.h +++ b/include/net/netfilter/nf_conntrack_l3proto.h @@ -18,9 +18,6 @@ struct nfattr; struct nf_conntrack_l3proto { - /* Next pointer. */ - struct list_head list; - /* L3 Protocol Family number. ex) PF_INET */ u_int16_t l3proto; @@ -78,6 +75,12 @@ struct nf_conntrack_l3proto int (*nfattr_to_tuple)(struct nfattr *tb[], struct nf_conntrack_tuple *t); +#ifdef CONFIG_SYSCTL + struct ctl_table_header *ctl_table_header; + struct ctl_table *ctl_table_path; + struct ctl_table *ctl_table; +#endif /* CONFIG_SYSCTL */ + /* Module (if any) which this is connected to. */ struct module *me; }; @@ -86,7 +89,7 @@ extern struct nf_conntrack_l3proto *nf_ct_l3protos[AF_MAX]; /* Protocol registration. */ extern int nf_conntrack_l3proto_register(struct nf_conntrack_l3proto *proto); -extern void nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto); +extern int nf_conntrack_l3proto_unregister(struct nf_conntrack_l3proto *proto); extern struct nf_conntrack_l3proto * nf_ct_l3proto_find_get(u_int16_t l3proto); @@ -96,13 +99,13 @@ extern void nf_ct_l3proto_put(struct nf_conntrack_l3proto *p); /* Existing built-in protocols */ extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4; extern struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6; -extern struct nf_conntrack_l3proto nf_conntrack_generic_l3proto; +extern struct nf_conntrack_l3proto nf_conntrack_l3proto_generic; static inline struct nf_conntrack_l3proto * __nf_ct_l3proto_find(u_int16_t l3proto) { if (unlikely(l3proto >= AF_MAX)) - return &nf_conntrack_generic_l3proto; + return &nf_conntrack_l3proto_generic; return nf_ct_l3protos[l3proto]; } diff --git a/include/net/netfilter/nf_conntrack_protocol.h b/include/net/netfilter/nf_conntrack_l4proto.h index 1f33737fcea5..fc8af08ff542 100644 --- a/include/net/netfilter/nf_conntrack_protocol.h +++ b/include/net/netfilter/nf_conntrack_l4proto.h @@ -1,5 +1,5 @@ /* - * Header for use in defining a given protocol for connection tracking. + * Header for use in defining a given L4 protocol for connection tracking. * * 16 Dec 2003: Yasuyuki Kozakai @USAGI <yasuyuki.kozakai@toshiba.co.jp> * - generalized L3 protocol dependent part. @@ -7,23 +7,20 @@ * Derived from include/linux/netfiter_ipv4/ip_conntrack_protcol.h */ -#ifndef _NF_CONNTRACK_PROTOCOL_H -#define _NF_CONNTRACK_PROTOCOL_H +#ifndef _NF_CONNTRACK_L4PROTO_H +#define _NF_CONNTRACK_L4PROTO_H #include <net/netfilter/nf_conntrack.h> struct seq_file; struct nfattr; -struct nf_conntrack_protocol +struct nf_conntrack_l4proto { - /* Next pointer. */ - struct list_head list; - /* L3 Protocol number. */ u_int16_t l3proto; - /* Protocol number. */ - u_int8_t proto; + /* L4 Protocol number. */ + u_int8_t l4proto; /* Protocol name */ const char *name; @@ -79,30 +76,40 @@ struct nf_conntrack_protocol int (*nfattr_to_tuple)(struct nfattr *tb[], struct nf_conntrack_tuple *t); +#ifdef CONFIG_SYSCTL + struct ctl_table_header **ctl_table_header; + struct ctl_table *ctl_table; + unsigned int *ctl_table_users; +#ifdef CONFIG_NF_CONNTRACK_PROC_COMPAT + struct ctl_table_header *ctl_compat_table_header; + struct ctl_table *ctl_compat_table; +#endif +#endif + /* Module (if any) which this is connected to. */ struct module *me; }; /* Existing built-in protocols */ -extern struct nf_conntrack_protocol nf_conntrack_protocol_tcp6; -extern struct nf_conntrack_protocol nf_conntrack_protocol_udp4; -extern struct nf_conntrack_protocol nf_conntrack_protocol_udp6; -extern struct nf_conntrack_protocol nf_conntrack_generic_protocol; +extern struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6; +extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4; +extern struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6; +extern struct nf_conntrack_l4proto nf_conntrack_l4proto_generic; #define MAX_NF_CT_PROTO 256 -extern struct nf_conntrack_protocol **nf_ct_protos[PF_MAX]; +extern struct nf_conntrack_l4proto **nf_ct_protos[PF_MAX]; -extern struct nf_conntrack_protocol * -__nf_ct_proto_find(u_int16_t l3proto, u_int8_t protocol); +extern struct nf_conntrack_l4proto * +__nf_ct_l4proto_find(u_int16_t l3proto, u_int8_t l4proto); -extern struct nf_conntrack_protocol * -nf_ct_proto_find_get(u_int16_t l3proto, u_int8_t protocol); +extern struct nf_conntrack_l4proto * +nf_ct_l4proto_find_get(u_int16_t l3proto, u_int8_t protocol); -extern void nf_ct_proto_put(struct nf_conntrack_protocol *p); +extern void nf_ct_l4proto_put(struct nf_conntrack_l4proto *p); /* Protocol registration. */ -extern int nf_conntrack_protocol_register(struct nf_conntrack_protocol *proto); -extern void nf_conntrack_protocol_unregister(struct nf_conntrack_protocol *proto); +extern int nf_conntrack_l4proto_register(struct nf_conntrack_l4proto *proto); +extern int nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *proto); /* Generic netlink helpers */ extern int nf_ct_port_tuple_to_nfattr(struct sk_buff *skb, diff --git a/include/net/netfilter/nf_conntrack_tuple.h b/include/net/netfilter/nf_conntrack_tuple.h index 530ef1f75283..5d72b16e876f 100644 --- a/include/net/netfilter/nf_conntrack_tuple.h +++ b/include/net/netfilter/nf_conntrack_tuple.h @@ -24,10 +24,10 @@ /* The l3 protocol-specific manipulable parts of the tuple: always in network order! */ -union nf_conntrack_man_l3proto { +union nf_conntrack_address { u_int32_t all[NF_CT_TUPLE_L3SIZE]; - u_int32_t ip; - u_int32_t ip6[4]; + __be32 ip; + __be32 ip6[4]; }; /* The protocol-specific manipulable parts of the tuple: always in @@ -38,23 +38,26 @@ union nf_conntrack_man_proto u_int16_t all; struct { - u_int16_t port; + __be16 port; } tcp; struct { - u_int16_t port; + __be16 port; } udp; struct { - u_int16_t id; + __be16 id; } icmp; struct { - u_int16_t port; + __be16 port; } sctp; + struct { + __be16 key; /* GRE key is 32bit, PPtP only uses 16bit */ + } gre; }; /* The manipulable part of the tuple. */ struct nf_conntrack_man { - union nf_conntrack_man_l3proto u3; + union nf_conntrack_address u3; union nf_conntrack_man_proto u; /* Layer 3 protocol */ u_int16_t l3num; @@ -67,27 +70,26 @@ struct nf_conntrack_tuple /* These are the parts of the tuple which are fixed. */ struct { - union { - u_int32_t all[NF_CT_TUPLE_L3SIZE]; - u_int32_t ip; - u_int32_t ip6[4]; - } u3; + union nf_conntrack_address u3; union { /* Add other protocols here. */ u_int16_t all; struct { - u_int16_t port; + __be16 port; } tcp; struct { - u_int16_t port; + __be16 port; } udp; struct { u_int8_t type, code; } icmp; struct { - u_int16_t port; + __be16 port; } sctp; + struct { + __be16 key; + } gre; } u; /* The protocol. */ diff --git a/include/net/netfilter/nf_nat.h b/include/net/netfilter/nf_nat.h new file mode 100644 index 000000000000..61c62068ca6b --- /dev/null +++ b/include/net/netfilter/nf_nat.h @@ -0,0 +1,77 @@ +#ifndef _NF_NAT_H +#define _NF_NAT_H +#include <linux/netfilter_ipv4.h> +#include <net/netfilter/nf_conntrack_tuple.h> + +#define NF_NAT_MAPPING_TYPE_MAX_NAMELEN 16 + +enum nf_nat_manip_type +{ + IP_NAT_MANIP_SRC, + IP_NAT_MANIP_DST +}; + +/* SRC manip occurs POST_ROUTING or LOCAL_IN */ +#define HOOK2MANIP(hooknum) ((hooknum) != NF_IP_POST_ROUTING && (hooknum) != NF_IP_LOCAL_IN) + +#define IP_NAT_RANGE_MAP_IPS 1 +#define IP_NAT_RANGE_PROTO_SPECIFIED 2 + +/* NAT sequence number modifications */ +struct nf_nat_seq { + /* position of the last TCP sequence number modification (if any) */ + u_int32_t correction_pos; + + /* sequence number offset before and after last modification */ + int16_t offset_before, offset_after; +}; + +/* Single range specification. */ +struct nf_nat_range +{ + /* Set to OR of flags above. */ + unsigned int flags; + + /* Inclusive: network order. */ + __be32 min_ip, max_ip; + + /* Inclusive: network order */ + union nf_conntrack_man_proto min, max; +}; + +/* For backwards compat: don't use in modern code. */ +struct nf_nat_multi_range_compat +{ + unsigned int rangesize; /* Must be 1. */ + + /* hangs off end. */ + struct nf_nat_range range[1]; +}; + +#ifdef __KERNEL__ +#include <linux/list.h> + +/* The structure embedded in the conntrack structure. */ +struct nf_nat_info +{ + struct list_head bysource; + struct nf_nat_seq seq[IP_CT_DIR_MAX]; +}; + +struct nf_conn; + +/* Set up the info structure to map into this range. */ +extern unsigned int nf_nat_setup_info(struct nf_conn *ct, + const struct nf_nat_range *range, + unsigned int hooknum); + +/* Is this tuple already taken? (not by us)*/ +extern int nf_nat_used_tuple(const struct nf_conntrack_tuple *tuple, + const struct nf_conn *ignored_conntrack); + +extern int nf_nat_module_is_loaded; + +#else /* !__KERNEL__: iptables wants this to compile. */ +#define nf_nat_multi_range nf_nat_multi_range_compat +#endif /*__KERNEL__*/ +#endif diff --git a/include/net/netfilter/nf_nat_core.h b/include/net/netfilter/nf_nat_core.h new file mode 100644 index 000000000000..9778ffa93440 --- /dev/null +++ b/include/net/netfilter/nf_nat_core.h @@ -0,0 +1,27 @@ +#ifndef _NF_NAT_CORE_H +#define _NF_NAT_CORE_H +#include <linux/list.h> +#include <net/netfilter/nf_conntrack.h> + +/* This header used to share core functionality between the standalone + NAT module, and the compatibility layer's use of NAT for masquerading. */ + +extern unsigned int nf_nat_packet(struct nf_conn *ct, + enum ip_conntrack_info ctinfo, + unsigned int hooknum, + struct sk_buff **pskb); + +extern int nf_nat_icmp_reply_translation(struct nf_conn *ct, + enum ip_conntrack_info ctinfo, + unsigned int hooknum, + struct sk_buff **pskb); + +static inline int nf_nat_initialized(struct nf_conn *ct, + enum nf_nat_manip_type manip) +{ + if (manip == IP_NAT_MANIP_SRC) + return test_bit(IPS_SRC_NAT_DONE_BIT, &ct->status); + else + return test_bit(IPS_DST_NAT_DONE_BIT, &ct->status); +} +#endif /* _NF_NAT_CORE_H */ diff --git a/include/net/netfilter/nf_nat_helper.h b/include/net/netfilter/nf_nat_helper.h new file mode 100644 index 000000000000..ec98ecf95fc8 --- /dev/null +++ b/include/net/netfilter/nf_nat_helper.h @@ -0,0 +1,32 @@ +#ifndef _NF_NAT_HELPER_H +#define _NF_NAT_HELPER_H +/* NAT protocol helper routines. */ + +#include <net/netfilter/nf_conntrack.h> + +struct sk_buff; + +/* These return true or false. */ +extern int nf_nat_mangle_tcp_packet(struct sk_buff **skb, + struct nf_conn *ct, + enum ip_conntrack_info ctinfo, + unsigned int match_offset, + unsigned int match_len, + const char *rep_buffer, + unsigned int rep_len); +extern int nf_nat_mangle_udp_packet(struct sk_buff **skb, + struct nf_conn *ct, + enum ip_conntrack_info ctinfo, + unsigned int match_offset, + unsigned int match_len, + const char *rep_buffer, + unsigned int rep_len); +extern int nf_nat_seq_adjust(struct sk_buff **pskb, + struct nf_conn *ct, + enum ip_conntrack_info ctinfo); + +/* Setup NAT on this expected conntrack so it follows master, but goes + * to port ct->master->saved_proto. */ +extern void nf_nat_follow_master(struct nf_conn *ct, + struct nf_conntrack_expect *this); +#endif diff --git a/include/net/netfilter/nf_nat_protocol.h b/include/net/netfilter/nf_nat_protocol.h new file mode 100644 index 000000000000..a9ec5ef61468 --- /dev/null +++ b/include/net/netfilter/nf_nat_protocol.h @@ -0,0 +1,70 @@ +/* Header for use in defining a given protocol. */ +#ifndef _NF_NAT_PROTOCOL_H +#define _NF_NAT_PROTOCOL_H +#include <net/netfilter/nf_nat.h> +#include <linux/netfilter/nfnetlink_conntrack.h> + +struct nf_nat_range; + +struct nf_nat_protocol +{ + /* Protocol name */ + const char *name; + + /* Protocol number. */ + unsigned int protonum; + + struct module *me; + + /* Translate a packet to the target according to manip type. + Return true if succeeded. */ + int (*manip_pkt)(struct sk_buff **pskb, + unsigned int iphdroff, + const struct nf_conntrack_tuple *tuple, + enum nf_nat_manip_type maniptype); + + /* Is the manipable part of the tuple between min and max incl? */ + int (*in_range)(const struct nf_conntrack_tuple *tuple, + enum nf_nat_manip_type maniptype, + const union nf_conntrack_man_proto *min, + const union nf_conntrack_man_proto *max); + + /* Alter the per-proto part of the tuple (depending on + maniptype), to give a unique tuple in the given range if + possible; return false if not. Per-protocol part of tuple + is initialized to the incoming packet. */ + int (*unique_tuple)(struct nf_conntrack_tuple *tuple, + const struct nf_nat_range *range, + enum nf_nat_manip_type maniptype, + const struct nf_conn *ct); + + int (*range_to_nfattr)(struct sk_buff *skb, + const struct nf_nat_range *range); + + int (*nfattr_to_range)(struct nfattr *tb[], + struct nf_nat_range *range); +}; + +/* Protocol registration. */ +extern int nf_nat_protocol_register(struct nf_nat_protocol *proto); +extern void nf_nat_protocol_unregister(struct nf_nat_protocol *proto); + +extern struct nf_nat_protocol *nf_nat_proto_find_get(u_int8_t protocol); +extern void nf_nat_proto_put(struct nf_nat_protocol *proto); + +/* Built-in protocols. */ +extern struct nf_nat_protocol nf_nat_protocol_tcp; +extern struct nf_nat_protocol nf_nat_protocol_udp; +extern struct nf_nat_protocol nf_nat_protocol_icmp; +extern struct nf_nat_protocol nf_nat_unknown_protocol; + +extern int init_protocols(void) __init; +extern void cleanup_protocols(void); +extern struct nf_nat_protocol *find_nat_proto(u_int16_t protonum); + +extern int nf_nat_port_range_to_nfattr(struct sk_buff *skb, + const struct nf_nat_range *range); +extern int nf_nat_port_nfattr_to_range(struct nfattr *tb[], + struct nf_nat_range *range); + +#endif /*_NF_NAT_PROTO_H*/ diff --git a/include/net/netfilter/nf_nat_rule.h b/include/net/netfilter/nf_nat_rule.h new file mode 100644 index 000000000000..f191c672bcc6 --- /dev/null +++ b/include/net/netfilter/nf_nat_rule.h @@ -0,0 +1,35 @@ +#ifndef _NF_NAT_RULE_H +#define _NF_NAT_RULE_H +#include <net/netfilter/nf_conntrack.h> +#include <net/netfilter/nf_nat.h> +#include <linux/netfilter_ipv4/ip_tables.h> + +/* Compatibility definitions for ipt_FOO modules */ +#define ip_nat_range nf_nat_range +#define ip_conntrack_tuple nf_conntrack_tuple +#define ip_conntrack_get nf_ct_get +#define ip_conntrack nf_conn +#define ip_nat_setup_info nf_nat_setup_info +#define ip_nat_multi_range_compat nf_nat_multi_range_compat +#define ip_ct_iterate_cleanup nf_ct_iterate_cleanup +#define IP_NF_ASSERT NF_CT_ASSERT + +extern int nf_nat_rule_init(void) __init; +extern void nf_nat_rule_cleanup(void); +extern int nf_nat_rule_find(struct sk_buff **pskb, + unsigned int hooknum, + const struct net_device *in, + const struct net_device *out, + struct nf_conn *ct, + struct nf_nat_info *info); + +extern unsigned int +alloc_null_binding(struct nf_conn *ct, + struct nf_nat_info *info, + unsigned int hooknum); + +extern unsigned int +alloc_null_binding_confirmed(struct nf_conn *ct, + struct nf_nat_info *info, + unsigned int hooknum); +#endif /* _NF_NAT_RULE_H */ diff --git a/include/net/netlabel.h b/include/net/netlabel.h index 12c214b9eadf..83da7e1f0d3d 100644 --- a/include/net/netlabel.h +++ b/include/net/netlabel.h @@ -111,13 +111,34 @@ struct netlbl_lsm_cache { void (*free) (const void *data); void *data; }; +/* The catmap bitmap field MUST be a power of two in length and large + * enough to hold at least 240 bits. Special care (i.e. check the code!) + * should be used when changing these values as the LSM implementation + * probably has functions which rely on the sizes of these types to speed + * processing. */ +#define NETLBL_CATMAP_MAPTYPE u64 +#define NETLBL_CATMAP_MAPCNT 4 +#define NETLBL_CATMAP_MAPSIZE (sizeof(NETLBL_CATMAP_MAPTYPE) * 8) +#define NETLBL_CATMAP_SIZE (NETLBL_CATMAP_MAPSIZE * \ + NETLBL_CATMAP_MAPCNT) +#define NETLBL_CATMAP_BIT (NETLBL_CATMAP_MAPTYPE)0x01 +struct netlbl_lsm_secattr_catmap { + u32 startbit; + NETLBL_CATMAP_MAPTYPE bitmap[NETLBL_CATMAP_MAPCNT]; + struct netlbl_lsm_secattr_catmap *next; +}; +#define NETLBL_SECATTR_NONE 0x00000000 +#define NETLBL_SECATTR_DOMAIN 0x00000001 +#define NETLBL_SECATTR_CACHE 0x00000002 +#define NETLBL_SECATTR_MLS_LVL 0x00000004 +#define NETLBL_SECATTR_MLS_CAT 0x00000008 struct netlbl_lsm_secattr { + u32 flags; + char *domain; u32 mls_lvl; - u32 mls_lvl_vld; - unsigned char *mls_cat; - size_t mls_cat_len; + struct netlbl_lsm_secattr_catmap *mls_cat; struct netlbl_lsm_cache *cache; }; @@ -165,18 +186,54 @@ static inline void netlbl_secattr_cache_free(struct netlbl_lsm_cache *cache) } /** + * netlbl_secattr_catmap_alloc - Allocate a LSM secattr catmap + * @flags: memory allocation flags + * + * Description: + * Allocate memory for a LSM secattr catmap, returns a pointer on success, NULL + * on failure. + * + */ +static inline struct netlbl_lsm_secattr_catmap *netlbl_secattr_catmap_alloc( + gfp_t flags) +{ + return kzalloc(sizeof(struct netlbl_lsm_secattr_catmap), flags); +} + +/** + * netlbl_secattr_catmap_free - Free a LSM secattr catmap + * @catmap: the category bitmap + * + * Description: + * Free a LSM secattr catmap. + * + */ +static inline void netlbl_secattr_catmap_free( + struct netlbl_lsm_secattr_catmap *catmap) +{ + struct netlbl_lsm_secattr_catmap *iter; + + do { + iter = catmap; + catmap = catmap->next; + kfree(iter); + } while (catmap); +} + +/** * netlbl_secattr_init - Initialize a netlbl_lsm_secattr struct * @secattr: the struct to initialize * * Description: - * Initialize an already allocated netlbl_lsm_secattr struct. Returns zero on - * success, negative values on error. + * Initialize an already allocated netlbl_lsm_secattr struct. * */ -static inline int netlbl_secattr_init(struct netlbl_lsm_secattr *secattr) +static inline void netlbl_secattr_init(struct netlbl_lsm_secattr *secattr) { - memset(secattr, 0, sizeof(*secattr)); - return 0; + secattr->flags = 0; + secattr->domain = NULL; + secattr->mls_cat = NULL; + secattr->cache = NULL; } /** @@ -193,7 +250,8 @@ static inline void netlbl_secattr_destroy(struct netlbl_lsm_secattr *secattr) if (secattr->cache) netlbl_secattr_cache_free(secattr->cache); kfree(secattr->domain); - kfree(secattr->mls_cat); + if (secattr->mls_cat) + netlbl_secattr_catmap_free(secattr->mls_cat); } /** @@ -205,7 +263,7 @@ static inline void netlbl_secattr_destroy(struct netlbl_lsm_secattr *secattr) * pointer on success, or NULL on failure. * */ -static inline struct netlbl_lsm_secattr *netlbl_secattr_alloc(int flags) +static inline struct netlbl_lsm_secattr *netlbl_secattr_alloc(gfp_t flags) { return kzalloc(sizeof(struct netlbl_lsm_secattr), flags); } @@ -224,6 +282,51 @@ static inline void netlbl_secattr_free(struct netlbl_lsm_secattr *secattr) kfree(secattr); } +#ifdef CONFIG_NETLABEL +int netlbl_secattr_catmap_walk(struct netlbl_lsm_secattr_catmap *catmap, + u32 offset); +int netlbl_secattr_catmap_walk_rng(struct netlbl_lsm_secattr_catmap *catmap, + u32 offset); +int netlbl_secattr_catmap_setbit(struct netlbl_lsm_secattr_catmap *catmap, + u32 bit, + gfp_t flags); +int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap, + u32 start, + u32 end, + gfp_t flags); +#else +static inline int netlbl_secattr_catmap_walk( + struct netlbl_lsm_secattr_catmap *catmap, + u32 offset) +{ + return -ENOENT; +} + +static inline int netlbl_secattr_catmap_walk_rng( + struct netlbl_lsm_secattr_catmap *catmap, + u32 offset) +{ + return -ENOENT; +} + +static inline int netlbl_secattr_catmap_setbit( + struct netlbl_lsm_secattr_catmap *catmap, + u32 bit, + gfp_t flags) +{ + return 0; +} + +static inline int netlbl_secattr_catmap_setrng( + struct netlbl_lsm_secattr_catmap *catmap, + u32 start, + u32 end, + gfp_t flags) +{ + return 0; +} +#endif + /* * LSM protocol operations */ diff --git a/include/net/netlink.h b/include/net/netlink.h index ce5cba19c393..fd75fd65d59e 100644 --- a/include/net/netlink.h +++ b/include/net/netlink.h @@ -500,14 +500,15 @@ static inline struct nlmsghdr *nlmsg_put_answer(struct sk_buff *skb, /** * nlmsg_new - Allocate a new netlink message - * @size: maximum size of message + * @payload: size of the message payload * @flags: the type of memory to allocate. * - * Use NLMSG_GOODSIZE if size isn't know and you need a good default size. + * Use NLMSG_DEFAULT_SIZE if the size of the payload isn't known + * and a good default is needed. */ -static inline struct sk_buff *nlmsg_new(int size, gfp_t flags) +static inline struct sk_buff *nlmsg_new(size_t payload, gfp_t flags) { - return alloc_skb(size, flags); + return alloc_skb(nlmsg_total_size(payload), flags); } /** @@ -828,6 +829,9 @@ static inline int nla_put_msecs(struct sk_buff *skb, int attrtype, #define NLA_PUT_U16(skb, attrtype, value) \ NLA_PUT_TYPE(skb, u16, attrtype, value) +#define NLA_PUT_LE16(skb, attrtype, value) \ + NLA_PUT_TYPE(skb, __le16, attrtype, value) + #define NLA_PUT_U32(skb, attrtype, value) \ NLA_PUT_TYPE(skb, u32, attrtype, value) @@ -874,6 +878,15 @@ static inline u16 nla_get_u16(struct nlattr *nla) } /** + * nla_get_le16 - return payload of __le16 attribute + * @nla: __le16 netlink attribute + */ +static inline __le16 nla_get_le16(struct nlattr *nla) +{ + return *(__le16 *) nla_data(nla); +} + +/** * nla_get_u8 - return payload of u8 attribute * @nla: u8 netlink attribute */ diff --git a/include/net/protocol.h b/include/net/protocol.h index c643bce64e55..105bf12b0c79 100644 --- a/include/net/protocol.h +++ b/include/net/protocol.h @@ -50,7 +50,7 @@ struct inet6_protocol void (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt, int type, int code, int offset, - __u32 info); + __be32 info); int (*gso_send_check)(struct sk_buff *skb); struct sk_buff *(*gso_segment)(struct sk_buff *skb, @@ -71,7 +71,7 @@ struct inet_protosw { /* These two fields form the lookup key. */ unsigned short type; /* This is the 2nd argument to socket(2). */ - int protocol; /* This is the L4 protocol number. */ + unsigned short protocol; /* This is the L4 protocol number. */ struct proto *prot; const struct proto_ops *ops; diff --git a/include/net/rawv6.h b/include/net/rawv6.h index 14476a71725e..af8960878ef4 100644 --- a/include/net/rawv6.h +++ b/include/net/rawv6.h @@ -21,7 +21,7 @@ extern void rawv6_err(struct sock *sk, struct sk_buff *skb, struct inet6_skb_parm *opt, int type, int code, - int offset, u32 info); + int offset, __be32 info); #endif diff --git a/include/net/request_sock.h b/include/net/request_sock.h index 8e165ca16bd8..e37baaf2080b 100644 --- a/include/net/request_sock.h +++ b/include/net/request_sock.h @@ -28,14 +28,15 @@ struct proto; struct request_sock_ops { int family; - kmem_cache_t *slab; int obj_size; + kmem_cache_t *slab; int (*rtx_syn_ack)(struct sock *sk, struct request_sock *req, struct dst_entry *dst); void (*send_ack)(struct sk_buff *skb, struct request_sock *req); - void (*send_reset)(struct sk_buff *skb); + void (*send_reset)(struct sock *sk, + struct sk_buff *skb); void (*destructor)(struct request_sock *req); }; @@ -51,12 +52,13 @@ struct request_sock { u32 rcv_wnd; /* rcv_wnd offered first time */ u32 ts_recent; unsigned long expires; - struct request_sock_ops *rsk_ops; + const struct request_sock_ops *rsk_ops; struct sock *sk; u32 secid; + u32 peer_secid; }; -static inline struct request_sock *reqsk_alloc(struct request_sock_ops *ops) +static inline struct request_sock *reqsk_alloc(const struct request_sock_ops *ops) { struct request_sock *req = kmem_cache_alloc(ops->slab, SLAB_ATOMIC); @@ -120,7 +122,7 @@ struct request_sock_queue { }; extern int reqsk_queue_alloc(struct request_sock_queue *queue, - const int nr_table_entries); + unsigned int nr_table_entries); static inline struct listen_sock *reqsk_queue_yank_listen_sk(struct request_sock_queue *queue) { diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index b0e9108a4e18..82086392735a 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h @@ -60,6 +60,7 @@ struct Qdisc_class_ops int (*graft)(struct Qdisc *, unsigned long cl, struct Qdisc *, struct Qdisc **); struct Qdisc * (*leaf)(struct Qdisc *, unsigned long cl); + void (*qlen_notify)(struct Qdisc *, unsigned long); /* Class manipulation routines */ unsigned long (*get)(struct Qdisc *, u32 classid); @@ -144,7 +145,7 @@ struct tcf_proto void *root; int (*classify)(struct sk_buff*, struct tcf_proto*, struct tcf_result *); - u32 protocol; + __be16 protocol; /* All the rest */ u32 prio; @@ -172,9 +173,10 @@ extern void dev_activate(struct net_device *dev); extern void dev_deactivate(struct net_device *dev); extern void qdisc_reset(struct Qdisc *qdisc); extern void qdisc_destroy(struct Qdisc *qdisc); +extern void qdisc_tree_decrease_qlen(struct Qdisc *qdisc, unsigned int n); extern struct Qdisc *qdisc_alloc(struct net_device *dev, struct Qdisc_ops *ops); extern struct Qdisc *qdisc_create_dflt(struct net_device *dev, - struct Qdisc_ops *ops); + struct Qdisc_ops *ops, u32 parentid); static inline void tcf_destroy(struct tcf_proto *tp) diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h index 807d6f1ef4b5..6114c4f54b0a 100644 --- a/include/net/sctp/command.h +++ b/include/net/sctp/command.h @@ -116,9 +116,11 @@ typedef enum { typedef union { __s32 i32; __u32 u32; + __be32 be32; __u16 u16; __u8 u8; int error; + __be16 err; sctp_state_t state; sctp_event_timeout_t to; unsigned long zero; @@ -164,9 +166,11 @@ SCTP_## name (type arg) \ SCTP_ARG_CONSTRUCTOR(I32, __s32, i32) SCTP_ARG_CONSTRUCTOR(U32, __u32, u32) +SCTP_ARG_CONSTRUCTOR(BE32, __be32, be32) SCTP_ARG_CONSTRUCTOR(U16, __u16, u16) SCTP_ARG_CONSTRUCTOR(U8, __u8, u8) SCTP_ARG_CONSTRUCTOR(ERROR, int, error) +SCTP_ARG_CONSTRUCTOR(PERR, __be16, err) /* protocol error */ SCTP_ARG_CONSTRUCTOR(STATE, sctp_state_t, state) SCTP_ARG_CONSTRUCTOR(TO, sctp_event_timeout_t, to) SCTP_ARG_CONSTRUCTOR(PTR, void *, ptr) diff --git a/include/net/sctp/constants.h b/include/net/sctp/constants.h index 6c632e26f72d..5ddb85599863 100644 --- a/include/net/sctp/constants.h +++ b/include/net/sctp/constants.h @@ -356,7 +356,7 @@ typedef enum { * addresses. */ #define IS_IPV4_UNUSABLE_ADDRESS(a) \ - ((INADDR_BROADCAST == *a) || \ + ((htonl(INADDR_BROADCAST) == *a) || \ (MULTICAST(*a)) || \ (((unsigned char *)(a))[0] == 0) || \ ((((unsigned char *)(a))[0] == 198) && \ diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h index 764e3af5be93..215461f18db1 100644 --- a/include/net/sctp/sctp.h +++ b/include/net/sctp/sctp.h @@ -585,7 +585,7 @@ static inline int ipver2af(__u8 ipver) } /* Convert from an address parameter type to an address family. */ -static inline int param_type2af(__u16 type) +static inline int param_type2af(__be16 type) { switch (type) { case SCTP_PARAM_IPV4_ADDRESS: diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h index de313de4fefe..3269ed1cc222 100644 --- a/include/net/sctp/sm.h +++ b/include/net/sctp/sm.h @@ -213,7 +213,7 @@ struct sctp_chunk *sctp_make_shutdown_ack(const struct sctp_association *asoc, const struct sctp_chunk *); struct sctp_chunk *sctp_make_shutdown_complete(const struct sctp_association *, const struct sctp_chunk *); -void sctp_init_cause(struct sctp_chunk *, __u16 cause, const void *, size_t); +void sctp_init_cause(struct sctp_chunk *, __be16 cause, const void *, size_t); struct sctp_chunk *sctp_make_abort(const struct sctp_association *, const struct sctp_chunk *, const size_t hint); @@ -236,14 +236,14 @@ struct sctp_chunk *sctp_make_heartbeat_ack(const struct sctp_association *, const size_t paylen); struct sctp_chunk *sctp_make_op_error(const struct sctp_association *, const struct sctp_chunk *chunk, - __u16 cause_code, + __be16 cause_code, const void *payload, size_t paylen); struct sctp_chunk *sctp_make_asconf_update_ip(struct sctp_association *, union sctp_addr *, struct sockaddr *, - int, __u16); + int, __be16); struct sctp_chunk *sctp_make_asconf_set_prim(struct sctp_association *asoc, union sctp_addr *addr); struct sctp_chunk *sctp_process_asconf(struct sctp_association *asoc, diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 60b684470db8..c089f93ba591 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -537,7 +537,7 @@ struct sctp_af { struct net_device *); void (*dst_saddr) (union sctp_addr *saddr, struct dst_entry *dst, - unsigned short port); + __be16 port); int (*cmp_addr) (const union sctp_addr *addr1, const union sctp_addr *addr2); void (*addr_copy) (union sctp_addr *dst, @@ -553,14 +553,14 @@ struct sctp_af { struct sock *sk); void (*from_addr_param) (union sctp_addr *, union sctp_addr_param *, - __u16 port, int iif); + __be16 port, int iif); int (*to_addr_param) (const union sctp_addr *, union sctp_addr_param *); int (*addr_valid) (union sctp_addr *, struct sctp_sock *, const struct sk_buff *); sctp_scope_t (*scope) (union sctp_addr *); - void (*inaddr_any) (union sctp_addr *, unsigned short); + void (*inaddr_any) (union sctp_addr *, __be16); int (*is_any) (const union sctp_addr *); int (*available) (union sctp_addr *, struct sctp_sock *); @@ -587,7 +587,7 @@ struct sctp_pf { struct sctp_sock *); int (*bind_verify) (struct sctp_sock *, union sctp_addr *); int (*send_verify) (struct sctp_sock *, union sctp_addr *); - int (*supported_addrs)(const struct sctp_sock *, __u16 *); + int (*supported_addrs)(const struct sctp_sock *, __be16 *); struct sock *(*create_accept_sk) (struct sock *sk, struct sctp_association *asoc); void (*addr_v4map) (struct sctp_sock *, union sctp_addr *); @@ -1270,7 +1270,7 @@ struct sctp_endpoint { * this here so we pre-allocate this once and can re-use * on every receive. */ - __u8 digest[SCTP_SIGNATURE_SIZE]; + __u8 *digest; /* sendbuf acct. policy. */ __u32 sndbuf_policy; @@ -1314,6 +1314,13 @@ int sctp_process_init(struct sctp_association *, sctp_cid_t cid, __u32 sctp_generate_tag(const struct sctp_endpoint *); __u32 sctp_generate_tsn(const struct sctp_endpoint *); +struct sctp_inithdr_host { + __u32 init_tag; + __u32 a_rwnd; + __u16 num_outbound_streams; + __u16 num_inbound_streams; + __u32 initial_tsn; +}; /* RFC2960 * @@ -1482,9 +1489,9 @@ struct sctp_association { /* This mask is used to disable sending the ASCONF chunk * with specified parameter to peer. */ - __u16 addip_disabled_mask; + __be16 addip_disabled_mask; - struct sctp_inithdr i; + struct sctp_inithdr_host i; int cookie_len; void *cookie; diff --git a/include/net/sctp/tsnmap.h b/include/net/sctp/tsnmap.h index 021947da70ea..70a824df6f60 100644 --- a/include/net/sctp/tsnmap.h +++ b/include/net/sctp/tsnmap.h @@ -105,7 +105,7 @@ struct sctp_tsnmap { * every SACK. Store up to SCTP_MAX_DUP_TSNS worth of * information. */ - __u32 dup_tsns[SCTP_MAX_DUP_TSNS]; + __be32 dup_tsns[SCTP_MAX_DUP_TSNS]; __u16 num_dup_tsns; /* Record gap ack block information here. */ @@ -162,7 +162,7 @@ static inline __u16 sctp_tsnmap_num_dups(struct sctp_tsnmap *map) } /* Return pointer to duplicate tsn array as needed by SACK. */ -static inline __u32 *sctp_tsnmap_get_dups(struct sctp_tsnmap *map) +static inline __be32 *sctp_tsnmap_get_dups(struct sctp_tsnmap *map) { map->num_dup_tsns = 0; return map->dup_tsns; diff --git a/include/net/sock.h b/include/net/sock.h index ac286a353032..26fc0b16bc0c 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -745,7 +745,13 @@ static inline int sk_stream_wmem_schedule(struct sock *sk, int size) */ #define sock_owned_by_user(sk) ((sk)->sk_lock.owner) -extern void FASTCALL(lock_sock(struct sock *sk)); +extern void FASTCALL(lock_sock_nested(struct sock *sk, int subclass)); + +static inline void lock_sock(struct sock *sk) +{ + lock_sock_nested(sk, 0); +} + extern void FASTCALL(release_sock(struct sock *sk)); /* BH context may only use the following locking interface. */ @@ -883,18 +889,23 @@ static inline int sk_filter(struct sock *sk, struct sk_buff *skb) } /** - * sk_filter_release: Release a socket filter - * @rcu: rcu_head that contains the sk_filter info to remove - * - * Remove a filter from a socket and release its resources. + * sk_filter_rcu_free: Free a socket filter + * @rcu: rcu_head that contains the sk_filter to free */ - static inline void sk_filter_rcu_free(struct rcu_head *rcu) { struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu); kfree(fp); } +/** + * sk_filter_release: Release a socket filter + * @sk: socket + * @fp: filter to remove + * + * Remove a filter from a socket and release its resources. + */ + static inline void sk_filter_release(struct sock *sk, struct sk_filter *fp) { unsigned int size = sk_filter_len(fp); @@ -943,7 +954,8 @@ static inline void sock_put(struct sock *sk) sk_free(sk); } -extern int sk_receive_skb(struct sock *sk, struct sk_buff *skb); +extern int sk_receive_skb(struct sock *sk, struct sk_buff *skb, + const int nested); /* Detach socket from process context. * Announce socket dead, detach it from wait queue and inode. @@ -1077,7 +1089,7 @@ static inline int skb_copy_to_page(struct sock *sk, char __user *from, { if (skb->ip_summed == CHECKSUM_NONE) { int err = 0; - unsigned int csum = csum_and_copy_from_user(from, + __wsum csum = csum_and_copy_from_user(from, page_address(page) + off, copy, 0, &err); if (err) diff --git a/include/net/tcp.h b/include/net/tcp.h index 7a093d0aa0fe..c99774f15eba 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h @@ -28,6 +28,7 @@ #include <linux/percpu.h> #include <linux/skbuff.h> #include <linux/dmaengine.h> +#include <linux/crypto.h> #include <net/inet_connection_sock.h> #include <net/inet_timewait_sock.h> @@ -138,7 +139,6 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo); #define MAX_TCP_SYNCNT 127 #define TCP_SYNQ_INTERVAL (HZ/5) /* Period of SYNACK timer */ -#define TCP_SYNQ_HSIZE 512 /* Size of SYNACK hash table */ #define TCP_PAWS_24DAYS (60 * 60 * 24 * 24) #define TCP_PAWS_MSL 60 /* Per-host timestamps are invalidated @@ -162,6 +162,7 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo); #define TCPOPT_SACK_PERM 4 /* SACK Permitted */ #define TCPOPT_SACK 5 /* SACK Block */ #define TCPOPT_TIMESTAMP 8 /* Better RTT estimations/PAWS */ +#define TCPOPT_MD5SIG 19 /* MD5 Signature (RFC2385) */ /* * TCP option lengths @@ -171,6 +172,7 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo); #define TCPOLEN_WINDOW 3 #define TCPOLEN_SACK_PERM 2 #define TCPOLEN_TIMESTAMP 10 +#define TCPOLEN_MD5SIG 18 /* But this is what stacks really send out. */ #define TCPOLEN_TSTAMP_ALIGNED 12 @@ -179,6 +181,7 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo); #define TCPOLEN_SACK_BASE 2 #define TCPOLEN_SACK_BASE_ALIGNED 4 #define TCPOLEN_SACK_PERBLOCK 8 +#define TCPOLEN_MD5SIG_ALIGNED 20 /* Flags in tp->nonagle */ #define TCP_NAGLE_OFF 1 /* Nagle's algo is disabled */ @@ -300,6 +303,8 @@ extern void tcp_cleanup_rbuf(struct sock *sk, int copied); extern int tcp_twsk_unique(struct sock *sk, struct sock *sktw, void *twp); +extern void tcp_twsk_destructor(struct sock *sk); + static inline void tcp_dec_quickack_mode(struct sock *sk, const unsigned int pkts) { @@ -621,8 +626,12 @@ enum tcp_ca_event { * Interface for adding new TCP congestion control handlers */ #define TCP_CA_NAME_MAX 16 +#define TCP_CA_MAX 128 +#define TCP_CA_BUF_MAX (TCP_CA_NAME_MAX*TCP_CA_MAX) + struct tcp_congestion_ops { struct list_head list; + int non_restricted; /* initialize private data (optional) */ void (*init)(struct sock *sk); @@ -660,6 +669,9 @@ extern void tcp_init_congestion_control(struct sock *sk); extern void tcp_cleanup_congestion_control(struct sock *sk); extern int tcp_set_default_congestion_control(const char *name); extern void tcp_get_default_congestion_control(char *name); +extern void tcp_get_available_congestion_control(char *buf, size_t len); +extern void tcp_get_allowed_congestion_control(char *buf, size_t len); +extern int tcp_set_allowed_congestion_control(char *allowed); extern int tcp_set_congestion_control(struct sock *sk, const char *name); extern void tcp_slow_start(struct tcp_sock *tp); @@ -795,14 +807,14 @@ static inline void tcp_update_wl(struct tcp_sock *tp, u32 ack, u32 seq) /* * Calculate(/check) TCP checksum */ -static inline u16 tcp_v4_check(struct tcphdr *th, int len, - unsigned long saddr, unsigned long daddr, - unsigned long base) +static inline __sum16 tcp_v4_check(struct tcphdr *th, int len, + __be32 saddr, __be32 daddr, + __wsum base) { return csum_tcpudp_magic(saddr,daddr,len,IPPROTO_TCP,base); } -static inline int __tcp_checksum_complete(struct sk_buff *skb) +static inline __sum16 __tcp_checksum_complete(struct sk_buff *skb) { return __skb_checksum_complete(skb); } @@ -1058,6 +1070,114 @@ static inline void clear_all_retrans_hints(struct tcp_sock *tp){ tp->fastpath_skb_hint = NULL; } +/* MD5 Signature */ +struct crypto_hash; + +/* - key database */ +struct tcp_md5sig_key { + u8 *key; + u8 keylen; +}; + +struct tcp4_md5sig_key { + u8 *key; + u16 keylen; + __be32 addr; +}; + +struct tcp6_md5sig_key { + u8 *key; + u16 keylen; +#if 0 + u32 scope_id; /* XXX */ +#endif + struct in6_addr addr; +}; + +/* - sock block */ +struct tcp_md5sig_info { + struct tcp4_md5sig_key *keys4; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + struct tcp6_md5sig_key *keys6; + u32 entries6; + u32 alloced6; +#endif + u32 entries4; + u32 alloced4; +}; + +/* - pseudo header */ +struct tcp4_pseudohdr { + __be32 saddr; + __be32 daddr; + __u8 pad; + __u8 protocol; + __be16 len; +}; + +struct tcp6_pseudohdr { + struct in6_addr saddr; + struct in6_addr daddr; + __be32 len; + __be32 protocol; /* including padding */ +}; + +union tcp_md5sum_block { + struct tcp4_pseudohdr ip4; +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) + struct tcp6_pseudohdr ip6; +#endif +}; + +/* - pool: digest algorithm, hash description and scratch buffer */ +struct tcp_md5sig_pool { + struct hash_desc md5_desc; + union tcp_md5sum_block md5_blk; +}; + +#define TCP_MD5SIG_MAXKEYS (~(u32)0) /* really?! */ + +/* - functions */ +extern int tcp_v4_calc_md5_hash(char *md5_hash, + struct tcp_md5sig_key *key, + struct sock *sk, + struct dst_entry *dst, + struct request_sock *req, + struct tcphdr *th, + int protocol, int tcplen); +extern struct tcp_md5sig_key *tcp_v4_md5_lookup(struct sock *sk, + struct sock *addr_sk); + +extern int tcp_v4_md5_do_add(struct sock *sk, + __be32 addr, + u8 *newkey, + u8 newkeylen); + +extern int tcp_v4_md5_do_del(struct sock *sk, + __be32 addr); + +extern struct tcp_md5sig_pool **tcp_alloc_md5sig_pool(void); +extern void tcp_free_md5sig_pool(void); + +extern struct tcp_md5sig_pool *__tcp_get_md5sig_pool(int cpu); +extern void __tcp_put_md5sig_pool(void); + +static inline +struct tcp_md5sig_pool *tcp_get_md5sig_pool(void) +{ + int cpu = get_cpu(); + struct tcp_md5sig_pool *ret = __tcp_get_md5sig_pool(cpu); + if (!ret) + put_cpu(); + return ret; +} + +static inline void tcp_put_md5sig_pool(void) +{ + __tcp_put_md5sig_pool(); + put_cpu(); +} + /* /proc */ enum tcp_seq_states { TCP_SEQ_STATE_LISTENING, @@ -1097,6 +1217,35 @@ extern int tcp4_proc_init(void); extern void tcp4_proc_exit(void); #endif +/* TCP af-specific functions */ +struct tcp_sock_af_ops { +#ifdef CONFIG_TCP_MD5SIG + struct tcp_md5sig_key *(*md5_lookup) (struct sock *sk, + struct sock *addr_sk); + int (*calc_md5_hash) (char *location, + struct tcp_md5sig_key *md5, + struct sock *sk, + struct dst_entry *dst, + struct request_sock *req, + struct tcphdr *th, + int protocol, int len); + int (*md5_add) (struct sock *sk, + struct sock *addr_sk, + u8 *newkey, + u8 len); + int (*md5_parse) (struct sock *sk, + char __user *optval, + int optlen); +#endif +}; + +struct tcp_request_sock_ops { +#ifdef CONFIG_TCP_MD5SIG + struct tcp_md5sig_key *(*md5_lookup) (struct sock *sk, + struct request_sock *req); +#endif +}; + extern void tcp_v4_init(struct net_proto_family *ops); extern void tcp_init(void); diff --git a/include/net/timewait_sock.h b/include/net/timewait_sock.h index be293d795e38..d7a306ea560d 100644 --- a/include/net/timewait_sock.h +++ b/include/net/timewait_sock.h @@ -31,6 +31,9 @@ static inline int twsk_unique(struct sock *sk, struct sock *sktw, void *twp) static inline void twsk_destructor(struct sock *sk) { + BUG_ON(sk == NULL); + BUG_ON(sk->sk_prot == NULL); + BUG_ON(sk->sk_prot->twsk_prot == NULL); if (sk->sk_prot->twsk_prot->twsk_destructor != NULL) sk->sk_prot->twsk_prot->twsk_destructor(sk); } diff --git a/include/net/tipc/tipc_bearer.h b/include/net/tipc/tipc_bearer.h index e07136d74c2f..2151a80cdf30 100644 --- a/include/net/tipc/tipc_bearer.h +++ b/include/net/tipc/tipc_bearer.h @@ -58,7 +58,7 @@ */ struct tipc_media_addr { - __u32 type; /* bearer type (network byte order) */ + __be32 type; /* bearer type (network byte order) */ union { __u8 eth_addr[6]; /* 48 bit Ethernet addr (byte array) */ #if 0 diff --git a/include/net/tipc/tipc_msg.h b/include/net/tipc/tipc_msg.h index 4d096eebc93f..fb42eb7a86a5 100644 --- a/include/net/tipc/tipc_msg.h +++ b/include/net/tipc/tipc_msg.h @@ -40,7 +40,7 @@ #ifdef __KERNEL__ struct tipc_msg { - u32 hdr[15]; + __be32 hdr[15]; }; diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h index 61f724c1036f..409da3a9a455 100644 --- a/include/net/transp_v6.h +++ b/include/net/transp_v6.h @@ -11,6 +11,7 @@ extern struct proto rawv6_prot; extern struct proto udpv6_prot; +extern struct proto udplitev6_prot; extern struct proto tcpv6_prot; struct flowi; @@ -24,6 +25,7 @@ extern void ipv6_destopt_init(void); /* transport protocols */ extern void rawv6_init(void); extern void udpv6_init(void); +extern void udplitev6_init(void); extern void tcpv6_init(void); extern int udpv6_connect(struct sock *sk, diff --git a/include/net/udp.h b/include/net/udp.h index db0c05f67546..1548d68d45da 100644 --- a/include/net/udp.h +++ b/include/net/udp.h @@ -26,9 +26,28 @@ #include <net/inet_sock.h> #include <net/sock.h> #include <net/snmp.h> +#include <net/ip.h> +#include <linux/ipv6.h> #include <linux/seq_file.h> -#define UDP_HTABLE_SIZE 128 +/** + * struct udp_skb_cb - UDP(-Lite) private variables + * + * @header: private variables used by IPv4/IPv6 + * @cscov: checksum coverage length (UDP-Lite only) + * @partial_cov: if set indicates partial csum coverage + */ +struct udp_skb_cb { + union { + struct inet_skb_parm h4; +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE) + struct inet6_skb_parm h6; +#endif + } header; + __u16 cscov; + __u8 partial_cov; +}; +#define UDP_SKB_CB(__skb) ((struct udp_skb_cb *)((__skb)->cb)) extern struct hlist_head udp_hash[UDP_HTABLE_SIZE]; extern rwlock_t udp_hash_lock; @@ -47,6 +66,62 @@ extern struct proto udp_prot; struct sk_buff; +/* + * Generic checksumming routines for UDP(-Lite) v4 and v6 + */ +static inline __sum16 __udp_lib_checksum_complete(struct sk_buff *skb) +{ + if (! UDP_SKB_CB(skb)->partial_cov) + return __skb_checksum_complete(skb); + return csum_fold(skb_checksum(skb, 0, UDP_SKB_CB(skb)->cscov, + skb->csum)); +} + +static inline int udp_lib_checksum_complete(struct sk_buff *skb) +{ + return skb->ip_summed != CHECKSUM_UNNECESSARY && + __udp_lib_checksum_complete(skb); +} + +/** + * udp_csum_outgoing - compute UDPv4/v6 checksum over fragments + * @sk: socket we are writing to + * @skb: sk_buff containing the filled-in UDP header + * (checksum field must be zeroed out) + */ +static inline __wsum udp_csum_outgoing(struct sock *sk, struct sk_buff *skb) +{ + __wsum csum = csum_partial(skb->h.raw, sizeof(struct udphdr), 0); + + skb_queue_walk(&sk->sk_write_queue, skb) { + csum = csum_add(csum, skb->csum); + } + return csum; +} + +/* hash routines shared between UDPv4/6 and UDP-Litev4/6 */ +static inline void udp_lib_hash(struct sock *sk) +{ + BUG(); +} + +static inline void udp_lib_unhash(struct sock *sk) +{ + write_lock_bh(&udp_hash_lock); + if (sk_del_node_init(sk)) { + inet_sk(sk)->num = 0; + sock_prot_dec_use(sk->sk_prot); + } + write_unlock_bh(&udp_hash_lock); +} + +static inline void udp_lib_close(struct sock *sk, long timeout) +{ + sk_common_release(sk); +} + + +/* net/ipv4/udp.c */ extern int udp_get_port(struct sock *sk, unsigned short snum, int (*saddr_cmp)(const struct sock *, const struct sock *)); extern void udp_err(struct sk_buff *, u32); @@ -59,23 +134,36 @@ extern int udp_ioctl(struct sock *sk, int cmd, unsigned long arg); extern int udp_disconnect(struct sock *sk, int flags); extern unsigned int udp_poll(struct file *file, struct socket *sock, poll_table *wait); +extern int udp_lib_getsockopt(struct sock *sk, int level, int optname, + char __user *optval, int __user *optlen); +extern int udp_lib_setsockopt(struct sock *sk, int level, int optname, + char __user *optval, int optlen, + int (*push_pending_frames)(struct sock *)); DECLARE_SNMP_STAT(struct udp_mib, udp_statistics); -#define UDP_INC_STATS(field) SNMP_INC_STATS(udp_statistics, field) -#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) +/* + * SNMP statistics for UDP and UDP-Lite + */ +#define UDP_INC_STATS_USER(field, is_udplite) do { \ + if (is_udplite) SNMP_INC_STATS_USER(udplite_statistics, field); \ + else SNMP_INC_STATS_USER(udp_statistics, field); } while(0) +#define UDP_INC_STATS_BH(field, is_udplite) do { \ + if (is_udplite) SNMP_INC_STATS_BH(udplite_statistics, field); \ + else SNMP_INC_STATS_BH(udp_statistics, field); } while(0) /* /proc */ struct udp_seq_afinfo { struct module *owner; char *name; sa_family_t family; + struct hlist_head *hashtable; int (*seq_show) (struct seq_file *m, void *v); struct file_operations *seq_fops; }; struct udp_iter_state { sa_family_t family; + struct hlist_head *hashtable; int bucket; struct seq_operations seq_ops; }; diff --git a/include/net/udplite.h b/include/net/udplite.h new file mode 100644 index 000000000000..67ac51424307 --- /dev/null +++ b/include/net/udplite.h @@ -0,0 +1,151 @@ +/* + * Definitions for the UDP-Lite (RFC 3828) code. + */ +#ifndef _UDPLITE_H +#define _UDPLITE_H + +#include <net/ip6_checksum.h> + +/* UDP-Lite socket options */ +#define UDPLITE_SEND_CSCOV 10 /* sender partial coverage (as sent) */ +#define UDPLITE_RECV_CSCOV 11 /* receiver partial coverage (threshold ) */ + +extern struct proto udplite_prot; +extern struct hlist_head udplite_hash[UDP_HTABLE_SIZE]; + +/* UDP-Lite does not have a standardized MIB yet, so we inherit from UDP */ +DECLARE_SNMP_STAT(struct udp_mib, udplite_statistics); + +/* + * Checksum computation is all in software, hence simpler getfrag. + */ +static __inline__ int udplite_getfrag(void *from, char *to, int offset, + int len, int odd, struct sk_buff *skb) +{ + return memcpy_fromiovecend(to, (struct iovec *) from, offset, len); +} + +/* Designate sk as UDP-Lite socket */ +static inline int udplite_sk_init(struct sock *sk) +{ + udp_sk(sk)->pcflag = UDPLITE_BIT; + return 0; +} + +/* + * Checksumming routines + */ +static inline int udplite_checksum_init(struct sk_buff *skb, struct udphdr *uh) +{ + u16 cscov; + + /* In UDPv4 a zero checksum means that the transmitter generated no + * checksum. UDP-Lite (like IPv6) mandates checksums, hence packets + * with a zero checksum field are illegal. */ + if (uh->check == 0) { + LIMIT_NETDEBUG(KERN_DEBUG "UDPLITE: zeroed checksum field\n"); + return 1; + } + + UDP_SKB_CB(skb)->partial_cov = 0; + cscov = ntohs(uh->len); + + if (cscov == 0) /* Indicates that full coverage is required. */ + cscov = skb->len; + else if (cscov < 8 || cscov > skb->len) { + /* + * Coverage length violates RFC 3828: log and discard silently. + */ + LIMIT_NETDEBUG(KERN_DEBUG "UDPLITE: bad csum coverage %d/%d\n", + cscov, skb->len); + return 1; + + } else if (cscov < skb->len) + UDP_SKB_CB(skb)->partial_cov = 1; + + UDP_SKB_CB(skb)->cscov = cscov; + + /* + * There is no known NIC manufacturer supporting UDP-Lite yet, + * hence ip_summed is always (re-)set to CHECKSUM_NONE. + */ + skb->ip_summed = CHECKSUM_NONE; + + return 0; +} + +static __inline__ int udplite4_csum_init(struct sk_buff *skb, struct udphdr *uh) +{ + int rc = udplite_checksum_init(skb, uh); + + if (!rc) + skb->csum = csum_tcpudp_nofold(skb->nh.iph->saddr, + skb->nh.iph->daddr, + skb->len, IPPROTO_UDPLITE, 0); + return rc; +} + +static __inline__ int udplite6_csum_init(struct sk_buff *skb, struct udphdr *uh) +{ + int rc = udplite_checksum_init(skb, uh); + + if (!rc) + skb->csum = ~csum_unfold(csum_ipv6_magic(&skb->nh.ipv6h->saddr, + &skb->nh.ipv6h->daddr, + skb->len, IPPROTO_UDPLITE, 0)); + return rc; +} + +static inline int udplite_sender_cscov(struct udp_sock *up, struct udphdr *uh) +{ + int cscov = up->len; + + /* + * Sender has set `partial coverage' option on UDP-Lite socket + */ + if (up->pcflag & UDPLITE_SEND_CC) { + if (up->pcslen < up->len) { + /* up->pcslen == 0 means that full coverage is required, + * partial coverage only if 0 < up->pcslen < up->len */ + if (0 < up->pcslen) { + cscov = up->pcslen; + } + uh->len = htons(up->pcslen); + } + /* + * NOTE: Causes for the error case `up->pcslen > up->len': + * (i) Application error (will not be penalized). + * (ii) Payload too big for send buffer: data is split + * into several packets, each with its own header. + * In this case (e.g. last segment), coverage may + * exceed packet length. + * Since packets with coverage length > packet length are + * illegal, we fall back to the defaults here. + */ + } + return cscov; +} + +static inline __wsum udplite_csum_outgoing(struct sock *sk, struct sk_buff *skb) +{ + int off, len, cscov = udplite_sender_cscov(udp_sk(sk), skb->h.uh); + __wsum csum = 0; + + skb->ip_summed = CHECKSUM_NONE; /* no HW support for checksumming */ + + skb_queue_walk(&sk->sk_write_queue, skb) { + off = skb->h.raw - skb->data; + len = skb->len - off; + + csum = skb_checksum(skb, off, (cscov > len)? len : cscov, csum); + + if ((cscov -= len) <= 0) + break; + } + return csum; +} + +extern void udplite4_register(void); +extern int udplite_get_port(struct sock *sk, unsigned short snum, + int (*scmp)(const struct sock *, const struct sock *)); +#endif /* _UDPLITE_H */ diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 737fdb2ee8a4..15ec19dcf9c8 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -310,6 +310,8 @@ struct xfrm_tmpl /* Source address of tunnel. Ignored, if it is not a tunnel. */ xfrm_address_t saddr; + unsigned short encap_family; + __u32 reqid; /* Mode: transport, tunnel etc. */ @@ -340,18 +342,19 @@ struct xfrm_policy atomic_t refcnt; struct timer_list timer; - u8 type; u32 priority; u32 index; struct xfrm_selector selector; struct xfrm_lifetime_cfg lft; struct xfrm_lifetime_cur curlft; struct dst_entry *bundles; - __u16 family; - __u8 action; - __u8 flags; - __u8 dead; - __u8 xfrm_nr; + u16 family; + u8 type; + u8 action; + u8 flags; + u8 dead; + u8 xfrm_nr; + /* XXX 1 byte hole, try to pack */ struct xfrm_sec_ctx *security; struct xfrm_tmpl xfrm_vec[XFRM_MAX_DEPTH]; }; @@ -379,7 +382,7 @@ struct xfrm_mgr int (*notify)(struct xfrm_state *x, struct km_event *c); int (*acquire)(struct xfrm_state *x, struct xfrm_tmpl *, struct xfrm_policy *xp, int dir); struct xfrm_policy *(*compile_policy)(struct sock *sk, int opt, u8 *data, int len, int *dir); - int (*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport); + int (*new_mapping)(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport); int (*notify_policy)(struct xfrm_policy *x, int dir, struct km_event *c); int (*report)(u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr); }; @@ -468,6 +471,7 @@ __be16 xfrm_flowi_sport(struct flowi *fl) switch(fl->proto) { case IPPROTO_TCP: case IPPROTO_UDP: + case IPPROTO_UDPLITE: case IPPROTO_SCTP: port = fl->fl_ip_sport; break; @@ -493,6 +497,7 @@ __be16 xfrm_flowi_dport(struct flowi *fl) switch(fl->proto) { case IPPROTO_TCP: case IPPROTO_UDP: + case IPPROTO_UDPLITE: case IPPROTO_SCTP: port = fl->fl_ip_dport; break; @@ -506,40 +511,8 @@ __be16 xfrm_flowi_dport(struct flowi *fl) return port; } -static inline int -__xfrm4_selector_match(struct xfrm_selector *sel, struct flowi *fl) -{ - return addr_match(&fl->fl4_dst, &sel->daddr, sel->prefixlen_d) && - addr_match(&fl->fl4_src, &sel->saddr, sel->prefixlen_s) && - !((xfrm_flowi_dport(fl) ^ sel->dport) & sel->dport_mask) && - !((xfrm_flowi_sport(fl) ^ sel->sport) & sel->sport_mask) && - (fl->proto == sel->proto || !sel->proto) && - (fl->oif == sel->ifindex || !sel->ifindex); -} - -static inline int -__xfrm6_selector_match(struct xfrm_selector *sel, struct flowi *fl) -{ - return addr_match(&fl->fl6_dst, &sel->daddr, sel->prefixlen_d) && - addr_match(&fl->fl6_src, &sel->saddr, sel->prefixlen_s) && - !((xfrm_flowi_dport(fl) ^ sel->dport) & sel->dport_mask) && - !((xfrm_flowi_sport(fl) ^ sel->sport) & sel->sport_mask) && - (fl->proto == sel->proto || !sel->proto) && - (fl->oif == sel->ifindex || !sel->ifindex); -} - -static inline int -xfrm_selector_match(struct xfrm_selector *sel, struct flowi *fl, - unsigned short family) -{ - switch (family) { - case AF_INET: - return __xfrm4_selector_match(sel, fl); - case AF_INET6: - return __xfrm6_selector_match(sel, fl); - } - return 0; -} +extern int xfrm_selector_match(struct xfrm_selector *sel, struct flowi *fl, + unsigned short family); #ifdef CONFIG_SECURITY_NETWORK_XFRM /* If neither has a context --> match @@ -887,8 +860,7 @@ struct xfrm_tunnel { struct xfrm6_tunnel { int (*handler)(struct sk_buff *skb); int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt, - int type, int code, int offset, __u32 info); - + int type, int code, int offset, __be32 info); struct xfrm6_tunnel *next; int priority; }; @@ -951,9 +923,9 @@ extern int xfrm6_input_addr(struct sk_buff *skb, xfrm_address_t *daddr, xfrm_address_t *saddr, u8 proto); extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler); extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler); -extern u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr); +extern __be32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr); extern void xfrm6_tunnel_free_spi(xfrm_address_t *saddr); -extern u32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr); +extern __be32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr); extern int xfrm6_output(struct sk_buff *skb); extern int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb, u8 **prevhdr); @@ -1000,7 +972,7 @@ extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst, extern void xfrm_init_pmtu(struct dst_entry *dst); extern wait_queue_head_t km_waitq; -extern int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport); +extern int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport); extern void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 pid); extern int km_report(u8 proto, struct xfrm_selector *sel, xfrm_address_t *addr); @@ -1033,7 +1005,7 @@ static inline int xfrm_addr_cmp(xfrm_address_t *a, xfrm_address_t *b, switch (family) { default: case AF_INET: - return a->a4 - b->a4; + return (__force __u32)a->a4 - (__force __u32)b->a4; case AF_INET6: return ipv6_addr_cmp((struct in6_addr *)a, (struct in6_addr *)b); |