hfsc: reduce hfsc_sched to 14 cachelines
[deliverable/linux.git] / net / ipv4 / ip_sockglue.c
index 035ad645a8d9d8abd55321ad2bcd0e44d1d0fc3c..71a52f4d4cffba2db9353f43dc817689bf4fab10 100644 (file)
@@ -106,7 +106,8 @@ static void ip_cmsg_recv_checksum(struct msghdr *msg, struct sk_buff *skb,
                return;
 
        if (offset != 0)
-               csum = csum_sub(csum, csum_partial(skb->data, offset, 0));
+               csum = csum_sub(csum, csum_partial(skb_transport_header(skb),
+                                                  offset, 0));
 
        put_cmsg(msg, SOL_IP, IP_CHECKSUM, sizeof(__wsum), &csum);
 }
@@ -219,11 +220,12 @@ void ip_cmsg_recv_offset(struct msghdr *msg, struct sk_buff *skb,
 }
 EXPORT_SYMBOL(ip_cmsg_recv_offset);
 
-int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc,
+int ip_cmsg_send(struct sock *sk, struct msghdr *msg, struct ipcm_cookie *ipc,
                 bool allow_ipv6)
 {
        int err, val;
        struct cmsghdr *cmsg;
+       struct net *net = sock_net(sk);
 
        for_each_cmsghdr(cmsg, msg) {
                if (!CMSG_OK(msg, cmsg))
@@ -244,6 +246,13 @@ int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc,
                        continue;
                }
 #endif
+               if (cmsg->cmsg_level == SOL_SOCKET) {
+                       err = __sock_cmsg_send(sk, msg, cmsg, &ipc->sockc);
+                       if (err)
+                               return err;
+                       continue;
+               }
+
                if (cmsg->cmsg_level != SOL_IP)
                        continue;
                switch (cmsg->cmsg_type) {
@@ -502,9 +511,10 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
                copied = len;
        }
        err = skb_copy_datagram_msg(skb, 0, msg, copied);
-       if (err)
-               goto out_free_skb;
-
+       if (unlikely(err)) {
+               kfree_skb(skb);
+               return err;
+       }
        sock_recv_timestamp(msg, sk, skb);
 
        serr = SKB_EXT_ERR(skb);
@@ -536,8 +546,7 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
        msg->msg_flags |= MSG_ERRQUEUE;
        err = copied;
 
-out_free_skb:
-       kfree_skb(skb);
+       consume_skb(skb);
 out:
        return err;
 }
@@ -635,7 +644,7 @@ static int do_ip_setsockopt(struct sock *sk, int level,
                if (err)
                        break;
                old = rcu_dereference_protected(inet->inet_opt,
-                                               sock_owned_by_user(sk));
+                                               lockdep_sock_is_held(sk));
                if (inet->is_icsk) {
                        struct inet_connection_sock *icsk = inet_csk(sk);
 #if IS_ENABLED(CONFIG_IPV6)
@@ -1185,7 +1194,12 @@ void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb)
                       ipv6_sk_rxinfo(sk);
 
        if (prepare && skb_rtable(skb)) {
-               pktinfo->ipi_ifindex = inet_iif(skb);
+               /* skb->cb is overloaded: prior to this point it is IP{6}CB
+                * which has interface index (iif) as the first member of the
+                * underlying inet{6}_skb_parm struct. This code then overlays
+                * PKTINFO_SKB_CB and in_pktinfo also has iif as the first
+                * element so the iif is picked up from the prior IPCB
+                */
                pktinfo->ipi_spec_dst.s_addr = fib_compute_spec_dst(skb);
        } else {
                pktinfo->ipi_ifindex = 0;
@@ -1295,7 +1309,7 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
                struct ip_options_rcu *inet_opt;
 
                inet_opt = rcu_dereference_protected(inet->inet_opt,
-                                                    sock_owned_by_user(sk));
+                                                    lockdep_sock_is_held(sk));
                opt->optlen = 0;
                if (inet_opt)
                        memcpy(optbuf, &inet_opt->opt,
This page took 0.025307 seconds and 5 git commands to generate.