Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net: ipv4: ipmr: Split ipmr_queue_xmit() in two

Some of the work of ipmr_queue_xmit() is specific to IPMR forwarding, and
should not take place on the output path. In order to allow reuse of the
common parts, split the function into two: the ipmr_prepare_xmit() helper
that takes care of the common bits, and the ipmr_queue_fwd_xmit(), which
invokes the former and encapsulates the whole forwarding algorithm.

Signed-off-by: Petr Machata <petrm@nvidia.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Link: https://patch.msgid.link/4e8db165572a4f8bd29a723a801e854e9d20df4d.1750113335.git.petrm@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Petr Machata and committed by
Jakub Kicinski
b2e653bc 3b7bc938

+29 -16
+29 -16
net/ipv4/ipmr.c
··· 1853 1853 1854 1854 /* Processing handlers for ipmr_forward, under rcu_read_lock() */ 1855 1855 1856 - static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt, 1857 - int in_vifi, struct sk_buff *skb, int vifi) 1856 + static int ipmr_prepare_xmit(struct net *net, struct mr_table *mrt, 1857 + struct sk_buff *skb, int vifi) 1858 1858 { 1859 1859 const struct iphdr *iph = ip_hdr(skb); 1860 1860 struct vif_device *vif = &mrt->vif_table[vifi]; ··· 1865 1865 1866 1866 vif_dev = vif_dev_read(vif); 1867 1867 if (!vif_dev) 1868 - goto out_free; 1868 + return -1; 1869 1869 1870 1870 if (vif->flags & VIFF_REGISTER) { 1871 1871 WRITE_ONCE(vif->pkt_out, vif->pkt_out + 1); ··· 1873 1873 DEV_STATS_ADD(vif_dev, tx_bytes, skb->len); 1874 1874 DEV_STATS_INC(vif_dev, tx_packets); 1875 1875 ipmr_cache_report(mrt, skb, vifi, IGMPMSG_WHOLEPKT); 1876 - goto out_free; 1876 + return -1; 1877 1877 } 1878 - 1879 - if (ipmr_forward_offloaded(skb, mrt, in_vifi, vifi)) 1880 - goto out_free; 1881 1878 1882 1879 if (vif->flags & VIFF_TUNNEL) { 1883 1880 rt = ip_route_output_ports(net, &fl4, NULL, ··· 1883 1886 IPPROTO_IPIP, 1884 1887 iph->tos & INET_DSCP_MASK, vif->link); 1885 1888 if (IS_ERR(rt)) 1886 - goto out_free; 1889 + return -1; 1887 1890 encap = sizeof(struct iphdr); 1888 1891 } else { 1889 1892 rt = ip_route_output_ports(net, &fl4, NULL, iph->daddr, 0, ··· 1891 1894 IPPROTO_IPIP, 1892 1895 iph->tos & INET_DSCP_MASK, vif->link); 1893 1896 if (IS_ERR(rt)) 1894 - goto out_free; 1897 + return -1; 1895 1898 } 1896 1899 1897 1900 if (skb->len+encap > dst_mtu(&rt->dst) && (ntohs(iph->frag_off) & IP_DF)) { ··· 1901 1904 */ 1902 1905 IP_INC_STATS(net, IPSTATS_MIB_FRAGFAILS); 1903 1906 ip_rt_put(rt); 1904 - goto out_free; 1907 + return -1; 1905 1908 } 1906 1909 1907 1910 encap += LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len; 1908 1911 1909 1912 if (skb_cow(skb, encap)) { 1910 1913 ip_rt_put(rt); 1911 - goto out_free; 1914 + return -1; 1912 1915 } 1913 1916 1914 1917 WRITE_ONCE(vif->pkt_out, vif->pkt_out + 1); ··· 1927 1930 DEV_STATS_INC(vif_dev, tx_packets); 1928 1931 DEV_STATS_ADD(vif_dev, tx_bytes, skb->len); 1929 1932 } 1933 + 1934 + return 0; 1935 + } 1936 + 1937 + static void ipmr_queue_fwd_xmit(struct net *net, struct mr_table *mrt, 1938 + int in_vifi, struct sk_buff *skb, int vifi) 1939 + { 1940 + struct rtable *rt; 1941 + 1942 + if (ipmr_forward_offloaded(skb, mrt, in_vifi, vifi)) 1943 + goto out_free; 1944 + 1945 + if (ipmr_prepare_xmit(net, mrt, skb, vifi)) 1946 + goto out_free; 1947 + 1948 + rt = skb_rtable(skb); 1930 1949 1931 1950 IPCB(skb)->flags |= IPSKB_FORWARDED; 1932 1951 ··· 2075 2062 struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); 2076 2063 2077 2064 if (skb2) 2078 - ipmr_queue_xmit(net, mrt, true_vifi, 2079 - skb2, psend); 2065 + ipmr_queue_fwd_xmit(net, mrt, true_vifi, 2066 + skb2, psend); 2080 2067 } 2081 2068 psend = ct; 2082 2069 } ··· 2087 2074 struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); 2088 2075 2089 2076 if (skb2) 2090 - ipmr_queue_xmit(net, mrt, true_vifi, skb2, 2091 - psend); 2077 + ipmr_queue_fwd_xmit(net, mrt, true_vifi, skb2, 2078 + psend); 2092 2079 } else { 2093 - ipmr_queue_xmit(net, mrt, true_vifi, skb, psend); 2080 + ipmr_queue_fwd_xmit(net, mrt, true_vifi, skb, psend); 2094 2081 return; 2095 2082 } 2096 2083 }