ip6_output.c (c5e77f5216abdd1d98e6d14d9a3eb4e88d80011a) ip6_output.c (63159f29be1df7f93563a8a0f78c5e65fc844ed6)
1/*
2 * IPv6 output functions
3 * Linux INET6 implementation
4 *
5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt>
7 *
8 * Based on linux/net/ipv4/ip_output.c

--- 163 unchanged lines hidden (view full) ---

172 MAX_HEADER is not enough.
173 */
174 head_room = opt->opt_nflen + opt->opt_flen;
175 seg_len += head_room;
176 head_room += sizeof(struct ipv6hdr) + LL_RESERVED_SPACE(dst->dev);
177
178 if (skb_headroom(skb) < head_room) {
179 struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room);
1/*
2 * IPv6 output functions
3 * Linux INET6 implementation
4 *
5 * Authors:
6 * Pedro Roque <roque@di.fc.ul.pt>
7 *
8 * Based on linux/net/ipv4/ip_output.c

--- 163 unchanged lines hidden (view full) ---

172 MAX_HEADER is not enough.
173 */
174 head_room = opt->opt_nflen + opt->opt_flen;
175 seg_len += head_room;
176 head_room += sizeof(struct ipv6hdr) + LL_RESERVED_SPACE(dst->dev);
177
178 if (skb_headroom(skb) < head_room) {
179 struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room);
180 if (skb2 == NULL) {
180 if (!skb2) {
181 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
182 IPSTATS_MIB_OUTDISCARDS);
183 kfree_skb(skb);
184 return -ENOBUFS;
185 }
186 consume_skb(skb);
187 skb = skb2;
188 skb_set_owner_w(skb, sk);

--- 434 unchanged lines hidden (view full) ---

623 }
624
625 __skb_pull(skb, hlen);
626 fh = (struct frag_hdr *)__skb_push(skb, sizeof(struct frag_hdr));
627 __skb_push(skb, hlen);
628 skb_reset_network_header(skb);
629 memcpy(skb_network_header(skb), tmp_hdr, hlen);
630
181 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
182 IPSTATS_MIB_OUTDISCARDS);
183 kfree_skb(skb);
184 return -ENOBUFS;
185 }
186 consume_skb(skb);
187 skb = skb2;
188 skb_set_owner_w(skb, sk);

--- 434 unchanged lines hidden (view full) ---

623 }
624
625 __skb_pull(skb, hlen);
626 fh = (struct frag_hdr *)__skb_push(skb, sizeof(struct frag_hdr));
627 __skb_push(skb, hlen);
628 skb_reset_network_header(skb);
629 memcpy(skb_network_header(skb), tmp_hdr, hlen);
630
631 ipv6_select_ident(fh, rt);
631 ipv6_select_ident(net, fh, rt);
632 fh->nexthdr = nexthdr;
633 fh->reserved = 0;
634 fh->frag_off = htons(IP6_MF);
635 frag_id = fh->identification;
636
637 first_len = skb_pagelen(skb);
638 skb->data_len = first_len - skb_headlen(skb);
639 skb->len = first_len;

--- 130 unchanged lines hidden (view full) ---

770 skb_copy_from_linear_data(skb, skb_network_header(frag), hlen);
771
772 /*
773 * Build fragment header.
774 */
775 fh->nexthdr = nexthdr;
776 fh->reserved = 0;
777 if (!frag_id) {
632 fh->nexthdr = nexthdr;
633 fh->reserved = 0;
634 fh->frag_off = htons(IP6_MF);
635 frag_id = fh->identification;
636
637 first_len = skb_pagelen(skb);
638 skb->data_len = first_len - skb_headlen(skb);
639 skb->len = first_len;

--- 130 unchanged lines hidden (view full) ---

770 skb_copy_from_linear_data(skb, skb_network_header(frag), hlen);
771
772 /*
773 * Build fragment header.
774 */
775 fh->nexthdr = nexthdr;
776 fh->reserved = 0;
777 if (!frag_id) {
778 ipv6_select_ident(fh, rt);
778 ipv6_select_ident(net, fh, rt);
779 frag_id = fh->identification;
780 } else
781 fh->identification = frag_id;
782
783 /*
784 * Copy a block of the IP datagram.
785 */
786 BUG_ON(skb_copy_bits(skb, ptr, skb_transport_header(frag),

--- 31 unchanged lines hidden (view full) ---

818 return err;
819}
820
821static inline int ip6_rt_check(const struct rt6key *rt_key,
822 const struct in6_addr *fl_addr,
823 const struct in6_addr *addr_cache)
824{
825 return (rt_key->plen != 128 || !ipv6_addr_equal(fl_addr, &rt_key->addr)) &&
779 frag_id = fh->identification;
780 } else
781 fh->identification = frag_id;
782
783 /*
784 * Copy a block of the IP datagram.
785 */
786 BUG_ON(skb_copy_bits(skb, ptr, skb_transport_header(frag),

--- 31 unchanged lines hidden (view full) ---

818 return err;
819}
820
821static inline int ip6_rt_check(const struct rt6key *rt_key,
822 const struct in6_addr *fl_addr,
823 const struct in6_addr *addr_cache)
824{
825 return (rt_key->plen != 128 || !ipv6_addr_equal(fl_addr, &rt_key->addr)) &&
826 (addr_cache == NULL || !ipv6_addr_equal(fl_addr, addr_cache));
826 (!addr_cache || !ipv6_addr_equal(fl_addr, addr_cache));
827}
828
829static struct dst_entry *ip6_sk_dst_check(struct sock *sk,
830 struct dst_entry *dst,
831 const struct flowi6 *fl6)
832{
833 struct ipv6_pinfo *np = inet6_sk(sk);
834 struct rt6_info *rt;

--- 42 unchanged lines hidden (view full) ---

877{
878 struct net *net = sock_net(sk);
879#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
880 struct neighbour *n;
881 struct rt6_info *rt;
882#endif
883 int err;
884
827}
828
829static struct dst_entry *ip6_sk_dst_check(struct sock *sk,
830 struct dst_entry *dst,
831 const struct flowi6 *fl6)
832{
833 struct ipv6_pinfo *np = inet6_sk(sk);
834 struct rt6_info *rt;

--- 42 unchanged lines hidden (view full) ---

877{
878 struct net *net = sock_net(sk);
879#ifdef CONFIG_IPV6_OPTIMISTIC_DAD
880 struct neighbour *n;
881 struct rt6_info *rt;
882#endif
883 int err;
884
885 if (*dst == NULL)
885 if (!*dst)
886 *dst = ip6_route_output(net, sk, fl6);
887
888 err = (*dst)->error;
889 if (err)
890 goto out_err_release;
891
892 if (ipv6_addr_any(&fl6->saddr)) {
893 struct rt6_info *rt = (struct rt6_info *) *dst;

--- 146 unchanged lines hidden (view full) ---

1040 struct frag_hdr fhdr;
1041 int err;
1042
1043 /* There is support for UDP large send offload by network
1044 * device, so create one single skb packet containing complete
1045 * udp datagram
1046 */
1047 skb = skb_peek_tail(queue);
886 *dst = ip6_route_output(net, sk, fl6);
887
888 err = (*dst)->error;
889 if (err)
890 goto out_err_release;
891
892 if (ipv6_addr_any(&fl6->saddr)) {
893 struct rt6_info *rt = (struct rt6_info *) *dst;

--- 146 unchanged lines hidden (view full) ---

1040 struct frag_hdr fhdr;
1041 int err;
1042
1043 /* There is support for UDP large send offload by network
1044 * device, so create one single skb packet containing complete
1045 * udp datagram
1046 */
1047 skb = skb_peek_tail(queue);
1048 if (skb == NULL) {
1048 if (!skb) {
1049 skb = sock_alloc_send_skb(sk,
1050 hh_len + fragheaderlen + transhdrlen + 20,
1051 (flags & MSG_DONTWAIT), &err);
1049 skb = sock_alloc_send_skb(sk,
1050 hh_len + fragheaderlen + transhdrlen + 20,
1051 (flags & MSG_DONTWAIT), &err);
1052 if (skb == NULL)
1052 if (!skb)
1053 return err;
1054
1055 /* reserve space for Hardware header */
1056 skb_reserve(skb, hh_len);
1057
1058 /* create space for UDP/IP header */
1059 skb_put(skb, fragheaderlen + transhdrlen);
1060

--- 13 unchanged lines hidden (view full) ---

1074
1075 skb->ip_summed = CHECKSUM_PARTIAL;
1076 /* Specify the length of each IPv6 datagram fragment.
1077 * It has to be a multiple of 8.
1078 */
1079 skb_shinfo(skb)->gso_size = (mtu - fragheaderlen -
1080 sizeof(struct frag_hdr)) & ~7;
1081 skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
1053 return err;
1054
1055 /* reserve space for Hardware header */
1056 skb_reserve(skb, hh_len);
1057
1058 /* create space for UDP/IP header */
1059 skb_put(skb, fragheaderlen + transhdrlen);
1060

--- 13 unchanged lines hidden (view full) ---

1074
1075 skb->ip_summed = CHECKSUM_PARTIAL;
1076 /* Specify the length of each IPv6 datagram fragment.
1077 * It has to be a multiple of 8.
1078 */
1079 skb_shinfo(skb)->gso_size = (mtu - fragheaderlen -
1080 sizeof(struct frag_hdr)) & ~7;
1081 skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
1082 ipv6_select_ident(&fhdr, rt);
1082 ipv6_select_ident(sock_net(sk), &fhdr, rt);
1083 skb_shinfo(skb)->ip6_frag_id = fhdr.identification;
1084
1085append:
1086 return skb_append_datato_frags(sk, skb, getfrag, from,
1087 (length - transhdrlen));
1088}
1089
1090static inline struct ipv6_opt_hdr *ip6_opt_dup(struct ipv6_opt_hdr *src,

--- 11 unchanged lines hidden (view full) ---

1102static void ip6_append_data_mtu(unsigned int *mtu,
1103 int *maxfraglen,
1104 unsigned int fragheaderlen,
1105 struct sk_buff *skb,
1106 struct rt6_info *rt,
1107 unsigned int orig_mtu)
1108{
1109 if (!(rt->dst.flags & DST_XFRM_TUNNEL)) {
1083 skb_shinfo(skb)->ip6_frag_id = fhdr.identification;
1084
1085append:
1086 return skb_append_datato_frags(sk, skb, getfrag, from,
1087 (length - transhdrlen));
1088}
1089
1090static inline struct ipv6_opt_hdr *ip6_opt_dup(struct ipv6_opt_hdr *src,

--- 11 unchanged lines hidden (view full) ---

1102static void ip6_append_data_mtu(unsigned int *mtu,
1103 int *maxfraglen,
1104 unsigned int fragheaderlen,
1105 struct sk_buff *skb,
1106 struct rt6_info *rt,
1107 unsigned int orig_mtu)
1108{
1109 if (!(rt->dst.flags & DST_XFRM_TUNNEL)) {
1110 if (skb == NULL) {
1110 if (!skb) {
1111 /* first fragment, reserve header_len */
1112 *mtu = orig_mtu - rt->dst.header_len;
1113
1114 } else {
1115 /*
1116 * this fragment is not first, the headers
1117 * space is regarded as data space.
1118 */

--- 15 unchanged lines hidden (view full) ---

1134 /*
1135 * setup for corking
1136 */
1137 if (opt) {
1138 if (WARN_ON(v6_cork->opt))
1139 return -EINVAL;
1140
1141 v6_cork->opt = kzalloc(opt->tot_len, sk->sk_allocation);
1111 /* first fragment, reserve header_len */
1112 *mtu = orig_mtu - rt->dst.header_len;
1113
1114 } else {
1115 /*
1116 * this fragment is not first, the headers
1117 * space is regarded as data space.
1118 */

--- 15 unchanged lines hidden (view full) ---

1134 /*
1135 * setup for corking
1136 */
1137 if (opt) {
1138 if (WARN_ON(v6_cork->opt))
1139 return -EINVAL;
1140
1141 v6_cork->opt = kzalloc(opt->tot_len, sk->sk_allocation);
1142 if (unlikely(v6_cork->opt == NULL))
1142 if (unlikely(!v6_cork->opt))
1143 return -ENOBUFS;
1144
1145 v6_cork->opt->tot_len = opt->tot_len;
1146 v6_cork->opt->opt_flen = opt->opt_flen;
1147 v6_cork->opt->opt_nflen = opt->opt_nflen;
1148
1149 v6_cork->opt->dst0opt = ip6_opt_dup(opt->dst0opt,
1150 sk->sk_allocation);

--- 175 unchanged lines hidden (view full) ---

1326 unsigned int alloclen;
1327alloc_new_skb:
1328 /* There's no room in the current skb */
1329 if (skb)
1330 fraggap = skb->len - maxfraglen;
1331 else
1332 fraggap = 0;
1333 /* update mtu and maxfraglen if necessary */
1143 return -ENOBUFS;
1144
1145 v6_cork->opt->tot_len = opt->tot_len;
1146 v6_cork->opt->opt_flen = opt->opt_flen;
1147 v6_cork->opt->opt_nflen = opt->opt_nflen;
1148
1149 v6_cork->opt->dst0opt = ip6_opt_dup(opt->dst0opt,
1150 sk->sk_allocation);

--- 175 unchanged lines hidden (view full) ---

1326 unsigned int alloclen;
1327alloc_new_skb:
1328 /* There's no room in the current skb */
1329 if (skb)
1330 fraggap = skb->len - maxfraglen;
1331 else
1332 fraggap = 0;
1333 /* update mtu and maxfraglen if necessary */
1334 if (skb == NULL || skb_prev == NULL)
1334 if (!skb || !skb_prev)
1335 ip6_append_data_mtu(&mtu, &maxfraglen,
1336 fragheaderlen, skb, rt,
1337 orig_mtu);
1338
1339 skb_prev = skb;
1340
1341 /*
1342 * If remaining data exceeds the mtu,

--- 35 unchanged lines hidden (view full) ---

1378 (flags & MSG_DONTWAIT), &err);
1379 } else {
1380 skb = NULL;
1381 if (atomic_read(&sk->sk_wmem_alloc) <=
1382 2 * sk->sk_sndbuf)
1383 skb = sock_wmalloc(sk,
1384 alloclen + hh_len, 1,
1385 sk->sk_allocation);
1335 ip6_append_data_mtu(&mtu, &maxfraglen,
1336 fragheaderlen, skb, rt,
1337 orig_mtu);
1338
1339 skb_prev = skb;
1340
1341 /*
1342 * If remaining data exceeds the mtu,

--- 35 unchanged lines hidden (view full) ---

1378 (flags & MSG_DONTWAIT), &err);
1379 } else {
1380 skb = NULL;
1381 if (atomic_read(&sk->sk_wmem_alloc) <=
1382 2 * sk->sk_sndbuf)
1383 skb = sock_wmalloc(sk,
1384 alloclen + hh_len, 1,
1385 sk->sk_allocation);
1386 if (unlikely(skb == NULL))
1386 if (unlikely(!skb))
1387 err = -ENOBUFS;
1388 }
1387 err = -ENOBUFS;
1388 }
1389 if (skb == NULL)
1389 if (!skb)
1390 goto error;
1391 /*
1392 * Fill in the control structures
1393 */
1394 skb->protocol = htons(ETH_P_IPV6);
1395 skb->ip_summed = csummode;
1396 skb->csum = 0;
1397 /* reserve for fragmentation and ipsec header */

--- 175 unchanged lines hidden (view full) ---

1573 struct net *net = sock_net(sk);
1574 struct ipv6hdr *hdr;
1575 struct ipv6_txoptions *opt = v6_cork->opt;
1576 struct rt6_info *rt = (struct rt6_info *)cork->base.dst;
1577 struct flowi6 *fl6 = &cork->fl.u.ip6;
1578 unsigned char proto = fl6->flowi6_proto;
1579
1580 skb = __skb_dequeue(queue);
1390 goto error;
1391 /*
1392 * Fill in the control structures
1393 */
1394 skb->protocol = htons(ETH_P_IPV6);
1395 skb->ip_summed = csummode;
1396 skb->csum = 0;
1397 /* reserve for fragmentation and ipsec header */

--- 175 unchanged lines hidden (view full) ---

1573 struct net *net = sock_net(sk);
1574 struct ipv6hdr *hdr;
1575 struct ipv6_txoptions *opt = v6_cork->opt;
1576 struct rt6_info *rt = (struct rt6_info *)cork->base.dst;
1577 struct flowi6 *fl6 = &cork->fl.u.ip6;
1578 unsigned char proto = fl6->flowi6_proto;
1579
1580 skb = __skb_dequeue(queue);
1581 if (skb == NULL)
1581 if (!skb)
1582 goto out;
1583 tail_skb = &(skb_shinfo(skb)->frag_list);
1584
1585 /* move skb->data to ip header from ext header */
1586 if (skb->data < skb_network_header(skb))
1587 __skb_pull(skb, skb_network_offset(skb));
1588 while ((tmp_skb = __skb_dequeue(queue)) != NULL) {
1589 __skb_pull(tmp_skb, skb_network_header_len(skb));

--- 144 unchanged lines hidden ---
1582 goto out;
1583 tail_skb = &(skb_shinfo(skb)->frag_list);
1584
1585 /* move skb->data to ip header from ext header */
1586 if (skb->data < skb_network_header(skb))
1587 __skb_pull(skb, skb_network_offset(skb));
1588 while ((tmp_skb = __skb_dequeue(queue)) != NULL) {
1589 __skb_pull(tmp_skb, skb_network_header_len(skb));

--- 144 unchanged lines hidden ---