public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
From: Xin Long <lucien.xin@gmail.com>
To: network dev <netdev@vger.kernel.org>,
	David Ahern <dsahern@gmail.com>,
	stephen@networkplumber.org
Cc: Jamal Hadi Salim <jhs@mojatatu.com>,
	Cong Wang <xiyou.wangcong@gmail.com>,
	Jiri Pirko <jiri@resnulli.us>,
	Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>,
	Davide Caratti <dcaratti@redhat.com>
Subject: [PATCH iproute2-next] tc: m_ct: add support for helper
Date: Fri, 10 Feb 2023 16:43:13 -0500	[thread overview]
Message-ID: <ab1e6bfbefff74b2b4fe230162b198c38cf5b394.1676065393.git.lucien.xin@gmail.com> (raw)

This patch is to add the setup and dump for helper in tc ct action
in userspace, and the support in kernel was added in:

  https://lore.kernel.org/netdev/cover.1667766782.git.lucien.xin@gmail.com/

here is an example for usage:

  # ip link add dummy0 type dummy
  # tc qdisc add dev dummy0 ingress

  # tc filter add dev dummy0 ingress proto ip flower ip_proto \
    tcp ct_state -trk action ct helper ipv4-tcp-ftp

  # tc filter show dev dummy0 ingress
    filter protocol ip pref 49152 flower chain 0 handle 0x1
      eth_type ipv4
      ip_proto tcp
      ct_state -trk
      not_in_hw
        action order 1: ct zone 0 helper ipv4-tcp-ftp pipe
        index 1 ref 1 bind

Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 tc/m_ct.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 52 insertions(+), 1 deletion(-)

diff --git a/tc/m_ct.c b/tc/m_ct.c
index 54d64867..6556e41c 100644
--- a/tc/m_ct.c
+++ b/tc/m_ct.c
@@ -13,6 +13,7 @@
 #include <string.h>
 #include "utils.h"
 #include "tc_util.h"
+#include "rt_names.h"
 #include <linux/tc_act/tc_ct.h>
 
 static void
@@ -20,10 +21,11 @@ usage(void)
 {
 	fprintf(stderr,
 		"Usage: ct clear\n"
-		"	ct commit [force] [zone ZONE] [mark MASKED_MARK] [label MASKED_LABEL] [nat NAT_SPEC]\n"
+		"	ct commit [force] [zone ZONE] [mark MASKED_MARK] [label MASKED_LABEL] [nat NAT_SPEC] [helper HELPER]\n"
 		"	ct [nat] [zone ZONE]\n"
 		"Where: ZONE is the conntrack zone table number\n"
 		"	NAT_SPEC is {src|dst} addr addr1[-addr2] [port port1[-port2]]\n"
+		"	HELPER is family-proto-name such as ipv4-tcp-ftp\n"
 		"\n");
 	exit(-1);
 }
@@ -156,6 +158,30 @@ static int ct_parse_mark(char *str, struct nlmsghdr *n)
 	return ct_parse_u32(str, TCA_CT_MARK, TCA_CT_MARK_MASK, n);
 }
 
+static int ct_parse_helper(char *str, struct nlmsghdr *n)
+{
+	char f[32], p[32], name[32];
+	__u8 family, proto;
+
+	if (strlen(str) >= 32 ||
+	    sscanf(str, "%[^-]-%[^-]-%[^-]", f, p, name) != 3)
+		return -1;
+	if (!strcmp(f, "ipv4"))
+		family = AF_INET;
+	else if (!strcmp(f, "ipv6"))
+		family = AF_INET6;
+	else
+		return -1;
+	proto = inet_proto_a2n(p);
+	if (proto < 0)
+		return -1;
+
+	addattr8(n, MAX_MSG, TCA_CT_HELPER_FAMILY, family);
+	addattr8(n, MAX_MSG, TCA_CT_HELPER_PROTO, proto);
+	addattrstrz(n, MAX_MSG, TCA_CT_HELPER_NAME, name);
+	return 0;
+}
+
 static int ct_parse_labels(char *str, struct nlmsghdr *n)
 {
 #define LABELS_SIZE	16
@@ -283,6 +309,14 @@ parse_ct(struct action_util *a, int *argc_p, char ***argv_p, int tca_id,
 			}
 		} else if (matches(*argv, "help") == 0) {
 			usage();
+		} else if (matches(*argv, "helper") == 0) {
+			NEXT_ARG();
+
+			ret = ct_parse_helper(*argv, n);
+			if (ret) {
+				fprintf(stderr, "ct: Illegal \"helper\"\n");
+				return -1;
+			}
 		} else {
 			break;
 		}
@@ -436,6 +470,22 @@ static void ct_print_labels(struct rtattr *attr,
 	print_string(PRINT_ANY, "label", " label %s", out);
 }
 
+static void ct_print_helper(struct rtattr *family, struct rtattr *proto, struct rtattr *name)
+{
+	char helper[32], buf[32], *n;
+	int *f, *p;
+
+	if (!family || !proto || !name)
+		return;
+
+	f = RTA_DATA(family);
+	p = RTA_DATA(proto);
+	n = RTA_DATA(name);
+	sprintf(helper, "%s-%s-%s", (*f == AF_INET) ? "ipv4" : "ipv6",
+		inet_proto_n2a(*p, buf, sizeof(buf)), n);
+	print_string(PRINT_ANY, "helper", " helper %s", helper);
+}
+
 static int print_ct(struct action_util *au, FILE *f, struct rtattr *arg)
 {
 	struct rtattr *tb[TCA_CT_MAX + 1];
@@ -468,6 +518,7 @@ static int print_ct(struct action_util *au, FILE *f, struct rtattr *arg)
 	print_masked_u32("mark", tb[TCA_CT_MARK], tb[TCA_CT_MARK_MASK], false);
 	print_masked_u16("zone", tb[TCA_CT_ZONE], NULL, false);
 	ct_print_labels(tb[TCA_CT_LABELS], tb[TCA_CT_LABELS_MASK]);
+	ct_print_helper(tb[TCA_CT_HELPER_FAMILY], tb[TCA_CT_HELPER_PROTO], tb[TCA_CT_HELPER_NAME]);
 	ct_print_nat(ct_action, tb);
 
 	print_action_control(f, " ", p->action, "");
-- 
2.31.1


             reply	other threads:[~2023-02-10 21:43 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-10 21:43 Xin Long [this message]
2023-02-11  1:20 ` [PATCH iproute2-next] tc: m_ct: add support for helper Marcelo Ricardo Leitner
2023-02-11 17:21 ` Stephen Hemminger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ab1e6bfbefff74b2b4fe230162b198c38cf5b394.1676065393.git.lucien.xin@gmail.com \
    --to=lucien.xin@gmail.com \
    --cc=dcaratti@redhat.com \
    --cc=dsahern@gmail.com \
    --cc=jhs@mojatatu.com \
    --cc=jiri@resnulli.us \
    --cc=marcelo.leitner@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=stephen@networkplumber.org \
    --cc=xiyou.wangcong@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox