[PATCH] This patch introduces a mask to the fwmark test cases in the advanced routing. This let's one test individual bits of the fwmark to determine how things should be routed (pick a routing table). This patch retains compatibility with tests that do not set the mask by assuming a mask of 0 is equivalent to a mask of 0xffffffff.
Sign-off-by: Michael Richardson <[EMAIL PROTECTED]> --- include/linux/rtnetlink.h | 1 + net/ipv4/fib_rules.c | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) bcdda64a16d4dfda6d95452bbf8541999121831a diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h index 27fd17e..a5b55c2 100644 --- a/include/linux/rtnetlink.h +++ b/include/linux/rtnetlink.h @@ -266,6 +266,7 @@ enum rtattr_type_t }; #define RTA_FWMARK RTA_PROTOINFO +#define RTA_FWMARK_MASK RTA_CACHEINFO #define RTA_MAX (__RTA_MAX - 1) diff --git a/net/ipv4/fib_rules.c b/net/ipv4/fib_rules.c index de327b3..69eed89 100644 --- a/net/ipv4/fib_rules.c +++ b/net/ipv4/fib_rules.c @@ -68,6 +68,7 @@ struct fib_rule u8 r_tos; #ifdef CONFIG_IP_ROUTE_FWMARK u32 r_fwmark; + u32 r_fwmark_mask; #endif int r_ifindex; #ifdef CONFIG_NET_CLS_ROUTE @@ -117,6 +118,7 @@ int inet_rtm_delrule(struct sk_buff *skb rtm->rtm_tos == r->r_tos && #ifdef CONFIG_IP_ROUTE_FWMARK (!rta[RTA_FWMARK-1] || memcmp(RTA_DATA(rta[RTA_FWMARK-1]), &r->r_fwmark, 4) == 0) && + (!rta[RTA_FWMARK_MASK-1] || memcmp(RTA_DATA(rta[RTA_FWMARK_MASK-1]), &r->r_fwmark_mask, 4) == 0) && #endif (!rtm->rtm_type || rtm->rtm_type == r->r_action) && (!rta[RTA_PRIORITY-1] || memcmp(RTA_DATA(rta[RTA_PRIORITY-1]), &r->r_preference, 4) == 0) && @@ -202,6 +204,17 @@ int inet_rtm_newrule(struct sk_buff *skb #ifdef CONFIG_IP_ROUTE_FWMARK if (rta[RTA_FWMARK-1]) memcpy(&new_r->r_fwmark, RTA_DATA(rta[RTA_FWMARK-1]), 4); + if (rta[RTA_FWMARK_MASK-1]) + memcpy(&new_r->r_fwmark_mask, RTA_DATA(rta[RTA_FWMARK_MASK-1]), 4); + /* + * if the user doesn't set a mask, then set it to care about + * all bits. This retains compatibility. Note it is impossible + * to match SOMETHING & 0xMASK == 0, because fwmark==0 means + * do not match fwmark at all. + */ + if(new_r->r_fwmark_mask == 0) { + new_r->r_fwmark_mask = 0xffffffff; + } #endif new_r->r_action = rtm->rtm_type; new_r->r_flags = rtm->rtm_flags; @@ -298,7 +311,7 @@ FRprintk("Lookup: %u.%u.%u.%u <- %u.%u.% ((daddr^r->r_dst) & r->r_dstmask) || (r->r_tos && r->r_tos != flp->fl4_tos) || #ifdef CONFIG_IP_ROUTE_FWMARK - (r->r_fwmark && r->r_fwmark != flp->fl4_fwmark) || + (r->r_fwmark && r->r_fwmark != (flp->fl4_fwmark & r->r_fwmark_mask)) || #endif (r->r_ifindex && r->r_ifindex != flp->iif)) continue; @@ -382,8 +395,10 @@ static __inline__ int inet_fill_rule(str rtm->rtm_src_len = r->r_src_len; rtm->rtm_tos = r->r_tos; #ifdef CONFIG_IP_ROUTE_FWMARK - if (r->r_fwmark) + if (r->r_fwmark) { RTA_PUT(skb, RTA_FWMARK, 4, &r->r_fwmark); + RTA_PUT(skb, RTA_FWMARK_MASK, 4, &r->r_fwmark_mask); + } #endif rtm->rtm_table = r->r_table; rtm->rtm_protocol = 0; --
pgpOP3aSevdbi.pgp
Description: PGP signature