aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/dn_route.h10
-rw-r--r--include/net/route.h10
-rw-r--r--net/decnet/dn_route.c4
-rw-r--r--net/ipv4/icmp.c4
-rw-r--r--net/ipv4/igmp.c2
-rw-r--r--net/ipv4/ip_gre.c2
-rw-r--r--net/ipv4/ipmr.c2
-rw-r--r--net/ipv4/route.c20
-rw-r--r--net/netfilter/ipvs/ip_vs_xmit.c8
9 files changed, 42 insertions, 20 deletions
diff --git a/include/net/dn_route.h b/include/net/dn_route.h
index ccadab3aa3f6..9b185df265fb 100644
--- a/include/net/dn_route.h
+++ b/include/net/dn_route.h
@@ -80,6 +80,16 @@ struct dn_route {
80 unsigned rt_type; 80 unsigned rt_type;
81}; 81};
82 82
83static inline bool dn_is_input_route(struct dn_route *rt)
84{
85 return rt->fl.iif != 0;
86}
87
88static inline bool dn_is_output_route(struct dn_route *rt)
89{
90 return rt->fl.iif == 0;
91}
92
83extern void dn_route_init(void); 93extern void dn_route_init(void);
84extern void dn_route_cleanup(void); 94extern void dn_route_cleanup(void);
85 95
diff --git a/include/net/route.h b/include/net/route.h
index cea533eaa853..5cd46d1c0e14 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -71,6 +71,16 @@ struct rtable {
71 struct inet_peer *peer; /* long-living peer info */ 71 struct inet_peer *peer; /* long-living peer info */
72}; 72};
73 73
74static inline bool rt_is_input_route(struct rtable *rt)
75{
76 return rt->fl.iif != 0;
77}
78
79static inline bool rt_is_output_route(struct rtable *rt)
80{
81 return rt->fl.iif == 0;
82}
83
74struct ip_rt_acct { 84struct ip_rt_acct {
75 __u32 o_bytes; 85 __u32 o_bytes;
76 __u32 o_packets; 86 __u32 o_packets;
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index 94a9eb1d313e..474d54dd08c2 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -1181,7 +1181,7 @@ static int __dn_route_output_key(struct dst_entry **pprt, const struct flowi *fl
1181 if ((flp->fld_dst == rt->fl.fld_dst) && 1181 if ((flp->fld_dst == rt->fl.fld_dst) &&
1182 (flp->fld_src == rt->fl.fld_src) && 1182 (flp->fld_src == rt->fl.fld_src) &&
1183 (flp->mark == rt->fl.mark) && 1183 (flp->mark == rt->fl.mark) &&
1184 (rt->fl.iif == 0) && 1184 dn_is_output_route(rt) &&
1185 (rt->fl.oif == flp->oif)) { 1185 (rt->fl.oif == flp->oif)) {
1186 dst_use(&rt->dst, jiffies); 1186 dst_use(&rt->dst, jiffies);
1187 rcu_read_unlock_bh(); 1187 rcu_read_unlock_bh();
@@ -1512,7 +1512,7 @@ static int dn_rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
1512 if (rtnl_put_cacheinfo(skb, &rt->dst, 0, 0, 0, expires, 1512 if (rtnl_put_cacheinfo(skb, &rt->dst, 0, 0, 0, expires,
1513 rt->dst.error) < 0) 1513 rt->dst.error) < 0)
1514 goto rtattr_failure; 1514 goto rtattr_failure;
1515 if (rt->fl.iif) 1515 if (dn_is_input_route(rt))
1516 RTA_PUT(skb, RTA_IIF, sizeof(int), &rt->fl.iif); 1516 RTA_PUT(skb, RTA_IIF, sizeof(int), &rt->fl.iif);
1517 1517
1518 nlh->nlmsg_len = skb_tail_pointer(skb) - b; 1518 nlh->nlmsg_len = skb_tail_pointer(skb) - b;
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 96bc7f9475a3..c6e2affafbd3 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -506,8 +506,8 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
506 struct net_device *dev = NULL; 506 struct net_device *dev = NULL;
507 507
508 rcu_read_lock(); 508 rcu_read_lock();
509 if (rt->fl.iif && 509 if (rt_is_input_route(rt) &&
510 net->ipv4.sysctl_icmp_errors_use_inbound_ifaddr) 510 net->ipv4.sysctl_icmp_errors_use_inbound_ifaddr)
511 dev = dev_get_by_index_rcu(net, rt->fl.iif); 511 dev = dev_get_by_index_rcu(net, rt->fl.iif);
512 512
513 if (dev) 513 if (dev)
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index c8877c6c7216..08d0d81ffc15 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -961,7 +961,7 @@ int igmp_rcv(struct sk_buff *skb)
961 case IGMP_HOST_MEMBERSHIP_REPORT: 961 case IGMP_HOST_MEMBERSHIP_REPORT:
962 case IGMPV2_HOST_MEMBERSHIP_REPORT: 962 case IGMPV2_HOST_MEMBERSHIP_REPORT:
963 /* Is it our report looped back? */ 963 /* Is it our report looped back? */
964 if (skb_rtable(skb)->fl.iif == 0) 964 if (rt_is_output_route(skb_rtable(skb)))
965 break; 965 break;
966 /* don't rely on MC router hearing unicast reports */ 966 /* don't rely on MC router hearing unicast reports */
967 if (skb->pkt_type == PACKET_MULTICAST || 967 if (skb->pkt_type == PACKET_MULTICAST ||
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 70ff77f02eee..cab2057d5430 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -634,7 +634,7 @@ static int ipgre_rcv(struct sk_buff *skb)
634#ifdef CONFIG_NET_IPGRE_BROADCAST 634#ifdef CONFIG_NET_IPGRE_BROADCAST
635 if (ipv4_is_multicast(iph->daddr)) { 635 if (ipv4_is_multicast(iph->daddr)) {
636 /* Looped back packet, drop it! */ 636 /* Looped back packet, drop it! */
637 if (skb_rtable(skb)->fl.iif == 0) 637 if (rt_is_output_route(skb_rtable(skb)))
638 goto drop; 638 goto drop;
639 tunnel->dev->stats.multicast++; 639 tunnel->dev->stats.multicast++;
640 skb->pkt_type = PACKET_BROADCAST; 640 skb->pkt_type = PACKET_BROADCAST;
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 86dd5691af46..ef2b0089e0ea 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -1654,7 +1654,7 @@ static int ip_mr_forward(struct net *net, struct mr_table *mrt,
1654 if (mrt->vif_table[vif].dev != skb->dev) { 1654 if (mrt->vif_table[vif].dev != skb->dev) {
1655 int true_vifi; 1655 int true_vifi;
1656 1656
1657 if (skb_rtable(skb)->fl.iif == 0) { 1657 if (rt_is_output_route(skb_rtable(skb))) {
1658 /* It is our own packet, looped back. 1658 /* It is our own packet, looped back.
1659 * Very complicated situation... 1659 * Very complicated situation...
1660 * 1660 *
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 5955965c7953..66610ea3c87b 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -623,7 +623,7 @@ static inline int rt_fast_clean(struct rtable *rth)
623 /* Kill broadcast/multicast entries very aggresively, if they 623 /* Kill broadcast/multicast entries very aggresively, if they
624 collide in hash table with more useful entries */ 624 collide in hash table with more useful entries */
625 return (rth->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) && 625 return (rth->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) &&
626 rth->fl.iif && rth->dst.rt_next; 626 rt_is_input_route(rth) && rth->dst.rt_next;
627} 627}
628 628
629static inline int rt_valuable(struct rtable *rth) 629static inline int rt_valuable(struct rtable *rth)
@@ -668,7 +668,7 @@ static inline u32 rt_score(struct rtable *rt)
668 if (rt_valuable(rt)) 668 if (rt_valuable(rt))
669 score |= (1<<31); 669 score |= (1<<31);
670 670
671 if (!rt->fl.iif || 671 if (rt_is_output_route(rt) ||
672 !(rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL))) 672 !(rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST|RTCF_LOCAL)))
673 score |= (1<<30); 673 score |= (1<<30);
674 674
@@ -1126,7 +1126,7 @@ restart:
1126 */ 1126 */
1127 1127
1128 rt->dst.flags |= DST_NOCACHE; 1128 rt->dst.flags |= DST_NOCACHE;
1129 if (rt->rt_type == RTN_UNICAST || rt->fl.iif == 0) { 1129 if (rt->rt_type == RTN_UNICAST || rt_is_output_route(rt)) {
1130 int err = arp_bind_neighbour(&rt->dst); 1130 int err = arp_bind_neighbour(&rt->dst);
1131 if (err) { 1131 if (err) {
1132 if (net_ratelimit()) 1132 if (net_ratelimit())
@@ -1224,7 +1224,7 @@ restart:
1224 /* Try to bind route to arp only if it is output 1224 /* Try to bind route to arp only if it is output
1225 route or unicast forwarding path. 1225 route or unicast forwarding path.
1226 */ 1226 */
1227 if (rt->rt_type == RTN_UNICAST || rt->fl.iif == 0) { 1227 if (rt->rt_type == RTN_UNICAST || rt_is_output_route(rt)) {
1228 int err = arp_bind_neighbour(&rt->dst); 1228 int err = arp_bind_neighbour(&rt->dst);
1229 if (err) { 1229 if (err) {
1230 spin_unlock_bh(rt_hash_lock_addr(hash)); 1230 spin_unlock_bh(rt_hash_lock_addr(hash));
@@ -1406,7 +1406,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
1406 if (rth->fl.fl4_dst != daddr || 1406 if (rth->fl.fl4_dst != daddr ||
1407 rth->fl.fl4_src != skeys[i] || 1407 rth->fl.fl4_src != skeys[i] ||
1408 rth->fl.oif != ikeys[k] || 1408 rth->fl.oif != ikeys[k] ||
1409 rth->fl.iif != 0 || 1409 rt_is_input_route(rth) ||
1410 rt_is_expired(rth) || 1410 rt_is_expired(rth) ||
1411 !net_eq(dev_net(rth->dst.dev), net)) { 1411 !net_eq(dev_net(rth->dst.dev), net)) {
1412 rthp = &rth->dst.rt_next; 1412 rthp = &rth->dst.rt_next;
@@ -1666,7 +1666,7 @@ unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph,
1666 rth->rt_dst != daddr || 1666 rth->rt_dst != daddr ||
1667 rth->rt_src != iph->saddr || 1667 rth->rt_src != iph->saddr ||
1668 rth->fl.oif != ikeys[k] || 1668 rth->fl.oif != ikeys[k] ||
1669 rth->fl.iif != 0 || 1669 rt_is_input_route(rth) ||
1670 dst_metric_locked(&rth->dst, RTAX_MTU) || 1670 dst_metric_locked(&rth->dst, RTAX_MTU) ||
1671 !net_eq(dev_net(rth->dst.dev), net) || 1671 !net_eq(dev_net(rth->dst.dev), net) ||
1672 rt_is_expired(rth)) 1672 rt_is_expired(rth))
@@ -1770,7 +1770,7 @@ void ip_rt_get_source(u8 *addr, struct rtable *rt)
1770 __be32 src; 1770 __be32 src;
1771 struct fib_result res; 1771 struct fib_result res;
1772 1772
1773 if (rt->fl.iif == 0) 1773 if (rt_is_output_route(rt))
1774 src = rt->rt_src; 1774 src = rt->rt_src;
1775 else { 1775 else {
1776 rcu_read_lock(); 1776 rcu_read_lock();
@@ -2669,7 +2669,7 @@ int __ip_route_output_key(struct net *net, struct rtable **rp,
2669 rth = rcu_dereference_bh(rth->dst.rt_next)) { 2669 rth = rcu_dereference_bh(rth->dst.rt_next)) {
2670 if (rth->fl.fl4_dst == flp->fl4_dst && 2670 if (rth->fl.fl4_dst == flp->fl4_dst &&
2671 rth->fl.fl4_src == flp->fl4_src && 2671 rth->fl.fl4_src == flp->fl4_src &&
2672 rth->fl.iif == 0 && 2672 rt_is_output_route(rth) &&
2673 rth->fl.oif == flp->oif && 2673 rth->fl.oif == flp->oif &&
2674 rth->fl.mark == flp->mark && 2674 rth->fl.mark == flp->mark &&
2675 !((rth->fl.fl4_tos ^ flp->fl4_tos) & 2675 !((rth->fl.fl4_tos ^ flp->fl4_tos) &
@@ -2824,7 +2824,7 @@ static int rt_fill_info(struct net *net,
2824 if (rt->dst.tclassid) 2824 if (rt->dst.tclassid)
2825 NLA_PUT_U32(skb, RTA_FLOW, rt->dst.tclassid); 2825 NLA_PUT_U32(skb, RTA_FLOW, rt->dst.tclassid);
2826#endif 2826#endif
2827 if (rt->fl.iif) 2827 if (rt_is_input_route(rt))
2828 NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_spec_dst); 2828 NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_spec_dst);
2829 else if (rt->rt_src != rt->fl.fl4_src) 2829 else if (rt->rt_src != rt->fl.fl4_src)
2830 NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_src); 2830 NLA_PUT_BE32(skb, RTA_PREFSRC, rt->rt_src);
@@ -2849,7 +2849,7 @@ static int rt_fill_info(struct net *net,
2849 } 2849 }
2850 } 2850 }
2851 2851
2852 if (rt->fl.iif) { 2852 if (rt_is_input_route(rt)) {
2853#ifdef CONFIG_IP_MROUTE 2853#ifdef CONFIG_IP_MROUTE
2854 __be32 dst = rt->rt_dst; 2854 __be32 dst = rt->rt_dst;
2855 2855
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index de04ea39cde8..10bd39c0ae2d 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -169,7 +169,7 @@ __ip_vs_reroute_locally(struct sk_buff *skb)
169 struct net *net = dev_net(dev); 169 struct net *net = dev_net(dev);
170 struct iphdr *iph = ip_hdr(skb); 170 struct iphdr *iph = ip_hdr(skb);
171 171
172 if (rt->fl.iif) { 172 if (rt_is_input_route(rt)) {
173 unsigned long orefdst = skb->_skb_refdst; 173 unsigned long orefdst = skb->_skb_refdst;
174 174
175 if (ip_route_input(skb, iph->daddr, iph->saddr, 175 if (ip_route_input(skb, iph->daddr, iph->saddr,
@@ -552,7 +552,8 @@ ip_vs_nat_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
552#endif 552#endif
553 553
554 /* From world but DNAT to loopback address? */ 554 /* From world but DNAT to loopback address? */
555 if (local && ipv4_is_loopback(rt->rt_dst) && skb_rtable(skb)->fl.iif) { 555 if (local && ipv4_is_loopback(rt->rt_dst) &&
556 rt_is_input_route(skb_rtable(skb))) {
556 IP_VS_DBG_RL_PKT(1, AF_INET, pp, skb, 0, "ip_vs_nat_xmit(): " 557 IP_VS_DBG_RL_PKT(1, AF_INET, pp, skb, 0, "ip_vs_nat_xmit(): "
557 "stopping DNAT to loopback address"); 558 "stopping DNAT to loopback address");
558 goto tx_error_put; 559 goto tx_error_put;
@@ -1165,7 +1166,8 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
1165#endif 1166#endif
1166 1167
1167 /* From world but DNAT to loopback address? */ 1168 /* From world but DNAT to loopback address? */
1168 if (local && ipv4_is_loopback(rt->rt_dst) && skb_rtable(skb)->fl.iif) { 1169 if (local && ipv4_is_loopback(rt->rt_dst) &&
1170 rt_is_input_route(skb_rtable(skb))) {
1169 IP_VS_DBG(1, "%s(): " 1171 IP_VS_DBG(1, "%s(): "
1170 "stopping DNAT to loopback %pI4\n", 1172 "stopping DNAT to loopback %pI4\n",
1171 __func__, &cp->daddr.ip); 1173 __func__, &cp->daddr.ip);