diff options
author | David S. Miller <davem@davemloft.net> | 2011-03-09 17:06:20 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-03-09 17:06:20 -0500 |
commit | ee3f1aaf930b7cfbf3d34eff1e5e076393227e90 (patch) | |
tree | 814621b53a1a26f00acd05e83f4b7be297abd607 /net/ipv4 | |
parent | bd33acc3cc525972ac779067e98efb26516c5b94 (diff) |
ipv4: Lookup multicast routes by rtable using helper.
Create a common helper for this operation, since we do
it identically in three spots.
Suggested by Eric Dumazet.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/ipmr.c | 70 |
1 files changed, 28 insertions, 42 deletions
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 9d5f6340af13..74909bac8817 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -1793,6 +1793,24 @@ dont_forward: | |||
1793 | return 0; | 1793 | return 0; |
1794 | } | 1794 | } |
1795 | 1795 | ||
1796 | static struct mr_table *ipmr_rt_fib_lookup(struct net *net, struct rtable *rt) | ||
1797 | { | ||
1798 | struct flowi fl = { | ||
1799 | .fl4_dst = rt->rt_key_dst, | ||
1800 | .fl4_src = rt->rt_key_src, | ||
1801 | .fl4_tos = rt->rt_tos, | ||
1802 | .oif = rt->rt_oif, | ||
1803 | .iif = rt->rt_iif, | ||
1804 | .mark = rt->rt_mark, | ||
1805 | }; | ||
1806 | struct mr_table *mrt; | ||
1807 | int err; | ||
1808 | |||
1809 | err = ipmr_fib_lookup(net, &fl, &mrt); | ||
1810 | if (err) | ||
1811 | return ERR_PTR(err); | ||
1812 | return mrt; | ||
1813 | } | ||
1796 | 1814 | ||
1797 | /* | 1815 | /* |
1798 | * Multicast packets for forwarding arrive here | 1816 | * Multicast packets for forwarding arrive here |
@@ -1805,7 +1823,6 @@ int ip_mr_input(struct sk_buff *skb) | |||
1805 | struct net *net = dev_net(skb->dev); | 1823 | struct net *net = dev_net(skb->dev); |
1806 | int local = skb_rtable(skb)->rt_flags & RTCF_LOCAL; | 1824 | int local = skb_rtable(skb)->rt_flags & RTCF_LOCAL; |
1807 | struct mr_table *mrt; | 1825 | struct mr_table *mrt; |
1808 | int err; | ||
1809 | 1826 | ||
1810 | /* Packet is looped back after forward, it should not be | 1827 | /* Packet is looped back after forward, it should not be |
1811 | * forwarded second time, but still can be delivered locally. | 1828 | * forwarded second time, but still can be delivered locally. |
@@ -1813,21 +1830,10 @@ int ip_mr_input(struct sk_buff *skb) | |||
1813 | if (IPCB(skb)->flags & IPSKB_FORWARDED) | 1830 | if (IPCB(skb)->flags & IPSKB_FORWARDED) |
1814 | goto dont_forward; | 1831 | goto dont_forward; |
1815 | 1832 | ||
1816 | { | 1833 | mrt = ipmr_rt_fib_lookup(net, skb_rtable(skb)); |
1817 | struct rtable *rt = skb_rtable(skb); | 1834 | if (IS_ERR(mrt)) { |
1818 | struct flowi fl = { | 1835 | kfree_skb(skb); |
1819 | .fl4_dst = rt->rt_key_dst, | 1836 | return PTR_ERR(mrt); |
1820 | .fl4_src = rt->rt_key_src, | ||
1821 | .fl4_tos = rt->rt_tos, | ||
1822 | .oif = rt->rt_oif, | ||
1823 | .iif = rt->rt_iif, | ||
1824 | .mark = rt->rt_mark, | ||
1825 | }; | ||
1826 | err = ipmr_fib_lookup(net, &fl, &mrt); | ||
1827 | if (err < 0) { | ||
1828 | kfree_skb(skb); | ||
1829 | return err; | ||
1830 | } | ||
1831 | } | 1837 | } |
1832 | if (!local) { | 1838 | if (!local) { |
1833 | if (IPCB(skb)->opt.router_alert) { | 1839 | if (IPCB(skb)->opt.router_alert) { |
@@ -1956,19 +1962,9 @@ int pim_rcv_v1(struct sk_buff *skb) | |||
1956 | 1962 | ||
1957 | pim = igmp_hdr(skb); | 1963 | pim = igmp_hdr(skb); |
1958 | 1964 | ||
1959 | { | 1965 | mrt = ipmr_rt_fib_lookup(net, skb_rtable(skb)); |
1960 | struct rtable *rt = skb_rtable(skb); | 1966 | if (IS_ERR(mrt)) |
1961 | struct flowi fl = { | 1967 | goto drop; |
1962 | .fl4_dst = rt->rt_key_dst, | ||
1963 | .fl4_src = rt->rt_key_src, | ||
1964 | .fl4_tos = rt->rt_tos, | ||
1965 | .oif = rt->rt_oif, | ||
1966 | .iif = rt->rt_iif, | ||
1967 | .mark = rt->rt_mark, | ||
1968 | }; | ||
1969 | if (ipmr_fib_lookup(net, &fl, &mrt) < 0) | ||
1970 | goto drop; | ||
1971 | } | ||
1972 | if (!mrt->mroute_do_pim || | 1968 | if (!mrt->mroute_do_pim || |
1973 | pim->group != PIM_V1_VERSION || pim->code != PIM_V1_REGISTER) | 1969 | pim->group != PIM_V1_VERSION || pim->code != PIM_V1_REGISTER) |
1974 | goto drop; | 1970 | goto drop; |
@@ -1998,19 +1994,9 @@ static int pim_rcv(struct sk_buff *skb) | |||
1998 | csum_fold(skb_checksum(skb, 0, skb->len, 0)))) | 1994 | csum_fold(skb_checksum(skb, 0, skb->len, 0)))) |
1999 | goto drop; | 1995 | goto drop; |
2000 | 1996 | ||
2001 | { | 1997 | mrt = ipmr_rt_fib_lookup(net, skb_rtable(skb)); |
2002 | struct rtable *rt = skb_rtable(skb); | 1998 | if (IS_ERR(mrt)) |
2003 | struct flowi fl = { | 1999 | goto drop; |
2004 | .fl4_dst = rt->rt_key_dst, | ||
2005 | .fl4_src = rt->rt_key_src, | ||
2006 | .fl4_tos = rt->rt_tos, | ||
2007 | .oif = rt->rt_oif, | ||
2008 | .iif = rt->rt_iif, | ||
2009 | .mark = rt->rt_mark, | ||
2010 | }; | ||
2011 | if (ipmr_fib_lookup(net, &fl, &mrt) < 0) | ||
2012 | goto drop; | ||
2013 | } | ||
2014 | if (__pim_rcv(mrt, skb, sizeof(*pim))) { | 2000 | if (__pim_rcv(mrt, skb, sizeof(*pim))) { |
2015 | drop: | 2001 | drop: |
2016 | kfree_skb(skb); | 2002 | kfree_skb(skb); |