00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
#include <linux/config.h>
00023
#include <asm/uaccess.h>
00024
#include <asm/system.h>
00025
#include <asm/bitops.h>
00026
#include <linux/types.h>
00027
#include <linux/kernel.h>
00028
#include <linux/sched.h>
00029
#include <linux/mm.h>
00030
#include <linux/string.h>
00031
#include <linux/socket.h>
00032
#include <linux/sockios.h>
00033
#include <linux/errno.h>
00034
#include <linux/in.h>
00035
#include <linux/inet.h>
00036
#include <linux/netdevice.h>
00037
#include <linux/if_arp.h>
00038
#include <linux/proc_fs.h>
00039
#include <linux/skbuff.h>
00040
#include <linux/netlink.h>
00041
#include <linux/init.h>
00042
00043
#include <net/ip.h>
00044
#include <net/protocol.h>
00045
#include <net/route.h>
00046
#include <net/tcp.h>
00047
#include <net/sock.h>
00048
#include <net/ip_fib.h>
00049
00050 #define FRprintk(a...)
00051
00052 struct fib_rule
00053 {
00054 struct fib_rule *
r_next;
00055 atomic_t
r_clntref;
00056 u32
r_preference;
00057 unsigned char r_table;
00058 unsigned char r_action;
00059 unsigned char r_dst_len;
00060 unsigned char r_src_len;
00061 u32
r_src;
00062 u32
r_srcmask;
00063 u32
r_dst;
00064 u32
r_dstmask;
00065 u32
r_srcmap;
00066 u8
r_flags;
00067 u8
r_tos;
00068
#ifdef CONFIG_IP_ROUTE_FWMARK
00069
u32 r_fwmark;
00070
#endif
00071 int r_ifindex;
00072
#ifdef CONFIG_NET_CLS_ROUTE
00073
__u32 r_tclassid;
00074
#endif
00075 char r_ifname[IFNAMSIZ];
00076 int r_dead;
00077 };
00078
00079 static struct fib_rule default_rule = {
00080 r_clntref: ATOMIC_INIT(2),
00081 r_preference: 0x7FFF,
00082 r_table: RT_TABLE_DEFAULT,
00083 r_action: RTN_UNICAST,
00084 };
00085
00086 static struct fib_rule main_rule = {
00087 r_next: &
default_rule,
00088 r_clntref: ATOMIC_INIT(2),
00089 r_preference: 0x7FFE,
00090 r_table: RT_TABLE_MAIN,
00091 r_action: RTN_UNICAST,
00092 };
00093
00094 static struct fib_rule local_rule = {
00095 r_next: &
main_rule,
00096 r_clntref: ATOMIC_INIT(2),
00097 r_table: RT_TABLE_LOCAL,
00098 r_action: RTN_UNICAST,
00099 };
00100
00101 static struct fib_rule *
fib_rules = &
local_rule;
00102 static rwlock_t
fib_rules_lock = RW_LOCK_UNLOCKED;
00103
00104 int inet_rtm_delrule(
struct sk_buff *skb,
struct nlmsghdr* nlh,
void *arg)
00105 {
00106
struct rtattr **rta = arg;
00107
struct rtmsg *rtm =
NLMSG_DATA(nlh);
00108
struct fib_rule *r, **rp;
00109
int err = -ESRCH;
00110
00111
for (rp=&
fib_rules; (r=*rp) != NULL; rp=&r->
r_next) {
00112
if ((!rta[RTA_SRC-1] || memcmp(RTA_DATA(rta[RTA_SRC-1]), &r->r_src, 4) == 0) &&
00113 rtm->rtm_src_len == r->r_src_len &&
00114 rtm->rtm_dst_len == r->r_dst_len &&
00115 (!rta[RTA_DST-1] || memcmp(RTA_DATA(rta[RTA_DST-1]), &r->r_dst, 4) == 0) &&
00116 rtm->rtm_tos == r->r_tos &&
00117
#ifdef CONFIG_IP_ROUTE_FWMARK
00118
(!rta[RTA_PROTOINFO-1] || memcmp(RTA_DATA(rta[RTA_PROTOINFO-1]), &r->r_fwmark, 4) == 0) &&
00119
#endif
00120
(!rtm->rtm_type || rtm->rtm_type == r->r_action) &&
00121 (!rta[RTA_PRIORITY-1] || memcmp(RTA_DATA(rta[RTA_PRIORITY-1]), &r->r_preference, 4) == 0) &&
00122 (!rta[RTA_IIF-1] || strcmp(RTA_DATA(rta[RTA_IIF-1]), r->r_ifname) == 0) &&
00123 (!rtm->rtm_table || (r && rtm->rtm_table == r->r_table))) {
00124 err = -EPERM;
00125
if (r == &
local_rule)
00126
break;
00127
00128 write_lock_bh(&
fib_rules_lock);
00129 *rp = r->r_next;
00130 r->r_dead = 1;
00131 write_unlock_bh(&
fib_rules_lock);
00132
fib_rule_put(r);
00133 err = 0;
00134
break;
00135 }
00136 }
00137
return err;
00138 }
00139
00140
00141
00142 static struct fib_table *
fib_empty_table(
void)
00143 {
00144
int id;
00145
00146
for (
id = 1;
id <= RT_TABLE_MAX;
id++)
00147
if (fib_tables[
id] == NULL)
00148
return __fib_new_table(
id);
00149
return NULL;
00150 }
00151
00152 void fib_rule_put(
struct fib_rule *r)
00153 {
00154
if (atomic_dec_and_test(&r->
r_clntref)) {
00155
if (r->
r_dead)
00156 kfree(r);
00157
else
00158 printk(
"Freeing alive rule %p\n", r);
00159 }
00160 }
00161
00162 int inet_rtm_newrule(
struct sk_buff *skb,
struct nlmsghdr* nlh,
void *arg)
00163 {
00164
struct rtattr **rta = arg;
00165
struct rtmsg *rtm =
NLMSG_DATA(nlh);
00166
struct fib_rule *r, *new_r, **rp;
00167
unsigned char table_id;
00168
00169
if (rtm->rtm_src_len > 32 || rtm->rtm_dst_len > 32 ||
00170 (rtm->rtm_tos & ~
IPTOS_TOS_MASK))
00171
return -EINVAL;
00172
00173
if (rta[RTA_IIF-1] && RTA_PAYLOAD(rta[RTA_IIF-1]) > IFNAMSIZ)
00174
return -EINVAL;
00175
00176 table_id = rtm->rtm_table;
00177
if (table_id == RT_TABLE_UNSPEC) {
00178
struct fib_table *table;
00179
if (rtm->rtm_type == RTN_UNICAST || rtm->rtm_type == RTN_NAT) {
00180
if ((table =
fib_empty_table()) == NULL)
00181
return -ENOBUFS;
00182 table_id = table->tb_id;
00183 }
00184 }
00185
00186 new_r = kmalloc(
sizeof(*new_r), GFP_KERNEL);
00187
if (!new_r)
00188
return -ENOMEM;
00189 memset(new_r, 0,
sizeof(*new_r));
00190
if (rta[RTA_SRC-1])
00191 memcpy(&new_r->r_src, RTA_DATA(rta[RTA_SRC-1]), 4);
00192
if (rta[RTA_DST-1])
00193 memcpy(&new_r->r_dst, RTA_DATA(rta[RTA_DST-1]), 4);
00194
if (rta[RTA_GATEWAY-1])
00195 memcpy(&new_r->r_srcmap, RTA_DATA(rta[RTA_GATEWAY-1]), 4);
00196 new_r->r_src_len = rtm->rtm_src_len;
00197 new_r->r_dst_len = rtm->rtm_dst_len;
00198 new_r->r_srcmask =
inet_make_mask(rtm->rtm_src_len);
00199 new_r->r_dstmask =
inet_make_mask(rtm->rtm_dst_len);
00200 new_r->r_tos = rtm->rtm_tos;
00201
#ifdef CONFIG_IP_ROUTE_FWMARK
00202
if (rta[RTA_PROTOINFO-1])
00203 memcpy(&new_r->r_fwmark, RTA_DATA(rta[RTA_PROTOINFO-1]), 4);
00204
#endif
00205
new_r->r_action = rtm->rtm_type;
00206 new_r->r_flags = rtm->rtm_flags;
00207
if (rta[RTA_PRIORITY-1])
00208 memcpy(&new_r->r_preference, RTA_DATA(rta[RTA_PRIORITY-1]), 4);
00209 new_r->r_table = table_id;
00210
if (rta[RTA_IIF-1]) {
00211
struct net_device *dev;
00212 memcpy(new_r->r_ifname, RTA_DATA(rta[RTA_IIF-1]), IFNAMSIZ);
00213 new_r->r_ifname[IFNAMSIZ-1] = 0;
00214 new_r->r_ifindex = -1;
00215 dev =
__dev_get_by_name(new_r->r_ifname);
00216
if (dev)
00217 new_r->r_ifindex = dev->ifindex;
00218 }
00219
#ifdef CONFIG_NET_CLS_ROUTE
00220
if (rta[RTA_FLOW-1])
00221 memcpy(&new_r->r_tclassid, RTA_DATA(rta[RTA_FLOW-1]), 4);
00222
#endif
00223
00224 rp = &
fib_rules;
00225
if (!new_r->r_preference) {
00226 r =
fib_rules;
00227
if (r && (r = r->r_next) != NULL) {
00228 rp = &
fib_rules->
r_next;
00229
if (r->r_preference)
00230 new_r->
r_preference = r->r_preference - 1;
00231 }
00232 }
00233
00234
while ( (r = *rp) != NULL ) {
00235
if (r->r_preference > new_r->r_preference)
00236
break;
00237 rp = &r->r_next;
00238 }
00239
00240 new_r->r_next = r;
00241 atomic_inc(&new_r->r_clntref);
00242 write_lock_bh(&
fib_rules_lock);
00243 *rp = new_r;
00244 write_unlock_bh(&
fib_rules_lock);
00245
return 0;
00246 }
00247
00248 u32
fib_rules_map_destination(u32 daddr,
struct fib_result *res)
00249 {
00250 u32 mask =
inet_make_mask(res->
prefixlen);
00251
return (daddr&~mask)|res->
fi->
fib_nh->
nh_gw;
00252 }
00253
00254 u32
fib_rules_policy(u32 saddr,
struct fib_result *res,
unsigned *flags)
00255 {
00256
struct fib_rule *r = res->r;
00257
00258
if (r->r_action == RTN_NAT) {
00259
int addrtype =
inet_addr_type(r->r_srcmap);
00260
00261
if (addrtype == RTN_NAT) {
00262
00263 saddr = (saddr&~r->r_srcmask)|r->r_srcmap;
00264 *flags |= RTCF_SNAT;
00265 }
else if (addrtype == RTN_LOCAL || r->r_srcmap == 0) {
00266
00267 saddr = r->r_srcmap;
00268 *flags |= RTCF_MASQ;
00269 }
00270 }
00271
return saddr;
00272 }
00273
00274
#ifdef CONFIG_NET_CLS_ROUTE
00275
u32 fib_rules_tclass(
struct fib_result *res)
00276 {
00277
if (res->r)
00278
return res->r->r_tclassid;
00279
return 0;
00280 }
00281
#endif
00282
00283
00284 static void fib_rules_detach(
struct net_device *dev)
00285 {
00286
struct fib_rule *r;
00287
00288
for (r=
fib_rules; r; r=r->
r_next) {
00289
if (r->r_ifindex == dev->
ifindex) {
00290 write_lock_bh(&
fib_rules_lock);
00291 r->r_ifindex = -1;
00292 write_unlock_bh(&
fib_rules_lock);
00293 }
00294 }
00295 }
00296
00297 static void fib_rules_attach(
struct net_device *dev)
00298 {
00299
struct fib_rule *r;
00300
00301
for (r=
fib_rules; r; r=r->
r_next) {
00302
if (r->r_ifindex == -1 && strcmp(dev->
name, r->r_ifname) == 0) {
00303 write_lock_bh(&
fib_rules_lock);
00304 r->r_ifindex = dev->
ifindex;
00305 write_unlock_bh(&
fib_rules_lock);
00306 }
00307 }
00308 }
00309
00310 int fib_lookup(
const struct rt_key *key,
struct fib_result *res)
00311 {
00312
int err;
00313
struct fib_rule *r, *policy;
00314
struct fib_table *tb;
00315
00316 u32 daddr = key->
dst;
00317 u32 saddr = key->
src;
00318
00319
FRprintk(
"Lookup: %u.%u.%u.%u <- %u.%u.%u.%u ",
00320 NIPQUAD(key->
dst), NIPQUAD(key->
src));
00321 read_lock(&
fib_rules_lock);
00322
for (r =
fib_rules; r; r=r->
r_next) {
00323
if (((saddr^r->r_src) & r->r_srcmask) ||
00324 ((daddr^r->r_dst) & r->r_dstmask) ||
00325
#ifdef CONFIG_IP_ROUTE_TOS
00326
(r->r_tos && r->r_tos != key->
tos) ||
00327
#endif
00328
#ifdef CONFIG_IP_ROUTE_FWMARK
00329
(r->r_fwmark && r->r_fwmark != key->fwmark) ||
00330
#endif
00331
(r->r_ifindex && r->r_ifindex != key->
iif))
00332
continue;
00333
00334
FRprintk(
"tb %d r %d ", r->r_table, r->r_action);
00335
switch (r->r_action) {
00336
case RTN_UNICAST:
00337
case RTN_NAT:
00338 policy = r;
00339
break;
00340
case RTN_UNREACHABLE:
00341 read_unlock(&
fib_rules_lock);
00342
return -ENETUNREACH;
00343
default:
00344
case RTN_BLACKHOLE:
00345 read_unlock(&
fib_rules_lock);
00346
return -EINVAL;
00347
case RTN_PROHIBIT:
00348 read_unlock(&
fib_rules_lock);
00349
return -EACCES;
00350 }
00351
00352
if ((tb =
fib_get_table(r->r_table)) == NULL)
00353
continue;
00354 err = tb->tb_lookup(tb, key, res);
00355
if (err == 0) {
00356 res->r = policy;
00357
if (policy)
00358 atomic_inc(&policy->r_clntref);
00359 read_unlock(&
fib_rules_lock);
00360
return 0;
00361 }
00362
if (err < 0 && err != -EAGAIN) {
00363 read_unlock(&
fib_rules_lock);
00364
return err;
00365 }
00366 }
00367
FRprintk(
"FAILURE\n");
00368 read_unlock(&
fib_rules_lock);
00369
return -ENETUNREACH;
00370 }
00371
00372 void fib_select_default(
const struct rt_key *key,
struct fib_result *res)
00373 {
00374
if (res->r && res->r->r_action == RTN_UNICAST &&
00375
FIB_RES_GW(*res) &&
FIB_RES_NH(*res).nh_scope == RT_SCOPE_LINK) {
00376
struct fib_table *tb;
00377
if ((tb =
fib_get_table(res->r->r_table)) != NULL)
00378 tb->tb_select_default(tb, key, res);
00379 }
00380 }
00381
00382 static int fib_rules_event(
struct notifier_block *
this,
unsigned long event,
void *ptr)
00383 {
00384
struct net_device *dev = ptr;
00385
00386
if (event == NETDEV_UNREGISTER)
00387
fib_rules_detach(dev);
00388
else if (event == NETDEV_REGISTER)
00389
fib_rules_attach(dev);
00390
return NOTIFY_DONE;
00391 }
00392
00393
00394 struct notifier_block
fib_rules_notifier = {
00395 notifier_call:
fib_rules_event,
00396 };
00397
00398 static __inline__
int inet_fill_rule(
struct sk_buff *skb,
00399
struct fib_rule *r,
00400
struct netlink_callback *cb)
00401 {
00402
struct rtmsg *rtm;
00403
struct nlmsghdr *nlh;
00404
unsigned char *b = skb->
tail;
00405
00406 nlh =
NLMSG_PUT(skb,
NETLINK_CREDS(cb->
skb)->pid, cb->
nlh->
nlmsg_seq, RTM_NEWRULE,
sizeof(*rtm));
00407 rtm =
NLMSG_DATA(nlh);
00408 rtm->rtm_family = AF_INET;
00409 rtm->rtm_dst_len = r->
r_dst_len;
00410 rtm->rtm_src_len = r->
r_src_len;
00411 rtm->rtm_tos = r->
r_tos;
00412
#ifdef CONFIG_IP_ROUTE_FWMARK
00413
if (r->r_fwmark)
00414 RTA_PUT(skb, RTA_PROTOINFO, 4, &r->r_fwmark);
00415
#endif
00416
rtm->rtm_table = r->
r_table;
00417 rtm->rtm_protocol = 0;
00418 rtm->rtm_scope = 0;
00419 rtm->rtm_type = r->
r_action;
00420 rtm->rtm_flags = r->
r_flags;
00421
00422
if (r->
r_dst_len)
00423 RTA_PUT(skb, RTA_DST, 4, &r->
r_dst);
00424
if (r->
r_src_len)
00425 RTA_PUT(skb, RTA_SRC, 4, &r->
r_src);
00426
if (r->
r_ifname[0])
00427 RTA_PUT(skb, RTA_IIF, IFNAMSIZ, &r->
r_ifname);
00428
if (r->
r_preference)
00429 RTA_PUT(skb, RTA_PRIORITY, 4, &r->
r_preference);
00430
if (r->
r_srcmap)
00431 RTA_PUT(skb, RTA_GATEWAY, 4, &r->
r_srcmap);
00432
#ifdef CONFIG_NET_CLS_ROUTE
00433
if (r->r_tclassid)
00434 RTA_PUT(skb, RTA_FLOW, 4, &r->r_tclassid);
00435
#endif
00436
nlh->nlmsg_len = skb->
tail - b;
00437
return skb->
len;
00438
00439 nlmsg_failure:
00440 rtattr_failure:
00441
skb_put(skb, b - skb->
tail);
00442
return -1;
00443 }
00444
00445 int inet_dump_rules(
struct sk_buff *skb,
struct netlink_callback *cb)
00446 {
00447
int idx;
00448
int s_idx = cb->
args[0];
00449
struct fib_rule *r;
00450
00451 read_lock(&
fib_rules_lock);
00452
for (r=
fib_rules, idx=0; r; r = r->
r_next, idx++) {
00453
if (idx < s_idx)
00454
continue;
00455
if (
inet_fill_rule(skb, r, cb) < 0)
00456
break;
00457 }
00458 read_unlock(&
fib_rules_lock);
00459 cb->
args[0] = idx;
00460
00461
return skb->
len;
00462 }
00463
00464 void __init
fib_rules_init(
void)
00465 {
00466
register_netdevice_notifier(&
fib_rules_notifier);
00467 }