?? simple-beet-and-interfamily-2.6.17.9-v1.patch
字號:
diff -urN linux-2.6.17.9/include/linux/in.h linux-2.6.17.9.hipl/include/linux/in.h--- linux-2.6.17.9/include/linux/in.h 2006-08-18 19:26:24.000000000 +0300+++ linux-2.6.17.9.hipl/include/linux/in.h 2006-12-18 15:01:03.000000000 +0200@@ -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 linux-2.6.17.9/include/linux/ip.h linux-2.6.17.9.hipl/include/linux/ip.h--- linux-2.6.17.9/include/linux/ip.h 2006-08-18 19:26:24.000000000 +0300+++ linux-2.6.17.9.hipl/include/linux/ip.h 2006-12-18 15:01:03.000000000 +0200@@ -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 */diff -urN linux-2.6.17.9/include/linux/ipsec.h linux-2.6.17.9.hipl/include/linux/ipsec.h--- linux-2.6.17.9/include/linux/ipsec.h 2006-08-18 19:26:24.000000000 +0300+++ linux-2.6.17.9.hipl/include/linux/ipsec.h 2006-12-18 15:01:03.000000000 +0200@@ -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 linux-2.6.17.9/include/linux/xfrm.h linux-2.6.17.9.hipl/include/linux/xfrm.h--- linux-2.6.17.9/include/linux/xfrm.h 2006-08-18 19:26:24.000000000 +0300+++ linux-2.6.17.9.hipl/include/linux/xfrm.h 2006-12-18 15:01:03.000000000 +0200@@ -118,6 +118,13 @@ XFRM_SHARE_UNIQUE /* Use once */ }; +enum+{+ XFRM_MODE_TRANSPORT = 0,+ XFRM_MODE_TUNNEL,+ XFRM_MODE_BEET+};+ /* Netlink configuration messages. */ enum { XFRM_MSG_BASE = 0x10,diff -urN linux-2.6.17.9/include/net/xfrm.h linux-2.6.17.9.hipl/include/net/xfrm.h--- linux-2.6.17.9/include/net/xfrm.h 2006-08-18 19:26:24.000000000 +0300+++ linux-2.6.17.9.hipl/include/net/xfrm.h 2006-12-18 15:01:03.000000000 +0200@@ -287,6 +287,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 linux-2.6.17.9/net/ipv4/ah4.c linux-2.6.17.9.hipl/net/ipv4/ah4.c--- linux-2.6.17.9/net/ipv4/ah4.c 2006-08-18 19:26:24.000000000 +0300+++ linux-2.6.17.9.hipl/net/ipv4/ah4.c 2006-12-18 15:01:03.000000000 +0200@@ -257,8 +257,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 linux-2.6.17.9/net/ipv4/esp4.c linux-2.6.17.9.hipl/net/ipv4/esp4.c--- linux-2.6.17.9/net/ipv4/esp4.c 2006-08-18 19:26:24.000000000 +0300+++ linux-2.6.17.9.hipl/net/ipv4/esp4.c 2006-12-18 15:01:03.000000000 +0200@@ -240,7 +240,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; } @@ -262,17 +263,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)@@ -377,8 +388,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 linux-2.6.17.9/net/ipv4/esp4.c.orig linux-2.6.17.9.hipl/net/ipv4/esp4.c.orig--- linux-2.6.17.9/net/ipv4/esp4.c.orig 1970-01-01 02:00:00.000000000 +0200+++ linux-2.6.17.9.hipl/net/ipv4/esp4.c.orig 2006-12-18 15:01:03.000000000 +0200@@ -0,0 +1,449 @@+#include <linux/config.h>+#include <linux/module.h>+#include <net/ip.h>+#include <net/xfrm.h>+#include <net/esp.h>+#include <asm/scatterlist.h>+#include <linux/crypto.h>+#include <linux/kernel.h>+#include <linux/pfkeyv2.h>+#include <linux/random.h>+#include <net/icmp.h>+#include <net/protocol.h>+#include <net/udp.h>++static int esp_output(struct xfrm_state *x, struct sk_buff *skb)+{+ int err;+ struct iphdr *top_iph;+ struct ip_esp_hdr *esph;+ struct crypto_tfm *tfm;+ struct esp_data *esp;+ struct sk_buff *trailer;+ int blksize;+ int clen;+ int alen;+ int nfrags;++ /* Strip IP+ESP header. */+ __skb_pull(skb, skb->h.raw - skb->data);+ /* Now skb is pure payload to encrypt */++ err = -ENOMEM;++ /* Round to block size */+ clen = skb->len;++ esp = x->data;+ alen = esp->auth.icv_trunc_len;+ tfm = esp->conf.tfm;+ blksize = ALIGN(crypto_tfm_alg_blocksize(tfm), 4);+ clen = ALIGN(clen + 2, blksize);+ if (esp->conf.padlen)+ clen = ALIGN(clen, esp->conf.padlen);++ if ((nfrags = skb_cow_data(skb, clen-skb->len+alen, &trailer)) < 0)+ goto error;++ /* Fill padding... */+ do {+ int i;+ for (i=0; i<clen-skb->len - 2; i++)+ *(u8*)(trailer->tail + i) = i+1;+ } while (0);+ *(u8*)(trailer->tail + clen-skb->len - 2) = (clen - skb->len)-2;+ pskb_put(skb, trailer, clen - skb->len);++ __skb_push(skb, skb->data - skb->nh.raw);+ top_iph = skb->nh.iph;+ esph = (struct ip_esp_hdr *)(skb->nh.raw + top_iph->ihl*4);+ top_iph->tot_len = htons(skb->len + alen);+ *(u8*)(trailer->tail - 1) = top_iph->protocol;++ /* this is non-NULL only with UDP Encapsulation */+ if (x->encap) {+ struct xfrm_encap_tmpl *encap = x->encap;+ struct udphdr *uh;+ u32 *udpdata32;++ uh = (struct udphdr *)esph;+ uh->source = encap->encap_sport;+ uh->dest = encap->encap_dport;+ uh->len = htons(skb->len + alen - top_iph->ihl*4);+ uh->check = 0;++ switch (encap->encap_type) {+ default:+ case UDP_ENCAP_ESPINUDP:+ esph = (struct ip_esp_hdr *)(uh + 1);+ break;+ case UDP_ENCAP_ESPINUDP_NON_IKE:+ udpdata32 = (u32 *)(uh + 1);+ udpdata32[0] = udpdata32[1] = 0;+ esph = (struct ip_esp_hdr *)(udpdata32 + 2);+ break;+ }++ top_iph->protocol = IPPROTO_UDP;+ } else+ top_iph->protocol = IPPROTO_ESP;++ esph->spi = x->id.spi;+ esph->seq_no = htonl(++x->replay.oseq);+ xfrm_aevent_doreplay(x);++ if (esp->conf.ivlen)+ crypto_cipher_set_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm));++ do {+ struct scatterlist *sg = &esp->sgbuf[0];++ if (unlikely(nfrags > ESP_NUM_FAST_SG)) {+ sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);+ if (!sg)+ goto error;+ }+ skb_to_sgvec(skb, sg, esph->enc_data+esp->conf.ivlen-skb->data, clen);+ crypto_cipher_encrypt(tfm, sg, sg, clen);+ if (unlikely(sg != &esp->sgbuf[0]))+ kfree(sg);+ } while (0);++ if (esp->conf.ivlen) {+ memcpy(esph->enc_data, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm));+ crypto_cipher_get_iv(tfm, esp->conf.ivec, crypto_tfm_alg_ivsize(tfm));+ }++ if (esp->auth.icv_full_len) {+ esp->auth.icv(esp, skb, (u8*)esph-skb->data,+ sizeof(struct ip_esp_hdr) + esp->conf.ivlen+clen, trailer->tail);+ pskb_put(skb, trailer, alen);+ }++ ip_send_check(top_iph);++ err = 0;++error:+ return err;+}++/*+ * Note: detecting truncated vs. non-truncated authentication data is very+ * expensive, so we only support truncated data, which is the recommended+ * and common case.+ */+static int esp_input(struct xfrm_state *x, struct sk_buff *skb)+{+ struct iphdr *iph;+ struct ip_esp_hdr *esph;+ struct esp_data *esp = x->data;+ struct sk_buff *trailer;+ int blksize = ALIGN(crypto_tfm_alg_blocksize(esp->conf.tfm), 4);+ int alen = esp->auth.icv_trunc_len;+ int elen = skb->len - sizeof(struct ip_esp_hdr) - esp->conf.ivlen - alen;+ int nfrags;+ int encap_len = 0;+ u8 nexthdr[2];+ struct scatterlist *sg;+ u8 workbuf[60];+ int padlen;++ if (!pskb_may_pull(skb, sizeof(struct ip_esp_hdr)))+ goto out;++ if (elen <= 0 || (elen & (blksize-1)))+ goto out;++ /* If integrity check is required, do this. */+ if (esp->auth.icv_full_len) {+ u8 sum[esp->auth.icv_full_len];+ u8 sum1[alen];+ + esp->auth.icv(esp, skb, 0, skb->len-alen, sum);++ if (skb_copy_bits(skb, skb->len-alen, sum1, alen))+ BUG();++ if (unlikely(memcmp(sum, sum1, alen))) {+ x->stats.integrity_failed++;+ goto out;+ }+ }++ if ((nfrags = skb_cow_data(skb, 0, &trailer)) < 0)+ goto out;++ skb->ip_summed = CHECKSUM_NONE;++ esph = (struct ip_esp_hdr*)skb->data;+ iph = skb->nh.iph;++ /* Get ivec. This can be wrong, check against another impls. */+ if (esp->conf.ivlen)+ crypto_cipher_set_iv(esp->conf.tfm, esph->enc_data, crypto_tfm_alg_ivsize(esp->conf.tfm));++ sg = &esp->sgbuf[0];++ if (unlikely(nfrags > ESP_NUM_FAST_SG)) {+ sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC);+ if (!sg)+ goto out;+ }+ skb_to_sgvec(skb, sg, sizeof(struct ip_esp_hdr) + esp->conf.ivlen, elen);+ crypto_cipher_decrypt(esp->conf.tfm, sg, sg, elen);+ if (unlikely(sg != &esp->sgbuf[0]))+ kfree(sg);++ if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2))+ BUG();++ padlen = nexthdr[0];+ if (padlen+2 >= elen)+ goto out;++ /* ... check padding bits here. Silly. :-) */ ++ if (x->encap) {+ struct xfrm_encap_tmpl *encap = x->encap;+ struct udphdr *uh;++ uh = (struct udphdr *)(iph + 1);+ encap_len = (void*)esph - (void*)uh;++ /*+ * 1) if the NAT-T peer's IP or port changed then+ * advertize the change to the keying daemon.+ * This is an inbound SA, so just compare+ * SRC ports.+ */+ if (iph->saddr != x->props.saddr.a4 ||+ uh->source != encap->encap_sport) {+ xfrm_address_t ipaddr;++ ipaddr.a4 = iph->saddr;+ km_new_mapping(x, &ipaddr, uh->source);+ + /* XXX: perhaps add an extra+ * policy check here, to see+ * if we should allow or+ * reject a packet from a+ * different source+ * address/port.+ */+ }+ + /*+ * 2) ignore UDP/TCP checksums in case+ * of NAT-T in Transport Mode, or+ * perform other post-processing fixes+ * as per draft-ietf-ipsec-udp-encaps-06,
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -