diff options
Diffstat (limited to 'net/ipv6/fib6_rules.c')
-rw-r--r-- | net/ipv6/fib6_rules.c | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c index b1108ede18e1..34d244df907d 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c | |||
@@ -29,16 +29,16 @@ struct fib6_rule | |||
29 | u8 tclass; | 29 | u8 tclass; |
30 | }; | 30 | }; |
31 | 31 | ||
32 | struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl, | 32 | struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6, |
33 | int flags, pol_lookup_t lookup) | 33 | int flags, pol_lookup_t lookup) |
34 | { | 34 | { |
35 | struct fib_lookup_arg arg = { | 35 | struct fib_lookup_arg arg = { |
36 | .lookup_ptr = lookup, | 36 | .lookup_ptr = lookup, |
37 | .flags = FIB_LOOKUP_NOREF, | ||
37 | }; | 38 | }; |
38 | 39 | ||
39 | fib_rules_lookup(net->ipv6.fib6_rules_ops, fl, flags, &arg); | 40 | fib_rules_lookup(net->ipv6.fib6_rules_ops, |
40 | if (arg.rule) | 41 | flowi6_to_flowi(fl6), flags, &arg); |
41 | fib_rule_put(arg.rule); | ||
42 | 42 | ||
43 | if (arg.result) | 43 | if (arg.result) |
44 | return arg.result; | 44 | return arg.result; |
@@ -50,6 +50,7 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi *fl, | |||
50 | static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, | 50 | static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, |
51 | int flags, struct fib_lookup_arg *arg) | 51 | int flags, struct fib_lookup_arg *arg) |
52 | { | 52 | { |
53 | struct flowi6 *flp6 = &flp->u.ip6; | ||
53 | struct rt6_info *rt = NULL; | 54 | struct rt6_info *rt = NULL; |
54 | struct fib6_table *table; | 55 | struct fib6_table *table; |
55 | struct net *net = rule->fr_net; | 56 | struct net *net = rule->fr_net; |
@@ -72,7 +73,7 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, | |||
72 | 73 | ||
73 | table = fib6_get_table(net, rule->table); | 74 | table = fib6_get_table(net, rule->table); |
74 | if (table) | 75 | if (table) |
75 | rt = lookup(net, table, flp, flags); | 76 | rt = lookup(net, table, flp6, flags); |
76 | 77 | ||
77 | if (rt != net->ipv6.ip6_null_entry) { | 78 | if (rt != net->ipv6.ip6_null_entry) { |
78 | struct fib6_rule *r = (struct fib6_rule *)rule; | 79 | struct fib6_rule *r = (struct fib6_rule *)rule; |
@@ -87,14 +88,14 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, | |||
87 | 88 | ||
88 | if (ipv6_dev_get_saddr(net, | 89 | if (ipv6_dev_get_saddr(net, |
89 | ip6_dst_idev(&rt->dst)->dev, | 90 | ip6_dst_idev(&rt->dst)->dev, |
90 | &flp->fl6_dst, | 91 | &flp6->daddr, |
91 | rt6_flags2srcprefs(flags), | 92 | rt6_flags2srcprefs(flags), |
92 | &saddr)) | 93 | &saddr)) |
93 | goto again; | 94 | goto again; |
94 | if (!ipv6_prefix_equal(&saddr, &r->src.addr, | 95 | if (!ipv6_prefix_equal(&saddr, &r->src.addr, |
95 | r->src.plen)) | 96 | r->src.plen)) |
96 | goto again; | 97 | goto again; |
97 | ipv6_addr_copy(&flp->fl6_src, &saddr); | 98 | ipv6_addr_copy(&flp6->saddr, &saddr); |
98 | } | 99 | } |
99 | goto out; | 100 | goto out; |
100 | } | 101 | } |
@@ -114,9 +115,10 @@ out: | |||
114 | static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags) | 115 | static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags) |
115 | { | 116 | { |
116 | struct fib6_rule *r = (struct fib6_rule *) rule; | 117 | struct fib6_rule *r = (struct fib6_rule *) rule; |
118 | struct flowi6 *fl6 = &fl->u.ip6; | ||
117 | 119 | ||
118 | if (r->dst.plen && | 120 | if (r->dst.plen && |
119 | !ipv6_prefix_equal(&fl->fl6_dst, &r->dst.addr, r->dst.plen)) | 121 | !ipv6_prefix_equal(&fl6->daddr, &r->dst.addr, r->dst.plen)) |
120 | return 0; | 122 | return 0; |
121 | 123 | ||
122 | /* | 124 | /* |
@@ -126,14 +128,14 @@ static int fib6_rule_match(struct fib_rule *rule, struct flowi *fl, int flags) | |||
126 | */ | 128 | */ |
127 | if (r->src.plen) { | 129 | if (r->src.plen) { |
128 | if (flags & RT6_LOOKUP_F_HAS_SADDR) { | 130 | if (flags & RT6_LOOKUP_F_HAS_SADDR) { |
129 | if (!ipv6_prefix_equal(&fl->fl6_src, &r->src.addr, | 131 | if (!ipv6_prefix_equal(&fl6->saddr, &r->src.addr, |
130 | r->src.plen)) | 132 | r->src.plen)) |
131 | return 0; | 133 | return 0; |
132 | } else if (!(r->common.flags & FIB_RULE_FIND_SADDR)) | 134 | } else if (!(r->common.flags & FIB_RULE_FIND_SADDR)) |
133 | return 0; | 135 | return 0; |
134 | } | 136 | } |
135 | 137 | ||
136 | if (r->tclass && r->tclass != ((ntohl(fl->fl6_flowlabel) >> 20) & 0xff)) | 138 | if (r->tclass && r->tclass != ((ntohl(fl6->flowlabel) >> 20) & 0xff)) |
137 | return 0; | 139 | return 0; |
138 | 140 | ||
139 | return 1; | 141 | return 1; |