Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 315000
b: refs/heads/master
c: f4530fa
h: refs/heads/master
v: v3
  • Loading branch information
David S. Miller committed Jul 6, 2012
1 parent 96da5e2 commit 2ef8e18
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 17 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 700db99d0140e9da2a31e08ebd3e1b121691aa26
refs/heads/master: f4530fa574df4d833506c53697ed1daa0d390bf4
36 changes: 32 additions & 4 deletions trunk/include/net/ip_fib.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,33 @@ extern void __net_exit fib4_rules_exit(struct net *net);
extern u32 fib_rules_tclass(const struct fib_result *res);
#endif

extern int fib_lookup(struct net *n, struct flowi4 *flp, struct fib_result *res);

extern struct fib_table *fib_new_table(struct net *net, u32 id);
extern struct fib_table *fib_get_table(struct net *net, u32 id);

extern int __fib_lookup(struct net *net, struct flowi4 *flp,
struct fib_result *res);

static inline int fib_lookup(struct net *net, struct flowi4 *flp,
struct fib_result *res)
{
if (!net->ipv4.fib_has_custom_rules) {
if (net->ipv4.fib_local &&
!fib_table_lookup(net->ipv4.fib_local, flp, res,
FIB_LOOKUP_NOREF))
return 0;
if (net->ipv4.fib_main &&
!fib_table_lookup(net->ipv4.fib_main, flp, res,
FIB_LOOKUP_NOREF))
return 0;
if (net->ipv4.fib_default &&
!fib_table_lookup(net->ipv4.fib_default, flp, res,
FIB_LOOKUP_NOREF))
return 0;
return -ENETUNREACH;
}
return __fib_lookup(net, flp, res);
}

#endif /* CONFIG_IP_MULTIPLE_TABLES */

/* Exported by fib_frontend.c */
Expand All @@ -236,9 +258,15 @@ extern int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
struct in_device *idev, u32 *itag);
extern void fib_select_default(struct fib_result *res);
#ifdef CONFIG_IP_ROUTE_CLASSID
extern int fib_num_tclassid_users;
static inline int fib_num_tclassid_users(struct net *net)
{
return net->ipv4.fib_num_tclassid_users;
}
#else
#define fib_num_tclassid_users 0
static inline int fib_num_tclassid_users(struct net *net)
{
return 0;
}
#endif

/* Exported by fib_semantics.c */
Expand Down
8 changes: 8 additions & 0 deletions trunk/include/net/netns/ipv4.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ struct ctl_table_header;
struct ipv4_devconf;
struct fib_rules_ops;
struct hlist_head;
struct fib_table;
struct sock;

struct netns_ipv4 {
Expand All @@ -24,6 +25,13 @@ struct netns_ipv4 {
struct ipv4_devconf *devconf_dflt;
#ifdef CONFIG_IP_MULTIPLE_TABLES
struct fib_rules_ops *rules_ops;
bool fib_has_custom_rules;
struct fib_table *fib_local;
struct fib_table *fib_main;
struct fib_table *fib_default;
#endif
#ifdef CONFIG_IP_ROUTE_CLASSID
int fib_num_tclassid_users;
#endif
struct hlist_head *fib_table_hash;
struct sock *fibnl;
Expand Down
27 changes: 22 additions & 5 deletions trunk/net/ipv4/fib_frontend.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,24 @@ struct fib_table *fib_new_table(struct net *net, u32 id)
tb = fib_trie_table(id);
if (!tb)
return NULL;

switch (id) {
case RT_TABLE_LOCAL:
net->ipv4.fib_local = tb;
break;

case RT_TABLE_MAIN:
net->ipv4.fib_main = tb;
break;

case RT_TABLE_DEFAULT:
net->ipv4.fib_default = tb;
break;

default:
break;
}

h = id & (FIB_TABLE_HASHSZ - 1);
hlist_add_head_rcu(&tb->tb_hlist, &net->ipv4.fib_table_hash[h]);
return tb;
Expand Down Expand Up @@ -218,10 +236,6 @@ __be32 fib_compute_spec_dst(struct sk_buff *skb)
return inet_select_addr(dev, ip_hdr(skb)->saddr, scope);
}

#ifdef CONFIG_IP_ROUTE_CLASSID
int fib_num_tclassid_users __read_mostly;
#endif

/* Given (packet source, input interface) and optional (dst, oif, tos):
* - (main) check, that source is valid i.e. not broadcast or our local
* address.
Expand Down Expand Up @@ -312,7 +326,7 @@ int fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
{
int r = secpath_exists(skb) ? 0 : IN_DEV_RPFILTER(idev);

if (!r && !fib_num_tclassid_users) {
if (!r && !fib_num_tclassid_users(dev_net(dev))) {
*itag = 0;
return 0;
}
Expand Down Expand Up @@ -1134,6 +1148,9 @@ static int __net_init fib_net_init(struct net *net)
{
int error;

#ifdef CONFIG_IP_ROUTE_CLASSID
net->ipv4.fib_num_tclassid_users = 0;
#endif
error = ip_fib_net_init(net);
if (error < 0)
goto out;
Expand Down
12 changes: 8 additions & 4 deletions trunk/net/ipv4/fib_rules.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ u32 fib_rules_tclass(const struct fib_result *res)
}
#endif

int fib_lookup(struct net *net, struct flowi4 *flp, struct fib_result *res)
int __fib_lookup(struct net *net, struct flowi4 *flp, struct fib_result *res)
{
struct fib_lookup_arg arg = {
.result = res,
Expand All @@ -67,7 +67,7 @@ int fib_lookup(struct net *net, struct flowi4 *flp, struct fib_result *res)

return err;
}
EXPORT_SYMBOL_GPL(fib_lookup);
EXPORT_SYMBOL_GPL(__fib_lookup);

static int fib4_rule_action(struct fib_rule *rule, struct flowi *flp,
int flags, struct fib_lookup_arg *arg)
Expand Down Expand Up @@ -172,7 +172,7 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
if (tb[FRA_FLOW]) {
rule4->tclassid = nla_get_u32(tb[FRA_FLOW]);
if (rule4->tclassid)
fib_num_tclassid_users++;
net->ipv4.fib_num_tclassid_users++;
}
#endif

Expand All @@ -182,19 +182,22 @@ static int fib4_rule_configure(struct fib_rule *rule, struct sk_buff *skb,
rule4->dstmask = inet_make_mask(rule4->dst_len);
rule4->tos = frh->tos;

net->ipv4.fib_has_custom_rules = true;
err = 0;
errout:
return err;
}

static void fib4_rule_delete(struct fib_rule *rule)
{
struct net *net = rule->fr_net;
#ifdef CONFIG_IP_ROUTE_CLASSID
struct fib4_rule *rule4 = (struct fib4_rule *) rule;

if (rule4->tclassid)
fib_num_tclassid_users--;
net->ipv4.fib_num_tclassid_users--;
#endif
net->ipv4.fib_has_custom_rules = true;
}

static int fib4_rule_compare(struct fib_rule *rule, struct fib_rule_hdr *frh,
Expand Down Expand Up @@ -309,6 +312,7 @@ int __net_init fib4_rules_init(struct net *net)
if (err < 0)
goto fail;
net->ipv4.rules_ops = ops;
net->ipv4.fib_has_custom_rules = false;
return 0;

fail:
Expand Down
6 changes: 3 additions & 3 deletions trunk/net/ipv4/fib_semantics.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ void free_fib_info(struct fib_info *fi)
#ifdef CONFIG_IP_ROUTE_CLASSID
change_nexthops(fi) {
if (nexthop_nh->nh_tclassid)
fib_num_tclassid_users--;
fi->fib_net->ipv4.fib_num_tclassid_users--;
} endfor_nexthops(fi);
#endif
call_rcu(&fi->rcu, free_fib_info_rcu);
Expand Down Expand Up @@ -428,7 +428,7 @@ static int fib_get_nhs(struct fib_info *fi, struct rtnexthop *rtnh,
nla = nla_find(attrs, attrlen, RTA_FLOW);
nexthop_nh->nh_tclassid = nla ? nla_get_u32(nla) : 0;
if (nexthop_nh->nh_tclassid)
fib_num_tclassid_users++;
fi->fib_net->ipv4.fib_num_tclassid_users++;
#endif
}

Expand Down Expand Up @@ -824,7 +824,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
#ifdef CONFIG_IP_ROUTE_CLASSID
nh->nh_tclassid = cfg->fc_flow;
if (nh->nh_tclassid)
fib_num_tclassid_users++;
fi->fib_net->ipv4.fib_num_tclassid_users++;
#endif
#ifdef CONFIG_IP_ROUTE_MULTIPATH
nh->nh_weight = 1;
Expand Down

0 comments on commit 2ef8e18

Please sign in to comment.