aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ip6_output.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/ip6_output.c')
-rw-r--r--net/ipv6/ip6_output.c223
1 files changed, 139 insertions, 84 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 980912ed7a38..9d4b165837d6 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -56,7 +56,7 @@
56#include <net/checksum.h> 56#include <net/checksum.h>
57#include <linux/mroute6.h> 57#include <linux/mroute6.h>
58 58
59static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)); 59int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *));
60 60
61int __ip6_local_out(struct sk_buff *skb) 61int __ip6_local_out(struct sk_buff *skb)
62{ 62{
@@ -145,14 +145,6 @@ static int ip6_finish_output2(struct sk_buff *skb)
145 return -EINVAL; 145 return -EINVAL;
146} 146}
147 147
148static inline int ip6_skb_dst_mtu(struct sk_buff *skb)
149{
150 struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL;
151
152 return (np && np->pmtudisc == IPV6_PMTUDISC_PROBE) ?
153 skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb));
154}
155
156static int ip6_finish_output(struct sk_buff *skb) 148static int ip6_finish_output(struct sk_buff *skb)
157{ 149{
158 if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) || 150 if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) ||
@@ -182,15 +174,15 @@ int ip6_output(struct sk_buff *skb)
182 * xmit an sk_buff (used by TCP, SCTP and DCCP) 174 * xmit an sk_buff (used by TCP, SCTP and DCCP)
183 */ 175 */
184 176
185int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, 177int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
186 struct ipv6_txoptions *opt) 178 struct ipv6_txoptions *opt)
187{ 179{
188 struct net *net = sock_net(sk); 180 struct net *net = sock_net(sk);
189 struct ipv6_pinfo *np = inet6_sk(sk); 181 struct ipv6_pinfo *np = inet6_sk(sk);
190 struct in6_addr *first_hop = &fl->fl6_dst; 182 struct in6_addr *first_hop = &fl6->daddr;
191 struct dst_entry *dst = skb_dst(skb); 183 struct dst_entry *dst = skb_dst(skb);
192 struct ipv6hdr *hdr; 184 struct ipv6hdr *hdr;
193 u8 proto = fl->proto; 185 u8 proto = fl6->flowi6_proto;
194 int seg_len = skb->len; 186 int seg_len = skb->len;
195 int hlimit = -1; 187 int hlimit = -1;
196 int tclass = 0; 188 int tclass = 0;
@@ -238,13 +230,13 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
238 if (hlimit < 0) 230 if (hlimit < 0)
239 hlimit = ip6_dst_hoplimit(dst); 231 hlimit = ip6_dst_hoplimit(dst);
240 232
241 *(__be32 *)hdr = htonl(0x60000000 | (tclass << 20)) | fl->fl6_flowlabel; 233 *(__be32 *)hdr = htonl(0x60000000 | (tclass << 20)) | fl6->flowlabel;
242 234
243 hdr->payload_len = htons(seg_len); 235 hdr->payload_len = htons(seg_len);
244 hdr->nexthdr = proto; 236 hdr->nexthdr = proto;
245 hdr->hop_limit = hlimit; 237 hdr->hop_limit = hlimit;
246 238
247 ipv6_addr_copy(&hdr->saddr, &fl->fl6_src); 239 ipv6_addr_copy(&hdr->saddr, &fl6->saddr);
248 ipv6_addr_copy(&hdr->daddr, first_hop); 240 ipv6_addr_copy(&hdr->daddr, first_hop);
249 241
250 skb->priority = sk->sk_priority; 242 skb->priority = sk->sk_priority;
@@ -282,13 +274,10 @@ int ip6_nd_hdr(struct sock *sk, struct sk_buff *skb, struct net_device *dev,
282{ 274{
283 struct ipv6_pinfo *np = inet6_sk(sk); 275 struct ipv6_pinfo *np = inet6_sk(sk);
284 struct ipv6hdr *hdr; 276 struct ipv6hdr *hdr;
285 int totlen;
286 277
287 skb->protocol = htons(ETH_P_IPV6); 278 skb->protocol = htons(ETH_P_IPV6);
288 skb->dev = dev; 279 skb->dev = dev;
289 280
290 totlen = len + sizeof(struct ipv6hdr);
291
292 skb_reset_network_header(skb); 281 skb_reset_network_header(skb);
293 skb_put(skb, sizeof(struct ipv6hdr)); 282 skb_put(skb, sizeof(struct ipv6hdr));
294 hdr = ipv6_hdr(skb); 283 hdr = ipv6_hdr(skb);
@@ -409,6 +398,9 @@ int ip6_forward(struct sk_buff *skb)
409 goto drop; 398 goto drop;
410 } 399 }
411 400
401 if (skb->pkt_type != PACKET_HOST)
402 goto drop;
403
412 skb_forward_csum(skb); 404 skb_forward_csum(skb);
413 405
414 /* 406 /*
@@ -484,10 +476,13 @@ int ip6_forward(struct sk_buff *skb)
484 else 476 else
485 target = &hdr->daddr; 477 target = &hdr->daddr;
486 478
479 if (!rt->rt6i_peer)
480 rt6_bind_peer(rt, 1);
481
487 /* Limit redirects both by destination (here) 482 /* Limit redirects both by destination (here)
488 and by source (inside ndisc_send_redirect) 483 and by source (inside ndisc_send_redirect)
489 */ 484 */
490 if (xrlim_allow(dst, 1*HZ)) 485 if (inet_peer_xrlim_allow(rt->rt6i_peer, 1*HZ))
491 ndisc_send_redirect(skb, n, target); 486 ndisc_send_redirect(skb, n, target);
492 } else { 487 } else {
493 int addrtype = ipv6_addr_type(&hdr->saddr); 488 int addrtype = ipv6_addr_type(&hdr->saddr);
@@ -601,7 +596,7 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
601 return offset; 596 return offset;
602} 597}
603 598
604static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) 599int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
605{ 600{
606 struct sk_buff *frag; 601 struct sk_buff *frag;
607 struct rt6_info *rt = (struct rt6_info*)skb_dst(skb); 602 struct rt6_info *rt = (struct rt6_info*)skb_dst(skb);
@@ -637,7 +632,7 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
637 } 632 }
638 mtu -= hlen + sizeof(struct frag_hdr); 633 mtu -= hlen + sizeof(struct frag_hdr);
639 634
640 if (skb_has_frags(skb)) { 635 if (skb_has_frag_list(skb)) {
641 int first_len = skb_pagelen(skb); 636 int first_len = skb_pagelen(skb);
642 struct sk_buff *frag2; 637 struct sk_buff *frag2;
643 638
@@ -784,7 +779,7 @@ slow_path:
784 /* IF: it doesn't fit, use 'mtu' - the data space left */ 779 /* IF: it doesn't fit, use 'mtu' - the data space left */
785 if (len > mtu) 780 if (len > mtu)
786 len = mtu; 781 len = mtu;
787 /* IF: we are not sending upto and including the packet end 782 /* IF: we are not sending up to and including the packet end
788 then align the next start on an eight byte boundary */ 783 then align the next start on an eight byte boundary */
789 if (len < left) { 784 if (len < left) {
790 len &= ~7; 785 len &= ~7;
@@ -874,17 +869,17 @@ fail:
874 return err; 869 return err;
875} 870}
876 871
877static inline int ip6_rt_check(struct rt6key *rt_key, 872static inline int ip6_rt_check(const struct rt6key *rt_key,
878 struct in6_addr *fl_addr, 873 const struct in6_addr *fl_addr,
879 struct in6_addr *addr_cache) 874 const struct in6_addr *addr_cache)
880{ 875{
881 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)) &&
882 (addr_cache == NULL || !ipv6_addr_equal(fl_addr, addr_cache))); 877 (addr_cache == NULL || !ipv6_addr_equal(fl_addr, addr_cache));
883} 878}
884 879
885static struct dst_entry *ip6_sk_dst_check(struct sock *sk, 880static struct dst_entry *ip6_sk_dst_check(struct sock *sk,
886 struct dst_entry *dst, 881 struct dst_entry *dst,
887 struct flowi *fl) 882 const struct flowi6 *fl6)
888{ 883{
889 struct ipv6_pinfo *np = inet6_sk(sk); 884 struct ipv6_pinfo *np = inet6_sk(sk);
890 struct rt6_info *rt = (struct rt6_info *)dst; 885 struct rt6_info *rt = (struct rt6_info *)dst;
@@ -909,11 +904,11 @@ static struct dst_entry *ip6_sk_dst_check(struct sock *sk,
909 * sockets. 904 * sockets.
910 * 2. oif also should be the same. 905 * 2. oif also should be the same.
911 */ 906 */
912 if (ip6_rt_check(&rt->rt6i_dst, &fl->fl6_dst, np->daddr_cache) || 907 if (ip6_rt_check(&rt->rt6i_dst, &fl6->daddr, np->daddr_cache) ||
913#ifdef CONFIG_IPV6_SUBTREES 908#ifdef CONFIG_IPV6_SUBTREES
914 ip6_rt_check(&rt->rt6i_src, &fl->fl6_src, np->saddr_cache) || 909 ip6_rt_check(&rt->rt6i_src, &fl6->saddr, np->saddr_cache) ||
915#endif 910#endif
916 (fl->oif && fl->oif != dst->dev->ifindex)) { 911 (fl6->flowi6_oif && fl6->flowi6_oif != dst->dev->ifindex)) {
917 dst_release(dst); 912 dst_release(dst);
918 dst = NULL; 913 dst = NULL;
919 } 914 }
@@ -923,22 +918,22 @@ out:
923} 918}
924 919
925static int ip6_dst_lookup_tail(struct sock *sk, 920static int ip6_dst_lookup_tail(struct sock *sk,
926 struct dst_entry **dst, struct flowi *fl) 921 struct dst_entry **dst, struct flowi6 *fl6)
927{ 922{
928 int err; 923 int err;
929 struct net *net = sock_net(sk); 924 struct net *net = sock_net(sk);
930 925
931 if (*dst == NULL) 926 if (*dst == NULL)
932 *dst = ip6_route_output(net, sk, fl); 927 *dst = ip6_route_output(net, sk, fl6);
933 928
934 if ((err = (*dst)->error)) 929 if ((err = (*dst)->error))
935 goto out_err_release; 930 goto out_err_release;
936 931
937 if (ipv6_addr_any(&fl->fl6_src)) { 932 if (ipv6_addr_any(&fl6->saddr)) {
938 err = ipv6_dev_get_saddr(net, ip6_dst_idev(*dst)->dev, 933 struct rt6_info *rt = (struct rt6_info *) *dst;
939 &fl->fl6_dst, 934 err = ip6_route_get_saddr(net, rt, &fl6->daddr,
940 sk ? inet6_sk(sk)->srcprefs : 0, 935 sk ? inet6_sk(sk)->srcprefs : 0,
941 &fl->fl6_src); 936 &fl6->saddr);
942 if (err) 937 if (err)
943 goto out_err_release; 938 goto out_err_release;
944 } 939 }
@@ -954,10 +949,10 @@ static int ip6_dst_lookup_tail(struct sock *sk,
954 */ 949 */
955 if ((*dst)->neighbour && !((*dst)->neighbour->nud_state & NUD_VALID)) { 950 if ((*dst)->neighbour && !((*dst)->neighbour->nud_state & NUD_VALID)) {
956 struct inet6_ifaddr *ifp; 951 struct inet6_ifaddr *ifp;
957 struct flowi fl_gw; 952 struct flowi6 fl_gw6;
958 int redirect; 953 int redirect;
959 954
960 ifp = ipv6_get_ifaddr(net, &fl->fl6_src, 955 ifp = ipv6_get_ifaddr(net, &fl6->saddr,
961 (*dst)->dev, 1); 956 (*dst)->dev, 1);
962 957
963 redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC); 958 redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC);
@@ -970,9 +965,9 @@ static int ip6_dst_lookup_tail(struct sock *sk,
970 * default router instead 965 * default router instead
971 */ 966 */
972 dst_release(*dst); 967 dst_release(*dst);
973 memcpy(&fl_gw, fl, sizeof(struct flowi)); 968 memcpy(&fl_gw6, fl6, sizeof(struct flowi6));
974 memset(&fl_gw.fl6_dst, 0, sizeof(struct in6_addr)); 969 memset(&fl_gw6.daddr, 0, sizeof(struct in6_addr));
975 *dst = ip6_route_output(net, sk, &fl_gw); 970 *dst = ip6_route_output(net, sk, &fl_gw6);
976 if ((err = (*dst)->error)) 971 if ((err = (*dst)->error))
977 goto out_err_release; 972 goto out_err_release;
978 } 973 }
@@ -993,43 +988,85 @@ out_err_release:
993 * ip6_dst_lookup - perform route lookup on flow 988 * ip6_dst_lookup - perform route lookup on flow
994 * @sk: socket which provides route info 989 * @sk: socket which provides route info
995 * @dst: pointer to dst_entry * for result 990 * @dst: pointer to dst_entry * for result
996 * @fl: flow to lookup 991 * @fl6: flow to lookup
997 * 992 *
998 * This function performs a route lookup on the given flow. 993 * This function performs a route lookup on the given flow.
999 * 994 *
1000 * It returns zero on success, or a standard errno code on error. 995 * It returns zero on success, or a standard errno code on error.
1001 */ 996 */
1002int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl) 997int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi6 *fl6)
1003{ 998{
1004 *dst = NULL; 999 *dst = NULL;
1005 return ip6_dst_lookup_tail(sk, dst, fl); 1000 return ip6_dst_lookup_tail(sk, dst, fl6);
1006} 1001}
1007EXPORT_SYMBOL_GPL(ip6_dst_lookup); 1002EXPORT_SYMBOL_GPL(ip6_dst_lookup);
1008 1003
1009/** 1004/**
1010 * ip6_sk_dst_lookup - perform socket cached route lookup on flow 1005 * ip6_dst_lookup_flow - perform route lookup on flow with ipsec
1006 * @sk: socket which provides route info
1007 * @fl6: flow to lookup
1008 * @final_dst: final destination address for ipsec lookup
1009 * @can_sleep: we are in a sleepable context
1010 *
1011 * This function performs a route lookup on the given flow.
1012 *
1013 * It returns a valid dst pointer on success, or a pointer encoded
1014 * error code.
1015 */
1016struct dst_entry *ip6_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
1017 const struct in6_addr *final_dst,
1018 bool can_sleep)
1019{
1020 struct dst_entry *dst = NULL;
1021 int err;
1022
1023 err = ip6_dst_lookup_tail(sk, &dst, fl6);
1024 if (err)
1025 return ERR_PTR(err);
1026 if (final_dst)
1027 ipv6_addr_copy(&fl6->daddr, final_dst);
1028 if (can_sleep)
1029 fl6->flowi6_flags |= FLOWI_FLAG_CAN_SLEEP;
1030
1031 return xfrm_lookup(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0);
1032}
1033EXPORT_SYMBOL_GPL(ip6_dst_lookup_flow);
1034
1035/**
1036 * ip6_sk_dst_lookup_flow - perform socket cached route lookup on flow
1011 * @sk: socket which provides the dst cache and route info 1037 * @sk: socket which provides the dst cache and route info
1012 * @dst: pointer to dst_entry * for result 1038 * @fl6: flow to lookup
1013 * @fl: flow to lookup 1039 * @final_dst: final destination address for ipsec lookup
1040 * @can_sleep: we are in a sleepable context
1014 * 1041 *
1015 * This function performs a route lookup on the given flow with the 1042 * This function performs a route lookup on the given flow with the
1016 * possibility of using the cached route in the socket if it is valid. 1043 * possibility of using the cached route in the socket if it is valid.
1017 * It will take the socket dst lock when operating on the dst cache. 1044 * It will take the socket dst lock when operating on the dst cache.
1018 * As a result, this function can only be used in process context. 1045 * As a result, this function can only be used in process context.
1019 * 1046 *
1020 * It returns zero on success, or a standard errno code on error. 1047 * It returns a valid dst pointer on success, or a pointer encoded
1048 * error code.
1021 */ 1049 */
1022int ip6_sk_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl) 1050struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
1051 const struct in6_addr *final_dst,
1052 bool can_sleep)
1023{ 1053{
1024 *dst = NULL; 1054 struct dst_entry *dst = sk_dst_check(sk, inet6_sk(sk)->dst_cookie);
1025 if (sk) { 1055 int err;
1026 *dst = sk_dst_check(sk, inet6_sk(sk)->dst_cookie); 1056
1027 *dst = ip6_sk_dst_check(sk, *dst, fl); 1057 dst = ip6_sk_dst_check(sk, dst, fl6);
1028 }
1029 1058
1030 return ip6_dst_lookup_tail(sk, dst, fl); 1059 err = ip6_dst_lookup_tail(sk, &dst, fl6);
1060 if (err)
1061 return ERR_PTR(err);
1062 if (final_dst)
1063 ipv6_addr_copy(&fl6->daddr, final_dst);
1064 if (can_sleep)
1065 fl6->flowi6_flags |= FLOWI_FLAG_CAN_SLEEP;
1066
1067 return xfrm_lookup(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0);
1031} 1068}
1032EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup); 1069EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup_flow);
1033 1070
1034static inline int ip6_ufo_append_data(struct sock *sk, 1071static inline int ip6_ufo_append_data(struct sock *sk,
1035 int getfrag(void *from, char *to, int offset, int len, 1072 int getfrag(void *from, char *to, int offset, int len,
@@ -1066,7 +1103,6 @@ static inline int ip6_ufo_append_data(struct sock *sk,
1066 1103
1067 skb->ip_summed = CHECKSUM_PARTIAL; 1104 skb->ip_summed = CHECKSUM_PARTIAL;
1068 skb->csum = 0; 1105 skb->csum = 0;
1069 sk->sk_sndmsg_off = 0;
1070 } 1106 }
1071 1107
1072 err = skb_append_datato_frags(sk,skb, getfrag, from, 1108 err = skb_append_datato_frags(sk,skb, getfrag, from,
@@ -1109,11 +1145,12 @@ static inline struct ipv6_rt_hdr *ip6_rthdr_dup(struct ipv6_rt_hdr *src,
1109int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, 1145int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1110 int offset, int len, int odd, struct sk_buff *skb), 1146 int offset, int len, int odd, struct sk_buff *skb),
1111 void *from, int length, int transhdrlen, 1147 void *from, int length, int transhdrlen,
1112 int hlimit, int tclass, struct ipv6_txoptions *opt, struct flowi *fl, 1148 int hlimit, int tclass, struct ipv6_txoptions *opt, struct flowi6 *fl6,
1113 struct rt6_info *rt, unsigned int flags, int dontfrag) 1149 struct rt6_info *rt, unsigned int flags, int dontfrag)
1114{ 1150{
1115 struct inet_sock *inet = inet_sk(sk); 1151 struct inet_sock *inet = inet_sk(sk);
1116 struct ipv6_pinfo *np = inet6_sk(sk); 1152 struct ipv6_pinfo *np = inet6_sk(sk);
1153 struct inet_cork *cork;
1117 struct sk_buff *skb; 1154 struct sk_buff *skb;
1118 unsigned int maxfraglen, fragheaderlen; 1155 unsigned int maxfraglen, fragheaderlen;
1119 int exthdrlen; 1156 int exthdrlen;
@@ -1123,9 +1160,11 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1123 int err; 1160 int err;
1124 int offset = 0; 1161 int offset = 0;
1125 int csummode = CHECKSUM_NONE; 1162 int csummode = CHECKSUM_NONE;
1163 __u8 tx_flags = 0;
1126 1164
1127 if (flags&MSG_PROBE) 1165 if (flags&MSG_PROBE)
1128 return 0; 1166 return 0;
1167 cork = &inet->cork.base;
1129 if (skb_queue_empty(&sk->sk_write_queue)) { 1168 if (skb_queue_empty(&sk->sk_write_queue)) {
1130 /* 1169 /*
1131 * setup for corking 1170 * setup for corking
@@ -1165,8 +1204,8 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1165 /* need source address above miyazawa*/ 1204 /* need source address above miyazawa*/
1166 } 1205 }
1167 dst_hold(&rt->dst); 1206 dst_hold(&rt->dst);
1168 inet->cork.dst = &rt->dst; 1207 cork->dst = &rt->dst;
1169 inet->cork.fl = *fl; 1208 inet->cork.fl.u.ip6 = *fl6;
1170 np->cork.hop_limit = hlimit; 1209 np->cork.hop_limit = hlimit;
1171 np->cork.tclass = tclass; 1210 np->cork.tclass = tclass;
1172 mtu = np->pmtudisc == IPV6_PMTUDISC_PROBE ? 1211 mtu = np->pmtudisc == IPV6_PMTUDISC_PROBE ?
@@ -1175,10 +1214,10 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1175 if (np->frag_size) 1214 if (np->frag_size)
1176 mtu = np->frag_size; 1215 mtu = np->frag_size;
1177 } 1216 }
1178 inet->cork.fragsize = mtu; 1217 cork->fragsize = mtu;
1179 if (dst_allfrag(rt->dst.path)) 1218 if (dst_allfrag(rt->dst.path))
1180 inet->cork.flags |= IPCORK_ALLFRAG; 1219 cork->flags |= IPCORK_ALLFRAG;
1181 inet->cork.length = 0; 1220 cork->length = 0;
1182 sk->sk_sndmsg_page = NULL; 1221 sk->sk_sndmsg_page = NULL;
1183 sk->sk_sndmsg_off = 0; 1222 sk->sk_sndmsg_off = 0;
1184 exthdrlen = rt->dst.header_len + (opt ? opt->opt_flen : 0) - 1223 exthdrlen = rt->dst.header_len + (opt ? opt->opt_flen : 0) -
@@ -1186,12 +1225,12 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1186 length += exthdrlen; 1225 length += exthdrlen;
1187 transhdrlen += exthdrlen; 1226 transhdrlen += exthdrlen;
1188 } else { 1227 } else {
1189 rt = (struct rt6_info *)inet->cork.dst; 1228 rt = (struct rt6_info *)cork->dst;
1190 fl = &inet->cork.fl; 1229 fl6 = &inet->cork.fl.u.ip6;
1191 opt = np->cork.opt; 1230 opt = np->cork.opt;
1192 transhdrlen = 0; 1231 transhdrlen = 0;
1193 exthdrlen = 0; 1232 exthdrlen = 0;
1194 mtu = inet->cork.fragsize; 1233 mtu = cork->fragsize;
1195 } 1234 }
1196 1235
1197 hh_len = LL_RESERVED_SPACE(rt->dst.dev); 1236 hh_len = LL_RESERVED_SPACE(rt->dst.dev);
@@ -1201,12 +1240,19 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1201 maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen - sizeof(struct frag_hdr); 1240 maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen - sizeof(struct frag_hdr);
1202 1241
1203 if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) { 1242 if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) {
1204 if (inet->cork.length + length > sizeof(struct ipv6hdr) + IPV6_MAXPLEN - fragheaderlen) { 1243 if (cork->length + length > sizeof(struct ipv6hdr) + IPV6_MAXPLEN - fragheaderlen) {
1205 ipv6_local_error(sk, EMSGSIZE, fl, mtu-exthdrlen); 1244 ipv6_local_error(sk, EMSGSIZE, fl6, mtu-exthdrlen);
1206 return -EMSGSIZE; 1245 return -EMSGSIZE;
1207 } 1246 }
1208 } 1247 }
1209 1248
1249 /* For UDP, check if TX timestamp is enabled */
1250 if (sk->sk_type == SOCK_DGRAM) {
1251 err = sock_tx_timestamp(sk, &tx_flags);
1252 if (err)
1253 goto error;
1254 }
1255
1210 /* 1256 /*
1211 * Let's try using as much space as possible. 1257 * Let's try using as much space as possible.
1212 * Use MTU if total length of the message fits into the MTU. 1258 * Use MTU if total length of the message fits into the MTU.
@@ -1223,11 +1269,11 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1223 * --yoshfuji 1269 * --yoshfuji
1224 */ 1270 */
1225 1271
1226 inet->cork.length += length; 1272 cork->length += length;
1227 if (length > mtu) { 1273 if (length > mtu) {
1228 int proto = sk->sk_protocol; 1274 int proto = sk->sk_protocol;
1229 if (dontfrag && (proto == IPPROTO_UDP || proto == IPPROTO_RAW)){ 1275 if (dontfrag && (proto == IPPROTO_UDP || proto == IPPROTO_RAW)){
1230 ipv6_local_rxpmtu(sk, fl, mtu-exthdrlen); 1276 ipv6_local_rxpmtu(sk, fl6, mtu-exthdrlen);
1231 return -EMSGSIZE; 1277 return -EMSGSIZE;
1232 } 1278 }
1233 1279
@@ -1248,7 +1294,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1248 1294
1249 while (length > 0) { 1295 while (length > 0) {
1250 /* Check if the remaining data fits into current packet. */ 1296 /* Check if the remaining data fits into current packet. */
1251 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;
1252 if (copy < length) 1298 if (copy < length)
1253 copy = maxfraglen - skb->len; 1299 copy = maxfraglen - skb->len;
1254 1300
@@ -1273,7 +1319,7 @@ alloc_new_skb:
1273 * we know we need more fragment(s). 1319 * we know we need more fragment(s).
1274 */ 1320 */
1275 datalen = length + fraggap; 1321 datalen = length + fraggap;
1276 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)
1277 datalen = maxfraglen - fragheaderlen; 1323 datalen = maxfraglen - fragheaderlen;
1278 1324
1279 fraglen = datalen + fragheaderlen; 1325 fraglen = datalen + fragheaderlen;
@@ -1311,6 +1357,12 @@ alloc_new_skb:
1311 sk->sk_allocation); 1357 sk->sk_allocation);
1312 if (unlikely(skb == NULL)) 1358 if (unlikely(skb == NULL))
1313 err = -ENOBUFS; 1359 err = -ENOBUFS;
1360 else {
1361 /* Only the initial fragment
1362 * is time stamped.
1363 */
1364 tx_flags = 0;
1365 }
1314 } 1366 }
1315 if (skb == NULL) 1367 if (skb == NULL)
1316 goto error; 1368 goto error;
@@ -1322,6 +1374,9 @@ alloc_new_skb:
1322 /* reserve for fragmentation */ 1374 /* reserve for fragmentation */
1323 skb_reserve(skb, hh_len+sizeof(struct frag_hdr)); 1375 skb_reserve(skb, hh_len+sizeof(struct frag_hdr));
1324 1376
1377 if (sk->sk_type == SOCK_DGRAM)
1378 skb_shinfo(skb)->tx_flags = tx_flags;
1379
1325 /* 1380 /*
1326 * Find where to start putting bytes 1381 * Find where to start putting bytes
1327 */ 1382 */
@@ -1428,7 +1483,7 @@ alloc_new_skb:
1428 } 1483 }
1429 return 0; 1484 return 0;
1430error: 1485error:
1431 inet->cork.length -= length; 1486 cork->length -= length;
1432 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);
1433 return err; 1488 return err;
1434} 1489}
@@ -1444,10 +1499,10 @@ static void ip6_cork_release(struct inet_sock *inet, struct ipv6_pinfo *np)
1444 np->cork.opt = NULL; 1499 np->cork.opt = NULL;
1445 } 1500 }
1446 1501
1447 if (inet->cork.dst) { 1502 if (inet->cork.base.dst) {
1448 dst_release(inet->cork.dst); 1503 dst_release(inet->cork.base.dst);
1449 inet->cork.dst = NULL; 1504 inet->cork.base.dst = NULL;
1450 inet->cork.flags &= ~IPCORK_ALLFRAG; 1505 inet->cork.base.flags &= ~IPCORK_ALLFRAG;
1451 } 1506 }
1452 memset(&inet->cork.fl, 0, sizeof(inet->cork.fl)); 1507 memset(&inet->cork.fl, 0, sizeof(inet->cork.fl));
1453} 1508}
@@ -1462,9 +1517,9 @@ int ip6_push_pending_frames(struct sock *sk)
1462 struct net *net = sock_net(sk); 1517 struct net *net = sock_net(sk);
1463 struct ipv6hdr *hdr; 1518 struct ipv6hdr *hdr;
1464 struct ipv6_txoptions *opt = np->cork.opt; 1519 struct ipv6_txoptions *opt = np->cork.opt;
1465 struct rt6_info *rt = (struct rt6_info *)inet->cork.dst; 1520 struct rt6_info *rt = (struct rt6_info *)inet->cork.base.dst;
1466 struct flowi *fl = &inet->cork.fl; 1521 struct flowi6 *fl6 = &inet->cork.fl.u.ip6;
1467 unsigned char proto = fl->proto; 1522 unsigned char proto = fl6->flowi6_proto;
1468 int err = 0; 1523 int err = 0;
1469 1524
1470 if ((skb = __skb_dequeue(&sk->sk_write_queue)) == NULL) 1525 if ((skb = __skb_dequeue(&sk->sk_write_queue)) == NULL)
@@ -1489,7 +1544,7 @@ int ip6_push_pending_frames(struct sock *sk)
1489 if (np->pmtudisc < IPV6_PMTUDISC_DO) 1544 if (np->pmtudisc < IPV6_PMTUDISC_DO)
1490 skb->local_df = 1; 1545 skb->local_df = 1;
1491 1546
1492 ipv6_addr_copy(final_dst, &fl->fl6_dst); 1547 ipv6_addr_copy(final_dst, &fl6->daddr);
1493 __skb_pull(skb, skb_network_header_len(skb)); 1548 __skb_pull(skb, skb_network_header_len(skb));
1494 if (opt && opt->opt_flen) 1549 if (opt && opt->opt_flen)
1495 ipv6_push_frag_opts(skb, opt, &proto); 1550 ipv6_push_frag_opts(skb, opt, &proto);
@@ -1500,12 +1555,12 @@ int ip6_push_pending_frames(struct sock *sk)
1500 skb_reset_network_header(skb); 1555 skb_reset_network_header(skb);
1501 hdr = ipv6_hdr(skb); 1556 hdr = ipv6_hdr(skb);
1502 1557
1503 *(__be32*)hdr = fl->fl6_flowlabel | 1558 *(__be32*)hdr = fl6->flowlabel |
1504 htonl(0x60000000 | ((int)np->cork.tclass << 20)); 1559 htonl(0x60000000 | ((int)np->cork.tclass << 20));
1505 1560
1506 hdr->hop_limit = np->cork.hop_limit; 1561 hdr->hop_limit = np->cork.hop_limit;
1507 hdr->nexthdr = proto; 1562 hdr->nexthdr = proto;
1508 ipv6_addr_copy(&hdr->saddr, &fl->fl6_src); 1563 ipv6_addr_copy(&hdr->saddr, &fl6->saddr);
1509 ipv6_addr_copy(&hdr->daddr, final_dst); 1564 ipv6_addr_copy(&hdr->daddr, final_dst);
1510 1565
1511 skb->priority = sk->sk_priority; 1566 skb->priority = sk->sk_priority;