aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/af_inet.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/af_inet.c')
-rw-r--r--net/ipv4/af_inet.c75
1 files changed, 58 insertions, 17 deletions
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 461216b47948..edcf0932ac6d 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -67,7 +67,6 @@
67 * 2 of the License, or (at your option) any later version. 67 * 2 of the License, or (at your option) any later version.
68 */ 68 */
69 69
70#include <linux/config.h>
71#include <linux/err.h> 70#include <linux/err.h>
72#include <linux/errno.h> 71#include <linux/errno.h>
73#include <linux/types.h> 72#include <linux/types.h>
@@ -392,7 +391,7 @@ int inet_release(struct socket *sock)
392} 391}
393 392
394/* It is off by default, see below. */ 393/* It is off by default, see below. */
395int sysctl_ip_nonlocal_bind; 394int sysctl_ip_nonlocal_bind __read_mostly;
396 395
397int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) 396int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
398{ 397{
@@ -988,7 +987,7 @@ void inet_unregister_protosw(struct inet_protosw *p)
988 * Shall we try to damage output packets if routing dev changes? 987 * Shall we try to damage output packets if routing dev changes?
989 */ 988 */
990 989
991int sysctl_ip_dynaddr; 990int sysctl_ip_dynaddr __read_mostly;
992 991
993static int inet_sk_reselect_saddr(struct sock *sk) 992static int inet_sk_reselect_saddr(struct sock *sk)
994{ 993{
@@ -997,7 +996,7 @@ static int inet_sk_reselect_saddr(struct sock *sk)
997 struct rtable *rt; 996 struct rtable *rt;
998 __u32 old_saddr = inet->saddr; 997 __u32 old_saddr = inet->saddr;
999 __u32 new_saddr; 998 __u32 new_saddr;
1000 __u32 daddr = inet->daddr; 999 __be32 daddr = inet->daddr;
1001 1000
1002 if (inet->opt && inet->opt->srr) 1001 if (inet->opt && inet->opt->srr)
1003 daddr = inet->opt->faddr; 1002 daddr = inet->opt->faddr;
@@ -1044,7 +1043,7 @@ int inet_sk_rebuild_header(struct sock *sk)
1044{ 1043{
1045 struct inet_sock *inet = inet_sk(sk); 1044 struct inet_sock *inet = inet_sk(sk);
1046 struct rtable *rt = (struct rtable *)__sk_dst_check(sk, 0); 1045 struct rtable *rt = (struct rtable *)__sk_dst_check(sk, 0);
1047 u32 daddr; 1046 __be32 daddr;
1048 int err; 1047 int err;
1049 1048
1050 /* Route is OK, nothing to do. */ 1049 /* Route is OK, nothing to do. */
@@ -1074,6 +1073,7 @@ int inet_sk_rebuild_header(struct sock *sk)
1074 }, 1073 },
1075 }; 1074 };
1076 1075
1076 security_sk_classify_flow(sk, &fl);
1077 err = ip_route_output_flow(&rt, &fl, sk, 0); 1077 err = ip_route_output_flow(&rt, &fl, sk, 0);
1078} 1078}
1079 if (!err) 1079 if (!err)
@@ -1097,7 +1097,41 @@ int inet_sk_rebuild_header(struct sock *sk)
1097 1097
1098EXPORT_SYMBOL(inet_sk_rebuild_header); 1098EXPORT_SYMBOL(inet_sk_rebuild_header);
1099 1099
1100static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int sg) 1100static int inet_gso_send_check(struct sk_buff *skb)
1101{
1102 struct iphdr *iph;
1103 struct net_protocol *ops;
1104 int proto;
1105 int ihl;
1106 int err = -EINVAL;
1107
1108 if (unlikely(!pskb_may_pull(skb, sizeof(*iph))))
1109 goto out;
1110
1111 iph = skb->nh.iph;
1112 ihl = iph->ihl * 4;
1113 if (ihl < sizeof(*iph))
1114 goto out;
1115
1116 if (unlikely(!pskb_may_pull(skb, ihl)))
1117 goto out;
1118
1119 skb->h.raw = __skb_pull(skb, ihl);
1120 iph = skb->nh.iph;
1121 proto = iph->protocol & (MAX_INET_PROTOS - 1);
1122 err = -EPROTONOSUPPORT;
1123
1124 rcu_read_lock();
1125 ops = rcu_dereference(inet_protos[proto]);
1126 if (likely(ops && ops->gso_send_check))
1127 err = ops->gso_send_check(skb);
1128 rcu_read_unlock();
1129
1130out:
1131 return err;
1132}
1133
1134static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int features)
1101{ 1135{
1102 struct sk_buff *segs = ERR_PTR(-EINVAL); 1136 struct sk_buff *segs = ERR_PTR(-EINVAL);
1103 struct iphdr *iph; 1137 struct iphdr *iph;
@@ -1106,7 +1140,15 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int sg)
1106 int ihl; 1140 int ihl;
1107 int id; 1141 int id;
1108 1142
1109 if (!pskb_may_pull(skb, sizeof(*iph))) 1143 if (unlikely(skb_shinfo(skb)->gso_type &
1144 ~(SKB_GSO_TCPV4 |
1145 SKB_GSO_UDP |
1146 SKB_GSO_DODGY |
1147 SKB_GSO_TCP_ECN |
1148 0)))
1149 goto out;
1150
1151 if (unlikely(!pskb_may_pull(skb, sizeof(*iph))))
1110 goto out; 1152 goto out;
1111 1153
1112 iph = skb->nh.iph; 1154 iph = skb->nh.iph;
@@ -1114,7 +1156,7 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int sg)
1114 if (ihl < sizeof(*iph)) 1156 if (ihl < sizeof(*iph))
1115 goto out; 1157 goto out;
1116 1158
1117 if (!pskb_may_pull(skb, ihl)) 1159 if (unlikely(!pskb_may_pull(skb, ihl)))
1118 goto out; 1160 goto out;
1119 1161
1120 skb->h.raw = __skb_pull(skb, ihl); 1162 skb->h.raw = __skb_pull(skb, ihl);
@@ -1125,11 +1167,11 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, int sg)
1125 1167
1126 rcu_read_lock(); 1168 rcu_read_lock();
1127 ops = rcu_dereference(inet_protos[proto]); 1169 ops = rcu_dereference(inet_protos[proto]);
1128 if (ops && ops->gso_segment) 1170 if (likely(ops && ops->gso_segment))
1129 segs = ops->gso_segment(skb, sg); 1171 segs = ops->gso_segment(skb, features);
1130 rcu_read_unlock(); 1172 rcu_read_unlock();
1131 1173
1132 if (IS_ERR(segs)) 1174 if (!segs || unlikely(IS_ERR(segs)))
1133 goto out; 1175 goto out;
1134 1176
1135 skb = segs; 1177 skb = segs;
@@ -1154,6 +1196,7 @@ static struct net_protocol igmp_protocol = {
1154static struct net_protocol tcp_protocol = { 1196static struct net_protocol tcp_protocol = {
1155 .handler = tcp_v4_rcv, 1197 .handler = tcp_v4_rcv,
1156 .err_handler = tcp_v4_err, 1198 .err_handler = tcp_v4_err,
1199 .gso_send_check = tcp_v4_gso_send_check,
1157 .gso_segment = tcp_tso_segment, 1200 .gso_segment = tcp_tso_segment,
1158 .no_policy = 1, 1201 .no_policy = 1,
1159}; 1202};
@@ -1200,6 +1243,7 @@ static int ipv4_proc_init(void);
1200static struct packet_type ip_packet_type = { 1243static struct packet_type ip_packet_type = {
1201 .type = __constant_htons(ETH_P_IP), 1244 .type = __constant_htons(ETH_P_IP),
1202 .func = ip_rcv, 1245 .func = ip_rcv,
1246 .gso_send_check = inet_gso_send_check,
1203 .gso_segment = inet_gso_segment, 1247 .gso_segment = inet_gso_segment,
1204}; 1248};
1205 1249
@@ -1210,10 +1254,7 @@ static int __init inet_init(void)
1210 struct list_head *r; 1254 struct list_head *r;
1211 int rc = -EINVAL; 1255 int rc = -EINVAL;
1212 1256
1213 if (sizeof(struct inet_skb_parm) > sizeof(dummy_skb->cb)) { 1257 BUILD_BUG_ON(sizeof(struct inet_skb_parm) > sizeof(dummy_skb->cb));
1214 printk(KERN_CRIT "%s: panic\n", __FUNCTION__);
1215 goto out;
1216 }
1217 1258
1218 rc = proto_register(&tcp_prot, 1); 1259 rc = proto_register(&tcp_prot, 1);
1219 if (rc) 1260 if (rc)
@@ -1301,10 +1342,10 @@ static int __init inet_init(void)
1301 rc = 0; 1342 rc = 0;
1302out: 1343out:
1303 return rc; 1344 return rc;
1304out_unregister_tcp_proto:
1305 proto_unregister(&tcp_prot);
1306out_unregister_udp_proto: 1345out_unregister_udp_proto:
1307 proto_unregister(&udp_prot); 1346 proto_unregister(&udp_prot);
1347out_unregister_tcp_proto:
1348 proto_unregister(&tcp_prot);
1308 goto out; 1349 goto out;
1309} 1350}
1310 1351