diff options
author | Sachin Saxena <sachin.saxena@freescale.com> | 2013-04-15 09:53:06 (GMT) |
---|---|---|
committer | Fleming Andrew-AFLEMING <AFLEMING@freescale.com> | 2013-04-16 22:40:26 (GMT) |
commit | 2559f18bc5045d73e120556d4127496407125a25 (patch) | |
tree | 41853e4b95e1f9f413c43919373a0f65d9d91fe6 /net/ipv6/netfilter/ip6_tables.c | |
parent | 107eeafdd3d8dd59d4c493460902ce5d79269068 (diff) | |
download | linux-fsl-qoriq-2559f18bc5045d73e120556d4127496407125a25.tar.xz |
ASF_QOS: Adding Hooks to offload Marking Rules.
- Support added to offload both Rules via iptables &ip6tables tool
- Only MANGLE table supported with POSTROUTING Hook.
Signed-off-by: Sachin Saxena <sachin.saxena@freescale.com>
CQ ID : ENGR00253307
Change-Id: I4df4245091ef0e195e058dce4fb611b04746061c
Reviewed-on: http://git.am.freescale.net:8181/1346
Reviewed-by: Gupta Rajan-B15745 <rajan.gupta@freescale.com>
Tested-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com>
Reviewed-by: Fleming Andrew-AFLEMING <AFLEMING@freescale.com>
Diffstat (limited to 'net/ipv6/netfilter/ip6_tables.c')
-rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 84d9931..f90992e 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c @@ -62,6 +62,18 @@ MODULE_DESCRIPTION("IPv6 packet filter"); #define static #define inline #endif +#ifdef CONFIG_ASF_INGRESS_MARKER +marker_add_hook *marker_v6_add_fn; +marker_flush_hook *marker_v6_flush_fn; + +void marker_v6_hook_fn_register(marker_add_hook *add, + marker_flush_hook *flush) +{ + marker_v6_add_fn = add; + marker_v6_flush_fn = flush; +} +EXPORT_SYMBOL(marker_v6_hook_fn_register); +#endif void *ip6t_alloc_initial_table(const struct xt_table *info) { @@ -876,6 +888,70 @@ translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0, memcpy(newinfo->entries[i], entry0, newinfo->size); } +#ifdef CONFIG_ASF_INGRESS_MARKER + /* Rules has been verified now safe to offload to ASF */ + if (marker_v6_add_fn && (0 == strcmp(repl->name, "mangle"))) { + struct xt_entry_match *m; + struct xt_entry_target *t; + markerRule_t rules[MAX_MARKER_RULES] = {}; + uint16_t *sport, *dport; + uint32_t num = 0; + + /* Whether It is FLUSH request ? */ + /* Note: num_entries are always equals to num_counters +1, when adding Rules + while num_entries comes as '6' as default value when FLUSH is required */ + if ((repl->num_entries == 6) && (repl->num_entries < repl->num_counters)) { + if (marker_v6_flush_fn) + marker_v6_flush_fn(); + return ret; + } + xt_entry_foreach(iter, entry0, newinfo->size) + { + /* Only POSTROUTING CHAINS */ + if (iter->comefrom != (0x1 << NF_INET_POST_ROUTING)) + continue; + if ((iter->ipv6.proto != 17/*UDP */) && (iter->ipv6.proto != 6/*TCP */)) + continue; + + if (num == MAX_MARKER_RULES) { + printk(KERN_INFO "Maximum %d Rule permitted\n", + MAX_MARKER_RULES); + break; + } + m = (void *)iter + sizeof(struct ip6t_entry); + t = (void *)iter + iter->target_offset; + if (0 != strcmp(t->u.kernel.target->name, "DSCP")) + continue; + + rules[num].src_ip[0] = iter->ipv6.src.in6_u.u6_addr32[0]; + rules[num].src_ip[1] = iter->ipv6.src.in6_u.u6_addr32[1]; + rules[num].src_ip[2] = iter->ipv6.src.in6_u.u6_addr32[2]; + rules[num].src_ip[3] = iter->ipv6.src.in6_u.u6_addr32[3]; + rules[num].dst_ip[0] = iter->ipv6.dst.in6_u.u6_addr32[0]; + rules[num].dst_ip[1] = iter->ipv6.dst.in6_u.u6_addr32[1]; + rules[num].dst_ip[2] = iter->ipv6.dst.in6_u.u6_addr32[2]; + rules[num].dst_ip[3] = iter->ipv6.dst.in6_u.u6_addr32[3]; + rules[num].proto = iter->ipv6.proto; + /* We are passing Port Mask instead of Value , since mask = value. + But when Port are not configured, we get 0xFFFF to indicate that + ANY port value is accepted. */ + sport = (uint16_t *)&m->data[2]; + dport = (uint16_t *)&m->data[6]; + rules[num].src_port = *sport; + rules[num].dst_port = *dport; + rules[num].uciDscp = (t->data[0] << 2); + + num++; + } + if (num > 0) { + marker_db_t arg; + + arg.rule = &rules[0]; + arg.num_rules = num; + marker_v6_add_fn(&arg); + } + } +#endif return ret; } |