X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=net%2Fipv4%2Fip_options.c;h=aeed4e5858ec2305e8c1e786bd7e6d75131b612e;hb=061964fb988ca51087948975da66ff523b3a5852;hp=f906a80d5a87952e408c1507df4b9eb26ad35352;hpb=58a3bb59973e33a428d72fa530a3d1d81feb0e8f;p=linux-2.6 diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index f906a80d5a..aeed4e5858 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c @@ -40,12 +40,11 @@ void ip_options_build(struct sk_buff * skb, struct ip_options * opt, __be32 daddr, struct rtable *rt, int is_frag) { - unsigned char * iph = skb->nh.raw; + unsigned char *iph = skb_network_header(skb); memcpy(&(IPCB(skb)->opt), opt, sizeof(struct ip_options)); memcpy(iph+sizeof(struct iphdr), opt->__data, opt->optlen); opt = &(IPCB(skb)->opt); - opt->is_data = 0; if (opt->srr) memcpy(iph+opt->srr+iph[opt->srr+1]-4, &daddr, 4); @@ -95,8 +94,6 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb) memset(dopt, 0, sizeof(struct ip_options)); - dopt->is_data = 1; - sopt = &(IPCB(skb)->opt); if (sopt->optlen == 0) { @@ -104,13 +101,10 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb) return 0; } - sptr = skb->nh.raw; + sptr = skb_network_header(skb); dptr = dopt->__data; - if (skb->dst) - daddr = ((struct rtable*)skb->dst)->rt_spec_dst; - else - daddr = skb->nh.iph->daddr; + daddr = skb->rtable->rt_spec_dst; if (sopt->rr) { optlen = sptr[sopt->rr+1]; @@ -151,7 +145,7 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb) __be32 addr; memcpy(&addr, sptr+soffset-1, 4); - if (inet_addr_type(addr) != RTN_LOCAL) { + if (inet_addr_type(&init_net, addr) != RTN_LOCAL) { dopt->ts_needtime = 1; soffset += 8; } @@ -180,7 +174,8 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb) /* * RFC1812 requires to fix illegal source routes. */ - if (memcmp(&skb->nh.iph->saddr, &start[soffset+3], 4) == 0) + if (memcmp(&ip_hdr(skb)->saddr, + &start[soffset + 3], 4) == 0) doffset -= 4; } if (doffset > 3) { @@ -217,7 +212,7 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb) void ip_options_fragment(struct sk_buff * skb) { - unsigned char * optptr = skb->nh.raw + sizeof(struct iphdr); + unsigned char *optptr = skb_network_header(skb) + sizeof(struct iphdr); struct ip_options * opt = &(IPCB(skb)->opt); int l = opt->optlen; int optlen; @@ -260,18 +255,14 @@ int ip_options_compile(struct ip_options * opt, struct sk_buff * skb) unsigned char * optptr; int optlen; unsigned char * pp_ptr = NULL; - struct rtable *rt = skb ? (struct rtable*)skb->dst : NULL; - - if (!opt) { - opt = &(IPCB(skb)->opt); - iph = skb->nh.raw; - opt->optlen = ((struct iphdr *)iph)->ihl*4 - sizeof(struct iphdr); - optptr = iph + sizeof(struct iphdr); - opt->is_data = 0; - } else { - optptr = opt->is_data ? opt->__data : (unsigned char*)&(skb->nh.iph[1]); - iph = optptr - sizeof(struct iphdr); - } + struct rtable *rt = NULL; + + if (skb != NULL) { + rt = skb->rtable; + optptr = (unsigned char *)&(ip_hdr(skb)[1]); + } else + optptr = opt->__data; + iph = optptr - sizeof(struct iphdr); for (l = opt->optlen; l > 0; ) { switch (*optptr) { @@ -398,7 +389,7 @@ int ip_options_compile(struct ip_options * opt, struct sk_buff * skb) { __be32 addr; memcpy(&addr, &optptr[optptr[2]-1], 4); - if (inet_addr_type(addr) == RTN_UNICAST) + if (inet_addr_type(&init_net, addr) == RTN_UNICAST) break; if (skb) timeptr = (__be32*)&optptr[optptr[2]+3]; @@ -511,11 +502,8 @@ void ip_options_undo(struct ip_options * opt) static struct ip_options *ip_options_get_alloc(const int optlen) { - struct ip_options *opt = kmalloc(sizeof(*opt) + ((optlen + 3) & ~3), - GFP_KERNEL); - if (opt) - memset(opt, 0, sizeof(*opt)); - return opt; + return kzalloc(sizeof(struct ip_options) + ((optlen + 3) & ~3), + GFP_KERNEL); } static int ip_options_get_finish(struct ip_options **optp, @@ -524,7 +512,6 @@ static int ip_options_get_finish(struct ip_options **optp, while (optlen & 3) opt->__data[optlen++] = IPOPT_END; opt->optlen = optlen; - opt->is_data = 1; if (optlen && ip_options_compile(opt, NULL)) { kfree(opt); return -EINVAL; @@ -562,8 +549,8 @@ void ip_forward_options(struct sk_buff *skb) { struct ip_options * opt = &(IPCB(skb)->opt); unsigned char * optptr; - struct rtable *rt = (struct rtable*)skb->dst; - unsigned char *raw = skb->nh.raw; + struct rtable *rt = skb->rtable; + unsigned char *raw = skb_network_header(skb); if (opt->rr_needaddr) { optptr = (unsigned char *)raw + opt->rr; @@ -587,7 +574,7 @@ void ip_forward_options(struct sk_buff *skb) if (srrptr + 3 <= srrspace) { opt->is_changed = 1; ip_rt_get_source(&optptr[srrptr-1], rt); - skb->nh.iph->daddr = rt->rt_dst; + ip_hdr(skb)->daddr = rt->rt_dst; optptr[2] = srrptr+4; } else if (net_ratelimit()) printk(KERN_CRIT "ip_forward(): Argh! Destination lost!\n"); @@ -599,7 +586,7 @@ void ip_forward_options(struct sk_buff *skb) } if (opt->is_changed) { opt->is_changed = 0; - ip_send_check(skb->nh.iph); + ip_send_check(ip_hdr(skb)); } } @@ -608,9 +595,9 @@ int ip_options_rcv_srr(struct sk_buff *skb) struct ip_options *opt = &(IPCB(skb)->opt); int srrspace, srrptr; __be32 nexthop; - struct iphdr *iph = skb->nh.iph; - unsigned char * optptr = skb->nh.raw + opt->srr; - struct rtable *rt = (struct rtable*)skb->dst; + struct iphdr *iph = ip_hdr(skb); + unsigned char *optptr = skb_network_header(skb) + opt->srr; + struct rtable *rt = skb->rtable; struct rtable *rt2; int err; @@ -635,13 +622,13 @@ int ip_options_rcv_srr(struct sk_buff *skb) } memcpy(&nexthop, &optptr[srrptr-1], 4); - rt = (struct rtable*)skb->dst; - skb->dst = NULL; + rt = skb->rtable; + skb->rtable = NULL; err = ip_route_input(skb, nexthop, iph->saddr, iph->tos, skb->dev); - rt2 = (struct rtable*)skb->dst; + rt2 = skb->rtable; if (err || (rt2->rt_type != RTN_UNICAST && rt2->rt_type != RTN_LOCAL)) { ip_rt_put(rt2); - skb->dst = &rt->u.dst; + skb->rtable = rt; return -EINVAL; } ip_rt_put(rt);