All of lore.kernel.org
 help / color / mirror / Atom feed
From: Masahide Nakamura <nakam@linux-ipv6.org>
To: Stephen Hemminger <shemminger@osdl.org>
Cc: Herbert Xu <herbert@gondor.apana.org.au>,
	netdev@oss.sgi.com, nakam@linux-ipv6.org
Subject: [PATCH][IPROUTE2] clean xfrm message format
Date: Tue, 3 Aug 2004 16:45:39 -0700	[thread overview]
Message-ID: <20040803164539.41a0a975@localhost> (raw)

Hello,

This is a patch for ip xfrm and against for the latest
snapshot(iproute2-2.6.8-ss040730.tar.gz). Please apply it.

Here is log:

  fix xfrm command line option and clean its output message format
  (commented by Herbert Xu <herbert@gondor.apana.org.au>).
  * fix to specify algorithm key correctly and its output format.
  * omit some items when they are zero/default.
  * fix output can be one line.
  * use "enc/auth/comp" instead of "E/A/C" for altorithm type.
  * show SPI in hex.
  * remove "sel" and "upspec" from command.

diff -uNr iproute2-2.6.8.orig/ip/ipxfrm.c iproute2-2.6.8/ip/ipxfrm.c
--- iproute2-2.6.8.orig/ip/ipxfrm.c	2004-07-30 15:28:47.000000000 -0700
+++ iproute2-2.6.8/ip/ipxfrm.c	2004-08-02 17:27:43.000000000 -0700
@@ -52,6 +52,48 @@
 	exit(-1);
 }
 
+struct typeent {
+	const char *t_name;
+	int t_type;
+};
+
+static const struct typeent algo_types[]= {
+	{ "enc", XFRMA_ALG_CRYPT }, { "auth", XFRMA_ALG_AUTH },
+	{ "comp", XFRMA_ALG_COMP }, { NULL, -1 }
+};
+
+int xfrm_algotype_getbyname(char *name)
+{
+	int i;
+
+	for (i = 0; ; i++) {
+		const struct typeent *t = &algo_types[i];
+		if (!t->t_name || t->t_type == -1)
+			break;
+
+		if (strcmp(t->t_name, name) == 0)
+			return t->t_type;
+	}
+
+	return -1;
+}
+
+const char *strxf_algotype(int type)
+{
+	int i;
+
+	for (i = 0; ; i++) {
+		const struct typeent *t = &algo_types[i];
+		if (!t->t_name || t->t_type == -1)
+			break;
+
+		if (t->t_type == type)
+			return t->t_name;
+	}
+
+	return NULL;
+}
+
 const char *strxf_flags(__u8 flags)
 {
 	static char str[16];
@@ -84,7 +126,7 @@
 		strcpy(str, "unique");
 		break;
 	default:
-		sprintf(str, "unknown-share(%d)", share);
+		sprintf(str, "%d", share);
 		break;
 	}
 
@@ -114,9 +156,6 @@
 {
 	char abuf[256];
 	__u32 spi;
-	struct protoent *pp;
-	char pbuf[32];
-	char *p;
 
 	if (prefix)
 		fprintf(fp, prefix);
@@ -125,26 +164,20 @@
 	fprintf(fp, "src %s ", rt_addr_n2a(family, sizeof(*saddr),
 					   saddr, abuf, sizeof(abuf)));
 	memset(abuf, '\0', sizeof(abuf));
-	fprintf(fp, "dst %s\n", rt_addr_n2a(family, sizeof(id->daddr),
-					    &id->daddr, abuf, sizeof(abuf)));
+	fprintf(fp, "dst %s", rt_addr_n2a(family, sizeof(id->daddr),
+					  &id->daddr, abuf, sizeof(abuf)));
+	fprintf(fp, "%s", _SL_);
 
 	if (prefix)
 		fprintf(fp, prefix);
 	fprintf(fp, "\t");
 
-	pp = getprotobynumber(id->proto);
-	if (pp)
-		p = pp->p_name;
-	else {
-		sprintf(pbuf, "%d", id->proto);
-		p = pbuf;
-	}
-	fprintf(fp, "proto %s ", p);
+	fprintf(fp, "proto %s ", strxf_proto(id->proto));
 
 	spi = ntohl(id->spi);
-	fprintf(fp, "spi %u", spi);
+	fprintf(fp, "spi 0x%08x", spi);
 	if (show_stats > 0)
-		fprintf(fp, "(0x%08x)", spi);
+		fprintf(fp, "(%u)", spi);
 	fprintf(fp, " ");
 
 	fprintf(fp, "reqid %u", reqid);
@@ -152,7 +185,19 @@
 		fprintf(fp, "(0x%08x)", reqid);
 	fprintf(fp, " ");
 
-	fprintf(fp, "mode %s\n", (mode ? "tunnel" : "transport"));
+	fprintf(fp, "mode ");
+	switch (mode) {
+	case 0:
+		fprintf(fp, "transport");
+		break;
+	case 1:
+		fprintf(fp, "tunnel");
+		break;
+	default:
+		fprintf(fp, "%u", mode);
+		break;
+	}
+	fprintf(fp, "%s", _SL_);
 }
 
 static const char *strxf_limit(__u64 limit)
@@ -170,7 +215,8 @@
 {
 	if (prefix)
 		fprintf(fp, prefix);
-	fprintf(fp, "stats:\n");
+	fprintf(fp, "stats:");
+	fprintf(fp, "%s", _SL_);
 
 	if (prefix)
 		fprintf(fp, prefix);
@@ -178,25 +224,26 @@
 	fprintf(fp, "replay-window %d ", s->replay_window);
 	fprintf(fp, "replay %d ", s->replay);
 	fprintf(fp, "failed %d", s->integrity_failed);
-	fprintf(fp, "\n");
+	fprintf(fp, "%s", _SL_);
 }
 
 static const char *strxf_time(__u64 time)
 {
 	static char str[32];
-	struct tm *tp;
-	time_t t;
 
-	if (time == 0) {
-		strcpy(str, "(undefined)");
-	} else {
-		/* XXX: treat time in the same manner of xfrm_{user,state}.c */
+	if (time == 0)
+		strcpy(str, "-");
+	else {
+		time_t t;
+		struct tm *tp;
+
+		/* XXX: treat time in the same manner of kernel's 
+		 * net/xfrm/xfrm_{user,state}.c
+		 */
 		t = (long)time;
 		tp = localtime(&t);
 
-		sprintf(str, "%04d/%02d/%02d %02d:%02d:%02d",
-			tp->tm_year + 1900, tp->tm_mon + 1, tp->tm_mday,
-			tp->tm_hour, tp->tm_min, tp->tm_sec);
+		strftime(str, sizeof(str), "%F %T", tp);
 	}
 
 	return str;
@@ -209,7 +256,8 @@
 	if (cfg) {
 		if (prefix)
 			fprintf(fp, prefix);
-		fprintf(fp, "lifetime config:\n");
+		fprintf(fp, "lifetime config:");
+		fprintf(fp, "%s", _SL_);
 
 		if (prefix)
 			fprintf(fp, prefix);
@@ -219,7 +267,8 @@
 		fprintf(fp, strxf_limit(cfg->soft_byte_limit));
 		fprintf(fp, "(bytes), hard ");
 		fprintf(fp, strxf_limit(cfg->hard_byte_limit));
-		fprintf(fp, "(bytes)\n");
+		fprintf(fp, "(bytes)");
+		fprintf(fp, "%s", _SL_);
 
 		if (prefix)
 			fprintf(fp, prefix);
@@ -229,7 +278,8 @@
 		fprintf(fp, strxf_limit(cfg->soft_packet_limit));
 		fprintf(fp, "(packets), hard ");
 		fprintf(fp, strxf_limit(cfg->hard_packet_limit));
-		fprintf(fp, "(packets)\n");
+		fprintf(fp, "(packets)");
+		fprintf(fp, "%s", _SL_);
 
 		if (prefix)
 			fprintf(fp, prefix);
@@ -239,7 +289,8 @@
 		fprintf(fp, "%llu", cfg->soft_add_expires_seconds);
 		fprintf(fp, "(sec), hard ");
 		fprintf(fp, "%llu", cfg->hard_add_expires_seconds);
-		fprintf(fp, "(sec)\n");
+		fprintf(fp, "(sec)");
+		fprintf(fp, "%s", _SL_);
 
 		if (prefix)
 			fprintf(fp, prefix);
@@ -249,24 +300,28 @@
 		fprintf(fp, "%llu", cfg->soft_use_expires_seconds);
 		fprintf(fp, "(sec), hard ");
 		fprintf(fp, "%llu", cfg->hard_use_expires_seconds);
-		fprintf(fp, "(sec)\n");
+		fprintf(fp, "(sec)");
+		fprintf(fp, "%s", _SL_);
 	}
 	if (cur) {
 		if (prefix)
 			fprintf(fp, prefix);
-		fprintf(fp, "lifetime current:\n");
+		fprintf(fp, "lifetime current:");
+		fprintf(fp, "%s", _SL_);
 
 		if (prefix)
 			fprintf(fp, prefix);
 		fprintf(fp, "  ");
 		fprintf(fp, "%llu(bytes), ", cur->bytes);
-		fprintf(fp, "%llu(packets)\n", cur->packets);
+		fprintf(fp, "%llu(packets)", cur->packets);
+		fprintf(fp, "%s", _SL_);
+
 		if (prefix)
 			fprintf(fp, prefix);
 		fprintf(fp, "  ");
 		fprintf(fp, "add %s ", strxf_time(cur->add_time));
 		fprintf(fp, "use %s", strxf_time(cur->use_time));
-		fprintf(fp, "\n");
+		fprintf(fp, "%s", _SL_);
 	}
 }
 
@@ -291,18 +346,16 @@
 		sel->prefixlen_s);
 
 	memset(abuf, '\0', sizeof(abuf));
-	fprintf(fp, "dst %s/%d", rt_addr_n2a(f, sizeof(sel->daddr),
+	fprintf(fp, "dst %s/%d ", rt_addr_n2a(f, sizeof(sel->daddr),
 					      &sel->daddr, abuf, sizeof(abuf)),
 		sel->prefixlen_d);
 
-	fprintf(fp, "\n");
-
-	if (prefix)
-		fprintf(fp, prefix);
-	fprintf(fp, "\t");
-
-	fprintf(fp, "upspec proto %u ", sel->proto);
-	fprintf(fp, "sport %u dport %u ", sel->sport, sel->dport);
+	if (sel->proto)
+		fprintf(fp, "proto %s ", strxf_proto(sel->proto));
+	if (sel->sport)
+		fprintf(fp, "sport %u ", ntohs(sel->sport));
+	if (sel->dport)
+		fprintf(fp, "dport %u ", ntohs(sel->dport));
 
 	if (sel->ifindex > 0) {
 		char buf[IF_NAMESIZE];
@@ -314,10 +367,11 @@
 
 	if (show_stats > 0)
 		fprintf(fp, "uid %u", sel->user);
-	fprintf(fp, "\n");
+
+	fprintf(fp, "%s", _SL_);
 }
 
-static void xfrm_algo_print(struct xfrm_algo *algo, FILE *fp,
+static void xfrm_algo_print(struct xfrm_algo *algo, int type, FILE *fp,
 			    const char *prefix)
 {
 	int len;
@@ -326,16 +380,18 @@
 	if (prefix)
 		fprintf(fp, prefix);
 
-	fprintf(fp, "%s", algo->alg_name);
+	fprintf(fp, "%s ", strxf_algotype(type));
+	fprintf(fp, "%s ", algo->alg_name);
 
+	fprintf(fp, "0x");
 	len = algo->alg_key_len / 8;
-	for (i = 0; i < len; i ++) {
-		if (i % 4 == 0)
-			fprintf(fp, " ");
-		fprintf(fp, "%x", algo->alg_key[i]);
-	}
+	for (i = 0; i < len; i ++)
+		fprintf(fp, "%.2x", (unsigned char)algo->alg_key[i]);
 
-	fprintf(fp, "\n");
+	if (show_stats > 0)
+		fprintf(fp, " (%d bits)", algo->alg_key_len);
+
+	fprintf(fp, "%s", _SL_);
 }
 
 static const char *strxf_mask(__u32 mask)
@@ -384,30 +440,36 @@
 		xfrm_id_info_print(&tmpl->saddr, &tmpl->id, tmpl->mode,
 				   tmpl->reqid, family, fp, prefix);
 
-		fprintf(fp, prefix);
+		if (prefix)
+			fprintf(fp, prefix);
 		fprintf(fp, "\t");
-		fprintf(fp, "level ");
 		switch (tmpl->optional) {
 		case 0:
-			fprintf(fp, "required");
+			if (show_stats > 0)
+				fprintf(fp, "level required ");
 			break;
 		case 1:
-			fprintf(fp, "use");
+			fprintf(fp, "level use ");
 			break;
 		default:
-			fprintf(fp, "%d", tmpl->optional);
+			fprintf(fp, "level %d ", tmpl->optional);
 			break;
 		}
-		fprintf(fp, " ");
 
 		if (show_stats > 0) {
 			fprintf(fp, "share %s ", strxf_share(tmpl->share));
 			fprintf(fp, "algo-mask:");
-			fprintf(fp, "E=%s, ", strxf_mask(tmpl->ealgos));
-			fprintf(fp, "A=%s, ", strxf_mask(tmpl->aalgos));
-			fprintf(fp, "C=%s", strxf_mask(tmpl->calgos));
+			fprintf(fp, "%s=%s, ",
+				strxf_algotype(XFRMA_ALG_CRYPT),
+				strxf_mask(tmpl->ealgos));
+			fprintf(fp, "%s=%s, ",
+				strxf_algotype(XFRMA_ALG_AUTH),
+				strxf_mask(tmpl->aalgos));
+			fprintf(fp, "%s=%s",
+				strxf_algotype(XFRMA_ALG_COMP),
+				strxf_mask(tmpl->calgos));
 		}
-		fprintf(fp, "\n");
+		fprintf(fp, "%s", _SL_);
 	}
 }
 
@@ -422,25 +484,17 @@
 
 		switch (type) {
 		case XFRMA_ALG_CRYPT:
-			if (prefix)
-				fprintf(fp, prefix);
-			xfrm_algo_print((struct xfrm_algo *)data, fp, "algo E ");
-			break;
 		case XFRMA_ALG_AUTH:
-			if (prefix)
-				fprintf(fp, prefix);
-			xfrm_algo_print((struct xfrm_algo *)data, fp, "algo A ");
-			break;
 		case XFRMA_ALG_COMP:
-			if (prefix)
-				fprintf(fp, prefix);
-			xfrm_algo_print((struct xfrm_algo *)data, fp, "algo C ");
+			xfrm_algo_print((struct xfrm_algo *)data, type, fp,
+					prefix);
 			break;
 		case XFRMA_ENCAP:
 			if (prefix)
 				fprintf(fp, prefix);
 			/* XXX */
-			fprintf(fp, "encap: (not implemented yet!)\n");
+			fprintf(fp, "encap (not implemented yet!)");
+			fprintf(fp, "%s", _SL_);
 			break;
 		case XFRMA_TMPL:
 		{
@@ -454,14 +508,15 @@
 		default:
 			if (prefix)
 				fprintf(fp, prefix);
-			fprintf(fp, "unknown rta_type: %u\n", type);
+			fprintf(fp, "%u (unknown rta_type)", type);
+			fprintf(fp, "%s", _SL_);
 			break;
 		}
 	}
 }
 
 int xfrm_id_parse(xfrm_address_t *saddr, struct xfrm_id *id, __u16 *family,
-		  int *argcp, char ***argvp)
+		  int loose, int *argcp, char ***argvp)
 {
 	int argc = *argcp;
 	char **argv = *argvp;
@@ -509,7 +564,7 @@
 				proto = pp->p_proto;
 			else {
 				if (get_u8(&proto, *argv, 0))
-					invarg("\"PROTO\" is invalid", *argv);
+					invarg("\"XFRM_PROTO\" is invalid", *argv);
 			}
 
 			switch (proto) {
@@ -519,7 +574,7 @@
 				id->proto = proto;
 				break;
 			default:
-				invarg("\"PROTO\" is unsuppored proto", *argv);
+				invarg("\"XFRM_PROTO\" is unsuppored proto", *argv);
 			}
 
 			filter.id_proto_mask = XFRM_FILTER_MASK_FULL;
@@ -548,9 +603,9 @@
 
 	if (src.family && dst.family && (src.family != dst.family))
 		invarg("the same address family is required between \"SADDR\" and \"DADDR\"", *argv);
-	if (proto == 0)
-		missarg("PROTO");
 
+	if (loose == 0 && proto == 0)
+		missarg("PROTO");
 	if (argc == *argcp)
 		missarg("ID");
 
@@ -598,10 +653,11 @@
 {
 	int argc = *argcp;
 	char **argv = *argvp;
-	__u8 upspec;
 
 	while (1) {
 		if (strcmp(*argv, "proto") == 0) {
+			__u8 upspec;
+
 			NEXT_ARG();
 
 			if (strcmp(*argv, "any") == 0)
@@ -613,7 +669,7 @@
 					upspec = pp->p_proto;
 				else {
 					if (get_u8(&upspec, *argv, 0))
-						invarg("\"UPSPEC\" is invalid", *argv);
+						invarg("\"PROTO\" is invalid", *argv);
 				}
 			}
 			sel->proto = upspec;
@@ -666,6 +722,7 @@
 	char **argv = *argvp;
 	inet_prefix dst;
 	inet_prefix src;
+	char *upspecp = NULL;
 
 	memset(&dst, 0, sizeof(dst));
 	memset(&src, 0, sizeof(src));
@@ -697,11 +754,6 @@
 
 			filter.sel_dst_mask = dst.bitlen;
 
-		} else if (strcmp(*argv, "upspec") == 0) {
-			NEXT_ARG();
-
-			xfrm_selector_upspec_parse(sel, &argc, &argv);
-
 		} else if (strcmp(*argv, "dev") == 0) {
 			int ifindex;
 
@@ -719,8 +771,13 @@
 			filter.sel_dev_mask = XFRM_FILTER_MASK_FULL;
 
 		} else {
-			PREV_ARG(); /* back track */
-			break;
+			if (upspecp) {
+				PREV_ARG(); /* back track */
+				break;
+			} else {
+				upspecp = *argv;
+				xfrm_selector_upspec_parse(sel, &argc, &argv);
+			}
 		}
 
 		if (!NEXT_ARG_OK())
diff -uNr iproute2-2.6.8.orig/ip/xfrm.h iproute2-2.6.8/ip/xfrm.h
--- iproute2-2.6.8.orig/ip/xfrm.h	2004-07-30 15:28:47.000000000 -0700
+++ iproute2-2.6.8/ip/xfrm.h	2004-08-02 17:27:43.000000000 -0700
@@ -78,6 +78,8 @@
 int do_xfrm_state(int argc, char **argv);
 int do_xfrm_policy(int argc, char **argv);
 
+int xfrm_algotype_getbyname(char *name);
+const char *strxf_algotype(int type);
 const char *strxf_flags(__u8 flags);
 const char *strxf_share(__u8 share);
 const char *strxf_proto(__u8 proto);
@@ -93,7 +95,7 @@
 void xfrm_xfrma_print(struct rtattr *tb[], int ntb, __u16 family,
 		      FILE *fp, const char *prefix);
 int xfrm_id_parse(xfrm_address_t *saddr, struct xfrm_id *id, __u16 *family,
-		    int *argcp, char ***argvp);
+		  int loose, int *argcp, char ***argvp);
 int xfrm_mode_parse(__u8 *mode, int *argcp, char ***argvp);
 int xfrm_reqid_parse(__u32 *reqid, int *argcp, char ***argvp);
 int xfrm_selector_parse(struct xfrm_selector *sel, int *argcp, char ***argvp);
diff -uNr iproute2-2.6.8.orig/ip/xfrm_policy.c iproute2-2.6.8/ip/xfrm_policy.c
--- iproute2-2.6.8.orig/ip/xfrm_policy.c	2004-07-30 15:28:47.000000000 -0700
+++ iproute2-2.6.8/ip/xfrm_policy.c	2004-08-02 17:27:43.000000000 -0700
@@ -53,14 +53,14 @@
 
 static void usage(void)
 {
-	fprintf(stderr, "Usage: ip xfrm policy { add | update } dir DIR sel SELECTOR [ index INDEX ] \n");
+	fprintf(stderr, "Usage: ip xfrm policy { add | update } dir DIR SELECTOR [ index INDEX ] \n");
 	fprintf(stderr, "        [ action ACTION ] [ priority PRIORITY ] [ LIMIT-LIST ] [ TMPL-LIST ]\n");
-	fprintf(stderr, "Usage: ip xfrm policy { delete | get } dir DIR [ sel SELECTOR | index INDEX ]\n");
-	fprintf(stderr, "Usage: ip xfrm policy { flush | list } [ dir DIR ] [ sel SELECTOR ]\n");
+	fprintf(stderr, "Usage: ip xfrm policy { delete | get } dir DIR [ SELECTOR | index INDEX ]\n");
+	fprintf(stderr, "Usage: ip xfrm policy { flush | list } [ dir DIR ] [ SELECTOR ]\n");
 	fprintf(stderr, "        [ index INDEX ] [ action ACTION ] [ priority PRIORITY ]\n");
 	fprintf(stderr, "DIR := [ in | out | fwd ]\n");
 
-	fprintf(stderr, "SELECTOR := src ADDR[/PLEN] dst ADDR[/PLEN] [ upspec UPSPEC ] [ dev DEV ]\n");
+	fprintf(stderr, "SELECTOR := src ADDR[/PLEN] dst ADDR[/PLEN] [ UPSPEC ] [ dev DEV ]\n");
 
 	fprintf(stderr, "UPSPEC := proto PROTO [ sport PORT ] [ dport PORT ]\n");
 
@@ -134,7 +134,7 @@
 			else if (strcmp(*argv, "use") == 0)
 				tmpl->optional = 1;
 			else
-				invarg("\"level\" value is invalid\n", *argv);
+				invarg("\"LEVEL\" is invalid\n", *argv);
 
 		} else {
 			if (idp) {
@@ -143,7 +143,7 @@
 			}
 			idp = *argv;
 			xfrm_id_parse(&tmpl->saddr, &tmpl->id, &tmpl->family,
-				      &argc, &argv);
+				      0, &argc, &argv);
 			if (preferred_family == AF_UNSPEC)
 				preferred_family = tmpl->family;
 		}
@@ -171,6 +171,7 @@
 		char				buf[RTA_BUF_SIZE];
 	} req;
 	char *dirp = NULL;
+	char *selp = NULL;
 	char tmpls_buf[XFRM_TMPLS_BUF_SIZE];
 	int tmpls_len = 0;
 
@@ -198,12 +199,6 @@
 
 			filter.dir_mask = XFRM_FILTER_MASK_FULL;
 
-		} else if (strcmp(*argv, "sel") == 0) {
-			NEXT_ARG();
-			xfrm_selector_parse(&req.xpinfo.sel, &argc, &argv);
-			if (preferred_family == AF_UNSPEC)
-				preferred_family = req.xpinfo.sel.family;
-
 		} else if (strcmp(*argv, "index") == 0) {
 			NEXT_ARG();
 			if (get_u32(&req.xpinfo.index, *argv, 0))
@@ -250,8 +245,15 @@
 			xfrm_tmpl_parse(tmpl, &argc, &argv);
 
 			tmpls_len += sizeof(*tmpl);
-		} else
-			invarg("unknown", *argv);
+		} else {
+			if (selp)
+				duparg("unknown", *argv);
+			selp = *argv;
+
+			xfrm_selector_parse(&req.xpinfo.sel, &argc, &argv);
+			if (preferred_family == AF_UNSPEC)
+				preferred_family = req.xpinfo.sel.family;
+		}
 
 		argc--; argv++;
 	}
@@ -362,7 +364,6 @@
 	if (n->nlmsg_type == XFRM_MSG_DELPOLICY)
 		fprintf(fp, "Deleted ");
 
-	fprintf(fp, "sel ");
 	xfrm_selector_print(&xpinfo->sel, preferred_family, fp, NULL);
 
 	fprintf(fp, "\t");
@@ -383,33 +384,36 @@
 	}
 	fprintf(fp, " ");
 
-	fprintf(fp, "action ");
 	switch (xpinfo->action) {
 	case XFRM_POLICY_ALLOW:
-		fprintf(fp, "allow");
+		if (show_stats > 0)
+			fprintf(fp, "action allow ");
 		break;
 	case XFRM_POLICY_BLOCK:
-		fprintf(fp, "block");
+		fprintf(fp, "action block ");
 		break;
 	default:
-		fprintf(fp, "%d", xpinfo->action);
+		fprintf(fp, "action %d ", xpinfo->action);
 		break;
 	}
-	fprintf(fp, " ");
 
-	fprintf(fp, "index %u ", xpinfo->index);
+	if (show_stats)
+		fprintf(fp, "index %u ", xpinfo->index);
 	fprintf(fp, "priority %u ", xpinfo->priority);
 	if (show_stats > 0) {
 		fprintf(fp, "share %s ", strxf_share(xpinfo->share));
 		fprintf(fp, "flags 0x%s", strxf_flags(xpinfo->flags));
 	}
-	fprintf(fp, "\n");
+	fprintf(fp, "%s", _SL_);
 
 	if (show_stats > 0)
 		xfrm_lifetime_print(&xpinfo->lft, &xpinfo->curlft, fp, "\t");
 
 	xfrm_xfrma_print(tb, ntb, xpinfo->sel.family, fp, "\t");
 
+	if (oneline)
+		fprintf(fp, "\n");
+
 	return 0;
 }
 
@@ -440,16 +444,6 @@
 			NEXT_ARG();
 			xfrm_policy_dir_parse(&req.xpid.dir, &argc, &argv);
 
-		} else if (strcmp(*argv, "sel") == 0) {
-			if (selp)
-				duparg("sel", *argv);
-			selp = *argv;
-
-			NEXT_ARG();
-			xfrm_selector_parse(&req.xpid.sel, &argc, &argv);
-			if (preferred_family == AF_UNSPEC)
-				preferred_family = req.xpid.sel.family;
-
 		} else if (strcmp(*argv, "index") == 0) {
 			if (indexp)
 				duparg("index", *argv);
@@ -459,8 +453,16 @@
 			if (get_u32(&req.xpid.index, *argv, 0))
 				invarg("\"INDEX\" is invalid", *argv);
 
-		} else
-			invarg("unknown", *argv);
+		} else {
+			if (selp)
+				invarg("unknown", *argv);
+			selp = *argv;
+
+			xfrm_selector_parse(&req.xpid.sel, &argc, &argv);
+			if (preferred_family == AF_UNSPEC)
+				preferred_family = req.xpid.sel.family;
+
+		}
 
 		argc--; argv++;
 	}
@@ -564,6 +566,7 @@
 
 static int xfrm_policy_list_or_flush(int argc, char **argv, int flush)
 {
+	char *selp = NULL;
 	struct rtnl_handle rth;
 
 	if (argc > 0)
@@ -577,12 +580,6 @@
 
 			filter.dir_mask = XFRM_FILTER_MASK_FULL;
 
-		} else if (strcmp(*argv, "sel") == 0) {
-			NEXT_ARG();
-			xfrm_selector_parse(&filter.xpinfo.sel, &argc, &argv);
-			if (preferred_family == AF_UNSPEC)
-				preferred_family = filter.xpinfo.sel.family;
-
 		} else if (strcmp(*argv, "index") == 0) {
 			NEXT_ARG();
 			if (get_u32(&filter.xpinfo.index, *argv, 0))
@@ -597,7 +594,7 @@
 			else if (strcmp(*argv, "block") == 0)
 				filter.xpinfo.action = XFRM_POLICY_BLOCK;
 			else
-				invarg("\"action\" value is invalid\n", *argv);
+				invarg("\"ACTION\" is invalid\n", *argv);
 
 			filter.action_mask = XFRM_FILTER_MASK_FULL;
 
@@ -608,8 +605,16 @@
 
 			filter.priority_mask = XFRM_FILTER_MASK_FULL;
 
-		} else
-			invarg("unknown", *argv);
+		} else {
+			if (selp)
+				invarg("unknown", *argv);
+			selp = *argv;
+
+			xfrm_selector_parse(&filter.xpinfo.sel, &argc, &argv);
+			if (preferred_family == AF_UNSPEC)
+				preferred_family = filter.xpinfo.sel.family;
+
+		}
 
 		argc--; argv++;
 	}
diff -uNr iproute2-2.6.8.orig/ip/xfrm_state.c iproute2-2.6.8/ip/xfrm_state.c
--- iproute2-2.6.8.orig/ip/xfrm_state.c	2004-07-30 15:28:47.000000000 -0700
+++ iproute2-2.6.8/ip/xfrm_state.c	2004-08-02 17:27:43.000000000 -0700
@@ -67,8 +67,8 @@
 	fprintf(stderr, "XFRM_PROTO := [ ");
 	fprintf(stderr, "%s | ", strxf_proto(IPPROTO_ESP));
 	fprintf(stderr, "%s | ", strxf_proto(IPPROTO_AH));
-	fprintf(stderr, "%s", strxf_proto(IPPROTO_COMP));
-	fprintf(stderr, " ]\n");
+	fprintf(stderr, "%s ", strxf_proto(IPPROTO_COMP));
+	fprintf(stderr, "]\n");
 
 	//fprintf(stderr, "SPI - security parameter index(default=0)\n");
 
@@ -78,9 +78,14 @@
 	fprintf(stderr, "FLAG-LIST := [ FLAG-LIST ] [ flag FLAG ]\n");
 	fprintf(stderr, "FLAG := [ noecn ]\n");
 
-	fprintf(stderr, "ALGO-LIST := [ ALGO-LIST ] | [ algo ALGO ]\n");
+	fprintf(stderr, "ALGO-LIST := [ ALGO-LIST ] | [ ALGO ]\n");
 	fprintf(stderr, "ALGO := ALGO_TYPE ALGO_NAME ALGO_KEY\n");
-	fprintf(stderr, "ALGO_TYPE := [ E | A | C ]\n");
+	fprintf(stderr, "ALGO_TYPE := [ ");
+	fprintf(stderr, "%s | ", strxf_algotype(XFRMA_ALG_CRYPT));
+	fprintf(stderr, "%s | ", strxf_algotype(XFRMA_ALG_AUTH));
+	fprintf(stderr, "%s ", strxf_algotype(XFRMA_ALG_COMP));
+	fprintf(stderr, "]\n");
+
 	//fprintf(stderr, "ALGO_NAME - algorithm name\n");
 	//fprintf(stderr, "ALGO_KEY - algorithm key\n");
 
@@ -99,6 +104,7 @@
 			   char *name, char *key, int max)
 {
 	int len;
+	int slen = strlen(key);
 
 #if 1
 	/* XXX: verifying both name and key is required! */
@@ -107,30 +113,37 @@
 
 	strncpy(alg->alg_name, name, sizeof(alg->alg_name));
 
-	if (strncmp(key, "0x", 2) == 0) {
+	if (slen > 2 && strncmp(key, "0x", 2) == 0) {
 		/*
 		 * XXX: fix me!!
 		 */
-		__u64 val = 0;
-		char *p = (char *)&val;
+		union {
+			__u64 x;
+			unsigned char p[8];
+		} val;
+
+		memset(&val, 0, sizeof(val));
 
-		if (get_u64(&val, key, 16))
+		if (get_u64(&val.x, key, 16))
 			invarg("\"ALGOKEY\" is invalid", key);
 
-		len = (strlen(key) - 2) / 2;
+		len = (slen - 2) / 2;
 		if (len > sizeof(val))
 			invarg("\"ALGOKEY\" is invalid: too large", key);
 
 		if (len > 0) {
-			int index = sizeof(val) - len;
+			int i;
+
 			if (len > max)
 				invarg("\"ALGOKEY\" makes buffer overflow\n", key);
-
-			memcpy(alg->alg_key, &p[index], len);
+			for (i = sizeof(val.p) - 1; i >= 0; i--) {
+				int j = sizeof(val.p) - 1 - i;
+				alg->alg_key[j] = val.p[i];
+			}
 		}
 
 	} else {
-		len = strlen(key);
+		len = slen;
 		if (len > 0) {
 			if (len > max)
 				invarg("\"ALGOKEY\" makes buffer overflow\n", key);
@@ -197,56 +210,7 @@
 	req.xsinfo.lft.hard_packet_limit = XFRM_INF;
 
 	while (argc > 0) {
-		if (strcmp(*argv, "algo") == 0) {
-			struct {
-				struct xfrm_algo alg;
-				char buf[XFRM_ALGO_KEY_BUF_SIZE];
-			} alg;
-			int len;
-			enum xfrm_attr_type_t type;
-			char *name;
-			char *key;
-
-			NEXT_ARG();
-
-			if (strcmp(*argv, "E") == 0) {
-				if (ealgop)
-					duparg("ALGOTYPE", *argv);
-				ealgop = *argv;
-				type = XFRMA_ALG_CRYPT;
-			} else if (strcmp(*argv, "A") == 0) {
-				if (aalgop)
-					duparg("ALGOTYPE", *argv);
-				aalgop = *argv;
-				type = XFRMA_ALG_AUTH;
-
-			} else if (strcmp(*argv, "C") == 0) {
-				if (calgop)
-					duparg("ALGOTYPE", *argv);
-				calgop = *argv;
-				type = XFRMA_ALG_COMP;
-			} else
-				invarg("\"ALGOTYPE\" is invalid\n", *argv);
-
-			if (!NEXT_ARG_OK())
-				missarg("ALGONAME");
-			NEXT_ARG();
-			name = *argv;
-
-			if (!NEXT_ARG_OK())
-				missarg("ALGOKEY");
-			NEXT_ARG();
-			key = *argv;
-
-			memset(&alg, 0, sizeof(alg));
-
-			xfrm_algo_parse((void *)&alg, type, name, key, sizeof(alg.buf));
-			len = sizeof(struct xfrm_algo) + alg.alg.alg_key_len;
-
-			addattr_l(&req.n, sizeof(req.buf), type,
-				  (void *)&alg, len);
-
-		} else if (strcmp(*argv, "mode") == 0) {
+		if (strcmp(*argv, "mode") == 0) {
 			NEXT_ARG();
 			xfrm_mode_parse(&req.xsinfo.mode, &argc, &argv);
 		} else if (strcmp(*argv, "reqid") == 0) {
@@ -258,20 +222,79 @@
 		} else if (strcmp(*argv, "sel") == 0) {
 			NEXT_ARG();
 			xfrm_selector_parse(&req.xsinfo.sel, &argc, &argv);
-
 		} else if (strcmp(*argv, "limit") == 0) {
 			NEXT_ARG();
 			xfrm_lifetime_cfg_parse(&req.xsinfo.lft, &argc, &argv);
 		} else {
-			if (idp)
-				invarg("unknown", *argv);
-			idp = *argv;
+			/* try to assume ALGO */
+			int type = xfrm_algotype_getbyname(*argv);
+			switch (type) {
+			case XFRMA_ALG_CRYPT:
+			case XFRMA_ALG_AUTH:
+			case XFRMA_ALG_COMP:
+			{
+				/* ALGO */
+				struct {
+					struct xfrm_algo alg;
+					char buf[XFRM_ALGO_KEY_BUF_SIZE];
+				} alg;
+				int len;
+				char *name;
+				char *key;
+
+				switch (type) {
+				case XFRMA_ALG_CRYPT:
+					if (ealgop)
+						duparg("ALGOTYPE", *argv);
+					ealgop = *argv;
+					break;
+				case XFRMA_ALG_AUTH:
+					if (aalgop)
+						duparg("ALGOTYPE", *argv);
+					aalgop = *argv;
+					break;
+				case XFRMA_ALG_COMP:
+					if (calgop)
+						duparg("ALGOTYPE", *argv);
+					calgop = *argv;
+					break;
+				default:
+					/* not reached */
+					invarg("\"ALGOTYPE\" is invalid\n", *argv);
+				}
+
+				if (!NEXT_ARG_OK())
+					missarg("ALGONAME");
+				NEXT_ARG();
+				name = *argv;
+
+				if (!NEXT_ARG_OK())
+					missarg("ALGOKEY");
+				NEXT_ARG();
+				key = *argv;
+
+				memset(&alg, 0, sizeof(alg));
+
+				xfrm_algo_parse((void *)&alg, type, name, key,
+						sizeof(alg.buf));
+				len = sizeof(struct xfrm_algo) + alg.alg.alg_key_len;
 
-			/* ID */
-			xfrm_id_parse(&req.xsinfo.saddr, &req.xsinfo.id,
-				      &req.xsinfo.family, &argc, &argv);
-			if (preferred_family == AF_UNSPEC)
-				preferred_family = req.xsinfo.family;
+				addattr_l(&req.n, sizeof(req.buf), type,
+					  (void *)&alg, len);
+				break;
+			}
+			default:
+				/* try to assume ID */
+				if (idp)
+					invarg("unknown", *argv);
+				idp = *argv;
+
+				/* ID */
+				xfrm_id_parse(&req.xsinfo.saddr, &req.xsinfo.id,
+					      &req.xsinfo.family, 0, &argc, &argv);
+				if (preferred_family == AF_UNSPEC)
+					preferred_family = req.xsinfo.family;
+			}
 		}
 		argc--; argv++;
 	}
@@ -285,14 +308,14 @@
 		if (req.xsinfo.id.proto != IPPROTO_ESP &&
 		    req.xsinfo.id.proto != IPPROTO_AH &&
 		    req.xsinfo.id.proto != IPPROTO_COMP) {
-			fprintf(stderr, "\"ALGO\" is invalid with proto=%d\n", req.xsinfo.id.proto);
+			fprintf(stderr, "\"ALGO\" is invalid with proto=%s\n", strxf_proto(req.xsinfo.id.proto));
 			exit(1);
 		}
 	} else {
 		if (req.xsinfo.id.proto == IPPROTO_ESP ||
 		    req.xsinfo.id.proto == IPPROTO_AH ||
 		    req.xsinfo.id.proto == IPPROTO_COMP) {
-			fprintf(stderr, "\"ALGO\" is required with proto=%d\n", req.xsinfo.id.proto);
+			fprintf(stderr, "\"ALGO\" is required with proto=%s\n", strxf_proto(req.xsinfo.id.proto));
 			exit (1);
 		}
 	}
@@ -339,6 +362,15 @@
 	return 1;
 }
 
+static int xfrm_selector_iszero(struct xfrm_selector *s)
+{
+	struct xfrm_selector s0;
+
+	memset(&s0, 0, sizeof(s0));
+
+	return (memcmp(&s0, s, sizeof(s0)) == 0);
+}
+
 int xfrm_state_print(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
 {
 	FILE *fp = (FILE*)arg;
@@ -373,33 +405,35 @@
 			   xsinfo->reqid, xsinfo->family, fp, NULL);
 
 	fprintf(fp, "\t");
-	if (show_stats > 0) {
+	fprintf(fp, "replay-window %d ", xsinfo->replay_window);
+	if (show_stats > 0)
 		fprintf(fp, "seq 0x%08u ", xsinfo->seq);
-		fprintf(fp, "replay-window %d ", xsinfo->replay_window);
-	}
-	fprintf(fp, "flag 0x%s", strxf_flags(xsinfo->flags));
-	if (show_stats > 0) {
-		if (xsinfo->flags) {
-			fprintf(fp, "(");
-			if (xsinfo->flags & XFRM_STATE_NOECN)
-				fprintf(fp, "noecn");
-			fprintf(fp, ")");
+	if (xsinfo->flags) {
+		fprintf(fp, "flag 0x%s", strxf_flags(xsinfo->flags));
+		if (show_stats > 0) {
+			if (xsinfo->flags) {
+				fprintf(fp, "(");
+				if (xsinfo->flags & XFRM_STATE_NOECN)
+					fprintf(fp, "noecn");
+				fprintf(fp, ")");
+			}
 		}
 	}
-	fprintf(fp, "\n");
+	fprintf(fp, "%s", _SL_);
 
 	xfrm_xfrma_print(tb, ntb, xsinfo->family, fp, "\t");
 
-	if (show_stats > 0) {
-		fprintf(fp, "\tsel\n");
-		xfrm_selector_print(&xsinfo->sel, xsinfo->family, fp, "\t  ");
-	}
+	if (!xfrm_selector_iszero(&xsinfo->sel))
+		xfrm_selector_print(&xsinfo->sel, xsinfo->family, fp, "\tsel ");
 
 	if (show_stats > 0) {
 		xfrm_lifetime_print(&xsinfo->lft, &xsinfo->curlft, fp, "\t");
 		xfrm_stats_print(&xsinfo->stats, fp, "\t");
 	}
 
+	if (oneline)
+		fprintf(fp, "\n");
+
 	return 0;
 }
 
@@ -434,7 +468,7 @@
 
 		/* ID */
 		memset(&id, 0, sizeof(id));
-		xfrm_id_parse(&ignore_saddr, &id, &req.xsid.family,
+		xfrm_id_parse(&ignore_saddr, &id, &req.xsid.family, 0,
 			      &argc, &argv);
 
 		memcpy(&req.xsid.daddr, &id.daddr, sizeof(req.xsid.daddr));
@@ -557,9 +591,8 @@
 			idp = *argv;
 
 			/* ID */
-			xfrm_id_parse(&filter.xsinfo.saddr,
-				      &filter.xsinfo.id,
-					&filter.xsinfo.family, &argc, &argv);
+			xfrm_id_parse(&filter.xsinfo.saddr, &filter.xsinfo.id,
+				      &filter.xsinfo.family, 1, &argc, &argv);
 			if (preferred_family == AF_UNSPEC)
 				preferred_family = filter.xsinfo.family;
 		}


-- 
Masahide NAKAMURA

             reply	other threads:[~2004-08-03 23:45 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-08-03 23:45 Masahide Nakamura [this message]
2004-08-04 10:11 ` [PATCH][IPROUTE2] clean xfrm message format Herbert Xu

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=20040803164539.41a0a975@localhost \
    --to=nakam@linux-ipv6.org \
    --cc=herbert@gondor.apana.org.au \
    --cc=netdev@oss.sgi.com \
    --cc=shemminger@osdl.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.