^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * INET An implementation of the TCP/IP protocol suite for the LINUX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * operating system. INET is implemented using the BSD Socket
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * interface as the means of communication with the user level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * The IP forwarding functionality.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Authors: see ip.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Fixes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Many : Split from ip.c , see ip_input.c for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * history.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Dave Gregorich : NULL ip_rt_put fix for multicast
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * routing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * Jos Vos : Add call_out_firewall before sending,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * use output device for accounting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Jos Vos : Call forward firewall after routing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * (always use output device).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * Mike McLagan : Routing by source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/ip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/icmp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <net/sock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <net/ip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <net/tcp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <net/udp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <net/icmp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/tcp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/udp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/netfilter_ipv4.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <net/checksum.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/route.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <net/route.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <net/xfrm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static bool ip_exceeds_mtu(const struct sk_buff *skb, unsigned int mtu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) if (skb->len <= mtu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) if (unlikely((ip_hdr(skb)->frag_off & htons(IP_DF)) == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* original fragment exceeds mtu and DF is set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (unlikely(IPCB(skb)->frag_max_size > mtu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (skb->ignore_df)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) if (skb_is_gso(skb) && skb_gso_validate_network_len(skb, mtu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) static int ip_forward_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct ip_options *opt = &(IPCB(skb)->opt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) __IP_INC_STATS(net, IPSTATS_MIB_OUTFORWDATAGRAMS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) __IP_ADD_STATS(net, IPSTATS_MIB_OUTOCTETS, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #ifdef CONFIG_NET_SWITCHDEV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (skb->offload_l3_fwd_mark) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) consume_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (unlikely(opt->optlen))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) ip_forward_options(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) skb->tstamp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return dst_output(net, sk, skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) int ip_forward(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) u32 mtu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct iphdr *iph; /* Our header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct rtable *rt; /* Route we use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) struct ip_options *opt = &(IPCB(skb)->opt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct net *net;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /* that should never happen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (skb->pkt_type != PACKET_HOST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) if (unlikely(skb->sk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (skb_warn_if_lro(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (!xfrm4_policy_check(NULL, XFRM_POLICY_FWD, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (IPCB(skb)->opt.router_alert && ip_call_ra_chain(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return NET_RX_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) skb_forward_csum(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) net = dev_net(skb->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * According to the RFC, we must first decrease the TTL field. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * that reaches zero, we must reply an ICMP control message telling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * that the packet's lifetime expired.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (ip_hdr(skb)->ttl <= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) goto too_many_hops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (!xfrm4_route_forward(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) rt = skb_rtable(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (opt->is_strictroute && rt->rt_uses_gateway)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) goto sr_failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) IPCB(skb)->flags |= IPSKB_FORWARDED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) mtu = ip_dst_mtu_maybe_forward(&rt->dst, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (ip_exceeds_mtu(skb, mtu)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) IP_INC_STATS(net, IPSTATS_MIB_FRAGFAILS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) htonl(mtu));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) /* We are about to mangle packet. Copy it! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (skb_cow(skb, LL_RESERVED_SPACE(rt->dst.dev)+rt->dst.header_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) iph = ip_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) /* Decrease ttl after skb cow done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) ip_decrease_ttl(iph);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * We now generate an ICMP HOST REDIRECT giving the route
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * we calculated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) if (IPCB(skb)->flags & IPSKB_DOREDIRECT && !opt->srr &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) !skb_sec_path(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) ip_rt_send_redirect(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (net->ipv4.sysctl_ip_fwd_update_priority)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) skb->priority = rt_tos2priority(iph->tos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return NF_HOOK(NFPROTO_IPV4, NF_INET_FORWARD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) net, NULL, skb, skb->dev, rt->dst.dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) ip_forward_finish);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) sr_failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) * Strict routing permits no gatewaying
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) icmp_send(skb, ICMP_DEST_UNREACH, ICMP_SR_FAILED, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) too_many_hops:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) /* Tell the sender its packet died... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) __IP_INC_STATS(net, IPSTATS_MIB_INHDRERRORS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) icmp_send(skb, ICMP_TIME_EXCEEDED, ICMP_EXC_TTL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) drop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) return NET_RX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }