summaryrefslogtreecommitdiff
path: root/net/ipv4/ip_options.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/ip_options.c')
-rw-r--r--net/ipv4/ip_options.c42
1 files changed, 15 insertions, 27 deletions
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index 4d315158fd3c..aeed4e5858ec 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -45,7 +45,6 @@ void ip_options_build(struct sk_buff * skb, struct ip_options * opt,
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) {
@@ -107,10 +104,7 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb)
sptr = skb_network_header(skb);
dptr = dopt->__data;
- if (skb->dst)
- daddr = ((struct rtable*)skb->dst)->rt_spec_dst;
- else
- daddr = ip_hdr(skb)->daddr;
+ daddr = skb->rtable->rt_spec_dst;
if (sopt->rr) {
optlen = sptr[sopt->rr+1];
@@ -261,19 +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_network_header(skb);
- 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 *)&(ip_hdr(skb)[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) {
@@ -523,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;
@@ -561,7 +549,7 @@ 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;
+ struct rtable *rt = skb->rtable;
unsigned char *raw = skb_network_header(skb);
if (opt->rr_needaddr) {
@@ -609,7 +597,7 @@ int ip_options_rcv_srr(struct sk_buff *skb)
__be32 nexthop;
struct iphdr *iph = ip_hdr(skb);
unsigned char *optptr = skb_network_header(skb) + opt->srr;
- struct rtable *rt = (struct rtable*)skb->dst;
+ struct rtable *rt = skb->rtable;
struct rtable *rt2;
int err;
@@ -634,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);