All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH][IPSEC] IPsec policy can be matched by ICMP type and code
@ 2004-08-09  8:54 Masahide Nakamura
  2004-08-09  9:03 ` YOSHIFUJI Hideaki / 吉藤英明
  2004-08-10  0:07 ` David S. Miller
  0 siblings, 2 replies; 9+ messages in thread
From: Masahide Nakamura @ 2004-08-09  8:54 UTC (permalink / raw)
  To: davem; +Cc: netdev, usagi-core

Hello,

This patch makes that IPsec policy can be matched by ICMP type and
code. Actually setkey(ipsec-tools) already has their interface so it
follows setkey's manner where type/code are stored in selector. I
added shortcuts for them as a trial. Please read the patch and its log
below first.

Thinking of raw socket (in outbound case), the patch supports only
ICMP; it is out of scope such packet as user-land builds non-ICMP data
(e.g. TCP/UDP) and sends through raw socket. IMO this behavior is
enough, however does anybody have comments?

The patch is against 2.6.8-rc3. Can you check it?

Regards,
-- 
Masahide NAKAMURA


Log:
IPsec ICMP type and code support.

* inbound:
 - add entry of ICMP[46] to decode_session[46]() to update flowi.
 - add xfrm_selector_icmp_match().
* outbound:
 - store type/code to flowi when it seems to be ICMP[46] data in raw
socket.


Signed-off-by: Masahide NAKAMURA <nakam@linux-ipv6.org>


Index: include/linux/xfrm.h
===================================================================
RCS file: /cvsroot/usagi/usagi/kernel/linux26/include/linux/xfrm.h,v
retrieving revision 1.1.1.14
diff -u -r1.1.1.14 xfrm.h
--- include/linux/xfrm.h	19 Jul 2004 16:53:28 -0000	1.1.1.14
+++ include/linux/xfrm.h	9 Aug 2004 08:31:12 -0000
@@ -43,6 +43,15 @@
 	__u8	proto;
 	int	ifindex;
 	uid_t	user;
+	/*
+	 * XXX: ICMP values defined like a manner which setkey does:
+	 * XXX: ICMP-type is "sport" area and ICMP-code is stored "dport" area.
+	 * XXX: Should it be formed union like struct flowi? --nakam
+	 */
+#define xfrmsel_icmp_type	sport
+#define xfrmsel_icmp_type_mask	sport_mask
+#define xfrmsel_icmp_code	dport
+#define xfrmsel_icmp_code_mask	dport_mask
 };
 
 #define XFRM_INF (~(__u64)0)
Index: include/net/xfrm.h
===================================================================
RCS file: /cvsroot/usagi/usagi/kernel/linux26/include/net/xfrm.h,v
retrieving revision 1.1.1.28
diff -u -r1.1.1.28 xfrm.h
--- include/net/xfrm.h	3 Aug 2004 23:00:04 -0000	1.1.1.28
+++ include/net/xfrm.h	9 Aug 2004 08:31:13 -0000
@@ -463,25 +463,54 @@
 }
 
 static inline int
+__xfrm_selector_icmp_match(struct xfrm_selector *sel, struct flowi *fl)
+{
+	/* In selector, type/code are stored 16-bit area and
+	 * should be network byte-order.
+	 */
+	__u8 *xtype = (__u8 *)&sel->xfrmsel_icmp_type;
+	__u8 *xcode = (__u8 *)&sel->xfrmsel_icmp_code;
+	__u8 *xtypemask = (__u8 *)&sel->xfrmsel_icmp_type_mask;
+	__u8 *xcodemask = (__u8 *)&sel->xfrmsel_icmp_code_mask;
+
+	return (!(xtype[0]&xtypemask[0]) &&
+		!((fl->fl_icmp_type^xtype[1])&xtypemask[1])) &&
+	       (!(xcode[0]&xcodemask[0]) &&
+		!((fl->fl_icmp_code^xcode[1])&xcodemask[1]));
+}
+
+static inline int
 __xfrm4_selector_match(struct xfrm_selector *sel, struct flowi *fl)
 {
-	return  addr_match(&fl->fl4_dst, &sel->daddr, sel->prefixlen_d) &&
-		addr_match(&fl->fl4_src, &sel->saddr, sel->prefixlen_s) &&
-		!((fl->fl_ip_dport^sel->dport)&sel->dport_mask) &&
-		!((fl->fl_ip_sport^sel->sport)&sel->sport_mask) &&
-		(fl->proto == sel->proto || !sel->proto) &&
-		(fl->oif == sel->ifindex || !sel->ifindex);
+	if (!(addr_match(&fl->fl4_dst, &sel->daddr, sel->prefixlen_d) &&
+	      addr_match(&fl->fl4_src, &sel->saddr, sel->prefixlen_s) &&
+	      (fl->proto == sel->proto || !sel->proto) &&
+	      (fl->oif == sel->ifindex || !sel->ifindex)))
+		return 0;
+	      
+	if (fl->proto == IPPROTO_ICMP)
+		return __xfrm_selector_icmp_match(sel, fl);
+	else {
+		return !((fl->fl_ip_dport^sel->dport)&sel->dport_mask) &&
+		       !((fl->fl_ip_sport^sel->sport)&sel->sport_mask);
+	}
 }
 
 static inline int
 __xfrm6_selector_match(struct xfrm_selector *sel, struct flowi *fl)
 {
-	return  addr_match(&fl->fl6_dst, &sel->daddr, sel->prefixlen_d) &&
-		addr_match(&fl->fl6_src, &sel->saddr, sel->prefixlen_s) &&
-		!((fl->fl_ip_dport^sel->dport)&sel->dport_mask) &&
-		!((fl->fl_ip_sport^sel->sport)&sel->sport_mask) &&
-		(fl->proto == sel->proto || !sel->proto) &&
-		(fl->oif == sel->ifindex || !sel->ifindex);
+	if (!(addr_match(&fl->fl6_dst, &sel->daddr, sel->prefixlen_d) &&
+	      addr_match(&fl->fl6_src, &sel->saddr, sel->prefixlen_s) &&
+	      (fl->oif == sel->ifindex || !sel->ifindex) &&
+	      (fl->proto == sel->proto || !sel->proto)))
+		return 0;
+
+	if (fl->proto == IPPROTO_ICMPV6)
+		return __xfrm_selector_icmp_match(sel, fl);
+	else {
+		return !((fl->fl_ip_dport^sel->dport)&sel->dport_mask) &&
+		       !((fl->fl_ip_sport^sel->sport)&sel->sport_mask);
+	}
 }
 
 static inline int
Index: net/ipv4/raw.c
===================================================================
RCS file: /cvsroot/usagi/usagi/kernel/linux26/net/ipv4/raw.c,v
retrieving revision 1.1.1.29
diff -u -r1.1.1.29 raw.c
--- net/ipv4/raw.c	3 Aug 2004 23:01:54 -0000	1.1.1.29
+++ net/ipv4/raw.c	9 Aug 2004 08:31:15 -0000
@@ -323,6 +323,51 @@
 	return err; 
 }
 
+static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
+{
+	struct iovec *iov;
+	u8 *type = NULL;
+	u8 *code = NULL;
+	int probed = 0;
+	int i;
+
+	if (!msg->msg_iov)
+		return;
+
+	for (i = 0; i < msg->msg_iovlen; i++) {
+		iov = &msg->msg_iov[i];
+		if (!iov)
+			continue;
+
+		switch (fl->proto) {
+		case IPPROTO_ICMP:
+			/* check if one-byte field is readable or not. */
+			if (iov->iov_base && iov->iov_len < 1)
+				break;
+
+			if (!type) {
+				type = iov->iov_base;
+				/* check if code field is readable or not. */
+				if (iov->iov_len > 1)
+					code = type + 1;
+			} else if (!code)
+				code = iov->iov_base;
+
+			if (type && code) {
+				fl->fl_icmp_type = *type;
+				fl->fl_icmp_code = *code;
+				probed = 1;
+			}
+			break;
+		default:
+			probed = 1;
+			break;
+		}
+		if (probed)
+			break;
+	}
+}
+
 static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 		       size_t len)
 {
@@ -429,6 +474,8 @@
 				    .proto = inet->hdrincl ? IPPROTO_RAW :
 					    		     sk->sk_protocol,
 				  };
+		raw_probe_proto_opt(&fl, msg);
+
 		err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT));
 	}
 	if (err)
Index: net/ipv4/xfrm4_policy.c
===================================================================
RCS file: /cvsroot/usagi/usagi/kernel/linux26/net/ipv4/xfrm4_policy.c,v
retrieving revision 1.1.1.7
diff -u -r1.1.1.7 xfrm4_policy.c
--- net/ipv4/xfrm4_policy.c	19 Jul 2004 16:55:14 -0000	1.1.1.7
+++ net/ipv4/xfrm4_policy.c	9 Aug 2004 08:31:15 -0000
@@ -183,6 +183,15 @@
 			}
 			break;
 
+		case IPPROTO_ICMP:
+			if (pskb_may_pull(skb, xprth + 2 - skb->data)) {
+				u8 *icmp = xprth;
+
+				fl->fl_icmp_type = icmp[0];
+				fl->fl_icmp_code = icmp[1];
+			}
+			break;
+
 		case IPPROTO_ESP:
 			if (pskb_may_pull(skb, xprth + 4 - skb->data)) {
 				u32 *ehdr = (u32 *)xprth;
Index: net/ipv6/raw.c
===================================================================
RCS file: /cvsroot/usagi/usagi/kernel/linux26/net/ipv6/raw.c,v
retrieving revision 1.1.1.35
diff -u -r1.1.1.35 raw.c
--- net/ipv6/raw.c	3 Aug 2004 23:01:59 -0000	1.1.1.35
+++ net/ipv6/raw.c	9 Aug 2004 08:31:15 -0000
@@ -555,6 +555,52 @@
 	IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS);
 	return err; 
 }
+
+static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
+{
+	struct iovec *iov;
+	u8 *type = NULL;
+	u8 *code = NULL;
+	int probed = 0;
+	int i;
+
+	if (!msg->msg_iov)
+		return;
+
+	for (i = 0; i < msg->msg_iovlen; i++) {
+		iov = &msg->msg_iov[i];
+		if (!iov)
+			continue;
+
+		switch (fl->proto) {
+		case IPPROTO_ICMPV6:
+			/* check if one-byte field is readable or not. */
+			if (iov->iov_base && iov->iov_len < 1)
+				break;
+
+			if (!type) {
+				type = iov->iov_base;
+				/* check if code field is readable or not. */
+				if (iov->iov_len > 1)
+					code = type + 1;
+			} else if (!code)
+				code = iov->iov_base;
+
+			if (type && code) {
+				fl->fl_icmp_type = *type;
+				fl->fl_icmp_code = *code;
+				probed = 1;
+			}
+			break;
+		default:
+			probed = 1;
+			break;
+		}
+		if (probed)
+			break;
+	}
+}
+
 static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
 		   struct msghdr *msg, size_t len)
 {
@@ -674,6 +720,8 @@
 		opt = fl6_merge_options(&opt_space, flowlabel, opt);
 
 	fl.proto = proto;
+	rawv6_probe_proto_opt(&fl, msg);
+ 
 	ipv6_addr_copy(&fl.fl6_dst, daddr);
 	if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr))
 		ipv6_addr_copy(&fl.fl6_src, &np->saddr);
Index: net/ipv6/xfrm6_policy.c
===================================================================
RCS file: /cvsroot/usagi/usagi/kernel/linux26/net/ipv6/xfrm6_policy.c,v
retrieving revision 1.1.1.15
diff -u -r1.1.1.15 xfrm6_policy.c
--- net/ipv6/xfrm6_policy.c	3 Aug 2004 23:01:59 -0000	1.1.1.15
+++ net/ipv6/xfrm6_policy.c	9 Aug 2004 08:31:15 -0000
@@ -213,6 +213,16 @@
 			fl->proto = nexthdr;
 			return;
 
+		case IPPROTO_ICMPV6:
+			if (pskb_may_pull(skb, skb->nh.raw + offset + 2 - skb->data)) {
+				u8 *icmp = (u8 *)exthdr;
+
+				fl->fl_icmp_type = icmp[0];
+				fl->fl_icmp_code = icmp[1];
+			}
+			fl->proto = nexthdr;
+			return;
+
 		/* XXX Why are there these headers? */
 		case IPPROTO_AH:
 		case IPPROTO_ESP:

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH][IPSEC] IPsec policy can be matched by ICMP type and code
  2004-08-09  8:54 [PATCH][IPSEC] IPsec policy can be matched by ICMP type and code Masahide Nakamura
@ 2004-08-09  9:03 ` YOSHIFUJI Hideaki / 吉藤英明
  2004-08-10  0:07 ` David S. Miller
  1 sibling, 0 replies; 9+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2004-08-09  9:03 UTC (permalink / raw)
  To: usagi-core, nakam; +Cc: davem, netdev

In article <20040809175404.301bd60a@localhost> (at Mon, 9 Aug 2004 17:54:04 +0900), Masahide Nakamura <nakam@linux-ipv6.org> says:

> This patch makes that IPsec policy can be matched by ICMP type and
> code. Actually setkey(ipsec-tools) already has their interface so it
> follows setkey's manner where type/code are stored in selector. I
> added shortcuts for them as a trial. Please read the patch and its log
> below first.

Sorry, please do not apply this.
I notice that this does not seem to work on big-endian archs.

--yoshfuji

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH][IPSEC] IPsec policy can be matched by ICMP type and code
  2004-08-09  8:54 [PATCH][IPSEC] IPsec policy can be matched by ICMP type and code Masahide Nakamura
  2004-08-09  9:03 ` YOSHIFUJI Hideaki / 吉藤英明
@ 2004-08-10  0:07 ` David S. Miller
  2004-08-10  1:32   ` YOSHIFUJI Hideaki / 吉藤英明
  2004-08-18 14:09   ` [PATCH] XFRM: ICMP{,v6} type/code support (Take 2) (was Re: [PATCH][IPSEC] IPsec policy can be matched by ICMP type and code) YOSHIFUJI Hideaki / 吉藤英明
  1 sibling, 2 replies; 9+ messages in thread
From: David S. Miller @ 2004-08-10  0:07 UTC (permalink / raw)
  To: Masahide Nakamura; +Cc: netdev, usagi-core

On Mon, 9 Aug 2004 17:54:04 +0900
Masahide Nakamura <nakam@linux-ipv6.org> wrote:

> Thinking of raw socket (in outbound case), the patch supports only
> ICMP; it is out of scope such packet as user-land builds non-ICMP data
> (e.g. TCP/UDP) and sends through raw socket. IMO this behavior is
> enough, however does anybody have comments?

Truly %100 RAW sockets should have their packets untouched by
the kernel.  User wants exactly that packet to be sent onto
the wire.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH][IPSEC] IPsec policy can be matched by ICMP type and code
  2004-08-10  0:07 ` David S. Miller
@ 2004-08-10  1:32   ` YOSHIFUJI Hideaki / 吉藤英明
  2004-08-11  6:01     ` David S. Miller
  2004-08-18 14:09   ` [PATCH] XFRM: ICMP{,v6} type/code support (Take 2) (was Re: [PATCH][IPSEC] IPsec policy can be matched by ICMP type and code) YOSHIFUJI Hideaki / 吉藤英明
  1 sibling, 1 reply; 9+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2004-08-10  1:32 UTC (permalink / raw)
  To: davem; +Cc: nakam, netdev, usagi-core

In article <20040809170705.6ab75c5f.davem@redhat.com> (at Mon, 9 Aug 2004 17:07:05 -0700), "David S. Miller" <davem@redhat.com> says:

> Truly %100 RAW sockets should have their packets untouched by
> the kernel.  User wants exactly that packet to be sent onto
> the wire.

Does it make sense to excude IPPPROTO_RAW sockets and/or hdrincl sockets, 
which would be 100% truly raw socket?
Or, do we add some socket option for this?

Mip6 is required to exchange ipsec'ed datagrams (!= IPPROTO_RAW).
(as I told you at Networking Summit if I remember correctly),
so we need some sort of the patch, anyway.

Thanks.

--yoshfuji

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH][IPSEC] IPsec policy can be matched by ICMP type and code
  2004-08-10  1:32   ` YOSHIFUJI Hideaki / 吉藤英明
@ 2004-08-11  6:01     ` David S. Miller
  2004-08-11 19:14       ` David Stevens
  0 siblings, 1 reply; 9+ messages in thread
From: David S. Miller @ 2004-08-11  6:01 UTC (permalink / raw)
  To: yoshfuji; +Cc: nakam, netdev, usagi-core

On Tue, 10 Aug 2004 10:32:29 +0900 (JST)
YOSHIFUJI Hideaki / ^[$B5HF#1QL@^[(B <yoshfuji@linux-ipv6.org> wrote:

> Does it make sense to excude IPPPROTO_RAW sockets and/or hdrincl sockets, 
> which would be 100% truly raw socket?
> Or, do we add some socket option for this?
> 
> Mip6 is required to exchange ipsec'ed datagrams (!= IPPROTO_RAW).
> (as I told you at Networking Summit if I remember correctly),
> so we need some sort of the patch, anyway.

This is what Alexey told me when I last spoke with him
about this:

Return-Path: <kuznet@ms2.inr.ac.ru>
Received: from localhost (IDENT:davem@localhost.localdomain [127.0.0.1])
	by pizda.ninka.net (8.9.3/8.9.3) with ESMTP id QAA27793
	for <davem@localhost>; Sat, 17 May 2003 16:28:26 -0700
From: kuznet@ms2.inr.ac.ru
Received: from localhost.localdomain [127.0.0.1]
	by localhost with POP3 (fetchmail-6.2.2)
	for davem@localhost (single-drop); Sat, 17 May 2003 16:28:26 -0700 (PDT)
Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254])
	by devserv.devel.redhat.com (8.11.6/8.11.0) with ESMTP id h4HNSr500334
	for <davem@devserv.devel.redhat.com>; Sat, 17 May 2003 19:28:53 -0400
Received: from mx1.redhat.com (mx1.redhat.com [172.16.48.31])
	by int-mx1.corp.redhat.com (8.11.6/8.11.6) with SMTP id h4HNSrI11137
	for <davem@redhat.com>; Sat, 17 May 2003 19:28:53 -0400
Received: from dub.inr.ac.ru (dub.inr.ac.ru [193.233.7.105])
	by mx1.redhat.com (8.11.6/8.11.6) with SMTP id h4HNSqH20272
	for <davem@redhat.com>; Sat, 17 May 2003 19:28:52 -0400
Received: (from kuznet@localhost) by dub.inr.ac.ru (8.6.13/ANK) id DAA10631 for davem@redhat.com; Sun, 18 May 2003 03:28:45 +0400
Message-Id: <200305172328.DAA10631@dub.inr.ac.ru>
Subject: Re: dst_pmtu() check in ip_output()
To: davem@redhat.com (David S. Miller)
Date: Sun, 18 May 2003 03:28:45 +0400 (MSD)
In-Reply-To: <20030514.184139.55739273.davem@redhat.com> from "David S. Miller" at May 14, 2003 06:41:39 PM
X-Mailer: ELM [version 2.5 PL6]
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hello!

> Let's ask the following question: What is difference between adding
> transformation locally, and adding it at some hop on the way to
> destination?
> 
> I can already hear answers of the form "It is same difference as
> that between tunnel and transport mode." :-)

Exactly.

Plus one more thing: when you noticed pathology with raw socket
you referred to "What does user expect?".

Use of raw socket is pathological itself, f.e. IPv6 does not even
have such a concept. It is used by (and invented by VJ for) traceroute.
And beyond this it is used by various testing and attacker's software.
Shortly, the packet which it generates are _tricky_ by user desire,
when user wants to test (or attack) someone.

So, I would expect the packet is not transformed locally at all.
Remember f.e. that it can be an _IPsec_ packet already.

Alexey

PS. This is the first mail which I send from new account. Please,
tell me if it looks unusual.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH][IPSEC] IPsec policy can be matched by ICMP type and code
  2004-08-11  6:01     ` David S. Miller
@ 2004-08-11 19:14       ` David Stevens
  2004-08-11 20:30         ` David S. Miller
  0 siblings, 1 reply; 9+ messages in thread
From: David Stevens @ 2004-08-11 19:14 UTC (permalink / raw)
  To: David S. Miller; +Cc: nakam, netdev, usagi-core, yoshfuji

I may be catching this out of context, but...

raw sockets predate VJ contributions by many years and are
typically used by protocols not in the kernel. The original "ping"
used raw sockets, as well as routing protocols like BGP and RIP
which are directly encapsulated in IP, without a separate transport
protocol. The original traceroute I believe used UDP and just set
the TTL-- I don't believe it used raw sockets at all. Don't know what
the current versions do; haven't looked in a while.

And IPv6 does support raw sockets; it just doesn't let you
generate bad checksums and some header fields, I expect
to make it harder to write attack software.

                                        +-DLS




"David S. Miller" <davem@redhat.com> 
Sent by: netdev-bounce@oss.sgi.com
08/10/2004 11:01 PM

To
yoshfuji@linux-ipv6.org
cc
nakam@linux-ipv6.org, netdev@oss.sgi.com, usagi-core@linux-ipv6.org
Subject
Re: [PATCH][IPSEC] IPsec policy can be matched by ICMP type and code






On Tue, 10 Aug 2004 10:32:29 +0900 (JST)
YOSHIFUJI Hideaki / ^[$B5HF#1QL@^[(B <yoshfuji@linux-ipv6.org> wrote:

> Does it make sense to excude IPPPROTO_RAW sockets and/or hdrincl 
sockets,
> which would be 100% truly raw socket?
> Or, do we add some socket option for this?
>
> Mip6 is required to exchange ipsec'ed datagrams (!= IPPROTO_RAW).
> (as I told you at Networking Summit if I remember correctly),
> so we need some sort of the patch, anyway.

This is what Alexey told me when I last spoke with him
about this:

Return-Path: <kuznet@ms2.inr.ac.ru>
Received: from localhost (IDENT:davem@localhost.localdomain [127.0.0.1])
by pizda.ninka.net (8.9.3/8.9.3) with ESMTP id QAA27793
for <davem@localhost>; Sat, 17 May 2003 16:28:26 -0700
From: kuznet@ms2.inr.ac.ru
Received: from localhost.localdomain [127.0.0.1]
by localhost with POP3 (fetchmail-6.2.2)
for davem@localhost (single-drop); Sat, 17 May 2003 16:28:26 -0700 (PDT)
Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com 
[172.16.52.254])
by devserv.devel.redhat.com (8.11.6/8.11.0) with ESMTP id h4HNSr500334
for <davem@devserv.devel.redhat.com>; Sat, 17 May 2003 19:28:53 -0400
Received: from mx1.redhat.com (mx1.redhat.com [172.16.48.31])
by int-mx1.corp.redhat.com (8.11.6/8.11.6) with SMTP id h4HNSrI11137
for <davem@redhat.com>; Sat, 17 May 2003 19:28:53 -0400
Received: from dub.inr.ac.ru (dub.inr.ac.ru [193.233.7.105])
by mx1.redhat.com (8.11.6/8.11.6) with SMTP id h4HNSqH20272
for <davem@redhat.com>; Sat, 17 May 2003 19:28:52 -0400
Received: (from kuznet@localhost) by dub.inr.ac.ru (8.6.13/ANK) id 
DAA10631 for davem@redhat.com; Sun, 18 May 2003 03:28:45 +0400
Message-Id: <200305172328.DAA10631@dub.inr.ac.ru>
Subject: Re: dst_pmtu() check in ip_output()
To: davem@redhat.com (David S. Miller)
Date: Sun, 18 May 2003 03:28:45 +0400 (MSD)
In-Reply-To: <20030514.184139.55739273.davem@redhat.com> from "David S. 
Miller" at May 14, 2003 06:41:39 PM
X-Mailer: ELM [version 2.5 PL6]
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hello!

> Let's ask the following question: What is difference between adding
> transformation locally, and adding it at some hop on the way to
> destination?
>
> I can already hear answers of the form "It is same difference as
> that between tunnel and transport mode." :-)

Exactly.

Plus one more thing: when you noticed pathology with raw socket
you referred to "What does user expect?".

Use of raw socket is pathological itself, f.e. IPv6 does not even
have such a concept. It is used by (and invented by VJ for) traceroute.
And beyond this it is used by various testing and attacker's software.
Shortly, the packet which it generates are _tricky_ by user desire,
when user wants to test (or attack) someone.

So, I would expect the packet is not transformed locally at all.
Remember f.e. that it can be an _IPsec_ packet already.

Alexey

PS. This is the first mail which I send from new account. Please,
tell me if it looks unusual.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH][IPSEC] IPsec policy can be matched by ICMP type and code
  2004-08-11 19:14       ` David Stevens
@ 2004-08-11 20:30         ` David S. Miller
  0 siblings, 0 replies; 9+ messages in thread
From: David S. Miller @ 2004-08-11 20:30 UTC (permalink / raw)
  To: David Stevens; +Cc: nakam, netdev, usagi-core, yoshfuji

On Wed, 11 Aug 2004 13:14:19 -0600
David Stevens <dlstevens@us.ibm.com> wrote:

> raw sockets predate VJ contributions by many years and are
> typically used by protocols not in the kernel. The original "ping"
> used raw sockets, as well as routing protocols like BGP and RIP
> which are directly encapsulated in IP, without a separate transport
> protocol. The original traceroute I believe used UDP and just set
> the TTL-- I don't believe it used raw sockets at all. Don't know what
> the current versions do; haven't looked in a while.

"ping" does not use the hdrinclude feature.

> And IPv6 does support raw sockets; it just doesn't let you
> generate bad checksums and some header fields, I expect
> to make it harder to write attack software.

So like I said, raw without the hdrinclude feature.

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH] XFRM: ICMP{,v6} type/code support (Take 2) (was Re: [PATCH][IPSEC] IPsec policy can be matched by ICMP type and code)
  2004-08-10  0:07 ` David S. Miller
  2004-08-10  1:32   ` YOSHIFUJI Hideaki / 吉藤英明
@ 2004-08-18 14:09   ` YOSHIFUJI Hideaki / 吉藤英明
  2004-08-18 22:24     ` David S. Miller
  1 sibling, 1 reply; 9+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2004-08-18 14:09 UTC (permalink / raw)
  To: davem; +Cc: nakam, netdev, usagi-core, yoshfuji

Hello.

In article <20040809170705.6ab75c5f.davem@redhat.com> (at Mon, 9 Aug 2004 17:07:05 -0700), "David S. Miller" <davem@redhat.com> says:

> On Mon, 9 Aug 2004 17:54:04 +0900
> Masahide Nakamura <nakam@linux-ipv6.org> wrote:
> 
> > Thinking of raw socket (in outbound case), the patch supports only
> > ICMP; it is out of scope such packet as user-land builds non-ICMP data
> > (e.g. TCP/UDP) and sends through raw socket. IMO this behavior is
> > enough, however does anybody have comments?
> 
> Truly %100 RAW sockets should have their packets untouched by
> the kernel.  User wants exactly that packet to be sent onto
> the wire.

Here's the updated version of the patch.
Changesets are available at:
	<bk://bk.skbuff.net:20609/linux-2.6-xfrm-icmp/>.

Thanks.

DIFFSTAT
--------
 include/net/xfrm.h      |   46 ++++++++++++++++++++++++++++++++++++++++----
 net/ipv4/raw.c          |   50 +++++++++++++++++++++++++++++++++++++++++++++++-
 net/ipv4/xfrm4_policy.c |    9 ++++++++
 net/ipv6/raw.c          |   48 ++++++++++++++++++++++++++++++++++++++++++++++
 net/ipv6/xfrm6_policy.c |   10 +++++++++
 5 files changed, 158 insertions(+), 5 deletions(-)

CHANGESET
---------
ChangeSet@1.1838, 2004-08-18 22:39:42+09:00, yoshfuji@linux-ipv6.org
  [XFRM] Fix selector comparison against icmp{,v6} flows.
  
  Signed-off-by: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>

diff -Nru a/include/net/xfrm.h b/include/net/xfrm.h
--- a/include/net/xfrm.h	2004-08-18 22:58:51 +09:00
+++ b/include/net/xfrm.h	2004-08-18 22:58:51 +09:00
@@ -462,13 +462,51 @@
 	return 1;
 }
 
+static __inline__
+u16 xfrm_flowi_sport(struct flowi *fl)
+{
+	u16 port;
+	switch(fl->proto) {
+	case IPPROTO_TCP:
+	case IPPROTO_UDP:
+		port = fl->fl_ip_sport;
+		break;
+	case IPPROTO_ICMP:
+	case IPPROTO_ICMPV6:
+		port = htons(fl->fl_icmp_type);
+		break;
+	default:
+		port = 0;	/*XXX*/
+	}
+	return port;
+}
+
+static __inline__
+u16 xfrm_flowi_dport(struct flowi *fl)
+{
+	u16 port;
+	switch(fl->proto) {
+	case IPPROTO_TCP:
+	case IPPROTO_UDP:
+		port = fl->fl_ip_dport;
+		break;
+	case IPPROTO_ICMP:
+	case IPPROTO_ICMPV6:
+		port = htons(fl->fl_icmp_code);
+		break;
+	default:
+		port = 0;	/*XXX*/
+	}
+	return port;
+}
+
 static inline int
 __xfrm4_selector_match(struct xfrm_selector *sel, struct flowi *fl)
 {
 	return  addr_match(&fl->fl4_dst, &sel->daddr, sel->prefixlen_d) &&
 		addr_match(&fl->fl4_src, &sel->saddr, sel->prefixlen_s) &&
-		!((fl->fl_ip_dport^sel->dport)&sel->dport_mask) &&
-		!((fl->fl_ip_sport^sel->sport)&sel->sport_mask) &&
+		!((xfrm_flowi_dport(fl) ^ sel->dport) & sel->dport_mask) &&
+		!((xfrm_flowi_sport(fl) ^ sel->sport) & sel->sport_mask) &&
 		(fl->proto == sel->proto || !sel->proto) &&
 		(fl->oif == sel->ifindex || !sel->ifindex);
 }
@@ -478,8 +516,8 @@
 {
 	return  addr_match(&fl->fl6_dst, &sel->daddr, sel->prefixlen_d) &&
 		addr_match(&fl->fl6_src, &sel->saddr, sel->prefixlen_s) &&
-		!((fl->fl_ip_dport^sel->dport)&sel->dport_mask) &&
-		!((fl->fl_ip_sport^sel->sport)&sel->sport_mask) &&
+		!((xfrm_flowi_dport(fl) ^ sel->dport) & sel->dport_mask) &&
+		!((xfrm_flowi_sport(fl) ^ sel->sport) & sel->sport_mask) &&
 		(fl->proto == sel->proto || !sel->proto) &&
 		(fl->oif == sel->ifindex || !sel->ifindex);
 }


ChangeSet@1.1839, 2004-08-18 22:42:00+09:00, nakam@linux-ipv6.org
  [IPV6] XFRM: decode icmpv6 session.
  
  Signed-off-by: Masahide Nakamura <nakam@linux-ipv6.org>
  Signed-off-by: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>

diff -Nru a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
--- a/net/ipv6/xfrm6_policy.c	2004-08-18 22:58:54 +09:00
+++ b/net/ipv6/xfrm6_policy.c	2004-08-18 22:58:54 +09:00
@@ -213,6 +213,16 @@
 			fl->proto = nexthdr;
 			return;
 
+		case IPPROTO_ICMPV6:
+			if (pskb_may_pull(skb, skb->nh.raw + offset + 2 - skb->data)) {
+				u8 *icmp = (u8 *)exthdr;
+
+				fl->fl_icmp_type = icmp[0];
+				fl->fl_icmp_code = icmp[1];
+			}
+			fl->proto = nexthdr;
+			return;
+
 		/* XXX Why are there these headers? */
 		case IPPROTO_AH:
 		case IPPROTO_ESP:


ChangeSet@1.1840, 2004-08-18 22:43:52+09:00, nakam@linux-ipv6.org
  [IPV6] XFRM: probe icmpv6 type/code when sending packets via raw socket.
  
  Signed-off-by: Masahide Nakamura <nakam@linux-ipv6.org>
  Signed-off-by: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>

diff -Nru a/net/ipv6/raw.c b/net/ipv6/raw.c
--- a/net/ipv6/raw.c	2004-08-18 22:58:57 +09:00
+++ b/net/ipv6/raw.c	2004-08-18 22:58:57 +09:00
@@ -555,6 +555,52 @@
 	IP6_INC_STATS(IPSTATS_MIB_OUTDISCARDS);
 	return err; 
 }
+
+static void rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
+{
+	struct iovec *iov;
+	u8 *type = NULL;
+	u8 *code = NULL;
+	int probed = 0;
+	int i;
+
+	if (!msg->msg_iov)
+		return;
+
+	for (i = 0; i < msg->msg_iovlen; i++) {
+		iov = &msg->msg_iov[i];
+		if (!iov)
+			continue;
+
+		switch (fl->proto) {
+		case IPPROTO_ICMPV6:
+			/* check if one-byte field is readable or not. */
+			if (iov->iov_base && iov->iov_len < 1)
+				break;
+
+			if (!type) {
+				type = iov->iov_base;
+				/* check if code field is readable or not. */
+				if (iov->iov_len > 1)
+					code = type + 1;
+			} else if (!code)
+				code = iov->iov_base;
+
+			if (type && code) {
+				fl->fl_icmp_type = *type;
+				fl->fl_icmp_code = *code;
+				probed = 1;
+			}
+			break;
+		default:
+			probed = 1;
+			break;
+		}
+		if (probed)
+			break;
+	}
+}
+
 static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
 		   struct msghdr *msg, size_t len)
 {
@@ -674,6 +720,8 @@
 		opt = fl6_merge_options(&opt_space, flowlabel, opt);
 
 	fl.proto = proto;
+	rawv6_probe_proto_opt(&fl, msg);
+ 
 	ipv6_addr_copy(&fl.fl6_dst, daddr);
 	if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr))
 		ipv6_addr_copy(&fl.fl6_src, &np->saddr);


ChangeSet@1.1841, 2004-08-18 22:45:29+09:00, nakam@linux-ipv6.org
  [IPV4] XFRM: decode icmp session.
  
  Signed-off-by: Masahide Nakamura <nakam@linux-ipv6.org>
  Signed-off-by: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>

diff -Nru a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
--- a/net/ipv4/xfrm4_policy.c	2004-08-18 22:59:00 +09:00
+++ b/net/ipv4/xfrm4_policy.c	2004-08-18 22:59:00 +09:00
@@ -183,6 +183,15 @@
 			}
 			break;
 
+		case IPPROTO_ICMP:
+			if (pskb_may_pull(skb, xprth + 2 - skb->data)) {
+				u8 *icmp = xprth;
+
+				fl->fl_icmp_type = icmp[0];
+				fl->fl_icmp_code = icmp[1];
+			}
+			break;
+
 		case IPPROTO_ESP:
 			if (pskb_may_pull(skb, xprth + 4 - skb->data)) {
 				u32 *ehdr = (u32 *)xprth;


ChangeSet@1.1842, 2004-08-18 22:51:21+09:00, nakam@linux-ipv6.org
  [IPV4] XFRM: probe icmp type/code when sending packets via raw socket.
  
  Signed-off-by: Masahide Nakamura <nakam@linux-ipv6.org>
  Signed-off-by: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>

diff -Nru a/net/ipv4/raw.c b/net/ipv4/raw.c
--- a/net/ipv4/raw.c	2004-08-18 22:59:03 +09:00
+++ b/net/ipv4/raw.c	2004-08-18 22:59:03 +09:00
@@ -323,6 +323,51 @@
 	return err; 
 }
 
+static void raw_probe_proto_opt(struct flowi *fl, struct msghdr *msg)
+{
+	struct iovec *iov;
+	u8 *type = NULL;
+	u8 *code = NULL;
+	int probed = 0;
+	int i;
+
+	if (!msg->msg_iov)
+		return;
+
+	for (i = 0; i < msg->msg_iovlen; i++) {
+		iov = &msg->msg_iov[i];
+		if (!iov)
+			continue;
+
+		switch (fl->proto) {
+		case IPPROTO_ICMP:
+			/* check if one-byte field is readable or not. */
+			if (iov->iov_base && iov->iov_len < 1)
+				break;
+
+			if (!type) {
+				type = iov->iov_base;
+				/* check if code field is readable or not. */
+				if (iov->iov_len > 1)
+					code = type + 1;
+			} else if (!code)
+				code = iov->iov_base;
+
+			if (type && code) {
+				fl->fl_icmp_type = *type;
+				fl->fl_icmp_code = *code;
+				probed = 1;
+			}
+			break;
+		default:
+			probed = 1;
+			break;
+		}
+		if (probed)
+			break;
+	}
+}
+
 static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 		       size_t len)
 {
@@ -429,6 +474,8 @@
 				    .proto = inet->hdrincl ? IPPROTO_RAW :
 					    		     sk->sk_protocol,
 				  };
+		raw_probe_proto_opt(&fl, msg);
+
 		err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT));
 	}
 	if (err)


ChangeSet@1.1843, 2004-08-18 22:56:49+09:00, yoshfuji@linux-ipv6.org
  [IPV4] XFRM: don't probe icmp type/code for hdrincl sockets.
  
  Signed-off-by: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>

diff -Nru a/net/ipv4/raw.c b/net/ipv4/raw.c
--- a/net/ipv4/raw.c	2004-08-18 22:59:06 +09:00
+++ b/net/ipv4/raw.c	2004-08-18 22:59:06 +09:00
@@ -474,7 +474,8 @@
 				    .proto = inet->hdrincl ? IPPROTO_RAW :
 					    		     sk->sk_protocol,
 				  };
-		raw_probe_proto_opt(&fl, msg);
+		if (!inet->hdrincl)
+			raw_probe_proto_opt(&fl, msg);
 
 		err = ip_route_output_flow(&rt, &fl, sk, !(msg->msg_flags&MSG_DONTWAIT));
 	}



-- 
Hideaki YOSHIFUJI @ USAGI Project <yoshfuji@linux-ipv6.org>
GPG FP: 9022 65EB 1ECF 3AD1 0BDF  80D8 4807 F894 E062 0EEA

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] XFRM: ICMP{,v6} type/code support (Take 2) (was Re: [PATCH][IPSEC] IPsec policy can be matched by ICMP type and code)
  2004-08-18 14:09   ` [PATCH] XFRM: ICMP{,v6} type/code support (Take 2) (was Re: [PATCH][IPSEC] IPsec policy can be matched by ICMP type and code) YOSHIFUJI Hideaki / 吉藤英明
@ 2004-08-18 22:24     ` David S. Miller
  0 siblings, 0 replies; 9+ messages in thread
From: David S. Miller @ 2004-08-18 22:24 UTC (permalink / raw)
  To: yoshfuji; +Cc: nakam, netdev, usagi-core

On Wed, 18 Aug 2004 23:09:36 +0900 (JST)
YOSHIFUJI Hideaki / ^[$B5HF#1QL@^[(B <yoshfuji@linux-ipv6.org> wrote:

> > Truly %100 RAW sockets should have their packets untouched by
> > the kernel.  User wants exactly that packet to be sent onto
> > the wire.
> 
> Here's the updated version of the patch.
> Changesets are available at:
> 	<bk://bk.skbuff.net:20609/linux-2.6-xfrm-icmp/>.

Pulled, thanks Yoshifuji.

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2004-08-18 22:24 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-08-09  8:54 [PATCH][IPSEC] IPsec policy can be matched by ICMP type and code Masahide Nakamura
2004-08-09  9:03 ` YOSHIFUJI Hideaki / 吉藤英明
2004-08-10  0:07 ` David S. Miller
2004-08-10  1:32   ` YOSHIFUJI Hideaki / 吉藤英明
2004-08-11  6:01     ` David S. Miller
2004-08-11 19:14       ` David Stevens
2004-08-11 20:30         ` David S. Miller
2004-08-18 14:09   ` [PATCH] XFRM: ICMP{,v6} type/code support (Take 2) (was Re: [PATCH][IPSEC] IPsec policy can be matched by ICMP type and code) YOSHIFUJI Hideaki / 吉藤英明
2004-08-18 22:24     ` David S. Miller

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.