summaryrefslogtreecommitdiff
path: root/net/ipv4/netfilter/ip_tables.c
diff options
context:
space:
mode:
authorSachin Saxena <sachin.saxena@freescale.com>2013-04-15 09:53:06 (GMT)
committerFleming Andrew-AFLEMING <AFLEMING@freescale.com>2013-04-16 22:40:26 (GMT)
commit2559f18bc5045d73e120556d4127496407125a25 (patch)
tree41853e4b95e1f9f413c43919373a0f65d9d91fe6 /net/ipv4/netfilter/ip_tables.c
parent107eeafdd3d8dd59d4c493460902ce5d79269068 (diff)
downloadlinux-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/ipv4/netfilter/ip_tables.c')
-rw-r--r--net/ipv4/netfilter/ip_tables.c74
1 files changed, 73 insertions, 1 deletions
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 56a1b72..537b249 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -62,6 +62,19 @@ MODULE_DESCRIPTION("IPv4 packet filter");
#define inline
#endif
+#ifdef CONFIG_ASF_INGRESS_MARKER
+marker_add_hook *marker_add_fn;
+marker_flush_hook *marker_flush_fn;
+
+void marker_v4_hook_fn_register(marker_add_hook *add,
+ marker_flush_hook *flush)
+{
+ marker_add_fn = add;
+ marker_flush_fn = flush;
+}
+EXPORT_SYMBOL(marker_v4_hook_fn_register);
+#endif
+
void *ipt_alloc_initial_table(const struct xt_table *info)
{
return xt_alloc_initial_table(ipt, IPT);
@@ -818,6 +831,7 @@ translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0,
++newinfo->stacksize;
}
+
if (i != repl->num_entries) {
duprintf("translate_table: %u not %u entries\n",
i, repl->num_entries);
@@ -868,6 +882,65 @@ 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_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_flush_fn)
+ marker_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->ip.proto != 17/*UDP */) &&
+ (iter->ip.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 ipt_entry);
+ t = (void *)iter + iter->target_offset;
+ if (0 != strcmp(t->u.kernel.target->name, "DSCP"))
+ continue;
+
+ rules[num].src_ip[0] = iter->ip.src.s_addr;
+ rules[num].dst_ip[0] = iter->ip.dst.s_addr;
+ rules[num].proto = iter->ip.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_add_fn(&arg);
+ }
+ }
+#endif
return ret;
}
@@ -976,7 +1049,6 @@ copy_entries_to_user(unsigned int total_size,
goto free_counters;
}
}
-
t = ipt_get_target_c(e);
if (copy_to_user(userptr + off + e->target_offset
+ offsetof(struct xt_entry_target,