fix connection marking
this commit fixes 3 issues:
1. the mark was being pulled from the skb in the post_routing_hook
regardless of its value, which could be zero.
2. the event parameter of the conntrack event callback was being
incorrectly tested for the IPCT_MARK flag. the following function was
used as an example for how to properly test the flag:
netfilter/nf_conntrack_netlink.c:ctnetlink_conntrack_event.
3. the mark wasn't being pulled from the nfct object during a
conntrack event, which resulted in overwriting a connection's
mark with garbage. now that I think about it, this probably
explains the presence of the mark manipulation code in the
post_routing_hook (issue resolution #1).
Change-Id: I2404bfc4142f79d68bb93400b85cdb2c9f7bc5a8
Signed-off-by: Nicolas Costa <ncosta@codeaurora.org>
diff --git a/fast-classifier/fast-classifier.c b/fast-classifier/fast-classifier.c
index 91db303..968567e 100644
--- a/fast-classifier/fast-classifier.c
+++ b/fast-classifier/fast-classifier.c
@@ -558,10 +558,14 @@
p_sic->dest_port == sic.dest_port &&
p_sic->src_ip == sic.src_ip &&
p_sic->dest_ip == sic.dest_ip ) {
- if (skb->mark) {
+ /* is this really necessary? shouldn't the conntrack
+ callback be sufficient for tracking the conmark?
+ regardless, don't overwrite the sic mark if the
+ skb's mark is zero */
+ if (skb->mark != 0) {
DEBUG_TRACE("UPDATING MARK %x\n", skb->mark);
+ p_sic->mark = skb->mark;
}
- p_sic->mark = skb->mark;
conn->hits++;
@@ -795,29 +799,6 @@
unsigned long flags;
struct fast_classifier_tuple fc_msg;
- if (events & IPCT_MARK) {
- struct sfe_ipv4_mark mark;
- orig_tuple = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
-
- mark.protocol = (int32_t)orig_tuple.dst.protonum;
- mark.src_ip = (__be32)orig_tuple.src.u3.ip;
- mark.dest_ip = (__be32)orig_tuple.dst.u3.ip;
- switch (mark.protocol) {
- case IPPROTO_TCP:
- mark.src_port = orig_tuple.src.u.tcp.port;
- mark.dest_port = orig_tuple.dst.u.tcp.port;
- break;
- case IPPROTO_UDP:
- mark.src_port = orig_tuple.src.u.udp.port;
- mark.dest_port = orig_tuple.dst.u.udp.port;
- break;
- default:
- break;
- }
-
- sfe_ipv4_mark_rule(&mark);
- }
-
/*
* If we don't have a conntrack entry then we're done.
*/
@@ -843,6 +824,33 @@
}
/*
+ * Check for an updated mark
+ */
+ if ((events & (1 << IPCT_MARK)) && (ct->mark != 0)) {
+ struct sfe_ipv4_mark mark;
+ orig_tuple = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
+
+ mark.protocol = (int32_t)orig_tuple.dst.protonum;
+ mark.src_ip = (__be32)orig_tuple.src.u3.ip;
+ mark.dest_ip = (__be32)orig_tuple.dst.u3.ip;
+ switch (mark.protocol) {
+ case IPPROTO_TCP:
+ mark.src_port = orig_tuple.src.u.tcp.port;
+ mark.dest_port = orig_tuple.dst.u.tcp.port;
+ break;
+ case IPPROTO_UDP:
+ mark.src_port = orig_tuple.src.u.udp.port;
+ mark.dest_port = orig_tuple.dst.u.udp.port;
+ break;
+ default:
+ break;
+ }
+
+ mark.mark = ct->mark;
+ sfe_ipv4_mark_rule(&mark);
+ }
+
+ /*
* We're only interested in destroy events at this point
*/
if (unlikely(!(events & (1 << IPCT_DESTROY)))) {