ip6_output.c (888dc273ea4e7ca332a6f73d10dfc8f2b212c803) ip6_output.c (b7034146756b9e91cc059b19df7fe4defd4d7de7)
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * IPv6 output functions
4 * Linux INET6 implementation
5 *
6 * Authors:
7 * Pedro Roque <roque@di.fc.ul.pt>
8 *
9 * Based on linux/net/ipv4/ip_output.c
10 *
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
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 *
11 * Changes:
12 * A.N.Kuznetsov : airthmetics in fragmentation.
13 * extension headers are implemented.
14 * route changes now work.
15 * ip6_forward does not confuse sniffers.
16 * etc.
17 *
18 * H. von Brand : Added missing #include <linux/string.h>

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

119 }
120 rcu_read_unlock_bh();
121
122 IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
123 kfree_skb(skb);
124 return -EINVAL;
125}
126
15 * Changes:
16 * A.N.Kuznetsov : airthmetics in fragmentation.
17 * extension headers are implemented.
18 * route changes now work.
19 * ip6_forward does not confuse sniffers.
20 * etc.
21 *
22 * H. von Brand : Added missing #include <linux/string.h>

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

123 }
124 rcu_read_unlock_bh();
125
126 IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
127 kfree_skb(skb);
128 return -EINVAL;
129}
130
127static int ip6_finish_output(struct net *net, struct sock *sk, struct sk_buff *skb)
131static int __ip6_finish_output(struct net *net, struct sock *sk, struct sk_buff *skb)
128{
132{
129 int ret;
130
131 ret = BPF_CGROUP_RUN_PROG_INET_EGRESS(sk, skb);
132 if (ret) {
133 kfree_skb(skb);
134 return ret;
135 }
136
137#if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM)
138 /* Policy lookup after SNAT yielded a new policy */
139 if (skb_dst(skb)->xfrm) {
140 IPCB(skb)->flags |= IPSKB_REROUTED;
141 return dst_output(net, sk, skb);
142 }
143#endif
144
145 if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) ||
146 dst_allfrag(skb_dst(skb)) ||
147 (IP6CB(skb)->frag_max_size && skb->len > IP6CB(skb)->frag_max_size))
148 return ip6_fragment(net, sk, skb, ip6_finish_output2);
149 else
150 return ip6_finish_output2(net, sk, skb);
151}
152
133#if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM)
134 /* Policy lookup after SNAT yielded a new policy */
135 if (skb_dst(skb)->xfrm) {
136 IPCB(skb)->flags |= IPSKB_REROUTED;
137 return dst_output(net, sk, skb);
138 }
139#endif
140
141 if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) ||
142 dst_allfrag(skb_dst(skb)) ||
143 (IP6CB(skb)->frag_max_size && skb->len > IP6CB(skb)->frag_max_size))
144 return ip6_fragment(net, sk, skb, ip6_finish_output2);
145 else
146 return ip6_finish_output2(net, sk, skb);
147}
148
149static int ip6_finish_output(struct net *net, struct sock *sk, struct sk_buff *skb)
150{
151 int ret;
152
153 ret = BPF_CGROUP_RUN_PROG_INET_EGRESS(sk, skb);
154 switch (ret) {
155 case NET_XMIT_SUCCESS:
156 return __ip6_finish_output(net, sk, skb);
157 case NET_XMIT_CN:
158 return __ip6_finish_output(net, sk, skb) ? : ret;
159 default:
160 kfree_skb(skb);
161 return ret;
162 }
163}
164
153int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
154{
155 struct net_device *dev = skb_dst(skb)->dev;
156 struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
157
158 skb->protocol = htons(ETH_P_IPV6);
159 skb->dev = dev;
160

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

583#ifdef CONFIG_NET_SCHED
584 to->tc_index = from->tc_index;
585#endif
586 nf_copy(to, from);
587 skb_ext_copy(to, from);
588 skb_copy_secmark(to, from);
589}
590
165int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
166{
167 struct net_device *dev = skb_dst(skb)->dev;
168 struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
169
170 skb->protocol = htons(ETH_P_IPV6);
171 skb->dev = dev;
172

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

595#ifdef CONFIG_NET_SCHED
596 to->tc_index = from->tc_index;
597#endif
598 nf_copy(to, from);
599 skb_ext_copy(to, from);
600 skb_copy_secmark(to, from);
601}
602
603int ip6_fraglist_init(struct sk_buff *skb, unsigned int hlen, u8 *prevhdr,
604 u8 nexthdr, __be32 frag_id,
605 struct ip6_fraglist_iter *iter)
606{
607 unsigned int first_len;
608 struct frag_hdr *fh;
609
610 /* BUILD HEADER */
611 *prevhdr = NEXTHDR_FRAGMENT;
612 iter->tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC);
613 if (!iter->tmp_hdr)
614 return -ENOMEM;
615
616 iter->frag = skb_shinfo(skb)->frag_list;
617 skb_frag_list_init(skb);
618
619 iter->offset = 0;
620 iter->hlen = hlen;
621 iter->frag_id = frag_id;
622 iter->nexthdr = nexthdr;
623
624 __skb_pull(skb, hlen);
625 fh = __skb_push(skb, sizeof(struct frag_hdr));
626 __skb_push(skb, hlen);
627 skb_reset_network_header(skb);
628 memcpy(skb_network_header(skb), iter->tmp_hdr, hlen);
629
630 fh->nexthdr = nexthdr;
631 fh->reserved = 0;
632 fh->frag_off = htons(IP6_MF);
633 fh->identification = frag_id;
634
635 first_len = skb_pagelen(skb);
636 skb->data_len = first_len - skb_headlen(skb);
637 skb->len = first_len;
638 ipv6_hdr(skb)->payload_len = htons(first_len - sizeof(struct ipv6hdr));
639
640 return 0;
641}
642EXPORT_SYMBOL(ip6_fraglist_init);
643
644void ip6_fraglist_prepare(struct sk_buff *skb,
645 struct ip6_fraglist_iter *iter)
646{
647 struct sk_buff *frag = iter->frag;
648 unsigned int hlen = iter->hlen;
649 struct frag_hdr *fh;
650
651 frag->ip_summed = CHECKSUM_NONE;
652 skb_reset_transport_header(frag);
653 fh = __skb_push(frag, sizeof(struct frag_hdr));
654 __skb_push(frag, hlen);
655 skb_reset_network_header(frag);
656 memcpy(skb_network_header(frag), iter->tmp_hdr, hlen);
657 iter->offset += skb->len - hlen - sizeof(struct frag_hdr);
658 fh->nexthdr = iter->nexthdr;
659 fh->reserved = 0;
660 fh->frag_off = htons(iter->offset);
661 if (frag->next)
662 fh->frag_off |= htons(IP6_MF);
663 fh->identification = iter->frag_id;
664 ipv6_hdr(frag)->payload_len = htons(frag->len - sizeof(struct ipv6hdr));
665 ip6_copy_metadata(frag, skb);
666}
667EXPORT_SYMBOL(ip6_fraglist_prepare);
668
669void ip6_frag_init(struct sk_buff *skb, unsigned int hlen, unsigned int mtu,
670 unsigned short needed_tailroom, int hdr_room, u8 *prevhdr,
671 u8 nexthdr, __be32 frag_id, struct ip6_frag_state *state)
672{
673 state->prevhdr = prevhdr;
674 state->nexthdr = nexthdr;
675 state->frag_id = frag_id;
676
677 state->hlen = hlen;
678 state->mtu = mtu;
679
680 state->left = skb->len - hlen; /* Space per frame */
681 state->ptr = hlen; /* Where to start from */
682
683 state->hroom = hdr_room;
684 state->troom = needed_tailroom;
685
686 state->offset = 0;
687}
688EXPORT_SYMBOL(ip6_frag_init);
689
690struct sk_buff *ip6_frag_next(struct sk_buff *skb, struct ip6_frag_state *state)
691{
692 u8 *prevhdr = state->prevhdr, *fragnexthdr_offset;
693 struct sk_buff *frag;
694 struct frag_hdr *fh;
695 unsigned int len;
696
697 len = state->left;
698 /* IF: it doesn't fit, use 'mtu' - the data space left */
699 if (len > state->mtu)
700 len = state->mtu;
701 /* IF: we are not sending up to and including the packet end
702 then align the next start on an eight byte boundary */
703 if (len < state->left)
704 len &= ~7;
705
706 /* Allocate buffer */
707 frag = alloc_skb(len + state->hlen + sizeof(struct frag_hdr) +
708 state->hroom + state->troom, GFP_ATOMIC);
709 if (!frag)
710 return ERR_PTR(-ENOMEM);
711
712 /*
713 * Set up data on packet
714 */
715
716 ip6_copy_metadata(frag, skb);
717 skb_reserve(frag, state->hroom);
718 skb_put(frag, len + state->hlen + sizeof(struct frag_hdr));
719 skb_reset_network_header(frag);
720 fh = (struct frag_hdr *)(skb_network_header(frag) + state->hlen);
721 frag->transport_header = (frag->network_header + state->hlen +
722 sizeof(struct frag_hdr));
723
724 /*
725 * Charge the memory for the fragment to any owner
726 * it might possess
727 */
728 if (skb->sk)
729 skb_set_owner_w(frag, skb->sk);
730
731 /*
732 * Copy the packet header into the new buffer.
733 */
734 skb_copy_from_linear_data(skb, skb_network_header(frag), state->hlen);
735
736 fragnexthdr_offset = skb_network_header(frag);
737 fragnexthdr_offset += prevhdr - skb_network_header(skb);
738 *fragnexthdr_offset = NEXTHDR_FRAGMENT;
739
740 /*
741 * Build fragment header.
742 */
743 fh->nexthdr = state->nexthdr;
744 fh->reserved = 0;
745 fh->identification = state->frag_id;
746
747 /*
748 * Copy a block of the IP datagram.
749 */
750 BUG_ON(skb_copy_bits(skb, state->ptr, skb_transport_header(frag),
751 len));
752 state->left -= len;
753
754 fh->frag_off = htons(state->offset);
755 if (state->left > 0)
756 fh->frag_off |= htons(IP6_MF);
757 ipv6_hdr(frag)->payload_len = htons(frag->len - sizeof(struct ipv6hdr));
758
759 state->ptr += len;
760 state->offset += len;
761
762 return frag;
763}
764EXPORT_SYMBOL(ip6_frag_next);
765
591int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
592 int (*output)(struct net *, struct sock *, struct sk_buff *))
593{
594 struct sk_buff *frag;
595 struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
596 struct ipv6_pinfo *np = skb->sk && !dev_recursion_level() ?
597 inet6_sk(skb->sk) : NULL;
766int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
767 int (*output)(struct net *, struct sock *, struct sk_buff *))
768{
769 struct sk_buff *frag;
770 struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
771 struct ipv6_pinfo *np = skb->sk && !dev_recursion_level() ?
772 inet6_sk(skb->sk) : NULL;
598 struct ipv6hdr *tmp_hdr;
599 struct frag_hdr *fh;
600 unsigned int mtu, hlen, left, len, nexthdr_offset;
601 int hroom, troom;
773 struct ip6_frag_state state;
774 unsigned int mtu, hlen, nexthdr_offset;
775 int hroom, err = 0;
602 __be32 frag_id;
776 __be32 frag_id;
603 int ptr, offset = 0, err = 0;
604 u8 *prevhdr, nexthdr = 0;
605
606 err = ip6_find_1stfragopt(skb, &prevhdr);
607 if (err < 0)
608 goto fail;
609 hlen = err;
610 nexthdr = *prevhdr;
611 nexthdr_offset = prevhdr - skb_network_header(skb);

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

642 if (skb->ip_summed == CHECKSUM_PARTIAL &&
643 (err = skb_checksum_help(skb)))
644 goto fail;
645
646 prevhdr = skb_network_header(skb) + nexthdr_offset;
647 hroom = LL_RESERVED_SPACE(rt->dst.dev);
648 if (skb_has_frag_list(skb)) {
649 unsigned int first_len = skb_pagelen(skb);
777 u8 *prevhdr, nexthdr = 0;
778
779 err = ip6_find_1stfragopt(skb, &prevhdr);
780 if (err < 0)
781 goto fail;
782 hlen = err;
783 nexthdr = *prevhdr;
784 nexthdr_offset = prevhdr - skb_network_header(skb);

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

815 if (skb->ip_summed == CHECKSUM_PARTIAL &&
816 (err = skb_checksum_help(skb)))
817 goto fail;
818
819 prevhdr = skb_network_header(skb) + nexthdr_offset;
820 hroom = LL_RESERVED_SPACE(rt->dst.dev);
821 if (skb_has_frag_list(skb)) {
822 unsigned int first_len = skb_pagelen(skb);
823 struct ip6_fraglist_iter iter;
650 struct sk_buff *frag2;
651
652 if (first_len - hlen > mtu ||
653 ((first_len - hlen) & 7) ||
654 skb_cloned(skb) ||
655 skb_headroom(skb) < (hroom + sizeof(struct frag_hdr)))
656 goto slow_path;
657

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

669 BUG_ON(frag->sk);
670 if (skb->sk) {
671 frag->sk = skb->sk;
672 frag->destructor = sock_wfree;
673 }
674 skb->truesize -= frag->truesize;
675 }
676
824 struct sk_buff *frag2;
825
826 if (first_len - hlen > mtu ||
827 ((first_len - hlen) & 7) ||
828 skb_cloned(skb) ||
829 skb_headroom(skb) < (hroom + sizeof(struct frag_hdr)))
830 goto slow_path;
831

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

843 BUG_ON(frag->sk);
844 if (skb->sk) {
845 frag->sk = skb->sk;
846 frag->destructor = sock_wfree;
847 }
848 skb->truesize -= frag->truesize;
849 }
850
677 err = 0;
678 offset = 0;
679 /* BUILD HEADER */
680
681 *prevhdr = NEXTHDR_FRAGMENT;
682 tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC);
683 if (!tmp_hdr) {
684 err = -ENOMEM;
851 err = ip6_fraglist_init(skb, hlen, prevhdr, nexthdr, frag_id,
852 &iter);
853 if (err < 0)
685 goto fail;
854 goto fail;
686 }
687 frag = skb_shinfo(skb)->frag_list;
688 skb_frag_list_init(skb);
689
855
690 __skb_pull(skb, hlen);
691 fh = __skb_push(skb, sizeof(struct frag_hdr));
692 __skb_push(skb, hlen);
693 skb_reset_network_header(skb);
694 memcpy(skb_network_header(skb), tmp_hdr, hlen);
695
696 fh->nexthdr = nexthdr;
697 fh->reserved = 0;
698 fh->frag_off = htons(IP6_MF);
699 fh->identification = frag_id;
700
701 first_len = skb_pagelen(skb);
702 skb->data_len = first_len - skb_headlen(skb);
703 skb->len = first_len;
704 ipv6_hdr(skb)->payload_len = htons(first_len -
705 sizeof(struct ipv6hdr));
706
707 for (;;) {
708 /* Prepare header of the next frame,
709 * before previous one went down. */
856 for (;;) {
857 /* Prepare header of the next frame,
858 * before previous one went down. */
710 if (frag) {
711 frag->ip_summed = CHECKSUM_NONE;
712 skb_reset_transport_header(frag);
713 fh = __skb_push(frag, sizeof(struct frag_hdr));
714 __skb_push(frag, hlen);
715 skb_reset_network_header(frag);
716 memcpy(skb_network_header(frag), tmp_hdr,
717 hlen);
718 offset += skb->len - hlen - sizeof(struct frag_hdr);
719 fh->nexthdr = nexthdr;
720 fh->reserved = 0;
721 fh->frag_off = htons(offset);
722 if (frag->next)
723 fh->frag_off |= htons(IP6_MF);
724 fh->identification = frag_id;
725 ipv6_hdr(frag)->payload_len =
726 htons(frag->len -
727 sizeof(struct ipv6hdr));
728 ip6_copy_metadata(frag, skb);
729 }
859 if (iter.frag)
860 ip6_fraglist_prepare(skb, &iter);
730
731 err = output(net, sk, skb);
732 if (!err)
733 IP6_INC_STATS(net, ip6_dst_idev(&rt->dst),
734 IPSTATS_MIB_FRAGCREATES);
735
861
862 err = output(net, sk, skb);
863 if (!err)
864 IP6_INC_STATS(net, ip6_dst_idev(&rt->dst),
865 IPSTATS_MIB_FRAGCREATES);
866
736 if (err || !frag)
867 if (err || !iter.frag)
737 break;
738
868 break;
869
739 skb = frag;
740 frag = skb->next;
741 skb_mark_not_on_list(skb);
870 skb = ip6_fraglist_next(&iter);
742 }
743
871 }
872
744 kfree(tmp_hdr);
873 kfree(iter.tmp_hdr);
745
746 if (err == 0) {
747 IP6_INC_STATS(net, ip6_dst_idev(&rt->dst),
748 IPSTATS_MIB_FRAGOKS);
749 return 0;
750 }
751
874
875 if (err == 0) {
876 IP6_INC_STATS(net, ip6_dst_idev(&rt->dst),
877 IPSTATS_MIB_FRAGOKS);
878 return 0;
879 }
880
752 kfree_skb_list(frag);
881 kfree_skb_list(iter.frag);
753
754 IP6_INC_STATS(net, ip6_dst_idev(&rt->dst),
755 IPSTATS_MIB_FRAGFAILS);
756 return err;
757
758slow_path_clean:
759 skb_walk_frags(skb, frag2) {
760 if (frag2 == frag)
761 break;
762 frag2->sk = NULL;
763 frag2->destructor = NULL;
764 skb->truesize += frag2->truesize;
765 }
766 }
767
768slow_path:
882
883 IP6_INC_STATS(net, ip6_dst_idev(&rt->dst),
884 IPSTATS_MIB_FRAGFAILS);
885 return err;
886
887slow_path_clean:
888 skb_walk_frags(skb, frag2) {
889 if (frag2 == frag)
890 break;
891 frag2->sk = NULL;
892 frag2->destructor = NULL;
893 skb->truesize += frag2->truesize;
894 }
895 }
896
897slow_path:
769 left = skb->len - hlen; /* Space per frame */
770 ptr = hlen; /* Where to start from */
771
772 /*
773 * Fragment the datagram.
774 */
775
898 /*
899 * Fragment the datagram.
900 */
901
776 troom = rt->dst.dev->needed_tailroom;
902 ip6_frag_init(skb, hlen, mtu, rt->dst.dev->needed_tailroom,
903 LL_RESERVED_SPACE(rt->dst.dev), prevhdr, nexthdr, frag_id,
904 &state);
777
778 /*
779 * Keep copying data until we run out.
780 */
905
906 /*
907 * Keep copying data until we run out.
908 */
781 while (left > 0) {
782 u8 *fragnexthdr_offset;
783
909
784 len = left;
785 /* IF: it doesn't fit, use 'mtu' - the data space left */
786 if (len > mtu)
787 len = mtu;
788 /* IF: we are not sending up to and including the packet end
789 then align the next start on an eight byte boundary */
790 if (len < left) {
791 len &= ~7;
792 }
793
794 /* Allocate buffer */
795 frag = alloc_skb(len + hlen + sizeof(struct frag_hdr) +
796 hroom + troom, GFP_ATOMIC);
797 if (!frag) {
798 err = -ENOMEM;
910 while (state.left > 0) {
911 frag = ip6_frag_next(skb, &state);
912 if (IS_ERR(frag)) {
913 err = PTR_ERR(frag);
799 goto fail;
800 }
801
802 /*
914 goto fail;
915 }
916
917 /*
803 * Set up data on packet
804 */
805
806 ip6_copy_metadata(frag, skb);
807 skb_reserve(frag, hroom);
808 skb_put(frag, len + hlen + sizeof(struct frag_hdr));
809 skb_reset_network_header(frag);
810 fh = (struct frag_hdr *)(skb_network_header(frag) + hlen);
811 frag->transport_header = (frag->network_header + hlen +
812 sizeof(struct frag_hdr));
813
814 /*
815 * Charge the memory for the fragment to any owner
816 * it might possess
817 */
818 if (skb->sk)
819 skb_set_owner_w(frag, skb->sk);
820
821 /*
822 * Copy the packet header into the new buffer.
823 */
824 skb_copy_from_linear_data(skb, skb_network_header(frag), hlen);
825
826 fragnexthdr_offset = skb_network_header(frag);
827 fragnexthdr_offset += prevhdr - skb_network_header(skb);
828 *fragnexthdr_offset = NEXTHDR_FRAGMENT;
829
830 /*
831 * Build fragment header.
832 */
833 fh->nexthdr = nexthdr;
834 fh->reserved = 0;
835 fh->identification = frag_id;
836
837 /*
838 * Copy a block of the IP datagram.
839 */
840 BUG_ON(skb_copy_bits(skb, ptr, skb_transport_header(frag),
841 len));
842 left -= len;
843
844 fh->frag_off = htons(offset);
845 if (left > 0)
846 fh->frag_off |= htons(IP6_MF);
847 ipv6_hdr(frag)->payload_len = htons(frag->len -
848 sizeof(struct ipv6hdr));
849
850 ptr += len;
851 offset += len;
852
853 /*
854 * Put this fragment into the sending queue.
855 */
856 err = output(net, sk, frag);
857 if (err)
858 goto fail;
859
860 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
861 IPSTATS_MIB_FRAGCREATES);

--- 959 unchanged lines hidden ---
918 * Put this fragment into the sending queue.
919 */
920 err = output(net, sk, frag);
921 if (err)
922 goto fail;
923
924 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
925 IPSTATS_MIB_FRAGCREATES);

--- 959 unchanged lines hidden ---