diff options
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/fib_rules.c | 29 |
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 | ||