[ULOGD RFC 29/30] NFCT: adapt to new libnetfilter_conntrack

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Short-term solution until using libnl for that.

Signed-off-by: Holger Eitzenberger <holger@xxxxxxxxxxxxxxxx>

Index: ulogd-netfilter/input/flow/ulogd_inpflow_NFCT.c
===================================================================
--- ulogd-netfilter.orig/input/flow/ulogd_inpflow_NFCT.c
+++ ulogd-netfilter/input/flow/ulogd_inpflow_NFCT.c
@@ -84,6 +84,7 @@ struct cache {
 struct nfct_pluginstance {
 	struct nfct_handle *cth;
 	struct ulogd_fd nfct_fd;
+	struct nf_conntrack *nfct_opaque;
 	struct cache *tcache;       /* tuple cache */
 	struct cache *scache;       /* sequence cache */
 	struct ulogd_timer timer;
@@ -795,8 +796,8 @@ scache_cleanup(struct ulogd_pluginstance
 
 static int
 propagate_ct_flow(struct ulogd_pluginstance *upi, 
-				  struct nfct_conntrack *nfct, unsigned int flags,
-				  struct conntrack *ct)
+				  const struct nfct_conntrack *nfct,
+				  const struct conntrack *ct)
 {
 	struct ulogd_key *ret = upi->output.keys;
 
@@ -829,27 +830,21 @@ propagate_ct_flow(struct ulogd_pluginsta
 		break;
 	}
 
-	if (flags & NFCT_COUNTERS_ORIG) {
-		ret[O_RAW_IN_PKTLEN].u.value.ui32 = nfct->counters[ORIG].bytes;
-		ret[O_RAW_IN_PKTLEN].flags |= ULOGD_RETF_VALID;
-		ret[O_RAW_IN_PKTCOUNT].u.value.ui32 = nfct->counters[REPL].packets;
-		ret[O_RAW_IN_PKTCOUNT].flags |= ULOGD_RETF_VALID;
-
-		ret[O_RAW_OUT_PKTLEN].u.value.ui32 = nfct->counters[REPL].bytes;
-		ret[O_RAW_OUT_PKTLEN].flags |= ULOGD_RETF_VALID;
-		ret[O_RAW_OUT_PKTCOUNT].u.value.ui32 = nfct->counters[REPL].packets;
-		ret[O_RAW_OUT_PKTCOUNT].flags |= ULOGD_RETF_VALID;
-	}
+	ret[O_RAW_IN_PKTLEN].u.value.ui32 = nfct->counters[ORIG].bytes;
+	ret[O_RAW_IN_PKTLEN].flags |= ULOGD_RETF_VALID;
+	ret[O_RAW_IN_PKTCOUNT].u.value.ui32 = nfct->counters[ORIG].packets;
+	ret[O_RAW_IN_PKTCOUNT].flags |= ULOGD_RETF_VALID;
+
+	ret[O_RAW_OUT_PKTLEN].u.value.ui32 = nfct->counters[REPL].bytes;
+	ret[O_RAW_OUT_PKTLEN].flags |= ULOGD_RETF_VALID;
+	ret[O_RAW_OUT_PKTCOUNT].u.value.ui32 = nfct->counters[REPL].packets;
+	ret[O_RAW_OUT_PKTCOUNT].flags |= ULOGD_RETF_VALID;
 
-	if (flags & NFCT_MARK) {
-		ret[O_CT_MARK].u.value.ui32 = nfct->mark;
-		ret[O_CT_MARK].flags |= ULOGD_RETF_VALID;
-	}
+	ret[O_CT_MARK].u.value.ui32 = nfct->mark;
+	ret[O_CT_MARK].flags |= ULOGD_RETF_VALID;
 
-	if (flags & NFCT_ID) {
-		ret[O_CT_ID].u.value.ui32 = nfct->id;
-		ret[O_CT_ID].flags |= ULOGD_RETF_VALID;
-	}
+	ret[O_CT_ID].u.value.ui32 = nfct->id;
+	ret[O_CT_ID].flags |= ULOGD_RETF_VALID;
 
 	ret[O_FLOW_START_SEC].u.value.ui32 = ct->time[START].tv_sec;
 	ret[O_FLOW_START_SEC].flags |= ULOGD_RETF_VALID;
@@ -873,8 +868,8 @@ propagate_ct_flow(struct ulogd_pluginsta
 }
 
 static int
-propagate_ct(struct ulogd_pluginstance *upi, struct nfct_conntrack *nfct,
-			 struct conntrack *ct, unsigned int flags)
+propagate_ct(struct ulogd_pluginstance *upi,
+			 struct nfct_conntrack *nfct, struct conntrack *ct)
 {
 	struct nfct_pluginstance *priv = (void *)upi->private;
 
@@ -885,7 +880,7 @@ propagate_ct(struct ulogd_pluginstance *
 
 		ct->time[STOP].tv_sec = t_now_local;
 
-		propagate_ct_flow(upi, nfct, flags, ct);
+		propagate_ct_flow(upi, nfct, ct);
 	} while (0);
 
 	cache_del(priv->tcache, ct);
@@ -893,26 +888,97 @@ propagate_ct(struct ulogd_pluginstance *
 	return 0;
 }
 
+/* nfct_to_conntrack() - translate from opaque type to nfct_conntrack */
+static int
+nfct_to_conntrack(const struct ulogd_pluginstance *pi,
+				  const struct nf_conntrack *ct, struct nfct_conntrack *out)
+{
+	bzero(out, sizeof(struct nfct_conntrack));
+
+	assert(nfct_attr_is_set(ct, ATTR_L3PROTO));
+	out->tuple[ORIG].l3protonum = nfct_get_attr_u8(ct, ATTR_L3PROTO);
+
+	assert(nfct_attr_is_set(ct, ATTR_L4PROTO));
+	out->tuple[ORIG].protonum = nfct_get_attr_u8(ct, ATTR_L4PROTO);
+
+	out->tuple[ORIG].src.v4 = nfct_get_attr_u32(ct, ATTR_IPV4_SRC);
+	out->tuple[REPL].src.v4 = nfct_get_attr_u32(ct, ATTR_REPL_IPV4_SRC);
+	out->tuple[ORIG].dst.v4 = nfct_get_attr_u32(ct, ATTR_IPV4_DST);
+	out->tuple[REPL].dst.v4 = nfct_get_attr_u32(ct, ATTR_REPL_IPV4_DST);
+
+	if (out->tuple[ORIG].l3protonum == IPPROTO_ICMP) {
+		out->tuple[ORIG].l4src.icmp.type
+			= nfct_get_attr_u8(ct, ATTR_ICMP_TYPE);
+		out->tuple[ORIG].l4src.icmp.code
+			= nfct_get_attr_u8(ct, ATTR_ICMP_CODE);
+		out->tuple[ORIG].l4src.icmp.id
+			= nfct_get_attr_u16(ct, ATTR_ICMP_ID);
+	}
+
+	if (out->tuple[ORIG].protonum == IPPROTO_TCP
+		|| out->tuple[ORIG].protonum == IPPROTO_UDP) {
+		assert(nfct_attr_is_set(ct, ATTR_ORIG_PORT_SRC));
+		out->tuple[ORIG].l4src.tcp.port
+			= nfct_get_attr_u16(ct, ATTR_ORIG_PORT_SRC);
+
+		assert(nfct_attr_is_set(ct, ATTR_ORIG_PORT_DST));
+		out->tuple[ORIG].l4dst.tcp.port
+			= nfct_get_attr_u16(ct, ATTR_ORIG_PORT_DST);
+
+		assert(nfct_attr_is_set(ct, ATTR_REPL_PORT_SRC));
+		out->tuple[REPL].l4src.tcp.port
+			= nfct_get_attr_u16(ct, ATTR_REPL_PORT_SRC);
+
+		assert(nfct_attr_is_set(ct, ATTR_REPL_PORT_DST));
+		out->tuple[REPL].l4dst.tcp.port
+			= nfct_get_attr_u16(ct, ATTR_REPL_PORT_DST);
+
+		if (nfct_attr_is_set(ct, ATTR_TCP_STATE))
+			out->protoinfo.tcp.state = nfct_get_attr_u8(ct, ATTR_TCP_STATE);
+	}
+
+	if (nfct_attr_is_set(ct, ATTR_STATUS))
+		out->status = nfct_get_attr_u32(ct, ATTR_STATUS);
+	if (nfct_attr_is_set(ct, ATTR_TIMEOUT))
+		out->timeout = nfct_get_attr_u32(ct, ATTR_TIMEOUT);
+	if (nfct_attr_is_set(ct, ATTR_MARK))
+		out->mark = nfct_get_attr_u32(ct, ATTR_MARK);
+	if (nfct_attr_is_set(ct, ATTR_USE))
+		out->use = nfct_get_attr_u32(ct, ATTR_USE);
+
+	/* counter */
+	if (nfct_attr_is_set(ct, ATTR_ORIG_COUNTER_BYTES))
+		out->counters[ORIG].bytes
+			= nfct_get_attr_u32(ct, ATTR_ORIG_COUNTER_BYTES);
+	if (nfct_attr_is_set(ct, ATTR_ORIG_COUNTER_PACKETS))
+		out->counters[ORIG].packets
+			= nfct_get_attr_u32(ct, ATTR_ORIG_COUNTER_PACKETS);
+	if (nfct_attr_is_set(ct, ATTR_REPL_COUNTER_BYTES))
+		out->counters[ORIG].bytes
+			= nfct_get_attr_u32(ct, ATTR_REPL_COUNTER_BYTES);
+	if (nfct_attr_is_set(ct, ATTR_REPL_COUNTER_PACKETS))
+		out->counters[REPL].packets
+			= nfct_get_attr_u32(ct, ATTR_REPL_COUNTER_PACKETS);
+
+	return 0;
+}
 
 static int
 do_nfct_msg(struct nlmsghdr *nlh, void *arg)
 {
 	struct ulogd_pluginstance *pi = arg;
 	struct nfct_pluginstance *priv = (void *)pi->private;
-	struct nfgenmsg *nfh = NLMSG_DATA(nlh);
 	struct nfct_conntrack nfct;
 	struct conntrack *ct;
-	int flags, type = nfct_msg_type(nlh);
+	int type = nfct_msg_type(nlh);
 
 	if (type == NFCT_MSG_UNKNOWN)
 		return 0;
 
-	bzero(&nfct, sizeof(nfct));
-
-	nfct.tuple[ORIG].l3protonum =
-		nfct.tuple[REPL].l3protonum = nfh->nfgen_family;
+	if (nfct_parse_conntrack(NFCT_T_ALL, nlh, priv->nfct_opaque) < 0)
+		return -1;
 
-	if (nfct_netlink_to_conntrack(nlh, &nfct, &flags) < 0)
+	if (nfct_to_conntrack(pi, priv->nfct_opaque, &nfct) < 0)
 		return -1;
 
 	/* TODO handle NFCT_COUNTER_FILLING */
@@ -949,13 +1015,13 @@ do_nfct_msg(struct nlmsghdr *nlh, void *
 		   hash with many TIME_WAIT connections */
 		if (nfct.tuple[ORIG].protonum == IPPROTO_TCP) {
 			if (nfct.protoinfo.tcp.state == TCP_CONNTRACK_TIME_WAIT)
-				return propagate_ct(pi, &nfct, ct, flags);
+				return propagate_ct(pi, &nfct, ct);
 		}
 		break;
 		
 	case NFCT_MSG_DESTROY:
 		if ((ct = tcache_find(pi, &nfct.tuple[ORIG])) != NULL)
-			return propagate_ct(pi, &nfct, ct, flags);
+			return propagate_ct(pi, &nfct, ct);
 		break;
 		
 	default:
@@ -1070,8 +1136,15 @@ nfct_start(struct ulogd_pluginstance *up
 		return 0;
 	}
 
+	if (priv->nfct_opaque == NULL) {
+		if ((priv->nfct_opaque = nfct_new()) == NULL) {
+			ulogd_log(ULOGD_FATAL, "%s: out of memory\n", upi->id);
+			return -1;
+		}
+	}
+
 	if (init_caches(upi) < 0)
-		return -1;
+		goto err_free;
 
 	priv->cth = nfct_open(NFNL_SUBSYS_CTNETLINK, CT_EVENTS);
 	if (priv->cth == NULL) {
@@ -1111,6 +1184,8 @@ nfct_start(struct ulogd_pluginstance *up
 	nfct_close(priv->cth);
 	priv->cth = NULL;
  err_free:
+	free(priv->nfct_opaque);
+	priv->nfct_opaque = NULL;
 	cache_free(priv->tcache);
 	priv->tcache = NULL;
 	cache_free(priv->scache);
@@ -1148,6 +1223,9 @@ nfct_stop(struct ulogd_pluginstance *pi)
 	cache_free(priv->scache);
 	priv->scache = NULL;
 
+	free(priv->nfct_opaque);
+	priv->nfct_opaque = NULL;
+
 	return 0;
 }
 

-- 
-
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux