aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
Diffstat (limited to 'net/core')
-rw-r--r--net/core/fib_rules.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index 6b0e63cacd93..da91bf2e6151 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -119,6 +119,9 @@ int fib_rules_lookup(struct fib_rules_ops *ops, struct flowi *fl,
119 if (rule->ifindex && (rule->ifindex != fl->iif)) 119 if (rule->ifindex && (rule->ifindex != fl->iif))
120 continue; 120 continue;
121 121
122 if ((rule->mark ^ fl->mark) & rule->mark_mask)
123 continue;
124
122 if (!ops->match(rule, fl, flags)) 125 if (!ops->match(rule, fl, flags))
123 continue; 126 continue;
124 127
@@ -179,6 +182,18 @@ int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
179 rule->ifindex = dev->ifindex; 182 rule->ifindex = dev->ifindex;
180 } 183 }
181 184
185 if (tb[FRA_FWMARK]) {
186 rule->mark = nla_get_u32(tb[FRA_FWMARK]);
187 if (rule->mark)
188 /* compatibility: if the mark value is non-zero all bits
189 * are compared unless a mask is explicitly specified.
190 */
191 rule->mark_mask = 0xFFFFFFFF;
192 }
193
194 if (tb[FRA_FWMASK])
195 rule->mark_mask = nla_get_u32(tb[FRA_FWMASK]);
196
182 rule->action = frh->action; 197 rule->action = frh->action;
183 rule->flags = frh->flags; 198 rule->flags = frh->flags;
184 rule->table = frh_get_table(frh, tb); 199 rule->table = frh_get_table(frh, tb);
@@ -250,6 +265,14 @@ int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
250 nla_strcmp(tb[FRA_IFNAME], rule->ifname)) 265 nla_strcmp(tb[FRA_IFNAME], rule->ifname))
251 continue; 266 continue;
252 267
268 if (tb[FRA_FWMARK] &&
269 (rule->mark != nla_get_u32(tb[FRA_FWMARK])))
270 continue;
271
272 if (tb[FRA_FWMASK] &&
273 (rule->mark_mask != nla_get_u32(tb[FRA_FWMASK])))
274 continue;
275
253 if (!ops->compare(rule, frh, tb)) 276 if (!ops->compare(rule, frh, tb))
254 continue; 277 continue;
255 278
@@ -298,6 +321,12 @@ static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule,
298 if (rule->pref) 321 if (rule->pref)
299 NLA_PUT_U32(skb, FRA_PRIORITY, rule->pref); 322 NLA_PUT_U32(skb, FRA_PRIORITY, rule->pref);
300 323
324 if (rule->mark)
325 NLA_PUT_U32(skb, FRA_FWMARK, rule->mark);
326
327 if (rule->mark_mask || rule->mark)
328 NLA_PUT_U32(skb, FRA_FWMASK, rule->mark_mask);
329
301 if (ops->fill(rule, skb, nlh, frh) < 0) 330 if (ops->fill(rule, skb, nlh, frh) < 0)
302 goto nla_put_failure; 331 goto nla_put_failure;
303 332