aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2010-10-04 16:00:18 -0400
committerDavid S. Miller <davem@davemloft.net>2010-10-05 03:47:38 -0400
commit6a31d2a97c04ffe9b161ec0177a2296366ff9249 (patch)
treee564d7b06a69927f572e629b9281682f3c5c6cee /net/ipv4
parente3d32687a624845e97f9717d9d2027b44b8c49a2 (diff)
fib: cleanups
Code style cleanups before upcoming functional changes. C99 initializer for fib_props array. Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/fib_frontend.c121
-rw-r--r--net/ipv4/fib_rules.c10
-rw-r--r--net/ipv4/fib_semantics.c257
3 files changed, 206 insertions, 182 deletions
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 4a69a957872b..b05c23b05a9f 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -225,30 +225,33 @@ EXPORT_SYMBOL(inet_addr_type);
225unsigned int inet_dev_addr_type(struct net *net, const struct net_device *dev, 225unsigned int inet_dev_addr_type(struct net *net, const struct net_device *dev,
226 __be32 addr) 226 __be32 addr)
227{ 227{
228 return __inet_dev_addr_type(net, dev, addr); 228 return __inet_dev_addr_type(net, dev, addr);
229} 229}
230EXPORT_SYMBOL(inet_dev_addr_type); 230EXPORT_SYMBOL(inet_dev_addr_type);
231 231
232/* Given (packet source, input interface) and optional (dst, oif, tos): 232/* Given (packet source, input interface) and optional (dst, oif, tos):
233 - (main) check, that source is valid i.e. not broadcast or our local 233 * - (main) check, that source is valid i.e. not broadcast or our local
234 address. 234 * address.
235 - figure out what "logical" interface this packet arrived 235 * - figure out what "logical" interface this packet arrived
236 and calculate "specific destination" address. 236 * and calculate "specific destination" address.
237 - check, that packet arrived from expected physical interface. 237 * - check, that packet arrived from expected physical interface.
238 */ 238 */
239
240int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif, 239int fib_validate_source(__be32 src, __be32 dst, u8 tos, int oif,
241 struct net_device *dev, __be32 *spec_dst, 240 struct net_device *dev, __be32 *spec_dst,
242 u32 *itag, u32 mark) 241 u32 *itag, u32 mark)
243{ 242{
244 struct in_device *in_dev; 243 struct in_device *in_dev;
245 struct flowi fl = { .nl_u = { .ip4_u = 244 struct flowi fl = {
246 { .daddr = src, 245 .nl_u = {
247 .saddr = dst, 246 .ip4_u = {
248 .tos = tos } }, 247 .daddr = src,
249 .mark = mark, 248 .saddr = dst,
250 .iif = oif }; 249 .tos = tos
251 250 }
251 },
252 .mark = mark,
253 .iif = oif
254 };
252 struct fib_result res; 255 struct fib_result res;
253 int no_addr, rpf, accept_local; 256 int no_addr, rpf, accept_local;
254 bool dev_match; 257 bool dev_match;
@@ -477,9 +480,9 @@ static int rtentry_to_fib_config(struct net *net, int cmd, struct rtentry *rt,
477} 480}
478 481
479/* 482/*
480 * Handle IP routing ioctl calls. These are used to manipulate the routing tables 483 * Handle IP routing ioctl calls.
484 * These are used to manipulate the routing tables
481 */ 485 */
482
483int ip_rt_ioctl(struct net *net, unsigned int cmd, void __user *arg) 486int ip_rt_ioctl(struct net *net, unsigned int cmd, void __user *arg)
484{ 487{
485 struct fib_config cfg; 488 struct fib_config cfg;
@@ -523,7 +526,7 @@ int ip_rt_ioctl(struct net *net, unsigned int cmd, void __user *arg)
523 return -EINVAL; 526 return -EINVAL;
524} 527}
525 528
526const struct nla_policy rtm_ipv4_policy[RTA_MAX+1] = { 529const struct nla_policy rtm_ipv4_policy[RTA_MAX + 1] = {
527 [RTA_DST] = { .type = NLA_U32 }, 530 [RTA_DST] = { .type = NLA_U32 },
528 [RTA_SRC] = { .type = NLA_U32 }, 531 [RTA_SRC] = { .type = NLA_U32 },
529 [RTA_IIF] = { .type = NLA_U32 }, 532 [RTA_IIF] = { .type = NLA_U32 },
@@ -537,7 +540,7 @@ const struct nla_policy rtm_ipv4_policy[RTA_MAX+1] = {
537}; 540};
538 541
539static int rtm_to_fib_config(struct net *net, struct sk_buff *skb, 542static int rtm_to_fib_config(struct net *net, struct sk_buff *skb,
540 struct nlmsghdr *nlh, struct fib_config *cfg) 543 struct nlmsghdr *nlh, struct fib_config *cfg)
541{ 544{
542 struct nlattr *attr; 545 struct nlattr *attr;
543 int err, remaining; 546 int err, remaining;
@@ -692,12 +695,11 @@ out:
692} 695}
693 696
694/* Prepare and feed intra-kernel routing request. 697/* Prepare and feed intra-kernel routing request.
695 Really, it should be netlink message, but :-( netlink 698 * Really, it should be netlink message, but :-( netlink
696 can be not configured, so that we feed it directly 699 * can be not configured, so that we feed it directly
697 to fib engine. It is legal, because all events occur 700 * to fib engine. It is legal, because all events occur
698 only when netlink is already locked. 701 * only when netlink is already locked.
699 */ 702 */
700
701static void fib_magic(int cmd, int type, __be32 dst, int dst_len, struct in_ifaddr *ifa) 703static void fib_magic(int cmd, int type, __be32 dst, int dst_len, struct in_ifaddr *ifa)
702{ 704{
703 struct net *net = dev_net(ifa->ifa_dev->dev); 705 struct net *net = dev_net(ifa->ifa_dev->dev);
@@ -743,9 +745,9 @@ void fib_add_ifaddr(struct in_ifaddr *ifa)
743 struct in_ifaddr *prim = ifa; 745 struct in_ifaddr *prim = ifa;
744 __be32 mask = ifa->ifa_mask; 746 __be32 mask = ifa->ifa_mask;
745 __be32 addr = ifa->ifa_local; 747 __be32 addr = ifa->ifa_local;
746 __be32 prefix = ifa->ifa_address&mask; 748 __be32 prefix = ifa->ifa_address & mask;
747 749
748 if (ifa->ifa_flags&IFA_F_SECONDARY) { 750 if (ifa->ifa_flags & IFA_F_SECONDARY) {
749 prim = inet_ifa_byprefix(in_dev, prefix, mask); 751 prim = inet_ifa_byprefix(in_dev, prefix, mask);
750 if (prim == NULL) { 752 if (prim == NULL) {
751 printk(KERN_WARNING "fib_add_ifaddr: bug: prim == NULL\n"); 753 printk(KERN_WARNING "fib_add_ifaddr: bug: prim == NULL\n");
@@ -755,22 +757,24 @@ void fib_add_ifaddr(struct in_ifaddr *ifa)
755 757
756 fib_magic(RTM_NEWROUTE, RTN_LOCAL, addr, 32, prim); 758 fib_magic(RTM_NEWROUTE, RTN_LOCAL, addr, 32, prim);
757 759
758 if (!(dev->flags&IFF_UP)) 760 if (!(dev->flags & IFF_UP))
759 return; 761 return;
760 762
761 /* Add broadcast address, if it is explicitly assigned. */ 763 /* Add broadcast address, if it is explicitly assigned. */
762 if (ifa->ifa_broadcast && ifa->ifa_broadcast != htonl(0xFFFFFFFF)) 764 if (ifa->ifa_broadcast && ifa->ifa_broadcast != htonl(0xFFFFFFFF))
763 fib_magic(RTM_NEWROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim); 765 fib_magic(RTM_NEWROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim);
764 766
765 if (!ipv4_is_zeronet(prefix) && !(ifa->ifa_flags&IFA_F_SECONDARY) && 767 if (!ipv4_is_zeronet(prefix) && !(ifa->ifa_flags & IFA_F_SECONDARY) &&
766 (prefix != addr || ifa->ifa_prefixlen < 32)) { 768 (prefix != addr || ifa->ifa_prefixlen < 32)) {
767 fib_magic(RTM_NEWROUTE, dev->flags&IFF_LOOPBACK ? RTN_LOCAL : 769 fib_magic(RTM_NEWROUTE,
768 RTN_UNICAST, prefix, ifa->ifa_prefixlen, prim); 770 dev->flags & IFF_LOOPBACK ? RTN_LOCAL : RTN_UNICAST,
771 prefix, ifa->ifa_prefixlen, prim);
769 772
770 /* Add network specific broadcasts, when it takes a sense */ 773 /* Add network specific broadcasts, when it takes a sense */
771 if (ifa->ifa_prefixlen < 31) { 774 if (ifa->ifa_prefixlen < 31) {
772 fib_magic(RTM_NEWROUTE, RTN_BROADCAST, prefix, 32, prim); 775 fib_magic(RTM_NEWROUTE, RTN_BROADCAST, prefix, 32, prim);
773 fib_magic(RTM_NEWROUTE, RTN_BROADCAST, prefix|~mask, 32, prim); 776 fib_magic(RTM_NEWROUTE, RTN_BROADCAST, prefix | ~mask,
777 32, prim);
774 } 778 }
775 } 779 }
776} 780}
@@ -781,17 +785,18 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa)
781 struct net_device *dev = in_dev->dev; 785 struct net_device *dev = in_dev->dev;
782 struct in_ifaddr *ifa1; 786 struct in_ifaddr *ifa1;
783 struct in_ifaddr *prim = ifa; 787 struct in_ifaddr *prim = ifa;
784 __be32 brd = ifa->ifa_address|~ifa->ifa_mask; 788 __be32 brd = ifa->ifa_address | ~ifa->ifa_mask;
785 __be32 any = ifa->ifa_address&ifa->ifa_mask; 789 __be32 any = ifa->ifa_address & ifa->ifa_mask;
786#define LOCAL_OK 1 790#define LOCAL_OK 1
787#define BRD_OK 2 791#define BRD_OK 2
788#define BRD0_OK 4 792#define BRD0_OK 4
789#define BRD1_OK 8 793#define BRD1_OK 8
790 unsigned ok = 0; 794 unsigned ok = 0;
791 795
792 if (!(ifa->ifa_flags&IFA_F_SECONDARY)) 796 if (!(ifa->ifa_flags & IFA_F_SECONDARY))
793 fib_magic(RTM_DELROUTE, dev->flags&IFF_LOOPBACK ? RTN_LOCAL : 797 fib_magic(RTM_DELROUTE,
794 RTN_UNICAST, any, ifa->ifa_prefixlen, prim); 798 dev->flags & IFF_LOOPBACK ? RTN_LOCAL : RTN_UNICAST,
799 any, ifa->ifa_prefixlen, prim);
795 else { 800 else {
796 prim = inet_ifa_byprefix(in_dev, any, ifa->ifa_mask); 801 prim = inet_ifa_byprefix(in_dev, any, ifa->ifa_mask);
797 if (prim == NULL) { 802 if (prim == NULL) {
@@ -801,9 +806,9 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa)
801 } 806 }
802 807
803 /* Deletion is more complicated than add. 808 /* Deletion is more complicated than add.
804 We should take care of not to delete too much :-) 809 * We should take care of not to delete too much :-)
805 810 *
806 Scan address list to be sure that addresses are really gone. 811 * Scan address list to be sure that addresses are really gone.
807 */ 812 */
808 813
809 for (ifa1 = in_dev->ifa_list; ifa1; ifa1 = ifa1->ifa_next) { 814 for (ifa1 = in_dev->ifa_list; ifa1; ifa1 = ifa1->ifa_next) {
@@ -817,23 +822,23 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa)
817 ok |= BRD0_OK; 822 ok |= BRD0_OK;
818 } 823 }
819 824
820 if (!(ok&BRD_OK)) 825 if (!(ok & BRD_OK))
821 fib_magic(RTM_DELROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim); 826 fib_magic(RTM_DELROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim);
822 if (!(ok&BRD1_OK)) 827 if (!(ok & BRD1_OK))
823 fib_magic(RTM_DELROUTE, RTN_BROADCAST, brd, 32, prim); 828 fib_magic(RTM_DELROUTE, RTN_BROADCAST, brd, 32, prim);
824 if (!(ok&BRD0_OK)) 829 if (!(ok & BRD0_OK))
825 fib_magic(RTM_DELROUTE, RTN_BROADCAST, any, 32, prim); 830 fib_magic(RTM_DELROUTE, RTN_BROADCAST, any, 32, prim);
826 if (!(ok&LOCAL_OK)) { 831 if (!(ok & LOCAL_OK)) {
827 fib_magic(RTM_DELROUTE, RTN_LOCAL, ifa->ifa_local, 32, prim); 832 fib_magic(RTM_DELROUTE, RTN_LOCAL, ifa->ifa_local, 32, prim);
828 833
829 /* Check, that this local address finally disappeared. */ 834 /* Check, that this local address finally disappeared. */
830 if (inet_addr_type(dev_net(dev), ifa->ifa_local) != RTN_LOCAL) { 835 if (inet_addr_type(dev_net(dev), ifa->ifa_local) != RTN_LOCAL) {
831 /* And the last, but not the least thing. 836 /* And the last, but not the least thing.
832 We must flush stray FIB entries. 837 * We must flush stray FIB entries.
833 838 *
834 First of all, we scan fib_info list searching 839 * First of all, we scan fib_info list searching
835 for stray nexthop entries, then ignite fib_flush. 840 * for stray nexthop entries, then ignite fib_flush.
836 */ 841 */
837 if (fib_sync_down_addr(dev_net(dev), ifa->ifa_local)) 842 if (fib_sync_down_addr(dev_net(dev), ifa->ifa_local))
838 fib_flush(dev_net(dev)); 843 fib_flush(dev_net(dev));
839 } 844 }
@@ -844,14 +849,20 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa)
844#undef BRD1_OK 849#undef BRD1_OK
845} 850}
846 851
847static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb ) 852static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb)
848{ 853{
849 854
850 struct fib_result res; 855 struct fib_result res;
851 struct flowi fl = { .mark = frn->fl_mark, 856 struct flowi fl = {
852 .nl_u = { .ip4_u = { .daddr = frn->fl_addr, 857 .mark = frn->fl_mark,
853 .tos = frn->fl_tos, 858 .nl_u = {
854 .scope = frn->fl_scope } } }; 859 .ip4_u = {
860 .daddr = frn->fl_addr,
861 .tos = frn->fl_tos,
862 .scope = frn->fl_scope
863 }
864 }
865 };
855 866
856#ifdef CONFIG_IP_MULTIPLE_TABLES 867#ifdef CONFIG_IP_MULTIPLE_TABLES
857 res.r = NULL; 868 res.r = NULL;
@@ -899,8 +910,8 @@ static void nl_fib_input(struct sk_buff *skb)
899 910
900 nl_fib_lookup(frn, tb); 911 nl_fib_lookup(frn, tb);
901 912
902 pid = NETLINK_CB(skb).pid; /* pid of sending process */ 913 pid = NETLINK_CB(skb).pid; /* pid of sending process */
903 NETLINK_CB(skb).pid = 0; /* from kernel */ 914 NETLINK_CB(skb).pid = 0; /* from kernel */
904 NETLINK_CB(skb).dst_group = 0; /* unicast */ 915 NETLINK_CB(skb).dst_group = 0; /* unicast */
905 netlink_unicast(net->ipv4.fibnl, skb, pid, MSG_DONTWAIT); 916 netlink_unicast(net->ipv4.fibnl, skb, pid, MSG_DONTWAIT);
906} 917}
@@ -947,7 +958,7 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event,
947 fib_del_ifaddr(ifa); 958 fib_del_ifaddr(ifa);
948 if (ifa->ifa_dev->ifa_list == NULL) { 959 if (ifa->ifa_dev->ifa_list == NULL) {
949 /* Last address was deleted from this interface. 960 /* Last address was deleted from this interface.
950 Disable IP. 961 * Disable IP.
951 */ 962 */
952 fib_disable_ip(dev, 1, 0); 963 fib_disable_ip(dev, 1, 0);
953 } else { 964 } else {
diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c
index 76daeb5ff564..32300521e32c 100644
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -6,7 +6,7 @@
6 * IPv4 Forwarding Information Base: policy rules. 6 * IPv4 Forwarding Information Base: policy rules.
7 * 7 *
8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
9 * Thomas Graf <tgraf@suug.ch> 9 * Thomas Graf <tgraf@suug.ch>
10 * 10 *
11 * This program is free software; you can redistribute it and/or 11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License 12 * modify it under the terms of the GNU General Public License
@@ -14,7 +14,7 @@
14 * 2 of the License, or (at your option) any later version. 14 * 2 of the License, or (at your option) any later version.
15 * 15 *
16 * Fixes: 16 * Fixes:
17 * Rani Assaf : local_rule cannot be deleted 17 * Rani Assaf : local_rule cannot be deleted
18 * Marc Boucher : routing by fwmark 18 * Marc Boucher : routing by fwmark
19 */ 19 */
20 20
@@ -32,8 +32,7 @@
32#include <net/ip_fib.h> 32#include <net/ip_fib.h>
33#include <net/fib_rules.h> 33#include <net/fib_rules.h>
34 34
35struct fib4_rule 35struct fib4_rule {
36{
37 struct fib_rule common; 36 struct fib_rule common;
38 u8 dst_len; 37 u8 dst_len;
39 u8 src_len; 38 u8 src_len;
@@ -91,7 +90,8 @@ static int fib4_rule_action(struct fib_rule *rule, struct flowi *flp,
91 goto errout; 90 goto errout;
92 } 91 }
93 92
94 if ((tbl = fib_get_table(rule->fr_net, rule->table)) == NULL) 93 tbl = fib_get_table(rule->fr_net, rule->table);
94 if (!tbl)
95 goto errout; 95 goto errout;
96 96
97 err = fib_table_lookup(tbl, flp, (struct fib_result *) arg->result); 97 err = fib_table_lookup(tbl, flp, (struct fib_result *) arg->result);
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 20f09c5b31e8..ba52f399a898 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -60,21 +60,30 @@ static struct hlist_head fib_info_devhash[DEVINDEX_HASHSIZE];
60 60
61static DEFINE_SPINLOCK(fib_multipath_lock); 61static DEFINE_SPINLOCK(fib_multipath_lock);
62 62
63#define for_nexthops(fi) { int nhsel; const struct fib_nh * nh; \ 63#define for_nexthops(fi) { \
64for (nhsel=0, nh = (fi)->fib_nh; nhsel < (fi)->fib_nhs; nh++, nhsel++) 64 int nhsel; const struct fib_nh *nh; \
65 65 for (nhsel = 0, nh = (fi)->fib_nh; \
66#define change_nexthops(fi) { int nhsel; struct fib_nh *nexthop_nh; \ 66 nhsel < (fi)->fib_nhs; \
67for (nhsel=0, nexthop_nh = (struct fib_nh *)((fi)->fib_nh); nhsel < (fi)->fib_nhs; nexthop_nh++, nhsel++) 67 nh++, nhsel++)
68
69#define change_nexthops(fi) { \
70 int nhsel; struct fib_nh *nexthop_nh; \
71 for (nhsel = 0, nexthop_nh = (struct fib_nh *)((fi)->fib_nh); \
72 nhsel < (fi)->fib_nhs; \
73 nexthop_nh++, nhsel++)
68 74
69#else /* CONFIG_IP_ROUTE_MULTIPATH */ 75#else /* CONFIG_IP_ROUTE_MULTIPATH */
70 76
71/* Hope, that gcc will optimize it to get rid of dummy loop */ 77/* Hope, that gcc will optimize it to get rid of dummy loop */
72 78
73#define for_nexthops(fi) { int nhsel = 0; const struct fib_nh * nh = (fi)->fib_nh; \ 79#define for_nexthops(fi) { \
74for (nhsel=0; nhsel < 1; nhsel++) 80 int nhsel; const struct fib_nh *nh = (fi)->fib_nh; \
81 for (nhsel = 0; nhsel < 1; nhsel++)
75 82
76#define change_nexthops(fi) { int nhsel = 0; struct fib_nh *nexthop_nh = (struct fib_nh *)((fi)->fib_nh); \ 83#define change_nexthops(fi) { \
77for (nhsel=0; nhsel < 1; nhsel++) 84 int nhsel; \
85 struct fib_nh *nexthop_nh = (struct fib_nh *)((fi)->fib_nh); \
86 for (nhsel = 0; nhsel < 1; nhsel++)
78 87
79#endif /* CONFIG_IP_ROUTE_MULTIPATH */ 88#endif /* CONFIG_IP_ROUTE_MULTIPATH */
80 89
@@ -86,54 +95,54 @@ static const struct
86 int error; 95 int error;
87 u8 scope; 96 u8 scope;
88} fib_props[RTN_MAX + 1] = { 97} fib_props[RTN_MAX + 1] = {
89 { 98 [RTN_UNSPEC] = {
90 .error = 0, 99 .error = 0,
91 .scope = RT_SCOPE_NOWHERE, 100 .scope = RT_SCOPE_NOWHERE,
92 }, /* RTN_UNSPEC */ 101 },
93 { 102 [RTN_UNICAST] = {
94 .error = 0, 103 .error = 0,
95 .scope = RT_SCOPE_UNIVERSE, 104 .scope = RT_SCOPE_UNIVERSE,
96 }, /* RTN_UNICAST */ 105 },
97 { 106 [RTN_LOCAL] = {
98 .error = 0, 107 .error = 0,
99 .scope = RT_SCOPE_HOST, 108 .scope = RT_SCOPE_HOST,
100 }, /* RTN_LOCAL */ 109 },
101 { 110 [RTN_BROADCAST] = {
102 .error = 0, 111 .error = 0,
103 .scope = RT_SCOPE_LINK, 112 .scope = RT_SCOPE_LINK,
104 }, /* RTN_BROADCAST */ 113 },
105 { 114 [RTN_ANYCAST] = {
106 .error = 0, 115 .error = 0,
107 .scope = RT_SCOPE_LINK, 116 .scope = RT_SCOPE_LINK,
108 }, /* RTN_ANYCAST */ 117 },
109 { 118 [RTN_MULTICAST] = {
110 .error = 0, 119 .error = 0,
111 .scope = RT_SCOPE_UNIVERSE, 120 .scope = RT_SCOPE_UNIVERSE,
112 }, /* RTN_MULTICAST */ 121 },
113 { 122 [RTN_BLACKHOLE] = {
114 .error = -EINVAL, 123 .error = -EINVAL,
115 .scope = RT_SCOPE_UNIVERSE, 124 .scope = RT_SCOPE_UNIVERSE,
116 }, /* RTN_BLACKHOLE */ 125 },
117 { 126 [RTN_UNREACHABLE] = {
118 .error = -EHOSTUNREACH, 127 .error = -EHOSTUNREACH,
119 .scope = RT_SCOPE_UNIVERSE, 128 .scope = RT_SCOPE_UNIVERSE,
120 }, /* RTN_UNREACHABLE */ 129 },
121 { 130 [RTN_PROHIBIT] = {
122 .error = -EACCES, 131 .error = -EACCES,
123 .scope = RT_SCOPE_UNIVERSE, 132 .scope = RT_SCOPE_UNIVERSE,
124 }, /* RTN_PROHIBIT */ 133 },
125 { 134 [RTN_THROW] = {
126 .error = -EAGAIN, 135 .error = -EAGAIN,
127 .scope = RT_SCOPE_UNIVERSE, 136 .scope = RT_SCOPE_UNIVERSE,
128 }, /* RTN_THROW */ 137 },
129 { 138 [RTN_NAT] = {
130 .error = -EINVAL, 139 .error = -EINVAL,
131 .scope = RT_SCOPE_NOWHERE, 140 .scope = RT_SCOPE_NOWHERE,
132 }, /* RTN_NAT */ 141 },
133 { 142 [RTN_XRESOLVE] = {
134 .error = -EINVAL, 143 .error = -EINVAL,
135 .scope = RT_SCOPE_NOWHERE, 144 .scope = RT_SCOPE_NOWHERE,
136 }, /* RTN_XRESOLVE */ 145 },
137}; 146};
138 147
139 148
@@ -142,7 +151,7 @@ static const struct
142void free_fib_info(struct fib_info *fi) 151void free_fib_info(struct fib_info *fi)
143{ 152{
144 if (fi->fib_dead == 0) { 153 if (fi->fib_dead == 0) {
145 printk(KERN_WARNING "Freeing alive fib_info %p\n", fi); 154 pr_warning("Freeing alive fib_info %p\n", fi);
146 return; 155 return;
147 } 156 }
148 change_nexthops(fi) { 157 change_nexthops(fi) {
@@ -173,7 +182,7 @@ void fib_release_info(struct fib_info *fi)
173 spin_unlock_bh(&fib_info_lock); 182 spin_unlock_bh(&fib_info_lock);
174} 183}
175 184
176static __inline__ int nh_comp(const struct fib_info *fi, const struct fib_info *ofi) 185static inline int nh_comp(const struct fib_info *fi, const struct fib_info *ofi)
177{ 186{
178 const struct fib_nh *onh = ofi->fib_nh; 187 const struct fib_nh *onh = ofi->fib_nh;
179 188
@@ -187,7 +196,7 @@ static __inline__ int nh_comp(const struct fib_info *fi, const struct fib_info *
187#ifdef CONFIG_NET_CLS_ROUTE 196#ifdef CONFIG_NET_CLS_ROUTE
188 nh->nh_tclassid != onh->nh_tclassid || 197 nh->nh_tclassid != onh->nh_tclassid ||
189#endif 198#endif
190 ((nh->nh_flags^onh->nh_flags)&~RTNH_F_DEAD)) 199 ((nh->nh_flags ^ onh->nh_flags) & ~RTNH_F_DEAD))
191 return -1; 200 return -1;
192 onh++; 201 onh++;
193 } endfor_nexthops(fi); 202 } endfor_nexthops(fi);
@@ -238,7 +247,7 @@ static struct fib_info *fib_find_info(const struct fib_info *nfi)
238 nfi->fib_priority == fi->fib_priority && 247 nfi->fib_priority == fi->fib_priority &&
239 memcmp(nfi->fib_metrics, fi->fib_metrics, 248 memcmp(nfi->fib_metrics, fi->fib_metrics,
240 sizeof(fi->fib_metrics)) == 0 && 249 sizeof(fi->fib_metrics)) == 0 &&
241 ((nfi->fib_flags^fi->fib_flags)&~RTNH_F_DEAD) == 0 && 250 ((nfi->fib_flags ^ fi->fib_flags) & ~RTNH_F_DEAD) == 0 &&
242 (nfi->fib_nhs == 0 || nh_comp(fi, nfi) == 0)) 251 (nfi->fib_nhs == 0 || nh_comp(fi, nfi) == 0))
243 return fi; 252 return fi;
244 } 253 }
@@ -247,9 +256,8 @@ static struct fib_info *fib_find_info(const struct fib_info *nfi)
247} 256}
248 257
249/* Check, that the gateway is already configured. 258/* Check, that the gateway is already configured.
250 Used only by redirect accept routine. 259 * Used only by redirect accept routine.
251 */ 260 */
252
253int ip_fib_check_default(__be32 gw, struct net_device *dev) 261int ip_fib_check_default(__be32 gw, struct net_device *dev)
254{ 262{
255 struct hlist_head *head; 263 struct hlist_head *head;
@@ -264,7 +272,7 @@ int ip_fib_check_default(__be32 gw, struct net_device *dev)
264 hlist_for_each_entry(nh, node, head, nh_hash) { 272 hlist_for_each_entry(nh, node, head, nh_hash) {
265 if (nh->nh_dev == dev && 273 if (nh->nh_dev == dev &&
266 nh->nh_gw == gw && 274 nh->nh_gw == gw &&
267 !(nh->nh_flags&RTNH_F_DEAD)) { 275 !(nh->nh_flags & RTNH_F_DEAD)) {
268 spin_unlock(&fib_info_lock); 276 spin_unlock(&fib_info_lock);
269 return 0; 277 return 0;
270 } 278 }
@@ -362,10 +370,10 @@ int fib_detect_death(struct fib_info *fi, int order,
362 } 370 }
363 if (state == NUD_REACHABLE) 371 if (state == NUD_REACHABLE)
364 return 0; 372 return 0;
365 if ((state&NUD_VALID) && order != dflt) 373 if ((state & NUD_VALID) && order != dflt)
366 return 0; 374 return 0;
367 if ((state&NUD_VALID) || 375 if ((state & NUD_VALID) ||
368 (*last_idx<0 && order > dflt)) { 376 (*last_idx < 0 && order > dflt)) {
369 *last_resort = fi; 377 *last_resort = fi;
370 *last_idx = order; 378 *last_idx = order;
371 } 379 }
@@ -476,69 +484,69 @@ int fib_nh_match(struct fib_config *cfg, struct fib_info *fi)
476 484
477 485
478/* 486/*
479 Picture 487 * Picture
480 ------- 488 * -------
481 489 *
482 Semantics of nexthop is very messy by historical reasons. 490 * Semantics of nexthop is very messy by historical reasons.
483 We have to take into account, that: 491 * We have to take into account, that:
484 a) gateway can be actually local interface address, 492 * a) gateway can be actually local interface address,
485 so that gatewayed route is direct. 493 * so that gatewayed route is direct.
486 b) gateway must be on-link address, possibly 494 * b) gateway must be on-link address, possibly
487 described not by an ifaddr, but also by a direct route. 495 * described not by an ifaddr, but also by a direct route.
488 c) If both gateway and interface are specified, they should not 496 * c) If both gateway and interface are specified, they should not
489 contradict. 497 * contradict.
490 d) If we use tunnel routes, gateway could be not on-link. 498 * d) If we use tunnel routes, gateway could be not on-link.
491 499 *
492 Attempt to reconcile all of these (alas, self-contradictory) conditions 500 * Attempt to reconcile all of these (alas, self-contradictory) conditions
493 results in pretty ugly and hairy code with obscure logic. 501 * results in pretty ugly and hairy code with obscure logic.
494 502 *
495 I chose to generalized it instead, so that the size 503 * I chose to generalized it instead, so that the size
496 of code does not increase practically, but it becomes 504 * of code does not increase practically, but it becomes
497 much more general. 505 * much more general.
498 Every prefix is assigned a "scope" value: "host" is local address, 506 * Every prefix is assigned a "scope" value: "host" is local address,
499 "link" is direct route, 507 * "link" is direct route,
500 [ ... "site" ... "interior" ... ] 508 * [ ... "site" ... "interior" ... ]
501 and "universe" is true gateway route with global meaning. 509 * and "universe" is true gateway route with global meaning.
502 510 *
503 Every prefix refers to a set of "nexthop"s (gw, oif), 511 * Every prefix refers to a set of "nexthop"s (gw, oif),
504 where gw must have narrower scope. This recursion stops 512 * where gw must have narrower scope. This recursion stops
505 when gw has LOCAL scope or if "nexthop" is declared ONLINK, 513 * when gw has LOCAL scope or if "nexthop" is declared ONLINK,
506 which means that gw is forced to be on link. 514 * which means that gw is forced to be on link.
507 515 *
508 Code is still hairy, but now it is apparently logically 516 * Code is still hairy, but now it is apparently logically
509 consistent and very flexible. F.e. as by-product it allows 517 * consistent and very flexible. F.e. as by-product it allows
510 to co-exists in peace independent exterior and interior 518 * to co-exists in peace independent exterior and interior
511 routing processes. 519 * routing processes.
512 520 *
513 Normally it looks as following. 521 * Normally it looks as following.
514 522 *
515 {universe prefix} -> (gw, oif) [scope link] 523 * {universe prefix} -> (gw, oif) [scope link]
516 | 524 * |
517 |-> {link prefix} -> (gw, oif) [scope local] 525 * |-> {link prefix} -> (gw, oif) [scope local]
518 | 526 * |
519 |-> {local prefix} (terminal node) 527 * |-> {local prefix} (terminal node)
520 */ 528 */
521
522static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi, 529static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi,
523 struct fib_nh *nh) 530 struct fib_nh *nh)
524{ 531{
525 int err; 532 int err;
526 struct net *net; 533 struct net *net;
534 struct net_device *dev;
527 535
528 net = cfg->fc_nlinfo.nl_net; 536 net = cfg->fc_nlinfo.nl_net;
529 if (nh->nh_gw) { 537 if (nh->nh_gw) {
530 struct fib_result res; 538 struct fib_result res;
531 539
532 if (nh->nh_flags&RTNH_F_ONLINK) { 540 if (nh->nh_flags & RTNH_F_ONLINK) {
533 struct net_device *dev;
534 541
535 if (cfg->fc_scope >= RT_SCOPE_LINK) 542 if (cfg->fc_scope >= RT_SCOPE_LINK)
536 return -EINVAL; 543 return -EINVAL;
537 if (inet_addr_type(net, nh->nh_gw) != RTN_UNICAST) 544 if (inet_addr_type(net, nh->nh_gw) != RTN_UNICAST)
538 return -EINVAL; 545 return -EINVAL;
539 if ((dev = __dev_get_by_index(net, nh->nh_oif)) == NULL) 546 dev = __dev_get_by_index(net, nh->nh_oif);
547 if (!dev)
540 return -ENODEV; 548 return -ENODEV;
541 if (!(dev->flags&IFF_UP)) 549 if (!(dev->flags & IFF_UP))
542 return -ENETDOWN; 550 return -ENETDOWN;
543 nh->nh_dev = dev; 551 nh->nh_dev = dev;
544 dev_hold(dev); 552 dev_hold(dev);
@@ -559,7 +567,8 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi,
559 /* It is not necessary, but requires a bit of thinking */ 567 /* It is not necessary, but requires a bit of thinking */
560 if (fl.fl4_scope < RT_SCOPE_LINK) 568 if (fl.fl4_scope < RT_SCOPE_LINK)
561 fl.fl4_scope = RT_SCOPE_LINK; 569 fl.fl4_scope = RT_SCOPE_LINK;
562 if ((err = fib_lookup(net, &fl, &res)) != 0) 570 err = fib_lookup(net, &fl, &res);
571 if (err)
563 return err; 572 return err;
564 } 573 }
565 err = -EINVAL; 574 err = -EINVAL;
@@ -567,11 +576,12 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi,
567 goto out; 576 goto out;
568 nh->nh_scope = res.scope; 577 nh->nh_scope = res.scope;
569 nh->nh_oif = FIB_RES_OIF(res); 578 nh->nh_oif = FIB_RES_OIF(res);
570 if ((nh->nh_dev = FIB_RES_DEV(res)) == NULL) 579 nh->nh_dev = dev = FIB_RES_DEV(res);
580 if (!dev)
571 goto out; 581 goto out;
572 dev_hold(nh->nh_dev); 582 dev_hold(dev);
573 err = -ENETDOWN; 583 err = -ENETDOWN;
574 if (!(nh->nh_dev->flags & IFF_UP)) 584 if (!(dev->flags & IFF_UP))
575 goto out; 585 goto out;
576 err = 0; 586 err = 0;
577out: 587out:
@@ -580,13 +590,13 @@ out:
580 } else { 590 } else {
581 struct in_device *in_dev; 591 struct in_device *in_dev;
582 592
583 if (nh->nh_flags&(RTNH_F_PERVASIVE|RTNH_F_ONLINK)) 593 if (nh->nh_flags & (RTNH_F_PERVASIVE | RTNH_F_ONLINK))
584 return -EINVAL; 594 return -EINVAL;
585 595
586 in_dev = inetdev_by_index(net, nh->nh_oif); 596 in_dev = inetdev_by_index(net, nh->nh_oif);
587 if (in_dev == NULL) 597 if (in_dev == NULL)
588 return -ENODEV; 598 return -ENODEV;
589 if (!(in_dev->dev->flags&IFF_UP)) { 599 if (!(in_dev->dev->flags & IFF_UP)) {
590 in_dev_put(in_dev); 600 in_dev_put(in_dev);
591 return -ENETDOWN; 601 return -ENETDOWN;
592 } 602 }
@@ -602,7 +612,9 @@ static inline unsigned int fib_laddr_hashfn(__be32 val)
602{ 612{
603 unsigned int mask = (fib_hash_size - 1); 613 unsigned int mask = (fib_hash_size - 1);
604 614
605 return ((__force u32)val ^ ((__force u32)val >> 7) ^ ((__force u32)val >> 14)) & mask; 615 return ((__force u32)val ^
616 ((__force u32)val >> 7) ^
617 ((__force u32)val >> 14)) & mask;
606} 618}
607 619
608static struct hlist_head *fib_hash_alloc(int bytes) 620static struct hlist_head *fib_hash_alloc(int bytes)
@@ -611,7 +623,8 @@ static struct hlist_head *fib_hash_alloc(int bytes)
611 return kzalloc(bytes, GFP_KERNEL); 623 return kzalloc(bytes, GFP_KERNEL);
612 else 624 else
613 return (struct hlist_head *) 625 return (struct hlist_head *)
614 __get_free_pages(GFP_KERNEL | __GFP_ZERO, get_order(bytes)); 626 __get_free_pages(GFP_KERNEL | __GFP_ZERO,
627 get_order(bytes));
615} 628}
616 629
617static void fib_hash_free(struct hlist_head *hash, int bytes) 630static void fib_hash_free(struct hlist_head *hash, int bytes)
@@ -806,7 +819,8 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
806 goto failure; 819 goto failure;
807 } else { 820 } else {
808 change_nexthops(fi) { 821 change_nexthops(fi) {
809 if ((err = fib_check_nh(cfg, fi, nexthop_nh)) != 0) 822 err = fib_check_nh(cfg, fi, nexthop_nh);
823 if (err != 0)
810 goto failure; 824 goto failure;
811 } endfor_nexthops(fi) 825 } endfor_nexthops(fi)
812 } 826 }
@@ -819,7 +833,8 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
819 } 833 }
820 834
821link_it: 835link_it:
822 if ((ofi = fib_find_info(fi)) != NULL) { 836 ofi = fib_find_info(fi);
837 if (ofi) {
823 fi->fib_dead = 1; 838 fi->fib_dead = 1;
824 free_fib_info(fi); 839 free_fib_info(fi);
825 ofi->fib_treeref++; 840 ofi->fib_treeref++;
@@ -895,7 +910,7 @@ int fib_semantic_match(struct list_head *head, const struct flowi *flp,
895 case RTN_ANYCAST: 910 case RTN_ANYCAST:
896 case RTN_MULTICAST: 911 case RTN_MULTICAST:
897 for_nexthops(fi) { 912 for_nexthops(fi) {
898 if (nh->nh_flags&RTNH_F_DEAD) 913 if (nh->nh_flags & RTNH_F_DEAD)
899 continue; 914 continue;
900 if (!flp->oif || flp->oif == nh->nh_oif) 915 if (!flp->oif || flp->oif == nh->nh_oif)
901 break; 916 break;
@@ -906,16 +921,15 @@ int fib_semantic_match(struct list_head *head, const struct flowi *flp,
906 goto out_fill_res; 921 goto out_fill_res;
907 } 922 }
908#else 923#else
909 if (nhsel < 1) { 924 if (nhsel < 1)
910 goto out_fill_res; 925 goto out_fill_res;
911 }
912#endif 926#endif
913 endfor_nexthops(fi); 927 endfor_nexthops(fi);
914 continue; 928 continue;
915 929
916 default: 930 default:
917 printk(KERN_WARNING "fib_semantic_match bad type %#x\n", 931 pr_warning("fib_semantic_match bad type %#x\n",
918 fa->fa_type); 932 fa->fa_type);
919 return -EINVAL; 933 return -EINVAL;
920 } 934 }
921 } 935 }
@@ -1028,10 +1042,10 @@ nla_put_failure:
1028} 1042}
1029 1043
1030/* 1044/*
1031 Update FIB if: 1045 * Update FIB if:
1032 - local address disappeared -> we must delete all the entries 1046 * - local address disappeared -> we must delete all the entries
1033 referring to it. 1047 * referring to it.
1034 - device went down -> we must shutdown all nexthops going via it. 1048 * - device went down -> we must shutdown all nexthops going via it.
1035 */ 1049 */
1036int fib_sync_down_addr(struct net *net, __be32 local) 1050int fib_sync_down_addr(struct net *net, __be32 local)
1037{ 1051{
@@ -1078,7 +1092,7 @@ int fib_sync_down_dev(struct net_device *dev, int force)
1078 prev_fi = fi; 1092 prev_fi = fi;
1079 dead = 0; 1093 dead = 0;
1080 change_nexthops(fi) { 1094 change_nexthops(fi) {
1081 if (nexthop_nh->nh_flags&RTNH_F_DEAD) 1095 if (nexthop_nh->nh_flags & RTNH_F_DEAD)
1082 dead++; 1096 dead++;
1083 else if (nexthop_nh->nh_dev == dev && 1097 else if (nexthop_nh->nh_dev == dev &&
1084 nexthop_nh->nh_scope != scope) { 1098 nexthop_nh->nh_scope != scope) {
@@ -1110,10 +1124,9 @@ int fib_sync_down_dev(struct net_device *dev, int force)
1110#ifdef CONFIG_IP_ROUTE_MULTIPATH 1124#ifdef CONFIG_IP_ROUTE_MULTIPATH
1111 1125
1112/* 1126/*
1113 Dead device goes up. We wake up dead nexthops. 1127 * Dead device goes up. We wake up dead nexthops.
1114 It takes sense only on multipath routes. 1128 * It takes sense only on multipath routes.
1115 */ 1129 */
1116
1117int fib_sync_up(struct net_device *dev) 1130int fib_sync_up(struct net_device *dev)
1118{ 1131{
1119 struct fib_info *prev_fi; 1132 struct fib_info *prev_fi;
@@ -1123,7 +1136,7 @@ int fib_sync_up(struct net_device *dev)
1123 struct fib_nh *nh; 1136 struct fib_nh *nh;
1124 int ret; 1137 int ret;
1125 1138
1126 if (!(dev->flags&IFF_UP)) 1139 if (!(dev->flags & IFF_UP))
1127 return 0; 1140 return 0;
1128 1141
1129 prev_fi = NULL; 1142 prev_fi = NULL;
@@ -1142,12 +1155,12 @@ int fib_sync_up(struct net_device *dev)
1142 prev_fi = fi; 1155 prev_fi = fi;
1143 alive = 0; 1156 alive = 0;
1144 change_nexthops(fi) { 1157 change_nexthops(fi) {
1145 if (!(nexthop_nh->nh_flags&RTNH_F_DEAD)) { 1158 if (!(nexthop_nh->nh_flags & RTNH_F_DEAD)) {
1146 alive++; 1159 alive++;
1147 continue; 1160 continue;
1148 } 1161 }
1149 if (nexthop_nh->nh_dev == NULL || 1162 if (nexthop_nh->nh_dev == NULL ||
1150 !(nexthop_nh->nh_dev->flags&IFF_UP)) 1163 !(nexthop_nh->nh_dev->flags & IFF_UP))
1151 continue; 1164 continue;
1152 if (nexthop_nh->nh_dev != dev || 1165 if (nexthop_nh->nh_dev != dev ||
1153 !__in_dev_get_rtnl(dev)) 1166 !__in_dev_get_rtnl(dev))
@@ -1169,10 +1182,9 @@ int fib_sync_up(struct net_device *dev)
1169} 1182}
1170 1183
1171/* 1184/*
1172 The algorithm is suboptimal, but it provides really 1185 * The algorithm is suboptimal, but it provides really
1173 fair weighted route distribution. 1186 * fair weighted route distribution.
1174 */ 1187 */
1175
1176void fib_select_multipath(const struct flowi *flp, struct fib_result *res) 1188void fib_select_multipath(const struct flowi *flp, struct fib_result *res)
1177{ 1189{
1178 struct fib_info *fi = res->fi; 1190 struct fib_info *fi = res->fi;
@@ -1182,7 +1194,7 @@ void fib_select_multipath(const struct flowi *flp, struct fib_result *res)
1182 if (fi->fib_power <= 0) { 1194 if (fi->fib_power <= 0) {
1183 int power = 0; 1195 int power = 0;
1184 change_nexthops(fi) { 1196 change_nexthops(fi) {
1185 if (!(nexthop_nh->nh_flags&RTNH_F_DEAD)) { 1197 if (!(nexthop_nh->nh_flags & RTNH_F_DEAD)) {
1186 power += nexthop_nh->nh_weight; 1198 power += nexthop_nh->nh_weight;
1187 nexthop_nh->nh_power = nexthop_nh->nh_weight; 1199 nexthop_nh->nh_power = nexthop_nh->nh_weight;
1188 } 1200 }
@@ -1198,15 +1210,16 @@ void fib_select_multipath(const struct flowi *flp, struct fib_result *res)
1198 1210
1199 1211
1200 /* w should be random number [0..fi->fib_power-1], 1212 /* w should be random number [0..fi->fib_power-1],
1201 it is pretty bad approximation. 1213 * it is pretty bad approximation.
1202 */ 1214 */
1203 1215
1204 w = jiffies % fi->fib_power; 1216 w = jiffies % fi->fib_power;
1205 1217
1206 change_nexthops(fi) { 1218 change_nexthops(fi) {
1207 if (!(nexthop_nh->nh_flags&RTNH_F_DEAD) && 1219 if (!(nexthop_nh->nh_flags & RTNH_F_DEAD) &&
1208 nexthop_nh->nh_power) { 1220 nexthop_nh->nh_power) {
1209 if ((w -= nexthop_nh->nh_power) <= 0) { 1221 w -= nexthop_nh->nh_power;
1222 if (w <= 0) {
1210 nexthop_nh->nh_power--; 1223 nexthop_nh->nh_power--;
1211 fi->fib_power--; 1224 fi->fib_power--;
1212 res->nh_sel = nhsel; 1225 res->nh_sel = nhsel;