aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/fib_frontend.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/fib_frontend.c')
-rw-r--r--net/ipv4/fib_frontend.c188
1 files changed, 71 insertions, 117 deletions
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 5cd75e2dab2..92fc5f69f5d 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -15,6 +15,7 @@
15 15
16#include <linux/module.h> 16#include <linux/module.h>
17#include <asm/uaccess.h> 17#include <asm/uaccess.h>
18#include <asm/system.h>
18#include <linux/bitops.h> 19#include <linux/bitops.h>
19#include <linux/capability.h> 20#include <linux/capability.h>
20#include <linux/types.h> 21#include <linux/types.h>
@@ -31,7 +32,6 @@
31#include <linux/if_addr.h> 32#include <linux/if_addr.h>
32#include <linux/if_arp.h> 33#include <linux/if_arp.h>
33#include <linux/skbuff.h> 34#include <linux/skbuff.h>
34#include <linux/cache.h>
35#include <linux/init.h> 35#include <linux/init.h>
36#include <linux/list.h> 36#include <linux/list.h>
37#include <linux/slab.h> 37#include <linux/slab.h>
@@ -86,24 +86,6 @@ struct fib_table *fib_new_table(struct net *net, u32 id)
86 tb = fib_trie_table(id); 86 tb = fib_trie_table(id);
87 if (!tb) 87 if (!tb)
88 return NULL; 88 return NULL;
89
90 switch (id) {
91 case RT_TABLE_LOCAL:
92 net->ipv4.fib_local = tb;
93 break;
94
95 case RT_TABLE_MAIN:
96 net->ipv4.fib_main = tb;
97 break;
98
99 case RT_TABLE_DEFAULT:
100 net->ipv4.fib_default = tb;
101 break;
102
103 default:
104 break;
105 }
106
107 h = id & (FIB_TABLE_HASHSZ - 1); 89 h = id & (FIB_TABLE_HASHSZ - 1);
108 hlist_add_head_rcu(&tb->tb_hlist, &net->ipv4.fib_table_hash[h]); 90 hlist_add_head_rcu(&tb->tb_hlist, &net->ipv4.fib_table_hash[h]);
109 return tb; 91 return tb;
@@ -148,20 +130,20 @@ static void fib_flush(struct net *net)
148 } 130 }
149 131
150 if (flushed) 132 if (flushed)
151 rt_cache_flush(net); 133 rt_cache_flush(net, -1);
152} 134}
153 135
154/* 136/*
155 * Find address type as if only "dev" was present in the system. If 137 * Find address type as if only "dev" was present in the system. If
156 * on_dev is NULL then all interfaces are taken into consideration. 138 * on_dev is NULL then all interfaces are taken into consideration.
157 */ 139 */
158static inline unsigned int __inet_dev_addr_type(struct net *net, 140static inline unsigned __inet_dev_addr_type(struct net *net,
159 const struct net_device *dev, 141 const struct net_device *dev,
160 __be32 addr) 142 __be32 addr)
161{ 143{
162 struct flowi4 fl4 = { .daddr = addr }; 144 struct flowi4 fl4 = { .daddr = addr };
163 struct fib_result res; 145 struct fib_result res;
164 unsigned int ret = RTN_BROADCAST; 146 unsigned ret = RTN_BROADCAST;
165 struct fib_table *local_table; 147 struct fib_table *local_table;
166 148
167 if (ipv4_is_zeronet(addr) || ipv4_is_lbcast(addr)) 149 if (ipv4_is_zeronet(addr) || ipv4_is_lbcast(addr))
@@ -169,6 +151,10 @@ static inline unsigned int __inet_dev_addr_type(struct net *net,
169 if (ipv4_is_multicast(addr)) 151 if (ipv4_is_multicast(addr))
170 return RTN_MULTICAST; 152 return RTN_MULTICAST;
171 153
154#ifdef CONFIG_IP_MULTIPLE_TABLES
155 res.r = NULL;
156#endif
157
172 local_table = fib_get_table(net, RT_TABLE_LOCAL); 158 local_table = fib_get_table(net, RT_TABLE_LOCAL);
173 if (local_table) { 159 if (local_table) {
174 ret = RTN_UNICAST; 160 ret = RTN_UNICAST;
@@ -195,44 +181,6 @@ unsigned int inet_dev_addr_type(struct net *net, const struct net_device *dev,
195} 181}
196EXPORT_SYMBOL(inet_dev_addr_type); 182EXPORT_SYMBOL(inet_dev_addr_type);
197 183
198__be32 fib_compute_spec_dst(struct sk_buff *skb)
199{
200 struct net_device *dev = skb->dev;
201 struct in_device *in_dev;
202 struct fib_result res;
203 struct rtable *rt;
204 struct flowi4 fl4;
205 struct net *net;
206 int scope;
207
208 rt = skb_rtable(skb);
209 if ((rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST | RTCF_LOCAL)) ==
210 RTCF_LOCAL)
211 return ip_hdr(skb)->daddr;
212
213 in_dev = __in_dev_get_rcu(dev);
214 BUG_ON(!in_dev);
215
216 net = dev_net(dev);
217
218 scope = RT_SCOPE_UNIVERSE;
219 if (!ipv4_is_zeronet(ip_hdr(skb)->saddr)) {
220 fl4.flowi4_oif = 0;
221 fl4.flowi4_iif = LOOPBACK_IFINDEX;
222 fl4.daddr = ip_hdr(skb)->saddr;
223 fl4.saddr = 0;
224 fl4.flowi4_tos = RT_TOS(ip_hdr(skb)->tos);
225 fl4.flowi4_scope = scope;
226 fl4.flowi4_mark = IN_DEV_SRC_VMARK(in_dev) ? skb->mark : 0;
227 if (!fib_lookup(net, &fl4, &res))
228 return FIB_RES_PREFSRC(net, res);
229 } else {
230 scope = RT_SCOPE_LINK;
231 }
232
233 return inet_select_addr(dev, ip_hdr(skb)->saddr, scope);
234}
235
236/* Given (packet source, input interface) and optional (dst, oif, tos): 184/* Given (packet source, input interface) and optional (dst, oif, tos):
237 * - (main) check, that source is valid i.e. not broadcast or our local 185 * - (main) check, that source is valid i.e. not broadcast or our local
238 * address. 186 * address.
@@ -241,15 +189,17 @@ __be32 fib_compute_spec_dst(struct sk_buff *skb)
241 * - check, that packet arrived from expected physical interface. 189 * - check, that packet arrived from expected physical interface.
242 * called with rcu_read_lock() 190 * called with rcu_read_lock()
243 */ 191 */
244static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, 192int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst, u8 tos,
245 u8 tos, int oif, struct net_device *dev, 193 int oif, struct net_device *dev, __be32 *spec_dst,
246 int rpf, struct in_device *idev, u32 *itag) 194 u32 *itag)
247{ 195{
248 int ret, no_addr, accept_local; 196 struct in_device *in_dev;
249 struct fib_result res;
250 struct flowi4 fl4; 197 struct flowi4 fl4;
251 struct net *net; 198 struct fib_result res;
199 int no_addr, rpf, accept_local;
252 bool dev_match; 200 bool dev_match;
201 int ret;
202 struct net *net;
253 203
254 fl4.flowi4_oif = 0; 204 fl4.flowi4_oif = 0;
255 fl4.flowi4_iif = oif; 205 fl4.flowi4_iif = oif;
@@ -258,10 +208,20 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
258 fl4.flowi4_tos = tos; 208 fl4.flowi4_tos = tos;
259 fl4.flowi4_scope = RT_SCOPE_UNIVERSE; 209 fl4.flowi4_scope = RT_SCOPE_UNIVERSE;
260 210
261 no_addr = idev->ifa_list == NULL; 211 no_addr = rpf = accept_local = 0;
212 in_dev = __in_dev_get_rcu(dev);
213 if (in_dev) {
214 no_addr = in_dev->ifa_list == NULL;
215
216 /* Ignore rp_filter for packets protected by IPsec. */
217 rpf = secpath_exists(skb) ? 0 : IN_DEV_RPFILTER(in_dev);
218
219 accept_local = IN_DEV_ACCEPT_LOCAL(in_dev);
220 fl4.flowi4_mark = IN_DEV_SRC_VMARK(in_dev) ? skb->mark : 0;
221 }
262 222
263 accept_local = IN_DEV_ACCEPT_LOCAL(idev); 223 if (in_dev == NULL)
264 fl4.flowi4_mark = IN_DEV_SRC_VMARK(idev) ? skb->mark : 0; 224 goto e_inval;
265 225
266 net = dev_net(dev); 226 net = dev_net(dev);
267 if (fib_lookup(net, &fl4, &res)) 227 if (fib_lookup(net, &fl4, &res))
@@ -270,6 +230,7 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
270 if (res.type != RTN_LOCAL || !accept_local) 230 if (res.type != RTN_LOCAL || !accept_local)
271 goto e_inval; 231 goto e_inval;
272 } 232 }
233 *spec_dst = FIB_RES_PREFSRC(net, res);
273 fib_combine_itag(itag, &res); 234 fib_combine_itag(itag, &res);
274 dev_match = false; 235 dev_match = false;
275 236
@@ -298,14 +259,17 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
298 259
299 ret = 0; 260 ret = 0;
300 if (fib_lookup(net, &fl4, &res) == 0) { 261 if (fib_lookup(net, &fl4, &res) == 0) {
301 if (res.type == RTN_UNICAST) 262 if (res.type == RTN_UNICAST) {
263 *spec_dst = FIB_RES_PREFSRC(net, res);
302 ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST; 264 ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST;
265 }
303 } 266 }
304 return ret; 267 return ret;
305 268
306last_resort: 269last_resort:
307 if (rpf) 270 if (rpf)
308 goto e_rpf; 271 goto e_rpf;
272 *spec_dst = inet_select_addr(dev, 0, RT_SCOPE_UNIVERSE);
309 *itag = 0; 273 *itag = 0;
310 return 0; 274 return 0;
311 275
@@ -315,21 +279,6 @@ e_rpf:
315 return -EXDEV; 279 return -EXDEV;
316} 280}
317 281
318/* Ignore rp_filter for packets protected by IPsec. */
319int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
320 u8 tos, int oif, struct net_device *dev,
321 struct in_device *idev, u32 *itag)
322{
323 int r = secpath_exists(skb) ? 0 : IN_DEV_RPFILTER(idev);
324
325 if (!r && !fib_num_tclassid_users(dev_net(dev)) &&
326 (dev->ifindex != oif || !IN_DEV_TX_REDIRECTS(idev))) {
327 *itag = 0;
328 return 0;
329 }
330 return __fib_validate_source(skb, src, dst, tos, oif, dev, r, idev, itag);
331}
332
333static inline __be32 sk_extract_addr(struct sockaddr *addr) 282static inline __be32 sk_extract_addr(struct sockaddr *addr)
334{ 283{
335 return ((struct sockaddr_in *) addr)->sin_addr.s_addr; 284 return ((struct sockaddr_in *) addr)->sin_addr.s_addr;
@@ -488,7 +437,7 @@ int ip_rt_ioctl(struct net *net, unsigned int cmd, void __user *arg)
488 switch (cmd) { 437 switch (cmd) {
489 case SIOCADDRT: /* Add a route */ 438 case SIOCADDRT: /* Add a route */
490 case SIOCDELRT: /* Delete a route */ 439 case SIOCDELRT: /* Delete a route */
491 if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) 440 if (!capable(CAP_NET_ADMIN))
492 return -EPERM; 441 return -EPERM;
493 442
494 if (copy_from_user(&rt, arg, sizeof(rt))) 443 if (copy_from_user(&rt, arg, sizeof(rt)))
@@ -558,7 +507,7 @@ static int rtm_to_fib_config(struct net *net, struct sk_buff *skb,
558 cfg->fc_flags = rtm->rtm_flags; 507 cfg->fc_flags = rtm->rtm_flags;
559 cfg->fc_nlflags = nlh->nlmsg_flags; 508 cfg->fc_nlflags = nlh->nlmsg_flags;
560 509
561 cfg->fc_nlinfo.portid = NETLINK_CB(skb).portid; 510 cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid;
562 cfg->fc_nlinfo.nlh = nlh; 511 cfg->fc_nlinfo.nlh = nlh;
563 cfg->fc_nlinfo.nl_net = net; 512 cfg->fc_nlinfo.nl_net = net;
564 513
@@ -746,7 +695,7 @@ void fib_add_ifaddr(struct in_ifaddr *ifa)
746 if (ifa->ifa_flags & IFA_F_SECONDARY) { 695 if (ifa->ifa_flags & IFA_F_SECONDARY) {
747 prim = inet_ifa_byprefix(in_dev, prefix, mask); 696 prim = inet_ifa_byprefix(in_dev, prefix, mask);
748 if (prim == NULL) { 697 if (prim == NULL) {
749 pr_warn("%s: bug: prim == NULL\n", __func__); 698 printk(KERN_WARNING "fib_add_ifaddr: bug: prim == NULL\n");
750 return; 699 return;
751 } 700 }
752 } 701 }
@@ -792,7 +741,7 @@ void fib_del_ifaddr(struct in_ifaddr *ifa, struct in_ifaddr *iprim)
792#define BRD_OK 2 741#define BRD_OK 2
793#define BRD0_OK 4 742#define BRD0_OK 4
794#define BRD1_OK 8 743#define BRD1_OK 8
795 unsigned int ok = 0; 744 unsigned ok = 0;
796 int subnet = 0; /* Primary network */ 745 int subnet = 0; /* Primary network */
797 int gone = 1; /* Address is missing */ 746 int gone = 1; /* Address is missing */
798 int same_prefsrc = 0; /* Another primary with same IP */ 747 int same_prefsrc = 0; /* Another primary with same IP */
@@ -800,11 +749,11 @@ void fib_del_ifaddr(struct in_ifaddr *ifa, struct in_ifaddr *iprim)
800 if (ifa->ifa_flags & IFA_F_SECONDARY) { 749 if (ifa->ifa_flags & IFA_F_SECONDARY) {
801 prim = inet_ifa_byprefix(in_dev, any, ifa->ifa_mask); 750 prim = inet_ifa_byprefix(in_dev, any, ifa->ifa_mask);
802 if (prim == NULL) { 751 if (prim == NULL) {
803 pr_warn("%s: bug: prim == NULL\n", __func__); 752 printk(KERN_WARNING "fib_del_ifaddr: bug: prim == NULL\n");
804 return; 753 return;
805 } 754 }
806 if (iprim && iprim != prim) { 755 if (iprim && iprim != prim) {
807 pr_warn("%s: bug: iprim != prim\n", __func__); 756 printk(KERN_WARNING "fib_del_ifaddr: bug: iprim != prim\n");
808 return; 757 return;
809 } 758 }
810 } else if (!ipv4_is_zeronet(any) && 759 } else if (!ipv4_is_zeronet(any) &&
@@ -931,6 +880,10 @@ static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb)
931 .flowi4_scope = frn->fl_scope, 880 .flowi4_scope = frn->fl_scope,
932 }; 881 };
933 882
883#ifdef CONFIG_IP_MULTIPLE_TABLES
884 res.r = NULL;
885#endif
886
934 frn->err = -ENOENT; 887 frn->err = -ENOENT;
935 if (tb) { 888 if (tb) {
936 local_bh_disable(); 889 local_bh_disable();
@@ -956,7 +909,7 @@ static void nl_fib_input(struct sk_buff *skb)
956 struct fib_result_nl *frn; 909 struct fib_result_nl *frn;
957 struct nlmsghdr *nlh; 910 struct nlmsghdr *nlh;
958 struct fib_table *tb; 911 struct fib_table *tb;
959 u32 portid; 912 u32 pid;
960 913
961 net = sock_net(skb->sk); 914 net = sock_net(skb->sk);
962 nlh = nlmsg_hdr(skb); 915 nlh = nlmsg_hdr(skb);
@@ -974,20 +927,17 @@ static void nl_fib_input(struct sk_buff *skb)
974 927
975 nl_fib_lookup(frn, tb); 928 nl_fib_lookup(frn, tb);
976 929
977 portid = NETLINK_CB(skb).portid; /* pid of sending process */ 930 pid = NETLINK_CB(skb).pid; /* pid of sending process */
978 NETLINK_CB(skb).portid = 0; /* from kernel */ 931 NETLINK_CB(skb).pid = 0; /* from kernel */
979 NETLINK_CB(skb).dst_group = 0; /* unicast */ 932 NETLINK_CB(skb).dst_group = 0; /* unicast */
980 netlink_unicast(net->ipv4.fibnl, skb, portid, MSG_DONTWAIT); 933 netlink_unicast(net->ipv4.fibnl, skb, pid, MSG_DONTWAIT);
981} 934}
982 935
983static int __net_init nl_fib_lookup_init(struct net *net) 936static int __net_init nl_fib_lookup_init(struct net *net)
984{ 937{
985 struct sock *sk; 938 struct sock *sk;
986 struct netlink_kernel_cfg cfg = { 939 sk = netlink_kernel_create(net, NETLINK_FIB_LOOKUP, 0,
987 .input = nl_fib_input, 940 nl_fib_input, NULL, THIS_MODULE);
988 };
989
990 sk = netlink_kernel_create(net, NETLINK_FIB_LOOKUP, &cfg);
991 if (sk == NULL) 941 if (sk == NULL)
992 return -EAFNOSUPPORT; 942 return -EAFNOSUPPORT;
993 net->ipv4.fibnl = sk; 943 net->ipv4.fibnl = sk;
@@ -1000,11 +950,11 @@ static void nl_fib_lookup_exit(struct net *net)
1000 net->ipv4.fibnl = NULL; 950 net->ipv4.fibnl = NULL;
1001} 951}
1002 952
1003static void fib_disable_ip(struct net_device *dev, int force) 953static void fib_disable_ip(struct net_device *dev, int force, int delay)
1004{ 954{
1005 if (fib_sync_down_dev(dev, force)) 955 if (fib_sync_down_dev(dev, force))
1006 fib_flush(dev_net(dev)); 956 fib_flush(dev_net(dev));
1007 rt_cache_flush(dev_net(dev)); 957 rt_cache_flush(dev_net(dev), delay);
1008 arp_ifdown(dev); 958 arp_ifdown(dev);
1009} 959}
1010 960
@@ -1021,7 +971,7 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event,
1021 fib_sync_up(dev); 971 fib_sync_up(dev);
1022#endif 972#endif
1023 atomic_inc(&net->ipv4.dev_addr_genid); 973 atomic_inc(&net->ipv4.dev_addr_genid);
1024 rt_cache_flush(dev_net(dev)); 974 rt_cache_flush(dev_net(dev), -1);
1025 break; 975 break;
1026 case NETDEV_DOWN: 976 case NETDEV_DOWN:
1027 fib_del_ifaddr(ifa, NULL); 977 fib_del_ifaddr(ifa, NULL);
@@ -1030,9 +980,9 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event,
1030 /* Last address was deleted from this interface. 980 /* Last address was deleted from this interface.
1031 * Disable IP. 981 * Disable IP.
1032 */ 982 */
1033 fib_disable_ip(dev, 1); 983 fib_disable_ip(dev, 1, 0);
1034 } else { 984 } else {
1035 rt_cache_flush(dev_net(dev)); 985 rt_cache_flush(dev_net(dev), -1);
1036 } 986 }
1037 break; 987 break;
1038 } 988 }
@@ -1042,16 +992,16 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event,
1042static int fib_netdev_event(struct notifier_block *this, unsigned long event, void *ptr) 992static int fib_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
1043{ 993{
1044 struct net_device *dev = ptr; 994 struct net_device *dev = ptr;
1045 struct in_device *in_dev; 995 struct in_device *in_dev = __in_dev_get_rtnl(dev);
1046 struct net *net = dev_net(dev); 996 struct net *net = dev_net(dev);
1047 997
1048 if (event == NETDEV_UNREGISTER) { 998 if (event == NETDEV_UNREGISTER) {
1049 fib_disable_ip(dev, 2); 999 fib_disable_ip(dev, 2, -1);
1050 rt_flush_dev(dev);
1051 return NOTIFY_DONE; 1000 return NOTIFY_DONE;
1052 } 1001 }
1053 1002
1054 in_dev = __in_dev_get_rtnl(dev); 1003 if (!in_dev)
1004 return NOTIFY_DONE;
1055 1005
1056 switch (event) { 1006 switch (event) {
1057 case NETDEV_UP: 1007 case NETDEV_UP:
@@ -1062,14 +1012,21 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
1062 fib_sync_up(dev); 1012 fib_sync_up(dev);
1063#endif 1013#endif
1064 atomic_inc(&net->ipv4.dev_addr_genid); 1014 atomic_inc(&net->ipv4.dev_addr_genid);
1065 rt_cache_flush(net); 1015 rt_cache_flush(dev_net(dev), -1);
1066 break; 1016 break;
1067 case NETDEV_DOWN: 1017 case NETDEV_DOWN:
1068 fib_disable_ip(dev, 0); 1018 fib_disable_ip(dev, 0, 0);
1069 break; 1019 break;
1070 case NETDEV_CHANGEMTU: 1020 case NETDEV_CHANGEMTU:
1071 case NETDEV_CHANGE: 1021 case NETDEV_CHANGE:
1072 rt_cache_flush(net); 1022 rt_cache_flush(dev_net(dev), 0);
1023 break;
1024 case NETDEV_UNREGISTER_BATCH:
1025 /* The batch unregister is only called on the first
1026 * device in the list of devices being unregistered.
1027 * Therefore we should not pass dev_net(dev) in here.
1028 */
1029 rt_cache_flush_batch(NULL);
1073 break; 1030 break;
1074 } 1031 }
1075 return NOTIFY_DONE; 1032 return NOTIFY_DONE;
@@ -1134,9 +1091,6 @@ static int __net_init fib_net_init(struct net *net)
1134{ 1091{
1135 int error; 1092 int error;
1136 1093
1137#ifdef CONFIG_IP_ROUTE_CLASSID
1138 net->ipv4.fib_num_tclassid_users = 0;
1139#endif
1140 error = ip_fib_net_init(net); 1094 error = ip_fib_net_init(net);
1141 if (error < 0) 1095 if (error < 0)
1142 goto out; 1096 goto out;