aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2009-12-02 20:25:56 -0500
committerDavid S. Miller <davem@davemloft.net>2009-12-03 15:14:36 -0500
commit1b038a5e60c7812f19818e8a5df96d029e49c38f (patch)
treeeea09368802178a64429beb656a03a2cc71e2f42 /net/core
parent491deb24bf5bf7124141287aaf02c3219783ceab (diff)
net 03/05: fib_rules: add oif classification
commit 68144d350f4f6c348659c825cde6a82b34c27a91 Author: Patrick McHardy <kaber@trash.net> Date: Thu Dec 3 12:05:25 2009 +0100 net: fib_rules: add oif classification Support routing table lookup based on the flow's oif. This is useful to classify packets originating from sockets bound to interfaces differently. The route cache already includes the oif and needs no changes. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/fib_rules.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c
index 8e8028cdc87f..d1a70ad4b544 100644
--- a/net/core/fib_rules.c
+++ b/net/core/fib_rules.c
@@ -138,6 +138,9 @@ static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops,
138 if (rule->iifindex && (rule->iifindex != fl->iif)) 138 if (rule->iifindex && (rule->iifindex != fl->iif))
139 goto out; 139 goto out;
140 140
141 if (rule->oifindex && (rule->oifindex != fl->oif))
142 goto out;
143
141 if ((rule->mark ^ fl->mark) & rule->mark_mask) 144 if ((rule->mark ^ fl->mark) & rule->mark_mask)
142 goto out; 145 goto out;
143 146
@@ -258,6 +261,16 @@ static int fib_nl_newrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
258 rule->iifindex = dev->ifindex; 261 rule->iifindex = dev->ifindex;
259 } 262 }
260 263
264 if (tb[FRA_OIFNAME]) {
265 struct net_device *dev;
266
267 rule->oifindex = -1;
268 nla_strlcpy(rule->oifname, tb[FRA_OIFNAME], IFNAMSIZ);
269 dev = __dev_get_by_name(net, rule->oifname);
270 if (dev)
271 rule->oifindex = dev->ifindex;
272 }
273
261 if (tb[FRA_FWMARK]) { 274 if (tb[FRA_FWMARK]) {
262 rule->mark = nla_get_u32(tb[FRA_FWMARK]); 275 rule->mark = nla_get_u32(tb[FRA_FWMARK]);
263 if (rule->mark) 276 if (rule->mark)
@@ -392,6 +405,10 @@ static int fib_nl_delrule(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
392 nla_strcmp(tb[FRA_IIFNAME], rule->iifname)) 405 nla_strcmp(tb[FRA_IIFNAME], rule->iifname))
393 continue; 406 continue;
394 407
408 if (tb[FRA_OIFNAME] &&
409 nla_strcmp(tb[FRA_OIFNAME], rule->oifname))
410 continue;
411
395 if (tb[FRA_FWMARK] && 412 if (tb[FRA_FWMARK] &&
396 (rule->mark != nla_get_u32(tb[FRA_FWMARK]))) 413 (rule->mark != nla_get_u32(tb[FRA_FWMARK])))
397 continue; 414 continue;
@@ -448,6 +465,7 @@ static inline size_t fib_rule_nlmsg_size(struct fib_rules_ops *ops,
448{ 465{
449 size_t payload = NLMSG_ALIGN(sizeof(struct fib_rule_hdr)) 466 size_t payload = NLMSG_ALIGN(sizeof(struct fib_rule_hdr))
450 + nla_total_size(IFNAMSIZ) /* FRA_IIFNAME */ 467 + nla_total_size(IFNAMSIZ) /* FRA_IIFNAME */
468 + nla_total_size(IFNAMSIZ) /* FRA_OIFNAME */
451 + nla_total_size(4) /* FRA_PRIORITY */ 469 + nla_total_size(4) /* FRA_PRIORITY */
452 + nla_total_size(4) /* FRA_TABLE */ 470 + nla_total_size(4) /* FRA_TABLE */
453 + nla_total_size(4) /* FRA_FWMARK */ 471 + nla_total_size(4) /* FRA_FWMARK */
@@ -488,6 +506,13 @@ static int fib_nl_fill_rule(struct sk_buff *skb, struct fib_rule *rule,
488 frh->flags |= FIB_RULE_IIF_DETACHED; 506 frh->flags |= FIB_RULE_IIF_DETACHED;
489 } 507 }
490 508
509 if (rule->oifname[0]) {
510 NLA_PUT_STRING(skb, FRA_OIFNAME, rule->oifname);
511
512 if (rule->oifindex == -1)
513 frh->flags |= FIB_RULE_OIF_DETACHED;
514 }
515
491 if (rule->pref) 516 if (rule->pref)
492 NLA_PUT_U32(skb, FRA_PRIORITY, rule->pref); 517 NLA_PUT_U32(skb, FRA_PRIORITY, rule->pref);
493 518
@@ -603,6 +628,9 @@ static void attach_rules(struct list_head *rules, struct net_device *dev)
603 if (rule->iifindex == -1 && 628 if (rule->iifindex == -1 &&
604 strcmp(dev->name, rule->iifname) == 0) 629 strcmp(dev->name, rule->iifname) == 0)
605 rule->iifindex = dev->ifindex; 630 rule->iifindex = dev->ifindex;
631 if (rule->oifindex == -1 &&
632 strcmp(dev->name, rule->oifname) == 0)
633 rule->oifindex = dev->ifindex;
606 } 634 }
607} 635}
608 636
@@ -610,9 +638,12 @@ static void detach_rules(struct list_head *rules, struct net_device *dev)
610{ 638{
611 struct fib_rule *rule; 639 struct fib_rule *rule;
612 640
613 list_for_each_entry(rule, rules, list) 641 list_for_each_entry(rule, rules, list) {
614 if (rule->iifindex == dev->ifindex) 642 if (rule->iifindex == dev->ifindex)
615 rule->iifindex = -1; 643 rule->iifindex = -1;
644 if (rule->oifindex == dev->ifindex)
645 rule->oifindex = -1;
646 }
616} 647}
617 648
618 649