]> Pileus Git - ~andy/linux/blobdiff - net/ipv6/datagram.c
Merge tag 'v3.9-rc3' into v4l_for_linus
[~andy/linux] / net / ipv6 / datagram.c
index 8edf2601065af07790500809b8dee9fad0fc8eaa..f5a54782a3408422ab4aa5da733bdbffb8755905 100644 (file)
@@ -30,6 +30,7 @@
 #include <net/transp_v6.h>
 #include <net/ip6_route.h>
 #include <net/tcp_states.h>
+#include <net/dsfield.h>
 
 #include <linux/errqueue.h>
 #include <asm/uaccess.h>
@@ -356,12 +357,11 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
                sin->sin6_port = serr->port;
                sin->sin6_scope_id = 0;
                if (skb->protocol == htons(ETH_P_IPV6)) {
-                       sin->sin6_addr =
-                               *(struct in6_addr *)(nh + serr->addr_offset);
+                       const struct ipv6hdr *ip6h = container_of((struct in6_addr *)(nh + serr->addr_offset),
+                                                                 struct ipv6hdr, daddr);
+                       sin->sin6_addr = ip6h->daddr;
                        if (np->sndflow)
-                               sin->sin6_flowinfo =
-                                       (*(__be32 *)(nh + serr->addr_offset - 24) &
-                                        IPV6_FLOWINFO_MASK);
+                               sin->sin6_flowinfo = ip6_flowinfo(ip6h);
                        if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL)
                                sin->sin6_scope_id = IP6CB(skb)->iif;
                } else {
@@ -380,7 +380,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)
                if (skb->protocol == htons(ETH_P_IPV6)) {
                        sin->sin6_addr = ipv6_hdr(skb)->saddr;
                        if (np->rxopt.all)
-                               datagram_recv_ctl(sk, msg, skb);
+                               ip6_datagram_recv_ctl(sk, msg, skb);
                        if (ipv6_addr_type(&sin->sin6_addr) & IPV6_ADDR_LINKLOCAL)
                                sin->sin6_scope_id = IP6CB(skb)->iif;
                } else {
@@ -468,7 +468,8 @@ out:
 }
 
 
-int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
+int ip6_datagram_recv_ctl(struct sock *sk, struct msghdr *msg,
+                         struct sk_buff *skb)
 {
        struct ipv6_pinfo *np = inet6_sk(sk);
        struct inet6_skb_parm *opt = IP6CB(skb);
@@ -488,13 +489,14 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
        }
 
        if (np->rxopt.bits.rxtclass) {
-               int tclass = ipv6_tclass(ipv6_hdr(skb));
+               int tclass = ipv6_get_dsfield(ipv6_hdr(skb));
                put_cmsg(msg, SOL_IPV6, IPV6_TCLASS, sizeof(tclass), &tclass);
        }
 
-       if (np->rxopt.bits.rxflow && (*(__be32 *)nh & IPV6_FLOWINFO_MASK)) {
-               __be32 flowinfo = *(__be32 *)nh & IPV6_FLOWINFO_MASK;
-               put_cmsg(msg, SOL_IPV6, IPV6_FLOWINFO, sizeof(flowinfo), &flowinfo);
+       if (np->rxopt.bits.rxflow) {
+               __be32 flowinfo = ip6_flowinfo((struct ipv6hdr *)nh);
+               if (flowinfo)
+                       put_cmsg(msg, SOL_IPV6, IPV6_FLOWINFO, sizeof(flowinfo), &flowinfo);
        }
 
        /* HbH is allowed only once */
@@ -597,11 +599,12 @@ int datagram_recv_ctl(struct sock *sk, struct msghdr *msg, struct sk_buff *skb)
        }
        return 0;
 }
+EXPORT_SYMBOL_GPL(ip6_datagram_recv_ctl);
 
-int datagram_send_ctl(struct net *net, struct sock *sk,
-                     struct msghdr *msg, struct flowi6 *fl6,
-                     struct ipv6_txoptions *opt,
-                     int *hlimit, int *tclass, int *dontfrag)
+int ip6_datagram_send_ctl(struct net *net, struct sock *sk,
+                         struct msghdr *msg, struct flowi6 *fl6,
+                         struct ipv6_txoptions *opt,
+                         int *hlimit, int *tclass, int *dontfrag)
 {
        struct in6_pktinfo *src_info;
        struct cmsghdr *cmsg;
@@ -871,4 +874,4 @@ int datagram_send_ctl(struct net *net, struct sock *sk,
 exit_f:
        return err;
 }
-EXPORT_SYMBOL_GPL(datagram_send_ctl);
+EXPORT_SYMBOL_GPL(ip6_datagram_send_ctl);