diff options
Diffstat (limited to 'net/ipv6/ip6_output.c')
-rw-r--r-- | net/ipv6/ip6_output.c | 50 |
1 files changed, 26 insertions, 24 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 46cf7bea6769..9d4b165837d6 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -869,9 +869,9 @@ fail: | |||
869 | return err; | 869 | return err; |
870 | } | 870 | } |
871 | 871 | ||
872 | static inline int ip6_rt_check(struct rt6key *rt_key, | 872 | static inline int ip6_rt_check(const struct rt6key *rt_key, |
873 | struct in6_addr *fl_addr, | 873 | const struct in6_addr *fl_addr, |
874 | struct in6_addr *addr_cache) | 874 | const struct in6_addr *addr_cache) |
875 | { | 875 | { |
876 | return (rt_key->plen != 128 || !ipv6_addr_equal(fl_addr, &rt_key->addr)) && | 876 | return (rt_key->plen != 128 || !ipv6_addr_equal(fl_addr, &rt_key->addr)) && |
877 | (addr_cache == NULL || !ipv6_addr_equal(fl_addr, addr_cache)); | 877 | (addr_cache == NULL || !ipv6_addr_equal(fl_addr, addr_cache)); |
@@ -879,7 +879,7 @@ static inline int ip6_rt_check(struct rt6key *rt_key, | |||
879 | 879 | ||
880 | static struct dst_entry *ip6_sk_dst_check(struct sock *sk, | 880 | static struct dst_entry *ip6_sk_dst_check(struct sock *sk, |
881 | struct dst_entry *dst, | 881 | struct dst_entry *dst, |
882 | struct flowi6 *fl6) | 882 | const struct flowi6 *fl6) |
883 | { | 883 | { |
884 | struct ipv6_pinfo *np = inet6_sk(sk); | 884 | struct ipv6_pinfo *np = inet6_sk(sk); |
885 | struct rt6_info *rt = (struct rt6_info *)dst; | 885 | struct rt6_info *rt = (struct rt6_info *)dst; |
@@ -930,10 +930,10 @@ static int ip6_dst_lookup_tail(struct sock *sk, | |||
930 | goto out_err_release; | 930 | goto out_err_release; |
931 | 931 | ||
932 | if (ipv6_addr_any(&fl6->saddr)) { | 932 | if (ipv6_addr_any(&fl6->saddr)) { |
933 | err = ipv6_dev_get_saddr(net, ip6_dst_idev(*dst)->dev, | 933 | struct rt6_info *rt = (struct rt6_info *) *dst; |
934 | &fl6->daddr, | 934 | err = ip6_route_get_saddr(net, rt, &fl6->daddr, |
935 | sk ? inet6_sk(sk)->srcprefs : 0, | 935 | sk ? inet6_sk(sk)->srcprefs : 0, |
936 | &fl6->saddr); | 936 | &fl6->saddr); |
937 | if (err) | 937 | if (err) |
938 | goto out_err_release; | 938 | goto out_err_release; |
939 | } | 939 | } |
@@ -1150,6 +1150,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
1150 | { | 1150 | { |
1151 | struct inet_sock *inet = inet_sk(sk); | 1151 | struct inet_sock *inet = inet_sk(sk); |
1152 | struct ipv6_pinfo *np = inet6_sk(sk); | 1152 | struct ipv6_pinfo *np = inet6_sk(sk); |
1153 | struct inet_cork *cork; | ||
1153 | struct sk_buff *skb; | 1154 | struct sk_buff *skb; |
1154 | unsigned int maxfraglen, fragheaderlen; | 1155 | unsigned int maxfraglen, fragheaderlen; |
1155 | int exthdrlen; | 1156 | int exthdrlen; |
@@ -1163,6 +1164,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
1163 | 1164 | ||
1164 | if (flags&MSG_PROBE) | 1165 | if (flags&MSG_PROBE) |
1165 | return 0; | 1166 | return 0; |
1167 | cork = &inet->cork.base; | ||
1166 | if (skb_queue_empty(&sk->sk_write_queue)) { | 1168 | if (skb_queue_empty(&sk->sk_write_queue)) { |
1167 | /* | 1169 | /* |
1168 | * setup for corking | 1170 | * setup for corking |
@@ -1202,7 +1204,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
1202 | /* need source address above miyazawa*/ | 1204 | /* need source address above miyazawa*/ |
1203 | } | 1205 | } |
1204 | dst_hold(&rt->dst); | 1206 | dst_hold(&rt->dst); |
1205 | inet->cork.dst = &rt->dst; | 1207 | cork->dst = &rt->dst; |
1206 | inet->cork.fl.u.ip6 = *fl6; | 1208 | inet->cork.fl.u.ip6 = *fl6; |
1207 | np->cork.hop_limit = hlimit; | 1209 | np->cork.hop_limit = hlimit; |
1208 | np->cork.tclass = tclass; | 1210 | np->cork.tclass = tclass; |
@@ -1212,10 +1214,10 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
1212 | if (np->frag_size) | 1214 | if (np->frag_size) |
1213 | mtu = np->frag_size; | 1215 | mtu = np->frag_size; |
1214 | } | 1216 | } |
1215 | inet->cork.fragsize = mtu; | 1217 | cork->fragsize = mtu; |
1216 | if (dst_allfrag(rt->dst.path)) | 1218 | if (dst_allfrag(rt->dst.path)) |
1217 | inet->cork.flags |= IPCORK_ALLFRAG; | 1219 | cork->flags |= IPCORK_ALLFRAG; |
1218 | inet->cork.length = 0; | 1220 | cork->length = 0; |
1219 | sk->sk_sndmsg_page = NULL; | 1221 | sk->sk_sndmsg_page = NULL; |
1220 | sk->sk_sndmsg_off = 0; | 1222 | sk->sk_sndmsg_off = 0; |
1221 | exthdrlen = rt->dst.header_len + (opt ? opt->opt_flen : 0) - | 1223 | exthdrlen = rt->dst.header_len + (opt ? opt->opt_flen : 0) - |
@@ -1223,12 +1225,12 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
1223 | length += exthdrlen; | 1225 | length += exthdrlen; |
1224 | transhdrlen += exthdrlen; | 1226 | transhdrlen += exthdrlen; |
1225 | } else { | 1227 | } else { |
1226 | rt = (struct rt6_info *)inet->cork.dst; | 1228 | rt = (struct rt6_info *)cork->dst; |
1227 | fl6 = &inet->cork.fl.u.ip6; | 1229 | fl6 = &inet->cork.fl.u.ip6; |
1228 | opt = np->cork.opt; | 1230 | opt = np->cork.opt; |
1229 | transhdrlen = 0; | 1231 | transhdrlen = 0; |
1230 | exthdrlen = 0; | 1232 | exthdrlen = 0; |
1231 | mtu = inet->cork.fragsize; | 1233 | mtu = cork->fragsize; |
1232 | } | 1234 | } |
1233 | 1235 | ||
1234 | hh_len = LL_RESERVED_SPACE(rt->dst.dev); | 1236 | hh_len = LL_RESERVED_SPACE(rt->dst.dev); |
@@ -1238,7 +1240,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
1238 | maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen - sizeof(struct frag_hdr); | 1240 | maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen - sizeof(struct frag_hdr); |
1239 | 1241 | ||
1240 | if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) { | 1242 | if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) { |
1241 | if (inet->cork.length + length > sizeof(struct ipv6hdr) + IPV6_MAXPLEN - fragheaderlen) { | 1243 | if (cork->length + length > sizeof(struct ipv6hdr) + IPV6_MAXPLEN - fragheaderlen) { |
1242 | ipv6_local_error(sk, EMSGSIZE, fl6, mtu-exthdrlen); | 1244 | ipv6_local_error(sk, EMSGSIZE, fl6, mtu-exthdrlen); |
1243 | return -EMSGSIZE; | 1245 | return -EMSGSIZE; |
1244 | } | 1246 | } |
@@ -1267,7 +1269,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
1267 | * --yoshfuji | 1269 | * --yoshfuji |
1268 | */ | 1270 | */ |
1269 | 1271 | ||
1270 | inet->cork.length += length; | 1272 | cork->length += length; |
1271 | if (length > mtu) { | 1273 | if (length > mtu) { |
1272 | int proto = sk->sk_protocol; | 1274 | int proto = sk->sk_protocol; |
1273 | if (dontfrag && (proto == IPPROTO_UDP || proto == IPPROTO_RAW)){ | 1275 | if (dontfrag && (proto == IPPROTO_UDP || proto == IPPROTO_RAW)){ |
@@ -1292,7 +1294,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
1292 | 1294 | ||
1293 | while (length > 0) { | 1295 | while (length > 0) { |
1294 | /* Check if the remaining data fits into current packet. */ | 1296 | /* Check if the remaining data fits into current packet. */ |
1295 | copy = (inet->cork.length <= mtu && !(inet->cork.flags & IPCORK_ALLFRAG) ? mtu : maxfraglen) - skb->len; | 1297 | copy = (cork->length <= mtu && !(cork->flags & IPCORK_ALLFRAG) ? mtu : maxfraglen) - skb->len; |
1296 | if (copy < length) | 1298 | if (copy < length) |
1297 | copy = maxfraglen - skb->len; | 1299 | copy = maxfraglen - skb->len; |
1298 | 1300 | ||
@@ -1317,7 +1319,7 @@ alloc_new_skb: | |||
1317 | * we know we need more fragment(s). | 1319 | * we know we need more fragment(s). |
1318 | */ | 1320 | */ |
1319 | datalen = length + fraggap; | 1321 | datalen = length + fraggap; |
1320 | if (datalen > (inet->cork.length <= mtu && !(inet->cork.flags & IPCORK_ALLFRAG) ? mtu : maxfraglen) - fragheaderlen) | 1322 | if (datalen > (cork->length <= mtu && !(cork->flags & IPCORK_ALLFRAG) ? mtu : maxfraglen) - fragheaderlen) |
1321 | datalen = maxfraglen - fragheaderlen; | 1323 | datalen = maxfraglen - fragheaderlen; |
1322 | 1324 | ||
1323 | fraglen = datalen + fragheaderlen; | 1325 | fraglen = datalen + fragheaderlen; |
@@ -1481,7 +1483,7 @@ alloc_new_skb: | |||
1481 | } | 1483 | } |
1482 | return 0; | 1484 | return 0; |
1483 | error: | 1485 | error: |
1484 | inet->cork.length -= length; | 1486 | cork->length -= length; |
1485 | IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS); | 1487 | IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS); |
1486 | return err; | 1488 | return err; |
1487 | } | 1489 | } |
@@ -1497,10 +1499,10 @@ static void ip6_cork_release(struct inet_sock *inet, struct ipv6_pinfo *np) | |||
1497 | np->cork.opt = NULL; | 1499 | np->cork.opt = NULL; |
1498 | } | 1500 | } |
1499 | 1501 | ||
1500 | if (inet->cork.dst) { | 1502 | if (inet->cork.base.dst) { |
1501 | dst_release(inet->cork.dst); | 1503 | dst_release(inet->cork.base.dst); |
1502 | inet->cork.dst = NULL; | 1504 | inet->cork.base.dst = NULL; |
1503 | inet->cork.flags &= ~IPCORK_ALLFRAG; | 1505 | inet->cork.base.flags &= ~IPCORK_ALLFRAG; |
1504 | } | 1506 | } |
1505 | memset(&inet->cork.fl, 0, sizeof(inet->cork.fl)); | 1507 | memset(&inet->cork.fl, 0, sizeof(inet->cork.fl)); |
1506 | } | 1508 | } |
@@ -1515,7 +1517,7 @@ int ip6_push_pending_frames(struct sock *sk) | |||
1515 | struct net *net = sock_net(sk); | 1517 | struct net *net = sock_net(sk); |
1516 | struct ipv6hdr *hdr; | 1518 | struct ipv6hdr *hdr; |
1517 | struct ipv6_txoptions *opt = np->cork.opt; | 1519 | struct ipv6_txoptions *opt = np->cork.opt; |
1518 | struct rt6_info *rt = (struct rt6_info *)inet->cork.dst; | 1520 | struct rt6_info *rt = (struct rt6_info *)inet->cork.base.dst; |
1519 | struct flowi6 *fl6 = &inet->cork.fl.u.ip6; | 1521 | struct flowi6 *fl6 = &inet->cork.fl.u.ip6; |
1520 | unsigned char proto = fl6->flowi6_proto; | 1522 | unsigned char proto = fl6->flowi6_proto; |
1521 | int err = 0; | 1523 | int err = 0; |