Re: [PATCH] [XFRM] Beet: Fix output for ipv6

2008-02-25 Thread Joakim Koskela
Hi Herbert, 

Have you had a chance to look this, or are you working on something else for 
it?

On Friday 08 February 2008 18:12, Joakim Koskela wrote:
 Hi,

 This patch fixes the ipv6 mode of ipsec beet. It has been using logic
 similar to tunnel mode, making it crash during esp packaging.

 Signed-off-by: Joakim Koskela [EMAIL PROTECTED]
 ---
  net/ipv6/xfrm6_mode_beet.c |9 ++---
  1 files changed, 6 insertions(+), 3 deletions(-)

 diff --git a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c
 index 0527d11..0395800 100644
 --- a/net/ipv6/xfrm6_mode_beet.c
 +++ b/net/ipv6/xfrm6_mode_beet.c
 @@ -40,11 +40,14 @@ static void xfrm6_beet_make_header(struct sk_buff *skb)
  static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb)
  {
   struct ipv6hdr *top_iph;
 + u8 *prevhdr;
 + int hdr_len;

 + hdr_len = x-type-hdr_offset(x, skb, prevhdr);
 + skb_set_mac_header(skb, (prevhdr - x-props.header_len) - skb-data);
   skb_set_network_header(skb, -x-props.header_len);
 - skb-mac_header = skb-network_header +
 -   offsetof(struct ipv6hdr, nexthdr);
 - skb-transport_header = skb-network_header + sizeof(*top_iph);
 + skb-transport_header = skb-network_header + hdr_len;
 + __skb_pull(skb, hdr_len);

   xfrm6_beet_make_header(skb);


--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] [XFRM] Beet: Fix output for ipv6

2008-02-08 Thread Joakim Koskela
Hi,

This patch fixes the ipv6 mode of ipsec beet. It has been using logic
similar to tunnel mode, making it crash during esp packaging.

Signed-off-by: Joakim Koskela [EMAIL PROTECTED]
---
 net/ipv6/xfrm6_mode_beet.c |9 ++---
 1 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c
index 0527d11..0395800 100644
--- a/net/ipv6/xfrm6_mode_beet.c
+++ b/net/ipv6/xfrm6_mode_beet.c
@@ -40,11 +40,14 @@ static void xfrm6_beet_make_header(struct sk_buff *skb)
 static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb)
 {
struct ipv6hdr *top_iph;
+   u8 *prevhdr;
+   int hdr_len;
 
+   hdr_len = x-type-hdr_offset(x, skb, prevhdr);
+   skb_set_mac_header(skb, (prevhdr - x-props.header_len) - skb-data);
skb_set_network_header(skb, -x-props.header_len);
-   skb-mac_header = skb-network_header +
- offsetof(struct ipv6hdr, nexthdr);
-   skb-transport_header = skb-network_header + sizeof(*top_iph);
+   skb-transport_header = skb-network_header + hdr_len;
+   __skb_pull(skb, hdr_len);
 
xfrm6_beet_make_header(skb);
 
--
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] netdev: Reset ipv4 flags during bundle creation on interfamily ipsec

2007-10-22 Thread Joakim Koskela
On Friday 19 October 2007 17:25:49 Herbert Xu wrote:
 Joakim Koskela [EMAIL PROTECTED] wrote:
  I'm not sure I follow. This affects the ipv6 bundling only where the
  struct (fl_tunnel) has previously been used for ipv6 addresses. Not that
  we are using the same block for holding the ipv4 info, the tos-value is
  really undefined before we reset it.

 You're right.  But sure the same bug could affect IPv4 as well
 if you had a 4-6-4 configuration.  Let me think about this one
 a bit more.

Hi, and thanks for the feedback. True, this one affects only one level of 
inter-family, and supporting more would require a lot more changes in the 
bundle creation (perhaps combining both versions and taking better into 
account the outer family of the last transformation..). 

Another quite annoying example of this is that 6 in 4 actually crashes the 
kernel on 64 bit, as xfrm_dst_lookup around xfrm6_policy.c:197 changes rt 
from a rt6_info to a rtable. On 64 bit, rt-rt61i_node will usually contain 
something (due to the larger pointer size), making the path_cookie assignment 
on line 208 crash.

I've been trying address this in a proper manner, but it hasn't really 
progressed quite the way I've wanted (..thus this shallow patch, just to make 
6-4 inter-work in most cases on the standard kernel). Needless to say, any 
work done for this would be greatly appreciated :)

-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] netdev: Interfamily support for IPSEC BEET

2007-10-22 Thread Joakim Koskela
On Friday 19 October 2007 17:22:22 Herbert Xu wrote:

 Please hold onto this.  I've got a more generic version of this
 that doesn't duplicate the inter-family logic between BEET mode
 and tunnel mode.

 Instead I've created a generic function that reads info from the
 inner header and puts them in an address-neutral format which is
 then picked up by either BEET or tunnel mode.

Ok, this really sounds like a good development. Do you think it could make it 
in time for 2.6.24?

Thanks,
Joakim
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] netdev: Netfilters on outgoing interfamily ipsec

2007-10-19 Thread Joakim Koskela
On Friday 19 October 2007 15:55:55 Herbert Xu wrote:
 While I agree that this is definitely a problem, I've already
 got a solution for it which we happen to need for async crypto
 anyway.

 Basically xfrm_output will invoke a continuation function based
 on the external mode/family which will then call the right hooks.

 Cheers,

Ok, great. Lets go with that.
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] netdev: Interfamily support for IPSEC BEET

2007-10-19 Thread Joakim Koskela
Hi,

Here's an updated version of the patch adding support for ipv4/ipv6
interfamily addressing for the ipsec BEET (Bound End-to-End Tunnel)
mode, as specified by the ietf draft found at:

http://www.ietf.org/internet-drafts/draft-nikander-esp-beet-mode-07.txt

The previous implementation required that both address pairs in the SA
were of the same family. This patch enables mixing ipv4 and ipv6
addresses. All combinations (4-4, 4-6, 6-4, 6-6) have been tested.

The generic interfamily fixes have been chopped off from this into
separate patches.

Signed-off-by: Joakim Koskela [EMAIL PROTECTED]
Signed-off-by: Herbert Xu [EMAIL PROTECTED]
Signed-off-by: Diego Beltrami [EMAIL PROTECTED]
Signed-off-by: Miika Komu [EMAIL PROTECTED]
---

diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 6b1a31a..b41e68d 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -288,8 +288,6 @@ static u32 esp4_get_mtu(struct xfrm_state *x, int mtu)
mtu += min_t(u32, blksize - 4, rem);
break;
case XFRM_MODE_BEET:
-   /* The worst case. */
-   mtu += min_t(u32, IPV4_BEET_PHMAXLEN, rem);
break;
}
 
@@ -397,8 +395,11 @@ static int esp_init_state(struct xfrm_state *x)
x-props.header_len = sizeof(struct ip_esp_hdr) + esp-conf.ivlen;
if (x-props.mode == XFRM_MODE_TUNNEL)
x-props.header_len += sizeof(struct iphdr);
-   else if (x-props.mode == XFRM_MODE_BEET)
-   x-props.header_len += IPV4_BEET_PHMAXLEN;
+   else if (x-props.mode == XFRM_MODE_BEET) {
+   if (x-sel.family == AF_INET) {
+   x-props.header_len += IPV4_BEET_PHMAXLEN;
+   }
+   }
if (x-encap) {
struct xfrm_encap_tmpl *encap = x-encap;
 
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index 2f14745..be58f8e 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -656,3 +656,6 @@ int ip_options_rcv_srr(struct sk_buff *skb)
}
return 0;
 }
+
+EXPORT_SYMBOL(ip_options_compile);
+
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index 5e95c8a..b2e9308 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -94,7 +94,9 @@ int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 
spi,
if (x-outer_mode-input(x, skb))
goto drop;
 
-   if (x-outer_mode-flags  XFRM_MODE_FLAG_TUNNEL) {
+   if ((x-outer_mode-flags  XFRM_MODE_FLAG_TUNNEL) 
+   (x-props.mode != XFRM_MODE_BEET ||
+x-sel.family != AF_INET)) {
decaps = 1;
break;
}
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c
index e42e122..1346efc 100644
--- a/net/ipv4/xfrm4_mode_beet.c
+++ b/net/ipv4/xfrm4_mode_beet.c
@@ -6,6 +6,7 @@
  *Herbert Xu [EMAIL PROTECTED]
  *Abhinav Pathak [EMAIL PROTECTED]
  *Jeff Ahrenholz [EMAIL PROTECTED]
+ *Joakim Koskela [EMAIL PROTECTED]
  */
 
 #include linux/init.h
@@ -16,6 +17,7 @@
 #include net/dst.h
 #include net/ip.h
 #include net/xfrm.h
+#include net/inet_ecn.h
 
 /* Add encapsulation header.
  *
@@ -23,88 +25,172 @@
  */
 static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
 {
-   struct ip_beet_phdr *ph;
-   struct iphdr *iph, *top_iph;
-   int hdrlen, optlen;
-
-   iph = ip_hdr(skb);
-
-   hdrlen = 0;
-   optlen = iph-ihl * 4 - sizeof(*iph);
-   if (unlikely(optlen))
-   hdrlen += IPV4_BEET_PHMAXLEN - (optlen  4);
-
-   skb_set_network_header(skb, IPV4_BEET_PHMAXLEN - x-props.header_len -
-   hdrlen);
-   skb-mac_header = skb-network_header +
- offsetof(struct iphdr, protocol);
-   skb-transport_header = skb-network_header + sizeof(*iph);
-
-   ph = (struct ip_beet_phdr *)__skb_pull(skb, sizeof(*iph) - hdrlen);
-
-   top_iph = ip_hdr(skb);
-   memmove(top_iph, iph, sizeof(*iph));
-   if (unlikely(optlen)) {
-   BUG_ON(optlen  0);
-
-   ph-padlen = 4 - (optlen  4);
-   ph-hdrlen = optlen / 8;
-   ph-nexthdr = top_iph-protocol;
-   if (ph-padlen)
-   memset(ph + 1, IPOPT_NOP, ph-padlen);
-
-   top_iph-protocol = IPPROTO_BEETPH;
-   top_iph-ihl = sizeof(struct iphdr) / 4;
-   }
+   struct dst_entry *dst = skb-dst;
+   struct iphdr *iphv4, *top_iphv4;
+   int hdrlen;
+
+   if (ip_hdr(skb)-version == 4) {
+   int optlen;
+   struct ip_beet_phdr *ph;
 
-   top_iph-saddr = x-props.saddr.a4;
-   top_iph-daddr = x-id.daddr.a4;
+   /* 4-4 */
+   iphv4 = ip_hdr(skb);
+
+   hdrlen = 0;
+   optlen = iphv4-ihl * 4 - sizeof

[PATCH] netdev: Reset ipv4 flags during bundle creation on interfamily ipsec

2007-10-19 Thread Joakim Koskela
This patch resets the ipv4-related flags in the new flow as their
content will otherwise depend on the bits of the ipv6 addresses the
struct was previously used for. For example, fl4_tos might have
RTO_ONLINK set, which usually prevents the right route from being
found.

This bit was chopped off the larger patch dealing with the problems
related to creating the bundles for inter-family tranformations.

Signed-off-by: Joakim Koskela [EMAIL PROTECTED]
--

diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 82e27b8..386a762 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -184,6 +184,8 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct 
xfrm_state **xfrm, int
case AF_INET:
fl_tunnel.fl4_dst = xfrm[i]-id.daddr.a4;
fl_tunnel.fl4_src = xfrm[i]-props.saddr.a4;
+   fl_tunnel.fl4_tos = 0;
+   fl_tunnel.fl4_scope = 0;
break;
case AF_INET6:
ipv6_addr_copy(fl_tunnel.fl6_dst, 
__xfrm6_bundle_addr_remote(xfrm[i], fl-fl6_dst));
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] netdev: Netfilters on outgoing interfamily ipsec

2007-10-19 Thread Joakim Koskela
Hi,

I understand that Herbert is in midst of cleaning up the output of
interfamily transformations, but I thought I'd post a couple of
patches related to that anyway, sort of to show what we've needed to
fix to get our systems working.

This one changes how the netfilters are applied during output to be
based on the current address family of the packet instead of what it
will be transformed to.

Signed-off-by: Joakim Koskela [EMAIL PROTECTED]
---

diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index c4a7156..8b0c6bd 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -13,6 +13,9 @@
 #include linux/kernel.h
 #include linux/skbuff.h
 #include linux/netfilter_ipv4.h
+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
+#include linux/netfilter_ipv6.h
+#endif
 #include net/ip.h
 #include net/xfrm.h
 #include net/icmp.h
@@ -139,7 +142,13 @@ static int xfrm4_output_finish(struct sk_buff *skb)
 
 int xfrm4_output(struct sk_buff *skb)
 {
-   return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, 
skb-dst-dev,
-   xfrm4_output_finish,
-   !(IPCB(skb)-flags  IPSKB_REROUTED));
+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
+   if (ip_hdr(skb)-version == 6)
+   return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL, 
skb-dst-dev,
+  xfrm4_output_finish);
+   else
+#endif
+   return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, 
skb-dst-dev,
+   xfrm4_output_finish,
+   !(IPCB(skb)-flags  IPSKB_REROUTED));
 }
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index 6569767..7624613 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -14,8 +14,10 @@
 #include linux/skbuff.h
 #include linux/icmpv6.h
 #include linux/netfilter_ipv6.h
+#include linux/netfilter_ipv4.h
 #include net/ipv6.h
 #include net/xfrm.h
+#include net/ip.h
 
 int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb,
  u8 **prevhdr)
@@ -134,6 +136,11 @@ static int xfrm6_output_finish(struct sk_buff *skb)
 
 int xfrm6_output(struct sk_buff *skb)
 {
-   return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL, skb-dst-dev,
-  xfrm6_output_finish);
+   if (ip_hdr(skb)-version == 4)
+   return NF_HOOK_COND(PF_INET, NF_IP_POST_ROUTING, skb, NULL, 
skb-dst-dev,
+   xfrm6_output_finish,
+   !(IPCB(skb)-flags  IPSKB_REROUTED));
+   else
+   return NF_HOOK(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL, 
skb-dst-dev,
+  xfrm6_output_finish);
 }
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] netdev: Reset ipv4 flags during bundle creation on interfamily ipsec

2007-10-19 Thread Joakim Koskela
On Friday 19 October 2007 16:09:05 Herbert Xu wrote:
 On Fri, Oct 19, 2007 at 02:40:16PM +0300, Joakim Koskela wrote:
 
  This bit was chopped off the larger patch dealing with the problems
  related to creating the bundles for inter-family tranformations.

 This changes behaviour.  Previously the same TOS value would be
 used all the way through.  With this it won't apply to the first
 tunnel and every SA after it.

 Cheers,

I'm not sure I follow. This affects the ipv6 bundling only where the struct 
(fl_tunnel) has previously been used for ipv6 addresses. Not that we are 
using the same block for holding the ipv4 info, the tos-value is really 
undefined before we reset it.

br, j
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH net-2.6.23-rc5] ipsec interfamily route handling fix

2007-10-11 Thread Joakim Koskela
On Friday 14 September 2007 23:42:52 David Miller wrote:
 From: Joakim Koskela [EMAIL PROTECTED]
 Date: Thu, 6 Sep 2007 19:00:10 +0300

  This patch addresses a couple of issues related to interfamily ipsec
  modes. The problem is that the structure of the routing info changes
  with the family during the __xfrmX_bundle_create, which hasn't been
  taken properly into account. Seems that by coincidence it hasn't

 Since nobody else found time to review this, I did :-)


Thanks for taking the time, and sorry for not getting back on this until
now..

 It sets encap_type in the inner loop, but what if we find multiple
 entries some ipv4 and some ipv6?  This logic can't be right.

 Instead, we need to treat these objects on an individual basis, I
 think, and that requires a bit more changes.

Yes, this is what I was worried about. But as I'm not that familiar with 
how these dst_entries are used down the line or with subpolicy 
transformations I didn't feel comfortable rewriting that completely.
I'm trying to get this thing solved (any help is of course appreciated :),
but in the meantime I think the following bit could actually be separated as,
although related, fixes an issue not directly tied to the original problem
(..and would be great to get applied as it makes interfamily work quite ok
for a number of setups). What do you think?

..and for a short description:

This patch resets the ipv4-related flags in the new flow as their content
will otherwise depend on the bits of the ipv6 addresses the struct was 
previously used for. For example, fl4_tos might have RTO_ONLINK set, which
usually prevents the right route from being found.

--
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 15aa4c5..b4a0b54 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -185,6 +185,8 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct 
xfrm_state **xfrm, int
case AF_INET:
fl_tunnel.fl4_dst = xfrm[i]-id.daddr.a4;
fl_tunnel.fl4_src = xfrm[i]-props.saddr.a4;
+   fl_tunnel.fl4_tos = 0;
+   fl_tunnel.fl4_scope = 0;
break;
case AF_INET6:
ipv6_addr_copy(fl_tunnel.fl6_dst, 
__xfrm6_bundle_addr_remote(xfrm[i], fl-fl6_dst));
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-2.6.23-rc5] ipsec interfamily route handling fix

2007-09-06 Thread Joakim Koskela
Hi,

This patch addresses a couple of issues related to interfamily ipsec
modes. The problem is that the structure of the routing info changes
with the family during the __xfrmX_bundle_create, which hasn't been
taken properly into account. Seems that by coincidence it hasn't
caused problems on 32bit platforms, but crashes for example on x86_64
in 6-4 around line 209 of xfrm6_policy.c as rt doesn't point to a
rt6_info anymore, but actually a struct rtable. With 64bit pointers,
the rt-rt6i_node pointer seems to hit something usually not null in
the rtable that rt now points to, making it go for the path_cookie
assignment and subsequently crashing.

Tested on both 32/64bit with all four (44/46/64/66) combinations of
transformation. I'm still a bit worried about how for example nested
transformations work with all of this and would appreciate if someone
more familiar with the details of these structs could comment.

Signed-off-by: Joakim Koskela [EMAIL PROTECTED]
---

diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index 4ff8ed3..7410c0d 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -72,6 +72,7 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct 
xfrm_state **xfrm, int
struct dst_entry *dst, *dst_prev;
struct rtable *rt0 = (struct rtable*)(*dst_p);
struct rtable *rt = rt0;
+   unsigned short encap_family = AF_INET;
struct flowi fl_tunnel = {
.nl_u = {
.ip4_u = {
@@ -118,7 +119,7 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct 
xfrm_state **xfrm, int
trailer_len += xfrm[i]-props.trailer_len;
 
if (xfrm[i]-props.mode == XFRM_MODE_TUNNEL) {
-   unsigned short encap_family = xfrm[i]-props.family;
+   encap_family = xfrm[i]-props.family;
switch (encap_family) {
case AF_INET:
fl_tunnel.fl4_dst = xfrm[i]-id.daddr.a4;
@@ -180,16 +181,19 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct 
xfrm_state **xfrm, int
}
dst_prev-output = afinfo-output;
xfrm_state_put_afinfo(afinfo);
-   if (dst_prev-xfrm-props.family == AF_INET  rt-peer)
-   atomic_inc(rt-peer-refcnt);
-   x-u.rt.peer = rt-peer;
+
+   if (encap_family == AF_INET) {
+   if (dst_prev-xfrm-props.family == AF_INET  rt-peer)
+   atomic_inc(rt-peer-refcnt);
+   x-u.rt.peer = rt-peer;
+   x-u.rt.rt_type = rt-rt_type;
+   x-u.rt.rt_gateway = rt-rt_gateway;
+   }
/* Sheit... I remember I did this right. Apparently,
 * it was magically lost, so this code needs audit */
x-u.rt.rt_flags = rt0-rt_flags(RTCF_BROADCAST|RTCF_MULTICAST|
RTCF_LOCAL);
-   x-u.rt.rt_type = rt-rt_type;
x-u.rt.rt_src = rt0-rt_src;
x-u.rt.rt_dst = rt0-rt_dst;
-   x-u.rt.rt_gateway = rt-rt_gateway;
x-u.rt.rt_spec_dst = rt0-rt_spec_dst;
x-u.rt.idev = rt0-idev;
in_dev_hold(rt0-idev);
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 3ec0c47..9733f39 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -131,6 +131,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct 
xfrm_state **xfrm, int
struct dst_entry *dst, *dst_prev;
struct rt6_info *rt0 = (struct rt6_info*)(*dst_p);
struct rt6_info *rt  = rt0;
+   unsigned short encap_family = AF_INET6;
struct flowi fl_tunnel = {
.nl_u = {
.ip6_u = {
@@ -180,11 +181,13 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct 
xfrm_state **xfrm, int
 
if (xfrm[i]-props.mode == XFRM_MODE_TUNNEL ||
xfrm[i]-props.mode == XFRM_MODE_ROUTEOPTIMIZATION) {
-   unsigned short encap_family = xfrm[i]-props.family;
+   encap_family = xfrm[i]-props.family;
switch(encap_family) {
case AF_INET:
fl_tunnel.fl4_dst = xfrm[i]-id.daddr.a4;
fl_tunnel.fl4_src = xfrm[i]-props.saddr.a4;
+   fl_tunnel.fl4_tos = 0;
+   fl_tunnel.fl4_scope = 0;
break;
case AF_INET6:
ipv6_addr_copy(fl_tunnel.fl6_dst, 
__xfrm6_bundle_addr_remote(xfrm[i], 
fl-fl6_dst));
@@ -205,7 +208,7 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct 
xfrm_state **xfrm, int
 
dst_prev-child = rt-u.dst;
dst-path = rt-u.dst;
-   if (rt-rt6i_node)
+   if (encap_family == AF_INET6  rt

tcp user timeout option

2007-08-31 Thread Joakim Koskela
Hi,

Does anybody know of any effort put into implementing support for the TCP user 
timeout option in Linux?

The related draft:
http://www.ietf.org/internet-drafts/draft-ietf-tcpm-tcp-uto-06.txt

Basically its a per-connection parameter which says how long data can remain 
unacknowledged before the connection is closed.

br, j
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: ipsec not working in 2.6.23-rc1-git10 when using pfkey

2007-08-06 Thread Joakim Koskela
On Friday 03 August 2007 01:01:14 David Miller wrote:
 Joakim, TEST YOUR PATCHES, and not just with your BEET test cases,
 before submitting them in the future.  Having normal configurations of
 both PF_KEY and XFRM_USER ipsec totally break as a result of your
 changes is totally unacceptable and I will doubly scrutinize your
 patch submissions in the future because of what has happened here.

Ok, seems fair and sorry for all the extra work this caused. Had a creeping 
feeling it would break something (as it so obviously could), but wrote it off 
as paranoia as it didn't seem to negatively affect either transport or tunnel 
mode (..but then again, I was only using the ip tool to manually set them 
up).

br, j
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH net-2.6.22-rc7] xfrm beet interfamily support

2007-08-06 Thread Joakim Koskela
On Tuesday 17 July 2007 17:30:21 Joakim Koskela wrote:
  Joakim Koskela wrote:
   diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
   index fa1902d..7a39f4c 100644
   --- a/net/ipv4/xfrm4_input.c
   +++ b/net/ipv4/xfrm4_input.c
   @@ -108,7 +108,8 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16
   encap_type) if (x-mode-input(x, skb))
 goto drop;
  
   - if (x-props.mode == XFRM_MODE_TUNNEL) {
   + if (x-props.mode == XFRM_MODE_TUNNEL ||
   + x-props.mode == XFRM_MODE_BEET) {
 decaps = 1;
 break;
 }
 
  I was under the impression that one of the main points of BEET is that
  it offers tunnel semantics but does only transport mode processing.
  Its necessary for inter-family tunnels, but shouldn't this be avoided
  for normal use?

 Yes, this is actually quite a nice improvement to the interfamily
 processing I (at least) haven't thought of before. Tested it  works fine
 (ipv4-ipv4).

It's been a while, but as a fyi in case there are comments / suggestions 
before submitting the whole patch again - it seems that this had some 
problems after all. Works ok for normal cases, but fails when using ip 
options for the inner packet as they don't get processed after being 
extracted from the pseudoheader. Calling something like ip_options_compile 
from beet_mode's input when handling ipv4 would do the trick, but seems a bit 
ugly  perhaps unsafe, I'd rather just put the whole packet through the loop 
again.

br, j
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH net-2.6.22-rc7] xfrm beet interfamily support

2007-08-06 Thread Joakim Koskela
On Monday 06 August 2007 15:08:12 Patrick McHardy wrote:
 
  It's been a while, but as a fyi in case there are comments / suggestions
  before submitting the whole patch again - it seems that this had some
  problems after all. Works ok for normal cases, but fails when using ip
  options for the inner packet as they don't get processed after being
  extracted from the pseudoheader. Calling something like
  ip_options_compile from beet_mode's input when handling ipv4 would do the
  trick, but seems a bit ugly  perhaps unsafe, I'd rather just put the
  whole packet through the loop again.

 Won't the options get parsed by ip_rcv() on the second reception?

Yes. The thing was that it seemed like we could get by with only a 
transport-mode- amount of processing of same-family beet packets. But unless 
we do some special processing during beet reception (which doesn't seem that 
elegant), it won't work. So I'm changing it back to tunnel-like processing.

br, j
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH net-2.6.22-rc7] xfrm beet interfamily support

2007-07-31 Thread Joakim Koskela
On Thursday 19 July 2007 17:46:42 Patrick McHardy wrote:
 Joakim Koskela wrote:
  +   skb_push(skb, hdrlen);
  +   iphv6 = ipv6_hdr(skb);
  +
  +   skb_reset_network_header(skb);
  +   top_iphv6 = ipv6_hdr(skb);
  +
  +   protocol = iphv6-nexthdr;
  +   skb_pull(skb, delta);
  +   skb_reset_network_header(skb);
  +   top_iphv4 = ip_hdr(skb);
  +   skb_set_transport_header(skb, hdrlen);
  +   top_iphv4-ihl = (sizeof(struct iphdr)  2);
  +   top_iphv4-version = 4;
  +   top_iphv4-id = 0;
  +   top_iphv4-frag_off = htons(IP_DF);
  +   top_iphv4-ttl = dst_metric(dst-child, RTAX_HOPLIMIT);
  +   top_iphv4-saddr = x-props.saddr.a4;
  +   top_iphv4-daddr = x-id.daddr.a4;
  +   skb-transport_header += top_iphv4-ihl*4;
  +   top_iphv4-protocol = protocol;
  +
  +   skb-protocol = htons(ETH_P_IP);
  +#endif

 The output function in the IPv6/IPv4 case is called from
 xfrm6_output_one, which loops until after a tunnel mode
 encapsulation is done and then returns to the outer loop
 in xfrm6_output_finish2, which passes the packet through
 the netfilter hooks and continues with the next transform.


I'm not sure I really got this. IPv6/IPv4 means IPv6 inner, IPv4 outer, right? 
Isn't that called from xfrm4_output_one and subsequently passed through the 
right filters as well (as it has a ipv4 header by then)?

 There are multiple problems resulting from the inter-family
 encapsulation. First of all, the inner loop continues after
 beet mode encapsulation, skipping the netfilter hooks in
 case there are more transforms. It should (as with decaps = 1
 on input) at least call netfilter hooks after an inter-family
 transform. If the beet transform is the last one, the IPv4
 skb will be passed through the IPv6 netfilter hooks, which is
 clearly wrong. To fix these problems some restructuring in
 xfrm[46]_output.c seems to be necessary.

Couldn't this be solved just by ending the inner loop in case of beet mode (as 
it is done for tunnel)?

br, j

-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH net-2.6.22-rc7] xfrm beet interfamily support

2007-07-31 Thread Joakim Koskela
On Tuesday 31 July 2007 13:51:42 Patrick McHardy wrote:
 Joakim Koskela wrote:
  I'm not sure I really got this. IPv6/IPv4 means IPv6 inner, IPv4 outer,
  right? Isn't that called from xfrm4_output_one and subsequently passed
  through the right filters as well (as it has a ipv4 header by then)?

 I think you're right, it uses xfrm4_output. But there's a mismatch
 in either case, in both cases (IPv4 and IPv6) we first call the
 POSTROUTING hook for this family, than do the transform (changing
 the family), then call the OUTPUT hook for the same family. So
 either the POSTROUTING or the OUTPUT hook is called for the wrong
 family.

Ok, so changing int xfrm[46]_output(struct sk_buff*) to use the right PF  
hook based on the skb's [current] family should put things through the right 
hoops, right?

br, j
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH net-2.6.22-rc7] xfrm beet interfamily support

2007-07-31 Thread Joakim Koskela
On Tuesday 31 July 2007 14:14:30 Patrick McHardy wrote:
 Joakim Koskela wrote:
  Ok, so changing int xfrm[46]_output(struct sk_buff*) to use the right PF
   hook based on the skb's [current] family should put things through the
  right hoops, right?

 Almost, in xfrm4_output the conditional calling of the hook should
 only be done for IPv4 and the IPCB is not valid for IPv6 of course.
 Speaking of which, shouldn't the entire cb be zeroed for interfamily
 transforms? xfrm4_tunnel_output only clears out the options, and I
 think your patch didn't touch it at all ..

Right, thanks for pointing out (to my understanding both flags and opts should 
be reset for 6-4, on 4-4 only the opts)!

br ,j
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-2.6.22-rc7] xfrm state selection update to use inner addresses

2007-07-23 Thread Joakim Koskela
This patch modifies the xfrm state selection logic to use the inner
addresses where the outer have been (incorrectly) used. This is
required for beet mode in general and interfamily setups in both
tunnel and beet mode.

Signed-off-by: Joakim Koskela [EMAIL PROTECTED]
Signed-off-by: Herbert Xu [EMAIL PROTECTED]
Signed-off-by: Diego Beltrami [EMAIL PROTECTED]
Signed-off-by: Miika Komu [EMAIL PROTECTED]
---

diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 157bfbd..75fdb7d 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1299,7 +1299,8 @@ xfrm_tmpl_resolve_one(struct xfrm_policy *policy, struct 
flowi *fl,
xfrm_address_t *local  = saddr;
struct xfrm_tmpl *tmpl = policy-xfrm_vec[i];
 
-   if (tmpl-mode == XFRM_MODE_TUNNEL) {
+   if (tmpl-mode == XFRM_MODE_TUNNEL ||
+   tmpl-mode == XFRM_MODE_BEET) {
remote = tmpl-id.daddr;
local = tmpl-saddr;
family = tmpl-encap_family;
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index e070c3f..f5d30c4 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -611,7 +611,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t 
*saddr,
  selector.
 */
if (x-km.state == XFRM_STATE_VALID) {
-   if (!xfrm_selector_match(x-sel, fl, family) ||
+   if (!xfrm_selector_match(x-sel, fl, 
x-sel.family) ||
!security_xfrm_state_pol_flow_match(x, pol, 
fl))
continue;
if (!best ||
@@ -623,7 +623,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t 
*saddr,
acquire_in_progress = 1;
} else if (x-km.state == XFRM_STATE_ERROR ||
   x-km.state == XFRM_STATE_EXPIRED) {
-   if (xfrm_selector_match(x-sel, fl, family) 
+   if (xfrm_selector_match(x-sel, fl, 
x-sel.family) 
security_xfrm_state_pol_flow_match(x, pol, 
fl))
error = -ESRCH;
}
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-2.6.22-rc7] xfrm beet interfamily support

2007-07-19 Thread Joakim Koskela
Hi all,

Here's once again a corrected version of the patch adding support for
ipv4/ipv6 interfamily addressing for the ipsec BEET (Bound End-to-End
Tunnel) mode, as specified by the ietf draft found at:

http://www.ietf.org/internet-drafts/draft-nikander-esp-beet-mode-07.txt

The previous implementation required that both address pairs in the SA
were of the same family. This patch enables mixing ipv4 and ipv6
addresses. All combinations (4-4, 4-6, 6-4, 6-6) have been tested
using manual key setups.

Signed-off-by: Joakim Koskela [EMAIL PROTECTED]
Signed-off-by: Herbert Xu [EMAIL PROTECTED]
Signed-off-by: Diego Beltrami [EMAIL PROTECTED]
Signed-off-by: Miika Komu [EMAIL PROTECTED]
---

diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index fa1902d..43c0d80 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -108,7 +108,9 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
if (x-mode-input(x, skb))
goto drop;
 
-   if (x-props.mode == XFRM_MODE_TUNNEL) {
+   if (x-props.mode == XFRM_MODE_TUNNEL ||
+   (x-props.mode == XFRM_MODE_BEET 
+x-sel.family != AF_INET)) {
decaps = 1;
break;
}
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c
index a73e710..20e0610 100644
--- a/net/ipv4/xfrm4_mode_beet.c
+++ b/net/ipv4/xfrm4_mode_beet.c
@@ -6,6 +6,7 @@
  *Herbert Xu [EMAIL PROTECTED]
  *Abhinav Pathak [EMAIL PROTECTED]
  *Jeff Ahrenholz [EMAIL PROTECTED]
+ *Joakim Koskela [EMAIL PROTECTED]
  */
 
 #include linux/init.h
@@ -24,92 +25,179 @@
  *  tot_len
  *  check
  *
- * On exit, skb-h will be set to the start of the payload to be processed
- * by x-type-output and skb-nh will be set to the top IP header.
+ * On exit, skb-transport_header will be set to the start of the
+ * payload to be processed by x-type-output and skb-network_header
+ * will be set to the top IP header.
  */
 static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
 {
-   struct iphdr *iph, *top_iph;
-   int hdrlen, optlen;
-
-   iph = ip_hdr(skb);
-   skb-transport_header = skb-network_header;
-
-   hdrlen = 0;
-   optlen = iph-ihl * 4 - sizeof(*iph);
-   if (unlikely(optlen))
-   hdrlen += IPV4_BEET_PHMAXLEN - (optlen  4);
-
-   skb_push(skb, x-props.header_len - IPV4_BEET_PHMAXLEN + hdrlen);
-   skb_reset_network_header(skb);
-   top_iph = ip_hdr(skb);
-   skb-transport_header += sizeof(*iph) - hdrlen;
-
-   memmove(top_iph, iph, sizeof(*iph));
-   if (unlikely(optlen)) {
-   struct ip_beet_phdr *ph;
-
-   BUG_ON(optlen  0);
-
-   ph = (struct ip_beet_phdr *)skb_transport_header(skb);
-   ph-padlen = 4 - (optlen  4);
-   ph-hdrlen = optlen / 8;
-   ph-nexthdr = top_iph-protocol;
-   if (ph-padlen)
-   memset(ph + 1, IPOPT_NOP, ph-padlen);
-
-   top_iph-protocol = IPPROTO_BEETPH;
-   top_iph-ihl = sizeof(struct iphdr) / 4;
+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
+   struct ipv6hdr *iphv6, *top_iphv6;
+#endif
+   struct dst_entry *dst = skb-dst;
+   struct iphdr *iphv4, *top_iphv4;
+   int hdrlen;
+
+   if (ip_hdr(skb)-version == 4) {
+   int optlen;
+
+   /* 4-4 */
+   iphv4 = ip_hdr(skb);
+   skb-transport_header = skb-network_header;
+
+   hdrlen = 0;
+   optlen = iphv4-ihl * 4 - sizeof(*iphv4);
+   if (unlikely(optlen))
+   hdrlen += IPV4_BEET_PHMAXLEN - (optlen  4);
+
+   skb_push(skb, x-props.header_len - IPV4_BEET_PHMAXLEN + 
hdrlen);
+   skb_reset_network_header(skb);
+   top_iphv4 = ip_hdr(skb);
+   skb-transport_header += sizeof(*iphv4) - hdrlen;
+
+   memmove(top_iphv4, iphv4, sizeof(*iphv4));
+   if (unlikely(optlen)) {
+   struct ip_beet_phdr *ph;
+
+   BUG_ON(optlen  0);
+
+   ph = (struct ip_beet_phdr *)skb_transport_header(skb);
+   ph-padlen = 4 - (optlen  4);
+   ph-hdrlen = optlen / 8;
+   ph-nexthdr = iphv4-protocol;
+   if (ph-padlen)
+   memset(ph + 1, IPOPT_NOP, ph-padlen);
+   top_iphv4-protocol = IPPROTO_BEETPH;
+   top_iphv4-ihl = sizeof(struct iphdr) / 4;
+   }
+
+   top_iphv4-saddr = x-props.saddr.a4;
+   top_iphv4-daddr = x-id.daddr.a4;
+
+   skb-protocol = htons(ETH_P_IP);
+   } else if (ip_hdr(skb)-version == 6) {
+#if defined

Re: [PATCH net-2.6.22-rc7] xfrm beet interfamily support

2007-07-19 Thread Joakim Koskela
On Thursday 19 July 2007 17:46:42 Patrick McHardy wrote:
  -
  +   if (xfrm[i]-props.mode != XFRM_MODE_TRANSPORT) {
  +   encap_family = xfrm[i]-props.family;
  +   if (encap_family == AF_INET) {
  +   remote.in = (struct in_addr *)
  +   xfrm[i]-id.daddr.a4;
  +   local.in  = (struct in_addr *)
  +   xfrm[i]-props.saddr.a4;
  +#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
  +   } else if (encap_family == AF_INET6) {
  +   remote.in6 = (struct in6_addr *)
  +   xfrm[i]-id.daddr.a6;
  +   local.in6 = (struct in6_addr *)
  +   xfrm[i]-props.saddr.a6;
  +#endif

 You set the addresses above ..

..

 and don't seem to use them for anything.


Right. Thought I removed that [redundant code], but apparently only on the 
ipv6 side, thanks.


  diff --git a/net/ipv6/xfrm6_state.c b/net/ipv6/xfrm6_state.c
  +   /* Rule 5: select IPsec BEET */
  +   for (i = 0; i  n; i++) {
  +   if (src[i] 
  +   src[i]-props.mode == XFRM_MODE_BEET) {
  +   dst[j++] = src[i];
  +   src[i] = NULL;
  +   }
  +   }

 Just out of interest, is there any particular logic behind the
 ordering of the rules?


Got me there. Not that familiar with the details of the other modes to make 
even any educated guesses..

  if (likely(j == n))
  goto end;
 
  diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
  index 157bfbd..75fdb7d 100644
  --- a/net/xfrm/xfrm_policy.c
  +++ b/net/xfrm/xfrm_policy.c
  @@ -1299,7 +1299,8 @@ xfrm_tmpl_resolve_one(struct xfrm_policy *policy,
  struct flowi *fl, xfrm_address_t *local  = saddr;
  struct xfrm_tmpl *tmpl = policy-xfrm_vec[i];
 
  -   if (tmpl-mode == XFRM_MODE_TUNNEL) {
  +   if (tmpl-mode == XFRM_MODE_TUNNEL ||
  +   tmpl-mode == XFRM_MODE_BEET) {

 Is this a bugfix?

  remote = tmpl-id.daddr;
  local = tmpl-saddr;
  family = tmpl-encap_family;
  diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
  index dfacb9c..0a2ff8e 100644
  --- a/net/xfrm/xfrm_state.c
  +++ b/net/xfrm/xfrm_state.c
  @@ -611,7 +611,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t
  *saddr, selector.
   */
  if (x-km.state == XFRM_STATE_VALID) {
  -   if (!xfrm_selector_match(x-sel, fl, family) ||
  +   if (!xfrm_selector_match(x-sel, fl, 
  x-sel.family) ||
  !security_xfrm_state_pol_flow_match(x, pol, 
  fl))
  continue;
  if (!best ||
  @@ -623,7 +623,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t
  *saddr, acquire_in_progress = 1;
  } else if (x-km.state == XFRM_STATE_ERROR ||
 x-km.state == XFRM_STATE_EXPIRED) {
  -   if (xfrm_selector_match(x-sel, fl, family) 
  +   if (xfrm_selector_match(x-sel, fl, 
  x-sel.family) 
  security_xfrm_state_pol_flow_match(x, pol, 
  fl))
  error = -ESRCH;
  }

 And these two? Also look like bugfixes ..
 -

Well yes if we're using interfamily anywhere. D'you think they deserve a patch 
for themselves?

Thanks again for reviewing, I'll address the other issues asap. Sort of eager 
to get this out as its been dangling for such a long time, but seems I'm 
taking a lot of things for granted (..as its been sitting around 'ok' for so 
long). 

br, j
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH net-2.6.22-rc7] xfrm beet interfamily support

2007-07-17 Thread Joakim Koskela
On Monday 16 July 2007 21:47:40 Patrick McHardy wrote:

 I lost interest here, but the reintroduced bugs make me think that
 some old version was simply rediffed without even checking the
 output and the state initialization also seems to need a bit more work.


Thanks for reviewing the code, really appreciate it (whoa, would have been a 
lot of problems [re-]introduced)! And yes, you're right - it seemed at the 
time easier to just convert the old code to run in the new kernel as it's 
been working fine for us. Quickly scanned the existing (non-interfamily) beet 
implementation, but I guess not thoroughly enough. Anyway, merged back the 
latest non-interfamily versions and rolling with those now. Should have a 
fixed version ready soon..

Some other comments:

 Joakim Koskela wrote:
  diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
  index fa1902d..7a39f4c 100644
  --- a/net/ipv4/xfrm4_input.c
  +++ b/net/ipv4/xfrm4_input.c
  @@ -108,7 +108,8 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16
  encap_type) if (x-mode-input(x, skb))
  goto drop;
 
  -   if (x-props.mode == XFRM_MODE_TUNNEL) {
  +   if (x-props.mode == XFRM_MODE_TUNNEL ||
  +   x-props.mode == XFRM_MODE_BEET) {
  decaps = 1;
  break;
  }

 I was under the impression that one of the main points of BEET is that
 it offers tunnel semantics but does only transport mode processing.
 Its necessary for inter-family tunnels, but shouldn't this be avoided
 for normal use?


Yes, this is actually quite a nice improvement to the interfamily processing I 
(at least) haven't thought of before. Tested it  works fine (ipv4-ipv4).


  diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
  index 44ef208..8db7910 100644
  --- a/net/ipv4/xfrm4_output.c
  +++ b/net/ipv4/xfrm4_output.c
  @@ -53,7 +53,8 @@ static int xfrm4_output_one(struct sk_buff *skb)
  goto error_nolock;
  }
 
  -   if (x-props.mode == XFRM_MODE_TUNNEL) {
  +   if (x-props.mode == XFRM_MODE_TUNNEL ||
  +   x-props.mode == XFRM_MODE_BEET) {
  err = xfrm4_tunnel_check_size(skb);

 Its not a real tunnel and all packets are generated locally, why
 does it need to send ICMPs?

Guess not. I'll have to still trace through, but can probably be removed.

  +   if (xfrm[i]-props.mode != XFRM_MODE_TRANSPORT) {
  +   encap_family = xfrm[i]-props.family;
  +   if (encap_family == AF_INET) {
  +   remote.in = (struct in_addr *)
  +   xfrm[i]-id.daddr.a4;
  +   local.in  = (struct in_addr *)
  +   xfrm[i]-props.saddr.a4;
  +   } else if (encap_family == AF_INET6) {
  +   remote.in6 = (struct in6_addr *)
  +   xfrm[i]-id.daddr.a6;
  +   local.in6 = (struct in6_addr *)
  +   xfrm[i]-props.saddr.a6;
  +   }

 No ifdefs here?

Thanks for noticing!

   static int ipip_init_state(struct xfrm_state *x)
   {
  -   if (x-props.mode != XFRM_MODE_TUNNEL)
  +   if (x-props.mode != XFRM_MODE_TUNNEL ||
  +   x-props.mode != XFRM_MODE_BEET)
  return -EINVAL;

 Looks like a bug fix that should be seperated.


Probably. This has been there for a while, don't know what's the story behind 
it, have to check..

br, j
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH net-2.6.22-rc7] xfrm beet interfamily support

2007-07-16 Thread Joakim Koskela
Hi all,

Here's again a cleaned-up and corrected version of the patch adding
support for ipv4/ipv6 interfamily addressing for the ipsec BEET (Bound
End-to-End Tunnel) mode, as specified by the ietf draft found at:

http://www.ietf.org/internet-drafts/draft-nikander-esp-beet-mode-07.txt

The previous implementation required that both address pairs in the SA
were of the same family. This patch enables mixing ipv4 and ipv6
addresses. All combinations (4-4, 4-6, 6-4, 6-6) have been tested
using manual key setups.

Signed-off-by: Joakim Koskela [EMAIL PROTECTED]
Signed-off-by: Herbert Xu [EMAIL PROTECTED]
Signed-off-by: Diego Beltrami [EMAIL PROTECTED]
Signed-off-by: Miika Komu [EMAIL PROTECTED]
---

diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index fa1902d..7a39f4c 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -108,7 +108,8 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
if (x-mode-input(x, skb))
goto drop;
 
-   if (x-props.mode == XFRM_MODE_TUNNEL) {
+   if (x-props.mode == XFRM_MODE_TUNNEL ||
+   x-props.mode == XFRM_MODE_BEET) {
decaps = 1;
break;
}
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c
index a73e710..2994dc5 100644
--- a/net/ipv4/xfrm4_mode_beet.c
+++ b/net/ipv4/xfrm4_mode_beet.c
@@ -6,6 +6,7 @@
  *Herbert Xu [EMAIL PROTECTED]
  *Abhinav Pathak [EMAIL PROTECTED]
  *Jeff Ahrenholz [EMAIL PROTECTED]
+ *Joakim Koskela [EMAIL PROTECTED]
  */
 
 #include linux/init.h
@@ -29,86 +30,176 @@
  */
 static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
 {
-   struct iphdr *iph, *top_iph;
-   int hdrlen, optlen;
-
-   iph = ip_hdr(skb);
-   skb-transport_header = skb-network_header;
-
-   hdrlen = 0;
-   optlen = iph-ihl * 4 - sizeof(*iph);
-   if (unlikely(optlen))
-   hdrlen += IPV4_BEET_PHMAXLEN - (optlen  4);
-
-   skb_push(skb, x-props.header_len - IPV4_BEET_PHMAXLEN + hdrlen);
-   skb_reset_network_header(skb);
-   top_iph = ip_hdr(skb);
-   skb-transport_header += sizeof(*iph) - hdrlen;
-
-   memmove(top_iph, iph, sizeof(*iph));
-   if (unlikely(optlen)) {
-   struct ip_beet_phdr *ph;
-
-   BUG_ON(optlen  0);
-
-   ph = (struct ip_beet_phdr *)skb_transport_header(skb);
-   ph-padlen = 4 - (optlen  4);
-   ph-hdrlen = optlen / 8;
-   ph-nexthdr = top_iph-protocol;
-   if (ph-padlen)
-   memset(ph + 1, IPOPT_NOP, ph-padlen);
-
-   top_iph-protocol = IPPROTO_BEETPH;
-   top_iph-ihl = sizeof(struct iphdr) / 4;
+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
+   struct ipv6hdr *iphv6, *top_iphv6;
+#endif
+   struct dst_entry *dst = skb-dst;
+   struct iphdr *iphv4, *top_iphv4;
+   int hdrlen;
+
+   if (ip_hdr(skb)-version == 4) {
+   int optlen;
+
+   /* 4-4 */
+   iphv4 = ip_hdr(skb);
+   skb_set_transport_header(skb, skb_network_offset(skb));
+
+   hdrlen = x-props.header_len;
+   optlen = iphv4-ihl * 4 - sizeof(*iphv4);
+   if (!optlen) {
+   hdrlen -= IPV4_BEET_PHMAXLEN;
+   } else {
+   skb-transport_header -=
+   (IPV4_BEET_PHMAXLEN - (optlen  4));
+   hdrlen -= optlen  4;
+   }
+
+   skb_push(skb, hdrlen);
+   skb_reset_network_header(skb);
+
+   top_iphv4 = ip_hdr(skb);
+   hdrlen = iphv4-ihl * 4 - optlen;
+   skb-transport_header += hdrlen;
+   memmove(top_iphv4, iphv4, hdrlen);
+
+   if (unlikely(optlen)) {
+   struct ip_beet_phdr *ph;
+
+   BUG_ON(optlen  0);
+
+   ph = (struct ip_beet_phdr *)skb_transport_header(skb);
+   ph-padlen = 4 - (optlen  4);
+   ph-hdrlen = (optlen + ph-padlen + sizeof(*ph)) / 8;
+   ph-nexthdr = iphv4-protocol;
+   top_iphv4-protocol = IPPROTO_BEETPH;
+   top_iphv4-ihl = sizeof(struct iphdr) / 4;
+   }
+
+   top_iphv4-saddr = x-props.saddr.a4;
+   top_iphv4-daddr = x-id.daddr.a4;
+
+   skb-protocol = htons(ETH_P_IP);
+   } else if (ip_hdr(skb)-version == 6) {
+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
+   int delta = sizeof(struct ipv6hdr) - sizeof(struct iphdr);
+   u8 protocol;
+
+   /* Inner = 6, Outer = 4 : changing the external IP hdr
+* to the outer addresses

[PATCH net-2.6.22-rc7] xfrm beet interfamily support

2007-07-12 Thread Joakim Koskela
Hi,

This (resubmitted) patch adds support for ipv4/ipv6 interfamily
addressing for the ipsec BEET (Bound End-to-End Tunnel) mode, as
specified by the ietf draft found at:

http://www.ietf.org/internet-drafts/draft-nikander-esp-beet-mode-07.txt

The previous implementation required that both address pairs in the SA
were of the same family. This patch enables mixing ipv4 and ipv6
addresses. All combinations (4-4, 4-6, 6-4, 6-6) have been tested
using manual key setups.

Signed-off-by: Joakim Koskela [EMAIL PROTECTED]
Signed-off-by: Herbert Xu [EMAIL PROTECTED]
Signed-off-by: Diego Beltrami [EMAIL PROTECTED]
Signed-off-by: Miika Komu [EMAIL PROTECTED]
---

diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index fa1902d..105b36a 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -108,7 +108,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
if (x-mode-input(x, skb))
goto drop;
 
-   if (x-props.mode == XFRM_MODE_TUNNEL) {
+   if (x-props.mode == XFRM_MODE_TUNNEL || x-props.mode == 
XFRM_MODE_BEET) {
decaps = 1;
break;
}
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c
index a73e710..004dc6b 100644
--- a/net/ipv4/xfrm4_mode_beet.c
+++ b/net/ipv4/xfrm4_mode_beet.c
@@ -6,6 +6,7 @@
  *Herbert Xu [EMAIL PROTECTED]
  *Abhinav Pathak [EMAIL PROTECTED]
  *Jeff Ahrenholz [EMAIL PROTECTED]
+ *Joakim Koskela [EMAIL PROTECTED]
  */
 
 #include linux/init.h
@@ -29,86 +30,175 @@
  */
 static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
 {
-   struct iphdr *iph, *top_iph;
-   int hdrlen, optlen;
-
-   iph = ip_hdr(skb);
-   skb-transport_header = skb-network_header;
-
-   hdrlen = 0;
-   optlen = iph-ihl * 4 - sizeof(*iph);
-   if (unlikely(optlen))
-   hdrlen += IPV4_BEET_PHMAXLEN - (optlen  4);
-
-   skb_push(skb, x-props.header_len - IPV4_BEET_PHMAXLEN + hdrlen);
-   skb_reset_network_header(skb);
-   top_iph = ip_hdr(skb);
-   skb-transport_header += sizeof(*iph) - hdrlen;
-
-   memmove(top_iph, iph, sizeof(*iph));
-   if (unlikely(optlen)) {
-   struct ip_beet_phdr *ph;
-
-   BUG_ON(optlen  0);
-
-   ph = (struct ip_beet_phdr *)skb_transport_header(skb);
-   ph-padlen = 4 - (optlen  4);
-   ph-hdrlen = optlen / 8;
-   ph-nexthdr = top_iph-protocol;
-   if (ph-padlen)
-   memset(ph + 1, IPOPT_NOP, ph-padlen);
-
-   top_iph-protocol = IPPROTO_BEETPH;
-   top_iph-ihl = sizeof(struct iphdr) / 4;
-   }
-
-   top_iph-saddr = x-props.saddr.a4;
-   top_iph-daddr = x-id.daddr.a4;
-
-   return 0;
+struct dst_entry *dst = skb-dst;
+int hdrlen;
+struct iphdr *iphv4, *top_iphv4;
+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
+struct ipv6hdr *iphv6, *top_iphv6;
+#endif
+if (ip_hdr(skb)-version == 4) {
+int optlen;
+
+/* 4-4 */
+
+iphv4 = ip_hdr(skb);
+skb-transport_header = skb-network_header;
+
+hdrlen = x-props.header_len;
+optlen = iphv4-ihl * 4 - sizeof(*iphv4);
+
+if (!optlen) {
+hdrlen -= IPV4_BEET_PHMAXLEN;
+} else {
+skb-transport_header -= (IPV4_BEET_PHMAXLEN - (optlen 
 4));
+hdrlen -= optlen  4;
+}
+
+skb-network_header = skb_push(skb, hdrlen);
+
+top_iphv4 = ip_hdr(skb);
+hdrlen = iphv4-ihl * 4 - optlen;
+skb-transport_header += hdrlen;
+memmove(top_iphv4, iphv4, hdrlen);
+
+if (unlikely(optlen)) {
+struct ip_beet_phdr *ph;
+
+BUG_ON(optlen  0);
+
+ph = (struct ip_beet_phdr *)skb-transport_header;
+ph-padlen = 4 - (optlen  4);
+ph-hdrlen = (optlen + ph-padlen + sizeof(*ph)) / 8;
+ph-nexthdr = iphv4-protocol;
+top_iphv4-protocol = IPPROTO_BEETPH;
+top_iphv4-ihl = sizeof(struct iphdr) / 4;
+}
+
+top_iphv4-saddr = x-props.saddr.a4;
+top_iphv4-daddr = x-id.daddr.a4;
+
+skb-protocol = htons(ETH_P_IP);
+
+   } else if (ip_hdr(skb)-version == 6) {
+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
+
+u8 protocol

[PATCH 2.6.22-rc2] xfrm BEET interfamily support

2007-05-30 Thread Joakim Koskela
Hi,

Here is the patch for the net-2.6 (22-rc2) BEET (Bound End-to-End
Tunnel) mode implementation to support ipv4/ipv6 interfamily
addressing, as specified by the ietf draft found at:

http://www.ietf.org/internet-drafts/draft-nikander-esp-beet-mode-07.txt

The previous implementation required that both address pairs in the SA
were of the same family. This patch enables mixing ipv4 and ipv6
addresses. All combinations (4-4, 4-6, 6-4, 6-6) have been tested
using manual key setups. Also, the existing tunnel mode was run
through as this patch modifies the xfrm state selection (in
xfrm_state.c).

Signed-off-by: Joakim Koskela [EMAIL PROTECTED]
Signed-off-by: Herbert Xu [EMAIL PROTECTED]
Signed-off-by: Diego Beltrami [EMAIL PROTECTED]
Signed-off-by: Miika Komu [EMAIL PROTECTED]
---

diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c
index 5ceca95..969d79d 100644
--- a/net/ipv4/xfrm4_input.c
+++ b/net/ipv4/xfrm4_input.c
@@ -108,7 +108,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)
if (x-mode-input(x, skb))
goto drop;
 
-   if (x-props.mode == XFRM_MODE_TUNNEL) {
+   if (x-props.mode == XFRM_MODE_TUNNEL || x-props.mode == 
XFRM_MODE_BEET) {
decaps = 1;
break;
}
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c
index a73e710..004dc6b 100644
--- a/net/ipv4/xfrm4_mode_beet.c
+++ b/net/ipv4/xfrm4_mode_beet.c
@@ -6,6 +6,7 @@
  *Herbert Xu [EMAIL PROTECTED]
  *Abhinav Pathak [EMAIL PROTECTED]
  *Jeff Ahrenholz [EMAIL PROTECTED]
+ *Joakim Koskela [EMAIL PROTECTED]
  */
 
 #include linux/init.h
@@ -29,86 +30,175 @@
  */
 static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
 {
-   struct iphdr *iph, *top_iph;
-   int hdrlen, optlen;
-
-   iph = ip_hdr(skb);
-   skb-transport_header = skb-network_header;
-
-   hdrlen = 0;
-   optlen = iph-ihl * 4 - sizeof(*iph);
-   if (unlikely(optlen))
-   hdrlen += IPV4_BEET_PHMAXLEN - (optlen  4);
-
-   skb_push(skb, x-props.header_len - IPV4_BEET_PHMAXLEN + hdrlen);
-   skb_reset_network_header(skb);
-   top_iph = ip_hdr(skb);
-   skb-transport_header += sizeof(*iph) - hdrlen;
-
-   memmove(top_iph, iph, sizeof(*iph));
-   if (unlikely(optlen)) {
-   struct ip_beet_phdr *ph;
-
-   BUG_ON(optlen  0);
-
-   ph = (struct ip_beet_phdr *)skb_transport_header(skb);
-   ph-padlen = 4 - (optlen  4);
-   ph-hdrlen = optlen / 8;
-   ph-nexthdr = top_iph-protocol;
-   if (ph-padlen)
-   memset(ph + 1, IPOPT_NOP, ph-padlen);
-
-   top_iph-protocol = IPPROTO_BEETPH;
-   top_iph-ihl = sizeof(struct iphdr) / 4;
-   }
-
-   top_iph-saddr = x-props.saddr.a4;
-   top_iph-daddr = x-id.daddr.a4;
-
-   return 0;
+struct dst_entry *dst = skb-dst;
+int hdrlen;
+struct iphdr *iphv4, *top_iphv4;
+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
+struct ipv6hdr *iphv6, *top_iphv6;
+#endif
+if (ip_hdr(skb)-version == 4) {
+int optlen;
+
+/* 4-4 */
+
+iphv4 = ip_hdr(skb);
+skb-transport_header = skb-network_header;
+
+hdrlen = x-props.header_len;
+optlen = iphv4-ihl * 4 - sizeof(*iphv4);
+
+if (!optlen) {
+hdrlen -= IPV4_BEET_PHMAXLEN;
+} else {
+skb-transport_header -= (IPV4_BEET_PHMAXLEN - (optlen 
 4));
+hdrlen -= optlen  4;
+}
+
+skb-network_header = skb_push(skb, hdrlen);
+
+top_iphv4 = ip_hdr(skb);
+hdrlen = iphv4-ihl * 4 - optlen;
+skb-transport_header += hdrlen;
+memmove(top_iphv4, iphv4, hdrlen);
+
+if (unlikely(optlen)) {
+struct ip_beet_phdr *ph;
+
+BUG_ON(optlen  0);
+
+ph = (struct ip_beet_phdr *)skb-transport_header;
+ph-padlen = 4 - (optlen  4);
+ph-hdrlen = (optlen + ph-padlen + sizeof(*ph)) / 8;
+ph-nexthdr = iphv4-protocol;
+top_iphv4-protocol = IPPROTO_BEETPH;
+top_iphv4-ihl = sizeof(struct iphdr) / 4;
+}
+
+top_iphv4-saddr = x-props.saddr.a4;
+top_iphv4-daddr = x-id.daddr.a4;
+
+skb-protocol = htons(ETH_P_IP);
+
+   } else if (ip_hdr(skb

Re: Problem with xfrm (ipsec) as state/spi selected solely on outer ip addresses

2007-05-14 Thread Joakim Koskela
On Friday 11 May 2007 19:13:41 Patrick McHardy wrote:
 Joakim Koskela wrote:
  I'm running a system where there might be multiple simultenously
  active ipsec states between two hosts (ipv6, but guess it applies to
  v4 as well) where the outer ip is the same for all states, but the
  inner differ (using beet mode).
 
  The problem is that after establishing these states, it seems that the
  one associated with outgoing traffic is selected solely by the outer
  address (the first state matching the outer ip-pairs is used), which
  usually results in the wrong spi and the packet being dropped at the
  receiver.

 This should only pick states matching the flow:

 if (x-km.state == XFRM_STATE_VALID) {


 if (!xfrm_selector_match(x-sel, fl, family) ||
 !security_xfrm_state_pol_flow_match(x, pol, fl))
 continue;
 ...

 I'm probably misunderstanding your configuration, could you post the
 SA selectors and addresses that result in an incorrect state being
 picked?

 -
 To unsubscribe from this list: send the line unsubscribe netdev in
 the body of a message to [EMAIL PROTECTED]
 More majordomo info at  http://vger.kernel.org/majordomo-info.html

Oh, your right. I wasn't setting the netmask correctly (zero) for the 
selectors, making them match anything. Sorry for the waste of time!

br, j

-- 
Joakim Koskela
Helsinki Institute for Information Technology (HIIT)
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Problem with xfrm (ipsec) as state/spi selected solely on outer ip addresses

2007-05-11 Thread Joakim Koskela
Hi all, 

I'm running a system where there might be multiple simultenously
active ipsec states between two hosts (ipv6, but guess it applies to
v4 as well) where the outer ip is the same for all states, but the
inner differ (using beet mode).

The problem is that after establishing these states, it seems that the
one associated with outgoing traffic is selected solely by the outer
address (the first state matching the outer ip-pairs is used), which
usually results in the wrong spi and the packet being dropped at the
receiver.

I've circumvented the problem by modifying the state selection
algorithm in xfrm_state_find() [xfrm_state.c] to prefer, if possible,
states which also match by the inner addresses. Is this really a
problem of the selection algorithm, or might I be doing something 
wrong elsewhere?

Here's the changes I've done to make it work for me.  As said, it
prefers states with matching inner-address, but if none is found it
works as before:


diff -urN  a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
--- a/net/xfrm/xfrm_state.c 2007-05-11 15:37:35.0 +0300
+++ b/net/xfrm/xfrm_state.c 2007-05-11 15:37:35.0 +0300
@@ -374,6 +374,17 @@
(best-km.dying == x-km.dying 
 best-curlft.add_time  
x-curlft.add_time))
best = x;
+   else if (pol-selector.family == x-sel.family 

+(pol-selector.family == AF_INET6 
+ !ipv6_addr_cmp((struct in6_addr 
*)pol-selector.daddr,
+(struct in6_addr 
*)x-sel.daddr) 
+ !ipv6_addr_cmp((struct in6_addr 
*)pol-selector.saddr,
+(struct in6_addr 
*)x-sel.saddr)) ||
+(pol-selector.family == AF_INET 
+ pol-selector.daddr.a4 == 
x-sel.daddr.a4 
+ pol-selector.saddr.a4 == 
x-sel.saddr.a4))
+   best = x;
+
} else if (x-km.state == XFRM_STATE_ACQ) {
acquire_in_progress = 1;
} else if (x-km.state == XFRM_STATE_ERROR ||

br, j

--
Joakim Koskela
Helsinki Institute for Information Technology, http://www.hiit.fi
-
To unsubscribe from this list: send the line unsubscribe netdev in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html