aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/hci_conn.c6
-rw-r--r--net/bluetooth/l2cap_core.c21
-rw-r--r--net/bridge/br_multicast.c5
-rw-r--r--net/ipv4/ip_output.c17
-rw-r--r--net/ipv4/netfilter.c60
-rw-r--r--net/ipv4/netfilter/ipt_REJECT.c14
-rw-r--r--net/ipv4/udp.c3
-rw-r--r--net/ipv6/udp.c5
8 files changed, 62 insertions, 69 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 3163330cd4f1..d3a05b9ade7a 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -608,11 +608,11 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
608 goto encrypt; 608 goto encrypt;
609 609
610auth: 610auth:
611 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) 611 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
612 return 0; 612 return 0;
613 613
614 hci_conn_auth(conn, sec_level, auth_type); 614 if (!hci_conn_auth(conn, sec_level, auth_type))
615 return 0; 615 return 0;
616 616
617encrypt: 617encrypt:
618 if (conn->link_mode & HCI_LM_ENCRYPT) 618 if (conn->link_mode & HCI_LM_ENCRYPT)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index e64a1c2df238..56fdd9162da9 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -4002,21 +4002,30 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
4002 } 4002 }
4003 } else if (sk->sk_state == BT_CONNECT2) { 4003 } else if (sk->sk_state == BT_CONNECT2) {
4004 struct l2cap_conn_rsp rsp; 4004 struct l2cap_conn_rsp rsp;
4005 __u16 result; 4005 __u16 res, stat;
4006 4006
4007 if (!status) { 4007 if (!status) {
4008 sk->sk_state = BT_CONFIG; 4008 if (bt_sk(sk)->defer_setup) {
4009 result = L2CAP_CR_SUCCESS; 4009 struct sock *parent = bt_sk(sk)->parent;
4010 res = L2CAP_CR_PEND;
4011 stat = L2CAP_CS_AUTHOR_PEND;
4012 parent->sk_data_ready(parent, 0);
4013 } else {
4014 sk->sk_state = BT_CONFIG;
4015 res = L2CAP_CR_SUCCESS;
4016 stat = L2CAP_CS_NO_INFO;
4017 }
4010 } else { 4018 } else {
4011 sk->sk_state = BT_DISCONN; 4019 sk->sk_state = BT_DISCONN;
4012 l2cap_sock_set_timer(sk, HZ / 10); 4020 l2cap_sock_set_timer(sk, HZ / 10);
4013 result = L2CAP_CR_SEC_BLOCK; 4021 res = L2CAP_CR_SEC_BLOCK;
4022 stat = L2CAP_CS_NO_INFO;
4014 } 4023 }
4015 4024
4016 rsp.scid = cpu_to_le16(chan->dcid); 4025 rsp.scid = cpu_to_le16(chan->dcid);
4017 rsp.dcid = cpu_to_le16(chan->scid); 4026 rsp.dcid = cpu_to_le16(chan->scid);
4018 rsp.result = cpu_to_le16(result); 4027 rsp.result = cpu_to_le16(res);
4019 rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); 4028 rsp.status = cpu_to_le16(stat);
4020 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP, 4029 l2cap_send_cmd(conn, chan->ident, L2CAP_CONN_RSP,
4021 sizeof(rsp), &rsp); 4030 sizeof(rsp), &rsp);
4022 } 4031 }
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index 29b9812c8da0..2d85ca7111d3 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -1379,8 +1379,11 @@ static int br_multicast_ipv4_rcv(struct net_bridge *br,
1379 if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl))) 1379 if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl)))
1380 return -EINVAL; 1380 return -EINVAL;
1381 1381
1382 if (iph->protocol != IPPROTO_IGMP) 1382 if (iph->protocol != IPPROTO_IGMP) {
1383 if ((iph->daddr & IGMP_LOCAL_GROUP_MASK) != IGMP_LOCAL_GROUP)
1384 BR_INPUT_SKB_CB(skb)->mrouters_only = 1;
1383 return 0; 1385 return 0;
1386 }
1384 1387
1385 len = ntohs(iph->tot_len); 1388 len = ntohs(iph->tot_len);
1386 if (skb->len < len || len < ip_hdrlen(skb)) 1389 if (skb->len < len || len < ip_hdrlen(skb))
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index a8024eaa0e87..4a7e16b5d3f3 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -802,8 +802,6 @@ static int __ip_append_data(struct sock *sk,
802 skb = skb_peek_tail(queue); 802 skb = skb_peek_tail(queue);
803 803
804 exthdrlen = !skb ? rt->dst.header_len : 0; 804 exthdrlen = !skb ? rt->dst.header_len : 0;
805 length += exthdrlen;
806 transhdrlen += exthdrlen;
807 mtu = cork->fragsize; 805 mtu = cork->fragsize;
808 806
809 hh_len = LL_RESERVED_SPACE(rt->dst.dev); 807 hh_len = LL_RESERVED_SPACE(rt->dst.dev);
@@ -883,17 +881,16 @@ alloc_new_skb:
883 else 881 else
884 alloclen = fraglen; 882 alloclen = fraglen;
885 883
884 alloclen += exthdrlen;
885
886 /* The last fragment gets additional space at tail. 886 /* The last fragment gets additional space at tail.
887 * Note, with MSG_MORE we overallocate on fragments, 887 * Note, with MSG_MORE we overallocate on fragments,
888 * because we have no idea what fragment will be 888 * because we have no idea what fragment will be
889 * the last. 889 * the last.
890 */ 890 */
891 if (datalen == length + fraggap) { 891 if (datalen == length + fraggap)
892 alloclen += rt->dst.trailer_len; 892 alloclen += rt->dst.trailer_len;
893 /* make sure mtu is not reached */ 893
894 if (datalen > mtu - fragheaderlen - rt->dst.trailer_len)
895 datalen -= ALIGN(rt->dst.trailer_len, 8);
896 }
897 if (transhdrlen) { 894 if (transhdrlen) {
898 skb = sock_alloc_send_skb(sk, 895 skb = sock_alloc_send_skb(sk,
899 alloclen + hh_len + 15, 896 alloclen + hh_len + 15,
@@ -926,11 +923,11 @@ alloc_new_skb:
926 /* 923 /*
927 * Find where to start putting bytes. 924 * Find where to start putting bytes.
928 */ 925 */
929 data = skb_put(skb, fraglen); 926 data = skb_put(skb, fraglen + exthdrlen);
930 skb_set_network_header(skb, exthdrlen); 927 skb_set_network_header(skb, exthdrlen);
931 skb->transport_header = (skb->network_header + 928 skb->transport_header = (skb->network_header +
932 fragheaderlen); 929 fragheaderlen);
933 data += fragheaderlen; 930 data += fragheaderlen + exthdrlen;
934 931
935 if (fraggap) { 932 if (fraggap) {
936 skb->csum = skb_copy_and_csum_bits( 933 skb->csum = skb_copy_and_csum_bits(
@@ -1064,7 +1061,7 @@ static int ip_setup_cork(struct sock *sk, struct inet_cork *cork,
1064 */ 1061 */
1065 *rtp = NULL; 1062 *rtp = NULL;
1066 cork->fragsize = inet->pmtudisc == IP_PMTUDISC_PROBE ? 1063 cork->fragsize = inet->pmtudisc == IP_PMTUDISC_PROBE ?
1067 rt->dst.dev->mtu : dst_mtu(rt->dst.path); 1064 rt->dst.dev->mtu : dst_mtu(&rt->dst);
1068 cork->dst = &rt->dst; 1065 cork->dst = &rt->dst;
1069 cork->length = 0; 1066 cork->length = 0;
1070 cork->tx_flags = ipc->tx_flags; 1067 cork->tx_flags = ipc->tx_flags;
diff --git a/net/ipv4/netfilter.c b/net/ipv4/netfilter.c
index 4614babdc45f..2e97e3ec1eb7 100644
--- a/net/ipv4/netfilter.c
+++ b/net/ipv4/netfilter.c
@@ -17,51 +17,35 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
17 const struct iphdr *iph = ip_hdr(skb); 17 const struct iphdr *iph = ip_hdr(skb);
18 struct rtable *rt; 18 struct rtable *rt;
19 struct flowi4 fl4 = {}; 19 struct flowi4 fl4 = {};
20 unsigned long orefdst; 20 __be32 saddr = iph->saddr;
21 __u8 flags = 0;
21 unsigned int hh_len; 22 unsigned int hh_len;
22 unsigned int type;
23 23
24 type = inet_addr_type(net, iph->saddr); 24 if (!skb->sk && addr_type != RTN_LOCAL) {
25 if (skb->sk && inet_sk(skb->sk)->transparent) 25 if (addr_type == RTN_UNSPEC)
26 type = RTN_LOCAL; 26 addr_type = inet_addr_type(net, saddr);
27 if (addr_type == RTN_UNSPEC) 27 if (addr_type == RTN_LOCAL || addr_type == RTN_UNICAST)
28 addr_type = type; 28 flags |= FLOWI_FLAG_ANYSRC;
29 else
30 saddr = 0;
31 }
29 32
30 /* some non-standard hacks like ipt_REJECT.c:send_reset() can cause 33 /* some non-standard hacks like ipt_REJECT.c:send_reset() can cause
31 * packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook. 34 * packets with foreign saddr to appear on the NF_INET_LOCAL_OUT hook.
32 */ 35 */
33 if (addr_type == RTN_LOCAL) { 36 fl4.daddr = iph->daddr;
34 fl4.daddr = iph->daddr; 37 fl4.saddr = saddr;
35 if (type == RTN_LOCAL) 38 fl4.flowi4_tos = RT_TOS(iph->tos);
36 fl4.saddr = iph->saddr; 39 fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0;
37 fl4.flowi4_tos = RT_TOS(iph->tos); 40 fl4.flowi4_mark = skb->mark;
38 fl4.flowi4_oif = skb->sk ? skb->sk->sk_bound_dev_if : 0; 41 fl4.flowi4_flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : flags;
39 fl4.flowi4_mark = skb->mark; 42 rt = ip_route_output_key(net, &fl4);
40 fl4.flowi4_flags = skb->sk ? inet_sk_flowi_flags(skb->sk) : 0; 43 if (IS_ERR(rt))
41 rt = ip_route_output_key(net, &fl4); 44 return -1;
42 if (IS_ERR(rt))
43 return -1;
44
45 /* Drop old route. */
46 skb_dst_drop(skb);
47 skb_dst_set(skb, &rt->dst);
48 } else {
49 /* non-local src, find valid iif to satisfy
50 * rp-filter when calling ip_route_input. */
51 fl4.daddr = iph->saddr;
52 rt = ip_route_output_key(net, &fl4);
53 if (IS_ERR(rt))
54 return -1;
55 45
56 orefdst = skb->_skb_refdst; 46 /* Drop old route. */
57 if (ip_route_input(skb, iph->daddr, iph->saddr, 47 skb_dst_drop(skb);
58 RT_TOS(iph->tos), rt->dst.dev) != 0) { 48 skb_dst_set(skb, &rt->dst);
59 dst_release(&rt->dst);
60 return -1;
61 }
62 dst_release(&rt->dst);
63 refdst_drop(orefdst);
64 }
65 49
66 if (skb_dst(skb)->error) 50 if (skb_dst(skb)->error)
67 return -1; 51 return -1;
diff --git a/net/ipv4/netfilter/ipt_REJECT.c b/net/ipv4/netfilter/ipt_REJECT.c
index 1ff79e557f96..51f13f8ec724 100644
--- a/net/ipv4/netfilter/ipt_REJECT.c
+++ b/net/ipv4/netfilter/ipt_REJECT.c
@@ -40,7 +40,6 @@ static void send_reset(struct sk_buff *oldskb, int hook)
40 struct iphdr *niph; 40 struct iphdr *niph;
41 const struct tcphdr *oth; 41 const struct tcphdr *oth;
42 struct tcphdr _otcph, *tcph; 42 struct tcphdr _otcph, *tcph;
43 unsigned int addr_type;
44 43
45 /* IP header checks: fragment. */ 44 /* IP header checks: fragment. */
46 if (ip_hdr(oldskb)->frag_off & htons(IP_OFFSET)) 45 if (ip_hdr(oldskb)->frag_off & htons(IP_OFFSET))
@@ -55,6 +54,9 @@ static void send_reset(struct sk_buff *oldskb, int hook)
55 if (oth->rst) 54 if (oth->rst)
56 return; 55 return;
57 56
57 if (skb_rtable(oldskb)->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST))
58 return;
59
58 /* Check checksum */ 60 /* Check checksum */
59 if (nf_ip_checksum(oldskb, hook, ip_hdrlen(oldskb), IPPROTO_TCP)) 61 if (nf_ip_checksum(oldskb, hook, ip_hdrlen(oldskb), IPPROTO_TCP))
60 return; 62 return;
@@ -101,19 +103,11 @@ static void send_reset(struct sk_buff *oldskb, int hook)
101 nskb->csum_start = (unsigned char *)tcph - nskb->head; 103 nskb->csum_start = (unsigned char *)tcph - nskb->head;
102 nskb->csum_offset = offsetof(struct tcphdr, check); 104 nskb->csum_offset = offsetof(struct tcphdr, check);
103 105
104 addr_type = RTN_UNSPEC;
105 if (hook != NF_INET_FORWARD
106#ifdef CONFIG_BRIDGE_NETFILTER
107 || (nskb->nf_bridge && nskb->nf_bridge->mask & BRNF_BRIDGED)
108#endif
109 )
110 addr_type = RTN_LOCAL;
111
112 /* ip_route_me_harder expects skb->dst to be set */ 106 /* ip_route_me_harder expects skb->dst to be set */
113 skb_dst_set_noref(nskb, skb_dst(oldskb)); 107 skb_dst_set_noref(nskb, skb_dst(oldskb));
114 108
115 nskb->protocol = htons(ETH_P_IP); 109 nskb->protocol = htons(ETH_P_IP);
116 if (ip_route_me_harder(nskb, addr_type)) 110 if (ip_route_me_harder(nskb, RTN_UNSPEC))
117 goto free_nskb; 111 goto free_nskb;
118 112
119 niph->ttl = ip4_dst_hoplimit(skb_dst(nskb)); 113 niph->ttl = ip4_dst_hoplimit(skb_dst(nskb));
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index abca870d8ff6..48cd88e62553 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1249,6 +1249,9 @@ csum_copy_err:
1249 1249
1250 if (noblock) 1250 if (noblock)
1251 return -EAGAIN; 1251 return -EAGAIN;
1252
1253 /* starting over for a new packet */
1254 msg->msg_flags &= ~MSG_TRUNC;
1252 goto try_again; 1255 goto try_again;
1253} 1256}
1254 1257
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 41f8c9c08dba..328985c40883 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -453,8 +453,11 @@ csum_copy_err:
453 } 453 }
454 unlock_sock_fast(sk, slow); 454 unlock_sock_fast(sk, slow);
455 455
456 if (flags & MSG_DONTWAIT) 456 if (noblock)
457 return -EAGAIN; 457 return -EAGAIN;
458
459 /* starting over for a new packet */
460 msg->msg_flags &= ~MSG_TRUNC;
458 goto try_again; 461 goto try_again;
459} 462}
460 463