Skip to contentSkip to conversation

updated ctnetlink patches: connmark.diff/ctsynd.c

RFC New Patrick McHardy 1 participant 1 message May 28, 2003

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

RFC 1/1 updated ctnetlink patches: connmark.diff/ctsynd.c

# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas:
# ChangeSet 1.1229 -> 1.1230
# net/ipv4/netfilter/ipt_CONNMARK.c 1.1 -> 1.2
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/05/27 [email protected] 1.1230
# CONNMARK changes for conntrack event notifications
# --------------------------------------------
#

net/ipv4/netfilter/ipt_CONNMARK.c +6 -1
diff -Nru a/net/ipv4/netfilter/ipt_CONNMARK.c b/net/ipv4/netfilter/ipt_CONNMARK.c
@@ -19,16 +19,21 @@
        void *userinfo)
 {
 	const struct ipt_connmark_target_info *markinfo = targinfo;
-
 	enum ip_conntrack_info ctinfo;
 	struct ip_conntrack *ct = ip_conntrack_get((*pskb), &ctinfo);
+	unsigned long oldmark = ct->mark;
+
 	if (ct) {
 	    switch(markinfo->mode) {
 	    case IPT_CONNMARK_SET:
 		ct->mark = markinfo->mark;
+		if (oldmark != ct->mark)
+			ip_conntrack_event(IPCT_MARK, ct);
 		break;
 	    case IPT_CONNMARK_SAVE:
 		ct->mark = (*pskb)->nfmark;
+		if (oldmark != ct->mark)
+			ip_conntrack_event(IPCT_MARK, ct);
 		break;
 	    case IPT_CONNMARK_RESTORE:
 		if (ct->mark != (*pskb)->nfmark) {

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <errno.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <asm/types.h>
#include <linux/if.h>
#include <linux/netlink.h>
#include <linux/netfilter_ipv4/ip_nat.h> #include <linux/netfilter_ipv4/ip_tables.h> #include <linux/netfilter_ipv4/ip_conntrack.h> #include <linux/netfilter_ipv4/ip_conntrack_tcp.h> #include <linux/netfilter_ipv4/ip_conntrack_ftp.h> #include <linux/netfilter_ipv4/ip_conntrack_icmp.h> #include <linux/netfilter_ipv4/ip_conntrack_tuple.h> #include <linux/nfnetlink_conntrack.h>

#include "libctnetlink.h"

#define NETLINK_SOCKBUFSZ 1<<20

int accept_msg(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)

{
	int udp_sock = *(int *)arg;

	if (send(udp_sock, n, n->nlmsg_len, 0) < 0)
		perror("send\n");

	return 0;
}

int main(int argc, char **argv)

{
	struct nfnl_handle nlh;
	struct sockaddr_in sin;
	int sock_buf_size = NETLINK_SOCKBUFSZ;
	int udp_sock;

	if (argc < 2) {
		fprintf(stderr, "Usage: %s [ <ip> | listen ]\n", argv[0]);
		exit(1);
	}

	if (nfnl_open(&nlh, NFNL_SUBSYS_CTNETLINK, ~NFGRP_IPV4_CT_UDP)) {
		perror("nfnl_open\n");
		exit(1);
	}

	if ((udp_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
		perror("socket\n");
		exit(1);
	}

	sin.sin_family = AF_INET;
	sin.sin_port = htons(10000);

	if (strncmp(argv[1], "listen", sizeof("listen")) == 0) {
		char buf[4000];
		struct nlmsghdr *n = (struct nlmsghdr *)buf;
		int len;
		
		sin.sin_addr.s_addr = 0;
		if (bind(udp_sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
			perror("bind\n");
			exit(1);
		}

		while ((len = recv(udp_sock, &buf, sizeof(buf), 0))) {
			n->nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL;
			if (nfnl_send(&nlh, n) < 0)
				perror("nfnl_send\n");
		}
		exit(0);
	}

	if (setsockopt(nlh.fd, SOL_SOCKET, SO_RCVBUF,
	               (const char *)&sock_buf_size, sizeof(int)) < 0) {
		perror("setsockopt\n");
		exit(1);
	}

	inet_aton(argv[1],&sin.sin_addr.s_addr);

	if (connect(udp_sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
		perror("connect\n");
		exit(1);
	}

	if (nfnl_listen(&nlh, accept_msg, &udp_sock) < 0) {
		perror("nfnl_listen\n");
		exit(1);
	}
}