Main Page | Class List | File List | Class Members | File Members

fib_rules.c File Reference

#include <linux/config.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/bitops.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/socket.h>
#include <linux/sockios.h>
#include <linux/errno.h>
#include <linux/in.h>
#include <linux/inet.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/proc_fs.h>
#include <linux/skbuff.h>
#include <linux/netlink.h>
#include <linux/init.h>
#include <net/ip.h>
#include <net/protocol.h>
#include <net/route.h>
#include <net/tcp.h>
#include <net/sock.h>
#include <net/ip_fib.h>

Go to the source code of this file.

Classes

struct  fib_rule

Defines

#define FRprintk(a...)

Functions

int inet_rtm_delrule (struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
fib_tablefib_empty_table (void)
void fib_rule_put (struct fib_rule *r)
int inet_rtm_newrule (struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
u32 fib_rules_map_destination (u32 daddr, struct fib_result *res)
u32 fib_rules_policy (u32 saddr, struct fib_result *res, unsigned *flags)
void fib_rules_detach (struct net_device *dev)
void fib_rules_attach (struct net_device *dev)
int fib_lookup (const struct rt_key *key, struct fib_result *res)
void fib_select_default (const struct rt_key *key, struct fib_result *res)
int fib_rules_event (struct notifier_block *this, unsigned long event, void *ptr)
__inline__ int inet_fill_rule (struct sk_buff *skb, struct fib_rule *r, struct netlink_callback *cb)
int inet_dump_rules (struct sk_buff *skb, struct netlink_callback *cb)
void __init fib_rules_init (void)

Variables

fib_rule default_rule
fib_rule main_rule
fib_rule local_rule
fib_rulefib_rules = &local_rule
rwlock_t fib_rules_lock = RW_LOCK_UNLOCKED
notifier_block fib_rules_notifier


Define Documentation

#define FRprintk a...   ) 
 

Definition at line 50 of file fib_rules.c.

Referenced by fib_lookup().


Function Documentation

struct fib_table* fib_empty_table void   )  [static]
 

Definition at line 142 of file fib_rules.c.

Referenced by inet_rtm_newrule().

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 }

int fib_lookup const struct rt_key key,
struct fib_result res
 

Definition at line 310 of file fib_rules.c.

References rt_key::dst, fib_get_table(), fib_rules, fib_rules_lock, FRprintk, rt_key::iif, fib_rule::r_next, rt_key::src, and rt_key::tos.

Referenced by fib_check_nh(), fib_validate_source(), ip_do_nat(), ip_route_input_slow(), ip_route_output_slow(), and ip_rt_get_source().

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 }

void fib_rule_put struct fib_rule r  ) 
 

Definition at line 152 of file fib_rules.c.

References fib_rule::r_clntref, and fib_rule::r_dead.

Referenced by fib_res_put(), and inet_rtm_delrule().

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 }

void fib_rules_attach struct net_device dev  )  [static]
 

Definition at line 297 of file fib_rules.c.

References fib_rules, fib_rules_lock, net_device::ifindex, net_device::name, and fib_rule::r_next.

Referenced by fib_rules_event().

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 }

void fib_rules_detach struct net_device dev  )  [static]
 

Definition at line 284 of file fib_rules.c.

References fib_rules, fib_rules_lock, net_device::ifindex, and fib_rule::r_next.

Referenced by fib_rules_event().

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 }

int fib_rules_event struct notifier_block *  this,
unsigned long  event,
void *  ptr
[static]
 

Definition at line 382 of file fib_rules.c.

References fib_rules_attach(), and fib_rules_detach().

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 }

void __init fib_rules_init void   ) 
 

Definition at line 464 of file fib_rules.c.

References fib_rules_notifier, and register_netdevice_notifier().

Referenced by ip_fib_init().

00465 { 00466 register_netdevice_notifier(&fib_rules_notifier); 00467 }

u32 fib_rules_map_destination u32  daddr,
struct fib_result res
 

Definition at line 248 of file fib_rules.c.

References fib_result::fi, fib_info::fib_nh, inet_make_mask(), fib_nh::nh_gw, and fib_result::prefixlen.

Referenced by ip_route_input_slow().

00249 { 00250 u32 mask = inet_make_mask(res->prefixlen); 00251 return (daddr&~mask)|res->fi->fib_nh->nh_gw; 00252 }

u32 fib_rules_policy u32  saddr,
struct fib_result res,
unsigned *  flags
 

Definition at line 254 of file fib_rules.c.

References inet_addr_type().

Referenced by ip_do_nat(), and ip_route_input_slow().

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 /* Packet is from translated source; remember it */ 00263 saddr = (saddr&~r->r_srcmask)|r->r_srcmap; 00264 *flags |= RTCF_SNAT; 00265 } else if (addrtype == RTN_LOCAL || r->r_srcmap == 0) { 00266 /* Packet is from masqueraded source; remember it */ 00267 saddr = r->r_srcmap; 00268 *flags |= RTCF_MASQ; 00269 } 00270 } 00271 return saddr; 00272 }

void fib_select_default const struct rt_key key,
struct fib_result res
 

Definition at line 372 of file fib_rules.c.

References fib_get_table(), FIB_RES_GW, and FIB_RES_NH.

Referenced by ip_route_output_slow().

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 }

int inet_dump_rules struct sk_buff skb,
struct netlink_callback cb
 

Definition at line 445 of file fib_rules.c.

References netlink_callback::args, fib_rules, fib_rules_lock, inet_fill_rule(), sk_buff::len, and fib_rule::r_next.

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 }

__inline__ int inet_fill_rule struct sk_buff skb,
struct fib_rule r,
struct netlink_callback cb
[static]
 

Definition at line 398 of file fib_rules.c.

References sk_buff::len, NETLINK_CREDS, netlink_callback::nlh, NLMSG_DATA, NLMSG_PUT, nlmsghdr::nlmsg_seq, fib_rule::r_action, fib_rule::r_dst, fib_rule::r_dst_len, fib_rule::r_flags, fib_rule::r_ifname, fib_rule::r_preference, fib_rule::r_src, fib_rule::r_src_len, fib_rule::r_srcmap, fib_rule::r_table, fib_rule::r_tos, netlink_callback::skb, skb_put(), and sk_buff::tail.

Referenced by inet_dump_rules().

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 }

int inet_rtm_delrule struct sk_buff skb,
struct nlmsghdr nlh,
void *  arg
 

Definition at line 104 of file fib_rules.c.

References fib_rule_put(), fib_rules, fib_rules_lock, local_rule, NLMSG_DATA, and fib_rule::r_next.

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 }

int inet_rtm_newrule struct sk_buff skb,
struct nlmsghdr nlh,
void *  arg
 

Definition at line 162 of file fib_rules.c.

References __dev_get_by_name(), fib_empty_table(), fib_rules, fib_rules_lock, inet_make_mask(), IPTOS_TOS_MASK, NLMSG_DATA, fib_rule::r_next, and fib_rule::r_preference.

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 }


Variable Documentation

struct fib_rule default_rule [static]
 

Initial value:

{ r_clntref: ATOMIC_INIT(2), r_preference: 0x7FFF, r_table: RT_TABLE_DEFAULT, r_action: RTN_UNICAST, }
Definition at line 79 of file fib_rules.c.

struct fib_rule* fib_rules = &local_rule [static]
 

Definition at line 101 of file fib_rules.c.

Referenced by fib_lookup(), fib_rules_attach(), fib_rules_detach(), inet_dump_rules(), inet_rtm_delrule(), and inet_rtm_newrule().

rwlock_t fib_rules_lock = RW_LOCK_UNLOCKED [static]
 

Definition at line 102 of file fib_rules.c.

Referenced by fib_lookup(), fib_rules_attach(), fib_rules_detach(), inet_dump_rules(), inet_rtm_delrule(), and inet_rtm_newrule().

struct notifier_block fib_rules_notifier
 

Initial value:

{ notifier_call: fib_rules_event, }
Definition at line 394 of file fib_rules.c.

Referenced by fib_rules_init().

struct fib_rule local_rule [static]
 

Initial value:

{ r_next: &main_rule, r_clntref: ATOMIC_INIT(2), r_table: RT_TABLE_LOCAL, r_action: RTN_UNICAST, }
Definition at line 94 of file fib_rules.c.

Referenced by inet_rtm_delrule().

struct fib_rule main_rule [static]
 

Initial value:

{ r_next: &default_rule, r_clntref: ATOMIC_INIT(2), r_preference: 0x7FFE, r_table: RT_TABLE_MAIN, r_action: RTN_UNICAST, }
Definition at line 86 of file fib_rules.c.


Generated on Wed Dec 1 21:25:34 2004 for Linux 2.4.23 Networking by doxygen 1.3.8