📄 hip-beet-2.6.15.7-4in1.patch
字号:
+}++static inline int xfrm_state_kern(struct xfrm_state *x)+{+ return atomic_read(&x->tunnel_users);+}++/*+ * xfrm algorithm information+ */+struct xfrm_algo_auth_info {+ u16 icv_truncbits;+ u16 icv_fullbits;+};++struct xfrm_algo_encr_info {+ u16 blockbits;+ u16 defkeybits;+};++struct xfrm_algo_comp_info {+ u16 threshold;+};++struct xfrm_algo_desc {+ char *name;+ u8 available:1;+ union {+ struct xfrm_algo_auth_info auth;+ struct xfrm_algo_encr_info encr;+ struct xfrm_algo_comp_info comp;+ } uinfo;+ struct sadb_alg desc;+};++/* XFRM tunnel handlers. */+struct xfrm_tunnel {+ int (*handler)(struct sk_buff *skb);+ void (*err_handler)(struct sk_buff *skb, __u32 info);+};++struct xfrm6_tunnel {+ int (*handler)(struct sk_buff **pskb, unsigned int *nhoffp);+ void (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt,+ int type, int code, int offset, __u32 info);+};++extern void xfrm_init(void);+extern void xfrm4_init(void);+extern void xfrm6_init(void);+extern void xfrm6_fini(void);+extern void xfrm_state_init(void);+extern void xfrm4_state_init(void);+extern void xfrm6_state_init(void);+extern void xfrm6_state_fini(void);++extern int xfrm_state_walk(u8 proto, int (*func)(struct xfrm_state *, int, void*), void *);+extern struct xfrm_state *xfrm_state_alloc(void);+extern struct xfrm_state *xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, + struct flowi *fl, struct xfrm_tmpl *tmpl,+ struct xfrm_policy *pol, int *err,+ unsigned short family);+extern int xfrm_state_check_expire(struct xfrm_state *x);+extern void xfrm_state_insert(struct xfrm_state *x);+extern int xfrm_state_add(struct xfrm_state *x);+extern int xfrm_state_update(struct xfrm_state *x);+extern struct xfrm_state *xfrm_state_lookup(xfrm_address_t *daddr, u32 spi, u8 proto, unsigned short family);+extern struct xfrm_state *xfrm_find_acq_byseq(u32 seq);+extern int xfrm_state_delete(struct xfrm_state *x);+extern void xfrm_state_flush(u8 proto);+extern int xfrm_replay_check(struct xfrm_state *x, u32 seq);+extern void xfrm_replay_advance(struct xfrm_state *x, u32 seq);+extern int xfrm_state_check(struct xfrm_state *x, struct sk_buff *skb);+extern int xfrm_state_mtu(struct xfrm_state *x, int mtu);+extern int xfrm_init_state(struct xfrm_state *x);+extern int xfrm4_rcv(struct sk_buff *skb);+extern int xfrm4_output(struct sk_buff *skb);+extern int xfrm4_tunnel_register(struct xfrm_tunnel *handler);+extern int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler);+extern int xfrm6_rcv_spi(struct sk_buff **pskb, unsigned int *nhoffp, u32 spi);+extern int xfrm6_rcv(struct sk_buff **pskb, unsigned int *nhoffp);+extern int xfrm6_tunnel_register(struct xfrm6_tunnel *handler);+extern int xfrm6_tunnel_deregister(struct xfrm6_tunnel *handler);+extern u32 xfrm6_tunnel_alloc_spi(xfrm_address_t *saddr);+extern void xfrm6_tunnel_free_spi(xfrm_address_t *saddr);+extern u32 xfrm6_tunnel_spi_lookup(xfrm_address_t *saddr);+extern int xfrm6_output(struct sk_buff *skb);++#ifdef CONFIG_XFRM+extern int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type);+extern int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen);+extern int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsigned short family);+#else+static inline int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen)+{+ return -ENOPROTOOPT;+} ++static inline int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)+{+ /* should not happen */+ kfree_skb(skb);+ return 0;+}+static inline int xfrm_dst_lookup(struct xfrm_dst **dst, struct flowi *fl, unsigned short family)+{+ return -EINVAL;+} +#endif++struct xfrm_policy *xfrm_policy_alloc(gfp_t gfp);+extern int xfrm_policy_walk(int (*func)(struct xfrm_policy *, int, int, void*), void *);+int xfrm_policy_insert(int dir, struct xfrm_policy *policy, int excl);+struct xfrm_policy *xfrm_policy_bysel(int dir, struct xfrm_selector *sel,+ int delete);+struct xfrm_policy *xfrm_policy_byid(int dir, u32 id, int delete);+void xfrm_policy_flush(void);+u32 xfrm_get_acqseq(void);+void xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);+struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto, + xfrm_address_t *daddr, xfrm_address_t *saddr, + int create, unsigned short family);+extern void xfrm_policy_flush(void);+extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);+extern int xfrm_flush_bundles(void);+extern void xfrm_flush_all_bundles(void);+extern int xfrm_bundle_ok(struct xfrm_dst *xdst, struct flowi *fl, int family);+extern void xfrm_init_pmtu(struct dst_entry *dst);++extern wait_queue_head_t km_waitq;+extern int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, u16 sport);+extern void km_policy_expired(struct xfrm_policy *pol, int dir, int hard);++extern void xfrm_input_init(void);+extern int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq);++extern void xfrm_probe_algs(void);+extern int xfrm_count_auth_supported(void);+extern int xfrm_count_enc_supported(void);+extern struct xfrm_algo_desc *xfrm_aalg_get_byidx(unsigned int idx);+extern struct xfrm_algo_desc *xfrm_ealg_get_byidx(unsigned int idx);+extern struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id);+extern struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id);+extern struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id);+extern struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name, int probe);+extern struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe);+extern struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe);++struct crypto_tfm;+typedef void (icv_update_fn_t)(struct crypto_tfm *, struct scatterlist *, unsigned int);++extern void skb_icv_walk(const struct sk_buff *skb, struct crypto_tfm *tfm,+ int offset, int len, icv_update_fn_t icv_update);++static inline int xfrm_addr_cmp(xfrm_address_t *a, xfrm_address_t *b,+ int family)+{+ switch (family) {+ default:+ case AF_INET:+ return a->a4 - b->a4;+ case AF_INET6:+ return ipv6_addr_cmp((struct in6_addr *)a,+ (struct in6_addr *)b);+ }+}++static inline int xfrm_policy_id2dir(u32 index)+{+ return index & 7;+}++#endif /* _NET_XFRM_H */diff -urN linux-source-2.6.15/net/ipv4/ah4.c linux-source-2.6.15-beet/net/ipv4/ah4.c--- linux-source-2.6.15/net/ipv4/ah4.c 2006-03-02 23:18:42.000000000 +0200+++ linux-source-2.6.15-beet/net/ipv4/ah4.c 2006-07-02 16:45:06.000000000 +0300@@ -255,8 +255,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-source-2.6.15/net/ipv4/ah4.c.orig linux-source-2.6.15-beet/net/ipv4/ah4.c.orig--- linux-source-2.6.15/net/ipv4/ah4.c.orig 1970-01-01 02:00:00.000000000 +0200+++ linux-source-2.6.15-beet/net/ipv4/ah4.c.orig 2006-03-02 23:18:42.000000000 +0200@@ -0,0 +1,329 @@+#include <linux/config.h>+#include <linux/module.h>+#include <net/ip.h>+#include <net/xfrm.h>+#include <net/ah.h>+#include <linux/crypto.h>+#include <linux/pfkeyv2.h>+#include <net/icmp.h>+#include <asm/scatterlist.h>+++/* Clear mutable options and find final destination to substitute+ * into IP header for icv calculation. Options are already checked+ * for validity, so paranoia is not required. */++static int ip_clear_mutable_options(struct iphdr *iph, u32 *daddr)+{+ unsigned char * optptr = (unsigned char*)(iph+1);+ int l = iph->ihl*4 - sizeof(struct iphdr);+ int optlen;++ while (l > 0) {+ switch (*optptr) {+ case IPOPT_END:+ return 0;+ case IPOPT_NOOP:+ l--;+ optptr++;+ continue;+ }+ optlen = optptr[1];+ if (optlen<2 || optlen>l)+ return -EINVAL;+ switch (*optptr) {+ case IPOPT_SEC:+ case 0x85: /* Some "Extended Security" crap. */+ case 0x86: /* Another "Commercial Security" crap. */+ case IPOPT_RA:+ case 0x80|21: /* RFC1770 */+ break;+ case IPOPT_LSRR:+ case IPOPT_SSRR:+ if (optlen < 6)+ return -EINVAL;+ memcpy(daddr, optptr+optlen-4, 4);+ /* Fall through */+ default:+ memset(optptr+2, 0, optlen-2);+ }+ l -= optlen;+ optptr += optlen;+ }+ return 0;+}++static int ah_output(struct xfrm_state *x, struct sk_buff *skb)+{+ int err;+ struct iphdr *iph, *top_iph;+ struct ip_auth_hdr *ah;+ struct ah_data *ahp;+ union {+ struct iphdr iph;+ char buf[60];+ } tmp_iph;++ top_iph = skb->nh.iph;+ iph = &tmp_iph.iph;++ iph->tos = top_iph->tos;+ iph->ttl = top_iph->ttl;+ iph->frag_off = top_iph->frag_off;++ if (top_iph->ihl != 5) {+ iph->daddr = top_iph->daddr;+ memcpy(iph+1, top_iph+1, top_iph->ihl*4 - sizeof(struct iphdr));+ err = ip_clear_mutable_options(top_iph, &top_iph->daddr);+ if (err)+ goto error;+ }++ ah = (struct ip_auth_hdr *)((char *)top_iph+top_iph->ihl*4);+ ah->nexthdr = top_iph->protocol;++ top_iph->tos = 0;+ top_iph->tot_len = htons(skb->len);+ top_iph->frag_off = 0;+ top_iph->ttl = 0;+ top_iph->protocol = IPPROTO_AH;+ top_iph->check = 0;++ ahp = x->data;+ ah->hdrlen = (XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + + ahp->icv_trunc_len) >> 2) - 2;++ ah->reserved = 0;+ ah->spi = x->id.spi;+ ah->seq_no = htonl(++x->replay.oseq);+ ahp->icv(ahp, skb, ah->auth_data);++ top_iph->tos = iph->tos;+ top_iph->ttl = iph->ttl;+ top_iph->frag_off = iph->frag_off;+ if (top_iph->ihl != 5) {+ top_iph->daddr = iph->daddr;+ memcpy(top_iph+1, iph+1, top_iph->ihl*4 - sizeof(struct iphdr));+ }++ ip_send_check(top_iph);++ err = 0;++error:+ return err;+}++static int ah_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb)+{+ int ah_hlen;+ struct iphdr *iph;+ struct ip_auth_hdr *ah;+ struct ah_data *ahp;+ char work_buf[60];++ if (!pskb_may_pull(skb, sizeof(struct ip_auth_hdr)))+ goto out;++ ah = (struct ip_auth_hdr*)skb->data;+ ahp = x->data;+ ah_hlen = (ah->hdrlen + 2) << 2;+ + if (ah_hlen != XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + ahp->icv_full_len) &&+ ah_hlen != XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + ahp->icv_trunc_len)) + goto out;++ if (!pskb_may_pull(skb, ah_hlen))+ goto out;++ /* We are going to _remove_ AH header to keep sockets happy,+ * so... Later this can change. */+ if (skb_cloned(skb) &&+ pskb_expand_head(skb, 0, 0, GFP_ATOMIC))+ goto out;++ skb->ip_summed = CHECKSUM_NONE;++ ah = (struct ip_auth_hdr*)skb->data;+ iph = skb->nh.iph;++ memcpy(work_buf, iph, iph->ihl*4);++ iph->ttl = 0;+ iph->tos = 0;+ iph->frag_off = 0;+ iph->check = 0;+ if (iph->ihl != 5) {+ u32 dummy;+ if (ip_clear_mutable_options(iph, &dummy))+ goto out;+ }+ {+ u8 auth_data[MAX_AH_AUTH_LEN];+ + memcpy(auth_data, ah->auth_data, ahp->icv_trunc_len);+ skb_push(skb, skb->data - skb->nh.raw);+ ahp->icv(ahp, skb, ah->auth_data);+ if (memcmp(ah->auth_data, auth_data, ahp->icv_trunc_len)) {+ x->stats.integrity_failed++;+ goto out;+ }+ }+ ((struct iphdr*)work_buf)->protocol = ah->nexthdr;+ skb->nh.raw = skb_pull(skb, ah_hlen);+ memcpy(skb->nh.raw, work_buf, iph->ihl*4);+ skb->nh.iph->tot_len = htons(skb->len);+ skb_pull(skb, skb->nh.iph->ihl*4);+ skb->h.raw = skb->data;++ return 0;++out:+ return -EINVAL;+}++static void ah4_err(struct sk_buff *skb, u32 info)+{+ struct iphdr *iph = (struct iphdr*)skb->data;+ struct ip_auth_hdr *ah = (struct ip_auth_hdr*)(skb->data+(iph->ihl<<2));+ struct xfrm_state *x;++ if (skb->h.icmph->type != ICMP_DEST_UNREACH ||+ skb->h.icmph->code != ICMP_FRAG_NEEDED)+ return;++ x = xfrm_state_lookup((xfrm_address_t *)&iph->daddr, ah->spi, IPPROTO_AH, AF_INET);+ if (!x)+ return;+ printk(KERN_DEBUG "pmtu discovery on SA AH/%08x/%08x\n",+ ntohl(ah->spi), ntohl(iph->daddr));+ xfrm_state_put(x);+}++static int ah_init_state(struct xfrm_state *x)+{+ struct ah_data *ahp = NULL;+ struct xfrm_algo_desc *aalg_desc;++ if (!x->aalg)+ goto error;++ /* null auth can use a zero length key */+ if (x->aalg->alg_key_len > 512)+ goto error;++ if (x->encap)+ goto error;++ ahp = kmalloc(sizeof(*ahp), GFP_KERNEL);+ if (ahp == NULL)+ return -ENOMEM;++ memset(ahp, 0, sizeof(*ahp));++ ahp->key = x->aalg->alg_key;+ ahp->key_len = (x->aalg->alg_key_len+7)/8;+ ahp->tfm = crypto_alloc_tfm(x->aalg->alg_name, 0);+ if (!ahp->tfm)+ goto error;+ ahp->icv = ah_hmac_digest;+ + /*+ * Lookup the algorithm description maintained by xfrm_algo,+ * verify crypto transform properties, and store information+ * we need for AH processing. This lookup cannot fail here+ * after a successful crypto_alloc_tfm().+ */+ aalg_desc = xfrm_aalg_get_byname(x->aalg->alg_name, 0);+ BUG_ON(!aalg_desc);++ if (aalg_desc->uinfo.auth.icv_fullbits/8 !=+ crypto_tfm_alg_digestsize(ahp->tfm)) {+ printk(KERN_INFO "AH: %s digestsize %u != %hu\n",+ x->aalg->alg_name, crypto_tfm_alg_digestsize(ahp->tfm),+ aalg_desc->uinfo.auth.icv_fullbits/8);+ goto error;+ }+ + ahp->icv_full_len = aalg_desc->uinfo.auth.icv_fullbits/8;+ ahp->icv_trunc_len = aalg_desc->uinfo.auth.icv_truncbits/8;+ + BUG_ON(ahp->icv_trunc_len > MAX_AH_AUTH_LEN);+ + ahp->work_icv = kmalloc(ahp->icv_full_len, GFP_KERNEL);+ if (!ahp->work_icv)+ goto error;+ + x->props.header_len = XFRM_ALIGN8(sizeof(struct ip_auth_hdr) + ahp->icv_trunc_len);+ if (x->props.mode)+ x->props.header_len += sizeof(struct iphdr);+ x->data = ahp;++ return 0;++error:+ if (ahp) {+ kfree(ahp->work_icv);+ crypto_free_tfm(ahp->tfm);+ kfree(ahp);+ }+ return -EINVAL;+}++static void ah_destroy(struct xfrm_state *x)+{+ struct ah_data *ahp = x->data;++ if (!ahp)+ return;++ kfree(ahp->work_icv);+ ahp->work_icv = NULL;+ crypto_free_tfm(ahp->tfm);+ ahp->tfm = NULL;+ kfree(ahp);+}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -