vserver 1.9.5.x5
[linux-2.6.git] / include / linux / ipv6.h
index e98637f..9399423 100644 (file)
@@ -182,8 +182,7 @@ enum {
    as offsets from skb->nh.
  */
 
-struct inet6_skb_parm
-{
+struct inet6_skb_parm {
        int                     iif;
        __u16                   ra;
        __u16                   hop;
@@ -192,6 +191,16 @@ struct inet6_skb_parm
        __u16                   dst1;
 };
 
+#define IP6CB(skb)     ((struct inet6_skb_parm*)((skb)->cb))
+
+/**
+ * struct ipv6_pinfo - ipv6 private area
+ *
+ * In the struct sock hierarchy (tcp6_sock, upd6_sock, etc)
+ * this _must_ be the last member, so that inet6_sk_generic
+ * is able to calculate its offset from the base struct sock
+ * by using the struct proto->slab_obj_size member. -acme
+ */
 struct ipv6_pinfo {
        struct in6_addr         saddr;
        struct in6_addr         rcv_saddr;
@@ -238,54 +247,67 @@ struct ipv6_pinfo {
        } cork;
 };
 
-struct raw6_opt {
+/* WARNING: don't change the layout of the members in {raw,udp,tcp}6_sock! */
+struct raw6_sock {
+       /* inet_sock has to be the first member of raw6_sock */
+       struct inet_sock        inet;
        __u32                   checksum;       /* perform checksum */
        __u32                   offset;         /* checksum offset  */
-
        struct icmp6_filter     filter;
-};
-
-/* WARNING: don't change the layout of the members in {raw,udp,tcp}6_sock! */
-struct raw6_sock {
-       struct sock       sk;
-       struct ipv6_pinfo *pinet6;
-       struct inet_opt   inet;
-       struct raw6_opt   raw6;
-       struct ipv6_pinfo inet6;
+       /* ipv6_pinfo has to be the last member of raw6_sock, see inet6_sk_generic */
+       struct ipv6_pinfo       inet6;
 };
 
 struct udp6_sock {
-       struct sock       sk;
-       struct ipv6_pinfo *pinet6;
-       struct inet_opt   inet;
-       struct udp_opt    udp;
+       struct udp_sock   udp;
+       /* ipv6_pinfo has to be the last member of udp6_sock, see inet6_sk_generic */
        struct ipv6_pinfo inet6;
 };
 
 struct tcp6_sock {
-       struct sock       sk;
-       struct ipv6_pinfo *pinet6;
-       struct inet_opt   inet;
-       struct tcp_opt    tcp;
+       struct tcp_sock   tcp;
+       /* ipv6_pinfo has to be the last member of tcp6_sock, see inet6_sk_generic */
        struct ipv6_pinfo inet6;
 };
 
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 static inline struct ipv6_pinfo * inet6_sk(const struct sock *__sk)
 {
-       return ((struct raw6_sock *)__sk)->pinet6;
+       return inet_sk(__sk)->pinet6;
 }
 
-static inline struct raw6_opt * raw6_sk(const struct sock *__sk)
+static inline struct raw6_sock *raw6_sk(const struct sock *sk)
 {
-       return &((struct raw6_sock *)__sk)->raw6;
+       return (struct raw6_sock *)sk;
+}
+
+static inline void inet_sk_copy_descendant(struct sock *sk_to,
+                                          const struct sock *sk_from)
+{
+       int ancestor_size = sizeof(struct inet_sock);
+
+       if (sk_from->sk_family == PF_INET6)
+               ancestor_size += sizeof(struct ipv6_pinfo);
+
+       __inet_sk_copy_descendant(sk_to, sk_from, ancestor_size);
 }
 
-#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 #define __ipv6_only_sock(sk)   (inet6_sk(sk)->ipv6only)
 #define ipv6_only_sock(sk)     ((sk)->sk_family == PF_INET6 && __ipv6_only_sock(sk))
 #else
 #define __ipv6_only_sock(sk)   0
 #define ipv6_only_sock(sk)     0
+
+static inline struct ipv6_pinfo * inet6_sk(const struct sock *__sk)
+{
+       return NULL;
+}
+
+static inline struct raw6_sock *raw6_sk(const struct sock *sk)
+{
+       return NULL;
+}
+
 #endif
 
 #endif