aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-01-06 17:37:45 -0500
committerDavid S. Miller <davem@davemloft.net>2014-01-06 17:37:45 -0500
commit56a4342dfe3145cd66f766adccb28fd9b571606d (patch)
treed1593764488ff8cbb0b83cb9ae35fd968bf81760 /net/ipv4
parent805c1f4aedaba1bc8d839e7c27b128083dd5c2f0 (diff)
parentfe0d692bbc645786bce1a98439e548ae619269f5 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts: drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c net/ipv6/ip6_tunnel.c net/ipv6/ip6_vti.c ipv6 tunnel statistic bug fixes conflicting with consolidation into generic sw per-cpu net stats. qlogic conflict between queue counting bug fix and the addition of multiple MAC address support. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/gre_offload.c11
-rw-r--r--net/ipv4/inet_diag.c16
-rw-r--r--net/ipv4/ip_gre.c1
-rw-r--r--net/ipv4/ip_output.c5
-rw-r--r--net/ipv4/udp.c6
-rw-r--r--net/ipv4/udp_offload.c37
6 files changed, 51 insertions, 25 deletions
diff --git a/net/ipv4/gre_offload.c b/net/ipv4/gre_offload.c
index e5d436188464..2cd02f32f99f 100644
--- a/net/ipv4/gre_offload.c
+++ b/net/ipv4/gre_offload.c
@@ -28,6 +28,7 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb,
28 netdev_features_t enc_features; 28 netdev_features_t enc_features;
29 int ghl = GRE_HEADER_SECTION; 29 int ghl = GRE_HEADER_SECTION;
30 struct gre_base_hdr *greh; 30 struct gre_base_hdr *greh;
31 u16 mac_offset = skb->mac_header;
31 int mac_len = skb->mac_len; 32 int mac_len = skb->mac_len;
32 __be16 protocol = skb->protocol; 33 __be16 protocol = skb->protocol;
33 int tnl_hlen; 34 int tnl_hlen;
@@ -58,13 +59,13 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb,
58 } else 59 } else
59 csum = false; 60 csum = false;
60 61
62 if (unlikely(!pskb_may_pull(skb, ghl)))
63 goto out;
64
61 /* setup inner skb. */ 65 /* setup inner skb. */
62 skb->protocol = greh->protocol; 66 skb->protocol = greh->protocol;
63 skb->encapsulation = 0; 67 skb->encapsulation = 0;
64 68
65 if (unlikely(!pskb_may_pull(skb, ghl)))
66 goto out;
67
68 __skb_pull(skb, ghl); 69 __skb_pull(skb, ghl);
69 skb_reset_mac_header(skb); 70 skb_reset_mac_header(skb);
70 skb_set_network_header(skb, skb_inner_network_offset(skb)); 71 skb_set_network_header(skb, skb_inner_network_offset(skb));
@@ -73,8 +74,10 @@ static struct sk_buff *gre_gso_segment(struct sk_buff *skb,
73 /* segment inner packet. */ 74 /* segment inner packet. */
74 enc_features = skb->dev->hw_enc_features & netif_skb_features(skb); 75 enc_features = skb->dev->hw_enc_features & netif_skb_features(skb);
75 segs = skb_mac_gso_segment(skb, enc_features); 76 segs = skb_mac_gso_segment(skb, enc_features);
76 if (!segs || IS_ERR(segs)) 77 if (!segs || IS_ERR(segs)) {
78 skb_gso_error_unwind(skb, protocol, ghl, mac_offset, mac_len);
77 goto out; 79 goto out;
80 }
78 81
79 skb = segs; 82 skb = segs;
80 tnl_hlen = skb_tnl_header_len(skb); 83 tnl_hlen = skb_tnl_header_len(skb);
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c
index 56a964a553d2..a0f52dac8940 100644
--- a/net/ipv4/inet_diag.c
+++ b/net/ipv4/inet_diag.c
@@ -106,6 +106,10 @@ int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk,
106 106
107 r->id.idiag_sport = inet->inet_sport; 107 r->id.idiag_sport = inet->inet_sport;
108 r->id.idiag_dport = inet->inet_dport; 108 r->id.idiag_dport = inet->inet_dport;
109
110 memset(&r->id.idiag_src, 0, sizeof(r->id.idiag_src));
111 memset(&r->id.idiag_dst, 0, sizeof(r->id.idiag_dst));
112
109 r->id.idiag_src[0] = inet->inet_rcv_saddr; 113 r->id.idiag_src[0] = inet->inet_rcv_saddr;
110 r->id.idiag_dst[0] = inet->inet_daddr; 114 r->id.idiag_dst[0] = inet->inet_daddr;
111 115
@@ -240,12 +244,19 @@ static int inet_twsk_diag_fill(struct inet_timewait_sock *tw,
240 244
241 r->idiag_family = tw->tw_family; 245 r->idiag_family = tw->tw_family;
242 r->idiag_retrans = 0; 246 r->idiag_retrans = 0;
247
243 r->id.idiag_if = tw->tw_bound_dev_if; 248 r->id.idiag_if = tw->tw_bound_dev_if;
244 sock_diag_save_cookie(tw, r->id.idiag_cookie); 249 sock_diag_save_cookie(tw, r->id.idiag_cookie);
250
245 r->id.idiag_sport = tw->tw_sport; 251 r->id.idiag_sport = tw->tw_sport;
246 r->id.idiag_dport = tw->tw_dport; 252 r->id.idiag_dport = tw->tw_dport;
253
254 memset(&r->id.idiag_src, 0, sizeof(r->id.idiag_src));
255 memset(&r->id.idiag_dst, 0, sizeof(r->id.idiag_dst));
256
247 r->id.idiag_src[0] = tw->tw_rcv_saddr; 257 r->id.idiag_src[0] = tw->tw_rcv_saddr;
248 r->id.idiag_dst[0] = tw->tw_daddr; 258 r->id.idiag_dst[0] = tw->tw_daddr;
259
249 r->idiag_state = tw->tw_substate; 260 r->idiag_state = tw->tw_substate;
250 r->idiag_timer = 3; 261 r->idiag_timer = 3;
251 r->idiag_expires = jiffies_to_msecs(tmo); 262 r->idiag_expires = jiffies_to_msecs(tmo);
@@ -726,8 +737,13 @@ static int inet_diag_fill_req(struct sk_buff *skb, struct sock *sk,
726 737
727 r->id.idiag_sport = inet->inet_sport; 738 r->id.idiag_sport = inet->inet_sport;
728 r->id.idiag_dport = ireq->ir_rmt_port; 739 r->id.idiag_dport = ireq->ir_rmt_port;
740
741 memset(&r->id.idiag_src, 0, sizeof(r->id.idiag_src));
742 memset(&r->id.idiag_dst, 0, sizeof(r->id.idiag_dst));
743
729 r->id.idiag_src[0] = ireq->ir_loc_addr; 744 r->id.idiag_src[0] = ireq->ir_loc_addr;
730 r->id.idiag_dst[0] = ireq->ir_rmt_addr; 745 r->id.idiag_dst[0] = ireq->ir_rmt_addr;
746
731 r->idiag_expires = jiffies_to_msecs(tmo); 747 r->idiag_expires = jiffies_to_msecs(tmo);
732 r->idiag_rqueue = 0; 748 r->idiag_rqueue = 0;
733 r->idiag_wqueue = 0; 749 r->idiag_wqueue = 0;
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index d7aea4c5b940..e560ef34cf4b 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -217,6 +217,7 @@ static int ipgre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi)
217 iph->saddr, iph->daddr, tpi->key); 217 iph->saddr, iph->daddr, tpi->key);
218 218
219 if (tunnel) { 219 if (tunnel) {
220 skb_pop_mac_header(skb);
220 ip_tunnel_rcv(tunnel, skb, tpi, log_ecn_error); 221 ip_tunnel_rcv(tunnel, skb, tpi, log_ecn_error);
221 return PACKET_RCVD; 222 return PACKET_RCVD;
222 } 223 }
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 912402752f2f..df184616493f 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -828,7 +828,7 @@ static int __ip_append_data(struct sock *sk,
828 828
829 if (cork->length + length > maxnonfragsize - fragheaderlen) { 829 if (cork->length + length > maxnonfragsize - fragheaderlen) {
830 ip_local_error(sk, EMSGSIZE, fl4->daddr, inet->inet_dport, 830 ip_local_error(sk, EMSGSIZE, fl4->daddr, inet->inet_dport,
831 mtu-exthdrlen); 831 mtu - (opt ? opt->optlen : 0));
832 return -EMSGSIZE; 832 return -EMSGSIZE;
833 } 833 }
834 834
@@ -1151,7 +1151,8 @@ ssize_t ip_append_page(struct sock *sk, struct flowi4 *fl4, struct page *page,
1151 mtu : 0xFFFF; 1151 mtu : 0xFFFF;
1152 1152
1153 if (cork->length + size > maxnonfragsize - fragheaderlen) { 1153 if (cork->length + size > maxnonfragsize - fragheaderlen) {
1154 ip_local_error(sk, EMSGSIZE, fl4->daddr, inet->inet_dport, mtu); 1154 ip_local_error(sk, EMSGSIZE, fl4->daddr, inet->inet_dport,
1155 mtu - (opt ? opt->optlen : 0));
1155 return -EMSGSIZE; 1156 return -EMSGSIZE;
1156 } 1157 }
1157 1158
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index d5d24ecde6a5..80f649fbee63 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -2478,6 +2478,7 @@ struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb,
2478 netdev_features_t features) 2478 netdev_features_t features)
2479{ 2479{
2480 struct sk_buff *segs = ERR_PTR(-EINVAL); 2480 struct sk_buff *segs = ERR_PTR(-EINVAL);
2481 u16 mac_offset = skb->mac_header;
2481 int mac_len = skb->mac_len; 2482 int mac_len = skb->mac_len;
2482 int tnl_hlen = skb_inner_mac_header(skb) - skb_transport_header(skb); 2483 int tnl_hlen = skb_inner_mac_header(skb) - skb_transport_header(skb);
2483 __be16 protocol = skb->protocol; 2484 __be16 protocol = skb->protocol;
@@ -2497,8 +2498,11 @@ struct sk_buff *skb_udp_tunnel_segment(struct sk_buff *skb,
2497 /* segment inner packet. */ 2498 /* segment inner packet. */
2498 enc_features = skb->dev->hw_enc_features & netif_skb_features(skb); 2499 enc_features = skb->dev->hw_enc_features & netif_skb_features(skb);
2499 segs = skb_mac_gso_segment(skb, enc_features); 2500 segs = skb_mac_gso_segment(skb, enc_features);
2500 if (!segs || IS_ERR(segs)) 2501 if (!segs || IS_ERR(segs)) {
2502 skb_gso_error_unwind(skb, protocol, tnl_hlen, mac_offset,
2503 mac_len);
2501 goto out; 2504 goto out;
2505 }
2502 2506
2503 outer_hlen = skb_tnl_header_len(skb); 2507 outer_hlen = skb_tnl_header_len(skb);
2504 skb = segs; 2508 skb = segs;
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
index 83206de2bc76..79c62bdcd3c5 100644
--- a/net/ipv4/udp_offload.c
+++ b/net/ipv4/udp_offload.c
@@ -41,6 +41,14 @@ static struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb,
41{ 41{
42 struct sk_buff *segs = ERR_PTR(-EINVAL); 42 struct sk_buff *segs = ERR_PTR(-EINVAL);
43 unsigned int mss; 43 unsigned int mss;
44 int offset;
45 __wsum csum;
46
47 if (skb->encapsulation &&
48 skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL) {
49 segs = skb_udp_tunnel_segment(skb, features);
50 goto out;
51 }
44 52
45 mss = skb_shinfo(skb)->gso_size; 53 mss = skb_shinfo(skb)->gso_size;
46 if (unlikely(skb->len <= mss)) 54 if (unlikely(skb->len <= mss))
@@ -63,27 +71,20 @@ static struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb,
63 goto out; 71 goto out;
64 } 72 }
65 73
74 /* Do software UFO. Complete and fill in the UDP checksum as
75 * HW cannot do checksum of UDP packets sent as multiple
76 * IP fragments.
77 */
78 offset = skb_checksum_start_offset(skb);
79 csum = skb_checksum(skb, offset, skb->len - offset, 0);
80 offset += skb->csum_offset;
81 *(__sum16 *)(skb->data + offset) = csum_fold(csum);
82 skb->ip_summed = CHECKSUM_NONE;
83
66 /* Fragment the skb. IP headers of the fragments are updated in 84 /* Fragment the skb. IP headers of the fragments are updated in
67 * inet_gso_segment() 85 * inet_gso_segment()
68 */ 86 */
69 if (skb->encapsulation && skb_shinfo(skb)->gso_type & SKB_GSO_UDP_TUNNEL) 87 segs = skb_segment(skb, features);
70 segs = skb_udp_tunnel_segment(skb, features);
71 else {
72 int offset;
73 __wsum csum;
74
75 /* Do software UFO. Complete and fill in the UDP checksum as
76 * HW cannot do checksum of UDP packets sent as multiple
77 * IP fragments.
78 */
79 offset = skb_checksum_start_offset(skb);
80 csum = skb_checksum(skb, offset, skb->len - offset, 0);
81 offset += skb->csum_offset;
82 *(__sum16 *)(skb->data + offset) = csum_fold(csum);
83 skb->ip_summed = CHECKSUM_NONE;
84
85 segs = skb_segment(skb, features);
86 }
87out: 88out:
88 return segs; 89 return segs;
89} 90}