diff options
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/esp4.c | 185 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_LOG.c | 7 | ||||
-rw-r--r-- | net/ipv4/route.c | 2 | ||||
-rw-r--r-- | net/ipv4/xfrm4_policy.c | 5 |
4 files changed, 77 insertions, 122 deletions
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 73bfcae8af9..09590f35608 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c @@ -12,13 +12,6 @@ #include <net/protocol.h> #include <net/udp.h> -/* decapsulation data for use when post-processing */ -struct esp_decap_data { - xfrm_address_t saddr; - __u16 sport; - __u8 proto; -}; - static int esp_output(struct xfrm_state *x, struct sk_buff *skb) { int err; @@ -150,6 +143,10 @@ static int esp_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struc 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; @@ -185,122 +182,82 @@ static int esp_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struc if (esp->conf.ivlen) crypto_cipher_set_iv(esp->conf.tfm, esph->enc_data, crypto_tfm_alg_ivsize(esp->conf.tfm)); - { - u8 nexthdr[2]; - struct scatterlist *sg = &esp->sgbuf[0]; - u8 workbuf[60]; - int padlen; - - 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(); + sg = &esp->sgbuf[0]; - padlen = nexthdr[0]; - if (padlen+2 >= elen) + if (unlikely(nfrags > ESP_NUM_FAST_SG)) { + sg = kmalloc(sizeof(struct scatterlist)*nfrags, GFP_ATOMIC); + if (!sg) goto out; - - /* ... check padding bits here. Silly. :-) */ - - if (x->encap && decap && decap->decap_type) { - struct esp_decap_data *encap_data; - struct udphdr *uh = (struct udphdr *) (iph+1); - - encap_data = (struct esp_decap_data *) (decap->decap_data); - encap_data->proto = 0; - - switch (decap->decap_type) { - case UDP_ENCAP_ESPINUDP: - case UDP_ENCAP_ESPINUDP_NON_IKE: - encap_data->proto = AF_INET; - encap_data->saddr.a4 = iph->saddr; - encap_data->sport = uh->source; - encap_len = (void*)esph - (void*)uh; - break; - - default: - goto out; - } - } - - iph->protocol = nexthdr[1]; - pskb_trim(skb, skb->len - alen - padlen - 2); - memcpy(workbuf, skb->nh.raw, iph->ihl*4); - skb->h.raw = skb_pull(skb, sizeof(struct ip_esp_hdr) + esp->conf.ivlen); - skb->nh.raw += encap_len + sizeof(struct ip_esp_hdr) + esp->conf.ivlen; - memcpy(skb->nh.raw, workbuf, iph->ihl*4); - skb->nh.iph->tot_len = htons(skb->len); } + 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); - return 0; + if (skb_copy_bits(skb, skb->len-alen-2, nexthdr, 2)) + BUG(); -out: - return -EINVAL; -} + padlen = nexthdr[0]; + if (padlen+2 >= elen) + goto out; -static int esp_post_input(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb) -{ - - if (x->encap) { - struct xfrm_encap_tmpl *encap; - struct esp_decap_data *decap_data; + /* ... check padding bits here. Silly. :-) */ - encap = x->encap; - decap_data = (struct esp_decap_data *)(decap->decap_data); + if (x->encap) { + struct xfrm_encap_tmpl *encap = x->encap; + struct udphdr *uh; - /* first, make sure that the decap type == the encap type */ if (encap->encap_type != decap->decap_type) - return -EINVAL; + goto out; - switch (encap->encap_type) { - default: - case UDP_ENCAP_ESPINUDP: - case UDP_ENCAP_ESPINUDP_NON_IKE: - /* - * 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 (decap_data->proto == AF_INET && - (decap_data->saddr.a4 != x->props.saddr.a4 || - decap_data->sport != encap->encap_sport)) { - xfrm_address_t ipaddr; - - ipaddr.a4 = decap_data->saddr.a4; - km_new_mapping(x, &ipaddr, decap_data->sport); - - /* 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, - * section 3.1.2 + 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. */ - if (!x->props.mode) - skb->ip_summed = CHECKSUM_UNNECESSARY; - - break; } + + /* + * 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, + * section 3.1.2 + */ + if (!x->props.mode) + skb->ip_summed = CHECKSUM_UNNECESSARY; } + + iph->protocol = nexthdr[1]; + pskb_trim(skb, skb->len - alen - padlen - 2); + memcpy(workbuf, skb->nh.raw, iph->ihl*4); + skb->h.raw = skb_pull(skb, sizeof(struct ip_esp_hdr) + esp->conf.ivlen); + skb->nh.raw += encap_len + sizeof(struct ip_esp_hdr) + esp->conf.ivlen; + memcpy(skb->nh.raw, workbuf, iph->ihl*4); + skb->nh.iph->tot_len = htons(skb->len); + return 0; + +out: + return -EINVAL; } static u32 esp4_get_max_size(struct xfrm_state *x, int mtu) @@ -458,7 +415,6 @@ static struct xfrm_type esp_type = .destructor = esp_destroy, .get_max_size = esp4_get_max_size, .input = esp_input, - .post_input = esp_post_input, .output = esp_output }; @@ -470,15 +426,6 @@ static struct net_protocol esp4_protocol = { static int __init esp4_init(void) { - struct xfrm_decap_state decap; - - if (sizeof(struct esp_decap_data) > - sizeof(decap.decap_data)) { - extern void decap_data_too_small(void); - - decap_data_too_small(); - } - if (xfrm_register_type(&esp_type, AF_INET) < 0) { printk(KERN_INFO "ip esp init: can't add xfrm type\n"); return -EAGAIN; diff --git a/net/ipv4/netfilter/ipt_LOG.c b/net/ipv4/netfilter/ipt_LOG.c index 6606ddb66a2..cc27545ff97 100644 --- a/net/ipv4/netfilter/ipt_LOG.c +++ b/net/ipv4/netfilter/ipt_LOG.c @@ -425,7 +425,12 @@ ipt_log_target(struct sk_buff **pskb, li.u.log.level = loginfo->level; li.u.log.logflags = loginfo->logflags; - nf_log_packet(PF_INET, hooknum, *pskb, in, out, &li, loginfo->prefix); + if (loginfo->logflags & IPT_LOG_NFLOG) + nf_log_packet(PF_INET, hooknum, *pskb, in, out, &li, + loginfo->prefix); + else + ipt_log_packet(PF_INET, hooknum, *pskb, in, out, &li, + loginfo->prefix); return IPT_CONTINUE; } diff --git a/net/ipv4/route.c b/net/ipv4/route.c index d82c242ea70..fca5fe0cf94 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -835,7 +835,7 @@ static int rt_garbage_collect(void) int r; rthp = rt_remove_balanced_route( - &rt_hash_table[i].chain, + &rt_hash_table[k].chain, rth, &r); goal -= r; diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index 45f7ae58f2c..f285bbf296e 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c @@ -35,6 +35,7 @@ __xfrm4_find_bundle(struct flowi *fl, struct xfrm_policy *policy) if (xdst->u.rt.fl.oif == fl->oif && /*XXX*/ xdst->u.rt.fl.fl4_dst == fl->fl4_dst && xdst->u.rt.fl.fl4_src == fl->fl4_src && + xdst->u.rt.fl.fl4_tos == fl->fl4_tos && xfrm_bundle_ok(xdst, fl, AF_INET)) { dst_clone(dst); break; @@ -61,7 +62,8 @@ __xfrm4_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int .nl_u = { .ip4_u = { .saddr = local, - .daddr = remote + .daddr = remote, + .tos = fl->fl4_tos } } }; @@ -230,6 +232,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl) fl->proto = iph->protocol; fl->fl4_dst = iph->daddr; fl->fl4_src = iph->saddr; + fl->fl4_tos = iph->tos; } static inline int xfrm4_garbage_collect(void) |