I am trying to build a custom kernel for the HIPL code (infrahip.hip.fi), using the patch for the Linux 2.6.18 kernel. I followed all the instructions for getting the kernel source and making a custom kernel provided on the wiki. The rpmbuild fails with the following messages: Get an error on this step (figured out my other problem): Patch #40000 (centos-5.2-hipmod-sleep-beet-and-interfamily-all-in-one.patch): 1 out of 4 hunks FAILED -- saving rejects to file net/ipv4/xfrm4_output.c.rej 2 out of 3 hunks FAILED -- saving rejects to file net/ipv4/esp4.c.rej 1 out of 1 hunk FAILED -- saving rejects to file net/ipv6/udp.c.rej 1 out of 1 hunk FAILED -- saving rejects to file net/ipv6/tcp_ipv6.c.rej 1 out of 1 hunk FAILED -- saving rejects to file net/ipv6/esp6.c.rej 2 out of 2 hunks FAILED -- saving rejects to file net/ipv6/icmp.c.rej 2 out of 2 hunks FAILED -- saving rejects to file net/xfrm/xfrm_state.c.rej 1 out of 2 hunks FAILED -- saving rejects to file include/net/xfrm.h.rej Reversed (or previously applied) patch detected! Assume -R? [n] Apply anyway? [n] 1 out of 1 hunk ignored -- saving rejects to file include/linux/net.h.rej I've asked for help on the hipl list, but there is no real experience there with Centos (FC8 and 9), and they are trying to help, put perhaps someone here might know what I am doing wrong? Oh, one question was asked about how the ~/rpmbuild/BUILD/kernel-2.16.18 directory looks like. I think the linux-2.6.18.i386 (or i686) is not what the patch is expecting? Here is the patch file (centos-5.2-hipmod-sleep-beet-and-interfamily-all-in-one.patch): diff -urN a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c --- a/net/ipv4/xfrm4_input.c 2007-05-25 12:21:11.000000000 +0300 +++ b/net/ipv4/xfrm4_input.c 2007-05-25 12:21:11.000000000 +0300 @@ -13,6 +13,7 @@ #include <linux/string.h> #include <linux/netfilter.h> #include <linux/netfilter_ipv4.h> +#include <net/inet_ecn.h> #include <net/ip.h> #include <net/xfrm.h> @@ -23,6 +24,15 @@ EXPORT_SYMBOL(xfrm4_rcv); +static inline void ipip_ecn_decapsulate(struct sk_buff *skb) +{ + struct iphdr *outer_iph = skb->nh.iph; + struct iphdr *inner_iph = skb->h.ipiph; + + if (INET_ECN_is_ce(outer_iph->tos)) + IP_ECN_set_ce(inner_iph); +} + static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq) { switch (nexthdr) { @@ -103,11 +113,11 @@ xfrm_vec[xfrm_nr++] = x; - if (x->mode->input(x, skb)) + if (x->mode->input(x, skb)) goto drop; - + if (x->props.mode) { - decaps = 1; + decaps = 1; break; } diff -urN a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c --- a/net/ipv4/xfrm4_output.c 2007-05-25 12:21:11.000000000 +0300 +++ b/net/ipv4/xfrm4_output.c 2007-05-25 12:21:11.000000000 +0300 @@ -14,10 +14,12 @@ #include <linux/skbuff.h> #include <linux/spinlock.h> #include <linux/netfilter_ipv4.h> +#include <net/inet_ecn.h> #include <net/ip.h> #include <net/xfrm.h> #include <net/icmp.h> + static int xfrm4_tunnel_check_size(struct sk_buff *skb) { int mtu, ret = 0; @@ -54,7 +56,7 @@ goto error_nolock; } - if (x->props.mode) { + if (x->props.mode == XFRM_MODE_TUNNEL) { err = xfrm4_tunnel_check_size(skb); if (err) goto error_nolock; @@ -66,7 +68,7 @@ if (err) goto error; - err = x->mode->output(skb); + err = x->mode->output(skb); if (err) goto error; @@ -85,6 +87,7 @@ } dst = skb->dst; x = dst->xfrm; + } while (x && !x->props.mode); IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED; diff -urN a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c --- a/net/ipv4/xfrm4_tunnel.c 2007-05-25 12:21:11.000000000 +0300 +++ b/net/ipv4/xfrm4_tunnel.c 2007-05-25 12:21:11.000000000 +0300 @@ -28,13 +28,20 @@ static int ipip_init_state(struct xfrm_state *x) { - if (!x->props.mode) - return -EINVAL; - if (x->encap) return -EINVAL; - x->props.header_len = sizeof(struct iphdr); + switch (x->props.mode) { + case XFRM_MODE_TRANSPORT: + return -EINVAL; + default: + case XFRM_MODE_TUNNEL: + x->props.header_len = sizeof(struct iphdr); + break; + case XFRM_MODE_BEET: + x->props.header_len += IPV4_BEET_PHMAXLEN; + break; + } return 0; } diff -urN a/net/ipv4/route.c b/net/ipv4/route.c --- a/net/ipv4/route.c 2007-05-25 12:21:11.000000000 +0300 +++ b/net/ipv4/route.c 2007-05-25 12:21:11.000000000 +0300 @@ -108,6 +108,7 @@ #ifdef CONFIG_SYSCTL #include <linux/sysctl.h> #endif +#include <linux/xfrm.h> #define RT_FL_TOS(oldflp) \ ((u32)(oldflp->fl4_tos & (IPTOS_RT_MASK | RTO_ONLINK))) @@ -2631,7 +2632,7 @@ int ip_route_output_key(struct rtable **rp, struct flowi *flp) { - return ip_route_output_flow(rp, flp, NULL, 0); + return ip_route_output_flow(rp, flp, NULL, XFRM_LOOKUP_SLEEP); } static int rt_fill_info(struct sk_buff *skb, u32 pid, u32 seq, int event, diff -urN a/net/ipv4/ah4.c b/net/ipv4/ah4.c --- a/net/ipv4/ah4.c 2007-05-25 12:21:11.000000000 +0300 +++ b/net/ipv4/ah4.c 2007-05-25 12:21:11.000000000 +0300 @@ -253,8 +253,10 @@ goto error; x->props.header_len = XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + ahp->icv_trunc_len); - if (x->props.mode) + 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; x->data = ahp; return 0; diff -urN a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c --- a/net/ipv4/xfrm4_policy.c 2007-05-25 12:21:11.000000000 +0300 +++ b/net/ipv4/xfrm4_policy.c 2007-05-25 12:21:11.000000000 +0300 @@ -16,6 +16,8 @@ static struct dst_ops xfrm4_dst_ops; static struct xfrm_policy_afinfo xfrm4_policy_afinfo; +static void xfrm4_update_pmtu(struct dst_entry *dst, u32 mtu); + static int xfrm4_dst_lookup(struct xfrm_dst **dst, struct flowi *fl) { return __ip_route_output_key((struct rtable**)dst, fl); @@ -53,17 +55,20 @@ struct dst_entry *dst, *dst_prev; struct rtable *rt0 = (struct rtable*)(*dst_p); struct rtable *rt = rt0; - u32 remote = fl->fl4_dst; - u32 local = fl->fl4_src; struct flowi fl_tunnel = { .nl_u = { .ip4_u = { - .saddr = local, - .daddr = remote, + .saddr = fl->fl4_dst, + .daddr = fl->fl4_src, .tos = fl->fl4_tos } } }; + union { + struct in6_addr *in6; + struct in_addr *in; + } remote, local; + unsigned short outer_family = 0, beet = 0; int i; int err; int header_len = 0; @@ -75,7 +80,6 @@ for (i = 0; i < nx; i++) { struct dst_entry *dst1 = dst_alloc(&xfrm4_dst_ops); struct xfrm_dst *xdst; - int tunnel = 0; if (unlikely(dst1 == NULL)) { err = -ENOBUFS; @@ -96,21 +100,45 @@ dst1->next = dst_prev; dst_prev = dst1; - if (xfrm[i]->props.mode) { - remote = xfrm[i]->id.daddr.a4; - local = xfrm[i]->props.saddr.a4; - tunnel = 1; + + if (xfrm[i]->props.mode == XFRM_MODE_TUNNEL || xfrm[i]->props.mode == XFRM_MODE_BEET) { + outer_family = xfrm[i]->props.family; + beet = (xfrm[i]->props.mode == XFRM_MODE_BEET); + + if(outer_family == AF_INET6){ + remote.in6 = (struct in6_addr*)&xfrm[i]->id.daddr; + local.in6 = (struct in6_addr*)&xfrm[i]->props.saddr; + } else if(outer_family == AF_INET){ + remote.in = (struct in_addr*)&xfrm[i]->id.daddr; + local.in = (struct in_addr*)&xfrm[i]->props.saddr; + } else + BUG_ON(1); } header_len += xfrm[i]->props.header_len; trailer_len += xfrm[i]->props.trailer_len; - if (tunnel) { - fl_tunnel.fl4_src = local; - fl_tunnel.fl4_dst = remote; + if (outer_family) { + switch(outer_family) { + case AF_INET: + fl_tunnel.fl4_dst = remote.in->s_addr; + fl_tunnel.fl4_src = local.in->s_addr; + break; + case AF_INET6: + ipv6_addr_copy(&fl_tunnel.fl6_dst, remote.in6); + ipv6_addr_copy(&fl_tunnel.fl6_src, local.in6); + break; + default: + BUG_ON(1); + } err = xfrm_dst_lookup((struct xfrm_dst **)&rt, - &fl_tunnel, AF_INET); + &fl_tunnel, outer_family); if (err) goto error; + /* Without this, the atomic inc below segfaults */ + if (outer_family == AF_INET6) { + rt->peer = NULL; + rt_bind_peer(rt,1); + } } else dst_hold(&rt->u.dst); } @@ -160,6 +188,11 @@ } xfrm_init_pmtu(dst); + if (beet && outer_family == AF_INET6) { + int delta = sizeof(struct ipv6hdr) - sizeof(struct iphdr); + u32 mtu = dst_mtu(dst); + xfrm4_update_pmtu(dst, mtu - delta); + } return 0; error: diff -urN a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c --- a/net/ipv4/xfrm4_mode_tunnel.c 2007-05-25 12:21:11.000000000 +0300 +++ b/net/ipv4/xfrm4_mode_tunnel.c 2007-05-25 12:21:11.000000000 +0300 @@ -33,7 +33,7 @@ * 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. */ -static int xfrm4_tunnel_output(struct sk_buff *skb) + static int xfrm4_tunnel_output(struct sk_buff *skb) { struct dst_entry *dst = skb->dst; struct xfrm_state *x = dst->xfrm; @@ -98,6 +98,182 @@ return err; } +/* jk: this should be moved to the beet module! */ +static int xfrm4_beet_output(struct sk_buff *skb) +{ + struct dst_entry *dst = skb->dst; + struct xfrm_state *x = dst->xfrm; + int hdrlen; + struct iphdr *iphv4, *top_iphv4; + struct ipv6hdr *iphv6, *top_iphv6; + + if (skb->nh.iph->version == 4) { + + int optlen; + + /* 4-4 */ + + iphv4 = skb->nh.iph; + skb->h.ipiph = iphv4; + + hdrlen = x->props.header_len; + + optlen = iphv4->ihl * 4 - sizeof(*iphv4); + if (!optlen) { + hdrlen -= IPV4_BEET_PHMAXLEN; + } else { + skb->h.raw -= (IPV4_BEET_PHMAXLEN - (optlen & 4)); + hdrlen -= optlen & 4; + } + + skb->nh.raw = skb_push(skb, hdrlen); + top_iphv4 = skb->nh.iph; + + hdrlen = iphv4->ihl * 4 - optlen; + skb->h.raw += hdrlen; + memmove(top_iphv4, iphv4, hdrlen); + + if (unlikely(optlen)) { + struct ip_beet_phdr *ph; + + BUG_ON(optlen < 0); + + ph = (struct ip_beet_phdr *)skb->h.raw; + 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; + + } else if (skb->nh.iph->version == 6) { + + u8 protocol; + int delta = sizeof(struct ipv6hdr) - sizeof(struct iphdr); + + /* Inner = 6, Outer = 4 : changing the external IP hdr + * to the outer addresses + */ + + hdrlen = x->props.header_len - IPV4_BEET_PHMAXLEN; + skb_push(skb, hdrlen); + iphv6 = skb->nh.ipv6h; + + skb->nh.raw = skb->data; + top_iphv6 = skb->nh.ipv6h; + + protocol = iphv6->nexthdr; + skb->nh.raw = skb_pull(skb, delta); + top_iphv4 = skb->nh.iph; + skb->h.raw = skb->data + 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->h.raw += top_iphv4->ihl*4; + top_iphv4->protocol = protocol; + + } else + BUG_ON(1); + + return 0; +} + + +/* jk: this should be moved to the beet module! */ +static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb) +{ + int err = -EINVAL; + int phlen = 0; + int optlen = 0; + __u8 ph_nexthdr = 0; + int size = (x->sel.family == AF_INET) ? sizeof(struct iphdr) : sizeof(struct ipv6hdr); + int proto = skb->nh.iph->protocol; + int hops = skb->nh.iph->ttl; + int delta = sizeof(struct ipv6hdr) - sizeof(struct iphdr); + + if (x->sel.family == AF_INET6) { + /* Here, the inner family is 6, therefore I have to + * substitute the IPhdr by enlarging it */ + if (skb_tailroom(skb) < delta){ + if (pskb_expand_head(skb, 0, delta, GFP_ATOMIC)) + goto out; //Just returning from here. + } + + skb->nh.raw -= delta; + } else if (x->sel.family == AF_INET) { + // We need to extract the PH + struct ip_beet_phdr *ph = (struct ip_beet_phdr*)(skb->nh.iph + 1); + + if (proto == IPPROTO_BEETPH) { + if (!pskb_may_pull(skb, sizeof(*ph))) + goto out; + phlen = ph->hdrlen * 8; + optlen = phlen - ph->padlen - sizeof(*ph); + + if (optlen < 0 || optlen & 3 || optlen > 250) + goto out; + if (!pskb_may_pull(skb, phlen)) + goto out; + + ph_nexthdr = ph->nexthdr; + } + } else + BUG_ON(1); + + if (skb_cloned(skb) && + pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) + goto out; + + skb_push(skb, size); + memmove(skb->data, skb->nh.raw, size); + skb->nh.raw = skb->data; + + if (x->sel.family == AF_INET) { + struct iphdr *iph = skb->nh.iph; + + if (unlikely(phlen)) { + skb_pull(skb, phlen - optlen); + memmove(skb->data, skb->nh.raw, sizeof(*iph)); + skb->nh.raw = skb->data; + iph = skb->nh.iph; + } + + iph->ihl = (sizeof(*iph) + optlen) / 4; + iph->tot_len = htons(skb->len); + iph->daddr = x->sel.daddr.a4; + iph->saddr = x->sel.saddr.a4; + if (ph_nexthdr) + iph->protocol = ph_nexthdr; + else + iph->protocol = proto; + ip_send_check(iph); + } else if (x->sel.family == AF_INET6) { + struct ipv6hdr *ip6h = skb->nh.ipv6h; + + memset(ip6h->flow_lbl, 0, sizeof(ip6h->flow_lbl)); + ip6h->version = 6; + ip6h->priority = 0; + ip6h->nexthdr = proto; + ip6h->hop_limit = hops; + ip6h->payload_len = htons(skb->len - size); + ipv6_addr_copy(&ip6h->daddr, (struct in6_addr *)&x->sel.daddr.a6); + ipv6_addr_copy(&ip6h->saddr, (struct in6_addr *)&x->sel.saddr.a6); + skb->protocol = htons(ETH_P_IPV6); + } + + err = 0; + out: + + return err; +} + static struct xfrm_mode xfrm4_tunnel_mode = { .input = xfrm4_tunnel_input, .output = xfrm4_tunnel_output, @@ -105,8 +281,19 @@ .encap = XFRM_MODE_TUNNEL, }; +/* jk: this should be moved to the beet module! */ +static struct xfrm_mode xfrm4_beet_mode = { + .input = xfrm4_beet_input, + .output = xfrm4_beet_output, + .owner = THIS_MODULE, + .encap = XFRM_MODE_BEET, +}; + static int __init xfrm4_tunnel_init(void) { + int err; + /* jk: this should be moved to the beet module! */ + err = xfrm_register_mode(&xfrm4_beet_mode, AF_INET); return xfrm_register_mode(&xfrm4_tunnel_mode, AF_INET); } @@ -114,6 +301,9 @@ { int err; + /* jk: this should be moved to the beet module! */ + err = xfrm_unregister_mode(&xfrm4_beet_mode, AF_INET); + BUG_ON(err); err = xfrm_unregister_mode(&xfrm4_tunnel_mode, AF_INET); BUG_ON(err); } diff -urN a/net/ipv4/esp4.c b/net/ipv4/esp4.c --- a/net/ipv4/esp4.c 2007-05-25 12:21:11.000000000 +0300 +++ b/net/ipv4/esp4.c 2007-05-25 12:21:11.000000000 +0300 @@ -237,7 +237,8 @@ * as per draft-ietf-ipsec-udp-encaps-06, * section 3.1.2 */ - if (!x->props.mode) + if (x->props.mode == XFRM_MODE_TRANSPORT || + x->props.mode == XFRM_MODE_BEET) skb->ip_summed = CHECKSUM_UNNECESSARY; } @@ -255,17 +256,27 @@ { struct esp_data *esp = x->data; u32 blksize = ALIGN(crypto_tfm_alg_blocksize(esp->conf.tfm), 4); + int enclen = 0; - if (x->props.mode) { - mtu = ALIGN(mtu + 2, blksize); - } else { - /* The worst case. */ + switch (x->props.mode) { + default: + case XFRM_MODE_TUNNEL: + mtu = ALIGN(mtu +2, blksize); + break; + case XFRM_MODE_TRANSPORT: + /* The worst case */ mtu = ALIGN(mtu + 2, 4) + blksize - 4; + break; + case XFRM_MODE_BEET: + /* The worst case. */ + enclen = IPV4_BEET_PHMAXLEN; + mtu = ALIGN(mtu + enclen + 2, blksize); + break; } if (esp->conf.padlen) mtu = ALIGN(mtu, esp->conf.padlen); - return mtu + x->props.header_len + esp->auth.icv_trunc_len; + return mtu + x->props.header_len + esp->auth.icv_trunc_len - enclen; } static void esp4_err(struct sk_buff *skb, u32 info) @@ -368,8 +379,10 @@ if (crypto_cipher_setkey(esp->conf.tfm, esp->conf.key, esp->conf.key_len)) goto error; x->props.header_len = sizeof(struct ip_esp_hdr) + esp->conf.ivlen; - if (x->props.mode) + 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; if (x->encap) { struct xfrm_encap_tmpl *encap = x->encap; diff -urN a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c --- a/net/ipv4/ipcomp.c 2007-05-25 12:21:11.000000000 +0300 +++ b/net/ipv4/ipcomp.c 2007-05-25 12:21:11.000000000 +0300 @@ -176,7 +176,7 @@ return 0; out_ok: - if (x->props.mode) + if (x->props.mode == XFRM_MODE_TUNNEL) ip_send_check(iph); return 0; } @@ -216,7 +216,7 @@ t->id.daddr.a4 = x->id.daddr.a4; memcpy(&t->sel, &x->sel, sizeof(t->sel)); t->props.family = AF_INET; - t->props.mode = 1; + t->props.mode = x->props.mode; t->props.saddr.a4 = x->props.saddr.a4; t->props.flags = x->props.flags; @@ -415,8 +415,10 @@ goto out; x->props.header_len = 0; - if (x->props.mode) + 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; mutex_lock(&ipcomp_resource_mutex); if (!ipcomp_alloc_scratches()) @@ -427,7 +429,7 @@ goto error; mutex_unlock(&ipcomp_resource_mutex); - if (x->props.mode) { + if (x->props.mode == XFRM_MODE_TUNNEL) { err = ipcomp_tunnel_attach(x); if (err) goto error_tunnel; diff -urN a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c --- a/net/ipv6/xfrm6_input.c 2007-05-25 12:21:11.000000000 +0300 +++ b/net/ipv6/xfrm6_input.c 2007-05-25 12:21:11.000000000 +0300 @@ -13,9 +13,21 @@ #include <linux/string.h> #include <linux/netfilter.h> #include <linux/netfilter_ipv6.h> +#include <net/dsfield.h> +#include <net/inet_ecn.h> +#include <net/ip.h> #include <net/ipv6.h> #include <net/xfrm.h> +static inline void ipip6_ecn_decapsulate(struct sk_buff *skb) +{ + struct ipv6hdr *outer_iph = skb->nh.ipv6h; + struct ipv6hdr *inner_iph = skb->h.ipv6h; + + if (INET_ECN_is_ce(ipv6_get_dsfield(outer_iph))) + IP6_ECN_set_ce(inner_iph); +} + int xfrm6_rcv_spi(struct sk_buff *skb, u32 spi) { int err; @@ -33,7 +45,6 @@ seq = 0; if (!spi && (err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) != 0) goto drop; - do { struct ipv6hdr *iph = skb->nh.ipv6h; @@ -44,6 +55,7 @@ if (x == NULL) goto drop; spin_lock(&x->lock); + if (unlikely(x->km.state != XFRM_STATE_VALID)) goto drop_unlock; @@ -69,16 +81,17 @@ xfrm_vec[xfrm_nr++] = x; - if (x->mode->input(x, skb)) + if (x->mode->input(x, skb)) goto drop; - - if (x->props.mode) { /* XXX */ - decaps = 1; - break; + + if (x->props.mode) { + decaps = 1; + break; } if ((err = xfrm_parse_spi(skb, nexthdr, &spi, &seq)) < 0) goto drop; + } while (!err); /* Allocate new secpath or COW existing one. */ @@ -110,6 +123,7 @@ netif_rx(skb); return -1; } else { + #ifdef CONFIG_NETFILTER skb->nh.ipv6h->payload_len = htons(skb->len); __skb_push(skb, skb->data - skb->nh.raw); diff -urN a/net/ipv6/ah6.c b/net/ipv6/ah6.c --- a/net/ipv6/ah6.c 2007-05-25 12:21:11.000000000 +0300 +++ b/net/ipv6/ah6.c 2007-05-25 12:21:11.000000000 +0300 @@ -387,8 +387,10 @@ goto error; x->props.header_len = XFRM_ALIGN8(sizeof(struct ipv6_auth_hdr) + ahp->icv_trunc_len); - if (x->props.mode) + if (x->props.mode == XFRM_MODE_TUNNEL) x->props.header_len += sizeof(struct ipv6hdr); + else if (x->props.mode == XFRM_MODE_BEET) + x->props.header_len += IPV4_BEET_PHMAXLEN; x->data = ahp; return 0; diff -urN a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c --- a/net/ipv6/xfrm6_policy.c 2007-05-25 12:21:11.000000000 +0300 +++ b/net/ipv6/xfrm6_policy.c 2007-05-25 12:21:11.000000000 +0300 @@ -22,6 +22,8 @@ static struct dst_ops xfrm6_dst_ops; static struct xfrm_policy_afinfo xfrm6_policy_afinfo; +static void xfrm6_update_pmtu(struct dst_entry *dst, u32 mtu); + static int xfrm6_dst_lookup(struct xfrm_dst **dst, struct flowi *fl) { int err = 0; @@ -70,16 +72,19 @@ struct dst_entry *dst, *dst_prev; struct rt6_info *rt0 = (struct rt6_info*)(*dst_p); struct rt6_info *rt = rt0; - struct in6_addr *remote = &fl->fl6_dst; - struct in6_addr *local = &fl->fl6_src; struct flowi fl_tunnel = { .nl_u = { .ip6_u = { - .saddr = *local, - .daddr = *remote + .saddr = fl->fl6_src, + .daddr = fl->fl6_dst } } }; + union { + struct in6_addr *in6; + struct in_addr *in; + } remote, local; + unsigned short outer_family = 0, beet = 0; int i; int err = 0; int header_len = 0; @@ -91,7 +96,6 @@ for (i = 0; i < nx; i++) { struct dst_entry *dst1 = dst_alloc(&xfrm6_dst_ops); struct xfrm_dst *xdst; - int tunnel = 0; if (unlikely(dst1 == NULL)) { err = -ENOBUFS; @@ -114,19 +118,39 @@ dst1->next = dst_prev; dst_prev = dst1; - if (xfrm[i]->props.mode) { - remote = (struct in6_addr*)&xfrm[i]->id.daddr; - local = (struct in6_addr*)&xfrm[i]->props.saddr; - tunnel = 1; + if (xfrm[i]->props.mode == XFRM_MODE_TUNNEL || xfrm[i]->props.mode == XFRM_MODE_BEET) { + outer_family = xfrm[i]->props.family; + beet = (xfrm[i]->props.mode == XFRM_MODE_BEET); + if (outer_family == AF_INET6) { + remote.in6 = (struct in6_addr*)&xfrm[i]->id.daddr; + local.in6 = (struct in6_addr*)&xfrm[i]->props.saddr; + } else if(outer_family == AF_INET){ + remote.in = (struct in_addr*)&xfrm[i]->id.daddr; + local.in = (struct in_addr*)&xfrm[i]->props.saddr; + } } header_len += xfrm[i]->props.header_len; trailer_len += xfrm[i]->props.trailer_len; - if (tunnel) { - ipv6_addr_copy(&fl_tunnel.fl6_dst, remote); - ipv6_addr_copy(&fl_tunnel.fl6_src, local); + if (outer_family) { + switch(outer_family) { + case AF_INET: + fl_tunnel.fl4_dst = remote.in->s_addr; + fl_tunnel.fl4_src = local.in->s_addr; + + fl_tunnel.fl4_tos = 0; + fl_tunnel.fl4_fwmark = 0; + fl_tunnel.fl4_scope = 0; + break; + case AF_INET6: + ipv6_addr_copy(&fl_tunnel.fl6_dst, remote.in6); + ipv6_addr_copy(&fl_tunnel.fl6_src, local.in6); + break; + default: + BUG_ON(1); + } err = xfrm_dst_lookup((struct xfrm_dst **) &rt, - &fl_tunnel, AF_INET6); + &fl_tunnel, outer_family); if (err) goto error; } else @@ -177,6 +201,11 @@ } xfrm_init_pmtu(dst); + if (beet && outer_family == AF_INET) { + int delta = sizeof(struct ipv6hdr) - sizeof(struct iphdr); + u32 mtu = dst_mtu(dst); + xfrm6_update_pmtu(dst, mtu + delta); + } return 0; error: diff -urN a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c --- a/net/ipv6/xfrm6_output.c 2007-05-25 12:21:11.000000000 +0300 +++ b/net/ipv6/xfrm6_output.c 2007-05-25 12:21:11.000000000 +0300 @@ -14,8 +14,11 @@ #include <linux/spinlock.h> #include <linux/icmpv6.h> #include <linux/netfilter_ipv6.h> +#include <net/dsfield.h> +#include <net/inet_ecn.h> #include <net/ipv6.h> #include <net/xfrm.h> +#include <net/ip.h> static int xfrm6_tunnel_check_size(struct sk_buff *skb) { @@ -47,7 +50,7 @@ goto error_nolock; } - if (x->props.mode) { + if (x->props.mode == XFRM_MODE_TUNNEL) { err = xfrm6_tunnel_check_size(skb); if (err) goto error_nolock; @@ -59,7 +62,7 @@ if (err) goto error; - err = x->mode->output(skb); + err = x->mode->output(skb); if (err) goto error; diff -urN a/net/ipv6/udp.c b/net/ipv6/udp.c --- a/net/ipv6/udp.c 2007-05-25 12:21:11.000000000 +0300 +++ b/net/ipv6/udp.c 2007-05-25 12:21:11.000000000 +0300 @@ -788,7 +788,7 @@ if (final_p) ipv6_addr_copy(&fl->fl6_dst, final_p); - if ((err = xfrm_lookup(&dst, fl, sk, 0)) < 0) + if ((err = xfrm_lookup(&dst, fl, sk, XFRM_LOOKUP_SLEEP)) < 0) goto out; if (hlimit < 0) { diff -urN a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c --- a/net/ipv6/tcp_ipv6.c 2007-05-25 12:21:11.000000000 +0300 +++ b/net/ipv6/tcp_ipv6.c 2007-05-25 12:21:11.000000000 +0300 @@ -257,7 +257,7 @@ if (final_p) ipv6_addr_copy(&fl.fl6_dst, final_p); - if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) + if ((err = xfrm_lookup(&dst, &fl, sk, XFRM_LOOKUP_SLEEP)) < 0) goto failure; if (saddr == NULL) { diff -urN a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c --- a/net/ipv6/af_inet6.c 2007-05-25 12:21:11.000000000 +0300 +++ b/net/ipv6/af_inet6.c 2007-05-25 12:21:11.000000000 +0300 @@ -939,4 +939,8 @@ } module_exit(inet6_exit); +EXPORT_SYMBOL(inet6_create); +EXPORT_SYMBOL(inet6_stream_ops); +EXPORT_SYMBOL(inet6_dgram_ops); + MODULE_ALIAS_NETPROTO(PF_INET6); diff -urN a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c --- a/net/ipv6/xfrm6_mode_tunnel.c 2007-05-25 12:21:11.000000000 +0300 +++ b/net/ipv6/xfrm6_mode_tunnel.c 2007-05-25 12:21:11.000000000 +0300 @@ -15,6 +15,7 @@ #include <net/inet_ecn.h> #include <net/ipv6.h> #include <net/xfrm.h> +#include <net/ip.h> static inline void ipip6_ecn_decapsulate(struct sk_buff *skb) { @@ -95,6 +96,209 @@ return err; } + +/* jk: move this to beet module! */ +static int xfrm6_beet_output(struct sk_buff *skb) +{ + struct dst_entry *dst = skb->dst; + struct xfrm_state *x = dst->xfrm; + int hdrlen; + struct iphdr *iphv4, *top_iphv4; + struct ipv6hdr *iphv6, *top_iphv6; + + if (skb->nh.iph->version == 6) { + + u8 *prevhdr; + int hdr_len; + + /* 6-6 */ + + hdrlen = x->props.header_len - IPV4_BEET_PHMAXLEN; + skb_push(skb, hdrlen); + iphv6 = skb->nh.ipv6h; + + hdr_len = ip6_find_1stfragopt(skb, &prevhdr); + skb->nh.raw = prevhdr - hdrlen; + skb->h.raw = skb->data + hdr_len; + memmove(skb->data, iphv6, hdr_len); + + skb->nh.raw = skb->data; + top_iphv6 = skb->nh.ipv6h; + skb->nh.raw = &top_iphv6->nexthdr; + skb->h.ipv6h = top_iphv6 + 1; + ipv6_addr_copy(&top_iphv6->saddr, (struct in6_addr *)&x->props.saddr); + ipv6_addr_copy(&top_iphv6->daddr, (struct in6_addr *)&x->id.daddr); + + } else if (skb->nh.iph->version == 4) { + + int flags; + int optlen; + int dsfield; + u8 protocol; + int delta = sizeof(struct ipv6hdr) - sizeof(struct iphdr); + + /* Inner = 4, Outer = 6*/ + + iphv4 = skb->nh.iph; + skb->h.ipiph = iphv4; + + hdrlen = x->props.header_len; + + optlen = iphv4->ihl * 4 - sizeof(*iphv4); + if (!optlen) { + hdrlen -= IPV4_BEET_PHMAXLEN; + } else { + skb->h.raw -= (IPV4_BEET_PHMAXLEN - (optlen & 4)); + hdrlen -= optlen & 4; + } + + skb->nh.raw = skb_push(skb, hdrlen); + top_iphv4 = skb->nh.iph; + + hdrlen = iphv4->ihl * 4 - optlen; + skb->h.raw += hdrlen; + + if (unlikely(optlen)) { + struct ip_beet_phdr *ph; + + BUG_ON(optlen < 0); + + ph = (struct ip_beet_phdr *)skb->h.raw; + 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; + } + + protocol = top_iphv4->protocol; + + if (unlikely(optlen)) + protocol = top_iphv4->protocol; + else + protocol = iphv4->protocol; + + if (skb_headroom(skb) <= 2*delta){ + if (pskb_expand_head(skb, delta,0, GFP_ATOMIC)) + return 0; + } + + skb->nh.raw = skb_push(skb, delta); + + top_iphv6 = skb->nh.ipv6h; + skb->h.ipv6h = top_iphv6 + 1; + /* DS disclosed */ + top_iphv6->version = 6; + top_iphv6->priority = 0; + top_iphv6->flow_lbl[0] = 0; + top_iphv6->flow_lbl[1] = 0; + top_iphv6->flow_lbl[2] = 0; + dsfield = ipv6_get_dsfield(top_iphv6); + dsfield = INET_ECN_encapsulate(dsfield, dsfield); + flags = x->props.flags; + if (flags & XFRM_STATE_NOECN) + dsfield &= ~INET_ECN_MASK; + ipv6_change_dsfield(top_iphv6, 0, dsfield); + + top_iphv6->nexthdr = protocol; + top_iphv6->hop_limit = dst_metric(dst->child, RTAX_HOPLIMIT); + top_iphv6->payload_len = htons(skb->len - sizeof(struct ipv6hdr)); + ipv6_addr_copy(&top_iphv6->saddr,(struct in6_addr *)&x->props.saddr); + ipv6_addr_copy(&top_iphv6->daddr, (struct in6_addr *)&x->id.daddr); + skb->nh.raw = &top_iphv6->nexthdr; + + } else + BUG_ON(1); + + return 0; +} + + + +/* jk: move this to beet module! */ +static int xfrm6_beet_input(struct xfrm_state *x, struct sk_buff *skb) +{ + struct ip_beet_phdr *ph = (struct ip_beet_phdr*)(skb->h.raw); + int size = (x->sel.family == AF_INET) ? sizeof(struct iphdr) : sizeof(struct ipv6hdr); + int delta = sizeof(struct ipv6hdr) - sizeof(struct iphdr); + __u8 proto = skb->nh.ipv6h->nexthdr, hops = skb->nh.ipv6h->hop_limit; + __u8 ph_nexthdr = 0; + int phlen = 0; + int optlen = 0; + int err = -EINVAL; + + if (x->sel.family == AF_INET) { + /* Inner = IPv4, therefore the IPhdr must be shrunk */ + /* Inner = 4, Outer = 6 */ + if (unlikely(proto == IPPROTO_BEETPH)) { + if (!pskb_may_pull(skb, sizeof(*ph))) + goto out; + phlen = ph->hdrlen * 8; + optlen = phlen - ph->padlen - sizeof(*ph); + + if (optlen < 0 || optlen & 3 || optlen > 250) + goto out; + if (!pskb_may_pull(skb, phlen)) + goto out; + + proto = ph_nexthdr = ph->nexthdr; + } + skb->nh.raw += delta; + } + + if (skb_cloned(skb) && + pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) + goto out; + + skb_push(skb, size); + memmove(skb->data, skb->nh.raw, size); + skb->nh.raw = skb->data; + + skb->mac.raw = memmove(skb->data - skb->mac_len, + skb->mac.raw, skb->mac_len); + if (unlikely(phlen)) { + skb_pull(skb, phlen - optlen); + skb->nh.raw = skb->data; + } + + if (x->sel.family == AF_INET6) { + struct ipv6hdr *ip6h = skb->nh.ipv6h; + + ip6h->payload_len = htons(skb->len - size); + ipv6_addr_copy(&ip6h->daddr, (struct in6_addr *) &x->sel.daddr.a6); + ipv6_addr_copy(&ip6h->saddr, (struct in6_addr *) &x->sel.saddr.a6); + + } else if (x->sel.family == AF_INET) { + + struct iphdr *iph = skb->nh.iph; + + iph->ihl = (sizeof(*iph) + optlen) / 4; + iph->version = 4; + iph->tos = 0; + iph->id = 0; + iph->frag_off = 0; + iph->ttl = hops; + iph->protocol = proto; + iph->daddr = x->sel.daddr.a4; + iph->saddr = x->sel.saddr.a4; + iph->tot_len = htons(skb->len); + ip_send_check(iph); + skb->protocol = htons(ETH_P_IP); + if (unlikely(!optlen)) { + skb->h.raw = skb->nh.raw; + } + dst_release(skb->dst); + skb->dst = NULL; + } else + BUG_ON(1); + + err = 0; + + out: + return err; +} + + static struct xfrm_mode xfrm6_tunnel_mode = { .input = xfrm6_tunnel_input, .output = xfrm6_tunnel_output, @@ -102,8 +306,20 @@ .encap = XFRM_MODE_TUNNEL, }; +/* jk: move this to beet module! */ +static struct xfrm_mode xfrm6_beet_mode = { + .input = xfrm6_beet_input, + .output = xfrm6_beet_output, + .owner = THIS_MODULE, + .encap = XFRM_MODE_BEET, +}; + static int __init xfrm6_tunnel_init(void) { + + /* jk: move this to beet module! */ + xfrm_register_mode(&xfrm6_beet_mode, AF_INET6); + return xfrm_register_mode(&xfrm6_tunnel_mode, AF_INET6); } @@ -111,6 +327,9 @@ { int err; + /* jk: move this to beet module! */ + err = xfrm_unregister_mode(&xfrm6_beet_mode, AF_INET6); + err = xfrm_unregister_mode(&xfrm6_tunnel_mode, AF_INET6); BUG_ON(err); } diff -urN a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c --- a/net/ipv6/ipcomp6.c 2007-05-25 12:21:11.000000000 +0300 +++ b/net/ipv6/ipcomp6.c 2007-05-25 12:21:11.000000000 +0300 @@ -416,8 +416,10 @@ goto out; x->props.header_len = 0; - if (x->props.mode) + if (x->props.mode == XFRM_MODE_TUNNEL) x->props.header_len += sizeof(struct ipv6hdr); + else if (x->props.mode == XFRM_MODE_BEET) + x->props.header_len += IPV4_BEET_PHMAXLEN; mutex_lock(&ipcomp6_resource_mutex); if (!ipcomp6_alloc_scratches()) @@ -428,7 +430,7 @@ goto error; mutex_unlock(&ipcomp6_resource_mutex); - if (x->props.mode) { + if (x->props.mode == XFRM_MODE_TUNNEL) { err = ipcomp6_tunnel_attach(x); if (err) goto error_tunnel; diff -urN a/net/ipv6/esp6.c b/net/ipv6/esp6.c --- a/net/ipv6/esp6.c 2007-05-25 12:21:11.000000000 +0300 +++ b/net/ipv6/esp6.c 2007-05-25 12:21:11.000000000 +0300 @@ -344,8 +344,10 @@ if (crypto_cipher_setkey(esp->conf.tfm, esp->conf.key, esp->conf.key_len)) goto error; x->props.header_len = sizeof(struct ipv6_esp_hdr) + esp->conf.ivlen; - if (x->props.mode) + if (x->props.mode == XFRM_MODE_TUNNEL) x->props.header_len += sizeof(struct ipv6hdr); + else if (x->props.mode == XFRM_MODE_BEET) + x->props.header_len += IPV4_BEET_PHMAXLEN; x->data = esp; return 0; diff -urN a/net/ipv6/icmp.c b/net/ipv6/icmp.c --- a/net/ipv6/icmp.c 2007-05-25 12:21:11.000000000 +0300 +++ b/net/ipv6/icmp.c 2007-05-25 12:21:11.000000000 +0300 @@ -64,6 +64,7 @@ #include <net/ip6_route.h> #include <net/addrconf.h> #include <net/icmp.h> +#include <linux/xfrm.h> #include <asm/uaccess.h> #include <asm/system.h> @@ -389,7 +390,7 @@ goto out_dst_release; } - if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) + if ((err = xfrm_lookup(&dst, &fl, sk, XFRM_LOOKUP_SLEEP)) < 0) goto out; if (ipv6_addr_is_multicast(&fl.fl6_dst)) diff -urN a/net/key/af_key.c b/net/key/af_key.c --- a/net/key/af_key.c 2007-05-25 12:21:11.000000000 +0300 +++ b/net/key/af_key.c 2007-05-25 12:21:11.000000000 +0300 @@ -1166,7 +1166,8 @@ /* Nobody uses this, but we try. */ x->sel.family = pfkey_sadb_addr2xfrm_addr(addr, &x->sel.saddr); x->sel.prefixlen_s = addr->sadb_address_prefixlen; - } + } else + x->sel.family = x->props.family; /* Conservative */ if (ext_hdrs[SADB_X_EXT_NAT_T_TYPE-1]) { struct sadb_x_nat_t_type* n_type; @@ -1763,14 +1764,13 @@ if (!t->reqid && !(t->reqid = gen_reqid())) return -ENOBUFS; } - - /* addresses present only in tunnel mode */ - if (t->mode) { - switch (xp->family) { +/* addresses present in any mode */ + { + struct sockaddr *sa; + sa = (struct sockaddr *)(rq+1); + switch(sa->sa_family) { case AF_INET: - sin = (void*)(rq+1); - if (sin->sin_family != AF_INET) - return -EINVAL; + sin = (struct sockaddr_in *)sa; t->saddr.a4 = sin->sin_addr.s_addr; sin++; if (sin->sin_family != AF_INET) @@ -1779,9 +1779,7 @@ break; #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) case AF_INET6: - sin6 = (void *)(rq+1); - if (sin6->sin6_family != AF_INET6) - return -EINVAL; + sin6 = (struct sockaddr_in6 *)sa; memcpy(t->saddr.a6, &sin6->sin6_addr, sizeof(struct in6_addr)); sin6++; if (sin6->sin6_family != AF_INET6) @@ -1792,6 +1790,7 @@ default: return -EINVAL; } + t->outer_family = sa->sa_family; } /* No way to set this via kame pfkey */ t->aalgos = t->ealgos = t->calgos = ~0; diff -urN a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c --- a/net/xfrm/xfrm_user.c 2007-05-25 12:21:11.000000000 +0300 +++ b/net/xfrm/xfrm_user.c 2007-05-25 12:21:11.000000000 +0300 @@ -173,8 +173,9 @@ err = -EINVAL; switch (p->mode) { - case 0: - case 1: + case XFRM_MODE_TRANSPORT: + case XFRM_MODE_TUNNEL: + case XFRM_MODE_BEET: break; default: @@ -763,6 +764,7 @@ t->aalgos = ut->aalgos; t->ealgos = ut->ealgos; t->calgos = ut->calgos; + t->outer_family = ut->family; } } diff -urN a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c --- a/net/xfrm/xfrm_policy.c 2007-05-25 12:21:11.000000000 +0300 +++ b/net/xfrm/xfrm_policy.c 2007-05-25 12:21:11.000000000 +0300 @@ -782,6 +782,7 @@ if (tmpl->mode) { remote = &tmpl->id.daddr; local = &tmpl->saddr; + family = tmpl->outer_family; } x = xfrm_state_find(remote, local, fl, tmpl, policy, &error, family); diff -urN a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c --- a/net/xfrm/xfrm_state.c 2007-05-25 12:21:11.000000000 +0300 +++ b/net/xfrm/xfrm_state.c 2007-05-25 12:21:11.000000000 +0300 @@ -366,7 +366,7 @@ 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) || !xfrm_sec_ctx_match(pol->security, x->security)) continue; if (!best || @@ -378,7 +378,7 @@ 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) && xfrm_sec_ctx_match(pol->security, x->security)) error = -ESRCH; } diff -urN a/include/net/xfrm.h b/include/net/xfrm.h --- a/include/net/xfrm.h 2007-05-25 12:21:11.000000000 +0300 +++ b/include/net/xfrm.h 2007-05-25 12:21:11.000000000 +0300 @@ -226,7 +226,7 @@ extern int xfrm_policy_unregister_afinfo(struct xfrm_policy_afinfo *afinfo); extern void km_policy_notify(struct xfrm_policy *xp, int dir, struct km_event *c); extern void km_state_notify(struct xfrm_state *x, struct km_event *c); -#define XFRM_ACQ_EXPIRES 30 +#define XFRM_ACQ_EXPIRES 3 struct xfrm_tmpl; extern int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol); @@ -297,6 +297,10 @@ /* Source address of tunnel. Ignored, if it is not a tunnel. */ xfrm_address_t saddr; +/* family of the outer addresses. The family may differ from + the one in selector */ + unsigned short outer_family; + __u32 reqid; /* Mode: transport/tunnel */ diff -urN a/include/linux/xfrm.h b/include/linux/xfrm.h --- a/include/linux/xfrm.h 2007-05-25 12:21:11.000000000 +0300 +++ b/include/linux/xfrm.h 2007-05-25 12:21:11.000000000 +0300 @@ -43,6 +43,12 @@ #define XFRM_SC_ALG_RESERVED 0 #define XFRM_SC_ALG_SELINUX 1 +/* Transport layer flag passed to xfrm_lookup. If set, the userspace + process sleeps in a waitqueue until key management daemon has + finished setting up security associations. This workaround exists + until we have queues for outgoing IPsec packets. */ +#define XFRM_LOOKUP_SLEEP (!in_atomic() && !in_softirq()) + /* Selector, used as selector both on policy rules (SPD) and SAs. */ struct xfrm_selector @@ -118,9 +124,13 @@ XFRM_SHARE_UNIQUE /* Use once */ }; -#define XFRM_MODE_TRANSPORT 0 -#define XFRM_MODE_TUNNEL 1 -#define XFRM_MODE_MAX 2 +enum +{ + XFRM_MODE_TRANSPORT = 0, + XFRM_MODE_TUNNEL, + XFRM_MODE_BEET, + XFRM_MODE_MAX +}; /* Netlink configuration messages. */ enum { diff -urN a/include/linux/ipsec.h b/include/linux/ipsec.h --- a/include/linux/ipsec.h 2007-05-25 12:21:12.000000000 +0300 +++ b/include/linux/ipsec.h 2007-05-25 12:21:12.000000000 +0300 @@ -12,7 +12,8 @@ enum { IPSEC_MODE_ANY = 0, /* We do not support this for SA */ IPSEC_MODE_TRANSPORT = 1, - IPSEC_MODE_TUNNEL = 2 + IPSEC_MODE_TUNNEL = 2, + IPSEC_MODE_BEET = 3 }; enum { diff -urN a/include/linux/net.h b/include/linux/net.h --- a/include/linux/net.h 2007-05-25 12:21:12.000000000 +0300 +++ b/include/linux/net.h 2007-05-25 12:21:12.000000000 +0300 @@ -24,7 +24,7 @@ struct poll_table_struct; struct inode; -#define NPROTO 32 /* should be enough for now.. */ +#define NPROTO 33 /* should be enough for now.. */ #define SYS_SOCKET 1 /* sys_socket(2) */ #define SYS_BIND 2 /* sys_bind(2) */ diff -urN a/include/linux/in.h b/include/linux/in.h --- a/include/linux/in.h 2007-05-25 12:21:12.000000000 +0300 +++ b/include/linux/in.h 2007-05-25 12:21:12.000000000 +0300 @@ -40,6 +40,7 @@ IPPROTO_ESP = 50, /* Encapsulation Security Payload protocol */ IPPROTO_AH = 51, /* Authentication Header protocol */ + IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET */ IPPROTO_PIM = 103, /* Protocol Independent Multicast */ IPPROTO_COMP = 108, /* Compression Header protocol */ diff -urN a/include/linux/ip.h b/include/linux/ip.h --- a/include/linux/ip.h 2007-05-25 12:21:12.000000000 +0300 +++ b/include/linux/ip.h 2007-05-25 12:21:12.000000000 +0300 @@ -79,6 +79,8 @@ #define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */ #define IPOPT_TS_PRESPEC 3 /* specified modules only */ +#define IPV4_BEET_PHMAXLEN 8 + struct iphdr { #if defined(__LITTLE_ENDIAN_BITFIELD) __u8 ihl:4, @@ -122,4 +124,11 @@ __u16 cpi; }; +struct ip_beet_phdr { + __u8 nexthdr; + __u8 hdrlen; + __u8 padlen; + __u8 reserved; +}; + #endif /* _LINUX_IP_H */
Filipe Brandenburger
2008-Sep-12 20:56 UTC
[CentOS] Custom build kernel patch fails big time.
On Fri, Sep 12, 2008 at 16:46, Robert Moskowitz <rgm at htt-consult.com> wrote:> Oh, one question was asked about how the ~/rpmbuild/BUILD/kernel-2.16.18 > directory looks like. I think the linux-2.6.18.i386 (or i686) is not what > the patch is expecting?As some of the patches fail only 1/2 or 2/3 or 1/4, that means that there is a part of it that succeeded, so it's probably not a matter of directory layout. It seems that what you are trying to do is take a patch created on the latest kernel from kernel.org, and applying it verbatim to the latest CentOS kernel, which is far far far away from the latest kernel.org. The problem is that the kernel from kernel.org was probably changed a lot between the version used on CentOS and the latest version, in some areas the code may have changed so much that it's highly improbable that any non-trivial patch will succeed there. That's why this is called "back-porting", because there is actually quite a lot of effort into it. Filipe
Robert Moskowitz wrote:> I am trying to build a custom kernel for the HIPL code > (infrahip.hip.fi), using the patch for the Linux 2.6.18 kernel. IYour problem is likely because Red hat already applies 10 bazillion patches to the kernel for their packages, so there's little chance that the patch from that site will apply cleanly. So you, or someone will have to fix the patch, or go download the raw kernel sources that the patch is for and use that kernel instead knowing that you'll likely have other problems that Red Hat's patches were designed to prevent. Welcome to the development world of linux 2.6. I miss the older model they used on 2.4 and earlier. Now distributions are expected to maintain the stable kernels, which is fine until you need/want to do something like your trying to do. In the past this was much easier. Fortunately I haven't had to patch the kernel for years. nate
Filipe Brandenburger wrote:> On Fri, Sep 12, 2008 at 16:46, Robert Moskowitz <rgm at htt-consult.com> wrote: > >> Oh, one question was asked about how the ~/rpmbuild/BUILD/kernel-2.16.18 >> directory looks like. I think the linux-2.6.18.i386 (or i686) is not what >> the patch is expecting? >> > > As some of the patches fail only 1/2 or 2/3 or 1/4, that means that > there is a part of it that succeeded, so it's probably not a matter of > directory layout. > > It seems that what you are trying to do is take a patch created on the > latest kernel from kernel.org, and applying it verbatim to the latest > CentOS kernel,Quite wrong there. The hipl main code comes with separate patches for each kernel. I AM using the one in the 2.6.18.0 directory.> which is far far far away from the latest kernel.org. > The problem is that the kernel from kernel.org was probably changed a > lot between the version used on CentOS and the latest version, in some > areas the code may have changed so much that it's highly improbable > that any non-trivial patch will succeed there. That's why this is > called "back-porting", because there is actually quite a lot of effort > into it. > > Filipe > _______________________________________________ > CentOS mailing list > CentOS at centos.org > http://lists.centos.org/mailman/listinfo/centos > >
nate wrote:> Robert Moskowitz wrote: > >> I am trying to build a custom kernel for the HIPL code >> (infrahip.hip.fi), using the patch for the Linux 2.6.18 kernel. I >> > > Your problem is likely because Red hat already applies > 10 bazillion patches to the kernel for their packages, so > there's little chance that the patch from that site will > apply cleanly. >Well the patch maintainer told me to use the 2.6.18.0 patch, but...> So you, or someone will have to fix the patch,Well I hope for them to get the patch right soon...> or go download > the raw kernel sources that the patch is for and use that > kernel instead knowing that you'll likely have other problems > that Red Hat's patches were designed to prevent. >I am kind of thinking this patch is for FC6's 2.6.18.0 kernel, which as you hint is different from RHEL/Centos' 2.6.18.0 kernel. Oh, I WAS told NOT to use the patch for 2.6.18.1> Welcome to the development world of linux 2.6. I miss the older > model they used on 2.4 and earlier. Now distributions are expected > to maintain the stable kernels, which is fine until you need/want > to do something like your trying to do. In the past this > was much easier. > > Fortunately I haven't had to patch the kernel for years. > > nate > > _______________________________________________ > CentOS mailing list > CentOS at centos.org > http://lists.centos.org/mailman/listinfo/centos > >